xref: /wlan-dirver/qca-wifi-host-cmn/target_if/mlme/vdev_mgr/src/target_if_vdev_mgr_rx_ops.c (revision f28396d060cff5c6519f883cb28ae0116ce479f1)
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 void target_if_vdev_mgr_rsp_timer_cb(struct vdev_response_timer *vdev_rsp)
36 {
37 	struct wlan_objmgr_psoc *psoc;
38 	struct wlan_lmac_if_mlme_rx_ops *rx_ops;
39 	struct crash_inject param;
40 	struct wmi_unified *wmi_handle;
41 	struct vdev_start_response start_rsp = {0};
42 	struct vdev_stop_response stop_rsp = {0};
43 	struct vdev_delete_response del_rsp = {0};
44 	struct peer_delete_all_response peer_del_all_rsp = {0};
45 	uint8_t vdev_id;
46 	uint16_t rsp_pos = RESPONSE_BIT_MAX;
47 
48 	if (!vdev_rsp) {
49 		mlme_err("Vdev response timer is NULL");
50 		return;
51 	}
52 
53 	psoc = vdev_rsp->psoc;
54 	if (!psoc) {
55 		mlme_err("PSOC is NULL");
56 		return;
57 	}
58 
59 	rx_ops = target_if_vdev_mgr_get_rx_ops(psoc);
60 	if (!rx_ops || !rx_ops->psoc_get_vdev_response_timer_info) {
61 		mlme_err("No Rx Ops");
62 		return;
63 	}
64 
65 	if (!qdf_atomic_test_bit(START_RESPONSE_BIT, &vdev_rsp->rsp_status) &&
66 	    !qdf_atomic_test_bit(RESTART_RESPONSE_BIT, &vdev_rsp->rsp_status) &&
67 	    !qdf_atomic_test_bit(STOP_RESPONSE_BIT, &vdev_rsp->rsp_status) &&
68 	    !qdf_atomic_test_bit(DELETE_RESPONSE_BIT, &vdev_rsp->rsp_status) &&
69 	    !qdf_atomic_test_bit(
70 			PEER_DELETE_ALL_RESPONSE_BIT,
71 			&vdev_rsp->rsp_status)) {
72 		mlme_debug("No response bit is set, ignoring actions :%d",
73 			   vdev_rsp->vdev_id);
74 		return;
75 	}
76 
77 	vdev_id = vdev_rsp->vdev_id;
78 	if (vdev_id >= WLAN_UMAC_PSOC_MAX_VDEVS) {
79 		mlme_err("Invalid VDEV_%d PSOC_%d", vdev_id,
80 			 wlan_psoc_get_id(psoc));
81 		return;
82 	}
83 
84 	vdev_rsp->timer_status = QDF_STATUS_E_TIMEOUT;
85 	if (qdf_atomic_test_bit(START_RESPONSE_BIT,
86 				&vdev_rsp->rsp_status) ||
87 	    qdf_atomic_test_bit(RESTART_RESPONSE_BIT,
88 				&vdev_rsp->rsp_status)) {
89 		start_rsp.vdev_id = vdev_id;
90 		start_rsp.status = WLAN_MLME_HOST_VDEV_START_TIMEOUT;
91 		if (qdf_atomic_test_bit(START_RESPONSE_BIT,
92 					&vdev_rsp->rsp_status)) {
93 			start_rsp.resp_type =
94 				WMI_HOST_VDEV_START_RESP_EVENT;
95 			rsp_pos = START_RESPONSE_BIT;
96 		} else {
97 			start_rsp.resp_type =
98 				WMI_HOST_VDEV_RESTART_RESP_EVENT;
99 			rsp_pos = RESTART_RESPONSE_BIT;
100 		}
101 
102 		target_if_vdev_mgr_rsp_timer_stop(psoc, vdev_rsp, rsp_pos);
103 
104 		rx_ops->vdev_mgr_start_response(psoc, &start_rsp);
105 	} else if (qdf_atomic_test_bit(STOP_RESPONSE_BIT,
106 				       &vdev_rsp->rsp_status)) {
107 		rsp_pos = STOP_RESPONSE_BIT;
108 		stop_rsp.vdev_id = vdev_id;
109 		target_if_vdev_mgr_rsp_timer_stop(psoc, vdev_rsp, rsp_pos);
110 
111 		rx_ops->vdev_mgr_stop_response(psoc, &stop_rsp);
112 	} else if (qdf_atomic_test_bit(DELETE_RESPONSE_BIT,
113 				       &vdev_rsp->rsp_status)) {
114 		del_rsp.vdev_id = vdev_id;
115 		rsp_pos = DELETE_RESPONSE_BIT;
116 		target_if_vdev_mgr_rsp_timer_stop(psoc, vdev_rsp, rsp_pos);
117 
118 		rx_ops->vdev_mgr_delete_response(psoc, &del_rsp);
119 	} else if (qdf_atomic_test_bit(PEER_DELETE_ALL_RESPONSE_BIT,
120 				&vdev_rsp->rsp_status)) {
121 		peer_del_all_rsp.vdev_id = vdev_id;
122 		rsp_pos = PEER_DELETE_ALL_RESPONSE_BIT;
123 		target_if_vdev_mgr_rsp_timer_stop(psoc, vdev_rsp, rsp_pos);
124 
125 		rx_ops->vdev_mgr_peer_delete_all_response(
126 				psoc,
127 				&peer_del_all_rsp);
128 	} else {
129 		mlme_err("PSOC_%d VDEV_%d: Unknown error",
130 			 wlan_psoc_get_id(psoc), vdev_id);
131 		return;
132 	}
133 
134 	if (!target_if_vdev_mgr_is_panic_allowed()) {
135 		mlme_debug("PSOC_%d VDEV_%d: Panic not allowed",
136 			   wlan_psoc_get_id(psoc), vdev_id);
137 		return;
138 	}
139 
140 	/* Trigger fw recovery to collect fw dump */
141 	wmi_handle = GET_WMI_HDL_FROM_PSOC(psoc);
142 	if (wmi_handle) {
143 		mlme_err("PSOC_%d VDEV_%d: Self recovery, %s rsp timeout",
144 			 wlan_psoc_get_id(psoc), vdev_id,
145 			 string_from_rsp_bit(rsp_pos));
146 		qdf_mem_set(&param, sizeof(param), 0);
147 		/* RECOVERY_SIM_ASSERT */
148 		param.type = 0x01;
149 		wmi_crash_inject(wmi_handle, &param);
150 	} else if (target_if_vdev_mgr_is_panic_on_bug()) {
151 		QDF_DEBUG_PANIC("PSOC_%d VDEV_%d: Panic, %s response timeout",
152 				wlan_psoc_get_id(psoc),
153 				vdev_id, string_from_rsp_bit(rsp_pos));
154 	}
155 }
156 
157 #ifdef SERIALIZE_VDEV_RESP
158 static QDF_STATUS target_if_vdev_mgr_rsp_flush_cb(struct scheduler_msg *msg)
159 {
160 	struct vdev_response_timer *vdev_rsp;
161 	struct wlan_objmgr_psoc *psoc;
162 
163 	if (!msg->bodyptr) {
164 		mlme_err("Message bodyptr is NULL");
165 		return QDF_STATUS_E_INVAL;
166 	}
167 
168 	vdev_rsp = msg->bodyptr;
169 	if (!vdev_rsp) {
170 		mlme_err("vdev response timer is NULL");
171 		return QDF_STATUS_E_INVAL;
172 	}
173 
174 	psoc = vdev_rsp->psoc;
175 	if (!psoc) {
176 		mlme_err("PSOC is NULL");
177 		return QDF_STATUS_E_INVAL;
178 	}
179 
180 	if (vdev_rsp->rsp_status)
181 		wlan_objmgr_psoc_release_ref(psoc, WLAN_PSOC_TARGET_IF_ID);
182 
183 	return QDF_STATUS_SUCCESS;
184 }
185 
186 static void
187 target_if_vdev_mgr_rsp_cb_mc_ctx(void *arg)
188 {
189 	struct scheduler_msg msg = {0};
190 	struct vdev_response_timer *vdev_rsp = arg;
191 	struct wlan_objmgr_psoc *psoc;
192 
193 	psoc = vdev_rsp->psoc;
194 	if (!psoc) {
195 		mlme_err("PSOC is NULL");
196 		return;
197 	}
198 
199 	msg.type = SYS_MSG_ID_MC_TIMER;
200 	msg.reserved = SYS_MSG_COOKIE;
201 	msg.callback = target_if_vdev_mgr_rsp_timer_cb;
202 	msg.bodyptr = vdev_rsp;
203 	msg.bodyval = 0;
204 	msg.flush_callback = target_if_vdev_mgr_rsp_flush_cb;
205 
206 	if (scheduler_post_message(QDF_MODULE_ID_TARGET_IF,
207 				   QDF_MODULE_ID_TARGET_IF,
208 				   QDF_MODULE_ID_SYS, &msg) ==
209 				   QDF_STATUS_SUCCESS)
210 		return;
211 
212 	mlme_err("Could not enqueue timer to timer queue");
213 	if (psoc)
214 		wlan_objmgr_psoc_release_ref(psoc, WLAN_PSOC_TARGET_IF_ID);
215 }
216 
217 void target_if_vdev_mgr_rsp_timer_mgmt_cb(void *arg)
218 {
219 	target_if_vdev_mgr_rsp_cb_mc_ctx(arg);
220 }
221 
222 #define VDEV_RSP_RX_CTX WMI_RX_SERIALIZER_CTX
223 #else
224 void target_if_vdev_mgr_rsp_timer_mgmt_cb(void *arg)
225 {
226 	target_if_vdev_mgr_rsp_timer_cb(arg);
227 }
228 
229 #define VDEV_RSP_RX_CTX WMI_RX_UMAC_CTX
230 #endif
231 
232 static int target_if_vdev_mgr_start_response_handler(ol_scn_t scn,
233 						     uint8_t *data,
234 						     uint32_t datalen)
235 {
236 	QDF_STATUS status = QDF_STATUS_E_INVAL;
237 	struct wlan_objmgr_psoc *psoc;
238 	struct wmi_unified *wmi_handle;
239 	struct wlan_lmac_if_mlme_rx_ops *rx_ops;
240 	struct vdev_start_response rsp = {0};
241 	wmi_host_vdev_start_resp vdev_start_resp;
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 	rsp.vdev_id = vdev_start_resp.vdev_id;
296 	rsp.requestor_id = vdev_start_resp.requestor_id;
297 	rsp.status = vdev_start_resp.status;
298 	rsp.resp_type = vdev_start_resp.resp_type;
299 	rsp.chain_mask = vdev_start_resp.chain_mask;
300 	rsp.smps_mode = vdev_start_resp.smps_mode;
301 	rsp.mac_id = vdev_start_resp.mac_id;
302 	rsp.cfgd_tx_streams = vdev_start_resp.cfgd_tx_streams;
303 	rsp.cfgd_rx_streams = vdev_start_resp.cfgd_rx_streams;
304 
305 	status = rx_ops->vdev_mgr_start_response(psoc, &rsp);
306 
307 err:
308 	return qdf_status_to_os_return(status);
309 }
310 
311 static int target_if_vdev_mgr_stop_response_handler(ol_scn_t scn,
312 						    uint8_t *data,
313 						    uint32_t datalen)
314 {
315 	QDF_STATUS status = QDF_STATUS_E_INVAL;
316 	struct wlan_objmgr_psoc *psoc;
317 	struct wmi_unified *wmi_handle;
318 	struct wlan_lmac_if_mlme_rx_ops *rx_ops;
319 	struct vdev_stop_response rsp = {0};
320 	uint32_t vdev_id;
321 	struct vdev_response_timer *vdev_rsp;
322 
323 	if (!scn || !data) {
324 		mlme_err("Invalid input");
325 		return -EINVAL;
326 	}
327 
328 	psoc = target_if_get_psoc_from_scn_hdl(scn);
329 	if (!psoc) {
330 		mlme_err("PSOC is NULL");
331 		return -EINVAL;
332 	}
333 
334 	rx_ops = target_if_vdev_mgr_get_rx_ops(psoc);
335 	if (!rx_ops || !rx_ops->vdev_mgr_stop_response) {
336 		mlme_err("No Rx Ops");
337 		return -EINVAL;
338 	}
339 
340 	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
341 	if (!wmi_handle) {
342 		mlme_err("wmi_handle is null");
343 		return -EINVAL;
344 	}
345 
346 	if (wmi_extract_vdev_stopped_param(wmi_handle, data, &vdev_id)) {
347 		mlme_err("WMI extract failed");
348 		return -EINVAL;
349 	}
350 
351 	vdev_rsp = rx_ops->psoc_get_vdev_response_timer_info(psoc, vdev_id);
352 	if (!vdev_rsp) {
353 		mlme_err("vdev response timer is null VDEV_%d PSOC_%d",
354 			 vdev_id, wlan_psoc_get_id(psoc));
355 		return -EINVAL;
356 	}
357 
358 	status = target_if_vdev_mgr_rsp_timer_stop(psoc, vdev_rsp,
359 						   STOP_RESPONSE_BIT);
360 
361 	if (QDF_IS_STATUS_ERROR(status)) {
362 		mlme_err("PSOC_%d VDEV_%d: VDE MGR RSP Timer stop failed",
363 			 psoc->soc_objmgr.psoc_id, vdev_id);
364 		goto err;
365 	}
366 
367 	rsp.vdev_id = vdev_id;
368 	status = rx_ops->vdev_mgr_stop_response(psoc, &rsp);
369 
370 err:
371 	return qdf_status_to_os_return(status);
372 }
373 
374 static int target_if_vdev_mgr_delete_response_handler(ol_scn_t scn,
375 						      uint8_t *data,
376 						      uint32_t datalen)
377 {
378 	QDF_STATUS status = QDF_STATUS_E_INVAL;
379 	struct wlan_objmgr_psoc *psoc;
380 	struct wmi_unified *wmi_handle;
381 	struct wlan_lmac_if_mlme_rx_ops *rx_ops;
382 	struct vdev_delete_response rsp = {0};
383 	struct wmi_host_vdev_delete_resp vdev_del_resp;
384 	struct vdev_response_timer *vdev_rsp;
385 
386 	if (!scn || !data) {
387 		mlme_err("Invalid input");
388 		return -EINVAL;
389 	}
390 
391 	psoc = target_if_get_psoc_from_scn_hdl(scn);
392 	if (!psoc) {
393 		mlme_err("PSOC is NULL");
394 		return -EINVAL;
395 	}
396 
397 	rx_ops = target_if_vdev_mgr_get_rx_ops(psoc);
398 	if (!rx_ops || !rx_ops->vdev_mgr_delete_response) {
399 		mlme_err("No Rx Ops");
400 		return -EINVAL;
401 	}
402 
403 	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
404 	if (!wmi_handle) {
405 		mlme_err("wmi_handle is null");
406 		return -EINVAL;
407 	}
408 
409 	if (wmi_extract_vdev_delete_resp(wmi_handle, data, &vdev_del_resp)) {
410 		mlme_err("WMI extract failed");
411 		return -EINVAL;
412 	}
413 
414 	vdev_rsp = rx_ops->psoc_get_vdev_response_timer_info(psoc,
415 							 vdev_del_resp.vdev_id);
416 	if (!vdev_rsp) {
417 		mlme_err("vdev response timer is null VDEV_%d PSOC_%d",
418 			 vdev_del_resp.vdev_id, wlan_psoc_get_id(psoc));
419 		return -EINVAL;
420 	}
421 
422 	status = target_if_vdev_mgr_rsp_timer_stop(
423 						psoc, vdev_rsp,
424 						DELETE_RESPONSE_BIT);
425 
426 	if (QDF_IS_STATUS_ERROR(status)) {
427 		mlme_err("PSOC_%d VDEV_%d: VDE MGR RSP Timer stop failed",
428 			 wlan_psoc_get_id(psoc), vdev_del_resp.vdev_id);
429 		goto err;
430 	}
431 
432 	rsp.vdev_id = vdev_del_resp.vdev_id;
433 	status = rx_ops->vdev_mgr_delete_response(psoc, &rsp);
434 
435 err:
436 	return qdf_status_to_os_return(status);
437 }
438 
439 static int target_if_vdev_mgr_peer_delete_all_response_handler(
440 							ol_scn_t scn,
441 							uint8_t *data,
442 							uint32_t datalen)
443 {
444 	QDF_STATUS status = QDF_STATUS_E_INVAL;
445 	struct wlan_objmgr_psoc *psoc;
446 	struct wmi_unified *wmi_handle;
447 	struct wlan_lmac_if_mlme_rx_ops *rx_ops;
448 	struct peer_delete_all_response rsp = {0};
449 	struct wmi_host_vdev_peer_delete_all_response_event
450 						vdev_peer_del_all_resp;
451 	struct vdev_response_timer *vdev_rsp;
452 
453 	if (!scn || !data) {
454 		mlme_err("Invalid input");
455 		return -EINVAL;
456 	}
457 
458 	psoc = target_if_get_psoc_from_scn_hdl(scn);
459 	if (!psoc) {
460 		mlme_err("PSOC is NULL");
461 		return -EINVAL;
462 	}
463 
464 	rx_ops = target_if_vdev_mgr_get_rx_ops(psoc);
465 	if (!rx_ops || !rx_ops->vdev_mgr_peer_delete_all_response) {
466 		mlme_err("No Rx Ops");
467 		return -EINVAL;
468 	}
469 
470 	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
471 	if (!wmi_handle) {
472 		mlme_err("wmi_handle is null");
473 		return -EINVAL;
474 	}
475 
476 	if (wmi_extract_vdev_peer_delete_all_response_event(
477 						wmi_handle, data,
478 						&vdev_peer_del_all_resp)) {
479 		mlme_err("WMI extract failed");
480 		return -EINVAL;
481 	}
482 
483 	vdev_rsp = rx_ops->psoc_get_vdev_response_timer_info(psoc,
484 						vdev_peer_del_all_resp.vdev_id);
485 	if (!vdev_rsp) {
486 		mlme_err("vdev response timer is null VDEV_%d PSOC_%d",
487 			 vdev_peer_del_all_resp.vdev_id,
488 			 wlan_psoc_get_id(psoc));
489 		return -EINVAL;
490 	}
491 
492 	status = target_if_vdev_mgr_rsp_timer_stop(
493 						psoc,
494 						vdev_rsp,
495 						PEER_DELETE_ALL_RESPONSE_BIT);
496 
497 	if (QDF_IS_STATUS_ERROR(status)) {
498 		mlme_err("PSOC_%d VDEV_%d: VDE MGR RSP Timer stop failed",
499 			 psoc->soc_objmgr.psoc_id,
500 			 vdev_peer_del_all_resp.vdev_id);
501 		goto err;
502 	}
503 
504 	rsp.vdev_id = vdev_peer_del_all_resp.vdev_id;
505 	rsp.status = vdev_peer_del_all_resp.status;
506 	status = rx_ops->vdev_mgr_peer_delete_all_response(psoc, &rsp);
507 
508 err:
509 	return qdf_status_to_os_return(status);
510 }
511 
512 int target_if_vdev_mgr_offload_bcn_tx_status_handler(
513 					ol_scn_t scn,
514 					uint8_t *data,
515 					uint32_t datalen)
516 {
517 	QDF_STATUS status;
518 	struct wlan_objmgr_psoc *psoc;
519 	struct wmi_unified *wmi_handle;
520 	struct wlan_lmac_if_mlme_rx_ops *rx_ops;
521 	uint32_t vdev_id, tx_status;
522 
523 	if (!scn || !data) {
524 		mlme_err("Invalid input");
525 		return -EINVAL;
526 	}
527 	psoc = target_if_get_psoc_from_scn_hdl(scn);
528 	if (!psoc) {
529 		mlme_err("PSOC is NULL");
530 		return -EINVAL;
531 	}
532 
533 	rx_ops = target_if_vdev_mgr_get_rx_ops(psoc);
534 	if (!rx_ops || !rx_ops->vdev_mgr_offload_bcn_tx_status_event_handle) {
535 		mlme_err("No Rx Ops");
536 		return -EINVAL;
537 	}
538 
539 	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
540 	if (!wmi_handle) {
541 		mlme_err("wmi_handle is null");
542 		return -EINVAL;
543 	}
544 
545 	if (wmi_extract_offload_bcn_tx_status_evt(wmi_handle, data,
546 						  &vdev_id, &tx_status)) {
547 		mlme_err("WMI extract failed");
548 		return -EINVAL;
549 	}
550 
551 	status = rx_ops->vdev_mgr_offload_bcn_tx_status_event_handle(
552 								vdev_id,
553 								tx_status);
554 
555 	return qdf_status_to_os_return(status);
556 }
557 
558 int target_if_vdev_mgr_tbttoffset_update_handler(
559 						ol_scn_t scn, uint8_t *data,
560 						uint32_t datalen)
561 {
562 	QDF_STATUS status;
563 	struct wlan_objmgr_psoc *psoc;
564 	struct wmi_unified *wmi_handle;
565 	struct wlan_lmac_if_mlme_rx_ops *rx_ops;
566 	uint32_t num_vdevs = 0;
567 
568 	if (!scn || !data) {
569 		mlme_err("Invalid input");
570 		return -EINVAL;
571 	}
572 	psoc = target_if_get_psoc_from_scn_hdl(scn);
573 	if (!psoc) {
574 		mlme_err("PSOC is NULL");
575 		return -EINVAL;
576 	}
577 
578 	rx_ops = target_if_vdev_mgr_get_rx_ops(psoc);
579 	if (!rx_ops || !rx_ops->vdev_mgr_tbttoffset_update_handle) {
580 		mlme_err("No Rx Ops");
581 		return -EINVAL;
582 	}
583 
584 	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
585 	if (!wmi_handle) {
586 		mlme_err("wmi_handle is null");
587 		return -EINVAL;
588 	}
589 
590 	if (wmi_extract_tbttoffset_num_vdevs(wmi_handle, data, &num_vdevs)) {
591 		mlme_err("WMI extract failed");
592 		return -EINVAL;
593 	}
594 
595 	status = rx_ops->vdev_mgr_tbttoffset_update_handle(num_vdevs,
596 							   false);
597 
598 	return qdf_status_to_os_return(status);
599 }
600 
601 int target_if_vdev_mgr_ext_tbttoffset_update_handler(
602 						ol_scn_t scn,
603 						uint8_t *data,
604 						uint32_t datalen)
605 {
606 	QDF_STATUS status;
607 	struct wlan_objmgr_psoc *psoc;
608 	struct wmi_unified *wmi_handle;
609 	struct wlan_lmac_if_mlme_rx_ops *rx_ops;
610 	uint32_t num_vdevs = 0;
611 
612 	if (!scn || !data) {
613 		mlme_err("Invalid input");
614 		return -EINVAL;
615 	}
616 	psoc = target_if_get_psoc_from_scn_hdl(scn);
617 	if (!psoc) {
618 		mlme_err("PSOC is NULL");
619 		return -EINVAL;
620 	}
621 
622 	rx_ops = target_if_vdev_mgr_get_rx_ops(psoc);
623 	if (!rx_ops || !rx_ops->vdev_mgr_tbttoffset_update_handle) {
624 		mlme_err("No Rx Ops");
625 		return -EINVAL;
626 	}
627 
628 	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
629 	if (!wmi_handle) {
630 		mlme_err("wmi_handle is null");
631 		return -EINVAL;
632 	}
633 
634 	if (wmi_extract_ext_tbttoffset_num_vdevs(wmi_handle, data,
635 						 &num_vdevs)) {
636 		mlme_err("WMI extract failed");
637 		return -EINVAL;
638 	}
639 
640 	status = rx_ops->vdev_mgr_tbttoffset_update_handle(num_vdevs,
641 							   true);
642 
643 	return qdf_status_to_os_return(status);
644 }
645 
646 static int target_if_vdev_mgr_multi_vdev_restart_resp_handler(
647 							ol_scn_t scn,
648 							uint8_t *data,
649 							uint32_t datalen)
650 {
651 	QDF_STATUS status = QDF_STATUS_E_INVAL;
652 	struct wlan_objmgr_psoc *psoc;
653 	struct wmi_unified *wmi_handle;
654 	struct wlan_lmac_if_mlme_rx_ops *rx_ops;
655 	struct multi_vdev_restart_resp restart_resp;
656 	struct vdev_response_timer *vdev_rsp;
657 	uint8_t max_vdevs, vdev_idx;
658 
659 	if (!scn || !data) {
660 		mlme_err("Invalid input");
661 		return -EINVAL;
662 	}
663 
664 	psoc = target_if_get_psoc_from_scn_hdl(scn);
665 	if (!psoc) {
666 		mlme_err("PSOC is NULL");
667 		return -EINVAL;
668 	}
669 
670 	rx_ops = target_if_vdev_mgr_get_rx_ops(psoc);
671 	if (!rx_ops || !rx_ops->vdev_mgr_multi_vdev_restart_resp ||
672 	    !rx_ops->psoc_get_vdev_response_timer_info) {
673 		mlme_err("No Rx Ops");
674 		return -EINVAL;
675 	}
676 
677 	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
678 	if (!wmi_handle) {
679 		mlme_err("wmi_handle is null");
680 		return -EINVAL;
681 	}
682 
683 	qdf_mem_zero(&restart_resp, sizeof(restart_resp));
684 	if (wmi_extract_multi_vdev_restart_resp_event(wmi_handle, data,
685 						      &restart_resp)) {
686 		mlme_err("WMI extract failed");
687 		return -EINVAL;
688 	}
689 
690 	max_vdevs = wlan_psoc_get_max_vdev_count(psoc);
691 	for (vdev_idx = 0; vdev_idx < max_vdevs; vdev_idx++) {
692 		if (!qdf_test_bit(vdev_idx, restart_resp.vdev_id_bmap))
693 			continue;
694 
695 		mlme_debug("PSOC_%d VDEV_%d: Restart resp received",
696 			   wlan_psoc_get_id(psoc), vdev_idx);
697 		vdev_rsp = rx_ops->psoc_get_vdev_response_timer_info(psoc,
698 								     vdev_idx);
699 		if (!vdev_rsp) {
700 			mlme_err("PSOC_%d VDEV_%d: VDEV RSP is NULL",
701 				 wlan_psoc_get_id(psoc), vdev_idx);
702 			continue;
703 		}
704 
705 		status = target_if_vdev_mgr_rsp_timer_stop(
706 				psoc, vdev_rsp, RESTART_RESPONSE_BIT);
707 		if (QDF_IS_STATUS_ERROR(status))
708 			mlme_err("PSOC_%d VDEV_%d: VDE MGR RSP Timer stop failed",
709 				 wlan_psoc_get_id(psoc), vdev_idx);
710 	}
711 
712 	status = rx_ops->vdev_mgr_multi_vdev_restart_resp(psoc, &restart_resp);
713 
714 	return qdf_status_to_os_return(status);
715 }
716 
717 QDF_STATUS target_if_vdev_mgr_wmi_event_register(
718 				struct wlan_objmgr_psoc *psoc)
719 {
720 	int retval = 0;
721 	struct wmi_unified *wmi_handle;
722 
723 	if (!psoc) {
724 		mlme_err("PSOC is NULL");
725 		return QDF_STATUS_E_NULL_VALUE;
726 	}
727 
728 	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
729 	if (!wmi_handle) {
730 		mlme_err("wmi_handle is null");
731 		return QDF_STATUS_E_INVAL;
732 	}
733 
734 	retval = wmi_unified_register_event_handler(
735 				wmi_handle,
736 				wmi_vdev_stopped_event_id,
737 				target_if_vdev_mgr_stop_response_handler,
738 				VDEV_RSP_RX_CTX);
739 	if (retval)
740 		mlme_err("failed to register for stop response");
741 
742 	retval = wmi_unified_register_event_handler(
743 				wmi_handle,
744 				wmi_vdev_delete_resp_event_id,
745 				target_if_vdev_mgr_delete_response_handler,
746 				VDEV_RSP_RX_CTX);
747 	if (retval)
748 		mlme_err("failed to register for delete response");
749 
750 	retval = wmi_unified_register_event_handler(
751 				wmi_handle,
752 				wmi_vdev_start_resp_event_id,
753 				target_if_vdev_mgr_start_response_handler,
754 				VDEV_RSP_RX_CTX);
755 	if (retval)
756 		mlme_err("failed to register for start response");
757 
758 	retval = wmi_unified_register_event_handler(
759 			wmi_handle,
760 			wmi_peer_delete_all_response_event_id,
761 			target_if_vdev_mgr_peer_delete_all_response_handler,
762 			VDEV_RSP_RX_CTX);
763 	if (retval)
764 		mlme_err("failed to register for peer delete all response");
765 
766 	retval = wmi_unified_register_event_handler(
767 			wmi_handle,
768 			wmi_pdev_multi_vdev_restart_response_event_id,
769 			target_if_vdev_mgr_multi_vdev_restart_resp_handler,
770 			VDEV_RSP_RX_CTX);
771 	if (retval)
772 		mlme_err("failed to register for multivdev restart response");
773 
774 	return qdf_status_from_os_return(retval);
775 }
776 
777 QDF_STATUS target_if_vdev_mgr_wmi_event_unregister(
778 					struct wlan_objmgr_psoc *psoc)
779 {
780 	struct wmi_unified *wmi_handle;
781 
782 	if (!psoc) {
783 		mlme_err("PSOC is NULL");
784 		return QDF_STATUS_E_INVAL;
785 	}
786 
787 	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
788 	if (!wmi_handle) {
789 		mlme_err("wmi_handle is null");
790 		return QDF_STATUS_E_INVAL;
791 	}
792 
793 	wmi_unified_unregister_event_handler(
794 			wmi_handle,
795 			wmi_pdev_multi_vdev_restart_response_event_id);
796 
797 	wmi_unified_unregister_event_handler(
798 			wmi_handle,
799 			wmi_peer_delete_all_response_event_id);
800 
801 	wmi_unified_unregister_event_handler(wmi_handle,
802 					     wmi_vdev_start_resp_event_id);
803 
804 	wmi_unified_unregister_event_handler(wmi_handle,
805 					     wmi_vdev_delete_resp_event_id);
806 
807 	wmi_unified_unregister_event_handler(wmi_handle,
808 					     wmi_vdev_stopped_event_id);
809 
810 	return QDF_STATUS_SUCCESS;
811 }
812