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