123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351 |
- 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;
-
|