mirror of
https://github.com/Telecominfraproject/wlan-ap.git
synced 2025-12-21 19:31:55 +00:00
254 lines
7.6 KiB
Diff
254 lines
7.6 KiB
Diff
From ae444bf877fd94256a110d03582ddb045c541525 Mon Sep 17 00:00:00 2001
|
|
From: Aditya Kumar Singh <quic_adisi@quicinc.com>
|
|
Date: Wed, 24 Aug 2022 12:25:31 -0800
|
|
Subject: [PATCH] ath12k: add dts support
|
|
|
|
DTS support was removed in upstream. Add it back.
|
|
|
|
Signed-off-by: Aditya Kumar Singh <quic_adisi@quicinc.com>
|
|
|
|
--- a/drivers/net/wireless/ath/ath12k/core.c
|
|
+++ b/drivers/net/wireless/ath/ath12k/core.c
|
|
@@ -106,6 +106,29 @@ int ath12k_core_resume(struct ath12k_bas
|
|
return 0;
|
|
}
|
|
|
|
+int ath12k_core_check_dt(struct ath12k_base *ab)
|
|
+{
|
|
+ size_t max_len = sizeof(ab->qmi.target.bdf_ext);
|
|
+ const char *variant = NULL;
|
|
+ struct device_node *node;
|
|
+
|
|
+ node = ab->dev->of_node;
|
|
+ if (!node)
|
|
+ return -ENOENT;
|
|
+
|
|
+ of_property_read_string(node, "qcom,ath12k-calibration-variant",
|
|
+ &variant);
|
|
+ if (!variant)
|
|
+ return -ENODATA;
|
|
+
|
|
+ if (strscpy(ab->qmi.target.bdf_ext, variant, max_len) < 0)
|
|
+ ath12k_dbg(ab, ATH12K_DBG_BOOT,
|
|
+ "bdf variant string is longer than the buffer can accommodate (variant: %s)\n",
|
|
+ variant);
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
static int ath12k_core_create_board_name(struct ath12k_base *ab, char *name,
|
|
size_t name_len)
|
|
{
|
|
--- a/drivers/net/wireless/ath/ath12k/pci.c
|
|
+++ b/drivers/net/wireless/ath/ath12k/pci.c
|
|
@@ -7,6 +7,7 @@
|
|
#include <linux/module.h>
|
|
#include <linux/msi.h>
|
|
#include <linux/pci.h>
|
|
+#include <linux/of.h>
|
|
|
|
#include "pci.h"
|
|
#include "core.h"
|
|
@@ -593,6 +594,7 @@ static int ath12k_pci_config_irq(struct
|
|
static void ath12k_pci_init_qmi_ce_config(struct ath12k_base *ab)
|
|
{
|
|
struct ath12k_qmi_ce_cfg *cfg = &ab->qmi.ce_cfg;
|
|
+ u32 instance_id = 0;
|
|
|
|
cfg->tgt_ce = ab->hw_params->target_ce_config;
|
|
cfg->tgt_ce_len = ab->hw_params->target_ce_count;
|
|
@@ -600,6 +602,9 @@ static void ath12k_pci_init_qmi_ce_confi
|
|
cfg->svc_to_ce_map = ab->hw_params->svc_to_ce_map;
|
|
cfg->svc_to_ce_map_len = ab->hw_params->svc_to_ce_map_len;
|
|
ab->qmi.service_ins_id = ab->hw_params->qmi_service_ins_id;
|
|
+
|
|
+ if (!of_property_read_u32(ab->dev->of_node, "qrtr_instance_id", &instance_id))
|
|
+ ab->qmi.service_ins_id = instance_id + ATH12K_QMI_WLFW_NODE_ID_BASE;
|
|
}
|
|
|
|
static void ath12k_pci_ce_irqs_enable(struct ath12k_base *ab)
|
|
@@ -1145,6 +1150,7 @@ static int ath12k_pci_probe(struct pci_d
|
|
{
|
|
struct ath12k_base *ab;
|
|
struct ath12k_pci *ab_pci;
|
|
+ u32 addr;
|
|
int ret;
|
|
|
|
ab = ath12k_core_alloc(&pdev->dev, sizeof(*ab_pci), ATH12K_BUS_PCI,
|
|
@@ -1164,6 +1170,12 @@ static int ath12k_pci_probe(struct pci_d
|
|
pci_set_drvdata(pdev, ab);
|
|
spin_lock_init(&ab_pci->window_lock);
|
|
|
|
+ /* Set fixed_mem_region to true for
|
|
+ * the platforms supports reserved memory.
|
|
+ */
|
|
+ if (of_property_read_u32(ab->dev->of_node, "qcom,base-addr", &addr))
|
|
+ ab->bus_params.fixed_mem_region = true;
|
|
+
|
|
ret = ath12k_pci_claim(ab_pci, pdev);
|
|
if (ret) {
|
|
ath12k_err(ab, "failed to claim device: %d\n", ret);
|
|
--- a/drivers/net/wireless/ath/ath12k/qmi.c
|
|
+++ b/drivers/net/wireless/ath/ath12k/qmi.c
|
|
@@ -2296,7 +2296,7 @@ static int ath12k_qmi_respond_fw_mem_req
|
|
* failure to firmware and firmware then request multiple blocks of
|
|
* small chunk size memory.
|
|
*/
|
|
- if (ab->qmi.target_mem_delayed) {
|
|
+ if (!ab->bus_params.fixed_mem_region && ab->qmi.target_mem_delayed) {
|
|
delayed = true;
|
|
ath12k_dbg(ab, ATH12K_DBG_QMI, "qmi delays mem_request %d\n",
|
|
ab->qmi.mem_seg_count);
|
|
@@ -2359,13 +2359,20 @@ static void ath12k_qmi_free_target_mem_c
|
|
int i;
|
|
|
|
for (i = 0; i < ab->qmi.mem_seg_count; i++) {
|
|
- if (!ab->qmi.target_mem[i].v.addr)
|
|
- continue;
|
|
- dma_free_coherent(ab->dev,
|
|
- ab->qmi.target_mem[i].size,
|
|
- ab->qmi.target_mem[i].v.addr,
|
|
- ab->qmi.target_mem[i].paddr);
|
|
- ab->qmi.target_mem[i].v.addr = NULL;
|
|
+ if (ab->bus_params.fixed_mem_region) {
|
|
+ if (!ab->qmi.target_mem[i].v.ioaddr)
|
|
+ continue;
|
|
+ iounmap(ab->qmi.target_mem[i].v.ioaddr);
|
|
+ ab->qmi.target_mem[i].v.ioaddr = NULL;
|
|
+ } else {
|
|
+ if (!ab->qmi.target_mem[i].v.addr)
|
|
+ continue;
|
|
+ dma_free_coherent(ab->dev,
|
|
+ ab->qmi.target_mem[i].size,
|
|
+ ab->qmi.target_mem[i].v.addr,
|
|
+ ab->qmi.target_mem[i].paddr);
|
|
+ ab->qmi.target_mem[i].v.addr = NULL;
|
|
+ }
|
|
}
|
|
}
|
|
|
|
@@ -2418,14 +2425,68 @@ static int ath12k_qmi_alloc_target_mem_c
|
|
return 0;
|
|
}
|
|
|
|
+static int ath12k_qmi_assign_target_mem_chunk(struct ath12k_base *ab)
|
|
+{
|
|
+ struct device *dev = ab->dev;
|
|
+ int i, idx;
|
|
+ u32 addr = 0;
|
|
+
|
|
+ for (i = 0, idx = 0; i < ab->qmi.mem_seg_count; i++) {
|
|
+ switch (ab->qmi.target_mem[i].type) {
|
|
+ case HOST_DDR_REGION_TYPE:
|
|
+ if (of_property_read_u32(dev->of_node, "qcom,base-addr", &addr)) {
|
|
+ ath12k_warn(ab, "qmi fail to get base-addr from dt\n");
|
|
+ return -ENOENT;
|
|
+ }
|
|
+ ab->qmi.target_mem[idx].paddr = addr;
|
|
+ ab->qmi.target_mem[idx].v.ioaddr =
|
|
+ ioremap(ab->qmi.target_mem[idx].paddr,
|
|
+ ab->qmi.target_mem[i].size);
|
|
+ ab->qmi.target_mem[idx].size = ab->qmi.target_mem[i].size;
|
|
+ ab->qmi.target_mem[idx].type = ab->qmi.target_mem[i].type;
|
|
+ idx++;
|
|
+ break;
|
|
+ case CALDB_MEM_REGION_TYPE:
|
|
+ if (ab->qmi.target_mem[i].size > ATH12K_QMI_CALDB_SIZE) {
|
|
+ ath12k_warn(ab, "qmi mem size is low to load caldata\n");
|
|
+ return -EINVAL;
|
|
+ }
|
|
+
|
|
+ if (!of_property_read_u32(dev->of_node,
|
|
+ "qcom,caldb-addr", &addr)) {
|
|
+ ab->qmi.target_mem[idx].paddr = addr;
|
|
+ ab->qmi.target_mem[idx].v.ioaddr =
|
|
+ ioremap(ab->qmi.target_mem[idx].paddr,
|
|
+ ab->qmi.target_mem[i].size);
|
|
+ } else {
|
|
+ ab->qmi.target_mem[idx].paddr = 0;
|
|
+ ab->qmi.target_mem[idx].v.ioaddr = NULL;
|
|
+ }
|
|
+
|
|
+ ab->qmi.target_mem[idx].size = ab->qmi.target_mem[i].size;
|
|
+ ab->qmi.target_mem[idx].type = ab->qmi.target_mem[i].type;
|
|
+ idx++;
|
|
+ break;
|
|
+ default:
|
|
+ ath12k_warn(ab, "qmi ignore invalid mem req type %d\n",
|
|
+ ab->qmi.target_mem[i].type);
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+ ab->qmi.mem_seg_count = idx;
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
static int ath12k_qmi_request_target_cap(struct ath12k_base *ab)
|
|
{
|
|
struct qmi_wlanfw_cap_req_msg_v01 req;
|
|
struct qmi_wlanfw_cap_resp_msg_v01 resp;
|
|
struct qmi_txn txn = {};
|
|
- unsigned int board_id = ATH12K_BOARD_ID_DEFAULT;
|
|
+ struct device *dev = ab->dev;
|
|
+ unsigned int board_id;
|
|
int ret = 0;
|
|
- int i;
|
|
+ int r, i;
|
|
|
|
memset(&req, 0, sizeof(req));
|
|
memset(&resp, 0, sizeof(resp));
|
|
@@ -2463,10 +2524,13 @@ static int ath12k_qmi_request_target_cap
|
|
ab->qmi.target.chip_family = resp.chip_info.chip_family;
|
|
}
|
|
|
|
- if (resp.board_info_valid)
|
|
+ if (!of_property_read_u32(dev->of_node, "qcom,board_id", &board_id) &&
|
|
+ board_id != 0xFF)
|
|
+ ab->qmi.target.board_id = board_id;
|
|
+ else if (resp.board_info_valid)
|
|
ab->qmi.target.board_id = resp.board_info.board_id;
|
|
else
|
|
- ab->qmi.target.board_id = board_id;
|
|
+ ab->qmi.target.board_id = ATH12K_BOARD_ID_DEFAULT;
|
|
|
|
if (resp.soc_info_valid)
|
|
ab->qmi.target.soc_id = resp.soc_info.soc_id;
|
|
@@ -2509,6 +2573,10 @@ static int ath12k_qmi_request_target_cap
|
|
ab->qmi.target.fw_build_timestamp,
|
|
ab->qmi.target.fw_build_id);
|
|
|
|
+ r = ath12k_core_check_dt(ab);
|
|
+ if (r)
|
|
+ ath12k_dbg(ab, ATH12K_DBG_QMI, "DT bdf variant name not set.\n");
|
|
+
|
|
out:
|
|
return ret;
|
|
}
|
|
@@ -3160,11 +3228,20 @@ static void ath12k_qmi_msg_mem_request_c
|
|
msg->mem_seg[i].type, msg->mem_seg[i].size);
|
|
}
|
|
|
|
- ret = ath12k_qmi_alloc_target_mem_chunk(ab);
|
|
- if (ret) {
|
|
- ath12k_warn(ab, "qmi failed to alloc target memory: %d\n",
|
|
- ret);
|
|
- return;
|
|
+ if (ab->bus_params.fixed_mem_region) {
|
|
+ ret = ath12k_qmi_assign_target_mem_chunk(ab);
|
|
+ if (ret) {
|
|
+ ath12k_warn(ab, "qmi failed to assign target memory: %d\n",
|
|
+ ret);
|
|
+ return;
|
|
+ }
|
|
+ } else {
|
|
+ ret = ath12k_qmi_alloc_target_mem_chunk(ab);
|
|
+ if (ret) {
|
|
+ ath12k_warn(ab, "qmi failed to alloc target memory: %d\n",
|
|
+ ret);
|
|
+ return;
|
|
+ }
|
|
}
|
|
|
|
ath12k_qmi_driver_event_post(qmi, ATH12K_QMI_EVENT_REQUEST_MEM, NULL);
|