xref: /wlan-dirver/qcacld-3.0/core/hdd/src/wlan_hdd_main.c (revision fa7ef9dc94d54d7249583ffc7a8a13fa1d3381e4)
1 /*
2  * Copyright (c) 2012-2021 The Linux Foundation. All rights reserved.
3  * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
4  *
5  * Permission to use, copy, modify, and/or distribute this software for
6  * any purpose with or without fee is hereby granted, provided that the
7  * above copyright notice and this permission notice appear in all
8  * copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
11  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
12  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
13  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
14  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
16  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17  * PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20 /**
21  *  DOC: wlan_hdd_main.c
22  *
23  *  WLAN Host Device Driver implementation
24  *
25  */
26 
27 /* Include Files */
28 #include <wbuff.h>
29 #include "cfg_ucfg_api.h"
30 #include <wlan_hdd_includes.h>
31 #include <cds_api.h>
32 #include <cds_sched.h>
33 #include <linux/cpu.h>
34 #include <linux/etherdevice.h>
35 #include <linux/firmware.h>
36 #include <linux/kernel.h>
37 #include <wlan_hdd_tx_rx.h>
38 #include <wni_api.h>
39 #include <wlan_hdd_cfg.h>
40 #include <wlan_ptt_sock_svc.h>
41 #include <dbglog_host.h>
42 #include <wlan_logging_sock_svc.h>
43 #include <wlan_roam_debug.h>
44 #include <wlan_hdd_connectivity_logging.h>
45 #include "osif_sync.h"
46 #include <wlan_hdd_wowl.h>
47 #include <wlan_hdd_misc.h>
48 #include <wlan_hdd_wext.h>
49 #include "wlan_hdd_trace.h"
50 #include "wlan_hdd_ioctl.h"
51 #include "wlan_hdd_ftm.h"
52 #include "wlan_hdd_power.h"
53 #include "wlan_hdd_stats.h"
54 #include "wlan_hdd_scan.h"
55 #include "wlan_policy_mgr_ucfg.h"
56 #include "wlan_osif_priv.h"
57 #include <wlan_osif_request_manager.h>
58 #ifdef CONFIG_LEAK_DETECTION
59 #include "qdf_debug_domain.h"
60 #endif
61 #include "qdf_delayed_work.h"
62 #include "qdf_periodic_work.h"
63 #include "qdf_str.h"
64 #include "qdf_talloc.h"
65 #include "qdf_trace.h"
66 #include "qdf_types.h"
67 #include "qdf_net_if.h"
68 #include <cdp_txrx_peer_ops.h>
69 #include <cdp_txrx_misc.h>
70 #include <cdp_txrx_stats.h>
71 #include "cdp_txrx_flow_ctrl_legacy.h"
72 #include "qdf_ssr_driver_dump.h"
73 
74 #include <net/addrconf.h>
75 #include <linux/wireless.h>
76 #include <net/cfg80211.h>
77 #include <linux/inetdevice.h>
78 #include <net/addrconf.h>
79 #include "wlan_hdd_cfg80211.h"
80 #include "wlan_hdd_ext_scan.h"
81 #include "wlan_hdd_p2p.h"
82 #include <linux/rtnetlink.h>
83 #include "sap_api.h"
84 #include <sap_internal.h>
85 #include <linux/semaphore.h>
86 #include <linux/ctype.h>
87 #include <linux/compat.h>
88 #include <linux/ethtool.h>
89 #include <linux/suspend.h>
90 
91 #ifdef WLAN_FEATURE_DP_BUS_BANDWIDTH
92 #include "qdf_periodic_work.h"
93 #endif
94 
95 #include <wlan_hdd_hostapd.h>
96 #include <wlan_hdd_softap_tx_rx.h>
97 #include <wlan_hdd_green_ap.h>
98 #include "qwlan_version.h"
99 #include "wma_types.h"
100 #include "wlan_hdd_tdls.h"
101 #ifdef FEATURE_WLAN_CH_AVOID
102 #include "cds_regdomain.h"
103 #endif /* FEATURE_WLAN_CH_AVOID */
104 #include "cdp_txrx_flow_ctrl_v2.h"
105 #include "pld_common.h"
106 #include "wlan_hdd_ocb.h"
107 #include "wlan_hdd_nan.h"
108 #include "wlan_hdd_debugfs.h"
109 #include "wlan_hdd_debugfs_csr.h"
110 #include "wlan_hdd_driver_ops.h"
111 #include "epping_main.h"
112 #include "wlan_hdd_data_stall_detection.h"
113 #include "wlan_hdd_mpta_helper.h"
114 
115 #include <wlan_hdd_ipa.h>
116 #include "hif.h"
117 #include "wma.h"
118 #include "wlan_policy_mgr_api.h"
119 #include "wlan_hdd_tsf.h"
120 #include "bmi.h"
121 #include <wlan_hdd_regulatory.h>
122 #include "wlan_hdd_lpass.h"
123 #include "wlan_nan_api.h"
124 #include <wlan_hdd_napi.h>
125 #include "wlan_hdd_disa.h"
126 #include <dispatcher_init_deinit.h>
127 #include "wlan_hdd_object_manager.h"
128 #include "cds_utils.h"
129 #include <cdp_txrx_handle.h>
130 #include <qca_vendor.h>
131 #include "wlan_pmo_ucfg_api.h"
132 #include "sir_api.h"
133 #include "os_if_wifi_pos.h"
134 #include "wifi_pos_api.h"
135 #include "wlan_hdd_oemdata.h"
136 #include "wlan_hdd_he.h"
137 #include "os_if_nan.h"
138 #include "nan_public_structs.h"
139 #include "nan_ucfg_api.h"
140 #include "wlan_reg_ucfg_api.h"
141 #include "wlan_hdd_afc.h"
142 #include "wlan_afc_ucfg_api.h"
143 #include "wlan_dfs_ucfg_api.h"
144 #include "wlan_hdd_rx_monitor.h"
145 #include "sme_power_save_api.h"
146 #include "enet.h"
147 #include <cdp_txrx_cmn_struct.h>
148 #include "wlan_hdd_sysfs.h"
149 #include "wlan_disa_ucfg_api.h"
150 #include "wlan_disa_obj_mgmt_api.h"
151 #include "wlan_action_oui_ucfg_api.h"
152 #include "wlan_ipa_ucfg_api.h"
153 #include <target_if.h>
154 #include "wlan_hdd_nud_tracking.h"
155 #include "wlan_hdd_apf.h"
156 #include "wlan_hdd_twt.h"
157 #include "qc_sap_ioctl.h"
158 #include "wlan_mlme_main.h"
159 #include "wlan_p2p_cfg_api.h"
160 #include "wlan_cfg80211_p2p.h"
161 #include "wlan_cfg80211_interop_issues_ap.h"
162 #include "wlan_tdls_cfg_api.h"
163 #include <wlan_hdd_rssi_monitor.h>
164 #include "wlan_mlme_ucfg_api.h"
165 #include "wlan_mlme_twt_ucfg_api.h"
166 #include "wlan_fwol_ucfg_api.h"
167 #include "wlan_policy_mgr_ucfg.h"
168 #include "qdf_func_tracker.h"
169 #include "pld_common.h"
170 #include "wlan_hdd_pre_cac.h"
171 
172 #include "sme_api.h"
173 
174 #ifdef CNSS_GENL
175 #ifdef CONFIG_CNSS_OUT_OF_TREE
176 #include "cnss_nl.h"
177 #else
178 #include <net/cnss_nl.h>
179 #endif
180 #endif
181 #include "wlan_reg_ucfg_api.h"
182 #include "wlan_ocb_ucfg_api.h"
183 #include <wlan_hdd_spectralscan.h>
184 #include "wlan_green_ap_ucfg_api.h"
185 #include <wlan_p2p_ucfg_api.h>
186 #include <wlan_interop_issues_ap_ucfg_api.h>
187 #include <target_type.h>
188 #include <wlan_hdd_debugfs_coex.h>
189 #include <wlan_hdd_debugfs_config.h>
190 #include "wlan_dlm_ucfg_api.h"
191 #include "ftm_time_sync_ucfg_api.h"
192 #include "wlan_pre_cac_ucfg_api.h"
193 #include "ol_txrx.h"
194 #include "wlan_hdd_sta_info.h"
195 #include "mac_init_api.h"
196 #include "wlan_pkt_capture_ucfg_api.h"
197 #include <wlan_hdd_sar_limits.h>
198 #include "cfg_nan_api.h"
199 #include "wlan_hdd_btc_chain_mode.h"
200 #include <wlan_hdd_dcs.h>
201 #include "wlan_hdd_debugfs_unit_test.h"
202 #include "wlan_hdd_debugfs_mibstat.h"
203 #include <wlan_hdd_hang_event.h>
204 #include "wlan_global_lmac_if_api.h"
205 #include "wlan_coex_ucfg_api.h"
206 #include "wlan_cm_roam_api.h"
207 #include "wlan_cm_roam_ucfg_api.h"
208 #include <cdp_txrx_ctrl.h>
209 #include "qdf_lock.h"
210 #include "wlan_hdd_thermal.h"
211 #include "osif_cm_util.h"
212 #include "wlan_hdd_gpio_wakeup.h"
213 #include "wlan_hdd_bootup_marker.h"
214 #include "wlan_dp_ucfg_api.h"
215 #include "wlan_hdd_medium_assess.h"
216 #include "wlan_hdd_eht.h"
217 #include <linux/bitfield.h>
218 #include "wlan_hdd_mlo.h"
219 #include <wlan_hdd_son.h>
220 #ifdef WLAN_FEATURE_11BE_MLO
221 #include <wlan_mlo_mgr_ap.h>
222 #endif
223 #include "wlan_osif_features.h"
224 #include "wlan_vdev_mgr_ucfg_api.h"
225 #include <wlan_objmgr_psoc_obj_i.h>
226 #include <wlan_objmgr_vdev_obj_i.h>
227 #include "wifi_pos_ucfg_api.h"
228 #include "osif_vdev_mgr_util.h"
229 #include <son_ucfg_api.h>
230 #include "osif_twt_util.h"
231 #include "wlan_twt_ucfg_ext_api.h"
232 #include "wlan_hdd_mcc_quota.h"
233 #include "osif_pre_cac.h"
234 #include "wlan_hdd_pre_cac.h"
235 #include "wlan_osif_features.h"
236 #ifdef WLAN_FEATURE_DYNAMIC_RX_AGGREGATION
237 #include <net/pkt_cls.h>
238 #endif
239 #include "wlan_dp_public_struct.h"
240 #include "os_if_dp.h"
241 #include <wlan_dp_ucfg_api.h>
242 #include "wlan_psoc_mlme_ucfg_api.h"
243 #include "os_if_qmi.h"
244 #include "wlan_qmi_ucfg_api.h"
245 #include "wlan_psoc_mlme_ucfg_api.h"
246 #include "wlan_ll_sap_ucfg_api.h"
247 
248 #include "os_if_dp_local_pkt_capture.h"
249 #include <wlan_mlo_mgr_link_switch.h>
250 #include "cdp_txrx_mon.h"
251 
252 #ifdef MULTI_CLIENT_LL_SUPPORT
253 #define WLAM_WLM_HOST_DRIVER_PORT_ID 0xFFFFFF
254 #endif
255 
256 #ifdef MODULE
257 #ifdef WLAN_WEAR_CHIPSET
258 #define WLAN_MODULE_NAME  "wlan"
259 #else
260 #define WLAN_MODULE_NAME  module_name(THIS_MODULE)
261 #endif
262 #else
263 #define WLAN_MODULE_NAME  "wlan"
264 #endif
265 
266 #ifdef TIMER_MANAGER
267 #define TIMER_MANAGER_STR " +TIMER_MANAGER"
268 #else
269 #define TIMER_MANAGER_STR ""
270 #endif
271 
272 #ifdef MEMORY_DEBUG
273 #define MEMORY_DEBUG_STR " +MEMORY_DEBUG"
274 #else
275 #define MEMORY_DEBUG_STR ""
276 #endif
277 
278 #ifdef PANIC_ON_BUG
279 #define PANIC_ON_BUG_STR " +PANIC_ON_BUG"
280 #else
281 #define PANIC_ON_BUG_STR ""
282 #endif
283 
284 /* PCIe gen speed change idle shutdown timer 100 milliseconds */
285 #define HDD_PCIE_GEN_SPEED_CHANGE_TIMEOUT_MS (100)
286 
287 #define MAX_NET_DEV_REF_LEAK_ITERATIONS 10
288 #define NET_DEV_REF_LEAK_ITERATION_SLEEP_TIME_MS 10
289 
290 #ifdef FEATURE_TSO
291 #define TSO_FEATURE_FLAGS (NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_SG)
292 #else
293 #define TSO_FEATURE_FLAGS 0
294 #endif
295 
296 int wlan_start_ret_val;
297 static DECLARE_COMPLETION(wlan_start_comp);
298 static qdf_atomic_t wlan_hdd_state_fops_ref;
299 #ifndef MODULE
300 static struct gwlan_loader *wlan_loader;
301 static ssize_t wlan_boot_cb(struct kobject *kobj,
302 			    struct kobj_attribute *attr,
303 			    const char *buf, size_t count);
304 struct gwlan_loader {
305 	bool loaded_state;
306 	struct kobject *boot_wlan_obj;
307 	struct attribute_group *attr_group;
308 };
309 
310 static struct kobj_attribute wlan_boot_attribute =
311 	__ATTR(boot_wlan, 0220, NULL, wlan_boot_cb);
312 
313 static struct attribute *attrs[] = {
314 	&wlan_boot_attribute.attr,
315 	NULL,
316 };
317 #define MODULE_INITIALIZED 1
318 
319 #ifdef MULTI_IF_NAME
320 #define WLAN_LOADER_NAME "boot_" MULTI_IF_NAME
321 #else
322 #define WLAN_LOADER_NAME "boot_wlan"
323 #endif
324 #endif
325 
326 /* the Android framework expects this param even though we don't use it */
327 #define BUF_LEN 20
328 static char fwpath_buffer[BUF_LEN];
329 static struct kparam_string fwpath = {
330 	.string = fwpath_buffer,
331 	.maxlen = BUF_LEN,
332 };
333 
334 char *country_code;
335 #ifdef FEATURE_WLAN_RESIDENT_DRIVER
336 EXPORT_SYMBOL(country_code);
337 #endif
338 static int enable_11d = -1;
339 static int enable_dfs_chan_scan = -1;
340 static bool is_mode_change_psoc_idle_shutdown;
341 
342 #define WLAN_NLINK_CESIUM 30
343 
344 static qdf_wake_lock_t wlan_wake_lock;
345 
346 /* The valid PCIe gen speeds are 1, 2, 3 */
347 #define HDD_INVALID_MIN_PCIE_GEN_SPEED (0)
348 #define HDD_INVALID_MAX_PCIE_GEN_SPEED (4)
349 
350 #define MAX_PDEV_PRE_ENABLE_PARAMS 8
351 #define FTM_MAX_PDEV_PARAMS 1
352 
353 #define WOW_MAX_FILTER_LISTS 1
354 #define WOW_MAX_FILTERS_PER_LIST 4
355 #define WOW_MIN_PATTERN_SIZE 6
356 #define WOW_MAX_PATTERN_SIZE 64
357 #define MGMT_DEFAULT_DATA_RATE_6GHZ 0x400 /* This maps to 8.6Mbps data rate */
358 
359 #define IS_IDLE_STOP (!cds_is_driver_unloading() && \
360 		      !cds_is_driver_recovering() && !cds_is_driver_loading())
361 
362 #define HDD_FW_VER_MAJOR_SPID(tgt_fw_ver)     ((tgt_fw_ver & 0xf0000000) >> 28)
363 #define HDD_FW_VER_MINOR_SPID(tgt_fw_ver)     ((tgt_fw_ver & 0xf000000) >> 24)
364 #define HDD_FW_VER_SIID(tgt_fw_ver)           ((tgt_fw_ver & 0xf00000) >> 20)
365 #define HDD_FW_VER_CRM_ID(tgt_fw_ver)         (tgt_fw_ver & 0x7fff)
366 #define HDD_FW_VER_SUB_ID(tgt_fw_ver_ext) \
367 (((tgt_fw_ver_ext & 0x1c00) >> 6) | ((tgt_fw_ver_ext & 0xf0000000) >> 28))
368 #define HDD_FW_VER_REL_ID(tgt_fw_ver_ext) \
369 ((tgt_fw_ver_ext &  0xf800000) >> 23)
370 
371 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
372 static const struct wiphy_wowlan_support wowlan_support_reg_init = {
373 	.flags = WIPHY_WOWLAN_ANY |
374 		 WIPHY_WOWLAN_MAGIC_PKT |
375 		 WIPHY_WOWLAN_DISCONNECT |
376 		 WIPHY_WOWLAN_SUPPORTS_GTK_REKEY |
377 		 WIPHY_WOWLAN_GTK_REKEY_FAILURE |
378 		 WIPHY_WOWLAN_EAP_IDENTITY_REQ |
379 		 WIPHY_WOWLAN_4WAY_HANDSHAKE |
380 		 WIPHY_WOWLAN_RFKILL_RELEASE,
381 	.n_patterns = WOW_MAX_FILTER_LISTS * WOW_MAX_FILTERS_PER_LIST,
382 	.pattern_min_len = WOW_MIN_PATTERN_SIZE,
383 	.pattern_max_len = WOW_MAX_PATTERN_SIZE,
384 };
385 #endif
386 
387 static const struct category_info cinfo[MAX_SUPPORTED_CATEGORY] = {
388 	[QDF_MODULE_ID_TLSHIM] = {QDF_TRACE_LEVEL_ALL},
389 	[QDF_MODULE_ID_WMI] = {QDF_TRACE_LEVEL_ALL},
390 	[QDF_MODULE_ID_HTT] = {QDF_TRACE_LEVEL_ALL},
391 	[QDF_MODULE_ID_HDD] = {QDF_TRACE_LEVEL_ALL},
392 	[QDF_MODULE_ID_SME] = {QDF_TRACE_LEVEL_ALL},
393 	[QDF_MODULE_ID_PE] = {QDF_TRACE_LEVEL_ALL},
394 	[QDF_MODULE_ID_WMA] = {QDF_TRACE_LEVEL_ALL},
395 	[QDF_MODULE_ID_SYS] = {QDF_TRACE_LEVEL_ALL},
396 	[QDF_MODULE_ID_QDF] = {QDF_TRACE_LEVEL_ALL},
397 	[QDF_MODULE_ID_SAP] = {QDF_TRACE_LEVEL_ALL},
398 	[QDF_MODULE_ID_HDD_SOFTAP] = {QDF_TRACE_LEVEL_ALL},
399 	[QDF_MODULE_ID_HDD_DATA] = {QDF_DATA_PATH_TRACE_LEVEL},
400 	[QDF_MODULE_ID_HDD_SAP_DATA] = {QDF_DATA_PATH_TRACE_LEVEL},
401 	[QDF_MODULE_ID_HIF] = {QDF_DATA_PATH_TRACE_LEVEL},
402 	[QDF_MODULE_ID_HTC] = {QDF_DATA_PATH_TRACE_LEVEL},
403 	[QDF_MODULE_ID_TXRX] = {QDF_DATA_PATH_TRACE_LEVEL},
404 	[QDF_MODULE_ID_HAL] = {QDF_DATA_PATH_TRACE_LEVEL},
405 	[QDF_MODULE_ID_QDF_DEVICE] = {QDF_TRACE_LEVEL_ALL},
406 	[QDF_MODULE_ID_CFG] = {QDF_TRACE_LEVEL_ALL},
407 	[QDF_MODULE_ID_BMI] = {QDF_TRACE_LEVEL_ALL},
408 	[QDF_MODULE_ID_EPPING] = {QDF_TRACE_LEVEL_ALL},
409 	[QDF_MODULE_ID_QVIT] = {QDF_TRACE_LEVEL_ALL},
410 	[QDF_MODULE_ID_DP] = {QDF_DATA_PATH_TRACE_LEVEL},
411 	[QDF_MODULE_ID_DP_TX_CAPTURE] = {QDF_DATA_PATH_TRACE_LEVEL},
412 	[QDF_MODULE_ID_DP_INIT] = {QDF_DATA_PATH_TRACE_LEVEL},
413 	[QDF_MODULE_ID_DP_STATS] = {QDF_DATA_PATH_TRACE_LEVEL},
414 	[QDF_MODULE_ID_DP_HTT] = {QDF_DATA_PATH_TRACE_LEVEL},
415 	[QDF_MODULE_ID_DP_PEER] = {QDF_DATA_PATH_TRACE_LEVEL},
416 	[QDF_MODULE_ID_DP_HTT_TX_STATS] = {QDF_DATA_PATH_TRACE_LEVEL},
417 	[QDF_MODULE_ID_DP_REO] = {QDF_DATA_PATH_TRACE_LEVEL},
418 	[QDF_MODULE_ID_DP_VDEV] = {QDF_DATA_PATH_TRACE_LEVEL},
419 	[QDF_MODULE_ID_DP_CDP] = {QDF_DATA_PATH_TRACE_LEVEL},
420 	[QDF_MODULE_ID_DP_UMAC_RESET] = {QDF_DATA_PATH_TRACE_LEVEL},
421 	[QDF_MODULE_ID_DP_SAWF] = {QDF_DATA_PATH_TRACE_LEVEL},
422 	[QDF_MODULE_ID_SOC] = {QDF_TRACE_LEVEL_ALL},
423 	[QDF_MODULE_ID_OS_IF] = {QDF_TRACE_LEVEL_ALL},
424 	[QDF_MODULE_ID_TARGET_IF] = {QDF_TRACE_LEVEL_ALL},
425 	[QDF_MODULE_ID_SCHEDULER] = {QDF_TRACE_LEVEL_ALL},
426 	[QDF_MODULE_ID_MGMT_TXRX] = {QDF_TRACE_LEVEL_ALL},
427 	[QDF_MODULE_ID_PMO] = {QDF_TRACE_LEVEL_ALL},
428 	[QDF_MODULE_ID_SCAN] = {QDF_TRACE_LEVEL_ALL},
429 	[QDF_MODULE_ID_POLICY_MGR] = {QDF_TRACE_LEVEL_ALL},
430 	[QDF_MODULE_ID_P2P] = {QDF_TRACE_LEVEL_ALL},
431 	[QDF_MODULE_ID_TDLS] = {QDF_TRACE_LEVEL_ALL},
432 	[QDF_MODULE_ID_REGULATORY] = {QDF_TRACE_LEVEL_ALL},
433 	[QDF_MODULE_ID_SERIALIZATION] = {QDF_TRACE_LEVEL_ALL},
434 	[QDF_MODULE_ID_DFS] = {QDF_TRACE_LEVEL_ALL},
435 	[QDF_MODULE_ID_OBJ_MGR] = {QDF_TRACE_LEVEL_ALL},
436 	[QDF_MODULE_ID_ROAM_DEBUG] = {QDF_TRACE_LEVEL_ALL},
437 	[QDF_MODULE_ID_GREEN_AP] = {QDF_TRACE_LEVEL_ALL},
438 	[QDF_MODULE_ID_OCB] = {QDF_TRACE_LEVEL_ALL},
439 	[QDF_MODULE_ID_IPA] = {QDF_TRACE_LEVEL_ALL},
440 	[QDF_MODULE_ID_ACTION_OUI] = {QDF_TRACE_LEVEL_ALL},
441 	[QDF_MODULE_ID_CONFIG] = {QDF_TRACE_LEVEL_ALL},
442 	[QDF_MODULE_ID_MLME] = {QDF_TRACE_LEVEL_ALL},
443 	[QDF_MODULE_ID_TARGET] = {QDF_TRACE_LEVEL_ALL},
444 	[QDF_MODULE_ID_CRYPTO] = {QDF_TRACE_LEVEL_ALL},
445 	[QDF_MODULE_ID_FWOL] = {QDF_TRACE_LEVEL_ALL},
446 	[QDF_MODULE_ID_SM_ENGINE] = {QDF_TRACE_LEVEL_ALL},
447 	[QDF_MODULE_ID_CMN_MLME] = {QDF_TRACE_LEVEL_ALL},
448 	[QDF_MODULE_ID_NAN] = {QDF_TRACE_LEVEL_ALL},
449 	[QDF_MODULE_ID_CP_STATS] = {QDF_TRACE_LEVEL_ALL},
450 	[QDF_MODULE_ID_DCS] = {QDF_TRACE_LEVEL_ALL},
451 	[QDF_MODULE_ID_INTEROP_ISSUES_AP] = {QDF_TRACE_LEVEL_ALL},
452 	[QDF_MODULE_ID_DENYLIST_MGR] = {QDF_TRACE_LEVEL_ALL},
453 	[QDF_MODULE_ID_DIRECT_BUF_RX] = {QDF_TRACE_LEVEL_ALL},
454 	[QDF_MODULE_ID_SPECTRAL] = {QDF_TRACE_LEVEL_ALL},
455 	[QDF_MODULE_ID_WIFIPOS] = {QDF_TRACE_LEVEL_ALL},
456 	[QDF_MODULE_ID_PKT_CAPTURE] = {QDF_TRACE_LEVEL_ALL},
457 	[QDF_MODULE_ID_FTM_TIME_SYNC] = {QDF_TRACE_LEVEL_ALL},
458 	[QDF_MODULE_ID_CFR] = {QDF_TRACE_LEVEL_ALL},
459 	[QDF_MODULE_ID_IFMGR] = {QDF_TRACE_LEVEL_ALL},
460 	[QDF_MODULE_ID_GPIO] = {QDF_TRACE_LEVEL_ALL},
461 	[QDF_MODULE_ID_T2LM] = {QDF_TRACE_LEVEL_ALL},
462 	[QDF_MODULE_ID_MLO] = {QDF_TRACE_LEVEL_ALL},
463 	[QDF_MODULE_ID_SON] = {QDF_TRACE_LEVEL_ALL},
464 	[QDF_MODULE_ID_TWT] = {QDF_TRACE_LEVEL_ALL},
465 	[QDF_MODULE_ID_WLAN_PRE_CAC] = {QDF_TRACE_LEVEL_ALL},
466 	[QDF_MODULE_ID_COAP] = {QDF_TRACE_LEVEL_ALL},
467 	[QDF_MODULE_ID_MON_FILTER] = {QDF_DATA_PATH_TRACE_LEVEL},
468 	[QDF_MODULE_ID_LL_SAP] = {QDF_TRACE_LEVEL_ALL},
469 };
470 
471 struct notifier_block hdd_netdev_notifier;
472 
473 struct sock *cesium_nl_srv_sock;
474 #ifdef FEATURE_WLAN_AUTO_SHUTDOWN
475 static void wlan_hdd_auto_shutdown_cb(void);
476 #endif
477 
478 static void hdd_dp_register_callbacks(struct hdd_context *hdd_ctx);
479 
480 bool hdd_adapter_is_ap(struct hdd_adapter *adapter)
481 {
482 	if (!adapter) {
483 		hdd_err("null adapter");
484 		return false;
485 	}
486 
487 	return adapter->device_mode == QDF_SAP_MODE ||
488 		adapter->device_mode == QDF_P2P_GO_MODE;
489 }
490 
491 QDF_STATUS hdd_common_roam_callback(struct wlan_objmgr_psoc *psoc,
492 				    uint8_t session_id,
493 				    struct csr_roam_info *roam_info,
494 				    eRoamCmdStatus roam_status,
495 				    eCsrRoamResult roam_result)
496 {
497 	struct hdd_context *hdd_ctx;
498 	struct hdd_adapter *adapter;
499 	struct wlan_hdd_link_info *link_info;
500 	QDF_STATUS status = QDF_STATUS_SUCCESS;
501 
502 	link_info = wlan_hdd_get_link_info_from_vdev(psoc, session_id);
503 	if (!link_info)
504 		return QDF_STATUS_E_INVAL;
505 
506 	adapter = link_info->adapter;
507 	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
508 	if (!hdd_ctx)
509 		return QDF_STATUS_E_INVAL;
510 
511 	switch (adapter->device_mode) {
512 	case QDF_STA_MODE:
513 	case QDF_NDI_MODE:
514 	case QDF_P2P_CLIENT_MODE:
515 	case QDF_P2P_DEVICE_MODE:
516 		status = hdd_sme_roam_callback(link_info, roam_info,
517 					       roam_status, roam_result);
518 		break;
519 	case QDF_SAP_MODE:
520 	case QDF_P2P_GO_MODE:
521 		status =
522 			wlansap_roam_callback(link_info->session.ap.sap_context,
523 					      roam_info, roam_status,
524 					      roam_result);
525 		break;
526 	default:
527 		hdd_err("Wrong device mode");
528 		break;
529 	}
530 
531 	return status;
532 }
533 
534 void hdd_start_complete(int ret)
535 {
536 	wlan_start_ret_val = ret;
537 	complete_all(&wlan_start_comp);
538 }
539 
540 #ifdef WLAN_FEATURE_LOCAL_PKT_CAPTURE
541 /**
542  * wlan_hdd_lpc_del_monitor_interface() - Delete monitor interface
543  * @hdd_ctx: hdd_ctx
544  *
545  * This function takes care of deleting monitor interface
546  *
547  * Return: none
548  */
549 static void
550 wlan_hdd_lpc_del_monitor_interface(struct hdd_context *hdd_ctx)
551 {
552 	struct hdd_adapter *adapter;
553 	void *soc;
554 	bool running;
555 
556 	if (!hdd_ctx)
557 		return;
558 
559 	if (!ucfg_dp_is_local_pkt_capture_enabled(hdd_ctx->psoc))
560 		return;
561 
562 	soc = cds_get_context(QDF_MODULE_ID_SOC);
563 	if (!soc)
564 		return;
565 
566 	running = cdp_is_local_pkt_capture_running(soc, OL_TXRX_PDEV_ID);
567 	if (!running)
568 		return;
569 
570 	adapter = hdd_get_adapter(hdd_ctx, QDF_MONITOR_MODE);
571 	if (!adapter) {
572 		hdd_debug("There is no monitor adapter");
573 		return;
574 	}
575 
576 	hdd_debug("lpc: Delete monitor interface");
577 	wlan_hdd_release_intf_addr(hdd_ctx, adapter->mac_addr.bytes);
578 	hdd_stop_adapter(hdd_ctx, adapter);
579 	hdd_close_adapter(hdd_ctx, adapter, true);
580 }
581 #else
582 static inline
583 void wlan_hdd_lpc_del_monitor_interface(struct hdd_context *hdd_ctx)
584 {
585 }
586 #endif
587 
588 #ifdef QCA_HL_NETDEV_FLOW_CONTROL
589 void wlan_hdd_mod_fc_timer(struct hdd_adapter *adapter,
590 			   enum netif_action_type action)
591 {
592 	struct hdd_stats *hdd_stats;
593 
594 	if (!adapter->tx_flow_timer_initialized)
595 		return;
596 
597 	hdd_stats = &adapter->deflink->hdd_stats;
598 	if (action == WLAN_WAKE_NON_PRIORITY_QUEUE) {
599 		qdf_mc_timer_stop(&adapter->tx_flow_control_timer);
600 		hdd_stats->tx_rx_stats.is_txflow_paused = false;
601 		hdd_stats->tx_rx_stats.txflow_unpause_cnt++;
602 	} else if (action == WLAN_STOP_NON_PRIORITY_QUEUE) {
603 		QDF_STATUS status =
604 		qdf_mc_timer_start(&adapter->tx_flow_control_timer,
605 				   WLAN_HDD_TX_FLOW_CONTROL_OS_Q_BLOCK_TIME);
606 
607 		if (!QDF_IS_STATUS_SUCCESS(status))
608 			hdd_err("Failed to start tx_flow_control_timer");
609 		else
610 			hdd_stats->tx_rx_stats.txflow_timer_cnt++;
611 
612 		hdd_stats->tx_rx_stats.txflow_pause_cnt++;
613 		hdd_stats->tx_rx_stats.is_txflow_paused = true;
614 	}
615 }
616 #endif /* QCA_HL_NETDEV_FLOW_CONTROL */
617 
618 /**
619  * wlan_hdd_txrx_pause_cb() - pause callback from txrx layer
620  * @vdev_id: vdev_id
621  * @action: action type
622  * @reason: reason type
623  *
624  * Return: none
625  */
626 void wlan_hdd_txrx_pause_cb(uint8_t vdev_id,
627 		enum netif_action_type action, enum netif_reason_type reason)
628 {
629 	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
630 	struct hdd_adapter *adapter;
631 	struct wlan_hdd_link_info *link_info;
632 
633 	if (!hdd_ctx)
634 		return;
635 
636 	link_info = hdd_get_link_info_by_vdev(hdd_ctx, vdev_id);
637 	if (!link_info)
638 		return;
639 
640 	adapter =  link_info->adapter;
641 	wlan_hdd_mod_fc_timer(adapter, action);
642 	wlan_hdd_netif_queue_control(adapter, action, reason);
643 }
644 
645 /*
646  * Store WLAN driver version and timestamp info in global variables such that
647  * crash debugger can extract them from driver debug symbol and crashdump for
648  * post processing
649  */
650 #ifdef BUILD_TAG
651 uint8_t g_wlan_driver_version[] = QWLAN_VERSIONSTR TIMER_MANAGER_STR MEMORY_DEBUG_STR PANIC_ON_BUG_STR "; " BUILD_TAG;
652 #else
653 uint8_t g_wlan_driver_version[] = QWLAN_VERSIONSTR TIMER_MANAGER_STR MEMORY_DEBUG_STR PANIC_ON_BUG_STR;
654 #endif
655 
656 int hdd_validate_channel_and_bandwidth(struct hdd_adapter *adapter,
657 				       qdf_freq_t chan_freq,
658 				       enum phy_ch_width chan_bw)
659 {
660 	struct ch_params ch_params = {0};
661 	struct hdd_context *hdd_ctx;
662 
663 	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
664 	if (!hdd_ctx) {
665 		hdd_err("hdd context is NULL");
666 		return -EINVAL;
667 	}
668 
669 	if (reg_is_chan_enum_invalid(
670 			wlan_reg_get_chan_enum_for_freq(chan_freq))) {
671 		hdd_err("Channel freq %d not in driver's valid channel list", chan_freq);
672 		return -EOPNOTSUPP;
673 	}
674 
675 	if ((!WLAN_REG_IS_24GHZ_CH_FREQ(chan_freq)) &&
676 	    (!WLAN_REG_IS_5GHZ_CH_FREQ(chan_freq)) &&
677 	    (!WLAN_REG_IS_6GHZ_CHAN_FREQ(chan_freq))) {
678 		hdd_err("CH %d is not in 2.4GHz or 5GHz or 6GHz", chan_freq);
679 		return -EINVAL;
680 	}
681 	ch_params.ch_width = CH_WIDTH_MAX;
682 	wlan_reg_set_channel_params_for_pwrmode(hdd_ctx->pdev, chan_freq,
683 						0, &ch_params,
684 						REG_CURRENT_PWR_MODE);
685 	if (ch_params.ch_width == CH_WIDTH_MAX) {
686 		hdd_err("failed to get max bandwdith for %d", chan_freq);
687 		return -EINVAL;
688 	}
689 	if (WLAN_REG_IS_24GHZ_CH_FREQ(chan_freq)) {
690 		if (chan_bw == CH_WIDTH_80MHZ) {
691 			hdd_err("BW80 not possible in 2.4GHz band");
692 			return -EINVAL;
693 		}
694 		if ((chan_bw != CH_WIDTH_20MHZ) &&
695 		    (chan_freq == wlan_reg_ch_to_freq(CHAN_ENUM_2484)) &&
696 		    (chan_bw != CH_WIDTH_MAX) &&
697 		    (ch_params.ch_width == CH_WIDTH_20MHZ)) {
698 			hdd_err("Only BW20 possible on channel freq 2484");
699 			return -EINVAL;
700 		}
701 	}
702 
703 	if (WLAN_REG_IS_5GHZ_CH_FREQ(chan_freq)) {
704 		if ((chan_bw != CH_WIDTH_20MHZ) &&
705 		    (chan_freq == wlan_reg_ch_to_freq(CHAN_ENUM_5825)) &&
706 		    (chan_bw != CH_WIDTH_MAX) &&
707 		    (ch_params.ch_width == CH_WIDTH_20MHZ)) {
708 			hdd_err("Only BW20 possible on channel freq 5825");
709 			return -EINVAL;
710 		}
711 	}
712 
713 	return 0;
714 }
715 
716 uint32_t hdd_get_link_info_home_channel(struct wlan_hdd_link_info *link_info)
717 {
718 	uint32_t home_chan_freq = 0;
719 	enum QDF_OPMODE opmode = link_info->adapter->device_mode;
720 
721 	switch (opmode) {
722 	case QDF_SAP_MODE:
723 	case QDF_P2P_GO_MODE:
724 		if (test_bit(SOFTAP_BSS_STARTED, &link_info->link_flags)) {
725 			home_chan_freq =
726 				link_info->session.ap.operating_chan_freq;
727 		}
728 		break;
729 	case QDF_STA_MODE:
730 	case QDF_P2P_CLIENT_MODE:
731 		if (hdd_cm_is_vdev_associated(link_info)) {
732 			home_chan_freq =
733 				link_info->session.station.conn_info.chan_freq;
734 		}
735 		break;
736 	default:
737 		break;
738 	}
739 
740 	return home_chan_freq;
741 }
742 
743 enum phy_ch_width hdd_get_link_info_width(struct wlan_hdd_link_info *link_info)
744 {
745 	enum phy_ch_width width = CH_WIDTH_20MHZ;
746 	enum QDF_OPMODE opmode = link_info->adapter->device_mode;
747 
748 	switch (opmode) {
749 	case QDF_SAP_MODE:
750 	case QDF_P2P_GO_MODE:
751 		if (test_bit(SOFTAP_BSS_STARTED, &link_info->link_flags)) {
752 			struct hdd_ap_ctx *ap_ctx =
753 					WLAN_HDD_GET_AP_CTX_PTR(link_info);
754 
755 			width = ap_ctx->sap_config.ch_params.ch_width;
756 		}
757 		break;
758 	case QDF_STA_MODE:
759 	case QDF_P2P_CLIENT_MODE:
760 		if (hdd_cm_is_vdev_associated(link_info))
761 			width = link_info->session.station.conn_info.ch_width;
762 		break;
763 	default:
764 		break;
765 	}
766 
767 	return width;
768 }
769 
770 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
771 static inline struct net_device *hdd_net_dev_from_notifier(void *context)
772 {
773 	struct netdev_notifier_info *info = context;
774 
775 	return info->dev;
776 }
777 #else
778 static inline struct net_device *hdd_net_dev_from_notifier(void *context)
779 {
780 	return context;
781 }
782 #endif
783 
784 static int __hdd_netdev_notifier_call(struct net_device *net_dev,
785 				      unsigned long state)
786 {
787 	struct hdd_adapter *adapter;
788 	struct hdd_context *hdd_ctx;
789 	struct wlan_objmgr_vdev *vdev;
790 
791 	hdd_enter_dev(net_dev);
792 
793 	if (!net_dev->ieee80211_ptr) {
794 		hdd_debug("ieee80211_ptr is null");
795 		return NOTIFY_DONE;
796 	}
797 
798 	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
799 	if (!hdd_ctx)
800 		return NOTIFY_DONE;
801 
802 	if (hdd_ctx->driver_status == DRIVER_MODULES_CLOSED) {
803 		hdd_debug("Driver module is closed");
804 		return NOTIFY_DONE;
805 	}
806 
807 	/* Make sure that this callback corresponds to our device. */
808 	adapter = hdd_get_adapter_by_iface_name(hdd_ctx, net_dev->name);
809 	if (!adapter) {
810 		hdd_debug("failed to look up adapter for '%s'", net_dev->name);
811 		return NOTIFY_DONE;
812 	}
813 
814 	if (adapter != WLAN_HDD_GET_PRIV_PTR(net_dev)) {
815 		hdd_err("HDD adapter mismatch!");
816 		return NOTIFY_DONE;
817 	}
818 
819 	if (cds_is_driver_recovering()) {
820 		hdd_debug("Driver is recovering");
821 		return NOTIFY_DONE;
822 	}
823 
824 	if (cds_is_driver_in_bad_state()) {
825 		hdd_debug("Driver is in failed recovery state");
826 		return NOTIFY_DONE;
827 	}
828 
829 	hdd_debug("%s New Net Device State = %lu, flags 0x%x",
830 		  net_dev->name, state, net_dev->flags);
831 
832 	switch (state) {
833 	case NETDEV_REGISTER:
834 		break;
835 
836 	case NETDEV_UNREGISTER:
837 		break;
838 
839 	case NETDEV_UP:
840 		sme_ch_avoid_update_req(hdd_ctx->mac_handle);
841 		break;
842 
843 	case NETDEV_DOWN:
844 		break;
845 
846 	case NETDEV_CHANGE:
847 		if (adapter->is_link_up_service_needed)
848 			complete(&adapter->linkup_event_var);
849 		break;
850 
851 	case NETDEV_GOING_DOWN:
852 		vdev = hdd_objmgr_get_vdev_by_user(adapter->deflink,
853 						   WLAN_OSIF_SCAN_ID);
854 		if (!vdev)
855 			break;
856 		if (ucfg_scan_get_vdev_status(vdev) !=
857 				SCAN_NOT_IN_PROGRESS) {
858 			wlan_abort_scan(hdd_ctx->pdev, INVAL_PDEV_ID,
859 					adapter->deflink->vdev_id,
860 					INVALID_SCAN_ID, true);
861 		}
862 		hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_SCAN_ID);
863 		cds_flush_work(&adapter->scan_block_work);
864 		/* Need to clean up blocked scan request */
865 		wlan_hdd_cfg80211_scan_block(adapter);
866 		hdd_debug("Scan is not Pending from user");
867 		/*
868 		 * After NETDEV_GOING_DOWN, kernel calls hdd_stop.Irrespective
869 		 * of return status of hdd_stop call, kernel resets the IFF_UP
870 		 * flag after which driver does not send the cfg80211_scan_done.
871 		 * Ensure to cleanup the scan queue in NETDEV_GOING_DOWN
872 		 */
873 		wlan_cfg80211_cleanup_scan_queue(hdd_ctx->pdev, net_dev);
874 		break;
875 	case NETDEV_FEAT_CHANGE:
876 		hdd_debug("vdev %d netdev Feature 0x%llx\n",
877 			  adapter->deflink->vdev_id, net_dev->features);
878 		break;
879 	default:
880 		break;
881 	}
882 
883 	return NOTIFY_DONE;
884 }
885 
886 static int hdd_netdev_notifier_bridge_intf(struct net_device *net_dev,
887 					   unsigned long state)
888 {
889 	struct hdd_adapter *adapter, *next_adapter = NULL;
890 	wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_GET_ADAPTER;
891 	struct hdd_context *hdd_ctx;
892 	QDF_STATUS status;
893 
894 	hdd_enter_dev(net_dev);
895 
896 	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
897 	if (wlan_hdd_validate_context(hdd_ctx))
898 		return NOTIFY_DONE;
899 
900 	hdd_debug("%s New Net Device State = %lu, flags 0x%x bridge mac address: "QDF_MAC_ADDR_FMT,
901 		  net_dev->name, state, net_dev->flags, QDF_MAC_ADDR_REF(net_dev->dev_addr));
902 
903 	if (!qdf_mem_cmp(hdd_ctx->bridgeaddr, net_dev->dev_addr,
904 			 QDF_MAC_ADDR_SIZE))
905 		return NOTIFY_DONE;
906 
907 	switch (state) {
908 	case NETDEV_REGISTER:
909 	case NETDEV_CHANGEADDR:
910 		/* Update FW WoW pattern with new MAC address */
911 		qdf_mem_copy(hdd_ctx->bridgeaddr, net_dev->dev_addr,
912 			     QDF_MAC_ADDR_SIZE);
913 
914 		hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
915 						   dbgid) {
916 			if (adapter->device_mode != QDF_SAP_MODE)
917 				goto loop_next;
918 
919 			if (wlan_hdd_validate_vdev_id(adapter->deflink->vdev_id))
920 				goto loop_next;
921 
922 			status = wlan_objmgr_vdev_try_get_ref(adapter->deflink->vdev,
923 							      WLAN_HDD_ID_OBJ_MGR);
924 			if (QDF_IS_STATUS_ERROR(status))
925 				goto loop_next;
926 
927 			ucfg_pmo_set_vdev_bridge_addr(adapter->deflink->vdev,
928 				(struct qdf_mac_addr *)hdd_ctx->bridgeaddr);
929 			ucfg_pmo_del_wow_pattern(adapter->deflink->vdev);
930 			ucfg_pmo_register_wow_default_patterns(adapter->deflink->vdev);
931 
932 			wlan_objmgr_vdev_release_ref(adapter->deflink->vdev,
933 						     WLAN_HDD_ID_OBJ_MGR);
934 
935 loop_next:
936 			hdd_adapter_dev_put_debug(adapter, dbgid);
937 		}
938 
939 		break;
940 	case NETDEV_UNREGISTER:
941 		qdf_zero_macaddr((struct qdf_mac_addr *)hdd_ctx->bridgeaddr);
942 		break;
943 	default:
944 		break;
945 	}
946 
947 	return NOTIFY_DONE;
948 }
949 
950 /**
951  * hdd_netdev_notifier_call() - netdev notifier callback function
952  * @nb: pointer to notifier block
953  * @state: state
954  * @context: notifier callback context pointer
955  *
956  * Return: 0 on success, error number otherwise.
957  */
958 static int hdd_netdev_notifier_call(struct notifier_block *nb,
959 					unsigned long state,
960 					void *context)
961 {
962 	struct net_device *net_dev = hdd_net_dev_from_notifier(context);
963 	struct osif_vdev_sync *vdev_sync;
964 	int errno;
965 
966 	if (net_dev->priv_flags & IFF_EBRIDGE) {
967 		errno = hdd_netdev_notifier_bridge_intf(net_dev, state);
968 		if (errno)
969 			return NOTIFY_DONE;
970 	}
971 
972 	errno = osif_vdev_sync_op_start(net_dev, &vdev_sync);
973 	if (errno)
974 		return NOTIFY_DONE;
975 
976 	errno = __hdd_netdev_notifier_call(net_dev, state);
977 
978 	osif_vdev_sync_op_stop(vdev_sync);
979 
980 	return NOTIFY_DONE;
981 }
982 
983 struct notifier_block hdd_netdev_notifier = {
984 	.notifier_call = hdd_netdev_notifier_call,
985 };
986 
987 /* variable to hold the insmod parameters */
988 int con_mode;
989 #ifdef FEATURE_WLAN_RESIDENT_DRIVER
990 EXPORT_SYMBOL(con_mode);
991 #endif
992 
993 int con_mode_ftm;
994 #ifdef FEATURE_WLAN_RESIDENT_DRIVER
995 EXPORT_SYMBOL(con_mode_ftm);
996 #endif
997 int con_mode_epping;
998 
999 static int pcie_gen_speed;
1000 
1001 /* Variable to hold connection mode including module parameter con_mode */
1002 static int curr_con_mode;
1003 
1004 #if defined(WLAN_FEATURE_11BE) && defined(CFG80211_11BE_BASIC)
1005 static enum phy_ch_width hdd_get_eht_phy_ch_width_from_target(void)
1006 {
1007 	uint32_t max_fw_bw = sme_get_eht_ch_width();
1008 
1009 	if (max_fw_bw == WNI_CFG_EHT_CHANNEL_WIDTH_320MHZ)
1010 		return CH_WIDTH_320MHZ;
1011 	else if (max_fw_bw == WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ)
1012 		return CH_WIDTH_160MHZ;
1013 	else
1014 		return CH_WIDTH_80MHZ;
1015 }
1016 
1017 static bool hdd_is_target_eht_phy_ch_width_supported(enum phy_ch_width width)
1018 {
1019 	enum phy_ch_width max_fw_bw = hdd_get_eht_phy_ch_width_from_target();
1020 
1021 	if (width <= max_fw_bw)
1022 		return true;
1023 
1024 	hdd_err("FW does not support this BW %d max BW supported %d",
1025 		width, max_fw_bw);
1026 	return false;
1027 }
1028 
1029 static bool hdd_is_target_eht_160mhz_capable(void)
1030 {
1031 	return hdd_is_target_eht_phy_ch_width_supported(CH_WIDTH_160MHZ);
1032 }
1033 
1034 static enum phy_ch_width
1035 wlan_hdd_map_nl_chan_width(enum nl80211_chan_width width)
1036 {
1037 	if (width == NL80211_CHAN_WIDTH_320) {
1038 		return hdd_get_eht_phy_ch_width_from_target();
1039 	} else {
1040 		hdd_err("Invalid channel width %d, setting to default", width);
1041 		return CH_WIDTH_INVALID;
1042 	}
1043 }
1044 
1045 #else /* !WLAN_FEATURE_11BE */
1046 static inline bool
1047 hdd_is_target_eht_phy_ch_width_supported(enum phy_ch_width width)
1048 {
1049 	return true;
1050 }
1051 
1052 static inline bool hdd_is_target_eht_160mhz_capable(void)
1053 {
1054 	return false;
1055 }
1056 
1057 static enum phy_ch_width
1058 wlan_hdd_map_nl_chan_width(enum nl80211_chan_width width)
1059 {
1060 	hdd_err("Invalid channel width %d, setting to default", width);
1061 	return CH_WIDTH_INVALID;
1062 }
1063 #endif /* WLAN_FEATURE_11BE */
1064 
1065 /**
1066  * hdd_map_nl_chan_width() - Map NL channel width to internal representation
1067  * @ch_width: NL channel width
1068  *
1069  * Converts the NL channel width to the driver's internal representation
1070  *
1071  * Return: Converted channel width. In case of non matching NL channel width,
1072  * CH_WIDTH_MAX will be returned.
1073  */
1074 enum phy_ch_width hdd_map_nl_chan_width(enum nl80211_chan_width ch_width)
1075 {
1076 	uint8_t fw_ch_bw;
1077 
1078 	fw_ch_bw = wma_get_vht_ch_width();
1079 	switch (ch_width) {
1080 	case NL80211_CHAN_WIDTH_20_NOHT:
1081 	case NL80211_CHAN_WIDTH_20:
1082 		return CH_WIDTH_20MHZ;
1083 	case NL80211_CHAN_WIDTH_40:
1084 		return CH_WIDTH_40MHZ;
1085 	case NL80211_CHAN_WIDTH_80:
1086 		return CH_WIDTH_80MHZ;
1087 	case NL80211_CHAN_WIDTH_80P80:
1088 		if (fw_ch_bw == WNI_CFG_VHT_CHANNEL_WIDTH_80_PLUS_80MHZ)
1089 			return CH_WIDTH_80P80MHZ;
1090 		else if (fw_ch_bw == WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ)
1091 			return CH_WIDTH_160MHZ;
1092 		else
1093 			return CH_WIDTH_80MHZ;
1094 	case NL80211_CHAN_WIDTH_160:
1095 		if (hdd_is_target_eht_160mhz_capable())
1096 			return CH_WIDTH_160MHZ;
1097 
1098 		if (fw_ch_bw >= WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ)
1099 			return CH_WIDTH_160MHZ;
1100 		else
1101 			return CH_WIDTH_80MHZ;
1102 	case NL80211_CHAN_WIDTH_5:
1103 		return CH_WIDTH_5MHZ;
1104 	case NL80211_CHAN_WIDTH_10:
1105 		return CH_WIDTH_10MHZ;
1106 	default:
1107 		return wlan_hdd_map_nl_chan_width(ch_width);
1108 	}
1109 }
1110 
1111 #if defined(WLAN_FEATURE_NAN) && \
1112 	   (KERNEL_VERSION(4, 9, 0) <= LINUX_VERSION_CODE)
1113 /**
1114  * wlan_hdd_convert_nan_type() - Convert nl type to qdf type
1115  * @nl_type: NL80211 interface type
1116  * @out_qdf_type: QDF type for the given nl_type
1117  *
1118  * Convert nl type to QDF type
1119  *
1120  * Return: QDF_STATUS_SUCCESS if converted, failure otherwise.
1121  */
1122 static QDF_STATUS wlan_hdd_convert_nan_type(enum nl80211_iftype nl_type,
1123 					    enum QDF_OPMODE *out_qdf_type)
1124 {
1125 	if (nl_type == NL80211_IFTYPE_NAN) {
1126 		*out_qdf_type = QDF_NAN_DISC_MODE;
1127 		return QDF_STATUS_SUCCESS;
1128 	}
1129 	return QDF_STATUS_E_INVAL;
1130 }
1131 
1132 /**
1133  * wlan_hdd_set_nan_if_type() - Set the NAN iftype
1134  * @adapter: pointer to HDD adapter
1135  *
1136  * Set the NL80211_IFTYPE_NAN to wdev iftype.
1137  *
1138  * Return: None
1139  */
1140 static void wlan_hdd_set_nan_if_type(struct hdd_adapter *adapter)
1141 {
1142 	adapter->wdev.iftype = NL80211_IFTYPE_NAN;
1143 }
1144 
1145 static bool wlan_hdd_is_vdev_creation_allowed(struct wlan_objmgr_psoc *psoc)
1146 {
1147 	return ucfg_nan_is_vdev_creation_allowed(psoc);
1148 }
1149 #else
1150 static QDF_STATUS wlan_hdd_convert_nan_type(enum nl80211_iftype nl_type,
1151 					    enum QDF_OPMODE *out_qdf_type)
1152 {
1153 	return QDF_STATUS_E_INVAL;
1154 }
1155 
1156 static void wlan_hdd_set_nan_if_type(struct hdd_adapter *adapter)
1157 {
1158 }
1159 
1160 static bool wlan_hdd_is_vdev_creation_allowed(struct wlan_objmgr_psoc *psoc)
1161 {
1162 	return false;
1163 }
1164 #endif
1165 
1166 QDF_STATUS hdd_nl_to_qdf_iface_type(enum nl80211_iftype nl_type,
1167 				    enum QDF_OPMODE *out_qdf_type)
1168 {
1169 	QDF_STATUS status = QDF_STATUS_SUCCESS;
1170 
1171 	switch (nl_type) {
1172 	case NL80211_IFTYPE_AP:
1173 		*out_qdf_type = QDF_SAP_MODE;
1174 		break;
1175 	case NL80211_IFTYPE_MONITOR:
1176 		*out_qdf_type = QDF_MONITOR_MODE;
1177 		break;
1178 	case NL80211_IFTYPE_OCB:
1179 		*out_qdf_type = QDF_OCB_MODE;
1180 		break;
1181 	case NL80211_IFTYPE_P2P_CLIENT:
1182 		*out_qdf_type = QDF_P2P_CLIENT_MODE;
1183 		break;
1184 	case NL80211_IFTYPE_P2P_DEVICE:
1185 		*out_qdf_type = QDF_P2P_DEVICE_MODE;
1186 		break;
1187 	case NL80211_IFTYPE_P2P_GO:
1188 		*out_qdf_type = QDF_P2P_GO_MODE;
1189 		break;
1190 	case NL80211_IFTYPE_STATION:
1191 		*out_qdf_type = QDF_STA_MODE;
1192 		break;
1193 	case NL80211_IFTYPE_WDS:
1194 		*out_qdf_type = QDF_WDS_MODE;
1195 		break;
1196 	default:
1197 		status = wlan_hdd_convert_nan_type(nl_type, out_qdf_type);
1198 		if (QDF_IS_STATUS_SUCCESS(status))
1199 			break;
1200 		hdd_err("Invalid nl80211 interface type %d", nl_type);
1201 		return QDF_STATUS_E_INVAL;
1202 	}
1203 
1204 	return QDF_STATUS_SUCCESS;
1205 }
1206 
1207 uint8_t wlan_hdd_find_opclass(mac_handle_t mac_handle, uint8_t channel,
1208 			      uint8_t bw_offset)
1209 {
1210 	uint8_t opclass = 0;
1211 
1212 	sme_get_opclass(mac_handle, channel, bw_offset, &opclass);
1213 	return opclass;
1214 }
1215 
1216 /**
1217  * hdd_qdf_trace_enable() - configure initial QDF Trace enable
1218  * @module_id:	Module whose trace level is being configured
1219  * @bitmask:	Bitmask of log levels to be enabled
1220  *
1221  * Called immediately after the cfg.ini is read in order to configure
1222  * the desired trace levels.
1223  *
1224  * Return: None
1225  */
1226 int hdd_qdf_trace_enable(QDF_MODULE_ID module_id, uint32_t bitmask)
1227 {
1228 	QDF_TRACE_LEVEL level;
1229 	int qdf_print_idx = -1;
1230 	int status = -1;
1231 	/*
1232 	 * if the bitmask is the default value, then a bitmask was not
1233 	 * specified in cfg.ini, so leave the logging level alone (it
1234 	 * will remain at the "compiled in" default value)
1235 	 */
1236 	if (CFG_QDF_TRACE_ENABLE_DEFAULT == bitmask)
1237 		return 0;
1238 
1239 	qdf_print_idx = qdf_get_pidx();
1240 
1241 	/* a mask was specified.  start by disabling all logging */
1242 	status = qdf_print_set_category_verbose(qdf_print_idx, module_id,
1243 					QDF_TRACE_LEVEL_NONE, 0);
1244 
1245 	if (QDF_STATUS_SUCCESS != status)
1246 		return -EINVAL;
1247 	/* now cycle through the bitmask until all "set" bits are serviced */
1248 	level = QDF_TRACE_LEVEL_NONE;
1249 	while (0 != bitmask) {
1250 		if (bitmask & 1) {
1251 			status = qdf_print_set_category_verbose(qdf_print_idx,
1252 							module_id, level, 1);
1253 			if (QDF_STATUS_SUCCESS != status)
1254 				return -EINVAL;
1255 		}
1256 
1257 		level++;
1258 		bitmask >>= 1;
1259 	}
1260 	return 0;
1261 }
1262 
1263 int __wlan_hdd_validate_context(struct hdd_context *hdd_ctx, const char *func)
1264 {
1265 	if (!hdd_ctx) {
1266 		hdd_err("HDD context is null (via %s)", func);
1267 		return -ENODEV;
1268 	}
1269 
1270 	if (!hdd_ctx->config) {
1271 		hdd_err("HDD config is null (via %s)", func);
1272 		return -ENODEV;
1273 	}
1274 
1275 	if (cds_is_driver_recovering()) {
1276 		hdd_debug("Recovery in progress (via %s); state:0x%x",
1277 			  func, cds_get_driver_state());
1278 		return -EAGAIN;
1279 	}
1280 
1281 	if (cds_is_load_or_unload_in_progress()) {
1282 		hdd_debug("Load/unload in progress (via %s); state:0x%x",
1283 			  func, cds_get_driver_state());
1284 		return -EAGAIN;
1285 	}
1286 
1287 	if (cds_is_driver_in_bad_state()) {
1288 		hdd_debug("Driver in bad state (via %s); state:0x%x",
1289 			  func, cds_get_driver_state());
1290 		return -EAGAIN;
1291 	}
1292 
1293 	if (cds_is_fw_down()) {
1294 		hdd_debug("FW is down (via %s); state:0x%x",
1295 			  func, cds_get_driver_state());
1296 		return -EAGAIN;
1297 	}
1298 
1299 	if (hdd_ctx->is_wlan_disabled) {
1300 		hdd_debug("WLAN is disabled by user space");
1301 		return -EAGAIN;
1302 	}
1303 
1304 	return 0;
1305 }
1306 
1307 int __hdd_validate_adapter(struct hdd_adapter *adapter, const char *func)
1308 {
1309 	if (!adapter) {
1310 		hdd_err("adapter is null (via %s)", func);
1311 		return -EINVAL;
1312 	}
1313 
1314 	if (adapter->magic != WLAN_HDD_ADAPTER_MAGIC) {
1315 		hdd_err("bad adapter magic (via %s)", func);
1316 		return -EINVAL;
1317 	}
1318 
1319 	if (!adapter->dev) {
1320 		hdd_err("adapter net_device is null (via %s)", func);
1321 		return -EINVAL;
1322 	}
1323 
1324 	if (!(adapter->dev->flags & IFF_UP)) {
1325 		hdd_debug_rl("adapter '%s' is not up (via %s)",
1326 			     adapter->dev->name, func);
1327 		return -EAGAIN;
1328 	}
1329 
1330 	return __wlan_hdd_validate_vdev_id(adapter->deflink->vdev_id, func);
1331 }
1332 
1333 int __wlan_hdd_validate_vdev_id(uint8_t vdev_id, const char *func)
1334 {
1335 	if (vdev_id == WLAN_UMAC_VDEV_ID_MAX) {
1336 		hdd_debug_rl("adapter is not up (via %s)", func);
1337 		return -EINVAL;
1338 	}
1339 
1340 	if (vdev_id >= WLAN_MAX_VDEVS) {
1341 		hdd_err("bad vdev Id:%u (via %s)", vdev_id, func);
1342 		return -EINVAL;
1343 	}
1344 
1345 	return 0;
1346 }
1347 
1348 QDF_STATUS __wlan_hdd_validate_mac_address(struct qdf_mac_addr *mac_addr,
1349 					   const char *func)
1350 {
1351 	if (!mac_addr) {
1352 		hdd_err("Received NULL mac address (via %s)", func);
1353 		return QDF_STATUS_E_INVAL;
1354 	}
1355 
1356 	if (qdf_is_macaddr_zero(mac_addr)) {
1357 		hdd_err("MAC is all zero (via %s)", func);
1358 		return QDF_STATUS_E_INVAL;
1359 	}
1360 
1361 	if (qdf_is_macaddr_broadcast(mac_addr)) {
1362 		hdd_err("MAC is Broadcast (via %s)", func);
1363 		return QDF_STATUS_E_INVAL;
1364 	}
1365 
1366 	if (QDF_NET_IS_MAC_MULTICAST(mac_addr->bytes)) {
1367 		hdd_err("MAC is Multicast (via %s)", func);
1368 		return QDF_STATUS_E_INVAL;
1369 	}
1370 
1371 	return QDF_STATUS_SUCCESS;
1372 }
1373 
1374 /**
1375  * wlan_hdd_validate_modules_state() - Check modules status
1376  * @hdd_ctx: HDD context pointer
1377  *
1378  * Check's the driver module's state and returns true if the
1379  * modules are enabled returns false if modules are closed.
1380  *
1381  * Return: True if modules are enabled or false.
1382  */
1383 bool wlan_hdd_validate_modules_state(struct hdd_context *hdd_ctx)
1384 {
1385 	if (hdd_ctx->driver_status != DRIVER_MODULES_ENABLED) {
1386 		hdd_info("Modules not enabled, Present status: %d",
1387 			 hdd_ctx->driver_status);
1388 		return false;
1389 	}
1390 
1391 	return true;
1392 }
1393 
1394 #ifdef FEATURE_RUNTIME_PM
1395 /**
1396  * hdd_runtime_suspend_context_init() - API to initialize HDD Runtime Contexts
1397  * @hdd_ctx: HDD context
1398  *
1399  * Return: None
1400  */
1401 static void hdd_runtime_suspend_context_init(struct hdd_context *hdd_ctx)
1402 {
1403 	struct hdd_runtime_pm_context *ctx = &hdd_ctx->runtime_context;
1404 
1405 	qdf_runtime_lock_init(&ctx->dfs);
1406 	qdf_runtime_lock_init(&ctx->connect);
1407 	qdf_runtime_lock_init(&ctx->user);
1408 	qdf_runtime_lock_init(&ctx->monitor_mode);
1409 	qdf_runtime_lock_init(&ctx->wow_unit_test);
1410 	qdf_runtime_lock_init(&ctx->system_suspend);
1411 	qdf_runtime_lock_init(&ctx->dyn_mac_addr_update);
1412 	qdf_runtime_lock_init(&ctx->vdev_destroy);
1413 	qdf_runtime_lock_init(&ctx->oem_data_cmd);
1414 
1415 	qdf_rtpm_register(QDF_RTPM_ID_WIPHY_SUSPEND, NULL);
1416 	qdf_rtpm_register(QDF_RTPM_ID_PM_QOS_NOTIFY, NULL);
1417 
1418 	ctx->is_user_wakelock_acquired = false;
1419 
1420 	wlan_scan_runtime_pm_init(hdd_ctx->pdev);
1421 }
1422 
1423 /**
1424  * hdd_runtime_suspend_context_deinit() - API to deinit HDD runtime context
1425  * @hdd_ctx: HDD Context
1426  *
1427  * Return: None
1428  */
1429 static void hdd_runtime_suspend_context_deinit(struct hdd_context *hdd_ctx)
1430 {
1431 	struct hdd_runtime_pm_context *ctx = &hdd_ctx->runtime_context;
1432 
1433 	if (ctx->is_user_wakelock_acquired)
1434 		qdf_runtime_pm_allow_suspend(&ctx->user);
1435 
1436 	qdf_runtime_lock_deinit(&ctx->oem_data_cmd);
1437 	qdf_runtime_lock_deinit(&ctx->dyn_mac_addr_update);
1438 	qdf_runtime_lock_deinit(&ctx->wow_unit_test);
1439 	qdf_runtime_lock_deinit(&ctx->monitor_mode);
1440 	qdf_runtime_lock_deinit(&ctx->user);
1441 	qdf_runtime_lock_deinit(&ctx->connect);
1442 	qdf_runtime_lock_deinit(&ctx->dfs);
1443 	qdf_runtime_lock_deinit(&ctx->system_suspend);
1444 	qdf_runtime_lock_deinit(&ctx->vdev_destroy);
1445 
1446 	qdf_rtpm_deregister(QDF_RTPM_ID_WIPHY_SUSPEND);
1447 	qdf_rtpm_deregister(QDF_RTPM_ID_PM_QOS_NOTIFY);
1448 
1449 	wlan_scan_runtime_pm_deinit(hdd_ctx->pdev);
1450 }
1451 
1452 #else /* FEATURE_RUNTIME_PM */
1453 static void hdd_runtime_suspend_context_init(struct hdd_context *hdd_ctx) {}
1454 static void hdd_runtime_suspend_context_deinit(struct hdd_context *hdd_ctx) {}
1455 #endif /* FEATURE_RUNTIME_PM */
1456 
1457 void hdd_update_macaddr(struct hdd_context *hdd_ctx,
1458 			struct qdf_mac_addr hw_macaddr, bool generate_mac_auto)
1459 {
1460 	int8_t i;
1461 	uint8_t macaddr_b3, tmp_br3;
1462 
1463 	/*
1464 	 * If "generate_mac_auto" is true, it indicates that all the
1465 	 * addresses are derived addresses, else the first addresses
1466 	 * is not derived address (It is provided by fw).
1467 	 */
1468 	if (!generate_mac_auto) {
1469 		qdf_mem_copy(hdd_ctx->provisioned_mac_addr[0].bytes,
1470 			     hw_macaddr.bytes, QDF_MAC_ADDR_SIZE);
1471 		hdd_ctx->num_provisioned_addr++;
1472 		hdd_debug("hdd_ctx->provisioned_mac_addr[0]: "
1473 			 QDF_MAC_ADDR_FMT,
1474 			 QDF_MAC_ADDR_REF(hdd_ctx->
1475 					provisioned_mac_addr[0].bytes));
1476 	} else {
1477 		qdf_mem_copy(hdd_ctx->derived_mac_addr[0].bytes,
1478 			     hw_macaddr.bytes,
1479 			     QDF_MAC_ADDR_SIZE);
1480 		hdd_ctx->num_derived_addr++;
1481 		hdd_debug("hdd_ctx->derived_mac_addr[0]: "
1482 			 QDF_MAC_ADDR_FMT,
1483 			 QDF_MAC_ADDR_REF(hdd_ctx->derived_mac_addr[0].bytes));
1484 	}
1485 	for (i = hdd_ctx->num_derived_addr; i < (QDF_MAX_CONCURRENCY_PERSONA -
1486 						hdd_ctx->num_provisioned_addr);
1487 			i++) {
1488 		qdf_mem_copy(hdd_ctx->derived_mac_addr[i].bytes,
1489 			     hw_macaddr.bytes,
1490 			     QDF_MAC_ADDR_SIZE);
1491 		macaddr_b3 = hdd_ctx->derived_mac_addr[i].bytes[3];
1492 		tmp_br3 = ((macaddr_b3 >> 4 & INTF_MACADDR_MASK) + i) &
1493 			  INTF_MACADDR_MASK;
1494 		macaddr_b3 += tmp_br3;
1495 
1496 		/* XOR-ing bit-24 of the mac address. This will give enough
1497 		 * mac address range before collision
1498 		 */
1499 		macaddr_b3 ^= (1 << 7);
1500 
1501 		/* Set locally administered bit */
1502 		hdd_ctx->derived_mac_addr[i].bytes[0] |= 0x02;
1503 		hdd_ctx->derived_mac_addr[i].bytes[3] = macaddr_b3;
1504 		hdd_debug("hdd_ctx->derived_mac_addr[%d]: "
1505 			QDF_MAC_ADDR_FMT, i,
1506 			QDF_MAC_ADDR_REF(hdd_ctx->derived_mac_addr[i].bytes));
1507 		hdd_ctx->num_derived_addr++;
1508 	}
1509 }
1510 
1511 #ifdef FEATURE_WLAN_TDLS
1512 static int hdd_update_tdls_config(struct hdd_context *hdd_ctx)
1513 {
1514 	struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc;
1515 	struct tdls_start_params tdls_cfg;
1516 	QDF_STATUS status;
1517 	struct wlan_mlme_nss_chains vdev_ini_cfg;
1518 
1519 	/* Populate the nss chain params from ini for this vdev type */
1520 	sme_populate_nss_chain_params(hdd_ctx->mac_handle, &vdev_ini_cfg,
1521 				      QDF_TDLS_MODE,
1522 				      hdd_ctx->num_rf_chains);
1523 
1524 	cfg_tdls_set_vdev_nss_2g(hdd_ctx->psoc,
1525 				 vdev_ini_cfg.rx_nss[NSS_CHAINS_BAND_2GHZ]);
1526 	cfg_tdls_set_vdev_nss_5g(hdd_ctx->psoc,
1527 				 vdev_ini_cfg.rx_nss[NSS_CHAINS_BAND_5GHZ]);
1528 	hdd_init_tdls_config(&tdls_cfg);
1529 	tdls_cfg.tdls_del_all_peers = eWNI_SME_DEL_ALL_TDLS_PEERS;
1530 	tdls_cfg.tdls_update_dp_vdev_flags = CDP_UPDATE_TDLS_FLAGS;
1531 	tdls_cfg.tdls_event_cb = wlan_cfg80211_tdls_event_callback;
1532 	tdls_cfg.tdls_evt_cb_data = psoc;
1533 	tdls_cfg.tdls_peer_context = hdd_ctx;
1534 	tdls_cfg.tdls_reg_peer = hdd_tdls_register_peer;
1535 	tdls_cfg.tdls_wmm_cb = hdd_wmm_is_acm_allowed;
1536 	tdls_cfg.tdls_wmm_cb_data = psoc;
1537 	tdls_cfg.tdls_rx_cb = wlan_cfg80211_tdls_rx_callback;
1538 	tdls_cfg.tdls_rx_cb_data = psoc;
1539 	tdls_cfg.tdls_dp_vdev_update = hdd_update_dp_vdev_flags;
1540 	tdls_cfg.tdls_osif_init_cb = wlan_cfg80211_tdls_osif_priv_init;
1541 	tdls_cfg.tdls_osif_deinit_cb = wlan_cfg80211_tdls_osif_priv_deinit;
1542 	tdls_cfg.tdls_osif_update_cb.tdls_osif_conn_update =
1543 					hdd_check_and_set_tdls_conn_params;
1544 	tdls_cfg.tdls_osif_update_cb.tdls_osif_disconn_update =
1545 					hdd_check_and_set_tdls_disconn_params;
1546 
1547 	status = ucfg_tdls_update_config(psoc, &tdls_cfg);
1548 	if (status != QDF_STATUS_SUCCESS) {
1549 		hdd_err("failed pmo psoc configuration");
1550 		return -EINVAL;
1551 	}
1552 
1553 	hdd_ctx->tdls_umac_comp_active = true;
1554 	/* enable napier specific tdls data path */
1555 	hdd_ctx->tdls_nap_active = true;
1556 
1557 	return 0;
1558 }
1559 #else
1560 static int hdd_update_tdls_config(struct hdd_context *hdd_ctx)
1561 {
1562 	return 0;
1563 }
1564 #endif
1565 
1566 void hdd_indicate_active_ndp_cnt(struct wlan_objmgr_psoc *psoc,
1567 				 uint8_t vdev_id, uint8_t cnt)
1568 {
1569 	struct wlan_hdd_link_info *link_info;
1570 
1571 	link_info = wlan_hdd_get_link_info_from_vdev(psoc, vdev_id);
1572 	if (!link_info || !cfg_nan_is_roam_config_disabled(psoc))
1573 		return;
1574 
1575 	hdd_debug("vdev_id:%d%s active ndp sessions present", vdev_id,
1576 		  cnt ? "" : " no more");
1577 	if (!cnt)
1578 		wlan_hdd_set_roaming_state(link_info, RSO_NDP_CON_ON_NDI, true);
1579 	else
1580 		wlan_hdd_set_roaming_state(link_info, RSO_NDP_CON_ON_NDI,
1581 					   false);
1582 }
1583 
1584 #ifdef WLAN_FEATURE_ROAM_OFFLOAD
1585 static void hdd_update_roam_offload(struct hdd_context *hdd_ctx,
1586 				    struct wma_tgt_services *cfg)
1587 {
1588 	bool roam_offload_enable;
1589 
1590 	ucfg_mlme_get_roaming_offload(hdd_ctx->psoc, &roam_offload_enable);
1591 	ucfg_mlme_set_roaming_offload(hdd_ctx->psoc,
1592 				      roam_offload_enable &
1593 				      cfg->en_roam_offload);
1594 }
1595 #else
1596 static inline void hdd_update_roam_offload(struct hdd_context *hdd_ctx,
1597 					   struct wma_tgt_services *cfg)
1598 {
1599 }
1600 #endif
1601 
1602 #ifdef FEATURE_CLUB_LL_STATS_AND_GET_STATION
1603 static void
1604 hdd_club_ll_stats_in_get_sta_cfg_update(struct hdd_config *config,
1605 					struct wlan_objmgr_psoc *psoc)
1606 {
1607 	config->sta_stats_cache_expiry_time =
1608 			cfg_get(psoc, CFG_STA_STATS_CACHE_EXPIRY);
1609 }
1610 
1611 static void
1612 hdd_update_feature_cfg_club_get_sta_in_ll_stats_req(
1613 					struct hdd_context *hdd_ctx,
1614 					struct wma_tgt_services *cfg)
1615 {
1616 	hdd_ctx->is_get_station_clubbed_in_ll_stats_req =
1617 				cfg->is_get_station_clubbed_in_ll_stats_req &&
1618 				cfg_get(hdd_ctx->psoc,
1619 					CFG_CLUB_LL_STA_AND_GET_STATION);
1620 }
1621 
1622 static void
1623 hdd_init_get_sta_in_ll_stats_config(struct hdd_adapter *adapter)
1624 {
1625 	adapter->sta_stats_cached_timestamp = 0;
1626 }
1627 #else
1628 static void
1629 hdd_club_ll_stats_in_get_sta_cfg_update(struct hdd_config *config,
1630 					struct wlan_objmgr_psoc *psoc)
1631 {
1632 }
1633 
1634 static void
1635 hdd_update_feature_cfg_club_get_sta_in_ll_stats_req(
1636 					struct hdd_context *hdd_ctx,
1637 					struct wma_tgt_services *cfg)
1638 {
1639 }
1640 
1641 static void
1642 hdd_init_get_sta_in_ll_stats_config(struct hdd_adapter *adapter)
1643 {
1644 }
1645 #endif /* FEATURE_CLUB_LL_STATS_AND_GET_STATION */
1646 
1647 #ifdef WLAN_FEATURE_IGMP_OFFLOAD
1648 static void
1649 hdd_intersect_igmp_offload_setting(struct wlan_objmgr_psoc *psoc,
1650 				   struct wma_tgt_services *cfg)
1651 {
1652 	bool igmp_offload_enable;
1653 
1654 	igmp_offload_enable =
1655 		ucfg_pmo_is_igmp_offload_enabled(psoc);
1656 	ucfg_pmo_set_igmp_offload_enabled(psoc,
1657 					  igmp_offload_enable &
1658 					  cfg->igmp_offload_enable);
1659 	hdd_info("fw cap to handle igmp %d igmp_offload_enable ini %d",
1660 		 cfg->igmp_offload_enable, igmp_offload_enable);
1661 }
1662 #else
1663 static inline void
1664 hdd_intersect_igmp_offload_setting(struct wlan_objmgr_psoc *psoc,
1665 				   struct wma_tgt_services *cfg)
1666 {}
1667 #endif
1668 
1669 #ifdef FEATURE_WLAN_TDLS
1670 static void hdd_update_fw_tdls_wideband_capability(struct hdd_context *hdd_ctx,
1671 						   struct wma_tgt_services *cfg)
1672 {
1673 	ucfg_tdls_update_fw_wideband_capability(hdd_ctx->psoc,
1674 						cfg->en_tdls_wideband_support);
1675 }
1676 
1677 #ifdef WLAN_FEATURE_11BE
1678 static void hdd_update_fw_tdls_mlo_capability(struct hdd_context *hdd_ctx,
1679 					      struct wma_tgt_services *cfg)
1680 {
1681 	ucfg_tdls_update_fw_mlo_capability(hdd_ctx->psoc,
1682 					   cfg->en_tdls_mlo_support);
1683 }
1684 #else
1685 static inline
1686 void hdd_update_fw_tdls_mlo_capability(struct hdd_context *hdd_ctx,
1687 				       struct wma_tgt_services *cfg)
1688 {}
1689 #endif
1690 
1691 #ifdef WLAN_FEATURE_11AX
1692 static void hdd_update_fw_tdls_11ax_capability(struct hdd_context *hdd_ctx,
1693 					       struct wma_tgt_services *cfg)
1694 {
1695 	ucfg_tdls_update_fw_11ax_capability(hdd_ctx->psoc,
1696 					    cfg->en_tdls_11ax_support);
1697 }
1698 
1699 static void hdd_update_fw_tdls_6g_capability(struct hdd_context *hdd_ctx,
1700 					     struct wma_tgt_services *cfg)
1701 {
1702 	ucfg_update_fw_tdls_6g_capability(hdd_ctx->psoc,
1703 					  cfg->en_tdls_6g_support);
1704 }
1705 
1706 #else
1707 static inline
1708 void hdd_update_fw_tdls_11ax_capability(struct hdd_context *hdd_ctx,
1709 					struct wma_tgt_services *cfg)
1710 {}
1711 static inline
1712 void hdd_update_fw_tdls_6g_capability(struct hdd_context *hdd_ctx,
1713 				      struct wma_tgt_services *cfg)
1714 {}
1715 #endif
1716 #else
1717 static inline
1718 void hdd_update_fw_tdls_mlo_capability(struct hdd_context *hdd_ctx,
1719 				       struct wma_tgt_services *cfg)
1720 {}
1721 
1722 static inline
1723 void hdd_update_fw_tdls_11ax_capability(struct hdd_context *hdd_ctx,
1724 					struct wma_tgt_services *cfg)
1725 {}
1726 
1727 static inline
1728 void hdd_update_fw_tdls_6g_capability(struct hdd_context *hdd_ctx,
1729 				      struct wma_tgt_services *cfg)
1730 {}
1731 
1732 static inline
1733 void hdd_update_fw_tdls_wideband_capability(struct hdd_context *hdd_ctx,
1734 					    struct wma_tgt_services *cfg)
1735 {}
1736 #endif
1737 
1738 #ifdef WLAN_FEATURE_DYNAMIC_MAC_ADDR_UPDATE
1739 static inline void
1740 hdd_set_dynamic_macaddr_update_capability(struct hdd_context *hdd_ctx,
1741 					  struct wma_tgt_services *cfg)
1742 {
1743 	hdd_ctx->is_vdev_macaddr_dynamic_update_supported =
1744 				cfg->dynamic_vdev_macaddr_support &&
1745 				cfg_get(hdd_ctx->psoc,
1746 					CFG_DYNAMIC_MAC_ADDR_UPDATE_SUPPORTED);
1747 }
1748 #else
1749 static inline void
1750 hdd_set_dynamic_macaddr_update_capability(struct hdd_context *hdd_ctx,
1751 					  struct wma_tgt_services *cfg)
1752 {
1753 }
1754 #endif
1755 
1756 #ifdef WLAN_FEATURE_11BE
1757 static bool hdd_dot11Mode_support_11be(enum hdd_dot11_mode dot11Mode)
1758 {
1759 	if (dot11Mode != eHDD_DOT11_MODE_AUTO &&
1760 	    dot11Mode < eHDD_DOT11_MODE_11be)
1761 		return false;
1762 
1763 	return true;
1764 }
1765 #else
1766 static bool hdd_dot11Mode_support_11be(enum hdd_dot11_mode dot11Mode)
1767 {
1768 	return false;
1769 }
1770 #endif
1771 
1772 #ifdef WLAN_FEATURE_11BE_MLO
1773 static void
1774 hdd_update_mlo_per_link_stats_capability(struct hdd_context *hdd_ctx,
1775 					 struct wma_tgt_services *cfg)
1776 {
1777 	hdd_ctx->is_mlo_per_link_stats_supported =
1778 				cfg->is_mlo_per_link_stats_supported;
1779 }
1780 #else
1781 static void
1782 hdd_update_mlo_per_link_stats_capability(struct hdd_context *hdd_ctx,
1783 					 struct wma_tgt_services *cfg)
1784 {
1785 }
1786 #endif
1787 
1788 static void hdd_update_tgt_services(struct hdd_context *hdd_ctx,
1789 				    struct wma_tgt_services *cfg)
1790 {
1791 	struct hdd_config *config = hdd_ctx->config;
1792 	bool arp_offload_enable;
1793 	bool mawc_enabled;
1794 #ifdef FEATURE_WLAN_TDLS
1795 	bool tdls_support;
1796 	bool tdls_off_channel;
1797 	bool tdls_buffer_sta;
1798 	uint32_t tdls_uapsd_mask;
1799 #endif
1800 	bool get_peer_info_enable;
1801 
1802 	/* Set up UAPSD */
1803 	ucfg_mlme_set_sap_uapsd_flag(hdd_ctx->psoc, cfg->uapsd);
1804 
1805 	/* 11AX mode support */
1806 	if ((config->dot11Mode == eHDD_DOT11_MODE_11ax ||
1807 	     config->dot11Mode == eHDD_DOT11_MODE_11ax_ONLY) && !cfg->en_11ax)
1808 		config->dot11Mode = eHDD_DOT11_MODE_11ac;
1809 
1810 	/* 11AC mode support */
1811 	if ((config->dot11Mode == eHDD_DOT11_MODE_11ac ||
1812 	     config->dot11Mode == eHDD_DOT11_MODE_11ac_ONLY) && !cfg->en_11ac)
1813 		config->dot11Mode = eHDD_DOT11_MODE_AUTO;
1814 	/* 11BE mode support */
1815 	if (!hdd_dot11Mode_support_11be(config->dot11Mode) &&
1816 	    cfg->en_11be) {
1817 		hdd_debug("dot11Mode %d override target en_11be to false",
1818 			  config->dot11Mode);
1819 		cfg->en_11be = false;
1820 	}
1821 
1822 	/* ARP offload: override user setting if invalid  */
1823 	arp_offload_enable =
1824 			ucfg_pmo_is_arp_offload_enabled(hdd_ctx->psoc);
1825 	ucfg_pmo_set_arp_offload_enabled(hdd_ctx->psoc,
1826 					 arp_offload_enable & cfg->arp_offload);
1827 
1828 	/* Intersect igmp offload ini configuration and fw cap*/
1829 	hdd_intersect_igmp_offload_setting(hdd_ctx->psoc, cfg);
1830 
1831 #ifdef FEATURE_WLAN_SCAN_PNO
1832 	/* PNO offload */
1833 	hdd_debug("PNO Capability in f/w = %d", cfg->pno_offload);
1834 	if (cfg->pno_offload)
1835 		ucfg_scan_set_pno_offload(hdd_ctx->psoc, true);
1836 #endif
1837 #ifdef FEATURE_WLAN_TDLS
1838 	cfg_tdls_get_support_enable(hdd_ctx->psoc, &tdls_support);
1839 	cfg_tdls_set_support_enable(hdd_ctx->psoc,
1840 				    tdls_support & cfg->en_tdls);
1841 
1842 	cfg_tdls_get_off_channel_enable(hdd_ctx->psoc, &tdls_off_channel);
1843 	cfg_tdls_set_off_channel_enable(hdd_ctx->psoc,
1844 					tdls_off_channel &&
1845 					cfg->en_tdls_offchan);
1846 
1847 	cfg_tdls_get_buffer_sta_enable(hdd_ctx->psoc, &tdls_buffer_sta);
1848 	cfg_tdls_set_buffer_sta_enable(hdd_ctx->psoc,
1849 				       tdls_buffer_sta &&
1850 				       cfg->en_tdls_uapsd_buf_sta);
1851 
1852 	cfg_tdls_get_uapsd_mask(hdd_ctx->psoc, &tdls_uapsd_mask);
1853 	if (tdls_uapsd_mask && cfg->en_tdls_uapsd_sleep_sta)
1854 		cfg_tdls_set_sleep_sta_enable(hdd_ctx->psoc, true);
1855 	else
1856 		cfg_tdls_set_sleep_sta_enable(hdd_ctx->psoc, false);
1857 #endif
1858 	hdd_update_roam_offload(hdd_ctx, cfg);
1859 
1860 	if (ucfg_mlme_get_sap_get_peer_info(
1861 		hdd_ctx->psoc, &get_peer_info_enable) == QDF_STATUS_SUCCESS) {
1862 		get_peer_info_enable &= cfg->get_peer_info_enabled;
1863 		ucfg_mlme_set_sap_get_peer_info(hdd_ctx->psoc,
1864 						get_peer_info_enable);
1865 	}
1866 
1867 	ucfg_mlme_is_mawc_enabled(hdd_ctx->psoc, &mawc_enabled);
1868 	ucfg_mlme_set_mawc_enabled(hdd_ctx->psoc,
1869 				   mawc_enabled & cfg->is_fw_mawc_capable);
1870 	hdd_update_tdls_config(hdd_ctx);
1871 	sme_update_tgt_services(hdd_ctx->mac_handle, cfg);
1872 	hdd_ctx->roam_ch_from_fw_supported = cfg->is_roam_scan_ch_to_host;
1873 	hdd_ctx->ll_stats_per_chan_rx_tx_time =
1874 					cfg->ll_stats_per_chan_rx_tx_time;
1875 
1876 	hdd_update_feature_cfg_club_get_sta_in_ll_stats_req(hdd_ctx, cfg);
1877 	hdd_ctx->is_therm_cmd_supp =
1878 				cfg->is_fw_therm_throt_supp &&
1879 				cfg_get(hdd_ctx->psoc,
1880 					CFG_THERMAL_MITIGATION_ENABLE);
1881 	hdd_update_fw_tdls_11ax_capability(hdd_ctx, cfg);
1882 	hdd_update_fw_tdls_mlo_capability(hdd_ctx, cfg);
1883 	hdd_set_dynamic_macaddr_update_capability(hdd_ctx, cfg);
1884 	hdd_update_fw_tdls_6g_capability(hdd_ctx, cfg);
1885 	hdd_update_fw_tdls_wideband_capability(hdd_ctx, cfg);
1886 	ucfg_psoc_mlme_set_11be_capab(hdd_ctx->psoc, cfg->en_11be);
1887 	hdd_update_mlo_per_link_stats_capability(hdd_ctx, cfg);
1888 }
1889 
1890 /**
1891  * hdd_update_vdev_nss() - sets the vdev nss
1892  * @hdd_ctx: HDD context
1893  *
1894  * Sets the Nss per vdev type based on INI
1895  *
1896  * Return: None
1897  */
1898 static void hdd_update_vdev_nss(struct hdd_context *hdd_ctx)
1899 {
1900 	uint8_t max_supp_nss = 1;
1901 	mac_handle_t mac_handle;
1902 	QDF_STATUS status;
1903 	bool bval;
1904 
1905 	status = ucfg_mlme_get_vht_enable2x2(hdd_ctx->psoc, &bval);
1906 	if (!QDF_IS_STATUS_SUCCESS(status))
1907 		hdd_err("unable to get vht_enable2x2");
1908 
1909 	if (bval && !cds_is_sub_20_mhz_enabled())
1910 		max_supp_nss = 2;
1911 
1912 	hdd_debug("max nss %d", max_supp_nss);
1913 
1914 	mac_handle = hdd_ctx->mac_handle;
1915 	sme_update_vdev_type_nss(mac_handle, max_supp_nss,
1916 				 NSS_CHAINS_BAND_2GHZ);
1917 
1918 	sme_update_vdev_type_nss(mac_handle, max_supp_nss,
1919 				 NSS_CHAINS_BAND_5GHZ);
1920 }
1921 
1922 /**
1923  * hdd_update_2g_wiphy_vhtcap() - Updates 2G wiphy vhtcap fields
1924  * @hdd_ctx: HDD context
1925  *
1926  * Updates 2G wiphy vhtcap fields
1927  *
1928  * Return: None
1929  */
1930 static void hdd_update_2g_wiphy_vhtcap(struct hdd_context *hdd_ctx)
1931 {
1932 	struct ieee80211_supported_band *band_2g =
1933 		hdd_ctx->wiphy->bands[NL80211_BAND_2GHZ];
1934 	uint32_t value;
1935 	bool is_vht_24ghz;
1936 
1937 	if (!band_2g) {
1938 		hdd_debug("2GHz band disabled, skipping capability population");
1939 		return;
1940 	}
1941 
1942 	ucfg_mlme_get_vht_for_24ghz(hdd_ctx->psoc, &is_vht_24ghz);
1943 
1944 	if (is_vht_24ghz) {
1945 		ucfg_mlme_cfg_get_vht_tx_mcs_map(hdd_ctx->psoc, &value);
1946 		band_2g->vht_cap.vht_mcs.tx_mcs_map = value;
1947 	}
1948 }
1949 
1950 /**
1951  * hdd_update_5g_wiphy_vhtcap() - Updates 5G wiphy vhtcap fields
1952  * @hdd_ctx: HDD context
1953  *
1954  * Updates 5G wiphy vhtcap fields
1955  *
1956  * Return: None
1957  */
1958 static void hdd_update_5g_wiphy_vhtcap(struct hdd_context *hdd_ctx)
1959 {
1960 	struct ieee80211_supported_band *band_5g =
1961 		hdd_ctx->wiphy->bands[NL80211_BAND_5GHZ];
1962 	QDF_STATUS status;
1963 	uint8_t value = 0, value1 = 0;
1964 	uint32_t value2;
1965 
1966 	if (!band_5g) {
1967 		hdd_debug("5GHz band disabled, skipping capability population");
1968 		return;
1969 	}
1970 
1971 	status = ucfg_mlme_cfg_get_vht_tx_bfee_ant_supp(hdd_ctx->psoc,
1972 							&value);
1973 	if (!QDF_IS_STATUS_SUCCESS(status))
1974 		hdd_err("unable to get tx_bfee_ant_supp");
1975 
1976 	band_5g->vht_cap.cap |=
1977 			(value << IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT);
1978 
1979 	value1 = NUM_OF_SOUNDING_DIMENSIONS;
1980 	band_5g->vht_cap.cap |=
1981 		(value1 << IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_SHIFT);
1982 
1983 	hdd_debug("Updated wiphy vhtcap:0x%x, CSNAntSupp:%d, NumSoundDim:%d",
1984 		  band_5g->vht_cap.cap, value, value1);
1985 
1986 	ucfg_mlme_cfg_get_vht_rx_mcs_map(hdd_ctx->psoc, &value2);
1987 	band_5g->vht_cap.vht_mcs.rx_mcs_map = value2;
1988 
1989 	ucfg_mlme_cfg_get_vht_tx_mcs_map(hdd_ctx->psoc, &value2);
1990 	band_5g->vht_cap.vht_mcs.tx_mcs_map = value2;
1991 }
1992 
1993 /**
1994  * hdd_update_wiphy_vhtcap() - Updates wiphy vhtcap fields
1995  * @hdd_ctx: HDD context
1996  *
1997  * Updates wiphy vhtcap fields
1998  *
1999  * Return: None
2000  */
2001 static void hdd_update_wiphy_vhtcap(struct hdd_context *hdd_ctx)
2002 {
2003 	hdd_update_2g_wiphy_vhtcap(hdd_ctx);
2004 	hdd_update_5g_wiphy_vhtcap(hdd_ctx);
2005 }
2006 
2007 static void hdd_update_tgt_ht_cap(struct hdd_context *hdd_ctx,
2008 				  struct wma_tgt_ht_cap *cfg)
2009 {
2010 	QDF_STATUS status;
2011 	qdf_size_t value_len;
2012 	uint32_t value;
2013 	uint8_t mpdu_density;
2014 	struct mlme_ht_capabilities_info ht_cap_info;
2015 	uint8_t mcs_set[SIZE_OF_SUPPORTED_MCS_SET];
2016 	bool b_enable1x1;
2017 
2018 	/* get the MPDU density */
2019 	status = ucfg_mlme_get_ht_mpdu_density(hdd_ctx->psoc, &mpdu_density);
2020 	if (QDF_IS_STATUS_ERROR(status)) {
2021 		hdd_err("could not get HT MPDU Density");
2022 		return;
2023 	}
2024 
2025 	/*
2026 	 * MPDU density:
2027 	 * override user's setting if value is larger
2028 	 * than the one supported by target,
2029 	 * if target value is 0, then follow user's setting.
2030 	 */
2031 	if (cfg->mpdu_density && mpdu_density > cfg->mpdu_density) {
2032 		status = ucfg_mlme_set_ht_mpdu_density(hdd_ctx->psoc,
2033 						       cfg->mpdu_density);
2034 		if (QDF_IS_STATUS_ERROR(status))
2035 			hdd_err("could not set HT capability to CCM");
2036 	}
2037 
2038 	/* get the HT capability info */
2039 	status = ucfg_mlme_get_ht_cap_info(hdd_ctx->psoc, &ht_cap_info);
2040 	if (QDF_STATUS_SUCCESS != status) {
2041 		hdd_err("could not get HT capability info");
2042 		return;
2043 	}
2044 
2045 	/* check and update RX STBC */
2046 	if (ht_cap_info.rx_stbc && !cfg->ht_rx_stbc)
2047 		ht_cap_info.rx_stbc = cfg->ht_rx_stbc;
2048 
2049 	/* Set the LDPC capability */
2050 	if (ht_cap_info.adv_coding_cap && !cfg->ht_rx_ldpc)
2051 		ht_cap_info.adv_coding_cap = cfg->ht_rx_ldpc;
2052 
2053 	if (ht_cap_info.short_gi_20_mhz && !cfg->ht_sgi_20)
2054 		ht_cap_info.short_gi_20_mhz = cfg->ht_sgi_20;
2055 
2056 	if (ht_cap_info.short_gi_40_mhz && !cfg->ht_sgi_40)
2057 		ht_cap_info.short_gi_40_mhz = cfg->ht_sgi_40;
2058 
2059 	hdd_ctx->num_rf_chains = cfg->num_rf_chains;
2060 	hdd_ctx->ht_tx_stbc_supported = cfg->ht_tx_stbc;
2061 
2062 	status = ucfg_mlme_get_vht_enable2x2(hdd_ctx->psoc, &b_enable1x1);
2063 	if (!QDF_IS_STATUS_SUCCESS(status))
2064 		hdd_err("unable to get vht_enable2x2");
2065 
2066 	b_enable1x1 = b_enable1x1 && (cfg->num_rf_chains == 2);
2067 
2068 	status = ucfg_mlme_set_vht_enable2x2(hdd_ctx->psoc, b_enable1x1);
2069 	if (!QDF_IS_STATUS_SUCCESS(status))
2070 		hdd_err("unable to set vht_enable2x2");
2071 
2072 	if (!b_enable1x1)
2073 		ht_cap_info.tx_stbc = 0;
2074 
2075 	if (!(cfg->ht_tx_stbc && b_enable1x1))
2076 		ht_cap_info.tx_stbc = 0;
2077 
2078 	status = ucfg_mlme_set_ht_cap_info(hdd_ctx->psoc, ht_cap_info);
2079 	if (status != QDF_STATUS_SUCCESS)
2080 		hdd_err("could not set HT capability to CCM");
2081 #define WLAN_HDD_RX_MCS_ALL_NSTREAM_RATES 0xff
2082 	value_len = SIZE_OF_SUPPORTED_MCS_SET;
2083 	if (ucfg_mlme_get_supported_mcs_set(
2084 				hdd_ctx->psoc, mcs_set,
2085 				&value_len) == QDF_STATUS_SUCCESS) {
2086 		hdd_debug("Read MCS rate set");
2087 		if (cfg->num_rf_chains > SIZE_OF_SUPPORTED_MCS_SET)
2088 			cfg->num_rf_chains = SIZE_OF_SUPPORTED_MCS_SET;
2089 
2090 		if (b_enable1x1) {
2091 			for (value = 0; value < cfg->num_rf_chains; value++)
2092 				mcs_set[value] =
2093 					WLAN_HDD_RX_MCS_ALL_NSTREAM_RATES;
2094 
2095 			status = ucfg_mlme_set_supported_mcs_set(
2096 					hdd_ctx->psoc,
2097 					mcs_set,
2098 					(qdf_size_t)SIZE_OF_SUPPORTED_MCS_SET);
2099 			if (QDF_IS_STATUS_ERROR(status))
2100 				hdd_err("could not set MCS SET to CCM");
2101 		}
2102 	}
2103 #undef WLAN_HDD_RX_MCS_ALL_NSTREAM_RATES
2104 }
2105 
2106 static void hdd_update_tgt_vht_cap(struct hdd_context *hdd_ctx,
2107 				   struct wma_tgt_vht_cap *cfg)
2108 {
2109 	QDF_STATUS status;
2110 	struct wiphy *wiphy = hdd_ctx->wiphy;
2111 	struct ieee80211_supported_band *band_5g =
2112 		wiphy->bands[HDD_NL80211_BAND_5GHZ];
2113 	uint32_t ch_width;
2114 	struct wma_caps_per_phy caps_per_phy = {0};
2115 	bool vht_enable_2x2;
2116 	uint32_t tx_highest_data_rate;
2117 	uint32_t rx_highest_data_rate;
2118 
2119 	if (!band_5g) {
2120 		hdd_debug("5GHz band disabled, skipping capability population");
2121 		return;
2122 	}
2123 
2124 	status = ucfg_mlme_update_vht_cap(hdd_ctx->psoc, cfg);
2125 	if (QDF_IS_STATUS_ERROR(status))
2126 		hdd_err("could not update vht capabilities");
2127 
2128 	status = ucfg_mlme_get_vht_enable2x2(hdd_ctx->psoc, &vht_enable_2x2);
2129 	if (!QDF_IS_STATUS_SUCCESS(status))
2130 		hdd_err("unable to get vht_enable2x2");
2131 
2132 	if (vht_enable_2x2) {
2133 		tx_highest_data_rate =
2134 				VHT_TX_HIGHEST_SUPPORTED_DATA_RATE_2_2;
2135 		rx_highest_data_rate =
2136 				VHT_RX_HIGHEST_SUPPORTED_DATA_RATE_2_2;
2137 	} else {
2138 		tx_highest_data_rate =
2139 				VHT_TX_HIGHEST_SUPPORTED_DATA_RATE_1_1;
2140 		rx_highest_data_rate =
2141 				VHT_RX_HIGHEST_SUPPORTED_DATA_RATE_1_1;
2142 	}
2143 
2144 	status = ucfg_mlme_cfg_set_vht_rx_supp_data_rate(hdd_ctx->psoc,
2145 							 rx_highest_data_rate);
2146 	if (!QDF_IS_STATUS_SUCCESS(status))
2147 		hdd_err("Failed to set rx_supp_data_rate");
2148 
2149 	status = ucfg_mlme_cfg_set_vht_tx_supp_data_rate(hdd_ctx->psoc,
2150 							 tx_highest_data_rate);
2151 	if (!QDF_IS_STATUS_SUCCESS(status))
2152 		hdd_err("Failed to set tx_supp_data_rate");
2153 
2154 	/* Update the real highest data rate to wiphy */
2155 	if (cfg->vht_short_gi_80 & WMI_VHT_CAP_SGI_80MHZ) {
2156 		if (vht_enable_2x2) {
2157 			tx_highest_data_rate =
2158 				VHT_TX_HIGHEST_SUPPORTED_DATA_RATE_2_2_SGI80;
2159 			rx_highest_data_rate =
2160 				VHT_RX_HIGHEST_SUPPORTED_DATA_RATE_2_2_SGI80;
2161 		} else {
2162 			tx_highest_data_rate =
2163 				VHT_TX_HIGHEST_SUPPORTED_DATA_RATE_1_1_SGI80;
2164 			rx_highest_data_rate =
2165 				VHT_RX_HIGHEST_SUPPORTED_DATA_RATE_1_1_SGI80;
2166 		}
2167 	}
2168 
2169 	if (WMI_VHT_CAP_MAX_MPDU_LEN_11454 == cfg->vht_max_mpdu)
2170 		band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454;
2171 	else if (WMI_VHT_CAP_MAX_MPDU_LEN_7935 == cfg->vht_max_mpdu)
2172 		band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_7991;
2173 	else
2174 		band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_3895;
2175 
2176 
2177 	if (cfg->supp_chan_width & (1 << eHT_CHANNEL_WIDTH_80P80MHZ)) {
2178 		band_5g->vht_cap.cap |=
2179 			IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ;
2180 		ch_width = VHT_CAP_160_AND_80P80_SUPP;
2181 	} else if (cfg->supp_chan_width & (1 << eHT_CHANNEL_WIDTH_160MHZ)) {
2182 		band_5g->vht_cap.cap |=
2183 			IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ;
2184 		ch_width = VHT_CAP_160_SUPP;
2185 	} else {
2186 		ch_width = VHT_CAP_NO_160M_SUPP;
2187 	}
2188 
2189 	status = ucfg_mlme_set_vht_ch_width(hdd_ctx->psoc, ch_width);
2190 	if (QDF_IS_STATUS_ERROR(status))
2191 		hdd_err("could not set the channel width");
2192 	else
2193 		hdd_debug("supported channel width %d", ch_width);
2194 
2195 	if (cfg->vht_rx_ldpc & WMI_VHT_CAP_RX_LDPC) {
2196 		band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_RXLDPC;
2197 		hdd_debug("VHT RxLDPC capability is set");
2198 	} else {
2199 		/*
2200 		 * Get the RX LDPC capability for the NON DBS
2201 		 * hardware mode for 5G band
2202 		 */
2203 		status = wma_get_caps_for_phyidx_hwmode(&caps_per_phy,
2204 					HW_MODE_DBS_NONE, CDS_BAND_5GHZ);
2205 		if ((QDF_IS_STATUS_SUCCESS(status)) &&
2206 			(caps_per_phy.vht_5g & WMI_VHT_CAP_RX_LDPC)) {
2207 			band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_RXLDPC;
2208 			hdd_debug("VHT RX LDPC capability is set");
2209 		}
2210 	}
2211 
2212 	if (cfg->vht_short_gi_80 & WMI_VHT_CAP_SGI_80MHZ)
2213 		band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_SHORT_GI_80;
2214 	if (cfg->vht_short_gi_160 & WMI_VHT_CAP_SGI_160MHZ)
2215 		band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_SHORT_GI_160;
2216 
2217 	if (vht_enable_2x2 && (cfg->vht_tx_stbc & WMI_VHT_CAP_TX_STBC))
2218 		band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_TXSTBC;
2219 
2220 	if (cfg->vht_rx_stbc & WMI_VHT_CAP_RX_STBC_1SS)
2221 		band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_RXSTBC_1;
2222 	if (vht_enable_2x2 && (cfg->vht_rx_stbc & WMI_VHT_CAP_RX_STBC_2SS))
2223 		band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_RXSTBC_2;
2224 	if (cfg->vht_rx_stbc & WMI_VHT_CAP_RX_STBC_3SS)
2225 		band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_RXSTBC_3;
2226 
2227 	band_5g->vht_cap.cap |=
2228 		(cfg->vht_max_ampdu_len_exp <<
2229 		 IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT);
2230 
2231 	if (cfg->vht_su_bformer & WMI_VHT_CAP_SU_BFORMER)
2232 		band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE;
2233 	if (cfg->vht_su_bformee & WMI_VHT_CAP_SU_BFORMEE)
2234 		band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE;
2235 	if (cfg->vht_mu_bformer & WMI_VHT_CAP_MU_BFORMER)
2236 		band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE;
2237 	if (cfg->vht_mu_bformee & WMI_VHT_CAP_MU_BFORMEE)
2238 		band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE;
2239 
2240 	if (cfg->vht_txop_ps & WMI_VHT_CAP_TXOP_PS)
2241 		band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_VHT_TXOP_PS;
2242 
2243 	band_5g->vht_cap.vht_mcs.rx_highest = cpu_to_le16(rx_highest_data_rate);
2244 	band_5g->vht_cap.vht_mcs.tx_highest = cpu_to_le16(tx_highest_data_rate);
2245 }
2246 
2247 /**
2248  * hdd_generate_macaddr_auto() - Auto-generate mac address
2249  * @hdd_ctx: Pointer to the HDD context
2250  *
2251  * Auto-generate mac address using device serial number.
2252  * Keep the first 3 bytes of OUI as before and replace
2253  * the last 3 bytes with the lower 3 bytes of serial number.
2254  *
2255  * Return: 0 for success
2256  *         Non zero failure code for errors
2257  */
2258 static int hdd_generate_macaddr_auto(struct hdd_context *hdd_ctx)
2259 {
2260 	unsigned int serialno = 0;
2261 	struct qdf_mac_addr mac_addr = {
2262 		{0x00, 0x0A, 0xF5, 0x00, 0x00, 0x00}
2263 	};
2264 
2265 	serialno = pld_socinfo_get_serial_number(hdd_ctx->parent_dev);
2266 	if (serialno == 0)
2267 		return -EINVAL;
2268 
2269 	serialno &= 0x00ffffff;
2270 
2271 	mac_addr.bytes[3] = (serialno >> 16) & 0xff;
2272 	mac_addr.bytes[4] = (serialno >> 8) & 0xff;
2273 	mac_addr.bytes[5] = serialno & 0xff;
2274 
2275 	hdd_update_macaddr(hdd_ctx, mac_addr, true);
2276 	return 0;
2277 }
2278 
2279 static void hdd_sar_target_config(struct hdd_context *hdd_ctx,
2280 				  struct wma_tgt_cfg *cfg)
2281 {
2282 	hdd_ctx->sar_version = cfg->sar_version;
2283 }
2284 
2285 static void hdd_update_vhtcap_2g(struct hdd_context *hdd_ctx)
2286 {
2287 	uint64_t chip_mode = 0;
2288 	QDF_STATUS status;
2289 	bool b2g_vht_cfg = false;
2290 	bool b2g_vht_target = false;
2291 	struct wma_caps_per_phy caps_per_phy = {0};
2292 	struct wmi_unified *wmi_handle;
2293 
2294 	wmi_handle = get_wmi_unified_hdl_from_psoc(hdd_ctx->psoc);
2295 	if (!wmi_handle) {
2296 		hdd_err("wmi handle is NULL");
2297 		return;
2298 	}
2299 
2300 	status = ucfg_mlme_get_vht_for_24ghz(hdd_ctx->psoc, &b2g_vht_cfg);
2301 	if (QDF_IS_STATUS_ERROR(status)) {
2302 		hdd_err("Failed to get 2g vht mode");
2303 		return;
2304 	}
2305 	if (wmi_service_enabled(wmi_handle, wmi_service_ext_msg)) {
2306 		status = wma_get_caps_for_phyidx_hwmode(&caps_per_phy,
2307 							HW_MODE_DBS_NONE,
2308 							CDS_BAND_2GHZ);
2309 		if (QDF_IS_STATUS_ERROR(status)) {
2310 			hdd_err("Failed to get phy caps");
2311 			return;
2312 		}
2313 		if (caps_per_phy.vht_2g)
2314 			b2g_vht_target = true;
2315 	} else {
2316 		status = wlan_reg_get_chip_mode(hdd_ctx->pdev, &chip_mode);
2317 		if (QDF_IS_STATUS_ERROR(status)) {
2318 			hdd_err("Failed to get chip mode");
2319 			return;
2320 		}
2321 		b2g_vht_target =
2322 		(chip_mode & HOST_REGDMN_MODE_11AC_VHT20_2G) ?
2323 		true : false;
2324 	}
2325 
2326 	b2g_vht_cfg = b2g_vht_cfg && b2g_vht_target;
2327 	hdd_debug("vht 2g target: %d, cfg: %d", b2g_vht_target, b2g_vht_cfg);
2328 	status = ucfg_mlme_set_vht_for_24ghz(hdd_ctx->psoc, b2g_vht_cfg);
2329 	if (QDF_IS_STATUS_ERROR(status)) {
2330 		hdd_err("Failed to update 2g vht mode");
2331 		return;
2332 	}
2333 }
2334 
2335 static void hdd_extract_fw_version_info(struct hdd_context *hdd_ctx)
2336 {
2337 	hdd_ctx->fw_version_info.major_spid =
2338 			HDD_FW_VER_MAJOR_SPID(hdd_ctx->target_fw_version);
2339 	hdd_ctx->fw_version_info.minor_spid =
2340 			HDD_FW_VER_MINOR_SPID(hdd_ctx->target_fw_version);
2341 	hdd_ctx->fw_version_info.siid =
2342 			HDD_FW_VER_SIID(hdd_ctx->target_fw_version);
2343 	hdd_ctx->fw_version_info.crmid =
2344 			HDD_FW_VER_CRM_ID(hdd_ctx->target_fw_version);
2345 	hdd_ctx->fw_version_info.sub_id =
2346 			HDD_FW_VER_SUB_ID(hdd_ctx->target_fw_vers_ext);
2347 	hdd_ctx->fw_version_info.rel_id =
2348 			HDD_FW_VER_REL_ID(hdd_ctx->target_fw_vers_ext);
2349 }
2350 
2351 #if defined(WLAN_FEATURE_11AX) && \
2352 	(defined(CFG80211_SBAND_IFTYPE_DATA_BACKPORT) || \
2353 	 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0)))
2354 
2355 static void
2356 hdd_update_wiphy_he_mcs(struct ieee80211_sband_iftype_data *iftype_data,
2357 			tDot11fIEhe_cap *he_cap_cfg)
2358 {
2359 	if (!iftype_data || !he_cap_cfg) {
2360 		hdd_err("Unable to update wiphy he_mcs");
2361 		return;
2362 	}
2363 
2364 	iftype_data->he_cap.he_mcs_nss_supp.tx_mcs_80 =
2365 		he_cap_cfg->tx_he_mcs_map_lt_80;
2366 	iftype_data->he_cap.he_mcs_nss_supp.tx_mcs_160 =
2367 		*((uint16_t *)he_cap_cfg->tx_he_mcs_map_160);
2368 	iftype_data->he_cap.he_mcs_nss_supp.tx_mcs_80p80 =
2369 		*((uint16_t *)he_cap_cfg->tx_he_mcs_map_80_80);
2370 }
2371 
2372 #if defined(CONFIG_BAND_6GHZ) && (defined(IEEE80211_HE_6GHZ_CAP_MIN_MPDU_START))
2373 static void hdd_update_wiphy_he_6ghz_capa(struct hdd_context *hdd_ctx)
2374 {
2375 	uint16_t he_6ghz_capa = 0;
2376 	uint8_t min_mpdu_start_spacing;
2377 	uint8_t max_ampdu_len_exp;
2378 	uint8_t max_mpdu_len;
2379 	uint8_t sm_pow_save;
2380 
2381 	ucfg_mlme_get_ht_mpdu_density(hdd_ctx->psoc, &min_mpdu_start_spacing);
2382 	he_6ghz_capa |= FIELD_PREP(IEEE80211_HE_6GHZ_CAP_MIN_MPDU_START,
2383 				   min_mpdu_start_spacing);
2384 
2385 	ucfg_mlme_cfg_get_vht_ampdu_len_exp(hdd_ctx->psoc, &max_ampdu_len_exp);
2386 	he_6ghz_capa |= FIELD_PREP(IEEE80211_HE_6GHZ_CAP_MAX_AMPDU_LEN_EXP,
2387 				   max_ampdu_len_exp);
2388 
2389 	ucfg_mlme_cfg_get_vht_max_mpdu_len(hdd_ctx->psoc, &max_mpdu_len);
2390 	he_6ghz_capa |= FIELD_PREP(IEEE80211_HE_6GHZ_CAP_MAX_MPDU_LEN,
2391 				   max_mpdu_len);
2392 
2393 	ucfg_mlme_cfg_get_ht_smps(hdd_ctx->psoc, &sm_pow_save);
2394 	he_6ghz_capa |= FIELD_PREP(IEEE80211_HE_6GHZ_CAP_SM_PS, sm_pow_save);
2395 
2396 	he_6ghz_capa |= IEEE80211_HE_6GHZ_CAP_RX_ANTPAT_CONS;
2397 	he_6ghz_capa |= IEEE80211_HE_6GHZ_CAP_TX_ANTPAT_CONS;
2398 
2399 	hdd_ctx->iftype_data_6g->he_6ghz_capa.capa = he_6ghz_capa;
2400 }
2401 #else
2402 static inline void hdd_update_wiphy_he_6ghz_capa(struct hdd_context *hdd_ctx)
2403 {
2404 }
2405 #endif
2406 
2407 #if defined(CONFIG_BAND_6GHZ) && (defined(CFG80211_6GHZ_BAND_SUPPORTED) || \
2408       (KERNEL_VERSION(5, 4, 0) <= LINUX_VERSION_CODE))
2409 static void
2410 hdd_update_wiphy_he_caps_6ghz(struct hdd_context *hdd_ctx,
2411 			      tDot11fIEhe_cap *he_cap_cfg)
2412 {
2413 	struct ieee80211_supported_band *band_6g =
2414 		   hdd_ctx->wiphy->bands[HDD_NL80211_BAND_6GHZ];
2415 	uint8_t *phy_info =
2416 		    hdd_ctx->iftype_data_6g->he_cap.he_cap_elem.phy_cap_info;
2417 	uint8_t *mac_info_6g =
2418 		hdd_ctx->iftype_data_6g->he_cap.he_cap_elem.mac_cap_info;
2419 	uint8_t max_fw_bw = sme_get_vht_ch_width();
2420 
2421 	if (!band_6g || !phy_info) {
2422 		hdd_debug("6ghz not supported in wiphy");
2423 		return;
2424 	}
2425 
2426 	hdd_ctx->iftype_data_6g->types_mask =
2427 		(BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP));
2428 	hdd_ctx->iftype_data_6g->he_cap.has_he = true;
2429 	band_6g->n_iftype_data = 1;
2430 
2431 	if (max_fw_bw >= WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ)
2432 		phy_info[0] |=
2433 		      IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_80MHZ_IN_5G;
2434 	if (max_fw_bw >= WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ)
2435 		phy_info[0] |=
2436 			IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_160MHZ_IN_5G;
2437 	if (max_fw_bw >= WNI_CFG_VHT_CHANNEL_WIDTH_80_PLUS_80MHZ)
2438 		phy_info[0] |=
2439 		     IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G;
2440 
2441 	if (he_cap_cfg->twt_request)
2442 		mac_info_6g[0] |= IEEE80211_HE_MAC_CAP0_TWT_REQ;
2443 
2444 	if (he_cap_cfg->twt_responder)
2445 		mac_info_6g[0] |= IEEE80211_HE_MAC_CAP0_TWT_RES;
2446 
2447 	hdd_update_wiphy_he_6ghz_capa(hdd_ctx);
2448 
2449 	hdd_update_wiphy_he_mcs(hdd_ctx->iftype_data_6g, he_cap_cfg);
2450 
2451 	band_6g->iftype_data = hdd_ctx->iftype_data_6g;
2452 }
2453 #else
2454 static inline void
2455 hdd_update_wiphy_he_caps_6ghz(struct hdd_context *hdd_ctx,
2456 			      tDot11fIEhe_cap *he_cap_cfg)
2457 {
2458 }
2459 #endif
2460 
2461 static void hdd_update_wiphy_he_cap(struct hdd_context *hdd_ctx)
2462 {
2463 	tDot11fIEhe_cap he_cap_cfg;
2464 	struct ieee80211_supported_band *band_2g =
2465 			hdd_ctx->wiphy->bands[HDD_NL80211_BAND_2GHZ];
2466 	struct ieee80211_supported_band *band_5g =
2467 			hdd_ctx->wiphy->bands[HDD_NL80211_BAND_5GHZ];
2468 	QDF_STATUS status;
2469 	uint8_t *phy_info_5g =
2470 		    hdd_ctx->iftype_data_5g->he_cap.he_cap_elem.phy_cap_info;
2471 	uint8_t max_fw_bw = sme_get_vht_ch_width();
2472 	uint32_t channel_bonding_mode_2g;
2473 	uint8_t *phy_info_2g =
2474 		    hdd_ctx->iftype_data_2g->he_cap.he_cap_elem.phy_cap_info;
2475 	uint8_t *mac_info_2g =
2476 		hdd_ctx->iftype_data_2g->he_cap.he_cap_elem.mac_cap_info;
2477 	uint8_t *mac_info_5g =
2478 		hdd_ctx->iftype_data_5g->he_cap.he_cap_elem.mac_cap_info;
2479 
2480 	status = ucfg_mlme_cfg_get_he_caps(hdd_ctx->psoc, &he_cap_cfg);
2481 
2482 	if (QDF_IS_STATUS_ERROR(status))
2483 		return;
2484 
2485 	if (band_2g) {
2486 		hdd_ctx->iftype_data_2g->types_mask =
2487 			(BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP));
2488 		hdd_ctx->iftype_data_2g->he_cap.has_he = he_cap_cfg.present;
2489 		band_2g->n_iftype_data = 1;
2490 		hdd_update_wiphy_he_mcs(hdd_ctx->iftype_data_2g, &he_cap_cfg);
2491 		band_2g->iftype_data = hdd_ctx->iftype_data_2g;
2492 
2493 		ucfg_mlme_get_channel_bonding_24ghz(hdd_ctx->psoc,
2494 						    &channel_bonding_mode_2g);
2495 		if (channel_bonding_mode_2g)
2496 			phy_info_2g[0] |=
2497 			    IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_IN_2G;
2498 
2499 		if (he_cap_cfg.twt_request)
2500 			mac_info_2g[0] |= IEEE80211_HE_MAC_CAP0_TWT_REQ;
2501 
2502 		if (he_cap_cfg.twt_responder)
2503 			mac_info_2g[0] |= IEEE80211_HE_MAC_CAP0_TWT_RES;
2504 	}
2505 	if (band_5g) {
2506 		hdd_ctx->iftype_data_5g->types_mask =
2507 			(BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP));
2508 		hdd_ctx->iftype_data_5g->he_cap.has_he = he_cap_cfg.present;
2509 		band_5g->n_iftype_data = 1;
2510 		hdd_update_wiphy_he_mcs(hdd_ctx->iftype_data_5g, &he_cap_cfg);
2511 		band_5g->iftype_data = hdd_ctx->iftype_data_5g;
2512 
2513 		if (max_fw_bw >= WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ)
2514 			phy_info_5g[0] |=
2515 				IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_80MHZ_IN_5G;
2516 		if (max_fw_bw >= WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ)
2517 			phy_info_5g[0] |=
2518 				IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_160MHZ_IN_5G;
2519 		if (max_fw_bw >= WNI_CFG_VHT_CHANNEL_WIDTH_80_PLUS_80MHZ)
2520 			phy_info_5g[0] |=
2521 			     IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G;
2522 
2523 		if (he_cap_cfg.twt_request)
2524 			mac_info_5g[0] |= IEEE80211_HE_MAC_CAP0_TWT_REQ;
2525 
2526 		if (he_cap_cfg.twt_responder)
2527 			mac_info_5g[0] |= IEEE80211_HE_MAC_CAP0_TWT_RES;
2528 	}
2529 
2530 	hdd_update_wiphy_he_caps_6ghz(hdd_ctx, &he_cap_cfg);
2531 }
2532 #else
2533 static void hdd_update_wiphy_he_cap(struct hdd_context *hdd_ctx)
2534 {
2535 }
2536 #endif
2537 
2538 static void hdd_component_cfg_chan_to_freq(struct wlan_objmgr_pdev *pdev)
2539 {
2540 	ucfg_mlme_cfg_chan_to_freq(pdev);
2541 }
2542 
2543 static uint32_t hdd_update_band_cap_from_dot11mode(
2544 		struct hdd_context *hdd_ctx, uint32_t band_capability)
2545 {
2546 	if (hdd_ctx->config->dot11Mode == eHDD_DOT11_MODE_AUTO)
2547 		return band_capability;
2548 
2549 	if (hdd_ctx->config->dot11Mode == eHDD_DOT11_MODE_11b ||
2550 	    hdd_ctx->config->dot11Mode == eHDD_DOT11_MODE_11g ||
2551 	    hdd_ctx->config->dot11Mode == eHDD_DOT11_MODE_11g_ONLY ||
2552 	    hdd_ctx->config->dot11Mode == eHDD_DOT11_MODE_11b_ONLY)
2553 		band_capability = (band_capability & (~BIT(REG_BAND_5G)));
2554 
2555 	if (hdd_ctx->config->dot11Mode == eHDD_DOT11_MODE_11a)
2556 		band_capability = (band_capability & (~BIT(REG_BAND_2G)));
2557 
2558 	if (hdd_ctx->config->dot11Mode != eHDD_DOT11_MODE_11ax_ONLY &&
2559 	    hdd_ctx->config->dot11Mode != eHDD_DOT11_MODE_11ax)
2560 		band_capability = (band_capability & (~BIT(REG_BAND_6G)));
2561 
2562 	qdf_debug("Update band capability %x", band_capability);
2563 	return band_capability;
2564 }
2565 
2566 #ifdef FEATURE_WPSS_THERMAL_MITIGATION
2567 static inline
2568 void hdd_update_multi_client_thermal_support(struct hdd_context *hdd_ctx)
2569 {
2570 	struct wmi_unified *wmi_handle;
2571 
2572 	wmi_handle = get_wmi_unified_hdl_from_psoc(hdd_ctx->psoc);
2573 	if (!wmi_handle)
2574 		return;
2575 
2576 	hdd_ctx->multi_client_thermal_mitigation =
2577 		wmi_service_enabled(wmi_handle,
2578 				    wmi_service_thermal_multi_client_support);
2579 }
2580 #else
2581 static inline
2582 void hdd_update_multi_client_thermal_support(struct hdd_context *hdd_ctx)
2583 {
2584 }
2585 #endif
2586 
2587 #ifdef WLAN_FEATURE_LOCAL_PKT_CAPTURE
2588 static void hdd_lpc_enable_powersave(struct hdd_context *hdd_ctx)
2589 {
2590 	struct hdd_adapter *sta_adapter;
2591 
2592 	if (!ucfg_dp_is_local_pkt_capture_enabled(hdd_ctx->psoc))
2593 		return;
2594 
2595 	ucfg_fwol_configure_global_params(hdd_ctx->psoc, hdd_ctx->pdev);
2596 
2597 	sta_adapter = hdd_get_adapter(hdd_ctx, QDF_STA_MODE);
2598 	if (!sta_adapter) {
2599 		hdd_debug("STA adapter does not exist");
2600 		return;
2601 	}
2602 
2603 	wlan_hdd_set_powersave(sta_adapter->deflink, true, 0);
2604 }
2605 
2606 static void hdd_lpc_disable_powersave(struct hdd_context *hdd_ctx)
2607 {
2608 	struct hdd_adapter *sta_adapter;
2609 
2610 	if (!ucfg_dp_is_local_pkt_capture_enabled(hdd_ctx->psoc))
2611 		return;
2612 
2613 	ucfg_fwol_set_ilp_config(hdd_ctx->psoc, hdd_ctx->pdev, 0);
2614 
2615 	sta_adapter = hdd_get_adapter(hdd_ctx, QDF_STA_MODE);
2616 	if (!sta_adapter) {
2617 		hdd_err("STA adapter does not exist");
2618 		return;
2619 	}
2620 	wlan_hdd_set_powersave(sta_adapter->deflink, false, 0);
2621 }
2622 #else
2623 static inline void hdd_lpc_enable_powersave(struct hdd_context *hdd_ctx)
2624 {
2625 }
2626 
2627 static inline void hdd_lpc_disable_powersave(struct hdd_context *hdd_ctx)
2628 {
2629 }
2630 #endif
2631 
2632 int hdd_update_tgt_cfg(hdd_handle_t hdd_handle, struct wma_tgt_cfg *cfg)
2633 {
2634 	int ret;
2635 	struct hdd_context *hdd_ctx = hdd_handle_to_context(hdd_handle);
2636 	uint32_t temp_band_cap, band_capability;
2637 	struct cds_config_info *cds_cfg = cds_get_ini_config();
2638 	uint8_t antenna_mode;
2639 	uint8_t sub_20_chan_width;
2640 	QDF_STATUS status;
2641 	mac_handle_t mac_handle;
2642 	bool bval = false;
2643 	uint8_t value = 0;
2644 	uint32_t fine_time_meas_cap = 0;
2645 	enum nss_chains_band_info band;
2646 	bool enable_dynamic_cfg;
2647 
2648 	if (!hdd_ctx) {
2649 		hdd_err("HDD context is NULL");
2650 		return -EINVAL;
2651 	}
2652 	ret = hdd_objmgr_create_and_store_pdev(hdd_ctx);
2653 	if (ret) {
2654 		QDF_DEBUG_PANIC("Failed to create pdev; errno:%d", ret);
2655 		return -EINVAL;
2656 	}
2657 
2658 	hdd_debug("New pdev has been created with pdev_id = %u",
2659 		  hdd_ctx->pdev->pdev_objmgr.wlan_pdev_id);
2660 
2661 	status = dispatcher_pdev_open(hdd_ctx->pdev);
2662 	if (QDF_IS_STATUS_ERROR(status)) {
2663 		QDF_DEBUG_PANIC("dispatcher pdev open failed; status:%d",
2664 				status);
2665 		ret = qdf_status_to_os_return(status);
2666 		goto exit;
2667 	}
2668 
2669 	status = hdd_component_pdev_open(hdd_ctx->pdev);
2670 	if (QDF_IS_STATUS_ERROR(status)) {
2671 		QDF_DEBUG_PANIC("hdd component pdev open failed; status:%d",
2672 				status);
2673 		ret = qdf_status_to_os_return(status);
2674 		goto dispatcher_close;
2675 	}
2676 	/*
2677 	 * For 6GHz support this api is added to convert mlme cfgs
2678 	 * channel numbers to frequency
2679 	 */
2680 	hdd_component_cfg_chan_to_freq(hdd_ctx->pdev);
2681 
2682 	hdd_objmgr_update_tgt_max_vdev_psoc(hdd_ctx, cfg->max_intf_count);
2683 
2684 	ucfg_ipa_set_dp_handle(hdd_ctx->psoc,
2685 			       cds_get_context(QDF_MODULE_ID_SOC));
2686 	ucfg_ipa_set_pdev_id(hdd_ctx->psoc, OL_TXRX_PDEV_ID);
2687 
2688 	status = ucfg_mlme_get_sub_20_chan_width(hdd_ctx->psoc,
2689 						 &sub_20_chan_width);
2690 	if (QDF_IS_STATUS_ERROR(status)) {
2691 		hdd_err("Failed to get sub_20_chan_width config");
2692 		ret = qdf_status_to_os_return(status);
2693 		goto pdev_close;
2694 	}
2695 
2696 	if (cds_cfg) {
2697 		if (sub_20_chan_width !=
2698 		    WLAN_SUB_20_CH_WIDTH_NONE && !cfg->sub_20_support) {
2699 			hdd_err("User requested sub 20 MHz channel width but unsupported by FW.");
2700 			cds_cfg->sub_20_channel_width =
2701 				WLAN_SUB_20_CH_WIDTH_NONE;
2702 		} else {
2703 			cds_cfg->sub_20_channel_width = sub_20_chan_width;
2704 		}
2705 	}
2706 
2707 	status = ucfg_mlme_get_band_capability(hdd_ctx->psoc, &band_capability);
2708 	if (QDF_IS_STATUS_ERROR(status)) {
2709 		hdd_err("Failed to get MLME band capability");
2710 		ret = qdf_status_to_os_return(status);
2711 		goto pdev_close;
2712 	}
2713 
2714 	band_capability =
2715 		hdd_update_band_cap_from_dot11mode(hdd_ctx, band_capability);
2716 
2717 	/* first store the INI band capability */
2718 	temp_band_cap = band_capability;
2719 
2720 	band_capability = cfg->band_cap;
2721 	hdd_ctx->is_fils_roaming_supported =
2722 			cfg->services.is_fils_roaming_supported;
2723 
2724 	hdd_ctx->config->is_11k_offload_supported =
2725 			cfg->services.is_11k_offload_supported;
2726 
2727 	/*
2728 	 * merge the target band capability with INI setting if the merge has
2729 	 * at least 1 band enabled
2730 	 */
2731 	temp_band_cap &= band_capability;
2732 	if (!temp_band_cap)
2733 		hdd_warn("ini BandCapability not supported by the target");
2734 	else
2735 		band_capability = temp_band_cap;
2736 
2737 	status = ucfg_mlme_set_band_capability(hdd_ctx->psoc, band_capability);
2738 	if (QDF_IS_STATUS_ERROR(status)) {
2739 		hdd_err("Failed to set MLME Band Capability");
2740 		ret = qdf_status_to_os_return(status);
2741 		goto pdev_close;
2742 	}
2743 
2744 	hdd_ctx->curr_band = band_capability;
2745 	hdd_ctx->psoc->soc_nif.user_config.band_capability = hdd_ctx->curr_band;
2746 
2747 	status = wlan_hdd_update_wiphy_supported_band(hdd_ctx);
2748 	if (QDF_IS_STATUS_ERROR(status)) {
2749 		hdd_err("Failed to update wiphy band info");
2750 		goto pdev_close;
2751 	}
2752 
2753 	status = ucfg_reg_set_band(hdd_ctx->pdev, band_capability);
2754 	if (QDF_IS_STATUS_ERROR(status))
2755 		/*
2756 		 * Continue, Do not close the pdev from here as if host fails
2757 		 * to update band information if cc_list event is not received
2758 		 * by this time, then also driver load should happen.
2759 		 */
2760 		hdd_err("Failed to update regulatory band info");
2761 
2762 	if (!cds_is_driver_recovering() || cds_is_driver_in_bad_state()) {
2763 		hdd_ctx->reg.reg_domain = cfg->reg_domain;
2764 		hdd_ctx->reg.eeprom_rd_ext = cfg->eeprom_rd_ext;
2765 	}
2766 
2767 	/* This can be extended to other configurations like ht, vht cap... */
2768 	status = wlan_hdd_validate_mac_address(&cfg->hw_macaddr);
2769 	if (QDF_IS_STATUS_SUCCESS(status))
2770 		qdf_mem_copy(&hdd_ctx->hw_macaddr, &cfg->hw_macaddr,
2771 			     QDF_MAC_ADDR_SIZE);
2772 
2773 	hdd_ctx->target_fw_version = cfg->target_fw_version;
2774 	hdd_ctx->target_fw_vers_ext = cfg->target_fw_vers_ext;
2775 	hdd_extract_fw_version_info(hdd_ctx);
2776 
2777 	hdd_ctx->hw_bd_id = cfg->hw_bd_id;
2778 	qdf_mem_copy(&hdd_ctx->hw_bd_info, &cfg->hw_bd_info,
2779 		     sizeof(cfg->hw_bd_info));
2780 
2781 	if (cfg->max_intf_count > WLAN_MAX_VDEVS) {
2782 		hdd_err("fw max vdevs (%u) > host max vdevs (%u); using %u",
2783 			cfg->max_intf_count, WLAN_MAX_VDEVS, WLAN_MAX_VDEVS);
2784 		hdd_ctx->max_intf_count = WLAN_MAX_VDEVS;
2785 	} else {
2786 		hdd_ctx->max_intf_count = cfg->max_intf_count;
2787 	}
2788 
2789 	hdd_sar_target_config(hdd_ctx, cfg);
2790 	hdd_lpass_target_config(hdd_ctx, cfg);
2791 
2792 	hdd_ctx->ap_arpns_support = cfg->ap_arpns_support;
2793 
2794 	hdd_update_tgt_services(hdd_ctx, &cfg->services);
2795 
2796 	hdd_update_tgt_ht_cap(hdd_ctx, &cfg->ht_cap);
2797 
2798 	sme_update_bfer_caps_as_per_nss_chains(hdd_ctx->mac_handle, cfg);
2799 
2800 	hdd_update_tgt_vht_cap(hdd_ctx, &cfg->vht_cap);
2801 	if (cfg->services.en_11ax  &&
2802 	    (hdd_ctx->config->dot11Mode == eHDD_DOT11_MODE_AUTO ||
2803 	     hdd_ctx->config->dot11Mode == eHDD_DOT11_MODE_11ax ||
2804 	     hdd_ctx->config->dot11Mode == eHDD_DOT11_MODE_11ax_ONLY)) {
2805 		hdd_debug("11AX: 11ax is enabled - update HDD config");
2806 		hdd_update_tgt_he_cap(hdd_ctx, cfg);
2807 		hdd_update_wiphy_he_cap(hdd_ctx);
2808 	}
2809 	hdd_update_tgt_twt_cap(hdd_ctx, cfg);
2810 	hdd_update_tgt_eht_cap(hdd_ctx, cfg);
2811 	hdd_update_wiphy_eht_cap(hdd_ctx);
2812 	ucfg_mlme_update_tgt_mlo_cap(hdd_ctx->psoc);
2813 
2814 	for (band = NSS_CHAINS_BAND_2GHZ; band < NSS_CHAINS_BAND_MAX; band++) {
2815 		sme_modify_nss_chains_tgt_cfg(hdd_ctx->mac_handle,
2816 					      QDF_STA_MODE, band);
2817 		sme_modify_nss_chains_tgt_cfg(hdd_ctx->mac_handle,
2818 					      QDF_SAP_MODE, band);
2819 		sme_modify_nss_chains_tgt_cfg(hdd_ctx->mac_handle,
2820 					      QDF_TDLS_MODE, band);
2821 		sme_modify_nss_chains_tgt_cfg(hdd_ctx->mac_handle,
2822 					      QDF_P2P_DEVICE_MODE,
2823 					      band);
2824 		sme_modify_nss_chains_tgt_cfg(hdd_ctx->mac_handle,
2825 					      QDF_OCB_MODE, band);
2826 		sme_modify_nss_chains_tgt_cfg(hdd_ctx->mac_handle,
2827 					      QDF_TDLS_MODE, band);
2828 	}
2829 
2830 	hdd_update_vdev_nss(hdd_ctx);
2831 
2832 	status =
2833 	  ucfg_mlme_get_enable_dynamic_nss_chains_cfg(hdd_ctx->psoc,
2834 						      &enable_dynamic_cfg);
2835 	if (QDF_IS_STATUS_ERROR(status)) {
2836 		hdd_err("unable to get enable dynamic config");
2837 		hdd_ctx->dynamic_nss_chains_support = false;
2838 	} else {
2839 		hdd_ctx->dynamic_nss_chains_support =
2840 					cfg->dynamic_nss_chains_support &
2841 					enable_dynamic_cfg;
2842 		hdd_debug("Dynamic nss chain support FW %d driver %d",
2843 			   cfg->dynamic_nss_chains_support, enable_dynamic_cfg);
2844 	}
2845 
2846 	status = ucfg_mlme_update_dynamic_nss_chains_support
2847 			(hdd_ctx->psoc, hdd_ctx->dynamic_nss_chains_support);
2848 	if (QDF_IS_STATUS_ERROR(status))
2849 		hdd_err("unable to set dynamic_nss_chains_support");
2850 
2851 	ucfg_mlme_get_fine_time_meas_cap(hdd_ctx->psoc, &fine_time_meas_cap);
2852 	fine_time_meas_cap &= cfg->fine_time_measurement_cap;
2853 	status = ucfg_mlme_set_fine_time_meas_cap(hdd_ctx->psoc,
2854 						  fine_time_meas_cap);
2855 	if (QDF_IS_STATUS_ERROR(status)) {
2856 		hdd_err("failed to set fine_time_meas_cap, 0x%x, ox%x",
2857 			fine_time_meas_cap, cfg->fine_time_measurement_cap);
2858 		ucfg_mlme_get_fine_time_meas_cap(hdd_ctx->psoc,
2859 						 &fine_time_meas_cap);
2860 	}
2861 
2862 	hdd_ctx->fine_time_meas_cap_target = cfg->fine_time_measurement_cap;
2863 	hdd_debug("fine_time_meas_cap: 0x%x", fine_time_meas_cap);
2864 
2865 	status = ucfg_mlme_get_vht_enable2x2(hdd_ctx->psoc, &bval);
2866 	if (!QDF_IS_STATUS_SUCCESS(status))
2867 		hdd_err("unable to get vht_enable2x2");
2868 
2869 	antenna_mode = (bval == 0x01) ?
2870 			HDD_ANTENNA_MODE_2X2 : HDD_ANTENNA_MODE_1X1;
2871 	hdd_update_smps_antenna_mode(hdd_ctx, antenna_mode);
2872 	hdd_debug("Init current antenna mode: %d",
2873 		  hdd_ctx->current_antenna_mode);
2874 
2875 	hdd_ctx->rcpi_enabled = cfg->rcpi_enabled;
2876 
2877 	status = ucfg_mlme_cfg_get_vht_tx_bfee_ant_supp(hdd_ctx->psoc,
2878 							&value);
2879 	if (QDF_IS_STATUS_ERROR(status)) {
2880 		status = false;
2881 		hdd_err("set tx_bfee_ant_supp failed");
2882 	}
2883 
2884 	status = ucfg_mlme_set_restricted_80p80_bw_supp(hdd_ctx->psoc,
2885 							cfg->restricted_80p80_bw_supp);
2886 	if (QDF_IS_STATUS_ERROR(status))
2887 		hdd_err("Failed to set MLME restircted 80p80 BW support");
2888 
2889 	if ((value > MLME_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED_FW_DEF) &&
2890 	    !cfg->tx_bfee_8ss_enabled) {
2891 		status = ucfg_mlme_cfg_set_vht_tx_bfee_ant_supp(hdd_ctx->psoc,
2892 				MLME_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED_FW_DEF);
2893 		if (QDF_IS_STATUS_ERROR(status)) {
2894 			status = false;
2895 			hdd_err("set tx_bfee_ant_supp failed");
2896 		}
2897 	}
2898 
2899 	mac_handle = hdd_ctx->mac_handle;
2900 
2901 	hdd_debug("txBFCsnValue %d", value);
2902 
2903 	/*
2904 	 * Update txBFCsnValue and NumSoundingDim values to vhtcap in wiphy
2905 	 */
2906 	hdd_update_wiphy_vhtcap(hdd_ctx);
2907 
2908 	hdd_update_vhtcap_2g(hdd_ctx);
2909 
2910 	hdd_ctx->wmi_max_len = cfg->wmi_max_len;
2911 
2912 	wlan_config_sched_scan_plans_to_wiphy(hdd_ctx->wiphy, hdd_ctx->psoc);
2913 	/*
2914 	 * This needs to be done after HDD pdev is created and stored since
2915 	 * it will access the HDD pdev object lock.
2916 	 */
2917 	hdd_runtime_suspend_context_init(hdd_ctx);
2918 
2919 	/* Configure NAN datapath features */
2920 	hdd_nan_datapath_target_config(hdd_ctx, cfg);
2921 	ucfg_nan_set_tgt_caps(hdd_ctx->psoc, &cfg->nan_caps);
2922 	hdd_ctx->dfs_cac_offload = cfg->dfs_cac_offload;
2923 	hdd_ctx->lte_coex_ant_share = cfg->services.lte_coex_ant_share;
2924 	hdd_ctx->obss_scan_offload = cfg->services.obss_scan_offload;
2925 	ucfg_scan_set_obss_scan_offload(hdd_ctx->psoc,
2926 					hdd_ctx->obss_scan_offload);
2927 	status = ucfg_mlme_set_obss_detection_offload_enabled(
2928 			hdd_ctx->psoc, cfg->obss_detection_offloaded);
2929 	if (QDF_IS_STATUS_ERROR(status))
2930 		hdd_err("Couldn't pass WNI_CFG_OBSS_DETECTION_OFFLOAD to CFG");
2931 
2932 	status = ucfg_mlme_set_obss_color_collision_offload_enabled(
2933 			hdd_ctx->psoc, cfg->obss_color_collision_offloaded);
2934 	if (QDF_IS_STATUS_ERROR(status))
2935 		hdd_err("Failed to set WNI_CFG_OBSS_COLOR_COLLISION_OFFLOAD");
2936 
2937 	ucfg_mlme_set_bss_color_collision_det_support(
2938 					hdd_ctx->psoc,
2939 					cfg->obss_color_collision_offloaded);
2940 	if (!cfg->obss_color_collision_offloaded) {
2941 		status = ucfg_mlme_set_bss_color_collision_det_sta(
2942 				hdd_ctx->psoc,
2943 				cfg->obss_color_collision_offloaded);
2944 		if (QDF_IS_STATUS_ERROR(status))
2945 			hdd_err("Failed to set CFG_BSS_CLR_COLLISION_DET_STA");
2946 	}
2947 
2948 	hdd_update_score_config(hdd_ctx);
2949 	hdd_update_multi_client_thermal_support(hdd_ctx);
2950 
2951 	ucfg_psoc_mlme_set_11be_capab(hdd_ctx->psoc, cfg->services.en_11be);
2952 	return 0;
2953 
2954 dispatcher_close:
2955 	dispatcher_pdev_close(hdd_ctx->pdev);
2956 pdev_close:
2957 	hdd_component_pdev_close(hdd_ctx->pdev);
2958 exit:
2959 	hdd_objmgr_release_and_destroy_pdev(hdd_ctx);
2960 
2961 	return ret;
2962 }
2963 
2964 bool hdd_dfs_indicate_radar(struct hdd_context *hdd_ctx)
2965 {
2966 	struct hdd_adapter *adapter, *next_adapter = NULL;
2967 	struct hdd_ap_ctx *ap_ctx;
2968 	uint32_t ap_chan;
2969 	bool dfs_disable_channel_switch = false;
2970 	struct wlan_hdd_link_info *link_info;
2971 
2972 	if (!hdd_ctx) {
2973 		hdd_info("Couldn't get hdd_ctx");
2974 		return true;
2975 	}
2976 
2977 	ucfg_mlme_get_dfs_disable_channel_switch(hdd_ctx->psoc,
2978 						 &dfs_disable_channel_switch);
2979 	if (dfs_disable_channel_switch) {
2980 		hdd_info("skip tx block hdd_ctx=%pK, disableDFSChSwitch=%d",
2981 			 hdd_ctx, dfs_disable_channel_switch);
2982 		return true;
2983 	}
2984 
2985 	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
2986 					   NET_DEV_HOLD_DFS_INDICATE_RADAR) {
2987 
2988 		if (adapter->device_mode != QDF_SAP_MODE &&
2989 		    adapter->device_mode != QDF_P2P_GO_MODE)
2990 			goto next_adapter;
2991 
2992 		hdd_adapter_for_each_active_link_info(adapter, link_info) {
2993 			ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(link_info);
2994 			ap_chan = ap_ctx->operating_chan_freq;
2995 			if (!wlan_reg_is_passive_or_disable_for_pwrmode(hdd_ctx->pdev,
2996 							ap_chan, REG_CURRENT_PWR_MODE))
2997 				continue;
2998 
2999 			ap_ctx->dfs_cac_block_tx = true;
3000 			hdd_info("tx blocked for vdev: %d", link_info->vdev_id);
3001 			if (link_info->vdev_id != WLAN_UMAC_VDEV_ID_MAX)
3002 				cdp_fc_vdev_flush(
3003 					cds_get_context(QDF_MODULE_ID_SOC),
3004 					link_info->vdev_id);
3005 		}
3006 next_adapter:
3007 		hdd_adapter_dev_put_debug(adapter,
3008 					  NET_DEV_HOLD_DFS_INDICATE_RADAR);
3009 	}
3010 
3011 	return true;
3012 }
3013 
3014 bool hdd_is_valid_mac_address(const uint8_t *mac_addr)
3015 {
3016 	int xdigit = 0;
3017 	int separator = 0;
3018 
3019 	while (*mac_addr) {
3020 		if (isxdigit(*mac_addr)) {
3021 			xdigit++;
3022 		} else if (':' == *mac_addr) {
3023 			if (0 == xdigit || ((xdigit / 2) - 1) != separator)
3024 				break;
3025 
3026 			++separator;
3027 		} else {
3028 			/* Invalid MAC found */
3029 			return false;
3030 		}
3031 		++mac_addr;
3032 	}
3033 	return xdigit == 12 && (separator == 5 || separator == 0);
3034 }
3035 
3036 /**
3037  * hdd_mon_mode_ether_setup() - Update monitor mode struct net_device.
3038  * @dev: Handle to struct net_device to be updated.
3039  *
3040  * Return: None
3041  */
3042 static void hdd_mon_mode_ether_setup(struct net_device *dev)
3043 {
3044 	dev->header_ops         = NULL;
3045 	dev->type               = ARPHRD_IEEE80211_RADIOTAP;
3046 	dev->hard_header_len    = ETH_HLEN;
3047 	dev->mtu                = ETH_DATA_LEN;
3048 	dev->addr_len           = ETH_ALEN;
3049 	dev->tx_queue_len       = 1000; /* Ethernet wants good queues */
3050 	dev->flags              = IFF_BROADCAST|IFF_MULTICAST;
3051 	dev->priv_flags        |= IFF_TX_SKB_SHARING;
3052 
3053 	memset(dev->broadcast, 0xFF, ETH_ALEN);
3054 }
3055 
3056 #ifdef FEATURE_MONITOR_MODE_SUPPORT
3057 /**
3058  * hdd_mon_turn_off_ps_and_wow() - Update monitor mode struct net_device.
3059  * @hdd_ctx: Pointer to HDD context.
3060  *
3061  * Return: None
3062  */
3063 static void hdd_mon_turn_off_ps_and_wow(struct hdd_context *hdd_ctx)
3064 {
3065 	ucfg_pmo_set_power_save_mode(hdd_ctx->psoc,
3066 				     PMO_PS_ADVANCED_POWER_SAVE_DISABLE);
3067 	ucfg_pmo_set_wow_enable(hdd_ctx->psoc, PMO_WOW_DISABLE_BOTH);
3068 }
3069 
3070 /**
3071  * __hdd_mon_open() - HDD Open function
3072  * @dev: Pointer to net_device structure
3073  *
3074  * This is called in response to ifconfig up
3075  *
3076  * Return: 0 for success; non-zero for failure
3077  */
3078 static int __hdd_mon_open(struct net_device *dev)
3079 {
3080 	int ret;
3081 	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
3082 	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
3083 	struct bbm_params param = {0};
3084 
3085 	hdd_enter_dev(dev);
3086 
3087 	if (test_bit(DEVICE_IFACE_OPENED, &adapter->event_flags)) {
3088 		hdd_debug_rl("Monitor interface is already up");
3089 		return 0;
3090 	}
3091 
3092 	ret = wlan_hdd_validate_context(hdd_ctx);
3093 	if (ret)
3094 		return ret;
3095 
3096 	hdd_mon_mode_ether_setup(dev);
3097 
3098 	if (con_mode == QDF_GLOBAL_MONITOR_MODE ||
3099 	    ucfg_mlme_is_sta_mon_conc_supported(hdd_ctx->psoc) ||
3100 	    ucfg_dp_is_local_pkt_capture_enabled(hdd_ctx->psoc)) {
3101 		ret = hdd_trigger_psoc_idle_restart(hdd_ctx);
3102 		if (ret) {
3103 			hdd_err("Failed to start WLAN modules return");
3104 			return ret;
3105 		}
3106 		hdd_err("hdd_wlan_start_modules() successful !");
3107 
3108 		if ((!test_bit(SME_SESSION_OPENED,
3109 			       &adapter->deflink->link_flags)) ||
3110 		    (policy_mgr_is_sta_mon_concurrency(hdd_ctx->psoc))) {
3111 			ret = hdd_start_adapter(adapter, true);
3112 			if (ret) {
3113 				hdd_err("Failed to start adapter :%d",
3114 						adapter->device_mode);
3115 				return ret;
3116 			}
3117 			hdd_err("hdd_start_adapters() successful !");
3118 		}
3119 		hdd_mon_turn_off_ps_and_wow(hdd_ctx);
3120 		set_bit(DEVICE_IFACE_OPENED, &adapter->event_flags);
3121 	}
3122 
3123 	if (con_mode != QDF_GLOBAL_MONITOR_MODE &&
3124 	    (ucfg_mlme_is_sta_mon_conc_supported(hdd_ctx->psoc) ||
3125 	     ucfg_dp_is_local_pkt_capture_enabled(hdd_ctx->psoc))) {
3126 		hdd_info("Acquire wakelock for STA + monitor mode");
3127 
3128 		qdf_wake_lock_acquire(&hdd_ctx->monitor_mode_wakelock,
3129 				      WIFI_POWER_EVENT_WAKELOCK_MONITOR_MODE);
3130 		hdd_lpc_disable_powersave(hdd_ctx);
3131 		qdf_runtime_pm_prevent_suspend(
3132 			&hdd_ctx->runtime_context.monitor_mode);
3133 	}
3134 
3135 	ret = hdd_set_mon_rx_cb(dev);
3136 
3137 	if (!ret)
3138 		ret = hdd_enable_monitor_mode(dev);
3139 
3140 	if (!ret) {
3141 		param.policy = BBM_DRIVER_MODE_POLICY;
3142 		param.policy_info.driver_mode = QDF_GLOBAL_MONITOR_MODE;
3143 		ucfg_dp_bbm_apply_independent_policy(hdd_ctx->psoc, &param);
3144 		ucfg_dp_set_current_throughput_level(hdd_ctx->psoc,
3145 						     PLD_BUS_WIDTH_VERY_HIGH);
3146 	}
3147 
3148 	return ret;
3149 }
3150 
3151 /**
3152  * hdd_mon_open() - Wrapper function for __hdd_mon_open to protect it from SSR
3153  * @net_dev: Pointer to net_device structure
3154  *
3155  * This is called in response to ifconfig up
3156  *
3157  * Return: 0 for success; non-zero for failure
3158  */
3159 static int hdd_mon_open(struct net_device *net_dev)
3160 {
3161 	int errno;
3162 	struct osif_vdev_sync *vdev_sync;
3163 
3164 	errno = osif_vdev_sync_trans_start(net_dev, &vdev_sync);
3165 	if (errno)
3166 		return errno;
3167 
3168 	errno = __hdd_mon_open(net_dev);
3169 
3170 	osif_vdev_sync_trans_stop(vdev_sync);
3171 
3172 	return errno;
3173 }
3174 #endif
3175 
3176 #ifdef WLAN_FEATURE_PKT_CAPTURE
3177 /**
3178  * __hdd_pktcapture_open() - HDD Open function
3179  * @dev: Pointer to net_device structure
3180  *
3181  * This is called in response to ifconfig up
3182  *
3183  * Return: 0 for success; non-zero for failure
3184  */
3185 static int __hdd_pktcapture_open(struct net_device *dev)
3186 {
3187 	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
3188 	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
3189 	struct hdd_adapter *sta_adapter;
3190 	QDF_STATUS status;
3191 	struct wlan_objmgr_vdev *vdev;
3192 	int ret;
3193 
3194 	hdd_enter_dev(dev);
3195 
3196 	ret = wlan_hdd_validate_context(hdd_ctx);
3197 	if (ret)
3198 		return ret;
3199 
3200 	sta_adapter = hdd_get_adapter(hdd_ctx, QDF_STA_MODE);
3201 	if (!sta_adapter) {
3202 		hdd_err("No station interface found");
3203 		return -EINVAL;
3204 	}
3205 
3206 	vdev = hdd_objmgr_get_vdev_by_user(sta_adapter->deflink, WLAN_OSIF_ID);
3207 	if (!vdev)
3208 		return -EINVAL;
3209 
3210 	hdd_mon_mode_ether_setup(dev);
3211 
3212 	status = ucfg_dp_register_pkt_capture_callbacks(vdev);
3213 	ret = qdf_status_to_os_return(status);
3214 	if (ret) {
3215 		hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_ID);
3216 		return ret;
3217 	}
3218 
3219 	adapter->deflink->vdev = vdev;
3220 	set_bit(DEVICE_IFACE_OPENED, &adapter->event_flags);
3221 	sta_adapter->mon_adapter = adapter;
3222 
3223 	return ret;
3224 }
3225 
3226 /**
3227  * hdd_pktcapture_open() - Wrapper function for hdd_pktcapture_open to
3228  * protect it from SSR
3229  * @net_dev: Pointer to net_device structure
3230  *
3231  * This is called in response to ifconfig up
3232  *
3233  * Return: 0 for success; non-zero for failure
3234  */
3235 static int hdd_pktcapture_open(struct net_device *net_dev)
3236 {
3237 	int errno;
3238 	struct osif_vdev_sync *vdev_sync;
3239 
3240 	errno = osif_vdev_sync_trans_start(net_dev, &vdev_sync);
3241 	if (errno)
3242 		return errno;
3243 
3244 	errno = __hdd_pktcapture_open(net_dev);
3245 
3246 	osif_vdev_sync_trans_stop(vdev_sync);
3247 
3248 	return errno;
3249 }
3250 
3251 /**
3252  * hdd_unmap_monitor_interface_vdev() - unmap monitor interface vdev and
3253  * deregister packet capture callbacks
3254  * @sta_adapter: station adapter
3255  *
3256  * Return: void
3257  */
3258 static void
3259 hdd_unmap_monitor_interface_vdev(struct hdd_adapter *sta_adapter)
3260 {
3261 	struct hdd_adapter *mon_adapter = sta_adapter->mon_adapter;
3262 
3263 	if (mon_adapter && hdd_is_interface_up(mon_adapter)) {
3264 		ucfg_pkt_capture_deregister_callbacks(
3265 						mon_adapter->deflink->vdev);
3266 		hdd_objmgr_put_vdev_by_user(mon_adapter->deflink->vdev,
3267 					    WLAN_OSIF_ID);
3268 		mon_adapter->deflink->vdev = NULL;
3269 		hdd_reset_monitor_interface(sta_adapter);
3270 	}
3271 }
3272 
3273 /**
3274  * hdd_map_monitor_interface_vdev() - Map monitor interface vdev and
3275  * register packet capture callbacks
3276  * @sta_adapter: Station adapter
3277  *
3278  * Return: None
3279  */
3280 static void hdd_map_monitor_interface_vdev(struct hdd_adapter *sta_adapter)
3281 {
3282 	struct hdd_adapter *mon_adapter;
3283 	QDF_STATUS status;
3284 	struct wlan_objmgr_vdev *vdev;
3285 	int ret;
3286 
3287 	mon_adapter = hdd_get_adapter(sta_adapter->hdd_ctx, QDF_MONITOR_MODE);
3288 	if (!mon_adapter) {
3289 		hdd_debug("No monitor interface found");
3290 		return;
3291 	}
3292 
3293 	if (!mon_adapter || !hdd_is_interface_up(mon_adapter)) {
3294 		hdd_debug("Monitor interface is not up\n");
3295 		return;
3296 	}
3297 
3298 	if (!wlan_hdd_is_session_type_monitor(mon_adapter->device_mode))
3299 		return;
3300 
3301 	vdev = hdd_objmgr_get_vdev_by_user(sta_adapter->deflink, WLAN_OSIF_ID);
3302 	if (!vdev)
3303 		return;
3304 
3305 	status = ucfg_dp_register_pkt_capture_callbacks(vdev);
3306 	ret = qdf_status_to_os_return(status);
3307 	if (ret) {
3308 		hdd_err("Failed registering packet capture callbacks");
3309 		hdd_objmgr_put_vdev_by_user(vdev,
3310 					    WLAN_OSIF_ID);
3311 		return;
3312 	}
3313 
3314 	mon_adapter->deflink->vdev = vdev;
3315 	sta_adapter->mon_adapter = mon_adapter;
3316 }
3317 
3318 void hdd_reset_monitor_interface(struct hdd_adapter *sta_adapter)
3319 {
3320 	sta_adapter->mon_adapter = NULL;
3321 }
3322 
3323 struct hdd_adapter *
3324 hdd_is_pkt_capture_mon_enable(struct hdd_adapter *sta_adapter)
3325 {
3326 	return sta_adapter->mon_adapter;
3327 }
3328 #else
3329 static inline void
3330 hdd_unmap_monitor_interface_vdev(struct hdd_adapter *sta_adapter)
3331 {
3332 }
3333 
3334 static inline void
3335 hdd_map_monitor_interface_vdev(struct hdd_adapter *sta_adapter)
3336 {
3337 }
3338 #endif
3339 
3340 static QDF_STATUS
3341 wlan_hdd_update_dbs_scan_and_fw_mode_config(void)
3342 {
3343 	struct policy_mgr_dual_mac_config cfg = {0};
3344 	QDF_STATUS status;
3345 	uint32_t chnl_sel_logic_conc = 0;
3346 	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
3347 	uint8_t dual_mac_feature = DISABLE_DBS_CXN_AND_SCAN;
3348 
3349 	if (!hdd_ctx)
3350 		return QDF_STATUS_E_FAILURE;
3351 
3352 	/*
3353 	 * ROME platform doesn't support any DBS related commands in FW,
3354 	 * so if driver sends wmi command with dual_mac_config with all set to
3355 	 * 0 then FW wouldn't respond back and driver would timeout on waiting
3356 	 * for response. Check if FW supports DBS to eliminate ROME vs
3357 	 * NON-ROME platform.
3358 	 */
3359 	if (!policy_mgr_find_if_fw_supports_dbs(hdd_ctx->psoc))
3360 		return QDF_STATUS_SUCCESS;
3361 
3362 	if (hdd_ctx->is_dual_mac_cfg_updated) {
3363 		hdd_debug("dual mac config has already been updated, skip");
3364 		return QDF_STATUS_SUCCESS;
3365 	}
3366 
3367 	cfg.scan_config = 0;
3368 	cfg.fw_mode_config = 0;
3369 	cfg.set_dual_mac_cb = policy_mgr_soc_set_dual_mac_cfg_cb;
3370 	if (policy_mgr_is_hw_dbs_capable(hdd_ctx->psoc)) {
3371 		status =
3372 		ucfg_policy_mgr_get_chnl_select_plcy(hdd_ctx->psoc,
3373 						     &chnl_sel_logic_conc);
3374 		if (status != QDF_STATUS_SUCCESS) {
3375 			hdd_err("can't get chnl sel policy, use def");
3376 			return status;
3377 		}
3378 	}
3379 	status =
3380 	ucfg_policy_mgr_get_dual_mac_feature(hdd_ctx->psoc,
3381 					     &dual_mac_feature);
3382 	if (status != QDF_STATUS_SUCCESS) {
3383 		hdd_err("ucfg_policy_mgr_get_dual_mac_feature failed, use def");
3384 		return status;
3385 	}
3386 
3387 	if (dual_mac_feature != DISABLE_DBS_CXN_AND_SCAN) {
3388 		status = policy_mgr_get_updated_scan_and_fw_mode_config(
3389 				hdd_ctx->psoc, &cfg.scan_config,
3390 				&cfg.fw_mode_config,
3391 				dual_mac_feature,
3392 				chnl_sel_logic_conc);
3393 
3394 		if (status != QDF_STATUS_SUCCESS) {
3395 			hdd_err("wma_get_updated_scan_and_fw_mode_config failed %d",
3396 				status);
3397 			return status;
3398 		}
3399 	}
3400 
3401 	hdd_debug("send scan_cfg: 0x%x fw_mode_cfg: 0x%x to fw",
3402 		cfg.scan_config, cfg.fw_mode_config);
3403 
3404 	status = sme_soc_set_dual_mac_config(cfg);
3405 	if (QDF_IS_STATUS_ERROR(status)) {
3406 		hdd_err("sme_soc_set_dual_mac_config failed %d", status);
3407 		return status;
3408 	}
3409 	hdd_ctx->is_dual_mac_cfg_updated = true;
3410 
3411 	return QDF_STATUS_SUCCESS;
3412 }
3413 
3414 /**
3415  * hdd_max_sta_interface_up_count_reached() - check sta/p2p_cli vdev count
3416  * @adapter: HDD adapter
3417  *
3418  * Return: true if vdev limit reached
3419  */
3420 static bool hdd_max_sta_interface_up_count_reached(struct hdd_adapter *adapter)
3421 {
3422 	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
3423 	struct hdd_adapter *temp_adapter = NULL, *next_adapter = NULL;
3424 	uint8_t intf_count = 0;
3425 	wlan_net_dev_ref_dbgid dbgid =
3426 				NET_DEV_HOLD_MAX_STA_INTERFACE_UP_COUNT_REACHED;
3427 
3428 	if (0 == CFG_TGT_DEFAULT_MAX_STA_VDEVS)
3429 		return false;
3430 
3431 	/*
3432 	 * Check for max no of supported STA/P2PCLI VDEVs before
3433 	 * creating another one.
3434 	 */
3435 	hdd_for_each_adapter_dev_held_safe(hdd_ctx, temp_adapter,
3436 					   next_adapter, dbgid) {
3437 		if ((temp_adapter != adapter) &&
3438 		    (temp_adapter->dev->flags & IFF_UP) &&
3439 		    ((temp_adapter->device_mode == QDF_STA_MODE) ||
3440 		     (temp_adapter->device_mode == QDF_P2P_CLIENT_MODE)))
3441 			intf_count++;
3442 
3443 		hdd_adapter_dev_put_debug(temp_adapter, dbgid);
3444 	}
3445 
3446 	if (intf_count >= CFG_TGT_DEFAULT_MAX_STA_VDEVS) {
3447 		hdd_err("Max limit reached sta vdev-current %d max %d",
3448 			intf_count, CFG_TGT_DEFAULT_MAX_STA_VDEVS);
3449 		return true;
3450 	}
3451 	return false;
3452 }
3453 
3454 #if (defined(WLAN_FEATURE_11BE_MLO) && defined(CFG80211_11BE_BASIC)) && \
3455 (defined(CFG80211_IFTYPE_MLO_LINK_SUPPORT) || \
3456 defined(CFG80211_SINGLE_NETDEV_MULTI_LINK_SUPPORT)) && \
3457 !defined(WLAN_HDD_MULTI_VDEV_SINGLE_NDEV)
3458 static int hdd_start_link_adapter(struct hdd_adapter *sta_adapter)
3459 {
3460 	int i, ret = 0;
3461 	struct hdd_mlo_adapter_info *mlo_adapter_info;
3462 	struct hdd_adapter *link_adapter;
3463 
3464 	hdd_enter_dev(sta_adapter->dev);
3465 	mlo_adapter_info = &sta_adapter->mlo_adapter_info;
3466 
3467 	for (i = 0; i < WLAN_MAX_MLD; i++) {
3468 		link_adapter = mlo_adapter_info->link_adapter[i];
3469 		if (!link_adapter)
3470 			continue;
3471 		if (link_adapter->mlo_adapter_info.associate_with_ml_adapter) {
3472 			/* TODO have proper references here */
3473 			qdf_spin_lock_bh(&link_adapter->deflink->vdev_lock);
3474 			link_adapter->deflink->vdev =
3475 						sta_adapter->deflink->vdev;
3476 			link_adapter->deflink->vdev_id =
3477 						sta_adapter->deflink->vdev_id;
3478 			qdf_spin_unlock_bh(&link_adapter->deflink->vdev_lock);
3479 
3480 			sta_adapter->link_info[i].vdev_id =
3481 						sta_adapter->deflink->vdev_id;
3482 			continue;
3483 		}
3484 		ret = hdd_start_station_adapter(link_adapter);
3485 		if (!ret) {
3486 			sta_adapter->link_info[i].vdev_id =
3487 						link_adapter->deflink->vdev_id;
3488 		}
3489 	}
3490 
3491 	hdd_adapter_update_mlo_mgr_mac_addr(sta_adapter);
3492 
3493 	hdd_exit();
3494 	return ret;
3495 }
3496 
3497 static int hdd_stop_link_adapter(struct hdd_context *hdd_ctx,
3498 				 struct hdd_adapter *sta_adapter)
3499 {
3500 	int i, ret = 0;
3501 	struct hdd_mlo_adapter_info *mlo_adapter_info;
3502 	struct hdd_adapter *link_adapter;
3503 
3504 	hdd_enter_dev(sta_adapter->dev);
3505 	hdd_debug("Stop adapter for link mode : %s(%d)",
3506 		  qdf_opmode_str(sta_adapter->device_mode),
3507 		  sta_adapter->deflink->vdev_id);
3508 
3509 	mlo_adapter_info = &sta_adapter->mlo_adapter_info;
3510 	for (i = 0; i < WLAN_MAX_MLD; i++) {
3511 		link_adapter = mlo_adapter_info->link_adapter[i];
3512 		if (!link_adapter)
3513 			continue;
3514 
3515 		if (link_adapter->mlo_adapter_info.associate_with_ml_adapter) {
3516 			/* TODO have proper references here */
3517 			qdf_spin_lock_bh(&link_adapter->deflink->vdev_lock);
3518 			link_adapter->deflink->vdev = NULL;
3519 			link_adapter->deflink->vdev_id = 0xff;
3520 			qdf_spin_unlock_bh(&link_adapter->deflink->vdev_lock);
3521 			continue;
3522 		}
3523 		ret = hdd_stop_adapter_ext(hdd_ctx, link_adapter);
3524 	}
3525 
3526 	hdd_exit();
3527 	return ret;
3528 }
3529 #else
3530 static int hdd_start_link_adapter(struct hdd_adapter *link_adapter)
3531 {
3532 	return 0;
3533 }
3534 
3535 static int hdd_stop_link_adapter(struct hdd_context *hdd_ctx,
3536 				 struct hdd_adapter *link_adapter)
3537 {
3538 	return 0;
3539 }
3540 #endif
3541 
3542 /**
3543  * hdd_start_adapter() - Wrapper function for device specific adapter
3544  * @adapter: pointer to HDD adapter
3545  * @rtnl_held: true if rtnl lock is taken, otherwise false
3546  *
3547  * This function is called to start the device specific adapter for
3548  * the mode passed in the adapter's device_mode.
3549  *
3550  * Return: 0 for success; non-zero for failure
3551  */
3552 int hdd_start_adapter(struct hdd_adapter *adapter, bool rtnl_held)
3553 {
3554 
3555 	int ret;
3556 	enum QDF_OPMODE device_mode = adapter->device_mode;
3557 
3558 	hdd_enter_dev(adapter->dev);
3559 
3560 	switch (device_mode) {
3561 	case QDF_STA_MODE:
3562 	case QDF_P2P_CLIENT_MODE:
3563 		if (hdd_max_sta_interface_up_count_reached(adapter))
3564 			goto err_start_adapter;
3565 
3566 		fallthrough;
3567 	case QDF_P2P_DEVICE_MODE:
3568 	case QDF_OCB_MODE:
3569 	case QDF_MONITOR_MODE:
3570 	case QDF_NAN_DISC_MODE:
3571 		ret = hdd_start_station_adapter(adapter);
3572 		if (ret)
3573 			goto err_start_adapter;
3574 
3575 		if (device_mode == QDF_STA_MODE) {
3576 			ret = hdd_start_link_adapter(adapter);
3577 			if (ret)
3578 				hdd_err("Failed to start link adapter:%d", ret);
3579 		}
3580 		break;
3581 	case QDF_P2P_GO_MODE:
3582 	case QDF_SAP_MODE:
3583 		ret = hdd_start_ap_adapter(adapter, rtnl_held);
3584 		if (ret)
3585 			goto err_start_adapter;
3586 		break;
3587 	case QDF_FTM_MODE:
3588 		/* vdevs are dynamically managed by firmware in FTM */
3589 		hdd_register_wext(adapter->dev);
3590 		goto exit_with_success;
3591 	default:
3592 		hdd_err("Invalid session type %d", device_mode);
3593 		QDF_ASSERT(0);
3594 		goto err_start_adapter;
3595 	}
3596 
3597 	if (hdd_set_fw_params(adapter))
3598 		hdd_err("Failed to set the FW params for the adapter!");
3599 
3600 	if (adapter->deflink->vdev_id != WLAN_UMAC_VDEV_ID_MAX) {
3601 		ret = wlan_hdd_cfg80211_register_frames(adapter);
3602 		if (ret < 0) {
3603 			hdd_err("Failed to register frames - ret %d", ret);
3604 			goto err_start_adapter;
3605 		}
3606 	}
3607 
3608 	wlan_hdd_update_dbs_scan_and_fw_mode_config();
3609 
3610 exit_with_success:
3611 	hdd_create_adapter_sysfs_files(adapter);
3612 
3613 	hdd_exit();
3614 
3615 	return 0;
3616 
3617 err_start_adapter:
3618 	return -EINVAL;
3619 }
3620 
3621 void hdd_update_hw_sw_info(struct hdd_context *hdd_ctx)
3622 {
3623 	void *hif_sc;
3624 	size_t target_hw_name_len;
3625 	const char *target_hw_name;
3626 	uint8_t *buf;
3627 	uint32_t buf_len;
3628 
3629 	hif_sc = cds_get_context(QDF_MODULE_ID_HIF);
3630 	if (!hif_sc)
3631 		return;
3632 
3633 	hif_get_hw_info(hif_sc, &hdd_ctx->target_hw_version,
3634 			&hdd_ctx->target_hw_revision,
3635 			&target_hw_name);
3636 
3637 	qdf_mem_zero(hdd_ctx->target_hw_name, MAX_TGT_HW_NAME_LEN);
3638 
3639 	target_hw_name_len = strlen(target_hw_name) + 1;
3640 
3641 	if (target_hw_name_len <= MAX_TGT_HW_NAME_LEN) {
3642 		qdf_mem_copy(hdd_ctx->target_hw_name, target_hw_name,
3643 			     target_hw_name_len);
3644 	} else {
3645 		hdd_err("target_hw_name_len is greater than MAX_TGT_HW_NAME_LEN");
3646 		return;
3647 	}
3648 
3649 	hdd_debug("target_hw_name = %s", hdd_ctx->target_hw_name);
3650 
3651 	buf = qdf_mem_malloc(WE_MAX_STR_LEN);
3652 	if (buf) {
3653 		buf_len = hdd_wlan_get_version(hdd_ctx, WE_MAX_STR_LEN, buf);
3654 		hdd_nofl_debug("%s", buf);
3655 		qdf_mem_free(buf);
3656 	}
3657 }
3658 
3659 /**
3660  * hdd_update_cds_ac_specs_params() - update cds ac_specs params
3661  * @hdd_ctx: Pointer to hdd context
3662  *
3663  * Return: none
3664  */
3665 static void
3666 hdd_update_cds_ac_specs_params(struct hdd_context *hdd_ctx)
3667 {
3668 	uint8_t tx_sched_wrr_param[TX_SCHED_WRR_PARAMS_NUM] = {0};
3669 	qdf_size_t out_size = 0;
3670 	int i;
3671 	struct cds_context *cds_ctx;
3672 
3673 	if (!hdd_ctx)
3674 		return;
3675 
3676 	if (!hdd_ctx->config) {
3677 		/* Do nothing if hdd_ctx is invalid */
3678 		hdd_err("Warning: hdd_ctx->cfg_ini is NULL");
3679 		return;
3680 	}
3681 
3682 	cds_ctx = cds_get_context(QDF_MODULE_ID_QDF);
3683 	if (!cds_ctx)
3684 		return;
3685 
3686 	for (i = 0; i < QCA_WLAN_AC_ALL; i++) {
3687 		switch (i) {
3688 		case QCA_WLAN_AC_BE:
3689 			qdf_uint8_array_parse(
3690 				cfg_get(hdd_ctx->psoc,
3691 					CFG_DP_ENABLE_TX_SCHED_WRR_BE),
3692 				tx_sched_wrr_param,
3693 				sizeof(tx_sched_wrr_param),
3694 				&out_size);
3695 			break;
3696 		case QCA_WLAN_AC_BK:
3697 			qdf_uint8_array_parse(
3698 				cfg_get(hdd_ctx->psoc,
3699 					CFG_DP_ENABLE_TX_SCHED_WRR_BK),
3700 				tx_sched_wrr_param,
3701 				sizeof(tx_sched_wrr_param),
3702 				&out_size);
3703 			break;
3704 		case QCA_WLAN_AC_VI:
3705 			qdf_uint8_array_parse(
3706 				cfg_get(hdd_ctx->psoc,
3707 					CFG_DP_ENABLE_TX_SCHED_WRR_VI),
3708 				tx_sched_wrr_param,
3709 				sizeof(tx_sched_wrr_param),
3710 				&out_size);
3711 			break;
3712 		case QCA_WLAN_AC_VO:
3713 			qdf_uint8_array_parse(
3714 				cfg_get(hdd_ctx->psoc,
3715 					CFG_DP_ENABLE_TX_SCHED_WRR_VO),
3716 				tx_sched_wrr_param,
3717 				sizeof(tx_sched_wrr_param),
3718 				&out_size);
3719 			break;
3720 		default:
3721 			break;
3722 		}
3723 
3724 		if (out_size == TX_SCHED_WRR_PARAMS_NUM) {
3725 			cds_ctx->ac_specs[i].wrr_skip_weight =
3726 						tx_sched_wrr_param[0];
3727 			cds_ctx->ac_specs[i].credit_threshold =
3728 						tx_sched_wrr_param[1];
3729 			cds_ctx->ac_specs[i].send_limit =
3730 						tx_sched_wrr_param[2];
3731 			cds_ctx->ac_specs[i].credit_reserve =
3732 						tx_sched_wrr_param[3];
3733 			cds_ctx->ac_specs[i].discard_weight =
3734 						tx_sched_wrr_param[4];
3735 		}
3736 
3737 		out_size = 0;
3738 	}
3739 }
3740 
3741 uint32_t hdd_wlan_get_version(struct hdd_context *hdd_ctx,
3742 			      const size_t version_len, uint8_t *version)
3743 {
3744 	uint32_t size;
3745 	uint8_t reg_major = 0, reg_minor = 0, bdf_major = 0, bdf_minor = 0;
3746 	struct target_psoc_info *tgt_hdl;
3747 
3748 	if (!hdd_ctx) {
3749 		hdd_err("Invalid context, HDD context is null");
3750 		return 0;
3751 	}
3752 
3753 	if (!version || version_len == 0) {
3754 		hdd_err("Invalid buffer pointr or buffer len\n");
3755 		return 0;
3756 	}
3757 	tgt_hdl = wlan_psoc_get_tgt_if_handle(hdd_ctx->psoc);
3758 	if (tgt_hdl)
3759 		target_psoc_get_version_info(tgt_hdl, &reg_major, &reg_minor,
3760 					     &bdf_major, &bdf_minor);
3761 
3762 	size = scnprintf(version, version_len,
3763 			 "Host SW:%s, FW:%d.%d.%d.%d.%d.%d, HW:%s, Board ver: %x Ref design id: %x, Customer id: %x, Project id: %x, Board Data Rev: %x, REG DB: %u:%u, BDF REG DB: %u:%u",
3764 			 QWLAN_VERSIONSTR,
3765 			 hdd_ctx->fw_version_info.major_spid,
3766 			 hdd_ctx->fw_version_info.minor_spid,
3767 			 hdd_ctx->fw_version_info.siid,
3768 			 hdd_ctx->fw_version_info.rel_id,
3769 			 hdd_ctx->fw_version_info.crmid,
3770 			 hdd_ctx->fw_version_info.sub_id,
3771 			 hdd_ctx->target_hw_name,
3772 			 hdd_ctx->hw_bd_info.bdf_version,
3773 			 hdd_ctx->hw_bd_info.ref_design_id,
3774 			 hdd_ctx->hw_bd_info.customer_id,
3775 			 hdd_ctx->hw_bd_info.project_id,
3776 			 hdd_ctx->hw_bd_info.board_data_rev,
3777 			 reg_major, reg_minor, bdf_major, bdf_minor);
3778 
3779 	return size;
3780 }
3781 
3782 int hdd_set_11ax_rate(struct hdd_adapter *adapter, int set_value,
3783 		      struct sap_config *sap_config)
3784 {
3785 	uint8_t preamble = 0, nss = 0, rix = 0;
3786 	int ret;
3787 	mac_handle_t mac_handle = adapter->hdd_ctx->mac_handle;
3788 
3789 	if (!sap_config) {
3790 		if (!sme_is_feature_supported_by_fw(DOT11AX)) {
3791 			hdd_err("Target does not support 11ax");
3792 			return -EIO;
3793 		}
3794 	} else if (sap_config->SapHw_mode != eCSR_DOT11_MODE_11ax &&
3795 		   sap_config->SapHw_mode != eCSR_DOT11_MODE_11ax_ONLY) {
3796 		hdd_err("Invalid hw mode, SAP hw_mode= 0x%x, ch_freq = %d",
3797 			sap_config->SapHw_mode, sap_config->chan_freq);
3798 		return -EIO;
3799 	}
3800 
3801 	if (set_value != 0xffff) {
3802 		rix = RC_2_RATE_IDX_11AX(set_value);
3803 		preamble = WMI_RATE_PREAMBLE_HE;
3804 		nss = HT_RC_2_STREAMS_11AX(set_value);
3805 
3806 		set_value = hdd_assemble_rate_code(preamble, nss, rix);
3807 	} else {
3808 		ret = sme_set_auto_rate_he_ltf(mac_handle,
3809 					       adapter->deflink->vdev_id,
3810 					       QCA_WLAN_HE_LTF_AUTO);
3811 	}
3812 
3813 	hdd_info("SET_11AX_RATE val %d rix %d preamble %x nss %d",
3814 		 set_value, rix, preamble, nss);
3815 
3816 	ret = wma_cli_set_command(adapter->deflink->vdev_id,
3817 				  wmi_vdev_param_fixed_rate,
3818 				  set_value, VDEV_CMD);
3819 
3820 	return ret;
3821 }
3822 
3823 int hdd_assemble_rate_code(uint8_t preamble, uint8_t nss, uint8_t rate)
3824 {
3825 	int set_value;
3826 
3827 	if (sme_is_feature_supported_by_fw(DOT11AX))
3828 		set_value = WMI_ASSEMBLE_RATECODE_V1(rate, nss, preamble);
3829 	else
3830 		set_value = (preamble << 6) | (nss << 4) | rate;
3831 
3832 	return set_value;
3833 }
3834 
3835 #ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
3836 static enum policy_mgr_con_mode wlan_hdd_get_mode_for_non_connected_vdev(
3837 			struct wlan_objmgr_psoc *psoc, uint8_t vdev_id)
3838 {
3839 	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
3840 	struct hdd_adapter *adapter;
3841 	enum policy_mgr_con_mode mode;
3842 	struct wlan_hdd_link_info *link_info;
3843 
3844 	link_info = hdd_get_link_info_by_vdev(hdd_ctx, vdev_id);
3845 	if (!link_info) {
3846 		hdd_err("Invalid vdev");
3847 		return PM_MAX_NUM_OF_MODE;
3848 	}
3849 
3850 	adapter = link_info->adapter;
3851 	mode = policy_mgr_qdf_opmode_to_pm_con_mode(psoc,
3852 						    adapter->device_mode,
3853 						    vdev_id);
3854 	return mode;
3855 }
3856 
3857 /**
3858  * hdd_is_chan_switch_in_progress() - Check if any adapter has channel switch in
3859  * progress
3860  *
3861  * Return: true, if any adapter has channel switch in
3862  * progress else false
3863  */
3864 static bool hdd_is_chan_switch_in_progress(void)
3865 {
3866 	struct hdd_adapter *adapter = NULL, *next_adapter = NULL;
3867 	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
3868 	wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_IS_CHAN_SWITCH_IN_PROGRESS;
3869 	struct hdd_ap_ctx *ap_ctx;
3870 	struct wlan_hdd_link_info *link_info;
3871 
3872 	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
3873 					   dbgid) {
3874 		if (adapter->device_mode != QDF_SAP_MODE &&
3875 		    adapter->device_mode != QDF_P2P_GO_MODE)
3876 			goto next_adapter;
3877 
3878 		hdd_adapter_for_each_active_link_info(adapter, link_info) {
3879 			ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(link_info);
3880 			if (qdf_atomic_read(&ap_ctx->ch_switch_in_progress)) {
3881 				hdd_debug("channel switch progress for vdev_id %d",
3882 					  link_info->vdev_id);
3883 				hdd_adapter_dev_put_debug(adapter, dbgid);
3884 				if (next_adapter)
3885 					hdd_adapter_dev_put_debug(next_adapter,
3886 								  dbgid);
3887 				return true;
3888 			}
3889 		}
3890 next_adapter:
3891 		hdd_adapter_dev_put_debug(adapter, dbgid);
3892 	}
3893 
3894 	return false;
3895 }
3896 
3897 /**
3898  * hdd_is_cac_in_progress() - Check if any SAP connection is performing
3899  * CAC on DFS channel
3900  *
3901  * Return: true, if any of existing SAP is performing CAC
3902  * or else false
3903  */
3904 static bool hdd_is_cac_in_progress(void)
3905 {
3906 	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
3907 
3908 	if (!hdd_ctx)
3909 		return false;
3910 
3911 	return (hdd_ctx->dev_dfs_cac_status == DFS_CAC_IN_PROGRESS);
3912 }
3913 
3914 static void hdd_register_policy_manager_callback(
3915 			struct wlan_objmgr_psoc *psoc)
3916 {
3917 	struct policy_mgr_hdd_cbacks hdd_cbacks;
3918 
3919 	qdf_mem_zero(&hdd_cbacks, sizeof(hdd_cbacks));
3920 	hdd_cbacks.sap_restart_chan_switch_cb =
3921 		hdd_sap_restart_chan_switch_cb;
3922 	hdd_cbacks.wlan_hdd_get_channel_for_sap_restart =
3923 		wlan_hdd_get_channel_for_sap_restart;
3924 	hdd_cbacks.get_mode_for_non_connected_vdev =
3925 		wlan_hdd_get_mode_for_non_connected_vdev;
3926 	hdd_cbacks.hdd_get_device_mode = hdd_get_device_mode;
3927 	hdd_cbacks.hdd_is_chan_switch_in_progress =
3928 				hdd_is_chan_switch_in_progress;
3929 	hdd_cbacks.hdd_is_cac_in_progress =
3930 				hdd_is_cac_in_progress;
3931 	hdd_cbacks.wlan_hdd_set_sap_csa_reason =
3932 				wlan_hdd_set_sap_csa_reason;
3933 	hdd_cbacks.hdd_get_ap_6ghz_capable = hdd_get_ap_6ghz_capable;
3934 	hdd_cbacks.wlan_hdd_indicate_active_ndp_cnt =
3935 				hdd_indicate_active_ndp_cnt;
3936 	hdd_cbacks.wlan_get_ap_prefer_conc_ch_params =
3937 			wlan_get_ap_prefer_conc_ch_params;
3938 	hdd_cbacks.wlan_get_sap_acs_band =
3939 			wlan_get_sap_acs_band;
3940 	hdd_cbacks.wlan_check_cc_intf_cb = wlan_hdd_check_cc_intf_cb;
3941 
3942 	if (QDF_STATUS_SUCCESS !=
3943 	    policy_mgr_register_hdd_cb(psoc, &hdd_cbacks)) {
3944 		hdd_err("HDD callback registration with policy manager failed");
3945 	}
3946 }
3947 #else
3948 static void hdd_register_policy_manager_callback(
3949 			struct wlan_objmgr_psoc *psoc)
3950 {
3951 }
3952 #endif
3953 
3954 #ifdef WLAN_SUPPORT_GAP_LL_PS_MODE
3955 static void hdd_register_green_ap_callback(struct wlan_objmgr_pdev *pdev)
3956 {
3957 	struct green_ap_hdd_callback hdd_cback;
3958 	qdf_mem_zero(&hdd_cback, sizeof(hdd_cback));
3959 
3960 	hdd_cback.send_event = wlan_hdd_send_green_ap_ll_ps_event;
3961 
3962 	if (QDF_STATUS_SUCCESS !=
3963 			green_ap_register_hdd_callback(pdev, &hdd_cback)) {
3964 		hdd_err("HDD callback registration for Green AP failed");
3965 	}
3966 }
3967 #else
3968 static inline void hdd_register_green_ap_callback(struct wlan_objmgr_pdev *pdev)
3969 {
3970 }
3971 #endif
3972 
3973 #ifdef WLAN_FEATURE_NAN
3974 #ifdef WLAN_FEATURE_SR
3975 static void hdd_register_sr_concurrency_cb(struct nan_callbacks *cb_obj)
3976 {
3977 	cb_obj->nan_sr_concurrency_update = hdd_nan_sr_concurrency_update;
3978 }
3979 #else
3980 static void hdd_register_sr_concurrency_cb(struct nan_callbacks *cb_obj)
3981 {}
3982 #endif
3983 static void hdd_nan_register_callbacks(struct hdd_context *hdd_ctx)
3984 {
3985 	struct nan_callbacks cb_obj = {0};
3986 
3987 	cb_obj.ndi_open = hdd_ndi_open;
3988 	cb_obj.ndi_close = hdd_ndi_close;
3989 	cb_obj.ndi_set_mode = hdd_ndi_set_mode;
3990 	cb_obj.ndi_start = hdd_ndi_start;
3991 	cb_obj.ndi_delete = hdd_ndi_delete;
3992 	cb_obj.drv_ndi_create_rsp_handler = hdd_ndi_drv_ndi_create_rsp_handler;
3993 	cb_obj.drv_ndi_delete_rsp_handler = hdd_ndi_drv_ndi_delete_rsp_handler;
3994 
3995 	cb_obj.new_peer_ind = hdd_ndp_new_peer_handler;
3996 	cb_obj.peer_departed_ind = hdd_ndp_peer_departed_handler;
3997 
3998 	cb_obj.nan_concurrency_update = hdd_nan_concurrency_update;
3999 	cb_obj.set_mc_list = hdd_update_multicast_list;
4000 
4001 	hdd_register_sr_concurrency_cb(&cb_obj);
4002 
4003 	os_if_nan_register_hdd_callbacks(hdd_ctx->psoc, &cb_obj);
4004 }
4005 #else
4006 static inline void hdd_nan_register_callbacks(struct hdd_context *hdd_ctx)
4007 {
4008 }
4009 #endif
4010 
4011 #ifdef CONFIG_LEAK_DETECTION
4012 /**
4013  * hdd_check_for_leaks() - Perform runtime memory leak checks
4014  * @hdd_ctx: the global HDD context
4015  * @is_ssr: true if SSR is in progress
4016  *
4017  * This API triggers runtime memory leak detection. This feature enforces the
4018  * policy that any memory allocated at runtime must also be released at runtime.
4019  *
4020  * Allocating memory at runtime and releasing it at unload is effectively a
4021  * memory leak for configurations which never unload (e.g. LONU, statically
4022  * compiled driver). Such memory leaks are NOT false positives, and must be
4023  * fixed.
4024  *
4025  * Return: None
4026  */
4027 static void hdd_check_for_leaks(struct hdd_context *hdd_ctx, bool is_ssr)
4028 {
4029 	/* DO NOT REMOVE these checks; for false positives, read above first */
4030 
4031 	wlan_objmgr_psoc_check_for_leaks(hdd_ctx->psoc);
4032 
4033 	/* many adapter resources are not freed by design during SSR */
4034 	if (is_ssr)
4035 		return;
4036 
4037 	qdf_wake_lock_check_for_leaks();
4038 	qdf_delayed_work_check_for_leaks();
4039 	qdf_mc_timer_check_for_leaks();
4040 	qdf_nbuf_map_check_for_leaks();
4041 	qdf_periodic_work_check_for_leaks();
4042 	qdf_mem_check_for_leaks();
4043 }
4044 
4045 /**
4046  * hdd_debug_domain_set() - Set qdf debug domain
4047  * @domain: debug domain to be set
4048  *
4049  * In the scenario of system reboot, it may have thread accessing debug domain
4050  * for memory allocation/free, other than the one trying to change it.
4051  * If debug domain is changed after a memory allocation but before the free,
4052  * it will hit debug domain mismatch assertion in memory free.
4053  * To avoid such assertion, skip debug domain transition if system reboot is
4054  * in progress.
4055  *
4056  * Return: 0 if the specified debug domain has been set, -EBUSY otherwise
4057  */
4058 static int hdd_debug_domain_set(enum qdf_debug_domain domain)
4059 {
4060 	int ret = 0;
4061 
4062 	if (cds_sys_reboot_protect()) {
4063 		hdd_info("System is rebooting, skip debug domain transition");
4064 		ret = -EBUSY;
4065 	} else {
4066 		qdf_debug_domain_set(domain);
4067 	}
4068 
4069 	cds_sys_reboot_unprotect();
4070 
4071 	return ret;
4072 }
4073 
4074 #define hdd_debug_domain_get() qdf_debug_domain_get()
4075 #else
4076 static void hdd_check_for_objmgr_peer_leaks(struct wlan_objmgr_psoc *psoc)
4077 {
4078 	uint32_t vdev_id;
4079 	struct wlan_objmgr_vdev *vdev;
4080 	struct wlan_objmgr_peer *peer;
4081 
4082 	/* get module id which cause the leak and release ref */
4083 	wlan_objmgr_for_each_psoc_vdev(psoc, vdev_id, vdev) {
4084 		wlan_vdev_obj_lock(vdev);
4085 		wlan_objmgr_for_each_vdev_peer(vdev, peer) {
4086 			qdf_atomic_t *ref_id_dbg;
4087 			int ref_id;
4088 			int32_t refs;
4089 
4090 			ref_id_dbg = vdev->vdev_objmgr.ref_id_dbg;
4091 			wlan_objmgr_for_each_refs(ref_id_dbg, ref_id, refs)
4092 				wlan_objmgr_peer_release_ref(peer, ref_id);
4093 		}
4094 		wlan_vdev_obj_unlock(vdev);
4095 	}
4096 }
4097 
4098 static void hdd_check_for_objmgr_leaks(struct hdd_context *hdd_ctx)
4099 {
4100 	uint32_t vdev_id, pdev_id;
4101 	struct wlan_objmgr_psoc *psoc;
4102 	struct wlan_objmgr_vdev *vdev;
4103 	struct wlan_objmgr_pdev *pdev;
4104 	/*
4105 	 * leak detection is disabled, force release the references for the wlan
4106 	 * to recover cleanly.
4107 	 */
4108 	psoc = hdd_ctx->psoc;
4109 	if (!psoc)
4110 		return;
4111 
4112 
4113 	hdd_check_for_objmgr_peer_leaks(psoc);
4114 
4115 	wlan_objmgr_for_each_psoc_vdev(psoc, vdev_id, vdev) {
4116 		qdf_atomic_t *ref_id_dbg;
4117 		int ref_id;
4118 		int32_t refs;
4119 
4120 		ref_id_dbg = vdev->vdev_objmgr.ref_id_dbg;
4121 		wlan_objmgr_for_each_refs(ref_id_dbg, ref_id, refs) {
4122 			wlan_objmgr_vdev_release_ref(vdev, ref_id);
4123 		}
4124 	}
4125 
4126 	wlan_objmgr_for_each_psoc_pdev(psoc, pdev_id, pdev) {
4127 		qdf_atomic_t *ref_id_dbg;
4128 		int ref_id;
4129 		int32_t refs;
4130 
4131 		ref_id_dbg = pdev->pdev_objmgr.ref_id_dbg;
4132 		wlan_objmgr_for_each_refs(ref_id_dbg, ref_id, refs)
4133 			wlan_objmgr_pdev_release_ref(pdev, ref_id);
4134 	}
4135 }
4136 
4137 static void hdd_check_for_leaks(struct hdd_context *hdd_ctx, bool is_ssr)
4138 {
4139 	hdd_check_for_objmgr_leaks(hdd_ctx);
4140 }
4141 
4142 #define hdd_debug_domain_set(domain) 0
4143 #define hdd_debug_domain_get() DEFAULT_DEBUG_DOMAIN_INIT
4144 #endif /* CONFIG_LEAK_DETECTION */
4145 
4146 #ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE
4147 /**
4148  * hdd_skip_acs_scan_timer_handler() - skip ACS scan timer timeout handler
4149  * @data: pointer to struct hdd_context
4150  *
4151  * This function will reset acs_scan_status to eSAP_DO_NEW_ACS_SCAN.
4152  * Then new ACS request will do a fresh scan without reusing the cached
4153  * scan information.
4154  *
4155  * Return: void
4156  */
4157 static void hdd_skip_acs_scan_timer_handler(void *data)
4158 {
4159 	struct hdd_context *hdd_ctx = data;
4160 	mac_handle_t mac_handle;
4161 
4162 	hdd_debug("ACS Scan result expired. Reset ACS scan skip");
4163 	hdd_ctx->skip_acs_scan_status = eSAP_DO_NEW_ACS_SCAN;
4164 	qdf_spin_lock(&hdd_ctx->acs_skip_lock);
4165 	qdf_mem_free(hdd_ctx->last_acs_freq_list);
4166 	hdd_ctx->last_acs_freq_list = NULL;
4167 	hdd_ctx->num_of_channels = 0;
4168 	qdf_spin_unlock(&hdd_ctx->acs_skip_lock);
4169 
4170 	mac_handle = hdd_ctx->mac_handle;
4171 	if (!mac_handle)
4172 		return;
4173 }
4174 
4175 static void hdd_skip_acs_scan_timer_init(struct hdd_context *hdd_ctx)
4176 {
4177 	QDF_STATUS status;
4178 
4179 	status = qdf_mc_timer_init(&hdd_ctx->skip_acs_scan_timer,
4180 				   QDF_TIMER_TYPE_SW,
4181 				   hdd_skip_acs_scan_timer_handler,
4182 				   hdd_ctx);
4183 	if (QDF_IS_STATUS_ERROR(status))
4184 		hdd_err("Failed to init ACS Skip timer");
4185 	qdf_spinlock_create(&hdd_ctx->acs_skip_lock);
4186 }
4187 
4188 static void hdd_skip_acs_scan_timer_deinit(struct hdd_context *hdd_ctx)
4189 {
4190 	if (QDF_TIMER_STATE_RUNNING ==
4191 	    qdf_mc_timer_get_current_state(&hdd_ctx->skip_acs_scan_timer)) {
4192 		qdf_mc_timer_stop(&hdd_ctx->skip_acs_scan_timer);
4193 	}
4194 
4195 	if (!QDF_IS_STATUS_SUCCESS
4196 		    (qdf_mc_timer_destroy(&hdd_ctx->skip_acs_scan_timer))) {
4197 		hdd_err("Cannot deallocate ACS Skip timer");
4198 	}
4199 	qdf_spin_lock(&hdd_ctx->acs_skip_lock);
4200 	qdf_mem_free(hdd_ctx->last_acs_freq_list);
4201 	hdd_ctx->last_acs_freq_list = NULL;
4202 	hdd_ctx->num_of_channels = 0;
4203 	qdf_spin_unlock(&hdd_ctx->acs_skip_lock);
4204 }
4205 #else
4206 static void hdd_skip_acs_scan_timer_init(struct hdd_context *hdd_ctx) {}
4207 static void hdd_skip_acs_scan_timer_deinit(struct hdd_context *hdd_ctx) {}
4208 #endif
4209 
4210 /**
4211  * hdd_update_country_code - Update country code
4212  * @hdd_ctx: HDD context
4213  *
4214  * Update country code based on module parameter country_code
4215  *
4216  * Return: 0 on success and errno on failure
4217  */
4218 int hdd_update_country_code(struct hdd_context *hdd_ctx)
4219 {
4220 	if (!country_code ||
4221 	    !ucfg_reg_is_user_country_set_allowed(hdd_ctx->psoc))
4222 		return 0;
4223 
4224 	return hdd_reg_set_country(hdd_ctx, country_code);
4225 }
4226 
4227 #ifdef WLAN_NS_OFFLOAD
4228 /**
4229  * hdd_wlan_unregister_ip6_notifier() - unregister IPv6 change notifier
4230  * @hdd_ctx: Pointer to hdd context
4231  *
4232  * Unregister for IPv6 address change notifications.
4233  *
4234  * Return: None
4235  */
4236 static void hdd_wlan_unregister_ip6_notifier(struct hdd_context *hdd_ctx)
4237 {
4238 	unregister_inet6addr_notifier(&hdd_ctx->ipv6_notifier);
4239 }
4240 
4241 /**
4242  * hdd_wlan_register_ip6_notifier() - register IPv6 change notifier
4243  * @hdd_ctx: Pointer to hdd context
4244  *
4245  * Register for IPv6 address change notifications.
4246  *
4247  * Return: 0 on success and errno on failure.
4248  */
4249 static int hdd_wlan_register_ip6_notifier(struct hdd_context *hdd_ctx)
4250 {
4251 	int ret;
4252 
4253 	hdd_ctx->ipv6_notifier.notifier_call = wlan_hdd_ipv6_changed;
4254 	ret = register_inet6addr_notifier(&hdd_ctx->ipv6_notifier);
4255 	if (ret) {
4256 		hdd_err("Failed to register IPv6 notifier: %d", ret);
4257 		goto out;
4258 	}
4259 
4260 	hdd_debug("Registered IPv6 notifier");
4261 out:
4262 	return ret;
4263 }
4264 #else
4265 /**
4266  * hdd_wlan_unregister_ip6_notifier() - unregister IPv6 change notifier
4267  * @hdd_ctx: Pointer to hdd context
4268  *
4269  * Unregister for IPv6 address change notifications.
4270  *
4271  * Return: None
4272  */
4273 static void hdd_wlan_unregister_ip6_notifier(struct hdd_context *hdd_ctx)
4274 {
4275 }
4276 
4277 /**
4278  * hdd_wlan_register_ip6_notifier() - register IPv6 change notifier
4279  * @hdd_ctx: Pointer to hdd context
4280  *
4281  * Register for IPv6 address change notifications.
4282  *
4283  * Return: None
4284  */
4285 static int hdd_wlan_register_ip6_notifier(struct hdd_context *hdd_ctx)
4286 {
4287 	return 0;
4288 }
4289 #endif
4290 
4291 #ifdef FEATURE_RUNTIME_PM
4292 #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 7, 0)
4293 static int hdd_pm_qos_add_notifier(struct hdd_context *hdd_ctx)
4294 {
4295 	return dev_pm_qos_add_notifier(hdd_ctx->parent_dev,
4296 				       &hdd_ctx->pm_qos_notifier,
4297 				       DEV_PM_QOS_RESUME_LATENCY);
4298 }
4299 
4300 static int hdd_pm_qos_remove_notifier(struct hdd_context *hdd_ctx)
4301 {
4302 	return dev_pm_qos_remove_notifier(hdd_ctx->parent_dev,
4303 					  &hdd_ctx->pm_qos_notifier,
4304 					  DEV_PM_QOS_RESUME_LATENCY);
4305 }
4306 #else
4307 static int hdd_pm_qos_add_notifier(struct hdd_context *hdd_ctx)
4308 {
4309 	return pm_qos_add_notifier(PM_QOS_CPU_DMA_LATENCY,
4310 				   &hdd_ctx->pm_qos_notifier);
4311 }
4312 
4313 static int hdd_pm_qos_remove_notifier(struct hdd_context *hdd_ctx)
4314 {
4315 	return pm_qos_remove_notifier(PM_QOS_CPU_DMA_LATENCY,
4316 				      &hdd_ctx->pm_qos_notifier);
4317 }
4318 #endif
4319 
4320 /**
4321  * hdd_wlan_register_pm_qos_notifier() - register PM QOS notifier
4322  * @hdd_ctx: Pointer to hdd context
4323  *
4324  * Register for PM QOS change notifications.
4325  *
4326  * Return: None
4327  */
4328 static int hdd_wlan_register_pm_qos_notifier(struct hdd_context *hdd_ctx)
4329 {
4330 	int ret;
4331 
4332 	qdf_spinlock_create(&hdd_ctx->pm_qos_lock);
4333 
4334 	/* if gRuntimePM is 1 then feature is enabled without CXPC */
4335 	if (hdd_ctx->config->runtime_pm != hdd_runtime_pm_dynamic) {
4336 		hdd_debug("Dynamic Runtime PM disabled");
4337 		return 0;
4338 	}
4339 
4340 	hdd_ctx->pm_qos_notifier.notifier_call = wlan_hdd_pm_qos_notify;
4341 	ret = hdd_pm_qos_add_notifier(hdd_ctx);
4342 	if (ret)
4343 		hdd_err("Failed to register PM_QOS notifier: %d", ret);
4344 	else
4345 		hdd_debug("PM QOS Notifier registered");
4346 
4347 	return ret;
4348 }
4349 
4350 /**
4351  * hdd_wlan_unregister_pm_qos_notifier() - unregister PM QOS notifier
4352  * @hdd_ctx: Pointer to hdd context
4353  *
4354  * Unregister for PM QOS change notifications.
4355  *
4356  * Return: None
4357  */
4358 static void hdd_wlan_unregister_pm_qos_notifier(struct hdd_context *hdd_ctx)
4359 {
4360 	int ret;
4361 
4362 	if (hdd_ctx->config->runtime_pm != hdd_runtime_pm_dynamic) {
4363 		hdd_debug("Dynamic Runtime PM disabled");
4364 		qdf_spinlock_destroy(&hdd_ctx->pm_qos_lock);
4365 		return;
4366 	}
4367 
4368 	ret = hdd_pm_qos_remove_notifier(hdd_ctx);
4369 	if (ret)
4370 		hdd_warn("Failed to remove qos notifier, err = %d\n", ret);
4371 
4372 	qdf_spin_lock_irqsave(&hdd_ctx->pm_qos_lock);
4373 
4374 	if (hdd_ctx->runtime_pm_prevented) {
4375 		hif_rtpm_put(HIF_RTPM_PUT_NOIDLE, HIF_RTPM_ID_PM_QOS_NOTIFY);
4376 		hdd_ctx->runtime_pm_prevented = false;
4377 	}
4378 
4379 	qdf_spin_unlock_irqrestore(&hdd_ctx->pm_qos_lock);
4380 
4381 	qdf_spinlock_destroy(&hdd_ctx->pm_qos_lock);
4382 }
4383 #else
4384 static int hdd_wlan_register_pm_qos_notifier(struct hdd_context *hdd_ctx)
4385 {
4386 	return 0;
4387 }
4388 
4389 static void hdd_wlan_unregister_pm_qos_notifier(struct hdd_context *hdd_ctx)
4390 {
4391 }
4392 #endif
4393 
4394 /**
4395  * hdd_enable_power_management() - API to Enable Power Management
4396  * @hdd_ctx: HDD context
4397  *
4398  * API invokes Bus Interface Layer power management functionality
4399  *
4400  * Return: None
4401  */
4402 static void hdd_enable_power_management(struct hdd_context *hdd_ctx)
4403 {
4404 	void *hif_ctx = cds_get_context(QDF_MODULE_ID_HIF);
4405 
4406 	if (!hif_ctx)
4407 		return;
4408 
4409 	hif_enable_power_management(hif_ctx, cds_is_packet_log_enabled());
4410 	hdd_wlan_register_pm_qos_notifier(hdd_ctx);
4411 }
4412 
4413 /**
4414  * hdd_disable_power_management() - API to disable Power Management
4415  * @hdd_ctx: HDD context
4416  *
4417  * API disable Bus Interface Layer Power management functionality
4418  *
4419  * Return: None
4420  */
4421 static void hdd_disable_power_management(struct hdd_context *hdd_ctx)
4422 {
4423 	void *hif_ctx = cds_get_context(QDF_MODULE_ID_HIF);
4424 
4425 	if (!hif_ctx)
4426 		return;
4427 
4428 	hdd_wlan_unregister_pm_qos_notifier(hdd_ctx);
4429 	hif_disable_power_management(hif_ctx);
4430 }
4431 
4432 /**
4433  * hdd_register_notifiers - Register netdev notifiers.
4434  * @hdd_ctx: HDD context
4435  *
4436  * Register netdev notifiers like IPv4 and IPv6.
4437  *
4438  * Return: 0 on success and errno on failure
4439  */
4440 static int hdd_register_notifiers(struct hdd_context *hdd_ctx)
4441 {
4442 	int ret;
4443 
4444 	ret = hdd_wlan_register_ip6_notifier(hdd_ctx);
4445 	if (ret)
4446 		goto out;
4447 
4448 	hdd_ctx->ipv4_notifier.notifier_call = wlan_hdd_ipv4_changed;
4449 	ret = register_inetaddr_notifier(&hdd_ctx->ipv4_notifier);
4450 	if (ret) {
4451 		hdd_err("Failed to register IPv4 notifier: %d", ret);
4452 		goto unregister_ip6_notifier;
4453 	}
4454 
4455 	ret = osif_dp_nud_register_netevent_notifier(hdd_ctx->psoc);
4456 	if (ret) {
4457 		hdd_err("Failed to register netevent notifier: %d",
4458 			ret);
4459 		goto unregister_inetaddr_notifier;
4460 	}
4461 
4462 	return 0;
4463 
4464 unregister_inetaddr_notifier:
4465 	unregister_inetaddr_notifier(&hdd_ctx->ipv4_notifier);
4466 unregister_ip6_notifier:
4467 	hdd_wlan_unregister_ip6_notifier(hdd_ctx);
4468 out:
4469 	return ret;
4470 }
4471 
4472 #ifdef WLAN_FEATURE_WMI_SEND_RECV_QMI
4473 static inline
4474 void hdd_set_qmi_stats_enabled(struct hdd_context *hdd_ctx)
4475 {
4476 	wmi_unified_t wmi_handle = get_wmi_unified_hdl_from_psoc(hdd_ctx->psoc);
4477 
4478 	if (!wmi_handle) {
4479 		hdd_err("could not get wmi handle");
4480 		return;
4481 	}
4482 
4483 	wmi_set_qmi_stats(wmi_handle, hdd_ctx->config->is_qmi_stats_enabled);
4484 }
4485 #else
4486 static inline
4487 void hdd_set_qmi_stats_enabled(struct hdd_context *hdd_ctx)
4488 {
4489 }
4490 #endif
4491 
4492 #ifdef CONFIG_FW_LOGS_BASED_ON_INI
4493 /**
4494  * hdd_set_fw_log_params() - Set log parameters to FW
4495  * @hdd_ctx: HDD Context
4496  * @vdev_id: vdev_id
4497  *
4498  * This function set the FW Debug log level based on the INI.
4499  *
4500  * Return: None
4501  */
4502 static void hdd_set_fw_log_params(struct hdd_context *hdd_ctx,
4503 				  uint8_t vdev_id)
4504 {
4505 	QDF_STATUS status;
4506 	uint16_t enable_fw_log_level, enable_fw_log_type;
4507 	int ret;
4508 
4509 	if (!hdd_ctx->config->enable_fw_log) {
4510 		hdd_debug("enable_fw_log not enabled in INI");
4511 		return;
4512 	}
4513 
4514 	/* Enable FW logs based on INI configuration */
4515 	status = ucfg_fwol_get_enable_fw_log_type(hdd_ctx->psoc,
4516 						  &enable_fw_log_type);
4517 	if (QDF_IS_STATUS_ERROR(status))
4518 		return;
4519 	ret = sme_cli_set_command(vdev_id, WMI_DBGLOG_TYPE,
4520 				  enable_fw_log_type, DBG_CMD);
4521 	if (ret != 0)
4522 		hdd_err("Failed to enable FW log type ret %d", ret);
4523 
4524 	status = ucfg_fwol_get_enable_fw_log_level(hdd_ctx->psoc,
4525 						   &enable_fw_log_level);
4526 	if (QDF_IS_STATUS_ERROR(status))
4527 		return;
4528 	ret = sme_cli_set_command(vdev_id, WMI_DBGLOG_LOG_LEVEL,
4529 				  enable_fw_log_level, DBG_CMD);
4530 	if (ret != 0)
4531 		hdd_err("Failed to enable FW log level ret %d", ret);
4532 
4533 	sme_enable_fw_module_log_level(hdd_ctx->mac_handle, vdev_id);
4534 }
4535 #else
4536 static void hdd_set_fw_log_params(struct hdd_context *hdd_ctx, uint8_t vdev_id)
4537 {
4538 }
4539 
4540 #endif
4541 
4542 /**
4543  * hdd_features_deinit() - Deinit features
4544  * @hdd_ctx:	HDD context
4545  *
4546  * De-Initialize features and their feature context.
4547  *
4548  * Return: none.
4549  */
4550 static void hdd_features_deinit(struct hdd_context *hdd_ctx)
4551 {
4552 	wlan_hdd_gpio_wakeup_deinit(hdd_ctx);
4553 	wlan_hdd_twt_deinit(hdd_ctx);
4554 	wlan_hdd_deinit_chan_info(hdd_ctx);
4555 	wlan_hdd_tsf_deinit(hdd_ctx);
4556 	if (cds_is_packet_log_enabled())
4557 		hdd_pktlog_enable_disable(hdd_ctx, false, 0, 0);
4558 }
4559 
4560 /**
4561  * hdd_deconfigure_cds() -De-Configure cds
4562  * @hdd_ctx:	HDD context
4563  *
4564  * Deconfigure Cds modules before WLAN firmware is down.
4565  *
4566  * Return: 0 on success and errno on failure.
4567  */
4568 static int hdd_deconfigure_cds(struct hdd_context *hdd_ctx)
4569 {
4570 	QDF_STATUS qdf_status;
4571 	int ret = 0;
4572 
4573 	hdd_enter();
4574 
4575 	wlan_hdd_hang_event_notifier_unregister();
4576 	/* De-init features */
4577 	hdd_features_deinit(hdd_ctx);
4578 
4579 	qdf_status = policy_mgr_deregister_mode_change_cb(hdd_ctx->psoc);
4580 	if (!QDF_IS_STATUS_SUCCESS(qdf_status))
4581 		hdd_debug("Failed to deregister mode change cb with Policy Manager");
4582 
4583 	qdf_status = cds_disable(hdd_ctx->psoc);
4584 	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
4585 		hdd_err("Failed to Disable the CDS Modules! :%d",
4586 			qdf_status);
4587 		ret = -EINVAL;
4588 	}
4589 
4590 	if (ucfg_ipa_uc_ol_deinit(hdd_ctx->pdev) != QDF_STATUS_SUCCESS) {
4591 		hdd_err("Failed to disconnect pipes");
4592 		ret = -EINVAL;
4593 	}
4594 
4595 	hdd_exit();
4596 	return ret;
4597 }
4598 
4599 /**
4600  * hdd_qmi_register_callbacks() - Register QMI callbacks
4601  * @hdd_ctx: HDD context
4602  *
4603  * Return: None
4604  */
4605 static inline void hdd_qmi_register_callbacks(struct hdd_context *hdd_ctx)
4606 {
4607 	struct wlan_qmi_psoc_callbacks cb_obj;
4608 
4609 	os_if_qmi_register_callbacks(hdd_ctx->psoc, &cb_obj);
4610 }
4611 
4612 /**
4613  * hdd_set_pcie_params() - Set pcie params
4614  * @hdd_ctx: HDD context
4615  * @index: index value
4616  * @param: pointer to vdev/pdev set param info
4617  *
4618  * Checks for pcie_config value and sets
4619  * corresponding params
4620  *
4621  * Return: 0 on success and errno on failure.
4622  */
4623 static int hdd_set_pcie_params(struct hdd_context *hdd_ctx,
4624 			       uint8_t index, struct dev_set_param *param)
4625 {
4626 	int ret = 0;
4627 	uint8_t check_value = 0;
4628 
4629 	ret = ucfg_fwol_get_pcie_config(hdd_ctx->psoc, &check_value);
4630 	if (QDF_IS_STATUS_SUCCESS(ret)) {
4631 		if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
4632 			ret = mlme_check_index_setparam(param,
4633 					wmi_pdev_param_pcie_config,
4634 					(int)check_value, index++,
4635 					FTM_MAX_PDEV_PARAMS);
4636 		} else {
4637 			ret = mlme_check_index_setparam(param,
4638 					wmi_pdev_param_pcie_config,
4639 					(int)check_value, index++,
4640 					MAX_PDEV_PRE_ENABLE_PARAMS);
4641 		}
4642 		if (QDF_IS_STATUS_ERROR(ret)) {
4643 			hdd_err("failed to set wmi_pdev_param_pcie_config");
4644 			return ret;
4645 		}
4646 	}
4647 	return ret;
4648 }
4649 
4650 #ifdef FEATURE_SET
4651 #ifdef WLAN_FEATURE_11BE
4652 /**
4653  * hdd_is_cfg_dot11_mode_11be() - Check if dot11 mode is 11 be
4654  * @dot11_mode: Input dot11_mode which needs to be checked
4655  *
4656  * Return: True, ifinput dot11_mode is 11be dot11 mode else return false
4657  */
4658 static bool hdd_is_cfg_dot11_mode_11be(enum hdd_dot11_mode dot11_mode)
4659 {
4660 	return (dot11_mode == eHDD_DOT11_MODE_11be ||
4661 		dot11_mode == eHDD_DOT11_MODE_11be_ONLY);
4662 }
4663 
4664 /**
4665  * hdd_is_11be_supported() - Check if 11be is supported or not
4666  * @hdd_ctx: Pointer to hdd context
4667  *
4668  * Return: True, if 11be is supported else return false
4669  */
4670 static bool hdd_is_11be_supported(struct hdd_context *hdd_ctx)
4671 {
4672 	bool mlo_capab;
4673 
4674 	ucfg_psoc_mlme_get_11be_capab(hdd_ctx->psoc, &mlo_capab);
4675 	if (!mlo_capab)
4676 		return false;
4677 
4678 	return true;
4679 }
4680 #else
4681 
4682 static bool hdd_is_cfg_dot11_mode_11be(enum hdd_dot11_mode dot11_mode)
4683 {
4684 	return false;
4685 }
4686 
4687 static bool hdd_is_11be_supported(struct hdd_context *hdd_ctx)
4688 {
4689 	return false;
4690 }
4691 #endif
4692 
4693 WMI_HOST_WIFI_STANDARD
4694 hdd_get_wifi_standard(struct hdd_context *hdd_ctx,
4695 		      enum hdd_dot11_mode dot11_mode, uint32_t band_capability)
4696 {
4697 	WMI_HOST_WIFI_STANDARD wifi_standard = WMI_HOST_WIFI_STANDARD_4;
4698 
4699 	if (dot11_mode == eHDD_DOT11_MODE_AUTO) {
4700 		if (hdd_is_11be_supported(hdd_ctx))
4701 			wifi_standard = WMI_HOST_WIFI_STANDARD_7;
4702 		else if (band_capability & BIT(REG_BAND_6G))
4703 			wifi_standard = WMI_HOST_WIFI_STANDARD_6E;
4704 		else
4705 			wifi_standard = WMI_HOST_WIFI_STANDARD_6;
4706 	} else if (hdd_is_cfg_dot11_mode_11be(dot11_mode)) {
4707 		wifi_standard = WMI_HOST_WIFI_STANDARD_7;
4708 	} else if (dot11_mode == eHDD_DOT11_MODE_11ax ||
4709 		   (dot11_mode == eHDD_DOT11_MODE_11ax_ONLY)) {
4710 		if (band_capability & BIT(REG_BAND_6G))
4711 			wifi_standard = WMI_HOST_WIFI_STANDARD_6E;
4712 		else
4713 			wifi_standard = WMI_HOST_WIFI_STANDARD_6;
4714 	} else if ((dot11_mode == eHDD_DOT11_MODE_11ac) ||
4715 		   (dot11_mode == eHDD_DOT11_MODE_11ac_ONLY)) {
4716 		wifi_standard = WMI_HOST_WIFI_STANDARD_5;
4717 	}
4718 
4719 	return wifi_standard;
4720 }
4721 
4722 /**
4723  * hdd_populate_feature_set_cds_config() - Populate cds feature set config
4724  * @hdd_ctx: hdd context pointer
4725  *
4726  * Return: None
4727  */
4728 static void hdd_populate_feature_set_cds_config(struct hdd_context *hdd_ctx)
4729 {
4730 	struct wlan_objmgr_psoc *psoc;
4731 	uint32_t band_capability;
4732 	QDF_STATUS status;
4733 	struct cds_config_info *cds_cfg;
4734 
4735 	if (!hdd_ctx)
4736 		return;
4737 
4738 	cds_cfg = cds_get_ini_config();
4739 	if (!cds_cfg) {
4740 		hdd_err("CDS config is null.");
4741 		return;
4742 	}
4743 
4744 	psoc = hdd_ctx->psoc;
4745 
4746 	cds_cfg->get_wifi_features = hdd_ctx->config->get_wifi_features;
4747 
4748 	status = ucfg_mlme_get_band_capability(hdd_ctx->psoc, &band_capability);
4749 	if (QDF_IS_STATUS_ERROR(status))
4750 		hdd_err("Failed to get MLME band capability");
4751 
4752 	band_capability =
4753 		hdd_update_band_cap_from_dot11mode(hdd_ctx, band_capability);
4754 
4755 	cds_cfg->cds_feature_set.wifi_standard =
4756 			  hdd_get_wifi_standard(hdd_ctx,
4757 						hdd_ctx->config->dot11Mode,
4758 						band_capability);
4759 
4760 	cds_cfg->cds_feature_set.sap_5g_supported =
4761 					band_capability & BIT(REG_BAND_5G);
4762 
4763 	cds_cfg->cds_feature_set.sap_6g_supported =
4764 					band_capability & BIT(REG_BAND_6G);
4765 	cds_cfg->cds_feature_set.band_capability = band_capability;
4766 }
4767 #else
4768 WMI_HOST_WIFI_STANDARD
4769 hdd_get_wifi_standard(struct hdd_context *hdd_ctx,
4770 		      enum hdd_dot11_mode dot11_mode, uint32_t band_capability)
4771 {
4772 	return WMI_HOST_WIFI_STANDARD_5;
4773 }
4774 
4775 static inline void
4776 hdd_populate_feature_set_cds_config(struct hdd_context *hdd_ctx)
4777 {
4778 }
4779 #endif
4780 
4781 int hdd_wlan_start_modules(struct hdd_context *hdd_ctx, bool reinit)
4782 {
4783 	int ret = 0;
4784 	qdf_device_t qdf_dev;
4785 	QDF_STATUS status;
4786 	bool unint = false;
4787 	void *hif_ctx;
4788 	struct target_psoc_info *tgt_hdl;
4789 	unsigned long thermal_state = 0;
4790 	uint8_t index = 0;
4791 	struct dev_set_param setparam[MAX_PDEV_PRE_ENABLE_PARAMS] = {};
4792 
4793 	hdd_enter();
4794 	qdf_dev = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
4795 	if (!qdf_dev) {
4796 		hdd_exit();
4797 		return -EINVAL;
4798 	}
4799 
4800 	hdd_psoc_idle_timer_stop(hdd_ctx);
4801 
4802 	if (hdd_ctx->driver_status == DRIVER_MODULES_ENABLED) {
4803 		hdd_debug("Driver modules already Enabled");
4804 		hdd_exit();
4805 		return 0;
4806 	}
4807 
4808 	cds_set_driver_state_module_stop(false);
4809 
4810 	switch (hdd_ctx->driver_status) {
4811 	case DRIVER_MODULES_UNINITIALIZED:
4812 		hdd_nofl_debug("Wlan transitioning (UNINITIALIZED -> CLOSED)");
4813 		unint = true;
4814 		fallthrough;
4815 	case DRIVER_MODULES_CLOSED:
4816 		hdd_nofl_debug("Wlan transitioning (CLOSED -> ENABLED)");
4817 		ret = hdd_debug_domain_set(QDF_DEBUG_DOMAIN_ACTIVE);
4818 		if (ret)
4819 			goto abort;
4820 
4821 		if (!reinit && !unint) {
4822 			ret = pld_power_on(qdf_dev->dev);
4823 			if (ret) {
4824 				hdd_err("Failed to power up device; errno:%d",
4825 					ret);
4826 				goto release_lock;
4827 			}
4828 		}
4829 
4830 		hdd_init_adapter_ops_wq(hdd_ctx);
4831 		pld_set_fw_log_mode(hdd_ctx->parent_dev,
4832 				    hdd_ctx->config->enable_fw_log);
4833 		ret = hdd_hif_open(qdf_dev->dev, qdf_dev->drv_hdl, qdf_dev->bid,
4834 				   qdf_dev->bus_type,
4835 				   (reinit == true) ?  HIF_ENABLE_TYPE_REINIT :
4836 				   HIF_ENABLE_TYPE_PROBE);
4837 		if (ret) {
4838 			hdd_err("Failed to open hif; errno: %d", ret);
4839 			goto power_down;
4840 		}
4841 
4842 		hif_ctx = cds_get_context(QDF_MODULE_ID_HIF);
4843 		if (!hif_ctx) {
4844 			ret = -EINVAL;
4845 			goto power_down;
4846 		}
4847 
4848 		status = ol_cds_init(qdf_dev, hif_ctx);
4849 		if (status != QDF_STATUS_SUCCESS) {
4850 			hdd_err("No Memory to Create BMI Context; status: %d",
4851 				status);
4852 			ret = qdf_status_to_os_return(status);
4853 			goto hif_close;
4854 		}
4855 
4856 		if (hdd_get_conparam() == QDF_GLOBAL_EPPING_MODE) {
4857 			status = epping_open();
4858 			if (status) {
4859 				hdd_err("Failed to open in epping mode: %d",
4860 					status);
4861 				ret = -EINVAL;
4862 				goto cds_free;
4863 			}
4864 
4865 			status = epping_enable(qdf_dev->dev, false);
4866 			if (status) {
4867 				hdd_err("Failed to enable in epping mode : %d",
4868 					status);
4869 				epping_close();
4870 				goto cds_free;
4871 			}
4872 
4873 			hdd_info("epping mode enabled");
4874 			break;
4875 		}
4876 
4877 		if (pld_is_ipa_offload_disabled(qdf_dev->dev))
4878 			ucfg_ipa_set_pld_enable(false);
4879 
4880 		ucfg_ipa_component_config_update(hdd_ctx->psoc);
4881 
4882 		hdd_update_cds_ac_specs_params(hdd_ctx);
4883 
4884 		hdd_dp_register_callbacks(hdd_ctx);
4885 
4886 		hdd_qmi_register_callbacks(hdd_ctx);
4887 
4888 		status = hdd_component_psoc_open(hdd_ctx->psoc);
4889 		if (QDF_IS_STATUS_ERROR(status)) {
4890 			hdd_err("Failed to Open legacy components; status: %d",
4891 				status);
4892 			ret = qdf_status_to_os_return(status);
4893 			goto ipa_component_free;
4894 		}
4895 
4896 		ret = hdd_update_config(hdd_ctx);
4897 		if (ret) {
4898 			hdd_err("Failed to update configuration; errno: %d",
4899 				ret);
4900 			goto ipa_component_free;
4901 		}
4902 
4903 		status = wbuff_module_init();
4904 		if (QDF_IS_STATUS_ERROR(status))
4905 			hdd_err("WBUFF init unsuccessful; status: %d", status);
4906 
4907 		status = cds_open(hdd_ctx->psoc);
4908 		if (QDF_IS_STATUS_ERROR(status)) {
4909 			hdd_err("Failed to Open CDS; status: %d", status);
4910 			ret = qdf_status_to_os_return(status);
4911 			goto psoc_close;
4912 		}
4913 
4914 		hdd_populate_feature_set_cds_config(hdd_ctx);
4915 
4916 		hdd_set_qmi_stats_enabled(hdd_ctx);
4917 
4918 		hdd_ctx->mac_handle = cds_get_context(QDF_MODULE_ID_SME);
4919 
4920 		ucfg_dp_set_rx_thread_affinity(hdd_ctx->psoc);
4921 
4922 		/* initialize components configurations after psoc open */
4923 		ret = hdd_update_components_config(hdd_ctx);
4924 		if (ret) {
4925 			hdd_err("Failed to update component configs; errno: %d",
4926 				ret);
4927 			goto close;
4928 		}
4929 
4930 		/* Override PS params for monitor mode */
4931 		if (hdd_get_conparam() == QDF_GLOBAL_MONITOR_MODE)
4932 			hdd_override_all_ps(hdd_ctx);
4933 
4934 		status = cds_dp_open(hdd_ctx->psoc);
4935 		if (!QDF_IS_STATUS_SUCCESS(status)) {
4936 			hdd_err("Failed to Open cds post open; status: %d",
4937 				status);
4938 			ret = qdf_status_to_os_return(status);
4939 			goto close;
4940 		}
4941 		/* Set IRQ affinity for WLAN DP and CE IRQS */
4942 		hif_config_irq_set_perf_affinity_hint(hif_ctx);
4943 
4944 		ret = hdd_register_cb(hdd_ctx);
4945 		if (ret) {
4946 			hdd_err("Failed to register HDD callbacks!");
4947 			goto cds_txrx_free;
4948 		}
4949 
4950 		ret = hdd_register_notifiers(hdd_ctx);
4951 		if (ret)
4952 			goto deregister_cb;
4953 
4954 		/*
4955 		 * NAN component requires certain operations like, open adapter,
4956 		 * close adapter, etc. to be initiated by HDD, for those
4957 		 * register HDD callbacks with UMAC's NAN component.
4958 		 */
4959 		hdd_nan_register_callbacks(hdd_ctx);
4960 
4961 		hdd_son_register_callbacks(hdd_ctx);
4962 
4963 		hdd_sr_register_callbacks(hdd_ctx);
4964 
4965 		wlan_hdd_register_btc_chain_mode_handler(hdd_ctx->psoc);
4966 
4967 		wlan_hdd_register_afc_pld_cb(hdd_ctx->psoc);
4968 
4969 		status = cds_pre_enable();
4970 		if (!QDF_IS_STATUS_SUCCESS(status)) {
4971 			hdd_err("Failed to pre-enable CDS; status: %d", status);
4972 			ret = qdf_status_to_os_return(status);
4973 			goto unregister_notifiers;
4974 		}
4975 
4976 		hdd_register_policy_manager_callback(
4977 			hdd_ctx->psoc);
4978 
4979 		/*
4980 		 * Call this function before hdd_enable_power_management. Since
4981 		 * it is required to trigger WMI_PDEV_DMA_RING_CFG_REQ_CMDID
4982 		 * to FW when power save isn't enable.
4983 		 */
4984 		hdd_spectral_register_to_dbr(hdd_ctx);
4985 
4986 		hdd_create_sysfs_files(hdd_ctx);
4987 		hdd_update_hw_sw_info(hdd_ctx);
4988 
4989 		if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
4990 			hdd_enable_power_management(hdd_ctx);
4991 			hdd_err("in ftm mode, no need to configure cds modules");
4992 			hdd_info("Enable FW log in ftm mode");
4993 			/*
4994 			 * Since vdev is not created for FTM mode,
4995 			 * in FW use vdev_id = 0.
4996 			 */
4997 			hdd_set_fw_log_params(hdd_ctx, 0);
4998 			ret = hdd_set_pcie_params(hdd_ctx, index, setparam);
4999 			if (QDF_IS_STATUS_ERROR(ret))
5000 				break;
5001 			index++;
5002 			ret = sme_send_multi_pdev_vdev_set_params(
5003 					MLME_PDEV_SETPARAM,
5004 					WMI_PDEV_ID_SOC, setparam, index);
5005 			if (QDF_IS_STATUS_ERROR(ret)) {
5006 				hdd_err("failed to send pdev set params");
5007 				return ret;
5008 			}
5009 
5010 			ret = -EINVAL;
5011 			break;
5012 		}
5013 
5014 		ret = hdd_configure_cds(hdd_ctx);
5015 		if (ret) {
5016 			hdd_err("Failed to Enable cds modules; errno: %d", ret);
5017 			goto sched_disable;
5018 		}
5019 
5020 		if (hdd_get_conparam() == QDF_GLOBAL_MISSION_MODE) {
5021 			status = ucfg_dp_direct_link_init(hdd_ctx->psoc);
5022 			if (QDF_IS_STATUS_ERROR(status)) {
5023 				cds_err("Failed to initialize Direct Link datapath");
5024 				ret = -EINVAL;
5025 				goto deconfigure_cds;
5026 			}
5027 		}
5028 
5029 		hdd_enable_power_management(hdd_ctx);
5030 
5031 		hdd_skip_acs_scan_timer_init(hdd_ctx);
5032 
5033 		hdd_set_hif_init_phase(hif_ctx, false);
5034 		hdd_hif_set_enable_detection(hif_ctx, true);
5035 
5036 		wlan_hdd_start_connectivity_logging(hdd_ctx);
5037 
5038 		break;
5039 
5040 	default:
5041 		QDF_DEBUG_PANIC("Unknown driver state:%d",
5042 				hdd_ctx->driver_status);
5043 		ret = -EINVAL;
5044 		goto release_lock;
5045 	}
5046 
5047 	hdd_ctx->driver_status = DRIVER_MODULES_ENABLED;
5048 	hdd_nofl_debug("Wlan transitioned (now ENABLED)");
5049 
5050 	ucfg_ipa_reg_is_driver_unloading_cb(hdd_ctx->pdev,
5051 					    cds_is_driver_unloading);
5052 	ucfg_ipa_reg_sap_xmit_cb(hdd_ctx->pdev,
5053 				 hdd_softap_ipa_start_xmit);
5054 	ucfg_ipa_reg_send_to_nw_cb(hdd_ctx->pdev,
5055 				   hdd_ipa_send_nbuf_to_network);
5056 	ucfg_dp_reg_ipa_rsp_ind(hdd_ctx->pdev);
5057 
5058 	if (!pld_get_thermal_state(hdd_ctx->parent_dev, &thermal_state,
5059 				   THERMAL_MONITOR_APPS)) {
5060 		if (thermal_state > QCA_WLAN_VENDOR_THERMAL_LEVEL_NONE)
5061 			hdd_send_thermal_mitigation_val(hdd_ctx,
5062 							thermal_state,
5063 							THERMAL_MONITOR_APPS);
5064 	}
5065 
5066 	if (!pld_get_thermal_state(hdd_ctx->parent_dev, &thermal_state,
5067 				   THERMAL_MONITOR_WPSS)) {
5068 		if (thermal_state > QCA_WLAN_VENDOR_THERMAL_LEVEL_NONE)
5069 			hdd_send_thermal_mitigation_val(hdd_ctx, thermal_state,
5070 							THERMAL_MONITOR_WPSS);
5071 	}
5072 
5073 	hdd_exit();
5074 
5075 	return 0;
5076 
5077 deconfigure_cds:
5078 	hdd_deconfigure_cds(hdd_ctx);
5079 sched_disable:
5080 	/*
5081 	 * Disable scheduler 1st so that scheduler thread doesn't send messages
5082 	 * to fw in parallel to the cleanup
5083 	 */
5084 	dispatcher_disable();
5085 	hdd_destroy_sysfs_files();
5086 	cds_post_disable();
5087 unregister_notifiers:
5088 	hdd_unregister_notifiers(hdd_ctx);
5089 
5090 deregister_cb:
5091 	hdd_deregister_cb(hdd_ctx);
5092 
5093 cds_txrx_free:
5094 
5095 	tgt_hdl = wlan_psoc_get_tgt_if_handle(hdd_ctx->psoc);
5096 
5097 	if (tgt_hdl && target_psoc_get_wmi_ready(tgt_hdl))
5098 		hdd_runtime_suspend_context_deinit(hdd_ctx);
5099 
5100 	if (hdd_ctx->pdev) {
5101 		dispatcher_pdev_close(hdd_ctx->pdev);
5102 		hdd_objmgr_release_and_destroy_pdev(hdd_ctx);
5103 	}
5104 
5105 	cds_dp_close(hdd_ctx->psoc);
5106 
5107 close:
5108 	dispatcher_disable();
5109 	hdd_ctx->driver_status = DRIVER_MODULES_CLOSED;
5110 	hdd_info("Wlan transition aborted (now CLOSED)");
5111 
5112 	cds_close(hdd_ctx->psoc);
5113 
5114 psoc_close:
5115 	hdd_component_psoc_close(hdd_ctx->psoc);
5116 	wlan_global_lmac_if_close(hdd_ctx->psoc);
5117 	cds_deinit_ini_config();
5118 
5119 ipa_component_free:
5120 	ucfg_ipa_component_config_free();
5121 
5122 cds_free:
5123 	ol_cds_free();
5124 
5125 hif_close:
5126 	hif_ctx = cds_get_context(QDF_MODULE_ID_HIF);
5127 	hdd_hif_close(hdd_ctx, hif_ctx);
5128 power_down:
5129 	hdd_deinit_adapter_ops_wq(hdd_ctx);
5130 	if (!reinit && !unint)
5131 		pld_power_off(qdf_dev->dev);
5132 release_lock:
5133 	cds_shutdown_notifier_purge();
5134 	hdd_check_for_leaks(hdd_ctx, reinit);
5135 	hdd_debug_domain_set(QDF_DEBUG_DOMAIN_INIT);
5136 
5137 abort:
5138 	cds_set_driver_state_module_stop(true);
5139 
5140 	hdd_exit();
5141 
5142 	return ret;
5143 }
5144 
5145 #ifdef WIFI_POS_CONVERGED
5146 static int hdd_activate_wifi_pos(struct hdd_context *hdd_ctx)
5147 {
5148 	int ret = os_if_wifi_pos_register_nl();
5149 
5150 	if (ret)
5151 		hdd_err("os_if_wifi_pos_register_nl failed");
5152 
5153 	return ret;
5154 }
5155 
5156 static int hdd_deactivate_wifi_pos(void)
5157 {
5158 	int ret = os_if_wifi_pos_deregister_nl();
5159 
5160 	if (ret)
5161 		hdd_err("os_if_wifi_pos_deregister_nl failed");
5162 
5163 	return ret;
5164 }
5165 
5166 /**
5167  * hdd_populate_wifi_pos_cfg - populates wifi_pos parameters
5168  * @hdd_ctx: hdd context
5169  *
5170  * Return: status of operation
5171  */
5172 static void hdd_populate_wifi_pos_cfg(struct hdd_context *hdd_ctx)
5173 {
5174 	struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc;
5175 	uint16_t neighbor_scan_max_chan_time;
5176 	uint16_t neighbor_scan_min_chan_time;
5177 
5178 	wifi_pos_set_oem_target_type(psoc, hdd_ctx->target_type);
5179 	wifi_pos_set_oem_fw_version(psoc, hdd_ctx->target_fw_version);
5180 	wifi_pos_set_drv_ver_major(psoc, QWLAN_VERSION_MAJOR);
5181 	wifi_pos_set_drv_ver_minor(psoc, QWLAN_VERSION_MINOR);
5182 	wifi_pos_set_drv_ver_patch(psoc, QWLAN_VERSION_PATCH);
5183 	wifi_pos_set_drv_ver_build(psoc, QWLAN_VERSION_BUILD);
5184 	ucfg_mlme_get_neighbor_scan_max_chan_time(psoc,
5185 						  &neighbor_scan_max_chan_time);
5186 	ucfg_mlme_get_neighbor_scan_min_chan_time(psoc,
5187 						  &neighbor_scan_min_chan_time);
5188 	wifi_pos_set_dwell_time_min(psoc, neighbor_scan_min_chan_time);
5189 	wifi_pos_set_dwell_time_max(psoc, neighbor_scan_max_chan_time);
5190 }
5191 #else
5192 static int hdd_activate_wifi_pos(struct hdd_context *hdd_ctx)
5193 {
5194 	return oem_activate_service(hdd_ctx);
5195 }
5196 
5197 static int hdd_deactivate_wifi_pos(void)
5198 {
5199 	return oem_deactivate_service();
5200 }
5201 
5202 static void hdd_populate_wifi_pos_cfg(struct hdd_context *hdd_ctx)
5203 {
5204 }
5205 #endif
5206 
5207 /**
5208  * __hdd_open() - HDD Open function
5209  * @dev:	Pointer to net_device structure
5210  *
5211  * This is called in response to ifconfig up
5212  *
5213  * Return: 0 for success; non-zero for failure
5214  */
5215 static int __hdd_open(struct net_device *dev)
5216 {
5217 	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
5218 	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
5219 	int ret;
5220 	struct wlan_hdd_link_info *link_info = adapter->deflink;
5221 
5222 	hdd_enter_dev(dev);
5223 
5224 	qdf_mtrace(QDF_MODULE_ID_HDD, QDF_MODULE_ID_HDD,
5225 		   TRACE_CODE_HDD_OPEN_REQUEST,
5226 		   link_info->vdev_id, adapter->device_mode);
5227 
5228 	/* Nothing to be done if device is unloading */
5229 	if (cds_is_driver_unloading()) {
5230 		hdd_err("Driver is unloading can not open the hdd");
5231 		return -EBUSY;
5232 	}
5233 
5234 	if (cds_is_driver_recovering()) {
5235 		hdd_err("WLAN is currently recovering; Please try again.");
5236 		return -EBUSY;
5237 	}
5238 
5239 	/*
5240 	 * This scenario can be hit in cases where in the wlan driver after
5241 	 * registering the netdevices and there is a failure in driver
5242 	 * initialization. So return error gracefully because the netdevices
5243 	 * will be de-registered as part of the load failure.
5244 	 */
5245 
5246 	if (!cds_is_driver_loaded()) {
5247 		hdd_err("Failed to start the wlan driver!!");
5248 		return -EIO;
5249 	}
5250 
5251 	ret = wlan_hdd_validate_context(hdd_ctx);
5252 	if (ret) {
5253 		hdd_err("Can't start WLAN module, WiFi Disabled");
5254 		return ret;
5255 	}
5256 
5257 	ret = hdd_trigger_psoc_idle_restart(hdd_ctx);
5258 	if (ret) {
5259 		hdd_err("Failed to start WLAN modules return");
5260 		return ret;
5261 	}
5262 
5263 	if (!test_bit(SME_SESSION_OPENED, &link_info->link_flags)) {
5264 		ret = hdd_start_adapter(adapter, true);
5265 		if (ret) {
5266 			hdd_err("Failed to start adapter :%d",
5267 				adapter->device_mode);
5268 			return ret;
5269 		}
5270 	}
5271 
5272 	set_bit(DEVICE_IFACE_OPENED, &adapter->event_flags);
5273 	if (hdd_cm_is_vdev_associated(link_info)) {
5274 		hdd_debug("Enabling Tx Queues");
5275 		/* Enable TX queues only when we are connected */
5276 		wlan_hdd_netif_queue_control(adapter,
5277 					     WLAN_START_ALL_NETIF_QUEUE,
5278 					     WLAN_CONTROL_PATH);
5279 	}
5280 
5281 	/* Enable carrier and transmit queues for NDI */
5282 	if (WLAN_HDD_IS_NDI(adapter)) {
5283 		hdd_debug("Enabling Tx Queues");
5284 		wlan_hdd_netif_queue_control(adapter,
5285 			WLAN_START_ALL_NETIF_QUEUE_N_CARRIER,
5286 			WLAN_CONTROL_PATH);
5287 	}
5288 
5289 	hdd_populate_wifi_pos_cfg(hdd_ctx);
5290 	hdd_lpass_notify_start(link_info);
5291 
5292 	if (ucfg_pkt_capture_get_mode(hdd_ctx->psoc) !=
5293 				      PACKET_CAPTURE_MODE_DISABLE)
5294 		hdd_map_monitor_interface_vdev(adapter);
5295 
5296 	return 0;
5297 }
5298 
5299 /**
5300  * hdd_open() - Wrapper function for __hdd_open to protect it from SSR
5301  * @net_dev: Pointer to net_device structure
5302  *
5303  * This is called in response to ifconfig up
5304  *
5305  * Return: 0 for success; non-zero for failure
5306  */
5307 static int hdd_open(struct net_device *net_dev)
5308 {
5309 	int errno;
5310 	struct osif_vdev_sync *vdev_sync;
5311 
5312 	errno = osif_vdev_sync_trans_start(net_dev, &vdev_sync);
5313 	if (errno)
5314 		return errno;
5315 
5316 	errno = __hdd_open(net_dev);
5317 	if (!errno)
5318 		osif_vdev_cache_command(vdev_sync, NO_COMMAND);
5319 
5320 	osif_vdev_sync_trans_stop(vdev_sync);
5321 
5322 	return errno;
5323 }
5324 
5325 int hdd_stop_no_trans(struct net_device *dev)
5326 {
5327 	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
5328 	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
5329 	int ret;
5330 	mac_handle_t mac_handle;
5331 
5332 	hdd_enter_dev(dev);
5333 
5334 	qdf_mtrace(QDF_MODULE_ID_HDD, QDF_MODULE_ID_HDD,
5335 		   TRACE_CODE_HDD_STOP_REQUEST,
5336 		   adapter->deflink->vdev_id, adapter->device_mode);
5337 
5338 	ret = wlan_hdd_validate_context(hdd_ctx);
5339 	if (ret)
5340 		return ret;
5341 
5342 	/* Nothing to be done if the interface is not opened */
5343 	if (false == test_bit(DEVICE_IFACE_OPENED, &adapter->event_flags)) {
5344 		hdd_err("NETDEV Interface is not OPENED");
5345 		return -ENODEV;
5346 	}
5347 
5348 	mac_handle = hdd_ctx->mac_handle;
5349 
5350 	if (!wlan_hdd_is_session_type_monitor(adapter->device_mode) &&
5351 	    adapter->device_mode != QDF_FTM_MODE) {
5352 		hdd_debug("Disabling Auto Power save timer");
5353 		sme_ps_disable_auto_ps_timer(
5354 			mac_handle,
5355 			adapter->deflink->vdev_id);
5356 	}
5357 
5358 	/*
5359 	 * Disable TX on the interface, after this hard_start_xmit() will not
5360 	 * be called on that interface
5361 	 */
5362 	hdd_debug("Disabling queues, adapter device mode: %s(%d)",
5363 		  qdf_opmode_str(adapter->device_mode), adapter->device_mode);
5364 
5365 	wlan_hdd_netif_queue_control(adapter,
5366 				     WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER,
5367 				     WLAN_CONTROL_PATH);
5368 
5369 	if (adapter->device_mode == QDF_STA_MODE)
5370 		hdd_lpass_notify_stop(hdd_ctx);
5371 
5372 	/*
5373 	 * NAN data interface is different in some sense. The traffic on NDI is
5374 	 * bursty in nature and depends on the need to transfer. The service
5375 	 * layer may down the interface after the usage and up again when
5376 	 * required. In some sense, the NDI is expected to be available
5377 	 * (like SAP) iface until NDI delete request is issued by the service
5378 	 * layer. Skip BSS termination and adapter deletion for NAN Data
5379 	 * interface (NDI).
5380 	 */
5381 	if (WLAN_HDD_IS_NDI(adapter))
5382 		goto reset_iface_opened;
5383 
5384 	/*
5385 	 * The interface is marked as down for outside world (aka kernel)
5386 	 * But the driver is pretty much alive inside. The driver needs to
5387 	 * tear down the existing connection on the netdev (session)
5388 	 * cleanup the data pipes and wait until the control plane is stabilized
5389 	 * for this interface. The call also needs to wait until the above
5390 	 * mentioned actions are completed before returning to the caller.
5391 	 * Notice that hdd_stop_adapter is requested not to close the session
5392 	 * That is intentional to be able to scan if it is a STA/P2P interface
5393 	 */
5394 	hdd_stop_adapter(hdd_ctx, adapter);
5395 
5396 	/* DeInit the adapter. This ensures datapath cleanup as well */
5397 	hdd_deinit_adapter(hdd_ctx, adapter, true);
5398 
5399 reset_iface_opened:
5400 	/* Make sure the interface is marked as closed */
5401 	clear_bit(DEVICE_IFACE_OPENED, &adapter->event_flags);
5402 	if (!hdd_is_any_interface_open(hdd_ctx))
5403 		hdd_psoc_idle_timer_start(hdd_ctx);
5404 	hdd_exit();
5405 
5406 	return 0;
5407 }
5408 
5409 /**
5410  * hdd_stop() - Wrapper function for __hdd_stop to protect it from SSR
5411  * @net_dev: pointer to net_device structure
5412  *
5413  * This is called in response to ifconfig down
5414  *
5415  * Return: 0 for success and error number for failure
5416  */
5417 static int hdd_stop(struct net_device *net_dev)
5418 {
5419 	int errno;
5420 	struct osif_vdev_sync *vdev_sync;
5421 
5422 	errno = osif_vdev_sync_trans_start(net_dev, &vdev_sync);
5423 	if (errno) {
5424 		if (vdev_sync)
5425 			osif_vdev_cache_command(vdev_sync, INTERFACE_DOWN);
5426 		return errno;
5427 	}
5428 
5429 	errno = hdd_stop_no_trans(net_dev);
5430 
5431 	osif_vdev_sync_trans_stop(vdev_sync);
5432 
5433 	return errno;
5434 }
5435 
5436 /**
5437  * hdd_uninit() - HDD uninit function
5438  * @dev: Pointer to net_device structure
5439  *
5440  * This is called during the netdev unregister to uninitialize all data
5441  * associated with the device
5442  *
5443  * This function must be protected by a transition
5444  *
5445  * Return: None
5446  */
5447 static void hdd_uninit(struct net_device *dev)
5448 {
5449 	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
5450 	struct hdd_context *hdd_ctx;
5451 
5452 	hdd_enter_dev(dev);
5453 
5454 	if (adapter->magic != WLAN_HDD_ADAPTER_MAGIC) {
5455 		hdd_err("Invalid magic");
5456 		goto exit;
5457 	}
5458 
5459 	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
5460 	if (!hdd_ctx) {
5461 		hdd_err("NULL hdd_ctx");
5462 		goto exit;
5463 	}
5464 
5465 	if (dev != adapter->dev)
5466 		hdd_err("Invalid device reference");
5467 
5468 	hdd_deinit_adapter(hdd_ctx, adapter, true);
5469 
5470 	/* after uninit our adapter structure will no longer be valid */
5471 	adapter->magic = 0;
5472 
5473 exit:
5474 	hdd_exit();
5475 }
5476 
5477 static int hdd_open_cesium_nl_sock(void)
5478 {
5479 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
5480 	struct netlink_kernel_cfg cfg = {
5481 		.groups = WLAN_NLINK_MCAST_GRP_ID,
5482 		.input = NULL
5483 	};
5484 #endif
5485 	int ret = 0;
5486 
5487 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
5488 	cesium_nl_srv_sock = netlink_kernel_create(&init_net, WLAN_NLINK_CESIUM,
5489 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 7, 0))
5490 						   THIS_MODULE,
5491 #endif
5492 						   &cfg);
5493 #else
5494 	cesium_nl_srv_sock = netlink_kernel_create(&init_net, WLAN_NLINK_CESIUM,
5495 						   WLAN_NLINK_MCAST_GRP_ID,
5496 						   NULL, NULL, THIS_MODULE);
5497 #endif
5498 
5499 	if (!cesium_nl_srv_sock) {
5500 		hdd_err("NLINK:  cesium netlink_kernel_create failed");
5501 		ret = -ECONNREFUSED;
5502 	}
5503 
5504 	return ret;
5505 }
5506 
5507 static void hdd_close_cesium_nl_sock(void)
5508 {
5509 	if (cesium_nl_srv_sock) {
5510 		netlink_kernel_release(cesium_nl_srv_sock);
5511 		cesium_nl_srv_sock = NULL;
5512 	}
5513 }
5514 
5515 void hdd_update_dynamic_mac(struct hdd_context *hdd_ctx,
5516 			    struct qdf_mac_addr *curr_mac_addr,
5517 			    struct qdf_mac_addr *new_mac_addr)
5518 {
5519 	uint8_t i;
5520 
5521 	hdd_enter();
5522 
5523 	for (i = 0; i < QDF_MAX_CONCURRENCY_PERSONA; i++) {
5524 		if (!qdf_mem_cmp(
5525 			curr_mac_addr->bytes,
5526 			&hdd_ctx->dynamic_mac_list[i].dynamic_mac.bytes[0],
5527 				 sizeof(struct qdf_mac_addr))) {
5528 			qdf_mem_copy(&hdd_ctx->dynamic_mac_list[i].dynamic_mac,
5529 				     new_mac_addr->bytes,
5530 				     sizeof(struct qdf_mac_addr));
5531 			break;
5532 		}
5533 	}
5534 
5535 	hdd_exit();
5536 }
5537 
5538 #if defined(WLAN_FEATURE_11BE_MLO) && defined(CFG80211_11BE_BASIC) && \
5539 	!defined(WLAN_HDD_MULTI_VDEV_SINGLE_NDEV)
5540 void hdd_set_mld_address(struct hdd_adapter *adapter,
5541 			 const struct qdf_mac_addr *mac_addr)
5542 {
5543 	int i;
5544 	bool eht_capab;
5545 	struct hdd_adapter *link_adapter;
5546 	struct hdd_mlo_adapter_info *mlo_adapter_info;
5547 
5548 	ucfg_psoc_mlme_get_11be_capab(adapter->hdd_ctx->psoc, &eht_capab);
5549 	if (adapter->mlo_adapter_info.is_ml_adapter && eht_capab) {
5550 		mlo_adapter_info = &adapter->mlo_adapter_info;
5551 		for (i = 0; i < WLAN_MAX_MLD; i++) {
5552 			link_adapter = mlo_adapter_info->link_adapter[i];
5553 			if (link_adapter)
5554 				qdf_copy_macaddr(&link_adapter->mld_addr,
5555 						 mac_addr);
5556 		}
5557 		qdf_copy_macaddr(&adapter->mld_addr, mac_addr);
5558 	}
5559 }
5560 
5561 /**
5562  * hdd_get_netdev_by_vdev_mac() - Get Netdev based on MAC
5563  * @mac_addr: Vdev MAC address
5564  *
5565  * Get netdev from adapter based upon Vdev MAC address.
5566  *
5567  * Return: netdev pointer.
5568  */
5569 static qdf_netdev_t
5570 hdd_get_netdev_by_vdev_mac(struct qdf_mac_addr *mac_addr)
5571 {
5572 	struct hdd_context *hdd_ctx;
5573 	struct hdd_adapter *adapter;
5574 	struct hdd_adapter *ml_adapter;
5575 
5576 	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
5577 	if (!hdd_ctx) {
5578 		hdd_err("Invalid HDD context");
5579 		return NULL;
5580 	}
5581 
5582 	adapter = hdd_get_adapter_by_macaddr(hdd_ctx, mac_addr->bytes);
5583 	if (!adapter) {
5584 		hdd_err("Adapter not foud for MAC " QDF_MAC_ADDR_FMT "",
5585 			QDF_MAC_ADDR_REF(mac_addr->bytes));
5586 		return NULL;
5587 	}
5588 
5589 	if (adapter->mlo_adapter_info.is_link_adapter &&
5590 	    adapter->mlo_adapter_info.associate_with_ml_adapter) {
5591 		ml_adapter = adapter->mlo_adapter_info.ml_adapter;
5592 		adapter =  ml_adapter;
5593 	}
5594 
5595 	return adapter->dev;
5596 }
5597 #else
5598 static qdf_netdev_t
5599 hdd_get_netdev_by_vdev_mac(struct qdf_mac_addr *mac_addr)
5600 {
5601 	struct hdd_context *hdd_ctx;
5602 	struct hdd_adapter *adapter;
5603 
5604 	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
5605 	if (!hdd_ctx) {
5606 		hdd_err("Invalid HDD context");
5607 		return NULL;
5608 	}
5609 
5610 	adapter = hdd_get_adapter_by_macaddr(hdd_ctx, mac_addr->bytes);
5611 	if (!adapter) {
5612 		hdd_err("Adapter not foud for MAC " QDF_MAC_ADDR_FMT "",
5613 			QDF_MAC_ADDR_REF(mac_addr->bytes));
5614 		return NULL;
5615 	}
5616 
5617 	return adapter->dev;
5618 }
5619 #endif
5620 
5621 #ifdef WLAN_FEATURE_DYNAMIC_MAC_ADDR_UPDATE
5622 #if defined(WLAN_FEATURE_11BE_MLO) && defined(CFG80211_11BE_BASIC) && \
5623 	!defined(WLAN_HDD_MULTI_VDEV_SINGLE_NDEV)
5624 static void hdd_update_set_mac_addr_req_ctx(struct hdd_adapter *adapter,
5625 					    void *req_ctx)
5626 {
5627 	adapter->set_mac_addr_req_ctx = req_ctx;
5628 	if (adapter->mlo_adapter_info.associate_with_ml_adapter)
5629 		adapter->mlo_adapter_info.ml_adapter->set_mac_addr_req_ctx =
5630 									req_ctx;
5631 }
5632 #else
5633 static void hdd_update_set_mac_addr_req_ctx(struct hdd_adapter *adapter,
5634 					    void *req_ctx)
5635 {
5636 	adapter->set_mac_addr_req_ctx = req_ctx;
5637 }
5638 #endif
5639 
5640 /**
5641  * hdd_is_dynamic_set_mac_addr_supported() - API to check dynamic MAC address
5642  *				             update is supported or not
5643  * @hdd_ctx: Pointer to the HDD context
5644  *
5645  * Return: true or false
5646  */
5647 static inline bool
5648 hdd_is_dynamic_set_mac_addr_supported(struct hdd_context *hdd_ctx)
5649 {
5650 	return hdd_ctx->is_vdev_macaddr_dynamic_update_supported;
5651 }
5652 
5653 bool hdd_is_dynamic_set_mac_addr_allowed(struct hdd_adapter *adapter)
5654 {
5655 	if (!adapter->deflink->vdev) {
5656 		hdd_err("VDEV is NULL");
5657 		return false;
5658 	}
5659 
5660 	if (!hdd_is_dynamic_set_mac_addr_supported(adapter->hdd_ctx)) {
5661 		hdd_info_rl("On iface up, set mac address change isn't supported");
5662 		return false;
5663 	}
5664 
5665 	switch (adapter->device_mode) {
5666 	case QDF_STA_MODE:
5667 		if (!cm_is_vdev_disconnected(adapter->deflink->vdev)) {
5668 			hdd_info_rl("VDEV is not in disconnected state, set mac address isn't supported");
5669 			return false;
5670 		}
5671 		return true;
5672 	case QDF_SAP_MODE:
5673 		if (test_bit(SOFTAP_BSS_STARTED,
5674 			     &adapter->deflink->link_flags)) {
5675 			hdd_info_rl("SAP is in up state, set mac address isn't supported");
5676 			return false;
5677 		} else {
5678 			return true;
5679 		}
5680 	default:
5681 		hdd_info_rl("Dynamic set mac address isn't supported for opmode:%d",
5682 			adapter->device_mode);
5683 		return false;
5684 	}
5685 }
5686 
5687 int hdd_dynamic_mac_address_set(struct wlan_hdd_link_info *link_info,
5688 				struct qdf_mac_addr mac_addr,
5689 				struct qdf_mac_addr mld_addr,
5690 				bool update_self_peer)
5691 {
5692 	int ret;
5693 	void *cookie;
5694 	bool update_mld_addr;
5695 	uint32_t *fw_resp_status;
5696 	QDF_STATUS status;
5697 	struct osif_request *request;
5698 	struct wlan_objmgr_vdev *vdev;
5699 	struct hdd_adapter *adapter = link_info->adapter;
5700 	struct hdd_context *hdd_ctx = adapter->hdd_ctx;
5701 	static const struct osif_request_params params = {
5702 		.priv_size = sizeof(*fw_resp_status),
5703 		.timeout_ms = WLAN_SET_MAC_ADDR_TIMEOUT
5704 	};
5705 
5706 	vdev = hdd_objmgr_get_vdev_by_user(link_info, WLAN_OSIF_ID);
5707 	if (!vdev)
5708 		return -EINVAL;
5709 
5710 	status = ucfg_vdev_mgr_cdp_vdev_detach(vdev);
5711 	if (QDF_IS_STATUS_ERROR(status)) {
5712 		hdd_err("Failed to detach CDP vdev. Status:%d", status);
5713 		ret = qdf_status_to_os_return(status);
5714 		goto vdev_ref;
5715 	}
5716 
5717 	request = osif_request_alloc(&params);
5718 	if (!request) {
5719 		ret = -ENOMEM;
5720 		goto status_ret;
5721 	}
5722 
5723 	/* Host should hold a wake lock until the FW event response is received
5724 	 * the WMI event would not be a wake up event.
5725 	 */
5726 	qdf_runtime_pm_prevent_suspend(
5727 			&hdd_ctx->runtime_context.dyn_mac_addr_update);
5728 	hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_DYN_MAC_ADDR_UPDATE);
5729 
5730 	cookie = osif_request_cookie(request);
5731 	hdd_update_set_mac_addr_req_ctx(adapter, cookie);
5732 
5733 	status = sme_send_set_mac_addr(mac_addr, mld_addr, vdev);
5734 	ret = qdf_status_to_os_return(status);
5735 	if (QDF_IS_STATUS_ERROR(status)) {
5736 		hdd_nofl_err("Failed to send set MAC address command. Status:%d",
5737 			     status);
5738 		osif_request_put(request);
5739 		goto status_ret;
5740 	} else {
5741 		ret = osif_request_wait_for_response(request);
5742 		if (ret) {
5743 			hdd_err("Set MAC address response timed out");
5744 		} else {
5745 			fw_resp_status = (uint32_t *)osif_request_priv(request);
5746 			if (*fw_resp_status) {
5747 				hdd_err("Set MAC address failed in FW. Status: %d",
5748 					*fw_resp_status);
5749 				ret = -EAGAIN;
5750 			}
5751 		}
5752 	}
5753 
5754 	osif_request_put(request);
5755 
5756 	if (qdf_is_macaddr_zero(&mld_addr))
5757 		update_mld_addr = false;
5758 	else
5759 		update_mld_addr = true;
5760 
5761 	status = sme_update_vdev_mac_addr(vdev, mac_addr, mld_addr,
5762 					  update_self_peer, update_mld_addr,
5763 					  ret);
5764 
5765 	if (QDF_IS_STATUS_ERROR(status))
5766 		ret = qdf_status_to_os_return(status);
5767 
5768 status_ret:
5769 	status = ucfg_vdev_mgr_cdp_vdev_attach(vdev);
5770 	if (QDF_IS_STATUS_ERROR(status)) {
5771 		hdd_err("Failed to attach CDP vdev. status:%d", status);
5772 		ret = qdf_status_to_os_return(status);
5773 		goto allow_suspend;
5774 	} else if (!ret) {
5775 		status = ucfg_dp_update_link_mac_addr(vdev, &mac_addr, false);
5776 		if (QDF_IS_STATUS_ERROR(status)) {
5777 			ret = qdf_status_to_os_return(status);
5778 			hdd_err("DP link MAC update failed");
5779 			goto allow_suspend;
5780 		}
5781 	}
5782 	sme_vdev_set_data_tx_callback(vdev);
5783 
5784 	/* Update FW WoW pattern with new MAC address */
5785 	ucfg_pmo_del_wow_pattern(vdev);
5786 	ucfg_pmo_register_wow_default_patterns(vdev);
5787 
5788 allow_suspend:
5789 	hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DYN_MAC_ADDR_UPDATE);
5790 	qdf_runtime_pm_allow_suspend(
5791 			&hdd_ctx->runtime_context.dyn_mac_addr_update);
5792 
5793 vdev_ref:
5794 	hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_ID);
5795 
5796 	return ret;
5797 }
5798 
5799 static void hdd_set_mac_addr_event_cb(uint8_t vdev_id, uint8_t status)
5800 {
5801 	struct hdd_context *hdd_ctx;
5802 	struct wlan_hdd_link_info *link_info;
5803 	struct osif_request *req;
5804 	uint32_t *fw_response_status;
5805 
5806 	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
5807 	if (!hdd_ctx) {
5808 		hdd_err("Invalid HDD context");
5809 		return;
5810 	}
5811 
5812 	link_info = hdd_get_link_info_by_vdev(hdd_ctx, vdev_id);
5813 	if (!link_info) {
5814 		hdd_err("No adapter found for VDEV ID:%d", vdev_id);
5815 		return;
5816 	}
5817 
5818 	req = osif_request_get(link_info->adapter->set_mac_addr_req_ctx);
5819 	if (!req) {
5820 		osif_err("Obsolete request for VDEV ID:%d", vdev_id);
5821 		return;
5822 	}
5823 
5824 	fw_response_status = (uint32_t *)osif_request_priv(req);
5825 	*fw_response_status = status;
5826 
5827 	osif_request_complete(req);
5828 	osif_request_put(req);
5829 }
5830 #else
5831 static inline bool
5832 hdd_is_dynamic_set_mac_addr_supported(struct hdd_context *hdd_ctx)
5833 {
5834 	return false;
5835 }
5836 #endif
5837 
5838 #if defined(WLAN_FEATURE_11BE_MLO) && defined(WLAN_HDD_MULTI_VDEV_SINGLE_NDEV)
5839 static QDF_STATUS
5840 hdd_adapter_update_links_on_link_switch(struct wlan_hdd_link_info *cur_link_info,
5841 					struct wlan_hdd_link_info *new_link_info)
5842 {
5843 	unsigned long link_flags;
5844 	struct wlan_objmgr_vdev *vdev;
5845 	int cur_link_idx, new_link_idx;
5846 	uint8_t cur_old_pos, cur_new_pos;
5847 	struct vdev_osif_priv *vdev_priv;
5848 	struct hdd_adapter *adapter = cur_link_info->adapter;
5849 
5850 	/* Update the new position of current and new link info
5851 	 * in the link info array.
5852 	 */
5853 	cur_link_idx = hdd_adapter_get_index_of_link_info(cur_link_info);
5854 	new_link_idx = hdd_adapter_get_index_of_link_info(new_link_info);
5855 
5856 	cur_old_pos = adapter->curr_link_info_map[cur_link_idx];
5857 	cur_new_pos = adapter->curr_link_info_map[new_link_idx];
5858 
5859 	adapter->curr_link_info_map[new_link_idx] = cur_old_pos;
5860 	adapter->curr_link_info_map[cur_link_idx] = cur_new_pos;
5861 
5862 	/* Move VDEV from current link info to new link info */
5863 	qdf_atomic_clear_bit(cur_link_idx, &adapter->active_links);
5864 	qdf_spin_lock_bh(&cur_link_info->vdev_lock);
5865 	vdev = cur_link_info->vdev;
5866 	cur_link_info->vdev = NULL;
5867 	cur_link_info->vdev_id = WLAN_INVALID_VDEV_ID;
5868 	qdf_spin_unlock_bh(&cur_link_info->vdev_lock);
5869 
5870 	qdf_spin_lock_bh(&new_link_info->vdev_lock);
5871 	new_link_info->vdev = vdev;
5872 	new_link_info->vdev_id = wlan_vdev_get_id(vdev);
5873 	qdf_spin_unlock_bh(&new_link_info->vdev_lock);
5874 	qdf_atomic_set_bit(new_link_idx, &adapter->active_links);
5875 
5876 	/* Move the link flags between current and new link info */
5877 	link_flags = new_link_info->link_flags;
5878 	new_link_info->link_flags = cur_link_info->link_flags;
5879 	cur_link_info->link_flags = link_flags;
5880 
5881 	/* Update VDEV-OSIF priv pointer to new link info */
5882 	vdev_priv = wlan_vdev_get_ospriv(new_link_info->vdev);
5883 	vdev_priv->legacy_osif_priv = new_link_info;
5884 
5885 	return QDF_STATUS_SUCCESS;
5886 }
5887 
5888 struct wlan_hdd_link_info *
5889 hdd_get_link_info_by_ieee_link_id(struct hdd_adapter *adapter, int32_t link_id)
5890 {
5891 	struct wlan_hdd_link_info *link_info;
5892 	struct hdd_station_ctx *sta_ctx;
5893 
5894 	if (!adapter || link_id == WLAN_INVALID_LINK_ID) {
5895 		hdd_err("NULL adapter or invalid link ID");
5896 		return NULL;
5897 	}
5898 
5899 	hdd_adapter_for_each_link_info(adapter, link_info) {
5900 		sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(link_info);
5901 		if (sta_ctx->conn_info.ieee_link_id == link_id)
5902 			return link_info;
5903 	}
5904 
5905 	return NULL;
5906 }
5907 
5908 QDF_STATUS
5909 hdd_link_switch_vdev_mac_addr_update(int32_t ieee_old_link_id,
5910 				     int32_t ieee_new_link_id, uint8_t vdev_id)
5911 {
5912 	QDF_STATUS status = QDF_STATUS_E_INVAL;
5913 	struct hdd_context *hdd_ctx;
5914 	struct hdd_adapter *adapter;
5915 	struct wlan_objmgr_vdev *vdev;
5916 	struct wlan_hdd_link_info *cur_link_info, *new_link_info;
5917 	struct hdd_station_ctx *sta_ctx;
5918 
5919 	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
5920 	if (!hdd_ctx) {
5921 		hdd_err("HDD ctx NULL");
5922 		return QDF_STATUS_E_INVAL;
5923 	}
5924 
5925 	cur_link_info = hdd_get_link_info_by_vdev(hdd_ctx, vdev_id);
5926 	if (!cur_link_info) {
5927 		hdd_err("VDEV %d not found", vdev_id);
5928 		return status;
5929 	}
5930 
5931 	vdev = hdd_objmgr_get_vdev_by_user(cur_link_info, WLAN_OSIF_ID);
5932 	if (!vdev) {
5933 		hdd_err("Invalid VDEV %d", vdev_id);
5934 		return status;
5935 	}
5936 
5937 	sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(cur_link_info);
5938 	if (sta_ctx->conn_info.ieee_link_id != ieee_old_link_id) {
5939 		hdd_err("Link id %d mismatch", sta_ctx->conn_info.ieee_link_id);
5940 		goto release_ref;
5941 	}
5942 
5943 	adapter = cur_link_info->adapter;
5944 	new_link_info = hdd_get_link_info_by_ieee_link_id(adapter,
5945 							  ieee_new_link_id);
5946 	if (!new_link_info) {
5947 		hdd_err("Link id %d not found", ieee_new_link_id);
5948 		goto release_ref;
5949 	}
5950 
5951 	status = ucfg_dp_update_link_mac_addr(vdev, &new_link_info->link_addr,
5952 					      true);
5953 	if (QDF_IS_STATUS_ERROR(status)) {
5954 		hdd_err("DP link MAC update failed");
5955 		goto release_ref;
5956 	}
5957 
5958 	status = hdd_adapter_update_links_on_link_switch(cur_link_info,
5959 							 new_link_info);
5960 	if (QDF_IS_STATUS_ERROR(status)) {
5961 		hdd_err("Failed to update adapter link info");
5962 		goto release_ref;
5963 	}
5964 
5965 	hdd_adapter_update_mlo_mgr_mac_addr(adapter);
5966 	sme_vdev_set_data_tx_callback(vdev);
5967 	ucfg_pmo_del_wow_pattern(vdev);
5968 	ucfg_pmo_register_wow_default_patterns(vdev);
5969 
5970 release_ref:
5971 	hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_ID);
5972 	return status;
5973 }
5974 #endif
5975 
5976 /**
5977  * __hdd_set_mac_address() - set the user specified mac address
5978  * @dev:	Pointer to the net device.
5979  * @addr:	Pointer to the sockaddr.
5980  *
5981  * This function sets the user specified mac address using
5982  * the command ifconfig wlanX hw ether <mac address>.
5983  *
5984  * Return: 0 for success, non zero for failure
5985  */
5986 static int __hdd_set_mac_address(struct net_device *dev, void *addr)
5987 {
5988 	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
5989 	struct hdd_adapter *adapter_temp;
5990 	struct hdd_context *hdd_ctx;
5991 	struct sockaddr *psta_mac_addr = addr;
5992 	QDF_STATUS qdf_ret_status = QDF_STATUS_SUCCESS;
5993 	int ret;
5994 	struct qdf_mac_addr mac_addr;
5995 	bool net_if_running = netif_running(dev);
5996 
5997 	hdd_enter_dev(dev);
5998 
5999 	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
6000 	ret = wlan_hdd_validate_context(hdd_ctx);
6001 	if (0 != ret)
6002 		return ret;
6003 
6004 	if (net_if_running) {
6005 		if (!hdd_is_dynamic_set_mac_addr_allowed(adapter))
6006 			return -ENOTSUPP;
6007 	}
6008 
6009 	qdf_mem_copy(&mac_addr, psta_mac_addr->sa_data, sizeof(mac_addr));
6010 	adapter_temp = hdd_get_adapter_by_macaddr(hdd_ctx, mac_addr.bytes);
6011 	if (adapter_temp) {
6012 		if (!qdf_str_cmp(adapter_temp->dev->name, dev->name))
6013 			return 0;
6014 		hdd_err("%s adapter exist with same address " QDF_MAC_ADDR_FMT,
6015 			adapter_temp->dev->name,
6016 			QDF_MAC_ADDR_REF(mac_addr.bytes));
6017 		return -EINVAL;
6018 	}
6019 	qdf_ret_status = wlan_hdd_validate_mac_address(&mac_addr);
6020 	if (QDF_IS_STATUS_ERROR(qdf_ret_status))
6021 		return -EINVAL;
6022 
6023 	hdd_nofl_debug("Changing MAC to "
6024 		       QDF_MAC_ADDR_FMT " of the interface %s ",
6025 		       QDF_MAC_ADDR_REF(mac_addr.bytes), dev->name);
6026 
6027 	if (net_if_running && adapter->deflink->vdev) {
6028 		ret = hdd_update_vdev_mac_address(adapter, mac_addr);
6029 		if (ret)
6030 			return ret;
6031 	}
6032 
6033 	hdd_set_mld_address(adapter, &mac_addr);
6034 
6035 	hdd_update_dynamic_mac(hdd_ctx, &adapter->mac_addr, &mac_addr);
6036 	ucfg_dp_update_intf_mac(hdd_ctx->psoc, &adapter->mac_addr, &mac_addr,
6037 				adapter->deflink->vdev);
6038 	memcpy(&adapter->mac_addr, psta_mac_addr->sa_data, ETH_ALEN);
6039 	qdf_net_update_net_device_dev_addr(dev, psta_mac_addr->sa_data,
6040 					   ETH_ALEN);
6041 
6042 	hdd_exit();
6043 	return ret;
6044 }
6045 
6046 /**
6047  * hdd_set_mac_address() - Wrapper function to protect __hdd_set_mac_address()
6048  *	function from SSR
6049  * @net_dev: pointer to net_device structure
6050  * @addr: Pointer to the sockaddr
6051  *
6052  * This function sets the user specified mac address using
6053  * the command ifconfig wlanX hw ether <mac address>.
6054  *
6055  * Return: 0 for success.
6056  */
6057 static int hdd_set_mac_address(struct net_device *net_dev, void *addr)
6058 {
6059 	struct osif_vdev_sync *vdev_sync;
6060 	int errno;
6061 
6062 	errno = osif_vdev_sync_op_start(net_dev, &vdev_sync);
6063 	if (errno)
6064 		return errno;
6065 
6066 	errno = __hdd_set_mac_address(net_dev, addr);
6067 
6068 	osif_vdev_sync_op_stop(vdev_sync);
6069 
6070 	return errno;
6071 }
6072 
6073 static uint8_t *wlan_hdd_get_derived_intf_addr(struct hdd_context *hdd_ctx)
6074 {
6075 	int i, j;
6076 
6077 	i = qdf_ffz(hdd_ctx->derived_intf_addr_mask);
6078 	if (i < 0 || i >= hdd_ctx->num_derived_addr)
6079 		return NULL;
6080 	qdf_atomic_set_bit(i, &hdd_ctx->derived_intf_addr_mask);
6081 	hdd_nofl_debug("Assigning MAC from derived list "QDF_MAC_ADDR_FMT,
6082 		       QDF_MAC_ADDR_REF(hdd_ctx->derived_mac_addr[i].bytes));
6083 
6084 	/* Copy the mac in dynamic mac list at first free position */
6085 	for (j = 0; j < QDF_MAX_CONCURRENCY_PERSONA; j++) {
6086 		if (qdf_is_macaddr_zero(&hdd_ctx->
6087 					dynamic_mac_list[j].dynamic_mac))
6088 			break;
6089 	}
6090 	if (j == QDF_MAX_CONCURRENCY_PERSONA) {
6091 		hdd_err("Max interfaces are up");
6092 		return NULL;
6093 	}
6094 
6095 	qdf_mem_copy(&hdd_ctx->dynamic_mac_list[j].dynamic_mac.bytes,
6096 		     &hdd_ctx->derived_mac_addr[i].bytes,
6097 		     sizeof(struct qdf_mac_addr));
6098 	hdd_ctx->dynamic_mac_list[j].is_provisioned_mac = false;
6099 	hdd_ctx->dynamic_mac_list[j].bit_position = i;
6100 
6101 	return hdd_ctx->derived_mac_addr[i].bytes;
6102 }
6103 
6104 static uint8_t *wlan_hdd_get_provisioned_intf_addr(struct hdd_context *hdd_ctx)
6105 {
6106 	int i, j;
6107 
6108 	i = qdf_ffz(hdd_ctx->provisioned_intf_addr_mask);
6109 	if (i < 0 || i >= hdd_ctx->num_provisioned_addr)
6110 		return NULL;
6111 	qdf_atomic_set_bit(i, &hdd_ctx->provisioned_intf_addr_mask);
6112 	hdd_debug("Assigning MAC from provisioned list "QDF_MAC_ADDR_FMT,
6113 		  QDF_MAC_ADDR_REF(hdd_ctx->provisioned_mac_addr[i].bytes));
6114 
6115 	/* Copy the mac in dynamic mac list at first free position */
6116 	for (j = 0; j < QDF_MAX_CONCURRENCY_PERSONA; j++) {
6117 		if (qdf_is_macaddr_zero(&hdd_ctx->
6118 					dynamic_mac_list[j].dynamic_mac))
6119 			break;
6120 	}
6121 	if (j == QDF_MAX_CONCURRENCY_PERSONA) {
6122 		hdd_err("Max interfaces are up");
6123 		return NULL;
6124 	}
6125 
6126 	qdf_mem_copy(&hdd_ctx->dynamic_mac_list[j].dynamic_mac.bytes,
6127 		     &hdd_ctx->provisioned_mac_addr[i].bytes,
6128 		     sizeof(struct qdf_mac_addr));
6129 	hdd_ctx->dynamic_mac_list[j].is_provisioned_mac = true;
6130 	hdd_ctx->dynamic_mac_list[j].bit_position = i;
6131 	return hdd_ctx->provisioned_mac_addr[i].bytes;
6132 }
6133 
6134 uint8_t *wlan_hdd_get_intf_addr(struct hdd_context *hdd_ctx,
6135 				enum QDF_OPMODE interface_type)
6136 {
6137 	uint8_t *mac_addr = NULL;
6138 
6139 	if (qdf_atomic_test_bit(interface_type,
6140 				(unsigned long *)
6141 				(&hdd_ctx->config->provisioned_intf_pool)))
6142 		mac_addr = wlan_hdd_get_provisioned_intf_addr(hdd_ctx);
6143 
6144 	if ((!mac_addr) &&
6145 	    (qdf_atomic_test_bit(interface_type,
6146 				 (unsigned long *)
6147 				 (&hdd_ctx->config->derived_intf_pool))))
6148 		mac_addr = wlan_hdd_get_derived_intf_addr(hdd_ctx);
6149 
6150 	if (!mac_addr)
6151 		hdd_err("MAC is not available in both the lists");
6152 	return mac_addr;
6153 }
6154 
6155 void wlan_hdd_release_intf_addr(struct hdd_context *hdd_ctx,
6156 				uint8_t *releaseAddr)
6157 {
6158 	int i;
6159 	int mac_pos_in_mask;
6160 
6161 	for (i = 0; i < QDF_MAX_CONCURRENCY_PERSONA; i++) {
6162 		if (!memcmp(releaseAddr,
6163 		    hdd_ctx->dynamic_mac_list[i].dynamic_mac.bytes,
6164 		    QDF_MAC_ADDR_SIZE)) {
6165 			mac_pos_in_mask =
6166 				hdd_ctx->dynamic_mac_list[i].bit_position;
6167 			if (hdd_ctx->dynamic_mac_list[i].is_provisioned_mac) {
6168 				qdf_atomic_clear_bit(
6169 						mac_pos_in_mask,
6170 						&hdd_ctx->
6171 						   provisioned_intf_addr_mask);
6172 				hdd_debug("Releasing MAC from provisioned list");
6173 				hdd_debug(
6174 					  QDF_MAC_ADDR_FMT,
6175 					  QDF_MAC_ADDR_REF(releaseAddr));
6176 			} else {
6177 				qdf_atomic_clear_bit(
6178 						mac_pos_in_mask, &hdd_ctx->
6179 						derived_intf_addr_mask);
6180 				hdd_debug("Releasing MAC from derived list");
6181 				hdd_debug(QDF_MAC_ADDR_FMT,
6182 					  QDF_MAC_ADDR_REF(releaseAddr));
6183 			}
6184 			qdf_zero_macaddr(&hdd_ctx->
6185 					    dynamic_mac_list[i].dynamic_mac);
6186 			hdd_ctx->dynamic_mac_list[i].is_provisioned_mac =
6187 									false;
6188 			hdd_ctx->dynamic_mac_list[i].bit_position = 0;
6189 			break;
6190 		}
6191 
6192 	}
6193 	if (i == QDF_MAX_CONCURRENCY_PERSONA)
6194 		hdd_debug("Releasing non existing MAC " QDF_MAC_ADDR_FMT,
6195 			  QDF_MAC_ADDR_REF(releaseAddr));
6196 }
6197 
6198 /**
6199  * hdd_set_derived_multicast_list(): Add derived peer multicast address list in
6200  *                                   multicast list request to the FW
6201  * @psoc: Pointer to psoc
6202  * @adapter: Pointer to hdd adapter
6203  * @mc_list_request: Multicast list request to the FW
6204  * @mc_count: number of multicast addresses received from the kernel
6205  *
6206  * Return: None
6207  */
6208 static void
6209 hdd_set_derived_multicast_list(struct wlan_objmgr_psoc *psoc,
6210 			       struct hdd_adapter *adapter,
6211 			       struct pmo_mc_addr_list_params *mc_list_request,
6212 			       int *mc_count)
6213 {
6214 	int i = 0, j = 0, list_count = *mc_count;
6215 	struct qdf_mac_addr *peer_mc_addr_list = NULL;
6216 	uint8_t  driver_mc_cnt = 0;
6217 	uint32_t max_ndp_sessions = 0;
6218 
6219 	cfg_nan_get_ndp_max_sessions(psoc, &max_ndp_sessions);
6220 
6221 	ucfg_nan_get_peer_mc_list(adapter->deflink->vdev, &peer_mc_addr_list);
6222 
6223 	for (j = 0; j < max_ndp_sessions; j++) {
6224 		for (i = 0; i < list_count; i++) {
6225 			if (qdf_is_macaddr_zero(&peer_mc_addr_list[j]) ||
6226 			    qdf_is_macaddr_equal(&mc_list_request->mc_addr[i],
6227 						 &peer_mc_addr_list[j]))
6228 				break;
6229 		}
6230 		if (i == list_count) {
6231 			qdf_mem_copy(
6232 			   &(mc_list_request->mc_addr[list_count +
6233 						driver_mc_cnt].bytes),
6234 			   peer_mc_addr_list[j].bytes, ETH_ALEN);
6235 			hdd_debug("mlist[%d] = " QDF_MAC_ADDR_FMT,
6236 				  list_count + driver_mc_cnt,
6237 				  QDF_MAC_ADDR_REF(
6238 					mc_list_request->mc_addr[list_count +
6239 					driver_mc_cnt].bytes));
6240 			driver_mc_cnt++;
6241 		}
6242 	}
6243 	*mc_count += driver_mc_cnt;
6244 }
6245 
6246 /**
6247  * __hdd_set_multicast_list() - set the multicast address list
6248  * @dev: Pointer to the WLAN device.
6249  *
6250  * This function sets the multicast address list.
6251  *
6252  * Return: None
6253  */
6254 static void __hdd_set_multicast_list(struct net_device *dev)
6255 {
6256 	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
6257 	int i = 0, errno;
6258 	struct netdev_hw_addr *ha;
6259 	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
6260 	struct pmo_mc_addr_list_params *mc_list_request = NULL;
6261 	struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc;
6262 	int mc_count = 0;
6263 
6264 	if (hdd_ctx->hdd_wlan_suspended) {
6265 		hdd_err_rl("Device is system suspended");
6266 		return;
6267 	}
6268 
6269 	hdd_enter_dev(dev);
6270 	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam())
6271 		return;
6272 
6273 	errno = wlan_hdd_validate_context(hdd_ctx);
6274 	if (errno)
6275 		return;
6276 
6277 	errno = hdd_validate_adapter(adapter);
6278 	if (errno)
6279 		return;
6280 
6281 	if (hdd_ctx->driver_status == DRIVER_MODULES_CLOSED) {
6282 		hdd_debug("Driver module is closed");
6283 		return;
6284 	}
6285 
6286 	mc_list_request = qdf_mem_malloc(sizeof(*mc_list_request));
6287 	if (!mc_list_request)
6288 		return;
6289 
6290 	qdf_spin_lock_bh(&adapter->mc_list_lock);
6291 	/* Delete already configured multicast address list */
6292 	if (adapter->mc_addr_list.mc_cnt > 0)
6293 		hdd_disable_and_flush_mc_addr_list(adapter,
6294 			pmo_mc_list_change_notify);
6295 
6296 	if (dev->flags & IFF_ALLMULTI) {
6297 		hdd_debug("allow all multicast frames");
6298 		hdd_disable_and_flush_mc_addr_list(adapter,
6299 			pmo_mc_list_change_notify);
6300 	} else {
6301 		mc_count = netdev_mc_count(dev);
6302 		if (mc_count > ucfg_pmo_max_mc_addr_supported(psoc)) {
6303 			hdd_debug("Exceeded max MC filter addresses (%d). Allowing all MC frames by disabling MC address filtering",
6304 				  ucfg_pmo_max_mc_addr_supported(psoc));
6305 			hdd_disable_and_flush_mc_addr_list(adapter,
6306 				pmo_mc_list_change_notify);
6307 			adapter->mc_addr_list.mc_cnt = 0;
6308 			goto free_req;
6309 		}
6310 		netdev_for_each_mc_addr(ha, dev) {
6311 			if (i == mc_count)
6312 				break;
6313 			memset(&(mc_list_request->mc_addr[i].bytes),
6314 				0, ETH_ALEN);
6315 			memcpy(&(mc_list_request->mc_addr[i].bytes),
6316 				ha->addr, ETH_ALEN);
6317 			hdd_debug("mlist[%d] = "QDF_MAC_ADDR_FMT, i,
6318 				  QDF_MAC_ADDR_REF(mc_list_request->mc_addr[i].bytes));
6319 			i++;
6320 		}
6321 
6322 		if (adapter->device_mode == QDF_NDI_MODE)
6323 			hdd_set_derived_multicast_list(psoc, adapter,
6324 						       mc_list_request,
6325 						       &mc_count);
6326 	}
6327 
6328 	adapter->mc_addr_list.mc_cnt = mc_count;
6329 	mc_list_request->psoc = psoc;
6330 	mc_list_request->vdev_id = adapter->deflink->vdev_id;
6331 	mc_list_request->count = mc_count;
6332 
6333 	errno = hdd_cache_mc_addr_list(mc_list_request);
6334 	if (errno) {
6335 		hdd_debug("Failed to cache MC address list for vdev %u; errno:%d",
6336 			  adapter->deflink->vdev_id, errno);
6337 		goto free_req;
6338 	}
6339 
6340 	hdd_enable_mc_addr_filtering(adapter, pmo_mc_list_change_notify);
6341 
6342 free_req:
6343 	qdf_spin_unlock_bh(&adapter->mc_list_lock);
6344 	qdf_mem_free(mc_list_request);
6345 }
6346 
6347 /**
6348  * hdd_set_multicast_list() - SSR wrapper function for __hdd_set_multicast_list
6349  * @net_dev: pointer to net_device
6350  *
6351  * Return: none
6352  */
6353 static void hdd_set_multicast_list(struct net_device *net_dev)
6354 {
6355 	struct osif_vdev_sync *vdev_sync;
6356 
6357 	if (osif_vdev_sync_op_start(net_dev, &vdev_sync))
6358 		return;
6359 
6360 	__hdd_set_multicast_list(net_dev);
6361 
6362 	osif_vdev_sync_op_stop(vdev_sync);
6363 }
6364 
6365 void hdd_update_multicast_list(struct wlan_objmgr_vdev *vdev)
6366 {
6367 	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
6368 	struct wlan_hdd_link_info *link_info;
6369 	struct hdd_adapter *adapter;
6370 	uint8_t vdev_id = wlan_vdev_get_id(vdev);
6371 	struct net_device *net_dev;
6372 
6373 	if (!hdd_ctx) {
6374 		hdd_err("hdd_ctx is null");
6375 		return;
6376 	}
6377 
6378 	link_info = hdd_get_link_info_by_vdev(hdd_ctx, vdev_id);
6379 	if (!link_info) {
6380 		hdd_err("adapter is null for vdev_id %d", vdev_id);
6381 		return;
6382 	}
6383 
6384 	adapter = link_info->adapter;
6385 	if (!adapter) {
6386 		hdd_err("adapter is null for vdev_id %d", vdev_id);
6387 		return;
6388 	}
6389 
6390 	net_dev = adapter->dev;
6391 	if (!net_dev) {
6392 		hdd_err("netdev is null");
6393 		return;
6394 	}
6395 
6396 	__hdd_set_multicast_list(net_dev);
6397 }
6398 
6399 #ifdef WLAN_FEATURE_TSF_PTP
6400 static const struct ethtool_ops wlan_ethtool_ops = {
6401 	.get_ts_info = wlan_get_ts_info,
6402 };
6403 #endif
6404 
6405 /**
6406  * __hdd_fix_features - Adjust the feature flags needed to be updated
6407  * @net_dev: Handle to net_device
6408  * @features: Currently enabled feature flags
6409  *
6410  * Return: Adjusted feature flags on success, old feature on failure
6411  */
6412 static netdev_features_t __hdd_fix_features(struct net_device *net_dev,
6413 					    netdev_features_t features)
6414 {
6415 	netdev_features_t feature_change_req = features;
6416 	netdev_features_t feature_tso_csum;
6417 	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(net_dev);
6418 
6419 	if (!adapter->handle_feature_update) {
6420 		hdd_debug("Not triggered by hdd_netdev_update_features");
6421 		return features;
6422 	}
6423 
6424 	feature_tso_csum = hdd_get_tso_csum_feature_flags();
6425 	if (hdd_is_legacy_connection(adapter->deflink)) {
6426 		/* Disable checksum and TSO */
6427 		feature_change_req &= ~feature_tso_csum;
6428 		adapter->tso_csum_feature_enabled = 0;
6429 	} else {
6430 		/* Enable checksum and TSO */
6431 		feature_change_req |= feature_tso_csum;
6432 		adapter->tso_csum_feature_enabled = 1;
6433 	}
6434 	hdd_debug("vdev mode %d current features 0x%llx, requesting feature change 0x%llx",
6435 		  adapter->device_mode, net_dev->features,
6436 		  feature_change_req);
6437 
6438 	return feature_change_req;
6439 }
6440 
6441 /**
6442  * hdd_fix_features() - Wrapper for __hdd_fix_features to protect it from SSR
6443  * @net_dev: Pointer to net_device structure
6444  * @features: Updated features set
6445  *
6446  * Adjusts the feature request, do not update the device yet.
6447  *
6448  * Return: updated feature for success, incoming feature as is on failure
6449  */
6450 static netdev_features_t hdd_fix_features(struct net_device *net_dev,
6451 					  netdev_features_t features)
6452 {
6453 	int errno;
6454 	int changed_features = features;
6455 	struct osif_vdev_sync *vdev_sync;
6456 
6457 	errno = osif_vdev_sync_op_start(net_dev, &vdev_sync);
6458 	if (errno)
6459 		return features;
6460 
6461 	changed_features = __hdd_fix_features(net_dev, features);
6462 
6463 	osif_vdev_sync_op_stop(vdev_sync);
6464 
6465 	return changed_features;
6466 }
6467 /**
6468  * __hdd_set_features - Notify device about change in features
6469  * @net_dev: Handle to net_device
6470  * @features: Existing + requested feature after resolving the dependency
6471  *
6472  * Return: 0 on success, non zero error on failure
6473  */
6474 static int __hdd_set_features(struct net_device *net_dev,
6475 			      netdev_features_t features)
6476 {
6477 	struct hdd_adapter *adapter = netdev_priv(net_dev);
6478 	ol_txrx_soc_handle soc = cds_get_context(QDF_MODULE_ID_SOC);
6479 
6480 	if (!adapter->handle_feature_update) {
6481 		hdd_debug("Not triggered by hdd_netdev_update_features");
6482 		return 0;
6483 	}
6484 
6485 	if (!soc)
6486 		return 0;
6487 
6488 	hdd_debug("vdev mode %d vdev_id %d current features 0x%llx, changed features 0x%llx",
6489 		  adapter->device_mode, adapter->deflink->vdev_id,
6490 		  net_dev->features, features);
6491 
6492 	return 0;
6493 }
6494 
6495 /**
6496  * hdd_set_features() - Wrapper for __hdd_set_features to protect it from SSR
6497  * @net_dev: Pointer to net_device structure
6498  * @features: Updated features set
6499  *
6500  * Is called to update device configurations for changed features.
6501  *
6502  * Return: 0 for success, non-zero for failure
6503  */
6504 static int hdd_set_features(struct net_device *net_dev,
6505 			    netdev_features_t features)
6506 {
6507 	int errno;
6508 	struct osif_vdev_sync *vdev_sync;
6509 
6510 	errno = osif_vdev_sync_op_start(net_dev, &vdev_sync);
6511 	if (errno) {
6512 		/*
6513 		 * Only invoke from netdev_feature_update_work expected,
6514 		 * which is from CLD inside.
6515 		 * Ignore others from upper stack during loading phase,
6516 		 * and return success to avoid failure print from kernel.
6517 		 */
6518 		hdd_debug("VDEV in transition, ignore set_features");
6519 		return 0;
6520 	}
6521 
6522 	errno = __hdd_set_features(net_dev, features);
6523 
6524 	osif_vdev_sync_op_stop(vdev_sync);
6525 
6526 	return errno;
6527 }
6528 
6529 #define HDD_NETDEV_FEATURES_UPDATE_MAX_WAIT_COUNT	10
6530 #define HDD_NETDEV_FEATURES_UPDATE_WAIT_INTERVAL_MS	20
6531 
6532 void hdd_netdev_update_features(struct hdd_adapter *adapter)
6533 {
6534 	struct net_device *net_dev = adapter->dev;
6535 	ol_txrx_soc_handle soc = cds_get_context(QDF_MODULE_ID_SOC);
6536 	bool request_feature_update = false;
6537 	int wait_count = HDD_NETDEV_FEATURES_UPDATE_MAX_WAIT_COUNT;
6538 
6539 	if (!soc)
6540 		return;
6541 
6542 	if (!cdp_cfg_get(soc, cfg_dp_disable_legacy_mode_csum_offload))
6543 		return;
6544 
6545 	switch (adapter->device_mode) {
6546 	case QDF_STA_MODE:
6547 		if (cdp_cfg_get(soc, cfg_dp_enable_ip_tcp_udp_checksum_offload))
6548 			request_feature_update = true;
6549 		break;
6550 	default:
6551 		break;
6552 	}
6553 
6554 	if (request_feature_update) {
6555 		hdd_debug("Update net_dev features for device mode %d",
6556 			  adapter->device_mode);
6557 		while (!adapter->delete_in_progress) {
6558 			if (rtnl_trylock()) {
6559 				adapter->handle_feature_update = true;
6560 				netdev_update_features(net_dev);
6561 				adapter->handle_feature_update = false;
6562 				rtnl_unlock();
6563 				break;
6564 			}
6565 
6566 			if (wait_count--) {
6567 				qdf_sleep(
6568 				HDD_NETDEV_FEATURES_UPDATE_WAIT_INTERVAL_MS);
6569 			} else {
6570 				/*
6571 				 * We have failed to updated the netdev
6572 				 * features for very long, so enable the queues
6573 				 * now. The impact of not being able to update
6574 				 * the netdev feature is lower TPUT when
6575 				 * switching from legacy to non-legacy mode.
6576 				 */
6577 				hdd_err("Failed to update netdev features for device mode %d",
6578 					adapter->device_mode);
6579 				break;
6580 			}
6581 		}
6582 	}
6583 }
6584 
6585 static const struct net_device_ops wlan_drv_ops = {
6586 	.ndo_open = hdd_open,
6587 	.ndo_stop = hdd_stop,
6588 	.ndo_uninit = hdd_uninit,
6589 	.ndo_start_xmit = hdd_hard_start_xmit,
6590 	.ndo_fix_features = hdd_fix_features,
6591 	.ndo_set_features = hdd_set_features,
6592 	.ndo_tx_timeout = hdd_tx_timeout,
6593 	.ndo_get_stats = hdd_get_stats,
6594 #if LINUX_VERSION_CODE < KERNEL_VERSION(5, 15, 0)
6595 	.ndo_do_ioctl = hdd_ioctl,
6596 #endif
6597 	.ndo_set_mac_address = hdd_set_mac_address,
6598 	.ndo_select_queue = hdd_select_queue,
6599 	.ndo_set_rx_mode = hdd_set_multicast_list,
6600 #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0)
6601 	.ndo_siocdevprivate = hdd_dev_private_ioctl,
6602 #endif
6603 };
6604 
6605 #ifdef FEATURE_MONITOR_MODE_SUPPORT
6606 /* Monitor mode net_device_ops, does not Tx and most of operations. */
6607 static const struct net_device_ops wlan_mon_drv_ops = {
6608 	.ndo_open = hdd_mon_open,
6609 	.ndo_stop = hdd_stop,
6610 	.ndo_get_stats = hdd_get_stats,
6611 };
6612 
6613 /**
6614  * hdd_set_mon_ops() - update net_device ops for monitor mode
6615  * @dev: Handle to struct net_device to be updated.
6616  * Return: None
6617  */
6618 static void hdd_set_mon_ops(struct net_device *dev)
6619 {
6620 	dev->netdev_ops = &wlan_mon_drv_ops;
6621 }
6622 
6623 #ifdef WLAN_FEATURE_TSF_PTP
6624 void hdd_set_station_ops(struct net_device *dev)
6625 {
6626 	if (cds_get_conparam() == QDF_GLOBAL_MONITOR_MODE) {
6627 		hdd_set_mon_ops(dev);
6628 	} else {
6629 		dev->netdev_ops = &wlan_drv_ops;
6630 		dev->ethtool_ops = &wlan_ethtool_ops;
6631 	}
6632 }
6633 #else
6634 void hdd_set_station_ops(struct net_device *dev)
6635 {
6636 	if (cds_get_conparam() == QDF_GLOBAL_MONITOR_MODE)
6637 		hdd_set_mon_ops(dev);
6638 	else
6639 		dev->netdev_ops = &wlan_drv_ops;
6640 }
6641 
6642 #endif
6643 #else
6644 #ifdef WLAN_FEATURE_TSF_PTP
6645 void hdd_set_station_ops(struct net_device *dev)
6646 {
6647 	dev->netdev_ops = &wlan_drv_ops;
6648 	dev->ethtool_ops = &wlan_ethtool_ops;
6649 }
6650 #else
6651 void hdd_set_station_ops(struct net_device *dev)
6652 {
6653 	dev->netdev_ops = &wlan_drv_ops;
6654 }
6655 #endif
6656 static void hdd_set_mon_ops(struct net_device *dev)
6657 {
6658 }
6659 #endif
6660 
6661 #ifdef WLAN_FEATURE_PKT_CAPTURE
6662 /* Packet Capture mode net_device_ops, does not Tx and most of operations. */
6663 static const struct net_device_ops wlan_pktcapture_drv_ops = {
6664 	.ndo_open = hdd_pktcapture_open,
6665 	.ndo_stop = hdd_stop,
6666 	.ndo_get_stats = hdd_get_stats,
6667 };
6668 
6669 static void hdd_set_pktcapture_ops(struct net_device *dev)
6670 {
6671 	dev->netdev_ops = &wlan_pktcapture_drv_ops;
6672 }
6673 #else
6674 static void hdd_set_pktcapture_ops(struct net_device *dev)
6675 {
6676 }
6677 #endif
6678 
6679 #ifdef MULTI_CLIENT_LL_SUPPORT
6680 /**
6681  * hdd_set_multi_client_ll_support() - set multi client ll support flag in
6682  * allocated station hdd adapter
6683  * @adapter: pointer to hdd adapter
6684  *
6685  * Return: none
6686  */
6687 static void hdd_set_multi_client_ll_support(struct hdd_adapter *adapter)
6688 {
6689 	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
6690 	bool multi_client_ll_ini_support, multi_client_ll_caps;
6691 
6692 	ucfg_mlme_cfg_get_multi_client_ll_ini_support(hdd_ctx->psoc,
6693 						&multi_client_ll_ini_support);
6694 	multi_client_ll_caps =
6695 		ucfg_mlme_get_wlm_multi_client_ll_caps(hdd_ctx->psoc);
6696 
6697 	hdd_debug("fw caps: %d, ini: %d", multi_client_ll_caps,
6698 		  multi_client_ll_ini_support);
6699 	if (multi_client_ll_caps && multi_client_ll_ini_support)
6700 		adapter->multi_client_ll_support = true;
6701 }
6702 #else
6703 static inline void
6704 hdd_set_multi_client_ll_support(struct hdd_adapter *adapter)
6705 {
6706 }
6707 #endif
6708 
6709 /**
6710  * hdd_alloc_station_adapter() - allocate the station hdd adapter
6711  * @hdd_ctx: global hdd context
6712  * @mac_addr: mac address to assign to the interface
6713  * @name_assign_type: name assignment type
6714  * @name: User-visible name of the interface
6715  * @session_type: interface type to be created
6716  *
6717  * hdd adapter pointer would point to the netdev->priv space, this function
6718  * would retrieve the pointer, and setup the hdd adapter configuration.
6719  *
6720  * Return: the pointer to hdd adapter, otherwise NULL
6721  */
6722 static struct hdd_adapter *
6723 hdd_alloc_station_adapter(struct hdd_context *hdd_ctx, tSirMacAddr mac_addr,
6724 			  unsigned char name_assign_type, const char *name,
6725 			  uint8_t session_type)
6726 {
6727 	struct net_device *dev;
6728 	struct hdd_adapter *adapter;
6729 	QDF_STATUS qdf_status;
6730 	uint8_t latency_level;
6731 
6732 	/* cfg80211 initialization and registration */
6733 	dev = alloc_netdev_mqs(sizeof(*adapter), name,
6734 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
6735 			      name_assign_type,
6736 #endif
6737 			      ((cds_get_conparam() == QDF_GLOBAL_MONITOR_MODE ||
6738 			       wlan_hdd_is_session_type_monitor(session_type)) ?
6739 			       hdd_mon_mode_ether_setup : ether_setup),
6740 			      NUM_TX_QUEUES, NUM_RX_QUEUES);
6741 
6742 	if (!dev) {
6743 		hdd_err("Failed to allocate new net_device '%s'", name);
6744 		return NULL;
6745 	}
6746 
6747 	adapter = netdev_priv(dev);
6748 
6749 	qdf_mem_zero(adapter, sizeof(*adapter));
6750 	adapter->dev = dev;
6751 	adapter->deflink = &adapter->link_info[WLAN_HDD_DEFLINK_IDX];
6752 	adapter->hdd_ctx = hdd_ctx;
6753 	adapter->magic = WLAN_HDD_ADAPTER_MAGIC;
6754 	qdf_atomic_set_bit(WLAN_HDD_DEFLINK_IDX, &adapter->active_links);
6755 
6756 	qdf_status = hdd_monitor_mode_qdf_create_event(adapter, session_type);
6757 	if (QDF_IS_STATUS_ERROR(qdf_status)) {
6758 		hdd_err_rl("create monitor mode vdve up event failed");
6759 		goto free_net_dev;
6760 	}
6761 
6762 	hdd_update_dynamic_tsf_sync(adapter);
6763 	adapter->is_link_up_service_needed = false;
6764 	adapter->send_mode_change = true;
6765 
6766 	/* Cache station count initialize to zero */
6767 	qdf_atomic_init(&adapter->cache_sta_count);
6768 
6769 	/* Init the net_device structure */
6770 	strlcpy(dev->name, name, IFNAMSIZ);
6771 
6772 	qdf_net_update_net_device_dev_addr(dev, mac_addr, sizeof(tSirMacAddr));
6773 	qdf_mem_copy(adapter->mac_addr.bytes, mac_addr, sizeof(tSirMacAddr));
6774 	dev->watchdog_timeo = HDD_TX_TIMEOUT;
6775 
6776 	if (wlan_hdd_is_session_type_monitor(session_type)) {
6777 		if (ucfg_pkt_capture_get_mode(hdd_ctx->psoc) !=
6778 						PACKET_CAPTURE_MODE_DISABLE)
6779 			hdd_set_pktcapture_ops(adapter->dev);
6780 		if (ucfg_mlme_is_sta_mon_conc_supported(hdd_ctx->psoc) ||
6781 		    ucfg_dp_is_local_pkt_capture_enabled(hdd_ctx->psoc))
6782 			hdd_set_mon_ops(adapter->dev);
6783 	} else {
6784 		hdd_set_station_ops(adapter->dev);
6785 	}
6786 
6787 	hdd_dev_setup_destructor(dev);
6788 	dev->ieee80211_ptr = &adapter->wdev;
6789 	dev->tx_queue_len = HDD_NETDEV_TX_QUEUE_LEN;
6790 	adapter->wdev.wiphy = hdd_ctx->wiphy;
6791 	adapter->wdev.netdev = dev;
6792 	qdf_status = ucfg_mlme_cfg_get_wlm_level(hdd_ctx->psoc, &latency_level);
6793 	if (QDF_IS_STATUS_ERROR(qdf_status)) {
6794 		hdd_debug("Can't get latency level");
6795 		latency_level =
6796 			QCA_WLAN_VENDOR_ATTR_CONFIG_LATENCY_LEVEL_NORMAL;
6797 	}
6798 	adapter->latency_level = latency_level;
6799 	hdd_set_multi_client_ll_support(adapter);
6800 
6801 	/* set dev's parent to underlying device */
6802 	SET_NETDEV_DEV(dev, hdd_ctx->parent_dev);
6803 	spin_lock_init(&adapter->pause_map_lock);
6804 	adapter->start_time = qdf_system_ticks();
6805 	adapter->last_time = adapter->start_time;
6806 
6807 	qdf_atomic_init(&adapter->is_ll_stats_req_pending);
6808 	hdd_init_get_sta_in_ll_stats_config(adapter);
6809 
6810 	return adapter;
6811 
6812 free_net_dev:
6813 	free_netdev(adapter->dev);
6814 
6815 	return NULL;
6816 }
6817 
6818 #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 12, 0)
6819 static int
6820 hdd_register_netdevice(struct hdd_adapter *adapter, struct net_device *dev,
6821 		       struct hdd_adapter_create_param *params)
6822 {
6823 	int ret;
6824 
6825 	if (params->is_add_virtual_iface)
6826 		ret = wlan_cfg80211_register_netdevice(dev);
6827 	else
6828 		ret = register_netdevice(dev);
6829 
6830 	return ret;
6831 }
6832 #else
6833 static int
6834 hdd_register_netdevice(struct hdd_adapter *adapter, struct net_device *dev,
6835 		       struct hdd_adapter_create_param *params)
6836 {
6837 	return register_netdevice(dev);
6838 }
6839 #endif
6840 
6841 static QDF_STATUS
6842 hdd_register_interface(struct hdd_adapter *adapter, bool rtnl_held,
6843 		       struct hdd_adapter_create_param *params)
6844 {
6845 	struct net_device *dev = adapter->dev;
6846 	int ret;
6847 
6848 	hdd_enter();
6849 
6850 	if (rtnl_held) {
6851 		if (strnchr(dev->name, IFNAMSIZ - 1, '%')) {
6852 
6853 			ret = dev_alloc_name(dev, dev->name);
6854 			if (ret < 0) {
6855 				hdd_err(
6856 				    "unable to get dev name: %s, err = 0x%x",
6857 				    dev->name, ret);
6858 				return QDF_STATUS_E_FAILURE;
6859 			}
6860 		}
6861 		hdd_debug("hdd_register_netdevice(%s) type:%d", dev->name,
6862 			  adapter->device_mode);
6863 		ret = hdd_register_netdevice(adapter, dev, params);
6864 		if (ret) {
6865 			hdd_err("register_netdevice(%s) failed, err = 0x%x",
6866 				dev->name, ret);
6867 			return QDF_STATUS_E_FAILURE;
6868 		}
6869 	} else {
6870 		hdd_debug("register_netdev(%s) type:%d", dev->name,
6871 			  adapter->device_mode);
6872 		ret = register_netdev(dev);
6873 		if (ret) {
6874 			hdd_err("register_netdev(%s) failed, err = 0x%x",
6875 				dev->name, ret);
6876 			return QDF_STATUS_E_FAILURE;
6877 		}
6878 	}
6879 	set_bit(NET_DEVICE_REGISTERED, &adapter->event_flags);
6880 
6881 	hdd_exit();
6882 
6883 	return QDF_STATUS_SUCCESS;
6884 }
6885 
6886 QDF_STATUS hdd_sme_close_session_callback(uint8_t vdev_id)
6887 {
6888 	struct hdd_adapter *adapter;
6889 	struct hdd_context *hdd_ctx;
6890 	struct wlan_hdd_link_info *link_info;
6891 
6892 	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
6893 	if (!hdd_ctx)
6894 		return QDF_STATUS_E_FAILURE;
6895 
6896 	link_info = hdd_get_link_info_by_vdev(hdd_ctx, vdev_id);
6897 	if (!link_info) {
6898 		hdd_err("Invalid vdev %d", vdev_id);
6899 		return QDF_STATUS_E_INVAL;
6900 	}
6901 
6902 	adapter = link_info->adapter;
6903 	if (WLAN_HDD_ADAPTER_MAGIC != adapter->magic) {
6904 		hdd_err("Invalid magic");
6905 		return QDF_STATUS_NOT_INITIALIZED;
6906 	}
6907 
6908 	clear_bit(SME_SESSION_OPENED, &link_info->link_flags);
6909 	qdf_spin_lock_bh(&link_info->vdev_lock);
6910 	link_info->vdev_id = WLAN_UMAC_VDEV_ID_MAX;
6911 	qdf_spin_unlock_bh(&link_info->vdev_lock);
6912 
6913 	/*
6914 	 * We can be blocked while waiting for scheduled work to be
6915 	 * flushed, and the adapter structure can potentially be freed, in
6916 	 * which case the magic will have been reset.  So make sure the
6917 	 * magic is still good, and hence the adapter structure is still
6918 	 * valid, before signaling completion
6919 	 */
6920 	if (WLAN_HDD_ADAPTER_MAGIC == adapter->magic)
6921 		complete(&link_info->vdev_destroy_event);
6922 
6923 	return QDF_STATUS_SUCCESS;
6924 }
6925 
6926 int hdd_vdev_ready(struct wlan_objmgr_vdev *vdev,
6927 		   struct qdf_mac_addr *bridgeaddr)
6928 {
6929 	QDF_STATUS status;
6930 
6931 	status = pmo_vdev_ready(vdev, bridgeaddr);
6932 	if (QDF_IS_STATUS_ERROR(status))
6933 		return qdf_status_to_os_return(status);
6934 
6935 	status = ucfg_reg_11d_vdev_created_update(vdev);
6936 	if (QDF_IS_STATUS_ERROR(status))
6937 		return qdf_status_to_os_return(status);
6938 
6939 	if (wma_capability_enhanced_mcast_filter())
6940 		status = ucfg_pmo_enhanced_mc_filter_enable(vdev);
6941 	else
6942 		status = ucfg_pmo_enhanced_mc_filter_disable(vdev);
6943 
6944 	return qdf_status_to_os_return(status);
6945 }
6946 
6947 /**
6948  * hdd_check_wait_for_hw_mode_completion - Check hw mode in progress
6949  * @hdd_ctx: hdd context
6950  *
6951  * Check and wait for hw mode response if any hw mode change is
6952  * in progress. Vdev delete will purge the serialization queue
6953  * for the vdev. It will cause issues when the fw event coming
6954  * up later and no active hw mode change req ser command in queue.
6955  *
6956  * Return void
6957  */
6958 static void hdd_check_wait_for_hw_mode_completion(struct hdd_context *hdd_ctx)
6959 {
6960 	QDF_STATUS status;
6961 
6962 	if (!wlan_hdd_validate_context(hdd_ctx) &&
6963 	    policy_mgr_is_hw_mode_change_in_progress(
6964 		hdd_ctx->psoc)) {
6965 		status = policy_mgr_wait_for_connection_update(
6966 			hdd_ctx->psoc);
6967 		if (!QDF_IS_STATUS_SUCCESS(status)) {
6968 			hdd_nofl_debug("qdf wait for hw mode event failed!!");
6969 		}
6970 	}
6971 }
6972 
6973 static void hdd_stop_last_active_connection(struct hdd_context *hdd_ctx,
6974 					    struct wlan_objmgr_vdev *vdev)
6975 {
6976 	enum policy_mgr_con_mode mode;
6977 	struct wlan_objmgr_psoc *psoc;
6978 	enum QDF_OPMODE op_mode;
6979 
6980 	/* If this is the last active connection check
6981 	 * and stop the opportunistic timer.
6982 	 */
6983 	psoc = wlan_vdev_get_psoc(vdev);
6984 	op_mode = wlan_vdev_mlme_get_opmode(vdev);
6985 	mode = policy_mgr_qdf_opmode_to_pm_con_mode(psoc, op_mode,
6986 						    wlan_vdev_get_id(vdev));
6987 	if ((policy_mgr_get_connection_count(psoc) == 1 &&
6988 	     policy_mgr_mode_specific_connection_count(psoc,
6989 						       mode, NULL) == 1) ||
6990 	     (!policy_mgr_get_connection_count(psoc) &&
6991 	     !hdd_is_any_sta_connecting(hdd_ctx))) {
6992 		policy_mgr_check_and_stop_opportunistic_timer(
6993 						psoc,
6994 						wlan_vdev_get_id(vdev));
6995 	}
6996 }
6997 
6998 static int hdd_vdev_destroy_event_wait(struct hdd_context *hdd_ctx,
6999 				       struct wlan_objmgr_vdev *vdev)
7000 {
7001 	long rc;
7002 	QDF_STATUS status;
7003 	uint8_t vdev_id;
7004 	struct wlan_hdd_link_info *link_info;
7005 
7006 	vdev_id = wlan_vdev_get_id(vdev);
7007 	link_info = hdd_get_link_info_by_vdev(hdd_ctx, vdev_id);
7008 	if (!link_info) {
7009 		hdd_err("Invalid vdev");
7010 		return -EINVAL;
7011 	}
7012 
7013 	/* close sme session (destroy vdev in firmware via legacy API) */
7014 	INIT_COMPLETION(link_info->vdev_destroy_event);
7015 	status = sme_vdev_delete(hdd_ctx->mac_handle, vdev);
7016 	if (QDF_IS_STATUS_ERROR(status)) {
7017 		hdd_err("vdev %d: failed to delete with status:%d",
7018 			vdev_id, status);
7019 		return -EAGAIN;
7020 	}
7021 
7022 	/* block on a completion variable until sme session is closed */
7023 	rc = wait_for_completion_timeout(
7024 			&link_info->vdev_destroy_event,
7025 			msecs_to_jiffies(SME_CMD_VDEV_CREATE_DELETE_TIMEOUT));
7026 	if (!rc) {
7027 		hdd_err("vdev %d: timed out waiting for delete", vdev_id);
7028 		clear_bit(SME_SESSION_OPENED, &link_info->link_flags);
7029 		sme_cleanup_session(hdd_ctx->mac_handle, vdev_id);
7030 		cds_flush_logs(WLAN_LOG_TYPE_FATAL,
7031 			       WLAN_LOG_INDICATOR_HOST_DRIVER,
7032 			       WLAN_LOG_REASON_VDEV_DELETE_RSP_TIMED_OUT,
7033 			       true, true);
7034 		return -EINVAL;
7035 	}
7036 
7037 	hdd_nofl_info("vdev %d destroyed successfully", vdev_id);
7038 	return 0;
7039 }
7040 
7041 static inline
7042 void hdd_vdev_deinit_components(struct wlan_objmgr_vdev *vdev)
7043 {
7044 	ucfg_pmo_del_wow_pattern(vdev);
7045 	ucfg_son_disable_cbs(vdev);
7046 }
7047 
7048 static inline
7049 void hdd_reset_vdev_info(struct wlan_hdd_link_info *link_info)
7050 {
7051 	qdf_spin_lock_bh(&link_info->vdev_lock);
7052 	link_info->vdev = NULL;
7053 	qdf_spin_unlock_bh(&link_info->vdev_lock);
7054 }
7055 
7056 int hdd_vdev_destroy(struct wlan_hdd_link_info *link_info)
7057 {
7058 	int ret;
7059 	uint8_t vdev_id;
7060 	struct hdd_context *hdd_ctx;
7061 	struct wlan_objmgr_vdev *vdev;
7062 	struct wlan_objmgr_psoc *psoc;
7063 	enum QDF_OPMODE op_mode;
7064 
7065 	vdev_id = link_info->vdev_id;
7066 	hdd_nofl_debug("destroying vdev %d", vdev_id);
7067 	/* vdev created sanity check */
7068 	if (!test_bit(SME_SESSION_OPENED, &link_info->link_flags)) {
7069 		hdd_nofl_debug("vdev %u does not exist", vdev_id);
7070 		return -EINVAL;
7071 	}
7072 
7073 	hdd_ctx = WLAN_HDD_GET_CTX(link_info->adapter);
7074 
7075 	vdev = hdd_objmgr_get_vdev_by_user(link_info, WLAN_OSIF_ID);
7076 	if (!vdev)
7077 		return -EINVAL;
7078 
7079 	psoc = wlan_vdev_get_psoc(vdev);
7080 	if (!psoc) {
7081 		hdd_err("invalid psoc");
7082 		return -EINVAL;
7083 	}
7084 	op_mode = wlan_vdev_mlme_get_opmode(vdev);
7085 
7086 	hdd_stop_last_active_connection(hdd_ctx, vdev);
7087 	hdd_check_wait_for_hw_mode_completion(hdd_ctx);
7088 	ucfg_scan_vdev_set_disable(vdev, REASON_VDEV_DOWN);
7089 	wlan_hdd_scan_abort(link_info);
7090 	hdd_vdev_deinit_components(vdev);
7091 	hdd_mlo_t2lm_unregister_callback(vdev);
7092 	hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_ID);
7093 
7094 	hdd_reset_vdev_info(link_info);
7095 	osif_cm_osif_priv_deinit(vdev);
7096 
7097 	/* Release the hdd reference */
7098 	wlan_objmgr_vdev_release_ref(vdev, WLAN_HDD_ID_OBJ_MGR);
7099 
7100 	/* Get runtime lock to prevent runtime suspend */
7101 	qdf_runtime_pm_prevent_suspend(&hdd_ctx->runtime_context.vdev_destroy);
7102 
7103 	ret = hdd_vdev_destroy_event_wait(hdd_ctx, vdev);
7104 
7105 	ucfg_reg_11d_vdev_delete_update(psoc, op_mode, vdev_id);
7106 
7107 	qdf_runtime_pm_allow_suspend(&hdd_ctx->runtime_context.vdev_destroy);
7108 	return ret;
7109 }
7110 
7111 void
7112 hdd_store_nss_chains_cfg_in_vdev(struct hdd_context *hdd_ctx,
7113 				 struct wlan_objmgr_vdev *vdev)
7114 {
7115 	struct wlan_mlme_nss_chains vdev_ini_cfg;
7116 
7117 	/* Populate the nss chain params from ini for this vdev type */
7118 	sme_populate_nss_chain_params(hdd_ctx->mac_handle, &vdev_ini_cfg,
7119 				      wlan_vdev_mlme_get_opmode(vdev),
7120 				      hdd_ctx->num_rf_chains);
7121 
7122 	/* Store the nss chain config into the vdev */
7123 	sme_store_nss_chains_cfg_in_vdev(vdev, &vdev_ini_cfg);
7124 }
7125 
7126 bool hdd_is_vdev_in_conn_state(struct wlan_hdd_link_info *link_info)
7127 {
7128 	switch (link_info->adapter->device_mode) {
7129 	case QDF_STA_MODE:
7130 	case QDF_P2P_CLIENT_MODE:
7131 	case QDF_P2P_DEVICE_MODE:
7132 		return hdd_cm_is_vdev_associated(link_info);
7133 	case QDF_SAP_MODE:
7134 	case QDF_P2P_GO_MODE:
7135 		return (test_bit(SOFTAP_BSS_STARTED,
7136 				 &link_info->link_flags));
7137 	default:
7138 		hdd_err("Device mode %d invalid",
7139 			link_info->adapter->device_mode);
7140 		return 0;
7141 	}
7142 }
7143 
7144 #define MAX_VDEV_RTT_PARAMS 2
7145 /* params being sent:
7146  * wmi_vdev_param_enable_disable_rtt_responder_role
7147  * wmi_vdev_param_enable_disable_rtt_initiator_role
7148  */
7149 static QDF_STATUS
7150 hdd_vdev_configure_rtt_params(struct wlan_objmgr_vdev *vdev)
7151 {
7152 	QDF_STATUS status;
7153 	struct wlan_objmgr_psoc *psoc;
7154 	uint32_t fine_time_meas_cap = 0;
7155 	uint8_t vdev_id = wlan_vdev_get_id(vdev);
7156 	struct dev_set_param vdevsetparam[MAX_VDEV_RTT_PARAMS] = {};
7157 	uint8_t index = 0;
7158 	WMI_FW_SUB_FEAT_CAPS wmi_fw_rtt_respr, wmi_fw_rtt_initr;
7159 
7160 	switch (wlan_vdev_mlme_get_opmode(vdev)) {
7161 	case QDF_STA_MODE:
7162 		wmi_fw_rtt_respr = WMI_FW_STA_RTT_RESPR;
7163 		wmi_fw_rtt_initr = WMI_FW_STA_RTT_INITR;
7164 		break;
7165 	case QDF_SAP_MODE:
7166 		wmi_fw_rtt_respr = WMI_FW_AP_RTT_RESPR;
7167 		wmi_fw_rtt_initr = WMI_FW_AP_RTT_INITR;
7168 		break;
7169 	default:
7170 		return QDF_STATUS_SUCCESS;
7171 	}
7172 
7173 	psoc = wlan_vdev_get_psoc(vdev);
7174 
7175 	ucfg_mlme_get_fine_time_meas_cap(psoc, &fine_time_meas_cap);
7176 	status = mlme_check_index_setparam(
7177 			vdevsetparam,
7178 			wmi_vdev_param_enable_disable_rtt_responder_role,
7179 			(fine_time_meas_cap & wmi_fw_rtt_respr), index++,
7180 			MAX_VDEV_RTT_PARAMS);
7181 	if (QDF_IS_STATUS_ERROR(status))
7182 		return status;
7183 
7184 	status = mlme_check_index_setparam(
7185 			vdevsetparam,
7186 			wmi_vdev_param_enable_disable_rtt_initiator_role,
7187 			(fine_time_meas_cap & wmi_fw_rtt_initr), index++,
7188 			MAX_VDEV_RTT_PARAMS);
7189 	if (QDF_IS_STATUS_ERROR(status))
7190 		return status;
7191 
7192 	status = sme_send_multi_pdev_vdev_set_params(MLME_VDEV_SETPARAM,
7193 						     vdev_id, vdevsetparam,
7194 						     index);
7195 	if (QDF_IS_STATUS_ERROR(status))
7196 		hdd_err("failed to set RTT_RESPONDER,INITIATOR params:%d",
7197 			status);
7198 
7199 	return status;
7200 }
7201 
7202 static void hdd_store_vdev_info(struct wlan_hdd_link_info *link_info,
7203 				struct wlan_objmgr_vdev *vdev)
7204 {
7205 	struct vdev_osif_priv *osif_priv;
7206 
7207 	osif_priv = wlan_vdev_get_ospriv(vdev);
7208 	if (osif_priv) {
7209 		osif_priv->wdev = link_info->adapter->dev->ieee80211_ptr;
7210 		osif_priv->legacy_osif_priv = link_info;
7211 	}
7212 
7213 	qdf_spin_lock_bh(&link_info->vdev_lock);
7214 	link_info->vdev_id = wlan_vdev_get_id(vdev);
7215 	link_info->vdev = vdev;
7216 	qdf_spin_unlock_bh(&link_info->vdev_lock);
7217 }
7218 
7219 static void
7220 hdd_init_station_context(struct wlan_hdd_link_info *link_info)
7221 {
7222 	struct hdd_station_ctx *sta_ctx;
7223 	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(link_info->adapter);
7224 
7225 	/* Set the default operation channel freq and auth type to open */
7226 	sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(link_info);
7227 	sta_ctx->conn_info.chan_freq = hdd_ctx->config->operating_chan_freq;
7228 	sta_ctx->conn_info.auth_type = eCSR_AUTH_TYPE_OPEN_SYSTEM;
7229 	hdd_roam_profile_init(link_info);
7230 }
7231 
7232 static void hdd_vdev_set_ht_vht_ies(mac_handle_t mac_handle,
7233 				    struct wlan_objmgr_vdev *vdev)
7234 {
7235 	QDF_STATUS status;
7236 	struct wlan_objmgr_psoc *psoc;
7237 	bool bval = false;
7238 
7239 	psoc = wlan_vdev_get_psoc(vdev);
7240 	status = ucfg_mlme_get_vht_enable2x2(psoc, &bval);
7241 	if (QDF_IS_STATUS_ERROR(status))
7242 		hdd_err("unable to get vht_enable2x2");
7243 
7244 	sme_set_pdev_ht_vht_ies(mac_handle, bval);
7245 	sme_set_vdev_ies_per_band(mac_handle, wlan_vdev_get_id(vdev),
7246 				  wlan_vdev_mlme_get_opmode(vdev));
7247 }
7248 
7249 static void
7250 hdd_vdev_configure_rtt_mac_randomization(struct wlan_objmgr_psoc *psoc,
7251 					 struct wlan_objmgr_vdev *vdev)
7252 {
7253 	int errno;
7254 	QDF_STATUS status;
7255 	bool bval = false;
7256 
7257 	status = ucfg_mlme_get_rtt_mac_randomization(psoc, &bval);
7258 	if (QDF_IS_STATUS_ERROR(status))
7259 		hdd_err("unable to get RTT MAC randomization value");
7260 
7261 	hdd_debug("setting RTT mac randomization param: %d", bval);
7262 	errno = sme_cli_set_command(
7263 			wlan_vdev_get_id(vdev),
7264 			wmi_vdev_param_enable_disable_rtt_initiator_random_mac,
7265 			bval, VDEV_CMD);
7266 
7267 	if (errno)
7268 		hdd_err("RTT mac randomization param set failed %d", errno);
7269 }
7270 
7271 static void
7272 hdd_vdev_configure_max_tdls_params(struct wlan_objmgr_psoc *psoc,
7273 				   struct wlan_objmgr_vdev *vdev)
7274 {
7275 	uint16_t max_peer_count;
7276 	bool target_bigtk_support = false;
7277 
7278 	/* Max peer can be tdls peers + self peer + bss peer */
7279 	max_peer_count = cfg_tdls_get_max_peer_count(psoc);
7280 	max_peer_count += 2;
7281 	wlan_vdev_set_max_peer_count(vdev, max_peer_count);
7282 
7283 	ucfg_mlme_get_bigtk_support(psoc, &target_bigtk_support);
7284 	if (target_bigtk_support)
7285 		mlme_set_bigtk_support(vdev, true);
7286 }
7287 
7288 static inline void
7289 hdd_vdev_configure_nan_params(struct wlan_objmgr_psoc *psoc,
7290 			      struct wlan_objmgr_vdev *vdev)
7291 {
7292 	sme_cli_set_command(
7293 		wlan_vdev_get_id(vdev),
7294 		wmi_vdev_param_allow_nan_initial_discovery_of_mp0_cluster,
7295 		cfg_nan_get_support_mp0_discovery(psoc), VDEV_CMD);
7296 }
7297 
7298 #if defined(WLAN_FEATURE_11BE_MLO) && defined(WLAN_EXTERNAL_AUTH_MLO_SUPPORT)
7299 static void
7300 hdd_set_vdev_mlo_external_sae_auth_conversion(struct wlan_objmgr_vdev *vdev,
7301 					      enum QDF_OPMODE mode)
7302 {
7303 	if (mode == QDF_STA_MODE || mode == QDF_SAP_MODE)
7304 		wlan_vdev_set_mlo_external_sae_auth_conversion(vdev, true);
7305 }
7306 #else
7307 static inline void
7308 hdd_set_vdev_mlo_external_sae_auth_conversion(struct wlan_objmgr_vdev *vdev,
7309 					      enum QDF_OPMODE mode)
7310 {
7311 }
7312 #endif
7313 
7314 static void
7315 hdd_vdev_configure_opmode_params(struct hdd_context *hdd_ctx,
7316 				 struct wlan_objmgr_vdev *vdev)
7317 {
7318 	struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc;
7319 	enum QDF_OPMODE opmode = wlan_vdev_mlme_get_opmode(vdev);
7320 
7321 	switch (opmode) {
7322 	case QDF_STA_MODE:
7323 		hdd_vdev_configure_rtt_mac_randomization(psoc, vdev);
7324 		hdd_vdev_configure_max_tdls_params(psoc, vdev);
7325 		break;
7326 	case QDF_P2P_CLIENT_MODE:
7327 		hdd_vdev_configure_max_tdls_params(psoc, vdev);
7328 		break;
7329 	case QDF_NAN_DISC_MODE:
7330 		hdd_vdev_configure_nan_params(psoc, vdev);
7331 		break;
7332 	default:
7333 		break;
7334 	}
7335 
7336 	ucfg_fwol_configure_vdev_params(psoc, vdev);
7337 	hdd_set_vdev_mlo_external_sae_auth_conversion(vdev, opmode);
7338 	hdd_store_nss_chains_cfg_in_vdev(hdd_ctx, vdev);
7339 }
7340 
7341 #if defined(WLAN_FEATURE_11BE_MLO) && defined(CFG80211_11BE_BASIC) && \
7342 	defined(WLAN_HDD_MULTI_VDEV_SINGLE_NDEV)
7343 static int
7344 hdd_populate_vdev_create_params(struct wlan_hdd_link_info *link_info,
7345 				struct wlan_vdev_create_params *vdev_params)
7346 {
7347 	struct hdd_adapter *adapter = link_info->adapter;
7348 
7349 	vdev_params->opmode = adapter->device_mode;
7350 	vdev_params->size_vdev_priv = sizeof(struct vdev_osif_priv);
7351 
7352 	if (hdd_adapter_is_ml_adapter(adapter)) {
7353 		qdf_ether_addr_copy(vdev_params->mldaddr,
7354 				    adapter->mac_addr.bytes);
7355 		qdf_ether_addr_copy(vdev_params->macaddr,
7356 				    link_info->link_addr.bytes);
7357 	} else {
7358 		qdf_ether_addr_copy(vdev_params->macaddr,
7359 				    adapter->mac_addr.bytes);
7360 	}
7361 	return 0;
7362 }
7363 #elif defined(WLAN_FEATURE_11BE_MLO) && defined(CFG80211_11BE_BASIC)
7364 static int
7365 hdd_populate_vdev_create_params(struct wlan_hdd_link_info *link_info,
7366 				struct wlan_vdev_create_params *vdev_params)
7367 {
7368 	struct hdd_adapter *adapter = link_info->adapter;
7369 	struct hdd_mlo_adapter_info *mlo_adapter_info;
7370 	struct hdd_adapter *link_adapter;
7371 	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
7372 	bool eht_capab;
7373 
7374 	hdd_enter_dev(adapter->dev);
7375 	mlo_adapter_info = &adapter->mlo_adapter_info;
7376 
7377 	ucfg_psoc_mlme_get_11be_capab(hdd_ctx->psoc, &eht_capab);
7378 	if (mlo_adapter_info->is_ml_adapter && eht_capab &&
7379 	    adapter->device_mode == QDF_STA_MODE) {
7380 		link_adapter = hdd_get_assoc_link_adapter(adapter);
7381 		if (link_adapter) {
7382 			qdf_ether_addr_copy(vdev_params->macaddr,
7383 					    link_adapter->mac_addr.bytes);
7384 		} else {
7385 			return -EINVAL;
7386 		}
7387 	} else {
7388 		qdf_ether_addr_copy(vdev_params->macaddr,
7389 				    adapter->mac_addr.bytes);
7390 	}
7391 
7392 	vdev_params->opmode = adapter->device_mode;
7393 
7394 	if (eht_capab) {
7395 		qdf_ether_addr_copy(vdev_params->mldaddr,
7396 				    adapter->mld_addr.bytes);
7397 	}
7398 
7399 	vdev_params->size_vdev_priv = sizeof(struct vdev_osif_priv);
7400 	hdd_exit();
7401 
7402 	return 0;
7403 }
7404 #else
7405 static int
7406 hdd_populate_vdev_create_params(struct wlan_hdd_link_info *link_info,
7407 				struct wlan_vdev_create_params *vdev_params)
7408 {
7409 	struct hdd_adapter *adapter = link_info->adapter;
7410 
7411 	vdev_params->opmode = adapter->device_mode;
7412 	qdf_ether_addr_copy(vdev_params->macaddr, adapter->mac_addr.bytes);
7413 	vdev_params->size_vdev_priv = sizeof(struct vdev_osif_priv);
7414 	return 0;
7415 }
7416 #endif
7417 
7418 int hdd_vdev_create(struct wlan_hdd_link_info *link_info)
7419 {
7420 	QDF_STATUS status;
7421 	int errno = 0;
7422 	struct hdd_adapter *adapter = link_info->adapter;
7423 	struct hdd_context *hdd_ctx;
7424 	struct wlan_objmgr_vdev *vdev;
7425 	struct wlan_vdev_create_params vdev_params = {0};
7426 
7427 	hdd_nofl_debug("creating new vdev");
7428 
7429 	/* do vdev create via objmgr */
7430 	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
7431 
7432 	errno = hdd_populate_vdev_create_params(link_info, &vdev_params);
7433 	if (errno)
7434 		return errno;
7435 
7436 	vdev = sme_vdev_create(hdd_ctx->mac_handle, &vdev_params);
7437 	if (!vdev) {
7438 		hdd_err("failed to create vdev");
7439 		return -EINVAL;
7440 	}
7441 
7442 	if (wlan_objmgr_vdev_try_get_ref(vdev, WLAN_HDD_ID_OBJ_MGR) !=
7443 	    QDF_STATUS_SUCCESS) {
7444 		errno = QDF_STATUS_E_INVAL;
7445 		sme_vdev_delete(hdd_ctx->mac_handle, vdev);
7446 		return -EINVAL;
7447 	}
7448 
7449 	hdd_store_vdev_info(link_info, vdev);
7450 	osif_cm_osif_priv_init(vdev);
7451 
7452 	if (hdd_adapter_is_ml_adapter(adapter))
7453 		hdd_mlo_t2lm_register_callback(vdev);
7454 
7455 	set_bit(SME_SESSION_OPENED, &link_info->link_flags);
7456 	status = sme_vdev_post_vdev_create_setup(hdd_ctx->mac_handle, vdev);
7457 	if (QDF_IS_STATUS_ERROR(status)) {
7458 		hdd_err("Failed to setup the vdev");
7459 		errno = qdf_status_to_os_return(status);
7460 		goto hdd_vdev_destroy_procedure;
7461 	}
7462 
7463 	/* firmware ready for component communication, raise vdev_ready event */
7464 	errno = hdd_vdev_ready(vdev,
7465 			       (struct qdf_mac_addr *)hdd_ctx->bridgeaddr);
7466 	if (errno) {
7467 		hdd_err("failed to dispatch vdev ready event: %d", errno);
7468 		goto hdd_vdev_destroy_procedure;
7469 	}
7470 
7471 	hdd_vdev_configure_opmode_params(hdd_ctx, vdev);
7472 
7473 	hdd_nofl_debug("vdev %d created successfully", link_info->vdev_id);
7474 
7475 	return errno;
7476 
7477 hdd_vdev_destroy_procedure:
7478 	QDF_BUG(!hdd_vdev_destroy(link_info));
7479 
7480 	return errno;
7481 }
7482 
7483 QDF_STATUS hdd_init_station_mode(struct wlan_hdd_link_info *link_info)
7484 {
7485 	struct hdd_adapter *adapter = link_info->adapter;
7486 	struct hdd_context *hdd_ctx;
7487 	QDF_STATUS status;
7488 	mac_handle_t mac_handle;
7489 	uint32_t roam_triggers;
7490 	struct wlan_objmgr_vdev *vdev;
7491 
7492 	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
7493 	mac_handle = hdd_ctx->mac_handle;
7494 
7495 	vdev = hdd_objmgr_get_vdev_by_user(link_info, WLAN_INIT_DEINIT_ID);
7496 	if (!vdev) {
7497 		status = QDF_STATUS_E_NULL_VALUE;
7498 		goto vdev_destroy;
7499 	}
7500 
7501 	hdd_vdev_set_ht_vht_ies(mac_handle, vdev);
7502 	hdd_init_station_context(link_info);
7503 
7504 	status = hdd_wmm_adapter_init(adapter);
7505 	if (QDF_STATUS_SUCCESS != status) {
7506 		hdd_err("hdd_wmm_adapter_init() failed, status code %08d [x%08x]",
7507 			status, status);
7508 		goto error_wmm_init;
7509 	}
7510 	set_bit(WMM_INIT_DONE, &adapter->event_flags);
7511 
7512 	/* rcpi info initialization */
7513 	qdf_mem_zero(&adapter->rcpi, sizeof(adapter->rcpi));
7514 
7515 	if (adapter->device_mode == QDF_STA_MODE) {
7516 		roam_triggers = ucfg_mlme_get_roaming_triggers(hdd_ctx->psoc);
7517 		mlme_set_roam_trigger_bitmap(hdd_ctx->psoc,
7518 					     link_info->vdev_id,
7519 					     roam_triggers);
7520 
7521 		status = hdd_vdev_configure_rtt_params(vdev);
7522 		if (QDF_IS_STATUS_ERROR(status))
7523 			goto error_wmm_init;
7524 	}
7525 
7526 	hdd_objmgr_put_vdev_by_user(vdev, WLAN_INIT_DEINIT_ID);
7527 	return QDF_STATUS_SUCCESS;
7528 
7529 error_wmm_init:
7530 	hdd_objmgr_put_vdev_by_user(vdev, WLAN_INIT_DEINIT_ID);
7531 
7532 vdev_destroy:
7533 	QDF_BUG(!hdd_vdev_destroy(link_info));
7534 
7535 	return status;
7536 }
7537 
7538 static char *net_dev_ref_debug_string_from_id(wlan_net_dev_ref_dbgid dbgid)
7539 {
7540 	static const char *strings[] = {
7541 		"NET_DEV_HOLD_ID_RESERVED",
7542 		"NET_DEV_HOLD_GET_STA_CONNECTION_IN_PROGRESS",
7543 		"NET_DEV_HOLD_CHECK_DFS_CHANNEL_FOR_ADAPTER",
7544 		"NET_DEV_HOLD_GET_SAP_OPERATING_BAND",
7545 		"NET_DEV_HOLD_RECOVERY_NOTIFIER_CALL",
7546 		"NET_DEV_HOLD_IS_ANY_STA_CONNECTING",
7547 		"NET_DEV_HOLD_SAP_DESTROY_CTX_ALL",
7548 		"NET_DEV_HOLD_DRV_CMD_MAX_TX_POWER",
7549 		"NET_DEV_HOLD_IPA_SET_TX_FLOW_INFO",
7550 		"NET_DEV_HOLD_SET_RPS_CPU_MASK",
7551 		"NET_DEV_HOLD_DFS_INDICATE_RADAR",
7552 		"NET_DEV_HOLD_MAX_STA_INTERFACE_UP_COUNT_REACHED",
7553 		"NET_DEV_HOLD_IS_CHAN_SWITCH_IN_PROGRESS",
7554 		"NET_DEV_HOLD_STA_DESTROY_CTX_ALL",
7555 		"NET_DEV_HOLD_CHECK_FOR_EXISTING_MACADDR",
7556 		"NET_DEV_HOLD_DEINIT_ALL_ADAPTERS",
7557 		"NET_DEV_HOLD_STOP_ALL_ADAPTERS",
7558 		"NET_DEV_HOLD_RESET_ALL_ADAPTERS",
7559 		"NET_DEV_HOLD_IS_ANY_INTERFACE_OPEN",
7560 		"NET_DEV_HOLD_START_ALL_ADAPTERS",
7561 		"NET_DEV_HOLD_GET_ADAPTER_BY_RAND_MACADDR",
7562 		"NET_DEV_HOLD_GET_ADAPTER_BY_MACADDR",
7563 		"NET_DEV_HOLD_GET_ADAPTER_BY_VDEV",
7564 		"NET_DEV_HOLD_ADAPTER_GET_BY_REFERENCE",
7565 		"NET_DEV_HOLD_GET_ADAPTER_BY_IFACE_NAME",
7566 		"NET_DEV_HOLD_GET_ADAPTER",
7567 		"NET_DEV_HOLD_GET_OPERATING_CHAN_FREQ",
7568 		"NET_DEV_HOLD_UNREGISTER_WEXT_ALL_ADAPTERS",
7569 		"NET_DEV_HOLD_ABORT_MAC_SCAN_ALL_ADAPTERS",
7570 		"NET_DEV_HOLD_ABORT_SCHED_SCAN_ALL_ADAPTERS",
7571 		"NET_DEV_HOLD_GET_FIRST_VALID_ADAPTER",
7572 		"NET_DEV_HOLD_CLEAR_RPS_CPU_MASK",
7573 		"NET_DEV_HOLD_BUS_BW_WORK_HANDLER",
7574 		"NET_DEV_HOLD_DISPLAY_NETIF_QUEUE_HISTORY_COMPACT",
7575 		"NET_DEV_HOLD_DISPLAY_NETIF_QUEUE_HISTORY",
7576 		"NET_DEV_HOLD_CLEAR_NETIF_QUEUE_HISTORY",
7577 		"NET_DEV_HOLD_UNSAFE_CHANNEL_RESTART_SAP",
7578 		"NET_DEV_HOLD_INDICATE_MGMT_FRAME",
7579 		"NET_DEV_HOLD_STATE_INFO_DUMP",
7580 		"NET_DEV_HOLD_DISABLE_ROAMING",
7581 		"NET_DEV_HOLD_ENABLE_ROAMING",
7582 		"NET_DEV_HOLD_AUTO_SHUTDOWN_ENABLE",
7583 		"NET_DEV_HOLD_GET_CON_SAP_ADAPTER",
7584 		"NET_DEV_HOLD_IS_ANY_ADAPTER_CONNECTED",
7585 		"NET_DEV_HOLD_IS_ROAMING_IN_PROGRESS",
7586 		"NET_DEV_HOLD_DEL_P2P_INTERFACE",
7587 		"NET_DEV_HOLD_IS_NDP_ALLOWED",
7588 		"NET_DEV_HOLD_NDI_OPEN",
7589 		"NET_DEV_HOLD_SEND_OEM_REG_RSP_NLINK_MSG",
7590 		"NET_DEV_HOLD_PERIODIC_STA_STATS_DISPLAY",
7591 		"NET_DEV_HOLD_SUSPEND_WLAN",
7592 		"NET_DEV_HOLD_RESUME_WLAN",
7593 		"NET_DEV_HOLD_SSR_RESTART_SAP",
7594 		"NET_DEV_HOLD_SEND_DEFAULT_SCAN_IES",
7595 		"NET_DEV_HOLD_CFG80211_SUSPEND_WLAN",
7596 		"NET_DEV_HOLD_COUNTRY_CHANGE_UPDATE_STA",
7597 		"NET_DEV_HOLD_COUNTRY_CHANGE_UPDATE_SAP",
7598 		"NET_DEV_HOLD_CACHE_STATION_STATS_CB",
7599 		"NET_DEV_HOLD_DISPLAY_TXRX_STATS",
7600 		"NET_DEV_HOLD_START_PRE_CAC_TRANS",
7601 		"NET_DEV_HOLD_IS_ANY_STA_CONNECTED",
7602 		"NET_DEV_HOLD_GET_ADAPTER_BY_BSSID",
7603 		"NET_DEV_HOLD_ID_MAX"};
7604 	int32_t num_dbg_strings = QDF_ARRAY_SIZE(strings);
7605 
7606 	if (dbgid >= num_dbg_strings) {
7607 		char *ret = "";
7608 
7609 		hdd_err("Debug string not found for debug id %d", dbgid);
7610 		return ret;
7611 	}
7612 
7613 	return (char *)strings[dbgid];
7614 }
7615 
7616 void hdd_check_for_net_dev_ref_leak(struct hdd_adapter *adapter)
7617 {
7618 	int i, id;
7619 
7620 	for (id = 0; id < NET_DEV_HOLD_ID_MAX; id++) {
7621 		for (i = 0; i < MAX_NET_DEV_REF_LEAK_ITERATIONS; i++) {
7622 			if (!qdf_atomic_read(
7623 				&adapter->net_dev_hold_ref_count[id]))
7624 				break;
7625 			hdd_info("net_dev held for debug id %s",
7626 				 net_dev_ref_debug_string_from_id(id));
7627 			qdf_sleep(NET_DEV_REF_LEAK_ITERATION_SLEEP_TIME_MS);
7628 		}
7629 		if (i == MAX_NET_DEV_REF_LEAK_ITERATIONS) {
7630 			hdd_err("net_dev hold reference leak detected for debug id: %s",
7631 				net_dev_ref_debug_string_from_id(id));
7632 			QDF_BUG(0);
7633 		}
7634 	}
7635 }
7636 
7637 /**
7638  * hdd_deinit_station_mode() - De-initialize the station adapter
7639  * @adapter: HDD adapter pointer
7640  *
7641  * This function De-initializes the STA/P2P/OCB adapter.
7642  *
7643  * Return: None.
7644  */
7645 static void hdd_deinit_station_mode(struct hdd_adapter *adapter)
7646 {
7647 	if (test_bit(WMM_INIT_DONE, &adapter->event_flags)) {
7648 		hdd_wmm_adapter_close(adapter);
7649 		clear_bit(WMM_INIT_DONE, &adapter->event_flags);
7650 	}
7651 }
7652 
7653 void hdd_deinit_session(struct hdd_adapter *adapter)
7654 {
7655 	struct wlan_hdd_link_info *link_info;
7656 
7657 	hdd_enter();
7658 
7659 	switch (adapter->device_mode) {
7660 	case QDF_STA_MODE:
7661 	case QDF_P2P_CLIENT_MODE:
7662 	case QDF_MONITOR_MODE:
7663 	case QDF_P2P_DEVICE_MODE:
7664 	case QDF_NDI_MODE:
7665 	case QDF_NAN_DISC_MODE:
7666 	{
7667 		hdd_deinit_station_mode(adapter);
7668 		break;
7669 	}
7670 
7671 	case QDF_SAP_MODE:
7672 	case QDF_P2P_GO_MODE:
7673 	{
7674 		hdd_adapter_for_each_active_link_info(adapter, link_info)
7675 			hdd_deinit_ap_mode(link_info);
7676 		break;
7677 	}
7678 
7679 	default:
7680 		break;
7681 	}
7682 
7683 	if (adapter->scan_info.default_scan_ies) {
7684 		qdf_mem_free(adapter->scan_info.default_scan_ies);
7685 		adapter->scan_info.default_scan_ies = NULL;
7686 		adapter->scan_info.default_scan_ies_len = 0;
7687 	}
7688 
7689 	hdd_exit();
7690 }
7691 
7692 void hdd_deinit_adapter(struct hdd_context *hdd_ctx,
7693 			struct hdd_adapter *adapter,
7694 			bool rtnl_held)
7695 {
7696 	hdd_enter_dev(adapter->dev);
7697 
7698 	hdd_wext_unregister(adapter->dev, rtnl_held);
7699 	hdd_deinit_session(adapter);
7700 	hdd_exit();
7701 }
7702 
7703 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0)) && \
7704      defined(WLAN_FEATURE_11AX)
7705 /**
7706  * hdd_cleanup_he_operation_info() - cleanup he operation info
7707  * @link_info: pointer to link_info struct in adapter
7708  *
7709  * This function destroys he operation information
7710  *
7711  * Return: none
7712  */
7713 static void hdd_cleanup_he_operation_info(struct wlan_hdd_link_info *link_info)
7714 {
7715 	struct hdd_station_ctx *hdd_sta_ctx;
7716 
7717 	hdd_debug("cleanup he operation info");
7718 
7719 	hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(link_info);
7720 
7721 	if (hdd_sta_ctx->cache_conn_info.he_operation) {
7722 		qdf_mem_free(hdd_sta_ctx->cache_conn_info.he_operation);
7723 		hdd_sta_ctx->cache_conn_info.he_operation = NULL;
7724 	}
7725 }
7726 #else
7727 static inline void
7728 hdd_cleanup_he_operation_info(struct wlan_hdd_link_info *link_info)
7729 {
7730 }
7731 #endif
7732 
7733 /**
7734  * hdd_cleanup_prev_ap_bcn_ie() - cleanup previous ap beacon ie
7735  * @link_info: pointer to link_info struct in adapter
7736  *
7737  * This function destroys previous ap beacon information
7738  *
7739  * Return: none
7740  */
7741 static void hdd_cleanup_prev_ap_bcn_ie(struct wlan_hdd_link_info *link_info)
7742 {
7743 	struct hdd_station_ctx *hdd_sta_ctx;
7744 	struct element_info *bcn_ie;
7745 
7746 	hdd_debug("cleanup previous ap bcn ie");
7747 
7748 	hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(link_info);
7749 	bcn_ie = &hdd_sta_ctx->conn_info.prev_ap_bcn_ie;
7750 
7751 	if (bcn_ie->ptr) {
7752 		qdf_mem_free(bcn_ie->ptr);
7753 		bcn_ie->ptr = NULL;
7754 		bcn_ie->len = 0;
7755 	}
7756 }
7757 
7758 void hdd_cleanup_conn_info(struct wlan_hdd_link_info *link_info)
7759 {
7760 	hdd_cleanup_he_operation_info(link_info);
7761 	hdd_cleanup_prev_ap_bcn_ie(link_info);
7762 }
7763 
7764 /**
7765  * hdd_sta_destroy_ctx_all() - cleanup all station contexts
7766  * @hdd_ctx: Global HDD context
7767  *
7768  * This function destroys all the station contexts
7769  *
7770  * Return: none
7771  */
7772 static void hdd_sta_destroy_ctx_all(struct hdd_context *hdd_ctx)
7773 {
7774 	struct hdd_adapter *adapter, *next_adapter = NULL;
7775 	struct wlan_hdd_link_info *link_info;
7776 
7777 	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
7778 					   NET_DEV_HOLD_STA_DESTROY_CTX_ALL) {
7779 		if (adapter->device_mode == QDF_STA_MODE) {
7780 			hdd_adapter_for_each_link_info(adapter, link_info) {
7781 				hdd_cleanup_conn_info(link_info);
7782 			}
7783 		}
7784 		hdd_adapter_dev_put_debug(adapter,
7785 					  NET_DEV_HOLD_STA_DESTROY_CTX_ALL);
7786 	}
7787 }
7788 
7789 #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 12, 0)
7790 static void
7791 hdd_unregister_netdevice(struct hdd_adapter *adapter, struct net_device *dev)
7792 {
7793 	if (adapter->is_virtual_iface) {
7794 		wlan_cfg80211_unregister_netdevice(dev);
7795 		adapter->is_virtual_iface = false;
7796 	} else {
7797 		unregister_netdevice(dev);
7798 	}
7799 }
7800 #else
7801 static void
7802 hdd_unregister_netdevice(struct hdd_adapter *adapter, struct net_device *dev)
7803 {
7804 	unregister_netdevice(dev);
7805 }
7806 #endif
7807 
7808 static inline void hdd_adapter_destroy_vdev_info(struct hdd_adapter *adapter)
7809 {
7810 	struct wlan_hdd_link_info *link_info;
7811 
7812 	hdd_adapter_for_each_link_info(adapter, link_info) {
7813 		qdf_event_destroy(&link_info->acs_complete_event);
7814 		qdf_spinlock_destroy(&link_info->vdev_lock);
7815 	}
7816 }
7817 
7818 static void hdd_cleanup_adapter(struct hdd_context *hdd_ctx,
7819 				struct hdd_adapter *adapter,
7820 				bool rtnl_held)
7821 {
7822 	struct net_device *dev = NULL;
7823 
7824 	if (adapter)
7825 		dev = adapter->dev;
7826 	else {
7827 		hdd_err("adapter is Null");
7828 		return;
7829 	}
7830 
7831 	hdd_apf_context_destroy(adapter);
7832 	qdf_spinlock_destroy(&adapter->mc_list_lock);
7833 	hdd_adapter_destroy_vdev_info(adapter);
7834 	hdd_sta_info_deinit(&adapter->sta_info_list);
7835 	hdd_sta_info_deinit(&adapter->cache_sta_info_list);
7836 
7837 	wlan_hdd_debugfs_csr_deinit(adapter);
7838 
7839 	hdd_debugfs_exit(adapter);
7840 
7841 	/*
7842 	 * The adapter is marked as closed. When hdd_wlan_exit() call returns,
7843 	 * the driver is almost closed and cannot handle either control
7844 	 * messages or data. However, unregister_netdevice() call above will
7845 	 * eventually invoke hdd_stop(ndo_close) driver callback, which attempts
7846 	 * to close the active connections(basically excites control path) which
7847 	 * is not right. Setting this flag helps hdd_stop() to recognize that
7848 	 * the interface is closed and restricts any operations on that
7849 	 */
7850 	clear_bit(DEVICE_IFACE_OPENED, &adapter->event_flags);
7851 
7852 	if (test_bit(NET_DEVICE_REGISTERED, &adapter->event_flags)) {
7853 		if (rtnl_held) {
7854 			hdd_debug("hdd_unregister_netdevice(%s) type:%d",
7855 				  dev->name, adapter->device_mode);
7856 			hdd_unregister_netdevice(adapter, dev);
7857 		} else {
7858 			hdd_debug("unregister_netdev(%s) type:%d", dev->name,
7859 				  adapter->device_mode);
7860 			unregister_netdev(dev);
7861 		}
7862 		/*
7863 		 * Note that the adapter is no longer valid at this point
7864 		 * since the memory has been reclaimed
7865 		 */
7866 	}
7867 }
7868 
7869 static QDF_STATUS hdd_check_for_existing_macaddr(struct hdd_context *hdd_ctx,
7870 						 tSirMacAddr mac_addr)
7871 {
7872 	struct hdd_adapter *adapter, *next_adapter = NULL;
7873 	wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_CHECK_FOR_EXISTING_MACADDR;
7874 
7875 	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
7876 					   dbgid) {
7877 		if (!qdf_mem_cmp(adapter->mac_addr.bytes,
7878 				 mac_addr, sizeof(tSirMacAddr))) {
7879 			hdd_adapter_dev_put_debug(adapter, dbgid);
7880 			if (next_adapter)
7881 				hdd_adapter_dev_put_debug(next_adapter,
7882 							  dbgid);
7883 			return QDF_STATUS_E_FAILURE;
7884 		}
7885 		hdd_adapter_dev_put_debug(adapter, dbgid);
7886 	}
7887 
7888 	return QDF_STATUS_SUCCESS;
7889 }
7890 
7891 /**
7892  * hdd_configure_chain_mask() - programs chain mask to firmware
7893  * @adapter: HDD adapter
7894  *
7895  * Return: 0 on success or errno on failure
7896  */
7897 static int hdd_configure_chain_mask(struct hdd_adapter *adapter)
7898 {
7899 	QDF_STATUS status;
7900 	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
7901 
7902 	status = ucfg_mlme_configure_chain_mask(hdd_ctx->psoc,
7903 						adapter->deflink->vdev_id);
7904 	if (QDF_IS_STATUS_ERROR(status))
7905 		goto error;
7906 
7907 	return 0;
7908 
7909 error:
7910 	hdd_debug("WMI PDEV set param failed");
7911 	return -EINVAL;
7912 }
7913 
7914 void hdd_adapter_update_mlo_mgr_mac_addr(struct hdd_adapter *adapter)
7915 {
7916 	int i = 0;
7917 	struct wlan_hdd_link_info *link_info;
7918 	struct wlan_mlo_link_mac_update link_mac = {0};
7919 
7920 	if (!hdd_adapter_is_ml_adapter(adapter))
7921 		return;
7922 
7923 	hdd_adapter_for_each_link_info(adapter, link_info) {
7924 		link_mac.link_mac_info[i].vdev_id = link_info->vdev_id;
7925 		qdf_copy_macaddr(&link_mac.link_mac_info[i++].link_mac_addr,
7926 				 &link_info->link_addr);
7927 	}
7928 
7929 	link_mac.num_mac_update = i;
7930 	mlo_mgr_update_link_info_mac_addr(adapter->deflink->vdev, &link_mac);
7931 }
7932 
7933 /**
7934  * hdd_send_coex_config_params() - Send coex config params to FW
7935  * @hdd_ctx: HDD context
7936  * @adapter: Primary adapter context
7937  *
7938  * This function is used to send all coex config related params to FW
7939  *
7940  * Return: 0 on success and -EINVAL on failure
7941  */
7942 static int hdd_send_coex_config_params(struct hdd_context *hdd_ctx,
7943 				       struct hdd_adapter *adapter)
7944 {
7945 	struct coex_config_params coex_cfg_params = {0};
7946 	struct wlan_fwol_coex_config config = {0};
7947 	struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc;
7948 	enum coex_btc_chain_mode btc_chain_mode;
7949 	QDF_STATUS status;
7950 
7951 	if (!adapter) {
7952 		hdd_err("adapter is invalid");
7953 		goto err;
7954 	}
7955 
7956 	if (!psoc) {
7957 		hdd_err("HDD psoc is invalid");
7958 		goto err;
7959 	}
7960 
7961 	status = ucfg_fwol_get_coex_config_params(psoc, &config);
7962 	if (QDF_IS_STATUS_ERROR(status)) {
7963 		hdd_err("Unable to get coex config params");
7964 		goto err;
7965 	}
7966 
7967 	coex_cfg_params.vdev_id = adapter->deflink->vdev_id;
7968 	coex_cfg_params.config_type = WMI_COEX_CONFIG_TX_POWER;
7969 	coex_cfg_params.config_arg1 = config.max_tx_power_for_btc;
7970 
7971 	wma_nofl_debug("TXP[W][send_coex_cfg]: %d",
7972 		       config.max_tx_power_for_btc);
7973 
7974 	status = sme_send_coex_config_cmd(&coex_cfg_params);
7975 	if (QDF_IS_STATUS_ERROR(status)) {
7976 		hdd_err("Failed to send coex Tx power");
7977 		goto err;
7978 	}
7979 
7980 	coex_cfg_params.config_type = WMI_COEX_CONFIG_HANDOVER_RSSI;
7981 	coex_cfg_params.config_arg1 = config.wlan_low_rssi_threshold;
7982 
7983 	status = sme_send_coex_config_cmd(&coex_cfg_params);
7984 	if (QDF_IS_STATUS_ERROR(status)) {
7985 		hdd_err("Failed to send coex handover RSSI");
7986 		goto err;
7987 	}
7988 
7989 	coex_cfg_params.config_type = WMI_COEX_CONFIG_BTC_MODE;
7990 
7991 	/* Modify BTC_MODE according to BTC_CHAIN_MODE */
7992 	status = ucfg_coex_psoc_get_btc_chain_mode(psoc, &btc_chain_mode);
7993 	if (QDF_IS_STATUS_ERROR(status)) {
7994 		hdd_err("Failed to get btc chain mode");
7995 		btc_chain_mode = WLAN_COEX_BTC_CHAIN_MODE_UNSETTLED;
7996 	}
7997 
7998 	if (btc_chain_mode <= WLAN_COEX_BTC_CHAIN_MODE_HYBRID)
7999 		coex_cfg_params.config_arg1 = btc_chain_mode;
8000 	else
8001 		coex_cfg_params.config_arg1 = config.btc_mode;
8002 
8003 	hdd_debug("Configured BTC mode is %d, BTC chain mode is 0x%x, set BTC mode to %d",
8004 		  config.btc_mode, btc_chain_mode,
8005 		  coex_cfg_params.config_arg1);
8006 	status = sme_send_coex_config_cmd(&coex_cfg_params);
8007 	if (QDF_IS_STATUS_ERROR(status)) {
8008 		hdd_err("Failed to send coex BTC mode");
8009 		goto err;
8010 	}
8011 
8012 	coex_cfg_params.config_type = WMI_COEX_CONFIG_ANTENNA_ISOLATION;
8013 	coex_cfg_params.config_arg1 = config.antenna_isolation;
8014 
8015 	status = sme_send_coex_config_cmd(&coex_cfg_params);
8016 	if (QDF_IS_STATUS_ERROR(status)) {
8017 		hdd_err("Failed to send coex antenna isolation");
8018 		goto err;
8019 	}
8020 
8021 	coex_cfg_params.config_type = WMI_COEX_CONFIG_BT_LOW_RSSI_THRESHOLD;
8022 	coex_cfg_params.config_arg1 = config.bt_low_rssi_threshold;
8023 
8024 	status = sme_send_coex_config_cmd(&coex_cfg_params);
8025 	if (QDF_IS_STATUS_ERROR(status)) {
8026 		hdd_err("Failed to send coex BT low RSSI threshold");
8027 		goto err;
8028 	}
8029 
8030 	coex_cfg_params.config_type = WMI_COEX_CONFIG_BT_INTERFERENCE_LEVEL;
8031 	coex_cfg_params.config_arg1 = config.bt_interference_low_ll;
8032 	coex_cfg_params.config_arg2 = config.bt_interference_low_ul;
8033 	coex_cfg_params.config_arg3 = config.bt_interference_medium_ll;
8034 	coex_cfg_params.config_arg4 = config.bt_interference_medium_ul;
8035 	coex_cfg_params.config_arg5 = config.bt_interference_high_ll;
8036 	coex_cfg_params.config_arg6 = config.bt_interference_high_ul;
8037 
8038 	status = sme_send_coex_config_cmd(&coex_cfg_params);
8039 	if (QDF_IS_STATUS_ERROR(status)) {
8040 		hdd_err("Failed to send coex BT interference level");
8041 		goto err;
8042 	}
8043 
8044 	if (wlan_hdd_mpta_helper_enable(&coex_cfg_params, &config))
8045 		goto err;
8046 
8047 	coex_cfg_params.config_type =
8048 				WMI_COEX_CONFIG_BT_SCO_ALLOW_WLAN_2G_SCAN;
8049 	coex_cfg_params.config_arg1 = config.bt_sco_allow_wlan_2g_scan;
8050 
8051 	status = sme_send_coex_config_cmd(&coex_cfg_params);
8052 	if (QDF_IS_STATUS_ERROR(status)) {
8053 		hdd_err("Failed to send coex BT sco allow wlan 2g scan");
8054 		goto err;
8055 	}
8056 
8057 	coex_cfg_params.config_type =
8058 				WMI_COEX_CONFIG_LE_SCAN_POLICY;
8059 	coex_cfg_params.config_arg1 = config.ble_scan_coex_policy;
8060 
8061 	status = sme_send_coex_config_cmd(&coex_cfg_params);
8062 	if (QDF_IS_STATUS_ERROR(status)) {
8063 		hdd_err("Failed to send coex BLE scan policy");
8064 		goto err;
8065 	}
8066 
8067 #ifdef FEATURE_COEX_TPUT_SHAPING_CONFIG
8068 	coex_cfg_params.config_type =
8069 				WMI_COEX_CONFIG_ENABLE_TPUT_SHAPING;
8070 	coex_cfg_params.config_arg1 = config.coex_tput_shaping_enable;
8071 
8072 	status = sme_send_coex_config_cmd(&coex_cfg_params);
8073 	if (QDF_IS_STATUS_ERROR(status)) {
8074 		hdd_err("Failed to send coex traffic shaping value %d",
8075 			coex_cfg_params.config_arg1);
8076 		goto err;
8077 	}
8078 #endif
8079 	return 0;
8080 err:
8081 	return -EINVAL;
8082 }
8083 
8084 #define MAX_PDEV_SET_FW_PARAMS 7
8085 /* params being sent:
8086  * 1.wmi_pdev_param_dtim_synth
8087  * 2.wmi_pdev_param_1ch_dtim_optimized_chain_selection
8088  * 3.wmi_pdev_param_tx_sch_delay
8089  * 4.wmi_pdev_param_en_update_scram_seed
8090  * 5.wmi_pdev_param_secondary_retry_enable
8091  * 6.wmi_pdev_param_set_sap_xlna_bypass
8092  * 7.wmi_pdev_param_set_dfs_chan_ageout_time
8093  */
8094 
8095 /**
8096  * hdd_set_fw_params() - Set parameters to firmware
8097  * @adapter: HDD adapter
8098  *
8099  * This function Sets various parameters to fw once the
8100  * adapter is started.
8101  *
8102  * Return: 0 on success or errno on failure
8103  */
8104 int hdd_set_fw_params(struct hdd_adapter *adapter)
8105 {
8106 	int ret;
8107 	uint16_t upper_brssi_thresh, lower_brssi_thresh, rts_profile;
8108 	bool enable_dtim_1chrx;
8109 	QDF_STATUS status;
8110 	struct hdd_context *hdd_ctx;
8111 	bool is_lprx_enabled;
8112 	bool bval = false;
8113 	uint8_t enable_tx_sch_delay, dfs_chan_ageout_time;
8114 	uint32_t dtim_sel_diversity, enable_secondary_rate;
8115 	bool sap_xlna_bypass;
8116 	bool enable_ofdm_scrambler_seed = false;
8117 	struct dev_set_param setparam[MAX_PDEV_SET_FW_PARAMS] = { };
8118 	uint8_t index = 0;
8119 
8120 	hdd_enter_dev(adapter->dev);
8121 
8122 	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
8123 	if (!hdd_ctx)
8124 		return -EINVAL;
8125 
8126 	if (cds_get_conparam() == QDF_GLOBAL_FTM_MODE) {
8127 		hdd_debug("FTM Mode is active; nothing to do");
8128 		return 0;
8129 	}
8130 
8131 	/* The ini gEnableLPRx is deprecated. By default, the ini
8132 	 * is enabled. So, making the variable is_lprx_enabled true.
8133 	 */
8134 	is_lprx_enabled = true;
8135 
8136 	ret = mlme_check_index_setparam(setparam, wmi_pdev_param_dtim_synth,
8137 					is_lprx_enabled, index++,
8138 					MAX_PDEV_SET_FW_PARAMS);
8139 	if (QDF_IS_STATUS_ERROR(ret))
8140 		goto error;
8141 
8142 	ucfg_mlme_get_dtim_selection_diversity(hdd_ctx->psoc,
8143 					       &dtim_sel_diversity);
8144 	ret = mlme_check_index_setparam(
8145 			setparam,
8146 			wmi_pdev_param_1ch_dtim_optimized_chain_selection,
8147 			dtim_sel_diversity, index++, MAX_PDEV_SET_FW_PARAMS);
8148 	if (QDF_IS_STATUS_ERROR(ret))
8149 		goto error;
8150 
8151 	if (QDF_IS_STATUS_SUCCESS(ucfg_fwol_get_enable_tx_sch_delay(
8152 				  hdd_ctx->psoc, &enable_tx_sch_delay))) {
8153 		ret = mlme_check_index_setparam(
8154 					      setparam,
8155 					      wmi_pdev_param_tx_sch_delay,
8156 					      enable_tx_sch_delay, index++,
8157 					      MAX_PDEV_SET_FW_PARAMS);
8158 		if (QDF_IS_STATUS_ERROR(ret))
8159 			goto error;
8160 	}
8161 
8162 	if (QDF_IS_STATUS_SUCCESS(ucfg_fwol_get_ofdm_scrambler_seed(
8163 				hdd_ctx->psoc, &enable_ofdm_scrambler_seed))) {
8164 		ret = mlme_check_index_setparam(
8165 					setparam,
8166 					wmi_pdev_param_en_update_scram_seed,
8167 					enable_ofdm_scrambler_seed, index++,
8168 					MAX_PDEV_SET_FW_PARAMS);
8169 		if (QDF_IS_STATUS_ERROR(ret))
8170 			goto error;
8171 	}
8172 
8173 	if (QDF_IS_STATUS_SUCCESS(ucfg_fwol_get_enable_secondary_rate(
8174 				  hdd_ctx->psoc, &enable_secondary_rate))) {
8175 		ret = mlme_check_index_setparam(
8176 					setparam,
8177 					wmi_pdev_param_secondary_retry_enable,
8178 					enable_secondary_rate, index++,
8179 					MAX_PDEV_SET_FW_PARAMS);
8180 		if (QDF_IS_STATUS_ERROR(ret))
8181 			goto error;
8182 	}
8183 	if (QDF_IS_STATUS_SUCCESS(ucfg_fwol_get_sap_xlna_bypass(
8184 				  hdd_ctx->psoc, &sap_xlna_bypass))) {
8185 		ret = mlme_check_index_setparam(
8186 					setparam,
8187 					wmi_pdev_param_set_sap_xlna_bypass,
8188 					sap_xlna_bypass, index++,
8189 					MAX_PDEV_SET_FW_PARAMS);
8190 		if (QDF_IS_STATUS_ERROR(ret))
8191 			goto error;
8192 	}
8193 	wlan_mlme_get_dfs_chan_ageout_time(hdd_ctx->psoc,
8194 					   &dfs_chan_ageout_time);
8195 	ret = mlme_check_index_setparam(
8196 				      setparam,
8197 				      wmi_pdev_param_set_dfs_chan_ageout_time,
8198 				      dfs_chan_ageout_time, index++,
8199 				      MAX_PDEV_SET_FW_PARAMS);
8200 	if (QDF_IS_STATUS_ERROR(ret))
8201 		goto error;
8202 
8203 	ret = sme_send_multi_pdev_vdev_set_params(MLME_PDEV_SETPARAM,
8204 						  WMI_PDEV_ID_SOC, setparam,
8205 						  index);
8206 	if (QDF_IS_STATUS_ERROR(ret)) {
8207 		goto error;
8208 	}
8209 	if (adapter->device_mode == QDF_STA_MODE) {
8210 		status = ucfg_get_upper_brssi_thresh(hdd_ctx->psoc,
8211 						     &upper_brssi_thresh);
8212 		if (QDF_IS_STATUS_ERROR(status))
8213 			return -EINVAL;
8214 
8215 		sme_set_smps_cfg(adapter->deflink->vdev_id,
8216 				 HDD_STA_SMPS_PARAM_UPPER_BRSSI_THRESH,
8217 				 upper_brssi_thresh);
8218 
8219 		status = ucfg_get_lower_brssi_thresh(hdd_ctx->psoc,
8220 						     &lower_brssi_thresh);
8221 		if (QDF_IS_STATUS_ERROR(status))
8222 			return -EINVAL;
8223 
8224 		sme_set_smps_cfg(adapter->deflink->vdev_id,
8225 				 HDD_STA_SMPS_PARAM_LOWER_BRSSI_THRESH,
8226 				 lower_brssi_thresh);
8227 
8228 		status = ucfg_get_enable_dtim_1chrx(hdd_ctx->psoc,
8229 						    &enable_dtim_1chrx);
8230 		if (QDF_IS_STATUS_ERROR(status))
8231 			return -EINVAL;
8232 
8233 		sme_set_smps_cfg(adapter->deflink->vdev_id,
8234 				 HDD_STA_SMPS_PARAM_DTIM_1CHRX_ENABLE,
8235 				 enable_dtim_1chrx);
8236 	}
8237 
8238 	status = ucfg_mlme_get_vht_enable2x2(hdd_ctx->psoc, &bval);
8239 	if (!QDF_IS_STATUS_SUCCESS(status))
8240 		hdd_err("unable to get vht_enable2x2");
8241 
8242 	if (bval) {
8243 		hdd_debug("configuring 2x2 mode fw params");
8244 
8245 		ret = sme_set_cck_tx_fir_override(hdd_ctx->mac_handle,
8246 						  adapter->deflink->vdev_id);
8247 		if (ret) {
8248 			hdd_err("wmi_pdev_param_enable_cck_tfir_override set failed %d",
8249 				ret);
8250 			goto error;
8251 		}
8252 
8253 		hdd_configure_chain_mask(adapter);
8254 	} else {
8255 #define HDD_DTIM_1CHAIN_RX_ID 0x5
8256 #define HDD_SMPS_PARAM_VALUE_S 29
8257 		hdd_debug("configuring 1x1 mode fw params");
8258 
8259 		/*
8260 		 * Disable DTIM 1 chain Rx when in 1x1,
8261 		 * we are passing two value
8262 		 * as param_id << 29 | param_value.
8263 		 * Below param_value = 0(disable)
8264 		 */
8265 		ret = sme_cli_set_command(adapter->deflink->vdev_id,
8266 					  WMI_STA_SMPS_PARAM_CMDID,
8267 					  HDD_DTIM_1CHAIN_RX_ID <<
8268 					  HDD_SMPS_PARAM_VALUE_S,
8269 					  VDEV_CMD);
8270 		if (ret) {
8271 			hdd_err("DTIM 1 chain set failed %d", ret);
8272 			goto error;
8273 		}
8274 
8275 #undef HDD_DTIM_1CHAIN_RX_ID
8276 #undef HDD_SMPS_PARAM_VALUE_S
8277 
8278 		hdd_configure_chain_mask(adapter);
8279 	}
8280 
8281 	ret = sme_set_enable_mem_deep_sleep(hdd_ctx->mac_handle,
8282 					    adapter->deflink->vdev_id);
8283 	if (ret) {
8284 		hdd_err("wmi_pdev_param_hyst_en set failed %d", ret);
8285 		goto error;
8286 	}
8287 
8288 	status = ucfg_fwol_get_rts_profile(hdd_ctx->psoc, &rts_profile);
8289 	if (QDF_IS_STATUS_ERROR(status))
8290 		return -EINVAL;
8291 
8292 	ret = sme_cli_set_command(adapter->deflink->vdev_id,
8293 				  wmi_vdev_param_enable_rtscts,
8294 				  rts_profile,
8295 				  VDEV_CMD);
8296 	if (ret) {
8297 		hdd_err("FAILED TO SET RTSCTS Profile ret:%d", ret);
8298 		goto error;
8299 	}
8300 
8301 	if (!hdd_ctx->is_fw_dbg_log_levels_configured) {
8302 		hdd_set_fw_log_params(hdd_ctx, adapter->deflink->vdev_id);
8303 		hdd_ctx->is_fw_dbg_log_levels_configured = true;
8304 	}
8305 
8306 	ret = hdd_send_coex_config_params(hdd_ctx, adapter);
8307 	if (ret) {
8308 		hdd_warn("Error initializing coex config params");
8309 		goto error;
8310 	}
8311 
8312 	hdd_exit();
8313 
8314 	return 0;
8315 
8316 error:
8317 	return -EINVAL;
8318 }
8319 
8320 /**
8321  * hdd_init_completion() - Initialize Completion Variables
8322  * @adapter: HDD adapter
8323  *
8324  * This function Initialize the completion variables for
8325  * a particular adapter
8326  *
8327  * Return: None
8328  */
8329 static void hdd_init_completion(struct hdd_adapter *adapter)
8330 {
8331 	init_completion(&adapter->disconnect_comp_var);
8332 	init_completion(&adapter->linkup_event_var);
8333 	init_completion(&adapter->lfr_fw_status.disable_lfr_event);
8334 }
8335 
8336 static void hdd_reset_locally_admin_bit(struct hdd_context *hdd_ctx,
8337 					tSirMacAddr mac_addr)
8338 {
8339 	int i;
8340 	/*
8341 	 * Reset locally administered bit for dynamic_mac_list
8342 	 * also as while releasing the MAC address for any
8343 	 * interface mac will be compared with dynamic mac list
8344 	 */
8345 	for (i = 0; i < QDF_MAX_CONCURRENCY_PERSONA; i++) {
8346 		if (!qdf_mem_cmp(
8347 			mac_addr,
8348 			 &hdd_ctx->
8349 				dynamic_mac_list[i].dynamic_mac.bytes[0],
8350 				sizeof(struct qdf_mac_addr))) {
8351 			WLAN_HDD_RESET_LOCALLY_ADMINISTERED_BIT(
8352 				hdd_ctx->
8353 					dynamic_mac_list[i].dynamic_mac.bytes);
8354 			break;
8355 		}
8356 	}
8357 	/*
8358 	 * Reset locally administered bit if the device mode is
8359 	 * STA
8360 	 */
8361 	WLAN_HDD_RESET_LOCALLY_ADMINISTERED_BIT(mac_addr);
8362 	hdd_debug("locally administered bit reset in sta mode: "
8363 		 QDF_MAC_ADDR_FMT, QDF_MAC_ADDR_REF(mac_addr));
8364 }
8365 
8366 static void wlan_hdd_cfg80211_scan_block_cb(struct work_struct *work)
8367 {
8368 	struct hdd_adapter *adapter =
8369 		container_of(work, struct hdd_adapter, scan_block_work);
8370 	struct osif_vdev_sync *vdev_sync;
8371 
8372 	if (osif_vdev_sync_op_start(adapter->dev, &vdev_sync))
8373 		return;
8374 
8375 	wlan_hdd_cfg80211_scan_block(adapter);
8376 
8377 	osif_vdev_sync_op_stop(vdev_sync);
8378 }
8379 
8380 #if defined(WLAN_FEATURE_11BE_MLO) && \
8381 	defined(WLAN_HDD_MULTI_VDEV_SINGLE_NDEV)
8382 static inline void
8383 wlan_hdd_set_ml_cap_for_sap_intf(struct hdd_adapter_create_param *create_params,
8384 				 enum QDF_OPMODE mode)
8385 {
8386 	if (mode != QDF_SAP_MODE)
8387 		return;
8388 
8389 	create_params->is_ml_adapter = true;
8390 }
8391 #elif defined(WLAN_FEATURE_11BE_MLO)
8392 static inline void
8393 wlan_hdd_set_ml_cap_for_sap_intf(struct hdd_adapter_create_param *create_params,
8394 				 enum QDF_OPMODE mode)
8395 {
8396 	if (mode != QDF_SAP_MODE)
8397 		return;
8398 
8399 	create_params->is_ml_adapter = true;
8400 	create_params->is_single_link = true;
8401 }
8402 #else
8403 static inline void
8404 wlan_hdd_set_ml_cap_for_sap_intf(struct hdd_adapter_create_param *create_params,
8405 				 enum QDF_OPMODE mode)
8406 {
8407 	create_params->is_ml_adapter = false;
8408 }
8409 #endif /* WLAN_FEATURE_11BE_MLO */
8410 
8411 #if defined(WLAN_FEATURE_11BE_MLO) && defined(CFG80211_11BE_BASIC) && \
8412 	defined(WLAN_HDD_MULTI_VDEV_SINGLE_NDEV)
8413 void hdd_adapter_disable_all_links(struct hdd_adapter *adapter)
8414 {
8415 	uint8_t idx_pos;
8416 	struct wlan_hdd_link_info *link_info;
8417 
8418 	hdd_adapter_for_each_link_info(adapter, link_info) {
8419 		qdf_zero_macaddr(&link_info->link_addr);
8420 		idx_pos = hdd_adapter_get_index_of_link_info(link_info);
8421 		adapter->curr_link_info_map[idx_pos] = idx_pos;
8422 	}
8423 	adapter->deflink = &adapter->link_info[WLAN_HDD_DEFLINK_IDX];
8424 	if (adapter->device_mode == QDF_STA_MODE)
8425 		adapter->active_links = (1 << adapter->num_links_on_create) - 1;
8426 	else
8427 		adapter->active_links = 0x1;
8428 }
8429 #endif
8430 
8431 static void hdd_adapter_enable_links(struct hdd_adapter *adapter,
8432 				     struct hdd_adapter_create_param *params)
8433 {
8434 	uint8_t num, link_idx;
8435 
8436 	/* Default link is already set on adapter allocation, only
8437 	 * enable other links if requested links is greater than 1
8438 	 */
8439 	if (params->num_sessions <= 1) {
8440 		adapter->num_links_on_create = 1;
8441 		return;
8442 	}
8443 
8444 	num = QDF_MIN(params->num_sessions, WLAN_MAX_MLD);
8445 	for (link_idx = WLAN_HDD_DEFLINK_IDX; link_idx < num; link_idx++)
8446 		qdf_atomic_set_bit(link_idx, &adapter->active_links);
8447 
8448 	adapter->num_links_on_create = num;
8449 }
8450 
8451 static void hdd_adapter_init_link_info(struct hdd_adapter *adapter)
8452 {
8453 	uint8_t idx_pos;
8454 	struct wlan_hdd_link_info *link_info;
8455 
8456 	/* Initialize each member in link info array to default values */
8457 	hdd_adapter_for_each_link_info(adapter, link_info) {
8458 		link_info->adapter = adapter;
8459 		link_info->vdev_id = WLAN_UMAC_VDEV_ID_MAX;
8460 		qdf_spinlock_create(&link_info->vdev_lock);
8461 		init_completion(&link_info->vdev_destroy_event);
8462 		qdf_event_create(&link_info->acs_complete_event);
8463 
8464 		idx_pos = hdd_adapter_get_index_of_link_info(link_info);
8465 		adapter->curr_link_info_map[idx_pos] = idx_pos;
8466 	}
8467 }
8468 
8469 /**
8470  * hdd_open_adapter() - open and setup the hdd adapter
8471  * @hdd_ctx: global hdd context
8472  * @session_type: type of the interface to be created
8473  * @iface_name: User-visible name of the interface
8474  * @mac_addr: MAC address to assign to the interface
8475  * @name_assign_type: the name of assign type of the netdev
8476  * @rtnl_held: the rtnl lock hold flag
8477  * @params: adapter create params
8478  *
8479  * This function open and setup the hdd adapter according to the device
8480  * type request, assign the name, the mac address assigned, and then prepared
8481  * the hdd related parameters, queue, lock and ready to start.
8482  *
8483  * Return: the pointer of hdd adapter, otherwise NULL.
8484  */
8485 struct hdd_adapter *hdd_open_adapter(struct hdd_context *hdd_ctx,
8486 				     uint8_t session_type,
8487 				     const char *iface_name,
8488 				     tSirMacAddr mac_addr,
8489 				     unsigned char name_assign_type,
8490 				     bool rtnl_held,
8491 				     struct hdd_adapter_create_param *params)
8492 {
8493 	struct net_device *ndev = NULL;
8494 	struct hdd_adapter *adapter = NULL, *sta_adapter = NULL;
8495 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
8496 	uint32_t i;
8497 	bool eht_capab = 0;
8498 
8499 	status = wlan_hdd_validate_mac_address((struct qdf_mac_addr *)mac_addr);
8500 	if (QDF_IS_STATUS_ERROR(status)) {
8501 		/* Not received valid mac_addr */
8502 		hdd_err("Unable to add virtual intf: Not able to get valid mac address");
8503 		return NULL;
8504 	}
8505 
8506 	status = hdd_check_for_existing_macaddr(hdd_ctx, mac_addr);
8507 	if (QDF_STATUS_E_FAILURE == status) {
8508 		hdd_err("Duplicate MAC addr: " QDF_MAC_ADDR_FMT
8509 				" already exists",
8510 				QDF_MAC_ADDR_REF(mac_addr));
8511 		return NULL;
8512 	}
8513 
8514 	if (params->only_wdev_register) {
8515 		sta_adapter = hdd_get_ml_adapter(hdd_ctx);
8516 		if (!sta_adapter) {
8517 			hdd_err("not able to find the sta adapter");
8518 			return NULL;
8519 		}
8520 	}
8521 
8522 	switch (session_type) {
8523 	case QDF_STA_MODE:
8524 		if (!(hdd_ctx->config->mac_provision ||
8525 		      params->only_wdev_register)) {
8526 			hdd_reset_locally_admin_bit(hdd_ctx, mac_addr);
8527 			/*
8528 			 * After resetting locally administered bit
8529 			 * again check if the new mac address is already
8530 			 * exists.
8531 			 */
8532 			status = hdd_check_for_existing_macaddr(hdd_ctx,
8533 								mac_addr);
8534 			if (QDF_STATUS_E_FAILURE == status) {
8535 				hdd_err("Duplicate MAC addr: " QDF_MAC_ADDR_FMT
8536 					" already exists",
8537 					QDF_MAC_ADDR_REF(mac_addr));
8538 				return NULL;
8539 			}
8540 		}
8541 
8542 		fallthrough;
8543 	case QDF_P2P_CLIENT_MODE:
8544 	case QDF_P2P_DEVICE_MODE:
8545 	case QDF_OCB_MODE:
8546 	case QDF_NDI_MODE:
8547 	case QDF_MONITOR_MODE:
8548 	case QDF_NAN_DISC_MODE:
8549 		adapter = hdd_alloc_station_adapter(hdd_ctx, mac_addr,
8550 						    name_assign_type,
8551 						    iface_name, session_type);
8552 
8553 		if (!adapter) {
8554 			hdd_err("failed to allocate adapter for session %d",
8555 					session_type);
8556 			return NULL;
8557 		}
8558 
8559 		ndev = adapter->dev;
8560 
8561 		status = ucfg_dp_create_intf(hdd_ctx->psoc, &adapter->mac_addr,
8562 					     (qdf_netdev_t)adapter->dev);
8563 		if (QDF_IS_STATUS_ERROR(status))
8564 			goto err_free_netdev;
8565 
8566 		if (QDF_P2P_CLIENT_MODE == session_type)
8567 			adapter->wdev.iftype = NL80211_IFTYPE_P2P_CLIENT;
8568 		else if (QDF_P2P_DEVICE_MODE == session_type)
8569 			adapter->wdev.iftype = NL80211_IFTYPE_P2P_DEVICE;
8570 		else if (QDF_MONITOR_MODE == session_type)
8571 			adapter->wdev.iftype = NL80211_IFTYPE_MONITOR;
8572 		else if (QDF_NAN_DISC_MODE == session_type)
8573 			wlan_hdd_set_nan_if_type(adapter);
8574 		else
8575 			adapter->wdev.iftype = NL80211_IFTYPE_STATION;
8576 
8577 		adapter->device_mode = session_type;
8578 
8579 
8580 		/*
8581 		 * Workqueue which gets scheduled in IPv4 notification
8582 		 * callback
8583 		 */
8584 		INIT_WORK(&adapter->ipv4_notifier_work,
8585 			  hdd_ipv4_notifier_work_queue);
8586 
8587 #ifdef WLAN_NS_OFFLOAD
8588 		/*
8589 		 * Workqueue which gets scheduled in IPv6
8590 		 * notification callback.
8591 		 */
8592 		INIT_WORK(&adapter->ipv6_notifier_work,
8593 			  hdd_ipv6_notifier_work_queue);
8594 #endif
8595 		if (params->only_wdev_register) {
8596 			hdd_register_wdev(sta_adapter, adapter, params);
8597 		} else {
8598 			status = hdd_register_interface(adapter, rtnl_held,
8599 							params);
8600 			if (QDF_STATUS_SUCCESS != status)
8601 				goto err_destroy_dp_intf;
8602 			/* Stop the Interface TX queue. */
8603 			hdd_debug("Disabling queues");
8604 			wlan_hdd_netif_queue_control(adapter,
8605 					WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER,
8606 					WLAN_CONTROL_PATH);
8607 		}
8608 		break;
8609 	case QDF_P2P_GO_MODE:
8610 	case QDF_SAP_MODE:
8611 		adapter = hdd_wlan_create_ap_dev(hdd_ctx, mac_addr,
8612 						 name_assign_type,
8613 						 (uint8_t *) iface_name);
8614 		if (!adapter) {
8615 			hdd_err("failed to allocate adapter for session %d",
8616 					  session_type);
8617 			return NULL;
8618 		}
8619 
8620 		ndev = adapter->dev;
8621 
8622 		status = ucfg_dp_create_intf(hdd_ctx->psoc, &adapter->mac_addr,
8623 					     (qdf_netdev_t)adapter->dev);
8624 		if (QDF_IS_STATUS_ERROR(status))
8625 			goto err_free_netdev;
8626 
8627 		adapter->wdev.iftype =
8628 			(session_type ==
8629 			 QDF_SAP_MODE) ? NL80211_IFTYPE_AP :
8630 			NL80211_IFTYPE_P2P_GO;
8631 		adapter->device_mode = session_type;
8632 
8633 		status = hdd_register_interface(adapter, rtnl_held, params);
8634 		if (QDF_STATUS_SUCCESS != status)
8635 			goto err_destroy_dp_intf;
8636 
8637 		hdd_debug("Disabling queues");
8638 		wlan_hdd_netif_queue_control(adapter,
8639 					WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER,
8640 					WLAN_CONTROL_PATH);
8641 
8642 		/*
8643 		 * Workqueue which gets scheduled in IPv4 notification
8644 		 * callback
8645 		 */
8646 		INIT_WORK(&adapter->ipv4_notifier_work,
8647 			  hdd_ipv4_notifier_work_queue);
8648 
8649 #ifdef WLAN_NS_OFFLOAD
8650 		/*
8651 		 * Workqueue which gets scheduled in IPv6
8652 		 * notification callback.
8653 		 */
8654 		INIT_WORK(&adapter->ipv6_notifier_work,
8655 			  hdd_ipv6_notifier_work_queue);
8656 #endif
8657 		wlan_hdd_set_ml_cap_for_sap_intf(params, session_type);
8658 		break;
8659 	case QDF_FTM_MODE:
8660 		adapter = hdd_alloc_station_adapter(hdd_ctx, mac_addr,
8661 						    name_assign_type,
8662 						    iface_name, session_type);
8663 		if (!adapter) {
8664 			hdd_err("Failed to allocate adapter for FTM mode");
8665 			return NULL;
8666 		}
8667 
8668 		ndev = adapter->dev;
8669 
8670 		status = ucfg_dp_create_intf(hdd_ctx->psoc, &adapter->mac_addr,
8671 					     (qdf_netdev_t)adapter->dev);
8672 		if (QDF_IS_STATUS_ERROR(status))
8673 			goto err_free_netdev;
8674 
8675 		adapter->wdev.iftype = NL80211_IFTYPE_STATION;
8676 		adapter->device_mode = session_type;
8677 		status = hdd_register_interface(adapter, rtnl_held, params);
8678 		if (QDF_STATUS_SUCCESS != status)
8679 			goto err_destroy_dp_intf;
8680 
8681 		/* Stop the Interface TX queue. */
8682 		hdd_debug("Disabling queues");
8683 		wlan_hdd_netif_queue_control(adapter,
8684 					WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER,
8685 					WLAN_CONTROL_PATH);
8686 
8687 		break;
8688 	default:
8689 		hdd_err("Invalid session type %d", session_type);
8690 		QDF_ASSERT(0);
8691 		return NULL;
8692 	}
8693 
8694 	hdd_adapter_init_link_info(adapter);
8695 	hdd_adapter_enable_links(adapter, params);
8696 
8697 	ucfg_psoc_mlme_get_11be_capab(hdd_ctx->psoc, &eht_capab);
8698 	if (params->is_ml_adapter && eht_capab) {
8699 		hdd_adapter_set_ml_adapter(adapter);
8700 		if (params->is_single_link)
8701 			hdd_adapter_set_sl_ml_adapter(adapter);
8702 	}
8703 
8704 	status = hdd_adapter_feature_update_work_init(adapter);
8705 	if (QDF_IS_STATUS_ERROR(status))
8706 		goto err_cleanup_adapter;
8707 
8708 	adapter->upgrade_udp_qos_threshold = QCA_WLAN_AC_BK;
8709 
8710 	hdd_init_completion(adapter);
8711 	INIT_WORK(&adapter->scan_block_work, wlan_hdd_cfg80211_scan_block_cb);
8712 	INIT_WORK(&adapter->sap_stop_bss_work,
8713 		  hdd_stop_sap_due_to_invalid_channel);
8714 	qdf_list_create(&adapter->blocked_scan_request_q, WLAN_MAX_SCAN_COUNT);
8715 	qdf_mutex_create(&adapter->blocked_scan_request_q_lock);
8716 	qdf_spinlock_create(&adapter->mc_list_lock);
8717 	qdf_event_create(&adapter->peer_cleanup_done);
8718 	hdd_sta_info_init(&adapter->sta_info_list);
8719 	hdd_sta_info_init(&adapter->cache_sta_info_list);
8720 
8721 	for (i = 0; i < NET_DEV_HOLD_ID_MAX; i++)
8722 		qdf_atomic_init(
8723 			&adapter->net_dev_hold_ref_count[NET_DEV_HOLD_ID_MAX]);
8724 
8725 	/* Add it to the hdd's session list. */
8726 	status = hdd_add_adapter_back(hdd_ctx, adapter);
8727 	if (QDF_STATUS_SUCCESS != status)
8728 		goto err_destroy_adapter_features_update_work;
8729 
8730 	hdd_apf_context_init(adapter);
8731 
8732 	policy_mgr_set_concurrency_mode(hdd_ctx->psoc, session_type);
8733 
8734 	if (QDF_STATUS_SUCCESS != hdd_debugfs_init(adapter))
8735 		hdd_err("debugfs: Interface %s init failed",
8736 			netdev_name(adapter->dev));
8737 
8738 	hdd_debug("%s interface created. iftype: %d", netdev_name(adapter->dev),
8739 		  session_type);
8740 
8741 	if (adapter->device_mode == QDF_STA_MODE)
8742 		wlan_hdd_debugfs_csr_init(adapter);
8743 
8744 	return adapter;
8745 
8746 err_destroy_adapter_features_update_work:
8747 	hdd_adapter_feature_update_work_deinit(adapter);
8748 
8749 err_cleanup_adapter:
8750 	if (adapter) {
8751 		hdd_cleanup_adapter(hdd_ctx, adapter, rtnl_held);
8752 		adapter = NULL;
8753 	}
8754 
8755 err_destroy_dp_intf:
8756 	ucfg_dp_destroy_intf(hdd_ctx->psoc, &adapter->mac_addr);
8757 
8758 err_free_netdev:
8759 	if (ndev)
8760 		free_netdev(ndev);
8761 
8762 	return NULL;
8763 }
8764 
8765 static void __hdd_close_adapter(struct hdd_context *hdd_ctx,
8766 				struct hdd_adapter *adapter,
8767 				bool rtnl_held)
8768 {
8769 	struct qdf_mac_addr adapter_mac;
8770 	struct wlan_hdd_link_info *link_info;
8771 
8772 
8773 	qdf_copy_macaddr(&adapter_mac, &adapter->mac_addr);
8774 	if (adapter->device_mode == QDF_STA_MODE) {
8775 		hdd_adapter_for_each_link_info(adapter, link_info)
8776 			hdd_cleanup_conn_info(link_info);
8777 	}
8778 	qdf_list_destroy(&adapter->blocked_scan_request_q);
8779 	qdf_mutex_destroy(&adapter->blocked_scan_request_q_lock);
8780 	policy_mgr_clear_concurrency_mode(hdd_ctx->psoc, adapter->device_mode);
8781 	qdf_event_destroy(&adapter->peer_cleanup_done);
8782 	hdd_adapter_feature_update_work_deinit(adapter);
8783 	hdd_cleanup_adapter(hdd_ctx, adapter, rtnl_held);
8784 	ucfg_dp_destroy_intf(hdd_ctx->psoc, &adapter_mac);
8785 }
8786 
8787 void hdd_close_adapter(struct hdd_context *hdd_ctx,
8788 		       struct hdd_adapter *adapter,
8789 		       bool rtnl_held)
8790 {
8791 	/*
8792 	 * Stop the global bus bandwidth timer while touching the adapter list
8793 	 * to avoid bad memory access by the timer handler.
8794 	 */
8795 	ucfg_dp_bus_bw_compute_timer_stop(hdd_ctx->psoc);
8796 
8797 	hdd_check_for_net_dev_ref_leak(adapter);
8798 	hdd_remove_adapter(hdd_ctx, adapter);
8799 	__hdd_close_adapter(hdd_ctx, adapter, rtnl_held);
8800 
8801 	/* conditionally restart the bw timer */
8802 	ucfg_dp_bus_bw_compute_timer_try_start(hdd_ctx->psoc);
8803 }
8804 
8805 void hdd_close_all_adapters(struct hdd_context *hdd_ctx, bool rtnl_held)
8806 {
8807 	struct hdd_adapter *adapter;
8808 	struct osif_vdev_sync *vdev_sync;
8809 	QDF_STATUS qdf_status;
8810 
8811 	hdd_enter();
8812 
8813 	while (QDF_IS_STATUS_SUCCESS(hdd_get_front_adapter(
8814 							hdd_ctx, &adapter))) {
8815 		/* If MLO is enabled unregister the link wdev's */
8816 		if (adapter->device_mode == QDF_STA_MODE ||
8817 		    adapter->device_mode == QDF_SAP_MODE) {
8818 			qdf_status = hdd_wlan_unregister_mlo_interfaces(adapter,
8819 								     rtnl_held);
8820 			if (QDF_IS_STATUS_ERROR(qdf_status))
8821 				continue;
8822 		}
8823 
8824 		hdd_check_for_net_dev_ref_leak(adapter);
8825 		hdd_remove_front_adapter(hdd_ctx, &adapter);
8826 		vdev_sync = osif_vdev_sync_unregister(adapter->dev);
8827 		if (vdev_sync)
8828 			osif_vdev_sync_wait_for_ops(vdev_sync);
8829 
8830 		wlan_hdd_release_intf_addr(hdd_ctx, adapter->mac_addr.bytes);
8831 		__hdd_close_adapter(hdd_ctx, adapter, rtnl_held);
8832 
8833 		if (vdev_sync)
8834 			osif_vdev_sync_destroy(vdev_sync);
8835 	}
8836 
8837 	hdd_exit();
8838 }
8839 
8840 void wlan_hdd_reset_prob_rspies(struct wlan_hdd_link_info *link_info)
8841 {
8842 	struct qdf_mac_addr *bssid = NULL;
8843 	tSirUpdateIE update_ie;
8844 	mac_handle_t mac_handle;
8845 	struct hdd_adapter *adapter = link_info->adapter;
8846 
8847 	switch (adapter->device_mode) {
8848 	case QDF_STA_MODE:
8849 	case QDF_P2P_CLIENT_MODE:
8850 	{
8851 		struct hdd_station_ctx *sta_ctx =
8852 			WLAN_HDD_GET_STATION_CTX_PTR(link_info);
8853 		bssid = &sta_ctx->conn_info.bssid;
8854 		break;
8855 	}
8856 	case QDF_SAP_MODE:
8857 	case QDF_P2P_GO_MODE:
8858 	{
8859 		bssid = &adapter->mac_addr;
8860 		break;
8861 	}
8862 	case QDF_FTM_MODE:
8863 	case QDF_P2P_DEVICE_MODE:
8864 	default:
8865 		/*
8866 		 * wlan_hdd_reset_prob_rspies should not have been called
8867 		 * for these kind of devices
8868 		 */
8869 		hdd_err("Unexpected request for the current device type %d",
8870 		       adapter->device_mode);
8871 		return;
8872 	}
8873 
8874 	qdf_copy_macaddr(&update_ie.bssid, bssid);
8875 	update_ie.vdev_id = link_info->vdev_id;
8876 	update_ie.ieBufferlength = 0;
8877 	update_ie.pAdditionIEBuffer = NULL;
8878 	update_ie.append = true;
8879 	update_ie.notify = false;
8880 	mac_handle = hdd_adapter_get_mac_handle(adapter);
8881 	if (sme_update_add_ie(mac_handle,
8882 			      &update_ie,
8883 			      eUPDATE_IE_PROBE_RESP) == QDF_STATUS_E_FAILURE) {
8884 		hdd_err("Could not pass on PROBE_RSP_BCN data to PE");
8885 	}
8886 }
8887 
8888 /**
8889  * hdd_ipa_ap_disconnect_evt() - Indicate wlan ipa ap disconnect event
8890  * @hdd_ctx: hdd context
8891  * @adapter: hdd adapter
8892  *
8893  * Return: None
8894  */
8895 static inline
8896 void hdd_ipa_ap_disconnect_evt(struct hdd_context *hdd_ctx,
8897 			       struct hdd_adapter *adapter)
8898 {
8899 	if (ucfg_ipa_is_enabled()) {
8900 		ucfg_ipa_uc_disconnect_ap(hdd_ctx->pdev,
8901 					  adapter->dev);
8902 		ucfg_ipa_cleanup_dev_iface(hdd_ctx->pdev,
8903 					   adapter->dev);
8904 	}
8905 }
8906 
8907 #ifdef WLAN_FEATURE_NAN
8908 /**
8909  * hdd_ndp_state_cleanup() - API to set NDP state to Disconnected
8910  * @psoc: pointer to psoc object
8911  * @ndi_vdev_id: vdev_id of the NDI
8912  *
8913  * Return: None
8914  */
8915 static void
8916 hdd_ndp_state_cleanup(struct wlan_objmgr_psoc *psoc, uint8_t ndi_vdev_id)
8917 {
8918 	struct wlan_objmgr_vdev *ndi_vdev;
8919 
8920 	ndi_vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, ndi_vdev_id,
8921 							WLAN_NAN_ID);
8922 	if (!ndi_vdev) {
8923 		hdd_err("Cannot obtain NDI vdev object!");
8924 		return;
8925 	}
8926 
8927 	ucfg_nan_set_ndi_state(ndi_vdev, NAN_DATA_DISCONNECTED_STATE);
8928 
8929 	wlan_objmgr_vdev_release_ref(ndi_vdev, WLAN_NAN_ID);
8930 }
8931 
8932 /**
8933  * hdd_peer_cleanup() - This API will delete NDP peer if exist and modifies
8934  * the NDP state.
8935  * @link_info: Link info pointer in HDD adapter
8936  *
8937  * Return: None
8938  */
8939 static void hdd_peer_cleanup(struct wlan_hdd_link_info *link_info)
8940 {
8941 	QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
8942 	struct hdd_adapter *adapter = link_info->adapter;
8943 	struct hdd_context *hdd_ctx = adapter->hdd_ctx;
8944 
8945 	/* Check if there is any peer present on the adapter */
8946 	if (!hdd_any_valid_peer_present(link_info)) {
8947 		/*
8948 		 * No peers are connected to the NDI. So, set the NDI state to
8949 		 * DISCONNECTED. If there are any peers, ucfg_nan_disable_ndi()
8950 		 * would take care of cleanup all the peers and setting the
8951 		 * state to DISCONNECTED.
8952 		 */
8953 		hdd_ndp_state_cleanup(hdd_ctx->psoc, link_info->vdev_id);
8954 		return;
8955 	}
8956 
8957 	if (adapter->device_mode == QDF_NDI_MODE)
8958 		qdf_status = ucfg_nan_disable_ndi(hdd_ctx->psoc,
8959 						  link_info->vdev_id);
8960 
8961 	if (QDF_IS_STATUS_ERROR(qdf_status))
8962 		return;
8963 
8964 	qdf_status = qdf_wait_for_event_completion(&adapter->peer_cleanup_done,
8965 						   WLAN_WAIT_PEER_CLEANUP);
8966 	if (QDF_IS_STATUS_ERROR(qdf_status))
8967 		hdd_debug("peer_cleanup_done wait fail");
8968 }
8969 #else
8970 static inline void
8971 hdd_ndp_state_cleanup(struct wlan_objmgr_psoc *psoc, uint8_t ndi_vdev_id)
8972 {
8973 }
8974 
8975 static inline void
8976 hdd_ndp_peer_cleanup(struct hdd_context *hdd_ctx, struct hdd_adapter *adapter)
8977 {
8978 }
8979 
8980 static inline void hdd_peer_cleanup(struct wlan_hdd_link_info *link_info)
8981 {
8982 }
8983 #endif /* WLAN_FEATURE_NAN */
8984 
8985 #ifdef FUNC_CALL_MAP
8986 
8987 /**
8988  * hdd_dump_func_call_map() - Dump the function call map
8989  *
8990  * Return: None
8991  */
8992 
8993 static void hdd_dump_func_call_map(void)
8994 {
8995 	char *cc_buf;
8996 
8997 	cc_buf = qdf_mem_malloc(QDF_FUNCTION_CALL_MAP_BUF_LEN);
8998 	/*
8999 	 * These logs are required as these indicates the start and end of the
9000 	 * dump for the auto script to parse
9001 	 */
9002 	hdd_info("Function call map dump start");
9003 	qdf_get_func_call_map(cc_buf);
9004 	qdf_trace_hex_dump(QDF_MODULE_ID_HDD,
9005 		QDF_TRACE_LEVEL_DEBUG, cc_buf, QDF_FUNCTION_CALL_MAP_BUF_LEN);
9006 	hdd_info("Function call map dump end");
9007 	qdf_mem_free(cc_buf);
9008 }
9009 #else
9010 static inline void hdd_dump_func_call_map(void)
9011 {
9012 }
9013 #endif
9014 
9015 static void hdd_reset_scan_operation(struct wlan_hdd_link_info *link_info)
9016 {
9017 	switch (link_info->adapter->device_mode) {
9018 	case QDF_STA_MODE:
9019 	case QDF_P2P_CLIENT_MODE:
9020 	case QDF_P2P_DEVICE_MODE:
9021 	case QDF_NDI_MODE:
9022 		wlan_hdd_scan_abort(link_info);
9023 		wlan_hdd_cleanup_remain_on_channel_ctx(link_info);
9024 		if (link_info->adapter->device_mode == QDF_STA_MODE) {
9025 			struct wlan_objmgr_vdev *vdev;
9026 
9027 			vdev = hdd_objmgr_get_vdev_by_user(link_info,
9028 							   WLAN_OSIF_SCAN_ID);
9029 			if (!vdev)
9030 				break;
9031 
9032 			wlan_cfg80211_sched_scan_stop(vdev);
9033 			hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_SCAN_ID);
9034 		}
9035 		break;
9036 	case QDF_P2P_GO_MODE:
9037 		wlan_hdd_cleanup_remain_on_channel_ctx(link_info);
9038 		break;
9039 	case QDF_SAP_MODE:
9040 		qdf_atomic_set(&link_info->session.ap.acs_in_progress, 0);
9041 		break;
9042 	default:
9043 		break;
9044 	}
9045 }
9046 
9047 #ifdef WLAN_OPEN_SOURCE
9048 void hdd_cancel_ip_notifier_work(struct hdd_adapter *adapter)
9049 {
9050 	cancel_work_sync(&adapter->ipv4_notifier_work);
9051 #ifdef WLAN_NS_OFFLOAD
9052 	cancel_work_sync(&adapter->ipv6_notifier_work);
9053 #endif
9054 }
9055 #endif
9056 
9057 void hdd_adapter_deregister_fc(struct hdd_adapter *adapter)
9058 {
9059 	hdd_deregister_hl_netdev_fc_timer(adapter);
9060 	hdd_deregister_tx_flow_control(adapter);
9061 }
9062 
9063 static void hdd_stop_and_cleanup_ndi(struct wlan_hdd_link_info *link_info)
9064 {
9065 	QDF_STATUS status;
9066 	unsigned long rc;
9067 	struct hdd_adapter *adapter = link_info->adapter;
9068 	struct hdd_context *hdd_ctx = adapter->hdd_ctx;
9069 
9070 	/* For NDI do not use roam_profile */
9071 	INIT_COMPLETION(adapter->disconnect_comp_var);
9072 	hdd_peer_cleanup(link_info);
9073 	status = sme_roam_ndi_stop(hdd_ctx->mac_handle, link_info->vdev_id);
9074 	if (QDF_IS_STATUS_SUCCESS(status)) {
9075 		rc = wait_for_completion_timeout(
9076 			&adapter->disconnect_comp_var,
9077 			msecs_to_jiffies(SME_CMD_STOP_BSS_TIMEOUT));
9078 		if (!rc)
9079 			hdd_warn("disconn_comp_var wait fail");
9080 		hdd_cleanup_ndi(link_info);
9081 	}
9082 }
9083 
9084 static void
9085 hdd_sta_disconnect_and_cleanup(struct wlan_hdd_link_info *link_info)
9086 {
9087 	QDF_STATUS status;
9088 	enum wlan_reason_code reason;
9089 	struct hdd_adapter *adapter = link_info->adapter;
9090 
9091 	/*
9092 	 * On vdev delete wait for disconnect to
9093 	 * complete. i.e use sync API, so that the
9094 	 * vdev ref of MLME are cleaned and disconnect
9095 	 * complete before vdev is moved to logically
9096 	 * deleted.
9097 	 */
9098 	if (cds_is_driver_recovering())
9099 		reason = REASON_DEVICE_RECOVERY;
9100 	else
9101 		reason = REASON_IFACE_DOWN;
9102 
9103 	status = wlan_hdd_cm_issue_disconnect(link_info, reason, true);
9104 	if (QDF_IS_STATUS_ERROR(status) && ucfg_ipa_is_enabled()) {
9105 		hdd_err("STA disconnect failed");
9106 		ucfg_ipa_uc_cleanup_sta(adapter->hdd_ctx->pdev, adapter->dev);
9107 	}
9108 }
9109 
9110 static void
9111 hdd_disable_nan_active_disc(struct hdd_adapter *adapter)
9112 {
9113 	struct hdd_context *hdd_ctx = adapter->hdd_ctx;
9114 	enum QDF_OPMODE device_mode = adapter->device_mode;
9115 
9116 	if ((device_mode == QDF_NAN_DISC_MODE ||
9117 	     (device_mode == QDF_STA_MODE &&
9118 	      !ucfg_nan_is_vdev_creation_allowed(hdd_ctx->psoc))) &&
9119 	    ucfg_is_nan_conc_control_supported(hdd_ctx->psoc) &&
9120 	    ucfg_is_nan_disc_active(hdd_ctx->psoc))
9121 		ucfg_disable_nan_discovery(hdd_ctx->psoc, NULL, 0);
9122 }
9123 
9124 static void
9125 hdd_monitor_mode_release_wakelock(struct wlan_hdd_link_info *link_info)
9126 {
9127 	struct hdd_adapter *adapter = link_info->adapter;
9128 	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
9129 
9130 	if (wlan_hdd_is_session_type_monitor(adapter->device_mode) &&
9131 	    (ucfg_mlme_is_sta_mon_conc_supported(hdd_ctx->psoc) ||
9132 	     ucfg_dp_is_local_pkt_capture_enabled(hdd_ctx->psoc))) {
9133 		hdd_info("Release wakelock for STA + monitor mode!");
9134 		os_if_dp_local_pkt_capture_stop(link_info->vdev);
9135 		qdf_runtime_pm_allow_suspend(
9136 				&hdd_ctx->runtime_context.monitor_mode);
9137 		hdd_lpc_enable_powersave(hdd_ctx);
9138 		qdf_wake_lock_release(&hdd_ctx->monitor_mode_wakelock,
9139 				      WIFI_POWER_EVENT_WAKELOCK_MONITOR_MODE);
9140 	}
9141 }
9142 
9143 static void
9144 hdd_monitor_mode_disable_and_delete(struct wlan_hdd_link_info *link_info)
9145 {
9146 	QDF_STATUS status;
9147 	struct hdd_adapter *adapter = link_info->adapter;
9148 	struct hdd_context *hdd_ctx = adapter->hdd_ctx;
9149 
9150 	status = hdd_disable_monitor_mode();
9151 	if (QDF_IS_STATUS_ERROR(status))
9152 		hdd_err_rl("datapath reset failed for montior mode");
9153 	hdd_set_idle_ps_config(hdd_ctx, true);
9154 	status = hdd_monitor_mode_vdev_status(adapter);
9155 	if (QDF_IS_STATUS_ERROR(status))
9156 		hdd_err_rl("stop failed montior mode");
9157 	sme_delete_mon_session(hdd_ctx->mac_handle, link_info->vdev_id);
9158 }
9159 
9160 static void
9161 hdd_stop_and_close_pre_cac_adapter(struct hdd_context *hdd_ctx,
9162 				   struct wlan_objmgr_vdev *vdev)
9163 {
9164 	if (!vdev)
9165 		return;
9166 
9167 	if (!ucfg_pre_cac_adapter_is_active(vdev)) {
9168 		ucfg_pre_cac_stop(hdd_ctx->psoc);
9169 		hdd_close_pre_cac_adapter(hdd_ctx);
9170 	} else {
9171 		if (ucfg_pre_cac_set_status(vdev, false))
9172 			hdd_err("Failed to set is_pre_cac_on to false");
9173 	}
9174 }
9175 
9176 static void hdd_reset_ies_on_sap_stop(struct wlan_hdd_link_info *link_info)
9177 {
9178 	mac_handle_t mac_handle;
9179 	tSirUpdateIE update_ie;
9180 	QDF_STATUS status;
9181 	struct hdd_adapter *adapter = link_info->adapter;
9182 
9183 	mac_handle = hdd_adapter_get_mac_handle(adapter);
9184 	update_ie.vdev_id = link_info->vdev_id;
9185 	update_ie.ieBufferlength = 0;
9186 	update_ie.pAdditionIEBuffer = NULL;
9187 	update_ie.append = false;
9188 	update_ie.notify = false;
9189 
9190 	/* Probe bcn reset */
9191 	status = sme_update_add_ie(mac_handle, &update_ie,
9192 				   eUPDATE_IE_PROBE_BCN);
9193 	if (status == QDF_STATUS_E_FAILURE)
9194 		hdd_err("Could not pass PROBE_RSP_BCN to PE");
9195 
9196 	/* Assoc resp reset */
9197 	status = sme_update_add_ie(mac_handle, &update_ie,
9198 				   eUPDATE_IE_ASSOC_RESP);
9199 	if (status == QDF_STATUS_E_FAILURE)
9200 		hdd_err("Could not pass ASSOC_RSP to PE");
9201 
9202 	/* Reset WNI_CFG_PROBE_RSP Flags */
9203 	wlan_hdd_reset_prob_rspies(link_info);
9204 }
9205 
9206 static void hdd_stop_station_adapter(struct hdd_adapter *adapter)
9207 {
9208 	struct wlan_objmgr_vdev *vdev;
9209 	enum QDF_OPMODE mode;
9210 	struct wlan_hdd_link_info *link_info;
9211 
9212 	mode = adapter->device_mode;
9213 	hdd_adapter_for_each_active_link_info(adapter, link_info) {
9214 		vdev = hdd_objmgr_get_vdev_by_user(link_info,
9215 						   WLAN_INIT_DEINIT_ID);
9216 		if (!vdev)
9217 			continue;
9218 
9219 		if (mode == QDF_NDI_MODE)
9220 			hdd_stop_and_cleanup_ndi(link_info);
9221 		else if (!hdd_cm_is_disconnected(link_info))
9222 			hdd_sta_disconnect_and_cleanup(link_info);
9223 
9224 		hdd_reset_scan_operation(link_info);
9225 		wlan_hdd_cleanup_actionframe(link_info);
9226 		wlan_hdd_flush_pmksa_cache(link_info);
9227 
9228 		if (mode == QDF_STA_MODE)
9229 			ucfg_ipa_flush_pending_vdev_events(
9230 						wlan_vdev_get_pdev(vdev),
9231 						link_info->vdev_id);
9232 		hdd_objmgr_put_vdev_by_user(vdev, WLAN_INIT_DEINIT_ID);
9233 		hdd_vdev_destroy(link_info);
9234 	}
9235 
9236 	hdd_disable_nan_active_disc(adapter);
9237 	hdd_adapter_deregister_fc(adapter);
9238 	hdd_cancel_ip_notifier_work(adapter);
9239 }
9240 
9241 static int hdd_stop_mon_adapter(struct hdd_adapter *adapter)
9242 {
9243 	struct wlan_objmgr_vdev *vdev;
9244 	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
9245 	struct wlan_hdd_link_info *link_info = adapter->deflink;
9246 
9247 	vdev = hdd_objmgr_get_vdev_by_user(link_info,
9248 					   WLAN_INIT_DEINIT_ID);
9249 	if (wlan_hdd_is_session_type_monitor(adapter->device_mode) &&
9250 	    vdev &&
9251 	    ucfg_pkt_capture_get_mode(hdd_ctx->psoc) !=
9252 					PACKET_CAPTURE_MODE_DISABLE) {
9253 		struct hdd_adapter *sta_adapter;
9254 
9255 		ucfg_pkt_capture_deregister_callbacks(vdev);
9256 		hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_ID);
9257 		link_info->vdev = NULL;
9258 
9259 		sta_adapter = hdd_get_adapter(hdd_ctx, QDF_STA_MODE);
9260 		if (!sta_adapter) {
9261 			hdd_objmgr_put_vdev_by_user(vdev, WLAN_INIT_DEINIT_ID);
9262 			hdd_err("No station interface found");
9263 			return -EINVAL;
9264 		}
9265 		hdd_reset_monitor_interface(sta_adapter);
9266 	}
9267 
9268 	hdd_monitor_mode_release_wakelock(link_info);
9269 	wlan_hdd_scan_abort(link_info);
9270 	hdd_adapter_deregister_fc(adapter);
9271 	hdd_monitor_mode_disable_and_delete(link_info);
9272 	if (vdev)
9273 		hdd_objmgr_put_vdev_by_user(vdev, WLAN_INIT_DEINIT_ID);
9274 
9275 	hdd_vdev_destroy(link_info);
9276 
9277 	return 0;
9278 }
9279 
9280 static void hdd_stop_sap_go_adapter(struct hdd_adapter *adapter)
9281 {
9282 	enum QDF_OPMODE mode;
9283 	struct hdd_ap_ctx *ap_ctx;
9284 	struct sap_context *sap_ctx;
9285 	struct sap_config *sap_config;
9286 	struct hdd_hostapd_state *hostapd_state;
9287 	struct wlan_objmgr_vdev *vdev;
9288 	struct wlan_hdd_link_info *link_info = adapter->deflink;
9289 	QDF_STATUS status = QDF_STATUS_SUCCESS;
9290 	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
9291 
9292 	mode = adapter->device_mode;
9293 	ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(link_info);
9294 	sap_ctx = WLAN_HDD_GET_SAP_CTX_PTR(link_info);
9295 	vdev = hdd_objmgr_get_vdev_by_user(link_info, WLAN_INIT_DEINIT_ID);
9296 
9297 	if (mode == QDF_SAP_MODE) {
9298 		wlan_hdd_scan_abort(link_info);
9299 		hdd_abort_ongoing_sta_connection(hdd_ctx);
9300 		/* Diassociate with all the peers before stop ap post */
9301 		if (test_bit(SOFTAP_BSS_STARTED, &link_info->link_flags)) {
9302 			if (wlan_hdd_del_station(adapter, NULL))
9303 				hdd_sap_indicate_disconnect_for_sta(adapter);
9304 		}
9305 		wlan_hdd_flush_pmksa_cache(link_info);
9306 		sap_config = &ap_ctx->sap_config;
9307 		wlansap_reset_sap_config_add_ie(sap_config, eUPDATE_IE_ALL);
9308 		hdd_stop_and_close_pre_cac_adapter(hdd_ctx, vdev);
9309 	}
9310 	wlansap_cleanup_cac_timer(sap_ctx);
9311 	cds_flush_work(&adapter->sap_stop_bss_work);
9312 
9313 	if (qdf_atomic_read(&ap_ctx->acs_in_progress)) {
9314 		hdd_info("ACS in progress, wait for complete");
9315 		qdf_wait_for_event_completion(&link_info->acs_complete_event,
9316 					      ACS_COMPLETE_TIMEOUT);
9317 	}
9318 
9319 	if (mode == QDF_P2P_GO_MODE) {
9320 		wlan_hdd_cleanup_remain_on_channel_ctx(link_info);
9321 		hdd_abort_ongoing_sta_connection(hdd_ctx);
9322 	}
9323 
9324 	hdd_adapter_deregister_fc(adapter);
9325 	hdd_destroy_acs_timer(adapter);
9326 
9327 	mutex_lock(&hdd_ctx->sap_lock);
9328 	if (test_bit(SOFTAP_BSS_STARTED, &link_info->link_flags)) {
9329 		hostapd_state = WLAN_HDD_GET_HOSTAP_STATE_PTR(link_info);
9330 		qdf_event_reset(&hostapd_state->qdf_stop_bss_event);
9331 		status = wlansap_stop_bss(ap_ctx->sap_context);
9332 		if (QDF_IS_STATUS_SUCCESS(status)) {
9333 			status = qdf_wait_single_event(&hostapd_state->qdf_stop_bss_event,
9334 						       SME_CMD_STOP_BSS_TIMEOUT);
9335 			if (QDF_IS_STATUS_ERROR(status)) {
9336 				hdd_err("failure waiting for wlansap_stop_bss %d",
9337 					status);
9338 				hdd_ipa_ap_disconnect_evt(hdd_ctx, adapter);
9339 			}
9340 		} else {
9341 			hdd_err("failure in wlansap_stop_bss");
9342 		}
9343 
9344 		clear_bit(SOFTAP_BSS_STARTED, &link_info->link_flags);
9345 		policy_mgr_decr_session_set_pcl(hdd_ctx->psoc,
9346 						adapter->device_mode,
9347 						link_info->vdev_id);
9348 		hdd_green_ap_start_state_mc(hdd_ctx, adapter->device_mode,
9349 					    false);
9350 
9351 		hdd_reset_ies_on_sap_stop(link_info);
9352 	}
9353 
9354 	/*
9355 	 * Note to restart sap after SSR driver needs below information
9356 	 * and is not cleared/freed on purpose in case of SAP SSR
9357 	 */
9358 	if (!cds_is_driver_recovering()) {
9359 		clear_bit(SOFTAP_INIT_DONE, &link_info->link_flags);
9360 		qdf_mem_free(ap_ctx->beacon);
9361 		ap_ctx->beacon = NULL;
9362 	}
9363 	/* Clear all the cached sta info */
9364 	hdd_clear_cached_sta_info(adapter);
9365 
9366 	if (vdev && policy_mgr_is_dnsc_set(vdev))
9367 		wlan_hdd_send_avoid_freq_for_dnbs(hdd_ctx, 0);
9368 
9369 	hdd_cancel_ip_notifier_work(adapter);
9370 	sap_release_vdev_ref(sap_ctx);
9371 
9372 	if (mode == QDF_SAP_MODE)
9373 		ucfg_ipa_flush_pending_vdev_events(hdd_ctx->pdev,
9374 						   link_info->vdev_id);
9375 	if (vdev)
9376 		hdd_objmgr_put_vdev_by_user(vdev, WLAN_INIT_DEINIT_ID);
9377 	hdd_vdev_destroy(link_info);
9378 	mutex_unlock(&hdd_ctx->sap_lock);
9379 	ucfg_ipa_flush(hdd_ctx->pdev);
9380 }
9381 
9382 static void hdd_stop_ocb_adapter(struct hdd_adapter *adapter)
9383 {
9384 	struct hdd_station_ctx *sta_ctx;
9385 	struct wlan_objmgr_vdev *vdev;
9386 	struct wlan_hdd_link_info *link_info = adapter->deflink;
9387 
9388 	vdev = hdd_objmgr_get_vdev_by_user(link_info, WLAN_INIT_DEINIT_ID);
9389 	sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(link_info);
9390 	cdp_clear_peer(cds_get_context(QDF_MODULE_ID_SOC), OL_TXRX_PDEV_ID,
9391 		       sta_ctx->conn_info.peer_macaddr[0]);
9392 	hdd_adapter_deregister_fc(adapter);
9393 	if (vdev)
9394 		hdd_objmgr_put_vdev_by_user(vdev, WLAN_INIT_DEINIT_ID);
9395 	hdd_vdev_destroy(link_info);
9396 }
9397 
9398 QDF_STATUS hdd_stop_adapter_ext(struct hdd_context *hdd_ctx,
9399 				struct hdd_adapter *adapter)
9400 {
9401 	QDF_STATUS status;
9402 	struct wlan_hdd_link_info *link_info = adapter->deflink;
9403 
9404 	hdd_enter();
9405 	hdd_destroy_adapter_sysfs_files(adapter);
9406 
9407 	if (adapter->device_mode == QDF_STA_MODE &&
9408 	    hdd_is_pkt_capture_mon_enable(adapter) &&
9409 	    ucfg_pkt_capture_get_mode(hdd_ctx->psoc) !=
9410 						PACKET_CAPTURE_MODE_DISABLE) {
9411 		hdd_unmap_monitor_interface_vdev(adapter);
9412 	}
9413 
9414 	if (link_info->vdev_id != WLAN_UMAC_VDEV_ID_MAX)
9415 		wlan_hdd_cfg80211_deregister_frames(adapter);
9416 
9417 	hdd_stop_tsf_sync(adapter);
9418 	cds_flush_work(&adapter->scan_block_work);
9419 	wlan_hdd_cfg80211_scan_block(adapter);
9420 	hdd_debug("Disabling queues");
9421 	wlan_hdd_netif_queue_control(adapter,
9422 				     WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER,
9423 				     WLAN_CONTROL_PATH);
9424 
9425 	switch (adapter->device_mode) {
9426 	case QDF_STA_MODE:
9427 	case QDF_P2P_CLIENT_MODE:
9428 	case QDF_NDI_MODE:
9429 	case QDF_P2P_DEVICE_MODE:
9430 	case QDF_NAN_DISC_MODE:
9431 		hdd_stop_station_adapter(adapter);
9432 		break;
9433 	case QDF_MONITOR_MODE:
9434 		status = hdd_stop_mon_adapter(adapter);
9435 		if (QDF_IS_STATUS_ERROR(status))
9436 			return status;
9437 
9438 		break;
9439 	case QDF_SAP_MODE:
9440 	case QDF_P2P_GO_MODE:
9441 		hdd_stop_sap_go_adapter(adapter);
9442 		break;
9443 	case QDF_OCB_MODE:
9444 		hdd_stop_ocb_adapter(adapter);
9445 		break;
9446 	default:
9447 		break;
9448 	}
9449 
9450 	/* Moved from vdev destroy as it is per adapter */
9451 	wlan_cfg80211_cleanup_scan_queue(hdd_ctx->pdev, adapter->dev);
9452 
9453 	/* Disable all links (expect default index) in adapter.
9454 	 * Set link address to NULL
9455 	 */
9456 	hdd_adapter_disable_all_links(adapter);
9457 
9458 	/* This function should be invoked at the end of this api*/
9459 	hdd_dump_func_call_map();
9460 	hdd_exit();
9461 
9462 	return QDF_STATUS_SUCCESS;
9463 }
9464 
9465 QDF_STATUS hdd_stop_adapter(struct hdd_context *hdd_ctx,
9466 			    struct hdd_adapter *adapter)
9467 {
9468 	QDF_STATUS status;
9469 
9470 	if (adapter->device_mode == QDF_STA_MODE)
9471 		status = hdd_stop_link_adapter(hdd_ctx, adapter);
9472 
9473 	status = hdd_stop_adapter_ext(hdd_ctx, adapter);
9474 
9475 	return status;
9476 }
9477 
9478 /**
9479  * hdd_deinit_all_adapters - deinit all adapters
9480  * @hdd_ctx:   HDD context
9481  * @rtnl_held: True if RTNL lock held
9482  *
9483  */
9484 void  hdd_deinit_all_adapters(struct hdd_context *hdd_ctx, bool rtnl_held)
9485 {
9486 	struct hdd_adapter *adapter, *next_adapter = NULL;
9487 
9488 	hdd_enter();
9489 
9490 	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
9491 					   NET_DEV_HOLD_DEINIT_ALL_ADAPTERS) {
9492 		hdd_deinit_adapter(hdd_ctx, adapter, rtnl_held);
9493 		hdd_adapter_dev_put_debug(adapter,
9494 					  NET_DEV_HOLD_DEINIT_ALL_ADAPTERS);
9495 	}
9496 
9497 	hdd_exit();
9498 }
9499 
9500 QDF_STATUS hdd_stop_all_adapters(struct hdd_context *hdd_ctx)
9501 {
9502 	struct hdd_adapter *adapter, *next_adapter = NULL;
9503 
9504 	hdd_enter();
9505 
9506 	ucfg_pre_cac_stop(hdd_ctx->psoc);
9507 	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
9508 					   NET_DEV_HOLD_STOP_ALL_ADAPTERS) {
9509 		hdd_stop_adapter(hdd_ctx, adapter);
9510 		hdd_adapter_dev_put_debug(adapter,
9511 					  NET_DEV_HOLD_STOP_ALL_ADAPTERS);
9512 	}
9513 
9514 	hdd_exit();
9515 
9516 	return QDF_STATUS_SUCCESS;
9517 }
9518 
9519 void hdd_set_netdev_flags(struct hdd_adapter *adapter)
9520 {
9521 	bool enable_csum = false;
9522 	bool enable_lro;
9523 	enum QDF_OPMODE device_mode;
9524 	struct hdd_context *hdd_ctx;
9525 	ol_txrx_soc_handle soc;
9526 	uint64_t temp;
9527 
9528 	if (!adapter || !adapter->dev) {
9529 		hdd_err("invalid input!");
9530 		return;
9531 	}
9532 	device_mode = adapter->device_mode;
9533 
9534 	hdd_ctx = adapter->hdd_ctx;
9535 	soc = cds_get_context(QDF_MODULE_ID_SOC);
9536 
9537 	if (!soc || !hdd_ctx) {
9538 		hdd_err("invalid SOC or HDD context!");
9539 		return;
9540 	}
9541 
9542 	/* Determine device_mode specific configuration */
9543 
9544 	enable_lro = !!cdp_cfg_get(soc, cfg_dp_lro_enable);
9545 	enable_csum = !!cdp_cfg_get(soc,
9546 				     cfg_dp_enable_ip_tcp_udp_checksum_offload);
9547 	switch (device_mode) {
9548 	case QDF_P2P_DEVICE_MODE:
9549 	case QDF_P2P_CLIENT_MODE:
9550 		enable_csum = !!cdp_cfg_get(soc,
9551 					    cfg_dp_enable_p2p_ip_tcp_udp_checksum_offload);
9552 		break;
9553 	case QDF_P2P_GO_MODE:
9554 		enable_csum = !!cdp_cfg_get(soc,
9555 					    cfg_dp_enable_p2p_ip_tcp_udp_checksum_offload);
9556 		enable_lro = false;
9557 		break;
9558 	case QDF_SAP_MODE:
9559 		enable_lro = false;
9560 		break;
9561 	case QDF_NDI_MODE:
9562 	case QDF_NAN_DISC_MODE:
9563 		enable_csum = !!cdp_cfg_get(soc,
9564 					    cfg_dp_enable_nan_ip_tcp_udp_checksum_offload);
9565 		break;
9566 	default:
9567 		break;
9568 	}
9569 
9570 	/* Set netdev flags */
9571 
9572 	/*
9573 	 * In case of USB tethering, LRO is disabled. If SSR happened
9574 	 * during that time, then as part of SSR init, do not enable
9575 	 * the LRO again. Keep the LRO state same as before SSR.
9576 	 */
9577 	if (enable_lro && !(qdf_atomic_read(&hdd_ctx->vendor_disable_lro_flag)))
9578 		adapter->dev->features |= NETIF_F_LRO;
9579 
9580 	if (enable_csum)
9581 		adapter->dev->features |=
9582 			(NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM);
9583 
9584 	if (cdp_cfg_get(soc, cfg_dp_tso_enable) && enable_csum) {
9585 		adapter->dev->features |= TSO_FEATURE_FLAGS;
9586 		adapter->tso_csum_feature_enabled = 1;
9587 	}
9588 
9589 	if (cdp_cfg_get(soc, cfg_dp_sg_enable))
9590 		adapter->dev->features |= NETIF_F_SG;
9591 
9592 	adapter->dev->features |= NETIF_F_RXCSUM;
9593 	temp = (uint64_t)adapter->dev->features;
9594 
9595 	hdd_debug("adapter mode %u dev feature 0x%llx", device_mode, temp);
9596 }
9597 
9598 #ifdef QCA_LL_LEGACY_TX_FLOW_CONTROL
9599 /**
9600  * hdd_adapter_abort_tx_flow() - Abort the tx flow control
9601  * @adapter: pointer to hdd adapter
9602  *
9603  * Resume tx and stop the tx flow control timer if the tx is paused
9604  * and the flow control timer is running. This function is called by
9605  * SSR to avoid the inconsistency of tx status before and after SSR.
9606  *
9607  * Return: void
9608  */
9609 static void hdd_adapter_abort_tx_flow(struct hdd_adapter *adapter)
9610 {
9611 	if (adapter->deflink->hdd_stats.tx_rx_stats.is_txflow_paused &&
9612 	    QDF_TIMER_STATE_RUNNING ==
9613 		qdf_mc_timer_get_current_state(
9614 			&adapter->tx_flow_control_timer)) {
9615 		hdd_tx_resume_timer_expired_handler(adapter);
9616 		qdf_mc_timer_stop(&adapter->tx_flow_control_timer);
9617 	}
9618 }
9619 #else
9620 static void hdd_adapter_abort_tx_flow(struct hdd_adapter *adapter)
9621 {
9622 }
9623 #endif
9624 
9625 QDF_STATUS hdd_reset_all_adapters(struct hdd_context *hdd_ctx)
9626 {
9627 	struct hdd_adapter *adapter, *next_adapter = NULL;
9628 	bool value;
9629 	struct wlan_objmgr_vdev *vdev;
9630 	struct wlan_hdd_link_info *link_info;
9631 
9632 	hdd_enter();
9633 
9634 	ucfg_mlme_get_sap_internal_restart(hdd_ctx->psoc, &value);
9635 
9636 
9637 	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
9638 					   NET_DEV_HOLD_RESET_ALL_ADAPTERS) {
9639 		hdd_info("[SSR] reset adapter with device mode %s(%d)",
9640 			 qdf_opmode_str(adapter->device_mode),
9641 			 adapter->device_mode);
9642 
9643 		hdd_adapter_for_each_active_link_info(adapter, link_info) {
9644 			hdd_adapter_abort_tx_flow(adapter);
9645 
9646 			if ((adapter->device_mode == QDF_STA_MODE) ||
9647 			    (adapter->device_mode == QDF_P2P_CLIENT_MODE)) {
9648 				hdd_send_twt_del_all_sessions_to_userspace(link_info);
9649 
9650 				/* Stop tdls timers */
9651 				vdev = hdd_objmgr_get_vdev_by_user(link_info,
9652 							   WLAN_OSIF_TDLS_ID);
9653 				if (vdev) {
9654 					hdd_notify_tdls_reset_adapter(vdev);
9655 					hdd_objmgr_put_vdev_by_user(vdev,
9656 							    WLAN_OSIF_TDLS_ID);
9657 				}
9658 			}
9659 
9660 			if (value &&
9661 			    adapter->device_mode == QDF_SAP_MODE) {
9662 				hdd_medium_assess_ssr_enable_flag();
9663 				wlan_hdd_netif_queue_control(adapter,
9664 						     WLAN_STOP_ALL_NETIF_QUEUE,
9665 						     WLAN_CONTROL_PATH);
9666 			} else {
9667 				wlan_hdd_netif_queue_control(adapter,
9668 					   WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER,
9669 					   WLAN_CONTROL_PATH);
9670 			}
9671 
9672 			/*
9673 			 * Clear fc flag if it was set before SSR to avoid
9674 			 * TX queues permanently stopped after SSR.
9675 			 * Here WLAN_START_ALL_NETIF_QUEUE will actually
9676 			 * not start any queue since it's blocked by reason
9677 			 * WLAN_CONTROL_PATH.
9678 			 */
9679 			if (adapter->pause_map & (1 << WLAN_DATA_FLOW_CONTROL))
9680 				wlan_hdd_netif_queue_control(adapter,
9681 						     WLAN_START_ALL_NETIF_QUEUE,
9682 						     WLAN_DATA_FLOW_CONTROL);
9683 
9684 			hdd_reset_scan_operation(link_info);
9685 
9686 			if (test_bit(WMM_INIT_DONE, &adapter->event_flags)) {
9687 				hdd_wmm_adapter_close(adapter);
9688 				clear_bit(WMM_INIT_DONE, &adapter->event_flags);
9689 			}
9690 
9691 			hdd_debug("Flush any mgmt references held by peer");
9692 			hdd_stop_adapter(hdd_ctx, adapter);
9693 		}
9694 		hdd_adapter_dev_put_debug(adapter,
9695 					  NET_DEV_HOLD_RESET_ALL_ADAPTERS);
9696 	}
9697 
9698 	hdd_exit();
9699 
9700 	return QDF_STATUS_SUCCESS;
9701 }
9702 
9703 static bool hdd_is_any_link_opened(struct hdd_adapter *adapter)
9704 {
9705 	struct wlan_hdd_link_info *link_info;
9706 
9707 	hdd_adapter_for_each_active_link_info(adapter, link_info) {
9708 		if (test_bit(SME_SESSION_OPENED, &link_info->link_flags))
9709 			return true;
9710 	}
9711 	return false;
9712 }
9713 
9714 bool hdd_is_any_interface_open(struct hdd_context *hdd_ctx)
9715 {
9716 	struct hdd_adapter *adapter, *next_adapter = NULL;
9717 	wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_IS_ANY_INTERFACE_OPEN;
9718 
9719 	if (hdd_get_conparam() == QDF_GLOBAL_FTM_MODE) {
9720 		hdd_info("FTM mode, don't close the module");
9721 		return true;
9722 	}
9723 
9724 	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
9725 					   dbgid) {
9726 		if (test_bit(DEVICE_IFACE_OPENED, &adapter->event_flags) ||
9727 		    hdd_is_any_link_opened(adapter)) {
9728 			hdd_adapter_dev_put_debug(adapter, dbgid);
9729 			if (next_adapter)
9730 				hdd_adapter_dev_put_debug(next_adapter, dbgid);
9731 			return true;
9732 		}
9733 		hdd_adapter_dev_put_debug(adapter, dbgid);
9734 	}
9735 
9736 	return false;
9737 }
9738 
9739 bool hdd_is_interface_up(struct hdd_adapter *adapter)
9740 {
9741 	if (test_bit(DEVICE_IFACE_OPENED, &adapter->event_flags))
9742 		return true;
9743 	else
9744 		return false;
9745 }
9746 
9747 #ifdef FEATURE_MONITOR_MODE_SUPPORT
9748 #ifdef WLAN_FEATURE_11BE
9749 static inline bool wlan_hdd_is_mon_channel_bw_valid(enum phy_ch_width ch_width)
9750 {
9751 	if (ch_width > CH_WIDTH_320MHZ ||
9752 	    (!cds_is_sub_20_mhz_enabled() && (ch_width == CH_WIDTH_5MHZ ||
9753 					      ch_width == CH_WIDTH_10MHZ)))
9754 		return false;
9755 
9756 	return true;
9757 }
9758 #else
9759 static inline bool wlan_hdd_is_mon_channel_bw_valid(enum phy_ch_width ch_width)
9760 {
9761 	if (ch_width > CH_WIDTH_10MHZ ||
9762 	    (!cds_is_sub_20_mhz_enabled() && (ch_width == CH_WIDTH_5MHZ ||
9763 					      ch_width == CH_WIDTH_10MHZ)))
9764 		return false;
9765 
9766 	return true;
9767 }
9768 #endif
9769 
9770 int wlan_hdd_set_mon_chan(struct hdd_adapter *adapter, qdf_freq_t freq,
9771 			  uint32_t bandwidth)
9772 {
9773 	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
9774 	struct hdd_station_ctx *sta_ctx;
9775 	struct hdd_mon_set_ch_info *ch_info;
9776 	QDF_STATUS status;
9777 	struct qdf_mac_addr bssid;
9778 	struct channel_change_req *req;
9779 	struct ch_params ch_params;
9780 	enum phy_ch_width max_fw_bw;
9781 	enum phy_ch_width ch_width;
9782 	int ret;
9783 
9784 	if ((hdd_get_conparam() != QDF_GLOBAL_MONITOR_MODE) &&
9785 	    (!policy_mgr_is_sta_mon_concurrency(hdd_ctx->psoc))) {
9786 		hdd_err("Not supported, device is not in monitor mode");
9787 		return -EINVAL;
9788 	}
9789 
9790 	if (adapter->device_mode != QDF_MONITOR_MODE) {
9791 		hdd_err_rl("Not supported, adapter is not in monitor mode");
9792 		return -EINVAL;
9793 	}
9794 
9795 	sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter->deflink);
9796 	ch_info = &sta_ctx->ch_info;
9797 
9798 	/* Verify the BW before accepting this request */
9799 	ch_width = bandwidth;
9800 
9801 	if (!wlan_hdd_is_mon_channel_bw_valid(ch_width)) {
9802 		hdd_err("invalid BW received %d", ch_width);
9803 		return -EINVAL;
9804 	}
9805 
9806 	max_fw_bw = sme_get_vht_ch_width();
9807 
9808 	hdd_debug("max fw BW %d ch width %d", max_fw_bw, ch_width);
9809 	if ((ch_width == CH_WIDTH_160MHZ &&
9810 	    max_fw_bw <= WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ) ||
9811 	    (ch_width == CH_WIDTH_80P80MHZ &&
9812 	    max_fw_bw <= WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ)) {
9813 		hdd_err("FW does not support this BW %d max BW supported %d",
9814 			ch_width, max_fw_bw);
9815 		return -EINVAL;
9816 	}
9817 
9818 	if (!hdd_is_target_eht_phy_ch_width_supported(ch_width))
9819 		return -EINVAL;
9820 
9821 	ret = hdd_validate_channel_and_bandwidth(adapter, freq, bandwidth);
9822 	if (ret) {
9823 		hdd_err("Invalid CH and BW combo");
9824 		return ret;
9825 	}
9826 
9827 	hdd_debug("Set monitor mode frequency %d", freq);
9828 	qdf_mem_copy(bssid.bytes, adapter->mac_addr.bytes,
9829 		     QDF_MAC_ADDR_SIZE);
9830 
9831 	ch_params.ch_width = bandwidth;
9832 	wlan_reg_set_channel_params_for_pwrmode(hdd_ctx->pdev, freq, 0,
9833 						&ch_params,
9834 						REG_CURRENT_PWR_MODE);
9835 
9836 	if (ch_params.ch_width == CH_WIDTH_INVALID) {
9837 		hdd_err("Invalid capture channel or bandwidth for a country");
9838 		return -EINVAL;
9839 	}
9840 	if (wlan_hdd_change_hw_mode_for_given_chnl(adapter, freq,
9841 						   POLICY_MGR_UPDATE_REASON_SET_OPER_CHAN)) {
9842 		hdd_err("Failed to change hw mode");
9843 		return -EINVAL;
9844 	}
9845 
9846 	if (adapter->monitor_mode_vdev_up_in_progress) {
9847 		hdd_err_rl("monitor mode vdev up in progress");
9848 		return -EBUSY;
9849 	}
9850 
9851 	status = qdf_event_reset(&adapter->qdf_monitor_mode_vdev_up_event);
9852 	if (QDF_IS_STATUS_ERROR(status)) {
9853 		hdd_err_rl("failed to reinit monitor mode vdev up event");
9854 		return qdf_status_to_os_return(status);
9855 	}
9856 	adapter->monitor_mode_vdev_up_in_progress = true;
9857 
9858 	qdf_mem_zero(&ch_params, sizeof(struct ch_params));
9859 
9860 	req = qdf_mem_malloc(sizeof(struct channel_change_req));
9861 	if (!req)
9862 		return -ENOMEM;
9863 	req->vdev_id = adapter->deflink->vdev_id;
9864 	req->target_chan_freq = freq;
9865 	req->ch_width = ch_width;
9866 
9867 	ch_params.ch_width = ch_width;
9868 	hdd_select_cbmode(adapter, freq, 0, &ch_params);
9869 
9870 	req->sec_ch_offset = ch_params.sec_ch_offset;
9871 	req->center_freq_seg0 = ch_params.center_freq_seg0;
9872 	req->center_freq_seg1 = ch_params.center_freq_seg1;
9873 
9874 	sme_fill_channel_change_request(hdd_ctx->mac_handle, req,
9875 					ch_info->phy_mode);
9876 	status = sme_send_channel_change_req(hdd_ctx->mac_handle, req);
9877 	qdf_mem_free(req);
9878 	if (status) {
9879 		hdd_err("Status: %d Failed to set sme_roam Channel for monitor mode",
9880 			status);
9881 		adapter->monitor_mode_vdev_up_in_progress = false;
9882 		return qdf_status_to_os_return(status);
9883 	}
9884 
9885 	adapter->mon_chan_freq = freq;
9886 	adapter->mon_bandwidth = bandwidth;
9887 
9888 	/* block on a completion variable until vdev up success*/
9889 	status = qdf_wait_for_event_completion(
9890 				       &adapter->qdf_monitor_mode_vdev_up_event,
9891 					WLAN_MONITOR_MODE_VDEV_UP_EVT);
9892 	if (QDF_IS_STATUS_ERROR(status)) {
9893 		hdd_err_rl("monitor vdev up event time out vdev id: %d",
9894 			    adapter->deflink->vdev_id);
9895 		if (adapter->qdf_monitor_mode_vdev_up_event.force_set)
9896 			/*
9897 			 * SSR/PDR has caused shutdown, which has
9898 			 * forcefully set the event.
9899 			 */
9900 			hdd_err_rl("monitor mode vdev up event forcefully set");
9901 		else if (status == QDF_STATUS_E_TIMEOUT)
9902 			hdd_err("monitor mode vdev up timed out");
9903 		else
9904 			hdd_err_rl("Failed monitor mode vdev up(status-%d)",
9905 				  status);
9906 
9907 		adapter->monitor_mode_vdev_up_in_progress = false;
9908 	}
9909 
9910 	return qdf_status_to_os_return(status);
9911 }
9912 #endif
9913 
9914 #if defined MSM_PLATFORM && (LINUX_VERSION_CODE <= KERNEL_VERSION(4, 19, 0))
9915 /**
9916  * hdd_stop_p2p_go() - call cfg80211 API to stop P2P GO
9917  * @adapter: pointer to adapter
9918  *
9919  * This function calls cfg80211 API to stop P2P GO
9920  *
9921  * Return: None
9922  */
9923 static void hdd_stop_p2p_go(struct hdd_adapter *adapter)
9924 {
9925 	hdd_debug("[SSR] send stop ap to supplicant");
9926 	cfg80211_ap_stopped(adapter->dev, GFP_KERNEL);
9927 }
9928 
9929 static inline void hdd_delete_sta(struct hdd_adapter *adapter)
9930 {
9931 }
9932 
9933 #else
9934 static void hdd_stop_p2p_go(struct hdd_adapter *adapter)
9935 {
9936 	hdd_debug("[SSR] send stop iface ap to supplicant");
9937 	cfg80211_stop_iface(adapter->hdd_ctx->wiphy, &adapter->wdev,
9938 			    GFP_KERNEL);
9939 }
9940 
9941 /**
9942  * hdd_delete_sta() - call cfg80211 API to delete STA
9943  * @adapter: pointer to adapter
9944  *
9945  * This function calls cfg80211 API to delete STA
9946  *
9947  * Return: None
9948  */
9949 static void hdd_delete_sta(struct hdd_adapter *adapter)
9950 {
9951 	struct qdf_mac_addr bcast_mac = QDF_MAC_ADDR_BCAST_INIT;
9952 
9953 	hdd_debug("[SSR] send restart supplicant");
9954 	/* event supplicant to restart */
9955 	cfg80211_del_sta(adapter->dev,
9956 			 (const u8 *)&bcast_mac.bytes[0],
9957 			 GFP_KERNEL);
9958 }
9959 #endif
9960 
9961 QDF_STATUS hdd_start_all_adapters(struct hdd_context *hdd_ctx, bool rtnl_held)
9962 {
9963 	struct hdd_adapter *adapter, *next_adapter = NULL;
9964 	bool value;
9965 	wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_START_ALL_ADAPTERS;
9966 	int ret;
9967 
9968 	hdd_enter();
9969 
9970 	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
9971 					   dbgid) {
9972 		if (!hdd_is_interface_up(adapter) &&
9973 		    adapter->device_mode != QDF_NDI_MODE) {
9974 			hdd_adapter_dev_put_debug(adapter, dbgid);
9975 			continue;
9976 		}
9977 
9978 		hdd_debug("[SSR] start adapter with device mode %s(%d)",
9979 			  qdf_opmode_str(adapter->device_mode),
9980 			  adapter->device_mode);
9981 
9982 		hdd_wmm_dscp_initial_state(adapter);
9983 
9984 		switch (adapter->device_mode) {
9985 		case QDF_STA_MODE:
9986 		case QDF_P2P_CLIENT_MODE:
9987 		case QDF_P2P_DEVICE_MODE:
9988 		case QDF_NAN_DISC_MODE:
9989 
9990 			ret = hdd_start_station_adapter(adapter);
9991 			if (ret) {
9992 				hdd_err("[SSR] Failed to start station adapter: %d",
9993 					ret);
9994 				hdd_adapter_dev_put_debug(adapter, dbgid);
9995 				continue;
9996 			}
9997 			if (adapter->device_mode == QDF_STA_MODE) {
9998 				ret = hdd_start_link_adapter(adapter);
9999 				if (ret) {
10000 					hdd_err("[SSR] Failed to start link adapter: %d",
10001 						ret);
10002 					hdd_stop_adapter(hdd_ctx, adapter);
10003 					hdd_adapter_dev_put_debug(adapter,
10004 								  dbgid);
10005 					continue;
10006 				}
10007 			}
10008 
10009 			/* Open the gates for HDD to receive Wext commands */
10010 			adapter->is_link_up_service_needed = false;
10011 
10012 			if ((adapter->device_mode == QDF_NAN_DISC_MODE ||
10013 			     (adapter->device_mode == QDF_STA_MODE &&
10014 			      !ucfg_nan_is_vdev_creation_allowed(
10015 							hdd_ctx->psoc))) &&
10016 			    cds_is_driver_recovering())
10017 				ucfg_nan_disable_ind_to_userspace(
10018 							hdd_ctx->psoc);
10019 
10020 			hdd_register_tx_flow_control(adapter,
10021 					hdd_tx_resume_timer_expired_handler,
10022 					hdd_tx_resume_cb,
10023 					hdd_tx_flow_control_is_pause);
10024 
10025 			hdd_register_hl_netdev_fc_timer(
10026 					adapter,
10027 					hdd_tx_resume_timer_expired_handler);
10028 
10029 			hdd_lpass_notify_start(adapter->deflink);
10030 			break;
10031 
10032 		case QDF_SAP_MODE:
10033 			ucfg_mlme_get_sap_internal_restart(hdd_ctx->psoc,
10034 							   &value);
10035 			if (value)
10036 				hdd_start_ap_adapter(adapter, rtnl_held);
10037 
10038 			break;
10039 
10040 		case QDF_P2P_GO_MODE:
10041 			hdd_delete_sta(adapter);
10042 			break;
10043 		case QDF_MONITOR_MODE:
10044 			if (wlan_hdd_is_session_type_monitor(
10045 			    adapter->device_mode) &&
10046 			    ucfg_pkt_capture_get_mode(hdd_ctx->psoc) !=
10047 						PACKET_CAPTURE_MODE_DISABLE) {
10048 				struct hdd_adapter *sta_adapter;
10049 
10050 				sta_adapter = hdd_get_adapter(hdd_ctx,
10051 							      QDF_STA_MODE);
10052 				if (!sta_adapter) {
10053 					hdd_err("No station interface found");
10054 					return -EINVAL;
10055 				}
10056 
10057 				hdd_map_monitor_interface_vdev(sta_adapter);
10058 				break;
10059 			}
10060 			hdd_start_station_adapter(adapter);
10061 			hdd_set_mon_rx_cb(adapter->dev);
10062 
10063 			wlan_hdd_set_mon_chan(
10064 					adapter, adapter->mon_chan_freq,
10065 					adapter->mon_bandwidth);
10066 			break;
10067 		case QDF_NDI_MODE:
10068 			hdd_ndi_start(adapter->dev->name, 0);
10069 			break;
10070 		default:
10071 			break;
10072 		}
10073 		/*
10074 		 * Action frame registered in one adapter which will
10075 		 * applicable to all interfaces
10076 		 */
10077 		if (hdd_set_fw_params(adapter))
10078 			hdd_err("Failed to set adapter FW params after SSR!");
10079 
10080 		wlan_hdd_cfg80211_register_frames(adapter);
10081 		hdd_create_adapter_sysfs_files(adapter);
10082 		hdd_adapter_dev_put_debug(adapter, dbgid);
10083 	}
10084 
10085 	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
10086 					   dbgid) {
10087 		if (!hdd_is_interface_up(adapter)) {
10088 			hdd_adapter_dev_put_debug(adapter, dbgid);
10089 			continue;
10090 		}
10091 
10092 		if (adapter->device_mode == QDF_P2P_GO_MODE)
10093 			hdd_stop_p2p_go(adapter);
10094 
10095 		hdd_adapter_dev_put_debug(adapter, dbgid);
10096 	}
10097 
10098 	hdd_exit();
10099 
10100 	return QDF_STATUS_SUCCESS;
10101 }
10102 
10103 void hdd_adapter_dev_hold_debug(struct hdd_adapter *adapter,
10104 				wlan_net_dev_ref_dbgid dbgid)
10105 {
10106 	if (dbgid >= NET_DEV_HOLD_ID_MAX) {
10107 		hdd_err("Invalid debug id: %d", dbgid);
10108 		QDF_BUG(0);
10109 	}
10110 	dev_hold(adapter->dev);
10111 	qdf_atomic_inc(&adapter->net_dev_hold_ref_count[dbgid]);
10112 }
10113 
10114 void hdd_adapter_dev_put_debug(struct hdd_adapter *adapter,
10115 			       wlan_net_dev_ref_dbgid dbgid)
10116 {
10117 	if (dbgid >= NET_DEV_HOLD_ID_MAX) {
10118 		hdd_err("Invalid debug id: %d", dbgid);
10119 		QDF_BUG(0);
10120 	}
10121 
10122 	if (qdf_atomic_dec_return(
10123 			&adapter->net_dev_hold_ref_count[dbgid]) < 0) {
10124 		hdd_err("dev_put detected without dev_hold for debug id: %s",
10125 			net_dev_ref_debug_string_from_id(dbgid));
10126 		QDF_BUG(0);
10127 	}
10128 
10129 	if (adapter->dev) {
10130 		dev_put(adapter->dev);
10131 	} else {
10132 		hdd_err("adapter->dev is NULL");
10133 		QDF_BUG(0);
10134 	}
10135 }
10136 
10137 QDF_STATUS hdd_get_front_adapter(struct hdd_context *hdd_ctx,
10138 				 struct hdd_adapter **out_adapter)
10139 {
10140 	QDF_STATUS status;
10141 	qdf_list_node_t *node;
10142 
10143 	*out_adapter = NULL;
10144 
10145 	qdf_spin_lock_bh(&hdd_ctx->hdd_adapter_lock);
10146 	status = qdf_list_peek_front(&hdd_ctx->hdd_adapters, &node);
10147 	qdf_spin_unlock_bh(&hdd_ctx->hdd_adapter_lock);
10148 
10149 	if (QDF_IS_STATUS_ERROR(status))
10150 		return status;
10151 
10152 	*out_adapter = qdf_container_of(node, struct hdd_adapter, node);
10153 
10154 	return QDF_STATUS_SUCCESS;
10155 }
10156 
10157 QDF_STATUS hdd_get_next_adapter(struct hdd_context *hdd_ctx,
10158 				struct hdd_adapter *current_adapter,
10159 				struct hdd_adapter **out_adapter)
10160 {
10161 	QDF_STATUS status;
10162 	qdf_list_node_t *node;
10163 
10164 	*out_adapter = NULL;
10165 
10166 	qdf_spin_lock_bh(&hdd_ctx->hdd_adapter_lock);
10167 	status = qdf_list_peek_next(&hdd_ctx->hdd_adapters,
10168 				    &current_adapter->node,
10169 				    &node);
10170 	qdf_spin_unlock_bh(&hdd_ctx->hdd_adapter_lock);
10171 
10172 	if (QDF_IS_STATUS_ERROR(status))
10173 		return status;
10174 
10175 	*out_adapter = qdf_container_of(node, struct hdd_adapter, node);
10176 
10177 	return status;
10178 }
10179 
10180 QDF_STATUS hdd_get_front_adapter_no_lock(struct hdd_context *hdd_ctx,
10181 					 struct hdd_adapter **out_adapter)
10182 {
10183 	QDF_STATUS status;
10184 	qdf_list_node_t *node;
10185 
10186 	*out_adapter = NULL;
10187 
10188 	status = qdf_list_peek_front(&hdd_ctx->hdd_adapters, &node);
10189 
10190 	if (QDF_IS_STATUS_ERROR(status))
10191 		return status;
10192 
10193 	*out_adapter = qdf_container_of(node, struct hdd_adapter, node);
10194 
10195 	return QDF_STATUS_SUCCESS;
10196 }
10197 
10198 QDF_STATUS hdd_get_next_adapter_no_lock(struct hdd_context *hdd_ctx,
10199 					struct hdd_adapter *current_adapter,
10200 					struct hdd_adapter **out_adapter)
10201 {
10202 	QDF_STATUS status;
10203 	qdf_list_node_t *node;
10204 
10205 	if (!current_adapter)
10206 		return QDF_STATUS_E_INVAL;
10207 
10208 	*out_adapter = NULL;
10209 
10210 	status = qdf_list_peek_next(&hdd_ctx->hdd_adapters,
10211 				    &current_adapter->node,
10212 				    &node);
10213 
10214 	if (QDF_IS_STATUS_ERROR(status))
10215 		return status;
10216 
10217 	*out_adapter = qdf_container_of(node, struct hdd_adapter, node);
10218 
10219 	return status;
10220 }
10221 
10222 QDF_STATUS hdd_remove_adapter(struct hdd_context *hdd_ctx,
10223 			      struct hdd_adapter *adapter)
10224 {
10225 	QDF_STATUS status;
10226 
10227 	qdf_spin_lock_bh(&hdd_ctx->hdd_adapter_lock);
10228 	status = qdf_list_remove_node(&hdd_ctx->hdd_adapters, &adapter->node);
10229 	qdf_spin_unlock_bh(&hdd_ctx->hdd_adapter_lock);
10230 
10231 	return status;
10232 }
10233 
10234 QDF_STATUS hdd_remove_front_adapter(struct hdd_context *hdd_ctx,
10235 				    struct hdd_adapter **out_adapter)
10236 {
10237 	QDF_STATUS status;
10238 	qdf_list_node_t *node;
10239 
10240 	*out_adapter = NULL;
10241 
10242 	qdf_spin_lock_bh(&hdd_ctx->hdd_adapter_lock);
10243 	status = qdf_list_remove_front(&hdd_ctx->hdd_adapters, &node);
10244 	qdf_spin_unlock_bh(&hdd_ctx->hdd_adapter_lock);
10245 
10246 	if (QDF_IS_STATUS_ERROR(status))
10247 		return status;
10248 
10249 	*out_adapter = qdf_container_of(node, struct hdd_adapter, node);
10250 
10251 	return status;
10252 }
10253 
10254 QDF_STATUS hdd_add_adapter_back(struct hdd_context *hdd_ctx,
10255 				struct hdd_adapter *adapter)
10256 {
10257 	QDF_STATUS status;
10258 
10259 	qdf_spin_lock_bh(&hdd_ctx->hdd_adapter_lock);
10260 	status = qdf_list_insert_back(&hdd_ctx->hdd_adapters, &adapter->node);
10261 	qdf_spin_unlock_bh(&hdd_ctx->hdd_adapter_lock);
10262 
10263 	return status;
10264 }
10265 
10266 QDF_STATUS hdd_add_adapter_front(struct hdd_context *hdd_ctx,
10267 				 struct hdd_adapter *adapter)
10268 {
10269 	QDF_STATUS status;
10270 
10271 	qdf_spin_lock_bh(&hdd_ctx->hdd_adapter_lock);
10272 	status = qdf_list_insert_front(&hdd_ctx->hdd_adapters, &adapter->node);
10273 	qdf_spin_unlock_bh(&hdd_ctx->hdd_adapter_lock);
10274 
10275 	return status;
10276 }
10277 
10278 void hdd_validate_next_adapter(struct hdd_adapter **curr,
10279 			       struct hdd_adapter **next,
10280 			       wlan_net_dev_ref_dbgid dbg_id)
10281 {
10282 	if (!*curr || !*next || *curr != *next)
10283 		return;
10284 
10285 	hdd_err("Validation failed");
10286 	hdd_adapter_dev_put_debug(*curr, dbg_id);
10287 	*curr = NULL;
10288 	*next = NULL;
10289 }
10290 
10291 QDF_STATUS hdd_adapter_iterate(hdd_adapter_iterate_cb cb, void *context)
10292 {
10293 	struct hdd_context *hdd_ctx;
10294 	struct hdd_adapter *cache[HDD_MAX_ADAPTERS];
10295 	struct hdd_adapter *adapter;
10296 	uint32_t n_cache = 0;
10297 	QDF_STATUS ret = QDF_STATUS_SUCCESS;
10298 	QDF_STATUS status;
10299 	int i;
10300 	struct wlan_hdd_link_info *link_info;
10301 
10302 	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
10303 	if (unlikely(!hdd_ctx))
10304 		return QDF_STATUS_E_FAILURE;
10305 
10306 	qdf_spin_lock_bh(&hdd_ctx->hdd_adapter_lock);
10307 	for (hdd_get_front_adapter_no_lock(hdd_ctx, &adapter); adapter;
10308 	     hdd_get_next_adapter_no_lock(hdd_ctx, adapter, &adapter)) {
10309 		cache[n_cache++] = adapter;
10310 	}
10311 	qdf_spin_unlock_bh(&hdd_ctx->hdd_adapter_lock);
10312 
10313 	for (i = 0; i < n_cache; i++) {
10314 		adapter = hdd_adapter_get_by_reference(hdd_ctx, cache[i]);
10315 		if (!adapter) {
10316 			/*
10317 			 * detected remove while iterating
10318 			 * concurrency failure
10319 			 */
10320 			ret = QDF_STATUS_E_FAILURE;
10321 			continue;
10322 		}
10323 		hdd_adapter_for_each_active_link_info(adapter, link_info) {
10324 			status = cb(link_info, context);
10325 			if (status != QDF_STATUS_SUCCESS) {
10326 				hdd_adapter_put(adapter);
10327 				return status;
10328 			}
10329 		}
10330 		hdd_adapter_put(adapter);
10331 	}
10332 
10333 	return ret;
10334 }
10335 
10336 struct hdd_adapter *hdd_get_adapter_by_rand_macaddr(
10337 	struct hdd_context *hdd_ctx, tSirMacAddr mac_addr)
10338 {
10339 	struct hdd_adapter *adapter, *next_adapter = NULL;
10340 	wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_GET_ADAPTER_BY_RAND_MACADDR;
10341 	struct wlan_hdd_link_info *link_info;
10342 
10343 	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
10344 					   dbgid) {
10345 		if (adapter->device_mode != QDF_STA_MODE &&
10346 		    adapter->device_mode != QDF_P2P_CLIENT_MODE &&
10347 		    adapter->device_mode != QDF_P2P_DEVICE_MODE) {
10348 			hdd_adapter_dev_put_debug(adapter, dbgid);
10349 			continue;
10350 		}
10351 
10352 		hdd_adapter_for_each_active_link_info(adapter, link_info) {
10353 			if (ucfg_p2p_check_random_mac(hdd_ctx->psoc,
10354 						      link_info->vdev_id,
10355 						      mac_addr)) {
10356 				hdd_adapter_dev_put_debug(adapter, dbgid);
10357 				if (next_adapter)
10358 					hdd_adapter_dev_put_debug(next_adapter,
10359 								  dbgid);
10360 				return adapter;
10361 			}
10362 		}
10363 		hdd_adapter_dev_put_debug(adapter, dbgid);
10364 	}
10365 
10366 	return NULL;
10367 }
10368 
10369 #ifdef WLAN_HDD_MULTI_VDEV_SINGLE_NDEV
10370 struct hdd_adapter *hdd_get_adapter_by_macaddr(struct hdd_context *hdd_ctx,
10371 					       tSirMacAddr mac_addr)
10372 {
10373 	struct hdd_adapter *adapter, *next_adapter = NULL;
10374 	wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_GET_ADAPTER_BY_MACADDR;
10375 	struct qdf_mac_addr zero_mac_addr = QDF_MAC_ADDR_ZERO_INIT;
10376 	struct wlan_hdd_link_info *link_info;
10377 
10378 	if (!qdf_mem_cmp(mac_addr, zero_mac_addr.bytes, sizeof(tSirMacAddr)))
10379 		return NULL;
10380 
10381 	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
10382 					   dbgid) {
10383 		if (!qdf_mem_cmp(adapter->mac_addr.bytes,
10384 				 mac_addr, sizeof(tSirMacAddr))) {
10385 			hdd_adapter_dev_put_debug(adapter, dbgid);
10386 			if (next_adapter)
10387 				hdd_adapter_dev_put_debug(next_adapter,
10388 							  dbgid);
10389 			return adapter;
10390 		}
10391 		hdd_adapter_for_each_active_link_info(adapter, link_info) {
10392 			if (!qdf_mem_cmp(link_info->link_addr.bytes,
10393 					 mac_addr, sizeof(tSirMacAddr))) {
10394 				hdd_adapter_dev_put_debug(adapter, dbgid);
10395 				if (next_adapter)
10396 					hdd_adapter_dev_put_debug(next_adapter,
10397 								  dbgid);
10398 				return adapter;
10399 			}
10400 		}
10401 		hdd_adapter_dev_put_debug(adapter, dbgid);
10402 	}
10403 
10404 	return NULL;
10405 }
10406 
10407 struct wlan_hdd_link_info *
10408 hdd_get_link_info_by_link_addr(struct hdd_context *hdd_ctx,
10409 			       struct qdf_mac_addr *link_addr)
10410 {
10411 	struct wlan_hdd_link_info *link_info;
10412 	struct hdd_adapter *adapter, *next_adapter = NULL;
10413 	wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_GET_ADAPTER_BY_MACADDR;
10414 
10415 	if (!link_addr || qdf_is_macaddr_zero(link_addr))
10416 		return NULL;
10417 
10418 	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
10419 					   dbgid) {
10420 		hdd_adapter_for_each_link_info(adapter, link_info) {
10421 			if (qdf_is_macaddr_equal(link_addr,
10422 						 &link_info->link_addr)) {
10423 				hdd_adapter_dev_put_debug(adapter, dbgid);
10424 				if (next_adapter)
10425 					hdd_adapter_dev_put_debug(next_adapter,
10426 								  dbgid);
10427 				return link_info;
10428 			}
10429 		}
10430 		hdd_adapter_dev_put_debug(adapter, dbgid);
10431 	}
10432 
10433 	return NULL;
10434 }
10435 #else
10436 struct hdd_adapter *hdd_get_adapter_by_macaddr(struct hdd_context *hdd_ctx,
10437 					       tSirMacAddr mac_addr)
10438 {
10439 	struct hdd_adapter *adapter, *next_adapter = NULL;
10440 	wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_GET_ADAPTER_BY_MACADDR;
10441 
10442 	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
10443 					   dbgid) {
10444 		if (!qdf_mem_cmp(adapter->mac_addr.bytes,
10445 				 mac_addr, sizeof(tSirMacAddr))) {
10446 			hdd_adapter_dev_put_debug(adapter, dbgid);
10447 			if (next_adapter)
10448 				hdd_adapter_dev_put_debug(next_adapter,
10449 							  dbgid);
10450 			return adapter;
10451 		}
10452 
10453 		if (hdd_adapter_is_sl_ml_adapter(adapter) &&
10454 		    !qdf_mem_cmp(adapter->mld_addr.bytes,
10455 				 mac_addr, sizeof(tSirMacAddr))) {
10456 			hdd_adapter_dev_put_debug(adapter, dbgid);
10457 			if (next_adapter)
10458 				hdd_adapter_dev_put_debug(next_adapter, dbgid);
10459 			return adapter;
10460 		}
10461 		hdd_adapter_dev_put_debug(adapter, dbgid);
10462 	}
10463 
10464 	return NULL;
10465 }
10466 
10467 struct wlan_hdd_link_info *
10468 hdd_get_link_info_by_link_addr(struct hdd_context *hdd_ctx,
10469 			       struct qdf_mac_addr *link_addr)
10470 {
10471 	return NULL;
10472 }
10473 #endif
10474 
10475 struct wlan_hdd_link_info *
10476 hdd_get_link_info_by_vdev(struct hdd_context *hdd_ctx, uint32_t vdev_id)
10477 {
10478 	struct hdd_adapter *adapter, *next_adapter = NULL;
10479 	wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_GET_ADAPTER_BY_VDEV;
10480 	struct wlan_hdd_link_info *link_info;
10481 
10482 	if (vdev_id == WLAN_INVALID_VDEV_ID)
10483 		return NULL;
10484 
10485 	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
10486 					   dbgid) {
10487 		hdd_adapter_for_each_active_link_info(adapter, link_info) {
10488 			if (link_info->vdev_id == vdev_id) {
10489 				hdd_adapter_dev_put_debug(adapter, dbgid);
10490 				if (next_adapter)
10491 					hdd_adapter_dev_put_debug(next_adapter,
10492 								  dbgid);
10493 				return link_info;
10494 			}
10495 		}
10496 		hdd_adapter_dev_put_debug(adapter, dbgid);
10497 	}
10498 
10499 	return NULL;
10500 }
10501 
10502 struct hdd_adapter *hdd_adapter_get_by_reference(struct hdd_context *hdd_ctx,
10503 						 struct hdd_adapter *reference)
10504 {
10505 	struct hdd_adapter *adapter, *next_adapter = NULL;
10506 	wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_ADAPTER_GET_BY_REFERENCE;
10507 
10508 	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
10509 					   dbgid) {
10510 		if (adapter == reference) {
10511 			dev_hold(adapter->dev);
10512 			hdd_adapter_dev_put_debug(adapter, dbgid);
10513 			if (next_adapter)
10514 				hdd_adapter_dev_put_debug(next_adapter,
10515 							  dbgid);
10516 			break;
10517 		}
10518 		hdd_adapter_dev_put_debug(adapter, dbgid);
10519 	}
10520 
10521 	return adapter;
10522 }
10523 
10524 void hdd_adapter_put(struct hdd_adapter *adapter)
10525 {
10526 	dev_put(adapter->dev);
10527 }
10528 
10529 struct hdd_adapter *hdd_get_adapter_by_iface_name(struct hdd_context *hdd_ctx,
10530 					     const char *iface_name)
10531 {
10532 	struct hdd_adapter *adapter, *next_adapter = NULL;
10533 	wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_GET_ADAPTER_BY_IFACE_NAME;
10534 
10535 	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
10536 					   dbgid) {
10537 		if (!qdf_str_cmp(adapter->dev->name, iface_name)) {
10538 			hdd_adapter_dev_put_debug(adapter, dbgid);
10539 			if (next_adapter)
10540 				hdd_adapter_dev_put_debug(next_adapter,
10541 							  dbgid);
10542 			return adapter;
10543 		}
10544 		hdd_adapter_dev_put_debug(adapter, dbgid);
10545 	}
10546 
10547 	return NULL;
10548 }
10549 
10550 struct hdd_adapter *hdd_get_adapter_by_ifindex(struct hdd_context *hdd_ctx,
10551 					       uint32_t if_index)
10552 {
10553 	struct hdd_adapter *adapter, *next_adapter = NULL;
10554 	wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_GET_ADAPTER;
10555 
10556 	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
10557 					   dbgid) {
10558 		if (adapter->dev->ifindex == if_index) {
10559 			hdd_adapter_dev_put_debug(adapter, dbgid);
10560 			if (next_adapter)
10561 				hdd_adapter_dev_put_debug(next_adapter,
10562 							  dbgid);
10563 			return adapter;
10564 		}
10565 		hdd_adapter_dev_put_debug(adapter, dbgid);
10566 	}
10567 
10568 	return NULL;
10569 }
10570 
10571 /**
10572  * hdd_get_adapter() - to get adapter matching the mode
10573  * @hdd_ctx: hdd context
10574  * @mode: adapter mode
10575  *
10576  * This routine will return the pointer to adapter matching
10577  * with the passed mode.
10578  *
10579  * Return: pointer to adapter or null
10580  */
10581 struct hdd_adapter *hdd_get_adapter(struct hdd_context *hdd_ctx,
10582 			enum QDF_OPMODE mode)
10583 {
10584 	struct hdd_adapter *adapter, *next_adapter = NULL;
10585 	wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_GET_ADAPTER;
10586 
10587 	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
10588 					   dbgid) {
10589 		if (adapter->device_mode == mode) {
10590 			hdd_adapter_dev_put_debug(adapter, dbgid);
10591 			if (next_adapter)
10592 				hdd_adapter_dev_put_debug(next_adapter,
10593 							  dbgid);
10594 			return adapter;
10595 		}
10596 		hdd_adapter_dev_put_debug(adapter, dbgid);
10597 	}
10598 
10599 	return NULL;
10600 }
10601 
10602 enum QDF_OPMODE hdd_get_device_mode(uint32_t vdev_id)
10603 {
10604 	struct hdd_context *hdd_ctx;
10605 	struct wlan_hdd_link_info *link_info;
10606 
10607 	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
10608 	if (!hdd_ctx)
10609 		return QDF_MAX_NO_OF_MODE;
10610 
10611 	link_info = hdd_get_link_info_by_vdev(hdd_ctx, vdev_id);
10612 	if (!link_info) {
10613 		hdd_err("Invalid vdev");
10614 		return QDF_MAX_NO_OF_MODE;
10615 	}
10616 
10617 	return link_info->adapter->device_mode;
10618 }
10619 
10620 uint32_t hdd_get_operating_chan_freq(struct hdd_context *hdd_ctx,
10621 				     enum QDF_OPMODE mode)
10622 {
10623 	struct hdd_adapter *adapter, *next_adapter = NULL;
10624 	uint32_t oper_chan_freq = 0;
10625 	wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_GET_OPERATING_CHAN_FREQ;
10626 
10627 	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
10628 					   dbgid) {
10629 		if (mode == adapter->device_mode) {
10630 			oper_chan_freq =
10631 			    hdd_get_link_info_home_channel(adapter->deflink);
10632 			hdd_adapter_dev_put_debug(adapter, dbgid);
10633 			if (next_adapter)
10634 				hdd_adapter_dev_put_debug(next_adapter,
10635 							  dbgid);
10636 			break;
10637 		}
10638 		hdd_adapter_dev_put_debug(adapter, dbgid);
10639 	}
10640 
10641 	return oper_chan_freq;
10642 }
10643 
10644 static inline QDF_STATUS hdd_unregister_wext_all_adapters(
10645 		struct hdd_context *hdd_ctx,
10646 		bool rtnl_held)
10647 {
10648 	struct hdd_adapter *adapter, *next_adapter = NULL;
10649 	wlan_net_dev_ref_dbgid dbgid =
10650 				NET_DEV_HOLD_UNREGISTER_WEXT_ALL_ADAPTERS;
10651 
10652 	hdd_enter();
10653 
10654 	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
10655 					   dbgid) {
10656 		if (adapter->device_mode == QDF_STA_MODE ||
10657 		    adapter->device_mode == QDF_P2P_CLIENT_MODE ||
10658 		    adapter->device_mode == QDF_P2P_DEVICE_MODE ||
10659 		    adapter->device_mode == QDF_SAP_MODE ||
10660 		    adapter->device_mode == QDF_P2P_GO_MODE) {
10661 			hdd_wext_unregister(adapter->dev, rtnl_held);
10662 		}
10663 		hdd_adapter_dev_put_debug(adapter, dbgid);
10664 	}
10665 
10666 	hdd_exit();
10667 
10668 	return QDF_STATUS_SUCCESS;
10669 }
10670 
10671 QDF_STATUS hdd_abort_mac_scan_all_adapters(struct hdd_context *hdd_ctx)
10672 {
10673 	struct hdd_adapter *adapter, *next_adapter = NULL;
10674 	wlan_net_dev_ref_dbgid dbgid =
10675 				NET_DEV_HOLD_ABORT_MAC_SCAN_ALL_ADAPTERS;
10676 	struct wlan_hdd_link_info *link_info;
10677 
10678 	hdd_enter();
10679 
10680 	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
10681 					   dbgid) {
10682 		if (adapter->device_mode == QDF_STA_MODE ||
10683 		    adapter->device_mode == QDF_P2P_CLIENT_MODE ||
10684 		    adapter->device_mode == QDF_P2P_DEVICE_MODE ||
10685 		    adapter->device_mode == QDF_SAP_MODE ||
10686 		    adapter->device_mode == QDF_P2P_GO_MODE) {
10687 			hdd_adapter_for_each_active_link_info(adapter,
10688 							      link_info) {
10689 				wlan_abort_scan(hdd_ctx->pdev, INVAL_PDEV_ID,
10690 						link_info->vdev_id,
10691 						INVALID_SCAN_ID, true);
10692 			}
10693 		}
10694 		hdd_adapter_dev_put_debug(adapter, dbgid);
10695 	}
10696 
10697 	hdd_exit();
10698 
10699 	return QDF_STATUS_SUCCESS;
10700 }
10701 
10702 /**
10703  * hdd_abort_sched_scan_all_adapters() - stops scheduled (PNO) scans for all
10704  * adapters
10705  * @hdd_ctx: The HDD context containing the adapters to operate on
10706  *
10707  * return: QDF_STATUS_SUCCESS
10708  */
10709 static QDF_STATUS hdd_abort_sched_scan_all_adapters(struct hdd_context *hdd_ctx)
10710 {
10711 	struct hdd_adapter *adapter, *next_adapter = NULL;
10712 	int err;
10713 	wlan_net_dev_ref_dbgid dbgid =
10714 				NET_DEV_HOLD_ABORT_SCHED_SCAN_ALL_ADAPTERS;
10715 
10716 	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
10717 					   dbgid) {
10718 		if (adapter->device_mode == QDF_STA_MODE ||
10719 		    adapter->device_mode == QDF_P2P_CLIENT_MODE ||
10720 		    adapter->device_mode == QDF_P2P_DEVICE_MODE ||
10721 		    adapter->device_mode == QDF_SAP_MODE ||
10722 		    adapter->device_mode == QDF_P2P_GO_MODE) {
10723 			err = wlan_hdd_sched_scan_stop(adapter->dev);
10724 			if (err)
10725 				hdd_err("Unable to stop scheduled scan");
10726 		}
10727 		hdd_adapter_dev_put_debug(adapter, dbgid);
10728 	}
10729 
10730 	return QDF_STATUS_SUCCESS;
10731 }
10732 
10733 /**
10734  * hdd_unregister_notifiers - Unregister netdev notifiers.
10735  * @hdd_ctx: HDD context
10736  *
10737  * Unregister netdev notifiers like IPv4 and IPv6.
10738  *
10739  * Return: None.
10740  */
10741 void hdd_unregister_notifiers(struct hdd_context *hdd_ctx)
10742 {
10743 	osif_dp_nud_unregister_netevent_notifier(hdd_ctx->psoc);
10744 	hdd_wlan_unregister_ip6_notifier(hdd_ctx);
10745 
10746 	unregister_inetaddr_notifier(&hdd_ctx->ipv4_notifier);
10747 }
10748 
10749 /**
10750  * hdd_exit_netlink_services - Exit netlink services
10751  * @hdd_ctx: HDD context
10752  *
10753  * Exit netlink services like cnss_diag, cesium netlink socket, ptt socket and
10754  * nl service.
10755  *
10756  * Return: None.
10757  */
10758 static void hdd_exit_netlink_services(struct hdd_context *hdd_ctx)
10759 {
10760 	spectral_scan_deactivate_service();
10761 	cnss_diag_deactivate_service();
10762 	hdd_close_cesium_nl_sock();
10763 	ptt_sock_deactivate_svc();
10764 	hdd_deactivate_wifi_pos();
10765 
10766 	nl_srv_exit();
10767 }
10768 
10769 /**
10770  * hdd_init_netlink_services- Init netlink services
10771  * @hdd_ctx: HDD context
10772  *
10773  * Init netlink services like cnss_diag, cesium netlink socket, ptt socket and
10774  * nl service.
10775  *
10776  * Return: 0 on success and errno on failure.
10777  */
10778 static int hdd_init_netlink_services(struct hdd_context *hdd_ctx)
10779 {
10780 	int ret;
10781 
10782 	ret = wlan_hdd_nl_init(hdd_ctx);
10783 	if (ret) {
10784 		hdd_err("nl_srv_init failed: %d", ret);
10785 		goto out;
10786 	}
10787 	cds_set_radio_index(hdd_ctx->radio_index);
10788 
10789 	ret = hdd_activate_wifi_pos(hdd_ctx);
10790 	if (ret) {
10791 		hdd_err("hdd_activate_wifi_pos failed: %d", ret);
10792 		goto err_nl_srv;
10793 	}
10794 
10795 	ptt_sock_activate_svc();
10796 
10797 	ret = hdd_open_cesium_nl_sock();
10798 	if (ret)
10799 		hdd_err("hdd_open_cesium_nl_sock failed ret: %d", ret);
10800 
10801 	ret = cnss_diag_activate_service();
10802 	if (ret) {
10803 		hdd_err("cnss_diag_activate_service failed: %d", ret);
10804 		goto err_close_cesium;
10805 	}
10806 
10807 	spectral_scan_activate_service(hdd_ctx);
10808 
10809 	return 0;
10810 
10811 err_close_cesium:
10812 	hdd_close_cesium_nl_sock();
10813 	ptt_sock_deactivate_svc();
10814 	hdd_deactivate_wifi_pos();
10815 err_nl_srv:
10816 	nl_srv_exit();
10817 out:
10818 	return ret;
10819 }
10820 
10821 #ifdef SHUTDOWN_WLAN_IN_SYSTEM_SUSPEND
10822 static QDF_STATUS
10823 hdd_shutdown_wlan_in_suspend_prepare(struct hdd_context *hdd_ctx)
10824 {
10825 #define SHUTDOWN_IN_SUSPEND_RETRY 10
10826 
10827 	int count = 0;
10828 
10829 	if (ucfg_pmo_get_suspend_mode(hdd_ctx->psoc) != PMO_SUSPEND_SHUTDOWN) {
10830 		hdd_debug("shutdown in suspend not supported");
10831 		return 0;
10832 	}
10833 
10834 	while (hdd_is_any_interface_open(hdd_ctx) &&
10835 	       count < SHUTDOWN_IN_SUSPEND_RETRY) {
10836 		count++;
10837 		hdd_debug_rl("sleep 50ms to wait adapters stopped, #%d", count);
10838 		msleep(50);
10839 	}
10840 	if (count >= SHUTDOWN_IN_SUSPEND_RETRY) {
10841 		hdd_err("some adapters not stopped");
10842 		return -EBUSY;
10843 	}
10844 
10845 	hdd_debug("call pld idle shutdown directly");
10846 	return pld_idle_shutdown(hdd_ctx->parent_dev, hdd_psoc_idle_shutdown);
10847 }
10848 
10849 static int hdd_pm_notify(struct notifier_block *b,
10850 			 unsigned long event, void *p)
10851 {
10852 	struct hdd_context *hdd_ctx = container_of(b, struct hdd_context,
10853 						   pm_notifier);
10854 
10855 	if (wlan_hdd_validate_context(hdd_ctx) != 0)
10856 		return NOTIFY_STOP;
10857 
10858 	hdd_debug("got PM event: %lu", event);
10859 
10860 	switch (event) {
10861 	case PM_SUSPEND_PREPARE:
10862 	case PM_HIBERNATION_PREPARE:
10863 		if (0 != hdd_shutdown_wlan_in_suspend_prepare(hdd_ctx))
10864 			return NOTIFY_STOP;
10865 		break;
10866 	case PM_POST_SUSPEND:
10867 	case PM_POST_HIBERNATION:
10868 		break;
10869 	}
10870 
10871 	return NOTIFY_DONE;
10872 }
10873 
10874 static void hdd_pm_notifier_init(struct hdd_context *hdd_ctx)
10875 {
10876 	hdd_ctx->pm_notifier.notifier_call = hdd_pm_notify;
10877 	register_pm_notifier(&hdd_ctx->pm_notifier);
10878 }
10879 
10880 static void hdd_pm_notifier_deinit(struct hdd_context *hdd_ctx)
10881 {
10882 	unregister_pm_notifier(&hdd_ctx->pm_notifier);
10883 }
10884 #else
10885 static inline void hdd_pm_notifier_init(struct hdd_context *hdd_ctx)
10886 {
10887 }
10888 
10889 static inline void hdd_pm_notifier_deinit(struct hdd_context *hdd_ctx)
10890 {
10891 }
10892 #endif
10893 
10894 /**
10895  * hdd_context_deinit() - Deinitialize HDD context
10896  * @hdd_ctx:    HDD context.
10897  *
10898  * Deinitialize HDD context along with all the feature specific contexts but
10899  * do not free hdd context itself. Caller of this API is supposed to free
10900  * HDD context.
10901  *
10902  * return: 0 on success and errno on failure.
10903  */
10904 static int hdd_context_deinit(struct hdd_context *hdd_ctx)
10905 {
10906 	qdf_wake_lock_destroy(&hdd_ctx->monitor_mode_wakelock);
10907 
10908 	wlan_hdd_cfg80211_deinit(hdd_ctx->wiphy);
10909 
10910 	ucfg_dp_bbm_context_deinit(hdd_ctx->psoc);
10911 
10912 	hdd_sap_context_destroy(hdd_ctx);
10913 
10914 	hdd_scan_context_destroy(hdd_ctx);
10915 
10916 	qdf_list_destroy(&hdd_ctx->hdd_adapters);
10917 
10918 	return 0;
10919 }
10920 
10921 void hdd_context_destroy(struct hdd_context *hdd_ctx)
10922 {
10923 	wlan_hdd_sar_timers_deinit(hdd_ctx);
10924 
10925 	cds_set_context(QDF_MODULE_ID_HDD, NULL);
10926 
10927 	hdd_exit_netlink_services(hdd_ctx);
10928 
10929 	hdd_context_deinit(hdd_ctx);
10930 
10931 	hdd_objmgr_release_and_destroy_psoc(hdd_ctx);
10932 
10933 	qdf_mem_free(hdd_ctx->config);
10934 	hdd_ctx->config = NULL;
10935 	cfg_release();
10936 
10937 	hdd_pm_notifier_deinit(hdd_ctx);
10938 	qdf_delayed_work_destroy(&hdd_ctx->psoc_idle_timeout_work);
10939 	wiphy_free(hdd_ctx->wiphy);
10940 }
10941 
10942 /**
10943  * wlan_destroy_bug_report_lock() - Destroy bug report lock
10944  *
10945  * This function is used to destroy bug report lock
10946  *
10947  * Return: None
10948  */
10949 static void wlan_destroy_bug_report_lock(void)
10950 {
10951 	struct cds_context *p_cds_context;
10952 
10953 	p_cds_context = cds_get_global_context();
10954 	if (!p_cds_context) {
10955 		hdd_err("cds context is NULL");
10956 		return;
10957 	}
10958 
10959 	qdf_spinlock_destroy(&p_cds_context->bug_report_lock);
10960 }
10961 
10962 #ifdef DISABLE_CHANNEL_LIST
10963 static void wlan_hdd_cache_chann_mutex_destroy(struct hdd_context *hdd_ctx)
10964 {
10965 	qdf_mutex_destroy(&hdd_ctx->cache_channel_lock);
10966 }
10967 #else
10968 static void wlan_hdd_cache_chann_mutex_destroy(struct hdd_context *hdd_ctx)
10969 {
10970 }
10971 #endif
10972 
10973 void hdd_wlan_exit(struct hdd_context *hdd_ctx)
10974 {
10975 	struct wiphy *wiphy = hdd_ctx->wiphy;
10976 
10977 	hdd_enter();
10978 
10979 	ucfg_dp_wait_complete_tasks();
10980 	wlan_hdd_destroy_mib_stats_lock();
10981 	hdd_debugfs_ini_config_deinit(hdd_ctx);
10982 	hdd_debugfs_mws_coex_info_deinit(hdd_ctx);
10983 	hdd_psoc_idle_timer_stop(hdd_ctx);
10984 	hdd_regulatory_deinit(hdd_ctx);
10985 
10986 	/*
10987 	 * Powersave Offload Case
10988 	 * Disable Idle Power Save Mode
10989 	 */
10990 	hdd_set_idle_ps_config(hdd_ctx, false);
10991 	/* clear the scan queue in all the scenarios */
10992 	wlan_cfg80211_cleanup_scan_queue(hdd_ctx->pdev, NULL);
10993 
10994 	if (hdd_ctx->driver_status != DRIVER_MODULES_CLOSED) {
10995 		hdd_unregister_wext_all_adapters(hdd_ctx, false);
10996 		/*
10997 		 * Cancel any outstanding scan requests.  We are about to close
10998 		 * all of our adapters, but an adapter structure is what SME
10999 		 * passes back to our callback function.  Hence if there
11000 		 * are any outstanding scan requests then there is a
11001 		 * race condition between when the adapter is closed and
11002 		 * when the callback is invoked.  We try to resolve that
11003 		 * race condition here by canceling any outstanding scans
11004 		 * before we close the adapters.
11005 		 * Note that the scans may be cancelled in an asynchronous
11006 		 * manner, so ideally there needs to be some kind of
11007 		 * synchronization.  Rather than introduce a new
11008 		 * synchronization here, we will utilize the fact that we are
11009 		 * about to Request Full Power, and since that is synchronized,
11010 		 * the expectation is that by the time Request Full Power has
11011 		 * completed, all scans will be cancelled
11012 		 */
11013 		hdd_abort_mac_scan_all_adapters(hdd_ctx);
11014 		hdd_abort_sched_scan_all_adapters(hdd_ctx);
11015 
11016 		hdd_stop_all_adapters(hdd_ctx);
11017 		hdd_deinit_all_adapters(hdd_ctx, false);
11018 	}
11019 
11020 	unregister_netdevice_notifier(&hdd_netdev_notifier);
11021 
11022 	qdf_dp_trace_deinit();
11023 
11024 	hdd_wlan_stop_modules(hdd_ctx, false);
11025 
11026 	hdd_driver_memdump_deinit();
11027 
11028 	qdf_nbuf_deinit_replenish_timer();
11029 
11030 	if (QDF_GLOBAL_MONITOR_MODE ==  hdd_get_conparam()) {
11031 		hdd_info("Release wakelock for monitor mode!");
11032 		qdf_wake_lock_release(&hdd_ctx->monitor_mode_wakelock,
11033 				      WIFI_POWER_EVENT_WAKELOCK_MONITOR_MODE);
11034 	}
11035 
11036 	qdf_spinlock_destroy(&hdd_ctx->hdd_adapter_lock);
11037 	qdf_spinlock_destroy(&hdd_ctx->connection_status_lock);
11038 	wlan_hdd_cache_chann_mutex_destroy(hdd_ctx);
11039 
11040 	osif_request_manager_deinit();
11041 
11042 	hdd_close_all_adapters(hdd_ctx, false);
11043 
11044 	wlansap_global_deinit();
11045 	/*
11046 	 * If there is re_init failure wiphy would have already de-registered
11047 	 * check the wiphy status before un-registering again
11048 	 */
11049 	if (wiphy && wiphy->registered) {
11050 		wiphy_unregister(wiphy);
11051 		wlan_hdd_cfg80211_deinit(wiphy);
11052 		hdd_lpass_notify_stop(hdd_ctx);
11053 	}
11054 
11055 	hdd_deinit_regulatory_update_event(hdd_ctx);
11056 	hdd_exit_netlink_services(hdd_ctx);
11057 #ifdef FEATURE_WLAN_CH_AVOID
11058 	mutex_destroy(&hdd_ctx->avoid_freq_lock);
11059 #endif
11060 
11061 	/* This function should be invoked at the end of this api*/
11062 	hdd_dump_func_call_map();
11063 }
11064 
11065 /**
11066  * hdd_wlan_notify_modem_power_state() - notify FW with modem power status
11067  * @state: state
11068  *
11069  * This function notifies FW with modem power status
11070  *
11071  * Return: 0 if successful, error number otherwise
11072  */
11073 int hdd_wlan_notify_modem_power_state(int state)
11074 {
11075 	int status;
11076 	QDF_STATUS qdf_status;
11077 	struct hdd_context *hdd_ctx;
11078 	mac_handle_t mac_handle;
11079 
11080 	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
11081 	status = wlan_hdd_validate_context(hdd_ctx);
11082 	if (status)
11083 		return status;
11084 
11085 	mac_handle = hdd_ctx->mac_handle;
11086 	if (!mac_handle)
11087 		return -EINVAL;
11088 
11089 	qdf_status = sme_notify_modem_power_state(mac_handle, state);
11090 	if (QDF_STATUS_SUCCESS != qdf_status) {
11091 		hdd_err("Fail to send notification with modem power state %d",
11092 		       state);
11093 		return -EINVAL;
11094 	}
11095 	return 0;
11096 }
11097 
11098 /**
11099  * hdd_post_cds_enable_config() - HDD post cds start config helper
11100  * @hdd_ctx: Pointer to the HDD
11101  *
11102  * Return: None
11103  */
11104 QDF_STATUS hdd_post_cds_enable_config(struct hdd_context *hdd_ctx)
11105 {
11106 	QDF_STATUS qdf_ret_status;
11107 
11108 	/*
11109 	 * Send ready indication to the HDD.  This will kick off the MAC
11110 	 * into a 'running' state and should kick off an initial scan.
11111 	 */
11112 	qdf_ret_status = sme_hdd_ready_ind(hdd_ctx->mac_handle);
11113 	if (!QDF_IS_STATUS_SUCCESS(qdf_ret_status)) {
11114 		hdd_err("sme_hdd_ready_ind() failed with status code %08d [x%08x]",
11115 			qdf_ret_status, qdf_ret_status);
11116 		return QDF_STATUS_E_FAILURE;
11117 	}
11118 
11119 	return QDF_STATUS_SUCCESS;
11120 }
11121 
11122 struct hdd_adapter *hdd_get_first_valid_adapter(struct hdd_context *hdd_ctx)
11123 {
11124 	struct hdd_adapter *adapter, *next_adapter = NULL;
11125 	wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_GET_FIRST_VALID_ADAPTER;
11126 
11127 	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
11128 					   dbgid) {
11129 		if (adapter && adapter->magic == WLAN_HDD_ADAPTER_MAGIC) {
11130 			hdd_adapter_dev_put_debug(adapter, dbgid);
11131 			if (next_adapter)
11132 				hdd_adapter_dev_put_debug(next_adapter,
11133 							  dbgid);
11134 			return adapter;
11135 		}
11136 		hdd_adapter_dev_put_debug(adapter, dbgid);
11137 	}
11138 
11139 	return NULL;
11140 }
11141 
11142 /* wake lock APIs for HDD */
11143 void hdd_prevent_suspend(uint32_t reason)
11144 {
11145 	qdf_wake_lock_acquire(&wlan_wake_lock, reason);
11146 }
11147 
11148 void hdd_allow_suspend(uint32_t reason)
11149 {
11150 	qdf_wake_lock_release(&wlan_wake_lock, reason);
11151 }
11152 
11153 void hdd_prevent_suspend_timeout(uint32_t timeout, uint32_t reason)
11154 {
11155 	cds_host_diag_log_work(&wlan_wake_lock, timeout, reason);
11156 	qdf_wake_lock_timeout_acquire(&wlan_wake_lock, timeout);
11157 }
11158 
11159 /* Initialize channel list in sme based on the country code */
11160 QDF_STATUS hdd_set_sme_chan_list(struct hdd_context *hdd_ctx)
11161 {
11162 	return sme_init_chan_list(hdd_ctx->mac_handle,
11163 				  hdd_ctx->reg.cc_src);
11164 }
11165 
11166 /**
11167  * hdd_is_5g_supported() - check if hardware supports 5GHz
11168  * @hdd_ctx:	Pointer to the hdd context
11169  *
11170  * HDD function to know if hardware supports 5GHz
11171  *
11172  * Return:  true if hardware supports 5GHz
11173  */
11174 bool hdd_is_5g_supported(struct hdd_context *hdd_ctx)
11175 {
11176 	if (!hdd_ctx)
11177 		return true;
11178 
11179 	if (hdd_ctx->curr_band != BAND_2G)
11180 		return true;
11181 	else
11182 		return false;
11183 }
11184 
11185 bool hdd_is_2g_supported(struct hdd_context *hdd_ctx)
11186 {
11187 	if (!hdd_ctx)
11188 		return false;
11189 
11190 	if (hdd_ctx->curr_band != BAND_5G)
11191 		return true;
11192 	else
11193 		return false;
11194 }
11195 
11196 static int hdd_wiphy_init(struct hdd_context *hdd_ctx)
11197 {
11198 	struct wiphy *wiphy;
11199 	int ret_val;
11200 	uint32_t channel_bonding_mode;
11201 
11202 	wiphy = hdd_ctx->wiphy;
11203 
11204 	/*
11205 	 * The channel information in
11206 	 * wiphy needs to be initialized before wiphy registration
11207 	 */
11208 	ret_val = hdd_regulatory_init(hdd_ctx, wiphy);
11209 	if (ret_val) {
11210 		hdd_err("regulatory init failed");
11211 		return ret_val;
11212 	}
11213 
11214 	if (ucfg_pmo_get_suspend_mode(hdd_ctx->psoc) == PMO_SUSPEND_WOW) {
11215 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
11216 		wiphy->wowlan = &wowlan_support_reg_init;
11217 #else
11218 		wiphy->wowlan.flags = WIPHY_WOWLAN_ANY |
11219 				      WIPHY_WOWLAN_MAGIC_PKT |
11220 				      WIPHY_WOWLAN_DISCONNECT |
11221 				      WIPHY_WOWLAN_SUPPORTS_GTK_REKEY |
11222 				      WIPHY_WOWLAN_GTK_REKEY_FAILURE |
11223 				      WIPHY_WOWLAN_EAP_IDENTITY_REQ |
11224 				      WIPHY_WOWLAN_4WAY_HANDSHAKE |
11225 				      WIPHY_WOWLAN_RFKILL_RELEASE;
11226 
11227 		wiphy->wowlan.n_patterns = (WOW_MAX_FILTER_LISTS *
11228 				    WOW_MAX_FILTERS_PER_LIST);
11229 		wiphy->wowlan.pattern_min_len = WOW_MIN_PATTERN_SIZE;
11230 		wiphy->wowlan.pattern_max_len = WOW_MAX_PATTERN_SIZE;
11231 #endif
11232 	}
11233 
11234 	ucfg_mlme_get_channel_bonding_24ghz(hdd_ctx->psoc,
11235 					    &channel_bonding_mode);
11236 	if (hdd_ctx->obss_scan_offload) {
11237 		hdd_debug("wmi_service_obss_scan supported");
11238 	} else if (channel_bonding_mode) {
11239 		hdd_debug("enable wpa_supp obss_scan");
11240 		wiphy->features |= NL80211_FEATURE_NEED_OBSS_SCAN;
11241 	}
11242 
11243 	if (hdd_ctx->num_rf_chains == HDD_ANTENNA_MODE_2X2 &&
11244 	    ucfg_mlme_is_chain_mask_supported(hdd_ctx->psoc)) {
11245 		wiphy->available_antennas_tx = HDD_CHAIN_MODE_2X2;
11246 		wiphy->available_antennas_rx = HDD_CHAIN_MODE_2X2;
11247 	}
11248 	/* registration of wiphy dev with cfg80211 */
11249 	ret_val = wlan_hdd_cfg80211_register(wiphy);
11250 	if (0 > ret_val) {
11251 		hdd_err("wiphy registration failed");
11252 		return ret_val;
11253 	}
11254 
11255 	/* Check the kernel version for upstream commit aced43ce780dc5 that
11256 	 * has support for processing user cell_base hints when wiphy is
11257 	 * self managed or check the backport flag for the same.
11258 	 */
11259 #if defined CFG80211_USER_HINT_CELL_BASE_SELF_MANAGED ||	\
11260 		(LINUX_VERSION_CODE >= KERNEL_VERSION(4, 18, 0))
11261 	hdd_send_wiphy_regd_sync_event(hdd_ctx);
11262 #endif
11263 
11264 	pld_increment_driver_load_cnt(hdd_ctx->parent_dev);
11265 
11266 	return ret_val;
11267 }
11268 
11269 #ifdef WLAN_FEATURE_DP_BUS_BANDWIDTH
11270 #ifdef CLD_PM_QOS
11271 #define PLD_REMOVE_PM_QOS(x)
11272 #define PLD_REQUEST_PM_QOS(x, y)
11273 #define HDD_PM_QOS_HIGH_TPUT_LATENCY_US 1
11274 
11275 /**
11276  * hdd_pm_qos_update_cpu_mask() - Prepare CPU mask for PM_qos voting
11277  * @mask: return variable of cpumask for the TPUT
11278  * @enable_perf_cluster: Enable PERF cluster or not
11279  *
11280  * By default, the function sets CPU mask for silver cluster unless
11281  * enable_perf_cluster is set as true.
11282  *
11283  * Return: none
11284  */
11285 static inline void hdd_pm_qos_update_cpu_mask(cpumask_t *mask,
11286 					      bool enable_perf_cluster)
11287 {
11288 	cpumask_set_cpu(0, mask);
11289 	cpumask_set_cpu(1, mask);
11290 	cpumask_set_cpu(2, mask);
11291 	cpumask_set_cpu(3, mask);
11292 
11293 	if (enable_perf_cluster) {
11294 		cpumask_set_cpu(4, mask);
11295 		cpumask_set_cpu(5, mask);
11296 		cpumask_set_cpu(6, mask);
11297 	}
11298 }
11299 
11300 #ifdef MSM_PLATFORM
11301 #define COPY_CPU_MASK(a, b) cpumask_copy(a, b)
11302 #define DUMP_CPU_AFFINE() hdd_info("Set cpu_mask %*pb for affine_cores", \
11303 			  cpumask_pr_args(&hdd_ctx->pm_qos_req.cpus_affine))
11304 #else
11305 #define COPY_CPU_MASK(a, b) /* no-op*/
11306 #define DUMP_CPU_AFFINE() /* no-op*/
11307 #endif
11308 
11309 #ifdef CLD_DEV_PM_QOS
11310 
11311 static inline void _hdd_pm_qos_update_request(struct hdd_context *hdd_ctx,
11312 					      cpumask_t *pm_qos_cpu_mask,
11313 					      unsigned int latency)
11314 {
11315 	int cpu;
11316 	uint32_t default_latency;
11317 
11318 	default_latency = wlan_hdd_get_default_pm_qos_cpu_latency();
11319 	qdf_cpumask_copy(&hdd_ctx->qos_cpu_mask, pm_qos_cpu_mask);
11320 
11321 	if (qdf_cpumask_empty(pm_qos_cpu_mask)) {
11322 		for_each_present_cpu(cpu) {
11323 			dev_pm_qos_update_request(
11324 				&hdd_ctx->pm_qos_req[cpu],
11325 				default_latency);
11326 		}
11327 		hdd_debug("Empty mask %*pb: Set latency %u",
11328 			  qdf_cpumask_pr_args(&hdd_ctx->qos_cpu_mask),
11329 			  default_latency);
11330 	} else { /* Set latency to default for CPUs not included in mask */
11331 		qdf_for_each_cpu_not(cpu, &hdd_ctx->qos_cpu_mask) {
11332 			dev_pm_qos_update_request(
11333 				&hdd_ctx->pm_qos_req[cpu],
11334 				default_latency);
11335 		}
11336 		/* Set latency for CPUs included in mask */
11337 		qdf_for_each_cpu(cpu, &hdd_ctx->qos_cpu_mask) {
11338 			dev_pm_qos_update_request(
11339 				&hdd_ctx->pm_qos_req[cpu],
11340 				latency);
11341 		}
11342 		hdd_debug("For qos_cpu_mask %*pb set latency %u",
11343 			  qdf_cpumask_pr_args(&hdd_ctx->qos_cpu_mask),
11344 			  latency);
11345 	}
11346 }
11347 
11348 /**
11349  * hdd_pm_qos_update_request() - API to request for pm_qos
11350  * @hdd_ctx: handle to hdd context
11351  * @pm_qos_cpu_mask: cpu_mask to apply
11352  *
11353  * Return: none
11354  */
11355 static void hdd_pm_qos_update_request(struct hdd_context *hdd_ctx,
11356 				      cpumask_t *pm_qos_cpu_mask)
11357 {
11358 	unsigned int latency;
11359 
11360 	if (qdf_cpumask_empty(pm_qos_cpu_mask))
11361 		latency = wlan_hdd_get_default_pm_qos_cpu_latency();
11362 	else
11363 		latency = HDD_PM_QOS_HIGH_TPUT_LATENCY_US;
11364 
11365 	_hdd_pm_qos_update_request(hdd_ctx, pm_qos_cpu_mask, latency);
11366 }
11367 
11368 static inline void hdd_pm_qos_add_request(struct hdd_context *hdd_ctx)
11369 {
11370 	struct device *cpu_dev;
11371 	int cpu;
11372 	uint32_t default_latency = wlan_hdd_get_default_pm_qos_cpu_latency();
11373 
11374 
11375 	qdf_cpumask_clear(&hdd_ctx->qos_cpu_mask);
11376 	hdd_pm_qos_update_cpu_mask(&hdd_ctx->qos_cpu_mask, false);
11377 
11378 	for_each_present_cpu(cpu) {
11379 		cpu_dev = get_cpu_device(cpu);
11380 		dev_pm_qos_add_request(cpu_dev, &hdd_ctx->pm_qos_req[cpu],
11381 				       DEV_PM_QOS_RESUME_LATENCY,
11382 				       default_latency);
11383 		hdd_debug("Set qos_cpu_mask %*pb for affine_cores",
11384 			 cpumask_pr_args(&hdd_ctx->qos_cpu_mask));
11385 	}
11386 }
11387 
11388 static inline void hdd_pm_qos_remove_request(struct hdd_context *hdd_ctx)
11389 {
11390 	int cpu;
11391 
11392 	for_each_present_cpu(cpu) {
11393 		dev_pm_qos_remove_request(&hdd_ctx->pm_qos_req[cpu]);
11394 		hdd_debug("Remove dev_pm_qos_request for all cpus: %d", cpu);
11395 	}
11396 	qdf_cpumask_clear(&hdd_ctx->qos_cpu_mask);
11397 }
11398 
11399 #else /* CLD_DEV_PM_QOS */
11400 
11401 #if defined(CONFIG_SMP) && defined(MSM_PLATFORM)
11402 /**
11403  * hdd_set_default_pm_qos_mask() - Update PM_qos request for AFFINE_CORES
11404  * @hdd_ctx: handle to hdd context
11405  *
11406  * Return: none
11407  */
11408 static inline void hdd_set_default_pm_qos_mask(struct hdd_context *hdd_ctx)
11409 {
11410 	hdd_ctx->pm_qos_req.type = PM_QOS_REQ_AFFINE_CORES;
11411 	qdf_cpumask_clear(&hdd_ctx->pm_qos_req.cpus_affine);
11412 	hdd_pm_qos_update_cpu_mask(&hdd_ctx->pm_qos_req.cpus_affine, false);
11413 }
11414 #else
11415 static inline void hdd_set_default_pm_qos_mask(struct hdd_context *hdd_ctx)
11416 {
11417 }
11418 #endif
11419 
11420 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 7, 0))
11421 /**
11422  * hdd_pm_qos_update_request() - API to request for pm_qos
11423  * @hdd_ctx: handle to hdd context
11424  * @pm_qos_cpu_mask: cpu_mask to apply
11425  *
11426  * Return: none
11427  */
11428 static inline void hdd_pm_qos_update_request(struct hdd_context *hdd_ctx,
11429 					     cpumask_t *pm_qos_cpu_mask)
11430 {
11431 	COPY_CPU_MASK(&hdd_ctx->pm_qos_req.cpus_affine, pm_qos_cpu_mask);
11432 
11433 	if (cpumask_empty(pm_qos_cpu_mask))
11434 		cpu_latency_qos_update_request(&hdd_ctx->pm_qos_req,
11435 					       PM_QOS_DEFAULT_VALUE);
11436 	else
11437 		cpu_latency_qos_update_request(&hdd_ctx->pm_qos_req, 1);
11438 }
11439 
11440 static inline void hdd_pm_qos_add_request(struct hdd_context *hdd_ctx)
11441 {
11442 	hdd_set_default_pm_qos_mask(hdd_ctx);
11443 	cpu_latency_qos_add_request(&hdd_ctx->pm_qos_req, PM_QOS_DEFAULT_VALUE);
11444 	DUMP_CPU_AFFINE();
11445 }
11446 
11447 static inline void hdd_pm_qos_remove_request(struct hdd_context *hdd_ctx)
11448 {
11449 	cpu_latency_qos_remove_request(&hdd_ctx->pm_qos_req);
11450 }
11451 #else
11452 static inline void hdd_pm_qos_update_request(struct hdd_context *hdd_ctx,
11453 					     cpumask_t *pm_qos_cpu_mask)
11454 {
11455 	COPY_CPU_MASK(&hdd_ctx->pm_qos_req.cpus_affine, pm_qos_cpu_mask);
11456 
11457 	if (cpumask_empty(pm_qos_cpu_mask))
11458 		pm_qos_update_request(&hdd_ctx->pm_qos_req,
11459 				      PM_QOS_DEFAULT_VALUE);
11460 	else
11461 		pm_qos_update_request(&hdd_ctx->pm_qos_req, 1);
11462 }
11463 
11464 static inline void hdd_pm_qos_add_request(struct hdd_context *hdd_ctx)
11465 {
11466 	hdd_set_default_pm_qos_mask(hdd_ctx);
11467 	pm_qos_add_request(&hdd_ctx->pm_qos_req, PM_QOS_CPU_DMA_LATENCY,
11468 			   PM_QOS_DEFAULT_VALUE);
11469 	DUMP_CPU_AFFINE();
11470 }
11471 
11472 static inline void hdd_pm_qos_remove_request(struct hdd_context *hdd_ctx)
11473 {
11474 	pm_qos_remove_request(&hdd_ctx->pm_qos_req);
11475 }
11476 #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(5, 7, 0) */
11477 #endif /* CLD_DEV_PM_QOS */
11478 
11479 #else /* CLD_PM_QOS */
11480 #define PLD_REMOVE_PM_QOS(x) pld_remove_pm_qos(x)
11481 #define PLD_REQUEST_PM_QOS(x, y) pld_request_pm_qos(x, y)
11482 
11483 static inline void hdd_pm_qos_add_request(struct hdd_context *hdd_ctx)
11484 {
11485 }
11486 
11487 static inline void hdd_pm_qos_remove_request(struct hdd_context *hdd_ctx)
11488 {
11489 }
11490 
11491 static inline void hdd_pm_qos_update_cpu_mask(cpumask_t *mask,
11492 					      bool high_throughput)
11493 {
11494 }
11495 
11496 static inline void hdd_pm_qos_update_request(struct hdd_context *hdd_ctx,
11497 					     cpumask_t *pm_qos_cpu_mask)
11498 {
11499 }
11500 #endif /* CLD_PM_QOS */
11501 
11502 #if defined(CLD_PM_QOS)
11503 #if defined(CLD_DEV_PM_QOS)
11504 void wlan_hdd_set_pm_qos_request(struct hdd_context *hdd_ctx,
11505 				 bool pm_qos_request)
11506 {
11507 	cpumask_t pm_qos_cpu_mask;
11508 
11509 	cpumask_clear(&pm_qos_cpu_mask);
11510 	if (pm_qos_request) {
11511 		hdd_ctx->pm_qos_request = true;
11512 		if (!hdd_ctx->hbw_requested) {
11513 			hdd_pm_qos_update_cpu_mask(&pm_qos_cpu_mask, true);
11514 			hdd_pm_qos_update_request(hdd_ctx, &pm_qos_cpu_mask);
11515 			hdd_ctx->hbw_requested = true;
11516 		}
11517 	} else {
11518 		if (hdd_ctx->hbw_requested) {
11519 			hdd_pm_qos_update_cpu_mask(&pm_qos_cpu_mask, false);
11520 			hdd_pm_qos_update_request(hdd_ctx, &pm_qos_cpu_mask);
11521 			hdd_ctx->hbw_requested = false;
11522 		}
11523 		hdd_ctx->pm_qos_request = false;
11524 	}
11525 }
11526 #else /* CLD_DEV_PM_QOS */
11527 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 7, 0))
11528 void wlan_hdd_set_pm_qos_request(struct hdd_context *hdd_ctx,
11529 				 bool pm_qos_request)
11530 {
11531 	if (pm_qos_request) {
11532 		hdd_ctx->pm_qos_request = true;
11533 		if (!hdd_ctx->hbw_requested) {
11534 			cpumask_setall(&hdd_ctx->pm_qos_req.cpus_affine);
11535 			cpu_latency_qos_update_request(
11536 				&hdd_ctx->pm_qos_req,
11537 				DISABLE_KRAIT_IDLE_PS_VAL);
11538 			hdd_ctx->hbw_requested = true;
11539 		}
11540 	} else {
11541 		if (hdd_ctx->hbw_requested) {
11542 			cpumask_clear(&hdd_ctx->pm_qos_req.cpus_affine);
11543 			cpu_latency_qos_update_request(&hdd_ctx->pm_qos_req,
11544 						       PM_QOS_DEFAULT_VALUE);
11545 			hdd_ctx->hbw_requested = false;
11546 		}
11547 		hdd_ctx->pm_qos_request = false;
11548 	}
11549 }
11550 #else /* (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 7, 0)) */
11551 void wlan_hdd_set_pm_qos_request(struct hdd_context *hdd_ctx,
11552 				 bool pm_qos_request)
11553 {
11554 	if (pm_qos_request) {
11555 		hdd_ctx->pm_qos_request = true;
11556 		if (!hdd_ctx->hbw_requested) {
11557 			cpumask_setall(&hdd_ctx->pm_qos_req.cpus_affine);
11558 			pm_qos_update_request(&hdd_ctx->pm_qos_req,
11559 					      DISABLE_KRAIT_IDLE_PS_VAL);
11560 			hdd_ctx->hbw_requested = true;
11561 		}
11562 	} else {
11563 		if (hdd_ctx->hbw_requested) {
11564 			cpumask_clear(&hdd_ctx->pm_qos_req.cpus_affine);
11565 			pm_qos_update_request(&hdd_ctx->pm_qos_req,
11566 					      PM_QOS_DEFAULT_VALUE);
11567 			hdd_ctx->hbw_requested = false;
11568 		}
11569 		hdd_ctx->pm_qos_request = false;
11570 	}
11571 }
11572 #endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 7, 0)) */
11573 #endif /* CLD_DEV_PM_QOS*/
11574 #endif /* CLD_PM_QOS */
11575 
11576 #define HDD_BW_GET_DIFF(_x, _y) (unsigned long)((ULONG_MAX - (_y)) + (_x) + 1)
11577 
11578 #ifdef WLAN_FEATURE_MSCS
11579 
11580 static
11581 void hdd_send_mscs_action_frame(struct wlan_hdd_link_info *link_info)
11582 {
11583 	struct hdd_context *hdd_ctx = link_info->adapter->hdd_ctx;
11584 	uint64_t mscs_vo_pkt_delta;
11585 	unsigned long tx_vo_pkts = 0;
11586 	unsigned int cpu;
11587 	struct hdd_tx_rx_stats *stats = &link_info->hdd_stats.tx_rx_stats;
11588 	uint32_t bus_bw_compute_interval;
11589 
11590 	/*
11591 	 * To disable MSCS feature in driver set mscs_pkt_threshold = 0
11592 	 * in ini file.
11593 	 */
11594 	if (!hdd_ctx->config->mscs_pkt_threshold)
11595 		return;
11596 
11597 	for (cpu = 0; cpu < NUM_CPUS; cpu++)
11598 		tx_vo_pkts += stats->per_cpu[cpu].tx_classified_ac[SME_AC_VO];
11599 
11600 	if (!link_info->mscs_counter)
11601 		link_info->mscs_prev_tx_vo_pkts = tx_vo_pkts;
11602 
11603 	link_info->mscs_counter++;
11604 	bus_bw_compute_interval =
11605 		ucfg_dp_get_bus_bw_compute_interval(hdd_ctx->psoc);
11606 	if (link_info->mscs_counter * bus_bw_compute_interval >=
11607 	    hdd_ctx->config->mscs_voice_interval * 1000) {
11608 		link_info->mscs_counter = 0;
11609 		mscs_vo_pkt_delta =
11610 			HDD_BW_GET_DIFF(tx_vo_pkts,
11611 					link_info->mscs_prev_tx_vo_pkts);
11612 		if (mscs_vo_pkt_delta > hdd_ctx->config->mscs_pkt_threshold &&
11613 		    !mlme_get_is_mscs_req_sent(link_info->vdev))
11614 			sme_send_mscs_action_frame(link_info->vdev_id);
11615 	}
11616 }
11617 #else
11618 static inline
11619 void hdd_send_mscs_action_frame(struct wlan_hdd_link_info *link_info)
11620 {
11621 }
11622 #endif
11623 #endif /*WLAN_FEATURE_DP_BUS_BANDWIDTH*/
11624 
11625 /**
11626  * wlan_hdd_sta_get_dot11mode() - GET AP client count
11627  * @context: HDD context
11628  * @netdev: netdev
11629  * @dot11_mode: variable in which mode need to update.
11630  *
11631  * Return: true on success else false
11632  */
11633 static inline
11634 bool wlan_hdd_sta_get_dot11mode(hdd_cb_handle context, qdf_netdev_t netdev,
11635 				enum qca_wlan_802_11_mode *dot11_mode)
11636 {
11637 	struct hdd_context *hdd_ctx;
11638 	struct wlan_hdd_link_info *link_info;
11639 	struct hdd_station_ctx *sta_ctx;
11640 	struct hdd_adapter *adapter;
11641 	enum csr_cfgdot11mode mode;
11642 
11643 	hdd_ctx = hdd_cb_handle_to_context(context);
11644 	if (!hdd_ctx)
11645 		return false;
11646 
11647 	adapter = WLAN_HDD_GET_PRIV_PTR(netdev);
11648 	if (!adapter)
11649 		return false;
11650 
11651 	link_info = adapter->deflink;
11652 
11653 	sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(link_info);
11654 	mode = sta_ctx->conn_info.dot11mode;
11655 	*dot11_mode = hdd_convert_cfgdot11mode_to_80211mode(mode);
11656 	return true;
11657 }
11658 
11659 /**
11660  * wlan_hdd_get_ap_client_count() - GET AP client count
11661  * @context: HDD context
11662  * @netdev: netdev
11663  * @client_count: variable in which number of client need to update.
11664  *
11665  * Return: true on success else false
11666  */
11667 static inline
11668 bool wlan_hdd_get_ap_client_count(hdd_cb_handle context, qdf_netdev_t netdev,
11669 				  uint16_t *client_count)
11670 {
11671 	struct hdd_context *hdd_ctx;
11672 	struct wlan_hdd_link_info *link_info;
11673 	struct hdd_adapter *adapter;
11674 	struct hdd_ap_ctx *ap_ctx;
11675 	enum qca_wlan_802_11_mode i;
11676 
11677 	hdd_ctx = hdd_cb_handle_to_context(context);
11678 	if (!hdd_ctx) {
11679 		hdd_err("hdd ctx is null");
11680 		return false;
11681 	}
11682 
11683 	adapter = WLAN_HDD_GET_PRIV_PTR(netdev);
11684 	if (!adapter) {
11685 		hdd_err("adapter is null");
11686 		return false;
11687 	}
11688 
11689 	link_info = adapter->deflink;
11690 	ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(link_info);
11691 	if (!ap_ctx->ap_active)
11692 		return false;
11693 
11694 	for (i = QCA_WLAN_802_11_MODE_11B; i < QCA_WLAN_802_11_MODE_INVALID;
11695 	     i++)
11696 		client_count[i] = ap_ctx->client_count[i];
11697 
11698 	return true;
11699 }
11700 
11701 /**
11702  * wlan_hdd_sta_ndi_connected() - Check if NDI connected
11703  * @context: HDD context
11704  * @netdev: netdev
11705  *
11706  * Return: true if NDI connected else false
11707  */
11708 static inline
11709 bool wlan_hdd_sta_ndi_connected(hdd_cb_handle context, qdf_netdev_t netdev)
11710 {
11711 	struct hdd_adapter *adapter;
11712 	struct hdd_context *hdd_ctx;
11713 	struct wlan_hdd_link_info *link_info;
11714 	struct hdd_station_ctx *sta_ctx;
11715 
11716 	hdd_ctx = hdd_cb_handle_to_context(context);
11717 	if (!hdd_ctx) {
11718 		hdd_err("hdd_ctx is null");
11719 		return false;
11720 	}
11721 
11722 	adapter = WLAN_HDD_GET_PRIV_PTR(netdev);
11723 	if (!adapter) {
11724 		hdd_err("adapter is null");
11725 		return false;
11726 	}
11727 
11728 	link_info = adapter->deflink;
11729 
11730 	sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(link_info);
11731 	if (sta_ctx->conn_info.conn_state != eConnectionState_NdiConnected)
11732 		return false;
11733 
11734 	return true;
11735 }
11736 
11737 /**
11738  * wlan_hdd_pktlog_enable_disable() - Enable/Disable packet logging
11739  * @context: HDD context
11740  * @enable_disable_flag: Flag to enable/disable
11741  * @user_triggered: triggered through iwpriv
11742  * @size: buffer size to be used for packetlog
11743  *
11744  * Return: 0 on success; error number otherwise
11745  */
11746 static inline
11747 int wlan_hdd_pktlog_enable_disable(hdd_cb_handle context,
11748 				   bool enable_disable_flag,
11749 				   uint8_t user_triggered, int size)
11750 {
11751 	struct hdd_context *hdd_ctx = hdd_cb_handle_to_context(context);
11752 
11753 	if (!hdd_ctx) {
11754 		hdd_err("hdd_ctx is null");
11755 		return -EINVAL;
11756 	}
11757 	return hdd_pktlog_enable_disable(hdd_ctx, enable_disable_flag,
11758 					 user_triggered, size);
11759 }
11760 
11761 /**
11762  * wlan_hdd_is_roaming_in_progress() - Check if roaming is in progress
11763  * @context: HDD context
11764  *
11765  * Return: true if roaming is in progress else false
11766  */
11767 static inline bool wlan_hdd_is_roaming_in_progress(hdd_cb_handle context)
11768 {
11769 	struct hdd_context *hdd_ctx = hdd_cb_handle_to_context(context);
11770 
11771 	if (!hdd_ctx) {
11772 		hdd_err("hdd_ctx is null");
11773 		return false;
11774 	}
11775 	return hdd_is_roaming_in_progress(hdd_ctx);
11776 }
11777 
11778 /**
11779  * hdd_is_ap_active() - Check if AP is active
11780  * @context: HDD context
11781  * @netdev: netdev
11782  *
11783  * Return: true if AP active else false
11784  */
11785 static inline bool hdd_is_ap_active(hdd_cb_handle context, qdf_netdev_t netdev)
11786 {
11787 	struct hdd_adapter *adapter;
11788 	struct hdd_context *hdd_ctx;
11789 	struct wlan_hdd_link_info *link_info;
11790 
11791 	hdd_ctx = hdd_cb_handle_to_context(context);
11792 	if (!hdd_ctx) {
11793 		hdd_err("hdd_ctx is null");
11794 		return false;
11795 	}
11796 
11797 	adapter = WLAN_HDD_GET_PRIV_PTR(netdev);
11798 	if (!adapter) {
11799 		hdd_err("adapter is null");
11800 		return false;
11801 	}
11802 
11803 	link_info = adapter->deflink;
11804 	return WLAN_HDD_GET_AP_CTX_PTR(link_info)->ap_active;
11805 }
11806 
11807 /**
11808  * wlan_hdd_napi_apply_throughput_policy() - Apply NAPI policy
11809  * @context: HDD context
11810  * @tx_packets: tx_packets
11811  * @rx_packets: rx_packets
11812  *
11813  * Return: 0 on success else error code
11814  */
11815 static inline
11816 int wlan_hdd_napi_apply_throughput_policy(hdd_cb_handle context,
11817 					  uint64_t tx_packets,
11818 					  uint64_t rx_packets)
11819 {
11820 	struct hdd_context *hdd_ctx = hdd_cb_handle_to_context(context);
11821 	int rc = 0;
11822 
11823 	if (!hdd_ctx) {
11824 		hdd_err("hdd_ctx is null");
11825 		return 0;
11826 	}
11827 	if (hdd_ctx->config->napi_cpu_affinity_mask)
11828 		rc = hdd_napi_apply_throughput_policy(hdd_ctx, tx_packets,
11829 						      rx_packets);
11830 	return rc;
11831 }
11832 
11833 /**
11834  * hdd_is_link_adapter() - Check if adapter is link adapter
11835  * @context: HDD context
11836  * @vdev_id: Vdev ID
11837  *
11838  * Return: true if link adapter else false
11839  */
11840 static inline bool hdd_is_link_adapter(hdd_cb_handle context, uint8_t vdev_id)
11841 {
11842 	struct hdd_context *hdd_ctx;
11843 	struct wlan_hdd_link_info *link_info;
11844 
11845 	hdd_ctx = hdd_cb_handle_to_context(context);
11846 	if (!hdd_ctx) {
11847 		hdd_err("hdd_ctx is null");
11848 		return false;
11849 	}
11850 
11851 	link_info = hdd_get_link_info_by_vdev(hdd_ctx, vdev_id);
11852 	if (!link_info) {
11853 		hdd_err("Invalid vdev");
11854 		return false;
11855 	}
11856 	return hdd_adapter_is_link_adapter(link_info->adapter);
11857 }
11858 
11859 /**
11860  * hdd_get_pause_map() - Get pause map value
11861  * @context: HDD context
11862  * @netdev: netdev
11863  *
11864  * Return: pause map value
11865  */
11866 static inline
11867 uint32_t hdd_get_pause_map(hdd_cb_handle context, qdf_netdev_t netdev)
11868 {
11869 	struct hdd_adapter *adapter;
11870 
11871 	adapter = WLAN_HDD_GET_PRIV_PTR(netdev);
11872 	if (!adapter) {
11873 		hdd_err("adapter is null");
11874 		return 0;
11875 	}
11876 
11877 	return adapter->pause_map;
11878 }
11879 
11880 /**
11881  * hdd_any_adapter_connected() - Check if any adapter connected.
11882  * @context: HDD context
11883  *
11884  * Return: True if connected else false.
11885  */
11886 static inline bool hdd_any_adapter_connected(hdd_cb_handle context)
11887 {
11888 	struct hdd_context *hdd_ctx = hdd_cb_handle_to_context(context);
11889 
11890 	if (!hdd_ctx) {
11891 		hdd_err("hdd_ctx is null");
11892 		return false;
11893 	}
11894 
11895 	return hdd_is_any_adapter_connected(hdd_ctx);
11896 }
11897 
11898 #ifdef WLAN_FEATURE_DP_BUS_BANDWIDTH
11899 /**
11900  * hdd_pld_request_pm_qos() - Request PLD PM QoS request
11901  * @context: HDD context
11902  *
11903  * Return: None
11904  */
11905 static inline void hdd_pld_request_pm_qos(hdd_cb_handle context)
11906 {
11907 	struct hdd_context *hdd_ctx = hdd_cb_handle_to_context(context);
11908 
11909 	if (!hdd_ctx) {
11910 		hdd_err("hdd_ctx is null");
11911 		return;
11912 	}
11913 
11914 	if (!hdd_ctx->hbw_requested) {
11915 		PLD_REQUEST_PM_QOS(hdd_ctx->parent_dev, 1);
11916 		hdd_ctx->hbw_requested = true;
11917 	}
11918 }
11919 
11920 /**
11921  * hdd_pld_remove_pm_qos() - Remove PLD PM QoS request
11922  * @context: HDD context
11923  *
11924  * Return: None
11925  */
11926 static inline void hdd_pld_remove_pm_qos(hdd_cb_handle context)
11927 {
11928 	struct hdd_context *hdd_ctx = hdd_cb_handle_to_context(context);
11929 
11930 	if (!hdd_ctx) {
11931 		hdd_err("hdd_ctx is null");
11932 		return;
11933 	}
11934 
11935 	if (hdd_ctx->hbw_requested &&
11936 	    !hdd_ctx->pm_qos_request) {
11937 		PLD_REMOVE_PM_QOS(hdd_ctx->parent_dev);
11938 		hdd_ctx->hbw_requested = false;
11939 	}
11940 }
11941 
11942 /**
11943  * wlan_hdd_pm_qos_update_request() - Update PM QoS request
11944  * @context: HDD context
11945  * @pm_qos_cpu_mask: CPU mask
11946  *
11947  * Return: None
11948  */
11949 static inline void
11950 wlan_hdd_pm_qos_update_request(hdd_cb_handle context,
11951 			       cpumask_t *pm_qos_cpu_mask)
11952 {
11953 	struct hdd_context *hdd_ctx = hdd_cb_handle_to_context(context);
11954 
11955 	if (!hdd_ctx) {
11956 		hdd_err("hdd_ctx is null");
11957 		return;
11958 	}
11959 
11960 	if (!hdd_ctx->pm_qos_request)
11961 		hdd_pm_qos_update_request(hdd_ctx, pm_qos_cpu_mask);
11962 }
11963 
11964 /**
11965  * wlan_hdd_pm_qos_add_request() - Add PM QoS request
11966  * @context: HDD context
11967  *
11968  * Return: None
11969  */
11970 static inline void wlan_hdd_pm_qos_add_request(hdd_cb_handle context)
11971 {
11972 	struct hdd_context *hdd_ctx = hdd_cb_handle_to_context(context);
11973 
11974 	if (!hdd_ctx) {
11975 		hdd_err("hdd_ctx is null");
11976 		return;
11977 	}
11978 
11979 	hdd_pm_qos_add_request(hdd_ctx);
11980 }
11981 
11982 /**
11983  * wlan_hdd_pm_qos_remove_request() - remove PM QoS request
11984  * @context: HDD context
11985  *
11986  * Return: None
11987  */
11988 static inline void wlan_hdd_pm_qos_remove_request(hdd_cb_handle context)
11989 {
11990 	struct hdd_context *hdd_ctx = hdd_cb_handle_to_context(context);
11991 
11992 	if (!hdd_ctx) {
11993 		hdd_err("hdd_ctx is null");
11994 		return;
11995 	}
11996 
11997 	hdd_pm_qos_remove_request(hdd_ctx);
11998 }
11999 
12000 /**
12001  * wlan_hdd_send_mscs_action_frame() - Send MSCS action frame
12002  * @context: HDD context
12003  * @netdev: netdev
12004  *
12005  * Return: None
12006  */
12007 static inline void wlan_hdd_send_mscs_action_frame(hdd_cb_handle context,
12008 						   qdf_netdev_t netdev)
12009 {
12010 	struct hdd_adapter *adapter;
12011 	struct wlan_hdd_link_info *link_info;
12012 
12013 	adapter = WLAN_HDD_GET_PRIV_PTR(netdev);
12014 	if (!adapter) {
12015 		hdd_err("adapter is null");
12016 		return;
12017 	}
12018 
12019 	link_info = adapter->deflink;
12020 	hdd_send_mscs_action_frame(link_info);
12021 }
12022 
12023 #else
12024 static inline void hdd_pld_remove_pm_qos(hdd_cb_handle context)
12025 {
12026 }
12027 
12028 static inline void hdd_pld_request_pm_qos(hdd_cb_handle context)
12029 {
12030 }
12031 
12032 static inline void
12033 wlan_hdd_pm_qos_update_request(hdd_cb_handle context,
12034 			       cpumask_t *pm_qos_cpu_mask)
12035 {
12036 }
12037 
12038 static inline void wlan_hdd_pm_qos_add_request(hdd_cb_handle context)
12039 {
12040 }
12041 
12042 static inline void wlan_hdd_pm_qos_remove_request(hdd_cb_handle context)
12043 {
12044 }
12045 
12046 static inline void wlan_hdd_send_mscs_action_frame(hdd_cb_handle context,
12047 						   qdf_netdev_t netdev)
12048 {
12049 }
12050 #endif
12051 
12052 #if defined(WLAN_FEATURE_ROAM_OFFLOAD) && \
12053 defined(FEATURE_RX_LINKSPEED_ROAM_TRIGGER)
12054 void wlan_hdd_link_speed_update(struct wlan_objmgr_psoc *psoc,
12055 				uint8_t vdev_id,
12056 				bool is_link_speed_good)
12057 {
12058 	ucfg_cm_roam_link_speed_update(psoc, vdev_id, is_link_speed_good);
12059 }
12060 #endif
12061 
12062 /**
12063  * hdd_dp_register_callbacks() - Register DP callbacks with HDD
12064  * @hdd_ctx: HDD context
12065  *
12066  * Return: None
12067  */
12068 static void hdd_dp_register_callbacks(struct hdd_context *hdd_ctx)
12069 {
12070 	struct wlan_dp_psoc_callbacks cb_obj = {0};
12071 
12072 	cb_obj.callback_ctx = (hdd_cb_handle)hdd_ctx;
12073 	cb_obj.wlan_dp_sta_get_dot11mode = wlan_hdd_sta_get_dot11mode;
12074 	cb_obj.wlan_dp_get_ap_client_count = wlan_hdd_get_ap_client_count;
12075 	cb_obj.wlan_dp_sta_ndi_connected = wlan_hdd_sta_ndi_connected;
12076 	cb_obj.dp_any_adapter_connected = hdd_any_adapter_connected;
12077 	cb_obj.dp_send_svc_nlink_msg = wlan_hdd_send_svc_nlink_msg;
12078 	cb_obj.dp_pld_remove_pm_qos = hdd_pld_remove_pm_qos;
12079 	cb_obj.dp_pld_request_pm_qos = hdd_pld_request_pm_qos;
12080 	cb_obj.dp_pktlog_enable_disable = wlan_hdd_pktlog_enable_disable;
12081 	cb_obj.dp_pm_qos_update_request = wlan_hdd_pm_qos_update_request;
12082 	cb_obj.dp_pm_qos_add_request = wlan_hdd_pm_qos_add_request;
12083 	cb_obj.dp_pm_qos_remove_request = wlan_hdd_pm_qos_remove_request;
12084 	cb_obj.dp_send_mscs_action_frame = wlan_hdd_send_mscs_action_frame;
12085 	cb_obj.dp_is_roaming_in_progress = wlan_hdd_is_roaming_in_progress;
12086 	cb_obj.wlan_dp_display_tx_multiq_stats =
12087 		wlan_hdd_display_tx_multiq_stats;
12088 	cb_obj.wlan_dp_display_netif_queue_history =
12089 		wlan_hdd_display_netif_queue_history;
12090 	cb_obj.dp_is_ap_active = hdd_is_ap_active;
12091 	cb_obj.dp_napi_apply_throughput_policy =
12092 		wlan_hdd_napi_apply_throughput_policy;
12093 	cb_obj.dp_is_link_adapter = hdd_is_link_adapter;
12094 	cb_obj.dp_nud_failure_work = hdd_nud_failure_work;
12095 	cb_obj.dp_get_pause_map = hdd_get_pause_map;
12096 
12097 	cb_obj.dp_get_netdev_by_vdev_mac =
12098 		hdd_get_netdev_by_vdev_mac;
12099 	cb_obj.dp_get_tx_resource = hdd_get_tx_resource;
12100 	cb_obj.dp_get_tx_flow_low_watermark = hdd_get_tx_flow_low_watermark;
12101 	cb_obj.dp_get_tsf_time = hdd_get_tsf_time_cb;
12102 	cb_obj.dp_tsf_timestamp_rx = hdd_tsf_timestamp_rx;
12103 	cb_obj.dp_gro_rx_legacy_get_napi = hdd_legacy_gro_get_napi;
12104 	cb_obj.link_monitoring_cb = wlan_hdd_link_speed_update;
12105 
12106 	os_if_dp_register_hdd_callbacks(hdd_ctx->psoc, &cb_obj);
12107 }
12108 
12109 /**
12110  * __hdd_adapter_param_update_work() - Gist of the work to process
12111  *				       netdev feature update.
12112  * @adapter: pointer to adapter structure
12113  *
12114  * This function assumes that the adapter pointer is always valid.
12115  * So the caller should always validate adapter pointer before calling
12116  * this function
12117  *
12118  * Returns: None
12119  */
12120 static inline void
12121 __hdd_adapter_param_update_work(struct hdd_adapter *adapter)
12122 {
12123 	/**
12124 	 * This check is needed in case the work got scheduled after the
12125 	 * interface got disconnected.
12126 	 * Netdev features update is to be done only after the connection,
12127 	 * since the connection mode plays an important role in identifying
12128 	 * the features that are to be updated.
12129 	 * So in case of interface disconnect skip feature update.
12130 	 */
12131 	if (!hdd_cm_is_vdev_associated(adapter->deflink))
12132 		return;
12133 
12134 	hdd_netdev_update_features(adapter);
12135 }
12136 
12137 /**
12138  * hdd_adapter_param_update_work() - work to process the netdev features
12139  *				     update.
12140  * @arg: private data passed to work
12141  *
12142  * Returns: None
12143  */
12144 static void hdd_adapter_param_update_work(void *arg)
12145 {
12146 	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
12147 	struct hdd_adapter *adapter = arg;
12148 	struct osif_vdev_sync *vdev_sync;
12149 	int errno;
12150 
12151 	if (!hdd_ctx)
12152 		return;
12153 
12154 	hdd_adapter_ops_record_event(hdd_ctx,
12155 				     WLAN_HDD_ADAPTER_OPS_WORK_SCHED,
12156 				     WLAN_INVALID_VDEV_ID);
12157 
12158 	if (hdd_validate_adapter(adapter))
12159 		return;
12160 
12161 	errno = osif_vdev_sync_op_start(adapter->dev, &vdev_sync);
12162 	if (errno)
12163 		return;
12164 
12165 	__hdd_adapter_param_update_work(adapter);
12166 
12167 	osif_vdev_sync_op_stop(vdev_sync);
12168 }
12169 
12170 QDF_STATUS hdd_init_adapter_ops_wq(struct hdd_context *hdd_ctx)
12171 {
12172 	hdd_enter();
12173 
12174 	hdd_ctx->adapter_ops_wq =
12175 		qdf_alloc_high_prior_ordered_workqueue("hdd_adapter_ops_wq");
12176 	if (!hdd_ctx->adapter_ops_wq)
12177 		return QDF_STATUS_E_NOMEM;
12178 
12179 	hdd_exit();
12180 
12181 	return QDF_STATUS_SUCCESS;
12182 }
12183 
12184 void hdd_deinit_adapter_ops_wq(struct hdd_context *hdd_ctx)
12185 {
12186 	hdd_enter();
12187 
12188 	qdf_flush_workqueue(0, hdd_ctx->adapter_ops_wq);
12189 	qdf_destroy_workqueue(0, hdd_ctx->adapter_ops_wq);
12190 
12191 	hdd_exit();
12192 }
12193 
12194 QDF_STATUS hdd_adapter_feature_update_work_init(struct hdd_adapter *adapter)
12195 {
12196 	QDF_STATUS status;
12197 
12198 	hdd_enter();
12199 
12200 	status = qdf_create_work(0, &adapter->netdev_features_update_work,
12201 				 hdd_adapter_param_update_work, adapter);
12202 	adapter->netdev_features_update_work_status = HDD_WORK_INITIALIZED;
12203 
12204 	hdd_exit();
12205 
12206 	return status;
12207 }
12208 
12209 void hdd_adapter_feature_update_work_deinit(struct hdd_adapter *adapter)
12210 {
12211 	hdd_enter();
12212 
12213 	if (adapter->netdev_features_update_work_status !=
12214 	    HDD_WORK_INITIALIZED) {
12215 		hdd_debug("work not yet init");
12216 		return;
12217 	}
12218 	qdf_cancel_work(&adapter->netdev_features_update_work);
12219 	qdf_flush_work(&adapter->netdev_features_update_work);
12220 	adapter->netdev_features_update_work_status = HDD_WORK_UNINITIALIZED;
12221 
12222 	hdd_exit();
12223 }
12224 
12225 #define HDD_DUMP_STAT_HELP(STAT_ID) \
12226 	hdd_nofl_debug("%u -- %s", STAT_ID, (# STAT_ID))
12227 /**
12228  * hdd_display_stats_help() - print statistics help
12229  *
12230  * Return: none
12231  */
12232 static void hdd_display_stats_help(void)
12233 {
12234 	hdd_nofl_debug("iwpriv wlan0 dumpStats [option] - dump statistics");
12235 	hdd_nofl_debug("iwpriv wlan0 clearStats [option] - clear statistics");
12236 	hdd_nofl_debug("options:");
12237 	HDD_DUMP_STAT_HELP(CDP_TXRX_PATH_STATS);
12238 	HDD_DUMP_STAT_HELP(CDP_TXRX_HIST_STATS);
12239 	HDD_DUMP_STAT_HELP(CDP_TXRX_TSO_STATS);
12240 	HDD_DUMP_STAT_HELP(CDP_HDD_NETIF_OPER_HISTORY);
12241 	HDD_DUMP_STAT_HELP(CDP_DUMP_TX_FLOW_POOL_INFO);
12242 	HDD_DUMP_STAT_HELP(CDP_TXRX_DESC_STATS);
12243 	HDD_DUMP_STAT_HELP(CDP_HIF_STATS);
12244 	HDD_DUMP_STAT_HELP(CDP_NAPI_STATS);
12245 	HDD_DUMP_STAT_HELP(CDP_DP_NAPI_STATS);
12246 	HDD_DUMP_STAT_HELP(CDP_DP_RX_THREAD_STATS);
12247 }
12248 
12249 int hdd_wlan_dump_stats(struct hdd_adapter *adapter, int stats_id)
12250 {
12251 	int ret = 0;
12252 	QDF_STATUS status;
12253 	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
12254 
12255 	hdd_debug("stats_id %d", stats_id);
12256 
12257 	switch (stats_id) {
12258 	case CDP_TXRX_HIST_STATS:
12259 		ucfg_wlan_dp_display_tx_rx_histogram(hdd_ctx->psoc);
12260 		break;
12261 	case CDP_HDD_NETIF_OPER_HISTORY:
12262 		wlan_hdd_display_adapter_netif_queue_history(adapter);
12263 		break;
12264 	case CDP_HIF_STATS:
12265 		hdd_display_hif_stats();
12266 		break;
12267 	case CDP_NAPI_STATS:
12268 		if (hdd_display_napi_stats()) {
12269 			hdd_err("error displaying napi stats");
12270 			ret = -EFAULT;
12271 		}
12272 		break;
12273 	case CDP_DP_RX_THREAD_STATS:
12274 		ucfg_dp_txrx_ext_dump_stats(cds_get_context(QDF_MODULE_ID_SOC),
12275 					    CDP_DP_RX_THREAD_STATS);
12276 		break;
12277 	case CDP_DISCONNECT_STATS:
12278 		sme_display_disconnect_stats(hdd_ctx->mac_handle,
12279 					     adapter->deflink->vdev_id);
12280 		break;
12281 	default:
12282 		status = cdp_display_stats(cds_get_context(QDF_MODULE_ID_SOC),
12283 					   stats_id,
12284 					   QDF_STATS_VERBOSITY_LEVEL_HIGH);
12285 		if (status == QDF_STATUS_E_INVAL) {
12286 			hdd_display_stats_help();
12287 			ret = -EINVAL;
12288 		}
12289 		break;
12290 	}
12291 	return ret;
12292 }
12293 
12294 int hdd_wlan_clear_stats(struct hdd_adapter *adapter, int stats_id)
12295 {
12296 	QDF_STATUS status = QDF_STATUS_SUCCESS;
12297 
12298 	hdd_debug("stats_id %d", stats_id);
12299 
12300 	switch (stats_id) {
12301 	case CDP_HDD_STATS:
12302 		ucfg_dp_clear_net_dev_stats(adapter->dev);
12303 		memset(&adapter->deflink->hdd_stats, 0,
12304 		       sizeof(adapter->deflink->hdd_stats));
12305 		break;
12306 	case CDP_TXRX_HIST_STATS:
12307 		ucfg_wlan_dp_clear_tx_rx_histogram(adapter->hdd_ctx->psoc);
12308 		break;
12309 	case CDP_HDD_NETIF_OPER_HISTORY:
12310 		wlan_hdd_clear_netif_queue_history(adapter->hdd_ctx);
12311 		break;
12312 	case CDP_HIF_STATS:
12313 		hdd_clear_hif_stats();
12314 		break;
12315 	case CDP_NAPI_STATS:
12316 		hdd_clear_napi_stats();
12317 		break;
12318 	default:
12319 		status = cdp_clear_stats(cds_get_context(QDF_MODULE_ID_SOC),
12320 					 OL_TXRX_PDEV_ID,
12321 					 stats_id);
12322 		if (status != QDF_STATUS_SUCCESS)
12323 			hdd_debug("Failed to dump stats for stats_id: %d",
12324 				  stats_id);
12325 		break;
12326 	}
12327 
12328 	return qdf_status_to_os_return(status);
12329 }
12330 
12331 /* length of the netif queue log needed per adapter */
12332 #define ADAP_NETIFQ_LOG_LEN ((20 * WLAN_REASON_TYPE_MAX) + 50)
12333 
12334 /**
12335  * hdd_display_netif_queue_history_compact() - display compact netifq history
12336  * @hdd_ctx: hdd context
12337  *
12338  * Return: none
12339  */
12340 static void
12341 hdd_display_netif_queue_history_compact(struct hdd_context *hdd_ctx)
12342 {
12343 	int adapter_num = 0;
12344 	int i;
12345 	int bytes_written;
12346 	u32 tbytes;
12347 	qdf_time_t total, pause, unpause, curr_time, delta;
12348 	char temp_str[20 * WLAN_REASON_TYPE_MAX];
12349 	char *comb_log_str;
12350 	uint32_t comb_log_str_size;
12351 	struct hdd_adapter *adapter = NULL, *next_adapter = NULL;
12352 	wlan_net_dev_ref_dbgid dbgid =
12353 			NET_DEV_HOLD_DISPLAY_NETIF_QUEUE_HISTORY_COMPACT;
12354 
12355 	comb_log_str_size = (ADAP_NETIFQ_LOG_LEN * WLAN_MAX_VDEVS) + 1;
12356 	comb_log_str = qdf_mem_malloc(comb_log_str_size);
12357 	if (!comb_log_str)
12358 		return;
12359 
12360 	bytes_written = 0;
12361 
12362 	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
12363 					   dbgid) {
12364 		curr_time = qdf_system_ticks();
12365 		total = curr_time - adapter->start_time;
12366 		delta = curr_time - adapter->last_time;
12367 
12368 		if (adapter->pause_map) {
12369 			pause = adapter->total_pause_time + delta;
12370 			unpause = adapter->total_unpause_time;
12371 		} else {
12372 			unpause = adapter->total_unpause_time + delta;
12373 			pause = adapter->total_pause_time;
12374 		}
12375 
12376 		tbytes = 0;
12377 		qdf_mem_zero(temp_str, sizeof(temp_str));
12378 		for (i = WLAN_CONTROL_PATH; i < WLAN_REASON_TYPE_MAX; i++) {
12379 			if (adapter->queue_oper_stats[i].pause_count == 0)
12380 				continue;
12381 			tbytes +=
12382 				snprintf(
12383 					&temp_str[tbytes],
12384 					(tbytes >= sizeof(temp_str) ?
12385 					0 : sizeof(temp_str) - tbytes),
12386 					"%d(%d,%d) ",
12387 					i,
12388 					adapter->queue_oper_stats[i].
12389 								pause_count,
12390 					adapter->queue_oper_stats[i].
12391 								unpause_count);
12392 		}
12393 		if (tbytes >= sizeof(temp_str))
12394 			hdd_warn("log truncated");
12395 
12396 		bytes_written += snprintf(&comb_log_str[bytes_written],
12397 			bytes_written >= comb_log_str_size ? 0 :
12398 					comb_log_str_size - bytes_written,
12399 			"[%d %d] (%d) %u/%ums %s|",
12400 			adapter->deflink->vdev_id, adapter->device_mode,
12401 			adapter->pause_map,
12402 			qdf_system_ticks_to_msecs(pause),
12403 			qdf_system_ticks_to_msecs(total),
12404 			temp_str);
12405 
12406 		adapter_num++;
12407 		/* dev_put has to be done here */
12408 		hdd_adapter_dev_put_debug(adapter, dbgid);
12409 	}
12410 
12411 	/* using QDF_TRACE to avoid printing function name */
12412 	QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_INFO_LOW,
12413 		  "STATS |%s", comb_log_str);
12414 
12415 	if (bytes_written >= comb_log_str_size)
12416 		hdd_warn("log string truncated");
12417 
12418 	qdf_mem_free(comb_log_str);
12419 }
12420 
12421 /* Max size of a single netdev tx queue state string. e.g. "1: 0x1" */
12422 #define HDD_NETDEV_TX_Q_STATE_STRLEN 15
12423 /**
12424  * wlan_hdd_display_adapter_netif_queue_stats() - display adapter based
12425  * netif queue stats
12426  * @adapter: hdd adapter
12427  *
12428  * Return: none
12429  */
12430 static void
12431 wlan_hdd_display_adapter_netif_queue_stats(struct hdd_adapter *adapter)
12432 {
12433 	int i;
12434 	qdf_time_t total, pause, unpause, curr_time, delta;
12435 	struct hdd_netif_queue_history *q_hist_ptr;
12436 	char q_status_buf[NUM_TX_QUEUES * HDD_NETDEV_TX_Q_STATE_STRLEN] = {0};
12437 
12438 	hdd_nofl_debug("Netif queue operation statistics:");
12439 	hdd_nofl_debug("vdev_id %d device mode %d",
12440 		       adapter->deflink->vdev_id, adapter->device_mode);
12441 	hdd_nofl_debug("Current pause_map %x", adapter->pause_map);
12442 	curr_time = qdf_system_ticks();
12443 	total = curr_time - adapter->start_time;
12444 	delta = curr_time - adapter->last_time;
12445 	if (adapter->pause_map) {
12446 		pause = adapter->total_pause_time + delta;
12447 		unpause = adapter->total_unpause_time;
12448 	} else {
12449 		unpause = adapter->total_unpause_time + delta;
12450 		pause = adapter->total_pause_time;
12451 	}
12452 	hdd_nofl_debug("Total: %ums Pause: %ums Unpause: %ums",
12453 		       qdf_system_ticks_to_msecs(total),
12454 		       qdf_system_ticks_to_msecs(pause),
12455 		       qdf_system_ticks_to_msecs(unpause));
12456 	hdd_nofl_debug("reason_type: pause_cnt: unpause_cnt: pause_time");
12457 
12458 	for (i = WLAN_CONTROL_PATH; i < WLAN_REASON_TYPE_MAX; i++) {
12459 		qdf_time_t pause_delta = 0;
12460 
12461 		if (adapter->pause_map & (1 << i))
12462 			pause_delta = delta;
12463 
12464 		/* using hdd_log to avoid printing function name */
12465 		hdd_nofl_debug("%s: %d: %d: %ums",
12466 			       hdd_reason_type_to_string(i),
12467 			       adapter->queue_oper_stats[i].pause_count,
12468 			       adapter->queue_oper_stats[i].
12469 			       unpause_count,
12470 			       qdf_system_ticks_to_msecs(
12471 			       adapter->queue_oper_stats[i].
12472 			       total_pause_time + pause_delta));
12473 	}
12474 
12475 	hdd_nofl_debug("Netif queue operation history: Total entries: %d current index %d(-1) time %u",
12476 		       WLAN_HDD_MAX_HISTORY_ENTRY,
12477 		       adapter->history_index,
12478 		       qdf_system_ticks_to_msecs(qdf_system_ticks()));
12479 
12480 	hdd_nofl_debug("%2s%20s%50s%30s%10s  %s",
12481 		       "#", "time(ms)", "action_type", "reason_type",
12482 		       "pause_map", "netdev-queue-status");
12483 
12484 	for (i = 0; i < WLAN_HDD_MAX_HISTORY_ENTRY; i++) {
12485 		/* using hdd_log to avoid printing function name */
12486 		if (adapter->queue_oper_history[i].time == 0)
12487 			continue;
12488 		q_hist_ptr = &adapter->queue_oper_history[i];
12489 		wlan_hdd_dump_queue_history_state(q_hist_ptr,
12490 						  q_status_buf,
12491 						  sizeof(q_status_buf));
12492 		hdd_nofl_debug("%2d%20u%50s%30s%10x  %s",
12493 			       i, qdf_system_ticks_to_msecs(
12494 				adapter->queue_oper_history[i].time),
12495 				   hdd_action_type_to_string(
12496 				adapter->queue_oper_history[i].
12497 					netif_action),
12498 				   hdd_reason_type_to_string(
12499 				adapter->queue_oper_history[i].
12500 					netif_reason),
12501 				   adapter->queue_oper_history[i].pause_map,
12502 				   q_status_buf);
12503 	}
12504 }
12505 
12506 void
12507 wlan_hdd_display_adapter_netif_queue_history(struct hdd_adapter *adapter)
12508 {
12509 	wlan_hdd_display_adapter_netif_queue_stats(adapter);
12510 }
12511 
12512 /**
12513  * wlan_hdd_display_netif_queue_history() - display netif queue history
12514  * @context: hdd context
12515  * @verb_lvl: verbosity level
12516  *
12517  * Return: none
12518  */
12519 void
12520 wlan_hdd_display_netif_queue_history(hdd_cb_handle context,
12521 				     enum qdf_stats_verbosity_level verb_lvl)
12522 {
12523 	struct hdd_adapter *adapter = NULL, *next_adapter = NULL;
12524 	struct hdd_context *hdd_ctx = hdd_cb_handle_to_context(context);
12525 	wlan_net_dev_ref_dbgid dbgid =
12526 				NET_DEV_HOLD_DISPLAY_NETIF_QUEUE_HISTORY;
12527 
12528 	if (!hdd_ctx) {
12529 		hdd_err("hdd_ctx is null");
12530 		return;
12531 	}
12532 
12533 	if (verb_lvl == QDF_STATS_VERBOSITY_LEVEL_LOW) {
12534 		hdd_display_netif_queue_history_compact(hdd_ctx);
12535 		return;
12536 	}
12537 
12538 	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
12539 					   dbgid) {
12540 		if (adapter->deflink->vdev_id == CDP_INVALID_VDEV_ID) {
12541 			hdd_adapter_dev_put_debug(adapter, dbgid);
12542 			continue;
12543 		}
12544 		wlan_hdd_display_adapter_netif_queue_stats(adapter);
12545 		/* dev_put has to be done here */
12546 		hdd_adapter_dev_put_debug(adapter, dbgid);
12547 	}
12548 }
12549 
12550 /**
12551  * wlan_hdd_clear_netif_queue_history() - clear netif queue operation history
12552  * @hdd_ctx: hdd context
12553  *
12554  * Return: none
12555  */
12556 void wlan_hdd_clear_netif_queue_history(struct hdd_context *hdd_ctx)
12557 {
12558 	struct hdd_adapter *adapter = NULL, *next_adapter = NULL;
12559 	wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_CLEAR_NETIF_QUEUE_HISTORY;
12560 
12561 	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
12562 					   dbgid) {
12563 		qdf_mem_zero(adapter->queue_oper_stats,
12564 					sizeof(adapter->queue_oper_stats));
12565 		qdf_mem_zero(adapter->queue_oper_history,
12566 					sizeof(adapter->queue_oper_history));
12567 		adapter->history_index = 0;
12568 		adapter->start_time = adapter->last_time = qdf_system_ticks();
12569 		adapter->total_pause_time = 0;
12570 		adapter->total_unpause_time = 0;
12571 		hdd_adapter_dev_put_debug(adapter, dbgid);
12572 	}
12573 }
12574 
12575 #ifdef WLAN_FEATURE_OFFLOAD_PACKETS
12576 /**
12577  * hdd_init_offloaded_packets_ctx() - Initialize offload packets context
12578  * @hdd_ctx: hdd global context
12579  *
12580  * Return: none
12581  */
12582 static void hdd_init_offloaded_packets_ctx(struct hdd_context *hdd_ctx)
12583 {
12584 	uint8_t i;
12585 
12586 	mutex_init(&hdd_ctx->op_ctx.op_lock);
12587 	for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++) {
12588 		hdd_ctx->op_ctx.op_table[i].request_id = MAX_REQUEST_ID;
12589 		hdd_ctx->op_ctx.op_table[i].pattern_id = i;
12590 	}
12591 }
12592 #else
12593 static void hdd_init_offloaded_packets_ctx(struct hdd_context *hdd_ctx)
12594 {
12595 }
12596 #endif
12597 
12598 #ifdef WLAN_FEATURE_WOW_PULSE
12599 /**
12600  * wlan_hdd_set_wow_pulse() - call SME to send wmi cmd of wow pulse
12601  * @hdd_ctx: struct hdd_context structure pointer
12602  * @enable: enable or disable this behaviour
12603  *
12604  * Return: int
12605  */
12606 static int wlan_hdd_set_wow_pulse(struct hdd_context *hdd_ctx, bool enable)
12607 {
12608 	struct wow_pulse_mode wow_pulse_set_info;
12609 	QDF_STATUS status;
12610 
12611 	hdd_debug("wow pulse enable flag is %d", enable);
12612 
12613 	if (!ucfg_pmo_is_wow_pulse_enabled(hdd_ctx->psoc))
12614 		return 0;
12615 
12616 	/* prepare the request to send to SME */
12617 	if (enable == true) {
12618 		wow_pulse_set_info.wow_pulse_enable = true;
12619 		wow_pulse_set_info.wow_pulse_pin =
12620 			ucfg_pmo_get_wow_pulse_pin(hdd_ctx->psoc);
12621 
12622 		wow_pulse_set_info.wow_pulse_interval_high =
12623 		    ucfg_pmo_get_wow_pulse_interval_high(hdd_ctx->psoc);
12624 
12625 		wow_pulse_set_info.wow_pulse_interval_low =
12626 		    ucfg_pmo_get_wow_pulse_interval_low(hdd_ctx->psoc);
12627 
12628 		wow_pulse_set_info.wow_pulse_repeat_count =
12629 		    ucfg_pmo_get_wow_pulse_repeat_count(hdd_ctx->psoc);
12630 
12631 		wow_pulse_set_info.wow_pulse_init_state =
12632 		    ucfg_pmo_get_wow_pulse_init_state(hdd_ctx->psoc);
12633 	} else {
12634 		wow_pulse_set_info.wow_pulse_enable = false;
12635 		wow_pulse_set_info.wow_pulse_pin = 0;
12636 		wow_pulse_set_info.wow_pulse_interval_low = 0;
12637 		wow_pulse_set_info.wow_pulse_interval_high = 0;
12638 		wow_pulse_set_info.wow_pulse_repeat_count = 0;
12639 		wow_pulse_set_info.wow_pulse_init_state = 0;
12640 	}
12641 	hdd_debug("enable %d pin %d low %d high %d count %d init %d",
12642 		  wow_pulse_set_info.wow_pulse_enable,
12643 		  wow_pulse_set_info.wow_pulse_pin,
12644 		  wow_pulse_set_info.wow_pulse_interval_low,
12645 		  wow_pulse_set_info.wow_pulse_interval_high,
12646 		  wow_pulse_set_info.wow_pulse_repeat_count,
12647 		  wow_pulse_set_info.wow_pulse_init_state);
12648 
12649 	status = sme_set_wow_pulse(&wow_pulse_set_info);
12650 	if (QDF_STATUS_E_FAILURE == status) {
12651 		hdd_debug("sme_set_wow_pulse failure!");
12652 		return -EIO;
12653 	}
12654 	hdd_debug("sme_set_wow_pulse success!");
12655 	return 0;
12656 }
12657 #else
12658 static inline int wlan_hdd_set_wow_pulse(struct hdd_context *hdd_ctx, bool enable)
12659 {
12660 	return 0;
12661 }
12662 #endif
12663 
12664 #ifdef WLAN_FEATURE_FASTPATH
12665 
12666 /**
12667  * hdd_enable_fastpath() - Enable fastpath if enabled in config INI
12668  * @hdd_ctx: hdd context
12669  * @context: lower layer context
12670  *
12671  * Return: none
12672  */
12673 void hdd_enable_fastpath(struct hdd_context *hdd_ctx,
12674 			 void *context)
12675 {
12676 	if (cfg_get(hdd_ctx->psoc, CFG_DP_ENABLE_FASTPATH))
12677 		hif_enable_fastpath(context);
12678 }
12679 #endif
12680 
12681 #if defined(FEATURE_WLAN_CH_AVOID)
12682 /**
12683  * hdd_set_thermal_level_cb() - set thermal level callback function
12684  * @hdd_handle:	opaque handle for the hdd context
12685  * @level:	thermal level
12686  *
12687  * Change IPA data path to SW path when the thermal throttle level greater
12688  * than 0, and restore the original data path when throttle level is 0
12689  *
12690  * Return: none
12691  */
12692 static void hdd_set_thermal_level_cb(hdd_handle_t hdd_handle, u_int8_t level)
12693 {
12694 	struct hdd_context *hdd_ctx = hdd_handle_to_context(hdd_handle);
12695 
12696 	/* Change IPA to SW path when throttle level greater than 0 */
12697 	if (level > THROTTLE_LEVEL_0)
12698 		ucfg_ipa_send_mcc_scc_msg(hdd_ctx->pdev, true);
12699 	else
12700 		/* restore original concurrency mode */
12701 		ucfg_ipa_send_mcc_scc_msg(hdd_ctx->pdev, hdd_ctx->mcc_mode);
12702 }
12703 #else
12704 /**
12705  * hdd_set_thermal_level_cb() - set thermal level callback function
12706  * @hdd_handle:	opaque handle for the hdd context
12707  * @level:	thermal level
12708  *
12709  * Change IPA data path to SW path when the thermal throttle level greater
12710  * than 0, and restore the original data path when throttle level is 0
12711  *
12712  * Return: none
12713  */
12714 static void hdd_set_thermal_level_cb(hdd_handle_t hdd_handle, u_int8_t level)
12715 {
12716 }
12717 #endif
12718 
12719 QDF_STATUS hdd_switch_sap_channel(struct wlan_hdd_link_info *link_info,
12720 				  uint8_t channel, bool forced)
12721 {
12722 	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(link_info->adapter);
12723 	mac_handle_t mac_handle;
12724 	struct sap_config *sap_cfg;
12725 	qdf_freq_t freq;
12726 
12727 	mac_handle = hdd_adapter_get_mac_handle(link_info->adapter);
12728 	if (!mac_handle) {
12729 		hdd_err("invalid MAC handle");
12730 		return QDF_STATUS_E_INVAL;
12731 	}
12732 
12733 	freq = wlan_reg_legacy_chan_to_freq(hdd_ctx->pdev, channel);
12734 	sap_cfg = &(WLAN_HDD_GET_AP_CTX_PTR(link_info)->sap_config);
12735 	hdd_debug("chan:%d width:%d", channel, sap_cfg->ch_width_orig);
12736 
12737 	return policy_mgr_change_sap_channel_with_csa(hdd_ctx->psoc,
12738 						      link_info->vdev_id, freq,
12739 						      sap_cfg->ch_width_orig,
12740 						      forced);
12741 }
12742 
12743 QDF_STATUS hdd_switch_sap_chan_freq(struct hdd_adapter *adapter,
12744 				    qdf_freq_t chan_freq,
12745 				    enum phy_ch_width ch_width,
12746 				    bool forced)
12747 {
12748 	struct hdd_ap_ctx *hdd_ap_ctx;
12749 	struct hdd_context *hdd_ctx;
12750 
12751 	if (hdd_validate_adapter(adapter))
12752 		return QDF_STATUS_E_INVAL;
12753 
12754 	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
12755 
12756 	if(wlan_hdd_validate_context(hdd_ctx))
12757 		return QDF_STATUS_E_INVAL;
12758 
12759 	hdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(adapter->deflink);
12760 
12761 	hdd_debug("chan freq:%d width:%d org bw %d",
12762 		  chan_freq, ch_width, hdd_ap_ctx->sap_config.ch_width_orig);
12763 
12764 	return policy_mgr_change_sap_channel_with_csa(hdd_ctx->psoc,
12765 						      adapter->deflink->vdev_id,
12766 						      chan_freq,
12767 						      ch_width,
12768 						      forced);
12769 }
12770 
12771 int hdd_update_acs_timer_reason(struct hdd_adapter *adapter, uint8_t reason)
12772 {
12773 	struct hdd_external_acs_timer_context *timer_context;
12774 	int status;
12775 	QDF_STATUS qdf_status;
12776 	qdf_mc_timer_t *vendor_acs_timer;
12777 
12778 	set_bit(VENDOR_ACS_RESPONSE_PENDING, &adapter->deflink->link_flags);
12779 
12780 	vendor_acs_timer = &adapter->deflink->session.ap.vendor_acs_timer;
12781 	if (QDF_TIMER_STATE_RUNNING ==
12782 	    qdf_mc_timer_get_current_state(vendor_acs_timer)) {
12783 		qdf_mc_timer_stop(vendor_acs_timer);
12784 	}
12785 	timer_context =
12786 		(struct hdd_external_acs_timer_context *)vendor_acs_timer->user_data;
12787 	timer_context->reason = reason;
12788 	qdf_status =
12789 		qdf_mc_timer_start(vendor_acs_timer, WLAN_VENDOR_ACS_WAIT_TIME);
12790 	if (qdf_status != QDF_STATUS_SUCCESS) {
12791 		hdd_err("failed to start external acs timer");
12792 		return -ENOSPC;
12793 	}
12794 	/* Update config to application */
12795 	status = hdd_cfg80211_update_acs_config(adapter, reason);
12796 	hdd_info("Updated ACS config to nl with reason %d", reason);
12797 
12798 	return status;
12799 }
12800 
12801 #ifdef FEATURE_WLAN_CH_AVOID_EXT
12802 uint32_t wlan_hdd_get_restriction_mask(struct hdd_context *hdd_ctx)
12803 {
12804 	return hdd_ctx->restriction_mask;
12805 }
12806 
12807 void wlan_hdd_set_restriction_mask(struct hdd_context *hdd_ctx)
12808 {
12809 	hdd_ctx->restriction_mask =
12810 		hdd_ctx->coex_avoid_freq_list.restriction_mask;
12811 }
12812 #else
12813 uint32_t wlan_hdd_get_restriction_mask(struct hdd_context *hdd_ctx)
12814 {
12815 	return -EINVAL;
12816 }
12817 
12818 void wlan_hdd_set_restriction_mask(struct hdd_context *hdd_ctx)
12819 {
12820 }
12821 #endif
12822 
12823 #if defined(FEATURE_WLAN_CH_AVOID)
12824 /**
12825  * hdd_store_sap_restart_channel() - store sap restart channel
12826  * @restart_chan: restart channel
12827  * @restart_chan_store: pointer to restart channel store
12828  *
12829  * The function will store new sap restart channel.
12830  *
12831  * Return - none
12832  */
12833 static void
12834 hdd_store_sap_restart_channel(qdf_freq_t restart_chan, qdf_freq_t *restart_chan_store)
12835 {
12836 	uint8_t i;
12837 
12838 	for (i = 0; i < SAP_MAX_NUM_SESSION; i++) {
12839 		if (*(restart_chan_store + i) == restart_chan)
12840 			return;
12841 
12842 		if (*(restart_chan_store + i))
12843 			continue;
12844 
12845 		*(restart_chan_store + i) = restart_chan;
12846 		return;
12847 	}
12848 }
12849 
12850 /**
12851  * hdd_check_chn_bw_boundary_unsafe() - check channel range unsafe
12852  * @hdd_ctxt: hdd context pointer
12853  * @adapter:  hdd adapter pointer
12854  *
12855  * hdd_check_chn_bw_boundary_unsafe check SAP channel range with certain
12856  * bandwidth whether cover all unsafe channel list.
12857  *
12858  * Return - bool
12859  */
12860 static bool
12861 hdd_check_chn_bw_boundary_unsafe(struct hdd_context *hdd_ctxt,
12862 				 struct hdd_adapter *adapter)
12863 {
12864 	uint32_t freq;
12865 	uint32_t start_freq = 0;
12866 	uint32_t end_freq = 0;
12867 	uint32_t i;
12868 	uint8_t ch_width;
12869 	const struct bonded_channel_freq *bonded_chan_ptr_ptr = NULL;
12870 
12871 	freq = adapter->deflink->session.ap.operating_chan_freq;
12872 	ch_width = adapter->deflink->session.ap.sap_config.acs_cfg.ch_width;
12873 
12874 	if (ch_width > CH_WIDTH_20MHZ)
12875 		bonded_chan_ptr_ptr =
12876 			wlan_reg_get_bonded_chan_entry(freq, ch_width, 0);
12877 
12878 	if (bonded_chan_ptr_ptr) {
12879 		start_freq = bonded_chan_ptr_ptr->start_freq;
12880 		end_freq   = bonded_chan_ptr_ptr->end_freq;
12881 	}
12882 
12883 	for (i = 0; i < hdd_ctxt->unsafe_channel_count; i++) {
12884 		if ((freq == hdd_ctxt->unsafe_channel_list[i]) ||
12885 		    (start_freq <= hdd_ctxt->unsafe_channel_list[i] &&
12886 		     hdd_ctxt->unsafe_channel_list[i] <= end_freq)) {
12887 			hdd_debug("op chn freq:%u is unsafe for chn list:%u",
12888 				  freq, hdd_ctxt->unsafe_channel_list[i]);
12889 			return true;
12890 		}
12891 	}
12892 
12893 	return false;
12894 }
12895 
12896 /**
12897  * hdd_unsafe_channel_restart_sap() - restart sap if sap is on unsafe channel
12898  * @hdd_ctx: hdd context pointer
12899  *
12900  * hdd_unsafe_channel_restart_sap check all unsafe channel list
12901  * and if ACS is enabled, driver will ask userspace to restart the
12902  * sap. User space on LTE coex indication restart driver.
12903  *
12904  * Return - none
12905  */
12906 QDF_STATUS hdd_unsafe_channel_restart_sap(struct hdd_context *hdd_ctx)
12907 {
12908 	struct hdd_adapter *adapter, *next_adapter = NULL;
12909 	struct hdd_ap_ctx *ap_ctx;
12910 	uint32_t i;
12911 	bool found = false;
12912 	qdf_freq_t restart_chan_store[SAP_MAX_NUM_SESSION] = {0};
12913 	uint8_t scc_on_lte_coex = 0;
12914 	uint32_t restart_freq, ap_chan_freq;
12915 	bool value;
12916 	QDF_STATUS status;
12917 	bool is_acs_support_for_dfs_ltecoex = cfg_default(CFG_USER_ACS_DFS_LTE);
12918 	bool is_vendor_acs_support =
12919 		cfg_default(CFG_USER_AUTO_CHANNEL_SELECTION);
12920 	wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_UNSAFE_CHANNEL_RESTART_SAP;
12921 	enum phy_ch_width ch_width;
12922 	struct wlan_hdd_link_info *link_info;
12923 
12924 	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
12925 					   dbgid) {
12926 		if (adapter->device_mode != QDF_SAP_MODE) {
12927 			hdd_debug_rl("skip device mode:%d",
12928 				     adapter->device_mode);
12929 			hdd_adapter_dev_put_debug(adapter, dbgid);
12930 			continue;
12931 		}
12932 
12933 		hdd_adapter_for_each_active_link_info(adapter, link_info) {
12934 			ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(link_info);
12935 			if (!ap_ctx->sap_config.acs_cfg.acs_mode) {
12936 				hdd_debug_rl("skip acs:%d",
12937 					     ap_ctx->sap_config.acs_cfg.acs_mode);
12938 				continue;
12939 			}
12940 
12941 			ap_chan_freq = ap_ctx->operating_chan_freq;
12942 			ch_width = ap_ctx->sap_config.ch_width_orig;
12943 			found = false;
12944 			status =
12945 			ucfg_policy_mgr_get_sta_sap_scc_lte_coex_chnl(hdd_ctx->psoc,
12946 								      &scc_on_lte_coex);
12947 			if (!QDF_IS_STATUS_SUCCESS(status))
12948 				hdd_err("can't get scc on lte coex chnl, use def");
12949 			/*
12950 			 * If STA+SAP is doing SCC &
12951 			 * g_sta_sap_scc_on_lte_coex_chan is set,
12952 			 * no need to move SAP.
12953 			 */
12954 			if ((policy_mgr_is_sta_sap_scc(hdd_ctx->psoc,
12955 						       ap_chan_freq) &&
12956 			     scc_on_lte_coex) ||
12957 			    policy_mgr_nan_sap_scc_on_unsafe_ch_chk(hdd_ctx->psoc,
12958 								    ap_chan_freq))
12959 				hdd_debug("SAP allowed in unsafe SCC channel");
12960 			else
12961 				found = hdd_check_chn_bw_boundary_unsafe(hdd_ctx,
12962 									 adapter);
12963 			if (!found) {
12964 				hdd_store_sap_restart_channel(ap_chan_freq,
12965 							      restart_chan_store);
12966 				hdd_debug("ch freq:%d is safe. no need to change channel",
12967 					  ap_chan_freq);
12968 				continue;
12969 			}
12970 
12971 			status = ucfg_mlme_get_acs_support_for_dfs_ltecoex(
12972 						hdd_ctx->psoc,
12973 						&is_acs_support_for_dfs_ltecoex);
12974 			if (!QDF_IS_STATUS_SUCCESS(status))
12975 				hdd_err("get_acs_support_for_dfs_ltecoex failed,set def");
12976 
12977 			status = ucfg_mlme_get_vendor_acs_support(
12978 						hdd_ctx->psoc,
12979 						&is_vendor_acs_support);
12980 			if (!QDF_IS_STATUS_SUCCESS(status))
12981 				hdd_err("get_vendor_acs_support failed, set default");
12982 
12983 			if (is_vendor_acs_support &&
12984 			    is_acs_support_for_dfs_ltecoex) {
12985 				hdd_update_acs_timer_reason(adapter,
12986 				    QCA_WLAN_VENDOR_ACS_SELECT_REASON_LTE_COEX);
12987 				continue;
12988 			}
12989 
12990 			restart_freq = 0;
12991 			for (i = 0; i < SAP_MAX_NUM_SESSION; i++) {
12992 				if (!restart_chan_store[i])
12993 					continue;
12994 
12995 				if (policy_mgr_is_force_scc(hdd_ctx->psoc) &&
12996 				    WLAN_REG_IS_SAME_BAND_FREQS(
12997 						restart_chan_store[i],
12998 						ap_chan_freq)) {
12999 					restart_freq = restart_chan_store[i];
13000 					break;
13001 				}
13002 			}
13003 			if (!restart_freq) {
13004 				restart_freq =
13005 					wlansap_get_safe_channel_from_pcl_and_acs_range(
13006 					    WLAN_HDD_GET_SAP_CTX_PTR(link_info),
13007 					    &ch_width);
13008 			}
13009 			if (!restart_freq) {
13010 				wlan_hdd_set_sap_csa_reason(hdd_ctx->psoc,
13011 							    link_info->vdev_id,
13012 							    CSA_REASON_UNSAFE_CHANNEL);
13013 				hdd_err("Unable to find safe chan, Stop the SAP if restriction mask is set else set txpower");
13014 				hdd_stop_sap_set_tx_power(hdd_ctx->psoc, adapter);
13015 				continue;
13016 			}
13017 			/*
13018 			 * SAP restart due to unsafe channel. While
13019 			 * restarting the SAP, make sure to clear
13020 			 * acs_channel, channel to reset to
13021 			 * 0. Otherwise these settings will override
13022 			 * the ACS while restart.
13023 			 */
13024 			hdd_ctx->acs_policy.acs_chan_freq =
13025 						AUTO_CHANNEL_SELECT;
13026 			ucfg_mlme_get_sap_internal_restart(hdd_ctx->psoc,
13027 							   &value);
13028 			if (value) {
13029 				wlan_hdd_set_sap_csa_reason(hdd_ctx->psoc,
13030 						    link_info->vdev_id,
13031 						    CSA_REASON_UNSAFE_CHANNEL);
13032 				status = hdd_switch_sap_chan_freq(adapter,
13033 								  restart_freq,
13034 								  ch_width,
13035 								  true);
13036 				if (QDF_IS_STATUS_SUCCESS(status)) {
13037 					hdd_adapter_dev_put_debug(adapter,
13038 								  dbgid);
13039 					if (next_adapter)
13040 						hdd_adapter_dev_put_debug(
13041 								next_adapter,
13042 								dbgid);
13043 					return QDF_STATUS_E_PENDING;
13044 				} else {
13045 					hdd_debug("CSA failed, check next SAP");
13046 				}
13047 			} else {
13048 				hdd_debug("sending coex indication");
13049 				wlan_hdd_send_svc_nlink_msg(
13050 						hdd_ctx->radio_index,
13051 						WLAN_SVC_LTE_COEX_IND, NULL, 0);
13052 				hdd_adapter_dev_put_debug(adapter, dbgid);
13053 				if (next_adapter)
13054 					hdd_adapter_dev_put_debug(next_adapter,
13055 								  dbgid);
13056 				return QDF_STATUS_SUCCESS;
13057 			}
13058 		}
13059 		/* dev_put has to be done here */
13060 		hdd_adapter_dev_put_debug(adapter, dbgid);
13061 	}
13062 
13063 	return QDF_STATUS_SUCCESS;
13064 }
13065 
13066 /**
13067  * hdd_init_channel_avoidance() - Initialize channel avoidance
13068  * @hdd_ctx:	HDD global context
13069  *
13070  * Initialize the channel avoidance logic by retrieving the unsafe
13071  * channel list from the platform driver and plumbing the data
13072  * down to the lower layers.  Then subscribe to subsequent channel
13073  * avoidance events.
13074  *
13075  * Return: None
13076  */
13077 static void hdd_init_channel_avoidance(struct hdd_context *hdd_ctx)
13078 {
13079 	uint16_t unsafe_channel_count;
13080 	int index;
13081 	qdf_freq_t *unsafe_freq_list;
13082 
13083 	pld_get_wlan_unsafe_channel(hdd_ctx->parent_dev,
13084 				    hdd_ctx->unsafe_channel_list,
13085 				     &(hdd_ctx->unsafe_channel_count),
13086 				     sizeof(uint16_t) * NUM_CHANNELS);
13087 
13088 	hdd_debug("num of unsafe channels is %d",
13089 	       hdd_ctx->unsafe_channel_count);
13090 
13091 	unsafe_channel_count = QDF_MIN((uint16_t)hdd_ctx->unsafe_channel_count,
13092 				       (uint16_t)NUM_CHANNELS);
13093 
13094 	if (!unsafe_channel_count)
13095 		return;
13096 
13097 	unsafe_freq_list = qdf_mem_malloc(
13098 			unsafe_channel_count * sizeof(*unsafe_freq_list));
13099 
13100 	if (!unsafe_freq_list)
13101 		return;
13102 
13103 	for (index = 0; index < unsafe_channel_count; index++) {
13104 		hdd_debug("channel frequency %d is not safe",
13105 			  hdd_ctx->unsafe_channel_list[index]);
13106 		unsafe_freq_list[index] =
13107 			(qdf_freq_t)hdd_ctx->unsafe_channel_list[index];
13108 	}
13109 
13110 	ucfg_policy_mgr_init_chan_avoidance(
13111 		hdd_ctx->psoc,
13112 		unsafe_freq_list,
13113 		unsafe_channel_count);
13114 
13115 	qdf_mem_free(unsafe_freq_list);
13116 }
13117 
13118 static void hdd_lte_coex_restart_sap(struct hdd_adapter *adapter,
13119 				     struct hdd_context *hdd_ctx)
13120 {
13121 	uint8_t restart_chan;
13122 	uint32_t restart_freq;
13123 
13124 	restart_freq = wlansap_get_safe_channel_from_pcl_and_acs_range(
13125 				WLAN_HDD_GET_SAP_CTX_PTR(adapter->deflink),
13126 				NULL);
13127 
13128 	restart_chan = wlan_reg_freq_to_chan(hdd_ctx->pdev,
13129 					     restart_freq);
13130 
13131 	if (!restart_chan) {
13132 		hdd_alert("fail to restart SAP");
13133 		return;
13134 	}
13135 
13136 	/* SAP restart due to unsafe channel. While restarting
13137 	 * the SAP, make sure to clear acs_channel, channel to
13138 	 * reset to 0. Otherwise these settings will override
13139 	 * the ACS while restart.
13140 	 */
13141 	hdd_ctx->acs_policy.acs_chan_freq = AUTO_CHANNEL_SELECT;
13142 
13143 	hdd_debug("sending coex indication");
13144 
13145 	wlan_hdd_send_svc_nlink_msg(hdd_ctx->radio_index,
13146 				    WLAN_SVC_LTE_COEX_IND, NULL, 0);
13147 	wlan_hdd_set_sap_csa_reason(hdd_ctx->psoc, adapter->deflink->vdev_id,
13148 				    CSA_REASON_LTE_COEX);
13149 	hdd_switch_sap_channel(adapter->deflink, restart_chan, true);
13150 }
13151 
13152 int hdd_clone_local_unsafe_chan(struct hdd_context *hdd_ctx,
13153 	uint16_t **local_unsafe_list, uint16_t *local_unsafe_list_count)
13154 {
13155 	uint32_t size;
13156 	uint16_t *unsafe_list;
13157 	uint16_t chan_count;
13158 
13159 	if (!hdd_ctx || !local_unsafe_list_count || !local_unsafe_list_count)
13160 		return -EINVAL;
13161 
13162 	chan_count = QDF_MIN(hdd_ctx->unsafe_channel_count,
13163 			     NUM_CHANNELS);
13164 	if (chan_count) {
13165 		size = chan_count * sizeof(hdd_ctx->unsafe_channel_list[0]);
13166 		unsafe_list = qdf_mem_malloc(size);
13167 		if (!unsafe_list)
13168 			return -ENOMEM;
13169 		qdf_mem_copy(unsafe_list, hdd_ctx->unsafe_channel_list, size);
13170 	} else {
13171 		unsafe_list = NULL;
13172 	}
13173 
13174 	*local_unsafe_list = unsafe_list;
13175 	*local_unsafe_list_count = chan_count;
13176 
13177 	return 0;
13178 }
13179 
13180 bool hdd_local_unsafe_channel_updated(
13181 	struct hdd_context *hdd_ctx, uint16_t *local_unsafe_list,
13182 	uint16_t local_unsafe_list_count, uint32_t restriction_mask)
13183 {
13184 	int i, j;
13185 
13186 	if (local_unsafe_list_count != hdd_ctx->unsafe_channel_count)
13187 		return true;
13188 	if (local_unsafe_list_count == 0)
13189 		return false;
13190 	for (i = 0; i < local_unsafe_list_count; i++) {
13191 		for (j = 0; j < local_unsafe_list_count; j++)
13192 			if (local_unsafe_list[i] ==
13193 			    hdd_ctx->unsafe_channel_list[j])
13194 				break;
13195 		if (j >= local_unsafe_list_count)
13196 			break;
13197 	}
13198 
13199 	if (ucfg_mlme_get_coex_unsafe_chan_nb_user_prefer(hdd_ctx->psoc)) {
13200 		/* Return false if current channel list is same as previous
13201 		 * and restriction mask is not altered
13202 		 */
13203 		if (i >= local_unsafe_list_count &&
13204 		    (restriction_mask ==
13205 		     wlan_hdd_get_restriction_mask(hdd_ctx))) {
13206 			hdd_info("unsafe chan list same");
13207 			return false;
13208 		}
13209 	} else if (i >= local_unsafe_list_count) {
13210 		hdd_info("unsafe chan list same");
13211 		return false;
13212 	}
13213 
13214 	return true;
13215 }
13216 #else
13217 static void hdd_init_channel_avoidance(struct hdd_context *hdd_ctx)
13218 {
13219 }
13220 
13221 static inline void hdd_lte_coex_restart_sap(struct hdd_adapter *adapter,
13222 					    struct hdd_context *hdd_ctx)
13223 {
13224 	hdd_debug("Channel avoidance is not enabled; Abort SAP restart");
13225 }
13226 #endif /* defined(FEATURE_WLAN_CH_AVOID) */
13227 
13228 struct wlan_hdd_link_info *
13229 wlan_hdd_get_link_info_from_objmgr(struct wlan_objmgr_vdev *vdev)
13230 {
13231 	if (!vdev) {
13232 		hdd_err("null vdev object");
13233 		return NULL;
13234 	}
13235 
13236 	if (vdev->vdev_nif.osdev)
13237 		return vdev->vdev_nif.osdev->legacy_osif_priv;
13238 
13239 	return NULL;
13240 }
13241 
13242 /**
13243  * hdd_indicate_mgmt_frame() - Wrapper to indicate management frame to
13244  * user space
13245  * @frame_ind: Management frame data to be informed.
13246  *
13247  * This function is used to indicate management frame to
13248  * user space
13249  *
13250  * Return: None
13251  *
13252  */
13253 void hdd_indicate_mgmt_frame(tSirSmeMgmtFrameInd *frame_ind)
13254 {
13255 	struct hdd_context *hdd_ctx = NULL;
13256 	struct hdd_adapter *adapter = NULL, *next_adapter = NULL;
13257 	int i, num_adapters;
13258 	uint8_t vdev_id[WLAN_MAX_VDEVS + WLAN_MAX_ML_VDEVS];
13259 	struct ieee80211_mgmt *mgmt =
13260 		(struct ieee80211_mgmt *)frame_ind->frameBuf;
13261 	struct wlan_objmgr_vdev *vdev;
13262 	wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_INDICATE_MGMT_FRAME;
13263 	struct wlan_hdd_link_info *link_info;
13264 
13265 	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
13266 	if (wlan_hdd_validate_context(hdd_ctx))
13267 		return;
13268 
13269 	if (frame_ind->frame_len < ieee80211_hdrlen(mgmt->frame_control)) {
13270 		hdd_err(" Invalid frame length");
13271 		return;
13272 	}
13273 
13274 	if (SME_SESSION_ID_ANY == frame_ind->sessionId) {
13275 		for (i = 0; i < WLAN_MAX_VDEVS; i++) {
13276 			link_info = hdd_get_link_info_by_vdev(hdd_ctx, i);
13277 			if (link_info) {
13278 				adapter = link_info->adapter;
13279 				break;
13280 			}
13281 		}
13282 	} else if (SME_SESSION_ID_BROADCAST == frame_ind->sessionId) {
13283 		num_adapters = 0;
13284 		hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter,
13285 						   next_adapter, dbgid) {
13286 			hdd_adapter_for_each_active_link_info(adapter,
13287 							      link_info) {
13288 				vdev_id[num_adapters] = link_info->vdev_id;
13289 				num_adapters++;
13290 			}
13291 			/* dev_put has to be done here */
13292 			hdd_adapter_dev_put_debug(adapter, dbgid);
13293 		}
13294 
13295 		adapter = NULL;
13296 
13297 		for (i = 0; i < num_adapters; i++) {
13298 			vdev = wlan_objmgr_get_vdev_by_id_from_psoc(
13299 							hdd_ctx->psoc,
13300 							vdev_id[i],
13301 							WLAN_OSIF_ID);
13302 
13303 			if (!vdev)
13304 				continue;
13305 
13306 			link_info = wlan_hdd_get_link_info_from_objmgr(vdev);
13307 			if (!link_info) {
13308 				wlan_objmgr_vdev_release_ref(vdev,
13309 							     WLAN_OSIF_ID);
13310 				continue;
13311 			}
13312 
13313 			hdd_indicate_mgmt_frame_to_user(link_info->adapter,
13314 							frame_ind->frame_len,
13315 							frame_ind->frameBuf,
13316 							frame_ind->frameType,
13317 							frame_ind->rx_freq,
13318 							frame_ind->rxRssi,
13319 							frame_ind->rx_flags);
13320 			wlan_objmgr_vdev_release_ref(vdev, WLAN_OSIF_ID);
13321 		}
13322 
13323 		adapter = NULL;
13324 	} else {
13325 		link_info = hdd_get_link_info_by_vdev(hdd_ctx,
13326 						      frame_ind->sessionId);
13327 
13328 		if (!link_info) {
13329 			hdd_err("Invalid vdev");
13330 			return;
13331 		}
13332 
13333 		adapter = link_info->adapter;
13334 	}
13335 
13336 	if ((adapter) &&
13337 		(WLAN_HDD_ADAPTER_MAGIC == adapter->magic))
13338 		hdd_indicate_mgmt_frame_to_user(adapter,
13339 						frame_ind->frame_len,
13340 						frame_ind->frameBuf,
13341 						frame_ind->frameType,
13342 						frame_ind->rx_freq,
13343 						frame_ind->rxRssi,
13344 						frame_ind->rx_flags);
13345 }
13346 
13347 void hdd_acs_response_timeout_handler(void *context)
13348 {
13349 	struct hdd_external_acs_timer_context *timer_context =
13350 			(struct hdd_external_acs_timer_context *)context;
13351 	struct hdd_adapter *adapter;
13352 	struct hdd_context *hdd_ctx;
13353 	uint8_t reason;
13354 	struct sap_context *sap_context;
13355 	struct wlan_hdd_link_info *link_info;
13356 
13357 	hdd_enter();
13358 	if (!timer_context) {
13359 		hdd_err("invalid timer context");
13360 		return;
13361 	}
13362 	adapter = timer_context->adapter;
13363 	reason = timer_context->reason;
13364 
13365 	if (!adapter || adapter->magic != WLAN_HDD_ADAPTER_MAGIC) {
13366 		hdd_err("invalid adapter or adapter has invalid magic");
13367 		return;
13368 	}
13369 
13370 	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
13371 	if (wlan_hdd_validate_context(hdd_ctx))
13372 		return;
13373 
13374 	link_info = adapter->deflink;
13375 	if (!test_bit(VENDOR_ACS_RESPONSE_PENDING, &link_info->link_flags))
13376 		return;
13377 
13378 	clear_bit(VENDOR_ACS_RESPONSE_PENDING, &link_info->link_flags);
13379 
13380 	hdd_err("ACS timeout happened for %s reason %d",
13381 		adapter->dev->name, reason);
13382 
13383 	sap_context = WLAN_HDD_GET_SAP_CTX_PTR(link_info);
13384 	switch (reason) {
13385 	/* SAP init case */
13386 	case QCA_WLAN_VENDOR_ACS_SELECT_REASON_INIT:
13387 		wlan_sap_set_vendor_acs(sap_context, false);
13388 		wlan_hdd_cfg80211_start_acs(link_info);
13389 		break;
13390 	/* DFS detected on current channel */
13391 	case QCA_WLAN_VENDOR_ACS_SELECT_REASON_DFS:
13392 		wlan_sap_update_next_channel(sap_context, 0, 0);
13393 		sme_update_new_channel_event(hdd_ctx->mac_handle,
13394 					     link_info->vdev_id);
13395 		break;
13396 	/* LTE coex event on current channel */
13397 	case QCA_WLAN_VENDOR_ACS_SELECT_REASON_LTE_COEX:
13398 		hdd_lte_coex_restart_sap(adapter, hdd_ctx);
13399 		break;
13400 	default:
13401 		hdd_info("invalid reason for timer invoke");
13402 	}
13403 }
13404 
13405 /**
13406  * hdd_override_ini_config - Override INI config
13407  * @hdd_ctx: HDD context
13408  *
13409  * Override INI config based on module parameter.
13410  *
13411  * Return: None
13412  */
13413 static void hdd_override_ini_config(struct hdd_context *hdd_ctx)
13414 {
13415 	QDF_STATUS status;
13416 
13417 	if (0 == enable_dfs_chan_scan || 1 == enable_dfs_chan_scan) {
13418 		ucfg_scan_cfg_set_dfs_chan_scan_allowed(hdd_ctx->psoc,
13419 							enable_dfs_chan_scan);
13420 		hdd_debug("Module enable_dfs_chan_scan set to %d",
13421 			   enable_dfs_chan_scan);
13422 	}
13423 	if (0 == enable_11d || 1 == enable_11d) {
13424 		status = ucfg_mlme_set_11d_enabled(hdd_ctx->psoc, enable_11d);
13425 		if (!QDF_IS_STATUS_SUCCESS(status))
13426 			hdd_err("Failed to set 11d_enable flag");
13427 	}
13428 }
13429 
13430 #ifdef ENABLE_MTRACE_LOG
13431 static void hdd_set_mtrace_for_each(struct hdd_context *hdd_ctx)
13432 {
13433 	uint8_t module_id = 0;
13434 	int qdf_print_idx = -1;
13435 
13436 	qdf_print_idx = qdf_get_pidx();
13437 	for (module_id = 0; module_id < QDF_MODULE_ID_MAX; module_id++)
13438 		qdf_print_set_category_verbose(
13439 					qdf_print_idx,
13440 					module_id, QDF_TRACE_LEVEL_TRACE,
13441 					hdd_ctx->config->enable_mtrace);
13442 }
13443 #else
13444 static void hdd_set_mtrace_for_each(struct hdd_context *hdd_ctx)
13445 {
13446 }
13447 
13448 #endif
13449 
13450 /**
13451  * hdd_log_level_to_bitmask() - user space log level to host log bitmask
13452  * @user_log_level: user space log level
13453  *
13454  * Convert log level from user space to host log level bitmask.
13455  *
13456  * Return: Bitmask of log levels to be enabled
13457  */
13458 static uint32_t hdd_log_level_to_bitmask(enum host_log_level user_log_level)
13459 {
13460 	QDF_TRACE_LEVEL host_trace_level;
13461 	uint32_t bitmask;
13462 
13463 	switch (user_log_level) {
13464 	case HOST_LOG_LEVEL_NONE:
13465 		host_trace_level = QDF_TRACE_LEVEL_NONE;
13466 		break;
13467 	case HOST_LOG_LEVEL_FATAL:
13468 		host_trace_level = QDF_TRACE_LEVEL_FATAL;
13469 		break;
13470 	case HOST_LOG_LEVEL_ERROR:
13471 		host_trace_level = QDF_TRACE_LEVEL_ERROR;
13472 		break;
13473 	case HOST_LOG_LEVEL_WARN:
13474 		host_trace_level = QDF_TRACE_LEVEL_WARN;
13475 		break;
13476 	case HOST_LOG_LEVEL_INFO:
13477 		host_trace_level = QDF_TRACE_LEVEL_INFO_LOW;
13478 		break;
13479 	case HOST_LOG_LEVEL_DEBUG:
13480 		host_trace_level = QDF_TRACE_LEVEL_DEBUG;
13481 		break;
13482 	case HOST_LOG_LEVEL_TRACE:
13483 		host_trace_level = QDF_TRACE_LEVEL_TRACE;
13484 		break;
13485 	default:
13486 		host_trace_level = QDF_TRACE_LEVEL_TRACE;
13487 		break;
13488 	}
13489 
13490 	bitmask = (1 << (host_trace_level + 1)) - 1;
13491 
13492 	return bitmask;
13493 }
13494 
13495 /**
13496  * hdd_set_trace_level_for_each - Set trace level for each INI config
13497  * @hdd_ctx: HDD context
13498  *
13499  * Set trace level for each module based on INI config.
13500  *
13501  * Return: None
13502  */
13503 static void hdd_set_trace_level_for_each(struct hdd_context *hdd_ctx)
13504 {
13505 	uint8_t host_module_log[QDF_MODULE_ID_MAX * 2];
13506 	qdf_size_t host_module_log_num = 0;
13507 	QDF_MODULE_ID module_id;
13508 	uint32_t bitmask;
13509 	uint32_t i;
13510 
13511 	qdf_uint8_array_parse(cfg_get(hdd_ctx->psoc,
13512 				      CFG_ENABLE_HOST_MODULE_LOG_LEVEL),
13513 			      host_module_log,
13514 			      QDF_MODULE_ID_MAX * 2,
13515 			      &host_module_log_num);
13516 
13517 	for (i = 0; i + 1 < host_module_log_num; i += 2) {
13518 		module_id = host_module_log[i];
13519 		bitmask = hdd_log_level_to_bitmask(host_module_log[i + 1]);
13520 		if (module_id < QDF_MODULE_ID_MAX &&
13521 		    module_id >= QDF_MODULE_ID_MIN)
13522 			hdd_qdf_trace_enable(module_id, bitmask);
13523 	}
13524 
13525 	hdd_set_mtrace_for_each(hdd_ctx);
13526 }
13527 
13528 /**
13529  * hdd_context_init() - Initialize HDD context
13530  * @hdd_ctx:	HDD context.
13531  *
13532  * Initialize HDD context along with all the feature specific contexts.
13533  *
13534  * return: 0 on success and errno on failure.
13535  */
13536 static int hdd_context_init(struct hdd_context *hdd_ctx)
13537 {
13538 	int ret;
13539 
13540 	hdd_ctx->ioctl_scan_mode = eSIR_ACTIVE_SCAN;
13541 	hdd_ctx->max_intf_count = WLAN_MAX_VDEVS;
13542 
13543 	init_completion(&hdd_ctx->mc_sus_event_var);
13544 	init_completion(&hdd_ctx->ready_to_suspend);
13545 
13546 	qdf_spinlock_create(&hdd_ctx->connection_status_lock);
13547 	qdf_spinlock_create(&hdd_ctx->hdd_adapter_lock);
13548 
13549 	qdf_list_create(&hdd_ctx->hdd_adapters, 0);
13550 
13551 	ret = hdd_scan_context_init(hdd_ctx);
13552 	if (ret)
13553 		goto list_destroy;
13554 
13555 	ret = hdd_sap_context_init(hdd_ctx);
13556 	if (ret)
13557 		goto scan_destroy;
13558 
13559 	ret = ucfg_dp_bbm_context_init(hdd_ctx->psoc);
13560 	if (ret)
13561 		goto sap_destroy;
13562 
13563 	wlan_hdd_cfg80211_extscan_init(hdd_ctx);
13564 
13565 	hdd_init_offloaded_packets_ctx(hdd_ctx);
13566 
13567 	ret = wlan_hdd_cfg80211_init(hdd_ctx->parent_dev, hdd_ctx->wiphy,
13568 				     hdd_ctx->config);
13569 	if (ret)
13570 		goto bbm_destroy;
13571 
13572 	qdf_wake_lock_create(&hdd_ctx->monitor_mode_wakelock,
13573 			     "monitor_mode_wakelock");
13574 
13575 	return 0;
13576 
13577 bbm_destroy:
13578 	ucfg_dp_bbm_context_deinit(hdd_ctx->psoc);
13579 
13580 sap_destroy:
13581 	hdd_sap_context_destroy(hdd_ctx);
13582 
13583 scan_destroy:
13584 	hdd_scan_context_destroy(hdd_ctx);
13585 list_destroy:
13586 	qdf_list_destroy(&hdd_ctx->hdd_adapters);
13587 
13588 	return ret;
13589 }
13590 
13591 void hdd_psoc_idle_timer_start(struct hdd_context *hdd_ctx)
13592 {
13593 	uint32_t timeout_ms = hdd_ctx->config->iface_change_wait_time;
13594 	uint32_t suspend_timeout_ms;
13595 	enum wake_lock_reason reason =
13596 		WIFI_POWER_EVENT_WAKELOCK_IFACE_CHANGE_TIMER;
13597 
13598 	if (!timeout_ms) {
13599 		hdd_info("psoc idle timer is disabled");
13600 		return;
13601 	}
13602 
13603 	hdd_debug("Starting psoc idle timer");
13604 
13605 	/* If PCIe gen speed change is requested, reduce idle shutdown
13606 	 * timeout to 100 ms
13607 	 */
13608 	if (hdd_ctx->current_pcie_gen_speed) {
13609 		timeout_ms = HDD_PCIE_GEN_SPEED_CHANGE_TIMEOUT_MS;
13610 		hdd_info("pcie gen speed change requested");
13611 	}
13612 
13613 	qdf_delayed_work_start(&hdd_ctx->psoc_idle_timeout_work, timeout_ms);
13614 	suspend_timeout_ms = timeout_ms + HDD_PSOC_IDLE_SHUTDOWN_SUSPEND_DELAY;
13615 	hdd_prevent_suspend_timeout(suspend_timeout_ms, reason);
13616 }
13617 
13618 void hdd_psoc_idle_timer_stop(struct hdd_context *hdd_ctx)
13619 {
13620 	qdf_delayed_work_stop_sync(&hdd_ctx->psoc_idle_timeout_work);
13621 	hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_IFACE_CHANGE_TIMER);
13622 	hdd_debug("Stopped psoc idle timer");
13623 }
13624 
13625 
13626 /**
13627  * __hdd_psoc_idle_shutdown() - perform an idle shutdown on the given psoc
13628  * @hdd_ctx: the hdd context which should be shutdown
13629  *
13630  * When no interfaces are "up" on a psoc, an idle shutdown timer is started.
13631  * If no interfaces are brought up before the timer expires, we do an
13632  * "idle shutdown," cutting power to the physical SoC to save power. This is
13633  * done completely transparently from the perspective of userspace.
13634  *
13635  * Return: None
13636  */
13637 static int __hdd_psoc_idle_shutdown(struct hdd_context *hdd_ctx)
13638 {
13639 	struct osif_psoc_sync *psoc_sync;
13640 	int errno;
13641 
13642 	hdd_enter();
13643 
13644 	hdd_reg_wait_for_country_change(hdd_ctx);
13645 
13646 	errno = osif_psoc_sync_trans_start(hdd_ctx->parent_dev, &psoc_sync);
13647 	if (errno) {
13648 		hdd_info("psoc busy, abort idle shutdown; errno:%d", errno);
13649 		errno = -EAGAIN;
13650 		goto exit;
13651 	}
13652 
13653 	osif_psoc_sync_wait_for_ops(psoc_sync);
13654 	/*
13655 	 * This is to handle scenario in which platform driver triggers
13656 	 * idle_shutdown if Deep Sleep/Hibernate entry notification is
13657 	 * received from modem subsystem in wearable devices
13658 	 */
13659 	if (hdd_is_any_interface_open(hdd_ctx)) {
13660 		hdd_err_rl("all interfaces are not down, ignore idle shutdown");
13661 		errno = -EAGAIN;
13662 	} else {
13663 		errno = hdd_wlan_stop_modules(hdd_ctx, false);
13664 	}
13665 
13666 	osif_psoc_sync_trans_stop(psoc_sync);
13667 
13668 exit:
13669 	hdd_exit();
13670 	return errno;
13671 }
13672 
13673 static int __hdd_mode_change_psoc_idle_shutdown(struct hdd_context *hdd_ctx)
13674 {
13675 	is_mode_change_psoc_idle_shutdown = false;
13676 	return hdd_wlan_stop_modules(hdd_ctx, true);
13677 }
13678 
13679 int hdd_psoc_idle_shutdown(struct device *dev)
13680 {
13681 	int ret;
13682 	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
13683 
13684 	if (!hdd_ctx)
13685 		return -EINVAL;
13686 
13687 	if (is_mode_change_psoc_idle_shutdown)
13688 		ret = __hdd_mode_change_psoc_idle_shutdown(hdd_ctx);
13689 	else {
13690 		ret =  __hdd_psoc_idle_shutdown(hdd_ctx);
13691 	}
13692 
13693 	return ret;
13694 }
13695 
13696 static int __hdd_psoc_idle_restart(struct hdd_context *hdd_ctx)
13697 {
13698 	int ret;
13699 
13700 	ret = hdd_soc_idle_restart_lock(hdd_ctx->parent_dev);
13701 	if (ret)
13702 		return ret;
13703 
13704 	ret = hdd_wlan_start_modules(hdd_ctx, false);
13705 
13706 	hdd_soc_idle_restart_unlock();
13707 
13708 	return ret;
13709 }
13710 
13711 int hdd_psoc_idle_restart(struct device *dev)
13712 {
13713 	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
13714 
13715 	if (!hdd_ctx)
13716 		return -EINVAL;
13717 
13718 	return __hdd_psoc_idle_restart(hdd_ctx);
13719 }
13720 
13721 int hdd_trigger_psoc_idle_restart(struct hdd_context *hdd_ctx)
13722 {
13723 	int ret;
13724 
13725 	QDF_BUG(rtnl_is_locked());
13726 
13727 	hdd_psoc_idle_timer_stop(hdd_ctx);
13728 	if (hdd_ctx->driver_status == DRIVER_MODULES_ENABLED) {
13729 		hdd_nofl_debug("Driver modules already Enabled");
13730 		return 0;
13731 	}
13732 
13733 	ret = hdd_soc_idle_restart_lock(hdd_ctx->parent_dev);
13734 	if (ret)
13735 		return ret;
13736 
13737 	if (hdd_ctx->current_pcie_gen_speed) {
13738 		hdd_info("request pcie gen speed change to %d",
13739 			 hdd_ctx->current_pcie_gen_speed);
13740 
13741 		/* call pld api for pcie gen speed change */
13742 		ret  = pld_set_pcie_gen_speed(hdd_ctx->parent_dev,
13743 					      hdd_ctx->current_pcie_gen_speed);
13744 		if (ret)
13745 			hdd_err_rl("failed to set pcie gen speed");
13746 
13747 		hdd_ctx->current_pcie_gen_speed = 0;
13748 	}
13749 
13750 	qdf_event_reset(&hdd_ctx->regulatory_update_event);
13751 	qdf_mutex_acquire(&hdd_ctx->regulatory_status_lock);
13752 	hdd_ctx->is_regulatory_update_in_progress = true;
13753 	qdf_mutex_release(&hdd_ctx->regulatory_status_lock);
13754 
13755 	ret = pld_idle_restart(hdd_ctx->parent_dev, hdd_psoc_idle_restart);
13756 	hdd_soc_idle_restart_unlock();
13757 
13758 	return ret;
13759 }
13760 
13761 /**
13762  * hdd_psoc_idle_timeout_callback() - Handler for psoc idle timeout
13763  * @priv: pointer to hdd context
13764  *
13765  * Return: None
13766  */
13767 static void hdd_psoc_idle_timeout_callback(void *priv)
13768 {
13769 	int ret;
13770 	struct hdd_context *hdd_ctx = priv;
13771 	void *hif_ctx;
13772 
13773 	if (wlan_hdd_validate_context(hdd_ctx))
13774 		return;
13775 
13776 	hif_ctx = cds_get_context(QDF_MODULE_ID_HIF);
13777 	if (hif_ctx) {
13778 		/*
13779 		 * Trigger runtime sync resume before psoc_idle_shutdown
13780 		 * such that resume can happen successfully
13781 		 */
13782 		qdf_rtpm_sync_resume();
13783 	}
13784 
13785 	hdd_info("Psoc idle timeout elapsed; starting psoc shutdown");
13786 
13787 	ret = pld_idle_shutdown(hdd_ctx->parent_dev, hdd_psoc_idle_shutdown);
13788 	if (-EAGAIN == ret || hdd_ctx->is_wiphy_suspended) {
13789 		hdd_debug("System suspend in progress. Restart idle shutdown timer");
13790 		hdd_psoc_idle_timer_start(hdd_ctx);
13791 	}
13792 
13793 	/* Clear the recovery flag for PCIe discrete soc after idle shutdown*/
13794 	if (PLD_BUS_TYPE_PCIE == pld_get_bus_type(hdd_ctx->parent_dev) &&
13795 	    -EBUSY != ret)
13796 		cds_set_recovery_in_progress(false);
13797 }
13798 
13799 #ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
13800 static void hdd_set_wlan_logging(struct hdd_context *hdd_ctx)
13801 {
13802 	wlan_set_console_log_levels(hdd_ctx->config->wlan_console_log_levels);
13803 	wlan_logging_set_active(hdd_ctx->config->wlan_logging_enable);
13804 }
13805 #else
13806 static void hdd_set_wlan_logging(struct hdd_context *hdd_ctx)
13807 { }
13808 #endif
13809 
13810 #ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
13811 static void hdd_init_wlan_logging_params(struct hdd_config *config,
13812 					 struct wlan_objmgr_psoc *psoc)
13813 {
13814 	config->wlan_logging_enable = cfg_get(psoc, CFG_WLAN_LOGGING_SUPPORT);
13815 
13816 	config->wlan_console_log_levels =
13817 			cfg_get(psoc, CFG_WLAN_LOGGING_CONSOLE_SUPPORT);
13818 	config->host_log_custom_nl_proto =
13819 		cfg_get(psoc, CFG_HOST_LOG_CUSTOM_NETLINK_PROTO);
13820 }
13821 #else
13822 static void hdd_init_wlan_logging_params(struct hdd_config *config,
13823 					 struct wlan_objmgr_psoc *psoc)
13824 {
13825 }
13826 #endif
13827 
13828 #ifdef FEATURE_WLAN_AUTO_SHUTDOWN
13829 static void hdd_init_wlan_auto_shutdown(struct hdd_config *config,
13830 					struct wlan_objmgr_psoc *psoc)
13831 {
13832 	config->wlan_auto_shutdown = cfg_get(psoc, CFG_WLAN_AUTO_SHUTDOWN);
13833 }
13834 #else
13835 static void hdd_init_wlan_auto_shutdown(struct hdd_config *config,
13836 					struct wlan_objmgr_psoc *psoc)
13837 {
13838 }
13839 #endif
13840 
13841 #ifndef REMOVE_PKT_LOG
13842 static void hdd_init_packet_log(struct hdd_config *config,
13843 				struct wlan_objmgr_psoc *psoc)
13844 {
13845 	config->enable_packet_log = cfg_get(psoc, CFG_ENABLE_PACKET_LOG);
13846 }
13847 #else
13848 static void hdd_init_packet_log(struct hdd_config *config,
13849 				struct wlan_objmgr_psoc *psoc)
13850 {
13851 }
13852 #endif
13853 
13854 #ifdef ENABLE_MTRACE_LOG
13855 static void hdd_init_mtrace_log(struct hdd_config *config,
13856 				struct wlan_objmgr_psoc *psoc)
13857 {
13858 	config->enable_mtrace = cfg_get(psoc, CFG_ENABLE_MTRACE);
13859 }
13860 #else
13861 static void hdd_init_mtrace_log(struct hdd_config *config,
13862 				struct wlan_objmgr_psoc *psoc)
13863 {
13864 }
13865 #endif
13866 
13867 #ifdef FEATURE_RUNTIME_PM
13868 static void hdd_init_runtime_pm(struct hdd_config *config,
13869 				struct wlan_objmgr_psoc *psoc)
13870 {
13871 	config->runtime_pm = cfg_get(psoc, CFG_ENABLE_RUNTIME_PM);
13872 }
13873 
13874 bool hdd_is_runtime_pm_enabled(struct hdd_context *hdd_ctx)
13875 {
13876 	return hdd_ctx->config->runtime_pm != hdd_runtime_pm_disabled;
13877 }
13878 #else
13879 static void hdd_init_runtime_pm(struct hdd_config *config,
13880 				struct wlan_objmgr_psoc *psoc)
13881 
13882 {
13883 }
13884 
13885 bool hdd_is_runtime_pm_enabled(struct hdd_context *hdd_ctx)
13886 {
13887 	return false;
13888 }
13889 #endif
13890 
13891 #ifdef WLAN_FEATURE_WMI_SEND_RECV_QMI
13892 static void hdd_init_qmi_stats(struct hdd_config *config,
13893 			       struct wlan_objmgr_psoc *psoc)
13894 {
13895 	config->is_qmi_stats_enabled = cfg_get(psoc, CFG_ENABLE_QMI_STATS);
13896 }
13897 #else
13898 static void hdd_init_qmi_stats(struct hdd_config *config,
13899 			       struct wlan_objmgr_psoc *psoc)
13900 
13901 {
13902 }
13903 #endif
13904 
13905 #ifdef FEATURE_WLAN_DYNAMIC_CVM
13906 static void hdd_init_vc_mode_cfg_bitmap(struct hdd_config *config,
13907 					struct wlan_objmgr_psoc *psoc)
13908 {
13909 	config->vc_mode_cfg_bitmap = cfg_get(psoc, CFG_VC_MODE_BITMAP);
13910 }
13911 #else
13912 static void hdd_init_vc_mode_cfg_bitmap(struct hdd_config *config,
13913 					struct wlan_objmgr_psoc *psoc)
13914 {
13915 }
13916 #endif
13917 
13918 #ifdef DHCP_SERVER_OFFLOAD
13919 static void
13920 hdd_init_dhcp_server_ip(struct hdd_context *hdd_ctx)
13921 {
13922 	uint8_t num_entries;
13923 
13924 	hdd_ctx->config->dhcp_server_ip.is_dhcp_server_ip_valid = true;
13925 	hdd_string_to_u8_array(cfg_get(hdd_ctx->psoc, CFG_DHCP_SERVER_IP_NAME),
13926 			       hdd_ctx->config->dhcp_server_ip.dhcp_server_ip,
13927 			       &num_entries, IPADDR_NUM_ENTRIES);
13928 
13929 	if (num_entries != IPADDR_NUM_ENTRIES) {
13930 		hdd_err("Incorrect IP address (%s) assigned for DHCP server!",
13931 			cfg_get(hdd_ctx->psoc, CFG_DHCP_SERVER_IP_NAME));
13932 		hdd_config->dhcp_server_ip.is_dhcp_server_ip_valid = false;
13933 	}
13934 }
13935 #else
13936 static void
13937 hdd_init_dhcp_server_ip(struct hdd_context *hdd_ctx)
13938 {
13939 }
13940 #endif
13941 
13942 #ifdef SAR_SAFETY_FEATURE
13943 static void hdd_sar_cfg_update(struct hdd_config *config,
13944 			       struct wlan_objmgr_psoc *psoc)
13945 {
13946 	config->sar_safety_timeout = cfg_get(psoc, CFG_SAR_SAFETY_TIMEOUT);
13947 	config->sar_safety_unsolicited_timeout =
13948 			cfg_get(psoc, CFG_SAR_SAFETY_UNSOLICITED_TIMEOUT);
13949 	config->sar_safety_req_resp_timeout =
13950 				cfg_get(psoc, CFG_SAR_SAFETY_REQ_RESP_TIMEOUT);
13951 	config->sar_safety_req_resp_retry =
13952 				cfg_get(psoc, CFG_SAR_SAFETY_REQ_RESP_RETRIES);
13953 	config->sar_safety_index = cfg_get(psoc, CFG_SAR_SAFETY_INDEX);
13954 	config->sar_safety_sleep_index =
13955 				cfg_get(psoc, CFG_SAR_SAFETY_SLEEP_INDEX);
13956 	config->enable_sar_safety =
13957 				cfg_get(psoc, CFG_ENABLE_SAR_SAFETY_FEATURE);
13958 	config->config_sar_safety_sleep_index =
13959 			cfg_get(psoc, CFG_CONFIG_SAR_SAFETY_SLEEP_MODE_INDEX);
13960 }
13961 #else
13962 static void hdd_sar_cfg_update(struct hdd_config *config,
13963 			       struct wlan_objmgr_psoc *psoc)
13964 {
13965 }
13966 #endif
13967 
13968 #ifdef FEATURE_SET
13969 /**
13970  * hdd_get_wifi_features_cfg_update() - Initialize get wifi features cfg
13971  * @config: Pointer to HDD config
13972  * @psoc: psoc pointer
13973  *
13974  * Return: None
13975  */
13976 static void hdd_get_wifi_features_cfg_update(struct hdd_config *config,
13977 					     struct wlan_objmgr_psoc *psoc)
13978 {
13979 	config->get_wifi_features = cfg_get(psoc, CFG_GET_WIFI_FEATURES);
13980 }
13981 #else
13982 static void hdd_get_wifi_features_cfg_update(struct hdd_config *config,
13983 					     struct wlan_objmgr_psoc *psoc)
13984 {
13985 }
13986 #endif
13987 
13988 #ifdef FEATURE_RUNTIME_PM
13989 /**
13990  * hdd_init_cpu_cxpc_threshold_cfg() - Initialize cpu cxpc threshold cfg
13991  * @config: Pointer to HDD config
13992  * @psoc: psoc pointer
13993  *
13994  * Return: None
13995  */
13996 static void hdd_init_cpu_cxpc_threshold_cfg(struct hdd_config *config,
13997 					    struct wlan_objmgr_psoc *psoc)
13998 {
13999 	config->cpu_cxpc_threshold = cfg_get(psoc, CFG_CPU_CXPC_THRESHOLD);
14000 }
14001 #else
14002 static void hdd_init_cpu_cxpc_threshold_cfg(struct hdd_config *config,
14003 					    struct wlan_objmgr_psoc *psoc)
14004 {
14005 }
14006 #endif
14007 
14008 /**
14009  * hdd_cfg_params_init() - Initialize hdd params in hdd_config structure
14010  * @hdd_ctx: Pointer to HDD context
14011  *
14012  * Return: None
14013  */
14014 static void hdd_cfg_params_init(struct hdd_context *hdd_ctx)
14015 {
14016 	struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc;
14017 	struct hdd_config *config = hdd_ctx->config;
14018 	if (!psoc) {
14019 		hdd_err("Invalid psoc");
14020 		return;
14021 	}
14022 
14023 	if (!config) {
14024 		hdd_err("Invalid hdd config");
14025 		return;
14026 	}
14027 
14028 	config->dot11Mode = cfg_get(psoc, CFG_HDD_DOT11_MODE);
14029 	config->bug_on_reinit_failure = cfg_get(psoc,
14030 						CFG_BUG_ON_REINIT_FAILURE);
14031 
14032 	config->is_ramdump_enabled = cfg_get(psoc,
14033 					     CFG_ENABLE_RAMDUMP_COLLECTION);
14034 
14035 	config->iface_change_wait_time = cfg_get(psoc,
14036 						 CFG_INTERFACE_CHANGE_WAIT);
14037 
14038 	config->multicast_host_fw_msgs = cfg_get(psoc,
14039 						 CFG_MULTICAST_HOST_FW_MSGS);
14040 
14041 	config->private_wext_control = cfg_get(psoc, CFG_PRIVATE_WEXT_CONTROL);
14042 	config->enablefwprint = cfg_get(psoc, CFG_ENABLE_FW_UART_PRINT);
14043 	config->enable_fw_log = cfg_get(psoc, CFG_ENABLE_FW_LOG);
14044 	config->operating_chan_freq = cfg_get(psoc, CFG_OPERATING_FREQUENCY);
14045 	config->num_vdevs = cfg_get(psoc, CFG_NUM_VDEV_ENABLE);
14046 	qdf_str_lcopy(config->enable_concurrent_sta,
14047 		      cfg_get(psoc, CFG_ENABLE_CONCURRENT_STA),
14048 		      CFG_CONCURRENT_IFACE_MAX_LEN);
14049 	qdf_str_lcopy(config->dbs_scan_selection,
14050 		      cfg_get(psoc, CFG_DBS_SCAN_SELECTION),
14051 		      CFG_DBS_SCAN_PARAM_LENGTH);
14052 	config->inform_bss_rssi_raw = cfg_get(psoc, CFG_INFORM_BSS_RSSI_RAW);
14053 	config->mac_provision = cfg_get(psoc, CFG_ENABLE_MAC_PROVISION);
14054 	config->provisioned_intf_pool =
14055 				cfg_get(psoc, CFG_PROVISION_INTERFACE_POOL);
14056 	config->derived_intf_pool = cfg_get(psoc, CFG_DERIVED_INTERFACE_POOL);
14057 	config->advertise_concurrent_operation =
14058 				cfg_get(psoc,
14059 					CFG_ADVERTISE_CONCURRENT_OPERATION);
14060 	config->is_unit_test_framework_enabled =
14061 			cfg_get(psoc, CFG_ENABLE_UNIT_TEST_FRAMEWORK);
14062 	config->disable_channel = cfg_get(psoc, CFG_ENABLE_DISABLE_CHANNEL);
14063 	config->enable_sar_conversion = cfg_get(psoc, CFG_SAR_CONVERSION);
14064 	config->nb_commands_interval =
14065 				cfg_get(psoc, CFG_NB_COMMANDS_RATE_LIMIT);
14066 
14067 	hdd_init_vc_mode_cfg_bitmap(config, psoc);
14068 	hdd_init_runtime_pm(config, psoc);
14069 	hdd_init_wlan_auto_shutdown(config, psoc);
14070 	hdd_init_wlan_logging_params(config, psoc);
14071 	hdd_init_packet_log(config, psoc);
14072 	hdd_init_mtrace_log(config, psoc);
14073 	hdd_init_dhcp_server_ip(hdd_ctx);
14074 	hdd_dp_cfg_update(psoc, hdd_ctx);
14075 	hdd_sar_cfg_update(config, psoc);
14076 	hdd_init_qmi_stats(config, psoc);
14077 	hdd_club_ll_stats_in_get_sta_cfg_update(config, psoc);
14078 	config->read_mac_addr_from_mac_file =
14079 			cfg_get(psoc, CFG_READ_MAC_ADDR_FROM_MAC_FILE);
14080 
14081 	hdd_get_wifi_features_cfg_update(config, psoc);
14082 	hdd_init_cpu_cxpc_threshold_cfg(config, psoc);
14083 }
14084 
14085 #ifdef CONNECTION_ROAMING_CFG
14086 static QDF_STATUS hdd_cfg_parse_connection_roaming_cfg(void)
14087 {
14088 	QDF_STATUS status = QDF_STATUS_E_INVAL;
14089 	bool is_valid;
14090 
14091 	is_valid = cfg_valid_ini_check(WLAN_CONNECTION_ROAMING_INI_FILE);
14092 
14093 	if (is_valid)
14094 		status = cfg_parse(WLAN_CONNECTION_ROAMING_INI_FILE);
14095 	if (QDF_IS_STATUS_ERROR(status)) {
14096 		is_valid = cfg_valid_ini_check(WLAN_CONNECTION_ROAMING_BACKUP_INI_FILE);
14097 		if (is_valid)
14098 			status = cfg_parse(WLAN_CONNECTION_ROAMING_BACKUP_INI_FILE);
14099 	}
14100 	return status;
14101 }
14102 #else
14103 static inline QDF_STATUS hdd_cfg_parse_connection_roaming_cfg(void)
14104 {
14105 	return QDF_STATUS_E_NOSUPPORT;
14106 }
14107 #endif
14108 
14109 struct hdd_context *hdd_context_create(struct device *dev)
14110 {
14111 	QDF_STATUS status;
14112 	int ret = 0;
14113 	struct hdd_context *hdd_ctx;
14114 
14115 	hdd_enter();
14116 
14117 	hdd_ctx = hdd_cfg80211_wiphy_alloc();
14118 	if (!hdd_ctx) {
14119 		ret = -ENOMEM;
14120 		goto err_out;
14121 	}
14122 
14123 	status = qdf_delayed_work_create(&hdd_ctx->psoc_idle_timeout_work,
14124 					 hdd_psoc_idle_timeout_callback,
14125 					 hdd_ctx);
14126 	if (QDF_IS_STATUS_ERROR(status)) {
14127 		ret = qdf_status_to_os_return(status);
14128 		goto wiphy_dealloc;
14129 	}
14130 
14131 	hdd_pm_notifier_init(hdd_ctx);
14132 
14133 	hdd_ctx->parent_dev = dev;
14134 	hdd_ctx->last_scan_reject_vdev_id = WLAN_UMAC_VDEV_ID_MAX;
14135 
14136 	hdd_ctx->config = qdf_mem_malloc(sizeof(struct hdd_config));
14137 	if (!hdd_ctx->config) {
14138 		ret = -ENOMEM;
14139 		goto err_free_hdd_context;
14140 	}
14141 
14142 	status = cfg_parse(WLAN_INI_FILE);
14143 	if (QDF_IS_STATUS_ERROR(status)) {
14144 		hdd_err("Failed to parse cfg %s; status:%d\n",
14145 			WLAN_INI_FILE, status);
14146 		/* Assert if failed to parse at least one INI parameter */
14147 		QDF_BUG(status != QDF_STATUS_E_INVAL);
14148 		ret = qdf_status_to_os_return(status);
14149 		goto err_free_config;
14150 	}
14151 
14152 	status = hdd_cfg_parse_connection_roaming_cfg();
14153 
14154 	ret = hdd_objmgr_create_and_store_psoc(hdd_ctx, DEFAULT_PSOC_ID);
14155 	if (ret) {
14156 		QDF_DEBUG_PANIC("Psoc creation fails!");
14157 		goto err_release_store;
14158 	}
14159 
14160 	if (QDF_IS_STATUS_SUCCESS(status))
14161 		ucfg_mlme_set_connection_roaming_ini_present(hdd_ctx->psoc,
14162 							     true);
14163 
14164 	hdd_cfg_params_init(hdd_ctx);
14165 
14166 	/* apply multiplier config, if not already set via module parameter */
14167 	if (qdf_timer_get_multiplier() == 1)
14168 		qdf_timer_set_multiplier(cfg_get(hdd_ctx->psoc,
14169 						 CFG_TIMER_MULTIPLIER));
14170 	hdd_debug("set timer multiplier: %u", qdf_timer_get_multiplier());
14171 
14172 	cds_set_fatal_event(cfg_get(hdd_ctx->psoc,
14173 				    CFG_ENABLE_FATAL_EVENT_TRIGGER));
14174 
14175 	hdd_override_ini_config(hdd_ctx);
14176 
14177 	ret = hdd_context_init(hdd_ctx);
14178 
14179 	if (ret)
14180 		goto err_hdd_objmgr_destroy;
14181 
14182 	if (hdd_get_conparam() == QDF_GLOBAL_EPPING_MODE)
14183 		goto skip_multicast_logging;
14184 
14185 	cds_set_multicast_logging(hdd_ctx->config->multicast_host_fw_msgs);
14186 	ret = hdd_init_netlink_services(hdd_ctx);
14187 	if (ret)
14188 		goto err_deinit_hdd_context;
14189 
14190 	hdd_set_wlan_logging(hdd_ctx);
14191 	qdf_atomic_init(&hdd_ctx->adapter_ops_history.index);
14192 
14193 skip_multicast_logging:
14194 	hdd_set_trace_level_for_each(hdd_ctx);
14195 
14196 	cds_set_context(QDF_MODULE_ID_HDD, hdd_ctx);
14197 
14198 	wlan_hdd_sar_timers_init(hdd_ctx);
14199 
14200 	hdd_exit();
14201 
14202 	return hdd_ctx;
14203 
14204 err_deinit_hdd_context:
14205 	hdd_context_deinit(hdd_ctx);
14206 
14207 err_hdd_objmgr_destroy:
14208 	hdd_objmgr_release_and_destroy_psoc(hdd_ctx);
14209 
14210 err_release_store:
14211 	cfg_release();
14212 
14213 err_free_config:
14214 	qdf_mem_free(hdd_ctx->config);
14215 
14216 err_free_hdd_context:
14217 	qdf_delayed_work_destroy(&hdd_ctx->psoc_idle_timeout_work);
14218 
14219 wiphy_dealloc:
14220 	wiphy_free(hdd_ctx->wiphy);
14221 
14222 err_out:
14223 	return ERR_PTR(ret);
14224 }
14225 
14226 #ifdef MULTI_CLIENT_LL_SUPPORT
14227 /**
14228  * wlan_hdd_init_multi_client_info_table()- Initialize the multi client info
14229  * table
14230  * @adapter: hdd adapter
14231  *
14232  * Return: none
14233  */
14234 static void
14235 wlan_hdd_init_multi_client_info_table(struct hdd_adapter *adapter)
14236 {
14237 	uint8_t i;
14238 
14239 	for (i = 0; i < WLM_MAX_HOST_CLIENT; i++) {
14240 		adapter->client_info[i].client_id = i;
14241 		adapter->client_info[i].port_id = 0;
14242 		adapter->client_info[i].in_use = false;
14243 	}
14244 }
14245 
14246 void wlan_hdd_deinit_multi_client_info_table(struct hdd_adapter *adapter)
14247 {
14248 	uint8_t i;
14249 
14250 	hdd_debug("deinitializing the client info table");
14251 	/* de-initialize the table for host driver client */
14252 	for (i = 0; i < WLM_MAX_HOST_CLIENT; i++) {
14253 		if (adapter->client_info[i].in_use) {
14254 			adapter->client_info[i].port_id = 0;
14255 			adapter->client_info[i].client_id = i;
14256 			adapter->client_info[i].in_use = false;
14257 		}
14258 	}
14259 }
14260 
14261 /**
14262  * wlan_hdd_get_host_driver_port_id()- get host driver port id
14263  * @port_id: argument to be filled
14264  *
14265  * Return: none
14266  */
14267 static void wlan_hdd_get_host_driver_port_id(uint32_t *port_id)
14268 {
14269 	*port_id = WLAM_WLM_HOST_DRIVER_PORT_ID;
14270 }
14271 
14272 #else
14273 static inline void
14274 wlan_hdd_init_multi_client_info_table(struct hdd_adapter *adapter)
14275 {
14276 }
14277 
14278 static inline void wlan_hdd_get_host_driver_port_id(uint32_t *port_id)
14279 {
14280 }
14281 #endif
14282 
14283 static void
14284 hdd_adapter_set_wlm_client_latency_level(struct hdd_adapter *adapter)
14285 {
14286 	QDF_STATUS status;
14287 	bool reset;
14288 	uint32_t port_id;
14289 	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
14290 
14291 	if (!hdd_ctx)
14292 		return;
14293 
14294 	status = ucfg_mlme_cfg_get_wlm_reset(hdd_ctx->psoc, &reset);
14295 	if (QDF_IS_STATUS_ERROR(status)) {
14296 		hdd_err("could not get the wlm reset flag");
14297 		reset = false;
14298 	}
14299 
14300 	if (reset)
14301 		goto out;
14302 
14303 	if (hdd_get_multi_client_ll_support(adapter)) {
14304 		wlan_hdd_get_host_driver_port_id(&port_id);
14305 		status = wlan_hdd_set_wlm_client_latency_level(
14306 						adapter, port_id,
14307 						adapter->latency_level);
14308 		if (QDF_IS_STATUS_ERROR(status))
14309 			hdd_warn("Fail to set latency level:%u", status);
14310 	} else {
14311 		status = sme_set_wlm_latency_level(hdd_ctx->mac_handle,
14312 						   adapter->deflink->vdev_id,
14313 						   adapter->latency_level,
14314 						   0, false);
14315 		if (QDF_IS_STATUS_ERROR(status))
14316 			hdd_warn("set wlm mode failed, %u", status);
14317 	}
14318 out:
14319 	hdd_debug("wlm initial mode %u", adapter->latency_level);
14320 }
14321 
14322 #ifdef WLAN_HDD_MULTI_VDEV_SINGLE_NDEV
14323 struct qdf_mac_addr *
14324 hdd_adapter_get_link_mac_addr(struct wlan_hdd_link_info *link_info)
14325 {
14326 	struct hdd_adapter *adapter;
14327 
14328 	if (!link_info)
14329 		return NULL;
14330 
14331 	adapter = link_info->adapter;
14332 	if (!hdd_adapter_is_ml_adapter(adapter) ||
14333 	    qdf_is_macaddr_zero(&link_info->link_addr) ||
14334 	    !wlan_vdev_mlme_is_mlo_vdev(link_info->vdev))
14335 		return &adapter->mac_addr;
14336 
14337 	return &link_info->link_addr;
14338 }
14339 #else
14340 struct qdf_mac_addr *
14341 hdd_adapter_get_link_mac_addr(struct wlan_hdd_link_info *link_info)
14342 {
14343 	if (!link_info)
14344 		return NULL;
14345 
14346 	return &link_info->adapter->mac_addr;
14347 }
14348 #endif
14349 
14350 #if defined(WLAN_FEATURE_11BE_MLO) && defined(CFG80211_11BE_BASIC) && \
14351 	defined(WLAN_HDD_MULTI_VDEV_SINGLE_NDEV)
14352 QDF_STATUS hdd_adapter_check_duplicate_session(struct hdd_adapter *adapter)
14353 {
14354 	int i = 0;
14355 	QDF_STATUS status;
14356 	uint8_t *addr_list[WLAN_MAX_MLD + 2] = {0};
14357 	struct wlan_hdd_link_info *link_info;
14358 
14359 	if (!hdd_adapter_is_ml_adapter(adapter) ||
14360 	    adapter->device_mode == QDF_SAP_MODE)
14361 		goto netdev_addr;
14362 
14363 	hdd_adapter_for_each_active_link_info(adapter, link_info)
14364 		addr_list[i++] = &link_info->link_addr.bytes[0];
14365 
14366 netdev_addr:
14367 	addr_list[i] = &adapter->mac_addr.bytes[0];
14368 	status = sme_check_for_duplicate_session(adapter->hdd_ctx->mac_handle,
14369 						 &addr_list[0]);
14370 	return status;
14371 }
14372 
14373 QDF_STATUS hdd_adapter_fill_link_address(struct hdd_adapter *adapter)
14374 {
14375 	int i = 0;
14376 	QDF_STATUS status;
14377 	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
14378 	enum QDF_OPMODE opmode = adapter->device_mode;
14379 	struct qdf_mac_addr link_addrs[WLAN_MAX_ML_BSS_LINKS] = {0};
14380 	struct wlan_hdd_link_info *link_info;
14381 
14382 	if (opmode != QDF_STA_MODE && opmode != QDF_SAP_MODE)
14383 		return QDF_STATUS_SUCCESS;
14384 
14385 	if (opmode == QDF_SAP_MODE) {
14386 		link_info = adapter->deflink;
14387 		qdf_copy_macaddr(&link_info->link_addr, &adapter->mac_addr);
14388 		return QDF_STATUS_SUCCESS;
14389 	}
14390 
14391 	if (!hdd_adapter_is_ml_adapter(adapter))
14392 		return QDF_STATUS_SUCCESS;
14393 
14394 	status = hdd_derive_link_address_from_mld(hdd_ctx->psoc,
14395 						  &adapter->mac_addr,
14396 						  &link_addrs[0],
14397 						  WLAN_MAX_ML_BSS_LINKS);
14398 	if (QDF_IS_STATUS_ERROR(status))
14399 		return status;
14400 
14401 	hdd_adapter_for_each_link_info(adapter, link_info)
14402 		qdf_copy_macaddr(&link_info->link_addr, &link_addrs[i++]);
14403 
14404 	return status;
14405 }
14406 #elif defined(WLAN_FEATURE_11BE_MLO) && defined(CFG80211_11BE_BASIC)
14407 QDF_STATUS hdd_adapter_check_duplicate_session(struct hdd_adapter *adapter)
14408 {
14409 	int i;
14410 	QDF_STATUS status;
14411 	uint8_t *addr_list[WLAN_MAX_MLD + 1] = {0};
14412 	struct hdd_adapter *link_adapter;
14413 	struct hdd_mlo_adapter_info *mlo_adapter_info;
14414 	mac_handle_t mac_handle = hdd_adapter_get_mac_handle(adapter);
14415 
14416 	if (hdd_adapter_is_ml_adapter(adapter) &&
14417 	    adapter->device_mode == QDF_STA_MODE) {
14418 		addr_list[0] = &adapter->mld_addr.bytes[0];
14419 		mlo_adapter_info = &adapter->mlo_adapter_info;
14420 		for (i = 0; i < WLAN_MAX_MLD; i++) {
14421 			link_adapter = mlo_adapter_info->link_adapter[i];
14422 			if (!link_adapter)
14423 				continue;
14424 			if (hdd_adapter_is_associated_with_ml_adapter(
14425 							link_adapter)) {
14426 				addr_list[1] = &link_adapter->mac_addr.bytes[0];
14427 			}
14428 		}
14429 	} else {
14430 		addr_list[0] = &adapter->mac_addr.bytes[0];
14431 	}
14432 
14433 	status = sme_check_for_duplicate_session(mac_handle, &addr_list[0]);
14434 	return status;
14435 }
14436 #else
14437 QDF_STATUS hdd_adapter_check_duplicate_session(struct hdd_adapter *adapter)
14438 {
14439 	QDF_STATUS status;
14440 	uint8_t *addr_list[2] = {0};
14441 	mac_handle_t mac_handle = hdd_adapter_get_mac_handle(adapter);
14442 
14443 	addr_list[0] = &adapter->mac_addr.bytes[0];
14444 	status = sme_check_for_duplicate_session(mac_handle, &addr_list[0]);
14445 
14446 	return status;
14447 }
14448 #endif
14449 
14450 static void hdd_restore_info_for_ssr(struct hdd_adapter *adapter)
14451 {
14452 	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
14453 
14454 	if (cds_is_driver_recovering()) {
14455 		/* ssr happens, recover the info */
14456 		hdd_set_vdev_phy_mode(adapter, adapter->user_phy_mode);
14457 		wlan_mlme_restore_user_set_link_num(hdd_ctx->psoc);
14458 	} else {
14459 		/* intf down/up happens, reset default info */
14460 		hdd_set_vdev_phy_mode(adapter, QCA_WLAN_VENDOR_PHY_MODE_AUTO);
14461 		wlan_mlme_clear_user_set_link_num(hdd_ctx->psoc);
14462 	}
14463 }
14464 
14465 void hdd_adapter_reset_station_ctx(struct hdd_adapter *adapter)
14466 {
14467 	struct wlan_hdd_link_info *link_info;
14468 
14469 	hdd_adapter_for_each_link_info(adapter, link_info)
14470 		hdd_cm_clear_ieee_link_id(link_info);
14471 }
14472 
14473 int hdd_start_station_adapter(struct hdd_adapter *adapter)
14474 {
14475 	QDF_STATUS status;
14476 	int ret;
14477 	struct wlan_hdd_link_info *link_info;
14478 
14479 	hdd_enter_dev(adapter->dev);
14480 	if (test_bit(SME_SESSION_OPENED, &adapter->deflink->link_flags)) {
14481 		hdd_err("session is already opened, %d",
14482 			adapter->deflink->vdev_id);
14483 		return qdf_status_to_os_return(QDF_STATUS_SUCCESS);
14484 	}
14485 
14486 	if ((adapter->device_mode == QDF_P2P_DEVICE_MODE) ||
14487 	    (adapter->device_mode == QDF_NAN_DISC_MODE))
14488 		wlan_hdd_lpc_del_monitor_interface(adapter->hdd_ctx);
14489 
14490 	status = hdd_adapter_fill_link_address(adapter);
14491 	if (QDF_IS_STATUS_ERROR(status)) {
14492 		hdd_debug("Link address derive failed");
14493 		return qdf_status_to_os_return(status);
14494 	}
14495 
14496 	status = hdd_adapter_check_duplicate_session(adapter);
14497 	if (QDF_IS_STATUS_ERROR(status)) {
14498 		hdd_err("Duplicate session is existing with same mac address");
14499 		return qdf_status_to_os_return(status);
14500 	}
14501 
14502 	hdd_adapter_for_each_active_link_info(adapter, link_info) {
14503 		ret = hdd_vdev_create(link_info);
14504 		if (ret) {
14505 			hdd_err("failed to create vdev: %d", ret);
14506 			goto fail;
14507 		}
14508 
14509 		status = hdd_init_station_mode(link_info);
14510 		if (QDF_STATUS_SUCCESS != status) {
14511 			hdd_err("Error Initializing station mode: %d", status);
14512 			ret = qdf_status_to_os_return(status);
14513 			goto fail;
14514 		}
14515 	}
14516 
14517 	hdd_adapter_reset_station_ctx(adapter);
14518 
14519 	hdd_register_wext(adapter->dev);
14520 	hdd_set_netdev_flags(adapter);
14521 
14522 	hdd_register_tx_flow_control(adapter,
14523 		hdd_tx_resume_timer_expired_handler,
14524 		hdd_tx_resume_cb,
14525 		hdd_tx_flow_control_is_pause);
14526 
14527 	hdd_register_hl_netdev_fc_timer(adapter,
14528 					hdd_tx_resume_timer_expired_handler);
14529 
14530 	if (hdd_get_multi_client_ll_support(adapter))
14531 		wlan_hdd_init_multi_client_info_table(adapter);
14532 
14533 	hdd_adapter_set_wlm_client_latency_level(adapter);
14534 	hdd_adapter_update_mlo_mgr_mac_addr(adapter);
14535 	hdd_restore_info_for_ssr(adapter);
14536 
14537 	hdd_exit();
14538 	return 0;
14539 
14540 fail:
14541 	hdd_adapter_for_each_active_link_info(adapter, link_info)
14542 		hdd_vdev_destroy(link_info);
14543 
14544 	return ret;
14545 }
14546 
14547 int hdd_start_ap_adapter(struct hdd_adapter *adapter, bool rtnl_held)
14548 {
14549 	QDF_STATUS status;
14550 	bool is_ssr = false;
14551 	int ret;
14552 	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
14553 	struct sap_context *sap_ctx;
14554 	struct wlan_hdd_link_info *link_info = adapter->deflink;
14555 
14556 	hdd_enter();
14557 
14558 	if (test_bit(SME_SESSION_OPENED, &link_info->link_flags)) {
14559 		hdd_err("session is already opened, %d",
14560 			link_info->vdev_id);
14561 		return qdf_status_to_os_return(QDF_STATUS_SUCCESS);
14562 	}
14563 
14564 	wlan_hdd_lpc_del_monitor_interface(hdd_ctx);
14565 
14566 	status = hdd_adapter_fill_link_address(adapter);
14567 	if (QDF_IS_STATUS_ERROR(status)) {
14568 		hdd_debug("Link address derive failed");
14569 		return qdf_status_to_os_return(status);
14570 	}
14571 
14572 	status = hdd_adapter_check_duplicate_session(adapter);
14573 	if (QDF_IS_STATUS_ERROR(status)) {
14574 		hdd_err("Duplicate session is existing with same mac address");
14575 		return qdf_status_to_os_return(status);
14576 	}
14577 
14578 	/*
14579 	 * In SSR case no need to create new sap context.
14580 	 * Otherwise create sap context first and then create
14581 	 * vdev as while creating the vdev, driver needs to
14582 	 * register SAP callback and that callback uses sap context
14583 	 */
14584 	if (WLAN_HDD_GET_SAP_CTX_PTR(link_info)) {
14585 		is_ssr = true;
14586 	} else if (!hdd_sap_create_ctx(adapter)) {
14587 		hdd_err("sap creation failed");
14588 		return qdf_status_to_os_return(QDF_STATUS_E_FAILURE);
14589 	}
14590 
14591 	ret = hdd_vdev_create(link_info);
14592 	if (ret) {
14593 		hdd_err("failed to create vdev, status:%d", ret);
14594 		goto sap_destroy_ctx;
14595 	}
14596 
14597 	sap_ctx = WLAN_HDD_GET_SAP_CTX_PTR(link_info);
14598 	status = sap_acquire_vdev_ref(hdd_ctx->psoc, sap_ctx,
14599 				      link_info->vdev_id);
14600 	if (!QDF_IS_STATUS_SUCCESS(status)) {
14601 		hdd_err("Failed to get vdev ref for sap for session_id: %u",
14602 			link_info->vdev_id);
14603 		ret = qdf_status_to_os_return(status);
14604 		goto sap_vdev_destroy;
14605 	}
14606 
14607 	if (adapter->device_mode == QDF_SAP_MODE) {
14608 		status = hdd_vdev_configure_rtt_params(sap_ctx->vdev);
14609 		if (QDF_IS_STATUS_ERROR(status))
14610 			goto sap_release_ref;
14611 	}
14612 
14613 	status = hdd_init_ap_mode(adapter, is_ssr, rtnl_held);
14614 	if (QDF_STATUS_SUCCESS != status) {
14615 		hdd_err("Error Initializing the AP mode: %d", status);
14616 		ret = qdf_status_to_os_return(status);
14617 		goto sap_release_ref;
14618 	}
14619 
14620 	hdd_register_tx_flow_control(adapter,
14621 		hdd_softap_tx_resume_timer_expired_handler,
14622 		hdd_softap_tx_resume_cb,
14623 		hdd_tx_flow_control_is_pause);
14624 
14625 	hdd_register_hl_netdev_fc_timer(adapter,
14626 					hdd_tx_resume_timer_expired_handler);
14627 
14628 	if (cds_is_driver_recovering())
14629 		hdd_medium_assess_ssr_reinit();
14630 
14631 	hdd_exit();
14632 	return 0;
14633 
14634 sap_release_ref:
14635 	sap_release_vdev_ref(sap_ctx);
14636 sap_vdev_destroy:
14637 	hdd_vdev_destroy(link_info);
14638 sap_destroy_ctx:
14639 	hdd_sap_destroy_ctx(link_info);
14640 	return ret;
14641 }
14642 
14643 #if defined(QCA_LL_TX_FLOW_CONTROL_V2) || defined(QCA_LL_PDEV_TX_FLOW_CONTROL)
14644 /**
14645  * hdd_txrx_populate_cds_config() - Populate txrx cds configuration
14646  * @cds_cfg: CDS Configuration
14647  * @hdd_ctx: Pointer to hdd context
14648  *
14649  * Return: none
14650  */
14651 static inline void hdd_txrx_populate_cds_config(struct cds_config_info
14652 						*cds_cfg,
14653 						struct hdd_context *hdd_ctx)
14654 {
14655 	cds_cfg->tx_flow_stop_queue_th =
14656 		cfg_get(hdd_ctx->psoc, CFG_DP_TX_FLOW_STOP_QUEUE_TH);
14657 	cds_cfg->tx_flow_start_queue_offset =
14658 		cfg_get(hdd_ctx->psoc, CFG_DP_TX_FLOW_START_QUEUE_OFFSET);
14659 	/* configuration for DP RX Threads */
14660 	cds_cfg->enable_dp_rx_threads =
14661 		ucfg_dp_is_rx_threads_enabled(hdd_ctx->psoc);
14662 }
14663 #else
14664 static inline void hdd_txrx_populate_cds_config(struct cds_config_info
14665 						*cds_cfg,
14666 						struct hdd_context *hdd_ctx)
14667 {
14668 }
14669 #endif
14670 
14671 /**
14672  * hdd_update_cds_config() - API to update cds configuration parameters
14673  * @hdd_ctx: HDD Context
14674  *
14675  * Return: 0 for Success, errno on failure
14676  */
14677 static int hdd_update_cds_config(struct hdd_context *hdd_ctx)
14678 {
14679 	struct cds_config_info *cds_cfg;
14680 	int value;
14681 	uint8_t band_capability;
14682 	uint32_t band_bitmap;
14683 	uint8_t ito_repeat_count;
14684 	bool crash_inject;
14685 	bool self_recovery;
14686 	bool fw_timeout_crash;
14687 	QDF_STATUS status;
14688 
14689 	cds_cfg = qdf_mem_malloc(sizeof(*cds_cfg));
14690 	if (!cds_cfg)
14691 		return -ENOMEM;
14692 
14693 	cds_cfg->driver_type = QDF_DRIVER_TYPE_PRODUCTION;
14694 	ucfg_mlme_get_sap_max_modulated_dtim(hdd_ctx->psoc,
14695 					     &cds_cfg->sta_maxlimod_dtim);
14696 
14697 	ucfg_mlme_get_max_modulated_dtim_ms(hdd_ctx->psoc,
14698 					    &cds_cfg->sta_maxlimod_dtim_ms);
14699 
14700 	status = ucfg_mlme_get_crash_inject(hdd_ctx->psoc, &crash_inject);
14701 	if (QDF_IS_STATUS_ERROR(status)) {
14702 		hdd_err("Failed to get crash inject ini config");
14703 		goto exit;
14704 	}
14705 
14706 	status = ucfg_mlme_get_self_recovery(hdd_ctx->psoc, &self_recovery);
14707 	if (QDF_IS_STATUS_ERROR(status)) {
14708 		hdd_err("Failed to get self recovery ini config");
14709 		goto exit;
14710 	}
14711 
14712 	status = ucfg_mlme_get_fw_timeout_crash(hdd_ctx->psoc,
14713 						&fw_timeout_crash);
14714 	if (QDF_IS_STATUS_ERROR(status)) {
14715 		hdd_err("Failed to get fw timeout crash ini config");
14716 		goto exit;
14717 	}
14718 
14719 	status = ucfg_mlme_get_ito_repeat_count(hdd_ctx->psoc,
14720 						&ito_repeat_count);
14721 	if (QDF_IS_STATUS_ERROR(status)) {
14722 		hdd_err("Failed to get ITO repeat count ini config");
14723 		goto exit;
14724 	}
14725 
14726 	cds_cfg->force_target_assert_enabled = crash_inject;
14727 
14728 	ucfg_mlme_get_sap_max_offload_peers(hdd_ctx->psoc, &value);
14729 	cds_cfg->ap_maxoffload_peers = value;
14730 	ucfg_mlme_get_sap_max_offload_reorder_buffs(hdd_ctx->psoc,
14731 						    &value);
14732 	cds_cfg->ap_maxoffload_reorderbuffs = value;
14733 
14734 	cds_cfg->reorder_offload = DP_REORDER_OFFLOAD_SUPPORT;
14735 
14736 	/* IPA micro controller data path offload resource config item */
14737 	cds_cfg->uc_offload_enabled = ucfg_ipa_uc_is_enabled();
14738 
14739 	cds_cfg->enable_rxthread =
14740 		ucfg_dp_is_rx_common_thread_enabled(hdd_ctx->psoc);
14741 	ucfg_mlme_get_sap_max_peers(hdd_ctx->psoc, &value);
14742 	cds_cfg->max_station = value;
14743 	cds_cfg->sub_20_channel_width = WLAN_SUB_20_CH_WIDTH_NONE;
14744 	cds_cfg->max_msdus_per_rxinorderind =
14745 		cfg_get(hdd_ctx->psoc, CFG_DP_MAX_MSDUS_PER_RXIND);
14746 	cds_cfg->self_recovery_enabled = self_recovery;
14747 	cds_cfg->fw_timeout_crash = fw_timeout_crash;
14748 
14749 	cds_cfg->ito_repeat_count = ito_repeat_count;
14750 
14751 	status = ucfg_mlme_get_band_capability(hdd_ctx->psoc, &band_bitmap);
14752 	if (QDF_IS_STATUS_ERROR(status))
14753 		goto exit;
14754 
14755 	band_capability = wlan_reg_band_bitmap_to_band_info(band_bitmap);
14756 	cds_cfg->bandcapability = band_capability;
14757 	cds_cfg->num_vdevs = hdd_ctx->config->num_vdevs;
14758 	cds_cfg->enable_tx_compl_tsf64 =
14759 		hdd_tsf_is_tsf64_tx_set(hdd_ctx);
14760 	hdd_txrx_populate_cds_config(cds_cfg, hdd_ctx);
14761 	hdd_lpass_populate_cds_config(cds_cfg, hdd_ctx);
14762 	cds_init_ini_config(cds_cfg);
14763 	return 0;
14764 
14765 exit:
14766 	qdf_mem_free(cds_cfg);
14767 	return -EINVAL;
14768 }
14769 
14770 /**
14771  * hdd_update_user_config() - API to update user configuration
14772  * parameters to obj mgr which are used by multiple components
14773  * @hdd_ctx: HDD Context
14774  *
14775  * Return: 0 for Success, errno on failure
14776  */
14777 static int hdd_update_user_config(struct hdd_context *hdd_ctx)
14778 {
14779 	struct wlan_objmgr_psoc_user_config *user_config;
14780 	uint8_t band_capability;
14781 	uint32_t band_bitmap;
14782 	QDF_STATUS status;
14783 	bool value = false;
14784 
14785 	status = ucfg_mlme_get_band_capability(hdd_ctx->psoc, &band_bitmap);
14786 	if (QDF_IS_STATUS_ERROR(status))
14787 		return -EIO;
14788 
14789 	user_config = qdf_mem_malloc(sizeof(*user_config));
14790 	if (!user_config)
14791 		return -ENOMEM;
14792 
14793 	user_config->dot11_mode = hdd_ctx->config->dot11Mode;
14794 	status = ucfg_mlme_is_11d_enabled(hdd_ctx->psoc, &value);
14795 	if (!QDF_IS_STATUS_SUCCESS(status))
14796 		hdd_err("Invalid 11d_enable flag");
14797 	user_config->is_11d_support_enabled = value;
14798 
14799 	value = false;
14800 	status = ucfg_mlme_is_11h_enabled(hdd_ctx->psoc, &value);
14801 	if (!QDF_IS_STATUS_SUCCESS(status))
14802 		hdd_err("Invalid 11h_enable flag");
14803 	user_config->is_11h_support_enabled = value;
14804 	band_capability = wlan_reg_band_bitmap_to_band_info(band_bitmap);
14805 	user_config->band_capability = band_capability;
14806 	wlan_objmgr_psoc_set_user_config(hdd_ctx->psoc, user_config);
14807 
14808 	qdf_mem_free(user_config);
14809 	return 0;
14810 }
14811 
14812 /**
14813  * hdd_init_thermal_info - Initialize thermal level
14814  * @hdd_ctx:	HDD context
14815  *
14816  * Initialize thermal level at SME layer and set the thermal level callback
14817  * which would be called when a configured thermal threshold is hit.
14818  *
14819  * Return: 0 on success and errno on failure
14820  */
14821 static int hdd_init_thermal_info(struct hdd_context *hdd_ctx)
14822 {
14823 	QDF_STATUS status;
14824 	mac_handle_t mac_handle = hdd_ctx->mac_handle;
14825 
14826 	status = sme_init_thermal_info(mac_handle);
14827 
14828 	if (!QDF_IS_STATUS_SUCCESS(status))
14829 		return qdf_status_to_os_return(status);
14830 
14831 	sme_add_set_thermal_level_callback(mac_handle,
14832 					   hdd_set_thermal_level_cb);
14833 
14834 	return 0;
14835 
14836 }
14837 
14838 #if defined(CONFIG_HDD_INIT_WITH_RTNL_LOCK)
14839 /**
14840  * hdd_hold_rtnl_lock - Hold RTNL lock
14841  *
14842  * Hold RTNL lock
14843  *
14844  * Return: True if held and false otherwise
14845  */
14846 static inline bool hdd_hold_rtnl_lock(void)
14847 {
14848 	rtnl_lock();
14849 	return true;
14850 }
14851 
14852 /**
14853  * hdd_release_rtnl_lock - Release RTNL lock
14854  *
14855  * Release RTNL lock
14856  *
14857  * Return: None
14858  */
14859 static inline void hdd_release_rtnl_lock(void)
14860 {
14861 	rtnl_unlock();
14862 }
14863 #else
14864 static inline bool hdd_hold_rtnl_lock(void) { return false; }
14865 static inline void hdd_release_rtnl_lock(void) { }
14866 #endif
14867 
14868 #if !defined(REMOVE_PKT_LOG)
14869 
14870 /* MAX iwpriv command support */
14871 #define PKTLOG_SET_BUFF_SIZE	3
14872 #define PKTLOG_CLEAR_BUFF	4
14873 /* Set Maximum pktlog file size to 64MB */
14874 #define MAX_PKTLOG_SIZE		64
14875 
14876 /**
14877  * hdd_pktlog_set_buff_size() - set pktlog buffer size
14878  * @hdd_ctx: hdd context
14879  * @set_value2: pktlog buffer size value
14880  *
14881  *
14882  * Return: 0 for success or error.
14883  */
14884 static int hdd_pktlog_set_buff_size(struct hdd_context *hdd_ctx, int set_value2)
14885 {
14886 	struct sir_wifi_start_log start_log = { 0 };
14887 	QDF_STATUS status;
14888 
14889 	start_log.ring_id = RING_ID_PER_PACKET_STATS;
14890 	start_log.verbose_level = WLAN_LOG_LEVEL_OFF;
14891 	start_log.ini_triggered = cds_is_packet_log_enabled();
14892 	start_log.user_triggered = 1;
14893 	start_log.size = set_value2;
14894 	start_log.is_pktlog_buff_clear = false;
14895 
14896 	status = sme_wifi_start_logger(hdd_ctx->mac_handle, start_log);
14897 	if (!QDF_IS_STATUS_SUCCESS(status)) {
14898 		hdd_err("sme_wifi_start_logger failed(err=%d)", status);
14899 		hdd_exit();
14900 		return -EINVAL;
14901 	}
14902 
14903 	return 0;
14904 }
14905 
14906 /**
14907  * hdd_pktlog_clear_buff() - clear pktlog buffer
14908  * @hdd_ctx: hdd context
14909  *
14910  * Return: 0 for success or error.
14911  */
14912 static int hdd_pktlog_clear_buff(struct hdd_context *hdd_ctx)
14913 {
14914 	struct sir_wifi_start_log start_log;
14915 	QDF_STATUS status;
14916 
14917 	start_log.ring_id = RING_ID_PER_PACKET_STATS;
14918 	start_log.verbose_level = WLAN_LOG_LEVEL_OFF;
14919 	start_log.ini_triggered = cds_is_packet_log_enabled();
14920 	start_log.user_triggered = 1;
14921 	start_log.size = 0;
14922 	start_log.is_pktlog_buff_clear = true;
14923 
14924 	status = sme_wifi_start_logger(hdd_ctx->mac_handle, start_log);
14925 	if (!QDF_IS_STATUS_SUCCESS(status)) {
14926 		hdd_err("sme_wifi_start_logger failed(err=%d)", status);
14927 		hdd_exit();
14928 		return -EINVAL;
14929 	}
14930 
14931 	return 0;
14932 }
14933 
14934 
14935 /**
14936  * hdd_process_pktlog_command() - process pktlog command
14937  * @hdd_ctx: hdd context
14938  * @set_value: value set by user
14939  * @set_value2: pktlog buffer size value
14940  *
14941  * This function process pktlog command.
14942  * set_value2 only matters when set_value is 3 (set buff size)
14943  * otherwise we ignore it.
14944  *
14945  * Return: 0 for success or error.
14946  */
14947 int hdd_process_pktlog_command(struct hdd_context *hdd_ctx, uint32_t set_value,
14948 			       int set_value2)
14949 {
14950 	int ret;
14951 	bool enable;
14952 	uint8_t user_triggered = 0;
14953 
14954 	ret = wlan_hdd_validate_context(hdd_ctx);
14955 	if (0 != ret)
14956 		return ret;
14957 
14958 	hdd_debug("set pktlog %d, set size %d", set_value, set_value2);
14959 
14960 	if (set_value > PKTLOG_CLEAR_BUFF) {
14961 		hdd_err("invalid pktlog value %d", set_value);
14962 		return -EINVAL;
14963 	}
14964 
14965 	if (set_value == PKTLOG_SET_BUFF_SIZE) {
14966 		if (set_value2 <= 0) {
14967 			hdd_err("invalid pktlog size %d", set_value2);
14968 			return -EINVAL;
14969 		} else if (set_value2 > MAX_PKTLOG_SIZE) {
14970 			hdd_err_rl("Pktlog size is large. max value is %uMB.",
14971 				   MAX_PKTLOG_SIZE);
14972 			return -EINVAL;
14973 		}
14974 		return hdd_pktlog_set_buff_size(hdd_ctx, set_value2);
14975 	} else if (set_value == PKTLOG_CLEAR_BUFF) {
14976 		return hdd_pktlog_clear_buff(hdd_ctx);
14977 	}
14978 
14979 	/*
14980 	 * set_value = 0 then disable packetlog
14981 	 * set_value = 1 enable packetlog forcefully
14982 	 * set_value = 2 then disable packetlog if disabled through ini or
14983 	 *                     enable packetlog with AUTO type.
14984 	 */
14985 	enable = ((set_value > 0) && cds_is_packet_log_enabled()) ?
14986 			 true : false;
14987 
14988 	if (1 == set_value) {
14989 		enable = true;
14990 		user_triggered = 1;
14991 	}
14992 
14993 	return hdd_pktlog_enable_disable(hdd_ctx, enable, user_triggered, 0);
14994 }
14995 
14996 /**
14997  * hdd_pktlog_enable_disable() - Enable/Disable packet logging
14998  * @hdd_ctx: HDD context
14999  * @enable_disable_flag: Flag to enable/disable
15000  * @user_triggered: triggered through iwpriv
15001  * @size: buffer size to be used for packetlog
15002  *
15003  * Return: 0 on success; error number otherwise
15004  */
15005 int hdd_pktlog_enable_disable(struct hdd_context *hdd_ctx,
15006 			      bool enable_disable_flag,
15007 			      uint8_t user_triggered, int size)
15008 {
15009 	struct sir_wifi_start_log start_log;
15010 	QDF_STATUS status;
15011 
15012 	if (hdd_ctx->is_pktlog_enabled && enable_disable_flag)
15013 		return 0;
15014 
15015 	if ((!hdd_ctx->is_pktlog_enabled) && (!enable_disable_flag))
15016 		return 0;
15017 
15018 	start_log.ring_id = RING_ID_PER_PACKET_STATS;
15019 	start_log.verbose_level =
15020 		enable_disable_flag ?
15021 			WLAN_LOG_LEVEL_ACTIVE : WLAN_LOG_LEVEL_OFF;
15022 	start_log.ini_triggered = cds_is_packet_log_enabled();
15023 	start_log.user_triggered = user_triggered;
15024 	start_log.size = size;
15025 	start_log.is_pktlog_buff_clear = false;
15026 	/*
15027 	 * Use "is_iwpriv_command" flag to distinguish iwpriv command from other
15028 	 * commands. Host uses this flag to decide whether to send pktlog
15029 	 * disable command to fw without sending pktlog enable command
15030 	 * previously. For eg, If vendor sends pktlog disable command without
15031 	 * sending pktlog enable command, then host discards the packet
15032 	 * but for iwpriv command, host will send it to fw.
15033 	 */
15034 	start_log.is_iwpriv_command = 1;
15035 
15036 	status = sme_wifi_start_logger(hdd_ctx->mac_handle, start_log);
15037 	if (!QDF_IS_STATUS_SUCCESS(status)) {
15038 		hdd_err("sme_wifi_start_logger failed(err=%d)", status);
15039 		hdd_exit();
15040 		return -EINVAL;
15041 	}
15042 
15043 	hdd_ctx->is_pktlog_enabled = enable_disable_flag;
15044 
15045 	return 0;
15046 }
15047 #endif /* REMOVE_PKT_LOG */
15048 
15049 void hdd_free_mac_address_lists(struct hdd_context *hdd_ctx)
15050 {
15051 	hdd_debug("Resetting MAC address lists");
15052 	qdf_mem_zero(hdd_ctx->provisioned_mac_addr,
15053 		    sizeof(hdd_ctx->provisioned_mac_addr));
15054 	qdf_mem_zero(hdd_ctx->derived_mac_addr,
15055 		    sizeof(hdd_ctx->derived_mac_addr));
15056 	hdd_ctx->num_provisioned_addr = 0;
15057 	hdd_ctx->num_derived_addr = 0;
15058 	hdd_ctx->provisioned_intf_addr_mask = 0;
15059 	hdd_ctx->derived_intf_addr_mask = 0;
15060 }
15061 
15062 /**
15063  * hdd_get_platform_wlan_mac_buff() - API to query platform driver
15064  *                                    for MAC address
15065  * @dev: Device Pointer
15066  * @num: Number of Valid Mac address
15067  *
15068  * Return: Pointer to MAC address buffer
15069  */
15070 static uint8_t *hdd_get_platform_wlan_mac_buff(struct device *dev,
15071 					       uint32_t *num)
15072 {
15073 	return pld_get_wlan_mac_address(dev, num);
15074 }
15075 
15076 /**
15077  * hdd_get_platform_wlan_derived_mac_buff() - API to query platform driver
15078  *                                    for derived MAC address
15079  * @dev: Device Pointer
15080  * @num: Number of Valid Mac address
15081  *
15082  * Return: Pointer to MAC address buffer
15083  */
15084 static uint8_t *hdd_get_platform_wlan_derived_mac_buff(struct device *dev,
15085 						       uint32_t *num)
15086 {
15087 	return pld_get_wlan_derived_mac_address(dev, num);
15088 }
15089 
15090 /**
15091  * hdd_populate_random_mac_addr() - API to populate random mac addresses
15092  * @hdd_ctx: HDD Context
15093  * @num: Number of random mac addresses needed
15094  *
15095  * Generate random addresses using bit manipulation on the base mac address
15096  *
15097  * Return: None
15098  */
15099 void hdd_populate_random_mac_addr(struct hdd_context *hdd_ctx, uint32_t num)
15100 {
15101 	uint32_t idx = hdd_ctx->num_derived_addr;
15102 	uint32_t iter;
15103 	uint8_t *buf = NULL;
15104 	uint8_t macaddr_b3, tmp_br3;
15105 	/*
15106 	 * Consider first provisioned mac address as source address to derive
15107 	 * remaining addresses
15108 	 */
15109 
15110 	uint8_t *src = hdd_ctx->provisioned_mac_addr[0].bytes;
15111 
15112 	for (iter = 0; iter < num; ++iter, ++idx) {
15113 		buf = hdd_ctx->derived_mac_addr[idx].bytes;
15114 		qdf_mem_copy(buf, src, QDF_MAC_ADDR_SIZE);
15115 		macaddr_b3 = buf[3];
15116 		tmp_br3 = ((macaddr_b3 >> 4 & INTF_MACADDR_MASK) + idx) &
15117 			INTF_MACADDR_MASK;
15118 		macaddr_b3 += tmp_br3;
15119 		macaddr_b3 ^= (1 << INTF_MACADDR_MASK);
15120 		buf[0] |= 0x02;
15121 		buf[3] = macaddr_b3;
15122 		hdd_debug(QDF_MAC_ADDR_FMT, QDF_MAC_ADDR_REF(buf));
15123 		hdd_ctx->num_derived_addr++;
15124 	}
15125 }
15126 
15127 /**
15128  * hdd_platform_wlan_mac() - API to get mac addresses from platform driver
15129  * @hdd_ctx: HDD Context
15130  *
15131  * API to get mac addresses from platform driver and update the driver
15132  * structures and configure FW with the base mac address.
15133  * Return: int
15134  */
15135 static int hdd_platform_wlan_mac(struct hdd_context *hdd_ctx)
15136 {
15137 	uint32_t no_of_mac_addr, iter;
15138 	uint32_t max_mac_addr = QDF_MAX_CONCURRENCY_PERSONA;
15139 	uint32_t mac_addr_size = QDF_MAC_ADDR_SIZE;
15140 	uint8_t *addr, *buf;
15141 	struct device *dev = hdd_ctx->parent_dev;
15142 	tSirMacAddr mac_addr;
15143 	QDF_STATUS status;
15144 
15145 	addr = hdd_get_platform_wlan_mac_buff(dev, &no_of_mac_addr);
15146 
15147 	if (no_of_mac_addr == 0 || !addr) {
15148 		hdd_debug("No mac configured from platform driver");
15149 		return -EINVAL;
15150 	}
15151 
15152 	hdd_free_mac_address_lists(hdd_ctx);
15153 
15154 	if (no_of_mac_addr > max_mac_addr)
15155 		no_of_mac_addr = max_mac_addr;
15156 
15157 	qdf_mem_copy(&mac_addr, addr, mac_addr_size);
15158 
15159 	for (iter = 0; iter < no_of_mac_addr; ++iter, addr += mac_addr_size) {
15160 		buf = hdd_ctx->provisioned_mac_addr[iter].bytes;
15161 		qdf_mem_copy(buf, addr, QDF_MAC_ADDR_SIZE);
15162 		hdd_info("provisioned MAC Addr [%d] "QDF_MAC_ADDR_FMT, iter,
15163 			 QDF_MAC_ADDR_REF(buf));
15164 	}
15165 
15166 	hdd_ctx->num_provisioned_addr = no_of_mac_addr;
15167 
15168 	if (hdd_ctx->config->mac_provision) {
15169 		addr = hdd_get_platform_wlan_derived_mac_buff(dev,
15170 							      &no_of_mac_addr);
15171 
15172 		if (no_of_mac_addr == 0 || !addr)
15173 			hdd_warn("No derived address from platform driver");
15174 		else if (no_of_mac_addr >
15175 			 (max_mac_addr - hdd_ctx->num_provisioned_addr))
15176 			no_of_mac_addr = (max_mac_addr -
15177 					  hdd_ctx->num_provisioned_addr);
15178 
15179 		for (iter = 0; iter < no_of_mac_addr; ++iter,
15180 		     addr += mac_addr_size) {
15181 			buf = hdd_ctx->derived_mac_addr[iter].bytes;
15182 			qdf_mem_copy(buf, addr, QDF_MAC_ADDR_SIZE);
15183 			hdd_debug("derived MAC Addr [%d] "QDF_MAC_ADDR_FMT, iter,
15184 				  QDF_MAC_ADDR_REF(buf));
15185 		}
15186 		hdd_ctx->num_derived_addr = no_of_mac_addr;
15187 	}
15188 
15189 	no_of_mac_addr = hdd_ctx->num_provisioned_addr +
15190 					 hdd_ctx->num_derived_addr;
15191 	if (no_of_mac_addr < max_mac_addr)
15192 		hdd_populate_random_mac_addr(hdd_ctx, max_mac_addr -
15193 					     no_of_mac_addr);
15194 
15195 	status = sme_set_custom_mac_addr(mac_addr);
15196 	if (!QDF_IS_STATUS_SUCCESS(status))
15197 		return -EAGAIN;
15198 
15199 	return 0;
15200 }
15201 
15202 /**
15203  * hdd_update_mac_addr_to_fw() - API to update wlan mac addresses to FW
15204  * @hdd_ctx: HDD Context
15205  *
15206  * Update MAC address to FW. If MAC address passed by FW is invalid, host
15207  * will generate its own MAC and update it to FW.
15208  *
15209  * Return: 0 for success
15210  *         Non-zero error code for failure
15211  */
15212 static int hdd_update_mac_addr_to_fw(struct hdd_context *hdd_ctx)
15213 {
15214 	tSirMacAddr custom_mac_addr;
15215 	QDF_STATUS status;
15216 
15217 	if (hdd_ctx->num_provisioned_addr)
15218 		qdf_mem_copy(&custom_mac_addr,
15219 			     &hdd_ctx->provisioned_mac_addr[0].bytes[0],
15220 			     sizeof(tSirMacAddr));
15221 	else
15222 		qdf_mem_copy(&custom_mac_addr,
15223 			     &hdd_ctx->derived_mac_addr[0].bytes[0],
15224 			     sizeof(tSirMacAddr));
15225 	status = sme_set_custom_mac_addr(custom_mac_addr);
15226 	if (!QDF_IS_STATUS_SUCCESS(status))
15227 		return -EAGAIN;
15228 	return 0;
15229 }
15230 
15231 /**
15232  * hdd_initialize_mac_address() - API to get wlan mac addresses
15233  * @hdd_ctx: HDD Context
15234  *
15235  * Get MAC addresses from platform driver or wlan_mac.bin. If platform driver
15236  * is provisioned with mac addresses, driver uses it, else it will use
15237  * wlan_mac.bin to update HW MAC addresses.
15238  *
15239  * Return: None
15240  */
15241 static int hdd_initialize_mac_address(struct hdd_context *hdd_ctx)
15242 {
15243 	QDF_STATUS status;
15244 	int ret;
15245 
15246 	ret = hdd_platform_wlan_mac(hdd_ctx);
15247 	if (!ret) {
15248 		hdd_info("using MAC address from platform driver");
15249 		return ret;
15250 	} else if (hdd_ctx->config->mac_provision) {
15251 		hdd_err("getting MAC address from platform driver failed");
15252 		return ret;
15253 	}
15254 
15255 	status = hdd_update_mac_config(hdd_ctx);
15256 	if (QDF_IS_STATUS_SUCCESS(status)) {
15257 		hdd_info("using MAC address from wlan_mac.bin");
15258 		return 0;
15259 	}
15260 
15261 	hdd_info("using default MAC address");
15262 
15263 	/* Use fw provided MAC */
15264 	if (!qdf_is_macaddr_zero(&hdd_ctx->hw_macaddr)) {
15265 		hdd_update_macaddr(hdd_ctx, hdd_ctx->hw_macaddr, false);
15266 		return 0;
15267 	} else if (hdd_generate_macaddr_auto(hdd_ctx) != 0) {
15268 		struct qdf_mac_addr mac_addr;
15269 
15270 		hdd_err("MAC failure from device serial no.");
15271 		qdf_get_random_bytes(&mac_addr, sizeof(mac_addr));
15272 		/*
15273 		 * Reset multicast bit (bit-0) and set
15274 		 * locally-administered bit
15275 		 */
15276 		mac_addr.bytes[0] = 0x2;
15277 		hdd_update_macaddr(hdd_ctx, mac_addr, true);
15278 	}
15279 
15280 	ret = hdd_update_mac_addr_to_fw(hdd_ctx);
15281 	if (ret)
15282 		hdd_err("MAC address out-of-sync, ret:%d", ret);
15283 	return ret;
15284 }
15285 
15286 /* params being sent:
15287  * wmi_pdev_param_tx_chain_mask_1ss
15288  * wmi_pdev_param_mgmt_retry_limit
15289  * wmi_pdev_param_default_6ghz_rate
15290  * wmi_pdev_param_pdev_stats_tx_xretry_ext
15291  * wmi_pdev_param_smart_chainmask_scheme
15292  * wmi_pdev_param_alternative_chainmask_scheme
15293  * wmi_pdev_param_ani_enable
15294  * wmi_pdev_param_pcie_config
15295  */
15296 /**
15297  * hdd_pre_enable_configure() - Configurations prior to cds_enable
15298  * @hdd_ctx:	HDD context
15299  *
15300  * Pre configurations to be done at lower layer before calling cds enable.
15301  *
15302  * Return: 0 on success and errno on failure.
15303  */
15304 static int hdd_pre_enable_configure(struct hdd_context *hdd_ctx)
15305 {
15306 	int ret;
15307 	uint8_t val = 0;
15308 	uint8_t max_retry = 0;
15309 	bool enable_he_mcs0_for_6ghz_mgmt = false;
15310 	uint32_t tx_retry_multiplier;
15311 	QDF_STATUS status;
15312 	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
15313 	struct dev_set_param setparam[MAX_PDEV_PRE_ENABLE_PARAMS] = {};
15314 	bool check_value;
15315 	uint8_t index = 0;
15316 
15317 	cdp_register_pause_cb(soc, wlan_hdd_txrx_pause_cb);
15318 	/* Register HL netdev flow control callback */
15319 	cdp_hl_fc_register(soc, OL_TXRX_PDEV_ID, wlan_hdd_txrx_pause_cb);
15320 	/* Register rx mic error indication handler */
15321 	ucfg_dp_register_rx_mic_error_ind_handler(soc);
15322 
15323 	/*
15324 	 * Note that the cds_pre_enable() sequence triggers the cfg download.
15325 	 * The cfg download must occur before we update the SME config
15326 	 * since the SME config operation must access the cfg database
15327 	 */
15328 	status = hdd_set_sme_config(hdd_ctx);
15329 
15330 	if (QDF_STATUS_SUCCESS != status) {
15331 		hdd_err("Failed hdd_set_sme_config: %d", status);
15332 		ret = qdf_status_to_os_return(status);
15333 		goto out;
15334 	}
15335 
15336 	status = hdd_set_policy_mgr_user_cfg(hdd_ctx);
15337 	if (QDF_STATUS_SUCCESS != status) {
15338 		hdd_alert("Failed hdd_set_policy_mgr_user_cfg: %d", status);
15339 		ret = qdf_status_to_os_return(status);
15340 		goto out;
15341 	}
15342 
15343 	status = ucfg_mlme_get_tx_chainmask_1ss(hdd_ctx->psoc, &val);
15344 	if (QDF_STATUS_SUCCESS != status) {
15345 		hdd_err("Get tx_chainmask_1ss from mlme failed");
15346 		ret = qdf_status_to_os_return(status);
15347 		goto out;
15348 	}
15349 	ret = mlme_check_index_setparam(setparam,
15350 					wmi_pdev_param_tx_chain_mask_1ss,
15351 					val, index++,
15352 					MAX_PDEV_PRE_ENABLE_PARAMS);
15353 	if (QDF_IS_STATUS_ERROR(ret)) {
15354 		hdd_err("failed at wmi_pdev_param_tx_chain_mask_1ss");
15355 		goto out;
15356 
15357 	}
15358 
15359 	wlan_mlme_get_mgmt_max_retry(hdd_ctx->psoc, &max_retry);
15360 	ret = mlme_check_index_setparam(setparam,
15361 					wmi_pdev_param_mgmt_retry_limit,
15362 					max_retry, index++,
15363 					MAX_PDEV_PRE_ENABLE_PARAMS);
15364 	if (QDF_IS_STATUS_ERROR(ret)) {
15365 		hdd_err("failed at wmi_pdev_param_mgmt_retry_limit");
15366 		goto out;
15367 	}
15368 
15369 	wlan_mlme_get_mgmt_6ghz_rate_support(hdd_ctx->psoc,
15370 					     &enable_he_mcs0_for_6ghz_mgmt);
15371 	if (enable_he_mcs0_for_6ghz_mgmt) {
15372 		hdd_debug("HE rates for 6GHz mgmt frames are supported");
15373 		ret = mlme_check_index_setparam(
15374 					setparam,
15375 					wmi_pdev_param_default_6ghz_rate,
15376 					MGMT_DEFAULT_DATA_RATE_6GHZ, index++,
15377 					MAX_PDEV_PRE_ENABLE_PARAMS);
15378 		if (QDF_IS_STATUS_ERROR(ret)) {
15379 			hdd_err("wmi_pdev_param_default_6ghz_rate failed %d",
15380 				ret);
15381 			goto out;
15382 		}
15383 	}
15384 
15385 	wlan_mlme_get_tx_retry_multiplier(hdd_ctx->psoc,
15386 					  &tx_retry_multiplier);
15387 	ret = mlme_check_index_setparam(setparam,
15388 					wmi_pdev_param_pdev_stats_tx_xretry_ext,
15389 					tx_retry_multiplier, index++,
15390 					MAX_PDEV_PRE_ENABLE_PARAMS);
15391 	if (QDF_IS_STATUS_ERROR(ret)) {
15392 		hdd_err("failed at wmi_pdev_param_pdev_stats_tx_xretry_ext");
15393 		goto out;
15394 	}
15395 
15396 	ret = ucfg_get_smart_chainmask_enabled(hdd_ctx->psoc,
15397 					      &check_value);
15398 	if (QDF_IS_STATUS_SUCCESS(ret)) {
15399 		ret = mlme_check_index_setparam(
15400 					 setparam,
15401 					 wmi_pdev_param_smart_chainmask_scheme,
15402 					 (int)check_value, index++,
15403 					 MAX_PDEV_PRE_ENABLE_PARAMS);
15404 		if (QDF_IS_STATUS_ERROR(ret)) {
15405 			hdd_err("failed to set wmi_pdev_param_smart_chainmask_scheme");
15406 			goto out;
15407 		}
15408 	}
15409 
15410 	ret = ucfg_get_alternative_chainmask_enabled(hdd_ctx->psoc,
15411 						    &check_value);
15412 	if (QDF_IS_STATUS_SUCCESS(ret)) {
15413 		ret = mlme_check_index_setparam(
15414 				setparam,
15415 				wmi_pdev_param_alternative_chainmask_scheme,
15416 				(int)check_value, index++,
15417 				MAX_PDEV_PRE_ENABLE_PARAMS);
15418 		if (QDF_IS_STATUS_ERROR(ret)) {
15419 			hdd_err("failed to set wmi_pdev_param_alternative_chainmask_scheme");
15420 			goto out;
15421 		}
15422 	}
15423 
15424 	ret = ucfg_fwol_get_ani_enabled(hdd_ctx->psoc, &check_value);
15425 	if (QDF_IS_STATUS_SUCCESS(ret)) {
15426 		ret = mlme_check_index_setparam(setparam,
15427 						wmi_pdev_param_ani_enable,
15428 						(int)check_value, index++,
15429 						MAX_PDEV_PRE_ENABLE_PARAMS);
15430 		if (QDF_IS_STATUS_ERROR(ret)) {
15431 			hdd_err("failed to set wmi_pdev_param_ani_enable");
15432 			goto out;
15433 		}
15434 	}
15435 
15436 	ret = hdd_set_pcie_params(hdd_ctx, index, setparam);
15437 	if (QDF_IS_STATUS_ERROR(ret))
15438 		goto out;
15439 	else
15440 		index++;
15441 	ret = sme_send_multi_pdev_vdev_set_params(MLME_PDEV_SETPARAM,
15442 						  WMI_PDEV_ID_SOC, setparam,
15443 						  index);
15444 	if (QDF_IS_STATUS_ERROR(ret)) {
15445 		hdd_err("failed to send pdev set params");
15446 		goto out;
15447 	}
15448 
15449 	/* Configure global firmware params */
15450 	ret = ucfg_fwol_configure_global_params(hdd_ctx->psoc, hdd_ctx->pdev);
15451 	if (ret)
15452 		goto out;
15453 
15454 	status = hdd_set_sme_chan_list(hdd_ctx);
15455 	if (status != QDF_STATUS_SUCCESS) {
15456 		hdd_err("Failed to init channel list: %d", status);
15457 		ret = qdf_status_to_os_return(status);
15458 		goto out;
15459 	}
15460 
15461 	if (!hdd_update_config_cfg(hdd_ctx)) {
15462 		hdd_err("config update failed");
15463 		ret = -EINVAL;
15464 		goto out;
15465 	}
15466 	hdd_init_channel_avoidance(hdd_ctx);
15467 
15468 out:
15469 	return ret;
15470 }
15471 
15472 #ifdef FEATURE_P2P_LISTEN_OFFLOAD
15473 /**
15474  * wlan_hdd_p2p_lo_event_callback - P2P listen offload stop event handler
15475  * @context: context registered with sme_register_p2p_lo_event(). HDD
15476  *   always registers a hdd context pointer
15477  * @evt:event structure pointer
15478  *
15479  * This is the p2p listen offload stop event handler, it sends vendor
15480  * event back to supplicant to notify the stop reason.
15481  *
15482  * Return: None
15483  */
15484 static void wlan_hdd_p2p_lo_event_callback(void *context,
15485 					   struct sir_p2p_lo_event *evt)
15486 {
15487 	struct hdd_context *hdd_ctx = context;
15488 	struct sk_buff *vendor_event;
15489 	enum qca_nl80211_vendor_subcmds_index index =
15490 		QCA_NL80211_VENDOR_SUBCMD_P2P_LO_EVENT_INDEX;
15491 	struct wlan_hdd_link_info *link_info;
15492 
15493 	hdd_enter();
15494 
15495 	if (!hdd_ctx) {
15496 		hdd_err("Invalid HDD context pointer");
15497 		return;
15498 	}
15499 
15500 	link_info = hdd_get_link_info_by_vdev(hdd_ctx, evt->vdev_id);
15501 	if (!link_info) {
15502 		hdd_err("Cannot find adapter by vdev_id = %d",
15503 				evt->vdev_id);
15504 		return;
15505 	}
15506 
15507 	vendor_event =
15508 		wlan_cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
15509 						 &link_info->adapter->wdev,
15510 						 sizeof(uint32_t) +
15511 						 NLMSG_HDRLEN,
15512 						 index, GFP_KERNEL);
15513 	if (!vendor_event) {
15514 		hdd_err("wlan_cfg80211_vendor_event_alloc failed");
15515 		return;
15516 	}
15517 
15518 	if (nla_put_u32(vendor_event,
15519 			QCA_WLAN_VENDOR_ATTR_P2P_LISTEN_OFFLOAD_STOP_REASON,
15520 			evt->reason_code)) {
15521 		hdd_err("nla put failed");
15522 		wlan_cfg80211_vendor_free_skb(vendor_event);
15523 		return;
15524 	}
15525 
15526 	wlan_cfg80211_vendor_event(vendor_event, GFP_KERNEL);
15527 	hdd_debug("Sent P2P_LISTEN_OFFLOAD_STOP event for vdev_id = %d",
15528 			evt->vdev_id);
15529 }
15530 #else
15531 static void wlan_hdd_p2p_lo_event_callback(void *context,
15532 					   struct sir_p2p_lo_event *evt)
15533 {
15534 }
15535 #endif
15536 
15537 #ifdef FEATURE_WLAN_DYNAMIC_CVM
15538 static inline int hdd_set_vc_mode_config(struct hdd_context *hdd_ctx)
15539 {
15540 	return sme_set_vc_mode_config(hdd_ctx->config->vc_mode_cfg_bitmap);
15541 }
15542 #else
15543 static inline int hdd_set_vc_mode_config(struct hdd_context *hdd_ctx)
15544 {
15545 	return QDF_STATUS_SUCCESS;
15546 }
15547 #endif
15548 
15549 /**
15550  * hdd_adaptive_dwelltime_init() - initialization for adaptive dwell time config
15551  * @hdd_ctx: HDD context
15552  *
15553  * This function sends the adaptive dwell time config configuration to the
15554  * firmware via WMA
15555  *
15556  * Return: 0 - success, < 0 - failure
15557  */
15558 static int hdd_adaptive_dwelltime_init(struct hdd_context *hdd_ctx)
15559 {
15560 	QDF_STATUS status;
15561 	struct adaptive_dwelltime_params dwelltime_params;
15562 
15563 	status = ucfg_fwol_get_all_adaptive_dwelltime_params(hdd_ctx->psoc,
15564 							     &dwelltime_params);
15565 	status = ucfg_fwol_set_adaptive_dwelltime_config(&dwelltime_params);
15566 
15567 	hdd_debug("Sending Adaptive Dwelltime Configuration to fw");
15568 	if (!QDF_IS_STATUS_SUCCESS(status)) {
15569 		hdd_err("Failed to send Adaptive Dwelltime configuration!");
15570 		return -EAGAIN;
15571 	}
15572 	return 0;
15573 }
15574 
15575 int hdd_dbs_scan_selection_init(struct hdd_context *hdd_ctx)
15576 {
15577 	QDF_STATUS status;
15578 	struct wmi_dbs_scan_sel_params dbs_scan_params;
15579 	uint32_t i = 0;
15580 	uint8_t count = 0, numentries = 0;
15581 	uint8_t dual_mac_feature;
15582 	uint8_t dbs_scan_config[CDS_DBS_SCAN_PARAM_PER_CLIENT
15583 				* CDS_DBS_SCAN_CLIENTS_MAX];
15584 
15585 	status = ucfg_policy_mgr_get_dual_mac_feature(hdd_ctx->psoc,
15586 						      &dual_mac_feature);
15587 
15588 	if (status != QDF_STATUS_SUCCESS) {
15589 		hdd_err("can't get dual mac feature flag");
15590 		return -EINVAL;
15591 	}
15592 	/* check if DBS is enabled or supported */
15593 	if ((dual_mac_feature == DISABLE_DBS_CXN_AND_SCAN) ||
15594 	    (dual_mac_feature == ENABLE_DBS_CXN_AND_DISABLE_DBS_SCAN))
15595 		return -EINVAL;
15596 
15597 	hdd_string_to_u8_array(hdd_ctx->config->dbs_scan_selection,
15598 			       dbs_scan_config, &numentries,
15599 			       (CDS_DBS_SCAN_PARAM_PER_CLIENT
15600 				* CDS_DBS_SCAN_CLIENTS_MAX));
15601 
15602 	if (!numentries) {
15603 		hdd_debug("Do not send scan_selection_config");
15604 		return 0;
15605 	}
15606 
15607 	/* hdd_set_fw_log_params */
15608 	dbs_scan_params.num_clients = 0;
15609 	while (count < (numentries - 2)) {
15610 		dbs_scan_params.module_id[i] = dbs_scan_config[count];
15611 		dbs_scan_params.num_dbs_scans[i] = dbs_scan_config[count + 1];
15612 		dbs_scan_params.num_non_dbs_scans[i] =
15613 			dbs_scan_config[count + 2];
15614 		dbs_scan_params.num_clients++;
15615 		hdd_debug("module:%d NDS:%d NNDS:%d",
15616 			  dbs_scan_params.module_id[i],
15617 			  dbs_scan_params.num_dbs_scans[i],
15618 			  dbs_scan_params.num_non_dbs_scans[i]);
15619 		count += CDS_DBS_SCAN_PARAM_PER_CLIENT;
15620 		i++;
15621 	}
15622 
15623 	dbs_scan_params.pdev_id = 0;
15624 
15625 	hdd_debug("clients:%d pdev:%d",
15626 		  dbs_scan_params.num_clients, dbs_scan_params.pdev_id);
15627 
15628 	status = sme_set_dbs_scan_selection_config(hdd_ctx->mac_handle,
15629 						   &dbs_scan_params);
15630 	hdd_debug("Sending DBS Scan Selection Configuration to fw");
15631 	if (!QDF_IS_STATUS_SUCCESS(status)) {
15632 		hdd_err("Failed to send DBS Scan selection configuration!");
15633 		return -EAGAIN;
15634 	}
15635 	return 0;
15636 }
15637 
15638 #ifdef FEATURE_WLAN_AUTO_SHUTDOWN
15639 /**
15640  * hdd_set_auto_shutdown_cb() - Set auto shutdown callback
15641  * @hdd_ctx:	HDD context
15642  *
15643  * Set auto shutdown callback to get indications from firmware to indicate
15644  * userspace to shutdown WLAN after a configured amount of inactivity.
15645  *
15646  * Return: 0 on success and errno on failure.
15647  */
15648 static int hdd_set_auto_shutdown_cb(struct hdd_context *hdd_ctx)
15649 {
15650 	QDF_STATUS status;
15651 
15652 	if (!hdd_ctx->config->wlan_auto_shutdown)
15653 		return 0;
15654 
15655 	status = sme_set_auto_shutdown_cb(hdd_ctx->mac_handle,
15656 					  wlan_hdd_auto_shutdown_cb);
15657 	if (status != QDF_STATUS_SUCCESS)
15658 		hdd_err("Auto shutdown feature could not be enabled: %d",
15659 			status);
15660 
15661 	return qdf_status_to_os_return(status);
15662 }
15663 #else
15664 static int hdd_set_auto_shutdown_cb(struct hdd_context *hdd_ctx)
15665 {
15666 	return 0;
15667 }
15668 #endif
15669 
15670 #ifdef MWS_COEX
15671 #define MAX_PDEV_MWSCOEX_PARAMS 4
15672 /* params being sent:
15673  * wmi_pdev_param_mwscoex_4g_allow_quick_ftdm
15674  * wmi_pdev_param_mwscoex_set_5gnr_pwr_limit
15675  * wmi_pdev_param_mwscoex_pcc_chavd_delay
15676  * wmi_pdev_param_mwscoex_scc_chavd_delay
15677  */
15678 
15679 /**
15680  * hdd_init_mws_coex() - Initialize MWS coex configurations
15681  * @hdd_ctx:   HDD context
15682  *
15683  * This function sends MWS-COEX 4G quick FTDM and
15684  * MWS-COEX 5G-NR power limit to FW
15685  *
15686  * Return: 0 on success and errno on failure.
15687  */
15688 static int hdd_init_mws_coex(struct hdd_context *hdd_ctx)
15689 {
15690 	int ret = 0;
15691 	uint32_t mws_coex_4g_quick_tdm = 0, mws_coex_5g_nr_pwr_limit = 0;
15692 	uint32_t mws_coex_pcc_channel_avoid_delay = 0;
15693 	uint32_t mws_coex_scc_channel_avoid_delay = 0;
15694 	struct dev_set_param setparam[MAX_PDEV_MWSCOEX_PARAMS] = {};
15695 	uint8_t index = 0;
15696 
15697 	ucfg_mlme_get_mws_coex_4g_quick_tdm(hdd_ctx->psoc,
15698 					    &mws_coex_4g_quick_tdm);
15699 	ret = mlme_check_index_setparam(
15700 				setparam,
15701 				wmi_pdev_param_mwscoex_4g_allow_quick_ftdm,
15702 				mws_coex_4g_quick_tdm, index++,
15703 				MAX_PDEV_MWSCOEX_PARAMS);
15704 	if (QDF_IS_STATUS_ERROR(ret)) {
15705 		hdd_err("failed at wmi_pdev_param_mwscoex_4g_allow_quick_ftdm");
15706 		goto error;
15707 	}
15708 
15709 	ucfg_mlme_get_mws_coex_5g_nr_pwr_limit(hdd_ctx->psoc,
15710 					       &mws_coex_5g_nr_pwr_limit);
15711 	ret = mlme_check_index_setparam(
15712 				      setparam,
15713 				      wmi_pdev_param_mwscoex_set_5gnr_pwr_limit,
15714 				      mws_coex_5g_nr_pwr_limit, index++,
15715 				      MAX_PDEV_MWSCOEX_PARAMS);
15716 	if (QDF_IS_STATUS_ERROR(ret)) {
15717 		hdd_err("failed at wmi_pdev_param_mwscoex_set_5gnr_pwr_limit");
15718 		goto error;
15719 	}
15720 
15721 	ucfg_mlme_get_mws_coex_pcc_channel_avoid_delay(
15722 					hdd_ctx->psoc,
15723 					&mws_coex_pcc_channel_avoid_delay);
15724 	ret = mlme_check_index_setparam(setparam,
15725 					wmi_pdev_param_mwscoex_pcc_chavd_delay,
15726 					mws_coex_pcc_channel_avoid_delay,
15727 					index++, MAX_PDEV_MWSCOEX_PARAMS);
15728 	if (QDF_IS_STATUS_ERROR(ret)) {
15729 		hdd_err("failed at wmi_pdev_param_mwscoex_pcc_chavd_delay");
15730 		goto error;
15731 	}
15732 
15733 	ucfg_mlme_get_mws_coex_scc_channel_avoid_delay(
15734 					hdd_ctx->psoc,
15735 					&mws_coex_scc_channel_avoid_delay);
15736 	ret = mlme_check_index_setparam(setparam,
15737 					wmi_pdev_param_mwscoex_scc_chavd_delay,
15738 					mws_coex_scc_channel_avoid_delay,
15739 					index++, MAX_PDEV_MWSCOEX_PARAMS);
15740 	if (QDF_IS_STATUS_ERROR(ret)) {
15741 		hdd_err("failed at wmi_pdev_param_mwscoex_scc_chavd_delay");
15742 		goto error;
15743 	}
15744 	ret = sme_send_multi_pdev_vdev_set_params(MLME_PDEV_SETPARAM,
15745 						  WMI_PDEV_ID_SOC, setparam,
15746 						  index);
15747 	if (QDF_IS_STATUS_ERROR(ret))
15748 		hdd_err("failed to send pdev MWSCOEX set params");
15749 error:
15750 	return ret;
15751 }
15752 #else
15753 static int hdd_init_mws_coex(struct hdd_context *hdd_ctx)
15754 {
15755 	return 0;
15756 }
15757 #endif
15758 
15759 #ifdef THERMAL_STATS_SUPPORT
15760 static void hdd_thermal_stats_cmd_init(struct hdd_context *hdd_ctx)
15761 {
15762 	hdd_send_get_thermal_stats_cmd(hdd_ctx, thermal_stats_init, NULL, NULL);
15763 }
15764 #else
15765 static void hdd_thermal_stats_cmd_init(struct hdd_context *hdd_ctx)
15766 {
15767 }
15768 #endif
15769 
15770 #ifdef WLAN_FEATURE_CAL_FAILURE_TRIGGER
15771 /**
15772  * hdd_cal_fail_send_event()- send calibration failure information
15773  * @cal_type: calibration type
15774  * @reason: reason for calibration failure
15775  *
15776  * This Function sends calibration failure diag event
15777  *
15778  * Return: void.
15779  */
15780 static void hdd_cal_fail_send_event(uint8_t cal_type, uint8_t reason)
15781 {
15782 	/*
15783 	 * For now we are going with the print. Once CST APK has support to
15784 	 * read the diag events then we will add the diag event here.
15785 	 */
15786 	hdd_debug("Received cal failure event with cal_type:%x reason:%x",
15787 		  cal_type, reason);
15788 }
15789 #else
15790 static inline void hdd_cal_fail_send_event(uint8_t cal_type, uint8_t reason)
15791 {
15792 }
15793 #endif
15794 
15795 /**
15796  * hdd_features_init() - Init features
15797  * @hdd_ctx:	HDD context
15798  *
15799  * Initialize features and their feature context after WLAN firmware is up.
15800  *
15801  * Return: 0 on success and errno on failure.
15802  */
15803 static int hdd_features_init(struct hdd_context *hdd_ctx)
15804 {
15805 	struct tx_power_limit hddtxlimit;
15806 	QDF_STATUS status;
15807 	int ret;
15808 	mac_handle_t mac_handle;
15809 	bool b_cts2self, is_imps_enabled;
15810 	bool rf_test_mode;
15811 	bool std_6ghz_conn_policy;
15812 	uint32_t fw_data_stall_evt;
15813 	bool disable_vlp_sta_conn_sp_ap;
15814 
15815 	hdd_enter();
15816 
15817 	ret = hdd_init_mws_coex(hdd_ctx);
15818 	if (ret)
15819 		hdd_warn("Error initializing mws-coex");
15820 
15821 	/* FW capabilities received, Set the Dot11 mode */
15822 	mac_handle = hdd_ctx->mac_handle;
15823 	sme_setdef_dot11mode(mac_handle);
15824 
15825 	ucfg_mlme_is_imps_enabled(hdd_ctx->psoc, &is_imps_enabled);
15826 	hdd_set_idle_ps_config(hdd_ctx, is_imps_enabled);
15827 
15828 	fw_data_stall_evt = ucfg_dp_fw_data_stall_evt_enabled();
15829 
15830 	/* Send Enable/Disable data stall detection cmd to FW */
15831 	sme_cli_set_command(0, wmi_pdev_param_data_stall_detect_enable,
15832 			    fw_data_stall_evt, PDEV_CMD);
15833 
15834 	ucfg_mlme_get_go_cts2self_for_sta(hdd_ctx->psoc, &b_cts2self);
15835 	if (b_cts2self)
15836 		sme_set_cts2self_for_p2p_go(mac_handle);
15837 
15838 	if (hdd_set_vc_mode_config(hdd_ctx))
15839 		hdd_warn("Error in setting Voltage Corner mode config to FW");
15840 
15841 	if (ucfg_dp_rx_ol_init(hdd_ctx->psoc, hdd_ctx->is_wifi3_0_target))
15842 		hdd_err("Unable to initialize Rx LRO/GRO in fw");
15843 
15844 	if (hdd_adaptive_dwelltime_init(hdd_ctx))
15845 		hdd_err("Unable to send adaptive dwelltime setting to FW");
15846 
15847 	if (hdd_dbs_scan_selection_init(hdd_ctx))
15848 		hdd_err("Unable to send DBS scan selection setting to FW");
15849 
15850 	ret = hdd_init_thermal_info(hdd_ctx);
15851 	if (ret) {
15852 		hdd_err("Error while initializing thermal information");
15853 		return ret;
15854 	}
15855 
15856 	/**
15857 	 * In case of SSR/PDR, if pktlog was enabled manually before
15858 	 * SSR/PDR, then enable it again automatically after Wlan
15859 	 * device up.
15860 	 * During SSR/PDR, pktlog will be disabled as part of
15861 	 * hdd_features_deinit if pktlog is enabled in ini.
15862 	 * Re-enable pktlog in SSR case, if pktlog is enabled in ini.
15863 	 */
15864 	if (hdd_get_conparam() != QDF_GLOBAL_MONITOR_MODE &&
15865 	    (cds_is_packet_log_enabled() ||
15866 	    (cds_is_driver_recovering() && hdd_ctx->is_pktlog_enabled)))
15867 		hdd_pktlog_enable_disable(hdd_ctx, true, 0, 0);
15868 
15869 	hddtxlimit.txPower2g = ucfg_get_tx_power(hdd_ctx->psoc, BAND_2G);
15870 	hddtxlimit.txPower5g = ucfg_get_tx_power(hdd_ctx->psoc, BAND_5G);
15871 	status = sme_txpower_limit(mac_handle, &hddtxlimit);
15872 	if (!QDF_IS_STATUS_SUCCESS(status))
15873 		hdd_err("Error setting txlimit in sme: %d", status);
15874 
15875 	wlan_hdd_tsf_init(hdd_ctx);
15876 
15877 	status = sme_enable_disable_chanavoidind_event(mac_handle, 0);
15878 	if (QDF_IS_STATUS_ERROR(status) && (status != QDF_STATUS_E_NOSUPPORT)) {
15879 		hdd_err("Failed to disable Chan Avoidance Indication");
15880 		return -EINVAL;
15881 	}
15882 
15883 	/* register P2P Listen Offload event callback */
15884 	if (wma_is_p2p_lo_capable())
15885 		sme_register_p2p_lo_event(mac_handle, hdd_ctx,
15886 					  wlan_hdd_p2p_lo_event_callback);
15887 	wlan_hdd_register_mcc_quota_event_callback(hdd_ctx);
15888 	ret = hdd_set_auto_shutdown_cb(hdd_ctx);
15889 
15890 	if (ret)
15891 		return -EINVAL;
15892 
15893 	wlan_hdd_init_chan_info(hdd_ctx);
15894 	wlan_hdd_twt_init(hdd_ctx);
15895 	wlan_hdd_gpio_wakeup_init(hdd_ctx);
15896 
15897 	status = ucfg_mlme_is_rf_test_mode_enabled(hdd_ctx->psoc,
15898 						   &rf_test_mode);
15899 	if (!QDF_IS_STATUS_SUCCESS(status)) {
15900 		hdd_err("Get rf test mode failed");
15901 		return QDF_STATUS_E_FAILURE;
15902 	}
15903 
15904 	if (rf_test_mode) {
15905 		wlan_cm_set_check_6ghz_security(hdd_ctx->psoc, false);
15906 		wlan_cm_set_6ghz_key_mgmt_mask(hdd_ctx->psoc,
15907 					       DEFAULT_KEYMGMT_6G_MASK);
15908 	}
15909 
15910 	status = ucfg_mlme_is_standard_6ghz_conn_policy_enabled(hdd_ctx->psoc,
15911 							&std_6ghz_conn_policy);
15912 
15913 	if (!QDF_IS_STATUS_SUCCESS(status)) {
15914 		hdd_err("Get 6ghz standard connection policy failed");
15915 		return QDF_STATUS_E_FAILURE;
15916 	}
15917 	if (std_6ghz_conn_policy)
15918 		wlan_cm_set_standard_6ghz_conn_policy(hdd_ctx->psoc, true);
15919 
15920 	status = ucfg_mlme_is_disable_vlp_sta_conn_to_sp_ap_enabled(
15921 						hdd_ctx->psoc,
15922 						&disable_vlp_sta_conn_sp_ap);
15923 	if (!QDF_IS_STATUS_SUCCESS(status)) {
15924 		hdd_err("Get disable vlp sta conn to sp flag failed");
15925 		return QDF_STATUS_E_FAILURE;
15926 	}
15927 
15928 	if (disable_vlp_sta_conn_sp_ap)
15929 		wlan_cm_set_disable_vlp_sta_conn_to_sp_ap(hdd_ctx->psoc, true);
15930 
15931 	hdd_thermal_stats_cmd_init(hdd_ctx);
15932 	sme_set_cal_failure_event_cb(hdd_ctx->mac_handle,
15933 				     hdd_cal_fail_send_event);
15934 
15935 	hdd_exit();
15936 	return 0;
15937 }
15938 
15939 /**
15940  * hdd_register_bcn_cb() - register scan beacon callback
15941  * @hdd_ctx: Pointer to the HDD context
15942  *
15943  * Return: QDF_STATUS
15944  */
15945 static inline QDF_STATUS hdd_register_bcn_cb(struct hdd_context *hdd_ctx)
15946 {
15947 	QDF_STATUS status;
15948 
15949 	status = ucfg_scan_register_bcn_cb(hdd_ctx->psoc,
15950 		wlan_cfg80211_inform_bss_frame,
15951 		SCAN_CB_TYPE_INFORM_BCN);
15952 	if (!QDF_IS_STATUS_SUCCESS(status)) {
15953 		hdd_err("failed to register SCAN_CB_TYPE_INFORM_BCN with status code %08d [x%08x]",
15954 			status, status);
15955 		return status;
15956 	}
15957 
15958 	status = ucfg_scan_register_bcn_cb(hdd_ctx->psoc,
15959 		wlan_cfg80211_unlink_bss_list,
15960 		SCAN_CB_TYPE_UNLINK_BSS);
15961 	if (!QDF_IS_STATUS_SUCCESS(status)) {
15962 		hdd_err("failed to refister SCAN_CB_TYPE_FLUSH_BSS with status code %08d [x%08x]",
15963 			status, status);
15964 		return status;
15965 	}
15966 
15967 	return QDF_STATUS_SUCCESS;
15968 }
15969 
15970 /**
15971  * hdd_v2_flow_pool_map() - Flow pool create callback when vdev is active
15972  * @vdev_id: vdev_id, corresponds to flow_pool
15973  *
15974  * Return: none.
15975  */
15976 static void hdd_v2_flow_pool_map(int vdev_id)
15977 {
15978 	QDF_STATUS status;
15979 	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
15980 	struct wlan_objmgr_vdev *vdev;
15981 
15982 	if (!hdd_ctx) {
15983 		hdd_err("HDD context null");
15984 		return;
15985 	}
15986 
15987 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(hdd_ctx->psoc, vdev_id,
15988 						    WLAN_OSIF_ID);
15989 	if (!vdev) {
15990 		hdd_err("Invalid VDEV %d", vdev_id);
15991 		return;
15992 	}
15993 
15994 	if (wlan_vdev_mlme_is_mlo_link_switch_in_progress(vdev)) {
15995 		hdd_info("Link switch ongoing, do not invoke flow pool map");
15996 		goto release_ref;
15997 	}
15998 
15999 	status = cdp_flow_pool_map(cds_get_context(QDF_MODULE_ID_SOC),
16000 				   OL_TXRX_PDEV_ID, vdev_id);
16001 	/*
16002 	 * For Adrastea flow control v2 is based on FW MAP events,
16003 	 * so this above callback is not implemented.
16004 	 * Hence this is not actual failure. Dont return failure
16005 	 */
16006 	if ((status != QDF_STATUS_SUCCESS) &&
16007 	    (status != QDF_STATUS_E_INVAL)) {
16008 		hdd_err("vdev_id: %d, failed to create flow pool status %d",
16009 			vdev_id, status);
16010 	}
16011 
16012 release_ref:
16013 	wlan_objmgr_vdev_release_ref(vdev, WLAN_OSIF_ID);
16014 }
16015 
16016 /**
16017  * hdd_v2_flow_pool_unmap() - Flow pool create callback when vdev is not active
16018  * @vdev_id: vdev_id, corresponds to flow_pool
16019  *
16020  * Return: none.
16021  */
16022 static void hdd_v2_flow_pool_unmap(int vdev_id)
16023 {
16024 	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
16025 	struct wlan_objmgr_vdev *vdev;
16026 
16027 	if (!hdd_ctx) {
16028 		hdd_err("HDD context null");
16029 		return;
16030 	}
16031 
16032 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(hdd_ctx->psoc, vdev_id,
16033 						    WLAN_OSIF_ID);
16034 	if (!vdev) {
16035 		hdd_err("Invalid VDEV %d", vdev_id);
16036 		return;
16037 	}
16038 
16039 	if (wlan_vdev_mlme_is_mlo_link_switch_in_progress(vdev)) {
16040 		hdd_info("Link switch ongoing do not invoke flow pool unmap");
16041 		goto release_ref;
16042 	}
16043 
16044 	cdp_flow_pool_unmap(cds_get_context(QDF_MODULE_ID_SOC),
16045 			    OL_TXRX_PDEV_ID, vdev_id);
16046 release_ref:
16047 	wlan_objmgr_vdev_release_ref(vdev, WLAN_OSIF_ID);
16048 }
16049 
16050 static void hdd_hastings_bt_war_initialize(struct hdd_context *hdd_ctx)
16051 {
16052 	if (hdd_ctx->config->iface_change_wait_time)
16053 		hdd_hastings_bt_war_disable_fw(hdd_ctx);
16054 	else
16055 		hdd_hastings_bt_war_enable_fw(hdd_ctx);
16056 }
16057 
16058 #define MAX_PDEV_CFG_CDS_PARAMS 8
16059 /* params being sent:
16060  * wmi_pdev_param_set_iot_pattern
16061  * wmi_pdev_param_max_mpdus_in_ampdu
16062  * wmi_pdev_param_enable_rts_sifs_bursting
16063  * wmi_pdev_param_peer_stats_info_enable
16064  * wmi_pdev_param_abg_mode_tx_chain_num
16065  * wmi_pdev_param_gcmp_support_enable
16066  * wmi_pdev_auto_detect_power_failure
16067  * wmi_pdev_param_fast_pwr_transition
16068  */
16069 
16070 /**
16071  * hdd_configure_cds() - Configure cds modules
16072  * @hdd_ctx:	HDD context
16073  *
16074  * Enable Cds modules after WLAN firmware is up.
16075  *
16076  * Return: 0 on success and errno on failure.
16077  */
16078 int hdd_configure_cds(struct hdd_context *hdd_ctx)
16079 {
16080 	int ret;
16081 	QDF_STATUS status;
16082 	int set_value;
16083 	mac_handle_t mac_handle;
16084 	bool enable_rts_sifsbursting;
16085 	uint8_t enable_phy_reg_retention;
16086 	uint8_t max_mpdus_inampdu, is_force_1x1 = 0;
16087 	uint32_t num_abg_tx_chains = 0;
16088 	uint16_t num_11b_tx_chains = 0;
16089 	uint16_t num_11ag_tx_chains = 0;
16090 	struct policy_mgr_dp_cbacks dp_cbs = {0};
16091 	bool value;
16092 	enum pmo_auto_pwr_detect_failure_mode auto_power_fail_mode;
16093 	bool bval = false;
16094 	uint8_t max_index = MAX_PDEV_CFG_CDS_PARAMS;
16095 	struct dev_set_param setparam[MAX_PDEV_CFG_CDS_PARAMS] = {};
16096 	uint8_t index = 0;
16097 	uint8_t next_index = 0;
16098 	mac_handle = hdd_ctx->mac_handle;
16099 
16100 	status = ucfg_policy_mgr_get_force_1x1(hdd_ctx->psoc, &is_force_1x1);
16101 	if (status != QDF_STATUS_SUCCESS) {
16102 		hdd_err("Failed to get force 1x1 value");
16103 		goto out;
16104 	}
16105 	if (is_force_1x1) {
16106 		status = mlme_check_index_setparam(
16107 						setparam,
16108 						wmi_pdev_param_set_iot_pattern,
16109 						1, index++,
16110 						max_index);
16111 		if (QDF_IS_STATUS_ERROR(status)) {
16112 			hdd_err("failed at wmi_pdev_param_set_iot_pattern");
16113 			goto out;
16114 		}
16115 	}
16116 	/* set chip power save failure detected callback */
16117 	sme_set_chip_pwr_save_fail_cb(mac_handle,
16118 				      hdd_chip_pwr_save_fail_detected_cb);
16119 
16120 	status = ucfg_get_max_mpdus_inampdu(hdd_ctx->psoc,
16121 					    &max_mpdus_inampdu);
16122 	if (status) {
16123 		hdd_err("Failed to get max mpdus in ampdu value");
16124 		goto out;
16125 	}
16126 
16127 	if (max_mpdus_inampdu) {
16128 		set_value = max_mpdus_inampdu;
16129 		status = mlme_check_index_setparam(
16130 					      setparam,
16131 					      wmi_pdev_param_max_mpdus_in_ampdu,
16132 					      set_value, index++,
16133 					      max_index);
16134 		if (QDF_IS_STATUS_ERROR(status)) {
16135 			hdd_err("failed at  wmi_pdev_param_max_mpdus_in_ampdu");
16136 			goto out;
16137 		}
16138 	}
16139 
16140 	status = ucfg_get_enable_rts_sifsbursting(hdd_ctx->psoc,
16141 						  &enable_rts_sifsbursting);
16142 	if (status) {
16143 		hdd_err("Failed to get rts sifs bursting value");
16144 		goto out;
16145 	}
16146 
16147 	if (enable_rts_sifsbursting) {
16148 		set_value = enable_rts_sifsbursting;
16149 		status = mlme_check_index_setparam(
16150 					setparam,
16151 					wmi_pdev_param_enable_rts_sifs_bursting,
16152 					set_value, index++,
16153 					max_index);
16154 		if (QDF_IS_STATUS_ERROR(status)) {
16155 			hdd_err("Failed at wmi_pdev_param_enable_rts_sifs_bursting");
16156 			goto out;
16157 		}
16158 	}
16159 
16160 	ucfg_mlme_get_sap_get_peer_info(hdd_ctx->psoc, &value);
16161 	if (value) {
16162 		set_value = value;
16163 		status = mlme_check_index_setparam(
16164 					setparam,
16165 					wmi_pdev_param_peer_stats_info_enable,
16166 					set_value, index++,
16167 					max_index);
16168 		if (QDF_IS_STATUS_ERROR(status)) {
16169 			hdd_err("Failed at wmi_pdev_param_peer_stats_info_enable");
16170 			goto out;
16171 		}
16172 	}
16173 
16174 	status = ucfg_mlme_get_num_11b_tx_chains(hdd_ctx->psoc,
16175 						 &num_11b_tx_chains);
16176 	if (status != QDF_STATUS_SUCCESS) {
16177 		hdd_err("Failed to get num_11b_tx_chains");
16178 		goto out;
16179 	}
16180 
16181 	status = ucfg_mlme_get_num_11ag_tx_chains(hdd_ctx->psoc,
16182 						  &num_11ag_tx_chains);
16183 	if (status != QDF_STATUS_SUCCESS) {
16184 		hdd_err("Failed to get num_11ag_tx_chains");
16185 		goto out;
16186 	}
16187 
16188 	status = ucfg_mlme_get_vht_enable2x2(hdd_ctx->psoc, &bval);
16189 	if (!QDF_IS_STATUS_SUCCESS(status))
16190 		hdd_err("unable to get vht_enable2x2");
16191 
16192 	if (!bval) {
16193 		if (num_11b_tx_chains > 1)
16194 			num_11b_tx_chains = 1;
16195 		if (num_11ag_tx_chains > 1)
16196 			num_11ag_tx_chains = 1;
16197 	}
16198 	WMI_PDEV_PARAM_SET_11B_TX_CHAIN_NUM(num_abg_tx_chains,
16199 					    num_11b_tx_chains);
16200 	WMI_PDEV_PARAM_SET_11AG_TX_CHAIN_NUM(num_abg_tx_chains,
16201 					     num_11ag_tx_chains);
16202 	status = mlme_check_index_setparam(setparam,
16203 					   wmi_pdev_param_abg_mode_tx_chain_num,
16204 					   num_abg_tx_chains, index++,
16205 					   max_index);
16206 	if (QDF_IS_STATUS_ERROR(status)) {
16207 		hdd_err("Failed at wmi_pdev_param_abg_mode_tx_chain_num");
16208 		goto out;
16209 	}
16210 	/* Send some pdev params to maintain legacy order of pdev set params
16211 	 * at hdd_pre_enable_configure
16212 	 */
16213 	status = sme_send_multi_pdev_vdev_set_params(MLME_PDEV_SETPARAM,
16214 						     WMI_PDEV_ID_SOC, setparam,
16215 						     index);
16216 	if (QDF_IS_STATUS_ERROR(status)) {
16217 		hdd_err("Failed to send 1st set of pdev params");
16218 		goto out;
16219 	}
16220 	if (!ucfg_reg_is_regdb_offloaded(hdd_ctx->psoc))
16221 		ucfg_reg_program_default_cc(hdd_ctx->pdev,
16222 					    hdd_ctx->reg.reg_domain);
16223 
16224 	ret = hdd_pre_enable_configure(hdd_ctx);
16225 	if (ret) {
16226 		hdd_err("Failed to pre-configure cds");
16227 		goto out;
16228 	}
16229 
16230 	/* Always get latest IPA resources allocated from cds_open and configure
16231 	 * IPA module before configuring them to FW. Sequence required as crash
16232 	 * observed otherwise.
16233 	 */
16234 
16235 	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
16236 		ipa_disable_register_cb();
16237 	} else {
16238 		status = ipa_register_is_ipa_ready(hdd_ctx->pdev);
16239 		if (!QDF_IS_STATUS_SUCCESS(status)) {
16240 			hdd_err("ipa_register_is_ipa_ready failed");
16241 			goto out;
16242 		}
16243 	}
16244 
16245 	/*
16246 	 * Start CDS which starts up the SME/MAC/HAL modules and everything
16247 	 * else
16248 	 */
16249 	status = cds_enable(hdd_ctx->psoc);
16250 
16251 	if (!QDF_IS_STATUS_SUCCESS(status)) {
16252 		hdd_err("cds_enable failed");
16253 		goto out;
16254 	}
16255 
16256 	status = hdd_post_cds_enable_config(hdd_ctx);
16257 	if (!QDF_IS_STATUS_SUCCESS(status)) {
16258 		hdd_err("hdd_post_cds_enable_config failed");
16259 		goto cds_disable;
16260 	}
16261 	status = hdd_register_bcn_cb(hdd_ctx);
16262 	if (!QDF_IS_STATUS_SUCCESS(status)) {
16263 		hdd_err("hdd_register_bcn_cb failed");
16264 		goto cds_disable;
16265 	}
16266 
16267 	ret = hdd_features_init(hdd_ctx);
16268 	if (ret)
16269 		goto cds_disable;
16270 
16271 	/*
16272 	 * Donot disable rx offload on concurrency for lithium and
16273 	 * beryllium based targets
16274 	 */
16275 	if (!hdd_ctx->is_wifi3_0_target)
16276 		if (ucfg_dp_is_ol_enabled(hdd_ctx->psoc))
16277 			dp_cbs.hdd_disable_rx_ol_in_concurrency =
16278 					hdd_disable_rx_ol_in_concurrency;
16279 	dp_cbs.hdd_set_rx_mode_rps_cb = ucfg_dp_set_rx_mode_rps;
16280 	dp_cbs.hdd_ipa_set_mcc_mode_cb = hdd_ipa_set_mcc_mode;
16281 	dp_cbs.hdd_v2_flow_pool_map = hdd_v2_flow_pool_map;
16282 	dp_cbs.hdd_v2_flow_pool_unmap = hdd_v2_flow_pool_unmap;
16283 	status = policy_mgr_register_dp_cb(hdd_ctx->psoc, &dp_cbs);
16284 	if (!QDF_IS_STATUS_SUCCESS(status)) {
16285 		hdd_debug("Failed to register DP cb with Policy Manager");
16286 		goto cds_disable;
16287 	}
16288 	status = policy_mgr_register_mode_change_cb(hdd_ctx->psoc,
16289 					       wlan_hdd_send_mode_change_event);
16290 	if (!QDF_IS_STATUS_SUCCESS(status)) {
16291 		hdd_debug("Failed to register mode change cb with Policy Manager");
16292 		goto cds_disable;
16293 	}
16294 
16295 	if (hdd_green_ap_enable_egap(hdd_ctx))
16296 		hdd_debug("enhance green ap is not enabled");
16297 
16298 	hdd_register_green_ap_callback(hdd_ctx->pdev);
16299 
16300 	if (0 != wlan_hdd_set_wow_pulse(hdd_ctx, true))
16301 		hdd_debug("Failed to set wow pulse");
16302 
16303 	max_index = max_index - index;
16304 	status = mlme_check_index_setparam(
16305 				      setparam + index,
16306 				      wmi_pdev_param_gcmp_support_enable,
16307 				      ucfg_fwol_get_gcmp_enable(hdd_ctx->psoc),
16308 				      next_index++, max_index);
16309 	if (QDF_IS_STATUS_ERROR(status)) {
16310 		hdd_err("failed at wmi_pdev_param_gcmp_support_enable");
16311 		goto out;
16312 	}
16313 
16314 	 auto_power_fail_mode =
16315 		ucfg_pmo_get_auto_power_fail_mode(hdd_ctx->psoc);
16316 	status = mlme_check_index_setparam(
16317 				      setparam + index,
16318 				      wmi_pdev_auto_detect_power_failure,
16319 				      auto_power_fail_mode,
16320 				      next_index++, max_index);
16321 	if (QDF_IS_STATUS_ERROR(status)) {
16322 		hdd_err("failed at wmi_pdev_auto_detect_power_failure");
16323 		goto out;
16324 	}
16325 
16326 	status = ucfg_get_enable_phy_reg_retention(hdd_ctx->psoc,
16327 						   &enable_phy_reg_retention);
16328 
16329 	if (QDF_IS_STATUS_ERROR(status))
16330 		return -EINVAL;
16331 
16332 	if (enable_phy_reg_retention) {
16333 		status = mlme_check_index_setparam(
16334 					setparam + index,
16335 					wmi_pdev_param_fast_pwr_transition,
16336 					enable_phy_reg_retention,
16337 					next_index++, max_index);
16338 		if (QDF_IS_STATUS_ERROR(status)) {
16339 			hdd_err("failed at wmi_pdev_param_fast_pwr_transition");
16340 			goto out;
16341 		}
16342 	}
16343 	/*Send remaining pdev setparams from array*/
16344 	status = sme_send_multi_pdev_vdev_set_params(MLME_PDEV_SETPARAM,
16345 						     WMI_PDEV_ID_SOC,
16346 						     setparam + index,
16347 						     next_index);
16348 	if (QDF_IS_STATUS_ERROR(status)) {
16349 		hdd_err("failed to send 2nd set of pdev set params");
16350 		goto out;
16351 	}
16352 
16353 	hdd_hastings_bt_war_initialize(hdd_ctx);
16354 
16355 	wlan_hdd_hang_event_notifier_register(hdd_ctx);
16356 	return 0;
16357 
16358 cds_disable:
16359 	cds_disable(hdd_ctx->psoc);
16360 
16361 out:
16362 	return -EINVAL;
16363 }
16364 
16365 #ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
16366 static void hdd_deregister_policy_manager_callback(
16367 			struct wlan_objmgr_psoc *psoc)
16368 {
16369 	if (QDF_STATUS_SUCCESS !=
16370 	    policy_mgr_deregister_hdd_cb(psoc)) {
16371 		hdd_err("HDD callback deregister with policy manager failed");
16372 	}
16373 }
16374 #else
16375 static void hdd_deregister_policy_manager_callback(
16376 			struct wlan_objmgr_psoc *psoc)
16377 {
16378 }
16379 #endif
16380 
16381 int hdd_wlan_stop_modules(struct hdd_context *hdd_ctx, bool ftm_mode)
16382 {
16383 	void *hif_ctx;
16384 	qdf_device_t qdf_ctx;
16385 	QDF_STATUS qdf_status;
16386 	bool is_recovery_stop = cds_is_driver_recovering();
16387 	int ret = 0;
16388 	int debugfs_threads;
16389 	struct target_psoc_info *tgt_hdl;
16390 	struct bbm_params param = {0};
16391 
16392 	hdd_enter();
16393 	qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
16394 	if (!qdf_ctx)
16395 		return -EINVAL;
16396 
16397 	cds_set_driver_state_module_stop(true);
16398 
16399 	debugfs_threads = hdd_return_debugfs_threads_count();
16400 
16401 	if (debugfs_threads > 0 || hdd_ctx->is_wiphy_suspended) {
16402 		hdd_warn("Debugfs threads %d, wiphy suspend %d",
16403 			 debugfs_threads, hdd_ctx->is_wiphy_suspended);
16404 
16405 		if (IS_IDLE_STOP && !ftm_mode) {
16406 			hdd_psoc_idle_timer_start(hdd_ctx);
16407 			cds_set_driver_state_module_stop(false);
16408 
16409 			ucfg_dp_bus_bw_compute_timer_stop(hdd_ctx->psoc);
16410 			return -EAGAIN;
16411 		}
16412 	}
16413 
16414 	ucfg_dp_bus_bw_compute_timer_stop(hdd_ctx->psoc);
16415 	hdd_deregister_policy_manager_callback(hdd_ctx->psoc);
16416 
16417 	/* free user wowl patterns */
16418 	hdd_free_user_wowl_ptrns();
16419 
16420 	switch (hdd_ctx->driver_status) {
16421 	case DRIVER_MODULES_UNINITIALIZED:
16422 		hdd_debug("Modules not initialized just return");
16423 		goto done;
16424 	case DRIVER_MODULES_CLOSED:
16425 		hdd_debug("Modules already closed");
16426 		goto done;
16427 	case DRIVER_MODULES_ENABLED:
16428 		hdd_debug("Wlan transitioning (CLOSED <- ENABLED)");
16429 
16430 		if (hdd_get_conparam() == QDF_GLOBAL_FTM_MODE) {
16431 			hdd_disable_power_management(hdd_ctx);
16432 			break;
16433 		}
16434 
16435 		if (hdd_get_conparam() == QDF_GLOBAL_EPPING_MODE)
16436 			break;
16437 
16438 		hdd_skip_acs_scan_timer_deinit(hdd_ctx);
16439 
16440 		hdd_disable_power_management(hdd_ctx);
16441 
16442 		if (hdd_get_conparam() == QDF_GLOBAL_MISSION_MODE)
16443 			ucfg_dp_direct_link_deinit(hdd_ctx->psoc,
16444 						   is_recovery_stop);
16445 
16446 		if (hdd_deconfigure_cds(hdd_ctx)) {
16447 			hdd_err("Failed to de-configure CDS");
16448 			QDF_ASSERT(0);
16449 			ret = -EINVAL;
16450 		}
16451 		hdd_debug("successfully Disabled the CDS modules!");
16452 
16453 		break;
16454 	default:
16455 		QDF_DEBUG_PANIC("Unknown driver state:%d",
16456 				hdd_ctx->driver_status);
16457 		ret = -EINVAL;
16458 		goto done;
16459 	}
16460 
16461 	hdd_destroy_sysfs_files();
16462 	hdd_debug("Closing CDS modules!");
16463 
16464 	if (hdd_get_conparam() != QDF_GLOBAL_EPPING_MODE) {
16465 		qdf_status = cds_post_disable();
16466 		if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
16467 			hdd_err("Failed to process post CDS disable! :%d",
16468 				qdf_status);
16469 			ret = -EINVAL;
16470 			QDF_ASSERT(0);
16471 		}
16472 
16473 		hdd_unregister_notifiers(hdd_ctx);
16474 		/* De-register the SME callbacks */
16475 		hdd_deregister_cb(hdd_ctx);
16476 
16477 		hdd_runtime_suspend_context_deinit(hdd_ctx);
16478 
16479 		qdf_status = cds_dp_close(hdd_ctx->psoc);
16480 		if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
16481 			hdd_warn("Failed to stop CDS DP: %d", qdf_status);
16482 			ret = -EINVAL;
16483 			QDF_ASSERT(0);
16484 		}
16485 
16486 		hdd_component_pdev_close(hdd_ctx->pdev);
16487 		dispatcher_pdev_close(hdd_ctx->pdev);
16488 		ret = hdd_objmgr_release_and_destroy_pdev(hdd_ctx);
16489 		if (ret) {
16490 			hdd_err("Failed to destroy pdev; errno:%d", ret);
16491 			QDF_ASSERT(0);
16492 		}
16493 
16494 		qdf_status = cds_close(hdd_ctx->psoc);
16495 		if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
16496 			hdd_warn("Failed to stop CDS: %d", qdf_status);
16497 			ret = -EINVAL;
16498 			QDF_ASSERT(0);
16499 		}
16500 
16501 		qdf_status = wbuff_module_deinit();
16502 		if (!QDF_IS_STATUS_SUCCESS(qdf_status))
16503 			hdd_err("WBUFF de-init unsuccessful; status: %d",
16504 				qdf_status);
16505 
16506 		hdd_component_psoc_close(hdd_ctx->psoc);
16507 		/* pdev close and destroy use tx rx ops so call this here */
16508 		wlan_global_lmac_if_close(hdd_ctx->psoc);
16509 	}
16510 
16511 	/*
16512 	 * Reset total mac phy during module stop such that during
16513 	 * next module start same psoc is used to populate new service
16514 	 * ready data
16515 	 */
16516 	tgt_hdl = wlan_psoc_get_tgt_if_handle(hdd_ctx->psoc);
16517 	if (tgt_hdl)
16518 		target_psoc_set_total_mac_phy_cnt(tgt_hdl, 0);
16519 
16520 
16521 	hif_ctx = cds_get_context(QDF_MODULE_ID_HIF);
16522 	if (!hif_ctx)
16523 		ret = -EINVAL;
16524 
16525 	if (hdd_get_conparam() == QDF_GLOBAL_EPPING_MODE) {
16526 		epping_disable();
16527 		epping_close();
16528 	}
16529 
16530 	wlan_connectivity_logging_stop();
16531 
16532 	ucfg_ipa_component_config_free();
16533 
16534 	hdd_hif_close(hdd_ctx, hif_ctx);
16535 
16536 	ol_cds_free();
16537 
16538 	if (IS_IDLE_STOP) {
16539 		ret = pld_power_off(qdf_ctx->dev);
16540 		if (ret)
16541 			hdd_err("Failed to power down device; errno:%d", ret);
16542 	}
16543 
16544 	/* Free the cache channels of the command SET_DISABLE_CHANNEL_LIST */
16545 	wlan_hdd_free_cache_channels(hdd_ctx);
16546 	hdd_driver_mem_cleanup();
16547 
16548 	/* Free the resources allocated while storing SAR config. These needs
16549 	 * to be freed only in the case when it is not SSR. As in the case of
16550 	 * SSR, the values needs to be intact so that it can be restored during
16551 	 * reinit path.
16552 	 */
16553 	if (!is_recovery_stop)
16554 		wlan_hdd_free_sar_config(hdd_ctx);
16555 
16556 	hdd_sap_destroy_ctx_all(hdd_ctx, is_recovery_stop);
16557 	hdd_sta_destroy_ctx_all(hdd_ctx);
16558 
16559 	/*
16560 	 * Reset the driver mode specific bus bw level
16561 	 */
16562 	param.policy = BBM_DRIVER_MODE_POLICY;
16563 	param.policy_info.driver_mode = QDF_GLOBAL_MAX_MODE;
16564 	ucfg_dp_bbm_apply_independent_policy(hdd_ctx->psoc, &param);
16565 
16566 	hdd_deinit_adapter_ops_wq(hdd_ctx);
16567 	hdd_deinit_qdf_ctx(hdd_debug_domain_get());
16568 
16569 	hdd_check_for_leaks(hdd_ctx, is_recovery_stop);
16570 	hdd_debug_domain_set(QDF_DEBUG_DOMAIN_INIT);
16571 	hdd_deinit_qdf_ctx(hdd_debug_domain_get());
16572 	qdf_dma_invalid_buf_list_deinit();
16573 
16574 	/* Restore PS params for monitor mode */
16575 	if (hdd_get_conparam() == QDF_GLOBAL_MONITOR_MODE)
16576 		hdd_restore_all_ps(hdd_ctx);
16577 
16578 	/* Once the firmware sequence is completed reset this flag */
16579 	hdd_ctx->imps_enabled = false;
16580 	hdd_ctx->is_dual_mac_cfg_updated = false;
16581 	hdd_ctx->driver_status = DRIVER_MODULES_CLOSED;
16582 	hdd_ctx->is_fw_dbg_log_levels_configured = false;
16583 	hdd_debug("Wlan transitioned (now CLOSED)");
16584 
16585 done:
16586 	hdd_exit();
16587 
16588 	return ret;
16589 }
16590 
16591 #ifdef WLAN_FEATURE_MEMDUMP_ENABLE
16592 /**
16593  * hdd_state_info_dump() - prints state information of hdd layer
16594  * @buf_ptr: buffer pointer
16595  * @size: size of buffer to be filled
16596  *
16597  * This function is used to dump state information of hdd layer
16598  *
16599  * Return: None
16600  */
16601 static void hdd_state_info_dump(char **buf_ptr, uint16_t *size)
16602 {
16603 	struct hdd_context *hdd_ctx;
16604 	struct hdd_station_ctx *sta_ctx;
16605 	struct hdd_adapter *adapter, *next_adapter = NULL;
16606 	uint16_t len = 0;
16607 	char *buf = *buf_ptr;
16608 	wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_STATE_INFO_DUMP;
16609 	struct wlan_hdd_link_info *link_info;
16610 
16611 	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
16612 	if (!hdd_ctx)
16613 		return;
16614 
16615 	hdd_debug("size of buffer: %d", *size);
16616 
16617 	len += scnprintf(buf + len, *size - len, "\n is_wiphy_suspended %d",
16618 			 hdd_ctx->is_wiphy_suspended);
16619 	len += scnprintf(buf + len, *size - len, "\n is_scheduler_suspended %d",
16620 			 hdd_ctx->is_scheduler_suspended);
16621 
16622 	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
16623 					   dbgid) {
16624 		hdd_adapter_for_each_active_link_info(adapter, link_info) {
16625 			len +=
16626 			scnprintf(buf + len, *size - len, "\n device name: %s",
16627 				  adapter->dev->name);
16628 			len +=
16629 			scnprintf(buf + len, *size - len, "\n device_mode: %d",
16630 				  adapter->device_mode);
16631 			switch (adapter->device_mode) {
16632 			case QDF_STA_MODE:
16633 			case QDF_P2P_CLIENT_MODE:
16634 				sta_ctx =
16635 					WLAN_HDD_GET_STATION_CTX_PTR(link_info);
16636 				len += scnprintf(buf + len, *size - len,
16637 					"\n conn_state: %d",
16638 					sta_ctx->conn_info.conn_state);
16639 				break;
16640 			default:
16641 				break;
16642 			}
16643 		}
16644 		hdd_adapter_dev_put_debug(adapter, dbgid);
16645 	}
16646 
16647 	*size -= len;
16648 	*buf_ptr += len;
16649 }
16650 
16651 /**
16652  * hdd_register_debug_callback() - registration function for hdd layer
16653  * to print hdd state information
16654  *
16655  * Return: None
16656  */
16657 static void hdd_register_debug_callback(void)
16658 {
16659 	qdf_register_debug_callback(QDF_MODULE_ID_HDD, &hdd_state_info_dump);
16660 }
16661 #else /* WLAN_FEATURE_MEMDUMP_ENABLE */
16662 static void hdd_register_debug_callback(void)
16663 {
16664 }
16665 #endif /* WLAN_FEATURE_MEMDUMP_ENABLE */
16666 
16667 /*
16668  * wlan_init_bug_report_lock() - Initialize bug report lock
16669  *
16670  * This function is used to create bug report lock
16671  *
16672  * Return: None
16673  */
16674 static void wlan_init_bug_report_lock(void)
16675 {
16676 	struct cds_context *p_cds_context;
16677 
16678 	p_cds_context = cds_get_global_context();
16679 	if (!p_cds_context) {
16680 		hdd_err("cds context is NULL");
16681 		return;
16682 	}
16683 
16684 	qdf_spinlock_create(&p_cds_context->bug_report_lock);
16685 }
16686 
16687 #ifdef DISABLE_CHANNEL_LIST
16688 static QDF_STATUS wlan_hdd_cache_chann_mutex_create(struct hdd_context *hdd_ctx)
16689 {
16690 	return qdf_mutex_create(&hdd_ctx->cache_channel_lock);
16691 }
16692 #else
16693 static QDF_STATUS wlan_hdd_cache_chann_mutex_create(struct hdd_context *hdd_ctx)
16694 {
16695 	return QDF_STATUS_SUCCESS;
16696 }
16697 #endif
16698 
16699 QDF_STATUS hdd_open_adapter_no_trans(struct hdd_context *hdd_ctx,
16700 				     enum QDF_OPMODE op_mode,
16701 				     const char *iface_name,
16702 				     uint8_t *mac_addr_bytes,
16703 				     struct hdd_adapter_create_param *params)
16704 {
16705 	struct osif_vdev_sync *vdev_sync;
16706 	struct hdd_adapter *adapter;
16707 	QDF_STATUS status;
16708 	int errno;
16709 
16710 	QDF_BUG(rtnl_is_locked());
16711 
16712 	errno = osif_vdev_sync_create(hdd_ctx->parent_dev, &vdev_sync);
16713 	if (errno)
16714 		return qdf_status_from_os_return(errno);
16715 
16716 	adapter = hdd_open_adapter(hdd_ctx, op_mode, iface_name,
16717 				   mac_addr_bytes, NET_NAME_UNKNOWN, true,
16718 				   params);
16719 	if (!adapter) {
16720 		status = QDF_STATUS_E_INVAL;
16721 		goto destroy_sync;
16722 	}
16723 
16724 	osif_vdev_sync_register(adapter->dev, vdev_sync);
16725 
16726 	return QDF_STATUS_SUCCESS;
16727 
16728 destroy_sync:
16729 	osif_vdev_sync_destroy(vdev_sync);
16730 
16731 	return status;
16732 }
16733 
16734 #ifdef WLAN_OPEN_P2P_INTERFACE
16735 /**
16736  * hdd_open_p2p_interface - Open P2P interface
16737  * @hdd_ctx: HDD context
16738  *
16739  * Return: QDF_STATUS
16740  */
16741 static QDF_STATUS hdd_open_p2p_interface(struct hdd_context *hdd_ctx)
16742 {
16743 	QDF_STATUS status;
16744 	bool p2p_dev_addr_admin;
16745 	bool is_p2p_locally_administered = false;
16746 	struct hdd_adapter_create_param params = {0};
16747 
16748 	cfg_p2p_get_device_addr_admin(hdd_ctx->psoc, &p2p_dev_addr_admin);
16749 
16750 	if (p2p_dev_addr_admin) {
16751 		if (hdd_ctx->num_provisioned_addr &&
16752 		    !(hdd_ctx->provisioned_mac_addr[0].bytes[0] & 0x02)) {
16753 			hdd_ctx->p2p_device_address =
16754 					hdd_ctx->provisioned_mac_addr[0];
16755 
16756 			/*
16757 			 * Generate the P2P Device Address.  This consists of
16758 			 * the device's primary MAC address with the locally
16759 			 * administered bit set.
16760 			 */
16761 
16762 			hdd_ctx->p2p_device_address.bytes[0] |= 0x02;
16763 			is_p2p_locally_administered = true;
16764 		} else if (!(hdd_ctx->derived_mac_addr[0].bytes[0] & 0x02)) {
16765 			hdd_ctx->p2p_device_address =
16766 						hdd_ctx->derived_mac_addr[0];
16767 			/*
16768 			 * Generate the P2P Device Address.  This consists of
16769 			 * the device's primary MAC address with the locally
16770 			 * administered bit set.
16771 			 */
16772 			hdd_ctx->p2p_device_address.bytes[0] |= 0x02;
16773 			is_p2p_locally_administered = true;
16774 		}
16775 	}
16776 	if (!is_p2p_locally_administered) {
16777 		uint8_t *p2p_dev_addr;
16778 
16779 		p2p_dev_addr = wlan_hdd_get_intf_addr(hdd_ctx,
16780 						      QDF_P2P_DEVICE_MODE);
16781 		if (!p2p_dev_addr) {
16782 			hdd_err("Failed to get MAC address for new p2p device");
16783 			return QDF_STATUS_E_INVAL;
16784 		}
16785 
16786 		qdf_mem_copy(hdd_ctx->p2p_device_address.bytes,
16787 			     p2p_dev_addr, QDF_MAC_ADDR_SIZE);
16788 	}
16789 
16790 	status = hdd_open_adapter_no_trans(hdd_ctx, QDF_P2P_DEVICE_MODE,
16791 					   "p2p%d",
16792 					   hdd_ctx->p2p_device_address.bytes,
16793 					   &params);
16794 	if (QDF_IS_STATUS_ERROR(status)) {
16795 		if (!is_p2p_locally_administered)
16796 			wlan_hdd_release_intf_addr(hdd_ctx,
16797 					hdd_ctx->p2p_device_address.bytes);
16798 		hdd_err("Failed to open p2p interface");
16799 		return QDF_STATUS_E_INVAL;
16800 	}
16801 
16802 	return QDF_STATUS_SUCCESS;
16803 }
16804 #else
16805 static inline QDF_STATUS hdd_open_p2p_interface(struct hdd_context *hdd_ctx)
16806 {
16807 	return QDF_STATUS_SUCCESS;
16808 }
16809 #endif
16810 
16811 static QDF_STATUS hdd_open_ocb_interface(struct hdd_context *hdd_ctx)
16812 {
16813 	QDF_STATUS status;
16814 	uint8_t *mac_addr;
16815 	struct hdd_adapter_create_param params = {0};
16816 
16817 	mac_addr = wlan_hdd_get_intf_addr(hdd_ctx, QDF_OCB_MODE);
16818 	if (!mac_addr)
16819 		return QDF_STATUS_E_INVAL;
16820 
16821 	status = hdd_open_adapter_no_trans(hdd_ctx, QDF_OCB_MODE,
16822 					   "wlanocb%d", mac_addr,
16823 					   &params);
16824 	if (QDF_IS_STATUS_ERROR(status)) {
16825 		wlan_hdd_release_intf_addr(hdd_ctx, mac_addr);
16826 		hdd_err("Failed to open 802.11p interface");
16827 	}
16828 
16829 	return status;
16830 }
16831 
16832 static QDF_STATUS hdd_open_concurrent_interface(struct hdd_context *hdd_ctx)
16833 {
16834 	QDF_STATUS status;
16835 	const char *iface_name;
16836 	uint8_t *mac_addr;
16837 	struct hdd_adapter_create_param params = {0};
16838 
16839 	if (qdf_str_eq(hdd_ctx->config->enable_concurrent_sta, ""))
16840 		return QDF_STATUS_SUCCESS;
16841 
16842 	iface_name = hdd_ctx->config->enable_concurrent_sta;
16843 	mac_addr = wlan_hdd_get_intf_addr(hdd_ctx, QDF_STA_MODE);
16844 	if (!mac_addr)
16845 		return QDF_STATUS_E_INVAL;
16846 
16847 	status = hdd_open_adapter_no_trans(hdd_ctx, QDF_STA_MODE,
16848 					   iface_name, mac_addr,
16849 					   &params);
16850 	if (QDF_IS_STATUS_ERROR(status)) {
16851 		wlan_hdd_release_intf_addr(hdd_ctx, mac_addr);
16852 		hdd_err("Failed to open concurrent station interface");
16853 	}
16854 
16855 	return status;
16856 }
16857 
16858 #ifdef WLAN_HDD_MULTI_VDEV_SINGLE_NDEV
16859 static inline void
16860 hdd_adapter_open_set_max_active_links(struct hdd_adapter_create_param *params)
16861 {
16862 	if (params->is_add_virtual_iface || !params->is_ml_adapter)
16863 		params->num_sessions = 1;
16864 	else
16865 		params->num_sessions = 2;
16866 }
16867 #else
16868 static inline void
16869 hdd_adapter_open_set_max_active_links(struct hdd_adapter_create_param *params)
16870 {
16871 	params->num_sessions = 1;
16872 }
16873 #endif
16874 
16875 static QDF_STATUS
16876 hdd_open_adapters_for_mission_mode(struct hdd_context *hdd_ctx)
16877 {
16878 	enum dot11p_mode dot11p_mode;
16879 	QDF_STATUS status;
16880 	uint8_t *mac_addr;
16881 	struct hdd_adapter_create_param params = {0};
16882 	bool eht_capab = 0;
16883 
16884 	ucfg_mlme_get_dot11p_mode(hdd_ctx->psoc, &dot11p_mode);
16885 	ucfg_psoc_mlme_get_11be_capab(hdd_ctx->psoc, &eht_capab);
16886 
16887 	/* Create only 802.11p interface? */
16888 	if (dot11p_mode == CFG_11P_STANDALONE)
16889 		return hdd_open_ocb_interface(hdd_ctx);
16890 
16891 	mac_addr = wlan_hdd_get_intf_addr(hdd_ctx, QDF_STA_MODE);
16892 	if (!mac_addr)
16893 		return QDF_STATUS_E_INVAL;
16894 
16895 	if (eht_capab) {
16896 		params.is_ml_adapter = true;
16897 		hdd_adapter_open_set_max_active_links(&params);
16898 	}
16899 
16900 	status = hdd_open_adapter_no_trans(hdd_ctx, QDF_STA_MODE,
16901 					   "wlan%d", mac_addr,
16902 					   &params);
16903 	if (QDF_IS_STATUS_ERROR(status)) {
16904 		wlan_hdd_release_intf_addr(hdd_ctx, mac_addr);
16905 		return status;
16906 	}
16907 
16908 	/* opening concurrent STA is best effort, continue on error */
16909 	hdd_open_concurrent_interface(hdd_ctx);
16910 
16911 	status = hdd_open_p2p_interface(hdd_ctx);
16912 	if (status)
16913 		goto err_close_adapters;
16914 
16915 	/*
16916 	 * Create separate interface (wifi-aware0) for NAN. All NAN commands
16917 	 * should go on this new interface.
16918 	 */
16919 	if (wlan_hdd_is_vdev_creation_allowed(hdd_ctx->psoc)) {
16920 		qdf_mem_zero(&params, sizeof(params));
16921 		mac_addr = wlan_hdd_get_intf_addr(hdd_ctx, QDF_NAN_DISC_MODE);
16922 		if (!mac_addr)
16923 			goto err_close_adapters;
16924 
16925 		status = hdd_open_adapter_no_trans(hdd_ctx, QDF_NAN_DISC_MODE,
16926 						   "wifi-aware%d", mac_addr,
16927 						   &params);
16928 		if (status) {
16929 			wlan_hdd_release_intf_addr(hdd_ctx, mac_addr);
16930 			goto err_close_adapters;
16931 		}
16932 	}
16933 	/* Open 802.11p Interface */
16934 	if (dot11p_mode == CFG_11P_CONCURRENT) {
16935 		status = hdd_open_ocb_interface(hdd_ctx);
16936 		if (QDF_IS_STATUS_ERROR(status))
16937 			goto err_close_adapters;
16938 	}
16939 
16940 	if (eht_capab)
16941 		hdd_wlan_register_mlo_interfaces(hdd_ctx);
16942 
16943 	return QDF_STATUS_SUCCESS;
16944 
16945 err_close_adapters:
16946 	hdd_close_all_adapters(hdd_ctx, true);
16947 
16948 	return status;
16949 }
16950 
16951 static QDF_STATUS hdd_open_adapters_for_ftm_mode(struct hdd_context *hdd_ctx)
16952 {
16953 	QDF_STATUS status;
16954 	uint8_t *mac_addr;
16955 	struct hdd_adapter_create_param params = {0};
16956 
16957 	mac_addr = wlan_hdd_get_intf_addr(hdd_ctx, QDF_FTM_MODE);
16958 	if (!mac_addr)
16959 		return QDF_STATUS_E_INVAL;
16960 
16961 	status = hdd_open_adapter_no_trans(hdd_ctx, QDF_FTM_MODE,
16962 					   "wlan%d", mac_addr,
16963 					   &params);
16964 	if (QDF_IS_STATUS_ERROR(status)) {
16965 		wlan_hdd_release_intf_addr(hdd_ctx, mac_addr);
16966 		return status;
16967 	}
16968 
16969 	return QDF_STATUS_SUCCESS;
16970 }
16971 
16972 static QDF_STATUS
16973 hdd_open_adapters_for_monitor_mode(struct hdd_context *hdd_ctx)
16974 {
16975 	QDF_STATUS status;
16976 	uint8_t *mac_addr;
16977 	struct hdd_adapter_create_param params = {0};
16978 
16979 	mac_addr = wlan_hdd_get_intf_addr(hdd_ctx, QDF_MONITOR_MODE);
16980 	if (!mac_addr)
16981 		return QDF_STATUS_E_INVAL;
16982 
16983 	status = hdd_open_adapter_no_trans(hdd_ctx, QDF_MONITOR_MODE,
16984 					   "wlan%d", mac_addr,
16985 					   &params);
16986 	if (QDF_IS_STATUS_ERROR(status)) {
16987 		wlan_hdd_release_intf_addr(hdd_ctx, mac_addr);
16988 		return status;
16989 	}
16990 
16991 	return QDF_STATUS_SUCCESS;
16992 }
16993 
16994 static QDF_STATUS hdd_open_adapters_for_epping_mode(struct hdd_context *hdd_ctx)
16995 {
16996 	epping_enable_adapter();
16997 	return QDF_STATUS_SUCCESS;
16998 }
16999 
17000 typedef QDF_STATUS (*hdd_open_mode_handler)(struct hdd_context *hdd_ctx);
17001 
17002 static const hdd_open_mode_handler
17003 hdd_open_mode_handlers[QDF_GLOBAL_MAX_MODE] = {
17004 	[QDF_GLOBAL_MISSION_MODE] = hdd_open_adapters_for_mission_mode,
17005 	[QDF_GLOBAL_FTM_MODE] = hdd_open_adapters_for_ftm_mode,
17006 	[QDF_GLOBAL_MONITOR_MODE] = hdd_open_adapters_for_monitor_mode,
17007 	[QDF_GLOBAL_EPPING_MODE] = hdd_open_adapters_for_epping_mode,
17008 };
17009 
17010 static QDF_STATUS hdd_open_adapters_for_mode(struct hdd_context *hdd_ctx,
17011 					     enum QDF_GLOBAL_MODE driver_mode)
17012 {
17013 	QDF_STATUS status;
17014 
17015 	if (driver_mode < 0 ||
17016 	    driver_mode >= QDF_GLOBAL_MAX_MODE ||
17017 	    !hdd_open_mode_handlers[driver_mode]) {
17018 		hdd_err("Driver mode %d not supported", driver_mode);
17019 		return -ENOTSUPP;
17020 	}
17021 
17022 	hdd_hold_rtnl_lock();
17023 	status = hdd_open_mode_handlers[driver_mode](hdd_ctx);
17024 	hdd_release_rtnl_lock();
17025 
17026 	return status;
17027 }
17028 
17029 int hdd_wlan_startup(struct hdd_context *hdd_ctx)
17030 {
17031 	QDF_STATUS status;
17032 	int errno;
17033 	bool is_imps_enabled;
17034 
17035 	hdd_enter();
17036 
17037 	qdf_nbuf_init_replenish_timer();
17038 
17039 	status = wlan_hdd_cache_chann_mutex_create(hdd_ctx);
17040 	if (QDF_IS_STATUS_ERROR(status))
17041 		return qdf_status_to_os_return(status);
17042 
17043 #ifdef FEATURE_WLAN_CH_AVOID
17044 	mutex_init(&hdd_ctx->avoid_freq_lock);
17045 #endif
17046 
17047 	osif_request_manager_init();
17048 	hdd_driver_memdump_init();
17049 
17050 	errno = hdd_init_regulatory_update_event(hdd_ctx);
17051 	if (errno) {
17052 		hdd_err("Failed to initialize regulatory update event; errno:%d",
17053 			errno);
17054 		goto memdump_deinit;
17055 	}
17056 
17057 	errno = hdd_wlan_start_modules(hdd_ctx, false);
17058 	if (errno) {
17059 		hdd_err("Failed to start modules; errno:%d", errno);
17060 		goto memdump_deinit;
17061 	}
17062 
17063 	if (hdd_get_conparam() == QDF_GLOBAL_EPPING_MODE)
17064 		return 0;
17065 
17066 	wlan_hdd_update_wiphy(hdd_ctx);
17067 
17068 	hdd_ctx->mac_handle = cds_get_context(QDF_MODULE_ID_SME);
17069 	if (!hdd_ctx->mac_handle)
17070 		goto stop_modules;
17071 
17072 	errno = hdd_wiphy_init(hdd_ctx);
17073 	if (errno) {
17074 		hdd_err("Failed to initialize wiphy; errno:%d", errno);
17075 		goto stop_modules;
17076 	}
17077 
17078 	errno = hdd_initialize_mac_address(hdd_ctx);
17079 	if (errno) {
17080 		hdd_err("MAC initializtion failed: %d", errno);
17081 		goto unregister_wiphy;
17082 	}
17083 
17084 	errno = register_netdevice_notifier(&hdd_netdev_notifier);
17085 	if (errno) {
17086 		hdd_err("register_netdevice_notifier failed; errno:%d", errno);
17087 		goto unregister_wiphy;
17088 	}
17089 
17090 	wlan_hdd_update_11n_mode(hdd_ctx);
17091 
17092 	hdd_lpass_notify_wlan_version(hdd_ctx);
17093 
17094 	status = wlansap_global_init();
17095 	if (QDF_IS_STATUS_ERROR(status))
17096 		goto unregister_notifiers;
17097 
17098 	ucfg_mlme_is_imps_enabled(hdd_ctx->psoc, &is_imps_enabled);
17099 	hdd_set_idle_ps_config(hdd_ctx, is_imps_enabled);
17100 	hdd_debugfs_mws_coex_info_init(hdd_ctx);
17101 	hdd_debugfs_ini_config_init(hdd_ctx);
17102 	wlan_hdd_debugfs_unit_test_host_create(hdd_ctx);
17103 	wlan_hdd_create_mib_stats_lock();
17104 	wlan_cfg80211_init_interop_issues_ap(hdd_ctx->pdev);
17105 
17106 	hdd_exit();
17107 
17108 	return 0;
17109 
17110 unregister_notifiers:
17111 	unregister_netdevice_notifier(&hdd_netdev_notifier);
17112 
17113 unregister_wiphy:
17114 	qdf_dp_trace_deinit();
17115 	wiphy_unregister(hdd_ctx->wiphy);
17116 
17117 stop_modules:
17118 	hdd_wlan_stop_modules(hdd_ctx, false);
17119 
17120 memdump_deinit:
17121 	hdd_driver_memdump_deinit();
17122 	osif_request_manager_deinit();
17123 	qdf_nbuf_deinit_replenish_timer();
17124 
17125 	if (cds_is_fw_down())
17126 		hdd_err("Not setting the complete event as fw is down");
17127 	else
17128 		hdd_start_complete(errno);
17129 
17130 	hdd_exit();
17131 
17132 	return errno;
17133 }
17134 
17135 QDF_STATUS hdd_psoc_create_vdevs(struct hdd_context *hdd_ctx)
17136 {
17137 	enum QDF_GLOBAL_MODE driver_mode = hdd_get_conparam();
17138 	QDF_STATUS status;
17139 
17140 	status = hdd_open_adapters_for_mode(hdd_ctx, driver_mode);
17141 	if (QDF_IS_STATUS_ERROR(status)) {
17142 		hdd_err("Failed to create vdevs; status:%d", status);
17143 		return status;
17144 	}
17145 
17146 	ucfg_dp_try_set_rps_cpu_mask(hdd_ctx->psoc);
17147 
17148 	if (driver_mode != QDF_GLOBAL_FTM_MODE &&
17149 	    driver_mode != QDF_GLOBAL_EPPING_MODE)
17150 		hdd_psoc_idle_timer_start(hdd_ctx);
17151 
17152 	return QDF_STATUS_SUCCESS;
17153 }
17154 
17155 /**
17156  * hdd_wlan_update_target_info() - update target type info
17157  * @hdd_ctx: HDD context
17158  * @context: hif context
17159  *
17160  * Update target info received from firmware in hdd context
17161  * Return:None
17162  */
17163 
17164 void hdd_wlan_update_target_info(struct hdd_context *hdd_ctx, void *context)
17165 {
17166 	struct hif_target_info *tgt_info = hif_get_target_info_handle(context);
17167 
17168 	if (!tgt_info) {
17169 		hdd_err("Target info is Null");
17170 		return;
17171 	}
17172 
17173 	hdd_ctx->target_type = tgt_info->target_type;
17174 }
17175 
17176 #ifdef WLAN_FEATURE_MOTION_DETECTION
17177 /**
17178  * hdd_md_host_evt_cb - Callback for Motion Detection Event
17179  * @ctx: HDD context
17180  * @event: motion detect event
17181  *
17182  * Callback for Motion Detection Event. Re-enables Motion
17183  * Detection again upon event
17184  *
17185  * Return: QDF_STATUS QDF_STATUS_SUCCESS on Success and
17186  * QDF_STATUS_E_FAILURE on failure
17187  */
17188 QDF_STATUS hdd_md_host_evt_cb(void *ctx, struct sir_md_evt *event)
17189 {
17190 	struct hdd_adapter *adapter;
17191 	struct hdd_context *hdd_ctx;
17192 	struct sme_motion_det_en motion_det;
17193 	struct wlan_hdd_link_info *link_info;
17194 
17195 	if (!ctx || !event)
17196 		return QDF_STATUS_E_INVAL;
17197 
17198 	hdd_ctx = (struct hdd_context *)ctx;
17199 	if (wlan_hdd_validate_context(hdd_ctx))
17200 		return QDF_STATUS_E_INVAL;
17201 
17202 	link_info = hdd_get_link_info_by_vdev(hdd_ctx, event->vdev_id);
17203 	if (!link_info ||
17204 	    WLAN_HDD_ADAPTER_MAGIC != link_info->adapter->magic) {
17205 		hdd_err("Invalid adapter or adapter has invalid magic");
17206 		return QDF_STATUS_E_INVAL;
17207 	}
17208 
17209 	adapter = link_info->adapter;
17210 	/* When motion is detected, reset the motion_det_in_progress flag */
17211 	if (event->status)
17212 		adapter->motion_det_in_progress = false;
17213 
17214 	hdd_debug("Motion Detection CB vdev_id=%u, status=%u",
17215 		  event->vdev_id, event->status);
17216 
17217 	if (adapter->motion_detection_mode) {
17218 		motion_det.vdev_id = event->vdev_id;
17219 		motion_det.enable = 1;
17220 		hdd_debug("Motion Detect CB -> Enable Motion Detection again");
17221 		sme_motion_det_enable(hdd_ctx->mac_handle, &motion_det);
17222 	}
17223 
17224 	return QDF_STATUS_SUCCESS;
17225 }
17226 
17227 /**
17228  * hdd_md_bl_evt_cb - Callback for Motion Detection Baseline Event
17229  * @ctx: HDD context
17230  * @event: motion detect baseline event
17231  *
17232  * Callback for Motion Detection Baseline completion
17233  *
17234  * Return: QDF_STATUS QDF_STATUS_SUCCESS on Success and
17235  * QDF_STATUS_E_FAILURE on failure
17236  */
17237 QDF_STATUS hdd_md_bl_evt_cb(void *ctx, struct sir_md_bl_evt *event)
17238 {
17239 	struct hdd_context *hdd_ctx;
17240 	struct wlan_hdd_link_info *link_info;
17241 
17242 	if (!ctx || !event)
17243 		return QDF_STATUS_E_INVAL;
17244 
17245 	hdd_ctx = (struct hdd_context *)ctx;
17246 	if (wlan_hdd_validate_context(hdd_ctx))
17247 		return QDF_STATUS_E_INVAL;
17248 
17249 	link_info = hdd_get_link_info_by_vdev(hdd_ctx, event->vdev_id);
17250 	if (!link_info ||
17251 	    WLAN_HDD_ADAPTER_MAGIC != link_info->adapter->magic) {
17252 		hdd_err("Invalid adapter or adapter has invalid magic");
17253 		return QDF_STATUS_E_INVAL;
17254 	}
17255 
17256 	hdd_debug("Motion Detection Baseline CB vdev id=%u, baseline val = %d",
17257 		  event->vdev_id, event->bl_baseline_value);
17258 
17259 	link_info->adapter->motion_det_baseline_value =
17260 						event->bl_baseline_value;
17261 
17262 	return QDF_STATUS_SUCCESS;
17263 }
17264 #endif /* WLAN_FEATURE_MOTION_DETECTION */
17265 
17266 /**
17267  * hdd_ssr_on_pagefault_cb - Callback to trigger SSR because
17268  * of host wake up by firmware with reason pagefault
17269  *
17270  * Return: None
17271  */
17272 static void hdd_ssr_on_pagefault_cb(void)
17273 {
17274 	uint32_t ssr_frequency_on_pagefault;
17275 	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
17276 	qdf_time_t curr_time;
17277 
17278 	hdd_enter();
17279 
17280 	if (!hdd_ctx)
17281 		return;
17282 
17283 	ssr_frequency_on_pagefault =
17284 		ucfg_pmo_get_ssr_frequency_on_pagefault(hdd_ctx->psoc);
17285 
17286 	curr_time = qdf_get_time_of_the_day_ms();
17287 
17288 	if (!hdd_ctx->last_pagefault_ssr_time ||
17289 	    (curr_time - hdd_ctx->last_pagefault_ssr_time) >=
17290 					ssr_frequency_on_pagefault) {
17291 		hdd_info("curr_time %lu last_pagefault_ssr_time %lu ssr_frequency %d",
17292 			 curr_time, hdd_ctx->last_pagefault_ssr_time,
17293 			 ssr_frequency_on_pagefault);
17294 		hdd_ctx->last_pagefault_ssr_time = curr_time;
17295 		cds_trigger_recovery(QDF_HOST_WAKEUP_REASON_PAGEFAULT);
17296 	}
17297 }
17298 
17299 /**
17300  * hdd_register_cb - Register HDD callbacks.
17301  * @hdd_ctx: HDD context
17302  *
17303  * Register the HDD callbacks to CDS/SME.
17304  *
17305  * Return: 0 for success or Error code for failure
17306  */
17307 int hdd_register_cb(struct hdd_context *hdd_ctx)
17308 {
17309 	QDF_STATUS status;
17310 	int ret = 0;
17311 	mac_handle_t mac_handle;
17312 
17313 	hdd_enter();
17314 	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
17315 		hdd_err("in ftm mode, no need to register callbacks");
17316 		return ret;
17317 	}
17318 
17319 	mac_handle = hdd_ctx->mac_handle;
17320 
17321 	sme_register_oem_data_rsp_callback(mac_handle,
17322 					   hdd_send_oem_data_rsp_msg);
17323 
17324 	sme_register_mgmt_frame_ind_callback(mac_handle,
17325 					     hdd_indicate_mgmt_frame);
17326 	sme_set_tsfcb(mac_handle, hdd_get_tsf_cb, hdd_ctx);
17327 	sme_stats_ext_register_callback(mac_handle,
17328 					wlan_hdd_cfg80211_stats_ext_callback);
17329 
17330 	sme_ext_scan_register_callback(mac_handle,
17331 					wlan_hdd_cfg80211_extscan_callback);
17332 	sme_stats_ext2_register_callback(mac_handle,
17333 					wlan_hdd_cfg80211_stats_ext2_callback);
17334 
17335 	sme_multi_client_ll_rsp_register_callback(mac_handle,
17336 					hdd_latency_level_event_handler_cb);
17337 
17338 	sme_set_rssi_threshold_breached_cb(mac_handle,
17339 					   hdd_rssi_threshold_breached);
17340 
17341 	sme_set_link_layer_stats_ind_cb(mac_handle,
17342 				wlan_hdd_cfg80211_link_layer_stats_callback);
17343 
17344 	sme_rso_cmd_status_cb(mac_handle, wlan_hdd_rso_cmd_status_cb);
17345 
17346 	sme_set_link_layer_ext_cb(mac_handle,
17347 			wlan_hdd_cfg80211_link_layer_stats_ext_callback);
17348 	sme_update_hidden_ssid_status_cb(mac_handle,
17349 					 hdd_hidden_ssid_enable_roaming);
17350 
17351 	status = sme_set_lost_link_info_cb(mac_handle,
17352 					   hdd_lost_link_info_cb);
17353 
17354 	wlan_hdd_register_cp_stats_cb(hdd_ctx);
17355 	hdd_dcs_register_cb(hdd_ctx);
17356 
17357 	hdd_thermal_register_callbacks(hdd_ctx);
17358 	/* print error and not block the startup process */
17359 	if (!QDF_IS_STATUS_SUCCESS(status))
17360 		hdd_err("set lost link info callback failed");
17361 
17362 	ret = hdd_register_data_stall_detect_cb();
17363 	if (ret) {
17364 		hdd_err("Register data stall detect detect callback failed.");
17365 		return ret;
17366 	}
17367 
17368 	wlan_hdd_dcc_register_for_dcc_stats_event(hdd_ctx);
17369 
17370 	sme_register_set_connection_info_cb(mac_handle,
17371 					    hdd_set_connection_in_progress,
17372 					    hdd_is_connection_in_progress);
17373 
17374 	status = sme_set_bt_activity_info_cb(mac_handle,
17375 					     hdd_bt_activity_cb);
17376 	if (!QDF_IS_STATUS_SUCCESS(status))
17377 		hdd_err("set bt activity info callback failed");
17378 
17379 	status = sme_register_tx_queue_cb(mac_handle,
17380 					  hdd_tx_queue_cb);
17381 	if (!QDF_IS_STATUS_SUCCESS(status))
17382 		hdd_err("Register tx queue callback failed");
17383 
17384 #ifdef WLAN_FEATURE_MOTION_DETECTION
17385 	sme_set_md_host_evt_cb(mac_handle, hdd_md_host_evt_cb, (void *)hdd_ctx);
17386 	sme_set_md_bl_evt_cb(mac_handle, hdd_md_bl_evt_cb, (void *)hdd_ctx);
17387 #endif /* WLAN_FEATURE_MOTION_DETECTION */
17388 
17389 	mac_register_session_open_close_cb(hdd_ctx->mac_handle,
17390 					   hdd_sme_close_session_callback,
17391 					   hdd_common_roam_callback);
17392 
17393 	sme_set_roam_scan_ch_event_cb(mac_handle, hdd_get_roam_scan_ch_cb);
17394 	status = sme_set_monitor_mode_cb(mac_handle,
17395 					 hdd_sme_monitor_mode_callback);
17396 	if (QDF_IS_STATUS_ERROR(status))
17397 		hdd_err_rl("Register monitor mode callback failed");
17398 
17399 	status = sme_set_beacon_latency_event_cb(mac_handle,
17400 						 hdd_beacon_latency_event_cb);
17401 	if (QDF_IS_STATUS_ERROR(status))
17402 		hdd_err_rl("Register beacon latency event callback failed");
17403 
17404 	sme_async_oem_event_init(mac_handle,
17405 				 hdd_oem_event_async_cb);
17406 
17407 	sme_register_ssr_on_pagefault_cb(mac_handle, hdd_ssr_on_pagefault_cb);
17408 
17409 	hdd_exit();
17410 
17411 	return ret;
17412 }
17413 
17414 /**
17415  * hdd_deregister_cb() - De-Register HDD callbacks.
17416  * @hdd_ctx: HDD context
17417  *
17418  * De-Register the HDD callbacks to CDS/SME.
17419  *
17420  * Return: void
17421  */
17422 void hdd_deregister_cb(struct hdd_context *hdd_ctx)
17423 {
17424 	QDF_STATUS status;
17425 	int ret;
17426 	mac_handle_t mac_handle;
17427 
17428 	hdd_enter();
17429 	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
17430 		hdd_err("in ftm mode, no need to deregister callbacks");
17431 		return;
17432 	}
17433 
17434 	mac_handle = hdd_ctx->mac_handle;
17435 
17436 	sme_deregister_ssr_on_pagefault_cb(mac_handle);
17437 
17438 	sme_async_oem_event_deinit(mac_handle);
17439 
17440 	sme_deregister_tx_queue_cb(mac_handle);
17441 
17442 	sme_reset_link_layer_stats_ind_cb(mac_handle);
17443 	sme_reset_rssi_threshold_breached_cb(mac_handle);
17444 
17445 	sme_stats_ext_deregister_callback(mac_handle);
17446 
17447 	status = sme_reset_tsfcb(mac_handle);
17448 	if (!QDF_IS_STATUS_SUCCESS(status))
17449 		hdd_err("Failed to de-register tsfcb the callback:%d",
17450 			status);
17451 
17452 	ret = hdd_deregister_data_stall_detect_cb();
17453 	if (ret)
17454 		hdd_err("Failed to de-register data stall detect event callback");
17455 	hdd_thermal_unregister_callbacks(hdd_ctx);
17456 	sme_deregister_oem_data_rsp_callback(mac_handle);
17457 	sme_multi_client_ll_rsp_deregister_callback(mac_handle);
17458 
17459 	hdd_exit();
17460 }
17461 
17462 /**
17463  * hdd_softap_sta_deauth() - handle deauth req from HDD
17464  * @adapter: Pointer to the HDD adapter
17465  * @param: Params to the operation
17466  *
17467  * This to take counter measure to handle deauth req from HDD
17468  *
17469  * Return: None
17470  */
17471 QDF_STATUS hdd_softap_sta_deauth(struct hdd_adapter *adapter,
17472 				 struct csr_del_sta_params *param)
17473 {
17474 	QDF_STATUS qdf_status = QDF_STATUS_E_FAULT;
17475 	struct hdd_context *hdd_ctx;
17476 	bool is_sap_bcast_deauth_enabled = false;
17477 
17478 	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
17479 	if (!hdd_ctx) {
17480 		hdd_err("hdd_ctx is NULL");
17481 		return QDF_STATUS_E_INVAL;
17482 	}
17483 
17484 	ucfg_mlme_get_sap_bcast_deauth_enabled(hdd_ctx->psoc,
17485 					       &is_sap_bcast_deauth_enabled);
17486 
17487 	hdd_enter();
17488 
17489 	hdd_debug("sap_bcast_deauth_enabled %d", is_sap_bcast_deauth_enabled);
17490 	/* Ignore request to deauth bcmc station */
17491 	if (!is_sap_bcast_deauth_enabled)
17492 		if (param->peerMacAddr.bytes[0] & 0x1)
17493 			return qdf_status;
17494 
17495 	qdf_status =
17496 		wlansap_deauth_sta(WLAN_HDD_GET_SAP_CTX_PTR(adapter->deflink),
17497 				   param);
17498 
17499 	hdd_exit();
17500 	return qdf_status;
17501 }
17502 
17503 /**
17504  * hdd_softap_sta_disassoc() - take counter measure to handle deauth req from HDD
17505  * @adapter: Pointer to the HDD
17506  * @param: pointer to station deletion parameters
17507  *
17508  * This to take counter measure to handle deauth req from HDD
17509  *
17510  * Return: None
17511  */
17512 void hdd_softap_sta_disassoc(struct hdd_adapter *adapter,
17513 			     struct csr_del_sta_params *param)
17514 {
17515 	hdd_enter();
17516 
17517 	/* Ignore request to disassoc bcmc station */
17518 	if (param->peerMacAddr.bytes[0] & 0x1)
17519 		return;
17520 
17521 	wlansap_disassoc_sta(WLAN_HDD_GET_SAP_CTX_PTR(adapter->deflink),
17522 			     param);
17523 }
17524 
17525 void
17526 wlan_hdd_set_roaming_state(struct wlan_hdd_link_info *cur_link_info,
17527 			   enum wlan_cm_rso_control_requestor rso_op_requestor,
17528 			   bool enab_roam)
17529 {
17530 	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(cur_link_info->adapter);
17531 	struct hdd_adapter *adapter = NULL, *next_adapter = NULL;
17532 	wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_DISABLE_ROAMING;
17533 	uint8_t vdev_id, cur_vdev_id = cur_link_info->vdev_id;
17534 	struct wlan_hdd_link_info *link_info;
17535 
17536 	if (!policy_mgr_is_sta_active_connection_exists(hdd_ctx->psoc))
17537 		return;
17538 
17539 	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
17540 					   dbgid) {
17541 		hdd_adapter_for_each_active_link_info(adapter, link_info) {
17542 			vdev_id = link_info->vdev_id;
17543 			if (cur_vdev_id != link_info->vdev_id &&
17544 			    adapter->device_mode == QDF_STA_MODE &&
17545 			    hdd_cm_is_vdev_associated(link_info)) {
17546 				if (enab_roam) {
17547 					hdd_debug("%d Enable roaming", vdev_id);
17548 					sme_start_roaming(hdd_ctx->mac_handle,
17549 							  vdev_id,
17550 							  REASON_DRIVER_ENABLED,
17551 							  rso_op_requestor);
17552 				} else {
17553 					hdd_debug("%d Disable roaming",
17554 						  vdev_id);
17555 					sme_stop_roaming(hdd_ctx->mac_handle,
17556 							 vdev_id,
17557 							 REASON_DRIVER_DISABLED,
17558 							 rso_op_requestor);
17559 				}
17560 			}
17561 		}
17562 		hdd_adapter_dev_put_debug(adapter, dbgid);
17563 	}
17564 }
17565 
17566 /**
17567  * nl_srv_bcast_svc() - Wrapper function to send bcast msgs to SVC mcast group
17568  * @skb: sk buffer pointer
17569  *
17570  * Sends the bcast message to SVC multicast group with generic nl socket
17571  * if CNSS_GENL is enabled. Else, use the legacy netlink socket to send.
17572  *
17573  * Return: None
17574  */
17575 static void nl_srv_bcast_svc(struct sk_buff *skb)
17576 {
17577 #ifdef CNSS_GENL
17578 	nl_srv_bcast(skb, CLD80211_MCGRP_SVC_MSGS, WLAN_NL_MSG_SVC);
17579 #else
17580 	nl_srv_bcast(skb);
17581 #endif
17582 }
17583 
17584 void wlan_hdd_send_svc_nlink_msg(int radio, int type, void *data, int len)
17585 {
17586 	struct sk_buff *skb;
17587 	struct nlmsghdr *nlh;
17588 	tAniMsgHdr *ani_hdr;
17589 	void *nl_data = NULL;
17590 	int flags = GFP_KERNEL;
17591 	struct radio_index_tlv *radio_info;
17592 	int tlv_len;
17593 
17594 	if (in_interrupt() || irqs_disabled() || in_atomic())
17595 		flags = GFP_ATOMIC;
17596 
17597 	skb = alloc_skb(NLMSG_SPACE(WLAN_NL_MAX_PAYLOAD), flags);
17598 
17599 	if (!skb)
17600 		return;
17601 
17602 	nlh = (struct nlmsghdr *)skb->data;
17603 	nlh->nlmsg_pid = 0;     /* from kernel */
17604 	nlh->nlmsg_flags = 0;
17605 	nlh->nlmsg_seq = 0;
17606 	nlh->nlmsg_type = WLAN_NL_MSG_SVC;
17607 
17608 	ani_hdr = NLMSG_DATA(nlh);
17609 	ani_hdr->type = type;
17610 
17611 	switch (type) {
17612 	case WLAN_SVC_FW_CRASHED_IND:
17613 	case WLAN_SVC_FW_SHUTDOWN_IND:
17614 	case WLAN_SVC_LTE_COEX_IND:
17615 	case WLAN_SVC_WLAN_AUTO_SHUTDOWN_IND:
17616 	case WLAN_SVC_WLAN_AUTO_SHUTDOWN_CANCEL_IND:
17617 		ani_hdr->length = 0;
17618 		nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr)));
17619 		break;
17620 	case WLAN_SVC_WLAN_STATUS_IND:
17621 	case WLAN_SVC_WLAN_VERSION_IND:
17622 	case WLAN_SVC_DFS_CAC_START_IND:
17623 	case WLAN_SVC_DFS_CAC_END_IND:
17624 	case WLAN_SVC_DFS_RADAR_DETECT_IND:
17625 	case WLAN_SVC_DFS_ALL_CHANNEL_UNAVAIL_IND:
17626 	case WLAN_SVC_WLAN_TP_IND:
17627 	case WLAN_SVC_WLAN_TP_TX_IND:
17628 	case WLAN_SVC_RPS_ENABLE_IND:
17629 	case WLAN_SVC_CORE_MINFREQ:
17630 		ani_hdr->length = len;
17631 		nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr) + len));
17632 		nl_data = (char *)ani_hdr + sizeof(tAniMsgHdr);
17633 		memcpy(nl_data, data, len);
17634 		break;
17635 
17636 	default:
17637 		hdd_err("WLAN SVC: Attempt to send unknown nlink message %d",
17638 		       type);
17639 		kfree_skb(skb);
17640 		return;
17641 	}
17642 
17643 	/*
17644 	 * Add radio index at the end of the svc event in TLV format
17645 	 * to maintain the backward compatibility with userspace
17646 	 * applications.
17647 	 */
17648 
17649 	tlv_len = 0;
17650 
17651 	if ((sizeof(*ani_hdr) + len + sizeof(struct radio_index_tlv))
17652 		< WLAN_NL_MAX_PAYLOAD) {
17653 		radio_info  = (struct radio_index_tlv *)((char *) ani_hdr +
17654 		sizeof(*ani_hdr) + len);
17655 		radio_info->type = (unsigned short) WLAN_SVC_WLAN_RADIO_INDEX;
17656 		radio_info->length = (unsigned short) sizeof(radio_info->radio);
17657 		radio_info->radio = radio;
17658 		tlv_len = sizeof(*radio_info);
17659 		hdd_debug("Added radio index tlv - radio index %d",
17660 			  radio_info->radio);
17661 	}
17662 
17663 	nlh->nlmsg_len += tlv_len;
17664 	skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr) + len + tlv_len));
17665 
17666 	nl_srv_bcast_svc(skb);
17667 }
17668 
17669 #ifdef FEATURE_WLAN_AUTO_SHUTDOWN
17670 void wlan_hdd_auto_shutdown_cb(void)
17671 {
17672 	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
17673 
17674 	if (!hdd_ctx)
17675 		return;
17676 
17677 	hdd_debug("Wlan Idle. Sending Shutdown event..");
17678 	wlan_hdd_send_svc_nlink_msg(hdd_ctx->radio_index,
17679 			WLAN_SVC_WLAN_AUTO_SHUTDOWN_IND, NULL, 0);
17680 }
17681 
17682 void wlan_hdd_auto_shutdown_enable(struct hdd_context *hdd_ctx, bool enable)
17683 {
17684 	struct hdd_adapter *adapter, *next_adapter = NULL;
17685 	bool ap_connected = false, sta_connected = false;
17686 	mac_handle_t mac_handle;
17687 	struct wlan_hdd_link_info *link_info;
17688 	struct hdd_ap_ctx *ap_ctx;
17689 	wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_AUTO_SHUTDOWN_ENABLE;
17690 
17691 	mac_handle = hdd_ctx->mac_handle;
17692 	if (!mac_handle)
17693 		return;
17694 
17695 	if (hdd_ctx->config->wlan_auto_shutdown == 0)
17696 		return;
17697 
17698 	if (enable == false) {
17699 		if (sme_set_auto_shutdown_timer(mac_handle, 0) !=
17700 							QDF_STATUS_SUCCESS) {
17701 			hdd_err("Failed to stop wlan auto shutdown timer");
17702 		}
17703 		wlan_hdd_send_svc_nlink_msg(hdd_ctx->radio_index,
17704 			WLAN_SVC_WLAN_AUTO_SHUTDOWN_CANCEL_IND, NULL, 0);
17705 		return;
17706 	}
17707 
17708 	/* To enable shutdown timer check conncurrency */
17709 	if (!policy_mgr_concurrent_open_sessions_running(hdd_ctx->psoc))
17710 		goto start_timer;
17711 
17712 	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter,
17713 					   next_adapter, dbgid) {
17714 		hdd_adapter_for_each_active_link_info(adapter, link_info) {
17715 			if (adapter->device_mode == QDF_STA_MODE &&
17716 			    hdd_cm_is_vdev_associated(link_info)) {
17717 				sta_connected = true;
17718 				hdd_adapter_dev_put_debug(adapter, dbgid);
17719 				if (next_adapter)
17720 					hdd_adapter_dev_put_debug(next_adapter,
17721 								  dbgid);
17722 				break;
17723 			}
17724 
17725 			if (adapter->device_mode == QDF_SAP_MODE) {
17726 				ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(link_info);
17727 				if (ap_ctx->ap_active == true) {
17728 					ap_connected = true;
17729 					hdd_adapter_dev_put_debug(adapter,
17730 								  dbgid);
17731 					if (next_adapter)
17732 						hdd_adapter_dev_put_debug(
17733 								next_adapter,
17734 								dbgid);
17735 					break;
17736 				}
17737 			}
17738 		}
17739 		hdd_adapter_dev_put_debug(adapter, dbgid);
17740 	}
17741 
17742 start_timer:
17743 	if (ap_connected == true || sta_connected == true) {
17744 		hdd_debug("CC Session active. Shutdown timer not enabled");
17745 		return;
17746 	}
17747 
17748 	if (sme_set_auto_shutdown_timer(mac_handle,
17749 					hdd_ctx->config->wlan_auto_shutdown)
17750 	    != QDF_STATUS_SUCCESS)
17751 		hdd_err("Failed to start wlan auto shutdown timer");
17752 	else
17753 		hdd_info("Auto Shutdown timer for %d seconds enabled",
17754 			 hdd_ctx->config->wlan_auto_shutdown);
17755 }
17756 #endif
17757 
17758 struct hdd_adapter *
17759 hdd_get_con_sap_adapter(struct hdd_adapter *this_sap_adapter,
17760 			bool check_start_bss)
17761 {
17762 	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(this_sap_adapter);
17763 	struct hdd_adapter *adapter, *next_adapter = NULL;
17764 	wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_GET_CON_SAP_ADAPTER;
17765 	struct wlan_hdd_link_info *link_info;
17766 
17767 	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
17768 					   dbgid) {
17769 		if ((adapter->device_mode == QDF_SAP_MODE ||
17770 		     adapter->device_mode == QDF_P2P_GO_MODE) &&
17771 		    adapter != this_sap_adapter) {
17772 			hdd_adapter_for_each_active_link_info(adapter,
17773 							      link_info) {
17774 				if (!check_start_bss) {
17775 					hdd_adapter_dev_put_debug(adapter,
17776 								  dbgid);
17777 					if (next_adapter)
17778 						hdd_adapter_dev_put_debug(
17779 								next_adapter,
17780 								dbgid);
17781 					return adapter;
17782 				}
17783 				if (test_bit(SOFTAP_BSS_STARTED,
17784 					     &link_info->link_flags)) {
17785 					hdd_adapter_dev_put_debug(adapter,
17786 								  dbgid);
17787 					if (next_adapter)
17788 						hdd_adapter_dev_put_debug(
17789 								next_adapter,
17790 								dbgid);
17791 					return adapter;
17792 				}
17793 			}
17794 		}
17795 		hdd_adapter_dev_put_debug(adapter, dbgid);
17796 	}
17797 
17798 	return NULL;
17799 }
17800 
17801 static inline bool hdd_adapter_is_sta(struct hdd_adapter *adapter)
17802 {
17803 	return adapter->device_mode == QDF_STA_MODE ||
17804 		adapter->device_mode == QDF_P2P_CLIENT_MODE;
17805 }
17806 
17807 bool hdd_is_any_adapter_connected(struct hdd_context *hdd_ctx)
17808 {
17809 	struct hdd_adapter *adapter, *next_adapter = NULL;
17810 	wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_IS_ANY_ADAPTER_CONNECTED;
17811 	struct wlan_hdd_link_info *link_info;
17812 
17813 	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
17814 					   dbgid) {
17815 		hdd_adapter_for_each_active_link_info(adapter, link_info) {
17816 			if (hdd_adapter_is_sta(adapter) &&
17817 			    hdd_cm_is_vdev_associated(link_info)) {
17818 				hdd_adapter_dev_put_debug(adapter, dbgid);
17819 				if (next_adapter)
17820 					hdd_adapter_dev_put_debug(next_adapter,
17821 								  dbgid);
17822 				return true;
17823 			}
17824 
17825 			if (hdd_adapter_is_ap(adapter) &&
17826 			    WLAN_HDD_GET_AP_CTX_PTR(link_info)->ap_active) {
17827 				hdd_adapter_dev_put_debug(adapter, dbgid);
17828 				if (next_adapter)
17829 					hdd_adapter_dev_put_debug(next_adapter,
17830 								  dbgid);
17831 				return true;
17832 			}
17833 
17834 			if (adapter->device_mode == QDF_NDI_MODE &&
17835 			    hdd_cm_is_vdev_associated(link_info)) {
17836 				hdd_adapter_dev_put_debug(adapter, dbgid);
17837 				if (next_adapter)
17838 					hdd_adapter_dev_put_debug(next_adapter,
17839 								  dbgid);
17840 				return true;
17841 			}
17842 		}
17843 		hdd_adapter_dev_put_debug(adapter, dbgid);
17844 	}
17845 
17846 	return false;
17847 }
17848 
17849 #if defined MSM_PLATFORM && (LINUX_VERSION_CODE <= KERNEL_VERSION(4, 19, 0))
17850 /**
17851  * hdd_inform_stop_sap() - call cfg80211 API to stop SAP
17852  * @adapter: pointer to adapter
17853  *
17854  * This function calls cfg80211 API to stop SAP
17855  *
17856  * Return: None
17857  */
17858 static void hdd_inform_stop_sap(struct hdd_adapter *adapter)
17859 {
17860 	hdd_debug("SAP stopped due to invalid channel vdev id %d",
17861 		  wlan_vdev_get_id(adapter->deflink->vdev));
17862 	cfg80211_ap_stopped(adapter->dev, GFP_KERNEL);
17863 }
17864 
17865 #else
17866 static void hdd_inform_stop_sap(struct hdd_adapter *adapter)
17867 {
17868 	hdd_debug("SAP stopped due to invalid channel vdev id %d",
17869 		  wlan_vdev_get_id(adapter->deflink->vdev));
17870 	cfg80211_stop_iface(adapter->hdd_ctx->wiphy, &adapter->wdev,
17871 			    GFP_KERNEL);
17872 }
17873 #endif
17874 
17875 /**
17876  * wlan_hdd_stop_sap() - This function stops bss of SAP.
17877  * @ap_adapter: SAP adapter
17878  *
17879  * This function will process the stopping of sap adapter.
17880  *
17881  * Return: None
17882  */
17883 void wlan_hdd_stop_sap(struct hdd_adapter *ap_adapter)
17884 {
17885 	struct hdd_ap_ctx *hdd_ap_ctx;
17886 	struct hdd_hostapd_state *hostapd_state;
17887 	QDF_STATUS qdf_status;
17888 	struct hdd_context *hdd_ctx;
17889 
17890 	if (!ap_adapter) {
17891 		hdd_err("ap_adapter is NULL here");
17892 		return;
17893 	}
17894 
17895 	hdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(ap_adapter->deflink);
17896 	hdd_ctx = WLAN_HDD_GET_CTX(ap_adapter);
17897 	if (wlan_hdd_validate_context(hdd_ctx))
17898 		return;
17899 
17900 	mutex_lock(&hdd_ctx->sap_lock);
17901 	if (test_bit(SOFTAP_BSS_STARTED, &ap_adapter->deflink->link_flags)) {
17902 		wlan_hdd_del_station(ap_adapter, NULL);
17903 		hostapd_state =
17904 			WLAN_HDD_GET_HOSTAP_STATE_PTR(ap_adapter->deflink);
17905 		hdd_debug("Now doing SAP STOPBSS");
17906 		qdf_event_reset(&hostapd_state->qdf_stop_bss_event);
17907 		if (QDF_STATUS_SUCCESS == wlansap_stop_bss(hdd_ap_ctx->
17908 							sap_context)) {
17909 			qdf_status = qdf_wait_single_event(&hostapd_state->
17910 					qdf_stop_bss_event,
17911 					SME_CMD_STOP_BSS_TIMEOUT);
17912 			if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
17913 				mutex_unlock(&hdd_ctx->sap_lock);
17914 				hdd_err("SAP Stop Failed");
17915 				return;
17916 			}
17917 		}
17918 		clear_bit(SOFTAP_BSS_STARTED, &ap_adapter->deflink->link_flags);
17919 		policy_mgr_decr_session_set_pcl(hdd_ctx->psoc,
17920 						ap_adapter->device_mode,
17921 						ap_adapter->deflink->vdev_id);
17922 		hdd_green_ap_start_state_mc(hdd_ctx, ap_adapter->device_mode,
17923 					    false);
17924 		hdd_inform_stop_sap(ap_adapter);
17925 		hdd_debug("SAP Stop Success");
17926 	} else {
17927 		hdd_err("Can't stop ap because its not started");
17928 	}
17929 	mutex_unlock(&hdd_ctx->sap_lock);
17930 }
17931 
17932 #if defined(WLAN_FEATURE_11BE_MLO) && defined(CFG80211_11BE_BASIC)
17933 /**
17934  * wlan_hdd_mlo_sap_reinit() - handle mlo scenario for ssr
17935  * @link_info: Pointer of link_info in adapter
17936  *
17937  * Return: QDF_STATUS
17938  */
17939 static QDF_STATUS wlan_hdd_mlo_sap_reinit(struct wlan_hdd_link_info *link_info)
17940 {
17941 	struct hdd_context *hdd_ctx = link_info->adapter->hdd_ctx;
17942 	struct sap_config *config = &link_info->session.ap.sap_config;
17943 
17944 	if (config->mlo_sap) {
17945 		if (!mlo_ap_vdev_attach(link_info->vdev, config->link_id,
17946 					config->num_link)) {
17947 			hdd_err("SAP mlo mgr attach fail");
17948 			return QDF_STATUS_E_INVAL;
17949 		}
17950 	}
17951 
17952 	if (!policy_mgr_is_mlo_sap_concurrency_allowed(hdd_ctx->psoc,
17953 						       config->mlo_sap,
17954 						       wlan_vdev_get_id(link_info->vdev))) {
17955 		hdd_err("MLO SAP concurrency check fails");
17956 		return QDF_STATUS_E_INVAL;
17957 	}
17958 
17959 	return QDF_STATUS_SUCCESS;
17960 }
17961 #else
17962 static inline QDF_STATUS
17963 wlan_hdd_mlo_sap_reinit(struct wlan_hdd_link_info *link_info)
17964 {
17965 	return QDF_STATUS_SUCCESS;
17966 }
17967 #endif
17968 
17969 void wlan_hdd_start_sap(struct wlan_hdd_link_info *link_info, bool reinit)
17970 {
17971 	struct hdd_ap_ctx *ap_ctx;
17972 	struct hdd_hostapd_state *hostapd_state;
17973 	QDF_STATUS qdf_status;
17974 	struct hdd_context *hdd_ctx;
17975 	struct sap_config *sap_config;
17976 	struct hdd_adapter *ap_adapter = link_info->adapter;
17977 
17978 	if (QDF_SAP_MODE != ap_adapter->device_mode) {
17979 		hdd_err("SoftAp role has not been enabled");
17980 		return;
17981 	}
17982 
17983 	hdd_ctx = WLAN_HDD_GET_CTX(ap_adapter);
17984 	ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(link_info);
17985 	hostapd_state = WLAN_HDD_GET_HOSTAP_STATE_PTR(link_info);
17986 	sap_config = &ap_ctx->sap_config;
17987 
17988 	mutex_lock(&hdd_ctx->sap_lock);
17989 	if (test_bit(SOFTAP_BSS_STARTED, &link_info->link_flags))
17990 		goto end;
17991 
17992 	if (wlan_hdd_cfg80211_update_apies(link_info)) {
17993 		hdd_err("SAP Not able to set AP IEs");
17994 		goto end;
17995 	}
17996 	wlan_reg_set_channel_params_for_pwrmode(hdd_ctx->pdev,
17997 						sap_config->chan_freq, 0,
17998 						&sap_config->ch_params,
17999 						REG_CURRENT_PWR_MODE);
18000 	qdf_status = wlan_hdd_mlo_sap_reinit(link_info);
18001 	if (QDF_IS_STATUS_ERROR(qdf_status)) {
18002 		hdd_err("SAP Not able to do mlo attach");
18003 		goto end;
18004 	}
18005 
18006 	qdf_event_reset(&hostapd_state->qdf_event);
18007 	qdf_status = wlansap_start_bss(ap_ctx->sap_context,
18008 				       hdd_hostapd_sap_event_cb, sap_config,
18009 				       ap_adapter->dev);
18010 	if (QDF_IS_STATUS_ERROR(qdf_status))
18011 		goto end;
18012 
18013 	hdd_debug("Waiting for SAP to start");
18014 	qdf_status = qdf_wait_single_event(&hostapd_state->qdf_event,
18015 					SME_CMD_START_BSS_TIMEOUT);
18016 	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
18017 		hdd_err("SAP Start failed");
18018 		goto end;
18019 	}
18020 	hdd_info("SAP Start Success");
18021 
18022 	wlansap_reset_sap_config_add_ie(sap_config, eUPDATE_IE_ALL);
18023 	set_bit(SOFTAP_BSS_STARTED, &link_info->link_flags);
18024 	if (hostapd_state->bss_state == BSS_START) {
18025 		policy_mgr_incr_active_session(hdd_ctx->psoc,
18026 					ap_adapter->device_mode,
18027 					link_info->vdev_id);
18028 		hdd_green_ap_start_state_mc(hdd_ctx, ap_adapter->device_mode,
18029 					    true);
18030 	}
18031 	mutex_unlock(&hdd_ctx->sap_lock);
18032 
18033 	return;
18034 end:
18035 	wlan_hdd_mlo_reset(link_info);
18036 	wlansap_reset_sap_config_add_ie(sap_config, eUPDATE_IE_ALL);
18037 	mutex_unlock(&hdd_ctx->sap_lock);
18038 	/* SAP context and beacon cleanup will happen during driver unload
18039 	 * in hdd_stop_adapter
18040 	 */
18041 	hdd_err("SAP restart after SSR failed! Reload WLAN and try SAP again");
18042 	/* Free the beacon memory in case of failure in the sap restart */
18043 	qdf_mem_free(ap_ctx->beacon);
18044 	ap_ctx->beacon = NULL;
18045 }
18046 
18047 #ifdef QCA_CONFIG_SMP
18048 /**
18049  * wlan_hdd_get_cpu() - get cpu_index
18050  *
18051  * Return: cpu_index
18052  */
18053 int wlan_hdd_get_cpu(void)
18054 {
18055 	int cpu_index = get_cpu();
18056 
18057 	put_cpu();
18058 	return cpu_index;
18059 }
18060 #endif
18061 
18062 /**
18063  * hdd_get_fwpath() - get framework path
18064  *
18065  * This function is used to get the string written by
18066  * userspace to start the wlan driver
18067  *
18068  * Return: string
18069  */
18070 const char *hdd_get_fwpath(void)
18071 {
18072 	return fwpath.string;
18073 }
18074 
18075 static inline int hdd_state_query_cb(void)
18076 {
18077 	return !!wlan_hdd_validate_context(cds_get_context(QDF_MODULE_ID_HDD));
18078 }
18079 
18080 static int __hdd_op_protect_cb(void **out_sync, const char *func)
18081 {
18082 	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
18083 
18084 	if (!hdd_ctx)
18085 		return -EAGAIN;
18086 
18087 	return __osif_psoc_sync_op_start(hdd_ctx->parent_dev,
18088 					 (struct osif_psoc_sync **)out_sync,
18089 					 func);
18090 }
18091 
18092 static void __hdd_op_unprotect_cb(void *sync, const char *func)
18093 {
18094 	__osif_psoc_sync_op_stop(sync, func);
18095 }
18096 
18097 #ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
18098 /**
18099  * hdd_logging_sock_init_svc() - Initialize logging sock
18100  *
18101  * Return: 0 for success, errno on failure
18102  */
18103 static int
18104 hdd_logging_sock_init_svc(void)
18105 {
18106 	return wlan_logging_sock_init_svc();
18107 }
18108 #else
18109 static inline int
18110 hdd_logging_sock_init_svc(void)
18111 {
18112 	return 0;
18113 }
18114 #endif
18115 
18116 /**
18117  * hdd_init() - Initialize Driver
18118  *
18119  * This function initializes CDS global context with the help of cds_init. This
18120  * has to be the first function called after probe to get a valid global
18121  * context.
18122  *
18123  * Return: 0 for success, errno on failure
18124  */
18125 int hdd_init(void)
18126 {
18127 	QDF_STATUS status;
18128 
18129 	status = cds_init();
18130 	if (QDF_IS_STATUS_ERROR(status)) {
18131 		hdd_err("Failed to allocate CDS context");
18132 		return -ENOMEM;
18133 	}
18134 
18135 	qdf_op_callbacks_register(__hdd_op_protect_cb, __hdd_op_unprotect_cb);
18136 
18137 	wlan_init_bug_report_lock();
18138 
18139 	if (hdd_logging_sock_init_svc()) {
18140 		hdd_err("logging sock init failed.");
18141 		goto err;
18142 	}
18143 
18144 	hdd_trace_init();
18145 	hdd_register_debug_callback();
18146 	wlan_roam_debug_init();
18147 
18148 	return 0;
18149 
18150 err:
18151 	wlan_destroy_bug_report_lock();
18152 	qdf_op_callbacks_register(NULL, NULL);
18153 	cds_deinit();
18154 	return -ENOMEM;
18155 }
18156 
18157 /**
18158  * hdd_deinit() - Deinitialize Driver
18159  *
18160  * This function frees CDS global context with the help of cds_deinit. This
18161  * has to be the last function call in remove callback to free the global
18162  * context.
18163  */
18164 void hdd_deinit(void)
18165 {
18166 	wlan_roam_debug_deinit();
18167 
18168 #ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
18169 	wlan_logging_sock_deinit_svc();
18170 #endif
18171 
18172 	wlan_destroy_bug_report_lock();
18173 	qdf_op_callbacks_register(NULL, NULL);
18174 	cds_deinit();
18175 }
18176 
18177 #ifdef QCA_WIFI_EMULATION
18178 #define HDD_WLAN_START_WAIT_TIME ((CDS_WMA_TIMEOUT + 5000) * 100)
18179 #else
18180 #define HDD_WLAN_START_WAIT_TIME (CDS_WMA_TIMEOUT + 5000)
18181 #endif
18182 
18183 void hdd_init_start_completion(void)
18184 {
18185 	INIT_COMPLETION(wlan_start_comp);
18186 }
18187 
18188 #ifdef WLAN_CTRL_NAME
18189 static unsigned int dev_num = 1;
18190 static struct cdev wlan_hdd_state_cdev;
18191 static struct class *class;
18192 static dev_t device;
18193 
18194 static void hdd_set_adapter_wlm_def_level(struct hdd_context *hdd_ctx)
18195 {
18196 	struct hdd_adapter *adapter, *next_adapter = NULL;
18197 	wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_GET_ADAPTER;
18198 	int ret;
18199 	QDF_STATUS qdf_status;
18200 	uint8_t latency_level;
18201 	bool reset;
18202 
18203 	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam())
18204 		return;
18205 
18206 	ret = wlan_hdd_validate_context(hdd_ctx);
18207 	if (ret != 0)
18208 		return;
18209 
18210 	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
18211 					   dbgid) {
18212 		qdf_status = ucfg_mlme_cfg_get_wlm_level(hdd_ctx->psoc,
18213 							 &latency_level);
18214 		if (QDF_IS_STATUS_ERROR(qdf_status))
18215 			adapter->latency_level =
18216 			       QCA_WLAN_VENDOR_ATTR_CONFIG_LATENCY_LEVEL_NORMAL;
18217 		else
18218 			adapter->latency_level = latency_level;
18219 		qdf_status = ucfg_mlme_cfg_get_wlm_reset(hdd_ctx->psoc, &reset);
18220 		if (QDF_IS_STATUS_ERROR(qdf_status)) {
18221 			hdd_err("could not get the wlm reset flag");
18222 			reset = false;
18223 		}
18224 
18225 		if (hdd_get_multi_client_ll_support(adapter) && !reset)
18226 			wlan_hdd_deinit_multi_client_info_table(adapter);
18227 
18228 		adapter->upgrade_udp_qos_threshold = QCA_WLAN_AC_BK;
18229 		hdd_debug("UDP packets qos reset to: %d",
18230 			  adapter->upgrade_udp_qos_threshold);
18231 		hdd_adapter_dev_put_debug(adapter, dbgid);
18232 	}
18233 }
18234 
18235 static int wlan_hdd_state_ctrl_param_open(struct inode *inode,
18236 					  struct file *file)
18237 {
18238 	qdf_atomic_inc(&wlan_hdd_state_fops_ref);
18239 
18240 	return 0;
18241 }
18242 
18243 static void __hdd_inform_wifi_off(void)
18244 {
18245 	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
18246 	int ret;
18247 
18248 	ret = wlan_hdd_validate_context(hdd_ctx);
18249 	if (ret != 0)
18250 		return;
18251 
18252 	ucfg_dlm_wifi_off(hdd_ctx->pdev);
18253 }
18254 
18255 static void hdd_inform_wifi_off(void)
18256 {
18257 	int ret;
18258 	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
18259 	struct osif_psoc_sync *psoc_sync;
18260 
18261 	if (!hdd_ctx)
18262 		return;
18263 
18264 	ret = osif_psoc_sync_op_start(wiphy_dev(hdd_ctx->wiphy), &psoc_sync);
18265 	if (ret)
18266 		return;
18267 
18268 	hdd_set_adapter_wlm_def_level(hdd_ctx);
18269 	__hdd_inform_wifi_off();
18270 
18271 	osif_psoc_sync_op_stop(psoc_sync);
18272 }
18273 
18274 #if defined CFG80211_USER_HINT_CELL_BASE_SELF_MANAGED || \
18275 	(LINUX_VERSION_CODE >= KERNEL_VERSION(4, 18, 0))
18276 static void hdd_inform_wifi_on(void)
18277 {
18278 	int ret;
18279 	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
18280 	struct osif_psoc_sync *psoc_sync;
18281 
18282 	hdd_nofl_debug("inform regdomain for wifi on");
18283 	ret = wlan_hdd_validate_context(hdd_ctx);
18284 	if (ret)
18285 		return;
18286 	if (!wlan_hdd_validate_modules_state(hdd_ctx))
18287 		return;
18288 	if (!hdd_ctx->wiphy)
18289 		return;
18290 	ret = osif_psoc_sync_op_start(wiphy_dev(hdd_ctx->wiphy), &psoc_sync);
18291 	if (ret)
18292 		return;
18293 	if (hdd_ctx->wiphy->registered)
18294 		hdd_send_wiphy_regd_sync_event(hdd_ctx);
18295 
18296 	osif_psoc_sync_op_stop(psoc_sync);
18297 }
18298 #else
18299 static void hdd_inform_wifi_on(void)
18300 {
18301 }
18302 #endif
18303 
18304 static int hdd_validate_wlan_string(const char __user *user_buf)
18305 {
18306 	char buf[15];
18307 	int i;
18308 	static const char * const wlan_str[] = {
18309 		[WLAN_OFF_STR] = "OFF",
18310 		[WLAN_ON_STR] = "ON",
18311 		[WLAN_ENABLE_STR] = "ENABLE",
18312 		[WLAN_DISABLE_STR] = "DISABLE",
18313 		[WLAN_WAIT_FOR_READY_STR] = "WAIT_FOR_READY",
18314 		[WLAN_FORCE_DISABLE_STR] = "FORCE_DISABLE"
18315 	};
18316 
18317 	if (copy_from_user(buf, user_buf, sizeof(buf))) {
18318 		pr_err("Failed to read buffer\n");
18319 		return -EINVAL;
18320 	}
18321 
18322 	for (i = 0; i < ARRAY_SIZE(wlan_str); i++) {
18323 		if (qdf_str_ncmp(buf, wlan_str[i], strlen(wlan_str[i])) == 0)
18324 			return i;
18325 	}
18326 
18327 	return -EINVAL;
18328 }
18329 
18330 #ifdef FEATURE_CNSS_HW_SECURE_DISABLE
18331 #define WIFI_DISABLE_SLEEP (10)
18332 #define WIFI_DISABLE_MAX_RETRY_ATTEMPTS (10)
18333 static bool g_soft_unload;
18334 
18335 bool hdd_get_wlan_driver_status(void)
18336 {
18337 	return g_soft_unload;
18338 }
18339 
18340 static int hdd_wlan_soft_driver_load(void)
18341 {
18342 	if (!cds_is_driver_loaded()) {
18343 		hdd_debug("\nEnabling CNSS WLAN HW");
18344 		pld_wlan_hw_enable();
18345 		return 0;
18346 	}
18347 
18348 	if (!g_soft_unload) {
18349 		hdd_debug_rl("Enabling WiFi\n");
18350 		return -EINVAL;
18351 	}
18352 
18353 	hdd_driver_load();
18354 	g_soft_unload = false;
18355 	return 0;
18356 }
18357 
18358 static void hdd_wlan_soft_driver_unload(void)
18359 {
18360 	if (g_soft_unload) {
18361 		hdd_debug_rl("WiFi is already disabled");
18362 		return;
18363 	}
18364 	hdd_debug("Initiating soft driver unload\n");
18365 	g_soft_unload = true;
18366 	hdd_driver_unload();
18367 }
18368 
18369 static int hdd_wlan_idle_shutdown(struct hdd_context *hdd_ctx)
18370 {
18371 	int ret;
18372 	int retries = 0;
18373 	void *hif_ctx;
18374 
18375 	if (!hdd_ctx) {
18376 		hdd_err_rl("hdd_ctx is Null");
18377 		return -EINVAL;
18378 	}
18379 
18380 	hif_ctx = cds_get_context(QDF_MODULE_ID_HIF);
18381 
18382 	hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_IDLE_SHUTDOWN);
18383 
18384 	while (retries < WIFI_DISABLE_MAX_RETRY_ATTEMPTS) {
18385 		if (hif_ctx) {
18386 			/*
18387 			 * Trigger runtime sync resume before psoc_idle_shutdown
18388 			 * such that resume can happen successfully
18389 			 */
18390 			qdf_rtpm_sync_resume();
18391 		}
18392 		ret = pld_idle_shutdown(hdd_ctx->parent_dev,
18393 					hdd_psoc_idle_shutdown);
18394 
18395 		if (-EAGAIN == ret || hdd_ctx->is_wiphy_suspended) {
18396 			hdd_debug("System suspend in progress.Retries done:%d",
18397 				  retries);
18398 			msleep(WIFI_DISABLE_SLEEP);
18399 			retries++;
18400 			continue;
18401 		}
18402 		break;
18403 	}
18404 	hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_IDLE_SHUTDOWN);
18405 
18406 	if (retries > WIFI_DISABLE_MAX_RETRY_ATTEMPTS) {
18407 		hdd_debug("Max retries reached");
18408 		return -EINVAL;
18409 	}
18410 	hdd_debug_rl("WiFi is disabled");
18411 
18412 	return 0;
18413 }
18414 
18415 static int hdd_disable_wifi(struct hdd_context *hdd_ctx)
18416 {
18417 	int ret;
18418 
18419 	if (hdd_ctx->is_wlan_disabled) {
18420 		hdd_err_rl("Wifi is already disabled");
18421 		return 0;
18422 	}
18423 
18424 	hdd_debug("Initiating WLAN idle shutdown");
18425 	if (hdd_is_any_interface_open(hdd_ctx)) {
18426 		hdd_err("Interfaces still open, cannot process wifi disable");
18427 		return -EAGAIN;
18428 	}
18429 
18430 	hdd_ctx->is_wlan_disabled = true;
18431 
18432 	ret = hdd_wlan_idle_shutdown(hdd_ctx);
18433 	if (ret)
18434 		hdd_ctx->is_wlan_disabled = false;
18435 
18436 	return ret;
18437 }
18438 #else
18439 static int hdd_wlan_soft_driver_load(void)
18440 {
18441 	return -EINVAL;
18442 }
18443 
18444 static void hdd_wlan_soft_driver_unload(void)
18445 {
18446 }
18447 
18448 static int hdd_disable_wifi(struct hdd_context *hdd_ctx)
18449 {
18450 	return 0;
18451 }
18452 #endif /* FEATURE_CNSS_HW_SECURE_DISABLE */
18453 
18454 static ssize_t wlan_hdd_state_ctrl_param_write(struct file *filp,
18455 						const char __user *user_buf,
18456 						size_t count,
18457 						loff_t *f_pos)
18458 {
18459 	int id, ret;
18460 	unsigned long rc;
18461 	struct hdd_context *hdd_ctx;
18462 	bool is_wait_for_ready = false;
18463 	bool is_wlan_force_disabled;
18464 
18465 	hdd_enter();
18466 
18467 	id = hdd_validate_wlan_string(user_buf);
18468 
18469 	switch (id) {
18470 	case WLAN_OFF_STR:
18471 		hdd_info("Wifi turning off from UI\n");
18472 		hdd_inform_wifi_off();
18473 		goto exit;
18474 	case WLAN_ON_STR:
18475 		hdd_info("Wifi Turning On from UI\n");
18476 		break;
18477 	case WLAN_WAIT_FOR_READY_STR:
18478 		is_wait_for_ready = true;
18479 		hdd_info("Wifi wait for ready from UI\n");
18480 		break;
18481 	case WLAN_ENABLE_STR:
18482 		hdd_nofl_debug("Received WiFi enable from framework\n");
18483 		if (!hdd_wlan_soft_driver_load())
18484 			goto exit;
18485 		pr_info("Enabling WiFi\n");
18486 		break;
18487 	case WLAN_DISABLE_STR:
18488 		hdd_nofl_debug("Received WiFi disable from framework\n");
18489 		if (!cds_is_driver_loaded())
18490 			goto exit;
18491 
18492 		is_wlan_force_disabled = hdd_get_wlan_driver_status();
18493 		if (is_wlan_force_disabled)
18494 			goto exit;
18495 		pr_info("Disabling WiFi\n");
18496 		break;
18497 	case WLAN_FORCE_DISABLE_STR:
18498 		hdd_nofl_debug("Received Force WiFi disable from framework\n");
18499 		if (!cds_is_driver_loaded())
18500 			goto exit;
18501 
18502 		hdd_wlan_soft_driver_unload();
18503 		goto exit;
18504 	default:
18505 		hdd_err_rl("Invalid value received from framework");
18506 		return -EINVAL;
18507 	}
18508 
18509 	hdd_info("is_driver_loaded %d is_driver_recovering %d",
18510 		 cds_is_driver_loaded(), cds_is_driver_recovering());
18511 
18512 	if (!cds_is_driver_loaded() || cds_is_driver_recovering()) {
18513 		rc = wait_for_completion_timeout(&wlan_start_comp,
18514 				msecs_to_jiffies(HDD_WLAN_START_WAIT_TIME));
18515 		if (!rc) {
18516 			hdd_err("Driver Loading Timed-out!!");
18517 			ret = -EINVAL;
18518 			return ret;
18519 		}
18520 	}
18521 
18522 	if (is_wait_for_ready)
18523 		return count;
18524 	/*
18525 	 * Flush idle shutdown work for cases to synchronize the wifi on
18526 	 * during the idle shutdown.
18527 	 */
18528 	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
18529 	if (hdd_ctx)
18530 		hdd_psoc_idle_timer_stop(hdd_ctx);
18531 
18532 	if (id == WLAN_DISABLE_STR) {
18533 		if (!hdd_ctx) {
18534 			hdd_err_rl("hdd_ctx is Null");
18535 			goto exit;
18536 		}
18537 
18538 		ret = hdd_disable_wifi(hdd_ctx);
18539 		if (ret)
18540 			return ret;
18541 	}
18542 
18543 	if (id == WLAN_ENABLE_STR) {
18544 		if (!hdd_ctx) {
18545 			hdd_err_rl("hdd_ctx is Null");
18546 			goto exit;
18547 		}
18548 
18549 		if (!hdd_ctx->is_wlan_disabled) {
18550 			hdd_err_rl("WiFi is already enabled");
18551 			goto exit;
18552 		}
18553 		hdd_ctx->is_wlan_disabled = false;
18554 	}
18555 
18556 	if (id == WLAN_ON_STR)
18557 		hdd_inform_wifi_on();
18558 exit:
18559 	hdd_exit();
18560 	return count;
18561 }
18562 
18563 /**
18564  * wlan_hdd_state_ctrl_param_release() -  Release callback for /dev/wlan.
18565  *
18566  * @inode: struct inode pointer.
18567  * @file: struct file pointer.
18568  *
18569  * Release callback that would be invoked when the file operations has
18570  * completed fully. This is implemented to provide a reference count mechanism
18571  * via which the driver can wait till all possible usage of the /dev/wlan
18572  * file is completed.
18573  *
18574  * Return: Success
18575  */
18576 static int wlan_hdd_state_ctrl_param_release(struct inode *inode,
18577 					     struct file *file)
18578 {
18579 	qdf_atomic_dec(&wlan_hdd_state_fops_ref);
18580 
18581 	return 0;
18582 }
18583 
18584 const struct file_operations wlan_hdd_state_fops = {
18585 	.owner = THIS_MODULE,
18586 	.open = wlan_hdd_state_ctrl_param_open,
18587 	.write = wlan_hdd_state_ctrl_param_write,
18588 	.release = wlan_hdd_state_ctrl_param_release,
18589 };
18590 
18591 static int  wlan_hdd_state_ctrl_param_create(void)
18592 {
18593 	unsigned int wlan_hdd_state_major = 0;
18594 	int ret;
18595 	struct device *dev;
18596 
18597 	init_completion(&wlan_start_comp);
18598 	qdf_atomic_init(&wlan_hdd_state_fops_ref);
18599 
18600 	device = MKDEV(wlan_hdd_state_major, 0);
18601 
18602 	ret = alloc_chrdev_region(&device, 0, dev_num, "qcwlanstate");
18603 	if (ret) {
18604 		pr_err("Failed to register qcwlanstate");
18605 		goto dev_alloc_err;
18606 	}
18607 	wlan_hdd_state_major = MAJOR(device);
18608 
18609 	class = class_create(THIS_MODULE, WLAN_CTRL_NAME);
18610 	if (IS_ERR(class)) {
18611 		pr_err("wlan_hdd_state class_create error");
18612 		goto class_err;
18613 	}
18614 
18615 	dev = device_create(class, NULL, device, NULL, WLAN_CTRL_NAME);
18616 	if (IS_ERR(dev)) {
18617 		pr_err("wlan_hdd_statedevice_create error");
18618 		goto err_class_destroy;
18619 	}
18620 
18621 	cdev_init(&wlan_hdd_state_cdev, &wlan_hdd_state_fops);
18622 
18623 	wlan_hdd_state_cdev.owner = THIS_MODULE;
18624 
18625 	ret = cdev_add(&wlan_hdd_state_cdev, device, dev_num);
18626 	if (ret) {
18627 		pr_err("Failed to add cdev error");
18628 		goto cdev_add_err;
18629 	}
18630 
18631 	pr_info("wlan_hdd_state %s major(%d) initialized",
18632 		WLAN_CTRL_NAME, wlan_hdd_state_major);
18633 
18634 	return 0;
18635 
18636 cdev_add_err:
18637 	device_destroy(class, device);
18638 err_class_destroy:
18639 	class_destroy(class);
18640 class_err:
18641 	unregister_chrdev_region(device, dev_num);
18642 dev_alloc_err:
18643 	return -ENODEV;
18644 }
18645 
18646 /*
18647  * When multiple instances of the driver are loaded in parallel, only
18648  * one can create and own the state ctrl param. An instance of the
18649  * driver that creates the state ctrl param will wait for
18650  * HDD_WLAN_START_WAIT_TIME to be probed. If it is probed, then that
18651  * instance of the driver will stay loaded and no other instances of
18652  * the driver can load. But if it is not probed, then that instance of
18653  * the driver will destroy the state ctrl param and exit, and another
18654  * instance of the driver can then create the state ctrl param.
18655  */
18656 
18657 /* max number of instances we expect (arbitrary) */
18658 #define WLAN_DRIVER_MAX_INSTANCES 5
18659 
18660 /* max amount of time an instance has to wait for all instances */
18661 #define CTRL_PARAM_WAIT (WLAN_DRIVER_MAX_INSTANCES * HDD_WLAN_START_WAIT_TIME)
18662 
18663 /* amount of time we sleep for each retry (arbitrary) */
18664 #define CTRL_PARAM_SLEEP 100
18665 
18666 static void wlan_hdd_state_ctrl_param_destroy(void)
18667 {
18668 	cdev_del(&wlan_hdd_state_cdev);
18669 	device_destroy(class, device);
18670 	class_destroy(class);
18671 	unregister_chrdev_region(device, dev_num);
18672 
18673 	pr_info("Device node unregistered");
18674 }
18675 
18676 #else /* WLAN_CTRL_NAME */
18677 
18678 static int wlan_hdd_state_ctrl_param_create(void)
18679 {
18680 	return 0;
18681 }
18682 
18683 static void wlan_hdd_state_ctrl_param_destroy(void)
18684 {
18685 }
18686 
18687 #endif /* WLAN_CTRL_NAME */
18688 
18689 /**
18690  * hdd_send_scan_done_complete_cb() - API to send scan done indication to upper
18691  * layer
18692  * @vdev_id: vdev id
18693  *
18694  * Return: none
18695  */
18696 static void hdd_send_scan_done_complete_cb(uint8_t vdev_id)
18697 {
18698 	struct hdd_context *hdd_ctx;
18699 	struct wlan_hdd_link_info *link_info;
18700 	struct hdd_adapter *adapter;
18701 	struct sk_buff *vendor_event;
18702 	uint32_t len;
18703 
18704 	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
18705 	if (!hdd_ctx)
18706 		return;
18707 
18708 	link_info = hdd_get_link_info_by_vdev(hdd_ctx, vdev_id);
18709 	if (!link_info) {
18710 		hdd_err("Invalid vdev id:%d", vdev_id);
18711 		return;
18712 	}
18713 
18714 	adapter = link_info->adapter;
18715 	len = NLMSG_HDRLEN;
18716 	vendor_event =
18717 		wlan_cfg80211_vendor_event_alloc(
18718 			hdd_ctx->wiphy, &adapter->wdev, len,
18719 			QCA_NL80211_VENDOR_SUBCMD_CONNECTED_CHANNEL_STATS_INDEX,
18720 			GFP_KERNEL);
18721 
18722 	if (!vendor_event) {
18723 		hdd_err("wlan_cfg80211_vendor_event_alloc failed");
18724 		return;
18725 	}
18726 
18727 	hdd_debug("sending scan done ind to upper layer for vdev_id:%d",
18728 		  vdev_id);
18729 	wlan_cfg80211_vendor_event(vendor_event, GFP_KERNEL);
18730 }
18731 
18732 struct osif_vdev_mgr_ops osif_vdev_mgrlegacy_ops = {
18733 #ifdef WLAN_FEATURE_DYNAMIC_MAC_ADDR_UPDATE
18734 	.osif_vdev_mgr_set_mac_addr_response = hdd_set_mac_addr_event_cb,
18735 #endif
18736 	.osif_vdev_mgr_send_scan_done_complete_cb =
18737 					hdd_send_scan_done_complete_cb,
18738 
18739 };
18740 
18741 static QDF_STATUS hdd_vdev_mgr_register_cb(void)
18742 {
18743 	osif_vdev_mgr_set_legacy_cb(&osif_vdev_mgrlegacy_ops);
18744 	return osif_vdev_mgr_register_cb();
18745 }
18746 
18747 static void hdd_vdev_mgr_unregister_cb(void)
18748 {
18749 	osif_vdev_mgr_reset_legacy_cb();
18750 }
18751 
18752 /**
18753  * hdd_component_cb_init() - Initialize component callbacks
18754  *
18755  * This function initializes hdd callbacks to different
18756  * components
18757  *
18758  * Context: Any context.
18759  * Return: QDF_STATUS
18760  */
18761 static QDF_STATUS hdd_component_cb_init(void)
18762 {
18763 	QDF_STATUS status;
18764 
18765 	status = hdd_cm_register_cb();
18766 	if (QDF_IS_STATUS_ERROR(status))
18767 		return status;
18768 
18769 	status = hdd_vdev_mgr_register_cb();
18770 	if (QDF_IS_STATUS_ERROR(status))
18771 		goto cm_unregister_cb;
18772 
18773 	status = osif_twt_register_cb();
18774 	if (QDF_IS_STATUS_ERROR(status))
18775 		goto hdd_vdev_mgr_unregister_cb;
18776 
18777 	status = hdd_pre_cac_register_cb();
18778 	if (QDF_IS_STATUS_ERROR(status))
18779 		goto hdd_vdev_mgr_unregister_cb;
18780 
18781 	return QDF_STATUS_SUCCESS;
18782 
18783 hdd_vdev_mgr_unregister_cb:
18784 	hdd_vdev_mgr_unregister_cb();
18785 cm_unregister_cb:
18786 	hdd_cm_unregister_cb();
18787 	return status;
18788 }
18789 
18790 /**
18791  * hdd_component_cb_deinit() - De-initialize component callbacks
18792  *
18793  * This function de-initializes hdd callbacks with different components
18794  *
18795  * Context: Any context.
18796  * Return: None`
18797  */
18798 static void hdd_component_cb_deinit(void)
18799 {
18800 	hdd_pre_cac_unregister_cb();
18801 	hdd_vdev_mgr_unregister_cb();
18802 	hdd_cm_unregister_cb();
18803 }
18804 
18805 /**
18806  * hdd_component_init() - Initialize all components
18807  *
18808  * Return: QDF_STATUS
18809  */
18810 static QDF_STATUS hdd_component_init(void)
18811 {
18812 	QDF_STATUS status;
18813 
18814 	/* initialize converged components */
18815 
18816 	status = ucfg_mlme_global_init();
18817 	if (QDF_IS_STATUS_ERROR(status))
18818 		return status;
18819 
18820 	status = dispatcher_init();
18821 	if (QDF_IS_STATUS_ERROR(status))
18822 		goto mlme_global_deinit;
18823 
18824 	status = target_if_init(wma_get_psoc_from_scn_handle);
18825 	if (QDF_IS_STATUS_ERROR(status))
18826 		goto dispatcher_deinit;
18827 
18828 	/* initialize non-converged components */
18829 	status = ucfg_mlme_init();
18830 	if (QDF_IS_STATUS_ERROR(status))
18831 		goto target_if_deinit;
18832 
18833 	status = ucfg_fwol_init();
18834 	if (QDF_IS_STATUS_ERROR(status))
18835 		goto mlme_deinit;
18836 
18837 	status = disa_init();
18838 	if (QDF_IS_STATUS_ERROR(status))
18839 		goto fwol_deinit;
18840 
18841 	status = pmo_init();
18842 	if (QDF_IS_STATUS_ERROR(status))
18843 		goto disa_deinit;
18844 
18845 	status = ucfg_ocb_init();
18846 	if (QDF_IS_STATUS_ERROR(status))
18847 		goto pmo_deinit;
18848 
18849 	status = ipa_init();
18850 	if (QDF_IS_STATUS_ERROR(status))
18851 		goto ocb_deinit;
18852 
18853 	status = ucfg_action_oui_init();
18854 	if (QDF_IS_STATUS_ERROR(status))
18855 		goto ipa_deinit;
18856 
18857 	status = nan_init();
18858 	if (QDF_IS_STATUS_ERROR(status))
18859 		goto action_oui_deinit;
18860 
18861 	status = ucfg_p2p_init();
18862 	if (QDF_IS_STATUS_ERROR(status))
18863 		goto nan_deinit;
18864 
18865 	status = ucfg_interop_issues_ap_init();
18866 	if (QDF_IS_STATUS_ERROR(status))
18867 		goto p2p_deinit;
18868 
18869 	status = policy_mgr_init();
18870 	if (QDF_IS_STATUS_ERROR(status))
18871 		goto interop_issues_ap_deinit;
18872 
18873 	status = ucfg_tdls_init();
18874 	if (QDF_IS_STATUS_ERROR(status))
18875 		goto policy_deinit;
18876 
18877 	status = ucfg_dlm_init();
18878 	if (QDF_IS_STATUS_ERROR(status))
18879 		goto tdls_deinit;
18880 
18881 	status = ucfg_pkt_capture_init();
18882 	if (QDF_IS_STATUS_ERROR(status))
18883 		goto dlm_deinit;
18884 
18885 	status = ucfg_ftm_time_sync_init();
18886 	if (QDF_IS_STATUS_ERROR(status))
18887 		goto pkt_capture_deinit;
18888 
18889 	status = ucfg_pre_cac_init();
18890 	if (QDF_IS_STATUS_ERROR(status))
18891 		goto pre_cac_deinit;
18892 
18893 	status = ucfg_dp_init();
18894 	if (QDF_IS_STATUS_ERROR(status))
18895 		goto pre_cac_deinit;
18896 
18897 	status = ucfg_qmi_init();
18898 	if (QDF_IS_STATUS_ERROR(status))
18899 		goto dp_deinit;
18900 
18901 	status = ucfg_ll_sap_init();
18902 	if (QDF_IS_STATUS_ERROR(status))
18903 		goto qmi_deinit;
18904 
18905 	status = ucfg_afc_init();
18906 	if (QDF_IS_STATUS_ERROR(status))
18907 		goto ll_sap_deinit;
18908 
18909 	status = hdd_mlo_mgr_register_osif_ops();
18910 	if (QDF_IS_STATUS_ERROR(status))
18911 		goto afc_deinit;
18912 
18913 	return QDF_STATUS_SUCCESS;
18914 
18915 afc_deinit:
18916 	ucfg_afc_deinit();
18917 ll_sap_deinit:
18918 	ucfg_ll_sap_deinit();
18919 qmi_deinit:
18920 	ucfg_qmi_deinit();
18921 dp_deinit:
18922 	ucfg_dp_deinit();
18923 pre_cac_deinit:
18924 	ucfg_pre_cac_deinit();
18925 pkt_capture_deinit:
18926 	ucfg_pkt_capture_deinit();
18927 dlm_deinit:
18928 	ucfg_dlm_deinit();
18929 tdls_deinit:
18930 	ucfg_tdls_deinit();
18931 policy_deinit:
18932 	policy_mgr_deinit();
18933 interop_issues_ap_deinit:
18934 	ucfg_interop_issues_ap_deinit();
18935 p2p_deinit:
18936 	ucfg_p2p_deinit();
18937 nan_deinit:
18938 	nan_deinit();
18939 action_oui_deinit:
18940 	ucfg_action_oui_deinit();
18941 ipa_deinit:
18942 	ipa_deinit();
18943 ocb_deinit:
18944 	ucfg_ocb_deinit();
18945 pmo_deinit:
18946 	pmo_deinit();
18947 disa_deinit:
18948 	disa_deinit();
18949 fwol_deinit:
18950 	ucfg_fwol_deinit();
18951 mlme_deinit:
18952 	ucfg_mlme_deinit();
18953 target_if_deinit:
18954 	target_if_deinit();
18955 dispatcher_deinit:
18956 	dispatcher_deinit();
18957 mlme_global_deinit:
18958 	ucfg_mlme_global_deinit();
18959 
18960 	return status;
18961 }
18962 
18963 /**
18964  * hdd_component_deinit() - Deinitialize all components
18965  *
18966  * Return: None
18967  */
18968 static void hdd_component_deinit(void)
18969 {
18970 	/* deinitialize non-converged components */
18971 	hdd_mlo_mgr_unregister_osif_ops();
18972 	ucfg_afc_deinit();
18973 	ucfg_ll_sap_deinit();
18974 	ucfg_qmi_deinit();
18975 	ucfg_dp_deinit();
18976 	ucfg_pre_cac_deinit();
18977 	ucfg_ftm_time_sync_deinit();
18978 	ucfg_pkt_capture_deinit();
18979 	ucfg_dlm_deinit();
18980 	ucfg_tdls_deinit();
18981 	policy_mgr_deinit();
18982 	ucfg_interop_issues_ap_deinit();
18983 	ucfg_p2p_deinit();
18984 	nan_deinit();
18985 	ucfg_action_oui_deinit();
18986 	ipa_deinit();
18987 	ucfg_ocb_deinit();
18988 	pmo_deinit();
18989 	disa_deinit();
18990 	ucfg_fwol_deinit();
18991 	ucfg_mlme_deinit();
18992 
18993 	/* deinitialize converged components */
18994 	target_if_deinit();
18995 	dispatcher_deinit();
18996 	ucfg_mlme_global_deinit();
18997 }
18998 
18999 QDF_STATUS hdd_component_psoc_open(struct wlan_objmgr_psoc *psoc)
19000 {
19001 	QDF_STATUS status;
19002 
19003 	status = ucfg_mlme_psoc_open(psoc);
19004 	if (QDF_IS_STATUS_ERROR(status))
19005 		return status;
19006 
19007 	status = ucfg_dlm_psoc_open(psoc);
19008 	if (QDF_IS_STATUS_ERROR(status))
19009 		goto err_dlm;
19010 
19011 	status = ucfg_fwol_psoc_open(psoc);
19012 	if (QDF_IS_STATUS_ERROR(status))
19013 		goto err_fwol;
19014 
19015 	status = ucfg_pmo_psoc_open(psoc);
19016 	if (QDF_IS_STATUS_ERROR(status))
19017 		goto err_pmo;
19018 
19019 	status = ucfg_policy_mgr_psoc_open(psoc);
19020 	if (QDF_IS_STATUS_ERROR(status))
19021 		goto err_plcy_mgr;
19022 
19023 	status = ucfg_p2p_psoc_open(psoc);
19024 	if (QDF_IS_STATUS_ERROR(status))
19025 		goto err_p2p;
19026 
19027 	status = ucfg_tdls_psoc_open(psoc);
19028 	if (QDF_IS_STATUS_ERROR(status))
19029 		goto err_tdls;
19030 
19031 	status = ucfg_nan_psoc_open(psoc);
19032 	if (QDF_IS_STATUS_ERROR(status))
19033 		goto err_nan;
19034 
19035 	status = ucfg_twt_psoc_open(psoc);
19036 	if (QDF_IS_STATUS_ERROR(status))
19037 		goto err_twt;
19038 
19039 	status = ucfg_wifi_pos_psoc_open(psoc);
19040 	if (QDF_IS_STATUS_ERROR(status))
19041 		goto err_wifi_pos;
19042 
19043 	status = ucfg_dp_psoc_open(psoc);
19044 	if (QDF_IS_STATUS_ERROR(status))
19045 		goto err_dp;
19046 
19047 	return status;
19048 
19049 err_dp:
19050 	ucfg_wifi_pos_psoc_close(psoc);
19051 err_wifi_pos:
19052 	ucfg_twt_psoc_close(psoc);
19053 err_twt:
19054 	ucfg_nan_psoc_close(psoc);
19055 err_nan:
19056 	ucfg_tdls_psoc_close(psoc);
19057 err_tdls:
19058 	ucfg_p2p_psoc_close(psoc);
19059 err_p2p:
19060 	ucfg_policy_mgr_psoc_close(psoc);
19061 err_plcy_mgr:
19062 	ucfg_pmo_psoc_close(psoc);
19063 err_pmo:
19064 	ucfg_fwol_psoc_close(psoc);
19065 err_fwol:
19066 	ucfg_dlm_psoc_close(psoc);
19067 err_dlm:
19068 	ucfg_mlme_psoc_close(psoc);
19069 
19070 	return status;
19071 }
19072 
19073 void hdd_component_psoc_close(struct wlan_objmgr_psoc *psoc)
19074 {
19075 	ucfg_dp_psoc_close(psoc);
19076 	ucfg_wifi_pos_psoc_close(psoc);
19077 	ucfg_twt_psoc_close(psoc);
19078 	ucfg_nan_psoc_close(psoc);
19079 	ucfg_tdls_psoc_close(psoc);
19080 	ucfg_p2p_psoc_close(psoc);
19081 	ucfg_policy_mgr_psoc_close(psoc);
19082 	ucfg_pmo_psoc_close(psoc);
19083 	ucfg_fwol_psoc_close(psoc);
19084 	ucfg_dlm_psoc_close(psoc);
19085 	ucfg_mlme_psoc_close(psoc);
19086 }
19087 
19088 void hdd_component_psoc_enable(struct wlan_objmgr_psoc *psoc)
19089 {
19090 	ocb_psoc_enable(psoc);
19091 	disa_psoc_enable(psoc);
19092 	nan_psoc_enable(psoc);
19093 	p2p_psoc_enable(psoc);
19094 	ucfg_interop_issues_ap_psoc_enable(psoc);
19095 	policy_mgr_psoc_enable(psoc);
19096 	ucfg_tdls_psoc_enable(psoc);
19097 	ucfg_fwol_psoc_enable(psoc);
19098 	ucfg_action_oui_psoc_enable(psoc);
19099 }
19100 
19101 void hdd_component_psoc_disable(struct wlan_objmgr_psoc *psoc)
19102 {
19103 	ucfg_action_oui_psoc_disable(psoc);
19104 	ucfg_fwol_psoc_disable(psoc);
19105 	ucfg_tdls_psoc_disable(psoc);
19106 	policy_mgr_psoc_disable(psoc);
19107 	ucfg_interop_issues_ap_psoc_disable(psoc);
19108 	p2p_psoc_disable(psoc);
19109 	nan_psoc_disable(psoc);
19110 	disa_psoc_disable(psoc);
19111 	ocb_psoc_disable(psoc);
19112 }
19113 
19114 QDF_STATUS hdd_component_pdev_open(struct wlan_objmgr_pdev *pdev)
19115 {
19116 	return ucfg_mlme_pdev_open(pdev);
19117 }
19118 
19119 void hdd_component_pdev_close(struct wlan_objmgr_pdev *pdev)
19120 {
19121 	ucfg_mlme_pdev_close(pdev);
19122 }
19123 
19124 static QDF_STATUS hdd_qdf_print_init(void)
19125 {
19126 	QDF_STATUS status;
19127 	int qdf_print_idx;
19128 
19129 	status = qdf_print_setup();
19130 	if (QDF_IS_STATUS_ERROR(status)) {
19131 		pr_err("Failed qdf_print_setup; status:%u\n", status);
19132 		return status;
19133 	}
19134 
19135 	qdf_print_idx = qdf_print_ctrl_register(cinfo, NULL, NULL, "MCL_WLAN");
19136 	if (qdf_print_idx < 0) {
19137 		pr_err("Failed to register for qdf_print_ctrl\n");
19138 		return QDF_STATUS_E_FAILURE;
19139 	}
19140 
19141 	qdf_set_pidx(qdf_print_idx);
19142 
19143 	return QDF_STATUS_SUCCESS;
19144 }
19145 
19146 static void hdd_qdf_print_deinit(void)
19147 {
19148 	int qdf_pidx = qdf_get_pidx();
19149 
19150 	qdf_set_pidx(-1);
19151 	qdf_print_ctrl_cleanup(qdf_pidx);
19152 
19153 	/* currently, no qdf print 'un-setup'*/
19154 }
19155 
19156 static QDF_STATUS hdd_qdf_init(void)
19157 {
19158 	QDF_STATUS status;
19159 
19160 	status = hdd_qdf_print_init();
19161 	if (QDF_IS_STATUS_ERROR(status))
19162 		goto exit;
19163 
19164 	status = qdf_debugfs_init();
19165 	if (QDF_IS_STATUS_ERROR(status)) {
19166 		hdd_err("Failed to init debugfs; status:%u", status);
19167 		goto print_deinit;
19168 	}
19169 
19170 	qdf_lock_stats_init();
19171 	qdf_mem_init();
19172 	qdf_delayed_work_feature_init();
19173 	qdf_periodic_work_feature_init();
19174 	qdf_wake_lock_feature_init();
19175 	qdf_mc_timer_manager_init();
19176 	qdf_event_list_init();
19177 
19178 	status = qdf_talloc_feature_init();
19179 	if (QDF_IS_STATUS_ERROR(status)) {
19180 		hdd_err("Failed to init talloc; status:%u", status);
19181 		goto event_deinit;
19182 	}
19183 
19184 	status = qdf_cpuhp_init();
19185 	if (QDF_IS_STATUS_ERROR(status)) {
19186 		hdd_err("Failed to init cpuhp; status:%u", status);
19187 		goto talloc_deinit;
19188 	}
19189 
19190 	status = qdf_trace_spin_lock_init();
19191 	if (QDF_IS_STATUS_ERROR(status)) {
19192 		hdd_err("Failed to init spinlock; status:%u", status);
19193 		goto cpuhp_deinit;
19194 	}
19195 
19196 	qdf_trace_init();
19197 	qdf_minidump_init();
19198 	qdf_ssr_driver_dump_init();
19199 	qdf_register_debugcb_init();
19200 
19201 	return QDF_STATUS_SUCCESS;
19202 
19203 cpuhp_deinit:
19204 	qdf_cpuhp_deinit();
19205 talloc_deinit:
19206 	qdf_talloc_feature_deinit();
19207 event_deinit:
19208 	qdf_event_list_destroy();
19209 	qdf_mc_timer_manager_exit();
19210 	qdf_wake_lock_feature_deinit();
19211 	qdf_periodic_work_feature_deinit();
19212 	qdf_delayed_work_feature_deinit();
19213 	qdf_mem_exit();
19214 	qdf_lock_stats_deinit();
19215 	qdf_debugfs_exit();
19216 print_deinit:
19217 	hdd_qdf_print_deinit();
19218 
19219 exit:
19220 	return status;
19221 }
19222 
19223 static void hdd_qdf_deinit(void)
19224 {
19225 	/* currently, no debugcb deinit */
19226 	qdf_ssr_driver_dump_deinit();
19227 	qdf_minidump_deinit();
19228 	qdf_trace_deinit();
19229 
19230 	/* currently, no trace spinlock deinit */
19231 
19232 	qdf_cpuhp_deinit();
19233 	qdf_talloc_feature_deinit();
19234 	qdf_event_list_destroy();
19235 	qdf_mc_timer_manager_exit();
19236 	qdf_wake_lock_feature_deinit();
19237 	qdf_periodic_work_feature_deinit();
19238 	qdf_delayed_work_feature_deinit();
19239 	qdf_mem_exit();
19240 	qdf_lock_stats_deinit();
19241 	qdf_debugfs_exit();
19242 	hdd_qdf_print_deinit();
19243 }
19244 
19245 #ifdef FEATURE_MONITOR_MODE_SUPPORT
19246 static bool is_monitor_mode_supported(void)
19247 {
19248 	return true;
19249 }
19250 #else
19251 static bool is_monitor_mode_supported(void)
19252 {
19253 	pr_err("Monitor mode not supported!");
19254 	return false;
19255 }
19256 #endif
19257 
19258 #ifdef WLAN_FEATURE_EPPING
19259 static bool is_epping_mode_supported(void)
19260 {
19261 	return true;
19262 }
19263 #else
19264 static bool is_epping_mode_supported(void)
19265 {
19266 	pr_err("Epping mode not supported!");
19267 	return false;
19268 }
19269 #endif
19270 
19271 #ifdef QCA_WIFI_FTM
19272 static bool is_ftm_mode_supported(void)
19273 {
19274 	return true;
19275 }
19276 #else
19277 static bool is_ftm_mode_supported(void)
19278 {
19279 	pr_err("FTM mode not supported!");
19280 	return false;
19281 }
19282 #endif
19283 
19284 /**
19285  * is_con_mode_valid() - check con mode is valid or not
19286  * @mode: global con mode
19287  *
19288  * Return: TRUE on success FALSE on failure
19289  */
19290 static bool is_con_mode_valid(enum QDF_GLOBAL_MODE mode)
19291 {
19292 	switch (mode) {
19293 	case QDF_GLOBAL_MONITOR_MODE:
19294 		return is_monitor_mode_supported();
19295 	case QDF_GLOBAL_EPPING_MODE:
19296 		return is_epping_mode_supported();
19297 	case QDF_GLOBAL_FTM_MODE:
19298 		return is_ftm_mode_supported();
19299 	case QDF_GLOBAL_MISSION_MODE:
19300 		return true;
19301 	default:
19302 		return false;
19303 	}
19304 }
19305 
19306 static void hdd_stop_present_mode(struct hdd_context *hdd_ctx,
19307 				  enum QDF_GLOBAL_MODE curr_mode)
19308 {
19309 	if (hdd_ctx->driver_status == DRIVER_MODULES_CLOSED)
19310 		return;
19311 
19312 	switch (curr_mode) {
19313 	case QDF_GLOBAL_MONITOR_MODE:
19314 		hdd_info("Release wakelock for monitor mode!");
19315 		qdf_wake_lock_release(&hdd_ctx->monitor_mode_wakelock,
19316 				      WIFI_POWER_EVENT_WAKELOCK_MONITOR_MODE);
19317 		fallthrough;
19318 	case QDF_GLOBAL_MISSION_MODE:
19319 	case QDF_GLOBAL_FTM_MODE:
19320 		hdd_abort_mac_scan_all_adapters(hdd_ctx);
19321 		wlan_cfg80211_cleanup_scan_queue(hdd_ctx->pdev, NULL);
19322 		hdd_stop_all_adapters(hdd_ctx);
19323 		hdd_deinit_all_adapters(hdd_ctx, false);
19324 
19325 		break;
19326 	default:
19327 		break;
19328 	}
19329 }
19330 
19331 static void hdd_cleanup_present_mode(struct hdd_context *hdd_ctx,
19332 				    enum QDF_GLOBAL_MODE curr_mode)
19333 {
19334 	switch (curr_mode) {
19335 	case QDF_GLOBAL_MISSION_MODE:
19336 	case QDF_GLOBAL_MONITOR_MODE:
19337 	case QDF_GLOBAL_FTM_MODE:
19338 		hdd_close_all_adapters(hdd_ctx, false);
19339 		break;
19340 	case QDF_GLOBAL_EPPING_MODE:
19341 		epping_disable();
19342 		epping_close();
19343 		break;
19344 	default:
19345 		return;
19346 	}
19347 }
19348 
19349 static int
19350 hdd_parse_driver_mode(const char *mode_str, enum QDF_GLOBAL_MODE *out_mode)
19351 {
19352 	QDF_STATUS status;
19353 	uint32_t mode;
19354 
19355 	*out_mode = QDF_GLOBAL_MAX_MODE;
19356 
19357 	status = qdf_uint32_parse(mode_str, &mode);
19358 	if (QDF_IS_STATUS_ERROR(status))
19359 		return qdf_status_to_os_return(status);
19360 
19361 	if (mode >= QDF_GLOBAL_MAX_MODE)
19362 		return -ERANGE;
19363 
19364 	*out_mode = (enum QDF_GLOBAL_MODE)mode;
19365 
19366 	return 0;
19367 }
19368 
19369 static int hdd_mode_change_psoc_idle_shutdown(struct device *dev)
19370 {
19371 	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
19372 
19373 	if (!hdd_ctx)
19374 		return -EINVAL;
19375 
19376 	return hdd_wlan_stop_modules(hdd_ctx, true);
19377 }
19378 
19379 static int hdd_mode_change_psoc_idle_restart(struct device *dev)
19380 {
19381 	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
19382 	int ret;
19383 
19384 	if (!hdd_ctx)
19385 		return -EINVAL;
19386 	ret = hdd_soc_idle_restart_lock(dev);
19387 	if (ret)
19388 		return ret;
19389 	ret = hdd_wlan_start_modules(hdd_ctx, false);
19390 	hdd_soc_idle_restart_unlock();
19391 
19392 	return ret;
19393 }
19394 
19395 /**
19396  * __hdd_driver_mode_change() - Handles a driver mode change
19397  * @hdd_ctx: Pointer to the global HDD context
19398  * @next_mode: the driver mode to transition to
19399  *
19400  * This function is invoked when user updates con_mode using sys entry,
19401  * to initialize and bring-up driver in that specific mode.
19402  *
19403  * Return: Errno
19404  */
19405 static int __hdd_driver_mode_change(struct hdd_context *hdd_ctx,
19406 				    enum QDF_GLOBAL_MODE next_mode)
19407 {
19408 	enum QDF_GLOBAL_MODE curr_mode;
19409 	int errno;
19410 	struct bbm_params param = {0};
19411 
19412 	hdd_info("Driver mode changing to %d", next_mode);
19413 
19414 	errno = wlan_hdd_validate_context(hdd_ctx);
19415 	if (errno)
19416 		return errno;
19417 
19418 	if (!is_con_mode_valid(next_mode)) {
19419 		hdd_err_rl("Requested driver mode is invalid");
19420 		return -EINVAL;
19421 	}
19422 
19423 	curr_mode = hdd_get_conparam();
19424 	if (curr_mode == next_mode) {
19425 		hdd_err_rl("Driver is already in the requested mode");
19426 		return 0;
19427 	}
19428 
19429 	hdd_psoc_idle_timer_stop(hdd_ctx);
19430 
19431 	/* ensure adapters are stopped */
19432 	hdd_stop_present_mode(hdd_ctx, curr_mode);
19433 
19434 	if (DRIVER_MODULES_CLOSED != hdd_ctx->driver_status) {
19435 		is_mode_change_psoc_idle_shutdown = true;
19436 		errno = pld_idle_shutdown(hdd_ctx->parent_dev,
19437 					  hdd_mode_change_psoc_idle_shutdown);
19438 		if (errno) {
19439 			is_mode_change_psoc_idle_shutdown = false;
19440 			hdd_err("Stop wlan modules failed");
19441 			return errno;
19442 		}
19443 	}
19444 
19445 	/* Cleanup present mode before switching to new mode */
19446 	hdd_cleanup_present_mode(hdd_ctx, curr_mode);
19447 
19448 	hdd_set_conparam(next_mode);
19449 	pld_set_mode(next_mode);
19450 
19451 	qdf_event_reset(&hdd_ctx->regulatory_update_event);
19452 	qdf_mutex_acquire(&hdd_ctx->regulatory_status_lock);
19453 	hdd_ctx->is_regulatory_update_in_progress = true;
19454 	qdf_mutex_release(&hdd_ctx->regulatory_status_lock);
19455 
19456 	errno = pld_idle_restart(hdd_ctx->parent_dev,
19457 				 hdd_mode_change_psoc_idle_restart);
19458 	if (errno) {
19459 		hdd_err("Start wlan modules failed: %d", errno);
19460 		return errno;
19461 	}
19462 
19463 	errno = hdd_open_adapters_for_mode(hdd_ctx, next_mode);
19464 	if (errno) {
19465 		hdd_err("Failed to open adapters");
19466 		return errno;
19467 	}
19468 
19469 	if (next_mode == QDF_GLOBAL_MONITOR_MODE) {
19470 		struct hdd_adapter *adapter =
19471 			hdd_get_adapter(hdd_ctx, QDF_MONITOR_MODE);
19472 
19473 		QDF_BUG(adapter);
19474 		if (!adapter) {
19475 			hdd_err("Failed to get monitor adapter");
19476 			return -EINVAL;
19477 		}
19478 
19479 		errno = hdd_start_adapter(adapter, false);
19480 		if (errno) {
19481 			hdd_err("Failed to start monitor adapter");
19482 			return errno;
19483 		}
19484 
19485 		hdd_info("Acquire wakelock for monitor mode");
19486 		qdf_wake_lock_acquire(&hdd_ctx->monitor_mode_wakelock,
19487 				      WIFI_POWER_EVENT_WAKELOCK_MONITOR_MODE);
19488 	}
19489 
19490 	/* con_mode is a global module parameter */
19491 	con_mode = next_mode;
19492 	hdd_info("Driver mode successfully changed to %d", next_mode);
19493 
19494 	param.policy = BBM_DRIVER_MODE_POLICY;
19495 	param.policy_info.driver_mode = con_mode;
19496 	ucfg_dp_bbm_apply_independent_policy(hdd_ctx->psoc, &param);
19497 
19498 	return 0;
19499 }
19500 
19501 static int hdd_driver_mode_change(enum QDF_GLOBAL_MODE mode)
19502 {
19503 	struct osif_driver_sync *driver_sync;
19504 	struct hdd_context *hdd_ctx;
19505 	QDF_STATUS status;
19506 	int errno;
19507 
19508 	hdd_enter();
19509 
19510 	status = osif_driver_sync_trans_start_wait(&driver_sync);
19511 	if (QDF_IS_STATUS_ERROR(status)) {
19512 		hdd_err("Failed to start 'mode change'; status:%u", status);
19513 		errno = qdf_status_to_os_return(status);
19514 		goto exit;
19515 	}
19516 
19517 	osif_driver_sync_wait_for_ops(driver_sync);
19518 
19519 	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
19520 	errno = wlan_hdd_validate_context(hdd_ctx);
19521 	if (errno)
19522 		goto trans_stop;
19523 
19524 	errno = __hdd_driver_mode_change(hdd_ctx, mode);
19525 
19526 trans_stop:
19527 	osif_driver_sync_trans_stop(driver_sync);
19528 
19529 exit:
19530 	hdd_exit();
19531 
19532 	return errno;
19533 }
19534 
19535 static int hdd_set_con_mode(enum QDF_GLOBAL_MODE mode)
19536 {
19537 	con_mode = mode;
19538 
19539 	return 0;
19540 }
19541 
19542 static int (*hdd_set_con_mode_cb)(enum QDF_GLOBAL_MODE mode) = hdd_set_con_mode;
19543 
19544 static void hdd_driver_mode_change_register(void)
19545 {
19546 	hdd_set_con_mode_cb = hdd_driver_mode_change;
19547 }
19548 
19549 static void hdd_driver_mode_change_unregister(void)
19550 {
19551 	hdd_set_con_mode_cb = hdd_set_con_mode;
19552 }
19553 
19554 static int con_mode_handler(const char *kmessage, const struct kernel_param *kp)
19555 {
19556 	enum QDF_GLOBAL_MODE mode;
19557 	int errno;
19558 
19559 	errno = hdd_parse_driver_mode(kmessage, &mode);
19560 	if (errno) {
19561 		hdd_err_rl("Failed to parse driver mode '%s'", kmessage);
19562 		return errno;
19563 	}
19564 
19565 	return hdd_set_con_mode_cb(mode);
19566 }
19567 
19568 /*
19569  * If the wlan_hdd_register_driver will return an error
19570  * if the wlan driver tries to register with the
19571  * platform driver before cnss_probe is completed.
19572  * Depending on the error code, the wlan driver waits
19573  * and retries to register.
19574  */
19575 
19576 /* Max number of retries (arbitrary)*/
19577 #define HDD_MAX_PLD_REGISTER_RETRY (50)
19578 
19579 /* Max amount of time we sleep before each retry */
19580 #define HDD_PLD_REGISTER_FAIL_SLEEP_DURATION (100)
19581 
19582 static int hdd_register_driver_retry(void)
19583 {
19584 	int count = 0;
19585 	int errno;
19586 
19587 	while (true) {
19588 		errno = wlan_hdd_register_driver();
19589 		if (errno != -EAGAIN)
19590 			return errno;
19591 		hdd_nofl_info("Retry Platform Driver Registration; errno:%d count:%d",
19592 			      errno, count);
19593 		if (++count == HDD_MAX_PLD_REGISTER_RETRY)
19594 			return errno;
19595 		msleep(HDD_PLD_REGISTER_FAIL_SLEEP_DURATION);
19596 		continue;
19597 	}
19598 
19599 	return errno;
19600 }
19601 
19602 /**
19603  * hdd_create_wifi_feature_interface() - Create wifi feature interface
19604  *
19605  * Return: none
19606  */
19607 static void hdd_create_wifi_feature_interface(void)
19608 {
19609 	hdd_sysfs_create_wifi_root_obj();
19610 	hdd_create_wifi_feature_interface_sysfs_file();
19611 }
19612 
19613 int hdd_driver_load(void)
19614 {
19615 	struct osif_driver_sync *driver_sync;
19616 	QDF_STATUS status;
19617 	int errno;
19618 	bool soft_load;
19619 
19620 	pr_info("%s: Loading driver v%s\n", WLAN_MODULE_NAME,
19621 		g_wlan_driver_version);
19622 	hdd_place_marker(NULL, "START LOADING", NULL);
19623 
19624 	status = hdd_qdf_init();
19625 	if (QDF_IS_STATUS_ERROR(status)) {
19626 		errno = qdf_status_to_os_return(status);
19627 		goto exit;
19628 	}
19629 
19630 	osif_sync_init();
19631 
19632 	status = osif_driver_sync_create_and_trans(&driver_sync);
19633 	if (QDF_IS_STATUS_ERROR(status)) {
19634 		hdd_err("Failed to init driver sync; status:%u", status);
19635 		errno = qdf_status_to_os_return(status);
19636 		goto sync_deinit;
19637 	}
19638 
19639 	errno = hdd_init();
19640 	if (errno) {
19641 		hdd_err("Failed to init HDD; errno:%d", errno);
19642 		goto trans_stop;
19643 	}
19644 
19645 	status = hdd_component_cb_init();
19646 	if (QDF_IS_STATUS_ERROR(status)) {
19647 		hdd_err("Failed to init component cb; status:%u", status);
19648 		errno = qdf_status_to_os_return(status);
19649 		goto hdd_deinit;
19650 	}
19651 
19652 	status = hdd_component_init();
19653 	if (QDF_IS_STATUS_ERROR(status)) {
19654 		hdd_err("Failed to init components; status:%u", status);
19655 		errno = qdf_status_to_os_return(status);
19656 		goto comp_cb_deinit;
19657 	}
19658 
19659 	status = qdf_wake_lock_create(&wlan_wake_lock, "wlan");
19660 	if (QDF_IS_STATUS_ERROR(status)) {
19661 		hdd_err("Failed to create wake lock; status:%u", status);
19662 		errno = qdf_status_to_os_return(status);
19663 		goto comp_deinit;
19664 	}
19665 
19666 	hdd_set_conparam(con_mode);
19667 
19668 	errno = pld_init();
19669 	if (errno) {
19670 		hdd_err("Failed to init PLD; errno:%d", errno);
19671 		goto wakelock_destroy;
19672 	}
19673 
19674 	/* driver mode pass to cnss2 platform driver*/
19675 	errno = pld_set_mode(con_mode);
19676 	if (errno)
19677 		hdd_err("Failed to set mode in PLD; errno:%d", errno);
19678 
19679 	hdd_driver_mode_change_register();
19680 
19681 	osif_driver_sync_register(driver_sync);
19682 	osif_driver_sync_trans_stop(driver_sync);
19683 
19684 	/* psoc probe can happen in registration; do after 'load' transition */
19685 	errno = hdd_register_driver_retry();
19686 	if (errno) {
19687 		hdd_err("Failed to register driver; errno:%d", errno);
19688 		goto pld_deinit;
19689 	}
19690 
19691 	/* If a soft unload of driver is done, we don't call
19692 	 * wlan_hdd_state_ctrl_param_destroy() to maintain sync
19693 	 * with userspace. In Symmetry, during soft load, avoid
19694 	 * calling wlan_hdd_state_ctrl_param_create().
19695 	 */
19696 	soft_load = hdd_get_wlan_driver_status();
19697 	if (soft_load)
19698 		goto out;
19699 
19700 	errno = wlan_hdd_state_ctrl_param_create();
19701 	if (errno) {
19702 		hdd_err("Failed to create ctrl param; errno:%d", errno);
19703 		goto unregister_driver;
19704 	}
19705 	hdd_create_wifi_feature_interface();
19706 out:
19707 	hdd_debug("%s: driver loaded", WLAN_MODULE_NAME);
19708 	hdd_place_marker(NULL, "DRIVER LOADED", NULL);
19709 
19710 	return 0;
19711 
19712 unregister_driver:
19713 	wlan_hdd_unregister_driver();
19714 pld_deinit:
19715 	status = osif_driver_sync_trans_start(&driver_sync);
19716 	QDF_BUG(QDF_IS_STATUS_SUCCESS(status));
19717 
19718 	osif_driver_sync_unregister();
19719 	if (driver_sync)
19720 		osif_driver_sync_wait_for_ops(driver_sync);
19721 
19722 	hdd_driver_mode_change_unregister();
19723 	pld_deinit();
19724 
19725 	hdd_start_complete(errno);
19726 	/* Wait for any ref taken on /dev/wlan to be released */
19727 	while (qdf_atomic_read(&wlan_hdd_state_fops_ref))
19728 		;
19729 wakelock_destroy:
19730 	qdf_wake_lock_destroy(&wlan_wake_lock);
19731 comp_deinit:
19732 	hdd_component_deinit();
19733 comp_cb_deinit:
19734 	hdd_component_cb_deinit();
19735 hdd_deinit:
19736 	hdd_deinit();
19737 trans_stop:
19738 	if (driver_sync) {
19739 		osif_driver_sync_trans_stop(driver_sync);
19740 		osif_driver_sync_destroy(driver_sync);
19741 	}
19742 sync_deinit:
19743 	osif_sync_deinit();
19744 	hdd_qdf_deinit();
19745 
19746 exit:
19747 	return errno;
19748 }
19749 
19750 #ifdef FEATURE_WLAN_RESIDENT_DRIVER
19751 EXPORT_SYMBOL(hdd_driver_load);
19752 #endif
19753 
19754 /**
19755  * hdd_distroy_wifi_feature_interface() - Distroy wifi feature interface
19756  *
19757  * Return: none
19758  */
19759 static void hdd_distroy_wifi_feature_interface(void)
19760 {
19761 	hdd_destroy_wifi_feature_interface_sysfs_file();
19762 	hdd_sysfs_destroy_wifi_root_obj();
19763 }
19764 
19765 void hdd_driver_unload(void)
19766 {
19767 	struct osif_driver_sync *driver_sync;
19768 	struct hdd_context *hdd_ctx;
19769 	QDF_STATUS status;
19770 	void *hif_ctx;
19771 	bool soft_unload;
19772 
19773 	soft_unload = hdd_get_wlan_driver_status();
19774 	if (soft_unload) {
19775 		pr_info("%s: Soft Unloading driver v%s\n", WLAN_MODULE_NAME,
19776 			QWLAN_VERSIONSTR);
19777 	} else {
19778 		pr_info("%s: Hard Unloading driver v%s\n", WLAN_MODULE_NAME,
19779 			QWLAN_VERSIONSTR);
19780 	}
19781 
19782 	hdd_place_marker(NULL, "START UNLOADING", NULL);
19783 
19784 	/*
19785 	 * Wait for any trans to complete and then start the driver trans
19786 	 * for the unload. This will ensure that the driver trans proceeds only
19787 	 * after all trans have been completed. As a part of this trans, set
19788 	 * the driver load/unload flag to further ensure that any upcoming
19789 	 * trans are rejected via wlan_hdd_validate_context.
19790 	 */
19791 	status = osif_driver_sync_trans_start_wait(&driver_sync);
19792 	QDF_BUG(QDF_IS_STATUS_SUCCESS(status));
19793 	if (QDF_IS_STATUS_ERROR(status)) {
19794 		hdd_err("Unable to unload wlan; status:%u", status);
19795 		hdd_place_marker(NULL, "UNLOAD FAILURE", NULL);
19796 		return;
19797 	}
19798 
19799 	hif_ctx = cds_get_context(QDF_MODULE_ID_HIF);
19800 	if (hif_ctx) {
19801 		/*
19802 		 * Trigger runtime sync resume before setting unload in progress
19803 		 * such that resume can happen successfully
19804 		 */
19805 		qdf_rtpm_sync_resume();
19806 	}
19807 
19808 	cds_set_driver_loaded(false);
19809 	cds_set_unload_in_progress(true);
19810 
19811 	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
19812 	if (hdd_ctx) {
19813 		hdd_psoc_idle_timer_stop(hdd_ctx);
19814 		/*
19815 		 * Runtime PM sync resume may have started the bus bandwidth
19816 		 * periodic work hence stop it.
19817 		 */
19818 		ucfg_dp_bus_bw_compute_timer_stop(hdd_ctx->psoc);
19819 	}
19820 
19821 	/*
19822 	 * Stop the trans before calling unregister_driver as that involves a
19823 	 * call to pld_remove which in itself is a psoc transaction
19824 	 */
19825 	osif_driver_sync_trans_stop(driver_sync);
19826 
19827 	hdd_distroy_wifi_feature_interface();
19828 	if (!soft_unload)
19829 		wlan_hdd_state_ctrl_param_destroy();
19830 
19831 	/* trigger SoC remove */
19832 	wlan_hdd_unregister_driver();
19833 
19834 	status = osif_driver_sync_trans_start_wait(&driver_sync);
19835 	QDF_BUG(QDF_IS_STATUS_SUCCESS(status));
19836 	if (QDF_IS_STATUS_ERROR(status)) {
19837 		hdd_err("Unable to unload wlan; status:%u", status);
19838 		hdd_place_marker(NULL, "UNLOAD FAILURE", NULL);
19839 		return;
19840 	}
19841 
19842 	osif_driver_sync_unregister();
19843 	osif_driver_sync_wait_for_ops(driver_sync);
19844 
19845 	hdd_driver_mode_change_unregister();
19846 	pld_deinit();
19847 	hdd_set_conparam(0);
19848 	qdf_wake_lock_destroy(&wlan_wake_lock);
19849 	hdd_component_deinit();
19850 	hdd_component_cb_deinit();
19851 	hdd_deinit();
19852 
19853 	osif_driver_sync_trans_stop(driver_sync);
19854 	osif_driver_sync_destroy(driver_sync);
19855 
19856 	osif_sync_deinit();
19857 
19858 	hdd_qdf_deinit();
19859 	hdd_place_marker(NULL, "UNLOAD DONE", NULL);
19860 }
19861 
19862 #ifdef FEATURE_WLAN_RESIDENT_DRIVER
19863 EXPORT_SYMBOL(hdd_driver_unload);
19864 #endif
19865 
19866 #ifndef MODULE
19867 /**
19868  * wlan_boot_cb() - Wlan boot callback
19869  * @kobj:      object whose directory we're creating the link in.
19870  * @attr:      attribute the user is interacting with
19871  * @buf:       the buffer containing the user data
19872  * @count:     number of bytes in the buffer
19873  *
19874  * This callback is invoked when the fs is ready to start the
19875  * wlan driver initialization.
19876  *
19877  * Return: 'count' on success or a negative error code in case of failure
19878  */
19879 static ssize_t wlan_boot_cb(struct kobject *kobj,
19880 			    struct kobj_attribute *attr,
19881 			    const char *buf,
19882 			    size_t count)
19883 {
19884 
19885 	if (wlan_loader->loaded_state) {
19886 		hdd_err("wlan driver already initialized");
19887 		return -EALREADY;
19888 	}
19889 
19890 	if (hdd_driver_load())
19891 		return -EIO;
19892 
19893 	wlan_loader->loaded_state = MODULE_INITIALIZED;
19894 
19895 	return count;
19896 }
19897 
19898 /**
19899  * hdd_sysfs_cleanup() - cleanup sysfs
19900  *
19901  * Return: None
19902  *
19903  */
19904 static void hdd_sysfs_cleanup(void)
19905 {
19906 	/* remove from group */
19907 	if (wlan_loader->boot_wlan_obj && wlan_loader->attr_group)
19908 		sysfs_remove_group(wlan_loader->boot_wlan_obj,
19909 				   wlan_loader->attr_group);
19910 
19911 	/* unlink the object from parent */
19912 	kobject_del(wlan_loader->boot_wlan_obj);
19913 
19914 	/* free the object */
19915 	kobject_put(wlan_loader->boot_wlan_obj);
19916 
19917 	kfree(wlan_loader->attr_group);
19918 	kfree(wlan_loader);
19919 
19920 	wlan_loader = NULL;
19921 }
19922 
19923 /**
19924  * wlan_init_sysfs() - Creates the sysfs to be invoked when the fs is
19925  * ready
19926  *
19927  * This is creates the syfs entry boot_wlan. Which shall be invoked
19928  * when the filesystem is ready.
19929  *
19930  * QDF API cannot be used here since this function is called even before
19931  * initializing WLAN driver.
19932  *
19933  * Return: 0 for success, errno on failure
19934  */
19935 static int wlan_init_sysfs(void)
19936 {
19937 	int ret = -ENOMEM;
19938 
19939 	wlan_loader = kzalloc(sizeof(*wlan_loader), GFP_KERNEL);
19940 	if (!wlan_loader)
19941 		return -ENOMEM;
19942 
19943 	wlan_loader->boot_wlan_obj = NULL;
19944 	wlan_loader->attr_group = kzalloc(sizeof(*(wlan_loader->attr_group)),
19945 					  GFP_KERNEL);
19946 	if (!wlan_loader->attr_group)
19947 		goto error_return;
19948 
19949 	wlan_loader->loaded_state = 0;
19950 	wlan_loader->attr_group->attrs = attrs;
19951 
19952 	wlan_loader->boot_wlan_obj = kobject_create_and_add(WLAN_LOADER_NAME,
19953 							    kernel_kobj);
19954 	if (!wlan_loader->boot_wlan_obj) {
19955 		hdd_err("sysfs create and add failed");
19956 		goto error_return;
19957 	}
19958 
19959 	ret = sysfs_create_group(wlan_loader->boot_wlan_obj,
19960 				 wlan_loader->attr_group);
19961 	if (ret) {
19962 		hdd_err("sysfs create group failed; errno:%d", ret);
19963 		goto error_return;
19964 	}
19965 
19966 	return 0;
19967 
19968 error_return:
19969 	hdd_sysfs_cleanup();
19970 
19971 	return ret;
19972 }
19973 
19974 /**
19975  * wlan_deinit_sysfs() - Removes the sysfs created to initialize the wlan
19976  *
19977  * Return: 0 on success or errno on failure
19978  */
19979 static int wlan_deinit_sysfs(void)
19980 {
19981 	if (!wlan_loader) {
19982 		hdd_err("wlan_loader is null");
19983 		return -EINVAL;
19984 	}
19985 
19986 	hdd_sysfs_cleanup();
19987 	return 0;
19988 }
19989 
19990 #endif /* MODULE */
19991 
19992 #ifdef MODULE
19993 /**
19994  * hdd_module_init() - Module init helper
19995  *
19996  * Module init helper function used by both module and static driver.
19997  *
19998  * Return: 0 for success, errno on failure
19999  */
20000 #ifdef FEATURE_WLAN_RESIDENT_DRIVER
20001 static int hdd_module_init(void)
20002 {
20003 	return 0;
20004 }
20005 #else
20006 static int hdd_module_init(void)
20007 {
20008 	if (hdd_driver_load())
20009 		return -EINVAL;
20010 
20011 	return 0;
20012 }
20013 #endif
20014 #else
20015 static int __init hdd_module_init(void)
20016 {
20017 	int ret = -EINVAL;
20018 
20019 	ret = wlan_init_sysfs();
20020 	if (ret)
20021 		hdd_err("Failed to create sysfs entry");
20022 
20023 	return ret;
20024 }
20025 #endif
20026 
20027 
20028 #ifdef MODULE
20029 /**
20030  * hdd_module_exit() - Exit function
20031  *
20032  * This is the driver exit point (invoked when module is unloaded using rmmod)
20033  *
20034  * Return: None
20035  */
20036 #ifdef FEATURE_WLAN_RESIDENT_DRIVER
20037 static void __exit hdd_module_exit(void)
20038 {
20039 }
20040 #else
20041 static void __exit hdd_module_exit(void)
20042 {
20043 	hdd_driver_unload();
20044 }
20045 #endif
20046 #else
20047 static void __exit hdd_module_exit(void)
20048 {
20049 	hdd_driver_unload();
20050 	wlan_deinit_sysfs();
20051 }
20052 #endif
20053 
20054 static int fwpath_changed_handler(const char *kmessage,
20055 				  const struct kernel_param *kp)
20056 {
20057 	return param_set_copystring(kmessage, kp);
20058 }
20059 
20060 static int con_mode_handler_ftm(const char *kmessage,
20061 				const struct kernel_param *kp)
20062 {
20063 	int ret;
20064 
20065 	ret = param_set_int(kmessage, kp);
20066 
20067 	if (cds_is_driver_loaded() || cds_is_load_or_unload_in_progress()) {
20068 		pr_err("Driver already loaded or load/unload in progress");
20069 		return -ENOTSUPP;
20070 	}
20071 
20072 	if (con_mode_ftm != QDF_GLOBAL_FTM_MODE) {
20073 		pr_err("Only FTM mode supported!");
20074 		return -ENOTSUPP;
20075 	}
20076 
20077 	hdd_set_conparam(con_mode_ftm);
20078 	con_mode = con_mode_ftm;
20079 
20080 	return ret;
20081 }
20082 
20083 #ifdef WLAN_FEATURE_EPPING
20084 static int con_mode_handler_epping(const char *kmessage,
20085 				   const struct kernel_param *kp)
20086 {
20087 	int ret;
20088 
20089 	ret = param_set_int(kmessage, kp);
20090 
20091 	if (con_mode_epping != QDF_GLOBAL_EPPING_MODE) {
20092 		pr_err("Only EPPING mode supported!");
20093 		return -ENOTSUPP;
20094 	}
20095 
20096 	hdd_set_conparam(con_mode_epping);
20097 	con_mode = con_mode_epping;
20098 
20099 	return ret;
20100 }
20101 #endif
20102 
20103 /**
20104  * hdd_get_conparam() - driver exit point
20105  *
20106  * This is the driver exit point (invoked when module is unloaded using rmmod)
20107  *
20108  * Return: enum QDF_GLOBAL_MODE
20109  */
20110 enum QDF_GLOBAL_MODE hdd_get_conparam(void)
20111 {
20112 	return (enum QDF_GLOBAL_MODE) curr_con_mode;
20113 }
20114 
20115 void hdd_set_conparam(int32_t con_param)
20116 {
20117 	curr_con_mode = con_param;
20118 }
20119 
20120 /**
20121  * hdd_svc_fw_crashed_ind() - API to send FW CRASHED IND to Userspace
20122  *
20123  * Return: void
20124  */
20125 static void hdd_svc_fw_crashed_ind(void)
20126 {
20127 	struct hdd_context *hdd_ctx;
20128 
20129 	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
20130 
20131 	hdd_ctx ? wlan_hdd_send_svc_nlink_msg(hdd_ctx->radio_index,
20132 					      WLAN_SVC_FW_CRASHED_IND,
20133 					      NULL, 0) : 0;
20134 }
20135 
20136 /**
20137  * hdd_update_ol_config - API to update ol configuration parameters
20138  * @hdd_ctx: HDD context
20139  *
20140  * Return: void
20141  */
20142 static void hdd_update_ol_config(struct hdd_context *hdd_ctx)
20143 {
20144 	struct ol_config_info cfg = {0};
20145 	struct ol_context *ol_ctx = cds_get_context(QDF_MODULE_ID_BMI);
20146 	bool self_recovery = false;
20147 	QDF_STATUS status;
20148 
20149 	if (!ol_ctx)
20150 		return;
20151 
20152 	status = ucfg_mlme_get_self_recovery(hdd_ctx->psoc, &self_recovery);
20153 	if (QDF_IS_STATUS_ERROR(status))
20154 		hdd_err("Failed to get self recovery ini config");
20155 
20156 	cfg.enable_self_recovery = self_recovery;
20157 	cfg.enable_uart_print = hdd_ctx->config->enablefwprint;
20158 	cfg.enable_fw_log = hdd_ctx->config->enable_fw_log;
20159 	cfg.enable_ramdump_collection = hdd_ctx->config->is_ramdump_enabled;
20160 	cfg.enable_lpass_support = hdd_lpass_is_supported(hdd_ctx);
20161 
20162 	ol_init_ini_config(ol_ctx, &cfg);
20163 	ol_set_fw_crashed_cb(ol_ctx, hdd_svc_fw_crashed_ind);
20164 }
20165 
20166 #ifdef FEATURE_RUNTIME_PM
20167 /**
20168  * hdd_populate_runtime_cfg() - populate runtime configuration
20169  * @hdd_ctx: hdd context
20170  * @cfg: pointer to the configuration memory being populated
20171  *
20172  * Return: void
20173  */
20174 static void hdd_populate_runtime_cfg(struct hdd_context *hdd_ctx,
20175 				     struct hif_config_info *cfg)
20176 {
20177 	cfg->enable_runtime_pm = hdd_ctx->config->runtime_pm;
20178 	cfg->runtime_pm_delay =
20179 		ucfg_pmo_get_runtime_pm_delay(hdd_ctx->psoc);
20180 }
20181 #else
20182 static void hdd_populate_runtime_cfg(struct hdd_context *hdd_ctx,
20183 				     struct hif_config_info *cfg)
20184 {
20185 }
20186 #endif
20187 
20188 /**
20189  * hdd_update_hif_config - API to update HIF configuration parameters
20190  * @hdd_ctx: HDD Context
20191  *
20192  * Return: void
20193  */
20194 static void hdd_update_hif_config(struct hdd_context *hdd_ctx)
20195 {
20196 	struct hif_opaque_softc *scn = cds_get_context(QDF_MODULE_ID_HIF);
20197 	struct hif_config_info cfg = {0};
20198 	bool prevent_link_down = false;
20199 	bool self_recovery = false;
20200 	QDF_STATUS status;
20201 
20202 	if (!scn)
20203 		return;
20204 
20205 	status = ucfg_mlme_get_prevent_link_down(hdd_ctx->psoc,
20206 						 &prevent_link_down);
20207 	if (QDF_IS_STATUS_ERROR(status))
20208 		hdd_err("Failed to get prevent_link_down config");
20209 
20210 	status = ucfg_mlme_get_self_recovery(hdd_ctx->psoc, &self_recovery);
20211 	if (QDF_IS_STATUS_ERROR(status))
20212 		hdd_err("Failed to get self recovery ini config");
20213 
20214 	cfg.enable_self_recovery = self_recovery;
20215 	hdd_populate_runtime_cfg(hdd_ctx, &cfg);
20216 	cfg.rx_softirq_max_yield_duration_ns =
20217 		ucfg_dp_get_rx_softirq_yield_duration(hdd_ctx->psoc);
20218 
20219 	hif_init_ini_config(scn, &cfg);
20220 
20221 	if (prevent_link_down)
20222 		hif_vote_link_up(scn);
20223 }
20224 
20225 /**
20226  * hdd_update_dp_config() - Propagate config parameters to Lithium
20227  *                          datapath
20228  * @hdd_ctx: HDD Context
20229  *
20230  * Return: 0 for success/errno for failure
20231  */
20232 static int hdd_update_dp_config(struct hdd_context *hdd_ctx)
20233 {
20234 	struct wlan_dp_user_config dp_cfg;
20235 	QDF_STATUS status;
20236 
20237 	dp_cfg.ipa_enable = ucfg_ipa_is_enabled();
20238 	dp_cfg.arp_connectivity_map = CONNECTIVITY_CHECK_SET_ARP;
20239 
20240 	status = ucfg_dp_update_config(hdd_ctx->psoc, &dp_cfg);
20241 	if (status != QDF_STATUS_SUCCESS) {
20242 		hdd_err("failed DP PSOC configuration update");
20243 		return -EINVAL;
20244 	}
20245 
20246 	return 0;
20247 }
20248 
20249 /**
20250  * hdd_update_config() - Initialize driver per module ini parameters
20251  * @hdd_ctx: HDD Context
20252  *
20253  * API is used to initialize all driver per module configuration parameters
20254  * Return: 0 for success, errno for failure
20255  */
20256 int hdd_update_config(struct hdd_context *hdd_ctx)
20257 {
20258 	int ret;
20259 
20260 	if (ucfg_pmo_is_ns_offloaded(hdd_ctx->psoc))
20261 		hdd_ctx->ns_offload_enable = true;
20262 
20263 	hdd_update_ol_config(hdd_ctx);
20264 	hdd_update_hif_config(hdd_ctx);
20265 	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam())
20266 		ret = hdd_update_cds_config_ftm(hdd_ctx);
20267 	else
20268 		ret = hdd_update_cds_config(hdd_ctx);
20269 	ret = hdd_update_user_config(hdd_ctx);
20270 
20271 	hdd_update_regdb_offload_config(hdd_ctx);
20272 
20273 	return ret;
20274 }
20275 
20276 /**
20277  * hdd_update_pmo_config - API to update pmo configuration parameters
20278  * @hdd_ctx: HDD context
20279  *
20280  * Return: void
20281  */
20282 static int hdd_update_pmo_config(struct hdd_context *hdd_ctx)
20283 {
20284 	struct pmo_psoc_cfg psoc_cfg = {0};
20285 	QDF_STATUS status;
20286 	enum pmo_wow_enable_type wow_enable;
20287 
20288 	ucfg_pmo_get_psoc_config(hdd_ctx->psoc, &psoc_cfg);
20289 
20290 	/*
20291 	 * Value of hdd_ctx->wowEnable can be,
20292 	 * 0 - Disable both magic pattern match and pattern byte match.
20293 	 * 1 - Enable magic pattern match on all interfaces.
20294 	 * 2 - Enable pattern byte match on all interfaces.
20295 	 * 3 - Enable both magic pattern and pattern byte match on
20296 	 *     all interfaces.
20297 	 */
20298 	wow_enable = ucfg_pmo_get_wow_enable(hdd_ctx->psoc);
20299 	psoc_cfg.magic_ptrn_enable = (wow_enable & 0x01) ? true : false;
20300 	psoc_cfg.ptrn_match_enable_all_vdev =
20301 				(wow_enable & 0x02) ? true : false;
20302 	psoc_cfg.ap_arpns_support = hdd_ctx->ap_arpns_support;
20303 	psoc_cfg.d0_wow_supported = wma_d0_wow_is_supported();
20304 	ucfg_mlme_get_sap_max_modulated_dtim(hdd_ctx->psoc,
20305 					     &psoc_cfg.sta_max_li_mod_dtim);
20306 
20307 	hdd_lpass_populate_pmo_config(&psoc_cfg, hdd_ctx);
20308 
20309 	status = ucfg_pmo_update_psoc_config(hdd_ctx->psoc, &psoc_cfg);
20310 	if (QDF_IS_STATUS_ERROR(status))
20311 		hdd_err("failed pmo psoc configuration; status:%d", status);
20312 
20313 	return qdf_status_to_os_return(status);
20314 }
20315 
20316 void hdd_update_ie_allowlist_attr(struct probe_req_allowlist_attr *ie_allowlist,
20317 				  struct hdd_context *hdd_ctx)
20318 {
20319 	struct wlan_fwol_ie_allowlist allowlist = {0};
20320 	struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc;
20321 	QDF_STATUS status;
20322 	bool is_ie_allowlist_enable = false;
20323 	uint8_t i = 0;
20324 
20325 	status = ucfg_fwol_get_ie_allowlist(psoc, &is_ie_allowlist_enable);
20326 	if (QDF_IS_STATUS_ERROR(status)) {
20327 		hdd_err("Unable to get IE allowlist param");
20328 		return;
20329 	}
20330 
20331 	ie_allowlist->allow_list = is_ie_allowlist_enable;
20332 	if (!ie_allowlist->allow_list)
20333 		return;
20334 
20335 	status = ucfg_fwol_get_all_allowlist_params(psoc, &allowlist);
20336 	if (QDF_IS_STATUS_ERROR(status)) {
20337 		hdd_err("Unable to get all allowlist params");
20338 		return;
20339 	}
20340 
20341 	ie_allowlist->ie_bitmap[0] = allowlist.ie_bitmap_0;
20342 	ie_allowlist->ie_bitmap[1] = allowlist.ie_bitmap_1;
20343 	ie_allowlist->ie_bitmap[2] = allowlist.ie_bitmap_2;
20344 	ie_allowlist->ie_bitmap[3] = allowlist.ie_bitmap_3;
20345 	ie_allowlist->ie_bitmap[4] = allowlist.ie_bitmap_4;
20346 	ie_allowlist->ie_bitmap[5] = allowlist.ie_bitmap_5;
20347 	ie_allowlist->ie_bitmap[6] = allowlist.ie_bitmap_6;
20348 	ie_allowlist->ie_bitmap[7] = allowlist.ie_bitmap_7;
20349 
20350 	ie_allowlist->num_vendor_oui = allowlist.no_of_probe_req_ouis;
20351 	for (i = 0; i < ie_allowlist->num_vendor_oui; i++)
20352 		ie_allowlist->voui[i] = allowlist.probe_req_voui[i];
20353 }
20354 
20355 QDF_STATUS hdd_update_score_config(struct hdd_context *hdd_ctx)
20356 {
20357 	struct hdd_config *cfg = hdd_ctx->config;
20358 	eCsrPhyMode phy_mode = hdd_cfg_xlate_to_csr_phy_mode(cfg->dot11Mode);
20359 
20360 	sme_update_score_config(hdd_ctx->mac_handle, phy_mode,
20361 				hdd_ctx->num_rf_chains);
20362 
20363 	return QDF_STATUS_SUCCESS;
20364 }
20365 
20366 /**
20367  * hdd_update_dfs_config() - API to update dfs configuration parameters.
20368  * @hdd_ctx: HDD context
20369  *
20370  * Return: 0 if success else err
20371  */
20372 static int hdd_update_dfs_config(struct hdd_context *hdd_ctx)
20373 {
20374 	struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc;
20375 	struct dfs_user_config dfs_cfg = {0};
20376 	QDF_STATUS status;
20377 
20378 	ucfg_mlme_get_dfs_filter_offload(hdd_ctx->psoc,
20379 					 &dfs_cfg.dfs_is_phyerr_filter_offload);
20380 	status = ucfg_dfs_update_config(psoc, &dfs_cfg);
20381 	if (QDF_IS_STATUS_ERROR(status)) {
20382 		hdd_err("failed dfs psoc configuration");
20383 		return -EINVAL;
20384 	}
20385 
20386 	return 0;
20387 }
20388 
20389 /**
20390  * hdd_update_scan_config - API to update scan configuration parameters
20391  * @hdd_ctx: HDD context
20392  *
20393  * Return: 0 if success else err
20394  */
20395 int hdd_update_scan_config(struct hdd_context *hdd_ctx)
20396 {
20397 	struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc;
20398 	struct scan_user_cfg scan_cfg;
20399 	QDF_STATUS status;
20400 	uint32_t mcast_mcc_rest_time = 0;
20401 
20402 	qdf_mem_zero(&scan_cfg, sizeof(scan_cfg));
20403 	status = ucfg_mlme_get_sta_miracast_mcc_rest_time(hdd_ctx->psoc,
20404 							  &mcast_mcc_rest_time);
20405 	if (!QDF_IS_STATUS_SUCCESS(status)) {
20406 		hdd_err("ucfg_mlme_get_sta_miracast_mcc_rest_time, use def");
20407 		return -EIO;
20408 	}
20409 	scan_cfg.sta_miracast_mcc_rest_time = mcast_mcc_rest_time;
20410 	hdd_update_ie_allowlist_attr(&scan_cfg.ie_allowlist, hdd_ctx);
20411 
20412 	status = ucfg_scan_update_user_config(psoc, &scan_cfg);
20413 	if (status != QDF_STATUS_SUCCESS) {
20414 		hdd_err("failed pmo psoc configuration");
20415 		return -EINVAL;
20416 	}
20417 
20418 	return 0;
20419 }
20420 
20421 int hdd_update_components_config(struct hdd_context *hdd_ctx)
20422 {
20423 	int ret;
20424 
20425 	ret = hdd_update_pmo_config(hdd_ctx);
20426 	if (ret)
20427 		return ret;
20428 
20429 	ret = hdd_update_scan_config(hdd_ctx);
20430 	if (ret)
20431 		return ret;
20432 
20433 	ret = hdd_update_tdls_config(hdd_ctx);
20434 	if (ret)
20435 		return ret;
20436 
20437 	ret = hdd_update_dp_config(hdd_ctx);
20438 	if (ret)
20439 		return ret;
20440 
20441 	ret = hdd_update_dfs_config(hdd_ctx);
20442 	if (ret)
20443 		return ret;
20444 
20445 	ret = hdd_update_regulatory_config(hdd_ctx);
20446 	if (ret)
20447 		return ret;
20448 
20449 	return ret;
20450 }
20451 
20452 /**
20453  * wlan_hdd_get_dfs_mode() - get ACS DFS mode
20454  * @mode : cfg80211 DFS mode
20455  *
20456  * Return: return SAP ACS DFS mode else return ACS_DFS_MODE_NONE
20457  */
20458 enum  sap_acs_dfs_mode wlan_hdd_get_dfs_mode(enum dfs_mode mode)
20459 {
20460 	switch (mode) {
20461 	case DFS_MODE_ENABLE:
20462 		return ACS_DFS_MODE_ENABLE;
20463 	case DFS_MODE_DISABLE:
20464 		return ACS_DFS_MODE_DISABLE;
20465 	case DFS_MODE_DEPRIORITIZE:
20466 		return ACS_DFS_MODE_DEPRIORITIZE;
20467 	default:
20468 		hdd_debug("ACS dfs mode is NONE");
20469 		return ACS_DFS_MODE_NONE;
20470 	}
20471 }
20472 
20473 /**
20474  * hdd_enable_disable_ca_event() - enable/disable channel avoidance event
20475  * @hdd_ctx: pointer to hdd context
20476  * @set_value: enable/disable
20477  *
20478  * When Host sends vendor command enable, FW will send *ONE* CA ind to
20479  * Host(even though it is duplicate). When Host send vendor command
20480  * disable,FW doesn't perform any action. Whenever any change in
20481  * CA *and* WLAN is in SAP/P2P-GO mode, FW sends CA ind to host.
20482  *
20483  * return - 0 on success, appropriate error values on failure.
20484  */
20485 int hdd_enable_disable_ca_event(struct hdd_context *hdd_ctx, uint8_t set_value)
20486 {
20487 	QDF_STATUS status;
20488 
20489 	if (0 != wlan_hdd_validate_context(hdd_ctx))
20490 		return -EAGAIN;
20491 
20492 	status = sme_enable_disable_chanavoidind_event(hdd_ctx->mac_handle,
20493 						       set_value);
20494 	if (!QDF_IS_STATUS_SUCCESS(status)) {
20495 		hdd_err("Failed to send chan avoid command to SME");
20496 		return -EINVAL;
20497 	}
20498 	return 0;
20499 }
20500 
20501 bool hdd_is_roaming_in_progress(struct hdd_context *hdd_ctx)
20502 {
20503 	struct hdd_adapter *adapter = NULL, *next_adapter = NULL;
20504 	uint8_t vdev_id;
20505 	wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_IS_ROAMING_IN_PROGRESS;
20506 	struct wlan_hdd_link_info *link_info;
20507 
20508 	if (!hdd_ctx) {
20509 		hdd_err("HDD context is NULL");
20510 		return false;
20511 	}
20512 
20513 	if (!policy_mgr_is_sta_active_connection_exists(hdd_ctx->psoc))
20514 		return false;
20515 
20516 	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
20517 					   dbgid) {
20518 		if (adapter->device_mode != QDF_STA_MODE)
20519 			goto adapter_put;
20520 
20521 		hdd_adapter_for_each_active_link_info(adapter, link_info) {
20522 			vdev_id = link_info->vdev_id;
20523 			if (test_bit(SME_SESSION_OPENED,
20524 				     &link_info->link_flags) &&
20525 			    sme_roaming_in_progress(hdd_ctx->mac_handle,
20526 						    vdev_id)) {
20527 				hdd_debug("Roaming is in progress on:vdev_id:%d",
20528 					  link_info->vdev_id);
20529 				hdd_adapter_dev_put_debug(adapter, dbgid);
20530 				if (next_adapter)
20531 					hdd_adapter_dev_put_debug(next_adapter,
20532 								  dbgid);
20533 				return true;
20534 			}
20535 		}
20536 adapter_put:
20537 		hdd_adapter_dev_put_debug(adapter, dbgid);
20538 	}
20539 
20540 	return false;
20541 }
20542 
20543 /**
20544  * struct hdd_is_connection_in_progress_priv - adapter connection info
20545  * @out_vdev_id: id of vdev where connection is occurring
20546  * @out_reason: scan reject reason
20547  * @connection_in_progress: true if connection is in progress
20548  */
20549 struct hdd_is_connection_in_progress_priv {
20550 	uint8_t out_vdev_id;
20551 	enum scan_reject_states out_reason;
20552 	bool connection_in_progress;
20553 };
20554 
20555 /**
20556  * hdd_is_connection_in_progress_iterator() - Check adapter connection based
20557  * on device mode
20558  * @link_info: Link info pointer in HDD adapter
20559  * @ctx: user context supplied
20560  *
20561  * Check if connection is in progress for the current adapter according to the
20562  * device mode
20563  *
20564  * Return:
20565  * * QDF_STATUS_SUCCESS if iteration should continue
20566  * * QDF_STATUS_E_ABORTED if iteration should be aborted
20567  */
20568 static QDF_STATUS
20569 hdd_is_connection_in_progress_iterator(struct wlan_hdd_link_info *link_info,
20570 				       void *ctx)
20571 {
20572 	struct hdd_station_ctx *hdd_sta_ctx;
20573 	uint8_t *sta_mac;
20574 	struct hdd_context *hdd_ctx;
20575 	mac_handle_t mac_handle;
20576 	struct hdd_station_info *sta_info, *tmp = NULL;
20577 	struct hdd_is_connection_in_progress_priv *context = ctx;
20578 	struct hdd_adapter *adapter = link_info->adapter;
20579 
20580 	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
20581 	if (!hdd_ctx)
20582 		return QDF_STATUS_E_ABORTED;
20583 
20584 	mac_handle = hdd_ctx->mac_handle;
20585 
20586 	if (!test_bit(SME_SESSION_OPENED, &link_info->link_flags) &&
20587 	    (adapter->device_mode == QDF_STA_MODE ||
20588 	     adapter->device_mode == QDF_P2P_CLIENT_MODE ||
20589 	     adapter->device_mode == QDF_P2P_DEVICE_MODE ||
20590 	     adapter->device_mode == QDF_P2P_GO_MODE ||
20591 	     adapter->device_mode == QDF_SAP_MODE))
20592 		return QDF_STATUS_SUCCESS;
20593 
20594 	if ((QDF_STA_MODE == adapter->device_mode ||
20595 	     QDF_P2P_CLIENT_MODE == adapter->device_mode ||
20596 	     QDF_P2P_DEVICE_MODE == adapter->device_mode) &&
20597 	    hdd_cm_is_connecting(link_info)) {
20598 		hdd_debug("%pK(%d) mode %d Connection is in progress",
20599 			  WLAN_HDD_GET_STATION_CTX_PTR(link_info),
20600 			  link_info->vdev_id, adapter->device_mode);
20601 
20602 		context->out_vdev_id = link_info->vdev_id;
20603 		context->out_reason = CONNECTION_IN_PROGRESS;
20604 		context->connection_in_progress = true;
20605 
20606 		return QDF_STATUS_E_ABORTED;
20607 	}
20608 
20609 	if ((QDF_STA_MODE == adapter->device_mode) &&
20610 	     sme_roaming_in_progress(mac_handle, link_info->vdev_id)) {
20611 		hdd_debug("%pK(%d) mode %d Reassociation in progress",
20612 			  WLAN_HDD_GET_STATION_CTX_PTR(link_info),
20613 			  link_info->vdev_id, adapter->device_mode);
20614 
20615 		context->out_vdev_id = link_info->vdev_id;
20616 		context->out_reason = REASSOC_IN_PROGRESS;
20617 		context->connection_in_progress = true;
20618 		return QDF_STATUS_E_ABORTED;
20619 	}
20620 
20621 	if ((QDF_STA_MODE == adapter->device_mode) ||
20622 		(QDF_P2P_CLIENT_MODE == adapter->device_mode) ||
20623 		(QDF_P2P_DEVICE_MODE == adapter->device_mode)) {
20624 		hdd_sta_ctx =
20625 			WLAN_HDD_GET_STATION_CTX_PTR(link_info);
20626 		if (hdd_cm_is_vdev_associated(link_info)
20627 		    && sme_is_sta_key_exchange_in_progress(
20628 		    mac_handle, link_info->vdev_id)) {
20629 			sta_mac = (uint8_t *)&(adapter->mac_addr.bytes[0]);
20630 			hdd_debug("client " QDF_MAC_ADDR_FMT
20631 				  " is in middle of WPS/EAPOL exchange.",
20632 				  QDF_MAC_ADDR_REF(sta_mac));
20633 
20634 			context->out_vdev_id = link_info->vdev_id;
20635 			context->out_reason = EAPOL_IN_PROGRESS;
20636 			context->connection_in_progress = true;
20637 
20638 			return QDF_STATUS_E_ABORTED;
20639 		}
20640 	} else if ((QDF_SAP_MODE == adapter->device_mode) ||
20641 			(QDF_P2P_GO_MODE == adapter->device_mode)) {
20642 		hdd_for_each_sta_ref_safe(adapter->sta_info_list, sta_info, tmp,
20643 				     STA_INFO_CONNECTION_IN_PROGRESS_ITERATOR) {
20644 			if (sta_info->peer_state !=
20645 				OL_TXRX_PEER_STATE_CONN) {
20646 				hdd_put_sta_info_ref(
20647 				     &adapter->sta_info_list, &sta_info, true,
20648 				     STA_INFO_CONNECTION_IN_PROGRESS_ITERATOR);
20649 				continue;
20650 			}
20651 
20652 			sta_mac = sta_info->sta_mac.bytes;
20653 			hdd_debug("client " QDF_MAC_ADDR_FMT
20654 				  " of SAP/GO is in middle of WPS/EAPOL exchange",
20655 				  QDF_MAC_ADDR_REF(sta_mac));
20656 
20657 			context->out_vdev_id = link_info->vdev_id;
20658 			context->out_reason = SAP_EAPOL_IN_PROGRESS;
20659 			context->connection_in_progress = true;
20660 
20661 			hdd_put_sta_info_ref(
20662 				&adapter->sta_info_list, &sta_info, true,
20663 				STA_INFO_CONNECTION_IN_PROGRESS_ITERATOR);
20664 			if (tmp)
20665 				hdd_put_sta_info_ref(
20666 				    &adapter->sta_info_list, &tmp, true,
20667 				    STA_INFO_CONNECTION_IN_PROGRESS_ITERATOR);
20668 
20669 			return QDF_STATUS_E_ABORTED;
20670 		}
20671 		if (hdd_ctx->connection_in_progress) {
20672 			hdd_debug("AP/GO: vdev %d connection is in progress",
20673 				  link_info->vdev_id);
20674 			context->out_reason = SAP_CONNECTION_IN_PROGRESS;
20675 			context->out_vdev_id = link_info->vdev_id;
20676 			context->connection_in_progress = true;
20677 
20678 			return QDF_STATUS_E_ABORTED;
20679 		}
20680 	}
20681 
20682 	if (ucfg_nan_is_enable_disable_in_progress(hdd_ctx->psoc)) {
20683 		context->out_reason = NAN_ENABLE_DISABLE_IN_PROGRESS;
20684 		context->out_vdev_id = NAN_PSEUDO_VDEV_ID;
20685 		context->connection_in_progress = true;
20686 
20687 		return QDF_STATUS_E_ABORTED;
20688 	}
20689 
20690 	return QDF_STATUS_SUCCESS;
20691 }
20692 
20693 bool hdd_is_connection_in_progress(uint8_t *out_vdev_id,
20694 				   enum scan_reject_states *out_reason)
20695 {
20696 	struct hdd_is_connection_in_progress_priv hdd_conn;
20697 	hdd_adapter_iterate_cb cb;
20698 
20699 	hdd_conn.out_vdev_id = 0;
20700 	hdd_conn.out_reason = SCAN_REJECT_DEFAULT;
20701 	hdd_conn.connection_in_progress = false;
20702 
20703 	cb = hdd_is_connection_in_progress_iterator;
20704 
20705 	hdd_adapter_iterate(cb, &hdd_conn);
20706 
20707 	if (hdd_conn.connection_in_progress && out_vdev_id && out_reason) {
20708 		*out_vdev_id = hdd_conn.out_vdev_id;
20709 		*out_reason = hdd_conn.out_reason;
20710 	}
20711 
20712 	return hdd_conn.connection_in_progress;
20713 }
20714 
20715 void hdd_restart_sap(struct wlan_hdd_link_info *link_info)
20716 {
20717 	struct hdd_hostapd_state *hapd_state;
20718 	QDF_STATUS status;
20719 	struct hdd_adapter *ap_adapter = link_info->adapter;
20720 	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(ap_adapter);
20721 	struct sap_config *sap_config;
20722 	void *sap_ctx;
20723 
20724 	sap_config =
20725 		&(WLAN_HDD_GET_AP_CTX_PTR(link_info)->sap_config);
20726 	sap_ctx = WLAN_HDD_GET_SAP_CTX_PTR(link_info);
20727 
20728 	mutex_lock(&hdd_ctx->sap_lock);
20729 	if (test_bit(SOFTAP_BSS_STARTED, &link_info->link_flags)) {
20730 		wlan_hdd_del_station(ap_adapter, NULL);
20731 		hapd_state = WLAN_HDD_GET_HOSTAP_STATE_PTR(link_info);
20732 		qdf_event_reset(&hapd_state->qdf_stop_bss_event);
20733 		if (QDF_STATUS_SUCCESS == wlansap_stop_bss(sap_ctx)) {
20734 			status = qdf_wait_single_event(&hapd_state->qdf_stop_bss_event,
20735 						       SME_CMD_STOP_BSS_TIMEOUT);
20736 
20737 			if (!QDF_IS_STATUS_SUCCESS(status)) {
20738 				hdd_err("SAP Stop Failed");
20739 				goto end;
20740 			}
20741 		}
20742 		clear_bit(SOFTAP_BSS_STARTED, &link_info->link_flags);
20743 		policy_mgr_decr_session_set_pcl(hdd_ctx->psoc,
20744 			ap_adapter->device_mode, link_info->vdev_id);
20745 		hdd_green_ap_start_state_mc(hdd_ctx, ap_adapter->device_mode,
20746 					    false);
20747 		hdd_err("SAP Stop Success");
20748 
20749 		if (0 != wlan_hdd_cfg80211_update_apies(link_info)) {
20750 			hdd_err("SAP Not able to set AP IEs");
20751 			goto end;
20752 		}
20753 
20754 		status = wlan_hdd_mlo_sap_reinit(link_info);
20755 		if (QDF_IS_STATUS_ERROR(status)) {
20756 			hdd_err("SAP Not able to do mlo attach");
20757 			goto deinit_mlo;
20758 		}
20759 
20760 		qdf_event_reset(&hapd_state->qdf_event);
20761 		status = wlansap_start_bss(sap_ctx, hdd_hostapd_sap_event_cb,
20762 					   sap_config, ap_adapter->dev);
20763 		if (QDF_IS_STATUS_ERROR(status)) {
20764 			hdd_err("SAP Start Bss fail");
20765 			goto deinit_mlo;
20766 		}
20767 
20768 		hdd_info("Waiting for SAP to start");
20769 		status = qdf_wait_single_event(&hapd_state->qdf_event,
20770 					       SME_CMD_START_BSS_TIMEOUT);
20771 		if (!QDF_IS_STATUS_SUCCESS(status)) {
20772 			hdd_err("SAP Start failed");
20773 			goto deinit_mlo;
20774 		}
20775 		wlansap_reset_sap_config_add_ie(sap_config, eUPDATE_IE_ALL);
20776 		hdd_err("SAP Start Success");
20777 		set_bit(SOFTAP_BSS_STARTED, &link_info->link_flags);
20778 		if (hapd_state->bss_state == BSS_START) {
20779 			policy_mgr_incr_active_session(hdd_ctx->psoc,
20780 						ap_adapter->device_mode,
20781 						link_info->vdev_id);
20782 			hdd_green_ap_start_state_mc(hdd_ctx,
20783 						    ap_adapter->device_mode,
20784 						    true);
20785 		}
20786 	}
20787 	mutex_unlock(&hdd_ctx->sap_lock);
20788 	return;
20789 
20790 deinit_mlo:
20791 	wlan_hdd_mlo_reset(link_info);
20792 end:
20793 	wlansap_reset_sap_config_add_ie(sap_config, eUPDATE_IE_ALL);
20794 	mutex_unlock(&hdd_ctx->sap_lock);
20795 }
20796 
20797 /**
20798  * hdd_set_connection_in_progress() - to set the connection in
20799  * progress flag
20800  * @value: value to set
20801  *
20802  * This function will set the passed value to connection in progress flag.
20803  * If value is previously being set to true then no need to set it again.
20804  *
20805  * Return: true if value is being set correctly and false otherwise.
20806  */
20807 bool hdd_set_connection_in_progress(bool value)
20808 {
20809 	bool status = true;
20810 	struct hdd_context *hdd_ctx;
20811 
20812 	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
20813 	if (!hdd_ctx)
20814 		return false;
20815 
20816 	qdf_spin_lock(&hdd_ctx->connection_status_lock);
20817 	/*
20818 	 * if the value is set to true previously and if someone is
20819 	 * trying to make it true again then it could be some race
20820 	 * condition being triggered. Avoid this situation by returning
20821 	 * false
20822 	 */
20823 	if (hdd_ctx->connection_in_progress && value)
20824 		status = false;
20825 	else
20826 		hdd_ctx->connection_in_progress = value;
20827 	qdf_spin_unlock(&hdd_ctx->connection_status_lock);
20828 	return status;
20829 }
20830 
20831 int wlan_hdd_send_mcc_vdev_quota(struct hdd_adapter *adapter, int set_value)
20832 {
20833 	if (!adapter) {
20834 		hdd_err("Invalid adapter");
20835 		return -EINVAL;
20836 	}
20837 	hdd_info("send mcc vdev quota to fw: %d", set_value);
20838 	sme_cli_set_command(adapter->deflink->vdev_id,
20839 			    WMA_VDEV_MCC_SET_TIME_QUOTA,
20840 			    set_value, VDEV_CMD);
20841 	return 0;
20842 
20843 }
20844 
20845 int wlan_hdd_send_mcc_latency(struct hdd_adapter *adapter, int set_value)
20846 {
20847 	if (!adapter) {
20848 		hdd_err("Invalid adapter");
20849 		return -EINVAL;
20850 	}
20851 
20852 	hdd_info("Send MCC latency WMA: %d", set_value);
20853 	sme_cli_set_command(adapter->deflink->vdev_id,
20854 			    WMA_VDEV_MCC_SET_TIME_LATENCY,
20855 			    set_value, VDEV_CMD);
20856 	return 0;
20857 }
20858 
20859 struct wlan_hdd_link_info *
20860 wlan_hdd_get_link_info_from_vdev(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id)
20861 {
20862 	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
20863 	struct wlan_hdd_link_info *link_info;
20864 
20865 	/*
20866 	 * Currently PSOC is not being used. But this logic will
20867 	 * change once we have the converged implementation of
20868 	 * HDD context per PSOC in place. This would break if
20869 	 * multiple vdev objects reuse the vdev id.
20870 	 */
20871 	link_info = hdd_get_link_info_by_vdev(hdd_ctx, vdev_id);
20872 	if (!link_info) {
20873 		hdd_err("Get adapter by vdev id failed");
20874 		return NULL;
20875 	}
20876 
20877 	return link_info;
20878 }
20879 
20880 int hdd_get_rssi_snr_by_bssid(mac_handle_t mac_handle, const uint8_t *bssid,
20881 			      int8_t *rssi, int8_t *snr)
20882 {
20883 	QDF_STATUS status;
20884 
20885 	status = sme_get_rssi_snr_by_bssid(mac_handle, bssid, rssi, snr);
20886 	if (QDF_IS_STATUS_ERROR(status)) {
20887 		hdd_debug("sme_get_rssi_snr_by_bssid failed");
20888 		return -EINVAL;
20889 	}
20890 
20891 	return 0;
20892 }
20893 
20894 /**
20895  * hdd_reset_limit_off_chan() - reset limit off-channel command parameters
20896  * @adapter: HDD adapter
20897  *
20898  * Return: 0 on success and non zero value on failure
20899  */
20900 int hdd_reset_limit_off_chan(struct hdd_adapter *adapter)
20901 {
20902 	struct hdd_context *hdd_ctx;
20903 	int ret;
20904 	QDF_STATUS status;
20905 	uint8_t sys_pref = 0;
20906 
20907 	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
20908 	ret = wlan_hdd_validate_context(hdd_ctx);
20909 	if (ret < 0)
20910 		return ret;
20911 
20912 	ucfg_policy_mgr_get_sys_pref(hdd_ctx->psoc,
20913 				     &sys_pref);
20914 	/* set the system preferece to default */
20915 	policy_mgr_set_cur_conc_system_pref(hdd_ctx->psoc, sys_pref);
20916 
20917 	/* clear the bitmap */
20918 	adapter->active_ac = 0;
20919 
20920 	hdd_debug("reset ac_bitmap for session %hu active_ac %0x",
20921 		  adapter->deflink->vdev_id, adapter->active_ac);
20922 
20923 	status = sme_send_limit_off_channel_params(hdd_ctx->mac_handle,
20924 						   adapter->deflink->vdev_id,
20925 						   false, 0, 0, false);
20926 	if (!QDF_IS_STATUS_SUCCESS(status)) {
20927 		hdd_err("failed to reset limit off chan params");
20928 		ret = -EINVAL;
20929 	}
20930 
20931 	return ret;
20932 }
20933 
20934 void hdd_hidden_ssid_enable_roaming(hdd_handle_t hdd_handle, uint8_t vdev_id)
20935 {
20936 	struct hdd_context *hdd_ctx = hdd_handle_to_context(hdd_handle);
20937 	struct wlan_hdd_link_info *link_info;
20938 
20939 	link_info = hdd_get_link_info_by_vdev(hdd_ctx, vdev_id);
20940 	if (!link_info) {
20941 		hdd_err("Invalid vdev");
20942 		return;
20943 	}
20944 	/* enable roaming on all adapters once hdd get hidden ssid rsp */
20945 	wlan_hdd_set_roaming_state(link_info, RSO_START_BSS, true);
20946 }
20947 
20948 #ifdef WLAN_FEATURE_PKT_CAPTURE
20949 bool wlan_hdd_is_mon_concurrency(void)
20950 {
20951 	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
20952 
20953 	if (!hdd_ctx)
20954 		return -EINVAL;
20955 
20956 	if (ucfg_pkt_capture_get_mode(hdd_ctx->psoc) !=
20957 						PACKET_CAPTURE_MODE_DISABLE) {
20958 		if (policy_mgr_get_concurrency_mode(hdd_ctx->psoc) ==
20959 		    (QDF_STA_MASK | QDF_MONITOR_MASK)) {
20960 			hdd_err("STA + MON mode is UP");
20961 			return true;
20962 		}
20963 	}
20964 	return false;
20965 }
20966 
20967 void wlan_hdd_del_monitor(struct hdd_context *hdd_ctx,
20968 			  struct hdd_adapter *adapter, bool rtnl_held)
20969 {
20970 	wlan_hdd_release_intf_addr(hdd_ctx, adapter->mac_addr.bytes);
20971 	hdd_stop_adapter(hdd_ctx, adapter);
20972 	hdd_close_adapter(hdd_ctx, adapter, true);
20973 
20974 	hdd_open_p2p_interface(hdd_ctx);
20975 }
20976 
20977 void
20978 wlan_hdd_del_p2p_interface(struct hdd_context *hdd_ctx)
20979 {
20980 	struct hdd_adapter *adapter = NULL, *next_adapter = NULL;
20981 	struct osif_vdev_sync *vdev_sync;
20982 
20983 	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
20984 					   NET_DEV_HOLD_DEL_P2P_INTERFACE) {
20985 		if (adapter->device_mode == QDF_P2P_CLIENT_MODE ||
20986 		    adapter->device_mode == QDF_P2P_DEVICE_MODE ||
20987 		    adapter->device_mode == QDF_P2P_GO_MODE) {
20988 			vdev_sync = osif_vdev_sync_unregister(adapter->dev);
20989 			if (vdev_sync)
20990 				osif_vdev_sync_wait_for_ops(vdev_sync);
20991 
20992 			hdd_adapter_dev_put_debug(
20993 				adapter, NET_DEV_HOLD_DEL_P2P_INTERFACE);
20994 
20995 			hdd_clean_up_interface(hdd_ctx, adapter);
20996 
20997 			if (vdev_sync)
20998 				osif_vdev_sync_destroy(vdev_sync);
20999 		} else
21000 			hdd_adapter_dev_put_debug(
21001 				adapter, NET_DEV_HOLD_DEL_P2P_INTERFACE);
21002 	}
21003 }
21004 
21005 #endif /* WLAN_FEATURE_PKT_CAPTURE */
21006 
21007 bool wlan_hdd_is_session_type_monitor(uint8_t session_type)
21008 {
21009 	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
21010 
21011 	if (!hdd_ctx) {
21012 		cds_err("HDD context is NULL");
21013 		return false;
21014 	}
21015 
21016 	if (cds_get_conparam() != QDF_GLOBAL_MONITOR_MODE &&
21017 	    session_type == QDF_MONITOR_MODE)
21018 		return true;
21019 	else
21020 		return false;
21021 }
21022 
21023 int
21024 wlan_hdd_add_monitor_check(struct hdd_context *hdd_ctx,
21025 			   struct hdd_adapter **adapter,
21026 			   const char *name, bool rtnl_held,
21027 			   unsigned char name_assign_type)
21028 {
21029 	struct hdd_adapter *sta_adapter;
21030 	struct hdd_adapter *mon_adapter;
21031 	uint8_t num_open_session = 0;
21032 	QDF_STATUS status;
21033 	struct hdd_adapter_create_param params = {0};
21034 
21035 	sta_adapter = hdd_get_adapter(hdd_ctx, QDF_STA_MODE);
21036 	if (!sta_adapter) {
21037 		hdd_err("No station adapter");
21038 		return -EINVAL;
21039 	}
21040 
21041 	status = policy_mgr_check_mon_concurrency(hdd_ctx->psoc);
21042 
21043 	if (QDF_IS_STATUS_ERROR(status))
21044 		return -EINVAL;
21045 
21046 	if (hdd_is_connection_in_progress(NULL, NULL)) {
21047 		hdd_err("cannot add monitor mode, Connection in progress");
21048 		return -EINVAL;
21049 	}
21050 
21051 	if (!ucfg_dp_is_local_pkt_capture_enabled(hdd_ctx->psoc) &&
21052 	    ucfg_mlme_is_sta_mon_conc_supported(hdd_ctx->psoc)) {
21053 		num_open_session = policy_mgr_mode_specific_connection_count(
21054 						hdd_ctx->psoc,
21055 						PM_STA_MODE,
21056 						NULL);
21057 
21058 		if (num_open_session) {
21059 			/* Try disconnecting if already in connected state */
21060 			wlan_hdd_cm_issue_disconnect(sta_adapter->deflink,
21061 						     REASON_UNSPEC_FAILURE,
21062 						     true);
21063 		}
21064 	}
21065 
21066 	if (ucfg_pkt_capture_get_mode(hdd_ctx->psoc) !=
21067 						PACKET_CAPTURE_MODE_DISABLE)
21068 		wlan_hdd_del_p2p_interface(hdd_ctx);
21069 
21070 	params.is_add_virtual_iface = 1;
21071 
21072 	mon_adapter = hdd_open_adapter(hdd_ctx, QDF_MONITOR_MODE, name,
21073 				       wlan_hdd_get_intf_addr(
21074 				       hdd_ctx,
21075 				       QDF_MONITOR_MODE),
21076 				       name_assign_type, rtnl_held, &params);
21077 	if (!mon_adapter) {
21078 		hdd_err("hdd_open_adapter failed");
21079 		if (ucfg_pkt_capture_get_mode(hdd_ctx->psoc) !=
21080 						PACKET_CAPTURE_MODE_DISABLE)
21081 			hdd_open_p2p_interface(hdd_ctx);
21082 		return -EINVAL;
21083 	}
21084 
21085 	if (mon_adapter)
21086 		hdd_set_idle_ps_config(hdd_ctx, false);
21087 
21088 	*adapter = mon_adapter;
21089 	return 0;
21090 }
21091 
21092 #ifdef FEATURE_MONITOR_MODE_SUPPORT
21093 
21094 void hdd_sme_monitor_mode_callback(uint8_t vdev_id)
21095 {
21096 	struct hdd_context *hdd_ctx;
21097 	struct hdd_adapter *adapter;
21098 	struct wlan_hdd_link_info *link_info;
21099 
21100 	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
21101 	if (!hdd_ctx)
21102 		return;
21103 
21104 	link_info = hdd_get_link_info_by_vdev(hdd_ctx, vdev_id);
21105 	if (!link_info) {
21106 		hdd_err_rl("NULL adapter");
21107 		return;
21108 	}
21109 
21110 	adapter = link_info->adapter;
21111 	if (adapter->magic != WLAN_HDD_ADAPTER_MAGIC) {
21112 		hdd_err_rl("Invalid magic");
21113 		return;
21114 	}
21115 
21116 	qdf_event_set(&adapter->qdf_monitor_mode_vdev_up_event);
21117 
21118 	hdd_debug("monitor mode vdev up completed");
21119 	adapter->monitor_mode_vdev_up_in_progress = false;
21120 }
21121 
21122 QDF_STATUS hdd_monitor_mode_qdf_create_event(struct hdd_adapter *adapter,
21123 					     uint8_t session_type)
21124 {
21125 	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
21126 
21127 	if (session_type == QDF_MONITOR_MODE) {
21128 		qdf_status = qdf_event_create(
21129 				&adapter->qdf_monitor_mode_vdev_up_event);
21130 	}
21131 	return qdf_status;
21132 }
21133 
21134 QDF_STATUS hdd_monitor_mode_vdev_status(struct hdd_adapter *adapter)
21135 {
21136 	QDF_STATUS status = QDF_STATUS_SUCCESS;
21137 
21138 	if (!adapter->monitor_mode_vdev_up_in_progress)
21139 		return status;
21140 
21141 	/* block on a completion variable until vdev up success*/
21142 	status = qdf_wait_for_event_completion(
21143 				       &adapter->qdf_monitor_mode_vdev_up_event,
21144 					WLAN_MONITOR_MODE_VDEV_UP_EVT);
21145 	if (QDF_IS_STATUS_ERROR(status)) {
21146 		hdd_err_rl("monitor mode vdev up event time out vdev id: %d",
21147 			   adapter->deflink->vdev_id);
21148 		if (adapter->qdf_monitor_mode_vdev_up_event.force_set)
21149 			/*
21150 			 * SSR/PDR has caused shutdown, which has
21151 			 * forcefully set the event.
21152 			 */
21153 			hdd_err_rl("monitor mode vdev up event forcefully set");
21154 		else if (status == QDF_STATUS_E_TIMEOUT)
21155 			hdd_err_rl("mode vdev up event timed out");
21156 		else
21157 			hdd_err_rl("Failed to wait for monitor vdev up(status-%d)",
21158 				   status);
21159 
21160 		adapter->monitor_mode_vdev_up_in_progress = false;
21161 		return status;
21162 	}
21163 
21164 	return QDF_STATUS_SUCCESS;
21165 }
21166 #endif
21167 
21168 #if defined(CLD_PM_QOS) && defined(WLAN_FEATURE_LL_MODE)
21169 void hdd_beacon_latency_event_cb(uint32_t latency_level)
21170 {
21171 	struct hdd_context *hdd_ctx;
21172 
21173 	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
21174 	if (!hdd_ctx)
21175 		return;
21176 
21177 	if (latency_level ==
21178 		QCA_WLAN_VENDOR_ATTR_CONFIG_LATENCY_LEVEL_ULTRALOW)
21179 		wlan_hdd_set_pm_qos_request(hdd_ctx, true);
21180 	else
21181 		wlan_hdd_set_pm_qos_request(hdd_ctx, false);
21182 }
21183 #endif
21184 
21185 #ifdef CONFIG_WLAN_DEBUG_CRASH_INJECT
21186 int hdd_crash_inject(struct hdd_adapter *adapter, uint32_t v1, uint32_t v2)
21187 {
21188 	struct hdd_context *hdd_ctx;
21189 	int ret;
21190 	bool crash_inject;
21191 	QDF_STATUS status;
21192 
21193 	hdd_debug("v1: %d v2: %d", v1, v2);
21194 	pr_err("SSR is triggered by CRASH_INJECT: %d %d\n",
21195 	       v1, v2);
21196 	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
21197 
21198 	status = ucfg_mlme_get_crash_inject(hdd_ctx->psoc, &crash_inject);
21199 	if (QDF_IS_STATUS_ERROR(status)) {
21200 		hdd_err("Failed to get crash inject ini config");
21201 		return 0;
21202 	}
21203 
21204 	if (!crash_inject) {
21205 		hdd_err("Crash Inject ini disabled, Ignore Crash Inject");
21206 		return 0;
21207 	}
21208 
21209 	if (v1 == 3) {
21210 		cds_trigger_recovery(QDF_REASON_UNSPECIFIED);
21211 		return 0;
21212 	}
21213 	ret = wma_cli_set2_command(adapter->deflink->vdev_id,
21214 				   GEN_PARAM_CRASH_INJECT,
21215 				   v1, v2, GEN_CMD);
21216 	return ret;
21217 }
21218 #endif
21219 
21220 static const struct hdd_chwidth_info chwidth_info[] = {
21221 	[NL80211_CHAN_WIDTH_20_NOHT] = {
21222 		.ch_bw = HW_MODE_20_MHZ,
21223 		.ch_bw_str = "20MHz",
21224 		.phy_chwidth = CH_WIDTH_20MHZ,
21225 	},
21226 	[NL80211_CHAN_WIDTH_20] = {
21227 		.sir_chwidth_valid = true,
21228 		.sir_chwidth = eHT_CHANNEL_WIDTH_20MHZ,
21229 		.ch_bw = HW_MODE_20_MHZ,
21230 		.ch_bw_str = "20MHz",
21231 		.phy_chwidth = CH_WIDTH_20MHZ,
21232 		.bonding_mode = WNI_CFG_CHANNEL_BONDING_MODE_DISABLE,
21233 	},
21234 	[NL80211_CHAN_WIDTH_40] = {
21235 		.sir_chwidth_valid = true,
21236 		.sir_chwidth = eHT_CHANNEL_WIDTH_40MHZ,
21237 		.ch_bw = HW_MODE_40_MHZ,
21238 		.ch_bw_str = "40MHz",
21239 		.phy_chwidth = CH_WIDTH_40MHZ,
21240 		.bonding_mode = WNI_CFG_CHANNEL_BONDING_MODE_ENABLE,
21241 	},
21242 	[NL80211_CHAN_WIDTH_80] = {
21243 		.sir_chwidth_valid = true,
21244 		.sir_chwidth = eHT_CHANNEL_WIDTH_80MHZ,
21245 		.ch_bw = HW_MODE_80_MHZ,
21246 		.ch_bw_str = "80MHz",
21247 		.phy_chwidth = CH_WIDTH_80MHZ,
21248 		.bonding_mode = WNI_CFG_CHANNEL_BONDING_MODE_ENABLE,
21249 	},
21250 	[NL80211_CHAN_WIDTH_80P80] = {
21251 		.sir_chwidth_valid = true,
21252 		.sir_chwidth = eHT_CHANNEL_WIDTH_80P80MHZ,
21253 		.ch_bw = HW_MODE_80_PLUS_80_MHZ,
21254 		.ch_bw_str = "(80 + 80)MHz",
21255 		.phy_chwidth = CH_WIDTH_80P80MHZ,
21256 		.bonding_mode = WNI_CFG_CHANNEL_BONDING_MODE_ENABLE,
21257 	},
21258 	[NL80211_CHAN_WIDTH_160] = {
21259 		.sir_chwidth_valid = true,
21260 		.sir_chwidth = eHT_CHANNEL_WIDTH_160MHZ,
21261 		.ch_bw = HW_MODE_160_MHZ,
21262 		.ch_bw_str = "160MHz",
21263 		.phy_chwidth = CH_WIDTH_160MHZ,
21264 		.bonding_mode = WNI_CFG_CHANNEL_BONDING_MODE_ENABLE,
21265 	},
21266 	[NL80211_CHAN_WIDTH_5] = {
21267 		.ch_bw = HW_MODE_5_MHZ,
21268 		.ch_bw_str = "5MHz",
21269 		.phy_chwidth = CH_WIDTH_5MHZ,
21270 	},
21271 	[NL80211_CHAN_WIDTH_10] = {
21272 		.ch_bw = HW_MODE_10_MHZ,
21273 		.ch_bw_str = "10MHz",
21274 		.phy_chwidth = CH_WIDTH_10MHZ,
21275 	},
21276 #if defined(WLAN_FEATURE_11BE) && defined(CFG80211_11BE_BASIC)
21277 	[NL80211_CHAN_WIDTH_320] = {
21278 		.sir_chwidth_valid = true,
21279 		.sir_chwidth = eHT_CHANNEL_WIDTH_320MHZ,
21280 		.ch_bw = HW_MODE_320_MHZ,
21281 		.ch_bw_str = "320MHz",
21282 		.phy_chwidth = CH_WIDTH_320MHZ,
21283 		.bonding_mode = WNI_CFG_CHANNEL_BONDING_MODE_ENABLE,
21284 	},
21285 #endif
21286 };
21287 
21288 enum eSirMacHTChannelWidth
21289 hdd_nl80211_chwidth_to_chwidth(uint8_t nl80211_chwidth)
21290 {
21291 	if (nl80211_chwidth >= ARRAY_SIZE(chwidth_info) ||
21292 	    !chwidth_info[nl80211_chwidth].sir_chwidth_valid) {
21293 		hdd_err("Unsupported channel width %d", nl80211_chwidth);
21294 		return -EINVAL;
21295 	}
21296 
21297 	return chwidth_info[nl80211_chwidth].sir_chwidth;
21298 }
21299 
21300 uint8_t hdd_chwidth_to_nl80211_chwidth(enum eSirMacHTChannelWidth chwidth)
21301 {
21302 	int i;
21303 
21304 	for (i = 0; i < ARRAY_SIZE(chwidth_info); i++) {
21305 		if (chwidth_info[i].sir_chwidth_valid &&
21306 		    chwidth_info[i].sir_chwidth == chwidth)
21307 			return i;
21308 	}
21309 
21310 	hdd_err("Unsupported channel width %d", chwidth);
21311 	return 0xFF;
21312 }
21313 
21314 enum hw_mode_bandwidth wlan_hdd_get_channel_bw(enum nl80211_chan_width width)
21315 {
21316 	if (width >= ARRAY_SIZE(chwidth_info)) {
21317 		hdd_err("Invalid width: %d, using default 20MHz", width);
21318 		return HW_MODE_20_MHZ;
21319 	}
21320 
21321 	return chwidth_info[width].ch_bw;
21322 }
21323 
21324 uint8_t *hdd_ch_width_str(enum phy_ch_width ch_width)
21325 {
21326 	int i;
21327 
21328 	for (i = 0; i < ARRAY_SIZE(chwidth_info); i++) {
21329 		if (chwidth_info[i].phy_chwidth == ch_width)
21330 			return chwidth_info[i].ch_bw_str;
21331 	}
21332 
21333 	return "UNKNOWN";
21334 }
21335 
21336 int hdd_we_set_ch_width(struct wlan_hdd_link_info *link_info, int ch_width)
21337 {
21338 	int i;
21339 
21340 	/* updating channel bonding only on 5Ghz */
21341 	hdd_debug("wmi_vdev_param_chwidth val %d", ch_width);
21342 
21343 	for (i = 0; i < ARRAY_SIZE(chwidth_info); i++) {
21344 		if (!chwidth_info[i].sir_chwidth_valid ||
21345 		    chwidth_info[i].sir_chwidth != ch_width)
21346 			continue;
21347 
21348 		return hdd_update_channel_width(link_info->adapter, ch_width,
21349 						chwidth_info[i].bonding_mode);
21350 	}
21351 
21352 	hdd_err("Invalid ch_width %d", ch_width);
21353 	return -EINVAL;
21354 }
21355 
21356 /* Register the module init/exit functions */
21357 module_init(hdd_module_init);
21358 module_exit(hdd_module_exit);
21359 
21360 MODULE_LICENSE("Dual BSD/GPL");
21361 MODULE_AUTHOR("Qualcomm Atheros, Inc.");
21362 MODULE_DESCRIPTION("WLAN HOST DEVICE DRIVER");
21363 
21364 const struct kernel_param_ops con_mode_ops = {
21365 	.set = con_mode_handler,
21366 	.get = param_get_int,
21367 };
21368 
21369 #ifdef FEATURE_WLAN_RESIDENT_DRIVER
21370 EXPORT_SYMBOL(con_mode_ops);
21371 #endif
21372 
21373 const struct kernel_param_ops con_mode_ftm_ops = {
21374 	.set = con_mode_handler_ftm,
21375 	.get = param_get_int,
21376 };
21377 
21378 #ifdef FEATURE_WLAN_RESIDENT_DRIVER
21379 EXPORT_SYMBOL(con_mode_ftm_ops);
21380 #endif
21381 
21382 #ifdef WLAN_FEATURE_EPPING
21383 static const struct kernel_param_ops con_mode_epping_ops = {
21384 	.set = con_mode_handler_epping,
21385 	.get = param_get_int,
21386 };
21387 #endif
21388 
21389 static const struct kernel_param_ops fwpath_ops = {
21390 	.set = fwpath_changed_handler,
21391 	.get = param_get_string,
21392 };
21393 
21394 static int __pcie_set_gen_speed_handler(void)
21395 {
21396 	int ret;
21397 	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
21398 
21399 	ret = wlan_hdd_validate_context(hdd_ctx);
21400 	if (ret)
21401 		return ret;
21402 
21403 	hdd_info_rl("Received PCIe gen speed %d", pcie_gen_speed);
21404 	if (pcie_gen_speed <= HDD_INVALID_MIN_PCIE_GEN_SPEED ||
21405 	    pcie_gen_speed >= HDD_INVALID_MAX_PCIE_GEN_SPEED) {
21406 		hdd_err_rl("invalid pcie gen speed %d", pcie_gen_speed);
21407 		return -EINVAL;
21408 	}
21409 
21410 	hdd_ctx->current_pcie_gen_speed = pcie_gen_speed;
21411 
21412 	return 0;
21413 }
21414 
21415 static int pcie_set_gen_speed_handler(const char *kmessage,
21416 				      const struct kernel_param *kp)
21417 {
21418 	struct osif_driver_sync *driver_sync;
21419 	int ret;
21420 
21421 	ret = osif_driver_sync_op_start(&driver_sync);
21422 	if (ret)
21423 		return ret;
21424 
21425 	ret = param_set_int(kmessage, kp);
21426 	if (ret) {
21427 		hdd_err_rl("param set int failed %d", ret);
21428 		goto out;
21429 	}
21430 
21431 	ret = __pcie_set_gen_speed_handler();
21432 
21433 out:
21434 	osif_driver_sync_op_stop(driver_sync);
21435 
21436 	return ret;
21437 }
21438 
21439 static const struct kernel_param_ops pcie_gen_speed_ops = {
21440 	.set = pcie_set_gen_speed_handler,
21441 	.get = param_get_int,
21442 };
21443 
21444 module_param_cb(con_mode, &con_mode_ops, &con_mode,
21445 		S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
21446 
21447 module_param_cb(con_mode_ftm, &con_mode_ftm_ops, &con_mode_ftm,
21448 		S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
21449 
21450 module_param_cb(pcie_gen_speed, &pcie_gen_speed_ops, &pcie_gen_speed,
21451 		S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
21452 
21453 #ifdef WLAN_FEATURE_EPPING
21454 module_param_cb(con_mode_epping, &con_mode_epping_ops,
21455 		&con_mode_epping, 0644);
21456 #endif
21457 
21458 module_param_cb(fwpath, &fwpath_ops, &fwpath,
21459 		S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
21460 
21461 module_param(enable_dfs_chan_scan, int, S_IRUSR | S_IRGRP | S_IROTH);
21462 
21463 module_param(enable_11d, int, S_IRUSR | S_IRGRP | S_IROTH);
21464 
21465 module_param(country_code, charp, S_IRUSR | S_IRGRP | S_IROTH);
21466 
21467 static int timer_multiplier_get_handler(char *buffer,
21468 					const struct kernel_param *kp)
21469 {
21470 	return scnprintf(buffer, PAGE_SIZE, "%u", qdf_timer_get_multiplier());
21471 }
21472 
21473 static int timer_multiplier_set_handler(const char *kmessage,
21474 					const struct kernel_param *kp)
21475 {
21476 	QDF_STATUS status;
21477 	uint32_t scalar;
21478 
21479 	status = qdf_uint32_parse(kmessage, &scalar);
21480 	if (QDF_IS_STATUS_ERROR(status))
21481 		return qdf_status_to_os_return(status);
21482 
21483 	if (!cfg_in_range(CFG_TIMER_MULTIPLIER, scalar))
21484 		return -ERANGE;
21485 
21486 	qdf_timer_set_multiplier(scalar);
21487 
21488 	return 0;
21489 }
21490 
21491 static const struct kernel_param_ops timer_multiplier_ops = {
21492 	.get = timer_multiplier_get_handler,
21493 	.set = timer_multiplier_set_handler,
21494 };
21495 
21496 module_param_cb(timer_multiplier, &timer_multiplier_ops, NULL, 0644);
21497