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