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