xref: /wlan-dirver/qca-wifi-host-cmn/target_if/core/src/target_if_main.c (revision f28396d060cff5c6519f883cb28ae0116ce479f1)
1 /*
2  * Copyright (c) 2017-2020 The Linux Foundation. All rights reserved.
3  *
4  * Permission to use, copy, modify, and/or distribute this software for
5  * any purpose with or without fee is hereby granted, provided that the
6  * above copyright notice and this permission notice appear in all
7  * copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
10  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
11  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
12  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
13  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
14  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
15  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16  * PERFORMANCE OF THIS SOFTWARE.
17  */
18 
19 /**
20  * DOC: API for interacting with target interface.
21  *
22  */
23 
24 #include "target_if.h"
25 #include "target_type.h"
26 #ifdef WLAN_ATF_ENABLE
27 #include "target_if_atf.h"
28 #endif
29 #ifdef WLAN_SA_API_ENABLE
30 #include "target_if_sa_api.h"
31 #endif
32 #ifdef WLAN_CFR_ENABLE
33 #include "target_if_cfr.h"
34 #endif
35 #ifdef WLAN_CONV_SPECTRAL_ENABLE
36 #include "target_if_spectral.h"
37 #endif
38 #include <target_if_reg.h>
39 #include <target_if_scan.h>
40 #include <target_if_ftm.h>
41 #ifdef DFS_COMPONENT_ENABLE
42 #include <target_if_dfs.h>
43 #endif
44 
45 #ifdef CONVERGED_P2P_ENABLE
46 #include "target_if_p2p.h"
47 #endif
48 
49 #ifdef WIFI_POS_CONVERGED
50 #include "target_if_wifi_pos.h"
51 #endif
52 
53 #ifdef FEATURE_WLAN_TDLS
54 #include "target_if_tdls.h"
55 #endif
56 #ifdef QCA_SUPPORT_SON
57 #include <target_if_son.h>
58 #endif
59 #ifdef WLAN_OFFCHAN_TXRX_ENABLE
60 #include <target_if_offchan_txrx_api.h>
61 #endif
62 #ifdef WLAN_SUPPORT_GREEN_AP
63 #include <target_if_green_ap.h>
64 #endif
65 #include <init_deinit_lmac.h>
66 #include <service_ready_util.h>
67 
68 #ifdef DIRECT_BUF_RX_ENABLE
69 #include <target_if_direct_buf_rx_api.h>
70 #endif
71 
72 #ifdef WLAN_SUPPORT_FILS
73 #include <target_if_fd.h>
74 #endif
75 #include "qdf_module.h"
76 
77 #include <target_if_cp_stats.h>
78 #ifdef CRYPTO_SET_KEY_CONVERGED
79 #include <target_if_crypto.h>
80 #endif
81 #include <target_if_vdev_mgr_tx_ops.h>
82 
83 #ifdef FEATURE_COEX
84 #include <target_if_coex.h>
85 #endif
86 
87 static struct target_if_ctx *g_target_if_ctx;
88 
89 struct target_if_ctx *target_if_get_ctx()
90 {
91 	return g_target_if_ctx;
92 }
93 
94 struct wlan_objmgr_psoc *target_if_get_psoc_from_scn_hdl(void *scn_handle)
95 {
96 	struct wlan_objmgr_psoc *psoc;
97 
98 	qdf_spin_lock_bh(&g_target_if_ctx->lock);
99 	if (scn_handle && g_target_if_ctx->get_psoc_hdl_cb)
100 		psoc = g_target_if_ctx->get_psoc_hdl_cb(scn_handle);
101 	else
102 		psoc = NULL;
103 	qdf_spin_unlock_bh(&g_target_if_ctx->lock);
104 
105 	return psoc;
106 }
107 
108 struct wlan_objmgr_pdev *target_if_get_pdev_from_scn_hdl(void *scn_handle)
109 {
110 	struct wlan_objmgr_pdev *pdev;
111 
112 	qdf_spin_lock_bh(&g_target_if_ctx->lock);
113 	if (scn_handle && g_target_if_ctx->get_pdev_hdl_cb)
114 		pdev = g_target_if_ctx->get_pdev_hdl_cb(scn_handle);
115 	else
116 		pdev = NULL;
117 	qdf_spin_unlock_bh(&g_target_if_ctx->lock);
118 
119 	return pdev;
120 }
121 
122 #ifdef DIRECT_BUF_RX_ENABLE
123 static QDF_STATUS target_if_direct_buf_rx_init(void)
124 {
125 	return direct_buf_rx_init();
126 }
127 
128 static QDF_STATUS target_if_direct_buf_rx_deinit(void)
129 {
130 	return direct_buf_rx_deinit();
131 }
132 #else
133 static QDF_STATUS target_if_direct_buf_rx_init(void)
134 {
135 	return QDF_STATUS_SUCCESS;
136 }
137 
138 static QDF_STATUS target_if_direct_buf_rx_deinit(void)
139 {
140 	return QDF_STATUS_SUCCESS;
141 }
142 #endif /* DIRECT_BUF_RX_ENABLE */
143 
144 QDF_STATUS target_if_init(get_psoc_handle_callback psoc_hdl_cb)
145 {
146 	g_target_if_ctx = qdf_mem_malloc(sizeof(*g_target_if_ctx));
147 	if (!g_target_if_ctx) {
148 		QDF_ASSERT(0);
149 		return QDF_STATUS_E_NOMEM;
150 	}
151 
152 	qdf_spinlock_create(&g_target_if_ctx->lock);
153 
154 	qdf_spin_lock_bh(&g_target_if_ctx->lock);
155 	g_target_if_ctx->magic = TGT_MAGIC;
156 	g_target_if_ctx->get_psoc_hdl_cb = psoc_hdl_cb;
157 	qdf_spin_unlock_bh(&g_target_if_ctx->lock);
158 
159 	target_if_direct_buf_rx_init();
160 
161 	return QDF_STATUS_SUCCESS;
162 }
163 
164 QDF_STATUS target_if_deinit(void)
165 {
166 	if (!g_target_if_ctx) {
167 		QDF_ASSERT(0);
168 		target_if_err("target if ctx is null");
169 		return QDF_STATUS_E_INVAL;
170 	}
171 
172 	qdf_spin_lock_bh(&g_target_if_ctx->lock);
173 	g_target_if_ctx->magic = 0;
174 	g_target_if_ctx->get_psoc_hdl_cb = NULL;
175 	g_target_if_ctx->get_pdev_hdl_cb = NULL;
176 	g_target_if_ctx->service_ready_cb = NULL;
177 	qdf_spin_unlock_bh(&g_target_if_ctx->lock);
178 
179 	qdf_spinlock_destroy(&g_target_if_ctx->lock);
180 	qdf_mem_free(g_target_if_ctx);
181 	g_target_if_ctx = NULL;
182 
183 	target_if_direct_buf_rx_deinit();
184 
185 	return QDF_STATUS_SUCCESS;
186 }
187 
188 qdf_export_symbol(target_if_deinit);
189 
190 QDF_STATUS target_if_store_pdev_target_if_ctx(
191 		get_pdev_handle_callback pdev_hdl_cb)
192 {
193 	if (!g_target_if_ctx) {
194 		QDF_ASSERT(0);
195 		target_if_err("target if ctx is null");
196 		return QDF_STATUS_E_INVAL;
197 	}
198 
199 	qdf_spin_lock_bh(&g_target_if_ctx->lock);
200 	g_target_if_ctx->get_pdev_hdl_cb = pdev_hdl_cb;
201 	qdf_spin_unlock_bh(&g_target_if_ctx->lock);
202 
203 	return QDF_STATUS_SUCCESS;
204 }
205 
206 #ifndef WLAN_OFFCHAN_TXRX_ENABLE
207 static void target_if_offchan_txrx_ops_register(
208 					struct wlan_lmac_if_tx_ops *tx_ops)
209 {
210 }
211 #endif /* WLAN_OFFCHAN_TXRX_ENABLE */
212 
213 #ifndef WLAN_ATF_ENABLE
214 static void target_if_atf_tx_ops_register(struct wlan_lmac_if_tx_ops *tx_ops)
215 {
216 }
217 #endif /* WLAN_ATF_ENABLE */
218 
219 #ifndef WLAN_SA_API_ENABLE
220 static void target_if_sa_api_tx_ops_register(struct wlan_lmac_if_tx_ops *tx_ops)
221 {
222 }
223 #endif /* WLAN_SA_API_ENABLE */
224 
225 #ifndef WLAN_CFR_ENABLE
226 static void target_if_cfr_tx_ops_register(struct wlan_lmac_if_tx_ops *tx_ops)
227 {
228 }
229 #endif
230 
231 #ifdef WLAN_SUPPORT_FILS
232 static void target_if_fd_tx_ops_register(struct wlan_lmac_if_tx_ops *tx_ops)
233 {
234 	target_if_fd_register_tx_ops(tx_ops);
235 }
236 #else
237 static void target_if_fd_tx_ops_register(struct wlan_lmac_if_tx_ops *tx_ops)
238 {
239 }
240 #endif
241 
242 #ifdef WIFI_POS_CONVERGED
243 static void target_if_wifi_pos_tx_ops_register(
244 			struct wlan_lmac_if_tx_ops *tx_ops)
245 {
246 	target_if_wifi_pos_register_tx_ops(tx_ops);
247 }
248 #else
249 static void target_if_wifi_pos_tx_ops_register(
250 			struct wlan_lmac_if_tx_ops *tx_ops)
251 {
252 }
253 #endif
254 #ifdef QCA_SUPPORT_SON
255 static void target_if_son_tx_ops_register(
256 			struct wlan_lmac_if_tx_ops *tx_ops)
257 {
258 	target_if_son_register_tx_ops(tx_ops);
259 	return;
260 }
261 #else
262 static void target_if_son_tx_ops_register(
263 			struct wlan_lmac_if_tx_ops *tx_ops)
264 {
265 	return;
266 }
267 #endif
268 
269 #ifdef FEATURE_WLAN_TDLS
270 static void target_if_tdls_tx_ops_register(struct wlan_lmac_if_tx_ops *tx_ops)
271 {
272 	target_if_tdls_register_tx_ops(tx_ops);
273 }
274 #else
275 static void target_if_tdls_tx_ops_register(struct wlan_lmac_if_tx_ops *tx_ops)
276 {
277 }
278 #endif /* FEATURE_WLAN_TDLS */
279 
280 #ifdef DFS_COMPONENT_ENABLE
281 static void target_if_dfs_tx_ops_register(
282 				struct wlan_lmac_if_tx_ops *tx_ops)
283 {
284 	target_if_register_dfs_tx_ops(tx_ops);
285 }
286 #else
287 static void target_if_dfs_tx_ops_register(
288 				struct wlan_lmac_if_tx_ops *tx_ops)
289 {
290 }
291 #endif /* DFS_COMPONENT_ENABLE */
292 
293 #ifdef WLAN_CONV_SPECTRAL_ENABLE
294 static void target_if_sptrl_tx_ops_register(
295 				struct wlan_lmac_if_tx_ops *tx_ops)
296 {
297 	target_if_sptrl_register_tx_ops(tx_ops);
298 }
299 #else
300 static void target_if_sptrl_tx_ops_register(
301 				struct wlan_lmac_if_tx_ops *tx_ops)
302 {
303 }
304 #endif /* WLAN_CONV_SPECTRAL_ENABLE */
305 
306 #ifdef DIRECT_BUF_RX_ENABLE
307 static void target_if_direct_buf_rx_tx_ops_register(
308 				struct wlan_lmac_if_tx_ops *tx_ops)
309 {
310 	target_if_direct_buf_rx_register_tx_ops(tx_ops);
311 }
312 #else
313 static void target_if_direct_buf_rx_tx_ops_register(
314 				struct wlan_lmac_if_tx_ops *tx_ops)
315 {
316 }
317 #endif /* DIRECT_BUF_RX_ENABLE */
318 
319 #ifdef WLAN_SUPPORT_GREEN_AP
320 static QDF_STATUS target_if_green_ap_tx_ops_register(
321 				struct wlan_lmac_if_tx_ops *tx_ops)
322 {
323 	return target_if_register_green_ap_tx_ops(tx_ops);
324 }
325 #else
326 static QDF_STATUS target_if_green_ap_tx_ops_register(
327 				struct wlan_lmac_if_tx_ops *tx_ops)
328 {
329 	return QDF_STATUS_SUCCESS;
330 }
331 #endif /* WLAN_SUPPORT_GREEN_AP */
332 #if defined(WLAN_CONV_CRYPTO_SUPPORTED) && defined(CRYPTO_SET_KEY_CONVERGED)
333 static void target_if_crypto_tx_ops_register(
334 				struct wlan_lmac_if_tx_ops *tx_ops)
335 {
336 	target_if_crypto_register_tx_ops(tx_ops);
337 }
338 #else
339 static inline void target_if_crypto_tx_ops_register(
340 				struct wlan_lmac_if_tx_ops *tx_ops)
341 {
342 }
343 #endif
344 
345 #ifdef FEATURE_COEX
346 static QDF_STATUS
347 target_if_coex_tx_ops_register(struct wlan_lmac_if_tx_ops *tx_ops)
348 {
349 	return target_if_coex_register_tx_ops(tx_ops);
350 }
351 #else
352 static inline QDF_STATUS
353 target_if_coex_tx_ops_register(struct wlan_lmac_if_tx_ops *tx_ops)
354 {
355 	return QDF_STATUS_SUCCESS;
356 }
357 #endif
358 
359 static void target_if_target_tx_ops_register(
360 		struct wlan_lmac_if_tx_ops *tx_ops)
361 {
362 	struct wlan_lmac_if_target_tx_ops *target_tx_ops;
363 
364 	if (!tx_ops) {
365 		target_if_err("invalid tx_ops");
366 		return;
367 	}
368 
369 	target_tx_ops = &tx_ops->target_tx_ops;
370 
371 	target_tx_ops->tgt_is_tgt_type_ar900b =
372 		target_is_tgt_type_ar900b;
373 
374 	target_tx_ops->tgt_is_tgt_type_ipq4019 =
375 		target_is_tgt_type_ipq4019;
376 
377 	target_tx_ops->tgt_is_tgt_type_qca9984 =
378 		target_is_tgt_type_qca9984;
379 
380 	target_tx_ops->tgt_is_tgt_type_qca9888 =
381 		target_is_tgt_type_qca9888;
382 
383 	target_tx_ops->tgt_is_tgt_type_adrastea =
384 		target_is_tgt_type_adrastea;
385 
386 	target_tx_ops->tgt_get_tgt_type =
387 		lmac_get_tgt_type;
388 
389 	target_tx_ops->tgt_get_tgt_version =
390 		lmac_get_tgt_version;
391 
392 	target_tx_ops->tgt_get_tgt_revision =
393 		lmac_get_tgt_revision;
394 }
395 
396 static QDF_STATUS
397 target_if_cp_stats_tx_ops_register(struct wlan_lmac_if_tx_ops *tx_ops)
398 {
399 	return target_if_cp_stats_register_tx_ops(tx_ops);
400 }
401 
402 static QDF_STATUS
403 target_if_vdev_mgr_tx_ops_register(struct wlan_lmac_if_tx_ops *tx_ops)
404 {
405 	return target_if_vdev_mgr_register_tx_ops(tx_ops);
406 }
407 
408 #ifdef QCA_WIFI_FTM
409 static
410 void target_if_ftm_tx_ops_register(struct wlan_lmac_if_tx_ops *tx_ops)
411 {
412 	target_if_ftm_register_tx_ops(tx_ops);
413 }
414 #else
415 static
416 void target_if_ftm_tx_ops_register(struct wlan_lmac_if_tx_ops *tx_ops)
417 {
418 }
419 #endif
420 static
421 QDF_STATUS target_if_register_umac_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops)
422 {
423 	/* call regulatory callback to register tx ops */
424 	target_if_register_regulatory_tx_ops(tx_ops);
425 
426 	/* call umac callback to register legacy tx ops */
427 	wlan_lmac_if_umac_tx_ops_register(tx_ops);
428 
429 	/* Register scan tx ops */
430 	target_if_scan_tx_ops_register(tx_ops);
431 
432 	target_if_atf_tx_ops_register(tx_ops);
433 
434 	target_if_sa_api_tx_ops_register(tx_ops);
435 
436 	target_if_cfr_tx_ops_register(tx_ops);
437 
438 	target_if_wifi_pos_tx_ops_register(tx_ops);
439 
440 	target_if_dfs_tx_ops_register(tx_ops);
441 
442 	target_if_son_tx_ops_register(tx_ops);
443 
444 	target_if_tdls_tx_ops_register(tx_ops);
445 
446 	target_if_fd_tx_ops_register(tx_ops);
447 
448 	target_if_target_tx_ops_register(tx_ops);
449 
450 	target_if_offchan_txrx_ops_register(tx_ops);
451 
452 	target_if_green_ap_tx_ops_register(tx_ops);
453 
454 	target_if_ftm_tx_ops_register(tx_ops);
455 
456 	target_if_cp_stats_tx_ops_register(tx_ops);
457 
458 	target_if_crypto_tx_ops_register(tx_ops);
459 
460 	target_if_vdev_mgr_tx_ops_register(tx_ops);
461 
462 	target_if_coex_tx_ops_register(tx_ops);
463 
464 	/* Converged UMAC components to register their TX-ops here */
465 	return QDF_STATUS_SUCCESS;
466 }
467 
468 QDF_STATUS target_if_register_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops)
469 {
470 	/* Converged UMAC components to register their TX-ops */
471 	target_if_register_umac_tx_ops(tx_ops);
472 
473 	/* Components parallel to UMAC to register their TX-ops here */
474 	target_if_sptrl_tx_ops_register(tx_ops);
475 
476 	/* Register direct buffer rx component tx ops here */
477 	target_if_direct_buf_rx_tx_ops_register(tx_ops);
478 
479 #ifdef CONVERGED_P2P_ENABLE
480 	/* Converged UMAC components to register P2P TX-ops */
481 	target_if_p2p_register_tx_ops(tx_ops);
482 #endif
483 
484 	return QDF_STATUS_SUCCESS;
485 }
486 qdf_export_symbol(target_if_register_tx_ops);
487 
488 wmi_legacy_service_ready_callback
489 target_if_get_psoc_legacy_service_ready_cb(void)
490 {
491 	wmi_legacy_service_ready_callback service_ready_cb;
492 
493 	qdf_spin_lock_bh(&g_target_if_ctx->lock);
494 	if (g_target_if_ctx->service_ready_cb)
495 		service_ready_cb = g_target_if_ctx->service_ready_cb;
496 	else
497 		service_ready_cb = NULL;
498 	qdf_spin_unlock_bh(&g_target_if_ctx->lock);
499 
500 	return service_ready_cb;
501 }
502 qdf_export_symbol(target_if_get_psoc_legacy_service_ready_cb);
503 
504 QDF_STATUS target_if_register_legacy_service_ready_cb(
505 	wmi_legacy_service_ready_callback service_ready_cb)
506 {
507 	qdf_spin_lock_bh(&g_target_if_ctx->lock);
508 	g_target_if_ctx->service_ready_cb = service_ready_cb;
509 	qdf_spin_unlock_bh(&g_target_if_ctx->lock);
510 
511 	return QDF_STATUS_SUCCESS;
512 }
513 qdf_export_symbol(target_if_register_legacy_service_ready_cb);
514 
515 QDF_STATUS target_if_alloc_pdev_tgt_info(struct wlan_objmgr_pdev *pdev)
516 {
517 	struct target_pdev_info *tgt_pdev_info;
518 
519 	if (!pdev) {
520 		target_if_err("pdev is null");
521 		return QDF_STATUS_E_INVAL;
522 	}
523 
524 	tgt_pdev_info = qdf_mem_malloc(sizeof(*tgt_pdev_info));
525 
526 	if (!tgt_pdev_info)
527 		return QDF_STATUS_E_NOMEM;
528 
529 	wlan_pdev_set_tgt_if_handle(pdev, tgt_pdev_info);
530 
531 	return QDF_STATUS_SUCCESS;
532 }
533 
534 QDF_STATUS target_if_free_pdev_tgt_info(struct wlan_objmgr_pdev *pdev)
535 {
536 	struct target_pdev_info *tgt_pdev_info;
537 
538 	if (!pdev) {
539 		target_if_err("pdev is null");
540 		return QDF_STATUS_E_INVAL;
541 	}
542 
543 	tgt_pdev_info = wlan_pdev_get_tgt_if_handle(pdev);
544 
545 	wlan_pdev_set_tgt_if_handle(pdev, NULL);
546 
547 	qdf_mem_free(tgt_pdev_info);
548 
549 	return QDF_STATUS_SUCCESS;
550 }
551 
552 QDF_STATUS target_if_alloc_psoc_tgt_info(struct wlan_objmgr_psoc *psoc)
553 {
554 	struct target_psoc_info *tgt_psoc_info;
555 
556 	if (!psoc) {
557 		target_if_err("psoc is null");
558 		return QDF_STATUS_E_INVAL;
559 	}
560 
561 	tgt_psoc_info = qdf_mem_malloc(sizeof(*tgt_psoc_info));
562 
563 	if (!tgt_psoc_info)
564 		return QDF_STATUS_E_NOMEM;
565 
566 	wlan_psoc_set_tgt_if_handle(psoc, tgt_psoc_info);
567 	target_psoc_set_preferred_hw_mode(tgt_psoc_info, WMI_HOST_HW_MODE_MAX);
568 
569 	qdf_event_create(&tgt_psoc_info->info.event);
570 
571 	return QDF_STATUS_SUCCESS;
572 }
573 
574 QDF_STATUS target_if_free_psoc_tgt_info(struct wlan_objmgr_psoc *psoc)
575 {
576 	struct target_psoc_info *tgt_psoc_info;
577 	struct wlan_psoc_host_service_ext_param *ext_param;
578 
579 	if (!psoc) {
580 		target_if_err("psoc is null");
581 		return QDF_STATUS_E_INVAL;
582 	}
583 
584 	tgt_psoc_info = wlan_psoc_get_tgt_if_handle(psoc);
585 
586 	ext_param = target_psoc_get_service_ext_param(tgt_psoc_info);
587 	if (!ext_param) {
588 		target_if_err("tgt_psoc_info is NULL");
589 		return QDF_STATUS_E_INVAL;
590 	}
591 	init_deinit_chainmask_table_free(ext_param);
592 	init_deinit_dbr_ring_cap_free(tgt_psoc_info);
593 	init_deinit_spectral_scaling_params_free(tgt_psoc_info);
594 
595 	qdf_event_destroy(&tgt_psoc_info->info.event);
596 
597 	wlan_psoc_set_tgt_if_handle(psoc, NULL);
598 
599 	qdf_mem_free(tgt_psoc_info);
600 
601 	return QDF_STATUS_SUCCESS;
602 }
603 
604 bool target_is_tgt_type_ar900b(uint32_t target_type)
605 {
606 	return target_type == TARGET_TYPE_AR900B;
607 }
608 
609 bool target_is_tgt_type_ipq4019(uint32_t target_type)
610 {
611 	return target_type == TARGET_TYPE_IPQ4019;
612 }
613 
614 bool target_is_tgt_type_qca9984(uint32_t target_type)
615 {
616 	return target_type == TARGET_TYPE_QCA9984;
617 }
618 
619 bool target_is_tgt_type_qca9888(uint32_t target_type)
620 {
621 	return target_type == TARGET_TYPE_QCA9888;
622 }
623 
624 bool target_is_tgt_type_adrastea(uint32_t target_type)
625 {
626 	return target_type == TARGET_TYPE_ADRASTEA;
627 }
628