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