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