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