1 /*
2 * Copyright (c) 2019-2020 The Linux Foundation. All rights reserved.
3 * Copyright (c) 2021-2023 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 #include <wlan_reg_services_api.h>
40 #ifdef DP_UMAC_HW_RESET_SUPPORT
41 #include <cdp_txrx_ctrl.h>
42 #endif
43
44 static inline
target_if_vdev_mgr_handle_recovery(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id,enum qdf_hang_reason recovery_reason,uint16_t rsp_pos)45 void target_if_vdev_mgr_handle_recovery(struct wlan_objmgr_psoc *psoc,
46 uint8_t vdev_id,
47 enum qdf_hang_reason recovery_reason,
48 uint16_t rsp_pos)
49 {
50 mlme_nofl_err("PSOC_%d VDEV_%d: %s rsp timeout", wlan_psoc_get_id(psoc),
51 vdev_id, string_from_rsp_bit(rsp_pos));
52 if (target_if_vdev_mgr_is_panic_allowed())
53 qdf_trigger_self_recovery(psoc, recovery_reason);
54 else
55 mlme_nofl_debug("PSOC_%d VDEV_%d: Panic not allowed",
56 wlan_psoc_get_id(psoc), vdev_id);
57 }
58
59 #ifdef WLAN_FEATURE_ROAM_OFFLOAD
60 static inline QDF_STATUS
target_if_send_rso_stop_failure_rsp(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id)61 target_if_send_rso_stop_failure_rsp(struct wlan_objmgr_psoc *psoc,
62 uint8_t vdev_id)
63 {
64 return target_if_cm_send_rso_stop_failure_rsp(psoc, vdev_id);
65 }
66 #else
67 static inline QDF_STATUS
target_if_send_rso_stop_failure_rsp(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id)68 target_if_send_rso_stop_failure_rsp(struct wlan_objmgr_psoc *psoc,
69 uint8_t vdev_id)
70 {
71 return QDF_STATUS_E_NOSUPPORT;
72 }
73 #endif
74
75 #ifdef WLAN_FEATURE_DYNAMIC_MAC_ADDR_UPDATE
76 static void
target_if_vdev_mgr_mac_addr_rsp_timeout(struct wlan_objmgr_psoc * psoc,struct vdev_response_timer * vdev_rsp,uint8_t vdev_id)77 target_if_vdev_mgr_mac_addr_rsp_timeout(struct wlan_objmgr_psoc *psoc,
78 struct vdev_response_timer *vdev_rsp,
79 uint8_t vdev_id)
80 {
81 uint16_t rsp_pos;
82 struct wlan_objmgr_vdev *vdev;
83 enum qdf_hang_reason recovery_reason;
84 struct wlan_lmac_if_mlme_rx_ops *rx_ops;
85
86 rx_ops = target_if_vdev_mgr_get_rx_ops(psoc);
87 if (!rx_ops) {
88 mlme_err("No Rx Ops");
89 return;
90 }
91
92 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
93 WLAN_VDEV_TARGET_IF_ID);
94 if (!vdev) {
95 mlme_err("Invalid vdev %d", vdev_id);
96 return;
97 }
98
99 rsp_pos = UPDATE_MAC_ADDR_RESPONSE_BIT;
100 recovery_reason = QDF_VDEV_MAC_ADDR_UPDATE_RESPONSE_TIMED_OUT;
101 target_if_vdev_mgr_rsp_timer_stop(psoc, vdev_rsp, rsp_pos);
102 target_if_vdev_mgr_handle_recovery(psoc, vdev_id,
103 recovery_reason, rsp_pos);
104 rx_ops->vdev_mgr_set_mac_addr_response(vdev, -EAGAIN);
105 wlan_objmgr_vdev_release_ref(vdev, WLAN_VDEV_TARGET_IF_ID);
106 }
107 #else
108 static inline void
target_if_vdev_mgr_mac_addr_rsp_timeout(struct wlan_objmgr_psoc * psoc,struct vdev_response_timer * vdev_rsp,uint8_t vdev_id)109 target_if_vdev_mgr_mac_addr_rsp_timeout(struct wlan_objmgr_psoc *psoc,
110 struct vdev_response_timer *vdev_rsp,
111 uint8_t vdev_id)
112 {
113 }
114 #endif
115
116 #ifdef DP_UMAC_HW_RESET_SUPPORT
117 /**
118 * target_if_check_and_restart_vdev_mgr_rsp_timer - Check and restart the vdev
119 * manager response timer if UMAC reset is in progress
120 * @vdev_rsp: Pointer to vdev response timer structure
121 *
122 * Return: QDF_STATUS
123 */
124 static inline QDF_STATUS
target_if_check_and_restart_vdev_mgr_rsp_timer(struct vdev_response_timer * vdev_rsp)125 target_if_check_and_restart_vdev_mgr_rsp_timer(
126 struct vdev_response_timer *vdev_rsp)
127 {
128 ol_txrx_soc_handle soc_txrx_handle;
129
130 soc_txrx_handle = wlan_psoc_get_dp_handle(vdev_rsp->psoc);
131
132 if (!soc_txrx_handle)
133 return QDF_STATUS_E_INVAL;
134
135 /* Restart the timer if UMAC reset is inprogress */
136 if (cdp_umac_reset_is_inprogress(soc_txrx_handle)) {
137 mlme_debug("Umac reset is in progress, restart the vdev manager response timer");
138 qdf_timer_mod(&vdev_rsp->rsp_timer, vdev_rsp->expire_time);
139 return QDF_STATUS_SUCCESS;
140 }
141
142 return QDF_STATUS_E_FAILURE;
143 }
144 #else
145 static inline QDF_STATUS
target_if_check_and_restart_vdev_mgr_rsp_timer(struct vdev_response_timer * vdev_rsp)146 target_if_check_and_restart_vdev_mgr_rsp_timer(
147 struct vdev_response_timer *vdev_rsp)
148 {
149 return QDF_STATUS_E_FAILURE;
150 }
151 #endif
152
target_if_vdev_mgr_rsp_timer_cb(void * arg)153 void target_if_vdev_mgr_rsp_timer_cb(void *arg)
154 {
155 struct wlan_objmgr_psoc *psoc;
156 struct wlan_lmac_if_mlme_rx_ops *rx_ops;
157 struct vdev_start_response start_rsp = {0};
158 struct vdev_stop_response stop_rsp = {0};
159 struct vdev_delete_response del_rsp = {0};
160 struct peer_delete_all_response peer_del_all_rsp = {0};
161 struct vdev_response_timer *vdev_rsp = arg;
162 enum qdf_hang_reason recovery_reason;
163 uint8_t vdev_id;
164 uint16_t rsp_pos = RESPONSE_BIT_MAX;
165 QDF_STATUS status;
166
167 if (!vdev_rsp) {
168 mlme_err("Vdev response timer is NULL");
169 return;
170 }
171
172 psoc = vdev_rsp->psoc;
173 if (!psoc) {
174 mlme_err("PSOC is NULL");
175 return;
176 }
177
178 rx_ops = target_if_vdev_mgr_get_rx_ops(psoc);
179 if (!rx_ops || !rx_ops->psoc_get_vdev_response_timer_info) {
180 mlme_err("No Rx Ops");
181 return;
182 }
183
184 if (!qdf_atomic_test_bit(START_RESPONSE_BIT, &vdev_rsp->rsp_status) &&
185 !qdf_atomic_test_bit(RESTART_RESPONSE_BIT, &vdev_rsp->rsp_status) &&
186 !qdf_atomic_test_bit(STOP_RESPONSE_BIT, &vdev_rsp->rsp_status) &&
187 !qdf_atomic_test_bit(DELETE_RESPONSE_BIT, &vdev_rsp->rsp_status) &&
188 !qdf_atomic_test_bit(PEER_DELETE_ALL_RESPONSE_BIT,
189 &vdev_rsp->rsp_status) &&
190 !qdf_atomic_test_bit(RSO_STOP_RESPONSE_BIT,
191 &vdev_rsp->rsp_status) &&
192 !qdf_atomic_test_bit(UPDATE_MAC_ADDR_RESPONSE_BIT,
193 &vdev_rsp->rsp_status)) {
194 mlme_debug("No response bit is set, ignoring actions :%d",
195 vdev_rsp->vdev_id);
196 return;
197 }
198
199 vdev_id = vdev_rsp->vdev_id;
200 if (vdev_id >= WLAN_UMAC_PSOC_MAX_VDEVS) {
201 mlme_err("Invalid VDEV_%d PSOC_%d", vdev_id,
202 wlan_psoc_get_id(psoc));
203 return;
204 }
205
206 vdev_rsp->timer_status = QDF_STATUS_E_TIMEOUT;
207 if (qdf_atomic_test_bit(START_RESPONSE_BIT,
208 &vdev_rsp->rsp_status) ||
209 qdf_atomic_test_bit(RESTART_RESPONSE_BIT,
210 &vdev_rsp->rsp_status)) {
211 start_rsp.vdev_id = vdev_id;
212 start_rsp.status = WLAN_MLME_HOST_VDEV_START_TIMEOUT;
213 if (qdf_atomic_test_bit(START_RESPONSE_BIT,
214 &vdev_rsp->rsp_status)) {
215 start_rsp.resp_type =
216 WMI_HOST_VDEV_START_RESP_EVENT;
217 rsp_pos = START_RESPONSE_BIT;
218 recovery_reason = QDF_VDEV_START_RESPONSE_TIMED_OUT;
219 } else {
220 start_rsp.resp_type =
221 WMI_HOST_VDEV_RESTART_RESP_EVENT;
222 rsp_pos = RESTART_RESPONSE_BIT;
223 recovery_reason = QDF_VDEV_RESTART_RESPONSE_TIMED_OUT;
224 }
225
226 target_if_vdev_mgr_rsp_timer_stop(psoc, vdev_rsp, rsp_pos);
227 target_if_vdev_mgr_handle_recovery(psoc, vdev_id,
228 recovery_reason, rsp_pos);
229 rx_ops->vdev_mgr_start_response(psoc, &start_rsp);
230 } else if (qdf_atomic_test_bit(STOP_RESPONSE_BIT,
231 &vdev_rsp->rsp_status)) {
232 rsp_pos = STOP_RESPONSE_BIT;
233 stop_rsp.vdev_id = vdev_id;
234 recovery_reason = QDF_VDEV_STOP_RESPONSE_TIMED_OUT;
235
236 target_if_vdev_mgr_rsp_timer_stop(psoc, vdev_rsp, rsp_pos);
237 target_if_vdev_mgr_handle_recovery(psoc, vdev_id,
238 recovery_reason, rsp_pos);
239 rx_ops->vdev_mgr_stop_response(psoc, &stop_rsp);
240 } else if (qdf_atomic_test_bit(DELETE_RESPONSE_BIT,
241 &vdev_rsp->rsp_status)) {
242 status = target_if_check_and_restart_vdev_mgr_rsp_timer(
243 vdev_rsp);
244 if (QDF_IS_STATUS_SUCCESS(status))
245 return;
246
247 del_rsp.vdev_id = vdev_id;
248 rsp_pos = DELETE_RESPONSE_BIT;
249 recovery_reason = QDF_VDEV_DELETE_RESPONSE_TIMED_OUT;
250 target_if_vdev_mgr_rsp_timer_stop(psoc, vdev_rsp, rsp_pos);
251 target_if_vdev_mgr_handle_recovery(psoc, vdev_id,
252 recovery_reason, rsp_pos);
253 rx_ops->vdev_mgr_delete_response(psoc, &del_rsp);
254 } else if (qdf_atomic_test_bit(PEER_DELETE_ALL_RESPONSE_BIT,
255 &vdev_rsp->rsp_status)) {
256 status = target_if_check_and_restart_vdev_mgr_rsp_timer(
257 vdev_rsp);
258 if (QDF_IS_STATUS_SUCCESS(status))
259 return;
260
261 peer_del_all_rsp.vdev_id = vdev_id;
262 peer_del_all_rsp.peer_type_bitmap = vdev_rsp->peer_type_bitmap;
263 rsp_pos = PEER_DELETE_ALL_RESPONSE_BIT;
264 recovery_reason = QDF_VDEV_PEER_DELETE_ALL_RESPONSE_TIMED_OUT;
265 target_if_vdev_mgr_rsp_timer_stop(psoc, vdev_rsp, rsp_pos);
266 target_if_vdev_mgr_handle_recovery(psoc, vdev_id,
267 recovery_reason, rsp_pos);
268 rx_ops->vdev_mgr_peer_delete_all_response(psoc,
269 &peer_del_all_rsp);
270 } else if (qdf_atomic_test_bit(RSO_STOP_RESPONSE_BIT,
271 &vdev_rsp->rsp_status)) {
272 rsp_pos = RSO_STOP_RESPONSE_BIT;
273 target_if_vdev_mgr_rsp_timer_stop(psoc, vdev_rsp, rsp_pos);
274 /**
275 * FW did not respond to rso stop cmd, as roaming is
276 * disabled either due to race condition
277 * that happened during previous disconnect OR
278 * supplicant disabled roaming.
279 * To solve this issue, skip recovery and host will
280 * continue disconnect and cleanup rso state.
281 */
282 mlme_debug("No rsp from FW received , continue with disconnect");
283 target_if_send_rso_stop_failure_rsp(psoc, vdev_id);
284 } else if (qdf_atomic_test_bit(UPDATE_MAC_ADDR_RESPONSE_BIT,
285 &vdev_rsp->rsp_status)) {
286 mlme_debug("VDEV %d MAC addr update resp timeout", vdev_id);
287 target_if_vdev_mgr_mac_addr_rsp_timeout(psoc,
288 vdev_rsp, vdev_id);
289 } else {
290 mlme_err("PSOC_%d VDEV_%d: Unknown error",
291 wlan_psoc_get_id(psoc), vdev_id);
292 return;
293 }
294 }
295
296 #ifdef SERIALIZE_VDEV_RESP
target_if_vdev_mgr_rsp_flush_cb_mc(struct scheduler_msg * msg)297 static QDF_STATUS target_if_vdev_mgr_rsp_flush_cb_mc(struct scheduler_msg *msg)
298 {
299 struct vdev_response_timer *vdev_rsp;
300 struct wlan_objmgr_psoc *psoc;
301
302 if (!msg->bodyptr) {
303 mlme_err("Message bodyptr is NULL");
304 return QDF_STATUS_E_INVAL;
305 }
306
307 vdev_rsp = scheduler_qdf_mc_timer_deinit_return_data_ptr(msg->bodyptr);
308 if (!vdev_rsp) {
309 mlme_err("vdev response timer is NULL");
310 return QDF_STATUS_E_INVAL;
311 }
312
313 psoc = vdev_rsp->psoc;
314 if (!psoc) {
315 mlme_err("PSOC is NULL");
316 return QDF_STATUS_E_INVAL;
317 }
318
319 if (vdev_rsp->rsp_status)
320 wlan_objmgr_psoc_release_ref(psoc, WLAN_PSOC_TARGET_IF_ID);
321
322 return QDF_STATUS_SUCCESS;
323 }
324
325 static void
target_if_vdev_mgr_rsp_cb_mc_ctx(void * arg)326 target_if_vdev_mgr_rsp_cb_mc_ctx(void *arg)
327 {
328 struct scheduler_msg msg = {0};
329 struct vdev_response_timer *vdev_rsp = arg;
330 struct wlan_objmgr_psoc *psoc;
331 struct sched_qdf_mc_timer_cb_wrapper *mc_timer_wrapper;
332
333 psoc = vdev_rsp->psoc;
334 if (!psoc) {
335 mlme_err("PSOC is NULL");
336 return;
337 }
338
339 msg.type = SYS_MSG_ID_MC_TIMER;
340 msg.reserved = SYS_MSG_COOKIE;
341
342 mc_timer_wrapper = scheduler_qdf_mc_timer_init(
343 target_if_vdev_mgr_rsp_timer_cb,
344 arg);
345
346 if (!mc_timer_wrapper) {
347 mlme_err("failed to allocate sched_qdf_mc_timer_cb_wrapper");
348 return;
349 }
350
351 msg.callback = scheduler_qdf_mc_timer_callback_t_wrapper;
352 msg.bodyptr = mc_timer_wrapper;
353 msg.bodyval = 0;
354 msg.flush_callback = target_if_vdev_mgr_rsp_flush_cb_mc;
355
356 if (scheduler_post_message(QDF_MODULE_ID_TARGET_IF,
357 QDF_MODULE_ID_TARGET_IF,
358 QDF_MODULE_ID_SYS, &msg) ==
359 QDF_STATUS_SUCCESS)
360 return;
361
362 mlme_err("Could not enqueue timer to timer queue");
363 qdf_mem_free(mc_timer_wrapper);
364 if (psoc)
365 wlan_objmgr_psoc_release_ref(psoc, WLAN_PSOC_TARGET_IF_ID);
366 }
367
target_if_vdev_mgr_rsp_timer_mgmt_cb(void * arg)368 void target_if_vdev_mgr_rsp_timer_mgmt_cb(void *arg)
369 {
370 target_if_vdev_mgr_rsp_cb_mc_ctx(arg);
371 }
372
373 #define VDEV_RSP_RX_CTX WMI_RX_SERIALIZER_CTX
374 #else
target_if_vdev_mgr_rsp_timer_mgmt_cb(void * arg)375 void target_if_vdev_mgr_rsp_timer_mgmt_cb(void *arg)
376 {
377 target_if_vdev_mgr_rsp_timer_cb(arg);
378 }
379
380 #define VDEV_RSP_RX_CTX WMI_RX_UMAC_CTX
381 #endif
382
target_if_vdev_mgr_start_response_handler(ol_scn_t scn,uint8_t * data,uint32_t datalen)383 static int target_if_vdev_mgr_start_response_handler(ol_scn_t scn,
384 uint8_t *data,
385 uint32_t datalen)
386 {
387 QDF_STATUS status = QDF_STATUS_E_INVAL;
388 struct wlan_objmgr_psoc *psoc;
389 struct wmi_unified *wmi_handle;
390 struct wlan_lmac_if_mlme_rx_ops *rx_ops;
391 struct vdev_start_response vdev_start_resp = {0};
392 uint8_t vdev_id;
393 struct vdev_response_timer *vdev_rsp;
394
395 if (!scn || !data) {
396 mlme_err("Invalid input");
397 return -EINVAL;
398 }
399
400 psoc = target_if_get_psoc_from_scn_hdl(scn);
401 if (!psoc) {
402 mlme_err("PSOC is NULL");
403 return -EINVAL;
404 }
405
406 rx_ops = target_if_vdev_mgr_get_rx_ops(psoc);
407 if (!rx_ops || !rx_ops->vdev_mgr_start_response) {
408 mlme_err("No Rx Ops");
409 return -EINVAL;
410 }
411
412 wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
413 if (!wmi_handle) {
414 mlme_err("wmi_handle is null");
415 return -EINVAL;
416 }
417
418 if (wmi_extract_vdev_start_resp(wmi_handle, data, &vdev_start_resp)) {
419 mlme_err("WMI extract failed");
420 return -EINVAL;
421 }
422
423 vdev_id = vdev_start_resp.vdev_id;
424 vdev_rsp = rx_ops->psoc_get_vdev_response_timer_info(psoc, vdev_id);
425 if (!vdev_rsp) {
426 mlme_err("vdev response timer is null VDEV_%d PSOC_%d",
427 vdev_id, wlan_psoc_get_id(psoc));
428 return -EINVAL;
429 }
430
431 if (vdev_start_resp.resp_type == WMI_HOST_VDEV_RESTART_RESP_EVENT)
432 status = target_if_vdev_mgr_rsp_timer_stop(
433 psoc, vdev_rsp,
434 RESTART_RESPONSE_BIT);
435 else
436 status = target_if_vdev_mgr_rsp_timer_stop(psoc, vdev_rsp,
437 START_RESPONSE_BIT);
438
439 if (QDF_IS_STATUS_ERROR(status)) {
440 mlme_err("PSOC_%d VDEV_%d: VDE MGR RSP Timer stop failed",
441 psoc->soc_objmgr.psoc_id, vdev_id);
442 goto err;
443 }
444
445 status = rx_ops->vdev_mgr_start_response(psoc, &vdev_start_resp);
446
447 err:
448 return qdf_status_to_os_return(status);
449 }
450
target_if_vdev_mgr_stop_response_handler(ol_scn_t scn,uint8_t * data,uint32_t datalen)451 static int target_if_vdev_mgr_stop_response_handler(ol_scn_t scn,
452 uint8_t *data,
453 uint32_t datalen)
454 {
455 QDF_STATUS status = QDF_STATUS_E_INVAL;
456 struct wlan_objmgr_psoc *psoc;
457 struct wmi_unified *wmi_handle;
458 struct wlan_lmac_if_mlme_rx_ops *rx_ops;
459 struct vdev_stop_response rsp = {0};
460 uint32_t vdev_id;
461 struct vdev_response_timer *vdev_rsp;
462
463 if (!scn || !data) {
464 mlme_err("Invalid input");
465 return -EINVAL;
466 }
467
468 psoc = target_if_get_psoc_from_scn_hdl(scn);
469 if (!psoc) {
470 mlme_err("PSOC is NULL");
471 return -EINVAL;
472 }
473
474 rx_ops = target_if_vdev_mgr_get_rx_ops(psoc);
475 if (!rx_ops || !rx_ops->vdev_mgr_stop_response) {
476 mlme_err("No Rx Ops");
477 return -EINVAL;
478 }
479
480 wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
481 if (!wmi_handle) {
482 mlme_err("wmi_handle is null");
483 return -EINVAL;
484 }
485
486 if (wmi_extract_vdev_stopped_param(wmi_handle, data, &vdev_id)) {
487 mlme_err("WMI extract failed");
488 return -EINVAL;
489 }
490
491 vdev_rsp = rx_ops->psoc_get_vdev_response_timer_info(psoc, vdev_id);
492 if (!vdev_rsp) {
493 mlme_err("vdev response timer is null VDEV_%d PSOC_%d",
494 vdev_id, wlan_psoc_get_id(psoc));
495 return -EINVAL;
496 }
497
498 status = target_if_vdev_mgr_rsp_timer_stop(psoc, vdev_rsp,
499 STOP_RESPONSE_BIT);
500
501 if (QDF_IS_STATUS_ERROR(status)) {
502 mlme_err("PSOC_%d VDEV_%d: VDE MGR RSP Timer stop failed",
503 psoc->soc_objmgr.psoc_id, vdev_id);
504 goto err;
505 }
506
507 rsp.vdev_id = vdev_id;
508 status = rx_ops->vdev_mgr_stop_response(psoc, &rsp);
509
510 err:
511 return qdf_status_to_os_return(status);
512 }
513
target_if_vdev_mgr_delete_response_handler(ol_scn_t scn,uint8_t * data,uint32_t datalen)514 static int target_if_vdev_mgr_delete_response_handler(ol_scn_t scn,
515 uint8_t *data,
516 uint32_t datalen)
517 {
518 QDF_STATUS status = QDF_STATUS_E_INVAL;
519 struct wlan_objmgr_psoc *psoc;
520 struct wmi_unified *wmi_handle;
521 struct wlan_lmac_if_mlme_rx_ops *rx_ops;
522 struct vdev_delete_response vdev_del_resp = {0};
523 struct vdev_response_timer *vdev_rsp;
524
525 if (!scn || !data) {
526 mlme_err("Invalid input");
527 return -EINVAL;
528 }
529
530 psoc = target_if_get_psoc_from_scn_hdl(scn);
531 if (!psoc) {
532 mlme_err("PSOC is NULL");
533 return -EINVAL;
534 }
535
536 rx_ops = target_if_vdev_mgr_get_rx_ops(psoc);
537 if (!rx_ops || !rx_ops->vdev_mgr_delete_response) {
538 mlme_err("No Rx Ops");
539 return -EINVAL;
540 }
541
542 wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
543 if (!wmi_handle) {
544 mlme_err("wmi_handle is null");
545 return -EINVAL;
546 }
547
548 if (wmi_extract_vdev_delete_resp(wmi_handle, data, &vdev_del_resp)) {
549 mlme_err("WMI extract failed");
550 return -EINVAL;
551 }
552
553 vdev_rsp = rx_ops->psoc_get_vdev_response_timer_info(psoc,
554 vdev_del_resp.vdev_id);
555 if (!vdev_rsp) {
556 mlme_err("vdev response timer is null VDEV_%d PSOC_%d",
557 vdev_del_resp.vdev_id, wlan_psoc_get_id(psoc));
558 return -EINVAL;
559 }
560
561 status = target_if_vdev_mgr_rsp_timer_stop(
562 psoc, vdev_rsp,
563 DELETE_RESPONSE_BIT);
564
565 if (QDF_IS_STATUS_ERROR(status)) {
566 mlme_err("PSOC_%d VDEV_%d: VDE MGR RSP Timer stop failed",
567 wlan_psoc_get_id(psoc), vdev_del_resp.vdev_id);
568 goto err;
569 }
570
571 status = rx_ops->vdev_mgr_delete_response(psoc, &vdev_del_resp);
572 target_if_wake_lock_timeout_release(psoc, DELETE_WAKELOCK);
573 err:
574 return qdf_status_to_os_return(status);
575 }
576
target_if_vdev_mgr_peer_delete_all_response_handler(ol_scn_t scn,uint8_t * data,uint32_t datalen)577 static int target_if_vdev_mgr_peer_delete_all_response_handler(
578 ol_scn_t scn,
579 uint8_t *data,
580 uint32_t datalen)
581 {
582 QDF_STATUS status = QDF_STATUS_E_INVAL;
583 struct wlan_objmgr_psoc *psoc;
584 struct wmi_unified *wmi_handle;
585 struct wlan_lmac_if_mlme_rx_ops *rx_ops;
586 struct peer_delete_all_response vdev_peer_del_all_resp = {0};
587 struct vdev_response_timer *vdev_rsp;
588
589 if (!scn || !data) {
590 mlme_err("Invalid input");
591 return -EINVAL;
592 }
593
594 psoc = target_if_get_psoc_from_scn_hdl(scn);
595 if (!psoc) {
596 mlme_err("PSOC is NULL");
597 return -EINVAL;
598 }
599
600 rx_ops = target_if_vdev_mgr_get_rx_ops(psoc);
601 if (!rx_ops || !rx_ops->vdev_mgr_peer_delete_all_response) {
602 mlme_err("No Rx Ops");
603 return -EINVAL;
604 }
605
606 wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
607 if (!wmi_handle) {
608 mlme_err("wmi_handle is null");
609 return -EINVAL;
610 }
611
612 if (wmi_extract_vdev_peer_delete_all_response_event(
613 wmi_handle, data,
614 &vdev_peer_del_all_resp)) {
615 mlme_err("WMI extract failed");
616 return -EINVAL;
617 }
618
619 vdev_rsp = rx_ops->psoc_get_vdev_response_timer_info(psoc,
620 vdev_peer_del_all_resp.vdev_id);
621 if (!vdev_rsp) {
622 mlme_err("vdev response timer is null VDEV_%d PSOC_%d",
623 vdev_peer_del_all_resp.vdev_id,
624 wlan_psoc_get_id(psoc));
625 return -EINVAL;
626 }
627
628 status = target_if_vdev_mgr_rsp_timer_stop(
629 psoc,
630 vdev_rsp,
631 PEER_DELETE_ALL_RESPONSE_BIT);
632
633 if (QDF_IS_STATUS_ERROR(status)) {
634 mlme_err("PSOC_%d VDEV_%d: VDE MGR RSP Timer stop failed",
635 psoc->soc_objmgr.psoc_id,
636 vdev_peer_del_all_resp.vdev_id);
637 goto err;
638 }
639
640 vdev_peer_del_all_resp.peer_type_bitmap = vdev_rsp->peer_type_bitmap;
641
642 status = rx_ops->vdev_mgr_peer_delete_all_response(
643 psoc,
644 &vdev_peer_del_all_resp);
645
646 err:
647 return qdf_status_to_os_return(status);
648 }
649
target_if_vdev_mgr_offload_bcn_tx_status_handler(ol_scn_t scn,uint8_t * data,uint32_t datalen)650 int target_if_vdev_mgr_offload_bcn_tx_status_handler(
651 ol_scn_t scn,
652 uint8_t *data,
653 uint32_t datalen)
654 {
655 QDF_STATUS status;
656 struct wlan_objmgr_psoc *psoc;
657 struct wmi_unified *wmi_handle;
658 struct wlan_lmac_if_mlme_rx_ops *rx_ops;
659 uint32_t vdev_id, tx_status;
660
661 if (!scn || !data) {
662 mlme_err("Invalid input");
663 return -EINVAL;
664 }
665 psoc = target_if_get_psoc_from_scn_hdl(scn);
666 if (!psoc) {
667 mlme_err("PSOC is NULL");
668 return -EINVAL;
669 }
670
671 rx_ops = target_if_vdev_mgr_get_rx_ops(psoc);
672 if (!rx_ops || !rx_ops->vdev_mgr_offload_bcn_tx_status_event_handle) {
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 if (wmi_extract_offload_bcn_tx_status_evt(wmi_handle, data,
684 &vdev_id, &tx_status)) {
685 mlme_err("WMI extract failed");
686 return -EINVAL;
687 }
688
689 status = rx_ops->vdev_mgr_offload_bcn_tx_status_event_handle(
690 vdev_id,
691 tx_status);
692
693 return qdf_status_to_os_return(status);
694 }
695
target_if_vdev_mgr_tbttoffset_update_handler(ol_scn_t scn,uint8_t * data,uint32_t datalen)696 int target_if_vdev_mgr_tbttoffset_update_handler(
697 ol_scn_t scn, uint8_t *data,
698 uint32_t datalen)
699 {
700 QDF_STATUS status;
701 struct wlan_objmgr_psoc *psoc;
702 struct wmi_unified *wmi_handle;
703 struct wlan_lmac_if_mlme_rx_ops *rx_ops;
704 uint32_t num_vdevs = 0;
705
706 if (!scn || !data) {
707 mlme_err("Invalid input");
708 return -EINVAL;
709 }
710 psoc = target_if_get_psoc_from_scn_hdl(scn);
711 if (!psoc) {
712 mlme_err("PSOC is NULL");
713 return -EINVAL;
714 }
715
716 rx_ops = target_if_vdev_mgr_get_rx_ops(psoc);
717 if (!rx_ops || !rx_ops->vdev_mgr_tbttoffset_update_handle) {
718 mlme_err("No Rx Ops");
719 return -EINVAL;
720 }
721
722 wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
723 if (!wmi_handle) {
724 mlme_err("wmi_handle is null");
725 return -EINVAL;
726 }
727
728 if (wmi_extract_tbttoffset_num_vdevs(wmi_handle, data, &num_vdevs)) {
729 mlme_err("WMI extract failed");
730 return -EINVAL;
731 }
732
733 status = rx_ops->vdev_mgr_tbttoffset_update_handle(num_vdevs,
734 false);
735
736 return qdf_status_to_os_return(status);
737 }
738
target_if_vdev_mgr_ext_tbttoffset_update_handler(ol_scn_t scn,uint8_t * data,uint32_t datalen)739 int target_if_vdev_mgr_ext_tbttoffset_update_handler(
740 ol_scn_t scn,
741 uint8_t *data,
742 uint32_t datalen)
743 {
744 QDF_STATUS status;
745 struct wlan_objmgr_psoc *psoc;
746 struct wmi_unified *wmi_handle;
747 struct wlan_lmac_if_mlme_rx_ops *rx_ops;
748 uint32_t num_vdevs = 0;
749
750 if (!scn || !data) {
751 mlme_err("Invalid input");
752 return -EINVAL;
753 }
754 psoc = target_if_get_psoc_from_scn_hdl(scn);
755 if (!psoc) {
756 mlme_err("PSOC is NULL");
757 return -EINVAL;
758 }
759
760 rx_ops = target_if_vdev_mgr_get_rx_ops(psoc);
761 if (!rx_ops || !rx_ops->vdev_mgr_tbttoffset_update_handle) {
762 mlme_err("No Rx Ops");
763 return -EINVAL;
764 }
765
766 wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
767 if (!wmi_handle) {
768 mlme_err("wmi_handle is null");
769 return -EINVAL;
770 }
771
772 if (wmi_extract_ext_tbttoffset_num_vdevs(wmi_handle, data,
773 &num_vdevs)) {
774 mlme_err("WMI extract failed");
775 return -EINVAL;
776 }
777
778 status = rx_ops->vdev_mgr_tbttoffset_update_handle(num_vdevs,
779 true);
780
781 return qdf_status_to_os_return(status);
782 }
783
target_if_vdev_mgr_multi_vdev_restart_resp_handler(ol_scn_t scn,uint8_t * data,uint32_t datalen)784 static int target_if_vdev_mgr_multi_vdev_restart_resp_handler(
785 ol_scn_t scn,
786 uint8_t *data,
787 uint32_t datalen)
788 {
789 QDF_STATUS status = QDF_STATUS_E_INVAL;
790 struct wlan_objmgr_psoc *psoc;
791 struct wmi_unified *wmi_handle;
792 struct wlan_lmac_if_mlme_rx_ops *rx_ops;
793 struct multi_vdev_restart_resp restart_resp;
794 struct vdev_response_timer *vdev_rsp;
795 uint8_t max_vdevs, vdev_idx;
796
797 if (!scn || !data) {
798 mlme_err("Invalid input");
799 return -EINVAL;
800 }
801
802 psoc = target_if_get_psoc_from_scn_hdl(scn);
803 if (!psoc) {
804 mlme_err("PSOC is NULL");
805 return -EINVAL;
806 }
807
808 rx_ops = target_if_vdev_mgr_get_rx_ops(psoc);
809 if (!rx_ops || !rx_ops->vdev_mgr_multi_vdev_restart_resp ||
810 !rx_ops->psoc_get_vdev_response_timer_info) {
811 mlme_err("No Rx Ops");
812 return -EINVAL;
813 }
814
815 wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
816 if (!wmi_handle) {
817 mlme_err("wmi_handle is null");
818 return -EINVAL;
819 }
820
821 qdf_mem_zero(&restart_resp, sizeof(restart_resp));
822 restart_resp.timestamp = qdf_get_log_timestamp();
823 if (wmi_extract_multi_vdev_restart_resp_event(wmi_handle, data,
824 &restart_resp)) {
825 mlme_err("WMI extract failed");
826 return -EINVAL;
827 }
828
829 max_vdevs = wlan_psoc_get_max_vdev_count(psoc);
830 for (vdev_idx = 0; vdev_idx < max_vdevs; vdev_idx++) {
831 if (!qdf_test_bit(vdev_idx, restart_resp.vdev_id_bmap))
832 continue;
833
834 mlme_debug("PSOC_%d VDEV_%d: Restart resp received",
835 wlan_psoc_get_id(psoc), vdev_idx);
836 vdev_rsp = rx_ops->psoc_get_vdev_response_timer_info(psoc,
837 vdev_idx);
838 if (!vdev_rsp) {
839 mlme_err("PSOC_%d VDEV_%d: VDEV RSP is NULL",
840 wlan_psoc_get_id(psoc), vdev_idx);
841 continue;
842 }
843
844 status = target_if_vdev_mgr_rsp_timer_stop(
845 psoc, vdev_rsp, RESTART_RESPONSE_BIT);
846 if (QDF_IS_STATUS_ERROR(status))
847 mlme_err("PSOC_%d VDEV_%d: VDE MGR RSP Timer stop failed",
848 wlan_psoc_get_id(psoc), vdev_idx);
849 }
850
851 status = rx_ops->vdev_mgr_multi_vdev_restart_resp(psoc, &restart_resp);
852
853 return qdf_status_to_os_return(status);
854 }
855
856 /**
857 * target_if_vdev_csa_complete - CSA complete event handler
858 * @psoc: psoc
859 * @vdev_id: vdev id
860 *
861 * Return: 0 on success
862 */
target_if_vdev_csa_complete(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id)863 static int target_if_vdev_csa_complete(struct wlan_objmgr_psoc *psoc,
864 uint8_t vdev_id)
865 {
866 QDF_STATUS status = QDF_STATUS_E_FAILURE;
867 struct vdev_mlme_obj *vdev_mlme;
868 struct wlan_objmgr_vdev *vdev;
869 int ret = 0;
870
871 if (!psoc) {
872 mlme_err("Invalid input");
873 return -EINVAL;
874 }
875 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
876 WLAN_VDEV_TARGET_IF_ID);
877 if (!vdev) {
878 mlme_err("VDEV is NULL");
879 return -EINVAL;
880 }
881 vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev);
882 if (!vdev_mlme) {
883 mlme_err("VDEV_%d: PSOC_%d VDEV_MLME is NULL", vdev_id,
884 wlan_psoc_get_id(psoc));
885 ret = -EINVAL;
886 goto end;
887 }
888
889 if ((vdev_mlme->ops) && vdev_mlme->ops->mlme_vdev_csa_complete) {
890 status = vdev_mlme->ops->mlme_vdev_csa_complete(vdev_mlme);
891 if (QDF_IS_STATUS_ERROR(status)) {
892 mlme_err("vdev csa complete failed");
893 ret = -EINVAL;
894 }
895 }
896 end:
897 wlan_objmgr_vdev_release_ref(vdev, WLAN_VDEV_TARGET_IF_ID);
898 return ret;
899 }
900
901 /**
902 * target_if_pdev_csa_status_event_handler - CSA event handler
903 * @scn: Pointer to scn structure
904 * @data: pointer to event data
905 * @datalen: event data length
906 *
907 * Return: 0 on success
908 */
target_if_pdev_csa_status_event_handler(ol_scn_t scn,uint8_t * data,uint32_t datalen)909 static int target_if_pdev_csa_status_event_handler(
910 ol_scn_t scn,
911 uint8_t *data,
912 uint32_t datalen)
913 {
914 struct pdev_csa_switch_count_status csa_status;
915 struct wlan_objmgr_psoc *psoc;
916 struct wmi_unified *wmi_handle;
917 struct target_psoc_info *tgt_hdl;
918 int i;
919 QDF_STATUS status;
920 struct wlan_lmac_if_mlme_rx_ops *rx_ops = NULL;
921
922 if (!scn || !data) {
923 mlme_err("Invalid input");
924 return -EINVAL;
925 }
926
927 psoc = target_if_get_psoc_from_scn_hdl(scn);
928 if (!psoc) {
929 mlme_err("PSOC is NULL");
930 return -EINVAL;
931 }
932
933 rx_ops = target_if_vdev_mgr_get_rx_ops(psoc);
934 if (!rx_ops || !rx_ops->vdev_mgr_set_max_channel_switch_time) {
935 mlme_err("No Rx Ops");
936 return -EINVAL;
937 }
938
939 wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
940 if (!wmi_handle) {
941 mlme_err("wmi_handle is null");
942 return -EINVAL;
943 }
944
945 tgt_hdl = wlan_psoc_get_tgt_if_handle(psoc);
946 if (!tgt_hdl) {
947 mlme_err("target_psoc_info is null");
948 return -EINVAL;
949 }
950
951 qdf_mem_zero(&csa_status, sizeof(csa_status));
952 status = wmi_extract_pdev_csa_switch_count_status(
953 wmi_handle, data, &csa_status);
954 if (QDF_IS_STATUS_ERROR(status)) {
955 mlme_err("Extracting CSA switch count status event failed");
956 return -EINVAL;
957 }
958
959 if (csa_status.current_switch_count == 1)
960 rx_ops->vdev_mgr_set_max_channel_switch_time
961 (psoc, csa_status.vdev_ids, csa_status.num_vdevs);
962
963 if (wlan_psoc_nif_fw_ext_cap_get(psoc, WLAN_SOC_CEXT_CSA_TX_OFFLOAD)) {
964 for (i = 0; i < csa_status.num_vdevs; i++) {
965 if (!csa_status.current_switch_count)
966 target_if_vdev_csa_complete(psoc,
967 csa_status.vdev_ids[i]);
968 }
969 }
970
971 return target_if_csa_switch_count_status(psoc, tgt_hdl, csa_status);
972 }
973
974 /**
975 * target_if_vdev_mgr_csa_ie_received_handler - CSA IE Received event handler
976 * @scn: Pointer to scn structure
977 * @data: pointer to event data
978 * @datalen: event data length
979 *
980 * Return: 0 on success
981 */
target_if_vdev_mgr_csa_ie_received_handler(ol_scn_t scn,uint8_t * data,uint32_t datalen)982 static int target_if_vdev_mgr_csa_ie_received_handler(ol_scn_t scn,
983 uint8_t *data,
984 uint32_t datalen)
985 {
986 QDF_STATUS status;
987 uint8_t vdev_id = 0;
988 struct wlan_objmgr_psoc *psoc;
989 struct wmi_unified *wmi_handle;
990 struct wlan_objmgr_vdev *vdev;
991 struct wlan_objmgr_pdev *pdev;
992 struct wlan_lmac_if_mlme_rx_ops *rx_ops;
993 struct csa_offload_params csa_event = {0};
994
995 if (!scn || !data) {
996 mlme_err("Invalid input");
997 return -EINVAL;
998 }
999
1000 psoc = target_if_get_psoc_from_scn_hdl(scn);
1001 if (!psoc) {
1002 mlme_err("PSOC is NULL");
1003 return -EINVAL;
1004 }
1005
1006 rx_ops = target_if_vdev_mgr_get_rx_ops(psoc);
1007 if (!rx_ops || !rx_ops->vdev_mgr_csa_received) {
1008 mlme_err("No Rx Ops");
1009 return -EINVAL;
1010 }
1011
1012 wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
1013 if (!wmi_handle) {
1014 mlme_err("wmi_handle is null");
1015 return -EINVAL;
1016 }
1017
1018 status = wmi_extract_csa_ie_received_event(wmi_handle, data,
1019 &vdev_id, &csa_event);
1020 if (QDF_IS_STATUS_ERROR(status)) {
1021 mlme_err("Extracting CSA IE Received event failed");
1022 return -EINVAL;
1023 }
1024
1025 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
1026 WLAN_VDEV_TARGET_IF_ID);
1027 if (!vdev) {
1028 mlme_err("Null Vdev");
1029 return -EINVAL;
1030 }
1031
1032 pdev = wlan_vdev_get_pdev(vdev);
1033 wlan_objmgr_vdev_release_ref(vdev, WLAN_VDEV_TARGET_IF_ID);
1034
1035 if (csa_event.new_op_class &&
1036 wlan_reg_is_6ghz_op_class(pdev, csa_event.new_op_class)) {
1037 csa_event.csa_chan_freq =
1038 wlan_reg_chan_band_to_freq(pdev, csa_event.channel,
1039 BIT(REG_BAND_6G));
1040 } else {
1041 csa_event.csa_chan_freq =
1042 wlan_reg_legacy_chan_to_freq(pdev, csa_event.channel);
1043 }
1044
1045 return rx_ops->vdev_mgr_csa_received(psoc, vdev_id, &csa_event);
1046 }
1047
1048 #ifdef WLAN_FEATURE_DYNAMIC_MAC_ADDR_UPDATE
1049 /**
1050 * target_if_update_macaddr_conf_evt_handler() - Set MAC address confirmation
1051 * event handler
1052 * @scn: Pointer to scn structure
1053 * @event_buff: event data
1054 * @len: length
1055 *
1056 * Response handler for set MAC address request command.
1057 *
1058 * Return: 0 for success or error code
1059 */
target_if_update_macaddr_conf_evt_handler(ol_scn_t scn,uint8_t * event_buff,uint32_t len)1060 static int target_if_update_macaddr_conf_evt_handler(ol_scn_t scn,
1061 uint8_t *event_buff,
1062 uint32_t len)
1063 {
1064 int8_t ret;
1065 struct wlan_objmgr_psoc *psoc;
1066 struct wlan_objmgr_vdev *vdev;
1067 struct wmi_unified *wmi_handle;
1068 uint8_t vdev_id, resp_status;
1069 QDF_STATUS status;
1070 struct wlan_lmac_if_mlme_rx_ops *rx_ops;
1071 struct vdev_response_timer *vdev_rsp;
1072
1073 if (!event_buff) {
1074 mlme_err("Received NULL event ptr from FW");
1075 return -EINVAL;
1076 }
1077
1078 psoc = target_if_get_psoc_from_scn_hdl(scn);
1079 if (!psoc) {
1080 mlme_err("PSOC is NULL");
1081 return -EINVAL;
1082 }
1083
1084 wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
1085 if (!wmi_handle) {
1086 mlme_err("wmi_handle is null");
1087 return -EINVAL;
1088 }
1089
1090 status = wmi_extract_update_mac_address_event(wmi_handle, event_buff,
1091 &vdev_id, &resp_status);
1092 if (QDF_IS_STATUS_ERROR(status)) {
1093 mlme_err("Failed to extract update MAC address event");
1094 return -EINVAL;
1095 }
1096
1097 rx_ops = target_if_vdev_mgr_get_rx_ops(psoc);
1098 if (!rx_ops || !rx_ops->vdev_mgr_set_mac_addr_response) {
1099 mlme_err("No Rx Ops");
1100 return -EINVAL;
1101 }
1102
1103 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
1104 WLAN_VDEV_TARGET_IF_ID);
1105 if (!vdev) {
1106 mlme_err("VDEV NULL");
1107 return -EINVAL;
1108 }
1109
1110 if (!wlan_vdev_mlme_is_mlo_link_switch_in_progress(vdev)) {
1111 ret = 0;
1112 goto send_rsp;
1113 }
1114
1115 /* This is for LinkSwitch request case */
1116 vdev_rsp = rx_ops->psoc_get_vdev_response_timer_info(psoc, vdev_id);
1117 if (!vdev_rsp) {
1118 mlme_err("vdev response timer is null VDEV_%d PSOC_%d",
1119 vdev_id, wlan_psoc_get_id(psoc));
1120 ret = -EINVAL;
1121 goto out;
1122 }
1123
1124 status =
1125 target_if_vdev_mgr_rsp_timer_stop(psoc, vdev_rsp,
1126 UPDATE_MAC_ADDR_RESPONSE_BIT);
1127
1128 ret = qdf_status_to_os_return(status);
1129 if (QDF_IS_STATUS_ERROR(status)) {
1130 mlme_err("PSOC_%d VDEV_%d: VDE MGR RSP Timer stop failed",
1131 wlan_psoc_get_id(psoc), vdev_id);
1132 goto out;
1133 }
1134
1135 send_rsp:
1136 rx_ops->vdev_mgr_set_mac_addr_response(vdev, resp_status);
1137 out:
1138 wlan_objmgr_vdev_release_ref(vdev, WLAN_VDEV_TARGET_IF_ID);
1139 return ret;
1140 }
1141
1142 static inline void
target_if_register_set_mac_addr_evt_cbk(struct wmi_unified * wmi_handle)1143 target_if_register_set_mac_addr_evt_cbk(struct wmi_unified *wmi_handle)
1144 {
1145 wmi_unified_register_event_handler(
1146 wmi_handle, wmi_vdev_update_mac_addr_conf_eventid,
1147 target_if_update_macaddr_conf_evt_handler, VDEV_RSP_RX_CTX);
1148 }
1149
1150 static inline void
target_if_unregister_set_mac_addr_evt_cbk(struct wmi_unified * wmi_handle)1151 target_if_unregister_set_mac_addr_evt_cbk(struct wmi_unified *wmi_handle)
1152 {
1153 wmi_unified_unregister_event_handler(
1154 wmi_handle, wmi_vdev_update_mac_addr_conf_eventid);
1155 }
1156 #else
1157 static inline void
target_if_register_set_mac_addr_evt_cbk(struct wmi_unified * wmi_handle)1158 target_if_register_set_mac_addr_evt_cbk(struct wmi_unified *wmi_handle)
1159 {
1160 }
1161
1162 static inline void
target_if_unregister_set_mac_addr_evt_cbk(struct wmi_unified * wmi_handle)1163 target_if_unregister_set_mac_addr_evt_cbk(struct wmi_unified *wmi_handle)
1164 {
1165 }
1166 #endif
1167
1168 #ifdef WLAN_FEATURE_11BE_MLO
1169 /**
1170 * target_if_quiet_offload_event_handler() - Quiet IE offload mlo
1171 * station event handler
1172 * @scn: Pointer to scn structure
1173 * @event_buff: event data
1174 * @len: length
1175 *
1176 * Return: 0 for success or error code
1177 */
target_if_quiet_offload_event_handler(ol_scn_t scn,uint8_t * event_buff,uint32_t len)1178 static int target_if_quiet_offload_event_handler(ol_scn_t scn,
1179 uint8_t *event_buff,
1180 uint32_t len)
1181 {
1182 struct wlan_objmgr_psoc *psoc;
1183 struct wmi_unified *wmi_handle;
1184 QDF_STATUS status;
1185 struct wlan_lmac_if_mlme_rx_ops *rx_ops;
1186 struct vdev_sta_quiet_event sta_quiet_event = {0};
1187
1188 if (!event_buff) {
1189 mlme_err("Received NULL event ptr from FW");
1190 return -EINVAL;
1191 }
1192
1193 psoc = target_if_get_psoc_from_scn_hdl(scn);
1194 if (!psoc) {
1195 mlme_err("PSOC is NULL");
1196 return -EINVAL;
1197 }
1198
1199 wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
1200 if (!wmi_handle) {
1201 mlme_err("wmi_handle is null");
1202 return -EINVAL;
1203 }
1204
1205 status = wmi_extract_quiet_offload_event(wmi_handle, event_buff,
1206 &sta_quiet_event);
1207 if (QDF_IS_STATUS_ERROR(status)) {
1208 mlme_err("Failed to extract quiet IE offload event");
1209 return -EINVAL;
1210 }
1211
1212 rx_ops = target_if_vdev_mgr_get_rx_ops(psoc);
1213 if (!rx_ops || !rx_ops->vdev_mgr_quiet_offload) {
1214 mlme_err("No Rx Ops");
1215 return -EINVAL;
1216 }
1217
1218 rx_ops->vdev_mgr_quiet_offload(psoc, &sta_quiet_event);
1219
1220 return 0;
1221 }
1222
1223 static inline void
target_if_register_quiet_offload_event(struct wmi_unified * wmi_handle)1224 target_if_register_quiet_offload_event(struct wmi_unified *wmi_handle)
1225 {
1226 wmi_unified_register_event_handler(
1227 wmi_handle, wmi_vdev_quiet_offload_eventid,
1228 target_if_quiet_offload_event_handler, VDEV_RSP_RX_CTX);
1229 }
1230
1231 static inline void
target_if_unregister_quiet_offload_event(struct wmi_unified * wmi_handle)1232 target_if_unregister_quiet_offload_event(struct wmi_unified *wmi_handle)
1233 {
1234 wmi_unified_unregister_event_handler(
1235 wmi_handle, wmi_vdev_quiet_offload_eventid);
1236 }
1237 #else
1238 static inline void
target_if_register_quiet_offload_event(struct wmi_unified * wmi_handle)1239 target_if_register_quiet_offload_event(struct wmi_unified *wmi_handle)
1240 {
1241 }
1242
1243 static inline void
target_if_unregister_quiet_offload_event(struct wmi_unified * wmi_handle)1244 target_if_unregister_quiet_offload_event(struct wmi_unified *wmi_handle)
1245 {
1246 }
1247 #endif
1248
target_if_vdev_mgr_wmi_event_register(struct wlan_objmgr_psoc * psoc)1249 QDF_STATUS target_if_vdev_mgr_wmi_event_register(
1250 struct wlan_objmgr_psoc *psoc)
1251 {
1252 QDF_STATUS retval = QDF_STATUS_SUCCESS;
1253 struct wmi_unified *wmi_handle;
1254
1255 if (!psoc) {
1256 mlme_err("PSOC is NULL");
1257 return QDF_STATUS_E_NULL_VALUE;
1258 }
1259
1260 wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
1261 if (!wmi_handle) {
1262 mlme_err("wmi_handle is null");
1263 return QDF_STATUS_E_INVAL;
1264 }
1265
1266 retval = wmi_unified_register_event_handler(
1267 wmi_handle,
1268 wmi_vdev_stopped_event_id,
1269 target_if_vdev_mgr_stop_response_handler,
1270 VDEV_RSP_RX_CTX);
1271 if (QDF_IS_STATUS_ERROR(retval))
1272 mlme_err("failed to register for stop response");
1273
1274 retval = wmi_unified_register_event_handler(
1275 wmi_handle,
1276 wmi_vdev_delete_resp_event_id,
1277 target_if_vdev_mgr_delete_response_handler,
1278 VDEV_RSP_RX_CTX);
1279 if (QDF_IS_STATUS_ERROR(retval))
1280 mlme_err("failed to register for delete response");
1281
1282 retval = wmi_unified_register_event_handler(
1283 wmi_handle,
1284 wmi_vdev_start_resp_event_id,
1285 target_if_vdev_mgr_start_response_handler,
1286 VDEV_RSP_RX_CTX);
1287 if (QDF_IS_STATUS_ERROR(retval))
1288 mlme_err("failed to register for start response");
1289
1290 retval = wmi_unified_register_event_handler(
1291 wmi_handle,
1292 wmi_peer_delete_all_response_event_id,
1293 target_if_vdev_mgr_peer_delete_all_response_handler,
1294 VDEV_RSP_RX_CTX);
1295 if (QDF_IS_STATUS_ERROR(retval))
1296 mlme_err("failed to register for peer delete all response");
1297
1298 retval = wmi_unified_register_event_handler(
1299 wmi_handle,
1300 wmi_pdev_multi_vdev_restart_response_event_id,
1301 target_if_vdev_mgr_multi_vdev_restart_resp_handler,
1302 VDEV_RSP_RX_CTX);
1303 if (QDF_IS_STATUS_ERROR(retval))
1304 mlme_err("failed to register for multivdev restart response");
1305
1306 if (wmi_service_enabled(wmi_handle, wmi_service_beacon_offload)) {
1307 retval = wmi_unified_register_event_handler(
1308 wmi_handle,
1309 wmi_pdev_csa_switch_count_status_event_id,
1310 target_if_pdev_csa_status_event_handler,
1311 VDEV_RSP_RX_CTX);
1312 if (QDF_IS_STATUS_ERROR(retval))
1313 mlme_err("failed to register for csa event handler");
1314 }
1315
1316 retval = wmi_unified_register_event_handler
1317 (wmi_handle,
1318 wmi_csa_ie_received_event_id,
1319 target_if_vdev_mgr_csa_ie_received_handler,
1320 VDEV_RSP_RX_CTX);
1321 if (QDF_IS_STATUS_ERROR(retval))
1322 mlme_err("failed to register for CSA IE Received Event");
1323
1324 target_if_register_set_mac_addr_evt_cbk(wmi_handle);
1325
1326 target_if_register_quiet_offload_event(wmi_handle);
1327
1328 return retval;
1329 }
1330
target_if_vdev_mgr_wmi_event_unregister(struct wlan_objmgr_psoc * psoc)1331 QDF_STATUS target_if_vdev_mgr_wmi_event_unregister(
1332 struct wlan_objmgr_psoc *psoc)
1333 {
1334 struct wmi_unified *wmi_handle;
1335
1336 if (!psoc) {
1337 mlme_err("PSOC is NULL");
1338 return QDF_STATUS_E_INVAL;
1339 }
1340
1341 wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
1342 if (!wmi_handle) {
1343 mlme_err("wmi_handle is null");
1344 return QDF_STATUS_E_INVAL;
1345 }
1346
1347 target_if_unregister_quiet_offload_event(wmi_handle);
1348
1349 target_if_unregister_set_mac_addr_evt_cbk(wmi_handle);
1350
1351 wmi_unified_unregister_event_handler(wmi_handle,
1352 wmi_csa_ie_received_event_id);
1353
1354 wmi_unified_unregister_event_handler(
1355 wmi_handle,
1356 wmi_pdev_multi_vdev_restart_response_event_id);
1357
1358 wmi_unified_unregister_event_handler(
1359 wmi_handle,
1360 wmi_peer_delete_all_response_event_id);
1361
1362 wmi_unified_unregister_event_handler(wmi_handle,
1363 wmi_vdev_start_resp_event_id);
1364
1365 wmi_unified_unregister_event_handler(wmi_handle,
1366 wmi_vdev_delete_resp_event_id);
1367
1368 wmi_unified_unregister_event_handler(wmi_handle,
1369 wmi_vdev_stopped_event_id);
1370
1371 return QDF_STATUS_SUCCESS;
1372 }
1373