1 /*
2  * Copyright (c) 2016-2021 The Linux Foundation. All rights reserved.
3  * Copyright (c) 2022-2023 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)
dfs_mlme_start_rcsa(struct wlan_objmgr_pdev * pdev,bool * wait_for_csa)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)
dfs_mlme_proc_spoof_success(struct wlan_objmgr_pdev * pdev)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
dfs_mlme_mark_dfs(struct wlan_objmgr_pdev * pdev,uint8_t ieee,uint16_t freq,uint16_t vhtop_ch_freq_seg2,uint64_t flags,uint16_t dfs_radar_bitmap)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 */
dfs_send_radar_ind(struct wlan_objmgr_pdev * pdev,void * object,void * arg)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 
dfs_mlme_mark_dfs(struct wlan_objmgr_pdev * pdev,uint8_t ieee,uint16_t freq,uint16_t vhtop_ch_freq_seg2,uint64_t flags,uint16_t dfs_radar_bitmap)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
dfs_mlme_start_csa_for_freq(struct wlan_objmgr_pdev * pdev,uint8_t ieee_chan,uint16_t freq,uint16_t cfreq2,uint64_t flags)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
dfs_mlme_start_csa_for_freq(struct wlan_objmgr_pdev * pdev,uint8_t ieee_chan,uint16_t freq,uint16_t cfreq2,uint64_t flags)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
dfs_mlme_proc_cac(struct wlan_objmgr_pdev * pdev,uint32_t vdev_id)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
dfs_mlme_proc_cac(struct wlan_objmgr_pdev * pdev,uint32_t vdev_id)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 
dfs_mlme_deliver_event_up_after_cac(struct wlan_objmgr_pdev * pdev)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
dfs_mlme_get_extchan_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_ch_freq_seg1,uint8_t * dfs_chan_vhtop_ch_freq_seg2,uint16_t * dfs_chan_mhz_freq_seg1,uint16_t * dfs_chan_mhz_freq_seg2)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 
dfs_mlme_set_no_chans_available(struct wlan_objmgr_pdev * pdev,int val)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 
dfs_mlme_ieee2mhz(struct wlan_objmgr_pdev * pdev,int ieee,uint64_t flag)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
dfs_mlme_find_dot11_chan_for_freq(struct wlan_objmgr_pdev * pdev,uint16_t freq,uint16_t des_cfreq2,int mode,uint16_t * dfs_chan_freq,uint64_t * dfs_chan_flag,uint16_t * dfs_flagext,uint8_t * dfs_chan_ieee,uint8_t * dfs_cfreq1,uint8_t * dfs_cfreq2,uint16_t * cfreq1_mhz,uint16_t * cfreq2_mhz)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 
dfs_mlme_dfs_ch_flags_ext(struct wlan_objmgr_pdev * pdev)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 
dfs_mlme_channel_change_by_precac(struct wlan_objmgr_pdev * pdev)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 
dfs_mlme_nol_timeout_notification(struct wlan_objmgr_pdev * pdev)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 
dfs_mlme_set_tx_flag(struct wlan_objmgr_pdev * pdev,bool is_tx_allowed)278 void dfs_mlme_set_tx_flag(struct wlan_objmgr_pdev *pdev, bool is_tx_allowed)
279 {
280 	if (global_dfs_to_mlme.mlme_set_tx_flag)
281 		global_dfs_to_mlme.mlme_set_tx_flag(pdev, is_tx_allowed);
282 }
283 
dfs_mlme_clist_update(struct wlan_objmgr_pdev * pdev,void * nollist,int nentries)284 void dfs_mlme_clist_update(struct wlan_objmgr_pdev *pdev,
285 		void *nollist,
286 		int nentries)
287 {
288 	if (global_dfs_to_mlme.mlme_clist_update)
289 		global_dfs_to_mlme.mlme_clist_update(pdev,
290 				nollist,
291 				nentries);
292 }
293 
294 #ifdef CONFIG_CHAN_FREQ_API
dfs_mlme_get_cac_timeout_for_freq(struct wlan_objmgr_pdev * pdev,uint16_t dfs_chan_freq,uint16_t dfs_cfreq2,uint64_t dfs_ch_flags)295 int dfs_mlme_get_cac_timeout_for_freq(struct wlan_objmgr_pdev *pdev,
296 				      uint16_t dfs_chan_freq,
297 				      uint16_t dfs_cfreq2,
298 				      uint64_t dfs_ch_flags)
299 {
300 	int cac_timeout = 0;
301 
302 	if (global_dfs_to_mlme.mlme_get_cac_timeout_for_freq)
303 		global_dfs_to_mlme.mlme_get_cac_timeout_for_freq(pdev,
304 								 dfs_chan_freq,
305 								 dfs_cfreq2,
306 								 dfs_ch_flags,
307 								 &cac_timeout);
308 
309 	return cac_timeout;
310 }
311 #endif
312 
313 #if defined(WLAN_DFS_PARTIAL_OFFLOAD) && defined(HOST_DFS_SPOOF_TEST)
dfs_mlme_rebuild_chan_list_with_non_dfs_channels(struct wlan_objmgr_pdev * pdev)314 int dfs_mlme_rebuild_chan_list_with_non_dfs_channels(
315 		struct wlan_objmgr_pdev *pdev)
316 {
317 	if (!global_dfs_to_mlme.mlme_rebuild_chan_list_with_non_dfs_channels)
318 		return 1;
319 
320 	return global_dfs_to_mlme.mlme_rebuild_chan_list_with_non_dfs_channels(
321 			pdev);
322 }
323 
dfs_mlme_restart_vaps_with_non_dfs_chan(struct wlan_objmgr_pdev * pdev,int no_chans_avail)324 void dfs_mlme_restart_vaps_with_non_dfs_chan(struct wlan_objmgr_pdev *pdev,
325 					     int no_chans_avail)
326 {
327 	if (!global_dfs_to_mlme.mlme_restart_vaps_with_non_dfs_chan)
328 		return;
329 
330 	global_dfs_to_mlme.mlme_restart_vaps_with_non_dfs_chan(pdev,
331 							       no_chans_avail);
332 }
333 #endif
334 
335 #if defined(WLAN_SUPPORT_PRIMARY_ALLOWED_CHAN)
dfs_mlme_check_allowed_prim_chanlist(struct wlan_objmgr_pdev * pdev,uint32_t chan_freq)336 bool dfs_mlme_check_allowed_prim_chanlist(struct wlan_objmgr_pdev *pdev,
337 					  uint32_t chan_freq)
338 {
339 	if (!global_dfs_to_mlme.mlme_check_allowed_prim_chanlist)
340 		return true;
341 
342 	return global_dfs_to_mlme.mlme_check_allowed_prim_chanlist(pdev,
343 								   chan_freq);
344 }
345 
346 #endif
347 
348 #if defined(WLAN_DFS_FULL_OFFLOAD) && defined(QCA_DFS_NOL_OFFLOAD)
dfs_mlme_handle_dfs_scan_violation(struct wlan_objmgr_pdev * pdev)349 void dfs_mlme_handle_dfs_scan_violation(struct wlan_objmgr_pdev *pdev)
350 {
351 	bool dfs_enable = 0;
352 
353 	/*Disable all DFS channels in master channel list and ic channel list */
354 	ucfg_reg_enable_dfs_channels(pdev, dfs_enable);
355 
356 	/* send the updated channel list to FW */
357 	global_dfs_to_mlme.mlme_update_scan_channel_list(pdev);
358 }
359 #endif
360 
dfs_mlme_is_inter_band_chan_switch_allowed(struct wlan_objmgr_pdev * pdev)361 bool dfs_mlme_is_inter_band_chan_switch_allowed(struct wlan_objmgr_pdev *pdev)
362 {
363 	if (!global_dfs_to_mlme.mlme_is_inter_band_chan_switch_allowed)
364 		return false;
365 
366 	return global_dfs_to_mlme.mlme_is_inter_band_chan_switch_allowed(pdev);
367 }
368 
dfs_mlme_is_opmode_sta(struct wlan_objmgr_pdev * pdev)369 bool dfs_mlme_is_opmode_sta(struct wlan_objmgr_pdev *pdev)
370 {
371 	if (!global_dfs_to_mlme.mlme_is_opmode_sta)
372 		return false;
373 
374 	return global_dfs_to_mlme.mlme_is_opmode_sta(pdev);
375 }
376