1 /*
2 * Copyright (c) 2016-2021 The Linux Foundation. All rights reserved.
3 * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
4 *
5 *
6 * Permission to use, copy, modify, and/or distribute this software for
7 * any purpose with or without fee is hereby granted, provided that the
8 * above copyright notice and this permission notice appear in all
9 * copies.
10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
12 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
13 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
14 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
15 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
16 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
17 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
18 * PERFORMANCE OF THIS SOFTWARE.
19 */
20
21 /**
22 * DOC: This file has the DFS dispatcher API implementation which is exposed
23 * to outside of DFS component.
24 */
25
26 #include "wlan_dfs_ucfg_api.h"
27 #include "wlan_dfs_init_deinit_api.h"
28 #include "../../core/src/dfs.h"
29 #include "../../core/src/dfs_zero_cac.h"
30 #include "../../core/src/dfs_partial_offload_radar.h"
31 #include "../../core/src/dfs_process_radar_found_ind.h"
32 #include <qdf_module.h>
33
ucfg_dfs_is_ap_cac_timer_running(struct wlan_objmgr_pdev * pdev,int * is_ap_cac_timer_running)34 QDF_STATUS ucfg_dfs_is_ap_cac_timer_running(struct wlan_objmgr_pdev *pdev,
35 int *is_ap_cac_timer_running)
36 {
37 struct wlan_dfs *dfs;
38
39 dfs = wlan_pdev_get_dfs_obj(pdev);
40 if (!dfs)
41 return QDF_STATUS_E_FAILURE;
42
43 *is_ap_cac_timer_running = dfs_is_ap_cac_timer_running(dfs);
44
45 return QDF_STATUS_SUCCESS;
46 }
47 qdf_export_symbol(ucfg_dfs_is_ap_cac_timer_running);
48
ucfg_dfs_getnol(struct wlan_objmgr_pdev * pdev,void * dfs_nolinfo)49 QDF_STATUS ucfg_dfs_getnol(struct wlan_objmgr_pdev *pdev,
50 void *dfs_nolinfo)
51 {
52 struct wlan_dfs *dfs;
53
54 dfs = wlan_pdev_get_dfs_obj(pdev);
55 if (!dfs)
56 return QDF_STATUS_E_FAILURE;
57
58 dfs_getnol(dfs, dfs_nolinfo);
59
60 return QDF_STATUS_SUCCESS;
61 }
62 qdf_export_symbol(ucfg_dfs_getnol);
63
ucfg_dfs_override_cac_timeout(struct wlan_objmgr_pdev * pdev,int cac_timeout,int * status)64 QDF_STATUS ucfg_dfs_override_cac_timeout(struct wlan_objmgr_pdev *pdev,
65 int cac_timeout,
66 int *status)
67 {
68 struct wlan_dfs *dfs;
69
70 dfs = wlan_pdev_get_dfs_obj(pdev);
71 if (!dfs)
72 return QDF_STATUS_E_FAILURE;
73
74 *status = dfs_override_cac_timeout(dfs, cac_timeout);
75
76 return QDF_STATUS_SUCCESS;
77 }
78 qdf_export_symbol(ucfg_dfs_override_cac_timeout);
79
ucfg_dfs_get_override_cac_timeout(struct wlan_objmgr_pdev * pdev,int * cac_timeout,int * status)80 QDF_STATUS ucfg_dfs_get_override_cac_timeout(struct wlan_objmgr_pdev *pdev,
81 int *cac_timeout,
82 int *status)
83 {
84 struct wlan_dfs *dfs;
85
86 dfs = wlan_pdev_get_dfs_obj(pdev);
87 if (!dfs)
88 return QDF_STATUS_E_FAILURE;
89
90 *status = dfs_get_override_cac_timeout(dfs, cac_timeout);
91
92 return QDF_STATUS_SUCCESS;
93 }
94 qdf_export_symbol(ucfg_dfs_get_override_cac_timeout);
95
ucfg_dfs_get_override_precac_timeout(struct wlan_objmgr_pdev * pdev,int * precac_timeout)96 QDF_STATUS ucfg_dfs_get_override_precac_timeout(struct wlan_objmgr_pdev *pdev,
97 int *precac_timeout)
98 {
99 struct wlan_dfs *dfs;
100
101 dfs = wlan_pdev_get_dfs_obj(pdev);
102 if (!dfs)
103 return QDF_STATUS_E_FAILURE;
104
105 dfs_get_override_precac_timeout(dfs, precac_timeout);
106
107 return QDF_STATUS_SUCCESS;
108 }
109 qdf_export_symbol(ucfg_dfs_get_override_precac_timeout);
110
ucfg_dfs_override_precac_timeout(struct wlan_objmgr_pdev * pdev,int precac_timeout)111 QDF_STATUS ucfg_dfs_override_precac_timeout(struct wlan_objmgr_pdev *pdev,
112 int precac_timeout)
113 {
114 struct wlan_dfs *dfs;
115
116 dfs = wlan_pdev_get_dfs_obj(pdev);
117 if (!dfs)
118 return QDF_STATUS_E_FAILURE;
119
120 dfs_override_precac_timeout(dfs, precac_timeout);
121
122 return QDF_STATUS_SUCCESS;
123 }
124 qdf_export_symbol(ucfg_dfs_override_precac_timeout);
125
ucfg_dfs_set_precac_enable(struct wlan_objmgr_pdev * pdev,uint32_t value)126 QDF_STATUS ucfg_dfs_set_precac_enable(struct wlan_objmgr_pdev *pdev,
127 uint32_t value)
128 {
129 struct wlan_dfs *dfs;
130
131 dfs = wlan_pdev_get_dfs_obj(pdev);
132 if (!dfs) {
133 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "null dfs");
134 return QDF_STATUS_E_FAILURE;
135 }
136
137 dfs_set_precac_enable(dfs, value);
138
139 return QDF_STATUS_SUCCESS;
140 }
141 qdf_export_symbol(ucfg_dfs_set_precac_enable);
142
ucfg_dfs_get_agile_precac_enable(struct wlan_objmgr_pdev * pdev,bool * buff)143 QDF_STATUS ucfg_dfs_get_agile_precac_enable(struct wlan_objmgr_pdev *pdev,
144 bool *buff)
145 {
146 struct wlan_dfs *dfs;
147
148 if (!pdev || !buff)
149 return QDF_STATUS_E_FAILURE;
150
151 if (!tgt_dfs_is_5ghz_supported_in_pdev(pdev)) {
152 *buff = false;
153 return QDF_STATUS_SUCCESS;
154 }
155
156 dfs = wlan_pdev_get_dfs_obj(pdev);
157 if (!dfs) {
158 dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, "null dfs");
159 *buff = false;
160 return QDF_STATUS_SUCCESS;
161 }
162
163 *buff = dfs_is_agile_precac_enabled(dfs);
164
165 return QDF_STATUS_SUCCESS;
166 }
167
168 qdf_export_symbol(ucfg_dfs_get_agile_precac_enable);
169
170 QDF_STATUS
ucfg_dfs_set_nol_subchannel_marking(struct wlan_objmgr_pdev * pdev,bool nol_subchannel_marking)171 ucfg_dfs_set_nol_subchannel_marking(struct wlan_objmgr_pdev *pdev,
172 bool nol_subchannel_marking)
173 {
174 struct wlan_dfs *dfs;
175
176 dfs = wlan_pdev_get_dfs_obj(pdev);
177 if (!dfs)
178 return QDF_STATUS_E_FAILURE;
179
180 dfs_set_nol_subchannel_marking(dfs, nol_subchannel_marking);
181
182 return QDF_STATUS_SUCCESS;
183 }
184 qdf_export_symbol(ucfg_dfs_set_nol_subchannel_marking);
185
ucfg_dfs_get_nol_subchannel_marking(struct wlan_objmgr_pdev * pdev,bool * nol_subchannel_marking)186 QDF_STATUS ucfg_dfs_get_nol_subchannel_marking(struct wlan_objmgr_pdev *pdev,
187 bool *nol_subchannel_marking)
188 {
189 struct wlan_dfs *dfs;
190
191 dfs = wlan_pdev_get_dfs_obj(pdev);
192 if (!dfs)
193 return QDF_STATUS_E_FAILURE;
194
195 dfs_get_nol_subchannel_marking(dfs, nol_subchannel_marking);
196
197 return QDF_STATUS_SUCCESS;
198 }
199 qdf_export_symbol(ucfg_dfs_get_nol_subchannel_marking);
200 #ifdef WLAN_DFS_PRECAC_AUTO_CHAN_SUPPORT
ucfg_dfs_set_precac_intermediate_chan(struct wlan_objmgr_pdev * pdev,uint32_t value)201 QDF_STATUS ucfg_dfs_set_precac_intermediate_chan(struct wlan_objmgr_pdev *pdev,
202 uint32_t value)
203 {
204 struct wlan_dfs *dfs;
205
206 dfs = wlan_pdev_get_dfs_obj(pdev);
207 if (!dfs) {
208 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "null dfs");
209 return QDF_STATUS_E_FAILURE;
210 }
211
212 dfs_set_precac_intermediate_chan(dfs, value);
213
214 return QDF_STATUS_SUCCESS;
215 }
216
ucfg_dfs_get_precac_intermediate_chan(struct wlan_objmgr_pdev * pdev,int * buff)217 QDF_STATUS ucfg_dfs_get_precac_intermediate_chan(struct wlan_objmgr_pdev *pdev,
218 int *buff)
219 {
220 struct wlan_dfs *dfs;
221
222 dfs = wlan_pdev_get_dfs_obj(pdev);
223 if (!dfs) {
224 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "null dfs");
225 return QDF_STATUS_E_FAILURE;
226 }
227
228 *buff = dfs_get_precac_intermediate_chan(dfs);
229
230 return QDF_STATUS_SUCCESS;
231 }
232
233 #ifdef CONFIG_CHAN_FREQ_API
234 enum precac_chan_state
ucfg_dfs_get_precac_chan_state_for_freq(struct wlan_objmgr_pdev * pdev,uint16_t precac_chan_freq)235 ucfg_dfs_get_precac_chan_state_for_freq(struct wlan_objmgr_pdev *pdev,
236 uint16_t precac_chan_freq)
237 {
238 struct wlan_dfs *dfs;
239 enum precac_chan_state retval = PRECAC_ERR;
240
241 dfs = wlan_pdev_get_dfs_obj(pdev);
242 if (!dfs) {
243 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "null dfs");
244 return PRECAC_ERR;
245 }
246
247 retval = dfs_get_precac_chan_state_for_freq(dfs, precac_chan_freq);
248 if (retval == PRECAC_ERR) {
249 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,
250 "Could not find precac channel state");
251 }
252
253 return retval;
254 }
255 #endif
256 #endif
257
258 #ifdef MOBILE_DFS_SUPPORT
ucfg_dfs_update_config(struct wlan_objmgr_psoc * psoc,struct dfs_user_config * req)259 QDF_STATUS ucfg_dfs_update_config(struct wlan_objmgr_psoc *psoc,
260 struct dfs_user_config *req)
261 {
262 struct dfs_soc_priv_obj *soc_obj;
263
264 if (!psoc || !req) {
265 dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS,
266 "psoc: 0x%pK, req: 0x%pK", psoc, req);
267 return QDF_STATUS_E_FAILURE;
268 }
269
270 soc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc,
271 WLAN_UMAC_COMP_DFS);
272 if (!soc_obj) {
273 dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS,
274 "Failed to get dfs psoc component");
275 return QDF_STATUS_E_FAILURE;
276 }
277
278 soc_obj->dfs_is_phyerr_filter_offload =
279 req->dfs_is_phyerr_filter_offload;
280
281 return QDF_STATUS_SUCCESS;
282 }
283 qdf_export_symbol(ucfg_dfs_update_config);
284 #endif
285
286 #if defined(WLAN_DFS_PARTIAL_OFFLOAD) && defined(HOST_DFS_SPOOF_TEST)
ucfg_dfs_set_override_status_timeout(struct wlan_objmgr_pdev * pdev,int status_timeout)287 QDF_STATUS ucfg_dfs_set_override_status_timeout(struct wlan_objmgr_pdev *pdev,
288 int status_timeout)
289 {
290 struct wlan_dfs *dfs;
291
292 dfs = wlan_pdev_get_dfs_obj(pdev);
293 if (!dfs) {
294 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "null dfs");
295 return QDF_STATUS_E_FAILURE;
296 }
297
298 dfs_set_override_status_timeout(dfs, status_timeout);
299
300 return QDF_STATUS_SUCCESS;
301 }
302
303 qdf_export_symbol(ucfg_dfs_set_override_status_timeout);
304
ucfg_dfs_get_override_status_timeout(struct wlan_objmgr_pdev * pdev,int * status_timeout)305 QDF_STATUS ucfg_dfs_get_override_status_timeout(struct wlan_objmgr_pdev *pdev,
306 int *status_timeout)
307 {
308 struct wlan_dfs *dfs;
309
310 dfs = wlan_pdev_get_dfs_obj(pdev);
311 if (!dfs) {
312 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "null dfs");
313 return QDF_STATUS_E_FAILURE;
314 }
315
316 dfs_get_override_status_timeout(dfs, status_timeout);
317
318 return QDF_STATUS_SUCCESS;
319 }
320
321 qdf_export_symbol(ucfg_dfs_get_override_status_timeout);
322 #endif
323
324 #if defined(WLAN_DFS_PARTIAL_OFFLOAD) && defined(WLAN_DFS_SYNTHETIC_RADAR)
ucfg_dfs_allow_hw_pulses(struct wlan_objmgr_pdev * pdev,bool allow_hw_pulses)325 void ucfg_dfs_allow_hw_pulses(struct wlan_objmgr_pdev *pdev,
326 bool allow_hw_pulses)
327 {
328 struct wlan_dfs *dfs;
329
330 if (!tgt_dfs_is_5ghz_supported_in_pdev(pdev))
331 return;
332
333 dfs = wlan_pdev_get_dfs_obj(pdev);
334 if (!dfs) {
335 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL");
336 return;
337 }
338
339 dfs_allow_hw_pulses(dfs, allow_hw_pulses);
340 }
341
342 qdf_export_symbol(ucfg_dfs_allow_hw_pulses);
343
ucfg_dfs_is_hw_pulses_allowed(struct wlan_objmgr_pdev * pdev)344 bool ucfg_dfs_is_hw_pulses_allowed(struct wlan_objmgr_pdev *pdev)
345 {
346 struct wlan_dfs *dfs;
347
348 if (!tgt_dfs_is_5ghz_supported_in_pdev(pdev))
349 return false;
350
351 dfs = wlan_pdev_get_dfs_obj(pdev);
352 if (!dfs) {
353 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL");
354 return false;
355 }
356
357 return dfs_is_hw_pulses_allowed(dfs);
358 }
359
360 qdf_export_symbol(ucfg_dfs_is_hw_pulses_allowed);
361 #endif
362
363 #ifdef QCA_SUPPORT_AGILE_DFS
ucfg_dfs_reset_agile_config(struct wlan_objmgr_psoc * psoc)364 QDF_STATUS ucfg_dfs_reset_agile_config(struct wlan_objmgr_psoc *psoc)
365 {
366 struct dfs_soc_priv_obj *soc_obj;
367
368 if (!psoc) {
369 dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS, "psoc is null");
370 return QDF_STATUS_E_FAILURE;
371 }
372
373 soc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc,
374 WLAN_UMAC_COMP_DFS);
375 if (!soc_obj) {
376 dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS,
377 "Failed to get dfs psoc component");
378 return QDF_STATUS_E_FAILURE;
379 }
380
381 dfs_reset_agile_config(soc_obj);
382
383 return QDF_STATUS_SUCCESS;
384 }
385
386 qdf_export_symbol(ucfg_dfs_reset_agile_config);
387 #endif
388
ucfg_dfs_reinit_timers(struct wlan_objmgr_pdev * pdev)389 QDF_STATUS ucfg_dfs_reinit_timers(struct wlan_objmgr_pdev *pdev)
390 {
391 struct wlan_dfs *dfs;
392
393 if (!tgt_dfs_is_5ghz_supported_in_pdev(pdev))
394 return QDF_STATUS_SUCCESS;
395
396 dfs = wlan_pdev_get_dfs_obj(pdev);
397 if (!dfs) {
398 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL");
399 return QDF_STATUS_E_FAILURE;
400 }
401
402 dfs_reinit_timers(dfs);
403
404 return QDF_STATUS_SUCCESS;
405 }
406
407 qdf_export_symbol(ucfg_dfs_reinit_timers);
408
409 #ifdef QCA_SUPPORT_ADFS_RCAC
ucfg_dfs_set_rcac_enable(struct wlan_objmgr_pdev * pdev,bool rcac_en)410 QDF_STATUS ucfg_dfs_set_rcac_enable(struct wlan_objmgr_pdev *pdev,
411 bool rcac_en)
412 {
413 struct wlan_dfs *dfs;
414
415 dfs = wlan_pdev_get_dfs_obj(pdev);
416 if (!dfs) {
417 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "null dfs");
418 return QDF_STATUS_E_FAILURE;
419 }
420
421 dfs_set_rcac_enable(dfs, rcac_en);
422
423 return QDF_STATUS_SUCCESS;
424 }
425
426 qdf_export_symbol(ucfg_dfs_set_rcac_enable);
427
ucfg_dfs_get_rcac_enable(struct wlan_objmgr_pdev * pdev,bool * rcac_en)428 QDF_STATUS ucfg_dfs_get_rcac_enable(struct wlan_objmgr_pdev *pdev,
429 bool *rcac_en)
430 {
431 struct wlan_dfs *dfs;
432
433 if (!tgt_dfs_is_5ghz_supported_in_pdev(pdev)) {
434 *rcac_en = false;
435 return QDF_STATUS_SUCCESS;
436 }
437
438 dfs = wlan_pdev_get_dfs_obj(pdev);
439 if (!dfs) {
440 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "null dfs");
441 return QDF_STATUS_E_FAILURE;
442 }
443
444 dfs_get_rcac_enable(dfs, rcac_en);
445
446 return QDF_STATUS_SUCCESS;
447 }
448
449 qdf_export_symbol(ucfg_dfs_get_rcac_enable);
450
ucfg_dfs_set_rcac_freq(struct wlan_objmgr_pdev * pdev,qdf_freq_t rcac_freq)451 QDF_STATUS ucfg_dfs_set_rcac_freq(struct wlan_objmgr_pdev *pdev,
452 qdf_freq_t rcac_freq)
453 {
454 struct wlan_dfs *dfs;
455
456 dfs = wlan_pdev_get_dfs_obj(pdev);
457 if (!dfs) {
458 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "null dfs");
459 return QDF_STATUS_E_FAILURE;
460 }
461
462 dfs_set_rcac_freq(dfs, rcac_freq);
463
464 return QDF_STATUS_SUCCESS;
465 }
466
467 qdf_export_symbol(ucfg_dfs_set_rcac_freq);
468
ucfg_dfs_get_rcac_freq(struct wlan_objmgr_pdev * pdev,qdf_freq_t * rcac_freq)469 QDF_STATUS ucfg_dfs_get_rcac_freq(struct wlan_objmgr_pdev *pdev,
470 qdf_freq_t *rcac_freq)
471 {
472 struct wlan_dfs *dfs;
473
474 dfs = wlan_pdev_get_dfs_obj(pdev);
475 if (!dfs) {
476 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "null dfs");
477 return QDF_STATUS_E_FAILURE;
478 }
479
480 dfs_get_rcac_freq(dfs, rcac_freq);
481
482 return QDF_STATUS_SUCCESS;
483 }
484
485 qdf_export_symbol(ucfg_dfs_get_rcac_freq);
486
ucfg_dfs_is_agile_rcac_enabled(struct wlan_objmgr_pdev * pdev)487 bool ucfg_dfs_is_agile_rcac_enabled(struct wlan_objmgr_pdev *pdev)
488 {
489 struct wlan_dfs *dfs;
490
491 dfs = wlan_pdev_get_dfs_obj(pdev);
492 if (!dfs) {
493 dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "null dfs");
494 return false;
495 }
496
497 return dfs_is_agile_rcac_enabled(dfs);
498 }
499
500 qdf_export_symbol(ucfg_dfs_is_agile_rcac_enabled);
501 #endif
502
503