xref: /wlan-dirver/qca-wifi-host-cmn/umac/mlme/vdev_mgr/dispatcher/src/wlan_vdev_mlme_api.c (revision dd4dc88b837a295134aa9869114a2efee0f4894b)
1 /*
2  * Copyright (c) 2018-2019 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, void *ext_hdl)
50 {
51 	struct vdev_mlme_obj *vdev_mlme;
52 
53 	if (!ext_hdl) {
54 		mlme_err("Invalid input");
55 		return;
56 	}
57 
58 	vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev);
59 	if (vdev_mlme)
60 		vdev_mlme->ext_vdev_ptr = ext_hdl;
61 }
62 
63 qdf_export_symbol(wlan_vdev_mlme_set_ext_hdl);
64 
65 void *wlan_vdev_mlme_get_ext_hdl(struct wlan_objmgr_vdev *vdev)
66 {
67 	struct vdev_mlme_obj *vdev_mlme;
68 
69 	vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev);
70 	if (vdev_mlme)
71 		return vdev_mlme->ext_vdev_ptr;
72 
73 	return NULL;
74 }
75 
76 qdf_export_symbol(wlan_vdev_mlme_get_ext_hdl);
77 
78 QDF_STATUS wlan_vdev_mlme_sm_deliver_evt(struct wlan_objmgr_vdev *vdev,
79 					 enum wlan_vdev_sm_evt event,
80 					 uint16_t event_data_len,
81 					 void *event_data)
82 {
83 	struct vdev_mlme_obj *vdev_mlme;
84 	QDF_STATUS status;
85 	enum wlan_vdev_state state_entry, state_exit;
86 	enum wlan_vdev_state substate_entry, substate_exit;
87 
88 	vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev);
89 	if (!vdev_mlme) {
90 		mlme_err("vdev component object is NULL");
91 		return QDF_STATUS_E_FAILURE;
92 	}
93 
94 	mlme_vdev_sm_spin_lock(vdev_mlme);
95 
96 	/* store entry state and sub state for prints */
97 	state_entry = wlan_vdev_mlme_get_state(vdev);
98 	substate_entry = wlan_vdev_mlme_get_substate(vdev);
99 	mlme_vdev_sm_print_state_event(vdev_mlme, event);
100 
101 	status = mlme_vdev_sm_deliver_event(vdev_mlme, event, event_data_len,
102 					    event_data);
103 	/* Take exit state, exit substate for prints */
104 	state_exit = wlan_vdev_mlme_get_state(vdev);
105 	substate_exit = wlan_vdev_mlme_get_substate(vdev);
106 	/* If no state and substate change, don't print */
107 	if (!((state_entry == state_exit) && (substate_entry == substate_exit)))
108 		mlme_vdev_sm_print_state(vdev_mlme);
109 	mlme_vdev_sm_spin_unlock(vdev_mlme);
110 
111 	return status;
112 }
113 
114 qdf_export_symbol(wlan_vdev_mlme_sm_deliver_evt);
115 
116 QDF_STATUS wlan_vdev_mlme_sm_deliver_evt_sync(struct wlan_objmgr_vdev *vdev,
117 					      enum wlan_vdev_sm_evt event,
118 					      uint16_t event_data_len,
119 					      void *event_data)
120 {
121 	struct vdev_mlme_obj *vdev_mlme;
122 	QDF_STATUS status;
123 
124 	vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev);
125 	if (!vdev_mlme) {
126 		mlme_err("vdev component object is NULL");
127 		return QDF_STATUS_E_FAILURE;
128 	}
129 
130 	status = mlme_vdev_sm_deliver_event(vdev_mlme, event, event_data_len,
131 					    event_data);
132 
133 	return status;
134 }
135 
136 qdf_export_symbol(wlan_vdev_mlme_sm_deliver_evt_sync);
137 
138 #ifdef SM_ENG_HIST_ENABLE
139 void wlan_vdev_mlme_sm_history_print(struct wlan_objmgr_vdev *vdev)
140 {
141 	struct vdev_mlme_obj *vdev_mlme;
142 
143 	vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev);
144 	if (!vdev_mlme) {
145 		mlme_err("vdev component object is NULL");
146 		return;
147 	}
148 
149 	mlme_vdev_sm_history_print(vdev_mlme);
150 }
151 #endif
152 
153 QDF_STATUS wlan_vdev_allow_connect_n_tx(struct wlan_objmgr_vdev *vdev)
154 {
155 	enum wlan_vdev_state state;
156 	enum wlan_vdev_state substate;
157 
158 	state = wlan_vdev_mlme_get_state(vdev);
159 	substate = wlan_vdev_mlme_get_substate(vdev);
160 	if ((state == WLAN_VDEV_S_UP) ||
161 	    ((state == WLAN_VDEV_S_SUSPEND) &&
162 	     (substate == WLAN_VDEV_SS_SUSPEND_CSA_RESTART)))
163 		return QDF_STATUS_SUCCESS;
164 
165 	return QDF_STATUS_E_FAILURE;
166 }
167 
168 QDF_STATUS wlan_vdev_mlme_is_active(struct wlan_objmgr_vdev *vdev)
169 {
170 	enum wlan_vdev_state state;
171 
172 	state = wlan_vdev_mlme_get_state(vdev);
173 	if ((state == WLAN_VDEV_S_UP) ||  (state == WLAN_VDEV_S_DFS_CAC_WAIT) ||
174 	    (state == WLAN_VDEV_S_SUSPEND))
175 		return QDF_STATUS_SUCCESS;
176 
177 	return QDF_STATUS_E_FAILURE;
178 }
179 
180 qdf_export_symbol(wlan_vdev_mlme_is_active);
181 
182 QDF_STATUS wlan_vdev_chan_config_valid(struct wlan_objmgr_vdev *vdev)
183 {
184 	enum wlan_vdev_state state;
185 	enum wlan_vdev_state substate;
186 
187 	state = wlan_vdev_mlme_get_state(vdev);
188 	substate = wlan_vdev_mlme_get_substate(vdev);
189 	if (!((state == WLAN_VDEV_S_INIT) || (state == WLAN_VDEV_S_STOP)))
190 		return QDF_STATUS_SUCCESS;
191 
192 	return QDF_STATUS_E_FAILURE;
193 }
194 
195 qdf_export_symbol(wlan_vdev_chan_config_valid);
196 
197 QDF_STATUS wlan_vdev_mlme_is_csa_restart(struct wlan_objmgr_vdev *vdev)
198 {
199 	enum wlan_vdev_state state;
200 	enum wlan_vdev_state substate;
201 
202 	state = wlan_vdev_mlme_get_state(vdev);
203 	substate = wlan_vdev_mlme_get_substate(vdev);
204 	if ((state == WLAN_VDEV_S_SUSPEND) &&
205 	    (substate == WLAN_VDEV_SS_SUSPEND_CSA_RESTART))
206 		return QDF_STATUS_SUCCESS;
207 
208 	return QDF_STATUS_E_FAILURE;
209 }
210 
211 QDF_STATUS wlan_vdev_is_going_down(struct wlan_objmgr_vdev *vdev)
212 {
213 	enum wlan_vdev_state state;
214 	enum wlan_vdev_state substate;
215 
216 	state = wlan_vdev_mlme_get_state(vdev);
217 	substate = wlan_vdev_mlme_get_substate(vdev);
218 	if ((state == WLAN_VDEV_S_STOP) ||
219 	    ((state == WLAN_VDEV_S_SUSPEND) &&
220 	     (substate == WLAN_VDEV_SS_SUSPEND_SUSPEND_DOWN)))
221 		return QDF_STATUS_SUCCESS;
222 
223 	return QDF_STATUS_E_FAILURE;
224 }
225 
226 QDF_STATUS wlan_vdev_is_restart_progress(struct wlan_objmgr_vdev *vdev)
227 {
228 	enum wlan_vdev_state state;
229 	enum wlan_vdev_state substate;
230 
231 	state = wlan_vdev_mlme_get_state(vdev);
232 	substate = wlan_vdev_mlme_get_substate(vdev);
233 	if ((state == WLAN_VDEV_S_START) &&
234 	    (substate == WLAN_VDEV_SS_START_RESTART_PROGRESS))
235 		return QDF_STATUS_SUCCESS;
236 
237 	return QDF_STATUS_E_FAILURE;
238 }
239 
240 QDF_STATUS wlan_vdev_is_dfs_cac_wait(struct wlan_objmgr_vdev *vdev)
241 {
242 	if (wlan_vdev_mlme_get_state(vdev) == WLAN_VDEV_S_DFS_CAC_WAIT)
243 		return QDF_STATUS_SUCCESS;
244 
245 	return QDF_STATUS_E_FAILURE;
246 }
247 
248 void wlan_vdev_mlme_cmd_lock(struct wlan_objmgr_vdev *vdev)
249 {
250 	struct vdev_mlme_obj *vdev_mlme;
251 
252 	vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev);
253 	if (!vdev_mlme) {
254 		mlme_err("vdev component object is NULL");
255 		return;
256 	}
257 
258 	mlme_vdev_cmd_mutex_acquire(vdev_mlme);
259 }
260 
261 void wlan_vdev_mlme_cmd_unlock(struct wlan_objmgr_vdev *vdev)
262 {
263 	struct vdev_mlme_obj *vdev_mlme;
264 
265 	vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev);
266 	if (!vdev_mlme) {
267 		mlme_err("vdev component object is NULL");
268 		return;
269 	}
270 
271 	mlme_vdev_cmd_mutex_release(vdev_mlme);
272 }
273 
274 QDF_STATUS wlan_vdev_mlme_is_scan_allowed(struct wlan_objmgr_vdev *vdev)
275 {
276 	enum wlan_vdev_state state;
277 
278 	state = wlan_vdev_mlme_get_state(vdev);
279 	if ((state == WLAN_VDEV_S_INIT) ||  (state == WLAN_VDEV_S_UP) ||
280 	    (state == WLAN_VDEV_S_STOP))
281 		return QDF_STATUS_SUCCESS;
282 
283 	return QDF_STATUS_E_FAILURE;
284 }
285