xref: /wlan-dirver/qca-wifi-host-cmn/target_if/mlme/vdev_mgr/src/target_if_vdev_mgr_rx_ops.c (revision 8b3dca18206e1a0461492f082fa6e270b092c035)
1 /*
2  * Copyright (c) 2019-2020 The Linux Foundation. All rights reserved.
3  * Copyright (c) 2021-2022 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: target_if_vdev_mgr_rx_ops.c
22  *
23  * This file provide definition for APIs registered through events received
24  * from FW
25  */
26 #include <target_if_vdev_mgr_rx_ops.h>
27 #include <target_if_vdev_mgr_tx_ops.h>
28 #include <wlan_vdev_mgr_tgt_if_rx_defs.h>
29 #include <wlan_vdev_mgr_tgt_if_tx_defs.h>
30 #include <wmi_unified_param.h>
31 #include <wlan_mlme_dbg.h>
32 #include <target_if.h>
33 #include <wlan_vdev_mlme_main.h>
34 #include <wmi_unified_vdev_api.h>
35 #include <target_if_psoc_wake_lock.h>
36 #ifdef WLAN_FEATURE_ROAM_OFFLOAD
37 #include <target_if_cm_roam_offload.h>
38 #endif
39 
40 static inline
41 void target_if_vdev_mgr_handle_recovery(struct wlan_objmgr_psoc *psoc,
42 					uint8_t vdev_id,
43 					enum qdf_hang_reason recovery_reason,
44 					uint16_t rsp_pos)
45 {
46 	mlme_nofl_err("PSOC_%d VDEV_%d: %s rsp timeout", wlan_psoc_get_id(psoc),
47 		      vdev_id, string_from_rsp_bit(rsp_pos));
48 	if (target_if_vdev_mgr_is_panic_allowed())
49 		qdf_trigger_self_recovery(psoc, recovery_reason);
50 	else
51 		mlme_nofl_debug("PSOC_%d VDEV_%d: Panic not allowed",
52 				wlan_psoc_get_id(psoc), vdev_id);
53 }
54 
55 #ifdef WLAN_FEATURE_ROAM_OFFLOAD
56 static inline QDF_STATUS
57 target_if_send_rso_stop_failure_rsp(struct wlan_objmgr_psoc *psoc,
58 				    uint8_t vdev_id)
59 {
60 	return target_if_cm_send_rso_stop_failure_rsp(psoc, vdev_id);
61 }
62 #else
63 static inline QDF_STATUS
64 target_if_send_rso_stop_failure_rsp(struct wlan_objmgr_psoc *psoc,
65 				    uint8_t vdev_id)
66 {
67 	return QDF_STATUS_E_NOSUPPORT;
68 }
69 #endif
70 
71 void target_if_vdev_mgr_rsp_timer_cb(void *arg)
72 {
73 	struct wlan_objmgr_psoc *psoc;
74 	struct wlan_lmac_if_mlme_rx_ops *rx_ops;
75 	struct vdev_start_response start_rsp = {0};
76 	struct vdev_stop_response stop_rsp = {0};
77 	struct vdev_delete_response del_rsp = {0};
78 	struct peer_delete_all_response peer_del_all_rsp = {0};
79 	struct vdev_response_timer *vdev_rsp = arg;
80 	enum qdf_hang_reason recovery_reason;
81 	uint8_t vdev_id;
82 	uint16_t rsp_pos = RESPONSE_BIT_MAX;
83 
84 	if (!vdev_rsp) {
85 		mlme_err("Vdev response timer is NULL");
86 		return;
87 	}
88 
89 	psoc = vdev_rsp->psoc;
90 	if (!psoc) {
91 		mlme_err("PSOC is NULL");
92 		return;
93 	}
94 
95 	rx_ops = target_if_vdev_mgr_get_rx_ops(psoc);
96 	if (!rx_ops || !rx_ops->psoc_get_vdev_response_timer_info) {
97 		mlme_err("No Rx Ops");
98 		return;
99 	}
100 
101 	if (!qdf_atomic_test_bit(START_RESPONSE_BIT, &vdev_rsp->rsp_status) &&
102 	    !qdf_atomic_test_bit(RESTART_RESPONSE_BIT, &vdev_rsp->rsp_status) &&
103 	    !qdf_atomic_test_bit(STOP_RESPONSE_BIT, &vdev_rsp->rsp_status) &&
104 	    !qdf_atomic_test_bit(DELETE_RESPONSE_BIT, &vdev_rsp->rsp_status) &&
105 	    !qdf_atomic_test_bit(PEER_DELETE_ALL_RESPONSE_BIT,
106 				 &vdev_rsp->rsp_status) &&
107 	    !qdf_atomic_test_bit(RSO_STOP_RESPONSE_BIT,
108 				 &vdev_rsp->rsp_status)) {
109 		mlme_debug("No response bit is set, ignoring actions :%d",
110 			   vdev_rsp->vdev_id);
111 		return;
112 	}
113 
114 	vdev_id = vdev_rsp->vdev_id;
115 	if (vdev_id >= WLAN_UMAC_PSOC_MAX_VDEVS) {
116 		mlme_err("Invalid VDEV_%d PSOC_%d", vdev_id,
117 			 wlan_psoc_get_id(psoc));
118 		return;
119 	}
120 
121 	vdev_rsp->timer_status = QDF_STATUS_E_TIMEOUT;
122 	if (qdf_atomic_test_bit(START_RESPONSE_BIT,
123 				&vdev_rsp->rsp_status) ||
124 	    qdf_atomic_test_bit(RESTART_RESPONSE_BIT,
125 				&vdev_rsp->rsp_status)) {
126 		start_rsp.vdev_id = vdev_id;
127 		start_rsp.status = WLAN_MLME_HOST_VDEV_START_TIMEOUT;
128 		if (qdf_atomic_test_bit(START_RESPONSE_BIT,
129 					&vdev_rsp->rsp_status)) {
130 			start_rsp.resp_type =
131 				WMI_HOST_VDEV_START_RESP_EVENT;
132 			rsp_pos = START_RESPONSE_BIT;
133 			recovery_reason = QDF_VDEV_START_RESPONSE_TIMED_OUT;
134 		} else {
135 			start_rsp.resp_type =
136 				WMI_HOST_VDEV_RESTART_RESP_EVENT;
137 			rsp_pos = RESTART_RESPONSE_BIT;
138 			recovery_reason = QDF_VDEV_RESTART_RESPONSE_TIMED_OUT;
139 		}
140 
141 		target_if_vdev_mgr_rsp_timer_stop(psoc, vdev_rsp, rsp_pos);
142 		target_if_vdev_mgr_handle_recovery(psoc, vdev_id,
143 						   recovery_reason, rsp_pos);
144 		rx_ops->vdev_mgr_start_response(psoc, &start_rsp);
145 	} else if (qdf_atomic_test_bit(STOP_RESPONSE_BIT,
146 				       &vdev_rsp->rsp_status)) {
147 		rsp_pos = STOP_RESPONSE_BIT;
148 		stop_rsp.vdev_id = vdev_id;
149 		recovery_reason = QDF_VDEV_STOP_RESPONSE_TIMED_OUT;
150 
151 		target_if_vdev_mgr_rsp_timer_stop(psoc, vdev_rsp, rsp_pos);
152 		target_if_vdev_mgr_handle_recovery(psoc, vdev_id,
153 						   recovery_reason, rsp_pos);
154 		rx_ops->vdev_mgr_stop_response(psoc, &stop_rsp);
155 	} else if (qdf_atomic_test_bit(DELETE_RESPONSE_BIT,
156 				       &vdev_rsp->rsp_status)) {
157 		del_rsp.vdev_id = vdev_id;
158 		rsp_pos = DELETE_RESPONSE_BIT;
159 		recovery_reason = QDF_VDEV_DELETE_RESPONSE_TIMED_OUT;
160 		target_if_vdev_mgr_rsp_timer_stop(psoc, vdev_rsp, rsp_pos);
161 		target_if_vdev_mgr_handle_recovery(psoc, vdev_id,
162 						   recovery_reason, rsp_pos);
163 		rx_ops->vdev_mgr_delete_response(psoc, &del_rsp);
164 	} else if (qdf_atomic_test_bit(PEER_DELETE_ALL_RESPONSE_BIT,
165 				&vdev_rsp->rsp_status)) {
166 		peer_del_all_rsp.vdev_id = vdev_id;
167 		peer_del_all_rsp.peer_type_bitmap = vdev_rsp->peer_type_bitmap;
168 		rsp_pos = PEER_DELETE_ALL_RESPONSE_BIT;
169 		recovery_reason = QDF_VDEV_PEER_DELETE_ALL_RESPONSE_TIMED_OUT;
170 		target_if_vdev_mgr_rsp_timer_stop(psoc, vdev_rsp, rsp_pos);
171 		target_if_vdev_mgr_handle_recovery(psoc, vdev_id,
172 						   recovery_reason, rsp_pos);
173 		rx_ops->vdev_mgr_peer_delete_all_response(psoc,
174 							  &peer_del_all_rsp);
175 	} else if (qdf_atomic_test_bit(RSO_STOP_RESPONSE_BIT,
176 				       &vdev_rsp->rsp_status)) {
177 		rsp_pos = RSO_STOP_RESPONSE_BIT;
178 		target_if_vdev_mgr_rsp_timer_stop(psoc, vdev_rsp, rsp_pos);
179 		/**
180 		 * FW did not respond to rso stop cmd, as roaming is
181 		 * disabled either due to race condition
182 		 * that happened during previous disconnect OR
183 		 * supplicant disabled roaming.
184 		 * To solve this issue, skip recovery and host will
185 		 * continue disconnect and cleanup rso state.
186 		 */
187 		mlme_debug("No rsp from FW received , continue with disconnect");
188 		target_if_send_rso_stop_failure_rsp(psoc, vdev_id);
189 	} else {
190 		mlme_err("PSOC_%d VDEV_%d: Unknown error",
191 			 wlan_psoc_get_id(psoc), vdev_id);
192 		return;
193 	}
194 }
195 
196 #ifdef SERIALIZE_VDEV_RESP
197 static QDF_STATUS target_if_vdev_mgr_rsp_flush_cb(struct scheduler_msg *msg)
198 {
199 	struct vdev_response_timer *vdev_rsp;
200 	struct wlan_objmgr_psoc *psoc;
201 
202 	if (!msg->bodyptr) {
203 		mlme_err("Message bodyptr is NULL");
204 		return QDF_STATUS_E_INVAL;
205 	}
206 
207 	vdev_rsp = msg->bodyptr;
208 	if (!vdev_rsp) {
209 		mlme_err("vdev response timer is NULL");
210 		return QDF_STATUS_E_INVAL;
211 	}
212 
213 	psoc = vdev_rsp->psoc;
214 	if (!psoc) {
215 		mlme_err("PSOC is NULL");
216 		return QDF_STATUS_E_INVAL;
217 	}
218 
219 	if (vdev_rsp->rsp_status)
220 		wlan_objmgr_psoc_release_ref(psoc, WLAN_PSOC_TARGET_IF_ID);
221 
222 	return QDF_STATUS_SUCCESS;
223 }
224 
225 static void
226 target_if_vdev_mgr_rsp_cb_mc_ctx(void *arg)
227 {
228 	struct scheduler_msg msg = {0};
229 	struct vdev_response_timer *vdev_rsp = arg;
230 	struct wlan_objmgr_psoc *psoc;
231 
232 	psoc = vdev_rsp->psoc;
233 	if (!psoc) {
234 		mlme_err("PSOC is NULL");
235 		return;
236 	}
237 
238 	msg.type = SYS_MSG_ID_MC_TIMER;
239 	msg.reserved = SYS_MSG_COOKIE;
240 
241 	/* msg.callback will explicitly cast back to qdf_mc_timer_callback_t
242 	 * in scheduler_timer_q_mq_handler.
243 	 * but in future we do not want to introduce more this kind of
244 	 * typecast by properly using QDF MC timer for MCC from get go in
245 	 * common code.
246 	 */
247 	msg.callback =
248 		(scheduler_msg_process_fn_t)target_if_vdev_mgr_rsp_timer_cb;
249 	msg.bodyptr = arg;
250 	msg.bodyval = 0;
251 	msg.flush_callback = target_if_vdev_mgr_rsp_flush_cb;
252 
253 	if (scheduler_post_message(QDF_MODULE_ID_TARGET_IF,
254 				   QDF_MODULE_ID_TARGET_IF,
255 				   QDF_MODULE_ID_SYS, &msg) ==
256 				   QDF_STATUS_SUCCESS)
257 		return;
258 
259 	mlme_err("Could not enqueue timer to timer queue");
260 	if (psoc)
261 		wlan_objmgr_psoc_release_ref(psoc, WLAN_PSOC_TARGET_IF_ID);
262 }
263 
264 void target_if_vdev_mgr_rsp_timer_mgmt_cb(void *arg)
265 {
266 	target_if_vdev_mgr_rsp_cb_mc_ctx(arg);
267 }
268 
269 #define VDEV_RSP_RX_CTX WMI_RX_SERIALIZER_CTX
270 #else
271 void target_if_vdev_mgr_rsp_timer_mgmt_cb(void *arg)
272 {
273 	target_if_vdev_mgr_rsp_timer_cb(arg);
274 }
275 
276 #define VDEV_RSP_RX_CTX WMI_RX_UMAC_CTX
277 #endif
278 
279 static int target_if_vdev_mgr_start_response_handler(ol_scn_t scn,
280 						     uint8_t *data,
281 						     uint32_t datalen)
282 {
283 	QDF_STATUS status = QDF_STATUS_E_INVAL;
284 	struct wlan_objmgr_psoc *psoc;
285 	struct wmi_unified *wmi_handle;
286 	struct wlan_lmac_if_mlme_rx_ops *rx_ops;
287 	struct vdev_start_response vdev_start_resp = {0};
288 	uint8_t vdev_id;
289 	struct vdev_response_timer *vdev_rsp;
290 
291 	if (!scn || !data) {
292 		mlme_err("Invalid input");
293 		return -EINVAL;
294 	}
295 
296 	psoc = target_if_get_psoc_from_scn_hdl(scn);
297 	if (!psoc) {
298 		mlme_err("PSOC is NULL");
299 		return -EINVAL;
300 	}
301 
302 	rx_ops = target_if_vdev_mgr_get_rx_ops(psoc);
303 	if (!rx_ops || !rx_ops->vdev_mgr_start_response) {
304 		mlme_err("No Rx Ops");
305 		return -EINVAL;
306 	}
307 
308 	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
309 	if (!wmi_handle) {
310 		mlme_err("wmi_handle is null");
311 		return -EINVAL;
312 	}
313 
314 	if (wmi_extract_vdev_start_resp(wmi_handle, data, &vdev_start_resp)) {
315 		mlme_err("WMI extract failed");
316 		return -EINVAL;
317 	}
318 
319 	vdev_id = vdev_start_resp.vdev_id;
320 	vdev_rsp = rx_ops->psoc_get_vdev_response_timer_info(psoc, vdev_id);
321 	if (!vdev_rsp) {
322 		mlme_err("vdev response timer is null VDEV_%d PSOC_%d",
323 			 vdev_id, wlan_psoc_get_id(psoc));
324 		return -EINVAL;
325 	}
326 
327 	if (vdev_start_resp.resp_type == WMI_HOST_VDEV_RESTART_RESP_EVENT)
328 		status = target_if_vdev_mgr_rsp_timer_stop(
329 							psoc, vdev_rsp,
330 							RESTART_RESPONSE_BIT);
331 	else
332 		status = target_if_vdev_mgr_rsp_timer_stop(psoc, vdev_rsp,
333 							   START_RESPONSE_BIT);
334 
335 	if (QDF_IS_STATUS_ERROR(status)) {
336 		mlme_err("PSOC_%d VDEV_%d: VDE MGR RSP Timer stop failed",
337 			 psoc->soc_objmgr.psoc_id, vdev_id);
338 		goto err;
339 	}
340 
341 	status = rx_ops->vdev_mgr_start_response(psoc, &vdev_start_resp);
342 
343 err:
344 	return qdf_status_to_os_return(status);
345 }
346 
347 static int target_if_vdev_mgr_stop_response_handler(ol_scn_t scn,
348 						    uint8_t *data,
349 						    uint32_t datalen)
350 {
351 	QDF_STATUS status = QDF_STATUS_E_INVAL;
352 	struct wlan_objmgr_psoc *psoc;
353 	struct wmi_unified *wmi_handle;
354 	struct wlan_lmac_if_mlme_rx_ops *rx_ops;
355 	struct vdev_stop_response rsp = {0};
356 	uint32_t vdev_id;
357 	struct vdev_response_timer *vdev_rsp;
358 
359 	if (!scn || !data) {
360 		mlme_err("Invalid input");
361 		return -EINVAL;
362 	}
363 
364 	psoc = target_if_get_psoc_from_scn_hdl(scn);
365 	if (!psoc) {
366 		mlme_err("PSOC is NULL");
367 		return -EINVAL;
368 	}
369 
370 	rx_ops = target_if_vdev_mgr_get_rx_ops(psoc);
371 	if (!rx_ops || !rx_ops->vdev_mgr_stop_response) {
372 		mlme_err("No Rx Ops");
373 		return -EINVAL;
374 	}
375 
376 	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
377 	if (!wmi_handle) {
378 		mlme_err("wmi_handle is null");
379 		return -EINVAL;
380 	}
381 
382 	if (wmi_extract_vdev_stopped_param(wmi_handle, data, &vdev_id)) {
383 		mlme_err("WMI extract failed");
384 		return -EINVAL;
385 	}
386 
387 	vdev_rsp = rx_ops->psoc_get_vdev_response_timer_info(psoc, vdev_id);
388 	if (!vdev_rsp) {
389 		mlme_err("vdev response timer is null VDEV_%d PSOC_%d",
390 			 vdev_id, wlan_psoc_get_id(psoc));
391 		return -EINVAL;
392 	}
393 
394 	status = target_if_vdev_mgr_rsp_timer_stop(psoc, vdev_rsp,
395 						   STOP_RESPONSE_BIT);
396 
397 	if (QDF_IS_STATUS_ERROR(status)) {
398 		mlme_err("PSOC_%d VDEV_%d: VDE MGR RSP Timer stop failed",
399 			 psoc->soc_objmgr.psoc_id, vdev_id);
400 		goto err;
401 	}
402 
403 	rsp.vdev_id = vdev_id;
404 	status = rx_ops->vdev_mgr_stop_response(psoc, &rsp);
405 
406 err:
407 	return qdf_status_to_os_return(status);
408 }
409 
410 static int target_if_vdev_mgr_delete_response_handler(ol_scn_t scn,
411 						      uint8_t *data,
412 						      uint32_t datalen)
413 {
414 	QDF_STATUS status = QDF_STATUS_E_INVAL;
415 	struct wlan_objmgr_psoc *psoc;
416 	struct wmi_unified *wmi_handle;
417 	struct wlan_lmac_if_mlme_rx_ops *rx_ops;
418 	struct vdev_delete_response vdev_del_resp = {0};
419 	struct vdev_response_timer *vdev_rsp;
420 
421 	if (!scn || !data) {
422 		mlme_err("Invalid input");
423 		return -EINVAL;
424 	}
425 
426 	psoc = target_if_get_psoc_from_scn_hdl(scn);
427 	if (!psoc) {
428 		mlme_err("PSOC is NULL");
429 		return -EINVAL;
430 	}
431 
432 	rx_ops = target_if_vdev_mgr_get_rx_ops(psoc);
433 	if (!rx_ops || !rx_ops->vdev_mgr_delete_response) {
434 		mlme_err("No Rx Ops");
435 		return -EINVAL;
436 	}
437 
438 	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
439 	if (!wmi_handle) {
440 		mlme_err("wmi_handle is null");
441 		return -EINVAL;
442 	}
443 
444 	if (wmi_extract_vdev_delete_resp(wmi_handle, data, &vdev_del_resp)) {
445 		mlme_err("WMI extract failed");
446 		return -EINVAL;
447 	}
448 
449 	vdev_rsp = rx_ops->psoc_get_vdev_response_timer_info(psoc,
450 							 vdev_del_resp.vdev_id);
451 	if (!vdev_rsp) {
452 		mlme_err("vdev response timer is null VDEV_%d PSOC_%d",
453 			 vdev_del_resp.vdev_id, wlan_psoc_get_id(psoc));
454 		return -EINVAL;
455 	}
456 
457 	status = target_if_vdev_mgr_rsp_timer_stop(
458 						psoc, vdev_rsp,
459 						DELETE_RESPONSE_BIT);
460 
461 	if (QDF_IS_STATUS_ERROR(status)) {
462 		mlme_err("PSOC_%d VDEV_%d: VDE MGR RSP Timer stop failed",
463 			 wlan_psoc_get_id(psoc), vdev_del_resp.vdev_id);
464 		goto err;
465 	}
466 
467 	status = rx_ops->vdev_mgr_delete_response(psoc, &vdev_del_resp);
468 	target_if_wake_lock_timeout_release(psoc, DELETE_WAKELOCK);
469 err:
470 	return qdf_status_to_os_return(status);
471 }
472 
473 static int target_if_vdev_mgr_peer_delete_all_response_handler(
474 							ol_scn_t scn,
475 							uint8_t *data,
476 							uint32_t datalen)
477 {
478 	QDF_STATUS status = QDF_STATUS_E_INVAL;
479 	struct wlan_objmgr_psoc *psoc;
480 	struct wmi_unified *wmi_handle;
481 	struct wlan_lmac_if_mlme_rx_ops *rx_ops;
482 	struct peer_delete_all_response vdev_peer_del_all_resp = {0};
483 	struct vdev_response_timer *vdev_rsp;
484 
485 	if (!scn || !data) {
486 		mlme_err("Invalid input");
487 		return -EINVAL;
488 	}
489 
490 	psoc = target_if_get_psoc_from_scn_hdl(scn);
491 	if (!psoc) {
492 		mlme_err("PSOC is NULL");
493 		return -EINVAL;
494 	}
495 
496 	rx_ops = target_if_vdev_mgr_get_rx_ops(psoc);
497 	if (!rx_ops || !rx_ops->vdev_mgr_peer_delete_all_response) {
498 		mlme_err("No Rx Ops");
499 		return -EINVAL;
500 	}
501 
502 	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
503 	if (!wmi_handle) {
504 		mlme_err("wmi_handle is null");
505 		return -EINVAL;
506 	}
507 
508 	if (wmi_extract_vdev_peer_delete_all_response_event(
509 						wmi_handle, data,
510 						&vdev_peer_del_all_resp)) {
511 		mlme_err("WMI extract failed");
512 		return -EINVAL;
513 	}
514 
515 	vdev_rsp = rx_ops->psoc_get_vdev_response_timer_info(psoc,
516 						vdev_peer_del_all_resp.vdev_id);
517 	if (!vdev_rsp) {
518 		mlme_err("vdev response timer is null VDEV_%d PSOC_%d",
519 			 vdev_peer_del_all_resp.vdev_id,
520 			 wlan_psoc_get_id(psoc));
521 		return -EINVAL;
522 	}
523 
524 	status = target_if_vdev_mgr_rsp_timer_stop(
525 						psoc,
526 						vdev_rsp,
527 						PEER_DELETE_ALL_RESPONSE_BIT);
528 
529 	if (QDF_IS_STATUS_ERROR(status)) {
530 		mlme_err("PSOC_%d VDEV_%d: VDE MGR RSP Timer stop failed",
531 			 psoc->soc_objmgr.psoc_id,
532 			 vdev_peer_del_all_resp.vdev_id);
533 		goto err;
534 	}
535 
536 	vdev_peer_del_all_resp.peer_type_bitmap = vdev_rsp->peer_type_bitmap;
537 
538 	status = rx_ops->vdev_mgr_peer_delete_all_response(
539 						psoc,
540 						&vdev_peer_del_all_resp);
541 
542 err:
543 	return qdf_status_to_os_return(status);
544 }
545 
546 int target_if_vdev_mgr_offload_bcn_tx_status_handler(
547 					ol_scn_t scn,
548 					uint8_t *data,
549 					uint32_t datalen)
550 {
551 	QDF_STATUS status;
552 	struct wlan_objmgr_psoc *psoc;
553 	struct wmi_unified *wmi_handle;
554 	struct wlan_lmac_if_mlme_rx_ops *rx_ops;
555 	uint32_t vdev_id, tx_status;
556 
557 	if (!scn || !data) {
558 		mlme_err("Invalid input");
559 		return -EINVAL;
560 	}
561 	psoc = target_if_get_psoc_from_scn_hdl(scn);
562 	if (!psoc) {
563 		mlme_err("PSOC is NULL");
564 		return -EINVAL;
565 	}
566 
567 	rx_ops = target_if_vdev_mgr_get_rx_ops(psoc);
568 	if (!rx_ops || !rx_ops->vdev_mgr_offload_bcn_tx_status_event_handle) {
569 		mlme_err("No Rx Ops");
570 		return -EINVAL;
571 	}
572 
573 	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
574 	if (!wmi_handle) {
575 		mlme_err("wmi_handle is null");
576 		return -EINVAL;
577 	}
578 
579 	if (wmi_extract_offload_bcn_tx_status_evt(wmi_handle, data,
580 						  &vdev_id, &tx_status)) {
581 		mlme_err("WMI extract failed");
582 		return -EINVAL;
583 	}
584 
585 	status = rx_ops->vdev_mgr_offload_bcn_tx_status_event_handle(
586 								vdev_id,
587 								tx_status);
588 
589 	return qdf_status_to_os_return(status);
590 }
591 
592 int target_if_vdev_mgr_tbttoffset_update_handler(
593 						ol_scn_t scn, uint8_t *data,
594 						uint32_t datalen)
595 {
596 	QDF_STATUS status;
597 	struct wlan_objmgr_psoc *psoc;
598 	struct wmi_unified *wmi_handle;
599 	struct wlan_lmac_if_mlme_rx_ops *rx_ops;
600 	uint32_t num_vdevs = 0;
601 
602 	if (!scn || !data) {
603 		mlme_err("Invalid input");
604 		return -EINVAL;
605 	}
606 	psoc = target_if_get_psoc_from_scn_hdl(scn);
607 	if (!psoc) {
608 		mlme_err("PSOC is NULL");
609 		return -EINVAL;
610 	}
611 
612 	rx_ops = target_if_vdev_mgr_get_rx_ops(psoc);
613 	if (!rx_ops || !rx_ops->vdev_mgr_tbttoffset_update_handle) {
614 		mlme_err("No Rx Ops");
615 		return -EINVAL;
616 	}
617 
618 	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
619 	if (!wmi_handle) {
620 		mlme_err("wmi_handle is null");
621 		return -EINVAL;
622 	}
623 
624 	if (wmi_extract_tbttoffset_num_vdevs(wmi_handle, data, &num_vdevs)) {
625 		mlme_err("WMI extract failed");
626 		return -EINVAL;
627 	}
628 
629 	status = rx_ops->vdev_mgr_tbttoffset_update_handle(num_vdevs,
630 							   false);
631 
632 	return qdf_status_to_os_return(status);
633 }
634 
635 int target_if_vdev_mgr_ext_tbttoffset_update_handler(
636 						ol_scn_t scn,
637 						uint8_t *data,
638 						uint32_t datalen)
639 {
640 	QDF_STATUS status;
641 	struct wlan_objmgr_psoc *psoc;
642 	struct wmi_unified *wmi_handle;
643 	struct wlan_lmac_if_mlme_rx_ops *rx_ops;
644 	uint32_t num_vdevs = 0;
645 
646 	if (!scn || !data) {
647 		mlme_err("Invalid input");
648 		return -EINVAL;
649 	}
650 	psoc = target_if_get_psoc_from_scn_hdl(scn);
651 	if (!psoc) {
652 		mlme_err("PSOC is NULL");
653 		return -EINVAL;
654 	}
655 
656 	rx_ops = target_if_vdev_mgr_get_rx_ops(psoc);
657 	if (!rx_ops || !rx_ops->vdev_mgr_tbttoffset_update_handle) {
658 		mlme_err("No Rx Ops");
659 		return -EINVAL;
660 	}
661 
662 	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
663 	if (!wmi_handle) {
664 		mlme_err("wmi_handle is null");
665 		return -EINVAL;
666 	}
667 
668 	if (wmi_extract_ext_tbttoffset_num_vdevs(wmi_handle, data,
669 						 &num_vdevs)) {
670 		mlme_err("WMI extract failed");
671 		return -EINVAL;
672 	}
673 
674 	status = rx_ops->vdev_mgr_tbttoffset_update_handle(num_vdevs,
675 							   true);
676 
677 	return qdf_status_to_os_return(status);
678 }
679 
680 static int target_if_vdev_mgr_multi_vdev_restart_resp_handler(
681 							ol_scn_t scn,
682 							uint8_t *data,
683 							uint32_t datalen)
684 {
685 	QDF_STATUS status = QDF_STATUS_E_INVAL;
686 	struct wlan_objmgr_psoc *psoc;
687 	struct wmi_unified *wmi_handle;
688 	struct wlan_lmac_if_mlme_rx_ops *rx_ops;
689 	struct multi_vdev_restart_resp restart_resp;
690 	struct vdev_response_timer *vdev_rsp;
691 	uint8_t max_vdevs, vdev_idx;
692 
693 	if (!scn || !data) {
694 		mlme_err("Invalid input");
695 		return -EINVAL;
696 	}
697 
698 	psoc = target_if_get_psoc_from_scn_hdl(scn);
699 	if (!psoc) {
700 		mlme_err("PSOC is NULL");
701 		return -EINVAL;
702 	}
703 
704 	rx_ops = target_if_vdev_mgr_get_rx_ops(psoc);
705 	if (!rx_ops || !rx_ops->vdev_mgr_multi_vdev_restart_resp ||
706 	    !rx_ops->psoc_get_vdev_response_timer_info) {
707 		mlme_err("No Rx Ops");
708 		return -EINVAL;
709 	}
710 
711 	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
712 	if (!wmi_handle) {
713 		mlme_err("wmi_handle is null");
714 		return -EINVAL;
715 	}
716 
717 	qdf_mem_zero(&restart_resp, sizeof(restart_resp));
718 	if (wmi_extract_multi_vdev_restart_resp_event(wmi_handle, data,
719 						      &restart_resp)) {
720 		mlme_err("WMI extract failed");
721 		return -EINVAL;
722 	}
723 
724 	max_vdevs = wlan_psoc_get_max_vdev_count(psoc);
725 	for (vdev_idx = 0; vdev_idx < max_vdevs; vdev_idx++) {
726 		if (!qdf_test_bit(vdev_idx, restart_resp.vdev_id_bmap))
727 			continue;
728 
729 		mlme_debug("PSOC_%d VDEV_%d: Restart resp received",
730 			   wlan_psoc_get_id(psoc), vdev_idx);
731 		vdev_rsp = rx_ops->psoc_get_vdev_response_timer_info(psoc,
732 								     vdev_idx);
733 		if (!vdev_rsp) {
734 			mlme_err("PSOC_%d VDEV_%d: VDEV RSP is NULL",
735 				 wlan_psoc_get_id(psoc), vdev_idx);
736 			continue;
737 		}
738 
739 		status = target_if_vdev_mgr_rsp_timer_stop(
740 				psoc, vdev_rsp, RESTART_RESPONSE_BIT);
741 		if (QDF_IS_STATUS_ERROR(status))
742 			mlme_err("PSOC_%d VDEV_%d: VDE MGR RSP Timer stop failed",
743 				 wlan_psoc_get_id(psoc), vdev_idx);
744 	}
745 
746 	status = rx_ops->vdev_mgr_multi_vdev_restart_resp(psoc, &restart_resp);
747 
748 	return qdf_status_to_os_return(status);
749 }
750 
751 /**
752  * target_if_vdev_csa_complete - CSA complete event handler
753  * @psoc: psoc
754  * @vdev_id: vdev id
755  *
756  * Return: 0 on success
757  */
758 static int target_if_vdev_csa_complete(struct wlan_objmgr_psoc *psoc,
759 				       uint8_t vdev_id)
760 {
761 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
762 	struct vdev_mlme_obj *vdev_mlme;
763 	struct wlan_objmgr_vdev *vdev;
764 	int ret = 0;
765 
766 	if (!psoc) {
767 		mlme_err("Invalid input");
768 		return -EINVAL;
769 	}
770 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
771 						    WLAN_VDEV_TARGET_IF_ID);
772 	if (!vdev) {
773 		mlme_err("VDEV is NULL");
774 		return -EINVAL;
775 	}
776 	vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev);
777 	if (!vdev_mlme) {
778 		mlme_err("VDEV_%d: PSOC_%d VDEV_MLME is NULL", vdev_id,
779 			 wlan_psoc_get_id(psoc));
780 		ret = -EINVAL;
781 		goto end;
782 	}
783 
784 	if ((vdev_mlme->ops) && vdev_mlme->ops->mlme_vdev_csa_complete) {
785 		status = vdev_mlme->ops->mlme_vdev_csa_complete(vdev_mlme);
786 		if (QDF_IS_STATUS_ERROR(status)) {
787 			mlme_err("vdev csa complete failed");
788 			ret = -EINVAL;
789 		}
790 	}
791 end:
792 	wlan_objmgr_vdev_release_ref(vdev, WLAN_VDEV_TARGET_IF_ID);
793 	return ret;
794 }
795 
796 /**
797  * target_if_pdev_csa_status_event_handler - CSA event handler
798  * @scn: Pointer to scn structure
799  * @data: pointer to event data
800  * @datalen: event data length
801  *
802  * Return: 0 on success
803  */
804 static int target_if_pdev_csa_status_event_handler(
805 		ol_scn_t scn,
806 		uint8_t *data,
807 		uint32_t datalen)
808 {
809 	struct pdev_csa_switch_count_status csa_status;
810 	struct wlan_objmgr_psoc *psoc;
811 	struct wmi_unified *wmi_handle;
812 	struct target_psoc_info *tgt_hdl;
813 	int i;
814 	QDF_STATUS status;
815 	struct wlan_lmac_if_mlme_rx_ops *rx_ops = NULL;
816 
817 	if (!scn || !data) {
818 		mlme_err("Invalid input");
819 		return -EINVAL;
820 	}
821 
822 	psoc = target_if_get_psoc_from_scn_hdl(scn);
823 	if (!psoc) {
824 		mlme_err("PSOC is NULL");
825 		return -EINVAL;
826 	}
827 
828 	rx_ops = target_if_vdev_mgr_get_rx_ops(psoc);
829 	if (!rx_ops || !rx_ops->vdev_mgr_set_max_channel_switch_time) {
830 		mlme_err("No Rx Ops");
831 		return -EINVAL;
832 	}
833 
834 	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
835 	if (!wmi_handle) {
836 		mlme_err("wmi_handle is null");
837 		return -EINVAL;
838 	}
839 
840 	tgt_hdl = wlan_psoc_get_tgt_if_handle(psoc);
841 	if (!tgt_hdl) {
842 		mlme_err("target_psoc_info is null");
843 		return -EINVAL;
844 	}
845 
846 	qdf_mem_zero(&csa_status, sizeof(csa_status));
847 	status = wmi_extract_pdev_csa_switch_count_status(
848 			wmi_handle, data, &csa_status);
849 	if (QDF_IS_STATUS_ERROR(status)) {
850 		mlme_err("Extracting CSA switch count status event failed");
851 		return -EINVAL;
852 	}
853 
854 	if (csa_status.current_switch_count == 1)
855 		rx_ops->vdev_mgr_set_max_channel_switch_time
856 			(psoc, csa_status.vdev_ids, csa_status.num_vdevs);
857 
858 	if (wlan_psoc_nif_fw_ext_cap_get(psoc, WLAN_SOC_CEXT_CSA_TX_OFFLOAD)) {
859 		for (i = 0; i < csa_status.num_vdevs; i++) {
860 			if (!csa_status.current_switch_count)
861 				target_if_vdev_csa_complete(psoc,
862 							csa_status.vdev_ids[i]);
863 		}
864 	}
865 
866 	return target_if_csa_switch_count_status(psoc, tgt_hdl, csa_status);
867 }
868 
869 #ifdef WLAN_FEATURE_DYNAMIC_MAC_ADDR_UPDATE
870 /**
871  * target_if_update_macaddr_conf_evt_handler() - Set MAC address confirmation
872  *                                               event handler
873  * @scn: Pointer to scn structure
874  * @event_buff: event data
875  * @len: length
876  *
877  * Response handler for set MAC address request command.
878  *
879  * Return: 0 for success or error code
880  */
881 static int target_if_update_macaddr_conf_evt_handler(ol_scn_t scn,
882 						     uint8_t *event_buff,
883 						     uint32_t len)
884 {
885 	struct wlan_objmgr_psoc *psoc;
886 	struct wmi_unified *wmi_handle;
887 	uint8_t vdev_id, resp_status;
888 	QDF_STATUS status;
889 	struct wlan_lmac_if_mlme_rx_ops *rx_ops;
890 
891 	if (!event_buff) {
892 		mlme_err("Received NULL event ptr from FW");
893 		return -EINVAL;
894 	}
895 
896 	psoc = target_if_get_psoc_from_scn_hdl(scn);
897 	if (!psoc) {
898 		mlme_err("PSOC is NULL");
899 		return -EINVAL;
900 	}
901 
902 	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
903 	if (!wmi_handle) {
904 		mlme_err("wmi_handle is null");
905 		return -EINVAL;
906 	}
907 
908 	status = wmi_extract_update_mac_address_event(wmi_handle, event_buff,
909 						      &vdev_id, &resp_status);
910 	if (QDF_IS_STATUS_ERROR(status)) {
911 		mlme_err("Failed to extract update MAC address event");
912 		return -EINVAL;
913 	}
914 
915 	rx_ops = target_if_vdev_mgr_get_rx_ops(psoc);
916 	if (!rx_ops || !rx_ops->vdev_mgr_set_mac_addr_response) {
917 		mlme_err("No Rx Ops");
918 		return -EINVAL;
919 	}
920 
921 	rx_ops->vdev_mgr_set_mac_addr_response(vdev_id, resp_status);
922 
923 	return 0;
924 }
925 
926 static inline void
927 target_if_register_set_mac_addr_evt_cbk(struct wmi_unified *wmi_handle)
928 {
929 	wmi_unified_register_event_handler(
930 		   wmi_handle, wmi_vdev_update_mac_addr_conf_eventid,
931 		   target_if_update_macaddr_conf_evt_handler, VDEV_RSP_RX_CTX);
932 }
933 
934 static inline void
935 target_if_unregister_set_mac_addr_evt_cbk(struct wmi_unified *wmi_handle)
936 {
937 	wmi_unified_unregister_event_handler(
938 			wmi_handle, wmi_vdev_update_mac_addr_conf_eventid);
939 }
940 #else
941 static inline void
942 target_if_register_set_mac_addr_evt_cbk(struct wmi_unified *wmi_handle)
943 {
944 }
945 
946 static inline void
947 target_if_unregister_set_mac_addr_evt_cbk(struct wmi_unified *wmi_handle)
948 {
949 }
950 #endif
951 
952 #ifdef WLAN_FEATURE_11BE_MLO
953 /**
954  * target_if_quiet_offload_event_handler() - Quiet IE offload mlo
955  *                                           station event handler
956  * @scn: Pointer to scn structure
957  * @event_buff: event data
958  * @len: length
959  *
960  * Return: 0 for success or error code
961  */
962 static int target_if_quiet_offload_event_handler(ol_scn_t scn,
963 						 uint8_t *event_buff,
964 						 uint32_t len)
965 {
966 	struct wlan_objmgr_psoc *psoc;
967 	struct wmi_unified *wmi_handle;
968 	QDF_STATUS status;
969 	struct wlan_lmac_if_mlme_rx_ops *rx_ops;
970 	struct vdev_sta_quiet_event sta_quiet_event = {0};
971 
972 	if (!event_buff) {
973 		mlme_err("Received NULL event ptr from FW");
974 		return -EINVAL;
975 	}
976 
977 	psoc = target_if_get_psoc_from_scn_hdl(scn);
978 	if (!psoc) {
979 		mlme_err("PSOC is NULL");
980 		return -EINVAL;
981 	}
982 
983 	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
984 	if (!wmi_handle) {
985 		mlme_err("wmi_handle is null");
986 		return -EINVAL;
987 	}
988 
989 	status = wmi_extract_quiet_offload_event(wmi_handle, event_buff,
990 						 &sta_quiet_event);
991 	if (QDF_IS_STATUS_ERROR(status)) {
992 		mlme_err("Failed to extract quiet IE offload event");
993 		return -EINVAL;
994 	}
995 
996 	rx_ops = target_if_vdev_mgr_get_rx_ops(psoc);
997 	if (!rx_ops || !rx_ops->vdev_mgr_quiet_offload) {
998 		mlme_err("No Rx Ops");
999 		return -EINVAL;
1000 	}
1001 
1002 	rx_ops->vdev_mgr_quiet_offload(psoc, &sta_quiet_event);
1003 
1004 	return 0;
1005 }
1006 
1007 static inline void
1008 target_if_register_quiet_offload_event(struct wmi_unified *wmi_handle)
1009 {
1010 	wmi_unified_register_event_handler(
1011 		   wmi_handle, wmi_vdev_quiet_offload_eventid,
1012 		   target_if_quiet_offload_event_handler, VDEV_RSP_RX_CTX);
1013 }
1014 
1015 static inline void
1016 target_if_unregister_quiet_offload_event(struct wmi_unified *wmi_handle)
1017 {
1018 	wmi_unified_unregister_event_handler(
1019 			wmi_handle, wmi_vdev_quiet_offload_eventid);
1020 }
1021 #else
1022 static inline void
1023 target_if_register_quiet_offload_event(struct wmi_unified *wmi_handle)
1024 {
1025 }
1026 
1027 static inline void
1028 target_if_unregister_quiet_offload_event(struct wmi_unified *wmi_handle)
1029 {
1030 }
1031 #endif
1032 
1033 QDF_STATUS target_if_vdev_mgr_wmi_event_register(
1034 				struct wlan_objmgr_psoc *psoc)
1035 {
1036 	QDF_STATUS retval = QDF_STATUS_SUCCESS;
1037 	struct wmi_unified *wmi_handle;
1038 
1039 	if (!psoc) {
1040 		mlme_err("PSOC is NULL");
1041 		return QDF_STATUS_E_NULL_VALUE;
1042 	}
1043 
1044 	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
1045 	if (!wmi_handle) {
1046 		mlme_err("wmi_handle is null");
1047 		return QDF_STATUS_E_INVAL;
1048 	}
1049 
1050 	retval = wmi_unified_register_event_handler(
1051 				wmi_handle,
1052 				wmi_vdev_stopped_event_id,
1053 				target_if_vdev_mgr_stop_response_handler,
1054 				VDEV_RSP_RX_CTX);
1055 	if (QDF_IS_STATUS_ERROR(retval))
1056 		mlme_err("failed to register for stop response");
1057 
1058 	retval = wmi_unified_register_event_handler(
1059 				wmi_handle,
1060 				wmi_vdev_delete_resp_event_id,
1061 				target_if_vdev_mgr_delete_response_handler,
1062 				VDEV_RSP_RX_CTX);
1063 	if (QDF_IS_STATUS_ERROR(retval))
1064 		mlme_err("failed to register for delete response");
1065 
1066 	retval = wmi_unified_register_event_handler(
1067 				wmi_handle,
1068 				wmi_vdev_start_resp_event_id,
1069 				target_if_vdev_mgr_start_response_handler,
1070 				VDEV_RSP_RX_CTX);
1071 	if (QDF_IS_STATUS_ERROR(retval))
1072 		mlme_err("failed to register for start response");
1073 
1074 	retval = wmi_unified_register_event_handler(
1075 			wmi_handle,
1076 			wmi_peer_delete_all_response_event_id,
1077 			target_if_vdev_mgr_peer_delete_all_response_handler,
1078 			VDEV_RSP_RX_CTX);
1079 	if (QDF_IS_STATUS_ERROR(retval))
1080 		mlme_err("failed to register for peer delete all response");
1081 
1082 	retval = wmi_unified_register_event_handler(
1083 			wmi_handle,
1084 			wmi_pdev_multi_vdev_restart_response_event_id,
1085 			target_if_vdev_mgr_multi_vdev_restart_resp_handler,
1086 			VDEV_RSP_RX_CTX);
1087 	if (QDF_IS_STATUS_ERROR(retval))
1088 		mlme_err("failed to register for multivdev restart response");
1089 
1090 	if (wmi_service_enabled(wmi_handle, wmi_service_beacon_offload)) {
1091 		retval = wmi_unified_register_event_handler(
1092 				wmi_handle,
1093 				wmi_pdev_csa_switch_count_status_event_id,
1094 				target_if_pdev_csa_status_event_handler,
1095 				VDEV_RSP_RX_CTX);
1096 		if (QDF_IS_STATUS_ERROR(retval))
1097 			mlme_err("failed to register for csa event handler");
1098 	}
1099 
1100 	target_if_register_set_mac_addr_evt_cbk(wmi_handle);
1101 
1102 	target_if_register_quiet_offload_event(wmi_handle);
1103 
1104 	return retval;
1105 }
1106 
1107 QDF_STATUS target_if_vdev_mgr_wmi_event_unregister(
1108 					struct wlan_objmgr_psoc *psoc)
1109 {
1110 	struct wmi_unified *wmi_handle;
1111 
1112 	if (!psoc) {
1113 		mlme_err("PSOC is NULL");
1114 		return QDF_STATUS_E_INVAL;
1115 	}
1116 
1117 	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
1118 	if (!wmi_handle) {
1119 		mlme_err("wmi_handle is null");
1120 		return QDF_STATUS_E_INVAL;
1121 	}
1122 
1123 	target_if_unregister_quiet_offload_event(wmi_handle);
1124 
1125 	target_if_unregister_set_mac_addr_evt_cbk(wmi_handle);
1126 
1127 	wmi_unified_unregister_event_handler(
1128 			wmi_handle,
1129 			wmi_pdev_multi_vdev_restart_response_event_id);
1130 
1131 	wmi_unified_unregister_event_handler(
1132 			wmi_handle,
1133 			wmi_peer_delete_all_response_event_id);
1134 
1135 	wmi_unified_unregister_event_handler(wmi_handle,
1136 					     wmi_vdev_start_resp_event_id);
1137 
1138 	wmi_unified_unregister_event_handler(wmi_handle,
1139 					     wmi_vdev_delete_resp_event_id);
1140 
1141 	wmi_unified_unregister_event_handler(wmi_handle,
1142 					     wmi_vdev_stopped_event_id);
1143 
1144 	return QDF_STATUS_SUCCESS;
1145 }
1146