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