xref: /wlan-dirver/qca-wifi-host-cmn/umac/mlme/vdev_mgr/dispatcher/src/wlan_vdev_mlme_api.c (revision d0c05845839e5f2ba5a8dcebe0cd3e4cd4e8dfcf)
1 /*
2  * Copyright (c) 2018-2019, 2021 The Linux Foundation. All rights reserved.
3  * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
4  *
5  * Permission to use, copy, modify, and/or distribute this software for any
6  * purpose with or without fee is hereby granted, provided that the above
7  * copyright notice and this permission notice appear in all copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16  */
17 
18 /**
19  * DOC: Implements VDEV MLME public APIs
20  */
21 
22 #include <wlan_objmgr_vdev_obj.h>
23 #include <wlan_mlme_dbg.h>
24 #include "include/wlan_vdev_mlme.h"
25 #include "../../core/src/vdev_mlme_sm.h"
26 #include <wlan_vdev_mlme_api.h>
27 #include <include/wlan_mlme_cmn.h>
28 #include <qdf_module.h>
29 
30 struct vdev_mlme_obj *wlan_vdev_mlme_get_cmpt_obj(struct wlan_objmgr_vdev *vdev)
31 {
32 	struct vdev_mlme_obj *vdev_mlme;
33 
34 	if (!vdev) {
35 		mlme_err("vdev is NULL");
36 		return NULL;
37 	}
38 
39 	vdev_mlme = wlan_objmgr_vdev_get_comp_private_obj(vdev,
40 							  WLAN_UMAC_COMP_MLME);
41 	if (!vdev_mlme) {
42 		mlme_err(" MLME component object is NULL");
43 		return NULL;
44 	}
45 
46 	return vdev_mlme;
47 }
48 
49 qdf_export_symbol(wlan_vdev_mlme_get_cmpt_obj);
50 
51 void wlan_vdev_mlme_set_ext_hdl(struct wlan_objmgr_vdev *vdev,
52 				mlme_vdev_ext_t *ext_hdl)
53 {
54 	struct vdev_mlme_obj *vdev_mlme;
55 
56 	if (!ext_hdl) {
57 		mlme_err("Invalid input");
58 		return;
59 	}
60 
61 	vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev);
62 	if (vdev_mlme)
63 		vdev_mlme->ext_vdev_ptr = ext_hdl;
64 }
65 
66 qdf_export_symbol(wlan_vdev_mlme_set_ext_hdl);
67 
68 mlme_vdev_ext_t *wlan_vdev_mlme_get_ext_hdl(struct wlan_objmgr_vdev *vdev)
69 {
70 	struct vdev_mlme_obj *vdev_mlme;
71 
72 	vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev);
73 	if (vdev_mlme)
74 		return vdev_mlme->ext_vdev_ptr;
75 
76 	return NULL;
77 }
78 
79 qdf_export_symbol(wlan_vdev_mlme_get_ext_hdl);
80 
81 QDF_STATUS wlan_vdev_mlme_sm_deliver_evt(struct wlan_objmgr_vdev *vdev,
82 					 enum wlan_vdev_sm_evt event,
83 					 uint16_t event_data_len,
84 					 void *event_data)
85 {
86 	struct vdev_mlme_obj *vdev_mlme;
87 	QDF_STATUS status;
88 	enum wlan_vdev_state state_entry, state_exit;
89 	enum wlan_vdev_state substate_entry, substate_exit;
90 
91 	vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev);
92 	if (!vdev_mlme) {
93 		mlme_err("vdev component object is NULL");
94 		return QDF_STATUS_E_FAILURE;
95 	}
96 
97 	mlme_vdev_sm_spin_lock(vdev_mlme);
98 
99 	/* store entry state and sub state for prints */
100 	state_entry = wlan_vdev_mlme_get_state(vdev);
101 	substate_entry = wlan_vdev_mlme_get_substate(vdev);
102 	mlme_vdev_sm_print_state_event(vdev_mlme, event);
103 
104 	status = mlme_vdev_sm_deliver_event(vdev_mlme, event, event_data_len,
105 					    event_data);
106 	/* Take exit state, exit substate for prints */
107 	state_exit = wlan_vdev_mlme_get_state(vdev);
108 	substate_exit = wlan_vdev_mlme_get_substate(vdev);
109 	/* If no state and substate change, don't print */
110 	if (!((state_entry == state_exit) && (substate_entry == substate_exit)))
111 		mlme_vdev_sm_print_state(vdev_mlme);
112 	mlme_vdev_sm_spin_unlock(vdev_mlme);
113 
114 	return status;
115 }
116 
117 qdf_export_symbol(wlan_vdev_mlme_sm_deliver_evt);
118 
119 QDF_STATUS wlan_vdev_mlme_sm_deliver_evt_sync(struct wlan_objmgr_vdev *vdev,
120 					      enum wlan_vdev_sm_evt event,
121 					      uint16_t event_data_len,
122 					      void *event_data)
123 {
124 	struct vdev_mlme_obj *vdev_mlme;
125 	QDF_STATUS status;
126 
127 	vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev);
128 	if (!vdev_mlme) {
129 		mlme_err("vdev component object is NULL");
130 		return QDF_STATUS_E_FAILURE;
131 	}
132 
133 	status = mlme_vdev_sm_deliver_event(vdev_mlme, event, event_data_len,
134 					    event_data);
135 
136 	return status;
137 }
138 
139 qdf_export_symbol(wlan_vdev_mlme_sm_deliver_evt_sync);
140 
141 #ifdef SM_ENG_HIST_ENABLE
142 void wlan_vdev_mlme_sm_history_print(struct wlan_objmgr_vdev *vdev)
143 {
144 	struct vdev_mlme_obj *vdev_mlme;
145 
146 	vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev);
147 	if (!vdev_mlme) {
148 		mlme_err("vdev component object is NULL");
149 		return;
150 	}
151 
152 	mlme_vdev_sm_history_print(vdev_mlme);
153 }
154 #endif
155 
156 QDF_STATUS wlan_vdev_allow_connect_n_tx(struct wlan_objmgr_vdev *vdev)
157 {
158 	enum wlan_vdev_state state;
159 	enum wlan_vdev_state substate;
160 
161 	state = wlan_vdev_mlme_get_state(vdev);
162 	substate = wlan_vdev_mlme_get_substate(vdev);
163 	if ((state == WLAN_VDEV_S_UP && substate == WLAN_VDEV_SS_UP_ACTIVE) ||
164 	    ((state == WLAN_VDEV_S_SUSPEND) &&
165 	     (substate == WLAN_VDEV_SS_SUSPEND_CSA_RESTART)))
166 		return QDF_STATUS_SUCCESS;
167 
168 	return QDF_STATUS_E_FAILURE;
169 }
170 
171 QDF_STATUS wlan_vdev_mlme_is_active(struct wlan_objmgr_vdev *vdev)
172 {
173 	enum wlan_vdev_state state;
174 
175 	state = wlan_vdev_mlme_get_state(vdev);
176 	if ((state == WLAN_VDEV_S_UP) ||  (state == WLAN_VDEV_S_DFS_CAC_WAIT) ||
177 	    (state == WLAN_VDEV_S_SUSPEND))
178 		return QDF_STATUS_SUCCESS;
179 
180 	return QDF_STATUS_E_FAILURE;
181 }
182 
183 qdf_export_symbol(wlan_vdev_mlme_is_active);
184 
185 QDF_STATUS wlan_vdev_chan_config_valid(struct wlan_objmgr_vdev *vdev)
186 {
187 	enum wlan_vdev_state state;
188 	enum wlan_vdev_state substate;
189 
190 	state = wlan_vdev_mlme_get_state(vdev);
191 	substate = wlan_vdev_mlme_get_substate(vdev);
192 	if (!((state == WLAN_VDEV_S_INIT) || (state == WLAN_VDEV_S_STOP)))
193 		return QDF_STATUS_SUCCESS;
194 
195 	return QDF_STATUS_E_FAILURE;
196 }
197 
198 qdf_export_symbol(wlan_vdev_chan_config_valid);
199 
200 QDF_STATUS wlan_vdev_mlme_is_csa_restart(struct wlan_objmgr_vdev *vdev)
201 {
202 	enum wlan_vdev_state state;
203 	enum wlan_vdev_state substate;
204 
205 	state = wlan_vdev_mlme_get_state(vdev);
206 	substate = wlan_vdev_mlme_get_substate(vdev);
207 	if ((state == WLAN_VDEV_S_SUSPEND) &&
208 	    (substate == WLAN_VDEV_SS_SUSPEND_CSA_RESTART))
209 		return QDF_STATUS_SUCCESS;
210 
211 	return QDF_STATUS_E_FAILURE;
212 }
213 
214 qdf_export_symbol(wlan_vdev_mlme_is_csa_restart);
215 
216 QDF_STATUS wlan_vdev_is_going_down(struct wlan_objmgr_vdev *vdev)
217 {
218 	enum wlan_vdev_state state;
219 	enum wlan_vdev_state substate;
220 
221 	state = wlan_vdev_mlme_get_state(vdev);
222 	substate = wlan_vdev_mlme_get_substate(vdev);
223 	if ((state == WLAN_VDEV_S_STOP) ||
224 	    ((state == WLAN_VDEV_S_SUSPEND) &&
225 	     (substate == WLAN_VDEV_SS_SUSPEND_SUSPEND_DOWN)))
226 		return QDF_STATUS_SUCCESS;
227 
228 	return QDF_STATUS_E_FAILURE;
229 }
230 
231 QDF_STATUS wlan_vdev_is_mlo_peer_create_allowed(struct wlan_objmgr_vdev *vdev)
232 {
233 	enum wlan_vdev_state state;
234 	enum wlan_vdev_state substate;
235 	bool acs_in_progress;
236 	QDF_STATUS ret;
237 
238 	if (!vdev) {
239 		mlme_err("vdev is null");
240 		return QDF_STATUS_E_FAILURE;
241 	}
242 
243 	state = wlan_vdev_mlme_get_state(vdev);
244 	substate = wlan_vdev_mlme_get_substate(vdev);
245 
246 	acs_in_progress = false;
247 	ret = mlme_ext_hdl_get_acs_in_progress(vdev, &acs_in_progress);
248 	if (ret != QDF_STATUS_SUCCESS) {
249 		mlme_err("Unable to get ACS in progress status");
250 		return QDF_STATUS_E_FAILURE;
251 	}
252 
253 	if (!acs_in_progress)
254 		if ((state == WLAN_VDEV_S_UP) ||
255 		    ((state == WLAN_VDEV_S_SUSPEND) &&
256 		     (substate == WLAN_VDEV_SS_SUSPEND_CSA_RESTART)) ||
257 		    (state == WLAN_VDEV_S_DFS_CAC_WAIT))
258 			return QDF_STATUS_SUCCESS;
259 
260 	return QDF_STATUS_E_FAILURE;
261 }
262 
263 QDF_STATUS wlan_vdev_is_restart_progress(struct wlan_objmgr_vdev *vdev)
264 {
265 	enum wlan_vdev_state state;
266 	enum wlan_vdev_state substate;
267 
268 	state = wlan_vdev_mlme_get_state(vdev);
269 	substate = wlan_vdev_mlme_get_substate(vdev);
270 	if ((state == WLAN_VDEV_S_START) &&
271 	    (substate == WLAN_VDEV_SS_START_RESTART_PROGRESS))
272 		return QDF_STATUS_SUCCESS;
273 
274 	return QDF_STATUS_E_FAILURE;
275 }
276 
277 QDF_STATUS wlan_vdev_is_dfs_cac_wait(struct wlan_objmgr_vdev *vdev)
278 {
279 	if (wlan_vdev_mlme_get_state(vdev) == WLAN_VDEV_S_DFS_CAC_WAIT)
280 		return QDF_STATUS_SUCCESS;
281 
282 	return QDF_STATUS_E_FAILURE;
283 }
284 
285 void wlan_vdev_mlme_cmd_lock(struct wlan_objmgr_vdev *vdev)
286 {
287 	struct vdev_mlme_obj *vdev_mlme;
288 
289 	vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev);
290 	if (!vdev_mlme) {
291 		mlme_err("vdev component object is NULL");
292 		return;
293 	}
294 
295 	mlme_vdev_cmd_mutex_acquire(vdev_mlme);
296 }
297 
298 void wlan_vdev_mlme_cmd_unlock(struct wlan_objmgr_vdev *vdev)
299 {
300 	struct vdev_mlme_obj *vdev_mlme;
301 
302 	vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev);
303 	if (!vdev_mlme) {
304 		mlme_err("vdev component object is NULL");
305 		return;
306 	}
307 
308 	mlme_vdev_cmd_mutex_release(vdev_mlme);
309 }
310 
311 QDF_STATUS wlan_vdev_mlme_is_scan_allowed(struct wlan_objmgr_vdev *vdev)
312 {
313 	enum wlan_vdev_state state;
314 	enum wlan_vdev_state substate;
315 
316 	state = wlan_vdev_mlme_get_state(vdev);
317 	substate = wlan_vdev_mlme_get_substate(vdev);
318 	if ((state == WLAN_VDEV_S_INIT) ||
319 	    (state == WLAN_VDEV_S_UP && substate == WLAN_VDEV_SS_UP_ACTIVE) ||
320 	    (state == WLAN_VDEV_S_STOP))
321 		return QDF_STATUS_SUCCESS;
322 
323 	return QDF_STATUS_E_FAILURE;
324 }
325 
326 QDF_STATUS wlan_vdev_mlme_is_init_state(struct wlan_objmgr_vdev *vdev)
327 {
328 	enum wlan_vdev_state state;
329 
330 	state = wlan_vdev_mlme_get_state(vdev);
331 	if (state == WLAN_VDEV_S_INIT)
332 		return QDF_STATUS_SUCCESS;
333 
334 	return QDF_STATUS_E_FAILURE;
335 }
336 
337 QDF_STATUS wlan_vdev_is_up_active_state(struct wlan_objmgr_vdev *vdev)
338 {
339 	enum wlan_vdev_state state;
340 	enum wlan_vdev_state substate;
341 
342 	state = wlan_vdev_mlme_get_state(vdev);
343 	substate = wlan_vdev_mlme_get_substate(vdev);
344 	if (state == WLAN_VDEV_S_UP && substate == WLAN_VDEV_SS_UP_ACTIVE)
345 		return QDF_STATUS_SUCCESS;
346 
347 	return QDF_STATUS_E_FAILURE;
348 }
349 
350 qdf_export_symbol(wlan_vdev_is_up_active_state);
351 
352 #ifdef WLAN_FEATURE_11BE_MLO
353 bool
354 wlan_vdev_mlme_get_is_mlo_link(struct wlan_objmgr_psoc *psoc,
355 			       uint8_t vdev_id)
356 {
357 	struct wlan_objmgr_vdev *vdev;
358 	bool is_link = false;
359 
360 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
361 						    WLAN_MLME_OBJMGR_ID);
362 	if (!vdev) {
363 		mlme_err("vdev object is NULL for vdev %d", vdev_id);
364 		return is_link;
365 	}
366 
367 	if (wlan_vdev_mlme_is_mlo_vdev(vdev) &&
368 	    wlan_vdev_mlme_is_mlo_link_vdev(vdev))
369 		is_link = true;
370 
371 	wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_OBJMGR_ID);
372 
373 	return is_link;
374 }
375 
376 bool
377 wlan_vdev_mlme_get_is_mlo_vdev(struct wlan_objmgr_psoc *psoc,
378 			       uint8_t vdev_id)
379 {
380 	struct wlan_objmgr_vdev *vdev;
381 	bool is_mlo_vdev = false;
382 
383 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
384 						    WLAN_MLME_OBJMGR_ID);
385 	if (!vdev) {
386 		mlme_err("vdev object is NULL for vdev %d", vdev_id);
387 		return is_mlo_vdev;
388 	}
389 
390 	if (wlan_vdev_mlme_is_mlo_vdev(vdev) &&
391 	    !wlan_vdev_mlme_is_mlo_link_vdev(vdev))
392 		is_mlo_vdev = true;
393 
394 	wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_OBJMGR_ID);
395 
396 	return is_mlo_vdev;
397 }
398 #endif
399