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