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