xref: /wlan-dirver/qca-wifi-host-cmn/umac/mlme/mlme_objmgr/dispatcher/src/wlan_vdev_mlme_main.c (revision 8ddef7dd9a290d4a9b1efd5d3efacf51d78a1a0d)
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 
34 static QDF_STATUS mlme_vdev_obj_create_handler(struct wlan_objmgr_vdev *vdev,
35 					       void *arg)
36 {
37 	struct vdev_mlme_obj *vdev_mlme;
38 	struct wlan_objmgr_pdev *pdev;
39 	struct pdev_mlme_obj *pdev_mlme;
40 
41 	if (!vdev) {
42 		mlme_err(" VDEV is NULL");
43 		return QDF_STATUS_E_FAILURE;
44 	}
45 
46 	pdev = wlan_vdev_get_pdev(vdev);
47 	if (!pdev) {
48 		mlme_err(" PDEV is NULL");
49 		return QDF_STATUS_E_FAILURE;
50 	}
51 
52 	pdev_mlme = wlan_pdev_mlme_get_cmpt_obj(pdev);
53 	if (!pdev_mlme) {
54 		mlme_err(" PDEV MLME is NULL");
55 		return QDF_STATUS_E_FAILURE;
56 	}
57 
58 	vdev_mlme = qdf_mem_malloc(sizeof(*vdev_mlme));
59 	if (!vdev_mlme) {
60 		mlme_err(" MLME component object alloc failed");
61 		return QDF_STATUS_E_NOMEM;
62 	}
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 	if (mlme_vdev_ops_ext_hdl_post_create(vdev_mlme) !=
88 						QDF_STATUS_SUCCESS) {
89 		mlme_err("Legacy vdev object post creation failed");
90 		goto ext_hdl_post_create_failed;
91 	}
92 
93 	return QDF_STATUS_SUCCESS;
94 
95 ext_hdl_post_create_failed:
96 	mlme_vdev_ops_ext_hdl_destroy(vdev_mlme);
97 	wlan_objmgr_vdev_component_obj_detach(vdev, WLAN_UMAC_COMP_MLME,
98 					      vdev_mlme);
99 ext_hdl_create_failed:
100 	mlme_vdev_sm_destroy(vdev_mlme);
101 init_failed:
102 	qdf_mem_free(vdev_mlme);
103 
104 	return QDF_STATUS_E_FAILURE;
105 }
106 
107 static QDF_STATUS mlme_vdev_obj_destroy_handler(struct wlan_objmgr_vdev *vdev,
108 						void *arg)
109 {
110 	struct vdev_mlme_obj *vdev_mlme;
111 
112 	if (!vdev) {
113 		mlme_err(" VDEV is NULL");
114 		return QDF_STATUS_E_FAILURE;
115 	}
116 
117 	vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev);
118 	if (!vdev_mlme) {
119 		mlme_info(" VDEV MLME component object is NULL");
120 		return QDF_STATUS_SUCCESS;
121 	}
122 
123 	mlme_vdev_sm_destroy(vdev_mlme);
124 
125 	mlme_vdev_ops_ext_hdl_destroy(vdev_mlme);
126 
127 	wlan_objmgr_vdev_component_obj_detach(vdev, WLAN_UMAC_COMP_MLME,
128 					      vdev_mlme);
129 	qdf_mem_free(vdev_mlme);
130 
131 	return QDF_STATUS_SUCCESS;
132 }
133 
134 static void mlme_scan_serialization_comp_info_cb(
135 		struct wlan_objmgr_vdev *vdev,
136 		union wlan_serialization_rules_info *comp_info)
137 {
138 	struct wlan_objmgr_pdev *pdev;
139 	QDF_STATUS status;
140 
141 	if (!comp_info || !vdev) {
142 		mlme_err("comp_info or vdev is NULL");
143 		return;
144 	}
145 
146 	pdev = wlan_vdev_get_pdev(vdev);
147 	if (!pdev) {
148 		mlme_err("pdev is NULL");
149 		return;
150 	}
151 
152 	comp_info->scan_info.is_mlme_op_in_progress = false;
153 
154 	status = wlan_util_is_pdev_scan_allowed(pdev, WLAN_MLME_SER_IF_ID);
155 	if (status != QDF_STATUS_SUCCESS)
156 		comp_info->scan_info.is_mlme_op_in_progress = true;
157 }
158 
159 QDF_STATUS wlan_mlme_psoc_enable(struct wlan_objmgr_psoc *psoc)
160 {
161 	QDF_STATUS status;
162 	struct wlan_lmac_if_mlme_tx_ops *tx_ops;
163 
164 	status = wlan_serialization_register_comp_info_cb
165 			(psoc,
166 			 WLAN_UMAC_COMP_MLME,
167 			 WLAN_SER_CMD_SCAN,
168 			 mlme_scan_serialization_comp_info_cb);
169 	if (status != QDF_STATUS_SUCCESS) {
170 		mlme_err("Serialize scan cmd register failed");
171 		return status;
172 	}
173 
174 	/* Register for WMI events into target_if rx  */
175 	tx_ops = wlan_mlme_get_lmac_tx_ops(psoc);
176 	if (tx_ops && tx_ops->vdev_mlme_attach)
177 		tx_ops->vdev_mlme_attach(psoc);
178 
179 	return QDF_STATUS_SUCCESS;
180 }
181 
182 QDF_STATUS wlan_mlme_psoc_disable(struct wlan_objmgr_psoc *psoc)
183 {
184 	QDF_STATUS status;
185 	struct wlan_lmac_if_mlme_tx_ops *tx_ops;
186 
187 	status = wlan_serialization_deregister_comp_info_cb
188 						(psoc,
189 						 WLAN_UMAC_COMP_MLME,
190 						 WLAN_SER_CMD_SCAN);
191 	if (status != QDF_STATUS_SUCCESS) {
192 		mlme_err("Serialize scan cmd deregister failed");
193 		return status;
194 	}
195 
196 	/* Unregister WMI events  */
197 	tx_ops = wlan_mlme_get_lmac_tx_ops(psoc);
198 	if (tx_ops && tx_ops->vdev_mlme_detach)
199 		tx_ops->vdev_mlme_detach(psoc);
200 
201 	return QDF_STATUS_SUCCESS;
202 }
203 
204 QDF_STATUS wlan_vdev_mlme_init(void)
205 {
206 	if (wlan_objmgr_register_vdev_create_handler
207 				(WLAN_UMAC_COMP_MLME,
208 				 mlme_vdev_obj_create_handler, NULL)
209 						!= QDF_STATUS_SUCCESS)
210 		return QDF_STATUS_E_FAILURE;
211 
212 	if (wlan_objmgr_register_vdev_destroy_handler
213 				(WLAN_UMAC_COMP_MLME,
214 				 mlme_vdev_obj_destroy_handler, NULL)
215 						!= QDF_STATUS_SUCCESS) {
216 		if (wlan_objmgr_unregister_vdev_create_handler
217 					(WLAN_UMAC_COMP_MLME,
218 					 mlme_vdev_obj_create_handler, NULL)
219 						!= QDF_STATUS_SUCCESS)
220 			return QDF_STATUS_E_FAILURE;
221 
222 		return QDF_STATUS_E_FAILURE;
223 	}
224 
225 	return QDF_STATUS_SUCCESS;
226 }
227 
228 QDF_STATUS wlan_vdev_mlme_deinit(void)
229 {
230 	if (wlan_objmgr_unregister_vdev_create_handler
231 				(WLAN_UMAC_COMP_MLME,
232 				 mlme_vdev_obj_create_handler, NULL)
233 					!= QDF_STATUS_SUCCESS)
234 		return QDF_STATUS_E_FAILURE;
235 
236 	if (wlan_objmgr_unregister_vdev_destroy_handler
237 				(WLAN_UMAC_COMP_MLME,
238 				 mlme_vdev_obj_destroy_handler, NULL)
239 						!= QDF_STATUS_SUCCESS)
240 		return QDF_STATUS_E_FAILURE;
241 
242 	return QDF_STATUS_SUCCESS;
243 }
244