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