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