1 /*
2 * Copyright (c) 2016-2021 The Linux Foundation. All rights reserved.
3 * Copyright (c) 2022-2023 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 /**
21 * DOC: This file init/deint functions for DFS module.
22 */
23
24 #include "wlan_dfs_ucfg_api.h"
25 #include "wlan_dfs_tgt_api.h"
26 #include <wlan_objmgr_vdev_obj.h>
27 #include "wlan_dfs_utils_api.h"
28 #ifndef MOBILE_DFS_SUPPORT
29 #include "ieee80211_mlme_dfs_interface.h"
30 #endif
31 #include "wlan_objmgr_global_obj.h"
32 #include "wlan_dfs_init_deinit_api.h"
33 #include "wlan_dfs_lmac_api.h"
34 #include "../../core/src/dfs.h"
35 #include "a_types.h"
36 #include "wlan_serialization_api.h"
37 #include <qdf_trace.h>
38 #include "wlan_scan_ucfg_api.h"
39 #include "wlan_dfs_mlme_api.h"
40 #include "../../core/src/dfs_zero_cac.h"
41
42 struct dfs_to_mlme global_dfs_to_mlme;
43
wlan_pdev_get_dfs_obj(struct wlan_objmgr_pdev * pdev)44 struct wlan_dfs *wlan_pdev_get_dfs_obj(struct wlan_objmgr_pdev *pdev)
45 {
46 struct wlan_dfs *dfs;
47 dfs = wlan_objmgr_pdev_get_comp_private_obj(pdev,
48 WLAN_UMAC_COMP_DFS);
49
50 return dfs;
51 }
52
53 /*
54 * register_dfs_precac_auto_chan_callbacks_freq() - Register auto chan switch
55 * frequency based APIs callback.
56 * @mlme_callback: Pointer to dfs_to_mlme.
57 */
58 #ifndef MOBILE_DFS_SUPPORT
59 #if defined(WLAN_DFS_PRECAC_AUTO_CHAN_SUPPORT) && defined(CONFIG_CHAN_FREQ_API)
60 static inline void
register_dfs_precac_auto_chan_callbacks_freq(struct dfs_to_mlme * mlme_callback)61 register_dfs_precac_auto_chan_callbacks_freq(struct dfs_to_mlme *mlme_callback)
62 {
63 if (!mlme_callback)
64 return;
65
66 mlme_callback->mlme_precac_chan_change_csa_for_freq =
67 mlme_dfs_precac_chan_change_csa_for_freq;
68 }
69 #else
70 static inline void
register_dfs_precac_auto_chan_callbacks_freq(struct dfs_to_mlme * mlme_callback)71 register_dfs_precac_auto_chan_callbacks_freq(struct dfs_to_mlme *mlme_callback)
72 {
73 }
74 #endif
75 #endif
76
77 /**
78 * register_dfs_postnol_csa_callback - Register CSA callback
79 * @mlme_callback: Pointer to dfs_to_mlme.
80 */
81 #ifndef MOBILE_DFS_SUPPORT
82 #if defined(QCA_SUPPORT_DFS_CHAN_POSTNOL) || defined(QCA_DFS_BW_EXPAND)
83 static inline void
register_dfs_postnol_csa_callback(struct dfs_to_mlme * mlme_callback)84 register_dfs_postnol_csa_callback(struct dfs_to_mlme *mlme_callback)
85 {
86 if (!mlme_callback)
87 return;
88
89 mlme_callback->mlme_postnol_chan_switch =
90 mlme_dfs_postnol_chan_switch;
91 }
92 #else
93 static inline void
register_dfs_postnol_csa_callback(struct dfs_to_mlme * mlme_callback)94 register_dfs_postnol_csa_callback(struct dfs_to_mlme *mlme_callback)
95 {
96 }
97 #endif
98
99 /**
100 * register_dfs_unpunc_chan_switch_callback() - Register unpuncture channel VDEV
101 * restart callback.
102 * @mlme_callback: Pointer to dfs_to_mlme.
103 */
104 #if defined(QCA_DFS_BW_PUNCTURE) && !defined(CONFIG_REG_CLIENT)
105 static inline void
register_dfs_unpunc_chan_switch_callback(struct dfs_to_mlme * mlme_callback)106 register_dfs_unpunc_chan_switch_callback(struct dfs_to_mlme *mlme_callback)
107 {
108 if (!mlme_callback)
109 return;
110
111 mlme_callback->mlme_unpunc_chan_switch =
112 mlme_dfs_unpunc_chan_switch;
113 }
114 #else
115 static inline void
register_dfs_unpunc_chan_switch_callback(struct dfs_to_mlme * mlme_callback)116 register_dfs_unpunc_chan_switch_callback(struct dfs_to_mlme *mlme_callback)
117 {
118 }
119 #endif
120 #endif /* MOBILE_DFS_SUPPORT */
121
122 /*
123 * register_dfs_callbacks_for_freq() - Register dfs callbacks.
124 * @mlme_callback: Pointer to dfs_to_mlme.
125 */
126 #ifndef MOBILE_DFS_SUPPORT
127 #ifdef CONFIG_CHAN_FREQ_API
128 static inline void
register_dfs_callbacks_for_freq(struct dfs_to_mlme * mlme_callback)129 register_dfs_callbacks_for_freq(struct dfs_to_mlme *mlme_callback)
130 {
131 if (!mlme_callback)
132 return;
133
134 mlme_callback->mlme_find_dot11_chan_for_freq =
135 mlme_dfs_find_dot11_chan_for_freq;
136 mlme_callback->mlme_get_cac_timeout_for_freq =
137 mlme_dfs_get_cac_timeout_for_freq;
138 mlme_callback->mlme_get_extchan_for_freq =
139 mlme_dfs_get_extchan_for_freq;
140 mlme_callback->mlme_start_csa_for_freq = mlme_dfs_start_csa_for_freq;
141 }
142 #endif
143 #endif
144
145 #if defined(WLAN_DFS_PARTIAL_OFFLOAD) && defined(HOST_DFS_SPOOF_TEST)
register_dfs_callbacks_spoof_success_failure(struct dfs_to_mlme * tmp_dfs_to_mlme)146 static void register_dfs_callbacks_spoof_success_failure(
147 struct dfs_to_mlme *tmp_dfs_to_mlme)
148 {
149 tmp_dfs_to_mlme->mlme_rebuild_chan_list_with_non_dfs_channels =
150 mlme_dfs_rebuild_chan_list_with_non_dfs_channels;
151 tmp_dfs_to_mlme->mlme_proc_spoof_success =
152 mlme_dfs_proc_spoof_success;
153 }
154 #else
register_dfs_callbacks_spoof_success_failure(struct dfs_to_mlme * tmp_dfs_to_mlme)155 static inline void register_dfs_callbacks_spoof_success_failure(
156 struct dfs_to_mlme *tmp_dfs_to_mlme)
157 {
158 }
159 #endif
160
161 #ifndef MOBILE_DFS_SUPPORT
register_dfs_callbacks(void)162 void register_dfs_callbacks(void)
163 {
164 struct dfs_to_mlme *tmp_dfs_to_mlme = &global_dfs_to_mlme;
165
166 tmp_dfs_to_mlme->pdev_component_obj_attach =
167 wlan_objmgr_pdev_component_obj_attach;
168 tmp_dfs_to_mlme->pdev_component_obj_detach =
169 wlan_objmgr_pdev_component_obj_detach;
170
171 tmp_dfs_to_mlme->dfs_start_rcsa = mlme_dfs_start_rcsa;
172 tmp_dfs_to_mlme->mlme_proc_cac = mlme_dfs_proc_cac;
173 tmp_dfs_to_mlme->mlme_deliver_event_up_after_cac =
174 mlme_dfs_deliver_event_up_after_cac;
175 tmp_dfs_to_mlme->mlme_set_no_chans_available =
176 mlme_dfs_set_no_chans_available;
177 tmp_dfs_to_mlme->mlme_ieee2mhz = mlme_dfs_ieee2mhz;
178 tmp_dfs_to_mlme->mlme_dfs_ch_flags_ext = mlme_dfs_dfs_ch_flags_ext;
179 tmp_dfs_to_mlme->mlme_channel_change_by_precac =
180 mlme_dfs_channel_change_by_precac;
181 tmp_dfs_to_mlme->mlme_nol_timeout_notification =
182 mlme_dfs_nol_timeout_notification;
183 tmp_dfs_to_mlme->mlme_clist_update = mlme_dfs_clist_update;
184
185 register_dfs_callbacks_spoof_success_failure(tmp_dfs_to_mlme);
186
187 tmp_dfs_to_mlme->mlme_restart_vaps_with_non_dfs_chan =
188 mlme_dfs_restart_vaps_with_non_dfs_chan;
189 tmp_dfs_to_mlme->mlme_is_opmode_sta =
190 mlme_dfs_is_opmode_sta;
191 tmp_dfs_to_mlme->mlme_check_allowed_prim_chanlist =
192 mlme_dfs_check_allowed_prim_chanlist;
193 tmp_dfs_to_mlme->mlme_update_scan_channel_list =
194 mlme_dfs_update_scan_channel_list;
195 tmp_dfs_to_mlme->mlme_bringdown_vaps =
196 mlme_dfs_bringdown_vaps;
197 tmp_dfs_to_mlme->mlme_dfs_deliver_event =
198 mlme_dfs_deliver_event;
199 tmp_dfs_to_mlme->mlme_is_inter_band_chan_switch_allowed =
200 mlme_is_inter_band_chan_switch_allowed;
201
202 tmp_dfs_to_mlme->mlme_acquire_radar_mode_switch_lock =
203 mlme_acquire_radar_mode_switch_lock;
204 tmp_dfs_to_mlme->mlme_release_radar_mode_switch_lock =
205 mlme_release_radar_mode_switch_lock;
206 tmp_dfs_to_mlme->mlme_mark_dfs =
207 mlme_dfs_mark_dfs;
208 tmp_dfs_to_mlme->mlme_set_tx_flag = mlme_dfs_set_tx_flag;
209 /*
210 * Register precac auto channel switch feature related callbacks
211 */
212 register_dfs_precac_auto_chan_callbacks_freq(tmp_dfs_to_mlme);
213 /* Register freq based callbacks */
214 register_dfs_callbacks_for_freq(tmp_dfs_to_mlme);
215 register_dfs_postnol_csa_callback(tmp_dfs_to_mlme);
216 register_dfs_unpunc_chan_switch_callback(tmp_dfs_to_mlme);
217 }
218 #else
register_dfs_callbacks(void)219 void register_dfs_callbacks(void)
220 {
221 struct dfs_to_mlme *tmp_dfs_to_mlme = &global_dfs_to_mlme;
222
223 tmp_dfs_to_mlme->pdev_component_obj_attach =
224 wlan_objmgr_pdev_component_obj_attach;
225 tmp_dfs_to_mlme->pdev_component_obj_detach =
226 wlan_objmgr_pdev_component_obj_detach;
227 }
228 #endif
229
230 /**
231 * dfs_psoc_obj_create_notification() - dfs psoc create notification handler
232 * @psoc: psoc object
233 * @arg_list: Argument list
234 *
235 * Return: QDF_STATUS
236 */
dfs_psoc_obj_create_notification(struct wlan_objmgr_psoc * psoc,void * arg_list)237 static QDF_STATUS dfs_psoc_obj_create_notification(struct wlan_objmgr_psoc *psoc,
238 void *arg_list)
239 {
240 QDF_STATUS status;
241 struct dfs_soc_priv_obj *dfs_soc_obj;
242
243 dfs_soc_obj = qdf_mem_malloc(sizeof(*dfs_soc_obj));
244 if (!dfs_soc_obj)
245 return QDF_STATUS_E_NOMEM;
246
247 dfs_soc_obj->psoc = psoc;
248
249 status = wlan_objmgr_psoc_component_obj_attach(psoc,
250 WLAN_UMAC_COMP_DFS,
251 (void *)dfs_soc_obj,
252 QDF_STATUS_SUCCESS);
253
254 if (QDF_IS_STATUS_ERROR(status)) {
255 dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS,
256 "Failed to attach psoc dfs component");
257 qdf_mem_free(dfs_soc_obj);
258 return status;
259 }
260 /* Initialize precac timer here*/
261 dfs_zero_cac_timer_init(dfs_soc_obj);
262
263 /* Initialize Rolling CAC timer */
264 dfs_rcac_timer_init(dfs_soc_obj);
265
266 /* DFS Agile SM initialization */
267 dfs_agile_sm_create(dfs_soc_obj);
268
269 dfs_debug(NULL, WLAN_DEBUG_DFS1,
270 "DFS obj attach to psoc successfully");
271
272 return status;
273 }
274
275 /**
276 * dfs_psoc_obj_destroy_notification() - dfs psoc destroy notification handler
277 * @psoc: psoc object
278 * @arg_list: Argument list
279 *
280 * Return: QDF_STATUS
281 */
dfs_psoc_obj_destroy_notification(struct wlan_objmgr_psoc * psoc,void * arg_list)282 static QDF_STATUS dfs_psoc_obj_destroy_notification(struct wlan_objmgr_psoc *psoc,
283 void *arg_list)
284 {
285 QDF_STATUS status;
286 struct dfs_soc_priv_obj *dfs_soc_obj;
287
288 dfs_soc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc,
289 WLAN_UMAC_COMP_DFS);
290 if (!dfs_soc_obj) {
291 dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS,
292 "Failed to get dfs obj in psoc");
293 return QDF_STATUS_E_FAILURE;
294 }
295
296 /* Delete DFS Agile SM */
297 dfs_agile_sm_destroy(dfs_soc_obj);
298
299 dfs_rcac_timer_deinit(dfs_soc_obj);
300 dfs_zero_cac_timer_detach(dfs_soc_obj);
301
302 status = wlan_objmgr_psoc_component_obj_detach(psoc,
303 WLAN_UMAC_COMP_DFS,
304 dfs_soc_obj);
305
306 if (QDF_IS_STATUS_ERROR(status))
307 dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS,
308 "Failed to detach psoc dfs component");
309
310 qdf_mem_free(dfs_soc_obj);
311
312 return status;
313 }
314
dfs_init(void)315 QDF_STATUS dfs_init(void)
316 {
317 QDF_STATUS status;
318
319 status = wlan_objmgr_register_psoc_create_handler(WLAN_UMAC_COMP_DFS,
320 dfs_psoc_obj_create_notification,
321 NULL);
322
323 if (QDF_IS_STATUS_ERROR(status)) {
324 dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS,
325 "Failed to register psoc create handler for dfs");
326 goto err_psoc_create;
327 }
328
329 status = wlan_objmgr_register_psoc_destroy_handler(WLAN_UMAC_COMP_DFS,
330 dfs_psoc_obj_destroy_notification,
331 NULL);
332
333 if (QDF_IS_STATUS_ERROR(status)) {
334 dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS,
335 "Failed to register psoc delete handler for dfs");
336 goto err_psoc_delete;
337 }
338
339 register_dfs_callbacks();
340
341 status = wlan_objmgr_register_pdev_create_handler(WLAN_UMAC_COMP_DFS,
342 wlan_dfs_pdev_obj_create_notification,
343 NULL);
344
345 if (QDF_IS_STATUS_ERROR(status)) {
346 dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS,
347 "Failed to register pdev create handler for dfs");
348 goto err_pdev_create;
349 }
350
351 status = wlan_objmgr_register_pdev_destroy_handler(WLAN_UMAC_COMP_DFS,
352 wlan_dfs_pdev_obj_destroy_notification,
353 NULL);
354
355 if (QDF_IS_STATUS_ERROR(status)) {
356 dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS,
357 "Failed to register pdev delete handler for dfs");
358 goto err_pdev_delete;
359 }
360
361 status = qdf_print_set_category_verbose(qdf_get_pidx(),
362 QDF_MODULE_ID_DFS,
363 QDF_TRACE_LEVEL_DEBUG,
364 true);
365
366 if (QDF_IS_STATUS_ERROR(status)) {
367 dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS,
368 "Failed to set verbose for category");
369 goto err_category_verbose;
370 }
371
372 return QDF_STATUS_SUCCESS;
373
374 err_category_verbose:
375 wlan_objmgr_unregister_pdev_destroy_handler(WLAN_UMAC_COMP_DFS,
376 wlan_dfs_pdev_obj_destroy_notification,
377 NULL);
378 err_pdev_delete:
379 wlan_objmgr_unregister_pdev_create_handler(WLAN_UMAC_COMP_DFS,
380 wlan_dfs_pdev_obj_create_notification,
381 NULL);
382 err_pdev_create:
383 wlan_objmgr_unregister_psoc_destroy_handler(WLAN_UMAC_COMP_DFS,
384 dfs_psoc_obj_destroy_notification,
385 NULL);
386 err_psoc_delete:
387 wlan_objmgr_unregister_psoc_create_handler(WLAN_UMAC_COMP_DFS,
388 dfs_psoc_obj_create_notification,
389 NULL);
390 err_psoc_create:
391 return status;
392 }
393
dfs_deinit(void)394 QDF_STATUS dfs_deinit(void)
395 {
396 QDF_STATUS status;
397
398 status = wlan_objmgr_unregister_psoc_create_handler(WLAN_UMAC_COMP_DFS,
399 dfs_psoc_obj_create_notification,
400 NULL);
401
402 if (QDF_IS_STATUS_ERROR(status))
403 dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS,
404 "Failed to deregister dfs psoc obj create");
405
406 status = wlan_objmgr_unregister_psoc_destroy_handler(WLAN_UMAC_COMP_DFS,
407 dfs_psoc_obj_destroy_notification,
408 NULL);
409
410 if (QDF_IS_STATUS_ERROR(status))
411 dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS,
412 "Failed to deregister dfs psoc obj destroy");
413
414 status = wlan_objmgr_unregister_pdev_create_handler(WLAN_UMAC_COMP_DFS,
415 wlan_dfs_pdev_obj_create_notification,
416 NULL);
417
418 if (QDF_IS_STATUS_ERROR(status))
419 dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS,
420 "Failed to deregister dfs pdev obj create");
421
422 status = wlan_objmgr_unregister_pdev_destroy_handler(WLAN_UMAC_COMP_DFS,
423 wlan_dfs_pdev_obj_destroy_notification,
424 NULL);
425
426 if (QDF_IS_STATUS_ERROR(status))
427 dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS,
428 "Failed to deregister dfs pdev obj destroy");
429
430 return QDF_STATUS_SUCCESS;
431 }
432
wlan_dfs_pdev_obj_create_notification(struct wlan_objmgr_pdev * pdev,void * arg)433 QDF_STATUS wlan_dfs_pdev_obj_create_notification(struct wlan_objmgr_pdev *pdev,
434 void *arg)
435 {
436 struct wlan_dfs *dfs = NULL;
437 struct wlan_objmgr_psoc *psoc;
438 struct wlan_lmac_if_dfs_tx_ops *dfs_tx_ops;
439 struct dfs_soc_priv_obj *dfs_soc_obj;
440 uint8_t pdev_id;
441 QDF_STATUS status;
442 bool is_5ghz = false;
443 bool is_6ghz_only_pdev;
444 qdf_freq_t low_5g, high_5g;
445
446 if (!pdev) {
447 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "null pdev");
448 return QDF_STATUS_E_FAILURE;
449 }
450
451 psoc = wlan_pdev_get_psoc(pdev);
452 if (!psoc) {
453 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "null psoc");
454 return QDF_STATUS_E_FAILURE;
455 }
456
457 wlan_reg_get_freq_range(pdev, NULL, NULL, &low_5g, &high_5g);
458 is_6ghz_only_pdev = wlan_reg_is_range_only6g(low_5g, high_5g);
459
460 if (is_6ghz_only_pdev) {
461 pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev);
462 dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS,
463 "Do not allocate DFS object for 6G, pdev_id = %d",
464 pdev_id);
465 return QDF_STATUS_SUCCESS;
466 }
467
468 dfs_tx_ops = wlan_psoc_get_dfs_txops(psoc);
469 if (!(dfs_tx_ops && dfs_tx_ops->dfs_is_pdev_5ghz)) {
470 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs_tx_ops is null");
471 return QDF_STATUS_E_FAILURE;
472 }
473
474 status = dfs_tx_ops->dfs_is_pdev_5ghz(pdev, &is_5ghz);
475 if (QDF_IS_STATUS_ERROR(status)) {
476 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "Failed to get is_5ghz value");
477 return QDF_STATUS_E_FAILURE;
478 }
479
480 if (!is_5ghz) {
481 pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev);
482 dfs_info(dfs, WLAN_DEBUG_DFS,
483 "Do not allocate DFS object for 2G, pdev_id = %d",
484 pdev_id);
485 return QDF_STATUS_SUCCESS;
486 }
487
488 if (dfs_create_object(&dfs) == 1) {
489 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "failed to create object");
490 return QDF_STATUS_E_FAILURE;
491 }
492
493 status = global_dfs_to_mlme.pdev_component_obj_attach(pdev,
494 WLAN_UMAC_COMP_DFS, (void *)dfs, QDF_STATUS_SUCCESS);
495 if (QDF_IS_STATUS_ERROR(status)) {
496 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "obj attach failed");
497 dfs_destroy_object(dfs);
498 return QDF_STATUS_E_FAILURE;
499 }
500
501 dfs->dfs_pdev_obj = pdev;
502
503 if (!dfs_tx_ops->dfs_is_tgt_offload) {
504 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,
505 "dfs_is_tgt_offload is null");
506 dfs_destroy_object(dfs);
507 return QDF_STATUS_E_FAILURE;
508 }
509
510 dfs->dfs_is_offload_enabled = dfs_tx_ops->dfs_is_tgt_offload(psoc);
511 dfs_info(dfs, WLAN_DEBUG_DFS, "dfs_offload %d",
512 dfs->dfs_is_offload_enabled);
513
514 if (!dfs_tx_ops->dfs_is_tgt_bangradar_320_supp) {
515 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,
516 "dfs_is_tgt_bangradar_320_supp is null");
517 dfs_destroy_object(dfs);
518 return QDF_STATUS_E_FAILURE;
519 }
520
521 dfs->dfs_is_bangradar_320_supported =
522 dfs_tx_ops->dfs_is_tgt_bangradar_320_supp(psoc);
523 dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs_bangradar_320_support %d",
524 dfs->dfs_is_bangradar_320_supported);
525
526 if (!dfs_tx_ops->dfs_is_tgt_radar_found_chan_freq_eq_center_freq) {
527 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,
528 "dfs_is_radar_found_chan_freq_eq_center_freq is null");
529 dfs_destroy_object(dfs);
530 return QDF_STATUS_E_FAILURE;
531 }
532
533 dfs->dfs_is_radar_found_chan_freq_eq_center_freq =
534 dfs_tx_ops->dfs_is_tgt_radar_found_chan_freq_eq_center_freq(psoc);
535 dfs_info(dfs, WLAN_DEBUG_DFS,
536 "dfs_is_radar_found_chan_freq_eq_center_freq %d",
537 dfs->dfs_is_radar_found_chan_freq_eq_center_freq);
538
539 dfs_soc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc,
540 WLAN_UMAC_COMP_DFS);
541 dfs->dfs_soc_obj = dfs_soc_obj;
542 dfs_agile_soc_obj_init(dfs, psoc);
543 dfs_create_punc_sm(dfs);
544
545 if (dfs_attach(dfs) == 1) {
546 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs_attch failed");
547 dfs_destroy_object(dfs);
548 return QDF_STATUS_E_FAILURE;
549 }
550
551 return QDF_STATUS_SUCCESS;
552 }
553
wlan_dfs_pdev_obj_destroy_notification(struct wlan_objmgr_pdev * pdev,void * arg)554 QDF_STATUS wlan_dfs_pdev_obj_destroy_notification(struct wlan_objmgr_pdev *pdev,
555 void *arg)
556 {
557 struct wlan_dfs *dfs = NULL;
558
559 if (!pdev) {
560 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "PDEV is NULL");
561 return QDF_STATUS_E_FAILURE;
562 }
563
564 dfs = wlan_pdev_get_dfs_obj(pdev);
565
566 /* DFS is NULL during unload. should we call this function before */
567 if (dfs) {
568 dfs_destroy_punc_sm(dfs);
569 dfs_detach(dfs);
570 global_dfs_to_mlme.pdev_component_obj_detach(pdev,
571 WLAN_UMAC_COMP_DFS,
572 (void *)dfs);
573
574 dfs->dfs_pdev_obj = NULL;
575 dfs_destroy_object(dfs);
576 }
577
578 return QDF_STATUS_SUCCESS;
579 }
580
dfs_scan_serialization_comp_info_cb(struct wlan_objmgr_vdev * vdev,union wlan_serialization_rules_info * comp_info,struct wlan_serialization_command * cmd)581 static void dfs_scan_serialization_comp_info_cb(
582 struct wlan_objmgr_vdev *vdev,
583 union wlan_serialization_rules_info *comp_info,
584 struct wlan_serialization_command *cmd)
585 {
586 struct wlan_dfs *dfs = NULL;
587 struct wlan_objmgr_pdev *pdev;
588
589 if (!comp_info) {
590 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "comp_info is NULL");
591 return;
592 }
593
594 if (!vdev) {
595 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "vdev is NULL");
596 return;
597 }
598
599 pdev = wlan_vdev_get_pdev(vdev);
600 if (!pdev) {
601 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "pdev is NULL");
602 return;
603 }
604
605 comp_info->scan_info.is_cac_in_progress = false;
606
607 if (!tgt_dfs_is_5ghz_supported_in_pdev(pdev))
608 return;
609
610 dfs = wlan_pdev_get_dfs_obj(pdev);
611 if (!dfs) {
612 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL");
613 return;
614 }
615
616 if (dfs_is_ap_cac_timer_running(dfs))
617 comp_info->scan_info.is_cac_in_progress = true;
618 }
619
wifi_dfs_psoc_enable(struct wlan_objmgr_psoc * psoc)620 QDF_STATUS wifi_dfs_psoc_enable(struct wlan_objmgr_psoc *psoc)
621 {
622 QDF_STATUS status;
623
624 status = tgt_dfs_reg_ev_handler(psoc);
625 if (status != QDF_STATUS_SUCCESS) {
626 dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS, "tgt_dfs_reg_ev_handler failed");
627 return QDF_STATUS_E_FAILURE;
628 }
629
630 status = wlan_serialization_register_comp_info_cb(psoc,
631 WLAN_UMAC_COMP_DFS,
632 WLAN_SER_CMD_SCAN,
633 dfs_scan_serialization_comp_info_cb);
634 if (status != QDF_STATUS_SUCCESS) {
635 dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS, "Serialize scan cmd register failed");
636 return status;
637 }
638
639 return QDF_STATUS_SUCCESS;
640 }
641
wifi_dfs_psoc_disable(struct wlan_objmgr_psoc * psoc)642 QDF_STATUS wifi_dfs_psoc_disable(struct wlan_objmgr_psoc *psoc)
643 {
644 QDF_STATUS status;
645
646 status = wlan_serialization_deregister_comp_info_cb(psoc,
647 WLAN_UMAC_COMP_DFS,
648 WLAN_SER_CMD_SCAN);
649 if (status != QDF_STATUS_SUCCESS) {
650 dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS, "Serialize scan cmd deregister failed");
651 return status;
652 }
653
654 return QDF_STATUS_SUCCESS;
655 }
656