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