d07a258ac2acb7c6c66054632bb5dd2693bc0237
[openwrt/staging/wigyori.git] / package / kernel / mac80211 / patches / ath11k / 0021-wifi-ath11k-remap-ce-register-space-for-IPQ5018.patch
1 From b42b3678c91f3ca6e0888bf5a15c1e8678fd5f2d Mon Sep 17 00:00:00 2001
2 From: Sriram R <quic_srirrama@quicinc.com>
3 Date: Fri, 2 Dec 2022 23:37:14 +0200
4 Subject: [PATCH] wifi: ath11k: remap ce register space for IPQ5018
5
6 In IPQ5018 ce register space is moved out of wcss unlike
7 ipq8074 or ipq6018 and the space is not contiguous,
8 hence remap the CE registers to a new space to access them.
9
10 Register read/write is modified to check if the register to be written
11 falls in the CE register space and corresponding register is written.
12 Also adjust the interrupt register address to ce irq enable/disable.
13
14 Tested-on: IPQ5018 hw1.0 AHB WLAN.HK.2.6.0.1-00861-QCAHKSWPL_SILICONZ-1
15
16 Signed-off-by: Sriram R <quic_srirrama@quicinc.com>
17 Co-developed-by: Karthikeyan Kathirvel <quic_kathirve@quicinc.com>
18 Signed-off-by: Karthikeyan Kathirvel <quic_kathirve@quicinc.com>
19 Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
20 Link: https://lore.kernel.org/r/20221122132152.17771-5-quic_kathirve@quicinc.com
21 ---
22 drivers/net/wireless/ath/ath11k/ahb.c | 44 ++++++++++++++++++++++----
23 drivers/net/wireless/ath/ath11k/ce.h | 16 ++++++++++
24 drivers/net/wireless/ath/ath11k/core.c | 8 +++++
25 drivers/net/wireless/ath/ath11k/core.h | 1 +
26 drivers/net/wireless/ath/ath11k/hal.c | 17 ++++++----
27 drivers/net/wireless/ath/ath11k/hal.h | 5 +++
28 drivers/net/wireless/ath/ath11k/hw.c | 17 ++++++++++
29 drivers/net/wireless/ath/ath11k/hw.h | 9 ++++++
30 drivers/net/wireless/ath/ath11k/pci.c | 2 ++
31 9 files changed, 107 insertions(+), 12 deletions(-)
32
33 --- a/drivers/net/wireless/ath/ath11k/ahb.c
34 +++ b/drivers/net/wireless/ath/ath11k/ahb.c
35 @@ -267,30 +267,42 @@ static void ath11k_ahb_clearbit32(struct
36 static void ath11k_ahb_ce_irq_enable(struct ath11k_base *ab, u16 ce_id)
37 {
38 const struct ce_attr *ce_attr;
39 + const struct ce_ie_addr *ce_ie_addr = ab->hw_params.ce_ie_addr;
40 + u32 ie1_reg_addr, ie2_reg_addr, ie3_reg_addr;
41 +
42 + ie1_reg_addr = ce_ie_addr->ie1_reg_addr + ATH11K_CE_OFFSET(ab);
43 + ie2_reg_addr = ce_ie_addr->ie2_reg_addr + ATH11K_CE_OFFSET(ab);
44 + ie3_reg_addr = ce_ie_addr->ie3_reg_addr + ATH11K_CE_OFFSET(ab);
45
46 ce_attr = &ab->hw_params.host_ce_config[ce_id];
47 if (ce_attr->src_nentries)
48 - ath11k_ahb_setbit32(ab, ce_id, CE_HOST_IE_ADDRESS);
49 + ath11k_ahb_setbit32(ab, ce_id, ie1_reg_addr);
50
51 if (ce_attr->dest_nentries) {
52 - ath11k_ahb_setbit32(ab, ce_id, CE_HOST_IE_2_ADDRESS);
53 + ath11k_ahb_setbit32(ab, ce_id, ie2_reg_addr);
54 ath11k_ahb_setbit32(ab, ce_id + CE_HOST_IE_3_SHIFT,
55 - CE_HOST_IE_3_ADDRESS);
56 + ie3_reg_addr);
57 }
58 }
59
60 static void ath11k_ahb_ce_irq_disable(struct ath11k_base *ab, u16 ce_id)
61 {
62 const struct ce_attr *ce_attr;
63 + const struct ce_ie_addr *ce_ie_addr = ab->hw_params.ce_ie_addr;
64 + u32 ie1_reg_addr, ie2_reg_addr, ie3_reg_addr;
65 +
66 + ie1_reg_addr = ce_ie_addr->ie1_reg_addr + ATH11K_CE_OFFSET(ab);
67 + ie2_reg_addr = ce_ie_addr->ie2_reg_addr + ATH11K_CE_OFFSET(ab);
68 + ie3_reg_addr = ce_ie_addr->ie3_reg_addr + ATH11K_CE_OFFSET(ab);
69
70 ce_attr = &ab->hw_params.host_ce_config[ce_id];
71 if (ce_attr->src_nentries)
72 - ath11k_ahb_clearbit32(ab, ce_id, CE_HOST_IE_ADDRESS);
73 + ath11k_ahb_clearbit32(ab, ce_id, ie1_reg_addr);
74
75 if (ce_attr->dest_nentries) {
76 - ath11k_ahb_clearbit32(ab, ce_id, CE_HOST_IE_2_ADDRESS);
77 + ath11k_ahb_clearbit32(ab, ce_id, ie2_reg_addr);
78 ath11k_ahb_clearbit32(ab, ce_id + CE_HOST_IE_3_SHIFT,
79 - CE_HOST_IE_3_ADDRESS);
80 + ie3_reg_addr);
81 }
82 }
83
84 @@ -1142,10 +1154,26 @@ static int ath11k_ahb_probe(struct platf
85 goto err_core_free;
86 }
87
88 + ab->mem_ce = ab->mem;
89 +
90 ret = ath11k_core_pre_init(ab);
91 if (ret)
92 goto err_core_free;
93
94 + if (ab->hw_params.ce_remap) {
95 + const struct ce_remap *ce_remap = ab->hw_params.ce_remap;
96 + /* ce register space is moved out of wcss unlike ipq8074 or ipq6018
97 + * and the space is not contiguous, hence remapping the CE registers
98 + * to a new space for accessing them.
99 + */
100 + ab->mem_ce = ioremap(ce_remap->base, ce_remap->size);
101 + if (IS_ERR(ab->mem_ce)) {
102 + dev_err(&pdev->dev, "ce ioremap error\n");
103 + ret = -ENOMEM;
104 + goto err_core_free;
105 + }
106 + }
107 +
108 ret = ath11k_ahb_setup_resources(ab);
109 if (ret)
110 goto err_core_free;
111 @@ -1236,6 +1264,10 @@ static void ath11k_ahb_free_resources(st
112 ath11k_ahb_release_smp2p_handle(ab);
113 ath11k_ahb_fw_resource_deinit(ab);
114 ath11k_ce_free_pipes(ab);
115 +
116 + if (ab->hw_params.ce_remap)
117 + iounmap(ab->mem_ce);
118 +
119 ath11k_core_free(ab);
120 platform_set_drvdata(pdev, NULL);
121 }
122 --- a/drivers/net/wireless/ath/ath11k/ce.h
123 +++ b/drivers/net/wireless/ath/ath11k/ce.h
124 @@ -49,6 +49,11 @@ void ath11k_ce_byte_swap(void *mem, u32
125 #define CE_HOST_IE_2_ADDRESS 0x00A18040
126 #define CE_HOST_IE_3_ADDRESS CE_HOST_IE_ADDRESS
127
128 +/* CE IE registers are different for IPQ5018 */
129 +#define CE_HOST_IPQ5018_IE_ADDRESS 0x0841804C
130 +#define CE_HOST_IPQ5018_IE_2_ADDRESS 0x08418050
131 +#define CE_HOST_IPQ5018_IE_3_ADDRESS CE_HOST_IPQ5018_IE_ADDRESS
132 +
133 #define CE_HOST_IE_3_SHIFT 0xC
134
135 #define CE_RING_IDX_INCR(nentries_mask, idx) (((idx) + 1) & (nentries_mask))
136 @@ -84,6 +89,17 @@ struct ce_pipe_config {
137 __le32 reserved;
138 };
139
140 +struct ce_ie_addr {
141 + u32 ie1_reg_addr;
142 + u32 ie2_reg_addr;
143 + u32 ie3_reg_addr;
144 +};
145 +
146 +struct ce_remap {
147 + u32 base;
148 + u32 size;
149 +};
150 +
151 struct ce_attr {
152 /* CE_ATTR_* values */
153 unsigned int flags;
154 --- a/drivers/net/wireless/ath/ath11k/core.c
155 +++ b/drivers/net/wireless/ath/ath11k/core.c
156 @@ -54,6 +54,7 @@ static const struct ath11k_hw_params ath
157 .target_ce_count = 11,
158 .svc_to_ce_map = ath11k_target_service_to_ce_map_wlan_ipq8074,
159 .svc_to_ce_map_len = 21,
160 + .ce_ie_addr = &ath11k_ce_ie_addr_ipq8074,
161 .single_pdev_only = false,
162 .rxdma1_enable = true,
163 .num_rxmda_per_pdev = 1,
164 @@ -137,6 +138,7 @@ static const struct ath11k_hw_params ath
165 .target_ce_count = 11,
166 .svc_to_ce_map = ath11k_target_service_to_ce_map_wlan_ipq6018,
167 .svc_to_ce_map_len = 19,
168 + .ce_ie_addr = &ath11k_ce_ie_addr_ipq8074,
169 .single_pdev_only = false,
170 .rxdma1_enable = true,
171 .num_rxmda_per_pdev = 1,
172 @@ -218,6 +220,7 @@ static const struct ath11k_hw_params ath
173 .target_ce_count = 9,
174 .svc_to_ce_map = ath11k_target_service_to_ce_map_wlan_qca6390,
175 .svc_to_ce_map_len = 14,
176 + .ce_ie_addr = &ath11k_ce_ie_addr_ipq8074,
177 .single_pdev_only = true,
178 .rxdma1_enable = false,
179 .num_rxmda_per_pdev = 2,
180 @@ -301,6 +304,7 @@ static const struct ath11k_hw_params ath
181 .target_ce_count = 9,
182 .svc_to_ce_map = ath11k_target_service_to_ce_map_wlan_qcn9074,
183 .svc_to_ce_map_len = 18,
184 + .ce_ie_addr = &ath11k_ce_ie_addr_ipq8074,
185 .rxdma1_enable = true,
186 .num_rxmda_per_pdev = 1,
187 .rx_mac_buf_ring = false,
188 @@ -381,6 +385,7 @@ static const struct ath11k_hw_params ath
189 .target_ce_count = 9,
190 .svc_to_ce_map = ath11k_target_service_to_ce_map_wlan_qca6390,
191 .svc_to_ce_map_len = 14,
192 + .ce_ie_addr = &ath11k_ce_ie_addr_ipq8074,
193 .single_pdev_only = true,
194 .rxdma1_enable = false,
195 .num_rxmda_per_pdev = 2,
196 @@ -546,6 +551,7 @@ static const struct ath11k_hw_params ath
197 .target_ce_count = 9,
198 .svc_to_ce_map = ath11k_target_service_to_ce_map_wlan_qca6390,
199 .svc_to_ce_map_len = 14,
200 + .ce_ie_addr = &ath11k_ce_ie_addr_ipq8074,
201 .single_pdev_only = true,
202 .rxdma1_enable = false,
203 .num_rxmda_per_pdev = 1,
204 @@ -634,6 +640,8 @@ static const struct ath11k_hw_params ath
205 .target_ce_count = TARGET_CE_CNT_5018,
206 .svc_to_ce_map = ath11k_target_service_to_ce_map_wlan_ipq5018,
207 .svc_to_ce_map_len = SVC_CE_MAP_LEN_5018,
208 + .ce_ie_addr = &ath11k_ce_ie_addr_ipq5018,
209 + .ce_remap = &ath11k_ce_remap_ipq5018,
210 .rxdma1_enable = true,
211 .num_rxmda_per_pdev = RXDMA_PER_PDEV_5018,
212 .rx_mac_buf_ring = false,
213 --- a/drivers/net/wireless/ath/ath11k/core.h
214 +++ b/drivers/net/wireless/ath/ath11k/core.h
215 @@ -851,6 +851,7 @@ struct ath11k_base {
216 struct ath11k_dp dp;
217
218 void __iomem *mem;
219 + void __iomem *mem_ce;
220 unsigned long mem_len;
221
222 struct {
223 --- a/drivers/net/wireless/ath/ath11k/hal.c
224 +++ b/drivers/net/wireless/ath/ath11k/hal.c
225 @@ -1220,16 +1220,20 @@ static int ath11k_hal_srng_create_config
226 s->reg_start[1] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL_STATUS_RING_HP;
227
228 s = &hal->srng_config[HAL_CE_SRC];
229 - s->reg_start[0] = HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(ab) + HAL_CE_DST_RING_BASE_LSB;
230 - s->reg_start[1] = HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(ab) + HAL_CE_DST_RING_HP;
231 + s->reg_start[0] = HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(ab) + HAL_CE_DST_RING_BASE_LSB +
232 + ATH11K_CE_OFFSET(ab);
233 + s->reg_start[1] = HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(ab) + HAL_CE_DST_RING_HP +
234 + ATH11K_CE_OFFSET(ab);
235 s->reg_size[0] = HAL_SEQ_WCSS_UMAC_CE1_SRC_REG(ab) -
236 HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(ab);
237 s->reg_size[1] = HAL_SEQ_WCSS_UMAC_CE1_SRC_REG(ab) -
238 HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(ab);
239
240 s = &hal->srng_config[HAL_CE_DST];
241 - s->reg_start[0] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab) + HAL_CE_DST_RING_BASE_LSB;
242 - s->reg_start[1] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab) + HAL_CE_DST_RING_HP;
243 + s->reg_start[0] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab) + HAL_CE_DST_RING_BASE_LSB +
244 + ATH11K_CE_OFFSET(ab);
245 + s->reg_start[1] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab) + HAL_CE_DST_RING_HP +
246 + ATH11K_CE_OFFSET(ab);
247 s->reg_size[0] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG(ab) -
248 HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab);
249 s->reg_size[1] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG(ab) -
250 @@ -1237,8 +1241,9 @@ static int ath11k_hal_srng_create_config
251
252 s = &hal->srng_config[HAL_CE_DST_STATUS];
253 s->reg_start[0] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab) +
254 - HAL_CE_DST_STATUS_RING_BASE_LSB;
255 - s->reg_start[1] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab) + HAL_CE_DST_STATUS_RING_HP;
256 + HAL_CE_DST_STATUS_RING_BASE_LSB + ATH11K_CE_OFFSET(ab);
257 + s->reg_start[1] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab) + HAL_CE_DST_STATUS_RING_HP +
258 + ATH11K_CE_OFFSET(ab);
259 s->reg_size[0] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG(ab) -
260 HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab);
261 s->reg_size[1] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG(ab) -
262 --- a/drivers/net/wireless/ath/ath11k/hal.h
263 +++ b/drivers/net/wireless/ath/ath11k/hal.h
264 @@ -321,6 +321,10 @@ struct ath11k_base;
265 #define HAL_WBM2SW_RELEASE_RING_BASE_MSB_RING_SIZE 0x000fffff
266 #define HAL_RXDMA_RING_MAX_SIZE 0x0000ffff
267
268 +/* IPQ5018 ce registers */
269 +#define HAL_IPQ5018_CE_WFSS_REG_BASE 0x08400000
270 +#define HAL_IPQ5018_CE_SIZE 0x200000
271 +
272 /* Add any other errors here and return them in
273 * ath11k_hal_rx_desc_get_err().
274 */
275 @@ -519,6 +523,7 @@ enum hal_srng_dir {
276 #define HAL_SRNG_FLAGS_MSI_INTR 0x00020000
277 #define HAL_SRNG_FLAGS_CACHED 0x20000000
278 #define HAL_SRNG_FLAGS_LMAC_RING 0x80000000
279 +#define HAL_SRNG_FLAGS_REMAP_CE_RING 0x10000000
280
281 #define HAL_SRNG_TLV_HDR_TAG GENMASK(9, 1)
282 #define HAL_SRNG_TLV_HDR_LEN GENMASK(25, 10)
283 --- a/drivers/net/wireless/ath/ath11k/hw.c
284 +++ b/drivers/net/wireless/ath/ath11k/hw.c
285 @@ -2163,6 +2163,23 @@ const struct service_to_pipe ath11k_targ
286 { /* terminator entry */ }
287 };
288
289 +const struct ce_ie_addr ath11k_ce_ie_addr_ipq8074 = {
290 + .ie1_reg_addr = CE_HOST_IE_ADDRESS,
291 + .ie2_reg_addr = CE_HOST_IE_2_ADDRESS,
292 + .ie3_reg_addr = CE_HOST_IE_3_ADDRESS,
293 +};
294 +
295 +const struct ce_ie_addr ath11k_ce_ie_addr_ipq5018 = {
296 + .ie1_reg_addr = CE_HOST_IPQ5018_IE_ADDRESS - HAL_IPQ5018_CE_WFSS_REG_BASE,
297 + .ie2_reg_addr = CE_HOST_IPQ5018_IE_2_ADDRESS - HAL_IPQ5018_CE_WFSS_REG_BASE,
298 + .ie3_reg_addr = CE_HOST_IPQ5018_IE_3_ADDRESS - HAL_IPQ5018_CE_WFSS_REG_BASE,
299 +};
300 +
301 +const struct ce_remap ath11k_ce_remap_ipq5018 = {
302 + .base = HAL_IPQ5018_CE_WFSS_REG_BASE,
303 + .size = HAL_IPQ5018_CE_SIZE,
304 +};
305 +
306 const struct ath11k_hw_regs ipq8074_regs = {
307 /* SW2TCL(x) R0 ring configuration address */
308 .hal_tcl1_ring_base_lsb = 0x00000510,
309 --- a/drivers/net/wireless/ath/ath11k/hw.h
310 +++ b/drivers/net/wireless/ath/ath11k/hw.h
311 @@ -80,6 +80,8 @@
312 #define ATH11K_M3_FILE "m3.bin"
313 #define ATH11K_REGDB_FILE_NAME "regdb.bin"
314
315 +#define ATH11K_CE_OFFSET(ab) (ab->mem_ce - ab->mem)
316 +
317 enum ath11k_hw_rate_cck {
318 ATH11K_HW_RATE_CCK_LP_11M = 0,
319 ATH11K_HW_RATE_CCK_LP_5_5M,
320 @@ -158,6 +160,8 @@ struct ath11k_hw_params {
321 u32 target_ce_count;
322 const struct service_to_pipe *svc_to_ce_map;
323 u32 svc_to_ce_map_len;
324 + const struct ce_ie_addr *ce_ie_addr;
325 + const struct ce_remap *ce_remap;
326
327 bool single_pdev_only;
328
329 @@ -277,6 +281,11 @@ extern const struct ath11k_hw_ring_mask
330 extern const struct ath11k_hw_ring_mask ath11k_hw_ring_mask_qcn9074;
331 extern const struct ath11k_hw_ring_mask ath11k_hw_ring_mask_wcn6750;
332
333 +extern const struct ce_ie_addr ath11k_ce_ie_addr_ipq8074;
334 +extern const struct ce_ie_addr ath11k_ce_ie_addr_ipq5018;
335 +
336 +extern const struct ce_remap ath11k_ce_remap_ipq5018;
337 +
338 extern const struct ath11k_hw_hal_params ath11k_hw_hal_params_ipq8074;
339 extern const struct ath11k_hw_hal_params ath11k_hw_hal_params_qca6390;
340 extern const struct ath11k_hw_hal_params ath11k_hw_hal_params_wcn6750;
341 --- a/drivers/net/wireless/ath/ath11k/pci.c
342 +++ b/drivers/net/wireless/ath/ath11k/pci.c
343 @@ -543,6 +543,8 @@ static int ath11k_pci_claim(struct ath11
344 goto clear_master;
345 }
346
347 + ab->mem_ce = ab->mem;
348 +
349 ath11k_dbg(ab, ATH11K_DBG_BOOT, "boot pci_mem 0x%pK\n", ab->mem);
350 return 0;
351