xref: /wlan-dirver/qca-wifi-host-cmn/umac/dfs/dispatcher/src/wlan_dfs_mlme_api.c (revision 2888b71da71bce103343119fa1b31f4a0cee07c8)
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: Functions to call mlme functions from DFS component.
23  */
24 
25 #include "wlan_dfs_mlme_api.h"
26 #include "wlan_objmgr_vdev_obj.h"
27 #include "wlan_objmgr_pdev_obj.h"
28 #include "../../core/src/dfs.h"
29 #include "scheduler_api.h"
30 #include <wlan_reg_ucfg_api.h>
31 #ifdef MOBILE_DFS_SUPPORT
32 #include "wni_api.h"
33 #endif
34 
35 #if defined(QCA_DFS_RCSA_SUPPORT)
36 void dfs_mlme_start_rcsa(struct wlan_objmgr_pdev *pdev,
37 		bool *wait_for_csa)
38 {
39 	if (global_dfs_to_mlme.dfs_start_rcsa)
40 		global_dfs_to_mlme.dfs_start_rcsa(pdev, wait_for_csa);
41 }
42 #endif
43 
44 #if defined(WLAN_DFS_PARTIAL_OFFLOAD) && defined(HOST_DFS_SPOOF_TEST)
45 void dfs_mlme_proc_spoof_success(struct wlan_objmgr_pdev *pdev)
46 {
47 	if (global_dfs_to_mlme.mlme_proc_spoof_success)
48 		global_dfs_to_mlme.mlme_proc_spoof_success(pdev);
49 }
50 #endif
51 
52 #ifndef MOBILE_DFS_SUPPORT
53 void dfs_mlme_mark_dfs(struct wlan_objmgr_pdev *pdev,
54 		uint8_t ieee,
55 		uint16_t freq,
56 		uint16_t vhtop_ch_freq_seg2,
57 		uint64_t flags,
58 		uint16_t dfs_radar_bitmap)
59 {
60 	if (global_dfs_to_mlme.mlme_mark_dfs)
61 		global_dfs_to_mlme.mlme_mark_dfs(pdev,
62 				ieee,
63 				freq,
64 				vhtop_ch_freq_seg2,
65 				flags,
66 				dfs_radar_bitmap);
67 }
68 #else /* Else of ndef MCL_DFS_SUPPORT */
69 static void dfs_send_radar_ind(struct wlan_objmgr_pdev *pdev,
70 		void *object,
71 		void *arg)
72 {
73 	struct scheduler_msg sme_msg = {0};
74 	uint8_t vdev_id = wlan_vdev_get_id((struct wlan_objmgr_vdev *)object);
75 
76 	sme_msg.type = eWNI_SME_DFS_RADAR_FOUND;
77 	sme_msg.bodyptr = NULL;
78 	sme_msg.bodyval = vdev_id;
79 	scheduler_post_message(QDF_MODULE_ID_DFS,
80 			       QDF_MODULE_ID_SME,
81 			       QDF_MODULE_ID_SME, &sme_msg);
82 	dfs_debug(NULL, WLAN_DEBUG_DFS_ALWAYS, "eWNI_SME_DFS_RADAR_FOUND pdev%d posted",
83 		  vdev_id);
84 }
85 
86 void dfs_mlme_mark_dfs(struct wlan_objmgr_pdev *pdev,
87 		uint8_t ieee,
88 		uint16_t freq,
89 		uint16_t vhtop_ch_freq_seg2,
90 		uint64_t flags,
91 		uint16_t dfs_radar_bitmap)
92 {
93 	struct wlan_objmgr_vdev *vdev;
94 
95 	if (!pdev) {
96 		dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS,  "null pdev");
97 		return;
98 	}
99 
100 	vdev = wlan_pdev_peek_active_first_vdev(pdev, WLAN_DFS_ID);
101 
102 	if (vdev) {
103 		dfs_send_radar_ind(pdev, vdev, NULL);
104 		wlan_objmgr_vdev_release_ref(vdev, WLAN_DFS_ID);
105 	}
106 }
107 #endif
108 
109 #ifndef MOBILE_DFS_SUPPORT
110 #ifdef CONFIG_CHAN_FREQ_API
111 void dfs_mlme_start_csa_for_freq(struct wlan_objmgr_pdev *pdev,
112 				 uint8_t ieee_chan, uint16_t freq,
113 				 uint16_t cfreq2, uint64_t flags)
114 {
115 	if (global_dfs_to_mlme.mlme_start_csa_for_freq)
116 		global_dfs_to_mlme.mlme_start_csa_for_freq(pdev, ieee_chan,
117 							   freq, cfreq2, flags);
118 }
119 #endif
120 #else
121 #ifdef CONFIG_CHAN_FREQ_API
122 void dfs_mlme_start_csa_for_freq(struct wlan_objmgr_pdev *pdev,
123 				 uint8_t ieee_chan, uint16_t freq,
124 				 uint16_t cfreq2, uint64_t flags)
125 {
126 	struct wlan_objmgr_vdev *vdev;
127 
128 	if (!pdev) {
129 		dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS,  "null pdev");
130 		return;
131 	}
132 
133 	vdev = wlan_pdev_peek_active_first_vdev(pdev, WLAN_DFS_ID);
134 
135 	if (vdev) {
136 		dfs_send_radar_ind(pdev, vdev, NULL);
137 		wlan_objmgr_vdev_release_ref(vdev, WLAN_DFS_ID);
138 	}
139 }
140 #endif
141 #endif
142 
143 #ifndef MOBILE_DFS_SUPPORT
144 void dfs_mlme_proc_cac(struct wlan_objmgr_pdev *pdev, uint32_t vdev_id)
145 {
146 	if (global_dfs_to_mlme.mlme_proc_cac)
147 		global_dfs_to_mlme.mlme_proc_cac(pdev);
148 }
149 #else
150 void dfs_mlme_proc_cac(struct wlan_objmgr_pdev *pdev, uint32_t vdev_id)
151 {
152 	struct scheduler_msg sme_msg = {0};
153 
154 	sme_msg.type = eWNI_SME_DFS_CAC_COMPLETE;
155 	sme_msg.bodyptr = NULL;
156 	sme_msg.bodyval = vdev_id;
157 	scheduler_post_message(QDF_MODULE_ID_DFS,
158 			       QDF_MODULE_ID_SME,
159 			       QDF_MODULE_ID_SME, &sme_msg);
160 	dfs_info(NULL, WLAN_DEBUG_DFS_ALWAYS, "eWNI_SME_DFS_CAC_COMPLETE vdev%d posted",
161 		    vdev_id);
162 }
163 #endif
164 
165 void dfs_mlme_deliver_event_up_after_cac(struct wlan_objmgr_pdev *pdev)
166 {
167 	if (global_dfs_to_mlme.mlme_deliver_event_up_after_cac)
168 		global_dfs_to_mlme.mlme_deliver_event_up_after_cac(
169 				pdev);
170 }
171 
172 #ifdef CONFIG_CHAN_FREQ_API
173 QDF_STATUS dfs_mlme_get_extchan_for_freq(struct wlan_objmgr_pdev *pdev,
174 					 uint16_t *dfs_chan_freq,
175 					 uint64_t *dfs_chan_flags,
176 					 uint16_t *dfs_chan_flagext,
177 					 uint8_t *dfs_chan_ieee,
178 					 uint8_t *dfs_chan_vhtop_ch_freq_seg1,
179 					 uint8_t *dfs_chan_vhtop_ch_freq_seg2,
180 					 uint16_t *dfs_chan_mhz_freq_seg1,
181 					 uint16_t *dfs_chan_mhz_freq_seg2)
182 {
183 	if (global_dfs_to_mlme.mlme_get_extchan_for_freq)
184 		return global_dfs_to_mlme.mlme_get_extchan_for_freq(pdev,
185 				dfs_chan_freq,
186 				dfs_chan_flags,
187 				dfs_chan_flagext,
188 				dfs_chan_ieee,
189 				dfs_chan_vhtop_ch_freq_seg1,
190 				dfs_chan_vhtop_ch_freq_seg2,
191 				dfs_chan_mhz_freq_seg1,
192 				dfs_chan_mhz_freq_seg2);
193 
194 	return QDF_STATUS_E_FAILURE;
195 }
196 #endif
197 
198 void dfs_mlme_set_no_chans_available(struct wlan_objmgr_pdev *pdev,
199 		int val)
200 {
201 	if (global_dfs_to_mlme.mlme_set_no_chans_available)
202 		global_dfs_to_mlme.mlme_set_no_chans_available(
203 				pdev,
204 				val);
205 }
206 
207 int dfs_mlme_ieee2mhz(struct wlan_objmgr_pdev *pdev, int ieee, uint64_t flag)
208 {
209 	int freq = 0;
210 
211 	if (global_dfs_to_mlme.mlme_ieee2mhz)
212 		global_dfs_to_mlme.mlme_ieee2mhz(pdev,
213 				ieee,
214 				flag,
215 				&freq);
216 
217 	return freq;
218 }
219 
220 #ifdef CONFIG_CHAN_FREQ_API
221 QDF_STATUS
222 dfs_mlme_find_dot11_chan_for_freq(struct wlan_objmgr_pdev *pdev,
223 				  uint16_t freq,
224 				  uint16_t des_cfreq2,
225 				  int mode,
226 				  uint16_t *dfs_chan_freq,
227 				  uint64_t *dfs_chan_flag,
228 				  uint16_t *dfs_flagext,
229 				  uint8_t *dfs_chan_ieee,
230 				  uint8_t *dfs_cfreq1,
231 				  uint8_t *dfs_cfreq2,
232 				  uint16_t *cfreq1_mhz,
233 				  uint16_t *cfreq2_mhz)
234 {
235 	if (global_dfs_to_mlme.mlme_find_dot11_chan_for_freq)
236 	return global_dfs_to_mlme.mlme_find_dot11_chan_for_freq(pdev,
237 								freq,
238 								des_cfreq2,
239 								mode,
240 								dfs_chan_freq,
241 								dfs_chan_flag,
242 								dfs_flagext,
243 								dfs_chan_ieee,
244 								dfs_cfreq1,
245 								dfs_cfreq2,
246 								cfreq1_mhz,
247 								cfreq2_mhz);
248 	return QDF_STATUS_E_FAILURE;
249 }
250 #endif
251 
252 
253 uint32_t dfs_mlme_dfs_ch_flags_ext(struct wlan_objmgr_pdev *pdev)
254 {
255 	uint16_t flag_ext = 0;
256 
257 	if (global_dfs_to_mlme.mlme_dfs_ch_flags_ext)
258 		global_dfs_to_mlme.mlme_dfs_ch_flags_ext(pdev,
259 				&flag_ext);
260 
261 	return flag_ext;
262 }
263 
264 void dfs_mlme_channel_change_by_precac(struct wlan_objmgr_pdev *pdev)
265 {
266 	if (global_dfs_to_mlme.mlme_channel_change_by_precac)
267 		global_dfs_to_mlme.mlme_channel_change_by_precac(
268 				pdev);
269 }
270 
271 void dfs_mlme_nol_timeout_notification(struct wlan_objmgr_pdev *pdev)
272 {
273 	if (global_dfs_to_mlme.mlme_nol_timeout_notification)
274 		global_dfs_to_mlme.mlme_nol_timeout_notification(
275 				pdev);
276 }
277 
278 void dfs_mlme_clist_update(struct wlan_objmgr_pdev *pdev,
279 		void *nollist,
280 		int nentries)
281 {
282 	if (global_dfs_to_mlme.mlme_clist_update)
283 		global_dfs_to_mlme.mlme_clist_update(pdev,
284 				nollist,
285 				nentries);
286 }
287 
288 #ifdef CONFIG_CHAN_FREQ_API
289 int dfs_mlme_get_cac_timeout_for_freq(struct wlan_objmgr_pdev *pdev,
290 				      uint16_t dfs_chan_freq,
291 				      uint16_t dfs_cfreq2,
292 				      uint64_t dfs_ch_flags)
293 {
294 	int cac_timeout = 0;
295 
296 	if (global_dfs_to_mlme.mlme_get_cac_timeout_for_freq)
297 		global_dfs_to_mlme.mlme_get_cac_timeout_for_freq(pdev,
298 								 dfs_chan_freq,
299 								 dfs_cfreq2,
300 								 dfs_ch_flags,
301 								 &cac_timeout);
302 
303 	return cac_timeout;
304 }
305 #endif
306 
307 #if defined(WLAN_DFS_PARTIAL_OFFLOAD) && defined(HOST_DFS_SPOOF_TEST)
308 int dfs_mlme_rebuild_chan_list_with_non_dfs_channels(
309 		struct wlan_objmgr_pdev *pdev)
310 {
311 	if (!global_dfs_to_mlme.mlme_rebuild_chan_list_with_non_dfs_channels)
312 		return 1;
313 
314 	return global_dfs_to_mlme.mlme_rebuild_chan_list_with_non_dfs_channels(
315 			pdev);
316 }
317 
318 void dfs_mlme_restart_vaps_with_non_dfs_chan(struct wlan_objmgr_pdev *pdev,
319 					     int no_chans_avail)
320 {
321 	if (!global_dfs_to_mlme.mlme_restart_vaps_with_non_dfs_chan)
322 		return;
323 
324 	global_dfs_to_mlme.mlme_restart_vaps_with_non_dfs_chan(pdev,
325 							       no_chans_avail);
326 }
327 #endif
328 
329 #if defined(WLAN_SUPPORT_PRIMARY_ALLOWED_CHAN)
330 bool dfs_mlme_check_allowed_prim_chanlist(struct wlan_objmgr_pdev *pdev,
331 					  uint32_t chan_freq)
332 {
333 	if (!global_dfs_to_mlme.mlme_check_allowed_prim_chanlist)
334 		return true;
335 
336 	return global_dfs_to_mlme.mlme_check_allowed_prim_chanlist(pdev,
337 								   chan_freq);
338 }
339 
340 #endif
341 
342 #if defined(WLAN_DFS_FULL_OFFLOAD) && defined(QCA_DFS_NOL_OFFLOAD)
343 void dfs_mlme_handle_dfs_scan_violation(struct wlan_objmgr_pdev *pdev)
344 {
345 	bool dfs_enable = 0;
346 
347 	/*Disable all DFS channels in master channel list and ic channel list */
348 	ucfg_reg_enable_dfs_channels(pdev, dfs_enable);
349 
350 	/* send the updated channel list to FW */
351 	global_dfs_to_mlme.mlme_update_scan_channel_list(pdev);
352 }
353 #endif
354 
355 bool dfs_mlme_is_inter_band_chan_switch_allowed(struct wlan_objmgr_pdev *pdev)
356 {
357 	if (!global_dfs_to_mlme.mlme_is_inter_band_chan_switch_allowed)
358 		return false;
359 
360 	return global_dfs_to_mlme.mlme_is_inter_band_chan_switch_allowed(pdev);
361 }
362 
363 bool dfs_mlme_is_opmode_sta(struct wlan_objmgr_pdev *pdev)
364 {
365 	if (!global_dfs_to_mlme.mlme_is_opmode_sta)
366 		return false;
367 
368 	return global_dfs_to_mlme.mlme_is_opmode_sta(pdev);
369 }
370