xref: /wlan-dirver/qca-wifi-host-cmn/target_if/mlme/vdev_mgr/src/target_if_vdev_mgr_rx_ops.c (revision 8cfe6b10058a04cafb17eed051f2ddf11bee8931)
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_mc(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 = scheduler_qdf_mc_timer_deinit_return_data_ptr(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 	struct sched_qdf_mc_timer_cb_wrapper *mc_timer_wrapper;
232 
233 	psoc = vdev_rsp->psoc;
234 	if (!psoc) {
235 		mlme_err("PSOC is NULL");
236 		return;
237 	}
238 
239 	msg.type = SYS_MSG_ID_MC_TIMER;
240 	msg.reserved = SYS_MSG_COOKIE;
241 
242 	mc_timer_wrapper = scheduler_qdf_mc_timer_init(
243 			target_if_vdev_mgr_rsp_timer_cb,
244 			arg);
245 
246 	if (!mc_timer_wrapper) {
247 		mlme_err("failed to allocate sched_qdf_mc_timer_cb_wrapper");
248 		return;
249 	}
250 
251 	msg.callback = scheduler_qdf_mc_timer_callback_t_wrapper;
252 	msg.bodyptr = mc_timer_wrapper;
253 	msg.bodyval = 0;
254 	msg.flush_callback = target_if_vdev_mgr_rsp_flush_cb_mc;
255 
256 	if (scheduler_post_message(QDF_MODULE_ID_TARGET_IF,
257 				   QDF_MODULE_ID_TARGET_IF,
258 				   QDF_MODULE_ID_SYS, &msg) ==
259 				   QDF_STATUS_SUCCESS)
260 		return;
261 
262 	mlme_err("Could not enqueue timer to timer queue");
263 	qdf_mem_free(mc_timer_wrapper);
264 	if (psoc)
265 		wlan_objmgr_psoc_release_ref(psoc, WLAN_PSOC_TARGET_IF_ID);
266 }
267 
268 void target_if_vdev_mgr_rsp_timer_mgmt_cb(void *arg)
269 {
270 	target_if_vdev_mgr_rsp_cb_mc_ctx(arg);
271 }
272 
273 #define VDEV_RSP_RX_CTX WMI_RX_SERIALIZER_CTX
274 #else
275 void target_if_vdev_mgr_rsp_timer_mgmt_cb(void *arg)
276 {
277 	target_if_vdev_mgr_rsp_timer_cb(arg);
278 }
279 
280 #define VDEV_RSP_RX_CTX WMI_RX_UMAC_CTX
281 #endif
282 
283 static int target_if_vdev_mgr_start_response_handler(ol_scn_t scn,
284 						     uint8_t *data,
285 						     uint32_t datalen)
286 {
287 	QDF_STATUS status = QDF_STATUS_E_INVAL;
288 	struct wlan_objmgr_psoc *psoc;
289 	struct wmi_unified *wmi_handle;
290 	struct wlan_lmac_if_mlme_rx_ops *rx_ops;
291 	struct vdev_start_response vdev_start_resp = {0};
292 	uint8_t vdev_id;
293 	struct vdev_response_timer *vdev_rsp;
294 
295 	if (!scn || !data) {
296 		mlme_err("Invalid input");
297 		return -EINVAL;
298 	}
299 
300 	psoc = target_if_get_psoc_from_scn_hdl(scn);
301 	if (!psoc) {
302 		mlme_err("PSOC is NULL");
303 		return -EINVAL;
304 	}
305 
306 	rx_ops = target_if_vdev_mgr_get_rx_ops(psoc);
307 	if (!rx_ops || !rx_ops->vdev_mgr_start_response) {
308 		mlme_err("No Rx Ops");
309 		return -EINVAL;
310 	}
311 
312 	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
313 	if (!wmi_handle) {
314 		mlme_err("wmi_handle is null");
315 		return -EINVAL;
316 	}
317 
318 	if (wmi_extract_vdev_start_resp(wmi_handle, data, &vdev_start_resp)) {
319 		mlme_err("WMI extract failed");
320 		return -EINVAL;
321 	}
322 
323 	vdev_id = vdev_start_resp.vdev_id;
324 	vdev_rsp = rx_ops->psoc_get_vdev_response_timer_info(psoc, vdev_id);
325 	if (!vdev_rsp) {
326 		mlme_err("vdev response timer is null VDEV_%d PSOC_%d",
327 			 vdev_id, wlan_psoc_get_id(psoc));
328 		return -EINVAL;
329 	}
330 
331 	if (vdev_start_resp.resp_type == WMI_HOST_VDEV_RESTART_RESP_EVENT)
332 		status = target_if_vdev_mgr_rsp_timer_stop(
333 							psoc, vdev_rsp,
334 							RESTART_RESPONSE_BIT);
335 	else
336 		status = target_if_vdev_mgr_rsp_timer_stop(psoc, vdev_rsp,
337 							   START_RESPONSE_BIT);
338 
339 	if (QDF_IS_STATUS_ERROR(status)) {
340 		mlme_err("PSOC_%d VDEV_%d: VDE MGR RSP Timer stop failed",
341 			 psoc->soc_objmgr.psoc_id, vdev_id);
342 		goto err;
343 	}
344 
345 	status = rx_ops->vdev_mgr_start_response(psoc, &vdev_start_resp);
346 
347 err:
348 	return qdf_status_to_os_return(status);
349 }
350 
351 static int target_if_vdev_mgr_stop_response_handler(ol_scn_t scn,
352 						    uint8_t *data,
353 						    uint32_t datalen)
354 {
355 	QDF_STATUS status = QDF_STATUS_E_INVAL;
356 	struct wlan_objmgr_psoc *psoc;
357 	struct wmi_unified *wmi_handle;
358 	struct wlan_lmac_if_mlme_rx_ops *rx_ops;
359 	struct vdev_stop_response rsp = {0};
360 	uint32_t vdev_id;
361 	struct vdev_response_timer *vdev_rsp;
362 
363 	if (!scn || !data) {
364 		mlme_err("Invalid input");
365 		return -EINVAL;
366 	}
367 
368 	psoc = target_if_get_psoc_from_scn_hdl(scn);
369 	if (!psoc) {
370 		mlme_err("PSOC is NULL");
371 		return -EINVAL;
372 	}
373 
374 	rx_ops = target_if_vdev_mgr_get_rx_ops(psoc);
375 	if (!rx_ops || !rx_ops->vdev_mgr_stop_response) {
376 		mlme_err("No Rx Ops");
377 		return -EINVAL;
378 	}
379 
380 	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
381 	if (!wmi_handle) {
382 		mlme_err("wmi_handle is null");
383 		return -EINVAL;
384 	}
385 
386 	if (wmi_extract_vdev_stopped_param(wmi_handle, data, &vdev_id)) {
387 		mlme_err("WMI extract failed");
388 		return -EINVAL;
389 	}
390 
391 	vdev_rsp = rx_ops->psoc_get_vdev_response_timer_info(psoc, vdev_id);
392 	if (!vdev_rsp) {
393 		mlme_err("vdev response timer is null VDEV_%d PSOC_%d",
394 			 vdev_id, wlan_psoc_get_id(psoc));
395 		return -EINVAL;
396 	}
397 
398 	status = target_if_vdev_mgr_rsp_timer_stop(psoc, vdev_rsp,
399 						   STOP_RESPONSE_BIT);
400 
401 	if (QDF_IS_STATUS_ERROR(status)) {
402 		mlme_err("PSOC_%d VDEV_%d: VDE MGR RSP Timer stop failed",
403 			 psoc->soc_objmgr.psoc_id, vdev_id);
404 		goto err;
405 	}
406 
407 	rsp.vdev_id = vdev_id;
408 	status = rx_ops->vdev_mgr_stop_response(psoc, &rsp);
409 
410 err:
411 	return qdf_status_to_os_return(status);
412 }
413 
414 static int target_if_vdev_mgr_delete_response_handler(ol_scn_t scn,
415 						      uint8_t *data,
416 						      uint32_t datalen)
417 {
418 	QDF_STATUS status = QDF_STATUS_E_INVAL;
419 	struct wlan_objmgr_psoc *psoc;
420 	struct wmi_unified *wmi_handle;
421 	struct wlan_lmac_if_mlme_rx_ops *rx_ops;
422 	struct vdev_delete_response vdev_del_resp = {0};
423 	struct vdev_response_timer *vdev_rsp;
424 
425 	if (!scn || !data) {
426 		mlme_err("Invalid input");
427 		return -EINVAL;
428 	}
429 
430 	psoc = target_if_get_psoc_from_scn_hdl(scn);
431 	if (!psoc) {
432 		mlme_err("PSOC is NULL");
433 		return -EINVAL;
434 	}
435 
436 	rx_ops = target_if_vdev_mgr_get_rx_ops(psoc);
437 	if (!rx_ops || !rx_ops->vdev_mgr_delete_response) {
438 		mlme_err("No Rx Ops");
439 		return -EINVAL;
440 	}
441 
442 	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
443 	if (!wmi_handle) {
444 		mlme_err("wmi_handle is null");
445 		return -EINVAL;
446 	}
447 
448 	if (wmi_extract_vdev_delete_resp(wmi_handle, data, &vdev_del_resp)) {
449 		mlme_err("WMI extract failed");
450 		return -EINVAL;
451 	}
452 
453 	vdev_rsp = rx_ops->psoc_get_vdev_response_timer_info(psoc,
454 							 vdev_del_resp.vdev_id);
455 	if (!vdev_rsp) {
456 		mlme_err("vdev response timer is null VDEV_%d PSOC_%d",
457 			 vdev_del_resp.vdev_id, wlan_psoc_get_id(psoc));
458 		return -EINVAL;
459 	}
460 
461 	status = target_if_vdev_mgr_rsp_timer_stop(
462 						psoc, vdev_rsp,
463 						DELETE_RESPONSE_BIT);
464 
465 	if (QDF_IS_STATUS_ERROR(status)) {
466 		mlme_err("PSOC_%d VDEV_%d: VDE MGR RSP Timer stop failed",
467 			 wlan_psoc_get_id(psoc), vdev_del_resp.vdev_id);
468 		goto err;
469 	}
470 
471 	status = rx_ops->vdev_mgr_delete_response(psoc, &vdev_del_resp);
472 	target_if_wake_lock_timeout_release(psoc, DELETE_WAKELOCK);
473 err:
474 	return qdf_status_to_os_return(status);
475 }
476 
477 static int target_if_vdev_mgr_peer_delete_all_response_handler(
478 							ol_scn_t scn,
479 							uint8_t *data,
480 							uint32_t datalen)
481 {
482 	QDF_STATUS status = QDF_STATUS_E_INVAL;
483 	struct wlan_objmgr_psoc *psoc;
484 	struct wmi_unified *wmi_handle;
485 	struct wlan_lmac_if_mlme_rx_ops *rx_ops;
486 	struct peer_delete_all_response vdev_peer_del_all_resp = {0};
487 	struct vdev_response_timer *vdev_rsp;
488 
489 	if (!scn || !data) {
490 		mlme_err("Invalid input");
491 		return -EINVAL;
492 	}
493 
494 	psoc = target_if_get_psoc_from_scn_hdl(scn);
495 	if (!psoc) {
496 		mlme_err("PSOC is NULL");
497 		return -EINVAL;
498 	}
499 
500 	rx_ops = target_if_vdev_mgr_get_rx_ops(psoc);
501 	if (!rx_ops || !rx_ops->vdev_mgr_peer_delete_all_response) {
502 		mlme_err("No Rx Ops");
503 		return -EINVAL;
504 	}
505 
506 	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
507 	if (!wmi_handle) {
508 		mlme_err("wmi_handle is null");
509 		return -EINVAL;
510 	}
511 
512 	if (wmi_extract_vdev_peer_delete_all_response_event(
513 						wmi_handle, data,
514 						&vdev_peer_del_all_resp)) {
515 		mlme_err("WMI extract failed");
516 		return -EINVAL;
517 	}
518 
519 	vdev_rsp = rx_ops->psoc_get_vdev_response_timer_info(psoc,
520 						vdev_peer_del_all_resp.vdev_id);
521 	if (!vdev_rsp) {
522 		mlme_err("vdev response timer is null VDEV_%d PSOC_%d",
523 			 vdev_peer_del_all_resp.vdev_id,
524 			 wlan_psoc_get_id(psoc));
525 		return -EINVAL;
526 	}
527 
528 	status = target_if_vdev_mgr_rsp_timer_stop(
529 						psoc,
530 						vdev_rsp,
531 						PEER_DELETE_ALL_RESPONSE_BIT);
532 
533 	if (QDF_IS_STATUS_ERROR(status)) {
534 		mlme_err("PSOC_%d VDEV_%d: VDE MGR RSP Timer stop failed",
535 			 psoc->soc_objmgr.psoc_id,
536 			 vdev_peer_del_all_resp.vdev_id);
537 		goto err;
538 	}
539 
540 	vdev_peer_del_all_resp.peer_type_bitmap = vdev_rsp->peer_type_bitmap;
541 
542 	status = rx_ops->vdev_mgr_peer_delete_all_response(
543 						psoc,
544 						&vdev_peer_del_all_resp);
545 
546 err:
547 	return qdf_status_to_os_return(status);
548 }
549 
550 int target_if_vdev_mgr_offload_bcn_tx_status_handler(
551 					ol_scn_t scn,
552 					uint8_t *data,
553 					uint32_t datalen)
554 {
555 	QDF_STATUS status;
556 	struct wlan_objmgr_psoc *psoc;
557 	struct wmi_unified *wmi_handle;
558 	struct wlan_lmac_if_mlme_rx_ops *rx_ops;
559 	uint32_t vdev_id, tx_status;
560 
561 	if (!scn || !data) {
562 		mlme_err("Invalid input");
563 		return -EINVAL;
564 	}
565 	psoc = target_if_get_psoc_from_scn_hdl(scn);
566 	if (!psoc) {
567 		mlme_err("PSOC is NULL");
568 		return -EINVAL;
569 	}
570 
571 	rx_ops = target_if_vdev_mgr_get_rx_ops(psoc);
572 	if (!rx_ops || !rx_ops->vdev_mgr_offload_bcn_tx_status_event_handle) {
573 		mlme_err("No Rx Ops");
574 		return -EINVAL;
575 	}
576 
577 	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
578 	if (!wmi_handle) {
579 		mlme_err("wmi_handle is null");
580 		return -EINVAL;
581 	}
582 
583 	if (wmi_extract_offload_bcn_tx_status_evt(wmi_handle, data,
584 						  &vdev_id, &tx_status)) {
585 		mlme_err("WMI extract failed");
586 		return -EINVAL;
587 	}
588 
589 	status = rx_ops->vdev_mgr_offload_bcn_tx_status_event_handle(
590 								vdev_id,
591 								tx_status);
592 
593 	return qdf_status_to_os_return(status);
594 }
595 
596 int target_if_vdev_mgr_tbttoffset_update_handler(
597 						ol_scn_t scn, uint8_t *data,
598 						uint32_t datalen)
599 {
600 	QDF_STATUS status;
601 	struct wlan_objmgr_psoc *psoc;
602 	struct wmi_unified *wmi_handle;
603 	struct wlan_lmac_if_mlme_rx_ops *rx_ops;
604 	uint32_t num_vdevs = 0;
605 
606 	if (!scn || !data) {
607 		mlme_err("Invalid input");
608 		return -EINVAL;
609 	}
610 	psoc = target_if_get_psoc_from_scn_hdl(scn);
611 	if (!psoc) {
612 		mlme_err("PSOC is NULL");
613 		return -EINVAL;
614 	}
615 
616 	rx_ops = target_if_vdev_mgr_get_rx_ops(psoc);
617 	if (!rx_ops || !rx_ops->vdev_mgr_tbttoffset_update_handle) {
618 		mlme_err("No Rx Ops");
619 		return -EINVAL;
620 	}
621 
622 	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
623 	if (!wmi_handle) {
624 		mlme_err("wmi_handle is null");
625 		return -EINVAL;
626 	}
627 
628 	if (wmi_extract_tbttoffset_num_vdevs(wmi_handle, data, &num_vdevs)) {
629 		mlme_err("WMI extract failed");
630 		return -EINVAL;
631 	}
632 
633 	status = rx_ops->vdev_mgr_tbttoffset_update_handle(num_vdevs,
634 							   false);
635 
636 	return qdf_status_to_os_return(status);
637 }
638 
639 int target_if_vdev_mgr_ext_tbttoffset_update_handler(
640 						ol_scn_t scn,
641 						uint8_t *data,
642 						uint32_t datalen)
643 {
644 	QDF_STATUS status;
645 	struct wlan_objmgr_psoc *psoc;
646 	struct wmi_unified *wmi_handle;
647 	struct wlan_lmac_if_mlme_rx_ops *rx_ops;
648 	uint32_t num_vdevs = 0;
649 
650 	if (!scn || !data) {
651 		mlme_err("Invalid input");
652 		return -EINVAL;
653 	}
654 	psoc = target_if_get_psoc_from_scn_hdl(scn);
655 	if (!psoc) {
656 		mlme_err("PSOC is NULL");
657 		return -EINVAL;
658 	}
659 
660 	rx_ops = target_if_vdev_mgr_get_rx_ops(psoc);
661 	if (!rx_ops || !rx_ops->vdev_mgr_tbttoffset_update_handle) {
662 		mlme_err("No Rx Ops");
663 		return -EINVAL;
664 	}
665 
666 	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
667 	if (!wmi_handle) {
668 		mlme_err("wmi_handle is null");
669 		return -EINVAL;
670 	}
671 
672 	if (wmi_extract_ext_tbttoffset_num_vdevs(wmi_handle, data,
673 						 &num_vdevs)) {
674 		mlme_err("WMI extract failed");
675 		return -EINVAL;
676 	}
677 
678 	status = rx_ops->vdev_mgr_tbttoffset_update_handle(num_vdevs,
679 							   true);
680 
681 	return qdf_status_to_os_return(status);
682 }
683 
684 static int target_if_vdev_mgr_multi_vdev_restart_resp_handler(
685 							ol_scn_t scn,
686 							uint8_t *data,
687 							uint32_t datalen)
688 {
689 	QDF_STATUS status = QDF_STATUS_E_INVAL;
690 	struct wlan_objmgr_psoc *psoc;
691 	struct wmi_unified *wmi_handle;
692 	struct wlan_lmac_if_mlme_rx_ops *rx_ops;
693 	struct multi_vdev_restart_resp restart_resp;
694 	struct vdev_response_timer *vdev_rsp;
695 	uint8_t max_vdevs, vdev_idx;
696 
697 	if (!scn || !data) {
698 		mlme_err("Invalid input");
699 		return -EINVAL;
700 	}
701 
702 	psoc = target_if_get_psoc_from_scn_hdl(scn);
703 	if (!psoc) {
704 		mlme_err("PSOC is NULL");
705 		return -EINVAL;
706 	}
707 
708 	rx_ops = target_if_vdev_mgr_get_rx_ops(psoc);
709 	if (!rx_ops || !rx_ops->vdev_mgr_multi_vdev_restart_resp ||
710 	    !rx_ops->psoc_get_vdev_response_timer_info) {
711 		mlme_err("No Rx Ops");
712 		return -EINVAL;
713 	}
714 
715 	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
716 	if (!wmi_handle) {
717 		mlme_err("wmi_handle is null");
718 		return -EINVAL;
719 	}
720 
721 	qdf_mem_zero(&restart_resp, sizeof(restart_resp));
722 	restart_resp.timestamp = qdf_get_log_timestamp();
723 	if (wmi_extract_multi_vdev_restart_resp_event(wmi_handle, data,
724 						      &restart_resp)) {
725 		mlme_err("WMI extract failed");
726 		return -EINVAL;
727 	}
728 
729 	max_vdevs = wlan_psoc_get_max_vdev_count(psoc);
730 	for (vdev_idx = 0; vdev_idx < max_vdevs; vdev_idx++) {
731 		if (!qdf_test_bit(vdev_idx, restart_resp.vdev_id_bmap))
732 			continue;
733 
734 		mlme_debug("PSOC_%d VDEV_%d: Restart resp received",
735 			   wlan_psoc_get_id(psoc), vdev_idx);
736 		vdev_rsp = rx_ops->psoc_get_vdev_response_timer_info(psoc,
737 								     vdev_idx);
738 		if (!vdev_rsp) {
739 			mlme_err("PSOC_%d VDEV_%d: VDEV RSP is NULL",
740 				 wlan_psoc_get_id(psoc), vdev_idx);
741 			continue;
742 		}
743 
744 		status = target_if_vdev_mgr_rsp_timer_stop(
745 				psoc, vdev_rsp, RESTART_RESPONSE_BIT);
746 		if (QDF_IS_STATUS_ERROR(status))
747 			mlme_err("PSOC_%d VDEV_%d: VDE MGR RSP Timer stop failed",
748 				 wlan_psoc_get_id(psoc), vdev_idx);
749 	}
750 
751 	status = rx_ops->vdev_mgr_multi_vdev_restart_resp(psoc, &restart_resp);
752 
753 	return qdf_status_to_os_return(status);
754 }
755 
756 /**
757  * target_if_vdev_csa_complete - CSA complete event handler
758  * @psoc: psoc
759  * @vdev_id: vdev id
760  *
761  * Return: 0 on success
762  */
763 static int target_if_vdev_csa_complete(struct wlan_objmgr_psoc *psoc,
764 				       uint8_t vdev_id)
765 {
766 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
767 	struct vdev_mlme_obj *vdev_mlme;
768 	struct wlan_objmgr_vdev *vdev;
769 	int ret = 0;
770 
771 	if (!psoc) {
772 		mlme_err("Invalid input");
773 		return -EINVAL;
774 	}
775 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
776 						    WLAN_VDEV_TARGET_IF_ID);
777 	if (!vdev) {
778 		mlme_err("VDEV is NULL");
779 		return -EINVAL;
780 	}
781 	vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev);
782 	if (!vdev_mlme) {
783 		mlme_err("VDEV_%d: PSOC_%d VDEV_MLME is NULL", vdev_id,
784 			 wlan_psoc_get_id(psoc));
785 		ret = -EINVAL;
786 		goto end;
787 	}
788 
789 	if ((vdev_mlme->ops) && vdev_mlme->ops->mlme_vdev_csa_complete) {
790 		status = vdev_mlme->ops->mlme_vdev_csa_complete(vdev_mlme);
791 		if (QDF_IS_STATUS_ERROR(status)) {
792 			mlme_err("vdev csa complete failed");
793 			ret = -EINVAL;
794 		}
795 	}
796 end:
797 	wlan_objmgr_vdev_release_ref(vdev, WLAN_VDEV_TARGET_IF_ID);
798 	return ret;
799 }
800 
801 /**
802  * target_if_pdev_csa_status_event_handler - CSA event handler
803  * @scn: Pointer to scn structure
804  * @data: pointer to event data
805  * @datalen: event data length
806  *
807  * Return: 0 on success
808  */
809 static int target_if_pdev_csa_status_event_handler(
810 		ol_scn_t scn,
811 		uint8_t *data,
812 		uint32_t datalen)
813 {
814 	struct pdev_csa_switch_count_status csa_status;
815 	struct wlan_objmgr_psoc *psoc;
816 	struct wmi_unified *wmi_handle;
817 	struct target_psoc_info *tgt_hdl;
818 	int i;
819 	QDF_STATUS status;
820 	struct wlan_lmac_if_mlme_rx_ops *rx_ops = NULL;
821 
822 	if (!scn || !data) {
823 		mlme_err("Invalid input");
824 		return -EINVAL;
825 	}
826 
827 	psoc = target_if_get_psoc_from_scn_hdl(scn);
828 	if (!psoc) {
829 		mlme_err("PSOC is NULL");
830 		return -EINVAL;
831 	}
832 
833 	rx_ops = target_if_vdev_mgr_get_rx_ops(psoc);
834 	if (!rx_ops || !rx_ops->vdev_mgr_set_max_channel_switch_time) {
835 		mlme_err("No Rx Ops");
836 		return -EINVAL;
837 	}
838 
839 	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
840 	if (!wmi_handle) {
841 		mlme_err("wmi_handle is null");
842 		return -EINVAL;
843 	}
844 
845 	tgt_hdl = wlan_psoc_get_tgt_if_handle(psoc);
846 	if (!tgt_hdl) {
847 		mlme_err("target_psoc_info is null");
848 		return -EINVAL;
849 	}
850 
851 	qdf_mem_zero(&csa_status, sizeof(csa_status));
852 	status = wmi_extract_pdev_csa_switch_count_status(
853 			wmi_handle, data, &csa_status);
854 	if (QDF_IS_STATUS_ERROR(status)) {
855 		mlme_err("Extracting CSA switch count status event failed");
856 		return -EINVAL;
857 	}
858 
859 	if (csa_status.current_switch_count == 1)
860 		rx_ops->vdev_mgr_set_max_channel_switch_time
861 			(psoc, csa_status.vdev_ids, csa_status.num_vdevs);
862 
863 	if (wlan_psoc_nif_fw_ext_cap_get(psoc, WLAN_SOC_CEXT_CSA_TX_OFFLOAD)) {
864 		for (i = 0; i < csa_status.num_vdevs; i++) {
865 			if (!csa_status.current_switch_count)
866 				target_if_vdev_csa_complete(psoc,
867 							csa_status.vdev_ids[i]);
868 		}
869 	}
870 
871 	return target_if_csa_switch_count_status(psoc, tgt_hdl, csa_status);
872 }
873 
874 #ifdef WLAN_FEATURE_DYNAMIC_MAC_ADDR_UPDATE
875 /**
876  * target_if_update_macaddr_conf_evt_handler() - Set MAC address confirmation
877  *                                               event handler
878  * @scn: Pointer to scn structure
879  * @event_buff: event data
880  * @len: length
881  *
882  * Response handler for set MAC address request command.
883  *
884  * Return: 0 for success or error code
885  */
886 static int target_if_update_macaddr_conf_evt_handler(ol_scn_t scn,
887 						     uint8_t *event_buff,
888 						     uint32_t len)
889 {
890 	struct wlan_objmgr_psoc *psoc;
891 	struct wmi_unified *wmi_handle;
892 	uint8_t vdev_id, resp_status;
893 	QDF_STATUS status;
894 	struct wlan_lmac_if_mlme_rx_ops *rx_ops;
895 
896 	if (!event_buff) {
897 		mlme_err("Received NULL event ptr from FW");
898 		return -EINVAL;
899 	}
900 
901 	psoc = target_if_get_psoc_from_scn_hdl(scn);
902 	if (!psoc) {
903 		mlme_err("PSOC is NULL");
904 		return -EINVAL;
905 	}
906 
907 	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
908 	if (!wmi_handle) {
909 		mlme_err("wmi_handle is null");
910 		return -EINVAL;
911 	}
912 
913 	status = wmi_extract_update_mac_address_event(wmi_handle, event_buff,
914 						      &vdev_id, &resp_status);
915 	if (QDF_IS_STATUS_ERROR(status)) {
916 		mlme_err("Failed to extract update MAC address event");
917 		return -EINVAL;
918 	}
919 
920 	rx_ops = target_if_vdev_mgr_get_rx_ops(psoc);
921 	if (!rx_ops || !rx_ops->vdev_mgr_set_mac_addr_response) {
922 		mlme_err("No Rx Ops");
923 		return -EINVAL;
924 	}
925 
926 	rx_ops->vdev_mgr_set_mac_addr_response(vdev_id, resp_status);
927 
928 	return 0;
929 }
930 
931 static inline void
932 target_if_register_set_mac_addr_evt_cbk(struct wmi_unified *wmi_handle)
933 {
934 	wmi_unified_register_event_handler(
935 		   wmi_handle, wmi_vdev_update_mac_addr_conf_eventid,
936 		   target_if_update_macaddr_conf_evt_handler, VDEV_RSP_RX_CTX);
937 }
938 
939 static inline void
940 target_if_unregister_set_mac_addr_evt_cbk(struct wmi_unified *wmi_handle)
941 {
942 	wmi_unified_unregister_event_handler(
943 			wmi_handle, wmi_vdev_update_mac_addr_conf_eventid);
944 }
945 #else
946 static inline void
947 target_if_register_set_mac_addr_evt_cbk(struct wmi_unified *wmi_handle)
948 {
949 }
950 
951 static inline void
952 target_if_unregister_set_mac_addr_evt_cbk(struct wmi_unified *wmi_handle)
953 {
954 }
955 #endif
956 
957 #ifdef WLAN_FEATURE_11BE_MLO
958 /**
959  * target_if_quiet_offload_event_handler() - Quiet IE offload mlo
960  *                                           station event handler
961  * @scn: Pointer to scn structure
962  * @event_buff: event data
963  * @len: length
964  *
965  * Return: 0 for success or error code
966  */
967 static int target_if_quiet_offload_event_handler(ol_scn_t scn,
968 						 uint8_t *event_buff,
969 						 uint32_t len)
970 {
971 	struct wlan_objmgr_psoc *psoc;
972 	struct wmi_unified *wmi_handle;
973 	QDF_STATUS status;
974 	struct wlan_lmac_if_mlme_rx_ops *rx_ops;
975 	struct vdev_sta_quiet_event sta_quiet_event = {0};
976 
977 	if (!event_buff) {
978 		mlme_err("Received NULL event ptr from FW");
979 		return -EINVAL;
980 	}
981 
982 	psoc = target_if_get_psoc_from_scn_hdl(scn);
983 	if (!psoc) {
984 		mlme_err("PSOC is NULL");
985 		return -EINVAL;
986 	}
987 
988 	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
989 	if (!wmi_handle) {
990 		mlme_err("wmi_handle is null");
991 		return -EINVAL;
992 	}
993 
994 	status = wmi_extract_quiet_offload_event(wmi_handle, event_buff,
995 						 &sta_quiet_event);
996 	if (QDF_IS_STATUS_ERROR(status)) {
997 		mlme_err("Failed to extract quiet IE offload event");
998 		return -EINVAL;
999 	}
1000 
1001 	rx_ops = target_if_vdev_mgr_get_rx_ops(psoc);
1002 	if (!rx_ops || !rx_ops->vdev_mgr_quiet_offload) {
1003 		mlme_err("No Rx Ops");
1004 		return -EINVAL;
1005 	}
1006 
1007 	rx_ops->vdev_mgr_quiet_offload(psoc, &sta_quiet_event);
1008 
1009 	return 0;
1010 }
1011 
1012 static inline void
1013 target_if_register_quiet_offload_event(struct wmi_unified *wmi_handle)
1014 {
1015 	wmi_unified_register_event_handler(
1016 		   wmi_handle, wmi_vdev_quiet_offload_eventid,
1017 		   target_if_quiet_offload_event_handler, VDEV_RSP_RX_CTX);
1018 }
1019 
1020 static inline void
1021 target_if_unregister_quiet_offload_event(struct wmi_unified *wmi_handle)
1022 {
1023 	wmi_unified_unregister_event_handler(
1024 			wmi_handle, wmi_vdev_quiet_offload_eventid);
1025 }
1026 #else
1027 static inline void
1028 target_if_register_quiet_offload_event(struct wmi_unified *wmi_handle)
1029 {
1030 }
1031 
1032 static inline void
1033 target_if_unregister_quiet_offload_event(struct wmi_unified *wmi_handle)
1034 {
1035 }
1036 #endif
1037 
1038 QDF_STATUS target_if_vdev_mgr_wmi_event_register(
1039 				struct wlan_objmgr_psoc *psoc)
1040 {
1041 	QDF_STATUS retval = QDF_STATUS_SUCCESS;
1042 	struct wmi_unified *wmi_handle;
1043 
1044 	if (!psoc) {
1045 		mlme_err("PSOC is NULL");
1046 		return QDF_STATUS_E_NULL_VALUE;
1047 	}
1048 
1049 	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
1050 	if (!wmi_handle) {
1051 		mlme_err("wmi_handle is null");
1052 		return QDF_STATUS_E_INVAL;
1053 	}
1054 
1055 	retval = wmi_unified_register_event_handler(
1056 				wmi_handle,
1057 				wmi_vdev_stopped_event_id,
1058 				target_if_vdev_mgr_stop_response_handler,
1059 				VDEV_RSP_RX_CTX);
1060 	if (QDF_IS_STATUS_ERROR(retval))
1061 		mlme_err("failed to register for stop response");
1062 
1063 	retval = wmi_unified_register_event_handler(
1064 				wmi_handle,
1065 				wmi_vdev_delete_resp_event_id,
1066 				target_if_vdev_mgr_delete_response_handler,
1067 				VDEV_RSP_RX_CTX);
1068 	if (QDF_IS_STATUS_ERROR(retval))
1069 		mlme_err("failed to register for delete response");
1070 
1071 	retval = wmi_unified_register_event_handler(
1072 				wmi_handle,
1073 				wmi_vdev_start_resp_event_id,
1074 				target_if_vdev_mgr_start_response_handler,
1075 				VDEV_RSP_RX_CTX);
1076 	if (QDF_IS_STATUS_ERROR(retval))
1077 		mlme_err("failed to register for start response");
1078 
1079 	retval = wmi_unified_register_event_handler(
1080 			wmi_handle,
1081 			wmi_peer_delete_all_response_event_id,
1082 			target_if_vdev_mgr_peer_delete_all_response_handler,
1083 			VDEV_RSP_RX_CTX);
1084 	if (QDF_IS_STATUS_ERROR(retval))
1085 		mlme_err("failed to register for peer delete all response");
1086 
1087 	retval = wmi_unified_register_event_handler(
1088 			wmi_handle,
1089 			wmi_pdev_multi_vdev_restart_response_event_id,
1090 			target_if_vdev_mgr_multi_vdev_restart_resp_handler,
1091 			VDEV_RSP_RX_CTX);
1092 	if (QDF_IS_STATUS_ERROR(retval))
1093 		mlme_err("failed to register for multivdev restart response");
1094 
1095 	if (wmi_service_enabled(wmi_handle, wmi_service_beacon_offload)) {
1096 		retval = wmi_unified_register_event_handler(
1097 				wmi_handle,
1098 				wmi_pdev_csa_switch_count_status_event_id,
1099 				target_if_pdev_csa_status_event_handler,
1100 				VDEV_RSP_RX_CTX);
1101 		if (QDF_IS_STATUS_ERROR(retval))
1102 			mlme_err("failed to register for csa event handler");
1103 	}
1104 
1105 	target_if_register_set_mac_addr_evt_cbk(wmi_handle);
1106 
1107 	target_if_register_quiet_offload_event(wmi_handle);
1108 
1109 	return retval;
1110 }
1111 
1112 QDF_STATUS target_if_vdev_mgr_wmi_event_unregister(
1113 					struct wlan_objmgr_psoc *psoc)
1114 {
1115 	struct wmi_unified *wmi_handle;
1116 
1117 	if (!psoc) {
1118 		mlme_err("PSOC is NULL");
1119 		return QDF_STATUS_E_INVAL;
1120 	}
1121 
1122 	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
1123 	if (!wmi_handle) {
1124 		mlme_err("wmi_handle is null");
1125 		return QDF_STATUS_E_INVAL;
1126 	}
1127 
1128 	target_if_unregister_quiet_offload_event(wmi_handle);
1129 
1130 	target_if_unregister_set_mac_addr_evt_cbk(wmi_handle);
1131 
1132 	wmi_unified_unregister_event_handler(
1133 			wmi_handle,
1134 			wmi_pdev_multi_vdev_restart_response_event_id);
1135 
1136 	wmi_unified_unregister_event_handler(
1137 			wmi_handle,
1138 			wmi_peer_delete_all_response_event_id);
1139 
1140 	wmi_unified_unregister_event_handler(wmi_handle,
1141 					     wmi_vdev_start_resp_event_id);
1142 
1143 	wmi_unified_unregister_event_handler(wmi_handle,
1144 					     wmi_vdev_delete_resp_event_id);
1145 
1146 	wmi_unified_unregister_event_handler(wmi_handle,
1147 					     wmi_vdev_stopped_event_id);
1148 
1149 	return QDF_STATUS_SUCCESS;
1150 }
1151