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