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