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