xref: /wlan-dirver/qca-wifi-host-cmn/target_if/core/src/target_if_main.c (revision 302a1d9701784af5f4797b1a9fe07ae820b51907)
1 /*
2  * Copyright (c) 2017-2018 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_CONV_SPECTRAL_ENABLE
33 #include "target_if_spectral.h"
34 #endif
35 #include <target_if_reg.h>
36 #include <target_if_scan.h>
37 #include <target_if_ftm.h>
38 #ifdef DFS_COMPONENT_ENABLE
39 #include <target_if_dfs.h>
40 #endif
41 
42 #ifdef CONVERGED_P2P_ENABLE
43 #include "target_if_p2p.h"
44 #endif
45 
46 #ifdef WIFI_POS_CONVERGED
47 #include "target_if_wifi_pos.h"
48 #endif
49 
50 #ifdef WLAN_FEATURE_NAN_CONVERGENCE
51 #include "target_if_nan.h"
52 #endif /* WLAN_FEATURE_NAN_CONVERGENCE */
53 #ifdef CONVERGED_TDLS_ENABLE
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 
79 static struct target_if_ctx *g_target_if_ctx;
80 
81 struct target_if_ctx *target_if_get_ctx()
82 {
83 	return g_target_if_ctx;
84 }
85 
86 struct wlan_objmgr_psoc *target_if_get_psoc_from_scn_hdl(void *scn_handle)
87 {
88 	struct wlan_objmgr_psoc *psoc;
89 
90 	qdf_spin_lock_bh(&g_target_if_ctx->lock);
91 	if (scn_handle && g_target_if_ctx->get_psoc_hdl_cb)
92 		psoc = g_target_if_ctx->get_psoc_hdl_cb(scn_handle);
93 	else
94 		psoc = NULL;
95 	qdf_spin_unlock_bh(&g_target_if_ctx->lock);
96 
97 	return psoc;
98 }
99 
100 struct wlan_objmgr_pdev *target_if_get_pdev_from_scn_hdl(void *scn_handle)
101 {
102 	struct wlan_objmgr_pdev *pdev;
103 
104 	qdf_spin_lock_bh(&g_target_if_ctx->lock);
105 	if (scn_handle && g_target_if_ctx->get_pdev_hdl_cb)
106 		pdev = g_target_if_ctx->get_pdev_hdl_cb(scn_handle);
107 	else
108 		pdev = NULL;
109 	qdf_spin_unlock_bh(&g_target_if_ctx->lock);
110 
111 	return pdev;
112 }
113 
114 #ifdef DIRECT_BUF_RX_ENABLE
115 static QDF_STATUS target_if_direct_buf_rx_init(void)
116 {
117 	return direct_buf_rx_init();
118 }
119 
120 static QDF_STATUS target_if_direct_buf_rx_deinit(void)
121 {
122 	return direct_buf_rx_deinit();
123 }
124 #else
125 static QDF_STATUS target_if_direct_buf_rx_init(void)
126 {
127 	return QDF_STATUS_SUCCESS;
128 }
129 
130 static QDF_STATUS target_if_direct_buf_rx_deinit(void)
131 {
132 	return QDF_STATUS_SUCCESS;
133 }
134 #endif /* DIRECT_BUF_RX_ENABLE */
135 
136 QDF_STATUS target_if_open(get_psoc_handle_callback psoc_hdl_cb)
137 {
138 	g_target_if_ctx = qdf_mem_malloc(sizeof(*g_target_if_ctx));
139 	if (!g_target_if_ctx) {
140 		target_if_err("Cannot allocate target if ctx");
141 		QDF_ASSERT(0);
142 		return QDF_STATUS_E_NOMEM;
143 	}
144 
145 	qdf_spinlock_create(&g_target_if_ctx->lock);
146 
147 	qdf_spin_lock_bh(&g_target_if_ctx->lock);
148 	g_target_if_ctx->magic = TGT_MAGIC;
149 	g_target_if_ctx->get_psoc_hdl_cb = psoc_hdl_cb;
150 	qdf_spin_unlock_bh(&g_target_if_ctx->lock);
151 
152 	target_if_direct_buf_rx_init();
153 
154 	return QDF_STATUS_SUCCESS;
155 }
156 
157 QDF_STATUS target_if_close(void)
158 {
159 	if (!g_target_if_ctx) {
160 		QDF_ASSERT(0);
161 		target_if_err("target if ctx is null");
162 		return QDF_STATUS_E_INVAL;
163 	}
164 
165 	qdf_spin_lock_bh(&g_target_if_ctx->lock);
166 	g_target_if_ctx->magic = 0;
167 	g_target_if_ctx->get_psoc_hdl_cb = NULL;
168 	g_target_if_ctx->get_pdev_hdl_cb = NULL;
169 	g_target_if_ctx->service_ready_cb = NULL;
170 	qdf_spin_unlock_bh(&g_target_if_ctx->lock);
171 
172 	qdf_spinlock_destroy(&g_target_if_ctx->lock);
173 	qdf_mem_free(g_target_if_ctx);
174 	g_target_if_ctx = NULL;
175 
176 	target_if_direct_buf_rx_deinit();
177 
178 	return QDF_STATUS_SUCCESS;
179 }
180 qdf_export_symbol(target_if_close);
181 
182 QDF_STATUS target_if_store_pdev_target_if_ctx(
183 		get_pdev_handle_callback pdev_hdl_cb)
184 {
185 	if (!g_target_if_ctx) {
186 		QDF_ASSERT(0);
187 		target_if_err("target if ctx is null");
188 		return QDF_STATUS_E_INVAL;
189 	}
190 
191 	qdf_spin_lock_bh(&g_target_if_ctx->lock);
192 	g_target_if_ctx->get_pdev_hdl_cb = pdev_hdl_cb;
193 	qdf_spin_unlock_bh(&g_target_if_ctx->lock);
194 
195 	return QDF_STATUS_SUCCESS;
196 }
197 
198 #ifndef WLAN_OFFCHAN_TXRX_ENABLE
199 static void target_if_offchan_txrx_ops_register(
200 					struct wlan_lmac_if_tx_ops *tx_ops)
201 {
202 }
203 #endif /* WLAN_OFFCHAN_TXRX_ENABLE */
204 
205 #ifndef WLAN_ATF_ENABLE
206 static void target_if_atf_tx_ops_register(struct wlan_lmac_if_tx_ops *tx_ops)
207 {
208 }
209 #endif /* WLAN_ATF_ENABLE */
210 
211 #ifndef WLAN_SA_API_ENABLE
212 static void target_if_sa_api_tx_ops_register(struct wlan_lmac_if_tx_ops *tx_ops)
213 {
214 }
215 #endif /* WLAN_SA_API_ENABLE */
216 
217 #ifdef WLAN_SUPPORT_FILS
218 static void target_if_fd_tx_ops_register(struct wlan_lmac_if_tx_ops *tx_ops)
219 {
220 	target_if_fd_register_tx_ops(tx_ops);
221 }
222 #else
223 static void target_if_fd_tx_ops_register(struct wlan_lmac_if_tx_ops *tx_ops)
224 {
225 }
226 #endif
227 
228 #ifdef WIFI_POS_CONVERGED
229 static void target_if_wifi_pos_tx_ops_register(
230 			struct wlan_lmac_if_tx_ops *tx_ops)
231 {
232 	target_if_wifi_pos_register_tx_ops(tx_ops);
233 }
234 #else
235 static void target_if_wifi_pos_tx_ops_register(
236 			struct wlan_lmac_if_tx_ops *tx_ops)
237 {
238 }
239 #endif
240 #ifdef QCA_SUPPORT_SON
241 static void target_if_son_tx_ops_register(
242 			struct wlan_lmac_if_tx_ops *tx_ops)
243 {
244 	target_if_son_register_tx_ops(tx_ops);
245 	return;
246 }
247 #else
248 static void target_if_son_tx_ops_register(
249 			struct wlan_lmac_if_tx_ops *tx_ops)
250 {
251 	return;
252 }
253 #endif
254 
255 #ifdef WLAN_FEATURE_NAN_CONVERGENCE
256 static void target_if_nan_tx_ops_register(
257 				struct wlan_lmac_if_tx_ops *tx_ops)
258 {
259 	target_if_nan_register_tx_ops(tx_ops);
260 }
261 #else
262 static void target_if_nan_tx_ops_register(
263 				struct wlan_lmac_if_tx_ops *tx_ops)
264 {
265 }
266 #endif /* WLAN_FEATURE_NAN_CONVERGENCE */
267 
268 #ifdef CONVERGED_TDLS_ENABLE
269 static void target_if_tdls_tx_ops_register(struct wlan_lmac_if_tx_ops *tx_ops)
270 {
271 	target_if_tdls_register_tx_ops(tx_ops);
272 }
273 #else
274 static void target_if_tdls_tx_ops_register(struct wlan_lmac_if_tx_ops *tx_ops)
275 {
276 }
277 #endif /* CONVERGED_TDLS_ENABLE */
278 
279 #ifdef DFS_COMPONENT_ENABLE
280 static void target_if_dfs_tx_ops_register(
281 				struct wlan_lmac_if_tx_ops *tx_ops)
282 {
283 	target_if_register_dfs_tx_ops(tx_ops);
284 }
285 #else
286 static void target_if_dfs_tx_ops_register(
287 				struct wlan_lmac_if_tx_ops *tx_ops)
288 {
289 }
290 #endif /* DFS_COMPONENT_ENABLE */
291 
292 #ifdef WLAN_CONV_SPECTRAL_ENABLE
293 static void target_if_sptrl_tx_ops_register(
294 				struct wlan_lmac_if_tx_ops *tx_ops)
295 {
296 	target_if_sptrl_register_tx_ops(tx_ops);
297 }
298 #else
299 static void target_if_sptrl_tx_ops_register(
300 				struct wlan_lmac_if_tx_ops *tx_ops)
301 {
302 }
303 #endif /* WLAN_CONV_SPECTRAL_ENABLE */
304 
305 #ifdef DIRECT_BUF_RX_ENABLE
306 static void target_if_direct_buf_rx_tx_ops_register(
307 				struct wlan_lmac_if_tx_ops *tx_ops)
308 {
309 	target_if_direct_buf_rx_register_tx_ops(tx_ops);
310 }
311 #else
312 static void target_if_direct_buf_rx_tx_ops_register(
313 				struct wlan_lmac_if_tx_ops *tx_ops)
314 {
315 }
316 #endif /* DIRECT_BUF_RX_ENABLE */
317 
318 #ifdef WLAN_SUPPORT_GREEN_AP
319 static QDF_STATUS target_if_green_ap_tx_ops_register(
320 				struct wlan_lmac_if_tx_ops *tx_ops)
321 {
322 	return target_if_register_green_ap_tx_ops(tx_ops);
323 }
324 #else
325 static QDF_STATUS target_if_green_ap_tx_ops_register(
326 				struct wlan_lmac_if_tx_ops *tx_ops)
327 {
328 	return QDF_STATUS_SUCCESS;
329 }
330 #endif /* WLAN_SUPPORT_GREEN_AP */
331 
332 static void target_if_target_tx_ops_register(
333 		struct wlan_lmac_if_tx_ops *tx_ops)
334 {
335 	struct wlan_lmac_if_target_tx_ops *target_tx_ops;
336 
337 	if (!tx_ops) {
338 		target_if_err("invalid tx_ops");
339 		return;
340 	}
341 
342 	target_tx_ops = &tx_ops->target_tx_ops;
343 
344 	target_tx_ops->tgt_is_tgt_type_ar900b =
345 		target_is_tgt_type_ar900b;
346 
347 	target_tx_ops->tgt_is_tgt_type_ipq4019 =
348 		target_is_tgt_type_ipq4019;
349 
350 	target_tx_ops->tgt_is_tgt_type_qca9984 =
351 		target_is_tgt_type_qca9984;
352 
353 	target_tx_ops->tgt_is_tgt_type_qca9888 =
354 		target_is_tgt_type_qca9888;
355 
356 	target_tx_ops->tgt_get_tgt_type =
357 		lmac_get_tgt_type;
358 
359 	target_tx_ops->tgt_get_tgt_version =
360 		lmac_get_tgt_version;
361 
362 	target_tx_ops->tgt_get_tgt_revision =
363 		lmac_get_tgt_revision;
364 }
365 
366 static QDF_STATUS
367 target_if_cp_stats_tx_ops_register(struct wlan_lmac_if_tx_ops *tx_ops)
368 {
369 	return target_if_cp_stats_register_tx_ops(tx_ops);
370 }
371 
372 #ifdef QCA_WIFI_FTM
373 static
374 void target_if_ftm_tx_ops_register(struct wlan_lmac_if_tx_ops *tx_ops)
375 {
376 	target_if_ftm_register_tx_ops(tx_ops);
377 }
378 #else
379 static
380 void target_if_ftm_tx_ops_register(struct wlan_lmac_if_tx_ops *tx_ops)
381 {
382 }
383 #endif
384 static
385 QDF_STATUS target_if_register_umac_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops)
386 {
387 	/* call regulatory callback to register tx ops */
388 	target_if_register_regulatory_tx_ops(tx_ops);
389 
390 	/* call umac callback to register legacy tx ops */
391 	wlan_lmac_if_umac_tx_ops_register(tx_ops);
392 
393 	/* Register scan tx ops */
394 	target_if_scan_tx_ops_register(tx_ops);
395 
396 	target_if_atf_tx_ops_register(tx_ops);
397 
398 	target_if_sa_api_tx_ops_register(tx_ops);
399 
400 	target_if_wifi_pos_tx_ops_register(tx_ops);
401 
402 	target_if_nan_tx_ops_register(tx_ops);
403 
404 	target_if_dfs_tx_ops_register(tx_ops);
405 
406 	target_if_son_tx_ops_register(tx_ops);
407 
408 	target_if_tdls_tx_ops_register(tx_ops);
409 
410 	target_if_fd_tx_ops_register(tx_ops);
411 
412 	target_if_target_tx_ops_register(tx_ops);
413 
414 	target_if_offchan_txrx_ops_register(tx_ops);
415 
416 	target_if_green_ap_tx_ops_register(tx_ops);
417 
418 	target_if_ftm_tx_ops_register(tx_ops);
419 
420 	target_if_cp_stats_tx_ops_register(tx_ops);
421 
422 	/* Converged UMAC components to register their TX-ops here */
423 	return QDF_STATUS_SUCCESS;
424 }
425 
426 QDF_STATUS target_if_register_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops)
427 {
428 	/* Converged UMAC components to register their TX-ops */
429 	target_if_register_umac_tx_ops(tx_ops);
430 
431 	/* Components parallel to UMAC to register their TX-ops here */
432 	target_if_sptrl_tx_ops_register(tx_ops);
433 
434 	/* Register direct buffer rx component tx ops here */
435 	target_if_direct_buf_rx_tx_ops_register(tx_ops);
436 
437 #ifdef CONVERGED_P2P_ENABLE
438 	/* Converged UMAC components to register P2P TX-ops */
439 	target_if_p2p_register_tx_ops(tx_ops);
440 #endif
441 
442 	return QDF_STATUS_SUCCESS;
443 }
444 qdf_export_symbol(target_if_register_tx_ops);
445 
446 wmi_legacy_service_ready_callback
447 target_if_get_psoc_legacy_service_ready_cb(void)
448 {
449 	wmi_legacy_service_ready_callback service_ready_cb;
450 
451 	qdf_spin_lock_bh(&g_target_if_ctx->lock);
452 	if (g_target_if_ctx->service_ready_cb)
453 		service_ready_cb = g_target_if_ctx->service_ready_cb;
454 	else
455 		service_ready_cb = NULL;
456 	qdf_spin_unlock_bh(&g_target_if_ctx->lock);
457 
458 	return service_ready_cb;
459 }
460 qdf_export_symbol(target_if_get_psoc_legacy_service_ready_cb);
461 
462 QDF_STATUS target_if_register_legacy_service_ready_cb(
463 	wmi_legacy_service_ready_callback service_ready_cb)
464 {
465 	qdf_spin_lock_bh(&g_target_if_ctx->lock);
466 	g_target_if_ctx->service_ready_cb = service_ready_cb;
467 	qdf_spin_unlock_bh(&g_target_if_ctx->lock);
468 
469 	return QDF_STATUS_SUCCESS;
470 }
471 qdf_export_symbol(target_if_register_legacy_service_ready_cb);
472 
473 QDF_STATUS target_if_alloc_pdev_tgt_info(struct wlan_objmgr_pdev *pdev)
474 {
475 	struct target_pdev_info *tgt_pdev_info;
476 
477 	if (!pdev) {
478 		target_if_err("pdev is null");
479 		return QDF_STATUS_E_INVAL;
480 	}
481 
482 	tgt_pdev_info = qdf_mem_malloc(sizeof(*tgt_pdev_info));
483 
484 	if (tgt_pdev_info == NULL) {
485 		target_if_err("Failed to allocate pdev target info");
486 		return QDF_STATUS_E_NOMEM;
487 	}
488 
489 	wlan_pdev_set_tgt_if_handle(pdev, tgt_pdev_info);
490 
491 	return QDF_STATUS_SUCCESS;
492 }
493 
494 QDF_STATUS target_if_free_pdev_tgt_info(struct wlan_objmgr_pdev *pdev)
495 {
496 	struct target_pdev_info *tgt_pdev_info;
497 
498 	if (!pdev) {
499 		target_if_err("pdev is null");
500 		return QDF_STATUS_E_INVAL;
501 	}
502 
503 	tgt_pdev_info = wlan_pdev_get_tgt_if_handle(pdev);
504 
505 	wlan_pdev_set_tgt_if_handle(pdev, NULL);
506 
507 	qdf_mem_free(tgt_pdev_info);
508 
509 	return QDF_STATUS_SUCCESS;
510 }
511 
512 QDF_STATUS target_if_alloc_psoc_tgt_info(struct wlan_objmgr_psoc *psoc)
513 {
514 	struct target_psoc_info *tgt_psoc_info;
515 
516 	if (!psoc) {
517 		target_if_err("psoc is null");
518 		return QDF_STATUS_E_INVAL;
519 	}
520 
521 	tgt_psoc_info = qdf_mem_malloc(sizeof(*tgt_psoc_info));
522 
523 	if (tgt_psoc_info == NULL) {
524 		target_if_err("Failed to allocate psoc target info");
525 		return QDF_STATUS_E_NOMEM;
526 	}
527 
528 	wlan_psoc_set_tgt_if_handle(psoc, tgt_psoc_info);
529 	target_psoc_set_preferred_hw_mode(tgt_psoc_info, WMI_HOST_HW_MODE_MAX);
530 
531 	qdf_event_create(&tgt_psoc_info->info.event);
532 
533 	return QDF_STATUS_SUCCESS;
534 }
535 
536 QDF_STATUS target_if_free_psoc_tgt_info(struct wlan_objmgr_psoc *psoc)
537 {
538 	struct target_psoc_info *tgt_psoc_info;
539 	struct wlan_psoc_host_service_ext_param *ext_param;
540 
541 	if (!psoc) {
542 		target_if_err("psoc is null");
543 		return QDF_STATUS_E_INVAL;
544 	}
545 
546 	tgt_psoc_info = wlan_psoc_get_tgt_if_handle(psoc);
547 
548 	ext_param = target_psoc_get_service_ext_param(tgt_psoc_info);
549 	if (!ext_param) {
550 		target_if_err("tgt_psoc_info is NULL");
551 		return QDF_STATUS_E_INVAL;
552 	}
553 	init_deinit_chainmask_table_free(ext_param);
554 	init_deinit_dbr_ring_cap_free(tgt_psoc_info);
555 
556 	qdf_event_destroy(&tgt_psoc_info->info.event);
557 
558 	wlan_psoc_set_tgt_if_handle(psoc, NULL);
559 
560 	qdf_mem_free(tgt_psoc_info);
561 
562 	return QDF_STATUS_SUCCESS;
563 }
564 
565 bool target_is_tgt_type_ar900b(uint32_t target_type)
566 {
567 	return target_type == TARGET_TYPE_AR900B;
568 }
569 
570 bool target_is_tgt_type_ipq4019(uint32_t target_type)
571 {
572 	return target_type == TARGET_TYPE_IPQ4019;
573 }
574 
575 bool target_is_tgt_type_qca9984(uint32_t target_type)
576 {
577 	return target_type == TARGET_TYPE_QCA9984;
578 }
579 
580 bool target_is_tgt_type_qca9888(uint32_t target_type)
581 {
582 	return target_type == TARGET_TYPE_QCA9888;
583 }
584