1 /*
2  * Copyright (c) 2016-2021 The Linux Foundation. All rights reserved.
3  * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
4  *
5  * Permission to use, copy, modify, and/or distribute this software for
6  * any purpose with or without fee is hereby granted, provided that the
7  * above copyright notice and this permission notice appear in all
8  * copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
11  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
12  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
13  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
14  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
16  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17  * PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20 /**
21  *  DOC:    wlan_mgmt_txrx_utils_api.c
22  *  This file contains mgmt txrx public API definitions for umac
23  *  converged components.
24  */
25 
26 #include "wlan_mgmt_txrx_utils_api.h"
27 #include "wlan_mgmt_txrx_tgt_api.h"
28 #include "../../core/src/wlan_mgmt_txrx_main_i.h"
29 #include "wlan_objmgr_psoc_obj.h"
30 #include "wlan_objmgr_global_obj.h"
31 #include "wlan_objmgr_pdev_obj.h"
32 #include "wlan_objmgr_vdev_obj.h"
33 #include "wlan_objmgr_peer_obj.h"
34 #include "qdf_nbuf.h"
35 #include "wlan_lmac_if_api.h"
36 #include <wlan_mgmt_txrx_rx_reo_utils_api.h>
37 
38 /**
39  * wlan_mgmt_txrx_psoc_obj_create_notification() - called from objmgr when psoc
40  *                                                 is created
41  * @psoc: psoc context
42  * @arg: argument
43  *
44  * This function gets called from object manager when psoc is being created and
45  * creates mgmt_txrx context, mgmt desc pool.
46  *
47  * Return: QDF_STATUS_SUCCESS - in case of success
48  */
wlan_mgmt_txrx_psoc_obj_create_notification(struct wlan_objmgr_psoc * psoc,void * arg)49 static QDF_STATUS wlan_mgmt_txrx_psoc_obj_create_notification(
50 			struct wlan_objmgr_psoc *psoc,
51 			void *arg)
52 {
53 	struct mgmt_txrx_priv_psoc_context *mgmt_txrx_psoc_ctx;
54 	QDF_STATUS status;
55 
56 	if (!psoc) {
57 		mgmt_txrx_err("psoc context passed is NULL");
58 		status = QDF_STATUS_E_INVAL;
59 		goto err_return;
60 	}
61 
62 	mgmt_txrx_psoc_ctx = qdf_mem_malloc(sizeof(*mgmt_txrx_psoc_ctx));
63 	if (!mgmt_txrx_psoc_ctx) {
64 		status = QDF_STATUS_E_NOMEM;
65 		goto err_return;
66 	}
67 
68 	mgmt_txrx_psoc_ctx->psoc = psoc;
69 
70 	qdf_spinlock_create(&mgmt_txrx_psoc_ctx->mgmt_txrx_psoc_ctx_lock);
71 
72 	status = wlan_mgmt_rx_reo_psoc_obj_create_notification(psoc);
73 	if (QDF_IS_STATUS_ERROR(status)) {
74 		mgmt_txrx_err("Failed to run mgmt Rx REO psoc create handler");
75 		goto err_psoc_attach;
76 	}
77 
78 	if (wlan_objmgr_psoc_component_obj_attach(psoc,
79 				WLAN_UMAC_COMP_MGMT_TXRX,
80 				mgmt_txrx_psoc_ctx, QDF_STATUS_SUCCESS)
81 			!= QDF_STATUS_SUCCESS) {
82 		mgmt_txrx_err("Failed to attach mgmt txrx ctx in psoc ctx");
83 		status = QDF_STATUS_E_FAILURE;
84 		goto err_psoc_attach;
85 	}
86 
87 	mgmt_txrx_debug("Mgmt txrx creation successful, mgmt txrx ctx: %pK, psoc: %pK",
88 			mgmt_txrx_psoc_ctx, psoc);
89 
90 	return QDF_STATUS_SUCCESS;
91 
92 err_psoc_attach:
93 	qdf_spinlock_destroy(&mgmt_txrx_psoc_ctx->mgmt_txrx_psoc_ctx_lock);
94 	qdf_mem_free(mgmt_txrx_psoc_ctx);
95 err_return:
96 	return status;
97 }
98 
99 /**
100  * wlan_mgmt_txrx_psoc_obj_destroy_notification() - called from objmgr when
101  *                                                  psoc is destroyed
102  * @psoc: psoc context
103  * @arg: argument
104  *
105  * This function gets called from object manager when psoc is being destroyed
106  * psoc deletes mgmt_txrx context, mgmt desc pool.
107  *
108  * Return: QDF_STATUS_SUCCESS - in case of success
109  */
wlan_mgmt_txrx_psoc_obj_destroy_notification(struct wlan_objmgr_psoc * psoc,void * arg)110 static QDF_STATUS wlan_mgmt_txrx_psoc_obj_destroy_notification(
111 			struct wlan_objmgr_psoc *psoc,
112 			void *arg)
113 {
114 	struct mgmt_txrx_priv_psoc_context *mgmt_txrx_psoc_ctx;
115 	QDF_STATUS status;
116 
117 	if (!psoc) {
118 		mgmt_txrx_err("psoc context passed is NULL");
119 		return QDF_STATUS_E_INVAL;
120 	}
121 
122 	mgmt_txrx_psoc_ctx = wlan_objmgr_psoc_get_comp_private_obj(
123 			psoc, WLAN_UMAC_COMP_MGMT_TXRX);
124 	if (!mgmt_txrx_psoc_ctx) {
125 		mgmt_txrx_err("mgmt txrx context is already NULL");
126 		return QDF_STATUS_E_FAILURE;
127 	}
128 
129 	mgmt_txrx_debug("deleting mgmt txrx psoc obj, mgmt txrx ctx: %pK, psoc: %pK",
130 			mgmt_txrx_psoc_ctx, psoc);
131 
132 	status = wlan_mgmt_rx_reo_psoc_obj_destroy_notification(psoc);
133 	if (QDF_IS_STATUS_ERROR(status)) {
134 		mgmt_txrx_err("Failed to run mgmt Rx REO psoc destroy handler");
135 		return status;
136 	}
137 
138 	if (wlan_objmgr_psoc_component_obj_detach(psoc,
139 						  WLAN_UMAC_COMP_MGMT_TXRX,
140 						  mgmt_txrx_psoc_ctx)
141 			!= QDF_STATUS_SUCCESS) {
142 		mgmt_txrx_err("Failed to detach mgmt txrx ctx in psoc ctx");
143 		return QDF_STATUS_E_FAILURE;
144 	}
145 
146 	qdf_spinlock_destroy(&mgmt_txrx_psoc_ctx->mgmt_txrx_psoc_ctx_lock);
147 	qdf_mem_free(mgmt_txrx_psoc_ctx);
148 
149 	mgmt_txrx_debug("mgmt txrx deletion successful");
150 
151 	return QDF_STATUS_SUCCESS;
152 }
153 
154 /**
155  * wlan_mgmt_txrx_pdev_obj_create_notification() - called from objmgr when pdev
156  *                                                 is created
157  * @pdev: pdev context
158  * @arg: argument
159  *
160  * This function gets called from object manager when pdev is being created and
161  * creates mgmt_txrx context, mgmt desc pool.
162  *
163  * Return: QDF_STATUS_SUCCESS - in case of success
164  */
wlan_mgmt_txrx_pdev_obj_create_notification(struct wlan_objmgr_pdev * pdev,void * arg)165 static QDF_STATUS wlan_mgmt_txrx_pdev_obj_create_notification(
166 			struct wlan_objmgr_pdev *pdev,
167 			void *arg)
168 {
169 	struct mgmt_txrx_priv_pdev_context *mgmt_txrx_pdev_ctx;
170 	struct mgmt_txrx_stats_t *mgmt_txrx_stats;
171 	struct wlan_objmgr_psoc *psoc;
172 	uint8_t pdev_id;
173 	uint8_t psoc_id;
174 	QDF_STATUS status;
175 
176 	if (!pdev) {
177 		mgmt_txrx_err("pdev context passed is NULL");
178 		status = QDF_STATUS_E_INVAL;
179 		goto err_return;
180 	}
181 
182 	psoc = wlan_pdev_get_psoc(pdev);
183 
184 	if (!psoc) {
185 		mgmt_txrx_err("psoc context in pdev is NULL");
186 		status = QDF_STATUS_E_INVAL;
187 		goto err_return;
188 	}
189 
190 	pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev);
191 
192 	psoc_id = wlan_psoc_get_id(psoc);
193 
194 	mgmt_txrx_debug("enter pdev_id:%d psoc_id:%d", pdev_id, psoc_id);
195 
196 	mgmt_txrx_pdev_ctx = qdf_mem_malloc(sizeof(*mgmt_txrx_pdev_ctx));
197 	if (!mgmt_txrx_pdev_ctx) {
198 		status = QDF_STATUS_E_NOMEM;
199 		goto err_return;
200 	}
201 
202 	mgmt_txrx_pdev_ctx->pdev = pdev;
203 
204 	mgmt_txrx_debug("pool init pdev_id:%d psoc_id:%d", pdev_id, psoc_id);
205 
206 	status = wlan_mgmt_txrx_desc_pool_init(mgmt_txrx_pdev_ctx);
207 	if (status != QDF_STATUS_SUCCESS) {
208 		mgmt_txrx_err(
209 			"Failed to initialize mgmt desc. pool with status: %u",
210 			status);
211 		goto err_desc_pool_init;
212 	}
213 
214 	mgmt_txrx_stats = qdf_mem_malloc(sizeof(*mgmt_txrx_stats));
215 	if (!mgmt_txrx_stats) {
216 		status = QDF_STATUS_E_NOMEM;
217 		goto err_mgmt_txrx_stats;
218 	}
219 	mgmt_txrx_pdev_ctx->mgmt_txrx_stats = mgmt_txrx_stats;
220 
221 	mgmt_txrx_debug("lock create pdev_id:%d psoc_id:%d", pdev_id, psoc_id);
222 
223 	qdf_wake_lock_create(&mgmt_txrx_pdev_ctx->wakelock_tx_cmp,
224 			     "mgmt_txrx tx_cmp");
225 	qdf_runtime_lock_init(&mgmt_txrx_pdev_ctx->wakelock_tx_runtime_cmp);
226 
227 	mgmt_txrx_debug("notification create pdev_id:%d psoc_id:%d",
228 			pdev_id, psoc_id);
229 
230 	status = wlan_mgmt_rx_reo_pdev_obj_create_notification(
231 					pdev, mgmt_txrx_pdev_ctx);
232 	if (QDF_IS_STATUS_ERROR(status)) {
233 		mgmt_txrx_err("Failed to create mgmt Rx REO pdev object");
234 		goto err_mgmt_rx_reo_attach;
235 	}
236 
237 	mgmt_txrx_debug("obj attach pdev_id:%d psoc_id:%d", pdev_id, psoc_id);
238 
239 	if (wlan_objmgr_pdev_component_obj_attach(pdev,
240 			WLAN_UMAC_COMP_MGMT_TXRX,
241 			mgmt_txrx_pdev_ctx, QDF_STATUS_SUCCESS)
242 			!= QDF_STATUS_SUCCESS) {
243 		mgmt_txrx_err("Failed to attach mgmt txrx ctx in pdev ctx");
244 		status = QDF_STATUS_E_FAILURE;
245 		goto err_pdev_attach;
246 	}
247 
248 	mgmt_txrx_debug(
249 		"Mgmt txrx creation successful, mgmt txrx ctx: %pK, pdev: %pK",
250 		mgmt_txrx_pdev_ctx, pdev);
251 
252 	return QDF_STATUS_SUCCESS;
253 
254 err_pdev_attach:
255 	/* Avoiding error check in an error handler */
256 	wlan_mgmt_rx_reo_pdev_obj_destroy_notification(pdev,
257 						       mgmt_txrx_pdev_ctx);
258 err_mgmt_rx_reo_attach:
259 	qdf_runtime_lock_deinit(&mgmt_txrx_pdev_ctx->wakelock_tx_runtime_cmp);
260 	qdf_wake_lock_destroy(&mgmt_txrx_pdev_ctx->wakelock_tx_cmp);
261 	qdf_mem_free(mgmt_txrx_stats);
262 err_mgmt_txrx_stats:
263 	wlan_mgmt_txrx_desc_pool_deinit(mgmt_txrx_pdev_ctx);
264 err_desc_pool_init:
265 	qdf_mem_free(mgmt_txrx_pdev_ctx);
266 err_return:
267 	return status;
268 }
269 
270 /**
271  * wlan_mgmt_txrx_pdev_obj_destroy_notification() - called from objmgr when
272  *                                                  pdev is destroyed
273  * @pdev: pdev context
274  * @arg: argument
275  *
276  * This function gets called from object manager when pdev is being destroyed
277  * pdev deletes mgmt_txrx context, mgmt desc pool.
278  *
279  * Return: QDF_STATUS_SUCCESS - in case of success
280  */
wlan_mgmt_txrx_pdev_obj_destroy_notification(struct wlan_objmgr_pdev * pdev,void * arg)281 static QDF_STATUS wlan_mgmt_txrx_pdev_obj_destroy_notification(
282 			struct wlan_objmgr_pdev *pdev,
283 			void *arg)
284 {
285 	struct mgmt_txrx_priv_pdev_context *mgmt_txrx_pdev_ctx;
286 	QDF_STATUS status;
287 
288 	if (!pdev) {
289 		mgmt_txrx_err("pdev context passed is NULL");
290 		return QDF_STATUS_E_INVAL;
291 	}
292 
293 	mgmt_txrx_pdev_ctx = wlan_objmgr_pdev_get_comp_private_obj(
294 			pdev, WLAN_UMAC_COMP_MGMT_TXRX);
295 	if (!mgmt_txrx_pdev_ctx) {
296 		mgmt_txrx_err("mgmt txrx context is already NULL");
297 		return QDF_STATUS_E_FAILURE;
298 	}
299 
300 	mgmt_txrx_debug("deleting mgmt txrx pdev obj, mgmt txrx ctx: %pK, pdev: %pK",
301 			mgmt_txrx_pdev_ctx, pdev);
302 
303 	status = wlan_mgmt_rx_reo_pdev_obj_destroy_notification(
304 						pdev, mgmt_txrx_pdev_ctx);
305 	if (QDF_IS_STATUS_ERROR(status)) {
306 		mgmt_txrx_err("Failed to destroy mgmt Rx REO pdev object");
307 		return QDF_STATUS_E_FAILURE;
308 	}
309 
310 	if (wlan_objmgr_pdev_component_obj_detach(pdev,
311 						  WLAN_UMAC_COMP_MGMT_TXRX,
312 						  mgmt_txrx_pdev_ctx)
313 			!= QDF_STATUS_SUCCESS) {
314 		mgmt_txrx_err("Failed to detach mgmt txrx ctx in pdev ctx");
315 		return QDF_STATUS_E_FAILURE;
316 	}
317 
318 	wlan_mgmt_txrx_desc_pool_deinit(mgmt_txrx_pdev_ctx);
319 	qdf_mem_free(mgmt_txrx_pdev_ctx->mgmt_txrx_stats);
320 	qdf_runtime_lock_deinit(&mgmt_txrx_pdev_ctx->wakelock_tx_runtime_cmp);
321 	qdf_wake_lock_destroy(&mgmt_txrx_pdev_ctx->wakelock_tx_cmp);
322 	qdf_mem_free(mgmt_txrx_pdev_ctx);
323 
324 	mgmt_txrx_debug("mgmt txrx deletion successful, pdev: %pK", pdev);
325 
326 	return QDF_STATUS_SUCCESS;
327 }
328 
329 
wlan_mgmt_txrx_init(void)330 QDF_STATUS wlan_mgmt_txrx_init(void)
331 {
332 	QDF_STATUS status = QDF_STATUS_SUCCESS;
333 
334 	status = wlan_objmgr_register_psoc_create_handler(
335 				WLAN_UMAC_COMP_MGMT_TXRX,
336 				wlan_mgmt_txrx_psoc_obj_create_notification,
337 				NULL);
338 	if (status != QDF_STATUS_SUCCESS) {
339 		mgmt_txrx_err("Failed to register mgmt txrx psoc create handler");
340 		goto err_psoc_create;
341 	}
342 
343 	status = wlan_objmgr_register_psoc_destroy_handler(
344 				WLAN_UMAC_COMP_MGMT_TXRX,
345 				wlan_mgmt_txrx_psoc_obj_destroy_notification,
346 				NULL);
347 	if (status != QDF_STATUS_SUCCESS) {
348 		mgmt_txrx_err("Failed to register mgmt txrx psoc destroy handler");
349 		goto err_psoc_delete;
350 	}
351 
352 	status = wlan_objmgr_register_pdev_create_handler(
353 				WLAN_UMAC_COMP_MGMT_TXRX,
354 				wlan_mgmt_txrx_pdev_obj_create_notification,
355 				NULL);
356 	if (status != QDF_STATUS_SUCCESS) {
357 		mgmt_txrx_err("Failed to register mgmt txrx pdev obj create handler");
358 		goto err_pdev_create;
359 	}
360 
361 	status = wlan_objmgr_register_pdev_destroy_handler(
362 				WLAN_UMAC_COMP_MGMT_TXRX,
363 				wlan_mgmt_txrx_pdev_obj_destroy_notification,
364 				NULL);
365 	if (status != QDF_STATUS_SUCCESS) {
366 		mgmt_txrx_err("Failed to register mgmt txrx obj destroy handler");
367 		goto err_pdev_delete;
368 	}
369 
370 	status = wlan_mgmt_rx_reo_init();
371 	if (status != QDF_STATUS_SUCCESS) {
372 		mgmt_txrx_err("Failed to initialize mgmt Rx reo module");
373 		goto err_reo_init;
374 	}
375 
376 	mgmt_txrx_debug("Successfully registered create and destroy handlers with objmgr");
377 	return QDF_STATUS_SUCCESS;
378 
379 err_reo_init:
380 	wlan_objmgr_unregister_pdev_destroy_handler(
381 			WLAN_UMAC_COMP_MGMT_TXRX,
382 			wlan_mgmt_txrx_pdev_obj_destroy_notification, NULL);
383 err_pdev_delete:
384 	wlan_objmgr_unregister_pdev_create_handler(WLAN_UMAC_COMP_MGMT_TXRX,
385 			wlan_mgmt_txrx_pdev_obj_create_notification, NULL);
386 err_pdev_create:
387 	wlan_objmgr_unregister_psoc_destroy_handler(WLAN_UMAC_COMP_MGMT_TXRX,
388 			wlan_mgmt_txrx_psoc_obj_destroy_notification, NULL);
389 err_psoc_delete:
390 	wlan_objmgr_unregister_psoc_create_handler(WLAN_UMAC_COMP_MGMT_TXRX,
391 			wlan_mgmt_txrx_psoc_obj_create_notification, NULL);
392 err_psoc_create:
393 	return status;
394 }
395 
wlan_mgmt_txrx_deinit(void)396 QDF_STATUS wlan_mgmt_txrx_deinit(void)
397 {
398 	if (QDF_IS_STATUS_ERROR(wlan_mgmt_rx_reo_deinit())) {
399 		mgmt_txrx_err("Failed to de-initialize mgmt Rx reo module");
400 		return QDF_STATUS_E_FAILURE;
401 	}
402 
403 	if (wlan_objmgr_unregister_psoc_create_handler(WLAN_UMAC_COMP_MGMT_TXRX,
404 				wlan_mgmt_txrx_psoc_obj_create_notification,
405 				NULL)
406 			!= QDF_STATUS_SUCCESS) {
407 		return QDF_STATUS_E_FAILURE;
408 	}
409 
410 	if (wlan_objmgr_unregister_psoc_destroy_handler(
411 				WLAN_UMAC_COMP_MGMT_TXRX,
412 				wlan_mgmt_txrx_psoc_obj_destroy_notification,
413 				NULL)
414 			!= QDF_STATUS_SUCCESS) {
415 		return QDF_STATUS_E_FAILURE;
416 	}
417 
418 	if (wlan_objmgr_unregister_pdev_create_handler(WLAN_UMAC_COMP_MGMT_TXRX,
419 				wlan_mgmt_txrx_pdev_obj_create_notification,
420 				NULL)
421 			!= QDF_STATUS_SUCCESS) {
422 		return QDF_STATUS_E_FAILURE;
423 	}
424 
425 	if (wlan_objmgr_unregister_pdev_destroy_handler(
426 				WLAN_UMAC_COMP_MGMT_TXRX,
427 				wlan_mgmt_txrx_pdev_obj_destroy_notification,
428 				NULL)
429 			!= QDF_STATUS_SUCCESS) {
430 		return QDF_STATUS_E_FAILURE;
431 	}
432 
433 	mgmt_txrx_debug("Successfully unregistered create and destroy handlers with objmgr");
434 	return QDF_STATUS_SUCCESS;
435 }
436 
wlan_mgmt_txrx_mgmt_frame_tx(struct wlan_objmgr_peer * peer,void * context,qdf_nbuf_t buf,mgmt_tx_download_comp_cb tx_comp_cb,mgmt_ota_comp_cb tx_ota_comp_cb,enum wlan_umac_comp_id comp_id,void * mgmt_tx_params)437 QDF_STATUS wlan_mgmt_txrx_mgmt_frame_tx(struct wlan_objmgr_peer *peer,
438 					void *context,
439 					qdf_nbuf_t buf,
440 					mgmt_tx_download_comp_cb tx_comp_cb,
441 					mgmt_ota_comp_cb tx_ota_comp_cb,
442 					enum wlan_umac_comp_id comp_id,
443 					void *mgmt_tx_params)
444 {
445 	struct mgmt_txrx_desc_elem_t *desc;
446 	struct wlan_objmgr_psoc *psoc;
447 	struct wlan_objmgr_pdev *pdev;
448 	struct mgmt_txrx_priv_pdev_context *txrx_ctx;
449 	struct wlan_objmgr_vdev *vdev;
450 	QDF_STATUS status;
451 	struct wlan_lmac_if_tx_ops *tx_ops;
452 	struct ieee80211_frame *wh;
453 
454 	if (!peer) {
455 		mgmt_txrx_err("peer passed is NULL");
456 		return QDF_STATUS_E_NULL_VALUE;
457 	}
458 
459 	status = wlan_objmgr_peer_try_get_ref(peer, WLAN_MGMT_NB_ID);
460 	if (QDF_IS_STATUS_ERROR(status)) {
461 		mgmt_txrx_err("failed to get ref count for peer %pK", peer);
462 		return QDF_STATUS_E_NULL_VALUE;
463 	}
464 
465 	vdev = wlan_peer_get_vdev(peer);
466 	if (!vdev) {
467 		mgmt_txrx_err("vdev unavailable for peer %pK", peer);
468 		wlan_objmgr_peer_release_ref(peer, WLAN_MGMT_NB_ID);
469 		return QDF_STATUS_E_NULL_VALUE;
470 	}
471 
472 	psoc = wlan_vdev_get_psoc(vdev);
473 	if (!psoc) {
474 		mgmt_txrx_err("psoc unavailable for peer %pK vdev %pK",
475 				peer, vdev);
476 		wlan_objmgr_peer_release_ref(peer, WLAN_MGMT_NB_ID);
477 		return QDF_STATUS_E_NULL_VALUE;
478 	}
479 
480 	pdev = wlan_vdev_get_pdev(vdev);
481 	if (!pdev) {
482 		mgmt_txrx_err("pdev unavailable for peer %pK vdev %pK",
483 				peer, vdev);
484 		wlan_objmgr_peer_release_ref(peer, WLAN_MGMT_NB_ID);
485 		return QDF_STATUS_E_NULL_VALUE;
486 	}
487 
488 	wh = (struct ieee80211_frame *)qdf_nbuf_data(buf);
489 	if ((wh->i_fc[0] & QDF_IEEE80211_FC0_VERSION_MASK) !=
490 	    QDF_IEEE80211_FC0_VERSION_0) {
491 		mgmt_txrx_err("Incorrect frame control version");
492 		wlan_objmgr_peer_release_ref(peer, WLAN_MGMT_NB_ID);
493 		return QDF_STATUS_E_NULL_VALUE;
494 	}
495 
496 	txrx_ctx = (struct mgmt_txrx_priv_pdev_context *)
497 			wlan_objmgr_pdev_get_comp_private_obj(pdev,
498 				WLAN_UMAC_COMP_MGMT_TXRX);
499 	if (!txrx_ctx) {
500 		mgmt_txrx_err("No txrx context for peer %pK pdev %pK",
501 				peer, pdev);
502 		wlan_objmgr_peer_release_ref(peer, WLAN_MGMT_NB_ID);
503 		return QDF_STATUS_E_NULL_VALUE;
504 	}
505 
506 	desc = wlan_mgmt_txrx_desc_get(txrx_ctx);
507 	if (!desc) {
508 		wlan_objmgr_peer_release_ref(peer, WLAN_MGMT_NB_ID);
509 		return QDF_STATUS_E_RESOURCES;
510 	}
511 
512 	desc->nbuf = buf;
513 	desc->tx_ota_cmpl_cb = tx_ota_comp_cb;
514 	desc->tx_dwnld_cmpl_cb = tx_comp_cb;
515 	desc->peer = peer;
516 	desc->vdev_id = wlan_vdev_get_id(vdev);
517 	desc->context = context;
518 
519 	if (QDF_STATUS_E_NULL_VALUE ==
520 	    iot_sim_mgmt_tx_update(psoc, vdev, buf)) {
521 		wlan_objmgr_peer_release_ref(peer, WLAN_MGMT_NB_ID);
522 		wlan_mgmt_txrx_desc_put(txrx_ctx, desc->desc_id);
523 		return QDF_STATUS_E_NULL_VALUE;
524 	}
525 
526 	tx_ops = wlan_psoc_get_lmac_if_txops(psoc);
527 	if (!tx_ops) {
528 		mgmt_txrx_err("tx_ops is NULL");
529 		wlan_objmgr_peer_release_ref(peer, WLAN_MGMT_NB_ID);
530 		wlan_mgmt_txrx_desc_put(txrx_ctx, desc->desc_id);
531 		return QDF_STATUS_E_NULL_VALUE;
532 	}
533 
534 	if (!tx_ops->mgmt_txrx_tx_ops.mgmt_tx_send) {
535 		mgmt_txrx_err("mgmt txrx txop to send mgmt frame is NULL for psoc: %pK",
536 				psoc);
537 		wlan_objmgr_peer_release_ref(peer, WLAN_MGMT_NB_ID);
538 		desc->nbuf = NULL;
539 		wlan_mgmt_txrx_desc_put(txrx_ctx, desc->desc_id);
540 		return QDF_STATUS_E_FAILURE;
541 	}
542 
543 	if (tx_ops->mgmt_txrx_tx_ops.mgmt_tx_send(
544 			vdev, buf, desc->desc_id, mgmt_tx_params)) {
545 		mgmt_txrx_err("Mgmt send fail for peer %pK psoc %pK pdev: %pK",
546 				peer, psoc, pdev);
547 		wlan_objmgr_peer_release_ref(peer, WLAN_MGMT_NB_ID);
548 		desc->nbuf = NULL;
549 		wlan_mgmt_txrx_desc_put(txrx_ctx, desc->desc_id);
550 		return QDF_STATUS_E_FAILURE;
551 	}
552 	return QDF_STATUS_SUCCESS;
553 }
554 
wlan_mgmt_txrx_beacon_frame_tx(struct wlan_objmgr_peer * peer,qdf_nbuf_t buf,enum wlan_umac_comp_id comp_id)555 QDF_STATUS wlan_mgmt_txrx_beacon_frame_tx(struct wlan_objmgr_peer *peer,
556 					  qdf_nbuf_t buf,
557 					  enum wlan_umac_comp_id comp_id)
558 {
559 	struct wlan_objmgr_vdev *vdev;
560 	struct wlan_objmgr_psoc *psoc;
561 	struct wlan_lmac_if_tx_ops *tx_ops;
562 
563 	vdev = wlan_peer_get_vdev(peer);
564 	if (!vdev) {
565 		mgmt_txrx_err("vdev unavailable for peer %pK", peer);
566 		return QDF_STATUS_E_NULL_VALUE;
567 	}
568 
569 	psoc = wlan_vdev_get_psoc(vdev);
570 	if (!psoc) {
571 		mgmt_txrx_err("psoc unavailable for peer %pK", peer);
572 		return QDF_STATUS_E_NULL_VALUE;
573 	}
574 
575 	tx_ops = wlan_psoc_get_lmac_if_txops(psoc);
576 	if (!tx_ops) {
577 		mgmt_txrx_err("tx_ops is NULL");
578 		return QDF_STATUS_E_NULL_VALUE;
579 	}
580 
581 	if (!tx_ops->mgmt_txrx_tx_ops.beacon_send) {
582 		mgmt_txrx_err("mgmt txrx tx op to send beacon frame is NULL for psoc: %pK",
583 				psoc);
584 		return QDF_STATUS_E_FAILURE;
585 	}
586 
587 	if (tx_ops->mgmt_txrx_tx_ops.beacon_send(vdev, buf)) {
588 		mgmt_txrx_err("Beacon send fail for peer %pK psoc %pK",
589 				peer, psoc);
590 		return QDF_STATUS_E_FAILURE;
591 	}
592 	return QDF_STATUS_SUCCESS;
593 }
594 
wlan_mgmt_is_rmf_mgmt_action_frame(uint8_t action_category)595 bool wlan_mgmt_is_rmf_mgmt_action_frame(uint8_t action_category)
596 {
597 	switch (action_category) {
598 	case ACTION_CATEGORY_SPECTRUM_MGMT:
599 	case ACTION_CATEGORY_QOS:
600 	case ACTION_CATEGORY_DLS:
601 	case ACTION_CATEGORY_BACK:
602 	case ACTION_CATEGORY_RRM:
603 	case ACTION_FAST_BSS_TRNST:
604 	case ACTION_CATEGORY_SA_QUERY:
605 	case ACTION_CATEGORY_PROTECTED_DUAL_OF_PUBLIC_ACTION:
606 	case ACTION_CATEGORY_WNM:
607 	case ACTION_CATEGORY_MESH_ACTION:
608 	case ACTION_CATEGORY_MULTIHOP_ACTION:
609 	case ACTION_CATEGORY_DMG:
610 	case ACTION_CATEGORY_FST:
611 	case ACTION_CATEGORY_RVS:
612 	case ACTION_CATEGORY_SIG:
613 	case ACTION_CATEGORY_FLOW_CONTROL:
614 	case ACTION_CATEGORY_CONTROL_RSP_MCS_NEGO:
615 	case ACTION_CATEGORY_FILS:
616 	case ACTION_CATEGORY_CDMG:
617 	case ACTION_CATEGORY_CMMG:
618 	case ACTION_CATEGORY_GLK:
619 	case ACTION_CATEGORY_VENDOR_SPECIFIC_PROTECTED:
620 		return true;
621 	default:
622 		break;
623 	}
624 
625 	return false;
626 }
627 
628 #ifdef WLAN_SUPPORT_FILS
629 QDF_STATUS
wlan_mgmt_txrx_fd_action_frame_tx(struct wlan_objmgr_vdev * vdev,qdf_nbuf_t buf,enum wlan_umac_comp_id comp_id)630 wlan_mgmt_txrx_fd_action_frame_tx(struct wlan_objmgr_vdev *vdev,
631 				  qdf_nbuf_t buf,
632 				  enum wlan_umac_comp_id comp_id)
633 {
634 	struct wlan_objmgr_psoc *psoc;
635 	uint32_t vdev_id;
636 	struct wlan_lmac_if_tx_ops *tx_ops;
637 
638 	if (!vdev) {
639 		mgmt_txrx_err("Invalid vdev");
640 		return QDF_STATUS_E_NULL_VALUE;
641 	}
642 	vdev_id = wlan_vdev_get_id(vdev);
643 	psoc = wlan_vdev_get_psoc(vdev);
644 	if (!psoc) {
645 		mgmt_txrx_err("psoc unavailable for vdev %d", vdev_id);
646 		return QDF_STATUS_E_NULL_VALUE;
647 	}
648 
649 	tx_ops = wlan_psoc_get_lmac_if_txops(psoc);
650 	if (!tx_ops) {
651 		mgmt_txrx_err("tx_ops is NULL");
652 		return QDF_STATUS_E_NULL_VALUE;
653 	}
654 
655 	if (!tx_ops->mgmt_txrx_tx_ops.fd_action_frame_send) {
656 		mgmt_txrx_err("mgmt txrx txop to send fd action frame is NULL");
657 		return QDF_STATUS_E_FAILURE;
658 	}
659 
660 	if (tx_ops->mgmt_txrx_tx_ops.fd_action_frame_send(
661 			vdev, buf)) {
662 		mgmt_txrx_err("FD send fail for vdev %d", vdev_id);
663 		return QDF_STATUS_E_FAILURE;
664 	}
665 
666 	return QDF_STATUS_SUCCESS;
667 }
668 #endif /* WLAN_SUPPORT_FILS */
669 
670 /**
671  * wlan_mgmt_txrx_create_rx_handler() - creates rx handler node for umac comp.
672  * @mgmt_txrx_psoc_ctx: mgmt txrx context
673  * @mgmt_rx_cb: mgmt rx callback to be registered
674  * @comp_id: umac component id
675  * @frm_type: mgmt. frame for which cb to be registered.
676  *
677  * This function creates rx handler node for frame type and
678  * umac component passed in the func.
679  *
680  * Return: QDF_STATUS_SUCCESS - in case of success
681  */
wlan_mgmt_txrx_create_rx_handler(struct mgmt_txrx_priv_psoc_context * mgmt_txrx_psoc_ctx,mgmt_frame_rx_callback mgmt_rx_cb,enum wlan_umac_comp_id comp_id,enum mgmt_frame_type frm_type)682 static QDF_STATUS wlan_mgmt_txrx_create_rx_handler(
683 				struct mgmt_txrx_priv_psoc_context *mgmt_txrx_psoc_ctx,
684 				mgmt_frame_rx_callback mgmt_rx_cb,
685 				enum wlan_umac_comp_id comp_id,
686 				enum mgmt_frame_type frm_type)
687 {
688 	struct mgmt_rx_handler *rx_handler;
689 
690 	rx_handler = qdf_mem_malloc(sizeof(*rx_handler));
691 	if (!rx_handler)
692 		return QDF_STATUS_E_NOMEM;
693 
694 	rx_handler->comp_id = comp_id;
695 	rx_handler->rx_cb = mgmt_rx_cb;
696 
697 	qdf_spin_lock_bh(&mgmt_txrx_psoc_ctx->mgmt_txrx_psoc_ctx_lock);
698 	rx_handler->next = mgmt_txrx_psoc_ctx->mgmt_rx_comp_cb[frm_type];
699 	mgmt_txrx_psoc_ctx->mgmt_rx_comp_cb[frm_type] = rx_handler;
700 	qdf_spin_unlock_bh(&mgmt_txrx_psoc_ctx->mgmt_txrx_psoc_ctx_lock);
701 
702 	mgmt_txrx_debug("Callback registered for comp_id: %d, frm_type: %d",
703 			comp_id, frm_type);
704 	return QDF_STATUS_SUCCESS;
705 }
706 
707 /**
708  * wlan_mgmt_txrx_delete_rx_handler() - deletes rx handler node for umac comp.
709  * @mgmt_txrx_psoc_ctx: mgmt txrx context
710  * @mgmt_rx_cb: mgmt rx callback to be deregistered
711  * @comp_id: umac component id
712  * @frm_type: mgmt. frame for which cb to be registered.
713  *
714  * This function deletes rx handler node for frame type and
715  * umac component passed in the func.
716  *
717  * Return: QDF_STATUS_SUCCESS - in case of success
718  */
wlan_mgmt_txrx_delete_rx_handler(struct mgmt_txrx_priv_psoc_context * mgmt_txrx_psoc_ctx,mgmt_frame_rx_callback mgmt_rx_cb,enum wlan_umac_comp_id comp_id,enum mgmt_frame_type frm_type)719 static QDF_STATUS wlan_mgmt_txrx_delete_rx_handler(
720 		struct mgmt_txrx_priv_psoc_context *mgmt_txrx_psoc_ctx,
721 		mgmt_frame_rx_callback mgmt_rx_cb,
722 		enum wlan_umac_comp_id comp_id,
723 		enum mgmt_frame_type frm_type)
724 {
725 	struct mgmt_rx_handler *rx_handler = NULL, *rx_handler_prev = NULL;
726 	bool delete = false;
727 
728 	qdf_spin_lock_bh(&mgmt_txrx_psoc_ctx->mgmt_txrx_psoc_ctx_lock);
729 	rx_handler = mgmt_txrx_psoc_ctx->mgmt_rx_comp_cb[frm_type];
730 	while (rx_handler) {
731 		if (rx_handler->comp_id == comp_id &&
732 				rx_handler->rx_cb == mgmt_rx_cb) {
733 			if (rx_handler_prev)
734 				rx_handler_prev->next =
735 					rx_handler->next;
736 			else
737 				mgmt_txrx_psoc_ctx->mgmt_rx_comp_cb[frm_type] =
738 					rx_handler->next;
739 
740 			qdf_mem_free(rx_handler);
741 			delete = true;
742 			break;
743 		}
744 
745 		rx_handler_prev = rx_handler;
746 		rx_handler = rx_handler->next;
747 	}
748 	qdf_spin_unlock_bh(&mgmt_txrx_psoc_ctx->mgmt_txrx_psoc_ctx_lock);
749 
750 	if (!delete) {
751 		mgmt_txrx_err("No callback registered for comp_id: %d, frm_type: %d",
752 				comp_id, frm_type);
753 		return QDF_STATUS_E_FAILURE;
754 	}
755 
756 	mgmt_txrx_debug("Callback deregistered for comp_id: %d, frm_type: %d",
757 			comp_id, frm_type);
758 	return QDF_STATUS_SUCCESS;
759 }
760 
wlan_mgmt_txrx_register_rx_cb(struct wlan_objmgr_psoc * psoc,enum wlan_umac_comp_id comp_id,struct mgmt_txrx_mgmt_frame_cb_info * frm_cb_info,uint8_t num_entries)761 QDF_STATUS wlan_mgmt_txrx_register_rx_cb(
762 			struct wlan_objmgr_psoc *psoc,
763 			enum wlan_umac_comp_id comp_id,
764 			struct mgmt_txrx_mgmt_frame_cb_info *frm_cb_info,
765 			uint8_t num_entries)
766 {
767 	struct mgmt_txrx_priv_psoc_context *mgmt_txrx_psoc_ctx;
768 	QDF_STATUS status;
769 	uint8_t i, j;
770 
771 	if (!psoc) {
772 		mgmt_txrx_err("psoc context is NULL");
773 		return QDF_STATUS_E_INVAL;
774 	}
775 
776 	if (comp_id >= WLAN_UMAC_MAX_COMPONENTS) {
777 		mgmt_txrx_err("Invalid component id %d passed", comp_id);
778 		return QDF_STATUS_E_INVAL;
779 	}
780 
781 	if (!num_entries || num_entries >= MGMT_MAX_FRAME_TYPE) {
782 		mgmt_txrx_err("Invalid value for num_entries: %d passed",
783 				num_entries);
784 		return QDF_STATUS_E_INVAL;
785 	}
786 
787 	if (!frm_cb_info) {
788 		mgmt_txrx_err("frame cb info pointer is NULL");
789 		return QDF_STATUS_E_INVAL;
790 	}
791 
792 	mgmt_txrx_psoc_ctx = (struct mgmt_txrx_priv_psoc_context *)
793 			wlan_objmgr_psoc_get_comp_private_obj(psoc,
794 				WLAN_UMAC_COMP_MGMT_TXRX);
795 	if (!mgmt_txrx_psoc_ctx) {
796 		mgmt_txrx_err("mgmt txrx context is NULL");
797 		return QDF_STATUS_E_FAILURE;
798 	}
799 
800 	for (i = 0; i < num_entries; i++) {
801 		status = wlan_mgmt_txrx_create_rx_handler(mgmt_txrx_psoc_ctx,
802 				frm_cb_info[i].mgmt_rx_cb, comp_id,
803 				frm_cb_info[i].frm_type);
804 		if (status != QDF_STATUS_SUCCESS) {
805 			for (j = 0; j < i; j++) {
806 				wlan_mgmt_txrx_delete_rx_handler(
807 					mgmt_txrx_psoc_ctx,
808 					frm_cb_info[j].mgmt_rx_cb,
809 					comp_id, frm_cb_info[j].frm_type);
810 			}
811 			return status;
812 		}
813 	}
814 
815 	return QDF_STATUS_SUCCESS;
816 }
817 
wlan_mgmt_txrx_deregister_rx_cb(struct wlan_objmgr_psoc * psoc,enum wlan_umac_comp_id comp_id,struct mgmt_txrx_mgmt_frame_cb_info * frm_cb_info,uint8_t num_entries)818 QDF_STATUS wlan_mgmt_txrx_deregister_rx_cb(
819 			struct wlan_objmgr_psoc *psoc,
820 			enum wlan_umac_comp_id comp_id,
821 			struct mgmt_txrx_mgmt_frame_cb_info *frm_cb_info,
822 			uint8_t num_entries)
823 {
824 	struct mgmt_txrx_priv_psoc_context *mgmt_txrx_psoc_ctx;
825 	uint8_t i;
826 
827 	if (!psoc) {
828 		mgmt_txrx_err("psoc context is NULL");
829 		return QDF_STATUS_E_INVAL;
830 	}
831 
832 	if (comp_id >= WLAN_UMAC_MAX_COMPONENTS) {
833 		mgmt_txrx_err("Invalid component id %d passed", comp_id);
834 		return QDF_STATUS_E_INVAL;
835 	}
836 
837 	if (!num_entries || num_entries >= MGMT_MAX_FRAME_TYPE) {
838 		mgmt_txrx_err("Invalid value for num_entries: %d passed",
839 				num_entries);
840 		return QDF_STATUS_E_INVAL;
841 	}
842 
843 	if (!frm_cb_info) {
844 		mgmt_txrx_err("frame cb info pointer is NULL");
845 		return QDF_STATUS_E_INVAL;
846 	}
847 
848 	mgmt_txrx_psoc_ctx = (struct mgmt_txrx_priv_psoc_context *)
849 			wlan_objmgr_psoc_get_comp_private_obj(psoc,
850 				WLAN_UMAC_COMP_MGMT_TXRX);
851 	if (!mgmt_txrx_psoc_ctx) {
852 		mgmt_txrx_err("mgmt txrx context is NULL");
853 		return QDF_STATUS_E_FAILURE;
854 	}
855 
856 	for (i = 0; i < num_entries; i++) {
857 		wlan_mgmt_txrx_delete_rx_handler(mgmt_txrx_psoc_ctx,
858 				frm_cb_info[i].mgmt_rx_cb, comp_id,
859 				frm_cb_info[i].frm_type);
860 	}
861 
862 	return QDF_STATUS_SUCCESS;
863 }
864 
wlan_mgmt_txrx_psoc_open(struct wlan_objmgr_psoc * psoc)865 QDF_STATUS wlan_mgmt_txrx_psoc_open(struct wlan_objmgr_psoc *psoc)
866 {
867 	return QDF_STATUS_SUCCESS;
868 }
869 
wlan_mgmt_txrx_psoc_close(struct wlan_objmgr_psoc * psoc)870 QDF_STATUS wlan_mgmt_txrx_psoc_close(struct wlan_objmgr_psoc *psoc)
871 {
872 	return QDF_STATUS_SUCCESS;
873 }
874 
wlan_mgmt_txrx_psoc_enable(struct wlan_objmgr_psoc * psoc)875 QDF_STATUS wlan_mgmt_txrx_psoc_enable(struct wlan_objmgr_psoc *psoc)
876 {
877 	return tgt_mgmt_txrx_register_ev_handler(psoc);
878 }
879 
wlan_mgmt_txrx_psoc_disable(struct wlan_objmgr_psoc * psoc)880 QDF_STATUS wlan_mgmt_txrx_psoc_disable(struct wlan_objmgr_psoc *psoc)
881 {
882 	return tgt_mgmt_txrx_unregister_ev_handler(psoc);
883 }
884 
wlan_mgmt_txrx_pdev_open(struct wlan_objmgr_pdev * pdev)885 QDF_STATUS wlan_mgmt_txrx_pdev_open(struct wlan_objmgr_pdev *pdev)
886 {
887 	return QDF_STATUS_SUCCESS;
888 }
889 
wlan_mgmt_txrx_pdev_close(struct wlan_objmgr_pdev * pdev)890 QDF_STATUS wlan_mgmt_txrx_pdev_close(struct wlan_objmgr_pdev *pdev)
891 {
892 	struct wlan_objmgr_psoc *psoc;
893 	struct mgmt_txrx_priv_pdev_context *mgmt_txrx_pdev_ctx;
894 	struct mgmt_txrx_desc_elem_t *mgmt_desc;
895 	uint32_t pool_size;
896 	uint32_t index;
897 	struct wlan_lmac_if_tx_ops *tx_ops;
898 
899 	if (!pdev) {
900 		mgmt_txrx_err("pdev context is NULL");
901 		return QDF_STATUS_E_INVAL;
902 	}
903 
904 	psoc = wlan_pdev_get_psoc(pdev);
905 	if (!psoc) {
906 		mgmt_txrx_err("psoc unavailable for pdev %pK", pdev);
907 		return QDF_STATUS_E_NULL_VALUE;
908 	}
909 
910 	tx_ops = wlan_psoc_get_lmac_if_txops(psoc);
911 	if (!tx_ops) {
912 		mgmt_txrx_err("tx_ops is NULL");
913 		return QDF_STATUS_E_NULL_VALUE;
914 	}
915 
916 	mgmt_txrx_pdev_ctx = (struct mgmt_txrx_priv_pdev_context *)
917 		wlan_objmgr_pdev_get_comp_private_obj(pdev,
918 		WLAN_UMAC_COMP_MGMT_TXRX);
919 
920 	if (!mgmt_txrx_pdev_ctx) {
921 		mgmt_txrx_err("mgmt txrx context is NULL");
922 		return QDF_STATUS_E_FAILURE;
923 	}
924 
925 	pool_size = mgmt_txrx_pdev_ctx->mgmt_desc_pool.free_list.max_size;
926 	if (!pool_size) {
927 		mgmt_txrx_err("pool size is 0");
928 		return QDF_STATUS_E_FAILURE;
929 	}
930 
931 	for (index = 0; index < pool_size; index++) {
932 		if (mgmt_txrx_pdev_ctx->mgmt_desc_pool.pool[index].in_use) {
933 			mgmt_txrx_debug(
934 				"mgmt descriptor with desc id: %d not in freelist",
935 				index);
936 			mgmt_desc = &mgmt_txrx_pdev_ctx->mgmt_desc_pool.pool[index];
937 			if (tx_ops->mgmt_txrx_tx_ops.
938 					tx_drain_nbuf_op)
939 				tx_ops->mgmt_txrx_tx_ops.
940 					tx_drain_nbuf_op(pdev, mgmt_desc->nbuf);
941 			qdf_nbuf_free(mgmt_desc->nbuf);
942 			wlan_objmgr_peer_release_ref(mgmt_desc->peer,
943 				WLAN_MGMT_NB_ID);
944 			wlan_mgmt_txrx_desc_put(mgmt_txrx_pdev_ctx, index);
945 		}
946 	}
947 
948 	return QDF_STATUS_SUCCESS;
949 }
950 
wlan_mgmt_txrx_vdev_drain(struct wlan_objmgr_vdev * vdev,mgmt_frame_fill_peer_cb mgmt_fill_peer_cb,void * status)951 QDF_STATUS wlan_mgmt_txrx_vdev_drain(struct wlan_objmgr_vdev *vdev,
952 				mgmt_frame_fill_peer_cb mgmt_fill_peer_cb,
953 				void *status)
954 {
955 	struct wlan_objmgr_pdev *pdev;
956 	struct mgmt_txrx_priv_pdev_context *mgmt_txrx_pdev_ctx;
957 	struct mgmt_txrx_desc_elem_t *mgmt_desc;
958 	struct wlan_objmgr_peer *peer;
959 	struct wlan_objmgr_vdev *peer_vdev;
960 	uint32_t pool_size;
961 	int i;
962 
963 	if (!vdev) {
964 		mgmt_txrx_err("vdev context is NULL");
965 		return QDF_STATUS_E_INVAL;
966 	}
967 
968 	pdev = wlan_vdev_get_pdev(vdev);
969 	if (!pdev) {
970 		mgmt_txrx_err("pdev context is NULL");
971 		return QDF_STATUS_E_INVAL;
972 	}
973 	mgmt_txrx_pdev_ctx = (struct mgmt_txrx_priv_pdev_context *)
974 		wlan_objmgr_pdev_get_comp_private_obj(pdev,
975 			WLAN_UMAC_COMP_MGMT_TXRX);
976 	if (!mgmt_txrx_pdev_ctx) {
977 		mgmt_txrx_err("mgmt txrx context is NULL");
978 		return QDF_STATUS_E_FAILURE;
979 	}
980 
981 	pool_size = mgmt_txrx_pdev_ctx->mgmt_desc_pool.free_list.max_size;
982 	if (!pool_size) {
983 		mgmt_txrx_err("pool size is 0");
984 		return QDF_STATUS_E_FAILURE;
985 	}
986 
987 	for (i = 0; i < pool_size; i++) {
988 		if (mgmt_txrx_pdev_ctx->mgmt_desc_pool.pool[i].in_use) {
989 			mgmt_desc = &mgmt_txrx_pdev_ctx->mgmt_desc_pool.pool[i];
990 			peer = mgmt_txrx_get_peer(pdev, mgmt_desc->desc_id);
991 			if (peer) {
992 				peer_vdev = wlan_peer_get_vdev(peer);
993 				if (peer_vdev == vdev) {
994 					if (mgmt_fill_peer_cb)
995 						mgmt_fill_peer_cb(peer, mgmt_desc->nbuf);
996 					mgmt_txrx_tx_completion_handler(pdev,
997 						mgmt_desc->desc_id, 0, status);
998 				}
999 			}
1000 		}
1001 	}
1002 
1003 	return QDF_STATUS_SUCCESS;
1004 }
1005