1 /*
2  * Copyright (c) 2023 Qualcomm Innovation Center, Inc. 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 #include "wlan_ll_sap_main.h"
18 #include <wlan_objmgr_global_obj.h>
19 #include "qca_vendor.h"
20 #include "wlan_ll_lt_sap_main.h"
21 #include "target_if_ll_sap.h"
22 
23 struct ll_sap_ops *global_ll_sap_ops;
24 
ll_sap_psoc_obj_created_notification(struct wlan_objmgr_psoc * psoc,void * arg_list)25 static QDF_STATUS ll_sap_psoc_obj_created_notification(struct wlan_objmgr_psoc *psoc, void *arg_list)
26 {
27 	QDF_STATUS status = QDF_STATUS_SUCCESS;
28 	struct ll_sap_psoc_priv_obj *ll_sap_psoc_obj;
29 
30 	ll_sap_psoc_obj = qdf_mem_malloc(sizeof(*ll_sap_psoc_obj));
31 	if (!ll_sap_psoc_obj)
32 		return QDF_STATUS_E_NOMEM;
33 
34 	status = wlan_objmgr_psoc_component_obj_attach(psoc,
35 						       WLAN_UMAC_COMP_LL_SAP,
36 						       ll_sap_psoc_obj,
37 						       QDF_STATUS_SUCCESS);
38 	if (QDF_IS_STATUS_ERROR(status)) {
39 		ll_sap_err("ll_sap obj attach with psoc failed");
40 		goto ll_sap_psoc_obj_fail;
41 	}
42 
43 	target_if_ll_sap_register_tx_ops(&ll_sap_psoc_obj->tx_ops);
44 	target_if_ll_sap_register_rx_ops(&ll_sap_psoc_obj->rx_ops);
45 
46 	ll_sap_debug("ll sap psoc object created");
47 
48 	return status;
49 
50 ll_sap_psoc_obj_fail:
51 	qdf_mem_free(ll_sap_psoc_obj);
52 
53 	return status;
54 }
55 
ll_sap_psoc_obj_destroyed_notification(struct wlan_objmgr_psoc * psoc,void * arg_list)56 static QDF_STATUS ll_sap_psoc_obj_destroyed_notification(struct wlan_objmgr_psoc *psoc, void *arg_list)
57 {
58 	QDF_STATUS status = QDF_STATUS_SUCCESS;
59 	struct ll_sap_psoc_priv_obj *ll_sap_psoc_obj;
60 
61 	ll_sap_psoc_obj =
62 		wlan_objmgr_psoc_get_comp_private_obj(psoc,
63 						      WLAN_UMAC_COMP_LL_SAP);
64 
65 	status = wlan_objmgr_psoc_component_obj_detach(psoc,
66 						       WLAN_UMAC_COMP_LL_SAP,
67 						       ll_sap_psoc_obj);
68 	if (QDF_IS_STATUS_ERROR(status))
69 		ll_sap_err("ll_sap detach failed");
70 
71 	qdf_mem_free(ll_sap_psoc_obj);
72 
73 	ll_sap_debug("ll sap psoc object destroyed");
74 
75 	return status;
76 }
77 
ll_sap_vdev_obj_created_notification(struct wlan_objmgr_vdev * vdev,void * arg_list)78 static QDF_STATUS ll_sap_vdev_obj_created_notification(
79 				struct wlan_objmgr_vdev *vdev, void *arg_list)
80 {
81 	QDF_STATUS status = QDF_STATUS_SUCCESS;
82 	struct ll_sap_vdev_priv_obj *ll_sap_obj;
83 
84 	if (wlan_vdev_mlme_get_opmode(vdev) != QDF_SAP_MODE)
85 		return QDF_STATUS_SUCCESS;
86 
87 	ll_sap_obj = qdf_mem_malloc(sizeof(*ll_sap_obj));
88 	if (!ll_sap_obj)
89 		return QDF_STATUS_E_NOMEM;
90 
91 	status = wlan_objmgr_vdev_component_obj_attach(
92 						vdev,
93 						WLAN_UMAC_COMP_LL_SAP,
94 						(void *)ll_sap_obj,
95 						QDF_STATUS_SUCCESS);
96 	if (QDF_IS_STATUS_ERROR(status)) {
97 		ll_sap_err("vdev %d obj attach failed", wlan_vdev_get_id(vdev));
98 		goto ll_sap_vdev_attach_failed;
99 	}
100 
101 	status = ll_lt_sap_init(vdev);
102 	if (QDF_IS_STATUS_ERROR(status))
103 		goto ll_sap_init_failed;
104 
105 	return status;
106 
107 ll_sap_init_failed:
108 	wlan_objmgr_vdev_component_obj_detach(vdev,
109 					      WLAN_UMAC_COMP_LL_SAP,
110 					      ll_sap_obj);
111 
112 ll_sap_vdev_attach_failed:
113 	qdf_mem_free(ll_sap_obj);
114 	return status;
115 }
116 
ll_sap_vdev_obj_destroyed_notification(struct wlan_objmgr_vdev * vdev,void * arg_list)117 static QDF_STATUS ll_sap_vdev_obj_destroyed_notification(
118 				struct wlan_objmgr_vdev *vdev, void *arg_list)
119 {
120 	QDF_STATUS status = QDF_STATUS_SUCCESS;
121 	struct ll_sap_vdev_priv_obj *ll_sap_obj;
122 
123 	if (wlan_vdev_mlme_get_opmode(vdev) != QDF_SAP_MODE)
124 		return QDF_STATUS_SUCCESS;
125 
126 	ll_lt_sap_deinit(vdev);
127 
128 	ll_sap_obj = ll_sap_get_vdev_priv_obj(vdev);
129 
130 	if (!ll_sap_obj) {
131 		ll_sap_err("vdev %d ll sap obj null",
132 			   wlan_vdev_get_id(vdev));
133 		return QDF_STATUS_E_INVAL;
134 	}
135 
136 	status = wlan_objmgr_vdev_component_obj_detach(vdev,
137 						       WLAN_UMAC_COMP_LL_SAP,
138 						       ll_sap_obj);
139 	if (QDF_IS_STATUS_ERROR(status))
140 		ll_sap_err("vdev %d ll sap obj detach failed, status %d",
141 			   wlan_vdev_get_id(vdev), status);
142 
143 	qdf_mem_free(ll_sap_obj);
144 
145 	return status;
146 }
147 
ll_sap_init(void)148 QDF_STATUS ll_sap_init(void)
149 {
150 	QDF_STATUS status;
151 
152 	/* register psoc create handler functions. */
153 	status = wlan_objmgr_register_psoc_create_handler(WLAN_UMAC_COMP_LL_SAP,
154 							  ll_sap_psoc_obj_created_notification,
155 							  NULL);
156 	if (QDF_IS_STATUS_ERROR(status)) {
157 		ll_sap_err("objmgr_register_psoc_create_handler failed");
158 		return status;
159 	}
160 
161 	/* register psoc delete handler functions. */
162 	status = wlan_objmgr_register_psoc_destroy_handler(WLAN_UMAC_COMP_LL_SAP,
163 							   ll_sap_psoc_obj_destroyed_notification,
164 							   NULL);
165 	if (QDF_IS_STATUS_ERROR(status)) {
166 		ll_sap_err("objmgr_register_psoc_destroy_handler failed");
167 		goto err_psoc_destroy_reg;
168 	}
169 
170 	/* register vdev create handler functions. */
171 	status = wlan_objmgr_register_vdev_create_handler(
172 		WLAN_UMAC_COMP_LL_SAP,
173 		ll_sap_vdev_obj_created_notification,
174 		NULL);
175 	if (QDF_IS_STATUS_ERROR(status)) {
176 		ll_sap_err("objmgr_register_vdev_create_handler failed");
177 		goto err_vdev_create_reg;
178 	}
179 
180 	/* register vdev delete handler functions. */
181 	status = wlan_objmgr_register_vdev_destroy_handler(
182 		WLAN_UMAC_COMP_LL_SAP,
183 		ll_sap_vdev_obj_destroyed_notification,
184 		NULL);
185 	if (QDF_IS_STATUS_ERROR(status)) {
186 		ll_sap_err("objmgr_register_vdev_destroy_handler failed");
187 		goto err_vdev_destroy_reg;
188 	}
189 
190 	return status;
191 err_vdev_destroy_reg:
192 	wlan_objmgr_unregister_vdev_create_handler(
193 					WLAN_UMAC_COMP_LL_SAP,
194 					ll_sap_vdev_obj_created_notification,
195 					NULL);
196 
197 err_vdev_create_reg:
198 	wlan_objmgr_unregister_psoc_destroy_handler(
199 					WLAN_UMAC_COMP_LL_SAP,
200 					ll_sap_psoc_obj_destroyed_notification,
201 					NULL);
202 
203 err_psoc_destroy_reg:
204 	wlan_objmgr_unregister_psoc_create_handler(
205 					WLAN_UMAC_COMP_LL_SAP,
206 					ll_sap_psoc_obj_created_notification,
207 					NULL);
208 
209 	return status;
210 }
211 
ll_sap_deinit(void)212 QDF_STATUS ll_sap_deinit(void)
213 {
214 	QDF_STATUS ret = QDF_STATUS_SUCCESS, status;
215 
216 	/* de-register vdev delete handler functions. */
217 	status = wlan_objmgr_unregister_vdev_destroy_handler(
218 					WLAN_UMAC_COMP_LL_SAP,
219 					ll_sap_vdev_obj_destroyed_notification,
220 					NULL);
221 	if (QDF_IS_STATUS_ERROR(status)) {
222 		ll_sap_err("objmgr_unregister_vdev_destroy_handler failed");
223 		ret = status;
224 	}
225 
226 	/* de-register vdev create handler functions. */
227 	status = wlan_objmgr_unregister_vdev_create_handler(
228 					WLAN_UMAC_COMP_LL_SAP,
229 					ll_sap_vdev_obj_created_notification,
230 					NULL);
231 	if (QDF_IS_STATUS_ERROR(status)) {
232 		ll_sap_err("objmgr_unregister_vdev_create_handler failed");
233 		ret = status;
234 	}
235 
236 	/* unregister psoc destroy handler functions. */
237 	status = wlan_objmgr_unregister_psoc_destroy_handler(WLAN_UMAC_COMP_LL_SAP,
238 							     ll_sap_psoc_obj_destroyed_notification,
239 							     NULL);
240 	if (QDF_IS_STATUS_ERROR(status)) {
241 		ll_sap_err("objmgr_deregister_psoc_destroy_handler failed");
242 		ret = status;
243 	}
244 
245 	/* unregister psoc create handler functions. */
246 	status = wlan_objmgr_unregister_psoc_create_handler(WLAN_UMAC_COMP_LL_SAP,
247 							    ll_sap_psoc_obj_created_notification,
248 							    NULL);
249 	if (QDF_IS_STATUS_ERROR(status)) {
250 		ll_sap_err("objmgr_unregister_psoc_create_handler failed");
251 		ret = status;
252 	}
253 
254 	return ret;
255 }
256 
ll_sap_register_os_if_cb(struct ll_sap_ops * ll_sap_global_ops)257 void ll_sap_register_os_if_cb(struct ll_sap_ops *ll_sap_global_ops)
258 {
259 	global_ll_sap_ops = ll_sap_global_ops;
260 }
261 
ll_sap_unregister_os_if_cb(void)262 void ll_sap_unregister_os_if_cb(void)
263 {
264 	global_ll_sap_ops = NULL;
265 }
266 
ll_sap_get_osif_cbk(void)267 struct ll_sap_ops *ll_sap_get_osif_cbk(void)
268 {
269 	return global_ll_sap_ops;
270 }
271 
ll_sap_psoc_enable(struct wlan_objmgr_psoc * psoc)272 QDF_STATUS ll_sap_psoc_enable(struct wlan_objmgr_psoc *psoc)
273 {
274 	return target_if_ll_sap_register_events(psoc);
275 }
276 
ll_sap_psoc_disable(struct wlan_objmgr_psoc * psoc)277 QDF_STATUS ll_sap_psoc_disable(struct wlan_objmgr_psoc *psoc)
278 {
279 	return target_if_ll_sap_deregister_events(psoc);
280 }
281