mirror of
https://github.com/Telecominfraproject/wlan-ap.git
synced 2025-12-24 21:02:35 +00:00
1824 lines
58 KiB
Diff
1824 lines
58 KiB
Diff
From 12ce51423d768da650db9c76c5b67a8d2e86ff8c Mon Sep 17 00:00:00 2001
|
|
From: Sowmiya Sree Elavalagan <ssreeela@codeaurora.org>
|
|
Date: Tue, 22 Dec 2020 20:08:37 +0530
|
|
Subject: [PATCH] ath11k: qcn9100 bring up
|
|
|
|
Add qcn9100 platform support.
|
|
qcn9100 is a hybrid bus type device which is enumerated as
|
|
pci device by Q6 and enumerates as ahb device on host.
|
|
It uses qgic interrupts to notify events to host driver.
|
|
Used qgic api to convert MSI interrupt to qgic interrupt.
|
|
Added qmi message to learn bar address from qcn9100.
|
|
Test performed:
|
|
Ran ping test for open, ccmp and tkip modes.
|
|
Ran iperf traffic for few mins.
|
|
|
|
Signed-off-by: Sowmiya Sree Elavalagan <ssreeela@codeaurora.org>
|
|
---
|
|
drivers/net/wireless/ath/ath11k/ahb.c | 190 +++++++++++++++++++++----
|
|
drivers/net/wireless/ath/ath11k/ce.c | 2 +-
|
|
drivers/net/wireless/ath/ath11k/core.c | 80 +++++++++--
|
|
drivers/net/wireless/ath/ath11k/core.h | 11 ++
|
|
drivers/net/wireless/ath/ath11k/debugfs.c | 7 +-
|
|
drivers/net/wireless/ath/ath11k/hal.h | 1 -
|
|
drivers/net/wireless/ath/ath11k/hif.h | 33 +++++
|
|
drivers/net/wireless/ath/ath11k/hw.c | 117 +++++++++++++++
|
|
drivers/net/wireless/ath/ath11k/hw.h | 3 +
|
|
drivers/net/wireless/ath/ath11k/mhi.c | 6 +-
|
|
drivers/net/wireless/ath/ath11k/nss.c | 3 +
|
|
drivers/net/wireless/ath/ath11k/nss.h | 1 +
|
|
drivers/net/wireless/ath/ath11k/pci.c | 243 +++++++++++++++++++++-----------
|
|
drivers/net/wireless/ath/ath11k/pci.h | 62 +++++++-
|
|
drivers/net/wireless/ath/ath11k/qmi.c | 178 ++++++++++++++++++++++-
|
|
drivers/net/wireless/ath/ath11k/qmi.h | 23 ++-
|
|
16 files changed, 828 insertions(+), 132 deletions(-)
|
|
|
|
--- a/drivers/net/wireless/ath/ath11k/ahb.c
|
|
+++ b/drivers/net/wireless/ath/ath11k/ahb.c
|
|
@@ -12,7 +12,9 @@
|
|
#include "debug.h"
|
|
#include "hif.h"
|
|
#include "qmi.h"
|
|
+#include "pci.h"
|
|
#include <linux/remoteproc.h>
|
|
+#include <soc/qcom/qgic2m.h>
|
|
|
|
static const struct of_device_id ath11k_ahb_of_match[] = {
|
|
/* TODO: Should we change the compatible string to something similar
|
|
@@ -27,6 +29,9 @@ static const struct of_device_id ath11k_
|
|
{ .compatible = "qcom,ipq5018-wifi",
|
|
.data = (void *)ATH11K_HW_IPQ5018,
|
|
},
|
|
+ { .compatible = "qcom,qcn6122-wifi",
|
|
+ .data = (void *)ATH11K_HW_QCN6122,
|
|
+ },
|
|
{ }
|
|
};
|
|
|
|
@@ -39,6 +44,14 @@ static const struct ath11k_bus_params at
|
|
.fixed_mem_region = true,
|
|
};
|
|
|
|
+static const struct ath11k_bus_params ath11k_internal_pci_bus_params = {
|
|
+ .mhi_support = false,
|
|
+ .m3_fw_support = false,
|
|
+ .fixed_bdf_addr = true,
|
|
+ .fixed_mem_region = true,
|
|
+ .static_window_map = true,
|
|
+};
|
|
+
|
|
#define ATH11K_IRQ_CE0_OFFSET 4
|
|
|
|
static const char *irq_name[ATH11K_IRQ_NUM_MAX] = {
|
|
@@ -376,6 +389,29 @@ static void ath11k_ahb_power_down(struct
|
|
rproc_shutdown(ab_ahb->tgt_rproc);
|
|
}
|
|
|
|
+static int ath11k_get_userpd_id(struct device *dev)
|
|
+{
|
|
+ int ret;
|
|
+ int userpd_id = 0;
|
|
+ const char *subsys_name;
|
|
+
|
|
+ ret = of_property_read_string(dev->of_node,
|
|
+ "qcom,userpd-subsys-name",
|
|
+ &subsys_name);
|
|
+ if (ret) {
|
|
+ dev_err(dev, "Not multipd architecture");
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ if (strcmp(subsys_name, "q6v5_wcss_userpd2") == 0) {
|
|
+ userpd_id = QCN6122_USERPD_0;
|
|
+ } else if (strcmp(subsys_name, "q6v5_wcss_userpd3") == 0) {
|
|
+ userpd_id = QCN6122_USERPD_1;
|
|
+ }
|
|
+
|
|
+ return userpd_id;
|
|
+}
|
|
+
|
|
static void ath11k_ahb_init_qmi_ce_config(struct ath11k_base *ab)
|
|
{
|
|
struct ath11k_qmi_ce_cfg *cfg = &ab->qmi.ce_cfg;
|
|
@@ -385,6 +421,7 @@ static void ath11k_ahb_init_qmi_ce_confi
|
|
cfg->svc_to_ce_map_len = ab->hw_params.svc_to_ce_map_len;
|
|
cfg->svc_to_ce_map = ab->hw_params.svc_to_ce_map;
|
|
ab->qmi.service_ins_id = ab->hw_params.qmi_service_ins_id;
|
|
+ ab->qmi.service_ins_id += ab->userpd_id;
|
|
}
|
|
|
|
static void ath11k_ahb_free_ext_irq(struct ath11k_base *ab)
|
|
@@ -559,10 +596,65 @@ static int ath11k_ahb_ext_irq_config(str
|
|
return 0;
|
|
}
|
|
|
|
+static void ath11k_internal_pci_free_irq(struct ath11k_base *ab)
|
|
+{
|
|
+ ath11k_pci_free_irq(ab);
|
|
+ qgic2_disable_msi(ab->ipci.qgicm_id);
|
|
+}
|
|
+
|
|
+struct qgic2_msi *ath11k_qgic2_enable_msi(struct ath11k_base *ab, int qgicm_id)
|
|
+{
|
|
+ struct qgic2_msi *qgic2_msi;
|
|
+
|
|
+ ab->ipci.msi_cfg = &ath11k_msi_config[ATH11K_MSI_CONFIG_QCN6122];
|
|
+ qgic2_msi = qgic2_enable_msi(qgicm_id,
|
|
+ ab->ipci.msi_cfg->total_vectors);
|
|
+ if (IS_ERR(qgic2_msi)) {
|
|
+ ath11k_err(ab, "qgic2_enable_msi fails %ld\n", PTR_ERR(qgic2_msi));
|
|
+ return NULL;
|
|
+ }
|
|
+
|
|
+ return qgic2_msi;
|
|
+}
|
|
+
|
|
+static int ath11k_config_irq_internal_pci(struct ath11k_base *ab)
|
|
+{
|
|
+ int ret;
|
|
+
|
|
+ if (ab->userpd_id == QCN6122_USERPD_0) {
|
|
+ ab->ipci.qgicm_id = APCS_QGIC2M_0;
|
|
+ } else if (ab->userpd_id == QCN6122_USERPD_1) {
|
|
+ ab->ipci.qgicm_id = APCS_QGIC2M_1;
|
|
+ } else {
|
|
+ ath11k_warn(ab, "ath11k userpd invalid %d\n", ab->userpd_id);
|
|
+ return -ENODEV;
|
|
+ }
|
|
+
|
|
+ ab->ipci.qgic2_msi =
|
|
+ ath11k_qgic2_enable_msi(ab, ab->ipci.qgicm_id);
|
|
+ if (!ab->ipci.qgic2_msi) {
|
|
+ ath11k_err(ab, "qgic2_msi fails: dev %d\n", ab->hw_rev);
|
|
+ return -ENODEV;
|
|
+ }
|
|
+ ab->ipci.qgic_enabled = 1;
|
|
+ wake_up(&ab->ipci.qgic_msi_waitq);
|
|
+
|
|
+ /* qcn6122 is seen as ahb based device by driver but internallly it is pci
|
|
+ * Hence configuring pci irq for qcn6122
|
|
+ */
|
|
+ ret = ath11k_pci_config_qgic_msi_irq(ab);
|
|
+ if (ret) {
|
|
+ ath11k_err(ab, "internal pci msi configuration failed: dev %d\n",
|
|
+ ab->hw_rev);
|
|
+ qgic2_disable_msi(ab->ipci.qgicm_id);
|
|
+ }
|
|
+ return ret;
|
|
+}
|
|
+
|
|
static int ath11k_ahb_config_irq(struct ath11k_base *ab)
|
|
{
|
|
int irq, irq_idx, i;
|
|
- int ret;
|
|
+ int ret = 0;
|
|
|
|
/* Configure CE irqs */
|
|
for (i = 0; i < ab->hw_params.ce_count; i++) {
|
|
@@ -643,25 +735,67 @@ static const struct ath11k_hif_ops ath11
|
|
.map_service_to_pipe = ath11k_ahb_map_service_to_pipe,
|
|
.power_down = ath11k_ahb_power_down,
|
|
.power_up = ath11k_ahb_power_up,
|
|
+ .free_irq = ath11k_ahb_free_irq,
|
|
+ .config_irq = ath11k_ahb_config_irq,
|
|
+};
|
|
+
|
|
+static const struct ath11k_hif_ops ath11k_internal_pci_hif_ops = {
|
|
+ .start = ath11k_ipci_start,
|
|
+ .stop = ath11k_pci_stop,
|
|
+ .read32 = ath11k_ipci_read32,
|
|
+ .write32 = ath11k_ipci_write32,
|
|
+ .power_down = ath11k_ahb_power_down,
|
|
+ .power_up = ath11k_ahb_power_up,
|
|
+ .irq_enable = ath11k_pci_ext_irq_enable,
|
|
+ .irq_disable = ath11k_pci_ext_irq_disable,
|
|
+ .get_msi_address = ath11k_pci_get_qgic_msi_address,
|
|
+ .get_user_msi_vector = ath11k_get_user_qgic_msi_assignment,
|
|
+ .map_service_to_pipe = ath11k_pci_map_service_to_pipe,
|
|
+ .get_window_offset = ath11k_pci_get_window_offset,
|
|
+ .get_ce_msi_idx = ath11k_pci_get_ce_msi_idx,
|
|
+ /* TODO: Additional hif ops has been brought in to remove
|
|
+ * platform checks. QCN6122 is a hybrid bus which is a
|
|
+ * combination of pic and ahb. This addition ops needs
|
|
+ * to be removed in future
|
|
+ */
|
|
+ .config_static_window = ath11k_pci_config_static_window,
|
|
+ .free_irq = ath11k_internal_pci_free_irq,
|
|
+ .config_irq = ath11k_config_irq_internal_pci,
|
|
+ .get_msi_irq = ath11k_pci_get_qgic_msi_irq,
|
|
};
|
|
|
|
static int ath11k_core_get_rproc(struct ath11k_base *ab)
|
|
{
|
|
struct ath11k_ahb *ab_ahb = ath11k_ahb_priv(ab);
|
|
struct device *dev = ab->dev;
|
|
+ const char *name;
|
|
struct rproc *prproc;
|
|
phandle rproc_phandle;
|
|
+ bool multi_pd_arch;
|
|
|
|
- if (of_property_read_u32(dev->of_node, "qcom,rproc", &rproc_phandle)) {
|
|
- ath11k_err(ab, "failed to get q6_rproc handle\n");
|
|
- return -ENOENT;
|
|
- }
|
|
+ multi_pd_arch = of_property_read_bool(dev->of_node, "qcom,multipd_arch");
|
|
+ if (multi_pd_arch) {
|
|
+ if (of_property_read_string(dev->of_node, "qcom,userpd-subsys-name", &name))
|
|
+ return -EINVAL;
|
|
+
|
|
+ prproc = rproc_get_by_name(name);
|
|
+ if (!prproc) {
|
|
+ ath11k_err(ab, "failed to get rproc\n");
|
|
+ return -EINVAL;
|
|
+ }
|
|
+ } else {
|
|
+ if (of_property_read_u32(dev->of_node, "qcom,rproc", &rproc_phandle)) {
|
|
+ ath11k_err(ab, "failed to get q6_rproc handle\n");
|
|
+ return -ENOENT;
|
|
+ }
|
|
|
|
- prproc = rproc_get_by_phandle(rproc_phandle);
|
|
- if (!prproc) {
|
|
- ath11k_err(ab, "failed to get rproc\n");
|
|
- return -EINVAL;
|
|
+ prproc = rproc_get_by_phandle(rproc_phandle);
|
|
+ if (!prproc) {
|
|
+ ath11k_err(ab, "failed to get rproc\n");
|
|
+ return -EINVAL;
|
|
+ }
|
|
}
|
|
+
|
|
ab_ahb->tgt_rproc = prproc;
|
|
|
|
return 0;
|
|
@@ -675,6 +809,7 @@ static int ath11k_ahb_probe(struct platf
|
|
struct resource *mem_res;
|
|
void __iomem *mem;
|
|
int ret;
|
|
+ int userpd_id;
|
|
u32 hw_mode_id;
|
|
|
|
of_id = of_match_device(ath11k_ahb_of_match, &pdev->dev);
|
|
@@ -683,18 +818,7 @@ static int ath11k_ahb_probe(struct platf
|
|
return -EINVAL;
|
|
}
|
|
|
|
- mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
|
- if (!mem_res) {
|
|
- dev_err(&pdev->dev, "failed to get IO memory resource\n");
|
|
- return -ENXIO;
|
|
- }
|
|
-
|
|
- mem = devm_ioremap_resource(&pdev->dev, mem_res);
|
|
- if (IS_ERR(mem)) {
|
|
- dev_err(&pdev->dev, "ioremap error\n");
|
|
- return PTR_ERR(mem);
|
|
- }
|
|
-
|
|
+ userpd_id = ath11k_get_userpd_id(dev);
|
|
ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
|
|
if (ret) {
|
|
dev_err(&pdev->dev, "failed to set 32-bit consistent dma\n");
|
|
@@ -713,25 +837,45 @@ static int ath11k_ahb_probe(struct platf
|
|
ab->pdev = pdev;
|
|
ab->hw_rev = (enum ath11k_hw_rev)of_id->data;
|
|
ab->fw_mode = ATH11K_FIRMWARE_MODE_NORMAL;
|
|
- ab->mem = mem;
|
|
- ab->mem_pa = mem_res->start;
|
|
- ab->mem_len = resource_size(mem_res);
|
|
ab->enable_cold_boot_cal = enable_cold_boot_cal;
|
|
+ ab->userpd_id = userpd_id;
|
|
+
|
|
platform_set_drvdata(pdev, ab);
|
|
|
|
- ab->mem_ce = ab->mem;
|
|
- if (ab->hw_rev == ATH11K_HW_IPQ5018) {
|
|
- /* ce register space is moved out of wcss unlike ipq8074 or ipq6018
|
|
- * and the space is not contiguous, hence remapping the CE registers
|
|
- * to a new space for accessing them.
|
|
- */
|
|
- ab->mem_ce = ioremap_nocache(HAL_IPQ5018_CE_WFSS_REG_BASE, HAL_IPQ5018_CE_SIZE);
|
|
- if (IS_ERR(ab->mem_ce)) {
|
|
- dev_err(&pdev->dev, "ce ioremap error\n");
|
|
- return -ENOMEM;
|
|
+ if (ab->hw_rev != ATH11K_HW_QCN6122) {
|
|
+ mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
|
+ if (!mem_res) {
|
|
+ dev_err(&pdev->dev, "failed to get IO memory resource\n");
|
|
+ return -ENXIO;
|
|
+ }
|
|
+
|
|
+ mem = devm_ioremap_resource(&pdev->dev, mem_res);
|
|
+ if (IS_ERR(mem)) {
|
|
+ dev_err(&pdev->dev, "ioremap error\n");
|
|
+ return PTR_ERR(mem);
|
|
}
|
|
- ab->ce_remap = true;
|
|
- ab->ce_remap_base_addr = HAL_IPQ5018_CE_WFSS_REG_BASE;
|
|
+
|
|
+ ab->mem = mem;
|
|
+ ab->mem_pa = mem_res->start;
|
|
+ ab->mem_len = resource_size(mem_res);
|
|
+ ab->mem_ce = ab->mem;
|
|
+ if (ab->hw_rev == ATH11K_HW_IPQ5018) {
|
|
+ /* ce register space is moved out of wcss unlike ipq8074 or ipq6018
|
|
+ * and the space is not contiguous, hence remapping the CE registers
|
|
+ * to a new space for accessing them.
|
|
+ */
|
|
+ ab->mem_ce = ioremap_nocache(HAL_IPQ5018_CE_WFSS_REG_BASE,
|
|
+ HAL_IPQ5018_CE_SIZE);
|
|
+ if (IS_ERR(ab->mem_ce)) {
|
|
+ dev_err(&pdev->dev, "ce ioremap error\n");
|
|
+ return -ENOMEM;
|
|
+ }
|
|
+ ab->ce_remap = true;
|
|
+ ab->ce_remap_base_addr = HAL_IPQ5018_CE_WFSS_REG_BASE;
|
|
+ }
|
|
+ } else {
|
|
+ ab->hif.ops = &ath11k_internal_pci_hif_ops;
|
|
+ ab->bus_params = ath11k_internal_pci_bus_params;
|
|
}
|
|
|
|
ret = ath11k_core_pre_init(ab);
|
|
@@ -762,7 +906,7 @@ static int ath11k_ahb_probe(struct platf
|
|
goto err_ce_free;
|
|
}
|
|
|
|
- ret = ath11k_ahb_config_irq(ab);
|
|
+ ret = ath11k_hif_config_irq(ab);
|
|
if (ret) {
|
|
ath11k_err(ab, "failed to configure irq: %d\n", ret);
|
|
goto err_ce_free;
|
|
@@ -817,7 +961,7 @@ static int ath11k_ahb_remove(struct plat
|
|
|
|
ath11k_core_deinit(ab);
|
|
qmi_fail:
|
|
- ath11k_ahb_free_irq(ab);
|
|
+ ath11k_hif_free_irq(ab);
|
|
ath11k_hal_srng_deinit(ab);
|
|
ath11k_ce_free_pipes(ab);
|
|
|
|
--- a/drivers/net/wireless/ath/ath11k/ce.c
|
|
+++ b/drivers/net/wireless/ath/ath11k/ce.c
|
|
@@ -215,7 +215,7 @@ const struct ce_attr ath11k_host_ce_conf
|
|
.flags = CE_ATTR_FLAGS,
|
|
.src_nentries = 0,
|
|
.src_sz_max = 2048,
|
|
- .dest_nentries = 32,
|
|
+ .dest_nentries = 128,
|
|
.recv_cb = ath11k_htc_rx_completion_handler,
|
|
},
|
|
|
|
--- a/drivers/net/wireless/ath/ath11k/core.c
|
|
+++ b/drivers/net/wireless/ath/ath11k/core.c
|
|
@@ -284,7 +284,58 @@ static const struct ath11k_hw_params ath
|
|
.reo_dest_ring_map_shift = HAL_IPQ5018_REO_DEST_RING_CTRL_HASH_RING_SHIFT,
|
|
.ce_fwlog_enable = false,
|
|
.fwmem_mode_change = false,
|
|
+ .cold_boot_calib = true,
|
|
},
|
|
+ {
|
|
+ .hw_rev = ATH11K_HW_QCN6122,
|
|
+ .name = "qcn6122",
|
|
+ .fw = {
|
|
+ .dir = "qcn6122/hw1.0",
|
|
+ .board_size = 256 * 1024,
|
|
+ .cal_size = 256 * 1024,
|
|
+ },
|
|
+ .max_radios = 1,
|
|
+ .bdf_addr = 0x4D200000,
|
|
+ /* hal_desc_sz is similar to qcn9074 */
|
|
+ .hal_desc_sz = sizeof(struct hal_rx_desc_qcn9074),
|
|
+ .hw_ops = &qcn6122_ops,
|
|
+ .qmi_service_ins_id = ATH11K_QMI_WLFW_SERVICE_INS_ID_V01_QCN6122,
|
|
+ .ring_mask = &ath11k_hw_ring_mask_ipq8074,
|
|
+ .regs = &qcn6122_regs,
|
|
+ .m3_addr = ATH11K_QMI_QCN6122_M3_DUMP_ADDRESS,
|
|
+ .spectral_fft_sz = 2,
|
|
+ .credit_flow = false,
|
|
+ .num_dscp_tid_map_tbl = HAL_IPQ5018_DSCP_TID_MAP_TBL_NUM_ENTRIES_MAX,
|
|
+ .interface_modes = BIT(NL80211_IFTYPE_STATION) |
|
|
+ BIT(NL80211_IFTYPE_AP) |
|
|
+ BIT(NL80211_IFTYPE_MESH_POINT),
|
|
+ .supports_monitor = true,
|
|
+ .supports_shadow_regs = false,
|
|
+ .idle_ps = false,
|
|
+ .cold_boot_calib = false,
|
|
+ .supports_suspend = false,
|
|
+ .host_ce_config = ath11k_host_ce_config_qcn9074,
|
|
+ .ce_count = 6,
|
|
+ .target_ce_config = ath11k_target_ce_config_wlan_ipq5018,
|
|
+ .target_ce_count = 9,
|
|
+ .svc_to_ce_map = ath11k_target_service_to_ce_map_wlan_ipq5018,
|
|
+ .svc_to_ce_map_len = 17,
|
|
+ .single_pdev_only = false,
|
|
+ .needs_band_to_mac = true,
|
|
+ .rxdma1_enable = true,
|
|
+ .num_rxmda_per_pdev = 1,
|
|
+ .rx_mac_buf_ring = false,
|
|
+ .vdev_start_delay = false,
|
|
+ .htt_peer_map_v2 = true,
|
|
+ .tcl_0_only = false,
|
|
+ .spectral_max_fft_bins = 1024,
|
|
+ .spectral_summary_pad_sz = 16,
|
|
+ .spectral_fft_hdr_len = 24,
|
|
+ .reo_dest_ring_map_shift = HAL_IPQ5018_REO_DEST_RING_CTRL_HASH_RING_SHIFT,
|
|
+ .ce_fwlog_enable = false,
|
|
+ .cold_boot_calib = false,
|
|
+ .fwmem_mode_change = false,
|
|
+ },
|
|
};
|
|
|
|
static const struct ath11k_num_vdevs_peers ath11k_vdevs_peers[] = {
|
|
--- a/drivers/net/wireless/ath/ath11k/core.h
|
|
+++ b/drivers/net/wireless/ath/ath11k/core.h
|
|
@@ -125,6 +125,7 @@ enum ath11k_hw_rev {
|
|
ATH11K_HW_IPQ6018_HW10,
|
|
ATH11K_HW_QCN9074_HW10,
|
|
ATH11K_HW_IPQ5018,
|
|
+ ATH11K_HW_QCN6122,
|
|
};
|
|
|
|
enum ath11k_firmware_mode {
|
|
@@ -792,6 +793,14 @@ struct ath11k_num_vdevs_peers {
|
|
u32 num_peers;
|
|
};
|
|
|
|
+struct ath11k_internal_pci {
|
|
+ int qgicm_id;
|
|
+ bool qgic_enabled;
|
|
+ struct qgic2_msi *qgic2_msi;
|
|
+ const struct ath11k_msi_config *msi_cfg;
|
|
+ wait_queue_head_t qgic_msi_waitq;
|
|
+};
|
|
+
|
|
/* Master structure to hold the hw data which may be used in core module */
|
|
struct ath11k_base {
|
|
enum ath11k_hw_rev hw_rev;
|
|
@@ -905,6 +914,8 @@ struct ath11k_base {
|
|
u32 ce_remap_base_addr;
|
|
atomic_t num_max_allowed;
|
|
struct ath11k_num_vdevs_peers *num_vdevs_peers;
|
|
+ int userpd_id;
|
|
+ struct ath11k_internal_pci ipci;
|
|
|
|
/* must be last */
|
|
u8 drv_priv[0] __aligned(sizeof(void *));
|
|
--- a/drivers/net/wireless/ath/ath11k/hal.h
|
|
+++ b/drivers/net/wireless/ath/ath11k/hal.h
|
|
@@ -55,7 +55,6 @@ struct ath11k_base;
|
|
(ab->hw_params.regs->hal_seq_wcss_umac_ce1_dst_reg)
|
|
#define HAL_SEQ_WCSS_UMAC_WBM_REG 0x00a34000
|
|
|
|
-#define HAL_CE_WFSS_CE_REG_BASE 0x01b80000
|
|
#define HAL_WLAON_REG_BASE 0x01f80000
|
|
|
|
/* SW2TCL(x) R0 ring configuration address */
|
|
--- a/drivers/net/wireless/ath/ath11k/hif.h
|
|
+++ b/drivers/net/wireless/ath/ath11k/hif.h
|
|
@@ -30,6 +30,10 @@ struct ath11k_hif_ops {
|
|
void (*ce_irq_disable)(struct ath11k_base *ab);
|
|
void (*get_ce_msi_idx)(struct ath11k_base *ab, u32 ce_id, u32 *msi_idx);
|
|
u32 (*get_window_offset)(struct ath11k_base *ab, u32 offset);
|
|
+ void (*config_static_window)(struct ath11k_base *ab);
|
|
+ int (*config_irq)(struct ath11k_base *ab);
|
|
+ void (*free_irq)(struct ath11k_base *ab);
|
|
+ int (*get_msi_irq)(struct ath11k_base *ab, unsigned int vector);
|
|
};
|
|
|
|
static inline void ath11k_hif_ce_irq_enable(struct ath11k_base *ab)
|
|
@@ -143,4 +147,33 @@ static inline void ath11k_get_ce_msi_idx
|
|
else
|
|
*msi_data_idx = ce_id;
|
|
}
|
|
+
|
|
+static inline void ath11k_hif_config_static_window(struct ath11k_base *ab)
|
|
+{
|
|
+ if (!ab->hif.ops->config_static_window)
|
|
+ return;
|
|
+
|
|
+ ab->hif.ops->config_static_window(ab);
|
|
+}
|
|
+
|
|
+static inline void ath11k_hif_free_irq(struct ath11k_base *ab)
|
|
+{
|
|
+ if (!ab->hif.ops->free_irq)
|
|
+ return;
|
|
+
|
|
+ return ab->hif.ops->free_irq(ab);
|
|
+}
|
|
+
|
|
+static inline int ath11k_hif_config_irq(struct ath11k_base *ab)
|
|
+{
|
|
+ return ab->hif.ops->config_irq(ab);
|
|
+}
|
|
+
|
|
+static inline int ath11k_hif_get_msi_irq(struct ath11k_base *ab, unsigned int vector)
|
|
+{
|
|
+ if (!ab->hif.ops->get_msi_irq)
|
|
+ return -EOPNOTSUPP;
|
|
+
|
|
+ return ab->hif.ops->get_msi_irq(ab, vector);
|
|
+}
|
|
#endif /* _HIF_H_ */
|
|
--- a/drivers/net/wireless/ath/ath11k/hw.c
|
|
+++ b/drivers/net/wireless/ath/ath11k/hw.c
|
|
@@ -828,6 +828,48 @@ const struct ath11k_hw_ops ipq5018_ops =
|
|
.get_reo_dest_remap_config = ath11k_get_reo_dest_remap_config_5018,
|
|
};
|
|
|
|
+const struct ath11k_hw_ops qcn6122_ops = {
|
|
+ .get_hw_mac_from_pdev_id = ath11k_hw_ipq6018_mac_from_pdev_id,
|
|
+ .wmi_init_config = ath11k_init_wmi_config_ipq8074,
|
|
+ .mac_id_to_pdev_id = ath11k_hw_mac_id_to_pdev_id_ipq8074,
|
|
+ .mac_id_to_srng_id = ath11k_hw_mac_id_to_srng_id_ipq8074,
|
|
+ .rx_desc_get_da_mcbc = ath11k_hw_ipq8074_rx_desc_get_da_mcbc,
|
|
+ .rx_desc_mac_addr2_valid = ath11k_hw_ipq8074_rx_desc_mac_addr2_valid,
|
|
+ .rx_desc_mpdu_start_addr2 = ath11k_hw_ipq8074_rx_desc_mpdu_start_addr2,
|
|
+ .tx_mesh_enable = ath11k_hw_qcn9074_tx_mesh_enable,
|
|
+ .rx_desc_get_first_msdu = ath11k_hw_qcn9074_rx_desc_get_first_msdu,
|
|
+ .rx_desc_get_last_msdu = ath11k_hw_qcn9074_rx_desc_get_last_msdu,
|
|
+ .rx_desc_get_l3_pad_bytes = ath11k_hw_qcn9074_rx_desc_get_l3_pad_bytes,
|
|
+ .rx_desc_get_hdr_status = ath11k_hw_qcn9074_rx_desc_get_hdr_status,
|
|
+ .rx_desc_encrypt_valid = ath11k_hw_qcn9074_rx_desc_encrypt_valid,
|
|
+ .rx_desc_get_encrypt_type = ath11k_hw_qcn9074_rx_desc_get_encrypt_type,
|
|
+ .rx_desc_get_decap_type = ath11k_hw_qcn9074_rx_desc_get_decap_type,
|
|
+ .rx_desc_get_mesh_ctl = ath11k_hw_qcn9074_rx_desc_get_mesh_ctl,
|
|
+ .rx_desc_get_mpdu_seq_ctl_vld = ath11k_hw_qcn9074_rx_desc_get_mpdu_seq_ctl_vld,
|
|
+ .rx_desc_get_mpdu_fc_valid = ath11k_hw_qcn9074_rx_desc_get_mpdu_fc_valid,
|
|
+ .rx_desc_get_mpdu_start_seq_no = ath11k_hw_qcn9074_rx_desc_get_mpdu_start_seq_no,
|
|
+ .rx_desc_get_msdu_len = ath11k_hw_qcn9074_rx_desc_get_msdu_len,
|
|
+ .rx_desc_get_msdu_sgi = ath11k_hw_qcn9074_rx_desc_get_msdu_sgi,
|
|
+ .rx_desc_get_msdu_rate_mcs = ath11k_hw_qcn9074_rx_desc_get_msdu_rate_mcs,
|
|
+ .rx_desc_get_msdu_rx_bw = ath11k_hw_qcn9074_rx_desc_get_msdu_rx_bw,
|
|
+ .rx_desc_get_msdu_freq = ath11k_hw_qcn9074_rx_desc_get_msdu_freq,
|
|
+ .rx_desc_get_msdu_pkt_type = ath11k_hw_qcn9074_rx_desc_get_msdu_pkt_type,
|
|
+ .rx_desc_get_msdu_nss = ath11k_hw_qcn9074_rx_desc_get_msdu_nss,
|
|
+ .rx_desc_get_mpdu_tid = ath11k_hw_qcn9074_rx_desc_get_mpdu_tid,
|
|
+ .set_rx_fragmentation_dst_ring = ath11k_hw_ipq5018_set_rx_fragmentation_dst_ring,
|
|
+ .rx_desc_get_mpdu_peer_id = ath11k_hw_qcn9074_rx_desc_get_mpdu_peer_id,
|
|
+ .rx_desc_copy_attn_end_tlv = ath11k_hw_qcn9074_rx_desc_copy_attn_end,
|
|
+ .rx_desc_get_mpdu_start_tag = ath11k_hw_qcn9074_rx_desc_get_mpdu_start_tag,
|
|
+ .rx_desc_get_mpdu_ppdu_id = ath11k_hw_qcn9074_rx_desc_get_mpdu_ppdu_id,
|
|
+ .rx_desc_set_msdu_len = ath11k_hw_qcn9074_rx_desc_set_msdu_len,
|
|
+ .rx_desc_get_attention = ath11k_hw_qcn9074_rx_desc_get_attention,
|
|
+ .rx_desc_get_msdu_payload = ath11k_hw_qcn9074_rx_desc_get_msdu_payload,
|
|
+ .rx_desc_get_hal_mpdu_peerid = ath11k_hw_qcn9074_rx_desc_get_hal_mpdu_peerid,
|
|
+ .rx_desc_get_hal_mpdu_len = ath11k_hw_qcn9074_rx_desc_get_hal_mpdu_len,
|
|
+ .get_reo_dest_remap_config = ath11k_get_reo_dest_remap_config_5018,
|
|
+ .rx_process_mon_rings = ath11k_dp_rx_process_mon_rings_ipq8074,
|
|
+};
|
|
+
|
|
#define ATH11K_TX_RING_MASK_0 0x1
|
|
#define ATH11K_TX_RING_MASK_1 0x2
|
|
#define ATH11K_TX_RING_MASK_2 0x4
|
|
@@ -2181,3 +2223,79 @@ const struct ath11k_hw_regs ipq5018_regs
|
|
.pcie_qserdes_sysclk_en_sel = 0x01e0e0a8,
|
|
.pcie_pcs_osc_dtct_config_base = 0x01e0f45c,
|
|
};
|
|
+
|
|
+const struct ath11k_hw_regs qcn6122_regs = {
|
|
+ /* SW2TCL(x) R0 ring configuration address */
|
|
+ .hal_tcl1_ring_base_lsb = 0x00000694,
|
|
+ .hal_tcl1_ring_base_msb = 0x00000698,
|
|
+ .hal_tcl1_ring_id = 0x0000069c,
|
|
+ .hal_tcl1_ring_misc = 0x000006a4,
|
|
+ .hal_tcl1_ring_tp_addr_lsb = 0x000006b0,
|
|
+ .hal_tcl1_ring_tp_addr_msb = 0x000006b4,
|
|
+ .hal_tcl1_ring_consumer_int_setup_ix0 = 0x000006c4,
|
|
+ .hal_tcl1_ring_consumer_int_setup_ix1 = 0x000006c8,
|
|
+ .hal_tcl1_ring_msi1_base_lsb = 0x000006dc,
|
|
+ .hal_tcl1_ring_msi1_base_msb = 0x000006e0,
|
|
+ .hal_tcl1_ring_msi1_data = 0x000006e4,
|
|
+ .hal_tcl2_ring_base_lsb = 0x000006ec,
|
|
+ .hal_tcl_ring_base_lsb = 0x0000079c,
|
|
+
|
|
+ /* TCL STATUS ring address */
|
|
+ .hal_tcl_status_ring_base_lsb = 0x000008a4,
|
|
+
|
|
+ /* REO2SW(x) R0 ring configuration address */
|
|
+ .hal_reo1_ring_base_lsb = 0x000001ec,
|
|
+ .hal_reo1_ring_base_msb = 0x000001f0,
|
|
+ .hal_reo1_ring_id = 0x000001f4,
|
|
+ .hal_reo1_ring_misc = 0x000001fc,
|
|
+ .hal_reo1_ring_hp_addr_lsb = 0x00000200,
|
|
+ .hal_reo1_ring_hp_addr_msb = 0x00000204,
|
|
+ .hal_reo1_ring_producer_int_setup = 0x00000210,
|
|
+ .hal_reo1_ring_msi1_base_lsb = 0x00000234,
|
|
+ .hal_reo1_ring_msi1_base_msb = 0x00000238,
|
|
+ .hal_reo1_ring_msi1_data = 0x0000023c,
|
|
+ .hal_reo2_ring_base_lsb = 0x00000244,
|
|
+ .hal_reo1_aging_thresh_ix_0 = 0x00000564,
|
|
+ .hal_reo1_aging_thresh_ix_1 = 0x00000568,
|
|
+ .hal_reo1_aging_thresh_ix_2 = 0x0000056c,
|
|
+ .hal_reo1_aging_thresh_ix_3 = 0x00000570,
|
|
+
|
|
+ /* REO2SW(x) R2 ring pointers (head/tail) address */
|
|
+ .hal_reo1_ring_hp = 0x00003028,
|
|
+ .hal_reo1_ring_tp = 0x0000302c,
|
|
+ .hal_reo2_ring_hp = 0x00003030,
|
|
+
|
|
+ /* REO2TCL R0 ring configuration address */
|
|
+ .hal_reo_tcl_ring_base_lsb = 0x000003fc,
|
|
+ .hal_reo_tcl_ring_hp = 0x00003058,
|
|
+
|
|
+ /* SW2REO ring address */
|
|
+ .hal_sw2reo_ring_base_lsb = 0x0000013c,
|
|
+ .hal_sw2reo_ring_hp = 0x00003018,
|
|
+
|
|
+ /* REO CMD ring address */
|
|
+ .hal_reo_cmd_ring_base_lsb = 0x000000e4,
|
|
+ .hal_reo_cmd_ring_hp = 0x00003010,
|
|
+
|
|
+ /* REO status address */
|
|
+ .hal_reo_status_ring_base_lsb = 0x00000504,
|
|
+ .hal_reo_status_hp = 0x00003070,
|
|
+
|
|
+ /* WCSS relative address */
|
|
+ .hal_seq_wcss_umac_ce0_src_reg = 0x03B80000,
|
|
+ .hal_seq_wcss_umac_ce0_dst_reg = 0x03b81000,
|
|
+ .hal_seq_wcss_umac_ce1_src_reg = 0x03b82000,
|
|
+ .hal_seq_wcss_umac_ce1_dst_reg = 0x03b83000,
|
|
+
|
|
+ /* WBM Idle address */
|
|
+ .hal_wbm_idle_link_ring_base_lsb = 0x00000874,
|
|
+ .hal_wbm_idle_link_ring_misc = 0x00000884,
|
|
+
|
|
+ /* SW2WBM release address */
|
|
+ .hal_wbm_release_ring_base_lsb = 0x000001ec,
|
|
+
|
|
+ /* WBM2SW release address */
|
|
+ .hal_wbm0_release_ring_base_lsb = 0x00000924,
|
|
+ .hal_wbm1_release_ring_base_lsb = 0x0000097c,
|
|
+};
|
|
+
|
|
--- a/drivers/net/wireless/ath/ath11k/hw.h
|
|
+++ b/drivers/net/wireless/ath/ath11k/hw.h
|
|
@@ -192,6 +192,7 @@ struct ath11k_hw_params {
|
|
u32 hal_desc_sz;
|
|
u32 m3_addr;
|
|
u8 reo_dest_ring_map_shift;
|
|
+ bool cold_boot_calib;
|
|
bool ce_fwlog_enable;
|
|
bool fwmem_mode_change;
|
|
};
|
|
@@ -245,6 +246,7 @@ extern const struct ath11k_hw_ops ipq601
|
|
extern const struct ath11k_hw_ops qca6390_ops;
|
|
extern const struct ath11k_hw_ops qcn9074_ops;
|
|
extern const struct ath11k_hw_ops ipq5018_ops;
|
|
+extern const struct ath11k_hw_ops qcn6122_ops;
|
|
|
|
extern const struct ath11k_hw_ring_mask ath11k_hw_ring_mask_ipq8074;
|
|
extern const struct ath11k_hw_ring_mask ath11k_hw_ring_mask_qca6390;
|
|
@@ -365,5 +367,6 @@ extern const struct ath11k_hw_regs ipq80
|
|
extern const struct ath11k_hw_regs qca6390_regs;
|
|
extern const struct ath11k_hw_regs qcn9074_regs;
|
|
extern const struct ath11k_hw_regs ipq5018_regs;
|
|
+extern const struct ath11k_hw_regs qcn6122_regs;
|
|
|
|
#endif
|
|
--- a/drivers/net/wireless/ath/ath11k/mhi.c
|
|
+++ b/drivers/net/wireless/ath/ath11k/mhi.c
|
|
@@ -9,6 +9,7 @@
|
|
#include "debug.h"
|
|
#include "mhi.h"
|
|
#include "pci.h"
|
|
+#include "hif.h"
|
|
|
|
#define MHI_TIMEOUT_DEFAULT_MS 90000
|
|
|
|
@@ -258,7 +259,8 @@ static int ath11k_mhi_get_msi(struct ath
|
|
int ret, num_vectors, i;
|
|
int *irq;
|
|
|
|
- ret = ath11k_pci_get_user_msi_assignment(ab_pci,
|
|
+ ret = ath11k_pci_get_user_msi_assignment(ab, ab_pci->msi_config,
|
|
+ ab_pci->msi_ep_base_data,
|
|
"MHI", &num_vectors,
|
|
&user_base_data, &base_vector);
|
|
if (ret)
|
|
@@ -272,7 +274,7 @@ static int ath11k_mhi_get_msi(struct ath
|
|
return -ENOMEM;
|
|
|
|
for (i = 0; i < num_vectors; i++)
|
|
- irq[i] = ath11k_pci_get_msi_irq(ab->dev,
|
|
+ irq[i] = ath11k_hif_get_msi_irq(ab,
|
|
base_vector + i);
|
|
|
|
ab_pci->mhi_ctrl->irq = irq;
|
|
--- a/drivers/net/wireless/ath/ath11k/nss.c
|
|
+++ b/drivers/net/wireless/ath/ath11k/nss.c
|
|
@@ -2137,6 +2137,8 @@ static int ath11k_nss_get_target_type(st
|
|
return ATH11K_WIFILI_TARGET_TYPE_QCN9074;
|
|
case ATH11K_HW_IPQ5018:
|
|
return ATH11K_WIFILI_TARGET_TYPE_QCA5018;
|
|
+ case ATH11K_HW_QCN6122:
|
|
+ return ATH11K_WIFILI_TARGET_TYPE_QCN6122;
|
|
default:
|
|
ath11k_warn(ab, "NSS Offload not supported for this HW\n");
|
|
return ATH11K_WIFILI_TARGET_TYPE_UNKNOWN;
|
|
@@ -2151,6 +2153,7 @@ static int ath11k_nss_get_interface_type
|
|
case ATH11K_HW_IPQ5018:
|
|
return NSS_WIFILI_INTERNAL_INTERFACE;
|
|
case ATH11K_HW_QCN9074_HW10:
|
|
+ case ATH11K_HW_QCN6122:
|
|
return nss_get_available_wifili_external_if();
|
|
default:
|
|
/* This can't happen since we validated target type earlier */
|
|
--- a/drivers/net/wireless/ath/ath11k/nss.h
|
|
+++ b/drivers/net/wireless/ath/ath11k/nss.h
|
|
@@ -29,6 +29,7 @@ struct hal_rx_mon_ppdu_info;
|
|
#define ATH11K_WIFILI_TARGET_TYPE_QCA6018 25
|
|
#define ATH11K_WIFILI_TARGET_TYPE_QCN9074 26
|
|
#define ATH11K_WIFILI_TARGET_TYPE_QCA5018 29
|
|
+#define ATH11K_WIFILI_TARGET_TYPE_QCN6122 30
|
|
|
|
/* Max limit for NSS Queue */
|
|
#define ATH11K_WIFIILI_MAX_TX_PROCESSQ 1024
|
|
--- a/drivers/net/wireless/ath/ath11k/pci.c
|
|
+++ b/drivers/net/wireless/ath/ath11k/pci.c
|
|
@@ -14,6 +14,8 @@
|
|
#include "debug.h"
|
|
#include "qmi.h"
|
|
#include <linux/of.h>
|
|
+#include <soc/qcom/qgic2m.h>
|
|
+
|
|
|
|
#define ATH11K_PCI_BAR_NUM 0
|
|
#define ATH11K_PCI_DMA_MASK 32
|
|
@@ -54,28 +56,6 @@ static const struct ath11k_bus_params at
|
|
.fixed_mem_region = false,
|
|
};
|
|
|
|
-static const struct ath11k_msi_config ath11k_msi_config[] = {
|
|
- {
|
|
- .total_vectors = 32,
|
|
- .total_users = 4,
|
|
- .users = (struct ath11k_msi_user[]) {
|
|
- { .name = "MHI", .num_vectors = 3, .base_vector = 0 },
|
|
- { .name = "CE", .num_vectors = 10, .base_vector = 3 },
|
|
- { .name = "WAKE", .num_vectors = 1, .base_vector = 13 },
|
|
- { .name = "DP", .num_vectors = 18, .base_vector = 14 },
|
|
- },
|
|
- },
|
|
- {
|
|
- .total_vectors = 16,
|
|
- .total_users = 3,
|
|
- .users = (struct ath11k_msi_user[]) {
|
|
- { .name = "MHI", .num_vectors = 3, .base_vector = 0 },
|
|
- { .name = "CE", .num_vectors = 5, .base_vector = 3 },
|
|
- { .name = "DP", .num_vectors = 8, .base_vector = 8 },
|
|
- },
|
|
- },
|
|
-};
|
|
-
|
|
const char *ce_irq_name[ATH11K_MAX_PCI_DOMAINS + 1][CE_COUNT_MAX] = {
|
|
{
|
|
ATH11K_PCI_CE_IRQS_NAME(0)
|
|
@@ -88,9 +68,9 @@ const char *ce_irq_name[ATH11K_MAX_PCI_D
|
|
},
|
|
};
|
|
|
|
-static inline void ath11k_pci_select_window(struct ath11k_pci *ab_pci, u32 offset)
|
|
+static inline void ath11k_pci_select_window(struct ath11k_base *ab, u32 offset)
|
|
{
|
|
- struct ath11k_base *ab = ab_pci->ab;
|
|
+ struct ath11k_pci *ab_pci = ath11k_pci_priv(ab);
|
|
|
|
u32 window = FIELD_GET(WINDOW_VALUE_MASK, offset);
|
|
|
|
@@ -104,15 +84,15 @@ static inline void ath11k_pci_select_win
|
|
}
|
|
}
|
|
|
|
-static inline void ath11k_pci_select_static_window(struct ath11k_pci *ab_pci)
|
|
+static inline void ath11k_pci_select_static_window(struct ath11k_base *ab)
|
|
{
|
|
u32 umac_window = FIELD_GET(WINDOW_VALUE_MASK, HAL_SEQ_WCSS_UMAC_OFFSET);
|
|
- u32 ce_window = FIELD_GET(WINDOW_VALUE_MASK, HAL_CE_WFSS_CE_REG_BASE);
|
|
+ u32 ce_window = FIELD_GET(WINDOW_VALUE_MASK, HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(ab));
|
|
u32 window;
|
|
|
|
window = (umac_window << 12) | (ce_window << 6);
|
|
|
|
- iowrite32(WINDOW_ENABLE_BIT | window, ab_pci->ab->mem + WINDOW_REG_ADDRESS);
|
|
+ iowrite32(WINDOW_ENABLE_BIT | window, ab->mem + WINDOW_REG_ADDRESS);
|
|
}
|
|
|
|
static inline u32 ath11k_pci_get_window_start(struct ath11k_base *ab,
|
|
@@ -124,7 +104,7 @@ static inline u32 ath11k_pci_get_window_
|
|
if ((offset ^ HAL_SEQ_WCSS_UMAC_OFFSET) < WINDOW_RANGE_MASK)
|
|
window_start = 3 * WINDOW_START;
|
|
/* If offset lies within CE register range, use 2nd window */
|
|
- else if ((offset ^ HAL_CE_WFSS_CE_REG_BASE) < WINDOW_RANGE_MASK)
|
|
+ else if ((offset ^ HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(ab)) < WINDOW_RANGE_MASK)
|
|
window_start = 2 * WINDOW_START;
|
|
else
|
|
window_start = WINDOW_START;
|
|
@@ -132,8 +112,7 @@ static inline u32 ath11k_pci_get_window_
|
|
return window_start;
|
|
}
|
|
|
|
-static inline u32 ath11k_pci_get_window_offset(struct ath11k_base *ab,
|
|
- u32 offset)
|
|
+u32 ath11k_pci_get_window_offset(struct ath11k_base *ab, u32 offset)
|
|
{
|
|
u32 window_start;
|
|
|
|
@@ -145,6 +124,37 @@ static inline u32 ath11k_pci_get_window_
|
|
}
|
|
return offset;
|
|
}
|
|
+EXPORT_SYMBOL(ath11k_pci_get_window_offset);
|
|
+
|
|
+void ath11k_ipci_write32(struct ath11k_base *ab, u32 offset, u32 value)
|
|
+{
|
|
+ u32 window_start;
|
|
+
|
|
+ if (offset < WINDOW_START) {
|
|
+ iowrite32(value, ab->mem + offset);
|
|
+ } else {
|
|
+ window_start = ath11k_pci_get_window_start(ab, offset);
|
|
+ iowrite32(value, ab->mem + window_start +
|
|
+ (offset & WINDOW_RANGE_MASK));
|
|
+ }
|
|
+}
|
|
+EXPORT_SYMBOL(ath11k_ipci_write32);
|
|
+
|
|
+u32 ath11k_ipci_read32(struct ath11k_base *ab, u32 offset)
|
|
+{
|
|
+ u32 val, window_start;
|
|
+
|
|
+ if (offset < WINDOW_START) {
|
|
+ val = ioread32(ab->mem + offset);
|
|
+ } else {
|
|
+ window_start = ath11k_pci_get_window_start(ab, offset);
|
|
+ val = ioread32(ab->mem + window_start +
|
|
+ (offset & WINDOW_RANGE_MASK));
|
|
+ }
|
|
+
|
|
+ return val;
|
|
+}
|
|
+EXPORT_SYMBOL(ath11k_ipci_read32);
|
|
|
|
void ath11k_pci_write32(struct ath11k_base *ab, u32 offset, u32 value)
|
|
{
|
|
@@ -155,7 +165,7 @@ void ath11k_pci_write32(struct ath11k_ba
|
|
* need to wakeup MHI to access.
|
|
*/
|
|
if (test_bit(ATH11K_PCI_FLAG_INIT_DONE, &ab_pci->flags) &&
|
|
- offset >= ACCESS_ALWAYS_OFF)
|
|
+ offset >= ACCESS_ALWAYS_OFF && ab_pci->mhi_ctrl)
|
|
mhi_device_get_sync(ab_pci->mhi_ctrl->mhi_dev);
|
|
|
|
if (offset < WINDOW_START) {
|
|
@@ -168,7 +178,7 @@ void ath11k_pci_write32(struct ath11k_ba
|
|
|
|
if (window_start == WINDOW_START) {
|
|
spin_lock_bh(&ab_pci->window_lock);
|
|
- ath11k_pci_select_window(ab_pci, offset);
|
|
+ ath11k_pci_select_window(ab, offset);
|
|
iowrite32(value, ab->mem + window_start +
|
|
(offset & WINDOW_RANGE_MASK));
|
|
spin_unlock_bh(&ab_pci->window_lock);
|
|
@@ -179,9 +189,10 @@ void ath11k_pci_write32(struct ath11k_ba
|
|
}
|
|
|
|
if (test_bit(ATH11K_PCI_FLAG_INIT_DONE, &ab_pci->flags) &&
|
|
- offset >= ACCESS_ALWAYS_OFF)
|
|
+ offset >= ACCESS_ALWAYS_OFF && ab_pci->mhi_ctrl)
|
|
mhi_device_put(ab_pci->mhi_ctrl->mhi_dev);
|
|
}
|
|
+EXPORT_SYMBOL(ath11k_pci_write32);
|
|
|
|
u32 ath11k_pci_read32(struct ath11k_base *ab, u32 offset)
|
|
{
|
|
@@ -192,7 +203,7 @@ u32 ath11k_pci_read32(struct ath11k_base
|
|
* need to wakeup MHI to access.
|
|
*/
|
|
if (test_bit(ATH11K_PCI_FLAG_INIT_DONE, &ab_pci->flags) &&
|
|
- offset >= ACCESS_ALWAYS_OFF)
|
|
+ offset >= ACCESS_ALWAYS_OFF && ab_pci->mhi_ctrl)
|
|
mhi_device_get_sync(ab_pci->mhi_ctrl->mhi_dev);
|
|
|
|
if (offset < WINDOW_START) {
|
|
@@ -205,7 +216,7 @@ u32 ath11k_pci_read32(struct ath11k_base
|
|
|
|
if (window_start == WINDOW_START) {
|
|
spin_lock_bh(&ab_pci->window_lock);
|
|
- ath11k_pci_select_window(ab_pci, offset);
|
|
+ ath11k_pci_select_window(ab, offset);
|
|
val = ioread32(ab->mem + window_start +
|
|
(offset & WINDOW_RANGE_MASK));
|
|
spin_unlock_bh(&ab_pci->window_lock);
|
|
@@ -216,11 +227,12 @@ u32 ath11k_pci_read32(struct ath11k_base
|
|
}
|
|
|
|
if (test_bit(ATH11K_PCI_FLAG_INIT_DONE, &ab_pci->flags) &&
|
|
- offset >= ACCESS_ALWAYS_OFF)
|
|
+ offset >= ACCESS_ALWAYS_OFF && ab_pci->mhi_ctrl)
|
|
mhi_device_put(ab_pci->mhi_ctrl->mhi_dev);
|
|
|
|
return val;
|
|
}
|
|
+EXPORT_SYMBOL(ath11k_pci_read32);
|
|
|
|
static void ath11k_pci_soc_global_reset(struct ath11k_base *ab)
|
|
{
|
|
@@ -415,15 +427,35 @@ static void ath11k_pci_sw_reset(struct a
|
|
ath11k_pci_clear_dbg_registers(ab);
|
|
}
|
|
|
|
-int ath11k_pci_get_msi_irq(struct device *dev, unsigned int vector)
|
|
+#define MAX_MSI_IRQS 32
|
|
+
|
|
+int ath11k_pci_get_qgic_msi_irq(struct ath11k_base *ab, unsigned int vector)
|
|
{
|
|
+ struct qgic2_msi *qgic2_msi = ab->ipci.qgic2_msi;
|
|
+
|
|
+ if (!qgic2_msi) {
|
|
+ ath11k_err(ab, "qgic2_msi is NULL\n");
|
|
+ return -EINVAL;
|
|
+ }
|
|
+
|
|
+ if (vector >= MAX_MSI_IRQS) {
|
|
+ ath11k_err(ab, "irq vector greater than MAX MSI IRQ\n");
|
|
+ return -EINVAL;
|
|
+ }
|
|
+ return qgic2_msi->msi[vector];
|
|
+}
|
|
+EXPORT_SYMBOL(ath11k_pci_get_qgic_msi_irq);
|
|
+
|
|
+int ath11k_pci_get_msi_irq(struct ath11k_base *ab, unsigned int vector)
|
|
+{
|
|
+ struct device *dev = ab->dev;
|
|
struct pci_dev *pci_dev = to_pci_dev(dev);
|
|
|
|
return pci_irq_vector(pci_dev, vector);
|
|
}
|
|
|
|
-static void ath11k_pci_get_msi_address(struct ath11k_base *ab, u32 *msi_addr_lo,
|
|
- u32 *msi_addr_hi)
|
|
+void ath11k_pci_get_msi_address(struct ath11k_base *ab, u32 *msi_addr_lo,
|
|
+ u32 *msi_addr_hi)
|
|
{
|
|
struct ath11k_pci *ab_pci = ath11k_pci_priv(ab);
|
|
struct pci_dev *pci_dev = to_pci_dev(ab->dev);
|
|
@@ -439,19 +471,33 @@ static void ath11k_pci_get_msi_address(s
|
|
}
|
|
}
|
|
|
|
-int ath11k_pci_get_user_msi_assignment(struct ath11k_pci *ab_pci, char *user_name,
|
|
+void ath11k_pci_get_qgic_msi_address(struct ath11k_base *ab, u32 *msi_addr_lo,
|
|
+ u32 *msi_addr_hi)
|
|
+{
|
|
+ struct qgic2_msi *qgic2_msi = ab->ipci.qgic2_msi;
|
|
+
|
|
+ if (!qgic2_msi) {
|
|
+ ath11k_err(ab, "qgic2_msi is NULL\n");
|
|
+ return;
|
|
+ }
|
|
+ *msi_addr_lo = qgic2_msi->msi_gicm_addr;
|
|
+ *msi_addr_hi = 0;
|
|
+}
|
|
+EXPORT_SYMBOL(ath11k_pci_get_qgic_msi_address);
|
|
+
|
|
+int ath11k_pci_get_user_msi_assignment(struct ath11k_base *ab,
|
|
+ struct ath11k_msi_config *msi_config,
|
|
+ u32 msi_ep_base_data, char *user_name,
|
|
int *num_vectors, u32 *user_base_data,
|
|
u32 *base_vector)
|
|
{
|
|
- struct ath11k_base *ab = ab_pci->ab;
|
|
- const struct ath11k_msi_config *msi_config = ab_pci->msi_config;
|
|
int idx;
|
|
|
|
for (idx = 0; idx < msi_config->total_users; idx++) {
|
|
if (strcmp(user_name, msi_config->users[idx].name) == 0) {
|
|
*num_vectors = msi_config->users[idx].num_vectors;
|
|
*user_base_data = msi_config->users[idx].base_vector
|
|
- + ab_pci->msi_ep_base_data;
|
|
+ + msi_ep_base_data;
|
|
*base_vector = msi_config->users[idx].base_vector;
|
|
|
|
ath11k_dbg(ab, ATH11K_DBG_PCI, "Assign MSI to user: %s, num_vectors: %d, user_base_data: %u, base_vector: %u\n",
|
|
@@ -467,8 +513,8 @@ int ath11k_pci_get_user_msi_assignment(s
|
|
return -EINVAL;
|
|
}
|
|
|
|
-static void ath11k_pci_get_ce_msi_idx(struct ath11k_base *ab, u32 ce_id,
|
|
- u32 *msi_idx)
|
|
+void ath11k_pci_get_ce_msi_idx(struct ath11k_base *ab, u32 ce_id,
|
|
+ u32 *msi_idx)
|
|
{
|
|
u32 i, msi_data_idx;
|
|
|
|
@@ -483,18 +529,35 @@ static void ath11k_pci_get_ce_msi_idx(st
|
|
}
|
|
*msi_idx = msi_data_idx;
|
|
}
|
|
+EXPORT_SYMBOL(ath11k_pci_get_ce_msi_idx);
|
|
|
|
-static int ath11k_get_user_msi_assignment(struct ath11k_base *ab, char *user_name,
|
|
- int *num_vectors, u32 *user_base_data,
|
|
+int ath11k_get_user_msi_assignment(struct ath11k_base *ab, char *user_name,
|
|
+ int *num_vectors, u32 *user_base_data,
|
|
u32 *base_vector)
|
|
{
|
|
struct ath11k_pci *ab_pci = ath11k_pci_priv(ab);
|
|
|
|
- return ath11k_pci_get_user_msi_assignment(ab_pci, user_name,
|
|
+ return ath11k_pci_get_user_msi_assignment(ab, ab_pci->msi_config,
|
|
+ ab_pci->msi_ep_base_data, user_name,
|
|
num_vectors, user_base_data,
|
|
base_vector);
|
|
+
|
|
}
|
|
|
|
+int ath11k_get_user_qgic_msi_assignment(struct ath11k_base *ab, char *user_name,
|
|
+ int *num_vectors, u32 *user_base_data,
|
|
+ u32 *base_vector)
|
|
+{
|
|
+ struct qgic2_msi *qgic2_msi = ab->ipci.qgic2_msi;
|
|
+ struct ath11k_msi_config *msi_cfg = ab->ipci.msi_cfg;
|
|
+
|
|
+ return ath11k_pci_get_user_msi_assignment(ab, msi_cfg,
|
|
+ qgic2_msi->msi_gicm_base, user_name,
|
|
+ num_vectors, user_base_data,
|
|
+ base_vector);
|
|
+}
|
|
+EXPORT_SYMBOL(ath11k_get_user_qgic_msi_assignment);
|
|
+
|
|
const char *dp_irq_name[ATH11K_MAX_PCI_DOMAINS + 1][ATH11K_EXT_IRQ_GRP_NUM_MAX] = {
|
|
{
|
|
ATH11K_PCI_DP_IRQS_NAME(0)
|
|
@@ -521,7 +584,7 @@ static void ath11k_pci_free_ext_irq(stru
|
|
}
|
|
}
|
|
|
|
-static void ath11k_pci_free_irq(struct ath11k_base *ab)
|
|
+void ath11k_pci_free_irq(struct ath11k_base *ab)
|
|
{
|
|
int i, irq_idx;
|
|
|
|
@@ -534,6 +597,7 @@ static void ath11k_pci_free_irq(struct a
|
|
|
|
ath11k_pci_free_ext_irq(ab);
|
|
}
|
|
+EXPORT_SYMBOL(ath11k_pci_free_irq);
|
|
|
|
static void ath11k_pci_ce_irq_enable(struct ath11k_base *ab, u16 ce_id)
|
|
{
|
|
@@ -628,7 +692,7 @@ static void ath11k_pci_ext_grp_enable(st
|
|
enable_irq(irq_grp->ab->irq_num[irq_grp->irqs[i]]);
|
|
}
|
|
|
|
-static void ath11k_pci_ext_irq_enable(struct ath11k_base *ab)
|
|
+void ath11k_pci_ext_irq_enable(struct ath11k_base *ab)
|
|
{
|
|
int i;
|
|
|
|
@@ -639,6 +703,7 @@ static void ath11k_pci_ext_irq_enable(st
|
|
ath11k_pci_ext_grp_enable(irq_grp);
|
|
}
|
|
}
|
|
+EXPORT_SYMBOL(ath11k_pci_ext_irq_enable);
|
|
|
|
static void ath11k_pci_sync_ext_irqs(struct ath11k_base *ab)
|
|
{
|
|
@@ -654,11 +719,12 @@ static void ath11k_pci_sync_ext_irqs(str
|
|
}
|
|
}
|
|
|
|
-static void ath11k_pci_ext_irq_disable(struct ath11k_base *ab)
|
|
+void ath11k_pci_ext_irq_disable(struct ath11k_base *ab)
|
|
{
|
|
__ath11k_pci_ext_irq_disable(ab);
|
|
ath11k_pci_sync_ext_irqs(ab);
|
|
}
|
|
+EXPORT_SYMBOL(ath11k_pci_ext_irq_disable);
|
|
|
|
static int ath11k_pci_ext_grp_napi_poll(struct napi_struct *napi, int budget)
|
|
{
|
|
@@ -696,20 +762,34 @@ static irqreturn_t ath11k_pci_ext_interr
|
|
return IRQ_HANDLED;
|
|
}
|
|
|
|
-static int ath11k_pci_ext_irq_config(struct ath11k_base *ab)
|
|
+static int ath11k_pci_get_domain_id(struct ath11k_base *ab)
|
|
{
|
|
- int i, j, ret, num_vectors = 0;
|
|
- u32 user_base_data = 0, base_vector = 0, base_idx;
|
|
- struct ath11k_pci *ar_pci = ath11k_pci_priv(ab);
|
|
- u8 domain_id = pci_domain_nr(ar_pci->pdev->bus);
|
|
+ u8 domain_id;
|
|
+ struct ath11k_pci *ab_pci = ath11k_pci_priv(ab);
|
|
+
|
|
+ if (ab->userpd_id)
|
|
+ domain_id = ab->userpd_id;
|
|
+ else
|
|
+ domain_id = pci_domain_nr(ab_pci->pdev->bus);
|
|
|
|
if (domain_id > ATH11K_MAX_PCI_DOMAINS)
|
|
domain_id = ATH11K_MAX_PCI_DOMAINS;
|
|
|
|
+ return domain_id;
|
|
+}
|
|
+
|
|
+static int ath11k_pci_ext_irq_config(struct ath11k_base *ab,
|
|
+ struct ath11k_msi_config *msi_config,
|
|
+ u32 msi_ep_base_data)
|
|
+{
|
|
+ int i, j, ret, num_vectors = 0;
|
|
+ u32 user_base_data = 0, base_vector = 0, base_idx;
|
|
+ u8 domain_id;
|
|
+
|
|
+ domain_id = ath11k_pci_get_domain_id(ab);
|
|
base_idx = ATH11K_PCI_IRQ_CE0_OFFSET + CE_COUNT_MAX;
|
|
- ret = ath11k_pci_get_user_msi_assignment(ath11k_pci_priv(ab), "DP",
|
|
- &num_vectors,
|
|
- &user_base_data,
|
|
+ ret = ath11k_pci_get_user_msi_assignment(ab, msi_config, msi_ep_base_data,
|
|
+ "DP", &num_vectors, &user_base_data,
|
|
&base_vector);
|
|
if (ret < 0)
|
|
return ret;
|
|
@@ -746,7 +826,7 @@ static int ath11k_pci_ext_irq_config(str
|
|
for (j = 0; j < irq_grp->num_irq; j++) {
|
|
int irq_idx = irq_grp->irqs[j];
|
|
int vector = (i % num_vectors) + base_vector;
|
|
- int irq = ath11k_pci_get_msi_irq(ab->dev, vector);
|
|
+ int irq = ath11k_hif_get_msi_irq(ab, vector);
|
|
|
|
ab->irq_num[irq_idx] = irq;
|
|
|
|
@@ -770,21 +850,19 @@ static int ath11k_pci_ext_irq_config(str
|
|
return 0;
|
|
}
|
|
|
|
-static int ath11k_pci_config_irq(struct ath11k_base *ab)
|
|
+static int ath11k_config_msi_irq(struct ath11k_base *ab,
|
|
+ struct ath11k_msi_config *msi_config, u32 msi_ep_base_data)
|
|
{
|
|
struct ath11k_ce_pipe *ce_pipe;
|
|
u32 msi_data_start;
|
|
u32 msi_data_count, msi_data_idx;
|
|
u32 msi_irq_start;
|
|
unsigned int msi_data;
|
|
- int irq, i, ret, irq_idx;
|
|
- struct ath11k_pci *ar_pci = ath11k_pci_priv(ab);
|
|
- u8 domain_id = pci_domain_nr(ar_pci->pdev->bus);
|
|
+ int irq, i, ret = 0, irq_idx;
|
|
+ u8 domain_id;
|
|
|
|
- if (domain_id > ATH11K_MAX_PCI_DOMAINS)
|
|
- domain_id = ATH11K_MAX_PCI_DOMAINS;
|
|
-
|
|
- ret = ath11k_pci_get_user_msi_assignment(ath11k_pci_priv(ab),
|
|
+ domain_id = ath11k_pci_get_domain_id(ab);
|
|
+ ret = ath11k_pci_get_user_msi_assignment(ab, msi_config, msi_ep_base_data,
|
|
"CE", &msi_data_count,
|
|
&msi_data_start, &msi_irq_start);
|
|
if (ret)
|
|
@@ -796,7 +874,7 @@ static int ath11k_pci_config_irq(struct
|
|
continue;
|
|
|
|
msi_data = (msi_data_idx % msi_data_count) + msi_irq_start;
|
|
- irq = ath11k_pci_get_msi_irq(ab->dev, msi_data);
|
|
+ irq = ath11k_hif_get_msi_irq(ab, msi_data);
|
|
ce_pipe = &ab->ce.ce_pipe[i];
|
|
|
|
irq_idx = ATH11K_PCI_IRQ_CE0_OFFSET + i;
|
|
@@ -818,13 +896,22 @@ static int ath11k_pci_config_irq(struct
|
|
ath11k_pci_ce_irq_disable(ab, i);
|
|
}
|
|
|
|
- ret = ath11k_pci_ext_irq_config(ab);
|
|
+ ret = ath11k_pci_ext_irq_config(ab, msi_config, msi_ep_base_data);
|
|
if (ret)
|
|
return ret;
|
|
|
|
return 0;
|
|
}
|
|
|
|
+static int ath11k_pci_config_irq(struct ath11k_base *ab)
|
|
+{
|
|
+ int ret;
|
|
+ struct ath11k_pci *ab_pci = ath11k_pci_priv(ab);
|
|
+
|
|
+ ret = ath11k_config_msi_irq(ab, ab_pci->msi_config, ab_pci->msi_ep_base_data);
|
|
+ return ret;
|
|
+}
|
|
+
|
|
static void ath11k_pci_init_qmi_ce_config(struct ath11k_base *ab)
|
|
{
|
|
struct ath11k_qmi_ce_cfg *cfg = &ab->qmi.ce_cfg;
|
|
@@ -1034,7 +1121,7 @@ static int ath11k_pci_power_up(struct at
|
|
}
|
|
|
|
if (ab->bus_params.static_window_map)
|
|
- ath11k_pci_select_static_window(ab_pci);
|
|
+ ath11k_pci_select_static_window(ab);
|
|
|
|
return 0;
|
|
}
|
|
@@ -1091,13 +1178,23 @@ static void ath11k_pci_ce_irq_disable_sy
|
|
ath11k_pci_kill_tasklets(ab);
|
|
}
|
|
|
|
-static void ath11k_pci_stop(struct ath11k_base *ab)
|
|
+void ath11k_pci_stop(struct ath11k_base *ab)
|
|
{
|
|
ath11k_pci_ce_irq_disable_sync(ab);
|
|
ath11k_ce_cleanup_pipes(ab);
|
|
}
|
|
+EXPORT_SYMBOL(ath11k_pci_stop);
|
|
|
|
-static int ath11k_pci_start(struct ath11k_base *ab)
|
|
+int ath11k_ipci_start(struct ath11k_base *ab)
|
|
+{
|
|
+ ath11k_pci_ce_irqs_enable(ab);
|
|
+ ath11k_ce_rx_post_buf(ab);
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+EXPORT_SYMBOL(ath11k_ipci_start);
|
|
+
|
|
+int ath11k_pci_start(struct ath11k_base *ab)
|
|
{
|
|
struct ath11k_pci *ab_pci = ath11k_pci_priv(ab);
|
|
|
|
@@ -1110,6 +1207,7 @@ static int ath11k_pci_start(struct ath11
|
|
|
|
return 0;
|
|
}
|
|
+EXPORT_SYMBOL(ath11k_pci_start);
|
|
|
|
static void ath11k_pci_hif_ce_irq_enable(struct ath11k_base *ab)
|
|
{
|
|
@@ -1121,7 +1219,14 @@ static void ath11k_pci_hif_ce_irq_disabl
|
|
ath11k_pci_ce_irq_disable_sync(ab);
|
|
}
|
|
|
|
-static int ath11k_pci_map_service_to_pipe(struct ath11k_base *ab, u16 service_id,
|
|
+void ath11k_pci_config_static_window(struct ath11k_base *ab)
|
|
+{
|
|
+ if (ab->bus_params.static_window_map)
|
|
+ ath11k_pci_select_static_window(ab);
|
|
+}
|
|
+EXPORT_SYMBOL(ath11k_pci_config_static_window);
|
|
+
|
|
+int ath11k_pci_map_service_to_pipe(struct ath11k_base *ab, u16 service_id,
|
|
u8 *ul_pipe, u8 *dl_pipe)
|
|
{
|
|
const struct service_to_pipe *entry;
|
|
@@ -1163,6 +1268,7 @@ static int ath11k_pci_map_service_to_pip
|
|
|
|
return 0;
|
|
}
|
|
+EXPORT_SYMBOL(ath11k_pci_map_service_to_pipe);
|
|
|
|
static const struct ath11k_hif_ops ath11k_pci_hif_ops = {
|
|
.start = ath11k_pci_start,
|
|
@@ -1182,8 +1288,23 @@ static const struct ath11k_hif_ops ath11
|
|
.ce_irq_disable = ath11k_pci_hif_ce_irq_disable,
|
|
.get_window_offset = ath11k_pci_get_window_offset,
|
|
.get_ce_msi_idx = ath11k_pci_get_ce_msi_idx,
|
|
+ .config_static_window = ath11k_pci_config_static_window,
|
|
+ .free_irq = ath11k_pci_free_irq,
|
|
+ .get_msi_irq = ath11k_pci_get_msi_irq,
|
|
};
|
|
|
|
+int ath11k_pci_config_qgic_msi_irq(struct ath11k_base *ab)
|
|
+{
|
|
+ int ret = 0;
|
|
+ struct qgic2_msi *qgic2_msi = ab->ipci.qgic2_msi;
|
|
+ struct ath11k_msi_config *msi_cfg = ab->ipci.msi_cfg;
|
|
+
|
|
+ ret = ath11k_config_msi_irq(ab, msi_cfg,
|
|
+ qgic2_msi->msi_gicm_base);
|
|
+ return ret;
|
|
+}
|
|
+EXPORT_SYMBOL(ath11k_pci_config_qgic_msi_irq);
|
|
+
|
|
static int ath11k_pci_probe(struct pci_dev *pdev,
|
|
const struct pci_device_id *pci_dev)
|
|
{
|
|
@@ -1246,10 +1367,10 @@ static int ath11k_pci_probe(struct pci_d
|
|
ret = -EOPNOTSUPP;
|
|
goto err_pci_free_region;
|
|
}
|
|
- ab_pci->msi_config = &ath11k_msi_config[0];
|
|
+ ab_pci->msi_config = &ath11k_msi_config[ATH11K_MSI_CONFIG_QCA6390];
|
|
break;
|
|
case QCN9074_DEVICE_ID:
|
|
- ab_pci->msi_config = &ath11k_msi_config[1];
|
|
+ ab_pci->msi_config = &ath11k_msi_config[ATH11K_MSI_CONFIG_QCN9074];
|
|
ab->bus_params.static_window_map = true;
|
|
ab->hw_rev = ATH11K_HW_QCN9074_HW10;
|
|
ab->enable_cold_boot_cal = ath11k_cold_boot_cal;
|
|
@@ -1304,7 +1425,7 @@ static int ath11k_pci_probe(struct pci_d
|
|
return 0;
|
|
|
|
err_free_irq:
|
|
- ath11k_pci_free_irq(ab);
|
|
+ ath11k_hif_free_irq(ab);
|
|
|
|
err_ce_free:
|
|
ath11k_ce_free_pipes(ab);
|
|
@@ -1347,7 +1468,7 @@ static void ath11k_pci_remove(struct pci
|
|
qmi_fail:
|
|
ath11k_mhi_unregister(ab_pci);
|
|
|
|
- ath11k_pci_free_irq(ab);
|
|
+ ath11k_hif_free_irq(ab);
|
|
ath11k_pci_disable_msi(ab_pci);
|
|
ath11k_pci_free_region(ab_pci);
|
|
|
|
--- a/drivers/net/wireless/ath/ath11k/pci.h
|
|
+++ b/drivers/net/wireless/ath/ath11k/pci.h
|
|
@@ -101,6 +101,42 @@ enum ath11k_pci_flags {
|
|
ATH11K_PCI_ASPM_RESTORE,
|
|
};
|
|
|
|
+enum ath11k_msi_supported_hw {
|
|
+ ATH11K_MSI_CONFIG_QCA6390,
|
|
+ ATH11K_MSI_CONFIG_QCN9074,
|
|
+ ATH11K_MSI_CONFIG_QCN6122,
|
|
+};
|
|
+
|
|
+static const struct ath11k_msi_config ath11k_msi_config[] = {
|
|
+ {
|
|
+ .total_vectors = 32,
|
|
+ .total_users = 4,
|
|
+ .users = (struct ath11k_msi_user[]) {
|
|
+ { .name = "MHI", .num_vectors = 3, .base_vector = 0 },
|
|
+ { .name = "CE", .num_vectors = 10, .base_vector = 3 },
|
|
+ { .name = "WAKE", .num_vectors = 1, .base_vector = 13 },
|
|
+ { .name = "DP", .num_vectors = 18, .base_vector = 14 },
|
|
+ },
|
|
+ },
|
|
+ {
|
|
+ .total_vectors = 16,
|
|
+ .total_users = 3,
|
|
+ .users = (struct ath11k_msi_user[]) {
|
|
+ { .name = "MHI", .num_vectors = 3, .base_vector = 0 },
|
|
+ { .name = "CE", .num_vectors = 5, .base_vector = 3 },
|
|
+ { .name = "DP", .num_vectors = 8, .base_vector = 8 },
|
|
+ },
|
|
+ },
|
|
+ {
|
|
+ .total_vectors = 13,
|
|
+ .total_users = 2,
|
|
+ .users = (struct ath11k_msi_user[]) {
|
|
+ { .name = "CE", .num_vectors = 5, .base_vector = 0 },
|
|
+ { .name = "DP", .num_vectors = 8, .base_vector = 5 },
|
|
+ },
|
|
+ },
|
|
+};
|
|
+
|
|
struct ath11k_pci {
|
|
struct pci_dev *pdev;
|
|
struct ath11k_base *ab;
|
|
@@ -125,11 +161,34 @@ static inline struct ath11k_pci *ath11k_
|
|
return (struct ath11k_pci *)ab->drv_priv;
|
|
}
|
|
|
|
-int ath11k_pci_get_user_msi_assignment(struct ath11k_pci *ar_pci, char *user_name,
|
|
+int ath11k_pci_get_user_msi_assignment(struct ath11k_base *ab,
|
|
+ struct ath11k_msi_config *msi_config,
|
|
+ u32 msi_ep_base_data, char *user_name,
|
|
int *num_vectors, u32 *user_base_data,
|
|
u32 *base_vector);
|
|
-int ath11k_pci_get_msi_irq(struct device *dev, unsigned int vector);
|
|
+int ath11k_pci_get_msi_irq(struct ath11k_base *ab, unsigned int vector);
|
|
void ath11k_pci_write32(struct ath11k_base *ab, u32 offset, u32 value);
|
|
u32 ath11k_pci_read32(struct ath11k_base *ab, u32 offset);
|
|
-
|
|
+int ath11k_pci_config_qgic_msi_irq(struct ath11k_base *ab);
|
|
+int ath11k_pci_start(struct ath11k_base *ab);
|
|
+void ath11k_pci_stop(struct ath11k_base *ab);
|
|
+void ath11k_pci_ext_irq_enable(struct ath11k_base *ab);
|
|
+void ath11k_pci_ext_irq_disable(struct ath11k_base *ab);
|
|
+void ath11k_pci_get_qgic_msi_address(struct ath11k_base *ab, u32 *msi_addr_lo,
|
|
+ u32 *msi_addr_hi);
|
|
+int ath11k_get_user_qgic_msi_assignment(struct ath11k_base *ab, char *user_name,
|
|
+ int *num_vectors, u32 *user_base_data,
|
|
+ u32 *base_vector);
|
|
+int ath11k_pci_map_service_to_pipe(struct ath11k_base *ab, u16 service_id,
|
|
+ u8 *ul_pipe, u8 *dl_pipe);
|
|
+u32 ath11k_pci_get_window_offset(struct ath11k_base *ab,
|
|
+ u32 offset);
|
|
+void ath11k_pci_get_ce_msi_idx(struct ath11k_base *ab, u32 ce_id,
|
|
+ u32 *msi_idx);
|
|
+void ath11k_pci_config_static_window(struct ath11k_base *ab);
|
|
+void ath11k_pci_free_irq(struct ath11k_base *ab);
|
|
+int ath11k_pci_get_qgic_msi_irq(struct ath11k_base *ab, unsigned int vector);
|
|
+int ath11k_ipci_start(struct ath11k_base *ab);
|
|
+void ath11k_ipci_write32(struct ath11k_base *ab, u32 offset, u32 value);
|
|
+u32 ath11k_ipci_read32(struct ath11k_base *ab, u32 offset);
|
|
#endif
|
|
--- a/drivers/net/wireless/ath/ath11k/qmi.c
|
|
+++ b/drivers/net/wireless/ath/ath11k/qmi.c
|
|
@@ -1060,6 +1060,68 @@ static struct qmi_elem_info qmi_wlanfw_c
|
|
},
|
|
};
|
|
|
|
+static struct qmi_elem_info qmi_wlanfw_device_info_req_msg_v01_ei[] = {
|
|
+ {
|
|
+ .data_type = QMI_EOTI,
|
|
+ .array_type = NO_ARRAY,
|
|
+ .tlv_type = QMI_COMMON_TLV_TYPE,
|
|
+ },
|
|
+};
|
|
+
|
|
+struct qmi_elem_info qmi_wlanfw_device_info_resp_msg_v01_ei[] = {
|
|
+ {
|
|
+ .data_type = QMI_STRUCT,
|
|
+ .elem_len = 1,
|
|
+ .elem_size = sizeof(struct qmi_response_type_v01),
|
|
+ .array_type = NO_ARRAY,
|
|
+ .tlv_type = 0x02,
|
|
+ .offset = offsetof(struct qmi_wlanfw_device_info_resp_msg_v01,
|
|
+ resp),
|
|
+ .ei_array = qmi_response_type_v01_ei,
|
|
+ },
|
|
+ {
|
|
+ .data_type = QMI_OPT_FLAG,
|
|
+ .elem_len = 1,
|
|
+ .elem_size = sizeof(u8),
|
|
+ .array_type = NO_ARRAY,
|
|
+ .tlv_type = 0x10,
|
|
+ .offset = offsetof(struct qmi_wlanfw_device_info_resp_msg_v01,
|
|
+ bar_addr_valid),
|
|
+ },
|
|
+ {
|
|
+ .data_type = QMI_UNSIGNED_8_BYTE,
|
|
+ .elem_len = 1,
|
|
+ .elem_size = sizeof(u64),
|
|
+ .array_type = NO_ARRAY,
|
|
+ .tlv_type = 0x10,
|
|
+ .offset = offsetof(struct qmi_wlanfw_device_info_resp_msg_v01,
|
|
+ bar_addr),
|
|
+ },
|
|
+ {
|
|
+ .data_type = QMI_OPT_FLAG,
|
|
+ .elem_len = 1,
|
|
+ .elem_size = sizeof(u8),
|
|
+ .array_type = NO_ARRAY,
|
|
+ .tlv_type = 0x11,
|
|
+ .offset = offsetof(struct qmi_wlanfw_device_info_resp_msg_v01,
|
|
+ bar_size_valid),
|
|
+ },
|
|
+ {
|
|
+ .data_type = QMI_UNSIGNED_4_BYTE,
|
|
+ .elem_len = 1,
|
|
+ .elem_size = sizeof(u32),
|
|
+ .array_type = NO_ARRAY,
|
|
+ .tlv_type = 0x11,
|
|
+ .offset = offsetof(struct qmi_wlanfw_device_info_resp_msg_v01,
|
|
+ bar_size),
|
|
+ },
|
|
+ {
|
|
+ .data_type = QMI_EOTI,
|
|
+ .array_type = NO_ARRAY,
|
|
+ .tlv_type = QMI_COMMON_TLV_TYPE,
|
|
+ },
|
|
+};
|
|
+
|
|
static struct qmi_elem_info qmi_wlanfw_rf_chip_info_s_v01_ei[] = {
|
|
{
|
|
.data_type = QMI_UNSIGNED_4_BYTE,
|
|
@@ -2717,6 +2779,7 @@ static int ath11k_qmi_assign_target_mem_
|
|
struct device *dev = ab->dev;
|
|
int i, idx;
|
|
u32 addr = 0;
|
|
+ u32 location[3];
|
|
|
|
for (i = 0, idx = 0; i < ab->qmi.mem_seg_count; i++) {
|
|
switch (ab->qmi.target_mem[i].type) {
|
|
@@ -2743,6 +2806,10 @@ static int ath11k_qmi_assign_target_mem_
|
|
idx++;
|
|
break;
|
|
case BDF_MEM_REGION_TYPE:
|
|
+ if (!of_property_read_u32_array(dev->of_node, "qcom,bdf-addr", location,
|
|
+ ARRAY_SIZE(location))) {
|
|
+ ab->hw_params.bdf_addr = location[ab->qmi.target_mem_mode];
|
|
+ }
|
|
ab->qmi.target_mem[idx].paddr = ab->hw_params.bdf_addr;
|
|
ab->qmi.target_mem[idx].vaddr = NULL;
|
|
ab->qmi.target_mem[idx].size = ab->qmi.target_mem[i].size;
|
|
@@ -2762,7 +2829,8 @@ static int ath11k_qmi_assign_target_mem_
|
|
ath11k_warn(ab, "qmi fail to get caldb-addr in dt\n");
|
|
}
|
|
|
|
- if (!ab->enable_cold_boot_cal) {
|
|
+ if (!ab->enable_cold_boot_cal ||
|
|
+ !ab->hw_params.cold_boot_calib) {
|
|
ab->qmi.target_mem[idx].paddr = 0;
|
|
ab->qmi.target_mem[idx].vaddr = NULL;
|
|
} else {
|
|
@@ -2813,6 +2881,86 @@ static int ath11k_qmi_assign_target_mem_
|
|
return 0;
|
|
}
|
|
|
|
+static int ath11k_qmi_request_device_info(struct ath11k_base *ab)
|
|
+{
|
|
+ struct qmi_wlanfw_device_info_req_msg_v01 req;
|
|
+ struct qmi_wlanfw_device_info_resp_msg_v01 resp;
|
|
+ struct qmi_txn txn = {};
|
|
+ void *bar_addr_va = NULL;
|
|
+ int ret = 0;
|
|
+
|
|
+ /*device info message only supported for internal-PCI devices */
|
|
+ if (ab->hw_rev != ATH11K_HW_QCN6122)
|
|
+ return 0;
|
|
+
|
|
+ memset(&req, 0, sizeof(req));
|
|
+ memset(&resp, 0, sizeof(resp));
|
|
+
|
|
+ ret = qmi_txn_init(&ab->qmi.handle, &txn,
|
|
+ qmi_wlanfw_device_info_resp_msg_v01_ei, &resp);
|
|
+ if (ret < 0)
|
|
+ goto out;
|
|
+
|
|
+ ret = qmi_send_request(&ab->qmi.handle, NULL, &txn,
|
|
+ QMI_WLANFW_DEVICE_INFO_REQ_V01,
|
|
+ QMI_WLANFW_DEVICE_INFO_REQ_MSG_V01,
|
|
+ qmi_wlanfw_device_info_req_msg_v01_ei, &req);
|
|
+ if (ret < 0) {
|
|
+ ath11k_warn(ab, "qmi failed to send target device info request, err = %d\n",
|
|
+ ret);
|
|
+ goto out;
|
|
+ }
|
|
+
|
|
+ ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH11K_QMI_WLANFW_TIMEOUT_MS));
|
|
+ if (ret < 0) {
|
|
+ ath11k_warn(ab, "qmi failed target device info request %d\n", ret);
|
|
+ goto out;
|
|
+ }
|
|
+
|
|
+ if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
|
|
+ ath11k_warn(ab, "qmi device info req failed, result: %d, err: %d\n",
|
|
+ resp.resp.result, resp.resp.error);
|
|
+ ret = -EINVAL;
|
|
+ goto out;
|
|
+ }
|
|
+
|
|
+ if (!resp.bar_addr_valid || !resp.bar_size_valid) {
|
|
+ ath11k_warn(ab, "qmi device info response invalid, result: %d, err: %d\n",
|
|
+ resp.resp.result, resp.resp.error);
|
|
+ ret = -EINVAL;
|
|
+ goto out;
|
|
+ }
|
|
+ if (!resp.bar_addr ||
|
|
+ resp.bar_size != QCN6122_DEVICE_BAR_SIZE) {
|
|
+ ath11k_warn(ab, "qmi device info invalid addr and size, result: %d, err: %d\n",
|
|
+ resp.resp.result, resp.resp.error);
|
|
+ ret = -EINVAL;
|
|
+ goto out;
|
|
+ }
|
|
+
|
|
+ bar_addr_va = ioremap_nocache(resp.bar_addr, resp.bar_size);
|
|
+
|
|
+ if (!bar_addr_va) {
|
|
+ ath11k_warn(ab, "qmi device info ioremap failed\n");
|
|
+ ab->mem_pa = 0;
|
|
+ ab->mem_len = 0;
|
|
+ ret = -EIO;
|
|
+ goto out;
|
|
+ }
|
|
+
|
|
+ ab->mem = bar_addr_va;
|
|
+ ab->mem_pa = resp.bar_addr;
|
|
+ ab->mem_len = resp.bar_size;
|
|
+
|
|
+ ath11k_dbg(ab, ATH11K_DBG_QMI, "Device BAR Info pa: 0x%llx, va: 0x%p, size: 0x%lx\n",
|
|
+ (u64)ab->mem_pa, ab->mem, ab->mem_len);
|
|
+
|
|
+ ath11k_hif_config_static_window(ab);
|
|
+ return 0;
|
|
+out:
|
|
+ return ret;
|
|
+}
|
|
+
|
|
static int ath11k_qmi_request_target_cap(struct ath11k_base *ab)
|
|
{
|
|
struct device *dev = ab->dev;
|
|
@@ -3040,6 +3188,12 @@ static int ath11k_qmi_load_bdf_qmi(struc
|
|
if(ab->bus_params.fixed_bdf_addr) {
|
|
snprintf(filename, sizeof(filename),
|
|
"%s", ATH11K_DEFAULT_CAL_FILE);
|
|
+ if (ab->userpd_id) {
|
|
+ snprintf(filename, sizeof(filename), "%s%d%s",
|
|
+ ATH11K_QMI_DEF_CAL_FILE_PREFIX,
|
|
+ ab->userpd_id,
|
|
+ ATH11K_QMI_DEF_CAL_FILE_SUFFIX);
|
|
+ }
|
|
} else {
|
|
snprintf(filename, sizeof(filename),
|
|
"%s%d%s",
|
|
@@ -3382,7 +3536,8 @@ int ath11k_qmi_fwreset_from_cold_boot(st
|
|
{
|
|
int timeout;
|
|
|
|
- if (ab->enable_cold_boot_cal == 0 || ab->qmi.cal_done)
|
|
+ if (ab->enable_cold_boot_cal == 0 || ab->qmi.cal_done ||
|
|
+ ab->hw_params.cold_boot_calib == 0)
|
|
return 0;
|
|
|
|
ath11k_dbg(ab, ATH11K_DBG_QMI, "wait for cold boot done\n");
|
|
@@ -3658,6 +3813,25 @@ int ath11k_qmi_pci_alloc_qdss_mem(struct
|
|
return 0;
|
|
}
|
|
|
|
+static
|
|
+struct device_node *ath11k_get_etr_dev_node(struct ath11k_base *ab)
|
|
+{
|
|
+ struct device_node *dev_node = NULL;
|
|
+
|
|
+ if (ab->userpd_id) {
|
|
+ if (ab->userpd_id == QCN6122_USERPD_0)
|
|
+ dev_node = of_find_node_by_name(NULL,
|
|
+ "q6_qcn6122_etr_1");
|
|
+ else if (ab->userpd_id == QCN6122_USERPD_1)
|
|
+ dev_node = of_find_node_by_name(NULL,
|
|
+ "q6_qcn6122_etr_2");
|
|
+ } else {
|
|
+ dev_node = of_find_node_by_name(NULL, "q6_etr_dump");
|
|
+ }
|
|
+
|
|
+ return dev_node;
|
|
+}
|
|
+
|
|
int ath11k_qmi_qdss_mem_alloc(struct ath11k_qmi *qmi)
|
|
{
|
|
int ret, i;
|
|
@@ -3666,7 +3840,7 @@ int ath11k_qmi_qdss_mem_alloc(struct ath
|
|
struct resource q6_etr;
|
|
|
|
if (ab->bus_params.fixed_bdf_addr) {
|
|
- dev_node = of_find_node_by_name(NULL, "q6_etr_dump");
|
|
+ dev_node = ath11k_get_etr_dev_node(ab);
|
|
if (!dev_node) {
|
|
ath11k_err(ab, "No q6_etr_dump available in dts\n");
|
|
return -ENOMEM;
|
|
@@ -3681,6 +3855,19 @@ int ath11k_qmi_qdss_mem_alloc(struct ath
|
|
ab->qmi.qdss_mem[i].paddr = q6_etr.start;
|
|
ab->qmi.qdss_mem[i].size = resource_size(&q6_etr);
|
|
ab->qmi.qdss_mem[i].type = QDSS_ETR_MEM_REGION_TYPE;
|
|
+ if (ab->hw_rev == ATH11K_HW_QCN6122) {
|
|
+ ab->qmi.qdss_mem[i].vaddr =
|
|
+ ioremap(ab->qmi.qdss_mem[i].paddr,
|
|
+ ab->qmi.qdss_mem[i].size);
|
|
+ if (!ab->qmi.qdss_mem[i].vaddr) {
|
|
+ ath11k_err(ab, "Error: etr-addr remap failed\n");
|
|
+ return -ENOMEM;
|
|
+ }
|
|
+ }
|
|
+ ath11k_dbg(ab, ATH11K_DBG_QMI, "QDSS mem addr pa 0x%x va 0x%p, size 0x%x",
|
|
+ (unsigned int)ab->qmi.qdss_mem[i].paddr,
|
|
+ ab->qmi.qdss_mem[i].vaddr,
|
|
+ (unsigned int)ab->qmi.qdss_mem[i].size);
|
|
}
|
|
} else {
|
|
ret = ath11k_qmi_pci_alloc_qdss_mem(qmi);
|
|
@@ -3791,6 +3978,12 @@ static int ath11k_qmi_event_load_bdf(str
|
|
return ret;
|
|
}
|
|
|
|
+ ret = ath11k_qmi_request_device_info(ab);
|
|
+ if (ret < 0) {
|
|
+ ath11k_warn(ab, "qmi failed to req device info %d\n", ret);
|
|
+ return ret;
|
|
+ }
|
|
+
|
|
ret = ath11k_qmi_load_bdf_qmi(ab);
|
|
if (ret < 0) {
|
|
ath11k_warn(ab, "qmi failed to load board data file:%d\n", ret);
|
|
@@ -4211,6 +4404,23 @@ static const struct qmi_ops ath11k_qmi_o
|
|
.del_server = ath11k_qmi_ops_del_server,
|
|
};
|
|
|
|
+static int ath11k_wait_for_qgic_msi(struct ath11k_base *ab)
|
|
+{
|
|
+ int timeout;
|
|
+
|
|
+ if (ab->hw_rev != ATH11K_HW_QCN6122)
|
|
+ return 0;
|
|
+
|
|
+ timeout = wait_event_timeout(ab->ipci.qgic_msi_waitq,
|
|
+ (ab->ipci.qgic_enabled == 1),
|
|
+ ATH11K_RCV_QGIC_MSI_HDLR_DELAY);
|
|
+ if (timeout <= 0) {
|
|
+ ath11k_warn(ab, "Receive qgic msi handler timed out\n");
|
|
+ return -ETIMEDOUT;
|
|
+ }
|
|
+ return 0;
|
|
+}
|
|
+
|
|
static void ath11k_qmi_driver_event_work(struct work_struct *work)
|
|
{
|
|
struct ath11k_qmi *qmi = container_of(work, struct ath11k_qmi,
|
|
@@ -4264,6 +4474,14 @@ static void ath11k_qmi_driver_event_work
|
|
clear_bit(ATH11K_FLAG_CRASH_FLUSH,
|
|
&ab->dev_flags);
|
|
clear_bit(ATH11K_FLAG_RECOVERY, &ab->dev_flags);
|
|
+ ret = ath11k_wait_for_qgic_msi(ab);
|
|
+ if (ret) {
|
|
+ ath11k_warn(ab,
|
|
+ "Failed to get qgic handler for dev %d ret: %d\n",
|
|
+ ab->hw_rev, ret);
|
|
+ break;
|
|
+ }
|
|
+
|
|
ath11k_core_qmi_firmware_ready(ab);
|
|
set_bit(ATH11K_FLAG_REGISTERED, &ab->dev_flags);
|
|
}
|
|
@@ -4385,7 +4603,7 @@ int ath11k_qmi_init_service(struct ath11
|
|
destroy_workqueue(ab->qmi.event_wq);
|
|
return ret;
|
|
}
|
|
-
|
|
+ init_waitqueue_head(&ab->ipci.qgic_msi_waitq);
|
|
return ret;
|
|
}
|
|
|
|
--- a/drivers/net/wireless/ath/ath11k/qmi.h
|
|
+++ b/drivers/net/wireless/ath/ath11k/qmi.h
|
|
@@ -24,6 +24,7 @@
|
|
#define ATH11K_QMI_WLFW_SERVICE_INS_ID_V01_QCA6390 0x01
|
|
#define ATH11K_QMI_WLFW_SERVICE_INS_ID_V01_IPQ8074 0x02
|
|
#define ATH11K_QMI_WLFW_SERVICE_INS_ID_V01_QCN9074 0x07
|
|
+#define ATH11K_QMI_WLFW_SERVICE_INS_ID_V01_QCN6122 0x40
|
|
#define ATH11K_QMI_WLANFW_MAX_TIMESTAMP_LEN_V01 32
|
|
#define ATH11K_QMI_RESP_LEN_MAX 8192
|
|
#define ATH11K_QMI_WLANFW_MAX_NUM_MEM_SEG_V01 52
|
|
@@ -41,7 +42,8 @@
|
|
#define ATH11K_QMI_IPQ6018_M3_DUMP_ADDRESS 0x50100000
|
|
#endif
|
|
|
|
-#define ATH11K_QMI_IPQ5018_M3_DUMP_ADDRESS 0x4C800000
|
|
+#define ATH11K_QMI_IPQ5018_M3_DUMP_ADDRESS 0x4C800000
|
|
+#define ATH11K_QMI_QCN6122_M3_DUMP_ADDRESS 0x4E200000
|
|
#define ATH11K_QMI_M3_DUMP_SIZE 0x100000
|
|
|
|
#define QMI_WLFW_REQUEST_MEM_IND_V01 0x0035
|
|
@@ -58,6 +60,11 @@
|
|
#define ATH11K_FIRMWARE_MODE_OFF 4
|
|
#define ATH11K_COLD_BOOT_FW_RESET_DELAY (60 * HZ)
|
|
|
|
+#define QCN6122_USERPD_0 1
|
|
+#define QCN6122_USERPD_1 2
|
|
+#define QCN6122_DEVICE_BAR_SIZE 0x200000
|
|
+#define ATH11K_RCV_QGIC_MSI_HDLR_DELAY (3 * HZ)
|
|
+
|
|
struct ath11k_base;
|
|
extern unsigned int ath11k_host_ddr_addr;
|
|
|
|
@@ -452,6 +459,9 @@ struct ath11k_qmi_event_qdss_trace_save_
|
|
#define QMI_WLANFW_CAP_RESP_MSG_V01_MAX_LEN 235
|
|
#define QMI_WLANFW_CAP_REQ_V01 0x0024
|
|
#define QMI_WLANFW_CAP_RESP_V01 0x0024
|
|
+#define QMI_WLANFW_DEVICE_INFO_REQ_V01 0x004C
|
|
+#define QMI_WLANFW_DEVICE_INFO_REQ_MSG_V01 0
|
|
+
|
|
|
|
enum qmi_wlanfw_pipedir_enum_v01 {
|
|
QMI_WLFW_PIPEDIR_NONE_V01 = 0,
|
|
@@ -544,6 +554,18 @@ struct qmi_wlanfw_cap_req_msg_v01 {
|
|
char placeholder;
|
|
};
|
|
|
|
+struct qmi_wlanfw_device_info_req_msg_v01 {
|
|
+ char placeholder;
|
|
+};
|
|
+
|
|
+struct qmi_wlanfw_device_info_resp_msg_v01 {
|
|
+ struct qmi_response_type_v01 resp;
|
|
+ u8 bar_addr_valid;
|
|
+ u64 bar_addr;
|
|
+ u8 bar_size_valid;
|
|
+ u32 bar_size;
|
|
+};
|
|
+
|
|
#define QMI_WLANFW_BDF_DOWNLOAD_REQ_MSG_V01_MAX_LEN 6182
|
|
#define QMI_WLANFW_BDF_DOWNLOAD_RESP_MSG_V01_MAX_LEN 7
|
|
#define QMI_WLANFW_BDF_DOWNLOAD_RESP_V01 0x0025
|
|
--- a/drivers/net/wireless/ath/ath11k/debugfs.c
|
|
+++ b/drivers/net/wireless/ath/ath11k/debugfs.c
|
|
@@ -1510,7 +1510,12 @@ int ath11k_debugfs_soc_create(struct ath
|
|
return 0;
|
|
|
|
if (ab->hif.bus == ATH11K_BUS_AHB) {
|
|
- snprintf(soc_name, sizeof(soc_name), "%s", ab->hw_params.name);
|
|
+ if (ab->userpd_id) {
|
|
+ snprintf(soc_name, sizeof(soc_name), "%s_%d",
|
|
+ ab->hw_params.name, ab->userpd_id);
|
|
+ } else {
|
|
+ snprintf(soc_name, sizeof(soc_name), "%s", ab->hw_params.name);
|
|
+ }
|
|
} else {
|
|
snprintf(soc_name, sizeof(soc_name), "%s_%s",
|
|
ab->hw_params.name, dev_name(dev));
|