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