xref: /wlan-dirver/qca-wifi-host-cmn/umac/dfs/dispatcher/src/wlan_dfs_mlme_api.c (revision 97f44cd39e4ff816eaa1710279d28cf6b9e65ad9)
1 /*
2  * Copyright (c) 2016-2020 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: Functions to call mlme functions from DFS component.
22  */
23 
24 #include "wlan_dfs_mlme_api.h"
25 #include "wlan_objmgr_vdev_obj.h"
26 #include "wlan_objmgr_pdev_obj.h"
27 #include "../../core/src/dfs.h"
28 #include "scheduler_api.h"
29 #include <wlan_reg_ucfg_api.h>
30 #ifdef QCA_MCL_DFS_SUPPORT
31 #include "wni_api.h"
32 #endif
33 
34 #if defined(QCA_DFS_RCSA_SUPPORT)
35 void dfs_mlme_start_rcsa(struct wlan_objmgr_pdev *pdev,
36 		bool *wait_for_csa)
37 {
38 	if (global_dfs_to_mlme.dfs_start_rcsa)
39 		global_dfs_to_mlme.dfs_start_rcsa(pdev, wait_for_csa);
40 }
41 #endif
42 
43 #ifndef QCA_MCL_DFS_SUPPORT
44 void dfs_mlme_mark_dfs(struct wlan_objmgr_pdev *pdev,
45 		uint8_t ieee,
46 		uint16_t freq,
47 		uint16_t vhtop_ch_freq_seg2,
48 		uint64_t flags)
49 {
50 	if (global_dfs_to_mlme.mlme_mark_dfs)
51 		global_dfs_to_mlme.mlme_mark_dfs(pdev,
52 				ieee,
53 				freq,
54 				vhtop_ch_freq_seg2,
55 				flags);
56 }
57 #else /* Else of ndef MCL_DFS_SUPPORT */
58 static void dfs_send_radar_ind(struct wlan_objmgr_pdev *pdev,
59 		void *object,
60 		void *arg)
61 {
62 	struct scheduler_msg sme_msg = {0};
63 	uint8_t vdev_id = wlan_vdev_get_id((struct wlan_objmgr_vdev *)object);
64 
65 	sme_msg.type = eWNI_SME_DFS_RADAR_FOUND;
66 	sme_msg.bodyptr = NULL;
67 	sme_msg.bodyval = vdev_id;
68 	scheduler_post_message(QDF_MODULE_ID_DFS,
69 			       QDF_MODULE_ID_SME,
70 			       QDF_MODULE_ID_SME, &sme_msg);
71 	dfs_debug(NULL, WLAN_DEBUG_DFS_ALWAYS, "eWNI_SME_DFS_RADAR_FOUND pdev%d posted",
72 		  vdev_id);
73 }
74 
75 void dfs_mlme_mark_dfs(struct wlan_objmgr_pdev *pdev,
76 		uint8_t ieee,
77 		uint16_t freq,
78 		uint16_t vhtop_ch_freq_seg2,
79 		uint64_t flags)
80 {
81 	struct wlan_objmgr_vdev *vdev;
82 
83 	if (!pdev) {
84 		dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS,  "null pdev");
85 		return;
86 	}
87 
88 	vdev = wlan_pdev_peek_active_first_vdev(pdev, WLAN_DFS_ID);
89 
90 	if (vdev) {
91 		dfs_send_radar_ind(pdev, vdev, NULL);
92 		wlan_objmgr_vdev_release_ref(vdev, WLAN_DFS_ID);
93 	}
94 }
95 #endif
96 
97 #ifndef QCA_MCL_DFS_SUPPORT
98 #ifdef CONFIG_CHAN_NUM_API
99 void dfs_mlme_start_csa(struct wlan_objmgr_pdev *pdev,
100 		uint8_t ieee_chan, uint16_t freq,
101 		uint8_t cfreq2, uint64_t flags)
102 {
103 	if (global_dfs_to_mlme.mlme_start_csa)
104 		global_dfs_to_mlme.mlme_start_csa(pdev, ieee_chan, freq, cfreq2,
105 				flags);
106 }
107 #endif
108 #ifdef CONFIG_CHAN_FREQ_API
109 void dfs_mlme_start_csa_for_freq(struct wlan_objmgr_pdev *pdev,
110 				 uint8_t ieee_chan, uint16_t freq,
111 				 uint16_t cfreq2, uint64_t flags)
112 {
113 	if (global_dfs_to_mlme.mlme_start_csa_for_freq)
114 		global_dfs_to_mlme.mlme_start_csa_for_freq(pdev, ieee_chan,
115 							   freq, cfreq2, flags);
116 }
117 #endif
118 #else
119 #ifdef CONFIG_CHAN_NUM_API
120 void dfs_mlme_start_csa(struct wlan_objmgr_pdev *pdev,
121 			uint8_t ieee_chan, uint16_t freq,
122 			uint8_t cfreq2, uint64_t flags)
123 {
124 	struct wlan_objmgr_vdev *vdev;
125 
126 	if (!pdev) {
127 		dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS,  "null pdev");
128 		return;
129 	}
130 
131 	vdev = wlan_pdev_peek_active_first_vdev(pdev, WLAN_DFS_ID);
132 
133 	if (vdev) {
134 		dfs_send_radar_ind(pdev, vdev, NULL);
135 		wlan_objmgr_vdev_release_ref(vdev, WLAN_DFS_ID);
136 	}
137 }
138 #endif
139 #ifdef CONFIG_CHAN_FREQ_API
140 void dfs_mlme_start_csa_for_freq(struct wlan_objmgr_pdev *pdev,
141 				 uint8_t ieee_chan, uint16_t freq,
142 				 uint16_t cfreq2, uint64_t flags)
143 {
144 	struct wlan_objmgr_vdev *vdev;
145 
146 	if (!pdev) {
147 		dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS,  "null pdev");
148 		return;
149 	}
150 
151 	vdev = wlan_pdev_peek_active_first_vdev(pdev, WLAN_DFS_ID);
152 
153 	if (vdev) {
154 		dfs_send_radar_ind(pdev, vdev, NULL);
155 		wlan_objmgr_vdev_release_ref(vdev, WLAN_DFS_ID);
156 	}
157 }
158 #endif
159 #endif
160 
161 #ifndef QCA_MCL_DFS_SUPPORT
162 void dfs_mlme_proc_cac(struct wlan_objmgr_pdev *pdev, uint32_t vdev_id)
163 {
164 	if (global_dfs_to_mlme.mlme_proc_cac)
165 		global_dfs_to_mlme.mlme_proc_cac(pdev);
166 }
167 #else
168 void dfs_mlme_proc_cac(struct wlan_objmgr_pdev *pdev, uint32_t vdev_id)
169 {
170 	struct scheduler_msg sme_msg = {0};
171 
172 	sme_msg.type = eWNI_SME_DFS_CAC_COMPLETE;
173 	sme_msg.bodyptr = NULL;
174 	sme_msg.bodyval = vdev_id;
175 	scheduler_post_message(QDF_MODULE_ID_DFS,
176 			       QDF_MODULE_ID_SME,
177 			       QDF_MODULE_ID_SME, &sme_msg);
178 	dfs_info(NULL, WLAN_DEBUG_DFS_ALWAYS, "eWNI_SME_DFS_CAC_COMPLETE vdev%d posted",
179 		    vdev_id);
180 }
181 #endif
182 
183 void dfs_mlme_deliver_event_up_after_cac(struct wlan_objmgr_pdev *pdev)
184 {
185 	if (global_dfs_to_mlme.mlme_deliver_event_up_after_cac)
186 		global_dfs_to_mlme.mlme_deliver_event_up_after_cac(
187 				pdev);
188 }
189 
190 void dfs_mlme_get_dfs_ch_nchans(struct wlan_objmgr_pdev *pdev,
191 		int *nchans)
192 {
193 	if (global_dfs_to_mlme.mlme_get_dfs_ch_nchans)
194 		global_dfs_to_mlme.mlme_get_dfs_ch_nchans(pdev,
195 				nchans);
196 }
197 
198 #ifdef CONFIG_CHAN_NUM_API
199 QDF_STATUS dfs_mlme_get_extchan(struct wlan_objmgr_pdev *pdev,
200 		uint16_t *dfs_ch_freq,
201 		uint64_t *dfs_ch_flags,
202 		uint16_t *dfs_ch_flagext,
203 		uint8_t *dfs_ch_ieee,
204 		uint8_t *dfs_ch_vhtop_ch_freq_seg1,
205 		uint8_t *dfs_ch_vhtop_ch_freq_seg2)
206 {
207 	if (global_dfs_to_mlme.mlme_get_extchan)
208 		return global_dfs_to_mlme.mlme_get_extchan(pdev,
209 				dfs_ch_freq,
210 				dfs_ch_flags,
211 				dfs_ch_flagext,
212 				dfs_ch_ieee,
213 				dfs_ch_vhtop_ch_freq_seg1,
214 				dfs_ch_vhtop_ch_freq_seg2);
215 
216 	return QDF_STATUS_E_FAILURE;
217 }
218 #endif
219 
220 #ifdef CONFIG_CHAN_FREQ_API
221 QDF_STATUS dfs_mlme_get_extchan_for_freq(struct wlan_objmgr_pdev *pdev,
222 					 uint16_t *dfs_chan_freq,
223 					 uint64_t *dfs_chan_flags,
224 					 uint16_t *dfs_chan_flagext,
225 					 uint8_t *dfs_chan_ieee,
226 					 uint8_t *dfs_chan_vhtop_ch_freq_seg1,
227 					 uint8_t *dfs_chan_vhtop_ch_freq_seg2,
228 					 uint16_t *dfs_chan_mhz_freq_seg1,
229 					 uint16_t *dfs_chan_mhz_freq_seg2)
230 {
231 	if (global_dfs_to_mlme.mlme_get_extchan_for_freq)
232 		return global_dfs_to_mlme.mlme_get_extchan_for_freq(pdev,
233 				dfs_chan_freq,
234 				dfs_chan_flags,
235 				dfs_chan_flagext,
236 				dfs_chan_ieee,
237 				dfs_chan_vhtop_ch_freq_seg1,
238 				dfs_chan_vhtop_ch_freq_seg2,
239 				dfs_chan_mhz_freq_seg1,
240 				dfs_chan_mhz_freq_seg2);
241 
242 	return QDF_STATUS_E_FAILURE;
243 }
244 #endif
245 
246 void dfs_mlme_set_no_chans_available(struct wlan_objmgr_pdev *pdev,
247 		int val)
248 {
249 	if (global_dfs_to_mlme.mlme_set_no_chans_available)
250 		global_dfs_to_mlme.mlme_set_no_chans_available(
251 				pdev,
252 				val);
253 }
254 
255 int dfs_mlme_ieee2mhz(struct wlan_objmgr_pdev *pdev, int ieee, uint64_t flag)
256 {
257 	int freq = 0;
258 
259 	if (global_dfs_to_mlme.mlme_ieee2mhz)
260 		global_dfs_to_mlme.mlme_ieee2mhz(pdev,
261 				ieee,
262 				flag,
263 				&freq);
264 
265 	return freq;
266 }
267 
268 #ifdef CONFIG_CHAN_NUM_API
269 QDF_STATUS
270 dfs_mlme_find_dot11_channel(struct wlan_objmgr_pdev *pdev,
271 			    uint8_t ieee,
272 			    uint8_t des_cfreq2,
273 			    int mode,
274 			    uint16_t *dfs_ch_freq,
275 			    uint64_t *dfs_ch_flags,
276 			    uint16_t *dfs_ch_flagext,
277 			    uint8_t *dfs_ch_ieee,
278 			    uint8_t *dfs_ch_vhtop_ch_freq_seg1,
279 			    uint8_t *dfs_ch_vhtop_ch_freq_seg2)
280 {
281 	if (global_dfs_to_mlme.mlme_find_dot11_channel)
282 		return global_dfs_to_mlme.mlme_find_dot11_channel(pdev,
283 								  ieee,
284 								  des_cfreq2,
285 								  mode,
286 								  dfs_ch_freq,
287 								  dfs_ch_flags,
288 								  dfs_ch_flagext,
289 								  dfs_ch_ieee,
290 								  dfs_ch_vhtop_ch_freq_seg1,
291 								  dfs_ch_vhtop_ch_freq_seg2);
292 	return QDF_STATUS_E_FAILURE;
293 }
294 #endif
295 
296 #ifdef CONFIG_CHAN_FREQ_API
297 QDF_STATUS
298 dfs_mlme_find_dot11_chan_for_freq(struct wlan_objmgr_pdev *pdev,
299 				  uint16_t freq,
300 				  uint16_t des_cfreq2,
301 				  int mode,
302 				  uint16_t *dfs_chan_freq,
303 				  uint64_t *dfs_chan_flag,
304 				  uint16_t *dfs_flagext,
305 				  uint8_t *dfs_chan_ieee,
306 				  uint8_t *dfs_cfreq1,
307 				  uint8_t *dfs_cfreq2,
308 				  uint16_t *cfreq1_mhz,
309 				  uint16_t *cfreq2_mhz)
310 {
311 	if (global_dfs_to_mlme.mlme_find_dot11_chan_for_freq)
312 	return global_dfs_to_mlme.mlme_find_dot11_chan_for_freq(pdev,
313 								freq,
314 								des_cfreq2,
315 								mode,
316 								dfs_chan_freq,
317 								dfs_chan_flag,
318 								dfs_flagext,
319 								dfs_chan_ieee,
320 								dfs_cfreq1,
321 								dfs_cfreq2,
322 								cfreq1_mhz,
323 								cfreq2_mhz);
324 	return QDF_STATUS_E_FAILURE;
325 }
326 #endif
327 
328 #ifdef CONFIG_CHAN_NUM_API
329 void dfs_mlme_get_dfs_ch_channels(struct wlan_objmgr_pdev *pdev,
330 		uint16_t *dfs_ch_freq,
331 		uint64_t *dfs_ch_flags,
332 		uint16_t *dfs_ch_flagext,
333 		uint8_t *dfs_ch_ieee,
334 		uint8_t *dfs_ch_vhtop_ch_freq_seg1,
335 		uint8_t *dfs_ch_vhtop_ch_freq_seg2,
336 		int index)
337 {
338 	if (global_dfs_to_mlme.mlme_get_dfs_ch_channels)
339 		global_dfs_to_mlme.mlme_get_dfs_ch_channels(pdev,
340 				dfs_ch_freq,
341 				dfs_ch_flags,
342 				dfs_ch_flagext,
343 				dfs_ch_ieee,
344 				dfs_ch_vhtop_ch_freq_seg1,
345 				dfs_ch_vhtop_ch_freq_seg2,
346 				index);
347 }
348 #endif
349 
350 #ifdef CONFIG_CHAN_FREQ_API
351 void dfs_mlme_get_dfs_channels_for_freq(struct wlan_objmgr_pdev *pdev,
352 					uint16_t *dfs_chan_freq,
353 					uint64_t *dfs_chan_flags,
354 					uint16_t *dfs_chan_flagext,
355 					uint8_t *dfs_chan_ieee,
356 					uint8_t *dfs_chan_vhtop_freq_seg1,
357 					uint8_t *dfs_chan_vhtop_freq_seg2,
358 					uint16_t *dfs_ch_mhz_freq_seg1,
359 					uint16_t *dfs_ch_mhz_freq_seg2,
360 					int index)
361 {
362 	if (global_dfs_to_mlme.mlme_get_dfs_channels_for_freq)
363 		global_dfs_to_mlme.mlme_get_dfs_channels_for_freq(pdev,
364 				dfs_chan_freq,
365 				dfs_chan_flags,
366 				dfs_chan_flagext,
367 				dfs_chan_ieee,
368 				dfs_chan_vhtop_freq_seg1,
369 				dfs_chan_vhtop_freq_seg2,
370 				dfs_ch_mhz_freq_seg1,
371 				dfs_ch_mhz_freq_seg2,
372 				index);
373 }
374 #endif
375 
376 uint32_t dfs_mlme_dfs_ch_flags_ext(struct wlan_objmgr_pdev *pdev)
377 {
378 	uint16_t flag_ext = 0;
379 
380 	if (global_dfs_to_mlme.mlme_dfs_ch_flags_ext)
381 		global_dfs_to_mlme.mlme_dfs_ch_flags_ext(pdev,
382 				&flag_ext);
383 
384 	return flag_ext;
385 }
386 
387 void dfs_mlme_channel_change_by_precac(struct wlan_objmgr_pdev *pdev)
388 {
389 	if (global_dfs_to_mlme.mlme_channel_change_by_precac)
390 		global_dfs_to_mlme.mlme_channel_change_by_precac(
391 				pdev);
392 }
393 
394 void dfs_mlme_nol_timeout_notification(struct wlan_objmgr_pdev *pdev)
395 {
396 	if (global_dfs_to_mlme.mlme_nol_timeout_notification)
397 		global_dfs_to_mlme.mlme_nol_timeout_notification(
398 				pdev);
399 }
400 
401 void dfs_mlme_clist_update(struct wlan_objmgr_pdev *pdev,
402 		void *nollist,
403 		int nentries)
404 {
405 	if (global_dfs_to_mlme.mlme_clist_update)
406 		global_dfs_to_mlme.mlme_clist_update(pdev,
407 				nollist,
408 				nentries);
409 }
410 
411 #ifdef CONFIG_CHAN_NUM_API
412 int dfs_mlme_get_cac_timeout(struct wlan_objmgr_pdev *pdev,
413 		uint16_t dfs_ch_freq,
414 		uint8_t dfs_ch_vhtop_ch_freq_seg2,
415 		uint64_t dfs_ch_flags)
416 {
417 	int cac_timeout = 0;
418 
419 	if (global_dfs_to_mlme.mlme_get_cac_timeout)
420 		global_dfs_to_mlme.mlme_get_cac_timeout(pdev,
421 				dfs_ch_freq,
422 				dfs_ch_vhtop_ch_freq_seg2,
423 				dfs_ch_flags,
424 				&cac_timeout);
425 
426 	return cac_timeout;
427 }
428 #endif
429 
430 #ifdef CONFIG_CHAN_FREQ_API
431 int dfs_mlme_get_cac_timeout_for_freq(struct wlan_objmgr_pdev *pdev,
432 				      uint16_t dfs_chan_freq,
433 				      uint16_t dfs_cfreq2,
434 				      uint64_t dfs_ch_flags)
435 {
436 	int cac_timeout = 0;
437 
438 	if (global_dfs_to_mlme.mlme_get_cac_timeout_for_freq)
439 		global_dfs_to_mlme.mlme_get_cac_timeout_for_freq(pdev,
440 								 dfs_chan_freq,
441 								 dfs_cfreq2,
442 								 dfs_ch_flags,
443 								 &cac_timeout);
444 
445 	return cac_timeout;
446 }
447 #endif
448 
449 #if defined(WLAN_DFS_PARTIAL_OFFLOAD) && defined(HOST_DFS_SPOOF_TEST)
450 int dfs_mlme_rebuild_chan_list_with_non_dfs_channels(
451 		struct wlan_objmgr_pdev *pdev)
452 {
453 	if (!global_dfs_to_mlme.mlme_rebuild_chan_list_with_non_dfs_channels)
454 		return 1;
455 
456 	return global_dfs_to_mlme.mlme_rebuild_chan_list_with_non_dfs_channels(
457 			pdev);
458 }
459 
460 void dfs_mlme_restart_vaps_with_non_dfs_chan(struct wlan_objmgr_pdev *pdev,
461 					     int no_chans_avail)
462 {
463 	if (!global_dfs_to_mlme.mlme_restart_vaps_with_non_dfs_chan)
464 		return;
465 
466 	global_dfs_to_mlme.mlme_restart_vaps_with_non_dfs_chan(pdev,
467 							       no_chans_avail);
468 }
469 #endif
470 
471 #if defined(WLAN_SUPPORT_PRIMARY_ALLOWED_CHAN)
472 bool dfs_mlme_check_allowed_prim_chanlist(struct wlan_objmgr_pdev *pdev,
473 					  uint32_t chan_freq)
474 {
475 	if (!global_dfs_to_mlme.mlme_check_allowed_prim_chanlist)
476 		return true;
477 
478 	return global_dfs_to_mlme.mlme_check_allowed_prim_chanlist(pdev,
479 								   chan_freq);
480 }
481 
482 #endif
483 
484 #if defined(WLAN_DFS_FULL_OFFLOAD) && defined(QCA_DFS_NOL_OFFLOAD)
485 void dfs_mlme_handle_dfs_scan_violation(struct wlan_objmgr_pdev *pdev)
486 {
487 	bool dfs_enable = 0;
488 
489 	/*Disable all DFS channels in master channel list and ic channel list */
490 	ucfg_reg_enable_dfs_channels(pdev, dfs_enable);
491 
492 	/* send the updated channel list to FW */
493 	global_dfs_to_mlme.mlme_update_scan_channel_list(pdev);
494 }
495 #endif
496 
497 bool dfs_mlme_is_inter_band_chan_switch_allowed(struct wlan_objmgr_pdev *pdev)
498 {
499 	if (!global_dfs_to_mlme.mlme_is_inter_band_chan_switch_allowed)
500 		return false;
501 
502 	return global_dfs_to_mlme.mlme_is_inter_band_chan_switch_allowed(pdev);
503 }
504 
505 bool dfs_mlme_is_opmode_sta(struct wlan_objmgr_pdev *pdev)
506 {
507 	if (!global_dfs_to_mlme.mlme_is_opmode_sta)
508 		return false;
509 
510 	return global_dfs_to_mlme.mlme_is_opmode_sta(pdev);
511 }
512 
513 void dfs_mlme_acquire_radar_mode_switch_lock(struct wlan_objmgr_pdev *pdev)
514 {
515 	if (!global_dfs_to_mlme.mlme_acquire_radar_mode_switch_lock)
516 		return;
517 
518 	global_dfs_to_mlme.mlme_acquire_radar_mode_switch_lock(pdev);
519 }
520 
521 void dfs_mlme_release_radar_mode_switch_lock(struct wlan_objmgr_pdev *pdev)
522 {
523 	if (!global_dfs_to_mlme.mlme_release_radar_mode_switch_lock)
524 		return;
525 
526 	global_dfs_to_mlme.mlme_release_radar_mode_switch_lock(pdev);
527 }
528