xref: /wlan-dirver/qcacld-3.0/core/hdd/src/wlan_hdd_main.c (revision fe0c9461e0d07f801982087401e20be259f95eca)
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 		return &adapter->mac_addr;
14335 
14336 	return &link_info->link_addr;
14337 }
14338 #else
14339 struct qdf_mac_addr *
14340 hdd_adapter_get_link_mac_addr(struct wlan_hdd_link_info *link_info)
14341 {
14342 	if (!link_info)
14343 		return NULL;
14344 
14345 	return &link_info->adapter->mac_addr;
14346 }
14347 #endif
14348 
14349 #if defined(WLAN_FEATURE_11BE_MLO) && defined(CFG80211_11BE_BASIC) && \
14350 	defined(WLAN_HDD_MULTI_VDEV_SINGLE_NDEV)
14351 QDF_STATUS hdd_adapter_check_duplicate_session(struct hdd_adapter *adapter)
14352 {
14353 	int i = 0;
14354 	QDF_STATUS status;
14355 	uint8_t *addr_list[WLAN_MAX_MLD + 2] = {0};
14356 	struct wlan_hdd_link_info *link_info;
14357 
14358 	if (!hdd_adapter_is_ml_adapter(adapter) ||
14359 	    adapter->device_mode == QDF_SAP_MODE)
14360 		goto netdev_addr;
14361 
14362 	hdd_adapter_for_each_active_link_info(adapter, link_info)
14363 		addr_list[i++] = &link_info->link_addr.bytes[0];
14364 
14365 netdev_addr:
14366 	addr_list[i] = &adapter->mac_addr.bytes[0];
14367 	status = sme_check_for_duplicate_session(adapter->hdd_ctx->mac_handle,
14368 						 &addr_list[0]);
14369 	return status;
14370 }
14371 
14372 QDF_STATUS hdd_adapter_fill_link_address(struct hdd_adapter *adapter)
14373 {
14374 	int i = 0;
14375 	QDF_STATUS status;
14376 	enum QDF_OPMODE opmode = adapter->device_mode;
14377 	struct qdf_mac_addr link_addrs[WLAN_MAX_ML_BSS_LINKS] = {0};
14378 	struct wlan_hdd_link_info *link_info;
14379 
14380 	if (opmode != QDF_STA_MODE && opmode != QDF_SAP_MODE)
14381 		return QDF_STATUS_SUCCESS;
14382 
14383 	if (opmode == QDF_SAP_MODE) {
14384 		link_info = adapter->deflink;
14385 		qdf_copy_macaddr(&link_info->link_addr, &adapter->mac_addr);
14386 		return QDF_STATUS_SUCCESS;
14387 	}
14388 
14389 	if (!hdd_adapter_is_ml_adapter(adapter))
14390 		return QDF_STATUS_SUCCESS;
14391 
14392 	status = hdd_derive_link_address_from_mld(&adapter->mac_addr,
14393 						  &link_addrs[0],
14394 						  WLAN_MAX_ML_BSS_LINKS);
14395 	if (QDF_IS_STATUS_ERROR(status))
14396 		return status;
14397 
14398 	hdd_adapter_for_each_link_info(adapter, link_info)
14399 		qdf_copy_macaddr(&link_info->link_addr, &link_addrs[i++]);
14400 
14401 	return status;
14402 }
14403 #elif defined(WLAN_FEATURE_11BE_MLO) && defined(CFG80211_11BE_BASIC)
14404 QDF_STATUS hdd_adapter_check_duplicate_session(struct hdd_adapter *adapter)
14405 {
14406 	int i;
14407 	QDF_STATUS status;
14408 	uint8_t *addr_list[WLAN_MAX_MLD + 1] = {0};
14409 	struct hdd_adapter *link_adapter;
14410 	struct hdd_mlo_adapter_info *mlo_adapter_info;
14411 	mac_handle_t mac_handle = hdd_adapter_get_mac_handle(adapter);
14412 
14413 	if (hdd_adapter_is_ml_adapter(adapter) &&
14414 	    adapter->device_mode == QDF_STA_MODE) {
14415 		addr_list[0] = &adapter->mld_addr.bytes[0];
14416 		mlo_adapter_info = &adapter->mlo_adapter_info;
14417 		for (i = 0; i < WLAN_MAX_MLD; i++) {
14418 			link_adapter = mlo_adapter_info->link_adapter[i];
14419 			if (!link_adapter)
14420 				continue;
14421 			if (hdd_adapter_is_associated_with_ml_adapter(
14422 							link_adapter)) {
14423 				addr_list[1] = &link_adapter->mac_addr.bytes[0];
14424 			}
14425 		}
14426 	} else {
14427 		addr_list[0] = &adapter->mac_addr.bytes[0];
14428 	}
14429 
14430 	status = sme_check_for_duplicate_session(mac_handle, &addr_list[0]);
14431 	return status;
14432 }
14433 #else
14434 QDF_STATUS hdd_adapter_check_duplicate_session(struct hdd_adapter *adapter)
14435 {
14436 	QDF_STATUS status;
14437 	uint8_t *addr_list[2] = {0};
14438 	mac_handle_t mac_handle = hdd_adapter_get_mac_handle(adapter);
14439 
14440 	addr_list[0] = &adapter->mac_addr.bytes[0];
14441 	status = sme_check_for_duplicate_session(mac_handle, &addr_list[0]);
14442 
14443 	return status;
14444 }
14445 #endif
14446 
14447 static void hdd_restore_info_for_ssr(struct hdd_adapter *adapter)
14448 {
14449 	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
14450 
14451 	if (cds_is_driver_recovering()) {
14452 		/* ssr happens, recover the info */
14453 		hdd_set_vdev_phy_mode(adapter, adapter->user_phy_mode);
14454 		wlan_mlme_restore_user_set_link_num(hdd_ctx->psoc);
14455 	} else {
14456 		/* intf down/up happens, reset default info */
14457 		hdd_set_vdev_phy_mode(adapter, QCA_WLAN_VENDOR_PHY_MODE_AUTO);
14458 		wlan_mlme_clear_user_set_link_num(hdd_ctx->psoc);
14459 	}
14460 }
14461 
14462 void hdd_adapter_reset_station_ctx(struct hdd_adapter *adapter)
14463 {
14464 	struct wlan_hdd_link_info *link_info;
14465 
14466 	hdd_adapter_for_each_link_info(adapter, link_info)
14467 		hdd_cm_clear_ieee_link_id(link_info);
14468 }
14469 
14470 int hdd_start_station_adapter(struct hdd_adapter *adapter)
14471 {
14472 	QDF_STATUS status;
14473 	int ret;
14474 	struct wlan_hdd_link_info *link_info;
14475 
14476 	hdd_enter_dev(adapter->dev);
14477 	if (test_bit(SME_SESSION_OPENED, &adapter->deflink->link_flags)) {
14478 		hdd_err("session is already opened, %d",
14479 			adapter->deflink->vdev_id);
14480 		return qdf_status_to_os_return(QDF_STATUS_SUCCESS);
14481 	}
14482 
14483 	if ((adapter->device_mode == QDF_P2P_DEVICE_MODE) ||
14484 	    (adapter->device_mode == QDF_NAN_DISC_MODE))
14485 		wlan_hdd_lpc_del_monitor_interface(adapter->hdd_ctx);
14486 
14487 	status = hdd_adapter_fill_link_address(adapter);
14488 	if (QDF_IS_STATUS_ERROR(status)) {
14489 		hdd_debug("Link address derive failed");
14490 		return qdf_status_to_os_return(status);
14491 	}
14492 
14493 	status = hdd_adapter_check_duplicate_session(adapter);
14494 	if (QDF_IS_STATUS_ERROR(status)) {
14495 		hdd_err("Duplicate session is existing with same mac address");
14496 		return qdf_status_to_os_return(status);
14497 	}
14498 
14499 	hdd_adapter_for_each_active_link_info(adapter, link_info) {
14500 		ret = hdd_vdev_create(link_info);
14501 		if (ret) {
14502 			hdd_err("failed to create vdev: %d", ret);
14503 			goto fail;
14504 		}
14505 
14506 		status = hdd_init_station_mode(link_info);
14507 		if (QDF_STATUS_SUCCESS != status) {
14508 			hdd_err("Error Initializing station mode: %d", status);
14509 			ret = qdf_status_to_os_return(status);
14510 			goto fail;
14511 		}
14512 	}
14513 
14514 	hdd_adapter_reset_station_ctx(adapter);
14515 
14516 	hdd_register_wext(adapter->dev);
14517 	hdd_set_netdev_flags(adapter);
14518 
14519 	hdd_register_tx_flow_control(adapter,
14520 		hdd_tx_resume_timer_expired_handler,
14521 		hdd_tx_resume_cb,
14522 		hdd_tx_flow_control_is_pause);
14523 
14524 	hdd_register_hl_netdev_fc_timer(adapter,
14525 					hdd_tx_resume_timer_expired_handler);
14526 
14527 	if (hdd_get_multi_client_ll_support(adapter))
14528 		wlan_hdd_init_multi_client_info_table(adapter);
14529 
14530 	hdd_adapter_set_wlm_client_latency_level(adapter);
14531 	hdd_adapter_update_mlo_mgr_mac_addr(adapter);
14532 	hdd_restore_info_for_ssr(adapter);
14533 
14534 	hdd_exit();
14535 	return 0;
14536 
14537 fail:
14538 	hdd_adapter_for_each_active_link_info(adapter, link_info)
14539 		hdd_vdev_destroy(link_info);
14540 
14541 	return ret;
14542 }
14543 
14544 int hdd_start_ap_adapter(struct hdd_adapter *adapter, bool rtnl_held)
14545 {
14546 	QDF_STATUS status;
14547 	bool is_ssr = false;
14548 	int ret;
14549 	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
14550 	struct sap_context *sap_ctx;
14551 	struct wlan_hdd_link_info *link_info = adapter->deflink;
14552 
14553 	hdd_enter();
14554 
14555 	if (test_bit(SME_SESSION_OPENED, &link_info->link_flags)) {
14556 		hdd_err("session is already opened, %d",
14557 			link_info->vdev_id);
14558 		return qdf_status_to_os_return(QDF_STATUS_SUCCESS);
14559 	}
14560 
14561 	wlan_hdd_lpc_del_monitor_interface(hdd_ctx);
14562 
14563 	status = hdd_adapter_fill_link_address(adapter);
14564 	if (QDF_IS_STATUS_ERROR(status)) {
14565 		hdd_debug("Link address derive failed");
14566 		return qdf_status_to_os_return(status);
14567 	}
14568 
14569 	status = hdd_adapter_check_duplicate_session(adapter);
14570 	if (QDF_IS_STATUS_ERROR(status)) {
14571 		hdd_err("Duplicate session is existing with same mac address");
14572 		return qdf_status_to_os_return(status);
14573 	}
14574 
14575 	/*
14576 	 * In SSR case no need to create new sap context.
14577 	 * Otherwise create sap context first and then create
14578 	 * vdev as while creating the vdev, driver needs to
14579 	 * register SAP callback and that callback uses sap context
14580 	 */
14581 	if (WLAN_HDD_GET_SAP_CTX_PTR(link_info)) {
14582 		is_ssr = true;
14583 	} else if (!hdd_sap_create_ctx(adapter)) {
14584 		hdd_err("sap creation failed");
14585 		return qdf_status_to_os_return(QDF_STATUS_E_FAILURE);
14586 	}
14587 
14588 	ret = hdd_vdev_create(link_info);
14589 	if (ret) {
14590 		hdd_err("failed to create vdev, status:%d", ret);
14591 		goto sap_destroy_ctx;
14592 	}
14593 
14594 	sap_ctx = WLAN_HDD_GET_SAP_CTX_PTR(link_info);
14595 	status = sap_acquire_vdev_ref(hdd_ctx->psoc, sap_ctx,
14596 				      link_info->vdev_id);
14597 	if (!QDF_IS_STATUS_SUCCESS(status)) {
14598 		hdd_err("Failed to get vdev ref for sap for session_id: %u",
14599 			link_info->vdev_id);
14600 		ret = qdf_status_to_os_return(status);
14601 		goto sap_vdev_destroy;
14602 	}
14603 
14604 	if (adapter->device_mode == QDF_SAP_MODE) {
14605 		status = hdd_vdev_configure_rtt_params(sap_ctx->vdev);
14606 		if (QDF_IS_STATUS_ERROR(status))
14607 			goto sap_release_ref;
14608 	}
14609 
14610 	status = hdd_init_ap_mode(adapter, is_ssr, rtnl_held);
14611 	if (QDF_STATUS_SUCCESS != status) {
14612 		hdd_err("Error Initializing the AP mode: %d", status);
14613 		ret = qdf_status_to_os_return(status);
14614 		goto sap_release_ref;
14615 	}
14616 
14617 	hdd_register_tx_flow_control(adapter,
14618 		hdd_softap_tx_resume_timer_expired_handler,
14619 		hdd_softap_tx_resume_cb,
14620 		hdd_tx_flow_control_is_pause);
14621 
14622 	hdd_register_hl_netdev_fc_timer(adapter,
14623 					hdd_tx_resume_timer_expired_handler);
14624 
14625 	hdd_exit();
14626 	return 0;
14627 
14628 sap_release_ref:
14629 	sap_release_vdev_ref(sap_ctx);
14630 sap_vdev_destroy:
14631 	hdd_vdev_destroy(link_info);
14632 sap_destroy_ctx:
14633 	hdd_sap_destroy_ctx(link_info);
14634 	return ret;
14635 }
14636 
14637 #if defined(QCA_LL_TX_FLOW_CONTROL_V2) || defined(QCA_LL_PDEV_TX_FLOW_CONTROL)
14638 /**
14639  * hdd_txrx_populate_cds_config() - Populate txrx cds configuration
14640  * @cds_cfg: CDS Configuration
14641  * @hdd_ctx: Pointer to hdd context
14642  *
14643  * Return: none
14644  */
14645 static inline void hdd_txrx_populate_cds_config(struct cds_config_info
14646 						*cds_cfg,
14647 						struct hdd_context *hdd_ctx)
14648 {
14649 	cds_cfg->tx_flow_stop_queue_th =
14650 		cfg_get(hdd_ctx->psoc, CFG_DP_TX_FLOW_STOP_QUEUE_TH);
14651 	cds_cfg->tx_flow_start_queue_offset =
14652 		cfg_get(hdd_ctx->psoc, CFG_DP_TX_FLOW_START_QUEUE_OFFSET);
14653 	/* configuration for DP RX Threads */
14654 	cds_cfg->enable_dp_rx_threads =
14655 		ucfg_dp_is_rx_threads_enabled(hdd_ctx->psoc);
14656 }
14657 #else
14658 static inline void hdd_txrx_populate_cds_config(struct cds_config_info
14659 						*cds_cfg,
14660 						struct hdd_context *hdd_ctx)
14661 {
14662 }
14663 #endif
14664 
14665 /**
14666  * hdd_update_cds_config() - API to update cds configuration parameters
14667  * @hdd_ctx: HDD Context
14668  *
14669  * Return: 0 for Success, errno on failure
14670  */
14671 static int hdd_update_cds_config(struct hdd_context *hdd_ctx)
14672 {
14673 	struct cds_config_info *cds_cfg;
14674 	int value;
14675 	uint8_t band_capability;
14676 	uint32_t band_bitmap;
14677 	uint8_t ito_repeat_count;
14678 	bool crash_inject;
14679 	bool self_recovery;
14680 	bool fw_timeout_crash;
14681 	QDF_STATUS status;
14682 
14683 	cds_cfg = qdf_mem_malloc(sizeof(*cds_cfg));
14684 	if (!cds_cfg)
14685 		return -ENOMEM;
14686 
14687 	cds_cfg->driver_type = QDF_DRIVER_TYPE_PRODUCTION;
14688 	ucfg_mlme_get_sap_max_modulated_dtim(hdd_ctx->psoc,
14689 					     &cds_cfg->sta_maxlimod_dtim);
14690 
14691 	ucfg_mlme_get_max_modulated_dtim_ms(hdd_ctx->psoc,
14692 					    &cds_cfg->sta_maxlimod_dtim_ms);
14693 
14694 	status = ucfg_mlme_get_crash_inject(hdd_ctx->psoc, &crash_inject);
14695 	if (QDF_IS_STATUS_ERROR(status)) {
14696 		hdd_err("Failed to get crash inject ini config");
14697 		goto exit;
14698 	}
14699 
14700 	status = ucfg_mlme_get_self_recovery(hdd_ctx->psoc, &self_recovery);
14701 	if (QDF_IS_STATUS_ERROR(status)) {
14702 		hdd_err("Failed to get self recovery ini config");
14703 		goto exit;
14704 	}
14705 
14706 	status = ucfg_mlme_get_fw_timeout_crash(hdd_ctx->psoc,
14707 						&fw_timeout_crash);
14708 	if (QDF_IS_STATUS_ERROR(status)) {
14709 		hdd_err("Failed to get fw timeout crash ini config");
14710 		goto exit;
14711 	}
14712 
14713 	status = ucfg_mlme_get_ito_repeat_count(hdd_ctx->psoc,
14714 						&ito_repeat_count);
14715 	if (QDF_IS_STATUS_ERROR(status)) {
14716 		hdd_err("Failed to get ITO repeat count ini config");
14717 		goto exit;
14718 	}
14719 
14720 	cds_cfg->force_target_assert_enabled = crash_inject;
14721 
14722 	ucfg_mlme_get_sap_max_offload_peers(hdd_ctx->psoc, &value);
14723 	cds_cfg->ap_maxoffload_peers = value;
14724 	ucfg_mlme_get_sap_max_offload_reorder_buffs(hdd_ctx->psoc,
14725 						    &value);
14726 	cds_cfg->ap_maxoffload_reorderbuffs = value;
14727 
14728 	cds_cfg->reorder_offload = DP_REORDER_OFFLOAD_SUPPORT;
14729 
14730 	/* IPA micro controller data path offload resource config item */
14731 	cds_cfg->uc_offload_enabled = ucfg_ipa_uc_is_enabled();
14732 
14733 	cds_cfg->enable_rxthread =
14734 		ucfg_dp_is_rx_common_thread_enabled(hdd_ctx->psoc);
14735 	ucfg_mlme_get_sap_max_peers(hdd_ctx->psoc, &value);
14736 	cds_cfg->max_station = value;
14737 	cds_cfg->sub_20_channel_width = WLAN_SUB_20_CH_WIDTH_NONE;
14738 	cds_cfg->max_msdus_per_rxinorderind =
14739 		cfg_get(hdd_ctx->psoc, CFG_DP_MAX_MSDUS_PER_RXIND);
14740 	cds_cfg->self_recovery_enabled = self_recovery;
14741 	cds_cfg->fw_timeout_crash = fw_timeout_crash;
14742 
14743 	cds_cfg->ito_repeat_count = ito_repeat_count;
14744 
14745 	status = ucfg_mlme_get_band_capability(hdd_ctx->psoc, &band_bitmap);
14746 	if (QDF_IS_STATUS_ERROR(status))
14747 		goto exit;
14748 
14749 	band_capability = wlan_reg_band_bitmap_to_band_info(band_bitmap);
14750 	cds_cfg->bandcapability = band_capability;
14751 	cds_cfg->num_vdevs = hdd_ctx->config->num_vdevs;
14752 	cds_cfg->enable_tx_compl_tsf64 =
14753 		hdd_tsf_is_tsf64_tx_set(hdd_ctx);
14754 	hdd_txrx_populate_cds_config(cds_cfg, hdd_ctx);
14755 	hdd_lpass_populate_cds_config(cds_cfg, hdd_ctx);
14756 	cds_init_ini_config(cds_cfg);
14757 	return 0;
14758 
14759 exit:
14760 	qdf_mem_free(cds_cfg);
14761 	return -EINVAL;
14762 }
14763 
14764 /**
14765  * hdd_update_user_config() - API to update user configuration
14766  * parameters to obj mgr which are used by multiple components
14767  * @hdd_ctx: HDD Context
14768  *
14769  * Return: 0 for Success, errno on failure
14770  */
14771 static int hdd_update_user_config(struct hdd_context *hdd_ctx)
14772 {
14773 	struct wlan_objmgr_psoc_user_config *user_config;
14774 	uint8_t band_capability;
14775 	uint32_t band_bitmap;
14776 	QDF_STATUS status;
14777 	bool value = false;
14778 
14779 	status = ucfg_mlme_get_band_capability(hdd_ctx->psoc, &band_bitmap);
14780 	if (QDF_IS_STATUS_ERROR(status))
14781 		return -EIO;
14782 
14783 	user_config = qdf_mem_malloc(sizeof(*user_config));
14784 	if (!user_config)
14785 		return -ENOMEM;
14786 
14787 	user_config->dot11_mode = hdd_ctx->config->dot11Mode;
14788 	status = ucfg_mlme_is_11d_enabled(hdd_ctx->psoc, &value);
14789 	if (!QDF_IS_STATUS_SUCCESS(status))
14790 		hdd_err("Invalid 11d_enable flag");
14791 	user_config->is_11d_support_enabled = value;
14792 
14793 	value = false;
14794 	status = ucfg_mlme_is_11h_enabled(hdd_ctx->psoc, &value);
14795 	if (!QDF_IS_STATUS_SUCCESS(status))
14796 		hdd_err("Invalid 11h_enable flag");
14797 	user_config->is_11h_support_enabled = value;
14798 	band_capability = wlan_reg_band_bitmap_to_band_info(band_bitmap);
14799 	user_config->band_capability = band_capability;
14800 	wlan_objmgr_psoc_set_user_config(hdd_ctx->psoc, user_config);
14801 
14802 	qdf_mem_free(user_config);
14803 	return 0;
14804 }
14805 
14806 /**
14807  * hdd_init_thermal_info - Initialize thermal level
14808  * @hdd_ctx:	HDD context
14809  *
14810  * Initialize thermal level at SME layer and set the thermal level callback
14811  * which would be called when a configured thermal threshold is hit.
14812  *
14813  * Return: 0 on success and errno on failure
14814  */
14815 static int hdd_init_thermal_info(struct hdd_context *hdd_ctx)
14816 {
14817 	QDF_STATUS status;
14818 	mac_handle_t mac_handle = hdd_ctx->mac_handle;
14819 
14820 	status = sme_init_thermal_info(mac_handle);
14821 
14822 	if (!QDF_IS_STATUS_SUCCESS(status))
14823 		return qdf_status_to_os_return(status);
14824 
14825 	sme_add_set_thermal_level_callback(mac_handle,
14826 					   hdd_set_thermal_level_cb);
14827 
14828 	return 0;
14829 
14830 }
14831 
14832 #if defined(CONFIG_HDD_INIT_WITH_RTNL_LOCK)
14833 /**
14834  * hdd_hold_rtnl_lock - Hold RTNL lock
14835  *
14836  * Hold RTNL lock
14837  *
14838  * Return: True if held and false otherwise
14839  */
14840 static inline bool hdd_hold_rtnl_lock(void)
14841 {
14842 	rtnl_lock();
14843 	return true;
14844 }
14845 
14846 /**
14847  * hdd_release_rtnl_lock - Release RTNL lock
14848  *
14849  * Release RTNL lock
14850  *
14851  * Return: None
14852  */
14853 static inline void hdd_release_rtnl_lock(void)
14854 {
14855 	rtnl_unlock();
14856 }
14857 #else
14858 static inline bool hdd_hold_rtnl_lock(void) { return false; }
14859 static inline void hdd_release_rtnl_lock(void) { }
14860 #endif
14861 
14862 #if !defined(REMOVE_PKT_LOG)
14863 
14864 /* MAX iwpriv command support */
14865 #define PKTLOG_SET_BUFF_SIZE	3
14866 #define PKTLOG_CLEAR_BUFF	4
14867 /* Set Maximum pktlog file size to 64MB */
14868 #define MAX_PKTLOG_SIZE		64
14869 
14870 /**
14871  * hdd_pktlog_set_buff_size() - set pktlog buffer size
14872  * @hdd_ctx: hdd context
14873  * @set_value2: pktlog buffer size value
14874  *
14875  *
14876  * Return: 0 for success or error.
14877  */
14878 static int hdd_pktlog_set_buff_size(struct hdd_context *hdd_ctx, int set_value2)
14879 {
14880 	struct sir_wifi_start_log start_log = { 0 };
14881 	QDF_STATUS status;
14882 
14883 	start_log.ring_id = RING_ID_PER_PACKET_STATS;
14884 	start_log.verbose_level = WLAN_LOG_LEVEL_OFF;
14885 	start_log.ini_triggered = cds_is_packet_log_enabled();
14886 	start_log.user_triggered = 1;
14887 	start_log.size = set_value2;
14888 	start_log.is_pktlog_buff_clear = false;
14889 
14890 	status = sme_wifi_start_logger(hdd_ctx->mac_handle, start_log);
14891 	if (!QDF_IS_STATUS_SUCCESS(status)) {
14892 		hdd_err("sme_wifi_start_logger failed(err=%d)", status);
14893 		hdd_exit();
14894 		return -EINVAL;
14895 	}
14896 
14897 	return 0;
14898 }
14899 
14900 /**
14901  * hdd_pktlog_clear_buff() - clear pktlog buffer
14902  * @hdd_ctx: hdd context
14903  *
14904  * Return: 0 for success or error.
14905  */
14906 static int hdd_pktlog_clear_buff(struct hdd_context *hdd_ctx)
14907 {
14908 	struct sir_wifi_start_log start_log;
14909 	QDF_STATUS status;
14910 
14911 	start_log.ring_id = RING_ID_PER_PACKET_STATS;
14912 	start_log.verbose_level = WLAN_LOG_LEVEL_OFF;
14913 	start_log.ini_triggered = cds_is_packet_log_enabled();
14914 	start_log.user_triggered = 1;
14915 	start_log.size = 0;
14916 	start_log.is_pktlog_buff_clear = true;
14917 
14918 	status = sme_wifi_start_logger(hdd_ctx->mac_handle, start_log);
14919 	if (!QDF_IS_STATUS_SUCCESS(status)) {
14920 		hdd_err("sme_wifi_start_logger failed(err=%d)", status);
14921 		hdd_exit();
14922 		return -EINVAL;
14923 	}
14924 
14925 	return 0;
14926 }
14927 
14928 
14929 /**
14930  * hdd_process_pktlog_command() - process pktlog command
14931  * @hdd_ctx: hdd context
14932  * @set_value: value set by user
14933  * @set_value2: pktlog buffer size value
14934  *
14935  * This function process pktlog command.
14936  * set_value2 only matters when set_value is 3 (set buff size)
14937  * otherwise we ignore it.
14938  *
14939  * Return: 0 for success or error.
14940  */
14941 int hdd_process_pktlog_command(struct hdd_context *hdd_ctx, uint32_t set_value,
14942 			       int set_value2)
14943 {
14944 	int ret;
14945 	bool enable;
14946 	uint8_t user_triggered = 0;
14947 
14948 	ret = wlan_hdd_validate_context(hdd_ctx);
14949 	if (0 != ret)
14950 		return ret;
14951 
14952 	hdd_debug("set pktlog %d, set size %d", set_value, set_value2);
14953 
14954 	if (set_value > PKTLOG_CLEAR_BUFF) {
14955 		hdd_err("invalid pktlog value %d", set_value);
14956 		return -EINVAL;
14957 	}
14958 
14959 	if (set_value == PKTLOG_SET_BUFF_SIZE) {
14960 		if (set_value2 <= 0) {
14961 			hdd_err("invalid pktlog size %d", set_value2);
14962 			return -EINVAL;
14963 		} else if (set_value2 > MAX_PKTLOG_SIZE) {
14964 			hdd_err_rl("Pktlog size is large. max value is %uMB.",
14965 				   MAX_PKTLOG_SIZE);
14966 			return -EINVAL;
14967 		}
14968 		return hdd_pktlog_set_buff_size(hdd_ctx, set_value2);
14969 	} else if (set_value == PKTLOG_CLEAR_BUFF) {
14970 		return hdd_pktlog_clear_buff(hdd_ctx);
14971 	}
14972 
14973 	/*
14974 	 * set_value = 0 then disable packetlog
14975 	 * set_value = 1 enable packetlog forcefully
14976 	 * set_value = 2 then disable packetlog if disabled through ini or
14977 	 *                     enable packetlog with AUTO type.
14978 	 */
14979 	enable = ((set_value > 0) && cds_is_packet_log_enabled()) ?
14980 			 true : false;
14981 
14982 	if (1 == set_value) {
14983 		enable = true;
14984 		user_triggered = 1;
14985 	}
14986 
14987 	return hdd_pktlog_enable_disable(hdd_ctx, enable, user_triggered, 0);
14988 }
14989 
14990 /**
14991  * hdd_pktlog_enable_disable() - Enable/Disable packet logging
14992  * @hdd_ctx: HDD context
14993  * @enable_disable_flag: Flag to enable/disable
14994  * @user_triggered: triggered through iwpriv
14995  * @size: buffer size to be used for packetlog
14996  *
14997  * Return: 0 on success; error number otherwise
14998  */
14999 int hdd_pktlog_enable_disable(struct hdd_context *hdd_ctx,
15000 			      bool enable_disable_flag,
15001 			      uint8_t user_triggered, int size)
15002 {
15003 	struct sir_wifi_start_log start_log;
15004 	QDF_STATUS status;
15005 
15006 	if (hdd_ctx->is_pktlog_enabled && enable_disable_flag)
15007 		return 0;
15008 
15009 	if ((!hdd_ctx->is_pktlog_enabled) && (!enable_disable_flag))
15010 		return 0;
15011 
15012 	start_log.ring_id = RING_ID_PER_PACKET_STATS;
15013 	start_log.verbose_level =
15014 		enable_disable_flag ?
15015 			WLAN_LOG_LEVEL_ACTIVE : WLAN_LOG_LEVEL_OFF;
15016 	start_log.ini_triggered = cds_is_packet_log_enabled();
15017 	start_log.user_triggered = user_triggered;
15018 	start_log.size = size;
15019 	start_log.is_pktlog_buff_clear = false;
15020 	/*
15021 	 * Use "is_iwpriv_command" flag to distinguish iwpriv command from other
15022 	 * commands. Host uses this flag to decide whether to send pktlog
15023 	 * disable command to fw without sending pktlog enable command
15024 	 * previously. For eg, If vendor sends pktlog disable command without
15025 	 * sending pktlog enable command, then host discards the packet
15026 	 * but for iwpriv command, host will send it to fw.
15027 	 */
15028 	start_log.is_iwpriv_command = 1;
15029 
15030 	status = sme_wifi_start_logger(hdd_ctx->mac_handle, start_log);
15031 	if (!QDF_IS_STATUS_SUCCESS(status)) {
15032 		hdd_err("sme_wifi_start_logger failed(err=%d)", status);
15033 		hdd_exit();
15034 		return -EINVAL;
15035 	}
15036 
15037 	hdd_ctx->is_pktlog_enabled = enable_disable_flag;
15038 
15039 	return 0;
15040 }
15041 #endif /* REMOVE_PKT_LOG */
15042 
15043 void hdd_free_mac_address_lists(struct hdd_context *hdd_ctx)
15044 {
15045 	hdd_debug("Resetting MAC address lists");
15046 	qdf_mem_zero(hdd_ctx->provisioned_mac_addr,
15047 		    sizeof(hdd_ctx->provisioned_mac_addr));
15048 	qdf_mem_zero(hdd_ctx->derived_mac_addr,
15049 		    sizeof(hdd_ctx->derived_mac_addr));
15050 	hdd_ctx->num_provisioned_addr = 0;
15051 	hdd_ctx->num_derived_addr = 0;
15052 	hdd_ctx->provisioned_intf_addr_mask = 0;
15053 	hdd_ctx->derived_intf_addr_mask = 0;
15054 }
15055 
15056 /**
15057  * hdd_get_platform_wlan_mac_buff() - API to query platform driver
15058  *                                    for MAC address
15059  * @dev: Device Pointer
15060  * @num: Number of Valid Mac address
15061  *
15062  * Return: Pointer to MAC address buffer
15063  */
15064 static uint8_t *hdd_get_platform_wlan_mac_buff(struct device *dev,
15065 					       uint32_t *num)
15066 {
15067 	return pld_get_wlan_mac_address(dev, num);
15068 }
15069 
15070 /**
15071  * hdd_get_platform_wlan_derived_mac_buff() - API to query platform driver
15072  *                                    for derived MAC address
15073  * @dev: Device Pointer
15074  * @num: Number of Valid Mac address
15075  *
15076  * Return: Pointer to MAC address buffer
15077  */
15078 static uint8_t *hdd_get_platform_wlan_derived_mac_buff(struct device *dev,
15079 						       uint32_t *num)
15080 {
15081 	return pld_get_wlan_derived_mac_address(dev, num);
15082 }
15083 
15084 /**
15085  * hdd_populate_random_mac_addr() - API to populate random mac addresses
15086  * @hdd_ctx: HDD Context
15087  * @num: Number of random mac addresses needed
15088  *
15089  * Generate random addresses using bit manipulation on the base mac address
15090  *
15091  * Return: None
15092  */
15093 void hdd_populate_random_mac_addr(struct hdd_context *hdd_ctx, uint32_t num)
15094 {
15095 	uint32_t idx = hdd_ctx->num_derived_addr;
15096 	uint32_t iter;
15097 	uint8_t *buf = NULL;
15098 	uint8_t macaddr_b3, tmp_br3;
15099 	/*
15100 	 * Consider first provisioned mac address as source address to derive
15101 	 * remaining addresses
15102 	 */
15103 
15104 	uint8_t *src = hdd_ctx->provisioned_mac_addr[0].bytes;
15105 
15106 	for (iter = 0; iter < num; ++iter, ++idx) {
15107 		buf = hdd_ctx->derived_mac_addr[idx].bytes;
15108 		qdf_mem_copy(buf, src, QDF_MAC_ADDR_SIZE);
15109 		macaddr_b3 = buf[3];
15110 		tmp_br3 = ((macaddr_b3 >> 4 & INTF_MACADDR_MASK) + idx) &
15111 			INTF_MACADDR_MASK;
15112 		macaddr_b3 += tmp_br3;
15113 		macaddr_b3 ^= (1 << INTF_MACADDR_MASK);
15114 		buf[0] |= 0x02;
15115 		buf[3] = macaddr_b3;
15116 		hdd_debug(QDF_MAC_ADDR_FMT, QDF_MAC_ADDR_REF(buf));
15117 		hdd_ctx->num_derived_addr++;
15118 	}
15119 }
15120 
15121 /**
15122  * hdd_platform_wlan_mac() - API to get mac addresses from platform driver
15123  * @hdd_ctx: HDD Context
15124  *
15125  * API to get mac addresses from platform driver and update the driver
15126  * structures and configure FW with the base mac address.
15127  * Return: int
15128  */
15129 static int hdd_platform_wlan_mac(struct hdd_context *hdd_ctx)
15130 {
15131 	uint32_t no_of_mac_addr, iter;
15132 	uint32_t max_mac_addr = QDF_MAX_CONCURRENCY_PERSONA;
15133 	uint32_t mac_addr_size = QDF_MAC_ADDR_SIZE;
15134 	uint8_t *addr, *buf;
15135 	struct device *dev = hdd_ctx->parent_dev;
15136 	tSirMacAddr mac_addr;
15137 	QDF_STATUS status;
15138 
15139 	addr = hdd_get_platform_wlan_mac_buff(dev, &no_of_mac_addr);
15140 
15141 	if (no_of_mac_addr == 0 || !addr) {
15142 		hdd_debug("No mac configured from platform driver");
15143 		return -EINVAL;
15144 	}
15145 
15146 	hdd_free_mac_address_lists(hdd_ctx);
15147 
15148 	if (no_of_mac_addr > max_mac_addr)
15149 		no_of_mac_addr = max_mac_addr;
15150 
15151 	qdf_mem_copy(&mac_addr, addr, mac_addr_size);
15152 
15153 	for (iter = 0; iter < no_of_mac_addr; ++iter, addr += mac_addr_size) {
15154 		buf = hdd_ctx->provisioned_mac_addr[iter].bytes;
15155 		qdf_mem_copy(buf, addr, QDF_MAC_ADDR_SIZE);
15156 		hdd_info("provisioned MAC Addr [%d] "QDF_MAC_ADDR_FMT, iter,
15157 			 QDF_MAC_ADDR_REF(buf));
15158 	}
15159 
15160 	hdd_ctx->num_provisioned_addr = no_of_mac_addr;
15161 
15162 	if (hdd_ctx->config->mac_provision) {
15163 		addr = hdd_get_platform_wlan_derived_mac_buff(dev,
15164 							      &no_of_mac_addr);
15165 
15166 		if (no_of_mac_addr == 0 || !addr)
15167 			hdd_warn("No derived address from platform driver");
15168 		else if (no_of_mac_addr >
15169 			 (max_mac_addr - hdd_ctx->num_provisioned_addr))
15170 			no_of_mac_addr = (max_mac_addr -
15171 					  hdd_ctx->num_provisioned_addr);
15172 
15173 		for (iter = 0; iter < no_of_mac_addr; ++iter,
15174 		     addr += mac_addr_size) {
15175 			buf = hdd_ctx->derived_mac_addr[iter].bytes;
15176 			qdf_mem_copy(buf, addr, QDF_MAC_ADDR_SIZE);
15177 			hdd_debug("derived MAC Addr [%d] "QDF_MAC_ADDR_FMT, iter,
15178 				  QDF_MAC_ADDR_REF(buf));
15179 		}
15180 		hdd_ctx->num_derived_addr = no_of_mac_addr;
15181 	}
15182 
15183 	no_of_mac_addr = hdd_ctx->num_provisioned_addr +
15184 					 hdd_ctx->num_derived_addr;
15185 	if (no_of_mac_addr < max_mac_addr)
15186 		hdd_populate_random_mac_addr(hdd_ctx, max_mac_addr -
15187 					     no_of_mac_addr);
15188 
15189 	status = sme_set_custom_mac_addr(mac_addr);
15190 	if (!QDF_IS_STATUS_SUCCESS(status))
15191 		return -EAGAIN;
15192 
15193 	return 0;
15194 }
15195 
15196 /**
15197  * hdd_update_mac_addr_to_fw() - API to update wlan mac addresses to FW
15198  * @hdd_ctx: HDD Context
15199  *
15200  * Update MAC address to FW. If MAC address passed by FW is invalid, host
15201  * will generate its own MAC and update it to FW.
15202  *
15203  * Return: 0 for success
15204  *         Non-zero error code for failure
15205  */
15206 static int hdd_update_mac_addr_to_fw(struct hdd_context *hdd_ctx)
15207 {
15208 	tSirMacAddr custom_mac_addr;
15209 	QDF_STATUS status;
15210 
15211 	if (hdd_ctx->num_provisioned_addr)
15212 		qdf_mem_copy(&custom_mac_addr,
15213 			     &hdd_ctx->provisioned_mac_addr[0].bytes[0],
15214 			     sizeof(tSirMacAddr));
15215 	else
15216 		qdf_mem_copy(&custom_mac_addr,
15217 			     &hdd_ctx->derived_mac_addr[0].bytes[0],
15218 			     sizeof(tSirMacAddr));
15219 	status = sme_set_custom_mac_addr(custom_mac_addr);
15220 	if (!QDF_IS_STATUS_SUCCESS(status))
15221 		return -EAGAIN;
15222 	return 0;
15223 }
15224 
15225 /**
15226  * hdd_initialize_mac_address() - API to get wlan mac addresses
15227  * @hdd_ctx: HDD Context
15228  *
15229  * Get MAC addresses from platform driver or wlan_mac.bin. If platform driver
15230  * is provisioned with mac addresses, driver uses it, else it will use
15231  * wlan_mac.bin to update HW MAC addresses.
15232  *
15233  * Return: None
15234  */
15235 static int hdd_initialize_mac_address(struct hdd_context *hdd_ctx)
15236 {
15237 	QDF_STATUS status;
15238 	int ret;
15239 
15240 	ret = hdd_platform_wlan_mac(hdd_ctx);
15241 	if (!ret) {
15242 		hdd_info("using MAC address from platform driver");
15243 		return ret;
15244 	} else if (hdd_ctx->config->mac_provision) {
15245 		hdd_err("getting MAC address from platform driver failed");
15246 		return ret;
15247 	}
15248 
15249 	status = hdd_update_mac_config(hdd_ctx);
15250 	if (QDF_IS_STATUS_SUCCESS(status)) {
15251 		hdd_info("using MAC address from wlan_mac.bin");
15252 		return 0;
15253 	}
15254 
15255 	hdd_info("using default MAC address");
15256 
15257 	/* Use fw provided MAC */
15258 	if (!qdf_is_macaddr_zero(&hdd_ctx->hw_macaddr)) {
15259 		hdd_update_macaddr(hdd_ctx, hdd_ctx->hw_macaddr, false);
15260 		return 0;
15261 	} else if (hdd_generate_macaddr_auto(hdd_ctx) != 0) {
15262 		struct qdf_mac_addr mac_addr;
15263 
15264 		hdd_err("MAC failure from device serial no.");
15265 		qdf_get_random_bytes(&mac_addr, sizeof(mac_addr));
15266 		/*
15267 		 * Reset multicast bit (bit-0) and set
15268 		 * locally-administered bit
15269 		 */
15270 		mac_addr.bytes[0] = 0x2;
15271 		hdd_update_macaddr(hdd_ctx, mac_addr, true);
15272 	}
15273 
15274 	ret = hdd_update_mac_addr_to_fw(hdd_ctx);
15275 	if (ret)
15276 		hdd_err("MAC address out-of-sync, ret:%d", ret);
15277 	return ret;
15278 }
15279 
15280 /* params being sent:
15281  * wmi_pdev_param_tx_chain_mask_1ss
15282  * wmi_pdev_param_mgmt_retry_limit
15283  * wmi_pdev_param_default_6ghz_rate
15284  * wmi_pdev_param_pdev_stats_tx_xretry_ext
15285  * wmi_pdev_param_smart_chainmask_scheme
15286  * wmi_pdev_param_alternative_chainmask_scheme
15287  * wmi_pdev_param_ani_enable
15288  * wmi_pdev_param_pcie_config
15289  */
15290 /**
15291  * hdd_pre_enable_configure() - Configurations prior to cds_enable
15292  * @hdd_ctx:	HDD context
15293  *
15294  * Pre configurations to be done at lower layer before calling cds enable.
15295  *
15296  * Return: 0 on success and errno on failure.
15297  */
15298 static int hdd_pre_enable_configure(struct hdd_context *hdd_ctx)
15299 {
15300 	int ret;
15301 	uint8_t val = 0;
15302 	uint8_t max_retry = 0;
15303 	bool enable_he_mcs0_for_6ghz_mgmt = false;
15304 	uint32_t tx_retry_multiplier;
15305 	QDF_STATUS status;
15306 	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
15307 	struct dev_set_param setparam[MAX_PDEV_PRE_ENABLE_PARAMS] = {};
15308 	bool check_value;
15309 	uint8_t index = 0;
15310 
15311 	cdp_register_pause_cb(soc, wlan_hdd_txrx_pause_cb);
15312 	/* Register HL netdev flow control callback */
15313 	cdp_hl_fc_register(soc, OL_TXRX_PDEV_ID, wlan_hdd_txrx_pause_cb);
15314 	/* Register rx mic error indication handler */
15315 	ucfg_dp_register_rx_mic_error_ind_handler(soc);
15316 
15317 	/*
15318 	 * Note that the cds_pre_enable() sequence triggers the cfg download.
15319 	 * The cfg download must occur before we update the SME config
15320 	 * since the SME config operation must access the cfg database
15321 	 */
15322 	status = hdd_set_sme_config(hdd_ctx);
15323 
15324 	if (QDF_STATUS_SUCCESS != status) {
15325 		hdd_err("Failed hdd_set_sme_config: %d", status);
15326 		ret = qdf_status_to_os_return(status);
15327 		goto out;
15328 	}
15329 
15330 	status = hdd_set_policy_mgr_user_cfg(hdd_ctx);
15331 	if (QDF_STATUS_SUCCESS != status) {
15332 		hdd_alert("Failed hdd_set_policy_mgr_user_cfg: %d", status);
15333 		ret = qdf_status_to_os_return(status);
15334 		goto out;
15335 	}
15336 
15337 	status = ucfg_mlme_get_tx_chainmask_1ss(hdd_ctx->psoc, &val);
15338 	if (QDF_STATUS_SUCCESS != status) {
15339 		hdd_err("Get tx_chainmask_1ss from mlme failed");
15340 		ret = qdf_status_to_os_return(status);
15341 		goto out;
15342 	}
15343 	ret = mlme_check_index_setparam(setparam,
15344 					wmi_pdev_param_tx_chain_mask_1ss,
15345 					val, index++,
15346 					MAX_PDEV_PRE_ENABLE_PARAMS);
15347 	if (QDF_IS_STATUS_ERROR(ret)) {
15348 		hdd_err("failed at wmi_pdev_param_tx_chain_mask_1ss");
15349 		goto out;
15350 
15351 	}
15352 
15353 	wlan_mlme_get_mgmt_max_retry(hdd_ctx->psoc, &max_retry);
15354 	ret = mlme_check_index_setparam(setparam,
15355 					wmi_pdev_param_mgmt_retry_limit,
15356 					max_retry, index++,
15357 					MAX_PDEV_PRE_ENABLE_PARAMS);
15358 	if (QDF_IS_STATUS_ERROR(ret)) {
15359 		hdd_err("failed at wmi_pdev_param_mgmt_retry_limit");
15360 		goto out;
15361 	}
15362 
15363 	wlan_mlme_get_mgmt_6ghz_rate_support(hdd_ctx->psoc,
15364 					     &enable_he_mcs0_for_6ghz_mgmt);
15365 	if (enable_he_mcs0_for_6ghz_mgmt) {
15366 		hdd_debug("HE rates for 6GHz mgmt frames are supported");
15367 		ret = mlme_check_index_setparam(
15368 					setparam,
15369 					wmi_pdev_param_default_6ghz_rate,
15370 					MGMT_DEFAULT_DATA_RATE_6GHZ, index++,
15371 					MAX_PDEV_PRE_ENABLE_PARAMS);
15372 		if (QDF_IS_STATUS_ERROR(ret)) {
15373 			hdd_err("wmi_pdev_param_default_6ghz_rate failed %d",
15374 				ret);
15375 			goto out;
15376 		}
15377 	}
15378 
15379 	wlan_mlme_get_tx_retry_multiplier(hdd_ctx->psoc,
15380 					  &tx_retry_multiplier);
15381 	ret = mlme_check_index_setparam(setparam,
15382 					wmi_pdev_param_pdev_stats_tx_xretry_ext,
15383 					tx_retry_multiplier, index++,
15384 					MAX_PDEV_PRE_ENABLE_PARAMS);
15385 	if (QDF_IS_STATUS_ERROR(ret)) {
15386 		hdd_err("failed at wmi_pdev_param_pdev_stats_tx_xretry_ext");
15387 		goto out;
15388 	}
15389 
15390 	ret = ucfg_get_smart_chainmask_enabled(hdd_ctx->psoc,
15391 					      &check_value);
15392 	if (QDF_IS_STATUS_SUCCESS(ret)) {
15393 		ret = mlme_check_index_setparam(
15394 					 setparam,
15395 					 wmi_pdev_param_smart_chainmask_scheme,
15396 					 (int)check_value, index++,
15397 					 MAX_PDEV_PRE_ENABLE_PARAMS);
15398 		if (QDF_IS_STATUS_ERROR(ret)) {
15399 			hdd_err("failed to set wmi_pdev_param_smart_chainmask_scheme");
15400 			goto out;
15401 		}
15402 	}
15403 
15404 	ret = ucfg_get_alternative_chainmask_enabled(hdd_ctx->psoc,
15405 						    &check_value);
15406 	if (QDF_IS_STATUS_SUCCESS(ret)) {
15407 		ret = mlme_check_index_setparam(
15408 				setparam,
15409 				wmi_pdev_param_alternative_chainmask_scheme,
15410 				(int)check_value, index++,
15411 				MAX_PDEV_PRE_ENABLE_PARAMS);
15412 		if (QDF_IS_STATUS_ERROR(ret)) {
15413 			hdd_err("failed to set wmi_pdev_param_alternative_chainmask_scheme");
15414 			goto out;
15415 		}
15416 	}
15417 
15418 	ret = ucfg_fwol_get_ani_enabled(hdd_ctx->psoc, &check_value);
15419 	if (QDF_IS_STATUS_SUCCESS(ret)) {
15420 		ret = mlme_check_index_setparam(setparam,
15421 						wmi_pdev_param_ani_enable,
15422 						(int)check_value, index++,
15423 						MAX_PDEV_PRE_ENABLE_PARAMS);
15424 		if (QDF_IS_STATUS_ERROR(ret)) {
15425 			hdd_err("failed to set wmi_pdev_param_ani_enable");
15426 			goto out;
15427 		}
15428 	}
15429 
15430 	ret = hdd_set_pcie_params(hdd_ctx, index, setparam);
15431 	if (QDF_IS_STATUS_ERROR(ret))
15432 		goto out;
15433 	else
15434 		index++;
15435 	ret = sme_send_multi_pdev_vdev_set_params(MLME_PDEV_SETPARAM,
15436 						  WMI_PDEV_ID_SOC, setparam,
15437 						  index);
15438 	if (QDF_IS_STATUS_ERROR(ret)) {
15439 		hdd_err("failed to send pdev set params");
15440 		goto out;
15441 	}
15442 
15443 	/* Configure global firmware params */
15444 	ret = ucfg_fwol_configure_global_params(hdd_ctx->psoc, hdd_ctx->pdev);
15445 	if (ret)
15446 		goto out;
15447 
15448 	status = hdd_set_sme_chan_list(hdd_ctx);
15449 	if (status != QDF_STATUS_SUCCESS) {
15450 		hdd_err("Failed to init channel list: %d", status);
15451 		ret = qdf_status_to_os_return(status);
15452 		goto out;
15453 	}
15454 
15455 	if (!hdd_update_config_cfg(hdd_ctx)) {
15456 		hdd_err("config update failed");
15457 		ret = -EINVAL;
15458 		goto out;
15459 	}
15460 	hdd_init_channel_avoidance(hdd_ctx);
15461 
15462 out:
15463 	return ret;
15464 }
15465 
15466 #ifdef FEATURE_P2P_LISTEN_OFFLOAD
15467 /**
15468  * wlan_hdd_p2p_lo_event_callback - P2P listen offload stop event handler
15469  * @context: context registered with sme_register_p2p_lo_event(). HDD
15470  *   always registers a hdd context pointer
15471  * @evt:event structure pointer
15472  *
15473  * This is the p2p listen offload stop event handler, it sends vendor
15474  * event back to supplicant to notify the stop reason.
15475  *
15476  * Return: None
15477  */
15478 static void wlan_hdd_p2p_lo_event_callback(void *context,
15479 					   struct sir_p2p_lo_event *evt)
15480 {
15481 	struct hdd_context *hdd_ctx = context;
15482 	struct sk_buff *vendor_event;
15483 	enum qca_nl80211_vendor_subcmds_index index =
15484 		QCA_NL80211_VENDOR_SUBCMD_P2P_LO_EVENT_INDEX;
15485 	struct wlan_hdd_link_info *link_info;
15486 
15487 	hdd_enter();
15488 
15489 	if (!hdd_ctx) {
15490 		hdd_err("Invalid HDD context pointer");
15491 		return;
15492 	}
15493 
15494 	link_info = hdd_get_link_info_by_vdev(hdd_ctx, evt->vdev_id);
15495 	if (!link_info) {
15496 		hdd_err("Cannot find adapter by vdev_id = %d",
15497 				evt->vdev_id);
15498 		return;
15499 	}
15500 
15501 	vendor_event =
15502 		wlan_cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
15503 						 &link_info->adapter->wdev,
15504 						 sizeof(uint32_t) +
15505 						 NLMSG_HDRLEN,
15506 						 index, GFP_KERNEL);
15507 	if (!vendor_event) {
15508 		hdd_err("wlan_cfg80211_vendor_event_alloc failed");
15509 		return;
15510 	}
15511 
15512 	if (nla_put_u32(vendor_event,
15513 			QCA_WLAN_VENDOR_ATTR_P2P_LISTEN_OFFLOAD_STOP_REASON,
15514 			evt->reason_code)) {
15515 		hdd_err("nla put failed");
15516 		wlan_cfg80211_vendor_free_skb(vendor_event);
15517 		return;
15518 	}
15519 
15520 	wlan_cfg80211_vendor_event(vendor_event, GFP_KERNEL);
15521 	hdd_debug("Sent P2P_LISTEN_OFFLOAD_STOP event for vdev_id = %d",
15522 			evt->vdev_id);
15523 }
15524 #else
15525 static void wlan_hdd_p2p_lo_event_callback(void *context,
15526 					   struct sir_p2p_lo_event *evt)
15527 {
15528 }
15529 #endif
15530 
15531 #ifdef FEATURE_WLAN_DYNAMIC_CVM
15532 static inline int hdd_set_vc_mode_config(struct hdd_context *hdd_ctx)
15533 {
15534 	return sme_set_vc_mode_config(hdd_ctx->config->vc_mode_cfg_bitmap);
15535 }
15536 #else
15537 static inline int hdd_set_vc_mode_config(struct hdd_context *hdd_ctx)
15538 {
15539 	return QDF_STATUS_SUCCESS;
15540 }
15541 #endif
15542 
15543 /**
15544  * hdd_adaptive_dwelltime_init() - initialization for adaptive dwell time config
15545  * @hdd_ctx: HDD context
15546  *
15547  * This function sends the adaptive dwell time config configuration to the
15548  * firmware via WMA
15549  *
15550  * Return: 0 - success, < 0 - failure
15551  */
15552 static int hdd_adaptive_dwelltime_init(struct hdd_context *hdd_ctx)
15553 {
15554 	QDF_STATUS status;
15555 	struct adaptive_dwelltime_params dwelltime_params;
15556 
15557 	status = ucfg_fwol_get_all_adaptive_dwelltime_params(hdd_ctx->psoc,
15558 							     &dwelltime_params);
15559 	status = ucfg_fwol_set_adaptive_dwelltime_config(&dwelltime_params);
15560 
15561 	hdd_debug("Sending Adaptive Dwelltime Configuration to fw");
15562 	if (!QDF_IS_STATUS_SUCCESS(status)) {
15563 		hdd_err("Failed to send Adaptive Dwelltime configuration!");
15564 		return -EAGAIN;
15565 	}
15566 	return 0;
15567 }
15568 
15569 int hdd_dbs_scan_selection_init(struct hdd_context *hdd_ctx)
15570 {
15571 	QDF_STATUS status;
15572 	struct wmi_dbs_scan_sel_params dbs_scan_params;
15573 	uint32_t i = 0;
15574 	uint8_t count = 0, numentries = 0;
15575 	uint8_t dual_mac_feature;
15576 	uint8_t dbs_scan_config[CDS_DBS_SCAN_PARAM_PER_CLIENT
15577 				* CDS_DBS_SCAN_CLIENTS_MAX];
15578 
15579 	status = ucfg_policy_mgr_get_dual_mac_feature(hdd_ctx->psoc,
15580 						      &dual_mac_feature);
15581 
15582 	if (status != QDF_STATUS_SUCCESS) {
15583 		hdd_err("can't get dual mac feature flag");
15584 		return -EINVAL;
15585 	}
15586 	/* check if DBS is enabled or supported */
15587 	if ((dual_mac_feature == DISABLE_DBS_CXN_AND_SCAN) ||
15588 	    (dual_mac_feature == ENABLE_DBS_CXN_AND_DISABLE_DBS_SCAN))
15589 		return -EINVAL;
15590 
15591 	hdd_string_to_u8_array(hdd_ctx->config->dbs_scan_selection,
15592 			       dbs_scan_config, &numentries,
15593 			       (CDS_DBS_SCAN_PARAM_PER_CLIENT
15594 				* CDS_DBS_SCAN_CLIENTS_MAX));
15595 
15596 	if (!numentries) {
15597 		hdd_debug("Do not send scan_selection_config");
15598 		return 0;
15599 	}
15600 
15601 	/* hdd_set_fw_log_params */
15602 	dbs_scan_params.num_clients = 0;
15603 	while (count < (numentries - 2)) {
15604 		dbs_scan_params.module_id[i] = dbs_scan_config[count];
15605 		dbs_scan_params.num_dbs_scans[i] = dbs_scan_config[count + 1];
15606 		dbs_scan_params.num_non_dbs_scans[i] =
15607 			dbs_scan_config[count + 2];
15608 		dbs_scan_params.num_clients++;
15609 		hdd_debug("module:%d NDS:%d NNDS:%d",
15610 			  dbs_scan_params.module_id[i],
15611 			  dbs_scan_params.num_dbs_scans[i],
15612 			  dbs_scan_params.num_non_dbs_scans[i]);
15613 		count += CDS_DBS_SCAN_PARAM_PER_CLIENT;
15614 		i++;
15615 	}
15616 
15617 	dbs_scan_params.pdev_id = 0;
15618 
15619 	hdd_debug("clients:%d pdev:%d",
15620 		  dbs_scan_params.num_clients, dbs_scan_params.pdev_id);
15621 
15622 	status = sme_set_dbs_scan_selection_config(hdd_ctx->mac_handle,
15623 						   &dbs_scan_params);
15624 	hdd_debug("Sending DBS Scan Selection Configuration to fw");
15625 	if (!QDF_IS_STATUS_SUCCESS(status)) {
15626 		hdd_err("Failed to send DBS Scan selection configuration!");
15627 		return -EAGAIN;
15628 	}
15629 	return 0;
15630 }
15631 
15632 #ifdef FEATURE_WLAN_AUTO_SHUTDOWN
15633 /**
15634  * hdd_set_auto_shutdown_cb() - Set auto shutdown callback
15635  * @hdd_ctx:	HDD context
15636  *
15637  * Set auto shutdown callback to get indications from firmware to indicate
15638  * userspace to shutdown WLAN after a configured amount of inactivity.
15639  *
15640  * Return: 0 on success and errno on failure.
15641  */
15642 static int hdd_set_auto_shutdown_cb(struct hdd_context *hdd_ctx)
15643 {
15644 	QDF_STATUS status;
15645 
15646 	if (!hdd_ctx->config->wlan_auto_shutdown)
15647 		return 0;
15648 
15649 	status = sme_set_auto_shutdown_cb(hdd_ctx->mac_handle,
15650 					  wlan_hdd_auto_shutdown_cb);
15651 	if (status != QDF_STATUS_SUCCESS)
15652 		hdd_err("Auto shutdown feature could not be enabled: %d",
15653 			status);
15654 
15655 	return qdf_status_to_os_return(status);
15656 }
15657 #else
15658 static int hdd_set_auto_shutdown_cb(struct hdd_context *hdd_ctx)
15659 {
15660 	return 0;
15661 }
15662 #endif
15663 
15664 #ifdef MWS_COEX
15665 #define MAX_PDEV_MWSCOEX_PARAMS 4
15666 /* params being sent:
15667  * wmi_pdev_param_mwscoex_4g_allow_quick_ftdm
15668  * wmi_pdev_param_mwscoex_set_5gnr_pwr_limit
15669  * wmi_pdev_param_mwscoex_pcc_chavd_delay
15670  * wmi_pdev_param_mwscoex_scc_chavd_delay
15671  */
15672 
15673 /**
15674  * hdd_init_mws_coex() - Initialize MWS coex configurations
15675  * @hdd_ctx:   HDD context
15676  *
15677  * This function sends MWS-COEX 4G quick FTDM and
15678  * MWS-COEX 5G-NR power limit to FW
15679  *
15680  * Return: 0 on success and errno on failure.
15681  */
15682 static int hdd_init_mws_coex(struct hdd_context *hdd_ctx)
15683 {
15684 	int ret = 0;
15685 	uint32_t mws_coex_4g_quick_tdm = 0, mws_coex_5g_nr_pwr_limit = 0;
15686 	uint32_t mws_coex_pcc_channel_avoid_delay = 0;
15687 	uint32_t mws_coex_scc_channel_avoid_delay = 0;
15688 	struct dev_set_param setparam[MAX_PDEV_MWSCOEX_PARAMS] = {};
15689 	uint8_t index = 0;
15690 
15691 	ucfg_mlme_get_mws_coex_4g_quick_tdm(hdd_ctx->psoc,
15692 					    &mws_coex_4g_quick_tdm);
15693 	ret = mlme_check_index_setparam(
15694 				setparam,
15695 				wmi_pdev_param_mwscoex_4g_allow_quick_ftdm,
15696 				mws_coex_4g_quick_tdm, index++,
15697 				MAX_PDEV_MWSCOEX_PARAMS);
15698 	if (QDF_IS_STATUS_ERROR(ret)) {
15699 		hdd_err("failed at wmi_pdev_param_mwscoex_4g_allow_quick_ftdm");
15700 		goto error;
15701 	}
15702 
15703 	ucfg_mlme_get_mws_coex_5g_nr_pwr_limit(hdd_ctx->psoc,
15704 					       &mws_coex_5g_nr_pwr_limit);
15705 	ret = mlme_check_index_setparam(
15706 				      setparam,
15707 				      wmi_pdev_param_mwscoex_set_5gnr_pwr_limit,
15708 				      mws_coex_5g_nr_pwr_limit, index++,
15709 				      MAX_PDEV_MWSCOEX_PARAMS);
15710 	if (QDF_IS_STATUS_ERROR(ret)) {
15711 		hdd_err("failed at wmi_pdev_param_mwscoex_set_5gnr_pwr_limit");
15712 		goto error;
15713 	}
15714 
15715 	ucfg_mlme_get_mws_coex_pcc_channel_avoid_delay(
15716 					hdd_ctx->psoc,
15717 					&mws_coex_pcc_channel_avoid_delay);
15718 	ret = mlme_check_index_setparam(setparam,
15719 					wmi_pdev_param_mwscoex_pcc_chavd_delay,
15720 					mws_coex_pcc_channel_avoid_delay,
15721 					index++, MAX_PDEV_MWSCOEX_PARAMS);
15722 	if (QDF_IS_STATUS_ERROR(ret)) {
15723 		hdd_err("failed at wmi_pdev_param_mwscoex_pcc_chavd_delay");
15724 		goto error;
15725 	}
15726 
15727 	ucfg_mlme_get_mws_coex_scc_channel_avoid_delay(
15728 					hdd_ctx->psoc,
15729 					&mws_coex_scc_channel_avoid_delay);
15730 	ret = mlme_check_index_setparam(setparam,
15731 					wmi_pdev_param_mwscoex_scc_chavd_delay,
15732 					mws_coex_scc_channel_avoid_delay,
15733 					index++, MAX_PDEV_MWSCOEX_PARAMS);
15734 	if (QDF_IS_STATUS_ERROR(ret)) {
15735 		hdd_err("failed at wmi_pdev_param_mwscoex_scc_chavd_delay");
15736 		goto error;
15737 	}
15738 	ret = sme_send_multi_pdev_vdev_set_params(MLME_PDEV_SETPARAM,
15739 						  WMI_PDEV_ID_SOC, setparam,
15740 						  index);
15741 	if (QDF_IS_STATUS_ERROR(ret))
15742 		hdd_err("failed to send pdev MWSCOEX set params");
15743 error:
15744 	return ret;
15745 }
15746 #else
15747 static int hdd_init_mws_coex(struct hdd_context *hdd_ctx)
15748 {
15749 	return 0;
15750 }
15751 #endif
15752 
15753 #ifdef THERMAL_STATS_SUPPORT
15754 static void hdd_thermal_stats_cmd_init(struct hdd_context *hdd_ctx)
15755 {
15756 	hdd_send_get_thermal_stats_cmd(hdd_ctx, thermal_stats_init, NULL, NULL);
15757 }
15758 #else
15759 static void hdd_thermal_stats_cmd_init(struct hdd_context *hdd_ctx)
15760 {
15761 }
15762 #endif
15763 
15764 #ifdef WLAN_FEATURE_CAL_FAILURE_TRIGGER
15765 /**
15766  * hdd_cal_fail_send_event()- send calibration failure information
15767  * @cal_type: calibration type
15768  * @reason: reason for calibration failure
15769  *
15770  * This Function sends calibration failure diag event
15771  *
15772  * Return: void.
15773  */
15774 static void hdd_cal_fail_send_event(uint8_t cal_type, uint8_t reason)
15775 {
15776 	/*
15777 	 * For now we are going with the print. Once CST APK has support to
15778 	 * read the diag events then we will add the diag event here.
15779 	 */
15780 	hdd_debug("Received cal failure event with cal_type:%x reason:%x",
15781 		  cal_type, reason);
15782 }
15783 #else
15784 static inline void hdd_cal_fail_send_event(uint8_t cal_type, uint8_t reason)
15785 {
15786 }
15787 #endif
15788 
15789 /**
15790  * hdd_features_init() - Init features
15791  * @hdd_ctx:	HDD context
15792  *
15793  * Initialize features and their feature context after WLAN firmware is up.
15794  *
15795  * Return: 0 on success and errno on failure.
15796  */
15797 static int hdd_features_init(struct hdd_context *hdd_ctx)
15798 {
15799 	struct tx_power_limit hddtxlimit;
15800 	QDF_STATUS status;
15801 	int ret;
15802 	mac_handle_t mac_handle;
15803 	bool b_cts2self, is_imps_enabled;
15804 	bool rf_test_mode;
15805 	bool std_6ghz_conn_policy;
15806 	uint32_t fw_data_stall_evt;
15807 	bool disable_vlp_sta_conn_sp_ap;
15808 
15809 	hdd_enter();
15810 
15811 	ret = hdd_init_mws_coex(hdd_ctx);
15812 	if (ret)
15813 		hdd_warn("Error initializing mws-coex");
15814 
15815 	/* FW capabilities received, Set the Dot11 mode */
15816 	mac_handle = hdd_ctx->mac_handle;
15817 	sme_setdef_dot11mode(mac_handle);
15818 
15819 	ucfg_mlme_is_imps_enabled(hdd_ctx->psoc, &is_imps_enabled);
15820 	hdd_set_idle_ps_config(hdd_ctx, is_imps_enabled);
15821 
15822 	fw_data_stall_evt = ucfg_dp_fw_data_stall_evt_enabled();
15823 
15824 	/* Send Enable/Disable data stall detection cmd to FW */
15825 	sme_cli_set_command(0, wmi_pdev_param_data_stall_detect_enable,
15826 			    fw_data_stall_evt, PDEV_CMD);
15827 
15828 	ucfg_mlme_get_go_cts2self_for_sta(hdd_ctx->psoc, &b_cts2self);
15829 	if (b_cts2self)
15830 		sme_set_cts2self_for_p2p_go(mac_handle);
15831 
15832 	if (hdd_set_vc_mode_config(hdd_ctx))
15833 		hdd_warn("Error in setting Voltage Corner mode config to FW");
15834 
15835 	if (ucfg_dp_rx_ol_init(hdd_ctx->psoc, hdd_ctx->is_wifi3_0_target))
15836 		hdd_err("Unable to initialize Rx LRO/GRO in fw");
15837 
15838 	if (hdd_adaptive_dwelltime_init(hdd_ctx))
15839 		hdd_err("Unable to send adaptive dwelltime setting to FW");
15840 
15841 	if (hdd_dbs_scan_selection_init(hdd_ctx))
15842 		hdd_err("Unable to send DBS scan selection setting to FW");
15843 
15844 	ret = hdd_init_thermal_info(hdd_ctx);
15845 	if (ret) {
15846 		hdd_err("Error while initializing thermal information");
15847 		return ret;
15848 	}
15849 
15850 	/**
15851 	 * In case of SSR/PDR, if pktlog was enabled manually before
15852 	 * SSR/PDR, then enable it again automatically after Wlan
15853 	 * device up.
15854 	 * During SSR/PDR, pktlog will be disabled as part of
15855 	 * hdd_features_deinit if pktlog is enabled in ini.
15856 	 * Re-enable pktlog in SSR case, if pktlog is enabled in ini.
15857 	 */
15858 	if (hdd_get_conparam() != QDF_GLOBAL_MONITOR_MODE &&
15859 	    (cds_is_packet_log_enabled() ||
15860 	    (cds_is_driver_recovering() && hdd_ctx->is_pktlog_enabled)))
15861 		hdd_pktlog_enable_disable(hdd_ctx, true, 0, 0);
15862 
15863 	hddtxlimit.txPower2g = ucfg_get_tx_power(hdd_ctx->psoc, BAND_2G);
15864 	hddtxlimit.txPower5g = ucfg_get_tx_power(hdd_ctx->psoc, BAND_5G);
15865 	status = sme_txpower_limit(mac_handle, &hddtxlimit);
15866 	if (!QDF_IS_STATUS_SUCCESS(status))
15867 		hdd_err("Error setting txlimit in sme: %d", status);
15868 
15869 	wlan_hdd_tsf_init(hdd_ctx);
15870 
15871 	status = sme_enable_disable_chanavoidind_event(mac_handle, 0);
15872 	if (QDF_IS_STATUS_ERROR(status) && (status != QDF_STATUS_E_NOSUPPORT)) {
15873 		hdd_err("Failed to disable Chan Avoidance Indication");
15874 		return -EINVAL;
15875 	}
15876 
15877 	/* register P2P Listen Offload event callback */
15878 	if (wma_is_p2p_lo_capable())
15879 		sme_register_p2p_lo_event(mac_handle, hdd_ctx,
15880 					  wlan_hdd_p2p_lo_event_callback);
15881 	wlan_hdd_register_mcc_quota_event_callback(hdd_ctx);
15882 	ret = hdd_set_auto_shutdown_cb(hdd_ctx);
15883 
15884 	if (ret)
15885 		return -EINVAL;
15886 
15887 	wlan_hdd_init_chan_info(hdd_ctx);
15888 	wlan_hdd_twt_init(hdd_ctx);
15889 	wlan_hdd_gpio_wakeup_init(hdd_ctx);
15890 
15891 	status = ucfg_mlme_is_rf_test_mode_enabled(hdd_ctx->psoc,
15892 						   &rf_test_mode);
15893 	if (!QDF_IS_STATUS_SUCCESS(status)) {
15894 		hdd_err("Get rf test mode failed");
15895 		return QDF_STATUS_E_FAILURE;
15896 	}
15897 
15898 	if (rf_test_mode) {
15899 		wlan_cm_set_check_6ghz_security(hdd_ctx->psoc, false);
15900 		wlan_cm_set_6ghz_key_mgmt_mask(hdd_ctx->psoc,
15901 					       DEFAULT_KEYMGMT_6G_MASK);
15902 	}
15903 
15904 	status = ucfg_mlme_is_standard_6ghz_conn_policy_enabled(hdd_ctx->psoc,
15905 							&std_6ghz_conn_policy);
15906 
15907 	if (!QDF_IS_STATUS_SUCCESS(status)) {
15908 		hdd_err("Get 6ghz standard connection policy failed");
15909 		return QDF_STATUS_E_FAILURE;
15910 	}
15911 	if (std_6ghz_conn_policy)
15912 		wlan_cm_set_standard_6ghz_conn_policy(hdd_ctx->psoc, true);
15913 
15914 	status = ucfg_mlme_is_disable_vlp_sta_conn_to_sp_ap_enabled(
15915 						hdd_ctx->psoc,
15916 						&disable_vlp_sta_conn_sp_ap);
15917 	if (!QDF_IS_STATUS_SUCCESS(status)) {
15918 		hdd_err("Get disable vlp sta conn to sp flag failed");
15919 		return QDF_STATUS_E_FAILURE;
15920 	}
15921 
15922 	if (disable_vlp_sta_conn_sp_ap)
15923 		wlan_cm_set_disable_vlp_sta_conn_to_sp_ap(hdd_ctx->psoc, true);
15924 
15925 	hdd_thermal_stats_cmd_init(hdd_ctx);
15926 	sme_set_cal_failure_event_cb(hdd_ctx->mac_handle,
15927 				     hdd_cal_fail_send_event);
15928 
15929 	hdd_exit();
15930 	return 0;
15931 }
15932 
15933 /**
15934  * hdd_register_bcn_cb() - register scan beacon callback
15935  * @hdd_ctx: Pointer to the HDD context
15936  *
15937  * Return: QDF_STATUS
15938  */
15939 static inline QDF_STATUS hdd_register_bcn_cb(struct hdd_context *hdd_ctx)
15940 {
15941 	QDF_STATUS status;
15942 
15943 	status = ucfg_scan_register_bcn_cb(hdd_ctx->psoc,
15944 		wlan_cfg80211_inform_bss_frame,
15945 		SCAN_CB_TYPE_INFORM_BCN);
15946 	if (!QDF_IS_STATUS_SUCCESS(status)) {
15947 		hdd_err("failed to register SCAN_CB_TYPE_INFORM_BCN with status code %08d [x%08x]",
15948 			status, status);
15949 		return status;
15950 	}
15951 
15952 	status = ucfg_scan_register_bcn_cb(hdd_ctx->psoc,
15953 		wlan_cfg80211_unlink_bss_list,
15954 		SCAN_CB_TYPE_UNLINK_BSS);
15955 	if (!QDF_IS_STATUS_SUCCESS(status)) {
15956 		hdd_err("failed to refister SCAN_CB_TYPE_FLUSH_BSS with status code %08d [x%08x]",
15957 			status, status);
15958 		return status;
15959 	}
15960 
15961 	return QDF_STATUS_SUCCESS;
15962 }
15963 
15964 /**
15965  * hdd_v2_flow_pool_map() - Flow pool create callback when vdev is active
15966  * @vdev_id: vdev_id, corresponds to flow_pool
15967  *
15968  * Return: none.
15969  */
15970 static void hdd_v2_flow_pool_map(int vdev_id)
15971 {
15972 	QDF_STATUS status;
15973 	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
15974 	struct wlan_objmgr_vdev *vdev;
15975 
15976 	if (!hdd_ctx) {
15977 		hdd_err("HDD context null");
15978 		return;
15979 	}
15980 
15981 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(hdd_ctx->psoc, vdev_id,
15982 						    WLAN_OSIF_ID);
15983 	if (!vdev) {
15984 		hdd_err("Invalid VDEV %d", vdev_id);
15985 		return;
15986 	}
15987 
15988 	if (wlan_vdev_mlme_is_mlo_link_switch_in_progress(vdev)) {
15989 		hdd_info("Link switch ongoing, do not invoke flow pool map");
15990 		goto release_ref;
15991 	}
15992 
15993 	status = cdp_flow_pool_map(cds_get_context(QDF_MODULE_ID_SOC),
15994 				   OL_TXRX_PDEV_ID, vdev_id);
15995 	/*
15996 	 * For Adrastea flow control v2 is based on FW MAP events,
15997 	 * so this above callback is not implemented.
15998 	 * Hence this is not actual failure. Dont return failure
15999 	 */
16000 	if ((status != QDF_STATUS_SUCCESS) &&
16001 	    (status != QDF_STATUS_E_INVAL)) {
16002 		hdd_err("vdev_id: %d, failed to create flow pool status %d",
16003 			vdev_id, status);
16004 	}
16005 
16006 release_ref:
16007 	wlan_objmgr_vdev_release_ref(vdev, WLAN_OSIF_ID);
16008 }
16009 
16010 /**
16011  * hdd_v2_flow_pool_unmap() - Flow pool create callback when vdev is not active
16012  * @vdev_id: vdev_id, corresponds to flow_pool
16013  *
16014  * Return: none.
16015  */
16016 static void hdd_v2_flow_pool_unmap(int vdev_id)
16017 {
16018 	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
16019 	struct wlan_objmgr_vdev *vdev;
16020 
16021 	if (!hdd_ctx) {
16022 		hdd_err("HDD context null");
16023 		return;
16024 	}
16025 
16026 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(hdd_ctx->psoc, vdev_id,
16027 						    WLAN_OSIF_ID);
16028 	if (!vdev) {
16029 		hdd_err("Invalid VDEV %d", vdev_id);
16030 		return;
16031 	}
16032 
16033 	if (wlan_vdev_mlme_is_mlo_link_switch_in_progress(vdev)) {
16034 		hdd_info("Link switch ongoing do not invoke flow pool unmap");
16035 		goto release_ref;
16036 	}
16037 
16038 	cdp_flow_pool_unmap(cds_get_context(QDF_MODULE_ID_SOC),
16039 			    OL_TXRX_PDEV_ID, vdev_id);
16040 release_ref:
16041 	wlan_objmgr_vdev_release_ref(vdev, WLAN_OSIF_ID);
16042 }
16043 
16044 static void hdd_hastings_bt_war_initialize(struct hdd_context *hdd_ctx)
16045 {
16046 	if (hdd_ctx->config->iface_change_wait_time)
16047 		hdd_hastings_bt_war_disable_fw(hdd_ctx);
16048 	else
16049 		hdd_hastings_bt_war_enable_fw(hdd_ctx);
16050 }
16051 
16052 #define MAX_PDEV_CFG_CDS_PARAMS 8
16053 /* params being sent:
16054  * wmi_pdev_param_set_iot_pattern
16055  * wmi_pdev_param_max_mpdus_in_ampdu
16056  * wmi_pdev_param_enable_rts_sifs_bursting
16057  * wmi_pdev_param_peer_stats_info_enable
16058  * wmi_pdev_param_abg_mode_tx_chain_num
16059  * wmi_pdev_param_gcmp_support_enable
16060  * wmi_pdev_auto_detect_power_failure
16061  * wmi_pdev_param_fast_pwr_transition
16062  */
16063 
16064 /**
16065  * hdd_configure_cds() - Configure cds modules
16066  * @hdd_ctx:	HDD context
16067  *
16068  * Enable Cds modules after WLAN firmware is up.
16069  *
16070  * Return: 0 on success and errno on failure.
16071  */
16072 int hdd_configure_cds(struct hdd_context *hdd_ctx)
16073 {
16074 	int ret;
16075 	QDF_STATUS status;
16076 	int set_value;
16077 	mac_handle_t mac_handle;
16078 	bool enable_rts_sifsbursting;
16079 	uint8_t enable_phy_reg_retention;
16080 	uint8_t max_mpdus_inampdu, is_force_1x1 = 0;
16081 	uint32_t num_abg_tx_chains = 0;
16082 	uint16_t num_11b_tx_chains = 0;
16083 	uint16_t num_11ag_tx_chains = 0;
16084 	struct policy_mgr_dp_cbacks dp_cbs = {0};
16085 	bool value;
16086 	enum pmo_auto_pwr_detect_failure_mode auto_power_fail_mode;
16087 	bool bval = false;
16088 	uint8_t max_index = MAX_PDEV_CFG_CDS_PARAMS;
16089 	struct dev_set_param setparam[MAX_PDEV_CFG_CDS_PARAMS] = {};
16090 	uint8_t index = 0;
16091 	uint8_t next_index = 0;
16092 	mac_handle = hdd_ctx->mac_handle;
16093 
16094 	status = ucfg_policy_mgr_get_force_1x1(hdd_ctx->psoc, &is_force_1x1);
16095 	if (status != QDF_STATUS_SUCCESS) {
16096 		hdd_err("Failed to get force 1x1 value");
16097 		goto out;
16098 	}
16099 	if (is_force_1x1) {
16100 		status = mlme_check_index_setparam(
16101 						setparam,
16102 						wmi_pdev_param_set_iot_pattern,
16103 						1, index++,
16104 						max_index);
16105 		if (QDF_IS_STATUS_ERROR(status)) {
16106 			hdd_err("failed at wmi_pdev_param_set_iot_pattern");
16107 			goto out;
16108 		}
16109 	}
16110 	/* set chip power save failure detected callback */
16111 	sme_set_chip_pwr_save_fail_cb(mac_handle,
16112 				      hdd_chip_pwr_save_fail_detected_cb);
16113 
16114 	status = ucfg_get_max_mpdus_inampdu(hdd_ctx->psoc,
16115 					    &max_mpdus_inampdu);
16116 	if (status) {
16117 		hdd_err("Failed to get max mpdus in ampdu value");
16118 		goto out;
16119 	}
16120 
16121 	if (max_mpdus_inampdu) {
16122 		set_value = max_mpdus_inampdu;
16123 		status = mlme_check_index_setparam(
16124 					      setparam,
16125 					      wmi_pdev_param_max_mpdus_in_ampdu,
16126 					      set_value, index++,
16127 					      max_index);
16128 		if (QDF_IS_STATUS_ERROR(status)) {
16129 			hdd_err("failed at  wmi_pdev_param_max_mpdus_in_ampdu");
16130 			goto out;
16131 		}
16132 	}
16133 
16134 	status = ucfg_get_enable_rts_sifsbursting(hdd_ctx->psoc,
16135 						  &enable_rts_sifsbursting);
16136 	if (status) {
16137 		hdd_err("Failed to get rts sifs bursting value");
16138 		goto out;
16139 	}
16140 
16141 	if (enable_rts_sifsbursting) {
16142 		set_value = enable_rts_sifsbursting;
16143 		status = mlme_check_index_setparam(
16144 					setparam,
16145 					wmi_pdev_param_enable_rts_sifs_bursting,
16146 					set_value, index++,
16147 					max_index);
16148 		if (QDF_IS_STATUS_ERROR(status)) {
16149 			hdd_err("Failed at wmi_pdev_param_enable_rts_sifs_bursting");
16150 			goto out;
16151 		}
16152 	}
16153 
16154 	ucfg_mlme_get_sap_get_peer_info(hdd_ctx->psoc, &value);
16155 	if (value) {
16156 		set_value = value;
16157 		status = mlme_check_index_setparam(
16158 					setparam,
16159 					wmi_pdev_param_peer_stats_info_enable,
16160 					set_value, index++,
16161 					max_index);
16162 		if (QDF_IS_STATUS_ERROR(status)) {
16163 			hdd_err("Failed at wmi_pdev_param_peer_stats_info_enable");
16164 			goto out;
16165 		}
16166 	}
16167 
16168 	status = ucfg_mlme_get_num_11b_tx_chains(hdd_ctx->psoc,
16169 						 &num_11b_tx_chains);
16170 	if (status != QDF_STATUS_SUCCESS) {
16171 		hdd_err("Failed to get num_11b_tx_chains");
16172 		goto out;
16173 	}
16174 
16175 	status = ucfg_mlme_get_num_11ag_tx_chains(hdd_ctx->psoc,
16176 						  &num_11ag_tx_chains);
16177 	if (status != QDF_STATUS_SUCCESS) {
16178 		hdd_err("Failed to get num_11ag_tx_chains");
16179 		goto out;
16180 	}
16181 
16182 	status = ucfg_mlme_get_vht_enable2x2(hdd_ctx->psoc, &bval);
16183 	if (!QDF_IS_STATUS_SUCCESS(status))
16184 		hdd_err("unable to get vht_enable2x2");
16185 
16186 	if (!bval) {
16187 		if (num_11b_tx_chains > 1)
16188 			num_11b_tx_chains = 1;
16189 		if (num_11ag_tx_chains > 1)
16190 			num_11ag_tx_chains = 1;
16191 	}
16192 	WMI_PDEV_PARAM_SET_11B_TX_CHAIN_NUM(num_abg_tx_chains,
16193 					    num_11b_tx_chains);
16194 	WMI_PDEV_PARAM_SET_11AG_TX_CHAIN_NUM(num_abg_tx_chains,
16195 					     num_11ag_tx_chains);
16196 	status = mlme_check_index_setparam(setparam,
16197 					   wmi_pdev_param_abg_mode_tx_chain_num,
16198 					   num_abg_tx_chains, index++,
16199 					   max_index);
16200 	if (QDF_IS_STATUS_ERROR(status)) {
16201 		hdd_err("Failed at wmi_pdev_param_abg_mode_tx_chain_num");
16202 		goto out;
16203 	}
16204 	/* Send some pdev params to maintain legacy order of pdev set params
16205 	 * at hdd_pre_enable_configure
16206 	 */
16207 	status = sme_send_multi_pdev_vdev_set_params(MLME_PDEV_SETPARAM,
16208 						     WMI_PDEV_ID_SOC, setparam,
16209 						     index);
16210 	if (QDF_IS_STATUS_ERROR(status)) {
16211 		hdd_err("Failed to send 1st set of pdev params");
16212 		goto out;
16213 	}
16214 	if (!ucfg_reg_is_regdb_offloaded(hdd_ctx->psoc))
16215 		ucfg_reg_program_default_cc(hdd_ctx->pdev,
16216 					    hdd_ctx->reg.reg_domain);
16217 
16218 	ret = hdd_pre_enable_configure(hdd_ctx);
16219 	if (ret) {
16220 		hdd_err("Failed to pre-configure cds");
16221 		goto out;
16222 	}
16223 
16224 	/* Always get latest IPA resources allocated from cds_open and configure
16225 	 * IPA module before configuring them to FW. Sequence required as crash
16226 	 * observed otherwise.
16227 	 */
16228 
16229 	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
16230 		ipa_disable_register_cb();
16231 	} else {
16232 		status = ipa_register_is_ipa_ready(hdd_ctx->pdev);
16233 		if (!QDF_IS_STATUS_SUCCESS(status)) {
16234 			hdd_err("ipa_register_is_ipa_ready failed");
16235 			goto out;
16236 		}
16237 	}
16238 
16239 	/*
16240 	 * Start CDS which starts up the SME/MAC/HAL modules and everything
16241 	 * else
16242 	 */
16243 	status = cds_enable(hdd_ctx->psoc);
16244 
16245 	if (!QDF_IS_STATUS_SUCCESS(status)) {
16246 		hdd_err("cds_enable failed");
16247 		goto out;
16248 	}
16249 
16250 	status = hdd_post_cds_enable_config(hdd_ctx);
16251 	if (!QDF_IS_STATUS_SUCCESS(status)) {
16252 		hdd_err("hdd_post_cds_enable_config failed");
16253 		goto cds_disable;
16254 	}
16255 	status = hdd_register_bcn_cb(hdd_ctx);
16256 	if (!QDF_IS_STATUS_SUCCESS(status)) {
16257 		hdd_err("hdd_register_bcn_cb failed");
16258 		goto cds_disable;
16259 	}
16260 
16261 	ret = hdd_features_init(hdd_ctx);
16262 	if (ret)
16263 		goto cds_disable;
16264 
16265 	/*
16266 	 * Donot disable rx offload on concurrency for lithium and
16267 	 * beryllium based targets
16268 	 */
16269 	if (!hdd_ctx->is_wifi3_0_target)
16270 		if (ucfg_dp_is_ol_enabled(hdd_ctx->psoc))
16271 			dp_cbs.hdd_disable_rx_ol_in_concurrency =
16272 					hdd_disable_rx_ol_in_concurrency;
16273 	dp_cbs.hdd_set_rx_mode_rps_cb = ucfg_dp_set_rx_mode_rps;
16274 	dp_cbs.hdd_ipa_set_mcc_mode_cb = hdd_ipa_set_mcc_mode;
16275 	dp_cbs.hdd_v2_flow_pool_map = hdd_v2_flow_pool_map;
16276 	dp_cbs.hdd_v2_flow_pool_unmap = hdd_v2_flow_pool_unmap;
16277 	status = policy_mgr_register_dp_cb(hdd_ctx->psoc, &dp_cbs);
16278 	if (!QDF_IS_STATUS_SUCCESS(status)) {
16279 		hdd_debug("Failed to register DP cb with Policy Manager");
16280 		goto cds_disable;
16281 	}
16282 	status = policy_mgr_register_mode_change_cb(hdd_ctx->psoc,
16283 					       wlan_hdd_send_mode_change_event);
16284 	if (!QDF_IS_STATUS_SUCCESS(status)) {
16285 		hdd_debug("Failed to register mode change cb with Policy Manager");
16286 		goto cds_disable;
16287 	}
16288 
16289 	if (hdd_green_ap_enable_egap(hdd_ctx))
16290 		hdd_debug("enhance green ap is not enabled");
16291 
16292 	hdd_register_green_ap_callback(hdd_ctx->pdev);
16293 
16294 	if (0 != wlan_hdd_set_wow_pulse(hdd_ctx, true))
16295 		hdd_debug("Failed to set wow pulse");
16296 
16297 	max_index = max_index - index;
16298 	status = mlme_check_index_setparam(
16299 				      setparam + index,
16300 				      wmi_pdev_param_gcmp_support_enable,
16301 				      ucfg_fwol_get_gcmp_enable(hdd_ctx->psoc),
16302 				      next_index++, max_index);
16303 	if (QDF_IS_STATUS_ERROR(status)) {
16304 		hdd_err("failed at wmi_pdev_param_gcmp_support_enable");
16305 		goto out;
16306 	}
16307 
16308 	 auto_power_fail_mode =
16309 		ucfg_pmo_get_auto_power_fail_mode(hdd_ctx->psoc);
16310 	status = mlme_check_index_setparam(
16311 				      setparam + index,
16312 				      wmi_pdev_auto_detect_power_failure,
16313 				      auto_power_fail_mode,
16314 				      next_index++, max_index);
16315 	if (QDF_IS_STATUS_ERROR(status)) {
16316 		hdd_err("failed at wmi_pdev_auto_detect_power_failure");
16317 		goto out;
16318 	}
16319 
16320 	status = ucfg_get_enable_phy_reg_retention(hdd_ctx->psoc,
16321 						   &enable_phy_reg_retention);
16322 
16323 	if (QDF_IS_STATUS_ERROR(status))
16324 		return -EINVAL;
16325 
16326 	if (enable_phy_reg_retention) {
16327 		status = mlme_check_index_setparam(
16328 					setparam + index,
16329 					wmi_pdev_param_fast_pwr_transition,
16330 					enable_phy_reg_retention,
16331 					next_index++, max_index);
16332 		if (QDF_IS_STATUS_ERROR(status)) {
16333 			hdd_err("failed at wmi_pdev_param_fast_pwr_transition");
16334 			goto out;
16335 		}
16336 	}
16337 	/*Send remaining pdev setparams from array*/
16338 	status = sme_send_multi_pdev_vdev_set_params(MLME_PDEV_SETPARAM,
16339 						     WMI_PDEV_ID_SOC,
16340 						     setparam + index,
16341 						     next_index);
16342 	if (QDF_IS_STATUS_ERROR(status)) {
16343 		hdd_err("failed to send 2nd set of pdev set params");
16344 		goto out;
16345 	}
16346 
16347 	hdd_hastings_bt_war_initialize(hdd_ctx);
16348 
16349 	wlan_hdd_hang_event_notifier_register(hdd_ctx);
16350 	return 0;
16351 
16352 cds_disable:
16353 	cds_disable(hdd_ctx->psoc);
16354 
16355 out:
16356 	return -EINVAL;
16357 }
16358 
16359 #ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
16360 static void hdd_deregister_policy_manager_callback(
16361 			struct wlan_objmgr_psoc *psoc)
16362 {
16363 	if (QDF_STATUS_SUCCESS !=
16364 	    policy_mgr_deregister_hdd_cb(psoc)) {
16365 		hdd_err("HDD callback deregister with policy manager failed");
16366 	}
16367 }
16368 #else
16369 static void hdd_deregister_policy_manager_callback(
16370 			struct wlan_objmgr_psoc *psoc)
16371 {
16372 }
16373 #endif
16374 
16375 int hdd_wlan_stop_modules(struct hdd_context *hdd_ctx, bool ftm_mode)
16376 {
16377 	void *hif_ctx;
16378 	qdf_device_t qdf_ctx;
16379 	QDF_STATUS qdf_status;
16380 	bool is_recovery_stop = cds_is_driver_recovering();
16381 	int ret = 0;
16382 	int debugfs_threads;
16383 	struct target_psoc_info *tgt_hdl;
16384 	struct bbm_params param = {0};
16385 
16386 	hdd_enter();
16387 	qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
16388 	if (!qdf_ctx)
16389 		return -EINVAL;
16390 
16391 	cds_set_driver_state_module_stop(true);
16392 
16393 	debugfs_threads = hdd_return_debugfs_threads_count();
16394 
16395 	if (debugfs_threads > 0 || hdd_ctx->is_wiphy_suspended) {
16396 		hdd_warn("Debugfs threads %d, wiphy suspend %d",
16397 			 debugfs_threads, hdd_ctx->is_wiphy_suspended);
16398 
16399 		if (IS_IDLE_STOP && !ftm_mode) {
16400 			hdd_psoc_idle_timer_start(hdd_ctx);
16401 			cds_set_driver_state_module_stop(false);
16402 
16403 			ucfg_dp_bus_bw_compute_timer_stop(hdd_ctx->psoc);
16404 			return -EAGAIN;
16405 		}
16406 	}
16407 
16408 	ucfg_dp_bus_bw_compute_timer_stop(hdd_ctx->psoc);
16409 	hdd_deregister_policy_manager_callback(hdd_ctx->psoc);
16410 
16411 	/* free user wowl patterns */
16412 	hdd_free_user_wowl_ptrns();
16413 
16414 	switch (hdd_ctx->driver_status) {
16415 	case DRIVER_MODULES_UNINITIALIZED:
16416 		hdd_debug("Modules not initialized just return");
16417 		goto done;
16418 	case DRIVER_MODULES_CLOSED:
16419 		hdd_debug("Modules already closed");
16420 		goto done;
16421 	case DRIVER_MODULES_ENABLED:
16422 		hdd_debug("Wlan transitioning (CLOSED <- ENABLED)");
16423 
16424 		if (hdd_get_conparam() == QDF_GLOBAL_FTM_MODE) {
16425 			hdd_disable_power_management(hdd_ctx);
16426 			break;
16427 		}
16428 
16429 		if (hdd_get_conparam() == QDF_GLOBAL_EPPING_MODE)
16430 			break;
16431 
16432 		hdd_skip_acs_scan_timer_deinit(hdd_ctx);
16433 
16434 		hdd_disable_power_management(hdd_ctx);
16435 
16436 		if (hdd_get_conparam() == QDF_GLOBAL_MISSION_MODE)
16437 			ucfg_dp_direct_link_deinit(hdd_ctx->psoc,
16438 						   is_recovery_stop);
16439 
16440 		if (hdd_deconfigure_cds(hdd_ctx)) {
16441 			hdd_err("Failed to de-configure CDS");
16442 			QDF_ASSERT(0);
16443 			ret = -EINVAL;
16444 		}
16445 		hdd_debug("successfully Disabled the CDS modules!");
16446 
16447 		break;
16448 	default:
16449 		QDF_DEBUG_PANIC("Unknown driver state:%d",
16450 				hdd_ctx->driver_status);
16451 		ret = -EINVAL;
16452 		goto done;
16453 	}
16454 
16455 	hdd_destroy_sysfs_files();
16456 	hdd_debug("Closing CDS modules!");
16457 
16458 	if (hdd_get_conparam() != QDF_GLOBAL_EPPING_MODE) {
16459 		qdf_status = cds_post_disable();
16460 		if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
16461 			hdd_err("Failed to process post CDS disable! :%d",
16462 				qdf_status);
16463 			ret = -EINVAL;
16464 			QDF_ASSERT(0);
16465 		}
16466 
16467 		hdd_unregister_notifiers(hdd_ctx);
16468 		/* De-register the SME callbacks */
16469 		hdd_deregister_cb(hdd_ctx);
16470 
16471 		hdd_runtime_suspend_context_deinit(hdd_ctx);
16472 
16473 		qdf_status = cds_dp_close(hdd_ctx->psoc);
16474 		if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
16475 			hdd_warn("Failed to stop CDS DP: %d", qdf_status);
16476 			ret = -EINVAL;
16477 			QDF_ASSERT(0);
16478 		}
16479 
16480 		hdd_component_pdev_close(hdd_ctx->pdev);
16481 		dispatcher_pdev_close(hdd_ctx->pdev);
16482 		ret = hdd_objmgr_release_and_destroy_pdev(hdd_ctx);
16483 		if (ret) {
16484 			hdd_err("Failed to destroy pdev; errno:%d", ret);
16485 			QDF_ASSERT(0);
16486 		}
16487 
16488 		qdf_status = cds_close(hdd_ctx->psoc);
16489 		if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
16490 			hdd_warn("Failed to stop CDS: %d", qdf_status);
16491 			ret = -EINVAL;
16492 			QDF_ASSERT(0);
16493 		}
16494 
16495 		qdf_status = wbuff_module_deinit();
16496 		if (!QDF_IS_STATUS_SUCCESS(qdf_status))
16497 			hdd_err("WBUFF de-init unsuccessful; status: %d",
16498 				qdf_status);
16499 
16500 		hdd_component_psoc_close(hdd_ctx->psoc);
16501 		/* pdev close and destroy use tx rx ops so call this here */
16502 		wlan_global_lmac_if_close(hdd_ctx->psoc);
16503 	}
16504 
16505 	/*
16506 	 * Reset total mac phy during module stop such that during
16507 	 * next module start same psoc is used to populate new service
16508 	 * ready data
16509 	 */
16510 	tgt_hdl = wlan_psoc_get_tgt_if_handle(hdd_ctx->psoc);
16511 	if (tgt_hdl)
16512 		target_psoc_set_total_mac_phy_cnt(tgt_hdl, 0);
16513 
16514 
16515 	hif_ctx = cds_get_context(QDF_MODULE_ID_HIF);
16516 	if (!hif_ctx)
16517 		ret = -EINVAL;
16518 
16519 	if (hdd_get_conparam() == QDF_GLOBAL_EPPING_MODE) {
16520 		epping_disable();
16521 		epping_close();
16522 	}
16523 
16524 	wlan_connectivity_logging_stop();
16525 
16526 	ucfg_ipa_component_config_free();
16527 
16528 	hdd_hif_close(hdd_ctx, hif_ctx);
16529 
16530 	ol_cds_free();
16531 
16532 	if (IS_IDLE_STOP) {
16533 		ret = pld_power_off(qdf_ctx->dev);
16534 		if (ret)
16535 			hdd_err("Failed to power down device; errno:%d", ret);
16536 	}
16537 
16538 	/* Free the cache channels of the command SET_DISABLE_CHANNEL_LIST */
16539 	wlan_hdd_free_cache_channels(hdd_ctx);
16540 	hdd_driver_mem_cleanup();
16541 
16542 	/* Free the resources allocated while storing SAR config. These needs
16543 	 * to be freed only in the case when it is not SSR. As in the case of
16544 	 * SSR, the values needs to be intact so that it can be restored during
16545 	 * reinit path.
16546 	 */
16547 	if (!is_recovery_stop)
16548 		wlan_hdd_free_sar_config(hdd_ctx);
16549 
16550 	hdd_sap_destroy_ctx_all(hdd_ctx, is_recovery_stop);
16551 	hdd_sta_destroy_ctx_all(hdd_ctx);
16552 
16553 	/*
16554 	 * Reset the driver mode specific bus bw level
16555 	 */
16556 	param.policy = BBM_DRIVER_MODE_POLICY;
16557 	param.policy_info.driver_mode = QDF_GLOBAL_MAX_MODE;
16558 	ucfg_dp_bbm_apply_independent_policy(hdd_ctx->psoc, &param);
16559 
16560 	hdd_deinit_adapter_ops_wq(hdd_ctx);
16561 	hdd_deinit_qdf_ctx(hdd_debug_domain_get());
16562 
16563 	hdd_check_for_leaks(hdd_ctx, is_recovery_stop);
16564 	hdd_debug_domain_set(QDF_DEBUG_DOMAIN_INIT);
16565 	hdd_deinit_qdf_ctx(hdd_debug_domain_get());
16566 	qdf_dma_invalid_buf_list_deinit();
16567 
16568 	/* Restore PS params for monitor mode */
16569 	if (hdd_get_conparam() == QDF_GLOBAL_MONITOR_MODE)
16570 		hdd_restore_all_ps(hdd_ctx);
16571 
16572 	/* Once the firmware sequence is completed reset this flag */
16573 	hdd_ctx->imps_enabled = false;
16574 	hdd_ctx->is_dual_mac_cfg_updated = false;
16575 	hdd_ctx->driver_status = DRIVER_MODULES_CLOSED;
16576 	hdd_ctx->is_fw_dbg_log_levels_configured = false;
16577 	hdd_debug("Wlan transitioned (now CLOSED)");
16578 
16579 done:
16580 	hdd_exit();
16581 
16582 	return ret;
16583 }
16584 
16585 #ifdef WLAN_FEATURE_MEMDUMP_ENABLE
16586 /**
16587  * hdd_state_info_dump() - prints state information of hdd layer
16588  * @buf_ptr: buffer pointer
16589  * @size: size of buffer to be filled
16590  *
16591  * This function is used to dump state information of hdd layer
16592  *
16593  * Return: None
16594  */
16595 static void hdd_state_info_dump(char **buf_ptr, uint16_t *size)
16596 {
16597 	struct hdd_context *hdd_ctx;
16598 	struct hdd_station_ctx *sta_ctx;
16599 	struct hdd_adapter *adapter, *next_adapter = NULL;
16600 	uint16_t len = 0;
16601 	char *buf = *buf_ptr;
16602 	wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_STATE_INFO_DUMP;
16603 	struct wlan_hdd_link_info *link_info;
16604 
16605 	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
16606 	if (!hdd_ctx)
16607 		return;
16608 
16609 	hdd_debug("size of buffer: %d", *size);
16610 
16611 	len += scnprintf(buf + len, *size - len, "\n is_wiphy_suspended %d",
16612 			 hdd_ctx->is_wiphy_suspended);
16613 	len += scnprintf(buf + len, *size - len, "\n is_scheduler_suspended %d",
16614 			 hdd_ctx->is_scheduler_suspended);
16615 
16616 	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
16617 					   dbgid) {
16618 		hdd_adapter_for_each_active_link_info(adapter, link_info) {
16619 			len +=
16620 			scnprintf(buf + len, *size - len, "\n device name: %s",
16621 				  adapter->dev->name);
16622 			len +=
16623 			scnprintf(buf + len, *size - len, "\n device_mode: %d",
16624 				  adapter->device_mode);
16625 			switch (adapter->device_mode) {
16626 			case QDF_STA_MODE:
16627 			case QDF_P2P_CLIENT_MODE:
16628 				sta_ctx =
16629 					WLAN_HDD_GET_STATION_CTX_PTR(link_info);
16630 				len += scnprintf(buf + len, *size - len,
16631 					"\n conn_state: %d",
16632 					sta_ctx->conn_info.conn_state);
16633 				break;
16634 			default:
16635 				break;
16636 			}
16637 		}
16638 		hdd_adapter_dev_put_debug(adapter, dbgid);
16639 	}
16640 
16641 	*size -= len;
16642 	*buf_ptr += len;
16643 }
16644 
16645 /**
16646  * hdd_register_debug_callback() - registration function for hdd layer
16647  * to print hdd state information
16648  *
16649  * Return: None
16650  */
16651 static void hdd_register_debug_callback(void)
16652 {
16653 	qdf_register_debug_callback(QDF_MODULE_ID_HDD, &hdd_state_info_dump);
16654 }
16655 #else /* WLAN_FEATURE_MEMDUMP_ENABLE */
16656 static void hdd_register_debug_callback(void)
16657 {
16658 }
16659 #endif /* WLAN_FEATURE_MEMDUMP_ENABLE */
16660 
16661 /*
16662  * wlan_init_bug_report_lock() - Initialize bug report lock
16663  *
16664  * This function is used to create bug report lock
16665  *
16666  * Return: None
16667  */
16668 static void wlan_init_bug_report_lock(void)
16669 {
16670 	struct cds_context *p_cds_context;
16671 
16672 	p_cds_context = cds_get_global_context();
16673 	if (!p_cds_context) {
16674 		hdd_err("cds context is NULL");
16675 		return;
16676 	}
16677 
16678 	qdf_spinlock_create(&p_cds_context->bug_report_lock);
16679 }
16680 
16681 #ifdef DISABLE_CHANNEL_LIST
16682 static QDF_STATUS wlan_hdd_cache_chann_mutex_create(struct hdd_context *hdd_ctx)
16683 {
16684 	return qdf_mutex_create(&hdd_ctx->cache_channel_lock);
16685 }
16686 #else
16687 static QDF_STATUS wlan_hdd_cache_chann_mutex_create(struct hdd_context *hdd_ctx)
16688 {
16689 	return QDF_STATUS_SUCCESS;
16690 }
16691 #endif
16692 
16693 QDF_STATUS hdd_open_adapter_no_trans(struct hdd_context *hdd_ctx,
16694 				     enum QDF_OPMODE op_mode,
16695 				     const char *iface_name,
16696 				     uint8_t *mac_addr_bytes,
16697 				     struct hdd_adapter_create_param *params)
16698 {
16699 	struct osif_vdev_sync *vdev_sync;
16700 	struct hdd_adapter *adapter;
16701 	QDF_STATUS status;
16702 	int errno;
16703 
16704 	QDF_BUG(rtnl_is_locked());
16705 
16706 	errno = osif_vdev_sync_create(hdd_ctx->parent_dev, &vdev_sync);
16707 	if (errno)
16708 		return qdf_status_from_os_return(errno);
16709 
16710 	adapter = hdd_open_adapter(hdd_ctx, op_mode, iface_name,
16711 				   mac_addr_bytes, NET_NAME_UNKNOWN, true,
16712 				   params);
16713 	if (!adapter) {
16714 		status = QDF_STATUS_E_INVAL;
16715 		goto destroy_sync;
16716 	}
16717 
16718 	osif_vdev_sync_register(adapter->dev, vdev_sync);
16719 
16720 	return QDF_STATUS_SUCCESS;
16721 
16722 destroy_sync:
16723 	osif_vdev_sync_destroy(vdev_sync);
16724 
16725 	return status;
16726 }
16727 
16728 #ifdef WLAN_OPEN_P2P_INTERFACE
16729 /**
16730  * hdd_open_p2p_interface - Open P2P interface
16731  * @hdd_ctx: HDD context
16732  *
16733  * Return: QDF_STATUS
16734  */
16735 static QDF_STATUS hdd_open_p2p_interface(struct hdd_context *hdd_ctx)
16736 {
16737 	QDF_STATUS status;
16738 	bool p2p_dev_addr_admin;
16739 	bool is_p2p_locally_administered = false;
16740 	struct hdd_adapter_create_param params = {0};
16741 
16742 	cfg_p2p_get_device_addr_admin(hdd_ctx->psoc, &p2p_dev_addr_admin);
16743 
16744 	if (p2p_dev_addr_admin) {
16745 		if (hdd_ctx->num_provisioned_addr &&
16746 		    !(hdd_ctx->provisioned_mac_addr[0].bytes[0] & 0x02)) {
16747 			hdd_ctx->p2p_device_address =
16748 					hdd_ctx->provisioned_mac_addr[0];
16749 
16750 			/*
16751 			 * Generate the P2P Device Address.  This consists of
16752 			 * the device's primary MAC address with the locally
16753 			 * administered bit set.
16754 			 */
16755 
16756 			hdd_ctx->p2p_device_address.bytes[0] |= 0x02;
16757 			is_p2p_locally_administered = true;
16758 		} else if (!(hdd_ctx->derived_mac_addr[0].bytes[0] & 0x02)) {
16759 			hdd_ctx->p2p_device_address =
16760 						hdd_ctx->derived_mac_addr[0];
16761 			/*
16762 			 * Generate the P2P Device Address.  This consists of
16763 			 * the device's primary MAC address with the locally
16764 			 * administered bit set.
16765 			 */
16766 			hdd_ctx->p2p_device_address.bytes[0] |= 0x02;
16767 			is_p2p_locally_administered = true;
16768 		}
16769 	}
16770 	if (!is_p2p_locally_administered) {
16771 		uint8_t *p2p_dev_addr;
16772 
16773 		p2p_dev_addr = wlan_hdd_get_intf_addr(hdd_ctx,
16774 						      QDF_P2P_DEVICE_MODE);
16775 		if (!p2p_dev_addr) {
16776 			hdd_err("Failed to get MAC address for new p2p device");
16777 			return QDF_STATUS_E_INVAL;
16778 		}
16779 
16780 		qdf_mem_copy(hdd_ctx->p2p_device_address.bytes,
16781 			     p2p_dev_addr, QDF_MAC_ADDR_SIZE);
16782 	}
16783 
16784 	status = hdd_open_adapter_no_trans(hdd_ctx, QDF_P2P_DEVICE_MODE,
16785 					   "p2p%d",
16786 					   hdd_ctx->p2p_device_address.bytes,
16787 					   &params);
16788 	if (QDF_IS_STATUS_ERROR(status)) {
16789 		if (!is_p2p_locally_administered)
16790 			wlan_hdd_release_intf_addr(hdd_ctx,
16791 					hdd_ctx->p2p_device_address.bytes);
16792 		hdd_err("Failed to open p2p interface");
16793 		return QDF_STATUS_E_INVAL;
16794 	}
16795 
16796 	return QDF_STATUS_SUCCESS;
16797 }
16798 #else
16799 static inline QDF_STATUS hdd_open_p2p_interface(struct hdd_context *hdd_ctx)
16800 {
16801 	return QDF_STATUS_SUCCESS;
16802 }
16803 #endif
16804 
16805 static QDF_STATUS hdd_open_ocb_interface(struct hdd_context *hdd_ctx)
16806 {
16807 	QDF_STATUS status;
16808 	uint8_t *mac_addr;
16809 	struct hdd_adapter_create_param params = {0};
16810 
16811 	mac_addr = wlan_hdd_get_intf_addr(hdd_ctx, QDF_OCB_MODE);
16812 	if (!mac_addr)
16813 		return QDF_STATUS_E_INVAL;
16814 
16815 	status = hdd_open_adapter_no_trans(hdd_ctx, QDF_OCB_MODE,
16816 					   "wlanocb%d", mac_addr,
16817 					   &params);
16818 	if (QDF_IS_STATUS_ERROR(status)) {
16819 		wlan_hdd_release_intf_addr(hdd_ctx, mac_addr);
16820 		hdd_err("Failed to open 802.11p interface");
16821 	}
16822 
16823 	return status;
16824 }
16825 
16826 static QDF_STATUS hdd_open_concurrent_interface(struct hdd_context *hdd_ctx)
16827 {
16828 	QDF_STATUS status;
16829 	const char *iface_name;
16830 	uint8_t *mac_addr;
16831 	struct hdd_adapter_create_param params = {0};
16832 
16833 	if (qdf_str_eq(hdd_ctx->config->enable_concurrent_sta, ""))
16834 		return QDF_STATUS_SUCCESS;
16835 
16836 	iface_name = hdd_ctx->config->enable_concurrent_sta;
16837 	mac_addr = wlan_hdd_get_intf_addr(hdd_ctx, QDF_STA_MODE);
16838 	if (!mac_addr)
16839 		return QDF_STATUS_E_INVAL;
16840 
16841 	status = hdd_open_adapter_no_trans(hdd_ctx, QDF_STA_MODE,
16842 					   iface_name, mac_addr,
16843 					   &params);
16844 	if (QDF_IS_STATUS_ERROR(status)) {
16845 		wlan_hdd_release_intf_addr(hdd_ctx, mac_addr);
16846 		hdd_err("Failed to open concurrent station interface");
16847 	}
16848 
16849 	return status;
16850 }
16851 
16852 #ifdef WLAN_HDD_MULTI_VDEV_SINGLE_NDEV
16853 static inline void
16854 hdd_adapter_open_set_max_active_links(struct hdd_adapter_create_param *params)
16855 {
16856 	if (params->is_add_virtual_iface || !params->is_ml_adapter)
16857 		params->num_sessions = 1;
16858 	else
16859 		params->num_sessions = 2;
16860 }
16861 #else
16862 static inline void
16863 hdd_adapter_open_set_max_active_links(struct hdd_adapter_create_param *params)
16864 {
16865 	params->num_sessions = 1;
16866 }
16867 #endif
16868 
16869 static QDF_STATUS
16870 hdd_open_adapters_for_mission_mode(struct hdd_context *hdd_ctx)
16871 {
16872 	enum dot11p_mode dot11p_mode;
16873 	QDF_STATUS status;
16874 	uint8_t *mac_addr;
16875 	struct hdd_adapter_create_param params = {0};
16876 	bool eht_capab = 0;
16877 
16878 	ucfg_mlme_get_dot11p_mode(hdd_ctx->psoc, &dot11p_mode);
16879 	ucfg_psoc_mlme_get_11be_capab(hdd_ctx->psoc, &eht_capab);
16880 
16881 	/* Create only 802.11p interface? */
16882 	if (dot11p_mode == CFG_11P_STANDALONE)
16883 		return hdd_open_ocb_interface(hdd_ctx);
16884 
16885 	mac_addr = wlan_hdd_get_intf_addr(hdd_ctx, QDF_STA_MODE);
16886 	if (!mac_addr)
16887 		return QDF_STATUS_E_INVAL;
16888 
16889 	if (eht_capab) {
16890 		params.is_ml_adapter = true;
16891 		hdd_adapter_open_set_max_active_links(&params);
16892 	}
16893 
16894 	status = hdd_open_adapter_no_trans(hdd_ctx, QDF_STA_MODE,
16895 					   "wlan%d", mac_addr,
16896 					   &params);
16897 	if (QDF_IS_STATUS_ERROR(status)) {
16898 		wlan_hdd_release_intf_addr(hdd_ctx, mac_addr);
16899 		return status;
16900 	}
16901 
16902 	/* opening concurrent STA is best effort, continue on error */
16903 	hdd_open_concurrent_interface(hdd_ctx);
16904 
16905 	status = hdd_open_p2p_interface(hdd_ctx);
16906 	if (status)
16907 		goto err_close_adapters;
16908 
16909 	/*
16910 	 * Create separate interface (wifi-aware0) for NAN. All NAN commands
16911 	 * should go on this new interface.
16912 	 */
16913 	if (wlan_hdd_is_vdev_creation_allowed(hdd_ctx->psoc)) {
16914 		qdf_mem_zero(&params, sizeof(params));
16915 		mac_addr = wlan_hdd_get_intf_addr(hdd_ctx, QDF_NAN_DISC_MODE);
16916 		if (!mac_addr)
16917 			goto err_close_adapters;
16918 
16919 		status = hdd_open_adapter_no_trans(hdd_ctx, QDF_NAN_DISC_MODE,
16920 						   "wifi-aware%d", mac_addr,
16921 						   &params);
16922 		if (status) {
16923 			wlan_hdd_release_intf_addr(hdd_ctx, mac_addr);
16924 			goto err_close_adapters;
16925 		}
16926 	}
16927 	/* Open 802.11p Interface */
16928 	if (dot11p_mode == CFG_11P_CONCURRENT) {
16929 		status = hdd_open_ocb_interface(hdd_ctx);
16930 		if (QDF_IS_STATUS_ERROR(status))
16931 			goto err_close_adapters;
16932 	}
16933 
16934 	if (eht_capab)
16935 		hdd_wlan_register_mlo_interfaces(hdd_ctx);
16936 
16937 	return QDF_STATUS_SUCCESS;
16938 
16939 err_close_adapters:
16940 	hdd_close_all_adapters(hdd_ctx, true);
16941 
16942 	return status;
16943 }
16944 
16945 static QDF_STATUS hdd_open_adapters_for_ftm_mode(struct hdd_context *hdd_ctx)
16946 {
16947 	QDF_STATUS status;
16948 	uint8_t *mac_addr;
16949 	struct hdd_adapter_create_param params = {0};
16950 
16951 	mac_addr = wlan_hdd_get_intf_addr(hdd_ctx, QDF_FTM_MODE);
16952 	if (!mac_addr)
16953 		return QDF_STATUS_E_INVAL;
16954 
16955 	status = hdd_open_adapter_no_trans(hdd_ctx, QDF_FTM_MODE,
16956 					   "wlan%d", mac_addr,
16957 					   &params);
16958 	if (QDF_IS_STATUS_ERROR(status)) {
16959 		wlan_hdd_release_intf_addr(hdd_ctx, mac_addr);
16960 		return status;
16961 	}
16962 
16963 	return QDF_STATUS_SUCCESS;
16964 }
16965 
16966 static QDF_STATUS
16967 hdd_open_adapters_for_monitor_mode(struct hdd_context *hdd_ctx)
16968 {
16969 	QDF_STATUS status;
16970 	uint8_t *mac_addr;
16971 	struct hdd_adapter_create_param params = {0};
16972 
16973 	mac_addr = wlan_hdd_get_intf_addr(hdd_ctx, QDF_MONITOR_MODE);
16974 	if (!mac_addr)
16975 		return QDF_STATUS_E_INVAL;
16976 
16977 	status = hdd_open_adapter_no_trans(hdd_ctx, QDF_MONITOR_MODE,
16978 					   "wlan%d", mac_addr,
16979 					   &params);
16980 	if (QDF_IS_STATUS_ERROR(status)) {
16981 		wlan_hdd_release_intf_addr(hdd_ctx, mac_addr);
16982 		return status;
16983 	}
16984 
16985 	return QDF_STATUS_SUCCESS;
16986 }
16987 
16988 static QDF_STATUS hdd_open_adapters_for_epping_mode(struct hdd_context *hdd_ctx)
16989 {
16990 	epping_enable_adapter();
16991 	return QDF_STATUS_SUCCESS;
16992 }
16993 
16994 typedef QDF_STATUS (*hdd_open_mode_handler)(struct hdd_context *hdd_ctx);
16995 
16996 static const hdd_open_mode_handler
16997 hdd_open_mode_handlers[QDF_GLOBAL_MAX_MODE] = {
16998 	[QDF_GLOBAL_MISSION_MODE] = hdd_open_adapters_for_mission_mode,
16999 	[QDF_GLOBAL_FTM_MODE] = hdd_open_adapters_for_ftm_mode,
17000 	[QDF_GLOBAL_MONITOR_MODE] = hdd_open_adapters_for_monitor_mode,
17001 	[QDF_GLOBAL_EPPING_MODE] = hdd_open_adapters_for_epping_mode,
17002 };
17003 
17004 static QDF_STATUS hdd_open_adapters_for_mode(struct hdd_context *hdd_ctx,
17005 					     enum QDF_GLOBAL_MODE driver_mode)
17006 {
17007 	QDF_STATUS status;
17008 
17009 	if (driver_mode < 0 ||
17010 	    driver_mode >= QDF_GLOBAL_MAX_MODE ||
17011 	    !hdd_open_mode_handlers[driver_mode]) {
17012 		hdd_err("Driver mode %d not supported", driver_mode);
17013 		return -ENOTSUPP;
17014 	}
17015 
17016 	hdd_hold_rtnl_lock();
17017 	status = hdd_open_mode_handlers[driver_mode](hdd_ctx);
17018 	hdd_release_rtnl_lock();
17019 
17020 	return status;
17021 }
17022 
17023 int hdd_wlan_startup(struct hdd_context *hdd_ctx)
17024 {
17025 	QDF_STATUS status;
17026 	int errno;
17027 	bool is_imps_enabled;
17028 
17029 	hdd_enter();
17030 
17031 	qdf_nbuf_init_replenish_timer();
17032 
17033 	status = wlan_hdd_cache_chann_mutex_create(hdd_ctx);
17034 	if (QDF_IS_STATUS_ERROR(status))
17035 		return qdf_status_to_os_return(status);
17036 
17037 #ifdef FEATURE_WLAN_CH_AVOID
17038 	mutex_init(&hdd_ctx->avoid_freq_lock);
17039 #endif
17040 
17041 	osif_request_manager_init();
17042 	hdd_driver_memdump_init();
17043 
17044 	errno = hdd_init_regulatory_update_event(hdd_ctx);
17045 	if (errno) {
17046 		hdd_err("Failed to initialize regulatory update event; errno:%d",
17047 			errno);
17048 		goto memdump_deinit;
17049 	}
17050 
17051 	errno = hdd_wlan_start_modules(hdd_ctx, false);
17052 	if (errno) {
17053 		hdd_err("Failed to start modules; errno:%d", errno);
17054 		goto memdump_deinit;
17055 	}
17056 
17057 	if (hdd_get_conparam() == QDF_GLOBAL_EPPING_MODE)
17058 		return 0;
17059 
17060 	wlan_hdd_update_wiphy(hdd_ctx);
17061 
17062 	hdd_ctx->mac_handle = cds_get_context(QDF_MODULE_ID_SME);
17063 	if (!hdd_ctx->mac_handle)
17064 		goto stop_modules;
17065 
17066 	errno = hdd_wiphy_init(hdd_ctx);
17067 	if (errno) {
17068 		hdd_err("Failed to initialize wiphy; errno:%d", errno);
17069 		goto stop_modules;
17070 	}
17071 
17072 	errno = hdd_initialize_mac_address(hdd_ctx);
17073 	if (errno) {
17074 		hdd_err("MAC initializtion failed: %d", errno);
17075 		goto unregister_wiphy;
17076 	}
17077 
17078 	errno = register_netdevice_notifier(&hdd_netdev_notifier);
17079 	if (errno) {
17080 		hdd_err("register_netdevice_notifier failed; errno:%d", errno);
17081 		goto unregister_wiphy;
17082 	}
17083 
17084 	wlan_hdd_update_11n_mode(hdd_ctx);
17085 
17086 	hdd_lpass_notify_wlan_version(hdd_ctx);
17087 
17088 	status = wlansap_global_init();
17089 	if (QDF_IS_STATUS_ERROR(status))
17090 		goto unregister_notifiers;
17091 
17092 	ucfg_mlme_is_imps_enabled(hdd_ctx->psoc, &is_imps_enabled);
17093 	hdd_set_idle_ps_config(hdd_ctx, is_imps_enabled);
17094 	hdd_debugfs_mws_coex_info_init(hdd_ctx);
17095 	hdd_debugfs_ini_config_init(hdd_ctx);
17096 	wlan_hdd_debugfs_unit_test_host_create(hdd_ctx);
17097 	wlan_hdd_create_mib_stats_lock();
17098 	wlan_cfg80211_init_interop_issues_ap(hdd_ctx->pdev);
17099 
17100 	hdd_exit();
17101 
17102 	return 0;
17103 
17104 unregister_notifiers:
17105 	unregister_netdevice_notifier(&hdd_netdev_notifier);
17106 
17107 unregister_wiphy:
17108 	qdf_dp_trace_deinit();
17109 	wiphy_unregister(hdd_ctx->wiphy);
17110 
17111 stop_modules:
17112 	hdd_wlan_stop_modules(hdd_ctx, false);
17113 
17114 memdump_deinit:
17115 	hdd_driver_memdump_deinit();
17116 	osif_request_manager_deinit();
17117 	qdf_nbuf_deinit_replenish_timer();
17118 
17119 	if (cds_is_fw_down())
17120 		hdd_err("Not setting the complete event as fw is down");
17121 	else
17122 		hdd_start_complete(errno);
17123 
17124 	hdd_exit();
17125 
17126 	return errno;
17127 }
17128 
17129 QDF_STATUS hdd_psoc_create_vdevs(struct hdd_context *hdd_ctx)
17130 {
17131 	enum QDF_GLOBAL_MODE driver_mode = hdd_get_conparam();
17132 	QDF_STATUS status;
17133 
17134 	status = hdd_open_adapters_for_mode(hdd_ctx, driver_mode);
17135 	if (QDF_IS_STATUS_ERROR(status)) {
17136 		hdd_err("Failed to create vdevs; status:%d", status);
17137 		return status;
17138 	}
17139 
17140 	ucfg_dp_try_set_rps_cpu_mask(hdd_ctx->psoc);
17141 
17142 	if (driver_mode != QDF_GLOBAL_FTM_MODE &&
17143 	    driver_mode != QDF_GLOBAL_EPPING_MODE)
17144 		hdd_psoc_idle_timer_start(hdd_ctx);
17145 
17146 	return QDF_STATUS_SUCCESS;
17147 }
17148 
17149 /**
17150  * hdd_wlan_update_target_info() - update target type info
17151  * @hdd_ctx: HDD context
17152  * @context: hif context
17153  *
17154  * Update target info received from firmware in hdd context
17155  * Return:None
17156  */
17157 
17158 void hdd_wlan_update_target_info(struct hdd_context *hdd_ctx, void *context)
17159 {
17160 	struct hif_target_info *tgt_info = hif_get_target_info_handle(context);
17161 
17162 	if (!tgt_info) {
17163 		hdd_err("Target info is Null");
17164 		return;
17165 	}
17166 
17167 	hdd_ctx->target_type = tgt_info->target_type;
17168 }
17169 
17170 #ifdef WLAN_FEATURE_MOTION_DETECTION
17171 /**
17172  * hdd_md_host_evt_cb - Callback for Motion Detection Event
17173  * @ctx: HDD context
17174  * @event: motion detect event
17175  *
17176  * Callback for Motion Detection Event. Re-enables Motion
17177  * Detection again upon event
17178  *
17179  * Return: QDF_STATUS QDF_STATUS_SUCCESS on Success and
17180  * QDF_STATUS_E_FAILURE on failure
17181  */
17182 QDF_STATUS hdd_md_host_evt_cb(void *ctx, struct sir_md_evt *event)
17183 {
17184 	struct hdd_adapter *adapter;
17185 	struct hdd_context *hdd_ctx;
17186 	struct sme_motion_det_en motion_det;
17187 	struct wlan_hdd_link_info *link_info;
17188 
17189 	if (!ctx || !event)
17190 		return QDF_STATUS_E_INVAL;
17191 
17192 	hdd_ctx = (struct hdd_context *)ctx;
17193 	if (wlan_hdd_validate_context(hdd_ctx))
17194 		return QDF_STATUS_E_INVAL;
17195 
17196 	link_info = hdd_get_link_info_by_vdev(hdd_ctx, event->vdev_id);
17197 	if (!link_info ||
17198 	    WLAN_HDD_ADAPTER_MAGIC != link_info->adapter->magic) {
17199 		hdd_err("Invalid adapter or adapter has invalid magic");
17200 		return QDF_STATUS_E_INVAL;
17201 	}
17202 
17203 	adapter = link_info->adapter;
17204 	/* When motion is detected, reset the motion_det_in_progress flag */
17205 	if (event->status)
17206 		adapter->motion_det_in_progress = false;
17207 
17208 	hdd_debug("Motion Detection CB vdev_id=%u, status=%u",
17209 		  event->vdev_id, event->status);
17210 
17211 	if (adapter->motion_detection_mode) {
17212 		motion_det.vdev_id = event->vdev_id;
17213 		motion_det.enable = 1;
17214 		hdd_debug("Motion Detect CB -> Enable Motion Detection again");
17215 		sme_motion_det_enable(hdd_ctx->mac_handle, &motion_det);
17216 	}
17217 
17218 	return QDF_STATUS_SUCCESS;
17219 }
17220 
17221 /**
17222  * hdd_md_bl_evt_cb - Callback for Motion Detection Baseline Event
17223  * @ctx: HDD context
17224  * @event: motion detect baseline event
17225  *
17226  * Callback for Motion Detection Baseline completion
17227  *
17228  * Return: QDF_STATUS QDF_STATUS_SUCCESS on Success and
17229  * QDF_STATUS_E_FAILURE on failure
17230  */
17231 QDF_STATUS hdd_md_bl_evt_cb(void *ctx, struct sir_md_bl_evt *event)
17232 {
17233 	struct hdd_context *hdd_ctx;
17234 	struct wlan_hdd_link_info *link_info;
17235 
17236 	if (!ctx || !event)
17237 		return QDF_STATUS_E_INVAL;
17238 
17239 	hdd_ctx = (struct hdd_context *)ctx;
17240 	if (wlan_hdd_validate_context(hdd_ctx))
17241 		return QDF_STATUS_E_INVAL;
17242 
17243 	link_info = hdd_get_link_info_by_vdev(hdd_ctx, event->vdev_id);
17244 	if (!link_info ||
17245 	    WLAN_HDD_ADAPTER_MAGIC != link_info->adapter->magic) {
17246 		hdd_err("Invalid adapter or adapter has invalid magic");
17247 		return QDF_STATUS_E_INVAL;
17248 	}
17249 
17250 	hdd_debug("Motion Detection Baseline CB vdev id=%u, baseline val = %d",
17251 		  event->vdev_id, event->bl_baseline_value);
17252 
17253 	link_info->adapter->motion_det_baseline_value =
17254 						event->bl_baseline_value;
17255 
17256 	return QDF_STATUS_SUCCESS;
17257 }
17258 #endif /* WLAN_FEATURE_MOTION_DETECTION */
17259 
17260 /**
17261  * hdd_ssr_on_pagefault_cb - Callback to trigger SSR because
17262  * of host wake up by firmware with reason pagefault
17263  *
17264  * Return: None
17265  */
17266 static void hdd_ssr_on_pagefault_cb(void)
17267 {
17268 	uint32_t ssr_frequency_on_pagefault;
17269 	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
17270 	qdf_time_t curr_time;
17271 
17272 	hdd_enter();
17273 
17274 	if (!hdd_ctx)
17275 		return;
17276 
17277 	ssr_frequency_on_pagefault =
17278 		ucfg_pmo_get_ssr_frequency_on_pagefault(hdd_ctx->psoc);
17279 
17280 	curr_time = qdf_get_time_of_the_day_ms();
17281 
17282 	if (!hdd_ctx->last_pagefault_ssr_time ||
17283 	    (curr_time - hdd_ctx->last_pagefault_ssr_time) >=
17284 					ssr_frequency_on_pagefault) {
17285 		hdd_info("curr_time %lu last_pagefault_ssr_time %lu ssr_frequency %d",
17286 			 curr_time, hdd_ctx->last_pagefault_ssr_time,
17287 			 ssr_frequency_on_pagefault);
17288 		hdd_ctx->last_pagefault_ssr_time = curr_time;
17289 		cds_trigger_recovery(QDF_HOST_WAKEUP_REASON_PAGEFAULT);
17290 	}
17291 }
17292 
17293 /**
17294  * hdd_register_cb - Register HDD callbacks.
17295  * @hdd_ctx: HDD context
17296  *
17297  * Register the HDD callbacks to CDS/SME.
17298  *
17299  * Return: 0 for success or Error code for failure
17300  */
17301 int hdd_register_cb(struct hdd_context *hdd_ctx)
17302 {
17303 	QDF_STATUS status;
17304 	int ret = 0;
17305 	mac_handle_t mac_handle;
17306 
17307 	hdd_enter();
17308 	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
17309 		hdd_err("in ftm mode, no need to register callbacks");
17310 		return ret;
17311 	}
17312 
17313 	mac_handle = hdd_ctx->mac_handle;
17314 
17315 	sme_register_oem_data_rsp_callback(mac_handle,
17316 					   hdd_send_oem_data_rsp_msg);
17317 
17318 	sme_register_mgmt_frame_ind_callback(mac_handle,
17319 					     hdd_indicate_mgmt_frame);
17320 	sme_set_tsfcb(mac_handle, hdd_get_tsf_cb, hdd_ctx);
17321 	sme_stats_ext_register_callback(mac_handle,
17322 					wlan_hdd_cfg80211_stats_ext_callback);
17323 
17324 	sme_ext_scan_register_callback(mac_handle,
17325 					wlan_hdd_cfg80211_extscan_callback);
17326 	sme_stats_ext2_register_callback(mac_handle,
17327 					wlan_hdd_cfg80211_stats_ext2_callback);
17328 
17329 	sme_multi_client_ll_rsp_register_callback(mac_handle,
17330 					hdd_latency_level_event_handler_cb);
17331 
17332 	sme_set_rssi_threshold_breached_cb(mac_handle,
17333 					   hdd_rssi_threshold_breached);
17334 
17335 	sme_set_link_layer_stats_ind_cb(mac_handle,
17336 				wlan_hdd_cfg80211_link_layer_stats_callback);
17337 
17338 	sme_rso_cmd_status_cb(mac_handle, wlan_hdd_rso_cmd_status_cb);
17339 
17340 	sme_set_link_layer_ext_cb(mac_handle,
17341 			wlan_hdd_cfg80211_link_layer_stats_ext_callback);
17342 	sme_update_hidden_ssid_status_cb(mac_handle,
17343 					 hdd_hidden_ssid_enable_roaming);
17344 
17345 	status = sme_set_lost_link_info_cb(mac_handle,
17346 					   hdd_lost_link_info_cb);
17347 
17348 	wlan_hdd_register_cp_stats_cb(hdd_ctx);
17349 	hdd_dcs_register_cb(hdd_ctx);
17350 
17351 	hdd_thermal_register_callbacks(hdd_ctx);
17352 	/* print error and not block the startup process */
17353 	if (!QDF_IS_STATUS_SUCCESS(status))
17354 		hdd_err("set lost link info callback failed");
17355 
17356 	ret = hdd_register_data_stall_detect_cb();
17357 	if (ret) {
17358 		hdd_err("Register data stall detect detect callback failed.");
17359 		return ret;
17360 	}
17361 
17362 	wlan_hdd_dcc_register_for_dcc_stats_event(hdd_ctx);
17363 
17364 	sme_register_set_connection_info_cb(mac_handle,
17365 					    hdd_set_connection_in_progress,
17366 					    hdd_is_connection_in_progress);
17367 
17368 	status = sme_set_bt_activity_info_cb(mac_handle,
17369 					     hdd_bt_activity_cb);
17370 	if (!QDF_IS_STATUS_SUCCESS(status))
17371 		hdd_err("set bt activity info callback failed");
17372 
17373 	status = sme_register_tx_queue_cb(mac_handle,
17374 					  hdd_tx_queue_cb);
17375 	if (!QDF_IS_STATUS_SUCCESS(status))
17376 		hdd_err("Register tx queue callback failed");
17377 
17378 #ifdef WLAN_FEATURE_MOTION_DETECTION
17379 	sme_set_md_host_evt_cb(mac_handle, hdd_md_host_evt_cb, (void *)hdd_ctx);
17380 	sme_set_md_bl_evt_cb(mac_handle, hdd_md_bl_evt_cb, (void *)hdd_ctx);
17381 #endif /* WLAN_FEATURE_MOTION_DETECTION */
17382 
17383 	mac_register_session_open_close_cb(hdd_ctx->mac_handle,
17384 					   hdd_sme_close_session_callback,
17385 					   hdd_common_roam_callback);
17386 
17387 	sme_set_roam_scan_ch_event_cb(mac_handle, hdd_get_roam_scan_ch_cb);
17388 	status = sme_set_monitor_mode_cb(mac_handle,
17389 					 hdd_sme_monitor_mode_callback);
17390 	if (QDF_IS_STATUS_ERROR(status))
17391 		hdd_err_rl("Register monitor mode callback failed");
17392 
17393 	status = sme_set_beacon_latency_event_cb(mac_handle,
17394 						 hdd_beacon_latency_event_cb);
17395 	if (QDF_IS_STATUS_ERROR(status))
17396 		hdd_err_rl("Register beacon latency event callback failed");
17397 
17398 	sme_async_oem_event_init(mac_handle,
17399 				 hdd_oem_event_async_cb);
17400 
17401 	sme_register_ssr_on_pagefault_cb(mac_handle, hdd_ssr_on_pagefault_cb);
17402 
17403 	hdd_exit();
17404 
17405 	return ret;
17406 }
17407 
17408 /**
17409  * hdd_deregister_cb() - De-Register HDD callbacks.
17410  * @hdd_ctx: HDD context
17411  *
17412  * De-Register the HDD callbacks to CDS/SME.
17413  *
17414  * Return: void
17415  */
17416 void hdd_deregister_cb(struct hdd_context *hdd_ctx)
17417 {
17418 	QDF_STATUS status;
17419 	int ret;
17420 	mac_handle_t mac_handle;
17421 
17422 	hdd_enter();
17423 	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
17424 		hdd_err("in ftm mode, no need to deregister callbacks");
17425 		return;
17426 	}
17427 
17428 	mac_handle = hdd_ctx->mac_handle;
17429 
17430 	sme_deregister_ssr_on_pagefault_cb(mac_handle);
17431 
17432 	sme_async_oem_event_deinit(mac_handle);
17433 
17434 	sme_deregister_tx_queue_cb(mac_handle);
17435 
17436 	sme_reset_link_layer_stats_ind_cb(mac_handle);
17437 	sme_reset_rssi_threshold_breached_cb(mac_handle);
17438 
17439 	sme_stats_ext_deregister_callback(mac_handle);
17440 
17441 	status = sme_reset_tsfcb(mac_handle);
17442 	if (!QDF_IS_STATUS_SUCCESS(status))
17443 		hdd_err("Failed to de-register tsfcb the callback:%d",
17444 			status);
17445 
17446 	ret = hdd_deregister_data_stall_detect_cb();
17447 	if (ret)
17448 		hdd_err("Failed to de-register data stall detect event callback");
17449 	hdd_thermal_unregister_callbacks(hdd_ctx);
17450 	sme_deregister_oem_data_rsp_callback(mac_handle);
17451 	sme_multi_client_ll_rsp_deregister_callback(mac_handle);
17452 
17453 	hdd_exit();
17454 }
17455 
17456 /**
17457  * hdd_softap_sta_deauth() - handle deauth req from HDD
17458  * @adapter: Pointer to the HDD adapter
17459  * @param: Params to the operation
17460  *
17461  * This to take counter measure to handle deauth req from HDD
17462  *
17463  * Return: None
17464  */
17465 QDF_STATUS hdd_softap_sta_deauth(struct hdd_adapter *adapter,
17466 				 struct csr_del_sta_params *param)
17467 {
17468 	QDF_STATUS qdf_status = QDF_STATUS_E_FAULT;
17469 	struct hdd_context *hdd_ctx;
17470 	bool is_sap_bcast_deauth_enabled = false;
17471 
17472 	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
17473 	if (!hdd_ctx) {
17474 		hdd_err("hdd_ctx is NULL");
17475 		return QDF_STATUS_E_INVAL;
17476 	}
17477 
17478 	ucfg_mlme_get_sap_bcast_deauth_enabled(hdd_ctx->psoc,
17479 					       &is_sap_bcast_deauth_enabled);
17480 
17481 	hdd_enter();
17482 
17483 	hdd_debug("sap_bcast_deauth_enabled %d", is_sap_bcast_deauth_enabled);
17484 	/* Ignore request to deauth bcmc station */
17485 	if (!is_sap_bcast_deauth_enabled)
17486 		if (param->peerMacAddr.bytes[0] & 0x1)
17487 			return qdf_status;
17488 
17489 	qdf_status =
17490 		wlansap_deauth_sta(WLAN_HDD_GET_SAP_CTX_PTR(adapter->deflink),
17491 				   param);
17492 
17493 	hdd_exit();
17494 	return qdf_status;
17495 }
17496 
17497 /**
17498  * hdd_softap_sta_disassoc() - take counter measure to handle deauth req from HDD
17499  * @adapter: Pointer to the HDD
17500  * @param: pointer to station deletion parameters
17501  *
17502  * This to take counter measure to handle deauth req from HDD
17503  *
17504  * Return: None
17505  */
17506 void hdd_softap_sta_disassoc(struct hdd_adapter *adapter,
17507 			     struct csr_del_sta_params *param)
17508 {
17509 	hdd_enter();
17510 
17511 	/* Ignore request to disassoc bcmc station */
17512 	if (param->peerMacAddr.bytes[0] & 0x1)
17513 		return;
17514 
17515 	wlansap_disassoc_sta(WLAN_HDD_GET_SAP_CTX_PTR(adapter->deflink),
17516 			     param);
17517 }
17518 
17519 void
17520 wlan_hdd_set_roaming_state(struct wlan_hdd_link_info *cur_link_info,
17521 			   enum wlan_cm_rso_control_requestor rso_op_requestor,
17522 			   bool enab_roam)
17523 {
17524 	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(cur_link_info->adapter);
17525 	struct hdd_adapter *adapter = NULL, *next_adapter = NULL;
17526 	wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_DISABLE_ROAMING;
17527 	uint8_t vdev_id, cur_vdev_id = cur_link_info->vdev_id;
17528 	struct wlan_hdd_link_info *link_info;
17529 
17530 	if (!policy_mgr_is_sta_active_connection_exists(hdd_ctx->psoc))
17531 		return;
17532 
17533 	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
17534 					   dbgid) {
17535 		hdd_adapter_for_each_active_link_info(adapter, link_info) {
17536 			vdev_id = link_info->vdev_id;
17537 			if (cur_vdev_id != link_info->vdev_id &&
17538 			    adapter->device_mode == QDF_STA_MODE &&
17539 			    hdd_cm_is_vdev_associated(link_info)) {
17540 				if (enab_roam) {
17541 					hdd_debug("%d Enable roaming", vdev_id);
17542 					sme_start_roaming(hdd_ctx->mac_handle,
17543 							  vdev_id,
17544 							  REASON_DRIVER_ENABLED,
17545 							  rso_op_requestor);
17546 				} else {
17547 					hdd_debug("%d Disable roaming",
17548 						  vdev_id);
17549 					sme_stop_roaming(hdd_ctx->mac_handle,
17550 							 vdev_id,
17551 							 REASON_DRIVER_DISABLED,
17552 							 rso_op_requestor);
17553 				}
17554 			}
17555 		}
17556 		hdd_adapter_dev_put_debug(adapter, dbgid);
17557 	}
17558 }
17559 
17560 /**
17561  * nl_srv_bcast_svc() - Wrapper function to send bcast msgs to SVC mcast group
17562  * @skb: sk buffer pointer
17563  *
17564  * Sends the bcast message to SVC multicast group with generic nl socket
17565  * if CNSS_GENL is enabled. Else, use the legacy netlink socket to send.
17566  *
17567  * Return: None
17568  */
17569 static void nl_srv_bcast_svc(struct sk_buff *skb)
17570 {
17571 #ifdef CNSS_GENL
17572 	nl_srv_bcast(skb, CLD80211_MCGRP_SVC_MSGS, WLAN_NL_MSG_SVC);
17573 #else
17574 	nl_srv_bcast(skb);
17575 #endif
17576 }
17577 
17578 void wlan_hdd_send_svc_nlink_msg(int radio, int type, void *data, int len)
17579 {
17580 	struct sk_buff *skb;
17581 	struct nlmsghdr *nlh;
17582 	tAniMsgHdr *ani_hdr;
17583 	void *nl_data = NULL;
17584 	int flags = GFP_KERNEL;
17585 	struct radio_index_tlv *radio_info;
17586 	int tlv_len;
17587 
17588 	if (in_interrupt() || irqs_disabled() || in_atomic())
17589 		flags = GFP_ATOMIC;
17590 
17591 	skb = alloc_skb(NLMSG_SPACE(WLAN_NL_MAX_PAYLOAD), flags);
17592 
17593 	if (!skb)
17594 		return;
17595 
17596 	nlh = (struct nlmsghdr *)skb->data;
17597 	nlh->nlmsg_pid = 0;     /* from kernel */
17598 	nlh->nlmsg_flags = 0;
17599 	nlh->nlmsg_seq = 0;
17600 	nlh->nlmsg_type = WLAN_NL_MSG_SVC;
17601 
17602 	ani_hdr = NLMSG_DATA(nlh);
17603 	ani_hdr->type = type;
17604 
17605 	switch (type) {
17606 	case WLAN_SVC_FW_CRASHED_IND:
17607 	case WLAN_SVC_FW_SHUTDOWN_IND:
17608 	case WLAN_SVC_LTE_COEX_IND:
17609 	case WLAN_SVC_WLAN_AUTO_SHUTDOWN_IND:
17610 	case WLAN_SVC_WLAN_AUTO_SHUTDOWN_CANCEL_IND:
17611 		ani_hdr->length = 0;
17612 		nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr)));
17613 		break;
17614 	case WLAN_SVC_WLAN_STATUS_IND:
17615 	case WLAN_SVC_WLAN_VERSION_IND:
17616 	case WLAN_SVC_DFS_CAC_START_IND:
17617 	case WLAN_SVC_DFS_CAC_END_IND:
17618 	case WLAN_SVC_DFS_RADAR_DETECT_IND:
17619 	case WLAN_SVC_DFS_ALL_CHANNEL_UNAVAIL_IND:
17620 	case WLAN_SVC_WLAN_TP_IND:
17621 	case WLAN_SVC_WLAN_TP_TX_IND:
17622 	case WLAN_SVC_RPS_ENABLE_IND:
17623 	case WLAN_SVC_CORE_MINFREQ:
17624 		ani_hdr->length = len;
17625 		nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr) + len));
17626 		nl_data = (char *)ani_hdr + sizeof(tAniMsgHdr);
17627 		memcpy(nl_data, data, len);
17628 		break;
17629 
17630 	default:
17631 		hdd_err("WLAN SVC: Attempt to send unknown nlink message %d",
17632 		       type);
17633 		kfree_skb(skb);
17634 		return;
17635 	}
17636 
17637 	/*
17638 	 * Add radio index at the end of the svc event in TLV format
17639 	 * to maintain the backward compatibility with userspace
17640 	 * applications.
17641 	 */
17642 
17643 	tlv_len = 0;
17644 
17645 	if ((sizeof(*ani_hdr) + len + sizeof(struct radio_index_tlv))
17646 		< WLAN_NL_MAX_PAYLOAD) {
17647 		radio_info  = (struct radio_index_tlv *)((char *) ani_hdr +
17648 		sizeof(*ani_hdr) + len);
17649 		radio_info->type = (unsigned short) WLAN_SVC_WLAN_RADIO_INDEX;
17650 		radio_info->length = (unsigned short) sizeof(radio_info->radio);
17651 		radio_info->radio = radio;
17652 		tlv_len = sizeof(*radio_info);
17653 		hdd_debug("Added radio index tlv - radio index %d",
17654 			  radio_info->radio);
17655 	}
17656 
17657 	nlh->nlmsg_len += tlv_len;
17658 	skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr) + len + tlv_len));
17659 
17660 	nl_srv_bcast_svc(skb);
17661 }
17662 
17663 #ifdef FEATURE_WLAN_AUTO_SHUTDOWN
17664 void wlan_hdd_auto_shutdown_cb(void)
17665 {
17666 	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
17667 
17668 	if (!hdd_ctx)
17669 		return;
17670 
17671 	hdd_debug("Wlan Idle. Sending Shutdown event..");
17672 	wlan_hdd_send_svc_nlink_msg(hdd_ctx->radio_index,
17673 			WLAN_SVC_WLAN_AUTO_SHUTDOWN_IND, NULL, 0);
17674 }
17675 
17676 void wlan_hdd_auto_shutdown_enable(struct hdd_context *hdd_ctx, bool enable)
17677 {
17678 	struct hdd_adapter *adapter, *next_adapter = NULL;
17679 	bool ap_connected = false, sta_connected = false;
17680 	mac_handle_t mac_handle;
17681 	struct wlan_hdd_link_info *link_info;
17682 	struct hdd_ap_ctx *ap_ctx;
17683 	wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_AUTO_SHUTDOWN_ENABLE;
17684 
17685 	mac_handle = hdd_ctx->mac_handle;
17686 	if (!mac_handle)
17687 		return;
17688 
17689 	if (hdd_ctx->config->wlan_auto_shutdown == 0)
17690 		return;
17691 
17692 	if (enable == false) {
17693 		if (sme_set_auto_shutdown_timer(mac_handle, 0) !=
17694 							QDF_STATUS_SUCCESS) {
17695 			hdd_err("Failed to stop wlan auto shutdown timer");
17696 		}
17697 		wlan_hdd_send_svc_nlink_msg(hdd_ctx->radio_index,
17698 			WLAN_SVC_WLAN_AUTO_SHUTDOWN_CANCEL_IND, NULL, 0);
17699 		return;
17700 	}
17701 
17702 	/* To enable shutdown timer check conncurrency */
17703 	if (!policy_mgr_concurrent_open_sessions_running(hdd_ctx->psoc))
17704 		goto start_timer;
17705 
17706 	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter,
17707 					   next_adapter, dbgid) {
17708 		hdd_adapter_for_each_active_link_info(adapter, link_info) {
17709 			if (adapter->device_mode == QDF_STA_MODE &&
17710 			    hdd_cm_is_vdev_associated(link_info)) {
17711 				sta_connected = true;
17712 				hdd_adapter_dev_put_debug(adapter, dbgid);
17713 				if (next_adapter)
17714 					hdd_adapter_dev_put_debug(next_adapter,
17715 								  dbgid);
17716 				break;
17717 			}
17718 
17719 			if (adapter->device_mode == QDF_SAP_MODE) {
17720 				ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(link_info);
17721 				if (ap_ctx->ap_active == true) {
17722 					ap_connected = true;
17723 					hdd_adapter_dev_put_debug(adapter,
17724 								  dbgid);
17725 					if (next_adapter)
17726 						hdd_adapter_dev_put_debug(
17727 								next_adapter,
17728 								dbgid);
17729 					break;
17730 				}
17731 			}
17732 		}
17733 		hdd_adapter_dev_put_debug(adapter, dbgid);
17734 	}
17735 
17736 start_timer:
17737 	if (ap_connected == true || sta_connected == true) {
17738 		hdd_debug("CC Session active. Shutdown timer not enabled");
17739 		return;
17740 	}
17741 
17742 	if (sme_set_auto_shutdown_timer(mac_handle,
17743 					hdd_ctx->config->wlan_auto_shutdown)
17744 	    != QDF_STATUS_SUCCESS)
17745 		hdd_err("Failed to start wlan auto shutdown timer");
17746 	else
17747 		hdd_info("Auto Shutdown timer for %d seconds enabled",
17748 			 hdd_ctx->config->wlan_auto_shutdown);
17749 }
17750 #endif
17751 
17752 struct hdd_adapter *
17753 hdd_get_con_sap_adapter(struct hdd_adapter *this_sap_adapter,
17754 			bool check_start_bss)
17755 {
17756 	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(this_sap_adapter);
17757 	struct hdd_adapter *adapter, *next_adapter = NULL;
17758 	wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_GET_CON_SAP_ADAPTER;
17759 	struct wlan_hdd_link_info *link_info;
17760 
17761 	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
17762 					   dbgid) {
17763 		if ((adapter->device_mode == QDF_SAP_MODE ||
17764 		     adapter->device_mode == QDF_P2P_GO_MODE) &&
17765 		    adapter != this_sap_adapter) {
17766 			hdd_adapter_for_each_active_link_info(adapter,
17767 							      link_info) {
17768 				if (!check_start_bss) {
17769 					hdd_adapter_dev_put_debug(adapter,
17770 								  dbgid);
17771 					if (next_adapter)
17772 						hdd_adapter_dev_put_debug(
17773 								next_adapter,
17774 								dbgid);
17775 					return adapter;
17776 				}
17777 				if (test_bit(SOFTAP_BSS_STARTED,
17778 					     &link_info->link_flags)) {
17779 					hdd_adapter_dev_put_debug(adapter,
17780 								  dbgid);
17781 					if (next_adapter)
17782 						hdd_adapter_dev_put_debug(
17783 								next_adapter,
17784 								dbgid);
17785 					return adapter;
17786 				}
17787 			}
17788 		}
17789 		hdd_adapter_dev_put_debug(adapter, dbgid);
17790 	}
17791 
17792 	return NULL;
17793 }
17794 
17795 static inline bool hdd_adapter_is_sta(struct hdd_adapter *adapter)
17796 {
17797 	return adapter->device_mode == QDF_STA_MODE ||
17798 		adapter->device_mode == QDF_P2P_CLIENT_MODE;
17799 }
17800 
17801 bool hdd_is_any_adapter_connected(struct hdd_context *hdd_ctx)
17802 {
17803 	struct hdd_adapter *adapter, *next_adapter = NULL;
17804 	wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_IS_ANY_ADAPTER_CONNECTED;
17805 	struct wlan_hdd_link_info *link_info;
17806 
17807 	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
17808 					   dbgid) {
17809 		hdd_adapter_for_each_active_link_info(adapter, link_info) {
17810 			if (hdd_adapter_is_sta(adapter) &&
17811 			    hdd_cm_is_vdev_associated(link_info)) {
17812 				hdd_adapter_dev_put_debug(adapter, dbgid);
17813 				if (next_adapter)
17814 					hdd_adapter_dev_put_debug(next_adapter,
17815 								  dbgid);
17816 				return true;
17817 			}
17818 
17819 			if (hdd_adapter_is_ap(adapter) &&
17820 			    WLAN_HDD_GET_AP_CTX_PTR(link_info)->ap_active) {
17821 				hdd_adapter_dev_put_debug(adapter, dbgid);
17822 				if (next_adapter)
17823 					hdd_adapter_dev_put_debug(next_adapter,
17824 								  dbgid);
17825 				return true;
17826 			}
17827 
17828 			if (adapter->device_mode == QDF_NDI_MODE &&
17829 			    hdd_cm_is_vdev_associated(link_info)) {
17830 				hdd_adapter_dev_put_debug(adapter, dbgid);
17831 				if (next_adapter)
17832 					hdd_adapter_dev_put_debug(next_adapter,
17833 								  dbgid);
17834 				return true;
17835 			}
17836 		}
17837 		hdd_adapter_dev_put_debug(adapter, dbgid);
17838 	}
17839 
17840 	return false;
17841 }
17842 
17843 #if defined MSM_PLATFORM && (LINUX_VERSION_CODE <= KERNEL_VERSION(4, 19, 0))
17844 /**
17845  * hdd_inform_stop_sap() - call cfg80211 API to stop SAP
17846  * @adapter: pointer to adapter
17847  *
17848  * This function calls cfg80211 API to stop SAP
17849  *
17850  * Return: None
17851  */
17852 static void hdd_inform_stop_sap(struct hdd_adapter *adapter)
17853 {
17854 	hdd_debug("SAP stopped due to invalid channel vdev id %d",
17855 		  wlan_vdev_get_id(adapter->deflink->vdev));
17856 	cfg80211_ap_stopped(adapter->dev, GFP_KERNEL);
17857 }
17858 
17859 #else
17860 static void hdd_inform_stop_sap(struct hdd_adapter *adapter)
17861 {
17862 	hdd_debug("SAP stopped due to invalid channel vdev id %d",
17863 		  wlan_vdev_get_id(adapter->deflink->vdev));
17864 	cfg80211_stop_iface(adapter->hdd_ctx->wiphy, &adapter->wdev,
17865 			    GFP_KERNEL);
17866 }
17867 #endif
17868 
17869 /**
17870  * wlan_hdd_stop_sap() - This function stops bss of SAP.
17871  * @ap_adapter: SAP adapter
17872  *
17873  * This function will process the stopping of sap adapter.
17874  *
17875  * Return: None
17876  */
17877 void wlan_hdd_stop_sap(struct hdd_adapter *ap_adapter)
17878 {
17879 	struct hdd_ap_ctx *hdd_ap_ctx;
17880 	struct hdd_hostapd_state *hostapd_state;
17881 	QDF_STATUS qdf_status;
17882 	struct hdd_context *hdd_ctx;
17883 
17884 	if (!ap_adapter) {
17885 		hdd_err("ap_adapter is NULL here");
17886 		return;
17887 	}
17888 
17889 	hdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(ap_adapter->deflink);
17890 	hdd_ctx = WLAN_HDD_GET_CTX(ap_adapter);
17891 	if (wlan_hdd_validate_context(hdd_ctx))
17892 		return;
17893 
17894 	mutex_lock(&hdd_ctx->sap_lock);
17895 	if (test_bit(SOFTAP_BSS_STARTED, &ap_adapter->deflink->link_flags)) {
17896 		wlan_hdd_del_station(ap_adapter, NULL);
17897 		hostapd_state =
17898 			WLAN_HDD_GET_HOSTAP_STATE_PTR(ap_adapter->deflink);
17899 		hdd_debug("Now doing SAP STOPBSS");
17900 		qdf_event_reset(&hostapd_state->qdf_stop_bss_event);
17901 		if (QDF_STATUS_SUCCESS == wlansap_stop_bss(hdd_ap_ctx->
17902 							sap_context)) {
17903 			qdf_status = qdf_wait_single_event(&hostapd_state->
17904 					qdf_stop_bss_event,
17905 					SME_CMD_STOP_BSS_TIMEOUT);
17906 			if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
17907 				mutex_unlock(&hdd_ctx->sap_lock);
17908 				hdd_err("SAP Stop Failed");
17909 				return;
17910 			}
17911 		}
17912 		clear_bit(SOFTAP_BSS_STARTED, &ap_adapter->deflink->link_flags);
17913 		policy_mgr_decr_session_set_pcl(hdd_ctx->psoc,
17914 						ap_adapter->device_mode,
17915 						ap_adapter->deflink->vdev_id);
17916 		hdd_green_ap_start_state_mc(hdd_ctx, ap_adapter->device_mode,
17917 					    false);
17918 		hdd_inform_stop_sap(ap_adapter);
17919 		hdd_debug("SAP Stop Success");
17920 	} else {
17921 		hdd_err("Can't stop ap because its not started");
17922 	}
17923 	mutex_unlock(&hdd_ctx->sap_lock);
17924 }
17925 
17926 #if defined(WLAN_FEATURE_11BE_MLO) && defined(CFG80211_11BE_BASIC)
17927 /**
17928  * wlan_hdd_mlo_sap_reinit() - handle mlo scenario for ssr
17929  * @link_info: Pointer of link_info in adapter
17930  *
17931  * Return: QDF_STATUS
17932  */
17933 static QDF_STATUS wlan_hdd_mlo_sap_reinit(struct wlan_hdd_link_info *link_info)
17934 {
17935 	struct hdd_context *hdd_ctx = link_info->adapter->hdd_ctx;
17936 	struct sap_config *config = &link_info->session.ap.sap_config;
17937 
17938 	if (config->mlo_sap) {
17939 		if (!mlo_ap_vdev_attach(link_info->vdev, config->link_id,
17940 					config->num_link)) {
17941 			hdd_err("SAP mlo mgr attach fail");
17942 			return QDF_STATUS_E_INVAL;
17943 		}
17944 	}
17945 
17946 	if (!policy_mgr_is_mlo_sap_concurrency_allowed(hdd_ctx->psoc,
17947 						       config->mlo_sap,
17948 						       wlan_vdev_get_id(link_info->vdev))) {
17949 		hdd_err("MLO SAP concurrency check fails");
17950 		return QDF_STATUS_E_INVAL;
17951 	}
17952 
17953 	return QDF_STATUS_SUCCESS;
17954 }
17955 #else
17956 static inline QDF_STATUS
17957 wlan_hdd_mlo_sap_reinit(struct wlan_hdd_link_info *link_info)
17958 {
17959 	return QDF_STATUS_SUCCESS;
17960 }
17961 #endif
17962 
17963 void wlan_hdd_start_sap(struct wlan_hdd_link_info *link_info, bool reinit)
17964 {
17965 	struct hdd_ap_ctx *ap_ctx;
17966 	struct hdd_hostapd_state *hostapd_state;
17967 	QDF_STATUS qdf_status;
17968 	struct hdd_context *hdd_ctx;
17969 	struct sap_config *sap_config;
17970 	struct hdd_adapter *ap_adapter = link_info->adapter;
17971 
17972 	if (QDF_SAP_MODE != ap_adapter->device_mode) {
17973 		hdd_err("SoftAp role has not been enabled");
17974 		return;
17975 	}
17976 
17977 	hdd_ctx = WLAN_HDD_GET_CTX(ap_adapter);
17978 	ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(link_info);
17979 	hostapd_state = WLAN_HDD_GET_HOSTAP_STATE_PTR(link_info);
17980 	sap_config = &ap_ctx->sap_config;
17981 
17982 	mutex_lock(&hdd_ctx->sap_lock);
17983 	if (test_bit(SOFTAP_BSS_STARTED, &link_info->link_flags))
17984 		goto end;
17985 
17986 	if (wlan_hdd_cfg80211_update_apies(link_info)) {
17987 		hdd_err("SAP Not able to set AP IEs");
17988 		goto end;
17989 	}
17990 	wlan_reg_set_channel_params_for_pwrmode(hdd_ctx->pdev,
17991 						sap_config->chan_freq, 0,
17992 						&sap_config->ch_params,
17993 						REG_CURRENT_PWR_MODE);
17994 	qdf_status = wlan_hdd_mlo_sap_reinit(link_info);
17995 	if (QDF_IS_STATUS_ERROR(qdf_status)) {
17996 		hdd_err("SAP Not able to do mlo attach");
17997 		goto end;
17998 	}
17999 
18000 	qdf_event_reset(&hostapd_state->qdf_event);
18001 	qdf_status = wlansap_start_bss(ap_ctx->sap_context,
18002 				       hdd_hostapd_sap_event_cb, sap_config,
18003 				       ap_adapter->dev);
18004 	if (QDF_IS_STATUS_ERROR(qdf_status))
18005 		goto end;
18006 
18007 	hdd_debug("Waiting for SAP to start");
18008 	qdf_status = qdf_wait_single_event(&hostapd_state->qdf_event,
18009 					SME_CMD_START_BSS_TIMEOUT);
18010 	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
18011 		hdd_err("SAP Start failed");
18012 		goto end;
18013 	}
18014 	hdd_info("SAP Start Success");
18015 
18016 	if (reinit)
18017 		hdd_medium_assess_init();
18018 	wlansap_reset_sap_config_add_ie(sap_config, eUPDATE_IE_ALL);
18019 	set_bit(SOFTAP_BSS_STARTED, &link_info->link_flags);
18020 	if (hostapd_state->bss_state == BSS_START) {
18021 		policy_mgr_incr_active_session(hdd_ctx->psoc,
18022 					ap_adapter->device_mode,
18023 					link_info->vdev_id);
18024 		hdd_green_ap_start_state_mc(hdd_ctx, ap_adapter->device_mode,
18025 					    true);
18026 	}
18027 	mutex_unlock(&hdd_ctx->sap_lock);
18028 
18029 	return;
18030 end:
18031 	wlan_hdd_mlo_reset(link_info);
18032 	wlansap_reset_sap_config_add_ie(sap_config, eUPDATE_IE_ALL);
18033 	mutex_unlock(&hdd_ctx->sap_lock);
18034 	/* SAP context and beacon cleanup will happen during driver unload
18035 	 * in hdd_stop_adapter
18036 	 */
18037 	hdd_err("SAP restart after SSR failed! Reload WLAN and try SAP again");
18038 	/* Free the beacon memory in case of failure in the sap restart */
18039 	qdf_mem_free(ap_ctx->beacon);
18040 	ap_ctx->beacon = NULL;
18041 }
18042 
18043 #ifdef QCA_CONFIG_SMP
18044 /**
18045  * wlan_hdd_get_cpu() - get cpu_index
18046  *
18047  * Return: cpu_index
18048  */
18049 int wlan_hdd_get_cpu(void)
18050 {
18051 	int cpu_index = get_cpu();
18052 
18053 	put_cpu();
18054 	return cpu_index;
18055 }
18056 #endif
18057 
18058 /**
18059  * hdd_get_fwpath() - get framework path
18060  *
18061  * This function is used to get the string written by
18062  * userspace to start the wlan driver
18063  *
18064  * Return: string
18065  */
18066 const char *hdd_get_fwpath(void)
18067 {
18068 	return fwpath.string;
18069 }
18070 
18071 static inline int hdd_state_query_cb(void)
18072 {
18073 	return !!wlan_hdd_validate_context(cds_get_context(QDF_MODULE_ID_HDD));
18074 }
18075 
18076 static int __hdd_op_protect_cb(void **out_sync, const char *func)
18077 {
18078 	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
18079 
18080 	if (!hdd_ctx)
18081 		return -EAGAIN;
18082 
18083 	return __osif_psoc_sync_op_start(hdd_ctx->parent_dev,
18084 					 (struct osif_psoc_sync **)out_sync,
18085 					 func);
18086 }
18087 
18088 static void __hdd_op_unprotect_cb(void *sync, const char *func)
18089 {
18090 	__osif_psoc_sync_op_stop(sync, func);
18091 }
18092 
18093 #ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
18094 /**
18095  * hdd_logging_sock_init_svc() - Initialize logging sock
18096  *
18097  * Return: 0 for success, errno on failure
18098  */
18099 static int
18100 hdd_logging_sock_init_svc(void)
18101 {
18102 	return wlan_logging_sock_init_svc();
18103 }
18104 #else
18105 static inline int
18106 hdd_logging_sock_init_svc(void)
18107 {
18108 	return 0;
18109 }
18110 #endif
18111 
18112 /**
18113  * hdd_init() - Initialize Driver
18114  *
18115  * This function initializes CDS global context with the help of cds_init. This
18116  * has to be the first function called after probe to get a valid global
18117  * context.
18118  *
18119  * Return: 0 for success, errno on failure
18120  */
18121 int hdd_init(void)
18122 {
18123 	QDF_STATUS status;
18124 
18125 	status = cds_init();
18126 	if (QDF_IS_STATUS_ERROR(status)) {
18127 		hdd_err("Failed to allocate CDS context");
18128 		return -ENOMEM;
18129 	}
18130 
18131 	qdf_op_callbacks_register(__hdd_op_protect_cb, __hdd_op_unprotect_cb);
18132 
18133 	wlan_init_bug_report_lock();
18134 
18135 	if (hdd_logging_sock_init_svc()) {
18136 		hdd_err("logging sock init failed.");
18137 		goto err;
18138 	}
18139 
18140 	hdd_trace_init();
18141 	hdd_register_debug_callback();
18142 	wlan_roam_debug_init();
18143 
18144 	return 0;
18145 
18146 err:
18147 	wlan_destroy_bug_report_lock();
18148 	qdf_op_callbacks_register(NULL, NULL);
18149 	cds_deinit();
18150 	return -ENOMEM;
18151 }
18152 
18153 /**
18154  * hdd_deinit() - Deinitialize Driver
18155  *
18156  * This function frees CDS global context with the help of cds_deinit. This
18157  * has to be the last function call in remove callback to free the global
18158  * context.
18159  */
18160 void hdd_deinit(void)
18161 {
18162 	wlan_roam_debug_deinit();
18163 
18164 #ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
18165 	wlan_logging_sock_deinit_svc();
18166 #endif
18167 
18168 	wlan_destroy_bug_report_lock();
18169 	qdf_op_callbacks_register(NULL, NULL);
18170 	cds_deinit();
18171 }
18172 
18173 #ifdef QCA_WIFI_EMULATION
18174 #define HDD_WLAN_START_WAIT_TIME ((CDS_WMA_TIMEOUT + 5000) * 100)
18175 #else
18176 #define HDD_WLAN_START_WAIT_TIME (CDS_WMA_TIMEOUT + 5000)
18177 #endif
18178 
18179 void hdd_init_start_completion(void)
18180 {
18181 	INIT_COMPLETION(wlan_start_comp);
18182 }
18183 
18184 #ifdef WLAN_CTRL_NAME
18185 static unsigned int dev_num = 1;
18186 static struct cdev wlan_hdd_state_cdev;
18187 static struct class *class;
18188 static dev_t device;
18189 
18190 static void hdd_set_adapter_wlm_def_level(struct hdd_context *hdd_ctx)
18191 {
18192 	struct hdd_adapter *adapter, *next_adapter = NULL;
18193 	wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_GET_ADAPTER;
18194 	int ret;
18195 	QDF_STATUS qdf_status;
18196 	uint8_t latency_level;
18197 	bool reset;
18198 
18199 	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam())
18200 		return;
18201 
18202 	ret = wlan_hdd_validate_context(hdd_ctx);
18203 	if (ret != 0)
18204 		return;
18205 
18206 	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
18207 					   dbgid) {
18208 		qdf_status = ucfg_mlme_cfg_get_wlm_level(hdd_ctx->psoc,
18209 							 &latency_level);
18210 		if (QDF_IS_STATUS_ERROR(qdf_status))
18211 			adapter->latency_level =
18212 			       QCA_WLAN_VENDOR_ATTR_CONFIG_LATENCY_LEVEL_NORMAL;
18213 		else
18214 			adapter->latency_level = latency_level;
18215 		qdf_status = ucfg_mlme_cfg_get_wlm_reset(hdd_ctx->psoc, &reset);
18216 		if (QDF_IS_STATUS_ERROR(qdf_status)) {
18217 			hdd_err("could not get the wlm reset flag");
18218 			reset = false;
18219 		}
18220 
18221 		if (hdd_get_multi_client_ll_support(adapter) && !reset)
18222 			wlan_hdd_deinit_multi_client_info_table(adapter);
18223 
18224 		adapter->upgrade_udp_qos_threshold = QCA_WLAN_AC_BK;
18225 		hdd_debug("UDP packets qos reset to: %d",
18226 			  adapter->upgrade_udp_qos_threshold);
18227 		hdd_adapter_dev_put_debug(adapter, dbgid);
18228 	}
18229 }
18230 
18231 static int wlan_hdd_state_ctrl_param_open(struct inode *inode,
18232 					  struct file *file)
18233 {
18234 	qdf_atomic_inc(&wlan_hdd_state_fops_ref);
18235 
18236 	return 0;
18237 }
18238 
18239 static void __hdd_inform_wifi_off(void)
18240 {
18241 	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
18242 	int ret;
18243 
18244 	ret = wlan_hdd_validate_context(hdd_ctx);
18245 	if (ret != 0)
18246 		return;
18247 
18248 	ucfg_dlm_wifi_off(hdd_ctx->pdev);
18249 }
18250 
18251 static void hdd_inform_wifi_off(void)
18252 {
18253 	int ret;
18254 	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
18255 	struct osif_psoc_sync *psoc_sync;
18256 
18257 	if (!hdd_ctx)
18258 		return;
18259 
18260 	ret = osif_psoc_sync_op_start(wiphy_dev(hdd_ctx->wiphy), &psoc_sync);
18261 	if (ret)
18262 		return;
18263 
18264 	hdd_set_adapter_wlm_def_level(hdd_ctx);
18265 	__hdd_inform_wifi_off();
18266 
18267 	osif_psoc_sync_op_stop(psoc_sync);
18268 }
18269 
18270 #if defined CFG80211_USER_HINT_CELL_BASE_SELF_MANAGED || \
18271 	(LINUX_VERSION_CODE >= KERNEL_VERSION(4, 18, 0))
18272 static void hdd_inform_wifi_on(void)
18273 {
18274 	int ret;
18275 	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
18276 	struct osif_psoc_sync *psoc_sync;
18277 
18278 	hdd_nofl_debug("inform regdomain for wifi on");
18279 	ret = wlan_hdd_validate_context(hdd_ctx);
18280 	if (ret)
18281 		return;
18282 	if (!wlan_hdd_validate_modules_state(hdd_ctx))
18283 		return;
18284 	if (!hdd_ctx->wiphy)
18285 		return;
18286 	ret = osif_psoc_sync_op_start(wiphy_dev(hdd_ctx->wiphy), &psoc_sync);
18287 	if (ret)
18288 		return;
18289 	if (hdd_ctx->wiphy->registered)
18290 		hdd_send_wiphy_regd_sync_event(hdd_ctx);
18291 
18292 	osif_psoc_sync_op_stop(psoc_sync);
18293 }
18294 #else
18295 static void hdd_inform_wifi_on(void)
18296 {
18297 }
18298 #endif
18299 
18300 static int hdd_validate_wlan_string(const char __user *user_buf)
18301 {
18302 	char buf[15];
18303 	int i;
18304 	static const char * const wlan_str[] = {
18305 		[WLAN_OFF_STR] = "OFF",
18306 		[WLAN_ON_STR] = "ON",
18307 		[WLAN_ENABLE_STR] = "ENABLE",
18308 		[WLAN_DISABLE_STR] = "DISABLE",
18309 		[WLAN_WAIT_FOR_READY_STR] = "WAIT_FOR_READY",
18310 		[WLAN_FORCE_DISABLE_STR] = "FORCE_DISABLE"
18311 	};
18312 
18313 	if (copy_from_user(buf, user_buf, sizeof(buf))) {
18314 		pr_err("Failed to read buffer\n");
18315 		return -EINVAL;
18316 	}
18317 
18318 	for (i = 0; i < ARRAY_SIZE(wlan_str); i++) {
18319 		if (qdf_str_ncmp(buf, wlan_str[i], strlen(wlan_str[i])) == 0)
18320 			return i;
18321 	}
18322 
18323 	return -EINVAL;
18324 }
18325 
18326 #ifdef FEATURE_CNSS_HW_SECURE_DISABLE
18327 #define WIFI_DISABLE_SLEEP (10)
18328 #define WIFI_DISABLE_MAX_RETRY_ATTEMPTS (10)
18329 static bool g_soft_unload;
18330 
18331 bool hdd_get_wlan_driver_status(void)
18332 {
18333 	return g_soft_unload;
18334 }
18335 
18336 static int hdd_wlan_soft_driver_load(void)
18337 {
18338 	if (!cds_is_driver_loaded()) {
18339 		hdd_debug("\nEnabling CNSS WLAN HW");
18340 		pld_wlan_hw_enable();
18341 		return 0;
18342 	}
18343 
18344 	if (!g_soft_unload) {
18345 		hdd_debug_rl("Enabling WiFi\n");
18346 		return -EINVAL;
18347 	}
18348 
18349 	hdd_driver_load();
18350 	g_soft_unload = false;
18351 	return 0;
18352 }
18353 
18354 static void hdd_wlan_soft_driver_unload(void)
18355 {
18356 	if (g_soft_unload) {
18357 		hdd_debug_rl("WiFi is already disabled");
18358 		return;
18359 	}
18360 	hdd_debug("Initiating soft driver unload\n");
18361 	g_soft_unload = true;
18362 	hdd_driver_unload();
18363 }
18364 
18365 static int hdd_wlan_idle_shutdown(struct hdd_context *hdd_ctx)
18366 {
18367 	int ret;
18368 	int retries = 0;
18369 	void *hif_ctx;
18370 
18371 	if (!hdd_ctx) {
18372 		hdd_err_rl("hdd_ctx is Null");
18373 		return -EINVAL;
18374 	}
18375 
18376 	hif_ctx = cds_get_context(QDF_MODULE_ID_HIF);
18377 
18378 	hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_IDLE_SHUTDOWN);
18379 
18380 	while (retries < WIFI_DISABLE_MAX_RETRY_ATTEMPTS) {
18381 		if (hif_ctx) {
18382 			/*
18383 			 * Trigger runtime sync resume before psoc_idle_shutdown
18384 			 * such that resume can happen successfully
18385 			 */
18386 			qdf_rtpm_sync_resume();
18387 		}
18388 		ret = pld_idle_shutdown(hdd_ctx->parent_dev,
18389 					hdd_psoc_idle_shutdown);
18390 
18391 		if (-EAGAIN == ret || hdd_ctx->is_wiphy_suspended) {
18392 			hdd_debug("System suspend in progress.Retries done:%d",
18393 				  retries);
18394 			msleep(WIFI_DISABLE_SLEEP);
18395 			retries++;
18396 			continue;
18397 		}
18398 		break;
18399 	}
18400 	hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_IDLE_SHUTDOWN);
18401 
18402 	if (retries > WIFI_DISABLE_MAX_RETRY_ATTEMPTS) {
18403 		hdd_debug("Max retries reached");
18404 		return -EINVAL;
18405 	}
18406 	hdd_debug_rl("WiFi is disabled");
18407 
18408 	return 0;
18409 }
18410 
18411 static int hdd_disable_wifi(struct hdd_context *hdd_ctx)
18412 {
18413 	int ret;
18414 
18415 	if (hdd_ctx->is_wlan_disabled) {
18416 		hdd_err_rl("Wifi is already disabled");
18417 		return 0;
18418 	}
18419 
18420 	hdd_debug("Initiating WLAN idle shutdown");
18421 	if (hdd_is_any_interface_open(hdd_ctx)) {
18422 		hdd_err("Interfaces still open, cannot process wifi disable");
18423 		return -EAGAIN;
18424 	}
18425 
18426 	hdd_ctx->is_wlan_disabled = true;
18427 
18428 	ret = hdd_wlan_idle_shutdown(hdd_ctx);
18429 	if (ret)
18430 		hdd_ctx->is_wlan_disabled = false;
18431 
18432 	return ret;
18433 }
18434 #else
18435 static int hdd_wlan_soft_driver_load(void)
18436 {
18437 	return -EINVAL;
18438 }
18439 
18440 static void hdd_wlan_soft_driver_unload(void)
18441 {
18442 }
18443 
18444 static int hdd_disable_wifi(struct hdd_context *hdd_ctx)
18445 {
18446 	return 0;
18447 }
18448 #endif /* FEATURE_CNSS_HW_SECURE_DISABLE */
18449 
18450 static ssize_t wlan_hdd_state_ctrl_param_write(struct file *filp,
18451 						const char __user *user_buf,
18452 						size_t count,
18453 						loff_t *f_pos)
18454 {
18455 	int id, ret;
18456 	unsigned long rc;
18457 	struct hdd_context *hdd_ctx;
18458 	bool is_wait_for_ready = false;
18459 	bool is_wlan_force_disabled;
18460 
18461 	hdd_enter();
18462 
18463 	id = hdd_validate_wlan_string(user_buf);
18464 
18465 	switch (id) {
18466 	case WLAN_OFF_STR:
18467 		hdd_info("Wifi turning off from UI\n");
18468 		hdd_inform_wifi_off();
18469 		goto exit;
18470 	case WLAN_ON_STR:
18471 		hdd_info("Wifi Turning On from UI\n");
18472 		break;
18473 	case WLAN_WAIT_FOR_READY_STR:
18474 		is_wait_for_ready = true;
18475 		hdd_info("Wifi wait for ready from UI\n");
18476 		break;
18477 	case WLAN_ENABLE_STR:
18478 		hdd_nofl_debug("Received WiFi enable from framework\n");
18479 		if (!hdd_wlan_soft_driver_load())
18480 			goto exit;
18481 		pr_info("Enabling WiFi\n");
18482 		break;
18483 	case WLAN_DISABLE_STR:
18484 		hdd_nofl_debug("Received WiFi disable from framework\n");
18485 		if (!cds_is_driver_loaded())
18486 			goto exit;
18487 
18488 		is_wlan_force_disabled = hdd_get_wlan_driver_status();
18489 		if (is_wlan_force_disabled)
18490 			goto exit;
18491 		pr_info("Disabling WiFi\n");
18492 		break;
18493 	case WLAN_FORCE_DISABLE_STR:
18494 		hdd_nofl_debug("Received Force WiFi disable from framework\n");
18495 		if (!cds_is_driver_loaded())
18496 			goto exit;
18497 
18498 		hdd_wlan_soft_driver_unload();
18499 		goto exit;
18500 	default:
18501 		hdd_err_rl("Invalid value received from framework");
18502 		return -EINVAL;
18503 	}
18504 
18505 	hdd_info("is_driver_loaded %d is_driver_recovering %d",
18506 		 cds_is_driver_loaded(), cds_is_driver_recovering());
18507 
18508 	if (!cds_is_driver_loaded() || cds_is_driver_recovering()) {
18509 		rc = wait_for_completion_timeout(&wlan_start_comp,
18510 				msecs_to_jiffies(HDD_WLAN_START_WAIT_TIME));
18511 		if (!rc) {
18512 			hdd_err("Driver Loading Timed-out!!");
18513 			ret = -EINVAL;
18514 			return ret;
18515 		}
18516 	}
18517 
18518 	if (is_wait_for_ready)
18519 		return count;
18520 	/*
18521 	 * Flush idle shutdown work for cases to synchronize the wifi on
18522 	 * during the idle shutdown.
18523 	 */
18524 	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
18525 	if (hdd_ctx)
18526 		hdd_psoc_idle_timer_stop(hdd_ctx);
18527 
18528 	if (id == WLAN_DISABLE_STR) {
18529 		if (!hdd_ctx) {
18530 			hdd_err_rl("hdd_ctx is Null");
18531 			goto exit;
18532 		}
18533 
18534 		ret = hdd_disable_wifi(hdd_ctx);
18535 		if (ret)
18536 			return ret;
18537 	}
18538 
18539 	if (id == WLAN_ENABLE_STR) {
18540 		if (!hdd_ctx) {
18541 			hdd_err_rl("hdd_ctx is Null");
18542 			goto exit;
18543 		}
18544 
18545 		if (!hdd_ctx->is_wlan_disabled) {
18546 			hdd_err_rl("WiFi is already enabled");
18547 			goto exit;
18548 		}
18549 		hdd_ctx->is_wlan_disabled = false;
18550 	}
18551 
18552 	if (id == WLAN_ON_STR)
18553 		hdd_inform_wifi_on();
18554 exit:
18555 	hdd_exit();
18556 	return count;
18557 }
18558 
18559 /**
18560  * wlan_hdd_state_ctrl_param_release() -  Release callback for /dev/wlan.
18561  *
18562  * @inode: struct inode pointer.
18563  * @file: struct file pointer.
18564  *
18565  * Release callback that would be invoked when the file operations has
18566  * completed fully. This is implemented to provide a reference count mechanism
18567  * via which the driver can wait till all possible usage of the /dev/wlan
18568  * file is completed.
18569  *
18570  * Return: Success
18571  */
18572 static int wlan_hdd_state_ctrl_param_release(struct inode *inode,
18573 					     struct file *file)
18574 {
18575 	qdf_atomic_dec(&wlan_hdd_state_fops_ref);
18576 
18577 	return 0;
18578 }
18579 
18580 const struct file_operations wlan_hdd_state_fops = {
18581 	.owner = THIS_MODULE,
18582 	.open = wlan_hdd_state_ctrl_param_open,
18583 	.write = wlan_hdd_state_ctrl_param_write,
18584 	.release = wlan_hdd_state_ctrl_param_release,
18585 };
18586 
18587 static int  wlan_hdd_state_ctrl_param_create(void)
18588 {
18589 	unsigned int wlan_hdd_state_major = 0;
18590 	int ret;
18591 	struct device *dev;
18592 
18593 	init_completion(&wlan_start_comp);
18594 	qdf_atomic_init(&wlan_hdd_state_fops_ref);
18595 
18596 	device = MKDEV(wlan_hdd_state_major, 0);
18597 
18598 	ret = alloc_chrdev_region(&device, 0, dev_num, "qcwlanstate");
18599 	if (ret) {
18600 		pr_err("Failed to register qcwlanstate");
18601 		goto dev_alloc_err;
18602 	}
18603 	wlan_hdd_state_major = MAJOR(device);
18604 
18605 	class = class_create(THIS_MODULE, WLAN_CTRL_NAME);
18606 	if (IS_ERR(class)) {
18607 		pr_err("wlan_hdd_state class_create error");
18608 		goto class_err;
18609 	}
18610 
18611 	dev = device_create(class, NULL, device, NULL, WLAN_CTRL_NAME);
18612 	if (IS_ERR(dev)) {
18613 		pr_err("wlan_hdd_statedevice_create error");
18614 		goto err_class_destroy;
18615 	}
18616 
18617 	cdev_init(&wlan_hdd_state_cdev, &wlan_hdd_state_fops);
18618 
18619 	wlan_hdd_state_cdev.owner = THIS_MODULE;
18620 
18621 	ret = cdev_add(&wlan_hdd_state_cdev, device, dev_num);
18622 	if (ret) {
18623 		pr_err("Failed to add cdev error");
18624 		goto cdev_add_err;
18625 	}
18626 
18627 	pr_info("wlan_hdd_state %s major(%d) initialized",
18628 		WLAN_CTRL_NAME, wlan_hdd_state_major);
18629 
18630 	return 0;
18631 
18632 cdev_add_err:
18633 	device_destroy(class, device);
18634 err_class_destroy:
18635 	class_destroy(class);
18636 class_err:
18637 	unregister_chrdev_region(device, dev_num);
18638 dev_alloc_err:
18639 	return -ENODEV;
18640 }
18641 
18642 /*
18643  * When multiple instances of the driver are loaded in parallel, only
18644  * one can create and own the state ctrl param. An instance of the
18645  * driver that creates the state ctrl param will wait for
18646  * HDD_WLAN_START_WAIT_TIME to be probed. If it is probed, then that
18647  * instance of the driver will stay loaded and no other instances of
18648  * the driver can load. But if it is not probed, then that instance of
18649  * the driver will destroy the state ctrl param and exit, and another
18650  * instance of the driver can then create the state ctrl param.
18651  */
18652 
18653 /* max number of instances we expect (arbitrary) */
18654 #define WLAN_DRIVER_MAX_INSTANCES 5
18655 
18656 /* max amount of time an instance has to wait for all instances */
18657 #define CTRL_PARAM_WAIT (WLAN_DRIVER_MAX_INSTANCES * HDD_WLAN_START_WAIT_TIME)
18658 
18659 /* amount of time we sleep for each retry (arbitrary) */
18660 #define CTRL_PARAM_SLEEP 100
18661 
18662 static void wlan_hdd_state_ctrl_param_destroy(void)
18663 {
18664 	cdev_del(&wlan_hdd_state_cdev);
18665 	device_destroy(class, device);
18666 	class_destroy(class);
18667 	unregister_chrdev_region(device, dev_num);
18668 
18669 	pr_info("Device node unregistered");
18670 }
18671 
18672 #else /* WLAN_CTRL_NAME */
18673 
18674 static int wlan_hdd_state_ctrl_param_create(void)
18675 {
18676 	return 0;
18677 }
18678 
18679 static void wlan_hdd_state_ctrl_param_destroy(void)
18680 {
18681 }
18682 
18683 #endif /* WLAN_CTRL_NAME */
18684 
18685 /**
18686  * hdd_send_scan_done_complete_cb() - API to send scan done indication to upper
18687  * layer
18688  * @vdev_id: vdev id
18689  *
18690  * Return: none
18691  */
18692 static void hdd_send_scan_done_complete_cb(uint8_t vdev_id)
18693 {
18694 	struct hdd_context *hdd_ctx;
18695 	struct wlan_hdd_link_info *link_info;
18696 	struct hdd_adapter *adapter;
18697 	struct sk_buff *vendor_event;
18698 	uint32_t len;
18699 
18700 	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
18701 	if (!hdd_ctx)
18702 		return;
18703 
18704 	link_info = hdd_get_link_info_by_vdev(hdd_ctx, vdev_id);
18705 	if (!link_info) {
18706 		hdd_err("Invalid vdev id:%d", vdev_id);
18707 		return;
18708 	}
18709 
18710 	adapter = link_info->adapter;
18711 	len = NLMSG_HDRLEN;
18712 	vendor_event =
18713 		wlan_cfg80211_vendor_event_alloc(
18714 			hdd_ctx->wiphy, &adapter->wdev, len,
18715 			QCA_NL80211_VENDOR_SUBCMD_CONNECTED_CHANNEL_STATS_INDEX,
18716 			GFP_KERNEL);
18717 
18718 	if (!vendor_event) {
18719 		hdd_err("wlan_cfg80211_vendor_event_alloc failed");
18720 		return;
18721 	}
18722 
18723 	hdd_debug("sending scan done ind to upper layer for vdev_id:%d",
18724 		  vdev_id);
18725 	wlan_cfg80211_vendor_event(vendor_event, GFP_KERNEL);
18726 }
18727 
18728 struct osif_vdev_mgr_ops osif_vdev_mgrlegacy_ops = {
18729 #ifdef WLAN_FEATURE_DYNAMIC_MAC_ADDR_UPDATE
18730 	.osif_vdev_mgr_set_mac_addr_response = hdd_set_mac_addr_event_cb,
18731 #endif
18732 	.osif_vdev_mgr_send_scan_done_complete_cb =
18733 					hdd_send_scan_done_complete_cb,
18734 
18735 };
18736 
18737 static QDF_STATUS hdd_vdev_mgr_register_cb(void)
18738 {
18739 	osif_vdev_mgr_set_legacy_cb(&osif_vdev_mgrlegacy_ops);
18740 	return osif_vdev_mgr_register_cb();
18741 }
18742 
18743 static void hdd_vdev_mgr_unregister_cb(void)
18744 {
18745 	osif_vdev_mgr_reset_legacy_cb();
18746 }
18747 
18748 /**
18749  * hdd_component_cb_init() - Initialize component callbacks
18750  *
18751  * This function initializes hdd callbacks to different
18752  * components
18753  *
18754  * Context: Any context.
18755  * Return: QDF_STATUS
18756  */
18757 static QDF_STATUS hdd_component_cb_init(void)
18758 {
18759 	QDF_STATUS status;
18760 
18761 	status = hdd_cm_register_cb();
18762 	if (QDF_IS_STATUS_ERROR(status))
18763 		return status;
18764 
18765 	status = hdd_vdev_mgr_register_cb();
18766 	if (QDF_IS_STATUS_ERROR(status))
18767 		goto cm_unregister_cb;
18768 
18769 	status = osif_twt_register_cb();
18770 	if (QDF_IS_STATUS_ERROR(status))
18771 		goto hdd_vdev_mgr_unregister_cb;
18772 
18773 	status = hdd_pre_cac_register_cb();
18774 	if (QDF_IS_STATUS_ERROR(status))
18775 		goto hdd_vdev_mgr_unregister_cb;
18776 
18777 	return QDF_STATUS_SUCCESS;
18778 
18779 hdd_vdev_mgr_unregister_cb:
18780 	hdd_vdev_mgr_unregister_cb();
18781 cm_unregister_cb:
18782 	hdd_cm_unregister_cb();
18783 	return status;
18784 }
18785 
18786 /**
18787  * hdd_component_cb_deinit() - De-initialize component callbacks
18788  *
18789  * This function de-initializes hdd callbacks with different components
18790  *
18791  * Context: Any context.
18792  * Return: None`
18793  */
18794 static void hdd_component_cb_deinit(void)
18795 {
18796 	hdd_pre_cac_unregister_cb();
18797 	hdd_vdev_mgr_unregister_cb();
18798 	hdd_cm_unregister_cb();
18799 }
18800 
18801 /**
18802  * hdd_component_init() - Initialize all components
18803  *
18804  * Return: QDF_STATUS
18805  */
18806 static QDF_STATUS hdd_component_init(void)
18807 {
18808 	QDF_STATUS status;
18809 
18810 	/* initialize converged components */
18811 
18812 	status = ucfg_mlme_global_init();
18813 	if (QDF_IS_STATUS_ERROR(status))
18814 		return status;
18815 
18816 	status = dispatcher_init();
18817 	if (QDF_IS_STATUS_ERROR(status))
18818 		goto mlme_global_deinit;
18819 
18820 	status = target_if_init(wma_get_psoc_from_scn_handle);
18821 	if (QDF_IS_STATUS_ERROR(status))
18822 		goto dispatcher_deinit;
18823 
18824 	/* initialize non-converged components */
18825 	status = ucfg_mlme_init();
18826 	if (QDF_IS_STATUS_ERROR(status))
18827 		goto target_if_deinit;
18828 
18829 	status = ucfg_fwol_init();
18830 	if (QDF_IS_STATUS_ERROR(status))
18831 		goto mlme_deinit;
18832 
18833 	status = disa_init();
18834 	if (QDF_IS_STATUS_ERROR(status))
18835 		goto fwol_deinit;
18836 
18837 	status = pmo_init();
18838 	if (QDF_IS_STATUS_ERROR(status))
18839 		goto disa_deinit;
18840 
18841 	status = ucfg_ocb_init();
18842 	if (QDF_IS_STATUS_ERROR(status))
18843 		goto pmo_deinit;
18844 
18845 	status = ipa_init();
18846 	if (QDF_IS_STATUS_ERROR(status))
18847 		goto ocb_deinit;
18848 
18849 	status = ucfg_action_oui_init();
18850 	if (QDF_IS_STATUS_ERROR(status))
18851 		goto ipa_deinit;
18852 
18853 	status = nan_init();
18854 	if (QDF_IS_STATUS_ERROR(status))
18855 		goto action_oui_deinit;
18856 
18857 	status = ucfg_p2p_init();
18858 	if (QDF_IS_STATUS_ERROR(status))
18859 		goto nan_deinit;
18860 
18861 	status = ucfg_interop_issues_ap_init();
18862 	if (QDF_IS_STATUS_ERROR(status))
18863 		goto p2p_deinit;
18864 
18865 	status = policy_mgr_init();
18866 	if (QDF_IS_STATUS_ERROR(status))
18867 		goto interop_issues_ap_deinit;
18868 
18869 	status = ucfg_tdls_init();
18870 	if (QDF_IS_STATUS_ERROR(status))
18871 		goto policy_deinit;
18872 
18873 	status = ucfg_dlm_init();
18874 	if (QDF_IS_STATUS_ERROR(status))
18875 		goto tdls_deinit;
18876 
18877 	status = ucfg_pkt_capture_init();
18878 	if (QDF_IS_STATUS_ERROR(status))
18879 		goto dlm_deinit;
18880 
18881 	status = ucfg_ftm_time_sync_init();
18882 	if (QDF_IS_STATUS_ERROR(status))
18883 		goto pkt_capture_deinit;
18884 
18885 	status = ucfg_pre_cac_init();
18886 	if (QDF_IS_STATUS_ERROR(status))
18887 		goto pre_cac_deinit;
18888 
18889 	status = ucfg_dp_init();
18890 	if (QDF_IS_STATUS_ERROR(status))
18891 		goto pre_cac_deinit;
18892 
18893 	status = ucfg_qmi_init();
18894 	if (QDF_IS_STATUS_ERROR(status))
18895 		goto dp_deinit;
18896 
18897 	status = ucfg_ll_sap_init();
18898 	if (QDF_IS_STATUS_ERROR(status))
18899 		goto qmi_deinit;
18900 
18901 	status = ucfg_afc_init();
18902 	if (QDF_IS_STATUS_ERROR(status))
18903 		goto ll_sap_deinit;
18904 
18905 	status = hdd_mlo_mgr_register_osif_ops();
18906 	if (QDF_IS_STATUS_ERROR(status))
18907 		goto afc_deinit;
18908 
18909 	return QDF_STATUS_SUCCESS;
18910 
18911 afc_deinit:
18912 	ucfg_afc_deinit();
18913 ll_sap_deinit:
18914 	ucfg_ll_sap_deinit();
18915 qmi_deinit:
18916 	ucfg_qmi_deinit();
18917 dp_deinit:
18918 	ucfg_dp_deinit();
18919 pre_cac_deinit:
18920 	ucfg_pre_cac_deinit();
18921 pkt_capture_deinit:
18922 	ucfg_pkt_capture_deinit();
18923 dlm_deinit:
18924 	ucfg_dlm_deinit();
18925 tdls_deinit:
18926 	ucfg_tdls_deinit();
18927 policy_deinit:
18928 	policy_mgr_deinit();
18929 interop_issues_ap_deinit:
18930 	ucfg_interop_issues_ap_deinit();
18931 p2p_deinit:
18932 	ucfg_p2p_deinit();
18933 nan_deinit:
18934 	nan_deinit();
18935 action_oui_deinit:
18936 	ucfg_action_oui_deinit();
18937 ipa_deinit:
18938 	ipa_deinit();
18939 ocb_deinit:
18940 	ucfg_ocb_deinit();
18941 pmo_deinit:
18942 	pmo_deinit();
18943 disa_deinit:
18944 	disa_deinit();
18945 fwol_deinit:
18946 	ucfg_fwol_deinit();
18947 mlme_deinit:
18948 	ucfg_mlme_deinit();
18949 target_if_deinit:
18950 	target_if_deinit();
18951 dispatcher_deinit:
18952 	dispatcher_deinit();
18953 mlme_global_deinit:
18954 	ucfg_mlme_global_deinit();
18955 
18956 	return status;
18957 }
18958 
18959 /**
18960  * hdd_component_deinit() - Deinitialize all components
18961  *
18962  * Return: None
18963  */
18964 static void hdd_component_deinit(void)
18965 {
18966 	/* deinitialize non-converged components */
18967 	hdd_mlo_mgr_unregister_osif_ops();
18968 	ucfg_afc_deinit();
18969 	ucfg_ll_sap_deinit();
18970 	ucfg_qmi_deinit();
18971 	ucfg_dp_deinit();
18972 	ucfg_pre_cac_deinit();
18973 	ucfg_ftm_time_sync_deinit();
18974 	ucfg_pkt_capture_deinit();
18975 	ucfg_dlm_deinit();
18976 	ucfg_tdls_deinit();
18977 	policy_mgr_deinit();
18978 	ucfg_interop_issues_ap_deinit();
18979 	ucfg_p2p_deinit();
18980 	nan_deinit();
18981 	ucfg_action_oui_deinit();
18982 	ipa_deinit();
18983 	ucfg_ocb_deinit();
18984 	pmo_deinit();
18985 	disa_deinit();
18986 	ucfg_fwol_deinit();
18987 	ucfg_mlme_deinit();
18988 
18989 	/* deinitialize converged components */
18990 	target_if_deinit();
18991 	dispatcher_deinit();
18992 	ucfg_mlme_global_deinit();
18993 }
18994 
18995 QDF_STATUS hdd_component_psoc_open(struct wlan_objmgr_psoc *psoc)
18996 {
18997 	QDF_STATUS status;
18998 
18999 	status = ucfg_mlme_psoc_open(psoc);
19000 	if (QDF_IS_STATUS_ERROR(status))
19001 		return status;
19002 
19003 	status = ucfg_dlm_psoc_open(psoc);
19004 	if (QDF_IS_STATUS_ERROR(status))
19005 		goto err_dlm;
19006 
19007 	status = ucfg_fwol_psoc_open(psoc);
19008 	if (QDF_IS_STATUS_ERROR(status))
19009 		goto err_fwol;
19010 
19011 	status = ucfg_pmo_psoc_open(psoc);
19012 	if (QDF_IS_STATUS_ERROR(status))
19013 		goto err_pmo;
19014 
19015 	status = ucfg_policy_mgr_psoc_open(psoc);
19016 	if (QDF_IS_STATUS_ERROR(status))
19017 		goto err_plcy_mgr;
19018 
19019 	status = ucfg_p2p_psoc_open(psoc);
19020 	if (QDF_IS_STATUS_ERROR(status))
19021 		goto err_p2p;
19022 
19023 	status = ucfg_tdls_psoc_open(psoc);
19024 	if (QDF_IS_STATUS_ERROR(status))
19025 		goto err_tdls;
19026 
19027 	status = ucfg_nan_psoc_open(psoc);
19028 	if (QDF_IS_STATUS_ERROR(status))
19029 		goto err_nan;
19030 
19031 	status = ucfg_twt_psoc_open(psoc);
19032 	if (QDF_IS_STATUS_ERROR(status))
19033 		goto err_twt;
19034 
19035 	status = ucfg_wifi_pos_psoc_open(psoc);
19036 	if (QDF_IS_STATUS_ERROR(status))
19037 		goto err_wifi_pos;
19038 
19039 	status = ucfg_dp_psoc_open(psoc);
19040 	if (QDF_IS_STATUS_ERROR(status))
19041 		goto err_dp;
19042 
19043 	return status;
19044 
19045 err_dp:
19046 	ucfg_wifi_pos_psoc_close(psoc);
19047 err_wifi_pos:
19048 	ucfg_twt_psoc_close(psoc);
19049 err_twt:
19050 	ucfg_nan_psoc_close(psoc);
19051 err_nan:
19052 	ucfg_tdls_psoc_close(psoc);
19053 err_tdls:
19054 	ucfg_p2p_psoc_close(psoc);
19055 err_p2p:
19056 	ucfg_policy_mgr_psoc_close(psoc);
19057 err_plcy_mgr:
19058 	ucfg_pmo_psoc_close(psoc);
19059 err_pmo:
19060 	ucfg_fwol_psoc_close(psoc);
19061 err_fwol:
19062 	ucfg_dlm_psoc_close(psoc);
19063 err_dlm:
19064 	ucfg_mlme_psoc_close(psoc);
19065 
19066 	return status;
19067 }
19068 
19069 void hdd_component_psoc_close(struct wlan_objmgr_psoc *psoc)
19070 {
19071 	ucfg_dp_psoc_close(psoc);
19072 	ucfg_wifi_pos_psoc_close(psoc);
19073 	ucfg_twt_psoc_close(psoc);
19074 	ucfg_nan_psoc_close(psoc);
19075 	ucfg_tdls_psoc_close(psoc);
19076 	ucfg_p2p_psoc_close(psoc);
19077 	ucfg_policy_mgr_psoc_close(psoc);
19078 	ucfg_pmo_psoc_close(psoc);
19079 	ucfg_fwol_psoc_close(psoc);
19080 	ucfg_dlm_psoc_close(psoc);
19081 	ucfg_mlme_psoc_close(psoc);
19082 }
19083 
19084 void hdd_component_psoc_enable(struct wlan_objmgr_psoc *psoc)
19085 {
19086 	ocb_psoc_enable(psoc);
19087 	disa_psoc_enable(psoc);
19088 	nan_psoc_enable(psoc);
19089 	p2p_psoc_enable(psoc);
19090 	ucfg_interop_issues_ap_psoc_enable(psoc);
19091 	policy_mgr_psoc_enable(psoc);
19092 	ucfg_tdls_psoc_enable(psoc);
19093 	ucfg_fwol_psoc_enable(psoc);
19094 	ucfg_action_oui_psoc_enable(psoc);
19095 }
19096 
19097 void hdd_component_psoc_disable(struct wlan_objmgr_psoc *psoc)
19098 {
19099 	ucfg_action_oui_psoc_disable(psoc);
19100 	ucfg_fwol_psoc_disable(psoc);
19101 	ucfg_tdls_psoc_disable(psoc);
19102 	policy_mgr_psoc_disable(psoc);
19103 	ucfg_interop_issues_ap_psoc_disable(psoc);
19104 	p2p_psoc_disable(psoc);
19105 	nan_psoc_disable(psoc);
19106 	disa_psoc_disable(psoc);
19107 	ocb_psoc_disable(psoc);
19108 }
19109 
19110 QDF_STATUS hdd_component_pdev_open(struct wlan_objmgr_pdev *pdev)
19111 {
19112 	return ucfg_mlme_pdev_open(pdev);
19113 }
19114 
19115 void hdd_component_pdev_close(struct wlan_objmgr_pdev *pdev)
19116 {
19117 	ucfg_mlme_pdev_close(pdev);
19118 }
19119 
19120 static QDF_STATUS hdd_qdf_print_init(void)
19121 {
19122 	QDF_STATUS status;
19123 	int qdf_print_idx;
19124 
19125 	status = qdf_print_setup();
19126 	if (QDF_IS_STATUS_ERROR(status)) {
19127 		pr_err("Failed qdf_print_setup; status:%u\n", status);
19128 		return status;
19129 	}
19130 
19131 	qdf_print_idx = qdf_print_ctrl_register(cinfo, NULL, NULL, "MCL_WLAN");
19132 	if (qdf_print_idx < 0) {
19133 		pr_err("Failed to register for qdf_print_ctrl\n");
19134 		return QDF_STATUS_E_FAILURE;
19135 	}
19136 
19137 	qdf_set_pidx(qdf_print_idx);
19138 
19139 	return QDF_STATUS_SUCCESS;
19140 }
19141 
19142 static void hdd_qdf_print_deinit(void)
19143 {
19144 	int qdf_pidx = qdf_get_pidx();
19145 
19146 	qdf_set_pidx(-1);
19147 	qdf_print_ctrl_cleanup(qdf_pidx);
19148 
19149 	/* currently, no qdf print 'un-setup'*/
19150 }
19151 
19152 static QDF_STATUS hdd_qdf_init(void)
19153 {
19154 	QDF_STATUS status;
19155 
19156 	status = hdd_qdf_print_init();
19157 	if (QDF_IS_STATUS_ERROR(status))
19158 		goto exit;
19159 
19160 	status = qdf_debugfs_init();
19161 	if (QDF_IS_STATUS_ERROR(status)) {
19162 		hdd_err("Failed to init debugfs; status:%u", status);
19163 		goto print_deinit;
19164 	}
19165 
19166 	qdf_lock_stats_init();
19167 	qdf_mem_init();
19168 	qdf_delayed_work_feature_init();
19169 	qdf_periodic_work_feature_init();
19170 	qdf_wake_lock_feature_init();
19171 	qdf_mc_timer_manager_init();
19172 	qdf_event_list_init();
19173 
19174 	status = qdf_talloc_feature_init();
19175 	if (QDF_IS_STATUS_ERROR(status)) {
19176 		hdd_err("Failed to init talloc; status:%u", status);
19177 		goto event_deinit;
19178 	}
19179 
19180 	status = qdf_cpuhp_init();
19181 	if (QDF_IS_STATUS_ERROR(status)) {
19182 		hdd_err("Failed to init cpuhp; status:%u", status);
19183 		goto talloc_deinit;
19184 	}
19185 
19186 	status = qdf_trace_spin_lock_init();
19187 	if (QDF_IS_STATUS_ERROR(status)) {
19188 		hdd_err("Failed to init spinlock; status:%u", status);
19189 		goto cpuhp_deinit;
19190 	}
19191 
19192 	qdf_trace_init();
19193 	qdf_minidump_init();
19194 	qdf_ssr_driver_dump_init();
19195 	qdf_register_debugcb_init();
19196 
19197 	return QDF_STATUS_SUCCESS;
19198 
19199 cpuhp_deinit:
19200 	qdf_cpuhp_deinit();
19201 talloc_deinit:
19202 	qdf_talloc_feature_deinit();
19203 event_deinit:
19204 	qdf_event_list_destroy();
19205 	qdf_mc_timer_manager_exit();
19206 	qdf_wake_lock_feature_deinit();
19207 	qdf_periodic_work_feature_deinit();
19208 	qdf_delayed_work_feature_deinit();
19209 	qdf_mem_exit();
19210 	qdf_lock_stats_deinit();
19211 	qdf_debugfs_exit();
19212 print_deinit:
19213 	hdd_qdf_print_deinit();
19214 
19215 exit:
19216 	return status;
19217 }
19218 
19219 static void hdd_qdf_deinit(void)
19220 {
19221 	/* currently, no debugcb deinit */
19222 	qdf_ssr_driver_dump_deinit();
19223 	qdf_minidump_deinit();
19224 	qdf_trace_deinit();
19225 
19226 	/* currently, no trace spinlock deinit */
19227 
19228 	qdf_cpuhp_deinit();
19229 	qdf_talloc_feature_deinit();
19230 	qdf_event_list_destroy();
19231 	qdf_mc_timer_manager_exit();
19232 	qdf_wake_lock_feature_deinit();
19233 	qdf_periodic_work_feature_deinit();
19234 	qdf_delayed_work_feature_deinit();
19235 	qdf_mem_exit();
19236 	qdf_lock_stats_deinit();
19237 	qdf_debugfs_exit();
19238 	hdd_qdf_print_deinit();
19239 }
19240 
19241 #ifdef FEATURE_MONITOR_MODE_SUPPORT
19242 static bool is_monitor_mode_supported(void)
19243 {
19244 	return true;
19245 }
19246 #else
19247 static bool is_monitor_mode_supported(void)
19248 {
19249 	pr_err("Monitor mode not supported!");
19250 	return false;
19251 }
19252 #endif
19253 
19254 #ifdef WLAN_FEATURE_EPPING
19255 static bool is_epping_mode_supported(void)
19256 {
19257 	return true;
19258 }
19259 #else
19260 static bool is_epping_mode_supported(void)
19261 {
19262 	pr_err("Epping mode not supported!");
19263 	return false;
19264 }
19265 #endif
19266 
19267 #ifdef QCA_WIFI_FTM
19268 static bool is_ftm_mode_supported(void)
19269 {
19270 	return true;
19271 }
19272 #else
19273 static bool is_ftm_mode_supported(void)
19274 {
19275 	pr_err("FTM mode not supported!");
19276 	return false;
19277 }
19278 #endif
19279 
19280 /**
19281  * is_con_mode_valid() - check con mode is valid or not
19282  * @mode: global con mode
19283  *
19284  * Return: TRUE on success FALSE on failure
19285  */
19286 static bool is_con_mode_valid(enum QDF_GLOBAL_MODE mode)
19287 {
19288 	switch (mode) {
19289 	case QDF_GLOBAL_MONITOR_MODE:
19290 		return is_monitor_mode_supported();
19291 	case QDF_GLOBAL_EPPING_MODE:
19292 		return is_epping_mode_supported();
19293 	case QDF_GLOBAL_FTM_MODE:
19294 		return is_ftm_mode_supported();
19295 	case QDF_GLOBAL_MISSION_MODE:
19296 		return true;
19297 	default:
19298 		return false;
19299 	}
19300 }
19301 
19302 static void hdd_stop_present_mode(struct hdd_context *hdd_ctx,
19303 				  enum QDF_GLOBAL_MODE curr_mode)
19304 {
19305 	if (hdd_ctx->driver_status == DRIVER_MODULES_CLOSED)
19306 		return;
19307 
19308 	switch (curr_mode) {
19309 	case QDF_GLOBAL_MONITOR_MODE:
19310 		hdd_info("Release wakelock for monitor mode!");
19311 		qdf_wake_lock_release(&hdd_ctx->monitor_mode_wakelock,
19312 				      WIFI_POWER_EVENT_WAKELOCK_MONITOR_MODE);
19313 		fallthrough;
19314 	case QDF_GLOBAL_MISSION_MODE:
19315 	case QDF_GLOBAL_FTM_MODE:
19316 		hdd_abort_mac_scan_all_adapters(hdd_ctx);
19317 		wlan_cfg80211_cleanup_scan_queue(hdd_ctx->pdev, NULL);
19318 		hdd_stop_all_adapters(hdd_ctx);
19319 		hdd_deinit_all_adapters(hdd_ctx, false);
19320 
19321 		break;
19322 	default:
19323 		break;
19324 	}
19325 }
19326 
19327 static void hdd_cleanup_present_mode(struct hdd_context *hdd_ctx,
19328 				    enum QDF_GLOBAL_MODE curr_mode)
19329 {
19330 	switch (curr_mode) {
19331 	case QDF_GLOBAL_MISSION_MODE:
19332 	case QDF_GLOBAL_MONITOR_MODE:
19333 	case QDF_GLOBAL_FTM_MODE:
19334 		hdd_close_all_adapters(hdd_ctx, false);
19335 		break;
19336 	case QDF_GLOBAL_EPPING_MODE:
19337 		epping_disable();
19338 		epping_close();
19339 		break;
19340 	default:
19341 		return;
19342 	}
19343 }
19344 
19345 static int
19346 hdd_parse_driver_mode(const char *mode_str, enum QDF_GLOBAL_MODE *out_mode)
19347 {
19348 	QDF_STATUS status;
19349 	uint32_t mode;
19350 
19351 	*out_mode = QDF_GLOBAL_MAX_MODE;
19352 
19353 	status = qdf_uint32_parse(mode_str, &mode);
19354 	if (QDF_IS_STATUS_ERROR(status))
19355 		return qdf_status_to_os_return(status);
19356 
19357 	if (mode >= QDF_GLOBAL_MAX_MODE)
19358 		return -ERANGE;
19359 
19360 	*out_mode = (enum QDF_GLOBAL_MODE)mode;
19361 
19362 	return 0;
19363 }
19364 
19365 static int hdd_mode_change_psoc_idle_shutdown(struct device *dev)
19366 {
19367 	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
19368 
19369 	if (!hdd_ctx)
19370 		return -EINVAL;
19371 
19372 	return hdd_wlan_stop_modules(hdd_ctx, true);
19373 }
19374 
19375 static int hdd_mode_change_psoc_idle_restart(struct device *dev)
19376 {
19377 	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
19378 	int ret;
19379 
19380 	if (!hdd_ctx)
19381 		return -EINVAL;
19382 	ret = hdd_soc_idle_restart_lock(dev);
19383 	if (ret)
19384 		return ret;
19385 	ret = hdd_wlan_start_modules(hdd_ctx, false);
19386 	hdd_soc_idle_restart_unlock();
19387 
19388 	return ret;
19389 }
19390 
19391 /**
19392  * __hdd_driver_mode_change() - Handles a driver mode change
19393  * @hdd_ctx: Pointer to the global HDD context
19394  * @next_mode: the driver mode to transition to
19395  *
19396  * This function is invoked when user updates con_mode using sys entry,
19397  * to initialize and bring-up driver in that specific mode.
19398  *
19399  * Return: Errno
19400  */
19401 static int __hdd_driver_mode_change(struct hdd_context *hdd_ctx,
19402 				    enum QDF_GLOBAL_MODE next_mode)
19403 {
19404 	enum QDF_GLOBAL_MODE curr_mode;
19405 	int errno;
19406 	struct bbm_params param = {0};
19407 
19408 	hdd_info("Driver mode changing to %d", next_mode);
19409 
19410 	errno = wlan_hdd_validate_context(hdd_ctx);
19411 	if (errno)
19412 		return errno;
19413 
19414 	if (!is_con_mode_valid(next_mode)) {
19415 		hdd_err_rl("Requested driver mode is invalid");
19416 		return -EINVAL;
19417 	}
19418 
19419 	curr_mode = hdd_get_conparam();
19420 	if (curr_mode == next_mode) {
19421 		hdd_err_rl("Driver is already in the requested mode");
19422 		return 0;
19423 	}
19424 
19425 	hdd_psoc_idle_timer_stop(hdd_ctx);
19426 
19427 	/* ensure adapters are stopped */
19428 	hdd_stop_present_mode(hdd_ctx, curr_mode);
19429 
19430 	if (DRIVER_MODULES_CLOSED != hdd_ctx->driver_status) {
19431 		is_mode_change_psoc_idle_shutdown = true;
19432 		errno = pld_idle_shutdown(hdd_ctx->parent_dev,
19433 					  hdd_mode_change_psoc_idle_shutdown);
19434 		if (errno) {
19435 			is_mode_change_psoc_idle_shutdown = false;
19436 			hdd_err("Stop wlan modules failed");
19437 			return errno;
19438 		}
19439 	}
19440 
19441 	/* Cleanup present mode before switching to new mode */
19442 	hdd_cleanup_present_mode(hdd_ctx, curr_mode);
19443 
19444 	hdd_set_conparam(next_mode);
19445 	pld_set_mode(next_mode);
19446 
19447 	qdf_event_reset(&hdd_ctx->regulatory_update_event);
19448 	qdf_mutex_acquire(&hdd_ctx->regulatory_status_lock);
19449 	hdd_ctx->is_regulatory_update_in_progress = true;
19450 	qdf_mutex_release(&hdd_ctx->regulatory_status_lock);
19451 
19452 	errno = pld_idle_restart(hdd_ctx->parent_dev,
19453 				 hdd_mode_change_psoc_idle_restart);
19454 	if (errno) {
19455 		hdd_err("Start wlan modules failed: %d", errno);
19456 		return errno;
19457 	}
19458 
19459 	errno = hdd_open_adapters_for_mode(hdd_ctx, next_mode);
19460 	if (errno) {
19461 		hdd_err("Failed to open adapters");
19462 		return errno;
19463 	}
19464 
19465 	if (next_mode == QDF_GLOBAL_MONITOR_MODE) {
19466 		struct hdd_adapter *adapter =
19467 			hdd_get_adapter(hdd_ctx, QDF_MONITOR_MODE);
19468 
19469 		QDF_BUG(adapter);
19470 		if (!adapter) {
19471 			hdd_err("Failed to get monitor adapter");
19472 			return -EINVAL;
19473 		}
19474 
19475 		errno = hdd_start_adapter(adapter, false);
19476 		if (errno) {
19477 			hdd_err("Failed to start monitor adapter");
19478 			return errno;
19479 		}
19480 
19481 		hdd_info("Acquire wakelock for monitor mode");
19482 		qdf_wake_lock_acquire(&hdd_ctx->monitor_mode_wakelock,
19483 				      WIFI_POWER_EVENT_WAKELOCK_MONITOR_MODE);
19484 	}
19485 
19486 	/* con_mode is a global module parameter */
19487 	con_mode = next_mode;
19488 	hdd_info("Driver mode successfully changed to %d", next_mode);
19489 
19490 	param.policy = BBM_DRIVER_MODE_POLICY;
19491 	param.policy_info.driver_mode = con_mode;
19492 	ucfg_dp_bbm_apply_independent_policy(hdd_ctx->psoc, &param);
19493 
19494 	return 0;
19495 }
19496 
19497 static int hdd_driver_mode_change(enum QDF_GLOBAL_MODE mode)
19498 {
19499 	struct osif_driver_sync *driver_sync;
19500 	struct hdd_context *hdd_ctx;
19501 	QDF_STATUS status;
19502 	int errno;
19503 
19504 	hdd_enter();
19505 
19506 	status = osif_driver_sync_trans_start_wait(&driver_sync);
19507 	if (QDF_IS_STATUS_ERROR(status)) {
19508 		hdd_err("Failed to start 'mode change'; status:%u", status);
19509 		errno = qdf_status_to_os_return(status);
19510 		goto exit;
19511 	}
19512 
19513 	osif_driver_sync_wait_for_ops(driver_sync);
19514 
19515 	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
19516 	errno = wlan_hdd_validate_context(hdd_ctx);
19517 	if (errno)
19518 		goto trans_stop;
19519 
19520 	errno = __hdd_driver_mode_change(hdd_ctx, mode);
19521 
19522 trans_stop:
19523 	osif_driver_sync_trans_stop(driver_sync);
19524 
19525 exit:
19526 	hdd_exit();
19527 
19528 	return errno;
19529 }
19530 
19531 static int hdd_set_con_mode(enum QDF_GLOBAL_MODE mode)
19532 {
19533 	con_mode = mode;
19534 
19535 	return 0;
19536 }
19537 
19538 static int (*hdd_set_con_mode_cb)(enum QDF_GLOBAL_MODE mode) = hdd_set_con_mode;
19539 
19540 static void hdd_driver_mode_change_register(void)
19541 {
19542 	hdd_set_con_mode_cb = hdd_driver_mode_change;
19543 }
19544 
19545 static void hdd_driver_mode_change_unregister(void)
19546 {
19547 	hdd_set_con_mode_cb = hdd_set_con_mode;
19548 }
19549 
19550 static int con_mode_handler(const char *kmessage, const struct kernel_param *kp)
19551 {
19552 	enum QDF_GLOBAL_MODE mode;
19553 	int errno;
19554 
19555 	errno = hdd_parse_driver_mode(kmessage, &mode);
19556 	if (errno) {
19557 		hdd_err_rl("Failed to parse driver mode '%s'", kmessage);
19558 		return errno;
19559 	}
19560 
19561 	return hdd_set_con_mode_cb(mode);
19562 }
19563 
19564 /*
19565  * If the wlan_hdd_register_driver will return an error
19566  * if the wlan driver tries to register with the
19567  * platform driver before cnss_probe is completed.
19568  * Depending on the error code, the wlan driver waits
19569  * and retries to register.
19570  */
19571 
19572 /* Max number of retries (arbitrary)*/
19573 #define HDD_MAX_PLD_REGISTER_RETRY (50)
19574 
19575 /* Max amount of time we sleep before each retry */
19576 #define HDD_PLD_REGISTER_FAIL_SLEEP_DURATION (100)
19577 
19578 static int hdd_register_driver_retry(void)
19579 {
19580 	int count = 0;
19581 	int errno;
19582 
19583 	while (true) {
19584 		errno = wlan_hdd_register_driver();
19585 		if (errno != -EAGAIN)
19586 			return errno;
19587 		hdd_nofl_info("Retry Platform Driver Registration; errno:%d count:%d",
19588 			      errno, count);
19589 		if (++count == HDD_MAX_PLD_REGISTER_RETRY)
19590 			return errno;
19591 		msleep(HDD_PLD_REGISTER_FAIL_SLEEP_DURATION);
19592 		continue;
19593 	}
19594 
19595 	return errno;
19596 }
19597 
19598 /**
19599  * hdd_create_wifi_feature_interface() - Create wifi feature interface
19600  *
19601  * Return: none
19602  */
19603 static void hdd_create_wifi_feature_interface(void)
19604 {
19605 	hdd_sysfs_create_wifi_root_obj();
19606 	hdd_create_wifi_feature_interface_sysfs_file();
19607 }
19608 
19609 int hdd_driver_load(void)
19610 {
19611 	struct osif_driver_sync *driver_sync;
19612 	QDF_STATUS status;
19613 	int errno;
19614 	bool soft_load;
19615 
19616 	pr_info("%s: Loading driver v%s\n", WLAN_MODULE_NAME,
19617 		g_wlan_driver_version);
19618 	hdd_place_marker(NULL, "START LOADING", NULL);
19619 
19620 	status = hdd_qdf_init();
19621 	if (QDF_IS_STATUS_ERROR(status)) {
19622 		errno = qdf_status_to_os_return(status);
19623 		goto exit;
19624 	}
19625 
19626 	osif_sync_init();
19627 
19628 	status = osif_driver_sync_create_and_trans(&driver_sync);
19629 	if (QDF_IS_STATUS_ERROR(status)) {
19630 		hdd_err("Failed to init driver sync; status:%u", status);
19631 		errno = qdf_status_to_os_return(status);
19632 		goto sync_deinit;
19633 	}
19634 
19635 	errno = hdd_init();
19636 	if (errno) {
19637 		hdd_err("Failed to init HDD; errno:%d", errno);
19638 		goto trans_stop;
19639 	}
19640 
19641 	status = hdd_component_cb_init();
19642 	if (QDF_IS_STATUS_ERROR(status)) {
19643 		hdd_err("Failed to init component cb; status:%u", status);
19644 		errno = qdf_status_to_os_return(status);
19645 		goto hdd_deinit;
19646 	}
19647 
19648 	status = hdd_component_init();
19649 	if (QDF_IS_STATUS_ERROR(status)) {
19650 		hdd_err("Failed to init components; status:%u", status);
19651 		errno = qdf_status_to_os_return(status);
19652 		goto comp_cb_deinit;
19653 	}
19654 
19655 	status = qdf_wake_lock_create(&wlan_wake_lock, "wlan");
19656 	if (QDF_IS_STATUS_ERROR(status)) {
19657 		hdd_err("Failed to create wake lock; status:%u", status);
19658 		errno = qdf_status_to_os_return(status);
19659 		goto comp_deinit;
19660 	}
19661 
19662 	hdd_set_conparam(con_mode);
19663 
19664 	errno = pld_init();
19665 	if (errno) {
19666 		hdd_err("Failed to init PLD; errno:%d", errno);
19667 		goto wakelock_destroy;
19668 	}
19669 
19670 	/* driver mode pass to cnss2 platform driver*/
19671 	errno = pld_set_mode(con_mode);
19672 	if (errno)
19673 		hdd_err("Failed to set mode in PLD; errno:%d", errno);
19674 
19675 	hdd_driver_mode_change_register();
19676 
19677 	osif_driver_sync_register(driver_sync);
19678 	osif_driver_sync_trans_stop(driver_sync);
19679 
19680 	/* psoc probe can happen in registration; do after 'load' transition */
19681 	errno = hdd_register_driver_retry();
19682 	if (errno) {
19683 		hdd_err("Failed to register driver; errno:%d", errno);
19684 		goto pld_deinit;
19685 	}
19686 
19687 	/* If a soft unload of driver is done, we don't call
19688 	 * wlan_hdd_state_ctrl_param_destroy() to maintain sync
19689 	 * with userspace. In Symmetry, during soft load, avoid
19690 	 * calling wlan_hdd_state_ctrl_param_create().
19691 	 */
19692 	soft_load = hdd_get_wlan_driver_status();
19693 	if (soft_load)
19694 		goto out;
19695 
19696 	errno = wlan_hdd_state_ctrl_param_create();
19697 	if (errno) {
19698 		hdd_err("Failed to create ctrl param; errno:%d", errno);
19699 		goto unregister_driver;
19700 	}
19701 	hdd_create_wifi_feature_interface();
19702 out:
19703 	hdd_debug("%s: driver loaded", WLAN_MODULE_NAME);
19704 	hdd_place_marker(NULL, "DRIVER LOADED", NULL);
19705 
19706 	return 0;
19707 
19708 unregister_driver:
19709 	wlan_hdd_unregister_driver();
19710 pld_deinit:
19711 	status = osif_driver_sync_trans_start(&driver_sync);
19712 	QDF_BUG(QDF_IS_STATUS_SUCCESS(status));
19713 
19714 	osif_driver_sync_unregister();
19715 	if (driver_sync)
19716 		osif_driver_sync_wait_for_ops(driver_sync);
19717 
19718 	hdd_driver_mode_change_unregister();
19719 	pld_deinit();
19720 
19721 	hdd_start_complete(errno);
19722 	/* Wait for any ref taken on /dev/wlan to be released */
19723 	while (qdf_atomic_read(&wlan_hdd_state_fops_ref))
19724 		;
19725 wakelock_destroy:
19726 	qdf_wake_lock_destroy(&wlan_wake_lock);
19727 comp_deinit:
19728 	hdd_component_deinit();
19729 comp_cb_deinit:
19730 	hdd_component_cb_deinit();
19731 hdd_deinit:
19732 	hdd_deinit();
19733 trans_stop:
19734 	if (driver_sync) {
19735 		osif_driver_sync_trans_stop(driver_sync);
19736 		osif_driver_sync_destroy(driver_sync);
19737 	}
19738 sync_deinit:
19739 	osif_sync_deinit();
19740 	hdd_qdf_deinit();
19741 
19742 exit:
19743 	return errno;
19744 }
19745 
19746 #ifdef FEATURE_WLAN_RESIDENT_DRIVER
19747 EXPORT_SYMBOL(hdd_driver_load);
19748 #endif
19749 
19750 /**
19751  * hdd_distroy_wifi_feature_interface() - Distroy wifi feature interface
19752  *
19753  * Return: none
19754  */
19755 static void hdd_distroy_wifi_feature_interface(void)
19756 {
19757 	hdd_destroy_wifi_feature_interface_sysfs_file();
19758 	hdd_sysfs_destroy_wifi_root_obj();
19759 }
19760 
19761 void hdd_driver_unload(void)
19762 {
19763 	struct osif_driver_sync *driver_sync;
19764 	struct hdd_context *hdd_ctx;
19765 	QDF_STATUS status;
19766 	void *hif_ctx;
19767 	bool soft_unload;
19768 
19769 	soft_unload = hdd_get_wlan_driver_status();
19770 	if (soft_unload) {
19771 		pr_info("%s: Soft Unloading driver v%s\n", WLAN_MODULE_NAME,
19772 			QWLAN_VERSIONSTR);
19773 	} else {
19774 		pr_info("%s: Hard Unloading driver v%s\n", WLAN_MODULE_NAME,
19775 			QWLAN_VERSIONSTR);
19776 	}
19777 
19778 	hdd_place_marker(NULL, "START UNLOADING", NULL);
19779 
19780 	/*
19781 	 * Wait for any trans to complete and then start the driver trans
19782 	 * for the unload. This will ensure that the driver trans proceeds only
19783 	 * after all trans have been completed. As a part of this trans, set
19784 	 * the driver load/unload flag to further ensure that any upcoming
19785 	 * trans are rejected via wlan_hdd_validate_context.
19786 	 */
19787 	status = osif_driver_sync_trans_start_wait(&driver_sync);
19788 	QDF_BUG(QDF_IS_STATUS_SUCCESS(status));
19789 	if (QDF_IS_STATUS_ERROR(status)) {
19790 		hdd_err("Unable to unload wlan; status:%u", status);
19791 		hdd_place_marker(NULL, "UNLOAD FAILURE", NULL);
19792 		return;
19793 	}
19794 
19795 	hif_ctx = cds_get_context(QDF_MODULE_ID_HIF);
19796 	if (hif_ctx) {
19797 		/*
19798 		 * Trigger runtime sync resume before setting unload in progress
19799 		 * such that resume can happen successfully
19800 		 */
19801 		qdf_rtpm_sync_resume();
19802 	}
19803 
19804 	cds_set_driver_loaded(false);
19805 	cds_set_unload_in_progress(true);
19806 
19807 	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
19808 	if (hdd_ctx) {
19809 		hdd_psoc_idle_timer_stop(hdd_ctx);
19810 		/*
19811 		 * Runtime PM sync resume may have started the bus bandwidth
19812 		 * periodic work hence stop it.
19813 		 */
19814 		ucfg_dp_bus_bw_compute_timer_stop(hdd_ctx->psoc);
19815 	}
19816 
19817 	/*
19818 	 * Stop the trans before calling unregister_driver as that involves a
19819 	 * call to pld_remove which in itself is a psoc transaction
19820 	 */
19821 	osif_driver_sync_trans_stop(driver_sync);
19822 
19823 	hdd_distroy_wifi_feature_interface();
19824 	if (!soft_unload)
19825 		wlan_hdd_state_ctrl_param_destroy();
19826 
19827 	/* trigger SoC remove */
19828 	wlan_hdd_unregister_driver();
19829 
19830 	status = osif_driver_sync_trans_start_wait(&driver_sync);
19831 	QDF_BUG(QDF_IS_STATUS_SUCCESS(status));
19832 	if (QDF_IS_STATUS_ERROR(status)) {
19833 		hdd_err("Unable to unload wlan; status:%u", status);
19834 		hdd_place_marker(NULL, "UNLOAD FAILURE", NULL);
19835 		return;
19836 	}
19837 
19838 	osif_driver_sync_unregister();
19839 	osif_driver_sync_wait_for_ops(driver_sync);
19840 
19841 	hdd_driver_mode_change_unregister();
19842 	pld_deinit();
19843 	hdd_set_conparam(0);
19844 	qdf_wake_lock_destroy(&wlan_wake_lock);
19845 	hdd_component_deinit();
19846 	hdd_component_cb_deinit();
19847 	hdd_deinit();
19848 
19849 	osif_driver_sync_trans_stop(driver_sync);
19850 	osif_driver_sync_destroy(driver_sync);
19851 
19852 	osif_sync_deinit();
19853 
19854 	hdd_qdf_deinit();
19855 	hdd_place_marker(NULL, "UNLOAD DONE", NULL);
19856 }
19857 
19858 #ifdef FEATURE_WLAN_RESIDENT_DRIVER
19859 EXPORT_SYMBOL(hdd_driver_unload);
19860 #endif
19861 
19862 #ifndef MODULE
19863 /**
19864  * wlan_boot_cb() - Wlan boot callback
19865  * @kobj:      object whose directory we're creating the link in.
19866  * @attr:      attribute the user is interacting with
19867  * @buf:       the buffer containing the user data
19868  * @count:     number of bytes in the buffer
19869  *
19870  * This callback is invoked when the fs is ready to start the
19871  * wlan driver initialization.
19872  *
19873  * Return: 'count' on success or a negative error code in case of failure
19874  */
19875 static ssize_t wlan_boot_cb(struct kobject *kobj,
19876 			    struct kobj_attribute *attr,
19877 			    const char *buf,
19878 			    size_t count)
19879 {
19880 
19881 	if (wlan_loader->loaded_state) {
19882 		hdd_err("wlan driver already initialized");
19883 		return -EALREADY;
19884 	}
19885 
19886 	if (hdd_driver_load())
19887 		return -EIO;
19888 
19889 	wlan_loader->loaded_state = MODULE_INITIALIZED;
19890 
19891 	return count;
19892 }
19893 
19894 /**
19895  * hdd_sysfs_cleanup() - cleanup sysfs
19896  *
19897  * Return: None
19898  *
19899  */
19900 static void hdd_sysfs_cleanup(void)
19901 {
19902 	/* remove from group */
19903 	if (wlan_loader->boot_wlan_obj && wlan_loader->attr_group)
19904 		sysfs_remove_group(wlan_loader->boot_wlan_obj,
19905 				   wlan_loader->attr_group);
19906 
19907 	/* unlink the object from parent */
19908 	kobject_del(wlan_loader->boot_wlan_obj);
19909 
19910 	/* free the object */
19911 	kobject_put(wlan_loader->boot_wlan_obj);
19912 
19913 	kfree(wlan_loader->attr_group);
19914 	kfree(wlan_loader);
19915 
19916 	wlan_loader = NULL;
19917 }
19918 
19919 /**
19920  * wlan_init_sysfs() - Creates the sysfs to be invoked when the fs is
19921  * ready
19922  *
19923  * This is creates the syfs entry boot_wlan. Which shall be invoked
19924  * when the filesystem is ready.
19925  *
19926  * QDF API cannot be used here since this function is called even before
19927  * initializing WLAN driver.
19928  *
19929  * Return: 0 for success, errno on failure
19930  */
19931 static int wlan_init_sysfs(void)
19932 {
19933 	int ret = -ENOMEM;
19934 
19935 	wlan_loader = kzalloc(sizeof(*wlan_loader), GFP_KERNEL);
19936 	if (!wlan_loader)
19937 		return -ENOMEM;
19938 
19939 	wlan_loader->boot_wlan_obj = NULL;
19940 	wlan_loader->attr_group = kzalloc(sizeof(*(wlan_loader->attr_group)),
19941 					  GFP_KERNEL);
19942 	if (!wlan_loader->attr_group)
19943 		goto error_return;
19944 
19945 	wlan_loader->loaded_state = 0;
19946 	wlan_loader->attr_group->attrs = attrs;
19947 
19948 	wlan_loader->boot_wlan_obj = kobject_create_and_add(WLAN_LOADER_NAME,
19949 							    kernel_kobj);
19950 	if (!wlan_loader->boot_wlan_obj) {
19951 		hdd_err("sysfs create and add failed");
19952 		goto error_return;
19953 	}
19954 
19955 	ret = sysfs_create_group(wlan_loader->boot_wlan_obj,
19956 				 wlan_loader->attr_group);
19957 	if (ret) {
19958 		hdd_err("sysfs create group failed; errno:%d", ret);
19959 		goto error_return;
19960 	}
19961 
19962 	return 0;
19963 
19964 error_return:
19965 	hdd_sysfs_cleanup();
19966 
19967 	return ret;
19968 }
19969 
19970 /**
19971  * wlan_deinit_sysfs() - Removes the sysfs created to initialize the wlan
19972  *
19973  * Return: 0 on success or errno on failure
19974  */
19975 static int wlan_deinit_sysfs(void)
19976 {
19977 	if (!wlan_loader) {
19978 		hdd_err("wlan_loader is null");
19979 		return -EINVAL;
19980 	}
19981 
19982 	hdd_sysfs_cleanup();
19983 	return 0;
19984 }
19985 
19986 #endif /* MODULE */
19987 
19988 #ifdef MODULE
19989 /**
19990  * hdd_module_init() - Module init helper
19991  *
19992  * Module init helper function used by both module and static driver.
19993  *
19994  * Return: 0 for success, errno on failure
19995  */
19996 #ifdef FEATURE_WLAN_RESIDENT_DRIVER
19997 static int hdd_module_init(void)
19998 {
19999 	return 0;
20000 }
20001 #else
20002 static int hdd_module_init(void)
20003 {
20004 	if (hdd_driver_load())
20005 		return -EINVAL;
20006 
20007 	return 0;
20008 }
20009 #endif
20010 #else
20011 static int __init hdd_module_init(void)
20012 {
20013 	int ret = -EINVAL;
20014 
20015 	ret = wlan_init_sysfs();
20016 	if (ret)
20017 		hdd_err("Failed to create sysfs entry");
20018 
20019 	return ret;
20020 }
20021 #endif
20022 
20023 
20024 #ifdef MODULE
20025 /**
20026  * hdd_module_exit() - Exit function
20027  *
20028  * This is the driver exit point (invoked when module is unloaded using rmmod)
20029  *
20030  * Return: None
20031  */
20032 #ifdef FEATURE_WLAN_RESIDENT_DRIVER
20033 static void __exit hdd_module_exit(void)
20034 {
20035 }
20036 #else
20037 static void __exit hdd_module_exit(void)
20038 {
20039 	hdd_driver_unload();
20040 }
20041 #endif
20042 #else
20043 static void __exit hdd_module_exit(void)
20044 {
20045 	hdd_driver_unload();
20046 	wlan_deinit_sysfs();
20047 }
20048 #endif
20049 
20050 static int fwpath_changed_handler(const char *kmessage,
20051 				  const struct kernel_param *kp)
20052 {
20053 	return param_set_copystring(kmessage, kp);
20054 }
20055 
20056 static int con_mode_handler_ftm(const char *kmessage,
20057 				const struct kernel_param *kp)
20058 {
20059 	int ret;
20060 
20061 	ret = param_set_int(kmessage, kp);
20062 
20063 	if (cds_is_driver_loaded() || cds_is_load_or_unload_in_progress()) {
20064 		pr_err("Driver already loaded or load/unload in progress");
20065 		return -ENOTSUPP;
20066 	}
20067 
20068 	if (con_mode_ftm != QDF_GLOBAL_FTM_MODE) {
20069 		pr_err("Only FTM mode supported!");
20070 		return -ENOTSUPP;
20071 	}
20072 
20073 	hdd_set_conparam(con_mode_ftm);
20074 	con_mode = con_mode_ftm;
20075 
20076 	return ret;
20077 }
20078 
20079 #ifdef WLAN_FEATURE_EPPING
20080 static int con_mode_handler_epping(const char *kmessage,
20081 				   const struct kernel_param *kp)
20082 {
20083 	int ret;
20084 
20085 	ret = param_set_int(kmessage, kp);
20086 
20087 	if (con_mode_epping != QDF_GLOBAL_EPPING_MODE) {
20088 		pr_err("Only EPPING mode supported!");
20089 		return -ENOTSUPP;
20090 	}
20091 
20092 	hdd_set_conparam(con_mode_epping);
20093 	con_mode = con_mode_epping;
20094 
20095 	return ret;
20096 }
20097 #endif
20098 
20099 /**
20100  * hdd_get_conparam() - driver exit point
20101  *
20102  * This is the driver exit point (invoked when module is unloaded using rmmod)
20103  *
20104  * Return: enum QDF_GLOBAL_MODE
20105  */
20106 enum QDF_GLOBAL_MODE hdd_get_conparam(void)
20107 {
20108 	return (enum QDF_GLOBAL_MODE) curr_con_mode;
20109 }
20110 
20111 void hdd_set_conparam(int32_t con_param)
20112 {
20113 	curr_con_mode = con_param;
20114 }
20115 
20116 /**
20117  * hdd_svc_fw_crashed_ind() - API to send FW CRASHED IND to Userspace
20118  *
20119  * Return: void
20120  */
20121 static void hdd_svc_fw_crashed_ind(void)
20122 {
20123 	struct hdd_context *hdd_ctx;
20124 
20125 	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
20126 
20127 	hdd_ctx ? wlan_hdd_send_svc_nlink_msg(hdd_ctx->radio_index,
20128 					      WLAN_SVC_FW_CRASHED_IND,
20129 					      NULL, 0) : 0;
20130 }
20131 
20132 /**
20133  * hdd_update_ol_config - API to update ol configuration parameters
20134  * @hdd_ctx: HDD context
20135  *
20136  * Return: void
20137  */
20138 static void hdd_update_ol_config(struct hdd_context *hdd_ctx)
20139 {
20140 	struct ol_config_info cfg = {0};
20141 	struct ol_context *ol_ctx = cds_get_context(QDF_MODULE_ID_BMI);
20142 	bool self_recovery = false;
20143 	QDF_STATUS status;
20144 
20145 	if (!ol_ctx)
20146 		return;
20147 
20148 	status = ucfg_mlme_get_self_recovery(hdd_ctx->psoc, &self_recovery);
20149 	if (QDF_IS_STATUS_ERROR(status))
20150 		hdd_err("Failed to get self recovery ini config");
20151 
20152 	cfg.enable_self_recovery = self_recovery;
20153 	cfg.enable_uart_print = hdd_ctx->config->enablefwprint;
20154 	cfg.enable_fw_log = hdd_ctx->config->enable_fw_log;
20155 	cfg.enable_ramdump_collection = hdd_ctx->config->is_ramdump_enabled;
20156 	cfg.enable_lpass_support = hdd_lpass_is_supported(hdd_ctx);
20157 
20158 	ol_init_ini_config(ol_ctx, &cfg);
20159 	ol_set_fw_crashed_cb(ol_ctx, hdd_svc_fw_crashed_ind);
20160 }
20161 
20162 #ifdef FEATURE_RUNTIME_PM
20163 /**
20164  * hdd_populate_runtime_cfg() - populate runtime configuration
20165  * @hdd_ctx: hdd context
20166  * @cfg: pointer to the configuration memory being populated
20167  *
20168  * Return: void
20169  */
20170 static void hdd_populate_runtime_cfg(struct hdd_context *hdd_ctx,
20171 				     struct hif_config_info *cfg)
20172 {
20173 	cfg->enable_runtime_pm = hdd_ctx->config->runtime_pm;
20174 	cfg->runtime_pm_delay =
20175 		ucfg_pmo_get_runtime_pm_delay(hdd_ctx->psoc);
20176 }
20177 #else
20178 static void hdd_populate_runtime_cfg(struct hdd_context *hdd_ctx,
20179 				     struct hif_config_info *cfg)
20180 {
20181 }
20182 #endif
20183 
20184 /**
20185  * hdd_update_hif_config - API to update HIF configuration parameters
20186  * @hdd_ctx: HDD Context
20187  *
20188  * Return: void
20189  */
20190 static void hdd_update_hif_config(struct hdd_context *hdd_ctx)
20191 {
20192 	struct hif_opaque_softc *scn = cds_get_context(QDF_MODULE_ID_HIF);
20193 	struct hif_config_info cfg = {0};
20194 	bool prevent_link_down = false;
20195 	bool self_recovery = false;
20196 	QDF_STATUS status;
20197 
20198 	if (!scn)
20199 		return;
20200 
20201 	status = ucfg_mlme_get_prevent_link_down(hdd_ctx->psoc,
20202 						 &prevent_link_down);
20203 	if (QDF_IS_STATUS_ERROR(status))
20204 		hdd_err("Failed to get prevent_link_down config");
20205 
20206 	status = ucfg_mlme_get_self_recovery(hdd_ctx->psoc, &self_recovery);
20207 	if (QDF_IS_STATUS_ERROR(status))
20208 		hdd_err("Failed to get self recovery ini config");
20209 
20210 	cfg.enable_self_recovery = self_recovery;
20211 	hdd_populate_runtime_cfg(hdd_ctx, &cfg);
20212 	cfg.rx_softirq_max_yield_duration_ns =
20213 		ucfg_dp_get_rx_softirq_yield_duration(hdd_ctx->psoc);
20214 
20215 	hif_init_ini_config(scn, &cfg);
20216 
20217 	if (prevent_link_down)
20218 		hif_vote_link_up(scn);
20219 }
20220 
20221 /**
20222  * hdd_update_dp_config() - Propagate config parameters to Lithium
20223  *                          datapath
20224  * @hdd_ctx: HDD Context
20225  *
20226  * Return: 0 for success/errno for failure
20227  */
20228 static int hdd_update_dp_config(struct hdd_context *hdd_ctx)
20229 {
20230 	struct wlan_dp_user_config dp_cfg;
20231 	QDF_STATUS status;
20232 
20233 	dp_cfg.ipa_enable = ucfg_ipa_is_enabled();
20234 	dp_cfg.arp_connectivity_map = CONNECTIVITY_CHECK_SET_ARP;
20235 
20236 	status = ucfg_dp_update_config(hdd_ctx->psoc, &dp_cfg);
20237 	if (status != QDF_STATUS_SUCCESS) {
20238 		hdd_err("failed DP PSOC configuration update");
20239 		return -EINVAL;
20240 	}
20241 
20242 	return 0;
20243 }
20244 
20245 /**
20246  * hdd_update_config() - Initialize driver per module ini parameters
20247  * @hdd_ctx: HDD Context
20248  *
20249  * API is used to initialize all driver per module configuration parameters
20250  * Return: 0 for success, errno for failure
20251  */
20252 int hdd_update_config(struct hdd_context *hdd_ctx)
20253 {
20254 	int ret;
20255 
20256 	if (ucfg_pmo_is_ns_offloaded(hdd_ctx->psoc))
20257 		hdd_ctx->ns_offload_enable = true;
20258 
20259 	hdd_update_ol_config(hdd_ctx);
20260 	hdd_update_hif_config(hdd_ctx);
20261 	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam())
20262 		ret = hdd_update_cds_config_ftm(hdd_ctx);
20263 	else
20264 		ret = hdd_update_cds_config(hdd_ctx);
20265 	ret = hdd_update_user_config(hdd_ctx);
20266 
20267 	hdd_update_regdb_offload_config(hdd_ctx);
20268 
20269 	return ret;
20270 }
20271 
20272 /**
20273  * hdd_update_pmo_config - API to update pmo configuration parameters
20274  * @hdd_ctx: HDD context
20275  *
20276  * Return: void
20277  */
20278 static int hdd_update_pmo_config(struct hdd_context *hdd_ctx)
20279 {
20280 	struct pmo_psoc_cfg psoc_cfg = {0};
20281 	QDF_STATUS status;
20282 	enum pmo_wow_enable_type wow_enable;
20283 
20284 	ucfg_pmo_get_psoc_config(hdd_ctx->psoc, &psoc_cfg);
20285 
20286 	/*
20287 	 * Value of hdd_ctx->wowEnable can be,
20288 	 * 0 - Disable both magic pattern match and pattern byte match.
20289 	 * 1 - Enable magic pattern match on all interfaces.
20290 	 * 2 - Enable pattern byte match on all interfaces.
20291 	 * 3 - Enable both magic pattern and pattern byte match on
20292 	 *     all interfaces.
20293 	 */
20294 	wow_enable = ucfg_pmo_get_wow_enable(hdd_ctx->psoc);
20295 	psoc_cfg.magic_ptrn_enable = (wow_enable & 0x01) ? true : false;
20296 	psoc_cfg.ptrn_match_enable_all_vdev =
20297 				(wow_enable & 0x02) ? true : false;
20298 	psoc_cfg.ap_arpns_support = hdd_ctx->ap_arpns_support;
20299 	psoc_cfg.d0_wow_supported = wma_d0_wow_is_supported();
20300 	ucfg_mlme_get_sap_max_modulated_dtim(hdd_ctx->psoc,
20301 					     &psoc_cfg.sta_max_li_mod_dtim);
20302 
20303 	hdd_lpass_populate_pmo_config(&psoc_cfg, hdd_ctx);
20304 
20305 	status = ucfg_pmo_update_psoc_config(hdd_ctx->psoc, &psoc_cfg);
20306 	if (QDF_IS_STATUS_ERROR(status))
20307 		hdd_err("failed pmo psoc configuration; status:%d", status);
20308 
20309 	return qdf_status_to_os_return(status);
20310 }
20311 
20312 void hdd_update_ie_allowlist_attr(struct probe_req_allowlist_attr *ie_allowlist,
20313 				  struct hdd_context *hdd_ctx)
20314 {
20315 	struct wlan_fwol_ie_allowlist allowlist = {0};
20316 	struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc;
20317 	QDF_STATUS status;
20318 	bool is_ie_allowlist_enable = false;
20319 	uint8_t i = 0;
20320 
20321 	status = ucfg_fwol_get_ie_allowlist(psoc, &is_ie_allowlist_enable);
20322 	if (QDF_IS_STATUS_ERROR(status)) {
20323 		hdd_err("Unable to get IE allowlist param");
20324 		return;
20325 	}
20326 
20327 	ie_allowlist->allow_list = is_ie_allowlist_enable;
20328 	if (!ie_allowlist->allow_list)
20329 		return;
20330 
20331 	status = ucfg_fwol_get_all_allowlist_params(psoc, &allowlist);
20332 	if (QDF_IS_STATUS_ERROR(status)) {
20333 		hdd_err("Unable to get all allowlist params");
20334 		return;
20335 	}
20336 
20337 	ie_allowlist->ie_bitmap[0] = allowlist.ie_bitmap_0;
20338 	ie_allowlist->ie_bitmap[1] = allowlist.ie_bitmap_1;
20339 	ie_allowlist->ie_bitmap[2] = allowlist.ie_bitmap_2;
20340 	ie_allowlist->ie_bitmap[3] = allowlist.ie_bitmap_3;
20341 	ie_allowlist->ie_bitmap[4] = allowlist.ie_bitmap_4;
20342 	ie_allowlist->ie_bitmap[5] = allowlist.ie_bitmap_5;
20343 	ie_allowlist->ie_bitmap[6] = allowlist.ie_bitmap_6;
20344 	ie_allowlist->ie_bitmap[7] = allowlist.ie_bitmap_7;
20345 
20346 	ie_allowlist->num_vendor_oui = allowlist.no_of_probe_req_ouis;
20347 	for (i = 0; i < ie_allowlist->num_vendor_oui; i++)
20348 		ie_allowlist->voui[i] = allowlist.probe_req_voui[i];
20349 }
20350 
20351 QDF_STATUS hdd_update_score_config(struct hdd_context *hdd_ctx)
20352 {
20353 	struct hdd_config *cfg = hdd_ctx->config;
20354 	eCsrPhyMode phy_mode = hdd_cfg_xlate_to_csr_phy_mode(cfg->dot11Mode);
20355 
20356 	sme_update_score_config(hdd_ctx->mac_handle, phy_mode,
20357 				hdd_ctx->num_rf_chains);
20358 
20359 	return QDF_STATUS_SUCCESS;
20360 }
20361 
20362 /**
20363  * hdd_update_dfs_config() - API to update dfs configuration parameters.
20364  * @hdd_ctx: HDD context
20365  *
20366  * Return: 0 if success else err
20367  */
20368 static int hdd_update_dfs_config(struct hdd_context *hdd_ctx)
20369 {
20370 	struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc;
20371 	struct dfs_user_config dfs_cfg = {0};
20372 	QDF_STATUS status;
20373 
20374 	ucfg_mlme_get_dfs_filter_offload(hdd_ctx->psoc,
20375 					 &dfs_cfg.dfs_is_phyerr_filter_offload);
20376 	status = ucfg_dfs_update_config(psoc, &dfs_cfg);
20377 	if (QDF_IS_STATUS_ERROR(status)) {
20378 		hdd_err("failed dfs psoc configuration");
20379 		return -EINVAL;
20380 	}
20381 
20382 	return 0;
20383 }
20384 
20385 /**
20386  * hdd_update_scan_config - API to update scan configuration parameters
20387  * @hdd_ctx: HDD context
20388  *
20389  * Return: 0 if success else err
20390  */
20391 int hdd_update_scan_config(struct hdd_context *hdd_ctx)
20392 {
20393 	struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc;
20394 	struct scan_user_cfg scan_cfg;
20395 	QDF_STATUS status;
20396 	uint32_t mcast_mcc_rest_time = 0;
20397 
20398 	qdf_mem_zero(&scan_cfg, sizeof(scan_cfg));
20399 	status = ucfg_mlme_get_sta_miracast_mcc_rest_time(hdd_ctx->psoc,
20400 							  &mcast_mcc_rest_time);
20401 	if (!QDF_IS_STATUS_SUCCESS(status)) {
20402 		hdd_err("ucfg_mlme_get_sta_miracast_mcc_rest_time, use def");
20403 		return -EIO;
20404 	}
20405 	scan_cfg.sta_miracast_mcc_rest_time = mcast_mcc_rest_time;
20406 	hdd_update_ie_allowlist_attr(&scan_cfg.ie_allowlist, hdd_ctx);
20407 
20408 	status = ucfg_scan_update_user_config(psoc, &scan_cfg);
20409 	if (status != QDF_STATUS_SUCCESS) {
20410 		hdd_err("failed pmo psoc configuration");
20411 		return -EINVAL;
20412 	}
20413 
20414 	return 0;
20415 }
20416 
20417 int hdd_update_components_config(struct hdd_context *hdd_ctx)
20418 {
20419 	int ret;
20420 
20421 	ret = hdd_update_pmo_config(hdd_ctx);
20422 	if (ret)
20423 		return ret;
20424 
20425 	ret = hdd_update_scan_config(hdd_ctx);
20426 	if (ret)
20427 		return ret;
20428 
20429 	ret = hdd_update_tdls_config(hdd_ctx);
20430 	if (ret)
20431 		return ret;
20432 
20433 	ret = hdd_update_dp_config(hdd_ctx);
20434 	if (ret)
20435 		return ret;
20436 
20437 	ret = hdd_update_dfs_config(hdd_ctx);
20438 	if (ret)
20439 		return ret;
20440 
20441 	ret = hdd_update_regulatory_config(hdd_ctx);
20442 	if (ret)
20443 		return ret;
20444 
20445 	return ret;
20446 }
20447 
20448 /**
20449  * wlan_hdd_get_dfs_mode() - get ACS DFS mode
20450  * @mode : cfg80211 DFS mode
20451  *
20452  * Return: return SAP ACS DFS mode else return ACS_DFS_MODE_NONE
20453  */
20454 enum  sap_acs_dfs_mode wlan_hdd_get_dfs_mode(enum dfs_mode mode)
20455 {
20456 	switch (mode) {
20457 	case DFS_MODE_ENABLE:
20458 		return ACS_DFS_MODE_ENABLE;
20459 	case DFS_MODE_DISABLE:
20460 		return ACS_DFS_MODE_DISABLE;
20461 	case DFS_MODE_DEPRIORITIZE:
20462 		return ACS_DFS_MODE_DEPRIORITIZE;
20463 	default:
20464 		hdd_debug("ACS dfs mode is NONE");
20465 		return ACS_DFS_MODE_NONE;
20466 	}
20467 }
20468 
20469 /**
20470  * hdd_enable_disable_ca_event() - enable/disable channel avoidance event
20471  * @hdd_ctx: pointer to hdd context
20472  * @set_value: enable/disable
20473  *
20474  * When Host sends vendor command enable, FW will send *ONE* CA ind to
20475  * Host(even though it is duplicate). When Host send vendor command
20476  * disable,FW doesn't perform any action. Whenever any change in
20477  * CA *and* WLAN is in SAP/P2P-GO mode, FW sends CA ind to host.
20478  *
20479  * return - 0 on success, appropriate error values on failure.
20480  */
20481 int hdd_enable_disable_ca_event(struct hdd_context *hdd_ctx, uint8_t set_value)
20482 {
20483 	QDF_STATUS status;
20484 
20485 	if (0 != wlan_hdd_validate_context(hdd_ctx))
20486 		return -EAGAIN;
20487 
20488 	status = sme_enable_disable_chanavoidind_event(hdd_ctx->mac_handle,
20489 						       set_value);
20490 	if (!QDF_IS_STATUS_SUCCESS(status)) {
20491 		hdd_err("Failed to send chan avoid command to SME");
20492 		return -EINVAL;
20493 	}
20494 	return 0;
20495 }
20496 
20497 bool hdd_is_roaming_in_progress(struct hdd_context *hdd_ctx)
20498 {
20499 	struct hdd_adapter *adapter = NULL, *next_adapter = NULL;
20500 	uint8_t vdev_id;
20501 	wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_IS_ROAMING_IN_PROGRESS;
20502 	struct wlan_hdd_link_info *link_info;
20503 
20504 	if (!hdd_ctx) {
20505 		hdd_err("HDD context is NULL");
20506 		return false;
20507 	}
20508 
20509 	if (!policy_mgr_is_sta_active_connection_exists(hdd_ctx->psoc))
20510 		return false;
20511 
20512 	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
20513 					   dbgid) {
20514 		if (adapter->device_mode != QDF_STA_MODE)
20515 			goto adapter_put;
20516 
20517 		hdd_adapter_for_each_active_link_info(adapter, link_info) {
20518 			vdev_id = link_info->vdev_id;
20519 			if (test_bit(SME_SESSION_OPENED,
20520 				     &link_info->link_flags) &&
20521 			    sme_roaming_in_progress(hdd_ctx->mac_handle,
20522 						    vdev_id)) {
20523 				hdd_debug("Roaming is in progress on:vdev_id:%d",
20524 					  link_info->vdev_id);
20525 				hdd_adapter_dev_put_debug(adapter, dbgid);
20526 				if (next_adapter)
20527 					hdd_adapter_dev_put_debug(next_adapter,
20528 								  dbgid);
20529 				return true;
20530 			}
20531 		}
20532 adapter_put:
20533 		hdd_adapter_dev_put_debug(adapter, dbgid);
20534 	}
20535 
20536 	return false;
20537 }
20538 
20539 /**
20540  * struct hdd_is_connection_in_progress_priv - adapter connection info
20541  * @out_vdev_id: id of vdev where connection is occurring
20542  * @out_reason: scan reject reason
20543  * @connection_in_progress: true if connection is in progress
20544  */
20545 struct hdd_is_connection_in_progress_priv {
20546 	uint8_t out_vdev_id;
20547 	enum scan_reject_states out_reason;
20548 	bool connection_in_progress;
20549 };
20550 
20551 /**
20552  * hdd_is_connection_in_progress_iterator() - Check adapter connection based
20553  * on device mode
20554  * @link_info: Link info pointer in HDD adapter
20555  * @ctx: user context supplied
20556  *
20557  * Check if connection is in progress for the current adapter according to the
20558  * device mode
20559  *
20560  * Return:
20561  * * QDF_STATUS_SUCCESS if iteration should continue
20562  * * QDF_STATUS_E_ABORTED if iteration should be aborted
20563  */
20564 static QDF_STATUS
20565 hdd_is_connection_in_progress_iterator(struct wlan_hdd_link_info *link_info,
20566 				       void *ctx)
20567 {
20568 	struct hdd_station_ctx *hdd_sta_ctx;
20569 	uint8_t *sta_mac;
20570 	struct hdd_context *hdd_ctx;
20571 	mac_handle_t mac_handle;
20572 	struct hdd_station_info *sta_info, *tmp = NULL;
20573 	struct hdd_is_connection_in_progress_priv *context = ctx;
20574 	struct hdd_adapter *adapter = link_info->adapter;
20575 
20576 	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
20577 	if (!hdd_ctx)
20578 		return QDF_STATUS_E_ABORTED;
20579 
20580 	mac_handle = hdd_ctx->mac_handle;
20581 
20582 	if (!test_bit(SME_SESSION_OPENED, &link_info->link_flags) &&
20583 	    (adapter->device_mode == QDF_STA_MODE ||
20584 	     adapter->device_mode == QDF_P2P_CLIENT_MODE ||
20585 	     adapter->device_mode == QDF_P2P_DEVICE_MODE ||
20586 	     adapter->device_mode == QDF_P2P_GO_MODE ||
20587 	     adapter->device_mode == QDF_SAP_MODE))
20588 		return QDF_STATUS_SUCCESS;
20589 
20590 	if ((QDF_STA_MODE == adapter->device_mode ||
20591 	     QDF_P2P_CLIENT_MODE == adapter->device_mode ||
20592 	     QDF_P2P_DEVICE_MODE == adapter->device_mode) &&
20593 	    hdd_cm_is_connecting(link_info)) {
20594 		hdd_debug("%pK(%d) mode %d Connection is in progress",
20595 			  WLAN_HDD_GET_STATION_CTX_PTR(link_info),
20596 			  link_info->vdev_id, adapter->device_mode);
20597 
20598 		context->out_vdev_id = link_info->vdev_id;
20599 		context->out_reason = CONNECTION_IN_PROGRESS;
20600 		context->connection_in_progress = true;
20601 
20602 		return QDF_STATUS_E_ABORTED;
20603 	}
20604 
20605 	if ((QDF_STA_MODE == adapter->device_mode) &&
20606 	     sme_roaming_in_progress(mac_handle, link_info->vdev_id)) {
20607 		hdd_debug("%pK(%d) mode %d Reassociation in progress",
20608 			  WLAN_HDD_GET_STATION_CTX_PTR(link_info),
20609 			  link_info->vdev_id, adapter->device_mode);
20610 
20611 		context->out_vdev_id = link_info->vdev_id;
20612 		context->out_reason = REASSOC_IN_PROGRESS;
20613 		context->connection_in_progress = true;
20614 		return QDF_STATUS_E_ABORTED;
20615 	}
20616 
20617 	if ((QDF_STA_MODE == adapter->device_mode) ||
20618 		(QDF_P2P_CLIENT_MODE == adapter->device_mode) ||
20619 		(QDF_P2P_DEVICE_MODE == adapter->device_mode)) {
20620 		hdd_sta_ctx =
20621 			WLAN_HDD_GET_STATION_CTX_PTR(link_info);
20622 		if (hdd_cm_is_vdev_associated(link_info)
20623 		    && sme_is_sta_key_exchange_in_progress(
20624 		    mac_handle, link_info->vdev_id)) {
20625 			sta_mac = (uint8_t *)&(adapter->mac_addr.bytes[0]);
20626 			hdd_debug("client " QDF_MAC_ADDR_FMT
20627 				  " is in middle of WPS/EAPOL exchange.",
20628 				  QDF_MAC_ADDR_REF(sta_mac));
20629 
20630 			context->out_vdev_id = link_info->vdev_id;
20631 			context->out_reason = EAPOL_IN_PROGRESS;
20632 			context->connection_in_progress = true;
20633 
20634 			return QDF_STATUS_E_ABORTED;
20635 		}
20636 	} else if ((QDF_SAP_MODE == adapter->device_mode) ||
20637 			(QDF_P2P_GO_MODE == adapter->device_mode)) {
20638 		hdd_for_each_sta_ref_safe(adapter->sta_info_list, sta_info, tmp,
20639 				     STA_INFO_CONNECTION_IN_PROGRESS_ITERATOR) {
20640 			if (sta_info->peer_state !=
20641 				OL_TXRX_PEER_STATE_CONN) {
20642 				hdd_put_sta_info_ref(
20643 				     &adapter->sta_info_list, &sta_info, true,
20644 				     STA_INFO_CONNECTION_IN_PROGRESS_ITERATOR);
20645 				continue;
20646 			}
20647 
20648 			sta_mac = sta_info->sta_mac.bytes;
20649 			hdd_debug("client " QDF_MAC_ADDR_FMT
20650 				  " of SAP/GO is in middle of WPS/EAPOL exchange",
20651 				  QDF_MAC_ADDR_REF(sta_mac));
20652 
20653 			context->out_vdev_id = link_info->vdev_id;
20654 			context->out_reason = SAP_EAPOL_IN_PROGRESS;
20655 			context->connection_in_progress = true;
20656 
20657 			hdd_put_sta_info_ref(
20658 				&adapter->sta_info_list, &sta_info, true,
20659 				STA_INFO_CONNECTION_IN_PROGRESS_ITERATOR);
20660 			if (tmp)
20661 				hdd_put_sta_info_ref(
20662 				    &adapter->sta_info_list, &tmp, true,
20663 				    STA_INFO_CONNECTION_IN_PROGRESS_ITERATOR);
20664 
20665 			return QDF_STATUS_E_ABORTED;
20666 		}
20667 		if (hdd_ctx->connection_in_progress) {
20668 			hdd_debug("AP/GO: vdev %d connection is in progress",
20669 				  link_info->vdev_id);
20670 			context->out_reason = SAP_CONNECTION_IN_PROGRESS;
20671 			context->out_vdev_id = link_info->vdev_id;
20672 			context->connection_in_progress = true;
20673 
20674 			return QDF_STATUS_E_ABORTED;
20675 		}
20676 	}
20677 
20678 	if (ucfg_nan_is_enable_disable_in_progress(hdd_ctx->psoc)) {
20679 		context->out_reason = NAN_ENABLE_DISABLE_IN_PROGRESS;
20680 		context->out_vdev_id = NAN_PSEUDO_VDEV_ID;
20681 		context->connection_in_progress = true;
20682 
20683 		return QDF_STATUS_E_ABORTED;
20684 	}
20685 
20686 	return QDF_STATUS_SUCCESS;
20687 }
20688 
20689 bool hdd_is_connection_in_progress(uint8_t *out_vdev_id,
20690 				   enum scan_reject_states *out_reason)
20691 {
20692 	struct hdd_is_connection_in_progress_priv hdd_conn;
20693 	hdd_adapter_iterate_cb cb;
20694 
20695 	hdd_conn.out_vdev_id = 0;
20696 	hdd_conn.out_reason = SCAN_REJECT_DEFAULT;
20697 	hdd_conn.connection_in_progress = false;
20698 
20699 	cb = hdd_is_connection_in_progress_iterator;
20700 
20701 	hdd_adapter_iterate(cb, &hdd_conn);
20702 
20703 	if (hdd_conn.connection_in_progress && out_vdev_id && out_reason) {
20704 		*out_vdev_id = hdd_conn.out_vdev_id;
20705 		*out_reason = hdd_conn.out_reason;
20706 	}
20707 
20708 	return hdd_conn.connection_in_progress;
20709 }
20710 
20711 void hdd_restart_sap(struct wlan_hdd_link_info *link_info)
20712 {
20713 	struct hdd_hostapd_state *hapd_state;
20714 	QDF_STATUS status;
20715 	struct hdd_adapter *ap_adapter = link_info->adapter;
20716 	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(ap_adapter);
20717 	struct sap_config *sap_config;
20718 	void *sap_ctx;
20719 
20720 	sap_config =
20721 		&(WLAN_HDD_GET_AP_CTX_PTR(link_info)->sap_config);
20722 	sap_ctx = WLAN_HDD_GET_SAP_CTX_PTR(link_info);
20723 
20724 	mutex_lock(&hdd_ctx->sap_lock);
20725 	if (test_bit(SOFTAP_BSS_STARTED, &link_info->link_flags)) {
20726 		wlan_hdd_del_station(ap_adapter, NULL);
20727 		hapd_state = WLAN_HDD_GET_HOSTAP_STATE_PTR(link_info);
20728 		qdf_event_reset(&hapd_state->qdf_stop_bss_event);
20729 		if (QDF_STATUS_SUCCESS == wlansap_stop_bss(sap_ctx)) {
20730 			status = qdf_wait_single_event(&hapd_state->qdf_stop_bss_event,
20731 						       SME_CMD_STOP_BSS_TIMEOUT);
20732 
20733 			if (!QDF_IS_STATUS_SUCCESS(status)) {
20734 				hdd_err("SAP Stop Failed");
20735 				goto end;
20736 			}
20737 		}
20738 		clear_bit(SOFTAP_BSS_STARTED, &link_info->link_flags);
20739 		policy_mgr_decr_session_set_pcl(hdd_ctx->psoc,
20740 			ap_adapter->device_mode, link_info->vdev_id);
20741 		hdd_green_ap_start_state_mc(hdd_ctx, ap_adapter->device_mode,
20742 					    false);
20743 		hdd_err("SAP Stop Success");
20744 
20745 		if (0 != wlan_hdd_cfg80211_update_apies(link_info)) {
20746 			hdd_err("SAP Not able to set AP IEs");
20747 			goto end;
20748 		}
20749 
20750 		status = wlan_hdd_mlo_sap_reinit(link_info);
20751 		if (QDF_IS_STATUS_ERROR(status)) {
20752 			hdd_err("SAP Not able to do mlo attach");
20753 			goto deinit_mlo;
20754 		}
20755 
20756 		qdf_event_reset(&hapd_state->qdf_event);
20757 		status = wlansap_start_bss(sap_ctx, hdd_hostapd_sap_event_cb,
20758 					   sap_config, ap_adapter->dev);
20759 		if (QDF_IS_STATUS_ERROR(status)) {
20760 			hdd_err("SAP Start Bss fail");
20761 			goto deinit_mlo;
20762 		}
20763 
20764 		hdd_info("Waiting for SAP to start");
20765 		status = qdf_wait_single_event(&hapd_state->qdf_event,
20766 					       SME_CMD_START_BSS_TIMEOUT);
20767 		if (!QDF_IS_STATUS_SUCCESS(status)) {
20768 			hdd_err("SAP Start failed");
20769 			goto deinit_mlo;
20770 		}
20771 		wlansap_reset_sap_config_add_ie(sap_config, eUPDATE_IE_ALL);
20772 		hdd_err("SAP Start Success");
20773 		hdd_medium_assess_init();
20774 		set_bit(SOFTAP_BSS_STARTED, &link_info->link_flags);
20775 		if (hapd_state->bss_state == BSS_START) {
20776 			policy_mgr_incr_active_session(hdd_ctx->psoc,
20777 						ap_adapter->device_mode,
20778 						link_info->vdev_id);
20779 			hdd_green_ap_start_state_mc(hdd_ctx,
20780 						    ap_adapter->device_mode,
20781 						    true);
20782 		}
20783 	}
20784 	mutex_unlock(&hdd_ctx->sap_lock);
20785 	return;
20786 
20787 deinit_mlo:
20788 	wlan_hdd_mlo_reset(link_info);
20789 end:
20790 	wlansap_reset_sap_config_add_ie(sap_config, eUPDATE_IE_ALL);
20791 	mutex_unlock(&hdd_ctx->sap_lock);
20792 }
20793 
20794 /**
20795  * hdd_set_connection_in_progress() - to set the connection in
20796  * progress flag
20797  * @value: value to set
20798  *
20799  * This function will set the passed value to connection in progress flag.
20800  * If value is previously being set to true then no need to set it again.
20801  *
20802  * Return: true if value is being set correctly and false otherwise.
20803  */
20804 bool hdd_set_connection_in_progress(bool value)
20805 {
20806 	bool status = true;
20807 	struct hdd_context *hdd_ctx;
20808 
20809 	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
20810 	if (!hdd_ctx)
20811 		return false;
20812 
20813 	qdf_spin_lock(&hdd_ctx->connection_status_lock);
20814 	/*
20815 	 * if the value is set to true previously and if someone is
20816 	 * trying to make it true again then it could be some race
20817 	 * condition being triggered. Avoid this situation by returning
20818 	 * false
20819 	 */
20820 	if (hdd_ctx->connection_in_progress && value)
20821 		status = false;
20822 	else
20823 		hdd_ctx->connection_in_progress = value;
20824 	qdf_spin_unlock(&hdd_ctx->connection_status_lock);
20825 	return status;
20826 }
20827 
20828 int wlan_hdd_send_mcc_vdev_quota(struct hdd_adapter *adapter, int set_value)
20829 {
20830 	if (!adapter) {
20831 		hdd_err("Invalid adapter");
20832 		return -EINVAL;
20833 	}
20834 	hdd_info("send mcc vdev quota to fw: %d", set_value);
20835 	sme_cli_set_command(adapter->deflink->vdev_id,
20836 			    WMA_VDEV_MCC_SET_TIME_QUOTA,
20837 			    set_value, VDEV_CMD);
20838 	return 0;
20839 
20840 }
20841 
20842 int wlan_hdd_send_mcc_latency(struct hdd_adapter *adapter, int set_value)
20843 {
20844 	if (!adapter) {
20845 		hdd_err("Invalid adapter");
20846 		return -EINVAL;
20847 	}
20848 
20849 	hdd_info("Send MCC latency WMA: %d", set_value);
20850 	sme_cli_set_command(adapter->deflink->vdev_id,
20851 			    WMA_VDEV_MCC_SET_TIME_LATENCY,
20852 			    set_value, VDEV_CMD);
20853 	return 0;
20854 }
20855 
20856 struct wlan_hdd_link_info *
20857 wlan_hdd_get_link_info_from_vdev(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id)
20858 {
20859 	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
20860 	struct wlan_hdd_link_info *link_info;
20861 
20862 	/*
20863 	 * Currently PSOC is not being used. But this logic will
20864 	 * change once we have the converged implementation of
20865 	 * HDD context per PSOC in place. This would break if
20866 	 * multiple vdev objects reuse the vdev id.
20867 	 */
20868 	link_info = hdd_get_link_info_by_vdev(hdd_ctx, vdev_id);
20869 	if (!link_info) {
20870 		hdd_err("Get adapter by vdev id failed");
20871 		return NULL;
20872 	}
20873 
20874 	return link_info;
20875 }
20876 
20877 int hdd_get_rssi_snr_by_bssid(mac_handle_t mac_handle, const uint8_t *bssid,
20878 			      int8_t *rssi, int8_t *snr)
20879 {
20880 	QDF_STATUS status;
20881 
20882 	status = sme_get_rssi_snr_by_bssid(mac_handle, bssid, rssi, snr);
20883 	if (QDF_IS_STATUS_ERROR(status)) {
20884 		hdd_debug("sme_get_rssi_snr_by_bssid failed");
20885 		return -EINVAL;
20886 	}
20887 
20888 	return 0;
20889 }
20890 
20891 /**
20892  * hdd_reset_limit_off_chan() - reset limit off-channel command parameters
20893  * @adapter: HDD adapter
20894  *
20895  * Return: 0 on success and non zero value on failure
20896  */
20897 int hdd_reset_limit_off_chan(struct hdd_adapter *adapter)
20898 {
20899 	struct hdd_context *hdd_ctx;
20900 	int ret;
20901 	QDF_STATUS status;
20902 	uint8_t sys_pref = 0;
20903 
20904 	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
20905 	ret = wlan_hdd_validate_context(hdd_ctx);
20906 	if (ret < 0)
20907 		return ret;
20908 
20909 	ucfg_policy_mgr_get_sys_pref(hdd_ctx->psoc,
20910 				     &sys_pref);
20911 	/* set the system preferece to default */
20912 	policy_mgr_set_cur_conc_system_pref(hdd_ctx->psoc, sys_pref);
20913 
20914 	/* clear the bitmap */
20915 	adapter->active_ac = 0;
20916 
20917 	hdd_debug("reset ac_bitmap for session %hu active_ac %0x",
20918 		  adapter->deflink->vdev_id, adapter->active_ac);
20919 
20920 	status = sme_send_limit_off_channel_params(hdd_ctx->mac_handle,
20921 						   adapter->deflink->vdev_id,
20922 						   false, 0, 0, false);
20923 	if (!QDF_IS_STATUS_SUCCESS(status)) {
20924 		hdd_err("failed to reset limit off chan params");
20925 		ret = -EINVAL;
20926 	}
20927 
20928 	return ret;
20929 }
20930 
20931 void hdd_hidden_ssid_enable_roaming(hdd_handle_t hdd_handle, uint8_t vdev_id)
20932 {
20933 	struct hdd_context *hdd_ctx = hdd_handle_to_context(hdd_handle);
20934 	struct wlan_hdd_link_info *link_info;
20935 
20936 	link_info = hdd_get_link_info_by_vdev(hdd_ctx, vdev_id);
20937 	if (!link_info) {
20938 		hdd_err("Invalid vdev");
20939 		return;
20940 	}
20941 	/* enable roaming on all adapters once hdd get hidden ssid rsp */
20942 	wlan_hdd_set_roaming_state(link_info, RSO_START_BSS, true);
20943 }
20944 
20945 #ifdef WLAN_FEATURE_PKT_CAPTURE
20946 bool wlan_hdd_is_mon_concurrency(void)
20947 {
20948 	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
20949 
20950 	if (!hdd_ctx)
20951 		return -EINVAL;
20952 
20953 	if (ucfg_pkt_capture_get_mode(hdd_ctx->psoc) !=
20954 						PACKET_CAPTURE_MODE_DISABLE) {
20955 		if (policy_mgr_get_concurrency_mode(hdd_ctx->psoc) ==
20956 		    (QDF_STA_MASK | QDF_MONITOR_MASK)) {
20957 			hdd_err("STA + MON mode is UP");
20958 			return true;
20959 		}
20960 	}
20961 	return false;
20962 }
20963 
20964 void wlan_hdd_del_monitor(struct hdd_context *hdd_ctx,
20965 			  struct hdd_adapter *adapter, bool rtnl_held)
20966 {
20967 	wlan_hdd_release_intf_addr(hdd_ctx, adapter->mac_addr.bytes);
20968 	hdd_stop_adapter(hdd_ctx, adapter);
20969 	hdd_close_adapter(hdd_ctx, adapter, true);
20970 
20971 	hdd_open_p2p_interface(hdd_ctx);
20972 }
20973 
20974 void
20975 wlan_hdd_del_p2p_interface(struct hdd_context *hdd_ctx)
20976 {
20977 	struct hdd_adapter *adapter = NULL, *next_adapter = NULL;
20978 	struct osif_vdev_sync *vdev_sync;
20979 
20980 	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
20981 					   NET_DEV_HOLD_DEL_P2P_INTERFACE) {
20982 		if (adapter->device_mode == QDF_P2P_CLIENT_MODE ||
20983 		    adapter->device_mode == QDF_P2P_DEVICE_MODE ||
20984 		    adapter->device_mode == QDF_P2P_GO_MODE) {
20985 			vdev_sync = osif_vdev_sync_unregister(adapter->dev);
20986 			if (vdev_sync)
20987 				osif_vdev_sync_wait_for_ops(vdev_sync);
20988 
20989 			hdd_adapter_dev_put_debug(
20990 				adapter, NET_DEV_HOLD_DEL_P2P_INTERFACE);
20991 
20992 			hdd_clean_up_interface(hdd_ctx, adapter);
20993 
20994 			if (vdev_sync)
20995 				osif_vdev_sync_destroy(vdev_sync);
20996 		} else
20997 			hdd_adapter_dev_put_debug(
20998 				adapter, NET_DEV_HOLD_DEL_P2P_INTERFACE);
20999 	}
21000 }
21001 
21002 #endif /* WLAN_FEATURE_PKT_CAPTURE */
21003 
21004 bool wlan_hdd_is_session_type_monitor(uint8_t session_type)
21005 {
21006 	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
21007 
21008 	if (!hdd_ctx) {
21009 		cds_err("HDD context is NULL");
21010 		return false;
21011 	}
21012 
21013 	if (cds_get_conparam() != QDF_GLOBAL_MONITOR_MODE &&
21014 	    session_type == QDF_MONITOR_MODE)
21015 		return true;
21016 	else
21017 		return false;
21018 }
21019 
21020 int
21021 wlan_hdd_add_monitor_check(struct hdd_context *hdd_ctx,
21022 			   struct hdd_adapter **adapter,
21023 			   const char *name, bool rtnl_held,
21024 			   unsigned char name_assign_type)
21025 {
21026 	struct hdd_adapter *sta_adapter;
21027 	struct hdd_adapter *mon_adapter;
21028 	uint8_t num_open_session = 0;
21029 	QDF_STATUS status;
21030 	struct hdd_adapter_create_param params = {0};
21031 
21032 	sta_adapter = hdd_get_adapter(hdd_ctx, QDF_STA_MODE);
21033 	if (!sta_adapter) {
21034 		hdd_err("No station adapter");
21035 		return -EINVAL;
21036 	}
21037 
21038 	status = policy_mgr_check_mon_concurrency(hdd_ctx->psoc);
21039 
21040 	if (QDF_IS_STATUS_ERROR(status))
21041 		return -EINVAL;
21042 
21043 	if (hdd_is_connection_in_progress(NULL, NULL)) {
21044 		hdd_err("cannot add monitor mode, Connection in progress");
21045 		return -EINVAL;
21046 	}
21047 
21048 	if (!ucfg_dp_is_local_pkt_capture_enabled(hdd_ctx->psoc) &&
21049 	    ucfg_mlme_is_sta_mon_conc_supported(hdd_ctx->psoc)) {
21050 		num_open_session = policy_mgr_mode_specific_connection_count(
21051 						hdd_ctx->psoc,
21052 						PM_STA_MODE,
21053 						NULL);
21054 
21055 		if (num_open_session) {
21056 			/* Try disconnecting if already in connected state */
21057 			wlan_hdd_cm_issue_disconnect(sta_adapter->deflink,
21058 						     REASON_UNSPEC_FAILURE,
21059 						     true);
21060 		}
21061 	}
21062 
21063 	if (ucfg_pkt_capture_get_mode(hdd_ctx->psoc) !=
21064 						PACKET_CAPTURE_MODE_DISABLE)
21065 		wlan_hdd_del_p2p_interface(hdd_ctx);
21066 
21067 	params.is_add_virtual_iface = 1;
21068 
21069 	mon_adapter = hdd_open_adapter(hdd_ctx, QDF_MONITOR_MODE, name,
21070 				       wlan_hdd_get_intf_addr(
21071 				       hdd_ctx,
21072 				       QDF_MONITOR_MODE),
21073 				       name_assign_type, rtnl_held, &params);
21074 	if (!mon_adapter) {
21075 		hdd_err("hdd_open_adapter failed");
21076 		if (ucfg_pkt_capture_get_mode(hdd_ctx->psoc) !=
21077 						PACKET_CAPTURE_MODE_DISABLE)
21078 			hdd_open_p2p_interface(hdd_ctx);
21079 		return -EINVAL;
21080 	}
21081 
21082 	if (mon_adapter)
21083 		hdd_set_idle_ps_config(hdd_ctx, false);
21084 
21085 	*adapter = mon_adapter;
21086 	return 0;
21087 }
21088 
21089 #ifdef FEATURE_MONITOR_MODE_SUPPORT
21090 
21091 void hdd_sme_monitor_mode_callback(uint8_t vdev_id)
21092 {
21093 	struct hdd_context *hdd_ctx;
21094 	struct hdd_adapter *adapter;
21095 	struct wlan_hdd_link_info *link_info;
21096 
21097 	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
21098 	if (!hdd_ctx)
21099 		return;
21100 
21101 	link_info = hdd_get_link_info_by_vdev(hdd_ctx, vdev_id);
21102 	if (!link_info) {
21103 		hdd_err_rl("NULL adapter");
21104 		return;
21105 	}
21106 
21107 	adapter = link_info->adapter;
21108 	if (adapter->magic != WLAN_HDD_ADAPTER_MAGIC) {
21109 		hdd_err_rl("Invalid magic");
21110 		return;
21111 	}
21112 
21113 	qdf_event_set(&adapter->qdf_monitor_mode_vdev_up_event);
21114 
21115 	hdd_debug("monitor mode vdev up completed");
21116 	adapter->monitor_mode_vdev_up_in_progress = false;
21117 }
21118 
21119 QDF_STATUS hdd_monitor_mode_qdf_create_event(struct hdd_adapter *adapter,
21120 					     uint8_t session_type)
21121 {
21122 	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
21123 
21124 	if (session_type == QDF_MONITOR_MODE) {
21125 		qdf_status = qdf_event_create(
21126 				&adapter->qdf_monitor_mode_vdev_up_event);
21127 	}
21128 	return qdf_status;
21129 }
21130 
21131 QDF_STATUS hdd_monitor_mode_vdev_status(struct hdd_adapter *adapter)
21132 {
21133 	QDF_STATUS status = QDF_STATUS_SUCCESS;
21134 
21135 	if (!adapter->monitor_mode_vdev_up_in_progress)
21136 		return status;
21137 
21138 	/* block on a completion variable until vdev up success*/
21139 	status = qdf_wait_for_event_completion(
21140 				       &adapter->qdf_monitor_mode_vdev_up_event,
21141 					WLAN_MONITOR_MODE_VDEV_UP_EVT);
21142 	if (QDF_IS_STATUS_ERROR(status)) {
21143 		hdd_err_rl("monitor mode vdev up event time out vdev id: %d",
21144 			   adapter->deflink->vdev_id);
21145 		if (adapter->qdf_monitor_mode_vdev_up_event.force_set)
21146 			/*
21147 			 * SSR/PDR has caused shutdown, which has
21148 			 * forcefully set the event.
21149 			 */
21150 			hdd_err_rl("monitor mode vdev up event forcefully set");
21151 		else if (status == QDF_STATUS_E_TIMEOUT)
21152 			hdd_err_rl("mode vdev up event timed out");
21153 		else
21154 			hdd_err_rl("Failed to wait for monitor vdev up(status-%d)",
21155 				   status);
21156 
21157 		adapter->monitor_mode_vdev_up_in_progress = false;
21158 		return status;
21159 	}
21160 
21161 	return QDF_STATUS_SUCCESS;
21162 }
21163 #endif
21164 
21165 #if defined(CLD_PM_QOS) && defined(WLAN_FEATURE_LL_MODE)
21166 void hdd_beacon_latency_event_cb(uint32_t latency_level)
21167 {
21168 	struct hdd_context *hdd_ctx;
21169 
21170 	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
21171 	if (!hdd_ctx)
21172 		return;
21173 
21174 	if (latency_level ==
21175 		QCA_WLAN_VENDOR_ATTR_CONFIG_LATENCY_LEVEL_ULTRALOW)
21176 		wlan_hdd_set_pm_qos_request(hdd_ctx, true);
21177 	else
21178 		wlan_hdd_set_pm_qos_request(hdd_ctx, false);
21179 }
21180 #endif
21181 
21182 #ifdef CONFIG_WLAN_DEBUG_CRASH_INJECT
21183 int hdd_crash_inject(struct hdd_adapter *adapter, uint32_t v1, uint32_t v2)
21184 {
21185 	struct hdd_context *hdd_ctx;
21186 	int ret;
21187 	bool crash_inject;
21188 	QDF_STATUS status;
21189 
21190 	hdd_debug("v1: %d v2: %d", v1, v2);
21191 	pr_err("SSR is triggered by CRASH_INJECT: %d %d\n",
21192 	       v1, v2);
21193 	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
21194 
21195 	status = ucfg_mlme_get_crash_inject(hdd_ctx->psoc, &crash_inject);
21196 	if (QDF_IS_STATUS_ERROR(status)) {
21197 		hdd_err("Failed to get crash inject ini config");
21198 		return 0;
21199 	}
21200 
21201 	if (!crash_inject) {
21202 		hdd_err("Crash Inject ini disabled, Ignore Crash Inject");
21203 		return 0;
21204 	}
21205 
21206 	if (v1 == 3) {
21207 		cds_trigger_recovery(QDF_REASON_UNSPECIFIED);
21208 		return 0;
21209 	}
21210 	ret = wma_cli_set2_command(adapter->deflink->vdev_id,
21211 				   GEN_PARAM_CRASH_INJECT,
21212 				   v1, v2, GEN_CMD);
21213 	return ret;
21214 }
21215 #endif
21216 
21217 static const struct hdd_chwidth_info chwidth_info[] = {
21218 	[NL80211_CHAN_WIDTH_20_NOHT] = {
21219 		.ch_bw = HW_MODE_20_MHZ,
21220 		.ch_bw_str = "20MHz",
21221 		.phy_chwidth = CH_WIDTH_20MHZ,
21222 	},
21223 	[NL80211_CHAN_WIDTH_20] = {
21224 		.sir_chwidth_valid = true,
21225 		.sir_chwidth = eHT_CHANNEL_WIDTH_20MHZ,
21226 		.ch_bw = HW_MODE_20_MHZ,
21227 		.ch_bw_str = "20MHz",
21228 		.phy_chwidth = CH_WIDTH_20MHZ,
21229 		.bonding_mode = WNI_CFG_CHANNEL_BONDING_MODE_DISABLE,
21230 	},
21231 	[NL80211_CHAN_WIDTH_40] = {
21232 		.sir_chwidth_valid = true,
21233 		.sir_chwidth = eHT_CHANNEL_WIDTH_40MHZ,
21234 		.ch_bw = HW_MODE_40_MHZ,
21235 		.ch_bw_str = "40MHz",
21236 		.phy_chwidth = CH_WIDTH_40MHZ,
21237 		.bonding_mode = WNI_CFG_CHANNEL_BONDING_MODE_ENABLE,
21238 	},
21239 	[NL80211_CHAN_WIDTH_80] = {
21240 		.sir_chwidth_valid = true,
21241 		.sir_chwidth = eHT_CHANNEL_WIDTH_80MHZ,
21242 		.ch_bw = HW_MODE_80_MHZ,
21243 		.ch_bw_str = "80MHz",
21244 		.phy_chwidth = CH_WIDTH_80MHZ,
21245 		.bonding_mode = WNI_CFG_CHANNEL_BONDING_MODE_ENABLE,
21246 	},
21247 	[NL80211_CHAN_WIDTH_80P80] = {
21248 		.sir_chwidth_valid = true,
21249 		.sir_chwidth = eHT_CHANNEL_WIDTH_80P80MHZ,
21250 		.ch_bw = HW_MODE_80_PLUS_80_MHZ,
21251 		.ch_bw_str = "(80 + 80)MHz",
21252 		.phy_chwidth = CH_WIDTH_80P80MHZ,
21253 		.bonding_mode = WNI_CFG_CHANNEL_BONDING_MODE_ENABLE,
21254 	},
21255 	[NL80211_CHAN_WIDTH_160] = {
21256 		.sir_chwidth_valid = true,
21257 		.sir_chwidth = eHT_CHANNEL_WIDTH_160MHZ,
21258 		.ch_bw = HW_MODE_160_MHZ,
21259 		.ch_bw_str = "160MHz",
21260 		.phy_chwidth = CH_WIDTH_160MHZ,
21261 		.bonding_mode = WNI_CFG_CHANNEL_BONDING_MODE_ENABLE,
21262 	},
21263 	[NL80211_CHAN_WIDTH_5] = {
21264 		.ch_bw = HW_MODE_5_MHZ,
21265 		.ch_bw_str = "5MHz",
21266 		.phy_chwidth = CH_WIDTH_5MHZ,
21267 	},
21268 	[NL80211_CHAN_WIDTH_10] = {
21269 		.ch_bw = HW_MODE_10_MHZ,
21270 		.ch_bw_str = "10MHz",
21271 		.phy_chwidth = CH_WIDTH_10MHZ,
21272 	},
21273 #if defined(WLAN_FEATURE_11BE) && defined(CFG80211_11BE_BASIC)
21274 	[NL80211_CHAN_WIDTH_320] = {
21275 		.sir_chwidth_valid = true,
21276 		.sir_chwidth = eHT_CHANNEL_WIDTH_320MHZ,
21277 		.ch_bw = HW_MODE_320_MHZ,
21278 		.ch_bw_str = "320MHz",
21279 		.phy_chwidth = CH_WIDTH_320MHZ,
21280 		.bonding_mode = WNI_CFG_CHANNEL_BONDING_MODE_ENABLE,
21281 	},
21282 #endif
21283 };
21284 
21285 enum eSirMacHTChannelWidth
21286 hdd_nl80211_chwidth_to_chwidth(uint8_t nl80211_chwidth)
21287 {
21288 	if (nl80211_chwidth >= ARRAY_SIZE(chwidth_info) ||
21289 	    !chwidth_info[nl80211_chwidth].sir_chwidth_valid) {
21290 		hdd_err("Unsupported channel width %d", nl80211_chwidth);
21291 		return -EINVAL;
21292 	}
21293 
21294 	return chwidth_info[nl80211_chwidth].sir_chwidth;
21295 }
21296 
21297 uint8_t hdd_chwidth_to_nl80211_chwidth(enum eSirMacHTChannelWidth chwidth)
21298 {
21299 	int i;
21300 
21301 	for (i = 0; i < ARRAY_SIZE(chwidth_info); i++) {
21302 		if (chwidth_info[i].sir_chwidth_valid &&
21303 		    chwidth_info[i].sir_chwidth == chwidth)
21304 			return i;
21305 	}
21306 
21307 	hdd_err("Unsupported channel width %d", chwidth);
21308 	return 0xFF;
21309 }
21310 
21311 enum hw_mode_bandwidth wlan_hdd_get_channel_bw(enum nl80211_chan_width width)
21312 {
21313 	if (width >= ARRAY_SIZE(chwidth_info)) {
21314 		hdd_err("Invalid width: %d, using default 20MHz", width);
21315 		return HW_MODE_20_MHZ;
21316 	}
21317 
21318 	return chwidth_info[width].ch_bw;
21319 }
21320 
21321 uint8_t *hdd_ch_width_str(enum phy_ch_width ch_width)
21322 {
21323 	int i;
21324 
21325 	for (i = 0; i < ARRAY_SIZE(chwidth_info); i++) {
21326 		if (chwidth_info[i].phy_chwidth == ch_width)
21327 			return chwidth_info[i].ch_bw_str;
21328 	}
21329 
21330 	return "UNKNOWN";
21331 }
21332 
21333 int hdd_we_set_ch_width(struct wlan_hdd_link_info *link_info, int ch_width)
21334 {
21335 	int i;
21336 
21337 	/* updating channel bonding only on 5Ghz */
21338 	hdd_debug("wmi_vdev_param_chwidth val %d", ch_width);
21339 
21340 	for (i = 0; i < ARRAY_SIZE(chwidth_info); i++) {
21341 		if (!chwidth_info[i].sir_chwidth_valid ||
21342 		    chwidth_info[i].sir_chwidth != ch_width)
21343 			continue;
21344 
21345 		return hdd_update_channel_width(link_info->adapter, ch_width,
21346 						chwidth_info[i].bonding_mode);
21347 	}
21348 
21349 	hdd_err("Invalid ch_width %d", ch_width);
21350 	return -EINVAL;
21351 }
21352 
21353 /* Register the module init/exit functions */
21354 module_init(hdd_module_init);
21355 module_exit(hdd_module_exit);
21356 
21357 MODULE_LICENSE("Dual BSD/GPL");
21358 MODULE_AUTHOR("Qualcomm Atheros, Inc.");
21359 MODULE_DESCRIPTION("WLAN HOST DEVICE DRIVER");
21360 
21361 const struct kernel_param_ops con_mode_ops = {
21362 	.set = con_mode_handler,
21363 	.get = param_get_int,
21364 };
21365 
21366 #ifdef FEATURE_WLAN_RESIDENT_DRIVER
21367 EXPORT_SYMBOL(con_mode_ops);
21368 #endif
21369 
21370 const struct kernel_param_ops con_mode_ftm_ops = {
21371 	.set = con_mode_handler_ftm,
21372 	.get = param_get_int,
21373 };
21374 
21375 #ifdef FEATURE_WLAN_RESIDENT_DRIVER
21376 EXPORT_SYMBOL(con_mode_ftm_ops);
21377 #endif
21378 
21379 #ifdef WLAN_FEATURE_EPPING
21380 static const struct kernel_param_ops con_mode_epping_ops = {
21381 	.set = con_mode_handler_epping,
21382 	.get = param_get_int,
21383 };
21384 #endif
21385 
21386 static const struct kernel_param_ops fwpath_ops = {
21387 	.set = fwpath_changed_handler,
21388 	.get = param_get_string,
21389 };
21390 
21391 static int __pcie_set_gen_speed_handler(void)
21392 {
21393 	int ret;
21394 	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
21395 
21396 	ret = wlan_hdd_validate_context(hdd_ctx);
21397 	if (ret)
21398 		return ret;
21399 
21400 	hdd_info_rl("Received PCIe gen speed %d", pcie_gen_speed);
21401 	if (pcie_gen_speed <= HDD_INVALID_MIN_PCIE_GEN_SPEED ||
21402 	    pcie_gen_speed >= HDD_INVALID_MAX_PCIE_GEN_SPEED) {
21403 		hdd_err_rl("invalid pcie gen speed %d", pcie_gen_speed);
21404 		return -EINVAL;
21405 	}
21406 
21407 	hdd_ctx->current_pcie_gen_speed = pcie_gen_speed;
21408 
21409 	return 0;
21410 }
21411 
21412 static int pcie_set_gen_speed_handler(const char *kmessage,
21413 				      const struct kernel_param *kp)
21414 {
21415 	struct osif_driver_sync *driver_sync;
21416 	int ret;
21417 
21418 	ret = osif_driver_sync_op_start(&driver_sync);
21419 	if (ret)
21420 		return ret;
21421 
21422 	ret = param_set_int(kmessage, kp);
21423 	if (ret) {
21424 		hdd_err_rl("param set int failed %d", ret);
21425 		goto out;
21426 	}
21427 
21428 	ret = __pcie_set_gen_speed_handler();
21429 
21430 out:
21431 	osif_driver_sync_op_stop(driver_sync);
21432 
21433 	return ret;
21434 }
21435 
21436 static const struct kernel_param_ops pcie_gen_speed_ops = {
21437 	.set = pcie_set_gen_speed_handler,
21438 	.get = param_get_int,
21439 };
21440 
21441 module_param_cb(con_mode, &con_mode_ops, &con_mode,
21442 		S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
21443 
21444 module_param_cb(con_mode_ftm, &con_mode_ftm_ops, &con_mode_ftm,
21445 		S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
21446 
21447 module_param_cb(pcie_gen_speed, &pcie_gen_speed_ops, &pcie_gen_speed,
21448 		S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
21449 
21450 #ifdef WLAN_FEATURE_EPPING
21451 module_param_cb(con_mode_epping, &con_mode_epping_ops,
21452 		&con_mode_epping, 0644);
21453 #endif
21454 
21455 module_param_cb(fwpath, &fwpath_ops, &fwpath,
21456 		S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
21457 
21458 module_param(enable_dfs_chan_scan, int, S_IRUSR | S_IRGRP | S_IROTH);
21459 
21460 module_param(enable_11d, int, S_IRUSR | S_IRGRP | S_IROTH);
21461 
21462 module_param(country_code, charp, S_IRUSR | S_IRGRP | S_IROTH);
21463 
21464 static int timer_multiplier_get_handler(char *buffer,
21465 					const struct kernel_param *kp)
21466 {
21467 	return scnprintf(buffer, PAGE_SIZE, "%u", qdf_timer_get_multiplier());
21468 }
21469 
21470 static int timer_multiplier_set_handler(const char *kmessage,
21471 					const struct kernel_param *kp)
21472 {
21473 	QDF_STATUS status;
21474 	uint32_t scalar;
21475 
21476 	status = qdf_uint32_parse(kmessage, &scalar);
21477 	if (QDF_IS_STATUS_ERROR(status))
21478 		return qdf_status_to_os_return(status);
21479 
21480 	if (!cfg_in_range(CFG_TIMER_MULTIPLIER, scalar))
21481 		return -ERANGE;
21482 
21483 	qdf_timer_set_multiplier(scalar);
21484 
21485 	return 0;
21486 }
21487 
21488 static const struct kernel_param_ops timer_multiplier_ops = {
21489 	.get = timer_multiplier_get_handler,
21490 	.set = timer_multiplier_set_handler,
21491 };
21492 
21493 module_param_cb(timer_multiplier, &timer_multiplier_ops, NULL, 0644);
21494