xref: /wlan-dirver/qca-wifi-host-cmn/ipa/core/src/wlan_ipa_core.c (revision d3be64a66deb873bac895fb0ecea12cbfca02017)
1 /*
2  * Copyright (c) 2013-2021 The Linux Foundation. All rights reserved.
3  * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
4  *
5  * Permission to use, copy, modify, and/or distribute this software for
6  * any purpose with or without fee is hereby granted, provided that the
7  * above copyright notice and this permission notice appear in all
8  * copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
11  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
12  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
13  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
14  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
16  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17  * PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20 /* Include Files */
21 #include "wlan_ipa_core.h"
22 #include "wlan_ipa_main.h"
23 #include "cdp_txrx_ipa.h"
24 #include "cdp_txrx_ctrl.h"
25 #include "wal_rx_desc.h"
26 #include "qdf_str.h"
27 #include "host_diag_core_event.h"
28 #include "wlan_objmgr_vdev_obj.h"
29 #include "qdf_platform.h"
30 #include <wmi_unified_param.h>
31 #include <wlan_osif_priv.h>
32 #include <net/cfg80211.h>
33 #ifdef IPA_OPT_WIFI_DP
34 #include "init_deinit_lmac.h"
35 #endif
36 #if defined(QCA_LL_TX_FLOW_CONTROL_V2) || !defined(QCA_IPA_LL_TX_FLOW_CONTROL)
37 #include <cdp_txrx_flow_ctrl_v2.h>
38 #include <cdp_txrx_peer_ops.h>
39 #endif
40 #include <qal_vbus_dev.h>
41 
42 #define IPA_SPS_DESC_SIZE 8
43 #define IPA_DEFAULT_HDL 0
44 #ifdef IPA_WDS_EASYMESH_FEATURE
45 #define IPA_TA_PEER_ID_ATTRI 2
46 #endif
47 #ifdef IPA_OPT_WIFI_DP
48 #define IPA_WDI_MAX_FILTER 2
49 #define IPV6BYTES 16 /* IPV6 addr: 128bits/8 = 16bytes */
50 #define IPV4BYTES 4 /* IPV4 addr: 32bits/8 = 4bytes */
51 #define DP_MAX_SLEEP_TIME 100
52 #define IPV4 0x0008
53 #define IPV6 0xdd86
54 #define IPV6ARRAY 4
55 #endif
56 
57 static struct wlan_ipa_priv *gp_ipa;
58 static void wlan_ipa_set_pending_tx_timer(struct wlan_ipa_priv *ipa_ctx);
59 static void wlan_ipa_reset_pending_tx_timer(struct wlan_ipa_priv *ipa_ctx);
60 
61 static inline
62 bool wlan_ipa_is_driver_unloading(struct wlan_ipa_priv *ipa_ctx)
63 {
64 	if (ipa_ctx->driver_is_unloading)
65 		return ipa_ctx->driver_is_unloading();
66 	return false;
67 }
68 
69 static struct wlan_ipa_iface_2_client {
70 	qdf_ipa_client_type_t cons_client;
71 	qdf_ipa_client_type_t prod_client;
72 } wlan_ipa_iface_2_client[WLAN_IPA_CLIENT_MAX_IFACE] = {
73 	{
74 		QDF_IPA_CLIENT_WLAN2_CONS, QDF_IPA_CLIENT_WLAN1_PROD
75 	},
76 	{
77 		QDF_IPA_CLIENT_MCC2_CONS,  QDF_IPA_CLIENT_WLAN1_PROD
78 	},
79 #if WLAN_IPA_CLIENT_MAX_IFACE >= 3
80 	{
81 		QDF_IPA_CLIENT_WLAN4_CONS, QDF_IPA_CLIENT_WLAN1_PROD
82 	},
83 #if WLAN_IPA_CLIENT_MAX_IFACE == 4
84 	{
85 		QDF_IPA_CLIENT_WLAN4_CONS, QDF_IPA_CLIENT_WLAN1_PROD
86 	},
87 #endif
88 #endif
89 };
90 
91 /* Local Function Prototypes */
92 static void wlan_ipa_i2w_cb(void *priv, qdf_ipa_dp_evt_type_t evt,
93 			    unsigned long data);
94 static void wlan_ipa_w2i_cb(void *priv, qdf_ipa_dp_evt_type_t evt,
95 			    unsigned long data);
96 static void wlan_ipa_update_wds_params(struct wlan_ipa_priv *ipa_ctx,
97 				       qdf_ipa_wdi_init_in_params_t *in);
98 static void wlan_ipa_msg_wds_update(bool ipa_wds, qdf_ipa_wlan_msg_t *msg);
99 
100 /**
101  * wlan_ipa_uc_sta_is_enabled() - Is STA mode IPA uC offload enabled?
102  * @ipa_cfg: IPA config
103  *
104  * Return: true if STA mode IPA uC offload is enabled, false otherwise
105  */
106 static inline bool wlan_ipa_uc_sta_is_enabled(struct wlan_ipa_config *ipa_cfg)
107 {
108 	return WLAN_IPA_IS_CONFIG_ENABLED(ipa_cfg, WLAN_IPA_UC_STA_ENABLE_MASK);
109 }
110 
111 /**
112  * wlan_ipa_is_pre_filter_enabled() - Is IPA pre-filter enabled?
113  * @ipa_cfg: IPA config
114  *
115  * Return: true if pre-filter is enabled, otherwise false
116  */
117 static inline
118 bool wlan_ipa_is_pre_filter_enabled(struct wlan_ipa_config *ipa_cfg)
119 {
120 	return WLAN_IPA_IS_CONFIG_ENABLED(ipa_cfg,
121 					 WLAN_IPA_PRE_FILTER_ENABLE_MASK);
122 }
123 
124 /**
125  * wlan_ipa_is_ipv6_enabled() - Is IPA IPv6 enabled?
126  * @ipa_cfg: IPA config
127  *
128  * Return: true if IPv6 is enabled, otherwise false
129  */
130 static inline bool wlan_ipa_is_ipv6_enabled(struct wlan_ipa_config *ipa_cfg)
131 {
132 	return WLAN_IPA_IS_CONFIG_ENABLED(ipa_cfg, WLAN_IPA_IPV6_ENABLE_MASK);
133 }
134 
135 /**
136  * wlan_ipa_is_sta_only_offload_enabled() - Is IPA STA only offload enabled
137  *
138  * STA only IPA offload is needed on MDM platforms to support
139  * tethering scenarios in STA-SAP configurations when SAP is idle.
140  *
141  * Currently in STA-SAP configurations, IPA pipes are enabled only
142  * when a wifi client is connected to SAP.
143  *
144  * Impact of this API is only limited to when IPA pipes are enabled
145  * and disabled. To take effect, WLAN_IPA_UC_STA_ENABLE_MASK needs to
146  * set to 1.
147  *
148  * Return: true if MDM_PLATFORM is defined, false otherwise
149  */
150 #ifdef MDM_PLATFORM
151 static inline bool wlan_ipa_is_sta_only_offload_enabled(void)
152 {
153 	return true;
154 }
155 #else
156 #ifdef IPA_OPT_WIFI_DP
157 static inline bool wlan_ipa_is_sta_only_offload_enabled(void)
158 {
159 	return true;
160 }
161 #else
162 static inline bool wlan_ipa_is_sta_only_offload_enabled(void)
163 {
164 	return false;
165 }
166 #endif /* IPA_OPT_WIFI_DP */
167 #endif /* MDM_PLATFORM */
168 
169 /**
170  * wlan_ipa_msg_free_fn() - Free an IPA message
171  * @buff: pointer to the IPA message
172  * @len: length of the IPA message
173  * @type: type of IPA message
174  *
175  * Return: None
176  */
177 static void wlan_ipa_msg_free_fn(void *buff, uint32_t len, uint32_t type)
178 {
179 	ipa_debug("msg type:%d, len:%d", type, len);
180 	qdf_mem_free(buff);
181 }
182 
183 /**
184  * wlan_ipa_uc_loaded_uc_cb() - IPA UC loaded event callback
185  * @priv_ctxt: IPA context
186  *
187  * Will be called by IPA context.
188  * It's atomic context, then should be scheduled to kworker thread
189  *
190  * Return: None
191  */
192 static void wlan_ipa_uc_loaded_uc_cb(void *priv_ctxt)
193 {
194 	struct wlan_ipa_priv *ipa_ctx;
195 	struct op_msg_type *msg;
196 	struct uc_op_work_struct *uc_op_work;
197 
198 	if (!ipa_cb_is_ready()) {
199 		ipa_info("IPA is not READY");
200 		return;
201 	}
202 
203 	if (!priv_ctxt) {
204 		ipa_err("Invalid IPA context");
205 		return;
206 	}
207 
208 	ipa_ctx = priv_ctxt;
209 
210 	uc_op_work = &ipa_ctx->uc_op_work[WLAN_IPA_UC_OPCODE_UC_READY];
211 	if (!list_empty(&uc_op_work->work.work.entry)) {
212 		/* uc_op_work is not initialized yet */
213 		ipa_ctx->uc_loaded = true;
214 		return;
215 	}
216 
217 	msg = qdf_mem_malloc(sizeof(*msg));
218 	if (!msg)
219 		return;
220 
221 	msg->op_code = WLAN_IPA_UC_OPCODE_UC_READY;
222 
223 	/* When the same uC OPCODE is already pended, just return */
224 	if (uc_op_work->msg)
225 		goto done;
226 
227 	uc_op_work->msg = msg;
228 
229 	if (!qdf_atomic_read(&ipa_ctx->deinit_in_prog)) {
230 		qdf_sched_work(0, &uc_op_work->work);
231 	} else {
232 		uc_op_work->msg = NULL;
233 		goto done;
234 	}
235 
236 	/* work handler will free the msg buffer */
237 	return;
238 
239 done:
240 	qdf_mem_free(msg);
241 }
242 
243 struct wlan_ipa_priv *wlan_ipa_get_obj_context(void)
244 {
245 	return gp_ipa;
246 }
247 
248 /**
249  * wlan_ipa_send_pkt_to_tl() - Send an IPA packet to TL
250  * @iface_context: interface-specific IPA context
251  * @ipa_tx_desc: packet data descriptor
252  *
253  * Return: None
254  */
255 static void wlan_ipa_send_pkt_to_tl(
256 		struct wlan_ipa_iface_context *iface_context,
257 		qdf_ipa_rx_data_t *ipa_tx_desc)
258 {
259 	struct wlan_ipa_priv *ipa_ctx = iface_context->ipa_ctx;
260 	struct wlan_objmgr_pdev *pdev;
261 	struct wlan_objmgr_psoc *psoc;
262 	qdf_device_t osdev;
263 	qdf_nbuf_t skb;
264 	struct wlan_ipa_tx_desc *tx_desc;
265 	qdf_dma_addr_t paddr;
266 	QDF_STATUS status;
267 
268 	if (!ipa_ctx)
269 		return;
270 	pdev = ipa_ctx->pdev;
271 	psoc = wlan_pdev_get_psoc(pdev);
272 	osdev = wlan_psoc_get_qdf_dev(psoc);
273 
274 	qdf_spin_lock_bh(&iface_context->interface_lock);
275 	/*
276 	 * During CAC period, data packets shouldn't be sent over the air so
277 	 * drop all the packets here
278 	 */
279 	if (iface_context->device_mode == QDF_SAP_MODE ||
280 	    iface_context->device_mode == QDF_P2P_GO_MODE) {
281 		if (ipa_ctx->dfs_cac_block_tx) {
282 			ipa_free_skb(ipa_tx_desc);
283 			qdf_spin_unlock_bh(&iface_context->interface_lock);
284 			iface_context->stats.num_tx_cac_drop++;
285 			wlan_ipa_wdi_rm_try_release(ipa_ctx);
286 			return;
287 		}
288 	}
289 
290 	if (!osdev) {
291 		ipa_free_skb(ipa_tx_desc);
292 		iface_context->stats.num_tx_drop++;
293 		qdf_spin_unlock_bh(&iface_context->interface_lock);
294 		wlan_ipa_wdi_rm_try_release(ipa_ctx);
295 		return;
296 	}
297 	qdf_spin_unlock_bh(&iface_context->interface_lock);
298 
299 	skb = QDF_IPA_RX_DATA_SKB(ipa_tx_desc);
300 
301 	qdf_mem_zero(skb->cb, sizeof(skb->cb));
302 
303 	/* Store IPA Tx buffer ownership into SKB CB */
304 	qdf_nbuf_ipa_owned_set(skb);
305 
306 	if (qdf_mem_smmu_s1_enabled(osdev)) {
307 		status = qdf_nbuf_map(osdev, skb, QDF_DMA_TO_DEVICE);
308 		if (QDF_IS_STATUS_SUCCESS(status)) {
309 			paddr = qdf_nbuf_get_frag_paddr(skb, 0);
310 		} else {
311 			ipa_free_skb(ipa_tx_desc);
312 			qdf_spin_lock_bh(&iface_context->interface_lock);
313 			iface_context->stats.num_tx_drop++;
314 			qdf_spin_unlock_bh(&iface_context->interface_lock);
315 			wlan_ipa_wdi_rm_try_release(ipa_ctx);
316 			return;
317 		}
318 	} else {
319 		paddr = QDF_IPA_RX_DATA_DMA_ADDR(ipa_tx_desc);
320 	}
321 
322 	if (wlan_ipa_uc_sta_is_enabled(ipa_ctx->config)) {
323 		qdf_nbuf_mapped_paddr_set(skb,
324 					  paddr +
325 					  WLAN_IPA_WLAN_FRAG_HEADER +
326 					  WLAN_IPA_WLAN_IPA_HEADER);
327 		QDF_IPA_RX_DATA_SKB_LEN(ipa_tx_desc) -=
328 			WLAN_IPA_WLAN_FRAG_HEADER + WLAN_IPA_WLAN_IPA_HEADER;
329 	} else {
330 		qdf_nbuf_mapped_paddr_set(skb, paddr);
331 	}
332 
333 	qdf_spin_lock_bh(&ipa_ctx->q_lock);
334 	/* get free Tx desc and assign ipa_tx_desc pointer */
335 	if (ipa_ctx->tx_desc_free_list.count &&
336 	    qdf_list_remove_front(&ipa_ctx->tx_desc_free_list,
337 				  (qdf_list_node_t **)&tx_desc) ==
338 							QDF_STATUS_SUCCESS) {
339 		tx_desc->ipa_tx_desc_ptr = ipa_tx_desc;
340 		ipa_ctx->stats.num_tx_desc_q_cnt++;
341 		qdf_spin_unlock_bh(&ipa_ctx->q_lock);
342 		/* Store Tx Desc index into SKB CB */
343 		qdf_nbuf_ipa_priv_set(skb, tx_desc->id);
344 	} else {
345 		ipa_ctx->stats.num_tx_desc_error++;
346 		qdf_spin_unlock_bh(&ipa_ctx->q_lock);
347 
348 		if (qdf_mem_smmu_s1_enabled(osdev)) {
349 			if (wlan_ipa_uc_sta_is_enabled(ipa_ctx->config))
350 				qdf_nbuf_mapped_paddr_set(skb, paddr);
351 
352 			qdf_nbuf_unmap(osdev, skb, QDF_DMA_TO_DEVICE);
353 		}
354 
355 		qdf_ipa_free_skb(ipa_tx_desc);
356 		wlan_ipa_wdi_rm_try_release(ipa_ctx);
357 		return;
358 	}
359 
360 	skb = cdp_ipa_tx_send_data_frame(ipa_ctx->dp_soc,
361 					 iface_context->session_id,
362 					 QDF_IPA_RX_DATA_SKB(ipa_tx_desc));
363 	if (skb) {
364 		qdf_nbuf_free(skb);
365 		iface_context->stats.num_tx_err++;
366 		return;
367 	}
368 
369 	atomic_inc(&ipa_ctx->tx_ref_cnt);
370 
371 	iface_context->stats.num_tx++;
372 }
373 
374 /**
375  * wlan_ipa_forward() - handle packet forwarding to wlan tx
376  * @ipa_ctx: pointer to ipa ipa context
377  * @iface_ctx: interface context
378  * @skb: data pointer
379  *
380  * if exception packet has set forward bit, copied new packet should be
381  * forwarded to wlan tx. if wlan subsystem is in suspend state, packet should
382  * put into pm queue and tx procedure will be differed
383  *
384  * Return: None
385  */
386 static void wlan_ipa_forward(struct wlan_ipa_priv *ipa_ctx,
387 			     struct wlan_ipa_iface_context *iface_ctx,
388 			     qdf_nbuf_t skb)
389 {
390 	struct wlan_ipa_pm_tx_cb *pm_tx_cb;
391 
392 	qdf_spin_lock_bh(&ipa_ctx->pm_lock);
393 
394 	/* Set IPA ownership for intra-BSS Tx packets to avoid skb_orphan */
395 	qdf_nbuf_ipa_owned_set(skb);
396 
397 	/* WLAN subsystem is in suspend, put in queue */
398 	if (ipa_ctx->suspended) {
399 		qdf_spin_unlock_bh(&ipa_ctx->pm_lock);
400 		ipa_info_rl("Tx in suspend, put in queue");
401 		qdf_mem_zero(skb->cb, sizeof(skb->cb));
402 		pm_tx_cb = (struct wlan_ipa_pm_tx_cb *)skb->cb;
403 		pm_tx_cb->exception = true;
404 		pm_tx_cb->iface_context = iface_ctx;
405 		qdf_spin_lock_bh(&ipa_ctx->pm_lock);
406 		qdf_nbuf_queue_add(&ipa_ctx->pm_queue_head, skb);
407 		qdf_spin_unlock_bh(&ipa_ctx->pm_lock);
408 		ipa_ctx->stats.num_tx_queued++;
409 	} else {
410 		/* Resume, put packet into WLAN TX */
411 		qdf_spin_unlock_bh(&ipa_ctx->pm_lock);
412 
413 		if (ipa_ctx->softap_xmit) {
414 			if (ipa_ctx->softap_xmit(skb, iface_ctx->dev)) {
415 				ipa_err_rl("packet Tx fail");
416 				ipa_ctx->stats.num_tx_fwd_err++;
417 			} else {
418 				ipa_ctx->stats.num_tx_fwd_ok++;
419 			}
420 		} else {
421 			dev_kfree_skb_any(skb);
422 		}
423 	}
424 }
425 
426 #ifndef QCA_IPA_LL_TX_FLOW_CONTROL
427 static inline
428 bool wlan_ipa_tx_desc_thresh_reached(struct cdp_soc_t *soc, uint8_t vdev_id)
429 {
430 	return cdp_tx_desc_thresh_reached(soc, vdev_id);
431 }
432 
433 static inline
434 bool wlan_ipa_get_peer_state(struct cdp_soc_t *soc, uint8_t vdev_id,
435 			     uint8_t *peer_mac)
436 {
437 	if (cdp_peer_state_get(soc, vdev_id, peer_mac) ==
438 	    OL_TXRX_PEER_STATE_AUTH)
439 		return true;
440 
441 	return false;
442 }
443 #else
444 static inline
445 bool wlan_ipa_tx_desc_thresh_reached(struct cdp_soc_t *soc, uint8_t vdev_id)
446 {
447 	return false;
448 }
449 
450 static inline
451 bool wlan_ipa_get_peer_state(struct cdp_soc_t *soc, uint8_t vdev_id,
452 			     uint8_t *peer_mac)
453 {
454 	return cdp_peer_get_authorize(soc, vdev_id, peer_mac);
455 }
456 #endif
457 
458 /**
459  * wlan_ipa_intrabss_forward() - Forward intra bss packets.
460  * @ipa_ctx: pointer to IPA IPA struct
461  * @iface_ctx: ipa interface context
462  * @desc: Firmware descriptor
463  * @skb: Data buffer
464  *
465  * Return:
466  *      WLAN_IPA_FORWARD_PKT_NONE
467  *      WLAN_IPA_FORWARD_PKT_DISCARD
468  *      WLAN_IPA_FORWARD_PKT_LOCAL_STACK
469  *
470  */
471 static enum wlan_ipa_forward_type wlan_ipa_intrabss_forward(
472 		struct wlan_ipa_priv *ipa_ctx,
473 		struct wlan_ipa_iface_context *iface_ctx,
474 		uint8_t desc,
475 		qdf_nbuf_t skb)
476 {
477 	int ret = WLAN_IPA_FORWARD_PKT_NONE;
478 	void *soc = ipa_ctx->dp_soc;
479 
480 	if ((desc & FW_RX_DESC_FORWARD_M)) {
481 		if (wlan_ipa_tx_desc_thresh_reached(soc,
482 						    iface_ctx->session_id)) {
483 			/* Drop the packet*/
484 			ipa_ctx->stats.num_tx_fwd_err++;
485 			goto drop_pkt;
486 		}
487 
488 		ipa_debug_rl("Forward packet to Tx (fw_desc=%d)", desc);
489 		ipa_ctx->ipa_tx_forward++;
490 
491 		if ((desc & FW_RX_DESC_DISCARD_M)) {
492 			wlan_ipa_forward(ipa_ctx, iface_ctx, skb);
493 			ipa_ctx->ipa_rx_internal_drop_count++;
494 			ipa_ctx->ipa_rx_discard++;
495 			ret = WLAN_IPA_FORWARD_PKT_DISCARD;
496 		} else {
497 			struct sk_buff *cloned_skb = skb_clone(skb, GFP_ATOMIC);
498 
499 			if (cloned_skb)
500 				wlan_ipa_forward(ipa_ctx, iface_ctx,
501 						 cloned_skb);
502 			else
503 				ipa_err_rl("tx skb alloc failed");
504 			ret = WLAN_IPA_FORWARD_PKT_LOCAL_STACK;
505 		}
506 	}
507 	return ret;
508 
509 drop_pkt:
510 	dev_kfree_skb_any(skb);
511 	ret = WLAN_IPA_FORWARD_PKT_DISCARD;
512 	return ret;
513 }
514 
515 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 10, 0)) || \
516 	defined(CONFIG_IPA_WDI_UNIFIED_API)
517 /*
518  * TODO: Get WDI version through FW capabilities
519  */
520 #if defined(QCA_WIFI_QCA6290) || defined(QCA_WIFI_QCA6390) || \
521     defined(QCA_WIFI_QCA6490) || defined(QCA_WIFI_QCA6750) || \
522     defined(QCA_WIFI_WCN7850)
523 static inline void wlan_ipa_wdi_get_wdi_version(struct wlan_ipa_priv *ipa_ctx)
524 {
525 	ipa_ctx->wdi_version = IPA_WDI_3;
526 }
527 #elif defined(QCA_WIFI_KIWI) || defined(QCA_WIFI_KIWI_V2)
528 static inline void wlan_ipa_wdi_get_wdi_version(struct wlan_ipa_priv *ipa_ctx)
529 {
530 	ipa_ctx->wdi_version = IPA_WDI_3_V2;
531 }
532 #elif defined(QCA_WIFI_QCN9000) || defined(QCA_WIFI_QCN9224)
533 static inline void wlan_ipa_wdi_get_wdi_version(struct wlan_ipa_priv *ipa_ctx)
534 {
535 	uint8_t wdi_ver;
536 
537 	cdp_ipa_get_wdi_version(ipa_ctx->dp_soc, &wdi_ver);
538 	ipa_ctx->wdi_version = wdi_ver;
539 }
540 #elif defined(QCA_WIFI_3_0)
541 static inline void wlan_ipa_wdi_get_wdi_version(struct wlan_ipa_priv *ipa_ctx)
542 {
543 	ipa_ctx->wdi_version = IPA_WDI_2;
544 }
545 #else
546 static inline void wlan_ipa_wdi_get_wdi_version(struct wlan_ipa_priv *ipa_ctx)
547 {
548 	ipa_ctx->wdi_version = IPA_WDI_1;
549 }
550 #endif
551 
552 static inline bool wlan_ipa_wdi_is_smmu_enabled(struct wlan_ipa_priv *ipa_ctx,
553 					       qdf_device_t osdev)
554 {
555 	return ipa_ctx->is_smmu_enabled && qdf_mem_smmu_s1_enabled(osdev);
556 }
557 
558 #ifdef IPA_WDS_EASYMESH_FEATURE
559 /**
560  * wlan_ipa_ast_notify_cb() - IPA AST create/update CB
561  * @priv: IPA context
562  * @data: Structure used for updating the AST table
563  *
564  * Will be called by IPA context.
565  *
566  * Return: None
567  */
568 static void wlan_ipa_ast_notify_cb(void *priv, void *data)
569 {
570 	qdf_ipa_ast_info_type_t *ast_info;
571 	struct wlan_ipa_priv *ipa_ctx;
572 
573 	if (!data) {
574 		dp_err("Invalid IPA AST data context");
575 		return;
576 	}
577 
578 	if (!priv) {
579 		dp_err("Invalid IPA context");
580 		return;
581 	}
582 
583 	ast_info = (qdf_ipa_ast_info_type_t *)data;
584 	ipa_ctx = (struct wlan_ipa_priv *)priv;
585 
586 	cdp_ipa_ast_create(ipa_ctx->dp_soc, ast_info);
587 }
588 #else
589 static inline void wlan_ipa_ast_notify_cb(void *priv, void *data)
590 {
591 }
592 #endif
593 
594 static inline QDF_STATUS
595 wlan_ipa_wdi_setup(struct wlan_ipa_priv *ipa_ctx,
596 		   qdf_device_t osdev)
597 {
598 	qdf_ipa_sys_connect_params_t *sys_in = NULL;
599 	int i;
600 	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
601 
602 	sys_in = qdf_mem_malloc(sizeof(*sys_in) * WLAN_IPA_MAX_IFACE);
603 	if (!sys_in)
604 		return QDF_STATUS_E_NOMEM;
605 
606 	for (i = 0; i < WLAN_IPA_MAX_IFACE; i++)
607 		qdf_mem_copy(sys_in + i,
608 			     &ipa_ctx->sys_pipe[i].ipa_sys_params,
609 			     sizeof(qdf_ipa_sys_connect_params_t));
610 
611 	qdf_status = cdp_ipa_setup(ipa_ctx->dp_soc, ipa_ctx->dp_pdev_id,
612 				   wlan_ipa_i2w_cb, wlan_ipa_w2i_cb,
613 				   wlan_ipa_wdi_meter_notifier_cb,
614 				   ipa_ctx->config->desc_size,
615 				   ipa_ctx,
616 				   wlan_ipa_is_rm_enabled(ipa_ctx->config),
617 				   &ipa_ctx->tx_pipe_handle,
618 				   &ipa_ctx->rx_pipe_handle,
619 				   wlan_ipa_wdi_is_smmu_enabled(ipa_ctx, osdev),
620 				   sys_in, ipa_ctx->over_gsi, ipa_ctx->hdl,
621 				   (qdf_ipa_wdi_hdl_t)ipa_ctx->instance_id,
622 				   wlan_ipa_ast_notify_cb);
623 
624 	qdf_mem_free(sys_in);
625 
626 	return qdf_status;
627 }
628 
629 #ifdef FEATURE_METERING
630 /**
631  * wlan_ipa_wdi_init_metering() - IPA WDI metering init
632  * @ipa_ctxt: IPA context
633  * @in: IPA WDI in param
634  *
635  * Return: QDF_STATUS
636  */
637 static inline void wlan_ipa_wdi_init_metering(struct wlan_ipa_priv *ipa_ctxt,
638 					      qdf_ipa_wdi_init_in_params_t *in)
639 {
640 	QDF_IPA_WDI_INIT_IN_PARAMS_WDI_NOTIFY(in) =
641 				wlan_ipa_wdi_meter_notifier_cb;
642 }
643 #else
644 static inline void wlan_ipa_wdi_init_metering(struct wlan_ipa_priv *ipa_ctxt,
645 					      qdf_ipa_wdi_init_in_params_t *in)
646 {
647 }
648 #endif
649 
650 #ifdef IPA_OPT_WIFI_DP
651 /**
652  * wlan_ipa_wdi_init_set_opt_wifi_dp - set if optional wifi dp enabled from IPA
653  * @ipa_ctxt: IPA context
654  * @out: IPA WDI out param
655  *
656  * Return: void
657  */
658 static inline void wlan_ipa_wdi_init_set_opt_wifi_dp(
659 					     struct wlan_ipa_priv *ipa_ctxt,
660 					     qdf_ipa_wdi_init_out_params_t *out)
661 {
662 	ipa_ctxt->opt_wifi_datapath =
663 				QDF_IPA_WDI_INIT_OUT_PARAMS_OPT_WIFI_DP(out);
664 }
665 
666 /**
667  * wlan_ipa_opt_wifi_dp_enabled - set if optional wifi dp enabled in WLAN
668  *
669  * Return: bool
670  */
671 static inline bool wlan_ipa_opt_wifi_dp_enabled(void)
672 {
673 	return true;
674 }
675 #else
676 static inline void wlan_ipa_wdi_init_set_opt_wifi_dp(
677 					     struct wlan_ipa_priv *ipa_ctxt,
678 					     qdf_ipa_wdi_init_out_params_t *out)
679 {
680 }
681 
682 static inline bool wlan_ipa_opt_wifi_dp_enabled(void)
683 {
684 	return false;
685 }
686 #endif
687 
688 #ifdef IPA_WDS_EASYMESH_FEATURE
689 /**
690  * wlan_ipa_update_wds_params() - IPA update WDS parameters
691  * @ipa_ctx: IPA context
692  * @in: IPA wdi init in params
693  *
694  * This function is to update wds status to IPA in wdi init params
695  *
696  * Return: None
697  */
698 static void wlan_ipa_update_wds_params(struct wlan_ipa_priv *ipa_ctx,
699 				       qdf_ipa_wdi_init_in_params_t *in)
700 {
701 	QDF_IPA_WDI_INIT_IN_PARAMS_WDS_UPDATE(in) = ipa_ctx->config->ipa_wds;
702 }
703 
704 /**
705  * wlan_ipa_msg_wds_update() - IPA message WDS update
706  * @ipa_wds: IPA WDS status
707  * @msg: Meta data message for IPA
708  *
709  * This function is to update wds status to IPA in meta message
710  *
711  * Return: None
712  */
713 static void wlan_ipa_msg_wds_update(bool ipa_wds,
714 				    qdf_ipa_wlan_msg_t *msg)
715 {
716 	QDF_IPA_WLAN_MSG_WDS_UPDATE(msg) = ipa_wds;
717 }
718 #else
719 static void wlan_ipa_update_wds_params(struct wlan_ipa_priv *ipa_ctx,
720 				       qdf_ipa_wdi_init_in_params_t *in)
721 {
722 }
723 
724 static void wlan_ipa_msg_wds_update(bool ipa_wds,
725 				    qdf_ipa_wlan_msg_t *msg)
726 {
727 }
728 #endif
729 
730 /**
731  * wlan_ipa_wdi_init() - IPA WDI init
732  * @ipa_ctx: IPA context
733  *
734  * Return: QDF_STATUS
735  */
736 static inline QDF_STATUS wlan_ipa_wdi_init(struct wlan_ipa_priv *ipa_ctx)
737 {
738 	qdf_ipa_wdi_init_in_params_t in;
739 	qdf_ipa_wdi_init_out_params_t out;
740 	int ret;
741 
742 	ipa_ctx->uc_loaded = false;
743 
744 	qdf_mem_zero(&in, sizeof(in));
745 	qdf_mem_zero(&out, sizeof(out));
746 
747 	QDF_IPA_WDI_INIT_IN_PARAMS_WDI_VERSION(&in) = ipa_ctx->wdi_version;
748 	QDF_IPA_WDI_INIT_IN_PARAMS_NOTIFY(&in) = wlan_ipa_uc_loaded_uc_cb;
749 	QDF_IPA_WDI_INIT_IN_PARAMS_PRIV(&in) = ipa_ctx;
750 	QDF_IPA_WDI_INIT_IN_PARAMS_INSTANCE_ID(&in) = ipa_ctx->instance_id;
751 	wlan_ipa_update_wds_params(ipa_ctx, &in);
752 	wlan_ipa_wdi_init_metering(ipa_ctx, &in);
753 	ret = qdf_ipa_wdi_init(&in, &out);
754 	if (ret) {
755 		ipa_err("ipa_wdi_init failed with ret=%d", ret);
756 		return QDF_STATUS_E_FAILURE;
757 	}
758 
759 	ipa_ctx->over_gsi =
760 		QDF_IPA_WDI_INIT_OUT_PARAMS_IS_OVER_GSI(&out);
761 	ipa_ctx->is_smmu_enabled =
762 		QDF_IPA_WDI_INIT_OUT_PARAMS_IS_SMMU_ENABLED(&out);
763 	ipa_ctx->hdl = QDF_IPA_WDI_INIT_OUT_PARAMS_HANDLE(&out);
764 	wlan_ipa_wdi_init_set_opt_wifi_dp(ipa_ctx, &out);
765 
766 	ipa_info("ipa_over_gsi: %d, is_smmu_enabled: %d, handle: %d",
767 		 ipa_ctx->over_gsi, ipa_ctx->is_smmu_enabled, ipa_ctx->hdl);
768 	ipa_info("opt_dp: enabled from IPA : %d",
769 		 ipa_ctx->opt_wifi_datapath);
770 
771 	if (QDF_IPA_WDI_INIT_OUT_PARAMS_IS_UC_READY(&out)) {
772 		ipa_debug("IPA uC READY");
773 		ipa_ctx->uc_loaded = true;
774 	} else {
775 		ipa_info("IPA uc not ready");
776 		return QDF_STATUS_E_BUSY;
777 	}
778 
779 	return QDF_STATUS_SUCCESS;
780 }
781 
782 static inline int wlan_ipa_wdi_cleanup(qdf_ipa_wdi_hdl_t hdl)
783 {
784 	int ret;
785 
786 	ret = qdf_ipa_wdi_cleanup(hdl);
787 	if (ret)
788 		ipa_info("ipa_wdi_cleanup failed ret=%d", ret);
789 	return ret;
790 }
791 
792 static inline int wlan_ipa_wdi_setup_sys_pipe(struct wlan_ipa_priv *ipa_ctx,
793 					     struct ipa_sys_connect_params *sys,
794 					     uint32_t *handle)
795 {
796 	return 0;
797 }
798 
799 static inline int wlan_ipa_wdi_teardown_sys_pipe(struct wlan_ipa_priv *ipa_ctx,
800 						uint32_t handle)
801 {
802 	return 0;
803 }
804 
805 /**
806  * wlan_ipa_pm_flush() - flush queued packets
807  * @data: IPA context
808  *
809  * Called during PM resume to send packets to TL which were queued
810  * while host was in the process of suspending.
811  *
812  * Return: None
813  */
814 static void wlan_ipa_pm_flush(void *data)
815 {
816 	struct wlan_ipa_priv *ipa_ctx = (struct wlan_ipa_priv *)data;
817 	struct wlan_ipa_pm_tx_cb *pm_tx_cb = NULL;
818 	qdf_nbuf_t skb;
819 	uint32_t dequeued = 0;
820 	qdf_netdev_t ndev;
821 
822 	qdf_spin_lock_bh(&ipa_ctx->pm_lock);
823 	while (((skb = qdf_nbuf_queue_remove(&ipa_ctx->pm_queue_head)) !=
824 	       NULL)) {
825 		qdf_spin_unlock_bh(&ipa_ctx->pm_lock);
826 
827 		pm_tx_cb = (struct wlan_ipa_pm_tx_cb *)skb->cb;
828 		dequeued++;
829 
830 		if (pm_tx_cb->exception) {
831 			if (ipa_ctx->softap_xmit &&
832 			    pm_tx_cb->iface_context->dev) {
833 				ipa_ctx->softap_xmit(skb,
834 						pm_tx_cb->iface_context->dev);
835 				ipa_ctx->stats.num_tx_fwd_ok++;
836 			} else {
837 				dev_kfree_skb_any(skb);
838 			}
839 		} else if (pm_tx_cb->send_to_nw) {
840 			ndev = pm_tx_cb->iface_context->dev;
841 
842 			if (ipa_ctx->send_to_nw && ndev) {
843 				ipa_ctx->send_to_nw(skb, ndev);
844 				ipa_ctx->ipa_rx_net_send_count++;
845 			} else {
846 				dev_kfree_skb_any(skb);
847 			}
848 		} else {
849 			wlan_ipa_send_pkt_to_tl(pm_tx_cb->iface_context,
850 						pm_tx_cb->ipa_tx_desc);
851 		}
852 
853 		qdf_spin_lock_bh(&ipa_ctx->pm_lock);
854 	}
855 	qdf_spin_unlock_bh(&ipa_ctx->pm_lock);
856 
857 	ipa_ctx->stats.num_tx_dequeued += dequeued;
858 	if (dequeued > ipa_ctx->stats.num_max_pm_queue)
859 		ipa_ctx->stats.num_max_pm_queue = dequeued;
860 }
861 
862 int wlan_ipa_uc_smmu_map(bool map, uint32_t num_buf, qdf_mem_info_t *buf_arr)
863 {
864 	if (!ipa_cb_is_ready()) {
865 		ipa_info("IPA is not READY");
866 		return 0;
867 	}
868 
869 	if (!num_buf) {
870 		ipa_info("No buffers to map/unmap");
871 		return 0;
872 	}
873 	/**
874 	 * This API will compile for prelithium chipset
875 	 * where we have only one soc so passing default
876 	 * handle to IPA which is 0.
877 	 */
878 	if (map)
879 		return qdf_ipa_wdi_create_smmu_mapping(IPA_DEFAULT_HDL,
880 						       num_buf, buf_arr);
881 	else
882 		return qdf_ipa_wdi_release_smmu_mapping(IPA_DEFAULT_HDL,
883 							num_buf, buf_arr);
884 	return 0;
885 }
886 
887 #ifdef MDM_PLATFORM
888 /**
889  * is_rx_dest_bridge_dev() - is RX skb bridge device terminated
890  * @iface_ctx: pointer to WLAN IPA interface context
891  * @nbuf: skb buffer
892  *
893  * Check if skb is destined for bridge device, where SAP is a bridge
894  * port of it.
895  *
896  * FIXME: If there's a BH lockless API to check if destination MAC
897  * address is a valid peer, this check can be deleted. Currently
898  * dp_find_peer_by_addr() is used to check if destination MAC
899  * is a valid peer. Since WLAN IPA RX is in process context,
900  * qdf_spin_lock_bh in dp_find_peer_by_addr() turns to spin_lock_bh
901  * and this BH lock hurts netif_rx.
902  *
903  * Return: true/false
904  */
905 static bool is_rx_dest_bridge_dev(struct wlan_ipa_iface_context *iface_ctx,
906 				  qdf_nbuf_t nbuf)
907 {
908 	qdf_netdev_t master_ndev;
909 	qdf_netdev_t ndev;
910 	struct ethhdr *eh;
911 	uint8_t da_is_bcmc;
912 	bool ret;
913 
914 	/*
915 	 * WDI 3.0 skb->cb[] info from IPA driver
916 	 * skb->cb[0] = vdev_id
917 	 * skb->cb[1].bit#1 = da_is_bcmc
918 	 */
919 	da_is_bcmc = ((uint8_t)nbuf->cb[1]) & 0x2;
920 	if (da_is_bcmc)
921 		return false;
922 
923 	ndev = iface_ctx->dev;
924 	if (!ndev)
925 		return false;
926 
927 	if (!netif_is_bridge_port(ndev))
928 		return false;
929 
930 	qal_vbus_rcu_read_lock();
931 
932 	master_ndev = netdev_master_upper_dev_get_rcu(ndev);
933 	if (!master_ndev) {
934 		ret = false;
935 		goto out;
936 	}
937 
938 	eh = (struct ethhdr *)qdf_nbuf_data(nbuf);
939 	if (qdf_mem_cmp(eh->h_dest, master_ndev->dev_addr, QDF_MAC_ADDR_SIZE)) {
940 		ret = false;
941 		goto out;
942 	}
943 
944 	ret = true;
945 
946 out:
947 	qal_vbus_rcu_read_unlock();
948 	return ret;
949 }
950 #else /* !MDM_PLATFORM */
951 static bool is_rx_dest_bridge_dev(struct wlan_ipa_iface_context *iface_ctx,
952 				  qdf_nbuf_t nbuf)
953 {
954 	return false;
955 }
956 #endif /* MDM_PLATFORM */
957 
958 static enum wlan_ipa_forward_type
959 wlan_ipa_rx_intrabss_fwd(struct wlan_ipa_priv *ipa_ctx,
960 			 struct wlan_ipa_iface_context *iface_ctx,
961 			 qdf_nbuf_t nbuf)
962 {
963 	uint8_t fw_desc = 0;
964 	bool fwd_success;
965 	int ret;
966 
967 	/* legacy intra-bss forwarding for WDI 1.0 and 2.0 */
968 	if (ipa_ctx->wdi_version < IPA_WDI_3) {
969 		fw_desc = (uint8_t)nbuf->cb[1];
970 		return wlan_ipa_intrabss_forward(ipa_ctx, iface_ctx, fw_desc,
971 						 nbuf);
972 	}
973 
974 	if (is_rx_dest_bridge_dev(iface_ctx, nbuf)) {
975 		fwd_success = 0;
976 		ret = WLAN_IPA_FORWARD_PKT_LOCAL_STACK;
977 		goto exit;
978 	}
979 
980 	if (cdp_ipa_rx_intrabss_fwd(ipa_ctx->dp_soc, iface_ctx->session_id,
981 				    nbuf, &fwd_success)) {
982 		ipa_ctx->ipa_rx_internal_drop_count++;
983 		ipa_ctx->ipa_rx_discard++;
984 
985 		ret = WLAN_IPA_FORWARD_PKT_DISCARD;
986 	} else {
987 		ret = WLAN_IPA_FORWARD_PKT_LOCAL_STACK;
988 	}
989 
990 exit:
991 	if (fwd_success)
992 		ipa_ctx->stats.num_tx_fwd_ok++;
993 	else
994 		ipa_ctx->stats.num_tx_fwd_err++;
995 
996 	return ret;
997 }
998 
999 #else /* CONFIG_IPA_WDI_UNIFIED_API */
1000 
1001 static inline void wlan_ipa_wdi_get_wdi_version(struct wlan_ipa_priv *ipa_ctx)
1002 {
1003 }
1004 
1005 static inline int wlan_ipa_wdi_is_smmu_enabled(struct wlan_ipa_priv *ipa_ctx,
1006 					       qdf_device_t osdev)
1007 {
1008 	return qdf_mem_smmu_s1_enabled(osdev);
1009 }
1010 
1011 static inline QDF_STATUS wlan_ipa_wdi_setup(struct wlan_ipa_priv *ipa_ctx,
1012 					    qdf_device_t osdev)
1013 {
1014 	return cdp_ipa_setup(ipa_ctx->dp_soc, ipa_ctx->dp_pdev_id,
1015 			     wlan_ipa_i2w_cb, wlan_ipa_w2i_cb,
1016 			     wlan_ipa_wdi_meter_notifier_cb,
1017 			     ipa_ctx->config->desc_size,
1018 			     ipa_ctx, wlan_ipa_is_rm_enabled(ipa_ctx->config),
1019 			     &ipa_ctx->tx_pipe_handle,
1020 			     &ipa_ctx->rx_pipe_handle);
1021 }
1022 
1023 static inline QDF_STATUS wlan_ipa_wdi_init(struct wlan_ipa_priv *ipa_ctx)
1024 {
1025 	struct ipa_wdi_uc_ready_params uc_ready_param;
1026 
1027 	ipa_ctx->uc_loaded = false;
1028 	uc_ready_param.priv = (void *)ipa_ctx;
1029 	uc_ready_param.notify = wlan_ipa_uc_loaded_uc_cb;
1030 	if (qdf_ipa_uc_reg_rdyCB(&uc_ready_param)) {
1031 		ipa_info("UC Ready CB register fail");
1032 		return QDF_STATUS_E_FAILURE;
1033 	}
1034 
1035 	if (true == uc_ready_param.is_uC_ready) {
1036 		ipa_info("UC Ready");
1037 		ipa_ctx->uc_loaded = true;
1038 	} else {
1039 		return QDF_STATUS_E_BUSY;
1040 	}
1041 
1042 	return QDF_STATUS_SUCCESS;
1043 }
1044 
1045 static inline int wlan_ipa_wdi_cleanup(void)
1046 {
1047 	int ret;
1048 
1049 	ret = qdf_ipa_uc_dereg_rdyCB();
1050 	if (ret)
1051 		ipa_info("UC Ready CB deregister fail");
1052 	return ret;
1053 }
1054 
1055 static inline int wlan_ipa_wdi_setup_sys_pipe(
1056 		struct wlan_ipa_priv *ipa_ctx,
1057 		struct ipa_sys_connect_params *sys, uint32_t *handle)
1058 {
1059 	return qdf_ipa_setup_sys_pipe(sys, handle);
1060 }
1061 
1062 static inline int wlan_ipa_wdi_teardown_sys_pipe(
1063 		struct wlan_ipa_priv *ipa_ctx,
1064 		uint32_t handle)
1065 {
1066 	return qdf_ipa_teardown_sys_pipe(handle);
1067 }
1068 
1069 /**
1070  * wlan_ipa_pm_flush() - flush queued packets
1071  * @data: IPA context
1072  *
1073  * Called during PM resume to send packets to TL which were queued
1074  * while host was in the process of suspending.
1075  *
1076  * Return: None
1077  */
1078 static void wlan_ipa_pm_flush(void *data)
1079 {
1080 	struct wlan_ipa_priv *ipa_ctx = (struct wlan_ipa_priv *)data;
1081 	struct wlan_ipa_pm_tx_cb *pm_tx_cb = NULL;
1082 	qdf_nbuf_t skb;
1083 	uint32_t dequeued = 0;
1084 
1085 	qdf_wake_lock_acquire(&ipa_ctx->wake_lock,
1086 			      WIFI_POWER_EVENT_WAKELOCK_IPA);
1087 	qdf_spin_lock_bh(&ipa_ctx->pm_lock);
1088 	while (((skb = qdf_nbuf_queue_remove(&ipa_ctx->pm_queue_head)) !=
1089 	       NULL)) {
1090 		qdf_spin_unlock_bh(&ipa_ctx->pm_lock);
1091 
1092 		pm_tx_cb = (struct wlan_ipa_pm_tx_cb *)skb->cb;
1093 		dequeued++;
1094 
1095 		if (pm_tx_cb->exception) {
1096 			if (ipa_ctx->softap_xmit &&
1097 			    pm_tx_cb->iface_context->dev) {
1098 				ipa_ctx->softap_xmit(skb,
1099 						pm_tx_cb->iface_context->dev);
1100 				ipa_ctx->stats.num_tx_fwd_ok++;
1101 			} else {
1102 				dev_kfree_skb_any(skb);
1103 			}
1104 		} else {
1105 			wlan_ipa_send_pkt_to_tl(pm_tx_cb->iface_context,
1106 						pm_tx_cb->ipa_tx_desc);
1107 		}
1108 
1109 		qdf_spin_lock_bh(&ipa_ctx->pm_lock);
1110 	}
1111 	qdf_spin_unlock_bh(&ipa_ctx->pm_lock);
1112 	qdf_wake_lock_release(&ipa_ctx->wake_lock,
1113 			      WIFI_POWER_EVENT_WAKELOCK_IPA);
1114 
1115 	ipa_ctx->stats.num_tx_dequeued += dequeued;
1116 	if (dequeued > ipa_ctx->stats.num_max_pm_queue)
1117 		ipa_ctx->stats.num_max_pm_queue = dequeued;
1118 }
1119 
1120 int wlan_ipa_uc_smmu_map(bool map, uint32_t num_buf, qdf_mem_info_t *buf_arr)
1121 {
1122 	if (!num_buf) {
1123 		ipa_info("No buffers to map/unmap");
1124 		return 0;
1125 	}
1126 
1127 	if (map)
1128 		return qdf_ipa_wdi_create_smmu_mapping(IPA_DEFAULT_HDL,
1129 						       num_buf, buf_arr);
1130 	else
1131 		return qdf_ipa_wdi_release_smmu_mapping(IPA_DEFAULT_HDL,
1132 							num_buf, buf_arr);
1133 	return 0;
1134 }
1135 
1136 static enum wlan_ipa_forward_type
1137 wlan_ipa_rx_intrabss_fwd(struct wlan_ipa_priv *ipa_ctx,
1138 			 struct wlan_ipa_iface_context *iface_ctx,
1139 			 qdf_nbuf_t nbuf)
1140 {
1141 	uint8_t fw_desc;
1142 
1143 	fw_desc = (uint8_t)nbuf->cb[1];
1144 
1145 	return wlan_ipa_intrabss_forward(ipa_ctx, iface_ctx, fw_desc, nbuf);
1146 }
1147 
1148 #endif /* CONFIG_IPA_WDI_UNIFIED_API */
1149 
1150 /**
1151  * wlan_ipa_send_sta_eapol_to_nw() - Send Rx EAPOL pkt for STA to Kernel
1152  * @skb: network buffer
1153  * @pdev: pdev obj
1154  *
1155  * Called when a EAPOL packet is received via IPA Exception path
1156  * before wlan_ipa_setup_iface is done for STA.
1157  *
1158  * Return: 0 on success, err_code for failure.
1159  */
1160 static int wlan_ipa_send_sta_eapol_to_nw(qdf_nbuf_t skb,
1161 					 struct wlan_objmgr_pdev *pdev)
1162 {
1163 	struct wlan_ipa_priv *ipa_ctx;
1164 	struct ethhdr *eh;
1165 	struct wlan_objmgr_vdev *vdev = NULL;
1166 
1167 	ipa_ctx = ipa_pdev_get_priv_obj(pdev);
1168 	if (!ipa_ctx)
1169 		return -EINVAL;
1170 
1171 	eh = (struct ethhdr *)qdf_nbuf_data(skb);
1172 	vdev = wlan_objmgr_get_vdev_by_macaddr_from_pdev(
1173 				pdev, eh->h_dest, WLAN_IPA_ID);
1174 	if (!vdev) {
1175 		ipa_err_rl("Invalid vdev");
1176 		return -EINVAL;
1177 	}
1178 
1179 	if (wlan_vdev_mlme_get_opmode(vdev) != QDF_STA_MODE) {
1180 		ipa_err_rl("device_mode is not STA");
1181 		wlan_objmgr_vdev_release_ref(vdev, WLAN_IPA_ID);
1182 		return -EINVAL;
1183 	}
1184 
1185 	skb->destructor = wlan_ipa_uc_rt_debug_destructor;
1186 
1187 	if (ipa_ctx->send_to_nw)
1188 		ipa_ctx->send_to_nw(skb, vdev->vdev_nif.osdev->wdev->netdev);
1189 
1190 	ipa_ctx->ipa_rx_net_send_count++;
1191 	ipa_ctx->stats.num_rx_no_iface_eapol++;
1192 	wlan_objmgr_vdev_release_ref(vdev, WLAN_IPA_ID);
1193 	return 0;
1194 }
1195 
1196 #ifndef QCA_IPA_LL_TX_FLOW_CONTROL
1197 
1198 #ifdef SAP_DHCP_FW_IND
1199 /**
1200  * wlan_ipa_send_to_nw_sap_dhcp - Check if SAP mode and skb is a DHCP packet
1201  * @iface_ctx: IPA per-interface ctx
1202  * @skb: socket buffer
1203  *
1204  * Check if @iface_ctx is SAP and @skb is a DHCP packet.
1205  *
1206  * When SAP_DHCP_FW_IND feature is enabled, DHCP packets received will be
1207  * notified to target via WMI cmd. However if system is suspended, WMI
1208  * cmd is not allowed from Host to Target.
1209  *
1210  * Return: true if iface is SAP mode and skb is a DHCP packet. Otherwise false
1211  */
1212 static bool
1213 wlan_ipa_send_to_nw_sap_dhcp(struct wlan_ipa_iface_context *iface_ctx,
1214 			     qdf_nbuf_t skb)
1215 {
1216 	if (iface_ctx->device_mode == QDF_SAP_MODE &&
1217 	    qdf_nbuf_is_ipv4_dhcp_pkt(skb) == true)
1218 		return true;
1219 
1220 	return false;
1221 }
1222 #else /* !SAP_DHCP_FW_IND */
1223 static inline bool
1224 wlan_ipa_send_to_nw_sap_dhcp(struct wlan_ipa_iface_context *iface_ctx,
1225 			     qdf_nbuf_t skb)
1226 {
1227 	return false;
1228 }
1229 #endif /* SAP_DHCP_FW_IND */
1230 
1231 /**
1232  * wlan_ipa_send_to_nw_defer - Check if skb needs to deferred to network stack
1233  * @iface_ctx: IPA per-interface ctx
1234  * @skb: socket buffer
1235  *
1236  * Check if @skb received on @iface_ctx needs to be deferred to be passed
1237  * up to network stack.
1238  *
1239  * Return: true if needs to be deferred, otherwise false
1240  */
1241 static bool wlan_ipa_send_to_nw_defer(struct wlan_ipa_iface_context *iface_ctx,
1242 				      qdf_nbuf_t skb)
1243 {
1244 	struct wlan_ipa_priv *ipa_ctx = iface_ctx->ipa_ctx;
1245 
1246 	qdf_spin_lock_bh(&ipa_ctx->pm_lock);
1247 	if (!ipa_ctx->suspended) {
1248 		qdf_spin_unlock_bh(&ipa_ctx->pm_lock);
1249 		return false;
1250 	}
1251 	qdf_spin_unlock_bh(&ipa_ctx->pm_lock);
1252 
1253 	return wlan_ipa_send_to_nw_sap_dhcp(iface_ctx, skb);
1254 }
1255 
1256 /**
1257  * wlan_ipa_send_to_nw_queue - Add skb to pm_queue_head if deferred
1258  * @iface_ctx: IPA per-interface ctx
1259  * @skb: socket buffer
1260  *
1261  * Add @skb to pm_queue_head to defer passing up to network stack due to
1262  * system suspended.
1263  *
1264  * Return: None
1265  */
1266 static void wlan_ipa_send_to_nw_queue(struct wlan_ipa_iface_context *iface_ctx,
1267 				      qdf_nbuf_t skb)
1268 {
1269 	struct wlan_ipa_priv *ipa_ctx = iface_ctx->ipa_ctx;
1270 	struct wlan_ipa_pm_tx_cb *pm_cb;
1271 
1272 	qdf_mem_zero(skb->cb, sizeof(skb->cb));
1273 	pm_cb = (struct wlan_ipa_pm_tx_cb *)skb->cb;
1274 
1275 	pm_cb->send_to_nw = true;
1276 	pm_cb->iface_context = iface_ctx;
1277 
1278 	qdf_spin_lock_bh(&ipa_ctx->pm_lock);
1279 	qdf_nbuf_queue_add(&ipa_ctx->pm_queue_head, skb);
1280 	qdf_spin_unlock_bh(&ipa_ctx->pm_lock);
1281 
1282 	ipa_ctx->stats.num_tx_queued++;
1283 }
1284 #else /* QCA_IPA_LL_TX_FLOW_CONTROL */
1285 static inline bool
1286 wlan_ipa_send_to_nw_defer(struct wlan_ipa_iface_context *iface_ctx,
1287 			  qdf_nbuf_t skb)
1288 {
1289 	return false;
1290 }
1291 
1292 static inline void
1293 wlan_ipa_send_to_nw_queue(struct wlan_ipa_iface_context *iface_ctx,
1294 			  qdf_nbuf_t skb)
1295 {
1296 }
1297 #endif /* QCA_IPA_LL_TX_FLOW_CONTROL */
1298 
1299 /**
1300  * wlan_ipa_send_skb_to_network() - Send skb to kernel
1301  * @skb: network buffer
1302  * @iface_ctx: IPA interface context
1303  *
1304  * Called when a network buffer is received which should not be routed
1305  * to the IPA module.
1306  *
1307  * Return: None
1308  */
1309 static void
1310 wlan_ipa_send_skb_to_network(qdf_nbuf_t skb,
1311 			     struct wlan_ipa_iface_context *iface_ctx)
1312 {
1313 	struct wlan_ipa_priv *ipa_ctx;
1314 
1315 	ipa_ctx = iface_ctx->ipa_ctx;
1316 
1317 	if (!iface_ctx->dev) {
1318 		ipa_debug_rl("Invalid interface");
1319 		ipa_ctx->ipa_rx_internal_drop_count++;
1320 		dev_kfree_skb_any(skb);
1321 		return;
1322 	}
1323 
1324 	skb->destructor = wlan_ipa_uc_rt_debug_destructor;
1325 
1326 	if (wlan_ipa_send_to_nw_defer(iface_ctx, skb)) {
1327 		wlan_ipa_send_to_nw_queue(iface_ctx, skb);
1328 	} else {
1329 		if (ipa_ctx->send_to_nw)
1330 			ipa_ctx->send_to_nw(skb, iface_ctx->dev);
1331 
1332 		ipa_ctx->ipa_rx_net_send_count++;
1333 	}
1334 }
1335 
1336 /**
1337  * wlan_ipa_eapol_intrabss_fwd_check() - Check if eapol pkt intrabss fwd is
1338  *  allowed or not
1339  * @ipa_ctx: IPA global context
1340  * @vdev_id: vdev id
1341  * @nbuf: network buffer
1342  *
1343  * Return: true if intrabss fwd is allowed for eapol else false
1344  */
1345 static bool
1346 wlan_ipa_eapol_intrabss_fwd_check(struct wlan_ipa_priv *ipa_ctx,
1347 				  uint8_t vdev_id, qdf_nbuf_t nbuf)
1348 {
1349 	uint8_t *vdev_mac_addr;
1350 
1351 	vdev_mac_addr = cdp_get_vdev_mac_addr(ipa_ctx->dp_soc, vdev_id);
1352 
1353 	if (!vdev_mac_addr)
1354 		return false;
1355 
1356 	if (qdf_mem_cmp(qdf_nbuf_data(nbuf) + QDF_NBUF_DEST_MAC_OFFSET,
1357 			vdev_mac_addr, QDF_MAC_ADDR_SIZE))
1358 		return false;
1359 
1360 	return true;
1361 }
1362 
1363 #ifdef MDM_PLATFORM
1364 static inline void
1365 wlan_ipa_set_sap_client_auth(struct wlan_ipa_priv *ipa_ctx,
1366 			     const uint8_t *peer_mac,
1367 			     uint8_t is_authenticated)
1368 {
1369 	uint8_t idx;
1370 	struct ipa_uc_stas_map *sta_map;
1371 
1372 	for (idx = 0; idx < WLAN_IPA_MAX_STA_COUNT; idx++) {
1373 		sta_map = &ipa_ctx->assoc_stas_map[idx];
1374 		if (sta_map->is_reserved &&
1375 		    qdf_is_macaddr_equal(&sta_map->mac_addr,
1376 					 (struct qdf_mac_addr *)peer_mac)) {
1377 			sta_map->is_authenticated = is_authenticated;
1378 			break;
1379 		}
1380 	}
1381 }
1382 
1383 static inline uint8_t
1384 wlan_ipa_get_sap_client_auth(struct wlan_ipa_priv *ipa_ctx, uint8_t *peer_mac)
1385 {
1386 	uint8_t idx;
1387 	struct ipa_uc_stas_map *sta_map;
1388 
1389 	for (idx = 0; idx < WLAN_IPA_MAX_STA_COUNT; idx++) {
1390 		sta_map = &ipa_ctx->assoc_stas_map[idx];
1391 		if (sta_map->is_reserved &&
1392 		    qdf_is_macaddr_equal(&sta_map->mac_addr,
1393 					 (struct qdf_mac_addr *)peer_mac)) {
1394 			return sta_map->is_authenticated;
1395 		}
1396 	}
1397 
1398 	return false;
1399 }
1400 
1401 /**
1402  * wlan_ipa_check_peer_auth() - Check whether peer is authenticated or not
1403  * @dp_soc: soc handle
1404  * @peer_mac: peer mac address
1405  * @iface: wlan ipa iface context
1406  *
1407  * Return: true if peer is authenticated
1408  */
1409 #ifdef QCA_WIFI_QCN9224
1410 static inline bool
1411 wlan_ipa_check_peer_auth(ol_txrx_soc_handle dp_soc,
1412 			 uint8_t *peer_mac,
1413 			 struct wlan_ipa_iface_context *iface)
1414 {
1415 	uint8_t is_authenticated = false;
1416 	struct cdp_ast_entry_info ast_info = {0};
1417 
1418 	cdp_peer_get_ast_info_by_soc(dp_soc, peer_mac,
1419 				     &ast_info);
1420 	peer_mac = &ast_info.peer_mac_addr[0];
1421 	is_authenticated = wlan_ipa_get_peer_state(dp_soc,
1422 						   iface->session_id,
1423 						   peer_mac);
1424 
1425 	return is_authenticated;
1426 }
1427 #else
1428 static inline bool
1429 wlan_ipa_check_peer_auth(ol_txrx_soc_handle dp_soc,
1430 			 uint8_t *peer_mac,
1431 			 struct wlan_ipa_iface_context *iface)
1432 {
1433 	uint8_t is_authenticated = false;
1434 
1435 	is_authenticated = wlan_ipa_get_peer_state(dp_soc, iface->session_id,
1436 						   peer_mac);
1437 
1438 	return is_authenticated;
1439 }
1440 #endif
1441 
1442 #ifdef IPA_WDS_EASYMESH_FEATURE
1443 static inline uint8_t
1444 wlan_ipa_get_peer_auth_state(ol_txrx_soc_handle dp_soc, uint8_t *peer_mac,
1445 			     struct wlan_ipa_iface_context *iface)
1446 {
1447 	uint8_t is_authenticated = false;
1448 	struct cdp_ast_entry_info ast_info = {0};
1449 
1450 	if (ipa_is_wds_enabled()) {
1451 		cdp_peer_get_ast_info_by_soc(dp_soc, peer_mac,
1452 					     &ast_info);
1453 		peer_mac = &ast_info.peer_mac_addr[0];
1454 		is_authenticated = wlan_ipa_get_peer_state(dp_soc,
1455 							   iface->session_id,
1456 							   peer_mac);
1457 	} else {
1458 		is_authenticated = wlan_ipa_get_peer_state(dp_soc,
1459 							   iface->session_id,
1460 							   peer_mac);
1461 	}
1462 
1463 	return is_authenticated;
1464 }
1465 #else
1466 static inline uint8_t
1467 wlan_ipa_get_peer_auth_state(ol_txrx_soc_handle dp_soc, uint8_t *peer_mac,
1468 			     struct wlan_ipa_iface_context *iface)
1469 {
1470 
1471 	return wlan_ipa_check_peer_auth(dp_soc, peer_mac, iface);
1472 }
1473 #endif
1474 
1475 static inline bool
1476 wlan_ipa_is_peer_authenticated(ol_txrx_soc_handle dp_soc,
1477 			       struct wlan_ipa_iface_context *iface,
1478 			       uint8_t *peer_mac)
1479 {
1480 	uint8_t is_authenticated = false;
1481 
1482 	if (iface->device_mode == QDF_SAP_MODE) {
1483 		is_authenticated = wlan_ipa_get_sap_client_auth(iface->ipa_ctx,
1484 								peer_mac);
1485 		if (is_authenticated)
1486 			return is_authenticated;
1487 
1488 		is_authenticated = wlan_ipa_get_peer_auth_state(dp_soc,
1489 								peer_mac,
1490 								iface);
1491 
1492 		if (is_authenticated)
1493 			wlan_ipa_set_sap_client_auth(iface->ipa_ctx,
1494 						     peer_mac,
1495 						     true);
1496 
1497 	} else if (iface->device_mode == QDF_STA_MODE) {
1498 		is_authenticated = iface->is_authenticated;
1499 		if (is_authenticated)
1500 			return is_authenticated;
1501 		is_authenticated = wlan_ipa_get_peer_state(dp_soc,
1502 							   iface->session_id,
1503 							   peer_mac);
1504 		if (is_authenticated)
1505 			iface->is_authenticated = true;
1506 	}
1507 
1508 	return is_authenticated;
1509 }
1510 #else /* !MDM_PLATFORM */
1511 static inline void
1512 wlan_ipa_set_sap_client_auth(struct wlan_ipa_priv *ipa_ctx,
1513 			     const uint8_t *peer_mac,
1514 			     uint8_t is_authenticated)
1515 {}
1516 
1517 static inline bool
1518 wlan_ipa_is_peer_authenticated(ol_txrx_soc_handle dp_soc,
1519 			       struct wlan_ipa_iface_context *iface,
1520 			       uint8_t *peer_mac)
1521 {
1522 	uint8_t is_authenticated = 0;
1523 
1524 	is_authenticated = wlan_ipa_get_peer_state(dp_soc,
1525 						   iface->session_id,
1526 						   peer_mac);
1527 
1528 	return is_authenticated;
1529 }
1530 #endif /* MDM_PLATFORM */
1531 
1532 /**
1533  * __wlan_ipa_w2i_cb() - WLAN to IPA callback handler
1534  * @priv: pointer to private data registered with IPA (we register a
1535  *	pointer to the global IPA context)
1536  * @evt: the IPA event which triggered the callback
1537  * @data: data associated with the event
1538  *
1539  * Return: None
1540  */
1541 static void __wlan_ipa_w2i_cb(void *priv, qdf_ipa_dp_evt_type_t evt,
1542 			      unsigned long data)
1543 {
1544 	struct wlan_ipa_priv *ipa_ctx = NULL;
1545 	qdf_nbuf_t skb;
1546 	uint8_t iface_id;
1547 	uint8_t session_id = 0xff;
1548 	struct wlan_ipa_iface_context *iface_context;
1549 	bool is_eapol_wapi = false;
1550 	struct qdf_mac_addr peer_mac_addr = QDF_MAC_ADDR_ZERO_INIT;
1551 
1552 	ipa_ctx = (struct wlan_ipa_priv *)priv;
1553 	if (!ipa_ctx) {
1554 		if (evt == IPA_RECEIVE) {
1555 			skb = (qdf_nbuf_t)data;
1556 			dev_kfree_skb_any(skb);
1557 		}
1558 		return;
1559 	}
1560 
1561 	switch (evt) {
1562 	case IPA_RECEIVE:
1563 		skb = (qdf_nbuf_t) data;
1564 		if (wlan_ipa_uc_is_enabled(ipa_ctx->config)) {
1565 			session_id = (uint8_t)skb->cb[0];
1566 			iface_id = ipa_ctx->vdev_to_iface[session_id];
1567 			ipa_ctx->stats.num_rx_excep++;
1568 			qdf_nbuf_pull_head(skb, WLAN_IPA_UC_WLAN_CLD_HDR_LEN);
1569 		} else {
1570 			iface_id = WLAN_IPA_GET_IFACE_ID(skb->data);
1571 			qdf_nbuf_pull_head(skb, WLAN_IPA_WLAN_CLD_HDR_LEN);
1572 		}
1573 
1574 		if (iface_id >= WLAN_IPA_MAX_IFACE) {
1575 			ipa_err_rl("Invalid iface_id %u,session_id %x %x %x %x",
1576 				   iface_id, session_id, (uint8_t)skb->cb[1],
1577 				   (uint8_t)skb->cb[2], (uint8_t)skb->cb[3]);
1578 
1579 			if (qdf_nbuf_is_ipv4_eapol_pkt(skb)) {
1580 				ipa_err_rl("EAPOL pkt. Sending to NW!");
1581 				if (!wlan_ipa_send_sta_eapol_to_nw(
1582 						skb, ipa_ctx->pdev))
1583 					break;
1584 			}
1585 			ipa_err_rl("Pkt Dropped!");
1586 			ipa_ctx->ipa_rx_internal_drop_count++;
1587 			dev_kfree_skb_any(skb);
1588 			return;
1589 		}
1590 
1591 		iface_context = &ipa_ctx->iface_context[iface_id];
1592 		if (iface_context->session_id >= WLAN_IPA_MAX_SESSION) {
1593 			ipa_err_rl("session_id of iface_id %u is invalid:%d",
1594 				   iface_id, iface_context->session_id);
1595 			ipa_ctx->ipa_rx_internal_drop_count++;
1596 			dev_kfree_skb_any(skb);
1597 			return;
1598 		}
1599 		iface_context->stats.num_rx_ipa_excep++;
1600 
1601 		if (iface_context->device_mode == QDF_STA_MODE)
1602 			qdf_copy_macaddr(&peer_mac_addr, &iface_context->bssid);
1603 		else if (iface_context->device_mode == QDF_SAP_MODE)
1604 			qdf_mem_copy(&peer_mac_addr.bytes[0],
1605 				     qdf_nbuf_data(skb) +
1606 				     QDF_NBUF_SRC_MAC_OFFSET,
1607 				     QDF_MAC_ADDR_SIZE);
1608 
1609 		cdp_ipa_update_peer_rx_stats(ipa_ctx->dp_soc,
1610 					     iface_context->session_id,
1611 					     &peer_mac_addr.bytes[0],
1612 					     skb);
1613 		if (qdf_nbuf_is_ipv4_eapol_pkt(skb)) {
1614 			is_eapol_wapi = true;
1615 			if (iface_context->device_mode == QDF_SAP_MODE &&
1616 			    !wlan_ipa_eapol_intrabss_fwd_check(ipa_ctx,
1617 					      iface_context->session_id, skb)) {
1618 				ipa_err_rl("EAPOL intrabss fwd drop DA:" QDF_MAC_ADDR_FMT,
1619 					   QDF_MAC_ADDR_REF(qdf_nbuf_data(skb) +
1620 					   QDF_NBUF_DEST_MAC_OFFSET));
1621 				ipa_ctx->ipa_rx_internal_drop_count++;
1622 				dev_kfree_skb_any(skb);
1623 				return;
1624 			}
1625 		} else if (qdf_nbuf_is_ipv4_wapi_pkt(skb)) {
1626 			is_eapol_wapi = true;
1627 		}
1628 
1629 		/*
1630 		 * Check for peer authorized state before allowing
1631 		 * non-EAPOL/WAPI frames to be intrabss forwarded
1632 		 * or submitted to stack.
1633 		 */
1634 		if (!wlan_ipa_is_peer_authenticated(ipa_ctx->dp_soc,
1635 						    iface_context,
1636 						    &peer_mac_addr.bytes[0]) &&
1637 		    !is_eapol_wapi) {
1638 			ipa_err_rl("Non EAPOL/WAPI packet received when peer " QDF_MAC_ADDR_FMT " is unauthorized",
1639 				   QDF_MAC_ADDR_REF(peer_mac_addr.bytes));
1640 			ipa_ctx->ipa_rx_internal_drop_count++;
1641 			dev_kfree_skb_any(skb);
1642 			return;
1643 		}
1644 
1645 		/* Disable to forward Intra-BSS Rx packets when
1646 		 * ap_isolate=1 in hostapd.conf
1647 		 */
1648 		if (!ipa_ctx->disable_intrabss_fwd[iface_context->session_id] &&
1649 		    iface_context->device_mode == QDF_SAP_MODE) {
1650 			/*
1651 			 * When INTRA_BSS_FWD_OFFLOAD is enabled, FW will send
1652 			 * all Rx packets to IPA uC, which need to be forwarded
1653 			 * to other interface.
1654 			 * And, IPA driver will send back to WLAN host driver
1655 			 * through exception pipe with fw_desc field set by FW.
1656 			 * Here we are checking fw_desc field for FORWARD bit
1657 			 * set, and forward to Tx. Then copy to kernel stack
1658 			 * only when DISCARD bit is not set.
1659 			 */
1660 			if (WLAN_IPA_FORWARD_PKT_DISCARD ==
1661 			    wlan_ipa_rx_intrabss_fwd(ipa_ctx, iface_context,
1662 						     skb))
1663 				break;
1664 		} else {
1665 			ipa_debug_rl("Intra-BSS fwd disabled for session_id %u",
1666 				     iface_context->session_id);
1667 		}
1668 
1669 		wlan_ipa_send_skb_to_network(skb, iface_context);
1670 		break;
1671 
1672 	default:
1673 		ipa_err_rl("w2i cb wrong event: 0x%x", evt);
1674 		return;
1675 	}
1676 }
1677 
1678 #ifndef MDM_PLATFORM
1679 /**
1680  * wlan_ipa_w2i_cb() - SSR wrapper for __wlan_ipa_w2i_cb
1681  * @priv: pointer to private data registered with IPA (we register a
1682  *	pointer to the global IPA context)
1683  * @evt: the IPA event which triggered the callback
1684  * @data: data associated with the event
1685  *
1686  * Return: None
1687  */
1688 static void wlan_ipa_w2i_cb(void *priv, qdf_ipa_dp_evt_type_t evt,
1689 			    unsigned long data)
1690 {
1691 	struct qdf_op_sync *op_sync;
1692 
1693 	if (qdf_op_protect(&op_sync)) {
1694 		if (evt == IPA_RECEIVE) {
1695 			struct wlan_ipa_priv *ipa_ctx = priv;
1696 			qdf_nbuf_t skb = (qdf_nbuf_t)data;
1697 
1698 			ipa_ctx->ipa_rx_internal_drop_count++;
1699 			dev_kfree_skb_any(skb);
1700 		}
1701 
1702 		return;
1703 	}
1704 
1705 	__wlan_ipa_w2i_cb(priv, evt, data);
1706 
1707 	qdf_op_unprotect(op_sync);
1708 }
1709 #else /* MDM_PLATFORM */
1710 static void wlan_ipa_w2i_cb(void *priv, qdf_ipa_dp_evt_type_t evt,
1711 			    unsigned long data)
1712 {
1713 	__wlan_ipa_w2i_cb(priv, evt, data);
1714 }
1715 #endif /* MDM_PLATFORM */
1716 
1717 #if !defined(QCA_LL_TX_FLOW_CONTROL_V2) && !defined(QCA_IPA_LL_TX_FLOW_CONTROL)
1718 
1719 /**
1720  * __wlan_ipa_i2w_cb() - IPA to WLAN callback
1721  * @priv: pointer to private data registered with IPA (we register a
1722  *	pointer to the interface-specific IPA context)
1723  * @evt: the IPA event which triggered the callback
1724  * @data: data associated with the event
1725  *
1726  * Return: None
1727  */
1728 static void __wlan_ipa_i2w_cb(void *priv, qdf_ipa_dp_evt_type_t evt,
1729 			      unsigned long data)
1730 {
1731 	struct wlan_ipa_priv *ipa_ctx = NULL;
1732 	qdf_ipa_rx_data_t *ipa_tx_desc;
1733 	struct wlan_ipa_iface_context *iface_context;
1734 	qdf_nbuf_t skb;
1735 	struct wlan_ipa_pm_tx_cb *pm_tx_cb = NULL;
1736 
1737 	iface_context = (struct wlan_ipa_iface_context *)priv;
1738 	ipa_tx_desc = (qdf_ipa_rx_data_t *)data;
1739 	ipa_ctx = iface_context->ipa_ctx;
1740 
1741 	if (evt != IPA_RECEIVE) {
1742 		ipa_err_rl("Event is not IPA_RECEIVE");
1743 		ipa_free_skb(ipa_tx_desc);
1744 		iface_context->stats.num_tx_drop++;
1745 		return;
1746 	}
1747 
1748 	skb = QDF_IPA_RX_DATA_SKB(ipa_tx_desc);
1749 
1750 	/*
1751 	 * If PROD resource is not requested here then there may be cases where
1752 	 * IPA hardware may be clocked down because of not having proper
1753 	 * dependency graph between WLAN CONS and modem PROD pipes. Adding the
1754 	 * workaround to request PROD resource while data is going over CONS
1755 	 * pipe to prevent the IPA hardware clockdown.
1756 	 */
1757 	wlan_ipa_wdi_rm_request(ipa_ctx);
1758 
1759 	qdf_spin_lock_bh(&ipa_ctx->pm_lock);
1760 	/*
1761 	 * If host is still suspended then queue the packets and these will be
1762 	 * drained later when resume completes. When packet is arrived here and
1763 	 * host is suspended, this means that there is already resume is in
1764 	 * progress.
1765 	 */
1766 	if (ipa_ctx->suspended) {
1767 		qdf_mem_zero(skb->cb, sizeof(skb->cb));
1768 		pm_tx_cb = (struct wlan_ipa_pm_tx_cb *)skb->cb;
1769 		pm_tx_cb->iface_context = iface_context;
1770 		pm_tx_cb->ipa_tx_desc = ipa_tx_desc;
1771 		qdf_nbuf_queue_add(&ipa_ctx->pm_queue_head, skb);
1772 		ipa_ctx->stats.num_tx_queued++;
1773 
1774 		qdf_spin_unlock_bh(&ipa_ctx->pm_lock);
1775 		return;
1776 	}
1777 
1778 	qdf_spin_unlock_bh(&ipa_ctx->pm_lock);
1779 
1780 	/*
1781 	 * If we are here means, host is not suspended, wait for the work queue
1782 	 * to finish.
1783 	 */
1784 	qdf_flush_work(&ipa_ctx->pm_work);
1785 
1786 	return wlan_ipa_send_pkt_to_tl(iface_context, ipa_tx_desc);
1787 }
1788 
1789 /**
1790  * wlan_ipa_i2w_cb() - IPA to WLAN callback
1791  * @priv: pointer to private data registered with IPA (we register a
1792  *	pointer to the interface-specific IPA context)
1793  * @evt: the IPA event which triggered the callback
1794  * @data: data associated with the event
1795  *
1796  * Return: None
1797  */
1798 static void wlan_ipa_i2w_cb(void *priv, qdf_ipa_dp_evt_type_t evt,
1799 			    unsigned long data)
1800 {
1801 	struct qdf_op_sync *op_sync;
1802 
1803 	if (qdf_op_protect(&op_sync)) {
1804 		qdf_ipa_rx_data_t *ipa_tx_desc = (qdf_ipa_rx_data_t *)data;
1805 		struct wlan_ipa_iface_context *iface_context = priv;
1806 
1807 		ipa_free_skb(ipa_tx_desc);
1808 		iface_context->stats.num_tx_drop++;
1809 
1810 		return;
1811 	}
1812 
1813 	__wlan_ipa_i2w_cb(priv, evt, data);
1814 
1815 	qdf_op_unprotect(op_sync);
1816 }
1817 
1818 #else /* QCA_LL_TX_FLOW_CONTROL_V2 */
1819 
1820 /**
1821  * wlan_ipa_i2w_cb() - IPA to WLAN callback
1822  * @priv: pointer to private data registered with IPA (we register a
1823  *	pointer to the interface-specific IPA context)
1824  * @evt: the IPA event which triggered the callback
1825  * @data: data associated with the event
1826  *
1827  * Return: None
1828  */
1829 static void wlan_ipa_i2w_cb(void *priv, qdf_ipa_dp_evt_type_t evt,
1830 			    unsigned long data)
1831 {
1832 }
1833 
1834 #endif /* QCA_LL_TX_FLOW_CONTROL_V2 */
1835 
1836 QDF_STATUS wlan_ipa_suspend(struct wlan_ipa_priv *ipa_ctx)
1837 {
1838 	/*
1839 	 * Check if IPA is ready for suspend, If we are here means, there is
1840 	 * high chance that suspend would go through but just to avoid any race
1841 	 * condition after suspend started, these checks are conducted before
1842 	 * allowing to suspend.
1843 	 */
1844 	if (atomic_read(&ipa_ctx->tx_ref_cnt))
1845 		return QDF_STATUS_E_AGAIN;
1846 
1847 	if (!wlan_ipa_is_rm_released(ipa_ctx))
1848 		return QDF_STATUS_E_AGAIN;
1849 
1850 	qdf_spin_lock_bh(&ipa_ctx->pm_lock);
1851 	ipa_ctx->suspended = true;
1852 	qdf_spin_unlock_bh(&ipa_ctx->pm_lock);
1853 
1854 	if (ipa_ctx->config->ipa_force_voting &&
1855 	    !ipa_ctx->ipa_pipes_down)
1856 		wlan_ipa_set_perf_level(ipa_ctx,
1857 					ipa_ctx->config->bus_bw_high,
1858 					ipa_ctx->config->bus_bw_high);
1859 
1860 	return QDF_STATUS_SUCCESS;
1861 }
1862 
1863 QDF_STATUS wlan_ipa_resume(struct wlan_ipa_priv *ipa_ctx)
1864 {
1865 	qdf_sched_work(0, &ipa_ctx->pm_work);
1866 
1867 	qdf_spin_lock_bh(&ipa_ctx->pm_lock);
1868 	ipa_ctx->suspended = false;
1869 	qdf_spin_unlock_bh(&ipa_ctx->pm_lock);
1870 
1871 	return QDF_STATUS_SUCCESS;
1872 }
1873 
1874 QDF_STATUS wlan_ipa_uc_enable_pipes(struct wlan_ipa_priv *ipa_ctx)
1875 {
1876 	int result;
1877 	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
1878 
1879 	ipa_debug("enter");
1880 
1881 	qdf_spin_lock_bh(&ipa_ctx->enable_disable_lock);
1882 	if (ipa_ctx->pipes_enable_in_progress) {
1883 		ipa_warn("IPA Pipes Enable in progress");
1884 		qdf_spin_unlock_bh(&ipa_ctx->enable_disable_lock);
1885 		return QDF_STATUS_E_ALREADY;
1886 	}
1887 	ipa_ctx->pipes_enable_in_progress = true;
1888 	qdf_spin_unlock_bh(&ipa_ctx->enable_disable_lock);
1889 
1890 	if (qdf_atomic_read(&ipa_ctx->waiting_on_pending_tx))
1891 		wlan_ipa_reset_pending_tx_timer(ipa_ctx);
1892 
1893 	if (qdf_atomic_read(&ipa_ctx->pipes_disabled)) {
1894 		result = cdp_ipa_enable_pipes(ipa_ctx->dp_soc,
1895 					      ipa_ctx->dp_pdev_id,
1896 					      ipa_ctx->hdl);
1897 		if (result) {
1898 			ipa_err("Enable IPA WDI PIPE failed: ret=%d", result);
1899 			qdf_status = QDF_STATUS_E_FAILURE;
1900 			goto end;
1901 		}
1902 		qdf_atomic_set(&ipa_ctx->pipes_disabled, 0);
1903 	}
1904 
1905 	qdf_event_reset(&ipa_ctx->ipa_resource_comp);
1906 
1907 	if (qdf_atomic_read(&ipa_ctx->autonomy_disabled)) {
1908 		if (wlan_ipa_opt_wifi_dp_enabled()) {
1909 			/* Default packet routing is to HOST REO rings */
1910 			ipa_info("opt_dp: enable pipes. Do not enable autonomy");
1911 		} else {
1912 			cdp_ipa_enable_autonomy(ipa_ctx->dp_soc,
1913 						ipa_ctx->dp_pdev_id);
1914 			qdf_atomic_set(&ipa_ctx->autonomy_disabled, 0);
1915 		}
1916 	}
1917 end:
1918 	qdf_spin_lock_bh(&ipa_ctx->enable_disable_lock);
1919 	if (((!qdf_atomic_read(&ipa_ctx->autonomy_disabled)) ||
1920 	     wlan_ipa_opt_wifi_dp_enabled()) &&
1921 	    !qdf_atomic_read(&ipa_ctx->pipes_disabled))
1922 		ipa_ctx->ipa_pipes_down = false;
1923 
1924 	ipa_ctx->pipes_enable_in_progress = false;
1925 	qdf_spin_unlock_bh(&ipa_ctx->enable_disable_lock);
1926 
1927 	ipa_debug("exit: ipa_pipes_down=%d", ipa_ctx->ipa_pipes_down);
1928 	return qdf_status;
1929 }
1930 
1931 QDF_STATUS
1932 wlan_ipa_uc_disable_pipes(struct wlan_ipa_priv *ipa_ctx, bool force_disable)
1933 {
1934 	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
1935 
1936 	ipa_debug("enter: force_disable %u autonomy_disabled %u pipes_disabled %u",
1937 		  force_disable,
1938 		  qdf_atomic_read(&ipa_ctx->autonomy_disabled),
1939 		  qdf_atomic_read(&ipa_ctx->pipes_disabled));
1940 
1941 	qdf_spin_lock_bh(&ipa_ctx->enable_disable_lock);
1942 	if (ipa_ctx->ipa_pipes_down || ipa_ctx->pipes_down_in_progress) {
1943 		qdf_spin_unlock_bh(&ipa_ctx->enable_disable_lock);
1944 		ipa_info("IPA WDI Pipes are already deactivated");
1945 		ipa_info("pipes_down %d, pipes_down_in_progress %d",
1946 			 ipa_ctx->ipa_pipes_down,
1947 			 ipa_ctx->pipes_down_in_progress);
1948 		return QDF_STATUS_E_ALREADY;
1949 	}
1950 	ipa_ctx->pipes_down_in_progress = true;
1951 	qdf_spin_unlock_bh(&ipa_ctx->enable_disable_lock);
1952 
1953 
1954 	if (!qdf_atomic_read(&ipa_ctx->autonomy_disabled)) {
1955 		cdp_ipa_disable_autonomy(ipa_ctx->dp_soc,
1956 					 ipa_ctx->dp_pdev_id);
1957 		qdf_atomic_set(&ipa_ctx->autonomy_disabled, 1);
1958 	}
1959 
1960 	if (!qdf_atomic_read(&ipa_ctx->pipes_disabled)) {
1961 		if (!force_disable) {
1962 			wlan_ipa_set_pending_tx_timer(ipa_ctx);
1963 		} else {
1964 			qdf_status = cdp_ipa_disable_pipes(ipa_ctx->dp_soc,
1965 							   ipa_ctx->dp_pdev_id,
1966 							   ipa_ctx->hdl);
1967 			if (QDF_IS_STATUS_ERROR(qdf_status)) {
1968 				ipa_err("Disable IPA WDI PIPE failed: ret=%u",
1969 					qdf_status);
1970 				qdf_status = QDF_STATUS_E_FAILURE;
1971 				goto end;
1972 			}
1973 			qdf_atomic_set(&ipa_ctx->pipes_disabled, 1);
1974 			wlan_ipa_reset_pending_tx_timer(ipa_ctx);
1975 		}
1976 	}
1977 
1978 end:
1979 	qdf_spin_lock_bh(&ipa_ctx->enable_disable_lock);
1980 	if (qdf_atomic_read(&ipa_ctx->pipes_disabled) &&
1981 	    qdf_atomic_read(&ipa_ctx->autonomy_disabled)) {
1982 		ipa_ctx->ipa_pipes_down = true;
1983 	}
1984 	ipa_ctx->pipes_down_in_progress = false;
1985 	qdf_spin_unlock_bh(&ipa_ctx->enable_disable_lock);
1986 
1987 	ipa_debug("exit: ipa_pipes_down %u autonomy_disabled %u pipes_disabled %u",
1988 		  ipa_ctx->ipa_pipes_down,
1989 		  qdf_atomic_read(&ipa_ctx->autonomy_disabled),
1990 		  qdf_atomic_read(&ipa_ctx->pipes_disabled));
1991 	return qdf_status;
1992 }
1993 
1994 /**
1995  * wlan_ipa_uc_find_add_assoc_sta() - Find associated station
1996  * @ipa_ctx: Global IPA IPA context
1997  * @sta_add: Should station be added
1998  * @mac_addr: mac address of station being queried
1999  *
2000  * Return: true if the station was found
2001  */
2002 static bool wlan_ipa_uc_find_add_assoc_sta(struct wlan_ipa_priv *ipa_ctx,
2003 					   bool sta_add,
2004 					   const uint8_t *mac_addr)
2005 {
2006 	bool sta_found = false;
2007 	uint8_t idx;
2008 
2009 	for (idx = 0; idx < WLAN_IPA_MAX_STA_COUNT; idx++) {
2010 		if ((ipa_ctx->assoc_stas_map[idx].is_reserved) &&
2011 		    (qdf_is_macaddr_equal(
2012 			&ipa_ctx->assoc_stas_map[idx].mac_addr,
2013 			(struct qdf_mac_addr *)mac_addr))) {
2014 			sta_found = true;
2015 			break;
2016 		}
2017 	}
2018 	if (sta_add && sta_found) {
2019 		ipa_err("STA already exist, cannot add: " QDF_MAC_ADDR_FMT,
2020 			QDF_MAC_ADDR_REF(mac_addr));
2021 		return sta_found;
2022 	}
2023 	if (sta_add) {
2024 		for (idx = 0; idx < WLAN_IPA_MAX_STA_COUNT; idx++) {
2025 			if (!ipa_ctx->assoc_stas_map[idx].is_reserved) {
2026 				ipa_ctx->assoc_stas_map[idx].is_reserved = true;
2027 				qdf_mem_copy(&ipa_ctx->assoc_stas_map[idx].
2028 					     mac_addr, mac_addr,
2029 					     QDF_NET_ETH_LEN);
2030 				return sta_found;
2031 			}
2032 		}
2033 	}
2034 	if (!sta_add && !sta_found) {
2035 		ipa_info("STA does not exist, cannot delete: "
2036 			 QDF_MAC_ADDR_FMT, QDF_MAC_ADDR_REF(mac_addr));
2037 		return sta_found;
2038 	}
2039 	if (!sta_add) {
2040 		for (idx = 0; idx < WLAN_IPA_MAX_STA_COUNT; idx++) {
2041 			if ((ipa_ctx->assoc_stas_map[idx].is_reserved) &&
2042 			    (qdf_is_macaddr_equal(
2043 				&ipa_ctx->assoc_stas_map[idx].mac_addr,
2044 				(struct qdf_mac_addr *)mac_addr))) {
2045 				ipa_ctx->assoc_stas_map[idx].is_reserved =
2046 					false;
2047 				qdf_mem_zero(
2048 					&ipa_ctx->assoc_stas_map[idx].mac_addr,
2049 					QDF_NET_ETH_LEN);
2050 				return sta_found;
2051 			}
2052 		}
2053 	}
2054 
2055 	return sta_found;
2056 }
2057 
2058 /**
2059  * wlan_ipa_get_ifaceid() - Get IPA context interface ID
2060  * @ipa_ctx: IPA context
2061  * @session_id: Session ID
2062  *
2063  * Return: None
2064  */
2065 static int wlan_ipa_get_ifaceid(struct wlan_ipa_priv *ipa_ctx,
2066 				uint8_t session_id)
2067 {
2068 	struct wlan_ipa_iface_context *iface_ctx;
2069 	int i;
2070 
2071 	for (i = 0; i < WLAN_IPA_MAX_IFACE; i++) {
2072 		iface_ctx = &ipa_ctx->iface_context[i];
2073 		if (iface_ctx->session_id == session_id)
2074 			break;
2075 	}
2076 
2077 	return i;
2078 }
2079 
2080 /**
2081  * wlan_ipa_cleanup_iface() - Cleanup IPA on a given interface
2082  * @iface_context: interface-specific IPA context
2083  * @mac_addr: MAC address
2084  *
2085  * Return: None
2086  */
2087 static void wlan_ipa_cleanup_iface(struct wlan_ipa_iface_context *iface_context,
2088 				   const uint8_t *mac_addr)
2089 {
2090 	struct wlan_ipa_priv *ipa_ctx = iface_context->ipa_ctx;
2091 
2092 	ipa_debug("enter");
2093 	ipa_err("net:%pK mode:%d MAC:"QDF_MAC_ADDR_FMT" id:%d",
2094 		iface_context->dev, iface_context->device_mode,
2095 		QDF_MAC_ADDR_REF(mac_addr), iface_context->session_id);
2096 
2097 	if (iface_context->session_id == WLAN_IPA_MAX_SESSION)
2098 		return;
2099 
2100 	if (mac_addr && qdf_mem_cmp(iface_context->mac_addr,
2101 				    mac_addr, QDF_MAC_ADDR_SIZE)) {
2102 		ipa_err("MAC mismatch "QDF_MAC_ADDR_FMT":"QDF_MAC_ADDR_FMT"",
2103 			QDF_MAC_ADDR_REF(mac_addr),
2104 			QDF_MAC_ADDR_REF(iface_context->mac_addr));
2105 	}
2106 
2107 	if (cdp_ipa_cleanup_iface(ipa_ctx->dp_soc,
2108 				  iface_context->dev->name,
2109 				  wlan_ipa_is_ipv6_enabled(ipa_ctx->config),
2110 				  ipa_ctx->hdl)) {
2111 		ipa_err("ipa_cleanup_iface failed");
2112 	}
2113 
2114 	if (iface_context->device_mode == QDF_SAP_MODE)
2115 		ipa_ctx->num_sap_connected--;
2116 
2117 	qdf_spin_lock_bh(&iface_context->interface_lock);
2118 	if (qdf_atomic_read(&iface_context->disconn_count) ==
2119 			qdf_atomic_read(&iface_context->conn_count) - 1) {
2120 		qdf_atomic_inc(&iface_context->disconn_count);
2121 	} else {
2122 		ipa_err("connect/disconnect out of sync");
2123 		QDF_BUG(0);
2124 	}
2125 
2126 	iface_context->is_authenticated = false;
2127 	iface_context->dev = NULL;
2128 	iface_context->device_mode = QDF_MAX_NO_OF_MODE;
2129 	iface_context->session_id = WLAN_IPA_MAX_SESSION;
2130 	qdf_mem_set(iface_context->mac_addr, QDF_MAC_ADDR_SIZE, 0);
2131 	qdf_spin_unlock_bh(&iface_context->interface_lock);
2132 	iface_context->ifa_address = 0;
2133 	qdf_zero_macaddr(&iface_context->bssid);
2134 	if (!iface_context->ipa_ctx->num_iface) {
2135 		ipa_err("NUM INTF 0, Invalid");
2136 		QDF_ASSERT(0);
2137 	}
2138 	iface_context->ipa_ctx->num_iface--;
2139 	ipa_debug("exit: num_iface=%d", iface_context->ipa_ctx->num_iface);
2140 }
2141 
2142 #if !defined(QCA_LL_TX_FLOW_CONTROL_V2) && !defined(QCA_IPA_LL_TX_FLOW_CONTROL)
2143 
2144 /**
2145  * wlan_ipa_nbuf_cb() - IPA TX complete callback
2146  * @skb: packet buffer which was transmitted
2147  *
2148  * Return: None
2149  */
2150 static void wlan_ipa_nbuf_cb(qdf_nbuf_t skb)
2151 {
2152 	struct wlan_ipa_priv *ipa_ctx = gp_ipa;
2153 	qdf_ipa_rx_data_t *ipa_tx_desc;
2154 	struct wlan_ipa_tx_desc *tx_desc;
2155 	uint16_t id;
2156 	struct wlan_objmgr_pdev *pdev;
2157 	struct wlan_objmgr_psoc *psoc;
2158 	qdf_device_t osdev;
2159 
2160 	if (!qdf_nbuf_ipa_owned_get(skb)) {
2161 		dev_kfree_skb_any(skb);
2162 		return;
2163 	}
2164 
2165 	if (!ipa_ctx)
2166 		return;
2167 	pdev = ipa_ctx->pdev;
2168 	psoc = wlan_pdev_get_psoc(pdev);
2169 	osdev = wlan_psoc_get_qdf_dev(psoc);
2170 
2171 	if (osdev && qdf_mem_smmu_s1_enabled(osdev)) {
2172 		if (wlan_ipa_uc_sta_is_enabled(ipa_ctx->config)) {
2173 			qdf_dma_addr_t paddr = QDF_NBUF_CB_PADDR(skb);
2174 
2175 			qdf_nbuf_mapped_paddr_set(skb,
2176 						  paddr -
2177 						  WLAN_IPA_WLAN_FRAG_HEADER -
2178 						  WLAN_IPA_WLAN_IPA_HEADER);
2179 		}
2180 
2181 		qdf_nbuf_unmap(osdev, skb, QDF_DMA_TO_DEVICE);
2182 	}
2183 
2184 	/* Get Tx desc pointer from SKB CB */
2185 	id = qdf_nbuf_ipa_priv_get(skb);
2186 	tx_desc = &ipa_ctx->tx_desc_pool[id];
2187 	ipa_tx_desc = tx_desc->ipa_tx_desc_ptr;
2188 
2189 	/* Return Tx Desc to IPA */
2190 	qdf_ipa_free_skb(ipa_tx_desc);
2191 
2192 	/* Return to free tx desc list */
2193 	qdf_spin_lock_bh(&ipa_ctx->q_lock);
2194 	tx_desc->ipa_tx_desc_ptr = NULL;
2195 	qdf_list_insert_back(&ipa_ctx->tx_desc_free_list, &tx_desc->node);
2196 	ipa_ctx->stats.num_tx_desc_q_cnt--;
2197 	qdf_spin_unlock_bh(&ipa_ctx->q_lock);
2198 
2199 	ipa_ctx->stats.num_tx_comp_cnt++;
2200 
2201 	qdf_atomic_dec(&ipa_ctx->tx_ref_cnt);
2202 
2203 	wlan_ipa_wdi_rm_try_release(ipa_ctx);
2204 }
2205 
2206 #else /* QCA_LL_TX_FLOW_CONTROL_V2 */
2207 
2208 /**
2209  * wlan_ipa_nbuf_cb() - IPA TX complete callback
2210  * @skb: packet buffer which was transmitted
2211  *
2212  * Return: None
2213  */
2214 static void wlan_ipa_nbuf_cb(qdf_nbuf_t skb)
2215 {
2216 	dev_kfree_skb_any(skb);
2217 }
2218 
2219 #endif /* QCA_LL_TX_FLOW_CONTROL_V2 */
2220 
2221 #ifdef IPA_WDI3_TX_TWO_PIPES
2222 #define WLAN_IPA_SESSION_ID_SHIFT 1
2223 static uint8_t wlan_ipa_set_session_id(uint8_t session_id, bool is_2g_iface)
2224 {
2225 	return (session_id << WLAN_IPA_SESSION_ID_SHIFT) | is_2g_iface;
2226 }
2227 #else
2228 static uint8_t wlan_ipa_set_session_id(uint8_t session_id, bool is_2g_iface)
2229 {
2230 	return session_id;
2231 }
2232 #endif
2233 
2234 /**
2235  * wlan_ipa_setup_iface() - Setup IPA on a given interface
2236  * @ipa_ctx: IPA IPA global context
2237  * @net_dev: Interface net device
2238  * @device_mode: Net interface device mode
2239  * @session_id: Session ID
2240  * @mac_addr: MAC address associated with the event
2241  * @is_2g_iface: true if Net interface is operating on 2G band, otherwise false
2242  *
2243  * Return: QDF STATUS
2244  */
2245 static QDF_STATUS wlan_ipa_setup_iface(struct wlan_ipa_priv *ipa_ctx,
2246 				       qdf_netdev_t net_dev,
2247 				       uint8_t device_mode,
2248 				       uint8_t session_id,
2249 				       const uint8_t *mac_addr,
2250 				       bool is_2g_iface)
2251 {
2252 	struct wlan_ipa_iface_context *iface_context = NULL;
2253 	int i;
2254 	QDF_STATUS status;
2255 
2256 	ipa_err("net:%pK mode:%d MAC:"QDF_MAC_ADDR_FMT" id:%d",
2257 		net_dev, device_mode, QDF_MAC_ADDR_REF(mac_addr), session_id);
2258 
2259 	for (i = 0; i < WLAN_IPA_MAX_IFACE; i++) {
2260 		iface_context = &(ipa_ctx->iface_context[i]);
2261 		if (iface_context->dev == net_dev) {
2262 			if (iface_context->device_mode == device_mode) {
2263 				/**
2264 				 * Lower layer may send multiple START_BSS_EVENT
2265 				 * in DFS mode or during channel change.
2266 				 * Since these indications are sent by lower
2267 				 * layer as SAP updates and IPA doesn't have to
2268 				 * do anything for these updates so ignoring!
2269 				 */
2270 				if (device_mode == QDF_SAP_MODE) {
2271 					ipa_debug("found iface %u device_mode %u",
2272 						  i, device_mode);
2273 					return QDF_STATUS_SUCCESS;
2274 				} else if (device_mode == QDF_STA_MODE &&
2275 					   qdf_mem_cmp(
2276 						   iface_context->mac_addr,
2277 						   mac_addr,
2278 						   QDF_MAC_ADDR_SIZE) == 0) {
2279 					ipa_err("same STA iface already connected");
2280 				}
2281 
2282 			}
2283 
2284 			ipa_err("Obsolete iface %u found, device_mode %u, will remove it.",
2285 				i, iface_context->device_mode);
2286 			wlan_ipa_cleanup_iface(iface_context, NULL);
2287 		} else if (iface_context->session_id == session_id) {
2288 			ipa_err("Obsolete iface %u found, net_dev %pK, will remove it.",
2289 				i, iface_context->dev);
2290 			wlan_ipa_cleanup_iface(iface_context, NULL);
2291 		}
2292 	}
2293 
2294 	if (WLAN_IPA_MAX_IFACE == ipa_ctx->num_iface) {
2295 		ipa_err("Max interface reached %d", WLAN_IPA_MAX_IFACE);
2296 		status = QDF_STATUS_E_NOMEM;
2297 		iface_context = NULL;
2298 		QDF_ASSERT(0);
2299 		goto end;
2300 	}
2301 
2302 	for (i = 0; i < WLAN_IPA_MAX_IFACE; i++) {
2303 		if (ipa_ctx->iface_context[i].session_id ==
2304 						WLAN_IPA_MAX_SESSION) {
2305 			iface_context = &(ipa_ctx->iface_context[i]);
2306 			break;
2307 		}
2308 	}
2309 
2310 	if (!iface_context) {
2311 		ipa_err("All the IPA interfaces are in use");
2312 		status = QDF_STATUS_E_NOMEM;
2313 		QDF_ASSERT(0);
2314 		goto end;
2315 	}
2316 
2317 	qdf_spin_lock_bh(&iface_context->interface_lock);
2318 	if (qdf_atomic_read(&iface_context->conn_count) ==
2319 			qdf_atomic_read(&iface_context->disconn_count)) {
2320 		qdf_atomic_inc(&iface_context->conn_count);
2321 	} else {
2322 		ipa_err("connect/disconnect out of sync");
2323 		QDF_BUG(0);
2324 	}
2325 
2326 	iface_context->dev = net_dev;
2327 	iface_context->device_mode = device_mode;
2328 	iface_context->session_id = session_id;
2329 	qdf_mem_copy(iface_context->mac_addr, mac_addr, QDF_MAC_ADDR_SIZE);
2330 	qdf_spin_unlock_bh(&iface_context->interface_lock);
2331 
2332 	status = cdp_ipa_setup_iface(ipa_ctx->dp_soc, net_dev->name,
2333 				     (uint8_t *)net_dev->dev_addr,
2334 				     iface_context->prod_client,
2335 				     iface_context->cons_client,
2336 				     wlan_ipa_set_session_id(session_id,
2337 							     is_2g_iface),
2338 				     wlan_ipa_is_ipv6_enabled(ipa_ctx->config),
2339 				     ipa_ctx->hdl);
2340 	if (status != QDF_STATUS_SUCCESS)
2341 		goto end;
2342 
2343 	/* Register IPA Tx desc free callback */
2344 	qdf_nbuf_reg_free_cb(wlan_ipa_nbuf_cb);
2345 
2346 	ipa_ctx->num_iface++;
2347 
2348 	if (device_mode == QDF_SAP_MODE)
2349 		ipa_ctx->num_sap_connected++;
2350 
2351 	ipa_debug("exit: num_iface=%d", ipa_ctx->num_iface);
2352 
2353 	return status;
2354 
2355 end:
2356 	if (iface_context)
2357 		wlan_ipa_cleanup_iface(iface_context, mac_addr);
2358 
2359 	return status;
2360 }
2361 
2362 #if defined(QCA_WIFI_QCA6290) || defined(QCA_WIFI_QCA6390) || \
2363     defined(QCA_WIFI_QCA6490) || defined(QCA_WIFI_QCA6750) || \
2364     defined(QCA_WIFI_WCN7850) || defined(QCA_WIFI_QCN9000) || \
2365     defined(QCA_WIFI_KIWI) || defined(QCA_WIFI_KIWI_V2)    || \
2366     defined(QCA_WIFI_QCN9224)
2367 
2368 #if defined(QCA_CONFIG_RPS) && !defined(MDM_PLATFORM)
2369 /**
2370  * ipa_set_rps(): Enable/disable RPS for all interfaces of specific mode
2371  * @ipa_ctx: IPA context
2372  * @mode: mode of interface for which RPS needs to be enabled
2373  * @enable: Set true to enable RPS
2374  *
2375  * Return: None
2376  */
2377 static void ipa_set_rps(struct wlan_ipa_priv *ipa_ctx, enum QDF_OPMODE mode,
2378 			bool enable)
2379 {
2380 	struct wlan_ipa_iface_context *iface_ctx;
2381 	wlan_ipa_rps_enable cb = ipa_ctx->rps_enable;
2382 	int i;
2383 
2384 	if (!cb)
2385 		return;
2386 
2387 	for (i = 0; i < WLAN_IPA_MAX_IFACE; i++) {
2388 		iface_ctx = &ipa_ctx->iface_context[i];
2389 		if (iface_ctx->device_mode == mode)
2390 			cb(iface_ctx->session_id, enable);
2391 	}
2392 }
2393 
2394 /**
2395  * wlan_ipa_uc_handle_first_con() - Handle first uC IPA connection
2396  * @ipa_ctx: IPA context
2397  *
2398  * Return: QDF STATUS
2399  */
2400 static QDF_STATUS wlan_ipa_uc_handle_first_con(struct wlan_ipa_priv *ipa_ctx)
2401 {
2402 	ipa_debug("enter");
2403 
2404 	if (qdf_ipa_get_lan_rx_napi() && (ipa_ctx->num_sap_connected > 1)) {
2405 		ipa_debug("Multiple SAP connected. Not enabling pipes. Exit");
2406 		return QDF_STATUS_E_PERM;
2407 	}
2408 
2409 	if (qdf_ipa_get_lan_rx_napi() && ipa_ctx->sta_connected)
2410 		ipa_set_rps(ipa_ctx, QDF_STA_MODE, true);
2411 
2412 	if (wlan_ipa_uc_enable_pipes(ipa_ctx) != QDF_STATUS_SUCCESS) {
2413 		ipa_err("IPA WDI Pipe activation failed");
2414 		return QDF_STATUS_E_BUSY;
2415 	}
2416 
2417 	ipa_debug("exit");
2418 
2419 	return QDF_STATUS_SUCCESS;
2420 }
2421 
2422 static
2423 void wlan_ipa_uc_handle_last_discon(struct wlan_ipa_priv *ipa_ctx,
2424 				    bool force_disable)
2425 {
2426 	ipa_debug("enter");
2427 
2428 	wlan_ipa_uc_disable_pipes(ipa_ctx, force_disable);
2429 
2430 	if (qdf_ipa_get_lan_rx_napi() && ipa_ctx->sta_connected)
2431 		ipa_set_rps(ipa_ctx, QDF_STA_MODE, false);
2432 
2433 	ipa_debug("exit: IPA WDI Pipes deactivated");
2434 }
2435 #else
2436 static QDF_STATUS wlan_ipa_uc_handle_first_con(struct wlan_ipa_priv *ipa_ctx)
2437 {
2438 	ipa_debug("enter");
2439 
2440 	if (wlan_ipa_uc_enable_pipes(ipa_ctx) != QDF_STATUS_SUCCESS) {
2441 		ipa_err("IPA WDI Pipe activation failed");
2442 		return QDF_STATUS_E_BUSY;
2443 	}
2444 
2445 	ipa_debug("exit");
2446 
2447 	return QDF_STATUS_SUCCESS;
2448 }
2449 
2450 static
2451 void wlan_ipa_uc_handle_last_discon(struct wlan_ipa_priv *ipa_ctx,
2452 				    bool force_disable)
2453 {
2454 	ipa_debug("enter");
2455 
2456 	wlan_ipa_uc_disable_pipes(ipa_ctx, force_disable);
2457 
2458 	ipa_debug("exit: IPA WDI Pipes deactivated");
2459 }
2460 #endif
2461 
2462 bool wlan_ipa_is_fw_wdi_activated(struct wlan_ipa_priv *ipa_ctx)
2463 {
2464 	return !ipa_ctx->ipa_pipes_down;
2465 }
2466 
2467 /* Time(ms) to wait for pending TX comps after last SAP client disconnects */
2468 #define WLAN_IPA_TX_PENDING_TIMEOUT_MS 15000
2469 
2470 static void wlan_ipa_set_pending_tx_timer(struct wlan_ipa_priv *ipa_ctx)
2471 {
2472 	ipa_ctx->pending_tx_start_ticks = qdf_system_ticks();
2473 	qdf_atomic_set(&ipa_ctx->waiting_on_pending_tx, 1);
2474 	ipa_info("done. pending_tx_start_ticks %llu wait_on_pending %u",
2475 		 ipa_ctx->pending_tx_start_ticks,
2476 		 qdf_atomic_read(&ipa_ctx->waiting_on_pending_tx));
2477 }
2478 
2479 bool wlan_ipa_is_tx_pending(struct wlan_ipa_priv *ipa_ctx)
2480 {
2481 	bool ret = false;
2482 	uint64_t diff_ms = 0;
2483 	uint64_t current_ticks = 0;
2484 
2485 	if (!ipa_ctx) {
2486 		ipa_err("IPA private context is NULL");
2487 		return false;
2488 	}
2489 
2490 	if (!qdf_atomic_read(&ipa_ctx->waiting_on_pending_tx)) {
2491 		ipa_debug("nothing pending");
2492 		return false;
2493 	}
2494 
2495 	current_ticks = qdf_system_ticks();
2496 
2497 	diff_ms = qdf_system_ticks_to_msecs(current_ticks -
2498 					    ipa_ctx->pending_tx_start_ticks);
2499 
2500 	if (diff_ms < WLAN_IPA_TX_PENDING_TIMEOUT_MS) {
2501 		ret = true;
2502 	} else {
2503 		ipa_debug("disabling pipes");
2504 		wlan_ipa_uc_disable_pipes(ipa_ctx, true);
2505 	}
2506 
2507 	ipa_debug("diff_ms %llu pending_tx_start_ticks %llu current_ticks %llu wait_on_pending %u",
2508 		  diff_ms, ipa_ctx->pending_tx_start_ticks, current_ticks,
2509 		  qdf_atomic_read(&ipa_ctx->waiting_on_pending_tx));
2510 
2511 	return ret;
2512 }
2513 
2514 static void wlan_ipa_reset_pending_tx_timer(struct wlan_ipa_priv *ipa_ctx)
2515 {
2516 	ipa_ctx->pending_tx_start_ticks = 0;
2517 	qdf_atomic_set(&ipa_ctx->waiting_on_pending_tx, 0);
2518 	ipa_info("done");
2519 }
2520 
2521 #else
2522 
2523 /**
2524  * wlan_ipa_uc_handle_first_con() - Handle first uC IPA connection
2525  * @ipa_ctx: IPA context
2526  *
2527  * Return: QDF STATUS
2528  */
2529 static QDF_STATUS wlan_ipa_uc_handle_first_con(struct wlan_ipa_priv *ipa_ctx)
2530 {
2531 	ipa_debug("enter");
2532 
2533 	ipa_ctx->activated_fw_pipe = 0;
2534 	ipa_ctx->resource_loading = true;
2535 
2536 	/* If RM feature enabled
2537 	 * Request PROD Resource first
2538 	 * PROD resource may return sync or async manners
2539 	 */
2540 	if (wlan_ipa_is_rm_enabled(ipa_ctx->config)) {
2541 		if (!wlan_ipa_wdi_rm_request_resource(ipa_ctx,
2542 						IPA_RM_RESOURCE_WLAN_PROD)) {
2543 			/* RM PROD request sync return
2544 			 * enable pipe immediately
2545 			 */
2546 			if (wlan_ipa_uc_enable_pipes(ipa_ctx)) {
2547 				ipa_err("IPA WDI Pipe activation failed");
2548 				ipa_ctx->resource_loading = false;
2549 				return QDF_STATUS_E_BUSY;
2550 			}
2551 		} else {
2552 			ipa_err("IPA WDI Pipe activation deferred");
2553 		}
2554 	} else {
2555 		/* RM Disabled
2556 		 * Just enabled all the PIPEs
2557 		 */
2558 		if (wlan_ipa_uc_enable_pipes(ipa_ctx)) {
2559 			ipa_err("IPA WDI Pipe activation failed");
2560 			ipa_ctx->resource_loading = false;
2561 			return QDF_STATUS_E_BUSY;
2562 		}
2563 		ipa_ctx->resource_loading = false;
2564 	}
2565 
2566 	ipa_debug("exit");
2567 
2568 	return QDF_STATUS_SUCCESS;
2569 }
2570 
2571 /**
2572  * wlan_ipa_uc_handle_last_discon() - Handle last uC IPA disconnection
2573  * @ipa_ctx: IPA context
2574  * @force_disable: force IPA pipes disablement
2575  *
2576  * Return: None
2577  */
2578 static
2579 void wlan_ipa_uc_handle_last_discon(struct wlan_ipa_priv *ipa_ctx,
2580 				    bool force_disable)
2581 {
2582 	ipa_debug("enter");
2583 
2584 	ipa_ctx->resource_unloading = true;
2585 	qdf_event_reset(&ipa_ctx->ipa_resource_comp);
2586 	ipa_info("Disable FW RX PIPE");
2587 	cdp_ipa_set_active(ipa_ctx->dp_soc, ipa_ctx->dp_pdev_id, false, false);
2588 
2589 	ipa_debug("exit: IPA WDI Pipes deactivated");
2590 }
2591 
2592 bool wlan_ipa_is_fw_wdi_activated(struct wlan_ipa_priv *ipa_ctx)
2593 {
2594 	return (WLAN_IPA_UC_NUM_WDI_PIPE == ipa_ctx->activated_fw_pipe);
2595 }
2596 
2597 static inline
2598 void wlan_ipa_set_pending_tx_timer(struct wlan_ipa_priv *ipa_ctx)
2599 {
2600 }
2601 
2602 bool wlan_ipa_is_tx_pending(struct wlan_ipa_priv *ipa_ctx)
2603 {
2604 	return false;
2605 }
2606 
2607 static inline
2608 void wlan_ipa_reset_pending_tx_timer(struct wlan_ipa_priv *ipa_ctx)
2609 {
2610 }
2611 
2612 #endif
2613 
2614 static inline
2615 bool wlan_sap_no_client_connected(struct wlan_ipa_priv *ipa_ctx)
2616 {
2617 	return !(ipa_ctx->sap_num_connected_sta);
2618 }
2619 
2620 static inline
2621 bool wlan_sta_is_connected(struct wlan_ipa_priv *ipa_ctx)
2622 {
2623 	return ipa_ctx->sta_connected;
2624 }
2625 
2626 static inline
2627 bool wlan_ipa_uc_is_loaded(struct wlan_ipa_priv *ipa_ctx)
2628 {
2629 	return ipa_ctx->uc_loaded;
2630 }
2631 
2632 #ifdef INTRA_BSS_FWD_OFFLOAD
2633 /**
2634  * wlan_ipa_intrabss_enable_disable() - wdi intrabss enable/disable notify to fw
2635  * @ipa_ctx: global IPA context
2636  * @session_id: Session Id
2637  * @enable: intrabss enable or disable
2638  *
2639  * Return: none
2640  */
2641 static void wlan_ipa_intrabss_enable_disable(struct wlan_ipa_priv *ipa_ctx,
2642 					     uint8_t session_id,
2643 					     bool enable)
2644 {
2645 	struct ipa_intrabss_control_params intrabss_req = {0};
2646 	uint32_t intra_bss_fwd = 0;
2647 
2648 	if (!enable || ipa_ctx->disable_intrabss_fwd[session_id]) {
2649 		ipa_debug("%s: ipa_offload->enable=%d, rx_fwd_disabled=%d",
2650 			  __func__, enable,
2651 			  ipa_ctx->disable_intrabss_fwd[session_id]);
2652 		intra_bss_fwd = 1;
2653 	}
2654 
2655 	intrabss_req.vdev_id = session_id;
2656 	intrabss_req.enable = intra_bss_fwd;
2657 
2658 	if (QDF_STATUS_SUCCESS !=
2659 	    ipa_send_intrabss_enable_disable(ipa_ctx->pdev, &intrabss_req)) {
2660 		ipa_err("intrabss offload vdev_id=%d, enable=%d failure",
2661 			session_id, intra_bss_fwd);
2662 	}
2663 }
2664 #else
2665 static inline
2666 void wlan_ipa_intrabss_enable_disable(struct wlan_ipa_priv *ipa_ctx,
2667 				      uint8_t session_id,
2668 				      bool enable)
2669 {}
2670 #endif
2671 
2672 /**
2673  * wlan_ipa_uc_offload_enable_disable() - wdi enable/disable notify to fw
2674  * @ipa_ctx: global IPA context
2675  * @offload_type: MCC or SCC
2676  * @session_id: Session Id
2677  * @enable: TX offload enable or disable
2678  *
2679  * Return: none
2680  */
2681 static void wlan_ipa_uc_offload_enable_disable(struct wlan_ipa_priv *ipa_ctx,
2682 					       uint32_t offload_type,
2683 					       uint8_t session_id,
2684 					       bool enable)
2685 {
2686 
2687 	struct ipa_uc_offload_control_params req = {0};
2688 
2689 	if (session_id >= WLAN_IPA_MAX_SESSION) {
2690 		ipa_err("invalid session id: %d", session_id);
2691 		return;
2692 	}
2693 
2694 	if (enable == ipa_ctx->vdev_offload_enabled[session_id]) {
2695 		ipa_info("IPA offload status is already set");
2696 		ipa_info("offload_type=%d, vdev_id=%d, enable=%d",
2697 			 offload_type, session_id, enable);
2698 		return;
2699 	}
2700 
2701 	ipa_info("offload_type=%d, session_id=%d, enable=%d",
2702 		 offload_type, session_id, enable);
2703 
2704 	req.offload_type = offload_type;
2705 	req.vdev_id = session_id;
2706 	req.enable = enable;
2707 
2708 	if (QDF_STATUS_SUCCESS !=
2709 	    ipa_send_uc_offload_enable_disable(ipa_ctx->pdev, &req)) {
2710 		ipa_err("Fail to enable IPA offload");
2711 		ipa_err("offload type=%d, vdev_id=%d, enable=%d",
2712 			offload_type, session_id, enable);
2713 	} else {
2714 		ipa_ctx->vdev_offload_enabled[session_id] = enable;
2715 	}
2716 
2717 	wlan_ipa_intrabss_enable_disable(ipa_ctx, session_id, enable);
2718 }
2719 
2720 #ifdef WDI3_STATS_BW_MONITOR
2721 static void wlan_ipa_uc_bw_monitor(struct wlan_ipa_priv *ipa_ctx, bool stop)
2722 {
2723 	qdf_ipa_wdi_bw_info_t bw_info;
2724 	uint32_t bw_low = ipa_ctx->config->ipa_bw_low;
2725 	uint32_t bw_medium = ipa_ctx->config->ipa_bw_medium;
2726 	uint32_t bw_high = ipa_ctx->config->ipa_bw_high;
2727 	int ret;
2728 
2729 	bw_info.num = WLAN_IPA_UC_BW_MONITOR_LEVEL;
2730 	/* IPA uc will mobitor three bw levels for wlan client */
2731 	QDF_IPA_WDI_BW_INFO_THRESHOLD_LEVEL_1(&bw_info) = bw_low;
2732 	QDF_IPA_WDI_BW_INFO_THRESHOLD_LEVEL_2(&bw_info) = bw_medium;
2733 	QDF_IPA_WDI_BW_INFO_THRESHOLD_LEVEL_3(&bw_info) = bw_high;
2734 	QDF_IPA_WDI_BW_INFO_START_STOP(&bw_info) = stop;
2735 
2736 	ret = qdf_ipa_uc_bw_monitor(&bw_info);
2737 	if (ret)
2738 		ipa_err("ipa uc bw monitor fails");
2739 
2740 	if (!stop) {
2741 		cdp_ipa_set_perf_level(ipa_ctx->dp_soc,
2742 				       QDF_IPA_CLIENT_WLAN2_CONS,
2743 				       ipa_ctx->config->ipa_bw_low);
2744 		ipa_ctx->curr_bw_level = WLAN_IPA_BW_LEVEL_LOW;
2745 	}
2746 
2747 	ipa_debug("ipa uc bw monitor %s", stop ? "stop" : "start");
2748 }
2749 #else
2750 static inline
2751 void wlan_ipa_uc_bw_monitor(struct wlan_ipa_priv *ipa_ctx, bool stop)
2752 {
2753 }
2754 #endif
2755 
2756 /**
2757  * wlan_ipa_send_msg() - Allocate and send message to IPA
2758  * @net_dev: Interface net device
2759  * @type: event enum of type ipa_wlan_event
2760  * @mac_addr: MAC address associated with the event
2761  *
2762  * Return: QDF STATUS
2763  */
2764 static QDF_STATUS wlan_ipa_send_msg(qdf_netdev_t net_dev,
2765 				    qdf_ipa_wlan_event type,
2766 				    const uint8_t *mac_addr)
2767 {
2768 	qdf_ipa_msg_meta_t meta;
2769 	qdf_ipa_wlan_msg_t *msg;
2770 
2771 	QDF_IPA_MSG_META_MSG_LEN(&meta) = sizeof(qdf_ipa_wlan_msg_t);
2772 
2773 	msg = qdf_mem_malloc(QDF_IPA_MSG_META_MSG_LEN(&meta));
2774 	if (!msg)
2775 		return QDF_STATUS_E_NOMEM;
2776 
2777 	QDF_IPA_SET_META_MSG_TYPE(&meta, type);
2778 	strlcpy(QDF_IPA_WLAN_MSG_NAME(msg), net_dev->name, IPA_RESOURCE_NAME_MAX);
2779 	qdf_mem_copy(QDF_IPA_WLAN_MSG_MAC_ADDR(msg), mac_addr, QDF_NET_ETH_LEN);
2780 	QDF_IPA_WLAN_MSG_NETDEV_IF_ID(msg) = net_dev->ifindex;
2781 
2782 	ipa_debug("%s: Evt: %d", QDF_IPA_WLAN_MSG_NAME(msg), QDF_IPA_MSG_META_MSG_TYPE(&meta));
2783 
2784 	if (qdf_ipa_send_msg(&meta, msg, wlan_ipa_msg_free_fn)) {
2785 		ipa_err("%s: Evt: %d fail",
2786 			QDF_IPA_WLAN_MSG_NAME(msg),
2787 			QDF_IPA_MSG_META_MSG_TYPE(&meta));
2788 		qdf_mem_free(msg);
2789 		return QDF_STATUS_E_FAILURE;
2790 	}
2791 
2792 	return QDF_STATUS_SUCCESS;
2793 }
2794 
2795 #if defined(QCA_CONFIG_RPS) && !defined(MDM_PLATFORM)
2796 /**
2797  * wlan_ipa_handle_multiple_sap_evt() - Handle multiple SAP connect/disconnect
2798  * @ipa_ctx: IPA global context
2799  * @type: IPA event type
2800  * @session_id: vdev id
2801  *
2802  * This function is used to disable pipes when multiple SAP are connected and
2803  * enable pipes back when only one SAP is connected.
2804  *
2805  * Return: None
2806  */
2807 static void wlan_ipa_handle_multiple_sap_evt(struct wlan_ipa_priv *ipa_ctx,
2808 					     qdf_ipa_wlan_event type,
2809 					     uint8_t session_id)
2810 {
2811 	struct wlan_ipa_iface_context *iface_ctx;
2812 	int i;
2813 
2814 	if (type == QDF_IPA_AP_DISCONNECT) {
2815 		ipa_debug("Multiple SAP disconnecting. Enabling IPA");
2816 
2817 		if (ipa_ctx->sap_num_connected_sta > 0)
2818 			wlan_ipa_uc_handle_first_con(ipa_ctx);
2819 
2820 		for (i = 0; i < WLAN_IPA_MAX_IFACE; i++) {
2821 			iface_ctx = &ipa_ctx->iface_context[i];
2822 
2823 			if (iface_ctx->device_mode == QDF_SAP_MODE) {
2824 				wlan_ipa_uc_offload_enable_disable(ipa_ctx,
2825 							WMI_AP_RX_DATA_OFFLOAD,
2826 							iface_ctx->session_id,
2827 							true);
2828 				break;
2829 			}
2830 		}
2831 	} else if (type == QDF_IPA_AP_CONNECT) {
2832 		ipa_debug("Multiple SAP connected. Disabling IPA");
2833 
2834 		for (i = 0; i < WLAN_IPA_MAX_IFACE; i++) {
2835 			iface_ctx = &ipa_ctx->iface_context[i];
2836 
2837 			if (iface_ctx->device_mode == QDF_SAP_MODE) {
2838 				wlan_ipa_uc_offload_enable_disable(ipa_ctx,
2839 							WMI_AP_RX_DATA_OFFLOAD,
2840 							iface_ctx->session_id,
2841 							false);
2842 			}
2843 		}
2844 
2845 		if (!ipa_ctx->ipa_pipes_down)
2846 			wlan_ipa_uc_handle_last_discon(ipa_ctx, true);
2847 	}
2848 }
2849 #else
2850 /**
2851  * wlan_ipa_handle_multiple_sap_evt() - Handle multiple SAP connect/disconnect
2852  * @ipa_ctx: IPA global context
2853  * @type: IPA event type
2854  * @session_id: vdev id
2855  *
2856  * Enable IPA for new SAP when multiple SAP are turned on
2857  *
2858  * Return: None
2859  */
2860 static void wlan_ipa_handle_multiple_sap_evt(struct wlan_ipa_priv *ipa_ctx,
2861 					     qdf_ipa_wlan_event type,
2862 					     uint8_t session_id)
2863 {
2864 	if (type == QDF_IPA_AP_CONNECT)
2865 		wlan_ipa_uc_offload_enable_disable(ipa_ctx,
2866 						   WMI_AP_RX_DATA_OFFLOAD,
2867 						   session_id,
2868 						   true);
2869 }
2870 #endif
2871 
2872 static inline void
2873 wlan_ipa_save_bssid_iface_ctx(struct wlan_ipa_priv *ipa_ctx, uint8_t iface_id,
2874 			      const uint8_t *mac_addr)
2875 {
2876 	qdf_mem_copy(ipa_ctx->iface_context[iface_id].bssid.bytes,
2877 		     mac_addr, QDF_MAC_ADDR_SIZE);
2878 }
2879 
2880 #ifdef IPA_WDS_EASYMESH_FEATURE
2881 /** wlan_ipa_set_peer_id() - Set ta_peer_id in IPA
2882  * @ipa_ctx: ipa context
2883  * @meta: Meta data for IPA
2884  * @net_dev: Interface net device
2885  * @type: WLAN IPA event
2886  * @mac_addr: mac_addr of peer
2887  *
2888  * Return: QDF STATUS
2889  */
2890 static QDF_STATUS
2891 wlan_ipa_set_peer_id(struct wlan_ipa_priv *ipa_ctx,
2892 		     qdf_ipa_msg_meta_t *meta,
2893 		     qdf_netdev_t net_dev,
2894 		     qdf_ipa_wlan_event type,
2895 		     const uint8_t *mac_addr)
2896 {
2897 	uint8_t ta_peer_id;
2898 	struct cdp_ast_entry_info peer_ast_info = {0};
2899 	struct cdp_soc_t *cdp_soc;
2900 	qdf_ipa_wlan_msg_ex_t *msg_ex;
2901 	bool status;
2902 
2903 	QDF_IPA_MSG_META_MSG_LEN(meta) =
2904 		(sizeof(qdf_ipa_wlan_msg_ex_t) +
2905 		 sizeof(qdf_ipa_wlan_hdr_attrib_val_t) *
2906 		 IPA_TA_PEER_ID_ATTRI);
2907 
2908 	msg_ex = qdf_mem_malloc(QDF_IPA_MSG_META_MSG_LEN(meta));
2909 	if (!msg_ex)
2910 		return QDF_STATUS_E_NOMEM;
2911 
2912 	strlcpy(msg_ex->name, net_dev->name, IPA_RESOURCE_NAME_MAX);
2913 	msg_ex->num_of_attribs = IPA_TA_PEER_ID_ATTRI;
2914 	ipa_info("Num of attribute set to: %d", IPA_TA_PEER_ID_ATTRI);
2915 
2916 	msg_ex->attribs[0].attrib_type = WLAN_HDR_ATTRIB_MAC_ADDR;
2917 	if (wlan_ipa_uc_is_enabled(ipa_ctx->config)) {
2918 		msg_ex->attribs[0].offset =
2919 			WLAN_IPA_UC_WLAN_HDR_DES_MAC_OFFSET;
2920 	} else {
2921 		msg_ex->attribs[0].offset =
2922 			WLAN_IPA_WLAN_HDR_DES_MAC_OFFSET;
2923 	}
2924 	memcpy(msg_ex->attribs[0].u.mac_addr, mac_addr, IPA_MAC_ADDR_SIZE);
2925 
2926 	msg_ex->attribs[1].attrib_type = WLAN_HDR_ATTRIB_TA_PEER_ID;
2927 	cdp_soc = (struct cdp_soc_t *)ipa_ctx->dp_soc;
2928 	status = cdp_peer_get_ast_info_by_soc(cdp_soc,
2929 					      msg_ex->attribs[0].u.mac_addr,
2930 					      &peer_ast_info);
2931 
2932 	if (!status) {
2933 		qdf_mem_free(msg_ex);
2934 		return QDF_STATUS_E_FAILURE;
2935 	}
2936 
2937 	ta_peer_id = peer_ast_info.peer_id;
2938 	ipa_info("ta_peer_id set to: %d", ta_peer_id);
2939 	msg_ex->attribs[1].u.ta_peer_id = ta_peer_id;
2940 
2941 	if (qdf_ipa_send_msg(meta, msg_ex, wlan_ipa_msg_free_fn)) {
2942 		ipa_info("%s: Evt: %d send ipa msg fail",
2943 			 net_dev->name, type);
2944 		qdf_mem_free(msg_ex);
2945 		return QDF_STATUS_E_FAILURE;
2946 	}
2947 	ipa_ctx->stats.num_send_msg++;
2948 
2949 	return QDF_STATUS_SUCCESS;
2950 }
2951 #else
2952 static QDF_STATUS
2953 wlan_ipa_set_peer_id(struct wlan_ipa_priv *ipa_ctx,
2954 		     qdf_ipa_msg_meta_t *meta,
2955 		     qdf_netdev_t net_dev,
2956 		     qdf_ipa_wlan_event type,
2957 		     const uint8_t *mac_addr)
2958 {
2959 	qdf_ipa_wlan_msg_ex_t *msg_ex;
2960 
2961 	QDF_IPA_MSG_META_MSG_LEN(meta) =
2962 		(sizeof(qdf_ipa_wlan_msg_ex_t) +
2963 		 sizeof(qdf_ipa_wlan_hdr_attrib_val_t));
2964 
2965 	msg_ex = qdf_mem_malloc(QDF_IPA_MSG_META_MSG_LEN(meta));
2966 	if (!msg_ex)
2967 		return QDF_STATUS_E_NOMEM;
2968 
2969 	strlcpy(msg_ex->name, net_dev->name, IPA_RESOURCE_NAME_MAX);
2970 	msg_ex->num_of_attribs = 1;
2971 	msg_ex->attribs[0].attrib_type = WLAN_HDR_ATTRIB_MAC_ADDR;
2972 
2973 	if (wlan_ipa_uc_is_enabled(ipa_ctx->config)) {
2974 		msg_ex->attribs[0].offset =
2975 			WLAN_IPA_UC_WLAN_HDR_DES_MAC_OFFSET;
2976 	} else {
2977 		msg_ex->attribs[0].offset = WLAN_IPA_WLAN_HDR_DES_MAC_OFFSET;
2978 	}
2979 	memcpy(msg_ex->attribs[0].u.mac_addr, mac_addr, IPA_MAC_ADDR_SIZE);
2980 
2981 	if (qdf_ipa_send_msg(meta, msg_ex, wlan_ipa_msg_free_fn)) {
2982 		ipa_info("%s: Evt: %d send ipa msg fail",
2983 			 net_dev->name, type);
2984 		qdf_mem_free(msg_ex);
2985 		return QDF_STATUS_E_FAILURE;
2986 	}
2987 	ipa_ctx->stats.num_send_msg++;
2988 
2989 	return QDF_STATUS_SUCCESS;
2990 }
2991 #endif
2992 
2993 /**
2994  * __wlan_ipa_wlan_evt() - IPA event handler
2995  * @net_dev: Interface net device
2996  * @device_mode: Net interface device mode
2997  * @session_id: session id for the event
2998  * @type: event enum of type ipa_wlan_event
2999  * @mac_addr: MAC address associated with the event
3000  * @is_2g_iface: @net_dev is 2G or not for QDF_IPA_STA_CONNECT and
3001  *		 QDF_IPA_AP_CONNECT
3002  * @ipa_obj: IPA object
3003  *
3004  * This function is meant to be called from within wlan_ipa_ctx.c
3005  *
3006  * Return: QDF STATUS
3007  */
3008 static QDF_STATUS __wlan_ipa_wlan_evt(qdf_netdev_t net_dev, uint8_t device_mode,
3009 				      uint8_t session_id,
3010 				      qdf_ipa_wlan_event type,
3011 				      const uint8_t *mac_addr, bool is_2g_iface,
3012 				      struct wlan_ipa_priv *ipa_obj)
3013 {
3014 	struct wlan_ipa_priv *ipa_ctx;
3015 	struct wlan_ipa_iface_context *iface_ctx = NULL;
3016 	qdf_ipa_msg_meta_t meta;
3017 	qdf_ipa_wlan_msg_t *msg;
3018 	qdf_ipa_wlan_msg_ex_t *msg_ex = NULL;
3019 	int i;
3020 	QDF_STATUS status;
3021 	uint8_t sta_session_id = WLAN_IPA_MAX_SESSION;
3022 	struct wlan_objmgr_pdev *pdev;
3023 	struct wlan_objmgr_psoc *psoc;
3024 	struct wlan_objmgr_vdev *vdev;
3025 	bool ipa_wds = false;
3026 
3027 	ipa_debug("%s: EVT: %d, MAC: "QDF_MAC_ADDR_FMT", session_id: %u is_2g_iface %u",
3028 		  net_dev->name, type, QDF_MAC_ADDR_REF(mac_addr), session_id,
3029 		  is_2g_iface);
3030 
3031 	if (type >= QDF_IPA_WLAN_EVENT_MAX)
3032 		return QDF_STATUS_E_INVAL;
3033 
3034 	ipa_ctx = ipa_obj;
3035 	if (wlan_ipa_uc_is_enabled(ipa_ctx->config) &&
3036 	    !wlan_ipa_uc_sta_is_enabled(ipa_ctx->config) &&
3037 	    (device_mode != QDF_SAP_MODE)) {
3038 		return QDF_STATUS_SUCCESS;
3039 	}
3040 
3041 	pdev = ipa_ctx->pdev;
3042 	psoc = wlan_pdev_get_psoc(pdev);
3043 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, session_id,
3044 						    WLAN_IPA_ID);
3045 	QDF_BUG(session_id < WLAN_IPA_MAX_SESSION);
3046 
3047 	if (vdev)
3048 		wlan_objmgr_vdev_release_ref(vdev, WLAN_IPA_ID);
3049 	else
3050 		ipa_err("vdev is NULL, session_id: %u", session_id);
3051 
3052 	if (ipa_ctx->sta_connected) {
3053 		iface_ctx = wlan_ipa_get_iface(ipa_ctx, QDF_STA_MODE);
3054 		if (iface_ctx)
3055 			sta_session_id = iface_ctx->session_id;
3056 		else
3057 			ipa_err("sta iface_ctx is NULL");
3058 	}
3059 
3060 	/*
3061 	 * During IPA UC resource loading/unloading new events can be issued.
3062 	 */
3063 	if (wlan_ipa_uc_is_enabled(ipa_ctx->config) &&
3064 	    (ipa_ctx->resource_loading || ipa_ctx->resource_unloading)) {
3065 		unsigned int pending_event_count;
3066 		struct wlan_ipa_uc_pending_event *pending_event = NULL;
3067 
3068 		ipa_info("Event:%d IPA resource %s inprogress", type,
3069 			 ipa_ctx->resource_loading ?
3070 			 "load" : "unload");
3071 
3072 		/* Wait until completion of the loading/unloading */
3073 		status = qdf_wait_for_event_completion(
3074 				&ipa_ctx->ipa_resource_comp,
3075 				IPA_RESOURCE_COMP_WAIT_TIME);
3076 		if (status != QDF_STATUS_SUCCESS) {
3077 			/*
3078 			 * If timed out, store the events separately and
3079 			 * handle them later.
3080 			 */
3081 			ipa_info("IPA resource %s timed out",
3082 				  ipa_ctx->resource_loading ?
3083 				  "load" : "unload");
3084 
3085 			if (type == QDF_IPA_AP_DISCONNECT) {
3086 				wlan_ipa_uc_offload_enable_disable(ipa_ctx,
3087 						WMI_AP_RX_DATA_OFFLOAD,
3088 						session_id, false);
3089 			} else if (type == QDF_IPA_CLIENT_CONNECT_EX &&
3090 				   wlan_sap_no_client_connected(ipa_ctx)) {
3091 				if (wlan_sta_is_connected(ipa_ctx) &&
3092 				    wlan_ipa_uc_is_loaded(ipa_ctx) &&
3093 				    wlan_ipa_uc_sta_is_enabled(ipa_ctx->
3094 							       config) &&
3095 				    !wlan_ipa_is_sta_only_offload_enabled()) {
3096 					wlan_ipa_uc_offload_enable_disable(
3097 							ipa_ctx,
3098 							WMI_STA_RX_DATA_OFFLOAD,
3099 							sta_session_id, true);
3100 				}
3101 			}
3102 
3103 			qdf_mutex_acquire(&ipa_ctx->ipa_lock);
3104 
3105 			pending_event_count =
3106 				qdf_list_size(&ipa_ctx->pending_event);
3107 			if (pending_event_count >=
3108 			    WLAN_IPA_MAX_PENDING_EVENT_COUNT) {
3109 				ipa_info("Reached max pending evt count");
3110 				qdf_list_remove_front(
3111 					&ipa_ctx->pending_event,
3112 					(qdf_list_node_t **)&pending_event);
3113 			} else {
3114 				pending_event =
3115 					(struct wlan_ipa_uc_pending_event *)
3116 					qdf_mem_malloc(sizeof(
3117 					struct wlan_ipa_uc_pending_event));
3118 			}
3119 
3120 			if (!pending_event) {
3121 				qdf_mutex_release(&ipa_ctx->ipa_lock);
3122 				return QDF_STATUS_E_NOMEM;
3123 			}
3124 
3125 			pending_event->net_dev = net_dev;
3126 			pending_event->device_mode = device_mode;
3127 			pending_event->session_id = session_id;
3128 			pending_event->type = type;
3129 			pending_event->is_loading = ipa_ctx->resource_loading;
3130 			qdf_mem_copy(pending_event->mac_addr,
3131 				     mac_addr, QDF_MAC_ADDR_SIZE);
3132 			pending_event->is_2g_iface = is_2g_iface;
3133 			qdf_list_insert_back(&ipa_ctx->pending_event,
3134 					     &pending_event->node);
3135 
3136 			qdf_mutex_release(&ipa_ctx->ipa_lock);
3137 
3138 			/* Cleanup interface */
3139 			if (type == QDF_IPA_STA_DISCONNECT ||
3140 			    type == QDF_IPA_AP_DISCONNECT) {
3141 				for (i = 0; i < WLAN_IPA_MAX_IFACE; i++) {
3142 					iface_ctx = &ipa_ctx->iface_context[i];
3143 					if (iface_ctx->dev == net_dev) {
3144 						wlan_ipa_cleanup_iface(
3145 								iface_ctx,
3146 								mac_addr);
3147 						break;
3148 					}
3149 				}
3150 
3151 				if (qdf_ipa_get_lan_rx_napi() &&
3152 				    ipa_ctx->num_sap_connected == 1) {
3153 					wlan_ipa_handle_multiple_sap_evt(ipa_ctx,
3154 							type, session_id);
3155 				}
3156 			}
3157 
3158 			return QDF_STATUS_SUCCESS;
3159 		}
3160 		ipa_info("IPA resource %s completed",
3161 			 ipa_ctx->resource_loading ?
3162 			 "load" : "unload");
3163 	}
3164 
3165 	ipa_ctx->stats.event[type]++;
3166 
3167 	QDF_IPA_SET_META_MSG_TYPE(&meta, type);
3168 	switch (type) {
3169 	case QDF_IPA_STA_CONNECT:
3170 		qdf_mutex_acquire(&ipa_ctx->event_lock);
3171 
3172 		/* STA already connected and without disconnect, connect again
3173 		 * This is Roaming scenario, clean up ipa iface first, then add
3174 		 * ipa iface later, sta_connected-- first, sta_connected++
3175 		 * later to reflect real sta number on DUT.
3176 		 */
3177 		if (ipa_ctx->sta_connected) {
3178 			iface_ctx = wlan_ipa_get_iface_by_mode_netdev(
3179 					ipa_ctx, net_dev, QDF_STA_MODE);
3180 			if (iface_ctx) {
3181 				ipa_ctx->sta_connected--;
3182 				wlan_ipa_cleanup_iface(iface_ctx, NULL);
3183 			}
3184 			status = wlan_ipa_send_msg(net_dev,
3185 						   QDF_IPA_STA_DISCONNECT,
3186 						   mac_addr);
3187 			if (status != QDF_STATUS_SUCCESS) {
3188 				ipa_err("QDF_IPA_STA_DISCONNECT send failed %u",
3189 					status);
3190 				qdf_mutex_release(&ipa_ctx->event_lock);
3191 				goto end;
3192 			}
3193 		}
3194 
3195 		status = wlan_ipa_setup_iface(ipa_ctx, net_dev, device_mode,
3196 					      session_id, mac_addr,
3197 					      is_2g_iface);
3198 		if (status != QDF_STATUS_SUCCESS) {
3199 			ipa_err("wlan_ipa_setup_iface failed %u", status);
3200 			qdf_mutex_release(&ipa_ctx->event_lock);
3201 			goto end;
3202 		}
3203 
3204 		ipa_ctx->vdev_to_iface[session_id] =
3205 				wlan_ipa_get_ifaceid(ipa_ctx, session_id);
3206 
3207 		wlan_ipa_save_bssid_iface_ctx(ipa_ctx,
3208 					     ipa_ctx->vdev_to_iface[session_id],
3209 					     mac_addr);
3210 
3211 		if (wlan_ipa_uc_sta_is_enabled(ipa_ctx->config) &&
3212 		    (ipa_ctx->sap_num_connected_sta > 0 ||
3213 		     wlan_ipa_is_sta_only_offload_enabled()) &&
3214 		    !ipa_ctx->sta_connected) {
3215 			qdf_mutex_release(&ipa_ctx->event_lock);
3216 			wlan_ipa_uc_offload_enable_disable(ipa_ctx,
3217 				WMI_STA_RX_DATA_OFFLOAD, session_id,
3218 				true);
3219 			qdf_mutex_acquire(&ipa_ctx->event_lock);
3220 			qdf_atomic_set(&ipa_ctx->stats_quota, 1);
3221 		}
3222 
3223 		if (!wlan_ipa_is_sta_only_offload_enabled()) {
3224 			ipa_debug("IPA STA only offload not enabled");
3225 		} else if (ipa_ctx->uc_loaded &&
3226 			   !ipa_ctx->sap_num_connected_sta &&
3227 			   !ipa_ctx->sta_connected) {
3228 			status = wlan_ipa_uc_handle_first_con(ipa_ctx);
3229 			if (status) {
3230 				qdf_mutex_release(&ipa_ctx->event_lock);
3231 				ipa_info("handle 1st conn failed %d", status);
3232 				wlan_ipa_uc_offload_enable_disable(
3233 						ipa_ctx,
3234 						WMI_STA_RX_DATA_OFFLOAD,
3235 						session_id,
3236 						false);
3237 				ipa_ctx->vdev_to_iface[session_id] =
3238 				    WLAN_IPA_MAX_SESSION;
3239 				goto end;
3240 			}
3241 		}
3242 
3243 		ipa_ctx->sta_connected++;
3244 
3245 		if (qdf_ipa_get_lan_rx_napi() && ipa_ctx->sap_num_connected_sta)
3246 			ipa_set_rps_per_vdev(ipa_ctx, session_id, true);
3247 
3248 		qdf_mutex_release(&ipa_ctx->event_lock);
3249 
3250 		ipa_debug("sta_connected=%d vdev_to_iface[%u] %u",
3251 			 ipa_ctx->sta_connected,
3252 			 session_id,
3253 			 ipa_ctx->vdev_to_iface[session_id]);
3254 		break;
3255 
3256 	case QDF_IPA_AP_CONNECT:
3257 		qdf_mutex_acquire(&ipa_ctx->event_lock);
3258 
3259 		/* For DFS channel we get two start_bss event (before and after
3260 		 * CAC). Also when ACS range includes both DFS and non DFS
3261 		 * channels, we could possibly change channel many times due to
3262 		 * RADAR detection and chosen channel may not be a DFS channels.
3263 		 * So dont return error here. Just discard the event.
3264 		 */
3265 		if (ipa_ctx->vdev_to_iface[session_id] !=
3266 				WLAN_IPA_MAX_SESSION) {
3267 			qdf_mutex_release(&ipa_ctx->event_lock);
3268 			return 0;
3269 		}
3270 
3271 		status = wlan_ipa_setup_iface(ipa_ctx, net_dev, device_mode,
3272 					      session_id, mac_addr,
3273 					      is_2g_iface);
3274 		if (status != QDF_STATUS_SUCCESS) {
3275 			qdf_mutex_release(&ipa_ctx->event_lock);
3276 			ipa_err("%s: Evt: %d, Interface setup failed",
3277 				msg_ex->name, QDF_IPA_MSG_META_MSG_TYPE(&meta));
3278 			goto end;
3279 		}
3280 
3281 		if (wlan_ipa_uc_is_enabled(ipa_ctx->config)) {
3282 			qdf_mutex_release(&ipa_ctx->event_lock);
3283 			if (qdf_ipa_get_lan_rx_napi() &&
3284 			    (ipa_ctx->num_sap_connected > 1)) {
3285 				wlan_ipa_handle_multiple_sap_evt(ipa_ctx, type,
3286 								 session_id);
3287 			} else {
3288 				wlan_ipa_uc_offload_enable_disable(ipa_ctx,
3289 							WMI_AP_RX_DATA_OFFLOAD,
3290 							session_id, true);
3291 			}
3292 			qdf_mutex_acquire(&ipa_ctx->event_lock);
3293 		}
3294 
3295 		ipa_ctx->vdev_to_iface[session_id] =
3296 				wlan_ipa_get_ifaceid(ipa_ctx, session_id);
3297 		ipa_debug("vdev_to_iface[%u]=%u",
3298 			 session_id,
3299 			 ipa_ctx->vdev_to_iface[session_id]);
3300 		ipa_wds = ipa_ctx->config->ipa_wds;
3301 		qdf_mutex_release(&ipa_ctx->event_lock);
3302 		break;
3303 
3304 	case QDF_IPA_STA_DISCONNECT:
3305 		qdf_mutex_acquire(&ipa_ctx->event_lock);
3306 
3307 		if (!ipa_ctx->sta_connected) {
3308 			struct wlan_ipa_iface_context *iface;
3309 
3310 			qdf_mutex_release(&ipa_ctx->event_lock);
3311 			ipa_info("%s: Evt: %d, STA already disconnected",
3312 				 msg_ex->name,
3313 				 QDF_IPA_MSG_META_MSG_TYPE(&meta));
3314 
3315 			iface = wlan_ipa_get_iface_by_mode_netdev(ipa_ctx,
3316 								  net_dev,
3317 								  QDF_STA_MODE);
3318 			if (iface)
3319 				wlan_ipa_cleanup_iface(iface, mac_addr);
3320 
3321 			return QDF_STATUS_E_INVAL;
3322 		}
3323 
3324 		ipa_ctx->sta_connected--;
3325 
3326 		if (!wlan_ipa_uc_is_enabled(ipa_ctx->config)) {
3327 			ipa_debug("%s: IPA UC OFFLOAD NOT ENABLED",
3328 				  msg_ex->name);
3329 		} else {
3330 			/*
3331 			 * Disable IPA pipes when
3332 			 * 1. STA is the last interface or
3333 			 * 2. STA only offload enabled and no clients connected
3334 			 * to SAP
3335 			 */
3336 			if ((ipa_ctx->num_iface == 1 ||
3337 			     (wlan_ipa_is_sta_only_offload_enabled() &&
3338 			      !ipa_ctx->sap_num_connected_sta)) &&
3339 			    wlan_ipa_is_fw_wdi_activated(ipa_ctx) &&
3340 			    !ipa_ctx->ipa_pipes_down &&
3341 			    (ipa_ctx->resource_unloading == false)) {
3342 				if (wlan_ipa_is_driver_unloading(ipa_ctx)) {
3343 					/*
3344 					 * We disable WDI pipes directly here
3345 					 * since IPA_OPCODE_TX/RX_SUSPEND
3346 					 * message will not be processed when
3347 					 * unloading WLAN driver is in progress
3348 					 */
3349 					wlan_ipa_uc_disable_pipes(ipa_ctx,
3350 								  true);
3351 				} else {
3352 					wlan_ipa_uc_handle_last_discon(ipa_ctx,
3353 								       true);
3354 				}
3355 			}
3356 		}
3357 
3358 		if (wlan_ipa_uc_sta_is_enabled(ipa_ctx->config) &&
3359 		    (ipa_ctx->sap_num_connected_sta > 0 ||
3360 		     wlan_ipa_is_sta_only_offload_enabled())) {
3361 			qdf_atomic_set(&ipa_ctx->stats_quota, 0);
3362 			qdf_mutex_release(&ipa_ctx->event_lock);
3363 			wlan_ipa_uc_offload_enable_disable(ipa_ctx,
3364 				WMI_STA_RX_DATA_OFFLOAD, session_id, false);
3365 			qdf_mutex_acquire(&ipa_ctx->event_lock);
3366 		}
3367 
3368 		ipa_ctx->vdev_to_iface[session_id] = WLAN_IPA_MAX_SESSION;
3369 		ipa_debug("vdev_to_iface[%u]=%u", session_id,
3370 			  ipa_ctx->vdev_to_iface[session_id]);
3371 
3372 		iface_ctx = wlan_ipa_get_iface_by_mode_netdev(ipa_ctx,
3373 							      net_dev,
3374 							      QDF_STA_MODE);
3375 		if (iface_ctx)
3376 			wlan_ipa_cleanup_iface(iface_ctx, mac_addr);
3377 
3378 		if (qdf_ipa_get_lan_rx_napi() && ipa_ctx->sap_num_connected_sta)
3379 			ipa_set_rps_per_vdev(ipa_ctx, session_id, false);
3380 
3381 		qdf_mutex_release(&ipa_ctx->event_lock);
3382 
3383 		ipa_debug("sta_connected=%d", ipa_ctx->sta_connected);
3384 		break;
3385 
3386 	case QDF_IPA_AP_DISCONNECT:
3387 		qdf_mutex_acquire(&ipa_ctx->event_lock);
3388 
3389 		if ((ipa_ctx->num_iface == 1) &&
3390 		    wlan_ipa_is_fw_wdi_activated(ipa_ctx) &&
3391 		    !ipa_ctx->ipa_pipes_down &&
3392 		    (ipa_ctx->resource_unloading == false)) {
3393 			if (wlan_ipa_is_driver_unloading(ipa_ctx)) {
3394 				/*
3395 				 * We disable WDI pipes directly here since
3396 				 * IPA_OPCODE_TX/RX_SUSPEND message will not be
3397 				 * processed when unloading WLAN driver is in
3398 				 * progress
3399 				 */
3400 				wlan_ipa_uc_disable_pipes(ipa_ctx, true);
3401 			} else {
3402 				/*
3403 				 * This shouldn't happen :
3404 				 * No interface left but WDI pipes are still
3405 				 * active - force close WDI pipes
3406 				 */
3407 				ipa_err("No interface left but WDI pipes are still active");
3408 				wlan_ipa_uc_handle_last_discon(ipa_ctx, true);
3409 			}
3410 		}
3411 
3412 		if (wlan_ipa_uc_is_enabled(ipa_ctx->config)) {
3413 			qdf_mutex_release(&ipa_ctx->event_lock);
3414 			wlan_ipa_uc_offload_enable_disable(ipa_ctx,
3415 				WMI_AP_RX_DATA_OFFLOAD, session_id, false);
3416 			qdf_mutex_acquire(&ipa_ctx->event_lock);
3417 			ipa_ctx->vdev_to_iface[session_id] =
3418 				WLAN_IPA_MAX_SESSION;
3419 			ipa_debug("vdev_to_iface[%u]=%u",
3420 				 session_id,
3421 				 ipa_ctx->vdev_to_iface[session_id]);
3422 		}
3423 
3424 		for (i = 0; i < WLAN_IPA_MAX_IFACE; i++) {
3425 			iface_ctx = &ipa_ctx->iface_context[i];
3426 			if (iface_ctx->dev == net_dev) {
3427 				wlan_ipa_cleanup_iface(iface_ctx, mac_addr);
3428 				break;
3429 			}
3430 		}
3431 
3432 		if (qdf_ipa_get_lan_rx_napi() &&
3433 		    (ipa_ctx->num_sap_connected == 1))
3434 			wlan_ipa_handle_multiple_sap_evt(ipa_ctx, type,
3435 							 session_id);
3436 
3437 		qdf_mutex_release(&ipa_ctx->event_lock);
3438 		break;
3439 
3440 	case QDF_IPA_CLIENT_CONNECT_EX:
3441 		if (!wlan_ipa_uc_is_enabled(ipa_ctx->config)) {
3442 			ipa_debug("%s: Evt: %d, IPA UC OFFLOAD NOT ENABLED",
3443 				  net_dev->name, type);
3444 			return QDF_STATUS_SUCCESS;
3445 		}
3446 
3447 		qdf_mutex_acquire(&ipa_ctx->event_lock);
3448 		if (wlan_ipa_uc_find_add_assoc_sta(ipa_ctx, true,
3449 						   mac_addr)) {
3450 			qdf_mutex_release(&ipa_ctx->event_lock);
3451 			ipa_err("%s: STA found, addr: " QDF_MAC_ADDR_FMT,
3452 				net_dev->name,
3453 				QDF_MAC_ADDR_REF(mac_addr));
3454 			return QDF_STATUS_SUCCESS;
3455 		}
3456 
3457 		/* Enable IPA UC Data PIPEs when first STA connected */
3458 		if (ipa_ctx->sap_num_connected_sta == 0 &&
3459 				ipa_ctx->uc_loaded == true) {
3460 
3461 			if (wlan_ipa_uc_sta_is_enabled(ipa_ctx->config) &&
3462 			    ipa_ctx->sta_connected &&
3463 			    !wlan_ipa_is_sta_only_offload_enabled()) {
3464 				qdf_mutex_release(&ipa_ctx->event_lock);
3465 				wlan_ipa_uc_offload_enable_disable(ipa_ctx,
3466 							WMI_STA_RX_DATA_OFFLOAD,
3467 							sta_session_id, true);
3468 				qdf_mutex_acquire(&ipa_ctx->event_lock);
3469 				qdf_atomic_set(&ipa_ctx->stats_quota, 1);
3470 			}
3471 
3472 			/*
3473 			 * IPA pipes already enabled if STA only offload
3474 			 * is enabled and STA is connected to remote AP.
3475 			 */
3476 			if (wlan_ipa_is_sta_only_offload_enabled() &&
3477 			    ipa_ctx->sta_connected) {
3478 				ipa_debug("IPA pipes already enabled");
3479 			} else if (wlan_ipa_uc_handle_first_con(ipa_ctx)) {
3480 				ipa_info("%s: handle 1st con fail",
3481 					 net_dev->name);
3482 
3483 				if (wlan_ipa_uc_sta_is_enabled(
3484 					ipa_ctx->config) &&
3485 				    ipa_ctx->sta_connected &&
3486 				    !wlan_ipa_is_sta_only_offload_enabled()) {
3487 					qdf_atomic_set(&ipa_ctx->stats_quota,
3488 						       0);
3489 					qdf_mutex_release(&ipa_ctx->event_lock);
3490 					wlan_ipa_uc_offload_enable_disable(
3491 							ipa_ctx,
3492 							WMI_STA_RX_DATA_OFFLOAD,
3493 							sta_session_id, false);
3494 				} else {
3495 					qdf_mutex_release(&ipa_ctx->event_lock);
3496 				}
3497 
3498 				return QDF_STATUS_E_BUSY;
3499 			}
3500 			wlan_ipa_uc_bw_monitor(ipa_ctx, false);
3501 			ipa_info("first sap client connected");
3502 		}
3503 
3504 		ipa_ctx->sap_num_connected_sta++;
3505 
3506 		qdf_mutex_release(&ipa_ctx->event_lock);
3507 
3508 		QDF_IPA_SET_META_MSG_TYPE(&meta, type);
3509 
3510 		status = wlan_ipa_set_peer_id(ipa_ctx, &meta, net_dev,
3511 					      type, mac_addr);
3512 		if (QDF_IS_STATUS_ERROR(status))
3513 			return QDF_STATUS_E_FAILURE;
3514 
3515 		ipa_debug("sap_num_connected_sta=%d",
3516 			   ipa_ctx->sap_num_connected_sta);
3517 
3518 		return QDF_STATUS_SUCCESS;
3519 
3520 	case WLAN_CLIENT_DISCONNECT:
3521 		if (!wlan_ipa_uc_is_enabled(ipa_ctx->config)) {
3522 			ipa_debug("%s: IPA UC OFFLOAD NOT ENABLED",
3523 				  msg_ex->name);
3524 			return QDF_STATUS_SUCCESS;
3525 		}
3526 
3527 		qdf_mutex_acquire(&ipa_ctx->event_lock);
3528 		wlan_ipa_set_sap_client_auth(ipa_ctx, mac_addr, false);
3529 		if (!ipa_ctx->sap_num_connected_sta) {
3530 			qdf_mutex_release(&ipa_ctx->event_lock);
3531 			ipa_debug("%s: Evt: %d, Client already disconnected",
3532 				  msg_ex->name,
3533 				  QDF_IPA_MSG_META_MSG_TYPE(&meta));
3534 
3535 			return QDF_STATUS_SUCCESS;
3536 		}
3537 		if (!wlan_ipa_uc_find_add_assoc_sta(ipa_ctx, false,
3538 						    mac_addr)) {
3539 			qdf_mutex_release(&ipa_ctx->event_lock);
3540 			ipa_debug("%s: STA NOT found, not valid: "
3541 				QDF_MAC_ADDR_FMT,
3542 				msg_ex->name, QDF_MAC_ADDR_REF(mac_addr));
3543 
3544 			return QDF_STATUS_SUCCESS;
3545 		}
3546 		ipa_ctx->sap_num_connected_sta--;
3547 
3548 		/*
3549 		 * Disable IPA pipes when
3550 		 * 1. last client disconnected and
3551 		 * 2. STA is not connected if STA only offload is enabled
3552 		 */
3553 		if (!ipa_ctx->sap_num_connected_sta &&
3554 		    ipa_ctx->uc_loaded &&
3555 		    !(wlan_ipa_is_sta_only_offload_enabled() &&
3556 		      ipa_ctx->sta_connected)) {
3557 			if ((false == ipa_ctx->resource_unloading) &&
3558 			    wlan_ipa_is_fw_wdi_activated(ipa_ctx) &&
3559 			    !ipa_ctx->ipa_pipes_down) {
3560 				if (wlan_ipa_is_driver_unloading(ipa_ctx)) {
3561 					/*
3562 					 * We disable WDI pipes directly here
3563 					 * since IPA_OPCODE_TX/RX_SUSPEND
3564 					 * message will not be processed when
3565 					 * unloading WLAN driver is in progress
3566 					 */
3567 
3568 					wlan_ipa_uc_bw_monitor(ipa_ctx, true);
3569 					wlan_ipa_uc_disable_pipes(ipa_ctx,
3570 								  true);
3571 				} else {
3572 					/*
3573 					 * If STA is connected, wait for IPA TX
3574 					 * completions before disabling
3575 					 * IPA pipes
3576 					 */
3577 					wlan_ipa_uc_handle_last_discon(ipa_ctx,
3578 								       !ipa_ctx->sta_connected);
3579 					wlan_ipa_uc_bw_monitor(ipa_ctx, true);
3580 				}
3581 				ipa_info("last sap client disconnected");
3582 			}
3583 
3584 			if (wlan_ipa_uc_sta_is_enabled(ipa_ctx->config) &&
3585 			    ipa_ctx->sta_connected &&
3586 			    !wlan_ipa_is_sta_only_offload_enabled()) {
3587 				qdf_atomic_set(&ipa_ctx->stats_quota, 0);
3588 				qdf_mutex_release(&ipa_ctx->event_lock);
3589 				wlan_ipa_uc_offload_enable_disable(ipa_ctx,
3590 							WMI_STA_RX_DATA_OFFLOAD,
3591 							sta_session_id, false);
3592 			} else {
3593 				qdf_mutex_release(&ipa_ctx->event_lock);
3594 			}
3595 		} else {
3596 			qdf_mutex_release(&ipa_ctx->event_lock);
3597 		}
3598 
3599 		ipa_debug("sap_num_connected_sta=%d",
3600 			  ipa_ctx->sap_num_connected_sta);
3601 		break;
3602 
3603 	default:
3604 		return QDF_STATUS_SUCCESS;
3605 	}
3606 
3607 	QDF_IPA_MSG_META_MSG_LEN(&meta) = sizeof(qdf_ipa_wlan_msg_t);
3608 	msg = qdf_mem_malloc(QDF_IPA_MSG_META_MSG_LEN(&meta));
3609 	if (!msg)
3610 		return QDF_STATUS_E_NOMEM;
3611 
3612 	QDF_IPA_SET_META_MSG_TYPE(&meta, type);
3613 	strlcpy(QDF_IPA_WLAN_MSG_NAME(msg), net_dev->name,
3614 		IPA_RESOURCE_NAME_MAX);
3615 	qdf_mem_copy(QDF_IPA_WLAN_MSG_MAC_ADDR(msg), mac_addr, QDF_NET_ETH_LEN);
3616 	QDF_IPA_WLAN_MSG_NETDEV_IF_ID(msg) = net_dev->ifindex;
3617 
3618 	wlan_ipa_msg_wds_update(ipa_wds, msg);
3619 
3620 	ipa_debug("%s: Evt: %d", QDF_IPA_WLAN_MSG_NAME(msg),
3621 		  QDF_IPA_MSG_META_MSG_TYPE(&meta));
3622 
3623 	if (qdf_ipa_send_msg(&meta, msg, wlan_ipa_msg_free_fn)) {
3624 
3625 		ipa_err("%s: Evt: %d fail",
3626 			QDF_IPA_WLAN_MSG_NAME(msg),
3627 			QDF_IPA_MSG_META_MSG_TYPE(&meta));
3628 		qdf_mem_free(msg);
3629 
3630 		return QDF_STATUS_E_FAILURE;
3631 	}
3632 
3633 	ipa_ctx->stats.num_send_msg++;
3634 
3635 end:
3636 	return QDF_STATUS_SUCCESS;
3637 }
3638 
3639 /**
3640  * wlan_host_to_ipa_wlan_event() - convert wlan_ipa_wlan_event to ipa_wlan_event
3641  * @wlan_ipa_event_type: event to be converted to an ipa_wlan_event
3642  *
3643  * Return: qdf_ipa_wlan_event representing the wlan_ipa_wlan_event
3644  */
3645 static qdf_ipa_wlan_event
3646 wlan_host_to_ipa_wlan_event(enum wlan_ipa_wlan_event wlan_ipa_event_type)
3647 {
3648 	qdf_ipa_wlan_event ipa_event;
3649 
3650 	switch (wlan_ipa_event_type) {
3651 	case WLAN_IPA_CLIENT_CONNECT:
3652 		ipa_event = QDF_IPA_CLIENT_CONNECT;
3653 		break;
3654 	case WLAN_IPA_CLIENT_DISCONNECT:
3655 		ipa_event = QDF_IPA_CLIENT_DISCONNECT;
3656 		break;
3657 	case WLAN_IPA_AP_CONNECT:
3658 		ipa_event = QDF_IPA_AP_CONNECT;
3659 		break;
3660 	case WLAN_IPA_AP_DISCONNECT:
3661 		ipa_event = QDF_IPA_AP_DISCONNECT;
3662 		break;
3663 	case WLAN_IPA_STA_CONNECT:
3664 		ipa_event = QDF_IPA_STA_CONNECT;
3665 		break;
3666 	case WLAN_IPA_STA_DISCONNECT:
3667 		ipa_event = QDF_IPA_STA_DISCONNECT;
3668 		break;
3669 	case WLAN_IPA_CLIENT_CONNECT_EX:
3670 		ipa_event = QDF_IPA_CLIENT_CONNECT_EX;
3671 		break;
3672 	case WLAN_IPA_WLAN_EVENT_MAX:
3673 	default:
3674 		ipa_event =  QDF_IPA_WLAN_EVENT_MAX;
3675 		break;
3676 	}
3677 
3678 	return ipa_event;
3679 }
3680 
3681 #ifdef IPA_P2P_SUPPORT
3682 /**
3683  * wlan_ipa_device_mode_switch() - Switch P2p GO/CLI to SAP/STA mode
3684  * @device_mode: device mode
3685  *
3686  * Return: New device mode after switching
3687  */
3688 static uint8_t wlan_ipa_device_mode_switch(uint8_t device_mode)
3689 {
3690 	switch (device_mode) {
3691 	case QDF_P2P_CLIENT_MODE:
3692 		return QDF_STA_MODE;
3693 	case QDF_P2P_GO_MODE:
3694 		return QDF_SAP_MODE;
3695 	default:
3696 		break;
3697 	}
3698 
3699 	return device_mode;
3700 }
3701 #else
3702 static uint8_t wlan_ipa_device_mode_switch(uint8_t device_mode)
3703 {
3704 	return device_mode;
3705 }
3706 #endif
3707 
3708 /**
3709  * wlan_ipa_wlan_evt() - SSR wrapper for __wlan_ipa_wlan_evt
3710  * @net_dev: Interface net device
3711  * @device_mode: Net interface device mode
3712  * @session_id: session id for the event
3713  * @ipa_event_type: event enum of type wlan_ipa_wlan_event
3714  * @mac_addr: MAC address associated with the event
3715  * @is_2g_iface: @net_dev is 2g interface or not
3716  * @ipa_obj: IPA object
3717  *
3718  * Return: QDF_STATUS
3719  */
3720 QDF_STATUS wlan_ipa_wlan_evt(qdf_netdev_t net_dev, uint8_t device_mode,
3721 		      uint8_t session_id,
3722 		      enum wlan_ipa_wlan_event ipa_event_type,
3723 		      const uint8_t *mac_addr, bool is_2g_iface,
3724 		      struct wlan_ipa_priv *ipa_obj)
3725 {
3726 	qdf_ipa_wlan_event type = wlan_host_to_ipa_wlan_event(ipa_event_type);
3727 	QDF_STATUS status = QDF_STATUS_SUCCESS;
3728 
3729 	device_mode = wlan_ipa_device_mode_switch(device_mode);
3730 
3731 	/* Data path offload only support for STA and SAP mode */
3732 	if ((device_mode == QDF_STA_MODE) ||
3733 	    (device_mode == QDF_SAP_MODE))
3734 		status  = __wlan_ipa_wlan_evt(net_dev, device_mode,
3735 					      session_id, type, mac_addr,
3736 					      is_2g_iface, ipa_obj);
3737 
3738 	return status;
3739 }
3740 
3741 /**
3742  * wlan_ipa_uc_proc_pending_event() - Process IPA uC pending events
3743  * @ipa_ctx: Global IPA IPA context
3744  * @is_loading: Indicate if invoked during loading
3745  *
3746  * Return: None
3747  */
3748 static void
3749 wlan_ipa_uc_proc_pending_event(struct wlan_ipa_priv *ipa_ctx, bool is_loading)
3750 {
3751 	unsigned int pending_event_count;
3752 	struct wlan_ipa_uc_pending_event *pending_event = NULL;
3753 
3754 	pending_event_count = qdf_list_size(&ipa_ctx->pending_event);
3755 	ipa_debug("Pending Event Count %d",  pending_event_count);
3756 	if (!pending_event_count) {
3757 		ipa_debug("No Pending Event");
3758 		return;
3759 	}
3760 
3761 	qdf_list_remove_front(&ipa_ctx->pending_event,
3762 			(qdf_list_node_t **)&pending_event);
3763 	while (pending_event) {
3764 		struct wlan_objmgr_pdev *pdev = ipa_ctx->pdev;
3765 		struct wlan_objmgr_psoc *psoc = wlan_pdev_get_psoc(pdev);
3766 		struct wlan_objmgr_vdev *vdev =
3767 				wlan_objmgr_get_vdev_by_id_from_psoc(psoc,
3768 					pending_event->session_id,
3769 					WLAN_IPA_ID);
3770 		if (pending_event->is_loading == is_loading && vdev) {
3771 			__wlan_ipa_wlan_evt(pending_event->net_dev,
3772 					   pending_event->device_mode,
3773 					   pending_event->session_id,
3774 					   pending_event->type,
3775 					   pending_event->mac_addr,
3776 					   pending_event->is_2g_iface, ipa_ctx);
3777 		}
3778 
3779 		if (vdev)
3780 			wlan_objmgr_vdev_release_ref(vdev, WLAN_IPA_ID);
3781 		qdf_mem_free(pending_event);
3782 		pending_event = NULL;
3783 		qdf_list_remove_front(&ipa_ctx->pending_event,
3784 				      (qdf_list_node_t **)&pending_event);
3785 	}
3786 }
3787 
3788 #if !defined(QCA_LL_TX_FLOW_CONTROL_V2) && !defined(QCA_IPA_LL_TX_FLOW_CONTROL)
3789 
3790 /**
3791  * wlan_ipa_free_tx_desc_list() - Free IPA Tx desc list
3792  * @ipa_ctx: IPA context
3793  *
3794  * Return: None
3795  */
3796 static inline void wlan_ipa_free_tx_desc_list(struct wlan_ipa_priv *ipa_ctx)
3797 {
3798 	int i;
3799 	qdf_ipa_rx_data_t *ipa_tx_desc;
3800 	uint32_t pool_size;
3801 
3802 	if (!ipa_ctx->tx_desc_pool)
3803 		return;
3804 
3805 	qdf_spin_lock_bh(&ipa_ctx->q_lock);
3806 	pool_size = ipa_ctx->tx_desc_free_list.max_size;
3807 	for (i = 0; i < pool_size; i++) {
3808 		ipa_tx_desc = ipa_ctx->tx_desc_pool[i].ipa_tx_desc_ptr;
3809 		if (ipa_tx_desc)
3810 			qdf_ipa_free_skb(ipa_tx_desc);
3811 
3812 		if (ipa_ctx->tx_desc_free_list.count &&
3813 		    qdf_list_remove_node(&ipa_ctx->tx_desc_free_list,
3814 					 &ipa_ctx->tx_desc_pool[i].node) !=
3815 							QDF_STATUS_SUCCESS)
3816 			ipa_err("Failed to remove node from tx desc freelist");
3817 	}
3818 	qdf_spin_unlock_bh(&ipa_ctx->q_lock);
3819 
3820 	qdf_list_destroy(&ipa_ctx->tx_desc_free_list);
3821 	qdf_mem_free(ipa_ctx->tx_desc_pool);
3822 	ipa_ctx->tx_desc_pool = NULL;
3823 
3824 	ipa_ctx->stats.num_tx_desc_q_cnt = 0;
3825 	ipa_ctx->stats.num_tx_desc_error = 0;
3826 }
3827 
3828 /**
3829  * wlan_ipa_alloc_tx_desc_free_list() - Allocate IPA Tx desc list
3830  * @ipa_ctx: IPA context
3831  *
3832  * Return: QDF_STATUS
3833  */
3834 static QDF_STATUS
3835 wlan_ipa_alloc_tx_desc_free_list(struct wlan_ipa_priv *ipa_ctx)
3836 {
3837 	int i;
3838 	uint32_t max_desc_cnt;
3839 
3840 	max_desc_cnt = ipa_ctx->config->txbuf_count;
3841 
3842 	ipa_ctx->tx_desc_pool = qdf_mem_malloc(sizeof(struct wlan_ipa_tx_desc) *
3843 					       max_desc_cnt);
3844 	if (!ipa_ctx->tx_desc_pool)
3845 		return QDF_STATUS_E_NOMEM;
3846 
3847 	qdf_list_create(&ipa_ctx->tx_desc_free_list, max_desc_cnt);
3848 
3849 	qdf_spin_lock_bh(&ipa_ctx->q_lock);
3850 	for (i = 0; i < max_desc_cnt; i++) {
3851 		ipa_ctx->tx_desc_pool[i].id = i;
3852 		ipa_ctx->tx_desc_pool[i].ipa_tx_desc_ptr = NULL;
3853 		qdf_list_insert_back(&ipa_ctx->tx_desc_free_list,
3854 				     &ipa_ctx->tx_desc_pool[i].node);
3855 	}
3856 
3857 	ipa_ctx->stats.num_tx_desc_q_cnt = 0;
3858 	ipa_ctx->stats.num_tx_desc_error = 0;
3859 
3860 	qdf_spin_unlock_bh(&ipa_ctx->q_lock);
3861 
3862 	return QDF_STATUS_SUCCESS;
3863 }
3864 
3865 /**
3866  * wlan_ipa_setup_tx_sys_pipe() - Setup IPA Tx system pipes
3867  * @ipa_ctx: Global IPA IPA context
3868  * @desc_fifo_sz: Number of descriptors
3869  *
3870  * Return: 0 on success, negative errno on error
3871  */
3872 static int wlan_ipa_setup_tx_sys_pipe(struct wlan_ipa_priv *ipa_ctx,
3873 				     int32_t desc_fifo_sz)
3874 {
3875 	int i, ret = 0;
3876 	qdf_ipa_sys_connect_params_t *ipa;
3877 
3878 	/*setup TX pipes */
3879 	for (i = 0; i < WLAN_IPA_MAX_IFACE; i++) {
3880 		ipa = &ipa_ctx->sys_pipe[i].ipa_sys_params;
3881 
3882 		ipa->client = wlan_ipa_iface_2_client[i].cons_client;
3883 		ipa->desc_fifo_sz = desc_fifo_sz;
3884 		ipa->priv = &ipa_ctx->iface_context[i];
3885 		ipa->notify = wlan_ipa_i2w_cb;
3886 
3887 		if (wlan_ipa_uc_sta_is_enabled(ipa_ctx->config)) {
3888 			ipa->ipa_ep_cfg.hdr.hdr_len =
3889 				WLAN_IPA_UC_WLAN_TX_HDR_LEN;
3890 			ipa->ipa_ep_cfg.nat.nat_en = IPA_BYPASS_NAT;
3891 			ipa->ipa_ep_cfg.hdr.hdr_ofst_pkt_size_valid = 1;
3892 			ipa->ipa_ep_cfg.hdr.hdr_ofst_pkt_size = 0;
3893 			ipa->ipa_ep_cfg.hdr.hdr_additional_const_len =
3894 				WLAN_IPA_UC_WLAN_8023_HDR_SIZE;
3895 			ipa->ipa_ep_cfg.hdr_ext.hdr_little_endian = true;
3896 		} else {
3897 			ipa->ipa_ep_cfg.hdr.hdr_len = WLAN_IPA_WLAN_TX_HDR_LEN;
3898 		}
3899 		ipa->ipa_ep_cfg.mode.mode = IPA_BASIC;
3900 
3901 		ret = wlan_ipa_wdi_setup_sys_pipe(ipa_ctx, ipa,
3902 				&ipa_ctx->sys_pipe[i].conn_hdl);
3903 		if (ret) {
3904 			ipa_err("Failed for pipe %d ret: %d", i, ret);
3905 			return ret;
3906 		}
3907 		ipa_ctx->sys_pipe[i].conn_hdl_valid = 1;
3908 	}
3909 
3910 	return ret;
3911 }
3912 #else /* QCA_LL_TX_FLOW_CONTROL_V2 */
3913 
3914 /**
3915  * wlan_ipa_free_tx_desc_list() - Free IPA Tx desc list
3916  * @ipa_ctx: IPA context
3917  *
3918  * Return: None
3919  */
3920 static inline void wlan_ipa_free_tx_desc_list(struct wlan_ipa_priv *ipa_ctx)
3921 {
3922 }
3923 
3924 /**
3925  * wlan_ipa_alloc_tx_desc_free_list() - Allocate IPA Tx desc list
3926  * @ipa_ctx: IPA context
3927  *
3928  * Return: QDF_STATUS
3929  */
3930 static QDF_STATUS
3931 wlan_ipa_alloc_tx_desc_free_list(struct wlan_ipa_priv *ipa_ctx)
3932 {
3933 	return QDF_STATUS_SUCCESS;
3934 }
3935 
3936 /**
3937  * wlan_ipa_setup_tx_sys_pipe() - Setup IPA Tx system pipes
3938  * @ipa_ctx: IPA context
3939  * @desc_fifo_sz: Number of descriptors
3940  *
3941  * Return: 0 on success, negative errno on error
3942  */
3943 static int wlan_ipa_setup_tx_sys_pipe(struct wlan_ipa_priv *ipa_ctx,
3944 				     int32_t desc_fifo_sz)
3945 {
3946 	/*
3947 	 * The Tx system pipes are not needed for MCC when TX_FLOW_CONTROL_V2
3948 	 * is enabled, where per vdev descriptors are supported in firmware.
3949 	 */
3950 	return 0;
3951 }
3952 #endif /* QCA_LL_TX_FLOW_CONTROL_V2 */
3953 
3954 #if defined(CONFIG_IPA_WDI_UNIFIED_API) && defined(IPA_WDI3_GSI)
3955 /**
3956  * wlan_ipa_get_rx_ipa_client() - Get IPA RX ipa client
3957  * @ipa_ctx: IPA context
3958  *
3959  * Return: rx ipa sys client
3960  */
3961 static inline uint8_t wlan_ipa_get_rx_ipa_client(struct wlan_ipa_priv *ipa_ctx)
3962 {
3963 	if (ipa_ctx->over_gsi)
3964 		return IPA_CLIENT_WLAN2_PROD;
3965 	else
3966 		return IPA_CLIENT_WLAN1_PROD;
3967 }
3968 
3969 /**
3970  * wlan_ipa_uc_send_wdi_control_msg() - Set WDI control message
3971  * @ipa_ctx: IPA context
3972  * @ctrl: WDI control value
3973  *
3974  * Send WLAN_WDI_ENABLE for ctrl = true and WLAN_WDI_DISABLE otherwise.
3975  *
3976  * Return: QDF_STATUS
3977  */
3978 static QDF_STATUS wlan_ipa_uc_send_wdi_control_msg(struct wlan_ipa_priv *ipa_ctx,
3979 						   bool ctrl)
3980 {
3981 	return QDF_STATUS_SUCCESS;
3982 }
3983 
3984 #else
3985 static inline uint8_t wlan_ipa_get_rx_ipa_client(struct wlan_ipa_priv *ipa_ctx)
3986 {
3987 	return IPA_CLIENT_WLAN1_PROD;
3988 }
3989 
3990 static QDF_STATUS wlan_ipa_uc_send_wdi_control_msg(struct wlan_ipa_priv *ipa_ctx,
3991 						   bool ctrl)
3992 {
3993 	struct wlan_ipa_priv *ipa_obj = ipa_ctx;
3994 	qdf_ipa_msg_meta_t meta;
3995 	qdf_ipa_wlan_msg_t *ipa_msg;
3996 	int ret = 0;
3997 
3998 	/* WDI enable message to IPA */
3999 	QDF_IPA_MSG_META_MSG_LEN(&meta) = sizeof(*ipa_msg);
4000 	ipa_msg = qdf_mem_malloc(QDF_IPA_MSG_META_MSG_LEN(&meta));
4001 	if (!ipa_msg)
4002 		return QDF_STATUS_E_NOMEM;
4003 
4004 	if (ctrl) {
4005 		QDF_IPA_SET_META_MSG_TYPE(&meta, QDF_WDI_ENABLE);
4006 		ipa_obj->stats.event[QDF_WDI_ENABLE]++;
4007 	} else {
4008 		QDF_IPA_SET_META_MSG_TYPE(&meta, QDF_WDI_DISABLE);
4009 		ipa_obj->stats.event[QDF_WDI_DISABLE]++;
4010 	}
4011 
4012 	ipa_debug("ipa_send_msg(Evt:%d)", QDF_IPA_MSG_META_MSG_TYPE(&meta));
4013 	ret = qdf_ipa_send_msg(&meta, ipa_msg, wlan_ipa_msg_free_fn);
4014 	if (ret) {
4015 		ipa_err("ipa_send_msg(Evt:%d)-fail=%d",
4016 			QDF_IPA_MSG_META_MSG_TYPE(&meta), ret);
4017 		qdf_mem_free(ipa_msg);
4018 		return QDF_STATUS_E_FAILURE;
4019 	}
4020 
4021 	return QDF_STATUS_SUCCESS;
4022 }
4023 #endif
4024 
4025 /**
4026  * wlan_ipa_setup_rx_sys_pipe() - Setup IPA Rx system pipes
4027  * @ipa_ctx: Global IPA IPA context
4028  * @desc_fifo_sz: Number of descriptors
4029  *
4030  * Return: 0 on success, negative errno on error
4031  */
4032 static int wlan_ipa_setup_rx_sys_pipe(struct wlan_ipa_priv *ipa_ctx,
4033 				     int32_t desc_fifo_sz)
4034 {
4035 	int ret = 0;
4036 	qdf_ipa_sys_connect_params_t *ipa;
4037 
4038 	/*
4039 	 * Hard code it here, this can be extended if in case
4040 	 * PROD pipe is also per interface.
4041 	 * Right now there is no advantage of doing this.
4042 	 */
4043 	ipa = &ipa_ctx->sys_pipe[WLAN_IPA_RX_PIPE].ipa_sys_params;
4044 
4045 	ipa->client = wlan_ipa_get_rx_ipa_client(ipa_ctx);
4046 	ipa->desc_fifo_sz = desc_fifo_sz;
4047 	ipa->priv = ipa_ctx;
4048 	ipa->notify = wlan_ipa_w2i_cb;
4049 
4050 	ipa->ipa_ep_cfg.nat.nat_en = IPA_BYPASS_NAT;
4051 	ipa->ipa_ep_cfg.hdr.hdr_len = WLAN_IPA_WLAN_RX_HDR_LEN;
4052 	ipa->ipa_ep_cfg.hdr.hdr_ofst_metadata_valid = 1;
4053 	ipa->ipa_ep_cfg.mode.mode = IPA_BASIC;
4054 
4055 	ret = qdf_ipa_setup_sys_pipe(ipa,
4056 			&ipa_ctx->sys_pipe[WLAN_IPA_RX_PIPE].conn_hdl);
4057 	if (ret) {
4058 		ipa_err("Failed for RX pipe: %d", ret);
4059 		return ret;
4060 	}
4061 	ipa_ctx->sys_pipe[WLAN_IPA_RX_PIPE].conn_hdl_valid = 1;
4062 
4063 	return ret;
4064 }
4065 
4066 /**
4067  * wlan_ipa_teardown_sys_pipe() - Tear down all IPA Sys pipes
4068  * @ipa_ctx: Global IPA IPA context
4069  *
4070  * Return: None
4071  */
4072 static void wlan_ipa_teardown_sys_pipe(struct wlan_ipa_priv *ipa_ctx)
4073 {
4074 	int ret, i;
4075 
4076 	if (!ipa_ctx)
4077 		return;
4078 
4079 	for (i = 0; i < WLAN_IPA_MAX_SYSBAM_PIPE; i++) {
4080 		if (ipa_ctx->sys_pipe[i].conn_hdl_valid) {
4081 			ret = wlan_ipa_wdi_teardown_sys_pipe(ipa_ctx,
4082 							     ipa_ctx->sys_pipe[i].conn_hdl);
4083 			if (ret)
4084 				ipa_err("Failed:%d", ret);
4085 
4086 			ipa_ctx->sys_pipe[i].conn_hdl_valid = 0;
4087 		}
4088 	}
4089 
4090 	wlan_ipa_free_tx_desc_list(ipa_ctx);
4091 }
4092 
4093 /**
4094  * wlan_ipa_setup_sys_pipe() - Setup all IPA system pipes
4095  * @ipa_ctx: Global IPA IPA context
4096  *
4097  * Return: 0 on success, negative errno on error
4098  */
4099 static int wlan_ipa_setup_sys_pipe(struct wlan_ipa_priv *ipa_ctx)
4100 {
4101 	int ret = 0;
4102 	uint32_t desc_fifo_sz;
4103 
4104 	/* The maximum number of descriptors that can be provided to a BAM at
4105 	 * once is one less than the total number of descriptors that the buffer
4106 	 * can contain.
4107 	 * If max_num_of_descriptors = (BAM_PIPE_DESCRIPTOR_FIFO_SIZE / sizeof
4108 	 * (SPS_DESCRIPTOR)), then (max_num_of_descriptors - 1) descriptors can
4109 	 * be provided at once.
4110 	 * Because of above requirement, one extra descriptor will be added to
4111 	 * make sure hardware always has one descriptor.
4112 	 */
4113 	desc_fifo_sz = ipa_ctx->config->desc_size + IPA_SPS_DESC_SIZE;
4114 
4115 	ret = wlan_ipa_setup_tx_sys_pipe(ipa_ctx, desc_fifo_sz);
4116 	if (ret) {
4117 		ipa_err("Failed for TX pipe: %d", ret);
4118 		goto setup_sys_pipe_fail;
4119 	}
4120 
4121 	if (!wlan_ipa_uc_sta_is_enabled(ipa_ctx->config)) {
4122 		ret = wlan_ipa_setup_rx_sys_pipe(ipa_ctx, desc_fifo_sz);
4123 		if (ret) {
4124 			ipa_err("Failed for RX pipe: %d", ret);
4125 			goto setup_sys_pipe_fail;
4126 		}
4127 	}
4128 
4129        /* Allocate free Tx desc list */
4130 	ret = wlan_ipa_alloc_tx_desc_free_list(ipa_ctx);
4131 	if (ret)
4132 		goto setup_sys_pipe_fail;
4133 
4134 	return ret;
4135 
4136 setup_sys_pipe_fail:
4137 	wlan_ipa_teardown_sys_pipe(ipa_ctx);
4138 
4139 	return ret;
4140 }
4141 
4142 #if !defined(QCA_LL_TX_FLOW_CONTROL_V2) && !defined(QCA_IPA_LL_TX_FLOW_CONTROL)
4143 QDF_STATUS wlan_ipa_send_mcc_scc_msg(struct wlan_ipa_priv *ipa_ctx,
4144 				     bool mcc_mode)
4145 {
4146 	qdf_ipa_msg_meta_t meta;
4147 	qdf_ipa_wlan_msg_t *msg;
4148 	int ret;
4149 
4150 	if (!wlan_ipa_uc_sta_is_enabled(ipa_ctx->config))
4151 		return QDF_STATUS_SUCCESS;
4152 
4153 	/* Send SCC/MCC Switching event to IPA */
4154 	QDF_IPA_MSG_META_MSG_LEN(&meta) = sizeof(*msg);
4155 	msg = qdf_mem_malloc(QDF_IPA_MSG_META_MSG_LEN(&meta));
4156 	if (!msg)
4157 		return QDF_STATUS_E_NOMEM;
4158 
4159 	if (mcc_mode) {
4160 		QDF_IPA_SET_META_MSG_TYPE(&meta, QDF_SWITCH_TO_MCC);
4161 		ipa_ctx->stats.event[QDF_SWITCH_TO_MCC]++;
4162 	} else {
4163 		QDF_IPA_SET_META_MSG_TYPE(&meta, QDF_SWITCH_TO_SCC);
4164 		ipa_ctx->stats.event[QDF_SWITCH_TO_SCC]++;
4165 	}
4166 
4167 	WLAN_IPA_LOG(QDF_TRACE_LEVEL_DEBUG,
4168 		    "ipa_send_msg(Evt:%d)",
4169 		    QDF_IPA_MSG_META_MSG_TYPE(&meta));
4170 
4171 	ret = qdf_ipa_send_msg(&meta, msg, wlan_ipa_msg_free_fn);
4172 
4173 	if (ret) {
4174 		ipa_err("ipa_send_msg(Evt:%d) - fail=%d",
4175 			QDF_IPA_MSG_META_MSG_TYPE(&meta), ret);
4176 		qdf_mem_free(msg);
4177 		return QDF_STATUS_E_FAILURE;
4178 	}
4179 
4180 	return QDF_STATUS_SUCCESS;
4181 }
4182 
4183 static void wlan_ipa_mcc_work_handler(void *data)
4184 {
4185 	struct wlan_ipa_priv *ipa_ctx = (struct wlan_ipa_priv *)data;
4186 
4187 	wlan_ipa_send_mcc_scc_msg(ipa_ctx, ipa_ctx->mcc_mode);
4188 }
4189 #endif
4190 
4191 #ifdef IPA_OPT_WIFI_DP
4192 /**
4193  * wlan_ipa_reg_flt_cbs() - register filter cbs with IPA to set up Rx CCE filter
4194  * rules for optional wifi datapath
4195  * @ipa_ctx: IPA context
4196  *
4197  *
4198  * Return: QDF_STATUS enumeration
4199  */
4200 static inline QDF_STATUS wlan_ipa_reg_flt_cbs(struct wlan_ipa_priv *ipa_ctx)
4201 {
4202 	QDF_STATUS status;
4203 
4204 	ipa_wdi_opt_dpath_flt_rsrv_cb flt_rsrv_cb =
4205 					    &wlan_ipa_wdi_opt_dpath_flt_rsrv_cb;
4206 	ipa_wdi_opt_dpath_flt_rsrv_rel_cb
4207 		flt_rsrv_rel_cb = &wlan_ipa_wdi_opt_dpath_flt_rsrv_rel_cb;
4208 	ipa_wdi_opt_dpath_flt_rem_cb flt_rem_cb =
4209 					     &wlan_ipa_wdi_opt_dpath_flt_rem_cb;
4210 	ipa_wdi_opt_dpath_flt_add_cb flt_add_cb =
4211 					     &wlan_ipa_wdi_opt_dpath_flt_add_cb;
4212 
4213 	ipa_info("opt_dp: ipa_reg_flt_cb");
4214 	status = qdf_ipa_wdi_register_flt_cb(ipa_ctx->hdl, flt_rsrv_cb,
4215 					     flt_rsrv_rel_cb,
4216 					     flt_add_cb,
4217 					     flt_rem_cb);
4218 	return status;
4219 }
4220 
4221 /**
4222  * wlan_ipa_opt_dp_init() - Check if OPT_WIFI_DP enabled from both IPA
4223  * and WLAN, and perform required init steps
4224  * @ipa_ctx: IPA context
4225  *
4226  *
4227  * Return: QDF_STATUS enumeration
4228  */
4229 static inline
4230 QDF_STATUS wlan_ipa_opt_dp_init(struct wlan_ipa_priv *ipa_ctx)
4231 {
4232 	QDF_STATUS status = QDF_STATUS_SUCCESS;
4233 
4234 	/* Register call backs for opt wifi dp */
4235 	if (ipa_ctx->opt_wifi_datapath) {
4236 		if (ipa_config_is_opt_wifi_dp_enabled()) {
4237 			status = wlan_ipa_reg_flt_cbs(ipa_ctx);
4238 			ipa_info("opt_dp: Register flt cb. status %d", status);
4239 			qdf_wake_lock_create(&ipa_ctx->opt_dp_wake_lock,
4240 					     "opt_dp");
4241 		} else {
4242 			ipa_info("opt_dp: Disabled from WLAN INI");
4243 		}
4244 	} else {
4245 		ipa_info("opt_dp: Disabled from IPA");
4246 	}
4247 
4248 	return status;
4249 }
4250 
4251 /**
4252  * wlan_ipa_destroy_opt_wifi_flt_cb_event - destroy filter cb event
4253  * @ipa_ctx: IPA context
4254  *
4255  *Return: void
4256  */
4257 static inline
4258 void wlan_ipa_destroy_opt_wifi_flt_cb_event(struct wlan_ipa_priv *ipa_ctx)
4259 {
4260 	qdf_event_destroy(&ipa_ctx->ipa_flt_evnt);
4261 }
4262 
4263 /**
4264  * wlan_ipa_opt_dp_deinit() - Perform opt_wifi_dp deinit steps
4265  * @ipa_ctx: IPA context
4266  *
4267  * Return: None
4268  */
4269 static inline
4270 void wlan_ipa_opt_dp_deinit(struct wlan_ipa_priv *ipa_ctx)
4271 {
4272 	if (ipa_ctx->uc_loaded)
4273 		wlan_ipa_destroy_opt_wifi_flt_cb_event(ipa_ctx);
4274 
4275 	if (ipa_ctx->opt_wifi_datapath && ipa_config_is_opt_wifi_dp_enabled())
4276 		qdf_wake_lock_destroy(&ipa_ctx->opt_dp_wake_lock);
4277 }
4278 
4279 #else
4280 static inline QDF_STATUS wlan_ipa_reg_flt_cbs(struct wlan_ipa_priv *ipa_ctx)
4281 {
4282 	return QDF_STATUS_SUCCESS;
4283 }
4284 
4285 static inline
4286 QDF_STATUS wlan_ipa_opt_dp_init(struct wlan_ipa_priv *ipa_ctx)
4287 {
4288 	return QDF_STATUS_SUCCESS;
4289 }
4290 
4291 static inline
4292 void wlan_ipa_destroy_opt_wifi_flt_cb_event(struct wlan_ipa_priv *ipa_ctx)
4293 {
4294 }
4295 
4296 static inline
4297 void wlan_ipa_opt_dp_deinit(struct wlan_ipa_priv *ipa_ctx)
4298 {
4299 }
4300 #endif
4301 
4302 /**
4303  * wlan_ipa_setup() - IPA initialization function
4304  * @ipa_ctx: IPA context
4305  * @ipa_cfg: IPA config
4306  *
4307  * Allocate ipa_ctx resources, ipa pipe resource and register
4308  * wlan interface with IPA module.
4309  *
4310  * Return: QDF_STATUS enumeration
4311  */
4312 QDF_STATUS wlan_ipa_setup(struct wlan_ipa_priv *ipa_ctx,
4313 			  struct wlan_ipa_config *ipa_cfg)
4314 {
4315 	int ret, i;
4316 	struct wlan_ipa_iface_context *iface_context = NULL;
4317 	QDF_STATUS status;
4318 
4319 	ipa_debug("enter");
4320 
4321 	gp_ipa = ipa_ctx;
4322 	ipa_ctx->num_iface = 0;
4323 	ipa_ctx->config = ipa_cfg;
4324 
4325 	wlan_ipa_wdi_get_wdi_version(ipa_ctx);
4326 
4327 	/* Create the interface context */
4328 	for (i = 0; i < WLAN_IPA_MAX_IFACE; i++) {
4329 		iface_context = &ipa_ctx->iface_context[i];
4330 		iface_context->ipa_ctx = ipa_ctx;
4331 		iface_context->cons_client =
4332 			wlan_ipa_iface_2_client[i].cons_client;
4333 		iface_context->prod_client =
4334 			wlan_ipa_iface_2_client[i].prod_client;
4335 		iface_context->iface_id = i;
4336 		iface_context->dev = NULL;
4337 		iface_context->device_mode = QDF_MAX_NO_OF_MODE;
4338 		iface_context->session_id = WLAN_IPA_MAX_SESSION;
4339 		qdf_atomic_init(&iface_context->conn_count);
4340 		qdf_atomic_init(&iface_context->disconn_count);
4341 		qdf_spinlock_create(&iface_context->interface_lock);
4342 	}
4343 
4344 	qdf_create_work(0, &ipa_ctx->pm_work, wlan_ipa_pm_flush, ipa_ctx);
4345 	qdf_spinlock_create(&ipa_ctx->pm_lock);
4346 	qdf_spinlock_create(&ipa_ctx->q_lock);
4347 	qdf_spinlock_create(&ipa_ctx->enable_disable_lock);
4348 	ipa_ctx->pipes_down_in_progress = false;
4349 	ipa_ctx->pipes_enable_in_progress = false;
4350 	qdf_nbuf_queue_init(&ipa_ctx->pm_queue_head);
4351 	qdf_list_create(&ipa_ctx->pending_event, 1000);
4352 	qdf_mutex_create(&ipa_ctx->event_lock);
4353 	qdf_mutex_create(&ipa_ctx->ipa_lock);
4354 	qdf_atomic_init(&ipa_ctx->deinit_in_prog);
4355 
4356 	cdp_ipa_set_smmu_mapped(ipa_ctx->dp_soc, 0);
4357 
4358 	status = wlan_ipa_wdi_setup_rm(ipa_ctx);
4359 	if (status != QDF_STATUS_SUCCESS)
4360 		goto fail_setup_rm;
4361 
4362 	for (i = 0; i < WLAN_IPA_MAX_SYSBAM_PIPE; i++)
4363 		qdf_mem_zero(&ipa_ctx->sys_pipe[i],
4364 			     sizeof(struct wlan_ipa_sys_pipe));
4365 
4366 	if (wlan_ipa_uc_is_enabled(ipa_ctx->config)) {
4367 		qdf_mem_zero(&ipa_ctx->stats, sizeof(ipa_ctx->stats));
4368 		ipa_ctx->sap_num_connected_sta = 0;
4369 		ipa_ctx->ipa_tx_packets_diff = 0;
4370 		ipa_ctx->ipa_rx_packets_diff = 0;
4371 		ipa_ctx->ipa_p_tx_packets = 0;
4372 		ipa_ctx->ipa_p_rx_packets = 0;
4373 		ipa_ctx->resource_loading = false;
4374 		ipa_ctx->resource_unloading = false;
4375 		ipa_ctx->num_sap_connected = 0;
4376 		ipa_ctx->sta_connected = 0;
4377 		ipa_ctx->ipa_pipes_down = true;
4378 		qdf_atomic_set(&ipa_ctx->pipes_disabled, 1);
4379 		qdf_atomic_set(&ipa_ctx->autonomy_disabled, 1);
4380 		ipa_ctx->wdi_enabled = false;
4381 
4382 		status = wlan_ipa_wdi_init(ipa_ctx);
4383 
4384 		if (status == QDF_STATUS_SUCCESS) {
4385 			/* Setup IPA system pipes */
4386 			if (wlan_ipa_uc_sta_is_enabled(ipa_ctx->config)) {
4387 				ret = wlan_ipa_setup_sys_pipe(ipa_ctx);
4388 				if (ret)
4389 					goto ipa_wdi_destroy;
4390 
4391 				qdf_create_work(0, &ipa_ctx->mcc_work,
4392 						wlan_ipa_mcc_work_handler,
4393 						ipa_ctx);
4394 			}
4395 		} else if (status == QDF_STATUS_E_BUSY) {
4396 			ret = wlan_ipa_uc_send_wdi_control_msg(ipa_ctx, false);
4397 			if (ret) {
4398 				ipa_err("IPA WDI msg send failed: ret=%d", ret);
4399 				goto ipa_wdi_destroy;
4400 			}
4401 		} else {
4402 			ipa_err("IPA WDI init failed: ret=%d", status);
4403 			goto ipa_wdi_destroy;
4404 		}
4405 	} else {
4406 		ret = wlan_ipa_setup_sys_pipe(ipa_ctx);
4407 		if (ret)
4408 			goto ipa_wdi_destroy;
4409 	}
4410 
4411 	status = wlan_ipa_opt_dp_init(ipa_ctx);
4412 
4413 	qdf_event_create(&ipa_ctx->ipa_resource_comp);
4414 
4415 	ipa_debug("exit: success");
4416 
4417 	return QDF_STATUS_SUCCESS;
4418 
4419 ipa_wdi_destroy:
4420 	wlan_ipa_wdi_destroy_rm(ipa_ctx);
4421 
4422 fail_setup_rm:
4423 	qdf_spinlock_destroy(&ipa_ctx->pm_lock);
4424 	qdf_spinlock_destroy(&ipa_ctx->q_lock);
4425 	qdf_spinlock_destroy(&ipa_ctx->enable_disable_lock);
4426 	for (i = 0; i < WLAN_IPA_MAX_IFACE; i++) {
4427 		iface_context = &ipa_ctx->iface_context[i];
4428 		qdf_spinlock_destroy(&iface_context->interface_lock);
4429 	}
4430 	qdf_mutex_destroy(&ipa_ctx->event_lock);
4431 	qdf_mutex_destroy(&ipa_ctx->ipa_lock);
4432 	qdf_list_destroy(&ipa_ctx->pending_event);
4433 	gp_ipa = NULL;
4434 	ipa_debug("exit: fail");
4435 
4436 	return QDF_STATUS_E_FAILURE;
4437 }
4438 
4439 void wlan_ipa_flush(struct wlan_ipa_priv *ipa_ctx)
4440 {
4441 	qdf_nbuf_t skb;
4442 	struct wlan_ipa_pm_tx_cb *pm_tx_cb;
4443 
4444 	if (!wlan_ipa_is_enabled(ipa_ctx->config))
4445 		return;
4446 
4447 	qdf_cancel_work(&ipa_ctx->pm_work);
4448 
4449 	qdf_spin_lock_bh(&ipa_ctx->pm_lock);
4450 
4451 	while (((skb = qdf_nbuf_queue_remove(&ipa_ctx->pm_queue_head))
4452 	       != NULL)) {
4453 		qdf_spin_unlock_bh(&ipa_ctx->pm_lock);
4454 
4455 		pm_tx_cb = (struct wlan_ipa_pm_tx_cb *)skb->cb;
4456 
4457 		if (pm_tx_cb->exception || pm_tx_cb->send_to_nw) {
4458 			dev_kfree_skb_any(skb);
4459 		} else {
4460 			if (pm_tx_cb->ipa_tx_desc)
4461 				ipa_free_skb(pm_tx_cb->ipa_tx_desc);
4462 		}
4463 
4464 		qdf_spin_lock_bh(&ipa_ctx->pm_lock);
4465 	}
4466 	qdf_spin_unlock_bh(&ipa_ctx->pm_lock);
4467 }
4468 
4469 QDF_STATUS wlan_ipa_cleanup(struct wlan_ipa_priv *ipa_ctx)
4470 {
4471 	struct wlan_ipa_iface_context *iface_context;
4472 	int i;
4473 
4474 	if (!ipa_cb_is_ready())
4475 		return QDF_STATUS_SUCCESS;
4476 	qdf_event_destroy(&ipa_ctx->ipa_resource_comp);
4477 	if (!wlan_ipa_uc_is_enabled(ipa_ctx->config))
4478 		wlan_ipa_teardown_sys_pipe(ipa_ctx);
4479 
4480 	wlan_ipa_opt_dp_deinit(ipa_ctx);
4481 
4482 	/* Teardown IPA sys_pipe for MCC */
4483 	if (wlan_ipa_uc_sta_is_enabled(ipa_ctx->config)) {
4484 		wlan_ipa_teardown_sys_pipe(ipa_ctx);
4485 		if (ipa_ctx->uc_loaded)
4486 			qdf_cancel_work(&ipa_ctx->mcc_work);
4487 	}
4488 
4489 	wlan_ipa_wdi_destroy_rm(ipa_ctx);
4490 
4491 	wlan_ipa_flush(ipa_ctx);
4492 
4493 	qdf_spinlock_destroy(&ipa_ctx->pm_lock);
4494 	qdf_spinlock_destroy(&ipa_ctx->q_lock);
4495 	qdf_spinlock_destroy(&ipa_ctx->enable_disable_lock);
4496 	qdf_destroy_work(0, &ipa_ctx->pm_work);
4497 
4498 	/* destroy the interface lock */
4499 	for (i = 0; i < WLAN_IPA_MAX_IFACE; i++) {
4500 		iface_context = &ipa_ctx->iface_context[i];
4501 		qdf_spinlock_destroy(&iface_context->interface_lock);
4502 	}
4503 
4504 	if (wlan_ipa_uc_is_enabled(ipa_ctx->config)) {
4505 		wlan_ipa_wdi_cleanup(ipa_ctx->hdl);
4506 		qdf_mutex_destroy(&ipa_ctx->event_lock);
4507 		qdf_mutex_destroy(&ipa_ctx->ipa_lock);
4508 		qdf_list_destroy(&ipa_ctx->pending_event);
4509 
4510 	}
4511 
4512 	gp_ipa = NULL;
4513 
4514 	ipa_ctx->handle_initialized = false;
4515 
4516 	return QDF_STATUS_SUCCESS;
4517 }
4518 
4519 struct wlan_ipa_iface_context
4520 *wlan_ipa_get_iface(struct wlan_ipa_priv *ipa_ctx, uint8_t mode)
4521 {
4522 	struct wlan_ipa_iface_context *iface_ctx = NULL;
4523 	int i;
4524 
4525 	for (i = 0; i < WLAN_IPA_MAX_IFACE; i++) {
4526 		iface_ctx = &ipa_ctx->iface_context[i];
4527 
4528 		if (iface_ctx->device_mode == mode)
4529 			return iface_ctx;
4530 	}
4531 
4532 	return NULL;
4533 }
4534 
4535 struct wlan_ipa_iface_context *
4536 wlan_ipa_get_iface_by_mode_netdev(struct wlan_ipa_priv *ipa_ctx,
4537 				  qdf_netdev_t ndev, uint8_t mode)
4538 {
4539 	struct wlan_ipa_iface_context *iface_ctx = NULL;
4540 	int i;
4541 
4542 	for (i = 0; i < WLAN_IPA_MAX_IFACE; i++) {
4543 		iface_ctx = &ipa_ctx->iface_context[i];
4544 
4545 		if (iface_ctx->device_mode == mode && iface_ctx->dev == ndev)
4546 			return iface_ctx;
4547 	}
4548 
4549 	return NULL;
4550 }
4551 
4552 void wlan_ipa_set_mcc_mode(struct wlan_ipa_priv *ipa_ctx, bool mcc_mode)
4553 {
4554 	if (!wlan_ipa_uc_sta_is_enabled(ipa_ctx->config))
4555 		return;
4556 
4557 	if (ipa_ctx->mcc_mode == mcc_mode)
4558 		return;
4559 
4560 	ipa_ctx->mcc_mode = mcc_mode;
4561 	qdf_sched_work(0, &ipa_ctx->mcc_work);
4562 }
4563 
4564 /**
4565  * wlan_ipa_uc_loaded_handler() - Process IPA uC loaded indication
4566  * @ipa_ctx: ipa ipa local context
4567  *
4568  * Will handle IPA UC image loaded indication comes from IPA kernel
4569  *
4570  * Return: None
4571  */
4572 static void wlan_ipa_uc_loaded_handler(struct wlan_ipa_priv *ipa_ctx)
4573 {
4574 	struct wlan_objmgr_pdev *pdev = ipa_ctx->pdev;
4575 	struct wlan_objmgr_psoc *psoc = wlan_pdev_get_psoc(pdev);
4576 	qdf_device_t qdf_dev = wlan_psoc_get_qdf_dev(psoc);
4577 	QDF_STATUS status;
4578 
4579 	ipa_info("UC READY");
4580 
4581 	if (true == ipa_ctx->uc_loaded) {
4582 		ipa_info("UC already loaded");
4583 		return;
4584 	}
4585 
4586 	if (!qdf_dev) {
4587 		ipa_err("qdf_dev is null");
4588 		return;
4589 	}
4590 
4591 	if (wlan_ipa_uc_sta_is_enabled(ipa_ctx->config)) {
4592 		/* Setup IPA system pipes */
4593 		status = wlan_ipa_setup_sys_pipe(ipa_ctx);
4594 		if (status) {
4595 			ipa_err("Fail to setup sys pipes (status=%d)", status);
4596 			return;
4597 		}
4598 		qdf_create_work(0, &ipa_ctx->mcc_work,
4599 				wlan_ipa_mcc_work_handler, ipa_ctx);
4600 	}
4601 
4602 	/* Connect pipe */
4603 	status = wlan_ipa_wdi_setup(ipa_ctx, qdf_dev);
4604 	if (status) {
4605 		ipa_err("Failure to setup IPA pipes (status=%d)",
4606 			status);
4607 		goto connect_pipe_fail;
4608 	}
4609 	/* Setup the Tx buffer SMMU mappings */
4610 	status = cdp_ipa_tx_buf_smmu_mapping(ipa_ctx->dp_soc,
4611 					     ipa_ctx->dp_pdev_id,
4612 					     __func__, __LINE__);
4613 	if (status) {
4614 		ipa_err("Failure to map Tx buffers for IPA(status=%d)",
4615 			status);
4616 		goto smmu_map_fail;
4617 	}
4618 	ipa_info("TX buffers mapped to IPA");
4619 	cdp_ipa_set_doorbell_paddr(ipa_ctx->dp_soc, ipa_ctx->dp_pdev_id);
4620 	wlan_ipa_init_metering(ipa_ctx);
4621 	wlan_ipa_add_rem_flt_cb_event(ipa_ctx);
4622 	if (QDF_IS_STATUS_ERROR(wlan_ipa_init_perf_level(ipa_ctx)))
4623 		ipa_err("Failed to init perf level");
4624 
4625 	/*
4626 	 * Enable IPA/FW PIPEs if
4627 	 * 1. any clients connected to SAP or
4628 	 * 2. STA connected to remote AP if STA only offload is enabled
4629 	 */
4630 	if (ipa_ctx->sap_num_connected_sta ||
4631 	    (wlan_ipa_is_sta_only_offload_enabled() &&
4632 	     ipa_ctx->sta_connected)) {
4633 		ipa_debug("Client already connected, enable IPA/FW PIPEs");
4634 		wlan_ipa_uc_handle_first_con(ipa_ctx);
4635 	}
4636 
4637 	ipa_ctx->uc_loaded = true;
4638 
4639 	return;
4640 
4641 smmu_map_fail:
4642 	qdf_ipa_wdi_disconn_pipes(ipa_ctx->hdl);
4643 
4644 connect_pipe_fail:
4645 	if (wlan_ipa_uc_sta_is_enabled(ipa_ctx->config)) {
4646 		qdf_cancel_work(&ipa_ctx->mcc_work);
4647 		wlan_ipa_teardown_sys_pipe(ipa_ctx);
4648 	}
4649 }
4650 
4651 /**
4652  * wlan_ipa_uc_op_cb() - IPA uC operation callback
4653  * @op_msg: operation message received from firmware
4654  * @ipa_ctx: IPA context
4655  *
4656  * Return: None
4657  */
4658 static void wlan_ipa_uc_op_cb(struct op_msg_type *op_msg,
4659 			      struct wlan_ipa_priv *ipa_ctx)
4660 {
4661 	struct op_msg_type *msg = op_msg;
4662 	struct ipa_uc_fw_stats *uc_fw_stat;
4663 
4664 	if (!ipa_ctx || !op_msg) {
4665 		ipa_err("INVALID ARG");
4666 		return;
4667 	}
4668 
4669 	if (msg->op_code >= WLAN_IPA_UC_OPCODE_MAX) {
4670 		ipa_err("INVALID OPCODE %d",  msg->op_code);
4671 		qdf_mem_free(op_msg);
4672 		return;
4673 	}
4674 
4675 	ipa_debug("OPCODE=%d", msg->op_code);
4676 
4677 	if ((msg->op_code == WLAN_IPA_UC_OPCODE_TX_RESUME) ||
4678 	    (msg->op_code == WLAN_IPA_UC_OPCODE_RX_RESUME)) {
4679 		qdf_mutex_acquire(&ipa_ctx->ipa_lock);
4680 		ipa_ctx->activated_fw_pipe++;
4681 		if (wlan_ipa_is_fw_wdi_activated(ipa_ctx)) {
4682 			ipa_ctx->resource_loading = false;
4683 			qdf_event_set(&ipa_ctx->ipa_resource_comp);
4684 			if (ipa_ctx->wdi_enabled == false) {
4685 				ipa_ctx->wdi_enabled = true;
4686 				if (wlan_ipa_uc_send_wdi_control_msg(ipa_ctx, true) == 0)
4687 					wlan_ipa_send_mcc_scc_msg(ipa_ctx,
4688 							ipa_ctx->mcc_mode);
4689 			}
4690 			wlan_ipa_uc_proc_pending_event(ipa_ctx, true);
4691 			if (ipa_ctx->pending_cons_req)
4692 				wlan_ipa_wdi_rm_notify_completion(
4693 						QDF_IPA_RM_RESOURCE_GRANTED,
4694 						QDF_IPA_RM_RESOURCE_WLAN_CONS);
4695 			ipa_ctx->pending_cons_req = false;
4696 		}
4697 		qdf_mutex_release(&ipa_ctx->ipa_lock);
4698 	} else if ((msg->op_code == WLAN_IPA_UC_OPCODE_TX_SUSPEND) ||
4699 	    (msg->op_code == WLAN_IPA_UC_OPCODE_RX_SUSPEND)) {
4700 		qdf_mutex_acquire(&ipa_ctx->ipa_lock);
4701 
4702 		if (msg->op_code == WLAN_IPA_UC_OPCODE_RX_SUSPEND) {
4703 			wlan_ipa_uc_disable_pipes(ipa_ctx, true);
4704 			ipa_info("Disable FW TX PIPE");
4705 			cdp_ipa_set_active(ipa_ctx->dp_soc, ipa_ctx->dp_pdev_id,
4706 					   false, true);
4707 		}
4708 
4709 		ipa_ctx->activated_fw_pipe--;
4710 		if (!ipa_ctx->activated_fw_pipe) {
4711 			/*
4712 			 * Async return success from FW
4713 			 * Disable/suspend all the PIPEs
4714 			 */
4715 			ipa_ctx->resource_unloading = false;
4716 			qdf_event_set(&ipa_ctx->ipa_resource_comp);
4717 			if (wlan_ipa_is_rm_enabled(ipa_ctx->config))
4718 				wlan_ipa_wdi_rm_release_resource(ipa_ctx,
4719 						QDF_IPA_RM_RESOURCE_WLAN_PROD);
4720 			wlan_ipa_uc_proc_pending_event(ipa_ctx, false);
4721 			ipa_ctx->pending_cons_req = false;
4722 		}
4723 		qdf_mutex_release(&ipa_ctx->ipa_lock);
4724 	} else if ((msg->op_code == WLAN_IPA_UC_OPCODE_STATS) &&
4725 		(ipa_ctx->stat_req_reason == WLAN_IPA_UC_STAT_REASON_DEBUG)) {
4726 		uc_fw_stat = (struct ipa_uc_fw_stats *)
4727 			((uint8_t *)op_msg + sizeof(struct op_msg_type));
4728 
4729 		/* WLAN FW WDI stats */
4730 		wlan_ipa_print_fw_wdi_stats(ipa_ctx, uc_fw_stat);
4731 	} else if ((msg->op_code == WLAN_IPA_UC_OPCODE_STATS) &&
4732 		(ipa_ctx->stat_req_reason == WLAN_IPA_UC_STAT_REASON_BW_CAL)) {
4733 		/* STATs from FW */
4734 		uc_fw_stat = (struct ipa_uc_fw_stats *)
4735 			((uint8_t *)op_msg + sizeof(struct op_msg_type));
4736 		qdf_mutex_acquire(&ipa_ctx->ipa_lock);
4737 		ipa_ctx->ipa_tx_packets_diff = BW_GET_DIFF(
4738 			uc_fw_stat->tx_pkts_completed,
4739 			ipa_ctx->ipa_p_tx_packets);
4740 		ipa_ctx->ipa_rx_packets_diff = BW_GET_DIFF(
4741 			(uc_fw_stat->rx_num_ind_drop_no_space +
4742 			uc_fw_stat->rx_num_ind_drop_no_buf +
4743 			uc_fw_stat->rx_num_pkts_indicated),
4744 			ipa_ctx->ipa_p_rx_packets);
4745 
4746 		ipa_ctx->ipa_p_tx_packets = uc_fw_stat->tx_pkts_completed;
4747 		ipa_ctx->ipa_p_rx_packets =
4748 			(uc_fw_stat->rx_num_ind_drop_no_space +
4749 			uc_fw_stat->rx_num_ind_drop_no_buf +
4750 			uc_fw_stat->rx_num_pkts_indicated);
4751 		qdf_mutex_release(&ipa_ctx->ipa_lock);
4752 	} else if (msg->op_code == WLAN_IPA_UC_OPCODE_UC_READY) {
4753 		qdf_mutex_acquire(&ipa_ctx->ipa_lock);
4754 		wlan_ipa_uc_loaded_handler(ipa_ctx);
4755 		qdf_mutex_release(&ipa_ctx->ipa_lock);
4756 	} else if (msg->op_code == WLAN_IPA_FILTER_RSV_NOTIFY) {
4757 		ipa_info("opt_dp: IPA notify filter resrv response: %d",
4758 			 msg->rsvd);
4759 		qdf_mutex_acquire(&ipa_ctx->ipa_lock);
4760 		qdf_ipa_wdi_opt_dpath_notify_flt_rsvd_per_inst(ipa_ctx->hdl,
4761 							       msg->rsvd);
4762 		qdf_mutex_release(&ipa_ctx->ipa_lock);
4763 	} else if (msg->op_code == WLAN_IPA_FILTER_REL_NOTIFY) {
4764 		ipa_info("opt_dp: IPA notify filter rel_response: %d",
4765 			 msg->rsvd);
4766 		qdf_mutex_acquire(&ipa_ctx->ipa_lock);
4767 		qdf_ipa_wdi_opt_dpath_notify_flt_rlsd_per_inst(ipa_ctx->hdl,
4768 							       msg->rsvd);
4769 		qdf_mutex_release(&ipa_ctx->ipa_lock);
4770 	} else if (msg->op_code == WLAN_IPA_SMMU_MAP) {
4771 		ipa_info("opt_dp: IPA smmu pool map");
4772 		qdf_mutex_acquire(&ipa_ctx->ipa_lock);
4773 		cdp_ipa_rx_buf_smmu_pool_mapping(ipa_ctx->dp_soc,
4774 						 ipa_ctx->dp_pdev_id, true,
4775 						 __func__, __LINE__);
4776 		qdf_mutex_release(&ipa_ctx->ipa_lock);
4777 	} else if (msg->op_code == WLAN_IPA_SMMU_UNMAP) {
4778 		ipa_info("opt_dp: IPA smmu pool unmap");
4779 		qdf_mutex_acquire(&ipa_ctx->ipa_lock);
4780 		cdp_ipa_rx_buf_smmu_pool_mapping(ipa_ctx->dp_soc,
4781 						 ipa_ctx->dp_pdev_id,
4782 						 false, __func__, __LINE__);
4783 		qdf_mutex_release(&ipa_ctx->ipa_lock);
4784 	} else if (wlan_ipa_uc_op_metering(ipa_ctx, op_msg)) {
4785 		ipa_err("Invalid message: op_code=%d, reason=%d",
4786 			msg->op_code, ipa_ctx->stat_req_reason);
4787 	}
4788 
4789 	qdf_mem_free(op_msg);
4790 }
4791 
4792 /**
4793  * __wlan_ipa_uc_fw_op_event_handler - IPA uC FW OPvent handler
4794  * @data: uC OP work
4795  *
4796  * Return: None
4797  */
4798 static void __wlan_ipa_uc_fw_op_event_handler(void *data)
4799 {
4800 	struct op_msg_type *msg;
4801 	struct uc_op_work_struct *uc_op_work =
4802 				(struct uc_op_work_struct *)data;
4803 	struct wlan_ipa_priv *ipa_ctx = uc_op_work->ipa_priv_bp;
4804 
4805 	msg = uc_op_work->msg;
4806 	uc_op_work->msg = NULL;
4807 	ipa_debug("posted msg %d", msg->op_code);
4808 
4809 	wlan_ipa_uc_op_cb(msg, ipa_ctx);
4810 }
4811 
4812 /**
4813  * wlan_ipa_uc_fw_op_event_handler - SSR wrapper for
4814  * __wlan_ipa_uc_fw_op_event_handler
4815  * @data: uC OP work
4816  *
4817  * Return: None
4818  */
4819 static void wlan_ipa_uc_fw_op_event_handler(void *data)
4820 {
4821 	if (qdf_is_recovering()) {
4822 		ipa_err("in recovering");
4823 		return;
4824 	}
4825 
4826 	__wlan_ipa_uc_fw_op_event_handler(data);
4827 }
4828 
4829 /**
4830  * wlan_ipa_uc_op_event_handler() - IPA UC OP event handler
4831  * @op_msg: operation message received from firmware
4832  * @ctx: Global IPA context
4833  *
4834  * Return: None
4835  */
4836 static void wlan_ipa_uc_op_event_handler(uint8_t *op_msg, void *ctx)
4837 {
4838 	struct wlan_ipa_priv *ipa_ctx = (struct wlan_ipa_priv *)ctx;
4839 	struct op_msg_type *msg;
4840 	struct uc_op_work_struct *uc_op_work;
4841 
4842 	if (!ipa_ctx)
4843 		goto end;
4844 
4845 	msg = (struct op_msg_type *)op_msg;
4846 
4847 	if (msg->op_code >= WLAN_IPA_UC_OPCODE_MAX) {
4848 		ipa_err("Invalid OP Code (%d)", msg->op_code);
4849 		goto end;
4850 	}
4851 
4852 	uc_op_work = &ipa_ctx->uc_op_work[msg->op_code];
4853 	if (uc_op_work->msg) {
4854 		/* When the same uC OPCODE is already pended, just return */
4855 		goto end;
4856 	}
4857 
4858 	uc_op_work->msg = msg;
4859 	qdf_sched_work(0, &uc_op_work->work);
4860 	return;
4861 
4862 end:
4863 	qdf_mem_free(op_msg);
4864 }
4865 
4866 QDF_STATUS wlan_ipa_uc_ol_init(struct wlan_ipa_priv *ipa_ctx,
4867 			       qdf_device_t osdev)
4868 {
4869 	uint8_t i;
4870 	QDF_STATUS status = QDF_STATUS_SUCCESS;
4871 
4872 	if (!wlan_ipa_uc_is_enabled(ipa_ctx->config))
4873 		return QDF_STATUS_SUCCESS;
4874 
4875 	ipa_debug("enter");
4876 
4877 	if (!osdev) {
4878 		ipa_err("osdev null");
4879 		status = QDF_STATUS_E_FAILURE;
4880 		goto fail_return;
4881 	}
4882 
4883 	for (i = 0; i < WLAN_IPA_MAX_SESSION; i++) {
4884 		ipa_ctx->vdev_to_iface[i] = WLAN_IPA_MAX_SESSION;
4885 		ipa_ctx->vdev_offload_enabled[i] = false;
4886 		ipa_ctx->disable_intrabss_fwd[i] = false;
4887 	}
4888 
4889 	if (cdp_ipa_get_resource(ipa_ctx->dp_soc, ipa_ctx->dp_pdev_id)) {
4890 		ipa_err("IPA UC resource alloc fail");
4891 		status = QDF_STATUS_E_FAILURE;
4892 		goto fail_return;
4893 	}
4894 
4895 	for (i = 0; i < WLAN_IPA_UC_OPCODE_MAX; i++) {
4896 		ipa_ctx->uc_op_work[i].osdev = osdev;
4897 		ipa_ctx->uc_op_work[i].msg = NULL;
4898 		ipa_ctx->uc_op_work[i].ipa_priv_bp = ipa_ctx;
4899 		qdf_create_work(0, &ipa_ctx->uc_op_work[i].work,
4900 				wlan_ipa_uc_fw_op_event_handler,
4901 				&ipa_ctx->uc_op_work[i]);
4902 	}
4903 
4904 	if (true == ipa_ctx->uc_loaded) {
4905 		status = wlan_ipa_wdi_setup(ipa_ctx, osdev);
4906 		if (status) {
4907 			ipa_err("Failure to setup IPA pipes (status=%d)",
4908 				status);
4909 			status = QDF_STATUS_E_FAILURE;
4910 
4911 			if (wlan_ipa_uc_sta_is_enabled(ipa_ctx->config)) {
4912 				qdf_cancel_work(&ipa_ctx->mcc_work);
4913 				wlan_ipa_teardown_sys_pipe(ipa_ctx);
4914 			}
4915 			ipa_ctx->uc_loaded = false;
4916 
4917 			goto fail_return;
4918 		}
4919 
4920 		/* Setup the Tx buffer SMMU mappings */
4921 		status = cdp_ipa_tx_buf_smmu_mapping(ipa_ctx->dp_soc,
4922 						     ipa_ctx->dp_pdev_id,
4923 						     __func__, __LINE__);
4924 		if (status) {
4925 			ipa_err("Failure to map Tx buffers for IPA(status=%d)",
4926 				status);
4927 			return status;
4928 		}
4929 		ipa_info("TX buffers mapped to IPA");
4930 		cdp_ipa_set_doorbell_paddr(ipa_ctx->dp_soc,
4931 					   ipa_ctx->dp_pdev_id);
4932 		wlan_ipa_init_metering(ipa_ctx);
4933 		wlan_ipa_add_rem_flt_cb_event(ipa_ctx);
4934 		if (wlan_ipa_init_perf_level(ipa_ctx) != QDF_STATUS_SUCCESS)
4935 			ipa_err("Failed to init perf level");
4936 	}
4937 
4938 	cdp_ipa_register_op_cb(ipa_ctx->dp_soc, ipa_ctx->dp_pdev_id,
4939 			       wlan_ipa_uc_op_event_handler, (void *)ipa_ctx);
4940 fail_return:
4941 	ipa_debug("exit: status=%d", status);
4942 	return status;
4943 }
4944 
4945 /**
4946  * wlan_ipa_cleanup_pending_event() - Cleanup IPA pending event list
4947  * @ipa_ctx: pointer to IPA IPA struct
4948  *
4949  * Return: none
4950  */
4951 static void wlan_ipa_cleanup_pending_event(struct wlan_ipa_priv *ipa_ctx)
4952 {
4953 	struct wlan_ipa_uc_pending_event *pending_event = NULL;
4954 
4955 	while (qdf_list_remove_front(&ipa_ctx->pending_event,
4956 		(qdf_list_node_t **)&pending_event) == QDF_STATUS_SUCCESS)
4957 		qdf_mem_free(pending_event);
4958 }
4959 
4960 QDF_STATUS wlan_ipa_uc_ol_deinit(struct wlan_ipa_priv *ipa_ctx)
4961 {
4962 	QDF_STATUS status = QDF_STATUS_SUCCESS;
4963 	int i;
4964 
4965 	ipa_debug("enter");
4966 
4967 	if (!wlan_ipa_uc_is_enabled(ipa_ctx->config))
4968 		return status;
4969 
4970 	wlan_ipa_uc_disable_pipes(ipa_ctx, true);
4971 
4972 	cdp_ipa_deregister_op_cb(ipa_ctx->dp_soc, ipa_ctx->dp_pdev_id);
4973 	qdf_atomic_set(&ipa_ctx->deinit_in_prog, 1);
4974 
4975 	for (i = 0; i < WLAN_IPA_UC_OPCODE_MAX; i++) {
4976 		qdf_cancel_work(&ipa_ctx->uc_op_work[i].work);
4977 		qdf_mem_free(ipa_ctx->uc_op_work[i].msg);
4978 		ipa_ctx->uc_op_work[i].msg = NULL;
4979 	}
4980 
4981 	cdp_ipa_iounmap_doorbell_vaddr(ipa_ctx->dp_soc,
4982 				       ipa_ctx->dp_pdev_id);
4983 
4984 	if (true == ipa_ctx->uc_loaded) {
4985 		cdp_ipa_tx_buf_smmu_unmapping(ipa_ctx->dp_soc,
4986 					      ipa_ctx->dp_pdev_id,
4987 					      __func__, __LINE__);
4988 		status = cdp_ipa_cleanup(ipa_ctx->dp_soc,
4989 					 ipa_ctx->dp_pdev_id,
4990 					 ipa_ctx->tx_pipe_handle,
4991 					 ipa_ctx->rx_pipe_handle, ipa_ctx->hdl);
4992 		if (status)
4993 			ipa_err("Failure to cleanup IPA pipes (status=%d)",
4994 				status);
4995 	}
4996 
4997 	qdf_mutex_acquire(&ipa_ctx->ipa_lock);
4998 	wlan_ipa_cleanup_pending_event(ipa_ctx);
4999 	qdf_mutex_release(&ipa_ctx->ipa_lock);
5000 
5001 	ipa_debug("exit: ret=%d", status);
5002 	return status;
5003 }
5004 
5005 /**
5006  * wlan_ipa_uc_send_evt() - send event to ipa
5007  * @net_dev: Interface net device
5008  * @type: event type
5009  * @mac_addr: pointer to mac address
5010  * @ipa_priv: IPA private context
5011  *
5012  * Send event to IPA driver
5013  *
5014  * Return: QDF_STATUS
5015  */
5016 static QDF_STATUS wlan_ipa_uc_send_evt(qdf_netdev_t net_dev,
5017 				       qdf_ipa_wlan_event type,
5018 				       uint8_t *mac_addr,
5019 				       struct wlan_ipa_priv *ipa_priv)
5020 {
5021 	struct wlan_ipa_priv *ipa_ctx;
5022 	qdf_ipa_msg_meta_t meta;
5023 	qdf_ipa_wlan_msg_t *msg;
5024 
5025 	if (!ipa_priv)
5026 		return QDF_STATUS_E_INVAL;
5027 
5028 	ipa_ctx = ipa_priv;
5029 
5030 	QDF_IPA_MSG_META_MSG_LEN(&meta) = sizeof(qdf_ipa_wlan_msg_t);
5031 	msg = qdf_mem_malloc(QDF_IPA_MSG_META_MSG_LEN(&meta));
5032 	if (!msg)
5033 		return QDF_STATUS_E_NOMEM;
5034 
5035 	QDF_IPA_SET_META_MSG_TYPE(&meta, type);
5036 	qdf_str_lcopy(QDF_IPA_WLAN_MSG_NAME(msg), net_dev->name,
5037 		      IPA_RESOURCE_NAME_MAX);
5038 	qdf_mem_copy(QDF_IPA_WLAN_MSG_MAC_ADDR(msg), mac_addr, QDF_NET_ETH_LEN);
5039 	QDF_IPA_WLAN_MSG_NETDEV_IF_ID(msg) = net_dev->ifindex;
5040 
5041 	if (qdf_ipa_send_msg(&meta, msg, wlan_ipa_msg_free_fn)) {
5042 		ipa_err("%s: Evt: %d fail",
5043 			QDF_IPA_WLAN_MSG_NAME(msg),
5044 			QDF_IPA_MSG_META_MSG_TYPE(&meta));
5045 		qdf_mem_free(msg);
5046 
5047 		return QDF_STATUS_E_FAILURE;
5048 	}
5049 
5050 	ipa_ctx->stats.num_send_msg++;
5051 
5052 	return QDF_STATUS_SUCCESS;
5053 }
5054 
5055 void wlan_ipa_uc_cleanup_sta(struct wlan_ipa_priv *ipa_ctx,
5056 			     qdf_netdev_t net_dev)
5057 {
5058 	struct wlan_ipa_iface_context *iface_ctx;
5059 	int i;
5060 
5061 	ipa_debug("enter");
5062 
5063 	for (i = 0; i < WLAN_IPA_MAX_IFACE; i++) {
5064 		iface_ctx = &ipa_ctx->iface_context[i];
5065 		if (iface_ctx && iface_ctx->device_mode == QDF_STA_MODE &&
5066 		    iface_ctx->dev && iface_ctx->dev == net_dev) {
5067 			wlan_ipa_uc_send_evt(net_dev, QDF_IPA_STA_DISCONNECT,
5068 					     (uint8_t *)net_dev->dev_addr,
5069 					     ipa_ctx);
5070 			wlan_ipa_cleanup_iface(iface_ctx, NULL);
5071 		}
5072 	}
5073 
5074 	ipa_debug("exit");
5075 }
5076 
5077 QDF_STATUS wlan_ipa_uc_disconnect_ap(struct wlan_ipa_priv *ipa_ctx,
5078 				     qdf_netdev_t net_dev)
5079 {
5080 	struct wlan_ipa_iface_context *iface_ctx;
5081 	QDF_STATUS status;
5082 
5083 	ipa_debug("enter");
5084 
5085 	iface_ctx = wlan_ipa_get_iface(ipa_ctx, QDF_SAP_MODE);
5086 	if (iface_ctx)
5087 		status = wlan_ipa_uc_send_evt(net_dev, QDF_IPA_AP_DISCONNECT,
5088 					      (uint8_t *)net_dev->dev_addr,
5089 					      ipa_ctx);
5090 	else
5091 		return QDF_STATUS_E_INVAL;
5092 
5093 	ipa_debug("exit :%d", status);
5094 
5095 	return status;
5096 }
5097 
5098 void wlan_ipa_cleanup_dev_iface(struct wlan_ipa_priv *ipa_ctx,
5099 				qdf_netdev_t net_dev)
5100 {
5101 	struct wlan_ipa_iface_context *iface_ctx;
5102 	int i;
5103 
5104 	for (i = 0; i < WLAN_IPA_MAX_IFACE; i++) {
5105 		iface_ctx = &ipa_ctx->iface_context[i];
5106 		if (iface_ctx->dev == net_dev) {
5107 			wlan_ipa_cleanup_iface(iface_ctx, NULL);
5108 			break;
5109 		}
5110 	}
5111 }
5112 
5113 void wlan_ipa_uc_ssr_cleanup(struct wlan_ipa_priv *ipa_ctx)
5114 {
5115 	struct wlan_ipa_iface_context *iface;
5116 	int i;
5117 
5118 	ipa_info("enter");
5119 
5120 	for (i = 0; i < WLAN_IPA_MAX_IFACE; i++) {
5121 		iface = &ipa_ctx->iface_context[i];
5122 		if (iface->dev) {
5123 			if (iface->device_mode == QDF_SAP_MODE)
5124 				wlan_ipa_uc_send_evt(iface->dev,
5125 						     QDF_IPA_AP_DISCONNECT,
5126 						     (uint8_t *)iface->dev->dev_addr,
5127 						     ipa_ctx);
5128 			else if (iface->device_mode == QDF_STA_MODE)
5129 				wlan_ipa_uc_send_evt(iface->dev,
5130 						     QDF_IPA_STA_DISCONNECT,
5131 						     (uint8_t *)iface->dev->dev_addr,
5132 						     ipa_ctx);
5133 			wlan_ipa_cleanup_iface(iface, NULL);
5134 		}
5135 	}
5136 }
5137 
5138 void wlan_ipa_fw_rejuvenate_send_msg(struct wlan_ipa_priv *ipa_ctx)
5139 {
5140 	qdf_ipa_msg_meta_t meta;
5141 	qdf_ipa_wlan_msg_t *msg;
5142 	int ret;
5143 
5144 	meta.msg_len = sizeof(*msg);
5145 	msg = qdf_mem_malloc(meta.msg_len);
5146 	if (!msg)
5147 		return;
5148 
5149 	QDF_IPA_SET_META_MSG_TYPE(&meta, QDF_FWR_SSR_BEFORE_SHUTDOWN);
5150 	ipa_debug("ipa_send_msg(Evt:%d)",
5151 		  meta.msg_type);
5152 	ret = qdf_ipa_send_msg(&meta, msg, wlan_ipa_msg_free_fn);
5153 
5154 	if (ret) {
5155 		ipa_err("ipa_send_msg(Evt:%d)-fail=%d",
5156 			meta.msg_type, ret);
5157 		qdf_mem_free(msg);
5158 	}
5159 	ipa_ctx->stats.num_send_msg++;
5160 }
5161 
5162 void wlan_ipa_flush_pending_vdev_events(struct wlan_ipa_priv *ipa_ctx,
5163 					uint8_t vdev_id)
5164 {
5165 	struct wlan_ipa_uc_pending_event *event;
5166 	struct wlan_ipa_uc_pending_event *next_event;
5167 
5168 	qdf_mutex_acquire(&ipa_ctx->ipa_lock);
5169 
5170 	qdf_list_for_each_del(&ipa_ctx->pending_event, event, next_event,
5171 			      node) {
5172 		if (event->session_id == vdev_id) {
5173 			qdf_list_remove_node(&ipa_ctx->pending_event,
5174 					     &event->node);
5175 			qdf_mem_free(event);
5176 		}
5177 	}
5178 
5179 	qdf_mutex_release(&ipa_ctx->ipa_lock);
5180 }
5181 
5182 #ifdef IPA_OPT_WIFI_DP
5183 void wlan_ipa_wdi_opt_dpath_notify_flt_rsvd(bool response)
5184 {
5185 	struct wlan_ipa_priv *ipa_ctx = gp_ipa;
5186 	struct op_msg_type *smmu_msg;
5187 	struct op_msg_type *notify_msg;
5188 	struct uc_op_work_struct *uc_op_work;
5189 
5190 	smmu_msg = qdf_mem_malloc(sizeof(*smmu_msg));
5191 	if (!smmu_msg)
5192 		return;
5193 
5194 	if (response) {
5195 		smmu_msg->op_code = WLAN_IPA_SMMU_MAP;
5196 		uc_op_work = &ipa_ctx->uc_op_work[WLAN_IPA_SMMU_MAP];
5197 		uc_op_work->msg = smmu_msg;
5198 		qdf_sched_work(0, &uc_op_work->work);
5199 		cdp_ipa_set_smmu_mapped(ipa_ctx->dp_soc, 1);
5200 	}
5201 
5202 	notify_msg = qdf_mem_malloc(sizeof(*notify_msg));
5203 	if (!notify_msg)
5204 		return;
5205 
5206 	notify_msg->op_code = WLAN_IPA_FILTER_RSV_NOTIFY;
5207 	notify_msg->rsvd = response;
5208 	uc_op_work = &ipa_ctx->uc_op_work[WLAN_IPA_FILTER_RSV_NOTIFY];
5209 	uc_op_work->msg = notify_msg;
5210 	qdf_sched_work(0, &uc_op_work->work);
5211 }
5212 
5213 int wlan_ipa_wdi_opt_dpath_flt_rsrv_cb(
5214 			void *ipa_ctx,
5215 			struct ipa_wdi_opt_dpath_flt_rsrv_cb_params *out_params)
5216 {
5217 	struct wifi_dp_flt_setup *dp_flt_params = NULL;
5218 	struct wlan_ipa_priv *ipa_obj = (struct wlan_ipa_priv *)ipa_ctx;
5219 	int i, pdev_id, param_val;
5220 	struct wlan_objmgr_pdev *pdev;
5221 	int response = 0;
5222 
5223 	pdev = ipa_obj->pdev;
5224 	pdev_id = ipa_obj->dp_pdev_id;
5225 
5226 	/* Hold wakelock */
5227 	qdf_wake_lock_acquire(&ipa_obj->opt_dp_wake_lock,
5228 			      WIFI_POWER_EVENT_WAKELOCK_OPT_WIFI_DP);
5229 	qdf_pm_system_wakeup();
5230 	ipa_info("opt_dp: Wakelock acquired");
5231 
5232 	/* Disable Low power features before filter reservation */
5233 	ipa_info("opt_dp: Disable low power features to reserve filter");
5234 	param_val = 0;
5235 	response = cdp_ipa_opt_dp_enable_disable_low_power_mode(pdev, pdev_id,
5236 								param_val);
5237 	if (response) {
5238 		ipa_err("Low power feature disable failed. status %d",
5239 			response);
5240 		return QDF_STATUS_FILT_REQ_ERROR;
5241 	}
5242 
5243 	response = cdp_ipa_pcie_link_up(ipa_obj->dp_soc);
5244 	ipa_info("opt_dp: Pcie link up status %d", response);
5245 
5246 	ipa_info("opt_dp: Send filter reserve req");
5247 	dp_flt_params = &(ipa_obj->dp_cce_super_rule_flt_param);
5248 	dp_flt_params->op = HTT_RX_CCE_SUPER_RULE_SETUP_REQUEST;
5249 	dp_flt_params->pdev_id = ipa_obj->dp_pdev_id;
5250 	for (i = 0; i < IPA_WDI_MAX_FILTER; i++) {
5251 		dp_flt_params->flt_addr_params[i].ipa_flt_evnt_required = 0;
5252 		dp_flt_params->flt_addr_params[i].ipa_flt_in_use = false;
5253 	}
5254 	return cdp_ipa_rx_cce_super_rule_setup(ipa_obj->dp_soc, dp_flt_params);
5255 }
5256 
5257 int wlan_ipa_wdi_opt_dpath_flt_add_cb(
5258 			     void *ipa_ctx,
5259 			     struct ipa_wdi_opt_dpath_flt_add_cb_params *in_out)
5260 {
5261 	struct ipa_wdi_opt_dpath_flt_add_cb_params *ipa_flt =
5262 			 (struct ipa_wdi_opt_dpath_flt_add_cb_params *)(in_out);
5263 	struct wlan_ipa_priv *ipa_obj = (struct wlan_ipa_priv *)ipa_ctx;
5264 	int i, j, flt, response = 0;
5265 	uint8_t num_flts;
5266 	uint32_t src_ip_addr, dst_ip_addr;
5267 	uint32_t *host_ipv6;
5268 	struct wlan_objmgr_pdev *pdev;
5269 	struct wlan_objmgr_psoc *psoc;
5270 	struct wifi_dp_flt_setup *dp_flt_param = NULL;
5271 	void *htc_handle;
5272 
5273 	pdev = ipa_obj->pdev;
5274 	psoc = wlan_pdev_get_psoc(pdev);
5275 	num_flts = ipa_flt->num_tuples;
5276 	htc_handle = lmac_get_htc_hdl(psoc);
5277 	if (!htc_handle) {
5278 		ipa_err("HTC Handle is null");
5279 		return QDF_STATUS_FILT_REQ_ERROR;
5280 	}
5281 
5282 	dp_flt_param = &(ipa_obj->dp_cce_super_rule_flt_param);
5283 
5284 	if (num_flts > IPA_WDI_MAX_FILTER) {
5285 		ipa_err("Wrong IPA flt count %d", num_flts);
5286 		return QDF_STATUS_FILT_REQ_ERROR;
5287 	}
5288 
5289 	for (flt = 0; flt < num_flts; flt++) {
5290 		for (i = 0; i < IPA_WDI_MAX_FILTER; i++)
5291 			if (!dp_flt_param->flt_addr_params[i].ipa_flt_in_use)
5292 				break;
5293 
5294 		if (i >= IPA_WDI_MAX_FILTER) {
5295 			ipa_err("Wrong IPA flt count %d, i=%d", num_flts, i);
5296 			return QDF_STATUS_FILT_REQ_ERROR;
5297 		}
5298 
5299 		ipa_flt->flt_info[flt].out_hdl = (WLAN_HDL_FILTER1 + i);
5300 		dp_flt_param->flt_addr_params[i].valid = 1;
5301 		dp_flt_param->flt_addr_params[i].flt_hdl =
5302 						ipa_flt->flt_info[flt].out_hdl;
5303 		dp_flt_param->flt_addr_params[i].ipa_flt_evnt_required = 1;
5304 		dp_flt_param->flt_addr_params[i].ipa_flt_in_use = true;
5305 
5306 		if (ipa_flt->flt_info[flt].version == 0) {
5307 			dp_flt_param->flt_addr_params[i].l3_type = IPV4;
5308 		} else if (ipa_flt->flt_info[flt].version == 1) {
5309 			dp_flt_param->flt_addr_params[i].l3_type = IPV6;
5310 		} else {
5311 			ipa_err("Wrong IPA version %d",
5312 				ipa_flt->flt_info[flt].version);
5313 			return QDF_STATUS_FILT_REQ_ERROR;
5314 		}
5315 
5316 		if (dp_flt_param->flt_addr_params[i].l3_type == IPV4) {
5317 			src_ip_addr = qdf_ntohl(ipa_flt->flt_info[flt].
5318 						ipv4_addr.ipv4_saddr);
5319 			dst_ip_addr = qdf_ntohl(ipa_flt->flt_info[flt].
5320 						ipv4_addr.ipv4_daddr);
5321 			qdf_mem_copy(
5322 				dp_flt_param->flt_addr_params[i].src_ipv4_addr,
5323 				(&src_ip_addr),
5324 				IPV4BYTES);
5325 			qdf_mem_copy(
5326 				dp_flt_param->flt_addr_params[i].dst_ipv4_addr,
5327 				(&dst_ip_addr),
5328 				IPV4BYTES);
5329 			ipa_info("ipv4 src addr rxed from ipa 0x%x",
5330 				 ipa_flt->flt_info[flt].ipv4_addr.ipv4_saddr);
5331 			ipa_info("ipv4 sent to FW 0x%x", src_ip_addr);
5332 		} else if (dp_flt_param->flt_addr_params[i].l3_type == IPV6) {
5333 			host_ipv6 = (uint32_t *)dp_flt_param->flt_addr_params[i].
5334 				    src_ipv6_addr;
5335 
5336 			for (j = 0; j < IPV6ARRAY; j++) {
5337 				src_ip_addr = qdf_ntohl(ipa_flt->flt_info[flt].
5338 							ipv6_addr.ipv6_saddr[j]);
5339 				qdf_mem_copy(host_ipv6,
5340 					     &src_ip_addr,
5341 					     IPV6ARRAY);
5342 				host_ipv6++;
5343 			}
5344 			for (j = 0; j < IPV6ARRAY; j++) {
5345 				ipa_info("ipv6 src addr rxed from ipa 0x%x",
5346 					 ipa_flt->flt_info[flt].ipv6_addr.
5347 					 ipv6_saddr[j]);
5348 			}
5349 			for (j = 0; j < IPV6ARRAY; j++)
5350 				ipa_info("ipv6 sent to FW 0x%x",
5351 					 *((uint32_t *)dp_flt_param->flt_addr_params[i].
5352 					 src_ipv6_addr + j));
5353 			/* Dest addr is currently not used in filter */
5354 		}
5355 	}
5356 
5357 	dp_flt_param->op = HTT_RX_CCE_SUPER_RULE_INSTALL;
5358 	dp_flt_param->pdev_id = ipa_obj->dp_pdev_id;
5359 	dp_flt_param->num_filters = num_flts;
5360 	qdf_event_reset(&ipa_obj->ipa_flt_evnt);
5361 
5362 	ipa_info("opt_dp: op %d, pdev_id %d. num_flts %d",
5363 		 dp_flt_param->op, dp_flt_param->pdev_id, num_flts);
5364 	for (i = 0; i < num_flts; i++)
5365 		ipa_info("version %d, valid %d, src addr_ %08lx, evnt reqd %d",
5366 			 dp_flt_param->flt_addr_params[i].l3_type,
5367 			 dp_flt_param->flt_addr_params[i].valid,
5368 			 dp_flt_param->flt_addr_params[i].src_ipv4_addr,
5369 			 dp_flt_param->flt_addr_params[i].ipa_flt_evnt_required);
5370 
5371 	cdp_ipa_rx_cce_super_rule_setup(ipa_obj->dp_soc, dp_flt_param);
5372 
5373 	qdf_wait_single_event(&ipa_obj->ipa_flt_evnt,
5374 			      DP_MAX_SLEEP_TIME);
5375 
5376 	for (i = 0; i < num_flts; i++)
5377 		dp_flt_param->flt_addr_params[i].ipa_flt_evnt_required = 0;
5378 
5379 	response = dp_flt_param->ipa_flt_evnt_response;
5380 	if (response != QDF_STATUS_SUCCESS) {
5381 		if (response == QDF_STATUS_E_TIMEOUT)
5382 			qdf_err("TIMEOUT_OCCURS");
5383 		else
5384 			qdf_err("Error on event wait for filter add cb");
5385 	}
5386 	return response;
5387 }
5388 
5389 int wlan_ipa_wdi_opt_dpath_flt_rem_cb(
5390 				void *ipa_ctx,
5391 				struct ipa_wdi_opt_dpath_flt_rem_cb_params *in)
5392 {
5393 	struct ipa_wdi_opt_dpath_flt_rem_cb_params *rem_flt =
5394 			 (struct ipa_wdi_opt_dpath_flt_rem_cb_params *)(in);
5395 	struct wifi_dp_flt_setup *dp_flt_params = NULL;
5396 	struct wlan_ipa_priv *ipa_obj = (struct wlan_ipa_priv *)ipa_ctx;
5397 	struct wlan_objmgr_pdev *pdev;
5398 	struct wlan_objmgr_psoc *psoc;
5399 	uint8_t num_flts;
5400 	uint32_t i, j, response = 0;
5401 	void *htc_handle;
5402 
5403 	pdev = ipa_obj->pdev;
5404 	psoc = wlan_pdev_get_psoc(pdev);
5405 	num_flts = rem_flt->num_tuples;
5406 
5407 	htc_handle = lmac_get_htc_hdl(psoc);
5408 	if (!htc_handle) {
5409 		ipa_err("HTC Handle is null");
5410 		return QDF_STATUS_FILT_REQ_ERROR;
5411 	}
5412 
5413 	dp_flt_params = &(ipa_obj->dp_cce_super_rule_flt_param);
5414 	for (i = 0; i < num_flts; i++) {
5415 		for (j = 0; j < IPA_WDI_MAX_FILTER; j++) {
5416 			if (rem_flt->hdl_info[i] ==
5417 				 dp_flt_params->flt_addr_params[j].flt_hdl) {
5418 				dp_flt_params->flt_addr_params[i].valid = 0;
5419 				qdf_mem_zero(dp_flt_params->flt_addr_params[i].
5420 					     src_ipv4_addr,
5421 					     IPV4BYTES);
5422 				qdf_mem_zero(dp_flt_params->flt_addr_params[i].
5423 					     src_ipv6_addr,
5424 					     IPV6BYTES);
5425 				dp_flt_params->flt_addr_params[i].
5426 						      ipa_flt_evnt_required = 1;
5427 				dp_flt_params->flt_addr_params[i].ipa_flt_in_use
5428 									= false;
5429 			}
5430 		}
5431 	}
5432 	dp_flt_params->op = HTT_RX_CCE_SUPER_RULE_INSTALL;
5433 	dp_flt_params->pdev_id = ipa_obj->dp_pdev_id;
5434 	dp_flt_params->num_filters = num_flts;
5435 	qdf_event_reset(&ipa_obj->ipa_flt_evnt);
5436 
5437 	ipa_info("opt_dp: op %d, pdev_id %d. num_flts %d",
5438 		 dp_flt_params->op, dp_flt_params->pdev_id, num_flts);
5439 	for (i = 0; i < num_flts; i++)
5440 		ipa_info("version %d, valid %d, src addr_ %08lx, evnt_reqd %d",
5441 			 dp_flt_params->flt_addr_params[i].l3_type,
5442 			 dp_flt_params->flt_addr_params[i].valid,
5443 			 dp_flt_params->flt_addr_params[i].src_ipv4_addr,
5444 			 dp_flt_params->flt_addr_params[i].ipa_flt_evnt_required);
5445 
5446 	cdp_ipa_rx_cce_super_rule_setup(ipa_obj->dp_soc, dp_flt_params);
5447 
5448 	qdf_wait_single_event(&ipa_obj->ipa_flt_evnt,
5449 			      DP_MAX_SLEEP_TIME);
5450 
5451 	for (i = 0; i < num_flts; i++)
5452 		dp_flt_params->flt_addr_params[i].ipa_flt_evnt_required = 0;
5453 
5454 	response = dp_flt_params->ipa_flt_evnt_response;
5455 	if (response != QDF_STATUS_SUCCESS) {
5456 		if (response == QDF_STATUS_E_TIMEOUT)
5457 			qdf_err("TIMEOUT_OCCURS");
5458 		else
5459 			qdf_err("Error on event wait for filter rem cb");
5460 	}
5461 	return response;
5462 }
5463 
5464 int wlan_ipa_wdi_opt_dpath_flt_rsrv_rel_cb(void *ipa_ctx)
5465 {
5466 	struct wifi_dp_flt_setup *dp_flt_params = NULL;
5467 	struct wlan_ipa_priv *ipa_obj = (struct wlan_ipa_priv *)ipa_ctx;
5468 	int i, param_val = 0;
5469 	struct wlan_objmgr_pdev *pdev;
5470 	int pdev_id;
5471 	int response = 0;
5472 
5473 	pdev = ipa_obj->pdev;
5474 	pdev_id = ipa_obj->dp_pdev_id;
5475 	/* Enable Low power features before filter release */
5476 	ipa_info("opt_dp: Enable low power features to release filter");
5477 	param_val = 1;
5478 	response = cdp_ipa_opt_dp_enable_disable_low_power_mode(pdev, pdev_id,
5479 								param_val);
5480 	if (response) {
5481 		ipa_err("Low power feature enable failed. status %d", response);
5482 		return QDF_STATUS_FILT_REQ_ERROR;
5483 	}
5484 
5485 	response = cdp_ipa_pcie_link_down(ipa_obj->dp_soc);
5486 	ipa_info("opt_dp: Vote for PCIe link down");
5487 	dp_flt_params = &(ipa_obj->dp_cce_super_rule_flt_param);
5488 	for (i = 0; i < IPA_WDI_MAX_FILTER; i++)
5489 		 dp_flt_params->flt_addr_params[i].valid = 0;
5490 	dp_flt_params->op = HTT_RX_CCE_SUPER_RULE_RELEASE;
5491 	dp_flt_params->pdev_id = ipa_obj->dp_pdev_id;
5492 	dp_flt_params->num_filters = IPA_WDI_MAX_FILTER;
5493 	return cdp_ipa_rx_cce_super_rule_setup(ipa_obj->dp_soc, dp_flt_params);
5494 }
5495 
5496 void wlan_ipa_wdi_opt_dpath_notify_flt_rlsd(int flt0_rslt, int flt1_rslt)
5497 {
5498 	struct wifi_dp_flt_setup *dp_flt_params = NULL;
5499 	struct wlan_ipa_priv *ipa_ctx = gp_ipa;
5500 	struct wlan_objmgr_pdev *pdev;
5501 	struct op_msg_type *smmu_msg;
5502 	struct op_msg_type *notify_msg;
5503 	struct uc_op_work_struct *uc_op_work;
5504 	bool result = false;
5505 	bool val = false;
5506 
5507 	pdev = ipa_ctx->pdev;
5508 	dp_flt_params = &(ipa_ctx->dp_cce_super_rule_flt_param);
5509 
5510 	if ((dp_flt_params->flt_addr_params[0].ipa_flt_in_use == true &&
5511 	     flt0_rslt == 0) ||
5512 	    (dp_flt_params->flt_addr_params[1].ipa_flt_in_use == true &&
5513 	     flt1_rslt == 0))
5514 		result = false;
5515 	else {
5516 		dp_flt_params->flt_addr_params[0].ipa_flt_in_use = false;
5517 		dp_flt_params->flt_addr_params[1].ipa_flt_in_use = false;
5518 		result = true;
5519 	}
5520 
5521 	smmu_msg = qdf_mem_malloc(sizeof(*smmu_msg));
5522 	if (!smmu_msg)
5523 		return;
5524 
5525 	val = cdp_ipa_get_smmu_mapped(ipa_ctx->dp_soc);
5526 	if (val) {
5527 		smmu_msg->op_code = WLAN_IPA_SMMU_UNMAP;
5528 		uc_op_work = &ipa_ctx->uc_op_work[WLAN_IPA_SMMU_UNMAP];
5529 		uc_op_work->msg = smmu_msg;
5530 		qdf_sched_work(0, &uc_op_work->work);
5531 		cdp_ipa_set_smmu_mapped(ipa_ctx->dp_soc, 0);
5532 	} else {
5533 		ipa_err("IPA SMMU not mapped!!");
5534 	}
5535 
5536 	notify_msg = qdf_mem_malloc(sizeof(*notify_msg));
5537 	if (!notify_msg)
5538 		return;
5539 
5540 	notify_msg->op_code = WLAN_IPA_FILTER_REL_NOTIFY;
5541 	notify_msg->rsvd = result;
5542 	uc_op_work = &ipa_ctx->uc_op_work[WLAN_IPA_FILTER_REL_NOTIFY];
5543 	uc_op_work->msg = notify_msg;
5544 	qdf_sched_work(0, &uc_op_work->work);
5545 
5546 	qdf_wake_lock_release(&ipa_ctx->opt_dp_wake_lock,
5547 			      WIFI_POWER_EVENT_WAKELOCK_OPT_WIFI_DP);
5548 	ipa_info("opt_dp: Wakelock released");
5549 }
5550 
5551 void wlan_ipa_wdi_opt_dpath_notify_flt_add_rem_cb(int flt0_rslt, int flt1_rslt)
5552 {
5553 	struct wifi_dp_flt_setup *dp_flt_params = NULL;
5554 	struct wlan_ipa_priv *ipa_obj = gp_ipa;
5555 
5556 	dp_flt_params = &(ipa_obj->dp_cce_super_rule_flt_param);
5557 
5558 	if ((dp_flt_params->flt_addr_params[0].ipa_flt_evnt_required == 1 &&
5559 	     flt0_rslt == 0) ||
5560 	    (dp_flt_params->flt_addr_params[1].ipa_flt_evnt_required == 1 &&
5561 	     flt1_rslt == 0))
5562 			dp_flt_params->ipa_flt_evnt_response =
5563 						      QDF_STATUS_FILT_REQ_ERROR;
5564 	else
5565 			dp_flt_params->ipa_flt_evnt_response =
5566 							     QDF_STATUS_SUCCESS;
5567 	ipa_info("opt_dp: ipa_flt_event_response set status: %d",
5568 		 dp_flt_params->ipa_flt_evnt_response);
5569 	qdf_event_set(&ipa_obj->ipa_flt_evnt);
5570 }
5571 #endif /* IPA_OPT_WIFI_DP */
5572