1 /*
2  * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
3  * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
4  *
5  * Permission to use, copy, modify, and/or distribute this software for any
6  * purpose with or without fee is hereby granted, provided that the above
7  * copyright notice and this permission notice appear in all copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16  */
17 
18 /*=== includes ===*/
19 /* header files for OS primitives */
20 #include <osdep.h>              /* uint32_t, etc. */
21 #include <qdf_mem.h>         /* qdf_mem_malloc,free */
22 #include <qdf_types.h>          /* qdf_device_t, qdf_print */
23 #include <qdf_lock.h>           /* qdf_spinlock */
24 #include <qdf_atomic.h>         /* qdf_atomic_read */
25 
26 /* header files for utilities */
27 #include "queue.h"         /* TAILQ */
28 
29 /* header files for configuration API */
30 #include <ol_cfg.h>             /* ol_cfg_is_high_latency */
31 #include <ol_if_athvar.h>
32 
33 /* header files for HTT API */
34 #include <ol_htt_api.h>
35 #include <ol_htt_tx_api.h>
36 
37 /* header files for our own APIs */
38 #include <ol_txrx_api.h>
39 #include <ol_txrx_dbg.h>
40 #include <cdp_txrx_ocb.h>
41 #include <ol_txrx_ctrl_api.h>
42 #include <cdp_txrx_stats.h>
43 #include <ol_txrx_osif_api.h>
44 /* header files for our internal definitions */
45 #include <ol_txrx_internal.h>   /* TXRX_ASSERT, etc. */
46 #include <wdi_event.h>          /* WDI events */
47 #include <ol_tx.h>              /* ol_tx_ll */
48 #include <ol_rx.h>              /* ol_rx_deliver */
49 #include <ol_txrx_peer_find.h>  /* ol_txrx_peer_find_attach, etc. */
50 #include <ol_rx_pn.h>           /* ol_rx_pn_check, etc. */
51 #include <ol_rx_fwd.h>          /* ol_rx_fwd_check, etc. */
52 #include <ol_rx_reorder_timeout.h>      /* OL_RX_REORDER_TIMEOUT_INIT, etc. */
53 #include <ol_rx_reorder.h>
54 #include <ol_tx_send.h>         /* ol_tx_discard_target_frms */
55 #include <ol_tx_desc.h>         /* ol_tx_desc_frame_free */
56 #include <ol_tx_queue.h>
57 #include <ol_tx_sched.h>           /* ol_tx_sched_attach, etc. */
58 #include <ol_txrx.h>
59 #include <ol_txrx_types.h>
60 #include <cdp_txrx_flow_ctrl_legacy.h>
61 #include <cdp_txrx_bus.h>
62 #include <cdp_txrx_ipa.h>
63 #include <cdp_txrx_pmf.h>
64 #include "wma.h"
65 #include "hif.h"
66 #include <cdp_txrx_peer_ops.h>
67 #ifndef REMOVE_PKT_LOG
68 #include "pktlog_ac.h"
69 #endif
70 #include "epping_main.h"
71 #include <a_types.h>
72 
73 #ifdef IPA_OFFLOAD
74 #include <ol_txrx_ipa.h>
75 
76 /* For Tx pipes, use Ethernet-II Header format */
77 #ifdef QCA_WIFI_3_0
78 struct ol_txrx_ipa_uc_tx_hdr ipa_uc_tx_hdr = {
79 	{
80 		0x0000,
81 		0x00000000,
82 		0x00000000
83 	},
84 	{
85 		0x00000000
86 	},
87 	{
88 		{0x00, 0x03, 0x7f, 0xaa, 0xbb, 0xcc},
89 		{0x00, 0x03, 0x7f, 0xdd, 0xee, 0xff},
90 		0x0008
91 	}
92 };
93 #else
94 struct ol_txrx_ipa_uc_tx_hdr ipa_uc_tx_hdr = {
95 	{
96 		0x00000000,
97 		0x00000000
98 	},
99 	{
100 		0x00000000
101 	},
102 	{
103 		{0x00, 0x03, 0x7f, 0xaa, 0xbb, 0xcc},
104 		{0x00, 0x03, 0x7f, 0xdd, 0xee, 0xff},
105 		0x0008
106 	}
107 };
108 #endif
109 
ol_txrx_ipa_uc_get_resource(struct cdp_soc_t * soc_hdl,uint8_t pdev_id)110 QDF_STATUS ol_txrx_ipa_uc_get_resource(struct cdp_soc_t *soc_hdl,
111 				       uint8_t pdev_id)
112 {
113 	struct ol_txrx_soc_t *soc = cdp_soc_t_to_ol_txrx_soc_t(soc_hdl);
114 	ol_txrx_pdev_handle pdev = ol_txrx_get_pdev_from_pdev_id(soc, pdev_id);
115 	struct ol_txrx_ipa_resources *ipa_res;
116 	qdf_device_t osdev = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
117 
118 	if (!pdev) {
119 		ol_txrx_err("Invalid instance");
120 		return QDF_STATUS_E_FAILURE;
121 	}
122 
123 	if (!osdev)
124 		return QDF_STATUS_E_NOENT;
125 
126 	ipa_res = &pdev->ipa_resource;
127 	htt_ipa_uc_get_resource(pdev->htt_pdev,
128 				&ipa_res->ce_sr,
129 				&ipa_res->tx_comp_ring,
130 				&ipa_res->rx_rdy_ring,
131 				&ipa_res->rx2_rdy_ring,
132 				&ipa_res->rx_proc_done_idx,
133 				&ipa_res->rx2_proc_done_idx,
134 				&ipa_res->ce_sr_ring_size,
135 				&ipa_res->ce_reg_paddr,
136 				&ipa_res->tx_num_alloc_buffer);
137 
138 	if ((0 == qdf_mem_get_dma_addr(osdev,
139 				&ipa_res->ce_sr->mem_info)) ||
140 	    (0 == qdf_mem_get_dma_addr(osdev,
141 				&ipa_res->tx_comp_ring->mem_info)) ||
142 	    (0 == qdf_mem_get_dma_addr(osdev,
143 				&ipa_res->rx_rdy_ring->mem_info))
144 #if defined(QCA_WIFI_3_0) && defined(CONFIG_IPA3)
145 	    || (0 == qdf_mem_get_dma_addr(osdev,
146 				&ipa_res->rx2_rdy_ring->mem_info))
147 #endif
148 	   )
149 		return QDF_STATUS_E_FAILURE;
150 
151 	return QDF_STATUS_SUCCESS;
152 }
153 
ol_txrx_ipa_uc_set_doorbell_paddr(struct cdp_soc_t * soc_hdl,uint8_t pdev_id)154 QDF_STATUS ol_txrx_ipa_uc_set_doorbell_paddr(struct cdp_soc_t *soc_hdl,
155 					     uint8_t pdev_id)
156 {
157 	struct ol_txrx_soc_t *soc = cdp_soc_t_to_ol_txrx_soc_t(soc_hdl);
158 	ol_txrx_pdev_handle pdev = ol_txrx_get_pdev_from_pdev_id(soc, pdev_id);
159 	struct ol_txrx_ipa_resources *ipa_res;
160 	int ret;
161 
162 	if (!pdev) {
163 		ol_txrx_err("Invalid instance");
164 		return QDF_STATUS_E_FAILURE;
165 	}
166 
167 	ipa_res = &pdev->ipa_resource;
168 	ret = htt_ipa_uc_set_doorbell_paddr(pdev->htt_pdev,
169 				      ipa_res->tx_comp_doorbell_dmaaddr,
170 				      ipa_res->rx_ready_doorbell_dmaaddr);
171 
172 	if (ret) {
173 		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
174 			  "htt_ipa_uc_set_doorbell_dmaaddr fail: %d", ret);
175 		return QDF_STATUS_E_FAILURE;
176 	}
177 
178 	return QDF_STATUS_SUCCESS;
179 }
180 
ol_txrx_ipa_uc_set_active(struct cdp_soc_t * soc_hdl,uint8_t pdev_id,bool uc_active,bool is_tx)181 QDF_STATUS ol_txrx_ipa_uc_set_active(struct cdp_soc_t *soc_hdl, uint8_t pdev_id,
182 				     bool uc_active, bool is_tx)
183 {
184 	struct ol_txrx_soc_t *soc = cdp_soc_t_to_ol_txrx_soc_t(soc_hdl);
185 	ol_txrx_pdev_handle pdev = ol_txrx_get_pdev_from_pdev_id(soc, pdev_id);
186 	int ret;
187 
188 	if (!pdev) {
189 		ol_txrx_err("Invalid instance");
190 		return QDF_STATUS_E_FAILURE;
191 	}
192 
193 	ret = htt_h2t_ipa_uc_set_active(pdev->htt_pdev, uc_active, is_tx);
194 	if (ret) {
195 		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
196 			  "htt_h2t_ipa_uc_set_active fail: %d", ret);
197 		return QDF_STATUS_E_FAILURE;
198 	}
199 
200 	return QDF_STATUS_SUCCESS;
201 }
202 
ol_txrx_ipa_uc_op_response(struct cdp_soc_t * soc_hdl,uint8_t pdev_id,uint8_t * op_msg)203 QDF_STATUS ol_txrx_ipa_uc_op_response(struct cdp_soc_t *soc_hdl,
204 				      uint8_t pdev_id, uint8_t *op_msg)
205 {
206 	struct ol_txrx_soc_t *soc = cdp_soc_t_to_ol_txrx_soc_t(soc_hdl);
207 	ol_txrx_pdev_handle pdev = ol_txrx_get_pdev_from_pdev_id(soc, pdev_id);
208 
209 	if (!pdev) {
210 		ol_txrx_err("Invalid instance");
211 		return QDF_STATUS_E_FAILURE;
212 	}
213 
214 	if (pdev->ipa_uc_op_cb) {
215 		pdev->ipa_uc_op_cb(op_msg, pdev->usr_ctxt);
216 	} else {
217 		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
218 		    "%s: IPA callback function is not registered", __func__);
219 		qdf_mem_free(op_msg);
220 		return QDF_STATUS_E_FAILURE;
221 	}
222 
223 	return QDF_STATUS_SUCCESS;
224 }
225 
ol_txrx_ipa_uc_register_op_cb(struct cdp_soc_t * soc_hdl,uint8_t pdev_id,ipa_uc_op_cb_type op_cb,void * usr_ctxt)226 QDF_STATUS ol_txrx_ipa_uc_register_op_cb(struct cdp_soc_t *soc_hdl,
227 					 uint8_t pdev_id,
228 					 ipa_uc_op_cb_type op_cb,
229 					 void *usr_ctxt)
230 {
231 	struct ol_txrx_soc_t *soc = cdp_soc_t_to_ol_txrx_soc_t(soc_hdl);
232 	ol_txrx_pdev_handle pdev = ol_txrx_get_pdev_from_pdev_id(soc, pdev_id);
233 
234 	if (!pdev) {
235 		ol_txrx_err("Invalid instance");
236 		return QDF_STATUS_E_FAILURE;
237 	}
238 
239 	pdev->ipa_uc_op_cb = op_cb;
240 	pdev->usr_ctxt = usr_ctxt;
241 
242 	return QDF_STATUS_SUCCESS;
243 }
244 
ol_txrx_ipa_uc_get_stat(struct cdp_soc_t * soc_hdl,uint8_t pdev_id)245 QDF_STATUS ol_txrx_ipa_uc_get_stat(struct cdp_soc_t *soc_hdl, uint8_t pdev_id)
246 {
247 	struct ol_txrx_soc_t *soc = cdp_soc_t_to_ol_txrx_soc_t(soc_hdl);
248 	ol_txrx_pdev_handle pdev = ol_txrx_get_pdev_from_pdev_id(soc, pdev_id);
249 	int ret;
250 
251 	if (!pdev) {
252 		ol_txrx_err("Invalid instance");
253 		return QDF_STATUS_E_FAILURE;
254 	}
255 
256 	ret = htt_h2t_ipa_uc_get_stats(pdev->htt_pdev);
257 
258 	if (ret) {
259 		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
260 			  "htt_h2t_ipa_uc_get_stats fail: %d", ret);
261 		return QDF_STATUS_E_FAILURE;
262 	}
263 
264 	return QDF_STATUS_SUCCESS;
265 }
266 
ol_txrx_ipa_enable_autonomy(struct cdp_soc_t * soc_hdl,uint8_t pdev_id)267 QDF_STATUS ol_txrx_ipa_enable_autonomy(struct cdp_soc_t *soc_hdl,
268 				       uint8_t pdev_id)
269 {
270 	/* TBD */
271 	return QDF_STATUS_SUCCESS;
272 }
273 
ol_txrx_ipa_disable_autonomy(struct cdp_soc_t * soc_hdl,uint8_t pdev_id)274 QDF_STATUS ol_txrx_ipa_disable_autonomy(struct cdp_soc_t *soc_hdl,
275 					uint8_t pdev_id)
276 {
277 	/* TBD */
278 	return QDF_STATUS_SUCCESS;
279 }
280 
__ol_txrx_ipa_tx_buf_smmu_mapping(struct ol_txrx_pdev_t * pdev,bool create)281 static QDF_STATUS __ol_txrx_ipa_tx_buf_smmu_mapping(struct ol_txrx_pdev_t *pdev,
282 						    bool create)
283 {
284 	uint32_t index;
285 	uint32_t unmap_cnt = 0;
286 	uint32_t tx_buffer_cnt;
287 	QDF_STATUS ret = QDF_STATUS_SUCCESS;
288 	struct htt_pdev_t *htt_pdev = pdev->htt_pdev;
289 	qdf_mem_info_t *mem_map_table = NULL, *mem_info = NULL;
290 
291 	if (!htt_pdev) {
292 		ol_txrx_err("htt_pdev is NULL");
293 		return QDF_STATUS_E_FAILURE;
294 	}
295 
296 	if (!qdf_mem_smmu_s1_enabled(htt_pdev->osdev)) {
297 		ol_txrx_info("SMMU-S1 mapping is disabled");
298 		return QDF_STATUS_SUCCESS;
299 	}
300 
301 	tx_buffer_cnt = htt_pdev->ipa_uc_tx_rsc.alloc_tx_buf_cnt;
302 	mem_map_table = qdf_mem_map_table_alloc(tx_buffer_cnt);
303 	if (!mem_map_table) {
304 		ol_txrx_err("Failed to allocate memory");
305 		return QDF_STATUS_E_FAILURE;
306 	}
307 	mem_info = mem_map_table;
308 
309 	for (index = 0; index < tx_buffer_cnt; index++) {
310 		if (htt_pdev->ipa_uc_tx_rsc.tx_buf_pool_strg[index]) {
311 			*mem_info = htt_pdev->ipa_uc_tx_rsc.
312 					tx_buf_pool_strg[index]->mem_info;
313 			mem_info++;
314 			unmap_cnt++;
315 		}
316 	}
317 
318 	ret = cds_smmu_map_unmap(create, unmap_cnt, mem_map_table);
319 	qdf_assert_always(!ret);
320 	qdf_mem_free(mem_map_table);
321 	htt_pdev->ipa_uc_tx_rsc.ipa_smmu_mapped = create;
322 	ol_txrx_info("smmu_map_unmap:%d of %d Tx buffers", create, unmap_cnt);
323 
324 	return ret;
325 }
326 
ol_txrx_ipa_tx_buf_smmu_mapping(struct cdp_soc_t * soc_hdl,uint8_t pdev_id,const char * func,uint32_t line)327 QDF_STATUS ol_txrx_ipa_tx_buf_smmu_mapping(struct cdp_soc_t *soc_hdl,
328 					   uint8_t pdev_id,
329 					   const char *func,
330 					   uint32_t line)
331 {
332 	QDF_STATUS ret;
333 	struct ol_txrx_soc_t *soc = cdp_soc_t_to_ol_txrx_soc_t(soc_hdl);
334 	ol_txrx_pdev_handle pdev = ol_txrx_get_pdev_from_pdev_id(soc, pdev_id);
335 
336 	if (!pdev) {
337 		ol_txrx_err("invalid instance");
338 		return QDF_STATUS_E_FAILURE;
339 	}
340 
341 	if (!qdf_mem_smmu_s1_enabled(pdev->htt_pdev->osdev)) {
342 		ol_txrx_err("SMMU S1 disabled");
343 		return QDF_STATUS_SUCCESS;
344 	}
345 	ret = __ol_txrx_ipa_tx_buf_smmu_mapping(pdev, true);
346 
347 	return ret;
348 }
349 
ol_txrx_ipa_tx_buf_smmu_unmapping(struct cdp_soc_t * soc_hdl,uint8_t pdev_id,const char * func,uint32_t line)350 QDF_STATUS ol_txrx_ipa_tx_buf_smmu_unmapping(struct cdp_soc_t *soc_hdl,
351 					     uint8_t pdev_id,
352 					     const char *func,
353 					     uint32_t line)
354 {
355 	QDF_STATUS ret;
356 	struct ol_txrx_soc_t *soc = cdp_soc_t_to_ol_txrx_soc_t(soc_hdl);
357 	ol_txrx_pdev_handle pdev = ol_txrx_get_pdev_from_pdev_id(soc, pdev_id);
358 
359 	if (!pdev) {
360 		ol_txrx_err("invalid instance");
361 		return QDF_STATUS_E_FAILURE;
362 	}
363 
364 	if (!qdf_mem_smmu_s1_enabled(pdev->htt_pdev->osdev)) {
365 		ol_txrx_err("SMMU S1 disabled");
366 		return QDF_STATUS_SUCCESS;
367 	}
368 	ret = __ol_txrx_ipa_tx_buf_smmu_mapping(pdev, false);
369 
370 	return ret;
371 }
372 
373 #ifdef CONFIG_IPA_WDI_UNIFIED_API
374 
375 #ifndef QCA_LL_TX_FLOW_CONTROL_V2
ol_txrx_setup_mcc_sys_pipes(qdf_ipa_sys_connect_params_t * sys_in,qdf_ipa_wdi_conn_in_params_t * pipe_in)376 static inline void ol_txrx_setup_mcc_sys_pipes(
377 		qdf_ipa_sys_connect_params_t *sys_in,
378 		qdf_ipa_wdi_conn_in_params_t *pipe_in)
379 {
380 	int i = 0;
381 
382 	/* Setup MCC sys pipe */
383 	QDF_IPA_WDI_CONN_IN_PARAMS_NUM_SYS_PIPE_NEEDED(pipe_in) =
384 			OL_TXRX_IPA_MAX_IFACE;
385 	for (i = 0; i < OL_TXRX_IPA_MAX_IFACE; i++)
386 		memcpy(&QDF_IPA_WDI_CONN_IN_PARAMS_SYS_IN(pipe_in)[i],
387 		       &sys_in[i], sizeof(qdf_ipa_sys_connect_params_t));
388 }
389 #else
ol_txrx_setup_mcc_sys_pipes(qdf_ipa_sys_connect_params_t * sys_in,qdf_ipa_wdi_conn_in_params_t * pipe_in)390 static inline void ol_txrx_setup_mcc_sys_pipes(
391 		qdf_ipa_sys_connect_params_t *sys_in,
392 		qdf_ipa_wdi_conn_in_params_t *pipe_in)
393 {
394 	QDF_IPA_WDI_CONN_IN_PARAMS_NUM_SYS_PIPE_NEEDED(pipe_in) = 0;
395 }
396 #endif
397 
398 #ifdef ENABLE_SMMU_S1_TRANSLATION
399 #ifdef QCA_WIFI_3_0
400 /**
401  * ol_txrx_ipa_wdi_tx_smmu_params() - Config IPA TX params
402  * @ipa_res: IPA resources
403  * @tx_smmu: IPA WDI pipe setup info
404  *
405  * Return: None
406  */
ol_txrx_ipa_wdi_tx_smmu_params(struct ol_txrx_ipa_resources * ipa_res,qdf_ipa_wdi_pipe_setup_info_smmu_t * tx_smmu,bool over_gsi)407 static inline void ol_txrx_ipa_wdi_tx_smmu_params(
408 				struct ol_txrx_ipa_resources *ipa_res,
409 				qdf_ipa_wdi_pipe_setup_info_smmu_t *tx_smmu,
410 				bool over_gsi)
411 {
412 	QDF_IPA_WDI_SETUP_INFO_SMMU_CLIENT(tx_smmu) =
413 		QDF_IPA_CLIENT_WLAN_WDI2_CONS;
414 	qdf_mem_copy(&QDF_IPA_WDI_SETUP_INFO_SMMU_TRANSFER_RING_BASE(
415 				tx_smmu),
416 		     &ipa_res->tx_comp_ring->sgtable,
417 		     sizeof(sgtable_t));
418 	QDF_IPA_WDI_SETUP_INFO_SMMU_TRANSFER_RING_SIZE(tx_smmu) =
419 		ipa_res->tx_comp_ring->mem_info.size;
420 	qdf_mem_copy(&QDF_IPA_WDI_SETUP_INFO_SMMU_EVENT_RING_BASE(
421 				tx_smmu),
422 		     &ipa_res->ce_sr->sgtable,
423 		     sizeof(sgtable_t));
424 	QDF_IPA_WDI_SETUP_INFO_SMMU_EVENT_RING_SIZE(tx_smmu) =
425 		ipa_res->ce_sr_ring_size;
426 	QDF_IPA_WDI_SETUP_INFO_SMMU_EVENT_RING_DOORBELL_PA(tx_smmu) =
427 		ipa_res->ce_reg_paddr;
428 	if (over_gsi)
429 		QDF_IPA_WDI_SETUP_INFO_SMMU_IS_EVT_RN_DB_PCIE_ADDR(tx_smmu) = true;
430 	QDF_IPA_WDI_SETUP_INFO_SMMU_NUM_PKT_BUFFERS(tx_smmu) =
431 		ipa_res->tx_num_alloc_buffer;
432 	QDF_IPA_WDI_SETUP_INFO_SMMU_PKT_OFFSET(tx_smmu) = 0;
433 }
434 
435 /**
436  * ol_txrx_ipa_wdi_rx_smmu_params() - Config IPA RX params
437  * @ipa_res: IPA resources
438  * @rx_smmu: IPA WDI pipe setup info
439  *
440  * Return: None
441  */
ol_txrx_ipa_wdi_rx_smmu_params(struct ol_txrx_ipa_resources * ipa_res,qdf_ipa_wdi_pipe_setup_info_smmu_t * rx_smmu,bool over_gsi)442 static inline void ol_txrx_ipa_wdi_rx_smmu_params(
443 				struct ol_txrx_ipa_resources *ipa_res,
444 				qdf_ipa_wdi_pipe_setup_info_smmu_t *rx_smmu,
445 				bool over_gsi)
446 {
447 	QDF_IPA_WDI_SETUP_INFO_SMMU_CLIENT(rx_smmu) =
448 		QDF_IPA_CLIENT_WLAN_WDI2_PROD;
449 	qdf_mem_copy(&QDF_IPA_WDI_SETUP_INFO_SMMU_TRANSFER_RING_BASE(
450 				rx_smmu),
451 		     &ipa_res->rx_rdy_ring->sgtable,
452 		     sizeof(sgtable_t));
453 	QDF_IPA_WDI_SETUP_INFO_SMMU_TRANSFER_RING_SIZE(rx_smmu) =
454 		ipa_res->rx_rdy_ring->mem_info.size;
455 	QDF_IPA_WDI_SETUP_INFO_SMMU_TRANSFER_RING_DOORBELL_PA(rx_smmu) =
456 		ipa_res->rx_proc_done_idx->mem_info.pa;
457 	if (over_gsi)
458 		QDF_IPA_WDI_SETUP_INFO_SMMU_IS_TXR_RN_DB_PCIE_ADDR(rx_smmu) = false;
459 	qdf_mem_copy(&QDF_IPA_WDI_SETUP_INFO_SMMU_EVENT_RING_BASE(
460 				rx_smmu),
461 		     &ipa_res->rx2_rdy_ring->sgtable,
462 		     sizeof(sgtable_t));
463 	QDF_IPA_WDI_SETUP_INFO_SMMU_EVENT_RING_SIZE(rx_smmu) =
464 		ipa_res->rx2_rdy_ring->mem_info.size;
465 	QDF_IPA_WDI_SETUP_INFO_SMMU_EVENT_RING_DOORBELL_PA(rx_smmu) =
466 		ipa_res->rx2_proc_done_idx->mem_info.pa;
467 	if (over_gsi)
468 		QDF_IPA_WDI_SETUP_INFO_SMMU_IS_EVT_RN_DB_PCIE_ADDR(rx_smmu) = false;
469 	QDF_IPA_WDI_SETUP_INFO_SMMU_PKT_OFFSET(rx_smmu) = 0;
470 
471 }
472 #else
473 
ol_txrx_ipa_wdi_tx_smmu_params(struct ol_txrx_ipa_resources * ipa_res,qdf_ipa_wdi_pipe_setup_info_smmu_t * tx_smmu,bool over_gsi)474 static inline void ol_txrx_ipa_wdi_tx_smmu_params(
475 				struct ol_txrx_ipa_resources *ipa_res,
476 				qdf_ipa_wdi_pipe_setup_info_smmu_t *tx_smmu,
477 				bool over_gsi)
478 {
479 	QDF_IPA_WDI_SETUP_INFO_SMMU_CLIENT(tx_smmu) =
480 		QDF_IPA_CLIENT_WLAN_LEGACY_CONS;
481 	qdf_mem_copy(&QDF_IPA_WDI_SETUP_INFO_SMMU_TRANSFER_RING_BASE(
482 				tx_smmu),
483 		     &ipa_res->tx_comp_ring->sgtable,
484 		     sizeof(sgtable_t));
485 	QDF_IPA_WDI_SETUP_INFO_SMMU_TRANSFER_RING_SIZE(tx_smmu) =
486 		ipa_res->tx_comp_ring->mem_info.size;
487 	qdf_mem_copy(&QDF_IPA_WDI_SETUP_INFO_SMMU_EVENT_RING_BASE(
488 				tx_smmu),
489 		     &ipa_res->ce_sr->sgtable,
490 		     sizeof(sgtable_t));
491 	QDF_IPA_WDI_SETUP_INFO_SMMU_EVENT_RING_SIZE(tx_smmu) =
492 		ipa_res->ce_sr_ring_size;
493 	QDF_IPA_WDI_SETUP_INFO_SMMU_EVENT_RING_DOORBELL_PA(tx_smmu) =
494 		ipa_res->ce_reg_paddr;
495 	QDF_IPA_WDI_SETUP_INFO_SMMU_NUM_PKT_BUFFERS(tx_smmu) =
496 		ipa_res->tx_num_alloc_buffer;
497 	QDF_IPA_WDI_SETUP_INFO_SMMU_PKT_OFFSET(tx_smmu) = 0;
498 }
499 
ol_txrx_ipa_wdi_rx_smmu_params(struct ol_txrx_ipa_resources * ipa_res,qdf_ipa_wdi_pipe_setup_info_smmu_t * rx_smmu,bool over_gsi)500 static inline void ol_txrx_ipa_wdi_rx_smmu_params(
501 				struct ol_txrx_ipa_resources *ipa_res,
502 				qdf_ipa_wdi_pipe_setup_info_smmu_t *rx_smmu,
503 				bool over_gsi)
504 {
505 	QDF_IPA_WDI_SETUP_INFO_SMMU_CLIENT(rx_smmu) =
506 		QDF_IPA_CLIENT_WLAN_LEGACY_PROD;
507 	qdf_mem_copy(&QDF_IPA_WDI_SETUP_INFO_SMMU_TRANSFER_RING_BASE(
508 				rx_smmu),
509 		     &ipa_res->rx_rdy_ring->sgtable,
510 		     sizeof(sgtable_t));
511 	QDF_IPA_WDI_SETUP_INFO_SMMU_TRANSFER_RING_SIZE(rx_smmu) =
512 		ipa_res->rx_rdy_ring->mem_info.size;
513 	QDF_IPA_WDI_SETUP_INFO_SMMU_TRANSFER_RING_DOORBELL_PA(rx_smmu) =
514 		ipa_res->rx_proc_done_idx->mem_info.pa;
515 	QDF_IPA_WDI_SETUP_INFO_SMMU_PKT_OFFSET(rx_smmu) = 0;
516 }
517 
518 #endif
519 
520 #else
521 
ol_txrx_ipa_wdi_tx_smmu_params(struct ol_txrx_ipa_resources * ipa_res,qdf_ipa_wdi_pipe_setup_info_smmu_t * tx_smmu,bool over_gsi)522 static inline void ol_txrx_ipa_wdi_tx_smmu_params(
523 				struct ol_txrx_ipa_resources *ipa_res,
524 				qdf_ipa_wdi_pipe_setup_info_smmu_t *tx_smmu,
525 				bool over_gsi)
526 {
527 }
528 
ol_txrx_ipa_wdi_rx_smmu_params(struct ol_txrx_ipa_resources * ipa_res,qdf_ipa_wdi_pipe_setup_info_smmu_t * rx_smmu,bool over_gsi)529 static inline void ol_txrx_ipa_wdi_rx_smmu_params(
530 				struct ol_txrx_ipa_resources *ipa_res,
531 				qdf_ipa_wdi_pipe_setup_info_smmu_t *rx_smmu,
532 				bool over_gsi)
533 {
534 }
535 #endif
536 
537 #ifdef QCA_WIFI_3_0
538 /**
539  * ol_txrx_ipa_wdi_tx_params() - Config IPA TX params
540  * @ipa_res: IPA resources
541  * @tx: IPA WDI pipe setup info
542  *
543  * Return: None
544  */
ol_txrx_ipa_wdi_tx_params(struct ol_txrx_ipa_resources * ipa_res,qdf_ipa_wdi_pipe_setup_info_t * tx,bool over_gsi)545 static inline void ol_txrx_ipa_wdi_tx_params(
546 				struct ol_txrx_ipa_resources *ipa_res,
547 				qdf_ipa_wdi_pipe_setup_info_t *tx,
548 				bool over_gsi)
549 {
550 	qdf_device_t osdev = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
551 
552 	if (!osdev)
553 		return;
554 
555 	QDF_IPA_WDI_SETUP_INFO_CLIENT(tx) = IPA_CLIENT_WLAN1_CONS;
556 	QDF_IPA_WDI_SETUP_INFO_TRANSFER_RING_BASE_PA(tx) =
557 		qdf_mem_get_dma_addr(osdev,
558 				&ipa_res->tx_comp_ring->mem_info);
559 	QDF_IPA_WDI_SETUP_INFO_TRANSFER_RING_SIZE(tx) =
560 		ipa_res->tx_comp_ring->mem_info.size;
561 	QDF_IPA_WDI_SETUP_INFO_EVENT_RING_BASE_PA(tx) =
562 		qdf_mem_get_dma_addr(osdev,
563 				&ipa_res->ce_sr->mem_info);
564 	QDF_IPA_WDI_SETUP_INFO_EVENT_RING_SIZE(tx) =
565 		ipa_res->ce_sr_ring_size;
566 	QDF_IPA_WDI_SETUP_INFO_EVENT_RING_DOORBELL_PA(tx) =
567 		ipa_res->ce_reg_paddr;
568 	if (over_gsi)
569 		QDF_IPA_WDI_SETUP_INFO_IS_EVT_RN_DB_PCIE_ADDR(tx) = true;
570 	QDF_IPA_WDI_SETUP_INFO_NUM_PKT_BUFFERS(tx) =
571 		ipa_res->tx_num_alloc_buffer;
572 	QDF_IPA_WDI_SETUP_INFO_PKT_OFFSET(tx) = 0;
573 }
574 
575 /**
576  * ol_txrx_ipa_wdi_rx_params() - Config IPA RX params
577  * @ipa_res: IPA resources
578  * @rx: IPA WDI pipe setup info
579  *
580  * Return: None
581  */
ol_txrx_ipa_wdi_rx_params(struct ol_txrx_ipa_resources * ipa_res,qdf_ipa_wdi_pipe_setup_info_t * rx,bool over_gsi)582 static inline void ol_txrx_ipa_wdi_rx_params(
583 				struct ol_txrx_ipa_resources *ipa_res,
584 				qdf_ipa_wdi_pipe_setup_info_t *rx,
585 				bool over_gsi)
586 {
587 	QDF_IPA_WDI_SETUP_INFO_CLIENT(rx) = IPA_CLIENT_WLAN1_PROD;
588 	QDF_IPA_WDI_SETUP_INFO_TRANSFER_RING_BASE_PA(rx) =
589 		ipa_res->rx_rdy_ring->mem_info.pa;
590 	QDF_IPA_WDI_SETUP_INFO_TRANSFER_RING_SIZE(rx) =
591 		ipa_res->rx_rdy_ring->mem_info.size;
592 	QDF_IPA_WDI_SETUP_INFO_TRANSFER_RING_DOORBELL_PA(rx) =
593 		ipa_res->rx_proc_done_idx->mem_info.pa;
594 	if (over_gsi)
595 		QDF_IPA_WDI_SETUP_INFO_IS_TXR_RN_DB_PCIE_ADDR(rx) = false;
596 	QDF_IPA_WDI_SETUP_INFO_EVENT_RING_BASE_PA(rx) =
597 		ipa_res->rx2_rdy_ring->mem_info.pa;
598 	QDF_IPA_WDI_SETUP_INFO_EVENT_RING_SIZE(rx) =
599 		ipa_res->rx2_rdy_ring->mem_info.size;
600 	QDF_IPA_WDI_SETUP_INFO_EVENT_RING_DOORBELL_PA(rx) =
601 		ipa_res->rx2_proc_done_idx->mem_info.pa;
602 	if (over_gsi)
603 		QDF_IPA_WDI_SETUP_INFO_IS_EVT_RN_DB_PCIE_ADDR(rx) = false;
604 	QDF_IPA_WDI_SETUP_INFO_PKT_OFFSET(rx) = 0;
605 }
606 
607 #else
ol_txrx_ipa_wdi_tx_params(struct ol_txrx_ipa_resources * ipa_res,qdf_ipa_wdi_pipe_setup_info_t * tx,bool over_gsi)608 static inline void ol_txrx_ipa_wdi_tx_params(
609 				struct ol_txrx_ipa_resources *ipa_res,
610 				qdf_ipa_wdi_pipe_setup_info_t *tx,
611 				bool over_gsi)
612 {
613 	qdf_device_t osdev = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
614 
615 	if (!osdev)
616 		return;
617 
618 	QDF_IPA_WDI_SETUP_INFO_CLIENT(tx) = QDF_IPA_CLIENT_WLAN_LEGACY_CONS;
619 	QDF_IPA_WDI_SETUP_INFO_TRANSFER_RING_BASE_PA(tx) =
620 		qdf_mem_get_dma_addr(osdev,
621 				&ipa_res->tx_comp_ring->mem_info);
622 	QDF_IPA_WDI_SETUP_INFO_TRANSFER_RING_SIZE(tx) =
623 		ipa_res->tx_comp_ring->mem_info.size;
624 	QDF_IPA_WDI_SETUP_INFO_EVENT_RING_BASE_PA(tx) =
625 		qdf_mem_get_dma_addr(osdev,
626 				&ipa_res->ce_sr->mem_info);
627 	QDF_IPA_WDI_SETUP_INFO_EVENT_RING_SIZE(tx) =
628 		ipa_res->ce_sr_ring_size;
629 	QDF_IPA_WDI_SETUP_INFO_EVENT_RING_DOORBELL_PA(tx) =
630 		ipa_res->ce_reg_paddr;
631 	QDF_IPA_WDI_SETUP_INFO_NUM_PKT_BUFFERS(tx) =
632 		ipa_res->tx_num_alloc_buffer;
633 	QDF_IPA_WDI_SETUP_INFO_PKT_OFFSET(tx) = 0;
634 }
635 
ol_txrx_ipa_wdi_rx_params(struct ol_txrx_ipa_resources * ipa_res,qdf_ipa_wdi_pipe_setup_info_t * rx,bool over_gsi)636 static inline void ol_txrx_ipa_wdi_rx_params(
637 				struct ol_txrx_ipa_resources *ipa_res,
638 				qdf_ipa_wdi_pipe_setup_info_t *rx,
639 				bool over_gsi)
640 {
641 	QDF_IPA_WDI_SETUP_INFO_CLIENT(rx) = QDF_IPA_CLIENT_WLAN_LEGACY_PROD;
642 	QDF_IPA_WDI_SETUP_INFO_TRANSFER_RING_BASE_PA(rx) =
643 		ipa_res->rx_rdy_ring->mem_info.pa;
644 	QDF_IPA_WDI_SETUP_INFO_TRANSFER_RING_SIZE(rx) =
645 		ipa_res->rx_rdy_ring->mem_info.size;
646 	QDF_IPA_WDI_SETUP_INFO_TRANSFER_RING_DOORBELL_PA(rx) =
647 		ipa_res->rx_proc_done_idx->mem_info.pa;
648 	QDF_IPA_WDI_SETUP_INFO_PKT_OFFSET(rx) = 0;
649 }
650 
651 #endif
652 
ol_txrx_ipa_setup(struct cdp_soc_t * soc_hdl,uint8_t pdev_id,void * ipa_i2w_cb,void * ipa_w2i_cb,void * ipa_wdi_meter_notifier_cb,uint32_t ipa_desc_size,void * ipa_priv,bool is_rm_enabled,uint32_t * p_tx_pipe_handle,uint32_t * p_rx_pipe_handle,bool is_smmu_enabled,qdf_ipa_sys_connect_params_t * sys_in,bool over_gsi,qdf_ipa_wdi_hdl_t hdl,qdf_ipa_wdi_hdl_t id,void * ipa_ast_notify_cb)653 QDF_STATUS ol_txrx_ipa_setup(struct cdp_soc_t *soc_hdl, uint8_t pdev_id,
654 			     void *ipa_i2w_cb, void *ipa_w2i_cb,
655 			     void *ipa_wdi_meter_notifier_cb,
656 			     uint32_t ipa_desc_size, void *ipa_priv,
657 			     bool is_rm_enabled, uint32_t *p_tx_pipe_handle,
658 			     uint32_t *p_rx_pipe_handle, bool is_smmu_enabled,
659 			     qdf_ipa_sys_connect_params_t *sys_in,
660 			     bool over_gsi,
661 			     qdf_ipa_wdi_hdl_t hdl,
662 			     qdf_ipa_wdi_hdl_t id,
663 			     void *ipa_ast_notify_cb)
664 {
665 	struct ol_txrx_soc_t *soc = cdp_soc_t_to_ol_txrx_soc_t(soc_hdl);
666 	ol_txrx_pdev_handle pdev = ol_txrx_get_pdev_from_pdev_id(soc, pdev_id);
667 	struct ol_txrx_ipa_resources *ipa_res;
668 	qdf_ipa_ep_cfg_t *tx_cfg;
669 	qdf_ipa_ep_cfg_t *rx_cfg;
670 	qdf_ipa_wdi_pipe_setup_info_t *tx;
671 	qdf_ipa_wdi_pipe_setup_info_t *rx;
672 	qdf_ipa_wdi_pipe_setup_info_smmu_t *tx_smmu;
673 	qdf_ipa_wdi_pipe_setup_info_smmu_t *rx_smmu;
674 	qdf_ipa_wdi_conn_in_params_t *pipe_in = NULL;
675 	qdf_ipa_wdi_conn_out_params_t pipe_out;
676 	qdf_device_t osdev = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
677 	uint32_t tx_comp_db_dmaaddr = 0, rx_rdy_db_dmaaddr = 0;
678 	int ret;
679 
680 	if (!pdev) {
681 		ol_txrx_err("Invalid instance");
682 		return QDF_STATUS_E_FAILURE;
683 	}
684 
685 	if (!osdev)
686 		return QDF_STATUS_E_NOENT;
687 
688 	pipe_in = qdf_mem_malloc(sizeof(*pipe_in));
689 	if (!pipe_in)
690 		return QDF_STATUS_E_NOMEM;
691 
692 	ipa_res = &pdev->ipa_resource;
693 	qdf_mem_zero(pipe_in, sizeof(*pipe_in));
694 	qdf_mem_zero(&pipe_out, sizeof(pipe_out));
695 
696 	ol_txrx_setup_mcc_sys_pipes(sys_in, pipe_in);
697 
698 	/* TX PIPE */
699 	if (is_smmu_enabled) {
700 		QDF_IPA_WDI_CONN_IN_PARAMS_SMMU_ENABLED(pipe_in) = true;
701 		tx_smmu = &QDF_IPA_WDI_CONN_IN_PARAMS_TX_SMMU(pipe_in);
702 		tx_cfg = &QDF_IPA_WDI_SETUP_INFO_SMMU_EP_CFG(tx_smmu);
703 	} else {
704 		QDF_IPA_WDI_CONN_IN_PARAMS_SMMU_ENABLED(pipe_in) = false;
705 		tx = &QDF_IPA_WDI_CONN_IN_PARAMS_TX(pipe_in);
706 		tx_cfg = &QDF_IPA_WDI_SETUP_INFO_EP_CFG(tx);
707 	}
708 
709 	QDF_IPA_EP_CFG_NAT_EN(tx_cfg) = IPA_BYPASS_NAT;
710 	QDF_IPA_EP_CFG_HDR_LEN(tx_cfg) = OL_TXRX_IPA_UC_WLAN_TX_HDR_LEN;
711 	QDF_IPA_EP_CFG_HDR_OFST_PKT_SIZE_VALID(tx_cfg) = 1;
712 	QDF_IPA_EP_CFG_HDR_OFST_PKT_SIZE(tx_cfg) = 0;
713 	QDF_IPA_EP_CFG_HDR_ADDITIONAL_CONST_LEN(tx_cfg) =
714 		OL_TXRX_IPA_UC_WLAN_8023_HDR_SIZE;
715 	QDF_IPA_EP_CFG_MODE(tx_cfg) = IPA_BASIC;
716 	QDF_IPA_EP_CFG_HDR_LITTLE_ENDIAN(tx_cfg) = true;
717 
718 	if (is_smmu_enabled)
719 		ol_txrx_ipa_wdi_tx_smmu_params(ipa_res, tx_smmu, over_gsi);
720 	else
721 		ol_txrx_ipa_wdi_tx_params(ipa_res, tx, over_gsi);
722 
723 
724 	/* RX PIPE */
725 	if (is_smmu_enabled) {
726 		rx_smmu = &QDF_IPA_WDI_CONN_IN_PARAMS_RX_SMMU(pipe_in);
727 		rx_cfg = &QDF_IPA_WDI_SETUP_INFO_EP_CFG(rx_smmu);
728 	} else {
729 		rx = &QDF_IPA_WDI_CONN_IN_PARAMS_RX(pipe_in);
730 		rx_cfg = &QDF_IPA_WDI_SETUP_INFO_EP_CFG(rx);
731 	}
732 
733 	QDF_IPA_EP_CFG_NAT_EN(rx_cfg) = IPA_BYPASS_NAT;
734 	QDF_IPA_EP_CFG_HDR_LEN(rx_cfg) = OL_TXRX_IPA_UC_WLAN_RX_HDR_LEN;
735 	QDF_IPA_EP_CFG_HDR_OFST_PKT_SIZE_VALID(rx_cfg) = 1;
736 	QDF_IPA_EP_CFG_HDR_OFST_PKT_SIZE(rx_cfg) = 0;
737 	QDF_IPA_EP_CFG_HDR_ADDITIONAL_CONST_LEN(rx_cfg) =
738 		OL_TXRX_IPA_UC_WLAN_8023_HDR_SIZE;
739 	QDF_IPA_EP_CFG_HDR_OFST_METADATA_VALID(rx_cfg) = 0;
740 	QDF_IPA_EP_CFG_HDR_METADATA_REG_VALID(rx_cfg) = 1;
741 	QDF_IPA_EP_CFG_MODE(rx_cfg) = IPA_BASIC;
742 	QDF_IPA_EP_CFG_HDR_LITTLE_ENDIAN(rx_cfg) = true;
743 
744 	if (is_smmu_enabled)
745 		ol_txrx_ipa_wdi_rx_smmu_params(ipa_res, rx_smmu, over_gsi);
746 	else
747 		ol_txrx_ipa_wdi_rx_params(ipa_res, rx, over_gsi);
748 
749 	QDF_IPA_WDI_CONN_IN_PARAMS_NOTIFY(pipe_in) = ipa_w2i_cb;
750 	QDF_IPA_WDI_CONN_IN_PARAMS_PRIV(pipe_in) = ipa_priv;
751 
752 	/* Connect WDI IPA PIPE */
753 	ret = qdf_ipa_wdi_conn_pipes(pipe_in, &pipe_out);
754 	if (ret) {
755 		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
756 			  "%s: ipa_wdi_conn_pipes: IPA pipe setup failed: ret=%d",
757 			  __func__, ret);
758 		qdf_mem_free(pipe_in);
759 		return QDF_STATUS_E_FAILURE;
760 	}
761 
762 	/* IPA uC Doorbell registers */
763 	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
764 		  "%s: Tx DB PA=0x%x, Rx DB PA=0x%x", __func__,
765 		  (unsigned int)
766 			QDF_IPA_WDI_CONN_OUT_PARAMS_TX_UC_DB_PA(&pipe_out),
767 		  (unsigned int)
768 			QDF_IPA_WDI_CONN_OUT_PARAMS_RX_UC_DB_PA(&pipe_out));
769 
770 	ipa_res->tx_comp_doorbell_dmaaddr =
771 		QDF_IPA_WDI_CONN_OUT_PARAMS_TX_UC_DB_PA(&pipe_out);
772 	ipa_res->rx_ready_doorbell_dmaaddr =
773 		QDF_IPA_WDI_CONN_OUT_PARAMS_RX_UC_DB_PA(&pipe_out);
774 
775 	if (is_smmu_enabled) {
776 		pld_smmu_map(osdev->dev, ipa_res->tx_comp_doorbell_dmaaddr,
777 			     &tx_comp_db_dmaaddr, sizeof(uint32_t));
778 		ipa_res->tx_comp_doorbell_dmaaddr = tx_comp_db_dmaaddr;
779 
780 		pld_smmu_map(osdev->dev, ipa_res->rx_ready_doorbell_dmaaddr,
781 			     &rx_rdy_db_dmaaddr, sizeof(uint32_t));
782 		ipa_res->rx_ready_doorbell_dmaaddr = rx_rdy_db_dmaaddr;
783 	}
784 
785 	qdf_mem_free(pipe_in);
786 	return QDF_STATUS_SUCCESS;
787 }
788 
789 /**
790  * ol_txrx_ipa_cleanup() - Disconnect IPA pipes
791  * @soc_hdl: soc handle
792  * @pdev_id: pdev id
793  * @tx_pipe_handle: Tx pipe handle
794  * @rx_pipe_handle: Rx pipe handle
795  *
796  * Return: QDF_STATUS
797  */
ol_txrx_ipa_cleanup(struct cdp_soc_t * soc_hdl,uint8_t pdev_id,uint32_t tx_pipe_handle,uint32_t rx_pipe_handle,qdf_ipa_wdi_hdl_t hdl)798 QDF_STATUS ol_txrx_ipa_cleanup(struct cdp_soc_t *soc_hdl, uint8_t pdev_id,
799 			       uint32_t tx_pipe_handle,
800 			       uint32_t rx_pipe_handle,
801 			       qdf_ipa_wdi_hdl_t hdl)
802 {
803 	int ret;
804 	struct ol_txrx_ipa_resources *ipa_res;
805 	struct ol_txrx_soc_t *soc = cds_get_context(QDF_MODULE_ID_SOC);
806 	qdf_device_t osdev = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
807 	ol_txrx_pdev_handle pdev;
808 
809 	if (!soc || !osdev)
810 		return QDF_STATUS_E_FAILURE;
811 
812 	pdev = ol_txrx_get_pdev_from_pdev_id(soc, OL_TXRX_PDEV_ID);
813 	if (!pdev) {
814 		ol_txrx_err("NULL pdev invalid instance");
815 		return QDF_STATUS_E_FAILURE;
816 	}
817 
818 	ipa_res = &pdev->ipa_resource;
819 	if (osdev->smmu_s1_enabled) {
820 		ret = pld_smmu_unmap(osdev->dev,
821 				     ipa_res->rx_ready_doorbell_dmaaddr,
822 				     sizeof(uint32_t));
823 		if (ret)
824 			ol_txrx_err("rx_ready, smmu unmap failed");
825 
826 		ret = pld_smmu_unmap(osdev->dev,
827 				     ipa_res->tx_comp_doorbell_dmaaddr,
828 				     sizeof(uint32_t));
829 		if (ret)
830 			ol_txrx_err("tx_comp, smmu unmap failed");
831 	}
832 
833 	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
834 		  "%s: Disconnect IPA pipe", __func__);
835 	ret = qdf_ipa_wdi_disconn_pipes(hdl);
836 	if (ret) {
837 		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
838 			  "ipa_wdi_disconn_pipes failed: ret=%d", ret);
839 		return QDF_STATUS_E_FAILURE;
840 	}
841 
842 	return QDF_STATUS_SUCCESS;
843 }
844 
845 /**
846  * ol_txrx_ipa_setup_iface() - Setup IPA header and register interface
847  * @ifname: Interface name
848  * @mac_addr: Interface MAC address
849  * @prod_client: IPA prod client type
850  * @cons_client: IPA cons client type
851  * @session_id: Session ID
852  * @is_ipv6_enabled: Is IPV6 enabled or not
853  *
854  * Return: QDF_STATUS
855  */
ol_txrx_ipa_setup_iface(char * ifname,uint8_t * mac_addr,qdf_ipa_client_type_t prod_client,qdf_ipa_client_type_t cons_client,uint8_t session_id,bool is_ipv6_enabled,qdf_ipa_wdi_hdl_t hdl)856 QDF_STATUS ol_txrx_ipa_setup_iface(char *ifname, uint8_t *mac_addr,
857 				   qdf_ipa_client_type_t prod_client,
858 				   qdf_ipa_client_type_t cons_client,
859 				   uint8_t session_id, bool is_ipv6_enabled,
860 				   qdf_ipa_wdi_hdl_t hdl)
861 {
862 	qdf_ipa_wdi_reg_intf_in_params_t in;
863 	qdf_ipa_wdi_hdr_info_t hdr_info;
864 	struct ol_txrx_ipa_uc_tx_hdr uc_tx_hdr;
865 	struct ol_txrx_ipa_uc_tx_hdr uc_tx_hdr_v6;
866 	int ret = -EINVAL;
867 
868 	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
869 		  "%s: Add Partial hdr: %s, "QDF_MAC_ADDR_FMT,
870 		  __func__, ifname, QDF_MAC_ADDR_REF(mac_addr));
871 
872 	qdf_mem_zero(&hdr_info, sizeof(qdf_ipa_wdi_hdr_info_t));
873 	memcpy(&uc_tx_hdr, &ipa_uc_tx_hdr, OL_TXRX_IPA_UC_WLAN_TX_HDR_LEN);
874 	qdf_ether_addr_copy(uc_tx_hdr.eth.h_source, mac_addr);
875 	uc_tx_hdr.ipa_hd.vdev_id = session_id;
876 
877 	/* IPV4 header */
878 	uc_tx_hdr.eth.h_proto = qdf_htons(ETH_P_IP);
879 
880 	QDF_IPA_WDI_HDR_INFO_HDR(&hdr_info) = (uint8_t *)&uc_tx_hdr;
881 	QDF_IPA_WDI_HDR_INFO_HDR_LEN(&hdr_info) =
882 		OL_TXRX_IPA_UC_WLAN_TX_HDR_LEN;
883 	QDF_IPA_WDI_HDR_INFO_HDR_TYPE(&hdr_info) = IPA_HDR_L2_ETHERNET_II;
884 	QDF_IPA_WDI_HDR_INFO_DST_MAC_ADDR_OFFSET(&hdr_info) =
885 		OL_TXRX_IPA_UC_WLAN_HDR_DES_MAC_OFFSET;
886 
887 	QDF_IPA_WDI_REG_INTF_IN_PARAMS_NETDEV_NAME(&in) = ifname;
888 	memcpy(&(QDF_IPA_WDI_REG_INTF_IN_PARAMS_HDR_INFO(&in)[IPA_IP_v4]),
889 	       &hdr_info, sizeof(qdf_ipa_wdi_hdr_info_t));
890 	QDF_IPA_WDI_REG_INTF_IN_PARAMS_ALT_DST_PIPE(&in) = cons_client;
891 	QDF_IPA_WDI_REG_INTF_IN_PARAMS_IS_META_DATA_VALID(&in) = 1;
892 	QDF_IPA_WDI_REG_INTF_IN_PARAMS_META_DATA(&in) =
893 		htonl(session_id << 16);
894 	QDF_IPA_WDI_REG_INTF_IN_PARAMS_META_DATA_MASK(&in) = htonl(0x00FF0000);
895 
896 	/* IPV6 header */
897 	if (is_ipv6_enabled) {
898 		memcpy(&uc_tx_hdr_v6, &uc_tx_hdr,
899 		       OL_TXRX_IPA_UC_WLAN_TX_HDR_LEN);
900 		uc_tx_hdr_v6.eth.h_proto = qdf_htons(ETH_P_IPV6);
901 		QDF_IPA_WDI_HDR_INFO_HDR(&hdr_info) = (uint8_t *)&uc_tx_hdr_v6;
902 		memcpy(&(QDF_IPA_WDI_REG_INTF_IN_PARAMS_HDR_INFO(&in)[IPA_IP_v6]),
903 		       &hdr_info, sizeof(qdf_ipa_wdi_hdr_info_t));
904 	}
905 
906 	ret = qdf_ipa_wdi_reg_intf(&in);
907 	if (ret) {
908 		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
909 			  "%s: ipa_wdi_reg_intf failed: ret=%d", __func__, ret);
910 	}
911 
912 	return ret;
913 }
914 
915 /**
916  * ol_txrx_ipa_cleanup_iface() - Cleanup IPA header and deregister interface
917  * @ifname: Interface name
918  * @is_ipv6_enabled: Is IPV6 enabled or not
919  *
920  * Return: QDF_STATUS
921  */
ol_txrx_ipa_cleanup_iface(char * ifname,bool is_ipv6_enabled,qdf_ipa_wdi_hdl_t hdl)922 QDF_STATUS ol_txrx_ipa_cleanup_iface(char *ifname, bool is_ipv6_enabled,
923 				     qdf_ipa_wdi_hdl_t hdl)
924 {
925 	int ret;
926 
927 	/* unregister the interface with IPA */
928 	ret = qdf_ipa_wdi_dereg_intf(ifname, hdl);
929 	if (ret) {
930 		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
931 			  "%s: ipa_wdi_dereg_intf failed: devname=%s, ret=%d",
932 			  __func__, ifname, ret);
933 		return QDF_STATUS_E_FAILURE;
934 	}
935 
936 	return QDF_STATUS_SUCCESS;
937 }
938 
ol_txrx_ipa_enable_pipes(struct cdp_soc_t * soc_hdl,uint8_t pdev_id,qdf_ipa_wdi_hdl_t hdl)939 QDF_STATUS ol_txrx_ipa_enable_pipes(struct cdp_soc_t *soc_hdl, uint8_t pdev_id,
940 				    qdf_ipa_wdi_hdl_t hdl)
941 {
942 	struct ol_txrx_soc_t *soc = cdp_soc_t_to_ol_txrx_soc_t(soc_hdl);
943 	ol_txrx_pdev_handle pdev = ol_txrx_get_pdev_from_pdev_id(soc, pdev_id);
944 	QDF_STATUS status;
945 	int ret;
946 
947 	if (!pdev) {
948 		ol_txrx_err("Invalid instance");
949 		return QDF_STATUS_E_FAILURE;
950 	}
951 
952 	status = htt_rx_update_smmu_map(pdev->htt_pdev, true);
953 	if (status != QDF_STATUS_SUCCESS) {
954 		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
955 			  "IPA SMMU map failed status:%d", status);
956 		return status;
957 	}
958 
959 	/* ACTIVATE TX PIPE */
960 	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
961 		  "%s: Enable IPA pipes", __func__);
962 	ret = qdf_ipa_wdi_enable_pipes(hdl);
963 	if (ret) {
964 		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
965 			  "%s: ipa_wdi_enable_pipes failed: ret=%d",
966 				__func__, ret);
967 		status = htt_rx_update_smmu_map(pdev->htt_pdev, false);
968 		if (status != QDF_STATUS_SUCCESS)
969 			QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
970 				  "IPA SMMU unmap failed");
971 		return QDF_STATUS_E_FAILURE;
972 	}
973 
974 	ol_txrx_ipa_uc_set_active(soc_hdl, pdev_id, true, true);
975 	ol_txrx_ipa_uc_set_active(soc_hdl, pdev_id, true, false);
976 
977 	return QDF_STATUS_SUCCESS;
978 }
979 
ol_txrx_ipa_disable_pipes(struct cdp_soc_t * soc_hdl,uint8_t pdev_id,qdf_ipa_wdi_hdl_t hdl)980 QDF_STATUS ol_txrx_ipa_disable_pipes(struct cdp_soc_t *soc_hdl, uint8_t pdev_id,
981 				     qdf_ipa_wdi_hdl_t hdl)
982 {
983 	struct ol_txrx_soc_t *soc = cdp_soc_t_to_ol_txrx_soc_t(soc_hdl);
984 	ol_txrx_pdev_handle pdev = ol_txrx_get_pdev_from_pdev_id(soc, pdev_id);
985 	int ret;
986 
987 	if (!pdev) {
988 		ol_txrx_err("Invalid instance");
989 		return QDF_STATUS_E_FAILURE;
990 	}
991 
992 	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
993 		  "%s: Disable IPA pipes", __func__);
994 	ret = qdf_ipa_wdi_disable_pipes(hdl);
995 	if (ret) {
996 		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
997 			  "%s: ipa_wdi_disable_pipes failed: ret=%d",
998 			  __func__, ret);
999 	}
1000 
1001 	if (htt_rx_update_smmu_map(pdev->htt_pdev, false) !=
1002 	    QDF_STATUS_SUCCESS) {
1003 		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
1004 			  "IPA SMMU unmap failed");
1005 	}
1006 
1007 	return ret ? QDF_STATUS_E_FAILURE : QDF_STATUS_SUCCESS;
1008 }
1009 
1010 /**
1011  * ol_txrx_ipa_set_perf_level() - Set IPA clock bandwidth based on data rates
1012  * @client: Client type
1013  * @max_supported_bw_mbps: Maximum bandwidth needed (in Mbps)
1014  *
1015  * Return: QDF_STATUS
1016  */
ol_txrx_ipa_set_perf_level(int client,uint32_t max_supported_bw_mbps,qdf_ipa_wdi_hdl_t hdl)1017 QDF_STATUS ol_txrx_ipa_set_perf_level(int client,
1018 				      uint32_t max_supported_bw_mbps,
1019 				      qdf_ipa_wdi_hdl_t hdl)
1020 {
1021 	qdf_ipa_wdi_perf_profile_t profile;
1022 	int result;
1023 
1024 	QDF_IPA_WDI_PERF_PROFILE_CLIENT(&profile) = client;
1025 	QDF_IPA_WDI_PERF_PROFILE_MAX_SUPPORTED_BW_MBPS(&profile) =
1026 		max_supported_bw_mbps;
1027 	result = qdf_ipa_wdi_set_perf_profile(hdl, &profile);
1028 
1029 	if (result) {
1030 		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
1031 				"Set perf profile failed, code %d", result);
1032 
1033 		return QDF_STATUS_E_FAILURE;
1034 	}
1035 
1036 	return QDF_STATUS_SUCCESS;
1037 }
1038 
1039 #else /* CONFIG_IPA_WDI_UNIFIED_API */
1040 
1041 #ifdef ENABLE_SMMU_S1_TRANSLATION
1042 /**
1043  * ol_txrx_ipa_tx_smmu_params() - Config IPA TX params
1044  * @ipa_res: IPA resources
1045  * @pipe_in: IPA WDI TX pipe params
1046  *
1047  * Return: None
1048  */
ol_txrx_ipa_tx_smmu_params(struct ol_txrx_ipa_resources * ipa_res,qdf_ipa_wdi_in_params_t * pipe_in)1049 static inline void ol_txrx_ipa_tx_smmu_params(
1050 					struct ol_txrx_ipa_resources *ipa_res,
1051 					qdf_ipa_wdi_in_params_t *pipe_in)
1052 {
1053 	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
1054 		    "%s: SMMU Enabled", __func__);
1055 
1056 	QDF_IPA_PIPE_IN_SMMU_ENABLED(pipe_in) = true;
1057 	qdf_mem_copy(&QDF_IPA_PIPE_IN_DL_SMMU_COMP_RING(pipe_in),
1058 		     &ipa_res->tx_comp_ring->sgtable,
1059 		     sizeof(sgtable_t));
1060 	QDF_IPA_PIPE_IN_DL_SMMU_COMP_RING_SIZE(pipe_in) =
1061 					ipa_res->tx_comp_ring->mem_info.size;
1062 	qdf_mem_copy(&QDF_IPA_PIPE_IN_DL_SMMU_CE_RING(pipe_in),
1063 		     &ipa_res->ce_sr->sgtable,
1064 		     sizeof(sgtable_t));
1065 	QDF_IPA_PIPE_IN_DL_SMMU_CE_DOOR_BELL_PA(pipe_in) =
1066 					ipa_res->ce_reg_paddr;
1067 	QDF_IPA_PIPE_IN_DL_SMMU_CE_RING_SIZE(pipe_in) =
1068 					ipa_res->ce_sr_ring_size;
1069 	QDF_IPA_PIPE_IN_DL_SMMU_NUM_TX_BUFFERS(pipe_in) =
1070 					ipa_res->tx_num_alloc_buffer;
1071 }
1072 
1073 /**
1074  * ol_txrx_ipa_rx_smmu_params() - Config IPA TX params
1075  * @ipa_res: IPA resources
1076  * @pipe_in: IPA WDI TX pipe params
1077  *
1078  * Return: None
1079  */
ol_txrx_ipa_rx_smmu_params(struct ol_txrx_ipa_resources * ipa_res,qdf_ipa_wdi_in_params_t * pipe_in)1080 static inline void ol_txrx_ipa_rx_smmu_params(
1081 					struct ol_txrx_ipa_resources *ipa_res,
1082 					qdf_ipa_wdi_in_params_t *pipe_in)
1083 {
1084 	qdf_mem_copy(&QDF_IPA_PIPE_IN_UL_SMMU_RDY_RING(pipe_in),
1085 		     &ipa_res->rx_rdy_ring->sgtable,
1086 		     sizeof(sgtable_t));
1087 	QDF_IPA_PIPE_IN_UL_SMMU_RDY_RING_SIZE(pipe_in) =
1088 				ipa_res->rx_rdy_ring->mem_info.size;
1089 	QDF_IPA_PIPE_IN_UL_SMMU_RDY_RING_RP_PA(pipe_in) =
1090 				ipa_res->rx_proc_done_idx->mem_info.pa;
1091 
1092 	QDF_IPA_PIPE_IN_UL_SMMU_RDY_RING_RP_VA(pipe_in) =
1093 				ipa_res->rx_proc_done_idx->vaddr;
1094 	qdf_mem_copy(&QDF_IPA_PIPE_IN_UL_SMMU_RDY_COMP_RING(pipe_in),
1095 		     &ipa_res->rx2_rdy_ring->sgtable,
1096 		     sizeof(sgtable_t));
1097 	QDF_IPA_PIPE_IN_UL_SMMU_RDY_COMP_RING_SIZE(pipe_in) =
1098 				ipa_res->rx2_rdy_ring->mem_info.size;
1099 	QDF_IPA_PIPE_IN_UL_SMMU_RDY_COMP_RING_WP_PA(pipe_in) =
1100 				ipa_res->rx2_proc_done_idx->mem_info.pa;
1101 	QDF_IPA_PIPE_IN_UL_SMMU_RDY_COMP_RING_WP_VA(pipe_in) =
1102 				ipa_res->rx2_proc_done_idx->vaddr;
1103 }
1104 #else
ol_txrx_ipa_tx_smmu_params(struct ol_txrx_ipa_resources * ipa_res,qdf_ipa_wdi_in_params_t * pipe_in)1105 static inline void ol_txrx_ipa_tx_smmu_params(
1106 				struct ol_txrx_ipa_resources *ipa_res,
1107 				qdf_ipa_wdi_in_params_t *pipe_in)
1108 {
1109 }
1110 
ol_txrx_ipa_rx_smmu_params(struct ol_txrx_ipa_resources * ipa_res,qdf_ipa_wdi_in_params_t * pipe_in)1111 static inline void ol_txrx_ipa_rx_smmu_params(
1112 				struct ol_txrx_ipa_resources *ipa_res,
1113 				qdf_ipa_wdi_in_params_t *pipe_in)
1114 {
1115 }
1116 #endif
1117 
1118 /**
1119  * ol_txrx_ipa_tx_params() - Config IPA TX params
1120  * @ipa_res: IPA resources
1121  * @pipe_in: IPA WDI TX pipe params
1122  *
1123  * Return: None
1124  */
ol_txrx_ipa_tx_params(struct ol_txrx_ipa_resources * ipa_res,qdf_ipa_wdi_in_params_t * pipe_in)1125 static inline void ol_txrx_ipa_tx_params(
1126 					struct ol_txrx_ipa_resources *ipa_res,
1127 					qdf_ipa_wdi_in_params_t *pipe_in)
1128 {
1129 	qdf_device_t osdev = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
1130 
1131 	if (!osdev)
1132 		return;
1133 
1134 	QDF_IPA_PIPE_IN_DL_COMP_RING_BASE_PA(pipe_in) =
1135 		qdf_mem_get_dma_addr(osdev,
1136 				&ipa_res->tx_comp_ring->mem_info);
1137 	QDF_IPA_PIPE_IN_DL_COMP_RING_SIZE(pipe_in) =
1138 		ipa_res->tx_comp_ring->mem_info.size;
1139 	QDF_IPA_PIPE_IN_DL_CE_RING_BASE_PA(pipe_in) =
1140 		qdf_mem_get_dma_addr(osdev,
1141 				&ipa_res->ce_sr->mem_info);
1142 	QDF_IPA_PIPE_IN_DL_CE_DOOR_BELL_PA(pipe_in) =
1143 		ipa_res->ce_reg_paddr;
1144 	QDF_IPA_PIPE_IN_DL_CE_RING_SIZE(pipe_in) =
1145 		ipa_res->ce_sr_ring_size;
1146 	QDF_IPA_PIPE_IN_DL_NUM_TX_BUFFERS(pipe_in) =
1147 		ipa_res->tx_num_alloc_buffer;
1148 }
1149 
1150 /**
1151  * ol_txrx_ipa_rx_params() - Config IPA RX params
1152  * @ipa_res: IPA resources
1153  * @pipe_in: IPA WDI RX pipe params
1154  *
1155  * Return: None
1156  */
ol_txrx_ipa_rx_params(struct ol_txrx_ipa_resources * ipa_res,qdf_ipa_wdi_in_params_t * pipe_in)1157 static inline void ol_txrx_ipa_rx_params(
1158 					struct ol_txrx_ipa_resources *ipa_res,
1159 					qdf_ipa_wdi_in_params_t *pipe_in)
1160 {
1161 	qdf_device_t osdev = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
1162 
1163 	if (!osdev)
1164 		return;
1165 
1166 	QDF_IPA_PIPE_IN_UL_RDY_RING_BASE_PA(pipe_in) =
1167 		ipa_res->rx_rdy_ring->mem_info.pa;
1168 	QDF_IPA_PIPE_IN_UL_RDY_RING_SIZE(pipe_in) =
1169 		ipa_res->rx_rdy_ring->mem_info.size;
1170 	QDF_IPA_PIPE_IN_UL_RDY_RING_RP_PA(pipe_in) =
1171 		ipa_res->rx_proc_done_idx->mem_info.pa;
1172 	OL_TXRX_IPA_WDI2_SET(pipe_in, ipa_res,
1173 			     osdev);
1174 }
1175 
ol_txrx_ipa_setup(struct cdp_soc_t * soc_hdl,uint8_t pdev_id,void * ipa_i2w_cb,void * ipa_w2i_cb,void * ipa_wdi_meter_notifier_cb,uint32_t ipa_desc_size,void * ipa_priv,bool is_rm_enabled,uint32_t * p_tx_pipe_handle,uint32_t * p_rx_pipe_handle)1176 QDF_STATUS ol_txrx_ipa_setup(struct cdp_soc_t *soc_hdl, uint8_t pdev_id,
1177 			     void *ipa_i2w_cb, void *ipa_w2i_cb,
1178 			     void *ipa_wdi_meter_notifier_cb,
1179 			     uint32_t ipa_desc_size, void *ipa_priv,
1180 			     bool is_rm_enabled, uint32_t *p_tx_pipe_handle,
1181 			     uint32_t *p_rx_pipe_handle)
1182 {
1183 	struct ol_txrx_soc_t *soc = cdp_soc_t_to_ol_txrx_soc_t(soc_hdl);
1184 	ol_txrx_pdev_handle pdev = ol_txrx_get_pdev_from_pdev_id(soc, pdev_id);
1185 	qdf_device_t osdev = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
1186 	struct ol_txrx_ipa_resources *ipa_res;
1187 	qdf_ipa_wdi_in_params_t pipe_in;
1188 	qdf_ipa_wdi_out_params_t pipe_out;
1189 	uint32_t tx_comp_db_dmaaddr = 0, rx_rdy_db_dmaaddr = 0;
1190 	int ret;
1191 
1192 	if (!pdev) {
1193 		ol_txrx_err("Invalid instance");
1194 		return QDF_STATUS_E_FAILURE;
1195 	}
1196 
1197 	if (!osdev)
1198 		return QDF_STATUS_E_NOENT;
1199 
1200 	ipa_res = &pdev->ipa_resource;
1201 	qdf_mem_zero(&pipe_in, sizeof(pipe_in));
1202 	qdf_mem_zero(&pipe_out, sizeof(pipe_out));
1203 
1204 	/* TX PIPE */
1205 	QDF_IPA_PIPE_IN_NAT_EN(&pipe_in) = IPA_BYPASS_NAT;
1206 	QDF_IPA_PIPE_IN_HDR_LEN(&pipe_in) = OL_TXRX_IPA_UC_WLAN_TX_HDR_LEN;
1207 	QDF_IPA_PIPE_IN_HDR_OFST_PKT_SIZE_VALID(&pipe_in) = 1;
1208 	QDF_IPA_PIPE_IN_HDR_OFST_PKT_SIZE(&pipe_in) = 0;
1209 	QDF_IPA_PIPE_IN_HDR_ADDITIONAL_CONST_LEN(&pipe_in) =
1210 		OL_TXRX_IPA_UC_WLAN_8023_HDR_SIZE;
1211 	QDF_IPA_PIPE_IN_MODE(&pipe_in) = IPA_BASIC;
1212 	QDF_IPA_PIPE_IN_CLIENT(&pipe_in) = IPA_CLIENT_WLAN1_CONS;
1213 	QDF_IPA_PIPE_IN_DESC_FIFO_SZ(&pipe_in) = ipa_desc_size;
1214 	QDF_IPA_PIPE_IN_PRIV(&pipe_in) = ipa_priv;
1215 	QDF_IPA_PIPE_IN_HDR_LITTLE_ENDIAN(&pipe_in) = true;
1216 	QDF_IPA_PIPE_IN_NOTIFY(&pipe_in) = ipa_i2w_cb;
1217 
1218 	if (!is_rm_enabled) {
1219 		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
1220 			    "%s: IPA RM DISABLED, IPA AWAKE", __func__);
1221 		QDF_IPA_PIPE_IN_KEEP_IPA_AWAKE(&pipe_in) = true;
1222 	}
1223 
1224 	if (qdf_mem_smmu_s1_enabled(osdev))
1225 		ol_txrx_ipa_tx_smmu_params(ipa_res, &pipe_in);
1226 	else
1227 		ol_txrx_ipa_tx_params(ipa_res, &pipe_in);
1228 
1229 	/* Connect WDI IPA PIPE */
1230 	ret = qdf_ipa_connect_wdi_pipe(&pipe_in, &pipe_out);
1231 	if (ret) {
1232 		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
1233 		    "ipa_connect_wdi_pipe: Tx pipe setup failed: ret=%d", ret);
1234 		return QDF_STATUS_E_FAILURE;
1235 	}
1236 
1237 	/* Micro Controller Doorbell register */
1238 	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
1239 		"%s CONS DB pipe out 0x%x TX PIPE Handle 0x%x", __func__,
1240 		(unsigned int)QDF_IPA_PIPE_OUT_UC_DOOR_BELL_PA(&pipe_out),
1241 		pipe_out.clnt_hdl);
1242 	ipa_res->tx_comp_doorbell_dmaaddr =
1243 		QDF_IPA_PIPE_OUT_UC_DOOR_BELL_PA(&pipe_out);
1244 	/* WLAN TX PIPE Handle */
1245 	ipa_res->tx_pipe_handle = QDF_IPA_PIPE_OUT_CLNT_HDL(&pipe_out);
1246 	*p_tx_pipe_handle = QDF_IPA_PIPE_OUT_CLNT_HDL(&pipe_out);
1247 
1248 	/* RX PIPE */
1249 	QDF_IPA_PIPE_IN_NAT_EN(&pipe_in) = IPA_BYPASS_NAT;
1250 	QDF_IPA_PIPE_IN_HDR_LEN(&pipe_in) = OL_TXRX_IPA_UC_WLAN_RX_HDR_LEN;
1251 	QDF_IPA_PIPE_IN_HDR_OFST_METADATA_VALID(&pipe_in) = 0;
1252 	QDF_IPA_PIPE_IN_HDR_METADATA_REG_VALID(&pipe_in) = 1;
1253 	QDF_IPA_PIPE_IN_MODE(&pipe_in) = IPA_BASIC;
1254 	QDF_IPA_PIPE_IN_CLIENT(&pipe_in) = IPA_CLIENT_WLAN1_PROD;
1255 	QDF_IPA_PIPE_IN_DESC_FIFO_SZ(&pipe_in) =
1256 		ipa_desc_size + SPS_DESC_SIZE;
1257 	QDF_IPA_PIPE_IN_NOTIFY(&pipe_in) = ipa_w2i_cb;
1258 	if (!is_rm_enabled) {
1259 		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
1260 			    "%s: IPA RM DISABLED, IPA AWAKE", __func__);
1261 		QDF_IPA_PIPE_IN_KEEP_IPA_AWAKE(&pipe_in) = true;
1262 	}
1263 
1264 	if (qdf_mem_smmu_s1_enabled(osdev))
1265 		ol_txrx_ipa_rx_smmu_params(ipa_res, &pipe_in);
1266 	else
1267 		ol_txrx_ipa_rx_params(ipa_res, &pipe_in);
1268 
1269 #ifdef FEATURE_METERING
1270 	QDF_IPA_PIPE_IN_WDI_NOTIFY(&pipe_in) = ipa_wdi_meter_notifier_cb;
1271 #endif
1272 
1273 	ret = qdf_ipa_connect_wdi_pipe(&pipe_in, &pipe_out);
1274 	if (ret) {
1275 		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
1276 		    "ipa_connect_wdi_pipe: Rx pipe setup failed: ret=%d", ret);
1277 		return QDF_STATUS_E_FAILURE;
1278 	}
1279 	ipa_res->rx_ready_doorbell_dmaaddr =
1280 		QDF_IPA_PIPE_OUT_UC_DOOR_BELL_PA(&pipe_out);
1281 	ipa_res->rx_pipe_handle = QDF_IPA_PIPE_OUT_CLNT_HDL(&pipe_out);
1282 	*p_rx_pipe_handle = QDF_IPA_PIPE_OUT_CLNT_HDL(&pipe_out);
1283 
1284 	if (qdf_mem_smmu_s1_enabled(osdev)) {
1285 		pld_smmu_map(osdev->dev, ipa_res->tx_comp_doorbell_dmaaddr,
1286 			     &tx_comp_db_dmaaddr, sizeof(uint32_t));
1287 		ipa_res->tx_comp_doorbell_dmaaddr = tx_comp_db_dmaaddr;
1288 
1289 		pld_smmu_map(osdev->dev, ipa_res->rx_ready_doorbell_dmaaddr,
1290 			     &rx_rdy_db_dmaaddr, sizeof(uint32_t));
1291 		ipa_res->rx_ready_doorbell_dmaaddr = rx_rdy_db_dmaaddr;
1292 	}
1293 
1294 	return QDF_STATUS_SUCCESS;
1295 }
1296 
1297 /**
1298  * ol_txrx_ipa_cleanup() - Disconnect IPA pipes
1299  * @soc_hdl: soc handle
1300  * @pdev_id: pdev id
1301  * @tx_pipe_handle: Tx pipe handle
1302  * @rx_pipe_handle: Rx pipe handle
1303  *
1304  * Return: QDF_STATUS
1305  */
ol_txrx_ipa_cleanup(struct cdp_soc_t * soc_hdl,uint8_t pdev_id,uint32_t tx_pipe_handle,uint32_t rx_pipe_handle)1306 QDF_STATUS ol_txrx_ipa_cleanup(struct cdp_soc_t *soc_hdl, uint8_t pdev_id,
1307 			       uint32_t tx_pipe_handle,
1308 			       uint32_t rx_pipe_handle)
1309 {
1310 	int ret;
1311 
1312 	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
1313 		    "%s: Disconnect TX PIPE tx_pipe_handle=0x%x",
1314 		    __func__, tx_pipe_handle);
1315 	ret = qdf_ipa_disconnect_wdi_pipe(tx_pipe_handle);
1316 	if (ret) {
1317 		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
1318 		    "ipa_disconnect_wdi_pipe: Tx pipe cleanup failed: ret=%d",
1319 		    ret);
1320 		return QDF_STATUS_E_FAILURE;
1321 	}
1322 
1323 	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
1324 		    "%s: Disconnect RX PIPE rx_pipe_handle=0x%x",
1325 		    __func__, rx_pipe_handle);
1326 	ret = qdf_ipa_disconnect_wdi_pipe(rx_pipe_handle);
1327 	if (ret) {
1328 		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
1329 		    "ipa_disconnect_wdi_pipe: Rx pipe cleanup failed: ret=%d",
1330 		    ret);
1331 		return QDF_STATUS_E_FAILURE;
1332 	}
1333 
1334 	return QDF_STATUS_SUCCESS;
1335 }
1336 
1337 /**
1338  * ol_txrx_remove_ipa_header() - Remove a specific header from IPA
1339  * @name: Name of the header to be removed
1340  *
1341  * Return: QDF_STATUS
1342  */
ol_txrx_ipa_remove_header(char * name)1343 static QDF_STATUS ol_txrx_ipa_remove_header(char *name)
1344 {
1345 	qdf_ipa_ioc_get_hdr_t hdrlookup;
1346 	int ret = 0, len;
1347 	qdf_ipa_ioc_del_hdr_t *ipa_hdr;
1348 
1349 	qdf_mem_zero(&hdrlookup, sizeof(hdrlookup));
1350 	strlcpy(hdrlookup.name, name, sizeof(hdrlookup.name));
1351 	ret = qdf_ipa_get_hdr(&hdrlookup);
1352 	if (ret) {
1353 		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
1354 			  "Hdr deleted already %s, %d", name, ret);
1355 		return QDF_STATUS_E_FAILURE;
1356 	}
1357 
1358 	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG, "hdl: 0x%x",
1359 		  hdrlookup.hdl);
1360 	len = sizeof(qdf_ipa_ioc_del_hdr_t) + sizeof(qdf_ipa_hdr_del_t) * 1;
1361 	ipa_hdr = (qdf_ipa_ioc_del_hdr_t *)qdf_mem_malloc(len);
1362 	if (!ipa_hdr)
1363 		return QDF_STATUS_E_FAILURE;
1364 
1365 	QDF_IPA_IOC_DEL_HDR_NUM_HDRS(ipa_hdr) = 1;
1366 	QDF_IPA_IOC_DEL_HDR_COMMIT(ipa_hdr) = 0;
1367 	QDF_IPA_IOC_DEL_HDR_HDL(ipa_hdr) = QDF_IPA_IOC_GET_HDR_HDL(&hdrlookup);
1368 	QDF_IPA_IOC_DEL_HDR_STATUS(ipa_hdr) = -1;
1369 	ret = qdf_ipa_del_hdr(ipa_hdr);
1370 	if (ret != 0) {
1371 		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
1372 			  "Delete header failed: %d", ret);
1373 		qdf_mem_free(ipa_hdr);
1374 		return QDF_STATUS_E_FAILURE;
1375 	}
1376 
1377 	qdf_mem_free(ipa_hdr);
1378 	return QDF_STATUS_SUCCESS;
1379 }
1380 
1381 /**
1382  * ol_txrx_ipa_add_header_info() - Add IPA header for a given interface
1383  * @ifname: Interface name
1384  * @mac_addr: Interface MAC address
1385  * @is_ipv6_enabled: Is IPV6 enabled or not
1386  *
1387  * Return: 0 on success, negativer errno value on error
1388  */
ol_txrx_ipa_add_header_info(char * ifname,uint8_t * mac_addr,uint8_t session_id,bool is_ipv6_enabled)1389 static int ol_txrx_ipa_add_header_info(char *ifname, uint8_t *mac_addr,
1390 				       uint8_t session_id, bool is_ipv6_enabled)
1391 {
1392 	qdf_ipa_ioc_add_hdr_t *ipa_hdr = NULL;
1393 	int ret = -EINVAL;
1394 	struct ol_txrx_ipa_uc_tx_hdr *uc_tx_hdr = NULL;
1395 
1396 	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
1397 		  "Add Partial hdr: %s, "QDF_MAC_ADDR_FMT, ifname,
1398 		  QDF_MAC_ADDR_REF(mac_addr));
1399 
1400 	/* dynamically allocate the memory to add the hdrs */
1401 	ipa_hdr = qdf_mem_malloc(sizeof(qdf_ipa_ioc_add_hdr_t)
1402 				 + sizeof(qdf_ipa_hdr_add_t));
1403 	if (!ipa_hdr) {
1404 		ret = -ENOMEM;
1405 		goto end;
1406 	}
1407 
1408 	QDF_IPA_IOC_ADD_HDR_COMMIT(ipa_hdr) = 0;
1409 	QDF_IPA_IOC_ADD_HDR_NUM_HDRS(ipa_hdr) = 1;
1410 
1411 	uc_tx_hdr = (struct ol_txrx_ipa_uc_tx_hdr *)
1412 		QDF_IPA_IOC_ADD_HDR_HDR(ipa_hdr);
1413 	memcpy(uc_tx_hdr, &ipa_uc_tx_hdr, OL_TXRX_IPA_UC_WLAN_TX_HDR_LEN);
1414 	memcpy(uc_tx_hdr->eth.h_source, mac_addr, ETH_ALEN);
1415 	uc_tx_hdr->ipa_hd.vdev_id = session_id;
1416 	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
1417 		  "ifname=%s, vdev_id=%d",
1418 		  ifname, uc_tx_hdr->ipa_hd.vdev_id);
1419 	snprintf(QDF_IPA_IOC_ADD_HDR_NAME(ipa_hdr), IPA_RESOURCE_NAME_MAX,
1420 		 "%s%s", ifname, OL_TXRX_IPA_IPV4_NAME_EXT);
1421 	QDF_IPA_IOC_ADD_HDR_HDR_LEN(ipa_hdr) = OL_TXRX_IPA_UC_WLAN_TX_HDR_LEN;
1422 	QDF_IPA_IOC_ADD_HDR_TYPE(ipa_hdr) = IPA_HDR_L2_ETHERNET_II;
1423 	QDF_IPA_IOC_ADD_HDR_IS_PARTIAL(ipa_hdr) = 1;
1424 	QDF_IPA_IOC_ADD_HDR_HDR_HDL(ipa_hdr) = 0;
1425 	QDF_IPA_IOC_ADD_HDR_IS_ETH2_OFST_VALID(ipa_hdr) = 1;
1426 	QDF_IPA_IOC_ADD_HDR_ETH2_OFST(ipa_hdr) =
1427 		OL_TXRX_IPA_UC_WLAN_HDR_DES_MAC_OFFSET;
1428 
1429 	ret = qdf_ipa_add_hdr(ipa_hdr);
1430 	if (ret) {
1431 		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
1432 			  "%s IPv4 add hdr failed: %d", ifname, ret);
1433 		goto end;
1434 	}
1435 
1436 	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
1437 		"%s: IPv4 hdr_hdl: 0x%x",
1438 		QDF_IPA_IOC_ADD_HDR_NAME(ipa_hdr),
1439 		QDF_IPA_IOC_ADD_HDR_HDR_HDL(ipa_hdr));
1440 
1441 	if (is_ipv6_enabled) {
1442 		snprintf(QDF_IPA_IOC_ADD_HDR_NAME(ipa_hdr),
1443 			 IPA_RESOURCE_NAME_MAX, "%s%s",
1444 			 ifname, OL_TXRX_IPA_IPV6_NAME_EXT);
1445 
1446 		uc_tx_hdr = (struct ol_txrx_ipa_uc_tx_hdr *)
1447 			QDF_IPA_IOC_ADD_HDR_HDR(ipa_hdr);
1448 		uc_tx_hdr->eth.h_proto = cpu_to_be16(ETH_P_IPV6);
1449 
1450 		ret = qdf_ipa_add_hdr(ipa_hdr);
1451 		if (ret) {
1452 			QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
1453 				    "%s: IPv6 add hdr failed: %d", ifname, ret);
1454 			goto clean_ipv4_hdr;
1455 		}
1456 
1457 		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
1458 			"%s: IPv6 hdr_hdl: 0x%x",
1459 			QDF_IPA_IOC_ADD_HDR_NAME(ipa_hdr),
1460 			QDF_IPA_IOC_ADD_HDR_HDR_HDL(ipa_hdr));
1461 	}
1462 
1463 	qdf_mem_free(ipa_hdr);
1464 
1465 	return ret;
1466 
1467 clean_ipv4_hdr:
1468 	snprintf(ipa_hdr->hdr[0].name, IPA_RESOURCE_NAME_MAX, "%s%s",
1469 		 ifname, OL_TXRX_IPA_IPV4_NAME_EXT);
1470 	ol_txrx_ipa_remove_header(ipa_hdr->hdr[0].name);
1471 end:
1472 	if (ipa_hdr)
1473 		qdf_mem_free(ipa_hdr);
1474 
1475 	return ret;
1476 }
1477 
1478 /**
1479  * ol_txrx_ipa_register_interface() - register IPA interface
1480  * @ifname: Interface name
1481  * @prod_client: IPA prod client type
1482  * @cons_client: IPA cons client type
1483  * @session_id: Session ID
1484  * @is_ipv6_enabled: Is IPV6 enabled or not
1485  *
1486  * Return: 0 on success, negative errno on error
1487  */
ol_txrx_ipa_register_interface(char * ifname,qdf_ipa_client_type_t prod_client,qdf_ipa_client_type_t cons_client,uint8_t session_id,bool is_ipv6_enabled)1488 static int ol_txrx_ipa_register_interface(char *ifname,
1489 					  qdf_ipa_client_type_t prod_client,
1490 					  qdf_ipa_client_type_t cons_client,
1491 					  uint8_t session_id,
1492 					  bool is_ipv6_enabled)
1493 {
1494 	qdf_ipa_tx_intf_t tx_intf;
1495 	qdf_ipa_rx_intf_t rx_intf;
1496 	qdf_ipa_ioc_tx_intf_prop_t *tx_prop = NULL;
1497 	qdf_ipa_ioc_rx_intf_prop_t *rx_prop = NULL;
1498 
1499 	char ipv4_hdr_name[IPA_RESOURCE_NAME_MAX];
1500 	char ipv6_hdr_name[IPA_RESOURCE_NAME_MAX];
1501 
1502 	int num_prop = 1;
1503 	int ret = 0;
1504 
1505 	if (is_ipv6_enabled)
1506 		num_prop++;
1507 
1508 	/* Allocate TX properties for TOS categories, 1 each for IPv4 & IPv6 */
1509 	tx_prop =
1510 		qdf_mem_malloc(sizeof(qdf_ipa_ioc_tx_intf_prop_t) * num_prop);
1511 	if (!tx_prop)
1512 		goto register_interface_fail;
1513 
1514 	/* Allocate RX properties, 1 each for IPv4 & IPv6 */
1515 	rx_prop =
1516 		qdf_mem_malloc(sizeof(qdf_ipa_ioc_rx_intf_prop_t) * num_prop);
1517 	if (!rx_prop)
1518 		goto register_interface_fail;
1519 
1520 	qdf_mem_zero(&tx_intf, sizeof(tx_intf));
1521 	qdf_mem_zero(&rx_intf, sizeof(rx_intf));
1522 
1523 	snprintf(ipv4_hdr_name, IPA_RESOURCE_NAME_MAX, "%s%s",
1524 		 ifname, OL_TXRX_IPA_IPV4_NAME_EXT);
1525 	snprintf(ipv6_hdr_name, IPA_RESOURCE_NAME_MAX, "%s%s",
1526 		 ifname, OL_TXRX_IPA_IPV6_NAME_EXT);
1527 
1528 	QDF_IPA_IOC_RX_INTF_PROP_IP(&rx_prop[IPA_IP_v4]) = IPA_IP_v4;
1529 	QDF_IPA_IOC_RX_INTF_PROP_SRC_PIPE(&rx_prop[IPA_IP_v4]) = prod_client;
1530 	QDF_IPA_IOC_RX_INTF_PROP_HDR_L2_TYPE(&rx_prop[IPA_IP_v4]) =
1531 		IPA_HDR_L2_ETHERNET_II;
1532 	QDF_IPA_IOC_RX_INTF_PROP_ATTRIB_MASK(&rx_prop[IPA_IP_v4]) =
1533 		IPA_FLT_META_DATA;
1534 
1535 	/*
1536 	 * Interface ID is 3rd byte in the CLD header. Add the meta data and
1537 	 * mask to identify the interface in IPA hardware
1538 	 */
1539 	QDF_IPA_IOC_RX_INTF_PROP_META_DATA(&rx_prop[IPA_IP_v4]) =
1540 		htonl(session_id << 16);
1541 	QDF_IPA_IOC_RX_INTF_PROP_META_DATA_MASK(&rx_prop[IPA_IP_v4]) =
1542 		htonl(0x00FF0000);
1543 
1544 	rx_intf.num_props++;
1545 	if (is_ipv6_enabled) {
1546 		QDF_IPA_IOC_RX_INTF_PROP_IP(&rx_prop[IPA_IP_v6]) = IPA_IP_v6;
1547 		QDF_IPA_IOC_RX_INTF_PROP_SRC_PIPE(&rx_prop[IPA_IP_v6]) =
1548 			prod_client;
1549 		QDF_IPA_IOC_RX_INTF_PROP_HDR_L2_TYPE(&rx_prop[IPA_IP_v6]) =
1550 			IPA_HDR_L2_ETHERNET_II;
1551 		QDF_IPA_IOC_RX_INTF_PROP_ATTRIB_MASK(&rx_prop[IPA_IP_v6]) =
1552 			IPA_FLT_META_DATA;
1553 		QDF_IPA_IOC_RX_INTF_PROP_META_DATA(&rx_prop[IPA_IP_v6]) =
1554 			htonl(session_id << 16);
1555 		QDF_IPA_IOC_RX_INTF_PROP_META_DATA_MASK(&rx_prop[IPA_IP_v6]) =
1556 			htonl(0x00FF0000);
1557 
1558 		rx_intf.num_props++;
1559 	}
1560 
1561 	QDF_IPA_IOC_TX_INTF_PROP_IP(&tx_prop[IPA_IP_v4]) = IPA_IP_v4;
1562 	QDF_IPA_IOC_TX_INTF_PROP_HDR_L2_TYPE(&tx_prop[IPA_IP_v4]) =
1563 			IPA_HDR_L2_ETHERNET_II;
1564 	QDF_IPA_IOC_TX_INTF_PROP_DST_PIPE(&tx_prop[IPA_IP_v4]) =
1565 			IPA_CLIENT_WLAN1_CONS;
1566 	QDF_IPA_IOC_TX_INTF_PROP_ALT_DST_PIPE(&tx_prop[IPA_IP_v4]) =
1567 			cons_client;
1568 	strlcpy(QDF_IPA_IOC_TX_INTF_PROP_HDR_NAME(&tx_prop[IPA_IP_v4]),
1569 		ipv4_hdr_name, IPA_RESOURCE_NAME_MAX);
1570 	tx_intf.num_props++;
1571 
1572 	if (is_ipv6_enabled) {
1573 		QDF_IPA_IOC_TX_INTF_PROP_IP(&tx_prop[IPA_IP_v6]) = IPA_IP_v6;
1574 		QDF_IPA_IOC_TX_INTF_PROP_HDR_L2_TYPE(&tx_prop[IPA_IP_v6]) =
1575 			IPA_HDR_L2_ETHERNET_II;
1576 		QDF_IPA_IOC_TX_INTF_PROP_DST_PIPE(&tx_prop[IPA_IP_v6]) =
1577 			IPA_CLIENT_WLAN1_CONS;
1578 		QDF_IPA_IOC_TX_INTF_PROP_ALT_DST_PIPE(&tx_prop[IPA_IP_v6]) =
1579 			cons_client;
1580 		strlcpy(QDF_IPA_IOC_TX_INTF_PROP_HDR_NAME(&tx_prop[IPA_IP_v6]),
1581 			ipv6_hdr_name, IPA_RESOURCE_NAME_MAX);
1582 		tx_intf.num_props++;
1583 	}
1584 
1585 	QDF_IPA_TX_INTF_PROP(&tx_intf) = tx_prop;
1586 	QDF_IPA_RX_INTF_PROP(&rx_intf) = rx_prop;
1587 
1588 	/* Call the ipa api to register interface */
1589 	ret = qdf_ipa_register_intf(ifname, &tx_intf, &rx_intf);
1590 
1591 register_interface_fail:
1592 	qdf_mem_free(tx_prop);
1593 	qdf_mem_free(rx_prop);
1594 	return ret;
1595 }
1596 
1597 /**
1598  * ol_txrx_ipa_setup_iface() - Setup IPA header and register interface
1599  * @ifname: Interface name
1600  * @mac_addr: Interface MAC address
1601  * @prod_client: IPA prod client type
1602  * @cons_client: IPA cons client type
1603  * @session_id: Session ID
1604  * @is_ipv6_enabled: Is IPV6 enabled or not
1605  *
1606  * Return: QDF_STATUS
1607  */
ol_txrx_ipa_setup_iface(char * ifname,uint8_t * mac_addr,qdf_ipa_client_type_t prod_client,qdf_ipa_client_type_t cons_client,uint8_t session_id,bool is_ipv6_enabled)1608 QDF_STATUS ol_txrx_ipa_setup_iface(char *ifname, uint8_t *mac_addr,
1609 				   qdf_ipa_client_type_t prod_client,
1610 				   qdf_ipa_client_type_t cons_client,
1611 				   uint8_t session_id, bool is_ipv6_enabled)
1612 {
1613 	int ret;
1614 
1615 	ret = ol_txrx_ipa_add_header_info(ifname, mac_addr, session_id,
1616 					  is_ipv6_enabled);
1617 	if (ret)
1618 		return QDF_STATUS_E_FAILURE;
1619 
1620 	/* Configure the TX and RX pipes filter rules */
1621 	ret = ol_txrx_ipa_register_interface(ifname,
1622 					     prod_client,
1623 					     cons_client,
1624 					     session_id, is_ipv6_enabled);
1625 	if (ret)
1626 		return QDF_STATUS_E_FAILURE;
1627 
1628 	return QDF_STATUS_SUCCESS;
1629 }
1630 
1631 /**
1632  * ol_txrx_ipa_cleanup_iface() - Cleanup IPA header and deregister interface
1633  * @ifname: Interface name
1634  * @is_ipv6_enabled: Is IPV6 enabled or not
1635  *
1636  * Return: QDF_STATUS
1637  */
ol_txrx_ipa_cleanup_iface(char * ifname,bool is_ipv6_enabled)1638 QDF_STATUS ol_txrx_ipa_cleanup_iface(char *ifname, bool is_ipv6_enabled)
1639 {
1640 	char name_ipa[IPA_RESOURCE_NAME_MAX];
1641 	int ret;
1642 
1643 	/* Remove the headers */
1644 	snprintf(name_ipa, IPA_RESOURCE_NAME_MAX, "%s%s",
1645 			ifname, OL_TXRX_IPA_IPV4_NAME_EXT);
1646 	ol_txrx_ipa_remove_header(name_ipa);
1647 
1648 	if (is_ipv6_enabled) {
1649 		snprintf(name_ipa, IPA_RESOURCE_NAME_MAX, "%s%s",
1650 				ifname, OL_TXRX_IPA_IPV6_NAME_EXT);
1651 		ol_txrx_ipa_remove_header(name_ipa);
1652 	}
1653 	/* unregister the interface with IPA */
1654 	ret = qdf_ipa_deregister_intf(ifname);
1655 	if (ret) {
1656 		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
1657 				"%s: ipa_deregister_intf fail: %d",
1658 				ifname, ret);
1659 		return QDF_STATUS_E_FAILURE;
1660 	}
1661 
1662 	return QDF_STATUS_SUCCESS;
1663 }
1664 
ol_txrx_ipa_enable_pipes(struct cdp_soc_t * soc_hdl,uint8_t pdev_id)1665 QDF_STATUS ol_txrx_ipa_enable_pipes(struct cdp_soc_t *soc_hdl, uint8_t pdev_id)
1666 {
1667 	struct ol_txrx_soc_t *soc = cdp_soc_t_to_ol_txrx_soc_t(soc_hdl);
1668 	ol_txrx_pdev_handle pdev = ol_txrx_get_pdev_from_pdev_id(soc, pdev_id);
1669 	struct ol_txrx_ipa_resources *ipa_res;
1670 	int result;
1671 	QDF_STATUS status;
1672 
1673 	if (!pdev) {
1674 		ol_txrx_err("Invalid instance");
1675 		return QDF_STATUS_E_FAILURE;
1676 	}
1677 
1678 	ipa_res = &pdev->ipa_resource;
1679 	status = htt_rx_update_smmu_map(pdev->htt_pdev, true);
1680 	if (status != QDF_STATUS_SUCCESS) {
1681 		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
1682 			  "IPA SMMU map failed status:%d", status);
1683 		return status;
1684 	}
1685 
1686 	/* ACTIVATE TX PIPE */
1687 	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
1688 			"%s: Enable TX PIPE(tx_pipe_handle=%d)",
1689 			__func__, ipa_res->tx_pipe_handle);
1690 	result = qdf_ipa_enable_wdi_pipe(ipa_res->tx_pipe_handle);
1691 	if (result) {
1692 		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
1693 				"%s: Enable TX PIPE fail, code %d",
1694 				__func__, result);
1695 		goto smmu_unmap;
1696 	}
1697 	result = qdf_ipa_resume_wdi_pipe(ipa_res->tx_pipe_handle);
1698 	if (result) {
1699 		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
1700 				"%s: Resume TX PIPE fail, code %d",
1701 				__func__, result);
1702 		goto smmu_unmap;
1703 	}
1704 	ol_txrx_ipa_uc_set_active(soc_hdl, pdev_id, true, true);
1705 
1706 	/* ACTIVATE RX PIPE */
1707 	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
1708 			"%s: Enable RX PIPE(rx_pipe_handle=%d)",
1709 			__func__, ipa_res->rx_pipe_handle);
1710 	result = qdf_ipa_enable_wdi_pipe(ipa_res->rx_pipe_handle);
1711 	if (result) {
1712 		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
1713 				"%s: Enable RX PIPE fail, code %d",
1714 				__func__, result);
1715 		goto smmu_unmap;
1716 	}
1717 	result = qdf_ipa_resume_wdi_pipe(ipa_res->rx_pipe_handle);
1718 	if (result) {
1719 		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
1720 				"%s: Resume RX PIPE fail, code %d",
1721 				__func__, result);
1722 		goto smmu_unmap;
1723 	}
1724 	ol_txrx_ipa_uc_set_active(soc_hdl, pdev_id, true, false);
1725 
1726 	return QDF_STATUS_SUCCESS;
1727 
1728 smmu_unmap:
1729 	if (htt_rx_update_smmu_map(pdev->htt_pdev, false) !=
1730 	    QDF_STATUS_SUCCESS) {
1731 		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
1732 			  "IPA SMMU unmap failed");
1733 	}
1734 
1735 	return QDF_STATUS_E_FAILURE;
1736 }
1737 
ol_txrx_ipa_disable_pipes(struct cdp_soc_t * soc_hdl,uint8_t pdev_id)1738 QDF_STATUS ol_txrx_ipa_disable_pipes(struct cdp_soc_t *soc_hdl, uint8_t pdev_id)
1739 {
1740 	struct ol_txrx_soc_t *soc = cdp_soc_t_to_ol_txrx_soc_t(soc_hdl);
1741 	ol_txrx_pdev_handle pdev = ol_txrx_get_pdev_from_pdev_id(soc, pdev_id);
1742 	struct ol_txrx_ipa_resources *ipa_res;
1743 	int result;
1744 
1745 	if (!pdev) {
1746 		ol_txrx_err("Invalid instance");
1747 		return QDF_STATUS_E_FAILURE;
1748 	}
1749 
1750 	ipa_res = &pdev->ipa_resource;
1751 	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
1752 			"%s: Disable RX PIPE", __func__);
1753 	result = qdf_ipa_suspend_wdi_pipe(ipa_res->rx_pipe_handle);
1754 	if (result) {
1755 		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
1756 				"%s: Suspend RX PIPE fail, code %d",
1757 				__func__, result);
1758 		goto smmu_unmap;
1759 	}
1760 
1761 	result = qdf_ipa_disable_wdi_pipe(ipa_res->rx_pipe_handle);
1762 	if (result) {
1763 		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
1764 				"%s: Disable RX PIPE fail, code %d",
1765 				__func__, result);
1766 		goto smmu_unmap;
1767 	}
1768 
1769 	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
1770 			"%s: Disable TX PIPE", __func__);
1771 	result = qdf_ipa_suspend_wdi_pipe(ipa_res->tx_pipe_handle);
1772 	if (result) {
1773 		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
1774 				"%s: Suspend TX PIPE fail, code %d",
1775 				__func__, result);
1776 		goto smmu_unmap;
1777 	}
1778 	result = qdf_ipa_disable_wdi_pipe(ipa_res->tx_pipe_handle);
1779 	if (result) {
1780 		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
1781 				"%s: Disable TX PIPE fail, code %d",
1782 				__func__, result);
1783 		goto smmu_unmap;
1784 	}
1785 
1786 smmu_unmap:
1787 	if (htt_rx_update_smmu_map(pdev->htt_pdev, false) !=
1788 	    QDF_STATUS_SUCCESS) {
1789 		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
1790 			  "IPA SMMU unmap failed");
1791 	}
1792 
1793 	return result ? QDF_STATUS_E_FAILURE : QDF_STATUS_SUCCESS;
1794 }
1795 
1796 /**
1797  * ol_txrx_ipa_set_perf_level() - Set IPA clock bandwidth based on data rates
1798  * @client: Client type
1799  * @max_supported_bw_mbps: Maximum bandwidth needed (in Mbps)
1800  *
1801  * Return: QDF_STATUS
1802  */
ol_txrx_ipa_set_perf_level(int client,uint32_t max_supported_bw_mbps)1803 QDF_STATUS ol_txrx_ipa_set_perf_level(int client,
1804 				      uint32_t max_supported_bw_mbps)
1805 {
1806 	qdf_ipa_rm_resource_name_t resource_name;
1807 	qdf_ipa_rm_perf_profile_t profile;
1808 	int result;
1809 
1810 	if (client == QDF_IPA_CLIENT_WLAN1_PROD) {
1811 		resource_name = QDF_IPA_RM_RESOURCE_WLAN_PROD;
1812 	} else if (client == QDF_IPA_CLIENT_WLAN1_CONS) {
1813 		resource_name = QDF_IPA_RM_RESOURCE_WLAN_CONS;
1814 	} else {
1815 		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
1816 				"not supported client %d", client);
1817 		return QDF_STATUS_E_FAILURE;
1818 	}
1819 
1820 	QDF_IPA_RM_PERF_PROFILE_MAX_SUPPORTED_BANDWIDTH_MBPS(&profile) =
1821 		max_supported_bw_mbps;
1822 	result = qdf_ipa_rm_set_perf_profile(resource_name, &profile);
1823 
1824 	if (result) {
1825 		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
1826 				"Set perf profile failed, code %d", result);
1827 
1828 		return QDF_STATUS_E_FAILURE;
1829 	}
1830 
1831 	return QDF_STATUS_SUCCESS;
1832 }
1833 
1834 #endif /* CONFIG_IPA_WDI_UNIFIED_API */
1835 
1836 #ifdef FEATURE_METERING
ol_txrx_ipa_uc_get_share_stats(struct cdp_soc_t * soc_hdl,uint8_t pdev_id,uint8_t reset_stats)1837 QDF_STATUS ol_txrx_ipa_uc_get_share_stats(struct cdp_soc_t *soc_hdl,
1838 					  uint8_t pdev_id, uint8_t reset_stats)
1839 {
1840 	struct ol_txrx_soc_t *soc = cdp_soc_t_to_ol_txrx_soc_t(soc_hdl);
1841 	ol_txrx_pdev_handle pdev = ol_txrx_get_pdev_from_pdev_id(soc, pdev_id);
1842 	int result;
1843 
1844 	if (!pdev) {
1845 		ol_txrx_err("Invalid instance");
1846 		return QDF_STATUS_E_FAILURE;
1847 	}
1848 
1849 	result = htt_h2t_ipa_uc_get_share_stats(pdev->htt_pdev, reset_stats);
1850 
1851 	if (result) {
1852 		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
1853 			  "Get IPA sharing stats failed, code %d", result);
1854 		return QDF_STATUS_E_FAILURE;
1855 	}
1856 
1857 	return QDF_STATUS_SUCCESS;
1858 }
1859 
ol_txrx_ipa_uc_set_quota(struct cdp_soc_t * soc_hdl,uint8_t pdev_id,uint64_t quota_bytes)1860 QDF_STATUS ol_txrx_ipa_uc_set_quota(struct cdp_soc_t *soc_hdl, uint8_t pdev_id,
1861 				    uint64_t quota_bytes)
1862 {
1863 	struct ol_txrx_soc_t *soc = cdp_soc_t_to_ol_txrx_soc_t(soc_hdl);
1864 	ol_txrx_pdev_handle pdev = ol_txrx_get_pdev_from_pdev_id(soc, pdev_id);
1865 	int result;
1866 
1867 	if (!pdev) {
1868 		ol_txrx_err("Invalid instance");
1869 		return QDF_STATUS_E_FAILURE;
1870 	}
1871 
1872 	result = htt_h2t_ipa_uc_set_quota(pdev->htt_pdev, quota_bytes);
1873 
1874 	if (result) {
1875 		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
1876 			  "Set IPA quota failed, code %d", result);
1877 		return QDF_STATUS_E_FAILURE;
1878 	}
1879 
1880 	return QDF_STATUS_SUCCESS;
1881 }
1882 #endif
1883 #endif /* IPA_UC_OFFLOAD */
1884