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