xref: /wlan-dirver/qca-wifi-host-cmn/target_if/mlme/vdev_mgr/src/target_if_vdev_mgr_rx_ops.c (revision 6d768494e5ce14eb1603a695c86739d12ecc6ec2)
1 /*
2  * Copyright (c) 2019-2020 The Linux Foundation. All rights reserved.
3  *
4  * Permission to use, copy, modify, and/or distribute this software for
5  * any purpose with or without fee is hereby granted, provided that the
6  * above copyright notice and this permission notice appear in all
7  * copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
10  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
11  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
12  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
13  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
14  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
15  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16  * PERFORMANCE OF THIS SOFTWARE.
17  */
18 
19 /**
20  * DOC: target_if_vdev_mgr_rx_ops.c
21  *
22  * This file provide definition for APIs registered through events received
23  * from FW
24  */
25 #include <target_if_vdev_mgr_rx_ops.h>
26 #include <target_if_vdev_mgr_tx_ops.h>
27 #include <wlan_vdev_mgr_tgt_if_rx_defs.h>
28 #include <wlan_vdev_mgr_tgt_if_tx_defs.h>
29 #include <wmi_unified_param.h>
30 #include <wlan_mlme_dbg.h>
31 #include <target_if.h>
32 #include <wlan_vdev_mlme_main.h>
33 #include <wmi_unified_vdev_api.h>
34 
35 static inline
36 void target_if_vdev_mgr_handle_recovery(struct wlan_objmgr_psoc *psoc,
37 					uint8_t vdev_id,
38 					enum qdf_hang_reason recovery_reason,
39 					uint16_t rsp_pos)
40 {
41 	mlme_nofl_err("PSOC_%d VDEV_%d: %s rsp timeout", wlan_psoc_get_id(psoc),
42 		      vdev_id, string_from_rsp_bit(rsp_pos));
43 	if (target_if_vdev_mgr_is_panic_allowed())
44 		qdf_trigger_self_recovery(psoc, recovery_reason);
45 	else
46 		mlme_nofl_debug("PSOC_%d VDEV_%d: Panic not allowed",
47 				wlan_psoc_get_id(psoc), vdev_id);
48 }
49 
50 void target_if_vdev_mgr_rsp_timer_cb(struct vdev_response_timer *vdev_rsp)
51 {
52 	struct wlan_objmgr_psoc *psoc;
53 	struct wlan_lmac_if_mlme_rx_ops *rx_ops;
54 	struct vdev_start_response start_rsp = {0};
55 	struct vdev_stop_response stop_rsp = {0};
56 	struct vdev_delete_response del_rsp = {0};
57 	struct peer_delete_all_response peer_del_all_rsp = {0};
58 	enum qdf_hang_reason recovery_reason;
59 	uint8_t vdev_id;
60 	uint16_t rsp_pos = RESPONSE_BIT_MAX;
61 
62 	if (!vdev_rsp) {
63 		mlme_err("Vdev response timer is NULL");
64 		return;
65 	}
66 
67 	psoc = vdev_rsp->psoc;
68 	if (!psoc) {
69 		mlme_err("PSOC is NULL");
70 		return;
71 	}
72 
73 	rx_ops = target_if_vdev_mgr_get_rx_ops(psoc);
74 	if (!rx_ops || !rx_ops->psoc_get_vdev_response_timer_info) {
75 		mlme_err("No Rx Ops");
76 		return;
77 	}
78 
79 	if (!qdf_atomic_test_bit(START_RESPONSE_BIT, &vdev_rsp->rsp_status) &&
80 	    !qdf_atomic_test_bit(RESTART_RESPONSE_BIT, &vdev_rsp->rsp_status) &&
81 	    !qdf_atomic_test_bit(STOP_RESPONSE_BIT, &vdev_rsp->rsp_status) &&
82 	    !qdf_atomic_test_bit(DELETE_RESPONSE_BIT, &vdev_rsp->rsp_status) &&
83 	    !qdf_atomic_test_bit(
84 			PEER_DELETE_ALL_RESPONSE_BIT,
85 			&vdev_rsp->rsp_status)) {
86 		mlme_debug("No response bit is set, ignoring actions :%d",
87 			   vdev_rsp->vdev_id);
88 		return;
89 	}
90 
91 	vdev_id = vdev_rsp->vdev_id;
92 	if (vdev_id >= WLAN_UMAC_PSOC_MAX_VDEVS) {
93 		mlme_err("Invalid VDEV_%d PSOC_%d", vdev_id,
94 			 wlan_psoc_get_id(psoc));
95 		return;
96 	}
97 
98 	vdev_rsp->timer_status = QDF_STATUS_E_TIMEOUT;
99 	if (qdf_atomic_test_bit(START_RESPONSE_BIT,
100 				&vdev_rsp->rsp_status) ||
101 	    qdf_atomic_test_bit(RESTART_RESPONSE_BIT,
102 				&vdev_rsp->rsp_status)) {
103 		start_rsp.vdev_id = vdev_id;
104 		start_rsp.status = WLAN_MLME_HOST_VDEV_START_TIMEOUT;
105 		if (qdf_atomic_test_bit(START_RESPONSE_BIT,
106 					&vdev_rsp->rsp_status)) {
107 			start_rsp.resp_type =
108 				WMI_HOST_VDEV_START_RESP_EVENT;
109 			rsp_pos = START_RESPONSE_BIT;
110 			recovery_reason = QDF_VDEV_START_RESPONSE_TIMED_OUT;
111 		} else {
112 			start_rsp.resp_type =
113 				WMI_HOST_VDEV_RESTART_RESP_EVENT;
114 			rsp_pos = RESTART_RESPONSE_BIT;
115 			recovery_reason = QDF_VDEV_RESTART_RESPONSE_TIMED_OUT;
116 		}
117 
118 		target_if_vdev_mgr_rsp_timer_stop(psoc, vdev_rsp, rsp_pos);
119 		target_if_vdev_mgr_handle_recovery(psoc, vdev_id,
120 						   recovery_reason, rsp_pos);
121 		rx_ops->vdev_mgr_start_response(psoc, &start_rsp);
122 	} else if (qdf_atomic_test_bit(STOP_RESPONSE_BIT,
123 				       &vdev_rsp->rsp_status)) {
124 		rsp_pos = STOP_RESPONSE_BIT;
125 		stop_rsp.vdev_id = vdev_id;
126 		recovery_reason = QDF_VDEV_STOP_RESPONSE_TIMED_OUT;
127 
128 		target_if_vdev_mgr_rsp_timer_stop(psoc, vdev_rsp, rsp_pos);
129 		target_if_vdev_mgr_handle_recovery(psoc, vdev_id,
130 						   recovery_reason, rsp_pos);
131 		rx_ops->vdev_mgr_stop_response(psoc, &stop_rsp);
132 	} else if (qdf_atomic_test_bit(DELETE_RESPONSE_BIT,
133 				       &vdev_rsp->rsp_status)) {
134 		del_rsp.vdev_id = vdev_id;
135 		rsp_pos = DELETE_RESPONSE_BIT;
136 		recovery_reason = QDF_VDEV_DELETE_RESPONSE_TIMED_OUT;
137 		target_if_vdev_mgr_rsp_timer_stop(psoc, vdev_rsp, rsp_pos);
138 		target_if_vdev_mgr_handle_recovery(psoc, vdev_id,
139 						   recovery_reason, rsp_pos);
140 		rx_ops->vdev_mgr_delete_response(psoc, &del_rsp);
141 	} else if (qdf_atomic_test_bit(PEER_DELETE_ALL_RESPONSE_BIT,
142 				&vdev_rsp->rsp_status)) {
143 		peer_del_all_rsp.vdev_id = vdev_id;
144 		rsp_pos = PEER_DELETE_ALL_RESPONSE_BIT;
145 		recovery_reason = QDF_VDEV_PEER_DELETE_ALL_RESPONSE_TIMED_OUT;
146 		target_if_vdev_mgr_rsp_timer_stop(psoc, vdev_rsp, rsp_pos);
147 		target_if_vdev_mgr_handle_recovery(psoc, vdev_id,
148 						   recovery_reason, rsp_pos);
149 		rx_ops->vdev_mgr_peer_delete_all_response(psoc,
150 							  &peer_del_all_rsp);
151 	} else {
152 		mlme_err("PSOC_%d VDEV_%d: Unknown error",
153 			 wlan_psoc_get_id(psoc), vdev_id);
154 		return;
155 	}
156 }
157 
158 #ifdef SERIALIZE_VDEV_RESP
159 static QDF_STATUS target_if_vdev_mgr_rsp_flush_cb(struct scheduler_msg *msg)
160 {
161 	struct vdev_response_timer *vdev_rsp;
162 	struct wlan_objmgr_psoc *psoc;
163 
164 	if (!msg->bodyptr) {
165 		mlme_err("Message bodyptr is NULL");
166 		return QDF_STATUS_E_INVAL;
167 	}
168 
169 	vdev_rsp = msg->bodyptr;
170 	if (!vdev_rsp) {
171 		mlme_err("vdev response timer is NULL");
172 		return QDF_STATUS_E_INVAL;
173 	}
174 
175 	psoc = vdev_rsp->psoc;
176 	if (!psoc) {
177 		mlme_err("PSOC is NULL");
178 		return QDF_STATUS_E_INVAL;
179 	}
180 
181 	if (vdev_rsp->rsp_status)
182 		wlan_objmgr_psoc_release_ref(psoc, WLAN_PSOC_TARGET_IF_ID);
183 
184 	return QDF_STATUS_SUCCESS;
185 }
186 
187 static void
188 target_if_vdev_mgr_rsp_cb_mc_ctx(void *arg)
189 {
190 	struct scheduler_msg msg = {0};
191 	struct vdev_response_timer *vdev_rsp = arg;
192 	struct wlan_objmgr_psoc *psoc;
193 
194 	psoc = vdev_rsp->psoc;
195 	if (!psoc) {
196 		mlme_err("PSOC is NULL");
197 		return;
198 	}
199 
200 	msg.type = SYS_MSG_ID_MC_TIMER;
201 	msg.reserved = SYS_MSG_COOKIE;
202 	msg.callback = target_if_vdev_mgr_rsp_timer_cb;
203 	msg.bodyptr = vdev_rsp;
204 	msg.bodyval = 0;
205 	msg.flush_callback = target_if_vdev_mgr_rsp_flush_cb;
206 
207 	if (scheduler_post_message(QDF_MODULE_ID_TARGET_IF,
208 				   QDF_MODULE_ID_TARGET_IF,
209 				   QDF_MODULE_ID_SYS, &msg) ==
210 				   QDF_STATUS_SUCCESS)
211 		return;
212 
213 	mlme_err("Could not enqueue timer to timer queue");
214 	if (psoc)
215 		wlan_objmgr_psoc_release_ref(psoc, WLAN_PSOC_TARGET_IF_ID);
216 }
217 
218 void target_if_vdev_mgr_rsp_timer_mgmt_cb(void *arg)
219 {
220 	target_if_vdev_mgr_rsp_cb_mc_ctx(arg);
221 }
222 
223 #define VDEV_RSP_RX_CTX WMI_RX_SERIALIZER_CTX
224 #else
225 void target_if_vdev_mgr_rsp_timer_mgmt_cb(void *arg)
226 {
227 	target_if_vdev_mgr_rsp_timer_cb(arg);
228 }
229 
230 #define VDEV_RSP_RX_CTX WMI_RX_UMAC_CTX
231 #endif
232 
233 static int target_if_vdev_mgr_start_response_handler(ol_scn_t scn,
234 						     uint8_t *data,
235 						     uint32_t datalen)
236 {
237 	QDF_STATUS status = QDF_STATUS_E_INVAL;
238 	struct wlan_objmgr_psoc *psoc;
239 	struct wmi_unified *wmi_handle;
240 	struct wlan_lmac_if_mlme_rx_ops *rx_ops;
241 	struct vdev_start_response vdev_start_resp = {0};
242 	uint8_t vdev_id;
243 	struct vdev_response_timer *vdev_rsp;
244 
245 	if (!scn || !data) {
246 		mlme_err("Invalid input");
247 		return -EINVAL;
248 	}
249 
250 	psoc = target_if_get_psoc_from_scn_hdl(scn);
251 	if (!psoc) {
252 		mlme_err("PSOC is NULL");
253 		return -EINVAL;
254 	}
255 
256 	rx_ops = target_if_vdev_mgr_get_rx_ops(psoc);
257 	if (!rx_ops || !rx_ops->vdev_mgr_start_response) {
258 		mlme_err("No Rx Ops");
259 		return -EINVAL;
260 	}
261 
262 	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
263 	if (!wmi_handle) {
264 		mlme_err("wmi_handle is null");
265 		return -EINVAL;
266 	}
267 
268 	if (wmi_extract_vdev_start_resp(wmi_handle, data, &vdev_start_resp)) {
269 		mlme_err("WMI extract failed");
270 		return -EINVAL;
271 	}
272 
273 	vdev_id = vdev_start_resp.vdev_id;
274 	vdev_rsp = rx_ops->psoc_get_vdev_response_timer_info(psoc, vdev_id);
275 	if (!vdev_rsp) {
276 		mlme_err("vdev response timer is null VDEV_%d PSOC_%d",
277 			 vdev_id, wlan_psoc_get_id(psoc));
278 		return -EINVAL;
279 	}
280 
281 	if (vdev_start_resp.resp_type == WMI_HOST_VDEV_RESTART_RESP_EVENT)
282 		status = target_if_vdev_mgr_rsp_timer_stop(
283 							psoc, vdev_rsp,
284 							RESTART_RESPONSE_BIT);
285 	else
286 		status = target_if_vdev_mgr_rsp_timer_stop(psoc, vdev_rsp,
287 							   START_RESPONSE_BIT);
288 
289 	if (QDF_IS_STATUS_ERROR(status)) {
290 		mlme_err("PSOC_%d VDEV_%d: VDE MGR RSP Timer stop failed",
291 			 psoc->soc_objmgr.psoc_id, vdev_id);
292 		goto err;
293 	}
294 
295 	status = rx_ops->vdev_mgr_start_response(psoc, &vdev_start_resp);
296 
297 err:
298 	return qdf_status_to_os_return(status);
299 }
300 
301 static int target_if_vdev_mgr_stop_response_handler(ol_scn_t scn,
302 						    uint8_t *data,
303 						    uint32_t datalen)
304 {
305 	QDF_STATUS status = QDF_STATUS_E_INVAL;
306 	struct wlan_objmgr_psoc *psoc;
307 	struct wmi_unified *wmi_handle;
308 	struct wlan_lmac_if_mlme_rx_ops *rx_ops;
309 	struct vdev_stop_response rsp = {0};
310 	uint32_t vdev_id;
311 	struct vdev_response_timer *vdev_rsp;
312 
313 	if (!scn || !data) {
314 		mlme_err("Invalid input");
315 		return -EINVAL;
316 	}
317 
318 	psoc = target_if_get_psoc_from_scn_hdl(scn);
319 	if (!psoc) {
320 		mlme_err("PSOC is NULL");
321 		return -EINVAL;
322 	}
323 
324 	rx_ops = target_if_vdev_mgr_get_rx_ops(psoc);
325 	if (!rx_ops || !rx_ops->vdev_mgr_stop_response) {
326 		mlme_err("No Rx Ops");
327 		return -EINVAL;
328 	}
329 
330 	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
331 	if (!wmi_handle) {
332 		mlme_err("wmi_handle is null");
333 		return -EINVAL;
334 	}
335 
336 	if (wmi_extract_vdev_stopped_param(wmi_handle, data, &vdev_id)) {
337 		mlme_err("WMI extract failed");
338 		return -EINVAL;
339 	}
340 
341 	vdev_rsp = rx_ops->psoc_get_vdev_response_timer_info(psoc, vdev_id);
342 	if (!vdev_rsp) {
343 		mlme_err("vdev response timer is null VDEV_%d PSOC_%d",
344 			 vdev_id, wlan_psoc_get_id(psoc));
345 		return -EINVAL;
346 	}
347 
348 	status = target_if_vdev_mgr_rsp_timer_stop(psoc, vdev_rsp,
349 						   STOP_RESPONSE_BIT);
350 
351 	if (QDF_IS_STATUS_ERROR(status)) {
352 		mlme_err("PSOC_%d VDEV_%d: VDE MGR RSP Timer stop failed",
353 			 psoc->soc_objmgr.psoc_id, vdev_id);
354 		goto err;
355 	}
356 
357 	rsp.vdev_id = vdev_id;
358 	status = rx_ops->vdev_mgr_stop_response(psoc, &rsp);
359 
360 err:
361 	return qdf_status_to_os_return(status);
362 }
363 
364 static int target_if_vdev_mgr_delete_response_handler(ol_scn_t scn,
365 						      uint8_t *data,
366 						      uint32_t datalen)
367 {
368 	QDF_STATUS status = QDF_STATUS_E_INVAL;
369 	struct wlan_objmgr_psoc *psoc;
370 	struct wmi_unified *wmi_handle;
371 	struct wlan_lmac_if_mlme_rx_ops *rx_ops;
372 	struct vdev_delete_response vdev_del_resp = {0};
373 	struct vdev_response_timer *vdev_rsp;
374 
375 	if (!scn || !data) {
376 		mlme_err("Invalid input");
377 		return -EINVAL;
378 	}
379 
380 	psoc = target_if_get_psoc_from_scn_hdl(scn);
381 	if (!psoc) {
382 		mlme_err("PSOC is NULL");
383 		return -EINVAL;
384 	}
385 
386 	rx_ops = target_if_vdev_mgr_get_rx_ops(psoc);
387 	if (!rx_ops || !rx_ops->vdev_mgr_delete_response) {
388 		mlme_err("No Rx Ops");
389 		return -EINVAL;
390 	}
391 
392 	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
393 	if (!wmi_handle) {
394 		mlme_err("wmi_handle is null");
395 		return -EINVAL;
396 	}
397 
398 	if (wmi_extract_vdev_delete_resp(wmi_handle, data, &vdev_del_resp)) {
399 		mlme_err("WMI extract failed");
400 		return -EINVAL;
401 	}
402 
403 	vdev_rsp = rx_ops->psoc_get_vdev_response_timer_info(psoc,
404 							 vdev_del_resp.vdev_id);
405 	if (!vdev_rsp) {
406 		mlme_err("vdev response timer is null VDEV_%d PSOC_%d",
407 			 vdev_del_resp.vdev_id, wlan_psoc_get_id(psoc));
408 		return -EINVAL;
409 	}
410 
411 	status = target_if_vdev_mgr_rsp_timer_stop(
412 						psoc, vdev_rsp,
413 						DELETE_RESPONSE_BIT);
414 
415 	if (QDF_IS_STATUS_ERROR(status)) {
416 		mlme_err("PSOC_%d VDEV_%d: VDE MGR RSP Timer stop failed",
417 			 wlan_psoc_get_id(psoc), vdev_del_resp.vdev_id);
418 		goto err;
419 	}
420 
421 	status = rx_ops->vdev_mgr_delete_response(psoc, &vdev_del_resp);
422 
423 err:
424 	return qdf_status_to_os_return(status);
425 }
426 
427 static int target_if_vdev_mgr_peer_delete_all_response_handler(
428 							ol_scn_t scn,
429 							uint8_t *data,
430 							uint32_t datalen)
431 {
432 	QDF_STATUS status = QDF_STATUS_E_INVAL;
433 	struct wlan_objmgr_psoc *psoc;
434 	struct wmi_unified *wmi_handle;
435 	struct wlan_lmac_if_mlme_rx_ops *rx_ops;
436 	struct peer_delete_all_response vdev_peer_del_all_resp = {0};
437 	struct vdev_response_timer *vdev_rsp;
438 
439 	if (!scn || !data) {
440 		mlme_err("Invalid input");
441 		return -EINVAL;
442 	}
443 
444 	psoc = target_if_get_psoc_from_scn_hdl(scn);
445 	if (!psoc) {
446 		mlme_err("PSOC is NULL");
447 		return -EINVAL;
448 	}
449 
450 	rx_ops = target_if_vdev_mgr_get_rx_ops(psoc);
451 	if (!rx_ops || !rx_ops->vdev_mgr_peer_delete_all_response) {
452 		mlme_err("No Rx Ops");
453 		return -EINVAL;
454 	}
455 
456 	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
457 	if (!wmi_handle) {
458 		mlme_err("wmi_handle is null");
459 		return -EINVAL;
460 	}
461 
462 	if (wmi_extract_vdev_peer_delete_all_response_event(
463 						wmi_handle, data,
464 						&vdev_peer_del_all_resp)) {
465 		mlme_err("WMI extract failed");
466 		return -EINVAL;
467 	}
468 
469 	vdev_rsp = rx_ops->psoc_get_vdev_response_timer_info(psoc,
470 						vdev_peer_del_all_resp.vdev_id);
471 	if (!vdev_rsp) {
472 		mlme_err("vdev response timer is null VDEV_%d PSOC_%d",
473 			 vdev_peer_del_all_resp.vdev_id,
474 			 wlan_psoc_get_id(psoc));
475 		return -EINVAL;
476 	}
477 
478 	status = target_if_vdev_mgr_rsp_timer_stop(
479 						psoc,
480 						vdev_rsp,
481 						PEER_DELETE_ALL_RESPONSE_BIT);
482 
483 	if (QDF_IS_STATUS_ERROR(status)) {
484 		mlme_err("PSOC_%d VDEV_%d: VDE MGR RSP Timer stop failed",
485 			 psoc->soc_objmgr.psoc_id,
486 			 vdev_peer_del_all_resp.vdev_id);
487 		goto err;
488 	}
489 
490 	status = rx_ops->vdev_mgr_peer_delete_all_response(
491 						psoc,
492 						&vdev_peer_del_all_resp);
493 
494 err:
495 	return qdf_status_to_os_return(status);
496 }
497 
498 int target_if_vdev_mgr_offload_bcn_tx_status_handler(
499 					ol_scn_t scn,
500 					uint8_t *data,
501 					uint32_t datalen)
502 {
503 	QDF_STATUS status;
504 	struct wlan_objmgr_psoc *psoc;
505 	struct wmi_unified *wmi_handle;
506 	struct wlan_lmac_if_mlme_rx_ops *rx_ops;
507 	uint32_t vdev_id, tx_status;
508 
509 	if (!scn || !data) {
510 		mlme_err("Invalid input");
511 		return -EINVAL;
512 	}
513 	psoc = target_if_get_psoc_from_scn_hdl(scn);
514 	if (!psoc) {
515 		mlme_err("PSOC is NULL");
516 		return -EINVAL;
517 	}
518 
519 	rx_ops = target_if_vdev_mgr_get_rx_ops(psoc);
520 	if (!rx_ops || !rx_ops->vdev_mgr_offload_bcn_tx_status_event_handle) {
521 		mlme_err("No Rx Ops");
522 		return -EINVAL;
523 	}
524 
525 	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
526 	if (!wmi_handle) {
527 		mlme_err("wmi_handle is null");
528 		return -EINVAL;
529 	}
530 
531 	if (wmi_extract_offload_bcn_tx_status_evt(wmi_handle, data,
532 						  &vdev_id, &tx_status)) {
533 		mlme_err("WMI extract failed");
534 		return -EINVAL;
535 	}
536 
537 	status = rx_ops->vdev_mgr_offload_bcn_tx_status_event_handle(
538 								vdev_id,
539 								tx_status);
540 
541 	return qdf_status_to_os_return(status);
542 }
543 
544 int target_if_vdev_mgr_tbttoffset_update_handler(
545 						ol_scn_t scn, uint8_t *data,
546 						uint32_t datalen)
547 {
548 	QDF_STATUS status;
549 	struct wlan_objmgr_psoc *psoc;
550 	struct wmi_unified *wmi_handle;
551 	struct wlan_lmac_if_mlme_rx_ops *rx_ops;
552 	uint32_t num_vdevs = 0;
553 
554 	if (!scn || !data) {
555 		mlme_err("Invalid input");
556 		return -EINVAL;
557 	}
558 	psoc = target_if_get_psoc_from_scn_hdl(scn);
559 	if (!psoc) {
560 		mlme_err("PSOC is NULL");
561 		return -EINVAL;
562 	}
563 
564 	rx_ops = target_if_vdev_mgr_get_rx_ops(psoc);
565 	if (!rx_ops || !rx_ops->vdev_mgr_tbttoffset_update_handle) {
566 		mlme_err("No Rx Ops");
567 		return -EINVAL;
568 	}
569 
570 	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
571 	if (!wmi_handle) {
572 		mlme_err("wmi_handle is null");
573 		return -EINVAL;
574 	}
575 
576 	if (wmi_extract_tbttoffset_num_vdevs(wmi_handle, data, &num_vdevs)) {
577 		mlme_err("WMI extract failed");
578 		return -EINVAL;
579 	}
580 
581 	status = rx_ops->vdev_mgr_tbttoffset_update_handle(num_vdevs,
582 							   false);
583 
584 	return qdf_status_to_os_return(status);
585 }
586 
587 int target_if_vdev_mgr_ext_tbttoffset_update_handler(
588 						ol_scn_t scn,
589 						uint8_t *data,
590 						uint32_t datalen)
591 {
592 	QDF_STATUS status;
593 	struct wlan_objmgr_psoc *psoc;
594 	struct wmi_unified *wmi_handle;
595 	struct wlan_lmac_if_mlme_rx_ops *rx_ops;
596 	uint32_t num_vdevs = 0;
597 
598 	if (!scn || !data) {
599 		mlme_err("Invalid input");
600 		return -EINVAL;
601 	}
602 	psoc = target_if_get_psoc_from_scn_hdl(scn);
603 	if (!psoc) {
604 		mlme_err("PSOC is NULL");
605 		return -EINVAL;
606 	}
607 
608 	rx_ops = target_if_vdev_mgr_get_rx_ops(psoc);
609 	if (!rx_ops || !rx_ops->vdev_mgr_tbttoffset_update_handle) {
610 		mlme_err("No Rx Ops");
611 		return -EINVAL;
612 	}
613 
614 	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
615 	if (!wmi_handle) {
616 		mlme_err("wmi_handle is null");
617 		return -EINVAL;
618 	}
619 
620 	if (wmi_extract_ext_tbttoffset_num_vdevs(wmi_handle, data,
621 						 &num_vdevs)) {
622 		mlme_err("WMI extract failed");
623 		return -EINVAL;
624 	}
625 
626 	status = rx_ops->vdev_mgr_tbttoffset_update_handle(num_vdevs,
627 							   true);
628 
629 	return qdf_status_to_os_return(status);
630 }
631 
632 static int target_if_vdev_mgr_multi_vdev_restart_resp_handler(
633 							ol_scn_t scn,
634 							uint8_t *data,
635 							uint32_t datalen)
636 {
637 	QDF_STATUS status = QDF_STATUS_E_INVAL;
638 	struct wlan_objmgr_psoc *psoc;
639 	struct wmi_unified *wmi_handle;
640 	struct wlan_lmac_if_mlme_rx_ops *rx_ops;
641 	struct multi_vdev_restart_resp restart_resp;
642 	struct vdev_response_timer *vdev_rsp;
643 	uint8_t max_vdevs, vdev_idx;
644 
645 	if (!scn || !data) {
646 		mlme_err("Invalid input");
647 		return -EINVAL;
648 	}
649 
650 	psoc = target_if_get_psoc_from_scn_hdl(scn);
651 	if (!psoc) {
652 		mlme_err("PSOC is NULL");
653 		return -EINVAL;
654 	}
655 
656 	rx_ops = target_if_vdev_mgr_get_rx_ops(psoc);
657 	if (!rx_ops || !rx_ops->vdev_mgr_multi_vdev_restart_resp ||
658 	    !rx_ops->psoc_get_vdev_response_timer_info) {
659 		mlme_err("No Rx Ops");
660 		return -EINVAL;
661 	}
662 
663 	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
664 	if (!wmi_handle) {
665 		mlme_err("wmi_handle is null");
666 		return -EINVAL;
667 	}
668 
669 	qdf_mem_zero(&restart_resp, sizeof(restart_resp));
670 	if (wmi_extract_multi_vdev_restart_resp_event(wmi_handle, data,
671 						      &restart_resp)) {
672 		mlme_err("WMI extract failed");
673 		return -EINVAL;
674 	}
675 
676 	max_vdevs = wlan_psoc_get_max_vdev_count(psoc);
677 	for (vdev_idx = 0; vdev_idx < max_vdevs; vdev_idx++) {
678 		if (!qdf_test_bit(vdev_idx, restart_resp.vdev_id_bmap))
679 			continue;
680 
681 		mlme_debug("PSOC_%d VDEV_%d: Restart resp received",
682 			   wlan_psoc_get_id(psoc), vdev_idx);
683 		vdev_rsp = rx_ops->psoc_get_vdev_response_timer_info(psoc,
684 								     vdev_idx);
685 		if (!vdev_rsp) {
686 			mlme_err("PSOC_%d VDEV_%d: VDEV RSP is NULL",
687 				 wlan_psoc_get_id(psoc), vdev_idx);
688 			continue;
689 		}
690 
691 		status = target_if_vdev_mgr_rsp_timer_stop(
692 				psoc, vdev_rsp, RESTART_RESPONSE_BIT);
693 		if (QDF_IS_STATUS_ERROR(status))
694 			mlme_err("PSOC_%d VDEV_%d: VDE MGR RSP Timer stop failed",
695 				 wlan_psoc_get_id(psoc), vdev_idx);
696 	}
697 
698 	status = rx_ops->vdev_mgr_multi_vdev_restart_resp(psoc, &restart_resp);
699 
700 	return qdf_status_to_os_return(status);
701 }
702 
703 QDF_STATUS target_if_vdev_mgr_wmi_event_register(
704 				struct wlan_objmgr_psoc *psoc)
705 {
706 	int retval = 0;
707 	struct wmi_unified *wmi_handle;
708 
709 	if (!psoc) {
710 		mlme_err("PSOC is NULL");
711 		return QDF_STATUS_E_NULL_VALUE;
712 	}
713 
714 	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
715 	if (!wmi_handle) {
716 		mlme_err("wmi_handle is null");
717 		return QDF_STATUS_E_INVAL;
718 	}
719 
720 	retval = wmi_unified_register_event_handler(
721 				wmi_handle,
722 				wmi_vdev_stopped_event_id,
723 				target_if_vdev_mgr_stop_response_handler,
724 				VDEV_RSP_RX_CTX);
725 	if (retval)
726 		mlme_err("failed to register for stop response");
727 
728 	retval = wmi_unified_register_event_handler(
729 				wmi_handle,
730 				wmi_vdev_delete_resp_event_id,
731 				target_if_vdev_mgr_delete_response_handler,
732 				VDEV_RSP_RX_CTX);
733 	if (retval)
734 		mlme_err("failed to register for delete response");
735 
736 	retval = wmi_unified_register_event_handler(
737 				wmi_handle,
738 				wmi_vdev_start_resp_event_id,
739 				target_if_vdev_mgr_start_response_handler,
740 				VDEV_RSP_RX_CTX);
741 	if (retval)
742 		mlme_err("failed to register for start response");
743 
744 	retval = wmi_unified_register_event_handler(
745 			wmi_handle,
746 			wmi_peer_delete_all_response_event_id,
747 			target_if_vdev_mgr_peer_delete_all_response_handler,
748 			VDEV_RSP_RX_CTX);
749 	if (retval)
750 		mlme_err("failed to register for peer delete all response");
751 
752 	retval = wmi_unified_register_event_handler(
753 			wmi_handle,
754 			wmi_pdev_multi_vdev_restart_response_event_id,
755 			target_if_vdev_mgr_multi_vdev_restart_resp_handler,
756 			VDEV_RSP_RX_CTX);
757 	if (retval)
758 		mlme_err("failed to register for multivdev restart response");
759 
760 	return qdf_status_from_os_return(retval);
761 }
762 
763 QDF_STATUS target_if_vdev_mgr_wmi_event_unregister(
764 					struct wlan_objmgr_psoc *psoc)
765 {
766 	struct wmi_unified *wmi_handle;
767 
768 	if (!psoc) {
769 		mlme_err("PSOC is NULL");
770 		return QDF_STATUS_E_INVAL;
771 	}
772 
773 	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
774 	if (!wmi_handle) {
775 		mlme_err("wmi_handle is null");
776 		return QDF_STATUS_E_INVAL;
777 	}
778 
779 	wmi_unified_unregister_event_handler(
780 			wmi_handle,
781 			wmi_pdev_multi_vdev_restart_response_event_id);
782 
783 	wmi_unified_unregister_event_handler(
784 			wmi_handle,
785 			wmi_peer_delete_all_response_event_id);
786 
787 	wmi_unified_unregister_event_handler(wmi_handle,
788 					     wmi_vdev_start_resp_event_id);
789 
790 	wmi_unified_unregister_event_handler(wmi_handle,
791 					     wmi_vdev_delete_resp_event_id);
792 
793 	wmi_unified_unregister_event_handler(wmi_handle,
794 					     wmi_vdev_stopped_event_id);
795 
796 	return QDF_STATUS_SUCCESS;
797 }
798