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