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