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