xref: /wlan-driver/qcacld-3.0/core/wma/src/wma_main.c (revision 5113495b16420b49004c444715d2daae2066e7dc) !
1 /*
2  * Copyright (c) 2013-2021 The Linux Foundation. All rights reserved.
3  * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
4  *
5  * Permission to use, copy, modify, and/or distribute this software for
6  * any purpose with or without fee is hereby granted, provided that the
7  * above copyright notice and this permission notice appear in all
8  * copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
11  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
12  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
13  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
14  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
16  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17  * PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20 /**
21  *  DOC:  wma_main.c
22  *
23  *  This file contains wma initialization and FW exchange
24  *  related functions.
25  */
26 
27 /* Header files */
28 
29 #include "wma.h"
30 #include "wma_api.h"
31 #include "cds_api.h"
32 #include "wmi_unified_api.h"
33 #include "wlan_qct_sys.h"
34 #include "wni_api.h"
35 #include "ani_global.h"
36 #include "wmi_unified.h"
37 #include "wni_cfg.h"
38 #if defined(CONFIG_HL_SUPPORT)
39 #include "wlan_tgt_def_config_hl.h"
40 #else
41 #include "wlan_tgt_def_config.h"
42 #endif
43 #include "qdf_nbuf.h"
44 #include "qdf_types.h"
45 #include "qdf_mem.h"
46 #include "wma_types.h"
47 #include "lim_api.h"
48 #include "lim_session_utils.h"
49 #include "wlan_cm_tgt_if_tx_api.h"
50 #include "wlan_cm_roam_api.h"
51 
52 #include "cds_utils.h"
53 
54 #if !defined(REMOVE_PKT_LOG)
55 #include "pktlog_ac.h"
56 #endif /* REMOVE_PKT_LOG */
57 
58 #include "dbglog_host.h"
59 #include "csr_api.h"
60 #include "ol_fw.h"
61 
62 #include "wma_internal.h"
63 
64 #include "wma_ocb.h"
65 #include "wlan_policy_mgr_api.h"
66 #include "cdp_txrx_cfg.h"
67 #include "cdp_txrx_flow_ctrl_legacy.h"
68 #include "cdp_txrx_flow_ctrl_v2.h"
69 #include "cdp_txrx_ipa.h"
70 #include "cdp_txrx_misc.h"
71 #include "wma_fips_api.h"
72 #include "wma_nan_datapath.h"
73 #include "wma_fw_state.h"
74 #include "wlan_lmac_if_def.h"
75 #include "wlan_lmac_if_api.h"
76 #include "target_if.h"
77 #include "target_if_scan.h"
78 #include "wlan_global_lmac_if_api.h"
79 #include "target_if_pmo.h"
80 #include "wma_he.h"
81 #include "wlan_pmo_obj_mgmt_api.h"
82 
83 #include "wlan_reg_tgt_api.h"
84 #include "wlan_reg_services_api.h"
85 #include <cdp_txrx_handle.h>
86 #include <wlan_pmo_ucfg_api.h>
87 #include "wifi_pos_api.h"
88 #include "hif_main.h"
89 #ifdef WLAN_CONV_SPECTRAL_ENABLE
90 #include <target_if_spectral.h>
91 #include <wlan_spectral_utils_api.h>
92 #endif
93 #include "init_event_handler.h"
94 #include "init_deinit_lmac.h"
95 #include "target_if_green_ap.h"
96 #include "service_ready_param.h"
97 #include "wlan_cp_stats_mc_ucfg_api.h"
98 #include "cfg_nan_api.h"
99 #include "wlan_mlme_api.h"
100 #include "wlan_mlme_ucfg_api.h"
101 #include "cfg_ucfg_api.h"
102 #include "init_cmd_api.h"
103 #include "nan_ucfg_api.h"
104 #include "wma_coex.h"
105 #include "wma_twt.h"
106 #include "target_if_vdev_mgr_rx_ops.h"
107 #include "wlan_tdls_cfg_api.h"
108 #include "wlan_policy_mgr_i.h"
109 #include "target_if_psoc_timer_tx_ops.h"
110 #include <ftm_time_sync_ucfg_api.h>
111 #include "wlan_ipa_ucfg_api.h"
112 #include "wma_eht.h"
113 
114 #ifdef DIRECT_BUF_RX_ENABLE
115 #include <target_if_direct_buf_rx_api.h>
116 #endif
117 
118 #include "wlan_pkt_capture_ucfg_api.h"
119 #include "target_if_cm_roam_event.h"
120 #include "wlan_fwol_ucfg_api.h"
121 #include "wlan_tdls_api.h"
122 #include "wlan_twt_cfg_ext_api.h"
123 #include "wlan_mlo_mgr_sta.h"
124 #include "wlan_dp_api.h"
125 #include "wlan_dp_ucfg_api.h"
126 
127 #define WMA_LOG_COMPLETION_TIMER 500 /* 500 msecs */
128 #define WMI_TLV_HEADROOM 128
129 
130 static uint32_t g_fw_wlan_feat_caps;
131 /**
132  * wma_get_fw_wlan_feat_caps() - get fw feature capability
133  * @feature: feature enum value
134  *
135  * Return: true/false
136  */
wma_get_fw_wlan_feat_caps(enum cap_bitmap feature)137 bool wma_get_fw_wlan_feat_caps(enum cap_bitmap feature)
138 {
139 	return (g_fw_wlan_feat_caps & (1 << feature)) ? true : false;
140 }
141 
142 /**
143  * wma_set_fw_wlan_feat_caps() - set fw feature capability
144  * @feature: feature enum value
145  *
146  * Return: None
147  */
wma_set_fw_wlan_feat_caps(enum cap_bitmap feature)148 void wma_set_fw_wlan_feat_caps(enum cap_bitmap feature)
149 {
150 	g_fw_wlan_feat_caps |= (1 << feature);
151 }
152 
153 /**
154  * wma_service_ready_ext_evt_timeout() - Service ready extended event timeout
155  * @data: Timeout handler data
156  *
157  * This function is called when the FW fails to send WMI_SERVICE_READY_EXT_EVENT
158  * message
159  *
160  * Return: None
161  */
wma_service_ready_ext_evt_timeout(void * data)162 static void wma_service_ready_ext_evt_timeout(void *data)
163 {
164 	wma_alert("Timeout waiting for WMI_SERVICE_READY_EXT_EVENT");
165 
166 	/* Assert here. Panic is being called in insmod thread */
167 	QDF_ASSERT(0);
168 }
169 
170 /**
171  * wma_get_ini_handle() - API to get WMA ini info handle
172  * @wma: WMA Handle
173  *
174  * Returns the pointer to WMA ini structure.
175  * Return: struct wma_ini_config
176  */
wma_get_ini_handle(tp_wma_handle wma)177 struct wma_ini_config *wma_get_ini_handle(tp_wma_handle wma)
178 {
179 	if (wma_validate_handle(wma))
180 		return NULL;
181 
182 	return &wma->ini_config;
183 }
184 
__wma_validate_handle(tp_wma_handle wma_handle,const char * func)185 int __wma_validate_handle(tp_wma_handle wma_handle, const char *func)
186 {
187 	if (!wma_handle) {
188 		wma_err("Invalid WMA handle (via %s)", func);
189 		return -EINVAL;
190 	}
191 
192 	return 0;
193 }
194 
195 #define MAX_SUPPORTED_PEERS_REV1_1 14
196 #define MAX_SUPPORTED_PEERS_REV1_3 32
197 #ifdef WLAN_MAX_CLIENTS_ALLOWED
198 #define MAX_SUPPORTED_PEERS WLAN_MAX_CLIENTS_ALLOWED
199 #else
200 #define MAX_SUPPORTED_PEERS 32
201 #endif
202 #define MIN_NO_OF_PEERS 1
203 
204 /**
205  * wma_get_number_of_peers_supported - API to query for number of peers
206  * supported
207  * @wma: WMA Handle
208  *
209  * Return: Max Number of Peers Supported
210  */
wma_get_number_of_peers_supported(tp_wma_handle wma)211 static uint8_t wma_get_number_of_peers_supported(tp_wma_handle wma)
212 {
213 	struct wma_ini_config *cfg = wma_get_ini_handle(wma);
214 	uint8_t max_no_of_peers = cfg ? cfg->max_no_of_peers : MIN_NO_OF_PEERS;
215 
216 	return max_no_of_peers;
217 }
218 
219 /**
220  * wma_get_number_of_tids_supported - API to query for number of tids supported
221  * @no_of_peers_supported: Number of peer supported
222  * @no_vdevs: Number of vdevs
223  *
224  * Return: Max number of tids supported
225  */
226 #if defined(CONFIG_HL_SUPPORT)
wma_get_number_of_tids_supported(uint8_t no_of_peers_supported,uint8_t num_vdevs)227 static uint32_t wma_get_number_of_tids_supported(uint8_t no_of_peers_supported,
228 						 uint8_t num_vdevs)
229 {
230 	return 4 * no_of_peers_supported;
231 }
232 #else
wma_get_number_of_tids_supported(uint8_t no_of_peers_supported,uint8_t num_vdevs)233 static uint32_t wma_get_number_of_tids_supported(uint8_t no_of_peers_supported,
234 						 uint8_t num_vdevs)
235 {
236 	return 2 * (no_of_peers_supported + num_vdevs + 2);
237 }
238 #endif
239 
240 #if (defined(IPA_DISABLE_OVERRIDE)) && (!defined(IPA_OFFLOAD))
wma_set_ipa_disable_config(target_resource_config * tgt_cfg)241 static void wma_set_ipa_disable_config(
242 					target_resource_config *tgt_cfg)
243 {
244 	tgt_cfg->ipa_disable = true;
245 }
246 #else
wma_set_ipa_disable_config(target_resource_config * tgt_cfg)247 static void wma_set_ipa_disable_config(
248 					target_resource_config *tgt_cfg)
249 {
250 	tgt_cfg->ipa_disable = ucfg_ipa_is_enabled() ? false : true;
251 }
252 #endif
253 
254 #ifndef NUM_OF_ADDITIONAL_FW_PEERS
255 #define NUM_OF_ADDITIONAL_FW_PEERS	2
256 #endif
257 
258 /**
259  * wma_update_num_peers_tids() - Update num_peers and tids based on num_vdevs
260  * @wma_handle: wma handle
261  * @tgt_cfg: Resource config given to target
262  *
263  * Get num_vdevs from tgt_cfg and update num_peers and tids based on it.
264  *
265  * Return: none
266  */
wma_update_num_peers_tids(t_wma_handle * wma_handle,target_resource_config * tgt_cfg)267 static void wma_update_num_peers_tids(t_wma_handle *wma_handle,
268 				      target_resource_config *tgt_cfg)
269 
270 {
271 	uint8_t no_of_peers_supported;
272 
273 	no_of_peers_supported = wma_get_number_of_peers_supported(wma_handle);
274 
275 	tgt_cfg->num_peers = no_of_peers_supported + tgt_cfg->num_vdevs +
276 				NUM_OF_ADDITIONAL_FW_PEERS;
277 	/* The current firmware implementation requires the number of
278 	 * offload peers should be (number of vdevs + 1).
279 	 */
280 	tgt_cfg->num_tids =
281 		wma_get_number_of_tids_supported(no_of_peers_supported,
282 						 tgt_cfg->num_vdevs);
283 }
284 
285 #ifdef FEATURE_WDS
286 /**
287  * wma_set_peer_map_unmap_v2_config() - Update peer_map_unmap_v2
288  * @psoc: Object manager psoc
289  * @tgt_cfg: Resource config given to target
290  *
291  * This function enables Peer map/unmap v2 feature.
292  *
293  * Return: none
294  */
wma_set_peer_map_unmap_v2_config(struct wlan_objmgr_psoc * psoc,target_resource_config * tgt_cfg)295 static void wma_set_peer_map_unmap_v2_config(struct wlan_objmgr_psoc *psoc,
296 					     target_resource_config *tgt_cfg)
297 {
298 	tgt_cfg->peer_map_unmap_v2 =
299 			wlan_mlme_get_wds_mode(psoc) ? true : false;
300 }
301 #else
wma_set_peer_map_unmap_v2_config(struct wlan_objmgr_psoc * psoc,target_resource_config * tgt_cfg)302 static void wma_set_peer_map_unmap_v2_config(struct wlan_objmgr_psoc *psoc,
303 					     target_resource_config *tgt_cfg)
304 {
305 	tgt_cfg->peer_map_unmap_v2 = false;
306 }
307 #endif
308 
309 #ifdef FEATURE_SET
310 /**
311  * wma_get_concurrency_support() - Get concurrency support
312  * @psoc: Object manager psoc
313  *
314  * Return: WMI_HOST_BAND_CONCURRENCY
315  */
316 static WMI_HOST_BAND_CONCURRENCY
wma_get_concurrency_support(struct wlan_objmgr_psoc * psoc)317 wma_get_concurrency_support(struct wlan_objmgr_psoc *psoc)
318 {
319 	bool is_sbs_enabled = false;
320 
321 	if (policy_mgr_is_dual_mac_disabled_in_ini(psoc))
322 		return WMI_HOST_BAND_CONCURRENCY_NONE;
323 
324 	policy_mgr_get_sbs_cfg(psoc, &is_sbs_enabled);
325 
326 	if (is_sbs_enabled)
327 		return WMI_HOST_BAND_CONCURRENCY_DBS_SBS;
328 	else
329 		return WMI_HOST_BAND_CONCURRENCY_DBS;
330 }
331 
332 /**
333  * wma_update_set_feature_version() - Update the set feature version
334  *
335  * @fs: Feature set structure in which version needs to be updated.
336  *
337  * Version 1 - Base feature version
338  * Version 2 - WMI_HOST_VENDOR1_REQ1_VERSION_3_30 updated.
339  * Version 3 - min sleep period for TWT and Scheduled PM in FW updated
340  * Version 4 - WMI_HOST_VENDOR1_REQ1_VERSION_3_40 updated.
341  * Version 5 - INI based 11BE support updated
342  * Version 6 - sta dump info updated
343  *
344  * Return: None
345  */
wma_update_set_feature_version(struct target_feature_set * fs)346 static void wma_update_set_feature_version(struct target_feature_set *fs)
347 {
348 	fs->feature_set_version = 6;
349 }
350 
351 /**
352  * wma_set_feature_set_info() - Set feature set info
353  * @wma_handle: WMA handle
354  * @feature_set: Feature set structure which needs to be filled
355  *
356  * Return: WMI_HOST_BAND_CONCURRENCY
357  */
wma_set_feature_set_info(tp_wma_handle wma_handle,struct target_feature_set * feature_set)358 static void wma_set_feature_set_info(tp_wma_handle wma_handle,
359 				     struct target_feature_set *feature_set)
360 {
361 	struct cds_context *cds_ctx =
362 		(struct cds_context *)(wma_handle->cds_context);
363 	struct wlan_objmgr_psoc *psoc;
364 	struct wlan_scan_features scan_feature_set = {0};
365 	struct wlan_twt_features twt_feature_set = {0};
366 	struct wlan_mlme_features mlme_feature_set = {0};
367 	struct wlan_tdls_features tdls_feature_set = {0};
368 
369 	psoc = wma_handle->psoc;
370 	if (!psoc) {
371 		wma_err("Invalid psoc");
372 		return;
373 	}
374 
375 	if (!cds_ctx) {
376 		wma_err("Invalid cds context");
377 		return;
378 	}
379 
380 	if (!cds_ctx->cds_cfg) {
381 		wma_err("Invalid cds config");
382 		return;
383 	}
384 
385 	feature_set->wifi_standard =
386 			cds_ctx->cds_cfg->cds_feature_set.wifi_standard;
387 	feature_set->sap_5g_supported =
388 			cds_ctx->cds_cfg->cds_feature_set.sap_5g_supported;
389 	feature_set->sap_6g_supported =
390 			cds_ctx->cds_cfg->cds_feature_set.sap_6g_supported;
391 	feature_set->band_capability =
392 			cds_ctx->cds_cfg->cds_feature_set.band_capability;
393 
394 	feature_set->concurrency_support = wma_get_concurrency_support(psoc);
395 
396 	wlan_scan_get_feature_info(psoc, &scan_feature_set);
397 	feature_set->pno_in_unassoc_state =
398 					scan_feature_set.pno_in_unassoc_state;
399 	if (feature_set->pno_in_unassoc_state)
400 		feature_set->pno_in_assoc_state =
401 					scan_feature_set.pno_in_assoc_state;
402 
403 	wlan_twt_get_feature_info(psoc, &twt_feature_set);
404 	feature_set->enable_twt = twt_feature_set.enable_twt;
405 	if (feature_set->enable_twt) {
406 		feature_set->enable_twt_requester =
407 					twt_feature_set.enable_twt_requester;
408 		feature_set->enable_twt_broadcast =
409 					twt_feature_set.enable_twt_broadcast;
410 		feature_set->enable_twt_flexible =
411 					twt_feature_set.enable_twt_flexible;
412 	}
413 
414 	feature_set->enable_rfc835 = true;
415 
416 	wlan_mlme_get_feature_info(psoc, &mlme_feature_set);
417 
418 	feature_set->enable_wifi_optimizer =
419 				mlme_feature_set.enable_wifi_optimizer;
420 	feature_set->sap_max_num_clients =
421 				mlme_feature_set.sap_max_num_clients;
422 
423 	feature_set->vendor_req_1_version =
424 				mlme_feature_set.vendor_req_1_version;
425 	feature_set->roaming_high_cu_roam_trigger =
426 				mlme_feature_set.roaming_high_cu_roam_trigger;
427 	feature_set->roaming_emergency_trigger =
428 				mlme_feature_set.roaming_emergency_trigger;
429 	feature_set->roaming_btm_trihgger =
430 					mlme_feature_set.roaming_btm_trihgger;
431 	feature_set->roaming_idle_trigger =
432 					mlme_feature_set.roaming_idle_trigger;
433 	feature_set->roaming_wtc_trigger =
434 				mlme_feature_set.roaming_wtc_trigger;
435 	feature_set->roaming_btcoex_trigger =
436 				mlme_feature_set.roaming_btcoex_trigger;
437 	feature_set->roaming_btw_wpa_wpa2 =
438 					mlme_feature_set.roaming_btw_wpa_wpa2;
439 	feature_set->roaming_manage_chan_list_api =
440 				mlme_feature_set.roaming_manage_chan_list_api;
441 
442 	feature_set->roaming_adaptive_11r =
443 					mlme_feature_set.roaming_adaptive_11r;
444 	feature_set->roaming_ctrl_api_get_set =
445 				mlme_feature_set.roaming_ctrl_api_get_set;
446 	feature_set->roaming_ctrl_api_reassoc =
447 				mlme_feature_set.roaming_ctrl_api_reassoc;
448 	feature_set->roaming_ctrl_get_cu =
449 					mlme_feature_set.roaming_ctrl_get_cu;
450 	feature_set->vendor_req_2_version =
451 			mlme_feature_set.vendor_req_2_version;
452 	feature_set->iface_combinations = mlme_feature_set.iface_combinations;
453 
454 	if (mlme_feature_set.enable2x2)
455 		feature_set->num_antennas = WMI_HOST_MIMO_2X2;
456 	else
457 		feature_set->num_antennas = WMI_HOST_SISO;
458 
459 	feature_set->set_country_code_hal_supported = true;
460 	feature_set->get_valid_channel_supported = true;
461 	feature_set->supported_dot11mode = feature_set->wifi_standard;
462 	feature_set->sap_wpa3_support = true;
463 	feature_set->assurance_disconnect_reason_api = true;
464 	feature_set->frame_pcap_log_mgmt =
465 				    ucfg_dp_is_local_pkt_capture_enabled(psoc);
466 	feature_set->frame_pcap_log_ctrl = feature_set->frame_pcap_log_mgmt;
467 	feature_set->frame_pcap_log_data = feature_set->frame_pcap_log_mgmt;
468 
469 	/*
470 	 * This information is hardcoded based on hdd_sta_akm_suites,
471 	 *wlan_crypto_key_mgmt and wlan_crypto_rsnx_cap
472 	 */
473 
474 	/* WLAN_CRYPTO_RSNX_CAP_SAE_H2E support*/
475 	feature_set->security_wpa3_sae_h2e = true;
476 	feature_set->security_wpa3_sae_ft = true;
477 	feature_set->security_wpa3_enterp_suitb = true;
478 	feature_set->security_wpa3_enterp_suitb_192bit = true;
479 	feature_set->security_fills_sha_256 = true;
480 	feature_set->security_fills_sha_384 = true;
481 	feature_set->security_fills_sha_256_FT = true;
482 	feature_set->security_fills_sha_384_FT = true;
483 	/* This is OWE security support */
484 	feature_set->security_enhanced_open = true;
485 
486 	feature_set->enable_nan = cfg_nan_get_enable(psoc);
487 
488 	wlan_tdls_get_features_info(psoc, &tdls_feature_set);
489 	feature_set->enable_tdls = tdls_feature_set.enable_tdls;
490 	if (feature_set->enable_tdls) {
491 		feature_set->enable_tdls_offchannel =
492 				tdls_feature_set.enable_tdls_offchannel;
493 		feature_set->max_tdls_peers = tdls_feature_set.max_tdls_peers;
494 		feature_set->enable_tdls_capability_enhance =
495 			tdls_feature_set.enable_tdls_capability_enhance;
496 	}
497 
498 	if (feature_set->sap_6g_supported)
499 		feature_set->enable_p2p_6e =
500 					policy_mgr_is_6ghz_conc_mode_supported(
501 							psoc,
502 							PM_P2P_CLIENT_MODE);
503 
504 	feature_set->peer_bigdata_getbssinfo_support = true;
505 	feature_set->peer_bigdata_assocreject_info_support = true;
506 	feature_set->peer_getstainfo_support = true;
507 	feature_set->sta_dump_support = true;
508 	wma_update_set_feature_version(feature_set);
509 }
510 
511 /**
512  * wma_send_feature_set_cmd() - Send feature set command to FW
513  * @wma_handle: WMA handle
514  *
515  * Return: None
516  */
wma_send_feature_set_cmd(tp_wma_handle wma_handle)517 static void wma_send_feature_set_cmd(tp_wma_handle wma_handle)
518 {
519 	struct target_feature_set feature_set;
520 
521 	if (!wma_handle) {
522 		wma_err("Invalid wma_handle");
523 		return;
524 	}
525 
526 	wma_set_feature_set_info(wma_handle, &feature_set);
527 
528 	wmi_feature_set_cmd_send(wma_handle->wmi_handle,
529 				 &feature_set);
530 }
531 
532 /**
533  * wma_is_feature_set_supported() - Check if feaure set is supported or not
534  * @wma_handle: WMA handle
535  *
536  * Return: True, if feature set is supported else return false
537  */
wma_is_feature_set_supported(tp_wma_handle wma_handle)538 static bool wma_is_feature_set_supported(tp_wma_handle wma_handle)
539 {
540 	struct cds_context *cds_ctx =
541 		(struct cds_context *)(wma_handle->cds_context);
542 	bool is_feature_enabled_from_fw;
543 
544 	if (!cds_ctx) {
545 		wma_err("Invalid cds context");
546 		return false;
547 	}
548 
549 	if (!cds_ctx->cds_cfg) {
550 		wma_err("Invalid cds config");
551 		return false;
552 	}
553 
554 	is_feature_enabled_from_fw =
555 		wmi_service_enabled(wma_handle->wmi_handle,
556 				    wmi_service_feature_set_event_support);
557 
558 	if (!is_feature_enabled_from_fw)
559 		wma_debug("Get wifi feature is disabled from fw");
560 
561 	return (is_feature_enabled_from_fw &&
562 		cds_ctx->cds_cfg->get_wifi_features);
563 }
564 #else
wma_send_feature_set_cmd(tp_wma_handle wma_handle)565 static inline void wma_send_feature_set_cmd(tp_wma_handle wma_handle)
566 {
567 }
568 
wma_is_feature_set_supported(tp_wma_handle wma_handle)569 static bool wma_is_feature_set_supported(tp_wma_handle wma_handle)
570 {
571 	return false;
572 }
573 
574 #endif
575 
576 /**
577  * wma_set_default_tgt_config() - set default tgt config
578  * @wma_handle: wma handle
579  * @tgt_cfg: Resource config given to target
580  * @cds_cfg: cds configuration
581  *
582  * Return: none
583  */
wma_set_default_tgt_config(tp_wma_handle wma_handle,target_resource_config * tgt_cfg,struct cds_config_info * cds_cfg)584 static void wma_set_default_tgt_config(tp_wma_handle wma_handle,
585 				       target_resource_config *tgt_cfg,
586 				       struct cds_config_info *cds_cfg)
587 {
588 	enum QDF_GLOBAL_MODE con_mode;
589 
590 	qdf_mem_zero(tgt_cfg, sizeof(target_resource_config));
591 
592 	tgt_cfg->num_vdevs = cds_cfg->num_vdevs;
593 	wma_update_num_peers_tids(wma_handle, tgt_cfg);
594 
595 	/* The current firmware implementation requires the number of
596 	 * offload peers should be (number of vdevs + 1).
597 	 */
598 	tgt_cfg->num_offload_peers = cds_cfg->ap_maxoffload_peers + 1;
599 	tgt_cfg->num_offload_reorder_buffs =
600 				cds_cfg->ap_maxoffload_reorderbuffs + 1;
601 	tgt_cfg->num_peer_keys = CFG_TGT_NUM_PEER_KEYS;
602 	tgt_cfg->ast_skid_limit = CFG_TGT_AST_SKID_LIMIT;
603 	tgt_cfg->tx_chain_mask = CFG_TGT_DEFAULT_TX_CHAIN_MASK;
604 	tgt_cfg->rx_chain_mask = CFG_TGT_DEFAULT_RX_CHAIN_MASK;
605 	tgt_cfg->rx_timeout_pri[0] = CFG_TGT_RX_TIMEOUT_LO_PRI;
606 	tgt_cfg->rx_timeout_pri[1] = CFG_TGT_RX_TIMEOUT_LO_PRI;
607 	tgt_cfg->rx_timeout_pri[2] = CFG_TGT_RX_TIMEOUT_LO_PRI;
608 	tgt_cfg->rx_timeout_pri[3] = CFG_TGT_RX_TIMEOUT_HI_PRI;
609 	tgt_cfg->rx_decap_mode = CFG_TGT_RX_DECAP_MODE;
610 	tgt_cfg->scan_max_pending_req = WLAN_MAX_ACTIVE_SCANS_ALLOWED;
611 	tgt_cfg->bmiss_offload_max_vdev =
612 			CFG_TGT_DEFAULT_BMISS_OFFLOAD_MAX_VDEV;
613 	tgt_cfg->roam_offload_max_vdev = CFG_TGT_DEFAULT_ROAM_OFFLOAD_MAX_VDEV;
614 	tgt_cfg->roam_offload_max_ap_profiles =
615 		CFG_TGT_DEFAULT_ROAM_OFFLOAD_MAX_PROFILES;
616 	tgt_cfg->num_mcast_groups = CFG_TGT_DEFAULT_NUM_MCAST_GROUPS;
617 	tgt_cfg->num_mcast_table_elems = CFG_TGT_DEFAULT_NUM_MCAST_TABLE_ELEMS;
618 	tgt_cfg->mcast2ucast_mode = CFG_TGT_DEFAULT_MCAST2UCAST_MODE;
619 	tgt_cfg->tx_dbg_log_size = CFG_TGT_DEFAULT_TX_DBG_LOG_SIZE;
620 	tgt_cfg->num_wds_entries = CFG_TGT_WDS_ENTRIES;
621 	tgt_cfg->dma_burst_size = CFG_TGT_DEFAULT_DMA_BURST_SIZE;
622 	tgt_cfg->mac_aggr_delim = CFG_TGT_DEFAULT_MAC_AGGR_DELIM;
623 	tgt_cfg->rx_skip_defrag_timeout_dup_detection_check =
624 		CFG_TGT_DEFAULT_RX_SKIP_DEFRAG_TIMEOUT_DUP_DETECTION_CHECK,
625 	tgt_cfg->vow_config = CFG_TGT_DEFAULT_VOW_CONFIG;
626 	tgt_cfg->gtk_offload_max_vdev = CFG_TGT_DEFAULT_GTK_OFFLOAD_MAX_VDEV;
627 	tgt_cfg->num_msdu_desc = CFG_TGT_NUM_MSDU_DESC;
628 	tgt_cfg->max_frag_entries = CFG_TGT_MAX_FRAG_TABLE_ENTRIES;
629 	tgt_cfg->num_tdls_vdevs = CFG_TGT_NUM_TDLS_VDEVS;
630 	tgt_cfg->num_tdls_conn_table_entries =
631 			QDF_MIN(CFG_TGT_NUM_TDLS_CONN_TABLE_ENTRIES,
632 				cfg_tdls_get_max_peer_count(wma_handle->psoc));
633 	tgt_cfg->beacon_tx_offload_max_vdev =
634 		CFG_TGT_DEFAULT_BEACON_TX_OFFLOAD_MAX_VDEV;
635 	tgt_cfg->num_multicast_filter_entries =
636 		CFG_TGT_MAX_MULTICAST_FILTER_ENTRIES;
637 	tgt_cfg->num_wow_filters = 0;
638 	tgt_cfg->num_keep_alive_pattern = MAXNUM_PERIODIC_TX_PTRNS;
639 	tgt_cfg->num_max_sta_vdevs = CFG_TGT_DEFAULT_MAX_STA_VDEVS;
640 	tgt_cfg->keep_alive_pattern_size = 0;
641 	tgt_cfg->max_tdls_concurrent_sleep_sta =
642 		CFG_TGT_NUM_TDLS_CONC_SLEEP_STAS;
643 	tgt_cfg->max_tdls_concurrent_buffer_sta =
644 		CFG_TGT_NUM_TDLS_CONC_BUFFER_STAS;
645 	tgt_cfg->wmi_send_separate = 0;
646 	tgt_cfg->num_ocb_vdevs = CFG_TGT_NUM_OCB_VDEVS;
647 	tgt_cfg->num_ocb_channels = CFG_TGT_NUM_OCB_CHANNELS;
648 	tgt_cfg->num_ocb_schedules = CFG_TGT_NUM_OCB_SCHEDULES;
649 	tgt_cfg->twt_ap_sta_count = CFG_TGT_DEFAULT_TWT_AP_STA_COUNT;
650 	tgt_cfg->enable_pci_gen = cfg_get(wma_handle->psoc, CFG_ENABLE_PCI_GEN);
651 
652 	tgt_cfg->mgmt_comp_evt_bundle_support = true;
653 	tgt_cfg->tx_msdu_new_partition_id_support = true;
654 	tgt_cfg->is_sap_connected_d3wow_enabled =
655 		ucfg_pmo_get_sap_mode_bus_suspend(wma_handle->psoc);
656 	tgt_cfg->is_go_connected_d3wow_enabled =
657 		ucfg_pmo_get_go_mode_bus_suspend(wma_handle->psoc);
658 	tgt_cfg->num_max_active_vdevs =
659 		policy_mgr_get_max_conc_cxns(wma_handle->psoc);
660 	tgt_cfg->num_max_mlo_link_per_ml_bss =
661 		wlan_mlme_get_sta_mlo_conn_max_num(wma_handle->psoc);
662 	cfg_nan_get_max_ndi(wma_handle->psoc,
663 			    &tgt_cfg->max_ndi);
664 
665 	con_mode = cds_get_conparam();
666 	if (con_mode == QDF_GLOBAL_MONITOR_MODE)
667 		tgt_cfg->rx_decap_mode = CFG_TGT_RX_DECAP_MODE_RAW;
668 
669 	if (con_mode == QDF_GLOBAL_FTM_MODE) {
670 		tgt_cfg->num_offload_peers = 0;
671 		tgt_cfg->num_offload_reorder_buffs = 0;
672 		tgt_cfg->bmiss_offload_max_vdev = 0;
673 		tgt_cfg->roam_offload_max_vdev = 0;
674 		tgt_cfg->roam_offload_max_ap_profiles = 0;
675 		tgt_cfg->beacon_tx_offload_max_vdev = 1;
676 		tgt_cfg->num_multicast_filter_entries = 0;
677 		tgt_cfg->gtk_offload_max_vdev = 0;
678 	}
679 	cfg_nan_get_ndp_max_sessions(wma_handle->psoc,
680 				     &tgt_cfg->max_ndp_sessions);
681 
682 	wma_set_ipa_disable_config(tgt_cfg);
683 	wma_set_peer_map_unmap_v2_config(wma_handle->psoc, tgt_cfg);
684 
685 	tgt_cfg->notify_frame_support = DP_MARK_NOTIFY_FRAME_SUPPORT;
686 }
687 
688 /**
689  * wma_cli_get_command() - WMA "get" command processor
690  * @vdev_id: virtual device for the command
691  * @param_id: parameter id
692  * @vpdev: parameter category
693  *
694  * Return: parameter value on success, -EINVAL on failure
695  */
wma_cli_get_command(int vdev_id,int param_id,int vpdev)696 int wma_cli_get_command(int vdev_id, int param_id, int vpdev)
697 {
698 	int ret = 0;
699 	tp_wma_handle wma;
700 	struct wma_txrx_node *intr = NULL;
701 
702 	wma = cds_get_context(QDF_MODULE_ID_WMA);
703 	if (!wma)
704 		return -EINVAL;
705 
706 	intr = wma->interfaces;
707 
708 	if (VDEV_CMD == vpdev) {
709 		switch (param_id) {
710 		case wmi_vdev_param_nss:
711 			ret = intr[vdev_id].config.nss;
712 			break;
713 #ifdef QCA_SUPPORT_GTX
714 		case wmi_vdev_param_gtx_ht_mcs:
715 			ret = intr[vdev_id].config.gtx_info.gtxRTMask[0];
716 			break;
717 		case wmi_vdev_param_gtx_vht_mcs:
718 			ret = intr[vdev_id].config.gtx_info.gtxRTMask[1];
719 			break;
720 		case wmi_vdev_param_gtx_usr_cfg:
721 			ret = intr[vdev_id].config.gtx_info.gtxUsrcfg;
722 			break;
723 		case wmi_vdev_param_gtx_thre:
724 			ret = intr[vdev_id].config.gtx_info.gtxPERThreshold;
725 			break;
726 		case wmi_vdev_param_gtx_margin:
727 			ret = intr[vdev_id].config.gtx_info.gtxPERMargin;
728 			break;
729 		case wmi_vdev_param_gtx_step:
730 			ret = intr[vdev_id].config.gtx_info.gtxTPCstep;
731 			break;
732 		case wmi_vdev_param_gtx_mintpc:
733 			ret = intr[vdev_id].config.gtx_info.gtxTPCMin;
734 			break;
735 		case wmi_vdev_param_gtx_bw_mask:
736 			ret = intr[vdev_id].config.gtx_info.gtxBWMask;
737 			break;
738 #endif /* QCA_SUPPORT_GTX */
739 		case wmi_vdev_param_ldpc:
740 			ret = intr[vdev_id].config.ldpc;
741 			break;
742 		case wmi_vdev_param_tx_stbc:
743 			ret = intr[vdev_id].config.tx_stbc;
744 			break;
745 		case wmi_vdev_param_rx_stbc:
746 			ret = intr[vdev_id].config.rx_stbc;
747 			break;
748 		case wmi_vdev_param_sgi:
749 			ret = intr[vdev_id].config.shortgi;
750 			break;
751 		case wmi_vdev_param_enable_rtscts:
752 			ret = intr[vdev_id].config.rtscts_en;
753 			break;
754 		case wmi_vdev_param_chwidth:
755 			ret = intr[vdev_id].config.chwidth;
756 			break;
757 		case wmi_vdev_param_fixed_rate:
758 			ret = intr[vdev_id].config.tx_rate;
759 			break;
760 		case wmi_vdev_param_he_dcm_enable:
761 		case wmi_vdev_param_he_range_ext:
762 			ret = wma_get_he_vdev_param(&intr[vdev_id], param_id);
763 			break;
764 		default:
765 			wma_err("Invalid cli_get vdev command/Not yet implemented 0x%x",
766 				param_id);
767 			return -EINVAL;
768 		}
769 	} else if (PDEV_CMD == vpdev) {
770 		switch (param_id) {
771 		case wmi_pdev_param_ani_enable:
772 			ret = wma->pdevconfig.ani_enable;
773 			break;
774 		case wmi_pdev_param_ani_poll_period:
775 			ret = wma->pdevconfig.ani_poll_len;
776 			break;
777 		case wmi_pdev_param_ani_listen_period:
778 			ret = wma->pdevconfig.ani_listen_len;
779 			break;
780 		case wmi_pdev_param_ani_ofdm_level:
781 			ret = wma->pdevconfig.ani_ofdm_level;
782 			break;
783 		case wmi_pdev_param_ani_cck_level:
784 			ret = wma->pdevconfig.ani_cck_level;
785 			break;
786 		case wmi_pdev_param_dynamic_bw:
787 			ret = wma->pdevconfig.cwmenable;
788 			break;
789 		case wmi_pdev_param_cts_cbw:
790 			ret = wma->pdevconfig.cts_cbw;
791 			break;
792 		case wmi_pdev_param_tx_chain_mask:
793 			ret = wma->pdevconfig.txchainmask;
794 			break;
795 		case wmi_pdev_param_rx_chain_mask:
796 			ret = wma->pdevconfig.rxchainmask;
797 			break;
798 		case wmi_pdev_param_txpower_limit2g:
799 			ret = wma->pdevconfig.txpow2g;
800 			break;
801 		case wmi_pdev_param_txpower_limit5g:
802 			ret = wma->pdevconfig.txpow5g;
803 			break;
804 		default:
805 			wma_err("Invalid cli_get pdev command/Not yet implemented 0x%x",
806 				param_id);
807 			return -EINVAL;
808 		}
809 	} else if (GEN_CMD == vpdev) {
810 		switch (param_id) {
811 		case GEN_VDEV_PARAM_AMPDU:
812 			ret = intr[vdev_id].config.ampdu;
813 			break;
814 		case GEN_VDEV_PARAM_AMSDU:
815 			ret = intr[vdev_id].config.amsdu;
816 			break;
817 		case GEN_VDEV_ROAM_SYNCH_DELAY:
818 			ret = intr[vdev_id].roam_synch_delay;
819 			break;
820 		case GEN_VDEV_PARAM_TX_AMPDU:
821 			ret = intr[vdev_id].config.tx_ampdu;
822 			break;
823 		case GEN_VDEV_PARAM_RX_AMPDU:
824 			ret = intr[vdev_id].config.rx_ampdu;
825 			break;
826 		case GEN_VDEV_PARAM_TX_AMSDU:
827 			ret = intr[vdev_id].config.tx_amsdu;
828 			break;
829 		case GEN_VDEV_PARAM_RX_AMSDU:
830 			ret = intr[vdev_id].config.rx_amsdu;
831 			break;
832 		default:
833 			wma_warn("Invalid generic vdev command/Not yet implemented 0x%x",
834 				 param_id);
835 			return -EINVAL;
836 		}
837 	} else if (PPS_CMD == vpdev) {
838 		switch (param_id) {
839 		case WMI_VDEV_PPS_PAID_MATCH:
840 			ret = intr[vdev_id].config.pps_params.paid_match_enable;
841 			break;
842 		case WMI_VDEV_PPS_GID_MATCH:
843 			ret = intr[vdev_id].config.pps_params.gid_match_enable;
844 			break;
845 		case WMI_VDEV_PPS_EARLY_TIM_CLEAR:
846 			ret = intr[vdev_id].config.pps_params.tim_clear;
847 			break;
848 		case WMI_VDEV_PPS_EARLY_DTIM_CLEAR:
849 			ret = intr[vdev_id].config.pps_params.dtim_clear;
850 			break;
851 		case WMI_VDEV_PPS_EOF_PAD_DELIM:
852 			ret = intr[vdev_id].config.pps_params.eof_delim;
853 			break;
854 		case WMI_VDEV_PPS_MACADDR_MISMATCH:
855 			ret = intr[vdev_id].config.pps_params.mac_match;
856 			break;
857 		case WMI_VDEV_PPS_DELIM_CRC_FAIL:
858 			ret = intr[vdev_id].config.pps_params.delim_fail;
859 			break;
860 		case WMI_VDEV_PPS_GID_NSTS_ZERO:
861 			ret = intr[vdev_id].config.pps_params.nsts_zero;
862 			break;
863 		case WMI_VDEV_PPS_RSSI_CHECK:
864 			ret = intr[vdev_id].config.pps_params.rssi_chk;
865 			break;
866 		default:
867 			wma_err("Invalid pps vdev command/Not yet implemented 0x%x",
868 				param_id);
869 			return -EINVAL;
870 		}
871 	} else if (QPOWER_CMD == vpdev) {
872 		switch (param_id) {
873 		case WMI_STA_PS_PARAM_QPOWER_PSPOLL_COUNT:
874 			ret = intr[vdev_id].config.qpower_params.
875 			      max_ps_poll_cnt;
876 			break;
877 		case WMI_STA_PS_PARAM_QPOWER_MAX_TX_BEFORE_WAKE:
878 			ret = intr[vdev_id].config.qpower_params.
879 			      max_tx_before_wake;
880 			break;
881 		case WMI_STA_PS_PARAM_QPOWER_SPEC_PSPOLL_WAKE_INTERVAL:
882 			ret = intr[vdev_id].config.qpower_params.
883 			      spec_ps_poll_wake_interval;
884 			break;
885 		case WMI_STA_PS_PARAM_QPOWER_SPEC_MAX_SPEC_NODATA_PSPOLL:
886 			ret = intr[vdev_id].config.qpower_params.
887 			      max_spec_nodata_ps_poll;
888 			break;
889 		default:
890 			wma_warn("Invalid generic vdev command/Not yet implemented 0x%x",
891 				 param_id);
892 			return -EINVAL;
893 		}
894 	} else if (GTX_CMD == vpdev) {
895 		switch (param_id) {
896 		case wmi_vdev_param_gtx_ht_mcs:
897 			ret = intr[vdev_id].config.gtx_info.gtxRTMask[0];
898 			break;
899 		case wmi_vdev_param_gtx_vht_mcs:
900 			ret = intr[vdev_id].config.gtx_info.gtxRTMask[1];
901 			break;
902 		case wmi_vdev_param_gtx_usr_cfg:
903 			ret = intr[vdev_id].config.gtx_info.gtxUsrcfg;
904 			break;
905 		case wmi_vdev_param_gtx_thre:
906 			ret = intr[vdev_id].config.gtx_info.gtxPERThreshold;
907 			break;
908 		case wmi_vdev_param_gtx_margin:
909 			ret = intr[vdev_id].config.gtx_info.gtxPERMargin;
910 			break;
911 		case wmi_vdev_param_gtx_step:
912 			ret = intr[vdev_id].config.gtx_info.gtxTPCstep;
913 			break;
914 		case wmi_vdev_param_gtx_mintpc:
915 			ret = intr[vdev_id].config.gtx_info.gtxTPCMin;
916 			break;
917 		case wmi_vdev_param_gtx_bw_mask:
918 			ret = intr[vdev_id].config.gtx_info.gtxBWMask;
919 			break;
920 		default:
921 			wma_warn("Invalid generic vdev command/Not yet implemented 0x%x",
922 				 param_id);
923 			return -EINVAL;
924 		}
925 	}
926 	return ret;
927 }
928 
929 /**
930  * wma_cli_set2_command() - WMA "set 2 params" command processor
931  * @vdev_id: virtual device for the command
932  * @param_id: parameter id
933  * @sval1: first parameter value
934  * @sval2: second parameter value
935  * @vpdev: parameter category
936  *
937  * Command handler for set operations which require 2 parameters
938  *
939  * Return: 0 on success, errno on failure
940  */
wma_cli_set2_command(int vdev_id,int param_id,int sval1,int sval2,int vpdev)941 int wma_cli_set2_command(int vdev_id, int param_id, int sval1,
942 			 int sval2, int vpdev)
943 {
944 	struct scheduler_msg msg = { 0 };
945 	wma_cli_set_cmd_t *iwcmd;
946 
947 	iwcmd = qdf_mem_malloc(sizeof(*iwcmd));
948 	if (!iwcmd)
949 		return -ENOMEM;
950 
951 	qdf_mem_zero(iwcmd, sizeof(*iwcmd));
952 	iwcmd->param_value = sval1;
953 	iwcmd->param_sec_value = sval2;
954 	iwcmd->param_vdev_id = vdev_id;
955 	iwcmd->param_id = param_id;
956 	iwcmd->param_vp_dev = vpdev;
957 	msg.type = WMA_CLI_SET_CMD;
958 	msg.reserved = 0;
959 	msg.bodyptr = iwcmd;
960 
961 	if (QDF_STATUS_SUCCESS !=
962 	    scheduler_post_message(QDF_MODULE_ID_WMA,
963 				   QDF_MODULE_ID_WMA,
964 				   QDF_MODULE_ID_WMA, &msg)) {
965 		qdf_mem_free(iwcmd);
966 		return -EIO;
967 	}
968 	return 0;
969 }
970 
971 /**
972  * wma_cli_set_command() - WMA "set" command processor
973  * @vdev_id: virtual device for the command
974  * @param_id: parameter id
975  * @sval: parameter value
976  * @vpdev: parameter category
977  *
978  * Command handler for set operations
979  *
980  * Return: 0 on success, errno on failure
981  */
wma_cli_set_command(int vdev_id,int param_id,int sval,int vpdev)982 int wma_cli_set_command(int vdev_id, int param_id, int sval, int vpdev)
983 {
984 	return wma_cli_set2_command(vdev_id, param_id, sval, 0, vpdev);
985 
986 }
987 
wma_form_unit_test_cmd_and_send(uint32_t vdev_id,uint32_t module_id,uint32_t arg_count,uint32_t * arg)988 QDF_STATUS wma_form_unit_test_cmd_and_send(uint32_t vdev_id,
989 			uint32_t module_id, uint32_t arg_count, uint32_t *arg)
990 {
991 	struct wmi_unit_test_cmd *unit_test_args;
992 	tp_wma_handle wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
993 	uint32_t i;
994 	QDF_STATUS status;
995 	struct wmi_unified *wmi_handle;
996 
997 	wma_debug("enter");
998 
999 	if (QDF_GLOBAL_FTM_MODE != cds_get_conparam()) {
1000 		if (!wma_is_vdev_valid(vdev_id))
1001 			return QDF_STATUS_E_FAILURE;
1002 	}
1003 
1004 	if (arg_count > WMI_UNIT_TEST_MAX_NUM_ARGS) {
1005 		wma_err("arg_count is crossed the boundary");
1006 		return QDF_STATUS_E_FAILURE;
1007 	}
1008 
1009 	if (wma_validate_handle(wma_handle))
1010 		return QDF_STATUS_E_FAILURE;
1011 
1012 	wmi_handle = wma_handle->wmi_handle;
1013 	if (wmi_validate_handle(wmi_handle))
1014 		return QDF_STATUS_E_FAILURE;
1015 
1016 	unit_test_args = qdf_mem_malloc(sizeof(*unit_test_args));
1017 	if (!unit_test_args)
1018 		return QDF_STATUS_E_NOMEM;
1019 
1020 	unit_test_args->vdev_id = vdev_id;
1021 	unit_test_args->module_id = module_id;
1022 	unit_test_args->num_args = arg_count;
1023 	for (i = 0; i < arg_count; i++)
1024 		unit_test_args->args[i] = arg[i];
1025 
1026 	status = wmi_unified_unit_test_cmd(wmi_handle,
1027 					   unit_test_args);
1028 	qdf_mem_free(unit_test_args);
1029 	wma_debug("exit");
1030 
1031 	return status;
1032 }
1033 
wma_process_send_addba_req(tp_wma_handle wma_handle,struct send_add_ba_req * send_addba)1034 static void wma_process_send_addba_req(tp_wma_handle wma_handle,
1035 		struct send_add_ba_req *send_addba)
1036 {
1037 	QDF_STATUS status;
1038 	struct wmi_unified *wmi_handle;
1039 
1040 	if (wma_validate_handle(wma_handle)) {
1041 		qdf_mem_free(send_addba);
1042 		return;
1043 	}
1044 
1045 	wmi_handle = wma_handle->wmi_handle;
1046 	if (wmi_validate_handle(wmi_handle)) {
1047 		qdf_mem_free(send_addba);
1048 		return;
1049 	}
1050 
1051 	status = wmi_unified_addba_send_cmd_send(wmi_handle,
1052 					   send_addba->mac_addr,
1053 					   &send_addba->param);
1054 	if (QDF_STATUS_SUCCESS != status) {
1055 		wma_err("Failed to process WMA_SEND_ADDBA_REQ");
1056 	}
1057 	wma_debug("sent ADDBA req to" QDF_MAC_ADDR_FMT "tid %d buff_size %d",
1058 			QDF_MAC_ADDR_REF(send_addba->mac_addr),
1059 			send_addba->param.tidno,
1060 			send_addba->param.buffersize);
1061 
1062 	qdf_mem_free(send_addba);
1063 }
1064 
1065 /**
1066  * wma_set_priv_cfg() - set private config parameters
1067  * @wma_handle: wma handle
1068  * @privcmd: private command
1069  *
1070  * Return: 0 for success or error code
1071  */
wma_set_priv_cfg(tp_wma_handle wma_handle,wma_cli_set_cmd_t * privcmd)1072 static int32_t wma_set_priv_cfg(tp_wma_handle wma_handle,
1073 				wma_cli_set_cmd_t *privcmd)
1074 {
1075 	int32_t ret = 0;
1076 
1077 	switch (privcmd->param_id) {
1078 	case WMA_VDEV_TXRX_FWSTATS_ENABLE_CMDID:
1079 		ret = wma_set_txrx_fw_stats_level(wma_handle,
1080 						  privcmd->param_vdev_id,
1081 						  privcmd->param_value);
1082 		break;
1083 	case WMA_VDEV_TXRX_FWSTATS_RESET_CMDID:
1084 		ret = wma_txrx_fw_stats_reset(wma_handle,
1085 					      privcmd->param_vdev_id,
1086 					      privcmd->param_value);
1087 		break;
1088 	case WMI_STA_SMPS_FORCE_MODE_CMDID:
1089 		ret = wma_set_mimops(wma_handle,
1090 				     privcmd->param_vdev_id,
1091 				     privcmd->param_value);
1092 		break;
1093 	case WMI_STA_SMPS_PARAM_CMDID:
1094 		wma_set_smps_params(wma_handle, privcmd->param_vdev_id,
1095 				    privcmd->param_value);
1096 		break;
1097 	case WMA_VDEV_MCC_SET_TIME_LATENCY:
1098 	{
1099 		/* Extract first MCC adapter/vdev channel number and latency */
1100 		uint8_t mcc_channel = privcmd->param_value & 0x000000FF;
1101 		uint8_t mcc_channel_latency =
1102 			(privcmd->param_value & 0x0000FF00) >> 8;
1103 		int ret = -1;
1104 
1105 		wma_debug("Parsed input: Channel #1:%d, latency:%dms",
1106 			 mcc_channel, mcc_channel_latency);
1107 		ret = wma_set_mcc_channel_time_latency(wma_handle,
1108 						       mcc_channel,
1109 						       mcc_channel_latency);
1110 	}
1111 		break;
1112 	case WMA_VDEV_MCC_SET_TIME_QUOTA:
1113 	{
1114 		/* Extract the MCC 2 adapters/vdevs channel numbers and time
1115 		 * quota value for the first adapter only (which is specified
1116 		 * in iwpriv command.
1117 		 */
1118 		uint8_t adapter_2_chan_number =
1119 			privcmd->param_value & 0x000000FF;
1120 		uint8_t adapter_1_chan_number =
1121 			(privcmd->param_value & 0x0000FF00) >> 8;
1122 		uint8_t adapter_1_quota =
1123 			(privcmd->param_value & 0x00FF0000) >> 16;
1124 		int ret = -1;
1125 
1126 		wma_debug("Parsed input: Channel #1:%d, Channel #2:%d, quota 1:%dms",
1127 			  adapter_1_chan_number,
1128 			  adapter_2_chan_number, adapter_1_quota);
1129 
1130 		ret = wma_set_mcc_channel_time_quota(wma_handle,
1131 						     adapter_1_chan_number,
1132 						     adapter_1_quota,
1133 						     adapter_2_chan_number);
1134 	}
1135 		break;
1136 	default:
1137 		wma_err("Invalid wma config command id:%d", privcmd->param_id);
1138 		ret = -EINVAL;
1139 	}
1140 	return ret;
1141 }
1142 
1143 /**
1144  * wma_set_dtim_period() - set dtim period to FW
1145  * @wma: wma handle
1146  * @dtim_params: dtim params
1147  *
1148  * Return: none
1149  */
wma_set_dtim_period(tp_wma_handle wma,struct set_dtim_params * dtim_params)1150 static void wma_set_dtim_period(tp_wma_handle wma,
1151 				struct set_dtim_params *dtim_params)
1152 {
1153 	struct wma_txrx_node *iface =
1154 		&wma->interfaces[dtim_params->session_id];
1155 	if (!wma_is_vdev_valid(dtim_params->session_id)) {
1156 		wma_err("invalid VDEV");
1157 		return;
1158 	}
1159 	wma_debug("set dtim_period %d", dtim_params->dtim_period);
1160 	iface->dtimPeriod = dtim_params->dtim_period;
1161 
1162 }
1163 
wma_is_tx_chainmask_valid(int value,struct target_psoc_info * tgt_hdl)1164 static inline bool wma_is_tx_chainmask_valid(int value,
1165 					     struct target_psoc_info *tgt_hdl)
1166 {
1167 	struct wlan_psoc_host_mac_phy_caps *mac_phy_cap;
1168 	uint8_t total_mac_phy_cnt, i;
1169 
1170 	mac_phy_cap = target_psoc_get_mac_phy_cap(tgt_hdl);
1171 	if (!mac_phy_cap) {
1172 		wma_err("Invalid MAC PHY capabilities handle");
1173 		return false;
1174 	}
1175 
1176 	total_mac_phy_cnt = target_psoc_get_total_mac_phy_cnt(tgt_hdl);
1177 	for (i = 0; i < total_mac_phy_cnt; i++) {
1178 		if (((mac_phy_cap[i].tx_chain_mask_5G) & (value))) {
1179 			return true;
1180 		}
1181 	}
1182 
1183 	return false;
1184 }
1185 
1186 /**
1187  * wma_convert_ac_value() - map ac setting to the value to be used in FW.
1188  * @ac_value: ac value to be mapped.
1189  *
1190  * Return: enum wmi_traffic_ac
1191  */
wma_convert_ac_value(uint32_t ac_value)1192 static inline wmi_traffic_ac wma_convert_ac_value(uint32_t ac_value)
1193 {
1194 	switch (ac_value) {
1195 	case QCA_WLAN_AC_BE:
1196 		return WMI_AC_BE;
1197 	case QCA_WLAN_AC_BK:
1198 		return WMI_AC_BK;
1199 	case QCA_WLAN_AC_VI:
1200 		return WMI_AC_VI;
1201 	case QCA_WLAN_AC_VO:
1202 		return WMI_AC_VO;
1203 	case QCA_WLAN_AC_ALL:
1204 		return WMI_AC_MAX;
1205 	}
1206 	wma_err("invalid enum: %u", ac_value);
1207 	return WMI_AC_MAX;
1208 }
1209 
1210 #ifdef WLAN_FEATURE_11BE
1211 /**
1212  * wma_set_per_link_amsdu_cap() - Set AMSDU/AMPDU capability per link to FW.
1213  * @wma: wma handle
1214  * @privcmd: pointer to set command parameters
1215  * @aggr_type: aggregration type
1216  *
1217  * Return: QDF_STATUS_SUCCESS if set command is sent successfully, else
1218  * QDF_STATUS_E_FAILURE
1219  */
1220 static QDF_STATUS
wma_set_per_link_amsdu_cap(tp_wma_handle wma,wma_cli_set_cmd_t * privcmd,wmi_vdev_custom_aggr_type_t aggr_type)1221 wma_set_per_link_amsdu_cap(tp_wma_handle wma, wma_cli_set_cmd_t *privcmd,
1222 			   wmi_vdev_custom_aggr_type_t aggr_type)
1223 {
1224 	uint8_t vdev_id;
1225 	uint8_t op_mode;
1226 	QDF_STATUS ret = QDF_STATUS_E_FAILURE;
1227 
1228 	for (vdev_id = 0; vdev_id < WLAN_MAX_VDEVS; vdev_id++) {
1229 		op_mode = wlan_get_opmode_from_vdev_id(wma->pdev, vdev_id);
1230 		if (op_mode == QDF_STA_MODE) {
1231 			ret = wma_set_tx_rx_aggr_size(vdev_id,
1232 						      privcmd->param_value,
1233 						      privcmd->param_value,
1234 						      aggr_type);
1235 			if (QDF_IS_STATUS_ERROR(ret)) {
1236 				wma_err("set_aggr_size failed for vdev: %d, ret %d",
1237 					vdev_id, ret);
1238 				return ret;
1239 			}
1240 		}
1241 	}
1242 
1243 	return ret;
1244 }
1245 #else
1246 static inline QDF_STATUS
wma_set_per_link_amsdu_cap(tp_wma_handle wma,wma_cli_set_cmd_t * privcmd,wmi_vdev_custom_aggr_type_t aggr_type)1247 wma_set_per_link_amsdu_cap(tp_wma_handle wma, wma_cli_set_cmd_t *privcmd,
1248 			   wmi_vdev_custom_aggr_type_t aggr_type)
1249 {
1250 	return QDF_STATUS_SUCCESS;
1251 }
1252 #endif
1253 
1254 /**
1255  * wma_process_cli_set_cmd() - set parameters to fw
1256  * @wma: wma handle
1257  * @privcmd: command
1258  *
1259  * Return: none
1260  */
wma_process_cli_set_cmd(tp_wma_handle wma,wma_cli_set_cmd_t * privcmd)1261 static void wma_process_cli_set_cmd(tp_wma_handle wma,
1262 				    wma_cli_set_cmd_t *privcmd)
1263 {
1264 	int vid = privcmd->param_vdev_id, pps_val = 0;
1265 	QDF_STATUS ret;
1266 	struct wma_txrx_node *intr = wma->interfaces;
1267 	struct mac_context *mac = cds_get_context(QDF_MODULE_ID_PE);
1268 	struct qpower_params *qparams = &intr[vid].config.qpower_params;
1269 	struct pdev_params pdev_param = {0};
1270 	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
1271 	struct target_psoc_info *tgt_hdl;
1272 	enum wlan_eht_mode eht_mode;
1273 
1274 	if (!mac) {
1275 		wma_err("Failed to get mac");
1276 		return;
1277 	}
1278 
1279 	tgt_hdl = wlan_psoc_get_tgt_if_handle(wma->psoc);
1280 	if (!tgt_hdl) {
1281 		wma_err("target psoc info is NULL");
1282 		return;
1283 	}
1284 
1285 	if (privcmd->param_id >= WMI_CMDID_MAX) {
1286 		/*
1287 		 * This configuration setting is not done using any wmi
1288 		 * command, call appropriate handler.
1289 		 */
1290 		if (wma_set_priv_cfg(wma, privcmd))
1291 			wma_err("Failed to set wma priv configuration");
1292 		return;
1293 	}
1294 
1295 	switch (privcmd->param_vp_dev) {
1296 	case VDEV_CMD:
1297 		if (!wma_is_vdev_valid(privcmd->param_vdev_id)) {
1298 			wma_err("Vdev id is not valid");
1299 			return;
1300 		}
1301 
1302 		wma_debug("vdev id %d pid %d pval %d", privcmd->param_vdev_id,
1303 			 privcmd->param_id, privcmd->param_value);
1304 		ret = wma_vdev_set_param(wma->wmi_handle,
1305 						      privcmd->param_vdev_id,
1306 						      privcmd->param_id,
1307 						      privcmd->param_value);
1308 		if (QDF_IS_STATUS_ERROR(ret)) {
1309 			wma_err("wma_vdev_set_param failed ret %d", ret);
1310 			return;
1311 		}
1312 		break;
1313 	case PDEV_CMD:
1314 		wma_debug("pdev pid %d pval %d", privcmd->param_id,
1315 			 privcmd->param_value);
1316 		if ((privcmd->param_id == wmi_pdev_param_rx_chain_mask) ||
1317 		    (privcmd->param_id == wmi_pdev_param_tx_chain_mask)) {
1318 			if (QDF_STATUS_SUCCESS !=
1319 					wma_check_txrx_chainmask(
1320 					target_if_get_num_rf_chains(tgt_hdl),
1321 					privcmd->param_value)) {
1322 				wma_debug("Chainmask value is invalid");
1323 				return;
1324 			}
1325 		}
1326 
1327 		if (privcmd->param_id == wmi_pdev_param_tx_chain_mask) {
1328 			if (!wma_is_tx_chainmask_valid(privcmd->param_value,
1329 						       tgt_hdl)) {
1330 				wma_debug("Chainmask value is invalid");
1331 				return;
1332 			}
1333 		}
1334 		pdev_param.param_id = privcmd->param_id;
1335 		pdev_param.param_value = privcmd->param_value;
1336 		if (privcmd->param_id == wmi_pdev_param_twt_ac_config)
1337 			pdev_param.param_value =
1338 				wma_convert_ac_value(pdev_param.param_value);
1339 		ret = wmi_unified_pdev_param_send(wma->wmi_handle,
1340 						 &pdev_param,
1341 						 privcmd->param_sec_value);
1342 		if (QDF_IS_STATUS_ERROR(ret)) {
1343 			wma_err("wma_vdev_set_param failed ret %d", ret);
1344 			return;
1345 		}
1346 		break;
1347 	case GEN_CMD:
1348 	{
1349 		struct wma_txrx_node *intr = wma->interfaces;
1350 		wmi_vdev_custom_aggr_type_t aggr_type =
1351 			WMI_VDEV_CUSTOM_AGGR_TYPE_AMSDU;
1352 
1353 		wma_debug("gen pid %d pval %d", privcmd->param_id,
1354 			 privcmd->param_value);
1355 
1356 		switch (privcmd->param_id) {
1357 		case GEN_VDEV_PARAM_AMSDU:
1358 		case GEN_VDEV_PARAM_AMPDU:
1359 			if (!soc) {
1360 				wma_err("SOC context is NULL");
1361 				return;
1362 			}
1363 
1364 			if (privcmd->param_id == GEN_VDEV_PARAM_AMPDU) {
1365 				ret = cdp_aggr_cfg(soc, privcmd->param_vdev_id,
1366 						   privcmd->param_value, 0);
1367 				if (ret)
1368 					wma_err("cdp_aggr_cfg set ampdu failed ret %d",
1369 						ret);
1370 				else
1371 					intr[privcmd->param_vdev_id].config.
1372 						ampdu = privcmd->param_value;
1373 
1374 				aggr_type =
1375 					WMI_VDEV_CUSTOM_AGGR_TYPE_AMPDU;
1376 			}
1377 
1378 			wlan_mlme_get_eht_mode(wma->psoc, &eht_mode);
1379 			if (eht_mode == WLAN_EHT_MODE_MLSR ||
1380 			    eht_mode == WLAN_EHT_MODE_MLMR) {
1381 				ret = wma_set_per_link_amsdu_cap(wma, privcmd,
1382 								 aggr_type);
1383 				if (QDF_IS_STATUS_ERROR(ret))
1384 					return;
1385 			} else {
1386 				ret = wma_set_tx_rx_aggr_size(
1387 							vid,
1388 							privcmd->param_value,
1389 							privcmd->param_value,
1390 							aggr_type);
1391 				if (QDF_IS_STATUS_ERROR(ret)) {
1392 					wma_err("set_aggr_size failed ret %d",
1393 						ret);
1394 					return;
1395 				}
1396 			}
1397 			break;
1398 		case GEN_PARAM_CRASH_INJECT:
1399 			if (QDF_GLOBAL_FTM_MODE  == cds_get_conparam())
1400 				wma_err("Crash inject not allowed in FTM mode");
1401 			else
1402 				ret = wma_crash_inject(wma,
1403 						privcmd->param_value,
1404 						privcmd->param_sec_value);
1405 			break;
1406 		case GEN_PARAM_CAPTURE_TSF:
1407 			ret = wma_capture_tsf(wma, privcmd->param_value);
1408 			break;
1409 		case GEN_PARAM_RESET_TSF_GPIO:
1410 			ret = wma_reset_tsf_gpio(wma, privcmd->param_value);
1411 			break;
1412 		default:
1413 			ret = wma_set_tsf_auto_report(wma,
1414 						      privcmd->param_vdev_id,
1415 						      privcmd->param_id,
1416 						      privcmd->param_value);
1417 			if (ret == QDF_STATUS_E_FAILURE)
1418 				wma_err("Invalid param id 0x%x",
1419 					privcmd->param_id);
1420 			break;
1421 		}
1422 		break;
1423 	}
1424 	case DBG_CMD:
1425 		wma_debug("dbg pid %d pval %d", privcmd->param_id,
1426 			 privcmd->param_value);
1427 		switch (privcmd->param_id) {
1428 		case WMI_DBGLOG_LOG_LEVEL:
1429 			ret = dbglog_set_log_lvl(wma->wmi_handle,
1430 						   privcmd->param_value);
1431 			if (ret)
1432 				wma_err("dbglog_set_log_lvl failed ret %d",
1433 					 ret);
1434 			break;
1435 		case WMI_DBGLOG_VAP_ENABLE:
1436 			ret = dbglog_vap_log_enable(wma->wmi_handle,
1437 						    privcmd->param_value, true);
1438 			if (ret)
1439 				wma_err("dbglog_vap_log_enable failed ret %d",
1440 					 ret);
1441 			break;
1442 		case WMI_DBGLOG_VAP_DISABLE:
1443 			ret = dbglog_vap_log_enable(wma->wmi_handle,
1444 						privcmd->param_value, false);
1445 			if (ret)
1446 				wma_err("dbglog_vap_log_enable failed ret %d",
1447 					 ret);
1448 			break;
1449 		case WMI_DBGLOG_MODULE_ENABLE:
1450 			ret = dbglog_module_log_enable(wma->wmi_handle,
1451 						privcmd->param_value, true);
1452 			if (ret)
1453 				wma_err("dbglog_module_log_enable failed ret %d",
1454 					ret);
1455 			break;
1456 		case WMI_DBGLOG_MODULE_DISABLE:
1457 			ret = dbglog_module_log_enable(wma->wmi_handle,
1458 						privcmd->param_value, false);
1459 			if (ret)
1460 				wma_err("dbglog_module_log_enable failed ret %d",
1461 					ret);
1462 			break;
1463 		case WMI_DBGLOG_MOD_LOG_LEVEL:
1464 			ret = dbglog_set_mod_log_lvl(wma->wmi_handle,
1465 						       privcmd->param_value);
1466 			if (ret)
1467 				wma_err("dbglog_module_log_enable failed ret %d",
1468 					ret);
1469 			break;
1470 		case WMI_DBGLOG_MOD_WOW_LOG_LEVEL:
1471 			ret = dbglog_set_mod_wow_log_lvl(wma->wmi_handle,
1472 							 privcmd->param_value);
1473 			if (ret)
1474 				wma_err("WMI_DBGLOG_MOD_WOW_LOG_LEVEL failed ret %d",
1475 					ret);
1476 			break;
1477 		case WMI_DBGLOG_TYPE:
1478 			ret = dbglog_parser_type_init(wma->wmi_handle,
1479 							privcmd->param_value);
1480 			if (ret)
1481 				wma_err("dbglog_parser_type_init failed ret %d",
1482 					ret);
1483 			break;
1484 		case WMI_DBGLOG_REPORT_ENABLE:
1485 			ret = dbglog_report_enable(wma->wmi_handle,
1486 						     privcmd->param_value);
1487 			if (ret)
1488 				wma_err("dbglog_report_enable failed ret %d",
1489 					 ret);
1490 			break;
1491 		case WMI_WLAN_PROFILE_TRIGGER_CMDID:
1492 			ret = wma_unified_fw_profiling_cmd(wma->wmi_handle,
1493 					 WMI_WLAN_PROFILE_TRIGGER_CMDID,
1494 					 privcmd->param_value, 0);
1495 			if (ret)
1496 				wma_err("Profile cmd failed for %d ret %d",
1497 					WMI_WLAN_PROFILE_TRIGGER_CMDID, ret);
1498 			break;
1499 		case WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID:
1500 			ret = wma_unified_fw_profiling_cmd(wma->wmi_handle,
1501 				  WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID,
1502 				  privcmd->param_value,
1503 				  privcmd->param_sec_value);
1504 			if (ret)
1505 				wma_err("Profile cmd failed for %d ret %d",
1506 					WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID,
1507 					ret);
1508 			break;
1509 		case WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID:
1510 			ret = wma_unified_fw_profiling_cmd(wma->wmi_handle,
1511 					 WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID,
1512 					 privcmd->param_value,
1513 					 privcmd->param_sec_value);
1514 			if (ret)
1515 				wma_err("Profile cmd failed for %d ret %d",
1516 					WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID,
1517 					ret);
1518 			break;
1519 		case WMI_WLAN_PROFILE_LIST_PROFILE_ID_CMDID:
1520 			ret = wma_unified_fw_profiling_cmd(wma->wmi_handle,
1521 					 WMI_WLAN_PROFILE_LIST_PROFILE_ID_CMDID,
1522 					 0, 0);
1523 			if (ret)
1524 				wma_err("Profile cmd failed for %d ret %d",
1525 					WMI_WLAN_PROFILE_LIST_PROFILE_ID_CMDID,
1526 					ret);
1527 			break;
1528 		case WMI_WLAN_PROFILE_GET_PROFILE_DATA_CMDID:
1529 			ret = wma_unified_fw_profiling_cmd(wma->wmi_handle,
1530 					WMI_WLAN_PROFILE_GET_PROFILE_DATA_CMDID,
1531 					0, 0);
1532 			if (ret)
1533 				wma_err("Profile cmd failed for %d ret %d",
1534 					WMI_WLAN_PROFILE_GET_PROFILE_DATA_CMDID,
1535 					ret);
1536 			break;
1537 		case WMI_PDEV_GREEN_AP_PS_ENABLE_CMDID:
1538 			/* Set the Green AP */
1539 			ret = wmi_unified_green_ap_ps_send
1540 					(wma->wmi_handle, privcmd->param_value,
1541 					 WMA_WILDCARD_PDEV_ID);
1542 			if (ret) {
1543 				wma_err("Set GreenAP Failed val %d",
1544 					privcmd->param_value);
1545 			}
1546 			break;
1547 
1548 		default:
1549 			wma_err("Invalid param id 0x%x", privcmd->param_id);
1550 			break;
1551 		}
1552 		break;
1553 	case PPS_CMD:
1554 		wma_debug("dbg pid %d pval %d", privcmd->param_id,
1555 			 privcmd->param_value);
1556 		switch (privcmd->param_id) {
1557 
1558 		case WMI_VDEV_PPS_PAID_MATCH:
1559 			pps_val = ((privcmd->param_value << 31) & 0xffff0000) |
1560 				  (PKT_PWR_SAVE_PAID_MATCH & 0xffff);
1561 			intr[vid].config.pps_params.paid_match_enable =
1562 				privcmd->param_value;
1563 			break;
1564 		case WMI_VDEV_PPS_GID_MATCH:
1565 			pps_val = ((privcmd->param_value << 31) & 0xffff0000) |
1566 				  (PKT_PWR_SAVE_GID_MATCH & 0xffff);
1567 			intr[vid].config.pps_params.gid_match_enable =
1568 				privcmd->param_value;
1569 			break;
1570 		case WMI_VDEV_PPS_EARLY_TIM_CLEAR:
1571 			pps_val = ((privcmd->param_value << 31) & 0xffff0000) |
1572 				  (PKT_PWR_SAVE_EARLY_TIM_CLEAR & 0xffff);
1573 			intr[vid].config.pps_params.tim_clear =
1574 				privcmd->param_value;
1575 			break;
1576 		case WMI_VDEV_PPS_EARLY_DTIM_CLEAR:
1577 			pps_val = ((privcmd->param_value << 31) & 0xffff0000) |
1578 				  (PKT_PWR_SAVE_EARLY_DTIM_CLEAR & 0xffff);
1579 			intr[vid].config.pps_params.dtim_clear =
1580 				privcmd->param_value;
1581 			break;
1582 		case WMI_VDEV_PPS_EOF_PAD_DELIM:
1583 			pps_val = ((privcmd->param_value << 31) & 0xffff0000) |
1584 				  (PKT_PWR_SAVE_EOF_PAD_DELIM & 0xffff);
1585 			intr[vid].config.pps_params.eof_delim =
1586 				privcmd->param_value;
1587 			break;
1588 		case WMI_VDEV_PPS_MACADDR_MISMATCH:
1589 			pps_val = ((privcmd->param_value << 31) & 0xffff0000) |
1590 				  (PKT_PWR_SAVE_MACADDR_MISMATCH & 0xffff);
1591 			intr[vid].config.pps_params.mac_match =
1592 				privcmd->param_value;
1593 			break;
1594 		case WMI_VDEV_PPS_DELIM_CRC_FAIL:
1595 			pps_val = ((privcmd->param_value << 31) & 0xffff0000) |
1596 				  (PKT_PWR_SAVE_DELIM_CRC_FAIL & 0xffff);
1597 			intr[vid].config.pps_params.delim_fail =
1598 				privcmd->param_value;
1599 			break;
1600 		case WMI_VDEV_PPS_GID_NSTS_ZERO:
1601 			pps_val = ((privcmd->param_value << 31) & 0xffff0000) |
1602 				  (PKT_PWR_SAVE_GID_NSTS_ZERO & 0xffff);
1603 			intr[vid].config.pps_params.nsts_zero =
1604 				privcmd->param_value;
1605 			break;
1606 		case WMI_VDEV_PPS_RSSI_CHECK:
1607 			pps_val = ((privcmd->param_value << 31) & 0xffff0000) |
1608 				  (PKT_PWR_SAVE_RSSI_CHECK & 0xffff);
1609 			intr[vid].config.pps_params.rssi_chk =
1610 				privcmd->param_value;
1611 			break;
1612 		case WMI_VDEV_PPS_5G_EBT:
1613 			pps_val = ((privcmd->param_value << 31) & 0xffff0000) |
1614 				  (PKT_PWR_SAVE_5G_EBT & 0xffff);
1615 			intr[vid].config.pps_params.ebt_5g =
1616 				privcmd->param_value;
1617 			break;
1618 		default:
1619 			wma_err("Invalid param id 0x%x", privcmd->param_id);
1620 			break;
1621 		}
1622 		break;
1623 
1624 	case QPOWER_CMD:
1625 		wma_debug("QPOWER CLI CMD pid %d pval %d", privcmd->param_id,
1626 			 privcmd->param_value);
1627 		switch (privcmd->param_id) {
1628 		case WMI_STA_PS_PARAM_QPOWER_PSPOLL_COUNT:
1629 			wma_debug("QPOWER CLI CMD:Ps Poll Cnt val %d",
1630 				 privcmd->param_value);
1631 			/* Set the QPower Ps Poll Count */
1632 			ret = wma_unified_set_sta_ps_param(wma->wmi_handle,
1633 				vid, WMI_STA_PS_PARAM_QPOWER_PSPOLL_COUNT,
1634 				privcmd->param_value);
1635 			if (ret) {
1636 				wma_err("Set Q-PsPollCnt Failed vdevId %d val %d",
1637 					vid, privcmd->param_value);
1638 			} else {
1639 				qparams->max_ps_poll_cnt = privcmd->param_value;
1640 			}
1641 			break;
1642 		case WMI_STA_PS_PARAM_QPOWER_MAX_TX_BEFORE_WAKE:
1643 			wma_debug("QPOWER CLI CMD:Max Tx Before wake val %d",
1644 				 privcmd->param_value);
1645 			/* Set the QPower Max Tx Before Wake */
1646 			ret = wma_unified_set_sta_ps_param(wma->wmi_handle,
1647 				vid, WMI_STA_PS_PARAM_QPOWER_MAX_TX_BEFORE_WAKE,
1648 				privcmd->param_value);
1649 			if (ret) {
1650 				wma_err("Set Q-MaxTxBefWake Failed vId %d val %d",
1651 					vid, privcmd->param_value);
1652 			} else {
1653 				qparams->max_tx_before_wake =
1654 						privcmd->param_value;
1655 			}
1656 			break;
1657 		case WMI_STA_PS_PARAM_QPOWER_SPEC_PSPOLL_WAKE_INTERVAL:
1658 			wma_debug("QPOWER CLI CMD:Ps Poll Wake Inv val %d",
1659 				 privcmd->param_value);
1660 			/* Set the QPower Spec Ps Poll Wake Inv */
1661 			ret = wma_unified_set_sta_ps_param(wma->wmi_handle, vid,
1662 				WMI_STA_PS_PARAM_QPOWER_SPEC_PSPOLL_WAKE_INTERVAL,
1663 				privcmd->param_value);
1664 			if (ret) {
1665 				wma_err("Set Q-PsPoll WakeIntv Failed vId %d val %d",
1666 					vid, privcmd->param_value);
1667 			} else {
1668 				qparams->spec_ps_poll_wake_interval =
1669 					privcmd->param_value;
1670 			}
1671 			break;
1672 		case WMI_STA_PS_PARAM_QPOWER_SPEC_MAX_SPEC_NODATA_PSPOLL:
1673 			wma_debug("QPOWER CLI CMD:Spec NoData Ps Poll val %d",
1674 				 privcmd->param_value);
1675 			/* Set the QPower Spec NoData PsPoll */
1676 			ret = wma_unified_set_sta_ps_param(wma->wmi_handle, vid,
1677 				WMI_STA_PS_PARAM_QPOWER_SPEC_MAX_SPEC_NODATA_PSPOLL,
1678 				privcmd->param_value);
1679 			if (ret) {
1680 				wma_err("Set Q-SpecNoDataPsPoll Failed vId %d val %d",
1681 					vid, privcmd->param_value);
1682 			} else {
1683 				qparams->max_spec_nodata_ps_poll =
1684 					privcmd->param_value;
1685 			}
1686 			break;
1687 
1688 		default:
1689 			wma_err("Invalid param id 0x%x", privcmd->param_id);
1690 			break;
1691 		}
1692 		break;
1693 	case GTX_CMD:
1694 		wma_debug("vdev id %d pid %d pval %d", privcmd->param_vdev_id,
1695 			 privcmd->param_id, privcmd->param_value);
1696 		switch (privcmd->param_id) {
1697 		case wmi_vdev_param_gtx_ht_mcs:
1698 			intr[vid].config.gtx_info.gtxRTMask[0] =
1699 				privcmd->param_value;
1700 			ret = wmi_unified_vdev_set_gtx_cfg_send(wma->wmi_handle,
1701 					privcmd->param_vdev_id,
1702 					&intr[vid].config.gtx_info);
1703 			break;
1704 		case wmi_vdev_param_gtx_vht_mcs:
1705 			intr[vid].config.gtx_info.gtxRTMask[1] =
1706 				privcmd->param_value;
1707 			ret = wmi_unified_vdev_set_gtx_cfg_send(wma->wmi_handle,
1708 					privcmd->param_vdev_id,
1709 					&intr[vid].config.gtx_info);
1710 			break;
1711 
1712 		case wmi_vdev_param_gtx_usr_cfg:
1713 			intr[vid].config.gtx_info.gtxUsrcfg =
1714 				privcmd->param_value;
1715 			ret = wmi_unified_vdev_set_gtx_cfg_send(wma->wmi_handle,
1716 					privcmd->param_vdev_id,
1717 					&intr[vid].config.gtx_info);
1718 			break;
1719 
1720 		case wmi_vdev_param_gtx_thre:
1721 			intr[vid].config.gtx_info.gtxPERThreshold =
1722 				privcmd->param_value;
1723 			ret = wmi_unified_vdev_set_gtx_cfg_send(wma->wmi_handle,
1724 					privcmd->param_vdev_id,
1725 					&intr[vid].config.gtx_info);
1726 			break;
1727 
1728 		case wmi_vdev_param_gtx_margin:
1729 			intr[vid].config.gtx_info.gtxPERMargin =
1730 				privcmd->param_value;
1731 			ret = wmi_unified_vdev_set_gtx_cfg_send(wma->wmi_handle,
1732 					privcmd->param_vdev_id,
1733 					&intr[vid].config.gtx_info);
1734 			break;
1735 
1736 		case wmi_vdev_param_gtx_step:
1737 			intr[vid].config.gtx_info.gtxTPCstep =
1738 				privcmd->param_value;
1739 			ret = wmi_unified_vdev_set_gtx_cfg_send(wma->wmi_handle,
1740 					privcmd->param_vdev_id,
1741 					&intr[vid].config.gtx_info);
1742 			break;
1743 
1744 		case wmi_vdev_param_gtx_mintpc:
1745 			intr[vid].config.gtx_info.gtxTPCMin =
1746 				privcmd->param_value;
1747 			ret = wmi_unified_vdev_set_gtx_cfg_send(wma->wmi_handle,
1748 					privcmd->param_vdev_id,
1749 					&intr[vid].config.gtx_info);
1750 			break;
1751 
1752 		case wmi_vdev_param_gtx_bw_mask:
1753 			intr[vid].config.gtx_info.gtxBWMask =
1754 				privcmd->param_value;
1755 			ret = wmi_unified_vdev_set_gtx_cfg_send(wma->wmi_handle,
1756 					privcmd->param_vdev_id,
1757 					&intr[vid].config.gtx_info);
1758 			if (ret) {
1759 				wma_err("wma_vdev_set_param failed ret %d",
1760 					 ret);
1761 				return;
1762 			}
1763 			break;
1764 		default:
1765 			break;
1766 		}
1767 		break;
1768 
1769 	default:
1770 		wma_err("Invalid vpdev command id");
1771 	}
1772 	if (1 == privcmd->param_vp_dev) {
1773 		switch (privcmd->param_id) {
1774 		case wmi_vdev_param_nss:
1775 			intr[vid].config.nss = privcmd->param_value;
1776 			break;
1777 		case wmi_vdev_param_ldpc:
1778 			intr[vid].config.ldpc = privcmd->param_value;
1779 			break;
1780 		case wmi_vdev_param_tx_stbc:
1781 			intr[vid].config.tx_stbc = privcmd->param_value;
1782 			break;
1783 		case wmi_vdev_param_rx_stbc:
1784 			intr[vid].config.rx_stbc = privcmd->param_value;
1785 			break;
1786 		case wmi_vdev_param_sgi:
1787 			intr[vid].config.shortgi = privcmd->param_value;
1788 			break;
1789 		case wmi_vdev_param_enable_rtscts:
1790 			intr[vid].config.rtscts_en = privcmd->param_value;
1791 			break;
1792 		case wmi_vdev_param_chwidth:
1793 			intr[vid].config.chwidth = privcmd->param_value;
1794 			break;
1795 		case wmi_vdev_param_fixed_rate:
1796 			intr[vid].config.tx_rate = privcmd->param_value;
1797 			break;
1798 		case wmi_vdev_param_early_rx_adjust_enable:
1799 			intr[vid].config.erx_adjust = privcmd->param_value;
1800 			break;
1801 		case wmi_vdev_param_early_rx_tgt_bmiss_num:
1802 			intr[vid].config.erx_bmiss_num = privcmd->param_value;
1803 			break;
1804 		case wmi_vdev_param_early_rx_bmiss_sample_cycle:
1805 			intr[vid].config.erx_bmiss_cycle = privcmd->param_value;
1806 			break;
1807 		case wmi_vdev_param_early_rx_slop_step:
1808 			intr[vid].config.erx_slop_step = privcmd->param_value;
1809 			break;
1810 		case wmi_vdev_param_early_rx_init_slop:
1811 			intr[vid].config.erx_init_slop = privcmd->param_value;
1812 			break;
1813 		case wmi_vdev_param_early_rx_adjust_pause:
1814 			intr[vid].config.erx_adj_pause = privcmd->param_value;
1815 			break;
1816 		case wmi_vdev_param_early_rx_drift_sample:
1817 			intr[vid].config.erx_dri_sample = privcmd->param_value;
1818 			break;
1819 		case wmi_vdev_param_he_dcm_enable:
1820 		case wmi_vdev_param_he_range_ext:
1821 			wma_set_he_vdev_param(&intr[vid], privcmd->param_id,
1822 					      privcmd->param_value);
1823 			break;
1824 		default:
1825 			wma_debug("vdev cmd is not part vdev_cli_config 0x%x",
1826 				  privcmd->param_id);
1827 			break;
1828 		}
1829 	} else if (2 == privcmd->param_vp_dev) {
1830 		switch (privcmd->param_id) {
1831 		case wmi_pdev_param_ani_enable:
1832 			wma->pdevconfig.ani_enable = privcmd->param_value;
1833 			break;
1834 		case wmi_pdev_param_ani_poll_period:
1835 			wma->pdevconfig.ani_poll_len = privcmd->param_value;
1836 			break;
1837 		case wmi_pdev_param_ani_listen_period:
1838 			wma->pdevconfig.ani_listen_len = privcmd->param_value;
1839 			break;
1840 		case wmi_pdev_param_ani_ofdm_level:
1841 			wma->pdevconfig.ani_ofdm_level = privcmd->param_value;
1842 			break;
1843 		case wmi_pdev_param_ani_cck_level:
1844 			wma->pdevconfig.ani_cck_level = privcmd->param_value;
1845 			break;
1846 		case wmi_pdev_param_dynamic_bw:
1847 			wma->pdevconfig.cwmenable = privcmd->param_value;
1848 			break;
1849 		case wmi_pdev_param_cts_cbw:
1850 			wma->pdevconfig.cts_cbw = privcmd->param_value;
1851 			break;
1852 		case wmi_pdev_param_tx_chain_mask:
1853 			wma->pdevconfig.txchainmask = privcmd->param_value;
1854 			break;
1855 		case wmi_pdev_param_rx_chain_mask:
1856 			wma->pdevconfig.rxchainmask = privcmd->param_value;
1857 			break;
1858 		case wmi_pdev_param_txpower_limit2g:
1859 			wma->pdevconfig.txpow2g = privcmd->param_value;
1860 			if (mac->mlme_cfg->gen.band_capability & BIT(REG_BAND_2G))
1861 				mac->mlme_cfg->power.current_tx_power_level =
1862 					(uint8_t)privcmd->param_value;
1863 			else
1864 				wma_err("Current band is not 2G");
1865 			break;
1866 		case wmi_pdev_param_txpower_limit5g:
1867 			wma->pdevconfig.txpow5g = privcmd->param_value;
1868 			if (mac->mlme_cfg->gen.band_capability & BIT(REG_BAND_5G))
1869 				mac->mlme_cfg->power.current_tx_power_level =
1870 					(uint8_t)privcmd->param_value;
1871 			else
1872 				wma_err("Current band is not 5G");
1873 			break;
1874 		default:
1875 			wma_debug("Invalid wma_cli_set pdev command/Not yet implemented 0x%x",
1876 				 privcmd->param_id);
1877 			break;
1878 		}
1879 	} else if (5 == privcmd->param_vp_dev) {
1880 		ret = wma_vdev_set_param(wma->wmi_handle,
1881 					privcmd->param_vdev_id,
1882 					wmi_vdev_param_packet_powersave,
1883 					pps_val);
1884 		if (ret)
1885 			wma_err("Failed to send wmi packet power save cmd");
1886 		else
1887 			wma_debug("Sent packet power save cmd %d value %x to target",
1888 				privcmd->param_id, pps_val);
1889 	}
1890 }
1891 
wma_critical_events_in_flight(void)1892 uint32_t wma_critical_events_in_flight(void)
1893 {
1894 	t_wma_handle *wma;
1895 
1896 	wma = cds_get_context(QDF_MODULE_ID_WMA);
1897 	if (!wma)
1898 		return 0;
1899 
1900 	if (wmi_validate_handle(wma->wmi_handle))
1901 		return 0;
1902 
1903 	return wmi_critical_events_in_flight(wma->wmi_handle);
1904 }
1905 
1906 /**
1907  * wma_process_hal_pwr_dbg_cmd() - send hal pwr dbg cmd to fw.
1908  * @handle: wma handle
1909  * @sir_pwr_dbg_params: unit test command
1910  *
1911  * This function send unit test command to fw.
1912  *
1913  * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error
1914  */
wma_process_hal_pwr_dbg_cmd(WMA_HANDLE handle,struct sir_mac_pwr_dbg_cmd * sir_pwr_dbg_params)1915 QDF_STATUS wma_process_hal_pwr_dbg_cmd(WMA_HANDLE handle,
1916 				       struct sir_mac_pwr_dbg_cmd *
1917 				       sir_pwr_dbg_params)
1918 {
1919 	tp_wma_handle wma_handle = (tp_wma_handle)handle;
1920 	int i;
1921 	struct wmi_power_dbg_params wmi_pwr_dbg_params;
1922 	QDF_STATUS status;
1923 
1924 	if (!sir_pwr_dbg_params) {
1925 		wma_err("sir_pwr_dbg_params is null");
1926 		return QDF_STATUS_E_INVAL;
1927 	}
1928 	wmi_pwr_dbg_params.module_id = sir_pwr_dbg_params->module_id;
1929 	wmi_pwr_dbg_params.pdev_id = sir_pwr_dbg_params->pdev_id;
1930 	wmi_pwr_dbg_params.num_args = sir_pwr_dbg_params->num_args;
1931 
1932 	for (i = 0; i < wmi_pwr_dbg_params.num_args; i++)
1933 		wmi_pwr_dbg_params.args[i] = sir_pwr_dbg_params->args[i];
1934 
1935 	status = wmi_unified_send_power_dbg_cmd(wma_handle->wmi_handle,
1936 						&wmi_pwr_dbg_params);
1937 
1938 	return status;
1939 }
1940 
wma_discard_fw_event(struct scheduler_msg * msg)1941 static QDF_STATUS wma_discard_fw_event(struct scheduler_msg *msg)
1942 {
1943 	if (!msg->bodyptr)
1944 		return QDF_STATUS_E_INVAL;
1945 
1946 	qdf_mem_free(msg->bodyptr);
1947 	msg->bodyptr = NULL;
1948 	msg->bodyval = 0;
1949 	msg->type = 0;
1950 
1951 	return QDF_STATUS_SUCCESS;
1952 }
1953 
1954 QDF_STATUS
wma_vdev_nss_chain_params_send(uint8_t vdev_id,struct wlan_mlme_nss_chains * user_cfg)1955 wma_vdev_nss_chain_params_send(uint8_t vdev_id,
1956 			       struct wlan_mlme_nss_chains *user_cfg)
1957 {
1958 	tp_wma_handle wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
1959 	struct vdev_nss_chains vdev_user_cfg;
1960 	if (!wma_handle)
1961 		return QDF_STATUS_E_FAILURE;
1962 
1963 	vdev_user_cfg.disable_rx_mrc[NSS_CHAINS_BAND_2GHZ] =
1964 				user_cfg->disable_rx_mrc[NSS_CHAINS_BAND_2GHZ];
1965 	vdev_user_cfg.disable_tx_mrc[NSS_CHAINS_BAND_2GHZ] =
1966 				user_cfg->disable_tx_mrc[NSS_CHAINS_BAND_2GHZ];
1967 	vdev_user_cfg.disable_rx_mrc[NSS_CHAINS_BAND_5GHZ] =
1968 				user_cfg->disable_rx_mrc[NSS_CHAINS_BAND_5GHZ];
1969 	vdev_user_cfg.disable_tx_mrc[NSS_CHAINS_BAND_5GHZ] =
1970 				user_cfg->disable_tx_mrc[NSS_CHAINS_BAND_5GHZ];
1971 
1972 	vdev_user_cfg.num_rx_chains[NSS_CHAINS_BAND_2GHZ]
1973 				= user_cfg->num_rx_chains[NSS_CHAINS_BAND_2GHZ];
1974 	vdev_user_cfg.num_tx_chains[NSS_CHAINS_BAND_2GHZ]
1975 				= user_cfg->num_tx_chains[NSS_CHAINS_BAND_2GHZ];
1976 	vdev_user_cfg.num_rx_chains[NSS_CHAINS_BAND_5GHZ] =
1977 				user_cfg->num_rx_chains[NSS_CHAINS_BAND_5GHZ];
1978 	vdev_user_cfg.num_tx_chains[NSS_CHAINS_BAND_5GHZ] =
1979 				user_cfg->num_tx_chains[NSS_CHAINS_BAND_5GHZ];
1980 
1981 	vdev_user_cfg.rx_nss[NSS_CHAINS_BAND_2GHZ] =
1982 				user_cfg->rx_nss[NSS_CHAINS_BAND_2GHZ];
1983 	vdev_user_cfg.tx_nss[NSS_CHAINS_BAND_2GHZ] =
1984 				user_cfg->tx_nss[NSS_CHAINS_BAND_2GHZ];
1985 	vdev_user_cfg.rx_nss[NSS_CHAINS_BAND_5GHZ] =
1986 				user_cfg->rx_nss[NSS_CHAINS_BAND_5GHZ];
1987 	vdev_user_cfg.tx_nss[NSS_CHAINS_BAND_5GHZ] =
1988 				user_cfg->tx_nss[NSS_CHAINS_BAND_5GHZ];
1989 
1990 	vdev_user_cfg.num_tx_chains_11a = user_cfg->num_tx_chains_11a;
1991 	vdev_user_cfg.num_tx_chains_11b = user_cfg->num_tx_chains_11b;
1992 	vdev_user_cfg.num_tx_chains_11g = user_cfg->num_tx_chains_11g;
1993 
1994 	return wmi_unified_vdev_nss_chain_params_send(wma_handle->wmi_handle,
1995 						      vdev_id,
1996 						      &vdev_user_cfg);
1997 }
1998 
1999 /**
2000  * wma_antenna_isolation_event_handler() - antenna isolation event handler
2001  * @handle: wma handle
2002  * @param: event data
2003  * @len: length
2004  *
2005  * Return: 0 for success or error code
2006  */
wma_antenna_isolation_event_handler(void * handle,u8 * param,u32 len)2007 static int wma_antenna_isolation_event_handler(void *handle,
2008 					       u8 *param,
2009 					       u32 len)
2010 {
2011 	struct scheduler_msg cds_msg = {0};
2012 	wmi_coex_report_isolation_event_fixed_param *event;
2013 	WMI_COEX_REPORT_ANTENNA_ISOLATION_EVENTID_param_tlvs *param_buf;
2014 	struct sir_isolation_resp *pisolation;
2015 	struct mac_context *mac = NULL;
2016 
2017 	wma_debug("handle %pK param %pK len %d", handle, param, len);
2018 
2019 	mac = (struct mac_context *)cds_get_context(QDF_MODULE_ID_PE);
2020 	if (!mac) {
2021 		wma_err("Invalid mac context");
2022 		return -EINVAL;
2023 	}
2024 
2025 	pisolation = qdf_mem_malloc(sizeof(*pisolation));
2026 	if (!pisolation)
2027 		return 0;
2028 
2029 	param_buf =
2030 		(WMI_COEX_REPORT_ANTENNA_ISOLATION_EVENTID_param_tlvs *)param;
2031 	if (!param_buf) {
2032 		wma_err("Invalid isolation event");
2033 		return -EINVAL;
2034 	}
2035 	event = param_buf->fixed_param;
2036 	pisolation->isolation_chain0 = event->isolation_chain0;
2037 	pisolation->isolation_chain1 = event->isolation_chain1;
2038 	pisolation->isolation_chain2 = event->isolation_chain2;
2039 	pisolation->isolation_chain3 = event->isolation_chain3;
2040 
2041 	wma_debug("chain1 %d chain2 %d chain3 %d chain4 %d",
2042 		 pisolation->isolation_chain0, pisolation->isolation_chain1,
2043 		 pisolation->isolation_chain2, pisolation->isolation_chain3);
2044 
2045 	cds_msg.type = eWNI_SME_ANTENNA_ISOLATION_RSP;
2046 	cds_msg.bodyptr = pisolation;
2047 	cds_msg.bodyval = 0;
2048 	if (QDF_STATUS_SUCCESS !=
2049 	    scheduler_post_message(QDF_MODULE_ID_WMA,
2050 				   QDF_MODULE_ID_SME,
2051 				   QDF_MODULE_ID_SME, &cds_msg)) {
2052 		wma_err("could not post peer info rsp msg to SME");
2053 		/* free the mem and return */
2054 		qdf_mem_free(pisolation);
2055 	}
2056 
2057 	return 0;
2058 }
2059 
2060 /**
2061  * wma_init_max_no_of_peers - API to initialize wma configuration params
2062  * @wma_handle: WMA Handle
2063  * @max_peers: Max Peers supported
2064  *
2065  * Return: void
2066  */
wma_init_max_no_of_peers(tp_wma_handle wma_handle,uint16_t max_peers)2067 static uint8_t wma_init_max_no_of_peers(tp_wma_handle wma_handle,
2068 				     uint16_t max_peers)
2069 {
2070 	struct wma_ini_config *cfg = wma_get_ini_handle(wma_handle);
2071 	struct hif_opaque_softc *scn = cds_get_context(QDF_MODULE_ID_HIF);
2072 	uint32_t tgt_version = hif_get_target_info_handle(scn)->target_version;
2073 	uint8_t max_no_of_peers;
2074 	uint8_t max_supported_peers;
2075 
2076 	if (!cfg) {
2077 		wma_err("NULL WMA ini handle");
2078 		return 0;
2079 	}
2080 
2081 	switch (tgt_version) {
2082 	case AR6320_REV1_1_VERSION:
2083 		max_supported_peers = MAX_SUPPORTED_PEERS_REV1_1;
2084 		break;
2085 	case AR6320_REV1_3_VERSION:
2086 		max_supported_peers = MAX_SUPPORTED_PEERS_REV1_3;
2087 		break;
2088 	default:
2089 		max_supported_peers = MAX_SUPPORTED_PEERS;
2090 		break;
2091 	}
2092 	max_no_of_peers = (max_peers > max_supported_peers) ?
2093 				max_supported_peers : max_peers;
2094 	cfg->max_no_of_peers = max_no_of_peers;
2095 
2096 	return max_no_of_peers;
2097 }
2098 
2099 /**
2100  * wma_cleanup_hold_req() - cleanup hold request queue
2101  * @wma: wma handle
2102  *
2103  * Return: none
2104  */
wma_cleanup_hold_req(tp_wma_handle wma)2105 static void wma_cleanup_hold_req(tp_wma_handle wma)
2106 {
2107 	struct wma_target_req *req_msg = NULL;
2108 	qdf_list_node_t *node1 = NULL;
2109 
2110 	qdf_spin_lock_bh(&wma->wma_hold_req_q_lock);
2111 	if (!qdf_list_size(&wma->wma_hold_req_queue)) {
2112 		qdf_spin_unlock_bh(&wma->wma_hold_req_q_lock);
2113 		wma_debug("request queue is empty");
2114 		return;
2115 	}
2116 
2117 	/* peek front, and then cleanup it in wma_hold_req_timer */
2118 	while (QDF_STATUS_SUCCESS ==
2119 		qdf_list_peek_front(&wma->wma_hold_req_queue, &node1)) {
2120 		req_msg = qdf_container_of(node1, struct wma_target_req, node);
2121 		qdf_spin_unlock_bh(&wma->wma_hold_req_q_lock);
2122 		/* Cleanup timeout handler */
2123 		qdf_mc_timer_stop(&req_msg->event_timeout);
2124 		wma_hold_req_timer(req_msg);
2125 		qdf_spin_lock_bh(&wma->wma_hold_req_q_lock);
2126 	}
2127 	qdf_spin_unlock_bh(&wma->wma_hold_req_q_lock);
2128 }
2129 
2130 /**
2131  * wma_cleanup_vdev_resp_and_hold_req() - cleaunup the vdev resp and hold req
2132  * queue
2133  * @msg :scheduler msg
2134  *
2135  * Return: QDF_STATUS
2136  */
2137 static QDF_STATUS
wma_cleanup_vdev_resp_and_hold_req(struct scheduler_msg * msg)2138 wma_cleanup_vdev_resp_and_hold_req(struct scheduler_msg *msg)
2139 {
2140 	tp_wma_handle wma;
2141 
2142 	if (!msg || !msg->bodyptr) {
2143 		wma_err("msg or body pointer is NULL");
2144 		return QDF_STATUS_E_INVAL;
2145 	}
2146 
2147 	wma = msg->bodyptr;
2148 	target_if_flush_psoc_vdev_timers(wma->psoc);
2149 	wma_cleanup_hold_req(wma);
2150 
2151 	return QDF_STATUS_SUCCESS;
2152 }
2153 
2154 /**
2155  * wma_cleanup_vdev_resp_and_hold_req_flush_cb() - flush cb for the msg to clean
2156  * up vdev resp and hold req
2157  * @msg :scheduler msg
2158  *
2159  * As passed msg->bodyptr is wma in this case this is dummy flush cb so that
2160  * driver doesn't try to free msg->bodyptr when this msg is flushed.
2161  *
2162  * Return: QDF_STATUS
2163  */
2164 static inline QDF_STATUS
wma_cleanup_vdev_resp_and_hold_req_flush_cb(struct scheduler_msg * msg)2165 wma_cleanup_vdev_resp_and_hold_req_flush_cb(struct scheduler_msg *msg)
2166 {
2167 	return QDF_STATUS_SUCCESS;
2168 }
2169 
2170 /**
2171  * wma_shutdown_notifier_cb - Shutdown notifier call back
2172  * @priv : WMA handle
2173  *
2174  * During recovery, WMA may wait for resume to complete if the crash happens
2175  * while in suspend. This may cause delays in completing the recovery. This call
2176  * back would be called during recovery and the event is completed so that if
2177  * the resume is waiting on FW to respond then it can get out of the wait so
2178  * that recovery thread can start bringing down all the modules.
2179  *
2180  * Return: None
2181  */
wma_shutdown_notifier_cb(void * priv)2182 static void wma_shutdown_notifier_cb(void *priv)
2183 {
2184 	tp_wma_handle wma_handle = priv;
2185 	struct scheduler_msg msg = { 0 };
2186 	QDF_STATUS status;
2187 
2188 	ucfg_pmo_psoc_wakeup_host_event_received(wma_handle->psoc);
2189 	wmi_stop(wma_handle->wmi_handle);
2190 
2191 	msg.bodyptr = wma_handle;
2192 	msg.callback = wma_cleanup_vdev_resp_and_hold_req;
2193 	msg.flush_callback = wma_cleanup_vdev_resp_and_hold_req_flush_cb;
2194 	status = scheduler_post_message(QDF_MODULE_ID_WMA,
2195 					QDF_MODULE_ID_WMA,
2196 					QDF_MODULE_ID_TARGET_IF, &msg);
2197 }
2198 
2199 struct wma_version_info g_wmi_version_info;
2200 
2201 #ifdef WLAN_FEATURE_MEMDUMP_ENABLE
2202 /**
2203  * wma_state_info_dump() - prints state information of wma layer
2204  * @buf_ptr: buffer pointer
2205  * @size: size of buffer to be filled
2206  *
2207  * This function is used to dump state information of wma layer
2208  *
2209  * Return: None
2210  */
wma_state_info_dump(char ** buf_ptr,uint16_t * size)2211 static void wma_state_info_dump(char **buf_ptr, uint16_t *size)
2212 {
2213 	uint8_t vdev_id;
2214 	uint16_t len = 0;
2215 	t_wma_handle *wma;
2216 	char *buf = *buf_ptr;
2217 	struct wma_txrx_node *iface;
2218 	struct wake_lock_stats stats;
2219 	struct wlan_objmgr_vdev *vdev;
2220 	uint32_t rate_flag;
2221 	QDF_STATUS status;
2222 
2223 	wma = cds_get_context(QDF_MODULE_ID_WMA);
2224 	if (!wma)
2225 		return;
2226 
2227 	wma_debug("size of buffer: %d", *size);
2228 
2229 	for (vdev_id = 0; vdev_id < wma->max_bssid; vdev_id++) {
2230 		iface = &wma->interfaces[vdev_id];
2231 		vdev = iface->vdev;
2232 		if (!vdev)
2233 			continue;
2234 
2235 		status = wma_get_vdev_rate_flag(iface->vdev, &rate_flag);
2236 		if (QDF_IS_STATUS_ERROR(status))
2237 			continue;
2238 
2239 		vdev = wlan_objmgr_get_vdev_by_id_from_psoc(wma->psoc,
2240 						vdev_id, WLAN_LEGACY_WMA_ID);
2241 		if (!vdev)
2242 			continue;
2243 		ucfg_mc_cp_stats_get_vdev_wake_lock_stats(vdev, &stats);
2244 		len += qdf_scnprintf(buf + len, *size - len,
2245 			"\n"
2246 			"vdev_id %d\n"
2247 			"WoW Stats\n"
2248 			"\tpno_match %u\n"
2249 			"\tpno_complete %u\n"
2250 			"\tgscan %u\n"
2251 			"\tlow_rssi %u\n"
2252 			"\trssi_breach %u\n"
2253 			"\tucast %u\n"
2254 			"\tbcast %u\n"
2255 			"\ticmpv4 %u\n"
2256 			"\ticmpv6 %u\n"
2257 			"\tipv4_mcast %u\n"
2258 			"\tipv6_mcast %u\n"
2259 			"\tipv6_mcast_ra %u\n"
2260 			"\tipv6_mcast_ns %u\n"
2261 			"\tipv6_mcast_na %u\n"
2262 			"\toem_response %u\n"
2263 			"\tuc_drop %u\n"
2264 			"\tfatal_event %u\n"
2265 			"dtimPeriod %d\n"
2266 			"chan_width %d\n"
2267 			"vdev_active %d\n"
2268 			"vdev_up %d\n"
2269 			"aid %d\n"
2270 			"rate_flags %d\n"
2271 			"nss %d\n"
2272 			"nwType %d\n"
2273 			"tx_streams %d",
2274 			vdev_id,
2275 			stats.pno_match_wake_up_count,
2276 			stats.pno_complete_wake_up_count,
2277 			stats.gscan_wake_up_count,
2278 			stats.low_rssi_wake_up_count,
2279 			stats.rssi_breach_wake_up_count,
2280 			stats.ucast_wake_up_count,
2281 			stats.bcast_wake_up_count,
2282 			stats.icmpv4_count,
2283 			stats.icmpv6_count,
2284 			stats.ipv4_mcast_wake_up_count,
2285 			stats.ipv6_mcast_wake_up_count,
2286 			stats.ipv6_mcast_ra_stats,
2287 			stats.ipv6_mcast_ns_stats,
2288 			stats.ipv6_mcast_na_stats,
2289 			stats.oem_response_wake_up_count,
2290 			stats.uc_drop_wake_up_count,
2291 			stats.fatal_event_wake_up_count,
2292 			iface->dtimPeriod,
2293 			iface->chan_width,
2294 			iface->vdev_active,
2295 			wma_is_vdev_up(vdev_id),
2296 			iface->aid,
2297 			rate_flag,
2298 			iface->nss,
2299 			iface->nwType,
2300 			iface->tx_streams);
2301 		wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_WMA_ID);
2302 	}
2303 
2304 	*size -= len;
2305 	*buf_ptr += len;
2306 }
2307 
2308 /**
2309  * wma_register_debug_callback() - registration function for wma layer
2310  * to print wma state information
2311  */
wma_register_debug_callback(void)2312 static void wma_register_debug_callback(void)
2313 {
2314 	qdf_register_debug_callback(QDF_MODULE_ID_WMA, &wma_state_info_dump);
2315 }
2316 #else /* WLAN_FEATURE_MEMDUMP_ENABLE */
wma_register_debug_callback(void)2317 static void wma_register_debug_callback(void)
2318 {
2319 }
2320 #endif /* WLAN_FEATURE_MEMDUMP_ENABLE */
2321 /**
2322  * wma_register_tx_ops_handler() - register tx_ops of southbound
2323  * @tx_ops:  tx_ops pointer in southbound
2324  *
2325  * Return: 0 on success, errno on failure
2326  */
2327 static QDF_STATUS
wma_register_tx_ops_handler(struct wlan_lmac_if_tx_ops * tx_ops)2328 wma_register_tx_ops_handler(struct wlan_lmac_if_tx_ops *tx_ops)
2329 {
2330 	/*
2331 	 * Assign tx_ops, it's up to UMAC modules to declare and define these
2332 	 * functions which are used to send wmi command to target.
2333 	 */
2334 
2335 	if (!tx_ops) {
2336 		wma_err("pointer to lmac if tx ops is NULL");
2337 		return QDF_STATUS_E_INVAL;
2338 	}
2339 
2340 	/* mgmt_txrx component's tx ops */
2341 	tx_ops->mgmt_txrx_tx_ops.mgmt_tx_send = wma_mgmt_unified_cmd_send;
2342 
2343 	/* mgmt txrx component nbuf op for nbuf dma unmap */
2344 	tx_ops->mgmt_txrx_tx_ops.tx_drain_nbuf_op = wma_mgmt_nbuf_unmap_cb;
2345 
2346 	return QDF_STATUS_SUCCESS;
2347 }
2348 
2349 /**
2350  * wma_target_if_open() - Attach UMAC modules' interface with wmi layer
2351  * @wma_handle: wma handle
2352  *
2353  * Separate module defines below functions:
2354  * 1. tgt_wmi_<module>_<action> api sends wmi command, assigned to south bound
2355  *    tx_ops function pointers;
2356  * 2. module's south dispatcher handles information from lower layer, assigned
2357  *    to south bound rx_ops function pointers;
2358  * 3. wmi event handler deals with wmi event, extracts umac needed information,
2359  *    and call rx_ops(module's dispatcher). It executes in tasklet context and
2360  *    is up to dispatcher to decide the context to reside in tasklet or in
2361  *    thread context.
2362  *
2363  * Return: None
2364  */
wma_target_if_open(tp_wma_handle wma_handle)2365 static void wma_target_if_open(tp_wma_handle wma_handle)
2366 {
2367 	struct wlan_objmgr_psoc *psoc = wma_handle->psoc;
2368 
2369 	if (!psoc)
2370 		return;
2371 
2372 	wlan_global_lmac_if_set_txops_registration_cb(WLAN_DEV_OL,
2373 					target_if_register_tx_ops);
2374 	wlan_lmac_if_set_umac_txops_registration_cb(
2375 		wma_register_tx_ops_handler);
2376 	wlan_global_lmac_if_open(psoc);
2377 
2378 }
2379 
2380 /**
2381  * wma_legacy_service_ready_event_handler() - legacy (ext)service ready handler
2382  * @event_id: event_id
2383  * @handle: wma handle
2384  * @event_data: event data
2385  * @length: event length
2386  *
2387  * Return: 0 for success, negative error code for failure
2388  */
wma_legacy_service_ready_event_handler(uint32_t event_id,void * handle,uint8_t * event_data,uint32_t length)2389 static int wma_legacy_service_ready_event_handler(uint32_t event_id,
2390 						  void *handle,
2391 						  uint8_t *event_data,
2392 						  uint32_t length)
2393 {
2394 	switch (event_id) {
2395 	case wmi_service_ready_event_id:
2396 		return wma_rx_service_ready_event(handle, event_data, length);
2397 	case wmi_service_ready_ext_event_id:
2398 		return wma_rx_service_ready_ext_event(handle, event_data,
2399 						      length);
2400 	case wmi_ready_event_id:
2401 		return wma_rx_ready_event(handle, event_data, length);
2402 	case wmi_service_ready_ext2_event_id:
2403 		return wma_rx_service_ready_ext2_event(handle, event_data,
2404 						      length);
2405 	default:
2406 		wma_err("Legacy callback invoked with invalid event_id:%d",
2407 			 event_id);
2408 		QDF_BUG(0);
2409 	}
2410 
2411 	return 0;
2412 }
2413 
2414 #ifdef WLAN_FEATURE_CAL_FAILURE_TRIGGER
2415 /**
2416  * wma_process_cal_fail_info() - Process cal failure event and
2417  *                               send it to userspace
2418  * @wmi_event:  Cal failure event data
2419  */
wma_process_cal_fail_info(uint8_t * wmi_event)2420 static void wma_process_cal_fail_info(uint8_t *wmi_event)
2421 {
2422 	struct mac_context *mac = cds_get_context(QDF_MODULE_ID_PE);
2423 	uint8_t *buf_ptr;
2424 	wmi_debug_mesg_fw_cal_failure_param *cal_failure_event;
2425 
2426 	if (!mac) {
2427 		wma_err("Invalid mac context");
2428 		return;
2429 	}
2430 
2431 	if (!mac->cal_failure_event_cb) {
2432 		wma_err("Callback not registered for cal failure event");
2433 		return;
2434 	}
2435 
2436 	buf_ptr = wmi_event;
2437 	buf_ptr = buf_ptr + sizeof(wmi_debug_mesg_flush_complete_fixed_param) +
2438 		  WMI_TLV_HDR_SIZE +
2439 		  sizeof(wmi_debug_mesg_fw_data_stall_param) + WMI_TLV_HDR_SIZE;
2440 
2441 	cal_failure_event = (wmi_debug_mesg_fw_cal_failure_param *)buf_ptr;
2442 
2443 	if (((cal_failure_event->tlv_header & 0xFFFF0000) >> 16 ==
2444 			WMITLV_TAG_STRUC_wmi_debug_mesg_fw_cal_failure_param)) {
2445 		/**
2446 		 * Log calibration failure information received from FW
2447 		 */
2448 		wma_debug("Calibration failure event:");
2449 		wma_debug("calType: %x calFailureReasonCode: %x",
2450 			  cal_failure_event->cal_type,
2451 			  cal_failure_event->cal_failure_reason_code);
2452 		mac->cal_failure_event_cb(
2453 				cal_failure_event->cal_type,
2454 				cal_failure_event->cal_failure_reason_code);
2455 	} else {
2456 		wma_err("Invalid TLV header in cal failure event");
2457 	}
2458 }
2459 #else
wma_process_cal_fail_info(uint8_t * wmi_event)2460 static inline void wma_process_cal_fail_info(uint8_t *wmi_event)
2461 {
2462 }
2463 #endif
2464 
2465 /**
2466  * wma_flush_complete_evt_handler() - FW log flush complete event handler
2467  * @handle: WMI handle
2468  * @event:  Event received from FW
2469  * @len:    Length of the event
2470  *
2471  */
wma_flush_complete_evt_handler(void * handle,u_int8_t * event,u_int32_t len)2472 static int wma_flush_complete_evt_handler(void *handle,
2473 		u_int8_t *event,
2474 		u_int32_t len)
2475 {
2476 	QDF_STATUS status;
2477 	tp_wma_handle wma = (tp_wma_handle) handle;
2478 
2479 	WMI_DEBUG_MESG_FLUSH_COMPLETE_EVENTID_param_tlvs *param_buf;
2480 	wmi_debug_mesg_flush_complete_fixed_param *wmi_event;
2481 	wmi_debug_mesg_fw_data_stall_param *data_stall_event;
2482 	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
2483 	uint8_t *buf_ptr;
2484 	uint32_t reason_code;
2485 
2486 	param_buf = (WMI_DEBUG_MESG_FLUSH_COMPLETE_EVENTID_param_tlvs *) event;
2487 	if (!param_buf) {
2488 		wma_err("Invalid log flush complete event buffer");
2489 		return QDF_STATUS_E_FAILURE;
2490 	}
2491 
2492 	wmi_event = param_buf->fixed_param;
2493 	reason_code = wmi_event->reserved0;
2494 	wma_debug("Received reason code %d from FW", reason_code);
2495 
2496 	if (reason_code == WMI_DIAG_TRIGGER_DATA_STALL) {
2497 		buf_ptr = (uint8_t *)wmi_event;
2498 		buf_ptr = buf_ptr +
2499 			  sizeof(wmi_debug_mesg_flush_complete_fixed_param) +
2500 			  WMI_TLV_HDR_SIZE;
2501 		data_stall_event =
2502 				(wmi_debug_mesg_fw_data_stall_param *)buf_ptr;
2503 	}
2504 
2505 	if (reason_code == WMI_DIAG_TRIGGER_DATA_STALL &&
2506 	    ((data_stall_event->tlv_header & 0xFFFF0000) >> 16 ==
2507 	      WMITLV_TAG_STRUC_wmi_debug_mesg_fw_data_stall_param)) {
2508 		/**
2509 		 * Log data stall info received from FW:
2510 		 *
2511 		 * Possible data stall recovery types:
2512 		 * WLAN_DBG_DATA_STALL_RECOVERY_CONNECT_DISCONNECT
2513 		 * WLAN_DBG_DATA_STALL_RECOVERY_CONNECT_MAC_PHY_RESET
2514 		 * WLAN_DBG_DATA_STALL_RECOVERY_CONNECT_PDR
2515 		 *
2516 		 * Possible data stall event types:
2517 		 * WLAN_DBG_DATA_STALL_VDEV_PAUSE
2518 		 * WLAN_DBG_DATA_STALL_HWSCHED_CMD_FILTER
2519 		 * WLAN_DBG_DATA_STALL_HWSCHED_CMD_FLUSH
2520 		 * WLAN_DBG_DATA_STALL_RX_REFILL_FAILED
2521 		 * WLAN_DBG_DATA_STALL_RX_FCS_LEN_ERROR
2522 		 *
2523 		 * reason_code1:
2524 		 * The information stored in reason_code1 varies based on the
2525 		 * data stall type values:
2526 		 *
2527 		 * data_stall_type      | reason_code1
2528 		 * -----------------------------------------------------
2529 		 * HWSCHED_CMD_FLUSH    | flush req reason (0-40)
2530 		 * RX_REFILL_FAILED     | ring_id (0-7)
2531 		 * RX_FCS_LEN_ERROR     | exact error type
2532 		 *
2533 		 * reasone_code2:
2534 		 * on which tid/hwq stall happened
2535 		 *
2536 		 */
2537 		QDF_TRACE(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_DEBUG,
2538 			  "Data Stall event:");
2539 		QDF_TRACE(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_DEBUG,
2540 			  "data_stall_type: %x vdev_id_bitmap: %x reason_code1: %x reason_code2: %x recovery_type: %x ",
2541 			  data_stall_event->data_stall_type,
2542 			  data_stall_event->vdev_id_bitmap,
2543 			  data_stall_event->reason_code1,
2544 			  data_stall_event->reason_code2,
2545 			  data_stall_event->recovery_type);
2546 
2547 		cdp_post_data_stall_event(soc,
2548 					DATA_STALL_LOG_INDICATOR_FIRMWARE,
2549 					data_stall_event->data_stall_type,
2550 					OL_TXRX_PDEV_ID,
2551 					data_stall_event->vdev_id_bitmap,
2552 					data_stall_event->recovery_type);
2553 	}
2554 
2555 	if (reason_code == WMI_DIAG_TRIGGER_CAL_FAILURE) {
2556 		wma_process_cal_fail_info((uint8_t *)wmi_event);
2557 		return QDF_STATUS_SUCCESS;
2558 	}
2559 
2560 	/*
2561 	 * reason_code = 0; Flush event in response to flush command
2562 	 * reason_code = other value; Asynchronous flush event for fatal events
2563 	 */
2564 	if (!reason_code && (cds_is_log_report_in_progress() == false)) {
2565 		wma_debug("Received WMI flush event without sending CMD");
2566 		return -EINVAL;
2567 	} else if (!reason_code && cds_is_log_report_in_progress() == true) {
2568 		/* Flush event in response to flush command */
2569 		wma_debug("Received WMI flush event in response to flush CMD");
2570 		status = qdf_mc_timer_stop(&wma->log_completion_timer);
2571 		if (status != QDF_STATUS_SUCCESS)
2572 			wma_err("Failed to stop the log completion timeout");
2573 		cds_logging_set_fw_flush_complete();
2574 		return QDF_STATUS_SUCCESS;
2575 	} else if (reason_code && cds_is_log_report_in_progress() == false) {
2576 		/* Asynchronous flush event for fatal events */
2577 		status = cds_set_log_completion(WLAN_LOG_TYPE_FATAL,
2578 				WLAN_LOG_INDICATOR_FIRMWARE,
2579 				reason_code, false);
2580 		if (QDF_STATUS_SUCCESS != status) {
2581 			wma_err("Failed to set log trigger params");
2582 			return QDF_STATUS_E_FAILURE;
2583 		}
2584 		cds_logging_set_fw_flush_complete();
2585 		return status;
2586 	} else {
2587 		/* Asynchronous flush event for fatal event,
2588 		 * but, report in progress already
2589 		 */
2590 		wma_debug("Bug report already in progress - dropping! type:%d, indicator=%d reason_code=%d",
2591 				WLAN_LOG_TYPE_FATAL,
2592 				WLAN_LOG_INDICATOR_FIRMWARE, reason_code);
2593 		return QDF_STATUS_E_FAILURE;
2594 	}
2595 	/* Asynchronous flush event for fatal event,
2596 	 * but, report in progress already
2597 	 */
2598 	wma_warn("Bug report already in progress - dropping! type:%d, indicator=%d reason_code=%d",
2599 		WLAN_LOG_TYPE_FATAL,
2600 		WLAN_LOG_INDICATOR_FIRMWARE, reason_code);
2601 	return QDF_STATUS_E_FAILURE;
2602 }
2603 
2604 #ifdef WLAN_CONV_SPECTRAL_ENABLE
2605 /**
2606  * wma_extract_single_phyerr_spectral() - extract single phy error from event
2607  * @handle: wma handle
2608  * @evt_buf: pointer to event buffer
2609  * @datalen: data length of event buffer
2610  * @buf_offset: Pointer to hold value of current event buffer offset
2611  * post extraction
2612  * @phyerr: Pointer to hold phyerr
2613  *
2614  * Return: QDF_STATUS
2615  */
wma_extract_single_phyerr_spectral(void * handle,void * evt_buf,uint16_t datalen,uint16_t * buf_offset,wmi_host_phyerr_t * phyerr)2616 static QDF_STATUS wma_extract_single_phyerr_spectral(void *handle,
2617 		void *evt_buf,
2618 		uint16_t datalen, uint16_t *buf_offset,
2619 		wmi_host_phyerr_t *phyerr)
2620 {
2621 	wmi_single_phyerr_rx_event *ev;
2622 	int n = *buf_offset;
2623 
2624 	ev = (wmi_single_phyerr_rx_event *)((uint8_t *)evt_buf + n);
2625 
2626 	if (n < datalen) {
2627 		/* ensure there's at least space for the header */
2628 		if ((datalen - n) < sizeof(ev->hdr)) {
2629 			wma_err("not enough space? (datalen=%d, n=%d, hdr=%zu bytes",
2630 				datalen, n, sizeof(ev->hdr));
2631 			return QDF_STATUS_E_FAILURE;
2632 		}
2633 
2634 		phyerr->bufp = ev->bufp;
2635 		phyerr->buf_len = ev->hdr.buf_len;
2636 
2637 		/*
2638 		 * Sanity check the buffer length of the event against
2639 		 * what we currently have.
2640 		 *
2641 		 * Since buf_len is 32 bits, we check if it overflows
2642 		 * a large 32 bit value.  It's not 0x7fffffff because
2643 		 * we increase n by (buf_len + sizeof(hdr)), which would
2644 		 * in itself cause n to overflow.
2645 		 *
2646 		 * If "int" is 64 bits then this becomes a moot point.
2647 		 */
2648 		if (ev->hdr.buf_len > 0x7f000000) {
2649 			wma_err("buf_len is garbage? (0x%x)", ev->hdr.buf_len);
2650 			return QDF_STATUS_E_FAILURE;
2651 		}
2652 		if (n + ev->hdr.buf_len > datalen) {
2653 			wma_err("buf_len exceeds available space n=%d, buf_len=%d, datalen=%d",
2654 				n, ev->hdr.buf_len, datalen);
2655 			return QDF_STATUS_E_FAILURE;
2656 		}
2657 
2658 		phyerr->phy_err_code = WMI_UNIFIED_PHYERRCODE_GET(&ev->hdr);
2659 		phyerr->tsf_timestamp = ev->hdr.tsf_timestamp;
2660 
2661 #ifdef DEBUG_SPECTRAL_SCAN
2662 		wma_debug("len=%d, tsf=0x%08x, rssi = 0x%x/0x%x/0x%x/0x%x, comb rssi = 0x%x, phycode=%d",
2663 				ev->hdr.buf_len,
2664 				ev->hdr.tsf_timestamp,
2665 				ev->hdr.rssi_chain0,
2666 				ev->hdr.rssi_chain1,
2667 				ev->hdr.rssi_chain2,
2668 				ev->hdr.rssi_chain3,
2669 				WMI_UNIFIED_RSSI_COMB_GET(&ev->hdr),
2670 					  phyerr->phy_err_code);
2671 
2672 		/*
2673 		 * For now, unroll this loop - the chain 'value' field isn't
2674 		 * a variable but glued together into a macro field definition.
2675 		 * Grr. :-)
2676 		 */
2677 		wma_debug("chain 0: raw=0x%08x; pri20=%d sec20=%d sec40=%d sec80=%d",
2678 				ev->hdr.rssi_chain0,
2679 				WMI_UNIFIED_RSSI_CHAN_GET(&ev->hdr, 0, PRI20),
2680 				WMI_UNIFIED_RSSI_CHAN_GET(&ev->hdr, 0, SEC20),
2681 				WMI_UNIFIED_RSSI_CHAN_GET(&ev->hdr, 0, SEC40),
2682 				WMI_UNIFIED_RSSI_CHAN_GET(&ev->hdr, 0, SEC80));
2683 
2684 		wma_debug("chain 1: raw=0x%08x: pri20=%d sec20=%d sec40=%d sec80=%d",
2685 				ev->hdr.rssi_chain1,
2686 				WMI_UNIFIED_RSSI_CHAN_GET(&ev->hdr, 1, PRI20),
2687 				WMI_UNIFIED_RSSI_CHAN_GET(&ev->hdr, 1, SEC20),
2688 				WMI_UNIFIED_RSSI_CHAN_GET(&ev->hdr, 1, SEC40),
2689 				WMI_UNIFIED_RSSI_CHAN_GET(&ev->hdr, 1, SEC80));
2690 
2691 		wma_debug("chain 2: raw=0x%08x: pri20=%d sec20=%d sec40=%d sec80=%d",
2692 				ev->hdr.rssi_chain2,
2693 				WMI_UNIFIED_RSSI_CHAN_GET(&ev->hdr, 2, PRI20),
2694 				WMI_UNIFIED_RSSI_CHAN_GET(&ev->hdr, 2, SEC20),
2695 				WMI_UNIFIED_RSSI_CHAN_GET(&ev->hdr, 2, SEC40),
2696 				WMI_UNIFIED_RSSI_CHAN_GET(&ev->hdr, 2, SEC80));
2697 
2698 		wma_debug("chain 3: raw=0x%08x: pri20=%d sec20=%d sec40=%d sec80=%d",
2699 				ev->hdr.rssi_chain3,
2700 				WMI_UNIFIED_RSSI_CHAN_GET(&ev->hdr, 3, PRI20),
2701 				WMI_UNIFIED_RSSI_CHAN_GET(&ev->hdr, 3, SEC20),
2702 				WMI_UNIFIED_RSSI_CHAN_GET(&ev->hdr, 3, SEC40),
2703 				WMI_UNIFIED_RSSI_CHAN_GET(&ev->hdr, 3, SEC80));
2704 
2705 
2706 		wma_debug("freq_info_1=0x%08x, freq_info_2=0x%08x",
2707 			   ev->hdr.freq_info_1, ev->hdr.freq_info_2);
2708 
2709 		/*
2710 		 * The NF chain values are signed and are negative - hence
2711 		 * the cast evilness.
2712 		 */
2713 		wma_debug("nfval[1]=0x%08x, nfval[2]=0x%08x, nf=%d/%d/%d/%d, freq1=%d, freq2=%d, cw=%d",
2714 				ev->hdr.nf_list_1,
2715 				ev->hdr.nf_list_2,
2716 				(int) WMI_UNIFIED_NF_CHAIN_GET(&ev->hdr, 0),
2717 				(int) WMI_UNIFIED_NF_CHAIN_GET(&ev->hdr, 1),
2718 				(int) WMI_UNIFIED_NF_CHAIN_GET(&ev->hdr, 2),
2719 				(int) WMI_UNIFIED_NF_CHAIN_GET(&ev->hdr, 3),
2720 				WMI_UNIFIED_FREQ_INFO_GET(&ev->hdr, 1),
2721 				WMI_UNIFIED_FREQ_INFO_GET(&ev->hdr, 2),
2722 				WMI_UNIFIED_CHWIDTH_GET(&ev->hdr));
2723 #endif
2724 
2725 		/*
2726 		 * If required, pass spectral events to the spectral module
2727 		 */
2728 		if (ev->hdr.buf_len > 0) {
2729 
2730 			/* Initialize the NF values to Zero. */
2731 			phyerr->rf_info.noise_floor[0] =
2732 			    WMI_UNIFIED_NF_CHAIN_GET(&ev->hdr, 0);
2733 			phyerr->rf_info.noise_floor[1] =
2734 			    WMI_UNIFIED_NF_CHAIN_GET(&ev->hdr, 1);
2735 			phyerr->rf_info.noise_floor[2] =
2736 			    WMI_UNIFIED_NF_CHAIN_GET(&ev->hdr, 2);
2737 			phyerr->rf_info.noise_floor[3] =
2738 			    WMI_UNIFIED_NF_CHAIN_GET(&ev->hdr, 3);
2739 
2740 			/* populate the rf info */
2741 			phyerr->rf_info.rssi_comb =
2742 			    WMI_UNIFIED_RSSI_COMB_GET(&ev->hdr);
2743 
2744 			/* Need to unroll loop due to macro
2745 			 * constraints chain 0
2746 			 */
2747 			phyerr->rf_info.pc_rssi_info[0].rssi_pri20 =
2748 			WMI_UNIFIED_RSSI_CHAN_GET(&ev->hdr, 0, PRI20);
2749 			phyerr->rf_info.pc_rssi_info[0].rssi_sec20 =
2750 			WMI_UNIFIED_RSSI_CHAN_GET(&ev->hdr, 0, SEC20);
2751 			phyerr->rf_info.pc_rssi_info[0].rssi_sec40 =
2752 			WMI_UNIFIED_RSSI_CHAN_GET(&ev->hdr, 0, SEC40);
2753 			phyerr->rf_info.pc_rssi_info[0].rssi_sec80 =
2754 			WMI_UNIFIED_RSSI_CHAN_GET(&ev->hdr, 0, SEC80);
2755 
2756 			/* chain 1 */
2757 			phyerr->rf_info.pc_rssi_info[1].rssi_pri20 =
2758 			WMI_UNIFIED_RSSI_CHAN_GET(&ev->hdr, 1, PRI20);
2759 			phyerr->rf_info.pc_rssi_info[1].rssi_sec20 =
2760 			WMI_UNIFIED_RSSI_CHAN_GET(&ev->hdr, 1, SEC20);
2761 			phyerr->rf_info.pc_rssi_info[1].rssi_sec40 =
2762 			WMI_UNIFIED_RSSI_CHAN_GET(&ev->hdr, 1, SEC40);
2763 			phyerr->rf_info.pc_rssi_info[1].rssi_sec80 =
2764 			WMI_UNIFIED_RSSI_CHAN_GET(&ev->hdr, 1, SEC80);
2765 
2766 			/* chain 2 */
2767 			phyerr->rf_info.pc_rssi_info[2].rssi_pri20 =
2768 			WMI_UNIFIED_RSSI_CHAN_GET(&ev->hdr, 2, PRI20);
2769 			phyerr->rf_info.pc_rssi_info[2].rssi_sec20 =
2770 			WMI_UNIFIED_RSSI_CHAN_GET(&ev->hdr, 2, SEC20);
2771 			phyerr->rf_info.pc_rssi_info[2].rssi_sec40 =
2772 			WMI_UNIFIED_RSSI_CHAN_GET(&ev->hdr, 2, SEC40);
2773 			phyerr->rf_info.pc_rssi_info[2].rssi_sec80 =
2774 			WMI_UNIFIED_RSSI_CHAN_GET(&ev->hdr, 2, SEC80);
2775 
2776 			/* chain 3 */
2777 			phyerr->rf_info.pc_rssi_info[3].rssi_pri20 =
2778 			WMI_UNIFIED_RSSI_CHAN_GET(&ev->hdr, 3, PRI20);
2779 			phyerr->rf_info.pc_rssi_info[3].rssi_sec20 =
2780 			WMI_UNIFIED_RSSI_CHAN_GET(&ev->hdr, 3, SEC20);
2781 			phyerr->rf_info.pc_rssi_info[3].rssi_sec40 =
2782 			WMI_UNIFIED_RSSI_CHAN_GET(&ev->hdr, 3, SEC40);
2783 			phyerr->rf_info.pc_rssi_info[3].rssi_sec80 =
2784 			WMI_UNIFIED_RSSI_CHAN_GET(&ev->hdr, 3, SEC80);
2785 
2786 			phyerr->chan_info.center_freq1 =
2787 			    WMI_UNIFIED_FREQ_INFO_GET(&ev->hdr, 1);
2788 			phyerr->chan_info.center_freq2 =
2789 			    WMI_UNIFIED_FREQ_INFO_GET(&ev->hdr, 2);
2790 
2791 		}
2792 
2793 		/*
2794 		 * Advance the buffer pointer to the next PHY error.
2795 		 * buflen is the length of this payload, so we need to
2796 		 * advance past the current header _AND_ the payload.
2797 		 */
2798 		 n += sizeof(*ev) + ev->hdr.buf_len;
2799 	}
2800 	*buf_offset += n;
2801 
2802 	return QDF_STATUS_SUCCESS;
2803 }
2804 
2805 /**
2806  * spectral_phyerr_event_handler() - spectral phyerr event handler
2807  * @handle: wma handle
2808  * @data: data buffer
2809  * @datalen: buffer length
2810  *
2811  * Return:  QDF_STATUS
2812  */
spectral_phyerr_event_handler(void * handle,uint8_t * data,uint32_t datalen)2813 static QDF_STATUS spectral_phyerr_event_handler(void *handle,
2814 						uint8_t *data,
2815 						uint32_t datalen)
2816 {
2817 	tp_wma_handle wma = (tp_wma_handle) handle;
2818 	QDF_STATUS status = QDF_STATUS_SUCCESS;
2819 	uint16_t buf_offset, event_buf_len = 0;
2820 	wmi_single_phyerr_rx_event *ev;
2821 	wmi_host_phyerr_t phyerr;
2822 	struct target_if_spectral_rfqual_info rfqual_info;
2823 	struct target_if_spectral_chan_info chan_info;
2824 	struct target_if_spectral_acs_stats acs_stats;
2825 
2826 	if (wma_validate_handle(wma))
2827 		return QDF_STATUS_E_FAILURE;
2828 
2829 	memset(&phyerr, 0, sizeof(wmi_host_phyerr_t));
2830 	status = wmi_extract_comb_phyerr(wma->wmi_handle, data, datalen,
2831 					 &buf_offset, &phyerr);
2832 	if (QDF_IS_STATUS_ERROR(status)) {
2833 		wma_err("extract comb phyerr failed");
2834 		return QDF_STATUS_E_FAILURE;
2835 	}
2836 
2837 	ev = (wmi_single_phyerr_rx_event *)phyerr.bufp;
2838 	event_buf_len = phyerr.buf_len;
2839 	/* Loop over the bufp, extracting out phyerrors */
2840 	buf_offset = 0;
2841 	while (buf_offset < event_buf_len) {
2842 		if (wma_extract_single_phyerr_spectral(handle, ev,
2843 			event_buf_len, &buf_offset, &phyerr)) {
2844 			wma_err("extract single phy err failed");
2845 			return QDF_STATUS_E_FAILURE;
2846 		}
2847 
2848 		if (phyerr.buf_len > 0) {
2849 			if (sizeof(phyerr.rf_info) > sizeof(rfqual_info))
2850 				qdf_mem_copy(&rfqual_info, &phyerr.rf_info,
2851 						sizeof(rfqual_info));
2852 			else
2853 				qdf_mem_copy(&rfqual_info, &phyerr.rf_info,
2854 						sizeof(phyerr.rf_info));
2855 
2856 			if (sizeof(phyerr.chan_info) > sizeof(chan_info))
2857 				qdf_mem_copy(&chan_info, &phyerr.chan_info,
2858 						sizeof(chan_info));
2859 			else
2860 				qdf_mem_copy(&chan_info, &phyerr.chan_info,
2861 						sizeof(phyerr.chan_info));
2862 
2863 			target_if_spectral_process_phyerr(wma->pdev, phyerr.bufp,
2864 							phyerr.buf_len,
2865 							&rfqual_info,
2866 							&chan_info,
2867 							phyerr.tsf64,
2868 							&acs_stats);
2869 		}
2870 	}
2871 
2872 	return status;
2873 }
2874 #else
2875 static QDF_STATUS
wma_extract_single_phyerr_spectral(void * handle,void * evt_buf,uint16_t datalen,uint16_t * buf_offset,wmi_host_phyerr_t * phyerr)2876 wma_extract_single_phyerr_spectral(void *handle, void *evt_buf,
2877 				   uint16_t datalen,
2878 				   uint16_t *buf_offset,
2879 				   wmi_host_phyerr_t *phyerr)
2880 {
2881 	return QDF_STATUS_SUCCESS;
2882 }
2883 
spectral_phyerr_event_handler(void * handle,uint8_t * data,uint32_t datalen)2884 static QDF_STATUS spectral_phyerr_event_handler(void *handle,
2885 					uint8_t *data, uint32_t datalen)
2886 {
2887 	return QDF_STATUS_SUCCESS;
2888 }
2889 #endif
2890 
2891 /**
2892  * dfs_phyerr_event_handler() - dfs phyerr event handler
2893  * @handle: wma handle
2894  * @data: data buffer
2895  * @datalen: buffer length
2896  * @fulltsf: 64 bit event TSF
2897  *
2898  * Function to process DFS phy errors.
2899  *
2900  * Return: QDF_STATUS
2901  */
dfs_phyerr_event_handler(tp_wma_handle handle,uint8_t * data,uint32_t datalen,uint64_t fulltsf)2902 static QDF_STATUS dfs_phyerr_event_handler(tp_wma_handle handle,
2903 					   uint8_t *data,
2904 					   uint32_t datalen,
2905 					   uint64_t fulltsf)
2906 {
2907 	QDF_STATUS status = QDF_STATUS_SUCCESS;
2908 	struct wlan_lmac_if_dfs_rx_ops *dfs_rx_ops;
2909 	wmi_host_phyerr_t phyerr;
2910 	int8_t rssi_comb;
2911 	uint16_t buf_offset;
2912 
2913 	if (!handle->psoc) {
2914 		wma_err("psoc is null");
2915 		return QDF_STATUS_E_INVAL;
2916 	}
2917 
2918 	dfs_rx_ops = wlan_lmac_if_get_dfs_rx_ops(handle->psoc);
2919 	if (!dfs_rx_ops) {
2920 		wma_err("dfs_rx_ops is null");
2921 		return QDF_STATUS_E_INVAL;
2922 	}
2923 
2924 	if (!dfs_rx_ops->dfs_process_phyerr) {
2925 		wma_err("dfs_process_phyerr handler is null");
2926 		return QDF_STATUS_E_INVAL;
2927 	}
2928 
2929 	if (!handle->pdev) {
2930 		wma_err("pdev is null");
2931 		return -EINVAL;
2932 	}
2933 
2934 	buf_offset = 0;
2935 	while (buf_offset < datalen) {
2936 		status = wmi_extract_single_phyerr(handle->wmi_handle, data, datalen,
2937 						   &buf_offset, &phyerr);
2938 		if (QDF_IS_STATUS_ERROR(status)) {
2939 			/* wmi_extract_single_phyerr has logs */
2940 			return status;
2941 		}
2942 
2943 		rssi_comb = phyerr.rf_info.rssi_comb & 0xFF;
2944 		if (phyerr.buf_len > 0)
2945 			dfs_rx_ops->dfs_process_phyerr(handle->pdev,
2946 						       &phyerr.bufp[0],
2947 						       phyerr.buf_len,
2948 						       rssi_comb,
2949 						       rssi_comb,
2950 						       phyerr.tsf_timestamp,
2951 						       fulltsf);
2952 	}
2953 
2954 	return QDF_STATUS_SUCCESS;
2955 }
2956 
2957 /**
2958  * wma_unified_phyerr_rx_event_handler() - phyerr event handler
2959  * @handle: wma handle
2960  * @data: data buffer
2961  * @datalen: buffer length
2962  *
2963  * WMI Handler for WMI_PHYERR_EVENTID event from firmware.
2964  * This handler is currently handling DFS and spectral scan
2965  * phy errors.
2966  *
2967  * Return: 0 for success, other value for failure
2968  */
wma_unified_phyerr_rx_event_handler(void * handle,uint8_t * data,uint32_t datalen)2969 static int wma_unified_phyerr_rx_event_handler(void *handle,
2970 					       uint8_t *data,
2971 					       uint32_t datalen)
2972 {
2973 	/* phyerr handling is moved to cmn project
2974 	 * As WIN still uses handler registration in non-cmn code.
2975 	 * need complete testing of non offloaded DFS code before we enable
2976 	 * it in cmn code.
2977 	 **/
2978 	tp_wma_handle wma = (tp_wma_handle) handle;
2979 	QDF_STATUS status = QDF_STATUS_SUCCESS;
2980 	wmi_host_phyerr_t phyerr;
2981 	uint16_t buf_offset = 0;
2982 	wmi_single_phyerr_rx_event *ev;
2983 	uint16_t event_buf_len = 0;
2984 	wmi_host_phyerr_t phyerr2;
2985 	bool spectralscan = false;
2986 
2987 	if (wma_validate_handle(wma))
2988 		return -EINVAL;
2989 
2990 	/* sanity check on data length */
2991 	status = wmi_extract_comb_phyerr(wma->wmi_handle, data, datalen,
2992 					 &buf_offset, &phyerr);
2993 	if (QDF_IS_STATUS_ERROR(status)) {
2994 		wma_err("extract phyerr failed: %d", status);
2995 		return qdf_status_to_os_return(status);
2996 	}
2997 	ev = (wmi_single_phyerr_rx_event *)phyerr.bufp;
2998 	event_buf_len = phyerr.buf_len;
2999 	/* Loop over the bufp, extracting out phyerrors */
3000 	buf_offset = 0;
3001 	while (ev && (buf_offset < event_buf_len)) {
3002 		if (wma_extract_single_phyerr_spectral(handle, ev,
3003 						       event_buf_len,
3004 						       &buf_offset,
3005 						       &phyerr2)) {
3006 			wma_err("extract single phy err failed");
3007 			return qdf_status_to_os_return(QDF_STATUS_E_FAILURE);
3008 		}
3009 		if ((buf_offset != 0) && (phyerr2.phy_err_code == 0x26 ||
3010 					  phyerr2.phy_err_code == 0x24)) {
3011 			spectralscan = true;
3012 		} else {
3013 			break;
3014 		}
3015 	}
3016 	if (spectralscan) {
3017 		status = spectral_phyerr_event_handler(wma, data, datalen);
3018 		return qdf_status_to_os_return(status);
3019 	}
3020 	/* handle different PHY Error conditions */
3021 	if (((phyerr.phy_err_mask0 & (WMI_PHY_ERROR_MASK0_RADAR |
3022 	    WMI_PHY_ERROR_MASK0_FALSE_RADAR_EXT |
3023 	    WMI_PHY_ERROR_MASK0_SPECTRAL_SCAN)) == 0)) {
3024 		wma_debug("Unknown phy error event");
3025 		return -EINVAL;
3026 	}
3027 
3028 	/* Handle Spectral or DFS PHY Error */
3029 	if (phyerr.phy_err_mask0 & (WMI_PHY_ERROR_MASK0_RADAR |
3030 	    WMI_PHY_ERROR_MASK0_FALSE_RADAR_EXT)) {
3031 		if (wma->is_dfs_offloaded) {
3032 			wma_debug("Unexpected phy error, dfs offloaded");
3033 			return -EINVAL;
3034 		}
3035 		status = dfs_phyerr_event_handler(wma,
3036 						  phyerr.bufp,
3037 						  phyerr.buf_len,
3038 						  phyerr.tsf64);
3039 	} else if (phyerr.phy_err_mask0 & (WMI_PHY_ERROR_MASK0_SPECTRAL_SCAN |
3040 		   WMI_PHY_ERROR_MASK0_FALSE_RADAR_EXT)) {
3041 		status = spectral_phyerr_event_handler(wma, data, datalen);
3042 	}
3043 
3044 	return qdf_status_to_os_return(status);
3045 }
3046 
wma_vdev_init(struct wma_txrx_node * vdev)3047 void wma_vdev_init(struct wma_txrx_node *vdev)
3048 {
3049 	vdev->is_waiting_for_key = false;
3050 }
3051 
wma_vdev_deinit(struct wma_txrx_node * vdev)3052 void wma_vdev_deinit(struct wma_txrx_node *vdev)
3053 {
3054 	struct beacon_info *bcn;
3055 	tp_wma_handle wma_handle;
3056 
3057 	wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
3058 	if (!wma_handle)
3059 		return;
3060 
3061 	bcn = vdev->beacon;
3062 	if (bcn) {
3063 		if (bcn->dma_mapped)
3064 			qdf_nbuf_unmap_single(wma_handle->qdf_dev,
3065 				bcn->buf, QDF_DMA_TO_DEVICE);
3066 		qdf_nbuf_free(bcn->buf);
3067 		qdf_mem_free(bcn);
3068 		vdev->beacon = NULL;
3069 	}
3070 
3071 	if (vdev->vdev_active == true)
3072 		vdev->vdev_active = false;
3073 
3074 	if (vdev->addBssStaContext) {
3075 		qdf_mem_free(vdev->addBssStaContext);
3076 		vdev->addBssStaContext = NULL;
3077 	}
3078 
3079 	if (vdev->psnr_req) {
3080 		qdf_mem_free(vdev->psnr_req);
3081 		vdev->psnr_req = NULL;
3082 	}
3083 
3084 	if (vdev->rcpi_req) {
3085 		qdf_mem_free(vdev->rcpi_req);
3086 		vdev->rcpi_req = NULL;
3087 	}
3088 
3089 	if (vdev->roam_scan_stats_req) {
3090 		struct sir_roam_scan_stats *req;
3091 
3092 		req = vdev->roam_scan_stats_req;
3093 		vdev->roam_scan_stats_req = NULL;
3094 		qdf_mem_free(req);
3095 	}
3096 
3097 	if (vdev->roam_synch_frame_ind.bcn_probe_rsp) {
3098 		qdf_mem_free(vdev->roam_synch_frame_ind.bcn_probe_rsp);
3099 		vdev->roam_synch_frame_ind.bcn_probe_rsp = NULL;
3100 	}
3101 
3102 	if (vdev->roam_synch_frame_ind.reassoc_req) {
3103 		qdf_mem_free(vdev->roam_synch_frame_ind.reassoc_req);
3104 		vdev->roam_synch_frame_ind.reassoc_req = NULL;
3105 	}
3106 
3107 	if (vdev->roam_synch_frame_ind.reassoc_rsp) {
3108 		qdf_mem_free(vdev->roam_synch_frame_ind.reassoc_rsp);
3109 		vdev->roam_synch_frame_ind.reassoc_rsp = NULL;
3110 	}
3111 
3112 	if (vdev->plink_status_req) {
3113 		qdf_mem_free(vdev->plink_status_req);
3114 		vdev->plink_status_req = NULL;
3115 	}
3116 
3117 	vdev->is_waiting_for_key = false;
3118 }
3119 
3120 /**
3121  * wma_wmi_stop() - generic function to block WMI commands
3122  * @return: None
3123  */
wma_wmi_stop(void)3124 void wma_wmi_stop(void)
3125 {
3126 	tp_wma_handle wma_handle;
3127 
3128 	wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
3129 	if (!wma_handle)
3130 		return;
3131 
3132 	if (wmi_validate_handle(wma_handle->wmi_handle))
3133 		return;
3134 
3135 	wmi_stop(wma_handle->wmi_handle);
3136 }
3137 
3138 #ifdef WLAN_WMI_BCN
3139 static QDF_STATUS
wma_register_swba_events(wmi_unified_t wmi_handle)3140 wma_register_swba_events(wmi_unified_t wmi_handle)
3141 {
3142 	QDF_STATUS status;
3143 
3144 	status = wmi_unified_register_event_handler(wmi_handle,
3145 						    wmi_host_swba_event_id,
3146 						    wma_beacon_swba_handler,
3147 						    WMA_RX_SERIALIZER_CTX);
3148 
3149 	return status;
3150 }
3151 #else
wma_register_swba_events(wmi_unified_t wmi_handle)3152 static QDF_STATUS wma_register_swba_events(wmi_unified_t wmi_handle)
3153 {
3154 	return QDF_STATUS_SUCCESS;
3155 }
3156 #endif
3157 
3158 #ifdef FEATURE_WLAN_APF
wma_register_apf_events(tp_wma_handle wma_handle)3159 static void wma_register_apf_events(tp_wma_handle wma_handle)
3160 {
3161 	if (wma_validate_handle(wma_handle))
3162 		return;
3163 
3164 	wmi_unified_register_event_handler(wma_handle->wmi_handle,
3165 					   wmi_apf_capability_info_event_id,
3166 					   wma_get_apf_caps_event_handler,
3167 					   WMA_RX_SERIALIZER_CTX);
3168 	wmi_unified_register_event_handler(wma_handle->wmi_handle,
3169 				wmi_apf_get_vdev_work_memory_resp_event_id,
3170 				wma_apf_read_work_memory_event_handler,
3171 				WMA_RX_SERIALIZER_CTX);
3172 }
3173 #else /* FEATURE_WLAN_APF */
wma_register_apf_events(tp_wma_handle wma_handle)3174 static void wma_register_apf_events(tp_wma_handle wma_handle)
3175 {
3176 }
3177 #endif /* FEATURE_WLAN_APF */
3178 
3179 #ifdef WLAN_FEATURE_MOTION_DETECTION
3180 /**
3181  * wma_register_md_events - Register motion detection event handlers
3182  * @wma_handle: wma handle
3183  * Return: None
3184  */
wma_register_md_events(tp_wma_handle wma_handle)3185 static void wma_register_md_events(tp_wma_handle wma_handle)
3186 {
3187 	if (wma_validate_handle(wma_handle))
3188 		return;
3189 
3190 	wmi_unified_register_event_handler(wma_handle->wmi_handle,
3191 					   wmi_motion_det_host_eventid,
3192 					   wma_motion_det_host_event_handler,
3193 					   WMA_RX_SERIALIZER_CTX);
3194 
3195 	wmi_unified_register_event_handler(
3196 				wma_handle->wmi_handle,
3197 				wmi_motion_det_base_line_host_eventid,
3198 				wma_motion_det_base_line_host_event_handler,
3199 				WMA_RX_SERIALIZER_CTX);
3200 }
3201 #else /* WLAN_FEATURE_MOTION_DETECTION */
3202 /**
3203  * wma_register_md_events - Register motion detection event handlers
3204  * @wma_handle: wma handle
3205  * Return: None
3206  */
wma_register_md_events(tp_wma_handle wma_handle)3207 static void wma_register_md_events(tp_wma_handle wma_handle)
3208 {
3209 }
3210 #endif /* WLAN_FEATURE_MOTION_DETECTION */
3211 
3212 #ifdef FEATURE_WLM_STATS
wma_register_wlm_stats_events(tp_wma_handle wma_handle)3213 static void wma_register_wlm_stats_events(tp_wma_handle wma_handle)
3214 {
3215 	wmi_unified_register_event_handler(wma_handle->wmi_handle,
3216 					   wmi_wlm_stats_event_id,
3217 					   wma_wlm_stats_rsp,
3218 					   WMA_RX_SERIALIZER_CTX);
3219 }
3220 #else /* FEATURE_WLM_STATS */
wma_register_wlm_stats_events(tp_wma_handle wma_handle)3221 static void wma_register_wlm_stats_events(tp_wma_handle wma_handle)
3222 {
3223 }
3224 #endif /* FEATURE_WLM_STATS */
3225 
3226 #ifdef MULTI_CLIENT_LL_SUPPORT
wma_register_wlm_latency_level_event(tp_wma_handle wma_handle)3227 static void wma_register_wlm_latency_level_event(tp_wma_handle wma_handle)
3228 {
3229 	wmi_unified_register_event_handler(wma_handle->wmi_handle,
3230 				   wmi_vdev_latency_event_id,
3231 				   wma_latency_level_event_handler,
3232 				   WMA_RX_WORK_CTX);
3233 }
3234 #else
wma_register_wlm_latency_level_event(tp_wma_handle wma_handle)3235 static void wma_register_wlm_latency_level_event(tp_wma_handle wma_handle)
3236 {
3237 }
3238 #endif
3239 
wma_get_psoc_from_scn_handle(void * scn_handle)3240 struct wlan_objmgr_psoc *wma_get_psoc_from_scn_handle(void *scn_handle)
3241 {
3242 	tp_wma_handle wma_handle;
3243 
3244 	if (!scn_handle) {
3245 		wma_err("invalid scn handle");
3246 		return NULL;
3247 	}
3248 	wma_handle = (tp_wma_handle)scn_handle;
3249 
3250 	return wma_handle->psoc;
3251 }
3252 
wma_get_fw_phy_mode_for_freq_cb(uint32_t freq,uint32_t chan_width,uint32_t * phy_mode)3253 void wma_get_fw_phy_mode_for_freq_cb(uint32_t freq, uint32_t chan_width,
3254 				     uint32_t *phy_mode)
3255 {
3256 	uint32_t dot11_mode;
3257 	enum wlan_phymode host_phy_mode;
3258 	struct mac_context *mac = cds_get_context(QDF_MODULE_ID_PE);
3259 
3260 	if (!mac) {
3261 		wma_err("MAC context is NULL");
3262 		*phy_mode = WLAN_PHYMODE_AUTO;
3263 		return;
3264 	}
3265 
3266 	dot11_mode = mac->mlme_cfg->dot11_mode.dot11_mode;
3267 
3268 	/* Update invalid dot11 modes to valid dot11 modes */
3269 	if (WLAN_REG_IS_24GHZ_CH_FREQ(freq) &&
3270 	    dot11_mode == MLME_DOT11_MODE_11A)
3271 		dot11_mode = MLME_DOT11_MODE_11G;
3272 
3273 	if (WLAN_REG_IS_5GHZ_CH_FREQ(freq) &&
3274 	    (dot11_mode == MLME_DOT11_MODE_11B ||
3275 	     dot11_mode == MLME_DOT11_MODE_11G ||
3276 	     dot11_mode == MLME_DOT11_MODE_11G_ONLY))
3277 		dot11_mode = MLME_DOT11_MODE_11A;
3278 
3279 	host_phy_mode = wma_chan_phy_mode(freq, chan_width, dot11_mode);
3280 	*phy_mode = wmi_host_to_fw_phymode(host_phy_mode);
3281 }
3282 
wma_get_phy_mode_cb(qdf_freq_t freq,uint32_t chan_width,enum wlan_phymode * phy_mode)3283 void wma_get_phy_mode_cb(qdf_freq_t freq, uint32_t chan_width,
3284 			 enum wlan_phymode *phy_mode)
3285 {
3286 	uint32_t dot11_mode;
3287 	struct mac_context *mac = cds_get_context(QDF_MODULE_ID_PE);
3288 
3289 	if (!mac) {
3290 		wma_err("MAC context is NULL");
3291 		*phy_mode = WLAN_PHYMODE_AUTO;
3292 		return;
3293 	}
3294 
3295 	dot11_mode = mac->mlme_cfg->dot11_mode.dot11_mode;
3296 	*phy_mode = wma_chan_phy_mode(freq, chan_width, dot11_mode);
3297 }
3298 
3299 #ifdef WLAN_FEATURE_NAN
3300 static void
wma_register_nan_callbacks(tp_wma_handle wma_handle)3301 wma_register_nan_callbacks(tp_wma_handle wma_handle)
3302 {
3303 	struct nan_callbacks cb_obj = {0};
3304 
3305 	cb_obj.update_ndi_conn = wma_ndi_update_connection_info;
3306 
3307 	ucfg_nan_register_wma_callbacks(wma_handle->psoc, &cb_obj);
3308 }
3309 #else
wma_register_nan_callbacks(tp_wma_handle wma_handle)3310 static void wma_register_nan_callbacks(tp_wma_handle wma_handle)
3311 {
3312 }
3313 #endif
3314 
3315 #ifdef WLAN_FEATURE_PKT_CAPTURE
3316 static void
wma_register_pkt_capture_callbacks(tp_wma_handle wma_handle)3317 wma_register_pkt_capture_callbacks(tp_wma_handle wma_handle)
3318 {
3319 	struct pkt_capture_callbacks cb_obj = {0};
3320 
3321 	cb_obj.get_rmf_status = wma_get_rmf_status;
3322 
3323 	ucfg_pkt_capture_register_wma_callbacks(wma_handle->psoc, &cb_obj);
3324 }
3325 #else
3326 static inline void
wma_register_pkt_capture_callbacks(tp_wma_handle wma_handle)3327 wma_register_pkt_capture_callbacks(tp_wma_handle wma_handle)
3328 {
3329 }
3330 #endif
3331 
3332 #ifdef TRACE_RECORD
wma_trace_dump(void * mac_ctx,tp_qdf_trace_record record,uint16_t rec_index)3333 static void wma_trace_dump(void *mac_ctx, tp_qdf_trace_record record,
3334 			   uint16_t rec_index)
3335 {
3336 	/*
3337 	 * This is dummy handler registered to qdf_trace as wma module wants to
3338 	 * insert trace records in qdf trace global record table but qdf_trace
3339 	 * does not allow to insert the trace records in the global record
3340 	 * table if a module is not registered with the qdf trace.
3341 	 */
3342 }
3343 
wma_trace_init(void)3344 static void wma_trace_init(void)
3345 {
3346 	qdf_trace_register(QDF_MODULE_ID_WMA, &wma_trace_dump);
3347 }
3348 #else
wma_trace_init(void)3349 static inline void wma_trace_init(void)
3350 {
3351 }
3352 #endif
3353 
3354 #ifdef FEATURE_CLUB_LL_STATS_AND_GET_STATION
wma_get_service_cap_club_get_sta_in_ll_stats_req(struct wmi_unified * wmi_handle,struct wma_tgt_services * cfg)3355 static void wma_get_service_cap_club_get_sta_in_ll_stats_req(
3356 					struct wmi_unified *wmi_handle,
3357 					struct wma_tgt_services *cfg)
3358 {
3359 	cfg->is_get_station_clubbed_in_ll_stats_req =
3360 		wmi_service_enabled(wmi_handle,
3361 				    wmi_service_get_station_in_ll_stats_req);
3362 }
3363 #else
wma_get_service_cap_club_get_sta_in_ll_stats_req(struct wmi_unified * wmi_handle,struct wma_tgt_services * cfg)3364 static void wma_get_service_cap_club_get_sta_in_ll_stats_req(
3365 					struct wmi_unified *wmi_handle,
3366 					struct wma_tgt_services *cfg)
3367 {
3368 }
3369 #endif /* FEATURE_CLUB_LL_STATS_AND_GET_STATION */
3370 
3371 #ifdef WLAN_FEATURE_11BE_MLO
3372 static void
wma_update_num_tdls_vdevs_if_11be_mlo(struct wlan_objmgr_psoc * psoc,target_resource_config * wlan_res_cfg)3373 wma_update_num_tdls_vdevs_if_11be_mlo(struct wlan_objmgr_psoc *psoc,
3374 				      target_resource_config *wlan_res_cfg)
3375 {
3376 	if (!wlan_tdls_is_fw_11be_mlo_capable(psoc))
3377 		return;
3378 
3379 	wlan_res_cfg->num_tdls_vdevs = WLAN_UMAC_MLO_MAX_VDEVS;
3380 	wma_debug("update tdls num vdevs %d", wlan_res_cfg->num_tdls_vdevs);
3381 }
3382 
3383 static void
wma_get_service_cap_per_link_mlo_stats(struct wmi_unified * wmi_handle,struct wma_tgt_services * cfg)3384 wma_get_service_cap_per_link_mlo_stats(struct wmi_unified *wmi_handle,
3385 				       struct wma_tgt_services *cfg)
3386 {
3387 	cfg->is_mlo_per_link_stats_supported =
3388 		wmi_service_enabled(wmi_handle,
3389 				    wmi_service_per_link_stats_support);
3390 	wma_debug("mlo_per_link stats is %s supported by FW",
3391 		  cfg->is_mlo_per_link_stats_supported ? "" : "NOT");
3392 }
3393 #else
3394 static void
wma_update_num_tdls_vdevs_if_11be_mlo(struct wlan_objmgr_psoc * psoc,target_resource_config * wlan_res_cfg)3395 wma_update_num_tdls_vdevs_if_11be_mlo(struct wlan_objmgr_psoc *psoc,
3396 				      target_resource_config *wlan_res_cfg)
3397 {
3398 }
3399 
3400 static void
wma_get_service_cap_per_link_mlo_stats(struct wmi_unified * wmi_handle,struct wma_tgt_services * cfg)3401 wma_get_service_cap_per_link_mlo_stats(struct wmi_unified *wmi_handle,
3402 				       struct wma_tgt_services *cfg)
3403 {
3404 }
3405 #endif
3406 
3407 /**
3408  * wma_set_exclude_selftx_from_cca_busy_time() - Set exclude self tx time from
3409  * cca busy time bool
3410  * @exclude_selftx_from_cca_busy: Bool to update in in wma ini config
3411  * @wma_handle: WMA handle
3412  *
3413  * Return: None
3414  */
3415 static void
wma_set_exclude_selftx_from_cca_busy_time(bool exclude_selftx_from_cca_busy,tp_wma_handle wma_handle)3416 wma_set_exclude_selftx_from_cca_busy_time(bool exclude_selftx_from_cca_busy,
3417 					  tp_wma_handle wma_handle)
3418 {
3419 	struct wma_ini_config *cfg = wma_get_ini_handle(wma_handle);
3420 
3421 	if (!cfg) {
3422 		wma_err("NULL WMA ini handle");
3423 		return;
3424 	}
3425 
3426 	cfg->exclude_selftx_from_cca_busy = exclude_selftx_from_cca_busy;
3427 }
3428 
wma_deinit_pagefault_wakeup_history(tp_wma_handle wma)3429 static void wma_deinit_pagefault_wakeup_history(tp_wma_handle wma)
3430 {
3431 	struct wma_pf_sym *pf_sym_entry;
3432 	int8_t idx, max_sym_count = WLAN_WMA_MAX_PF_SYM;
3433 	bool is_ssr = false;
3434 
3435 	if (wlan_pmo_enable_ssr_on_page_fault(wma->psoc)) {
3436 		is_ssr = true;
3437 		max_sym_count = 0x1;
3438 	}
3439 
3440 	for (idx = 0; idx < max_sym_count; idx++) {
3441 		pf_sym_entry = &wma->wma_pf_hist.wma_pf_sym[idx];
3442 		pf_sym_entry->pf_sym.symbol = 0x0;
3443 		pf_sym_entry->pf_sym.count = 0x0;
3444 		qdf_mem_free(pf_sym_entry->pf_ev_ts);
3445 		pf_sym_entry->pf_ev_ts = NULL;
3446 	}
3447 
3448 	if (!is_ssr) {
3449 		qdf_mem_free(wma->wma_pf_hist.pf_notify_buf_ptr);
3450 		wma->wma_pf_hist.pf_notify_buf_ptr = NULL;
3451 		wma->wma_pf_hist.pf_notify_buf_len = 0x0;
3452 	}
3453 	qdf_spinlock_destroy(&wma->wma_pf_hist.lock);
3454 }
3455 
wma_init_pagefault_wakeup_history(tp_wma_handle wma)3456 static QDF_STATUS wma_init_pagefault_wakeup_history(tp_wma_handle wma)
3457 {
3458 	struct wma_pf_sym *pf_sym_entry;
3459 	int8_t idx, idx2, max_sym_count = WLAN_WMA_MAX_PF_SYM;
3460 	uint8_t max_pf_count;
3461 	bool is_ssr = false;
3462 
3463 	if (wlan_pmo_enable_ssr_on_page_fault(wma->psoc)) {
3464 		is_ssr = true;
3465 		max_sym_count = 0x1;
3466 	}
3467 
3468 	max_pf_count = wlan_pmo_get_min_pagefault_wakeups_for_action(wma->psoc);
3469 	for (idx = 0; idx < max_sym_count; idx++) {
3470 		pf_sym_entry = &wma->wma_pf_hist.wma_pf_sym[idx];
3471 		pf_sym_entry->pf_sym.symbol = 0x0;
3472 		pf_sym_entry->pf_sym.count = 0x0;
3473 		pf_sym_entry->pf_ev_ts = qdf_mem_malloc(max_pf_count *
3474 							sizeof(qdf_time_t));
3475 		if (!pf_sym_entry->pf_ev_ts)
3476 			goto mem_err;
3477 	}
3478 
3479 	if (!is_ssr) {
3480 		wma->wma_pf_hist.pf_notify_buf_len = 0x0;
3481 		wma->wma_pf_hist.pf_notify_buf_ptr =
3482 				qdf_mem_malloc(WLAN_WMA_PF_APPS_NOTIFY_BUF_LEN);
3483 		if (!wma->wma_pf_hist.pf_notify_buf_ptr)
3484 			goto mem_err;
3485 	}
3486 
3487 	qdf_spinlock_create(&wma->wma_pf_hist.lock);
3488 
3489 	return QDF_STATUS_SUCCESS;
3490 
3491 mem_err:
3492 	for (idx2 = --idx; idx2 >= 0; idx2--) {
3493 		pf_sym_entry = &wma->wma_pf_hist.wma_pf_sym[idx2];
3494 		qdf_mem_free(pf_sym_entry->pf_ev_ts);
3495 		pf_sym_entry->pf_ev_ts = NULL;
3496 	}
3497 
3498 	return QDF_STATUS_E_NOMEM;
3499 }
3500 
3501 /**
3502  * wma_open() - Allocate wma context and initialize it.
3503  * @psoc: psoc object
3504  * @tgt_cfg_cb: tgt config callback fun
3505  * @cds_cfg:  mac parameters
3506  * @target_type: target type
3507  *
3508  * Return: 0 on success, errno on failure
3509  */
wma_open(struct wlan_objmgr_psoc * psoc,wma_tgt_cfg_cb tgt_cfg_cb,struct cds_config_info * cds_cfg,uint32_t target_type)3510 QDF_STATUS wma_open(struct wlan_objmgr_psoc *psoc,
3511 		    wma_tgt_cfg_cb tgt_cfg_cb,
3512 		    struct cds_config_info *cds_cfg,
3513 		    uint32_t target_type)
3514 {
3515 	tp_wma_handle wma_handle;
3516 	HTC_HANDLE htc_handle;
3517 	qdf_device_t qdf_dev;
3518 	void *wmi_handle;
3519 	QDF_STATUS qdf_status;
3520 	struct wmi_unified_attach_params *params;
3521 	struct policy_mgr_wma_cbacks wma_cbacks;
3522 	struct target_psoc_info *tgt_psoc_info;
3523 	int i;
3524 	bool val = 0;
3525 	void *cds_context;
3526 	target_resource_config *wlan_res_cfg;
3527 	uint32_t self_gen_frm_pwr = 0;
3528 	uint32_t device_mode = cds_get_conparam();
3529 
3530 	wma_debug("Enter");
3531 
3532 	cds_context = cds_get_global_context();
3533 	if (!cds_context) {
3534 		wma_err("Invalid CDS context");
3535 		return QDF_STATUS_E_INVAL;
3536 	}
3537 
3538 	g_wmi_version_info.major = __WMI_VER_MAJOR_;
3539 	g_wmi_version_info.minor = __WMI_VER_MINOR_;
3540 	g_wmi_version_info.revision = __WMI_REVISION_;
3541 
3542 	qdf_dev = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
3543 	htc_handle = cds_get_context(QDF_MODULE_ID_HTC);
3544 
3545 	if (!htc_handle) {
3546 		wma_err("Invalid HTC handle");
3547 		return QDF_STATUS_E_INVAL;
3548 	}
3549 
3550 	/* Alloc memory for WMA Context */
3551 	qdf_status = cds_alloc_context(QDF_MODULE_ID_WMA,
3552 				       (void **)&wma_handle,
3553 				       sizeof(*wma_handle));
3554 
3555 	if (qdf_status != QDF_STATUS_SUCCESS) {
3556 		wma_err("Memory allocation failed for wma_handle");
3557 		return qdf_status;
3558 	}
3559 
3560 	qdf_mem_zero(wma_handle, sizeof(t_wma_handle));
3561 
3562 	if (target_if_alloc_psoc_tgt_info(psoc)) {
3563 		wma_err("target psoc info allocation failed");
3564 		qdf_status = QDF_STATUS_E_NOMEM;
3565 		goto err_free_wma_handle;
3566 	}
3567 
3568 	if (device_mode != QDF_GLOBAL_FTM_MODE) {
3569 #ifdef FEATURE_WLAN_EXTSCAN
3570 		qdf_wake_lock_create(&wma_handle->extscan_wake_lock,
3571 					"wlan_extscan_wl");
3572 #endif /* FEATURE_WLAN_EXTSCAN */
3573 		qdf_wake_lock_create(&wma_handle->wow_wake_lock,
3574 			"wlan_wow_wl");
3575 		qdf_wake_lock_create(&wma_handle->wow_auth_req_wl,
3576 			"wlan_auth_req_wl");
3577 		qdf_wake_lock_create(&wma_handle->wow_assoc_req_wl,
3578 			"wlan_assoc_req_wl");
3579 		qdf_wake_lock_create(&wma_handle->wow_deauth_rec_wl,
3580 			"wlan_deauth_rec_wl");
3581 		qdf_wake_lock_create(&wma_handle->wow_disassoc_rec_wl,
3582 			"wlan_disassoc_rec_wl");
3583 		qdf_wake_lock_create(&wma_handle->wow_ap_assoc_lost_wl,
3584 			"wlan_ap_assoc_lost_wl");
3585 		qdf_wake_lock_create(&wma_handle->wow_auto_shutdown_wl,
3586 			"wlan_auto_shutdown_wl");
3587 		qdf_wake_lock_create(&wma_handle->roam_ho_wl,
3588 			"wlan_roam_ho_wl");
3589 		qdf_wake_lock_create(&wma_handle->roam_preauth_wl,
3590 				     "wlan_roam_preauth_wl");
3591 		qdf_wake_lock_create(&wma_handle->probe_req_wps_wl,
3592 				     "wlan_probe_req_wps_wl");
3593 		qdf_wake_lock_create(&wma_handle->sap_d3_wow_wake_lock,
3594 				     "wlan_sap_d3_wow_wake_lock");
3595 		qdf_wake_lock_create(&wma_handle->go_d3_wow_wake_lock,
3596 				     "wlan_go_d3_wow_wake_lock");
3597 	}
3598 
3599 	qdf_status = wlan_objmgr_psoc_try_get_ref(psoc, WLAN_LEGACY_WMA_ID);
3600 	if (QDF_IS_STATUS_ERROR(qdf_status)) {
3601 		wma_err("PSOC get_ref fails");
3602 		goto err_get_psoc_ref;
3603 	}
3604 	wma_handle->psoc = psoc;
3605 
3606 	if (!wlan_pmo_no_op_on_page_fault(psoc)) {
3607 		qdf_status = wma_init_pagefault_wakeup_history(wma_handle);
3608 		if (QDF_IS_STATUS_ERROR(qdf_status))
3609 			goto err_wma_handle;
3610 	}
3611 
3612 	wma_target_if_open(wma_handle);
3613 
3614 	/*
3615 	 * Allocate locally used params with its rx_ops member,
3616 	 * and free it immediately after used.
3617 	 */
3618 	params = qdf_mem_malloc(sizeof(*params));
3619 	if (!params) {
3620 		qdf_status = QDF_STATUS_E_NOMEM;
3621 		goto err_wma_handle;
3622 	}
3623 
3624 	params->osdev = NULL;
3625 	params->target_type = WMI_TLV_TARGET;
3626 	params->use_cookie = false;
3627 	params->psoc = psoc;
3628 	params->max_commands = WMI_MAX_CMDS;
3629 
3630 	/* initialize tlv attach */
3631 	wmi_tlv_init();
3632 
3633 	/* attach the wmi */
3634 	wmi_handle = wmi_unified_attach(wma_handle, params);
3635 	qdf_mem_free(params);
3636 	if (!wmi_handle) {
3637 		wma_err("failed to attach WMI");
3638 		qdf_status = QDF_STATUS_E_NOMEM;
3639 		goto err_wma_handle;
3640 	}
3641 
3642 	target_if_register_legacy_service_ready_cb(
3643 					wma_legacy_service_ready_event_handler);
3644 
3645 	wma_info("WMA --> wmi_unified_attach - success");
3646 
3647 	/* store the wmi handle in tgt_if_handle */
3648 	tgt_psoc_info = wlan_psoc_get_tgt_if_handle(psoc);
3649 
3650 	target_psoc_set_target_type(tgt_psoc_info, target_type);
3651 	target_psoc_set_device_mode(tgt_psoc_info, device_mode);
3652 	/* Save the WMI & HTC handle */
3653 	target_psoc_set_wmi_hdl(tgt_psoc_info, wmi_handle);
3654 	wma_handle->wmi_handle = wmi_handle;
3655 	target_psoc_set_htc_hdl(tgt_psoc_info, htc_handle);
3656 	wma_handle->cds_context = cds_context;
3657 	wma_handle->qdf_dev = qdf_dev;
3658 	wma_handle->enable_tx_compl_tsf64 =
3659 			cds_cfg->enable_tx_compl_tsf64;
3660 
3661 	/* Register Converged Event handlers */
3662 	init_deinit_register_tgt_psoc_ev_handlers(psoc);
3663 
3664 	/* Register LFR2/3 common Roam Event handler */
3665 	target_if_roam_register_common_events(psoc);
3666 
3667 	/* Register Roam offload Event handlers */
3668 	target_if_roam_offload_register_events(psoc);
3669 
3670 	/* Initialize max_no_of_peers for wma_get_number_of_peers_supported() */
3671 	cds_cfg->max_station = wma_init_max_no_of_peers(wma_handle,
3672 							cds_cfg->max_station);
3673 
3674 	wlan_mlme_set_assoc_sta_limit(psoc, cds_cfg->max_station);
3675 
3676 	wlan_mlme_register_common_events(psoc);
3677 
3678 	/* initialize default target config */
3679 	wlan_res_cfg = target_psoc_get_wlan_res_cfg(tgt_psoc_info);
3680 	if (!wlan_res_cfg) {
3681 		wma_err("wlan_res_cfg is null");
3682 		qdf_status = QDF_STATUS_E_NOMEM;
3683 		goto err_wma_handle;
3684 	}
3685 
3686 	wma_set_default_tgt_config(wma_handle, wlan_res_cfg, cds_cfg);
3687 	wma_update_num_tdls_vdevs_if_11be_mlo(psoc, wlan_res_cfg);
3688 
3689 	qdf_status = wlan_mlme_get_tx_chainmask_cck(psoc, &val);
3690 	if (qdf_status != QDF_STATUS_SUCCESS) {
3691 		wma_err("Failed to get tx_chainmask_cck");
3692 		qdf_status = QDF_STATUS_E_FAILURE;
3693 		goto err_wma_handle;
3694 	}
3695 	wma_handle->tx_chain_mask_cck = val;
3696 
3697 	qdf_status = wlan_mlme_get_self_gen_frm_pwr(psoc, &self_gen_frm_pwr);
3698 	if (qdf_status != QDF_STATUS_SUCCESS)
3699 		wma_err("Failed to get self_gen_frm_pwr");
3700 	wma_handle->self_gen_frm_pwr = self_gen_frm_pwr;
3701 
3702 	cds_cfg->max_bssid = WLAN_MAX_VDEVS;
3703 
3704 	wma_handle->max_station = cds_cfg->max_station;
3705 	wma_handle->max_bssid = cds_cfg->max_bssid;
3706 	wma_handle->enable_mc_list =
3707 		ucfg_pmo_is_mc_addr_list_enabled(wma_handle->psoc);
3708 	wma_handle->active_uc_apf_mode =
3709 		ucfg_pmo_get_active_uc_apf_mode(wma_handle->psoc);
3710 	wma_handle->active_mc_bc_apf_mode =
3711 		ucfg_pmo_get_active_mc_bc_apf_mode(wma_handle->psoc);
3712 	wma_handle->link_stats_results = NULL;
3713 #ifdef WLAN_FEATURE_LPSS
3714 	wma_handle->is_lpass_enabled = cds_cfg->is_lpass_enabled;
3715 #endif
3716 	wma_handle->interfaces = qdf_mem_malloc(sizeof(struct wma_txrx_node) *
3717 						wma_handle->max_bssid);
3718 	if (!wma_handle->interfaces) {
3719 		qdf_status = QDF_STATUS_E_NOMEM;
3720 		goto err_scn_context;
3721 	}
3722 
3723 	for (i = 0; i < wma_handle->max_bssid; ++i)
3724 		wma_vdev_init(&wma_handle->interfaces[i]);
3725 
3726 	/* Register the debug print event handler */
3727 	wmi_unified_register_event_handler(wma_handle->wmi_handle,
3728 					wmi_debug_print_event_id,
3729 					wma_unified_debug_print_event_handler,
3730 					WMA_RX_SERIALIZER_CTX);
3731 	/* Register profiling event Handler */
3732 	wmi_unified_register_event_handler(wma_handle->wmi_handle,
3733 					wmi_wlan_profile_data_event_id,
3734 					wma_profile_data_report_event_handler,
3735 					WMA_RX_SERIALIZER_CTX);
3736 
3737 	wma_handle->tgt_cfg_update_cb = tgt_cfg_cb;
3738 	wma_handle->old_hw_mode_index = WMA_DEFAULT_HW_MODE_INDEX;
3739 	wma_handle->new_hw_mode_index = WMA_DEFAULT_HW_MODE_INDEX;
3740 	wma_handle->saved_chan.num_channels = 0;
3741 	wma_handle->fw_timeout_crash = cds_cfg->fw_timeout_crash;
3742 
3743 	qdf_status = qdf_mc_timer_init(&wma_handle->service_ready_ext_timer,
3744 					QDF_TIMER_TYPE_SW,
3745 					wma_service_ready_ext_evt_timeout,
3746 					wma_handle);
3747 	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
3748 		wma_err("Failed to initialize service ready ext timeout");
3749 		goto err_event_init;
3750 	}
3751 
3752 	qdf_status = qdf_event_create(&wma_handle->target_suspend);
3753 	if (qdf_status != QDF_STATUS_SUCCESS) {
3754 		wma_err("target suspend event initialization failed");
3755 		goto err_event_init;
3756 	}
3757 
3758 	/* Init Tx Frame Complete event */
3759 	qdf_status = qdf_event_create(&wma_handle->tx_frm_download_comp_event);
3760 	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
3761 		wma_err("failed to init tx_frm_download_comp_event");
3762 		goto err_event_init;
3763 	}
3764 
3765 	/* Init tx queue empty check event */
3766 	qdf_status = qdf_event_create(&wma_handle->tx_queue_empty_event);
3767 	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
3768 		wma_err("failed to init tx_queue_empty_event");
3769 		goto err_event_init;
3770 	}
3771 
3772 	qdf_status = cds_shutdown_notifier_register(wma_shutdown_notifier_cb,
3773 						    wma_handle);
3774 	if (qdf_status != QDF_STATUS_SUCCESS) {
3775 		wma_err("Shutdown notifier register failed: %d", qdf_status);
3776 		goto err_event_init;
3777 	}
3778 
3779 	qdf_status = qdf_event_create(&wma_handle->runtime_suspend);
3780 	if (qdf_status != QDF_STATUS_SUCCESS) {
3781 		wma_err("runtime_suspend event initialization failed");
3782 		goto err_event_init;
3783 	}
3784 
3785 	qdf_status = qdf_event_create(&wma_handle->recovery_event);
3786 	if (qdf_status != QDF_STATUS_SUCCESS) {
3787 		wma_err("recovery event initialization failed");
3788 		goto err_event_init;
3789 	}
3790 
3791 	qdf_status = qdf_mutex_create(&wma_handle->radio_stats_lock);
3792 	if (QDF_IS_STATUS_ERROR(qdf_status)) {
3793 		wma_err("Failed to create radio stats mutex");
3794 		goto err_event_init;
3795 	}
3796 
3797 	qdf_list_create(&wma_handle->wma_hold_req_queue,
3798 		      MAX_ENTRY_HOLD_REQ_QUEUE);
3799 	qdf_spinlock_create(&wma_handle->wma_hold_req_q_lock);
3800 	qdf_atomic_init(&wma_handle->is_wow_bus_suspended);
3801 	qdf_atomic_init(&wma_handle->sap_num_clients_connected);
3802 	qdf_atomic_init(&wma_handle->go_num_clients_connected);
3803 
3804 	/* register for STA kickout function */
3805 	wmi_unified_register_event_handler(wma_handle->wmi_handle,
3806 					   wmi_peer_sta_kickout_event_id,
3807 					   wma_peer_sta_kickout_event_handler,
3808 					   WMA_RX_SERIALIZER_CTX);
3809 	/* register for fw state response event */
3810 	wma_register_fw_state_events(wma_handle->wmi_handle);
3811 
3812 #ifdef WLAN_POWER_DEBUG
3813 	/* register for Chip Power stats event */
3814 	wmi_unified_register_event_handler(wma_handle->wmi_handle,
3815 				wmi_pdev_chip_power_stats_event_id,
3816 				wma_unified_power_debug_stats_event_handler,
3817 				WMA_RX_SERIALIZER_CTX);
3818 #endif
3819 #ifdef WLAN_FEATURE_BEACON_RECEPTION_STATS
3820 	/* register for beacon stats event */
3821 	wmi_unified_register_event_handler(wma_handle->wmi_handle,
3822 				wmi_vdev_bcn_reception_stats_event_id,
3823 				wma_unified_beacon_debug_stats_event_handler,
3824 				WMA_RX_SERIALIZER_CTX);
3825 #endif
3826 
3827 #if defined(CLD_PM_QOS) && defined(WLAN_FEATURE_LL_MODE)
3828 	wmi_unified_register_event_handler(wma_handle->wmi_handle,
3829 					   wmi_vdev_bcn_latency_event_id,
3830 					   wma_vdev_bcn_latency_event_handler,
3831 					   WMA_RX_SERIALIZER_CTX);
3832 #endif
3833 	/* register for linkspeed response event */
3834 	wmi_unified_register_event_handler(wma_handle->wmi_handle,
3835 					   wmi_peer_estimated_linkspeed_event_id,
3836 					   wma_link_speed_event_handler,
3837 					   WMA_RX_SERIALIZER_CTX);
3838 
3839 #ifdef FEATURE_OEM_DATA_SUPPORT
3840 	wmi_unified_register_event_handler(wma_handle->wmi_handle,
3841 					   wmi_oem_response_event_id,
3842 					   wma_oem_data_response_handler,
3843 					   WMA_RX_SERIALIZER_CTX);
3844 #endif /* FEATURE_OEM_DATA_SUPPORT */
3845 
3846 	/* Register beacon tx complete event id. The event is required
3847 	 * for sending channel switch announcement frames
3848 	 */
3849 	wmi_unified_register_event_handler(wma_handle->wmi_handle,
3850 					wmi_offload_bcn_tx_status_event_id,
3851 					wma_unified_bcntx_status_event_handler,
3852 					WMA_RX_SERIALIZER_CTX);
3853 
3854 	wmi_unified_register_event_handler(wma_handle->wmi_handle,
3855 					   wmi_update_vdev_rate_stats_event_id,
3856 					   wma_link_status_event_handler,
3857 					   WMA_RX_SERIALIZER_CTX);
3858 
3859 	wmi_unified_register_event_handler(wma_handle->wmi_handle,
3860 					   wmi_roam_scan_stats_event_id,
3861 					   wma_roam_scan_stats_event_handler,
3862 					   WMA_RX_SERIALIZER_CTX);
3863 
3864 	wmi_unified_register_event_handler(wma_handle->wmi_handle,
3865 					   wmi_pdev_cold_boot_cal_event_id,
3866 					   wma_cold_boot_cal_event_handler,
3867 					   WMA_RX_WORK_CTX);
3868 
3869 #ifdef FEATURE_OEM_DATA
3870 	wmi_unified_register_event_handler(wma_handle->wmi_handle,
3871 					   wmi_oem_data_event_id,
3872 					   wma_oem_event_handler,
3873 					   WMA_RX_WORK_CTX);
3874 #endif
3875 
3876 #ifdef WLAN_FEATURE_LINK_LAYER_STATS
3877 	/* Register event handler for processing Link Layer Stats
3878 	 * response from the FW
3879 	 */
3880 	wma_register_ll_stats_event_handler(wma_handle);
3881 
3882 #endif /* WLAN_FEATURE_LINK_LAYER_STATS */
3883 
3884 	wmi_set_tgt_assert(wma_handle->wmi_handle,
3885 			   cds_cfg->force_target_assert_enabled);
3886 	/* Firmware debug log */
3887 	qdf_status = dbglog_init(wma_handle->wmi_handle);
3888 	if (qdf_status != QDF_STATUS_SUCCESS) {
3889 		wma_err("Firmware Dbglog initialization failed");
3890 		goto err_dbglog_init;
3891 	}
3892 
3893 	wma_handle->staMaxLIModDtim = cds_cfg->sta_maxlimod_dtim;
3894 	wma_handle->sta_max_li_mod_dtim_ms = cds_cfg->sta_maxlimod_dtim_ms;
3895 	wma_handle->staModDtim = ucfg_pmo_get_sta_mod_dtim(wma_handle->psoc);
3896 	wma_handle->staDynamicDtim =
3897 			ucfg_pmo_get_sta_dynamic_dtim(wma_handle->psoc);
3898 
3899 #ifdef WLAN_FEATURE_STATS_EXT
3900 	/* register for extended stats event */
3901 	wmi_unified_register_event_handler(wma_handle->wmi_handle,
3902 					   wmi_stats_ext_event_id,
3903 					   wma_stats_ext_event_handler,
3904 					   WMA_RX_SERIALIZER_CTX);
3905 #endif /* WLAN_FEATURE_STATS_EXT */
3906 #ifdef FEATURE_WLAN_EXTSCAN
3907 	wma_register_extscan_event_handler(wma_handle);
3908 #endif /* WLAN_FEATURE_STATS_EXT */
3909 
3910 	wmi_unified_register_event_handler(wma_handle->wmi_handle,
3911 				wmi_rssi_breach_event_id,
3912 				wma_rssi_breached_event_handler,
3913 				WMA_RX_SERIALIZER_CTX);
3914 
3915 	qdf_wake_lock_create(&wma_handle->wmi_cmd_rsp_wake_lock,
3916 					"wlan_fw_rsp_wakelock");
3917 	qdf_runtime_lock_init(&wma_handle->wmi_cmd_rsp_runtime_lock);
3918 	qdf_runtime_lock_init(&wma_handle->sap_prevent_runtime_pm_lock);
3919 	qdf_runtime_lock_init(&wma_handle->ndp_prevent_runtime_pm_lock);
3920 
3921 	/* Register peer assoc conf event handler */
3922 	wmi_unified_register_event_handler(wma_handle->wmi_handle,
3923 					   wmi_peer_assoc_conf_event_id,
3924 					   wma_peer_assoc_conf_handler,
3925 					   WMA_RX_SERIALIZER_CTX);
3926 	wmi_unified_register_event_handler(wma_handle->wmi_handle,
3927 					   wmi_peer_create_conf_event_id,
3928 					   wma_peer_create_confirm_handler,
3929 					   WMA_RX_SERIALIZER_CTX);
3930 	wmi_unified_register_event_handler(wma_handle->wmi_handle,
3931 					   wmi_peer_delete_response_event_id,
3932 					   wma_peer_delete_handler,
3933 					   WMA_RX_SERIALIZER_CTX);
3934 	wmi_unified_register_event_handler(wma_handle->wmi_handle,
3935 					   wmi_chan_info_event_id,
3936 					   wma_chan_info_event_handler,
3937 					   WMA_RX_SERIALIZER_CTX);
3938 	wmi_unified_register_event_handler(wma_handle->wmi_handle,
3939 				wmi_dbg_mesg_flush_complete_event_id,
3940 				wma_flush_complete_evt_handler,
3941 				WMA_RX_WORK_CTX);
3942 	wmi_unified_register_event_handler(wma_handle->wmi_handle,
3943 				wmi_report_rx_aggr_failure_event_id,
3944 				wma_rx_aggr_failure_event_handler,
3945 				WMA_RX_SERIALIZER_CTX);
3946 
3947 	wmi_unified_register_event_handler(
3948 				wma_handle->wmi_handle,
3949 				wmi_coex_report_antenna_isolation_event_id,
3950 				wma_antenna_isolation_event_handler,
3951 				WMA_RX_SERIALIZER_CTX);
3952 
3953 	wma_handle->ito_repeat_count = cds_cfg->ito_repeat_count;
3954 	wma_handle->bandcapability = cds_cfg->bandcapability;
3955 
3956 	/* Register PWR_SAVE_FAIL event only in case of recovery(1) */
3957 	if (ucfg_pmo_get_auto_power_fail_mode(wma_handle->psoc) ==
3958 	    PMO_FW_TO_SEND_WOW_IND_ON_PWR_FAILURE) {
3959 		wmi_unified_register_event_handler(wma_handle->wmi_handle,
3960 			wmi_pdev_chip_pwr_save_failure_detect_event_id,
3961 			wma_chip_power_save_failure_detected_handler,
3962 			WMA_RX_WORK_CTX);
3963 	}
3964 
3965 	wmi_unified_register_event_handler(wma_handle->wmi_handle,
3966 				wmi_pdev_div_rssi_antid_event_id,
3967 				wma_pdev_div_info_evt_handler,
3968 				WMA_RX_WORK_CTX);
3969 
3970 	wmi_unified_register_event_handler(wma_handle->wmi_handle,
3971 					   wmi_get_ani_level_event_id,
3972 					   wma_get_ani_level_evt_handler,
3973 					   WMA_RX_WORK_CTX);
3974 
3975 	wma_register_debug_callback();
3976 	wifi_pos_register_get_phy_mode_cb(wma_handle->psoc,
3977 					  wma_get_phy_mode_cb);
3978 	wifi_pos_register_get_fw_phy_mode_for_freq_cb(
3979 					wma_handle->psoc,
3980 					wma_get_fw_phy_mode_for_freq_cb);
3981 
3982 	/* Register callback with PMO so PMO can update the vdev pause bitmap*/
3983 	pmo_register_pause_bitmap_notifier(wma_handle->psoc,
3984 		wma_vdev_update_pause_bitmap);
3985 	pmo_register_get_pause_bitmap(wma_handle->psoc,
3986 		wma_vdev_get_pause_bitmap);
3987 	pmo_register_is_device_in_low_pwr_mode(wma_handle->psoc,
3988 		wma_vdev_is_device_in_low_pwr_mode);
3989 	pmo_register_get_dtim_period_callback(wma_handle->psoc,
3990 					      wma_vdev_get_dtim_period);
3991 	pmo_register_get_beacon_interval_callback(wma_handle->psoc,
3992 						  wma_vdev_get_beacon_interval);
3993 	wma_cbacks.wma_get_connection_info = wma_get_connection_info;
3994 	wma_register_nan_callbacks(wma_handle);
3995 	wma_register_pkt_capture_callbacks(wma_handle);
3996 	qdf_status = policy_mgr_register_wma_cb(wma_handle->psoc, &wma_cbacks);
3997 	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
3998 		wma_err("Failed to register wma cb with Policy Manager");
3999 	}
4000 
4001 	wmi_unified_register_event_handler(wma_handle->wmi_handle,
4002 			wmi_phyerr_event_id,
4003 			wma_unified_phyerr_rx_event_handler,
4004 			WMA_RX_WORK_CTX);
4005 
4006 	wmi_unified_register_event_handler(wma_handle->wmi_handle,
4007 			wmi_sap_obss_detection_report_event_id,
4008 			wma_vdev_obss_detection_info_handler,
4009 			WMA_RX_SERIALIZER_CTX);
4010 
4011 	wmi_unified_register_event_handler(wma_handle->wmi_handle,
4012 			wmi_obss_color_collision_report_event_id,
4013 			wma_vdev_bss_color_collision_info_handler,
4014 			WMA_RX_WORK_CTX);
4015 
4016 	wma_register_twt_events(wma_handle);
4017 
4018 	wma_register_apf_events(wma_handle);
4019 	wma_register_md_events(wma_handle);
4020 	wma_register_wlm_stats_events(wma_handle);
4021 	wma_register_wlm_latency_level_event(wma_handle);
4022 	wma_register_mws_coex_events(wma_handle);
4023 	wma_trace_init();
4024 	wma_set_exclude_selftx_from_cca_busy_time(
4025 			cds_cfg->exclude_selftx_from_cca_busy,
4026 			wma_handle);
4027 	return QDF_STATUS_SUCCESS;
4028 
4029 err_dbglog_init:
4030 	qdf_status = qdf_mutex_destroy(&wma_handle->radio_stats_lock);
4031 	if (QDF_IS_STATUS_ERROR(qdf_status))
4032 		wma_err("Failed to destroy radio stats mutex");
4033 
4034 	qdf_wake_lock_destroy(&wma_handle->wmi_cmd_rsp_wake_lock);
4035 	qdf_runtime_lock_deinit(&wma_handle->ndp_prevent_runtime_pm_lock);
4036 	qdf_runtime_lock_deinit(&wma_handle->sap_prevent_runtime_pm_lock);
4037 	qdf_runtime_lock_deinit(&wma_handle->wmi_cmd_rsp_runtime_lock);
4038 	qdf_spinlock_destroy(&wma_handle->wma_hold_req_q_lock);
4039 err_event_init:
4040 	wmi_unified_unregister_event_handler(wma_handle->wmi_handle,
4041 					     wmi_debug_print_event_id);
4042 
4043 	for (i = 0; i < wma_handle->max_bssid; ++i)
4044 		wma_vdev_deinit(&wma_handle->interfaces[i]);
4045 
4046 	qdf_mem_free(wma_handle->interfaces);
4047 
4048 err_scn_context:
4049 	qdf_mem_free(((struct cds_context *) cds_context)->cfg_ctx);
4050 	((struct cds_context *)cds_context)->cfg_ctx = NULL;
4051 	qdf_mem_free(wmi_handle);
4052 
4053 err_wma_handle:
4054 	wlan_objmgr_psoc_release_ref(psoc, WLAN_LEGACY_WMA_ID);
4055 err_get_psoc_ref:
4056 	target_if_free_psoc_tgt_info(psoc);
4057 	if (cds_get_conparam() != QDF_GLOBAL_FTM_MODE) {
4058 		qdf_wake_lock_destroy(&wma_handle->go_d3_wow_wake_lock);
4059 		qdf_wake_lock_destroy(&wma_handle->sap_d3_wow_wake_lock);
4060 #ifdef FEATURE_WLAN_EXTSCAN
4061 		qdf_wake_lock_destroy(&wma_handle->extscan_wake_lock);
4062 #endif /* FEATURE_WLAN_EXTSCAN */
4063 		qdf_wake_lock_destroy(&wma_handle->wow_wake_lock);
4064 		qdf_wake_lock_destroy(&wma_handle->wow_auth_req_wl);
4065 		qdf_wake_lock_destroy(&wma_handle->wow_assoc_req_wl);
4066 		qdf_wake_lock_destroy(&wma_handle->wow_deauth_rec_wl);
4067 		qdf_wake_lock_destroy(&wma_handle->wow_disassoc_rec_wl);
4068 		qdf_wake_lock_destroy(&wma_handle->wow_ap_assoc_lost_wl);
4069 		qdf_wake_lock_destroy(&wma_handle->wow_auto_shutdown_wl);
4070 		qdf_wake_lock_destroy(&wma_handle->roam_ho_wl);
4071 		qdf_wake_lock_destroy(&wma_handle->roam_preauth_wl);
4072 		qdf_wake_lock_destroy(&wma_handle->probe_req_wps_wl);
4073 	}
4074 err_free_wma_handle:
4075 	cds_free_context(QDF_MODULE_ID_WMA, wma_handle);
4076 
4077 	wma_debug("Exit");
4078 
4079 	return qdf_status;
4080 }
4081 
4082 /**
4083  * wma_pre_start() - wma pre start
4084  *
4085  * Return: 0 on success, errno on failure
4086  */
wma_pre_start(void)4087 QDF_STATUS wma_pre_start(void)
4088 {
4089 	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
4090 	tp_wma_handle wma_handle;
4091 	void *htc_handle;
4092 
4093 	wma_debug("Enter");
4094 
4095 	wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
4096 
4097 	/* Validate the wma_handle */
4098 	if (!wma_handle) {
4099 		qdf_status = QDF_STATUS_E_INVAL;
4100 		goto end;
4101 	}
4102 
4103 	htc_handle = lmac_get_htc_hdl(wma_handle->psoc);
4104 	if (!htc_handle) {
4105 		wma_err("invalid htc handle");
4106 		qdf_status = QDF_STATUS_E_INVAL;
4107 		goto end;
4108 	}
4109 
4110 	/* Open endpoint for ctrl path - WMI <--> HTC */
4111 	qdf_status = wmi_unified_connect_htc_service(wma_handle->wmi_handle,
4112 						     htc_handle);
4113 	if (qdf_status != QDF_STATUS_SUCCESS) {
4114 		wma_err("wmi_unified_connect_htc_service");
4115 		if (!cds_is_fw_down())
4116 			QDF_BUG(0);
4117 
4118 		qdf_status = QDF_STATUS_E_FAULT;
4119 		goto end;
4120 	}
4121 
4122 	/* Open endpoint for wmi diag path */
4123 	qdf_status = wmi_diag_connect_pdev_htc_service(wma_handle->wmi_handle,
4124 						       htc_handle);
4125 	if (qdf_status != QDF_STATUS_SUCCESS) {
4126 		wma_err("wmi_diag_connect_pdev_htc_service");
4127 		if (!cds_is_fw_down())
4128 			QDF_BUG(0);
4129 
4130 		qdf_status = QDF_STATUS_E_FAULT;
4131 		goto end;
4132 	}
4133 
4134 	wma_debug("WMA --> wmi_unified_connect_htc_service - success");
4135 
4136 end:
4137 	wma_debug("Exit");
4138 	return qdf_status;
4139 }
4140 
wma_send_msg_by_priority(tp_wma_handle wma_handle,uint16_t msg_type,void * body_ptr,uint32_t body_val,bool is_high_priority)4141 void wma_send_msg_by_priority(tp_wma_handle wma_handle, uint16_t msg_type,
4142 		 void *body_ptr, uint32_t body_val, bool is_high_priority)
4143 {
4144 	struct scheduler_msg msg = {0};
4145 	QDF_STATUS status;
4146 
4147 	msg.type = msg_type;
4148 	msg.bodyval = body_val;
4149 	msg.bodyptr = body_ptr;
4150 	msg.flush_callback = wma_discard_fw_event;
4151 
4152 	status = scheduler_post_msg_by_priority(QDF_MODULE_ID_PE,
4153 					       &msg, is_high_priority);
4154 	if (!QDF_IS_STATUS_SUCCESS(status)) {
4155 		if (body_ptr)
4156 			qdf_mem_free(body_ptr);
4157 	}
4158 }
4159 
4160 
wma_send_msg(tp_wma_handle wma_handle,uint16_t msg_type,void * body_ptr,uint32_t body_val)4161 void wma_send_msg(tp_wma_handle wma_handle, uint16_t msg_type,
4162 			 void *body_ptr, uint32_t body_val)
4163 {
4164 	wma_send_msg_by_priority(wma_handle, msg_type,
4165 				body_ptr, body_val, false);
4166 }
4167 
wma_send_msg_high_priority(tp_wma_handle wma_handle,uint16_t msg_type,void * body_ptr,uint32_t body_val)4168 void wma_send_msg_high_priority(tp_wma_handle wma_handle, uint16_t msg_type,
4169 			 void *body_ptr, uint32_t body_val)
4170 {
4171 	wma_send_msg_by_priority(wma_handle, msg_type,
4172 				body_ptr, body_val, true);
4173 }
4174 
4175 /**
4176  * wma_set_base_macaddr_indicate() - set base mac address in fw
4177  * @wma_handle: wma handle
4178  * @customAddr: base mac address
4179  *
4180  * Return: 0 for success or error code
4181  */
wma_set_base_macaddr_indicate(tp_wma_handle wma_handle,tSirMacAddr * customAddr)4182 static int wma_set_base_macaddr_indicate(tp_wma_handle wma_handle,
4183 					 tSirMacAddr *customAddr)
4184 {
4185 	int err;
4186 
4187 	err = wmi_unified_set_base_macaddr_indicate_cmd(wma_handle->wmi_handle,
4188 				     (uint8_t *)customAddr);
4189 	if (err)
4190 		return -EIO;
4191 	wma_debug("Base MAC Addr: " QDF_MAC_ADDR_FMT,
4192 		 QDF_MAC_ADDR_REF((*customAddr)));
4193 
4194 	return 0;
4195 }
4196 
4197 /**
4198  * wma_log_supported_evt_handler() - Enable/Disable FW diag/log events
4199  * @handle: WMA handle
4200  * @event:  Event received from FW
4201  * @len:    Length of the event
4202  *
4203  * Enables the low frequency events and disables the high frequency
4204  * events. Bit 17 indicates if the event if low/high frequency.
4205  * 1 - high frequency, 0 - low frequency
4206  *
4207  * Return: 0 on successfully enabling/disabling the events
4208  */
wma_log_supported_evt_handler(void * handle,uint8_t * event,uint32_t len)4209 static int wma_log_supported_evt_handler(void *handle,
4210 		uint8_t *event,
4211 		uint32_t len)
4212 {
4213 	tp_wma_handle wma = (tp_wma_handle) handle;
4214 
4215 	if (wmi_unified_log_supported_evt_cmd(wma->wmi_handle,
4216 				event, len))
4217 		return -EINVAL;
4218 
4219 	return 0;
4220 }
4221 
4222 /**
4223  * wma_pdev_set_hw_mode_resp_evt_handler() - Set HW mode resp evt handler
4224  * @handle: WMI handle
4225  * @event:  Event received from FW
4226  * @len:    Length of the event
4227  *
4228  * Event handler for WMI_PDEV_SET_HW_MODE_RESP_EVENTID that is sent to host
4229  * driver in response to a WMI_PDEV_SET_HW_MODE_CMDID being sent to WLAN
4230  * firmware
4231  *
4232  * Return: QDF_STATUS
4233  */
wma_pdev_set_hw_mode_resp_evt_handler(void * handle,uint8_t * event,uint32_t len)4234 static int wma_pdev_set_hw_mode_resp_evt_handler(void *handle,
4235 		uint8_t *event,
4236 		uint32_t len)
4237 {
4238 	WMI_PDEV_SET_HW_MODE_RESP_EVENTID_param_tlvs *param_buf;
4239 	wmi_pdev_set_hw_mode_response_event_fixed_param *wmi_event;
4240 	wmi_pdev_set_hw_mode_response_vdev_mac_entry *vdev_mac_entry;
4241 	uint32_t i;
4242 	struct sir_set_hw_mode_resp *hw_mode_resp;
4243 	tp_wma_handle wma = (tp_wma_handle) handle;
4244 
4245 	if (wma_validate_handle(wma)) {
4246 		/* Since WMA handle itself is NULL, we cannot send fail
4247 		 * response back to LIM here
4248 		 */
4249 		return QDF_STATUS_E_NULL_VALUE;
4250 	}
4251 
4252 	wma_release_wakelock(&wma->wmi_cmd_rsp_wake_lock);
4253 	wma_remove_req(wma, 0, WMA_PDEV_SET_HW_MODE_RESP);
4254 
4255 	hw_mode_resp = qdf_mem_malloc(sizeof(*hw_mode_resp));
4256 	if (!hw_mode_resp) {
4257 		/* Since this memory allocation itself failed, we cannot
4258 		 * send fail response back to LIM here
4259 		 */
4260 		return QDF_STATUS_E_NULL_VALUE;
4261 	}
4262 
4263 	param_buf = (WMI_PDEV_SET_HW_MODE_RESP_EVENTID_param_tlvs *) event;
4264 	if (!param_buf) {
4265 		wma_err("Invalid WMI_PDEV_SET_HW_MODE_RESP_EVENTID event");
4266 		/* Need to send response back to upper layer to free
4267 		 * active command list
4268 		 */
4269 		goto fail;
4270 	}
4271 	if (param_buf->fixed_param->num_vdev_mac_entries >=
4272 						MAX_VDEV_SUPPORTED) {
4273 		wma_err("num_vdev_mac_entries crossed max value");
4274 		goto fail;
4275 	}
4276 
4277 	wmi_event = param_buf->fixed_param;
4278 	if (wmi_event->num_vdev_mac_entries >
4279 	    param_buf->num_wmi_pdev_set_hw_mode_response_vdev_mac_mapping) {
4280 		wma_err("Invalid num_vdev_mac_entries: %d",
4281 			wmi_event->num_vdev_mac_entries);
4282 		goto fail;
4283 	}
4284 	hw_mode_resp->status = wmi_event->status;
4285 	hw_mode_resp->cfgd_hw_mode_index = wmi_event->cfgd_hw_mode_index;
4286 	hw_mode_resp->num_vdev_mac_entries = wmi_event->num_vdev_mac_entries;
4287 
4288 	wma->set_hw_mode_resp_status = wmi_event->status;
4289 	wma_debug("status:%d cfgd_hw_mode_index:%d num_vdev_mac_entries:%d",
4290 			wmi_event->status,
4291 			wmi_event->cfgd_hw_mode_index,
4292 			wmi_event->num_vdev_mac_entries);
4293 	vdev_mac_entry =
4294 		param_buf->wmi_pdev_set_hw_mode_response_vdev_mac_mapping;
4295 
4296 	/* Store the vdev-mac map in WMA and prepare to send to PE  */
4297 	for (i = 0; i < wmi_event->num_vdev_mac_entries; i++) {
4298 		uint32_t vdev_id, mac_id, pdev_id;
4299 
4300 		vdev_id = vdev_mac_entry[i].vdev_id;
4301 		pdev_id = vdev_mac_entry[i].pdev_id;
4302 		if (pdev_id == OL_TXRX_PDEV_ID) {
4303 			wma_err("soc level id received for mac id");
4304 			goto fail;
4305 		}
4306 		if (vdev_id >= wma->max_bssid) {
4307 			wma_err("vdev_id: %d is invalid, max_bssid: %d",
4308 				vdev_id, wma->max_bssid);
4309 			goto fail;
4310 		}
4311 
4312 		mac_id = WMA_PDEV_TO_MAC_MAP(vdev_mac_entry[i].pdev_id);
4313 
4314 		wma_debug("vdev_id:%d mac_id:%d", vdev_id, mac_id);
4315 
4316 		hw_mode_resp->vdev_mac_map[i].vdev_id = vdev_id;
4317 		hw_mode_resp->vdev_mac_map[i].mac_id = mac_id;
4318 		wma_update_intf_hw_mode_params(vdev_id, mac_id,
4319 				wmi_event->cfgd_hw_mode_index);
4320 	}
4321 
4322 	if (hw_mode_resp->status == SET_HW_MODE_STATUS_OK) {
4323 		if (WMA_DEFAULT_HW_MODE_INDEX == wma->new_hw_mode_index) {
4324 			wma->new_hw_mode_index = wmi_event->cfgd_hw_mode_index;
4325 		} else {
4326 			wma->old_hw_mode_index = wma->new_hw_mode_index;
4327 			wma->new_hw_mode_index = wmi_event->cfgd_hw_mode_index;
4328 		}
4329 		policy_mgr_update_hw_mode_index(wma->psoc,
4330 		wmi_event->cfgd_hw_mode_index);
4331 	}
4332 
4333 	wma_debug("Updated: old_hw_mode_index:%d new_hw_mode_index:%d",
4334 		 wma->old_hw_mode_index, wma->new_hw_mode_index);
4335 
4336 	wma_send_msg(wma, SIR_HAL_PDEV_SET_HW_MODE_RESP,
4337 		     (void *) hw_mode_resp, 0);
4338 
4339 	return QDF_STATUS_SUCCESS;
4340 
4341 fail:
4342 	wma_err("Sending fail response to LIM");
4343 	hw_mode_resp->status = SET_HW_MODE_STATUS_ECANCELED;
4344 	hw_mode_resp->cfgd_hw_mode_index = 0;
4345 	hw_mode_resp->num_vdev_mac_entries = 0;
4346 	wma_send_msg(wma, SIR_HAL_PDEV_SET_HW_MODE_RESP,
4347 			(void *) hw_mode_resp, 0);
4348 
4349 	return QDF_STATUS_E_FAILURE;
4350 }
4351 
4352 /**
4353  * wma_process_pdev_hw_mode_trans_ind() - Process HW mode transition info
4354  *
4355  * @handle: WMA handle
4356  * @fixed_param: Event fixed parameters
4357  * @vdev_mac_entry: vdev mac entry
4358  * @hw_mode_trans_ind: Buffer to store parsed information
4359  *
4360  * Parses fixed_param, vdev_mac_entry and fills in the information into
4361  * hw_mode_trans_ind and wma
4362  *
4363  * Return: None
4364  */
wma_process_pdev_hw_mode_trans_ind(void * handle,wmi_pdev_hw_mode_transition_event_fixed_param * fixed_param,wmi_pdev_set_hw_mode_response_vdev_mac_entry * vdev_mac_entry,struct cm_hw_mode_trans_ind * hw_mode_trans_ind)4365 void wma_process_pdev_hw_mode_trans_ind(void *handle,
4366 	wmi_pdev_hw_mode_transition_event_fixed_param *fixed_param,
4367 	wmi_pdev_set_hw_mode_response_vdev_mac_entry *vdev_mac_entry,
4368 	struct cm_hw_mode_trans_ind *hw_mode_trans_ind)
4369 {
4370 	uint32_t i;
4371 	tp_wma_handle wma = (tp_wma_handle) handle;
4372 
4373 	if (fixed_param->num_vdev_mac_entries > MAX_VDEV_SUPPORTED) {
4374 		wma_err("Number of Vdev mac entries %d exceeded max vdev supported %d",
4375 			fixed_param->num_vdev_mac_entries,
4376 			MAX_VDEV_SUPPORTED);
4377 		return;
4378 	}
4379 	hw_mode_trans_ind->old_hw_mode_index = fixed_param->old_hw_mode_index;
4380 	hw_mode_trans_ind->new_hw_mode_index = fixed_param->new_hw_mode_index;
4381 	hw_mode_trans_ind->num_vdev_mac_entries =
4382 					fixed_param->num_vdev_mac_entries;
4383 
4384 	if (!vdev_mac_entry) {
4385 		wma_debug("null vdev_mac_entry");
4386 		goto update_hw_mode;
4387 	}
4388 
4389 	/* Store the vdev-mac map in WMA and send to policy manager */
4390 	for (i = 0; i < fixed_param->num_vdev_mac_entries; i++) {
4391 		uint32_t vdev_id, mac_id, pdev_id;
4392 
4393 		vdev_id = vdev_mac_entry[i].vdev_id;
4394 		pdev_id = vdev_mac_entry[i].pdev_id;
4395 
4396 		if (pdev_id == OL_TXRX_PDEV_ID) {
4397 			wma_err("soc level id received for mac id");
4398 			return;
4399 		}
4400 		if (vdev_id >= wma->max_bssid) {
4401 			wma_err("vdev_id: %d is invalid, max_bssid: %d",
4402 			        vdev_id, wma->max_bssid);
4403 			return;
4404 		}
4405 
4406 		mac_id = WMA_PDEV_TO_MAC_MAP(vdev_mac_entry[i].pdev_id);
4407 		hw_mode_trans_ind->vdev_mac_map[i].vdev_id = vdev_id;
4408 		hw_mode_trans_ind->vdev_mac_map[i].mac_id = mac_id;
4409 		wma_update_intf_hw_mode_params(vdev_id, mac_id,
4410 				fixed_param->new_hw_mode_index);
4411 	}
4412 update_hw_mode:
4413 	wma->old_hw_mode_index = fixed_param->old_hw_mode_index;
4414 	wma->new_hw_mode_index = fixed_param->new_hw_mode_index;
4415 	policy_mgr_update_new_hw_mode_index(wma->psoc,
4416 		fixed_param->new_hw_mode_index);
4417 	policy_mgr_update_old_hw_mode_index(wma->psoc,
4418 		fixed_param->old_hw_mode_index);
4419 }
4420 
4421 static void
wma_process_mac_freq_mapping(struct cm_hw_mode_trans_ind * hw_mode_trans_ind,WMI_PDEV_HW_MODE_TRANSITION_EVENTID_param_tlvs * param_buf)4422 wma_process_mac_freq_mapping(struct cm_hw_mode_trans_ind *hw_mode_trans_ind,
4423 		WMI_PDEV_HW_MODE_TRANSITION_EVENTID_param_tlvs *param_buf)
4424 {
4425 	uint32_t i, num_mac_freq;
4426 	wmi_pdev_band_to_mac *mac_freq;
4427 
4428 	mac_freq = param_buf->mac_freq_mapping;
4429 	num_mac_freq = param_buf->num_mac_freq_mapping;
4430 
4431 	if (!mac_freq) {
4432 		wma_debug("mac_freq Null");
4433 		return;
4434 	}
4435 
4436 	if (!num_mac_freq || num_mac_freq > MAX_FREQ_RANGE_NUM) {
4437 		wma_debug("num mac freq invalid %d", num_mac_freq);
4438 		return;
4439 	}
4440 
4441 	hw_mode_trans_ind->num_freq_map = num_mac_freq;
4442 	for (i = 0; i < num_mac_freq; i++) {
4443 		hw_mode_trans_ind->mac_freq_map[i].mac_id =
4444 				WMA_PDEV_TO_MAC_MAP(mac_freq[i].pdev_id);
4445 		hw_mode_trans_ind->mac_freq_map[i].start_freq =
4446 							mac_freq[i].start_freq;
4447 		hw_mode_trans_ind->mac_freq_map[i].end_freq =
4448 							mac_freq[i].end_freq;
4449 	}
4450 }
4451 
4452 /**
4453  * wma_pdev_hw_mode_transition_evt_handler() - HW mode transition evt handler
4454  * @handle: WMI handle
4455  * @event:  Event received from FW
4456  * @len:    Length of the event
4457  *
4458  * Event handler for WMI_PDEV_HW_MODE_TRANSITION_EVENTID that indicates an
4459  * asynchronous hardware mode transition. This event notifies the host driver
4460  * that firmware independently changed the hardware mode for some reason, such
4461  * as Coex, LFR 3.0, etc
4462  *
4463  * Return: Success on receiving valid params from FW
4464  */
wma_pdev_hw_mode_transition_evt_handler(void * handle,uint8_t * event,uint32_t len)4465 static int wma_pdev_hw_mode_transition_evt_handler(void *handle,
4466 		uint8_t *event,
4467 		uint32_t len)
4468 {
4469 	WMI_PDEV_HW_MODE_TRANSITION_EVENTID_param_tlvs *param_buf;
4470 	wmi_pdev_hw_mode_transition_event_fixed_param *wmi_event;
4471 	wmi_pdev_set_hw_mode_response_vdev_mac_entry *vdev_mac_entry;
4472 	struct cm_hw_mode_trans_ind *hw_mode_trans_ind;
4473 	tp_wma_handle wma = (tp_wma_handle) handle;
4474 
4475 	if (wma_validate_handle(wma)) {
4476 		/* This is an async event. So, not sending any event to LIM */
4477 		return QDF_STATUS_E_NULL_VALUE;
4478 	}
4479 
4480 	param_buf = (WMI_PDEV_HW_MODE_TRANSITION_EVENTID_param_tlvs *) event;
4481 	if (!param_buf) {
4482 		/* This is an async event. So, not sending any event to LIM */
4483 		wma_err("Invalid WMI_PDEV_HW_MODE_TRANSITION_EVENTID event");
4484 		return QDF_STATUS_E_FAILURE;
4485 	}
4486 
4487 	if (param_buf->fixed_param->num_vdev_mac_entries > MAX_VDEV_SUPPORTED) {
4488 		wma_err("num_vdev_mac_entries: %d crossed max value: %d",
4489 			param_buf->fixed_param->num_vdev_mac_entries,
4490 			MAX_VDEV_SUPPORTED);
4491 		return QDF_STATUS_E_FAILURE;
4492 	}
4493 
4494 	hw_mode_trans_ind = qdf_mem_malloc(sizeof(*hw_mode_trans_ind));
4495 	if (!hw_mode_trans_ind)
4496 		return QDF_STATUS_E_NOMEM;
4497 
4498 	wmi_event = param_buf->fixed_param;
4499 	vdev_mac_entry =
4500 		param_buf->wmi_pdev_set_hw_mode_response_vdev_mac_mapping;
4501 	if (wmi_event->num_vdev_mac_entries >
4502 	    param_buf->num_wmi_pdev_set_hw_mode_response_vdev_mac_mapping) {
4503 		wma_err("Invalid num_vdev_mac_entries: %d",
4504 			wmi_event->num_vdev_mac_entries);
4505 		qdf_mem_free(hw_mode_trans_ind);
4506 		return -EINVAL;
4507 	}
4508 
4509 	wma_process_pdev_hw_mode_trans_ind(wma, wmi_event, vdev_mac_entry,
4510 		hw_mode_trans_ind);
4511 	wma_process_mac_freq_mapping(hw_mode_trans_ind, param_buf);
4512 
4513 	if (policy_mgr_is_hwmode_offload_enabled(wma->psoc)) {
4514 		policy_mgr_hw_mode_transition_cb(
4515 			hw_mode_trans_ind->old_hw_mode_index,
4516 			hw_mode_trans_ind->new_hw_mode_index,
4517 			hw_mode_trans_ind->num_vdev_mac_entries,
4518 			hw_mode_trans_ind->vdev_mac_map,
4519 			hw_mode_trans_ind->num_freq_map,
4520 			hw_mode_trans_ind->mac_freq_map,
4521 			wma->psoc);
4522 		qdf_mem_free(hw_mode_trans_ind);
4523 	} else {
4524 		struct scheduler_msg sme_msg = {0};
4525 		QDF_STATUS status;
4526 
4527 		wma_debug("post eWNI_SME_HW_MODE_TRANS_IND");
4528 		sme_msg.type = eWNI_SME_HW_MODE_TRANS_IND;
4529 		sme_msg.bodyptr = hw_mode_trans_ind;
4530 		sme_msg.flush_callback = wma_discard_fw_event;
4531 
4532 		status = scheduler_post_message(QDF_MODULE_ID_WMA,
4533 						QDF_MODULE_ID_SME,
4534 						QDF_MODULE_ID_SME, &sme_msg);
4535 		if (QDF_IS_STATUS_ERROR(status))
4536 			qdf_mem_free(hw_mode_trans_ind);
4537 	}
4538 
4539 	return QDF_STATUS_SUCCESS;
4540 }
4541 
4542 /**
4543  * wma_pdev_set_dual_mode_config_resp_evt_handler() - Dual mode evt handler
4544  * @handle: WMI handle
4545  * @event:  Event received from FW
4546  * @len:    Length of the event
4547  *
4548  * Notifies the host driver of the completion or failure of a
4549  * WMI_PDEV_SET_MAC_CONFIG_CMDID command. This event would be returned to
4550  * the host driver once the firmware has completed a reconfiguration of the Scan
4551  * and FW mode configuration. This changes could include entering or leaving a
4552  * dual mac configuration for either scan and/or more permanent firmware mode.
4553  *
4554  * Return: Success on receiving valid params from FW
4555  */
wma_pdev_set_dual_mode_config_resp_evt_handler(void * handle,uint8_t * event,uint32_t len)4556 static int wma_pdev_set_dual_mode_config_resp_evt_handler(void *handle,
4557 		uint8_t *event,
4558 		uint32_t len)
4559 {
4560 	WMI_PDEV_SET_MAC_CONFIG_RESP_EVENTID_param_tlvs *param_buf;
4561 	wmi_pdev_set_mac_config_response_event_fixed_param *wmi_event;
4562 	tp_wma_handle wma = (tp_wma_handle) handle;
4563 	struct sir_dual_mac_config_resp *dual_mac_cfg_resp;
4564 
4565 	if (wma_validate_handle(wma)) {
4566 		/* Since the WMA handle is NULL, we cannot send resp to LIM.
4567 		 * So, returning from here.
4568 		 */
4569 		return QDF_STATUS_E_NULL_VALUE;
4570 	}
4571 	wma_release_wakelock(&wma->wmi_cmd_rsp_wake_lock);
4572 	wma_remove_req(wma, 0, WMA_PDEV_MAC_CFG_RESP);
4573 
4574 	dual_mac_cfg_resp = qdf_mem_malloc(sizeof(*dual_mac_cfg_resp));
4575 	if (!dual_mac_cfg_resp)
4576 		/* Since the mem alloc failed, we cannot send resp to LIM.
4577 		 * So, returning from here.
4578 		 */
4579 		return QDF_STATUS_E_NULL_VALUE;
4580 
4581 	param_buf = (WMI_PDEV_SET_MAC_CONFIG_RESP_EVENTID_param_tlvs *)
4582 		event;
4583 	if (!param_buf) {
4584 		wma_err("Invalid event");
4585 		goto fail;
4586 	}
4587 
4588 	wmi_event = param_buf->fixed_param;
4589 	wma_debug("status: %d", wmi_event->status);
4590 	dual_mac_cfg_resp->status = wmi_event->status;
4591 
4592 	if (SET_HW_MODE_STATUS_OK == dual_mac_cfg_resp->status) {
4593 		policy_mgr_update_dbs_scan_config(wma->psoc);
4594 		policy_mgr_update_dbs_fw_config(wma->psoc);
4595 	}
4596 
4597 	/* Pass the message to PE */
4598 	wma_send_msg(wma, SIR_HAL_PDEV_MAC_CFG_RESP,
4599 			(void *) dual_mac_cfg_resp, 0);
4600 
4601 	return QDF_STATUS_SUCCESS;
4602 
4603 fail:
4604 	wma_err("Sending fail response to LIM");
4605 	dual_mac_cfg_resp->status = SET_HW_MODE_STATUS_ECANCELED;
4606 	wma_send_msg(wma, SIR_HAL_PDEV_MAC_CFG_RESP,
4607 			(void *) dual_mac_cfg_resp, 0);
4608 
4609 	return QDF_STATUS_E_FAILURE;
4610 
4611 }
4612 
4613 #ifdef WLAN_CONV_SPECTRAL_ENABLE
wma_register_spectral_cmds(tp_wma_handle wma_handle)4614 static void wma_register_spectral_cmds(tp_wma_handle wma_handle)
4615 {
4616 	struct spectral_wmi_ops cmd_ops;
4617 
4618 	cmd_ops.wmi_spectral_configure_cmd_send =
4619 			wmi_unified_vdev_spectral_configure_cmd_send;
4620 	cmd_ops.wmi_spectral_enable_cmd_send =
4621 			wmi_unified_vdev_spectral_enable_cmd_send;
4622 	wlan_register_spectral_wmi_ops(wma_handle->psoc, &cmd_ops);
4623 }
4624 #else
wma_register_spectral_cmds(tp_wma_handle wma_handle)4625 static void wma_register_spectral_cmds(tp_wma_handle wma_handle)
4626 {
4627 }
4628 #endif
4629 /**
4630  * wma_start() - wma start function.
4631  *               Initialize event handlers and timers.
4632  *
4633  * Return: 0 on success, QDF Error on failure
4634  */
wma_start(void)4635 QDF_STATUS wma_start(void)
4636 {
4637 	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
4638 	tp_wma_handle wma_handle;
4639 	struct wmi_unified *wmi_handle;
4640 	struct mac_context *mac = NULL;
4641 
4642 	wma_debug("Enter");
4643 
4644 	wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
4645 	if (!wma_handle) {
4646 		qdf_status = QDF_STATUS_E_INVAL;
4647 		goto end;
4648 	}
4649 
4650 	wmi_handle = get_wmi_unified_hdl_from_psoc(wma_handle->psoc);
4651 	if (wmi_validate_handle(wmi_handle)) {
4652 		qdf_status = QDF_STATUS_E_INVAL;
4653 		goto end;
4654 	}
4655 
4656 	mac = cds_get_context(QDF_MODULE_ID_PE);
4657 	if (!mac) {
4658 		qdf_status = QDF_STATUS_E_INVAL;
4659 		goto end;
4660 	}
4661 
4662 	qdf_status = wmi_unified_register_event_handler(wmi_handle,
4663 						    wmi_wow_wakeup_host_event_id,
4664 						    wma_wow_wakeup_host_event,
4665 						    WMA_RX_TASKLET_CTX);
4666 	if (QDF_IS_STATUS_ERROR(qdf_status)) {
4667 		wma_err("Failed to register wow wakeup host event handler");
4668 		qdf_status = QDF_STATUS_E_FAILURE;
4669 		goto end;
4670 	}
4671 
4672 	if (wma_d0_wow_is_supported()) {
4673 		qdf_status = wmi_unified_register_event_handler(
4674 				wmi_handle,
4675 				wmi_d0_wow_disable_ack_event_id,
4676 				wma_d0_wow_disable_ack_event,
4677 				WMA_RX_TASKLET_CTX);
4678 		if (QDF_IS_STATUS_ERROR(qdf_status)) {
4679 			wma_err("Failed to register d0wow disable ack event handler");
4680 			qdf_status = QDF_STATUS_E_FAILURE;
4681 			goto end;
4682 		}
4683 	}
4684 
4685 	qdf_status = wmi_unified_register_event_handler(wmi_handle,
4686 				wmi_pdev_resume_event_id,
4687 				wma_pdev_resume_event_handler,
4688 				WMA_RX_TASKLET_CTX);
4689 	if (QDF_IS_STATUS_ERROR(qdf_status)) {
4690 		wma_err("Failed to register PDEV resume event handler");
4691 		qdf_status = QDF_STATUS_E_FAILURE;
4692 		goto end;
4693 	}
4694 #if defined(QCA_LL_LEGACY_TX_FLOW_CONTROL) || \
4695 	defined(QCA_LL_TX_FLOW_CONTROL_V2) || defined(CONFIG_HL_SUPPORT)
4696 	wma_debug("MCC TX Pause Event Handler register");
4697 	qdf_status = wmi_unified_register_event_handler(wmi_handle,
4698 					wmi_tx_pause_event_id,
4699 					wma_mcc_vdev_tx_pause_evt_handler,
4700 					WMA_RX_TASKLET_CTX);
4701 #endif /* QCA_LL_LEGACY_TX_FLOW_CONTROL */
4702 
4703 	wma_debug("Registering SAR2 response handler");
4704 	qdf_status = wmi_unified_register_event_handler(wma_handle->wmi_handle,
4705 						wmi_wlan_sar2_result_event_id,
4706 						wma_sar_rsp_evt_handler,
4707 						WMA_RX_SERIALIZER_CTX);
4708 	if (QDF_IS_STATUS_ERROR(qdf_status)) {
4709 		wma_err("Failed to register sar response event cb");
4710 		qdf_status = QDF_STATUS_E_FAILURE;
4711 		goto end;
4712 	}
4713 
4714 #ifdef FEATURE_WLAN_AUTO_SHUTDOWN
4715 	wma_debug("Registering auto shutdown handler");
4716 	qdf_status = wmi_unified_register_event_handler(wmi_handle,
4717 						wmi_host_auto_shutdown_event_id,
4718 						wma_auto_shutdown_event_handler,
4719 						WMA_RX_SERIALIZER_CTX);
4720 	if (QDF_IS_STATUS_ERROR(qdf_status)) {
4721 		wma_err("Failed to register WMI Auto shutdown event handler");
4722 		qdf_status = QDF_STATUS_E_FAILURE;
4723 		goto end;
4724 	}
4725 #endif /* FEATURE_WLAN_AUTO_SHUTDOWN */
4726 	qdf_status = wmi_unified_register_event_handler(wmi_handle,
4727 						wmi_thermal_mgmt_event_id,
4728 						wma_thermal_mgmt_evt_handler,
4729 						WMA_RX_SERIALIZER_CTX);
4730 	if (QDF_IS_STATUS_ERROR(qdf_status)) {
4731 		wma_err("Failed to register thermal mitigation event cb");
4732 		qdf_status = QDF_STATUS_E_FAILURE;
4733 		goto end;
4734 	}
4735 
4736 	qdf_status = wma_ocb_register_callbacks(wma_handle);
4737 	if (QDF_IS_STATUS_ERROR(qdf_status)) {
4738 		wma_err("Failed to register OCB callbacks");
4739 		qdf_status = QDF_STATUS_E_FAILURE;
4740 		goto end;
4741 	}
4742 
4743 	qdf_status = QDF_STATUS_SUCCESS;
4744 
4745 #ifdef QCA_WIFI_FTM
4746 	/*
4747 	 * Tx mgmt attach requires TXRX context which is not created
4748 	 * in FTM mode. So skip the TX mgmt attach.
4749 	 */
4750 	if (cds_get_conparam() == QDF_GLOBAL_FTM_MODE)
4751 		goto end;
4752 #endif /* QCA_WIFI_FTM */
4753 
4754 	qdf_status = wma_tx_attach(wma_handle);
4755 	if (QDF_IS_STATUS_ERROR(qdf_status)) {
4756 		wma_err("Failed to register tx management");
4757 		goto end;
4758 	}
4759 
4760 	/* Initialize log completion timeout */
4761 	qdf_status = qdf_mc_timer_init(&wma_handle->log_completion_timer,
4762 			QDF_TIMER_TYPE_SW,
4763 			wma_log_completion_timeout,
4764 			wma_handle);
4765 	if (QDF_IS_STATUS_ERROR(qdf_status)) {
4766 		wma_err("Failed to initialize log completion timeout");
4767 		goto end;
4768 	}
4769 
4770 	qdf_status = wma_fips_register_event_handlers(wma_handle);
4771 	if (QDF_IS_STATUS_ERROR(qdf_status)) {
4772 		wma_err("Failed to register FIPS event handler");
4773 		qdf_status = QDF_STATUS_E_FAILURE;
4774 		goto end;
4775 	}
4776 
4777 	qdf_status = wma_sar_register_event_handlers(wma_handle);
4778 	if (QDF_IS_STATUS_ERROR(qdf_status)) {
4779 		wma_err("Failed to register SAR event handlers");
4780 		qdf_status = QDF_STATUS_E_FAILURE;
4781 		goto end;
4782 	}
4783 
4784 	/* Initialize the get temperature event handler */
4785 	qdf_status = wmi_unified_register_event_handler(wmi_handle,
4786 					wmi_pdev_temperature_event_id,
4787 					wma_pdev_temperature_evt_handler,
4788 					WMA_RX_SERIALIZER_CTX);
4789 	if (QDF_IS_STATUS_ERROR(qdf_status)) {
4790 		wma_err("Failed to register get_temperature event cb");
4791 		qdf_status = QDF_STATUS_E_FAILURE;
4792 		goto end;
4793 	}
4794 
4795 	qdf_status = wmi_unified_register_event_handler(wmi_handle,
4796 						wmi_vdev_tsf_report_event_id,
4797 						wma_vdev_tsf_handler,
4798 						WMA_RX_SERIALIZER_CTX);
4799 	if (QDF_IS_STATUS_ERROR(qdf_status)) {
4800 		wma_err("Failed to register tsf callback");
4801 		qdf_status = QDF_STATUS_E_FAILURE;
4802 		goto end;
4803 	}
4804 
4805 	/* Initialize the wma_pdev_set_hw_mode_resp_evt_handler event handler */
4806 	qdf_status = wmi_unified_register_event_handler(wmi_handle,
4807 			wmi_pdev_set_hw_mode_rsp_event_id,
4808 			wma_pdev_set_hw_mode_resp_evt_handler,
4809 			WMA_RX_SERIALIZER_CTX);
4810 	if (QDF_IS_STATUS_ERROR(qdf_status)) {
4811 		wma_err("Failed to register set hw mode resp event cb");
4812 		qdf_status = QDF_STATUS_E_FAILURE;
4813 		goto end;
4814 	}
4815 
4816 	/* Initialize the WMI_SOC_HW_MODE_TRANSITION_EVENTID event handler */
4817 	qdf_status = wmi_unified_register_event_handler(wmi_handle,
4818 			wmi_pdev_hw_mode_transition_event_id,
4819 			wma_pdev_hw_mode_transition_evt_handler,
4820 			WMA_RX_SERIALIZER_CTX);
4821 	if (QDF_IS_STATUS_ERROR(qdf_status)) {
4822 		wma_err("Failed to register hw mode transition event cb");
4823 		qdf_status = QDF_STATUS_E_FAILURE;
4824 		goto end;
4825 	}
4826 
4827 	/* Initialize the set dual mac configuration event handler */
4828 	qdf_status = wmi_unified_register_event_handler(wmi_handle,
4829 			wmi_pdev_set_mac_config_resp_event_id,
4830 			wma_pdev_set_dual_mode_config_resp_evt_handler,
4831 			WMA_RX_SERIALIZER_CTX);
4832 	if (QDF_IS_STATUS_ERROR(qdf_status)) {
4833 		wma_err("Failed to register hw mode transition event cb");
4834 		qdf_status = QDF_STATUS_E_FAILURE;
4835 		goto end;
4836 	}
4837 
4838 	qdf_status = wmi_unified_register_event_handler(wmi_handle,
4839 			wmi_coex_bt_activity_event_id,
4840 			wma_wlan_bt_activity_evt_handler,
4841 			WMA_RX_SERIALIZER_CTX);
4842 	if (QDF_IS_STATUS_ERROR(qdf_status)) {
4843 		wma_err("Failed to register coex bt activity event handler");
4844 		qdf_status = QDF_STATUS_E_FAILURE;
4845 		goto end;
4846 	}
4847 	wma_register_spectral_cmds(wma_handle);
4848 
4849 end:
4850 	wma_debug("Exit");
4851 	return qdf_status;
4852 }
4853 
wma_stop(void)4854 QDF_STATUS wma_stop(void)
4855 {
4856 	tp_wma_handle wma_handle;
4857 	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
4858 	int i;
4859 	struct mac_context *mac = NULL;
4860 	struct wlan_objmgr_vdev *vdev;
4861 
4862 	wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
4863 	wma_debug("Enter");
4864 	if (!wma_handle) {
4865 		qdf_status = QDF_STATUS_E_INVAL;
4866 		goto end;
4867 	}
4868 	mac = cds_get_context(QDF_MODULE_ID_PE);
4869 	if (!mac) {
4870 		goto end;
4871 	}
4872 #ifdef QCA_WIFI_FTM
4873 	/*
4874 	 * Tx mgmt detach requires TXRX context which is not created
4875 	 * in FTM mode. So skip the TX mgmt detach.
4876 	 */
4877 	if (cds_get_conparam() == QDF_GLOBAL_FTM_MODE) {
4878 		qdf_status = QDF_STATUS_SUCCESS;
4879 		goto end;
4880 	}
4881 #endif /* QCA_WIFI_FTM */
4882 
4883 	if (wma_handle->ack_work_ctx) {
4884 		cds_flush_work(&wma_handle->ack_work_ctx->ack_cmp_work);
4885 		if (wma_handle->ack_work_ctx->frame)
4886 			qdf_nbuf_free(wma_handle->ack_work_ctx->frame);
4887 
4888 		qdf_mem_free(wma_handle->ack_work_ctx);
4889 		wma_handle->ack_work_ctx = NULL;
4890 	}
4891 
4892 	/* Destroy the timer for log completion */
4893 	qdf_status = qdf_mc_timer_destroy(&wma_handle->log_completion_timer);
4894 	if (qdf_status != QDF_STATUS_SUCCESS)
4895 		wma_err("Failed to destroy the log completion timer");
4896 	/* clean up ll-queue for all vdev */
4897 	for (i = 0; i < wma_handle->max_bssid; i++) {
4898 		vdev = wma_handle->interfaces[i].vdev;
4899 		if (!vdev)
4900 			continue;
4901 
4902 		if (wma_is_vdev_up(i))
4903 			cdp_fc_vdev_flush(cds_get_context(QDF_MODULE_ID_SOC),
4904 					  i);
4905 	}
4906 
4907 	qdf_status = wma_tx_detach(wma_handle);
4908 	if (qdf_status != QDF_STATUS_SUCCESS) {
4909 		wma_err("Failed to deregister tx management");
4910 		goto end;
4911 	}
4912 
4913 end:
4914 	wma_debug("Exit");
4915 	return qdf_status;
4916 }
4917 
4918 /**
4919  * wma_wmi_service_close() - close wma wmi service interface.
4920  *
4921  * Return: 0 on success, QDF Error on failure
4922  */
wma_wmi_service_close(void)4923 QDF_STATUS wma_wmi_service_close(void)
4924 {
4925 	void *cds_ctx;
4926 	tp_wma_handle wma_handle;
4927 	uint8_t i;
4928 	struct wmi_unified *wmi_handle;
4929 
4930 	wma_debug("Enter");
4931 
4932 	cds_ctx = cds_get_global_context();
4933 	if (!cds_ctx) {
4934 		wma_err("Invalid CDS context");
4935 		return QDF_STATUS_E_INVAL;
4936 	}
4937 
4938 	wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
4939 	if (!wma_handle)
4940 		return QDF_STATUS_E_INVAL;
4941 
4942 	wmi_handle = wma_handle->wmi_handle;
4943 	if (wmi_validate_handle(wmi_handle))
4944 		return QDF_STATUS_E_INVAL;
4945 
4946 	/* detach the wmi service */
4947 	wma_debug("calling wmi_unified_detach");
4948 	wmi_unified_detach(wmi_handle);
4949 	wma_handle->wmi_handle = NULL;
4950 
4951 	for (i = 0; i < wma_handle->max_bssid; i++)
4952 		wma_vdev_deinit(&wma_handle->interfaces[i]);
4953 
4954 	qdf_mem_free(wma_handle->interfaces);
4955 
4956 	/* free the wma_handle */
4957 	cds_free_context(QDF_MODULE_ID_WMA, wma_handle);
4958 
4959 	if (((struct cds_context *)cds_ctx)->cfg_ctx)
4960 		qdf_mem_free(((struct cds_context *)cds_ctx)->cfg_ctx);
4961 	((struct cds_context *)cds_ctx)->cfg_ctx = NULL;
4962 	wma_debug("Exit");
4963 	return QDF_STATUS_SUCCESS;
4964 }
4965 
4966 /**
4967  * wma_wmi_work_close() - close the work queue items associated with WMI
4968  *
4969  * This function closes work queue items associated with WMI, but not fully
4970  * closes WMI service.
4971  *
4972  * Return: QDF_STATUS_SUCCESS if work close is successful. Otherwise
4973  *	proper error codes.
4974  */
wma_wmi_work_close(void)4975 QDF_STATUS wma_wmi_work_close(void)
4976 {
4977 	tp_wma_handle wma_handle;
4978 	struct wmi_unified *wmi_handle;
4979 
4980 	wma_debug("Enter");
4981 
4982 	wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
4983 	if (!wma_handle)
4984 		return QDF_STATUS_E_INVAL;
4985 
4986 	wmi_handle = wma_handle->wmi_handle;
4987 	if (wmi_validate_handle(wmi_handle))
4988 		return QDF_STATUS_E_INVAL;
4989 
4990 	/* remove the wmi work */
4991 	wma_debug("calling wmi_unified_remove_work");
4992 	wmi_unified_remove_work(wmi_handle);
4993 
4994 	wma_debug("Exit");
4995 	return QDF_STATUS_SUCCESS;
4996 }
4997 
4998 /**
4999  * wma_close() - wma close function.
5000  *               cleanup resources attached with wma.
5001  *
5002  * Return: 0 on success, QDF Error on failure
5003  */
wma_close(void)5004 QDF_STATUS wma_close(void)
5005 {
5006 	tp_wma_handle wma_handle;
5007 	struct target_psoc_info *tgt_psoc_info;
5008 	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
5009 	struct wmi_unified *wmi_handle;
5010 
5011 	wma_debug("Enter");
5012 
5013 	wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
5014 	if (!wma_handle)
5015 		return QDF_STATUS_E_INVAL;
5016 
5017 	wmi_handle = wma_handle->wmi_handle;
5018 	if (wmi_validate_handle(wmi_handle))
5019 		return QDF_STATUS_E_INVAL;
5020 
5021 	if (!wlan_pmo_no_op_on_page_fault(wma_handle->psoc))
5022 		wma_deinit_pagefault_wakeup_history(wma_handle);
5023 
5024 	qdf_atomic_set(&wma_handle->sap_num_clients_connected, 0);
5025 	qdf_atomic_set(&wma_handle->go_num_clients_connected, 0);
5026 
5027 	if (cds_get_conparam() != QDF_GLOBAL_FTM_MODE) {
5028 		qdf_wake_lock_destroy(&wma_handle->go_d3_wow_wake_lock);
5029 		qdf_wake_lock_destroy(&wma_handle->sap_d3_wow_wake_lock);
5030 #ifdef FEATURE_WLAN_EXTSCAN
5031 		qdf_wake_lock_destroy(&wma_handle->extscan_wake_lock);
5032 #endif /* FEATURE_WLAN_EXTSCAN */
5033 		qdf_wake_lock_destroy(&wma_handle->wow_wake_lock);
5034 		qdf_wake_lock_destroy(&wma_handle->wow_auth_req_wl);
5035 		qdf_wake_lock_destroy(&wma_handle->wow_assoc_req_wl);
5036 		qdf_wake_lock_destroy(&wma_handle->wow_deauth_rec_wl);
5037 		qdf_wake_lock_destroy(&wma_handle->wow_disassoc_rec_wl);
5038 		qdf_wake_lock_destroy(&wma_handle->wow_ap_assoc_lost_wl);
5039 		qdf_wake_lock_destroy(&wma_handle->wow_auto_shutdown_wl);
5040 		qdf_wake_lock_destroy(&wma_handle->roam_ho_wl);
5041 		qdf_wake_lock_destroy(&wma_handle->roam_preauth_wl);
5042 		qdf_wake_lock_destroy(&wma_handle->probe_req_wps_wl);
5043 	}
5044 
5045 	/* unregister Firmware debug log */
5046 	qdf_status = dbglog_deinit(wmi_handle);
5047 	if (qdf_status != QDF_STATUS_SUCCESS)
5048 		wma_err("dbglog_deinit failed");
5049 
5050 	qdf_status = qdf_mc_timer_destroy(&wma_handle->service_ready_ext_timer);
5051 	if (!QDF_IS_STATUS_SUCCESS(qdf_status))
5052 		wma_err("Failed to destroy service ready ext event timer");
5053 
5054 	qdf_event_destroy(&wma_handle->target_suspend);
5055 	qdf_event_destroy(&wma_handle->runtime_suspend);
5056 	qdf_event_destroy(&wma_handle->recovery_event);
5057 	qdf_event_destroy(&wma_handle->tx_frm_download_comp_event);
5058 	qdf_event_destroy(&wma_handle->tx_queue_empty_event);
5059 	wma_cleanup_hold_req(wma_handle);
5060 	qdf_wake_lock_destroy(&wma_handle->wmi_cmd_rsp_wake_lock);
5061 	qdf_runtime_lock_deinit(&wma_handle->ndp_prevent_runtime_pm_lock);
5062 	qdf_runtime_lock_deinit(&wma_handle->sap_prevent_runtime_pm_lock);
5063 	qdf_runtime_lock_deinit(&wma_handle->wmi_cmd_rsp_runtime_lock);
5064 	qdf_spinlock_destroy(&wma_handle->wma_hold_req_q_lock);
5065 
5066 	if (wma_handle->pGetRssiReq) {
5067 		qdf_mem_free(wma_handle->pGetRssiReq);
5068 		wma_handle->pGetRssiReq = NULL;
5069 	}
5070 
5071 	wma_unified_radio_tx_mem_free(wma_handle);
5072 
5073 	qdf_status = qdf_mutex_destroy(&wma_handle->radio_stats_lock);
5074 	if (QDF_IS_STATUS_ERROR(qdf_status))
5075 		wma_err("Failed to destroy radio stats mutex");
5076 
5077 	if (wma_handle->pdev) {
5078 		wlan_objmgr_pdev_release_ref(wma_handle->pdev,
5079 				WLAN_LEGACY_WMA_ID);
5080 		wma_handle->pdev = NULL;
5081 	}
5082 
5083 	pmo_unregister_get_beacon_interval_callback(wma_handle->psoc);
5084 	pmo_unregister_get_dtim_period_callback(wma_handle->psoc);
5085 	pmo_unregister_is_device_in_low_pwr_mode(wma_handle->psoc);
5086 	pmo_unregister_get_pause_bitmap(wma_handle->psoc);
5087 	pmo_unregister_pause_bitmap_notifier(wma_handle->psoc);
5088 
5089 	tgt_psoc_info = wlan_psoc_get_tgt_if_handle(wma_handle->psoc);
5090 	init_deinit_free_num_units(wma_handle->psoc, tgt_psoc_info);
5091 	target_if_free_psoc_tgt_info(wma_handle->psoc);
5092 
5093 	wlan_objmgr_psoc_release_ref(wma_handle->psoc, WLAN_LEGACY_WMA_ID);
5094 	wma_handle->psoc = NULL;
5095 
5096 	wma_debug("Exit");
5097 	return QDF_STATUS_SUCCESS;
5098 }
5099 
5100 /**
5101  * wma_update_fw_config() - update fw configuration
5102  * @psoc: psoc to query configuration from
5103  * @tgt_hdl: target capability info
5104  *
5105  * Return: none
5106  */
wma_update_fw_config(struct wlan_objmgr_psoc * psoc,struct target_psoc_info * tgt_hdl)5107 static void wma_update_fw_config(struct wlan_objmgr_psoc *psoc,
5108 				 struct target_psoc_info *tgt_hdl)
5109 {
5110 	target_resource_config *cfg = &tgt_hdl->info.wlan_res_cfg;
5111 
5112 	/* Override the no. of max fragments as per platform configuration */
5113 	cfg->max_frag_entries =	QDF_MIN(QCA_OL_11AC_TX_MAX_FRAGS,
5114 					target_if_get_max_frag_entry(tgt_hdl));
5115 	target_if_set_max_frag_entry(tgt_hdl, cfg->max_frag_entries);
5116 
5117 	if (cds_get_conparam() == QDF_GLOBAL_FTM_MODE)
5118 		cfg->num_wow_filters =  0;
5119 	else
5120 		cfg->num_wow_filters = ucfg_pmo_get_num_wow_filters(psoc);
5121 
5122 	cfg->apf_instruction_size = ucfg_pmo_get_apf_instruction_size(psoc);
5123 	cfg->num_packet_filters = ucfg_pmo_get_num_packet_filters(psoc);
5124 }
5125 
5126 /**
5127  * wma_set_tx_partition_base() - set TX MSDU ID partition base for IPA
5128  * @value:  TX MSDU ID partition base
5129  *
5130  * Return: none
5131  */
5132 #ifdef IPA_OFFLOAD
wma_set_tx_partition_base(uint32_t value)5133 static void wma_set_tx_partition_base(uint32_t value)
5134 {
5135 	cdp_ipa_set_uc_tx_partition_base(
5136 			cds_get_context(QDF_MODULE_ID_SOC),
5137 			(struct cdp_cfg *)cds_get_context(QDF_MODULE_ID_CFG),
5138 			value);
5139 	wma_debug("TX_MSDU_ID_PARTITION=%d", value);
5140 }
5141 #else
wma_set_tx_partition_base(uint32_t value)5142 static void wma_set_tx_partition_base(uint32_t value)
5143 {
5144 }
5145 #endif
5146 
5147 #ifdef WLAN_FEATURE_IGMP_OFFLOAD
5148 /**
5149  * wma_get_igmp_offload_enable() - update tgt service with igmp offload support
5150  * @wmi_handle: Unified wmi handle
5151  * @cfg: target services
5152  *
5153  * Return: none
5154  */
5155 static inline void
wma_get_igmp_offload_enable(struct wmi_unified * wmi_handle,struct wma_tgt_services * cfg)5156 wma_get_igmp_offload_enable(struct wmi_unified *wmi_handle,
5157 			    struct wma_tgt_services *cfg)
5158 {
5159 	cfg->igmp_offload_enable = wmi_service_enabled(
5160 					wmi_handle,
5161 					wmi_service_igmp_offload_support);
5162 }
5163 #else
5164 static inline void
wma_get_igmp_offload_enable(struct wmi_unified * wmi_handle,struct wma_tgt_services * cfg)5165 wma_get_igmp_offload_enable(struct wmi_unified *wmi_handle,
5166 			    struct wma_tgt_services *cfg)
5167 {}
5168 #endif
5169 
5170 #ifdef FEATURE_WLAN_TDLS
5171 /**
5172  * wma_get_tdls_wideband_support() - update tgt service with service tdls
5173  *                                   wideband support
5174  * @wmi_handle: Unified wmi handle
5175  * @cfg: target services
5176  *
5177  * Return: none
5178  */
5179 static inline void
wma_get_tdls_wideband_support(struct wmi_unified * wmi_handle,struct wma_tgt_services * cfg)5180 wma_get_tdls_wideband_support(struct wmi_unified *wmi_handle,
5181 			      struct wma_tgt_services *cfg)
5182 {
5183 	cfg->en_tdls_wideband_support = wmi_service_enabled(
5184 					     wmi_handle,
5185 					     wmi_service_tdls_wideband_support);
5186 }
5187 
5188 #ifdef WLAN_FEATURE_11BE
5189 /**
5190  * wma_get_tdls_mlo_support() - update tgt service with service tdls
5191  * be support
5192  * @wmi_handle: Unified wmi handle
5193  * @cfg: target services
5194  *
5195  * Return: none
5196  */
5197 static inline void
wma_get_tdls_mlo_support(struct wmi_unified * wmi_handle,struct wma_tgt_services * cfg)5198 wma_get_tdls_mlo_support(struct wmi_unified *wmi_handle,
5199 			 struct wma_tgt_services *cfg)
5200 {
5201 	cfg->en_tdls_mlo_support =
5202 		wmi_service_enabled(wmi_handle,
5203 				    wmi_service_tdls_mlo_support);
5204 }
5205 
5206 static inline void
wma_get_n_link_mlo_support(struct wmi_unified * wmi_handle,struct wma_tgt_services * cfg)5207 wma_get_n_link_mlo_support(struct wmi_unified *wmi_handle,
5208 			   struct wma_tgt_services *cfg)
5209 {
5210 	cfg->en_n_link_mlo_support =
5211 		wmi_service_enabled(wmi_handle,
5212 				    wmi_service_n_link_mlo_support);
5213 }
5214 
5215 #else
5216 static inline void
wma_get_tdls_mlo_support(struct wmi_unified * wmi_handle,struct wma_tgt_services * cfg)5217 wma_get_tdls_mlo_support(struct wmi_unified *wmi_handle,
5218 			 struct wma_tgt_services *cfg)
5219 {
5220 }
5221 
5222 static inline void
wma_get_n_link_mlo_support(struct wmi_unified * wmi_handle,struct wma_tgt_services * cfg)5223 wma_get_n_link_mlo_support(struct wmi_unified *wmi_handle,
5224 			   struct wma_tgt_services *cfg)
5225 {
5226 }
5227 #endif /* WLAN_FEATURE_11BE */
5228 
5229 #ifdef WLAN_FEATURE_11AX
5230 /**
5231  * wma_get_tdls_ax_support() - update tgt service with service tdls ax support
5232  * @wmi_handle: Unified wmi handle
5233  * @cfg: target services
5234  *
5235  * Return: none
5236  */
5237 static inline void
wma_get_tdls_ax_support(struct wmi_unified * wmi_handle,struct wma_tgt_services * cfg)5238 wma_get_tdls_ax_support(struct wmi_unified *wmi_handle,
5239 			struct wma_tgt_services *cfg)
5240 {
5241 	cfg->en_tdls_11ax_support = wmi_service_enabled(
5242 						wmi_handle,
5243 						wmi_service_tdls_ax_support);
5244 }
5245 
5246 static inline void
wma_get_tdls_6g_support(struct wmi_unified * wmi_handle,struct wma_tgt_services * cfg)5247 wma_get_tdls_6g_support(struct wmi_unified *wmi_handle,
5248 			struct wma_tgt_services *cfg)
5249 {
5250 	cfg->en_tdls_6g_support = wmi_service_enabled(
5251 						wmi_handle,
5252 						wmi_service_tdls_6g_support);
5253 }
5254 
5255 #else
5256 static inline void
wma_get_tdls_ax_support(struct wmi_unified * wmi_handle,struct wma_tgt_services * cfg)5257 wma_get_tdls_ax_support(struct wmi_unified *wmi_handle,
5258 			struct wma_tgt_services *cfg)
5259 {}
5260 
5261 static inline void
wma_get_tdls_6g_support(struct wmi_unified * wmi_handle,struct wma_tgt_services * cfg)5262 wma_get_tdls_6g_support(struct wmi_unified *wmi_handle,
5263 			struct wma_tgt_services *cfg)
5264 {}
5265 
5266 #endif
5267 #else
5268 static inline void
wma_get_tdls_mlo_support(struct wmi_unified * wmi_handle,struct wma_tgt_services * cfg)5269 wma_get_tdls_mlo_support(struct wmi_unified *wmi_handle,
5270 			 struct wma_tgt_services *cfg)
5271 {
5272 }
5273 
5274 static inline void
wma_get_n_link_mlo_support(struct wmi_unified * wmi_handle,struct wma_tgt_services * cfg)5275 wma_get_n_link_mlo_support(struct wmi_unified *wmi_handle,
5276 			   struct wma_tgt_services *cfg)
5277 {}
5278 
5279 static inline void
wma_get_tdls_ax_support(struct wmi_unified * wmi_handle,struct wma_tgt_services * cfg)5280 wma_get_tdls_ax_support(struct wmi_unified *wmi_handle,
5281 			struct wma_tgt_services *cfg)
5282 {}
5283 
5284 static inline void
wma_get_tdls_6g_support(struct wmi_unified * wmi_handle,struct wma_tgt_services * cfg)5285 wma_get_tdls_6g_support(struct wmi_unified *wmi_handle,
5286 			struct wma_tgt_services *cfg)
5287 {}
5288 
5289 static inline void
wma_get_tdls_wideband_support(struct wmi_unified * wmi_handle,struct wma_tgt_services * cfg)5290 wma_get_tdls_wideband_support(struct wmi_unified *wmi_handle,
5291 			      struct wma_tgt_services *cfg)
5292 {}
5293 #endif
5294 
5295 #ifdef WLAN_FEATURE_DYNAMIC_MAC_ADDR_UPDATE
wma_get_dynamic_vdev_macaddr_support(struct wmi_unified * wmi_handle,struct wma_tgt_services * cfg)5296 static inline void wma_get_dynamic_vdev_macaddr_support(
5297 		  struct wmi_unified *wmi_handle, struct wma_tgt_services *cfg)
5298 {
5299 	cfg->dynamic_vdev_macaddr_support =
5300 		wmi_service_enabled(
5301 			wmi_handle,
5302 			wmi_service_dynamic_update_vdev_macaddr_support);
5303 }
5304 #else
wma_get_dynamic_vdev_macaddr_support(struct wmi_unified * wmi_handle,struct wma_tgt_services * cfg)5305 static inline void wma_get_dynamic_vdev_macaddr_support(
5306 		  struct wmi_unified *wmi_handle, struct wma_tgt_services *cfg)
5307 {
5308 }
5309 #endif
5310 
5311 #ifdef WLAN_FEATURE_11BE
5312 /**
5313  * wma_get_mlo_tid_to_link_mapping_support() - update tgt service with
5314  * service tid to link mapping support
5315  * @wmi_handle: Unified wmi handle
5316  * @cfg: target services
5317  *
5318  * Return: none
5319  */
5320 static inline void
wma_get_mlo_tid_to_link_mapping_support(struct wmi_unified * wmi_handle,struct wma_tgt_services * cfg)5321 wma_get_mlo_tid_to_link_mapping_support(struct wmi_unified *wmi_handle,
5322 					struct wma_tgt_services *cfg)
5323 {
5324 	cfg->en_mlo_tid_to_link_support =
5325 		wmi_service_enabled(wmi_handle,
5326 				    wmi_service_mlo_tid_to_link_mapping_support);
5327 }
5328 
5329 #else
5330 static inline void
wma_get_mlo_tid_to_link_mapping_support(struct wmi_unified * wmi_handle,struct wma_tgt_services * cfg)5331 wma_get_mlo_tid_to_link_mapping_support(struct wmi_unified *wmi_handle,
5332 					struct wma_tgt_services *cfg)
5333 {
5334 }
5335 #endif
5336 
5337 #ifdef WLAN_FEATURE_NAN
5338 /**
5339  * wma_nan_set_pairing_feature() - set feature bit for Secure NAN if max
5340  * pairing session has non-zero value.
5341  *
5342  * Return: none
5343  */
wma_nan_set_pairing_feature(void)5344 static void wma_nan_set_pairing_feature(void)
5345 {
5346 	tp_wma_handle wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
5347 	struct target_psoc_info *tgt_hdl;
5348 	struct wlan_objmgr_psoc *psoc;
5349 
5350 	if (!wma_handle) {
5351 		wma_err("wma handle is null");
5352 		return;
5353 	}
5354 
5355 	psoc = wma_handle->psoc;
5356 	tgt_hdl = wlan_psoc_get_tgt_if_handle(psoc);
5357 	if (!tgt_hdl) {
5358 		wma_err("tgt_hdl is null");
5359 		return;
5360 	}
5361 
5362 	if (tgt_hdl->info.service_ext2_param.max_nan_pairing_sessions) {
5363 		wma_set_fw_wlan_feat_caps(SECURE_NAN);
5364 		wma_debug("Secure NAN is enabled");
5365 	}
5366 }
5367 #endif /* WLAN_FEATURE_NAN */
5368 
5369 /**
5370  * wma_update_target_services() - update target services from wma handle
5371  * @wmi_handle: Unified wmi handle
5372  * @cfg: target services
5373  *
5374  * Return: none
5375  */
wma_update_target_services(struct wmi_unified * wmi_handle,struct wma_tgt_services * cfg)5376 static inline void wma_update_target_services(struct wmi_unified *wmi_handle,
5377 					      struct wma_tgt_services *cfg)
5378 {
5379 	/* STA power save */
5380 	cfg->sta_power_save = wmi_service_enabled(wmi_handle,
5381 						     wmi_service_sta_pwrsave);
5382 
5383 	/* Enable UAPSD */
5384 	cfg->uapsd = wmi_service_enabled(wmi_handle,
5385 					    wmi_service_ap_uapsd);
5386 
5387 	/* Update AP DFS service */
5388 	cfg->ap_dfs = wmi_service_enabled(wmi_handle,
5389 					     wmi_service_ap_dfs);
5390 
5391 	/* Enable 11AC */
5392 	cfg->en_11ac = wmi_service_enabled(wmi_handle,
5393 					      wmi_service_11ac);
5394 	if (cfg->en_11ac)
5395 		g_fw_wlan_feat_caps |= (1 << DOT11AC);
5396 
5397 	/* Proactive ARP response */
5398 	g_fw_wlan_feat_caps |= (1 << WLAN_PERIODIC_TX_PTRN);
5399 
5400 	/* Enable WOW */
5401 	g_fw_wlan_feat_caps |= (1 << WOW);
5402 
5403 	/* ARP offload */
5404 	cfg->arp_offload = wmi_service_enabled(wmi_handle,
5405 						  wmi_service_arpns_offload);
5406 
5407 	/* Adaptive early-rx */
5408 	cfg->early_rx = wmi_service_enabled(wmi_handle,
5409 					       wmi_service_early_rx);
5410 
5411 	cfg->is_fw_therm_throt_supp = wmi_service_enabled(wmi_handle,
5412 							  wmi_service_tt);
5413 
5414 #ifdef FEATURE_WLAN_SCAN_PNO
5415 	/* PNO offload */
5416 	if (wmi_service_enabled(wmi_handle, wmi_service_nlo)) {
5417 		cfg->pno_offload = true;
5418 		g_fw_wlan_feat_caps |= (1 << PNO);
5419 	}
5420 #endif /* FEATURE_WLAN_SCAN_PNO */
5421 
5422 #ifdef FEATURE_WLAN_EXTSCAN
5423 	if (wmi_service_enabled(wmi_handle, wmi_service_extscan))
5424 		g_fw_wlan_feat_caps |= (1 << EXTENDED_SCAN);
5425 #endif /* FEATURE_WLAN_EXTSCAN */
5426 	cfg->lte_coex_ant_share = wmi_service_enabled(wmi_handle,
5427 					wmi_service_lte_ant_share_support);
5428 #ifdef FEATURE_WLAN_TDLS
5429 	/* Enable TDLS */
5430 	if (wmi_service_enabled(wmi_handle, wmi_service_tdls)) {
5431 		cfg->en_tdls = 1;
5432 		g_fw_wlan_feat_caps |= (1 << TDLS);
5433 	}
5434 	/* Enable advanced TDLS features */
5435 	if (wmi_service_enabled(wmi_handle, wmi_service_tdls_offchan)) {
5436 		cfg->en_tdls_offchan = 1;
5437 		g_fw_wlan_feat_caps |= (1 << TDLS_OFF_CHANNEL);
5438 	}
5439 
5440 	cfg->en_tdls_uapsd_buf_sta =
5441 		wmi_service_enabled(wmi_handle,
5442 				       wmi_service_tdls_uapsd_buffer_sta);
5443 	cfg->en_tdls_uapsd_sleep_sta =
5444 		wmi_service_enabled(wmi_handle,
5445 				       wmi_service_tdls_uapsd_sleep_sta);
5446 #endif /* FEATURE_WLAN_TDLS */
5447 	if (wmi_service_enabled
5448 		    (wmi_handle, wmi_service_beacon_offload))
5449 		cfg->beacon_offload = true;
5450 	if (wmi_service_enabled
5451 		    (wmi_handle, wmi_service_sta_pmf_offload))
5452 		cfg->pmf_offload = true;
5453 #ifdef WLAN_FEATURE_ROAM_OFFLOAD
5454 	/* Enable Roam Offload */
5455 	cfg->en_roam_offload = wmi_service_enabled(wmi_handle,
5456 					      wmi_service_roam_ho_offload);
5457 #endif /* WLAN_FEATURE_ROAM_OFFLOAD */
5458 #ifdef WLAN_FEATURE_NAN
5459 	if (wmi_service_enabled(wmi_handle, wmi_service_nan))
5460 		g_fw_wlan_feat_caps |= (1 << NAN);
5461 	wma_nan_set_pairing_feature();
5462 #endif /* WLAN_FEATURE_NAN */
5463 
5464 	if (wmi_service_enabled(wmi_handle, wmi_service_rtt))
5465 		g_fw_wlan_feat_caps |= (1 << RTT);
5466 
5467 	if (wmi_service_enabled(wmi_handle,
5468 			wmi_service_tx_msdu_id_new_partition_support)) {
5469 		wma_set_tx_partition_base(HTT_TX_IPA_NEW_MSDU_ID_SPACE_BEGIN);
5470 	} else {
5471 		wma_set_tx_partition_base(HTT_TX_IPA_MSDU_ID_SPACE_BEGIN);
5472 	}
5473 
5474 	wma_he_update_tgt_services(wmi_handle, cfg);
5475 	wma_eht_update_tgt_services(wmi_handle, cfg);
5476 
5477 	cfg->get_peer_info_enabled =
5478 		wmi_service_enabled(wmi_handle,
5479 				       wmi_service_peer_stats_info);
5480 	if (wmi_service_enabled(wmi_handle, wmi_service_fils_support))
5481 		cfg->is_fils_roaming_supported = true;
5482 
5483 	if (wmi_service_enabled(wmi_handle, wmi_service_mawc_support))
5484 		cfg->is_fw_mawc_capable = true;
5485 
5486 	if (wmi_service_enabled(wmi_handle,
5487 				wmi_service_11k_neighbour_report_support))
5488 		cfg->is_11k_offload_supported = true;
5489 
5490 	if (wmi_service_enabled(wmi_handle, wmi_service_twt_requestor))
5491 		cfg->twt_requestor = true;
5492 	if (wmi_service_enabled(wmi_handle, wmi_service_twt_responder))
5493 		cfg->twt_responder = true;
5494 	if (wmi_service_enabled(wmi_handle, wmi_service_obss_scan))
5495 		cfg->obss_scan_offload = true;
5496 	if (wmi_service_enabled(wmi_handle, wmi_service_beacon_reception_stats))
5497 		cfg->bcn_reception_stats = true;
5498 
5499 	if (wmi_service_enabled(wmi_handle, wmi_service_vdev_latency_config))
5500 		g_fw_wlan_feat_caps |= (1 << VDEV_LATENCY_CONFIG);
5501 	if (wmi_service_enabled(wmi_handle,
5502 				wmi_roam_scan_chan_list_to_host_support))
5503 		cfg->is_roam_scan_ch_to_host = true;
5504 
5505 	cfg->ll_stats_per_chan_rx_tx_time =
5506 		wmi_service_enabled(wmi_handle,
5507 				    wmi_service_ll_stats_per_chan_rx_tx_time);
5508 
5509 	wma_get_service_cap_club_get_sta_in_ll_stats_req(wmi_handle, cfg);
5510 
5511 	wma_get_igmp_offload_enable(wmi_handle, cfg);
5512 	wma_get_tdls_ax_support(wmi_handle, cfg);
5513 	wma_get_tdls_mlo_support(wmi_handle, cfg);
5514 	wma_get_tdls_6g_support(wmi_handle, cfg);
5515 	wma_get_tdls_wideband_support(wmi_handle, cfg);
5516 	wma_get_dynamic_vdev_macaddr_support(wmi_handle, cfg);
5517 	wma_get_service_cap_per_link_mlo_stats(wmi_handle, cfg);
5518 	wma_get_n_link_mlo_support(wmi_handle, cfg);
5519 	wma_get_mlo_tid_to_link_mapping_support(wmi_handle, cfg);
5520 }
5521 
5522 /**
5523  * wma_update_target_ht_cap() - update ht capabality from wma handle
5524  * @tgt_hdl: pointer to structure target_psoc_info
5525  * @cfg: ht capability
5526  *
5527  * Return: none
5528  */
5529 static inline void
wma_update_target_ht_cap(struct target_psoc_info * tgt_hdl,struct wma_tgt_ht_cap * cfg)5530 wma_update_target_ht_cap(struct target_psoc_info *tgt_hdl,
5531 			 struct wma_tgt_ht_cap *cfg)
5532 {
5533 	int ht_cap_info;
5534 
5535 	ht_cap_info = target_if_get_ht_cap_info(tgt_hdl);
5536 	/* RX STBC */
5537 	cfg->ht_rx_stbc = !!(ht_cap_info & WMI_HT_CAP_RX_STBC);
5538 
5539 	/* TX STBC */
5540 	cfg->ht_tx_stbc = !!(ht_cap_info & WMI_HT_CAP_TX_STBC);
5541 
5542 	/* MPDU density */
5543 	cfg->mpdu_density = ht_cap_info & WMI_HT_CAP_MPDU_DENSITY;
5544 
5545 	/* HT RX LDPC */
5546 	cfg->ht_rx_ldpc = !!(ht_cap_info & WMI_HT_CAP_LDPC);
5547 
5548 	/* HT SGI */
5549 	cfg->ht_sgi_20 = !!(ht_cap_info & WMI_HT_CAP_HT20_SGI);
5550 
5551 	cfg->ht_sgi_40 = !!(ht_cap_info & WMI_HT_CAP_HT40_SGI);
5552 
5553 	cfg->dynamic_smps = !!(ht_cap_info & WMI_HT_CAP_DYNAMIC_SMPS);
5554 
5555 	/* RF chains */
5556 	cfg->num_rf_chains = target_if_get_num_rf_chains(tgt_hdl);
5557 
5558 	wma_nofl_debug("ht_cap_info - %x ht_rx_stbc - %d, ht_tx_stbc - %d\n"
5559 		 "mpdu_density - %d ht_rx_ldpc - %d ht_sgi_20 - %d\n"
5560 		 "ht_sgi_40 - %d num_rf_chains - %d dynamic_smps - %d",
5561 		 ht_cap_info,
5562 		 cfg->ht_rx_stbc, cfg->ht_tx_stbc, cfg->mpdu_density,
5563 		 cfg->ht_rx_ldpc, cfg->ht_sgi_20, cfg->ht_sgi_40,
5564 		 cfg->num_rf_chains, cfg->dynamic_smps);
5565 
5566 }
5567 
5568 /**
5569  * wma_update_target_vht_cap() - update vht capabality from wma handle
5570  * @tgt_hdl: pointer to structure target_psoc_info
5571  * @cfg: vht capabality
5572  *
5573  * Return: none
5574  */
5575 static inline void
wma_update_target_vht_cap(struct target_psoc_info * tgt_hdl,struct wma_tgt_vht_cap * cfg)5576 wma_update_target_vht_cap(struct target_psoc_info *tgt_hdl,
5577 			  struct wma_tgt_vht_cap *cfg)
5578 {
5579 	int vht_cap_info = target_if_get_vht_cap_info(tgt_hdl);
5580 
5581 	if (vht_cap_info & WMI_VHT_CAP_MAX_MPDU_LEN_11454)
5582 		cfg->vht_max_mpdu = WMI_VHT_CAP_MAX_MPDU_LEN_11454;
5583 	else if (vht_cap_info & WMI_VHT_CAP_MAX_MPDU_LEN_7935)
5584 		cfg->vht_max_mpdu = WMI_VHT_CAP_MAX_MPDU_LEN_7935;
5585 	else
5586 		cfg->vht_max_mpdu = 0;
5587 
5588 
5589 	if (vht_cap_info & WMI_VHT_CAP_CH_WIDTH_80P80_160MHZ) {
5590 		cfg->supp_chan_width = 1 << eHT_CHANNEL_WIDTH_80P80MHZ;
5591 		cfg->supp_chan_width |= 1 << eHT_CHANNEL_WIDTH_160MHZ;
5592 	} else if (vht_cap_info & WMI_VHT_CAP_CH_WIDTH_160MHZ) {
5593 		cfg->supp_chan_width = 1 << eHT_CHANNEL_WIDTH_160MHZ;
5594 	} else {
5595 		cfg->supp_chan_width = 1 << eHT_CHANNEL_WIDTH_80MHZ;
5596 	}
5597 
5598 	cfg->vht_rx_ldpc = vht_cap_info & WMI_VHT_CAP_RX_LDPC;
5599 
5600 	cfg->vht_short_gi_80 = vht_cap_info & WMI_VHT_CAP_SGI_80MHZ;
5601 	cfg->vht_short_gi_160 = vht_cap_info & WMI_VHT_CAP_SGI_160MHZ;
5602 
5603 	cfg->vht_tx_stbc = vht_cap_info & WMI_VHT_CAP_TX_STBC;
5604 
5605 	cfg->vht_rx_stbc =
5606 		(vht_cap_info & WMI_VHT_CAP_RX_STBC_1SS) |
5607 		(vht_cap_info & WMI_VHT_CAP_RX_STBC_2SS) |
5608 		(vht_cap_info & WMI_VHT_CAP_RX_STBC_3SS);
5609 
5610 	cfg->vht_max_ampdu_len_exp = (vht_cap_info &
5611 				      WMI_VHT_CAP_MAX_AMPDU_LEN_EXP)
5612 				     >> WMI_VHT_CAP_MAX_AMPDU_LEN_EXP_SHIFT;
5613 
5614 	cfg->vht_su_bformer = vht_cap_info & WMI_VHT_CAP_SU_BFORMER;
5615 
5616 	cfg->vht_su_bformee = vht_cap_info & WMI_VHT_CAP_SU_BFORMEE;
5617 
5618 	cfg->vht_mu_bformer = vht_cap_info & WMI_VHT_CAP_MU_BFORMER;
5619 
5620 	cfg->vht_mu_bformee = vht_cap_info & WMI_VHT_CAP_MU_BFORMEE;
5621 
5622 	cfg->vht_txop_ps = vht_cap_info & WMI_VHT_CAP_TXOP_PS;
5623 
5624 	wma_nofl_debug("max_mpdu %d supp_chan_width %x rx_ldpc %x\n"
5625 		 "short_gi_80 %x tx_stbc %x rx_stbc %x txop_ps %x\n"
5626 		 "su_bformee %x mu_bformee %x max_ampdu_len_exp %d",
5627 		 cfg->vht_max_mpdu, cfg->supp_chan_width, cfg->vht_rx_ldpc,
5628 		 cfg->vht_short_gi_80, cfg->vht_tx_stbc, cfg->vht_rx_stbc,
5629 		 cfg->vht_txop_ps, cfg->vht_su_bformee, cfg->vht_mu_bformee,
5630 		 cfg->vht_max_ampdu_len_exp);
5631 }
5632 
5633 /**
5634  * wma_update_supported_bands() - update supported bands from service ready ext
5635  * @supported_bands: Supported band given by FW through service ready ext params
5636  * @new_supported_bands: New supported band which needs to be updated by
5637  *			 this API which WMA layer understands
5638  *
5639  * This API will convert FW given supported band to enum which WMA layer
5640  * understands
5641  *
5642  * Return: QDF_STATUS
5643  */
wma_update_supported_bands(WLAN_BAND_CAPABILITY supported_bands,WMI_PHY_CAPABILITY * new_supported_bands)5644 static QDF_STATUS wma_update_supported_bands(
5645 			WLAN_BAND_CAPABILITY supported_bands,
5646 			WMI_PHY_CAPABILITY *new_supported_bands)
5647 {
5648 	QDF_STATUS status = QDF_STATUS_SUCCESS;
5649 
5650 	if (!new_supported_bands) {
5651 		wma_err("NULL new supported band variable");
5652 		return QDF_STATUS_E_FAILURE;
5653 	}
5654 	switch (supported_bands) {
5655 	case WLAN_2G_CAPABILITY:
5656 		*new_supported_bands |= WMI_11G_CAPABILITY;
5657 		break;
5658 	case WLAN_5G_CAPABILITY:
5659 		*new_supported_bands |= WMI_11A_CAPABILITY;
5660 		break;
5661 	default:
5662 		wma_err("wrong supported band");
5663 		status = QDF_STATUS_E_FAILURE;
5664 		break;
5665 	}
5666 	return status;
5667 }
5668 
5669 /**
5670  * wma_derive_ext_ht_cap() - Derive HT caps based on given value
5671  * @ht_cap: given pointer to HT caps which needs to be updated
5672  * @value: new HT cap info provided in form of bitmask
5673  * @tx_chain: given tx chainmask value
5674  * @rx_chain: given rx chainmask value
5675  *
5676  * This function takes the value provided in form of bitmask and decodes
5677  * it. After decoding, what ever value it gets, it takes the union(max) or
5678  * intersection(min) with previously derived values.
5679  *
5680  * Return: none
5681  *
5682  */
wma_derive_ext_ht_cap(struct wma_tgt_ht_cap * ht_cap,uint32_t value,uint32_t tx_chain,uint32_t rx_chain)5683 static void wma_derive_ext_ht_cap(
5684 			struct wma_tgt_ht_cap *ht_cap, uint32_t value,
5685 			uint32_t tx_chain, uint32_t rx_chain)
5686 {
5687 	struct wma_tgt_ht_cap tmp = {0};
5688 
5689 	if (!ht_cap)
5690 		return;
5691 
5692 	if (!qdf_mem_cmp(ht_cap, &tmp, sizeof(struct wma_tgt_ht_cap))) {
5693 		ht_cap->ht_rx_stbc = (!!(value & WMI_HT_CAP_RX_STBC));
5694 		ht_cap->ht_tx_stbc = (!!(value & WMI_HT_CAP_TX_STBC));
5695 		ht_cap->mpdu_density = (!!(value & WMI_HT_CAP_MPDU_DENSITY));
5696 		ht_cap->ht_rx_ldpc = (!!(value & WMI_HT_CAP_RX_LDPC));
5697 		ht_cap->ht_sgi_20 = (!!(value & WMI_HT_CAP_HT20_SGI));
5698 		ht_cap->ht_sgi_40 = (!!(value & WMI_HT_CAP_HT40_SGI));
5699 		ht_cap->dynamic_smps = (!!(value & WMI_HT_CAP_DYNAMIC_SMPS));
5700 		ht_cap->num_rf_chains =
5701 			QDF_MAX(wma_get_num_of_setbits_from_bitmask(tx_chain),
5702 				wma_get_num_of_setbits_from_bitmask(rx_chain));
5703 	} else {
5704 		ht_cap->ht_rx_stbc = QDF_MIN(ht_cap->ht_rx_stbc,
5705 					(!!(value & WMI_HT_CAP_RX_STBC)));
5706 		ht_cap->ht_tx_stbc = QDF_MAX(ht_cap->ht_tx_stbc,
5707 					(!!(value & WMI_HT_CAP_TX_STBC)));
5708 		ht_cap->mpdu_density = QDF_MIN(ht_cap->mpdu_density,
5709 					(!!(value & WMI_HT_CAP_MPDU_DENSITY)));
5710 		ht_cap->ht_rx_ldpc = QDF_MIN(ht_cap->ht_rx_ldpc,
5711 					(!!(value & WMI_HT_CAP_RX_LDPC)));
5712 		ht_cap->ht_sgi_20 = QDF_MIN(ht_cap->ht_sgi_20,
5713 					(!!(value & WMI_HT_CAP_HT20_SGI)));
5714 		ht_cap->ht_sgi_40 = QDF_MIN(ht_cap->ht_sgi_40,
5715 					(!!(value & WMI_HT_CAP_HT40_SGI)));
5716 		ht_cap->dynamic_smps = QDF_MIN(ht_cap->dynamic_smps,
5717 					(!!(value & WMI_HT_CAP_DYNAMIC_SMPS)));
5718 
5719 		ht_cap->num_rf_chains =
5720 			QDF_MAX(ht_cap->num_rf_chains,
5721 				QDF_MAX(wma_get_num_of_setbits_from_bitmask(
5722 								tx_chain),
5723 					wma_get_num_of_setbits_from_bitmask(
5724 								rx_chain)));
5725 	}
5726 }
5727 
5728 /**
5729  * wma_update_target_ext_ht_cap() - Update HT caps with given extended cap
5730  * @tgt_hdl: target psoc information
5731  * @ht_cap: HT cap structure to be filled
5732  *
5733  * This function loop through each hardware mode and for each hardware mode
5734  * again it loop through each MAC/PHY and pull the caps 2G and 5G specific
5735  * HT caps and derives the final cap.
5736  *
5737  * Return: none
5738  *
5739  */
wma_update_target_ext_ht_cap(struct target_psoc_info * tgt_hdl,struct wma_tgt_ht_cap * ht_cap)5740 static void wma_update_target_ext_ht_cap(struct target_psoc_info *tgt_hdl,
5741 					 struct wma_tgt_ht_cap *ht_cap)
5742 {
5743 	int i, total_mac_phy_cnt;
5744 	uint32_t ht_2g, ht_5g;
5745 	struct wma_tgt_ht_cap tmp_ht_cap = {0}, tmp_cap = {0};
5746 	struct wlan_psoc_host_mac_phy_caps *mac_phy_cap;
5747 	int num_hw_modes;
5748 
5749 	total_mac_phy_cnt = target_psoc_get_total_mac_phy_cnt(tgt_hdl);
5750 	num_hw_modes = target_psoc_get_num_hw_modes(tgt_hdl);
5751 	mac_phy_cap = target_psoc_get_mac_phy_cap(tgt_hdl);
5752 
5753 	if (!mac_phy_cap) {
5754 		wma_err("Invalid MAC PHY capabilities handle");
5755 		return;
5756 	}
5757 
5758 	/*
5759 	 * for legacy device extended cap might not even come, so in that case
5760 	 * don't overwrite legacy values
5761 	 */
5762 	if (!num_hw_modes) {
5763 		wma_debug("No extended HT cap for current SOC");
5764 		return;
5765 	}
5766 
5767 	for (i = 0; i < total_mac_phy_cnt; i++) {
5768 		ht_2g = mac_phy_cap[i].ht_cap_info_2G;
5769 		ht_5g = mac_phy_cap[i].ht_cap_info_5G;
5770 		if (ht_2g)
5771 			wma_derive_ext_ht_cap(&tmp_ht_cap,
5772 					ht_2g,
5773 					mac_phy_cap[i].tx_chain_mask_2G,
5774 					mac_phy_cap[i].rx_chain_mask_2G);
5775 		if (ht_5g)
5776 			wma_derive_ext_ht_cap(&tmp_ht_cap,
5777 					ht_5g,
5778 					mac_phy_cap[i].tx_chain_mask_5G,
5779 					mac_phy_cap[i].rx_chain_mask_5G);
5780 	}
5781 
5782 	if (qdf_mem_cmp(&tmp_cap, &tmp_ht_cap,
5783 				sizeof(struct wma_tgt_ht_cap))) {
5784 		qdf_mem_copy(ht_cap, &tmp_ht_cap,
5785 				sizeof(struct wma_tgt_ht_cap));
5786 	}
5787 
5788 	wma_nofl_debug("[ext ht cap] ht_rx_stbc - %d, ht_tx_stbc - %d\n"
5789 			"mpdu_density - %d ht_rx_ldpc - %d ht_sgi_20 - %d\n"
5790 			"ht_sgi_40 - %d num_rf_chains - %d dynamic_smps - %d",
5791 			ht_cap->ht_rx_stbc, ht_cap->ht_tx_stbc,
5792 			ht_cap->mpdu_density, ht_cap->ht_rx_ldpc,
5793 			ht_cap->ht_sgi_20, ht_cap->ht_sgi_40,
5794 			ht_cap->num_rf_chains, ht_cap->dynamic_smps);
5795 }
5796 
5797 /**
5798  * wma_derive_ext_vht_cap() - Derive VHT caps based on given value
5799  * @vht_cap: pointer to given VHT caps to be filled
5800  * @value: new VHT cap info provided in form of bitmask
5801  *
5802  * This function takes the value provided in form of bitmask and decodes
5803  * it. After decoding, what ever value it gets, it takes the union(max) or
5804  * intersection(min) with previously derived values.
5805  *
5806  * Return: none
5807  *
5808  */
wma_derive_ext_vht_cap(struct wma_tgt_vht_cap * vht_cap,uint32_t value)5809 static void wma_derive_ext_vht_cap(
5810 			struct wma_tgt_vht_cap *vht_cap, uint32_t value)
5811 {
5812 	struct wma_tgt_vht_cap tmp_cap = {0};
5813 	uint32_t tmp = 0;
5814 
5815 	if (!vht_cap)
5816 		return;
5817 
5818 	if (!qdf_mem_cmp(vht_cap, &tmp_cap,
5819 				sizeof(struct wma_tgt_vht_cap))) {
5820 		if (value & WMI_VHT_CAP_MAX_MPDU_LEN_11454)
5821 			vht_cap->vht_max_mpdu = WMI_VHT_CAP_MAX_MPDU_LEN_11454;
5822 		else if (value & WMI_VHT_CAP_MAX_MPDU_LEN_7935)
5823 			vht_cap->vht_max_mpdu = WMI_VHT_CAP_MAX_MPDU_LEN_7935;
5824 		else
5825 			vht_cap->vht_max_mpdu = 0;
5826 
5827 		if (value & WMI_VHT_CAP_CH_WIDTH_80P80_160MHZ) {
5828 			vht_cap->supp_chan_width =
5829 				1 << eHT_CHANNEL_WIDTH_80P80MHZ;
5830 			vht_cap->supp_chan_width |=
5831 				1 << eHT_CHANNEL_WIDTH_160MHZ;
5832 		} else if (value & WMI_VHT_CAP_CH_WIDTH_160MHZ) {
5833 			vht_cap->supp_chan_width =
5834 				1 << eHT_CHANNEL_WIDTH_160MHZ;
5835 		} else {
5836 			vht_cap->supp_chan_width = 1 << eHT_CHANNEL_WIDTH_80MHZ;
5837 		}
5838 		vht_cap->vht_rx_ldpc = value & WMI_VHT_CAP_RX_LDPC;
5839 		vht_cap->vht_short_gi_80 = value & WMI_VHT_CAP_SGI_80MHZ;
5840 		vht_cap->vht_short_gi_160 = value & WMI_VHT_CAP_SGI_160MHZ;
5841 		vht_cap->vht_tx_stbc = value & WMI_VHT_CAP_TX_STBC;
5842 		vht_cap->vht_rx_stbc =
5843 			(value & WMI_VHT_CAP_RX_STBC_1SS) |
5844 			(value & WMI_VHT_CAP_RX_STBC_2SS) |
5845 			(value & WMI_VHT_CAP_RX_STBC_3SS);
5846 		vht_cap->vht_max_ampdu_len_exp =
5847 			(value & WMI_VHT_CAP_MAX_AMPDU_LEN_EXP) >>
5848 				WMI_VHT_CAP_MAX_AMPDU_LEN_EXP_SHIFT;
5849 		vht_cap->vht_su_bformer = value & WMI_VHT_CAP_SU_BFORMER;
5850 		vht_cap->vht_su_bformee = value & WMI_VHT_CAP_SU_BFORMEE;
5851 		vht_cap->vht_mu_bformer = value & WMI_VHT_CAP_MU_BFORMER;
5852 		vht_cap->vht_mu_bformee = value & WMI_VHT_CAP_MU_BFORMEE;
5853 		vht_cap->vht_txop_ps = value & WMI_VHT_CAP_TXOP_PS;
5854 	} else {
5855 		if (value & WMI_VHT_CAP_MAX_MPDU_LEN_11454)
5856 			tmp = WMI_VHT_CAP_MAX_MPDU_LEN_11454;
5857 		else if (value & WMI_VHT_CAP_MAX_MPDU_LEN_7935)
5858 			tmp = WMI_VHT_CAP_MAX_MPDU_LEN_7935;
5859 		else
5860 			tmp = 0;
5861 		vht_cap->vht_max_mpdu = QDF_MIN(vht_cap->vht_max_mpdu, tmp);
5862 
5863 		if ((value & WMI_VHT_CAP_CH_WIDTH_80P80_160MHZ)) {
5864 			tmp = (1 << eHT_CHANNEL_WIDTH_80P80MHZ) |
5865 				(1 << eHT_CHANNEL_WIDTH_160MHZ);
5866 		} else if (value & WMI_VHT_CAP_CH_WIDTH_160MHZ) {
5867 			tmp = 1 << eHT_CHANNEL_WIDTH_160MHZ;
5868 		} else {
5869 			tmp = 1 << eHT_CHANNEL_WIDTH_80MHZ;
5870 		}
5871 		vht_cap->supp_chan_width =
5872 			QDF_MAX(vht_cap->supp_chan_width, tmp);
5873 		vht_cap->vht_rx_ldpc = QDF_MIN(vht_cap->vht_rx_ldpc,
5874 						value & WMI_VHT_CAP_RX_LDPC);
5875 		vht_cap->vht_short_gi_80 = QDF_MAX(vht_cap->vht_short_gi_80,
5876 						value & WMI_VHT_CAP_SGI_80MHZ);
5877 		vht_cap->vht_short_gi_160 = QDF_MAX(vht_cap->vht_short_gi_160,
5878 						value & WMI_VHT_CAP_SGI_160MHZ);
5879 		vht_cap->vht_tx_stbc = QDF_MAX(vht_cap->vht_tx_stbc,
5880 						value & WMI_VHT_CAP_TX_STBC);
5881 		vht_cap->vht_rx_stbc = QDF_MIN(vht_cap->vht_rx_stbc,
5882 					(value & WMI_VHT_CAP_RX_STBC_1SS) |
5883 					(value & WMI_VHT_CAP_RX_STBC_2SS) |
5884 					(value & WMI_VHT_CAP_RX_STBC_3SS));
5885 		vht_cap->vht_max_ampdu_len_exp =
5886 			QDF_MIN(vht_cap->vht_max_ampdu_len_exp,
5887 				(value & WMI_VHT_CAP_MAX_AMPDU_LEN_EXP) >>
5888 					WMI_VHT_CAP_MAX_AMPDU_LEN_EXP_SHIFT);
5889 		vht_cap->vht_su_bformer = QDF_MAX(vht_cap->vht_su_bformer,
5890 						value & WMI_VHT_CAP_SU_BFORMER);
5891 		vht_cap->vht_su_bformee = QDF_MAX(vht_cap->vht_su_bformee,
5892 						value & WMI_VHT_CAP_SU_BFORMEE);
5893 		vht_cap->vht_mu_bformer = QDF_MAX(vht_cap->vht_mu_bformer,
5894 						value & WMI_VHT_CAP_MU_BFORMER);
5895 		vht_cap->vht_mu_bformee = QDF_MAX(vht_cap->vht_mu_bformee,
5896 						value & WMI_VHT_CAP_MU_BFORMEE);
5897 		vht_cap->vht_txop_ps = QDF_MIN(vht_cap->vht_txop_ps,
5898 						value & WMI_VHT_CAP_TXOP_PS);
5899 	}
5900 }
5901 
5902 /**
5903  * wma_update_target_ext_vht_cap() - Update VHT caps with given extended cap
5904  * @tgt_hdl: target psoc information
5905  * @vht_cap: VHT cap structure to be filled
5906  *
5907  * This function loop through each hardware mode and for each hardware mode
5908  * again it loop through each MAC/PHY and pull the caps 2G and 5G specific
5909  * VHT caps and derives the final cap.
5910  *
5911  * Return: none
5912  *
5913  */
wma_update_target_ext_vht_cap(struct target_psoc_info * tgt_hdl,struct wma_tgt_vht_cap * vht_cap)5914 static void wma_update_target_ext_vht_cap(struct target_psoc_info *tgt_hdl,
5915 					  struct wma_tgt_vht_cap *vht_cap)
5916 {
5917 	int i, num_hw_modes, total_mac_phy_cnt;
5918 	uint32_t vht_cap_info_2g, vht_cap_info_5g;
5919 	struct wma_tgt_vht_cap tmp_vht_cap = {0}, tmp_cap = {0};
5920 	struct wlan_psoc_host_mac_phy_caps *mac_phy_cap;
5921 	uint32_t vht_mcs_10_11_supp = 0;
5922 
5923 	total_mac_phy_cnt = target_psoc_get_total_mac_phy_cnt(tgt_hdl);
5924 	num_hw_modes = target_psoc_get_num_hw_modes(tgt_hdl);
5925 
5926 	mac_phy_cap = target_psoc_get_mac_phy_cap(tgt_hdl);
5927 	if (!mac_phy_cap) {
5928 		wma_err("Invalid MAC PHY capabilities handle");
5929 		return;
5930 	}
5931 
5932 	/*
5933 	 * for legacy device extended cap might not even come, so in that case
5934 	 * don't overwrite legacy values
5935 	 */
5936 	if (!num_hw_modes) {
5937 		wma_debug("No extended VHT cap for current SOC");
5938 		return;
5939 	}
5940 
5941 	for (i = 0; i < total_mac_phy_cnt; i++) {
5942 		vht_cap_info_2g = mac_phy_cap[i].vht_cap_info_2G;
5943 		vht_cap_info_5g = mac_phy_cap[i].vht_cap_info_5G;
5944 		if (vht_cap_info_2g)
5945 			wma_derive_ext_vht_cap(&tmp_vht_cap,
5946 					vht_cap_info_2g);
5947 		if (vht_cap_info_5g)
5948 			wma_derive_ext_vht_cap(&tmp_vht_cap,
5949 					vht_cap_info_5g);
5950 		if (WMI_GET_BITS(mac_phy_cap[i].vht_supp_mcs_5G, 16, 2) &&
5951 		    WMI_VHT_MCS_NOTIFY_EXT_SS_GET(mac_phy_cap[i].
5952 			    vht_supp_mcs_5G))
5953 			vht_mcs_10_11_supp = 1;
5954 		if (WMI_GET_BITS(mac_phy_cap[i].vht_supp_mcs_2G, 16, 2) &&
5955 		    WMI_VHT_MCS_NOTIFY_EXT_SS_GET(mac_phy_cap[i].
5956 			    vht_supp_mcs_2G))
5957 			vht_mcs_10_11_supp = 1;
5958 	}
5959 
5960 	if (qdf_mem_cmp(&tmp_cap, &tmp_vht_cap,
5961 				sizeof(struct wma_tgt_vht_cap))) {
5962 			qdf_mem_copy(vht_cap, &tmp_vht_cap,
5963 					sizeof(struct wma_tgt_vht_cap));
5964 	}
5965 	vht_cap->vht_mcs_10_11_supp = vht_mcs_10_11_supp;
5966 	wma_nofl_debug("[ext vhtcap] max_mpdu %d supp_chan_width %x rx_ldpc %x\n"
5967 		"short_gi_80 %x tx_stbc %x rx_stbc %x txop_ps %x\n"
5968 		"su_bformee %x mu_bformee %x max_ampdu_len_exp %d\n"
5969 		"vht_mcs_10_11_supp %d",
5970 		vht_cap->vht_max_mpdu, vht_cap->supp_chan_width,
5971 		vht_cap->vht_rx_ldpc, vht_cap->vht_short_gi_80,
5972 		vht_cap->vht_tx_stbc, vht_cap->vht_rx_stbc,
5973 		vht_cap->vht_txop_ps, vht_cap->vht_su_bformee,
5974 		vht_cap->vht_mu_bformee, vht_cap->vht_max_ampdu_len_exp,
5975 		vht_cap->vht_mcs_10_11_supp);
5976 }
5977 
5978 static void
wma_update_sar_version(struct wlan_psoc_host_service_ext_param * param,struct wma_tgt_cfg * cfg)5979 wma_update_sar_version(struct wlan_psoc_host_service_ext_param *param,
5980 		       struct wma_tgt_cfg *cfg)
5981 {
5982 	cfg->sar_version = param ? param->sar_version : SAR_VERSION_1;
5983 }
5984 
5985 /**
5986  * wma_update_hdd_band_cap() - update band cap which hdd understands
5987  * @supported_band: supported band which has been given by FW
5988  * @tgt_cfg: target configuration to be updated
5989  * @psoc: psoc ptr
5990  *
5991  * Convert WMA given supported band to enum which HDD understands
5992  *
5993  * Return: None
5994  */
wma_update_hdd_band_cap(WMI_PHY_CAPABILITY supported_band,struct wma_tgt_cfg * tgt_cfg,struct wlan_objmgr_psoc * psoc)5995 static void wma_update_hdd_band_cap(WMI_PHY_CAPABILITY supported_band,
5996 				    struct wma_tgt_cfg *tgt_cfg,
5997 				    struct wlan_objmgr_psoc *psoc)
5998 {
5999 	switch (supported_band) {
6000 	case WMI_11G_CAPABILITY:
6001 	case WMI_11NG_CAPABILITY:
6002 		tgt_cfg->band_cap = BIT(REG_BAND_2G);
6003 		break;
6004 	case WMI_11A_CAPABILITY:
6005 	case WMI_11NA_CAPABILITY:
6006 	case WMI_11AC_CAPABILITY:
6007 		tgt_cfg->band_cap = BIT(REG_BAND_5G);
6008 		break;
6009 	case WMI_11AG_CAPABILITY:
6010 	case WMI_11NAG_CAPABILITY:
6011 	case WMI_11AX_CAPABILITY:
6012 		tgt_cfg->band_cap = (BIT(REG_BAND_2G) | BIT(REG_BAND_5G));
6013 		if (wlan_reg_is_6ghz_supported(psoc))
6014 			tgt_cfg->band_cap |= BIT(REG_BAND_6G);
6015 		break;
6016 	default:
6017 		tgt_cfg->band_cap = (BIT(REG_BAND_2G) |
6018 				     BIT(REG_BAND_5G) |
6019 				     BIT(REG_BAND_6G));
6020 	}
6021 }
6022 
6023 /**
6024  * wma_update_obss_detection_support() - update obss detection offload support
6025  * @wh: wma handle
6026  * @tgt_cfg: target configuration to be updated
6027  *
6028  * Update obss detection offload support based on service bit.
6029  *
6030  * Return: None
6031  */
wma_update_obss_detection_support(tp_wma_handle wh,struct wma_tgt_cfg * tgt_cfg)6032 static void wma_update_obss_detection_support(tp_wma_handle wh,
6033 					      struct wma_tgt_cfg *tgt_cfg)
6034 {
6035 	if (wmi_service_enabled(wh->wmi_handle,
6036 				wmi_service_ap_obss_detection_offload))
6037 		tgt_cfg->obss_detection_offloaded = true;
6038 	else
6039 		tgt_cfg->obss_detection_offloaded = false;
6040 }
6041 
6042 /**
6043  * wma_update_obss_color_collision_support() - update obss color collision
6044  *   offload support
6045  * @wh: wma handle
6046  * @tgt_cfg: target configuration to be updated
6047  *
6048  * Update obss color collision offload support based on service bit.
6049  *
6050  * Return: None
6051  */
wma_update_obss_color_collision_support(tp_wma_handle wh,struct wma_tgt_cfg * tgt_cfg)6052 static void wma_update_obss_color_collision_support(tp_wma_handle wh,
6053 						    struct wma_tgt_cfg *tgt_cfg)
6054 {
6055 	if (wmi_service_enabled(wh->wmi_handle, wmi_service_bss_color_offload))
6056 		tgt_cfg->obss_color_collision_offloaded = true;
6057 	else
6058 		tgt_cfg->obss_color_collision_offloaded = false;
6059 }
6060 
6061 /**
6062  * wma_update_restricted_80p80_bw_support() - update restricted 80+80 support
6063  * @wh: wma handle
6064  * @tgt_cfg: target configuration to be updated
6065  *
6066  * Update restricted 80+80MHz (165MHz) BW support based on service bit.
6067  *
6068  * Return: None
6069  */
wma_update_restricted_80p80_bw_support(tp_wma_handle wh,struct wma_tgt_cfg * tgt_cfg)6070 static void wma_update_restricted_80p80_bw_support(tp_wma_handle wh,
6071 						   struct wma_tgt_cfg *tgt_cfg)
6072 {
6073 	if (wmi_service_enabled(wh->wmi_handle,
6074 				wmi_service_bw_165mhz_support))
6075 		tgt_cfg->restricted_80p80_bw_supp = true;
6076 	else
6077 		tgt_cfg->restricted_80p80_bw_supp = false;
6078 }
6079 
6080 /**
6081  * wma_update_aux_dev_caps() - update aux device capability
6082  * @tgt_hdl: target psoc information
6083  * @tgt_cfg: target configuration to be updated
6084  *
6085  * Update aux device capability to wma_tgt_cfg.
6086  *
6087  * Return: None
6088  */
wma_update_aux_dev_caps(struct target_psoc_info * tgt_hdl,struct wma_tgt_cfg * tgt_cfg)6089 static void wma_update_aux_dev_caps(struct target_psoc_info *tgt_hdl,
6090 				    struct wma_tgt_cfg *tgt_cfg)
6091 {
6092 	uint8_t cap_idx;
6093 	uint32_t num_aux_dev_caps;
6094 	struct wlan_psoc_host_aux_dev_caps *aux_dev_caps;
6095 	enum wmi_host_hw_mode_config_type hw_mode_id;
6096 
6097 	num_aux_dev_caps  = tgt_hdl->info.service_ext2_param.num_aux_dev_caps;
6098 	aux_dev_caps = tgt_hdl->info.aux_dev_caps;
6099 
6100 	for (cap_idx = 0; cap_idx < num_aux_dev_caps; cap_idx++) {
6101 		/*current only support AUX0*/
6102 		if (aux_dev_caps[cap_idx].aux_index != 0)
6103 			continue;
6104 
6105 		hw_mode_id = aux_dev_caps[cap_idx].hw_mode_id;
6106 		if (hw_mode_id >= WMI_HOST_HW_MODE_MAX) {
6107 			wma_err("invalid hw mode id %d.", hw_mode_id);
6108 			continue;
6109 		}
6110 		tgt_cfg->wma_aux0_dev_caps[hw_mode_id].supported_modes_bitmap =
6111 			aux_dev_caps[cap_idx].supported_modes_bitmap;
6112 		tgt_cfg->wma_aux0_dev_caps[hw_mode_id].listen_pdev_id_map =
6113 			aux_dev_caps[cap_idx].listen_pdev_id_map;
6114 		tgt_cfg->wma_aux0_dev_caps[hw_mode_id].emlsr_pdev_id_map =
6115 			aux_dev_caps[cap_idx].emlsr_pdev_id_map;
6116 	}
6117 }
6118 
6119 #ifdef WLAN_SUPPORT_GREEN_AP
wma_green_ap_register_handlers(tp_wma_handle wma_handle)6120 static void wma_green_ap_register_handlers(tp_wma_handle wma_handle)
6121 {
6122 	if (WMI_SERVICE_IS_ENABLED(wma_handle->wmi_service_bitmap,
6123 				   WMI_SERVICE_EGAP))
6124 		target_if_green_ap_register_egap_event_handler(
6125 					wma_handle->pdev);
6126 
6127 	target_if_green_ap_register_ll_ps_event_handler(wma_handle->pdev);
6128 
6129 }
6130 #else
wma_green_ap_register_handlers(tp_wma_handle wma_handle)6131 static inline void wma_green_ap_register_handlers(tp_wma_handle wma_handle)
6132 {
6133 }
6134 #endif
6135 
6136 #ifdef WLAN_FEATURE_NAN
6137 #ifdef WLAN_FEATURE_11BE_MLO
wma_update_mlo_sta_nan_ndi_target_caps(tp_wma_handle wma_handle,struct wma_tgt_cfg * tgt_cfg)6138 static void wma_update_mlo_sta_nan_ndi_target_caps(tp_wma_handle wma_handle,
6139 						   struct wma_tgt_cfg *tgt_cfg)
6140 {
6141 	if (wmi_service_enabled(wma_handle->wmi_handle,
6142 				wmi_service_mlo_sta_nan_ndi_support))
6143 		tgt_cfg->nan_caps.mlo_sta_nan_ndi_allowed = 1;
6144 }
6145 #else
wma_update_mlo_sta_nan_ndi_target_caps(tp_wma_handle wma_handle,struct wma_tgt_cfg * tgt_cfg)6146 static void wma_update_mlo_sta_nan_ndi_target_caps(tp_wma_handle wma_handle,
6147 						   struct wma_tgt_cfg *tgt_cfg)
6148 {
6149 }
6150 #endif /* WLAN_FEATURE_11BE_MLO */
6151 
wma_update_nan_target_caps(tp_wma_handle wma_handle,struct wma_tgt_cfg * tgt_cfg)6152 static void wma_update_nan_target_caps(tp_wma_handle wma_handle,
6153 				       struct wma_tgt_cfg *tgt_cfg)
6154 {
6155 	if (wmi_service_enabled(wma_handle->wmi_handle,
6156 				wmi_service_nan_disable_support))
6157 		tgt_cfg->nan_caps.nan_conc_control = 1;
6158 
6159 	if (wmi_service_enabled(wma_handle->wmi_handle,
6160 				wmi_service_nan_dbs_support))
6161 		tgt_cfg->nan_caps.nan_dbs_supported = 1;
6162 
6163 	if (wmi_service_enabled(wma_handle->wmi_handle,
6164 				wmi_service_ndi_dbs_support))
6165 		tgt_cfg->nan_caps.ndi_dbs_supported = 1;
6166 
6167 	if (wmi_service_enabled(wma_handle->wmi_handle,
6168 				wmi_service_nan_sap_support))
6169 		tgt_cfg->nan_caps.nan_sap_supported = 1;
6170 
6171 	if (wmi_service_enabled(wma_handle->wmi_handle,
6172 				wmi_service_ndi_sap_support))
6173 		tgt_cfg->nan_caps.ndi_sap_supported = 1;
6174 
6175 	if (wmi_service_enabled(wma_handle->wmi_handle, wmi_service_nan_vdev))
6176 		tgt_cfg->nan_caps.nan_vdev_allowed = 1;
6177 
6178 	if (wmi_service_enabled(wma_handle->wmi_handle,
6179 				wmi_service_sta_nan_ndi_four_port))
6180 		tgt_cfg->nan_caps.sta_nan_ndi_ndi_allowed = 1;
6181 
6182 	if (wmi_service_enabled(wma_handle->wmi_handle,
6183 				wmi_service_ndi_txbf_support))
6184 		tgt_cfg->nan_caps.ndi_txbf_supported = 1;
6185 
6186 	wma_update_mlo_sta_nan_ndi_target_caps(wma_handle, tgt_cfg);
6187 }
6188 #else
wma_update_nan_target_caps(tp_wma_handle wma_handle,struct wma_tgt_cfg * tgt_cfg)6189 static void wma_update_nan_target_caps(tp_wma_handle wma_handle,
6190 				       struct wma_tgt_cfg *tgt_cfg)
6191 {
6192 }
6193 #endif
6194 
6195 static uint8_t
wma_convert_chainmask_to_chain(uint8_t chainmask)6196 wma_convert_chainmask_to_chain(uint8_t chainmask)
6197 {
6198 	uint8_t num_chains = 0;
6199 
6200 	while (chainmask) {
6201 		chainmask &= (chainmask - 1);
6202 		num_chains++;
6203 	}
6204 
6205 	return num_chains;
6206 }
6207 
6208 static void
wma_fill_chain_cfg(struct target_psoc_info * tgt_hdl,uint8_t phy)6209 wma_fill_chain_cfg(struct target_psoc_info *tgt_hdl,
6210 		   uint8_t phy)
6211 {
6212 	struct mac_context *mac_ctx;
6213 	uint8_t num_chain;
6214 	struct wlan_psoc_host_mac_phy_caps *mac_phy_cap =
6215 						tgt_hdl->info.mac_phy_cap;
6216 
6217 	mac_ctx = cds_get_context(QDF_MODULE_ID_PE);
6218 	if (!mac_ctx) {
6219 		wma_err("fill chain cfg failed as mac_ctx is NULL");
6220 		return;
6221 	}
6222 
6223 	num_chain = wma_convert_chainmask_to_chain(mac_phy_cap[phy].
6224 						   tx_chain_mask_2G);
6225 
6226 	if (num_chain > mac_ctx->fw_chain_cfg.max_tx_chains_2g)
6227 		mac_ctx->fw_chain_cfg.max_tx_chains_2g = num_chain;
6228 
6229 	num_chain = wma_convert_chainmask_to_chain(mac_phy_cap[phy].
6230 						   tx_chain_mask_5G);
6231 
6232 	if (num_chain > mac_ctx->fw_chain_cfg.max_tx_chains_5g)
6233 		mac_ctx->fw_chain_cfg.max_tx_chains_5g = num_chain;
6234 
6235 	num_chain = wma_convert_chainmask_to_chain(mac_phy_cap[phy].
6236 						   rx_chain_mask_2G);
6237 
6238 	if (num_chain > mac_ctx->fw_chain_cfg.max_rx_chains_2g)
6239 		mac_ctx->fw_chain_cfg.max_rx_chains_2g = num_chain;
6240 
6241 	num_chain = wma_convert_chainmask_to_chain(mac_phy_cap[phy].
6242 						   rx_chain_mask_5G);
6243 
6244 	if (num_chain > mac_ctx->fw_chain_cfg.max_rx_chains_5g)
6245 		mac_ctx->fw_chain_cfg.max_rx_chains_5g = num_chain;
6246 }
6247 
wma_update_mlme_related_tgt_caps(struct wlan_objmgr_psoc * psoc,struct wmi_unified * wmi_handle)6248 static void wma_update_mlme_related_tgt_caps(struct wlan_objmgr_psoc *psoc,
6249 					     struct wmi_unified *wmi_handle)
6250 {
6251 	struct mlme_tgt_caps mlme_tgt_cfg;
6252 
6253 	mlme_tgt_cfg.data_stall_recovery_fw_support =
6254 		wmi_service_enabled(wmi_handle,
6255 				    wmi_service_data_stall_recovery_support);
6256 
6257 	mlme_tgt_cfg.bigtk_support =
6258 		wmi_service_enabled(wmi_handle, wmi_beacon_protection_support);
6259 
6260 	mlme_tgt_cfg.stop_all_host_scan_support =
6261 		wmi_service_enabled(wmi_handle,
6262 				    wmi_service_host_scan_stop_vdev_all);
6263 	mlme_tgt_cfg.dual_sta_roam_fw_support =
6264 		wmi_service_enabled(wmi_handle,
6265 				    wmi_service_dual_sta_roam_support);
6266 
6267 	mlme_tgt_cfg.ocv_support =
6268 		wmi_service_enabled(wmi_handle,
6269 				    wmi_service_ocv_support);
6270 
6271 	wma_debug("beacon protection support %d, ocv support %d",
6272 		  mlme_tgt_cfg.bigtk_support, mlme_tgt_cfg.ocv_support);
6273 
6274 	/* Call this at last only after filling all the tgt caps */
6275 	wlan_mlme_update_cfg_with_tgt_caps(psoc, &mlme_tgt_cfg);
6276 }
6277 
6278 /**
6279  * wma_update_mlme_aux_dev_caps() - update aux device capability to mlme
6280  * @psoc: psoc handle
6281  * @tgt_hdl: target psoc information
6282  *
6283  * Update aux device capability to mlme.
6284  *
6285  * Return: None
6286  */
wma_update_mlme_aux_dev_caps(struct wlan_objmgr_psoc * psoc,struct target_psoc_info * tgt_hdl)6287 static void wma_update_mlme_aux_dev_caps(struct wlan_objmgr_psoc *psoc,
6288 					 struct target_psoc_info *tgt_hdl)
6289 {
6290 	uint8_t cap_idx;
6291 	uint32_t num_aux_dev_caps;
6292 	struct wlan_psoc_host_aux_dev_caps *aux_dev_caps;
6293 	enum wmi_host_hw_mode_config_type hw_mode_id;
6294 	struct wlan_mlme_aux_dev_caps
6295 		wlan_mlme_aux0_dev_caps[WLAN_MLME_HW_MODE_MAX] = {0};
6296 
6297 	if (WMI_HOST_HW_MODE_MAX != WLAN_MLME_HW_MODE_MAX)
6298 		wma_err("struct define mismatch, pls fix it.");
6299 
6300 	num_aux_dev_caps =
6301 		tgt_hdl->info.service_ext2_param.num_aux_dev_caps;
6302 	aux_dev_caps = tgt_hdl->info.aux_dev_caps;
6303 
6304 	for (cap_idx = 0; cap_idx < num_aux_dev_caps; cap_idx++) {
6305 		/*current only support AUX0*/
6306 		if (aux_dev_caps[cap_idx].aux_index != 0)
6307 			continue;
6308 
6309 		hw_mode_id = aux_dev_caps[cap_idx].hw_mode_id;
6310 		if (hw_mode_id >= WMI_HOST_HW_MODE_MAX) {
6311 			wma_err("invalid hw mode id %d.", hw_mode_id);
6312 			continue;
6313 		}
6314 		wlan_mlme_aux0_dev_caps[hw_mode_id].supported_modes_bitmap =
6315 				aux_dev_caps[cap_idx].supported_modes_bitmap;
6316 		wlan_mlme_aux0_dev_caps[hw_mode_id].listen_pdev_id_map =
6317 				aux_dev_caps[cap_idx].listen_pdev_id_map;
6318 		wlan_mlme_aux0_dev_caps[hw_mode_id].emlsr_pdev_id_map =
6319 				aux_dev_caps[cap_idx].emlsr_pdev_id_map;
6320 	}
6321 
6322 	wlan_mlme_update_aux_dev_caps(psoc, wlan_mlme_aux0_dev_caps);
6323 }
6324 
6325 static bool
wma_is_dbs_mandatory(struct wlan_objmgr_psoc * psoc,struct target_psoc_info * tgt_hdl)6326 wma_is_dbs_mandatory(struct wlan_objmgr_psoc *psoc,
6327 		     struct target_psoc_info *tgt_hdl)
6328 {
6329 	uint8_t i, total_mac_phy_cnt;
6330 	struct wlan_psoc_host_mac_phy_caps *mac_cap, *mac_phy_cap;
6331 	uint8_t supported_band = 0;
6332 
6333 	if (!policy_mgr_find_if_fw_supports_dbs(psoc) ||
6334 	    !policy_mgr_find_if_hwlist_has_dbs(psoc)) {
6335 		wma_debug("DBS is not mandatory");
6336 		return false;
6337 	}
6338 
6339 	total_mac_phy_cnt = target_psoc_get_total_mac_phy_cnt(tgt_hdl);
6340 	mac_phy_cap = target_psoc_get_mac_phy_cap(tgt_hdl);
6341 	if (!mac_phy_cap) {
6342 		wma_err("Invalid MAC PHY capabilities handle");
6343 		return false;
6344 	}
6345 
6346 
6347 	for (i = 0; i < total_mac_phy_cnt; i++) {
6348 		mac_cap = &mac_phy_cap[i];
6349 		if (mac_cap && (mac_cap->phy_id == 0))
6350 			supported_band |= mac_cap->supported_bands;
6351 	}
6352 
6353 	/* If Mac0 supports both the bands then DBS is not mandatory */
6354 	if (supported_band & WLAN_2G_CAPABILITY &&
6355 	    supported_band & WLAN_5G_CAPABILITY) {
6356 		wma_debug("Mac0 supports both bands DBS is optional");
6357 		return false;
6358 	}
6359 
6360 	wma_info("MAC0 does not support both bands %d DBS is mandatory",
6361 		 supported_band);
6362 
6363 	return true;
6364 }
6365 
6366 /**
6367  * wma_update_hdd_cfg() - update HDD config
6368  * @wma_handle: wma handle
6369  *
6370  * Return: Zero on success err number on failure
6371  */
wma_update_hdd_cfg(tp_wma_handle wma_handle)6372 static int wma_update_hdd_cfg(tp_wma_handle wma_handle)
6373 {
6374 	struct wma_tgt_cfg tgt_cfg;
6375 	void *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
6376 	target_resource_config *wlan_res_cfg;
6377 	struct wlan_psoc_host_service_ext_param *service_ext_param;
6378 	struct target_psoc_info *tgt_hdl;
6379 	struct wmi_unified *wmi_handle;
6380 	uint8_t i;
6381 	int ret;
6382 
6383 	wma_debug("Enter");
6384 
6385 	tgt_hdl = wlan_psoc_get_tgt_if_handle(wma_handle->psoc);
6386 	if (!tgt_hdl) {
6387 		wma_err("target psoc info is NULL");
6388 		return -EINVAL;
6389 	}
6390 
6391 	wlan_res_cfg = target_psoc_get_wlan_res_cfg(tgt_hdl);
6392 	if (!wlan_res_cfg) {
6393 		wma_err("wlan_res_cfg is null");
6394 		return -EINVAL;
6395 	}
6396 
6397 	service_ext_param =
6398 			target_psoc_get_service_ext_param(tgt_hdl);
6399 	wmi_handle = get_wmi_unified_hdl_from_psoc(wma_handle->psoc);
6400 	if (wmi_validate_handle(wmi_handle))
6401 		return -EINVAL;
6402 
6403 	wma_update_mlme_related_tgt_caps(wma_handle->psoc, wmi_handle);
6404 	wma_update_mlme_aux_dev_caps(wma_handle->psoc, tgt_hdl);
6405 
6406 	if (wmi_service_enabled(wmi_handle, wmi_service_peer_create_conf))
6407 		wlan_psoc_nif_fw_ext_cap_set(wma_handle->psoc,
6408 					     WLAN_SOC_F_PEER_CREATE_RESP);
6409 
6410 	qdf_mem_zero(&tgt_cfg, sizeof(struct wma_tgt_cfg));
6411 
6412 	tgt_cfg.sub_20_support = wma_handle->sub_20_support;
6413 	tgt_cfg.reg_domain = wma_handle->reg_cap.eeprom_rd;
6414 	tgt_cfg.eeprom_rd_ext = wma_handle->reg_cap.eeprom_rd_ext;
6415 
6416 	tgt_cfg.max_intf_count = wlan_res_cfg->num_vdevs;
6417 	policy_mgr_set_max_conc_cxns(wma_handle->psoc,
6418 				     wlan_res_cfg->num_max_active_vdevs);
6419 
6420 	qdf_mem_copy(tgt_cfg.hw_macaddr.bytes, wma_handle->hwaddr,
6421 		     ATH_MAC_LEN);
6422 
6423 	wma_update_target_services(wmi_handle, &tgt_cfg.services);
6424 	wma_update_target_ht_cap(tgt_hdl, &tgt_cfg.ht_cap);
6425 	wma_update_target_vht_cap(tgt_hdl, &tgt_cfg.vht_cap);
6426 	/*
6427 	 * This will overwrite the structure filled by wma_update_target_ht_cap
6428 	 * and wma_update_target_vht_cap APIs.
6429 	 */
6430 	wma_update_target_ext_ht_cap(tgt_hdl, &tgt_cfg.ht_cap);
6431 	wma_update_target_ext_vht_cap(tgt_hdl, &tgt_cfg.vht_cap);
6432 
6433 	wma_update_target_ext_he_cap(tgt_hdl, &tgt_cfg);
6434 	wma_update_target_ext_eht_cap(tgt_hdl, &tgt_cfg);
6435 
6436 	tgt_cfg.target_fw_version = target_if_get_fw_version(tgt_hdl);
6437 	if (service_ext_param)
6438 		tgt_cfg.target_fw_vers_ext =
6439 				service_ext_param->fw_build_vers_ext;
6440 
6441 	tgt_cfg.hw_bd_id = wma_handle->hw_bd_id;
6442 	tgt_cfg.hw_bd_info.bdf_version = wma_handle->hw_bd_info[BDF_VERSION];
6443 	tgt_cfg.hw_bd_info.ref_design_id =
6444 		wma_handle->hw_bd_info[REF_DESIGN_ID];
6445 	tgt_cfg.hw_bd_info.customer_id = wma_handle->hw_bd_info[CUSTOMER_ID];
6446 	tgt_cfg.hw_bd_info.project_id = wma_handle->hw_bd_info[PROJECT_ID];
6447 	tgt_cfg.hw_bd_info.board_data_rev =
6448 		wma_handle->hw_bd_info[BOARD_DATA_REV];
6449 
6450 #ifdef WLAN_FEATURE_LPSS
6451 	tgt_cfg.lpss_support = wma_handle->lpss_support;
6452 #endif /* WLAN_FEATURE_LPSS */
6453 	tgt_cfg.ap_arpns_support = wma_handle->ap_arpns_support;
6454 	tgt_cfg.dfs_cac_offload = wma_handle->is_dfs_offloaded;
6455 	tgt_cfg.rcpi_enabled = wma_handle->rcpi_enabled;
6456 	wma_update_hdd_band_cap(target_if_get_phy_capability(tgt_hdl),
6457 				&tgt_cfg, wma_handle->psoc);
6458 	wma_update_sar_version(service_ext_param, &tgt_cfg);
6459 	tgt_cfg.fine_time_measurement_cap =
6460 		target_if_get_wmi_fw_sub_feat_caps(tgt_hdl);
6461 	tgt_cfg.wmi_max_len = wmi_get_max_msg_len(wma_handle->wmi_handle)
6462 			      - WMI_TLV_HEADROOM;
6463 	tgt_cfg.tx_bfee_8ss_enabled = wma_handle->tx_bfee_8ss_enabled;
6464 	tgt_cfg.dynamic_nss_chains_support =
6465 				wma_handle->dynamic_nss_chains_support;
6466 	wma_update_obss_detection_support(wma_handle, &tgt_cfg);
6467 	wma_update_obss_color_collision_support(wma_handle, &tgt_cfg);
6468 	wma_update_hdd_cfg_ndp(wma_handle, &tgt_cfg);
6469 	wma_update_nan_target_caps(wma_handle, &tgt_cfg);
6470 	wma_update_bcast_twt_support(wma_handle, &tgt_cfg);
6471 	wma_update_twt_tgt_cap(wma_handle, &tgt_cfg);
6472 	wma_update_restricted_80p80_bw_support(wma_handle, &tgt_cfg);
6473 	wma_update_aux_dev_caps(tgt_hdl, &tgt_cfg);
6474 	/* Take the max of chains supported by FW, which will limit nss */
6475 	for (i = 0; i < tgt_hdl->info.total_mac_phy_cnt; i++)
6476 		wma_fill_chain_cfg(tgt_hdl, i);
6477 
6478 	ret = wma_handle->tgt_cfg_update_cb(hdd_ctx, &tgt_cfg);
6479 	if (ret)
6480 		return -EINVAL;
6481 
6482 	wma_green_ap_register_handlers(wma_handle);
6483 
6484 	return ret;
6485 }
6486 
6487 /**
6488  * wma_init_scan_fw_mode_config() - Initialize scan/fw mode config
6489  * @psoc: Object manager psoc
6490  * @scan_config: Scam mode configuration
6491  * @fw_config: FW mode configuration
6492  *
6493  * Enables all the valid bits of concurrent_scan_config_bits and
6494  * fw_mode_config_bits.
6495  *
6496  * Return: None
6497  */
wma_init_scan_fw_mode_config(struct wlan_objmgr_psoc * psoc,uint32_t scan_config,uint32_t fw_config)6498 static void wma_init_scan_fw_mode_config(struct wlan_objmgr_psoc *psoc,
6499 					 uint32_t scan_config,
6500 					 uint32_t fw_config)
6501 {
6502 	wma_debug("Enter");
6503 
6504 	if (!psoc) {
6505 		wma_err("obj psoc is NULL");
6506 		return;
6507 	}
6508 
6509 	policy_mgr_init_dbs_config(psoc, scan_config, fw_config);
6510 	policy_mgr_init_sbs_fw_config(psoc, fw_config);
6511 
6512 	wma_debug("Exit");
6513 }
6514 
wma_set_pmo_caps(struct wlan_objmgr_psoc * psoc)6515 static void wma_set_pmo_caps(struct wlan_objmgr_psoc *psoc)
6516 {
6517 	QDF_STATUS status;
6518 	tp_wma_handle wma;
6519 	struct pmo_device_caps caps;
6520 
6521 	wma = cds_get_context(QDF_MODULE_ID_WMA);
6522 	if (!wma)
6523 		return;
6524 
6525 	caps.arp_ns_offload =
6526 		wmi_service_enabled(wma->wmi_handle, wmi_service_arpns_offload);
6527 	caps.apf =
6528 		wmi_service_enabled(wma->wmi_handle, wmi_service_apf_offload);
6529 	caps.packet_filter =
6530 		wmi_service_enabled(wma->wmi_handle,
6531 				    wmi_service_packet_filter_offload);
6532 	caps.unified_wow =
6533 		wmi_service_enabled(wma->wmi_handle,
6534 				    wmi_service_unified_wow_capability);
6535 	caps.li_offload =
6536 		wmi_service_enabled(wma->wmi_handle,
6537 				    wmi_service_listen_interval_offload_support
6538 				    );
6539 
6540 	status = ucfg_pmo_psoc_set_caps(psoc, &caps);
6541 	if (QDF_IS_STATUS_ERROR(status))
6542 		wma_err("Failed to set PMO capabilities; status:%d", status);
6543 }
6544 
6545 /**
6546  * wma_set_mlme_caps() - Populate the MLME related target capabilities to the
6547  * mlme component
6548  * @psoc: Pointer to psoc object
6549  *
6550  * Return: None
6551  */
wma_set_mlme_caps(struct wlan_objmgr_psoc * psoc)6552 static void wma_set_mlme_caps(struct wlan_objmgr_psoc *psoc)
6553 {
6554 	tp_wma_handle wma;
6555 	bool tgt_cap;
6556 	uint32_t akm_bitmap = 0;
6557 	QDF_STATUS status;
6558 
6559 	wma = cds_get_context(QDF_MODULE_ID_WMA);
6560 	if (!wma)
6561 		return;
6562 
6563 	tgt_cap = wmi_service_enabled(wma->wmi_handle,
6564 				      wmi_service_adaptive_11r_support);
6565 
6566 	status = ucfg_mlme_set_tgt_adaptive_11r_cap(psoc, tgt_cap);
6567 	if (QDF_IS_STATUS_ERROR(status))
6568 		wma_err("Failed to set adaptive 11r cap");
6569 
6570 	tgt_cap = wmi_service_enabled(wma->wmi_handle,
6571 				      wmi_service_wpa3_ft_sae_support);
6572 	if (tgt_cap)
6573 		 akm_bitmap |= (1 << AKM_FT_SAE);
6574 
6575 	tgt_cap = wmi_service_enabled(wma->wmi_handle,
6576 				      wmi_service_wpa3_ft_suite_b_support);
6577 	if (tgt_cap)
6578 		akm_bitmap |= (1 << AKM_FT_SUITEB_SHA384);
6579 
6580 	tgt_cap = wmi_service_enabled(wma->wmi_handle,
6581 				      wmi_service_ft_fils);
6582 	if (tgt_cap)
6583 		akm_bitmap |= (1 << AKM_FT_FILS);
6584 
6585 	tgt_cap = wmi_service_enabled(wma->wmi_handle,
6586 				      wmi_service_owe_roam_support);
6587 	if (tgt_cap)
6588 		akm_bitmap |= (1 << AKM_OWE);
6589 
6590 	tgt_cap = wmi_service_enabled(wma->wmi_handle,
6591 				      wmi_service_sae_roam_support);
6592 	if (tgt_cap)
6593 		akm_bitmap |= (1 << AKM_SAE);
6594 
6595 	tgt_cap = wmi_service_enabled(wma->wmi_handle,
6596 				      wmi_service_suiteb_roam_support);
6597 	if (tgt_cap)
6598 		akm_bitmap |= (1 << AKM_SUITEB);
6599 
6600 	tgt_cap = wmi_service_enabled(wma->wmi_handle,
6601 				      wmi_service_wpa3_sha384_roam_support);
6602 	if (tgt_cap)
6603 		akm_bitmap |= (1 << AKM_SAE_EXT);
6604 
6605 	status = mlme_set_tgt_wpa3_roam_cap(psoc, akm_bitmap);
6606 	if (QDF_IS_STATUS_ERROR(status))
6607 		wma_err("Failed to set sae roam support");
6608 }
6609 
6610 #ifdef WLAN_FEATURE_BIG_DATA_STATS
wma_is_big_data_support_enable(struct wmi_unified * wmi_handle)6611 static bool wma_is_big_data_support_enable(struct wmi_unified *wmi_handle)
6612 {
6613 	return wmi_service_enabled(wmi_handle, wmi_service_big_data_support);
6614 }
6615 #else
wma_is_big_data_support_enable(struct wmi_unified * wmi_handle)6616 static bool wma_is_big_data_support_enable(struct wmi_unified *wmi_handle)
6617 {
6618 	return false;
6619 }
6620 #endif
6621 
6622 /**
6623  * wma_set_mc_cp_caps() - Populate mc cp component related capabilities
6624  *			  to the mc cp component
6625  *
6626  * @psoc: Pointer to psoc object
6627  *
6628  * Return: None
6629  */
wma_set_mc_cp_caps(struct wlan_objmgr_psoc * psoc)6630 static void wma_set_mc_cp_caps(struct wlan_objmgr_psoc *psoc)
6631 {
6632 	tp_wma_handle wma;
6633 
6634 	wma = cds_get_context(QDF_MODULE_ID_WMA);
6635 	if (!wma)
6636 		return;
6637 
6638 	if (wma_is_big_data_support_enable(wma->wmi_handle))
6639 		ucfg_mc_cp_set_big_data_fw_support(psoc, true);
6640 	else
6641 		ucfg_mc_cp_set_big_data_fw_support(psoc, false);
6642 }
6643 
6644 #ifdef THERMAL_STATS_SUPPORT
wma_set_thermal_stats_fw_cap(tp_wma_handle wma,struct wlan_fwol_capability_info * cap)6645 static void wma_set_thermal_stats_fw_cap(tp_wma_handle wma,
6646 					 struct wlan_fwol_capability_info *cap)
6647 {
6648 	cap->fw_thermal_stats_cap = wmi_service_enabled(wma->wmi_handle,
6649 				wmi_service_thermal_stats_temp_range_supported);
6650 }
6651 #else
wma_set_thermal_stats_fw_cap(tp_wma_handle wma,struct wlan_fwol_capability_info * cap)6652 static void wma_set_thermal_stats_fw_cap(tp_wma_handle wma,
6653 					 struct wlan_fwol_capability_info *cap)
6654 {
6655 }
6656 #endif
6657 
6658 /**
6659  * wma_set_fwol_caps() - Populate fwol component related capabilities
6660  *			 to the fwol component
6661  *
6662  * @psoc: Pointer to psoc object
6663  *
6664  * Return: None
6665  */
wma_set_fwol_caps(struct wlan_objmgr_psoc * psoc)6666 static void wma_set_fwol_caps(struct wlan_objmgr_psoc *psoc)
6667 {
6668 	tp_wma_handle wma;
6669 	struct wlan_fwol_capability_info cap_info;
6670 	wma = cds_get_context(QDF_MODULE_ID_WMA);
6671 
6672 	if (!wma) {
6673 		wma_err_rl("wma Null");
6674 		return;
6675 	}
6676 	if (!psoc) {
6677 		wma_err_rl("psoc Null");
6678 		return;
6679 	}
6680 
6681 	wma_set_thermal_stats_fw_cap(wma, &cap_info);
6682 	ucfg_fwol_update_fw_cap_info(psoc, &cap_info);
6683 }
wma_set_component_caps(struct wlan_objmgr_psoc * psoc)6684 static void wma_set_component_caps(struct wlan_objmgr_psoc *psoc)
6685 {
6686 	wma_set_pmo_caps(psoc);
6687 	wma_set_mlme_caps(psoc);
6688 	wma_set_mc_cp_caps(psoc);
6689 	wma_set_fwol_caps(psoc);
6690 }
6691 
6692 #if defined(WLAN_FEATURE_GTK_OFFLOAD) && defined(WLAN_POWER_MANAGEMENT_OFFLOAD)
wma_register_gtk_offload_event(tp_wma_handle wma_handle)6693 static QDF_STATUS wma_register_gtk_offload_event(tp_wma_handle wma_handle)
6694 {
6695 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
6696 
6697 	if (wma_validate_handle(wma_handle))
6698 		return QDF_STATUS_E_FAILURE;
6699 
6700 	if (wmi_service_enabled(wma_handle->wmi_handle,
6701 				wmi_service_gtk_offload)) {
6702 		status = wmi_unified_register_event_handler(
6703 					wma_handle->wmi_handle,
6704 					wmi_gtk_offload_status_event_id,
6705 					target_if_pmo_gtk_offload_status_event,
6706 					WMA_RX_WORK_CTX);
6707 	}
6708 	return status;
6709 }
6710 #else
wma_register_gtk_offload_event(tp_wma_handle wma_handle)6711 static QDF_STATUS wma_register_gtk_offload_event(tp_wma_handle wma_handle)
6712 {
6713 	return QDF_STATUS_SUCCESS;
6714 }
6715 #endif /* WLAN_FEATURE_GTK_OFFLOAD && WLAN_POWER_MANAGEMENT_OFFLOAD */
6716 
6717 /**
6718  * wma_rx_service_ready_event() - event handler to process
6719  *                                wmi rx service ready event.
6720  * @handle: wma handle
6721  * @cmd_param_info: command params info
6722  * @length: param length
6723  *
6724  * Return: none
6725  */
wma_rx_service_ready_event(void * handle,uint8_t * cmd_param_info,uint32_t length)6726 int wma_rx_service_ready_event(void *handle, uint8_t *cmd_param_info,
6727 			       uint32_t length)
6728 {
6729 	tp_wma_handle wma_handle = (tp_wma_handle) handle;
6730 	WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf;
6731 	wmi_service_ready_event_fixed_param *ev;
6732 	QDF_STATUS status;
6733 	uint32_t *ev_wlan_dbs_hw_mode_list;
6734 	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
6735 	struct target_psoc_info *tgt_hdl;
6736 	struct wlan_psoc_target_capability_info *tgt_cap_info;
6737 	target_resource_config *wlan_res_cfg;
6738 	struct wmi_unified *wmi_handle;
6739 	uint32_t *service_bitmap;
6740 
6741 	wma_debug("Enter");
6742 
6743 	if (wma_validate_handle(wma_handle))
6744 		return -EINVAL;
6745 
6746 	tgt_hdl = wlan_psoc_get_tgt_if_handle(wma_handle->psoc);
6747 	if (!tgt_hdl) {
6748 		wma_err("target psoc info is NULL");
6749 		return -EINVAL;
6750 	}
6751 
6752 	wlan_res_cfg = target_psoc_get_wlan_res_cfg(tgt_hdl);
6753 	tgt_cap_info = target_psoc_get_target_caps(tgt_hdl);
6754 	service_bitmap = target_psoc_get_service_bitmap(tgt_hdl);
6755 
6756 	param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) cmd_param_info;
6757 	if (!param_buf) {
6758 		wma_err("Invalid arguments");
6759 		return -EINVAL;
6760 	}
6761 
6762 	ev = param_buf->fixed_param;
6763 	if (!ev) {
6764 		wma_err("Invalid buffer");
6765 		return -EINVAL;
6766 	}
6767 
6768 	wmi_handle = get_wmi_unified_hdl_from_psoc(wma_handle->psoc);
6769 	if (wmi_validate_handle(wmi_handle))
6770 		return -EINVAL;
6771 
6772 	wma_debug("WMA <-- WMI_SERVICE_READY_EVENTID");
6773 
6774 	if (ev->num_dbs_hw_modes > param_buf->num_wlan_dbs_hw_mode_list) {
6775 		wma_err("FW dbs_hw_mode entry %d more than value %d in TLV hdr",
6776 			ev->num_dbs_hw_modes,
6777 			param_buf->num_wlan_dbs_hw_mode_list);
6778 		return -EINVAL;
6779 	}
6780 
6781 	ev_wlan_dbs_hw_mode_list = param_buf->wlan_dbs_hw_mode_list;
6782 
6783 	/* Continuing with the rest of the processing,
6784 	 * even if memory allocation fails
6785 	 */
6786 	policy_mgr_init_dbs_hw_mode(wma_handle->psoc, ev->num_dbs_hw_modes,
6787 				    ev_wlan_dbs_hw_mode_list);
6788 
6789 	/* Initializes the fw_mode and scan_config to zero.
6790 	 * If ext service ready event is present it will set
6791 	 * the actual values of these two params.
6792 	 * This is to ensure that no garbage values would be
6793 	 * present in the absence of ext service ready event.
6794 	 */
6795 	wma_init_scan_fw_mode_config(wma_handle->psoc, 0, 0);
6796 
6797 	qdf_mem_copy(&wma_handle->reg_cap, param_buf->hal_reg_capabilities,
6798 				 sizeof(HAL_REG_CAPABILITIES));
6799 
6800 	wma_handle->vht_supp_mcs = ev->vht_supp_mcs;
6801 
6802 	wma_handle->new_hw_mode_index = tgt_cap_info->default_dbs_hw_mode_index;
6803 	policy_mgr_update_new_hw_mode_index(wma_handle->psoc,
6804 	tgt_cap_info->default_dbs_hw_mode_index);
6805 
6806 	wma_debug("Firmware default hw mode index : %d",
6807 		 tgt_cap_info->default_dbs_hw_mode_index);
6808 	wma_info("Firmware build version : %08x",
6809 		 ev->fw_build_vers);
6810 	wma_debug("FW fine time meas cap: 0x%x",
6811 		 tgt_cap_info->wmi_fw_sub_feat_caps);
6812 
6813 	wma_handle->hw_bd_id = ev->hw_bd_id;
6814 
6815 	wma_handle->hw_bd_info[BDF_VERSION] =
6816 		WMI_GET_BDF_VERSION(ev->hw_bd_info);
6817 	wma_handle->hw_bd_info[REF_DESIGN_ID] =
6818 		WMI_GET_REF_DESIGN(ev->hw_bd_info);
6819 	wma_handle->hw_bd_info[CUSTOMER_ID] =
6820 		WMI_GET_CUSTOMER_ID(ev->hw_bd_info);
6821 	wma_handle->hw_bd_info[PROJECT_ID] =
6822 		WMI_GET_PROJECT_ID(ev->hw_bd_info);
6823 	wma_handle->hw_bd_info[BOARD_DATA_REV] =
6824 		WMI_GET_BOARD_DATA_REV(ev->hw_bd_info);
6825 
6826 	wma_info("Board id: %x, Board version: %x %x %x %x %x",
6827 		 wma_handle->hw_bd_id,
6828 		 wma_handle->hw_bd_info[BDF_VERSION],
6829 		 wma_handle->hw_bd_info[REF_DESIGN_ID],
6830 		 wma_handle->hw_bd_info[CUSTOMER_ID],
6831 		 wma_handle->hw_bd_info[PROJECT_ID],
6832 		 wma_handle->hw_bd_info[BOARD_DATA_REV]);
6833 
6834 	/* wmi service is ready */
6835 	qdf_mem_copy(wma_handle->wmi_service_bitmap,
6836 		     service_bitmap,
6837 		     sizeof(wma_handle->wmi_service_bitmap));
6838 
6839 	cdp_cfg_tx_set_is_mgmt_over_wmi_enabled(soc,
6840 		wmi_service_enabled(wmi_handle, wmi_service_mgmt_tx_wmi));
6841 	cdp_set_desc_global_pool_size(soc, ev->num_msdu_desc);
6842 	/* SWBA event handler for beacon transmission */
6843 	status = wma_register_swba_events(wma_handle->wmi_handle);
6844 
6845 	if (QDF_IS_STATUS_ERROR(status)) {
6846 		wma_err("Failed to register swba beacon event cb");
6847 		goto failure;
6848 	}
6849 #ifdef WLAN_FEATURE_LPSS
6850 	wma_handle->lpss_support =
6851 		wmi_service_enabled(wmi_handle, wmi_service_lpass);
6852 #endif /* WLAN_FEATURE_LPSS */
6853 
6854 	if (wmi_service_enabled(wmi_handle, wmi_service_fse_cmem_alloc_support))
6855 		wlan_dp_set_fst_in_cmem(true);
6856 
6857 	if (wmi_service_enabled(wmi_handle,
6858 			wmi_service_fisa_dynamic_msdu_aggr_size_support))
6859 		wlan_dp_set_fisa_dynamic_aggr_size_support(true);
6860 	/*
6861 	 * This Service bit is added to check for ARP/NS Offload
6862 	 * support for LL/HL targets
6863 	 */
6864 	wma_handle->ap_arpns_support =
6865 		wmi_service_enabled(wmi_handle, wmi_service_ap_arpns_offload);
6866 
6867 	if (wmi_service_enabled(wmi_handle, wmi_service_csa_offload)) {
6868 		wma_debug("FW support CSA offload capability");
6869 		status = wmi_unified_register_event_handler(
6870 						wmi_handle,
6871 						wmi_csa_handling_event_id,
6872 						wma_csa_offload_handler,
6873 						WMA_RX_SERIALIZER_CTX);
6874 		if (QDF_IS_STATUS_ERROR(status)) {
6875 			wma_err("Failed to register CSA offload event cb");
6876 			goto failure;
6877 		}
6878 	}
6879 
6880 	if (wmi_service_enabled(wmi_handle, wmi_service_mgmt_tx_wmi)) {
6881 		wma_debug("Firmware supports management TX over WMI,use WMI interface instead of HTT for management Tx");
6882 		/*
6883 		 * Register Tx completion event handler for MGMT Tx over WMI
6884 		 * case
6885 		 */
6886 		status = wmi_unified_register_event_handler(
6887 					wmi_handle,
6888 					wmi_mgmt_tx_completion_event_id,
6889 					wma_mgmt_tx_completion_handler,
6890 					WMA_RX_SERIALIZER_CTX);
6891 		if (QDF_IS_STATUS_ERROR(status)) {
6892 			wma_err("Failed to register MGMT over WMI completion handler");
6893 			goto failure;
6894 		}
6895 
6896 		status = wmi_unified_register_event_handler(
6897 				wmi_handle,
6898 				wmi_mgmt_tx_bundle_completion_event_id,
6899 				wma_mgmt_tx_bundle_completion_handler,
6900 				WMA_RX_SERIALIZER_CTX);
6901 		if (QDF_IS_STATUS_ERROR(status)) {
6902 			wma_err("Failed to register MGMT over WMI completion handler");
6903 			goto failure;
6904 		}
6905 
6906 	} else {
6907 		wma_err("FW does not support WMI_SERVICE_MGMT_TX_WMI, Use HTT interface for Management Tx");
6908 	}
6909 
6910 	status = wma_register_gtk_offload_event(wma_handle);
6911 	if (QDF_IS_STATUS_ERROR(status)) {
6912 		wma_err("Failed to register GTK offload event cb");
6913 		goto failure;
6914 	}
6915 
6916 	status = wmi_unified_register_event_handler(wmi_handle,
6917 				wmi_tbttoffset_update_event_id,
6918 				wma_tbttoffset_update_event_handler,
6919 				WMA_RX_SERIALIZER_CTX);
6920 	if (QDF_IS_STATUS_ERROR(status)) {
6921 		wma_err("Failed to register WMI_TBTTOFFSET_UPDATE_EVENTID callback");
6922 		goto failure;
6923 	}
6924 
6925 	if (wmi_service_enabled(wma_handle->wmi_handle,
6926 				   wmi_service_rcpi_support)) {
6927 		/* register for rcpi response event */
6928 		status = wmi_unified_register_event_handler(
6929 							wmi_handle,
6930 							wmi_update_rcpi_event_id,
6931 							wma_rcpi_event_handler,
6932 							WMA_RX_SERIALIZER_CTX);
6933 		if (QDF_IS_STATUS_ERROR(status)) {
6934 			wma_err("Failed to register RCPI event handler");
6935 			goto failure;
6936 		}
6937 		wma_handle->rcpi_enabled = true;
6938 	}
6939 
6940 	/* mac_id is replaced with pdev_id in converged firmware to have
6941 	 * multi-radio support. In order to maintain backward compatibility
6942 	 * with old fw, host needs to check WMI_SERVICE_DEPRECATED_REPLACE
6943 	 * in service bitmap from FW and host needs to set use_pdev_id in
6944 	 * wmi_resource_config to true. If WMI_SERVICE_DEPRECATED_REPLACE
6945 	 * service is not set, then host shall not expect MAC ID from FW in
6946 	 * VDEV START RESPONSE event and host shall use PDEV ID.
6947 	 */
6948 	if (wmi_service_enabled(wmi_handle, wmi_service_deprecated_replace))
6949 		wlan_res_cfg->use_pdev_id = true;
6950 	else
6951 		wlan_res_cfg->use_pdev_id = false;
6952 
6953 	wlan_res_cfg->max_num_dbs_scan_duty_cycle = CDS_DBS_SCAN_CLIENTS_MAX;
6954 
6955 	/* Initialize the log supported event handler */
6956 	status = wmi_unified_register_event_handler(wmi_handle,
6957 			wmi_diag_event_id_log_supported_event_id,
6958 			wma_log_supported_evt_handler,
6959 			WMA_RX_SERIALIZER_CTX);
6960 	if (QDF_IS_STATUS_ERROR(status)) {
6961 		wma_err("Failed to register log supported event cb");
6962 		goto failure;
6963 	}
6964 
6965 	cdp_mark_first_wakeup_packet(
6966 		soc, OL_TXRX_PDEV_ID,
6967 		wmi_service_enabled(wmi_handle,
6968 				    wmi_service_mark_first_wakeup_packet));
6969 	wma_handle->is_dfs_offloaded =
6970 		wmi_service_enabled(wmi_handle,
6971 				    wmi_service_dfs_phyerr_offload);
6972 
6973 	wma_handle->nan_datapath_enabled =
6974 		wmi_service_enabled(wma_handle->wmi_handle,
6975 				    wmi_service_nan_data);
6976 
6977 	wma_handle->fw_therm_throt_support =
6978 		wmi_service_enabled(wma_handle->wmi_handle,
6979 				    wmi_service_tt);
6980 
6981 	wma_set_component_caps(wma_handle->psoc);
6982 
6983 	wma_update_fw_config(wma_handle->psoc, tgt_hdl);
6984 
6985 	status = wmi_unified_save_fw_version_cmd(wmi_handle, param_buf);
6986 	if (QDF_IS_STATUS_ERROR(status)) {
6987 		wma_err("Failed to send WMI_INIT_CMDID command");
6988 		goto failure;
6989 	}
6990 
6991 	if (wmi_service_enabled(wmi_handle, wmi_service_ext_msg)) {
6992 		status = qdf_mc_timer_start(
6993 				&wma_handle->service_ready_ext_timer,
6994 				WMA_SERVICE_READY_EXT_TIMEOUT);
6995 		if (QDF_IS_STATUS_ERROR(status))
6996 			wma_err("Failed to start the service ready ext timer");
6997 	}
6998 	wma_handle->tx_bfee_8ss_enabled =
6999 		wmi_service_enabled(wmi_handle, wmi_service_8ss_tx_bfee);
7000 
7001 	wma_handle->dynamic_nss_chains_support = wmi_service_enabled(wmi_handle,
7002 					wmi_service_per_vdev_chain_support);
7003 	target_psoc_set_num_radios(tgt_hdl, 1);
7004 
7005 	return 0;
7006 
7007 failure:
7008 	return -EINVAL;
7009 
7010 }
7011 
7012 /**
7013  * wma_get_caps_for_phyidx_hwmode() - to fetch caps for given hw mode and band
7014  * @caps_per_phy: Pointer to capabilities structure which needs to be filled
7015  * @hw_mode: Provided hardware mode
7016  * @band: Provide band i.e. 2G or 5G
7017  *
7018  * This API finds cap which suitable for provided hw mode and band. If user
7019  * is provides some invalid hw mode then it will automatically falls back to
7020  * default hw mode
7021  *
7022  * Return: QDF_STATUS
7023  */
wma_get_caps_for_phyidx_hwmode(struct wma_caps_per_phy * caps_per_phy,enum hw_mode_dbs_capab hw_mode,enum cds_band_type band)7024 QDF_STATUS wma_get_caps_for_phyidx_hwmode(struct wma_caps_per_phy *caps_per_phy,
7025 		enum hw_mode_dbs_capab hw_mode, enum cds_band_type band)
7026 {
7027 	t_wma_handle *wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
7028 	struct target_psoc_info *tgt_hdl;
7029 	int ht_cap_info, vht_cap_info;
7030 	uint8_t our_hw_mode = hw_mode, num_hw_modes, hw_mode_config_type;
7031 	struct wlan_psoc_host_mac_phy_caps *mac_phy_cap;
7032 	struct wlan_psoc_target_capability_info *tgt_cap_info;
7033 	uint8_t total_mac_phy_cnt, i;
7034 
7035 	if (!wma_handle)
7036 		return QDF_STATUS_E_FAILURE;
7037 
7038 	tgt_hdl = wlan_psoc_get_tgt_if_handle(wma_handle->psoc);
7039 	if (!tgt_hdl) {
7040 		wma_err("target psoc info is NULL");
7041 		return -EINVAL;
7042 	}
7043 	if (!caps_per_phy) {
7044 		wma_err("Invalid caps pointer");
7045 		return QDF_STATUS_E_FAILURE;
7046 	}
7047 
7048 	ht_cap_info = target_if_get_ht_cap_info(tgt_hdl);
7049 	vht_cap_info = target_if_get_vht_cap_info(tgt_hdl);
7050 	num_hw_modes = target_psoc_get_num_hw_modes(tgt_hdl);
7051 	mac_phy_cap = target_psoc_get_mac_phy_cap(tgt_hdl);
7052 	tgt_cap_info = target_psoc_get_target_caps(tgt_hdl);
7053 
7054 	if (!mac_phy_cap) {
7055 		wma_err("Invalid MAC PHY capabilities handle");
7056 		return QDF_STATUS_E_FAILURE;
7057 	}
7058 
7059 	if (!tgt_cap_info) {
7060 		wma_err("Invalid target capabilities handle");
7061 		return QDF_STATUS_E_FAILURE;
7062 	}
7063 
7064 	if (!num_hw_modes) {
7065 		wma_debug("Invalid number of hw modes, use legacy HT/VHT caps");
7066 		caps_per_phy->ht_2g = ht_cap_info;
7067 		caps_per_phy->ht_5g = ht_cap_info;
7068 		caps_per_phy->vht_2g = vht_cap_info;
7069 		caps_per_phy->vht_5g = vht_cap_info;
7070 		/* legacy platform doesn't support HE IE */
7071 		caps_per_phy->he_2g[0] = 0;
7072 		caps_per_phy->he_2g[1] = 0;
7073 		caps_per_phy->he_5g[0] = 0;
7074 		caps_per_phy->he_5g[1] = 0;
7075 		caps_per_phy->tx_chain_mask_2G =
7076 			EXTRACT_TX_CHAIN_MASK_2G(tgt_cap_info->txrx_chainmask);
7077 		caps_per_phy->rx_chain_mask_2G =
7078 			EXTRACT_RX_CHAIN_MASK_2G(tgt_cap_info->txrx_chainmask);
7079 		caps_per_phy->tx_chain_mask_5G =
7080 			EXTRACT_TX_CHAIN_MASK_5G(tgt_cap_info->txrx_chainmask);
7081 		caps_per_phy->rx_chain_mask_5G =
7082 			EXTRACT_RX_CHAIN_MASK_5G(tgt_cap_info->txrx_chainmask);
7083 
7084 		return QDF_STATUS_SUCCESS;
7085 	}
7086 
7087 	if (!policy_mgr_is_dbs_enable(wma_handle->psoc))
7088 		our_hw_mode = HW_MODE_DBS_NONE;
7089 
7090 	total_mac_phy_cnt = target_psoc_get_total_mac_phy_cnt(tgt_hdl);
7091 	for (i = 0; i < total_mac_phy_cnt; i++) {
7092 		hw_mode_config_type = mac_phy_cap[i].hw_mode_config_type;
7093 		if (our_hw_mode == HW_MODE_DBS &&
7094 		    !(hw_mode_config_type == WMI_HW_MODE_DBS ||
7095 		    hw_mode_config_type == WMI_HW_MODE_DBS_OR_SBS))
7096 			continue;
7097 
7098 		if ((band == CDS_BAND_2GHZ || band == CDS_BAND_ALL) &&
7099 		    (WLAN_2G_CAPABILITY & mac_phy_cap[i].supported_bands) &&
7100 		    !caps_per_phy->tx_chain_mask_2G) {
7101 			caps_per_phy->ht_2g = mac_phy_cap[i].ht_cap_info_2G;
7102 			caps_per_phy->vht_2g = mac_phy_cap[i].vht_cap_info_2G;
7103 			qdf_mem_copy(caps_per_phy->he_2g,
7104 				     mac_phy_cap[i].he_cap_info_2G,
7105 				     sizeof(caps_per_phy->he_2g));
7106 
7107 			caps_per_phy->tx_chain_mask_2G =
7108 					mac_phy_cap[i].tx_chain_mask_2G;
7109 			caps_per_phy->rx_chain_mask_2G =
7110 					mac_phy_cap[i].rx_chain_mask_2G;
7111 
7112 			wma_debug("Select 2G capable phyid[%d] chain %d %d ht 0x%x vht 0x%x",
7113 				 i,
7114 				 caps_per_phy->tx_chain_mask_2G,
7115 				 caps_per_phy->rx_chain_mask_2G,
7116 				 caps_per_phy->ht_2g,
7117 				 caps_per_phy->vht_2g);
7118 		}
7119 		if ((band == CDS_BAND_5GHZ || band == CDS_BAND_ALL) &&
7120 		    (WLAN_5G_CAPABILITY & mac_phy_cap[i].supported_bands) &&
7121 		    !caps_per_phy->tx_chain_mask_5G) {
7122 			caps_per_phy->ht_5g = mac_phy_cap[i].ht_cap_info_5G;
7123 			caps_per_phy->vht_5g = mac_phy_cap[i].vht_cap_info_5G;
7124 			qdf_mem_copy(caps_per_phy->he_5g,
7125 				     mac_phy_cap[i].he_cap_info_5G,
7126 				     sizeof(caps_per_phy->he_5g));
7127 
7128 			caps_per_phy->tx_chain_mask_5G =
7129 					mac_phy_cap[i].tx_chain_mask_5G;
7130 			caps_per_phy->rx_chain_mask_5G =
7131 					mac_phy_cap[i].rx_chain_mask_5G;
7132 
7133 			wma_debug("Select 5G capable phyid[%d] chain %d %d ht 0x%x vht 0x%x",
7134 				 i,
7135 				 caps_per_phy->tx_chain_mask_5G,
7136 				 caps_per_phy->rx_chain_mask_5G,
7137 				 caps_per_phy->ht_5g,
7138 				 caps_per_phy->vht_5g);
7139 		}
7140 	}
7141 
7142 	return QDF_STATUS_SUCCESS;
7143 }
7144 
7145 /**
7146  * wma_is_rx_ldpc_supported_for_channel() - to find out if ldpc is supported
7147  *
7148  * @ch_freq: Channel freq for which it needs to check if rx ldpc is enabled
7149  *
7150  * This API takes channel number as argument and takes default hw mode as DBS
7151  * to check if rx LDPC support is enabled for that channel or no
7152  */
wma_is_rx_ldpc_supported_for_channel(uint32_t ch_freq)7153 bool wma_is_rx_ldpc_supported_for_channel(uint32_t ch_freq)
7154 {
7155 	t_wma_handle *wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
7156 	struct target_psoc_info *tgt_hdl;
7157 	struct wma_caps_per_phy caps_per_phy = {0};
7158 	enum cds_band_type band;
7159 	bool status;
7160 	uint8_t num_hw_modes;
7161 
7162 	if (!wma_handle)
7163 		return false;
7164 
7165 	tgt_hdl = wlan_psoc_get_tgt_if_handle(wma_handle->psoc);
7166 	if (!tgt_hdl) {
7167 		wma_err("Target handle is NULL");
7168 		return QDF_STATUS_E_FAILURE;
7169 	}
7170 
7171 	num_hw_modes = target_psoc_get_num_hw_modes(tgt_hdl);
7172 
7173 	if (!WLAN_REG_IS_24GHZ_CH_FREQ(ch_freq))
7174 		band = CDS_BAND_5GHZ;
7175 	else
7176 		band = CDS_BAND_2GHZ;
7177 
7178 	if (QDF_STATUS_SUCCESS != wma_get_caps_for_phyidx_hwmode(
7179 						&caps_per_phy,
7180 						HW_MODE_DBS, band)) {
7181 		return false;
7182 	}
7183 
7184 	/*
7185 	 * Legacy platforms like Rome set WMI_HT_CAP_LDPC to specify RX LDPC
7186 	 * capability. But new platforms like Helium set WMI_HT_CAP_RX_LDPC
7187 	 * instead.
7188 	 */
7189 	if (0 == num_hw_modes) {
7190 		status = (!!(caps_per_phy.ht_2g & WMI_HT_CAP_LDPC));
7191 	} else {
7192 		if (WLAN_REG_IS_24GHZ_CH_FREQ(ch_freq))
7193 			status = (!!(caps_per_phy.ht_2g & WMI_HT_CAP_RX_LDPC));
7194 		else
7195 			status = (!!(caps_per_phy.ht_5g & WMI_HT_CAP_RX_LDPC));
7196 	}
7197 
7198 	return status;
7199 }
7200 
7201 /**
7202  * wma_print_mac_phy_capabilities() - Prints MAC PHY capabilities
7203  * @cap: pointer to WMI_MAC_PHY_CAPABILITIES
7204  * @index: MAC_PHY index
7205  *
7206  * Return: none
7207  */
wma_print_mac_phy_capabilities(struct wlan_psoc_host_mac_phy_caps * cap,int index)7208 static void wma_print_mac_phy_capabilities(struct wlan_psoc_host_mac_phy_caps
7209 					   *cap, int index)
7210 {
7211 	uint32_t mac_2G[PSOC_HOST_MAX_MAC_SIZE];
7212 	uint32_t mac_5G[PSOC_HOST_MAX_MAC_SIZE];
7213 	uint32_t phy_2G[WMI_MAX_HECAP_PHY_SIZE];
7214 	uint32_t phy_5G[WMI_MAX_HECAP_PHY_SIZE];
7215 	struct wlan_psoc_host_ppe_threshold ppet_2G, ppet_5G;
7216 
7217 	wma_nofl_debug("\t: index [%d]", index);
7218 	wma_nofl_debug("\t: cap for hw_mode_id[%d]", cap->hw_mode_id);
7219 	wma_nofl_debug("\t: pdev_id[%d]", cap->pdev_id);
7220 	wma_nofl_debug("\t: phy_id[%d]", cap->phy_id);
7221 	wma_nofl_debug("\t: hw_mode_config_type[%d]", cap->hw_mode_config_type);
7222 	wma_nofl_debug("\t: supports_11b[%d]", cap->supports_11b);
7223 	wma_nofl_debug("\t: supports_11g[%d]", cap->supports_11g);
7224 	wma_nofl_debug("\t: supports_11a[%d]", cap->supports_11a);
7225 	wma_nofl_debug("\t: supports_11n[%d]", cap->supports_11n);
7226 	wma_nofl_debug("\t: supports_11ac[%d]", cap->supports_11ac);
7227 	wma_nofl_debug("\t: supports_11ax[%d]", cap->supports_11ax);
7228 	wma_nofl_debug("\t: supported_bands[%d]", cap->supported_bands);
7229 	wma_nofl_debug("\t: ampdu_density[%d]", cap->ampdu_density);
7230 	wma_nofl_debug("\t: max_bw_supported_2G[%d]", cap->max_bw_supported_2G);
7231 	wma_nofl_debug("\t: ht_cap_info_2G[%d]", cap->ht_cap_info_2G);
7232 	wma_nofl_debug("\t: vht_cap_info_2G[0x%0X]", cap->vht_cap_info_2G);
7233 	wma_nofl_debug("\t: vht_supp_mcs_2G[0x%0X]", cap->vht_supp_mcs_2G);
7234 	wma_nofl_debug("\t: tx_chain_mask_2G[%d]", cap->tx_chain_mask_2G);
7235 	wma_nofl_debug("\t: rx_chain_mask_2G[%d]", cap->rx_chain_mask_2G);
7236 	wma_nofl_debug("\t: max_bw_supported_5G[%d]", cap->max_bw_supported_5G);
7237 	wma_nofl_debug("\t: ht_cap_info_5G[%d]", cap->ht_cap_info_5G);
7238 	wma_nofl_debug("\t: vht_cap_info_5G[0x%0X]", cap->vht_cap_info_5G);
7239 	wma_nofl_debug("\t: vht_supp_mcs_5G[0x%0X]", cap->vht_supp_mcs_5G);
7240 	wma_nofl_debug("\t: tx_chain_mask_5G[%d]", cap->tx_chain_mask_5G);
7241 	wma_nofl_debug("\t: rx_chain_mask_5G[%d]", cap->rx_chain_mask_5G);
7242 	wma_nofl_debug("\t: he_cap_info_2G[0][%08x]", cap->he_cap_info_2G[0]);
7243 	wma_nofl_debug("\t: he_cap_info_2G[1][%08x]", cap->he_cap_info_2G[1]);
7244 	wma_nofl_debug("\t: he_supp_mcs_2G[%08x]", cap->he_supp_mcs_2G);
7245 	wma_nofl_debug("\t: he_cap_info_5G[0][%08x]", cap->he_cap_info_5G[0]);
7246 	wma_nofl_debug("\t: he_cap_info_5G[1][%08x]", cap->he_cap_info_5G[1]);
7247 	wma_nofl_debug("\t: he_supp_mcs_5G[%08x]", cap->he_supp_mcs_5G);
7248 	qdf_mem_copy(mac_2G, cap->he_cap_info_2G, sizeof(mac_2G));
7249 	qdf_mem_copy(mac_5G, cap->he_cap_info_5G, sizeof(mac_5G));
7250 	qdf_mem_copy(phy_2G, cap->he_cap_phy_info_2G,
7251 		     WMI_MAX_HECAP_PHY_SIZE * 4);
7252 	qdf_mem_copy(phy_5G, cap->he_cap_phy_info_5G,
7253 		     WMI_MAX_HECAP_PHY_SIZE * 4);
7254 	ppet_2G = cap->he_ppet2G;
7255 	ppet_5G = cap->he_ppet5G;
7256 
7257 	wma_print_he_mac_cap_w1(mac_2G[0]);
7258 	wma_print_he_mac_cap_w2(mac_2G[1]);
7259 	wma_print_he_phy_cap(phy_2G);
7260 	wma_print_he_ppet(&ppet_2G);
7261 	wma_print_he_mac_cap_w1(mac_5G[0]);
7262 	wma_print_he_mac_cap_w1(mac_5G[1]);
7263 	wma_print_he_phy_cap(phy_5G);
7264 	wma_print_he_ppet(&ppet_5G);
7265 }
7266 
7267 /**
7268  * wma_print_populate_soc_caps() - Prints all the caps populated per hw mode
7269  * @tgt_hdl: target related info
7270  *
7271  * This function prints all the caps populater per hw mode and per PHY
7272  *
7273  * Return: none
7274  */
wma_print_populate_soc_caps(struct target_psoc_info * tgt_hdl)7275 static void wma_print_populate_soc_caps(struct target_psoc_info *tgt_hdl)
7276 {
7277 	int i, num_hw_modes, total_mac_phy_cnt;
7278 	struct wlan_psoc_host_mac_phy_caps *mac_phy_cap, *tmp;
7279 
7280 	num_hw_modes = target_psoc_get_num_hw_modes(tgt_hdl);
7281 	total_mac_phy_cnt = target_psoc_get_total_mac_phy_cnt(tgt_hdl);
7282 
7283 	/* print number of hw modes */
7284 	wma_debug("num of hw modes [%d]", num_hw_modes);
7285 	wma_debug("num mac_phy_cnt [%d]", total_mac_phy_cnt);
7286 
7287 	mac_phy_cap = target_psoc_get_mac_phy_cap(tgt_hdl);
7288 	if (!mac_phy_cap) {
7289 		wma_err("Invalid MAC PHY capabilities handle");
7290 		return;
7291 	}
7292 
7293 	wma_debug("<====== HW mode cap printing starts ======>");
7294 	/* print cap of each hw mode */
7295 	for (i = 0; i < total_mac_phy_cnt; i++) {
7296 		if (&mac_phy_cap[i]) {
7297 			wma_nofl_debug("====>: hw mode id[%d], phy id[%d]",
7298 				 mac_phy_cap[i].hw_mode_id,
7299 				 mac_phy_cap[i].phy_id);
7300 			tmp = &mac_phy_cap[i];
7301 			wma_print_mac_phy_capabilities(tmp, i);
7302 		}
7303 	}
7304 	wma_debug("<====== HW mode cap printing ends ======>\n");
7305 }
7306 
7307 /**
7308  * wma_update_hw_mode_list() - updates hw_mode_list
7309  * @wma_handle: pointer to wma global structure
7310  * @tgt_hdl: target psoc information
7311  *
7312  * This function updates hw_mode_list with tx_streams, rx_streams,
7313  * bandwidth, dbs and agile dfs for each hw_mode.
7314  *
7315  * Returns: 0 for success else failure.
7316  */
wma_update_hw_mode_list(t_wma_handle * wma_handle,struct target_psoc_info * tgt_hdl)7317 static QDF_STATUS wma_update_hw_mode_list(t_wma_handle *wma_handle,
7318 					  struct target_psoc_info *tgt_hdl)
7319 {
7320 	struct wlan_psoc_host_mac_phy_caps *tmp, *mac_phy_cap;
7321 	uint32_t i, hw_config_type, j = 0;
7322 	WMI_PHY_CAPABILITY new_supported_band = 0;
7323 	bool supported_band_update_failure = false;
7324 	struct wlan_psoc_target_capability_info *tgt_cap_info;
7325 	int num_hw_modes;
7326 
7327 	if (wma_validate_handle(wma_handle))
7328 		return QDF_STATUS_E_FAILURE;
7329 
7330 	num_hw_modes = target_psoc_get_num_hw_modes(tgt_hdl);
7331 	mac_phy_cap = target_psoc_get_mac_phy_cap(tgt_hdl);
7332 	tgt_cap_info = target_psoc_get_target_caps(tgt_hdl);
7333 
7334 	if (!mac_phy_cap) {
7335 		wma_err("mac_phy_cap Null");
7336 		return QDF_STATUS_E_FAILURE;
7337 	}
7338 
7339 	wma_debug("Num modes:%d", num_hw_modes);
7340 	for (i = 0; i < num_hw_modes; i++) {
7341 		/* Update for MAC0 */
7342 		tmp = &mac_phy_cap[j++];
7343 		hw_config_type = tmp->hw_mode_config_type;
7344 		if (wma_update_supported_bands(tmp->supported_bands,
7345 						&new_supported_band)
7346 		   != QDF_STATUS_SUCCESS)
7347 			supported_band_update_failure = true;
7348 
7349 		/* SBS and DBS have dual MAC. Upto 2 MACs are considered. */
7350 		if ((hw_config_type == WMI_HW_MODE_DBS) ||
7351 		    (hw_config_type == WMI_HW_MODE_SBS_PASSIVE) ||
7352 		    (hw_config_type == WMI_HW_MODE_SBS) ||
7353 		    (hw_config_type == WMI_HW_MODE_DBS_OR_SBS)) {
7354 			/* Update for MAC1 */
7355 			tmp = &mac_phy_cap[j++];
7356 			if (QDF_STATUS_SUCCESS !=
7357 			    wma_update_supported_bands(tmp->supported_bands,
7358 						       &new_supported_band))
7359 				supported_band_update_failure = true;
7360 		}
7361 	}
7362 
7363 	/* overwrite phy_capability which we got from service ready event */
7364 	if (!supported_band_update_failure) {
7365 		wma_debug("updating supported band from old[%d] to new[%d]",
7366 			 target_if_get_phy_capability(tgt_hdl),
7367 			 new_supported_band);
7368 		target_if_set_phy_capability(tgt_hdl, new_supported_band);
7369 	}
7370 
7371 	if (QDF_STATUS_SUCCESS !=
7372 			policy_mgr_update_hw_mode_list(wma_handle->psoc,
7373 						       tgt_hdl))
7374 		wma_err("failed to update policy manager");
7375 
7376 	return QDF_STATUS_SUCCESS;
7377 }
7378 
wma_init_wifi_pos_dma_rings(t_wma_handle * wma_handle,uint8_t num_mac,void * buf)7379 static void wma_init_wifi_pos_dma_rings(t_wma_handle *wma_handle,
7380 					uint8_t num_mac, void *buf)
7381 {
7382 	struct hif_opaque_softc *hif_ctx = cds_get_context(QDF_MODULE_ID_HIF);
7383 	void *hal_soc;
7384 
7385 	if (!hif_ctx) {
7386 		wma_err("invalid hif context");
7387 		return;
7388 	}
7389 
7390 	hal_soc = hif_get_hal_handle(hif_ctx);
7391 
7392 	wifi_pos_init_cir_cfr_rings(wma_handle->psoc, hal_soc, num_mac, buf);
7393 }
7394 
7395 /**
7396  * wma_populate_soc_caps() - populate entire SOC's capabilities
7397  * @wma_handle: pointer to wma global structure
7398  * @tgt_hdl: target psoc information
7399  * @param_buf: pointer to param of service ready extension event from fw
7400  *
7401  * This API populates all capabilities of entire SOC. For example,
7402  * how many number of hw modes are supported by this SOC, what are the
7403  * capabilities of each phy per hw mode, what are HAL reg capabilities per
7404  * phy.
7405  *
7406  * Return: none
7407  */
wma_populate_soc_caps(t_wma_handle * wma_handle,struct target_psoc_info * tgt_hdl,WMI_SERVICE_READY_EXT_EVENTID_param_tlvs * param_buf)7408 static void wma_populate_soc_caps(t_wma_handle *wma_handle,
7409 				  struct target_psoc_info *tgt_hdl,
7410 			WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf)
7411 {
7412 
7413 	wma_debug("Enter");
7414 
7415 	wma_init_wifi_pos_dma_rings(wma_handle,
7416 				    param_buf->num_oem_dma_ring_caps,
7417 				    param_buf->oem_dma_ring_caps);
7418 
7419 	wma_print_populate_soc_caps(tgt_hdl);
7420 	wma_debug("Exit");
7421 }
7422 
7423 /**
7424  * wma_init_dbr_params() - init dbr params
7425  * @wma_handle: pointer to wma global structure
7426  *
7427  * This API initializes params of direct buffer rx component.
7428  *
7429  * Return: none
7430  */
7431 #ifdef DIRECT_BUF_RX_ENABLE
wma_init_dbr_params(t_wma_handle * wma_handle)7432 static void wma_init_dbr_params(t_wma_handle *wma_handle)
7433 {
7434 	struct hif_opaque_softc *hif_ctx = cds_get_context(QDF_MODULE_ID_HIF);
7435 	void *hal_soc;
7436 
7437 	if (!hif_ctx) {
7438 		wma_err("invalid hif context");
7439 		return;
7440 	}
7441 
7442 	hal_soc = hif_get_hal_handle(hif_ctx);
7443 	direct_buf_rx_target_attach(wma_handle->psoc, hal_soc,
7444 				    wma_handle->qdf_dev);
7445 }
7446 #else
wma_init_dbr_params(t_wma_handle * wma_handle)7447 static inline void wma_init_dbr_params(t_wma_handle *wma_handle)
7448 {
7449 }
7450 #endif
7451 
7452 /**
7453  * wma_set_coex_res_cfg() - Set target COEX resource configuration.
7454  * @wma_handle: pointer to wma global structure
7455  * @wmi_handle: pointer to wmi handle
7456  * @wlan_res_cfg: Pointer to target resource configuration
7457  *
7458  * Return: none
7459  */
7460 #ifdef FEATURE_COEX_CONFIG
wma_set_coex_res_cfg(t_wma_handle * wma_handle,struct wmi_unified * wmi_handle,target_resource_config * wlan_res_cfg)7461 static void wma_set_coex_res_cfg(t_wma_handle *wma_handle,
7462 				 struct wmi_unified *wmi_handle,
7463 				 target_resource_config *wlan_res_cfg)
7464 {
7465 	if (cfg_get(wma_handle->psoc, CFG_THREE_WAY_COEX_CONFIG_LEGACY) &&
7466 	    wmi_service_enabled(wmi_handle,
7467 				wmi_service_three_way_coex_config_legacy)) {
7468 		wlan_res_cfg->three_way_coex_config_legacy_en = true;
7469 	} else {
7470 		wlan_res_cfg->three_way_coex_config_legacy_en = false;
7471 	}
7472 }
7473 #else
wma_set_coex_res_cfg(t_wma_handle * wma_handle,struct wmi_unified * wmi_handle,target_resource_config * wlan_res_cfg)7474 static void wma_set_coex_res_cfg(t_wma_handle *wma_handle,
7475 				 struct wmi_unified *wmi_handle,
7476 				 target_resource_config *wlan_res_cfg)
7477 {
7478 }
7479 #endif
7480 
wma_update_hw_mode_config(tp_wma_handle wma_handle,struct target_psoc_info * tgt_hdl)7481 static void wma_update_hw_mode_config(tp_wma_handle wma_handle,
7482 				      struct target_psoc_info *tgt_hdl)
7483 {
7484 	uint32_t conc_scan_config_bits, fw_config_bits;
7485 
7486 	fw_config_bits = target_if_get_fw_config_bits(tgt_hdl);
7487 	conc_scan_config_bits = target_if_get_conc_scan_config_bits(tgt_hdl);
7488 
7489 	wma_debug("Defaults: scan config:%x FW mode config:%x",
7490 		  conc_scan_config_bits, fw_config_bits);
7491 
7492 	if (wma_is_dbs_mandatory(wma_handle->psoc, tgt_hdl) &&
7493 	    (policy_mgr_is_dual_mac_disabled_in_ini(wma_handle->psoc))) {
7494 		policy_mgr_set_dual_mac_feature(wma_handle->psoc,
7495 				ENABLE_DBS_CXN_AND_DISABLE_SIMULTANEOUS_SCAN);
7496 		policy_mgr_set_ch_select_plcy(wma_handle->psoc,
7497 					      POLICY_MGR_CH_SELECT_POLICY_DEF);
7498 	}
7499 	wma_init_scan_fw_mode_config(wma_handle->psoc, conc_scan_config_bits,
7500 				     fw_config_bits);
7501 }
7502 
7503 #define MAX_GRP_KEY 16
7504 
wma_rx_service_ready_ext2_event(void * handle,uint8_t * ev,uint32_t len)7505 int wma_rx_service_ready_ext2_event(void *handle, uint8_t *ev, uint32_t len)
7506 {
7507 	tp_wma_handle wma_handle = (tp_wma_handle)handle;
7508 	struct target_psoc_info *tgt_hdl;
7509 	target_resource_config *wlan_res_cfg;
7510 	QDF_STATUS status;
7511 
7512 	wma_debug("Enter");
7513 
7514 	if (wma_validate_handle(wma_handle))
7515 		return -EINVAL;
7516 
7517 	tgt_hdl = wlan_psoc_get_tgt_if_handle(wma_handle->psoc);
7518 	if (!tgt_hdl) {
7519 		wma_err("target psoc info is NULL");
7520 		return -EINVAL;
7521 	}
7522 
7523 	wlan_res_cfg = target_psoc_get_wlan_res_cfg(tgt_hdl);
7524 
7525 	if (wlan_mlme_is_multipass_sap(wma_handle->psoc))
7526 		wlan_res_cfg->max_num_group_keys = MAX_GRP_KEY;
7527 
7528 	status = policy_mgr_update_sbs_freq(wma_handle->psoc, tgt_hdl);
7529 	if (QDF_IS_STATUS_ERROR(status))
7530 		return -EINVAL;
7531 
7532 	wma_update_hw_mode_config(wma_handle, tgt_hdl);
7533 
7534 	return 0;
7535 }
7536 
7537 /**
7538  * wma_rx_service_ready_ext_event() - evt handler for service ready ext event.
7539  * @handle: wma handle
7540  * @event: params of the service ready extended event
7541  * @length: param length
7542  *
7543  * Return: none
7544  */
wma_rx_service_ready_ext_event(void * handle,uint8_t * event,uint32_t length)7545 int wma_rx_service_ready_ext_event(void *handle, uint8_t *event,
7546 					uint32_t length)
7547 {
7548 	tp_wma_handle wma_handle = (tp_wma_handle) handle;
7549 	WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf;
7550 	wmi_service_ready_ext_event_fixed_param *ev;
7551 	QDF_STATUS ret;
7552 	struct target_psoc_info *tgt_hdl;
7553 	struct wlan_psoc_target_capability_info *tgt_cap_info;
7554 	struct wmi_unified *wmi_handle;
7555 	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
7556 	target_resource_config *wlan_res_cfg;
7557 
7558 	wma_debug("Enter");
7559 
7560 	if (wma_validate_handle(wma_handle))
7561 		return -EINVAL;
7562 
7563 	wmi_handle = get_wmi_unified_hdl_from_psoc(wma_handle->psoc);
7564 	if (wmi_validate_handle(wmi_handle))
7565 		return -EINVAL;
7566 
7567 	tgt_hdl = wlan_psoc_get_tgt_if_handle(wma_handle->psoc);
7568 	if (!tgt_hdl) {
7569 		wma_err("target psoc info is NULL");
7570 		return -EINVAL;
7571 	}
7572 
7573 	wlan_res_cfg = target_psoc_get_wlan_res_cfg(tgt_hdl);
7574 	param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event;
7575 	if (!param_buf) {
7576 		wma_err("Invalid event");
7577 		return -EINVAL;
7578 	}
7579 
7580 	ev = param_buf->fixed_param;
7581 	if (!ev) {
7582 		wma_err("Invalid buffer");
7583 		return -EINVAL;
7584 	}
7585 
7586 	wma_debug("WMA <-- WMI_SERVICE_READY_EXT_EVENTID");
7587 
7588 	tgt_cap_info = target_psoc_get_target_caps(tgt_hdl);
7589 	ret = qdf_mc_timer_stop(&wma_handle->service_ready_ext_timer);
7590 	if (!QDF_IS_STATUS_SUCCESS(ret)) {
7591 		wma_err("Failed to stop the service ready ext timer");
7592 		return -EINVAL;
7593 	}
7594 	wma_populate_soc_caps(wma_handle, tgt_hdl, param_buf);
7595 
7596 	ret = wma_update_hw_mode_list(wma_handle, tgt_hdl);
7597 	if (QDF_IS_STATUS_ERROR(ret)) {
7598 		wma_err("Failed to update hw mode list");
7599 		return -EINVAL;
7600 	}
7601 
7602 	wma_debug("WMA --> WMI_INIT_CMDID");
7603 
7604 	wma_update_hw_mode_config(wma_handle, tgt_hdl);
7605 
7606 	target_psoc_set_num_radios(tgt_hdl, 1);
7607 
7608 	wlan_dp_update_peer_map_unmap_version(&wlan_res_cfg->peer_map_unmap_version);
7609 
7610 	if (wmi_service_enabled(wmi_handle,
7611 				wmi_service_new_htt_msg_format)) {
7612 		cdp_cfg_set_new_htt_msg_format(soc, 1);
7613 		wlan_res_cfg->new_htt_msg_format = true;
7614 	} else {
7615 		cdp_cfg_set_new_htt_msg_format(soc, 0);
7616 		wlan_res_cfg->new_htt_msg_format = false;
7617 	}
7618 
7619 	if (QDF_GLOBAL_FTM_MODE  != cds_get_conparam() &&
7620 	    ucfg_mlme_get_peer_unmap_conf(wma_handle->psoc) &&
7621 	    wmi_service_enabled(wmi_handle,
7622 				wmi_service_peer_unmap_cnf_support)) {
7623 		wlan_res_cfg->peer_unmap_conf_support = true;
7624 		cdp_cfg_set_peer_unmap_conf_support(soc, true);
7625 	} else {
7626 		wlan_res_cfg->peer_unmap_conf_support = false;
7627 		cdp_cfg_set_peer_unmap_conf_support(soc, false);
7628 	}
7629 
7630 	if (wma_handle->enable_tx_compl_tsf64 &&
7631 	    wmi_service_enabled(wmi_handle,
7632 				wmi_service_tx_compl_tsf64)) {
7633 		wlan_res_cfg->tstamp64_en = true;
7634 		cdp_cfg_set_tx_compl_tsf64(soc, true);
7635 	} else {
7636 		wlan_res_cfg->tstamp64_en = false;
7637 		cdp_cfg_set_tx_compl_tsf64(soc, false);
7638 	}
7639 
7640 	if (ucfg_is_ftm_time_sync_enable(wma_handle->psoc) &&
7641 	    wmi_service_enabled(wmi_handle, wmi_service_time_sync_ftm)) {
7642 		wlan_res_cfg->time_sync_ftm = true;
7643 		ucfg_ftm_time_sync_set_enable(wma_handle->psoc, true);
7644 	} else {
7645 		wlan_res_cfg->time_sync_ftm = false;
7646 		ucfg_ftm_time_sync_set_enable(wma_handle->psoc, false);
7647 	}
7648 
7649 	if (wmi_service_enabled(wma_handle->wmi_handle, wmi_service_nan_vdev))
7650 		ucfg_nan_set_vdev_creation_supp_by_fw(wma_handle->psoc, true);
7651 
7652 	/* Change default hw mode as below kind of target will only be
7653 	 * sending single HW mode
7654 	 */
7655 	if (!wmi_service_enabled(wmi_handle,
7656 				 wmi_service_dual_band_simultaneous_support))
7657 		wma_handle->new_hw_mode_index =
7658 				tgt_cap_info->default_dbs_hw_mode_index;
7659 
7660 	/*
7661 	 * Firmware can accommodate maximum 4 vdevs and the ini gNumVdevs
7662 	 * indicates the same.
7663 	 * If host driver is going to create vdev for NAN, it indicates
7664 	 * the total no.of vdevs supported to firmware which includes the
7665 	 * NAN vdev.
7666 	 * If firmware is going to create NAN discovery vdev, host should
7667 	 * indicate 3 vdevs and firmware shall add 1 vdev for NAN. So decrement
7668 	 * the num_vdevs by 1.
7669 	 * If NAN is not supported on some target(disabled through ini
7670 	 * param gEnableNanSupport), there is no use of reserving one vdev for
7671 	 * it in firmware though firmware advertises wmi_service_nan. Indicate
7672 	 * firmware that host is going to take care of the NAN vdev. Host can
7673 	 * use the vdev either for NAN or other operations on need basis.
7674 	 */
7675 
7676 	if (wmi_service_enabled(wma_handle->wmi_handle, wmi_service_nan)) {
7677 		if (ucfg_nan_is_vdev_creation_allowed(wma_handle->psoc) ||
7678 		    QDF_GLOBAL_FTM_MODE == cds_get_conparam() ||
7679 		    !cfg_nan_get_enable(wma_handle->psoc)) {
7680 			wlan_res_cfg->nan_separate_iface_support = true;
7681 		} else {
7682 			wlan_res_cfg->num_vdevs--;
7683 			wma_update_num_peers_tids(wma_handle, wlan_res_cfg);
7684 		}
7685 	}
7686 
7687 	if ((ucfg_pkt_capture_get_mode(wma_handle->psoc) !=
7688 						PACKET_CAPTURE_MODE_DISABLE) &&
7689 	    wmi_service_enabled(wmi_handle,
7690 				wmi_service_packet_capture_support))
7691 		wlan_res_cfg->pktcapture_support = true;
7692 	else
7693 		wlan_res_cfg->pktcapture_support = false;
7694 	wlan_res_cfg->max_peer_ext_stats = WMA_SON_MAX_PEER_EXT_STATS;
7695 
7696 	if (wmi_service_enabled(wmi_handle,
7697 				wmi_service_sae_eapol_offload_support))
7698 		wlan_res_cfg->sae_eapol_offload = true;
7699 	else
7700 		wlan_res_cfg->sae_eapol_offload = false;
7701 
7702 	wma_debug("num_vdevs: %u", wlan_res_cfg->num_vdevs);
7703 
7704 	wma_init_dbr_params(wma_handle);
7705 
7706 	wma_set_coex_res_cfg(wma_handle, wmi_handle, wlan_res_cfg);
7707 
7708 	return 0;
7709 }
7710 
7711 /**
7712  * wma_rx_ready_event() - event handler to process
7713  *                        wmi rx ready event.
7714  * @handle: wma handle
7715  * @cmd_param_info: command params info
7716  * @length: param length
7717  *
7718  * Return: none
7719  */
wma_rx_ready_event(void * handle,uint8_t * cmd_param_info,uint32_t length)7720 int wma_rx_ready_event(void *handle, uint8_t *cmd_param_info,
7721 					uint32_t length)
7722 {
7723 	tp_wma_handle wma_handle = (tp_wma_handle) handle;
7724 	WMI_READY_EVENTID_param_tlvs *param_buf = NULL;
7725 	wmi_ready_event_fixed_param *ev = NULL;
7726 	int ret;
7727 
7728 	wma_debug("Enter");
7729 
7730 	param_buf = (WMI_READY_EVENTID_param_tlvs *) cmd_param_info;
7731 	if (!(wma_handle && param_buf)) {
7732 		wma_err("Invalid arguments");
7733 		QDF_ASSERT(0);
7734 		return -EINVAL;
7735 	}
7736 
7737 	wma_debug("WMA <-- WMI_READY_EVENTID");
7738 
7739 	if (wma_is_feature_set_supported(wma_handle))
7740 		wma_send_feature_set_cmd(wma_handle);
7741 
7742 	ev = param_buf->fixed_param;
7743 	/* Indicate to the waiting thread that the ready
7744 	 * event was received
7745 	 */
7746 	wma_handle->sub_20_support =
7747 		wmi_service_enabled(wma_handle->wmi_handle,
7748 				wmi_service_half_rate_quarter_rate_support);
7749 	wma_handle->wmi_ready = true;
7750 	wma_handle->wlan_init_status = ev->status;
7751 
7752 	if (wma_handle->is_dfs_offloaded)
7753 		wmi_unified_dfs_phyerr_offload_en_cmd(
7754 				wma_handle->wmi_handle, 0);
7755 	/* copy the mac addr */
7756 	WMI_MAC_ADDR_TO_CHAR_ARRAY(&ev->mac_addr, wma_handle->myaddr);
7757 	WMI_MAC_ADDR_TO_CHAR_ARRAY(&ev->mac_addr, wma_handle->hwaddr);
7758 	ret = wma_update_hdd_cfg(wma_handle);
7759 	if (ret)
7760 		return ret;
7761 
7762 	wma_debug("Exit");
7763 
7764 	return 0;
7765 }
7766 
7767 /**
7768  * wma_wait_for_ready_event() - wait for wma ready event
7769  * @handle: wma handle
7770  *
7771  * Return: 0 for success or QDF error
7772  */
wma_wait_for_ready_event(WMA_HANDLE handle)7773 QDF_STATUS wma_wait_for_ready_event(WMA_HANDLE handle)
7774 {
7775 	tp_wma_handle wma_handle = (tp_wma_handle)handle;
7776 	QDF_STATUS status;
7777 	struct target_psoc_info *tgt_hdl;
7778 
7779 	tgt_hdl = wlan_psoc_get_tgt_if_handle(wma_handle->psoc);
7780 	if (!tgt_hdl) {
7781 		wma_err("target psoc info is NULL");
7782 		return QDF_STATUS_E_INVAL;
7783 	}
7784 
7785 	status = qdf_wait_for_event_completion(&tgt_hdl->info.event,
7786 					       WMA_READY_EVENTID_TIMEOUT);
7787 	if (!tgt_hdl->info.wmi_ready) {
7788 		wma_err("Error in pdev creation");
7789 		if (!cds_is_driver_recovering() || !cds_is_fw_down())
7790 			QDF_DEBUG_PANIC("FW ready event timed out");
7791 		return QDF_STATUS_E_INVAL;
7792 	}
7793 
7794 	if (status == QDF_STATUS_E_TIMEOUT)
7795 		wma_err("Timeout waiting for FW ready event");
7796 	else if (QDF_IS_STATUS_ERROR(status))
7797 		wma_err("Failed to wait for FW ready event; status:%u", status);
7798 	else
7799 		wma_info("FW ready event received");
7800 
7801 	return status;
7802 }
7803 
7804 /**
7805  * wma_set_ppsconfig() - set pps config in fw
7806  * @vdev_id: vdev id
7807  * @pps_param: pps params
7808  * @val : param value
7809  *
7810  * Return: 0 for success or QDF error
7811  */
wma_set_ppsconfig(uint8_t vdev_id,uint16_t pps_param,int val)7812 QDF_STATUS wma_set_ppsconfig(uint8_t vdev_id, uint16_t pps_param,
7813 				    int val)
7814 {
7815 	tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA);
7816 	int ret = -EIO;
7817 	uint32_t pps_val;
7818 
7819 	if (!wma)
7820 		return QDF_STATUS_E_INVAL;
7821 
7822 	switch (pps_param) {
7823 	case WMA_VHT_PPS_PAID_MATCH:
7824 		pps_val = ((val << 31) & 0xffff0000) |
7825 			  (PKT_PWR_SAVE_PAID_MATCH & 0xffff);
7826 		goto pkt_pwr_save_config;
7827 	case WMA_VHT_PPS_GID_MATCH:
7828 		pps_val = ((val << 31) & 0xffff0000) |
7829 			  (PKT_PWR_SAVE_GID_MATCH & 0xffff);
7830 		goto pkt_pwr_save_config;
7831 	case WMA_VHT_PPS_DELIM_CRC_FAIL:
7832 		pps_val = ((val << 31) & 0xffff0000) |
7833 			  (PKT_PWR_SAVE_DELIM_CRC_FAIL & 0xffff);
7834 		goto pkt_pwr_save_config;
7835 
7836 		/* Enable the code below as and when the functionality
7837 		 * is supported/added in host.
7838 		 */
7839 #ifdef NOT_YET
7840 	case WMA_VHT_PPS_EARLY_TIM_CLEAR:
7841 		pps_val = ((val << 31) & 0xffff0000) |
7842 			  (PKT_PWR_SAVE_EARLY_TIM_CLEAR & 0xffff);
7843 		goto pkt_pwr_save_config;
7844 	case WMA_VHT_PPS_EARLY_DTIM_CLEAR:
7845 		pps_val = ((val << 31) & 0xffff0000) |
7846 			  (PKT_PWR_SAVE_EARLY_DTIM_CLEAR & 0xffff);
7847 		goto pkt_pwr_save_config;
7848 	case WMA_VHT_PPS_EOF_PAD_DELIM:
7849 		pps_val = ((val << 31) & 0xffff0000) |
7850 			  (PKT_PWR_SAVE_EOF_PAD_DELIM & 0xffff);
7851 		goto pkt_pwr_save_config;
7852 	case WMA_VHT_PPS_MACADDR_MISMATCH:
7853 		pps_val = ((val << 31) & 0xffff0000) |
7854 			  (PKT_PWR_SAVE_MACADDR_MISMATCH & 0xffff);
7855 		goto pkt_pwr_save_config;
7856 	case WMA_VHT_PPS_GID_NSTS_ZERO:
7857 		pps_val = ((val << 31) & 0xffff0000) |
7858 			  (PKT_PWR_SAVE_GID_NSTS_ZERO & 0xffff);
7859 		goto pkt_pwr_save_config;
7860 	case WMA_VHT_PPS_RSSI_CHECK:
7861 		pps_val = ((val << 31) & 0xffff0000) |
7862 			  (PKT_PWR_SAVE_RSSI_CHECK & 0xffff);
7863 		goto pkt_pwr_save_config;
7864 #endif /* NOT_YET */
7865 pkt_pwr_save_config:
7866 		wma_debug("vdev_id:%d val:0x%x pps_val:0x%x", vdev_id,
7867 			 val, pps_val);
7868 		ret = wma_vdev_set_param(wma->wmi_handle, vdev_id,
7869 					      wmi_vdev_param_packet_powersave,
7870 					      pps_val);
7871 		break;
7872 	default:
7873 		wma_err("INVALID PPS CONFIG");
7874 	}
7875 
7876 	return (ret) ? QDF_STATUS_E_FAILURE : QDF_STATUS_SUCCESS;
7877 }
7878 
7879 /**
7880  * wma_process_set_mas() - Function to enable/disable MAS
7881  * @wma:	Pointer to WMA handle
7882  * @mas_val:	1-Enable MAS, 0-Disable MAS
7883  *
7884  * This function enables/disables the MAS value
7885  *
7886  * Return: QDF_SUCCESS for success otherwise failure
7887  */
wma_process_set_mas(tp_wma_handle wma,uint32_t * mas_val)7888 static QDF_STATUS wma_process_set_mas(tp_wma_handle wma,
7889 				      uint32_t *mas_val)
7890 {
7891 	uint32_t val;
7892 
7893 	if (!wma || !mas_val) {
7894 		wma_err("Invalid input to enable/disable MAS");
7895 		return QDF_STATUS_E_FAILURE;
7896 	}
7897 
7898 	val = (*mas_val);
7899 
7900 	if (QDF_STATUS_SUCCESS !=
7901 			wma_set_enable_disable_mcc_adaptive_scheduler(val)) {
7902 		wma_err("Unable to enable/disable MAS");
7903 		return QDF_STATUS_E_FAILURE;
7904 	}
7905 	wma_debug("Value is %d", val);
7906 	return QDF_STATUS_SUCCESS;
7907 }
7908 
7909 /**
7910  * wma_process_set_miracast() - Function to set miracast value in WMA
7911  * @wma:		Pointer to WMA handle
7912  * @miracast_val:	0-Disabled,1-Source,2-Sink
7913  *
7914  * This function stores the miracast value in WMA
7915  *
7916  * Return: QDF_SUCCESS for success otherwise failure
7917  *
7918  */
wma_process_set_miracast(tp_wma_handle wma,uint32_t * miracast_val)7919 static QDF_STATUS wma_process_set_miracast(tp_wma_handle wma,
7920 					   uint32_t *miracast_val)
7921 {
7922 	if (!wma || !miracast_val) {
7923 		wma_err("Invalid input to store miracast value");
7924 		return QDF_STATUS_E_FAILURE;
7925 	}
7926 
7927 	wma->miracast_value = *miracast_val;
7928 	wma_debug("Miracast value is %d", wma->miracast_value);
7929 
7930 	return QDF_STATUS_SUCCESS;
7931 }
7932 
7933 /**
7934  * wma_config_stats_factor() - Function to configure stats avg. factor
7935  * @wma:  pointer to WMA handle
7936  * @avg_factor:	stats. avg. factor passed down by userspace
7937  *
7938  * This function configures the avg. stats value in firmware
7939  *
7940  * Return: QDF_STATUS_SUCCESS for success otherwise failure
7941  *
7942  */
wma_config_stats_factor(tp_wma_handle wma,struct sir_stats_avg_factor * avg_factor)7943 static QDF_STATUS wma_config_stats_factor(tp_wma_handle wma,
7944 				      struct sir_stats_avg_factor *avg_factor)
7945 {
7946 	QDF_STATUS ret;
7947 
7948 	if (!wma || !avg_factor) {
7949 		wma_err("Invalid input of stats avg factor");
7950 		return QDF_STATUS_E_FAILURE;
7951 	}
7952 
7953 	ret = wma_vdev_set_param(wma->wmi_handle,
7954 					    avg_factor->vdev_id,
7955 					    wmi_vdev_param_stats_avg_factor,
7956 					    avg_factor->stats_avg_factor);
7957 	if (QDF_IS_STATUS_ERROR(ret)) {
7958 		wma_err("failed to set avg_factor for vdev_id %d",
7959 			 avg_factor->vdev_id);
7960 	}
7961 
7962 	wma_debug("Set stats_avg_factor %d for vdev_id %d",
7963 		 avg_factor->stats_avg_factor, avg_factor->vdev_id);
7964 
7965 	return ret;
7966 }
7967 
7968 /**
7969  * wma_config_guard_time() - Function to set guard time in firmware
7970  * @wma:  pointer to WMA handle
7971  * @guard_time:  guard time passed down by userspace
7972  *
7973  * This function configures the guard time in firmware
7974  *
7975  * Return: QDF_STATUS_SUCCESS for success otherwise failure
7976  *
7977  */
wma_config_guard_time(tp_wma_handle wma,struct sir_guard_time_request * guard_time)7978 static QDF_STATUS wma_config_guard_time(tp_wma_handle wma,
7979 				   struct sir_guard_time_request *guard_time)
7980 {
7981 	QDF_STATUS ret;
7982 
7983 	if (!wma || !guard_time) {
7984 		wma_err("Invalid input of guard time");
7985 		return QDF_STATUS_E_FAILURE;
7986 	}
7987 
7988 	ret = wma_vdev_set_param(wma->wmi_handle,
7989 					      guard_time->vdev_id,
7990 					      wmi_vdev_param_rx_leak_window,
7991 					      guard_time->guard_time);
7992 	if (QDF_IS_STATUS_ERROR(ret)) {
7993 		wma_err("failed to set guard time for vdev_id %d",
7994 			 guard_time->vdev_id);
7995 	}
7996 
7997 	wma_debug("Set guard time %d for vdev_id %d",
7998 		 guard_time->guard_time, guard_time->vdev_id);
7999 
8000 	return ret;
8001 }
8002 
8003 /**
8004  * wma_enable_specific_fw_logs() - Start/Stop logging of diag event/log id
8005  * @wma_handle: WMA handle
8006  * @start_log: Start logging related parameters
8007  *
8008  * Send the command to the FW based on which specific logging of diag
8009  * event/log id can be started/stopped
8010  *
8011  * Return: None
8012  */
wma_enable_specific_fw_logs(tp_wma_handle wma_handle,struct sir_wifi_start_log * start_log)8013 static void wma_enable_specific_fw_logs(tp_wma_handle wma_handle,
8014 					struct sir_wifi_start_log *start_log)
8015 {
8016 
8017 	if (!start_log) {
8018 		wma_err("start_log pointer is NULL");
8019 		return;
8020 	}
8021 	if (wma_validate_handle(wma_handle))
8022 		return;
8023 
8024 	if (!((start_log->ring_id == RING_ID_CONNECTIVITY) ||
8025 			(start_log->ring_id == RING_ID_FIRMWARE_DEBUG))) {
8026 		wma_debug("Not connectivity or fw debug ring: %d",
8027 				start_log->ring_id);
8028 		return;
8029 	}
8030 
8031 	wmi_unified_enable_specific_fw_logs_cmd(wma_handle->wmi_handle,
8032 				(struct wmi_wifi_start_log *)start_log);
8033 }
8034 
8035 #define MEGABYTE	(1024 * 1024)
8036 /**
8037  * wma_set_wifi_start_packet_stats() - Start/stop packet stats
8038  * @wma_handle: WMA handle
8039  * @start_log: Structure containing the start wifi logger params
8040  *
8041  * This function is used to send the WMA commands to start/stop logging
8042  * of per packet statistics
8043  *
8044  * Return: None
8045  *
8046  */
8047 #if !defined(FEATURE_PKTLOG) || defined(REMOVE_PKT_LOG)
wma_set_wifi_start_packet_stats(void * wma_handle,struct sir_wifi_start_log * start_log)8048 static void wma_set_wifi_start_packet_stats(void *wma_handle,
8049 					struct sir_wifi_start_log *start_log)
8050 {
8051 }
8052 
8053 #else
wma_set_wifi_start_packet_stats(void * wma_handle,struct sir_wifi_start_log * start_log)8054 static void wma_set_wifi_start_packet_stats(void *wma_handle,
8055 					struct sir_wifi_start_log *start_log)
8056 {
8057 	struct hif_opaque_softc *scn;
8058 	uint32_t log_state;
8059 
8060 	if (!start_log) {
8061 		wma_err("start_log pointer is NULL");
8062 		return;
8063 	}
8064 	if (wma_validate_handle(wma_handle))
8065 		return;
8066 
8067 	/* No need to register for ring IDs other than packet stats */
8068 	if (start_log->ring_id != RING_ID_PER_PACKET_STATS) {
8069 		wma_debug("Ring id is not for per packet stats: %d",
8070 			 start_log->ring_id);
8071 		return;
8072 	}
8073 
8074 	scn = cds_get_context(QDF_MODULE_ID_HIF);
8075 	if (!scn) {
8076 		wma_err("Invalid HIF handle");
8077 		return;
8078 	}
8079 
8080 #ifdef PKTLOG_LEGACY
8081 	log_state = ATH_PKTLOG_ANI | ATH_PKTLOG_RCUPDATE | ATH_PKTLOG_RCFIND |
8082 		ATH_PKTLOG_RX | ATH_PKTLOG_TX |
8083 		ATH_PKTLOG_TEXT | ATH_PKTLOG_SW_EVENT;
8084 #elif defined(QCA_WIFI_QCA6390) || defined(QCA_WIFI_QCA6490) || \
8085       defined(QCA_WIFI_QCA6750) || defined(QCA_WIFI_KIWI) || \
8086       defined(QCA_WIFI_WCN6450)
8087 	log_state = ATH_PKTLOG_RCFIND | ATH_PKTLOG_RCUPDATE |
8088 		    ATH_PKTLOG_TX | ATH_PKTLOG_LITE_T2H |
8089 		    ATH_PKTLOG_SW_EVENT | ATH_PKTLOG_RX;
8090 #elif defined(QCA_WIFI_QCA6290)
8091 	log_state = ATH_PKTLOG_LITE_RX | ATH_PKTLOG_LITE_T2H;
8092 #else
8093 	wma_debug("Packet log Not supported");
8094 	log_state = 0;
8095 #endif
8096 	if (start_log->size != 0) {
8097 		pktlog_setsize(scn, start_log->size * MEGABYTE);
8098 		return;
8099 	} else if (start_log->is_pktlog_buff_clear == true) {
8100 		pktlog_clearbuff(scn, start_log->is_pktlog_buff_clear);
8101 		return;
8102 	}
8103 
8104 	if (start_log->verbose_level == WLAN_LOG_LEVEL_ACTIVE) {
8105 		pktlog_enable(scn, log_state, start_log->ini_triggered,
8106 			      start_log->user_triggered,
8107 			      start_log->is_iwpriv_command);
8108 		wma_debug("Enabling per packet stats");
8109 	} else {
8110 		pktlog_enable(scn, 0, start_log->ini_triggered,
8111 				start_log->user_triggered,
8112 				start_log->is_iwpriv_command);
8113 		wma_debug("Disabling per packet stats");
8114 	}
8115 }
8116 #endif
8117 
8118 /**
8119  * wma_send_flush_logs_to_fw() - Send log flush command to FW
8120  * @wma_handle: WMI handle
8121  *
8122  * This function is used to send the flush command to the FW,
8123  * that will flush the fw logs that are residue in the FW
8124  *
8125  * Return: None
8126  */
wma_send_flush_logs_to_fw(tp_wma_handle wma_handle)8127 void wma_send_flush_logs_to_fw(tp_wma_handle wma_handle)
8128 {
8129 	QDF_STATUS status;
8130 
8131 	status = wmi_unified_flush_logs_to_fw_cmd(wma_handle->wmi_handle);
8132 	if (QDF_IS_STATUS_ERROR(status))
8133 		return;
8134 
8135 	status = qdf_mc_timer_start(&wma_handle->log_completion_timer,
8136 				    WMA_LOG_COMPLETION_TIMER);
8137 	if (QDF_IS_STATUS_ERROR(status))
8138 		wma_err("Failed to start the log completion timer");
8139 }
8140 
8141 /**
8142  * wma_update_tx_fail_cnt_th() - Set threshold for TX pkt fail
8143  * @wma: WMA handle
8144  * @tx_fail_cnt_th: sme_tx_fail_cnt_threshold parameter
8145  *
8146  * This function is used to set Tx pkt fail count threshold,
8147  * FW will do disconnect with station once this threshold is reached.
8148  *
8149  * Return: QDF_STATUS
8150  */
wma_update_tx_fail_cnt_th(tp_wma_handle wma,struct sme_tx_fail_cnt_threshold * tx_fail_cnt_th)8151 static QDF_STATUS wma_update_tx_fail_cnt_th(tp_wma_handle wma,
8152 			struct sme_tx_fail_cnt_threshold *tx_fail_cnt_th)
8153 {
8154 	u_int8_t vdev_id;
8155 	u_int32_t tx_fail_disconn_th;
8156 	int ret = -EIO;
8157 	struct wmi_unified *wmi_handle;
8158 
8159 	if (wma_validate_handle(wma))
8160 		return QDF_STATUS_E_INVAL;
8161 
8162 	wmi_handle = wma->wmi_handle;
8163 	if (wmi_validate_handle(wmi_handle))
8164 		return QDF_STATUS_E_INVAL;
8165 
8166 	vdev_id = tx_fail_cnt_th->session_id;
8167 	tx_fail_disconn_th = tx_fail_cnt_th->tx_fail_cnt_threshold;
8168 	wma_debug("Set TX pkt fail count threshold  vdevId %d count %d",
8169 			vdev_id, tx_fail_disconn_th);
8170 
8171 	ret = wma_vdev_set_param(wmi_handle, vdev_id,
8172 			wmi_vdev_param_disconnect_th,
8173 			tx_fail_disconn_th);
8174 
8175 	if (ret) {
8176 		wma_err("Failed to send TX pkt fail count threshold command");
8177 		return QDF_STATUS_E_FAILURE;
8178 	}
8179 
8180 	return QDF_STATUS_SUCCESS;
8181 }
8182 
8183 /**
8184  * wma_update_short_retry_limit() - Set retry limit for short frames
8185  * @wma: WMA handle
8186  * @short_retry_limit_th: retry limir count for Short frames.
8187  *
8188  * This function is used to configure the transmission retry limit at which
8189  * short frames needs to be retry.
8190  *
8191  * Return: QDF_STATUS
8192  */
wma_update_short_retry_limit(tp_wma_handle wma,struct sme_short_retry_limit * short_retry_limit_th)8193 static QDF_STATUS wma_update_short_retry_limit(tp_wma_handle wma,
8194 		struct sme_short_retry_limit *short_retry_limit_th)
8195 {
8196 	uint8_t vdev_id;
8197 	uint32_t short_retry_limit;
8198 	int ret;
8199 	struct wmi_unified *wmi_handle;
8200 
8201 	if (wma_validate_handle(wma))
8202 		return QDF_STATUS_E_INVAL;
8203 
8204 	wmi_handle = wma->wmi_handle;
8205 	if (wmi_validate_handle(wmi_handle))
8206 		return QDF_STATUS_E_INVAL;
8207 
8208 	vdev_id = short_retry_limit_th->session_id;
8209 	short_retry_limit = short_retry_limit_th->short_retry_limit;
8210 	wma_debug("Set short retry limit threshold  vdevId %d count %d",
8211 		vdev_id, short_retry_limit);
8212 
8213 	ret = wma_vdev_set_param(wmi_handle, vdev_id,
8214 				 wmi_vdev_param_non_agg_sw_retry_th,
8215 				 short_retry_limit);
8216 
8217 	if (ret) {
8218 		wma_err("Failed to send short limit threshold command");
8219 		return QDF_STATUS_E_FAILURE;
8220 	}
8221 	return QDF_STATUS_SUCCESS;
8222 }
8223 
8224 /**
8225  * wma_update_long_retry_limit() - Set retry limit for long frames
8226  * @wma: WMA handle
8227  * @long_retry_limit_th: retry limir count for long frames
8228  *
8229  * This function is used to configure the transmission retry limit at which
8230  * long frames needs to be retry
8231  *
8232  * Return: QDF_STATUS
8233  */
wma_update_long_retry_limit(tp_wma_handle wma,struct sme_long_retry_limit * long_retry_limit_th)8234 static QDF_STATUS wma_update_long_retry_limit(tp_wma_handle wma,
8235 		struct sme_long_retry_limit  *long_retry_limit_th)
8236 {
8237 	uint8_t vdev_id;
8238 	uint32_t long_retry_limit;
8239 	int ret;
8240 	struct wmi_unified *wmi_handle;
8241 
8242 	if (wma_validate_handle(wma))
8243 		return QDF_STATUS_E_INVAL;
8244 
8245 	wmi_handle = wma->wmi_handle;
8246 	if (wmi_validate_handle(wmi_handle))
8247 		return QDF_STATUS_E_INVAL;
8248 
8249 	vdev_id = long_retry_limit_th->session_id;
8250 	long_retry_limit = long_retry_limit_th->long_retry_limit;
8251 	wma_debug("Set TX pkt fail count threshold  vdevId %d count %d",
8252 		vdev_id, long_retry_limit);
8253 
8254 	ret  = wma_vdev_set_param(wmi_handle, vdev_id,
8255 			wmi_vdev_param_agg_sw_retry_th,
8256 			long_retry_limit);
8257 
8258 	if (ret) {
8259 		wma_err("Failed to send long limit threshold command");
8260 		return QDF_STATUS_E_FAILURE;
8261 	}
8262 
8263 	return QDF_STATUS_SUCCESS;
8264 }
8265 
8266 #define MAX_VDEV_AP_ALIVE_PARAMS 4
8267 /* params being sent:
8268  * wmi_vdev_param_ap_keepalive_min_idle_inactive_time_secs
8269  * wmi_vdev_param_ap_keepalive_max_idle_inactive_secs
8270  * wmi_vdev_param_ap_keepalive_min_idle_inactive_time_secs
8271  * wmi_vdev_param_ap_keepalive_max_unresponsive_time_secs
8272  */
8273 
8274 /*
8275  * wma_update_sta_inactivity_timeout() - Set sta_inactivity_timeout to fw
8276  * @wma_handle: WMA handle
8277  * @sta_inactivity_timer: sme_sta_inactivity_timeout
8278  *
8279  * This function is used to set sta_inactivity_timeout.
8280  * If a station does not send anything in sta_inactivity_timeout seconds, an
8281  * empty data frame is sent to it in order to verify whether it is
8282  * still in range. If this frame is not ACKed, the station will be
8283  * disassociated and then deauthenticated.
8284  *
8285  * Return: None
8286  */
wma_update_sta_inactivity_timeout(tp_wma_handle wma,struct sme_sta_inactivity_timeout * sta_inactivity_timer)8287 void wma_update_sta_inactivity_timeout(tp_wma_handle wma,
8288 		struct sme_sta_inactivity_timeout  *sta_inactivity_timer)
8289 {
8290 	uint8_t vdev_id;
8291 	uint32_t max_unresponsive_time;
8292 	uint32_t min_inactive_time, max_inactive_time;
8293 	struct wmi_unified *wmi_handle;
8294 	struct dev_set_param setparam[MAX_VDEV_AP_ALIVE_PARAMS] = {};
8295 	uint8_t index = 0;
8296 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
8297 
8298 	if (wma_validate_handle(wma))
8299 		return;
8300 
8301 	wmi_handle = wma->wmi_handle;
8302 	if (wmi_validate_handle(wmi_handle))
8303 		return;
8304 
8305 	vdev_id = sta_inactivity_timer->session_id;
8306 	max_unresponsive_time = sta_inactivity_timer->sta_inactivity_timeout;
8307 	max_inactive_time = max_unresponsive_time * TWO_THIRD;
8308 	min_inactive_time = max_unresponsive_time - max_inactive_time;
8309 	status = mlme_check_index_setparam(
8310 			setparam,
8311 			wmi_vdev_param_ap_keepalive_min_idle_inactive_time_secs,
8312 			min_inactive_time, index++,
8313 			MAX_VDEV_AP_ALIVE_PARAMS);
8314 	if (QDF_IS_STATUS_ERROR(status)) {
8315 		wma_err("failed to set wmi_vdev_param_ap_keepalive_min_idle_inactive_time_secs");
8316 		goto error;
8317 	}
8318 	status = mlme_check_index_setparam(
8319 			setparam,
8320 			wmi_vdev_param_ap_keepalive_max_idle_inactive_secs,
8321 			min_inactive_time, index++, MAX_VDEV_AP_ALIVE_PARAMS);
8322 	if (QDF_IS_STATUS_ERROR(status)) {
8323 		wma_err("failed to set wmi_vdev_param_ap_keepalive_max_idle_inactive_secs");
8324 		goto error;
8325 	}
8326 	status = mlme_check_index_setparam(
8327 			setparam,
8328 			wmi_vdev_param_ap_keepalive_min_idle_inactive_time_secs,
8329 			max_inactive_time, index++, MAX_VDEV_AP_ALIVE_PARAMS);
8330 	if (QDF_IS_STATUS_ERROR(status)) {
8331 		wma_err("failed to set wmi_vdev_param_ap_keepalive_min_idle_inactive_time_secs");
8332 		goto error;
8333 	}
8334 	status = mlme_check_index_setparam(
8335 			setparam,
8336 			wmi_vdev_param_ap_keepalive_max_unresponsive_time_secs,
8337 			max_unresponsive_time, index++,
8338 			MAX_VDEV_AP_ALIVE_PARAMS);
8339 	if (QDF_IS_STATUS_ERROR(status)) {
8340 		wma_err("failed to set wmi_vdev_param_ap_keepalive_max_unresponsive_time_secs");
8341 		goto error;
8342 	}
8343 
8344 	status = wma_send_multi_pdev_vdev_set_params(MLME_VDEV_SETPARAM,
8345 						     vdev_id, setparam, index);
8346 	if (QDF_IS_STATUS_ERROR(status))
8347 		wma_err("Failed to send idle_inactive,unresponsive time vdev set params");
8348 
8349 error:
8350 	return;
8351 }
8352 
8353 #ifdef WLAN_FEATURE_WOW_PULSE
8354 
8355 
8356 #define WMI_WOW_HOSTWAKEUP_GPIO_CMD_FIXED_PARAM \
8357 WMI_WOW_HOSTWAKEUP_GPIO_PIN_PATTERN_CONFIG_CMD_fixed_param
8358 
8359 
8360 #define WMITLV_TAG_HOSTWAKEUP_GPIO_CMD_FIXED_PARAM \
8361 WMITLV_TAG_STRUC_wmi_wow_hostwakeup_gpio_pin_pattern_config_cmd_fixed_param
8362 
8363 /**
8364  * wma_send_wow_pulse_cmd() - send wmi cmd of wow pulse cmd
8365  * information to fw.
8366  * @wma_handle: wma handler
8367  * @wow_pulse_cmd: wow_pulse_mode pointer
8368  *
8369  * Return: Return QDF_STATUS
8370  */
wma_send_wow_pulse_cmd(tp_wma_handle wma_handle,struct wow_pulse_mode * wow_pulse_cmd)8371 static QDF_STATUS wma_send_wow_pulse_cmd(tp_wma_handle wma_handle,
8372 					struct wow_pulse_mode *wow_pulse_cmd)
8373 {
8374 	QDF_STATUS status = QDF_STATUS_SUCCESS;
8375 	wmi_buf_t buf;
8376 	WMI_WOW_HOSTWAKEUP_GPIO_CMD_FIXED_PARAM *cmd;
8377 	u_int16_t len;
8378 
8379 	len = sizeof(*cmd);
8380 	buf = wmi_buf_alloc(wma_handle->wmi_handle, len);
8381 	if (!buf)
8382 		return QDF_STATUS_E_NOMEM;
8383 
8384 	cmd = (WMI_WOW_HOSTWAKEUP_GPIO_CMD_FIXED_PARAM *)wmi_buf_data(buf);
8385 	qdf_mem_zero(cmd, len);
8386 
8387 	WMITLV_SET_HDR(&cmd->tlv_header,
8388 		WMITLV_TAG_HOSTWAKEUP_GPIO_CMD_FIXED_PARAM,
8389 		WMITLV_GET_STRUCT_TLVLEN(
8390 			WMI_WOW_HOSTWAKEUP_GPIO_CMD_FIXED_PARAM));
8391 
8392 	cmd->enable = wow_pulse_cmd->wow_pulse_enable;
8393 	cmd->pin = wow_pulse_cmd->wow_pulse_pin;
8394 	cmd->interval_low = wow_pulse_cmd->wow_pulse_interval_low;
8395 	cmd->interval_high = wow_pulse_cmd->wow_pulse_interval_high;
8396 	cmd->repeat_cnt = wow_pulse_cmd->wow_pulse_repeat_count;
8397 	cmd->init_state = wow_pulse_cmd->wow_pulse_init_state;
8398 
8399 	if (wmi_unified_cmd_send(wma_handle->wmi_handle, buf, len,
8400 		WMI_WOW_HOSTWAKEUP_GPIO_PIN_PATTERN_CONFIG_CMDID)) {
8401 		wmi_buf_free(buf);
8402 		status = QDF_STATUS_E_FAILURE;
8403 	}
8404 
8405 	wma_debug("Exit");
8406 	return status;
8407 }
8408 
8409 #undef WMI_WOW_HOSTWAKEUP_GPIO_CMD_FIXED_PARAM
8410 #undef WMITLV_TAG_HOSTWAKEUP_GPIO_CMD_FIXED_PARAM
8411 #undef WMI_WOW_PULSE_REPEAT_CNT
8412 
8413 #else
wma_send_wow_pulse_cmd(tp_wma_handle wma_handle,struct wow_pulse_mode * wow_pulse_cmd)8414 static inline QDF_STATUS wma_send_wow_pulse_cmd(tp_wma_handle wma_handle,
8415 					struct wow_pulse_mode *wow_pulse_cmd)
8416 {
8417 	return QDF_STATUS_E_FAILURE;
8418 }
8419 #endif
8420 
8421 
8422 /**
8423  * wma_process_power_debug_stats_req() - Process the Chip Power stats collect
8424  * request and pass the Power stats request to Fw
8425  * @wma_handle: WMA handle
8426  *
8427  * Return: QDF_STATUS
8428  */
8429 #ifdef WLAN_POWER_DEBUG
wma_process_power_debug_stats_req(tp_wma_handle wma_handle)8430 static QDF_STATUS wma_process_power_debug_stats_req(tp_wma_handle wma_handle)
8431 {
8432 	wmi_pdev_get_chip_power_stats_cmd_fixed_param *cmd;
8433 	int32_t len;
8434 	wmi_buf_t buf;
8435 	uint8_t *buf_ptr;
8436 	int ret;
8437 
8438 	if (wma_validate_handle(wma_handle))
8439 		return QDF_STATUS_E_FAILURE;
8440 
8441 	len = sizeof(*cmd);
8442 	buf = wmi_buf_alloc(wma_handle->wmi_handle, len);
8443 	if (!buf)
8444 		return QDF_STATUS_E_NOMEM;
8445 
8446 	buf_ptr = (u_int8_t *) wmi_buf_data(buf);
8447 	cmd = (wmi_pdev_get_chip_power_stats_cmd_fixed_param *) buf_ptr;
8448 
8449 	WMITLV_SET_HDR(&cmd->tlv_header,
8450 		WMITLV_TAG_STRUC_wmi_get_chip_power_stats_cmd_fixed_param,
8451 		WMITLV_GET_STRUCT_TLVLEN(
8452 			wmi_pdev_get_chip_power_stats_cmd_fixed_param));
8453 	cmd->pdev_id = 0;
8454 
8455 	wma_debug("POWER_DEBUG_STATS - Get Request Params; Pdev id - %d",
8456 			cmd->pdev_id);
8457 	ret = wmi_unified_cmd_send(wma_handle->wmi_handle, buf, len,
8458 			WMI_PDEV_GET_CHIP_POWER_STATS_CMDID);
8459 	if (ret) {
8460 		wmi_buf_free(buf);
8461 		return QDF_STATUS_E_FAILURE;
8462 	}
8463 	return QDF_STATUS_SUCCESS;
8464 }
8465 #else
wma_process_power_debug_stats_req(tp_wma_handle wma_handle)8466 static QDF_STATUS wma_process_power_debug_stats_req(tp_wma_handle wma_handle)
8467 {
8468 	return QDF_STATUS_SUCCESS;
8469 }
8470 #endif
8471 #ifdef WLAN_FEATURE_BEACON_RECEPTION_STATS
wma_process_beacon_debug_stats_req(tp_wma_handle wma_handle,uint32_t * vdev_id)8472 static QDF_STATUS wma_process_beacon_debug_stats_req(tp_wma_handle wma_handle,
8473 						     uint32_t *vdev_id)
8474 {
8475 	wmi_vdev_get_bcn_recv_stats_cmd_fixed_param *cmd;
8476 	int32_t len;
8477 	wmi_buf_t buf;
8478 	uint8_t *buf_ptr;
8479 	int ret;
8480 
8481 	wma_debug("Enter");
8482 	if (wma_validate_handle(wma_handle))
8483 		return QDF_STATUS_E_FAILURE;
8484 
8485 	len = sizeof(*cmd);
8486 	buf = wmi_buf_alloc(wma_handle->wmi_handle, len);
8487 	if (!buf)
8488 		return QDF_STATUS_E_NOMEM;
8489 
8490 	buf_ptr = (u_int8_t *)wmi_buf_data(buf);
8491 	cmd = (wmi_vdev_get_bcn_recv_stats_cmd_fixed_param *)buf_ptr;
8492 
8493 	WMITLV_SET_HDR(&cmd->tlv_header,
8494 		WMITLV_TAG_STRUC_wmi_get_bcn_recv_stats_fixed_param,
8495 		WMITLV_GET_STRUCT_TLVLEN(
8496 			wmi_vdev_get_bcn_recv_stats_cmd_fixed_param));
8497 	cmd->vdev_id = *vdev_id;
8498 
8499 	wma_debug("BEACON_DEBUG_STATS - Get Request Params; vdev id - %d",
8500 		 cmd->vdev_id);
8501 	ret = wmi_unified_cmd_send(wma_handle->wmi_handle, buf, len,
8502 				   WMI_VDEV_GET_BCN_RECEPTION_STATS_CMDID);
8503 	if (ret) {
8504 		wmi_buf_free(buf);
8505 		return QDF_STATUS_E_FAILURE;
8506 	}
8507 
8508 	wma_debug("Exit");
8509 	return QDF_STATUS_SUCCESS;
8510 }
8511 #else
wma_process_beacon_debug_stats_req(tp_wma_handle wma_handle,uint32_t * vdev_id)8512 static QDF_STATUS wma_process_beacon_debug_stats_req(tp_wma_handle wma_handle,
8513 						     uint32_t *vdev_id)
8514 {
8515 	return QDF_STATUS_SUCCESS;
8516 }
8517 #endif
8518 
8519 /**
8520  * wma_set_arp_req_stats() - process set arp stats request command to fw
8521  * @handle: WMA handle
8522  * @req_buf: set srp stats request buffer
8523  *
8524  * Return: None
8525  */
wma_set_arp_req_stats(WMA_HANDLE handle,struct set_arp_stats_params * req_buf)8526 static void wma_set_arp_req_stats(WMA_HANDLE handle,
8527 				  struct set_arp_stats_params *req_buf)
8528 {
8529 	QDF_STATUS status;
8530 	struct set_arp_stats *arp_stats;
8531 	tp_wma_handle wma_handle = (tp_wma_handle) handle;
8532 	struct wlan_objmgr_vdev *vdev;
8533 	struct wmi_unified *wmi_handle;
8534 
8535 	if (wma_validate_handle(wma_handle))
8536 		return;
8537 
8538 	wmi_handle = wma_handle->wmi_handle;
8539 	if (wmi_validate_handle(wmi_handle))
8540 		return;
8541 
8542 	if (!wma_is_vdev_valid(req_buf->vdev_id)) {
8543 		wma_err("vdev id:%d is not active", req_buf->vdev_id);
8544 		return;
8545 	}
8546 
8547 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(wma_handle->psoc,
8548 						    req_buf->vdev_id,
8549 						    WLAN_LEGACY_WMA_ID);
8550 	if (!vdev) {
8551 		wma_err("Can't get vdev by vdev_id:%d", req_buf->vdev_id);
8552 		return;
8553 	}
8554 
8555 	if (!wma_is_vdev_up(req_buf->vdev_id)) {
8556 		wma_debug("vdev id:%d is not started", req_buf->vdev_id);
8557 		goto release_ref;
8558 	}
8559 
8560 	arp_stats = (struct set_arp_stats *)req_buf;
8561 	status = wmi_unified_set_arp_stats_req(wmi_handle, arp_stats);
8562 	if (QDF_IS_STATUS_ERROR(status))
8563 		wma_err("failed to set arp stats to FW");
8564 
8565 release_ref:
8566 	wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_WMA_ID);
8567 }
8568 
8569 /**
8570  * wma_get_arp_req_stats() - process get arp stats request command to fw
8571  * @wma_handle: WMA handle
8572  * @req_buf: get srp stats request buffer
8573  *
8574  * Return: None
8575  */
wma_get_arp_req_stats(WMA_HANDLE handle,struct get_arp_stats_params * req_buf)8576 static void wma_get_arp_req_stats(WMA_HANDLE handle,
8577 				  struct get_arp_stats_params *req_buf)
8578 {
8579 	QDF_STATUS status;
8580 	struct get_arp_stats *arp_stats;
8581 	tp_wma_handle wma_handle = (tp_wma_handle) handle;
8582 	struct wmi_unified *wmi_handle;
8583 
8584 	if (wma_validate_handle(wma_handle))
8585 		return;
8586 
8587 	wmi_handle = wma_handle->wmi_handle;
8588 	if (wmi_validate_handle(wmi_handle))
8589 		return;
8590 
8591 	if (!wma_is_vdev_valid(req_buf->vdev_id)) {
8592 		wma_err("vdev id:%d is not active", req_buf->vdev_id);
8593 		return;
8594 	}
8595 
8596 	arp_stats = (struct get_arp_stats *)req_buf;
8597 	status = wmi_unified_get_arp_stats_req(wmi_handle, arp_stats);
8598 	if (QDF_IS_STATUS_ERROR(status))
8599 		wma_err("failed to send get arp stats to FW");
8600 }
8601 
8602 /**
8603  * wma_set_del_pmkid_cache() - API to set/delete PMKID cache entry in fw
8604  * @handle: WMA handle
8605  * @pmk_cache: PMK cache entry
8606  *
8607  * Return: None
8608  */
wma_set_del_pmkid_cache(WMA_HANDLE handle,struct wmi_unified_pmk_cache * pmk_cache)8609 static void wma_set_del_pmkid_cache(WMA_HANDLE handle,
8610 				    struct wmi_unified_pmk_cache *pmk_cache)
8611 {
8612 	QDF_STATUS status;
8613 	tp_wma_handle wma_handle = (tp_wma_handle) handle;
8614 	struct wmi_unified *wmi_handle;
8615 
8616 	if (wma_validate_handle(wma_handle))
8617 		return;
8618 
8619 	wmi_handle = wma_handle->wmi_handle;
8620 	if (wmi_validate_handle(wmi_handle))
8621 		return;
8622 
8623 	status = wmi_unified_set_del_pmkid_cache(wmi_handle, pmk_cache);
8624 	if (QDF_IS_STATUS_ERROR(status))
8625 		wma_err("failed to send set/del pmkid cmd to fw");
8626 }
8627 
8628 /**
8629  * wma_send_invoke_neighbor_report() - API to send invoke neighbor report
8630  * command to fw
8631  *
8632  * @handle: WMA handle
8633  * @params: Pointer to invoke neighbor report params
8634  *
8635  * Return: None
8636  */
8637 static
wma_send_invoke_neighbor_report(WMA_HANDLE handle,struct wmi_invoke_neighbor_report_params * params)8638 void wma_send_invoke_neighbor_report(WMA_HANDLE handle,
8639 			struct wmi_invoke_neighbor_report_params *params)
8640 {
8641 	QDF_STATUS status;
8642 	tp_wma_handle wma_handle = (tp_wma_handle) handle;
8643 	struct wmi_unified *wmi_handle;
8644 
8645 	if (wma_validate_handle(wma_handle))
8646 		return;
8647 
8648 	wmi_handle = wma_handle->wmi_handle;
8649 	if (wmi_validate_handle(wmi_handle))
8650 		return;
8651 
8652 	status = wmi_unified_invoke_neighbor_report_cmd(wmi_handle, params);
8653 
8654 	if (status != QDF_STATUS_SUCCESS)
8655 		wma_err("failed to send invoke neighbor report command");
8656 }
8657 
wma_set_rx_reorder_timeout_val(tp_wma_handle wma_handle,struct sir_set_rx_reorder_timeout_val * reorder_timeout)8658 QDF_STATUS wma_set_rx_reorder_timeout_val(tp_wma_handle wma_handle,
8659 	struct sir_set_rx_reorder_timeout_val *reorder_timeout)
8660 {
8661 	wmi_pdev_set_reorder_timeout_val_cmd_fixed_param *cmd;
8662 	uint32_t len;
8663 	wmi_buf_t buf;
8664 	int ret;
8665 
8666 	if (!reorder_timeout) {
8667 		wma_err("invalid pointer");
8668 		return QDF_STATUS_E_INVAL;
8669 	}
8670 
8671 	if (wma_validate_handle(wma_handle))
8672 		return QDF_STATUS_E_INVAL;
8673 
8674 	len = sizeof(*cmd);
8675 	buf = wmi_buf_alloc(wma_handle->wmi_handle, len);
8676 	if (!buf)
8677 		return QDF_STATUS_E_NOMEM;
8678 
8679 	cmd = (wmi_pdev_set_reorder_timeout_val_cmd_fixed_param *)
8680 		wmi_buf_data(buf);
8681 
8682 	WMITLV_SET_HDR(&cmd->tlv_header,
8683 	WMITLV_TAG_STRUC_wmi_pdev_set_reorder_timeout_val_cmd_fixed_param,
8684 	WMITLV_GET_STRUCT_TLVLEN(wmi_pdev_set_reorder_timeout_val_cmd_fixed_param));
8685 
8686 	memcpy(cmd->rx_timeout_pri, reorder_timeout->rx_timeout_pri,
8687 		sizeof(reorder_timeout->rx_timeout_pri));
8688 
8689 	wma_debug("rx aggr record timeout: VO: %d, VI: %d, BE: %d, BK: %d",
8690 		cmd->rx_timeout_pri[0], cmd->rx_timeout_pri[1],
8691 		cmd->rx_timeout_pri[2], cmd->rx_timeout_pri[3]);
8692 
8693 	ret = wmi_unified_cmd_send(wma_handle->wmi_handle, buf, len,
8694 			WMI_PDEV_SET_REORDER_TIMEOUT_VAL_CMDID);
8695 	if (ret) {
8696 		wmi_buf_free(buf);
8697 		return QDF_STATUS_E_FAILURE;
8698 	}
8699 
8700 	return QDF_STATUS_SUCCESS;
8701 }
8702 
wma_set_rx_blocksize(tp_wma_handle wma_handle,struct sir_peer_set_rx_blocksize * peer_rx_blocksize)8703 QDF_STATUS wma_set_rx_blocksize(tp_wma_handle wma_handle,
8704 	struct sir_peer_set_rx_blocksize *peer_rx_blocksize)
8705 {
8706 	wmi_peer_set_rx_blocksize_cmd_fixed_param *cmd;
8707 	int32_t len;
8708 	wmi_buf_t buf;
8709 	u_int8_t *buf_ptr;
8710 	int ret;
8711 
8712 	if (!peer_rx_blocksize) {
8713 		wma_err("invalid pointer");
8714 		return QDF_STATUS_E_INVAL;
8715 	}
8716 
8717 	if (wma_validate_handle(wma_handle))
8718 		return QDF_STATUS_E_INVAL;
8719 
8720 	len = sizeof(*cmd);
8721 	buf = wmi_buf_alloc(wma_handle->wmi_handle, len);
8722 	if (!buf)
8723 		return QDF_STATUS_E_NOMEM;
8724 
8725 	buf_ptr = (u_int8_t *) wmi_buf_data(buf);
8726 	cmd = (wmi_peer_set_rx_blocksize_cmd_fixed_param *) buf_ptr;
8727 
8728 	WMITLV_SET_HDR(&cmd->tlv_header,
8729 	WMITLV_TAG_STRUC_wmi_peer_set_rx_blocksize_cmd_fixed_param,
8730 	WMITLV_GET_STRUCT_TLVLEN(wmi_peer_set_rx_blocksize_cmd_fixed_param));
8731 
8732 	cmd->vdev_id = peer_rx_blocksize->vdev_id;
8733 	cmd->rx_block_ack_win_limit =
8734 		peer_rx_blocksize->rx_block_ack_win_limit;
8735 	WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_rx_blocksize->peer_macaddr.bytes,
8736 		&cmd->peer_macaddr);
8737 
8738 	wma_debug("rx aggr blocksize: %d", cmd->rx_block_ack_win_limit);
8739 
8740 	ret = wmi_unified_cmd_send(wma_handle->wmi_handle, buf, len,
8741 			WMI_PEER_SET_RX_BLOCKSIZE_CMDID);
8742 	if (ret) {
8743 		wmi_buf_free(buf);
8744 		return QDF_STATUS_E_FAILURE;
8745 	}
8746 
8747 	return QDF_STATUS_SUCCESS;
8748 }
8749 
wma_get_chain_rssi(tp_wma_handle wma_handle,struct get_chain_rssi_req_params * req_params)8750 QDF_STATUS wma_get_chain_rssi(tp_wma_handle wma_handle,
8751 		struct get_chain_rssi_req_params *req_params)
8752 {
8753 	wmi_pdev_div_get_rssi_antid_fixed_param *cmd;
8754 	wmi_buf_t wmi_buf;
8755 	uint32_t len = sizeof(wmi_pdev_div_get_rssi_antid_fixed_param);
8756 	u_int8_t *buf_ptr;
8757 
8758 	if (wma_validate_handle(wma_handle))
8759 		return QDF_STATUS_E_INVAL;
8760 
8761 	wmi_buf = wmi_buf_alloc(wma_handle->wmi_handle, len);
8762 	if (!wmi_buf)
8763 		return QDF_STATUS_E_NOMEM;
8764 
8765 	buf_ptr = (u_int8_t *)wmi_buf_data(wmi_buf);
8766 
8767 	cmd = (wmi_pdev_div_get_rssi_antid_fixed_param *)buf_ptr;
8768 	WMITLV_SET_HDR(&cmd->tlv_header,
8769 		WMITLV_TAG_STRUC_wmi_pdev_div_get_rssi_antid_fixed_param,
8770 		WMITLV_GET_STRUCT_TLVLEN(
8771 		wmi_pdev_div_get_rssi_antid_fixed_param));
8772 	cmd->pdev_id = 0;
8773 	WMI_CHAR_ARRAY_TO_MAC_ADDR(req_params->peer_macaddr.bytes,
8774 				&cmd->macaddr);
8775 
8776 	if (wmi_unified_cmd_send(wma_handle->wmi_handle, wmi_buf, len,
8777 				 WMI_PDEV_DIV_GET_RSSI_ANTID_CMDID)) {
8778 		wmi_buf_free(wmi_buf);
8779 		return QDF_STATUS_E_FAILURE;
8780 	}
8781 
8782 	return QDF_STATUS_SUCCESS;
8783 }
8784 
8785 #if defined(WLAN_FEATURE_FILS_SK)
8786 /**
8787  * wma_roam_scan_send_hlp() - API to send HLP IE info to fw
8788  * @wma_handle: WMA handle
8789  * @req: HLP params
8790  *
8791  * Return: QDF_STATUS
8792  */
wma_roam_scan_send_hlp(tp_wma_handle wma_handle,struct hlp_params * req)8793 static QDF_STATUS wma_roam_scan_send_hlp(tp_wma_handle wma_handle,
8794 					 struct hlp_params *req)
8795 {
8796 	struct hlp_params *params;
8797 	QDF_STATUS status;
8798 
8799 	params = qdf_mem_malloc(sizeof(*params));
8800 	if (!params)
8801 		return QDF_STATUS_E_NOMEM;
8802 
8803 	params->vdev_id = req->vdev_id;
8804 	params->hlp_ie_len = req->hlp_ie_len;
8805 	qdf_mem_copy(params->hlp_ie, req->hlp_ie, req->hlp_ie_len);
8806 	status = wmi_unified_roam_send_hlp_cmd(wma_handle->wmi_handle, params);
8807 
8808 	wma_debug("Send HLP status %d vdev id %d", status, params->vdev_id);
8809 	qdf_trace_hex_dump(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG,
8810 				params->hlp_ie, 10);
8811 
8812 	qdf_mem_free(params);
8813 	return status;
8814 }
8815 #else
wma_roam_scan_send_hlp(tp_wma_handle wma_handle,struct hlp_params * req)8816 static QDF_STATUS wma_roam_scan_send_hlp(tp_wma_handle wma_handle,
8817 					 struct hlp_params *req)
8818 {
8819 	return QDF_STATUS_SUCCESS;
8820 }
8821 #endif
8822 
8823 /**
8824  * wma_process_limit_off_chan() - set limit off channel parameters
8825  * @wma_handle: pointer to wma handle
8826  * @param: pointer to sir_limit_off_chan
8827  *
8828  * Return: QDF_STATUS_SUCCESS for success or error code.
8829  */
wma_process_limit_off_chan(tp_wma_handle wma_handle,struct sir_limit_off_chan * param)8830 static QDF_STATUS wma_process_limit_off_chan(tp_wma_handle wma_handle,
8831 	struct sir_limit_off_chan *param)
8832 {
8833 	int32_t err;
8834 	struct wmi_limit_off_chan_param limit_off_chan_param;
8835 
8836 	if (param->vdev_id >= wma_handle->max_bssid) {
8837 		wma_err("Invalid vdev_id: %d", param->vdev_id);
8838 		return QDF_STATUS_E_INVAL;
8839 	}
8840 	if (!wma_is_vdev_up(param->vdev_id)) {
8841 		wma_debug("vdev %d is not up skipping limit_off_chan_param",
8842 			 param->vdev_id);
8843 		return QDF_STATUS_E_INVAL;
8844 	}
8845 
8846 	limit_off_chan_param.vdev_id = param->vdev_id;
8847 	limit_off_chan_param.status = param->is_tos_active;
8848 	limit_off_chan_param.max_offchan_time = param->max_off_chan_time;
8849 	limit_off_chan_param.rest_time = param->rest_time;
8850 	limit_off_chan_param.skip_dfs_chans = param->skip_dfs_chans;
8851 
8852 	err = wmi_unified_send_limit_off_chan_cmd(wma_handle->wmi_handle,
8853 			&limit_off_chan_param);
8854 	if (err) {
8855 		wma_err("failed to set limit off chan cmd");
8856 		return QDF_STATUS_E_FAILURE;
8857 	}
8858 
8859 	return QDF_STATUS_SUCCESS;
8860 }
8861 
wma_process_obss_color_collision_req(tp_wma_handle wma_handle,struct wmi_obss_color_collision_cfg_param * cfg)8862 static QDF_STATUS wma_process_obss_color_collision_req(tp_wma_handle wma_handle,
8863 		struct wmi_obss_color_collision_cfg_param *cfg)
8864 {
8865 	QDF_STATUS status;
8866 
8867 	if (cfg->vdev_id >= wma_handle->max_bssid) {
8868 		wma_err("Invalid vdev_id: %d", cfg->vdev_id);
8869 		return QDF_STATUS_E_INVAL;
8870 	}
8871 	if (!wma_is_vdev_up(cfg->vdev_id)) {
8872 		wma_err("vdev %d is not up skipping obss color collision req",
8873 			 cfg->vdev_id);
8874 		return QDF_STATUS_E_INVAL;
8875 	}
8876 
8877 	status = wmi_unified_send_obss_color_collision_cfg_cmd(wma_handle->
8878 							       wmi_handle, cfg);
8879 	if (QDF_IS_STATUS_ERROR(status))
8880 		wma_err("Failed to send obss color collision cfg");
8881 
8882 	return status;
8883 }
8884 
8885 /**
8886  * wma_send_obss_detection_cfg() - send obss detection cfg to firmware
8887  * @wma_handle: pointer to wma handle
8888  * @cfg: obss detection configuration
8889  *
8890  * Send obss detection configuration to firmware.
8891  *
8892  * Return: None
8893  */
wma_send_obss_detection_cfg(tp_wma_handle wma_handle,struct wmi_obss_detection_cfg_param * cfg)8894 static void wma_send_obss_detection_cfg(tp_wma_handle wma_handle,
8895 					struct wmi_obss_detection_cfg_param
8896 					*cfg)
8897 {
8898 	QDF_STATUS status;
8899 
8900 	if (cfg->vdev_id >= wma_handle->max_bssid) {
8901 		wma_err("Invalid vdev_id: %d", cfg->vdev_id);
8902 		return;
8903 	}
8904 	if (!wma_is_vdev_up(cfg->vdev_id)) {
8905 		wma_err("vdev %d is not up skipping obss detection req",
8906 			 cfg->vdev_id);
8907 		return;
8908 	}
8909 
8910 	status = wmi_unified_send_obss_detection_cfg_cmd(wma_handle->wmi_handle,
8911 							 cfg);
8912 	if (QDF_IS_STATUS_ERROR(status))
8913 		wma_err("Failed to send obss detection cfg");
8914 
8915 	return;
8916 }
8917 
8918 #ifdef WLAN_FEATURE_MOTION_DETECTION
8919 /**
8920  * wma_motion_det_host_event_handler - motion detection event handler
8921  * @handle: WMA global handle
8922  * @event: motion detection event
8923  * @len: Length of cmd
8924  *
8925  * Call motion detection event callback handler
8926  *
8927  * Return: 0 on success, else error on failure
8928  */
wma_motion_det_host_event_handler(void * handle,uint8_t * event,uint32_t len)8929 int wma_motion_det_host_event_handler(void *handle, uint8_t *event,
8930 				      uint32_t len)
8931 {
8932 	wmi_motion_det_event *motion_det_event_hdr;
8933 	WMI_MOTION_DET_HOST_EVENTID_param_tlvs *param_buf =
8934 			(WMI_MOTION_DET_HOST_EVENTID_param_tlvs *)event;
8935 	struct sir_md_evt *md_event;
8936 	struct mac_context *pmac = (struct mac_context *)cds_get_context(
8937 				    QDF_MODULE_ID_PE);
8938 
8939 	if (!param_buf) {
8940 		wma_err("Invalid motion det host event buffer");
8941 		return -EINVAL;
8942 	}
8943 
8944 	if (!pmac || !pmac->sme.md_host_evt_cb) {
8945 		wma_err("Invalid motion detect callback");
8946 		return -EINVAL;
8947 	}
8948 
8949 	motion_det_event_hdr = param_buf->fixed_param;
8950 	wma_alert("motion detect host event received, vdev_id=%d, status=%d",
8951 		 motion_det_event_hdr->vdev_id, motion_det_event_hdr->status);
8952 
8953 	md_event = qdf_mem_malloc(sizeof(*md_event));
8954 	if (!md_event)
8955 		return -ENOMEM;
8956 
8957 	md_event->vdev_id = motion_det_event_hdr->vdev_id;
8958 	md_event->status = motion_det_event_hdr->status;
8959 
8960 	pmac->sme.md_host_evt_cb(pmac->sme.md_ctx, md_event);
8961 
8962 	qdf_mem_free(md_event);
8963 	return 0;
8964 }
8965 
8966 /**
8967  * wma_motion_det_base_line_host_event_handler - md baselining event handler
8968  * @handle: WMA global handle
8969  * @event: motion detection baselining event
8970  * @len: Length of cmd
8971  *
8972  * Return: 0 on success, else error on failure
8973  */
wma_motion_det_base_line_host_event_handler(void * handle,uint8_t * event,uint32_t len)8974 int wma_motion_det_base_line_host_event_handler(void *handle,
8975 						uint8_t *event, uint32_t len)
8976 {
8977 	wmi_motion_det_base_line_event *motion_det_base_line_event_hdr;
8978 	WMI_MOTION_DET_BASE_LINE_HOST_EVENTID_param_tlvs *param_buf =
8979 		(WMI_MOTION_DET_BASE_LINE_HOST_EVENTID_param_tlvs *)event;
8980 	struct sir_md_bl_evt *md_bl_event;
8981 	struct mac_context *pmac = (struct mac_context *)cds_get_context(
8982 				    QDF_MODULE_ID_PE);
8983 
8984 	if (!param_buf) {
8985 		wma_err("Invalid motion detection base line event buffer");
8986 		return -EINVAL;
8987 	}
8988 
8989 	if (!pmac || !pmac->sme.md_bl_evt_cb) {
8990 		wma_err("Invalid motion detection base line callback");
8991 		return -EINVAL;
8992 	}
8993 
8994 	motion_det_base_line_event_hdr = param_buf->fixed_param;
8995 	wma_alert("motion detection base line event received, vdev_id=%d",
8996 		 motion_det_base_line_event_hdr->vdev_id);
8997 	wma_alert("baseline_value=%d bl_max_corr_resv=%d bl_min_corr_resv=%d",
8998 		 motion_det_base_line_event_hdr->bl_baseline_value,
8999 		 motion_det_base_line_event_hdr->bl_max_corr_reserved,
9000 		 motion_det_base_line_event_hdr->bl_min_corr_reserved);
9001 
9002 	md_bl_event = qdf_mem_malloc(sizeof(*md_bl_event));
9003 	if (!md_bl_event)
9004 		return -ENOMEM;
9005 
9006 	md_bl_event->vdev_id = motion_det_base_line_event_hdr->vdev_id;
9007 	md_bl_event->bl_baseline_value =
9008 			motion_det_base_line_event_hdr->bl_baseline_value;
9009 	md_bl_event->bl_max_corr_reserved =
9010 			motion_det_base_line_event_hdr->bl_max_corr_reserved;
9011 	md_bl_event->bl_min_corr_reserved =
9012 			motion_det_base_line_event_hdr->bl_min_corr_reserved;
9013 
9014 	pmac->sme.md_bl_evt_cb(pmac->sme.md_ctx, md_bl_event);
9015 
9016 	qdf_mem_free(md_bl_event);
9017 	return 0;
9018 }
9019 
9020 /**
9021  * wma_set_motion_det_config - Sends motion detection configuration wmi cmd
9022  * @wma_handle: WMA global handle
9023  * @motion_det_cfg: motion detection configuration
9024  *
9025  * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_ERROR on error
9026  */
wma_set_motion_det_config(tp_wma_handle wma_handle,struct sme_motion_det_cfg * motion_det_cfg)9027 static QDF_STATUS wma_set_motion_det_config(
9028 				tp_wma_handle wma_handle,
9029 				struct sme_motion_det_cfg *motion_det_cfg)
9030 {
9031 	wmi_motion_det_config_params_cmd_fixed_param *cmd;
9032 	wmi_buf_t buf;
9033 	int err;
9034 
9035 	buf = wmi_buf_alloc(wma_handle->wmi_handle, sizeof(*cmd));
9036 	if (!buf)
9037 		return QDF_STATUS_E_NOMEM;
9038 
9039 	cmd = (wmi_motion_det_config_params_cmd_fixed_param *)wmi_buf_data(buf);
9040 	qdf_mem_zero(cmd, sizeof(*cmd));
9041 
9042 	WMITLV_SET_HDR(
9043 		&cmd->tlv_header,
9044 		WMITLV_TAG_STRUC_wmi_motion_det_config_params_cmd_fixed_param,
9045 		WMITLV_GET_STRUCT_TLVLEN(
9046 			wmi_motion_det_config_params_cmd_fixed_param));
9047 	cmd->vdev_id = motion_det_cfg->vdev_id;
9048 	cmd->time_t1 = motion_det_cfg->time_t1;
9049 	cmd->time_t2 = motion_det_cfg->time_t2;
9050 	cmd->n1 = motion_det_cfg->n1;
9051 	cmd->n2 = motion_det_cfg->n2;
9052 	cmd->time_t1_gap = motion_det_cfg->time_t1_gap;
9053 	cmd->time_t2_gap = motion_det_cfg->time_t2_gap;
9054 	cmd->coarse_K = motion_det_cfg->coarse_K;
9055 	cmd->fine_K = motion_det_cfg->fine_K;
9056 	cmd->coarse_Q = motion_det_cfg->coarse_Q;
9057 	cmd->fine_Q = motion_det_cfg->fine_Q;
9058 	cmd->md_coarse_thr_high = motion_det_cfg->md_coarse_thr_high;
9059 	cmd->md_fine_thr_high = motion_det_cfg->md_fine_thr_high;
9060 	cmd->md_coarse_thr_low = motion_det_cfg->md_coarse_thr_low;
9061 	cmd->md_fine_thr_low = motion_det_cfg->md_fine_thr_low;
9062 
9063 	err = wmi_unified_cmd_send(wma_handle->wmi_handle, buf, sizeof(*cmd),
9064 				   WMI_MOTION_DET_CONFIG_PARAM_CMDID);
9065 	if (err) {
9066 		wmi_buf_free(buf);
9067 		return QDF_STATUS_E_FAILURE;
9068 	}
9069 	wma_nofl_alert("Set motion_det_config to vdevId %d\n"
9070 		 "time_t1 %d\n"
9071 		 "time_t2 %d\n"
9072 		 "n1 %d\n"
9073 		 "n2 %d\n"
9074 		 "time_t1_gap %d\n"
9075 		 "time_t2_gap %d\n"
9076 		 "coarse_K %d\n"
9077 		 "fine_K %d\n"
9078 		 "coarse_Q %d\n"
9079 		 "fine_Q %d\n"
9080 		 "md_coarse_thr_high %d\n"
9081 		 "md_fine_thr_high %d\n"
9082 		 "md_coarse_thr_low %d\n"
9083 		 "md_fine_thr_low %d\n",
9084 		 motion_det_cfg->vdev_id,
9085 		 motion_det_cfg->time_t1,
9086 		 motion_det_cfg->time_t2,
9087 		 motion_det_cfg->n1,
9088 		 motion_det_cfg->n2,
9089 		 motion_det_cfg->time_t1_gap,
9090 		 motion_det_cfg->time_t2_gap,
9091 		 motion_det_cfg->coarse_K,
9092 		 motion_det_cfg->fine_K,
9093 		 motion_det_cfg->coarse_Q,
9094 		 motion_det_cfg->fine_Q,
9095 		 motion_det_cfg->md_coarse_thr_high,
9096 		 motion_det_cfg->md_fine_thr_high,
9097 		 motion_det_cfg->md_coarse_thr_low,
9098 		 motion_det_cfg->md_fine_thr_low);
9099 	return QDF_STATUS_SUCCESS;
9100 }
9101 
9102 /**
9103  * wma_set_motion_det_enable - Sends motion detection start/stop wmi cmd
9104  * @wma_handle: WMA global handle
9105  * @md_en: motion detection start/stop
9106  *
9107  * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_ERROR on error
9108  */
wma_set_motion_det_enable(tp_wma_handle wma_handle,struct sme_motion_det_en * md_en)9109 static QDF_STATUS wma_set_motion_det_enable(tp_wma_handle wma_handle,
9110 					    struct sme_motion_det_en *md_en)
9111 {
9112 	wmi_motion_det_start_stop_cmd_fixed_param *cmd;
9113 	wmi_buf_t buf;
9114 	int err;
9115 
9116 	buf = wmi_buf_alloc(wma_handle->wmi_handle, sizeof(*cmd));
9117 	if (!buf)
9118 		return QDF_STATUS_E_NOMEM;
9119 
9120 	cmd = (wmi_motion_det_start_stop_cmd_fixed_param *)wmi_buf_data(buf);
9121 	qdf_mem_zero(cmd, sizeof(*cmd));
9122 
9123 	WMITLV_SET_HDR(
9124 		&cmd->tlv_header,
9125 		WMITLV_TAG_STRUC_wmi_motion_det_start_stop_cmd_fixed_param,
9126 		WMITLV_GET_STRUCT_TLVLEN(
9127 			wmi_motion_det_start_stop_cmd_fixed_param));
9128 	cmd->vdev_id = md_en->vdev_id;
9129 	cmd->enable = md_en->enable;
9130 
9131 	err = wmi_unified_cmd_send(wma_handle->wmi_handle, buf, sizeof(*cmd),
9132 				   WMI_MOTION_DET_START_STOP_CMDID);
9133 	if (err) {
9134 		wmi_buf_free(buf);
9135 		return QDF_STATUS_E_FAILURE;
9136 	}
9137 	wma_alert("Set motion_det_enable to vdevId %d %d", md_en->vdev_id,
9138 		 md_en->enable);
9139 	return QDF_STATUS_SUCCESS;
9140 }
9141 
9142 /**
9143  * wma_set_motion_det_base_line_config - Sends md baselining cfg wmi cmd
9144  * @wma_handle: WMA global handle
9145  * @md_base_line_cfg: md baselining configuration
9146  *
9147  * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_ERROR on error
9148  */
wma_set_motion_det_base_line_config(tp_wma_handle wma_handle,struct sme_motion_det_base_line_cfg * md_base_line_cfg)9149 static QDF_STATUS wma_set_motion_det_base_line_config(
9150 		tp_wma_handle wma_handle,
9151 		struct sme_motion_det_base_line_cfg *md_base_line_cfg)
9152 {
9153 	wmi_motion_det_base_line_config_params_cmd_fixed_param *cmd;
9154 	wmi_buf_t buf;
9155 	int err;
9156 
9157 	buf = wmi_buf_alloc(wma_handle->wmi_handle, sizeof(*cmd));
9158 	if (!buf)
9159 		return QDF_STATUS_E_NOMEM;
9160 
9161 	cmd = (wmi_motion_det_base_line_config_params_cmd_fixed_param *)
9162 		wmi_buf_data(buf);
9163 	qdf_mem_zero(cmd, sizeof(*cmd));
9164 
9165 	WMITLV_SET_HDR(
9166 	&cmd->tlv_header,
9167 	WMITLV_TAG_STRUC_wmi_motion_det_base_line_config_params_cmd_fixed_param,
9168 	WMITLV_GET_STRUCT_TLVLEN(
9169 		wmi_motion_det_base_line_config_params_cmd_fixed_param));
9170 
9171 	cmd->vdev_id = md_base_line_cfg->vdev_id;
9172 	cmd->bl_time_t = md_base_line_cfg->bl_time_t;
9173 	cmd->bl_packet_gap = md_base_line_cfg->bl_packet_gap;
9174 	cmd->bl_n = md_base_line_cfg->bl_n;
9175 	cmd->bl_num_meas = md_base_line_cfg->bl_num_meas;
9176 
9177 	err = wmi_unified_cmd_send(wma_handle->wmi_handle, buf,	sizeof(*cmd),
9178 				   WMI_MOTION_DET_BASE_LINE_CONFIG_PARAM_CMDID);
9179 	if (err) {
9180 		wmi_buf_free(buf);
9181 		return QDF_STATUS_E_FAILURE;
9182 	}
9183 	wma_nofl_alert("Set motion_det_baseline_config to vdevId %d\n"
9184 		 "bl_time_t %d\n"
9185 		 "bl_packet_gap %d\n"
9186 		 "bl_n %d\n"
9187 		 "bl_num_meas %d\n",
9188 		 md_base_line_cfg->vdev_id,
9189 		 md_base_line_cfg->bl_time_t,
9190 		 md_base_line_cfg->bl_packet_gap,
9191 		 md_base_line_cfg->bl_n,
9192 		 md_base_line_cfg->bl_num_meas);
9193 	return QDF_STATUS_SUCCESS;
9194 }
9195 
9196 /**
9197  * wma_set_motion_det_base_line_enable - Sends md baselining start/stop wmi cmd
9198  * @wma_handle: WMA global handle
9199  * @md_base_line_en: motion detection baselining start/stop
9200  *
9201  * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_ERROR on error
9202  */
wma_set_motion_det_base_line_enable(tp_wma_handle wma_handle,struct sme_motion_det_base_line_en * md_base_line_en)9203 static QDF_STATUS wma_set_motion_det_base_line_enable(
9204 			tp_wma_handle wma_handle,
9205 			struct sme_motion_det_base_line_en *md_base_line_en)
9206 {
9207 	wmi_motion_det_base_line_start_stop_cmd_fixed_param *cmd;
9208 	wmi_buf_t buf;
9209 	int err;
9210 
9211 	buf = wmi_buf_alloc(wma_handle->wmi_handle, sizeof(*cmd));
9212 	if (!buf)
9213 		return QDF_STATUS_E_NOMEM;
9214 
9215 	cmd = (wmi_motion_det_base_line_start_stop_cmd_fixed_param *)
9216 		wmi_buf_data(buf);
9217 	qdf_mem_zero(cmd, sizeof(*cmd));
9218 
9219 	WMITLV_SET_HDR(
9220 	&cmd->tlv_header,
9221 	WMITLV_TAG_STRUC_wmi_motion_det_base_line_start_stop_cmd_fixed_param,
9222 	WMITLV_GET_STRUCT_TLVLEN(
9223 		wmi_motion_det_base_line_start_stop_cmd_fixed_param));
9224 
9225 	cmd->vdev_id = md_base_line_en->vdev_id;
9226 	cmd->enable = md_base_line_en->enable;
9227 
9228 	err = wmi_unified_cmd_send(wma_handle->wmi_handle, buf, sizeof(*cmd),
9229 				   WMI_MOTION_DET_BASE_LINE_START_STOP_CMDID);
9230 	if (err) {
9231 		wmi_buf_free(buf);
9232 		return QDF_STATUS_E_FAILURE;
9233 	}
9234 	wma_alert("Set motion_det_base_line_enable to vdevId %d enable %d",
9235 		 md_base_line_en->vdev_id, md_base_line_en->enable);
9236 	return QDF_STATUS_SUCCESS;
9237 }
9238 #endif /* WLAN_FEATURE_MOTION_DETECTION */
9239 
9240 /**
9241  * wma_mc_process_msg() - process wma messages and call appropriate function.
9242  * @msg: message
9243  *
9244  * Return: QDF_SUCCESS for success otherwise failure
9245  */
wma_mc_process_msg(struct scheduler_msg * msg)9246 static QDF_STATUS wma_mc_process_msg(struct scheduler_msg *msg)
9247 {
9248 	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
9249 	tp_wma_handle wma_handle;
9250 
9251 	if (!msg) {
9252 		wma_err("msg is NULL");
9253 		QDF_ASSERT(0);
9254 		qdf_status = QDF_STATUS_E_INVAL;
9255 		goto end;
9256 	}
9257 
9258 	wma_nofl_debug("Handle msg %s(0x%x)",
9259 		       mac_trace_get_wma_msg_string(msg->type), msg->type);
9260 
9261 	wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
9262 	if (!wma_handle) {
9263 		QDF_ASSERT(0);
9264 		qdf_mem_free(msg->bodyptr);
9265 		qdf_status = QDF_STATUS_E_INVAL;
9266 		goto end;
9267 	}
9268 
9269 	switch (msg->type) {
9270 #ifdef FEATURE_WLAN_ESE
9271 	case WMA_TSM_STATS_REQ:
9272 		wma_debug("McThread: WMA_TSM_STATS_REQ");
9273 		wma_process_tsm_stats_req(wma_handle, (void *)msg->bodyptr);
9274 		break;
9275 #endif /* FEATURE_WLAN_ESE */
9276 	case WMA_UPDATE_CHAN_LIST_REQ:
9277 		wma_update_channel_list(wma_handle,
9278 					(tSirUpdateChanList *) msg->bodyptr);
9279 		qdf_mem_free(msg->bodyptr);
9280 		break;
9281 	case WMA_ADD_STA_REQ:
9282 		wma_add_sta(wma_handle, (tpAddStaParams) msg->bodyptr);
9283 		break;
9284 	case WMA_SEND_PEER_UNMAP_CONF:
9285 		wma_peer_unmap_conf_send(
9286 			wma_handle,
9287 			(struct send_peer_unmap_conf_params *)msg->bodyptr);
9288 		qdf_mem_free(msg->bodyptr);
9289 		break;
9290 	case WMA_DELETE_STA_REQ:
9291 		wma_delete_sta(wma_handle, (tpDeleteStaParams) msg->bodyptr);
9292 		break;
9293 	case WMA_DELETE_BSS_HO_FAIL_REQ:
9294 		wma_delete_bss_ho_fail(wma_handle, msg->bodyval);
9295 		break;
9296 	case WMA_DELETE_BSS_REQ:
9297 		wma_delete_bss(wma_handle, msg->bodyval);
9298 		break;
9299 	case WMA_UPDATE_EDCA_PROFILE_IND:
9300 		wma_process_update_edca_param_req(wma_handle,
9301 						  (tEdcaParams *) msg->bodyptr);
9302 		qdf_mem_free(msg->bodyptr);
9303 		break;
9304 	case WMA_SEND_BEACON_REQ:
9305 		wma_send_beacon(wma_handle, (tpSendbeaconParams) msg->bodyptr);
9306 		break;
9307 	case WMA_SEND_AP_VDEV_UP:
9308 		wma_set_ap_vdev_up(wma_handle, msg->bodyval);
9309 		break;
9310 	case WMA_SEND_PROBE_RSP_TMPL:
9311 		wma_send_probe_rsp_tmpl(wma_handle,
9312 					(tpSendProbeRespParams) msg->bodyptr);
9313 		qdf_mem_free(msg->bodyptr);
9314 		break;
9315 	case WMA_CLI_SET_CMD:
9316 		wma_process_cli_set_cmd(wma_handle,
9317 					(wma_cli_set_cmd_t *) msg->bodyptr);
9318 		qdf_mem_free(msg->bodyptr);
9319 		break;
9320 	case WMA_SET_PDEV_IE_REQ:
9321 		wma_process_set_pdev_ie_req(wma_handle,
9322 				(struct set_ie_param *)msg->bodyptr);
9323 		qdf_mem_free(msg->bodyptr);
9324 		break;
9325 #if !defined(REMOVE_PKT_LOG) && defined(FEATURE_PKTLOG)
9326 	case WMA_PKTLOG_ENABLE_REQ:
9327 		wma_pktlog_wmi_send_cmd(wma_handle,
9328 			(struct ath_pktlog_wmi_params *)msg->bodyptr);
9329 		qdf_mem_free(msg->bodyptr);
9330 		break;
9331 #endif /* REMOVE_PKT_LOG */
9332 	case WMA_ENABLE_UAPSD_REQ:
9333 		wma_enable_uapsd_mode(wma_handle,
9334 				      (tpEnableUapsdParams) msg->bodyptr);
9335 		qdf_mem_free(msg->bodyptr);
9336 		break;
9337 	case WMA_DISABLE_UAPSD_REQ:
9338 		wma_disable_uapsd_mode(wma_handle,
9339 				       (tpDisableUapsdParams) msg->bodyptr);
9340 		qdf_mem_free(msg->bodyptr);
9341 		break;
9342 	case WMA_SET_DTIM_PERIOD:
9343 		wma_set_dtim_period(wma_handle,
9344 				    (struct set_dtim_params *)msg->bodyptr);
9345 		qdf_mem_free(msg->bodyptr);
9346 		break;
9347 	case WMA_SET_TX_POWER_REQ:
9348 		wma_set_tx_power(wma_handle, (tpMaxTxPowerParams) msg->bodyptr);
9349 		break;
9350 	case WMA_SET_MAX_TX_POWER_REQ:
9351 		wma_set_max_tx_power(wma_handle,
9352 				     (tpMaxTxPowerParams) msg->bodyptr);
9353 		break;
9354 	case WMA_SET_KEEP_ALIVE:
9355 		wma_set_keepalive_req(wma_handle, msg->bodyptr);
9356 		break;
9357 #ifdef FEATURE_WLAN_ESE
9358 	case WMA_SET_PLM_REQ:
9359 		wma_config_plm(wma_handle, msg->bodyptr);
9360 		qdf_mem_free(msg->bodyptr);
9361 		break;
9362 #endif
9363 
9364 	case WMA_UPDATE_OP_MODE:
9365 		wma_process_update_opmode(wma_handle,
9366 					  (tUpdateVHTOpMode *) msg->bodyptr);
9367 		qdf_mem_free(msg->bodyptr);
9368 		break;
9369 	case WMA_UPDATE_RX_NSS:
9370 		wma_process_update_rx_nss(wma_handle,
9371 					  (tUpdateRxNss *) msg->bodyptr);
9372 		qdf_mem_free(msg->bodyptr);
9373 		break;
9374 	case WMA_UPDATE_MEMBERSHIP:
9375 		wma_process_update_membership(wma_handle,
9376 			(tUpdateMembership *) msg->bodyptr);
9377 		break;
9378 	case WMA_UPDATE_USERPOS:
9379 		wma_process_update_userpos(wma_handle,
9380 					   (tUpdateUserPos *) msg->bodyptr);
9381 		break;
9382 	case WMA_UPDATE_BEACON_IND:
9383 		wma_process_update_beacon_params(wma_handle,
9384 			(tUpdateBeaconParams *) msg->bodyptr);
9385 		qdf_mem_free(msg->bodyptr);
9386 		break;
9387 
9388 	case WMA_ADD_TS_REQ:
9389 		wma_add_ts_req(wma_handle, msg->bodyptr);
9390 		break;
9391 
9392 	case WMA_DEL_TS_REQ:
9393 		wma_del_ts_req(wma_handle, msg->bodyptr);
9394 		break;
9395 
9396 	case WMA_AGGR_QOS_REQ:
9397 		wma_aggr_qos_req(wma_handle, msg->bodyptr);
9398 		break;
9399 
9400 	case WMA_8023_MULTICAST_LIST_REQ:
9401 		wma_process_mcbc_set_filter_req(wma_handle,
9402 				(tpSirRcvFltMcAddrList) msg->bodyptr);
9403 		qdf_mem_free(msg->bodyptr);
9404 		break;
9405 
9406 	case WMA_ROAM_PRE_AUTH_STATUS:
9407 		wma_send_roam_preauth_status(wma_handle, msg->bodyptr);
9408 		qdf_mem_free(msg->bodyptr);
9409 		break;
9410 
9411 	case WMA_ROAM_SYNC_TIMEOUT:
9412 		wma_handle_roam_sync_timeout(wma_handle, msg->bodyptr);
9413 		qdf_mem_free(msg->bodyptr);
9414 		break;
9415 	case WMA_RATE_UPDATE_IND:
9416 		wma_process_rate_update_indicate(wma_handle,
9417 				(tSirRateUpdateInd *) msg->bodyptr);
9418 		break;
9419 
9420 #ifdef FEATURE_WLAN_TDLS
9421 	case WMA_UPDATE_TDLS_PEER_STATE:
9422 		wma_update_tdls_peer_state(wma_handle, msg->bodyptr);
9423 		break;
9424 #endif /* FEATURE_WLAN_TDLS */
9425 	case WMA_ADD_PERIODIC_TX_PTRN_IND:
9426 		wma_process_add_periodic_tx_ptrn_ind(wma_handle,
9427 				(tSirAddPeriodicTxPtrn *) msg->bodyptr);
9428 		qdf_mem_free(msg->bodyptr);
9429 		break;
9430 	case WMA_DEL_PERIODIC_TX_PTRN_IND:
9431 		wma_process_del_periodic_tx_ptrn_ind(wma_handle,
9432 				(tSirDelPeriodicTxPtrn *) msg->bodyptr);
9433 		qdf_mem_free(msg->bodyptr);
9434 		break;
9435 	case WMA_TX_POWER_LIMIT:
9436 		wma_process_tx_power_limits(wma_handle, msg->bodyptr);
9437 		qdf_mem_free(msg->bodyptr);
9438 		break;
9439 	case WMA_SEND_ADDBA_REQ:
9440 		wma_process_send_addba_req(wma_handle,
9441 				(struct send_add_ba_req *)msg->bodyptr);
9442 		break;
9443 
9444 #ifdef FEATURE_WLAN_CH_AVOID
9445 	case WMA_CH_AVOID_UPDATE_REQ:
9446 		wma_process_ch_avoid_update_req(wma_handle,
9447 				(tSirChAvoidUpdateReq *) msg->bodyptr);
9448 		qdf_mem_free(msg->bodyptr);
9449 		break;
9450 #endif /* FEATURE_WLAN_CH_AVOID */
9451 #ifdef FEATURE_WLAN_AUTO_SHUTDOWN
9452 	case WMA_SET_AUTO_SHUTDOWN_TIMER_REQ:
9453 		wma_set_auto_shutdown_timer_req(wma_handle, msg->bodyptr);
9454 		qdf_mem_free(msg->bodyptr);
9455 		break;
9456 #endif /* FEATURE_WLAN_AUTO_SHUTDOWN */
9457 	case WMA_DHCP_START_IND:
9458 	case WMA_DHCP_STOP_IND:
9459 		wma_process_dhcp_ind(wma_handle, (tAniDHCPInd *) msg->bodyptr);
9460 		qdf_mem_free(msg->bodyptr);
9461 		break;
9462 	case WMA_INIT_THERMAL_INFO_CMD:
9463 		wma_process_init_thermal_info(wma_handle,
9464 					      (t_thermal_mgmt *) msg->bodyptr);
9465 		qdf_mem_free(msg->bodyptr);
9466 		break;
9467 
9468 	case WMA_SET_THERMAL_LEVEL:
9469 		wma_process_set_thermal_level(wma_handle, msg->bodyval);
9470 		break;
9471 #ifdef CONFIG_HL_SUPPORT
9472 	case WMA_INIT_BAD_PEER_TX_CTL_INFO_CMD:
9473 		wma_process_init_bad_peer_tx_ctl_info(
9474 			wma_handle,
9475 			(struct t_bad_peer_txtcl_config *)msg->bodyptr);
9476 		qdf_mem_free(msg->bodyptr);
9477 			break;
9478 #endif
9479 	case WMA_SET_MIMOPS_REQ:
9480 		wma_process_set_mimops_req(wma_handle,
9481 					   (tSetMIMOPS *) msg->bodyptr);
9482 		qdf_mem_free(msg->bodyptr);
9483 		break;
9484 	case WMA_SET_SAP_INTRABSS_DIS:
9485 		wma_set_vdev_intrabss_fwd(wma_handle,
9486 					  (tDisableIntraBssFwd *) msg->bodyptr);
9487 		qdf_mem_free(msg->bodyptr);
9488 		break;
9489 	case WMA_GET_ISOLATION:
9490 		wma_get_isolation(wma_handle);
9491 		break;
9492 	case WMA_MODEM_POWER_STATE_IND:
9493 		wma_notify_modem_power_state(wma_handle,
9494 				(tSirModemPowerStateInd *) msg->bodyptr);
9495 		qdf_mem_free(msg->bodyptr);
9496 		break;
9497 #ifdef WLAN_FEATURE_STATS_EXT
9498 	case WMA_STATS_EXT_REQUEST:
9499 		wma_stats_ext_req(wma_handle,
9500 				  (tpStatsExtRequest) (msg->bodyptr));
9501 		qdf_mem_free(msg->bodyptr);
9502 		break;
9503 #endif /* WLAN_FEATURE_STATS_EXT */
9504 #ifdef WLAN_FEATURE_EXTWOW_SUPPORT
9505 	case WMA_WLAN_EXT_WOW:
9506 		wma_enable_ext_wow(wma_handle,
9507 				   (tSirExtWoWParams *) msg->bodyptr);
9508 		qdf_mem_free(msg->bodyptr);
9509 		break;
9510 	case WMA_WLAN_SET_APP_TYPE1_PARAMS:
9511 		wma_set_app_type1_params_in_fw(wma_handle,
9512 				(tSirAppType1Params *) msg->bodyptr);
9513 		qdf_mem_free(msg->bodyptr);
9514 		break;
9515 	case WMA_WLAN_SET_APP_TYPE2_PARAMS:
9516 		wma_set_app_type2_params_in_fw(wma_handle,
9517 				(tSirAppType2Params *) msg->bodyptr);
9518 		qdf_mem_free(msg->bodyptr);
9519 		break;
9520 #endif /* WLAN_FEATURE_EXTWOW_SUPPORT */
9521 #ifdef FEATURE_WLAN_EXTSCAN
9522 	case WMA_EXTSCAN_START_REQ:
9523 		wma_start_extscan(wma_handle, msg->bodyptr);
9524 		qdf_mem_free(msg->bodyptr);
9525 		break;
9526 	case WMA_EXTSCAN_STOP_REQ:
9527 		wma_stop_extscan(wma_handle, msg->bodyptr);
9528 		qdf_mem_free(msg->bodyptr);
9529 		break;
9530 	case WMA_EXTSCAN_SET_BSSID_HOTLIST_REQ:
9531 		wma_extscan_start_hotlist_monitor(wma_handle, msg->bodyptr);
9532 		qdf_mem_free(msg->bodyptr);
9533 		break;
9534 	case WMA_EXTSCAN_RESET_BSSID_HOTLIST_REQ:
9535 		wma_extscan_stop_hotlist_monitor(wma_handle, msg->bodyptr);
9536 		qdf_mem_free(msg->bodyptr);
9537 		break;
9538 	case WMA_EXTSCAN_SET_SIGNF_CHANGE_REQ:
9539 		wma_extscan_start_change_monitor(wma_handle, msg->bodyptr);
9540 		qdf_mem_free(msg->bodyptr);
9541 		break;
9542 	case WMA_EXTSCAN_RESET_SIGNF_CHANGE_REQ:
9543 		wma_extscan_stop_change_monitor(wma_handle, msg->bodyptr);
9544 		qdf_mem_free(msg->bodyptr);
9545 		break;
9546 	case WMA_EXTSCAN_GET_CACHED_RESULTS_REQ:
9547 		wma_extscan_get_cached_results(wma_handle, msg->bodyptr);
9548 		qdf_mem_free(msg->bodyptr);
9549 		break;
9550 	case WMA_EXTSCAN_GET_CAPABILITIES_REQ:
9551 		wma_extscan_get_capabilities(wma_handle, msg->bodyptr);
9552 		qdf_mem_free(msg->bodyptr);
9553 		break;
9554 	case WMA_SET_EPNO_LIST_REQ:
9555 		wma_set_epno_network_list(wma_handle, msg->bodyptr);
9556 		qdf_mem_free(msg->bodyptr);
9557 		break;
9558 	case WMA_SET_PASSPOINT_LIST_REQ:
9559 		/* Issue reset passpoint network list first and clear
9560 		 * the entries
9561 		 */
9562 		wma_reset_passpoint_network_list(wma_handle, msg->bodyptr);
9563 
9564 		wma_set_passpoint_network_list(wma_handle, msg->bodyptr);
9565 		qdf_mem_free(msg->bodyptr);
9566 		break;
9567 	case WMA_RESET_PASSPOINT_LIST_REQ:
9568 		wma_reset_passpoint_network_list(wma_handle, msg->bodyptr);
9569 		qdf_mem_free(msg->bodyptr);
9570 		break;
9571 #endif /* FEATURE_WLAN_EXTSCAN */
9572 	case WMA_SET_SCAN_MAC_OUI_REQ:
9573 		wma_scan_probe_setoui(wma_handle, msg->bodyptr);
9574 		qdf_mem_free(msg->bodyptr);
9575 		break;
9576 #ifdef WLAN_FEATURE_LINK_LAYER_STATS
9577 	case WMA_LINK_LAYER_STATS_CLEAR_REQ:
9578 		wma_process_ll_stats_clear_req(wma_handle,
9579 			(tpSirLLStatsClearReq) msg->bodyptr);
9580 		qdf_mem_free(msg->bodyptr);
9581 		break;
9582 	case WMA_LINK_LAYER_STATS_SET_REQ:
9583 		wma_process_ll_stats_set_req(wma_handle,
9584 					     (tpSirLLStatsSetReq) msg->bodyptr);
9585 		qdf_mem_free(msg->bodyptr);
9586 		break;
9587 	case WMA_LINK_LAYER_STATS_GET_REQ:
9588 		wma_process_ll_stats_get_req(wma_handle,
9589 					     (tpSirLLStatsGetReq) msg->bodyptr);
9590 		qdf_mem_free(msg->bodyptr);
9591 		break;
9592 	case WDA_LINK_LAYER_STATS_SET_THRESHOLD:
9593 		wma_config_stats_ext_threshold(wma_handle,
9594 			(struct sir_ll_ext_stats_threshold *)msg->bodyptr);
9595 		qdf_mem_free(msg->bodyptr);
9596 		break;
9597 #endif /* WLAN_FEATURE_LINK_LAYER_STATS */
9598 	case SIR_HAL_SET_BASE_MACADDR_IND:
9599 		wma_set_base_macaddr_indicate(wma_handle,
9600 					      (tSirMacAddr *) msg->bodyptr);
9601 		qdf_mem_free(msg->bodyptr);
9602 		break;
9603 	case WMA_LINK_STATUS_GET_REQ:
9604 		wma_process_link_status_req(wma_handle,
9605 					    (tAniGetLinkStatus *) msg->bodyptr);
9606 		break;
9607 	case WMA_GET_TEMPERATURE_REQ:
9608 		wma_get_temperature(wma_handle);
9609 		qdf_mem_free(msg->bodyptr);
9610 		break;
9611 	case WMA_TSF_GPIO_PIN:
9612 		wma_set_tsf_gpio_pin(wma_handle, msg->bodyval);
9613 		break;
9614 
9615 #ifdef DHCP_SERVER_OFFLOAD
9616 	case WMA_SET_DHCP_SERVER_OFFLOAD_CMD:
9617 		wma_process_dhcpserver_offload(wma_handle, msg->bodyptr);
9618 		qdf_mem_free(msg->bodyptr);
9619 		break;
9620 #endif /* DHCP_SERVER_OFFLOAD */
9621 #ifdef WLAN_FEATURE_GPIO_LED_FLASHING
9622 	case WMA_LED_FLASHING_REQ:
9623 		wma_set_led_flashing(wma_handle, msg->bodyptr);
9624 		qdf_mem_free(msg->bodyptr);
9625 		break;
9626 #endif /* WLAN_FEATURE_GPIO_LED_FLASHING */
9627 	case SIR_HAL_SET_MAS:
9628 		wma_process_set_mas(wma_handle,
9629 				(uint32_t *)msg->bodyptr);
9630 		qdf_mem_free(msg->bodyptr);
9631 		break;
9632 	case SIR_HAL_SET_MIRACAST:
9633 		wma_process_set_miracast(wma_handle,
9634 				(uint32_t *)msg->bodyptr);
9635 		qdf_mem_free(msg->bodyptr);
9636 		break;
9637 	case SIR_HAL_CONFIG_STATS_FACTOR:
9638 		wma_config_stats_factor(wma_handle,
9639 					(struct sir_stats_avg_factor *)
9640 					msg->bodyptr);
9641 		qdf_mem_free(msg->bodyptr);
9642 		break;
9643 	case SIR_HAL_CONFIG_GUARD_TIME:
9644 		wma_config_guard_time(wma_handle,
9645 				      (struct sir_guard_time_request *)
9646 				      msg->bodyptr);
9647 		qdf_mem_free(msg->bodyptr);
9648 		break;
9649 	case SIR_HAL_START_STOP_LOGGING:
9650 		wma_set_wifi_start_packet_stats(wma_handle,
9651 				(struct sir_wifi_start_log *)msg->bodyptr);
9652 		wma_enable_specific_fw_logs(wma_handle,
9653 				(struct sir_wifi_start_log *)msg->bodyptr);
9654 		qdf_mem_free(msg->bodyptr);
9655 		break;
9656 	case SIR_HAL_FLUSH_LOG_TO_FW:
9657 		wma_send_flush_logs_to_fw(wma_handle);
9658 		/* Body ptr is NULL here */
9659 		break;
9660 	case WMA_SET_RSSI_MONITOR_REQ:
9661 		wma_set_rssi_monitoring(wma_handle, msg->bodyptr);
9662 		qdf_mem_free(msg->bodyptr);
9663 		break;
9664 	case SIR_HAL_SET_PCL_TO_FW:
9665 		wma_send_set_pcl_cmd(wma_handle,
9666 				     (struct set_pcl_req *)msg->bodyptr);
9667 		qdf_mem_free(msg->bodyptr);
9668 		break;
9669 	case SIR_HAL_PDEV_SET_HW_MODE:
9670 		wma_send_pdev_set_hw_mode_cmd(wma_handle,
9671 				(struct policy_mgr_hw_mode *)msg->bodyptr);
9672 		qdf_mem_free(msg->bodyptr);
9673 		break;
9674 	case WMA_SET_WISA_PARAMS:
9675 		wma_set_wisa_params(wma_handle,
9676 			(struct sir_wisa_params *)msg->bodyptr);
9677 		qdf_mem_free(msg->bodyptr);
9678 		break;
9679 	case SIR_HAL_PDEV_DUAL_MAC_CFG_REQ:
9680 		wma_send_pdev_set_dual_mac_config(wma_handle,
9681 				(struct policy_mgr_dual_mac_config *)msg->bodyptr);
9682 		qdf_mem_free(msg->bodyptr);
9683 		break;
9684 	case WMA_SET_IE_INFO:
9685 		wma_process_set_ie_info(wma_handle,
9686 			(struct vdev_ie_info *)msg->bodyptr);
9687 		qdf_mem_free(msg->bodyptr);
9688 		break;
9689 	case WMA_CFG_VENDOR_ACTION_TB_PPDU:
9690 		wma_process_cfg_action_frm_tb_ppdu(wma_handle, msg->bodyptr);
9691 		qdf_mem_free(msg->bodyptr);
9692 		break;
9693 	case SIR_HAL_SOC_ANTENNA_MODE_REQ:
9694 		wma_send_pdev_set_antenna_mode(wma_handle,
9695 			(struct sir_antenna_mode_param *)msg->bodyptr);
9696 		qdf_mem_free(msg->bodyptr);
9697 		break;
9698 	case WMA_GW_PARAM_UPDATE_REQ:
9699 		wma_set_gateway_params(wma_handle, msg->bodyptr);
9700 		qdf_mem_free(msg->bodyptr);
9701 		break;
9702 	case WMA_SET_ADAPT_DWELLTIME_CONF_PARAMS:
9703 		wma_send_adapt_dwelltime_params(wma_handle,
9704 			(struct adaptive_dwelltime_params *)msg->bodyptr);
9705 		qdf_mem_free(msg->bodyptr);
9706 		break;
9707 	case WMA_HT40_OBSS_SCAN_IND:
9708 		wma_send_ht40_obss_scanind(wma_handle,
9709 			(struct obss_ht40_scanind *)msg->bodyptr);
9710 		qdf_mem_free(msg->bodyptr);
9711 		break;
9712 	case WMA_ADD_BCN_FILTER_CMDID:
9713 		wma_add_beacon_filter(wma_handle, msg->bodyptr);
9714 		qdf_mem_free(msg->bodyptr);
9715 		break;
9716 	case WMA_REMOVE_BCN_FILTER_CMDID:
9717 		wma_remove_beacon_filter(wma_handle, msg->bodyptr);
9718 		qdf_mem_free(msg->bodyptr);
9719 		break;
9720 	case WDA_APF_GET_CAPABILITIES_REQ:
9721 		wma_get_apf_capabilities(wma_handle);
9722 		break;
9723 	case SIR_HAL_POWER_DBG_CMD:
9724 		wma_process_hal_pwr_dbg_cmd(wma_handle,
9725 					    msg->bodyptr);
9726 		qdf_mem_free(msg->bodyptr);
9727 		break;
9728 	case WMA_SEND_FREQ_RANGE_CONTROL_IND:
9729 		wma_enable_disable_caevent_ind(wma_handle, msg->bodyval);
9730 		break;
9731 	case SIR_HAL_UPDATE_TX_FAIL_CNT_TH:
9732 		wma_update_tx_fail_cnt_th(wma_handle, msg->bodyptr);
9733 		qdf_mem_free(msg->bodyptr);
9734 		break;
9735 	case SIR_HAL_LONG_RETRY_LIMIT_CNT:
9736 		wma_update_long_retry_limit(wma_handle, msg->bodyptr);
9737 		qdf_mem_free(msg->bodyptr);
9738 		break;
9739 	case SIR_HAL_SHORT_RETRY_LIMIT_CNT:
9740 		wma_update_short_retry_limit(wma_handle, msg->bodyptr);
9741 		qdf_mem_free(msg->bodyptr);
9742 		break;
9743 	case SIR_HAL_POWER_DEBUG_STATS_REQ:
9744 		wma_process_power_debug_stats_req(wma_handle);
9745 		break;
9746 	case WMA_BEACON_DEBUG_STATS_REQ:
9747 		wma_process_beacon_debug_stats_req(wma_handle, msg->bodyptr);
9748 		qdf_mem_free(msg->bodyptr);
9749 		break;
9750 	case WMA_GET_RCPI_REQ:
9751 		wma_get_rcpi_req(wma_handle,
9752 				 (struct sme_rcpi_req *)msg->bodyptr);
9753 		qdf_mem_free(msg->bodyptr);
9754 		break;
9755 	case WMA_SET_WOW_PULSE_CMD:
9756 		wma_send_wow_pulse_cmd(wma_handle,
9757 			(struct wow_pulse_mode *)msg->bodyptr);
9758 		qdf_mem_free(msg->bodyptr);
9759 		break;
9760 	case WMA_SET_DBS_SCAN_SEL_CONF_PARAMS:
9761 		wma_send_dbs_scan_selection_params(wma_handle,
9762 			(struct wmi_dbs_scan_sel_params *)msg->bodyptr);
9763 		qdf_mem_free(msg->bodyptr);
9764 		break;
9765 	case WMA_SET_ARP_STATS_REQ:
9766 		wma_set_arp_req_stats(wma_handle,
9767 			(struct set_arp_stats_params *)msg->bodyptr);
9768 		qdf_mem_free(msg->bodyptr);
9769 		break;
9770 	case WMA_GET_ARP_STATS_REQ:
9771 		wma_get_arp_req_stats(wma_handle,
9772 			(struct get_arp_stats_params *)msg->bodyptr);
9773 		qdf_mem_free(msg->bodyptr);
9774 		break;
9775 	case SIR_HAL_SET_DEL_PMKID_CACHE:
9776 		wma_set_del_pmkid_cache(wma_handle, msg->bodyptr);
9777 		if (msg->bodyptr) {
9778 			qdf_mem_zero(msg->bodyptr,
9779 				     sizeof(struct wmi_unified_pmk_cache));
9780 			qdf_mem_free(msg->bodyptr);
9781 		}
9782 		break;
9783 	case SIR_HAL_HLP_IE_INFO:
9784 		wma_roam_scan_send_hlp(wma_handle,
9785 			(struct hlp_params *)msg->bodyptr);
9786 		qdf_mem_free(msg->bodyptr);
9787 		break;
9788 	case WMA_SET_LIMIT_OFF_CHAN:
9789 		wma_process_limit_off_chan(wma_handle, msg->bodyptr);
9790 		qdf_mem_free(msg->bodyptr);
9791 		break;
9792 	case WMA_OBSS_DETECTION_REQ:
9793 		wma_send_obss_detection_cfg(wma_handle, msg->bodyptr);
9794 		qdf_mem_free(msg->bodyptr);
9795 		break;
9796 	case WMA_INVOKE_NEIGHBOR_REPORT:
9797 		wma_send_invoke_neighbor_report(wma_handle, msg->bodyptr);
9798 		qdf_mem_free(msg->bodyptr);
9799 		break;
9800 	case WMA_OBSS_COLOR_COLLISION_REQ:
9801 		wma_process_obss_color_collision_req(wma_handle, msg->bodyptr);
9802 		qdf_mem_free(msg->bodyptr);
9803 		break;
9804 	case WMA_GET_ROAM_SCAN_STATS:
9805 		wma_get_roam_scan_stats(wma_handle, msg->bodyptr);
9806 		qdf_mem_free(msg->bodyptr);
9807 		break;
9808 #ifdef WLAN_FEATURE_MOTION_DETECTION
9809 	case WMA_SET_MOTION_DET_CONFIG:
9810 		wma_set_motion_det_config(
9811 			wma_handle,
9812 			(struct sme_motion_det_cfg *)msg->bodyptr);
9813 		qdf_mem_free(msg->bodyptr);
9814 		break;
9815 	case WMA_SET_MOTION_DET_ENABLE:
9816 		wma_set_motion_det_enable(
9817 			wma_handle,
9818 			(struct sme_motion_det_en *)msg->bodyptr);
9819 		qdf_mem_free(msg->bodyptr);
9820 		break;
9821 	case WMA_SET_MOTION_DET_BASE_LINE_CONFIG:
9822 		wma_set_motion_det_base_line_config(
9823 			wma_handle,
9824 			(struct sme_motion_det_base_line_cfg *)msg->bodyptr);
9825 		qdf_mem_free(msg->bodyptr);
9826 		break;
9827 	case WMA_SET_MOTION_DET_BASE_LINE_ENABLE:
9828 		wma_set_motion_det_base_line_enable(
9829 			wma_handle,
9830 			(struct sme_motion_det_base_line_en *)msg->bodyptr);
9831 		qdf_mem_free(msg->bodyptr);
9832 		break;
9833 #endif /* WLAN_FEATURE_MOTION_DETECTION */
9834 #ifdef FW_THERMAL_THROTTLE_SUPPORT
9835 	case WMA_SET_THERMAL_THROTTLE_CFG:
9836 		if (!wma_handle->thermal_mgmt_info.thermalMgmtEnabled)
9837 			wmi_unified_thermal_mitigation_param_cmd_send(
9838 					wma_handle->wmi_handle, msg->bodyptr);
9839 		else
9840 			qdf_status = QDF_STATUS_E_INVAL;
9841 		qdf_mem_free(msg->bodyptr);
9842 		break;
9843 	case WMA_SET_THERMAL_MGMT:
9844 		if (!wma_handle->thermal_mgmt_info.thermalMgmtEnabled)
9845 			wma_set_thermal_mgmt(
9846 				wma_handle,
9847 				*((t_thermal_cmd_params *)msg->bodyptr));
9848 		else
9849 			qdf_status = QDF_STATUS_E_INVAL;
9850 		qdf_mem_free(msg->bodyptr);
9851 		break;
9852 #endif /* FW_THERMAL_THROTTLE_SUPPORT */
9853 #ifdef WLAN_MWS_INFO_DEBUGFS
9854 	case WMA_GET_MWS_COEX_INFO_REQ:
9855 		wma_get_mws_coex_info_req(wma_handle, msg->bodyptr);
9856 		qdf_mem_free(msg->bodyptr);
9857 		break;
9858 #endif
9859 	case WMA_ROAM_SCAN_CH_REQ:
9860 		wma_get_roam_scan_ch(wma_handle->wmi_handle, msg->bodyval);
9861 		break;
9862 	case WMA_TWT_ADD_DIALOG_REQUEST:
9863 		wma_twt_process_add_dialog(wma_handle, msg->bodyptr);
9864 		qdf_mem_free(msg->bodyptr);
9865 		break;
9866 	case WMA_TWT_DEL_DIALOG_REQUEST:
9867 		wma_twt_process_del_dialog(wma_handle, msg->bodyptr);
9868 		qdf_mem_free(msg->bodyptr);
9869 		break;
9870 	case WMA_TWT_PAUSE_DIALOG_REQUEST:
9871 		wma_twt_process_pause_dialog(wma_handle, msg->bodyptr);
9872 		qdf_mem_free(msg->bodyptr);
9873 		break;
9874 	case WMA_TWT_RESUME_DIALOG_REQUEST:
9875 		wma_twt_process_resume_dialog(wma_handle, msg->bodyptr);
9876 		qdf_mem_free(msg->bodyptr);
9877 		break;
9878 	case WMA_TWT_NUDGE_DIALOG_REQUEST:
9879 		wma_twt_process_nudge_dialog(wma_handle, msg->bodyptr);
9880 		qdf_mem_free(msg->bodyptr);
9881 		break;
9882 	case WMA_UPDATE_EDCA_PIFS_PARAM_IND:
9883 		wma_update_edca_pifs_param(
9884 				wma_handle,
9885 				(struct edca_pifs_vparam *)msg->bodyptr);
9886 		qdf_mem_free(msg->bodyptr);
9887 		break;
9888 	default:
9889 		wma_debug("Unhandled WMA message of type %d", msg->type);
9890 		if (msg->bodyptr)
9891 			qdf_mem_free(msg->bodyptr);
9892 	}
9893 end:
9894 	return qdf_status;
9895 }
9896 
wma_mc_process_handler(struct scheduler_msg * msg)9897 QDF_STATUS wma_mc_process_handler(struct scheduler_msg *msg)
9898 {
9899 	return wma_mc_process_msg(msg);
9900 }
9901 
9902 /**
9903  * wma_log_completion_timeout() - Log completion timeout
9904  * @data: Timeout handler data
9905  *
9906  * This function is called when log completion timer expires
9907  *
9908  * Return: None
9909  */
wma_log_completion_timeout(void * data)9910 void wma_log_completion_timeout(void *data)
9911 {
9912 	wma_debug("Timeout occurred for log completion command");
9913 
9914 	/* Though we did not receive any event from FW,
9915 	 * we can flush whatever logs we have with us
9916 	 */
9917 	cds_logging_set_fw_flush_complete();
9918 }
9919 
9920 /**
9921  * wma_map_pcl_weights() - Map PCL weights
9922  * @pcl_weight: Internal PCL weights
9923  *
9924  * Maps the internal weights of PCL to the weights needed by FW
9925  *
9926  * Return: Mapped channel weight of type wmi_pcl_chan_weight
9927  */
wma_map_pcl_weights(uint32_t pcl_weight)9928 wmi_pcl_chan_weight wma_map_pcl_weights(uint32_t pcl_weight)
9929 {
9930 	switch (pcl_weight) {
9931 	case WEIGHT_OF_GROUP1_PCL_CHANNELS:
9932 		return WMI_PCL_WEIGHT_VERY_HIGH;
9933 	case WEIGHT_OF_GROUP2_PCL_CHANNELS:
9934 		return WMI_PCL_WEIGHT_HIGH;
9935 	case WEIGHT_OF_GROUP3_PCL_CHANNELS:
9936 		return WMI_PCL_WEIGHT_MEDIUM;
9937 	case WEIGHT_OF_GROUP4_PCL_CHANNELS:
9938 		return WMI_PCL_WEIGHT_MEDIUM;
9939 	case WEIGHT_OF_NON_PCL_CHANNELS:
9940 		return WMI_PCL_WEIGHT_LOW;
9941 	default:
9942 		return WMI_PCL_WEIGHT_DISALLOW;
9943 	}
9944 }
9945 
9946 /**
9947  * wma_send_set_pcl_cmd() - Send WMI_SOC_SET_PCL_CMDID to FW
9948  * @wma_handle: WMA handle
9949  * @msg: PCL structure containing the PCL and the number of channels
9950  *
9951  * WMI_PDEV_SET_PCL_CMDID provides a Preferred Channel List (PCL) to the WLAN
9952  * firmware. The DBS Manager is the consumer of this information in the WLAN
9953  * firmware. The channel list will be used when a Virtual DEVice (VDEV) needs
9954  * to migrate to a new channel without host driver involvement. An example of
9955  * this behavior is Legacy Fast Roaming (LFR 3.0). Generally, the host will
9956  * manage the channel selection without firmware involvement.
9957  *
9958  * WMI_PDEV_SET_PCL_CMDID will carry only the weight list and not the actual
9959  * channel list. The weights corresponds to the channels sent in
9960  * WMI_SCAN_CHAN_LIST_CMDID. The channels from PCL would be having a higher
9961  * weightage compared to the non PCL channels.
9962  *
9963  * Return: Success if the cmd is sent successfully to the firmware
9964  */
wma_send_set_pcl_cmd(tp_wma_handle wma_handle,struct set_pcl_req * msg)9965 QDF_STATUS wma_send_set_pcl_cmd(tp_wma_handle wma_handle,
9966 				struct set_pcl_req *msg)
9967 {
9968 	uint32_t i;
9969 	QDF_STATUS status;
9970 	bool is_channel_allowed;
9971 
9972 	if (wma_validate_handle(wma_handle))
9973 		return QDF_STATUS_E_NULL_VALUE;
9974 
9975 	/*
9976 	 * if vdev_id is WLAN_UMAC_VDEV_ID_MAX, then roaming is enabled on
9977 	 * only one sta, so PDEV PCL command needs to be sent.
9978 	 * If a valid vdev id is present, then vdev pcl command needs to be
9979 	 * sent.
9980 	 */
9981 	if (msg->vdev_id != WLAN_UMAC_VDEV_ID_MAX)
9982 		return wlan_cm_roam_send_set_vdev_pcl(wma_handle->psoc, msg);
9983 
9984 
9985 	wma_debug("RSO_CFG: BandCapability:%d, band_mask:%d",
9986 		  wma_handle->bandcapability, msg->band_mask);
9987 	for (i = 0; i < wma_handle->saved_chan.num_channels; i++) {
9988 		msg->chan_weights.saved_chan_list[i] =
9989 					wma_handle->saved_chan.ch_freq_list[i];
9990 	}
9991 
9992 	msg->chan_weights.saved_num_chan = wma_handle->saved_chan.num_channels;
9993 
9994 	status = policy_mgr_get_valid_chan_weights(wma_handle->psoc,
9995 		(struct policy_mgr_pcl_chan_weights *)&msg->chan_weights,
9996 		PM_STA_MODE, NULL);
9997 	if (QDF_IS_STATUS_ERROR(status)) {
9998 		wma_err("Error in creating weighed pcl");
9999 		return status;
10000 	}
10001 
10002 	for (i = 0; i < msg->chan_weights.saved_num_chan; i++) {
10003 		msg->chan_weights.weighed_valid_list[i] =
10004 			wma_map_pcl_weights(
10005 				msg->chan_weights.weighed_valid_list[i]);
10006 
10007 		is_channel_allowed =
10008 			policy_mgr_is_sta_chan_valid_for_connect_and_roam(
10009 					wma_handle->pdev,
10010 					msg->chan_weights.saved_chan_list[i]);
10011 		if (!is_channel_allowed) {
10012 			msg->chan_weights.weighed_valid_list[i] =
10013 					WEIGHT_OF_DISALLOWED_CHANNELS;
10014 			continue;
10015 		}
10016 
10017 		if (msg->band_mask ==
10018 		      (BIT(REG_BAND_2G) | BIT(REG_BAND_5G) | BIT(REG_BAND_6G)))
10019 			continue;
10020 
10021 		/*
10022 		 * Dont allow roaming on 5G/6G band if only 2G band configured
10023 		 * as supported roam band mask
10024 		 */
10025 		if (((wma_handle->bandcapability == BAND_2G) ||
10026 		    (msg->band_mask == BIT(REG_BAND_2G))) &&
10027 		    !WLAN_REG_IS_24GHZ_CH_FREQ(
10028 		    msg->chan_weights.saved_chan_list[i])) {
10029 			msg->chan_weights.weighed_valid_list[i] =
10030 				WEIGHT_OF_DISALLOWED_CHANNELS;
10031 			continue;
10032 		}
10033 
10034 		/*
10035 		 * Dont allow roaming on 2G/6G band if only 5G band configured
10036 		 * as supported roam band mask
10037 		 */
10038 		if (((wma_handle->bandcapability == BAND_5G) ||
10039 		    (msg->band_mask == BIT(REG_BAND_5G))) &&
10040 		    !WLAN_REG_IS_5GHZ_CH_FREQ(
10041 		    msg->chan_weights.saved_chan_list[i])) {
10042 			msg->chan_weights.weighed_valid_list[i] =
10043 				WEIGHT_OF_DISALLOWED_CHANNELS;
10044 			continue;
10045 		}
10046 
10047 		/*
10048 		 * Dont allow roaming on 2G/5G band if only 6G band configured
10049 		 * as supported roam band mask
10050 		 */
10051 		if (msg->band_mask == BIT(REG_BAND_6G) &&
10052 		    !WLAN_REG_IS_6GHZ_CHAN_FREQ(
10053 		    msg->chan_weights.saved_chan_list[i])) {
10054 			msg->chan_weights.weighed_valid_list[i] =
10055 				WEIGHT_OF_DISALLOWED_CHANNELS;
10056 			continue;
10057 		}
10058 
10059 		/*
10060 		 * Dont allow roaming on 6G band if only 2G + 5G band configured
10061 		 * as supported roam band mask.
10062 		 */
10063 		if (msg->band_mask == (BIT(REG_BAND_2G) | BIT(REG_BAND_5G)) &&
10064 		    (WLAN_REG_IS_6GHZ_CHAN_FREQ(
10065 		    msg->chan_weights.saved_chan_list[i]))) {
10066 			msg->chan_weights.weighed_valid_list[i] =
10067 				WEIGHT_OF_DISALLOWED_CHANNELS;
10068 			continue;
10069 		}
10070 
10071 		/*
10072 		 * Dont allow roaming on 2G band if only 5G + 6G band configured
10073 		 * as supported roam band mask.
10074 		 */
10075 		if (msg->band_mask == (BIT(REG_BAND_5G) | BIT(REG_BAND_6G)) &&
10076 		    (WLAN_REG_IS_24GHZ_CH_FREQ(
10077 		    msg->chan_weights.saved_chan_list[i]))) {
10078 			msg->chan_weights.weighed_valid_list[i] =
10079 				WEIGHT_OF_DISALLOWED_CHANNELS;
10080 			continue;
10081 		}
10082 
10083 		/*
10084 		 * Dont allow roaming on 5G band if only 2G + 6G band configured
10085 		 * as supported roam band mask.
10086 		 */
10087 		if (msg->band_mask == (BIT(REG_BAND_2G) | BIT(REG_BAND_6G)) &&
10088 		    (WLAN_REG_IS_5GHZ_CH_FREQ(
10089 		    msg->chan_weights.saved_chan_list[i]))) {
10090 			msg->chan_weights.weighed_valid_list[i] =
10091 				WEIGHT_OF_DISALLOWED_CHANNELS;
10092 			continue;
10093 		}
10094 	}
10095 
10096 	wma_debug("RSO_CFG: Dump PDEV PCL weights for vdev[%d]", msg->vdev_id);
10097 	policy_mgr_dump_channel_list(msg->chan_weights.saved_num_chan,
10098 				     msg->chan_weights.saved_chan_list,
10099 				     msg->chan_weights.weighed_valid_list);
10100 
10101 	if (wmi_unified_pdev_set_pcl_cmd(wma_handle->wmi_handle,
10102 					 &msg->chan_weights))
10103 		return QDF_STATUS_E_FAILURE;
10104 
10105 	return QDF_STATUS_SUCCESS;
10106 }
10107 
10108 /**
10109  * wma_send_pdev_set_hw_mode_cmd() - Send WMI_PDEV_SET_HW_MODE_CMDID to FW
10110  * @wma_handle: WMA handle
10111  * @msg: Structure containing the following parameters
10112  *
10113  * - hw_mode_index: The HW_Mode field is a enumerated type that is selected
10114  * from the HW_Mode table, which is returned in the WMI_SERVICE_READY_EVENTID.
10115  *
10116  * Provides notification to the WLAN firmware that host driver is requesting a
10117  * HardWare (HW) Mode change. This command is needed to support iHelium in the
10118  * configurations that include the Dual Band Simultaneous (DBS) feature.
10119  *
10120  * Return: Success if the cmd is sent successfully to the firmware
10121  */
wma_send_pdev_set_hw_mode_cmd(tp_wma_handle wma_handle,struct policy_mgr_hw_mode * msg)10122 QDF_STATUS wma_send_pdev_set_hw_mode_cmd(tp_wma_handle wma_handle,
10123 					 struct policy_mgr_hw_mode *msg)
10124 {
10125 	struct sir_set_hw_mode_resp *param;
10126 	struct wma_target_req *timeout_msg;
10127 
10128 	if (wma_validate_handle(wma_handle)) {
10129 		/* Handle is NULL. Will not be able to send failure
10130 		 * response as well
10131 		 */
10132 		return QDF_STATUS_E_NULL_VALUE;
10133 	}
10134 
10135 	if (!msg) {
10136 		wma_err("Set HW mode param is NULL");
10137 		/* Lets try to free the active command list */
10138 		goto fail;
10139 	}
10140 
10141 	wma_acquire_wakelock(&wma_handle->wmi_cmd_rsp_wake_lock,
10142 			     WMA_VDEV_HW_MODE_REQUEST_TIMEOUT);
10143 	if (wmi_unified_soc_set_hw_mode_cmd(wma_handle->wmi_handle,
10144 					    msg->hw_mode_index)) {
10145 		wma_release_wakelock(&wma_handle->wmi_cmd_rsp_wake_lock);
10146 		goto fail;
10147 	}
10148 	timeout_msg = wma_fill_hold_req(wma_handle, 0,
10149 			SIR_HAL_PDEV_SET_HW_MODE,
10150 			WMA_PDEV_SET_HW_MODE_RESP, NULL,
10151 			WMA_VDEV_HW_MODE_REQUEST_TIMEOUT - 1);
10152 	if (!timeout_msg) {
10153 		wma_err("Failed to allocate request for SIR_HAL_PDEV_SET_HW_MODE");
10154 		wma_remove_req(wma_handle, 0, WMA_PDEV_SET_HW_MODE_RESP);
10155 	}
10156 
10157 	return QDF_STATUS_SUCCESS;
10158 fail:
10159 	param = qdf_mem_malloc(sizeof(*param));
10160 	if (!param)
10161 		return QDF_STATUS_E_NULL_VALUE;
10162 
10163 	param->status = SET_HW_MODE_STATUS_ECANCELED;
10164 	param->cfgd_hw_mode_index = 0;
10165 	param->num_vdev_mac_entries = 0;
10166 	wma_debug("Sending HW mode fail response to LIM");
10167 	wma_send_msg(wma_handle, SIR_HAL_PDEV_SET_HW_MODE_RESP,
10168 			(void *) param, 0);
10169 	return QDF_STATUS_E_FAILURE;
10170 }
10171 
10172 /**
10173  * wma_send_pdev_set_dual_mac_config() - Set dual mac config to FW
10174  * @wma_handle: WMA handle
10175  * @msg: Dual MAC config parameters
10176  *
10177  * Configures WLAN firmware with the dual MAC features
10178  *
10179  * Return: QDF_STATUS. 0 on success.
10180  */
wma_send_pdev_set_dual_mac_config(tp_wma_handle wma_handle,struct policy_mgr_dual_mac_config * msg)10181 QDF_STATUS wma_send_pdev_set_dual_mac_config(tp_wma_handle wma_handle,
10182 		struct policy_mgr_dual_mac_config *msg)
10183 {
10184 	QDF_STATUS status;
10185 	struct wma_target_req *req_msg;
10186 	struct sir_dual_mac_config_resp *resp;
10187 
10188 	if (wma_validate_handle(wma_handle))
10189 		return QDF_STATUS_E_NULL_VALUE;
10190 
10191 	if (!msg) {
10192 		wma_err("Set dual mode config is NULL");
10193 		return QDF_STATUS_E_NULL_VALUE;
10194 	}
10195 
10196 	req_msg = wma_fill_hold_req(wma_handle, 0,
10197 				    SIR_HAL_PDEV_DUAL_MAC_CFG_REQ,
10198 				    WMA_PDEV_MAC_CFG_RESP, NULL,
10199 				    WMA_VDEV_DUAL_MAC_CFG_TIMEOUT);
10200 	if (!req_msg) {
10201 		wma_err("Failed to allocate request for SIR_HAL_PDEV_DUAL_MAC_CFG_REQ");
10202 		return QDF_STATUS_E_FAILURE;
10203 	}
10204 
10205 	/*
10206 	 * acquire the wake lock here and release it in response handler function
10207 	 * In error condition, release the wake lock right away
10208 	 */
10209 	wma_acquire_wakelock(&wma_handle->wmi_cmd_rsp_wake_lock,
10210 			     WMA_VDEV_PLCY_MGR_WAKE_LOCK_TIMEOUT);
10211 	status = wmi_unified_pdev_set_dual_mac_config_cmd(
10212 				wma_handle->wmi_handle,
10213 				(struct policy_mgr_dual_mac_config *)msg);
10214 	if (QDF_IS_STATUS_ERROR(status)) {
10215 		wma_err("Failed to send WMI_PDEV_SET_DUAL_MAC_CONFIG_CMDID: %d",
10216 			status);
10217 		wma_release_wakelock(&wma_handle->wmi_cmd_rsp_wake_lock);
10218 		wma_remove_req(wma_handle, 0, WMA_PDEV_MAC_CFG_RESP);
10219 		goto fail;
10220 	}
10221 	policy_mgr_update_dbs_req_config(wma_handle->psoc,
10222 	msg->scan_config, msg->fw_mode_config);
10223 
10224 	return QDF_STATUS_SUCCESS;
10225 
10226 fail:
10227 	resp = qdf_mem_malloc(sizeof(*resp));
10228 	if (!resp)
10229 		return QDF_STATUS_E_NULL_VALUE;
10230 
10231 	resp->status = SET_HW_MODE_STATUS_ECANCELED;
10232 	wma_debug("Sending failure response to LIM");
10233 	wma_send_msg(wma_handle, SIR_HAL_PDEV_MAC_CFG_RESP, (void *) resp, 0);
10234 
10235 	return QDF_STATUS_E_FAILURE;
10236 }
10237 
10238 /**
10239  * wma_send_pdev_set_antenna_mode() - Set antenna mode to FW
10240  * @wma_handle: WMA handle
10241  * @msg: Antenna mode parameters
10242  *
10243  * Send WMI_PDEV_SET_ANTENNA_MODE_CMDID to FW requesting to
10244  * modify the number of TX/RX chains from host
10245  *
10246  * Return: QDF_STATUS. 0 on success.
10247  */
wma_send_pdev_set_antenna_mode(tp_wma_handle wma_handle,struct sir_antenna_mode_param * msg)10248 QDF_STATUS wma_send_pdev_set_antenna_mode(tp_wma_handle wma_handle,
10249 		struct sir_antenna_mode_param *msg)
10250 {
10251 	wmi_pdev_set_antenna_mode_cmd_fixed_param *cmd;
10252 	wmi_buf_t buf;
10253 	uint32_t len;
10254 	QDF_STATUS status = QDF_STATUS_SUCCESS;
10255 	struct sir_antenna_mode_resp *param;
10256 
10257 	if (wma_validate_handle(wma_handle))
10258 		return QDF_STATUS_E_NULL_VALUE;
10259 
10260 	if (!msg) {
10261 		wma_err("Set antenna mode param is NULL");
10262 		return QDF_STATUS_E_NULL_VALUE;
10263 	}
10264 
10265 	len = sizeof(*cmd);
10266 
10267 	buf = wmi_buf_alloc(wma_handle->wmi_handle, len);
10268 	if (!buf) {
10269 		status = QDF_STATUS_E_NOMEM;
10270 		goto resp;
10271 	}
10272 
10273 	cmd = (wmi_pdev_set_antenna_mode_cmd_fixed_param *) wmi_buf_data(buf);
10274 	WMITLV_SET_HDR(&cmd->tlv_header,
10275 		WMITLV_TAG_STRUC_wmi_pdev_set_antenna_mode_cmd_fixed_param,
10276 		WMITLV_GET_STRUCT_TLVLEN(
10277 			wmi_pdev_set_antenna_mode_cmd_fixed_param));
10278 
10279 	cmd->pdev_id = OL_TXRX_PDEV_ID;
10280 	/* Bits 0-15 is num of RX chains 16-31 is num of TX chains */
10281 	cmd->num_txrx_chains = msg->num_rx_chains;
10282 	cmd->num_txrx_chains |= (msg->num_tx_chains << 16);
10283 
10284 	wma_debug("Num of chains TX: %d RX: %d txrx_chains: 0x%x",
10285 		 msg->num_tx_chains,
10286 		 msg->num_rx_chains, cmd->num_txrx_chains);
10287 
10288 	if (wmi_unified_cmd_send(wma_handle->wmi_handle, buf, len,
10289 				 WMI_PDEV_SET_ANTENNA_MODE_CMDID)) {
10290 		wmi_buf_free(buf);
10291 		status = QDF_STATUS_E_FAILURE;
10292 		goto resp;
10293 	}
10294 	status = QDF_STATUS_SUCCESS;
10295 
10296 resp:
10297 	param = qdf_mem_malloc(sizeof(*param));
10298 	if (!param)
10299 		return QDF_STATUS_E_NOMEM;
10300 
10301 	param->status = (status) ?
10302 		SET_ANTENNA_MODE_STATUS_ECANCELED :
10303 		SET_ANTENNA_MODE_STATUS_OK;
10304 	wma_debug("Send antenna mode resp to LIM status: %d",
10305 		  param->status);
10306 	wma_send_msg(wma_handle, SIR_HAL_SOC_ANTENNA_MODE_RESP,
10307 			(void *) param, 0);
10308 	return status;
10309 }
10310 
10311 /**
10312  * wma_crash_inject() - sends command to FW to simulate crash
10313  * @wma_handle:         pointer of WMA context
10314  * @type:               subtype of the command
10315  * @delay_time_ms:      time in milliseconds for FW to delay the crash
10316  *
10317  * This function will send a command to FW in order to simulate different
10318  * kinds of FW crashes.
10319  *
10320  * Return: QDF_STATUS_SUCCESS for success or error code
10321  */
wma_crash_inject(WMA_HANDLE wma_handle,uint32_t type,uint32_t delay_time_ms)10322 QDF_STATUS wma_crash_inject(WMA_HANDLE wma_handle, uint32_t type,
10323 			    uint32_t delay_time_ms)
10324 {
10325 	struct crash_inject param;
10326 	tp_wma_handle wma = (tp_wma_handle)wma_handle;
10327 
10328 	param.type = type;
10329 	param.delay_time_ms = delay_time_ms;
10330 	return wmi_crash_inject(wma->wmi_handle, &param);
10331 }
10332 
wma_configure_smps_params(uint32_t vdev_id,uint32_t param_id,uint32_t param_val)10333 QDF_STATUS wma_configure_smps_params(uint32_t vdev_id, uint32_t param_id,
10334 							uint32_t param_val)
10335 {
10336 	tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA);
10337 	int smps_cmd_value;
10338 	int status = QDF_STATUS_E_INVAL;
10339 
10340 	if (!wma)
10341 		return status;
10342 
10343 	smps_cmd_value = param_id << WMI_SMPS_PARAM_VALUE_S;
10344 	smps_cmd_value = smps_cmd_value | param_val;
10345 
10346 	status = wma_set_smps_params(wma, vdev_id, smps_cmd_value);
10347 	if (status)
10348 		wma_err("Failed to set SMPS Param");
10349 
10350 	return status;
10351 }
10352 
10353 
10354 /**
10355  * wma_config_bmiss_bcnt_params() - set bmiss config parameters
10356  * @vdev_id: virtual device for the command
10357  * @first_cnt: bmiss first value
10358  * @final_cnt: bmiss final value
10359  *
10360  * Return: QDF_STATUS_SUCCESS or non-zero on failure
10361  */
wma_config_bmiss_bcnt_params(uint32_t vdev_id,uint32_t first_cnt,uint32_t final_cnt)10362 QDF_STATUS wma_config_bmiss_bcnt_params(uint32_t vdev_id, uint32_t first_cnt,
10363 		uint32_t final_cnt)
10364 {
10365 	tp_wma_handle wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
10366 	int status = QDF_STATUS_E_INVAL;
10367 
10368 	if (!wma_handle)
10369 		return status;
10370 
10371 	status = wma_roam_scan_bmiss_cnt(wma_handle, first_cnt, final_cnt,
10372 			vdev_id);
10373 
10374 	if (status)
10375 		wma_err("Failed to set Bmiss Param");
10376 
10377 	return status;
10378 }
10379 
wma_get_rx_chainmask(uint8_t pdev_id,uint32_t * chainmask_2g,uint32_t * chainmask_5g)10380 QDF_STATUS wma_get_rx_chainmask(uint8_t pdev_id, uint32_t *chainmask_2g,
10381 				uint32_t *chainmask_5g)
10382 {
10383 	struct wlan_psoc_host_mac_phy_caps *mac_phy_cap;
10384 	uint8_t total_mac_phy_cnt, idx;
10385 	struct target_psoc_info *tgt_hdl;
10386 	uint32_t hw_mode_idx = 0, num_hw_modes = 0;
10387 
10388 	tp_wma_handle wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
10389 	if (!wma_handle)
10390 		return QDF_STATUS_E_INVAL;
10391 
10392 	tgt_hdl = wlan_psoc_get_tgt_if_handle(wma_handle->psoc);
10393 	if (!tgt_hdl) {
10394 		wma_err("target psoc info is NULL");
10395 		return QDF_STATUS_E_INVAL;
10396 	}
10397 
10398 	total_mac_phy_cnt = target_psoc_get_total_mac_phy_cnt(tgt_hdl);
10399 	num_hw_modes = target_psoc_get_num_hw_modes(tgt_hdl);
10400 	if (total_mac_phy_cnt <= pdev_id) {
10401 		wma_err("mac phy cnt %d, pdev id %d",
10402 			total_mac_phy_cnt, pdev_id);
10403 		return QDF_STATUS_E_FAILURE;
10404 	}
10405 
10406 	if ((wma_handle->new_hw_mode_index != WMA_DEFAULT_HW_MODE_INDEX) &&
10407 	    (wma_handle->new_hw_mode_index <= num_hw_modes))
10408 		hw_mode_idx = wma_handle->new_hw_mode_index;
10409 	mac_phy_cap = target_psoc_get_mac_phy_cap(tgt_hdl);
10410 	if (!mac_phy_cap) {
10411 		wma_err("Invalid MAC PHY capabilities handle");
10412 		return QDF_STATUS_E_FAILURE;
10413 	}
10414 	for (idx = 0; idx < total_mac_phy_cnt; idx++) {
10415 		if (mac_phy_cap[idx].hw_mode_id != hw_mode_idx)
10416 			continue;
10417 		if (mac_phy_cap[idx].supported_bands & WLAN_2G_CAPABILITY)
10418 			*chainmask_2g = mac_phy_cap[idx].rx_chain_mask_2G;
10419 		if (mac_phy_cap[idx].supported_bands & WLAN_5G_CAPABILITY)
10420 			*chainmask_5g = mac_phy_cap[idx].rx_chain_mask_5G;
10421 	}
10422 	wma_debug("pdev id: %d, hw_mode_idx: %d, rx chainmask 2g:%d, 5g:%d",
10423 		 pdev_id, hw_mode_idx, *chainmask_2g, *chainmask_5g);
10424 
10425 	return QDF_STATUS_SUCCESS;
10426 }
10427 
10428 #ifdef FEATURE_ANI_LEVEL_REQUEST
wma_send_ani_level_request(tp_wma_handle wma_handle,uint32_t * freqs,uint8_t num_freqs)10429 QDF_STATUS wma_send_ani_level_request(tp_wma_handle wma_handle,
10430 				      uint32_t *freqs, uint8_t num_freqs)
10431 {
10432 	return wmi_unified_ani_level_cmd_send(wma_handle->wmi_handle, freqs,
10433 					      num_freqs);
10434 }
10435 #endif
10436