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 #include <wlan_objmgr_pdev_obj.h>
26 #include "wlan_dfs_tgt_api.h"
27 #include "wlan_dfs_utils_api.h"
28 #include "wlan_dfs_init_deinit_api.h"
29 #include "wlan_lmac_if_def.h"
30 #include "wlan_lmac_if_api.h"
31 #include "wlan_dfs_mlme_api.h"
32 #include "../../core/src/dfs.h"
33 #include "../../core/src/dfs_zero_cac.h"
34 #include "../../core/src/dfs_process_radar_found_ind.h"
35 #include <qdf_module.h>
36 #include "../../core/src/dfs_partial_offload_radar.h"
37 #ifdef MOBILE_DFS_SUPPORT
38 #include "wlan_mlme_ucfg_api.h"
39 #endif
40 
41 struct wlan_lmac_if_dfs_tx_ops *
wlan_psoc_get_dfs_txops(struct wlan_objmgr_psoc * psoc)42 wlan_psoc_get_dfs_txops(struct wlan_objmgr_psoc *psoc)
43 {
44 	struct wlan_lmac_if_tx_ops *tx_ops;
45 
46 	tx_ops = wlan_psoc_get_lmac_if_txops(psoc);
47 	if (!tx_ops) {
48 		dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS,  "tx_ops is null");
49 		return NULL;
50 	}
51 
52 	return &tx_ops->dfs_tx_ops;
53 }
54 
55 qdf_export_symbol(wlan_psoc_get_dfs_txops);
56 
tgt_dfs_is_5ghz_supported_in_pdev(struct wlan_objmgr_pdev * pdev)57 bool tgt_dfs_is_5ghz_supported_in_pdev(struct wlan_objmgr_pdev *pdev)
58 {
59 	struct wlan_lmac_if_dfs_tx_ops *dfs_tx_ops;
60 	struct wlan_objmgr_psoc *psoc;
61 	bool is_5ghz = false;
62 	QDF_STATUS status;
63 	bool is_6ghz_only_pdev;
64 	qdf_freq_t low_5g = 0;
65 	qdf_freq_t high_5g = 0;
66 
67 	wlan_reg_get_freq_range(pdev, NULL, NULL, &low_5g, &high_5g);
68 	is_6ghz_only_pdev = wlan_reg_is_range_only6g(low_5g, high_5g);
69 
70 	if (is_6ghz_only_pdev)
71 		return false;
72 
73 	psoc = wlan_pdev_get_psoc(pdev);
74 	if (!psoc) {
75 		dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS,  "null psoc");
76 		return false;
77 	}
78 
79 	dfs_tx_ops = wlan_psoc_get_dfs_txops(psoc);
80 	if (!(dfs_tx_ops && dfs_tx_ops->dfs_is_pdev_5ghz)) {
81 		dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS,  "dfs_tx_ops is null");
82 		return false;
83 	}
84 
85 	status = dfs_tx_ops->dfs_is_pdev_5ghz(pdev, &is_5ghz);
86 	if (QDF_IS_STATUS_ERROR(status)) {
87 		dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS,  "Failed to get is_5ghz value");
88 		return false;
89 	}
90 
91 	return is_5ghz;
92 }
93 
94 #ifdef CONFIG_CHAN_FREQ_API
95 QDF_STATUS
tgt_dfs_set_current_channel_for_freq(struct wlan_objmgr_pdev * pdev,uint16_t dfs_chan_freq,uint64_t dfs_chan_flags,uint16_t dfs_chan_flagext,uint8_t dfs_chan_ieee,uint8_t dfs_chan_vhtop_freq_seg1,uint8_t dfs_chan_vhtop_freq_seg2,uint16_t dfs_chan_mhz_freq_seg1,uint16_t dfs_chan_mhz_freq_seg2,uint16_t dfs_chan_punc_pattern,bool * is_channel_updated)96 tgt_dfs_set_current_channel_for_freq(struct wlan_objmgr_pdev *pdev,
97 				     uint16_t dfs_chan_freq,
98 				     uint64_t dfs_chan_flags,
99 				     uint16_t dfs_chan_flagext,
100 				     uint8_t dfs_chan_ieee,
101 				     uint8_t dfs_chan_vhtop_freq_seg1,
102 				     uint8_t dfs_chan_vhtop_freq_seg2,
103 				     uint16_t dfs_chan_mhz_freq_seg1,
104 				     uint16_t dfs_chan_mhz_freq_seg2,
105 				     uint16_t dfs_chan_punc_pattern,
106 				     bool *is_channel_updated)
107 {
108 	struct wlan_dfs *dfs;
109 
110 	if (!tgt_dfs_is_5ghz_supported_in_pdev(pdev))
111 		return QDF_STATUS_SUCCESS;
112 
113 	dfs = wlan_pdev_get_dfs_obj(pdev);
114 	if (!dfs) {
115 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL");
116 		return  QDF_STATUS_E_FAILURE;
117 	}
118 
119 	dfs_set_current_channel_for_freq(dfs,
120 					 dfs_chan_freq,
121 					 dfs_chan_flags,
122 					 dfs_chan_flagext,
123 					 dfs_chan_ieee,
124 					 dfs_chan_vhtop_freq_seg1,
125 					 dfs_chan_vhtop_freq_seg2,
126 					 dfs_chan_mhz_freq_seg1,
127 					 dfs_chan_mhz_freq_seg2,
128 					 dfs_chan_punc_pattern,
129 					 is_channel_updated);
130 
131 	return QDF_STATUS_SUCCESS;
132 }
133 
134 qdf_export_symbol(tgt_dfs_set_current_channel_for_freq);
135 #endif
136 
tgt_dfs_radar_enable(struct wlan_objmgr_pdev * pdev,int no_cac,uint32_t opmode,bool enable)137 QDF_STATUS tgt_dfs_radar_enable(struct wlan_objmgr_pdev *pdev,
138 				int no_cac, uint32_t opmode, bool enable)
139 {
140 	struct wlan_dfs *dfs;
141 	struct wlan_lmac_if_dfs_tx_ops *dfs_tx_ops;
142 	struct wlan_objmgr_psoc *psoc;
143 	QDF_STATUS status;
144 
145 	dfs = wlan_pdev_get_dfs_obj(pdev);
146 	if (!dfs) {
147 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL");
148 		return  QDF_STATUS_E_FAILURE;
149 	}
150 
151 	if (!dfs->dfs_is_offload_enabled) {
152 		if (enable) {
153 			dfs_radar_enable(dfs, no_cac, opmode);
154 			return QDF_STATUS_SUCCESS;
155 		} else {
156 			dfs_debug(dfs, WLAN_DEBUG_DFS_ALWAYS,
157 				  "Disabling dfs not allowed for non-offload chips");
158 			return QDF_STATUS_E_FAILURE;
159 		}
160 	}
161 
162 	psoc = wlan_pdev_get_psoc(pdev);
163 	if (!psoc) {
164 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "psoc is null");
165 		return  QDF_STATUS_E_FAILURE;
166 	}
167 
168 	dfs_tx_ops = wlan_psoc_get_dfs_txops(psoc);
169 	if (!dfs_tx_ops) {
170 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs_tx_ops is null");
171 		return  QDF_STATUS_E_FAILURE;
172 	}
173 
174 	status = dfs_tx_ops->dfs_send_offload_enable_cmd(pdev, enable);
175 	if (QDF_IS_STATUS_ERROR(status))
176 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,
177 			"Failed to enable dfs offload, pdev_id: %d",
178 			wlan_objmgr_pdev_get_pdev_id(pdev));
179 
180 	return status;
181 }
182 qdf_export_symbol(tgt_dfs_radar_enable);
183 
tgt_dfs_is_radar_enabled(struct wlan_objmgr_pdev * pdev,int * ignore_dfs)184 void tgt_dfs_is_radar_enabled(struct wlan_objmgr_pdev *pdev, int *ignore_dfs)
185 {
186 	struct wlan_dfs *dfs;
187 
188 	dfs = wlan_pdev_get_dfs_obj(pdev);
189 	if (!dfs) {
190 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL");
191 		return;
192 	}
193 
194 	dfs_is_radar_enabled(dfs, ignore_dfs);
195 }
196 
197 qdf_export_symbol(tgt_dfs_is_radar_enabled);
198 
199 #ifdef WLAN_DFS_PARTIAL_OFFLOAD
tgt_dfs_process_phyerr(struct wlan_objmgr_pdev * pdev,void * buf,uint16_t datalen,uint8_t r_rssi,uint8_t r_ext_rssi,uint32_t r_rs_tstamp,uint64_t r_fulltsf)200 QDF_STATUS tgt_dfs_process_phyerr(struct wlan_objmgr_pdev *pdev,
201 				  void *buf,
202 				  uint16_t datalen,
203 				  uint8_t r_rssi,
204 				  uint8_t r_ext_rssi,
205 				  uint32_t r_rs_tstamp,
206 				  uint64_t r_fulltsf)
207 {
208 	struct wlan_dfs *dfs;
209 
210 	dfs = wlan_pdev_get_dfs_obj(pdev);
211 	if (!dfs) {
212 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL");
213 		return  QDF_STATUS_E_FAILURE;
214 	}
215 
216 	if (!dfs->dfs_is_offload_enabled)
217 		dfs_process_phyerr(dfs, buf, datalen, r_rssi,
218 				   r_ext_rssi, r_rs_tstamp, r_fulltsf);
219 	else
220 		dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS,
221 			 "Unexpected phyerror as DFS is offloaded, pdev_id: %d",
222 			 wlan_objmgr_pdev_get_pdev_id(pdev));
223 
224 	return QDF_STATUS_SUCCESS;
225 }
226 qdf_export_symbol(tgt_dfs_process_phyerr);
227 #endif
228 
229 #ifdef MOBILE_DFS_SUPPORT
tgt_dfs_process_phyerr_filter_offload(struct wlan_objmgr_pdev * pdev,struct radar_event_info * wlan_radar_event)230 QDF_STATUS tgt_dfs_process_phyerr_filter_offload(struct wlan_objmgr_pdev *pdev,
231 						 struct radar_event_info
232 						 *wlan_radar_event)
233 {
234 	struct wlan_dfs *dfs;
235 
236 	dfs = wlan_pdev_get_dfs_obj(pdev);
237 	if (!dfs) {
238 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL");
239 		return  QDF_STATUS_E_FAILURE;
240 	}
241 	if (!dfs->dfs_is_offload_enabled)
242 		dfs_process_phyerr_filter_offload(dfs, wlan_radar_event);
243 	else
244 		dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS,
245 			 "Unexpected phyerror as DFS is offloaded, pdev_id: %d",
246 			 wlan_objmgr_pdev_get_pdev_id(pdev));
247 
248 	return QDF_STATUS_SUCCESS;
249 }
250 qdf_export_symbol(tgt_dfs_process_phyerr_filter_offload);
251 
tgt_dfs_is_phyerr_filter_offload(struct wlan_objmgr_psoc * psoc,bool * is_phyerr_filter_offload)252 QDF_STATUS tgt_dfs_is_phyerr_filter_offload(struct wlan_objmgr_psoc *psoc,
253 					    bool *is_phyerr_filter_offload)
254 {
255 	struct dfs_soc_priv_obj *soc_obj;
256 
257 	if (!psoc) {
258 		dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS,  "psoc is null");
259 		return QDF_STATUS_E_FAILURE;
260 	}
261 
262 	soc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc,
263 							WLAN_UMAC_COMP_DFS);
264 	if (!soc_obj) {
265 		dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS,
266 			"Failed to get dfs psoc component");
267 		return QDF_STATUS_E_FAILURE;
268 	}
269 
270 	*is_phyerr_filter_offload = soc_obj->dfs_is_phyerr_filter_offload;
271 
272 	return QDF_STATUS_SUCCESS;
273 }
274 qdf_export_symbol(tgt_dfs_is_phyerr_filter_offload);
275 #else
tgt_dfs_process_phyerr_filter_offload(struct wlan_objmgr_pdev * pdev,struct radar_event_info * wlan_radar_event)276 QDF_STATUS tgt_dfs_process_phyerr_filter_offload(struct wlan_objmgr_pdev *pdev,
277 						 struct radar_event_info
278 						 *wlan_radar_event)
279 {
280 	return QDF_STATUS_SUCCESS;
281 }
282 
tgt_dfs_is_phyerr_filter_offload(struct wlan_objmgr_psoc * psoc,bool * is_phyerr_filter_offload)283 QDF_STATUS tgt_dfs_is_phyerr_filter_offload(struct wlan_objmgr_psoc *psoc,
284 					    bool *is_phyerr_filter_offload)
285 {
286 	return QDF_STATUS_SUCCESS;
287 }
288 #endif
289 
tgt_dfs_is_precac_timer_running(struct wlan_objmgr_pdev * pdev,bool * is_precac_timer_running)290 QDF_STATUS tgt_dfs_is_precac_timer_running(struct wlan_objmgr_pdev *pdev,
291 					   bool *is_precac_timer_running)
292 {
293 	struct wlan_dfs *dfs;
294 
295 	if (!tgt_dfs_is_5ghz_supported_in_pdev(pdev))
296 		return QDF_STATUS_SUCCESS;
297 
298 	dfs = wlan_pdev_get_dfs_obj(pdev);
299 	if (!dfs) {
300 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL");
301 		return  QDF_STATUS_E_FAILURE;
302 	}
303 
304 	*is_precac_timer_running = dfs_is_precac_timer_running(dfs);
305 
306 	return QDF_STATUS_SUCCESS;
307 }
308 qdf_export_symbol(tgt_dfs_is_precac_timer_running);
309 
tgt_dfs_get_radars(struct wlan_objmgr_pdev * pdev)310 QDF_STATUS tgt_dfs_get_radars(struct wlan_objmgr_pdev *pdev)
311 {
312 	struct wlan_dfs *dfs;
313 
314 	if (!tgt_dfs_is_5ghz_supported_in_pdev(pdev))
315 		return QDF_STATUS_SUCCESS;
316 
317 	dfs = wlan_pdev_get_dfs_obj(pdev);
318 	if (!dfs) {
319 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL");
320 		return  QDF_STATUS_E_FAILURE;
321 	}
322 
323 	if (!dfs->dfs_is_offload_enabled)
324 		dfs_get_radars(dfs);
325 
326 	return QDF_STATUS_SUCCESS;
327 }
328 qdf_export_symbol(tgt_dfs_get_radars);
329 
tgt_dfs_destroy_object(struct wlan_objmgr_pdev * pdev)330 QDF_STATUS tgt_dfs_destroy_object(struct wlan_objmgr_pdev *pdev)
331 {
332 	struct wlan_dfs *dfs;
333 
334 	dfs = wlan_pdev_get_dfs_obj(pdev);
335 	if (!dfs) {
336 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL");
337 		return  QDF_STATUS_E_FAILURE;
338 	}
339 
340 	dfs_destroy_object(dfs);
341 
342 	return QDF_STATUS_SUCCESS;
343 }
344 qdf_export_symbol(tgt_dfs_destroy_object);
345 
346 #ifdef MOBILE_DFS_SUPPORT
tgt_dfs_set_tx_leakage_threshold(struct wlan_objmgr_pdev * pdev)347 QDF_STATUS tgt_dfs_set_tx_leakage_threshold(struct wlan_objmgr_pdev *pdev)
348 {
349 	struct wlan_dfs *dfs;
350 	uint32_t tx_leakage_threshold = 0;
351 	struct wlan_objmgr_psoc *psoc;
352 
353 	psoc = wlan_pdev_get_psoc(pdev);
354 	if (!psoc) {
355 		dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS, "psoc is null");
356 		return QDF_STATUS_E_FAILURE;
357 	}
358 
359 	dfs = wlan_pdev_get_dfs_obj(pdev);
360 	if (!dfs) {
361 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "dfs is NULL");
362 		return  QDF_STATUS_E_FAILURE;
363 	}
364 	ucfg_mlme_get_sap_tx_leakage_threshold(psoc,
365 					       &tx_leakage_threshold);
366 
367 	dfs->tx_leakage_threshold = tx_leakage_threshold;
368 	dfs_debug(dfs, WLAN_DEBUG_DFS_ALWAYS,
369 		  "dfs tx_leakage_threshold = %d", dfs->tx_leakage_threshold);
370 
371 	return QDF_STATUS_SUCCESS;
372 }
373 qdf_export_symbol(tgt_dfs_set_tx_leakage_threshold);
374 #endif
375 
tgt_dfs_control(struct wlan_objmgr_pdev * pdev,u_int id,void * indata,uint32_t insize,void * outdata,uint32_t * outsize,int * error)376 QDF_STATUS tgt_dfs_control(struct wlan_objmgr_pdev *pdev,
377 			   u_int id,
378 			   void *indata,
379 			   uint32_t insize,
380 			   void *outdata,
381 			   uint32_t *outsize,
382 			   int *error)
383 {
384 	struct wlan_dfs *dfs;
385 
386 	dfs = wlan_pdev_get_dfs_obj(pdev);
387 	if (!dfs) {
388 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL");
389 		return  QDF_STATUS_E_FAILURE;
390 	}
391 
392 	*error = dfs_control(dfs, id, indata, insize, outdata, outsize);
393 
394 	return  QDF_STATUS_SUCCESS;
395 }
396 qdf_export_symbol(tgt_dfs_control);
397 
398 #ifdef QCA_SUPPORT_AGILE_DFS
tgt_dfs_agile_precac_start(struct wlan_objmgr_pdev * pdev)399 QDF_STATUS tgt_dfs_agile_precac_start(struct wlan_objmgr_pdev *pdev)
400 {
401 	struct wlan_dfs *dfs;
402 
403 	dfs = wlan_pdev_get_dfs_obj(pdev);
404 	if (!dfs) {
405 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL");
406 		return  QDF_STATUS_E_FAILURE;
407 	}
408 
409 	dfs_agile_precac_start(dfs);
410 
411 	return  QDF_STATUS_SUCCESS;
412 }
413 #else
tgt_dfs_agile_precac_start(struct wlan_objmgr_pdev * pdev)414 QDF_STATUS tgt_dfs_agile_precac_start(struct wlan_objmgr_pdev *pdev)
415 {
416 	return  QDF_STATUS_SUCCESS;
417 }
418 #endif
419 qdf_export_symbol(tgt_dfs_agile_precac_start);
420 
421 #ifdef QCA_SUPPORT_AGILE_DFS
422 #ifdef CONFIG_CHAN_FREQ_API
tgt_dfs_set_agile_precac_state(struct wlan_objmgr_pdev * pdev,int agile_precac_state)423 QDF_STATUS tgt_dfs_set_agile_precac_state(struct wlan_objmgr_pdev *pdev,
424 					  int agile_precac_state)
425 {
426 	struct wlan_dfs *dfs;
427 	struct dfs_soc_priv_obj *dfs_soc;
428 	bool is_precac_running_on_given_pdev = false;
429 	int i;
430 
431 	if (!tgt_dfs_is_5ghz_supported_in_pdev(pdev))
432 		return QDF_STATUS_SUCCESS;
433 
434 	dfs = wlan_pdev_get_dfs_obj(pdev);
435 	if (!dfs) {
436 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL");
437 		return  QDF_STATUS_E_FAILURE;
438 	}
439 
440 	dfs_soc = dfs->dfs_soc_obj;
441 	for (i = 0; i < dfs_soc->num_dfs_privs; i++) {
442 		if (dfs_soc->dfs_priv[i].dfs == dfs) {
443 			/* Set the pdev state to given value. */
444 			dfs_soc->dfs_priv[i].agile_precac_active =
445 				agile_precac_state;
446 			/* If the pdev state is changed to inactive,
447 			 * reset the agile channel.
448 			 */
449 			if (!agile_precac_state)
450 				dfs->dfs_agile_precac_freq_mhz = 0;
451 			if (dfs_soc->cur_agile_dfs_index == i)
452 				is_precac_running_on_given_pdev = true;
453 		}
454 	}
455 
456 	/* If preCAC is running on this pdev and the agile_precac_state
457 	 * is set to false, set the global state in dfs_soc_obj to false.
458 	 * If this global state is not set to false, then preCAC will not be
459 	 * started the next time this pdev becomes active.
460 	 */
461 	if (is_precac_running_on_given_pdev && !agile_precac_state)
462 		dfs_soc->precac_state_started = PRECAC_NOT_STARTED;
463 
464 	return  QDF_STATUS_SUCCESS;
465 }
466 #else
467 #endif
468 
469 #else
tgt_dfs_set_agile_precac_state(struct wlan_objmgr_pdev * pdev,int agile_precac_state)470 QDF_STATUS tgt_dfs_set_agile_precac_state(struct wlan_objmgr_pdev *pdev,
471 					  int agile_precac_state)
472 {
473 	return  QDF_STATUS_SUCCESS;
474 }
475 #endif
476 qdf_export_symbol(tgt_dfs_set_agile_precac_state);
477 
478 #ifdef QCA_SUPPORT_AGILE_DFS
tgt_dfs_ocac_complete(struct wlan_objmgr_pdev * pdev,struct vdev_adfs_complete_status * adfs_status)479 QDF_STATUS tgt_dfs_ocac_complete(struct wlan_objmgr_pdev *pdev,
480 				 struct vdev_adfs_complete_status *adfs_status)
481 {
482 	struct wlan_dfs *dfs;
483 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
484 
485 	if (!pdev) {
486 		dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS, "null pdev");
487 		return status;
488 	}
489 
490 	dfs = wlan_pdev_get_dfs_obj(pdev);
491 	if (!dfs) {
492 		dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS, "dfs is null");
493 		return status;
494 	}
495 
496 	dfs_process_ocac_complete(pdev, adfs_status->ocac_status,
497 				  adfs_status->center_freq1,
498 				  adfs_status->center_freq2,
499 				  adfs_status->chan_width);
500 
501 	return  QDF_STATUS_SUCCESS;
502 }
503 #else
tgt_dfs_ocac_complete(struct wlan_objmgr_pdev * pdev,struct vdev_adfs_complete_status * adfs_status)504 QDF_STATUS tgt_dfs_ocac_complete(struct wlan_objmgr_pdev *pdev,
505 				 struct vdev_adfs_complete_status *adfs_status)
506 {
507 	return  QDF_STATUS_SUCCESS;
508 }
509 #endif
510 qdf_export_symbol(tgt_dfs_ocac_complete);
511 
tgt_dfs_process_radar_ind(struct wlan_objmgr_pdev * pdev,struct radar_found_info * radar_found)512 QDF_STATUS tgt_dfs_process_radar_ind(struct wlan_objmgr_pdev *pdev,
513 				     struct radar_found_info *radar_found)
514 {
515 	struct wlan_dfs *dfs;
516 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
517 
518 	if (!pdev) {
519 		dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS, "null pdev");
520 		return status;
521 	}
522 
523 	dfs = wlan_pdev_get_dfs_obj(pdev);
524 	if (!dfs) {
525 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is null");
526 		return status;
527 	}
528 
529 	dfs_translate_radar_params(dfs, radar_found);
530 	status = dfs_process_radar_ind(dfs, radar_found);
531 	dfs_inc_num_radar(dfs);
532 
533 	return status;
534 }
535 qdf_export_symbol(tgt_dfs_process_radar_ind);
536 
537 #ifndef MOBILE_DFS_SUPPORT
tgt_dfs_cac_complete(struct wlan_objmgr_pdev * pdev,uint32_t vdev_id)538 QDF_STATUS tgt_dfs_cac_complete(struct wlan_objmgr_pdev *pdev, uint32_t vdev_id)
539 {
540 	return QDF_STATUS_SUCCESS;
541 }
542 #else
tgt_dfs_cac_complete(struct wlan_objmgr_pdev * pdev,uint32_t vdev_id)543 QDF_STATUS tgt_dfs_cac_complete(struct wlan_objmgr_pdev *pdev, uint32_t vdev_id)
544 {
545 	dfs_mlme_proc_cac(pdev, vdev_id);
546 
547 	return QDF_STATUS_SUCCESS;
548 }
549 #endif
550 qdf_export_symbol(tgt_dfs_cac_complete);
551 
tgt_dfs_reg_ev_handler(struct wlan_objmgr_psoc * psoc)552 QDF_STATUS tgt_dfs_reg_ev_handler(struct wlan_objmgr_psoc *psoc)
553 {
554 	struct wlan_lmac_if_dfs_tx_ops *dfs_tx_ops;
555 
556 	if (!psoc) {
557 		dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS, "null psoc");
558 		return QDF_STATUS_E_FAILURE;
559 	}
560 
561 	dfs_tx_ops = wlan_psoc_get_dfs_txops(psoc);
562 	if (!dfs_tx_ops) {
563 		dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS, "null dfs_tx_ops");
564 		return QDF_STATUS_E_FAILURE;
565 	}
566 
567 	if (dfs_tx_ops->dfs_reg_ev_handler)
568 		return dfs_tx_ops->dfs_reg_ev_handler(psoc);
569 
570 	return QDF_STATUS_E_FAILURE;
571 }
572 qdf_export_symbol(tgt_dfs_reg_ev_handler);
573 
tgt_dfs_stop(struct wlan_objmgr_pdev * pdev)574 QDF_STATUS tgt_dfs_stop(struct wlan_objmgr_pdev *pdev)
575 {
576 	struct wlan_dfs *dfs;
577 
578 	if (!tgt_dfs_is_5ghz_supported_in_pdev(pdev))
579 		return QDF_STATUS_SUCCESS;
580 
581 	dfs = wlan_pdev_get_dfs_obj(pdev);
582 	if (!dfs) {
583 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL");
584 		return  QDF_STATUS_E_FAILURE;
585 	}
586 
587 	dfs_stop(dfs);
588 
589 	return QDF_STATUS_SUCCESS;
590 }
591 qdf_export_symbol(tgt_dfs_stop);
592 
tgt_dfs_process_emulate_bang_radar_cmd(struct wlan_objmgr_pdev * pdev,struct dfs_emulate_bang_radar_test_cmd * dfs_unit_test)593 QDF_STATUS tgt_dfs_process_emulate_bang_radar_cmd(struct wlan_objmgr_pdev *pdev,
594 		struct dfs_emulate_bang_radar_test_cmd *dfs_unit_test)
595 {
596 	struct wlan_objmgr_psoc *psoc;
597 	struct wlan_lmac_if_dfs_tx_ops *dfs_tx_ops;
598 
599 	psoc = wlan_pdev_get_psoc(pdev);
600 	if (!psoc) {
601 		dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS, "psoc is null");
602 		return QDF_STATUS_E_FAILURE;
603 	}
604 
605 	dfs_tx_ops = wlan_psoc_get_dfs_txops(psoc);
606 	if (dfs_tx_ops && dfs_tx_ops->dfs_process_emulate_bang_radar_cmd)
607 		return dfs_tx_ops->dfs_process_emulate_bang_radar_cmd(pdev,
608 				dfs_unit_test);
609 	else
610 		dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS,
611 			"dfs_tx_ops=%pK", dfs_tx_ops);
612 
613 	return QDF_STATUS_E_FAILURE;
614 }
615 qdf_export_symbol(tgt_dfs_process_emulate_bang_radar_cmd);
616 
617 #ifdef MOBILE_DFS_SUPPORT
tgt_dfs_set_phyerr_filter_offload(struct wlan_objmgr_pdev * pdev)618 QDF_STATUS tgt_dfs_set_phyerr_filter_offload(struct wlan_objmgr_pdev *pdev)
619 {
620 	struct wlan_objmgr_psoc *psoc;
621 	struct wlan_lmac_if_dfs_tx_ops *dfs_tx_ops;
622 	struct dfs_soc_priv_obj *soc_obj;
623 
624 	psoc = wlan_pdev_get_psoc(pdev);
625 	if (!psoc) {
626 		dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS, "psoc is null");
627 		return QDF_STATUS_E_FAILURE;
628 	}
629 
630 	soc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc,
631 							WLAN_UMAC_COMP_DFS);
632 	if (!soc_obj) {
633 		dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS,
634 			"Failed to get dfs psoc component");
635 		return QDF_STATUS_E_FAILURE;
636 	}
637 	dfs_tx_ops = wlan_psoc_get_dfs_txops(psoc);
638 	if (dfs_tx_ops && dfs_tx_ops->dfs_set_phyerr_filter_offload)
639 		return dfs_tx_ops->dfs_set_phyerr_filter_offload(pdev,
640 				soc_obj->dfs_is_phyerr_filter_offload);
641 	else
642 		dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS,
643 			"dfs_tx_ops=%pK", dfs_tx_ops);
644 
645 	return QDF_STATUS_E_FAILURE;
646 }
647 qdf_export_symbol(tgt_dfs_set_phyerr_filter_offload);
648 #endif
649 
650 #if defined(WLAN_DFS_PARTIAL_OFFLOAD) && defined(HOST_DFS_SPOOF_TEST)
651 QDF_STATUS
tgt_dfs_send_avg_params_to_fw(struct wlan_objmgr_pdev * pdev,struct dfs_radar_found_params * params)652 tgt_dfs_send_avg_params_to_fw(struct wlan_objmgr_pdev *pdev,
653 			      struct dfs_radar_found_params *params)
654 {
655 	struct wlan_objmgr_psoc *psoc;
656 	struct wlan_lmac_if_dfs_tx_ops *dfs_tx_ops;
657 	struct wlan_dfs *dfs;
658 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
659 
660 	dfs = wlan_pdev_get_dfs_obj(pdev);
661 	if (!dfs) {
662 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL");
663 		return  status;
664 	}
665 
666 	psoc = wlan_pdev_get_psoc(pdev);
667 	if (!psoc) {
668 		dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS, "psoc is null");
669 		return status;
670 	}
671 
672 	dfs_debug(dfs, WLAN_DEBUG_DFS_ALWAYS,
673 		  "params->pri_min = %d; params->pri_max = %d; params->duration_min = %d; params->duration_max = %d; params->sidx_min = %d; params->sidx_max = %d",
674 		  params->pri_min, params->pri_max,
675 		  params->duration_min, params->duration_max,
676 		  params->sidx_min, params->sidx_max);
677 	dfs_tx_ops = wlan_psoc_get_dfs_txops(psoc);
678 	if (dfs_tx_ops && dfs_tx_ops->dfs_send_avg_radar_params_to_fw)
679 		status = dfs_tx_ops->dfs_send_avg_radar_params_to_fw(pdev,
680 			params);
681 
682 	if (QDF_IS_STATUS_SUCCESS(status)) {
683 		dfs->dfs_average_params_sent = 1;
684 		dfs_debug(dfs, WLAN_DEBUG_DFS_ALWAYS, "Average radar parameters sent %d",
685 			  dfs->dfs_average_params_sent);
686 	}
687 
688 	return status;
689 }
690 
691 qdf_export_symbol(tgt_dfs_send_avg_params_to_fw);
692 
tgt_dfs_action_on_status_from_fw(struct wlan_objmgr_pdev * pdev,uint32_t * status)693 QDF_STATUS tgt_dfs_action_on_status_from_fw(struct wlan_objmgr_pdev *pdev,
694 					    uint32_t *status)
695 {
696 	struct wlan_dfs *dfs;
697 
698 	dfs = wlan_pdev_get_dfs_obj(pdev);
699 	if (!dfs) {
700 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL");
701 		return  QDF_STATUS_E_FAILURE;
702 	}
703 
704 	dfs_action_on_fw_radar_status_check(dfs, status);
705 
706 	return QDF_STATUS_SUCCESS;
707 }
708 
709 qdf_export_symbol(tgt_dfs_action_on_status_from_fw);
710 
tgt_dfs_reset_spoof_test(struct wlan_objmgr_pdev * pdev)711 QDF_STATUS tgt_dfs_reset_spoof_test(struct wlan_objmgr_pdev *pdev)
712 {
713 	struct wlan_dfs *dfs;
714 
715 	if (!tgt_dfs_is_5ghz_supported_in_pdev(pdev))
716 		return QDF_STATUS_SUCCESS;
717 
718 	dfs = wlan_pdev_get_dfs_obj(pdev);
719 	if (!dfs) {
720 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL");
721 		return  QDF_STATUS_E_FAILURE;
722 	}
723 
724 	dfs_reset_spoof_test(dfs);
725 
726 	return QDF_STATUS_SUCCESS;
727 }
728 
729 qdf_export_symbol(tgt_dfs_reset_spoof_test);
730 #endif
731 
732 #if defined(WLAN_DFS_FULL_OFFLOAD) && defined(QCA_DFS_NOL_OFFLOAD)
tgt_dfs_send_usenol_pdev_param(struct wlan_objmgr_pdev * pdev,bool usenol)733 QDF_STATUS tgt_dfs_send_usenol_pdev_param(struct wlan_objmgr_pdev *pdev,
734 					  bool usenol)
735 {
736 	struct wlan_objmgr_psoc *psoc;
737 	struct wlan_lmac_if_dfs_tx_ops *dfs_tx_ops;
738 
739 	psoc = wlan_pdev_get_psoc(pdev);
740 	if (!psoc) {
741 		dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS, "psoc is null");
742 		return QDF_STATUS_E_FAILURE;
743 	}
744 
745 	dfs_tx_ops = wlan_psoc_get_dfs_txops(psoc);
746 	if (dfs_tx_ops && dfs_tx_ops->dfs_send_usenol_pdev_param)
747 		return dfs_tx_ops->dfs_send_usenol_pdev_param(pdev, usenol);
748 
749 	dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS,
750 		"dfs_tx_ops=%pK", dfs_tx_ops);
751 
752 	return QDF_STATUS_E_FAILURE;
753 }
754 
755 qdf_export_symbol(tgt_dfs_send_usenol_pdev_param);
756 
tgt_dfs_send_subchan_marking(struct wlan_objmgr_pdev * pdev,bool subchanmark)757 QDF_STATUS tgt_dfs_send_subchan_marking(struct wlan_objmgr_pdev *pdev,
758 					bool subchanmark)
759 {
760 	struct wlan_objmgr_psoc *psoc;
761 	struct wlan_lmac_if_dfs_tx_ops *dfs_tx_ops;
762 
763 	psoc = wlan_pdev_get_psoc(pdev);
764 	if (!psoc) {
765 		dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS, "psoc is null");
766 		return QDF_STATUS_E_FAILURE;
767 	}
768 
769 	dfs_tx_ops = wlan_psoc_get_dfs_txops(psoc);
770 	if (!dfs_tx_ops) {
771 		dfs_debug(NULL, WLAN_DEBUG_DFS_ALWAYS,
772 			  "dfs_tx_ops=%pK", dfs_tx_ops);
773 		return QDF_STATUS_E_FAILURE;
774 	}
775 
776 	if (dfs_tx_ops->dfs_send_subchan_marking_pdev_param)
777 		return dfs_tx_ops->dfs_send_subchan_marking_pdev_param(
778 				pdev, subchanmark);
779 
780 	dfs_debug(NULL, WLAN_DEBUG_DFS_ALWAYS,
781 		  "dfs_send_subchan_marking_pdev_param is null");
782 
783 	return QDF_STATUS_E_FAILURE;
784 }
785 
786 qdf_export_symbol(tgt_dfs_send_subchan_marking);
787 #endif
788 
789 #ifdef QCA_SUPPORT_AGILE_DFS
tgt_dfs_set_fw_adfs_support(struct wlan_objmgr_pdev * pdev,bool fw_adfs_support_160,bool fw_adfs_support_non_160,bool fw_adfs_support_320)790 void tgt_dfs_set_fw_adfs_support(struct wlan_objmgr_pdev *pdev,
791 				 bool fw_adfs_support_160,
792 				 bool fw_adfs_support_non_160,
793 				 bool fw_adfs_support_320)
794 {
795 	struct wlan_dfs *dfs;
796 
797 	dfs = wlan_pdev_get_dfs_obj(pdev);
798 	if (!dfs) {
799 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL");
800 		return;
801 	}
802 
803 	dfs_set_fw_adfs_support(dfs,
804 				fw_adfs_support_160,
805 				fw_adfs_support_non_160,
806 				fw_adfs_support_320);
807 }
808 
809 qdf_export_symbol(tgt_dfs_set_fw_adfs_support);
810 #endif
811