xref: /wlan-dirver/qca-wifi-host-cmn/umac/mlme/mlme_objmgr/dispatcher/src/wlan_vdev_mlme_main.c (revision 2f4b444fb7e689b83a4ab0e7b3b38f0bf4def8e0)
1 /*
2  * Copyright (c) 2018-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 MLME component object creation/initialization/destroy
19  */
20 
21 #include <wlan_objmgr_cmn.h>
22 #include <wlan_objmgr_global_obj.h>
23 #include <wlan_objmgr_vdev_obj.h>
24 #include <wlan_mlme_dbg.h>
25 #include <include/wlan_mlme_cmn.h>
26 #include <include/wlan_vdev_mlme.h>
27 #include <include/wlan_pdev_mlme.h>
28 #include <vdev_mgr/core/src/vdev_mlme_sm.h>
29 #include <wlan_pdev_mlme_api.h>
30 #include <wlan_vdev_mlme_api.h>
31 #include <wlan_serialization_api.h>
32 #include <wlan_utility.h>
33 #include <cdp_txrx_cmn.h>
34 #include <wlan_lmac_if_def.h>
35 #include <target_if_vdev_mgr_tx_ops.h>
36 #include "connection_mgr/core/src/wlan_cm_main.h"
37 
38 static QDF_STATUS mlme_vdev_obj_create_handler(struct wlan_objmgr_vdev *vdev,
39 					       void *arg)
40 {
41 	struct vdev_mlme_obj *vdev_mlme;
42 	struct wlan_objmgr_pdev *pdev;
43 	struct wlan_objmgr_psoc *psoc;
44 	struct pdev_mlme_obj *pdev_mlme;
45 	struct wlan_lmac_if_mlme_tx_ops *txops;
46 	QDF_STATUS status;
47 
48 	if (!vdev) {
49 		mlme_err(" VDEV is NULL");
50 		return QDF_STATUS_E_FAILURE;
51 	}
52 
53 	pdev = wlan_vdev_get_pdev(vdev);
54 	if (!pdev) {
55 		mlme_err(" PDEV is NULL");
56 		return QDF_STATUS_E_FAILURE;
57 	}
58 
59 	/**
60 	 * 1st check whether for this vdev any vdev commands are pending for
61 	 * response.
62 	 */
63 	psoc = wlan_pdev_get_psoc(pdev);
64 	if (!psoc) {
65 		mlme_err("PSOC is NULL");
66 		return QDF_STATUS_E_FAILURE;
67 	}
68 
69 	txops = wlan_mlme_get_lmac_tx_ops(psoc);
70 	if (!txops || !txops->psoc_vdev_rsp_timer_inuse) {
71 		mlme_err("Failed to get mlme txrx_ops PSOC_%d",
72 			 wlan_psoc_get_id(psoc));
73 		return QDF_STATUS_E_FAILURE;
74 	}
75 
76 	status = txops->psoc_vdev_rsp_timer_inuse(psoc, wlan_vdev_get_id(vdev));
77 	if (QDF_IS_STATUS_ERROR(status)) {
78 		mlme_err("The vdev response is pending for VDEV_%d status:%d",
79 			 wlan_vdev_get_id(vdev), status);
80 		return QDF_STATUS_E_FAILURE;
81 	}
82 
83 	pdev_mlme = wlan_pdev_mlme_get_cmpt_obj(pdev);
84 	if (!pdev_mlme) {
85 		mlme_err("PDEV MLME is NULL");
86 		return QDF_STATUS_E_FAILURE;
87 	}
88 
89 	vdev_mlme = qdf_mem_malloc(sizeof(*vdev_mlme));
90 	if (!vdev_mlme)
91 		return QDF_STATUS_E_NOMEM;
92 	wlan_minidump_log(vdev_mlme, sizeof(*vdev_mlme), psoc,
93 			  WLAN_MD_OBJMGR_VDEV_MLME, "vdev_mlme");
94 
95 	vdev_mlme->vdev = vdev;
96 
97 	if (pdev_mlme->mlme_register_ops(vdev_mlme) != QDF_STATUS_SUCCESS) {
98 		mlme_err("Callbacks registration is failed");
99 		goto init_failed;
100 	}
101 
102 	if (mlme_vdev_sm_create(vdev_mlme) != QDF_STATUS_SUCCESS) {
103 		mlme_err("SME creation failed");
104 		goto init_failed;
105 	}
106 
107 	if (QDF_IS_STATUS_ERROR(wlan_cm_init(vdev_mlme))) {
108 		mlme_err("CM SM create failed");
109 		goto cm_sm_create_failed;
110 	}
111 
112 	if (mlme_vdev_ops_ext_hdl_create(vdev_mlme) !=
113 						QDF_STATUS_SUCCESS) {
114 		mlme_err("Legacy vdev object creation failed");
115 		goto ext_hdl_create_failed;
116 	}
117 
118 	wlan_objmgr_vdev_component_obj_attach((struct wlan_objmgr_vdev *)vdev,
119 					      WLAN_UMAC_COMP_MLME,
120 					      (void *)vdev_mlme,
121 					      QDF_STATUS_SUCCESS);
122 
123 	if (mlme_vdev_ops_ext_hdl_post_create(vdev_mlme) !=
124 						QDF_STATUS_SUCCESS) {
125 		mlme_err("Legacy vdev object post creation failed");
126 		goto ext_hdl_post_create_failed;
127 	}
128 
129 	return QDF_STATUS_SUCCESS;
130 
131 ext_hdl_post_create_failed:
132 	mlme_vdev_ops_ext_hdl_destroy(vdev_mlme);
133 	wlan_objmgr_vdev_component_obj_detach(vdev, WLAN_UMAC_COMP_MLME,
134 					      vdev_mlme);
135 ext_hdl_create_failed:
136 	wlan_cm_deinit(vdev_mlme);
137 cm_sm_create_failed:
138 	mlme_vdev_sm_destroy(vdev_mlme);
139 init_failed:
140 	wlan_minidump_remove(vdev_mlme, sizeof(*vdev_mlme), psoc,
141 			     WLAN_MD_OBJMGR_VDEV_MLME, "vdev_mlme");
142 
143 	qdf_mem_free(vdev_mlme);
144 	return QDF_STATUS_E_FAILURE;
145 }
146 
147 static QDF_STATUS mlme_vdev_obj_destroy_handler(struct wlan_objmgr_vdev *vdev,
148 						void *arg)
149 {
150 	struct vdev_mlme_obj *vdev_mlme;
151 
152 	if (!vdev) {
153 		mlme_err(" VDEV is NULL");
154 		return QDF_STATUS_E_FAILURE;
155 	}
156 
157 	vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev);
158 	if (!vdev_mlme) {
159 		mlme_info(" VDEV MLME component object is NULL");
160 		return QDF_STATUS_SUCCESS;
161 	}
162 
163 	wlan_cm_deinit(vdev_mlme);
164 	mlme_vdev_sm_destroy(vdev_mlme);
165 	mlme_vdev_ops_ext_hdl_destroy(vdev_mlme);
166 	wlan_objmgr_vdev_component_obj_detach(vdev, WLAN_UMAC_COMP_MLME,
167 					      vdev_mlme);
168 
169 	wlan_minidump_remove(vdev_mlme, sizeof(*vdev_mlme),
170 			     wlan_vdev_get_psoc(vdev),
171 			     WLAN_MD_OBJMGR_VDEV_MLME, "vdev_mlme");
172 
173 	qdf_mem_free(vdev_mlme);
174 
175 	return QDF_STATUS_SUCCESS;
176 }
177 
178 static void mlme_scan_serialization_comp_info_cb(
179 		struct wlan_objmgr_vdev *vdev,
180 		union wlan_serialization_rules_info *comp_info,
181 		struct wlan_serialization_command *cmd)
182 {
183 	struct wlan_objmgr_pdev *pdev;
184 	struct scan_start_request *scan_start_req = cmd->umac_cmd;
185 	QDF_STATUS status;
186 
187 	if (!comp_info || !vdev) {
188 		mlme_err("comp_info or vdev is NULL");
189 		return;
190 	}
191 
192 	pdev = wlan_vdev_get_pdev(vdev);
193 	if (!pdev) {
194 		mlme_err("pdev is NULL");
195 		return;
196 	}
197 
198 	if (!scan_start_req) {
199 		mlme_err("scan start request is null");
200 		return;
201 	}
202 
203 	comp_info->scan_info.is_scan_for_connect = false;
204 
205 	if (cmd->cmd_type == WLAN_SER_CMD_SCAN &&
206 	    scan_start_req->scan_req.scan_type == SCAN_TYPE_SCAN_FOR_CONNECT) {
207 		comp_info->scan_info.is_scan_for_connect = true;
208 	}
209 
210 	comp_info->scan_info.is_mlme_op_in_progress = false;
211 
212 	status = wlan_util_is_pdev_scan_allowed(pdev, WLAN_MLME_SER_IF_ID);
213 	if (status != QDF_STATUS_SUCCESS)
214 		comp_info->scan_info.is_mlme_op_in_progress = true;
215 }
216 
217 QDF_STATUS wlan_mlme_psoc_enable(struct wlan_objmgr_psoc *psoc)
218 {
219 	QDF_STATUS status;
220 	struct wlan_lmac_if_mlme_tx_ops *tx_ops;
221 
222 	status = wlan_serialization_register_comp_info_cb
223 			(psoc,
224 			 WLAN_UMAC_COMP_MLME,
225 			 WLAN_SER_CMD_SCAN,
226 			 mlme_scan_serialization_comp_info_cb);
227 	if (status != QDF_STATUS_SUCCESS) {
228 		mlme_err("Serialize scan cmd register failed");
229 		return status;
230 	}
231 
232 	/* Register for WMI events into target_if rx  */
233 	tx_ops = wlan_mlme_get_lmac_tx_ops(psoc);
234 	if (tx_ops && tx_ops->vdev_mlme_attach)
235 		tx_ops->vdev_mlme_attach(psoc);
236 
237 	return QDF_STATUS_SUCCESS;
238 }
239 
240 QDF_STATUS wlan_mlme_psoc_disable(struct wlan_objmgr_psoc *psoc)
241 {
242 	QDF_STATUS status;
243 	struct wlan_lmac_if_mlme_tx_ops *tx_ops;
244 
245 	status = wlan_serialization_deregister_comp_info_cb
246 						(psoc,
247 						 WLAN_UMAC_COMP_MLME,
248 						 WLAN_SER_CMD_SCAN);
249 	if (status != QDF_STATUS_SUCCESS) {
250 		mlme_err("Serialize scan cmd deregister failed");
251 		return status;
252 	}
253 
254 	/* Unregister WMI events  */
255 	tx_ops = wlan_mlme_get_lmac_tx_ops(psoc);
256 	if (tx_ops && tx_ops->vdev_mlme_detach)
257 		tx_ops->vdev_mlme_detach(psoc);
258 
259 	return QDF_STATUS_SUCCESS;
260 }
261 
262 QDF_STATUS wlan_vdev_mlme_init(void)
263 {
264 	if (wlan_objmgr_register_vdev_create_handler
265 				(WLAN_UMAC_COMP_MLME,
266 				 mlme_vdev_obj_create_handler, NULL)
267 						!= QDF_STATUS_SUCCESS)
268 		return QDF_STATUS_E_FAILURE;
269 
270 	if (wlan_objmgr_register_vdev_destroy_handler
271 				(WLAN_UMAC_COMP_MLME,
272 				 mlme_vdev_obj_destroy_handler, NULL)
273 						!= QDF_STATUS_SUCCESS) {
274 		if (wlan_objmgr_unregister_vdev_create_handler
275 					(WLAN_UMAC_COMP_MLME,
276 					 mlme_vdev_obj_create_handler, NULL)
277 						!= QDF_STATUS_SUCCESS)
278 			return QDF_STATUS_E_FAILURE;
279 
280 		return QDF_STATUS_E_FAILURE;
281 	}
282 
283 	return QDF_STATUS_SUCCESS;
284 }
285 
286 QDF_STATUS wlan_vdev_mlme_deinit(void)
287 {
288 	if (wlan_objmgr_unregister_vdev_create_handler
289 				(WLAN_UMAC_COMP_MLME,
290 				 mlme_vdev_obj_create_handler, NULL)
291 					!= QDF_STATUS_SUCCESS)
292 		return QDF_STATUS_E_FAILURE;
293 
294 	if (wlan_objmgr_unregister_vdev_destroy_handler
295 				(WLAN_UMAC_COMP_MLME,
296 				 mlme_vdev_obj_destroy_handler, NULL)
297 						!= QDF_STATUS_SUCCESS)
298 		return QDF_STATUS_E_FAILURE;
299 
300 	return QDF_STATUS_SUCCESS;
301 }
302