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