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