diff options
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.patch | 351 |
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; + |