xref: /wlan-dirver/qcacld-3.0/core/wma/src/wma_dev_if.c (revision 263d0d22964f82bb97b269d96e2b995b107f2e72)
1 /*
2  * Copyright (c) 2013-2021 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:    wma_dev_if.c
22  *  This file contains vdev & peer related operations.
23  */
24 
25 /* Header files */
26 
27 #include "wma.h"
28 #include "wma_api.h"
29 #include "cds_api.h"
30 #include "wmi_unified_api.h"
31 #include "wlan_qct_sys.h"
32 #include "wni_api.h"
33 #include "ani_global.h"
34 #include "wmi_unified.h"
35 #include "wni_cfg.h"
36 
37 #include "qdf_nbuf.h"
38 #include "qdf_types.h"
39 #include "qdf_mem.h"
40 
41 #include "wma_types.h"
42 #include "lim_api.h"
43 #include "lim_session_utils.h"
44 #include "wma_pasn_peer_api.h"
45 
46 #include "cds_utils.h"
47 
48 #if !defined(REMOVE_PKT_LOG)
49 #include "pktlog_ac.h"
50 #endif /* REMOVE_PKT_LOG */
51 
52 #include "dbglog_host.h"
53 #include "csr_api.h"
54 
55 #include "wma_internal.h"
56 
57 #include "wma_ocb.h"
58 #include "cdp_txrx_cfg.h"
59 #include "cdp_txrx_flow_ctrl_legacy.h"
60 #include <cdp_txrx_peer_ops.h>
61 #include <cdp_txrx_cfg.h>
62 #include <cdp_txrx_cmn.h>
63 #include <cdp_txrx_misc.h>
64 #include <cdp_txrx_ctrl.h>
65 
66 #include "wlan_policy_mgr_api.h"
67 #include "wma_nan_datapath.h"
68 #include "wifi_pos_pasn_api.h"
69 #if defined(CONFIG_HL_SUPPORT)
70 #include "wlan_tgt_def_config_hl.h"
71 #else
72 #include "wlan_tgt_def_config.h"
73 #endif
74 #include <wlan_dfs_tgt_api.h>
75 #include <cdp_txrx_handle.h>
76 #include "wlan_pmo_ucfg_api.h"
77 #include "wlan_reg_services_api.h"
78 #include <include/wlan_vdev_mlme.h>
79 #include "wma_he.h"
80 #include "wma_eht.h"
81 #include "wlan_roam_debug.h"
82 #include "wlan_ocb_ucfg_api.h"
83 #include "init_deinit_lmac.h"
84 #include <target_if.h>
85 #include "wlan_policy_mgr_ucfg.h"
86 #include "wlan_mlme_public_struct.h"
87 #include "wlan_mlme_api.h"
88 #include "wlan_mlme_main.h"
89 #include "wlan_mlme_ucfg_api.h"
90 #include "wlan_mlme_twt_api.h"
91 #include <wlan_dfs_utils_api.h>
92 #include "../../core/src/vdev_mgr_ops.h"
93 #include "wlan_utility.h"
94 #include "wlan_coex_ucfg_api.h"
95 #include <wlan_cp_stats_mc_ucfg_api.h>
96 #include "wmi_unified_vdev_api.h"
97 #include <wlan_cm_api.h>
98 #include <../../core/src/wlan_cm_vdev_api.h>
99 #include "wlan_nan_api.h"
100 #include "wlan_mlo_mgr_peer.h"
101 #include "wifi_pos_api.h"
102 #include "wifi_pos_pasn_api.h"
103 #ifdef DCS_INTERFERENCE_DETECTION
104 #include <wlan_dcs_ucfg_api.h>
105 #endif
106 
107 #ifdef FEATURE_STA_MODE_VOTE_LINK
108 #include "wlan_ipa_ucfg_api.h"
109 #endif
110 
111 #include "son_api.h"
112 #include "wlan_vdev_mgr_tgt_if_tx_defs.h"
113 #include "wlan_mlo_mgr_roam.h"
114 #include "target_if_vdev_mgr_tx_ops.h"
115 #include "wlan_fwol_ucfg_api.h"
116 #include "wlan_vdev_mgr_utils_api.h"
117 #include "target_if.h"
118 
119 /*
120  * FW only supports 8 clients in SAP/GO mode for D3 WoW feature
121  * and hence host needs to hold a wake lock after 9th client connects
122  * and release the wake lock when 9th client disconnects
123  */
124 #define SAP_D3_WOW_MAX_CLIENT_HOLD_WAKE_LOCK (9)
125 #define SAP_D3_WOW_MAX_CLIENT_RELEASE_WAKE_LOCK (8)
126 
127 QDF_STATUS wma_find_vdev_id_by_addr(tp_wma_handle wma, uint8_t *addr,
128 				    uint8_t *vdev_id)
129 {
130 	uint8_t i;
131 	struct wlan_objmgr_vdev *vdev;
132 
133 	for (i = 0; i < wma->max_bssid; i++) {
134 		vdev = wma->interfaces[i].vdev;
135 		if (!vdev)
136 			continue;
137 
138 		if (qdf_is_macaddr_equal(
139 			(struct qdf_mac_addr *)wlan_vdev_mlme_get_macaddr(vdev),
140 			(struct qdf_mac_addr *)addr) == true) {
141 			*vdev_id = i;
142 			return QDF_STATUS_SUCCESS;
143 		}
144 
145 		if (qdf_is_macaddr_equal((struct qdf_mac_addr *)wlan_vdev_mlme_get_mldaddr(vdev),
146 					 (struct qdf_mac_addr *)addr) == true) {
147 				*vdev_id = i;
148 				return QDF_STATUS_SUCCESS;
149 		}
150 	}
151 
152 	return QDF_STATUS_E_FAILURE;
153 }
154 
155 
156 /**
157  * wma_is_vdev_in_ap_mode() - check that vdev is in ap mode or not
158  * @wma: wma handle
159  * @vdev_id: vdev id
160  *
161  * Helper function to know whether given vdev id
162  * is in AP mode or not.
163  *
164  * Return: True/False
165  */
166 bool wma_is_vdev_in_ap_mode(tp_wma_handle wma, uint8_t vdev_id)
167 {
168 	struct wma_txrx_node *intf = wma->interfaces;
169 
170 	if (vdev_id >= wma->max_bssid) {
171 		wma_err("Invalid vdev_id %hu", vdev_id);
172 		QDF_ASSERT(0);
173 		return false;
174 	}
175 
176 	if ((intf[vdev_id].type == WMI_VDEV_TYPE_AP) &&
177 	    ((intf[vdev_id].sub_type == WMI_UNIFIED_VDEV_SUBTYPE_P2P_GO) ||
178 	     (intf[vdev_id].sub_type == 0)))
179 		return true;
180 
181 	return false;
182 }
183 
184 uint8_t *wma_get_vdev_bssid(struct wlan_objmgr_vdev *vdev)
185 {
186 	struct vdev_mlme_obj *mlme_obj;
187 
188 	if (!vdev) {
189 		wma_err("vdev is NULL");
190 		return NULL;
191 	}
192 
193 	mlme_obj = wlan_vdev_mlme_get_cmpt_obj(vdev);
194 	if (!mlme_obj) {
195 		wma_err("Failed to get mlme_obj");
196 		return NULL;
197 	}
198 
199 	return mlme_obj->mgmt.generic.bssid;
200 }
201 
202 QDF_STATUS wma_find_vdev_id_by_bssid(tp_wma_handle wma, uint8_t *bssid,
203 				     uint8_t *vdev_id)
204 {
205 	int i;
206 	uint8_t *bssid_addr;
207 
208 	for (i = 0; i < wma->max_bssid; i++) {
209 		if (!wma->interfaces[i].vdev)
210 			continue;
211 		bssid_addr = wma_get_vdev_bssid(wma->interfaces[i].vdev);
212 		if (!bssid_addr)
213 			continue;
214 
215 		if (qdf_is_macaddr_equal(
216 			(struct qdf_mac_addr *)bssid_addr,
217 			(struct qdf_mac_addr *)bssid) == true) {
218 			*vdev_id = i;
219 			return QDF_STATUS_SUCCESS;
220 		}
221 	}
222 
223 	return QDF_STATUS_E_FAILURE;
224 }
225 
226 /**
227  * wma_find_req_on_timer_expiry() - find request by address
228  * @wma: wma handle
229  * @req: pointer to the target request
230  *
231  * On timer expiry, the pointer to the req message is received from the
232  * timer callback. Lookup the wma_hold_req_queue for the request with the
233  * same address and return success if found.
234  *
235  * Return: QDF_STATUS
236  */
237 static QDF_STATUS wma_find_req_on_timer_expiry(tp_wma_handle wma,
238 					       struct wma_target_req *req)
239 {
240 	struct wma_target_req *req_msg = NULL;
241 	bool found = false;
242 	qdf_list_node_t *cur_node = NULL, *next_node = NULL;
243 	QDF_STATUS status;
244 
245 	qdf_spin_lock_bh(&wma->wma_hold_req_q_lock);
246 	if (QDF_STATUS_SUCCESS != qdf_list_peek_front(&wma->wma_hold_req_queue,
247 						      &next_node)) {
248 		qdf_spin_unlock_bh(&wma->wma_hold_req_q_lock);
249 		wma_err("unable to get msg node from request queue");
250 		return QDF_STATUS_E_FAILURE;
251 	}
252 
253 	do {
254 		cur_node = next_node;
255 		req_msg = qdf_container_of(cur_node,
256 					   struct wma_target_req, node);
257 		if (req_msg != req)
258 			continue;
259 
260 		found = true;
261 		status = qdf_list_remove_node(&wma->wma_hold_req_queue,
262 					      cur_node);
263 		if (QDF_STATUS_SUCCESS != status) {
264 			qdf_spin_unlock_bh(&wma->wma_hold_req_q_lock);
265 			wma_debug("Failed to remove request for req %pK", req);
266 			return QDF_STATUS_E_FAILURE;
267 		}
268 		break;
269 	} while (QDF_STATUS_SUCCESS  ==
270 		 qdf_list_peek_next(&wma->wma_hold_req_queue,
271 				    cur_node, &next_node));
272 
273 	qdf_spin_unlock_bh(&wma->wma_hold_req_q_lock);
274 	if (!found) {
275 		wma_err("target request not found for req %pK", req);
276 		return QDF_STATUS_E_INVAL;
277 	}
278 
279 	wma_debug("target request found for vdev id: %d type %d",
280 		 req_msg->vdev_id, req_msg->type);
281 
282 	return QDF_STATUS_SUCCESS;
283 }
284 
285 /**
286  * wma_find_req() - find target request for vdev id
287  * @wma: wma handle
288  * @vdev_id: vdev id
289  * @type: request type
290  * @peer_addr: Peer mac address
291  *
292  * Find target request for given vdev id & type of request.
293  * Remove that request from active list.
294  *
295  * Return: return target request if found or NULL.
296  */
297 static struct wma_target_req *wma_find_req(tp_wma_handle wma,
298 					   uint8_t vdev_id, uint8_t type,
299 					   struct qdf_mac_addr *peer_addr)
300 {
301 	struct wma_target_req *req_msg = NULL;
302 	bool found = false;
303 	qdf_list_node_t *node1 = NULL, *node2 = NULL;
304 	QDF_STATUS status;
305 
306 	qdf_spin_lock_bh(&wma->wma_hold_req_q_lock);
307 	if (QDF_STATUS_SUCCESS != qdf_list_peek_front(&wma->wma_hold_req_queue,
308 						      &node2)) {
309 		qdf_spin_unlock_bh(&wma->wma_hold_req_q_lock);
310 		wma_err("unable to get msg node from request queue");
311 		return NULL;
312 	}
313 
314 	do {
315 		node1 = node2;
316 		req_msg = qdf_container_of(node1, struct wma_target_req, node);
317 		if (req_msg->vdev_id != vdev_id)
318 			continue;
319 		if (req_msg->type != type)
320 			continue;
321 
322 		found = true;
323 		if (type == WMA_PEER_CREATE_RESPONSE &&
324 		    peer_addr &&
325 		    !qdf_is_macaddr_equal(&req_msg->addr, peer_addr))
326 			found = false;
327 
328 		status = qdf_list_remove_node(&wma->wma_hold_req_queue, node1);
329 		if (QDF_STATUS_SUCCESS != status) {
330 			qdf_spin_unlock_bh(&wma->wma_hold_req_q_lock);
331 			wma_debug("Failed to remove request for vdev_id %d type %d",
332 				 vdev_id, type);
333 			return NULL;
334 		}
335 		break;
336 	} while (QDF_STATUS_SUCCESS  ==
337 			qdf_list_peek_next(&wma->wma_hold_req_queue, node1,
338 					   &node2));
339 
340 	qdf_spin_unlock_bh(&wma->wma_hold_req_q_lock);
341 	if (!found) {
342 		wma_err("target request not found for vdev_id %d type %d",
343 			 vdev_id, type);
344 		return NULL;
345 	}
346 
347 	wma_debug("target request found for vdev id: %d type %d",
348 		 vdev_id, type);
349 
350 	return req_msg;
351 }
352 
353 struct wma_target_req *wma_find_remove_req_msgtype(tp_wma_handle wma,
354 						   uint8_t vdev_id,
355 						   uint32_t msg_type)
356 {
357 	struct wma_target_req *req_msg = NULL;
358 	bool found = false;
359 	qdf_list_node_t *node1 = NULL, *node2 = NULL;
360 	QDF_STATUS status;
361 
362 	qdf_spin_lock_bh(&wma->wma_hold_req_q_lock);
363 	if (QDF_STATUS_SUCCESS != qdf_list_peek_front(&wma->wma_hold_req_queue,
364 						      &node2)) {
365 		qdf_spin_unlock_bh(&wma->wma_hold_req_q_lock);
366 		wma_debug("unable to get msg node from request queue for vdev_id %d type %d",
367 			  vdev_id, msg_type);
368 		return NULL;
369 	}
370 
371 	do {
372 		node1 = node2;
373 		req_msg = qdf_container_of(node1, struct wma_target_req, node);
374 		if (req_msg->vdev_id != vdev_id)
375 			continue;
376 		if (req_msg->msg_type != msg_type)
377 			continue;
378 
379 		found = true;
380 		status = qdf_list_remove_node(&wma->wma_hold_req_queue, node1);
381 		if (QDF_STATUS_SUCCESS != status) {
382 			qdf_spin_unlock_bh(&wma->wma_hold_req_q_lock);
383 			wma_debug("Failed to remove request. vdev_id %d type %d",
384 				  vdev_id, msg_type);
385 			return NULL;
386 		}
387 		break;
388 	} while (QDF_STATUS_SUCCESS  ==
389 			qdf_list_peek_next(&wma->wma_hold_req_queue, node1,
390 					   &node2));
391 
392 	qdf_spin_unlock_bh(&wma->wma_hold_req_q_lock);
393 	if (!found) {
394 		wma_debug("target request not found for vdev_id %d type %d",
395 			  vdev_id, msg_type);
396 		return NULL;
397 	}
398 
399 	wma_debug("target request found for vdev id: %d type %d",
400 		  vdev_id, msg_type);
401 
402 	return req_msg;
403 }
404 
405 QDF_STATUS wma_vdev_detach_callback(struct vdev_delete_response *rsp)
406 {
407 	tp_wma_handle wma;
408 	struct wma_txrx_node *iface = NULL;
409 
410 	wma = cds_get_context(QDF_MODULE_ID_WMA);
411 	if (!wma)
412 		return QDF_STATUS_E_FAILURE;
413 
414 	/* Sanitize the vdev id*/
415 	if (rsp->vdev_id > wma->max_bssid) {
416 		wma_err("vdev delete response with invalid vdev_id :%d",
417 			rsp->vdev_id);
418 		QDF_BUG(0);
419 		return QDF_STATUS_E_FAILURE;
420 	}
421 
422 	iface = &wma->interfaces[rsp->vdev_id];
423 
424 	wma_debug("vdev del response received for VDEV_%d", rsp->vdev_id);
425 	iface->del_staself_req = NULL;
426 
427 	if (iface->roam_scan_stats_req) {
428 		struct sir_roam_scan_stats *roam_scan_stats_req =
429 						iface->roam_scan_stats_req;
430 
431 		iface->roam_scan_stats_req = NULL;
432 		qdf_mem_free(roam_scan_stats_req);
433 	}
434 
435 	wma_vdev_deinit(iface);
436 	qdf_mem_zero(iface, sizeof(*iface));
437 	wma_vdev_init(iface);
438 
439 	mlme_vdev_del_resp(rsp->vdev_id);
440 
441 	return QDF_STATUS_SUCCESS;
442 }
443 
444 static void
445 wma_cdp_vdev_detach(ol_txrx_soc_handle soc, tp_wma_handle wma_handle,
446 		    uint8_t vdev_id)
447 {
448 	struct wma_txrx_node *iface = &wma_handle->interfaces[vdev_id];
449 	struct wlan_objmgr_vdev *vdev = iface->vdev;
450 
451 	if (!vdev) {
452 		wma_err("vdev is NULL");
453 		return;
454 	}
455 
456 	if (soc && wlan_vdev_get_id(vdev) != WLAN_INVALID_VDEV_ID)
457 		cdp_vdev_detach(soc, vdev_id, NULL, NULL);
458 }
459 
460 /**
461  * wma_release_vdev_ref() - Release vdev object reference count
462  * @iface: wma interface txrx node
463  *
464  * Purpose of this function is to release vdev object reference count
465  * from wma interface txrx node.
466  *
467  * Return: None
468  */
469 static void
470 wma_release_vdev_ref(struct wma_txrx_node *iface)
471 {
472 	struct wlan_objmgr_vdev *vdev;
473 
474 	vdev = iface->vdev;
475 
476 	iface->vdev_active = false;
477 	iface->vdev = NULL;
478 	if (vdev)
479 		wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_WMA_ID);
480 }
481 
482 /**
483  * wma_handle_monitor_mode_vdev_detach() - Stop and down monitor mode vdev
484  * @wma_handle: wma handle
485  * @vdev_id: used to get wma interface txrx node
486  *
487  * Monitor mode is unconneted mode, so do explicit vdev stop and down
488  *
489  * Return: None
490  */
491 static void wma_handle_monitor_mode_vdev_detach(tp_wma_handle wma,
492 						uint8_t vdev_id)
493 {
494 	struct wma_txrx_node *iface;
495 
496 	iface = &wma->interfaces[vdev_id];
497 	wlan_vdev_mlme_sm_deliver_evt(iface->vdev,
498 				      WLAN_VDEV_SM_EV_DOWN,
499 				      0, NULL);
500 	iface->vdev_active = false;
501 }
502 
503 /**
504  * wma_handle_vdev_detach() - wma vdev detach handler
505  * @wma_handle: pointer to wma handle
506  * @del_vdev_req_param: pointer to del req param
507  *
508  * Return: none.
509  */
510 static QDF_STATUS wma_handle_vdev_detach(tp_wma_handle wma_handle,
511 			struct del_vdev_params *del_vdev_req_param)
512 {
513 	QDF_STATUS status = QDF_STATUS_SUCCESS;
514 	uint8_t vdev_id = del_vdev_req_param->vdev_id;
515 	struct wma_txrx_node *iface = &wma_handle->interfaces[vdev_id];
516 	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
517 	struct wmi_mgmt_params mgmt_params = {};
518 
519 	if (!soc) {
520 		status = QDF_STATUS_E_FAILURE;
521 		goto rel_ref;
522 	}
523 
524 	if ((cds_get_conparam() == QDF_GLOBAL_MONITOR_MODE) ||
525 	    (policy_mgr_is_sta_mon_concurrency(wma_handle->psoc) &&
526 	    wlan_vdev_mlme_get_opmode(iface->vdev) == QDF_MONITOR_MODE))
527 		wma_handle_monitor_mode_vdev_detach(wma_handle, vdev_id);
528 
529 rel_ref:
530 	wma_cdp_vdev_detach(soc, wma_handle, vdev_id);
531 	if (qdf_is_recovering())
532 		wlan_mgmt_txrx_vdev_drain(iface->vdev,
533 					  wma_mgmt_frame_fill_peer_cb,
534 					  &mgmt_params);
535 	wma_debug("Releasing wma reference for vdev:%d", vdev_id);
536 	wma_release_vdev_ref(iface);
537 	return status;
538 }
539 
540 /**
541  * wma_self_peer_remove() - Self peer remove handler
542  * @wma: wma handle
543  * @del_vdev_req_param: vdev id
544  * @generate_vdev_rsp: request type
545  *
546  * Return: success if peer delete command sent to firmware, else failure.
547  */
548 static QDF_STATUS wma_self_peer_remove(tp_wma_handle wma_handle,
549 				       struct del_vdev_params *del_vdev_req)
550 {
551 	QDF_STATUS qdf_status;
552 	uint8_t vdev_id = del_vdev_req->vdev_id;
553 	struct wma_target_req *msg = NULL;
554 	struct del_sta_self_rsp_params *sta_self_wmi_rsp;
555 
556 	wma_debug("P2P Device: removing self peer "QDF_MAC_ADDR_FMT,
557 		  QDF_MAC_ADDR_REF(del_vdev_req->self_mac_addr));
558 
559 	qdf_status = wma_remove_peer(wma_handle, del_vdev_req->self_mac_addr,
560 				     vdev_id, false);
561 	if (QDF_IS_STATUS_ERROR(qdf_status)) {
562 		wma_err("wma_remove_peer is failed");
563 		goto error;
564 	}
565 
566 	if (wmi_service_enabled(wma_handle->wmi_handle,
567 				wmi_service_sync_delete_cmds)) {
568 		sta_self_wmi_rsp =
569 			qdf_mem_malloc(sizeof(struct del_sta_self_rsp_params));
570 		if (!sta_self_wmi_rsp) {
571 			qdf_status = QDF_STATUS_E_NOMEM;
572 			goto error;
573 		}
574 
575 		sta_self_wmi_rsp->self_sta_param = del_vdev_req;
576 		msg = wma_fill_hold_req(wma_handle, vdev_id,
577 					WMA_DELETE_STA_REQ,
578 					WMA_DEL_P2P_SELF_STA_RSP_START,
579 					sta_self_wmi_rsp,
580 					WMA_DELETE_STA_TIMEOUT);
581 		if (!msg) {
582 			wma_err("Failed to allocate request for vdev_id %d",
583 				vdev_id);
584 			wma_remove_req(wma_handle, vdev_id,
585 				       WMA_DEL_P2P_SELF_STA_RSP_START);
586 			qdf_mem_free(sta_self_wmi_rsp);
587 			qdf_status = QDF_STATUS_E_FAILURE;
588 			goto error;
589 		}
590 	}
591 
592 error:
593 	return qdf_status;
594 }
595 
596 #ifdef WLAN_FEATURE_DYNAMIC_MAC_ADDR_UPDATE
597 QDF_STATUS wma_p2p_self_peer_remove(struct wlan_objmgr_vdev *vdev)
598 {
599 	struct del_vdev_params *del_self_peer_req;
600 	tp_wma_handle wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
601 	QDF_STATUS status;
602 
603 	if (!wma_handle)
604 		return QDF_STATUS_E_INVAL;
605 
606 	del_self_peer_req = qdf_mem_malloc(sizeof(*del_self_peer_req));
607 	if (!del_self_peer_req)
608 		return QDF_STATUS_E_NOMEM;
609 
610 	del_self_peer_req->vdev = vdev;
611 	del_self_peer_req->vdev_id = wlan_vdev_get_id(vdev);
612 	qdf_mem_copy(del_self_peer_req->self_mac_addr,
613 		     wlan_vdev_mlme_get_macaddr(vdev),
614 		     QDF_MAC_ADDR_SIZE);
615 
616 	status = wma_self_peer_remove(wma_handle, del_self_peer_req);
617 
618 	return status;
619 }
620 #endif
621 
622 void wma_remove_objmgr_peer(tp_wma_handle wma,
623 			    struct wlan_objmgr_vdev *obj_vdev,
624 			    uint8_t *peer_addr)
625 {
626 	struct wlan_objmgr_psoc *psoc;
627 	struct wlan_objmgr_peer *obj_peer;
628 	struct wlan_objmgr_pdev *obj_pdev;
629 	uint8_t pdev_id = 0;
630 
631 	psoc = wma->psoc;
632 	if (!psoc) {
633 		wma_err("PSOC is NULL");
634 		return;
635 	}
636 
637 	obj_pdev = wlan_vdev_get_pdev(obj_vdev);
638 	pdev_id = wlan_objmgr_pdev_get_pdev_id(obj_pdev);
639 	obj_peer = wlan_objmgr_get_peer(psoc, pdev_id, peer_addr,
640 					WLAN_LEGACY_WMA_ID);
641 	if (obj_peer) {
642 		wlan_objmgr_peer_obj_delete(obj_peer);
643 		/* Unref to decrement ref happened in find_peer */
644 		wlan_objmgr_peer_release_ref(obj_peer, WLAN_LEGACY_WMA_ID);
645 	} else {
646 		wma_nofl_err("Peer "QDF_MAC_ADDR_FMT" not found",
647 			 QDF_MAC_ADDR_REF(peer_addr));
648 	}
649 
650 }
651 
652 static QDF_STATUS wma_check_for_deferred_peer_delete(tp_wma_handle wma_handle,
653 						     struct del_vdev_params
654 						     *pdel_vdev_req_param)
655 {
656 	QDF_STATUS status = QDF_STATUS_SUCCESS;
657 	uint8_t vdev_id = pdel_vdev_req_param->vdev_id;
658 	struct wma_txrx_node *iface = &wma_handle->interfaces[vdev_id];
659 	uint32_t vdev_stop_type;
660 
661 	if (qdf_atomic_read(&iface->bss_status) == WMA_BSS_STATUS_STARTED) {
662 		status = mlme_get_vdev_stop_type(iface->vdev, &vdev_stop_type);
663 		if (QDF_IS_STATUS_ERROR(status)) {
664 			wma_err("Failed to get wma req msg_type for vdev_id: %d",
665 				vdev_id);
666 			status = QDF_STATUS_E_INVAL;
667 			return status;
668 		}
669 
670 		if (vdev_stop_type != WMA_DELETE_BSS_REQ) {
671 			status = QDF_STATUS_E_INVAL;
672 			return status;
673 		}
674 
675 		wma_debug("BSS is not yet stopped. Deferring vdev(vdev id %x) deletion",
676 			  vdev_id);
677 		iface->del_staself_req = pdel_vdev_req_param;
678 		iface->is_del_sta_deferred = true;
679 	}
680 
681 	return status;
682 }
683 
684 static QDF_STATUS
685 wma_vdev_self_peer_delete(tp_wma_handle wma_handle,
686 			  struct del_vdev_params *pdel_vdev_req_param)
687 {
688 	QDF_STATUS status = QDF_STATUS_SUCCESS;
689 	uint8_t vdev_id = pdel_vdev_req_param->vdev_id;
690 	struct wma_txrx_node *iface = &wma_handle->interfaces[vdev_id];
691 
692 	if (mlme_vdev_uses_self_peer(iface->type, iface->sub_type)) {
693 		status = wma_self_peer_remove(wma_handle, pdel_vdev_req_param);
694 		if (QDF_IS_STATUS_ERROR(status)) {
695 			wma_err("can't remove selfpeer, send rsp session: %d",
696 				vdev_id);
697 			wma_handle_vdev_detach(wma_handle, pdel_vdev_req_param);
698 			mlme_vdev_self_peer_delete_resp(pdel_vdev_req_param);
699 			cds_trigger_recovery(QDF_SELF_PEER_DEL_FAILED);
700 			return status;
701 		}
702 	} else if (iface->type == WMI_VDEV_TYPE_STA ||
703 		   iface->type == WMI_VDEV_TYPE_NAN) {
704 		wma_remove_objmgr_peer(wma_handle, iface->vdev,
705 				       pdel_vdev_req_param->self_mac_addr);
706 	}
707 
708 	return status;
709 }
710 
711 QDF_STATUS wma_vdev_detach(struct del_vdev_params *pdel_vdev_req_param)
712 {
713 	QDF_STATUS status = QDF_STATUS_SUCCESS;
714 	uint8_t vdev_id;
715 	struct wma_txrx_node *iface = NULL;
716 	tp_wma_handle wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
717 
718 	if (!wma_handle)
719 		return QDF_STATUS_E_INVAL;
720 
721 	vdev_id = wlan_vdev_get_id(pdel_vdev_req_param->vdev);
722 	iface = &wma_handle->interfaces[vdev_id];
723 	if (!iface->vdev) {
724 		wma_err("vdev %d is NULL", vdev_id);
725 		mlme_vdev_self_peer_delete_resp(pdel_vdev_req_param);
726 		return status;
727 	}
728 
729 	status = wma_check_for_deferred_peer_delete(wma_handle,
730 						    pdel_vdev_req_param);
731 	if (QDF_IS_STATUS_ERROR(status))
732 		goto  send_fail_rsp;
733 
734 	if (iface->is_del_sta_deferred)
735 		return status;
736 
737 	iface->is_del_sta_deferred = false;
738 	iface->del_staself_req = NULL;
739 
740 	status = wma_vdev_self_peer_delete(wma_handle, pdel_vdev_req_param);
741 	if (QDF_IS_STATUS_ERROR(status)) {
742 		wma_err("Failed to send self peer delete:%d", status);
743 		status = QDF_STATUS_E_INVAL;
744 		return status;
745 	}
746 
747 	if (iface->type != WMI_VDEV_TYPE_MONITOR)
748 		iface->vdev_active = false;
749 
750 	if (!mlme_vdev_uses_self_peer(iface->type, iface->sub_type) ||
751 	    !wmi_service_enabled(wma_handle->wmi_handle,
752 	    wmi_service_sync_delete_cmds)) {
753 		status = wma_handle_vdev_detach(wma_handle,
754 						pdel_vdev_req_param);
755 		pdel_vdev_req_param->status = status;
756 		mlme_vdev_self_peer_delete_resp(pdel_vdev_req_param);
757 	}
758 
759 	return status;
760 
761 send_fail_rsp:
762 	wma_err("rcvd del_self_sta without del_bss; vdev_id:%d", vdev_id);
763 	cds_trigger_recovery(QDF_DEL_SELF_STA_FAILED);
764 	status = QDF_STATUS_E_FAILURE;
765 	return status;
766 }
767 
768 /**
769  * wma_send_start_resp() - send vdev start response to upper layer
770  * @wma: wma handle
771  * @add_bss: add bss params
772  * @resp_event: response params
773  *
774  * Return: none
775  */
776 static void wma_send_start_resp(tp_wma_handle wma,
777 				struct add_bss_rsp *add_bss_rsp,
778 				struct vdev_start_response *rsp)
779 {
780 	struct wma_txrx_node *iface = &wma->interfaces[rsp->vdev_id];
781 	QDF_STATUS status;
782 
783 	if (QDF_IS_STATUS_SUCCESS(rsp->status) &&
784 	    QDF_IS_STATUS_SUCCESS(add_bss_rsp->status)) {
785 		status =
786 		  wlan_vdev_mlme_sm_deliver_evt(iface->vdev,
787 						WLAN_VDEV_SM_EV_START_RESP,
788 						sizeof(*add_bss_rsp),
789 						add_bss_rsp);
790 		if (QDF_IS_STATUS_SUCCESS(status))
791 			return;
792 
793 		add_bss_rsp->status = status;
794 	}
795 
796 	/* Send vdev stop if vdev start was success */
797 	if (QDF_IS_STATUS_ERROR(add_bss_rsp->status) &&
798 	    QDF_IS_STATUS_SUCCESS(rsp->status)) {
799 		wlan_vdev_mlme_sm_deliver_evt(iface->vdev,
800 					      WLAN_VDEV_SM_EV_DOWN,
801 					      sizeof(*add_bss_rsp),
802 					      add_bss_rsp);
803 		return;
804 	}
805 
806 	wma_remove_bss_peer_on_failure(wma, rsp->vdev_id);
807 
808 	wma_debug("Sending add bss rsp to umac(vdev %d status %d)",
809 		 rsp->vdev_id, add_bss_rsp->status);
810 	lim_handle_add_bss_rsp(wma->mac_context, add_bss_rsp);
811 }
812 
813 /**
814  * wma_vdev_start_rsp() - send vdev start response to upper layer
815  * @wma: wma handle
816  * @vdev: vdev
817  * @resp_event: response params
818  *
819  * Return: none
820  */
821 static void wma_vdev_start_rsp(tp_wma_handle wma, struct wlan_objmgr_vdev *vdev,
822 			       struct vdev_start_response *rsp)
823 {
824 	struct beacon_info *bcn;
825 	enum QDF_OPMODE opmode;
826 	struct add_bss_rsp *add_bss_rsp;
827 
828 	opmode = wlan_vdev_mlme_get_opmode(vdev);
829 
830 	add_bss_rsp = qdf_mem_malloc(sizeof(*add_bss_rsp));
831 	if (!add_bss_rsp)
832 		return;
833 
834 	add_bss_rsp->vdev_id = rsp->vdev_id;
835 	add_bss_rsp->status = rsp->status;
836 	add_bss_rsp->chain_mask = rsp->chain_mask;
837 	add_bss_rsp->smps_mode  = host_map_smps_mode(rsp->smps_mode);
838 
839 	if (rsp->status)
840 		goto send_fail_resp;
841 
842 	if (opmode == QDF_P2P_GO_MODE || opmode == QDF_SAP_MODE) {
843 		wma->interfaces[rsp->vdev_id].beacon =
844 			qdf_mem_malloc(sizeof(struct beacon_info));
845 
846 		bcn = wma->interfaces[rsp->vdev_id].beacon;
847 		if (!bcn) {
848 			add_bss_rsp->status = QDF_STATUS_E_NOMEM;
849 			goto send_fail_resp;
850 		}
851 		bcn->buf = qdf_nbuf_alloc(NULL, SIR_MAX_BEACON_SIZE, 0,
852 					  sizeof(uint32_t), 0);
853 		if (!bcn->buf) {
854 			qdf_mem_free(bcn);
855 			add_bss_rsp->status = QDF_STATUS_E_FAILURE;
856 			goto send_fail_resp;
857 		}
858 		bcn->seq_no = MIN_SW_SEQ;
859 		qdf_spinlock_create(&bcn->lock);
860 		qdf_atomic_set(&wma->interfaces[rsp->vdev_id].bss_status,
861 			       WMA_BSS_STATUS_STARTED);
862 		wma_debug("AP mode (type %d subtype %d) BSS is started",
863 			 wma->interfaces[rsp->vdev_id].type,
864 			 wma->interfaces[rsp->vdev_id].sub_type);
865 	}
866 
867 send_fail_resp:
868 	wma_send_start_resp(wma, add_bss_rsp, rsp);
869 }
870 
871 #ifdef FEATURE_AP_MCC_CH_AVOIDANCE
872 /**
873  * wma_find_mcc_ap() - finds if device is operating AP in MCC mode or not
874  * @wma: wma handle.
875  * @vdev_id: vdev ID of device for which MCC has to be checked
876  * @add: flag indicating if current device is added or deleted
877  *
878  * This function parses through all the interfaces in wma and finds if
879  * any of those devces are in MCC mode with AP. If such a vdev is found
880  * involved AP vdevs are sent WDA_UPDATE_Q2Q_IE_IND msg to update their
881  * beacon template to include Q2Q IE.
882  *
883  * Return: none
884  */
885 static void wma_find_mcc_ap(tp_wma_handle wma, uint8_t vdev_id, bool add)
886 {
887 	uint8_t i;
888 	uint16_t prev_ch_freq = 0;
889 	bool is_ap = false;
890 	bool result = false;
891 	uint8_t *ap_vdev_ids = NULL;
892 	uint8_t num_ch = 0;
893 
894 	ap_vdev_ids = qdf_mem_malloc(wma->max_bssid);
895 	if (!ap_vdev_ids)
896 		return;
897 
898 	for (i = 0; i < wma->max_bssid; i++) {
899 		ap_vdev_ids[i] = -1;
900 		if (add == false && i == vdev_id)
901 			continue;
902 
903 		if (wma_is_vdev_up(vdev_id) || (i == vdev_id && add)) {
904 			if (wma->interfaces[i].type == WMI_VDEV_TYPE_AP) {
905 				is_ap = true;
906 				ap_vdev_ids[i] = i;
907 			}
908 
909 			if (wma->interfaces[i].ch_freq != prev_ch_freq) {
910 				num_ch++;
911 				prev_ch_freq = wma->interfaces[i].ch_freq;
912 			}
913 		}
914 	}
915 
916 	if (is_ap && (num_ch > 1))
917 		result = true;
918 	else
919 		result = false;
920 
921 	wma_send_msg(wma, WMA_UPDATE_Q2Q_IE_IND, (void *)ap_vdev_ids, result);
922 }
923 #endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
924 
925 /**
926  * wma_handle_hidden_ssid_restart() - handle hidden ssid restart
927  * @wma: wma handle
928  * @iface: interface pointer
929  *
930  * Return: none
931  */
932 static void wma_handle_hidden_ssid_restart(tp_wma_handle wma,
933 					   struct wma_txrx_node *iface)
934 {
935 	wlan_vdev_mlme_sm_deliver_evt(iface->vdev,
936 				      WLAN_VDEV_SM_EV_RESTART_RESP,
937 				      0, NULL);
938 }
939 
940 #ifdef WLAN_FEATURE_11BE
941 /**
942  * wma_get_peer_phymode() - get phy mode and eht puncture
943  * @nw_type: wlan type
944  * @old_peer_phymode: old peer phy mode
945  * @vdev_chan: vdev channel
946  * @is_eht: is eht mode
947  * @puncture_bitmap: eht puncture bitmap
948  *
949  * Return: new wlan phy mode
950  */
951 static enum wlan_phymode
952 wma_get_peer_phymode(tSirNwType nw_type, enum wlan_phymode old_peer_phymode,
953 		     struct wlan_channel *vdev_chan, bool *is_eht,
954 		     uint16_t *puncture_bitmap)
955 {
956 	enum wlan_phymode new_phymode;
957 
958 	new_phymode = wma_peer_phymode(nw_type, STA_ENTRY_PEER,
959 				       IS_WLAN_PHYMODE_HT(old_peer_phymode),
960 				       vdev_chan->ch_width,
961 				       IS_WLAN_PHYMODE_VHT(old_peer_phymode),
962 				       IS_WLAN_PHYMODE_HE(old_peer_phymode),
963 				       IS_WLAN_PHYMODE_EHT(old_peer_phymode));
964 	*is_eht = IS_WLAN_PHYMODE_EHT(new_phymode);
965 	if (*is_eht)
966 		*puncture_bitmap = vdev_chan->puncture_bitmap;
967 
968 	return new_phymode;
969 }
970 #else
971 static enum wlan_phymode
972 wma_get_peer_phymode(tSirNwType nw_type, enum wlan_phymode old_peer_phymode,
973 		     struct wlan_channel *vdev_chan, bool *is_eht,
974 		     uint16_t *puncture_bitmap)
975 {
976 	enum wlan_phymode new_phymode;
977 
978 	new_phymode = wma_peer_phymode(nw_type, STA_ENTRY_PEER,
979 				       IS_WLAN_PHYMODE_HT(old_peer_phymode),
980 				       vdev_chan->ch_width,
981 				       IS_WLAN_PHYMODE_VHT(old_peer_phymode),
982 				       IS_WLAN_PHYMODE_HE(old_peer_phymode),
983 				       0);
984 
985 	return new_phymode;
986 }
987 #endif
988 
989 static void wma_peer_send_phymode(struct wlan_objmgr_vdev *vdev,
990 				  void *object, void *arg)
991 {
992 	struct wlan_objmgr_peer *peer = object;
993 	enum wlan_phymode old_peer_phymode;
994 	struct wlan_channel *vdev_chan;
995 	enum wlan_phymode new_phymode;
996 	tSirNwType nw_type;
997 	uint32_t fw_phymode;
998 	uint32_t max_ch_width_supported;
999 	tp_wma_handle wma;
1000 	uint8_t *peer_mac_addr;
1001 	uint8_t vdev_id;
1002 	bool is_eht = false;
1003 	uint16_t puncture_bitmap = 0;
1004 	uint16_t new_puncture_bitmap = 0;
1005 	uint32_t bw_puncture = 0;
1006 	enum phy_ch_width new_bw;
1007 
1008 	if (wlan_peer_get_peer_type(peer) == WLAN_PEER_SELF)
1009 		return;
1010 
1011 	wma = cds_get_context(QDF_MODULE_ID_WMA);
1012 	if(!wma)
1013 		return;
1014 
1015 	old_peer_phymode = wlan_peer_get_phymode(peer);
1016 	vdev_chan = wlan_vdev_mlme_get_des_chan(vdev);
1017 
1018 	peer_mac_addr = wlan_peer_get_macaddr(peer);
1019 
1020 	if (WLAN_REG_IS_24GHZ_CH_FREQ(vdev_chan->ch_freq)) {
1021 		if (vdev_chan->ch_phymode == WLAN_PHYMODE_11B ||
1022 		    old_peer_phymode == WLAN_PHYMODE_11B)
1023 			nw_type = eSIR_11B_NW_TYPE;
1024 		else
1025 			nw_type = eSIR_11G_NW_TYPE;
1026 	} else {
1027 		nw_type = eSIR_11A_NW_TYPE;
1028 	}
1029 
1030 	new_phymode = wma_get_peer_phymode(nw_type, old_peer_phymode,
1031 					   vdev_chan, &is_eht,
1032 					   &puncture_bitmap);
1033 
1034 	if (!is_eht && new_phymode == old_peer_phymode) {
1035 		wma_debug("Ignore update as old %d and new %d phymode are same for mac "QDF_MAC_ADDR_FMT,
1036 			  old_peer_phymode, new_phymode,
1037 			  QDF_MAC_ADDR_REF(peer_mac_addr));
1038 		return;
1039 	}
1040 	wlan_peer_set_phymode(peer, new_phymode);
1041 
1042 	fw_phymode = wmi_host_to_fw_phymode(new_phymode);
1043 	vdev_id = wlan_vdev_get_id(vdev);
1044 
1045 	wma_set_peer_param(wma, peer_mac_addr, WMI_HOST_PEER_PHYMODE,
1046 			   fw_phymode, vdev_id);
1047 
1048 	max_ch_width_supported =
1049 		wmi_get_ch_width_from_phy_mode(wma->wmi_handle,
1050 					       fw_phymode);
1051 	new_bw =
1052 	target_if_wmi_chan_width_to_phy_ch_width(max_ch_width_supported);
1053 
1054 	if (is_eht) {
1055 		wlan_reg_extract_puncture_by_bw(vdev_chan->ch_width,
1056 						puncture_bitmap,
1057 						vdev_chan->ch_freq,
1058 						vdev_chan->ch_freq_seg2,
1059 						new_bw,
1060 						&new_puncture_bitmap);
1061 		QDF_SET_BITS(bw_puncture, 0, 8, new_bw);
1062 		QDF_SET_BITS(bw_puncture, 8, 16, new_puncture_bitmap);
1063 		wlan_util_vdev_peer_set_param_send(vdev, peer_mac_addr,
1064 						   WLAN_MLME_PEER_BW_PUNCTURE,
1065 						   bw_puncture);
1066 	} else {
1067 		wma_set_peer_param(wma, peer_mac_addr, WMI_HOST_PEER_CHWIDTH,
1068 				   max_ch_width_supported, vdev_id);
1069 	}
1070 	wma_debug("FW phymode %d old phymode %d new phymode %d bw %d punct: 0x%x macaddr " QDF_MAC_ADDR_FMT,
1071 		  fw_phymode, old_peer_phymode, new_phymode,
1072 		  max_ch_width_supported, new_puncture_bitmap,
1073 		  QDF_MAC_ADDR_REF(peer_mac_addr));
1074 }
1075 
1076 static
1077 void wma_update_rate_flags_after_vdev_restart(tp_wma_handle wma,
1078 						struct wma_txrx_node *iface)
1079 {
1080 	struct vdev_mlme_obj *vdev_mlme;
1081 	uint32_t rate_flags = 0;
1082 	enum wlan_phymode bss_phymode;
1083 	struct wlan_channel *des_chan;
1084 
1085 	if (iface->type != WMI_VDEV_TYPE_STA)
1086 		return;
1087 
1088 	vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(iface->vdev);
1089 	if (!vdev_mlme)
1090 		return;
1091 
1092 	des_chan = wlan_vdev_mlme_get_des_chan(iface->vdev);
1093 	bss_phymode = des_chan->ch_phymode;
1094 
1095 	if (wma_is_eht_phymode_supported(bss_phymode)) {
1096 		rate_flags = wma_get_eht_rate_flags(des_chan->ch_width);
1097 	} else if (IS_WLAN_PHYMODE_HE(bss_phymode)) {
1098 		rate_flags = wma_get_he_rate_flags(des_chan->ch_width);
1099 	} else if (IS_WLAN_PHYMODE_VHT(bss_phymode)) {
1100 		rate_flags = wma_get_vht_rate_flags(des_chan->ch_width);
1101 	} else if (IS_WLAN_PHYMODE_HT(bss_phymode)) {
1102 		rate_flags = wma_get_ht_rate_flags(des_chan->ch_width);
1103 	} else {
1104 		rate_flags = TX_RATE_LEGACY;
1105 	}
1106 
1107 	vdev_mlme->mgmt.rate_info.rate_flags = rate_flags;
1108 
1109 	wma_debug("bss phymode %d rate_flags %x, ch_width %d",
1110 		  bss_phymode, rate_flags, des_chan->ch_width);
1111 
1112 	ucfg_mc_cp_stats_set_rate_flags(iface->vdev, rate_flags);
1113 }
1114 
1115 QDF_STATUS wma_handle_channel_switch_resp(tp_wma_handle wma,
1116 					  struct vdev_start_response *rsp)
1117 {
1118 	enum wlan_vdev_sm_evt  event;
1119 	struct wma_txrx_node *iface;
1120 
1121 	iface = &wma->interfaces[rsp->vdev_id];
1122 	wma_debug("Send channel switch resp vdev %d status %d",
1123 		 rsp->vdev_id, rsp->status);
1124 
1125 	/* Indicate channel switch failure to LIM */
1126 	if (QDF_IS_STATUS_ERROR(rsp->status) &&
1127 	    (iface->type == WMI_VDEV_TYPE_MONITOR ||
1128 	     wma_is_vdev_in_ap_mode(wma, rsp->vdev_id) ||
1129 	     mlme_is_chan_switch_in_progress(iface->vdev))) {
1130 		mlme_set_chan_switch_in_progress(iface->vdev, false);
1131 		lim_process_switch_channel_rsp(wma->mac_context, rsp);
1132 		return QDF_STATUS_SUCCESS;
1133 	}
1134 
1135 	if (QDF_IS_STATUS_SUCCESS(rsp->status) &&
1136 	    rsp->resp_type == WMI_VDEV_RESTART_RESP_EVENT) {
1137 		wlan_objmgr_iterate_peerobj_list(iface->vdev,
1138 					 wma_peer_send_phymode, NULL,
1139 					 WLAN_LEGACY_WMA_ID);
1140 		wma_update_rate_flags_after_vdev_restart(wma, iface);
1141 	}
1142 
1143 	if (wma_is_vdev_in_ap_mode(wma, rsp->vdev_id) ||
1144 	    mlme_is_chan_switch_in_progress(iface->vdev))
1145 		event = WLAN_VDEV_SM_EV_RESTART_RESP;
1146 	else
1147 		event = WLAN_VDEV_SM_EV_START_RESP;
1148 	wlan_vdev_mlme_sm_deliver_evt(iface->vdev, event,
1149 				      sizeof(rsp), rsp);
1150 
1151 	return QDF_STATUS_SUCCESS;
1152 }
1153 
1154 #ifdef DCS_INTERFERENCE_DETECTION
1155 /**
1156  * wma_dcs_clear_vdev_starting() - clear vdev starting within dcs information
1157  * @mac_ctx: mac context
1158  * @vdev_id: vdev id
1159  *
1160  * This function is used to clear vdev starting within dcs information
1161  *
1162  * Return: None
1163  */
1164 static void wma_dcs_clear_vdev_starting(struct mac_context *mac_ctx,
1165 					uint32_t vdev_id)
1166 {
1167 	mac_ctx->sap.dcs_info.is_vdev_starting[vdev_id] = false;
1168 }
1169 
1170 /**
1171  * wma_dcs_wlan_interference_mitigation_enable() - enable wlan
1172  * interference mitigation
1173  * @mac_ctx: mac context
1174  * @mac_id: mac id
1175  * @rsp: vdev start response
1176  *
1177  * This function is used to enable wlan interference mitigation through
1178  * send dcs command
1179  *
1180  * Return: None
1181  */
1182 static void wma_dcs_wlan_interference_mitigation_enable(
1183 					struct mac_context *mac_ctx,
1184 					uint32_t mac_id,
1185 					struct vdev_start_response *rsp)
1186 {
1187 	int vdev_index;
1188 	uint32_t list[MAX_NUMBER_OF_CONC_CONNECTIONS];
1189 	uint32_t count;
1190 	bool wlan_interference_mitigation_enable =
1191 			mac_ctx->sap.dcs_info.
1192 			wlan_interference_mitigation_enable[rsp->vdev_id];
1193 
1194 	count = policy_mgr_get_sap_go_count_on_mac(
1195 			mac_ctx->psoc, list, mac_id);
1196 
1197 	for (vdev_index = 0; vdev_index < count; vdev_index++) {
1198 		if (mac_ctx->sap.dcs_info.is_vdev_starting[list[vdev_index]]) {
1199 			wma_err("vdev %d: does not finish restart",
1200 				 list[vdev_index]);
1201 			return;
1202 		}
1203 		wlan_interference_mitigation_enable =
1204 			wlan_interference_mitigation_enable ||
1205 		mac_ctx->sap.dcs_info.
1206 			wlan_interference_mitigation_enable[list[vdev_index]];
1207 	}
1208 
1209 	if (wlan_interference_mitigation_enable)
1210 		ucfg_config_dcs_event_data(mac_ctx->psoc, mac_id, true);
1211 
1212 	if (rsp->resp_type == WMI_HOST_VDEV_START_RESP_EVENT) {
1213 		ucfg_config_dcs_enable(mac_ctx->psoc, mac_id,
1214 				       WLAN_HOST_DCS_WLANIM);
1215 		ucfg_wlan_dcs_cmd(mac_ctx->psoc, mac_id, true);
1216 	}
1217 }
1218 #else
1219 static void wma_dcs_wlan_interference_mitigation_enable(
1220 					struct mac_context *mac_ctx,
1221 					uint32_t mac_id,
1222 					struct vdev_start_response *rsp)
1223 {
1224 }
1225 
1226 
1227 static void wma_dcs_clear_vdev_starting(struct mac_context *mac_ctx,
1228 					uint32_t vdev_id)
1229 {
1230 }
1231 #endif
1232 
1233 /*
1234  * wma_get_ratemask_type() - convert user input ratemask type to FW type
1235  * @type: User input ratemask type maintained in HDD
1236  * @fwtype: Value return arg for fw ratemask type value
1237  *
1238  * Return: FW configurable ratemask type
1239  */
1240 static QDF_STATUS wma_get_ratemask_type(enum wlan_mlme_ratemask_type type,
1241 					uint8_t *fwtype)
1242 {
1243 	switch (type) {
1244 	case WLAN_MLME_RATEMASK_TYPE_CCK:
1245 		*fwtype = WMI_RATEMASK_TYPE_CCK;
1246 		break;
1247 	case WLAN_MLME_RATEMASK_TYPE_HT:
1248 		*fwtype = WMI_RATEMASK_TYPE_HT;
1249 		break;
1250 	case WLAN_MLME_RATEMASK_TYPE_VHT:
1251 		*fwtype = WMI_RATEMASK_TYPE_VHT;
1252 		break;
1253 	case WLAN_MLME_RATEMASK_TYPE_HE:
1254 		*fwtype = WMI_RATEMASK_TYPE_HE;
1255 		break;
1256 	default:
1257 		return QDF_STATUS_E_INVAL;
1258 	}
1259 
1260 	return QDF_STATUS_SUCCESS;
1261 }
1262 
1263 QDF_STATUS wma_vdev_start_resp_handler(struct vdev_mlme_obj *vdev_mlme,
1264 				       struct vdev_start_response *rsp)
1265 {
1266 	tp_wma_handle wma;
1267 	struct wma_txrx_node *iface;
1268 	target_resource_config *wlan_res_cfg;
1269 	struct wlan_objmgr_psoc *psoc;
1270 	struct mac_context *mac_ctx = cds_get_context(QDF_MODULE_ID_PE);
1271 	QDF_STATUS status;
1272 	enum vdev_assoc_type assoc_type = VDEV_ASSOC;
1273 	struct vdev_mlme_obj *mlme_obj;
1274 	struct wlan_mlme_psoc_ext_obj *mlme_psoc_obj;
1275 	const struct wlan_mlme_ratemask *ratemask_cfg;
1276 	struct config_ratemask_params rparams = {0};
1277 
1278 	wma = cds_get_context(QDF_MODULE_ID_WMA);
1279 	if (!wma)
1280 		return QDF_STATUS_E_FAILURE;
1281 
1282 	psoc = wma->psoc;
1283 	if (!psoc) {
1284 		wma_err("psoc is NULL");
1285 		return QDF_STATUS_E_FAILURE;
1286 	}
1287 
1288 	mlme_psoc_obj = mlme_get_psoc_ext_obj(psoc);
1289 	if (!mlme_psoc_obj) {
1290 		wma_err("Failed to get mlme_psoc");
1291 		return QDF_STATUS_E_FAILURE;
1292 	}
1293 
1294 	ratemask_cfg = &mlme_psoc_obj->cfg.ratemask_cfg;
1295 
1296 	if (!mac_ctx) {
1297 		wma_err("Failed to get mac_ctx");
1298 		return QDF_STATUS_E_FAILURE;
1299 	}
1300 
1301 	wlan_res_cfg = lmac_get_tgt_res_cfg(psoc);
1302 	if (!wlan_res_cfg) {
1303 		wma_err("Wlan resource config is NULL");
1304 		return QDF_STATUS_E_FAILURE;
1305 	}
1306 
1307 	if (rsp->vdev_id >= wma->max_bssid) {
1308 		wma_err("Invalid vdev id received from firmware");
1309 		return QDF_STATUS_E_FAILURE;
1310 	}
1311 
1312 	if (wma_is_vdev_in_ap_mode(wma, rsp->vdev_id))
1313 		tgt_dfs_radar_enable(wma->pdev, 0, 0, true);
1314 
1315 	iface = &wma->interfaces[rsp->vdev_id];
1316 	if (!iface->vdev) {
1317 		wma_err("Invalid vdev");
1318 		return QDF_STATUS_E_FAILURE;
1319 	}
1320 
1321 	if (rsp->status == QDF_STATUS_SUCCESS) {
1322 		wma->interfaces[rsp->vdev_id].tx_streams =
1323 			rsp->cfgd_tx_streams;
1324 
1325 		if (wlan_res_cfg->use_pdev_id) {
1326 			if (rsp->mac_id == OL_TXRX_PDEV_ID) {
1327 				wma_err("soc level id received for mac id");
1328 				return -QDF_STATUS_E_INVAL;
1329 			}
1330 			wma->interfaces[rsp->vdev_id].mac_id =
1331 				WMA_PDEV_TO_MAC_MAP(rsp->mac_id);
1332 		} else {
1333 			wma->interfaces[rsp->vdev_id].mac_id =
1334 			rsp->mac_id;
1335 		}
1336 
1337 		wma_debug("vdev:%d tx ss=%d rx ss=%d chain mask=%d mac=%d",
1338 				rsp->vdev_id,
1339 				rsp->cfgd_tx_streams,
1340 				rsp->cfgd_rx_streams,
1341 				rsp->chain_mask,
1342 				wma->interfaces[rsp->vdev_id].mac_id);
1343 
1344 		/* Fill bss_chan after vdev start */
1345 		qdf_mem_copy(iface->vdev->vdev_mlme.bss_chan,
1346 			     iface->vdev->vdev_mlme.des_chan,
1347 			     sizeof(struct wlan_channel));
1348 	}
1349 
1350 	if (wma_is_vdev_in_ap_mode(wma, rsp->vdev_id)) {
1351 		wma_dcs_clear_vdev_starting(mac_ctx, rsp->vdev_id);
1352 		wma_dcs_wlan_interference_mitigation_enable(mac_ctx,
1353 							    iface->mac_id, rsp);
1354 	}
1355 
1356 	if (iface->type == WMI_VDEV_TYPE_STA &&
1357 	    rsp->resp_type == WMI_VDEV_START_RESP_EVENT) {
1358 		wma_debug("BA mode: %d", mac_ctx->ba_mode);
1359 		if (wma_cli_set_command(rsp->vdev_id,
1360 					wmi_vdev_param_set_ba_mode,
1361 					mac_ctx->ba_mode, VDEV_CMD))
1362 			wma_err("Set BA opmode failed for vdev: %d",
1363 				rsp->vdev_id);
1364 	}
1365 
1366 #ifdef FEATURE_AP_MCC_CH_AVOIDANCE
1367 	if (rsp->status == QDF_STATUS_SUCCESS
1368 		&& mac_ctx->sap.sap_channel_avoidance)
1369 		wma_find_mcc_ap(wma, rsp->vdev_id, true);
1370 #endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
1371 
1372 	if (wma_get_hidden_ssid_restart_in_progress(iface) &&
1373 	    wma_is_vdev_in_ap_mode(wma, rsp->vdev_id)) {
1374 		wma_handle_hidden_ssid_restart(wma, iface);
1375 		return QDF_STATUS_SUCCESS;
1376 	}
1377 
1378 	mlme_obj = wlan_vdev_mlme_get_cmpt_obj(iface->vdev);
1379 	if (!mlme_obj)
1380 		return QDF_STATUS_E_INVAL;
1381 
1382 	mlme_obj->mgmt.generic.tx_pwrlimit = rsp->max_allowed_tx_power;
1383 	wma_debug("Max allowed tx power: %d", rsp->max_allowed_tx_power);
1384 
1385 	if (iface->type == WMI_VDEV_TYPE_STA)
1386 		assoc_type = mlme_get_assoc_type(vdev_mlme->vdev);
1387 
1388 	if (mlme_is_chan_switch_in_progress(iface->vdev) ||
1389 	    iface->type == WMI_VDEV_TYPE_MONITOR ||
1390 	    (iface->type == WMI_VDEV_TYPE_STA &&
1391 	     (assoc_type == VDEV_ASSOC || assoc_type == VDEV_REASSOC))) {
1392 		status = wma_handle_channel_switch_resp(wma,
1393 							rsp);
1394 		if (QDF_IS_STATUS_ERROR(status))
1395 			return QDF_STATUS_E_FAILURE;
1396 	}  else if (iface->type == WMI_VDEV_TYPE_OCB) {
1397 		mlme_obj->proto.sta.assoc_id = iface->aid;
1398 		if (vdev_mgr_up_send(mlme_obj) != QDF_STATUS_SUCCESS) {
1399 			wma_err("failed to send vdev up");
1400 			return QDF_STATUS_E_FAILURE;
1401 		}
1402 		ucfg_ocb_config_channel(wma->pdev);
1403 	} else {
1404 		struct qdf_mac_addr bss_peer;
1405 
1406 		status =
1407 			wlan_vdev_get_bss_peer_mac(iface->vdev, &bss_peer);
1408 		if (QDF_IS_STATUS_ERROR(status)) {
1409 			wma_err("Failed to get bssid");
1410 			return QDF_STATUS_E_INVAL;
1411 		}
1412 		qdf_mem_copy(mlme_obj->mgmt.generic.bssid, bss_peer.bytes,
1413 			     QDF_MAC_ADDR_SIZE);
1414 		wma_vdev_start_rsp(wma, vdev_mlme->vdev, rsp);
1415 	}
1416 	if (iface->type == WMI_VDEV_TYPE_AP && wma_is_vdev_up(rsp->vdev_id))
1417 		wma_set_sap_keepalive(wma, rsp->vdev_id);
1418 
1419 	/* Send ratemask to firmware */
1420 	if ((ratemask_cfg->type > WLAN_MLME_RATEMASK_TYPE_NO_MASK) &&
1421 	    (ratemask_cfg->type < WLAN_MLME_RATEMASK_TYPE_MAX)) {
1422 		struct wmi_unified *wmi_handle = wma->wmi_handle;
1423 
1424 		if (wmi_validate_handle(wmi_handle))
1425 			return QDF_STATUS_E_INVAL;
1426 
1427 		rparams.vdev_id = rsp->vdev_id;
1428 		status = wma_get_ratemask_type(ratemask_cfg->type,
1429 					       &rparams.type);
1430 
1431 		if (QDF_IS_STATUS_ERROR(status)) {
1432 			wma_err(FL("unable to map ratemask"));
1433 			/* don't fail, default rates will still work */
1434 			return QDF_STATUS_SUCCESS;
1435 		}
1436 
1437 		rparams.lower32 = ratemask_cfg->lower32;
1438 		rparams.higher32 = ratemask_cfg->higher32;
1439 		rparams.lower32_2 = ratemask_cfg->lower32_2;
1440 		rparams.higher32_2 = ratemask_cfg->higher32_2;
1441 
1442 		status = wmi_unified_vdev_config_ratemask_cmd_send(wmi_handle,
1443 								   &rparams);
1444 		/* Only log failure. Do not abort */
1445 		if (QDF_IS_STATUS_ERROR(status))
1446 			wma_err(FL("failed to send ratemask"));
1447 	}
1448 
1449 	return QDF_STATUS_SUCCESS;
1450 }
1451 
1452 bool wma_is_vdev_valid(uint32_t vdev_id)
1453 {
1454 	tp_wma_handle wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
1455 
1456 	if (!wma_handle)
1457 		return false;
1458 
1459 	/* No of interface are allocated based on max_bssid value */
1460 	if (vdev_id >= wma_handle->max_bssid) {
1461 		wma_debug("vdev_id: %d is invalid, max_bssid: %d",
1462 			 vdev_id, wma_handle->max_bssid);
1463 		return false;
1464 	}
1465 
1466 	return wma_handle->interfaces[vdev_id].vdev_active;
1467 }
1468 
1469 /**
1470  * wma_vdev_set_param() - set per vdev params in fw
1471  * @wmi_handle: wmi handle
1472  * @if_id: vdev id
1473  * @param_id: parameter id
1474  * @param_value: parameter value
1475  *
1476  * Return: QDF_STATUS_SUCCESS for success or error code
1477  */
1478 QDF_STATUS
1479 wma_vdev_set_param(wmi_unified_t wmi_handle, uint32_t if_id,
1480 				uint32_t param_id, uint32_t param_value)
1481 {
1482 	struct vdev_set_params param = {0};
1483 
1484 	if (!wma_is_vdev_valid(if_id)) {
1485 		wma_err("vdev_id: %d is not active reject the req: param id %d val %d",
1486 			if_id, param_id, param_value);
1487 		return QDF_STATUS_E_INVAL;
1488 	}
1489 
1490 	param.vdev_id = if_id;
1491 	param.param_id = param_id;
1492 	param.param_value = param_value;
1493 
1494 	return wmi_unified_vdev_set_param_send(wmi_handle, &param);
1495 }
1496 
1497 /**
1498  * wma_set_peer_param() - set peer parameter in fw
1499  * @wma_ctx: wma handle
1500  * @peer_addr: peer mac address
1501  * @param_id: parameter id
1502  * @param_value: parameter value
1503  * @vdev_id: vdev id
1504  *
1505  * Return: QDF_STATUS_SUCCESS for success or error code
1506  */
1507 QDF_STATUS wma_set_peer_param(void *wma_ctx, uint8_t *peer_addr,
1508 			      uint32_t param_id, uint32_t param_value,
1509 			      uint32_t vdev_id)
1510 {
1511 	tp_wma_handle wma_handle = (tp_wma_handle) wma_ctx;
1512 	struct peer_set_params param = {0};
1513 	QDF_STATUS status;
1514 
1515 	param.vdev_id = vdev_id;
1516 	param.param_value = param_value;
1517 	param.param_id = param_id;
1518 
1519 	status = wmi_set_peer_param_send(wma_handle->wmi_handle,
1520 					 peer_addr,
1521 					 &param);
1522 	if (QDF_IS_STATUS_ERROR(status))
1523 		wma_err("vdev_id: %d peer set failed, id %d, val %d",
1524 			 vdev_id, param_id, param_value);
1525 	return status;
1526 }
1527 
1528 /**
1529  * wma_peer_unmap_conf_send - send peer unmap conf cmnd to fw
1530  * @wma_ctx: wma handle
1531  * @msg: peer unmap conf params
1532  *
1533  * Return: QDF_STATUS
1534  */
1535 QDF_STATUS wma_peer_unmap_conf_send(tp_wma_handle wma,
1536 				    struct send_peer_unmap_conf_params *msg)
1537 {
1538 	QDF_STATUS qdf_status;
1539 
1540 	if (!msg) {
1541 		wma_err("null input params");
1542 		return QDF_STATUS_E_INVAL;
1543 	}
1544 
1545 	qdf_status = wmi_unified_peer_unmap_conf_send(
1546 					wma->wmi_handle,
1547 					msg->vdev_id,
1548 					msg->peer_id_cnt,
1549 					msg->peer_id_list);
1550 
1551 	if (qdf_status != QDF_STATUS_SUCCESS)
1552 		wma_err("peer_unmap_conf_send failed %d", qdf_status);
1553 
1554 	qdf_mem_free(msg->peer_id_list);
1555 	msg->peer_id_list = NULL;
1556 
1557 	return qdf_status;
1558 }
1559 
1560 /**
1561  * wma_peer_unmap_conf_cb - send peer unmap conf cmnd to fw
1562  * @vdev_id: vdev id
1563  * @peer_id_cnt: no of peer id
1564  * @peer_id_list: list of peer ids
1565  *
1566  * Return: QDF_STATUS
1567  */
1568 QDF_STATUS wma_peer_unmap_conf_cb(uint8_t vdev_id,
1569 				  uint32_t peer_id_cnt,
1570 				  uint16_t *peer_id_list)
1571 {
1572 	tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA);
1573 	QDF_STATUS qdf_status;
1574 
1575 	if (!wma)
1576 		return QDF_STATUS_E_INVAL;
1577 
1578 	wma_debug("peer_id_cnt: %d", peer_id_cnt);
1579 	qdf_status = wmi_unified_peer_unmap_conf_send(
1580 						wma->wmi_handle,
1581 						vdev_id, peer_id_cnt,
1582 						peer_id_list);
1583 
1584 	if (qdf_status == QDF_STATUS_E_BUSY) {
1585 		QDF_STATUS retcode;
1586 		struct scheduler_msg msg = {0};
1587 		struct send_peer_unmap_conf_params *peer_unmap_conf_req;
1588 		void *mac_ctx = cds_get_context(QDF_MODULE_ID_PE);
1589 
1590 		wma_debug("post unmap_conf cmd to MC thread");
1591 
1592 		if (!mac_ctx)
1593 			return QDF_STATUS_E_FAILURE;
1594 
1595 		peer_unmap_conf_req = qdf_mem_malloc(sizeof(
1596 					struct send_peer_unmap_conf_params));
1597 
1598 		if (!peer_unmap_conf_req)
1599 			return QDF_STATUS_E_NOMEM;
1600 
1601 		peer_unmap_conf_req->vdev_id = vdev_id;
1602 		peer_unmap_conf_req->peer_id_cnt = peer_id_cnt;
1603 		peer_unmap_conf_req->peer_id_list =  qdf_mem_malloc(
1604 					sizeof(uint16_t) * peer_id_cnt);
1605 		if (!peer_unmap_conf_req->peer_id_list) {
1606 			qdf_mem_free(peer_unmap_conf_req);
1607 			peer_unmap_conf_req = NULL;
1608 			return QDF_STATUS_E_NOMEM;
1609 		}
1610 		qdf_mem_copy(peer_unmap_conf_req->peer_id_list,
1611 			     peer_id_list, sizeof(uint16_t) * peer_id_cnt);
1612 
1613 		msg.type = WMA_SEND_PEER_UNMAP_CONF;
1614 		msg.reserved = 0;
1615 		msg.bodyptr = peer_unmap_conf_req;
1616 		msg.bodyval = 0;
1617 
1618 		retcode = wma_post_ctrl_msg(mac_ctx, &msg);
1619 		if (retcode != QDF_STATUS_SUCCESS) {
1620 			wma_err("wma_post_ctrl_msg failed");
1621 			qdf_mem_free(peer_unmap_conf_req->peer_id_list);
1622 			qdf_mem_free(peer_unmap_conf_req);
1623 			return QDF_STATUS_E_FAILURE;
1624 		}
1625 	}
1626 
1627 	return qdf_status;
1628 }
1629 
1630 bool wma_objmgr_peer_exist(tp_wma_handle wma,
1631 			   uint8_t *peer_addr, uint8_t *peer_vdev_id)
1632 {
1633 	struct wlan_objmgr_peer *peer;
1634 
1635 	if (!peer_addr ||
1636 	    qdf_is_macaddr_zero((struct qdf_mac_addr *)peer_addr))
1637 		return false;
1638 
1639 	peer = wlan_objmgr_get_peer_by_mac(wma->psoc, peer_addr,
1640 					   WLAN_LEGACY_WMA_ID);
1641 	if (!peer)
1642 		return false;
1643 
1644 	if (peer_vdev_id)
1645 		*peer_vdev_id = wlan_vdev_get_id(wlan_peer_get_vdev(peer));
1646 
1647 	wlan_objmgr_peer_release_ref(peer, WLAN_LEGACY_WMA_ID);
1648 
1649 	return true;
1650 }
1651 
1652 /**
1653  * wma_remove_peer() - remove peer information from host driver and fw
1654  * @wma: wma handle
1655  * @mac_addr: peer mac address, to be removed
1656  * @vdev_id: vdev id
1657  * @no_fw_peer_delete: If true dont send peer delete to firmware
1658  *
1659  * Return: QDF_STATUS
1660  */
1661 QDF_STATUS wma_remove_peer(tp_wma_handle wma, uint8_t *mac_addr,
1662 			   uint8_t vdev_id, bool no_fw_peer_delete)
1663 {
1664 #define PEER_ALL_TID_BITMASK 0xffffffff
1665 	uint32_t peer_tid_bitmap = PEER_ALL_TID_BITMASK;
1666 	uint8_t *peer_addr = mac_addr;
1667 	uint8_t peer_mac[QDF_MAC_ADDR_SIZE] = {0};
1668 	struct peer_flush_params param = {0};
1669 	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
1670 	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
1671 	uint32_t bitmap = 1 << CDP_PEER_DELETE_NO_SPECIAL;
1672 	bool peer_unmap_conf_support_enabled;
1673 	uint8_t peer_vdev_id;
1674 	struct peer_delete_cmd_params del_param = {0};
1675 
1676 	if (!wma->interfaces[vdev_id].peer_count) {
1677 		wma_err("Can't remove peer with peer_addr "QDF_MAC_ADDR_FMT" vdevid %d peer_count %d",
1678 			QDF_MAC_ADDR_REF(peer_addr), vdev_id,
1679 			wma->interfaces[vdev_id].peer_count);
1680 		QDF_ASSERT(0);
1681 		return QDF_STATUS_E_INVAL;
1682 	}
1683 
1684 	if (!soc) {
1685 		QDF_BUG(0);
1686 		return QDF_STATUS_E_INVAL;
1687 	}
1688 
1689 	if (!wma_objmgr_peer_exist(wma, peer_addr, &peer_vdev_id)) {
1690 		wma_err("peer doesn't exist peer_addr "QDF_MAC_ADDR_FMT" vdevid %d peer_count %d",
1691 			 QDF_MAC_ADDR_REF(peer_addr), vdev_id,
1692 			 wma->interfaces[vdev_id].peer_count);
1693 		return QDF_STATUS_E_INVAL;
1694 	}
1695 
1696 	if (peer_vdev_id != vdev_id) {
1697 		wma_err("peer "QDF_MAC_ADDR_FMT" is on vdev id %d but delete req on vdevid %d peer_count %d",
1698 			 QDF_MAC_ADDR_REF(peer_addr), peer_vdev_id, vdev_id,
1699 			 wma->interfaces[vdev_id].peer_count);
1700 		return QDF_STATUS_E_INVAL;
1701 	}
1702 	peer_unmap_conf_support_enabled =
1703 				cdp_cfg_get_peer_unmap_conf_support(soc);
1704 
1705 	cdp_peer_teardown(soc, vdev_id, peer_addr);
1706 
1707 	if (no_fw_peer_delete)
1708 		goto peer_detach;
1709 
1710 	/* Flush all TIDs except MGMT TID for this peer in Target */
1711 	peer_tid_bitmap &= ~(0x1 << WMI_MGMT_TID);
1712 	param.peer_tid_bitmap = peer_tid_bitmap;
1713 	param.vdev_id = vdev_id;
1714 	if (!wmi_service_enabled(wma->wmi_handle,
1715 				 wmi_service_peer_delete_no_peer_flush_tids_cmd))
1716 		wmi_unified_peer_flush_tids_send(wma->wmi_handle, mac_addr,
1717 						 &param);
1718 
1719 	/* peer->ref_cnt is not visible in WMA */
1720 	wlan_roam_debug_log(vdev_id, DEBUG_PEER_DELETE_SEND,
1721 			    DEBUG_INVALID_PEER_ID, peer_addr, NULL,
1722 			    0, 0);
1723 
1724 	del_param.vdev_id = vdev_id;
1725 	qdf_status = wmi_unified_peer_delete_send(wma->wmi_handle, peer_addr,
1726 						  &del_param);
1727 	if (QDF_IS_STATUS_ERROR(qdf_status)) {
1728 		wma_err("Peer delete could not be sent to firmware %d",
1729 			qdf_status);
1730 		/* Clear default bit and set to NOT_START_UNMAP */
1731 		bitmap = 1 << CDP_PEER_DO_NOT_START_UNMAP_TIMER;
1732 		qdf_status = QDF_STATUS_E_FAILURE;
1733 	}
1734 
1735 peer_detach:
1736 	wma_debug("vdevid %d is detaching with peer_addr "QDF_MAC_ADDR_FMT" peer_count %d",
1737 		vdev_id, QDF_MAC_ADDR_REF(peer_addr),
1738 		wma->interfaces[vdev_id].peer_count);
1739 	/* Copy peer mac to find and delete objmgr peer */
1740 	qdf_mem_copy(peer_mac, peer_addr, QDF_MAC_ADDR_SIZE);
1741 	if (no_fw_peer_delete &&
1742 	    is_cdp_peer_detach_force_delete_supported(soc)) {
1743 		if (!peer_unmap_conf_support_enabled) {
1744 			wma_debug("LFR3: trigger force delete for peer "QDF_MAC_ADDR_FMT,
1745 				 QDF_MAC_ADDR_REF(peer_addr));
1746 			cdp_peer_detach_force_delete(soc, vdev_id, peer_addr);
1747 		} else {
1748 			cdp_peer_delete_sync(soc, vdev_id, peer_addr,
1749 					     wma_peer_unmap_conf_cb,
1750 					     bitmap);
1751 		}
1752 	} else {
1753 		if (no_fw_peer_delete)
1754 			wma_debug("LFR3: Delete the peer "QDF_MAC_ADDR_FMT,
1755 				  QDF_MAC_ADDR_REF(peer_addr));
1756 
1757 		if (peer_unmap_conf_support_enabled)
1758 			cdp_peer_delete_sync(soc, vdev_id, peer_addr,
1759 					     wma_peer_unmap_conf_cb,
1760 					     bitmap);
1761 		else
1762 			cdp_peer_delete(soc, vdev_id, peer_addr, bitmap);
1763 	}
1764 
1765 	wlan_release_peer_key_wakelock(wma->pdev, peer_mac);
1766 	wma_remove_objmgr_peer(wma, wma->interfaces[vdev_id].vdev, peer_mac);
1767 
1768 	wma->interfaces[vdev_id].peer_count--;
1769 #undef PEER_ALL_TID_BITMASK
1770 
1771 	return qdf_status;
1772 }
1773 
1774 /**
1775  * wma_get_peer_type() - Determine the type of peer(eg. STA/AP) and return it
1776  * @wma: wma handle
1777  * @vdev_id: vdev id
1778  * @peer_addr: peer mac address
1779  * @wma_peer_type: wma peer type
1780  *
1781  * Return: Peer type
1782  */
1783 static int wma_get_obj_mgr_peer_type(tp_wma_handle wma, uint8_t vdev_id,
1784 				     uint8_t *peer_addr, uint32_t wma_peer_type)
1785 
1786 {
1787 	uint32_t obj_peer_type = 0;
1788 	struct wlan_objmgr_vdev *vdev;
1789 	uint8_t *addr;
1790 	uint8_t *mld_addr;
1791 
1792 	vdev = wma->interfaces[vdev_id].vdev;
1793 	if (!vdev) {
1794 		wma_err("Couldn't find vdev for VDEV_%d", vdev_id);
1795 		return obj_peer_type;
1796 	}
1797 	addr = wlan_vdev_mlme_get_macaddr(vdev);
1798 	mld_addr = wlan_vdev_mlme_get_mldaddr(vdev);
1799 
1800 	if (wma_peer_type == WMI_PEER_TYPE_TDLS)
1801 		return WLAN_PEER_TDLS;
1802 
1803 	if (wma_peer_type == WMI_PEER_TYPE_PASN)
1804 		return WLAN_PEER_RTT_PASN;
1805 
1806 	if (!qdf_mem_cmp(addr, peer_addr, QDF_MAC_ADDR_SIZE) ||
1807 	    !qdf_mem_cmp(mld_addr, peer_addr, QDF_MAC_ADDR_SIZE)) {
1808 		obj_peer_type = WLAN_PEER_SELF;
1809 	} else if (wma->interfaces[vdev_id].type == WMI_VDEV_TYPE_STA) {
1810 		if (wma->interfaces[vdev_id].sub_type ==
1811 					WMI_UNIFIED_VDEV_SUBTYPE_P2P_CLIENT)
1812 			obj_peer_type = WLAN_PEER_P2P_GO;
1813 		else
1814 			obj_peer_type = WLAN_PEER_AP;
1815 	} else if (wma->interfaces[vdev_id].type == WMI_VDEV_TYPE_AP) {
1816 			obj_peer_type = WLAN_PEER_STA;
1817 	} else if (wma->interfaces[vdev_id].type == WMI_VDEV_TYPE_IBSS) {
1818 		obj_peer_type = WLAN_PEER_IBSS;
1819 	} else if (wma->interfaces[vdev_id].type == WMI_VDEV_TYPE_NDI) {
1820 		obj_peer_type = WLAN_PEER_NDP;
1821 	} else {
1822 		wma_err("Couldn't find peertype for type %d and sub type %d",
1823 			 wma->interfaces[vdev_id].type,
1824 			 wma->interfaces[vdev_id].sub_type);
1825 	}
1826 
1827 	return obj_peer_type;
1828 
1829 }
1830 
1831 #ifdef WLAN_FEATURE_11BE_MLO
1832 static QDF_STATUS
1833 wma_create_peer_validate_mld_address(tp_wma_handle wma,
1834 				     uint8_t *peer_mld_addr,
1835 				     struct wlan_objmgr_vdev *vdev)
1836 {
1837 	uint8_t peer_vdev_id, vdev_id;
1838 	struct wlan_objmgr_vdev *dup_vdev;
1839 	QDF_STATUS status = QDF_STATUS_SUCCESS;
1840 	struct wlan_objmgr_psoc *psoc = wma->psoc;
1841 
1842 	vdev_id = wlan_vdev_get_id(vdev);
1843 	/* Check if the @peer_mld_addr matches any other
1844 	 * peer's link address.
1845 	 * We may find a match if one of the peers added
1846 	 * has same MLD and link, in such case check if
1847 	 * both are in same ML dev context.
1848 	 */
1849 	if (wma_objmgr_peer_exist(wma, peer_mld_addr, &peer_vdev_id)) {
1850 		if (peer_vdev_id != vdev_id) {
1851 			dup_vdev = wlan_objmgr_get_vdev_by_id_from_psoc(
1852 						psoc, peer_vdev_id,
1853 						WLAN_LEGACY_WMA_ID);
1854 			if (!dup_vdev)
1855 				return QDF_STATUS_E_INVAL;
1856 
1857 			/* If ML dev context is NULL then the matching
1858 			 * peer exist on non ML VDEV, so reject the peer.
1859 			 */
1860 			if (!dup_vdev->mlo_dev_ctx) {
1861 				wlan_objmgr_vdev_release_ref(
1862 						dup_vdev, WLAN_LEGACY_WMA_ID);
1863 				return QDF_STATUS_E_ALREADY;
1864 			} else if (dup_vdev->mlo_dev_ctx != vdev->mlo_dev_ctx) {
1865 				wma_debug("Peer " QDF_MAC_ADDR_FMT " already exists on vdev %d, current vdev %d",
1866 					  QDF_MAC_ADDR_REF(peer_mld_addr),
1867 					  peer_vdev_id, vdev_id);
1868 				wlan_objmgr_vdev_release_ref(
1869 						dup_vdev, WLAN_LEGACY_WMA_ID);
1870 				status = QDF_STATUS_E_ALREADY;
1871 			} else {
1872 				wlan_objmgr_vdev_release_ref(
1873 						dup_vdev, WLAN_LEGACY_WMA_ID);
1874 				wma_debug("Allow ML peer on same ML dev context");
1875 				status = QDF_STATUS_SUCCESS;
1876 			}
1877 		} else {
1878 			wma_debug("ML Peer exists on same VDEV %d", vdev_id);
1879 			status = QDF_STATUS_E_ALREADY;
1880 		}
1881 	} else if (mlo_mgr_ml_peer_exist_on_diff_ml_ctx(peer_mld_addr,
1882 							&vdev_id)) {
1883 		/* Reject if MLD exists on different ML dev context,
1884 		 */
1885 		wma_debug("ML Peer " QDF_MAC_ADDR_FMT " already exists on different ML dev context",
1886 			  QDF_MAC_ADDR_REF(peer_mld_addr));
1887 		status = QDF_STATUS_E_ALREADY;
1888 	}
1889 
1890 	return status;
1891 }
1892 #else
1893 static QDF_STATUS
1894 wma_create_peer_validate_mld_address(tp_wma_handle wma,
1895 				     uint8_t *peer_mld_addr,
1896 				     struct wlan_objmgr_vdev *vdev)
1897 {
1898 	return QDF_STATUS_SUCCESS;
1899 }
1900 #endif
1901 
1902 struct wlan_objmgr_peer *wma_create_objmgr_peer(tp_wma_handle wma,
1903 						uint8_t vdev_id,
1904 						uint8_t *peer_addr,
1905 						uint32_t wma_peer_type,
1906 						uint8_t *peer_mld_addr)
1907 {
1908 	QDF_STATUS status;
1909 	uint8_t peer_vdev_id;
1910 	uint32_t obj_peer_type;
1911 	struct wlan_objmgr_vdev *obj_vdev;
1912 	struct wlan_objmgr_peer *obj_peer = NULL;
1913 	struct wlan_objmgr_psoc *psoc = wma->psoc;
1914 
1915 	obj_vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
1916 							WLAN_LEGACY_WMA_ID);
1917 
1918 	if (!obj_vdev) {
1919 		wma_err("Invalid obj vdev. Unable to create peer");
1920 		return NULL;
1921 	}
1922 
1923 	/*
1924 	 * Check if peer with same MAC exist on any Vdev, If so avoid
1925 	 * adding this peer.
1926 	 */
1927 	if (wma_objmgr_peer_exist(wma, peer_addr, &peer_vdev_id)) {
1928 		wma_debug("Peer " QDF_MAC_ADDR_FMT " already exists on vdev %d, current vdev %d",
1929 			  QDF_MAC_ADDR_REF(peer_addr), peer_vdev_id, vdev_id);
1930 		goto vdev_ref;
1931 	}
1932 
1933 	/* Reject if same MAC exists on different ML dev context */
1934 	if (mlo_mgr_ml_peer_exist_on_diff_ml_ctx(peer_addr,
1935 						 &vdev_id)) {
1936 		wma_debug("Peer " QDF_MAC_ADDR_FMT " already exists on different ML dev context",
1937 			  QDF_MAC_ADDR_REF(peer_addr));
1938 		goto vdev_ref;
1939 	}
1940 
1941 	status = wma_create_peer_validate_mld_address(wma, peer_mld_addr,
1942 						      obj_vdev);
1943 	if (QDF_IS_STATUS_ERROR(status)) {
1944 		wma_debug("MLD " QDF_MAC_ADDR_FMT " matches with peer on different MLD context",
1945 			  QDF_MAC_ADDR_REF(peer_mld_addr));
1946 		goto vdev_ref;
1947 	}
1948 
1949 	obj_peer_type = wma_get_obj_mgr_peer_type(wma, vdev_id, peer_addr,
1950 						  wma_peer_type);
1951 	if (!obj_peer_type) {
1952 		wma_err("Invalid obj peer type. Unable to create peer %d",
1953 			obj_peer_type);
1954 		goto vdev_ref;
1955 	}
1956 
1957 	/* Create obj_mgr peer */
1958 	obj_peer = wlan_objmgr_peer_obj_create(obj_vdev, obj_peer_type,
1959 						peer_addr);
1960 
1961 vdev_ref:
1962 	wlan_objmgr_vdev_release_ref(obj_vdev, WLAN_LEGACY_WMA_ID);
1963 
1964 	return obj_peer;
1965 
1966 }
1967 
1968 /**
1969  * wma_increment_peer_count() - Increment the vdev peer
1970  * count
1971  * @wma: wma handle
1972  * @vdev_id: vdev id
1973  *
1974  * Return: None
1975  */
1976 static void
1977 wma_increment_peer_count(tp_wma_handle wma, uint8_t vdev_id)
1978 {
1979 	wma->interfaces[vdev_id].peer_count++;
1980 }
1981 
1982 /**
1983  * wma_update_mlo_peer_create() - update mlo parameter for peer creation
1984  * @param: peer create param
1985  * @mlo_enable: mlo enable or not
1986  *
1987  * Return: Void
1988  */
1989 #ifdef WLAN_FEATURE_11BE_MLO
1990 static void wma_update_mlo_peer_create(struct peer_create_params *param,
1991 				       bool mlo_enable)
1992 {
1993 	param->mlo_enabled = mlo_enable;
1994 }
1995 #else
1996 static void wma_update_mlo_peer_create(struct peer_create_params *param,
1997 				       bool mlo_enable)
1998 {
1999 }
2000 #endif
2001 
2002 /**
2003  * wma_add_peer() - send peer create command to fw
2004  * @wma: wma handle
2005  * @peer_addr: peer mac addr
2006  * @peer_type: peer type
2007  * @vdev_id: vdev id
2008  * @peer_mld_addr: peer mld addr
2009  * @is_assoc_peer: is assoc peer or not
2010  *
2011  * Return: QDF status
2012  */
2013 static
2014 QDF_STATUS wma_add_peer(tp_wma_handle wma,
2015 			uint8_t peer_addr[QDF_MAC_ADDR_SIZE],
2016 			uint32_t peer_type, uint8_t vdev_id,
2017 			uint8_t peer_mld_addr[QDF_MAC_ADDR_SIZE],
2018 			bool is_assoc_peer)
2019 {
2020 	struct peer_create_params param = {0};
2021 	void *dp_soc = cds_get_context(QDF_MODULE_ID_SOC);
2022 	struct wlan_objmgr_psoc *psoc = wma->psoc;
2023 	target_resource_config *wlan_res_cfg;
2024 	struct wlan_objmgr_peer *obj_peer = NULL;
2025 	QDF_STATUS status;
2026 
2027 	if (!psoc) {
2028 		wma_err("psoc is NULL");
2029 		return QDF_STATUS_E_INVAL;
2030 	}
2031 
2032 	wlan_res_cfg = lmac_get_tgt_res_cfg(psoc);
2033 	if (!wlan_res_cfg) {
2034 		wma_err("psoc target res cfg is null");
2035 		return QDF_STATUS_E_INVAL;
2036 	}
2037 
2038 	if (wma->interfaces[vdev_id].peer_count >=
2039 	    wlan_res_cfg->num_peers) {
2040 		wma_err("the peer count exceeds the limit %d",
2041 			 wma->interfaces[vdev_id].peer_count);
2042 		return QDF_STATUS_E_FAILURE;
2043 	}
2044 
2045 	if (!dp_soc)
2046 		return QDF_STATUS_E_FAILURE;
2047 
2048 	if (qdf_is_macaddr_group((struct qdf_mac_addr *)peer_addr) ||
2049 	    qdf_is_macaddr_zero((struct qdf_mac_addr *)peer_addr)) {
2050 		wma_err("Invalid peer address received reject it");
2051 		return QDF_STATUS_E_FAILURE;
2052 	}
2053 
2054 	obj_peer = wma_create_objmgr_peer(wma, vdev_id, peer_addr, peer_type,
2055 					  peer_mld_addr);
2056 	if (!obj_peer)
2057 		return QDF_STATUS_E_FAILURE;
2058 
2059 	/* The peer object should be created before sending the WMI peer
2060 	 * create command to firmware. This is to prevent a race condition
2061 	 * where the HTT peer map event is received before the peer object
2062 	 * is created in the data path
2063 	 */
2064 	if (peer_mld_addr &&
2065 	    !qdf_is_macaddr_zero((struct qdf_mac_addr *)peer_mld_addr)) {
2066 		wlan_peer_mlme_flag_ext_set(obj_peer, WLAN_PEER_FEXT_MLO);
2067 		wma_debug("peer " QDF_MAC_ADDR_FMT "is_assoc_peer%d mld mac " QDF_MAC_ADDR_FMT,
2068 			  QDF_MAC_ADDR_REF(peer_addr), is_assoc_peer,
2069 			  QDF_MAC_ADDR_REF(peer_mld_addr));
2070 		wlan_peer_mlme_set_mldaddr(obj_peer, peer_mld_addr);
2071 		wlan_peer_mlme_set_assoc_peer(obj_peer, is_assoc_peer);
2072 		wma_update_mlo_peer_create(&param, true);
2073 	}
2074 	status = cdp_peer_create(dp_soc, vdev_id, peer_addr);
2075 	if (QDF_IS_STATUS_ERROR(status)) {
2076 		wma_err("Unable to attach peer "QDF_MAC_ADDR_FMT,
2077 			QDF_MAC_ADDR_REF(peer_addr));
2078 		wlan_objmgr_peer_obj_delete(obj_peer);
2079 		return QDF_STATUS_E_FAILURE;
2080 	}
2081 
2082 	if (peer_type == WMI_PEER_TYPE_TDLS)
2083 		cdp_peer_set_peer_as_tdls(dp_soc, vdev_id, peer_addr, true);
2084 
2085 	if (wlan_cm_is_roam_sync_in_progress(wma->psoc, vdev_id) ||
2086 	    MLME_IS_MLO_ROAM_SYNCH_IN_PROGRESS(wma->psoc, vdev_id)) {
2087 		wma_debug("LFR3: Created peer "QDF_MAC_ADDR_FMT" vdev_id %d, peer_count %d",
2088 			 QDF_MAC_ADDR_REF(peer_addr), vdev_id,
2089 			 wma->interfaces[vdev_id].peer_count + 1);
2090 		return QDF_STATUS_SUCCESS;
2091 	}
2092 	param.peer_addr = peer_addr;
2093 	param.peer_type = peer_type;
2094 	param.vdev_id = vdev_id;
2095 	if (wmi_unified_peer_create_send(wma->wmi_handle,
2096 					 &param) != QDF_STATUS_SUCCESS) {
2097 		wma_err("Unable to create peer in Target");
2098 		if (cdp_cfg_get_peer_unmap_conf_support(dp_soc))
2099 			cdp_peer_delete_sync(
2100 				dp_soc, vdev_id, peer_addr,
2101 				wma_peer_unmap_conf_cb,
2102 				1 << CDP_PEER_DO_NOT_START_UNMAP_TIMER);
2103 		else
2104 			cdp_peer_delete(
2105 				dp_soc, vdev_id, peer_addr,
2106 				1 << CDP_PEER_DO_NOT_START_UNMAP_TIMER);
2107 		wlan_objmgr_peer_obj_delete(obj_peer);
2108 
2109 		return QDF_STATUS_E_FAILURE;
2110 	}
2111 
2112 	wma_debug("Created peer peer_addr "QDF_MAC_ADDR_FMT" vdev_id %d, peer_count - %d",
2113 		  QDF_MAC_ADDR_REF(peer_addr), vdev_id,
2114 		  wma->interfaces[vdev_id].peer_count + 1);
2115 
2116 	wlan_roam_debug_log(vdev_id, DEBUG_PEER_CREATE_SEND,
2117 			    DEBUG_INVALID_PEER_ID, peer_addr, NULL, 0, 0);
2118 
2119 	return QDF_STATUS_SUCCESS;
2120 }
2121 
2122 #ifdef WLAN_FEATURE_11BE_MLO
2123 /**
2124  * wma_cdp_peer_setup() - provide mlo information to cdp_peer_setup
2125  * @wma: wma handle
2126  * @dp_soc: dp soc
2127  * @vdev_id: vdev id
2128  * @peer_addr: peer mac addr
2129  *
2130  * Return: VOID
2131  */
2132 static void wma_cdp_peer_setup(tp_wma_handle wma,
2133 			       ol_txrx_soc_handle dp_soc,
2134 			       uint8_t vdev_id,
2135 			       uint8_t *peer_addr)
2136 {
2137 	struct cdp_peer_setup_info peer_info;
2138 	uint8_t *mld_mac;
2139 	struct wlan_objmgr_peer *obj_peer = NULL;
2140 
2141 	obj_peer = wlan_objmgr_get_peer_by_mac(wma->psoc,
2142 					       peer_addr,
2143 					       WLAN_LEGACY_WMA_ID);
2144 	if (!obj_peer) {
2145 		wma_err("Invalid obj_peer");
2146 		return;
2147 	}
2148 
2149 	mld_mac = wlan_peer_mlme_get_mldaddr(obj_peer);
2150 
2151 	if (!mld_mac || qdf_is_macaddr_zero((struct qdf_mac_addr *)mld_mac)) {
2152 		cdp_peer_setup(dp_soc, vdev_id, peer_addr, NULL);
2153 		wlan_objmgr_peer_release_ref(obj_peer, WLAN_LEGACY_WMA_ID);
2154 		return;
2155 	}
2156 
2157 	qdf_mem_zero(&peer_info, sizeof(peer_info));
2158 
2159 	peer_info.mld_peer_mac = mld_mac;
2160 	if (MLME_IS_MLO_ROAM_SYNCH_IN_PROGRESS(wma->psoc, vdev_id) &&
2161 	    wlan_vdev_mlme_get_is_mlo_link(wma->psoc, vdev_id)) {
2162 		peer_info.is_first_link = 1;
2163 		peer_info.is_primary_link = 0;
2164 	} else if (wlan_cm_is_roam_sync_in_progress(wma->psoc, vdev_id) &&
2165 		   wlan_vdev_mlme_get_is_mlo_vdev(wma->psoc, vdev_id)) {
2166 		if (mlo_get_single_link_ml_roaming(wma->psoc, vdev_id)) {
2167 			peer_info.is_first_link = 1;
2168 			peer_info.is_primary_link = 1;
2169 		} else {
2170 			peer_info.is_first_link = 0;
2171 			peer_info.is_primary_link = 1;
2172 		}
2173 	} else {
2174 		peer_info.is_first_link = wlan_peer_mlme_is_assoc_peer(obj_peer);
2175 		peer_info.is_primary_link = peer_info.is_first_link;
2176 	}
2177 
2178 	cdp_peer_setup(dp_soc, vdev_id, peer_addr, &peer_info);
2179 	wlan_objmgr_peer_release_ref(obj_peer, WLAN_LEGACY_WMA_ID);
2180 }
2181 #else
2182 static void wma_cdp_peer_setup(tp_wma_handle wma,
2183 			       ol_txrx_soc_handle dp_soc,
2184 			       uint8_t vdev_id,
2185 			       uint8_t *peer_addr)
2186 {
2187 	cdp_peer_setup(dp_soc, vdev_id, peer_addr, NULL);
2188 }
2189 #endif
2190 
2191 QDF_STATUS wma_create_peer(tp_wma_handle wma,
2192 			   uint8_t peer_addr[QDF_MAC_ADDR_SIZE],
2193 			   uint32_t peer_type, uint8_t vdev_id,
2194 			   uint8_t peer_mld_addr[QDF_MAC_ADDR_SIZE],
2195 			   bool is_assoc_peer)
2196 {
2197 	void *dp_soc = cds_get_context(QDF_MODULE_ID_SOC);
2198 	QDF_STATUS status;
2199 
2200 	if (!dp_soc)
2201 		return QDF_STATUS_E_FAILURE;
2202 	status = wma_add_peer(wma, peer_addr, peer_type, vdev_id,
2203 			      peer_mld_addr, is_assoc_peer);
2204 	if (QDF_IS_STATUS_ERROR(status))
2205 		return status;
2206 
2207 	wma_increment_peer_count(wma, vdev_id);
2208 	wma_cdp_peer_setup(wma, dp_soc, vdev_id, peer_addr);
2209 
2210 	return QDF_STATUS_SUCCESS;
2211 }
2212 
2213 /**
2214  * wma_create_sta_mode_bss_peer() - send peer create command to fw
2215  * and start peer create response timer
2216  * @wma: wma handle
2217  * @peer_addr: peer mac address
2218  * @peer_type: peer type
2219  * @vdev_id: vdev id
2220  * @mld_addr: peer mld address
2221  * @is_assoc_peer: is assoc peer or not
2222  *
2223  * Return: QDF_STATUS
2224  */
2225 static QDF_STATUS
2226 wma_create_sta_mode_bss_peer(tp_wma_handle wma,
2227 			     uint8_t peer_addr[QDF_MAC_ADDR_SIZE],
2228 			     uint32_t peer_type, uint8_t vdev_id,
2229 			     uint8_t mld_addr[QDF_MAC_ADDR_SIZE],
2230 			     bool is_assoc_peer)
2231 {
2232 	struct mac_context *mac = cds_get_context(QDF_MODULE_ID_PE);
2233 	struct wma_target_req *msg = NULL;
2234 	struct peer_create_rsp_params *peer_create_rsp = NULL;
2235 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
2236 	bool is_tgt_peer_conf_supported = false;
2237 
2238 	if (!mac) {
2239 		wma_err("vdev%d: Mac context is null", vdev_id);
2240 		return status;
2241 	}
2242 
2243 	/*
2244 	 * If fw doesn't advertise peer create confirm event support,
2245 	 * use the legacy peer create API
2246 	 */
2247 	is_tgt_peer_conf_supported =
2248 		wlan_psoc_nif_fw_ext_cap_get(wma->psoc,
2249 					     WLAN_SOC_F_PEER_CREATE_RESP);
2250 	if (!is_tgt_peer_conf_supported) {
2251 		status = wma_create_peer(wma, peer_addr, peer_type, vdev_id,
2252 					 mld_addr, is_assoc_peer);
2253 		goto end;
2254 	}
2255 
2256 	peer_create_rsp = qdf_mem_malloc(sizeof(*peer_create_rsp));
2257 	if (!peer_create_rsp)
2258 		goto end;
2259 
2260 	wma_acquire_wakelock(&wma->wmi_cmd_rsp_wake_lock,
2261 			     WMA_PEER_CREATE_RESPONSE_TIMEOUT);
2262 
2263 	status = wma_add_peer(wma, peer_addr, peer_type, vdev_id,
2264 			      mld_addr, is_assoc_peer);
2265 	if (QDF_IS_STATUS_ERROR(status)) {
2266 		wma_release_wakelock(&wma->wmi_cmd_rsp_wake_lock);
2267 		goto end;
2268 	}
2269 
2270 	wma_increment_peer_count(wma, vdev_id);
2271 	qdf_mem_copy(peer_create_rsp->peer_mac.bytes, peer_addr,
2272 		     QDF_MAC_ADDR_SIZE);
2273 
2274 	msg = wma_fill_hold_req(wma, vdev_id, WMA_PEER_CREATE_REQ,
2275 				WMA_PEER_CREATE_RESPONSE,
2276 				(void *)peer_create_rsp,
2277 				WMA_PEER_CREATE_RESPONSE_TIMEOUT);
2278 	if (!msg) {
2279 		wma_err("vdev:%d failed to fill peer create req", vdev_id);
2280 		wma_remove_peer_req(wma, vdev_id, WMA_PEER_CREATE_RESPONSE,
2281 				    (struct qdf_mac_addr *)peer_addr);
2282 		wma_remove_peer(wma, peer_addr, vdev_id, false);
2283 		wma_release_wakelock(&wma->wmi_cmd_rsp_wake_lock);
2284 		status = QDF_STATUS_E_FAILURE;
2285 		goto end;
2286 	}
2287 
2288 	return status;
2289 
2290 end:
2291 	qdf_mem_free(peer_create_rsp);
2292 	lim_send_peer_create_resp(mac, vdev_id, status, peer_addr);
2293 
2294 	return status;
2295 }
2296 
2297 /**
2298  * wma_remove_bss_peer() - remove BSS peer
2299  * @wma: pointer to WMA handle
2300  * @vdev_id: vdev id on which delete BSS request was received
2301  * @vdev_stop_resp: pointer to Delete BSS response
2302  *
2303  * This function is called on receiving vdev stop response from FW or
2304  * vdev stop response timeout. In case of NDI, use vdev's self MAC
2305  * for removing the peer. In case of STA/SAP use bssid passed as part of
2306  * delete STA parameter.
2307  *
2308  * Return: 0 on success, ERROR code on failure
2309  */
2310 static int wma_remove_bss_peer(tp_wma_handle wma, uint32_t vdev_id,
2311 			       struct del_bss_resp *vdev_stop_resp,
2312 			       uint8_t type)
2313 {
2314 	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
2315 	uint8_t *mac_addr = NULL;
2316 	struct wma_target_req *del_req;
2317 	int ret_value = 0;
2318 	QDF_STATUS qdf_status;
2319 	struct qdf_mac_addr bssid;
2320 
2321 	if (WMA_IS_VDEV_IN_NDI_MODE(wma->interfaces, vdev_id)) {
2322 		mac_addr = cdp_get_vdev_mac_addr(soc, vdev_id);
2323 		if (!mac_addr) {
2324 			wma_err("mac_addr is NULL for vdev_id = %d", vdev_id);
2325 			return -EINVAL;
2326 		}
2327 	} else {
2328 		qdf_status = wlan_vdev_get_bss_peer_mac(
2329 				wma->interfaces[vdev_id].vdev,
2330 				&bssid);
2331 		if (QDF_IS_STATUS_ERROR(qdf_status)) {
2332 			wma_err("Failed to get bssid for vdev_id: %d", vdev_id);
2333 			return -EINVAL;
2334 		}
2335 		mac_addr = bssid.bytes;
2336 	}
2337 
2338 	qdf_status = wma_remove_peer(wma, mac_addr, vdev_id, false);
2339 
2340 	if (QDF_IS_STATUS_ERROR(qdf_status)) {
2341 		wma_err("wma_remove_peer failed vdev_id:%d", vdev_id);
2342 		return -EINVAL;
2343 	}
2344 
2345 	if (cds_is_driver_recovering())
2346 		return -EINVAL;
2347 
2348 	if (wmi_service_enabled(wma->wmi_handle,
2349 				wmi_service_sync_delete_cmds)) {
2350 		wma_debug("Wait for the peer delete. vdev_id %d", vdev_id);
2351 		del_req = wma_fill_hold_req(wma, vdev_id,
2352 					    WMA_DELETE_STA_REQ,
2353 					    type,
2354 					    vdev_stop_resp,
2355 					    WMA_DELETE_STA_TIMEOUT);
2356 		if (!del_req) {
2357 			wma_err("Failed to allocate request. vdev_id %d", vdev_id);
2358 			vdev_stop_resp->status = QDF_STATUS_E_NOMEM;
2359 			ret_value = -EINVAL;
2360 		}
2361 	}
2362 
2363 	return ret_value;
2364 }
2365 
2366 #ifdef FEATURE_WLAN_APF
2367 /*
2368  * get_fw_active_apf_mode() - convert HDD APF mode to FW configurable APF
2369  * mode
2370  * @mode: APF mode maintained in HDD
2371  *
2372  * Return: FW configurable BP mode
2373  */
2374 static enum wmi_host_active_apf_mode
2375 get_fw_active_apf_mode(enum active_apf_mode mode)
2376 {
2377 	switch (mode) {
2378 	case ACTIVE_APF_DISABLED:
2379 		return WMI_HOST_ACTIVE_APF_DISABLED;
2380 	case ACTIVE_APF_ENABLED:
2381 		return WMI_HOST_ACTIVE_APF_ENABLED;
2382 	case ACTIVE_APF_ADAPTIVE:
2383 		return WMI_HOST_ACTIVE_APF_ADAPTIVE;
2384 	default:
2385 		wma_err("Invalid Active APF Mode %d; Using 'disabled'", mode);
2386 		return WMI_HOST_ACTIVE_APF_DISABLED;
2387 	}
2388 }
2389 
2390 /**
2391  * wma_config_active_apf_mode() - Config active APF mode in FW
2392  * @wma: the WMA handle
2393  * @vdev_id: the Id of the vdev for which the configuration should be applied
2394  *
2395  * Return: QDF status
2396  */
2397 static QDF_STATUS wma_config_active_apf_mode(t_wma_handle *wma, uint8_t vdev_id)
2398 {
2399 	enum wmi_host_active_apf_mode uc_mode, mcbc_mode;
2400 
2401 	uc_mode = get_fw_active_apf_mode(wma->active_uc_apf_mode);
2402 	mcbc_mode = get_fw_active_apf_mode(wma->active_mc_bc_apf_mode);
2403 
2404 	wma_debug("Configuring Active APF Mode UC:%d MC/BC:%d for vdev %u",
2405 		 uc_mode, mcbc_mode, vdev_id);
2406 
2407 	return wmi_unified_set_active_apf_mode_cmd(wma->wmi_handle, vdev_id,
2408 						   uc_mode, mcbc_mode);
2409 }
2410 #else /* FEATURE_WLAN_APF */
2411 static QDF_STATUS wma_config_active_apf_mode(t_wma_handle *wma, uint8_t vdev_id)
2412 {
2413 	return QDF_STATUS_SUCCESS;
2414 }
2415 #endif /* FEATURE_WLAN_APF */
2416 
2417 #ifdef FEATURE_AP_MCC_CH_AVOIDANCE
2418 /**
2419  * wma_check_and_find_mcc_ap() - finds if device is operating AP
2420  * in MCC mode or not
2421  * @wma: wma handle.
2422  * @vdev_id: vdev ID of device for which MCC has to be checked
2423  *
2424  * This function internally calls wma_find_mcc_ap finds if
2425  * device is operating AP in MCC mode or not
2426  *
2427  * Return: none
2428  */
2429 static void
2430 wma_check_and_find_mcc_ap(tp_wma_handle wma, uint8_t vdev_id)
2431 {
2432 	struct mac_context *mac_ctx = cds_get_context(QDF_MODULE_ID_PE);
2433 
2434 	if (!mac_ctx)
2435 		return;
2436 
2437 	if (mac_ctx->sap.sap_channel_avoidance)
2438 		wma_find_mcc_ap(wma, vdev_id, false);
2439 }
2440 #else
2441 static inline void
2442 wma_check_and_find_mcc_ap(tp_wma_handle wma, uint8_t vdev_id)
2443 {}
2444 #endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
2445 
2446 void wma_send_del_bss_response(tp_wma_handle wma, struct del_bss_resp *resp)
2447 {
2448 	struct wma_txrx_node *iface;
2449 	struct beacon_info *bcn;
2450 	uint8_t vdev_id;
2451 	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
2452 
2453 	if (!resp) {
2454 		wma_err("req is NULL");
2455 		return;
2456 	}
2457 
2458 	vdev_id = resp->vdev_id;
2459 	iface = &wma->interfaces[vdev_id];
2460 
2461 	if (!iface->vdev) {
2462 		wma_err("vdev id %d iface->vdev is NULL", vdev_id);
2463 		if (resp)
2464 			qdf_mem_free(resp);
2465 		return;
2466 	}
2467 
2468 	cdp_fc_vdev_flush(soc, vdev_id);
2469 	wma_debug("vdev_id: %d, un-pausing tx_ll_queue for VDEV_STOP rsp",
2470 		 vdev_id);
2471 	cdp_fc_vdev_unpause(soc, vdev_id, OL_TXQ_PAUSE_REASON_VDEV_STOP, 0);
2472 	wma_vdev_clear_pause_bit(vdev_id, PAUSE_TYPE_HOST);
2473 	qdf_atomic_set(&iface->bss_status, WMA_BSS_STATUS_STOPPED);
2474 	wma_debug("(type %d subtype %d) BSS is stopped",
2475 		 iface->type, iface->sub_type);
2476 
2477 	bcn = wma->interfaces[vdev_id].beacon;
2478 	if (bcn) {
2479 		wma_debug("Freeing beacon struct %pK, template memory %pK",
2480 			 bcn, bcn->buf);
2481 		if (bcn->dma_mapped)
2482 			qdf_nbuf_unmap_single(wma->qdf_dev, bcn->buf,
2483 					  QDF_DMA_TO_DEVICE);
2484 		qdf_nbuf_free(bcn->buf);
2485 		qdf_mem_free(bcn);
2486 		wma->interfaces[vdev_id].beacon = NULL;
2487 	}
2488 
2489 	/* Timeout status means its WMA generated DEL BSS REQ when ADD
2490 	 * BSS REQ was timed out to stop the VDEV in this case no need
2491 	 * to send response to UMAC
2492 	 */
2493 	if (resp->status == QDF_STATUS_FW_MSG_TIMEDOUT) {
2494 		qdf_mem_free(resp);
2495 		wma_err("DEL BSS from ADD BSS timeout do not send resp to UMAC (vdev id %x)",
2496 			vdev_id);
2497 	} else {
2498 		resp->status = QDF_STATUS_SUCCESS;
2499 		wma_send_msg_high_priority(wma, WMA_DELETE_BSS_RSP,
2500 					   (void *)resp, 0);
2501 	}
2502 
2503 	if (iface->del_staself_req && iface->is_del_sta_deferred) {
2504 		iface->is_del_sta_deferred = false;
2505 		wma_nofl_alert("scheduling deferred deletion (vdev id %x)",
2506 			      vdev_id);
2507 		wma_vdev_detach(iface->del_staself_req);
2508 	}
2509 }
2510 
2511 QDF_STATUS
2512 wma_send_vdev_down(tp_wma_handle wma, struct del_bss_resp *resp)
2513 {
2514 	uint8_t vdev_id;
2515 	struct wma_txrx_node *iface = &wma->interfaces[resp->vdev_id];
2516 	uint32_t vdev_stop_type;
2517 	QDF_STATUS status;
2518 
2519 	if (!resp) {
2520 		wma_err("resp is NULL");
2521 		return QDF_STATUS_E_NULL_VALUE;
2522 	}
2523 
2524 	vdev_id = resp->vdev_id;
2525 	status = mlme_get_vdev_stop_type(iface->vdev, &vdev_stop_type);
2526 	if (QDF_IS_STATUS_ERROR(status)) {
2527 		wma_err("Failed to get vdev stop type");
2528 		qdf_mem_free(resp);
2529 		return status;
2530 	}
2531 
2532 	if (vdev_stop_type != WMA_DELETE_BSS_HO_FAIL_REQ) {
2533 		status = wma_send_vdev_down_to_fw(wma, vdev_id);
2534 		if (QDF_IS_STATUS_ERROR(status))
2535 			wma_err("Failed to send vdev down cmd: vdev %d", vdev_id);
2536 		else
2537 			wma_check_and_find_mcc_ap(wma, vdev_id);
2538 	}
2539 
2540 	wlan_vdev_mlme_sm_deliver_evt(iface->vdev,
2541 				      WLAN_VDEV_SM_EV_DOWN_COMPLETE,
2542 				      sizeof(*resp), resp);
2543 	return status;
2544 }
2545 
2546 /**
2547  * wma_send_vdev_down_req() - handle vdev down req
2548  * @wma: wma handle
2549  * @resp: pointer to vde del bss response
2550  *
2551  * Return: none
2552  */
2553 
2554 static void wma_send_vdev_down_req(tp_wma_handle wma,
2555 				   struct del_bss_resp *resp)
2556 {
2557 	struct wma_txrx_node *iface = &wma->interfaces[resp->vdev_id];
2558 	enum QDF_OPMODE mode;
2559 
2560 	mode = wlan_vdev_mlme_get_opmode(iface->vdev);
2561 	if (mode == QDF_STA_MODE || mode == QDF_P2P_CLIENT_MODE) {
2562 		/* initiate MLME Down req from CM for STA/CLI */
2563 		wlan_cm_bss_peer_delete_rsp(iface->vdev, resp->status);
2564 		qdf_mem_free(resp);
2565 		return;
2566 	}
2567 
2568 	wlan_vdev_mlme_sm_deliver_evt(iface->vdev,
2569 				      WLAN_VDEV_SM_EV_MLME_DOWN_REQ,
2570 				      sizeof(*resp), resp);
2571 }
2572 
2573 #ifdef WLAN_FEATURE_11BE_MLO
2574 void wma_delete_peer_mlo(struct wlan_objmgr_psoc *psoc, uint8_t *macaddr)
2575 {
2576 	struct wlan_objmgr_peer *peer = NULL;
2577 
2578 	peer = wlan_objmgr_get_peer_by_mac(psoc, macaddr, WLAN_LEGACY_WMA_ID);
2579 	if (peer) {
2580 		wlan_mlo_link_peer_delete(peer);
2581 		wlan_objmgr_peer_release_ref(peer, WLAN_LEGACY_WMA_ID);
2582 	}
2583 }
2584 #endif /* WLAN_FEATURE_11BE_MLO */
2585 
2586 static QDF_STATUS
2587 wma_delete_peer_on_vdev_stop(tp_wma_handle wma, uint8_t vdev_id)
2588 {
2589 	uint32_t vdev_stop_type;
2590 	struct del_bss_resp *vdev_stop_resp;
2591 	struct wma_txrx_node *iface;
2592 	QDF_STATUS status;
2593 	struct qdf_mac_addr bssid;
2594 
2595 	iface = &wma->interfaces[vdev_id];
2596 	status = wlan_vdev_get_bss_peer_mac(iface->vdev, &bssid);
2597 	if (QDF_IS_STATUS_ERROR(status)) {
2598 		wma_err("Failed to get bssid");
2599 		return QDF_STATUS_E_INVAL;
2600 	}
2601 
2602 	status = mlme_get_vdev_stop_type(iface->vdev, &vdev_stop_type);
2603 	if (QDF_IS_STATUS_ERROR(status)) {
2604 		wma_err("Failed to get wma req msg type for vdev id %d",
2605 			vdev_id);
2606 		return QDF_STATUS_E_INVAL;
2607 	}
2608 
2609 	wma_delete_peer_mlo(wma->psoc, bssid.bytes);
2610 
2611 	vdev_stop_resp = qdf_mem_malloc(sizeof(*vdev_stop_resp));
2612 	if (!vdev_stop_resp)
2613 		return QDF_STATUS_E_NOMEM;
2614 
2615 	if (vdev_stop_type == WMA_DELETE_BSS_HO_FAIL_REQ) {
2616 		status = wma_remove_peer(wma, bssid.bytes,
2617 					 vdev_id, true);
2618 		if (QDF_IS_STATUS_ERROR(status))
2619 			goto free_params;
2620 
2621 		vdev_stop_resp->status = status;
2622 		vdev_stop_resp->vdev_id = vdev_id;
2623 		wma_send_vdev_down_req(wma, vdev_stop_resp);
2624 	} else if (vdev_stop_type == WMA_DELETE_BSS_REQ ||
2625 	    vdev_stop_type == WMA_SET_LINK_STATE) {
2626 		uint8_t type;
2627 
2628 		/* CCA is required only for sta interface */
2629 		if (iface->type == WMI_VDEV_TYPE_STA)
2630 			wma_get_cca_stats(wma, vdev_id);
2631 		if (vdev_stop_type == WMA_DELETE_BSS_REQ)
2632 			type = WMA_DELETE_PEER_RSP;
2633 		else
2634 			type = WMA_SET_LINK_PEER_RSP;
2635 
2636 		vdev_stop_resp->vdev_id = vdev_id;
2637 		vdev_stop_resp->status = status;
2638 		status = wma_remove_bss_peer(wma, vdev_id,
2639 					     vdev_stop_resp, type);
2640 		if (status) {
2641 			wma_err("Del bss failed vdev:%d", vdev_id);
2642 			wma_send_vdev_down_req(wma, vdev_stop_resp);
2643 			return status;
2644 		}
2645 
2646 		if (wmi_service_enabled(wma->wmi_handle,
2647 					wmi_service_sync_delete_cmds))
2648 			return status;
2649 
2650 		wma_send_vdev_down_req(wma, vdev_stop_resp);
2651 	}
2652 
2653 	return status;
2654 
2655 free_params:
2656 	qdf_mem_free(vdev_stop_resp);
2657 	return status;
2658 }
2659 
2660 QDF_STATUS
2661 cm_send_bss_peer_delete_req(struct wlan_objmgr_vdev *vdev)
2662 {
2663 	tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA);
2664 	uint8_t vdev_id = wlan_vdev_get_id(vdev);
2665 
2666 	if (!wma)
2667 		return QDF_STATUS_E_INVAL;
2668 
2669 	if (wlan_vdev_mlme_is_init_state(vdev) == QDF_STATUS_SUCCESS) {
2670 		wma_remove_bss_peer_on_failure(wma, vdev_id);
2671 		return QDF_STATUS_SUCCESS;
2672 	}
2673 
2674 	return wma_delete_peer_on_vdev_stop(wma, vdev_id);
2675 }
2676 
2677 QDF_STATUS
2678 __wma_handle_vdev_stop_rsp(struct vdev_stop_response *resp_event)
2679 {
2680 	tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA);
2681 	struct wma_txrx_node *iface;
2682 	QDF_STATUS status;
2683 	struct qdf_mac_addr bssid;
2684 	enum QDF_OPMODE mode;
2685 
2686 	if (!wma)
2687 		return QDF_STATUS_E_INVAL;
2688 
2689 	/* Ignore stop_response in Monitor mode */
2690 	if (cds_get_conparam() == QDF_GLOBAL_MONITOR_MODE)
2691 		return  QDF_STATUS_SUCCESS;
2692 
2693 	iface = &wma->interfaces[resp_event->vdev_id];
2694 
2695 	/* vdev in stopped state, no more waiting for key */
2696 	iface->is_waiting_for_key = false;
2697 
2698 	/*
2699 	 * Reset the rmfEnabled as there might be MGMT action frames
2700 	 * sent on this vdev before the next session is established.
2701 	 */
2702 	if (iface->rmfEnabled) {
2703 		iface->rmfEnabled = 0;
2704 		wma_debug("Reset rmfEnabled for vdev %d",
2705 			 resp_event->vdev_id);
2706 	}
2707 
2708 	mode = wlan_vdev_mlme_get_opmode(iface->vdev);
2709 	if (mode == QDF_STA_MODE || mode == QDF_P2P_CLIENT_MODE) {
2710 		status = wlan_vdev_get_bss_peer_mac(iface->vdev, &bssid);
2711 		if (QDF_IS_STATUS_ERROR(status)) {
2712 			wma_debug("Failed to get bssid, peer might have got deleted already");
2713 			return wlan_cm_bss_peer_delete_rsp(iface->vdev, status);
2714 		}
2715 		/* initiate CM to delete bss peer */
2716 		return wlan_cm_bss_peer_delete_ind(iface->vdev,  &bssid);
2717 	} else if (mode == QDF_SAP_MODE) {
2718 		wlan_son_deliver_vdev_stop(iface->vdev);
2719 	}
2720 
2721 	return wma_delete_peer_on_vdev_stop(wma, resp_event->vdev_id);
2722 }
2723 
2724 /**
2725  * wma_handle_vdev_stop_rsp() - handle vdev stop resp
2726  * @wma: wma handle
2727  * @resp_event: fw resp
2728  *
2729  * Return: QDF_STATUS
2730  */
2731 static QDF_STATUS
2732 wma_handle_vdev_stop_rsp(tp_wma_handle wma,
2733 			 struct vdev_stop_response *resp_event)
2734 {
2735 	struct wma_txrx_node *iface;
2736 
2737 	iface = &wma->interfaces[resp_event->vdev_id];
2738 	return wlan_vdev_mlme_sm_deliver_evt(iface->vdev,
2739 					     WLAN_VDEV_SM_EV_STOP_RESP,
2740 					     sizeof(*resp_event), resp_event);
2741 }
2742 
2743 QDF_STATUS wma_vdev_stop_resp_handler(struct vdev_mlme_obj *vdev_mlme,
2744 				      struct vdev_stop_response *rsp)
2745 {
2746 	tp_wma_handle wma;
2747 	struct wma_txrx_node *iface = NULL;
2748 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
2749 
2750 	wma = cds_get_context(QDF_MODULE_ID_WMA);
2751 	if (!wma)
2752 		return status;
2753 
2754 	iface = &wma->interfaces[vdev_mlme->vdev->vdev_objmgr.vdev_id];
2755 
2756 	if (rsp->vdev_id >= wma->max_bssid) {
2757 		wma_err("Invalid vdev_id %d from FW", rsp->vdev_id);
2758 		return QDF_STATUS_E_INVAL;
2759 	}
2760 
2761 	status = wma_handle_vdev_stop_rsp(wma, rsp);
2762 
2763 	return status;
2764 }
2765 
2766 void wma_cleanup_vdev(struct wlan_objmgr_vdev *vdev)
2767 {
2768 	tp_wma_handle wma_handle;
2769 	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
2770 	uint8_t vdev_id = wlan_vdev_get_id(vdev);
2771 	struct vdev_mlme_obj *vdev_mlme;
2772 
2773 	if (!soc)
2774 		return;
2775 
2776 	wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
2777 	if (!wma_handle)
2778 		return;
2779 
2780 	if (!wma_handle->interfaces[vdev_id].vdev) {
2781 		wma_err("vdev is NULL");
2782 		return;
2783 	}
2784 
2785 	vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev);
2786 	if (!vdev_mlme) {
2787 		wma_err("Failed to get vdev mlme obj for vdev id %d", vdev_id);
2788 		return;
2789 	}
2790 
2791 	wma_cdp_vdev_detach(soc, wma_handle, vdev_id);
2792 	wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_WMA_ID);
2793 	wma_handle->interfaces[vdev_id].vdev = NULL;
2794 	wma_handle->interfaces[vdev_id].vdev_active = false;
2795 }
2796 
2797 QDF_STATUS wma_vdev_self_peer_create(struct vdev_mlme_obj *vdev_mlme)
2798 {
2799 	struct wlan_objmgr_peer *obj_peer;
2800 	QDF_STATUS status = QDF_STATUS_SUCCESS;
2801 	struct wlan_objmgr_vdev *vdev = vdev_mlme->vdev;
2802 	tp_wma_handle wma_handle;
2803 	uint8_t peer_vdev_id, *self_peer_macaddr;
2804 
2805 	wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
2806 	if (!wma_handle)
2807 		return QDF_STATUS_E_FAILURE;
2808 
2809 	if (mlme_vdev_uses_self_peer(vdev_mlme->mgmt.generic.type,
2810 				     vdev_mlme->mgmt.generic.subtype)) {
2811 		status = wma_create_peer(wma_handle,
2812 					 vdev->vdev_mlme.macaddr,
2813 					 WMI_PEER_TYPE_DEFAULT,
2814 					 wlan_vdev_get_id(vdev),
2815 					 NULL, false);
2816 		if (QDF_IS_STATUS_ERROR(status))
2817 			wma_err("Failed to create peer %d", status);
2818 	} else if (vdev_mlme->mgmt.generic.type == WMI_VDEV_TYPE_STA ||
2819 		   vdev_mlme->mgmt.generic.type == WMI_VDEV_TYPE_NAN) {
2820 		if (!qdf_is_macaddr_zero(
2821 				(struct qdf_mac_addr *)vdev->vdev_mlme.mldaddr))
2822 			self_peer_macaddr = vdev->vdev_mlme.mldaddr;
2823 		else
2824 			self_peer_macaddr = vdev->vdev_mlme.macaddr;
2825 
2826 		/**
2827 		 * Self peer is used for the frames exchanged before
2828 		 * association. For ML STA, Self peer create will be triggered
2829 		 * for both the VDEVs, but one self peer is enough. So in case
2830 		 * of ML, use MLD address for the self peer and ignore self peer
2831 		 * creation for the partner link vdev.
2832 		 */
2833 		if (wma_objmgr_peer_exist(wma_handle, self_peer_macaddr,
2834 					  &peer_vdev_id))
2835 			return QDF_STATUS_SUCCESS;
2836 
2837 		obj_peer = wma_create_objmgr_peer(wma_handle,
2838 						  wlan_vdev_get_id(vdev),
2839 						  self_peer_macaddr,
2840 						  WMI_PEER_TYPE_DEFAULT,
2841 						  vdev->vdev_mlme.macaddr);
2842 		if (!obj_peer) {
2843 			wma_err("Failed to create obj mgr peer for self");
2844 			status = QDF_STATUS_E_INVAL;
2845 		}
2846 	}
2847 
2848 	return status;
2849 }
2850 
2851 #ifdef MULTI_CLIENT_LL_SUPPORT
2852 #define MAX_VDEV_LATENCY_PARAMS 10
2853 /* params being sent:
2854  * 1.wmi_vdev_param_set_multi_client_ll_feature_config
2855  * 2.wmi_vdev_param_set_normal_latency_flags_config
2856  * 3.wmi_vdev_param_set_xr_latency_flags_config
2857  * 4.wmi_vdev_param_set_low_latency_flags_config
2858  * 5.wmi_vdev_param_set_ultra_low_latency_flags_config
2859  * 6.wmi_vdev_param_set_normal_latency_ul_dl_config
2860  * 7.wmi_vdev_param_set_xr_latency_ul_dl_config
2861  * 8.wmi_vdev_param_set_low_latency_ul_dl_config
2862  * 9.wmi_vdev_param_set_ultra_low_latency_ul_dl_config
2863  * 10.wmi_vdev_param_set_default_ll_config
2864  */
2865 
2866 /**
2867  * wma_set_vdev_latency_level_param() - Set per vdev latency level params in FW
2868  * @wma_handle: wma handle
2869  * @mac: mac context
2870  * @vdev_id: vdev id
2871  *
2872  * Return: QDF_STATUS
2873  */
2874 static QDF_STATUS wma_set_vdev_latency_level_param(tp_wma_handle wma_handle,
2875 						   struct mac_context *mac,
2876 						   uint8_t vdev_id)
2877 {
2878 	QDF_STATUS status = QDF_STATUS_SUCCESS;
2879 	bool multi_client_ll_ini_support, multi_client_ll_caps;
2880 	uint32_t latency_flags;
2881 	static uint32_t ll[4] = {100, 60, 40, 20};
2882 	uint32_t ul_latency, dl_latency, ul_dl_latency;
2883 	uint8_t default_latency_level;
2884 	struct dev_set_param setparam[MAX_VDEV_LATENCY_PARAMS];
2885 	uint8_t index = 0;
2886 
2887 	multi_client_ll_ini_support =
2888 			mac->mlme_cfg->wlm_config.multi_client_ll_support;
2889 	multi_client_ll_caps =
2890 			wlan_mlme_get_wlm_multi_client_ll_caps(mac->psoc);
2891 	wma_debug("INI support: %d, fw capability:%d",
2892 		  multi_client_ll_ini_support, multi_client_ll_caps);
2893 	/*
2894 	 * Multi-Client arbiter functionality is enabled only if both INI is
2895 	 * set, and Service bit is configured.
2896 	 */
2897 	if (!(multi_client_ll_ini_support && multi_client_ll_caps))
2898 		return status;
2899 	status = mlme_check_index_setparam(
2900 			setparam,
2901 			wmi_vdev_param_set_multi_client_ll_feature_config,
2902 			multi_client_ll_ini_support, index++,
2903 			MAX_VDEV_LATENCY_PARAMS);
2904 	if (QDF_IS_STATUS_ERROR(status)) {
2905 		wma_err("failed to configure low latency feature");
2906 		return status;
2907 	}
2908 
2909 	/* wlm latency level index:0 - normal, 1 - xr, 2 - low, 3 - ultralow */
2910 	wma_debug("Setting vdev params for latency level flags");
2911 
2912 	latency_flags = mac->mlme_cfg->wlm_config.latency_flags[0];
2913 	status = mlme_check_index_setparam(
2914 				setparam,
2915 				wmi_vdev_param_set_normal_latency_flags_config,
2916 				latency_flags, index++,
2917 				MAX_VDEV_LATENCY_PARAMS);
2918 	if (QDF_IS_STATUS_ERROR(status)) {
2919 		wma_err("failed to configure normal latency feature");
2920 		return status;
2921 	}
2922 
2923 	latency_flags = mac->mlme_cfg->wlm_config.latency_flags[1];
2924 	status = mlme_check_index_setparam(
2925 				setparam,
2926 				wmi_vdev_param_set_xr_latency_flags_config,
2927 				latency_flags, index++,
2928 				MAX_VDEV_LATENCY_PARAMS);
2929 	if (QDF_IS_STATUS_ERROR(status)) {
2930 		wma_err("failed to configure xr latency feature");
2931 		return status;
2932 	}
2933 
2934 	latency_flags = mac->mlme_cfg->wlm_config.latency_flags[2];
2935 	status = mlme_check_index_setparam(
2936 				setparam,
2937 				wmi_vdev_param_set_low_latency_flags_config,
2938 				latency_flags, index++,
2939 				MAX_VDEV_LATENCY_PARAMS);
2940 	if (QDF_IS_STATUS_ERROR(status)) {
2941 		wma_err("failed to configure low latency feature");
2942 		return status;
2943 	}
2944 
2945 	latency_flags = mac->mlme_cfg->wlm_config.latency_flags[3];
2946 	status = mlme_check_index_setparam(
2947 			setparam,
2948 			wmi_vdev_param_set_ultra_low_latency_flags_config,
2949 			latency_flags, index++, MAX_VDEV_LATENCY_PARAMS);
2950 	if (QDF_IS_STATUS_ERROR(status)) {
2951 		wma_err("failed to configure ultra low latency feature");
2952 		return status;
2953 	}
2954 
2955 	wma_debug("Setting vdev params for Latency level UL/DL flags");
2956 	/*
2957 	 * Latency level UL/DL
2958 	 * 0-15 bits: UL and 16-31 bits: DL
2959 	 */
2960 	dl_latency = ll[0];
2961 	ul_latency = ll[0];
2962 	ul_dl_latency = dl_latency << 16 | ul_latency;
2963 	status = mlme_check_index_setparam(
2964 				setparam,
2965 				wmi_vdev_param_set_normal_latency_ul_dl_config,
2966 				ul_dl_latency, index++,
2967 				MAX_VDEV_LATENCY_PARAMS);
2968 	if (QDF_IS_STATUS_ERROR(status)) {
2969 		wma_err("failed to configure normal latency ul dl flag");
2970 		return status;
2971 	}
2972 
2973 	dl_latency = ll[1];
2974 	ul_latency = ll[1];
2975 	ul_dl_latency = dl_latency << 16 | ul_latency;
2976 	status = mlme_check_index_setparam(
2977 				setparam,
2978 				wmi_vdev_param_set_xr_latency_ul_dl_config,
2979 				ul_dl_latency, index++,
2980 				MAX_VDEV_LATENCY_PARAMS);
2981 	if (QDF_IS_STATUS_ERROR(status)) {
2982 		wma_err("failed to configure normal latency ul dl flag");
2983 		return status;
2984 	}
2985 
2986 	dl_latency = ll[2];
2987 	ul_latency = ll[2];
2988 	ul_dl_latency = dl_latency << 16 | ul_latency;
2989 	status = mlme_check_index_setparam(
2990 				setparam,
2991 				wmi_vdev_param_set_low_latency_ul_dl_config,
2992 				ul_dl_latency, index++,
2993 				MAX_VDEV_LATENCY_PARAMS);
2994 	if (QDF_IS_STATUS_ERROR(status)) {
2995 		wma_err("failed to configure normal latency ul dl flag");
2996 		return status;
2997 	}
2998 
2999 	dl_latency = ll[3];
3000 	ul_latency = ll[3];
3001 	ul_dl_latency = dl_latency << 16 | ul_latency;
3002 	status = mlme_check_index_setparam(
3003 			setparam,
3004 			wmi_vdev_param_set_ultra_low_latency_ul_dl_config,
3005 			ul_dl_latency, index++,
3006 			MAX_VDEV_LATENCY_PARAMS);
3007 	if (QDF_IS_STATUS_ERROR(status)) {
3008 		wma_err("failed to configure normal latency ul dl flag");
3009 		return status;
3010 	}
3011 
3012 	default_latency_level = mac->mlme_cfg->wlm_config.latency_level;
3013 	status = mlme_check_index_setparam(
3014 				      setparam,
3015 				      wmi_vdev_param_set_default_ll_config,
3016 				      default_latency_level, index++,
3017 				      MAX_VDEV_LATENCY_PARAMS);
3018 	if (QDF_IS_STATUS_ERROR(status)) {
3019 		wma_err("failed to configure low latency feature");
3020 		return status;
3021 	}
3022 
3023 	status = wma_send_multi_pdev_vdev_set_params(MLME_VDEV_SETPARAM,
3024 						     vdev_id, setparam, index);
3025 	if (QDF_IS_STATUS_ERROR(status))
3026 		wma_err("Failed to configure vdev latency level params");
3027 	return status;
3028 }
3029 #else
3030 static QDF_STATUS wma_set_vdev_latency_level_param(tp_wma_handle wma_handle,
3031 						   struct mac_context *mac,
3032 						   uint8_t vdev_id)
3033 {
3034 	return QDF_STATUS_E_FAILURE;
3035 }
3036 #endif
3037 
3038 QDF_STATUS wma_post_vdev_create_setup(struct wlan_objmgr_vdev *vdev)
3039 {
3040 	QDF_STATUS status = QDF_STATUS_SUCCESS;
3041 	struct mac_context *mac = cds_get_context(QDF_MODULE_ID_PE);
3042 	bool mcc_adapt_sch = false;
3043 	QDF_STATUS ret;
3044 	uint8_t vdev_id;
3045 	struct wlan_mlme_qos *qos_aggr;
3046 	struct vdev_mlme_obj *vdev_mlme;
3047 	tp_wma_handle wma_handle;
3048 	uint8_t enable_sifs_burst = 0;
3049 
3050 	if (!mac)
3051 		return QDF_STATUS_E_FAILURE;
3052 
3053 	wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
3054 	if (!wma_handle)
3055 		return QDF_STATUS_E_FAILURE;
3056 
3057 	if (wlan_objmgr_vdev_try_get_ref(vdev, WLAN_LEGACY_WMA_ID) !=
3058 		QDF_STATUS_SUCCESS)
3059 		return QDF_STATUS_E_FAILURE;
3060 
3061 	vdev_id = wlan_vdev_get_id(vdev);
3062 	wma_handle->interfaces[vdev_id].vdev = vdev;
3063 	wma_handle->interfaces[vdev_id].vdev_active = true;
3064 
3065 	vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev);
3066 	if (!vdev_mlme) {
3067 		wma_err("Failed to get vdev mlme obj!");
3068 		goto end;
3069 	}
3070 
3071 	wma_vdev_update_pause_bitmap(vdev_id, 0);
3072 
3073 	wma_handle->interfaces[vdev_id].type =
3074 		vdev_mlme->mgmt.generic.type;
3075 	wma_handle->interfaces[vdev_id].sub_type =
3076 		vdev_mlme->mgmt.generic.subtype;
3077 
3078 	qos_aggr = &mac->mlme_cfg->qos_mlme_params;
3079 	if (vdev_mlme->mgmt.generic.type == WMI_VDEV_TYPE_STA) {
3080 		wma_set_sta_keep_alive(
3081 				wma_handle, vdev_id,
3082 				SIR_KEEP_ALIVE_NULL_PKT,
3083 				mac->mlme_cfg->sta.sta_keep_alive_period,
3084 				NULL, NULL, NULL);
3085 
3086 		/* offload STA SA query related params to fwr */
3087 		if (wmi_service_enabled(wma_handle->wmi_handle,
3088 					wmi_service_sta_pmf_offload)) {
3089 			wma_set_sta_sa_query_param(wma_handle, vdev_id);
3090 		}
3091 
3092 		status = wma_set_sw_retry_threshold(qos_aggr);
3093 		if (QDF_IS_STATUS_ERROR(status))
3094 			wma_err("failed to set sw retry threshold (status = %d)",
3095 				status);
3096 
3097 		status = wma_set_sw_retry_threshold_per_ac(wma_handle, vdev_id,
3098 							   qos_aggr);
3099 		if (QDF_IS_STATUS_ERROR(status))
3100 			wma_err("failed to set sw retry threshold per ac(status = %d)",
3101 				 status);
3102 	}
3103 
3104 	status = wma_vdev_create_set_param(vdev);
3105 	if (QDF_IS_STATUS_ERROR(status)) {
3106 		wma_err("Failed to setup Vdev create set param for vdev: %d",
3107 			vdev_id);
3108 		return status;
3109 	}
3110 
3111 	if (policy_mgr_get_dynamic_mcc_adaptive_sch(mac->psoc,
3112 						    &mcc_adapt_sch) ==
3113 	    QDF_STATUS_SUCCESS) {
3114 		wma_debug("setting ini value for WNI_CFG_ENABLE_MCC_ADAPTIVE_SCHED: %d",
3115 			 mcc_adapt_sch);
3116 		ret =
3117 		wma_set_enable_disable_mcc_adaptive_scheduler(mcc_adapt_sch);
3118 		if (QDF_IS_STATUS_ERROR(ret)) {
3119 			wma_err("Failed to set WNI_CFG_ENABLE_MCC_ADAPTIVE_SCHED");
3120 		}
3121 	} else {
3122 		wma_err("Failed to get value for WNI_CFG_ENABLE_MCC_ADAPTIVE_SCHED, leaving unchanged");
3123 	}
3124 
3125 	if (vdev_mlme->mgmt.generic.type == WMI_VDEV_TYPE_STA &&
3126 	    ucfg_pmo_is_apf_enabled(wma_handle->psoc)) {
3127 		ret = wma_config_active_apf_mode(wma_handle,
3128 						 vdev_id);
3129 		if (QDF_IS_STATUS_ERROR(ret))
3130 			wma_err("Failed to configure active APF mode");
3131 	}
3132 
3133 	if (vdev_mlme->mgmt.generic.type == WMI_VDEV_TYPE_STA &&
3134 	    vdev_mlme->mgmt.generic.subtype == 0)
3135 		wma_set_vdev_latency_level_param(wma_handle, mac, vdev_id);
3136 
3137 	switch (vdev_mlme->mgmt.generic.type) {
3138 	case WMI_VDEV_TYPE_AP:
3139 		if (vdev_mlme->mgmt.generic.subtype !=
3140 		    WLAN_VDEV_MLME_SUBTYPE_P2P_DEVICE)
3141 			break;
3142 
3143 		fallthrough;
3144 	case WMI_VDEV_TYPE_STA:
3145 	case WMI_VDEV_TYPE_NAN:
3146 	case WMI_VDEV_TYPE_OCB:
3147 	case WMI_VDEV_TYPE_MONITOR:
3148 		status = ucfg_get_enable_sifs_burst(wma_handle->psoc,
3149 						    &enable_sifs_burst);
3150 		if (QDF_IS_STATUS_ERROR(status))
3151 			wma_err("Failed to get sifs burst value, use default");
3152 
3153 		status = wma_vdev_set_param(wma_handle->wmi_handle, vdev_id,
3154 					    WMI_PDEV_PARAM_BURST_ENABLE,
3155 					    enable_sifs_burst);
3156 
3157 		if (QDF_IS_STATUS_ERROR(status))
3158 			wma_err("WMI_PDEV_PARAM_BURST_ENABLE set failed %d",
3159 				status);
3160 		break;
3161 	default:
3162 		break;
3163 	}
3164 
3165 	wma_vdev_set_data_tx_callback(vdev);
3166 
3167 	return QDF_STATUS_SUCCESS;
3168 
3169 end:
3170 	wma_cleanup_vdev(vdev);
3171 	return QDF_STATUS_E_FAILURE;
3172 }
3173 
3174 QDF_STATUS wma_vdev_set_data_tx_callback(struct wlan_objmgr_vdev *vdev)
3175 {
3176 	u_int8_t vdev_id;
3177 	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
3178 	tp_wma_handle wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
3179 
3180 	if (!vdev || !wma_handle || !soc) {
3181 		wma_err("null vdev, wma_handle or soc");
3182 		return QDF_STATUS_E_FAILURE;
3183 	}
3184 
3185 	vdev_id = wlan_vdev_get_id(vdev);
3186 	cdp_data_tx_cb_set(soc, vdev_id,
3187 			   wma_data_tx_ack_comp_hdlr,
3188 			   wma_handle);
3189 
3190 	return QDF_STATUS_SUCCESS;
3191 }
3192 
3193 enum mlme_bcn_tx_rate_code wma_get_bcn_rate_code(uint16_t rate)
3194 {
3195 	/* rate in multiples of 100 Kbps */
3196 	switch (rate) {
3197 	case WMA_BEACON_TX_RATE_1_M:
3198 		return MLME_BCN_TX_RATE_CODE_1_M;
3199 	case WMA_BEACON_TX_RATE_2_M:
3200 		return MLME_BCN_TX_RATE_CODE_2_M;
3201 	case WMA_BEACON_TX_RATE_5_5_M:
3202 		return MLME_BCN_TX_RATE_CODE_5_5_M;
3203 	case WMA_BEACON_TX_RATE_11_M:
3204 		return MLME_BCN_TX_RATE_CODE_11M;
3205 	case WMA_BEACON_TX_RATE_6_M:
3206 		return MLME_BCN_TX_RATE_CODE_6_M;
3207 	case WMA_BEACON_TX_RATE_9_M:
3208 		return MLME_BCN_TX_RATE_CODE_9_M;
3209 	case WMA_BEACON_TX_RATE_12_M:
3210 		return MLME_BCN_TX_RATE_CODE_12_M;
3211 	case WMA_BEACON_TX_RATE_18_M:
3212 		return MLME_BCN_TX_RATE_CODE_18_M;
3213 	case WMA_BEACON_TX_RATE_24_M:
3214 		return MLME_BCN_TX_RATE_CODE_24_M;
3215 	case WMA_BEACON_TX_RATE_36_M:
3216 		return MLME_BCN_TX_RATE_CODE_36_M;
3217 	case WMA_BEACON_TX_RATE_48_M:
3218 		return MLME_BCN_TX_RATE_CODE_48_M;
3219 	case WMA_BEACON_TX_RATE_54_M:
3220 		return MLME_BCN_TX_RATE_CODE_54_M;
3221 	default:
3222 		return MLME_BCN_TX_RATE_CODE_1_M;
3223 	}
3224 }
3225 
3226 QDF_STATUS wma_vdev_pre_start(uint8_t vdev_id, bool restart)
3227 {
3228 	tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA);
3229 	struct wma_txrx_node *intr;
3230 	struct mac_context *mac_ctx =  cds_get_context(QDF_MODULE_ID_PE);
3231 	struct wlan_mlme_nss_chains *ini_cfg;
3232 	struct vdev_mlme_obj *mlme_obj;
3233 	struct wlan_objmgr_vdev *vdev;
3234 	struct wlan_channel *des_chan;
3235 	QDF_STATUS status;
3236 	enum coex_btc_chain_mode btc_chain_mode;
3237 	struct wlan_mlme_qos *qos_aggr;
3238 	uint8_t amsdu_val;
3239 
3240 	if (!wma || !mac_ctx)
3241 		return QDF_STATUS_E_FAILURE;
3242 
3243 	intr = wma->interfaces;
3244 	if (!intr) {
3245 		wma_err("Invalid interface");
3246 		return QDF_STATUS_E_FAILURE;
3247 	}
3248 	if (vdev_id >= WLAN_MAX_VDEVS) {
3249 		wma_err("Invalid vdev id");
3250 		return QDF_STATUS_E_INVAL;
3251 	}
3252 	vdev = intr[vdev_id].vdev;
3253 	if (!vdev) {
3254 		wma_err("Invalid vdev");
3255 		return QDF_STATUS_E_FAILURE;
3256 	}
3257 
3258 	mlme_obj = wlan_vdev_mlme_get_cmpt_obj(vdev);
3259 	if (!mlme_obj) {
3260 		wma_err("vdev component object is NULL");
3261 		return QDF_STATUS_E_FAILURE;
3262 	}
3263 	des_chan = vdev->vdev_mlme.des_chan;
3264 
3265 	ini_cfg = mlme_get_ini_vdev_config(vdev);
3266 	if (!ini_cfg) {
3267 		wma_err("nss chain ini config NULL");
3268 		return QDF_STATUS_E_FAILURE;
3269 	}
3270 
3271 	intr[vdev_id].config.gtx_info.gtxRTMask[0] =
3272 		CFG_TGT_DEFAULT_GTX_HT_MASK;
3273 	intr[vdev_id].config.gtx_info.gtxRTMask[1] =
3274 		CFG_TGT_DEFAULT_GTX_VHT_MASK;
3275 
3276 	intr[vdev_id].config.gtx_info.gtxUsrcfg =
3277 		mac_ctx->mlme_cfg->sta.tgt_gtx_usr_cfg;
3278 
3279 	intr[vdev_id].config.gtx_info.gtxPERThreshold =
3280 		CFG_TGT_DEFAULT_GTX_PER_THRESHOLD;
3281 	intr[vdev_id].config.gtx_info.gtxPERMargin =
3282 		CFG_TGT_DEFAULT_GTX_PER_MARGIN;
3283 	intr[vdev_id].config.gtx_info.gtxTPCstep =
3284 		CFG_TGT_DEFAULT_GTX_TPC_STEP;
3285 	intr[vdev_id].config.gtx_info.gtxTPCMin =
3286 		CFG_TGT_DEFAULT_GTX_TPC_MIN;
3287 	intr[vdev_id].config.gtx_info.gtxBWMask =
3288 		CFG_TGT_DEFAULT_GTX_BW_MASK;
3289 	intr[vdev_id].chan_width = des_chan->ch_width;
3290 	intr[vdev_id].ch_freq = des_chan->ch_freq;
3291 	intr[vdev_id].ch_flagext = des_chan->ch_flagext;
3292 
3293 	/*
3294 	 * If the channel has DFS set, flip on radar reporting.
3295 	 *
3296 	 * It may be that this should only be done for hostap operation
3297 	 * as this flag may be interpreted (at some point in the future)
3298 	 * by the firmware as "oh, and please do radar DETECTION."
3299 	 *
3300 	 * If that is ever the case we would insert the decision whether to
3301 	 * enable the firmware flag here.
3302 	 */
3303 	if (QDF_GLOBAL_MONITOR_MODE != cds_get_conparam() &&
3304 	    utils_is_dfs_chan_for_freq(wma->pdev, des_chan->ch_freq))
3305 		mlme_obj->mgmt.generic.disable_hw_ack = true;
3306 
3307 	if (mlme_obj->mgmt.rate_info.bcn_tx_rate) {
3308 		wma_debug("beacon tx rate [%u * 100 Kbps]",
3309 			  mlme_obj->mgmt.rate_info.bcn_tx_rate);
3310 		/*
3311 		 * beacon_tx_rate is in multiples of 100 Kbps.
3312 		 * Convert the data rate to hw rate code.
3313 		 */
3314 		mlme_obj->mgmt.rate_info.bcn_tx_rate =
3315 		wma_get_bcn_rate_code(mlme_obj->mgmt.rate_info.bcn_tx_rate);
3316 	}
3317 
3318 	if (!restart) {
3319 		wma_debug("vdev_id: %d, unpausing tx_ll_queue at VDEV_START",
3320 			 vdev_id);
3321 
3322 		cdp_fc_vdev_unpause(cds_get_context(QDF_MODULE_ID_SOC),
3323 				    vdev_id, 0xffffffff, 0);
3324 		wma_vdev_update_pause_bitmap(vdev_id, 0);
3325 	}
3326 
3327 	/* Send the dynamic nss chain params before vdev start to fw */
3328 	if (wma->dynamic_nss_chains_support && !restart)
3329 		wma_vdev_nss_chain_params_send(vdev_id, ini_cfg);
3330 
3331 	status = ucfg_coex_psoc_get_btc_chain_mode(wma->psoc, &btc_chain_mode);
3332 	if (QDF_IS_STATUS_ERROR(status)) {
3333 		wma_err("Failed to get btc chain mode");
3334 		return QDF_STATUS_E_FAILURE;
3335 	}
3336 
3337 	if (btc_chain_mode != WLAN_COEX_BTC_CHAIN_MODE_UNSETTLED) {
3338 		status = ucfg_coex_send_btc_chain_mode(vdev, btc_chain_mode);
3339 		if (QDF_IS_STATUS_ERROR(status)) {
3340 			wma_err("Failed to send btc chain mode %d",
3341 				btc_chain_mode);
3342 			return QDF_STATUS_E_FAILURE;
3343 		}
3344 	}
3345 
3346 	qos_aggr = &mac_ctx->mlme_cfg->qos_mlme_params;
3347 	status = wma_set_tx_rx_aggr_size(vdev_id, qos_aggr->tx_aggregation_size,
3348 					 qos_aggr->rx_aggregation_size,
3349 					 WMI_VDEV_CUSTOM_AGGR_TYPE_AMPDU);
3350 	if (QDF_IS_STATUS_ERROR(status))
3351 		wma_err("failed to set aggregation sizes(status = %d)", status);
3352 
3353 	status = wlan_mlme_get_max_amsdu_num(wma->psoc, &amsdu_val);
3354 	if (QDF_IS_STATUS_ERROR(status)) {
3355 		wma_err("failed to get amsdu aggr.size(status = %d)", status);
3356 	} else {
3357 		status = wma_set_tx_rx_aggr_size(vdev_id, amsdu_val, amsdu_val,
3358 					WMI_VDEV_CUSTOM_AGGR_TYPE_AMSDU);
3359 		if (QDF_IS_STATUS_ERROR(status))
3360 			wma_err("failed to set amsdu aggr.size(status = %d)",
3361 				status);
3362 	}
3363 
3364 	if (mlme_obj->mgmt.generic.type == WMI_VDEV_TYPE_STA) {
3365 		status = wma_set_tx_rx_aggr_size_per_ac(wma, vdev_id, qos_aggr,
3366 					WMI_VDEV_CUSTOM_AGGR_TYPE_AMPDU);
3367 
3368 		if (QDF_IS_STATUS_ERROR(status))
3369 			wma_err("failed to set aggr size per ac(status = %d)",
3370 				status);
3371 	}
3372 
3373 	return QDF_STATUS_SUCCESS;
3374 }
3375 
3376 /**
3377  * wma_peer_assoc_conf_handler() - peer assoc conf handler
3378  * @handle: wma handle
3379  * @cmd_param_info: event buffer
3380  * @len: buffer length
3381  *
3382  * Return: 0 for success or error code
3383  */
3384 int wma_peer_assoc_conf_handler(void *handle, uint8_t *cmd_param_info,
3385 				uint32_t len)
3386 {
3387 	tp_wma_handle wma = (tp_wma_handle) handle;
3388 	WMI_PEER_ASSOC_CONF_EVENTID_param_tlvs *param_buf;
3389 	wmi_peer_assoc_conf_event_fixed_param *event;
3390 	struct wma_target_req *req_msg;
3391 	uint8_t macaddr[QDF_MAC_ADDR_SIZE];
3392 	int status = 0;
3393 
3394 	param_buf = (WMI_PEER_ASSOC_CONF_EVENTID_param_tlvs *) cmd_param_info;
3395 	if (!param_buf) {
3396 		wma_err("Invalid peer assoc conf event buffer");
3397 		return -EINVAL;
3398 	}
3399 
3400 	event = param_buf->fixed_param;
3401 	if (!event) {
3402 		wma_err("Invalid peer assoc conf event buffer");
3403 		return -EINVAL;
3404 	}
3405 
3406 	WMI_MAC_ADDR_TO_CHAR_ARRAY(&event->peer_macaddr, macaddr);
3407 	wma_debug("peer assoc conf for vdev:%d mac="QDF_MAC_ADDR_FMT,
3408 		 event->vdev_id, QDF_MAC_ADDR_REF(macaddr));
3409 
3410 	req_msg = wma_find_req(wma, event->vdev_id,
3411 			       WMA_PEER_ASSOC_CNF_START, NULL);
3412 
3413 	if (!req_msg) {
3414 		wma_err("Failed to lookup request message for vdev %d",
3415 			event->vdev_id);
3416 		return -EINVAL;
3417 	}
3418 
3419 	qdf_mc_timer_stop(&req_msg->event_timeout);
3420 
3421 	if (req_msg->msg_type == WMA_ADD_STA_REQ) {
3422 		tpAddStaParams params = (tpAddStaParams)req_msg->user_data;
3423 
3424 		if (!params) {
3425 			wma_err("add STA params is NULL for vdev %d",
3426 				 event->vdev_id);
3427 			status = -EINVAL;
3428 			goto free_req_msg;
3429 		}
3430 
3431 		/* peer assoc conf event means the cmd succeeds */
3432 		params->status = event->status;
3433 		wma_debug("Send ADD_STA_RSP: statype %d vdev_id %d aid %d bssid "QDF_MAC_ADDR_FMT" status %d",
3434 			 params->staType, params->smesessionId,
3435 			 params->assocId, QDF_MAC_ADDR_REF(params->bssId),
3436 			 params->status);
3437 		wma_send_msg_high_priority(wma, WMA_ADD_STA_RSP,
3438 					   (void *)params, 0);
3439 	} else if (req_msg->msg_type == WMA_ADD_BSS_REQ) {
3440 		wma_send_add_bss_resp(wma, event->vdev_id, event->status);
3441 	} else {
3442 		wma_err("Unhandled request message type: %d", req_msg->msg_type);
3443 	}
3444 
3445 free_req_msg:
3446 	qdf_mc_timer_destroy(&req_msg->event_timeout);
3447 	qdf_mem_free(req_msg);
3448 
3449 	return status;
3450 }
3451 
3452 int wma_peer_create_confirm_handler(void *handle, uint8_t *evt_param_info,
3453 				    uint32_t len)
3454 {
3455 	tp_wma_handle wma = (tp_wma_handle)handle;
3456 	wmi_peer_create_conf_event_fixed_param *peer_create_rsp;
3457 	WMI_PEER_CREATE_CONF_EVENTID_param_tlvs *param_buf;
3458 	struct wma_target_req *req_msg = NULL;
3459 	struct mac_context *mac = cds_get_context(QDF_MODULE_ID_PE);
3460 	struct peer_create_rsp_params *rsp_data;
3461 	void *dp_soc = cds_get_context(QDF_MODULE_ID_SOC);
3462 	struct qdf_mac_addr peer_mac;
3463 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
3464 	int ret = -EINVAL;
3465 	uint8_t req_msg_type;
3466 
3467 	param_buf = (WMI_PEER_CREATE_CONF_EVENTID_param_tlvs *)evt_param_info;
3468 	if (!param_buf) {
3469 		wma_err("Invalid peer create conf evt buffer");
3470 		return -EINVAL;
3471 	}
3472 
3473 	peer_create_rsp = param_buf->fixed_param;
3474 
3475 	WMI_MAC_ADDR_TO_CHAR_ARRAY(&peer_create_rsp->peer_macaddr,
3476 				   peer_mac.bytes);
3477 	if (qdf_is_macaddr_zero(&peer_mac) ||
3478 	    qdf_is_macaddr_broadcast(&peer_mac) ||
3479 	    qdf_is_macaddr_group(&peer_mac)) {
3480 		wma_err("Invalid bssid");
3481 		return -EINVAL;
3482 	}
3483 
3484 	wma_debug("vdev:%d Peer create confirm for bssid: " QDF_MAC_ADDR_FMT,
3485 		  peer_create_rsp->vdev_id, QDF_MAC_ADDR_REF(peer_mac.bytes));
3486 	req_msg = wma_find_remove_req_msgtype(wma, peer_create_rsp->vdev_id,
3487 					      WMA_PEER_CREATE_REQ);
3488 	if (!req_msg) {
3489 		wma_debug("vdev:%d Failed to lookup peer create request msg",
3490 			  peer_create_rsp->vdev_id);
3491 		return -EINVAL;
3492 	}
3493 
3494 	rsp_data = (struct peer_create_rsp_params *)req_msg->user_data;
3495 	req_msg_type = req_msg->type;
3496 
3497 	qdf_mc_timer_stop(&req_msg->event_timeout);
3498 	qdf_mc_timer_destroy(&req_msg->event_timeout);
3499 	qdf_mem_free(rsp_data);
3500 	qdf_mem_free(req_msg);
3501 
3502 	if (req_msg_type == WMA_PASN_PEER_CREATE_RESPONSE) {
3503 		wma_pasn_handle_peer_create_conf(wma, &peer_mac,
3504 						 peer_create_rsp->status,
3505 						 peer_create_rsp->vdev_id);
3506 		wma_release_wakelock(&wma->wmi_cmd_rsp_wake_lock);
3507 		return 0;
3508 	}
3509 
3510 	wma_release_wakelock(&wma->wmi_cmd_rsp_wake_lock);
3511 	if (!peer_create_rsp->status) {
3512 		if (!dp_soc) {
3513 			wma_err("DP SOC context is NULL");
3514 			goto fail;
3515 		}
3516 
3517 		wma_cdp_peer_setup(wma, dp_soc, peer_create_rsp->vdev_id,
3518 				   peer_mac.bytes);
3519 
3520 		status = QDF_STATUS_SUCCESS;
3521 		ret = 0;
3522 	}
3523 
3524 fail:
3525 	if (QDF_IS_STATUS_ERROR(status))
3526 		wma_remove_peer(wma, peer_mac.bytes, peer_create_rsp->vdev_id,
3527 				(peer_create_rsp->status > 0) ? true : false);
3528 
3529 	if (mac)
3530 		lim_send_peer_create_resp(mac, peer_create_rsp->vdev_id, status,
3531 					  peer_mac.bytes);
3532 
3533 	return ret;
3534 }
3535 
3536 #ifdef FEATURE_WDS
3537 /*
3538  * wma_cdp_cp_peer_del_response - handle peer delete response
3539  * @psoc: psoc object pointer
3540  * @mac_addr: Mac address of the peer
3541  * @vdev_id: id of virtual device object
3542  *
3543  * when peer map v2 is enabled, cdp_peer_teardown() does not remove the AST from
3544  * hash table. Call cdp_cp_peer_del_response() when peer delete response is
3545  * received from fw to delete the AST entry from the AST hash.
3546  *
3547  * Return: None
3548  */
3549 static void
3550 wma_cdp_cp_peer_del_response(struct wlan_objmgr_psoc *psoc,
3551 			     uint8_t *peer_mac, uint8_t vdev_id)
3552 {
3553 	ol_txrx_soc_handle soc_txrx_handle;
3554 
3555 	soc_txrx_handle = wlan_psoc_get_dp_handle(psoc);
3556 	cdp_cp_peer_del_response(soc_txrx_handle, vdev_id, peer_mac);
3557 }
3558 #else
3559 static void
3560 wma_cdp_cp_peer_del_response(struct wlan_objmgr_psoc *psoc,
3561 			     uint8_t *peer_mac, uint8_t vdev_id)
3562 {
3563 }
3564 #endif
3565 
3566 /**
3567  * wma_peer_delete_handler() - peer delete response handler
3568  * @handle: wma handle
3569  * @cmd_param_info: event buffer
3570  * @len: buffer length
3571  *
3572  * Return: 0 for success or error code
3573  */
3574 int wma_peer_delete_handler(void *handle, uint8_t *cmd_param_info,
3575 				uint32_t len)
3576 {
3577 	tp_wma_handle wma = (tp_wma_handle) handle;
3578 	WMI_PEER_DELETE_RESP_EVENTID_param_tlvs *param_buf;
3579 	wmi_peer_delete_cmd_fixed_param *event;
3580 	struct wma_target_req *req_msg;
3581 	tDeleteStaParams *del_sta;
3582 	uint8_t macaddr[QDF_MAC_ADDR_SIZE];
3583 	int status = 0;
3584 	struct mac_context *mac = cds_get_context(QDF_MODULE_ID_PE);
3585 
3586 	if (!mac) {
3587 		wma_err("mac context is null");
3588 		return -EINVAL;
3589 	}
3590 	param_buf = (WMI_PEER_DELETE_RESP_EVENTID_param_tlvs *)cmd_param_info;
3591 	if (!param_buf) {
3592 		wma_err("Invalid vdev delete event buffer");
3593 		return -EINVAL;
3594 	}
3595 
3596 	event = (wmi_peer_delete_cmd_fixed_param *)param_buf->fixed_param;
3597 	if (!event) {
3598 		wma_err("Invalid vdev delete event buffer");
3599 		return -EINVAL;
3600 	}
3601 
3602 	WMI_MAC_ADDR_TO_CHAR_ARRAY(&event->peer_macaddr, macaddr);
3603 	wma_debug("Peer Delete Response, vdev %d Peer "QDF_MAC_ADDR_FMT,
3604 			event->vdev_id, QDF_MAC_ADDR_REF(macaddr));
3605 	wlan_roam_debug_log(event->vdev_id, DEBUG_PEER_DELETE_RESP,
3606 			    DEBUG_INVALID_PEER_ID, macaddr, NULL, 0, 0);
3607 	req_msg = wma_find_remove_req_msgtype(wma, event->vdev_id,
3608 					WMA_DELETE_STA_REQ);
3609 	if (!req_msg) {
3610 		wma_debug("Peer Delete response is not handled");
3611 		return -EINVAL;
3612 	}
3613 
3614 	wma_release_wakelock(&wma->wmi_cmd_rsp_wake_lock);
3615 
3616 	/* Cleanup timeout handler */
3617 	qdf_mc_timer_stop(&req_msg->event_timeout);
3618 	qdf_mc_timer_destroy(&req_msg->event_timeout);
3619 
3620 	if (req_msg->type == WMA_DELETE_STA_RSP_START) {
3621 		del_sta = req_msg->user_data;
3622 		if (del_sta->respReqd) {
3623 			wma_debug("Sending peer del rsp to umac");
3624 			wma_send_msg_high_priority(wma, WMA_DELETE_STA_RSP,
3625 				(void *)del_sta, QDF_STATUS_SUCCESS);
3626 		} else {
3627 			qdf_mem_free(del_sta);
3628 		}
3629 	} else if (req_msg->type == WMA_DEL_P2P_SELF_STA_RSP_START) {
3630 		struct del_sta_self_rsp_params *data;
3631 
3632 		data = (struct del_sta_self_rsp_params *)req_msg->user_data;
3633 		wma_debug("Calling vdev detach handler");
3634 		wma_handle_vdev_detach(wma, data->self_sta_param);
3635 		mlme_vdev_self_peer_delete_resp(data->self_sta_param);
3636 		qdf_mem_free(data);
3637 	} else if (req_msg->type == WMA_SET_LINK_PEER_RSP ||
3638 		   req_msg->type == WMA_DELETE_PEER_RSP) {
3639 		wma_send_vdev_down_req(wma, req_msg->user_data);
3640 	} else if (req_msg->type == WMA_DELETE_STA_CONNECT_RSP) {
3641 		wma_debug("wma delete peer completed vdev %d",
3642 			  req_msg->vdev_id);
3643 		lim_cm_send_connect_rsp(mac, NULL, req_msg->user_data,
3644 					CM_GENERIC_FAILURE,
3645 					QDF_STATUS_E_FAILURE, 0, false);
3646 		cm_free_join_req(req_msg->user_data);
3647 	}
3648 
3649 	wma_cdp_cp_peer_del_response(wma->psoc, macaddr, event->vdev_id);
3650 	qdf_mem_free(req_msg);
3651 
3652 	return status;
3653 }
3654 
3655 static
3656 void wma_trigger_recovery_assert_on_fw_timeout(uint16_t wma_msg,
3657 					       enum qdf_hang_reason reason)
3658 {
3659 	wma_err("%s timed out, triggering recovery",
3660 		 mac_trace_get_wma_msg_string(wma_msg));
3661 	qdf_trigger_self_recovery(NULL, reason);
3662 }
3663 
3664 static inline bool wma_crash_on_fw_timeout(bool crash_enabled)
3665 {
3666 	/* Discard FW timeouts and dont crash during SSR */
3667 	if (cds_is_driver_recovering())
3668 		return false;
3669 
3670 	/* Firmware is down send failure response */
3671 	if (cds_is_fw_down())
3672 		return false;
3673 
3674 	if (cds_is_driver_unloading())
3675 		return false;
3676 
3677 	return crash_enabled;
3678 }
3679 
3680 /**
3681  * wma_hold_req_timer() - wma hold request timeout function
3682  * @data: target request params
3683  *
3684  * Return: none
3685  */
3686 void wma_hold_req_timer(void *data)
3687 {
3688 	tp_wma_handle wma;
3689 	struct wma_target_req *tgt_req = (struct wma_target_req *)data;
3690 	struct mac_context *mac = cds_get_context(QDF_MODULE_ID_PE);
3691 	QDF_STATUS status;
3692 
3693 	wma = cds_get_context(QDF_MODULE_ID_WMA);
3694 	if (!wma)
3695 		return;
3696 
3697 	status = wma_find_req_on_timer_expiry(wma, tgt_req);
3698 
3699 	if (QDF_IS_STATUS_ERROR(status)) {
3700 		/*
3701 		 * if find request failed, then firmware rsp should have
3702 		 * consumed the buffer. Do not free.
3703 		 */
3704 		wma_debug("Failed to lookup request message - %pK", tgt_req);
3705 		return;
3706 	}
3707 	wma_alert("request %d is timed out for vdev_id - %d",
3708 		 tgt_req->msg_type, tgt_req->vdev_id);
3709 
3710 	if (tgt_req->msg_type == WMA_ADD_STA_REQ) {
3711 		tpAddStaParams params = (tpAddStaParams) tgt_req->user_data;
3712 
3713 		params->status = QDF_STATUS_E_TIMEOUT;
3714 		wma_alert("WMA_ADD_STA_REQ timed out");
3715 		wma_debug("Sending add sta rsp to umac (mac:"QDF_MAC_ADDR_FMT", status:%d)",
3716 			 QDF_MAC_ADDR_REF(params->staMac), params->status);
3717 		if (wma_crash_on_fw_timeout(wma->fw_timeout_crash))
3718 			wma_trigger_recovery_assert_on_fw_timeout(
3719 				WMA_ADD_STA_REQ,
3720 				QDF_AP_STA_CONNECT_REQ_TIMEOUT);
3721 		wma_send_msg_high_priority(wma, WMA_ADD_STA_RSP,
3722 					   (void *)params, 0);
3723 	} else if (tgt_req->msg_type == WMA_ADD_BSS_REQ) {
3724 
3725 		wma_alert("WMA_ADD_BSS_REQ timed out");
3726 		wma_debug("Sending add bss rsp to umac (vdev %d, status:%d)",
3727 			 tgt_req->vdev_id, QDF_STATUS_E_TIMEOUT);
3728 
3729 		if (wma_crash_on_fw_timeout(wma->fw_timeout_crash))
3730 			wma_trigger_recovery_assert_on_fw_timeout(
3731 				WMA_ADD_BSS_REQ,
3732 				QDF_STA_AP_CONNECT_REQ_TIMEOUT);
3733 
3734 		wma_send_add_bss_resp(wma, tgt_req->vdev_id,
3735 				      QDF_STATUS_E_TIMEOUT);
3736 	} else if ((tgt_req->msg_type == WMA_DELETE_STA_REQ) &&
3737 		(tgt_req->type == WMA_DELETE_STA_RSP_START)) {
3738 		tpDeleteStaParams params =
3739 				(tpDeleteStaParams) tgt_req->user_data;
3740 		params->status = QDF_STATUS_E_TIMEOUT;
3741 		wma_err("WMA_DEL_STA_REQ timed out");
3742 		wma_debug("Sending del sta rsp to umac (mac:"QDF_MAC_ADDR_FMT", status:%d)",
3743 			 QDF_MAC_ADDR_REF(params->staMac), params->status);
3744 
3745 		if (wma_crash_on_fw_timeout(wma->fw_timeout_crash))
3746 			wma_trigger_recovery_assert_on_fw_timeout(
3747 				WMA_DELETE_STA_REQ,
3748 				QDF_PEER_DELETION_TIMEDOUT);
3749 		wma_send_msg_high_priority(wma, WMA_DELETE_STA_RSP,
3750 					   (void *)params, 0);
3751 	} else if ((tgt_req->msg_type == WMA_DELETE_STA_REQ) &&
3752 		(tgt_req->type == WMA_DEL_P2P_SELF_STA_RSP_START)) {
3753 		struct del_sta_self_rsp_params *del_sta;
3754 
3755 		del_sta = (struct del_sta_self_rsp_params *)tgt_req->user_data;
3756 
3757 		del_sta->self_sta_param->status = QDF_STATUS_E_TIMEOUT;
3758 		wma_alert("wma delete sta p2p request timed out");
3759 
3760 		if (wma_crash_on_fw_timeout(wma->fw_timeout_crash))
3761 			wma_trigger_recovery_assert_on_fw_timeout(
3762 				WMA_DELETE_STA_REQ,
3763 				QDF_PEER_DELETION_TIMEDOUT);
3764 		wma_handle_vdev_detach(wma, del_sta->self_sta_param);
3765 		mlme_vdev_self_peer_delete_resp(del_sta->self_sta_param);
3766 		qdf_mem_free(tgt_req->user_data);
3767 	} else if ((tgt_req->msg_type == WMA_DELETE_STA_REQ) &&
3768 		   (tgt_req->type == WMA_SET_LINK_PEER_RSP ||
3769 		    tgt_req->type == WMA_DELETE_PEER_RSP)) {
3770 		struct del_bss_resp *params =
3771 			(struct del_bss_resp *)tgt_req->user_data;
3772 
3773 		params->status = QDF_STATUS_E_TIMEOUT;
3774 		wma_err("wma delete peer for del bss req timed out");
3775 
3776 		if (wma_crash_on_fw_timeout(wma->fw_timeout_crash))
3777 			wma_trigger_recovery_assert_on_fw_timeout(
3778 				WMA_DELETE_STA_REQ,
3779 				QDF_PEER_DELETION_TIMEDOUT);
3780 		wma_send_vdev_down_req(wma, params);
3781 	} else if ((tgt_req->msg_type == WMA_DELETE_STA_REQ) &&
3782 		   (tgt_req->type == WMA_DELETE_STA_CONNECT_RSP)) {
3783 		wma_err("wma delete peer timed out vdev %d",
3784 			tgt_req->vdev_id);
3785 
3786 		if (wma_crash_on_fw_timeout(wma->fw_timeout_crash))
3787 			wma_trigger_recovery_assert_on_fw_timeout(
3788 				WMA_DELETE_STA_REQ,
3789 				QDF_PEER_DELETION_TIMEDOUT);
3790 		if (!mac) {
3791 			wma_err("mac: Null Pointer Error");
3792 			goto timer_destroy;
3793 		}
3794 		lim_cm_send_connect_rsp(mac, NULL, tgt_req->user_data,
3795 					CM_GENERIC_FAILURE,
3796 					QDF_STATUS_E_FAILURE, 0, false);
3797 		cm_free_join_req(tgt_req->user_data);
3798 	} else if ((tgt_req->msg_type == SIR_HAL_PDEV_SET_HW_MODE) &&
3799 			(tgt_req->type == WMA_PDEV_SET_HW_MODE_RESP)) {
3800 		struct sir_set_hw_mode_resp *params =
3801 			qdf_mem_malloc(sizeof(*params));
3802 
3803 		wma_err("set hw mode req timed out");
3804 
3805 		if (wma_crash_on_fw_timeout(wma->fw_timeout_crash))
3806 			wma_trigger_recovery_assert_on_fw_timeout(
3807 			  SIR_HAL_PDEV_SET_HW_MODE,
3808 			  QDF_MAC_HW_MODE_CHANGE_TIMEOUT);
3809 		if (!params)
3810 			goto timer_destroy;
3811 
3812 		params->status = SET_HW_MODE_STATUS_ECANCELED;
3813 		params->cfgd_hw_mode_index = 0;
3814 		params->num_vdev_mac_entries = 0;
3815 		wma_send_msg_high_priority(wma, SIR_HAL_PDEV_SET_HW_MODE_RESP,
3816 					   params, 0);
3817 	} else if ((tgt_req->msg_type == SIR_HAL_PDEV_DUAL_MAC_CFG_REQ) &&
3818 			(tgt_req->type == WMA_PDEV_MAC_CFG_RESP)) {
3819 		struct sir_dual_mac_config_resp *resp =
3820 						qdf_mem_malloc(sizeof(*resp));
3821 
3822 		wma_err("set dual mac config timeout");
3823 		if (wma_crash_on_fw_timeout(wma->fw_timeout_crash))
3824 			wma_trigger_recovery_assert_on_fw_timeout(
3825 				SIR_HAL_PDEV_DUAL_MAC_CFG_REQ,
3826 				QDF_MAC_HW_MODE_CONFIG_TIMEOUT);
3827 		if (!resp)
3828 			goto timer_destroy;
3829 
3830 		resp->status = SET_HW_MODE_STATUS_ECANCELED;
3831 		wma_send_msg_high_priority(wma, SIR_HAL_PDEV_MAC_CFG_RESP,
3832 					   resp, 0);
3833 	} else if ((tgt_req->msg_type == WMA_PEER_CREATE_REQ) &&
3834 		   (tgt_req->type == WMA_PEER_CREATE_RESPONSE)) {
3835 		struct peer_create_rsp_params *peer_create_rsp;
3836 		struct qdf_mac_addr *peer_mac;
3837 
3838 		if (wma_crash_on_fw_timeout(wma->fw_timeout_crash))
3839 			wma_trigger_recovery_assert_on_fw_timeout(
3840 				WMA_PEER_CREATE_RESPONSE,
3841 				WMA_PEER_CREATE_RESPONSE_TIMEOUT);
3842 
3843 		peer_create_rsp =
3844 			(struct peer_create_rsp_params *)tgt_req->user_data;
3845 		peer_mac = &peer_create_rsp->peer_mac;
3846 		wma_remove_peer(wma, peer_mac->bytes,
3847 				tgt_req->vdev_id, false);
3848 		if (!mac) {
3849 			qdf_mem_free(tgt_req->user_data);
3850 			goto timer_destroy;
3851 		}
3852 
3853 		lim_send_peer_create_resp(mac, tgt_req->vdev_id,
3854 					  QDF_STATUS_E_TIMEOUT,
3855 					  (uint8_t *)tgt_req->user_data);
3856 		qdf_mem_free(tgt_req->user_data);
3857 	} else if ((tgt_req->msg_type == WMA_PEER_CREATE_REQ) &&
3858 		   (tgt_req->type == WMA_PASN_PEER_CREATE_RESPONSE)) {
3859 		struct peer_create_rsp_params *peer_create_rsp;
3860 		struct qdf_mac_addr *peer_mac;
3861 
3862 		if (wma_crash_on_fw_timeout(wma->fw_timeout_crash))
3863 			wma_trigger_recovery_assert_on_fw_timeout(
3864 				WMA_PEER_CREATE_RESPONSE,
3865 				WMA_PEER_CREATE_RESPONSE_TIMEOUT);
3866 
3867 		peer_create_rsp =
3868 			(struct peer_create_rsp_params *)tgt_req->user_data;
3869 		peer_mac = &peer_create_rsp->peer_mac;
3870 
3871 		wma_pasn_handle_peer_create_conf(
3872 				wma, peer_mac, QDF_STATUS_E_TIMEOUT,
3873 				tgt_req->vdev_id);
3874 		qdf_mem_free(tgt_req->user_data);
3875 	} else if (tgt_req->msg_type == WMA_PASN_PEER_DELETE_REQUEST &&
3876 		   tgt_req->type == WMA_PASN_PEER_DELETE_RESPONSE) {
3877 		wma_err("PASN Peer delete all resp not received. vdev:%d",
3878 			tgt_req->vdev_id);
3879 		if (wma_crash_on_fw_timeout(wma->fw_timeout_crash))
3880 			wma_trigger_recovery_assert_on_fw_timeout(
3881 				WMA_PASN_PEER_DELETE_RESPONSE,
3882 				WMA_PEER_DELETE_RESPONSE_TIMEOUT);
3883 
3884 		wma_resume_vdev_delete(wma, tgt_req->vdev_id);
3885 	} else {
3886 		wma_err("Unhandled timeout for msg_type:%d and type:%d",
3887 				tgt_req->msg_type, tgt_req->type);
3888 		QDF_BUG(0);
3889 	}
3890 
3891 timer_destroy:
3892 	qdf_mc_timer_destroy(&tgt_req->event_timeout);
3893 	qdf_mem_free(tgt_req);
3894 }
3895 
3896 /**
3897  * wma_fill_hold_req() - fill wma request
3898  * @wma: wma handle
3899  * @vdev_id: vdev id
3900  * @msg_type: message type
3901  * @type: request type
3902  * @params: request params
3903  * @timeout: timeout value
3904  *
3905  * Return: wma_target_req ptr
3906  */
3907 struct wma_target_req *wma_fill_hold_req(tp_wma_handle wma,
3908 					 uint8_t vdev_id,
3909 					 uint32_t msg_type, uint8_t type,
3910 					 void *params, uint32_t timeout)
3911 {
3912 	struct wma_target_req *req;
3913 	QDF_STATUS status;
3914 
3915 	req = qdf_mem_malloc(sizeof(*req));
3916 	if (!req)
3917 		return NULL;
3918 
3919 	wma_debug("vdev_id %d msg %d type %d", vdev_id, msg_type, type);
3920 	qdf_spin_lock_bh(&wma->wma_hold_req_q_lock);
3921 	req->vdev_id = vdev_id;
3922 	req->msg_type = msg_type;
3923 	req->type = type;
3924 	req->user_data = params;
3925 	status = qdf_list_insert_back(&wma->wma_hold_req_queue, &req->node);
3926 	if (QDF_STATUS_SUCCESS != status) {
3927 		qdf_spin_unlock_bh(&wma->wma_hold_req_q_lock);
3928 		wma_err("Failed add request in queue");
3929 		qdf_mem_free(req);
3930 		return NULL;
3931 	}
3932 	qdf_spin_unlock_bh(&wma->wma_hold_req_q_lock);
3933 	qdf_mc_timer_init(&req->event_timeout, QDF_TIMER_TYPE_SW,
3934 			  wma_hold_req_timer, req);
3935 	qdf_mc_timer_start(&req->event_timeout, timeout);
3936 	return req;
3937 }
3938 
3939 void wma_remove_peer_req(tp_wma_handle wma, uint8_t vdev_id,
3940 			 uint8_t type, struct qdf_mac_addr *peer_addr)
3941 {
3942 	struct wma_target_req *req_msg;
3943 
3944 	wma_debug("Remove req for vdev: %d type: %d", vdev_id, type);
3945 	req_msg = wma_find_req(wma, vdev_id, type, peer_addr);
3946 	if (!req_msg) {
3947 		wma_err("target req not found for vdev: %d type: %d",
3948 			vdev_id, type);
3949 		return;
3950 	}
3951 
3952 	qdf_mc_timer_stop(&req_msg->event_timeout);
3953 	qdf_mc_timer_destroy(&req_msg->event_timeout);
3954 	qdf_mem_free(req_msg);
3955 }
3956 
3957 /**
3958  * wma_remove_req() - remove request
3959  * @wma: wma handle
3960  * @vdev_id: vdev id
3961  * @type: type
3962  *
3963  * Return: none
3964  */
3965 void wma_remove_req(tp_wma_handle wma, uint8_t vdev_id,
3966 		    uint8_t type)
3967 {
3968 	struct wma_target_req *req_msg;
3969 
3970 	wma_debug("Remove req for vdev: %d type: %d", vdev_id, type);
3971 	req_msg = wma_find_req(wma, vdev_id, type, NULL);
3972 	if (!req_msg) {
3973 		wma_err("target req not found for vdev: %d type: %d",
3974 			 vdev_id, type);
3975 		return;
3976 	}
3977 
3978 	qdf_mc_timer_stop(&req_msg->event_timeout);
3979 	qdf_mc_timer_destroy(&req_msg->event_timeout);
3980 	qdf_mem_free(req_msg);
3981 }
3982 
3983 #define MAX_VDEV_SET_BSS_PARAMS 5
3984 /* params being sent:
3985  * 1.wmi_vdev_param_beacon_interval
3986  * 2.wmi_vdev_param_dtim_period
3987  * 3.wmi_vdev_param_tx_pwrlimit
3988  * 4.wmi_vdev_param_slot_time
3989  * 5.wmi_vdev_param_protection_mode
3990  */
3991 
3992 /**
3993  * wma_vdev_set_bss_params() - BSS set params functions
3994  * @wma: wma handle
3995  * @vdev_id: vdev id
3996  * @beaconInterval: beacon interval
3997  * @dtimPeriod: DTIM period
3998  * @shortSlotTimeSupported: short slot time
3999  * @llbCoexist: llbCoexist
4000  * @maxTxPower: max tx power
4001  * @bss_max_idle_period: BSS max idle period
4002  *
4003  * Return: QDF_STATUS
4004  */
4005 static QDF_STATUS
4006 wma_vdev_set_bss_params(tp_wma_handle wma, int vdev_id,
4007 			tSirMacBeaconInterval beaconInterval,
4008 			uint8_t dtimPeriod, uint8_t shortSlotTimeSupported,
4009 			uint8_t llbCoexist, int8_t maxTxPower,
4010 			uint16_t bss_max_idle_period)
4011 {
4012 	uint32_t slot_time;
4013 	struct wma_txrx_node *intr = wma->interfaces;
4014 	struct dev_set_param setparam[MAX_VDEV_SET_BSS_PARAMS];
4015 	uint8_t index = 0;
4016 	enum ieee80211_protmode prot_mode;
4017 	QDF_STATUS ret;
4018 
4019 	ret = QDF_STATUS_E_FAILURE;
4020 	/* Beacon Interval setting */
4021 	ret = mlme_check_index_setparam(setparam,
4022 					wmi_vdev_param_beacon_interval,
4023 					beaconInterval, index++,
4024 					MAX_VDEV_SET_BSS_PARAMS);
4025 	if (QDF_IS_STATUS_ERROR(ret)) {
4026 		wma_debug("failed to send wmi_vdev_param_beacon_interval to fw");
4027 		goto error;
4028 	}
4029 
4030 	ret = wmi_unified_vdev_set_gtx_cfg_send(wma->wmi_handle, vdev_id,
4031 						&intr[vdev_id].config.gtx_info);
4032 	if (QDF_IS_STATUS_ERROR(ret)) {
4033 		wma_err("failed to set vdev gtx cfg");
4034 		goto error;
4035 	}
4036 	ret = mlme_check_index_setparam(setparam, wmi_vdev_param_dtim_period,
4037 					dtimPeriod, index++,
4038 					MAX_VDEV_SET_BSS_PARAMS);
4039 	if (QDF_IS_STATUS_ERROR(ret)) {
4040 		wma_debug("failed to send wmi_vdev_param_dtim_period fw");
4041 		goto error;
4042 	}
4043 	intr[vdev_id].dtimPeriod = dtimPeriod;
4044 
4045 	if (!wlan_reg_is_ext_tpc_supported(wma->psoc)) {
4046 		if (!maxTxPower)
4047 			wma_warn("Setting Tx power limit to 0");
4048 
4049 		wma_nofl_debug("TXP[W][set_bss_params]: %d", maxTxPower);
4050 
4051 		if (maxTxPower != INVALID_TXPOWER) {
4052 			ret = mlme_check_index_setparam(
4053 						setparam,
4054 						wmi_vdev_param_tx_pwrlimit,
4055 						maxTxPower, index++,
4056 						MAX_VDEV_SET_BSS_PARAMS);
4057 			if (QDF_IS_STATUS_ERROR(ret)) {
4058 				wma_debug("failed to send wmi_vdev_param_tx_pwrlimit to fw");
4059 				goto error;
4060 			}
4061 		} else {
4062 			wma_err("Invalid max Tx power");
4063 		}
4064 	}
4065 	/* Slot time */
4066 	if (shortSlotTimeSupported)
4067 		slot_time = WMI_VDEV_SLOT_TIME_SHORT;
4068 	else
4069 		slot_time = WMI_VDEV_SLOT_TIME_LONG;
4070 	ret = mlme_check_index_setparam(setparam, wmi_vdev_param_slot_time,
4071 					slot_time, index++,
4072 					MAX_VDEV_SET_BSS_PARAMS);
4073 	if (QDF_IS_STATUS_ERROR(ret)) {
4074 		wma_debug("failed to send wmi_vdev_param_slot_time to fw");
4075 		goto error;
4076 	}
4077 	/* Initialize protection mode in case of coexistence */
4078 	prot_mode = llbCoexist ? IEEE80211_PROT_CTSONLY : IEEE80211_PROT_NONE;
4079 	ret = mlme_check_index_setparam(setparam,
4080 					wmi_vdev_param_protection_mode,
4081 					prot_mode, index++,
4082 					MAX_VDEV_SET_BSS_PARAMS);
4083 	if (QDF_IS_STATUS_ERROR(ret)) {
4084 		wma_debug("failed to send wmi_vdev_param_protection_mode to fw");
4085 		goto error;
4086 	}
4087 	ret = wma_send_multi_pdev_vdev_set_params(MLME_VDEV_SETPARAM,
4088 						  vdev_id, setparam, index);
4089 	if (QDF_IS_STATUS_ERROR(ret)) {
4090 		wma_err("Failed to set BEACON/DTIM_PERIOD/PWRLIMIT/SLOTTIME/PROTECTION params");
4091 		goto error;
4092 	}
4093 	mlme_set_max_reg_power(intr[vdev_id].vdev, maxTxPower);
4094 	if (bss_max_idle_period)
4095 		wma_set_sta_keep_alive(
4096 				wma, vdev_id,
4097 				SIR_KEEP_ALIVE_NULL_PKT,
4098 				bss_max_idle_period,
4099 				NULL, NULL, NULL);
4100 error:
4101 	return ret;
4102 }
4103 
4104 static void wma_set_mgmt_frame_protection(tp_wma_handle wma)
4105 {
4106 	struct pdev_params param = {0};
4107 	QDF_STATUS ret;
4108 
4109 	/*
4110 	 * when 802.11w PMF is enabled for hw encr/decr
4111 	 * use hw MFP Qos bits 0x10
4112 	 */
4113 	param.param_id = wmi_pdev_param_pmf_qos;
4114 	param.param_value = true;
4115 	ret = wmi_unified_pdev_param_send(wma->wmi_handle,
4116 					 &param, WMA_WILDCARD_PDEV_ID);
4117 	if (QDF_IS_STATUS_ERROR(ret)) {
4118 		wma_err("Failed to set QOS MFP/PMF (%d)", ret);
4119 	} else {
4120 		wma_debug("QOS MFP/PMF set");
4121 	}
4122 }
4123 
4124 /**
4125  * wma_set_peer_pmf_status() - Get the peer and update PMF capability of it
4126  * @wma: wma handle
4127  * @peer_mac: peer mac addr
4128  * @is_pmf_enabled: Carries the status whether PMF is enabled or not
4129  *
4130  * Return: QDF_STATUS
4131  */
4132 static QDF_STATUS
4133 wma_set_peer_pmf_status(tp_wma_handle wma, uint8_t *peer_mac,
4134 			bool is_pmf_enabled)
4135 {
4136 	struct wlan_objmgr_peer *peer;
4137 
4138 	peer = wlan_objmgr_get_peer(wma->psoc,
4139 				    wlan_objmgr_pdev_get_pdev_id(wma->pdev),
4140 				    peer_mac, WLAN_LEGACY_WMA_ID);
4141 	if (!peer) {
4142 		wma_err("Peer of peer_mac "QDF_MAC_ADDR_FMT" not found",
4143 			QDF_MAC_ADDR_REF(peer_mac));
4144 		return QDF_STATUS_E_INVAL;
4145 	}
4146 	mlme_set_peer_pmf_status(peer, is_pmf_enabled);
4147 	wlan_objmgr_peer_release_ref(peer, WLAN_LEGACY_WMA_ID);
4148 	wma_debug("set is_pmf_enabled %d for "QDF_MAC_ADDR_FMT,
4149 		  is_pmf_enabled, QDF_MAC_ADDR_REF(peer_mac));
4150 
4151 	return QDF_STATUS_SUCCESS;
4152 }
4153 
4154 QDF_STATUS wma_pre_vdev_start_setup(uint8_t vdev_id,
4155 				    struct bss_params *add_bss)
4156 {
4157 	QDF_STATUS status;
4158 	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
4159 	struct wma_txrx_node *iface;
4160 	tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA);
4161 	struct vdev_mlme_obj *mlme_obj;
4162 	uint8_t *mac_addr;
4163 
4164 	if (!soc || !wma)
4165 		return QDF_STATUS_E_FAILURE;
4166 
4167 	iface = &wma->interfaces[vdev_id];
4168 
4169 	mlme_obj = wlan_vdev_mlme_get_cmpt_obj(iface->vdev);
4170 	if (!mlme_obj) {
4171 		wma_err("vdev component object is NULL");
4172 		return QDF_STATUS_E_FAILURE;
4173 	}
4174 
4175 	wma_set_bss_rate_flags(wma, vdev_id, add_bss);
4176 	if (wlan_vdev_mlme_get_opmode(iface->vdev) == QDF_NDI_MODE ||
4177 	    wlan_vdev_mlme_get_opmode(iface->vdev) == QDF_IBSS_MODE)
4178 		mac_addr = mlme_obj->mgmt.generic.bssid;
4179 	else
4180 		mac_addr = wlan_vdev_mlme_get_macaddr(iface->vdev);
4181 
4182 	status = wma_create_peer(wma, mac_addr,
4183 				 WMI_PEER_TYPE_DEFAULT, vdev_id,
4184 				 NULL, false);
4185 	if (status != QDF_STATUS_SUCCESS) {
4186 		wma_err("Failed to create peer");
4187 		return status;
4188 	}
4189 
4190 	if (!cdp_find_peer_exist(soc, OL_TXRX_PDEV_ID, mac_addr)) {
4191 		wma_err("Failed to find peer "QDF_MAC_ADDR_FMT,
4192 			 QDF_MAC_ADDR_REF(mac_addr));
4193 		return QDF_STATUS_E_FAILURE;
4194 	}
4195 
4196 	iface->rmfEnabled = add_bss->rmfEnabled;
4197 	if (add_bss->rmfEnabled)
4198 		wma_set_mgmt_frame_protection(wma);
4199 
4200 	return status;
4201 }
4202 
4203 QDF_STATUS wma_post_vdev_start_setup(uint8_t vdev_id)
4204 {
4205 	QDF_STATUS status = QDF_STATUS_SUCCESS;
4206 	tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA);
4207 	struct wma_txrx_node *intr;
4208 	struct vdev_mlme_obj *mlme_obj;
4209 	struct wlan_objmgr_vdev *vdev;
4210 	uint8_t bss_power = 0;
4211 
4212 	if (!wma)
4213 		return QDF_STATUS_E_FAILURE;
4214 
4215 	intr = &wma->interfaces[vdev_id];
4216 	if (!intr) {
4217 		wma_err("Invalid interface");
4218 		return QDF_STATUS_E_FAILURE;
4219 	}
4220 	vdev = intr->vdev;
4221 	if (!vdev) {
4222 		wma_err("vdev is NULL");
4223 		return QDF_STATUS_E_FAILURE;
4224 	}
4225 	if (wlan_vdev_mlme_get_opmode(vdev) == QDF_NDI_MODE ||
4226 	    wlan_vdev_mlme_get_opmode(vdev) == QDF_IBSS_MODE) {
4227 		/* Initialize protection mode to no protection */
4228 		wma_vdev_set_param(wma->wmi_handle, vdev_id,
4229 				   wmi_vdev_param_protection_mode,
4230 				   IEEE80211_PROT_NONE);
4231 		return status;
4232 	}
4233 	mlme_obj = wlan_vdev_mlme_get_cmpt_obj(vdev);
4234 	if (!mlme_obj) {
4235 		wma_err("vdev component object is NULL");
4236 		return QDF_STATUS_E_FAILURE;
4237 	}
4238 
4239 	/* Fill bss_chan after vdev start */
4240 	qdf_mem_copy(vdev->vdev_mlme.bss_chan,
4241 		     vdev->vdev_mlme.des_chan,
4242 		     sizeof(struct wlan_channel));
4243 
4244 	if (!wlan_reg_is_ext_tpc_supported(wma->psoc))
4245 		bss_power = wlan_reg_get_channel_reg_power_for_freq(
4246 				wma->pdev, vdev->vdev_mlme.bss_chan->ch_freq);
4247 
4248 	if (wma_vdev_set_bss_params(wma, vdev_id,
4249 				    mlme_obj->proto.generic.beacon_interval,
4250 				    mlme_obj->proto.generic.dtim_period,
4251 				    mlme_obj->proto.generic.slot_time,
4252 				    mlme_obj->proto.generic.protection_mode,
4253 				    bss_power, 0)) {
4254 		wma_err("Failed to set wma_vdev_set_bss_params");
4255 	}
4256 
4257 	wma_vdev_set_he_bss_params(wma, vdev_id,
4258 				   &mlme_obj->proto.he_ops_info);
4259 #if defined(WLAN_FEATURE_11BE)
4260 	wma_vdev_set_eht_bss_params(wma, vdev_id,
4261 				    &mlme_obj->proto.eht_ops_info);
4262 #endif
4263 
4264 	return status;
4265 }
4266 
4267 static QDF_STATUS wma_update_iface_params(tp_wma_handle wma,
4268 					  struct bss_params *add_bss)
4269 {
4270 	struct wma_txrx_node *iface;
4271 	uint8_t vdev_id;
4272 
4273 	vdev_id = add_bss->staContext.smesessionId;
4274 	iface = &wma->interfaces[vdev_id];
4275 	wma_set_bss_rate_flags(wma, vdev_id, add_bss);
4276 
4277 	if (iface->addBssStaContext)
4278 		qdf_mem_free(iface->addBssStaContext);
4279 	iface->addBssStaContext = qdf_mem_malloc(sizeof(tAddStaParams));
4280 	if (!iface->addBssStaContext)
4281 		return QDF_STATUS_E_RESOURCES;
4282 
4283 	*iface->addBssStaContext = add_bss->staContext;
4284 	/* Save parameters later needed by WMA_ADD_STA_REQ */
4285 	iface->rmfEnabled = add_bss->rmfEnabled;
4286 	if (add_bss->rmfEnabled)
4287 		wma_set_peer_pmf_status(wma, add_bss->bssId, true);
4288 	iface->beaconInterval = add_bss->beaconInterval;
4289 	iface->llbCoexist = add_bss->llbCoexist;
4290 	iface->shortSlotTimeSupported = add_bss->shortSlotTimeSupported;
4291 	iface->nwType = add_bss->nwType;
4292 	iface->bss_max_idle_period = add_bss->bss_max_idle_period;
4293 
4294 	return QDF_STATUS_SUCCESS;
4295 }
4296 
4297 static inline
4298 bool wma_cdp_find_peer_by_addr(uint8_t *peer_addr)
4299 {
4300 	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
4301 	uint8_t pdev_id = OL_TXRX_PDEV_ID;
4302 
4303 	if (!soc || pdev_id == OL_TXRX_INVALID_PDEV_ID) {
4304 		wma_err("Failed to get pdev/soc");
4305 		return NULL;
4306 	}
4307 
4308 	return cdp_find_peer_exist(soc, pdev_id, peer_addr);
4309 }
4310 
4311 static
4312 QDF_STATUS wma_save_bss_params(tp_wma_handle wma, struct bss_params *add_bss)
4313 {
4314 	QDF_STATUS status;
4315 
4316 	wma_vdev_set_he_config(wma, add_bss->staContext.smesessionId, add_bss);
4317 	if (!wma_cdp_find_peer_by_addr(add_bss->bssId))
4318 		status = QDF_STATUS_E_FAILURE;
4319 	else
4320 		status = QDF_STATUS_SUCCESS;
4321 	qdf_mem_copy(add_bss->staContext.staMac, add_bss->bssId,
4322 		     sizeof(add_bss->staContext.staMac));
4323 
4324 	wma_debug("update_bss %d nw_type %d bssid "QDF_MAC_ADDR_FMT" status %d",
4325 		 add_bss->updateBss, add_bss->nwType,
4326 		 QDF_MAC_ADDR_REF(add_bss->bssId),
4327 		 status);
4328 
4329 	return status;
4330 }
4331 
4332 QDF_STATUS wma_pre_assoc_req(struct bss_params *add_bss)
4333 {
4334 	QDF_STATUS status;
4335 	tp_wma_handle wma;
4336 
4337 	wma = cds_get_context(QDF_MODULE_ID_WMA);
4338 	if (!wma)
4339 		return QDF_STATUS_E_INVAL;
4340 
4341 	status = wma_update_iface_params(wma, add_bss);
4342 	if (QDF_IS_STATUS_ERROR(status))
4343 		return status;
4344 
4345 	status = wma_save_bss_params(wma, add_bss);
4346 
4347 	return status;
4348 }
4349 
4350 void wma_add_bss_lfr3(tp_wma_handle wma, struct bss_params *add_bss)
4351 {
4352 	QDF_STATUS status;
4353 
4354 	status = wma_update_iface_params(wma, add_bss);
4355 	if (QDF_IS_STATUS_ERROR(status))
4356 		return;
4357 
4358 	if (!wma_cdp_find_peer_by_addr(add_bss->bssId)) {
4359 		wma_err("Failed to find peer "QDF_MAC_ADDR_FMT,
4360 			 QDF_MAC_ADDR_REF(add_bss->bssId));
4361 		return;
4362 	}
4363 	wma_debug("LFR3: bssid "QDF_MAC_ADDR_FMT,
4364 		  QDF_MAC_ADDR_REF(add_bss->bssId));
4365 }
4366 
4367 
4368 #if defined(QCA_LL_LEGACY_TX_FLOW_CONTROL) || defined(QCA_LL_TX_FLOW_CONTROL_V2)
4369 static
4370 QDF_STATUS wma_set_cdp_vdev_pause_reason(tp_wma_handle wma, uint8_t vdev_id)
4371 {
4372 	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
4373 
4374 	cdp_fc_vdev_pause(soc, vdev_id,
4375 			  OL_TXQ_PAUSE_REASON_PEER_UNAUTHORIZED, 0);
4376 
4377 	return QDF_STATUS_SUCCESS;
4378 }
4379 #else
4380 static inline
4381 QDF_STATUS wma_set_cdp_vdev_pause_reason(tp_wma_handle wma, uint8_t vdev_id)
4382 {
4383 	return QDF_STATUS_SUCCESS;
4384 }
4385 #endif
4386 
4387 void wma_send_add_bss_resp(tp_wma_handle wma, uint8_t vdev_id,
4388 			   QDF_STATUS status)
4389 {
4390 	struct add_bss_rsp *add_bss_rsp;
4391 
4392 	add_bss_rsp = qdf_mem_malloc(sizeof(*add_bss_rsp));
4393 	if (!add_bss_rsp)
4394 		return;
4395 
4396 	add_bss_rsp->vdev_id = vdev_id;
4397 	add_bss_rsp->status = status;
4398 	lim_handle_add_bss_rsp(wma->mac_context, add_bss_rsp);
4399 }
4400 
4401 #ifdef WLAN_FEATURE_HOST_ROAM
4402 QDF_STATUS wma_add_bss_lfr2_vdev_start(struct wlan_objmgr_vdev *vdev,
4403 				       struct bss_params *add_bss)
4404 {
4405 	tp_wma_handle wma;
4406 	QDF_STATUS status;
4407 	struct vdev_mlme_obj *mlme_obj;
4408 	uint8_t vdev_id;
4409 	bool peer_exist = false;
4410 
4411 	wma = cds_get_context(QDF_MODULE_ID_WMA);
4412 	if (!wma || !vdev) {
4413 		wma_err("Invalid wma or vdev");
4414 		return QDF_STATUS_E_INVAL;
4415 	}
4416 
4417 	vdev_id = vdev->vdev_objmgr.vdev_id;
4418 	mlme_obj = wlan_vdev_mlme_get_cmpt_obj(vdev);
4419 	if (!mlme_obj) {
4420 		wma_err("vdev component object is NULL");
4421 		return QDF_STATUS_E_FAILURE;
4422 	}
4423 
4424 	status = wma_update_iface_params(wma, add_bss);
4425 	if (QDF_IS_STATUS_ERROR(status))
4426 		goto send_fail_resp;
4427 
4428 	peer_exist = wma_cdp_find_peer_by_addr(mlme_obj->mgmt.generic.bssid);
4429 	if (!peer_exist) {
4430 		wma_err("Failed to find peer "QDF_MAC_ADDR_FMT,
4431 			QDF_MAC_ADDR_REF(mlme_obj->mgmt.generic.bssid));
4432 		goto send_fail_resp;
4433 	}
4434 
4435 	status = wma_vdev_pre_start(vdev_id, false);
4436 	if (QDF_IS_STATUS_ERROR(status)) {
4437 		wma_err("failed, status: %d", status);
4438 		goto peer_cleanup;
4439 	}
4440 	status = vdev_mgr_start_send(mlme_obj, false);
4441 	if (QDF_IS_STATUS_ERROR(status)) {
4442 		wma_err("failed, status: %d", status);
4443 		goto peer_cleanup;
4444 	}
4445 	status = wma_set_cdp_vdev_pause_reason(wma, vdev_id);
4446 	if (QDF_IS_STATUS_ERROR(status))
4447 		goto peer_cleanup;
4448 
4449 	/* ADD_BSS_RESP will be deferred to completion of VDEV_START */
4450 	return QDF_STATUS_SUCCESS;
4451 
4452 peer_cleanup:
4453 	if (peer_exist)
4454 		wma_remove_peer(wma, mlme_obj->mgmt.generic.bssid, vdev_id,
4455 				false);
4456 
4457 send_fail_resp:
4458 	wma_send_add_bss_resp(wma, vdev_id, QDF_STATUS_E_FAILURE);
4459 
4460 	return QDF_STATUS_SUCCESS;
4461 }
4462 #endif
4463 
4464 QDF_STATUS wma_send_peer_assoc_req(struct bss_params *add_bss)
4465 {
4466 	struct wma_target_req *msg;
4467 	tp_wma_handle wma;
4468 	uint8_t vdev_id;
4469 	bool peer_exist;
4470 	QDF_STATUS status;
4471 	struct wma_txrx_node *iface;
4472 	int pps_val = 0;
4473 	struct vdev_mlme_obj *mlme_obj;
4474 	struct mac_context *mac = cds_get_context(QDF_MODULE_ID_PE);
4475 	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
4476 
4477 	wma = cds_get_context(QDF_MODULE_ID_WMA);
4478 	if (!wma || !mac || !soc)
4479 		return QDF_STATUS_E_INVAL;
4480 
4481 	vdev_id = add_bss->staContext.smesessionId;
4482 
4483 	iface = &wma->interfaces[vdev_id];
4484 	status = wma_update_iface_params(wma, add_bss);
4485 	if (QDF_IS_STATUS_ERROR(status))
4486 		goto send_resp;
4487 
4488 	peer_exist = wma_cdp_find_peer_by_addr(add_bss->bssId);
4489 	if (add_bss->nonRoamReassoc && peer_exist)
4490 		goto send_resp;
4491 
4492 	if (!add_bss->updateBss)
4493 		goto send_resp;
4494 
4495 	if (!peer_exist) {
4496 		wma_err("Failed to find peer "QDF_MAC_ADDR_FMT,
4497 			QDF_MAC_ADDR_REF(add_bss->bssId));
4498 		status = QDF_STATUS_E_FAILURE;
4499 		goto send_resp;
4500 	}
4501 
4502 
4503 	if (add_bss->staContext.encryptType == eSIR_ED_NONE) {
4504 		wma_debug("Update peer("QDF_MAC_ADDR_FMT") state into auth",
4505 			 QDF_MAC_ADDR_REF(add_bss->bssId));
4506 		cdp_peer_state_update(soc, add_bss->bssId,
4507 				      OL_TXRX_PEER_STATE_AUTH);
4508 	} else {
4509 		wma_debug("Update peer("QDF_MAC_ADDR_FMT") state into conn",
4510 			 QDF_MAC_ADDR_REF(add_bss->bssId));
4511 		cdp_peer_state_update(soc, add_bss->bssId,
4512 				      OL_TXRX_PEER_STATE_CONN);
4513 		status = wma_set_cdp_vdev_pause_reason(wma, vdev_id);
4514 		if (QDF_IS_STATUS_ERROR(status))
4515 			goto send_resp;
4516 	}
4517 
4518 	wmi_unified_send_txbf(wma, &add_bss->staContext);
4519 
4520 	pps_val = ((mac->mlme_cfg->sta.enable_5g_ebt << 31) &
4521 		 0xffff0000) | (PKT_PWR_SAVE_5G_EBT & 0xffff);
4522 	status = wma_vdev_set_param(wma->wmi_handle, vdev_id,
4523 				    wmi_vdev_param_packet_powersave,
4524 				    pps_val);
4525 	if (QDF_IS_STATUS_ERROR(status))
4526 		wma_err("Failed to send wmi packet power save cmd");
4527 	else
4528 		wma_debug("Sent packet power save %x", pps_val);
4529 
4530 	add_bss->staContext.no_ptk_4_way = add_bss->no_ptk_4_way;
4531 
4532 	status = wma_send_peer_assoc(wma, add_bss->nwType,
4533 				     &add_bss->staContext);
4534 	if (QDF_IS_STATUS_ERROR(status)) {
4535 		wma_err("Failed to send peer assoc status:%d", status);
4536 		goto send_resp;
4537 	}
4538 
4539 	/* we just had peer assoc, so install key will be done later */
4540 	if (add_bss->staContext.encryptType != eSIR_ED_NONE)
4541 		iface->is_waiting_for_key = true;
4542 
4543 	if (add_bss->rmfEnabled)
4544 		wma_set_mgmt_frame_protection(wma);
4545 
4546 	if (wlan_reg_is_ext_tpc_supported(wma->psoc))
4547 		add_bss->maxTxPower = 0;
4548 
4549 	if (wma_vdev_set_bss_params(wma, add_bss->staContext.smesessionId,
4550 				    add_bss->beaconInterval,
4551 				    add_bss->dtimPeriod,
4552 				    add_bss->shortSlotTimeSupported,
4553 				    add_bss->llbCoexist,
4554 				    add_bss->maxTxPower,
4555 				    add_bss->bss_max_idle_period)) {
4556 		wma_err("Failed to set bss params");
4557 	}
4558 
4559 	mlme_obj = wlan_vdev_mlme_get_cmpt_obj(iface->vdev);
4560 	if (!mlme_obj) {
4561 		wma_err("Failed to mlme obj");
4562 		status = QDF_STATUS_E_FAILURE;
4563 		goto send_resp;
4564 	}
4565 	/*
4566 	 * Store the bssid in interface table, bssid will
4567 	 * be used during group key setting sta mode.
4568 	 */
4569 	qdf_mem_copy(mlme_obj->mgmt.generic.bssid,
4570 		     add_bss->bssId, QDF_MAC_ADDR_SIZE);
4571 
4572 	wma_save_bss_params(wma, add_bss);
4573 
4574 	if (!wmi_service_enabled(wma->wmi_handle,
4575 				 wmi_service_peer_assoc_conf)) {
4576 		wma_debug("WMI_SERVICE_PEER_ASSOC_CONF not enabled");
4577 		goto send_resp;
4578 	}
4579 
4580 	msg = wma_fill_hold_req(wma, vdev_id, WMA_ADD_BSS_REQ,
4581 				WMA_PEER_ASSOC_CNF_START, NULL,
4582 				WMA_PEER_ASSOC_TIMEOUT);
4583 	if (!msg) {
4584 		wma_err("Failed to allocate request for vdev_id %d", vdev_id);
4585 		wma_remove_req(wma, vdev_id, WMA_PEER_ASSOC_CNF_START);
4586 		status = QDF_STATUS_E_FAILURE;
4587 		goto send_resp;
4588 	}
4589 
4590 	return QDF_STATUS_SUCCESS;
4591 
4592 send_resp:
4593 	wma_send_add_bss_resp(wma, vdev_id, status);
4594 
4595 	return QDF_STATUS_SUCCESS;
4596 }
4597 
4598 #ifdef WLAN_FEATURE_11BE_MLO
4599 /**
4600  * wma_get_mld_info_ap() - get mld mac addr and assoc peer flag for ap
4601  * @add_sta: tpAddStaParams
4602  * @peer_mld_addr: peer mld mac addr
4603  * @is_assoc_peer: is assoc peer or not
4604  *
4605  * Return: void
4606  */
4607 static void wma_get_mld_info_ap(tpAddStaParams add_sta,
4608 				uint8_t **peer_mld_addr,
4609 				bool *is_assoc_peer)
4610 {
4611 	if (add_sta) {
4612 		*peer_mld_addr = add_sta->mld_mac_addr;
4613 		*is_assoc_peer = add_sta->is_assoc_peer;
4614 	} else {
4615 		peer_mld_addr = NULL;
4616 		*is_assoc_peer = false;
4617 	}
4618 }
4619 #else
4620 static void wma_get_mld_info_ap(tpAddStaParams add_sta,
4621 				uint8_t **peer_mld_addr,
4622 				bool *is_assoc_peer)
4623 {
4624 	*peer_mld_addr = NULL;
4625 	*is_assoc_peer = false;
4626 }
4627 #endif
4628 
4629 /**
4630  * wma_add_sta_req_ap_mode() - process add sta request in ap mode
4631  * @wma: wma handle
4632  * @add_sta: add sta params
4633  *
4634  * Return: none
4635  */
4636 static void wma_add_sta_req_ap_mode(tp_wma_handle wma, tpAddStaParams add_sta)
4637 {
4638 	enum ol_txrx_peer_state state = OL_TXRX_PEER_STATE_CONN;
4639 	uint8_t pdev_id = OL_TXRX_PDEV_ID;
4640 	QDF_STATUS status;
4641 	int32_t ret;
4642 	struct wma_txrx_node *iface = NULL;
4643 	struct wma_target_req *msg;
4644 	bool peer_assoc_cnf = false;
4645 	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
4646 	uint32_t i, j;
4647 	uint16_t mcs_limit;
4648 	uint8_t *rate_pos;
4649 	struct mac_context *mac = wma->mac_context;
4650 	uint8_t *peer_mld_addr = NULL;
4651 	bool is_assoc_peer = false;
4652 
4653 	/* UMAC sends WMA_ADD_STA_REQ msg twice to WMA when the station
4654 	 * associates. First WMA_ADD_STA_REQ will have staType as
4655 	 * STA_ENTRY_PEER and second posting will have STA_ENTRY_SELF.
4656 	 * Peer creation is done in first WMA_ADD_STA_REQ and second
4657 	 * WMA_ADD_STA_REQ which has STA_ENTRY_SELF is ignored and
4658 	 * send fake response with success to UMAC. Otherwise UMAC
4659 	 * will get blocked.
4660 	 */
4661 	if (add_sta->staType != STA_ENTRY_PEER) {
4662 		add_sta->status = QDF_STATUS_SUCCESS;
4663 		goto send_rsp;
4664 	}
4665 
4666 	iface = &wma->interfaces[add_sta->smesessionId];
4667 
4668 	if (cdp_find_peer_exist_on_vdev(soc, add_sta->smesessionId,
4669 					add_sta->staMac)) {
4670 		wma_remove_peer(wma, add_sta->staMac, add_sta->smesessionId,
4671 				false);
4672 		wma_err("Peer already exists, Deleted peer with peer_addr "QDF_MAC_ADDR_FMT,
4673 			QDF_MAC_ADDR_REF(add_sta->staMac));
4674 	}
4675 	/* The code above only checks the peer existence on its own vdev.
4676 	 * Need to check whether the peer exists on other vDevs because firmware
4677 	 * can't create the peer if the peer with same MAC address already
4678 	 * exists on the pDev. As this peer belongs to other vDevs, just return
4679 	 * here.
4680 	 */
4681 	if (cdp_find_peer_exist(soc, pdev_id, add_sta->staMac)) {
4682 		wma_err("My vdev id %d, but Peer exists on other vdev with peer_addr "QDF_MAC_ADDR_FMT,
4683 			 add_sta->smesessionId,
4684 			 QDF_MAC_ADDR_REF(add_sta->staMac));
4685 		add_sta->status = QDF_STATUS_E_FAILURE;
4686 		goto send_rsp;
4687 	}
4688 
4689 	wma_delete_invalid_peer_entries(add_sta->smesessionId, add_sta->staMac);
4690 
4691 	wma_get_mld_info_ap(add_sta, &peer_mld_addr, &is_assoc_peer);
4692 	status = wma_create_peer(wma, add_sta->staMac, WMI_PEER_TYPE_DEFAULT,
4693 				 add_sta->smesessionId, peer_mld_addr,
4694 				 is_assoc_peer);
4695 	if (status != QDF_STATUS_SUCCESS) {
4696 		wma_err("Failed to create peer for "QDF_MAC_ADDR_FMT,
4697 			QDF_MAC_ADDR_REF(add_sta->staMac));
4698 		add_sta->status = status;
4699 		goto send_rsp;
4700 	}
4701 
4702 	if (!cdp_find_peer_exist_on_vdev(soc, add_sta->smesessionId,
4703 					 add_sta->staMac)) {
4704 		wma_err("Failed to find peer handle using peer mac "QDF_MAC_ADDR_FMT,
4705 			QDF_MAC_ADDR_REF(add_sta->staMac));
4706 		add_sta->status = QDF_STATUS_E_FAILURE;
4707 		wma_remove_peer(wma, add_sta->staMac, add_sta->smesessionId,
4708 				false);
4709 		goto send_rsp;
4710 	}
4711 
4712 	wmi_unified_send_txbf(wma, add_sta);
4713 
4714 	/*
4715 	 * Get MCS limit from ini configure, and map it to rate parameters
4716 	 * This will limit HT rate upper bound. CFG_CTRL_MASK is used to
4717 	 * check whether ini config is enabled and CFG_DATA_MASK to get the
4718 	 * MCS value.
4719 	 */
4720 #define CFG_CTRL_MASK              0xFF00
4721 #define CFG_DATA_MASK              0x00FF
4722 
4723 	mcs_limit = mac->mlme_cfg->rates.sap_max_mcs_txdata;
4724 
4725 	if (mcs_limit & CFG_CTRL_MASK) {
4726 		wma_debug("set mcs_limit %x", mcs_limit);
4727 
4728 		mcs_limit &= CFG_DATA_MASK;
4729 		rate_pos = (u_int8_t *)add_sta->supportedRates.supportedMCSSet;
4730 		for (i = 0, j = 0; i < MAX_SUPPORTED_RATES;) {
4731 			if (j < mcs_limit / 8) {
4732 				rate_pos[j] = 0xff;
4733 				j++;
4734 				i += 8;
4735 			} else if (j < mcs_limit / 8 + 1) {
4736 				if (i <= mcs_limit)
4737 					rate_pos[i / 8] |= 1 << (i % 8);
4738 				else
4739 					rate_pos[i / 8] &= ~(1 << (i % 8));
4740 				i++;
4741 
4742 				if (i >= (j + 1) * 8)
4743 					j++;
4744 			} else {
4745 				rate_pos[j++] = 0;
4746 				i += 8;
4747 			}
4748 		}
4749 	}
4750 
4751 	if (wmi_service_enabled(wma->wmi_handle,
4752 				    wmi_service_peer_assoc_conf)) {
4753 		peer_assoc_cnf = true;
4754 		msg = wma_fill_hold_req(wma, add_sta->smesessionId,
4755 				   WMA_ADD_STA_REQ, WMA_PEER_ASSOC_CNF_START,
4756 				   add_sta, WMA_PEER_ASSOC_TIMEOUT);
4757 		if (!msg) {
4758 			wma_err("Failed to alloc request for vdev_id %d",
4759 				add_sta->smesessionId);
4760 			add_sta->status = QDF_STATUS_E_FAILURE;
4761 			wma_remove_req(wma, add_sta->smesessionId,
4762 				       WMA_PEER_ASSOC_CNF_START);
4763 			wma_remove_peer(wma, add_sta->staMac,
4764 					add_sta->smesessionId, false);
4765 			peer_assoc_cnf = false;
4766 			goto send_rsp;
4767 		}
4768 	} else {
4769 		wma_err("WMI_SERVICE_PEER_ASSOC_CONF not enabled");
4770 	}
4771 
4772 	ret = wma_send_peer_assoc(wma, add_sta->nwType, add_sta);
4773 	if (ret) {
4774 		add_sta->status = QDF_STATUS_E_FAILURE;
4775 		wma_remove_peer(wma, add_sta->staMac, add_sta->smesessionId,
4776 				false);
4777 		goto send_rsp;
4778 	}
4779 
4780 	if (add_sta->rmfEnabled)
4781 		wma_set_peer_pmf_status(wma, add_sta->staMac, true);
4782 
4783 	if (add_sta->uAPSD) {
4784 		status = wma_set_ap_peer_uapsd(wma, add_sta->smesessionId,
4785 					    add_sta->staMac,
4786 					    add_sta->uAPSD, add_sta->maxSPLen);
4787 		if (QDF_IS_STATUS_ERROR(status)) {
4788 			wma_err("Failed to set peer uapsd param for "QDF_MAC_ADDR_FMT,
4789 				QDF_MAC_ADDR_REF(add_sta->staMac));
4790 			add_sta->status = QDF_STATUS_E_FAILURE;
4791 			wma_remove_peer(wma, add_sta->staMac,
4792 					add_sta->smesessionId, false);
4793 			goto send_rsp;
4794 		}
4795 	}
4796 
4797 	wma_debug("Moving peer "QDF_MAC_ADDR_FMT" to state %d",
4798 		  QDF_MAC_ADDR_REF(add_sta->staMac), state);
4799 	cdp_peer_state_update(soc, add_sta->staMac, state);
4800 
4801 	add_sta->nss    = wma_objmgr_get_peer_mlme_nss(wma, add_sta->staMac);
4802 	add_sta->status = QDF_STATUS_SUCCESS;
4803 send_rsp:
4804 	/* Do not send add stat resp when peer assoc cnf is enabled */
4805 	if (peer_assoc_cnf) {
4806 		wma_debug("WMI_SERVICE_PEER_ASSOC_CONF is enabled");
4807 		return;
4808 	}
4809 
4810 	wma_debug("statype %d vdev_id %d aid %d bssid "QDF_MAC_ADDR_FMT" status %d",
4811 		 add_sta->staType, add_sta->smesessionId,
4812 		 add_sta->assocId, QDF_MAC_ADDR_REF(add_sta->bssId),
4813 		 add_sta->status);
4814 	wma_send_msg_high_priority(wma, WMA_ADD_STA_RSP, (void *)add_sta, 0);
4815 }
4816 
4817 #ifdef FEATURE_WLAN_TDLS
4818 
4819 /**
4820  * wma_add_tdls_sta() - process add sta request in TDLS mode
4821  * @wma: wma handle
4822  * @add_sta: add sta params
4823  *
4824  * Return: none
4825  */
4826 static void wma_add_tdls_sta(tp_wma_handle wma, tpAddStaParams add_sta)
4827 {
4828 	QDF_STATUS status;
4829 	int32_t ret;
4830 	struct tdls_peer_update_state *peer_state;
4831 	struct wma_target_req *msg;
4832 	bool peer_assoc_cnf = false;
4833 	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
4834 	uint8_t pdev_id = OL_TXRX_PDEV_ID;
4835 	struct wma_txrx_node *iface = &wma->interfaces[add_sta->smesessionId];
4836 
4837 	wma_debug("staType: %d, updateSta: %d, bssId: "QDF_MAC_ADDR_FMT", staMac: "QDF_MAC_ADDR_FMT,
4838 		 add_sta->staType,
4839 		 add_sta->updateSta, QDF_MAC_ADDR_REF(add_sta->bssId),
4840 		 QDF_MAC_ADDR_REF(add_sta->staMac));
4841 
4842 	if (iface->vdev && wlan_cm_is_vdev_roaming(iface->vdev)) {
4843 		wma_err("Vdev %d roaming in progress, reject add sta!",
4844 			add_sta->smesessionId);
4845 		add_sta->status = QDF_STATUS_E_PERM;
4846 		goto send_rsp;
4847 	}
4848 
4849 	if (0 == add_sta->updateSta) {
4850 		/* its a add sta request * */
4851 
4852 		cdp_peer_copy_mac_addr_raw(soc, add_sta->smesessionId,
4853 					   add_sta->bssId);
4854 
4855 		wma_debug("addSta, calling wma_create_peer for "QDF_MAC_ADDR_FMT", vdev_id %hu",
4856 			  QDF_MAC_ADDR_REF(add_sta->staMac),
4857 			  add_sta->smesessionId);
4858 
4859 		status = wma_create_peer(wma, add_sta->staMac,
4860 					 WMI_PEER_TYPE_TDLS,
4861 					 add_sta->smesessionId, NULL, false);
4862 		if (status != QDF_STATUS_SUCCESS) {
4863 			wma_err("Failed to create peer for "QDF_MAC_ADDR_FMT,
4864 				QDF_MAC_ADDR_REF(add_sta->staMac));
4865 			add_sta->status = status;
4866 			goto send_rsp;
4867 		}
4868 
4869 		wma_debug("addSta, after calling cdp_local_peer_id, staMac: "QDF_MAC_ADDR_FMT,
4870 			  QDF_MAC_ADDR_REF(add_sta->staMac));
4871 
4872 		peer_state = qdf_mem_malloc(sizeof(*peer_state));
4873 		if (!peer_state) {
4874 			add_sta->status = QDF_STATUS_E_NOMEM;
4875 			goto send_rsp;
4876 		}
4877 
4878 		peer_state->peer_state = WMI_TDLS_PEER_STATE_PEERING;
4879 		peer_state->vdev_id = add_sta->smesessionId;
4880 		qdf_mem_copy(&peer_state->peer_macaddr,
4881 			     &add_sta->staMac, sizeof(tSirMacAddr));
4882 		wma_update_tdls_peer_state(wma, peer_state);
4883 	} else {
4884 		if (wmi_service_enabled(wma->wmi_handle,
4885 					    wmi_service_peer_assoc_conf)) {
4886 			wma_err("WMI_SERVICE_PEER_ASSOC_CONF is enabled");
4887 			peer_assoc_cnf = true;
4888 			msg = wma_fill_hold_req(wma, add_sta->smesessionId,
4889 				WMA_ADD_STA_REQ, WMA_PEER_ASSOC_CNF_START,
4890 				add_sta, WMA_PEER_ASSOC_TIMEOUT);
4891 			if (!msg) {
4892 				wma_err("Failed to alloc request for vdev_id %d",
4893 					add_sta->smesessionId);
4894 				add_sta->status = QDF_STATUS_E_FAILURE;
4895 				wma_remove_req(wma, add_sta->smesessionId,
4896 					       WMA_PEER_ASSOC_CNF_START);
4897 				wma_remove_peer(wma, add_sta->staMac,
4898 						add_sta->smesessionId, false);
4899 				peer_assoc_cnf = false;
4900 				goto send_rsp;
4901 			}
4902 		} else {
4903 			wma_err("WMI_SERVICE_PEER_ASSOC_CONF not enabled");
4904 		}
4905 
4906 		wma_debug("changeSta, calling wma_send_peer_assoc");
4907 		if (add_sta->rmfEnabled)
4908 			wma_set_peer_pmf_status(wma, add_sta->staMac, true);
4909 
4910 		ret =
4911 			wma_send_peer_assoc(wma, add_sta->nwType, add_sta);
4912 		if (ret) {
4913 			add_sta->status = QDF_STATUS_E_FAILURE;
4914 			wma_remove_peer(wma, add_sta->staMac,
4915 					add_sta->smesessionId, false);
4916 			cdp_peer_add_last_real_peer(soc, pdev_id,
4917 						    add_sta->smesessionId);
4918 			wma_remove_req(wma, add_sta->smesessionId,
4919 				       WMA_PEER_ASSOC_CNF_START);
4920 			peer_assoc_cnf = false;
4921 
4922 			goto send_rsp;
4923 		}
4924 	}
4925 
4926 send_rsp:
4927 	/* Do not send add stat resp when peer assoc cnf is enabled */
4928 	if (peer_assoc_cnf)
4929 		return;
4930 
4931 	wma_debug("statype %d vdev_id %d aid %d bssid "QDF_MAC_ADDR_FMT" status %d",
4932 		 add_sta->staType, add_sta->smesessionId,
4933 		 add_sta->assocId, QDF_MAC_ADDR_REF(add_sta->bssId),
4934 		 add_sta->status);
4935 	wma_send_msg_high_priority(wma, WMA_ADD_STA_RSP, (void *)add_sta, 0);
4936 }
4937 #endif
4938 
4939 /**
4940  * wma_send_bss_color_change_enable() - send bss color change enable cmd.
4941  * @wma: wma handle
4942  * @params: add sta params
4943  *
4944  * Send bss color change command to firmware, to enable firmware to update
4945  * internally if any change in bss color in advertised by associated AP.
4946  *
4947  * Return: none
4948  */
4949 #ifdef WLAN_FEATURE_11AX
4950 static void wma_send_bss_color_change_enable(tp_wma_handle wma,
4951 					     tpAddStaParams params)
4952 {
4953 	QDF_STATUS status;
4954 	uint32_t vdev_id = params->smesessionId;
4955 
4956 	if (!params->he_capable) {
4957 		wma_debug("he_capable is not set for vdev_id:%d", vdev_id);
4958 		return;
4959 	}
4960 
4961 	status = wmi_unified_send_bss_color_change_enable_cmd(wma->wmi_handle,
4962 							      vdev_id,
4963 							      true);
4964 	if (QDF_IS_STATUS_ERROR(status)) {
4965 		wma_err("Failed to enable bss color change offload, vdev:%d",
4966 			vdev_id);
4967 	}
4968 
4969 	return;
4970 }
4971 #else
4972 static void wma_send_bss_color_change_enable(tp_wma_handle wma,
4973 					     tpAddStaParams params)
4974 {
4975 }
4976 #endif
4977 
4978 #define MAX_VDEV_STA_REQ_PARAMS 5
4979 /* params being sent:
4980  * 1.wmi_vdev_param_max_li_of_moddtim
4981  * 2.wmi_vdev_param_max_li_of_moddtim_ms
4982  * 3.wmi_vdev_param_dyndtim_cnt
4983  * 4.wmi_vdev_param_moddtim_cnt
4984  * 5.wmi_vdev_param_moddtim_cnt
4985  */
4986 
4987 /**
4988  * wma_add_sta_req_sta_mode() - process add sta request in sta mode
4989  * @wma: wma handle
4990  * @params: add sta params
4991  *
4992  * Return: none
4993  */
4994 static void wma_add_sta_req_sta_mode(tp_wma_handle wma, tpAddStaParams params)
4995 {
4996 	QDF_STATUS status = QDF_STATUS_SUCCESS;
4997 	struct wma_txrx_node *iface;
4998 	int8_t maxTxPower = 0;
4999 	int ret = 0;
5000 	struct wma_target_req *msg;
5001 	bool peer_assoc_cnf = false;
5002 	int smps_param;
5003 	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
5004 	struct dev_set_param setparam[MAX_VDEV_STA_REQ_PARAMS];
5005 	uint8_t index = 0;
5006 
5007 #ifdef FEATURE_WLAN_TDLS
5008 	if (STA_ENTRY_TDLS_PEER == params->staType) {
5009 		wma_add_tdls_sta(wma, params);
5010 		return;
5011 	}
5012 #endif
5013 
5014 	iface = &wma->interfaces[params->smesessionId];
5015 	if (params->staType != STA_ENTRY_SELF) {
5016 		wma_err("unsupported station type %d", params->staType);
5017 		goto out;
5018 	}
5019 	if (params->nonRoamReassoc) {
5020 		cdp_peer_state_update(soc, params->bssId,
5021 				      OL_TXRX_PEER_STATE_AUTH);
5022 		qdf_atomic_set(&iface->bss_status, WMA_BSS_STATUS_STARTED);
5023 		iface->aid = params->assocId;
5024 		goto out;
5025 	}
5026 
5027 	if (wma_is_vdev_up(params->smesessionId)) {
5028 		wma_debug("vdev id %d is already UP for "QDF_MAC_ADDR_FMT,
5029 			 params->smesessionId,
5030 			 QDF_MAC_ADDR_REF(params->bssId));
5031 		status = QDF_STATUS_E_FAILURE;
5032 		goto out;
5033 	}
5034 
5035 	if (cdp_peer_state_get(soc, params->smesessionId,
5036 			       params->bssId) == OL_TXRX_PEER_STATE_DISC) {
5037 		/*
5038 		 * This is the case for reassociation.
5039 		 * peer state update and peer_assoc is required since it
5040 		 * was not done by WMA_ADD_BSS_REQ.
5041 		 */
5042 
5043 		/* Update peer state */
5044 		if (params->encryptType == eSIR_ED_NONE) {
5045 			wma_debug("Update peer("QDF_MAC_ADDR_FMT") state into auth",
5046 				  QDF_MAC_ADDR_REF(params->bssId));
5047 			cdp_peer_state_update(soc, params->bssId,
5048 					      OL_TXRX_PEER_STATE_AUTH);
5049 		} else {
5050 			wma_debug("Update peer("QDF_MAC_ADDR_FMT") state into conn",
5051 				  QDF_MAC_ADDR_REF(params->bssId));
5052 			cdp_peer_state_update(soc, params->bssId,
5053 					      OL_TXRX_PEER_STATE_CONN);
5054 		}
5055 
5056 		if (wlan_cm_is_roam_sync_in_progress(wma->psoc,
5057 						     params->smesessionId) ||
5058 		    MLME_IS_MLO_ROAM_SYNCH_IN_PROGRESS(wma->psoc,
5059 						       params->smesessionId)) {
5060 			/* iface->nss = params->nss; */
5061 			/*In LFR2.0, the following operations are performed as
5062 			 * part of wma_send_peer_assoc. As we are
5063 			 * skipping this operation, we are just executing the
5064 			 * following which are useful for LFR3.0
5065 			 */
5066 			cdp_peer_state_update(soc, params->bssId,
5067 					      OL_TXRX_PEER_STATE_AUTH);
5068 			qdf_atomic_set(&iface->bss_status,
5069 				       WMA_BSS_STATUS_STARTED);
5070 			iface->aid = params->assocId;
5071 			wma_debug("LFR3:statype %d vdev %d aid %d bssid "QDF_MAC_ADDR_FMT,
5072 					params->staType, params->smesessionId,
5073 					params->assocId,
5074 					QDF_MAC_ADDR_REF(params->bssId));
5075 			return;
5076 		}
5077 		wmi_unified_send_txbf(wma, params);
5078 
5079 		if (wmi_service_enabled(wma->wmi_handle,
5080 					    wmi_service_peer_assoc_conf)) {
5081 			peer_assoc_cnf = true;
5082 			msg = wma_fill_hold_req(wma, params->smesessionId,
5083 				WMA_ADD_STA_REQ, WMA_PEER_ASSOC_CNF_START,
5084 				params, WMA_PEER_ASSOC_TIMEOUT);
5085 			if (!msg) {
5086 				wma_debug("Failed to alloc request for vdev_id %d",
5087 					 params->smesessionId);
5088 				params->status = QDF_STATUS_E_FAILURE;
5089 				wma_remove_req(wma, params->smesessionId,
5090 					       WMA_PEER_ASSOC_CNF_START);
5091 				wma_remove_peer(wma, params->bssId,
5092 						params->smesessionId, false);
5093 				peer_assoc_cnf = false;
5094 				goto out;
5095 			}
5096 		} else {
5097 			wma_debug("WMI_SERVICE_PEER_ASSOC_CONF not enabled");
5098 		}
5099 
5100 		((tAddStaParams *)iface->addBssStaContext)->no_ptk_4_way =
5101 						params->no_ptk_4_way;
5102 
5103 		qdf_mem_copy(((tAddStaParams *)iface->addBssStaContext)->
5104 			     supportedRates.supportedMCSSet,
5105 			     params->supportedRates.supportedMCSSet,
5106 			     SIR_MAC_MAX_SUPPORTED_MCS_SET);
5107 
5108 
5109 		ret = wma_send_peer_assoc(wma,
5110 				iface->nwType,
5111 				(tAddStaParams *) iface->addBssStaContext);
5112 		if (ret) {
5113 			status = QDF_STATUS_E_FAILURE;
5114 			wma_remove_peer(wma, params->bssId,
5115 					params->smesessionId, false);
5116 			goto out;
5117 		}
5118 
5119 		if (params->rmfEnabled) {
5120 			wma_set_mgmt_frame_protection(wma);
5121 			wma_set_peer_pmf_status(wma, params->bssId, true);
5122 		}
5123 	}
5124 
5125 	if (!wlan_reg_is_ext_tpc_supported(wma->psoc))
5126 		maxTxPower = params->maxTxPower;
5127 
5128 	if (wma_vdev_set_bss_params(wma, params->smesessionId,
5129 				    iface->beaconInterval, iface->dtimPeriod,
5130 				    iface->shortSlotTimeSupported,
5131 				    iface->llbCoexist, maxTxPower,
5132 				    iface->bss_max_idle_period)) {
5133 		wma_err("Failed to bss params");
5134 	}
5135 
5136 	params->csaOffloadEnable = 0;
5137 	if (wmi_service_enabled(wma->wmi_handle,
5138 				   wmi_service_csa_offload)) {
5139 		params->csaOffloadEnable = 1;
5140 		if (wma_unified_csa_offload_enable(wma, params->smesessionId) <
5141 		    0) {
5142 			wma_err("Unable to enable CSA offload for vdev_id:%d",
5143 				params->smesessionId);
5144 		}
5145 	}
5146 
5147 	if (wmi_service_enabled(wma->wmi_handle,
5148 				wmi_service_filter_ipsec_natkeepalive)) {
5149 		if (wmi_unified_nat_keepalive_en_cmd(wma->wmi_handle,
5150 						     params->smesessionId)) {
5151 			wma_err("Unable to enable NAT keepalive for vdev_id:%d",
5152 				params->smesessionId);
5153 		}
5154 	}
5155 	qdf_atomic_set(&iface->bss_status, WMA_BSS_STATUS_STARTED);
5156 	/* Sta is now associated, configure various params */
5157 
5158 	/* Send SMPS force command to FW to send the required
5159 	 * action frame only when SM power save is enabled in
5160 	 * from INI. In case dynamic antenna selection, the
5161 	 * action frames are sent by the chain mask manager
5162 	 * In addition to the action frames, The SM power save is
5163 	 * published in the assoc request HT SMPS IE for both cases.
5164 	 */
5165 	if ((params->enableHtSmps) && (params->send_smps_action)) {
5166 		smps_param = wma_smps_mode_to_force_mode_param(
5167 			params->htSmpsconfig);
5168 		if (smps_param >= 0) {
5169 			wma_debug("Send SMPS force mode: %d",
5170 				 params->htSmpsconfig);
5171 			wma_set_mimops(wma, params->smesessionId,
5172 				smps_param);
5173 		}
5174 	}
5175 
5176 	wma_send_bss_color_change_enable(wma, params);
5177 
5178 	/* Partial AID match power save, enable when SU bformee */
5179 	if (params->enableVhtpAid && params->vhtTxBFCapable)
5180 		wma_set_ppsconfig(params->smesessionId,
5181 				  WMA_VHT_PPS_PAID_MATCH, 1);
5182 
5183 	/* Enable AMPDU power save, if htCapable/vhtCapable */
5184 	if (params->enableAmpduPs && (params->htCapable || params->vhtCapable))
5185 		wma_set_ppsconfig(params->smesessionId,
5186 				  WMA_VHT_PPS_DELIM_CRC_FAIL, 1);
5187 	if (wmi_service_enabled(wma->wmi_handle,
5188 				wmi_service_listen_interval_offload_support)) {
5189 		struct wlan_objmgr_vdev *vdev;
5190 		uint32_t moddtim;
5191 		bool is_connection_roaming_cfg_set = 0;
5192 
5193 		wma_debug("listen interval offload enabled, setting params");
5194 		status = mlme_check_index_setparam(
5195 					setparam,
5196 					wmi_vdev_param_max_li_of_moddtim,
5197 					wma->staMaxLIModDtim, index++,
5198 					MAX_VDEV_STA_REQ_PARAMS);
5199 		if (QDF_IS_STATUS_ERROR(status)) {
5200 			wma_debug("failed to send wmi_vdev_param_max_li_of_moddtim");
5201 			goto out;
5202 		}
5203 
5204 		ucfg_mlme_get_connection_roaming_ini_present(
5205 						wma->psoc,
5206 						&is_connection_roaming_cfg_set);
5207 		if (is_connection_roaming_cfg_set) {
5208 			status = mlme_check_index_setparam(
5209 					setparam,
5210 					wmi_vdev_param_max_li_of_moddtim_ms,
5211 					wma->sta_max_li_mod_dtim_ms, index++,
5212 					MAX_VDEV_STA_REQ_PARAMS);
5213 			if (QDF_IS_STATUS_ERROR(status)) {
5214 				wma_debug("failed to send wmi_vdev_param_max_li_of_moddtim_ms");
5215 				goto out;
5216 			}
5217 		}
5218 		status = mlme_check_index_setparam(
5219 						setparam,
5220 						wmi_vdev_param_dyndtim_cnt,
5221 						wma->staDynamicDtim, index++,
5222 						MAX_VDEV_STA_REQ_PARAMS);
5223 		if (QDF_IS_STATUS_ERROR(status)) {
5224 			wma_debug("failed to send wmi_vdev_param_dyndtim_cnt");
5225 			goto out;
5226 		}
5227 		vdev = wlan_objmgr_get_vdev_by_id_from_psoc(wma->psoc,
5228 							params->smesessionId,
5229 							WLAN_LEGACY_WMA_ID);
5230 		if (!vdev || !ucfg_pmo_get_moddtim_user_enable(vdev)) {
5231 			moddtim = wma->staModDtim;
5232 			status = mlme_check_index_setparam(
5233 						setparam,
5234 						wmi_vdev_param_moddtim_cnt,
5235 						moddtim, index++,
5236 						MAX_VDEV_STA_REQ_PARAMS);
5237 			if (QDF_IS_STATUS_ERROR(status)) {
5238 				wma_debug("failed to send wmi_vdev_param_moddtim_cnt");
5239 				if (vdev)
5240 					wlan_objmgr_vdev_release_ref(vdev,
5241 							WLAN_LEGACY_WMA_ID);
5242 				goto out;
5243 			}
5244 			if (vdev)
5245 				wlan_objmgr_vdev_release_ref(vdev,
5246 							    WLAN_LEGACY_WMA_ID);
5247 		} else if (vdev && ucfg_pmo_get_moddtim_user_enable(vdev) &&
5248 			   !ucfg_pmo_get_moddtim_user_active(vdev)) {
5249 			moddtim = ucfg_pmo_get_moddtim_user(vdev);
5250 			status = mlme_check_index_setparam(
5251 						setparam,
5252 						wmi_vdev_param_moddtim_cnt,
5253 						moddtim, index++,
5254 						MAX_VDEV_STA_REQ_PARAMS);
5255 			if (QDF_IS_STATUS_ERROR(status)) {
5256 				wma_debug("failed to send wmi_vdev_param_moddtim_cnt");
5257 				wlan_objmgr_vdev_release_ref(vdev,
5258 							WLAN_LEGACY_WMA_ID);
5259 				goto out;
5260 			}
5261 			wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_WMA_ID);
5262 		}
5263 		status = wma_send_multi_pdev_vdev_set_params(MLME_VDEV_SETPARAM,
5264 							params->smesessionId,
5265 							setparam, index);
5266 		if (QDF_IS_STATUS_ERROR(status)) {
5267 			wma_err("failed to send DTIM vdev setparams");
5268 			goto out;
5269 		}
5270 
5271 	} else {
5272 		wma_debug("listen interval offload is not set");
5273 	}
5274 	params->nss = iface->nss;
5275 out:
5276 	iface->aid = params->assocId;
5277 
5278 	/* Do not send add stat resp when peer assoc cnf is enabled */
5279 	if (peer_assoc_cnf)
5280 		return;
5281 
5282 	params->status = status;
5283 	wma_debug("vdev_id %d aid %d sta mac " QDF_MAC_ADDR_FMT " status %d",
5284 		  params->smesessionId, iface->aid,
5285 		  QDF_MAC_ADDR_REF(params->bssId), params->status);
5286 
5287 	/* Don't send a response during roam sync operation */
5288 	if (!wlan_cm_is_roam_sync_in_progress(wma->psoc,
5289 					      params->smesessionId) &&
5290 	    !MLME_IS_MLO_ROAM_SYNCH_IN_PROGRESS(wma->psoc,
5291 						params->smesessionId))
5292 		wma_send_msg_high_priority(wma, WMA_ADD_STA_RSP,
5293 					   (void *)params, 0);
5294 }
5295 
5296 /**
5297  * wma_delete_sta_req_ap_mode() - process delete sta request from UMAC in AP mode
5298  * @wma: wma handle
5299  * @del_sta: delete sta params
5300  *
5301  * Return: none
5302  */
5303 static void wma_delete_sta_req_ap_mode(tp_wma_handle wma,
5304 				       tpDeleteStaParams del_sta)
5305 {
5306 	struct wma_target_req *msg;
5307 	QDF_STATUS qdf_status;
5308 
5309 	qdf_status = wma_remove_peer(wma, del_sta->staMac,
5310 				     del_sta->smesessionId, false);
5311 	if (QDF_IS_STATUS_ERROR(qdf_status)) {
5312 		wma_err("wma_remove_peer failed");
5313 		del_sta->status = QDF_STATUS_E_FAILURE;
5314 		goto send_del_rsp;
5315 	}
5316 	del_sta->status = QDF_STATUS_SUCCESS;
5317 
5318 	if (wmi_service_enabled(wma->wmi_handle,
5319 				    wmi_service_sync_delete_cmds)) {
5320 		msg = wma_fill_hold_req(wma, del_sta->smesessionId,
5321 				   WMA_DELETE_STA_REQ,
5322 				   WMA_DELETE_STA_RSP_START, del_sta,
5323 				   WMA_DELETE_STA_TIMEOUT);
5324 		if (!msg) {
5325 			wma_err("Failed to allocate request. vdev_id %d",
5326 				 del_sta->smesessionId);
5327 			wma_remove_req(wma, del_sta->smesessionId,
5328 				       WMA_DELETE_STA_RSP_START);
5329 			del_sta->status = QDF_STATUS_E_NOMEM;
5330 			goto send_del_rsp;
5331 		}
5332 
5333 		wma_acquire_wakelock(&wma->wmi_cmd_rsp_wake_lock,
5334 				     WMA_FW_RSP_EVENT_WAKE_LOCK_DURATION);
5335 
5336 		return;
5337 	}
5338 
5339 send_del_rsp:
5340 	if (del_sta->respReqd) {
5341 		wma_debug("Sending del rsp to umac (status: %d)",
5342 			 del_sta->status);
5343 		wma_send_msg_high_priority(wma, WMA_DELETE_STA_RSP,
5344 					   (void *)del_sta, 0);
5345 	}
5346 }
5347 
5348 #ifdef FEATURE_WLAN_TDLS
5349 /**
5350  * wma_del_tdls_sta() - process delete sta request from UMAC in TDLS
5351  * @wma: wma handle
5352  * @del_sta: delete sta params
5353  *
5354  * Return: none
5355  */
5356 static void wma_del_tdls_sta(tp_wma_handle wma, tpDeleteStaParams del_sta)
5357 {
5358 	struct tdls_peer_update_state *peer_state;
5359 	struct wma_target_req *msg;
5360 	int status;
5361 
5362 	peer_state = qdf_mem_malloc(sizeof(*peer_state));
5363 	if (!peer_state) {
5364 		del_sta->status = QDF_STATUS_E_NOMEM;
5365 		goto send_del_rsp;
5366 	}
5367 
5368 	peer_state->peer_state = TDLS_PEER_STATE_TEARDOWN;
5369 	peer_state->vdev_id = del_sta->smesessionId;
5370 	peer_state->resp_reqd = del_sta->respReqd;
5371 	qdf_mem_copy(&peer_state->peer_macaddr,
5372 		     &del_sta->staMac, sizeof(tSirMacAddr));
5373 
5374 	wma_debug("sending tdls_peer_state for peer mac: "QDF_MAC_ADDR_FMT", peerState: %d",
5375 		  QDF_MAC_ADDR_REF(peer_state->peer_macaddr),
5376 		 peer_state->peer_state);
5377 
5378 	status = wma_update_tdls_peer_state(wma, peer_state);
5379 
5380 	if (status < 0) {
5381 		wma_err("wma_update_tdls_peer_state returned failure");
5382 		del_sta->status = QDF_STATUS_E_FAILURE;
5383 		goto send_del_rsp;
5384 	}
5385 
5386 	if (del_sta->respReqd &&
5387 			wmi_service_enabled(wma->wmi_handle,
5388 				wmi_service_sync_delete_cmds)) {
5389 		del_sta->status = QDF_STATUS_SUCCESS;
5390 		msg = wma_fill_hold_req(wma,
5391 				del_sta->smesessionId,
5392 				WMA_DELETE_STA_REQ,
5393 				WMA_DELETE_STA_RSP_START, del_sta,
5394 				WMA_DELETE_STA_TIMEOUT);
5395 		if (!msg) {
5396 			wma_err("Failed to allocate vdev_id %d",
5397 				del_sta->smesessionId);
5398 			wma_remove_req(wma,
5399 					del_sta->smesessionId,
5400 					WMA_DELETE_STA_RSP_START);
5401 			del_sta->status = QDF_STATUS_E_NOMEM;
5402 			goto send_del_rsp;
5403 		}
5404 
5405 		wma_acquire_wakelock(&wma->wmi_cmd_rsp_wake_lock,
5406 				WMA_FW_RSP_EVENT_WAKE_LOCK_DURATION);
5407 	}
5408 
5409 	return;
5410 
5411 send_del_rsp:
5412 	if (del_sta->respReqd) {
5413 		wma_debug("Sending del rsp to umac (status: %d)",
5414 			 del_sta->status);
5415 		wma_send_msg_high_priority(wma, WMA_DELETE_STA_RSP,
5416 					   (void *)del_sta, 0);
5417 	}
5418 }
5419 #endif
5420 
5421 /**
5422  * wma_delete_sta_req_sta_mode() - process delete sta request from UMAC
5423  * @wma: wma handle
5424  * @params: delete sta params
5425  *
5426  * Return: none
5427  */
5428 static void wma_delete_sta_req_sta_mode(tp_wma_handle wma,
5429 					tpDeleteStaParams params)
5430 {
5431 	QDF_STATUS status = QDF_STATUS_SUCCESS;
5432 	struct wma_txrx_node *iface;
5433 
5434 	if (wmi_service_enabled(wma->wmi_handle,
5435 		wmi_service_listen_interval_offload_support)) {
5436 		struct wlan_objmgr_vdev *vdev;
5437 
5438 		vdev = wlan_objmgr_get_vdev_by_id_from_psoc(wma->psoc,
5439 							params->smesessionId,
5440 							WLAN_LEGACY_WMA_ID);
5441 		if (vdev) {
5442 			if (ucfg_pmo_get_moddtim_user_enable(vdev))
5443 				ucfg_pmo_set_moddtim_user_enable(vdev, false);
5444 			wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_WMA_ID);
5445 		}
5446 	}
5447 
5448 	iface = &wma->interfaces[params->smesessionId];
5449 	iface->uapsd_cached_val = 0;
5450 #ifdef FEATURE_WLAN_TDLS
5451 	if (STA_ENTRY_TDLS_PEER == params->staType) {
5452 		wma_del_tdls_sta(wma, params);
5453 		return;
5454 	}
5455 #endif
5456 	params->status = status;
5457 	if (params->respReqd) {
5458 		wma_debug("vdev_id %d status %d",
5459 			 params->smesessionId, status);
5460 		wma_send_msg_high_priority(wma, WMA_DELETE_STA_RSP,
5461 					   (void *)params, 0);
5462 	}
5463 }
5464 
5465 static void wma_sap_prevent_runtime_pm(tp_wma_handle wma)
5466 {
5467 	qdf_runtime_pm_prevent_suspend(&wma->sap_prevent_runtime_pm_lock);
5468 }
5469 
5470 static void wma_sap_allow_runtime_pm(tp_wma_handle wma)
5471 {
5472 	qdf_runtime_pm_allow_suspend(&wma->sap_prevent_runtime_pm_lock);
5473 }
5474 
5475 static void wma_ndp_prevent_runtime_pm(tp_wma_handle wma)
5476 {
5477 	qdf_runtime_pm_prevent_suspend(&wma->ndp_prevent_runtime_pm_lock);
5478 }
5479 
5480 static void wma_ndp_allow_runtime_pm(tp_wma_handle wma)
5481 {
5482 	qdf_runtime_pm_allow_suspend(&wma->ndp_prevent_runtime_pm_lock);
5483 }
5484 #ifdef FEATURE_STA_MODE_VOTE_LINK
5485 static bool wma_add_sta_allow_sta_mode_vote_link(uint8_t oper_mode)
5486 {
5487 	if (oper_mode == BSS_OPERATIONAL_MODE_STA && ucfg_ipa_is_enabled())
5488 		return true;
5489 
5490 	return false;
5491 }
5492 #else /* !FEATURE_STA_MODE_VOTE_LINK */
5493 static bool wma_add_sta_allow_sta_mode_vote_link(uint8_t oper_mode)
5494 {
5495 	return false;
5496 }
5497 #endif /* FEATURE_STA_MODE_VOTE_LINK */
5498 
5499 static bool wma_is_vdev_in_sap_mode(tp_wma_handle wma, uint8_t vdev_id)
5500 {
5501 	struct wma_txrx_node *intf = wma->interfaces;
5502 
5503 	if (vdev_id >= wma->max_bssid) {
5504 		wma_err("Invalid vdev_id %hu", vdev_id);
5505 		QDF_ASSERT(0);
5506 		return false;
5507 	}
5508 
5509 	if ((intf[vdev_id].type == WMI_VDEV_TYPE_AP) &&
5510 	    (intf[vdev_id].sub_type == 0))
5511 		return true;
5512 
5513 	return false;
5514 }
5515 
5516 static bool wma_is_vdev_in_go_mode(tp_wma_handle wma, uint8_t vdev_id)
5517 {
5518 	struct wma_txrx_node *intf = wma->interfaces;
5519 
5520 	if (vdev_id >= wma->max_bssid) {
5521 		wma_err("Invalid vdev_id %hu", vdev_id);
5522 		QDF_ASSERT(0);
5523 		return false;
5524 	}
5525 
5526 	if ((intf[vdev_id].type == WMI_VDEV_TYPE_AP) &&
5527 	    (intf[vdev_id].sub_type == WMI_UNIFIED_VDEV_SUBTYPE_P2P_GO))
5528 		return true;
5529 
5530 	return false;
5531 }
5532 
5533 static void wma_sap_d3_wow_client_connect(tp_wma_handle wma)
5534 {
5535 	uint32_t num_clients;
5536 
5537 	num_clients = qdf_atomic_inc_return(&wma->sap_num_clients_connected);
5538 	wmi_debug("sap d3 wow %d client connected", num_clients);
5539 	if (num_clients == SAP_D3_WOW_MAX_CLIENT_HOLD_WAKE_LOCK) {
5540 		wmi_info("max clients connected acquire sap d3 wow wake lock");
5541 		qdf_wake_lock_acquire(&wma->sap_d3_wow_wake_lock,
5542 				      WIFI_POWER_EVENT_WAKELOCK_SAP_D3_WOW);
5543 	}
5544 }
5545 
5546 static void wma_sap_d3_wow_client_disconnect(tp_wma_handle wma)
5547 {
5548 	uint32_t num_clients;
5549 
5550 	num_clients = qdf_atomic_dec_return(&wma->sap_num_clients_connected);
5551 	wmi_debug("sap d3 wow %d client connected", num_clients);
5552 	if (num_clients == SAP_D3_WOW_MAX_CLIENT_RELEASE_WAKE_LOCK) {
5553 		wmi_info("max clients disconnected release sap d3 wow wake lock");
5554 		qdf_wake_lock_release(&wma->sap_d3_wow_wake_lock,
5555 				      WIFI_POWER_EVENT_WAKELOCK_SAP_D3_WOW);
5556 	}
5557 }
5558 
5559 static void wma_go_d3_wow_client_connect(tp_wma_handle wma)
5560 {
5561 	uint32_t num_clients;
5562 
5563 	num_clients = qdf_atomic_inc_return(&wma->go_num_clients_connected);
5564 	wmi_debug("go d3 wow %d client connected", num_clients);
5565 	if (num_clients == SAP_D3_WOW_MAX_CLIENT_HOLD_WAKE_LOCK) {
5566 		wmi_info("max clients connected acquire go d3 wow wake lock");
5567 		qdf_wake_lock_acquire(&wma->go_d3_wow_wake_lock,
5568 				      WIFI_POWER_EVENT_WAKELOCK_GO_D3_WOW);
5569 	}
5570 }
5571 
5572 static void wma_go_d3_wow_client_disconnect(tp_wma_handle wma)
5573 {
5574 	uint32_t num_clients;
5575 
5576 	num_clients = qdf_atomic_dec_return(&wma->go_num_clients_connected);
5577 	wmi_debug("go d3 wow %d client connected", num_clients);
5578 	if (num_clients == SAP_D3_WOW_MAX_CLIENT_RELEASE_WAKE_LOCK) {
5579 		wmi_info("max clients disconnected release go d3 wow wake lock");
5580 		qdf_wake_lock_release(&wma->go_d3_wow_wake_lock,
5581 				      WIFI_POWER_EVENT_WAKELOCK_GO_D3_WOW);
5582 	}
5583 }
5584 
5585 void wma_add_sta(tp_wma_handle wma, tpAddStaParams add_sta)
5586 {
5587 	uint8_t oper_mode = BSS_OPERATIONAL_MODE_STA;
5588 	void *htc_handle;
5589 	QDF_STATUS status = QDF_STATUS_SUCCESS;
5590 	uint8_t vdev_id = add_sta->smesessionId;
5591 
5592 	htc_handle = lmac_get_htc_hdl(wma->psoc);
5593 	if (!htc_handle) {
5594 		wma_err("HTC handle is NULL");
5595 		return;
5596 	}
5597 
5598 	wma_debug("Vdev %d BSSID "QDF_MAC_ADDR_FMT, vdev_id,
5599 		  QDF_MAC_ADDR_REF(add_sta->bssId));
5600 
5601 	if (wma_is_vdev_in_ap_mode(wma, vdev_id))
5602 		oper_mode = BSS_OPERATIONAL_MODE_AP;
5603 
5604 	if (WMA_IS_VDEV_IN_NDI_MODE(wma->interfaces, vdev_id))
5605 		oper_mode = BSS_OPERATIONAL_MODE_NDI;
5606 	switch (oper_mode) {
5607 	case BSS_OPERATIONAL_MODE_STA:
5608 		wma_add_sta_req_sta_mode(wma, add_sta);
5609 		break;
5610 
5611 	case BSS_OPERATIONAL_MODE_AP:
5612 		wma_add_sta_req_ap_mode(wma, add_sta);
5613 		break;
5614 	case BSS_OPERATIONAL_MODE_NDI:
5615 		wma_add_sta_ndi_mode(wma, add_sta);
5616 		break;
5617 	}
5618 
5619 	/*
5620 	 * not use add_sta after this to avoid use after free
5621 	 * as it maybe freed.
5622 	 */
5623 
5624 	/* handle wow for sap with 1 or more peer in same way */
5625 	if (wma_is_vdev_in_sap_mode(wma, vdev_id)) {
5626 		bool is_bus_suspend_allowed_in_sap_mode =
5627 			(wlan_pmo_get_sap_mode_bus_suspend(wma->psoc) &&
5628 				wmi_service_enabled(wma->wmi_handle,
5629 					wmi_service_sap_connected_d3_wow));
5630 		if (!is_bus_suspend_allowed_in_sap_mode) {
5631 			htc_vote_link_up(htc_handle, HTC_LINK_VOTE_SAP_USER_ID);
5632 			wmi_info("sap d0 wow");
5633 		} else {
5634 			wmi_debug("sap d3 wow");
5635 			wma_sap_d3_wow_client_connect(wma);
5636 		}
5637 		wma_sap_prevent_runtime_pm(wma);
5638 
5639 		return;
5640 	}
5641 
5642 	/* handle wow for p2pgo with 1 or more peer in same way */
5643 	if (wma_is_vdev_in_go_mode(wma, vdev_id)) {
5644 		bool is_bus_suspend_allowed_in_go_mode =
5645 			(wlan_pmo_get_go_mode_bus_suspend(wma->psoc) &&
5646 				wmi_service_enabled(wma->wmi_handle,
5647 					wmi_service_go_connected_d3_wow));
5648 		if (!is_bus_suspend_allowed_in_go_mode) {
5649 			htc_vote_link_up(htc_handle, HTC_LINK_VOTE_GO_USER_ID);
5650 			wmi_info("p2p go d0 wow");
5651 		} else {
5652 			wmi_info("p2p go d3 wow");
5653 			wma_go_d3_wow_client_connect(wma);
5654 		}
5655 		wma_sap_prevent_runtime_pm(wma);
5656 
5657 		return;
5658 	}
5659 
5660 	/* handle wow for nan with 1 or more peer in same way */
5661 	if (BSS_OPERATIONAL_MODE_NDI == oper_mode &&
5662 	    QDF_IS_STATUS_SUCCESS(status)) {
5663 		wma_debug("disable runtime pm and vote for link up");
5664 		htc_vote_link_up(htc_handle, HTC_LINK_VOTE_NDP_USER_ID);
5665 		wma_ndp_prevent_runtime_pm(wma);
5666 	} else if (wma_add_sta_allow_sta_mode_vote_link(oper_mode)) {
5667 		wma_debug("vote for link up");
5668 		htc_vote_link_up(htc_handle, HTC_LINK_VOTE_STA_USER_ID);
5669 	}
5670 }
5671 
5672 void wma_delete_sta(tp_wma_handle wma, tpDeleteStaParams del_sta)
5673 {
5674 	uint8_t oper_mode = BSS_OPERATIONAL_MODE_STA;
5675 	uint8_t vdev_id = del_sta->smesessionId;
5676 	bool rsp_requested = del_sta->respReqd;
5677 	void *htc_handle;
5678 	QDF_STATUS status = QDF_STATUS_SUCCESS;
5679 
5680 	htc_handle = lmac_get_htc_hdl(wma->psoc);
5681 	if (!htc_handle) {
5682 		wma_err("HTC handle is NULL");
5683 		return;
5684 	}
5685 
5686 	if (wma_is_vdev_in_ap_mode(wma, vdev_id))
5687 		oper_mode = BSS_OPERATIONAL_MODE_AP;
5688 	if (del_sta->staType == STA_ENTRY_NDI_PEER)
5689 		oper_mode = BSS_OPERATIONAL_MODE_NDI;
5690 
5691 	wma_debug("vdev %d oper_mode %d", vdev_id, oper_mode);
5692 
5693 	switch (oper_mode) {
5694 	case BSS_OPERATIONAL_MODE_STA:
5695 		if (wlan_cm_is_roam_sync_in_progress(wma->psoc, vdev_id) ||
5696 		    MLME_IS_MLO_ROAM_SYNCH_IN_PROGRESS(wma->psoc, vdev_id) ||
5697 		    mlo_is_roaming_in_progress(wma->psoc, vdev_id)) {
5698 			wma_debug("LFR3: Del STA on vdev_id %d", vdev_id);
5699 			qdf_mem_free(del_sta);
5700 			return;
5701 		}
5702 		wma_delete_sta_req_sta_mode(wma, del_sta);
5703 		if (!rsp_requested)
5704 			qdf_mem_free(del_sta);
5705 
5706 		break;
5707 
5708 	case BSS_OPERATIONAL_MODE_AP:
5709 		wma_delete_sta_req_ap_mode(wma, del_sta);
5710 		/* free the memory here only if sync feature is not enabled */
5711 		if (!rsp_requested &&
5712 		    !wmi_service_enabled(wma->wmi_handle,
5713 					 wmi_service_sync_delete_cmds))
5714 			qdf_mem_free(del_sta);
5715 		else if (!rsp_requested &&
5716 			 (del_sta->status != QDF_STATUS_SUCCESS))
5717 			qdf_mem_free(del_sta);
5718 		break;
5719 	case BSS_OPERATIONAL_MODE_NDI:
5720 		status = wma_delete_sta_req_ndi_mode(wma, del_sta);
5721 		break;
5722 	default:
5723 		wma_err("Incorrect oper mode %d", oper_mode);
5724 		qdf_mem_free(del_sta);
5725 	}
5726 
5727 	if (wma_is_vdev_in_sap_mode(wma, vdev_id)) {
5728 		bool is_bus_suspend_allowed_in_sap_mode =
5729 			(wlan_pmo_get_sap_mode_bus_suspend(wma->psoc) &&
5730 				wmi_service_enabled(wma->wmi_handle,
5731 					wmi_service_sap_connected_d3_wow));
5732 		if (!is_bus_suspend_allowed_in_sap_mode) {
5733 			htc_vote_link_down(htc_handle,
5734 					   HTC_LINK_VOTE_SAP_USER_ID);
5735 			wmi_info("sap d0 wow");
5736 		} else {
5737 			wmi_debug("sap d3 wow");
5738 			wma_sap_d3_wow_client_disconnect(wma);
5739 		}
5740 		wma_sap_allow_runtime_pm(wma);
5741 
5742 		return;
5743 	}
5744 
5745 	if (wma_is_vdev_in_go_mode(wma, vdev_id)) {
5746 		bool is_bus_suspend_allowed_in_go_mode =
5747 			(wlan_pmo_get_go_mode_bus_suspend(wma->psoc) &&
5748 				wmi_service_enabled(wma->wmi_handle,
5749 					wmi_service_go_connected_d3_wow));
5750 		if (!is_bus_suspend_allowed_in_go_mode) {
5751 			htc_vote_link_down(htc_handle,
5752 					   HTC_LINK_VOTE_GO_USER_ID);
5753 			wmi_info("p2p go d0 wow");
5754 		} else {
5755 			wmi_info("p2p go d3 wow");
5756 			wma_go_d3_wow_client_disconnect(wma);
5757 		}
5758 		wma_sap_allow_runtime_pm(wma);
5759 
5760 		return;
5761 	}
5762 
5763 	if (BSS_OPERATIONAL_MODE_NDI == oper_mode &&
5764 	    QDF_IS_STATUS_SUCCESS(status)) {
5765 		wma_debug("allow runtime pm and vote for link down");
5766 		htc_vote_link_down(htc_handle, HTC_LINK_VOTE_NDP_USER_ID);
5767 		wma_ndp_allow_runtime_pm(wma);
5768 	} else if (wma_add_sta_allow_sta_mode_vote_link(oper_mode)) {
5769 		wma_debug("vote for link down");
5770 		htc_vote_link_down(htc_handle, HTC_LINK_VOTE_STA_USER_ID);
5771 	}
5772 }
5773 
5774 void wma_delete_bss_ho_fail(tp_wma_handle wma, uint8_t vdev_id)
5775 {
5776 	QDF_STATUS status = QDF_STATUS_SUCCESS;
5777 	struct wma_txrx_node *iface;
5778 	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
5779 	struct vdev_stop_response resp_event;
5780 	struct del_bss_resp *vdev_stop_resp;
5781 	uint8_t *bssid;
5782 
5783 	iface = &wma->interfaces[vdev_id];
5784 	if (!iface) {
5785 		wma_err("iface for vdev_id %d is already deleted", vdev_id);
5786 		goto fail_del_bss_ho_fail;
5787 	}
5788 	bssid = wma_get_vdev_bssid(iface->vdev);
5789 	if (!bssid) {
5790 		wma_err("Invalid bssid");
5791 		status = QDF_STATUS_E_FAILURE;
5792 		goto fail_del_bss_ho_fail;
5793 	}
5794 	qdf_mem_zero(bssid, QDF_MAC_ADDR_SIZE);
5795 
5796 	if (iface->psnr_req) {
5797 		qdf_mem_free(iface->psnr_req);
5798 		iface->psnr_req = NULL;
5799 	}
5800 
5801 	if (iface->rcpi_req) {
5802 		struct sme_rcpi_req *rcpi_req = iface->rcpi_req;
5803 
5804 		iface->rcpi_req = NULL;
5805 		qdf_mem_free(rcpi_req);
5806 	}
5807 
5808 	if (iface->roam_scan_stats_req) {
5809 		struct sir_roam_scan_stats *roam_scan_stats_req =
5810 						iface->roam_scan_stats_req;
5811 
5812 		iface->roam_scan_stats_req = NULL;
5813 		qdf_mem_free(roam_scan_stats_req);
5814 	}
5815 
5816 	wma_debug("vdev_id: %d, pausing tx_ll_queue for VDEV_STOP (del_bss)",
5817 		 vdev_id);
5818 	cdp_fc_vdev_pause(soc, vdev_id, OL_TXQ_PAUSE_REASON_VDEV_STOP, 0);
5819 	wma_vdev_set_pause_bit(vdev_id, PAUSE_TYPE_HOST);
5820 	cdp_fc_vdev_flush(soc, vdev_id);
5821 	wma_debug("vdev_id: %d, un-pausing tx_ll_queue for VDEV_STOP rsp",
5822 		 vdev_id);
5823 	cdp_fc_vdev_unpause(soc, vdev_id, OL_TXQ_PAUSE_REASON_VDEV_STOP, 0);
5824 	wma_vdev_clear_pause_bit(vdev_id, PAUSE_TYPE_HOST);
5825 	qdf_atomic_set(&iface->bss_status, WMA_BSS_STATUS_STOPPED);
5826 	wma_debug("(type %d subtype %d) BSS is stopped",
5827 			iface->type, iface->sub_type);
5828 
5829 	status = mlme_set_vdev_stop_type(iface->vdev,
5830 					 WMA_DELETE_BSS_HO_FAIL_REQ);
5831 	if (QDF_IS_STATUS_ERROR(status)) {
5832 		wma_err("Failed to set wma req msg_type for vdev_id: %d",
5833 			vdev_id);
5834 		goto fail_del_bss_ho_fail;
5835 	}
5836 
5837 	/* Try to use the vdev stop response path */
5838 	resp_event.vdev_id = vdev_id;
5839 	status = wma_handle_vdev_stop_rsp(wma, &resp_event);
5840 	if (QDF_IS_STATUS_ERROR(status)) {
5841 		wma_err("Failed to handle vdev stop rsp for vdev_id %d",
5842 			vdev_id);
5843 		goto fail_del_bss_ho_fail;
5844 	}
5845 
5846 	return;
5847 
5848 fail_del_bss_ho_fail:
5849 	vdev_stop_resp = qdf_mem_malloc(sizeof(*vdev_stop_resp));
5850 	if (!vdev_stop_resp)
5851 		return;
5852 
5853 	vdev_stop_resp->vdev_id = vdev_id;
5854 	vdev_stop_resp->status = status;
5855 	wma_send_msg_high_priority(wma, WMA_DELETE_BSS_HO_FAIL_RSP,
5856 				   (void *)vdev_stop_resp, 0);
5857 }
5858 
5859 /**
5860  * wma_wait_tx_complete() - Wait till tx packets are drained
5861  * @wma: wma handle
5862  * @session_id: vdev id
5863  *
5864  * Return: none
5865  */
5866 static void wma_wait_tx_complete(tp_wma_handle wma,
5867 				uint32_t session_id)
5868 {
5869 	uint8_t max_wait_iterations = 0, delay = 0;
5870 	cdp_config_param_type val;
5871 	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
5872 	QDF_STATUS status;
5873 
5874 	if (!wma_is_vdev_valid(session_id)) {
5875 		wma_err("Vdev is not valid: %d", session_id);
5876 		return;
5877 	}
5878 
5879 	status = ucfg_mlme_get_delay_before_vdev_stop(wma->psoc, &delay);
5880 	if (QDF_IS_STATUS_ERROR(status))
5881 		wma_err("Failed to get delay before vdev stop");
5882 
5883 	max_wait_iterations = delay / WMA_TX_Q_RECHECK_TIMER_WAIT;
5884 	if (cdp_txrx_get_pdev_param(soc,
5885 				    wlan_objmgr_pdev_get_pdev_id(wma->pdev),
5886 				    CDP_TX_PENDING, &val))
5887 		return;
5888 	while (val.cdp_pdev_param_tx_pending && max_wait_iterations) {
5889 		wma_warn("Waiting for outstanding packet to drain");
5890 		qdf_wait_for_event_completion(&wma->tx_queue_empty_event,
5891 				      WMA_TX_Q_RECHECK_TIMER_WAIT);
5892 		if (cdp_txrx_get_pdev_param(
5893 					soc,
5894 					wlan_objmgr_pdev_get_pdev_id(wma->pdev),
5895 					CDP_TX_PENDING, &val))
5896 			return;
5897 		max_wait_iterations--;
5898 	}
5899 }
5900 
5901 void wma_delete_bss(tp_wma_handle wma, uint8_t vdev_id)
5902 {
5903 	bool peer_exist = false;
5904 	QDF_STATUS status = QDF_STATUS_SUCCESS;
5905 	uint32_t tx_pending = 0;
5906 	cdp_config_param_type val;
5907 	bool roam_synch_in_progress = false;
5908 	struct wma_txrx_node *iface;
5909 	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
5910 	struct qdf_mac_addr bssid;
5911 	struct del_bss_resp *params;
5912 	uint8_t *addr, *bssid_addr;
5913 
5914 	iface = &wma->interfaces[vdev_id];
5915 	if (!iface || !iface->vdev) {
5916 		wma_err("vdev id %d is already deleted", vdev_id);
5917 		goto out;
5918 	}
5919 
5920 	status = wlan_vdev_get_bss_peer_mac(iface->vdev, &bssid);
5921 	if (QDF_IS_STATUS_ERROR(status)) {
5922 		wma_err("vdev id %d : failed to get bssid", vdev_id);
5923 		goto out;
5924 	}
5925 
5926 	addr = wlan_vdev_mlme_get_macaddr(iface->vdev);
5927 	if (!addr) {
5928 		wma_err("vdev id %d : failed to get macaddr", vdev_id);
5929 		goto out;
5930 	}
5931 
5932 	if (WMA_IS_VDEV_IN_NDI_MODE(wma->interfaces,
5933 			vdev_id))
5934 		/* In ndi case, self mac is used to create the self peer */
5935 		peer_exist = wma_cdp_find_peer_by_addr(addr);
5936 	else
5937 		peer_exist = wma_cdp_find_peer_by_addr(bssid.bytes);
5938 	if (!peer_exist) {
5939 		wma_err("Failed to find peer "QDF_MAC_ADDR_FMT,
5940 			 QDF_MAC_ADDR_REF(bssid.bytes));
5941 		status = QDF_STATUS_E_FAILURE;
5942 		goto out;
5943 	}
5944 	bssid_addr = wma_get_vdev_bssid(wma->interfaces[vdev_id].vdev);
5945 	if (!bssid_addr) {
5946 		wma_err("Failed to bssid for vdev_%d", vdev_id);
5947 		status = QDF_STATUS_E_FAILURE;
5948 		goto out;
5949 	}
5950 	qdf_mem_zero(bssid_addr,
5951 		     QDF_MAC_ADDR_SIZE);
5952 
5953 	wma_delete_invalid_peer_entries(vdev_id, NULL);
5954 
5955 	if (iface->psnr_req) {
5956 		qdf_mem_free(iface->psnr_req);
5957 		iface->psnr_req = NULL;
5958 	}
5959 
5960 	if (iface->rcpi_req) {
5961 		struct sme_rcpi_req *rcpi_req = iface->rcpi_req;
5962 
5963 		iface->rcpi_req = NULL;
5964 		qdf_mem_free(rcpi_req);
5965 	}
5966 
5967 	if (iface->roam_scan_stats_req) {
5968 		struct sir_roam_scan_stats *roam_scan_stats_req =
5969 						iface->roam_scan_stats_req;
5970 
5971 		iface->roam_scan_stats_req = NULL;
5972 		qdf_mem_free(roam_scan_stats_req);
5973 	}
5974 
5975 	if (wlan_cm_is_roam_sync_in_progress(wma->psoc, vdev_id) ||
5976 	    MLME_IS_MLO_ROAM_SYNCH_IN_PROGRESS(wma->psoc, vdev_id) ||
5977 	    mlo_is_roaming_in_progress(wma->psoc, vdev_id)) {
5978 		roam_synch_in_progress = true;
5979 		wma_debug("LFR3: Setting vdev_up to FALSE for vdev:%d",
5980 			  vdev_id);
5981 
5982 		goto detach_peer;
5983 	}
5984 
5985 	status = mlme_set_vdev_stop_type(iface->vdev,
5986 					 WMA_DELETE_BSS_REQ);
5987 	if (QDF_IS_STATUS_ERROR(status)) {
5988 		wma_err("Failed to set wma req msg_type for vdev_id: %d",
5989 			vdev_id);
5990 		goto out;
5991 	}
5992 
5993 	cdp_txrx_get_pdev_param(soc, wlan_objmgr_pdev_get_pdev_id(wma->pdev),
5994 				CDP_TX_PENDING, &val);
5995 	tx_pending = val.cdp_pdev_param_tx_pending;
5996 	wma_debug("Outstanding msdu packets: %u", tx_pending);
5997 	wma_wait_tx_complete(wma, vdev_id);
5998 
5999 	cdp_txrx_get_pdev_param(soc, wlan_objmgr_pdev_get_pdev_id(wma->pdev),
6000 				CDP_TX_PENDING, &val);
6001 	if (tx_pending) {
6002 		wma_debug("Outstanding msdu packets before VDEV_STOP : %u",
6003 			 tx_pending);
6004 	}
6005 
6006 	wma_debug("vdev_id: %d, pausing tx_ll_queue for VDEV_STOP (del_bss)",
6007 		 vdev_id);
6008 	wma_vdev_set_pause_bit(vdev_id, PAUSE_TYPE_HOST);
6009 	cdp_fc_vdev_pause(soc, vdev_id,
6010 			  OL_TXQ_PAUSE_REASON_VDEV_STOP, 0);
6011 
6012 	if (wma_send_vdev_stop_to_fw(wma, vdev_id)) {
6013 		struct vdev_stop_response vdev_stop_rsp = {0};
6014 
6015 		wma_err("Failed to send vdev stop to FW, explicitly invoke vdev stop rsp");
6016 		vdev_stop_rsp.vdev_id = vdev_id;
6017 		wma_handle_vdev_stop_rsp(wma, &vdev_stop_rsp);
6018 		qdf_atomic_set(&iface->bss_status, WMA_BSS_STATUS_STOPPED);
6019 	}
6020 	wma_debug("bssid "QDF_MAC_ADDR_FMT" vdev_id %d",
6021 		  QDF_MAC_ADDR_REF(bssid.bytes), vdev_id);
6022 
6023 	return;
6024 
6025 detach_peer:
6026 	wma_remove_peer(wma, bssid.bytes, vdev_id, roam_synch_in_progress);
6027 	if (roam_synch_in_progress)
6028 		return;
6029 
6030 out:
6031 	/* skip when legacy to mlo roam sync ongoing */
6032 	if (MLME_IS_MLO_ROAM_SYNCH_IN_PROGRESS(wma->psoc, vdev_id))
6033 		return;
6034 
6035 	params = qdf_mem_malloc(sizeof(*params));
6036 	if (!params)
6037 		return;
6038 
6039 	params->vdev_id = vdev_id;
6040 	params->status = status;
6041 	wma_send_msg_high_priority(wma, WMA_DELETE_BSS_RSP, params, 0);
6042 }
6043 
6044 /**
6045  * wma_find_ibss_vdev() - This function finds vdev_id based on input type
6046  * @wma: wma handle
6047  * @type: vdev type
6048  *
6049  * Return: vdev id
6050  */
6051 int32_t wma_find_vdev_by_type(tp_wma_handle wma, int32_t type)
6052 {
6053 	int32_t vdev_id = 0;
6054 	struct wma_txrx_node *intf = wma->interfaces;
6055 
6056 	for (vdev_id = 0; vdev_id < wma->max_bssid; vdev_id++) {
6057 		if (intf) {
6058 			if (intf[vdev_id].type == type)
6059 				return vdev_id;
6060 		}
6061 	}
6062 
6063 	return -EFAULT;
6064 }
6065 
6066 void wma_set_vdev_intrabss_fwd(tp_wma_handle wma_handle,
6067 				      tpDisableIntraBssFwd pdis_intra_fwd)
6068 {
6069 	struct wlan_objmgr_vdev *vdev;
6070 
6071 	wma_debug("intra_fwd:vdev(%d) intrabss_dis=%s",
6072 		 pdis_intra_fwd->sessionId,
6073 		 (pdis_intra_fwd->disableintrabssfwd ? "true" : "false"));
6074 
6075 	vdev = wma_handle->interfaces[pdis_intra_fwd->sessionId].vdev;
6076 	cdp_cfg_vdev_rx_set_intrabss_fwd(cds_get_context(QDF_MODULE_ID_SOC),
6077 					 pdis_intra_fwd->sessionId,
6078 					 pdis_intra_fwd->disableintrabssfwd);
6079 }
6080 
6081 /**
6082  * wma_get_pdev_from_scn_handle() - API to get pdev from scn handle
6083  * @scn_handle: opaque wma handle
6084  *
6085  * API to get pdev from scn handle
6086  *
6087  * Return: None
6088  */
6089 static struct wlan_objmgr_pdev *wma_get_pdev_from_scn_handle(void *scn_handle)
6090 {
6091 	tp_wma_handle wma_handle;
6092 
6093 	if (!scn_handle) {
6094 		wma_err("invalid scn handle");
6095 		return NULL;
6096 	}
6097 	wma_handle = (tp_wma_handle)scn_handle;
6098 
6099 	return wma_handle->pdev;
6100 }
6101 
6102 void wma_store_pdev(void *wma_ctx, struct wlan_objmgr_pdev *pdev)
6103 {
6104 	tp_wma_handle wma = (tp_wma_handle)wma_ctx;
6105 	QDF_STATUS status;
6106 
6107 	status = wlan_objmgr_pdev_try_get_ref(pdev, WLAN_LEGACY_WMA_ID);
6108 	if (QDF_STATUS_SUCCESS != status) {
6109 		wma->pdev = NULL;
6110 		return;
6111 	}
6112 
6113 	wma->pdev = pdev;
6114 
6115 	target_if_store_pdev_target_if_ctx(wma_get_pdev_from_scn_handle);
6116 	target_pdev_set_wmi_handle(wma->pdev->tgt_if_handle,
6117 				   wma->wmi_handle);
6118 }
6119 
6120 /**
6121  * wma_vdev_reset_beacon_interval_timer() - reset beacon interval back
6122  * to its original value after the channel switch.
6123  *
6124  * @data: data
6125  *
6126  * Return: void
6127  */
6128 static void wma_vdev_reset_beacon_interval_timer(void *data)
6129 {
6130 	tp_wma_handle wma;
6131 	struct wma_beacon_interval_reset_req *req =
6132 		(struct wma_beacon_interval_reset_req *)data;
6133 	uint16_t beacon_interval = req->interval;
6134 	uint8_t vdev_id = req->vdev_id;
6135 
6136 	wma = (tp_wma_handle)cds_get_context(QDF_MODULE_ID_WMA);
6137 	if (!wma)
6138 		goto end;
6139 
6140 	/* Change the beacon interval back to its original value */
6141 	wma_debug("Change beacon interval back to %d", beacon_interval);
6142 	wma_update_beacon_interval(wma, vdev_id, beacon_interval);
6143 
6144 end:
6145 	qdf_timer_stop(&req->event_timeout);
6146 	qdf_timer_free(&req->event_timeout);
6147 	qdf_mem_free(req);
6148 }
6149 
6150 int wma_fill_beacon_interval_reset_req(tp_wma_handle wma, uint8_t vdev_id,
6151 				uint16_t beacon_interval, uint32_t timeout)
6152 {
6153 	struct wma_beacon_interval_reset_req *req;
6154 
6155 	req = qdf_mem_malloc(sizeof(*req));
6156 	if (!req)
6157 		return -ENOMEM;
6158 
6159 	wma_debug("vdev_id %d ", vdev_id);
6160 	req->vdev_id = vdev_id;
6161 	req->interval = beacon_interval;
6162 	qdf_timer_init(NULL, &req->event_timeout,
6163 		wma_vdev_reset_beacon_interval_timer, req, QDF_TIMER_TYPE_SW);
6164 	qdf_timer_start(&req->event_timeout, timeout);
6165 
6166 	return 0;
6167 }
6168 
6169 QDF_STATUS wma_set_wlm_latency_level(void *wma_ptr,
6170 			struct wlm_latency_level_param *latency_params)
6171 {
6172 	QDF_STATUS ret;
6173 	tp_wma_handle wma = (tp_wma_handle)wma_ptr;
6174 
6175 	wma_debug("set latency level %d, fw wlm_latency_flags 0x%x",
6176 		 latency_params->wlm_latency_level,
6177 		 latency_params->wlm_latency_flags);
6178 
6179 	ret = wmi_unified_wlm_latency_level_cmd(wma->wmi_handle,
6180 						latency_params);
6181 	if (QDF_IS_STATUS_ERROR(ret))
6182 		wma_warn("Failed to set latency level");
6183 
6184 	return ret;
6185 }
6186 
6187 QDF_STATUS wma_add_bss_peer_sta(uint8_t vdev_id, uint8_t *bssid,
6188 				bool is_resp_required,
6189 				uint8_t *mld_mac, bool is_assoc_peer)
6190 {
6191 	tp_wma_handle wma;
6192 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
6193 
6194 	wma = cds_get_context(QDF_MODULE_ID_WMA);
6195 	if (!wma)
6196 		goto err;
6197 
6198 	if (is_resp_required)
6199 		status = wma_create_sta_mode_bss_peer(wma, bssid,
6200 						      WMI_PEER_TYPE_DEFAULT,
6201 						      vdev_id, mld_mac,
6202 						      is_assoc_peer);
6203 	else
6204 		status = wma_create_peer(wma, bssid, WMI_PEER_TYPE_DEFAULT,
6205 					 vdev_id, mld_mac, is_assoc_peer);
6206 err:
6207 	return status;
6208 }
6209 
6210 QDF_STATUS wma_send_vdev_stop(uint8_t vdev_id)
6211 {
6212 	tp_wma_handle wma;
6213 	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
6214 	QDF_STATUS status;
6215 
6216 	wma = cds_get_context(QDF_MODULE_ID_WMA);
6217 	if (!wma)
6218 		return QDF_STATUS_E_FAILURE;
6219 
6220 	wma_debug("vdev_id: %d, pausing tx_ll_queue for VDEV_STOP", vdev_id);
6221 	cdp_fc_vdev_pause(soc, vdev_id,
6222 			  OL_TXQ_PAUSE_REASON_VDEV_STOP, 0);
6223 
6224 	status = mlme_set_vdev_stop_type(
6225 				wma->interfaces[vdev_id].vdev,
6226 				WMA_SET_LINK_STATE);
6227 	if (QDF_IS_STATUS_ERROR(status)) {
6228 		wma_alert("Failed to set wma req msg_type for vdev_id %d",
6229 			 vdev_id);
6230 		return QDF_STATUS_E_FAILURE;
6231 	}
6232 
6233 	wma_vdev_set_pause_bit(vdev_id, PAUSE_TYPE_HOST);
6234 
6235 	status = wma_send_vdev_stop_to_fw(wma, vdev_id);
6236 	if (QDF_IS_STATUS_ERROR(status)) {
6237 		struct vdev_stop_response resp_event;
6238 
6239 		wma_info("vdev %d Failed to send vdev stop", vdev_id);
6240 		resp_event.vdev_id = vdev_id;
6241 		mlme_set_connection_fail(wma->interfaces[vdev_id].vdev, false);
6242 		wma_handle_vdev_stop_rsp(wma, &resp_event);
6243 	}
6244 
6245 	/*
6246 	 * Remove peer, Vdev down and sending set link
6247 	 * response will be handled in vdev stop response
6248 	 * handler
6249 	 */
6250 
6251 	return QDF_STATUS_SUCCESS;
6252 }
6253 
6254 #define TX_MGMT_RATE_2G_ENABLE_OFFSET 30
6255 #define TX_MGMT_RATE_5G_ENABLE_OFFSET 31
6256 #define TX_MGMT_RATE_2G_OFFSET 0
6257 #define TX_MGMT_RATE_5G_OFFSET 12
6258 
6259 /**
6260  * wma_verify_rate_code() - verify if rate code is valid.
6261  * @rate_code: rate code
6262  * @band: band information
6263  *
6264  * Return: verify result
6265  */
6266 static bool wma_verify_rate_code(uint32_t rate_code, enum cds_band_type band)
6267 {
6268 	uint8_t preamble, nss, rate;
6269 	bool valid = true;
6270 
6271 	preamble = (rate_code & 0xc0) >> 6;
6272 	nss = (rate_code & 0x30) >> 4;
6273 	rate = rate_code & 0xf;
6274 
6275 	switch (preamble) {
6276 	case WMI_RATE_PREAMBLE_CCK:
6277 		if (nss != 0 || rate > 3 || band == CDS_BAND_5GHZ)
6278 			valid = false;
6279 		break;
6280 	case WMI_RATE_PREAMBLE_OFDM:
6281 		if (nss != 0 || rate > 7)
6282 			valid = false;
6283 		break;
6284 	case WMI_RATE_PREAMBLE_HT:
6285 		if (nss != 0 || rate > 7)
6286 			valid = false;
6287 		break;
6288 	case WMI_RATE_PREAMBLE_VHT:
6289 		if (nss != 0 || rate > 9)
6290 			valid = false;
6291 		break;
6292 	default:
6293 		break;
6294 	}
6295 	return valid;
6296 }
6297 
6298 /**
6299  * wma_vdev_mgmt_tx_rate() - set vdev mgmt rate.
6300  * @info: pointer to vdev set param.
6301  *
6302  * Return: return status
6303  */
6304 static QDF_STATUS wma_vdev_mgmt_tx_rate(struct dev_set_param *info)
6305 {
6306 	uint32_t cfg_val;
6307 	enum cds_band_type band = 0;
6308 	QDF_STATUS status;
6309 	struct mac_context *mac = cds_get_context(QDF_MODULE_ID_PE);
6310 
6311 	if (!mac) {
6312 		wma_err("Failed to get mac");
6313 		return QDF_STATUS_E_FAILURE;
6314 	}
6315 
6316 	cfg_val = mac->mlme_cfg->sap_cfg.rate_tx_mgmt;
6317 	band = CDS_BAND_ALL;
6318 	if (cfg_val == MLME_CFG_TX_MGMT_RATE_DEF ||
6319 	    !wma_verify_rate_code(cfg_val, band)) {
6320 		wma_nofl_debug("default WNI_CFG_RATE_FOR_TX_MGMT, ignore");
6321 		status = QDF_STATUS_E_FAILURE;
6322 	} else {
6323 		info->param_id = wmi_vdev_param_mgmt_tx_rate;
6324 		info->param_value = cfg_val;
6325 		status = QDF_STATUS_SUCCESS;
6326 	}
6327 	return status;
6328 }
6329 
6330 /**
6331  * wma_vdev_mgmt_perband_tx_rate() - set vdev mgmt perband tx rate.
6332  * @info: pointer to vdev set param
6333  *
6334  * Return: returns status
6335  */
6336 static QDF_STATUS wma_vdev_mgmt_perband_tx_rate(struct dev_set_param *info)
6337 {
6338 	uint32_t cfg_val;
6339 	uint32_t per_band_mgmt_tx_rate = 0;
6340 	enum cds_band_type band = 0;
6341 	struct mac_context *mac = cds_get_context(QDF_MODULE_ID_PE);
6342 
6343 	if (!mac) {
6344 		wma_err("failed to get mac");
6345 		return QDF_STATUS_E_FAILURE;
6346 	}
6347 
6348 	cfg_val = mac->mlme_cfg->sap_cfg.rate_tx_mgmt_2g;
6349 	band = CDS_BAND_2GHZ;
6350 	if (cfg_val == MLME_CFG_TX_MGMT_2G_RATE_DEF ||
6351 	    !wma_verify_rate_code(cfg_val, band)) {
6352 		wma_nofl_debug("use default 2G MGMT rate.");
6353 		per_band_mgmt_tx_rate &=
6354 		    ~(1 << TX_MGMT_RATE_2G_ENABLE_OFFSET);
6355 	} else {
6356 		per_band_mgmt_tx_rate |=
6357 		    (1 << TX_MGMT_RATE_2G_ENABLE_OFFSET);
6358 		per_band_mgmt_tx_rate |=
6359 		    ((cfg_val & 0x7FF) << TX_MGMT_RATE_2G_OFFSET);
6360 	}
6361 
6362 	cfg_val = mac->mlme_cfg->sap_cfg.rate_tx_mgmt;
6363 	band = CDS_BAND_5GHZ;
6364 	if (cfg_val == MLME_CFG_TX_MGMT_5G_RATE_DEF ||
6365 	    !wma_verify_rate_code(cfg_val, band)) {
6366 		wma_nofl_debug("use default 5G MGMT rate.");
6367 		per_band_mgmt_tx_rate &=
6368 		    ~(1 << TX_MGMT_RATE_5G_ENABLE_OFFSET);
6369 	} else {
6370 		per_band_mgmt_tx_rate |=
6371 		    (1 << TX_MGMT_RATE_5G_ENABLE_OFFSET);
6372 		per_band_mgmt_tx_rate |=
6373 		    ((cfg_val & 0x7FF) << TX_MGMT_RATE_5G_OFFSET);
6374 	}
6375 
6376 	info->param_id = wmi_vdev_param_per_band_mgmt_tx_rate;
6377 	info->param_value = per_band_mgmt_tx_rate;
6378 	return QDF_STATUS_SUCCESS;
6379 }
6380 
6381 #define MAX_VDEV_CREATE_PARAMS 21
6382 /* params being sent:
6383  * 1.wmi_vdev_param_wmm_txop_enable
6384  * 2.wmi_vdev_param_disconnect_th
6385  * 3.wmi_vdev_param_mcc_rtscts_protection_enable
6386  * 4.wmi_vdev_param_mcc_broadcast_probe_enable
6387  * 5.wmi_vdev_param_rts_threshold
6388  * 6.wmi_vdev_param_fragmentation_threshold
6389  * 7.wmi_vdev_param_tx_stbc
6390  * 8.wmi_vdev_param_mgmt_tx_rate
6391  * 9.wmi_vdev_param_per_band_mgmt_tx_rate
6392  * 10.wmi_vdev_param_set_eht_mu_mode
6393  * 11.wmi_vdev_param_set_hemu_mode
6394  * 12.wmi_vdev_param_txbf
6395  * 13.wmi_vdev_param_enable_bcast_probe_response
6396  * 14.wmi_vdev_param_fils_max_channel_guard_time
6397  * 15.wmi_vdev_param_probe_delay
6398  * 16.wmi_vdev_param_repeat_probe_time
6399  * 17.wmi_vdev_param_enable_disable_oce_features
6400  * 18.wmi_vdev_param_bmiss_first_bcnt
6401  * 19.wmi_vdev_param_bmiss_final_bcnt
6402  * 20.wmi_vdev_param_set_sap_ps_with_twt
6403  * 21.wmi_vdev_param_disable_2g_twt
6404  */
6405 
6406 QDF_STATUS wma_vdev_create_set_param(struct wlan_objmgr_vdev *vdev)
6407 {
6408 	QDF_STATUS status;
6409 	struct mlme_ht_capabilities_info *ht_cap_info;
6410 	uint32_t cfg_val;
6411 	struct mac_context *mac = cds_get_context(QDF_MODULE_ID_PE);
6412 	struct dev_set_param ext_val;
6413 	wmi_vdev_txbf_en txbf_en = {0};
6414 	struct vdev_mlme_obj *vdev_mlme;
6415 	uint8_t vdev_id;
6416 	uint32_t hemu_mode;
6417 	struct dev_set_param setparam[MAX_VDEV_CREATE_PARAMS];
6418 	uint8_t index = 0;
6419 	bool is_24ghz_twt_enabled;
6420 	enum QDF_OPMODE opmode;
6421 
6422 	if (!mac)
6423 		return QDF_STATUS_E_FAILURE;
6424 
6425 	vdev_id = wlan_vdev_get_id(vdev);
6426 
6427 	vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev);
6428 	if (!vdev_mlme) {
6429 		wma_err("Failed to get vdev mlme obj!");
6430 		return QDF_STATUS_E_FAILURE;
6431 	}
6432 
6433 	status = mlme_check_index_setparam(
6434 				setparam, wmi_vdev_param_wmm_txop_enable,
6435 				mac->mlme_cfg->edca_params.enable_wmm_txop,
6436 				index++, MAX_VDEV_CREATE_PARAMS);
6437 	if (QDF_IS_STATUS_ERROR(status)) {
6438 		wma_debug("failed to set wmi_vdev_param_wmm_txop_enable");
6439 		goto error;
6440 	}
6441 	wma_debug("Setting wmi_vdev_param_disconnect_th: %d",
6442 		  mac->mlme_cfg->gen.dropped_pkt_disconnect_thresh);
6443 	status = mlme_check_index_setparam(
6444 			setparam, wmi_vdev_param_disconnect_th,
6445 			mac->mlme_cfg->gen.dropped_pkt_disconnect_thresh,
6446 			index++, MAX_VDEV_CREATE_PARAMS);
6447 	if (QDF_IS_STATUS_ERROR(status)) {
6448 		wma_debug("failed to set wmi_vdev_param_disconnect_th");
6449 		goto error;
6450 	}
6451 	status = mlme_check_index_setparam(
6452 				 setparam,
6453 				 wmi_vdev_param_mcc_rtscts_protection_enable,
6454 				 mac->roam.configParam.mcc_rts_cts_prot_enable,
6455 				 index++, MAX_VDEV_CREATE_PARAMS);
6456 	if (QDF_IS_STATUS_ERROR(status)) {
6457 		wma_debug("failed to set wmi_vdev_param_mcc_rtscts_protection_enable");
6458 		goto error;
6459 	}
6460 	status = mlme_check_index_setparam(
6461 			setparam,
6462 			wmi_vdev_param_mcc_broadcast_probe_enable,
6463 			mac->roam.configParam.mcc_bcast_prob_resp_enable,
6464 			index++, MAX_VDEV_CREATE_PARAMS);
6465 	if (QDF_IS_STATUS_ERROR(status)) {
6466 		wma_debug("failed to set wmi_vdev_param_mcc_broadcast_probe_enable");
6467 		goto error;
6468 	}
6469 	if (wlan_mlme_get_rts_threshold(mac->psoc, &cfg_val) ==
6470 							QDF_STATUS_SUCCESS) {
6471 		status = mlme_check_index_setparam(
6472 					      setparam,
6473 					      wmi_vdev_param_rts_threshold,
6474 					      cfg_val, index++,
6475 					      MAX_VDEV_CREATE_PARAMS);
6476 		if (QDF_IS_STATUS_ERROR(status)) {
6477 			wma_debug("failed to set wmi_vdev_param_rts_threshold");
6478 			goto error;
6479 		}
6480 	} else {
6481 		wma_err("Fail to get val for rts threshold, leave unchanged");
6482 	}
6483 	if (wlan_mlme_get_frag_threshold(mac->psoc, &cfg_val) ==
6484 		 QDF_STATUS_SUCCESS) {
6485 		status = mlme_check_index_setparam(
6486 					setparam,
6487 					wmi_vdev_param_fragmentation_threshold,
6488 					cfg_val, index++,
6489 					MAX_VDEV_CREATE_PARAMS);
6490 		if (QDF_IS_STATUS_ERROR(status)) {
6491 			wma_debug("failed to set wmi_vdev_param_fragmentation_threshold");
6492 			goto error;
6493 		}
6494 	} else {
6495 		wma_err("Fail to get val for frag threshold, leave unchanged");
6496 	}
6497 
6498 	ht_cap_info = &mac->mlme_cfg->ht_caps.ht_cap_info;
6499 	status = mlme_check_index_setparam(setparam,
6500 					   wmi_vdev_param_tx_stbc,
6501 					   ht_cap_info->tx_stbc, index++,
6502 					   MAX_VDEV_CREATE_PARAMS);
6503 	if (QDF_IS_STATUS_ERROR(status)) {
6504 		wma_debug("failed to set wmi_vdev_param_tx_stbc");
6505 		goto error;
6506 	}
6507 	if (!wma_vdev_mgmt_tx_rate(&ext_val)) {
6508 		status = mlme_check_index_setparam(setparam, ext_val.param_id,
6509 						   ext_val.param_value, index++,
6510 						   MAX_VDEV_CREATE_PARAMS);
6511 		if (QDF_IS_STATUS_ERROR(status)) {
6512 			wma_debug("failed to set param for MGMT RATE");
6513 			goto error;
6514 		}
6515 	}
6516 	if (!wma_vdev_mgmt_perband_tx_rate(&ext_val)) {
6517 		status = mlme_check_index_setparam(setparam, ext_val.param_id,
6518 						   ext_val.param_value, index++,
6519 						   MAX_VDEV_CREATE_PARAMS);
6520 		if (QDF_IS_STATUS_ERROR(status)) {
6521 			wma_debug("failed to set PERBAND_MGMT RATE");
6522 			goto error;
6523 		}
6524 	}
6525 	if (IS_FEATURE_11BE_SUPPORTED_BY_FW) {
6526 		uint32_t mode;
6527 
6528 		status = wma_set_eht_txbf_vdev_params(mac, &mode);
6529 		if (status == QDF_STATUS_SUCCESS) {
6530 			wma_debug("set EHTMU_MODE (ehtmu_mode = 0x%x)", mode);
6531 			status = mlme_check_index_setparam(
6532 						setparam,
6533 						wmi_vdev_param_set_eht_mu_mode,
6534 						mode, index++,
6535 						MAX_VDEV_CREATE_PARAMS);
6536 			if (QDF_IS_STATUS_ERROR(status)) {
6537 				wma_debug("failed to set wmi_vdev_param_set_eht_mu_mode");
6538 				goto error;
6539 			}
6540 		}
6541 	}
6542 	if (IS_FEATURE_SUPPORTED_BY_FW(DOT11AX)) {
6543 		if (!wma_get_hemu_mode(&hemu_mode, mac)) {
6544 			wma_debug("set HEMU_MODE (hemu_mode = 0x%x)",
6545 			  hemu_mode);
6546 			status = mlme_check_index_setparam(
6547 						setparam,
6548 						wmi_vdev_param_set_hemu_mode,
6549 						hemu_mode, index++,
6550 						MAX_VDEV_CREATE_PARAMS);
6551 			if (QDF_IS_STATUS_ERROR(status)) {
6552 				wma_debug("failed to set wmi_vdev_param_set_hemu_mode");
6553 				goto error;
6554 			}
6555 		}
6556 	}
6557 	if (wlan_nan_is_beamforming_supported(mac->psoc)) {
6558 		txbf_en.sutxbfee =
6559 			mac->mlme_cfg->vht_caps.vht_cap_info.su_bformee;
6560 		txbf_en.mutxbfee =
6561 		mac->mlme_cfg->vht_caps.vht_cap_info.enable_mu_bformee;
6562 		txbf_en.sutxbfer =
6563 			mac->mlme_cfg->vht_caps.vht_cap_info.su_bformer;
6564 		status = mlme_check_index_setparam(setparam,
6565 					      wmi_vdev_param_txbf,
6566 					      *((A_UINT8 *)&txbf_en), index++,
6567 					      MAX_VDEV_CREATE_PARAMS);
6568 		if (QDF_IS_STATUS_ERROR(status)) {
6569 			wma_debug("failed to set wmi_vdev_param_txbf");
6570 			goto error;
6571 		}
6572 	}
6573 	/* Initialize roaming offload state */
6574 	if (vdev_mlme->mgmt.generic.type == WMI_VDEV_TYPE_STA &&
6575 	    vdev_mlme->mgmt.generic.subtype == 0) {
6576 		/* Pass down enable/disable bcast probe rsp to FW */
6577 		status = mlme_check_index_setparam(
6578 				setparam,
6579 				wmi_vdev_param_enable_bcast_probe_response,
6580 				mac->mlme_cfg->oce.enable_bcast_probe_rsp,
6581 				index++, MAX_VDEV_CREATE_PARAMS);
6582 		if (QDF_IS_STATUS_ERROR(status)) {
6583 			wma_debug("failed to set wmi_vdev_param_enable_bcast_probe_response");
6584 			goto error;
6585 		}
6586 		/* Pass down the FILS max channel guard time to FW */
6587 		status = mlme_check_index_setparam(
6588 				setparam,
6589 				wmi_vdev_param_fils_max_channel_guard_time,
6590 				mac->mlme_cfg->sta.fils_max_chan_guard_time,
6591 				index++, MAX_VDEV_CREATE_PARAMS);
6592 		if (QDF_IS_STATUS_ERROR(status)) {
6593 			wma_debug("failed to set wmi_vdev_param_fils_max_channel_guard_time");
6594 			goto error;
6595 		}
6596 		/* Pass down the Probe Request tx delay(in ms) to FW */
6597 		status = mlme_check_index_setparam(setparam,
6598 						   wmi_vdev_param_probe_delay,
6599 						   PROBE_REQ_TX_DELAY, index++,
6600 						   MAX_VDEV_CREATE_PARAMS);
6601 		if (QDF_IS_STATUS_ERROR(status)) {
6602 			wma_debug("failed to set wmi_vdev_param_probe_delay");
6603 			goto error;
6604 		}
6605 		/* Pass down the probe request tx time gap_ms to FW */
6606 		status = mlme_check_index_setparam(
6607 					      setparam,
6608 					      wmi_vdev_param_repeat_probe_time,
6609 					      PROBE_REQ_TX_TIME_GAP, index++,
6610 					      MAX_VDEV_CREATE_PARAMS);
6611 		if (QDF_IS_STATUS_ERROR(status)) {
6612 			wma_debug("failed to set wmi_vdev_param_repeat_probe_time");
6613 			goto error;
6614 		}
6615 		status = mlme_check_index_setparam(
6616 				setparam,
6617 				wmi_vdev_param_enable_disable_oce_features,
6618 				mac->mlme_cfg->oce.feature_bitmap, index++,
6619 				MAX_VDEV_CREATE_PARAMS);
6620 		if (QDF_IS_STATUS_ERROR(status)) {
6621 			wma_debug("failed to set wmi_vdev_param_enable_disable_oce_features");
6622 			goto error;
6623 		}
6624 		/* Initialize BMISS parameters */
6625 		wma_debug("first_bcnt: %d, final_bcnt: %d",
6626 			  mac->mlme_cfg->lfr.roam_bmiss_first_bcnt,
6627 			  mac->mlme_cfg->lfr.roam_bmiss_final_bcnt);
6628 		status = mlme_check_index_setparam(
6629 				setparam,
6630 				wmi_vdev_param_bmiss_first_bcnt,
6631 				mac->mlme_cfg->lfr.roam_bmiss_first_bcnt,
6632 				index++, MAX_VDEV_CREATE_PARAMS);
6633 		if (QDF_IS_STATUS_ERROR(status)) {
6634 			wma_debug("failed to set wmi_vdev_param_bmiss_first_bcnt");
6635 			goto error;
6636 		}
6637 		status = mlme_check_index_setparam(setparam,
6638 				wmi_vdev_param_bmiss_final_bcnt,
6639 				mac->mlme_cfg->lfr.roam_bmiss_final_bcnt,
6640 				index++, MAX_VDEV_CREATE_PARAMS);
6641 		if (QDF_IS_STATUS_ERROR(status)) {
6642 			wma_debug("failed to set wmi_vdev_param_bmiss_final_bcnt");
6643 			goto error;
6644 		}
6645 	}
6646 	if (vdev_mlme->mgmt.generic.type == WMI_VDEV_TYPE_AP &&
6647 	    vdev_mlme->mgmt.generic.subtype == 0) {
6648 		status = mlme_check_index_setparam(setparam,
6649 				wmi_vdev_param_enable_disable_oce_features,
6650 				mac->mlme_cfg->oce.feature_bitmap, index++,
6651 				MAX_VDEV_CREATE_PARAMS);
6652 		if (QDF_IS_STATUS_ERROR(status)) {
6653 			wma_debug("failed to set wmi_vdev_param_enable_disable_oce_features");
6654 			goto error;
6655 		}
6656 	}
6657 
6658 	opmode = wlan_vdev_mlme_get_opmode(vdev);
6659 	if (opmode == QDF_SAP_MODE) {
6660 		status = mlme_check_index_setparam(
6661 				setparam,
6662 				wmi_vdev_param_set_sap_ps_with_twt,
6663 				wlan_mlme_get_sap_ps_with_twt(mac->psoc),
6664 				index++, MAX_VDEV_CREATE_PARAMS);
6665 		if (QDF_IS_STATUS_ERROR(status)) {
6666 			wma_debug("failed to set wmi_vdev_param_set_sap_ps_with_twt");
6667 			goto error;
6668 		}
6669 	}
6670 
6671 	is_24ghz_twt_enabled = mlme_is_24ghz_twt_enabled(mac->psoc);
6672 	status = mlme_check_index_setparam(setparam,
6673 					   wmi_vdev_param_disable_2g_twt,
6674 					   !is_24ghz_twt_enabled,
6675 					   index++, MAX_VDEV_CREATE_PARAMS);
6676 	if (QDF_IS_STATUS_ERROR(status)) {
6677 		wma_debug("failed to set wmi_vdev_param_disable_2g_twt");
6678 		goto error;
6679 	}
6680 
6681 	status = wma_send_multi_pdev_vdev_set_params(MLME_VDEV_SETPARAM,
6682 						     vdev_id, setparam, index);
6683 	if (QDF_IS_STATUS_ERROR(status)) {
6684 		wma_err("failed to update vdev set all params");
6685 		status = QDF_STATUS_E_FAILURE;
6686 		goto error;
6687 	}
6688 error:
6689 	return status;
6690 }
6691 
6692 static inline bool wma_tx_is_chainmask_valid(int value,
6693 					     struct target_psoc_info *tgt_hdl)
6694 {
6695 	struct wlan_psoc_host_mac_phy_caps *mac_phy_cap;
6696 	uint8_t total_mac_phy_cnt, i;
6697 
6698 	mac_phy_cap = target_psoc_get_mac_phy_cap(tgt_hdl);
6699 	if (!mac_phy_cap) {
6700 		wma_err("Invalid MAC PHY capabilities handle");
6701 		return false;
6702 	}
6703 	total_mac_phy_cnt = target_psoc_get_total_mac_phy_cnt(tgt_hdl);
6704 	for (i = 0; i < total_mac_phy_cnt; i++) {
6705 		if (((mac_phy_cap[i].tx_chain_mask_5G) & (value)))
6706 			return true;
6707 	}
6708 	return false;
6709 }
6710 
6711 QDF_STATUS
6712 wma_validate_txrx_chain_mask(uint32_t id, uint32_t value)
6713 {
6714 	tp_wma_handle wma_handle =
6715 			cds_get_context(QDF_MODULE_ID_WMA);
6716 	struct target_psoc_info *tgt_hdl;
6717 
6718 	if (!wma_handle)
6719 		return QDF_STATUS_E_FAILURE;
6720 
6721 	tgt_hdl = wlan_psoc_get_tgt_if_handle(wma_handle->psoc);
6722 	if (!tgt_hdl)
6723 		return QDF_STATUS_E_FAILURE;
6724 
6725 	wma_debug("pdev pid %d pval %d", id, value);
6726 	if (id == wmi_pdev_param_tx_chain_mask) {
6727 		if (wma_check_txrx_chainmask(target_if_get_num_rf_chains(
6728 		    tgt_hdl), value) || !wma_tx_is_chainmask_valid(value,
6729 								   tgt_hdl)) {
6730 			wma_err("failed in validating tx chainmask");
6731 			return QDF_STATUS_E_FAILURE;
6732 		}
6733 	}
6734 	if (id == wmi_pdev_param_rx_chain_mask) {
6735 		if (wma_check_txrx_chainmask(target_if_get_num_rf_chains(
6736 					     tgt_hdl), value)) {
6737 			wma_err("failed in validating rtx chainmask");
6738 			return QDF_STATUS_SUCCESS;
6739 		}
6740 	}
6741 	return QDF_STATUS_SUCCESS;
6742 }
6743 
6744 QDF_STATUS wma_send_multi_pdev_vdev_set_params(enum mlme_dev_setparam param_type,
6745 					       uint8_t dev_id,
6746 					       struct dev_set_param *param,
6747 					       uint8_t n_params)
6748 {
6749 	struct mac_context *mac = cds_get_context(QDF_MODULE_ID_PE);
6750 	struct set_multiple_pdev_vdev_param params = {};
6751 	QDF_STATUS status;
6752 	wmi_unified_t wmi_handle;
6753 
6754 	if (!mac)
6755 		return QDF_STATUS_E_FAILURE;
6756 
6757 	wmi_handle = get_wmi_unified_hdl_from_psoc(mac->psoc);
6758 	if (!wmi_handle)
6759 		return QDF_STATUS_E_FAILURE;
6760 
6761 	params.param_type = param_type;
6762 	params.dev_id = dev_id;
6763 	params.is_host_pdev_id = false;
6764 	params.params = param;
6765 	params.n_params = n_params;
6766 
6767 	if (param_type == MLME_VDEV_SETPARAM) {
6768 		status = wmi_unified_multiple_vdev_param_send(wmi_handle,
6769 							      &params);
6770 		if (QDF_IS_STATUS_ERROR(status))
6771 			wma_err("failed to send multi vdev set params");
6772 	} else if (param_type == MLME_PDEV_SETPARAM) {
6773 		status = wmi_unified_multiple_pdev_param_send(wmi_handle,
6774 							      &params);
6775 		if (QDF_IS_STATUS_ERROR(status))
6776 			wma_err("failed to send multi pdev set params");
6777 	} else {
6778 		status = QDF_STATUS_E_FAILURE;
6779 		wma_err("Invalid param type");
6780 	}
6781 	return status;
6782 }
6783