mirror of
https://github.com/coolsnowwolf/lede.git
synced 2025-04-16 14:23:38 +00:00
352 lines
13 KiB
Diff
352 lines
13 KiB
Diff
From b42b3678c91f3ca6e0888bf5a15c1e8678fd5f2d Mon Sep 17 00:00:00 2001
|
|
From: Sriram R <quic_srirrama@quicinc.com>
|
|
Date: Fri, 2 Dec 2022 23:37:14 +0200
|
|
Subject: [PATCH] wifi: ath11k: remap ce register space for IPQ5018
|
|
|
|
In IPQ5018 ce register space is moved out of wcss unlike
|
|
ipq8074 or ipq6018 and the space is not contiguous,
|
|
hence remap the CE registers to a new space to access them.
|
|
|
|
Register read/write is modified to check if the register to be written
|
|
falls in the CE register space and corresponding register is written.
|
|
Also adjust the interrupt register address to ce irq enable/disable.
|
|
|
|
Tested-on: IPQ5018 hw1.0 AHB WLAN.HK.2.6.0.1-00861-QCAHKSWPL_SILICONZ-1
|
|
|
|
Signed-off-by: Sriram R <quic_srirrama@quicinc.com>
|
|
Co-developed-by: Karthikeyan Kathirvel <quic_kathirve@quicinc.com>
|
|
Signed-off-by: Karthikeyan Kathirvel <quic_kathirve@quicinc.com>
|
|
Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
|
|
Link: https://lore.kernel.org/r/20221122132152.17771-5-quic_kathirve@quicinc.com
|
|
---
|
|
drivers/net/wireless/ath/ath11k/ahb.c | 44 ++++++++++++++++++++++----
|
|
drivers/net/wireless/ath/ath11k/ce.h | 16 ++++++++++
|
|
drivers/net/wireless/ath/ath11k/core.c | 8 +++++
|
|
drivers/net/wireless/ath/ath11k/core.h | 1 +
|
|
drivers/net/wireless/ath/ath11k/hal.c | 17 ++++++----
|
|
drivers/net/wireless/ath/ath11k/hal.h | 5 +++
|
|
drivers/net/wireless/ath/ath11k/hw.c | 17 ++++++++++
|
|
drivers/net/wireless/ath/ath11k/hw.h | 9 ++++++
|
|
drivers/net/wireless/ath/ath11k/pci.c | 2 ++
|
|
9 files changed, 107 insertions(+), 12 deletions(-)
|
|
|
|
--- a/drivers/net/wireless/ath/ath11k/ahb.c
|
|
+++ b/drivers/net/wireless/ath/ath11k/ahb.c
|
|
@@ -267,30 +267,42 @@ static void ath11k_ahb_clearbit32(struct
|
|
static void ath11k_ahb_ce_irq_enable(struct ath11k_base *ab, u16 ce_id)
|
|
{
|
|
const struct ce_attr *ce_attr;
|
|
+ const struct ce_ie_addr *ce_ie_addr = ab->hw_params.ce_ie_addr;
|
|
+ u32 ie1_reg_addr, ie2_reg_addr, ie3_reg_addr;
|
|
+
|
|
+ ie1_reg_addr = ce_ie_addr->ie1_reg_addr + ATH11K_CE_OFFSET(ab);
|
|
+ ie2_reg_addr = ce_ie_addr->ie2_reg_addr + ATH11K_CE_OFFSET(ab);
|
|
+ ie3_reg_addr = ce_ie_addr->ie3_reg_addr + ATH11K_CE_OFFSET(ab);
|
|
|
|
ce_attr = &ab->hw_params.host_ce_config[ce_id];
|
|
if (ce_attr->src_nentries)
|
|
- ath11k_ahb_setbit32(ab, ce_id, CE_HOST_IE_ADDRESS);
|
|
+ ath11k_ahb_setbit32(ab, ce_id, ie1_reg_addr);
|
|
|
|
if (ce_attr->dest_nentries) {
|
|
- ath11k_ahb_setbit32(ab, ce_id, CE_HOST_IE_2_ADDRESS);
|
|
+ ath11k_ahb_setbit32(ab, ce_id, ie2_reg_addr);
|
|
ath11k_ahb_setbit32(ab, ce_id + CE_HOST_IE_3_SHIFT,
|
|
- CE_HOST_IE_3_ADDRESS);
|
|
+ ie3_reg_addr);
|
|
}
|
|
}
|
|
|
|
static void ath11k_ahb_ce_irq_disable(struct ath11k_base *ab, u16 ce_id)
|
|
{
|
|
const struct ce_attr *ce_attr;
|
|
+ const struct ce_ie_addr *ce_ie_addr = ab->hw_params.ce_ie_addr;
|
|
+ u32 ie1_reg_addr, ie2_reg_addr, ie3_reg_addr;
|
|
+
|
|
+ ie1_reg_addr = ce_ie_addr->ie1_reg_addr + ATH11K_CE_OFFSET(ab);
|
|
+ ie2_reg_addr = ce_ie_addr->ie2_reg_addr + ATH11K_CE_OFFSET(ab);
|
|
+ ie3_reg_addr = ce_ie_addr->ie3_reg_addr + ATH11K_CE_OFFSET(ab);
|
|
|
|
ce_attr = &ab->hw_params.host_ce_config[ce_id];
|
|
if (ce_attr->src_nentries)
|
|
- ath11k_ahb_clearbit32(ab, ce_id, CE_HOST_IE_ADDRESS);
|
|
+ ath11k_ahb_clearbit32(ab, ce_id, ie1_reg_addr);
|
|
|
|
if (ce_attr->dest_nentries) {
|
|
- ath11k_ahb_clearbit32(ab, ce_id, CE_HOST_IE_2_ADDRESS);
|
|
+ ath11k_ahb_clearbit32(ab, ce_id, ie2_reg_addr);
|
|
ath11k_ahb_clearbit32(ab, ce_id + CE_HOST_IE_3_SHIFT,
|
|
- CE_HOST_IE_3_ADDRESS);
|
|
+ ie3_reg_addr);
|
|
}
|
|
}
|
|
|
|
@@ -1142,10 +1154,26 @@ static int ath11k_ahb_probe(struct platf
|
|
goto err_core_free;
|
|
}
|
|
|
|
+ ab->mem_ce = ab->mem;
|
|
+
|
|
ret = ath11k_core_pre_init(ab);
|
|
if (ret)
|
|
goto err_core_free;
|
|
|
|
+ if (ab->hw_params.ce_remap) {
|
|
+ const struct ce_remap *ce_remap = ab->hw_params.ce_remap;
|
|
+ /* 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(ce_remap->base, ce_remap->size);
|
|
+ if (IS_ERR(ab->mem_ce)) {
|
|
+ dev_err(&pdev->dev, "ce ioremap error\n");
|
|
+ ret = -ENOMEM;
|
|
+ goto err_core_free;
|
|
+ }
|
|
+ }
|
|
+
|
|
ret = ath11k_ahb_setup_resources(ab);
|
|
if (ret)
|
|
goto err_core_free;
|
|
@@ -1236,6 +1264,10 @@ static void ath11k_ahb_free_resources(st
|
|
ath11k_ahb_release_smp2p_handle(ab);
|
|
ath11k_ahb_fw_resource_deinit(ab);
|
|
ath11k_ce_free_pipes(ab);
|
|
+
|
|
+ if (ab->hw_params.ce_remap)
|
|
+ iounmap(ab->mem_ce);
|
|
+
|
|
ath11k_core_free(ab);
|
|
platform_set_drvdata(pdev, NULL);
|
|
}
|
|
--- a/drivers/net/wireless/ath/ath11k/ce.h
|
|
+++ b/drivers/net/wireless/ath/ath11k/ce.h
|
|
@@ -49,6 +49,11 @@ void ath11k_ce_byte_swap(void *mem, u32
|
|
#define CE_HOST_IE_2_ADDRESS 0x00A18040
|
|
#define CE_HOST_IE_3_ADDRESS CE_HOST_IE_ADDRESS
|
|
|
|
+/* CE IE registers are different for IPQ5018 */
|
|
+#define CE_HOST_IPQ5018_IE_ADDRESS 0x0841804C
|
|
+#define CE_HOST_IPQ5018_IE_2_ADDRESS 0x08418050
|
|
+#define CE_HOST_IPQ5018_IE_3_ADDRESS CE_HOST_IPQ5018_IE_ADDRESS
|
|
+
|
|
#define CE_HOST_IE_3_SHIFT 0xC
|
|
|
|
#define CE_RING_IDX_INCR(nentries_mask, idx) (((idx) + 1) & (nentries_mask))
|
|
@@ -84,6 +89,17 @@ struct ce_pipe_config {
|
|
__le32 reserved;
|
|
};
|
|
|
|
+struct ce_ie_addr {
|
|
+ u32 ie1_reg_addr;
|
|
+ u32 ie2_reg_addr;
|
|
+ u32 ie3_reg_addr;
|
|
+};
|
|
+
|
|
+struct ce_remap {
|
|
+ u32 base;
|
|
+ u32 size;
|
|
+};
|
|
+
|
|
struct ce_attr {
|
|
/* CE_ATTR_* values */
|
|
unsigned int flags;
|
|
--- a/drivers/net/wireless/ath/ath11k/core.c
|
|
+++ b/drivers/net/wireless/ath/ath11k/core.c
|
|
@@ -54,6 +54,7 @@ static const struct ath11k_hw_params ath
|
|
.target_ce_count = 11,
|
|
.svc_to_ce_map = ath11k_target_service_to_ce_map_wlan_ipq8074,
|
|
.svc_to_ce_map_len = 21,
|
|
+ .ce_ie_addr = &ath11k_ce_ie_addr_ipq8074,
|
|
.single_pdev_only = false,
|
|
.rxdma1_enable = true,
|
|
.num_rxmda_per_pdev = 1,
|
|
@@ -137,6 +138,7 @@ static const struct ath11k_hw_params ath
|
|
.target_ce_count = 11,
|
|
.svc_to_ce_map = ath11k_target_service_to_ce_map_wlan_ipq6018,
|
|
.svc_to_ce_map_len = 19,
|
|
+ .ce_ie_addr = &ath11k_ce_ie_addr_ipq8074,
|
|
.single_pdev_only = false,
|
|
.rxdma1_enable = true,
|
|
.num_rxmda_per_pdev = 1,
|
|
@@ -218,6 +220,7 @@ static const struct ath11k_hw_params ath
|
|
.target_ce_count = 9,
|
|
.svc_to_ce_map = ath11k_target_service_to_ce_map_wlan_qca6390,
|
|
.svc_to_ce_map_len = 14,
|
|
+ .ce_ie_addr = &ath11k_ce_ie_addr_ipq8074,
|
|
.single_pdev_only = true,
|
|
.rxdma1_enable = false,
|
|
.num_rxmda_per_pdev = 2,
|
|
@@ -301,6 +304,7 @@ static const struct ath11k_hw_params ath
|
|
.target_ce_count = 9,
|
|
.svc_to_ce_map = ath11k_target_service_to_ce_map_wlan_qcn9074,
|
|
.svc_to_ce_map_len = 18,
|
|
+ .ce_ie_addr = &ath11k_ce_ie_addr_ipq8074,
|
|
.rxdma1_enable = true,
|
|
.num_rxmda_per_pdev = 1,
|
|
.rx_mac_buf_ring = false,
|
|
@@ -381,6 +385,7 @@ static const struct ath11k_hw_params ath
|
|
.target_ce_count = 9,
|
|
.svc_to_ce_map = ath11k_target_service_to_ce_map_wlan_qca6390,
|
|
.svc_to_ce_map_len = 14,
|
|
+ .ce_ie_addr = &ath11k_ce_ie_addr_ipq8074,
|
|
.single_pdev_only = true,
|
|
.rxdma1_enable = false,
|
|
.num_rxmda_per_pdev = 2,
|
|
@@ -546,6 +551,7 @@ static const struct ath11k_hw_params ath
|
|
.target_ce_count = 9,
|
|
.svc_to_ce_map = ath11k_target_service_to_ce_map_wlan_qca6390,
|
|
.svc_to_ce_map_len = 14,
|
|
+ .ce_ie_addr = &ath11k_ce_ie_addr_ipq8074,
|
|
.single_pdev_only = true,
|
|
.rxdma1_enable = false,
|
|
.num_rxmda_per_pdev = 1,
|
|
@@ -634,6 +640,8 @@ static const struct ath11k_hw_params ath
|
|
.target_ce_count = TARGET_CE_CNT_5018,
|
|
.svc_to_ce_map = ath11k_target_service_to_ce_map_wlan_ipq5018,
|
|
.svc_to_ce_map_len = SVC_CE_MAP_LEN_5018,
|
|
+ .ce_ie_addr = &ath11k_ce_ie_addr_ipq5018,
|
|
+ .ce_remap = &ath11k_ce_remap_ipq5018,
|
|
.rxdma1_enable = true,
|
|
.num_rxmda_per_pdev = RXDMA_PER_PDEV_5018,
|
|
.rx_mac_buf_ring = false,
|
|
--- a/drivers/net/wireless/ath/ath11k/core.h
|
|
+++ b/drivers/net/wireless/ath/ath11k/core.h
|
|
@@ -851,6 +851,7 @@ struct ath11k_base {
|
|
struct ath11k_dp dp;
|
|
|
|
void __iomem *mem;
|
|
+ void __iomem *mem_ce;
|
|
unsigned long mem_len;
|
|
|
|
struct {
|
|
--- a/drivers/net/wireless/ath/ath11k/hal.c
|
|
+++ b/drivers/net/wireless/ath/ath11k/hal.c
|
|
@@ -1220,16 +1220,20 @@ static int ath11k_hal_srng_create_config
|
|
s->reg_start[1] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL_STATUS_RING_HP;
|
|
|
|
s = &hal->srng_config[HAL_CE_SRC];
|
|
- s->reg_start[0] = HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(ab) + HAL_CE_DST_RING_BASE_LSB;
|
|
- s->reg_start[1] = HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(ab) + HAL_CE_DST_RING_HP;
|
|
+ s->reg_start[0] = HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(ab) + HAL_CE_DST_RING_BASE_LSB +
|
|
+ ATH11K_CE_OFFSET(ab);
|
|
+ s->reg_start[1] = HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(ab) + HAL_CE_DST_RING_HP +
|
|
+ ATH11K_CE_OFFSET(ab);
|
|
s->reg_size[0] = HAL_SEQ_WCSS_UMAC_CE1_SRC_REG(ab) -
|
|
HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(ab);
|
|
s->reg_size[1] = HAL_SEQ_WCSS_UMAC_CE1_SRC_REG(ab) -
|
|
HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(ab);
|
|
|
|
s = &hal->srng_config[HAL_CE_DST];
|
|
- s->reg_start[0] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab) + HAL_CE_DST_RING_BASE_LSB;
|
|
- s->reg_start[1] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab) + HAL_CE_DST_RING_HP;
|
|
+ s->reg_start[0] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab) + HAL_CE_DST_RING_BASE_LSB +
|
|
+ ATH11K_CE_OFFSET(ab);
|
|
+ s->reg_start[1] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab) + HAL_CE_DST_RING_HP +
|
|
+ ATH11K_CE_OFFSET(ab);
|
|
s->reg_size[0] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG(ab) -
|
|
HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab);
|
|
s->reg_size[1] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG(ab) -
|
|
@@ -1237,8 +1241,9 @@ static int ath11k_hal_srng_create_config
|
|
|
|
s = &hal->srng_config[HAL_CE_DST_STATUS];
|
|
s->reg_start[0] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab) +
|
|
- HAL_CE_DST_STATUS_RING_BASE_LSB;
|
|
- s->reg_start[1] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab) + HAL_CE_DST_STATUS_RING_HP;
|
|
+ HAL_CE_DST_STATUS_RING_BASE_LSB + ATH11K_CE_OFFSET(ab);
|
|
+ s->reg_start[1] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab) + HAL_CE_DST_STATUS_RING_HP +
|
|
+ ATH11K_CE_OFFSET(ab);
|
|
s->reg_size[0] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG(ab) -
|
|
HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab);
|
|
s->reg_size[1] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG(ab) -
|
|
--- a/drivers/net/wireless/ath/ath11k/hal.h
|
|
+++ b/drivers/net/wireless/ath/ath11k/hal.h
|
|
@@ -321,6 +321,10 @@ struct ath11k_base;
|
|
#define HAL_WBM2SW_RELEASE_RING_BASE_MSB_RING_SIZE 0x000fffff
|
|
#define HAL_RXDMA_RING_MAX_SIZE 0x0000ffff
|
|
|
|
+/* IPQ5018 ce registers */
|
|
+#define HAL_IPQ5018_CE_WFSS_REG_BASE 0x08400000
|
|
+#define HAL_IPQ5018_CE_SIZE 0x200000
|
|
+
|
|
/* Add any other errors here and return them in
|
|
* ath11k_hal_rx_desc_get_err().
|
|
*/
|
|
@@ -519,6 +523,7 @@ enum hal_srng_dir {
|
|
#define HAL_SRNG_FLAGS_MSI_INTR 0x00020000
|
|
#define HAL_SRNG_FLAGS_CACHED 0x20000000
|
|
#define HAL_SRNG_FLAGS_LMAC_RING 0x80000000
|
|
+#define HAL_SRNG_FLAGS_REMAP_CE_RING 0x10000000
|
|
|
|
#define HAL_SRNG_TLV_HDR_TAG GENMASK(9, 1)
|
|
#define HAL_SRNG_TLV_HDR_LEN GENMASK(25, 10)
|
|
--- a/drivers/net/wireless/ath/ath11k/hw.c
|
|
+++ b/drivers/net/wireless/ath/ath11k/hw.c
|
|
@@ -2163,6 +2163,23 @@ const struct service_to_pipe ath11k_targ
|
|
{ /* terminator entry */ }
|
|
};
|
|
|
|
+const struct ce_ie_addr ath11k_ce_ie_addr_ipq8074 = {
|
|
+ .ie1_reg_addr = CE_HOST_IE_ADDRESS,
|
|
+ .ie2_reg_addr = CE_HOST_IE_2_ADDRESS,
|
|
+ .ie3_reg_addr = CE_HOST_IE_3_ADDRESS,
|
|
+};
|
|
+
|
|
+const struct ce_ie_addr ath11k_ce_ie_addr_ipq5018 = {
|
|
+ .ie1_reg_addr = CE_HOST_IPQ5018_IE_ADDRESS - HAL_IPQ5018_CE_WFSS_REG_BASE,
|
|
+ .ie2_reg_addr = CE_HOST_IPQ5018_IE_2_ADDRESS - HAL_IPQ5018_CE_WFSS_REG_BASE,
|
|
+ .ie3_reg_addr = CE_HOST_IPQ5018_IE_3_ADDRESS - HAL_IPQ5018_CE_WFSS_REG_BASE,
|
|
+};
|
|
+
|
|
+const struct ce_remap ath11k_ce_remap_ipq5018 = {
|
|
+ .base = HAL_IPQ5018_CE_WFSS_REG_BASE,
|
|
+ .size = HAL_IPQ5018_CE_SIZE,
|
|
+};
|
|
+
|
|
const struct ath11k_hw_regs ipq8074_regs = {
|
|
/* SW2TCL(x) R0 ring configuration address */
|
|
.hal_tcl1_ring_base_lsb = 0x00000510,
|
|
--- a/drivers/net/wireless/ath/ath11k/hw.h
|
|
+++ b/drivers/net/wireless/ath/ath11k/hw.h
|
|
@@ -80,6 +80,8 @@
|
|
#define ATH11K_M3_FILE "m3.bin"
|
|
#define ATH11K_REGDB_FILE_NAME "regdb.bin"
|
|
|
|
+#define ATH11K_CE_OFFSET(ab) (ab->mem_ce - ab->mem)
|
|
+
|
|
enum ath11k_hw_rate_cck {
|
|
ATH11K_HW_RATE_CCK_LP_11M = 0,
|
|
ATH11K_HW_RATE_CCK_LP_5_5M,
|
|
@@ -158,6 +160,8 @@ struct ath11k_hw_params {
|
|
u32 target_ce_count;
|
|
const struct service_to_pipe *svc_to_ce_map;
|
|
u32 svc_to_ce_map_len;
|
|
+ const struct ce_ie_addr *ce_ie_addr;
|
|
+ const struct ce_remap *ce_remap;
|
|
|
|
bool single_pdev_only;
|
|
|
|
@@ -277,6 +281,11 @@ extern const struct ath11k_hw_ring_mask
|
|
extern const struct ath11k_hw_ring_mask ath11k_hw_ring_mask_qcn9074;
|
|
extern const struct ath11k_hw_ring_mask ath11k_hw_ring_mask_wcn6750;
|
|
|
|
+extern const struct ce_ie_addr ath11k_ce_ie_addr_ipq8074;
|
|
+extern const struct ce_ie_addr ath11k_ce_ie_addr_ipq5018;
|
|
+
|
|
+extern const struct ce_remap ath11k_ce_remap_ipq5018;
|
|
+
|
|
extern const struct ath11k_hw_hal_params ath11k_hw_hal_params_ipq8074;
|
|
extern const struct ath11k_hw_hal_params ath11k_hw_hal_params_qca6390;
|
|
extern const struct ath11k_hw_hal_params ath11k_hw_hal_params_wcn6750;
|
|
--- a/drivers/net/wireless/ath/ath11k/pci.c
|
|
+++ b/drivers/net/wireless/ath/ath11k/pci.c
|
|
@@ -543,6 +543,8 @@ static int ath11k_pci_claim(struct ath11
|
|
goto clear_master;
|
|
}
|
|
|
|
+ ab->mem_ce = ab->mem;
|
|
+
|
|
ath11k_dbg(ab, ATH11K_DBG_BOOT, "boot pci_mem 0x%pK\n", ab->mem);
|
|
return 0;
|
|
|