aboutsummaryrefslogtreecommitdiffstats
path: root/package/kernel/mac80211/patches/ath11k/0021-wifi-ath11k-remap-ce-register-space-for-IPQ5018.patch
diff options
context:
space:
mode:
Diffstat (limited to 'package/kernel/mac80211/patches/ath11k/0021-wifi-ath11k-remap-ce-register-space-for-IPQ5018.patch')
-rw-r--r--package/kernel/mac80211/patches/ath11k/0021-wifi-ath11k-remap-ce-register-space-for-IPQ5018.patch351
1 files changed, 351 insertions, 0 deletions
diff --git a/package/kernel/mac80211/patches/ath11k/0021-wifi-ath11k-remap-ce-register-space-for-IPQ5018.patch b/package/kernel/mac80211/patches/ath11k/0021-wifi-ath11k-remap-ce-register-space-for-IPQ5018.patch
new file mode 100644
index 0000000000..d07a258ac2
--- /dev/null
+++ b/package/kernel/mac80211/patches/ath11k/0021-wifi-ath11k-remap-ce-register-space-for-IPQ5018.patch
@@ -0,0 +1,351 @@
+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;
+