xref: /wlan-dirver/qca-wifi-host-cmn/umac/dfs/dispatcher/src/wlan_dfs_tgt_api.c (revision 80bfeb949d91a4433bae9ec339c5b879889246ab)
1 /*
2  * Copyright (c) 2016-2018 The Linux Foundation. All rights reserved.
3  *
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 has the DFS dispatcher API implementation which is exposed
22  * to outside of DFS component.
23  */
24 #include <wlan_objmgr_pdev_obj.h>
25 #include "wlan_dfs_tgt_api.h"
26 #include "wlan_lmac_if_def.h"
27 #include "wlan_lmac_if_api.h"
28 #include "wlan_dfs_mlme_api.h"
29 #include "../../core/src/dfs.h"
30 #include "../../core/src/dfs_zero_cac.h"
31 #include "../../core/src/dfs_process_radar_found_ind.h"
32 #include <qdf_module.h>
33 
34 struct wlan_lmac_if_dfs_tx_ops *
35 wlan_psoc_get_dfs_txops(struct wlan_objmgr_psoc *psoc)
36 {
37 	return &((psoc->soc_cb.tx_ops.dfs_tx_ops));
38 }
39 
40 QDF_STATUS tgt_dfs_set_current_channel(struct wlan_objmgr_pdev *pdev,
41 				       uint16_t dfs_ch_freq,
42 				       uint64_t dfs_ch_flags,
43 				       uint16_t dfs_ch_flagext,
44 				       uint8_t dfs_ch_ieee,
45 				       uint8_t dfs_ch_vhtop_ch_freq_seg1,
46 				       uint8_t dfs_ch_vhtop_ch_freq_seg2)
47 {
48 	struct wlan_dfs *dfs;
49 
50 	dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev);
51 	if (!dfs) {
52 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL");
53 		return  QDF_STATUS_E_FAILURE;
54 	}
55 
56 	dfs_set_current_channel(dfs,
57 				dfs_ch_freq,
58 				dfs_ch_flags,
59 				dfs_ch_flagext,
60 				dfs_ch_ieee,
61 				dfs_ch_vhtop_ch_freq_seg1,
62 				dfs_ch_vhtop_ch_freq_seg2);
63 
64 	return QDF_STATUS_SUCCESS;
65 }
66 qdf_export_symbol(tgt_dfs_set_current_channel);
67 
68 QDF_STATUS tgt_dfs_radar_enable(struct wlan_objmgr_pdev *pdev,
69 				int no_cac, uint32_t opmode)
70 {
71 	struct wlan_dfs *dfs;
72 	struct wlan_lmac_if_dfs_tx_ops *dfs_tx_ops;
73 	struct wlan_objmgr_psoc *psoc;
74 	QDF_STATUS status;
75 
76 	dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev);
77 	if (!dfs) {
78 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL");
79 		return  QDF_STATUS_E_FAILURE;
80 	}
81 
82 	if (!dfs->dfs_is_offload_enabled) {
83 		dfs_radar_enable(dfs, no_cac, opmode);
84 		return QDF_STATUS_SUCCESS;
85 	}
86 
87 	psoc = wlan_pdev_get_psoc(pdev);
88 	if (!psoc) {
89 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "psoc is null");
90 		return  QDF_STATUS_E_FAILURE;
91 	}
92 
93 	dfs_tx_ops = wlan_psoc_get_dfs_txops(psoc);
94 	if (!dfs_tx_ops) {
95 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs_tx_ops is null");
96 		return  QDF_STATUS_E_FAILURE;
97 	}
98 
99 	status = dfs_tx_ops->dfs_send_offload_enable_cmd(pdev, true);
100 	if (QDF_IS_STATUS_ERROR(status))
101 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,
102 			"Failed to enable dfs offload, pdev_id: %d",
103 			wlan_objmgr_pdev_get_pdev_id(pdev));
104 
105 	return status;
106 }
107 qdf_export_symbol(tgt_dfs_radar_enable);
108 
109 QDF_STATUS tgt_dfs_process_phyerr(struct wlan_objmgr_pdev *pdev,
110 				  void *buf,
111 				  uint16_t datalen,
112 				  uint8_t r_rssi,
113 				  uint8_t r_ext_rssi,
114 				  uint32_t r_rs_tstamp,
115 				  uint64_t r_fulltsf)
116 {
117 	struct wlan_dfs *dfs;
118 
119 	dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev);
120 	if (!dfs) {
121 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL");
122 		return  QDF_STATUS_E_FAILURE;
123 	}
124 
125 	if (!dfs->dfs_is_offload_enabled)
126 		dfs_process_phyerr(dfs, buf, datalen, r_rssi,
127 				   r_ext_rssi, r_rs_tstamp, r_fulltsf);
128 	else
129 		dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS,
130 			 "Unexpect phyerror as DFS is offloaded, pdev_id: %d",
131 			 wlan_objmgr_pdev_get_pdev_id(pdev));
132 
133 	return QDF_STATUS_SUCCESS;
134 }
135 qdf_export_symbol(tgt_dfs_process_phyerr);
136 
137 #ifdef QCA_MCL_DFS_SUPPORT
138 QDF_STATUS tgt_dfs_process_phyerr_filter_offload(struct wlan_objmgr_pdev *pdev,
139 						 struct radar_event_info
140 						 *wlan_radar_event)
141 {
142 	struct wlan_dfs *dfs;
143 
144 	dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev);
145 	if (!dfs) {
146 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL");
147 		return  QDF_STATUS_E_FAILURE;
148 	}
149 	if (!dfs->dfs_is_offload_enabled)
150 		dfs_process_phyerr_filter_offload(dfs, wlan_radar_event);
151 	else
152 		dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS,
153 			 "Unexpect phyerror as DFS is offloaded, pdev_id: %d",
154 			 wlan_objmgr_pdev_get_pdev_id(pdev));
155 
156 	return QDF_STATUS_SUCCESS;
157 }
158 qdf_export_symbol(tgt_dfs_process_phyerr_filter_offload);
159 
160 QDF_STATUS tgt_dfs_is_phyerr_filter_offload(struct wlan_objmgr_psoc *psoc,
161 					    bool *is_phyerr_filter_offload)
162 {
163 	struct dfs_soc_priv_obj *soc_obj;
164 
165 	if (!psoc) {
166 		dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS,  "psoc is null");
167 		return QDF_STATUS_E_FAILURE;
168 	}
169 
170 	soc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc,
171 							WLAN_UMAC_COMP_DFS);
172 	if (!soc_obj) {
173 		dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS,
174 			"Failed to get dfs psoc component");
175 		return QDF_STATUS_E_FAILURE;
176 	}
177 
178 	*is_phyerr_filter_offload = soc_obj->dfs_is_phyerr_filter_offload;
179 
180 	return QDF_STATUS_SUCCESS;
181 }
182 qdf_export_symbol(tgt_dfs_is_phyerr_filter_offload);
183 #else
184 QDF_STATUS tgt_dfs_process_phyerr_filter_offload(struct wlan_objmgr_pdev *pdev,
185 						 struct radar_event_info
186 						 *wlan_radar_event)
187 {
188 	return QDF_STATUS_SUCCESS;
189 }
190 
191 QDF_STATUS tgt_dfs_is_phyerr_filter_offload(struct wlan_objmgr_psoc *psoc,
192 					    bool *is_phyerr_filter_offload)
193 {
194 	return QDF_STATUS_SUCCESS;
195 }
196 #endif
197 
198 QDF_STATUS tgt_dfs_is_precac_timer_running(struct wlan_objmgr_pdev *pdev,
199 					   bool *is_precac_timer_running)
200 {
201 	struct wlan_dfs *dfs;
202 
203 	dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev);
204 	if (!dfs) {
205 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL");
206 		return  QDF_STATUS_E_FAILURE;
207 	}
208 
209 	*is_precac_timer_running = dfs_is_precac_timer_running(dfs);
210 
211 	return QDF_STATUS_SUCCESS;
212 }
213 qdf_export_symbol(tgt_dfs_is_precac_timer_running);
214 
215 QDF_STATUS tgt_dfs_get_radars(struct wlan_objmgr_pdev *pdev)
216 {
217 	struct wlan_dfs *dfs;
218 
219 	dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev);
220 	if (!dfs) {
221 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL");
222 		return  QDF_STATUS_E_FAILURE;
223 	}
224 
225 	if (!dfs->dfs_is_offload_enabled)
226 		dfs_get_radars(dfs);
227 
228 	return QDF_STATUS_SUCCESS;
229 }
230 qdf_export_symbol(tgt_dfs_get_radars);
231 
232 QDF_STATUS tgt_dfs_destroy_object(struct wlan_objmgr_pdev *pdev)
233 {
234 	struct wlan_dfs *dfs;
235 
236 	dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev);
237 	if (!dfs) {
238 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL");
239 		return  QDF_STATUS_E_FAILURE;
240 	}
241 
242 	dfs_destroy_object(dfs);
243 
244 	return QDF_STATUS_SUCCESS;
245 }
246 qdf_export_symbol(tgt_dfs_destroy_object);
247 
248 #ifdef QCA_MCL_DFS_SUPPORT
249 QDF_STATUS tgt_dfs_set_tx_leakage_threshold(struct wlan_objmgr_pdev *pdev,
250 		uint16_t tx_leakage_threshold)
251 {
252 	struct wlan_dfs *dfs;
253 
254 	dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev);
255 	if (!dfs) {
256 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "dfs is NULL");
257 		return  QDF_STATUS_E_FAILURE;
258 	}
259 
260 	dfs->tx_leakage_threshold = tx_leakage_threshold;
261 
262 	return QDF_STATUS_SUCCESS;
263 }
264 qdf_export_symbol(tgt_dfs_set_tx_leakage_threshold);
265 #endif
266 
267 QDF_STATUS tgt_dfs_control(struct wlan_objmgr_pdev *pdev,
268 			   u_int id,
269 			   void *indata,
270 			   uint32_t insize,
271 			   void *outdata,
272 			   uint32_t *outsize,
273 			   int *error)
274 {
275 	struct wlan_dfs *dfs;
276 
277 	dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev);
278 	if (!dfs) {
279 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL");
280 		return  QDF_STATUS_E_FAILURE;
281 	}
282 
283 	*error = dfs_control(dfs, id, indata, insize, outdata, outsize);
284 
285 	return  QDF_STATUS_SUCCESS;
286 }
287 qdf_export_symbol(tgt_dfs_control);
288 
289 QDF_STATUS tgt_dfs_find_vht80_chan_for_precac(struct wlan_objmgr_pdev *pdev,
290 					      uint32_t chan_mode,
291 					      uint8_t ch_freq_seg1,
292 					      uint32_t *cfreq1,
293 					      uint32_t *cfreq2,
294 					      uint32_t *phy_mode,
295 					      bool *dfs_set_cfreq2,
296 					      bool *set_agile)
297 {
298 	struct wlan_dfs *dfs;
299 
300 	dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev);
301 	if (!dfs) {
302 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL");
303 		return  QDF_STATUS_E_FAILURE;
304 	}
305 
306 	dfs_find_vht80_chan_for_precac(dfs,
307 				       chan_mode,
308 				       ch_freq_seg1,
309 				       cfreq1,
310 				       cfreq2,
311 				       phy_mode,
312 				       dfs_set_cfreq2,
313 				       set_agile);
314 
315 	return  QDF_STATUS_SUCCESS;
316 }
317 qdf_export_symbol(tgt_dfs_find_vht80_chan_for_precac);
318 
319 QDF_STATUS tgt_dfs_process_radar_ind(struct wlan_objmgr_pdev *pdev,
320 				     struct radar_found_info *radar_found)
321 {
322 	struct wlan_dfs *dfs;
323 
324 	if (!pdev) {
325 		dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS, "null pdev");
326 		return QDF_STATUS_E_FAILURE;
327 	}
328 
329 	dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev);
330 	if (!dfs) {
331 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is null");
332 		return QDF_STATUS_E_FAILURE;
333 	}
334 
335 	return dfs_process_radar_ind(dfs, radar_found);
336 }
337 qdf_export_symbol(tgt_dfs_process_radar_ind);
338 
339 #ifndef QCA_MCL_DFS_SUPPORT
340 QDF_STATUS tgt_dfs_cac_complete(struct wlan_objmgr_pdev *pdev, uint32_t vdev_id)
341 {
342 	return QDF_STATUS_SUCCESS;
343 }
344 #else
345 QDF_STATUS tgt_dfs_cac_complete(struct wlan_objmgr_pdev *pdev, uint32_t vdev_id)
346 {
347 	dfs_mlme_proc_cac(pdev, vdev_id);
348 
349 	return QDF_STATUS_SUCCESS;
350 }
351 #endif
352 qdf_export_symbol(tgt_dfs_cac_complete);
353 
354 QDF_STATUS tgt_dfs_reg_ev_handler(struct wlan_objmgr_psoc *psoc,
355 				  bool dfs_offload)
356 {
357 	struct wlan_lmac_if_dfs_tx_ops *dfs_tx_ops;
358 
359 	if (!psoc) {
360 		dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS, "null psoc");
361 		return QDF_STATUS_E_FAILURE;
362 	}
363 
364 	dfs_tx_ops = wlan_psoc_get_dfs_txops(psoc);
365 	if (!dfs_tx_ops) {
366 		dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS, "null dfs_tx_ops");
367 		return QDF_STATUS_E_FAILURE;
368 	}
369 
370 	if (dfs_tx_ops->dfs_reg_ev_handler)
371 		return dfs_tx_ops->dfs_reg_ev_handler(psoc, dfs_offload);
372 
373 	return QDF_STATUS_E_FAILURE;
374 }
375 qdf_export_symbol(tgt_dfs_reg_ev_handler);
376 
377 QDF_STATUS tgt_dfs_stop(struct wlan_objmgr_pdev *pdev)
378 {
379 	struct wlan_dfs *dfs;
380 
381 	dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev);
382 	if (!dfs) {
383 		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL");
384 		return  QDF_STATUS_E_FAILURE;
385 	}
386 
387 	dfs_stop(dfs);
388 
389 	return QDF_STATUS_SUCCESS;
390 }
391 qdf_export_symbol(tgt_dfs_stop);
392 
393 QDF_STATUS tgt_dfs_process_emulate_bang_radar_cmd(struct wlan_objmgr_pdev *pdev,
394 		struct dfs_emulate_bang_radar_test_cmd *dfs_unit_test)
395 {
396 	struct wlan_objmgr_psoc *psoc;
397 	struct wlan_lmac_if_dfs_tx_ops *dfs_tx_ops;
398 
399 	psoc = wlan_pdev_get_psoc(pdev);
400 	if (!psoc) {
401 		dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS, "psoc is null");
402 		return QDF_STATUS_E_FAILURE;
403 	}
404 
405 	dfs_tx_ops = wlan_psoc_get_dfs_txops(psoc);
406 	if (dfs_tx_ops && dfs_tx_ops->dfs_process_emulate_bang_radar_cmd)
407 		return dfs_tx_ops->dfs_process_emulate_bang_radar_cmd(pdev,
408 				dfs_unit_test);
409 	else
410 		dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS,
411 			"dfs_tx_ops=%pK", dfs_tx_ops);
412 
413 	return QDF_STATUS_E_FAILURE;
414 }
415 qdf_export_symbol(tgt_dfs_process_emulate_bang_radar_cmd);
416 
417 #ifdef QCA_MCL_DFS_SUPPORT
418 QDF_STATUS tgt_dfs_set_phyerr_filter_offload(struct wlan_objmgr_pdev *pdev)
419 {
420 	struct wlan_objmgr_psoc *psoc;
421 	struct wlan_lmac_if_dfs_tx_ops *dfs_tx_ops;
422 	struct dfs_soc_priv_obj *soc_obj;
423 
424 	psoc = wlan_pdev_get_psoc(pdev);
425 	if (!psoc) {
426 		dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS, "psoc is null");
427 		return QDF_STATUS_E_FAILURE;
428 	}
429 
430 	soc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc,
431 							WLAN_UMAC_COMP_DFS);
432 	if (!soc_obj) {
433 		dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS,
434 			"Failed to get dfs psoc component");
435 		return QDF_STATUS_E_FAILURE;
436 	}
437 	dfs_tx_ops = wlan_psoc_get_dfs_txops(psoc);
438 	if (dfs_tx_ops && dfs_tx_ops->dfs_set_phyerr_filter_offload)
439 		return dfs_tx_ops->dfs_set_phyerr_filter_offload(pdev,
440 				soc_obj->dfs_is_phyerr_filter_offload);
441 	else
442 		dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS,
443 			"dfs_tx_ops=%pK", dfs_tx_ops);
444 
445 	return QDF_STATUS_E_FAILURE;
446 }
447 qdf_export_symbol(tgt_dfs_set_phyerr_filter_offload);
448 #endif
449