xref: /wlan-dirver/qcacld-3.0/core/hdd/src/wlan_hdd_main.c (revision 019b2fff7f27950fdf4acf3ed3d33ab750d67ede)
1 /*
2  * Copyright (c) 2012-2021 The Linux Foundation. All rights reserved.
3  * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
4  *
5  * Permission to use, copy, modify, and/or distribute this software for
6  * any purpose with or without fee is hereby granted, provided that the
7  * above copyright notice and this permission notice appear in all
8  * copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
11  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
12  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
13  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
14  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
16  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17  * PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20 /**
21  *  DOC: 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 #include "os_if_ll_sap.h"
252 #include "wlan_p2p_ucfg_api.h"
253 #include "wlan_crypto_obj_mgr_i.h"
254 
255 #ifdef MULTI_CLIENT_LL_SUPPORT
256 #define WLAM_WLM_HOST_DRIVER_PORT_ID 0xFFFFFF
257 #endif
258 
259 #ifdef MODULE
260 #ifdef WLAN_WEAR_CHIPSET
261 #define WLAN_MODULE_NAME  "wlan"
262 #else
263 #define WLAN_MODULE_NAME  module_name(THIS_MODULE)
264 #endif
265 #else
266 #define WLAN_MODULE_NAME  "wlan"
267 #endif
268 
269 #ifdef TIMER_MANAGER
270 #define TIMER_MANAGER_STR " +TIMER_MANAGER"
271 #else
272 #define TIMER_MANAGER_STR ""
273 #endif
274 
275 #ifdef MEMORY_DEBUG
276 #define MEMORY_DEBUG_STR " +MEMORY_DEBUG"
277 #else
278 #define MEMORY_DEBUG_STR ""
279 #endif
280 
281 #ifdef PANIC_ON_BUG
282 #define PANIC_ON_BUG_STR " +PANIC_ON_BUG"
283 #else
284 #define PANIC_ON_BUG_STR ""
285 #endif
286 
287 /* PCIe gen speed change idle shutdown timer 100 milliseconds */
288 #define HDD_PCIE_GEN_SPEED_CHANGE_TIMEOUT_MS (100)
289 
290 #define MAX_NET_DEV_REF_LEAK_ITERATIONS 10
291 #define NET_DEV_REF_LEAK_ITERATION_SLEEP_TIME_MS 10
292 
293 #ifdef FEATURE_TSO
294 #define TSO_FEATURE_FLAGS (NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_SG)
295 #else
296 #define TSO_FEATURE_FLAGS 0
297 #endif
298 
299 int wlan_start_ret_val;
300 static DECLARE_COMPLETION(wlan_start_comp);
301 static qdf_atomic_t wlan_hdd_state_fops_ref;
302 #ifndef MODULE
303 static struct gwlan_loader *wlan_loader;
304 static ssize_t wlan_boot_cb(struct kobject *kobj,
305 			    struct kobj_attribute *attr,
306 			    const char *buf, size_t count);
307 struct gwlan_loader {
308 	bool loaded_state;
309 	struct kobject *boot_wlan_obj;
310 	struct attribute_group *attr_group;
311 };
312 
313 static struct kobj_attribute wlan_boot_attribute =
314 	__ATTR(boot_wlan, 0220, NULL, wlan_boot_cb);
315 
316 static struct attribute *attrs[] = {
317 	&wlan_boot_attribute.attr,
318 	NULL,
319 };
320 #define MODULE_INITIALIZED 1
321 
322 #ifdef MULTI_IF_NAME
323 #define WLAN_LOADER_NAME "boot_" MULTI_IF_NAME
324 #else
325 #define WLAN_LOADER_NAME "boot_wlan"
326 #endif
327 #endif
328 
329 /* the Android framework expects this param even though we don't use it */
330 #define BUF_LEN 20
331 static char fwpath_buffer[BUF_LEN];
332 static struct kparam_string fwpath = {
333 	.string = fwpath_buffer,
334 	.maxlen = BUF_LEN,
335 };
336 
337 char *country_code;
338 #ifdef FEATURE_WLAN_RESIDENT_DRIVER
339 EXPORT_SYMBOL(country_code);
340 #endif
341 static int enable_11d = -1;
342 static int enable_dfs_chan_scan = -1;
343 static bool is_mode_change_psoc_idle_shutdown;
344 
345 #define WLAN_NLINK_CESIUM 30
346 
347 static qdf_wake_lock_t wlan_wake_lock;
348 
349 /* The valid PCIe gen speeds are 1, 2, 3 */
350 #define HDD_INVALID_MIN_PCIE_GEN_SPEED (0)
351 #define HDD_INVALID_MAX_PCIE_GEN_SPEED (4)
352 
353 #define MAX_PDEV_PRE_ENABLE_PARAMS 8
354 #define FTM_MAX_PDEV_PARAMS 1
355 
356 #define WOW_MAX_FILTER_LISTS 1
357 #define WOW_MAX_FILTERS_PER_LIST 4
358 #define WOW_MIN_PATTERN_SIZE 6
359 #define WOW_MAX_PATTERN_SIZE 64
360 #define MGMT_DEFAULT_DATA_RATE_6GHZ 0x400 /* This maps to 8.6Mbps data rate */
361 
362 #define IS_IDLE_STOP (!cds_is_driver_unloading() && \
363 		      !cds_is_driver_recovering() && !cds_is_driver_loading())
364 
365 #define HDD_FW_VER_MAJOR_SPID(tgt_fw_ver)     ((tgt_fw_ver & 0xf0000000) >> 28)
366 #define HDD_FW_VER_MINOR_SPID(tgt_fw_ver)     ((tgt_fw_ver & 0xf000000) >> 24)
367 #define HDD_FW_VER_SIID(tgt_fw_ver)           ((tgt_fw_ver & 0xf00000) >> 20)
368 #define HDD_FW_VER_CRM_ID(tgt_fw_ver)         (tgt_fw_ver & 0x7fff)
369 #define HDD_FW_VER_SUB_ID(tgt_fw_ver_ext) \
370 (((tgt_fw_ver_ext & 0x1c00) >> 6) | ((tgt_fw_ver_ext & 0xf0000000) >> 28))
371 #define HDD_FW_VER_REL_ID(tgt_fw_ver_ext) \
372 ((tgt_fw_ver_ext &  0xf800000) >> 23)
373 
374 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
375 static const struct wiphy_wowlan_support wowlan_support_reg_init = {
376 	.flags = WIPHY_WOWLAN_ANY |
377 		 WIPHY_WOWLAN_MAGIC_PKT |
378 		 WIPHY_WOWLAN_DISCONNECT |
379 		 WIPHY_WOWLAN_SUPPORTS_GTK_REKEY |
380 		 WIPHY_WOWLAN_GTK_REKEY_FAILURE |
381 		 WIPHY_WOWLAN_EAP_IDENTITY_REQ |
382 		 WIPHY_WOWLAN_4WAY_HANDSHAKE |
383 		 WIPHY_WOWLAN_RFKILL_RELEASE,
384 	.n_patterns = WOW_MAX_FILTER_LISTS * WOW_MAX_FILTERS_PER_LIST,
385 	.pattern_min_len = WOW_MIN_PATTERN_SIZE,
386 	.pattern_max_len = WOW_MAX_PATTERN_SIZE,
387 };
388 #endif
389 
390 static const struct category_info cinfo[MAX_SUPPORTED_CATEGORY] = {
391 	[QDF_MODULE_ID_TLSHIM] = {QDF_TRACE_LEVEL_ALL},
392 	[QDF_MODULE_ID_WMI] = {QDF_TRACE_LEVEL_ALL},
393 	[QDF_MODULE_ID_HTT] = {QDF_TRACE_LEVEL_ALL},
394 	[QDF_MODULE_ID_HDD] = {QDF_TRACE_LEVEL_ALL},
395 	[QDF_MODULE_ID_SME] = {QDF_TRACE_LEVEL_ALL},
396 	[QDF_MODULE_ID_PE] = {QDF_TRACE_LEVEL_ALL},
397 	[QDF_MODULE_ID_WMA] = {QDF_TRACE_LEVEL_ALL},
398 	[QDF_MODULE_ID_SYS] = {QDF_TRACE_LEVEL_ALL},
399 	[QDF_MODULE_ID_QDF] = {QDF_TRACE_LEVEL_ALL},
400 	[QDF_MODULE_ID_SAP] = {QDF_TRACE_LEVEL_ALL},
401 	[QDF_MODULE_ID_HDD_SOFTAP] = {QDF_TRACE_LEVEL_ALL},
402 	[QDF_MODULE_ID_HDD_DATA] = {QDF_DATA_PATH_TRACE_LEVEL},
403 	[QDF_MODULE_ID_HDD_SAP_DATA] = {QDF_DATA_PATH_TRACE_LEVEL},
404 	[QDF_MODULE_ID_HIF] = {QDF_DATA_PATH_TRACE_LEVEL},
405 	[QDF_MODULE_ID_HTC] = {QDF_DATA_PATH_TRACE_LEVEL},
406 	[QDF_MODULE_ID_TXRX] = {QDF_DATA_PATH_TRACE_LEVEL},
407 	[QDF_MODULE_ID_HAL] = {QDF_DATA_PATH_TRACE_LEVEL},
408 	[QDF_MODULE_ID_QDF_DEVICE] = {QDF_TRACE_LEVEL_ALL},
409 	[QDF_MODULE_ID_CFG] = {QDF_TRACE_LEVEL_ALL},
410 	[QDF_MODULE_ID_BMI] = {QDF_TRACE_LEVEL_ALL},
411 	[QDF_MODULE_ID_EPPING] = {QDF_TRACE_LEVEL_ALL},
412 	[QDF_MODULE_ID_QVIT] = {QDF_TRACE_LEVEL_ALL},
413 	[QDF_MODULE_ID_DP] = {QDF_DATA_PATH_TRACE_LEVEL},
414 	[QDF_MODULE_ID_DP_TX_CAPTURE] = {QDF_DATA_PATH_TRACE_LEVEL},
415 	[QDF_MODULE_ID_DP_INIT] = {QDF_DATA_PATH_TRACE_LEVEL},
416 	[QDF_MODULE_ID_DP_STATS] = {QDF_DATA_PATH_TRACE_LEVEL},
417 	[QDF_MODULE_ID_DP_HTT] = {QDF_DATA_PATH_TRACE_LEVEL},
418 	[QDF_MODULE_ID_DP_PEER] = {QDF_DATA_PATH_TRACE_LEVEL},
419 	[QDF_MODULE_ID_DP_HTT_TX_STATS] = {QDF_DATA_PATH_TRACE_LEVEL},
420 	[QDF_MODULE_ID_DP_REO] = {QDF_DATA_PATH_TRACE_LEVEL},
421 	[QDF_MODULE_ID_DP_VDEV] = {QDF_DATA_PATH_TRACE_LEVEL},
422 	[QDF_MODULE_ID_DP_CDP] = {QDF_DATA_PATH_TRACE_LEVEL},
423 	[QDF_MODULE_ID_DP_UMAC_RESET] = {QDF_DATA_PATH_TRACE_LEVEL},
424 	[QDF_MODULE_ID_DP_SAWF] = {QDF_DATA_PATH_TRACE_LEVEL},
425 	[QDF_MODULE_ID_SOC] = {QDF_TRACE_LEVEL_ALL},
426 	[QDF_MODULE_ID_OS_IF] = {QDF_TRACE_LEVEL_ALL},
427 	[QDF_MODULE_ID_TARGET_IF] = {QDF_TRACE_LEVEL_ALL},
428 	[QDF_MODULE_ID_SCHEDULER] = {QDF_TRACE_LEVEL_ALL},
429 	[QDF_MODULE_ID_MGMT_TXRX] = {QDF_TRACE_LEVEL_ALL},
430 	[QDF_MODULE_ID_PMO] = {QDF_TRACE_LEVEL_ALL},
431 	[QDF_MODULE_ID_SCAN] = {QDF_TRACE_LEVEL_ALL},
432 	[QDF_MODULE_ID_POLICY_MGR] = {QDF_TRACE_LEVEL_ALL},
433 	[QDF_MODULE_ID_P2P] = {QDF_TRACE_LEVEL_ALL},
434 	[QDF_MODULE_ID_TDLS] = {QDF_TRACE_LEVEL_ALL},
435 	[QDF_MODULE_ID_REGULATORY] = {QDF_TRACE_LEVEL_ALL},
436 	[QDF_MODULE_ID_SERIALIZATION] = {QDF_TRACE_LEVEL_ALL},
437 	[QDF_MODULE_ID_DFS] = {QDF_TRACE_LEVEL_ALL},
438 	[QDF_MODULE_ID_OBJ_MGR] = {QDF_TRACE_LEVEL_ALL},
439 	[QDF_MODULE_ID_ROAM_DEBUG] = {QDF_TRACE_LEVEL_ALL},
440 	[QDF_MODULE_ID_GREEN_AP] = {QDF_TRACE_LEVEL_ALL},
441 	[QDF_MODULE_ID_OCB] = {QDF_TRACE_LEVEL_ALL},
442 	[QDF_MODULE_ID_IPA] = {QDF_TRACE_LEVEL_ALL},
443 	[QDF_MODULE_ID_ACTION_OUI] = {QDF_TRACE_LEVEL_ALL},
444 	[QDF_MODULE_ID_CONFIG] = {QDF_TRACE_LEVEL_ALL},
445 	[QDF_MODULE_ID_MLME] = {QDF_TRACE_LEVEL_ALL},
446 	[QDF_MODULE_ID_TARGET] = {QDF_TRACE_LEVEL_ALL},
447 	[QDF_MODULE_ID_CRYPTO] = {QDF_TRACE_LEVEL_ALL},
448 	[QDF_MODULE_ID_FWOL] = {QDF_TRACE_LEVEL_ALL},
449 	[QDF_MODULE_ID_SM_ENGINE] = {QDF_TRACE_LEVEL_ALL},
450 	[QDF_MODULE_ID_CMN_MLME] = {QDF_TRACE_LEVEL_ALL},
451 	[QDF_MODULE_ID_NAN] = {QDF_TRACE_LEVEL_ALL},
452 	[QDF_MODULE_ID_CP_STATS] = {QDF_TRACE_LEVEL_ALL},
453 	[QDF_MODULE_ID_DCS] = {QDF_TRACE_LEVEL_ALL},
454 	[QDF_MODULE_ID_INTEROP_ISSUES_AP] = {QDF_TRACE_LEVEL_ALL},
455 	[QDF_MODULE_ID_DENYLIST_MGR] = {QDF_TRACE_LEVEL_ALL},
456 	[QDF_MODULE_ID_DIRECT_BUF_RX] = {QDF_TRACE_LEVEL_ALL},
457 	[QDF_MODULE_ID_SPECTRAL] = {QDF_TRACE_LEVEL_ALL},
458 	[QDF_MODULE_ID_WIFIPOS] = {QDF_TRACE_LEVEL_ALL},
459 	[QDF_MODULE_ID_PKT_CAPTURE] = {QDF_TRACE_LEVEL_ALL},
460 	[QDF_MODULE_ID_FTM_TIME_SYNC] = {QDF_TRACE_LEVEL_ALL},
461 	[QDF_MODULE_ID_CFR] = {QDF_TRACE_LEVEL_ALL},
462 	[QDF_MODULE_ID_IFMGR] = {QDF_TRACE_LEVEL_ALL},
463 	[QDF_MODULE_ID_GPIO] = {QDF_TRACE_LEVEL_ALL},
464 	[QDF_MODULE_ID_T2LM] = {QDF_TRACE_LEVEL_ALL},
465 	[QDF_MODULE_ID_MLO] = {QDF_TRACE_LEVEL_ALL},
466 	[QDF_MODULE_ID_SON] = {QDF_TRACE_LEVEL_ALL},
467 	[QDF_MODULE_ID_TWT] = {QDF_TRACE_LEVEL_ALL},
468 	[QDF_MODULE_ID_WLAN_PRE_CAC] = {QDF_TRACE_LEVEL_ALL},
469 	[QDF_MODULE_ID_COAP] = {QDF_TRACE_LEVEL_ALL},
470 	[QDF_MODULE_ID_MON_FILTER] = {QDF_DATA_PATH_TRACE_LEVEL},
471 	[QDF_MODULE_ID_LL_SAP] = {QDF_TRACE_LEVEL_ALL},
472 };
473 
474 struct notifier_block hdd_netdev_notifier;
475 
476 struct sock *cesium_nl_srv_sock;
477 #ifdef FEATURE_WLAN_AUTO_SHUTDOWN
478 static void wlan_hdd_auto_shutdown_cb(void);
479 #endif
480 
481 static void hdd_dp_register_callbacks(struct hdd_context *hdd_ctx);
482 
483 bool hdd_adapter_is_ap(struct hdd_adapter *adapter)
484 {
485 	if (!adapter) {
486 		hdd_err("null adapter");
487 		return false;
488 	}
489 
490 	return adapter->device_mode == QDF_SAP_MODE ||
491 		adapter->device_mode == QDF_P2P_GO_MODE;
492 }
493 
494 QDF_STATUS hdd_common_roam_callback(struct wlan_objmgr_psoc *psoc,
495 				    uint8_t session_id,
496 				    struct csr_roam_info *roam_info,
497 				    eRoamCmdStatus roam_status,
498 				    eCsrRoamResult roam_result)
499 {
500 	struct hdd_context *hdd_ctx;
501 	struct hdd_adapter *adapter;
502 	struct wlan_hdd_link_info *link_info;
503 	QDF_STATUS status = QDF_STATUS_SUCCESS;
504 
505 	link_info = wlan_hdd_get_link_info_from_vdev(psoc, session_id);
506 	if (!link_info)
507 		return QDF_STATUS_E_INVAL;
508 
509 	adapter = link_info->adapter;
510 	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
511 	if (!hdd_ctx)
512 		return QDF_STATUS_E_INVAL;
513 
514 	switch (adapter->device_mode) {
515 	case QDF_STA_MODE:
516 	case QDF_NDI_MODE:
517 	case QDF_P2P_CLIENT_MODE:
518 	case QDF_P2P_DEVICE_MODE:
519 		status = hdd_sme_roam_callback(link_info, roam_info,
520 					       roam_status, roam_result);
521 		break;
522 	case QDF_SAP_MODE:
523 	case QDF_P2P_GO_MODE:
524 		status =
525 			wlansap_roam_callback(link_info->session.ap.sap_context,
526 					      roam_info, roam_status,
527 					      roam_result);
528 		break;
529 	default:
530 		hdd_err("Wrong device mode");
531 		break;
532 	}
533 
534 	return status;
535 }
536 
537 void hdd_start_complete(int ret)
538 {
539 	wlan_start_ret_val = ret;
540 	complete_all(&wlan_start_comp);
541 }
542 
543 #ifdef WLAN_FEATURE_LOCAL_PKT_CAPTURE
544 /**
545  * wlan_hdd_lpc_del_monitor_interface() - Delete monitor interface
546  * @hdd_ctx: hdd_ctx
547  * @is_virtual_iface: Is virtual interface
548  *
549  * This function takes care of deleting monitor interface
550  *
551  * Return: none
552  */
553 static void
554 wlan_hdd_lpc_del_monitor_interface(struct hdd_context *hdd_ctx,
555 				   bool is_virtual_iface)
556 {
557 	struct hdd_adapter *adapter;
558 	void *soc;
559 	bool running;
560 
561 	if (!hdd_ctx)
562 		return;
563 
564 	if (!ucfg_dp_is_local_pkt_capture_enabled(hdd_ctx->psoc))
565 		return;
566 
567 	soc = cds_get_context(QDF_MODULE_ID_SOC);
568 	if (!soc)
569 		return;
570 
571 	running = cdp_is_local_pkt_capture_running(soc, OL_TXRX_PDEV_ID);
572 	if (!running)
573 		return;
574 
575 	adapter = hdd_get_adapter(hdd_ctx, QDF_MONITOR_MODE);
576 	if (!adapter) {
577 		hdd_debug("There is no monitor adapter");
578 		return;
579 	}
580 
581 	hdd_debug("lpc: Delete monitor interface");
582 
583 	wlan_hdd_release_intf_addr(hdd_ctx, adapter->mac_addr.bytes);
584 	qdf_zero_macaddr(&adapter->mac_addr);
585 	hdd_stop_adapter(hdd_ctx, adapter);
586 	hdd_deinit_adapter(hdd_ctx, adapter, true);
587 	adapter->is_virtual_iface = is_virtual_iface;
588 	hdd_ctx->lpc_info.mon_adapter = adapter;
589 
590 	hdd_ctx->lpc_info.lpc_wk_scheduled = true;
591 	qdf_sched_work(0, &hdd_ctx->lpc_info.lpc_wk);
592 }
593 
594 void wlan_hdd_lpc_handle_concurrency(struct hdd_context *hdd_ctx,
595 				     bool is_virtual_iface)
596 {
597 	if (policy_mgr_is_sta_mon_concurrency(hdd_ctx->psoc))
598 		wlan_hdd_lpc_del_monitor_interface(hdd_ctx, is_virtual_iface);
599 }
600 
601 bool hdd_lpc_is_work_scheduled(struct hdd_context *hdd_ctx)
602 {
603 	return hdd_ctx->lpc_info.lpc_wk_scheduled;
604 }
605 
606 static void hdd_lpc_work_handler(void *arg)
607 {
608 	struct hdd_context *hdd_ctx = (struct hdd_context *)arg;
609 	struct hdd_adapter *adapter;
610 	struct osif_vdev_sync *vdev_sync;
611 	int errno;
612 
613 	if (!hdd_ctx)
614 		return;
615 
616 	adapter = hdd_ctx->lpc_info.mon_adapter;
617 	if (!adapter) {
618 		hdd_err("There is no monitor adapter");
619 		return;
620 	}
621 
622 	errno = osif_vdev_sync_trans_start_wait(adapter->dev, &vdev_sync);
623 	if (errno)
624 		return;
625 
626 	osif_vdev_sync_unregister(adapter->dev);
627 	osif_vdev_sync_wait_for_ops(vdev_sync);
628 
629 	hdd_close_adapter(hdd_ctx, adapter, true);
630 	hdd_ctx->lpc_info.lpc_wk_scheduled = false;
631 
632 	osif_vdev_sync_trans_stop(vdev_sync);
633 	osif_vdev_sync_destroy(vdev_sync);
634 }
635 
636 static inline
637 void hdd_lp_create_work(struct hdd_context *hdd_ctx)
638 {
639 	hdd_ctx->lpc_info.lpc_wk_scheduled = false;
640 	qdf_create_work(0, &hdd_ctx->lpc_info.lpc_wk, hdd_lpc_work_handler,
641 			hdd_ctx);
642 }
643 
644 static inline
645 void hdd_lpc_delete_work(struct hdd_context *hdd_ctx)
646 {
647 	qdf_flush_work(&hdd_ctx->lpc_info.lpc_wk);
648 	hdd_ctx->lpc_info.lpc_wk_scheduled = false;
649 	qdf_destroy_work(NULL, &hdd_ctx->lpc_info.lpc_wk);
650 }
651 
652 #else
653 static inline
654 void hdd_lp_create_work(struct hdd_context *hdd_ctx)
655 {
656 }
657 
658 static inline
659 void hdd_lpc_delete_work(struct hdd_context *hdd_ctx)
660 {
661 }
662 
663 static inline
664 void wlan_hdd_lpc_del_monitor_interface(struct hdd_context *hdd_ctx,
665 					bool is_virtual_iface)
666 {
667 }
668 #endif
669 
670 #ifdef QCA_HL_NETDEV_FLOW_CONTROL
671 void wlan_hdd_mod_fc_timer(struct hdd_adapter *adapter,
672 			   enum netif_action_type action)
673 {
674 	struct hdd_stats *hdd_stats;
675 
676 	if (!adapter->tx_flow_timer_initialized)
677 		return;
678 
679 	hdd_stats = &adapter->deflink->hdd_stats;
680 	if (action == WLAN_WAKE_NON_PRIORITY_QUEUE) {
681 		qdf_mc_timer_stop(&adapter->tx_flow_control_timer);
682 		hdd_stats->tx_rx_stats.is_txflow_paused = false;
683 		hdd_stats->tx_rx_stats.txflow_unpause_cnt++;
684 	} else if (action == WLAN_STOP_NON_PRIORITY_QUEUE) {
685 		QDF_STATUS status =
686 		qdf_mc_timer_start(&adapter->tx_flow_control_timer,
687 				   WLAN_HDD_TX_FLOW_CONTROL_OS_Q_BLOCK_TIME);
688 
689 		if (!QDF_IS_STATUS_SUCCESS(status))
690 			hdd_err("Failed to start tx_flow_control_timer");
691 		else
692 			hdd_stats->tx_rx_stats.txflow_timer_cnt++;
693 
694 		hdd_stats->tx_rx_stats.txflow_pause_cnt++;
695 		hdd_stats->tx_rx_stats.is_txflow_paused = true;
696 	}
697 }
698 #endif /* QCA_HL_NETDEV_FLOW_CONTROL */
699 
700 /**
701  * wlan_hdd_txrx_pause_cb() - pause callback from txrx layer
702  * @vdev_id: vdev_id
703  * @action: action type
704  * @reason: reason type
705  *
706  * Return: none
707  */
708 void wlan_hdd_txrx_pause_cb(uint8_t vdev_id,
709 		enum netif_action_type action, enum netif_reason_type reason)
710 {
711 	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
712 	struct hdd_adapter *adapter;
713 	struct wlan_hdd_link_info *link_info;
714 
715 	if (!hdd_ctx)
716 		return;
717 
718 	link_info = hdd_get_link_info_by_vdev(hdd_ctx, vdev_id);
719 	if (!link_info)
720 		return;
721 
722 	adapter =  link_info->adapter;
723 	wlan_hdd_mod_fc_timer(adapter, action);
724 	wlan_hdd_netif_queue_control(adapter, action, reason);
725 }
726 
727 /*
728  * Store WLAN driver version and timestamp info in global variables such that
729  * crash debugger can extract them from driver debug symbol and crashdump for
730  * post processing
731  */
732 #ifdef BUILD_TAG
733 uint8_t g_wlan_driver_version[] = QWLAN_VERSIONSTR TIMER_MANAGER_STR MEMORY_DEBUG_STR PANIC_ON_BUG_STR "; " BUILD_TAG;
734 #else
735 uint8_t g_wlan_driver_version[] = QWLAN_VERSIONSTR TIMER_MANAGER_STR MEMORY_DEBUG_STR PANIC_ON_BUG_STR;
736 #endif
737 
738 int hdd_validate_channel_and_bandwidth(struct hdd_adapter *adapter,
739 				       qdf_freq_t chan_freq,
740 				       enum phy_ch_width chan_bw)
741 {
742 	struct ch_params ch_params = {0};
743 	struct hdd_context *hdd_ctx;
744 
745 	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
746 	if (!hdd_ctx) {
747 		hdd_err("hdd context is NULL");
748 		return -EINVAL;
749 	}
750 
751 	if (reg_is_chan_enum_invalid(
752 			wlan_reg_get_chan_enum_for_freq(chan_freq))) {
753 		hdd_err("Channel freq %d not in driver's valid channel list", chan_freq);
754 		return -EOPNOTSUPP;
755 	}
756 
757 	if ((!WLAN_REG_IS_24GHZ_CH_FREQ(chan_freq)) &&
758 	    (!WLAN_REG_IS_5GHZ_CH_FREQ(chan_freq)) &&
759 	    (!WLAN_REG_IS_6GHZ_CHAN_FREQ(chan_freq))) {
760 		hdd_err("CH %d is not in 2.4GHz or 5GHz or 6GHz", chan_freq);
761 		return -EINVAL;
762 	}
763 	ch_params.ch_width = CH_WIDTH_MAX;
764 	wlan_reg_set_channel_params_for_pwrmode(hdd_ctx->pdev, chan_freq,
765 						0, &ch_params,
766 						REG_CURRENT_PWR_MODE);
767 	if (ch_params.ch_width == CH_WIDTH_MAX) {
768 		hdd_err("failed to get max bandwdith for %d", chan_freq);
769 		return -EINVAL;
770 	}
771 	if (WLAN_REG_IS_24GHZ_CH_FREQ(chan_freq)) {
772 		if (chan_bw == CH_WIDTH_80MHZ) {
773 			hdd_err("BW80 not possible in 2.4GHz band");
774 			return -EINVAL;
775 		}
776 		if ((chan_bw != CH_WIDTH_20MHZ) &&
777 		    (chan_freq == wlan_reg_ch_to_freq(CHAN_ENUM_2484)) &&
778 		    (chan_bw != CH_WIDTH_MAX) &&
779 		    (ch_params.ch_width == CH_WIDTH_20MHZ)) {
780 			hdd_err("Only BW20 possible on channel freq 2484");
781 			return -EINVAL;
782 		}
783 	}
784 
785 	if (WLAN_REG_IS_5GHZ_CH_FREQ(chan_freq)) {
786 		if ((chan_bw != CH_WIDTH_20MHZ) &&
787 		    (chan_freq == wlan_reg_ch_to_freq(CHAN_ENUM_5825)) &&
788 		    (chan_bw != CH_WIDTH_MAX) &&
789 		    (ch_params.ch_width == CH_WIDTH_20MHZ)) {
790 			hdd_err("Only BW20 possible on channel freq 5825");
791 			return -EINVAL;
792 		}
793 	}
794 
795 	return 0;
796 }
797 
798 uint32_t hdd_get_link_info_home_channel(struct wlan_hdd_link_info *link_info)
799 {
800 	uint32_t home_chan_freq = 0;
801 	enum QDF_OPMODE opmode = link_info->adapter->device_mode;
802 
803 	switch (opmode) {
804 	case QDF_SAP_MODE:
805 	case QDF_P2P_GO_MODE:
806 		if (test_bit(SOFTAP_BSS_STARTED, &link_info->link_flags)) {
807 			home_chan_freq =
808 				link_info->session.ap.operating_chan_freq;
809 		}
810 		break;
811 	case QDF_STA_MODE:
812 	case QDF_P2P_CLIENT_MODE:
813 		if (hdd_cm_is_vdev_associated(link_info)) {
814 			home_chan_freq =
815 				link_info->session.station.conn_info.chan_freq;
816 		}
817 		break;
818 	default:
819 		break;
820 	}
821 
822 	return home_chan_freq;
823 }
824 
825 enum phy_ch_width hdd_get_link_info_width(struct wlan_hdd_link_info *link_info)
826 {
827 	enum phy_ch_width width = CH_WIDTH_20MHZ;
828 	enum QDF_OPMODE opmode = link_info->adapter->device_mode;
829 
830 	switch (opmode) {
831 	case QDF_SAP_MODE:
832 	case QDF_P2P_GO_MODE:
833 		if (test_bit(SOFTAP_BSS_STARTED, &link_info->link_flags)) {
834 			struct hdd_ap_ctx *ap_ctx =
835 					WLAN_HDD_GET_AP_CTX_PTR(link_info);
836 
837 			width = ap_ctx->sap_config.ch_params.ch_width;
838 		}
839 		break;
840 	case QDF_STA_MODE:
841 	case QDF_P2P_CLIENT_MODE:
842 		if (hdd_cm_is_vdev_associated(link_info))
843 			width = link_info->session.station.conn_info.ch_width;
844 		break;
845 	default:
846 		break;
847 	}
848 
849 	return width;
850 }
851 
852 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
853 static inline struct net_device *hdd_net_dev_from_notifier(void *context)
854 {
855 	struct netdev_notifier_info *info = context;
856 
857 	return info->dev;
858 }
859 #else
860 static inline struct net_device *hdd_net_dev_from_notifier(void *context)
861 {
862 	return context;
863 }
864 #endif
865 
866 static int __hdd_netdev_notifier_call(struct net_device *net_dev,
867 				      unsigned long state)
868 {
869 	struct hdd_adapter *adapter;
870 	struct hdd_context *hdd_ctx;
871 	struct wlan_objmgr_vdev *vdev;
872 
873 	hdd_enter_dev(net_dev);
874 
875 	if (!net_dev->ieee80211_ptr) {
876 		hdd_debug("ieee80211_ptr is null");
877 		return NOTIFY_DONE;
878 	}
879 
880 	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
881 	if (!hdd_ctx)
882 		return NOTIFY_DONE;
883 
884 	if (hdd_ctx->driver_status == DRIVER_MODULES_CLOSED) {
885 		hdd_debug("Driver module is closed");
886 		return NOTIFY_DONE;
887 	}
888 
889 	/* Make sure that this callback corresponds to our device. */
890 	adapter = hdd_get_adapter_by_iface_name(hdd_ctx, net_dev->name);
891 	if (!adapter) {
892 		hdd_debug("failed to look up adapter for '%s'", net_dev->name);
893 		return NOTIFY_DONE;
894 	}
895 
896 	if (adapter != WLAN_HDD_GET_PRIV_PTR(net_dev)) {
897 		hdd_err("HDD adapter mismatch!");
898 		return NOTIFY_DONE;
899 	}
900 
901 	if (cds_is_driver_recovering()) {
902 		hdd_debug("Driver is recovering");
903 		return NOTIFY_DONE;
904 	}
905 
906 	if (cds_is_driver_in_bad_state()) {
907 		hdd_debug("Driver is in failed recovery state");
908 		return NOTIFY_DONE;
909 	}
910 
911 	hdd_debug("%s New Net Device State = %lu, flags 0x%x",
912 		  net_dev->name, state, net_dev->flags);
913 
914 	switch (state) {
915 	case NETDEV_REGISTER:
916 		break;
917 
918 	case NETDEV_UNREGISTER:
919 		break;
920 
921 	case NETDEV_UP:
922 		sme_ch_avoid_update_req(hdd_ctx->mac_handle);
923 		break;
924 
925 	case NETDEV_DOWN:
926 		break;
927 
928 	case NETDEV_CHANGE:
929 		if (adapter->is_link_up_service_needed)
930 			complete(&adapter->linkup_event_var);
931 		break;
932 
933 	case NETDEV_GOING_DOWN:
934 		vdev = hdd_objmgr_get_vdev_by_user(adapter->deflink,
935 						   WLAN_OSIF_SCAN_ID);
936 		if (!vdev)
937 			break;
938 		if (ucfg_scan_get_vdev_status(vdev) !=
939 				SCAN_NOT_IN_PROGRESS) {
940 			wlan_abort_scan(hdd_ctx->pdev, INVAL_PDEV_ID,
941 					adapter->deflink->vdev_id,
942 					INVALID_SCAN_ID, true);
943 		}
944 		hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_SCAN_ID);
945 		cds_flush_work(&adapter->scan_block_work);
946 		/* Need to clean up blocked scan request */
947 		wlan_hdd_cfg80211_scan_block(adapter);
948 		hdd_debug("Scan is not Pending from user");
949 		/*
950 		 * After NETDEV_GOING_DOWN, kernel calls hdd_stop.Irrespective
951 		 * of return status of hdd_stop call, kernel resets the IFF_UP
952 		 * flag after which driver does not send the cfg80211_scan_done.
953 		 * Ensure to cleanup the scan queue in NETDEV_GOING_DOWN
954 		 */
955 		wlan_cfg80211_cleanup_scan_queue(hdd_ctx->pdev, net_dev);
956 		break;
957 	case NETDEV_FEAT_CHANGE:
958 		hdd_debug("vdev %d netdev Feature 0x%llx\n",
959 			  adapter->deflink->vdev_id, net_dev->features);
960 		break;
961 	default:
962 		break;
963 	}
964 
965 	return NOTIFY_DONE;
966 }
967 
968 static int hdd_netdev_notifier_bridge_intf(struct net_device *net_dev,
969 					   unsigned long state)
970 {
971 	struct hdd_adapter *adapter, *next_adapter = NULL;
972 	wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_GET_ADAPTER;
973 	struct hdd_context *hdd_ctx;
974 	QDF_STATUS status;
975 
976 	hdd_enter_dev(net_dev);
977 
978 	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
979 	if (wlan_hdd_validate_context(hdd_ctx))
980 		return NOTIFY_DONE;
981 
982 	hdd_debug("%s New Net Device State = %lu, flags 0x%x bridge mac address: "QDF_MAC_ADDR_FMT,
983 		  net_dev->name, state, net_dev->flags, QDF_MAC_ADDR_REF(net_dev->dev_addr));
984 
985 	if (!qdf_mem_cmp(hdd_ctx->bridgeaddr, net_dev->dev_addr,
986 			 QDF_MAC_ADDR_SIZE))
987 		return NOTIFY_DONE;
988 
989 	switch (state) {
990 	case NETDEV_REGISTER:
991 	case NETDEV_CHANGEADDR:
992 		/* Update FW WoW pattern with new MAC address */
993 		qdf_mem_copy(hdd_ctx->bridgeaddr, net_dev->dev_addr,
994 			     QDF_MAC_ADDR_SIZE);
995 
996 		hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
997 						   dbgid) {
998 			if (adapter->device_mode != QDF_SAP_MODE)
999 				goto loop_next;
1000 
1001 			if (wlan_hdd_validate_vdev_id(adapter->deflink->vdev_id))
1002 				goto loop_next;
1003 
1004 			status = wlan_objmgr_vdev_try_get_ref(adapter->deflink->vdev,
1005 							      WLAN_HDD_ID_OBJ_MGR);
1006 			if (QDF_IS_STATUS_ERROR(status))
1007 				goto loop_next;
1008 
1009 			ucfg_pmo_set_vdev_bridge_addr(adapter->deflink->vdev,
1010 				(struct qdf_mac_addr *)hdd_ctx->bridgeaddr);
1011 			ucfg_pmo_del_wow_pattern(adapter->deflink->vdev);
1012 			ucfg_pmo_register_wow_default_patterns(adapter->deflink->vdev);
1013 
1014 			wlan_objmgr_vdev_release_ref(adapter->deflink->vdev,
1015 						     WLAN_HDD_ID_OBJ_MGR);
1016 
1017 loop_next:
1018 			hdd_adapter_dev_put_debug(adapter, dbgid);
1019 		}
1020 
1021 		break;
1022 	case NETDEV_UNREGISTER:
1023 		qdf_zero_macaddr((struct qdf_mac_addr *)hdd_ctx->bridgeaddr);
1024 		break;
1025 	default:
1026 		break;
1027 	}
1028 
1029 	return NOTIFY_DONE;
1030 }
1031 
1032 /**
1033  * hdd_netdev_notifier_call() - netdev notifier callback function
1034  * @nb: pointer to notifier block
1035  * @state: state
1036  * @context: notifier callback context pointer
1037  *
1038  * Return: 0 on success, error number otherwise.
1039  */
1040 static int hdd_netdev_notifier_call(struct notifier_block *nb,
1041 					unsigned long state,
1042 					void *context)
1043 {
1044 	struct net_device *net_dev = hdd_net_dev_from_notifier(context);
1045 	struct osif_vdev_sync *vdev_sync;
1046 	int errno;
1047 
1048 	if (net_dev->priv_flags & IFF_EBRIDGE) {
1049 		errno = hdd_netdev_notifier_bridge_intf(net_dev, state);
1050 		if (errno)
1051 			return NOTIFY_DONE;
1052 	}
1053 
1054 	errno = osif_vdev_sync_op_start(net_dev, &vdev_sync);
1055 	if (errno) {
1056 		hdd_debug("%s New Net Device State = %lu, flags 0x%x NOTIFY_DONE",
1057 			  net_dev->name, state, net_dev->flags);
1058 		return NOTIFY_DONE;
1059 	}
1060 
1061 	errno = __hdd_netdev_notifier_call(net_dev, state);
1062 
1063 	osif_vdev_sync_op_stop(vdev_sync);
1064 
1065 	return NOTIFY_DONE;
1066 }
1067 
1068 struct notifier_block hdd_netdev_notifier = {
1069 	.notifier_call = hdd_netdev_notifier_call,
1070 };
1071 
1072 /* variable to hold the insmod parameters */
1073 int con_mode;
1074 #ifdef FEATURE_WLAN_RESIDENT_DRIVER
1075 EXPORT_SYMBOL(con_mode);
1076 #endif
1077 
1078 int con_mode_ftm;
1079 #ifdef FEATURE_WLAN_RESIDENT_DRIVER
1080 EXPORT_SYMBOL(con_mode_ftm);
1081 #endif
1082 int con_mode_epping;
1083 
1084 static int pcie_gen_speed;
1085 
1086 /* Variable to hold connection mode including module parameter con_mode */
1087 static int curr_con_mode;
1088 
1089 #if defined(WLAN_FEATURE_11BE) && defined(CFG80211_11BE_BASIC)
1090 static enum phy_ch_width hdd_get_eht_phy_ch_width_from_target(void)
1091 {
1092 	uint32_t max_fw_bw = sme_get_eht_ch_width();
1093 
1094 	if (max_fw_bw == WNI_CFG_EHT_CHANNEL_WIDTH_320MHZ)
1095 		return CH_WIDTH_320MHZ;
1096 	else if (max_fw_bw == WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ)
1097 		return CH_WIDTH_160MHZ;
1098 	else
1099 		return CH_WIDTH_80MHZ;
1100 }
1101 
1102 static bool hdd_is_target_eht_phy_ch_width_supported(enum phy_ch_width width)
1103 {
1104 	enum phy_ch_width max_fw_bw = hdd_get_eht_phy_ch_width_from_target();
1105 
1106 	if (width <= max_fw_bw)
1107 		return true;
1108 
1109 	hdd_err("FW does not support this BW %d max BW supported %d",
1110 		width, max_fw_bw);
1111 	return false;
1112 }
1113 
1114 static bool hdd_is_target_eht_160mhz_capable(void)
1115 {
1116 	return hdd_is_target_eht_phy_ch_width_supported(CH_WIDTH_160MHZ);
1117 }
1118 
1119 static enum phy_ch_width
1120 wlan_hdd_map_nl_chan_width(enum nl80211_chan_width width)
1121 {
1122 	if (width == NL80211_CHAN_WIDTH_320) {
1123 		return hdd_get_eht_phy_ch_width_from_target();
1124 	} else {
1125 		hdd_err("Invalid channel width %d, setting to default", width);
1126 		return CH_WIDTH_INVALID;
1127 	}
1128 }
1129 
1130 #else /* !WLAN_FEATURE_11BE */
1131 static inline bool
1132 hdd_is_target_eht_phy_ch_width_supported(enum phy_ch_width width)
1133 {
1134 	return true;
1135 }
1136 
1137 static inline bool hdd_is_target_eht_160mhz_capable(void)
1138 {
1139 	return false;
1140 }
1141 
1142 static enum phy_ch_width
1143 wlan_hdd_map_nl_chan_width(enum nl80211_chan_width width)
1144 {
1145 	hdd_err("Invalid channel width %d, setting to default", width);
1146 	return CH_WIDTH_INVALID;
1147 }
1148 #endif /* WLAN_FEATURE_11BE */
1149 
1150 /**
1151  * hdd_map_nl_chan_width() - Map NL channel width to internal representation
1152  * @ch_width: NL channel width
1153  *
1154  * Converts the NL channel width to the driver's internal representation
1155  *
1156  * Return: Converted channel width. In case of non matching NL channel width,
1157  * CH_WIDTH_MAX will be returned.
1158  */
1159 enum phy_ch_width hdd_map_nl_chan_width(enum nl80211_chan_width ch_width)
1160 {
1161 	uint8_t fw_ch_bw;
1162 
1163 	fw_ch_bw = wma_get_vht_ch_width();
1164 	switch (ch_width) {
1165 	case NL80211_CHAN_WIDTH_20_NOHT:
1166 	case NL80211_CHAN_WIDTH_20:
1167 		return CH_WIDTH_20MHZ;
1168 	case NL80211_CHAN_WIDTH_40:
1169 		return CH_WIDTH_40MHZ;
1170 	case NL80211_CHAN_WIDTH_80:
1171 		return CH_WIDTH_80MHZ;
1172 	case NL80211_CHAN_WIDTH_80P80:
1173 		if (fw_ch_bw == WNI_CFG_VHT_CHANNEL_WIDTH_80_PLUS_80MHZ)
1174 			return CH_WIDTH_80P80MHZ;
1175 		else if (fw_ch_bw == WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ)
1176 			return CH_WIDTH_160MHZ;
1177 		else
1178 			return CH_WIDTH_80MHZ;
1179 	case NL80211_CHAN_WIDTH_160:
1180 		if (hdd_is_target_eht_160mhz_capable())
1181 			return CH_WIDTH_160MHZ;
1182 
1183 		if (fw_ch_bw >= WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ)
1184 			return CH_WIDTH_160MHZ;
1185 		else
1186 			return CH_WIDTH_80MHZ;
1187 	case NL80211_CHAN_WIDTH_5:
1188 		return CH_WIDTH_5MHZ;
1189 	case NL80211_CHAN_WIDTH_10:
1190 		return CH_WIDTH_10MHZ;
1191 	default:
1192 		return wlan_hdd_map_nl_chan_width(ch_width);
1193 	}
1194 }
1195 
1196 #if defined(WLAN_FEATURE_NAN) && \
1197 	   (KERNEL_VERSION(4, 9, 0) <= LINUX_VERSION_CODE)
1198 /**
1199  * wlan_hdd_convert_nan_type() - Convert nl type to qdf type
1200  * @nl_type: NL80211 interface type
1201  * @out_qdf_type: QDF type for the given nl_type
1202  *
1203  * Convert nl type to QDF type
1204  *
1205  * Return: QDF_STATUS_SUCCESS if converted, failure otherwise.
1206  */
1207 static QDF_STATUS wlan_hdd_convert_nan_type(enum nl80211_iftype nl_type,
1208 					    enum QDF_OPMODE *out_qdf_type)
1209 {
1210 	if (nl_type == NL80211_IFTYPE_NAN) {
1211 		*out_qdf_type = QDF_NAN_DISC_MODE;
1212 		return QDF_STATUS_SUCCESS;
1213 	}
1214 	return QDF_STATUS_E_INVAL;
1215 }
1216 
1217 /**
1218  * wlan_hdd_set_nan_if_type() - Set the NAN iftype
1219  * @adapter: pointer to HDD adapter
1220  *
1221  * Set the NL80211_IFTYPE_NAN to wdev iftype.
1222  *
1223  * Return: None
1224  */
1225 static void wlan_hdd_set_nan_if_type(struct hdd_adapter *adapter)
1226 {
1227 	adapter->wdev.iftype = NL80211_IFTYPE_NAN;
1228 }
1229 
1230 static bool wlan_hdd_is_vdev_creation_allowed(struct wlan_objmgr_psoc *psoc)
1231 {
1232 	return ucfg_nan_is_vdev_creation_allowed(psoc);
1233 }
1234 #else
1235 static QDF_STATUS wlan_hdd_convert_nan_type(enum nl80211_iftype nl_type,
1236 					    enum QDF_OPMODE *out_qdf_type)
1237 {
1238 	return QDF_STATUS_E_INVAL;
1239 }
1240 
1241 static void wlan_hdd_set_nan_if_type(struct hdd_adapter *adapter)
1242 {
1243 }
1244 
1245 static bool wlan_hdd_is_vdev_creation_allowed(struct wlan_objmgr_psoc *psoc)
1246 {
1247 	return false;
1248 }
1249 #endif
1250 
1251 QDF_STATUS hdd_nl_to_qdf_iface_type(enum nl80211_iftype nl_type,
1252 				    enum QDF_OPMODE *out_qdf_type)
1253 {
1254 	QDF_STATUS status = QDF_STATUS_SUCCESS;
1255 
1256 	switch (nl_type) {
1257 	case NL80211_IFTYPE_AP:
1258 		*out_qdf_type = QDF_SAP_MODE;
1259 		break;
1260 	case NL80211_IFTYPE_MONITOR:
1261 		*out_qdf_type = QDF_MONITOR_MODE;
1262 		break;
1263 	case NL80211_IFTYPE_OCB:
1264 		*out_qdf_type = QDF_OCB_MODE;
1265 		break;
1266 	case NL80211_IFTYPE_P2P_CLIENT:
1267 		*out_qdf_type = QDF_P2P_CLIENT_MODE;
1268 		break;
1269 	case NL80211_IFTYPE_P2P_DEVICE:
1270 		*out_qdf_type = QDF_P2P_DEVICE_MODE;
1271 		break;
1272 	case NL80211_IFTYPE_P2P_GO:
1273 		*out_qdf_type = QDF_P2P_GO_MODE;
1274 		break;
1275 	case NL80211_IFTYPE_STATION:
1276 		*out_qdf_type = QDF_STA_MODE;
1277 		break;
1278 	case NL80211_IFTYPE_WDS:
1279 		*out_qdf_type = QDF_WDS_MODE;
1280 		break;
1281 	default:
1282 		status = wlan_hdd_convert_nan_type(nl_type, out_qdf_type);
1283 		if (QDF_IS_STATUS_SUCCESS(status))
1284 			break;
1285 		hdd_err("Invalid nl80211 interface type %d", nl_type);
1286 		return QDF_STATUS_E_INVAL;
1287 	}
1288 
1289 	return QDF_STATUS_SUCCESS;
1290 }
1291 
1292 uint8_t wlan_hdd_find_opclass(mac_handle_t mac_handle, uint8_t channel,
1293 			      uint8_t bw_offset)
1294 {
1295 	uint8_t opclass = 0;
1296 
1297 	sme_get_opclass(mac_handle, channel, bw_offset, &opclass);
1298 	return opclass;
1299 }
1300 
1301 /**
1302  * hdd_qdf_trace_enable() - configure initial QDF Trace enable
1303  * @module_id:	Module whose trace level is being configured
1304  * @bitmask:	Bitmask of log levels to be enabled
1305  *
1306  * Called immediately after the cfg.ini is read in order to configure
1307  * the desired trace levels.
1308  *
1309  * Return: None
1310  */
1311 int hdd_qdf_trace_enable(QDF_MODULE_ID module_id, uint32_t bitmask)
1312 {
1313 	QDF_TRACE_LEVEL level;
1314 	int qdf_print_idx = -1;
1315 	int status = -1;
1316 	/*
1317 	 * if the bitmask is the default value, then a bitmask was not
1318 	 * specified in cfg.ini, so leave the logging level alone (it
1319 	 * will remain at the "compiled in" default value)
1320 	 */
1321 	if (CFG_QDF_TRACE_ENABLE_DEFAULT == bitmask)
1322 		return 0;
1323 
1324 	qdf_print_idx = qdf_get_pidx();
1325 
1326 	/* a mask was specified.  start by disabling all logging */
1327 	status = qdf_print_set_category_verbose(qdf_print_idx, module_id,
1328 					QDF_TRACE_LEVEL_NONE, 0);
1329 
1330 	if (QDF_STATUS_SUCCESS != status)
1331 		return -EINVAL;
1332 	/* now cycle through the bitmask until all "set" bits are serviced */
1333 	level = QDF_TRACE_LEVEL_NONE;
1334 	while (0 != bitmask) {
1335 		if (bitmask & 1) {
1336 			status = qdf_print_set_category_verbose(qdf_print_idx,
1337 							module_id, level, 1);
1338 			if (QDF_STATUS_SUCCESS != status)
1339 				return -EINVAL;
1340 		}
1341 
1342 		level++;
1343 		bitmask >>= 1;
1344 	}
1345 	return 0;
1346 }
1347 
1348 int __wlan_hdd_validate_context(struct hdd_context *hdd_ctx, const char *func)
1349 {
1350 	if (!hdd_ctx) {
1351 		hdd_err("HDD context is null (via %s)", func);
1352 		return -ENODEV;
1353 	}
1354 
1355 	if (!hdd_ctx->config) {
1356 		hdd_err("HDD config is null (via %s)", func);
1357 		return -ENODEV;
1358 	}
1359 
1360 	if (cds_is_driver_recovering()) {
1361 		hdd_debug("Recovery in progress (via %s); state:0x%x",
1362 			  func, cds_get_driver_state());
1363 		return -EAGAIN;
1364 	}
1365 
1366 	if (cds_is_load_or_unload_in_progress()) {
1367 		hdd_debug("Load/unload in progress (via %s); state:0x%x",
1368 			  func, cds_get_driver_state());
1369 		return -EAGAIN;
1370 	}
1371 
1372 	if (cds_is_driver_in_bad_state()) {
1373 		hdd_debug("Driver in bad state (via %s); state:0x%x",
1374 			  func, cds_get_driver_state());
1375 		return -EAGAIN;
1376 	}
1377 
1378 	if (cds_is_fw_down()) {
1379 		hdd_debug("FW is down (via %s); state:0x%x",
1380 			  func, cds_get_driver_state());
1381 		return -EAGAIN;
1382 	}
1383 
1384 	if (hdd_ctx->is_wlan_disabled) {
1385 		hdd_debug("WLAN is disabled by user space");
1386 		return -EAGAIN;
1387 	}
1388 
1389 	return 0;
1390 }
1391 
1392 int __hdd_validate_adapter(struct hdd_adapter *adapter, const char *func)
1393 {
1394 	if (!adapter) {
1395 		hdd_err("adapter is null (via %s)", func);
1396 		return -EINVAL;
1397 	}
1398 
1399 	if (adapter->magic != WLAN_HDD_ADAPTER_MAGIC) {
1400 		hdd_err("bad adapter magic (via %s)", func);
1401 		return -EINVAL;
1402 	}
1403 
1404 	if (!adapter->dev) {
1405 		hdd_err("adapter net_device is null (via %s)", func);
1406 		return -EINVAL;
1407 	}
1408 
1409 	if (!(adapter->dev->flags & IFF_UP)) {
1410 		hdd_debug_rl("adapter '%s' is not up (via %s)",
1411 			     adapter->dev->name, func);
1412 		return -EAGAIN;
1413 	}
1414 
1415 	return __wlan_hdd_validate_vdev_id(adapter->deflink->vdev_id, func);
1416 }
1417 
1418 int __wlan_hdd_validate_vdev_id(uint8_t vdev_id, const char *func)
1419 {
1420 	if (vdev_id == WLAN_UMAC_VDEV_ID_MAX) {
1421 		hdd_debug_rl("adapter is not up (via %s)", func);
1422 		return -EINVAL;
1423 	}
1424 
1425 	if (vdev_id >= WLAN_MAX_VDEVS) {
1426 		hdd_err("bad vdev Id:%u (via %s)", vdev_id, func);
1427 		return -EINVAL;
1428 	}
1429 
1430 	return 0;
1431 }
1432 
1433 QDF_STATUS __wlan_hdd_validate_mac_address(struct qdf_mac_addr *mac_addr,
1434 					   const char *func)
1435 {
1436 	if (!mac_addr) {
1437 		hdd_err("Received NULL mac address (via %s)", func);
1438 		return QDF_STATUS_E_INVAL;
1439 	}
1440 
1441 	if (qdf_is_macaddr_zero(mac_addr)) {
1442 		hdd_err("MAC is all zero (via %s)", func);
1443 		return QDF_STATUS_E_INVAL;
1444 	}
1445 
1446 	if (qdf_is_macaddr_broadcast(mac_addr)) {
1447 		hdd_err("MAC is Broadcast (via %s)", func);
1448 		return QDF_STATUS_E_INVAL;
1449 	}
1450 
1451 	if (QDF_NET_IS_MAC_MULTICAST(mac_addr->bytes)) {
1452 		hdd_err("MAC is Multicast (via %s)", func);
1453 		return QDF_STATUS_E_INVAL;
1454 	}
1455 
1456 	return QDF_STATUS_SUCCESS;
1457 }
1458 
1459 /**
1460  * wlan_hdd_validate_modules_state() - Check modules status
1461  * @hdd_ctx: HDD context pointer
1462  *
1463  * Check's the driver module's state and returns true if the
1464  * modules are enabled returns false if modules are closed.
1465  *
1466  * Return: True if modules are enabled or false.
1467  */
1468 bool wlan_hdd_validate_modules_state(struct hdd_context *hdd_ctx)
1469 {
1470 	if (hdd_ctx->driver_status != DRIVER_MODULES_ENABLED) {
1471 		hdd_info("Modules not enabled, Present status: %d",
1472 			 hdd_ctx->driver_status);
1473 		return false;
1474 	}
1475 
1476 	return true;
1477 }
1478 
1479 #ifdef FEATURE_RUNTIME_PM
1480 /**
1481  * hdd_runtime_suspend_context_init() - API to initialize HDD Runtime Contexts
1482  * @hdd_ctx: HDD context
1483  *
1484  * Return: None
1485  */
1486 static void hdd_runtime_suspend_context_init(struct hdd_context *hdd_ctx)
1487 {
1488 	struct hdd_runtime_pm_context *ctx = &hdd_ctx->runtime_context;
1489 
1490 	qdf_runtime_lock_init(&ctx->dfs);
1491 	qdf_runtime_lock_init(&ctx->connect);
1492 	qdf_runtime_lock_init(&ctx->user);
1493 	qdf_runtime_lock_init(&ctx->monitor_mode);
1494 	qdf_runtime_lock_init(&ctx->wow_unit_test);
1495 	qdf_runtime_lock_init(&ctx->system_suspend);
1496 	qdf_runtime_lock_init(&ctx->dyn_mac_addr_update);
1497 	qdf_runtime_lock_init(&ctx->vdev_destroy);
1498 	qdf_runtime_lock_init(&ctx->oem_data_cmd);
1499 
1500 	qdf_rtpm_register(QDF_RTPM_ID_WIPHY_SUSPEND, NULL);
1501 	qdf_rtpm_register(QDF_RTPM_ID_PM_QOS_NOTIFY, NULL);
1502 
1503 	ctx->is_user_wakelock_acquired = false;
1504 
1505 	wlan_scan_runtime_pm_init(hdd_ctx->pdev);
1506 }
1507 
1508 /**
1509  * hdd_runtime_suspend_context_deinit() - API to deinit HDD runtime context
1510  * @hdd_ctx: HDD Context
1511  *
1512  * Return: None
1513  */
1514 static void hdd_runtime_suspend_context_deinit(struct hdd_context *hdd_ctx)
1515 {
1516 	struct hdd_runtime_pm_context *ctx = &hdd_ctx->runtime_context;
1517 
1518 	if (ctx->is_user_wakelock_acquired)
1519 		qdf_runtime_pm_allow_suspend(&ctx->user);
1520 
1521 	qdf_runtime_lock_deinit(&ctx->oem_data_cmd);
1522 	qdf_runtime_lock_deinit(&ctx->dyn_mac_addr_update);
1523 	qdf_runtime_lock_deinit(&ctx->wow_unit_test);
1524 	qdf_runtime_lock_deinit(&ctx->monitor_mode);
1525 	qdf_runtime_lock_deinit(&ctx->user);
1526 	qdf_runtime_lock_deinit(&ctx->connect);
1527 	qdf_runtime_lock_deinit(&ctx->dfs);
1528 	qdf_runtime_lock_deinit(&ctx->system_suspend);
1529 	qdf_runtime_lock_deinit(&ctx->vdev_destroy);
1530 
1531 	qdf_rtpm_deregister(QDF_RTPM_ID_WIPHY_SUSPEND);
1532 	qdf_rtpm_deregister(QDF_RTPM_ID_PM_QOS_NOTIFY);
1533 
1534 	wlan_scan_runtime_pm_deinit(hdd_ctx->pdev);
1535 }
1536 
1537 #else /* FEATURE_RUNTIME_PM */
1538 static void hdd_runtime_suspend_context_init(struct hdd_context *hdd_ctx) {}
1539 static void hdd_runtime_suspend_context_deinit(struct hdd_context *hdd_ctx) {}
1540 #endif /* FEATURE_RUNTIME_PM */
1541 
1542 void hdd_update_macaddr(struct hdd_context *hdd_ctx,
1543 			struct qdf_mac_addr hw_macaddr, bool generate_mac_auto)
1544 {
1545 	int8_t i;
1546 	uint8_t macaddr_b3, tmp_br3;
1547 
1548 	/*
1549 	 * If "generate_mac_auto" is true, it indicates that all the
1550 	 * addresses are derived addresses, else the first addresses
1551 	 * is not derived address (It is provided by fw).
1552 	 */
1553 	if (!generate_mac_auto) {
1554 		qdf_mem_copy(hdd_ctx->provisioned_mac_addr[0].bytes,
1555 			     hw_macaddr.bytes, QDF_MAC_ADDR_SIZE);
1556 		hdd_ctx->num_provisioned_addr++;
1557 		hdd_debug("hdd_ctx->provisioned_mac_addr[0]: "
1558 			 QDF_MAC_ADDR_FMT,
1559 			 QDF_MAC_ADDR_REF(hdd_ctx->
1560 					provisioned_mac_addr[0].bytes));
1561 	} else {
1562 		qdf_mem_copy(hdd_ctx->derived_mac_addr[0].bytes,
1563 			     hw_macaddr.bytes,
1564 			     QDF_MAC_ADDR_SIZE);
1565 		hdd_ctx->num_derived_addr++;
1566 		hdd_debug("hdd_ctx->derived_mac_addr[0]: "
1567 			 QDF_MAC_ADDR_FMT,
1568 			 QDF_MAC_ADDR_REF(hdd_ctx->derived_mac_addr[0].bytes));
1569 	}
1570 	for (i = hdd_ctx->num_derived_addr; i < (QDF_MAX_CONCURRENCY_PERSONA -
1571 						hdd_ctx->num_provisioned_addr);
1572 			i++) {
1573 		qdf_mem_copy(hdd_ctx->derived_mac_addr[i].bytes,
1574 			     hw_macaddr.bytes,
1575 			     QDF_MAC_ADDR_SIZE);
1576 		macaddr_b3 = hdd_ctx->derived_mac_addr[i].bytes[3];
1577 		tmp_br3 = ((macaddr_b3 >> 4 & INTF_MACADDR_MASK) + i) &
1578 			  INTF_MACADDR_MASK;
1579 		macaddr_b3 += tmp_br3;
1580 
1581 		/* XOR-ing bit-24 of the mac address. This will give enough
1582 		 * mac address range before collision
1583 		 */
1584 		macaddr_b3 ^= (1 << 7);
1585 
1586 		/* Set locally administered bit */
1587 		hdd_ctx->derived_mac_addr[i].bytes[0] |= 0x02;
1588 		hdd_ctx->derived_mac_addr[i].bytes[3] = macaddr_b3;
1589 		hdd_debug("hdd_ctx->derived_mac_addr[%d]: "
1590 			QDF_MAC_ADDR_FMT, i,
1591 			QDF_MAC_ADDR_REF(hdd_ctx->derived_mac_addr[i].bytes));
1592 		hdd_ctx->num_derived_addr++;
1593 	}
1594 }
1595 
1596 #ifdef FEATURE_WLAN_TDLS
1597 static int hdd_update_tdls_config(struct hdd_context *hdd_ctx)
1598 {
1599 	struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc;
1600 	struct tdls_start_params tdls_cfg;
1601 	QDF_STATUS status;
1602 	struct wlan_mlme_nss_chains vdev_ini_cfg;
1603 
1604 	/* Populate the nss chain params from ini for this vdev type */
1605 	sme_populate_nss_chain_params(hdd_ctx->mac_handle, &vdev_ini_cfg,
1606 				      QDF_TDLS_MODE,
1607 				      hdd_ctx->num_rf_chains);
1608 
1609 	cfg_tdls_set_vdev_nss_2g(hdd_ctx->psoc,
1610 				 vdev_ini_cfg.rx_nss[NSS_CHAINS_BAND_2GHZ]);
1611 	cfg_tdls_set_vdev_nss_5g(hdd_ctx->psoc,
1612 				 vdev_ini_cfg.rx_nss[NSS_CHAINS_BAND_5GHZ]);
1613 	hdd_init_tdls_config(&tdls_cfg);
1614 	tdls_cfg.tdls_del_all_peers = eWNI_SME_DEL_ALL_TDLS_PEERS;
1615 	tdls_cfg.tdls_update_dp_vdev_flags = CDP_UPDATE_TDLS_FLAGS;
1616 	tdls_cfg.tdls_event_cb = wlan_cfg80211_tdls_event_callback;
1617 	tdls_cfg.tdls_evt_cb_data = psoc;
1618 	tdls_cfg.tdls_peer_context = hdd_ctx;
1619 	tdls_cfg.tdls_reg_peer = hdd_tdls_register_peer;
1620 	tdls_cfg.tdls_wmm_cb = hdd_wmm_is_acm_allowed;
1621 	tdls_cfg.tdls_wmm_cb_data = psoc;
1622 	tdls_cfg.tdls_rx_cb = wlan_cfg80211_tdls_rx_callback;
1623 	tdls_cfg.tdls_rx_cb_data = psoc;
1624 	tdls_cfg.tdls_dp_vdev_update = hdd_update_dp_vdev_flags;
1625 	tdls_cfg.tdls_osif_init_cb = wlan_cfg80211_tdls_osif_priv_init;
1626 	tdls_cfg.tdls_osif_deinit_cb = wlan_cfg80211_tdls_osif_priv_deinit;
1627 	tdls_cfg.tdls_osif_update_cb.tdls_osif_conn_update =
1628 					hdd_check_and_set_tdls_conn_params;
1629 	tdls_cfg.tdls_osif_update_cb.tdls_osif_disconn_update =
1630 					hdd_check_and_set_tdls_disconn_params;
1631 
1632 	status = ucfg_tdls_update_config(psoc, &tdls_cfg);
1633 	if (status != QDF_STATUS_SUCCESS) {
1634 		hdd_err("failed pmo psoc configuration");
1635 		return -EINVAL;
1636 	}
1637 
1638 	hdd_ctx->tdls_umac_comp_active = true;
1639 	/* enable napier specific tdls data path */
1640 	hdd_ctx->tdls_nap_active = true;
1641 
1642 	return 0;
1643 }
1644 #else
1645 static int hdd_update_tdls_config(struct hdd_context *hdd_ctx)
1646 {
1647 	return 0;
1648 }
1649 #endif
1650 
1651 void hdd_indicate_active_ndp_cnt(struct wlan_objmgr_psoc *psoc,
1652 				 uint8_t vdev_id, uint8_t cnt)
1653 {
1654 	struct wlan_hdd_link_info *link_info;
1655 
1656 	link_info = wlan_hdd_get_link_info_from_vdev(psoc, vdev_id);
1657 	if (!link_info || !cfg_nan_is_roam_config_disabled(psoc))
1658 		return;
1659 
1660 	hdd_debug("vdev_id:%d%s active ndp sessions present", vdev_id,
1661 		  cnt ? "" : " no more");
1662 	if (!cnt)
1663 		wlan_hdd_set_roaming_state(link_info, RSO_NDP_CON_ON_NDI, true);
1664 	else
1665 		wlan_hdd_set_roaming_state(link_info, RSO_NDP_CON_ON_NDI,
1666 					   false);
1667 }
1668 
1669 #ifdef WLAN_FEATURE_ROAM_OFFLOAD
1670 static void hdd_update_roam_offload(struct hdd_context *hdd_ctx,
1671 				    struct wma_tgt_services *cfg)
1672 {
1673 	bool roam_offload_enable;
1674 
1675 	ucfg_mlme_get_roaming_offload(hdd_ctx->psoc, &roam_offload_enable);
1676 	ucfg_mlme_set_roaming_offload(hdd_ctx->psoc,
1677 				      roam_offload_enable &
1678 				      cfg->en_roam_offload);
1679 }
1680 #else
1681 static inline void hdd_update_roam_offload(struct hdd_context *hdd_ctx,
1682 					   struct wma_tgt_services *cfg)
1683 {
1684 }
1685 #endif
1686 
1687 #ifdef FEATURE_CLUB_LL_STATS_AND_GET_STATION
1688 static void
1689 hdd_club_ll_stats_in_get_sta_cfg_update(struct hdd_config *config,
1690 					struct wlan_objmgr_psoc *psoc)
1691 {
1692 	config->sta_stats_cache_expiry_time =
1693 			cfg_get(psoc, CFG_STA_STATS_CACHE_EXPIRY);
1694 }
1695 
1696 static void
1697 hdd_update_feature_cfg_club_get_sta_in_ll_stats_req(
1698 					struct hdd_context *hdd_ctx,
1699 					struct wma_tgt_services *cfg)
1700 {
1701 	hdd_ctx->is_get_station_clubbed_in_ll_stats_req =
1702 				cfg->is_get_station_clubbed_in_ll_stats_req &&
1703 				cfg_get(hdd_ctx->psoc,
1704 					CFG_CLUB_LL_STA_AND_GET_STATION);
1705 }
1706 
1707 static void
1708 hdd_init_get_sta_in_ll_stats_config(struct hdd_adapter *adapter)
1709 {
1710 	adapter->sta_stats_cached_timestamp = 0;
1711 }
1712 #else
1713 static void
1714 hdd_club_ll_stats_in_get_sta_cfg_update(struct hdd_config *config,
1715 					struct wlan_objmgr_psoc *psoc)
1716 {
1717 }
1718 
1719 static void
1720 hdd_update_feature_cfg_club_get_sta_in_ll_stats_req(
1721 					struct hdd_context *hdd_ctx,
1722 					struct wma_tgt_services *cfg)
1723 {
1724 }
1725 
1726 static void
1727 hdd_init_get_sta_in_ll_stats_config(struct hdd_adapter *adapter)
1728 {
1729 }
1730 #endif /* FEATURE_CLUB_LL_STATS_AND_GET_STATION */
1731 
1732 #ifdef WLAN_FEATURE_11BE_MLO
1733 
1734 static void
1735 hdd_init_link_state_cfg(struct hdd_config *config,
1736 			struct wlan_objmgr_psoc *psoc)
1737 {
1738 	config->link_state_cache_expiry_time =
1739 		cfg_get(psoc, CFG_LINK_STATE_CACHE_EXPIRY);
1740 }
1741 
1742 static void
1743 hdd_init_link_state_config(struct hdd_adapter *adapter)
1744 {
1745 	adapter->link_state_cached_timestamp = 0;
1746 }
1747 
1748 #else
1749 static void
1750 hdd_init_link_state_cfg(struct hdd_config *config,
1751 			struct wlan_objmgr_psoc *psoc)
1752 {
1753 }
1754 
1755 static void
1756 hdd_init_link_state_config(struct hdd_adapter *adapter)
1757 {
1758 }
1759 #endif /* WLAN_FEATURE_11BE_MLO */
1760 
1761 #ifdef WLAN_FEATURE_IGMP_OFFLOAD
1762 static void
1763 hdd_intersect_igmp_offload_setting(struct wlan_objmgr_psoc *psoc,
1764 				   struct wma_tgt_services *cfg)
1765 {
1766 	bool igmp_offload_enable;
1767 
1768 	igmp_offload_enable =
1769 		ucfg_pmo_is_igmp_offload_enabled(psoc);
1770 	ucfg_pmo_set_igmp_offload_enabled(psoc,
1771 					  igmp_offload_enable &
1772 					  cfg->igmp_offload_enable);
1773 	hdd_info("fw cap to handle igmp %d igmp_offload_enable ini %d",
1774 		 cfg->igmp_offload_enable, igmp_offload_enable);
1775 }
1776 #else
1777 static inline void
1778 hdd_intersect_igmp_offload_setting(struct wlan_objmgr_psoc *psoc,
1779 				   struct wma_tgt_services *cfg)
1780 {}
1781 #endif
1782 
1783 #ifdef FEATURE_WLAN_TDLS
1784 static void hdd_update_fw_tdls_wideband_capability(struct hdd_context *hdd_ctx,
1785 						   struct wma_tgt_services *cfg)
1786 {
1787 	ucfg_tdls_update_fw_wideband_capability(hdd_ctx->psoc,
1788 						cfg->en_tdls_wideband_support);
1789 }
1790 
1791 #ifdef WLAN_FEATURE_11BE
1792 static void hdd_update_fw_tdls_mlo_capability(struct hdd_context *hdd_ctx,
1793 					      struct wma_tgt_services *cfg)
1794 {
1795 	ucfg_tdls_update_fw_mlo_capability(hdd_ctx->psoc,
1796 					   cfg->en_tdls_mlo_support);
1797 }
1798 #else
1799 static inline
1800 void hdd_update_fw_tdls_mlo_capability(struct hdd_context *hdd_ctx,
1801 				       struct wma_tgt_services *cfg)
1802 {}
1803 #endif
1804 
1805 #ifdef WLAN_FEATURE_11AX
1806 static void hdd_update_fw_tdls_11ax_capability(struct hdd_context *hdd_ctx,
1807 					       struct wma_tgt_services *cfg)
1808 {
1809 	ucfg_tdls_update_fw_11ax_capability(hdd_ctx->psoc,
1810 					    cfg->en_tdls_11ax_support);
1811 }
1812 
1813 static void hdd_update_fw_tdls_6g_capability(struct hdd_context *hdd_ctx,
1814 					     struct wma_tgt_services *cfg)
1815 {
1816 	ucfg_update_fw_tdls_6g_capability(hdd_ctx->psoc,
1817 					  cfg->en_tdls_6g_support);
1818 }
1819 
1820 #else
1821 static inline
1822 void hdd_update_fw_tdls_11ax_capability(struct hdd_context *hdd_ctx,
1823 					struct wma_tgt_services *cfg)
1824 {}
1825 static inline
1826 void hdd_update_fw_tdls_6g_capability(struct hdd_context *hdd_ctx,
1827 				      struct wma_tgt_services *cfg)
1828 {}
1829 #endif
1830 #else
1831 static inline
1832 void hdd_update_fw_tdls_mlo_capability(struct hdd_context *hdd_ctx,
1833 				       struct wma_tgt_services *cfg)
1834 {}
1835 
1836 static inline
1837 void hdd_update_fw_tdls_11ax_capability(struct hdd_context *hdd_ctx,
1838 					struct wma_tgt_services *cfg)
1839 {}
1840 
1841 static inline
1842 void hdd_update_fw_tdls_6g_capability(struct hdd_context *hdd_ctx,
1843 				      struct wma_tgt_services *cfg)
1844 {}
1845 
1846 static inline
1847 void hdd_update_fw_tdls_wideband_capability(struct hdd_context *hdd_ctx,
1848 					    struct wma_tgt_services *cfg)
1849 {}
1850 #endif
1851 
1852 #ifdef WLAN_FEATURE_DYNAMIC_MAC_ADDR_UPDATE
1853 static inline void
1854 hdd_set_dynamic_macaddr_update_capability(struct hdd_context *hdd_ctx,
1855 					  struct wma_tgt_services *cfg)
1856 {
1857 	hdd_ctx->is_vdev_macaddr_dynamic_update_supported =
1858 				cfg->dynamic_vdev_macaddr_support &&
1859 				cfg_get(hdd_ctx->psoc,
1860 					CFG_DYNAMIC_MAC_ADDR_UPDATE_SUPPORTED);
1861 }
1862 #else
1863 static inline void
1864 hdd_set_dynamic_macaddr_update_capability(struct hdd_context *hdd_ctx,
1865 					  struct wma_tgt_services *cfg)
1866 {
1867 }
1868 #endif
1869 
1870 #ifdef WLAN_FEATURE_11BE
1871 static bool hdd_dot11Mode_support_11be(enum hdd_dot11_mode dot11Mode)
1872 {
1873 	if (dot11Mode != eHDD_DOT11_MODE_AUTO &&
1874 	    dot11Mode < eHDD_DOT11_MODE_11be)
1875 		return false;
1876 
1877 	return true;
1878 }
1879 
1880 static void
1881 hdd_update_tid_to_link_supported(struct hdd_context *hdd_ctx,
1882 				 struct wma_tgt_services *cfg)
1883 {
1884 	if (!cfg->en_mlo_tid_to_link_support)
1885 		ucfg_mlme_set_t2lm_negotiation_supported(hdd_ctx->psoc,
1886 							 T2LM_NEGOTIATION_DISABLED);
1887 }
1888 
1889 #else
1890 static bool hdd_dot11Mode_support_11be(enum hdd_dot11_mode dot11Mode)
1891 {
1892 	return false;
1893 }
1894 
1895 static inline void
1896 hdd_update_tid_to_link_supported(struct hdd_context *hdd_ctx,
1897 				 struct wma_tgt_services *cfg)
1898 {
1899 }
1900 #endif
1901 
1902 #ifdef WLAN_FEATURE_11BE_MLO
1903 static void
1904 hdd_update_mlo_per_link_stats_capability(struct hdd_context *hdd_ctx,
1905 					 struct wma_tgt_services *cfg)
1906 {
1907 	hdd_ctx->is_mlo_per_link_stats_supported =
1908 				cfg->is_mlo_per_link_stats_supported;
1909 }
1910 #else
1911 static void
1912 hdd_update_mlo_per_link_stats_capability(struct hdd_context *hdd_ctx,
1913 					 struct wma_tgt_services *cfg)
1914 {
1915 }
1916 #endif
1917 
1918 static void hdd_update_tgt_services(struct hdd_context *hdd_ctx,
1919 				    struct wma_tgt_services *cfg)
1920 {
1921 	struct hdd_config *config = hdd_ctx->config;
1922 	bool arp_offload_enable;
1923 	bool mawc_enabled;
1924 #ifdef FEATURE_WLAN_TDLS
1925 	bool tdls_support;
1926 	bool tdls_off_channel;
1927 	bool tdls_buffer_sta;
1928 	uint32_t tdls_uapsd_mask;
1929 #endif
1930 	bool get_peer_info_enable;
1931 
1932 	/* Set up UAPSD */
1933 	ucfg_mlme_set_sap_uapsd_flag(hdd_ctx->psoc, cfg->uapsd);
1934 
1935 	/* 11AX mode support */
1936 	if ((config->dot11Mode == eHDD_DOT11_MODE_11ax ||
1937 	     config->dot11Mode == eHDD_DOT11_MODE_11ax_ONLY) && !cfg->en_11ax)
1938 		config->dot11Mode = eHDD_DOT11_MODE_11ac;
1939 
1940 	/* 11AC mode support */
1941 	if ((config->dot11Mode == eHDD_DOT11_MODE_11ac ||
1942 	     config->dot11Mode == eHDD_DOT11_MODE_11ac_ONLY) && !cfg->en_11ac)
1943 		config->dot11Mode = eHDD_DOT11_MODE_AUTO;
1944 
1945 	/* 11BE mode support */
1946 	if (cfg->en_11be &&
1947 	    (!hdd_dot11Mode_support_11be(config->dot11Mode) ||
1948 	     !wlan_reg_phybitmap_support_11be(hdd_ctx->pdev))) {
1949 		hdd_debug("dot11Mode %d override target en_11be to false",
1950 			  config->dot11Mode);
1951 		cfg->en_11be = false;
1952 	}
1953 
1954 	/* ARP offload: override user setting if invalid  */
1955 	arp_offload_enable =
1956 			ucfg_pmo_is_arp_offload_enabled(hdd_ctx->psoc);
1957 	ucfg_pmo_set_arp_offload_enabled(hdd_ctx->psoc,
1958 					 arp_offload_enable & cfg->arp_offload);
1959 
1960 	/* Intersect igmp offload ini configuration and fw cap*/
1961 	hdd_intersect_igmp_offload_setting(hdd_ctx->psoc, cfg);
1962 
1963 #ifdef FEATURE_WLAN_SCAN_PNO
1964 	/* PNO offload */
1965 	hdd_debug("PNO Capability in f/w = %d", cfg->pno_offload);
1966 	if (cfg->pno_offload)
1967 		ucfg_scan_set_pno_offload(hdd_ctx->psoc, true);
1968 #endif
1969 #ifdef FEATURE_WLAN_TDLS
1970 	cfg_tdls_get_support_enable(hdd_ctx->psoc, &tdls_support);
1971 	cfg_tdls_set_support_enable(hdd_ctx->psoc,
1972 				    tdls_support & cfg->en_tdls);
1973 
1974 	cfg_tdls_get_off_channel_enable(hdd_ctx->psoc, &tdls_off_channel);
1975 	cfg_tdls_set_off_channel_enable(hdd_ctx->psoc,
1976 					tdls_off_channel &&
1977 					cfg->en_tdls_offchan);
1978 
1979 	cfg_tdls_get_buffer_sta_enable(hdd_ctx->psoc, &tdls_buffer_sta);
1980 	cfg_tdls_set_buffer_sta_enable(hdd_ctx->psoc,
1981 				       tdls_buffer_sta &&
1982 				       cfg->en_tdls_uapsd_buf_sta);
1983 
1984 	cfg_tdls_get_uapsd_mask(hdd_ctx->psoc, &tdls_uapsd_mask);
1985 	if (tdls_uapsd_mask && cfg->en_tdls_uapsd_sleep_sta)
1986 		cfg_tdls_set_sleep_sta_enable(hdd_ctx->psoc, true);
1987 	else
1988 		cfg_tdls_set_sleep_sta_enable(hdd_ctx->psoc, false);
1989 #endif
1990 	hdd_update_roam_offload(hdd_ctx, cfg);
1991 
1992 	if (ucfg_mlme_get_sap_get_peer_info(
1993 		hdd_ctx->psoc, &get_peer_info_enable) == QDF_STATUS_SUCCESS) {
1994 		get_peer_info_enable &= cfg->get_peer_info_enabled;
1995 		ucfg_mlme_set_sap_get_peer_info(hdd_ctx->psoc,
1996 						get_peer_info_enable);
1997 	}
1998 
1999 	ucfg_mlme_is_mawc_enabled(hdd_ctx->psoc, &mawc_enabled);
2000 	ucfg_mlme_set_mawc_enabled(hdd_ctx->psoc,
2001 				   mawc_enabled & cfg->is_fw_mawc_capable);
2002 	hdd_update_tdls_config(hdd_ctx);
2003 	sme_update_tgt_services(hdd_ctx->mac_handle, cfg);
2004 	hdd_ctx->roam_ch_from_fw_supported = cfg->is_roam_scan_ch_to_host;
2005 	hdd_ctx->ll_stats_per_chan_rx_tx_time =
2006 					cfg->ll_stats_per_chan_rx_tx_time;
2007 
2008 	hdd_update_feature_cfg_club_get_sta_in_ll_stats_req(hdd_ctx, cfg);
2009 	hdd_ctx->is_therm_cmd_supp =
2010 				cfg->is_fw_therm_throt_supp &&
2011 				cfg_get(hdd_ctx->psoc,
2012 					CFG_THERMAL_MITIGATION_ENABLE);
2013 	hdd_update_fw_tdls_11ax_capability(hdd_ctx, cfg);
2014 	hdd_update_fw_tdls_mlo_capability(hdd_ctx, cfg);
2015 	hdd_set_dynamic_macaddr_update_capability(hdd_ctx, cfg);
2016 	hdd_update_fw_tdls_6g_capability(hdd_ctx, cfg);
2017 	hdd_update_fw_tdls_wideband_capability(hdd_ctx, cfg);
2018 	ucfg_psoc_mlme_set_11be_capab(hdd_ctx->psoc, cfg->en_11be);
2019 	hdd_update_mlo_per_link_stats_capability(hdd_ctx, cfg);
2020 }
2021 
2022 /**
2023  * hdd_update_vdev_nss() - sets the vdev nss
2024  * @hdd_ctx: HDD context
2025  *
2026  * Sets the Nss per vdev type based on INI
2027  *
2028  * Return: None
2029  */
2030 static void hdd_update_vdev_nss(struct hdd_context *hdd_ctx)
2031 {
2032 	uint8_t max_supp_nss = 1;
2033 	mac_handle_t mac_handle;
2034 	QDF_STATUS status;
2035 	bool bval;
2036 
2037 	status = ucfg_mlme_get_vht_enable2x2(hdd_ctx->psoc, &bval);
2038 	if (!QDF_IS_STATUS_SUCCESS(status))
2039 		hdd_err("unable to get vht_enable2x2");
2040 
2041 	if (bval && !cds_is_sub_20_mhz_enabled())
2042 		max_supp_nss = 2;
2043 
2044 	hdd_debug("max nss %d", max_supp_nss);
2045 
2046 	mac_handle = hdd_ctx->mac_handle;
2047 	sme_update_vdev_type_nss(mac_handle, max_supp_nss,
2048 				 NSS_CHAINS_BAND_2GHZ);
2049 
2050 	sme_update_vdev_type_nss(mac_handle, max_supp_nss,
2051 				 NSS_CHAINS_BAND_5GHZ);
2052 }
2053 
2054 /**
2055  * hdd_update_2g_wiphy_vhtcap() - Updates 2G wiphy vhtcap fields
2056  * @hdd_ctx: HDD context
2057  *
2058  * Updates 2G wiphy vhtcap fields
2059  *
2060  * Return: None
2061  */
2062 static void hdd_update_2g_wiphy_vhtcap(struct hdd_context *hdd_ctx)
2063 {
2064 	struct ieee80211_supported_band *band_2g =
2065 		hdd_ctx->wiphy->bands[NL80211_BAND_2GHZ];
2066 	uint32_t value;
2067 	bool is_vht_24ghz;
2068 
2069 	if (!band_2g) {
2070 		hdd_debug("2GHz band disabled, skipping capability population");
2071 		return;
2072 	}
2073 
2074 	ucfg_mlme_get_vht_for_24ghz(hdd_ctx->psoc, &is_vht_24ghz);
2075 
2076 	if (is_vht_24ghz) {
2077 		ucfg_mlme_cfg_get_vht_tx_mcs_map(hdd_ctx->psoc, &value);
2078 		band_2g->vht_cap.vht_mcs.tx_mcs_map = value;
2079 	}
2080 }
2081 
2082 /**
2083  * hdd_update_5g_wiphy_vhtcap() - Updates 5G wiphy vhtcap fields
2084  * @hdd_ctx: HDD context
2085  *
2086  * Updates 5G wiphy vhtcap fields
2087  *
2088  * Return: None
2089  */
2090 static void hdd_update_5g_wiphy_vhtcap(struct hdd_context *hdd_ctx)
2091 {
2092 	struct ieee80211_supported_band *band_5g =
2093 		hdd_ctx->wiphy->bands[NL80211_BAND_5GHZ];
2094 	QDF_STATUS status;
2095 	uint8_t value = 0, value1 = 0;
2096 	uint32_t value2;
2097 
2098 	if (!band_5g) {
2099 		hdd_debug("5GHz band disabled, skipping capability population");
2100 		return;
2101 	}
2102 
2103 	status = ucfg_mlme_cfg_get_vht_tx_bfee_ant_supp(hdd_ctx->psoc,
2104 							&value);
2105 	if (!QDF_IS_STATUS_SUCCESS(status))
2106 		hdd_err("unable to get tx_bfee_ant_supp");
2107 
2108 	band_5g->vht_cap.cap |=
2109 			(value << IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT);
2110 
2111 	value1 = NUM_OF_SOUNDING_DIMENSIONS;
2112 	band_5g->vht_cap.cap |=
2113 		(value1 << IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_SHIFT);
2114 
2115 	hdd_debug("Updated wiphy vhtcap:0x%x, CSNAntSupp:%d, NumSoundDim:%d",
2116 		  band_5g->vht_cap.cap, value, value1);
2117 
2118 	ucfg_mlme_cfg_get_vht_rx_mcs_map(hdd_ctx->psoc, &value2);
2119 	band_5g->vht_cap.vht_mcs.rx_mcs_map = value2;
2120 
2121 	ucfg_mlme_cfg_get_vht_tx_mcs_map(hdd_ctx->psoc, &value2);
2122 	band_5g->vht_cap.vht_mcs.tx_mcs_map = value2;
2123 }
2124 
2125 /**
2126  * hdd_update_wiphy_vhtcap() - Updates wiphy vhtcap fields
2127  * @hdd_ctx: HDD context
2128  *
2129  * Updates wiphy vhtcap fields
2130  *
2131  * Return: None
2132  */
2133 static void hdd_update_wiphy_vhtcap(struct hdd_context *hdd_ctx)
2134 {
2135 	hdd_update_2g_wiphy_vhtcap(hdd_ctx);
2136 	hdd_update_5g_wiphy_vhtcap(hdd_ctx);
2137 }
2138 
2139 static void hdd_update_tgt_ht_cap(struct hdd_context *hdd_ctx,
2140 				  struct wma_tgt_ht_cap *cfg)
2141 {
2142 	QDF_STATUS status;
2143 	qdf_size_t value_len;
2144 	uint32_t value;
2145 	uint8_t mpdu_density;
2146 	struct mlme_ht_capabilities_info ht_cap_info;
2147 	uint8_t mcs_set[SIZE_OF_SUPPORTED_MCS_SET];
2148 	bool b_enable1x1;
2149 
2150 	/* get the MPDU density */
2151 	status = ucfg_mlme_get_ht_mpdu_density(hdd_ctx->psoc, &mpdu_density);
2152 	if (QDF_IS_STATUS_ERROR(status)) {
2153 		hdd_err("could not get HT MPDU Density");
2154 		return;
2155 	}
2156 
2157 	/*
2158 	 * MPDU density:
2159 	 * override user's setting if value is larger
2160 	 * than the one supported by target,
2161 	 * if target value is 0, then follow user's setting.
2162 	 */
2163 	if (cfg->mpdu_density && mpdu_density > cfg->mpdu_density) {
2164 		status = ucfg_mlme_set_ht_mpdu_density(hdd_ctx->psoc,
2165 						       cfg->mpdu_density);
2166 		if (QDF_IS_STATUS_ERROR(status))
2167 			hdd_err("could not set HT capability to CCM");
2168 	}
2169 
2170 	/* get the HT capability info */
2171 	status = ucfg_mlme_get_ht_cap_info(hdd_ctx->psoc, &ht_cap_info);
2172 	if (QDF_STATUS_SUCCESS != status) {
2173 		hdd_err("could not get HT capability info");
2174 		return;
2175 	}
2176 
2177 	/* check and update RX STBC */
2178 	if (ht_cap_info.rx_stbc && !cfg->ht_rx_stbc)
2179 		ht_cap_info.rx_stbc = cfg->ht_rx_stbc;
2180 
2181 	/* Set the LDPC capability */
2182 	if (ht_cap_info.adv_coding_cap && !cfg->ht_rx_ldpc)
2183 		ht_cap_info.adv_coding_cap = cfg->ht_rx_ldpc;
2184 
2185 	if (ht_cap_info.short_gi_20_mhz && !cfg->ht_sgi_20)
2186 		ht_cap_info.short_gi_20_mhz = cfg->ht_sgi_20;
2187 
2188 	if (ht_cap_info.short_gi_40_mhz && !cfg->ht_sgi_40)
2189 		ht_cap_info.short_gi_40_mhz = cfg->ht_sgi_40;
2190 
2191 	hdd_debug("gHtSMPS ini: %d, dynamic_smps fw cap: %d",
2192 		  ht_cap_info.mimo_power_save, cfg->dynamic_smps);
2193 	if (ht_cap_info.mimo_power_save == HDD_SMPS_MODE_DYNAMIC) {
2194 		if (cfg->dynamic_smps)
2195 			ht_cap_info.mimo_power_save = HDD_SMPS_MODE_DYNAMIC;
2196 		else
2197 			ht_cap_info.mimo_power_save = HDD_SMPS_MODE_DISABLED;
2198 	}
2199 
2200 	hdd_ctx->num_rf_chains = cfg->num_rf_chains;
2201 	hdd_ctx->ht_tx_stbc_supported = cfg->ht_tx_stbc;
2202 
2203 	status = ucfg_mlme_get_vht_enable2x2(hdd_ctx->psoc, &b_enable1x1);
2204 	if (!QDF_IS_STATUS_SUCCESS(status))
2205 		hdd_err("unable to get vht_enable2x2");
2206 
2207 	b_enable1x1 = b_enable1x1 && (cfg->num_rf_chains == 2);
2208 
2209 	status = ucfg_mlme_set_vht_enable2x2(hdd_ctx->psoc, b_enable1x1);
2210 	if (!QDF_IS_STATUS_SUCCESS(status))
2211 		hdd_err("unable to set vht_enable2x2");
2212 
2213 	if (!b_enable1x1)
2214 		ht_cap_info.tx_stbc = 0;
2215 
2216 	if (!(cfg->ht_tx_stbc && b_enable1x1))
2217 		ht_cap_info.tx_stbc = 0;
2218 
2219 	status = ucfg_mlme_set_ht_cap_info(hdd_ctx->psoc, ht_cap_info);
2220 	if (status != QDF_STATUS_SUCCESS)
2221 		hdd_err("could not set HT capability to CCM");
2222 #define WLAN_HDD_RX_MCS_ALL_NSTREAM_RATES 0xff
2223 	value_len = SIZE_OF_SUPPORTED_MCS_SET;
2224 	if (ucfg_mlme_get_supported_mcs_set(
2225 				hdd_ctx->psoc, mcs_set,
2226 				&value_len) == QDF_STATUS_SUCCESS) {
2227 		hdd_debug("Read MCS rate set");
2228 		if (cfg->num_rf_chains > SIZE_OF_SUPPORTED_MCS_SET)
2229 			cfg->num_rf_chains = SIZE_OF_SUPPORTED_MCS_SET;
2230 
2231 		if (b_enable1x1) {
2232 			for (value = 0; value < cfg->num_rf_chains; value++)
2233 				mcs_set[value] =
2234 					WLAN_HDD_RX_MCS_ALL_NSTREAM_RATES;
2235 
2236 			status = ucfg_mlme_set_supported_mcs_set(
2237 					hdd_ctx->psoc,
2238 					mcs_set,
2239 					(qdf_size_t)SIZE_OF_SUPPORTED_MCS_SET);
2240 			if (QDF_IS_STATUS_ERROR(status))
2241 				hdd_err("could not set MCS SET to CCM");
2242 		}
2243 	}
2244 #undef WLAN_HDD_RX_MCS_ALL_NSTREAM_RATES
2245 }
2246 
2247 static void hdd_update_tgt_vht_cap(struct hdd_context *hdd_ctx,
2248 				   struct wma_tgt_vht_cap *cfg)
2249 {
2250 	QDF_STATUS status;
2251 	struct wiphy *wiphy = hdd_ctx->wiphy;
2252 	struct ieee80211_supported_band *band_5g =
2253 		wiphy->bands[HDD_NL80211_BAND_5GHZ];
2254 	uint32_t ch_width;
2255 	struct wma_caps_per_phy caps_per_phy = {0};
2256 	bool vht_enable_2x2;
2257 	uint32_t tx_highest_data_rate;
2258 	uint32_t rx_highest_data_rate;
2259 
2260 	if (!band_5g) {
2261 		hdd_debug("5GHz band disabled, skipping capability population");
2262 		return;
2263 	}
2264 
2265 	status = ucfg_mlme_update_vht_cap(hdd_ctx->psoc, cfg);
2266 	if (QDF_IS_STATUS_ERROR(status))
2267 		hdd_err("could not update vht capabilities");
2268 
2269 	status = ucfg_mlme_get_vht_enable2x2(hdd_ctx->psoc, &vht_enable_2x2);
2270 	if (!QDF_IS_STATUS_SUCCESS(status))
2271 		hdd_err("unable to get vht_enable2x2");
2272 
2273 	if (vht_enable_2x2) {
2274 		tx_highest_data_rate =
2275 				VHT_TX_HIGHEST_SUPPORTED_DATA_RATE_2_2;
2276 		rx_highest_data_rate =
2277 				VHT_RX_HIGHEST_SUPPORTED_DATA_RATE_2_2;
2278 	} else {
2279 		tx_highest_data_rate =
2280 				VHT_TX_HIGHEST_SUPPORTED_DATA_RATE_1_1;
2281 		rx_highest_data_rate =
2282 				VHT_RX_HIGHEST_SUPPORTED_DATA_RATE_1_1;
2283 	}
2284 
2285 	status = ucfg_mlme_cfg_set_vht_rx_supp_data_rate(hdd_ctx->psoc,
2286 							 rx_highest_data_rate);
2287 	if (!QDF_IS_STATUS_SUCCESS(status))
2288 		hdd_err("Failed to set rx_supp_data_rate");
2289 
2290 	status = ucfg_mlme_cfg_set_vht_tx_supp_data_rate(hdd_ctx->psoc,
2291 							 tx_highest_data_rate);
2292 	if (!QDF_IS_STATUS_SUCCESS(status))
2293 		hdd_err("Failed to set tx_supp_data_rate");
2294 
2295 	/* Update the real highest data rate to wiphy */
2296 	if (cfg->vht_short_gi_80 & WMI_VHT_CAP_SGI_80MHZ) {
2297 		if (vht_enable_2x2) {
2298 			tx_highest_data_rate =
2299 				VHT_TX_HIGHEST_SUPPORTED_DATA_RATE_2_2_SGI80;
2300 			rx_highest_data_rate =
2301 				VHT_RX_HIGHEST_SUPPORTED_DATA_RATE_2_2_SGI80;
2302 		} else {
2303 			tx_highest_data_rate =
2304 				VHT_TX_HIGHEST_SUPPORTED_DATA_RATE_1_1_SGI80;
2305 			rx_highest_data_rate =
2306 				VHT_RX_HIGHEST_SUPPORTED_DATA_RATE_1_1_SGI80;
2307 		}
2308 	}
2309 
2310 	if (WMI_VHT_CAP_MAX_MPDU_LEN_11454 == cfg->vht_max_mpdu)
2311 		band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454;
2312 	else if (WMI_VHT_CAP_MAX_MPDU_LEN_7935 == cfg->vht_max_mpdu)
2313 		band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_7991;
2314 	else
2315 		band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_3895;
2316 
2317 
2318 	if (cfg->supp_chan_width & (1 << eHT_CHANNEL_WIDTH_80P80MHZ)) {
2319 		band_5g->vht_cap.cap |=
2320 			IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ;
2321 		ch_width = VHT_CAP_160_AND_80P80_SUPP;
2322 	} else if (cfg->supp_chan_width & (1 << eHT_CHANNEL_WIDTH_160MHZ)) {
2323 		band_5g->vht_cap.cap |=
2324 			IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ;
2325 		ch_width = VHT_CAP_160_SUPP;
2326 	} else {
2327 		ch_width = VHT_CAP_NO_160M_SUPP;
2328 	}
2329 
2330 	status = ucfg_mlme_set_vht_ch_width(hdd_ctx->psoc, ch_width);
2331 	if (QDF_IS_STATUS_ERROR(status))
2332 		hdd_err("could not set the channel width");
2333 	else
2334 		hdd_debug("supported channel width %d", ch_width);
2335 
2336 	if (cfg->vht_rx_ldpc & WMI_VHT_CAP_RX_LDPC) {
2337 		band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_RXLDPC;
2338 		hdd_debug("VHT RxLDPC capability is set");
2339 	} else {
2340 		/*
2341 		 * Get the RX LDPC capability for the NON DBS
2342 		 * hardware mode for 5G band
2343 		 */
2344 		status = wma_get_caps_for_phyidx_hwmode(&caps_per_phy,
2345 					HW_MODE_DBS_NONE, CDS_BAND_5GHZ);
2346 		if ((QDF_IS_STATUS_SUCCESS(status)) &&
2347 			(caps_per_phy.vht_5g & WMI_VHT_CAP_RX_LDPC)) {
2348 			band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_RXLDPC;
2349 			hdd_debug("VHT RX LDPC capability is set");
2350 		}
2351 	}
2352 
2353 	if (cfg->vht_short_gi_80 & WMI_VHT_CAP_SGI_80MHZ)
2354 		band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_SHORT_GI_80;
2355 	if (cfg->vht_short_gi_160 & WMI_VHT_CAP_SGI_160MHZ)
2356 		band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_SHORT_GI_160;
2357 
2358 	if (vht_enable_2x2 && (cfg->vht_tx_stbc & WMI_VHT_CAP_TX_STBC))
2359 		band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_TXSTBC;
2360 
2361 	if (cfg->vht_rx_stbc & WMI_VHT_CAP_RX_STBC_1SS)
2362 		band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_RXSTBC_1;
2363 	if (vht_enable_2x2 && (cfg->vht_rx_stbc & WMI_VHT_CAP_RX_STBC_2SS))
2364 		band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_RXSTBC_2;
2365 	if (cfg->vht_rx_stbc & WMI_VHT_CAP_RX_STBC_3SS)
2366 		band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_RXSTBC_3;
2367 
2368 	band_5g->vht_cap.cap |=
2369 		(cfg->vht_max_ampdu_len_exp <<
2370 		 IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT);
2371 
2372 	if (cfg->vht_su_bformer & WMI_VHT_CAP_SU_BFORMER)
2373 		band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE;
2374 	if (cfg->vht_su_bformee & WMI_VHT_CAP_SU_BFORMEE)
2375 		band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE;
2376 	if (cfg->vht_mu_bformer & WMI_VHT_CAP_MU_BFORMER)
2377 		band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE;
2378 	if (cfg->vht_mu_bformee & WMI_VHT_CAP_MU_BFORMEE)
2379 		band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE;
2380 
2381 	if (cfg->vht_txop_ps & WMI_VHT_CAP_TXOP_PS)
2382 		band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_VHT_TXOP_PS;
2383 
2384 	band_5g->vht_cap.vht_mcs.rx_highest = cpu_to_le16(rx_highest_data_rate);
2385 	band_5g->vht_cap.vht_mcs.tx_highest = cpu_to_le16(tx_highest_data_rate);
2386 }
2387 
2388 /**
2389  * hdd_generate_macaddr_auto() - Auto-generate mac address
2390  * @hdd_ctx: Pointer to the HDD context
2391  *
2392  * Auto-generate mac address using device serial number.
2393  * Keep the first 3 bytes of OUI as before and replace
2394  * the last 3 bytes with the lower 3 bytes of serial number.
2395  *
2396  * Return: 0 for success
2397  *         Non zero failure code for errors
2398  */
2399 static int hdd_generate_macaddr_auto(struct hdd_context *hdd_ctx)
2400 {
2401 	unsigned int serialno = 0;
2402 	struct qdf_mac_addr mac_addr = {
2403 		{0x00, 0x0A, 0xF5, 0x00, 0x00, 0x00}
2404 	};
2405 
2406 	serialno = pld_socinfo_get_serial_number(hdd_ctx->parent_dev);
2407 	if (serialno == 0)
2408 		return -EINVAL;
2409 
2410 	serialno &= 0x00ffffff;
2411 
2412 	mac_addr.bytes[3] = (serialno >> 16) & 0xff;
2413 	mac_addr.bytes[4] = (serialno >> 8) & 0xff;
2414 	mac_addr.bytes[5] = serialno & 0xff;
2415 
2416 	hdd_update_macaddr(hdd_ctx, mac_addr, true);
2417 	return 0;
2418 }
2419 
2420 static void hdd_sar_target_config(struct hdd_context *hdd_ctx,
2421 				  struct wma_tgt_cfg *cfg)
2422 {
2423 	hdd_ctx->sar_version = cfg->sar_version;
2424 }
2425 
2426 static void hdd_update_vhtcap_2g(struct hdd_context *hdd_ctx)
2427 {
2428 	uint64_t chip_mode = 0;
2429 	QDF_STATUS status;
2430 	bool b2g_vht_cfg = false;
2431 	bool b2g_vht_target = false;
2432 	struct wma_caps_per_phy caps_per_phy = {0};
2433 	struct wmi_unified *wmi_handle;
2434 
2435 	wmi_handle = get_wmi_unified_hdl_from_psoc(hdd_ctx->psoc);
2436 	if (!wmi_handle) {
2437 		hdd_err("wmi handle is NULL");
2438 		return;
2439 	}
2440 
2441 	status = ucfg_mlme_get_vht_for_24ghz(hdd_ctx->psoc, &b2g_vht_cfg);
2442 	if (QDF_IS_STATUS_ERROR(status)) {
2443 		hdd_err("Failed to get 2g vht mode");
2444 		return;
2445 	}
2446 	if (wmi_service_enabled(wmi_handle, wmi_service_ext_msg)) {
2447 		status = wma_get_caps_for_phyidx_hwmode(&caps_per_phy,
2448 							HW_MODE_DBS_NONE,
2449 							CDS_BAND_2GHZ);
2450 		if (QDF_IS_STATUS_ERROR(status)) {
2451 			hdd_err("Failed to get phy caps");
2452 			return;
2453 		}
2454 		if (caps_per_phy.vht_2g)
2455 			b2g_vht_target = true;
2456 	} else {
2457 		status = wlan_reg_get_chip_mode(hdd_ctx->pdev, &chip_mode);
2458 		if (QDF_IS_STATUS_ERROR(status)) {
2459 			hdd_err("Failed to get chip mode");
2460 			return;
2461 		}
2462 		b2g_vht_target =
2463 		(chip_mode & HOST_REGDMN_MODE_11AC_VHT20_2G) ?
2464 		true : false;
2465 	}
2466 
2467 	b2g_vht_cfg = b2g_vht_cfg && b2g_vht_target;
2468 	hdd_debug("vht 2g target: %d, cfg: %d", b2g_vht_target, b2g_vht_cfg);
2469 	status = ucfg_mlme_set_vht_for_24ghz(hdd_ctx->psoc, b2g_vht_cfg);
2470 	if (QDF_IS_STATUS_ERROR(status)) {
2471 		hdd_err("Failed to update 2g vht mode");
2472 		return;
2473 	}
2474 }
2475 
2476 static void hdd_extract_fw_version_info(struct hdd_context *hdd_ctx)
2477 {
2478 	hdd_ctx->fw_version_info.major_spid =
2479 			HDD_FW_VER_MAJOR_SPID(hdd_ctx->target_fw_version);
2480 	hdd_ctx->fw_version_info.minor_spid =
2481 			HDD_FW_VER_MINOR_SPID(hdd_ctx->target_fw_version);
2482 	hdd_ctx->fw_version_info.siid =
2483 			HDD_FW_VER_SIID(hdd_ctx->target_fw_version);
2484 	hdd_ctx->fw_version_info.crmid =
2485 			HDD_FW_VER_CRM_ID(hdd_ctx->target_fw_version);
2486 	hdd_ctx->fw_version_info.sub_id =
2487 			HDD_FW_VER_SUB_ID(hdd_ctx->target_fw_vers_ext);
2488 	hdd_ctx->fw_version_info.rel_id =
2489 			HDD_FW_VER_REL_ID(hdd_ctx->target_fw_vers_ext);
2490 }
2491 
2492 #if defined(WLAN_FEATURE_11AX) && \
2493 	(defined(CFG80211_SBAND_IFTYPE_DATA_BACKPORT) || \
2494 	 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0)))
2495 
2496 static void
2497 hdd_update_wiphy_he_mcs(struct ieee80211_sband_iftype_data *iftype_data,
2498 			tDot11fIEhe_cap *he_cap_cfg)
2499 {
2500 	if (!iftype_data || !he_cap_cfg) {
2501 		hdd_err("Unable to update wiphy he_mcs");
2502 		return;
2503 	}
2504 
2505 	iftype_data->he_cap.he_mcs_nss_supp.tx_mcs_80 =
2506 		he_cap_cfg->tx_he_mcs_map_lt_80;
2507 	iftype_data->he_cap.he_mcs_nss_supp.tx_mcs_160 =
2508 		*((uint16_t *)he_cap_cfg->tx_he_mcs_map_160);
2509 	iftype_data->he_cap.he_mcs_nss_supp.tx_mcs_80p80 =
2510 		*((uint16_t *)he_cap_cfg->tx_he_mcs_map_80_80);
2511 }
2512 
2513 #if defined(CONFIG_BAND_6GHZ) && (defined(IEEE80211_HE_6GHZ_CAP_MIN_MPDU_START))
2514 static void hdd_update_wiphy_he_6ghz_capa(struct hdd_context *hdd_ctx)
2515 {
2516 	uint16_t he_6ghz_capa = 0;
2517 	uint8_t min_mpdu_start_spacing;
2518 	uint8_t max_ampdu_len_exp;
2519 	uint8_t max_mpdu_len;
2520 	uint8_t sm_pow_save;
2521 
2522 	ucfg_mlme_get_ht_mpdu_density(hdd_ctx->psoc, &min_mpdu_start_spacing);
2523 	he_6ghz_capa |= FIELD_PREP(IEEE80211_HE_6GHZ_CAP_MIN_MPDU_START,
2524 				   min_mpdu_start_spacing);
2525 
2526 	ucfg_mlme_cfg_get_vht_ampdu_len_exp(hdd_ctx->psoc, &max_ampdu_len_exp);
2527 	he_6ghz_capa |= FIELD_PREP(IEEE80211_HE_6GHZ_CAP_MAX_AMPDU_LEN_EXP,
2528 				   max_ampdu_len_exp);
2529 
2530 	ucfg_mlme_cfg_get_vht_max_mpdu_len(hdd_ctx->psoc, &max_mpdu_len);
2531 	he_6ghz_capa |= FIELD_PREP(IEEE80211_HE_6GHZ_CAP_MAX_MPDU_LEN,
2532 				   max_mpdu_len);
2533 
2534 	ucfg_mlme_cfg_get_ht_smps(hdd_ctx->psoc, &sm_pow_save);
2535 	he_6ghz_capa |= FIELD_PREP(IEEE80211_HE_6GHZ_CAP_SM_PS, sm_pow_save);
2536 
2537 	he_6ghz_capa |= IEEE80211_HE_6GHZ_CAP_RX_ANTPAT_CONS;
2538 	he_6ghz_capa |= IEEE80211_HE_6GHZ_CAP_TX_ANTPAT_CONS;
2539 
2540 	hdd_ctx->iftype_data_6g->he_6ghz_capa.capa = he_6ghz_capa;
2541 }
2542 #else
2543 static inline void hdd_update_wiphy_he_6ghz_capa(struct hdd_context *hdd_ctx)
2544 {
2545 }
2546 #endif
2547 
2548 #if defined(CONFIG_BAND_6GHZ) && (defined(CFG80211_6GHZ_BAND_SUPPORTED) || \
2549       (KERNEL_VERSION(5, 4, 0) <= LINUX_VERSION_CODE))
2550 static void
2551 hdd_update_wiphy_he_caps_6ghz(struct hdd_context *hdd_ctx,
2552 			      tDot11fIEhe_cap *he_cap_cfg)
2553 {
2554 	struct ieee80211_supported_band *band_6g =
2555 		   hdd_ctx->wiphy->bands[HDD_NL80211_BAND_6GHZ];
2556 	uint8_t *phy_info =
2557 		    hdd_ctx->iftype_data_6g->he_cap.he_cap_elem.phy_cap_info;
2558 	uint8_t *mac_info_6g =
2559 		hdd_ctx->iftype_data_6g->he_cap.he_cap_elem.mac_cap_info;
2560 	uint8_t max_fw_bw = sme_get_vht_ch_width();
2561 
2562 	if (!band_6g || !phy_info) {
2563 		hdd_debug("6ghz not supported in wiphy");
2564 		return;
2565 	}
2566 
2567 	hdd_ctx->iftype_data_6g->types_mask =
2568 		(BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP));
2569 	hdd_ctx->iftype_data_6g->he_cap.has_he = true;
2570 	band_6g->n_iftype_data = 1;
2571 
2572 	if (max_fw_bw >= WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ)
2573 		phy_info[0] |=
2574 		      IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_80MHZ_IN_5G;
2575 	if (max_fw_bw >= WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ)
2576 		phy_info[0] |=
2577 			IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_160MHZ_IN_5G;
2578 	if (max_fw_bw >= WNI_CFG_VHT_CHANNEL_WIDTH_80_PLUS_80MHZ)
2579 		phy_info[0] |=
2580 		     IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G;
2581 
2582 	if (he_cap_cfg->twt_request)
2583 		mac_info_6g[0] |= IEEE80211_HE_MAC_CAP0_TWT_REQ;
2584 
2585 	if (he_cap_cfg->twt_responder)
2586 		mac_info_6g[0] |= IEEE80211_HE_MAC_CAP0_TWT_RES;
2587 
2588 	hdd_update_wiphy_he_6ghz_capa(hdd_ctx);
2589 
2590 	hdd_update_wiphy_he_mcs(hdd_ctx->iftype_data_6g, he_cap_cfg);
2591 
2592 	band_6g->iftype_data = hdd_ctx->iftype_data_6g;
2593 }
2594 #else
2595 static inline void
2596 hdd_update_wiphy_he_caps_6ghz(struct hdd_context *hdd_ctx,
2597 			      tDot11fIEhe_cap *he_cap_cfg)
2598 {
2599 }
2600 #endif
2601 
2602 static void hdd_update_wiphy_he_cap(struct hdd_context *hdd_ctx)
2603 {
2604 	tDot11fIEhe_cap he_cap_cfg;
2605 	struct ieee80211_supported_band *band_2g =
2606 			hdd_ctx->wiphy->bands[HDD_NL80211_BAND_2GHZ];
2607 	struct ieee80211_supported_band *band_5g =
2608 			hdd_ctx->wiphy->bands[HDD_NL80211_BAND_5GHZ];
2609 	QDF_STATUS status;
2610 	uint8_t *phy_info_5g =
2611 		    hdd_ctx->iftype_data_5g->he_cap.he_cap_elem.phy_cap_info;
2612 	uint8_t max_fw_bw = sme_get_vht_ch_width();
2613 	uint32_t channel_bonding_mode_2g;
2614 	uint8_t *phy_info_2g =
2615 		    hdd_ctx->iftype_data_2g->he_cap.he_cap_elem.phy_cap_info;
2616 	uint8_t *mac_info_2g =
2617 		hdd_ctx->iftype_data_2g->he_cap.he_cap_elem.mac_cap_info;
2618 	uint8_t *mac_info_5g =
2619 		hdd_ctx->iftype_data_5g->he_cap.he_cap_elem.mac_cap_info;
2620 
2621 	status = ucfg_mlme_cfg_get_he_caps(hdd_ctx->psoc, &he_cap_cfg);
2622 
2623 	if (QDF_IS_STATUS_ERROR(status))
2624 		return;
2625 
2626 	if (band_2g) {
2627 		hdd_ctx->iftype_data_2g->types_mask =
2628 			(BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP));
2629 		hdd_ctx->iftype_data_2g->he_cap.has_he = he_cap_cfg.present;
2630 		band_2g->n_iftype_data = 1;
2631 		hdd_update_wiphy_he_mcs(hdd_ctx->iftype_data_2g, &he_cap_cfg);
2632 		band_2g->iftype_data = hdd_ctx->iftype_data_2g;
2633 
2634 		ucfg_mlme_get_channel_bonding_24ghz(hdd_ctx->psoc,
2635 						    &channel_bonding_mode_2g);
2636 		if (channel_bonding_mode_2g)
2637 			phy_info_2g[0] |=
2638 			    IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_IN_2G;
2639 
2640 		if (he_cap_cfg.twt_request)
2641 			mac_info_2g[0] |= IEEE80211_HE_MAC_CAP0_TWT_REQ;
2642 
2643 		if (he_cap_cfg.twt_responder)
2644 			mac_info_2g[0] |= IEEE80211_HE_MAC_CAP0_TWT_RES;
2645 	}
2646 	if (band_5g) {
2647 		hdd_ctx->iftype_data_5g->types_mask =
2648 			(BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP));
2649 		hdd_ctx->iftype_data_5g->he_cap.has_he = he_cap_cfg.present;
2650 		band_5g->n_iftype_data = 1;
2651 		hdd_update_wiphy_he_mcs(hdd_ctx->iftype_data_5g, &he_cap_cfg);
2652 		band_5g->iftype_data = hdd_ctx->iftype_data_5g;
2653 
2654 		if (max_fw_bw >= WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ)
2655 			phy_info_5g[0] |=
2656 				IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_80MHZ_IN_5G;
2657 		if (max_fw_bw >= WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ)
2658 			phy_info_5g[0] |=
2659 				IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_160MHZ_IN_5G;
2660 		if (max_fw_bw >= WNI_CFG_VHT_CHANNEL_WIDTH_80_PLUS_80MHZ)
2661 			phy_info_5g[0] |=
2662 			     IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G;
2663 
2664 		if (he_cap_cfg.twt_request)
2665 			mac_info_5g[0] |= IEEE80211_HE_MAC_CAP0_TWT_REQ;
2666 
2667 		if (he_cap_cfg.twt_responder)
2668 			mac_info_5g[0] |= IEEE80211_HE_MAC_CAP0_TWT_RES;
2669 	}
2670 
2671 	hdd_update_wiphy_he_caps_6ghz(hdd_ctx, &he_cap_cfg);
2672 }
2673 #else
2674 static void hdd_update_wiphy_he_cap(struct hdd_context *hdd_ctx)
2675 {
2676 }
2677 #endif
2678 
2679 static void hdd_component_cfg_chan_to_freq(struct wlan_objmgr_pdev *pdev)
2680 {
2681 	ucfg_mlme_cfg_chan_to_freq(pdev);
2682 }
2683 
2684 static uint32_t hdd_update_band_cap_from_dot11mode(
2685 		struct hdd_context *hdd_ctx, uint32_t band_capability)
2686 {
2687 	if (hdd_ctx->config->dot11Mode == eHDD_DOT11_MODE_AUTO)
2688 		return band_capability;
2689 
2690 	if (hdd_ctx->config->dot11Mode == eHDD_DOT11_MODE_11b ||
2691 	    hdd_ctx->config->dot11Mode == eHDD_DOT11_MODE_11g ||
2692 	    hdd_ctx->config->dot11Mode == eHDD_DOT11_MODE_11g_ONLY ||
2693 	    hdd_ctx->config->dot11Mode == eHDD_DOT11_MODE_11b_ONLY)
2694 		band_capability = (band_capability & (~BIT(REG_BAND_5G)));
2695 
2696 	if (hdd_ctx->config->dot11Mode == eHDD_DOT11_MODE_11a)
2697 		band_capability = (band_capability & (~BIT(REG_BAND_2G)));
2698 
2699 	if (hdd_ctx->config->dot11Mode != eHDD_DOT11_MODE_11ax_ONLY &&
2700 	    hdd_ctx->config->dot11Mode != eHDD_DOT11_MODE_11ax)
2701 		band_capability = (band_capability & (~BIT(REG_BAND_6G)));
2702 
2703 	qdf_debug("Update band capability %x", band_capability);
2704 	return band_capability;
2705 }
2706 
2707 #ifdef FEATURE_WPSS_THERMAL_MITIGATION
2708 static inline
2709 void hdd_update_multi_client_thermal_support(struct hdd_context *hdd_ctx)
2710 {
2711 	struct wmi_unified *wmi_handle;
2712 
2713 	wmi_handle = get_wmi_unified_hdl_from_psoc(hdd_ctx->psoc);
2714 	if (!wmi_handle)
2715 		return;
2716 
2717 	hdd_ctx->multi_client_thermal_mitigation =
2718 		wmi_service_enabled(wmi_handle,
2719 				    wmi_service_thermal_multi_client_support);
2720 }
2721 #else
2722 static inline
2723 void hdd_update_multi_client_thermal_support(struct hdd_context *hdd_ctx)
2724 {
2725 }
2726 #endif
2727 
2728 #ifdef WLAN_FEATURE_LOCAL_PKT_CAPTURE
2729 static void hdd_lpc_enable_powersave(struct hdd_context *hdd_ctx)
2730 {
2731 	struct hdd_adapter *sta_adapter;
2732 
2733 	if (!ucfg_dp_is_local_pkt_capture_enabled(hdd_ctx->psoc))
2734 		return;
2735 
2736 	ucfg_fwol_configure_global_params(hdd_ctx->psoc, hdd_ctx->pdev);
2737 
2738 	if (wma_enable_disable_imps(hdd_ctx->pdev->pdev_objmgr.wlan_pdev_id, 1))
2739 		hdd_err("IMPS feature enable failed");
2740 
2741 	sta_adapter = hdd_get_adapter(hdd_ctx, QDF_STA_MODE);
2742 	if (!sta_adapter) {
2743 		hdd_debug("STA adapter does not exist");
2744 		return;
2745 	}
2746 
2747 	wlan_hdd_set_powersave(sta_adapter->deflink, true, 0);
2748 }
2749 
2750 static void hdd_lpc_disable_powersave(struct hdd_context *hdd_ctx)
2751 {
2752 	struct hdd_adapter *sta_adapter;
2753 
2754 	if (!ucfg_dp_is_local_pkt_capture_enabled(hdd_ctx->psoc))
2755 		return;
2756 
2757 	ucfg_fwol_set_ilp_config(hdd_ctx->psoc, hdd_ctx->pdev, 0);
2758 
2759 	if (wma_enable_disable_imps(hdd_ctx->pdev->pdev_objmgr.wlan_pdev_id, 0))
2760 		hdd_err("IMPS feature disable failed");
2761 
2762 	sta_adapter = hdd_get_adapter(hdd_ctx, QDF_STA_MODE);
2763 	if (!sta_adapter) {
2764 		hdd_err("STA adapter does not exist");
2765 		return;
2766 	}
2767 	wlan_hdd_set_powersave(sta_adapter->deflink, false, 0);
2768 }
2769 #else
2770 static inline void hdd_lpc_enable_powersave(struct hdd_context *hdd_ctx)
2771 {
2772 }
2773 
2774 static inline void hdd_lpc_disable_powersave(struct hdd_context *hdd_ctx)
2775 {
2776 }
2777 #endif
2778 
2779 int hdd_update_tgt_cfg(hdd_handle_t hdd_handle, struct wma_tgt_cfg *cfg)
2780 {
2781 	int ret;
2782 	struct hdd_context *hdd_ctx = hdd_handle_to_context(hdd_handle);
2783 	uint32_t temp_band_cap, band_capability;
2784 	struct cds_config_info *cds_cfg = cds_get_ini_config();
2785 	uint8_t antenna_mode;
2786 	uint8_t sub_20_chan_width;
2787 	QDF_STATUS status;
2788 	mac_handle_t mac_handle;
2789 	bool bval = false;
2790 	uint8_t value = 0;
2791 	uint32_t fine_time_meas_cap = 0;
2792 	enum nss_chains_band_info band;
2793 	bool enable_dynamic_cfg;
2794 
2795 	if (!hdd_ctx) {
2796 		hdd_err("HDD context is NULL");
2797 		return -EINVAL;
2798 	}
2799 	ret = hdd_objmgr_create_and_store_pdev(hdd_ctx);
2800 	if (ret) {
2801 		QDF_DEBUG_PANIC("Failed to create pdev; errno:%d", ret);
2802 		return -EINVAL;
2803 	}
2804 
2805 	hdd_debug("New pdev has been created with pdev_id = %u",
2806 		  hdd_ctx->pdev->pdev_objmgr.wlan_pdev_id);
2807 
2808 	status = dispatcher_pdev_open(hdd_ctx->pdev);
2809 	if (QDF_IS_STATUS_ERROR(status)) {
2810 		QDF_DEBUG_PANIC("dispatcher pdev open failed; status:%d",
2811 				status);
2812 		ret = qdf_status_to_os_return(status);
2813 		goto exit;
2814 	}
2815 
2816 	status = hdd_component_pdev_open(hdd_ctx->pdev);
2817 	if (QDF_IS_STATUS_ERROR(status)) {
2818 		QDF_DEBUG_PANIC("hdd component pdev open failed; status:%d",
2819 				status);
2820 		ret = qdf_status_to_os_return(status);
2821 		goto dispatcher_close;
2822 	}
2823 	/*
2824 	 * For 6GHz support this api is added to convert mlme cfgs
2825 	 * channel numbers to frequency
2826 	 */
2827 	hdd_component_cfg_chan_to_freq(hdd_ctx->pdev);
2828 
2829 	hdd_objmgr_update_tgt_max_vdev_psoc(hdd_ctx, cfg->max_intf_count);
2830 
2831 	ucfg_ipa_set_dp_handle(hdd_ctx->psoc,
2832 			       cds_get_context(QDF_MODULE_ID_SOC));
2833 	ucfg_ipa_set_pdev_id(hdd_ctx->psoc, OL_TXRX_PDEV_ID);
2834 
2835 	status = ucfg_mlme_get_sub_20_chan_width(hdd_ctx->psoc,
2836 						 &sub_20_chan_width);
2837 	if (QDF_IS_STATUS_ERROR(status)) {
2838 		hdd_err("Failed to get sub_20_chan_width config");
2839 		ret = qdf_status_to_os_return(status);
2840 		goto pdev_close;
2841 	}
2842 
2843 	if (cds_cfg) {
2844 		if (sub_20_chan_width !=
2845 		    WLAN_SUB_20_CH_WIDTH_NONE && !cfg->sub_20_support) {
2846 			hdd_err("User requested sub 20 MHz channel width but unsupported by FW.");
2847 			cds_cfg->sub_20_channel_width =
2848 				WLAN_SUB_20_CH_WIDTH_NONE;
2849 		} else {
2850 			cds_cfg->sub_20_channel_width = sub_20_chan_width;
2851 		}
2852 	}
2853 
2854 	status = ucfg_mlme_get_band_capability(hdd_ctx->psoc, &band_capability);
2855 	if (QDF_IS_STATUS_ERROR(status)) {
2856 		hdd_err("Failed to get MLME band capability");
2857 		ret = qdf_status_to_os_return(status);
2858 		goto pdev_close;
2859 	}
2860 
2861 	band_capability =
2862 		hdd_update_band_cap_from_dot11mode(hdd_ctx, band_capability);
2863 
2864 	/* first store the INI band capability */
2865 	temp_band_cap = band_capability;
2866 
2867 	band_capability = cfg->band_cap;
2868 	hdd_ctx->is_fils_roaming_supported =
2869 			cfg->services.is_fils_roaming_supported;
2870 
2871 	hdd_ctx->config->is_11k_offload_supported =
2872 			cfg->services.is_11k_offload_supported;
2873 
2874 	/*
2875 	 * merge the target band capability with INI setting if the merge has
2876 	 * at least 1 band enabled
2877 	 */
2878 	temp_band_cap &= band_capability;
2879 	if (!temp_band_cap)
2880 		hdd_warn("ini BandCapability not supported by the target");
2881 	else
2882 		band_capability = temp_band_cap;
2883 
2884 	status = ucfg_mlme_set_band_capability(hdd_ctx->psoc, band_capability);
2885 	if (QDF_IS_STATUS_ERROR(status)) {
2886 		hdd_err("Failed to set MLME Band Capability");
2887 		ret = qdf_status_to_os_return(status);
2888 		goto pdev_close;
2889 	}
2890 
2891 	hdd_ctx->curr_band = band_capability;
2892 	hdd_ctx->psoc->soc_nif.user_config.band_capability = hdd_ctx->curr_band;
2893 
2894 	status = wlan_hdd_update_wiphy_supported_band(hdd_ctx);
2895 	if (QDF_IS_STATUS_ERROR(status)) {
2896 		hdd_err("Failed to update wiphy band info");
2897 		goto pdev_close;
2898 	}
2899 
2900 	status = ucfg_reg_set_band(hdd_ctx->pdev, band_capability);
2901 	if (QDF_IS_STATUS_ERROR(status))
2902 		/*
2903 		 * Continue, Do not close the pdev from here as if host fails
2904 		 * to update band information if cc_list event is not received
2905 		 * by this time, then also driver load should happen.
2906 		 */
2907 		hdd_err("Failed to update regulatory band info");
2908 
2909 	if (!cds_is_driver_recovering() || cds_is_driver_in_bad_state()) {
2910 		hdd_ctx->reg.reg_domain = cfg->reg_domain;
2911 		hdd_ctx->reg.eeprom_rd_ext = cfg->eeprom_rd_ext;
2912 	}
2913 
2914 	/* This can be extended to other configurations like ht, vht cap... */
2915 	status = wlan_hdd_validate_mac_address(&cfg->hw_macaddr);
2916 	if (QDF_IS_STATUS_SUCCESS(status))
2917 		qdf_mem_copy(&hdd_ctx->hw_macaddr, &cfg->hw_macaddr,
2918 			     QDF_MAC_ADDR_SIZE);
2919 
2920 	hdd_ctx->target_fw_version = cfg->target_fw_version;
2921 	hdd_ctx->target_fw_vers_ext = cfg->target_fw_vers_ext;
2922 	hdd_extract_fw_version_info(hdd_ctx);
2923 
2924 	hdd_ctx->hw_bd_id = cfg->hw_bd_id;
2925 	qdf_mem_copy(&hdd_ctx->hw_bd_info, &cfg->hw_bd_info,
2926 		     sizeof(cfg->hw_bd_info));
2927 
2928 	if (cfg->max_intf_count > WLAN_MAX_VDEVS) {
2929 		hdd_err("fw max vdevs (%u) > host max vdevs (%u); using %u",
2930 			cfg->max_intf_count, WLAN_MAX_VDEVS, WLAN_MAX_VDEVS);
2931 		hdd_ctx->max_intf_count = WLAN_MAX_VDEVS;
2932 	} else {
2933 		hdd_ctx->max_intf_count = cfg->max_intf_count;
2934 	}
2935 
2936 	hdd_sar_target_config(hdd_ctx, cfg);
2937 	hdd_lpass_target_config(hdd_ctx, cfg);
2938 
2939 	hdd_ctx->ap_arpns_support = cfg->ap_arpns_support;
2940 
2941 	hdd_update_tgt_services(hdd_ctx, &cfg->services);
2942 
2943 	hdd_update_tgt_ht_cap(hdd_ctx, &cfg->ht_cap);
2944 
2945 	sme_update_bfer_caps_as_per_nss_chains(hdd_ctx->mac_handle, cfg);
2946 
2947 	hdd_update_tgt_vht_cap(hdd_ctx, &cfg->vht_cap);
2948 	if (cfg->services.en_11ax  &&
2949 	    (hdd_ctx->config->dot11Mode == eHDD_DOT11_MODE_AUTO ||
2950 	     hdd_ctx->config->dot11Mode == eHDD_DOT11_MODE_11ax ||
2951 	     hdd_ctx->config->dot11Mode == eHDD_DOT11_MODE_11ax_ONLY)) {
2952 		hdd_debug("11AX: 11ax is enabled - update HDD config");
2953 		hdd_update_tgt_he_cap(hdd_ctx, cfg);
2954 		hdd_update_wiphy_he_cap(hdd_ctx);
2955 	}
2956 	hdd_update_tgt_twt_cap(hdd_ctx, cfg);
2957 	hdd_update_tgt_eht_cap(hdd_ctx, cfg);
2958 	hdd_update_wiphy_eht_cap(hdd_ctx);
2959 	ucfg_mlme_update_tgt_mlo_cap(hdd_ctx->psoc);
2960 
2961 	for (band = NSS_CHAINS_BAND_2GHZ; band < NSS_CHAINS_BAND_MAX; band++) {
2962 		sme_modify_nss_chains_tgt_cfg(hdd_ctx->mac_handle,
2963 					      QDF_STA_MODE, band);
2964 		sme_modify_nss_chains_tgt_cfg(hdd_ctx->mac_handle,
2965 					      QDF_SAP_MODE, band);
2966 		sme_modify_nss_chains_tgt_cfg(hdd_ctx->mac_handle,
2967 					      QDF_TDLS_MODE, band);
2968 		sme_modify_nss_chains_tgt_cfg(hdd_ctx->mac_handle,
2969 					      QDF_P2P_DEVICE_MODE,
2970 					      band);
2971 		sme_modify_nss_chains_tgt_cfg(hdd_ctx->mac_handle,
2972 					      QDF_OCB_MODE, band);
2973 		sme_modify_nss_chains_tgt_cfg(hdd_ctx->mac_handle,
2974 					      QDF_TDLS_MODE, band);
2975 	}
2976 
2977 	hdd_update_vdev_nss(hdd_ctx);
2978 
2979 	status =
2980 	  ucfg_mlme_get_enable_dynamic_nss_chains_cfg(hdd_ctx->psoc,
2981 						      &enable_dynamic_cfg);
2982 	if (QDF_IS_STATUS_ERROR(status)) {
2983 		hdd_err("unable to get enable dynamic config");
2984 		hdd_ctx->dynamic_nss_chains_support = false;
2985 	} else {
2986 		hdd_ctx->dynamic_nss_chains_support =
2987 					cfg->dynamic_nss_chains_support &
2988 					enable_dynamic_cfg;
2989 		hdd_debug("Dynamic nss chain support FW %d driver %d",
2990 			   cfg->dynamic_nss_chains_support, enable_dynamic_cfg);
2991 	}
2992 
2993 	status = ucfg_mlme_update_dynamic_nss_chains_support
2994 			(hdd_ctx->psoc, hdd_ctx->dynamic_nss_chains_support);
2995 	if (QDF_IS_STATUS_ERROR(status))
2996 		hdd_err("unable to set dynamic_nss_chains_support");
2997 
2998 	ucfg_mlme_get_fine_time_meas_cap(hdd_ctx->psoc, &fine_time_meas_cap);
2999 	fine_time_meas_cap &= cfg->fine_time_measurement_cap;
3000 	status = ucfg_mlme_set_fine_time_meas_cap(hdd_ctx->psoc,
3001 						  fine_time_meas_cap);
3002 	if (QDF_IS_STATUS_ERROR(status)) {
3003 		hdd_err("failed to set fine_time_meas_cap, 0x%x, ox%x",
3004 			fine_time_meas_cap, cfg->fine_time_measurement_cap);
3005 		ucfg_mlme_get_fine_time_meas_cap(hdd_ctx->psoc,
3006 						 &fine_time_meas_cap);
3007 	}
3008 
3009 	hdd_ctx->fine_time_meas_cap_target = cfg->fine_time_measurement_cap;
3010 	hdd_debug("fine_time_meas_cap: 0x%x", fine_time_meas_cap);
3011 
3012 	status = ucfg_mlme_get_vht_enable2x2(hdd_ctx->psoc, &bval);
3013 	if (!QDF_IS_STATUS_SUCCESS(status))
3014 		hdd_err("unable to get vht_enable2x2");
3015 
3016 	antenna_mode = (bval == 0x01) ?
3017 			HDD_ANTENNA_MODE_2X2 : HDD_ANTENNA_MODE_1X1;
3018 	hdd_update_smps_antenna_mode(hdd_ctx, antenna_mode);
3019 	hdd_debug("Init current antenna mode: %d",
3020 		  hdd_ctx->current_antenna_mode);
3021 
3022 	hdd_ctx->rcpi_enabled = cfg->rcpi_enabled;
3023 
3024 	status = ucfg_mlme_cfg_get_vht_tx_bfee_ant_supp(hdd_ctx->psoc,
3025 							&value);
3026 	if (QDF_IS_STATUS_ERROR(status)) {
3027 		status = false;
3028 		hdd_err("set tx_bfee_ant_supp failed");
3029 	}
3030 
3031 	status = ucfg_mlme_set_restricted_80p80_bw_supp(hdd_ctx->psoc,
3032 							cfg->restricted_80p80_bw_supp);
3033 	if (QDF_IS_STATUS_ERROR(status))
3034 		hdd_err("Failed to set MLME restircted 80p80 BW support");
3035 
3036 	if ((value > MLME_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED_FW_DEF) &&
3037 	    !cfg->tx_bfee_8ss_enabled) {
3038 		status = ucfg_mlme_cfg_set_vht_tx_bfee_ant_supp(hdd_ctx->psoc,
3039 				MLME_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED_FW_DEF);
3040 		if (QDF_IS_STATUS_ERROR(status)) {
3041 			status = false;
3042 			hdd_err("set tx_bfee_ant_supp failed");
3043 		}
3044 	}
3045 
3046 	hdd_update_tid_to_link_supported(hdd_ctx, &cfg->services);
3047 	mac_handle = hdd_ctx->mac_handle;
3048 
3049 	hdd_debug("txBFCsnValue %d", value);
3050 
3051 	/*
3052 	 * Update txBFCsnValue and NumSoundingDim values to vhtcap in wiphy
3053 	 */
3054 	hdd_update_wiphy_vhtcap(hdd_ctx);
3055 
3056 	hdd_update_vhtcap_2g(hdd_ctx);
3057 
3058 	hdd_ctx->wmi_max_len = cfg->wmi_max_len;
3059 
3060 	wlan_config_sched_scan_plans_to_wiphy(hdd_ctx->wiphy, hdd_ctx->psoc);
3061 	/*
3062 	 * This needs to be done after HDD pdev is created and stored since
3063 	 * it will access the HDD pdev object lock.
3064 	 */
3065 	hdd_runtime_suspend_context_init(hdd_ctx);
3066 
3067 	/* Configure NAN datapath features */
3068 	hdd_nan_datapath_target_config(hdd_ctx, cfg);
3069 	ucfg_nan_set_tgt_caps(hdd_ctx->psoc, &cfg->nan_caps);
3070 	hdd_ctx->dfs_cac_offload = cfg->dfs_cac_offload;
3071 	hdd_ctx->lte_coex_ant_share = cfg->services.lte_coex_ant_share;
3072 	hdd_ctx->obss_scan_offload = cfg->services.obss_scan_offload;
3073 	ucfg_scan_set_obss_scan_offload(hdd_ctx->psoc,
3074 					hdd_ctx->obss_scan_offload);
3075 	status = ucfg_mlme_set_obss_detection_offload_enabled(
3076 			hdd_ctx->psoc, cfg->obss_detection_offloaded);
3077 	if (QDF_IS_STATUS_ERROR(status))
3078 		hdd_err("Couldn't pass WNI_CFG_OBSS_DETECTION_OFFLOAD to CFG");
3079 
3080 	status = ucfg_mlme_set_obss_color_collision_offload_enabled(
3081 			hdd_ctx->psoc, cfg->obss_color_collision_offloaded);
3082 	if (QDF_IS_STATUS_ERROR(status))
3083 		hdd_err("Failed to set WNI_CFG_OBSS_COLOR_COLLISION_OFFLOAD");
3084 
3085 	ucfg_mlme_set_bss_color_collision_det_support(
3086 					hdd_ctx->psoc,
3087 					cfg->obss_color_collision_offloaded);
3088 	if (!cfg->obss_color_collision_offloaded) {
3089 		status = ucfg_mlme_set_bss_color_collision_det_sta(
3090 				hdd_ctx->psoc,
3091 				cfg->obss_color_collision_offloaded);
3092 		if (QDF_IS_STATUS_ERROR(status))
3093 			hdd_err("Failed to set CFG_BSS_CLR_COLLISION_DET_STA");
3094 	}
3095 
3096 	hdd_update_score_config(hdd_ctx);
3097 	hdd_update_multi_client_thermal_support(hdd_ctx);
3098 
3099 	ucfg_psoc_mlme_set_11be_capab(hdd_ctx->psoc, cfg->services.en_11be);
3100 	return 0;
3101 
3102 dispatcher_close:
3103 	dispatcher_pdev_close(hdd_ctx->pdev);
3104 pdev_close:
3105 	hdd_component_pdev_close(hdd_ctx->pdev);
3106 exit:
3107 	hdd_objmgr_release_and_destroy_pdev(hdd_ctx);
3108 
3109 	return ret;
3110 }
3111 
3112 bool hdd_dfs_indicate_radar(struct hdd_context *hdd_ctx)
3113 {
3114 	struct hdd_adapter *adapter, *next_adapter = NULL;
3115 	struct hdd_ap_ctx *ap_ctx;
3116 	uint32_t ap_chan;
3117 	bool dfs_disable_channel_switch = false;
3118 	struct wlan_hdd_link_info *link_info;
3119 
3120 	if (!hdd_ctx) {
3121 		hdd_info("Couldn't get hdd_ctx");
3122 		return true;
3123 	}
3124 
3125 	ucfg_mlme_get_dfs_disable_channel_switch(hdd_ctx->psoc,
3126 						 &dfs_disable_channel_switch);
3127 	if (dfs_disable_channel_switch) {
3128 		hdd_info("skip tx block hdd_ctx=%pK, disableDFSChSwitch=%d",
3129 			 hdd_ctx, dfs_disable_channel_switch);
3130 		return true;
3131 	}
3132 
3133 	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
3134 					   NET_DEV_HOLD_DFS_INDICATE_RADAR) {
3135 
3136 		if (adapter->device_mode != QDF_SAP_MODE &&
3137 		    adapter->device_mode != QDF_P2P_GO_MODE)
3138 			goto next_adapter;
3139 
3140 		hdd_adapter_for_each_active_link_info(adapter, link_info) {
3141 			ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(link_info);
3142 			ap_chan = ap_ctx->operating_chan_freq;
3143 			if (!wlan_reg_is_passive_or_disable_for_pwrmode(hdd_ctx->pdev,
3144 							ap_chan, REG_CURRENT_PWR_MODE))
3145 				continue;
3146 
3147 			ap_ctx->dfs_cac_block_tx = true;
3148 			hdd_info("tx blocked for vdev: %d", link_info->vdev_id);
3149 			if (link_info->vdev_id != WLAN_UMAC_VDEV_ID_MAX)
3150 				cdp_fc_vdev_flush(
3151 					cds_get_context(QDF_MODULE_ID_SOC),
3152 					link_info->vdev_id);
3153 		}
3154 next_adapter:
3155 		hdd_adapter_dev_put_debug(adapter,
3156 					  NET_DEV_HOLD_DFS_INDICATE_RADAR);
3157 	}
3158 
3159 	return true;
3160 }
3161 
3162 bool hdd_is_valid_mac_address(const uint8_t *mac_addr)
3163 {
3164 	int xdigit = 0;
3165 	int separator = 0;
3166 
3167 	while (*mac_addr) {
3168 		if (isxdigit(*mac_addr)) {
3169 			xdigit++;
3170 		} else if (':' == *mac_addr) {
3171 			if (0 == xdigit || ((xdigit / 2) - 1) != separator)
3172 				break;
3173 
3174 			++separator;
3175 		} else {
3176 			/* Invalid MAC found */
3177 			return false;
3178 		}
3179 		++mac_addr;
3180 	}
3181 	return xdigit == 12 && (separator == 5 || separator == 0);
3182 }
3183 
3184 /**
3185  * hdd_mon_mode_ether_setup() - Update monitor mode struct net_device.
3186  * @dev: Handle to struct net_device to be updated.
3187  *
3188  * Return: None
3189  */
3190 static void hdd_mon_mode_ether_setup(struct net_device *dev)
3191 {
3192 	dev->header_ops         = NULL;
3193 	dev->type               = ARPHRD_IEEE80211_RADIOTAP;
3194 	dev->hard_header_len    = ETH_HLEN;
3195 	dev->mtu                = ETH_DATA_LEN;
3196 	dev->addr_len           = ETH_ALEN;
3197 	dev->tx_queue_len       = 1000; /* Ethernet wants good queues */
3198 	dev->flags              = IFF_BROADCAST|IFF_MULTICAST;
3199 	dev->priv_flags        |= IFF_TX_SKB_SHARING;
3200 
3201 	memset(dev->broadcast, 0xFF, ETH_ALEN);
3202 }
3203 
3204 #ifdef FEATURE_MONITOR_MODE_SUPPORT
3205 /**
3206  * hdd_mon_turn_off_ps_and_wow() - Update monitor mode struct net_device.
3207  * @hdd_ctx: Pointer to HDD context.
3208  *
3209  * Return: None
3210  */
3211 static void hdd_mon_turn_off_ps_and_wow(struct hdd_context *hdd_ctx)
3212 {
3213 	ucfg_pmo_set_power_save_mode(hdd_ctx->psoc,
3214 				     PMO_PS_ADVANCED_POWER_SAVE_DISABLE);
3215 	ucfg_pmo_set_wow_enable(hdd_ctx->psoc, PMO_WOW_DISABLE_BOTH);
3216 }
3217 
3218 /**
3219  * __hdd_mon_open() - HDD Open function
3220  * @dev: Pointer to net_device structure
3221  *
3222  * This is called in response to ifconfig up
3223  *
3224  * Return: 0 for success; non-zero for failure
3225  */
3226 static int __hdd_mon_open(struct net_device *dev)
3227 {
3228 	int ret;
3229 	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
3230 	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
3231 	struct bbm_params param = {0};
3232 
3233 	hdd_enter_dev(dev);
3234 
3235 	if (test_bit(DEVICE_IFACE_OPENED, &adapter->event_flags)) {
3236 		hdd_debug_rl("Monitor interface is already up");
3237 		return 0;
3238 	}
3239 
3240 	ret = wlan_hdd_validate_context(hdd_ctx);
3241 	if (ret)
3242 		return ret;
3243 
3244 	hdd_mon_mode_ether_setup(dev);
3245 
3246 	if (con_mode == QDF_GLOBAL_MONITOR_MODE ||
3247 	    ucfg_mlme_is_sta_mon_conc_supported(hdd_ctx->psoc) ||
3248 	    ucfg_dp_is_local_pkt_capture_enabled(hdd_ctx->psoc)) {
3249 		ret = hdd_trigger_psoc_idle_restart(hdd_ctx);
3250 		if (ret) {
3251 			hdd_err("Failed to start WLAN modules return");
3252 			return ret;
3253 		}
3254 		hdd_err("hdd_wlan_start_modules() successful !");
3255 
3256 		if ((!test_bit(SME_SESSION_OPENED,
3257 			       &adapter->deflink->link_flags)) ||
3258 		    (policy_mgr_is_sta_mon_concurrency(hdd_ctx->psoc))) {
3259 			ret = hdd_start_adapter(adapter, true);
3260 			if (ret) {
3261 				hdd_err("Failed to start adapter :%d",
3262 						adapter->device_mode);
3263 				return ret;
3264 			}
3265 			hdd_err("hdd_start_adapters() successful !");
3266 		}
3267 		hdd_mon_turn_off_ps_and_wow(hdd_ctx);
3268 		set_bit(DEVICE_IFACE_OPENED, &adapter->event_flags);
3269 	}
3270 
3271 	if (con_mode != QDF_GLOBAL_MONITOR_MODE &&
3272 	    (ucfg_mlme_is_sta_mon_conc_supported(hdd_ctx->psoc) ||
3273 	     ucfg_dp_is_local_pkt_capture_enabled(hdd_ctx->psoc))) {
3274 		hdd_info("Acquire wakelock for STA + monitor mode");
3275 
3276 		qdf_wake_lock_acquire(&hdd_ctx->monitor_mode_wakelock,
3277 				      WIFI_POWER_EVENT_WAKELOCK_MONITOR_MODE);
3278 		hdd_lpc_disable_powersave(hdd_ctx);
3279 		qdf_runtime_pm_prevent_suspend(
3280 			&hdd_ctx->runtime_context.monitor_mode);
3281 	}
3282 
3283 	ret = hdd_set_mon_rx_cb(dev);
3284 
3285 	if (!ret)
3286 		ret = hdd_enable_monitor_mode(dev);
3287 
3288 	if (!ret) {
3289 		param.policy = BBM_DRIVER_MODE_POLICY;
3290 		param.policy_info.driver_mode = QDF_GLOBAL_MONITOR_MODE;
3291 		ucfg_dp_bbm_apply_independent_policy(hdd_ctx->psoc, &param);
3292 		ucfg_dp_set_current_throughput_level(hdd_ctx->psoc,
3293 						     PLD_BUS_WIDTH_VERY_HIGH);
3294 	}
3295 
3296 	return ret;
3297 }
3298 
3299 /**
3300  * hdd_mon_open() - Wrapper function for __hdd_mon_open to protect it from SSR
3301  * @net_dev: Pointer to net_device structure
3302  *
3303  * This is called in response to ifconfig up
3304  *
3305  * Return: 0 for success; non-zero for failure
3306  */
3307 static int hdd_mon_open(struct net_device *net_dev)
3308 {
3309 	int errno;
3310 	struct osif_vdev_sync *vdev_sync;
3311 
3312 	errno = osif_vdev_sync_trans_start(net_dev, &vdev_sync);
3313 	if (errno)
3314 		return errno;
3315 
3316 	errno = __hdd_mon_open(net_dev);
3317 
3318 	osif_vdev_sync_trans_stop(vdev_sync);
3319 
3320 	return errno;
3321 }
3322 #endif
3323 
3324 #ifdef WLAN_FEATURE_PKT_CAPTURE
3325 /**
3326  * __hdd_pktcapture_open() - HDD Open function
3327  * @dev: Pointer to net_device structure
3328  *
3329  * This is called in response to ifconfig up
3330  *
3331  * Return: 0 for success; non-zero for failure
3332  */
3333 static int __hdd_pktcapture_open(struct net_device *dev)
3334 {
3335 	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
3336 	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
3337 	struct hdd_adapter *sta_adapter;
3338 	QDF_STATUS status;
3339 	struct wlan_objmgr_vdev *vdev;
3340 	int ret;
3341 
3342 	hdd_enter_dev(dev);
3343 
3344 	ret = wlan_hdd_validate_context(hdd_ctx);
3345 	if (ret)
3346 		return ret;
3347 
3348 	sta_adapter = hdd_get_adapter(hdd_ctx, QDF_STA_MODE);
3349 	if (!sta_adapter) {
3350 		hdd_err("No station interface found");
3351 		return -EINVAL;
3352 	}
3353 
3354 	vdev = hdd_objmgr_get_vdev_by_user(sta_adapter->deflink, WLAN_OSIF_ID);
3355 	if (!vdev)
3356 		return -EINVAL;
3357 
3358 	hdd_mon_mode_ether_setup(dev);
3359 
3360 	status = ucfg_dp_register_pkt_capture_callbacks(vdev);
3361 	ret = qdf_status_to_os_return(status);
3362 	if (ret) {
3363 		hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_ID);
3364 		return ret;
3365 	}
3366 
3367 	adapter->deflink->vdev = vdev;
3368 	set_bit(DEVICE_IFACE_OPENED, &adapter->event_flags);
3369 	sta_adapter->mon_adapter = adapter;
3370 
3371 	return ret;
3372 }
3373 
3374 /**
3375  * hdd_pktcapture_open() - Wrapper function for hdd_pktcapture_open to
3376  * protect it from SSR
3377  * @net_dev: Pointer to net_device structure
3378  *
3379  * This is called in response to ifconfig up
3380  *
3381  * Return: 0 for success; non-zero for failure
3382  */
3383 static int hdd_pktcapture_open(struct net_device *net_dev)
3384 {
3385 	int errno;
3386 	struct osif_vdev_sync *vdev_sync;
3387 
3388 	errno = osif_vdev_sync_trans_start(net_dev, &vdev_sync);
3389 	if (errno)
3390 		return errno;
3391 
3392 	errno = __hdd_pktcapture_open(net_dev);
3393 
3394 	osif_vdev_sync_trans_stop(vdev_sync);
3395 
3396 	return errno;
3397 }
3398 
3399 /**
3400  * hdd_unmap_monitor_interface_vdev() - unmap monitor interface vdev and
3401  * deregister packet capture callbacks
3402  * @sta_adapter: station adapter
3403  *
3404  * Return: void
3405  */
3406 static void
3407 hdd_unmap_monitor_interface_vdev(struct hdd_adapter *sta_adapter)
3408 {
3409 	struct hdd_adapter *mon_adapter = sta_adapter->mon_adapter;
3410 
3411 	if (mon_adapter && hdd_is_interface_up(mon_adapter)) {
3412 		ucfg_pkt_capture_deregister_callbacks(
3413 						mon_adapter->deflink->vdev);
3414 		hdd_objmgr_put_vdev_by_user(mon_adapter->deflink->vdev,
3415 					    WLAN_OSIF_ID);
3416 		mon_adapter->deflink->vdev = NULL;
3417 		hdd_reset_monitor_interface(sta_adapter);
3418 	}
3419 }
3420 
3421 /**
3422  * hdd_map_monitor_interface_vdev() - Map monitor interface vdev and
3423  * register packet capture callbacks
3424  * @sta_adapter: Station adapter
3425  *
3426  * Return: None
3427  */
3428 static void hdd_map_monitor_interface_vdev(struct hdd_adapter *sta_adapter)
3429 {
3430 	struct hdd_adapter *mon_adapter;
3431 	QDF_STATUS status;
3432 	struct wlan_objmgr_vdev *vdev;
3433 	int ret;
3434 
3435 	mon_adapter = hdd_get_adapter(sta_adapter->hdd_ctx, QDF_MONITOR_MODE);
3436 	if (!mon_adapter) {
3437 		hdd_debug("No monitor interface found");
3438 		return;
3439 	}
3440 
3441 	if (!mon_adapter || !hdd_is_interface_up(mon_adapter)) {
3442 		hdd_debug("Monitor interface is not up\n");
3443 		return;
3444 	}
3445 
3446 	if (!wlan_hdd_is_session_type_monitor(mon_adapter->device_mode))
3447 		return;
3448 
3449 	vdev = hdd_objmgr_get_vdev_by_user(sta_adapter->deflink, WLAN_OSIF_ID);
3450 	if (!vdev)
3451 		return;
3452 
3453 	status = ucfg_dp_register_pkt_capture_callbacks(vdev);
3454 	ret = qdf_status_to_os_return(status);
3455 	if (ret) {
3456 		hdd_err("Failed registering packet capture callbacks");
3457 		hdd_objmgr_put_vdev_by_user(vdev,
3458 					    WLAN_OSIF_ID);
3459 		return;
3460 	}
3461 
3462 	mon_adapter->deflink->vdev = vdev;
3463 	sta_adapter->mon_adapter = mon_adapter;
3464 }
3465 
3466 void hdd_reset_monitor_interface(struct hdd_adapter *sta_adapter)
3467 {
3468 	sta_adapter->mon_adapter = NULL;
3469 }
3470 
3471 struct hdd_adapter *
3472 hdd_is_pkt_capture_mon_enable(struct hdd_adapter *sta_adapter)
3473 {
3474 	return sta_adapter->mon_adapter;
3475 }
3476 #else
3477 static inline void
3478 hdd_unmap_monitor_interface_vdev(struct hdd_adapter *sta_adapter)
3479 {
3480 }
3481 
3482 static inline void
3483 hdd_map_monitor_interface_vdev(struct hdd_adapter *sta_adapter)
3484 {
3485 }
3486 #endif
3487 
3488 static QDF_STATUS
3489 wlan_hdd_update_dbs_scan_and_fw_mode_config(void)
3490 {
3491 	struct policy_mgr_dual_mac_config cfg = {0};
3492 	QDF_STATUS status;
3493 	uint32_t chnl_sel_logic_conc = 0;
3494 	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
3495 	uint8_t dual_mac_feature = DISABLE_DBS_CXN_AND_SCAN;
3496 
3497 	if (!hdd_ctx)
3498 		return QDF_STATUS_E_FAILURE;
3499 
3500 	/*
3501 	 * ROME platform doesn't support any DBS related commands in FW,
3502 	 * so if driver sends wmi command with dual_mac_config with all set to
3503 	 * 0 then FW wouldn't respond back and driver would timeout on waiting
3504 	 * for response. Check if FW supports DBS to eliminate ROME vs
3505 	 * NON-ROME platform.
3506 	 */
3507 	if (!policy_mgr_find_if_fw_supports_dbs(hdd_ctx->psoc))
3508 		return QDF_STATUS_SUCCESS;
3509 
3510 	if (hdd_ctx->is_dual_mac_cfg_updated) {
3511 		hdd_debug("dual mac config has already been updated, skip");
3512 		return QDF_STATUS_SUCCESS;
3513 	}
3514 
3515 	cfg.scan_config = 0;
3516 	cfg.fw_mode_config = 0;
3517 	cfg.set_dual_mac_cb = policy_mgr_soc_set_dual_mac_cfg_cb;
3518 	if (policy_mgr_is_hw_dbs_capable(hdd_ctx->psoc)) {
3519 		status =
3520 		ucfg_policy_mgr_get_chnl_select_plcy(hdd_ctx->psoc,
3521 						     &chnl_sel_logic_conc);
3522 		if (status != QDF_STATUS_SUCCESS) {
3523 			hdd_err("can't get chnl sel policy, use def");
3524 			return status;
3525 		}
3526 	}
3527 	status =
3528 	ucfg_policy_mgr_get_dual_mac_feature(hdd_ctx->psoc,
3529 					     &dual_mac_feature);
3530 	if (status != QDF_STATUS_SUCCESS) {
3531 		hdd_err("ucfg_policy_mgr_get_dual_mac_feature failed, use def");
3532 		return status;
3533 	}
3534 
3535 	if (dual_mac_feature != DISABLE_DBS_CXN_AND_SCAN) {
3536 		status = policy_mgr_get_updated_scan_and_fw_mode_config(
3537 				hdd_ctx->psoc, &cfg.scan_config,
3538 				&cfg.fw_mode_config,
3539 				dual_mac_feature,
3540 				chnl_sel_logic_conc);
3541 
3542 		if (status != QDF_STATUS_SUCCESS) {
3543 			hdd_err("wma_get_updated_scan_and_fw_mode_config failed %d",
3544 				status);
3545 			return status;
3546 		}
3547 	}
3548 
3549 	hdd_debug("send scan_cfg: 0x%x fw_mode_cfg: 0x%x to fw",
3550 		cfg.scan_config, cfg.fw_mode_config);
3551 
3552 	status = sme_soc_set_dual_mac_config(cfg);
3553 	if (QDF_IS_STATUS_ERROR(status)) {
3554 		hdd_err("sme_soc_set_dual_mac_config failed %d", status);
3555 		return status;
3556 	}
3557 	hdd_ctx->is_dual_mac_cfg_updated = true;
3558 
3559 	return QDF_STATUS_SUCCESS;
3560 }
3561 
3562 /**
3563  * hdd_max_sta_interface_up_count_reached() - check sta/p2p_cli vdev count
3564  * @adapter: HDD adapter
3565  *
3566  * Return: true if vdev limit reached
3567  */
3568 static bool hdd_max_sta_interface_up_count_reached(struct hdd_adapter *adapter)
3569 {
3570 	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
3571 	struct hdd_adapter *temp_adapter = NULL, *next_adapter = NULL;
3572 	uint8_t intf_count = 0;
3573 	wlan_net_dev_ref_dbgid dbgid =
3574 				NET_DEV_HOLD_MAX_STA_INTERFACE_UP_COUNT_REACHED;
3575 
3576 	if (0 == CFG_TGT_DEFAULT_MAX_STA_VDEVS)
3577 		return false;
3578 
3579 	/*
3580 	 * Check for max no of supported STA/P2PCLI VDEVs before
3581 	 * creating another one.
3582 	 */
3583 	hdd_for_each_adapter_dev_held_safe(hdd_ctx, temp_adapter,
3584 					   next_adapter, dbgid) {
3585 		if ((temp_adapter != adapter) &&
3586 		    (temp_adapter->dev->flags & IFF_UP) &&
3587 		    ((temp_adapter->device_mode == QDF_STA_MODE) ||
3588 		     (temp_adapter->device_mode == QDF_P2P_CLIENT_MODE)))
3589 			intf_count++;
3590 
3591 		hdd_adapter_dev_put_debug(temp_adapter, dbgid);
3592 	}
3593 
3594 	if (intf_count >= CFG_TGT_DEFAULT_MAX_STA_VDEVS) {
3595 		hdd_err("Max limit reached sta vdev-current %d max %d",
3596 			intf_count, CFG_TGT_DEFAULT_MAX_STA_VDEVS);
3597 		return true;
3598 	}
3599 	return false;
3600 }
3601 
3602 #if (defined(WLAN_FEATURE_11BE_MLO) && defined(CFG80211_11BE_BASIC)) && \
3603 (defined(CFG80211_IFTYPE_MLO_LINK_SUPPORT) || \
3604 defined(CFG80211_SINGLE_NETDEV_MULTI_LINK_SUPPORT)) && \
3605 !defined(WLAN_HDD_MULTI_VDEV_SINGLE_NDEV)
3606 static int hdd_start_link_adapter(struct hdd_adapter *sta_adapter)
3607 {
3608 	int i, ret = 0;
3609 	struct hdd_mlo_adapter_info *mlo_adapter_info;
3610 	struct hdd_adapter *link_adapter;
3611 
3612 	hdd_enter_dev(sta_adapter->dev);
3613 	mlo_adapter_info = &sta_adapter->mlo_adapter_info;
3614 
3615 	for (i = 0; i < WLAN_MAX_MLD; i++) {
3616 		link_adapter = mlo_adapter_info->link_adapter[i];
3617 		if (!link_adapter)
3618 			continue;
3619 		if (link_adapter->mlo_adapter_info.associate_with_ml_adapter) {
3620 			/* TODO have proper references here */
3621 			qdf_spin_lock_bh(&link_adapter->deflink->vdev_lock);
3622 			link_adapter->deflink->vdev =
3623 						sta_adapter->deflink->vdev;
3624 			link_adapter->deflink->vdev_id =
3625 						sta_adapter->deflink->vdev_id;
3626 			qdf_spin_unlock_bh(&link_adapter->deflink->vdev_lock);
3627 
3628 			sta_adapter->link_info[i].vdev_id =
3629 						sta_adapter->deflink->vdev_id;
3630 			continue;
3631 		}
3632 		ret = hdd_start_station_adapter(link_adapter);
3633 		if (!ret) {
3634 			sta_adapter->link_info[i].vdev_id =
3635 						link_adapter->deflink->vdev_id;
3636 		}
3637 	}
3638 
3639 	hdd_adapter_update_mlo_mgr_mac_addr(sta_adapter);
3640 
3641 	hdd_exit();
3642 	return ret;
3643 }
3644 
3645 static int hdd_stop_link_adapter(struct hdd_context *hdd_ctx,
3646 				 struct hdd_adapter *sta_adapter)
3647 {
3648 	int i, ret = 0;
3649 	struct hdd_mlo_adapter_info *mlo_adapter_info;
3650 	struct hdd_adapter *link_adapter;
3651 
3652 	hdd_enter_dev(sta_adapter->dev);
3653 	hdd_debug("Stop adapter for link mode : %s(%d)",
3654 		  qdf_opmode_str(sta_adapter->device_mode),
3655 		  sta_adapter->deflink->vdev_id);
3656 
3657 	mlo_adapter_info = &sta_adapter->mlo_adapter_info;
3658 	for (i = 0; i < WLAN_MAX_MLD; i++) {
3659 		link_adapter = mlo_adapter_info->link_adapter[i];
3660 		if (!link_adapter)
3661 			continue;
3662 
3663 		if (link_adapter->mlo_adapter_info.associate_with_ml_adapter) {
3664 			/* TODO have proper references here */
3665 			qdf_spin_lock_bh(&link_adapter->deflink->vdev_lock);
3666 			link_adapter->deflink->vdev = NULL;
3667 			link_adapter->deflink->vdev_id = 0xff;
3668 			qdf_spin_unlock_bh(&link_adapter->deflink->vdev_lock);
3669 			continue;
3670 		}
3671 		ret = hdd_stop_adapter_ext(hdd_ctx, link_adapter);
3672 	}
3673 
3674 	hdd_exit();
3675 	return ret;
3676 }
3677 #else
3678 static int hdd_start_link_adapter(struct hdd_adapter *link_adapter)
3679 {
3680 	return 0;
3681 }
3682 
3683 static int hdd_stop_link_adapter(struct hdd_context *hdd_ctx,
3684 				 struct hdd_adapter *link_adapter)
3685 {
3686 	return 0;
3687 }
3688 #endif
3689 
3690 /**
3691  * hdd_start_adapter() - Wrapper function for device specific adapter
3692  * @adapter: pointer to HDD adapter
3693  * @rtnl_held: true if rtnl lock is taken, otherwise false
3694  *
3695  * This function is called to start the device specific adapter for
3696  * the mode passed in the adapter's device_mode.
3697  *
3698  * Return: 0 for success; non-zero for failure
3699  */
3700 int hdd_start_adapter(struct hdd_adapter *adapter, bool rtnl_held)
3701 {
3702 
3703 	int ret;
3704 	enum QDF_OPMODE device_mode = adapter->device_mode;
3705 
3706 	hdd_enter_dev(adapter->dev);
3707 
3708 	switch (device_mode) {
3709 	case QDF_MONITOR_MODE:
3710 		ret = hdd_start_station_adapter(adapter);
3711 		if (ret)
3712 			goto err_start_adapter;
3713 		hdd_set_idle_ps_config(adapter->hdd_ctx, false);
3714 		break;
3715 	case QDF_STA_MODE:
3716 	case QDF_P2P_CLIENT_MODE:
3717 		if (hdd_max_sta_interface_up_count_reached(adapter))
3718 			goto err_start_adapter;
3719 		fallthrough;
3720 	case QDF_P2P_DEVICE_MODE:
3721 	case QDF_OCB_MODE:
3722 	case QDF_NAN_DISC_MODE:
3723 		ret = hdd_start_station_adapter(adapter);
3724 		if (ret)
3725 			goto err_start_adapter;
3726 
3727 		if (device_mode == QDF_STA_MODE) {
3728 			ret = hdd_start_link_adapter(adapter);
3729 			if (ret)
3730 				hdd_err("Failed to start link adapter:%d", ret);
3731 		}
3732 		break;
3733 	case QDF_P2P_GO_MODE:
3734 	case QDF_SAP_MODE:
3735 		ret = hdd_start_ap_adapter(adapter, rtnl_held);
3736 		if (ret)
3737 			goto err_start_adapter;
3738 		break;
3739 	case QDF_FTM_MODE:
3740 		/* vdevs are dynamically managed by firmware in FTM */
3741 		hdd_register_wext(adapter->dev);
3742 		goto exit_with_success;
3743 	default:
3744 		hdd_err("Invalid session type %d", device_mode);
3745 		QDF_ASSERT(0);
3746 		goto err_start_adapter;
3747 	}
3748 
3749 	if (hdd_set_fw_params(adapter))
3750 		hdd_err("Failed to set the FW params for the adapter!");
3751 
3752 	if (adapter->deflink->vdev_id != WLAN_UMAC_VDEV_ID_MAX) {
3753 		ret = wlan_hdd_cfg80211_register_frames(adapter);
3754 		if (ret < 0) {
3755 			hdd_err("Failed to register frames - ret %d", ret);
3756 			goto err_start_adapter;
3757 		}
3758 	}
3759 
3760 	wlan_hdd_update_dbs_scan_and_fw_mode_config();
3761 
3762 exit_with_success:
3763 	hdd_create_adapter_sysfs_files(adapter);
3764 
3765 	hdd_exit();
3766 
3767 	return 0;
3768 
3769 err_start_adapter:
3770 	return -EINVAL;
3771 }
3772 
3773 void hdd_update_hw_sw_info(struct hdd_context *hdd_ctx)
3774 {
3775 	void *hif_sc;
3776 	size_t target_hw_name_len;
3777 	const char *target_hw_name;
3778 	uint8_t *buf;
3779 	uint32_t buf_len;
3780 
3781 	hif_sc = cds_get_context(QDF_MODULE_ID_HIF);
3782 	if (!hif_sc)
3783 		return;
3784 
3785 	hif_get_hw_info(hif_sc, &hdd_ctx->target_hw_version,
3786 			&hdd_ctx->target_hw_revision,
3787 			&target_hw_name);
3788 
3789 	qdf_mem_zero(hdd_ctx->target_hw_name, MAX_TGT_HW_NAME_LEN);
3790 
3791 	target_hw_name_len = strlen(target_hw_name) + 1;
3792 
3793 	if (target_hw_name_len <= MAX_TGT_HW_NAME_LEN) {
3794 		qdf_mem_copy(hdd_ctx->target_hw_name, target_hw_name,
3795 			     target_hw_name_len);
3796 	} else {
3797 		hdd_err("target_hw_name_len is greater than MAX_TGT_HW_NAME_LEN");
3798 		return;
3799 	}
3800 
3801 	hdd_debug("target_hw_name = %s", hdd_ctx->target_hw_name);
3802 
3803 	buf = qdf_mem_malloc(WE_MAX_STR_LEN);
3804 	if (buf) {
3805 		buf_len = hdd_wlan_get_version(hdd_ctx, WE_MAX_STR_LEN, buf);
3806 		hdd_nofl_debug("%s", buf);
3807 		qdf_mem_free(buf);
3808 	}
3809 }
3810 
3811 /**
3812  * hdd_update_cds_ac_specs_params() - update cds ac_specs params
3813  * @hdd_ctx: Pointer to hdd context
3814  *
3815  * Return: none
3816  */
3817 static void
3818 hdd_update_cds_ac_specs_params(struct hdd_context *hdd_ctx)
3819 {
3820 	uint8_t tx_sched_wrr_param[TX_SCHED_WRR_PARAMS_NUM] = {0};
3821 	qdf_size_t out_size = 0;
3822 	int i;
3823 	struct cds_context *cds_ctx;
3824 
3825 	if (!hdd_ctx)
3826 		return;
3827 
3828 	if (!hdd_ctx->config) {
3829 		/* Do nothing if hdd_ctx is invalid */
3830 		hdd_err("Warning: hdd_ctx->cfg_ini is NULL");
3831 		return;
3832 	}
3833 
3834 	cds_ctx = cds_get_context(QDF_MODULE_ID_QDF);
3835 	if (!cds_ctx)
3836 		return;
3837 
3838 	for (i = 0; i < QCA_WLAN_AC_ALL; i++) {
3839 		switch (i) {
3840 		case QCA_WLAN_AC_BE:
3841 			qdf_uint8_array_parse(
3842 				cfg_get(hdd_ctx->psoc,
3843 					CFG_DP_ENABLE_TX_SCHED_WRR_BE),
3844 				tx_sched_wrr_param,
3845 				sizeof(tx_sched_wrr_param),
3846 				&out_size);
3847 			break;
3848 		case QCA_WLAN_AC_BK:
3849 			qdf_uint8_array_parse(
3850 				cfg_get(hdd_ctx->psoc,
3851 					CFG_DP_ENABLE_TX_SCHED_WRR_BK),
3852 				tx_sched_wrr_param,
3853 				sizeof(tx_sched_wrr_param),
3854 				&out_size);
3855 			break;
3856 		case QCA_WLAN_AC_VI:
3857 			qdf_uint8_array_parse(
3858 				cfg_get(hdd_ctx->psoc,
3859 					CFG_DP_ENABLE_TX_SCHED_WRR_VI),
3860 				tx_sched_wrr_param,
3861 				sizeof(tx_sched_wrr_param),
3862 				&out_size);
3863 			break;
3864 		case QCA_WLAN_AC_VO:
3865 			qdf_uint8_array_parse(
3866 				cfg_get(hdd_ctx->psoc,
3867 					CFG_DP_ENABLE_TX_SCHED_WRR_VO),
3868 				tx_sched_wrr_param,
3869 				sizeof(tx_sched_wrr_param),
3870 				&out_size);
3871 			break;
3872 		default:
3873 			break;
3874 		}
3875 
3876 		if (out_size == TX_SCHED_WRR_PARAMS_NUM) {
3877 			cds_ctx->ac_specs[i].wrr_skip_weight =
3878 						tx_sched_wrr_param[0];
3879 			cds_ctx->ac_specs[i].credit_threshold =
3880 						tx_sched_wrr_param[1];
3881 			cds_ctx->ac_specs[i].send_limit =
3882 						tx_sched_wrr_param[2];
3883 			cds_ctx->ac_specs[i].credit_reserve =
3884 						tx_sched_wrr_param[3];
3885 			cds_ctx->ac_specs[i].discard_weight =
3886 						tx_sched_wrr_param[4];
3887 		}
3888 
3889 		out_size = 0;
3890 	}
3891 }
3892 
3893 uint32_t hdd_wlan_get_version(struct hdd_context *hdd_ctx,
3894 			      const size_t version_len, uint8_t *version)
3895 {
3896 	uint32_t size;
3897 	uint8_t reg_major = 0, reg_minor = 0, bdf_major = 0, bdf_minor = 0;
3898 	struct target_psoc_info *tgt_hdl;
3899 
3900 	if (!hdd_ctx) {
3901 		hdd_err("Invalid context, HDD context is null");
3902 		return 0;
3903 	}
3904 
3905 	if (!version || version_len == 0) {
3906 		hdd_err("Invalid buffer pointr or buffer len\n");
3907 		return 0;
3908 	}
3909 	tgt_hdl = wlan_psoc_get_tgt_if_handle(hdd_ctx->psoc);
3910 	if (tgt_hdl)
3911 		target_psoc_get_version_info(tgt_hdl, &reg_major, &reg_minor,
3912 					     &bdf_major, &bdf_minor);
3913 
3914 	size = scnprintf(version, version_len,
3915 			 "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",
3916 			 QWLAN_VERSIONSTR,
3917 			 hdd_ctx->fw_version_info.major_spid,
3918 			 hdd_ctx->fw_version_info.minor_spid,
3919 			 hdd_ctx->fw_version_info.siid,
3920 			 hdd_ctx->fw_version_info.rel_id,
3921 			 hdd_ctx->fw_version_info.crmid,
3922 			 hdd_ctx->fw_version_info.sub_id,
3923 			 hdd_ctx->target_hw_name,
3924 			 hdd_ctx->hw_bd_info.bdf_version,
3925 			 hdd_ctx->hw_bd_info.ref_design_id,
3926 			 hdd_ctx->hw_bd_info.customer_id,
3927 			 hdd_ctx->hw_bd_info.project_id,
3928 			 hdd_ctx->hw_bd_info.board_data_rev,
3929 			 reg_major, reg_minor, bdf_major, bdf_minor);
3930 
3931 	return size;
3932 }
3933 
3934 int hdd_set_11ax_rate(struct hdd_adapter *adapter, int set_value,
3935 		      struct sap_config *sap_config)
3936 {
3937 	uint8_t preamble = 0, nss = 0, rix = 0;
3938 	int ret;
3939 	mac_handle_t mac_handle = adapter->hdd_ctx->mac_handle;
3940 
3941 	if (!sap_config) {
3942 		if (!sme_is_feature_supported_by_fw(DOT11AX)) {
3943 			hdd_err("Target does not support 11ax");
3944 			return -EIO;
3945 		}
3946 	} else if (sap_config->SapHw_mode != eCSR_DOT11_MODE_11ax &&
3947 		   sap_config->SapHw_mode != eCSR_DOT11_MODE_11ax_ONLY) {
3948 		hdd_err("Invalid hw mode, SAP hw_mode= 0x%x, ch_freq = %d",
3949 			sap_config->SapHw_mode, sap_config->chan_freq);
3950 		return -EIO;
3951 	}
3952 
3953 	if (set_value != 0xffff) {
3954 		rix = RC_2_RATE_IDX_11AX(set_value);
3955 		preamble = WMI_RATE_PREAMBLE_HE;
3956 		nss = HT_RC_2_STREAMS_11AX(set_value);
3957 
3958 		set_value = hdd_assemble_rate_code(preamble, nss, rix);
3959 	} else {
3960 		ret = sme_set_auto_rate_he_ltf(mac_handle,
3961 					       adapter->deflink->vdev_id,
3962 					       QCA_WLAN_HE_LTF_AUTO);
3963 	}
3964 
3965 	hdd_info("SET_11AX_RATE val %d rix %d preamble %x nss %d",
3966 		 set_value, rix, preamble, nss);
3967 
3968 	ret = wma_cli_set_command(adapter->deflink->vdev_id,
3969 				  wmi_vdev_param_fixed_rate,
3970 				  set_value, VDEV_CMD);
3971 
3972 	return ret;
3973 }
3974 
3975 int hdd_assemble_rate_code(uint8_t preamble, uint8_t nss, uint8_t rate)
3976 {
3977 	return ucfg_mlme_assemble_rate_code(preamble, nss, rate);
3978 }
3979 
3980 #ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
3981 static enum policy_mgr_con_mode wlan_hdd_get_mode_for_non_connected_vdev(
3982 			struct wlan_objmgr_psoc *psoc, uint8_t vdev_id)
3983 {
3984 	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
3985 	struct hdd_adapter *adapter;
3986 	enum policy_mgr_con_mode mode;
3987 	struct wlan_hdd_link_info *link_info;
3988 
3989 	link_info = hdd_get_link_info_by_vdev(hdd_ctx, vdev_id);
3990 	if (!link_info) {
3991 		hdd_err("Invalid vdev");
3992 		return PM_MAX_NUM_OF_MODE;
3993 	}
3994 
3995 	adapter = link_info->adapter;
3996 	mode = policy_mgr_qdf_opmode_to_pm_con_mode(psoc,
3997 						    adapter->device_mode,
3998 						    vdev_id);
3999 	return mode;
4000 }
4001 
4002 /**
4003  * hdd_is_chan_switch_in_progress() - Check if any adapter has channel switch in
4004  * progress
4005  *
4006  * Return: true, if any adapter has channel switch in
4007  * progress else false
4008  */
4009 static bool hdd_is_chan_switch_in_progress(void)
4010 {
4011 	struct hdd_adapter *adapter = NULL, *next_adapter = NULL;
4012 	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
4013 	wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_IS_CHAN_SWITCH_IN_PROGRESS;
4014 	struct hdd_ap_ctx *ap_ctx;
4015 	struct wlan_hdd_link_info *link_info;
4016 	bool is_restart;
4017 	struct wlan_objmgr_vdev *vdev;
4018 
4019 	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
4020 					   dbgid) {
4021 		if (adapter->device_mode != QDF_SAP_MODE &&
4022 		    adapter->device_mode != QDF_P2P_GO_MODE)
4023 			goto next_adapter;
4024 
4025 		hdd_adapter_for_each_active_link_info(adapter, link_info) {
4026 			ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(link_info);
4027 			vdev = hdd_objmgr_get_vdev_by_user(link_info,
4028 							   WLAN_OSIF_ID);
4029 			if (!vdev)
4030 				continue;
4031 			is_restart = false;
4032 			if (wlan_vdev_is_restart_progress(vdev) ==
4033 			    QDF_STATUS_SUCCESS) {
4034 				hdd_debug("vdev: %d restart in progress",
4035 					  wlan_vdev_get_id(vdev));
4036 				is_restart = true;
4037 			}
4038 			hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_ID);
4039 
4040 			if (is_restart ||
4041 			    qdf_atomic_read(&ap_ctx->ch_switch_in_progress)) {
4042 				hdd_debug("channel switch progress for vdev_id %d",
4043 					  link_info->vdev_id);
4044 				hdd_adapter_dev_put_debug(adapter, dbgid);
4045 				if (next_adapter)
4046 					hdd_adapter_dev_put_debug(next_adapter,
4047 								  dbgid);
4048 				return true;
4049 			}
4050 		}
4051 next_adapter:
4052 		hdd_adapter_dev_put_debug(adapter, dbgid);
4053 	}
4054 
4055 	return false;
4056 }
4057 
4058 /**
4059  * hdd_is_cac_in_progress() - Check if any SAP connection is performing
4060  * CAC on DFS channel
4061  *
4062  * Return: true, if any of existing SAP is performing CAC
4063  * or else false
4064  */
4065 static bool hdd_is_cac_in_progress(void)
4066 {
4067 	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
4068 
4069 	if (!hdd_ctx)
4070 		return false;
4071 
4072 	return (hdd_ctx->dev_dfs_cac_status == DFS_CAC_IN_PROGRESS);
4073 }
4074 
4075 static void hdd_register_policy_manager_callback(
4076 			struct wlan_objmgr_psoc *psoc)
4077 {
4078 	struct policy_mgr_hdd_cbacks hdd_cbacks;
4079 
4080 	qdf_mem_zero(&hdd_cbacks, sizeof(hdd_cbacks));
4081 	hdd_cbacks.sap_restart_chan_switch_cb =
4082 		hdd_sap_restart_chan_switch_cb;
4083 	hdd_cbacks.wlan_hdd_get_channel_for_sap_restart =
4084 		wlan_hdd_get_channel_for_sap_restart;
4085 	hdd_cbacks.get_mode_for_non_connected_vdev =
4086 		wlan_hdd_get_mode_for_non_connected_vdev;
4087 	hdd_cbacks.hdd_get_device_mode = hdd_get_device_mode;
4088 	hdd_cbacks.hdd_is_chan_switch_in_progress =
4089 				hdd_is_chan_switch_in_progress;
4090 	hdd_cbacks.hdd_is_cac_in_progress =
4091 				hdd_is_cac_in_progress;
4092 	hdd_cbacks.wlan_hdd_set_sap_csa_reason =
4093 				wlan_hdd_set_sap_csa_reason;
4094 	hdd_cbacks.hdd_get_ap_6ghz_capable = hdd_get_ap_6ghz_capable;
4095 	hdd_cbacks.wlan_hdd_indicate_active_ndp_cnt =
4096 				hdd_indicate_active_ndp_cnt;
4097 	hdd_cbacks.wlan_get_ap_prefer_conc_ch_params =
4098 			wlan_get_ap_prefer_conc_ch_params;
4099 	hdd_cbacks.wlan_get_sap_acs_band =
4100 			wlan_get_sap_acs_band;
4101 	hdd_cbacks.wlan_check_cc_intf_cb = wlan_hdd_check_cc_intf_cb;
4102 
4103 	if (QDF_STATUS_SUCCESS !=
4104 	    policy_mgr_register_hdd_cb(psoc, &hdd_cbacks)) {
4105 		hdd_err("HDD callback registration with policy manager failed");
4106 	}
4107 }
4108 #else
4109 static void hdd_register_policy_manager_callback(
4110 			struct wlan_objmgr_psoc *psoc)
4111 {
4112 }
4113 #endif
4114 
4115 #ifdef WLAN_SUPPORT_GAP_LL_PS_MODE
4116 static void hdd_register_green_ap_callback(struct wlan_objmgr_pdev *pdev)
4117 {
4118 	struct green_ap_hdd_callback hdd_cback;
4119 	qdf_mem_zero(&hdd_cback, sizeof(hdd_cback));
4120 
4121 	hdd_cback.send_event = wlan_hdd_send_green_ap_ll_ps_event;
4122 
4123 	if (QDF_STATUS_SUCCESS !=
4124 			green_ap_register_hdd_callback(pdev, &hdd_cback)) {
4125 		hdd_err("HDD callback registration for Green AP failed");
4126 	}
4127 }
4128 #else
4129 static inline void hdd_register_green_ap_callback(struct wlan_objmgr_pdev *pdev)
4130 {
4131 }
4132 #endif
4133 
4134 #ifdef WLAN_FEATURE_NAN
4135 #ifdef WLAN_FEATURE_SR
4136 static void hdd_register_sr_concurrency_cb(struct nan_callbacks *cb_obj)
4137 {
4138 	cb_obj->nan_sr_concurrency_update = hdd_nan_sr_concurrency_update;
4139 }
4140 #else
4141 static void hdd_register_sr_concurrency_cb(struct nan_callbacks *cb_obj)
4142 {}
4143 #endif
4144 static void hdd_nan_register_callbacks(struct hdd_context *hdd_ctx)
4145 {
4146 	struct nan_callbacks cb_obj = {0};
4147 
4148 	cb_obj.ndi_open = hdd_ndi_open;
4149 	cb_obj.ndi_close = hdd_ndi_close;
4150 	cb_obj.ndi_set_mode = hdd_ndi_set_mode;
4151 	cb_obj.ndi_start = hdd_ndi_start;
4152 	cb_obj.ndi_delete = hdd_ndi_delete;
4153 	cb_obj.drv_ndi_create_rsp_handler = hdd_ndi_drv_ndi_create_rsp_handler;
4154 	cb_obj.drv_ndi_delete_rsp_handler = hdd_ndi_drv_ndi_delete_rsp_handler;
4155 
4156 	cb_obj.new_peer_ind = hdd_ndp_new_peer_handler;
4157 	cb_obj.peer_departed_ind = hdd_ndp_peer_departed_handler;
4158 
4159 	cb_obj.nan_concurrency_update = hdd_nan_concurrency_update;
4160 	cb_obj.set_mc_list = hdd_update_multicast_list;
4161 
4162 	hdd_register_sr_concurrency_cb(&cb_obj);
4163 
4164 	os_if_nan_register_hdd_callbacks(hdd_ctx->psoc, &cb_obj);
4165 }
4166 #else
4167 static inline void hdd_nan_register_callbacks(struct hdd_context *hdd_ctx)
4168 {
4169 }
4170 #endif
4171 
4172 #ifdef CONFIG_LEAK_DETECTION
4173 /**
4174  * hdd_check_for_leaks() - Perform runtime memory leak checks
4175  * @hdd_ctx: the global HDD context
4176  * @is_ssr: true if SSR is in progress
4177  *
4178  * This API triggers runtime memory leak detection. This feature enforces the
4179  * policy that any memory allocated at runtime must also be released at runtime.
4180  *
4181  * Allocating memory at runtime and releasing it at unload is effectively a
4182  * memory leak for configurations which never unload (e.g. LONU, statically
4183  * compiled driver). Such memory leaks are NOT false positives, and must be
4184  * fixed.
4185  *
4186  * Return: None
4187  */
4188 static void hdd_check_for_leaks(struct hdd_context *hdd_ctx, bool is_ssr)
4189 {
4190 	/* DO NOT REMOVE these checks; for false positives, read above first */
4191 
4192 	wlan_objmgr_psoc_check_for_leaks(hdd_ctx->psoc);
4193 
4194 	/* many adapter resources are not freed by design during SSR */
4195 	if (is_ssr)
4196 		return;
4197 
4198 	qdf_wake_lock_check_for_leaks();
4199 	qdf_delayed_work_check_for_leaks();
4200 	qdf_mc_timer_check_for_leaks();
4201 	qdf_nbuf_map_check_for_leaks();
4202 	qdf_periodic_work_check_for_leaks();
4203 	qdf_mem_check_for_leaks();
4204 }
4205 
4206 /**
4207  * hdd_debug_domain_set() - Set qdf debug domain
4208  * @domain: debug domain to be set
4209  *
4210  * In the scenario of system reboot, it may have thread accessing debug domain
4211  * for memory allocation/free, other than the one trying to change it.
4212  * If debug domain is changed after a memory allocation but before the free,
4213  * it will hit debug domain mismatch assertion in memory free.
4214  * To avoid such assertion, skip debug domain transition if system reboot is
4215  * in progress.
4216  *
4217  * Return: 0 if the specified debug domain has been set, -EBUSY otherwise
4218  */
4219 static int hdd_debug_domain_set(enum qdf_debug_domain domain)
4220 {
4221 	int ret = 0;
4222 
4223 	if (cds_sys_reboot_protect()) {
4224 		hdd_info("System is rebooting, skip debug domain transition");
4225 		ret = -EBUSY;
4226 	} else {
4227 		qdf_debug_domain_set(domain);
4228 	}
4229 
4230 	cds_sys_reboot_unprotect();
4231 
4232 	return ret;
4233 }
4234 
4235 #define hdd_debug_domain_get() qdf_debug_domain_get()
4236 #else
4237 static void hdd_check_for_objmgr_peer_leaks(struct wlan_objmgr_psoc *psoc)
4238 {
4239 	uint32_t vdev_id;
4240 	struct wlan_objmgr_vdev *vdev;
4241 	struct wlan_objmgr_peer *peer;
4242 
4243 	/* get module id which cause the leak and release ref */
4244 	wlan_objmgr_for_each_psoc_vdev(psoc, vdev_id, vdev) {
4245 		wlan_objmgr_for_each_vdev_peer(vdev, peer) {
4246 			qdf_atomic_t *ref_id_dbg;
4247 			int ref_id;
4248 			int32_t refs;
4249 
4250 			ref_id_dbg = vdev->vdev_objmgr.ref_id_dbg;
4251 			wlan_objmgr_for_each_refs(ref_id_dbg, ref_id, refs)
4252 				wlan_objmgr_peer_release_ref(peer, ref_id);
4253 		}
4254 	}
4255 }
4256 
4257 static void hdd_check_for_objmgr_leaks(struct hdd_context *hdd_ctx)
4258 {
4259 	uint32_t vdev_id, pdev_id;
4260 	struct wlan_objmgr_psoc *psoc;
4261 	struct wlan_objmgr_vdev *vdev;
4262 	struct wlan_objmgr_pdev *pdev;
4263 	/*
4264 	 * leak detection is disabled, force release the references for the wlan
4265 	 * to recover cleanly.
4266 	 */
4267 	psoc = hdd_ctx->psoc;
4268 	if (!psoc)
4269 		return;
4270 
4271 
4272 	hdd_check_for_objmgr_peer_leaks(psoc);
4273 
4274 	wlan_objmgr_for_each_psoc_vdev(psoc, vdev_id, vdev) {
4275 		qdf_atomic_t *ref_id_dbg;
4276 		int ref_id;
4277 		int32_t refs;
4278 
4279 		ref_id_dbg = vdev->vdev_objmgr.ref_id_dbg;
4280 		wlan_objmgr_for_each_refs(ref_id_dbg, ref_id, refs) {
4281 			wlan_objmgr_vdev_release_ref(vdev, ref_id);
4282 		}
4283 	}
4284 
4285 	wlan_objmgr_for_each_psoc_pdev(psoc, pdev_id, pdev) {
4286 		qdf_atomic_t *ref_id_dbg;
4287 		int ref_id;
4288 		int32_t refs;
4289 
4290 		ref_id_dbg = pdev->pdev_objmgr.ref_id_dbg;
4291 		wlan_objmgr_for_each_refs(ref_id_dbg, ref_id, refs)
4292 			wlan_objmgr_pdev_release_ref(pdev, ref_id);
4293 	}
4294 }
4295 
4296 static void hdd_check_for_leaks(struct hdd_context *hdd_ctx, bool is_ssr)
4297 {
4298 	hdd_check_for_objmgr_leaks(hdd_ctx);
4299 }
4300 
4301 #define hdd_debug_domain_set(domain) 0
4302 #define hdd_debug_domain_get() DEFAULT_DEBUG_DOMAIN_INIT
4303 #endif /* CONFIG_LEAK_DETECTION */
4304 
4305 #ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE
4306 /**
4307  * hdd_skip_acs_scan_timer_handler() - skip ACS scan timer timeout handler
4308  * @data: pointer to struct hdd_context
4309  *
4310  * This function will reset acs_scan_status to eSAP_DO_NEW_ACS_SCAN.
4311  * Then new ACS request will do a fresh scan without reusing the cached
4312  * scan information.
4313  *
4314  * Return: void
4315  */
4316 static void hdd_skip_acs_scan_timer_handler(void *data)
4317 {
4318 	struct hdd_context *hdd_ctx = data;
4319 	mac_handle_t mac_handle;
4320 
4321 	hdd_debug("ACS Scan result expired. Reset ACS scan skip");
4322 	hdd_ctx->skip_acs_scan_status = eSAP_DO_NEW_ACS_SCAN;
4323 	qdf_spin_lock(&hdd_ctx->acs_skip_lock);
4324 	qdf_mem_free(hdd_ctx->last_acs_freq_list);
4325 	hdd_ctx->last_acs_freq_list = NULL;
4326 	hdd_ctx->num_of_channels = 0;
4327 	qdf_spin_unlock(&hdd_ctx->acs_skip_lock);
4328 
4329 	mac_handle = hdd_ctx->mac_handle;
4330 	if (!mac_handle)
4331 		return;
4332 }
4333 
4334 static void hdd_skip_acs_scan_timer_init(struct hdd_context *hdd_ctx)
4335 {
4336 	QDF_STATUS status;
4337 
4338 	status = qdf_mc_timer_init(&hdd_ctx->skip_acs_scan_timer,
4339 				   QDF_TIMER_TYPE_SW,
4340 				   hdd_skip_acs_scan_timer_handler,
4341 				   hdd_ctx);
4342 	if (QDF_IS_STATUS_ERROR(status))
4343 		hdd_err("Failed to init ACS Skip timer");
4344 	qdf_spinlock_create(&hdd_ctx->acs_skip_lock);
4345 }
4346 
4347 static void hdd_skip_acs_scan_timer_deinit(struct hdd_context *hdd_ctx)
4348 {
4349 	if (QDF_TIMER_STATE_RUNNING ==
4350 	    qdf_mc_timer_get_current_state(&hdd_ctx->skip_acs_scan_timer)) {
4351 		qdf_mc_timer_stop(&hdd_ctx->skip_acs_scan_timer);
4352 	}
4353 
4354 	if (!QDF_IS_STATUS_SUCCESS
4355 		    (qdf_mc_timer_destroy(&hdd_ctx->skip_acs_scan_timer))) {
4356 		hdd_err("Cannot deallocate ACS Skip timer");
4357 	}
4358 	qdf_spin_lock(&hdd_ctx->acs_skip_lock);
4359 	qdf_mem_free(hdd_ctx->last_acs_freq_list);
4360 	hdd_ctx->last_acs_freq_list = NULL;
4361 	hdd_ctx->num_of_channels = 0;
4362 	qdf_spin_unlock(&hdd_ctx->acs_skip_lock);
4363 }
4364 #else
4365 static void hdd_skip_acs_scan_timer_init(struct hdd_context *hdd_ctx) {}
4366 static void hdd_skip_acs_scan_timer_deinit(struct hdd_context *hdd_ctx) {}
4367 #endif
4368 
4369 /**
4370  * hdd_update_country_code - Update country code
4371  * @hdd_ctx: HDD context
4372  *
4373  * Update country code based on module parameter country_code
4374  *
4375  * Return: 0 on success and errno on failure
4376  */
4377 int hdd_update_country_code(struct hdd_context *hdd_ctx)
4378 {
4379 	if (!country_code ||
4380 	    !ucfg_reg_is_user_country_set_allowed(hdd_ctx->psoc))
4381 		return 0;
4382 
4383 	return hdd_reg_set_country(hdd_ctx, country_code);
4384 }
4385 
4386 #ifdef WLAN_NS_OFFLOAD
4387 /**
4388  * hdd_wlan_unregister_ip6_notifier() - unregister IPv6 change notifier
4389  * @hdd_ctx: Pointer to hdd context
4390  *
4391  * Unregister for IPv6 address change notifications.
4392  *
4393  * Return: None
4394  */
4395 static void hdd_wlan_unregister_ip6_notifier(struct hdd_context *hdd_ctx)
4396 {
4397 	unregister_inet6addr_notifier(&hdd_ctx->ipv6_notifier);
4398 }
4399 
4400 /**
4401  * hdd_wlan_register_ip6_notifier() - register IPv6 change notifier
4402  * @hdd_ctx: Pointer to hdd context
4403  *
4404  * Register for IPv6 address change notifications.
4405  *
4406  * Return: 0 on success and errno on failure.
4407  */
4408 static int hdd_wlan_register_ip6_notifier(struct hdd_context *hdd_ctx)
4409 {
4410 	int ret;
4411 
4412 	hdd_ctx->ipv6_notifier.notifier_call = wlan_hdd_ipv6_changed;
4413 	ret = register_inet6addr_notifier(&hdd_ctx->ipv6_notifier);
4414 	if (ret) {
4415 		hdd_err("Failed to register IPv6 notifier: %d", ret);
4416 		goto out;
4417 	}
4418 
4419 	hdd_debug("Registered IPv6 notifier");
4420 out:
4421 	return ret;
4422 }
4423 #else
4424 /**
4425  * hdd_wlan_unregister_ip6_notifier() - unregister IPv6 change notifier
4426  * @hdd_ctx: Pointer to hdd context
4427  *
4428  * Unregister for IPv6 address change notifications.
4429  *
4430  * Return: None
4431  */
4432 static void hdd_wlan_unregister_ip6_notifier(struct hdd_context *hdd_ctx)
4433 {
4434 }
4435 
4436 /**
4437  * hdd_wlan_register_ip6_notifier() - register IPv6 change notifier
4438  * @hdd_ctx: Pointer to hdd context
4439  *
4440  * Register for IPv6 address change notifications.
4441  *
4442  * Return: None
4443  */
4444 static int hdd_wlan_register_ip6_notifier(struct hdd_context *hdd_ctx)
4445 {
4446 	return 0;
4447 }
4448 #endif
4449 
4450 #ifdef FEATURE_RUNTIME_PM
4451 #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 7, 0)
4452 static int hdd_pm_qos_add_notifier(struct hdd_context *hdd_ctx)
4453 {
4454 	return dev_pm_qos_add_notifier(hdd_ctx->parent_dev,
4455 				       &hdd_ctx->pm_qos_notifier,
4456 				       DEV_PM_QOS_RESUME_LATENCY);
4457 }
4458 
4459 static int hdd_pm_qos_remove_notifier(struct hdd_context *hdd_ctx)
4460 {
4461 	return dev_pm_qos_remove_notifier(hdd_ctx->parent_dev,
4462 					  &hdd_ctx->pm_qos_notifier,
4463 					  DEV_PM_QOS_RESUME_LATENCY);
4464 }
4465 #else
4466 static int hdd_pm_qos_add_notifier(struct hdd_context *hdd_ctx)
4467 {
4468 	return pm_qos_add_notifier(PM_QOS_CPU_DMA_LATENCY,
4469 				   &hdd_ctx->pm_qos_notifier);
4470 }
4471 
4472 static int hdd_pm_qos_remove_notifier(struct hdd_context *hdd_ctx)
4473 {
4474 	return pm_qos_remove_notifier(PM_QOS_CPU_DMA_LATENCY,
4475 				      &hdd_ctx->pm_qos_notifier);
4476 }
4477 #endif
4478 
4479 /**
4480  * hdd_wlan_register_pm_qos_notifier() - register PM QOS notifier
4481  * @hdd_ctx: Pointer to hdd context
4482  *
4483  * Register for PM QOS change notifications.
4484  *
4485  * Return: None
4486  */
4487 static int hdd_wlan_register_pm_qos_notifier(struct hdd_context *hdd_ctx)
4488 {
4489 	int ret;
4490 
4491 	qdf_spinlock_create(&hdd_ctx->pm_qos_lock);
4492 
4493 	/* if gRuntimePM is 1 then feature is enabled without CXPC */
4494 	if (hdd_ctx->config->runtime_pm != hdd_runtime_pm_dynamic) {
4495 		hdd_debug("Dynamic Runtime PM disabled");
4496 		return 0;
4497 	}
4498 
4499 	hdd_ctx->pm_qos_notifier.notifier_call = wlan_hdd_pm_qos_notify;
4500 	ret = hdd_pm_qos_add_notifier(hdd_ctx);
4501 	if (ret)
4502 		hdd_err("Failed to register PM_QOS notifier: %d", ret);
4503 	else
4504 		hdd_debug("PM QOS Notifier registered");
4505 
4506 	return ret;
4507 }
4508 
4509 /**
4510  * hdd_wlan_unregister_pm_qos_notifier() - unregister PM QOS notifier
4511  * @hdd_ctx: Pointer to hdd context
4512  *
4513  * Unregister for PM QOS change notifications.
4514  *
4515  * Return: None
4516  */
4517 static void hdd_wlan_unregister_pm_qos_notifier(struct hdd_context *hdd_ctx)
4518 {
4519 	int ret;
4520 
4521 	if (hdd_ctx->config->runtime_pm != hdd_runtime_pm_dynamic) {
4522 		hdd_debug("Dynamic Runtime PM disabled");
4523 		qdf_spinlock_destroy(&hdd_ctx->pm_qos_lock);
4524 		return;
4525 	}
4526 
4527 	ret = hdd_pm_qos_remove_notifier(hdd_ctx);
4528 	if (ret)
4529 		hdd_warn("Failed to remove qos notifier, err = %d\n", ret);
4530 
4531 	qdf_spin_lock_irqsave(&hdd_ctx->pm_qos_lock);
4532 
4533 	if (hdd_ctx->runtime_pm_prevented) {
4534 		hif_rtpm_put(HIF_RTPM_PUT_NOIDLE, HIF_RTPM_ID_PM_QOS_NOTIFY);
4535 		hdd_ctx->runtime_pm_prevented = false;
4536 	}
4537 
4538 	qdf_spin_unlock_irqrestore(&hdd_ctx->pm_qos_lock);
4539 
4540 	qdf_spinlock_destroy(&hdd_ctx->pm_qos_lock);
4541 }
4542 #else
4543 static int hdd_wlan_register_pm_qos_notifier(struct hdd_context *hdd_ctx)
4544 {
4545 	return 0;
4546 }
4547 
4548 static void hdd_wlan_unregister_pm_qos_notifier(struct hdd_context *hdd_ctx)
4549 {
4550 }
4551 #endif
4552 
4553 /**
4554  * hdd_enable_power_management() - API to Enable Power Management
4555  * @hdd_ctx: HDD context
4556  *
4557  * API invokes Bus Interface Layer power management functionality
4558  *
4559  * Return: None
4560  */
4561 static void hdd_enable_power_management(struct hdd_context *hdd_ctx)
4562 {
4563 	void *hif_ctx = cds_get_context(QDF_MODULE_ID_HIF);
4564 
4565 	if (!hif_ctx)
4566 		return;
4567 
4568 	hif_enable_power_management(hif_ctx, cds_is_packet_log_enabled());
4569 	hdd_wlan_register_pm_qos_notifier(hdd_ctx);
4570 }
4571 
4572 /**
4573  * hdd_disable_power_management() - API to disable Power Management
4574  * @hdd_ctx: HDD context
4575  *
4576  * API disable Bus Interface Layer Power management functionality
4577  *
4578  * Return: None
4579  */
4580 static void hdd_disable_power_management(struct hdd_context *hdd_ctx)
4581 {
4582 	void *hif_ctx = cds_get_context(QDF_MODULE_ID_HIF);
4583 
4584 	if (!hif_ctx)
4585 		return;
4586 
4587 	hdd_wlan_unregister_pm_qos_notifier(hdd_ctx);
4588 	hif_disable_power_management(hif_ctx);
4589 }
4590 
4591 /**
4592  * hdd_register_notifiers - Register netdev notifiers.
4593  * @hdd_ctx: HDD context
4594  *
4595  * Register netdev notifiers like IPv4 and IPv6.
4596  *
4597  * Return: 0 on success and errno on failure
4598  */
4599 static int hdd_register_notifiers(struct hdd_context *hdd_ctx)
4600 {
4601 	int ret;
4602 
4603 	ret = hdd_wlan_register_ip6_notifier(hdd_ctx);
4604 	if (ret)
4605 		goto out;
4606 
4607 	hdd_ctx->ipv4_notifier.notifier_call = wlan_hdd_ipv4_changed;
4608 	ret = register_inetaddr_notifier(&hdd_ctx->ipv4_notifier);
4609 	if (ret) {
4610 		hdd_err("Failed to register IPv4 notifier: %d", ret);
4611 		goto unregister_ip6_notifier;
4612 	}
4613 
4614 	ret = osif_dp_nud_register_netevent_notifier(hdd_ctx->psoc);
4615 	if (ret) {
4616 		hdd_err("Failed to register netevent notifier: %d",
4617 			ret);
4618 		goto unregister_inetaddr_notifier;
4619 	}
4620 
4621 	return 0;
4622 
4623 unregister_inetaddr_notifier:
4624 	unregister_inetaddr_notifier(&hdd_ctx->ipv4_notifier);
4625 unregister_ip6_notifier:
4626 	hdd_wlan_unregister_ip6_notifier(hdd_ctx);
4627 out:
4628 	return ret;
4629 }
4630 
4631 #ifdef WLAN_FEATURE_WMI_SEND_RECV_QMI
4632 static inline
4633 void hdd_set_qmi_stats_enabled(struct hdd_context *hdd_ctx)
4634 {
4635 	wmi_unified_t wmi_handle = get_wmi_unified_hdl_from_psoc(hdd_ctx->psoc);
4636 
4637 	if (!wmi_handle) {
4638 		hdd_err("could not get wmi handle");
4639 		return;
4640 	}
4641 
4642 	wmi_set_qmi_stats(wmi_handle, hdd_ctx->config->is_qmi_stats_enabled);
4643 }
4644 #else
4645 static inline
4646 void hdd_set_qmi_stats_enabled(struct hdd_context *hdd_ctx)
4647 {
4648 }
4649 #endif
4650 
4651 #ifdef CONFIG_FW_LOGS_BASED_ON_INI
4652 /**
4653  * hdd_set_fw_log_params() - Set log parameters to FW
4654  * @hdd_ctx: HDD Context
4655  * @vdev_id: vdev_id
4656  *
4657  * This function set the FW Debug log level based on the INI.
4658  *
4659  * Return: None
4660  */
4661 static void hdd_set_fw_log_params(struct hdd_context *hdd_ctx,
4662 				  uint8_t vdev_id)
4663 {
4664 	QDF_STATUS status;
4665 	uint16_t enable_fw_log_level, enable_fw_log_type;
4666 	int ret;
4667 
4668 	if (!hdd_ctx->config->enable_fw_log) {
4669 		hdd_debug("enable_fw_log not enabled in INI");
4670 		return;
4671 	}
4672 
4673 	/* Enable FW logs based on INI configuration */
4674 	status = ucfg_fwol_get_enable_fw_log_type(hdd_ctx->psoc,
4675 						  &enable_fw_log_type);
4676 	if (QDF_IS_STATUS_ERROR(status))
4677 		return;
4678 	ret = sme_cli_set_command(vdev_id, WMI_DBGLOG_TYPE,
4679 				  enable_fw_log_type, DBG_CMD);
4680 	if (ret != 0)
4681 		hdd_err("Failed to enable FW log type ret %d", ret);
4682 
4683 	status = ucfg_fwol_get_enable_fw_log_level(hdd_ctx->psoc,
4684 						   &enable_fw_log_level);
4685 	if (QDF_IS_STATUS_ERROR(status))
4686 		return;
4687 	ret = sme_cli_set_command(vdev_id, WMI_DBGLOG_LOG_LEVEL,
4688 				  enable_fw_log_level, DBG_CMD);
4689 	if (ret != 0)
4690 		hdd_err("Failed to enable FW log level ret %d", ret);
4691 
4692 	sme_enable_fw_module_log_level(hdd_ctx->mac_handle, vdev_id);
4693 }
4694 #else
4695 static void hdd_set_fw_log_params(struct hdd_context *hdd_ctx, uint8_t vdev_id)
4696 {
4697 }
4698 
4699 #endif
4700 
4701 /**
4702  * hdd_features_deinit() - Deinit features
4703  * @hdd_ctx:	HDD context
4704  *
4705  * De-Initialize features and their feature context.
4706  *
4707  * Return: none.
4708  */
4709 static void hdd_features_deinit(struct hdd_context *hdd_ctx)
4710 {
4711 	wlan_hdd_gpio_wakeup_deinit(hdd_ctx);
4712 	wlan_hdd_twt_deinit(hdd_ctx);
4713 	wlan_hdd_deinit_chan_info(hdd_ctx);
4714 	wlan_hdd_tsf_deinit(hdd_ctx);
4715 	if (cds_is_packet_log_enabled())
4716 		hdd_pktlog_enable_disable(hdd_ctx, false, 0, 0);
4717 }
4718 
4719 /**
4720  * hdd_deconfigure_cds() -De-Configure cds
4721  * @hdd_ctx:	HDD context
4722  *
4723  * Deconfigure Cds modules before WLAN firmware is down.
4724  *
4725  * Return: 0 on success and errno on failure.
4726  */
4727 static int hdd_deconfigure_cds(struct hdd_context *hdd_ctx)
4728 {
4729 	QDF_STATUS qdf_status;
4730 	int ret = 0;
4731 
4732 	hdd_enter();
4733 
4734 	wlan_hdd_hang_event_notifier_unregister();
4735 	/* De-init features */
4736 	hdd_features_deinit(hdd_ctx);
4737 
4738 	qdf_status = policy_mgr_deregister_mode_change_cb(hdd_ctx->psoc);
4739 	if (!QDF_IS_STATUS_SUCCESS(qdf_status))
4740 		hdd_debug("Failed to deregister mode change cb with Policy Manager");
4741 
4742 	qdf_status = cds_disable(hdd_ctx->psoc);
4743 	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
4744 		hdd_err("Failed to Disable the CDS Modules! :%d",
4745 			qdf_status);
4746 		ret = -EINVAL;
4747 	}
4748 
4749 	if (ucfg_ipa_uc_ol_deinit(hdd_ctx->pdev) != QDF_STATUS_SUCCESS) {
4750 		hdd_err("Failed to disconnect pipes");
4751 		ret = -EINVAL;
4752 	}
4753 
4754 	hdd_exit();
4755 	return ret;
4756 }
4757 
4758 /**
4759  * hdd_qmi_register_callbacks() - Register QMI callbacks
4760  * @hdd_ctx: HDD context
4761  *
4762  * Return: None
4763  */
4764 static inline void hdd_qmi_register_callbacks(struct hdd_context *hdd_ctx)
4765 {
4766 	struct wlan_qmi_psoc_callbacks cb_obj;
4767 
4768 	os_if_qmi_register_callbacks(hdd_ctx->psoc, &cb_obj);
4769 }
4770 
4771 /**
4772  * hdd_set_pcie_params() - Set pcie params
4773  * @hdd_ctx: HDD context
4774  * @index: index value
4775  * @param: pointer to vdev/pdev set param info
4776  *
4777  * Checks for pcie_config value and sets
4778  * corresponding params
4779  *
4780  * Return: 0 on success and errno on failure.
4781  */
4782 static int hdd_set_pcie_params(struct hdd_context *hdd_ctx,
4783 			       uint8_t index, struct dev_set_param *param)
4784 {
4785 	int ret = 0;
4786 	uint8_t check_value = 0;
4787 
4788 	ret = ucfg_fwol_get_pcie_config(hdd_ctx->psoc, &check_value);
4789 	if (QDF_IS_STATUS_SUCCESS(ret)) {
4790 		if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
4791 			ret = mlme_check_index_setparam(param,
4792 					wmi_pdev_param_pcie_config,
4793 					(int)check_value, index++,
4794 					FTM_MAX_PDEV_PARAMS);
4795 		} else {
4796 			ret = mlme_check_index_setparam(param,
4797 					wmi_pdev_param_pcie_config,
4798 					(int)check_value, index++,
4799 					MAX_PDEV_PRE_ENABLE_PARAMS);
4800 		}
4801 		if (QDF_IS_STATUS_ERROR(ret)) {
4802 			hdd_err("failed to set wmi_pdev_param_pcie_config");
4803 			return ret;
4804 		}
4805 	}
4806 	return ret;
4807 }
4808 
4809 #ifdef FEATURE_SET
4810 #ifdef WLAN_FEATURE_11BE
4811 /**
4812  * hdd_is_cfg_dot11_mode_11be() - Check if dot11 mode is 11 be
4813  * @dot11_mode: Input dot11_mode which needs to be checked
4814  *
4815  * Return: True, ifinput dot11_mode is 11be dot11 mode else return false
4816  */
4817 static bool hdd_is_cfg_dot11_mode_11be(enum hdd_dot11_mode dot11_mode)
4818 {
4819 	return (dot11_mode == eHDD_DOT11_MODE_11be ||
4820 		dot11_mode == eHDD_DOT11_MODE_11be_ONLY);
4821 }
4822 
4823 /**
4824  * hdd_is_11be_supported() - Check if 11be is supported or not
4825  * @hdd_ctx: Pointer to hdd context
4826  *
4827  * Return: True, if 11be is supported else return false
4828  */
4829 static bool hdd_is_11be_supported(struct hdd_context *hdd_ctx)
4830 {
4831 	bool mlo_capab;
4832 
4833 	ucfg_psoc_mlme_get_11be_capab(hdd_ctx->psoc, &mlo_capab);
4834 	if (!mlo_capab)
4835 		return false;
4836 
4837 	return true;
4838 }
4839 #else
4840 
4841 static bool hdd_is_cfg_dot11_mode_11be(enum hdd_dot11_mode dot11_mode)
4842 {
4843 	return false;
4844 }
4845 
4846 static bool hdd_is_11be_supported(struct hdd_context *hdd_ctx)
4847 {
4848 	return false;
4849 }
4850 #endif
4851 
4852 WMI_HOST_WIFI_STANDARD
4853 hdd_get_wifi_standard(struct hdd_context *hdd_ctx,
4854 		      enum hdd_dot11_mode dot11_mode, uint32_t band_capability)
4855 {
4856 	WMI_HOST_WIFI_STANDARD wifi_standard = WMI_HOST_WIFI_STANDARD_4;
4857 
4858 	if (dot11_mode == eHDD_DOT11_MODE_AUTO) {
4859 		if (hdd_is_11be_supported(hdd_ctx))
4860 			wifi_standard = WMI_HOST_WIFI_STANDARD_7;
4861 		else if (band_capability & BIT(REG_BAND_6G))
4862 			wifi_standard = WMI_HOST_WIFI_STANDARD_6E;
4863 		else
4864 			wifi_standard = WMI_HOST_WIFI_STANDARD_6;
4865 	} else if (hdd_is_cfg_dot11_mode_11be(dot11_mode)) {
4866 		wifi_standard = WMI_HOST_WIFI_STANDARD_7;
4867 	} else if (dot11_mode == eHDD_DOT11_MODE_11ax ||
4868 		   (dot11_mode == eHDD_DOT11_MODE_11ax_ONLY)) {
4869 		if (band_capability & BIT(REG_BAND_6G))
4870 			wifi_standard = WMI_HOST_WIFI_STANDARD_6E;
4871 		else
4872 			wifi_standard = WMI_HOST_WIFI_STANDARD_6;
4873 	} else if ((dot11_mode == eHDD_DOT11_MODE_11ac) ||
4874 		   (dot11_mode == eHDD_DOT11_MODE_11ac_ONLY)) {
4875 		wifi_standard = WMI_HOST_WIFI_STANDARD_5;
4876 	}
4877 
4878 	return wifi_standard;
4879 }
4880 
4881 /**
4882  * hdd_populate_feature_set_cds_config() - Populate cds feature set config
4883  * @hdd_ctx: hdd context pointer
4884  *
4885  * Return: None
4886  */
4887 static void hdd_populate_feature_set_cds_config(struct hdd_context *hdd_ctx)
4888 {
4889 	struct wlan_objmgr_psoc *psoc;
4890 	uint32_t band_capability;
4891 	QDF_STATUS status;
4892 	struct cds_config_info *cds_cfg;
4893 
4894 	if (!hdd_ctx)
4895 		return;
4896 
4897 	cds_cfg = cds_get_ini_config();
4898 	if (!cds_cfg) {
4899 		hdd_err("CDS config is null.");
4900 		return;
4901 	}
4902 
4903 	psoc = hdd_ctx->psoc;
4904 
4905 	cds_cfg->get_wifi_features = hdd_ctx->config->get_wifi_features;
4906 
4907 	status = ucfg_mlme_get_band_capability(hdd_ctx->psoc, &band_capability);
4908 	if (QDF_IS_STATUS_ERROR(status))
4909 		hdd_err("Failed to get MLME band capability");
4910 
4911 	band_capability =
4912 		hdd_update_band_cap_from_dot11mode(hdd_ctx, band_capability);
4913 
4914 	cds_cfg->cds_feature_set.wifi_standard =
4915 			  hdd_get_wifi_standard(hdd_ctx,
4916 						hdd_ctx->config->dot11Mode,
4917 						band_capability);
4918 
4919 	cds_cfg->cds_feature_set.sap_5g_supported =
4920 					band_capability & BIT(REG_BAND_5G);
4921 
4922 	cds_cfg->cds_feature_set.sap_6g_supported =
4923 					band_capability & BIT(REG_BAND_6G);
4924 	cds_cfg->cds_feature_set.band_capability = band_capability;
4925 }
4926 #else
4927 WMI_HOST_WIFI_STANDARD
4928 hdd_get_wifi_standard(struct hdd_context *hdd_ctx,
4929 		      enum hdd_dot11_mode dot11_mode, uint32_t band_capability)
4930 {
4931 	return WMI_HOST_WIFI_STANDARD_5;
4932 }
4933 
4934 static inline void
4935 hdd_populate_feature_set_cds_config(struct hdd_context *hdd_ctx)
4936 {
4937 }
4938 #endif
4939 
4940 int hdd_wlan_start_modules(struct hdd_context *hdd_ctx, bool reinit)
4941 {
4942 	int ret = 0;
4943 	qdf_device_t qdf_dev;
4944 	QDF_STATUS status;
4945 	bool unint = false;
4946 	void *hif_ctx;
4947 	struct target_psoc_info *tgt_hdl;
4948 	unsigned long thermal_state = 0;
4949 	uint8_t index = 0;
4950 	struct dev_set_param setparam[MAX_PDEV_PRE_ENABLE_PARAMS] = {};
4951 
4952 	hdd_enter();
4953 	qdf_dev = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
4954 	if (!qdf_dev) {
4955 		hdd_exit();
4956 		return -EINVAL;
4957 	}
4958 
4959 	hdd_psoc_idle_timer_stop(hdd_ctx);
4960 
4961 	if (hdd_ctx->driver_status == DRIVER_MODULES_ENABLED) {
4962 		hdd_debug("Driver modules already Enabled");
4963 		hdd_exit();
4964 		return 0;
4965 	}
4966 
4967 	cds_set_driver_state_module_stop(false);
4968 
4969 	switch (hdd_ctx->driver_status) {
4970 	case DRIVER_MODULES_UNINITIALIZED:
4971 		hdd_nofl_debug("Wlan transitioning (UNINITIALIZED -> CLOSED)");
4972 		unint = true;
4973 		fallthrough;
4974 	case DRIVER_MODULES_CLOSED:
4975 		hdd_nofl_debug("Wlan transitioning (CLOSED -> ENABLED)");
4976 		ret = hdd_debug_domain_set(QDF_DEBUG_DOMAIN_ACTIVE);
4977 		if (ret)
4978 			goto abort;
4979 
4980 		if (!reinit && !unint) {
4981 			ret = pld_power_on(qdf_dev->dev);
4982 			if (ret) {
4983 				hdd_err("Failed to power up device; errno:%d",
4984 					ret);
4985 				goto release_lock;
4986 			}
4987 		}
4988 
4989 		hdd_init_adapter_ops_wq(hdd_ctx);
4990 		pld_set_fw_log_mode(hdd_ctx->parent_dev,
4991 				    hdd_ctx->config->enable_fw_log);
4992 		ret = hdd_hif_open(qdf_dev->dev, qdf_dev->drv_hdl, qdf_dev->bid,
4993 				   qdf_dev->bus_type,
4994 				   (reinit == true) ?  HIF_ENABLE_TYPE_REINIT :
4995 				   HIF_ENABLE_TYPE_PROBE);
4996 		if (ret) {
4997 			hdd_err("Failed to open hif; errno: %d", ret);
4998 			goto power_down;
4999 		}
5000 
5001 		hif_ctx = cds_get_context(QDF_MODULE_ID_HIF);
5002 		if (!hif_ctx) {
5003 			ret = -EINVAL;
5004 			goto power_down;
5005 		}
5006 
5007 		status = ol_cds_init(qdf_dev, hif_ctx);
5008 		if (status != QDF_STATUS_SUCCESS) {
5009 			hdd_err("No Memory to Create BMI Context; status: %d",
5010 				status);
5011 			ret = qdf_status_to_os_return(status);
5012 			goto hif_close;
5013 		}
5014 
5015 		if (hdd_get_conparam() == QDF_GLOBAL_EPPING_MODE) {
5016 			status = epping_open();
5017 			if (status) {
5018 				hdd_err("Failed to open in epping mode: %d",
5019 					status);
5020 				ret = -EINVAL;
5021 				goto cds_free;
5022 			}
5023 
5024 			status = epping_enable(qdf_dev->dev, false);
5025 			if (status) {
5026 				hdd_err("Failed to enable in epping mode : %d",
5027 					status);
5028 				epping_close();
5029 				goto cds_free;
5030 			}
5031 
5032 			hdd_info("epping mode enabled");
5033 			break;
5034 		}
5035 
5036 		if (pld_is_ipa_offload_disabled(qdf_dev->dev))
5037 			ucfg_ipa_set_pld_enable(false);
5038 
5039 		ucfg_ipa_component_config_update(hdd_ctx->psoc);
5040 
5041 		hdd_update_cds_ac_specs_params(hdd_ctx);
5042 
5043 		hdd_dp_register_callbacks(hdd_ctx);
5044 
5045 		hdd_qmi_register_callbacks(hdd_ctx);
5046 
5047 		status = hdd_component_psoc_open(hdd_ctx->psoc);
5048 		if (QDF_IS_STATUS_ERROR(status)) {
5049 			hdd_err("Failed to Open legacy components; status: %d",
5050 				status);
5051 			ret = qdf_status_to_os_return(status);
5052 			goto ipa_component_free;
5053 		}
5054 
5055 		ret = hdd_update_config(hdd_ctx);
5056 		if (ret) {
5057 			hdd_err("Failed to update configuration; errno: %d",
5058 				ret);
5059 			goto ipa_component_free;
5060 		}
5061 
5062 		status = wbuff_module_init();
5063 		if (QDF_IS_STATUS_ERROR(status))
5064 			hdd_err("WBUFF init unsuccessful; status: %d", status);
5065 
5066 		status = cds_open(hdd_ctx->psoc);
5067 		if (QDF_IS_STATUS_ERROR(status)) {
5068 			hdd_err("Failed to Open CDS; status: %d", status);
5069 			ret = qdf_status_to_os_return(status);
5070 			goto psoc_close;
5071 		}
5072 
5073 		hdd_populate_feature_set_cds_config(hdd_ctx);
5074 
5075 		hdd_set_qmi_stats_enabled(hdd_ctx);
5076 
5077 		hdd_ctx->mac_handle = cds_get_context(QDF_MODULE_ID_SME);
5078 
5079 		ucfg_dp_set_rx_thread_affinity(hdd_ctx->psoc);
5080 
5081 		/* initialize components configurations after psoc open */
5082 		ret = hdd_update_components_config(hdd_ctx);
5083 		if (ret) {
5084 			hdd_err("Failed to update component configs; errno: %d",
5085 				ret);
5086 			goto close;
5087 		}
5088 
5089 		/* Override PS params for monitor mode */
5090 		if (hdd_get_conparam() == QDF_GLOBAL_MONITOR_MODE)
5091 			hdd_override_all_ps(hdd_ctx);
5092 
5093 		status = cds_dp_open(hdd_ctx->psoc);
5094 		if (!QDF_IS_STATUS_SUCCESS(status)) {
5095 			hdd_err("Failed to Open cds post open; status: %d",
5096 				status);
5097 			ret = qdf_status_to_os_return(status);
5098 			goto close;
5099 		}
5100 		/* Set IRQ affinity for WLAN DP and CE IRQS */
5101 		hif_config_irq_set_perf_affinity_hint(hif_ctx);
5102 
5103 		ret = hdd_register_cb(hdd_ctx);
5104 		if (ret) {
5105 			hdd_err("Failed to register HDD callbacks!");
5106 			goto cds_txrx_free;
5107 		}
5108 
5109 		ret = hdd_register_notifiers(hdd_ctx);
5110 		if (ret)
5111 			goto deregister_cb;
5112 
5113 		/*
5114 		 * NAN component requires certain operations like, open adapter,
5115 		 * close adapter, etc. to be initiated by HDD, for those
5116 		 * register HDD callbacks with UMAC's NAN component.
5117 		 */
5118 		hdd_nan_register_callbacks(hdd_ctx);
5119 
5120 		hdd_son_register_callbacks(hdd_ctx);
5121 
5122 		hdd_sr_register_callbacks(hdd_ctx);
5123 
5124 		wlan_hdd_register_btc_chain_mode_handler(hdd_ctx->psoc);
5125 
5126 		wlan_hdd_register_afc_pld_cb(hdd_ctx->psoc);
5127 
5128 		status = cds_pre_enable();
5129 		if (!QDF_IS_STATUS_SUCCESS(status)) {
5130 			hdd_err("Failed to pre-enable CDS; status: %d", status);
5131 			ret = qdf_status_to_os_return(status);
5132 			goto unregister_notifiers;
5133 		}
5134 
5135 		hdd_register_policy_manager_callback(
5136 			hdd_ctx->psoc);
5137 
5138 		/*
5139 		 * Call this function before hdd_enable_power_management. Since
5140 		 * it is required to trigger WMI_PDEV_DMA_RING_CFG_REQ_CMDID
5141 		 * to FW when power save isn't enable.
5142 		 */
5143 		hdd_spectral_register_to_dbr(hdd_ctx);
5144 
5145 		hdd_create_sysfs_files(hdd_ctx);
5146 		hdd_update_hw_sw_info(hdd_ctx);
5147 
5148 		if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
5149 			hdd_enable_power_management(hdd_ctx);
5150 			hdd_err("in ftm mode, no need to configure cds modules");
5151 			hdd_info("Enable FW log in ftm mode");
5152 			/*
5153 			 * Since vdev is not created for FTM mode,
5154 			 * in FW use vdev_id = 0.
5155 			 */
5156 			hdd_set_fw_log_params(hdd_ctx, 0);
5157 			ret = hdd_set_pcie_params(hdd_ctx, index, setparam);
5158 			if (QDF_IS_STATUS_ERROR(ret))
5159 				break;
5160 			index++;
5161 			ret = sme_send_multi_pdev_vdev_set_params(
5162 					MLME_PDEV_SETPARAM,
5163 					WMI_PDEV_ID_SOC, setparam, index);
5164 			if (QDF_IS_STATUS_ERROR(ret)) {
5165 				hdd_err("failed to send pdev set params");
5166 				return ret;
5167 			}
5168 
5169 			ret = -EINVAL;
5170 			break;
5171 		}
5172 
5173 		ret = hdd_configure_cds(hdd_ctx);
5174 		if (ret) {
5175 			hdd_err("Failed to Enable cds modules; errno: %d", ret);
5176 			goto sched_disable;
5177 		}
5178 
5179 		if (hdd_get_conparam() == QDF_GLOBAL_MISSION_MODE) {
5180 			status = ucfg_dp_direct_link_init(hdd_ctx->psoc);
5181 			if (QDF_IS_STATUS_ERROR(status)) {
5182 				cds_err("Failed to initialize Direct Link datapath");
5183 				ret = -EINVAL;
5184 				goto deconfigure_cds;
5185 			}
5186 		}
5187 
5188 		hdd_enable_power_management(hdd_ctx);
5189 
5190 		hdd_skip_acs_scan_timer_init(hdd_ctx);
5191 
5192 		hdd_set_hif_init_phase(hif_ctx, false);
5193 		hdd_hif_set_enable_detection(hif_ctx, true);
5194 
5195 		wlan_hdd_start_connectivity_logging(hdd_ctx);
5196 
5197 		break;
5198 
5199 	default:
5200 		QDF_DEBUG_PANIC("Unknown driver state:%d",
5201 				hdd_ctx->driver_status);
5202 		ret = -EINVAL;
5203 		goto release_lock;
5204 	}
5205 
5206 	hdd_ctx->driver_status = DRIVER_MODULES_ENABLED;
5207 	hdd_nofl_debug("Wlan transitioned (now ENABLED)");
5208 
5209 	ucfg_ipa_reg_is_driver_unloading_cb(hdd_ctx->pdev,
5210 					    cds_is_driver_unloading);
5211 	ucfg_ipa_reg_sap_xmit_cb(hdd_ctx->pdev,
5212 				 hdd_softap_ipa_start_xmit);
5213 	ucfg_ipa_reg_send_to_nw_cb(hdd_ctx->pdev,
5214 				   hdd_ipa_send_nbuf_to_network);
5215 	ucfg_dp_reg_ipa_rsp_ind(hdd_ctx->pdev);
5216 
5217 	if (!pld_get_thermal_state(hdd_ctx->parent_dev, &thermal_state,
5218 				   THERMAL_MONITOR_APPS)) {
5219 		if (thermal_state > QCA_WLAN_VENDOR_THERMAL_LEVEL_NONE)
5220 			hdd_send_thermal_mitigation_val(hdd_ctx,
5221 							thermal_state,
5222 							THERMAL_MONITOR_APPS);
5223 	}
5224 
5225 	if (!pld_get_thermal_state(hdd_ctx->parent_dev, &thermal_state,
5226 				   THERMAL_MONITOR_WPSS)) {
5227 		if (thermal_state > QCA_WLAN_VENDOR_THERMAL_LEVEL_NONE)
5228 			hdd_send_thermal_mitigation_val(hdd_ctx, thermal_state,
5229 							THERMAL_MONITOR_WPSS);
5230 	}
5231 
5232 	hdd_exit();
5233 
5234 	return 0;
5235 
5236 deconfigure_cds:
5237 	hdd_deconfigure_cds(hdd_ctx);
5238 sched_disable:
5239 	/*
5240 	 * Disable scheduler 1st so that scheduler thread doesn't send messages
5241 	 * to fw in parallel to the cleanup
5242 	 */
5243 	dispatcher_disable();
5244 	hdd_destroy_sysfs_files();
5245 	cds_post_disable();
5246 unregister_notifiers:
5247 	hdd_unregister_notifiers(hdd_ctx);
5248 
5249 deregister_cb:
5250 	hdd_deregister_cb(hdd_ctx);
5251 
5252 cds_txrx_free:
5253 
5254 	tgt_hdl = wlan_psoc_get_tgt_if_handle(hdd_ctx->psoc);
5255 
5256 	if (tgt_hdl && target_psoc_get_wmi_ready(tgt_hdl))
5257 		hdd_runtime_suspend_context_deinit(hdd_ctx);
5258 
5259 	if (hdd_ctx->pdev) {
5260 		dispatcher_pdev_close(hdd_ctx->pdev);
5261 		hdd_objmgr_release_and_destroy_pdev(hdd_ctx);
5262 	}
5263 
5264 	cds_dp_close(hdd_ctx->psoc);
5265 
5266 close:
5267 	dispatcher_disable();
5268 	hdd_ctx->driver_status = DRIVER_MODULES_CLOSED;
5269 	hdd_info("Wlan transition aborted (now CLOSED)");
5270 
5271 	cds_close(hdd_ctx->psoc);
5272 
5273 psoc_close:
5274 	hdd_component_psoc_close(hdd_ctx->psoc);
5275 	wlan_global_lmac_if_close(hdd_ctx->psoc);
5276 	cds_deinit_ini_config();
5277 
5278 ipa_component_free:
5279 	ucfg_ipa_component_config_free();
5280 
5281 cds_free:
5282 	ol_cds_free();
5283 
5284 hif_close:
5285 	hif_ctx = cds_get_context(QDF_MODULE_ID_HIF);
5286 	hdd_hif_close(hdd_ctx, hif_ctx);
5287 power_down:
5288 	hdd_deinit_adapter_ops_wq(hdd_ctx);
5289 	if (!reinit && !unint)
5290 		pld_power_off(qdf_dev->dev);
5291 release_lock:
5292 	cds_shutdown_notifier_purge();
5293 	hdd_check_for_leaks(hdd_ctx, reinit);
5294 	hdd_debug_domain_set(QDF_DEBUG_DOMAIN_INIT);
5295 
5296 abort:
5297 	cds_set_driver_state_module_stop(true);
5298 
5299 	hdd_exit();
5300 
5301 	return ret;
5302 }
5303 
5304 #ifdef WIFI_POS_CONVERGED
5305 static int hdd_activate_wifi_pos(struct hdd_context *hdd_ctx)
5306 {
5307 	int ret = os_if_wifi_pos_register_nl();
5308 
5309 	if (ret)
5310 		hdd_err("os_if_wifi_pos_register_nl failed");
5311 
5312 	return ret;
5313 }
5314 
5315 static int hdd_deactivate_wifi_pos(void)
5316 {
5317 	int ret = os_if_wifi_pos_deregister_nl();
5318 
5319 	if (ret)
5320 		hdd_err("os_if_wifi_pos_deregister_nl failed");
5321 
5322 	return ret;
5323 }
5324 
5325 /**
5326  * hdd_populate_wifi_pos_cfg - populates wifi_pos parameters
5327  * @hdd_ctx: hdd context
5328  *
5329  * Return: status of operation
5330  */
5331 static void hdd_populate_wifi_pos_cfg(struct hdd_context *hdd_ctx)
5332 {
5333 	struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc;
5334 	uint16_t neighbor_scan_max_chan_time;
5335 	uint16_t neighbor_scan_min_chan_time;
5336 
5337 	wifi_pos_set_oem_target_type(psoc, hdd_ctx->target_type);
5338 	wifi_pos_set_oem_fw_version(psoc, hdd_ctx->target_fw_version);
5339 	wifi_pos_set_drv_ver_major(psoc, QWLAN_VERSION_MAJOR);
5340 	wifi_pos_set_drv_ver_minor(psoc, QWLAN_VERSION_MINOR);
5341 	wifi_pos_set_drv_ver_patch(psoc, QWLAN_VERSION_PATCH);
5342 	wifi_pos_set_drv_ver_build(psoc, QWLAN_VERSION_BUILD);
5343 	ucfg_mlme_get_neighbor_scan_max_chan_time(psoc,
5344 						  &neighbor_scan_max_chan_time);
5345 	ucfg_mlme_get_neighbor_scan_min_chan_time(psoc,
5346 						  &neighbor_scan_min_chan_time);
5347 	wifi_pos_set_dwell_time_min(psoc, neighbor_scan_min_chan_time);
5348 	wifi_pos_set_dwell_time_max(psoc, neighbor_scan_max_chan_time);
5349 }
5350 #else
5351 static int hdd_activate_wifi_pos(struct hdd_context *hdd_ctx)
5352 {
5353 	return oem_activate_service(hdd_ctx);
5354 }
5355 
5356 static int hdd_deactivate_wifi_pos(void)
5357 {
5358 	return oem_deactivate_service();
5359 }
5360 
5361 static void hdd_populate_wifi_pos_cfg(struct hdd_context *hdd_ctx)
5362 {
5363 }
5364 #endif
5365 
5366 /**
5367  * __hdd_open() - HDD Open function
5368  * @dev:	Pointer to net_device structure
5369  *
5370  * This is called in response to ifconfig up
5371  *
5372  * Return: 0 for success; non-zero for failure
5373  */
5374 static int __hdd_open(struct net_device *dev)
5375 {
5376 	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
5377 	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
5378 	int ret;
5379 	struct wlan_hdd_link_info *link_info = adapter->deflink;
5380 
5381 	hdd_enter_dev(dev);
5382 
5383 	qdf_mtrace(QDF_MODULE_ID_HDD, QDF_MODULE_ID_HDD,
5384 		   TRACE_CODE_HDD_OPEN_REQUEST,
5385 		   link_info->vdev_id, adapter->device_mode);
5386 
5387 	/* Nothing to be done if device is unloading */
5388 	if (cds_is_driver_unloading()) {
5389 		hdd_err("Driver is unloading can not open the hdd");
5390 		return -EBUSY;
5391 	}
5392 
5393 	if (cds_is_driver_recovering()) {
5394 		hdd_err("WLAN is currently recovering; Please try again.");
5395 		return -EBUSY;
5396 	}
5397 
5398 	/*
5399 	 * This scenario can be hit in cases where in the wlan driver after
5400 	 * registering the netdevices and there is a failure in driver
5401 	 * initialization. So return error gracefully because the netdevices
5402 	 * will be de-registered as part of the load failure.
5403 	 */
5404 
5405 	if (!cds_is_driver_loaded()) {
5406 		hdd_err("Failed to start the wlan driver!!");
5407 		return -EIO;
5408 	}
5409 
5410 	ret = wlan_hdd_validate_context(hdd_ctx);
5411 	if (ret) {
5412 		hdd_err("Can't start WLAN module, WiFi Disabled");
5413 		return ret;
5414 	}
5415 
5416 	ret = hdd_trigger_psoc_idle_restart(hdd_ctx);
5417 	if (ret) {
5418 		hdd_err("Failed to start WLAN modules return");
5419 		return ret;
5420 	}
5421 
5422 	if (!test_bit(SME_SESSION_OPENED, &link_info->link_flags)) {
5423 		ret = hdd_start_adapter(adapter, true);
5424 		if (ret) {
5425 			hdd_err("Failed to start adapter :%d",
5426 				adapter->device_mode);
5427 			return ret;
5428 		}
5429 	}
5430 
5431 	set_bit(DEVICE_IFACE_OPENED, &adapter->event_flags);
5432 	if (hdd_cm_is_vdev_associated(link_info)) {
5433 		hdd_debug("Enabling Tx Queues");
5434 		/* Enable TX queues only when we are connected */
5435 		wlan_hdd_netif_queue_control(adapter,
5436 					     WLAN_START_ALL_NETIF_QUEUE,
5437 					     WLAN_CONTROL_PATH);
5438 	}
5439 
5440 	/* Enable carrier and transmit queues for NDI */
5441 	if (WLAN_HDD_IS_NDI(adapter)) {
5442 		hdd_debug("Enabling Tx Queues");
5443 		wlan_hdd_netif_queue_control(adapter,
5444 			WLAN_START_ALL_NETIF_QUEUE_N_CARRIER,
5445 			WLAN_CONTROL_PATH);
5446 	}
5447 
5448 	hdd_populate_wifi_pos_cfg(hdd_ctx);
5449 	hdd_lpass_notify_start(link_info);
5450 
5451 	if (ucfg_pkt_capture_get_mode(hdd_ctx->psoc) !=
5452 				      PACKET_CAPTURE_MODE_DISABLE)
5453 		hdd_map_monitor_interface_vdev(adapter);
5454 
5455 	return 0;
5456 }
5457 
5458 /**
5459  * hdd_open() - Wrapper function for __hdd_open to protect it from SSR
5460  * @net_dev: Pointer to net_device structure
5461  *
5462  * This is called in response to ifconfig up
5463  *
5464  * Return: 0 for success; non-zero for failure
5465  */
5466 static int hdd_open(struct net_device *net_dev)
5467 {
5468 	int errno;
5469 	struct osif_vdev_sync *vdev_sync;
5470 
5471 	errno = osif_vdev_sync_trans_start(net_dev, &vdev_sync);
5472 	if (errno)
5473 		return errno;
5474 
5475 	errno = __hdd_open(net_dev);
5476 	if (!errno)
5477 		osif_vdev_cache_command(vdev_sync, NO_COMMAND);
5478 
5479 	osif_vdev_sync_trans_stop(vdev_sync);
5480 
5481 	return errno;
5482 }
5483 
5484 int hdd_stop_no_trans(struct net_device *dev)
5485 {
5486 	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
5487 	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
5488 	int ret;
5489 	mac_handle_t mac_handle;
5490 
5491 	hdd_enter_dev(dev);
5492 
5493 	qdf_mtrace(QDF_MODULE_ID_HDD, QDF_MODULE_ID_HDD,
5494 		   TRACE_CODE_HDD_STOP_REQUEST,
5495 		   adapter->deflink->vdev_id, adapter->device_mode);
5496 
5497 	ret = wlan_hdd_validate_context(hdd_ctx);
5498 	if (ret)
5499 		return ret;
5500 
5501 	/* Nothing to be done if the interface is not opened */
5502 	if (false == test_bit(DEVICE_IFACE_OPENED, &adapter->event_flags)) {
5503 		hdd_err("NETDEV Interface is not OPENED");
5504 		return -ENODEV;
5505 	}
5506 
5507 	mac_handle = hdd_ctx->mac_handle;
5508 
5509 	if (!wlan_hdd_is_session_type_monitor(adapter->device_mode) &&
5510 	    adapter->device_mode != QDF_FTM_MODE) {
5511 		hdd_debug("Disabling Auto Power save timer");
5512 		sme_ps_disable_auto_ps_timer(
5513 			mac_handle,
5514 			adapter->deflink->vdev_id);
5515 	}
5516 
5517 	/*
5518 	 * Disable TX on the interface, after this hard_start_xmit() will not
5519 	 * be called on that interface
5520 	 */
5521 	hdd_debug("Disabling queues, adapter device mode: %s(%d)",
5522 		  qdf_opmode_str(adapter->device_mode), adapter->device_mode);
5523 
5524 	wlan_hdd_netif_queue_control(adapter,
5525 				     WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER,
5526 				     WLAN_CONTROL_PATH);
5527 
5528 	if (adapter->device_mode == QDF_STA_MODE)
5529 		hdd_lpass_notify_stop(hdd_ctx);
5530 
5531 	/*
5532 	 * NAN data interface is different in some sense. The traffic on NDI is
5533 	 * bursty in nature and depends on the need to transfer. The service
5534 	 * layer may down the interface after the usage and up again when
5535 	 * required. In some sense, the NDI is expected to be available
5536 	 * (like SAP) iface until NDI delete request is issued by the service
5537 	 * layer. Skip BSS termination and adapter deletion for NAN Data
5538 	 * interface (NDI).
5539 	 */
5540 	if (WLAN_HDD_IS_NDI(adapter))
5541 		goto reset_iface_opened;
5542 
5543 	/*
5544 	 * The interface is marked as down for outside world (aka kernel)
5545 	 * But the driver is pretty much alive inside. The driver needs to
5546 	 * tear down the existing connection on the netdev (session)
5547 	 * cleanup the data pipes and wait until the control plane is stabilized
5548 	 * for this interface. The call also needs to wait until the above
5549 	 * mentioned actions are completed before returning to the caller.
5550 	 * Notice that hdd_stop_adapter is requested not to close the session
5551 	 * That is intentional to be able to scan if it is a STA/P2P interface
5552 	 */
5553 	hdd_stop_adapter(hdd_ctx, adapter);
5554 
5555 	/* DeInit the adapter. This ensures datapath cleanup as well */
5556 	hdd_deinit_adapter(hdd_ctx, adapter, true);
5557 
5558 reset_iface_opened:
5559 	/* Make sure the interface is marked as closed */
5560 	clear_bit(DEVICE_IFACE_OPENED, &adapter->event_flags);
5561 	if (!hdd_is_any_interface_open(hdd_ctx))
5562 		hdd_psoc_idle_timer_start(hdd_ctx);
5563 	hdd_exit();
5564 
5565 	return 0;
5566 }
5567 
5568 /**
5569  * hdd_stop() - Wrapper function for __hdd_stop to protect it from SSR
5570  * @net_dev: pointer to net_device structure
5571  *
5572  * This is called in response to ifconfig down
5573  *
5574  * Return: 0 for success and error number for failure
5575  */
5576 static int hdd_stop(struct net_device *net_dev)
5577 {
5578 	int errno;
5579 	struct osif_vdev_sync *vdev_sync;
5580 
5581 	errno = osif_vdev_sync_trans_start(net_dev, &vdev_sync);
5582 	if (errno) {
5583 		if (vdev_sync)
5584 			osif_vdev_cache_command(vdev_sync, INTERFACE_DOWN);
5585 		return errno;
5586 	}
5587 
5588 	errno = hdd_stop_no_trans(net_dev);
5589 
5590 	osif_vdev_sync_trans_stop(vdev_sync);
5591 
5592 	return errno;
5593 }
5594 
5595 /**
5596  * hdd_uninit() - HDD uninit function
5597  * @dev: Pointer to net_device structure
5598  *
5599  * This is called during the netdev unregister to uninitialize all data
5600  * associated with the device
5601  *
5602  * This function must be protected by a transition
5603  *
5604  * Return: None
5605  */
5606 static void hdd_uninit(struct net_device *dev)
5607 {
5608 	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
5609 	struct hdd_context *hdd_ctx;
5610 
5611 	hdd_enter_dev(dev);
5612 
5613 	if (adapter->magic != WLAN_HDD_ADAPTER_MAGIC) {
5614 		hdd_err("Invalid magic");
5615 		goto exit;
5616 	}
5617 
5618 	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
5619 	if (!hdd_ctx) {
5620 		hdd_err("NULL hdd_ctx");
5621 		goto exit;
5622 	}
5623 
5624 	if (dev != adapter->dev)
5625 		hdd_err("Invalid device reference");
5626 
5627 	hdd_deinit_adapter(hdd_ctx, adapter, true);
5628 
5629 	/* after uninit our adapter structure will no longer be valid */
5630 	adapter->magic = 0;
5631 
5632 exit:
5633 	hdd_exit();
5634 }
5635 
5636 static int hdd_open_cesium_nl_sock(void)
5637 {
5638 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
5639 	struct netlink_kernel_cfg cfg = {
5640 		.groups = WLAN_NLINK_MCAST_GRP_ID,
5641 		.input = NULL
5642 	};
5643 #endif
5644 	int ret = 0;
5645 
5646 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
5647 	cesium_nl_srv_sock = netlink_kernel_create(&init_net, WLAN_NLINK_CESIUM,
5648 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 7, 0))
5649 						   THIS_MODULE,
5650 #endif
5651 						   &cfg);
5652 #else
5653 	cesium_nl_srv_sock = netlink_kernel_create(&init_net, WLAN_NLINK_CESIUM,
5654 						   WLAN_NLINK_MCAST_GRP_ID,
5655 						   NULL, NULL, THIS_MODULE);
5656 #endif
5657 
5658 	if (!cesium_nl_srv_sock) {
5659 		hdd_err("NLINK:  cesium netlink_kernel_create failed");
5660 		ret = -ECONNREFUSED;
5661 	}
5662 
5663 	return ret;
5664 }
5665 
5666 static void hdd_close_cesium_nl_sock(void)
5667 {
5668 	if (cesium_nl_srv_sock) {
5669 		netlink_kernel_release(cesium_nl_srv_sock);
5670 		cesium_nl_srv_sock = NULL;
5671 	}
5672 }
5673 
5674 void hdd_update_dynamic_mac(struct hdd_context *hdd_ctx,
5675 			    struct qdf_mac_addr *curr_mac_addr,
5676 			    struct qdf_mac_addr *new_mac_addr)
5677 {
5678 	uint8_t i;
5679 
5680 	hdd_enter();
5681 
5682 	for (i = 0; i < QDF_MAX_CONCURRENCY_PERSONA; i++) {
5683 		if (!qdf_mem_cmp(
5684 			curr_mac_addr->bytes,
5685 			&hdd_ctx->dynamic_mac_list[i].dynamic_mac.bytes[0],
5686 				 sizeof(struct qdf_mac_addr))) {
5687 			qdf_mem_copy(&hdd_ctx->dynamic_mac_list[i].dynamic_mac,
5688 				     new_mac_addr->bytes,
5689 				     sizeof(struct qdf_mac_addr));
5690 			break;
5691 		}
5692 	}
5693 
5694 	hdd_exit();
5695 }
5696 
5697 #if defined(WLAN_FEATURE_11BE_MLO) && defined(CFG80211_11BE_BASIC) && \
5698 	!defined(WLAN_HDD_MULTI_VDEV_SINGLE_NDEV)
5699 void hdd_set_mld_address(struct hdd_adapter *adapter,
5700 			 const struct qdf_mac_addr *mac_addr)
5701 {
5702 	int i;
5703 	bool eht_capab;
5704 	struct hdd_adapter *link_adapter;
5705 	struct hdd_mlo_adapter_info *mlo_adapter_info;
5706 
5707 	ucfg_psoc_mlme_get_11be_capab(adapter->hdd_ctx->psoc, &eht_capab);
5708 	if (adapter->mlo_adapter_info.is_ml_adapter && eht_capab) {
5709 		mlo_adapter_info = &adapter->mlo_adapter_info;
5710 		for (i = 0; i < WLAN_MAX_MLD; i++) {
5711 			link_adapter = mlo_adapter_info->link_adapter[i];
5712 			if (link_adapter)
5713 				qdf_copy_macaddr(&link_adapter->mld_addr,
5714 						 mac_addr);
5715 		}
5716 		qdf_copy_macaddr(&adapter->mld_addr, mac_addr);
5717 	}
5718 }
5719 
5720 /**
5721  * hdd_get_netdev_by_vdev_mac() - Get Netdev based on MAC
5722  * @mac_addr: Vdev MAC address
5723  *
5724  * Get netdev from adapter based upon Vdev MAC address.
5725  *
5726  * Return: netdev pointer.
5727  */
5728 static qdf_netdev_t
5729 hdd_get_netdev_by_vdev_mac(struct qdf_mac_addr *mac_addr)
5730 {
5731 	struct hdd_context *hdd_ctx;
5732 	struct hdd_adapter *adapter;
5733 	struct hdd_adapter *ml_adapter;
5734 
5735 	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
5736 	if (!hdd_ctx) {
5737 		hdd_err("Invalid HDD context");
5738 		return NULL;
5739 	}
5740 
5741 	adapter = hdd_get_adapter_by_macaddr(hdd_ctx, mac_addr->bytes);
5742 	if (!adapter) {
5743 		hdd_err("Adapter not foud for MAC " QDF_MAC_ADDR_FMT "",
5744 			QDF_MAC_ADDR_REF(mac_addr->bytes));
5745 		return NULL;
5746 	}
5747 
5748 	if (adapter->mlo_adapter_info.is_link_adapter &&
5749 	    adapter->mlo_adapter_info.associate_with_ml_adapter) {
5750 		ml_adapter = adapter->mlo_adapter_info.ml_adapter;
5751 		adapter =  ml_adapter;
5752 	}
5753 
5754 	return adapter->dev;
5755 }
5756 #else
5757 static qdf_netdev_t
5758 hdd_get_netdev_by_vdev_mac(struct qdf_mac_addr *mac_addr)
5759 {
5760 	struct hdd_context *hdd_ctx;
5761 	struct hdd_adapter *adapter;
5762 
5763 	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
5764 	if (!hdd_ctx) {
5765 		hdd_err("Invalid HDD context");
5766 		return NULL;
5767 	}
5768 
5769 	adapter = hdd_get_adapter_by_macaddr(hdd_ctx, mac_addr->bytes);
5770 	if (!adapter) {
5771 		hdd_err("Adapter not foud for MAC " QDF_MAC_ADDR_FMT "",
5772 			QDF_MAC_ADDR_REF(mac_addr->bytes));
5773 		return NULL;
5774 	}
5775 
5776 	return adapter->dev;
5777 }
5778 #endif
5779 
5780 #ifdef WLAN_FEATURE_DYNAMIC_MAC_ADDR_UPDATE
5781 #if defined(WLAN_FEATURE_11BE_MLO) && defined(CFG80211_11BE_BASIC) && \
5782 	!defined(WLAN_HDD_MULTI_VDEV_SINGLE_NDEV)
5783 static void hdd_update_set_mac_addr_req_ctx(struct hdd_adapter *adapter,
5784 					    void *req_ctx)
5785 {
5786 	adapter->set_mac_addr_req_ctx = req_ctx;
5787 	if (adapter->mlo_adapter_info.associate_with_ml_adapter)
5788 		adapter->mlo_adapter_info.ml_adapter->set_mac_addr_req_ctx =
5789 									req_ctx;
5790 }
5791 #else
5792 static void hdd_update_set_mac_addr_req_ctx(struct hdd_adapter *adapter,
5793 					    void *req_ctx)
5794 {
5795 	adapter->set_mac_addr_req_ctx = req_ctx;
5796 }
5797 #endif
5798 
5799 /**
5800  * hdd_is_dynamic_set_mac_addr_supported() - API to check dynamic MAC address
5801  *				             update is supported or not
5802  * @hdd_ctx: Pointer to the HDD context
5803  *
5804  * Return: true or false
5805  */
5806 static inline bool
5807 hdd_is_dynamic_set_mac_addr_supported(struct hdd_context *hdd_ctx)
5808 {
5809 	return hdd_ctx->is_vdev_macaddr_dynamic_update_supported;
5810 }
5811 
5812 bool hdd_is_dynamic_set_mac_addr_allowed(struct hdd_adapter *adapter)
5813 {
5814 	if (!adapter->deflink->vdev) {
5815 		hdd_err("VDEV is NULL");
5816 		return false;
5817 	}
5818 
5819 	if (!hdd_is_dynamic_set_mac_addr_supported(adapter->hdd_ctx)) {
5820 		hdd_info_rl("On iface up, set mac address change isn't supported");
5821 		return false;
5822 	}
5823 
5824 	switch (adapter->device_mode) {
5825 	case QDF_STA_MODE:
5826 		if (!cm_is_vdev_disconnected(adapter->deflink->vdev)) {
5827 			hdd_info_rl("VDEV is not in disconnected state, set mac address isn't supported");
5828 			return false;
5829 		}
5830 		return true;
5831 	case QDF_P2P_DEVICE_MODE:
5832 		return ucfg_is_p2p_device_dynamic_set_mac_addr_supported(adapter->hdd_ctx->psoc);
5833 	case QDF_SAP_MODE:
5834 		if (test_bit(SOFTAP_BSS_STARTED,
5835 			     &adapter->deflink->link_flags)) {
5836 			hdd_info_rl("SAP is in up state, set mac address isn't supported");
5837 			return false;
5838 		} else {
5839 			return true;
5840 		}
5841 	default:
5842 		hdd_info_rl("Dynamic set mac address isn't supported for opmode:%d",
5843 			adapter->device_mode);
5844 		return false;
5845 	}
5846 }
5847 
5848 int hdd_dynamic_mac_address_set(struct wlan_hdd_link_info *link_info,
5849 				struct qdf_mac_addr mac_addr,
5850 				struct qdf_mac_addr mld_addr,
5851 				bool update_self_peer)
5852 {
5853 	int ret;
5854 	void *cookie;
5855 	bool update_mld_addr;
5856 	uint32_t fw_resp_status;
5857 	QDF_STATUS status = QDF_STATUS_SUCCESS;
5858 	struct osif_request *request;
5859 	struct wlan_objmgr_vdev *vdev;
5860 	struct hdd_adapter *adapter = link_info->adapter;
5861 	struct hdd_context *hdd_ctx = adapter->hdd_ctx;
5862 	struct mac_addr_set_priv *priv;
5863 	static const struct osif_request_params params = {
5864 		.priv_size = sizeof(*priv),
5865 		.timeout_ms = WLAN_SET_MAC_ADDR_TIMEOUT
5866 	};
5867 
5868 	vdev = hdd_objmgr_get_vdev_by_user(link_info, WLAN_OSIF_ID);
5869 	if (!vdev)
5870 		return -EINVAL;
5871 
5872 	if (wlan_vdev_mlme_get_opmode(vdev) != QDF_P2P_DEVICE_MODE) {
5873 		status = ucfg_vdev_mgr_cdp_vdev_detach(vdev);
5874 		if (QDF_IS_STATUS_ERROR(status)) {
5875 			hdd_err("Failed to detach CDP vdev. Status:%d", status);
5876 			ret = qdf_status_to_os_return(status);
5877 			goto vdev_ref;
5878 		}
5879 	}
5880 	request = osif_request_alloc(&params);
5881 	if (!request) {
5882 		hdd_err("request alloc fail");
5883 		status = QDF_STATUS_E_NOMEM;
5884 		ret = -ENOMEM;
5885 		goto status_ret;
5886 	}
5887 
5888 	/* Host should hold a wake lock until the FW event response is received
5889 	 * the WMI event would not be a wake up event.
5890 	 */
5891 	qdf_runtime_pm_prevent_suspend(
5892 			&hdd_ctx->runtime_context.dyn_mac_addr_update);
5893 	hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_DYN_MAC_ADDR_UPDATE);
5894 
5895 	cookie = osif_request_cookie(request);
5896 	hdd_update_set_mac_addr_req_ctx(adapter, cookie);
5897 
5898 	priv = (struct mac_addr_set_priv *)osif_request_priv(request);
5899 
5900 	/* For p2p device mode, need send delete self peer cmd to F/W,
5901 	 * To avoid p2p new DP vdev is created before old DP vdev deleted,
5902 	 * don't create new DP vdev until both self peer delete rsp and set
5903 	 * mac addr rsp received, so initialize pending_rsp_cnt as 2.
5904 	 *
5905 	 * For other mode like STA/SAP, don't need send delete self peer cmd
5906 	 * to F/W, only need wait set mad addr rsp, so initialize
5907 	 * pending_rsp_cnt as 1.
5908 	 */
5909 	if (wlan_vdev_mlme_get_opmode(vdev) == QDF_P2P_DEVICE_MODE)
5910 		qdf_atomic_set(&priv->pending_rsp_cnt, 2);
5911 	else
5912 		qdf_atomic_set(&priv->pending_rsp_cnt, 1);
5913 
5914 	status = sme_send_set_mac_addr(mac_addr, mld_addr, vdev);
5915 	ret = qdf_status_to_os_return(status);
5916 	if (QDF_IS_STATUS_ERROR(status)) {
5917 		hdd_nofl_err("Failed to send set MAC address command. Status:%d",
5918 			     status);
5919 		osif_request_put(request);
5920 		goto status_ret;
5921 	} else {
5922 		ret = osif_request_wait_for_response(request);
5923 		if (ret) {
5924 			hdd_err("Set MAC address response timed out");
5925 		} else {
5926 			fw_resp_status = priv->fw_resp_status;
5927 			if (fw_resp_status) {
5928 				hdd_err("Set MAC address failed in FW. Status: %d",
5929 					fw_resp_status);
5930 				ret = -EAGAIN;
5931 			}
5932 		}
5933 	}
5934 
5935 	osif_request_put(request);
5936 
5937 	if (qdf_is_macaddr_zero(&mld_addr))
5938 		update_mld_addr = false;
5939 	else
5940 		update_mld_addr = true;
5941 
5942 	status = sme_update_vdev_mac_addr(vdev, mac_addr, mld_addr,
5943 					  update_self_peer, update_mld_addr,
5944 					  ret);
5945 
5946 status_ret:
5947 	if (QDF_IS_STATUS_ERROR(status)) {
5948 		ret = qdf_status_to_os_return(status);
5949 		goto allow_suspend;
5950 	} else if (!ret) {
5951 		status = ucfg_dp_update_link_mac_addr(vdev, &mac_addr, false);
5952 		if (QDF_IS_STATUS_ERROR(status)) {
5953 			ret = qdf_status_to_os_return(status);
5954 			hdd_err("DP link MAC update failed");
5955 			goto allow_suspend;
5956 		}
5957 	}
5958 	sme_vdev_set_data_tx_callback(vdev);
5959 
5960 	/* Update FW WoW pattern with new MAC address */
5961 	ucfg_pmo_del_wow_pattern(vdev);
5962 	ucfg_pmo_register_wow_default_patterns(vdev);
5963 	hdd_tx_latency_restore_config(link_info);
5964 
5965 allow_suspend:
5966 	hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DYN_MAC_ADDR_UPDATE);
5967 	qdf_runtime_pm_allow_suspend(
5968 			&hdd_ctx->runtime_context.dyn_mac_addr_update);
5969 
5970 vdev_ref:
5971 	hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_ID);
5972 
5973 	return ret;
5974 }
5975 
5976 static void hdd_set_mac_addr_event_cb(uint8_t vdev_id, uint8_t status)
5977 {
5978 	struct hdd_context *hdd_ctx;
5979 	struct wlan_hdd_link_info *link_info;
5980 	struct osif_request *req;
5981 	struct mac_addr_set_priv *priv;
5982 
5983 	osif_debug("enter");
5984 	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
5985 	if (!hdd_ctx) {
5986 		hdd_err("Invalid HDD context");
5987 		return;
5988 	}
5989 
5990 	link_info = hdd_get_link_info_by_vdev(hdd_ctx, vdev_id);
5991 	if (!link_info) {
5992 		hdd_err("No adapter found for VDEV ID:%d", vdev_id);
5993 		return;
5994 	}
5995 
5996 	req = osif_request_get(link_info->adapter->set_mac_addr_req_ctx);
5997 	if (!req) {
5998 		osif_err("Obsolete request for VDEV ID:%d", vdev_id);
5999 		return;
6000 	}
6001 
6002 	priv = (struct mac_addr_set_priv *)osif_request_priv(req);
6003 
6004 	if (qdf_atomic_dec_and_test(&priv->pending_rsp_cnt)) {
6005 		priv->fw_resp_status = status;
6006 		osif_request_complete(req);
6007 	}
6008 
6009 	osif_request_put(req);
6010 }
6011 #else
6012 static inline bool
6013 hdd_is_dynamic_set_mac_addr_supported(struct hdd_context *hdd_ctx)
6014 {
6015 	return false;
6016 }
6017 #endif
6018 
6019 #if defined(WLAN_FEATURE_11BE_MLO) && defined(WLAN_HDD_MULTI_VDEV_SINGLE_NDEV)
6020 static QDF_STATUS
6021 hdd_adapter_update_links_on_link_switch(struct wlan_hdd_link_info *cur_link_info,
6022 					struct wlan_hdd_link_info *new_link_info)
6023 {
6024 	unsigned long link_flags;
6025 	struct wlan_objmgr_vdev *vdev;
6026 	int cur_link_idx, new_link_idx;
6027 	uint8_t cur_old_pos, cur_new_pos;
6028 	struct vdev_osif_priv *vdev_priv;
6029 	struct hdd_adapter *adapter = cur_link_info->adapter;
6030 
6031 	/* Update the new position of current and new link info
6032 	 * in the link info array.
6033 	 */
6034 	cur_link_idx = hdd_adapter_get_index_of_link_info(cur_link_info);
6035 	new_link_idx = hdd_adapter_get_index_of_link_info(new_link_info);
6036 
6037 	cur_old_pos = adapter->curr_link_info_map[cur_link_idx];
6038 	cur_new_pos = adapter->curr_link_info_map[new_link_idx];
6039 
6040 	adapter->curr_link_info_map[new_link_idx] = cur_old_pos;
6041 	adapter->curr_link_info_map[cur_link_idx] = cur_new_pos;
6042 
6043 	/* Move VDEV from current link info to new link info */
6044 	qdf_atomic_clear_bit(cur_link_idx, &adapter->active_links);
6045 	qdf_spin_lock_bh(&cur_link_info->vdev_lock);
6046 	vdev = cur_link_info->vdev;
6047 	cur_link_info->vdev = NULL;
6048 	cur_link_info->vdev_id = WLAN_INVALID_VDEV_ID;
6049 	qdf_spin_unlock_bh(&cur_link_info->vdev_lock);
6050 
6051 	qdf_spin_lock_bh(&new_link_info->vdev_lock);
6052 	new_link_info->vdev = vdev;
6053 	new_link_info->vdev_id = wlan_vdev_get_id(vdev);
6054 	qdf_spin_unlock_bh(&new_link_info->vdev_lock);
6055 	qdf_atomic_set_bit(new_link_idx, &adapter->active_links);
6056 
6057 	/* Move the link flags between current and new link info */
6058 	link_flags = new_link_info->link_flags;
6059 	new_link_info->link_flags = cur_link_info->link_flags;
6060 	cur_link_info->link_flags = link_flags;
6061 
6062 	/* Update VDEV-OSIF priv pointer to new link info */
6063 	vdev_priv = wlan_vdev_get_ospriv(new_link_info->vdev);
6064 	vdev_priv->legacy_osif_priv = new_link_info;
6065 
6066 	return QDF_STATUS_SUCCESS;
6067 }
6068 
6069 struct wlan_hdd_link_info *
6070 hdd_get_link_info_by_ieee_link_id(struct hdd_adapter *adapter, int32_t link_id)
6071 {
6072 	struct wlan_hdd_link_info *link_info;
6073 	struct hdd_station_ctx *sta_ctx;
6074 
6075 	if (!adapter || link_id == WLAN_INVALID_LINK_ID) {
6076 		hdd_err("NULL adapter or invalid link ID");
6077 		return NULL;
6078 	}
6079 
6080 	hdd_adapter_for_each_link_info(adapter, link_info) {
6081 		sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(link_info);
6082 		if (sta_ctx->conn_info.ieee_link_id == link_id)
6083 			return link_info;
6084 	}
6085 
6086 	return NULL;
6087 }
6088 
6089 QDF_STATUS
6090 hdd_link_switch_vdev_mac_addr_update(int32_t ieee_old_link_id,
6091 				     int32_t ieee_new_link_id, uint8_t vdev_id)
6092 {
6093 	QDF_STATUS status = QDF_STATUS_E_INVAL;
6094 	struct hdd_context *hdd_ctx;
6095 	struct hdd_adapter *adapter;
6096 	struct wlan_objmgr_vdev *vdev;
6097 	struct wlan_hdd_link_info *cur_link_info, *new_link_info;
6098 	struct hdd_station_ctx *sta_ctx;
6099 
6100 	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
6101 	if (!hdd_ctx) {
6102 		hdd_err("HDD ctx NULL");
6103 		return QDF_STATUS_E_INVAL;
6104 	}
6105 
6106 	cur_link_info = hdd_get_link_info_by_vdev(hdd_ctx, vdev_id);
6107 	if (!cur_link_info) {
6108 		hdd_err("VDEV %d not found", vdev_id);
6109 		return status;
6110 	}
6111 
6112 	vdev = hdd_objmgr_get_vdev_by_user(cur_link_info, WLAN_OSIF_ID);
6113 	if (!vdev) {
6114 		hdd_err("Invalid VDEV %d", vdev_id);
6115 		return status;
6116 	}
6117 
6118 	sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(cur_link_info);
6119 	if (sta_ctx->conn_info.ieee_link_id != ieee_old_link_id) {
6120 		hdd_err("Link id %d mismatch", sta_ctx->conn_info.ieee_link_id);
6121 		goto release_ref;
6122 	}
6123 
6124 	adapter = cur_link_info->adapter;
6125 	new_link_info = hdd_get_link_info_by_ieee_link_id(adapter,
6126 							  ieee_new_link_id);
6127 	if (!new_link_info) {
6128 		hdd_err("Link id %d not found", ieee_new_link_id);
6129 		goto release_ref;
6130 	}
6131 
6132 	status = ucfg_dp_update_link_mac_addr(vdev, &new_link_info->link_addr,
6133 					      true);
6134 	if (QDF_IS_STATUS_ERROR(status)) {
6135 		hdd_err("DP link MAC update failed");
6136 		goto release_ref;
6137 	}
6138 
6139 	status = hdd_adapter_update_links_on_link_switch(cur_link_info,
6140 							 new_link_info);
6141 	if (QDF_IS_STATUS_ERROR(status)) {
6142 		hdd_err("Failed to update adapter link info");
6143 		goto release_ref;
6144 	}
6145 
6146 	hdd_adapter_update_mlo_mgr_mac_addr(adapter);
6147 	sme_vdev_set_data_tx_callback(vdev);
6148 	ucfg_pmo_del_wow_pattern(vdev);
6149 	ucfg_pmo_register_wow_default_patterns(vdev);
6150 
6151 release_ref:
6152 	hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_ID);
6153 	return status;
6154 }
6155 #endif
6156 
6157 /**
6158  * __hdd_set_mac_address() - set the user specified mac address
6159  * @dev:	Pointer to the net device.
6160  * @addr:	Pointer to the sockaddr.
6161  *
6162  * This function sets the user specified mac address using
6163  * the command ifconfig wlanX hw ether <mac address>.
6164  *
6165  * Return: 0 for success, non zero for failure
6166  */
6167 static int __hdd_set_mac_address(struct net_device *dev, void *addr)
6168 {
6169 	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
6170 	struct hdd_adapter *adapter_temp;
6171 	struct hdd_context *hdd_ctx;
6172 	struct sockaddr *psta_mac_addr = addr;
6173 	QDF_STATUS qdf_ret_status = QDF_STATUS_SUCCESS;
6174 	int ret;
6175 	struct qdf_mac_addr mac_addr;
6176 	bool net_if_running = netif_running(dev);
6177 
6178 	hdd_enter_dev(dev);
6179 
6180 	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
6181 	ret = wlan_hdd_validate_context(hdd_ctx);
6182 	if (0 != ret)
6183 		return ret;
6184 
6185 	if (net_if_running) {
6186 		if (!hdd_is_dynamic_set_mac_addr_allowed(adapter))
6187 			return -ENOTSUPP;
6188 	}
6189 
6190 	qdf_mem_copy(&mac_addr, psta_mac_addr->sa_data, sizeof(mac_addr));
6191 	adapter_temp = hdd_get_adapter_by_macaddr(hdd_ctx, mac_addr.bytes);
6192 	if (adapter_temp) {
6193 		if (!qdf_str_cmp(adapter_temp->dev->name, dev->name))
6194 			return 0;
6195 		hdd_err("%s adapter exist with same address " QDF_MAC_ADDR_FMT,
6196 			adapter_temp->dev->name,
6197 			QDF_MAC_ADDR_REF(mac_addr.bytes));
6198 		return -EINVAL;
6199 	}
6200 	qdf_ret_status = wlan_hdd_validate_mac_address(&mac_addr);
6201 	if (QDF_IS_STATUS_ERROR(qdf_ret_status))
6202 		return -EINVAL;
6203 
6204 	hdd_nofl_debug("Changing MAC to "
6205 		       QDF_MAC_ADDR_FMT " of the interface %s ",
6206 		       QDF_MAC_ADDR_REF(mac_addr.bytes), dev->name);
6207 
6208 	if (net_if_running && adapter->deflink->vdev) {
6209 		ret = hdd_update_vdev_mac_address(adapter, mac_addr);
6210 		if (ret)
6211 			return ret;
6212 	}
6213 
6214 	hdd_set_mld_address(adapter, &mac_addr);
6215 
6216 	hdd_update_dynamic_mac(hdd_ctx, &adapter->mac_addr, &mac_addr);
6217 	ucfg_dp_update_intf_mac(hdd_ctx->psoc, &adapter->mac_addr, &mac_addr,
6218 				adapter->deflink->vdev);
6219 	memcpy(&adapter->mac_addr, psta_mac_addr->sa_data, ETH_ALEN);
6220 	qdf_net_update_net_device_dev_addr(dev, psta_mac_addr->sa_data,
6221 					   ETH_ALEN);
6222 
6223 	hdd_exit();
6224 	return ret;
6225 }
6226 
6227 /**
6228  * hdd_set_mac_address() - Wrapper function to protect __hdd_set_mac_address()
6229  *	function from SSR
6230  * @net_dev: pointer to net_device structure
6231  * @addr: Pointer to the sockaddr
6232  *
6233  * This function sets the user specified mac address using
6234  * the command ifconfig wlanX hw ether <mac address>.
6235  *
6236  * Return: 0 for success.
6237  */
6238 static int hdd_set_mac_address(struct net_device *net_dev, void *addr)
6239 {
6240 	struct osif_vdev_sync *vdev_sync;
6241 	int errno;
6242 
6243 	errno = osif_vdev_sync_op_start(net_dev, &vdev_sync);
6244 	if (errno)
6245 		return errno;
6246 
6247 	errno = __hdd_set_mac_address(net_dev, addr);
6248 
6249 	osif_vdev_sync_op_stop(vdev_sync);
6250 
6251 	return errno;
6252 }
6253 
6254 static uint8_t *wlan_hdd_get_derived_intf_addr(struct hdd_context *hdd_ctx)
6255 {
6256 	int i, j;
6257 
6258 	i = qdf_ffz(hdd_ctx->derived_intf_addr_mask);
6259 	if (i < 0 || i >= hdd_ctx->num_derived_addr)
6260 		return NULL;
6261 	qdf_atomic_set_bit(i, &hdd_ctx->derived_intf_addr_mask);
6262 	hdd_nofl_debug("Assigning MAC from derived list "QDF_MAC_ADDR_FMT,
6263 		       QDF_MAC_ADDR_REF(hdd_ctx->derived_mac_addr[i].bytes));
6264 
6265 	/* Copy the mac in dynamic mac list at first free position */
6266 	for (j = 0; j < QDF_MAX_CONCURRENCY_PERSONA; j++) {
6267 		if (qdf_is_macaddr_zero(&hdd_ctx->
6268 					dynamic_mac_list[j].dynamic_mac))
6269 			break;
6270 	}
6271 	if (j == QDF_MAX_CONCURRENCY_PERSONA) {
6272 		hdd_err("Max interfaces are up");
6273 		return NULL;
6274 	}
6275 
6276 	qdf_mem_copy(&hdd_ctx->dynamic_mac_list[j].dynamic_mac.bytes,
6277 		     &hdd_ctx->derived_mac_addr[i].bytes,
6278 		     sizeof(struct qdf_mac_addr));
6279 	hdd_ctx->dynamic_mac_list[j].is_provisioned_mac = false;
6280 	hdd_ctx->dynamic_mac_list[j].bit_position = i;
6281 
6282 	return hdd_ctx->derived_mac_addr[i].bytes;
6283 }
6284 
6285 static uint8_t *wlan_hdd_get_provisioned_intf_addr(struct hdd_context *hdd_ctx)
6286 {
6287 	int i, j;
6288 
6289 	i = qdf_ffz(hdd_ctx->provisioned_intf_addr_mask);
6290 	if (i < 0 || i >= hdd_ctx->num_provisioned_addr)
6291 		return NULL;
6292 	qdf_atomic_set_bit(i, &hdd_ctx->provisioned_intf_addr_mask);
6293 	hdd_debug("Assigning MAC from provisioned list "QDF_MAC_ADDR_FMT,
6294 		  QDF_MAC_ADDR_REF(hdd_ctx->provisioned_mac_addr[i].bytes));
6295 
6296 	/* Copy the mac in dynamic mac list at first free position */
6297 	for (j = 0; j < QDF_MAX_CONCURRENCY_PERSONA; j++) {
6298 		if (qdf_is_macaddr_zero(&hdd_ctx->
6299 					dynamic_mac_list[j].dynamic_mac))
6300 			break;
6301 	}
6302 	if (j == QDF_MAX_CONCURRENCY_PERSONA) {
6303 		hdd_err("Max interfaces are up");
6304 		return NULL;
6305 	}
6306 
6307 	qdf_mem_copy(&hdd_ctx->dynamic_mac_list[j].dynamic_mac.bytes,
6308 		     &hdd_ctx->provisioned_mac_addr[i].bytes,
6309 		     sizeof(struct qdf_mac_addr));
6310 	hdd_ctx->dynamic_mac_list[j].is_provisioned_mac = true;
6311 	hdd_ctx->dynamic_mac_list[j].bit_position = i;
6312 	return hdd_ctx->provisioned_mac_addr[i].bytes;
6313 }
6314 
6315 uint8_t *wlan_hdd_get_intf_addr(struct hdd_context *hdd_ctx,
6316 				enum QDF_OPMODE interface_type)
6317 {
6318 	uint8_t *mac_addr = NULL;
6319 
6320 	if (qdf_atomic_test_bit(interface_type,
6321 				(unsigned long *)
6322 				(&hdd_ctx->config->provisioned_intf_pool)))
6323 		mac_addr = wlan_hdd_get_provisioned_intf_addr(hdd_ctx);
6324 
6325 	if ((!mac_addr) &&
6326 	    (qdf_atomic_test_bit(interface_type,
6327 				 (unsigned long *)
6328 				 (&hdd_ctx->config->derived_intf_pool))))
6329 		mac_addr = wlan_hdd_get_derived_intf_addr(hdd_ctx);
6330 
6331 	if (!mac_addr)
6332 		hdd_err("MAC is not available in both the lists");
6333 	return mac_addr;
6334 }
6335 
6336 void wlan_hdd_release_intf_addr(struct hdd_context *hdd_ctx,
6337 				uint8_t *releaseAddr)
6338 {
6339 	int i;
6340 	int mac_pos_in_mask;
6341 
6342 	for (i = 0; i < QDF_MAX_CONCURRENCY_PERSONA; i++) {
6343 		if (!memcmp(releaseAddr,
6344 		    hdd_ctx->dynamic_mac_list[i].dynamic_mac.bytes,
6345 		    QDF_MAC_ADDR_SIZE)) {
6346 			mac_pos_in_mask =
6347 				hdd_ctx->dynamic_mac_list[i].bit_position;
6348 			if (hdd_ctx->dynamic_mac_list[i].is_provisioned_mac) {
6349 				qdf_atomic_clear_bit(
6350 						mac_pos_in_mask,
6351 						&hdd_ctx->
6352 						   provisioned_intf_addr_mask);
6353 				hdd_debug("Releasing MAC from provisioned list");
6354 				hdd_debug(
6355 					  QDF_MAC_ADDR_FMT,
6356 					  QDF_MAC_ADDR_REF(releaseAddr));
6357 			} else {
6358 				qdf_atomic_clear_bit(
6359 						mac_pos_in_mask, &hdd_ctx->
6360 						derived_intf_addr_mask);
6361 				hdd_debug("Releasing MAC from derived list");
6362 				hdd_debug(QDF_MAC_ADDR_FMT,
6363 					  QDF_MAC_ADDR_REF(releaseAddr));
6364 			}
6365 			qdf_zero_macaddr(&hdd_ctx->
6366 					    dynamic_mac_list[i].dynamic_mac);
6367 			hdd_ctx->dynamic_mac_list[i].is_provisioned_mac =
6368 									false;
6369 			hdd_ctx->dynamic_mac_list[i].bit_position = 0;
6370 			break;
6371 		}
6372 
6373 	}
6374 	if (i == QDF_MAX_CONCURRENCY_PERSONA)
6375 		hdd_debug("Releasing non existing MAC " QDF_MAC_ADDR_FMT,
6376 			  QDF_MAC_ADDR_REF(releaseAddr));
6377 }
6378 
6379 /**
6380  * hdd_set_derived_multicast_list(): Add derived peer multicast address list in
6381  *                                   multicast list request to the FW
6382  * @psoc: Pointer to psoc
6383  * @adapter: Pointer to hdd adapter
6384  * @mc_list_request: Multicast list request to the FW
6385  * @mc_count: number of multicast addresses received from the kernel
6386  *
6387  * Return: None
6388  */
6389 static void
6390 hdd_set_derived_multicast_list(struct wlan_objmgr_psoc *psoc,
6391 			       struct hdd_adapter *adapter,
6392 			       struct pmo_mc_addr_list_params *mc_list_request,
6393 			       int *mc_count)
6394 {
6395 	int i = 0, j = 0, list_count = *mc_count;
6396 	struct qdf_mac_addr *peer_mc_addr_list = NULL;
6397 	uint8_t  driver_mc_cnt = 0;
6398 	uint32_t max_ndp_sessions = 0;
6399 
6400 	cfg_nan_get_ndp_max_sessions(psoc, &max_ndp_sessions);
6401 
6402 	ucfg_nan_get_peer_mc_list(adapter->deflink->vdev, &peer_mc_addr_list);
6403 
6404 	for (j = 0; j < max_ndp_sessions; j++) {
6405 		for (i = 0; i < list_count; i++) {
6406 			if (qdf_is_macaddr_zero(&peer_mc_addr_list[j]) ||
6407 			    qdf_is_macaddr_equal(&mc_list_request->mc_addr[i],
6408 						 &peer_mc_addr_list[j]))
6409 				break;
6410 		}
6411 		if (i == list_count) {
6412 			qdf_mem_copy(
6413 			   &(mc_list_request->mc_addr[list_count +
6414 						driver_mc_cnt].bytes),
6415 			   peer_mc_addr_list[j].bytes, ETH_ALEN);
6416 			hdd_debug("mlist[%d] = " QDF_MAC_ADDR_FMT,
6417 				  list_count + driver_mc_cnt,
6418 				  QDF_MAC_ADDR_REF(
6419 					mc_list_request->mc_addr[list_count +
6420 					driver_mc_cnt].bytes));
6421 			driver_mc_cnt++;
6422 		}
6423 	}
6424 	*mc_count += driver_mc_cnt;
6425 }
6426 
6427 /**
6428  * __hdd_set_multicast_list() - set the multicast address list
6429  * @dev: Pointer to the WLAN device.
6430  *
6431  * This function sets the multicast address list.
6432  *
6433  * Return: None
6434  */
6435 static void __hdd_set_multicast_list(struct net_device *dev)
6436 {
6437 	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
6438 	int i = 0, errno;
6439 	struct netdev_hw_addr *ha;
6440 	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
6441 	struct pmo_mc_addr_list_params *mc_list_request = NULL;
6442 	struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc;
6443 	int mc_count = 0;
6444 
6445 	if (hdd_ctx->hdd_wlan_suspended) {
6446 		hdd_err_rl("Device is system suspended");
6447 		return;
6448 	}
6449 
6450 	hdd_enter_dev(dev);
6451 	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam())
6452 		return;
6453 
6454 	errno = wlan_hdd_validate_context(hdd_ctx);
6455 	if (errno)
6456 		return;
6457 
6458 	errno = hdd_validate_adapter(adapter);
6459 	if (errno)
6460 		return;
6461 
6462 	if (hdd_ctx->driver_status == DRIVER_MODULES_CLOSED) {
6463 		hdd_debug("Driver module is closed");
6464 		return;
6465 	}
6466 
6467 	mc_list_request = qdf_mem_malloc(sizeof(*mc_list_request));
6468 	if (!mc_list_request)
6469 		return;
6470 
6471 	qdf_spin_lock_bh(&adapter->mc_list_lock);
6472 	/* Delete already configured multicast address list */
6473 	if (adapter->mc_addr_list.mc_cnt > 0)
6474 		hdd_disable_and_flush_mc_addr_list(adapter,
6475 			pmo_mc_list_change_notify);
6476 
6477 	if (dev->flags & IFF_ALLMULTI) {
6478 		hdd_debug("allow all multicast frames");
6479 		hdd_disable_and_flush_mc_addr_list(adapter,
6480 			pmo_mc_list_change_notify);
6481 	} else {
6482 		mc_count = netdev_mc_count(dev);
6483 		if (mc_count > ucfg_pmo_max_mc_addr_supported(psoc)) {
6484 			hdd_debug("Exceeded max MC filter addresses (%d). Allowing all MC frames by disabling MC address filtering",
6485 				  ucfg_pmo_max_mc_addr_supported(psoc));
6486 			hdd_disable_and_flush_mc_addr_list(adapter,
6487 				pmo_mc_list_change_notify);
6488 			adapter->mc_addr_list.mc_cnt = 0;
6489 			goto free_req;
6490 		}
6491 		netdev_for_each_mc_addr(ha, dev) {
6492 			if (i == mc_count)
6493 				break;
6494 			memset(&(mc_list_request->mc_addr[i].bytes),
6495 				0, ETH_ALEN);
6496 			memcpy(&(mc_list_request->mc_addr[i].bytes),
6497 				ha->addr, ETH_ALEN);
6498 			hdd_debug("mlist[%d] = "QDF_MAC_ADDR_FMT, i,
6499 				  QDF_MAC_ADDR_REF(mc_list_request->mc_addr[i].bytes));
6500 			i++;
6501 		}
6502 
6503 		if (adapter->device_mode == QDF_NDI_MODE)
6504 			hdd_set_derived_multicast_list(psoc, adapter,
6505 						       mc_list_request,
6506 						       &mc_count);
6507 	}
6508 
6509 	adapter->mc_addr_list.mc_cnt = mc_count;
6510 	mc_list_request->psoc = psoc;
6511 	mc_list_request->vdev_id = adapter->deflink->vdev_id;
6512 	mc_list_request->count = mc_count;
6513 
6514 	errno = hdd_cache_mc_addr_list(mc_list_request);
6515 	if (errno) {
6516 		hdd_debug("Failed to cache MC address list for vdev %u; errno:%d",
6517 			  adapter->deflink->vdev_id, errno);
6518 		goto free_req;
6519 	}
6520 
6521 	hdd_enable_mc_addr_filtering(adapter, pmo_mc_list_change_notify);
6522 
6523 free_req:
6524 	qdf_spin_unlock_bh(&adapter->mc_list_lock);
6525 	qdf_mem_free(mc_list_request);
6526 }
6527 
6528 /**
6529  * hdd_set_multicast_list() - SSR wrapper function for __hdd_set_multicast_list
6530  * @net_dev: pointer to net_device
6531  *
6532  * Return: none
6533  */
6534 static void hdd_set_multicast_list(struct net_device *net_dev)
6535 {
6536 	struct osif_vdev_sync *vdev_sync;
6537 
6538 	if (osif_vdev_sync_op_start(net_dev, &vdev_sync))
6539 		return;
6540 
6541 	__hdd_set_multicast_list(net_dev);
6542 
6543 	osif_vdev_sync_op_stop(vdev_sync);
6544 }
6545 
6546 void hdd_update_multicast_list(struct wlan_objmgr_vdev *vdev)
6547 {
6548 	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
6549 	struct wlan_hdd_link_info *link_info;
6550 	struct hdd_adapter *adapter;
6551 	uint8_t vdev_id = wlan_vdev_get_id(vdev);
6552 	struct net_device *net_dev;
6553 
6554 	if (!hdd_ctx) {
6555 		hdd_err("hdd_ctx is null");
6556 		return;
6557 	}
6558 
6559 	link_info = hdd_get_link_info_by_vdev(hdd_ctx, vdev_id);
6560 	if (!link_info) {
6561 		hdd_err("adapter is null for vdev_id %d", vdev_id);
6562 		return;
6563 	}
6564 
6565 	adapter = link_info->adapter;
6566 	if (!adapter) {
6567 		hdd_err("adapter is null for vdev_id %d", vdev_id);
6568 		return;
6569 	}
6570 
6571 	net_dev = adapter->dev;
6572 	if (!net_dev) {
6573 		hdd_err("netdev is null");
6574 		return;
6575 	}
6576 
6577 	__hdd_set_multicast_list(net_dev);
6578 }
6579 
6580 #ifdef WLAN_FEATURE_TSF_PTP
6581 static const struct ethtool_ops wlan_ethtool_ops = {
6582 	.get_ts_info = wlan_get_ts_info,
6583 };
6584 #endif
6585 
6586 /**
6587  * __hdd_fix_features - Adjust the feature flags needed to be updated
6588  * @net_dev: Handle to net_device
6589  * @features: Currently enabled feature flags
6590  *
6591  * Return: Adjusted feature flags on success, old feature on failure
6592  */
6593 static netdev_features_t __hdd_fix_features(struct net_device *net_dev,
6594 					    netdev_features_t features)
6595 {
6596 	netdev_features_t feature_change_req = features;
6597 	netdev_features_t feature_tso_csum;
6598 	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(net_dev);
6599 
6600 	if (!adapter->handle_feature_update) {
6601 		hdd_debug("Not triggered by hdd_netdev_update_features");
6602 		return features;
6603 	}
6604 
6605 	feature_tso_csum = hdd_get_tso_csum_feature_flags();
6606 	if (hdd_is_legacy_connection(adapter->deflink)) {
6607 		/* Disable checksum and TSO */
6608 		feature_change_req &= ~feature_tso_csum;
6609 		adapter->tso_csum_feature_enabled = 0;
6610 	} else {
6611 		/* Enable checksum and TSO */
6612 		feature_change_req |= feature_tso_csum;
6613 		adapter->tso_csum_feature_enabled = 1;
6614 	}
6615 	hdd_debug("vdev mode %d current features 0x%llx, requesting feature change 0x%llx",
6616 		  adapter->device_mode, net_dev->features,
6617 		  feature_change_req);
6618 
6619 	return feature_change_req;
6620 }
6621 
6622 /**
6623  * hdd_fix_features() - Wrapper for __hdd_fix_features to protect it from SSR
6624  * @net_dev: Pointer to net_device structure
6625  * @features: Updated features set
6626  *
6627  * Adjusts the feature request, do not update the device yet.
6628  *
6629  * Return: updated feature for success, incoming feature as is on failure
6630  */
6631 static netdev_features_t hdd_fix_features(struct net_device *net_dev,
6632 					  netdev_features_t features)
6633 {
6634 	int errno;
6635 	int changed_features = features;
6636 	struct osif_vdev_sync *vdev_sync;
6637 
6638 	errno = osif_vdev_sync_op_start(net_dev, &vdev_sync);
6639 	if (errno)
6640 		return features;
6641 
6642 	changed_features = __hdd_fix_features(net_dev, features);
6643 
6644 	osif_vdev_sync_op_stop(vdev_sync);
6645 
6646 	return changed_features;
6647 }
6648 /**
6649  * __hdd_set_features - Notify device about change in features
6650  * @net_dev: Handle to net_device
6651  * @features: Existing + requested feature after resolving the dependency
6652  *
6653  * Return: 0 on success, non zero error on failure
6654  */
6655 static int __hdd_set_features(struct net_device *net_dev,
6656 			      netdev_features_t features)
6657 {
6658 	struct hdd_adapter *adapter = netdev_priv(net_dev);
6659 	ol_txrx_soc_handle soc = cds_get_context(QDF_MODULE_ID_SOC);
6660 
6661 	if (!adapter->handle_feature_update) {
6662 		hdd_debug("Not triggered by hdd_netdev_update_features");
6663 		return 0;
6664 	}
6665 
6666 	if (!soc)
6667 		return 0;
6668 
6669 	hdd_debug("vdev mode %d vdev_id %d current features 0x%llx, changed features 0x%llx",
6670 		  adapter->device_mode, adapter->deflink->vdev_id,
6671 		  net_dev->features, features);
6672 
6673 	return 0;
6674 }
6675 
6676 /**
6677  * hdd_set_features() - Wrapper for __hdd_set_features to protect it from SSR
6678  * @net_dev: Pointer to net_device structure
6679  * @features: Updated features set
6680  *
6681  * Is called to update device configurations for changed features.
6682  *
6683  * Return: 0 for success, non-zero for failure
6684  */
6685 static int hdd_set_features(struct net_device *net_dev,
6686 			    netdev_features_t features)
6687 {
6688 	int errno;
6689 	struct osif_vdev_sync *vdev_sync;
6690 
6691 	errno = osif_vdev_sync_op_start(net_dev, &vdev_sync);
6692 	if (errno) {
6693 		/*
6694 		 * Only invoke from netdev_feature_update_work expected,
6695 		 * which is from CLD inside.
6696 		 * Ignore others from upper stack during loading phase,
6697 		 * and return success to avoid failure print from kernel.
6698 		 */
6699 		hdd_debug("VDEV in transition, ignore set_features");
6700 		return 0;
6701 	}
6702 
6703 	errno = __hdd_set_features(net_dev, features);
6704 
6705 	osif_vdev_sync_op_stop(vdev_sync);
6706 
6707 	return errno;
6708 }
6709 
6710 #define HDD_NETDEV_FEATURES_UPDATE_MAX_WAIT_COUNT	10
6711 #define HDD_NETDEV_FEATURES_UPDATE_WAIT_INTERVAL_MS	20
6712 
6713 void hdd_netdev_update_features(struct hdd_adapter *adapter)
6714 {
6715 	struct net_device *net_dev = adapter->dev;
6716 	ol_txrx_soc_handle soc = cds_get_context(QDF_MODULE_ID_SOC);
6717 	bool request_feature_update = false;
6718 	int wait_count = HDD_NETDEV_FEATURES_UPDATE_MAX_WAIT_COUNT;
6719 
6720 	if (!soc)
6721 		return;
6722 
6723 	if (!cdp_cfg_get(soc, cfg_dp_disable_legacy_mode_csum_offload))
6724 		return;
6725 
6726 	switch (adapter->device_mode) {
6727 	case QDF_STA_MODE:
6728 		if (cdp_cfg_get(soc, cfg_dp_enable_ip_tcp_udp_checksum_offload))
6729 			request_feature_update = true;
6730 		break;
6731 	default:
6732 		break;
6733 	}
6734 
6735 	if (request_feature_update) {
6736 		hdd_debug("Update net_dev features for device mode %d",
6737 			  adapter->device_mode);
6738 		while (!adapter->delete_in_progress) {
6739 			if (rtnl_trylock()) {
6740 				adapter->handle_feature_update = true;
6741 				netdev_update_features(net_dev);
6742 				adapter->handle_feature_update = false;
6743 				rtnl_unlock();
6744 				break;
6745 			}
6746 
6747 			if (wait_count--) {
6748 				qdf_sleep(
6749 				HDD_NETDEV_FEATURES_UPDATE_WAIT_INTERVAL_MS);
6750 			} else {
6751 				/*
6752 				 * We have failed to updated the netdev
6753 				 * features for very long, so enable the queues
6754 				 * now. The impact of not being able to update
6755 				 * the netdev feature is lower TPUT when
6756 				 * switching from legacy to non-legacy mode.
6757 				 */
6758 				hdd_err("Failed to update netdev features for device mode %d",
6759 					adapter->device_mode);
6760 				break;
6761 			}
6762 		}
6763 	}
6764 }
6765 
6766 static const struct net_device_ops wlan_drv_ops = {
6767 	.ndo_open = hdd_open,
6768 	.ndo_stop = hdd_stop,
6769 	.ndo_uninit = hdd_uninit,
6770 	.ndo_start_xmit = hdd_hard_start_xmit,
6771 	.ndo_fix_features = hdd_fix_features,
6772 	.ndo_set_features = hdd_set_features,
6773 	.ndo_tx_timeout = hdd_tx_timeout,
6774 	.ndo_get_stats = hdd_get_stats,
6775 #if LINUX_VERSION_CODE < KERNEL_VERSION(5, 15, 0)
6776 	.ndo_do_ioctl = hdd_ioctl,
6777 #endif
6778 	.ndo_set_mac_address = hdd_set_mac_address,
6779 	.ndo_select_queue = hdd_select_queue,
6780 	.ndo_set_rx_mode = hdd_set_multicast_list,
6781 #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0)
6782 	.ndo_siocdevprivate = hdd_dev_private_ioctl,
6783 #endif
6784 };
6785 
6786 #ifdef FEATURE_MONITOR_MODE_SUPPORT
6787 /* Monitor mode net_device_ops, does not Tx and most of operations. */
6788 static const struct net_device_ops wlan_mon_drv_ops = {
6789 	.ndo_open = hdd_mon_open,
6790 	.ndo_stop = hdd_stop,
6791 	.ndo_get_stats = hdd_get_stats,
6792 };
6793 
6794 /**
6795  * hdd_set_mon_ops() - update net_device ops for monitor mode
6796  * @dev: Handle to struct net_device to be updated.
6797  * Return: None
6798  */
6799 static void hdd_set_mon_ops(struct net_device *dev)
6800 {
6801 	dev->netdev_ops = &wlan_mon_drv_ops;
6802 }
6803 
6804 #ifdef WLAN_FEATURE_TSF_PTP
6805 void hdd_set_station_ops(struct net_device *dev)
6806 {
6807 	if (cds_get_conparam() == QDF_GLOBAL_MONITOR_MODE) {
6808 		hdd_set_mon_ops(dev);
6809 	} else {
6810 		dev->netdev_ops = &wlan_drv_ops;
6811 		dev->ethtool_ops = &wlan_ethtool_ops;
6812 	}
6813 }
6814 #else
6815 void hdd_set_station_ops(struct net_device *dev)
6816 {
6817 	if (cds_get_conparam() == QDF_GLOBAL_MONITOR_MODE)
6818 		hdd_set_mon_ops(dev);
6819 	else
6820 		dev->netdev_ops = &wlan_drv_ops;
6821 }
6822 
6823 #endif
6824 #else
6825 #ifdef WLAN_FEATURE_TSF_PTP
6826 void hdd_set_station_ops(struct net_device *dev)
6827 {
6828 	dev->netdev_ops = &wlan_drv_ops;
6829 	dev->ethtool_ops = &wlan_ethtool_ops;
6830 }
6831 #else
6832 void hdd_set_station_ops(struct net_device *dev)
6833 {
6834 	dev->netdev_ops = &wlan_drv_ops;
6835 }
6836 #endif
6837 static void hdd_set_mon_ops(struct net_device *dev)
6838 {
6839 }
6840 #endif
6841 
6842 #ifdef WLAN_FEATURE_PKT_CAPTURE
6843 /* Packet Capture mode net_device_ops, does not Tx and most of operations. */
6844 static const struct net_device_ops wlan_pktcapture_drv_ops = {
6845 	.ndo_open = hdd_pktcapture_open,
6846 	.ndo_stop = hdd_stop,
6847 	.ndo_get_stats = hdd_get_stats,
6848 };
6849 
6850 static void hdd_set_pktcapture_ops(struct net_device *dev)
6851 {
6852 	dev->netdev_ops = &wlan_pktcapture_drv_ops;
6853 }
6854 #else
6855 static void hdd_set_pktcapture_ops(struct net_device *dev)
6856 {
6857 }
6858 #endif
6859 
6860 #ifdef MULTI_CLIENT_LL_SUPPORT
6861 /**
6862  * hdd_set_multi_client_ll_support() - set multi client ll support flag in
6863  * allocated station hdd adapter
6864  * @adapter: pointer to hdd adapter
6865  *
6866  * Return: none
6867  */
6868 static void hdd_set_multi_client_ll_support(struct hdd_adapter *adapter)
6869 {
6870 	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
6871 	bool multi_client_ll_ini_support, multi_client_ll_caps;
6872 
6873 	ucfg_mlme_cfg_get_multi_client_ll_ini_support(hdd_ctx->psoc,
6874 						&multi_client_ll_ini_support);
6875 	multi_client_ll_caps =
6876 		ucfg_mlme_get_wlm_multi_client_ll_caps(hdd_ctx->psoc);
6877 
6878 	hdd_debug("fw caps: %d, ini: %d", multi_client_ll_caps,
6879 		  multi_client_ll_ini_support);
6880 	if (multi_client_ll_caps && multi_client_ll_ini_support)
6881 		adapter->multi_client_ll_support = true;
6882 }
6883 #else
6884 static inline void
6885 hdd_set_multi_client_ll_support(struct hdd_adapter *adapter)
6886 {
6887 }
6888 #endif
6889 
6890 /**
6891  * hdd_alloc_station_adapter() - allocate the station hdd adapter
6892  * @hdd_ctx: global hdd context
6893  * @mac_addr: mac address to assign to the interface
6894  * @name_assign_type: name assignment type
6895  * @name: User-visible name of the interface
6896  * @session_type: interface type to be created
6897  *
6898  * hdd adapter pointer would point to the netdev->priv space, this function
6899  * would retrieve the pointer, and setup the hdd adapter configuration.
6900  *
6901  * Return: the pointer to hdd adapter, otherwise NULL
6902  */
6903 static struct hdd_adapter *
6904 hdd_alloc_station_adapter(struct hdd_context *hdd_ctx, tSirMacAddr mac_addr,
6905 			  unsigned char name_assign_type, const char *name,
6906 			  uint8_t session_type)
6907 {
6908 	struct net_device *dev;
6909 	struct hdd_adapter *adapter;
6910 	QDF_STATUS qdf_status;
6911 	uint8_t latency_level;
6912 
6913 	/* cfg80211 initialization and registration */
6914 	dev = alloc_netdev_mqs(sizeof(*adapter), name,
6915 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
6916 			      name_assign_type,
6917 #endif
6918 			      ((cds_get_conparam() == QDF_GLOBAL_MONITOR_MODE ||
6919 			       wlan_hdd_is_session_type_monitor(session_type)) ?
6920 			       hdd_mon_mode_ether_setup : ether_setup),
6921 			      NUM_TX_QUEUES, NUM_RX_QUEUES);
6922 
6923 	if (!dev) {
6924 		hdd_err("Failed to allocate new net_device '%s'", name);
6925 		return NULL;
6926 	}
6927 
6928 	adapter = netdev_priv(dev);
6929 
6930 	qdf_mem_zero(adapter, sizeof(*adapter));
6931 	adapter->dev = dev;
6932 	adapter->deflink = &adapter->link_info[WLAN_HDD_DEFLINK_IDX];
6933 	adapter->hdd_ctx = hdd_ctx;
6934 	adapter->magic = WLAN_HDD_ADAPTER_MAGIC;
6935 	qdf_atomic_set_bit(WLAN_HDD_DEFLINK_IDX, &adapter->active_links);
6936 
6937 	qdf_status = hdd_monitor_mode_qdf_create_event(adapter, session_type);
6938 	if (QDF_IS_STATUS_ERROR(qdf_status)) {
6939 		hdd_err_rl("create monitor mode vdve up event failed");
6940 		goto free_net_dev;
6941 	}
6942 
6943 	hdd_update_dynamic_tsf_sync(adapter);
6944 	adapter->is_link_up_service_needed = false;
6945 	adapter->send_mode_change = true;
6946 
6947 	/* Cache station count initialize to zero */
6948 	qdf_atomic_init(&adapter->cache_sta_count);
6949 
6950 	/* Init the net_device structure */
6951 	strlcpy(dev->name, name, IFNAMSIZ);
6952 
6953 	qdf_net_update_net_device_dev_addr(dev, mac_addr, sizeof(tSirMacAddr));
6954 	qdf_mem_copy(adapter->mac_addr.bytes, mac_addr, sizeof(tSirMacAddr));
6955 	dev->watchdog_timeo = HDD_TX_TIMEOUT;
6956 
6957 	if (wlan_hdd_is_session_type_monitor(session_type)) {
6958 		if (ucfg_pkt_capture_get_mode(hdd_ctx->psoc) !=
6959 						PACKET_CAPTURE_MODE_DISABLE)
6960 			hdd_set_pktcapture_ops(adapter->dev);
6961 		if (ucfg_mlme_is_sta_mon_conc_supported(hdd_ctx->psoc) ||
6962 		    ucfg_dp_is_local_pkt_capture_enabled(hdd_ctx->psoc))
6963 			hdd_set_mon_ops(adapter->dev);
6964 	} else {
6965 		hdd_set_station_ops(adapter->dev);
6966 	}
6967 
6968 	hdd_dev_setup_destructor(dev);
6969 	dev->ieee80211_ptr = &adapter->wdev;
6970 	dev->tx_queue_len = HDD_NETDEV_TX_QUEUE_LEN;
6971 	adapter->wdev.wiphy = hdd_ctx->wiphy;
6972 	adapter->wdev.netdev = dev;
6973 	qdf_status = ucfg_mlme_cfg_get_wlm_level(hdd_ctx->psoc, &latency_level);
6974 	if (QDF_IS_STATUS_ERROR(qdf_status)) {
6975 		hdd_debug("Can't get latency level");
6976 		latency_level =
6977 			QCA_WLAN_VENDOR_ATTR_CONFIG_LATENCY_LEVEL_NORMAL;
6978 	}
6979 	adapter->latency_level = latency_level;
6980 	hdd_set_multi_client_ll_support(adapter);
6981 
6982 	/* set dev's parent to underlying device */
6983 	SET_NETDEV_DEV(dev, hdd_ctx->parent_dev);
6984 	spin_lock_init(&adapter->pause_map_lock);
6985 	adapter->start_time = qdf_system_ticks();
6986 	adapter->last_time = adapter->start_time;
6987 
6988 	qdf_atomic_init(&adapter->is_ll_stats_req_pending);
6989 	hdd_init_get_sta_in_ll_stats_config(adapter);
6990 	hdd_init_link_state_config(adapter);
6991 
6992 	return adapter;
6993 
6994 free_net_dev:
6995 	free_netdev(adapter->dev);
6996 
6997 	return NULL;
6998 }
6999 
7000 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 12, 0) || \
7001 	(defined CFG80211_CHANGE_NETDEV_REGISTRATION_SEMANTICS))
7002 static int
7003 hdd_register_netdevice(struct hdd_adapter *adapter, struct net_device *dev,
7004 		       struct hdd_adapter_create_param *params)
7005 {
7006 	int ret;
7007 
7008 	if (params->is_add_virtual_iface)
7009 		ret = wlan_cfg80211_register_netdevice(dev);
7010 	else
7011 		ret = register_netdevice(dev);
7012 
7013 	return ret;
7014 }
7015 #else
7016 static int
7017 hdd_register_netdevice(struct hdd_adapter *adapter, struct net_device *dev,
7018 		       struct hdd_adapter_create_param *params)
7019 {
7020 	return register_netdevice(dev);
7021 }
7022 #endif
7023 
7024 static QDF_STATUS
7025 hdd_register_interface(struct hdd_adapter *adapter, bool rtnl_held,
7026 		       struct hdd_adapter_create_param *params)
7027 {
7028 	struct net_device *dev = adapter->dev;
7029 	int ret;
7030 
7031 	hdd_enter();
7032 
7033 	if (rtnl_held) {
7034 		if (strnchr(dev->name, IFNAMSIZ - 1, '%')) {
7035 
7036 			ret = dev_alloc_name(dev, dev->name);
7037 			if (ret < 0) {
7038 				hdd_err(
7039 				    "unable to get dev name: %s, err = 0x%x",
7040 				    dev->name, ret);
7041 				return QDF_STATUS_E_FAILURE;
7042 			}
7043 		}
7044 		hdd_debug("hdd_register_netdevice(%s) type:%d", dev->name,
7045 			  adapter->device_mode);
7046 		ret = hdd_register_netdevice(adapter, dev, params);
7047 		if (ret) {
7048 			hdd_err("register_netdevice(%s) failed, err = 0x%x",
7049 				dev->name, ret);
7050 			return QDF_STATUS_E_FAILURE;
7051 		}
7052 	} else {
7053 		hdd_debug("register_netdev(%s) type:%d", dev->name,
7054 			  adapter->device_mode);
7055 		ret = register_netdev(dev);
7056 		if (ret) {
7057 			hdd_err("register_netdev(%s) failed, err = 0x%x",
7058 				dev->name, ret);
7059 			return QDF_STATUS_E_FAILURE;
7060 		}
7061 	}
7062 	set_bit(NET_DEVICE_REGISTERED, &adapter->event_flags);
7063 
7064 	hdd_exit();
7065 
7066 	return QDF_STATUS_SUCCESS;
7067 }
7068 
7069 QDF_STATUS hdd_sme_close_session_callback(uint8_t vdev_id)
7070 {
7071 	struct hdd_adapter *adapter;
7072 	struct hdd_context *hdd_ctx;
7073 	struct wlan_hdd_link_info *link_info;
7074 
7075 	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
7076 	if (!hdd_ctx)
7077 		return QDF_STATUS_E_FAILURE;
7078 
7079 	link_info = hdd_get_link_info_by_vdev(hdd_ctx, vdev_id);
7080 	if (!link_info) {
7081 		hdd_err("Invalid vdev %d", vdev_id);
7082 		return QDF_STATUS_E_INVAL;
7083 	}
7084 
7085 	adapter = link_info->adapter;
7086 	if (WLAN_HDD_ADAPTER_MAGIC != adapter->magic) {
7087 		hdd_err("Invalid magic");
7088 		return QDF_STATUS_NOT_INITIALIZED;
7089 	}
7090 
7091 	clear_bit(SME_SESSION_OPENED, &link_info->link_flags);
7092 	qdf_spin_lock_bh(&link_info->vdev_lock);
7093 	link_info->vdev_id = WLAN_UMAC_VDEV_ID_MAX;
7094 	qdf_spin_unlock_bh(&link_info->vdev_lock);
7095 
7096 	/*
7097 	 * We can be blocked while waiting for scheduled work to be
7098 	 * flushed, and the adapter structure can potentially be freed, in
7099 	 * which case the magic will have been reset.  So make sure the
7100 	 * magic is still good, and hence the adapter structure is still
7101 	 * valid, before signaling completion
7102 	 */
7103 	if (WLAN_HDD_ADAPTER_MAGIC == adapter->magic)
7104 		complete(&link_info->vdev_destroy_event);
7105 
7106 	return QDF_STATUS_SUCCESS;
7107 }
7108 
7109 int hdd_vdev_ready(struct wlan_objmgr_vdev *vdev,
7110 		   struct qdf_mac_addr *bridgeaddr)
7111 {
7112 	QDF_STATUS status;
7113 
7114 	status = pmo_vdev_ready(vdev, bridgeaddr);
7115 	if (QDF_IS_STATUS_ERROR(status))
7116 		return qdf_status_to_os_return(status);
7117 
7118 	status = ucfg_reg_11d_vdev_created_update(vdev);
7119 	if (QDF_IS_STATUS_ERROR(status))
7120 		return qdf_status_to_os_return(status);
7121 
7122 	if (wma_capability_enhanced_mcast_filter())
7123 		status = ucfg_pmo_enhanced_mc_filter_enable(vdev);
7124 	else
7125 		status = ucfg_pmo_enhanced_mc_filter_disable(vdev);
7126 
7127 	return qdf_status_to_os_return(status);
7128 }
7129 
7130 /**
7131  * hdd_check_wait_for_hw_mode_completion - Check hw mode in progress
7132  * @hdd_ctx: hdd context
7133  *
7134  * Check and wait for hw mode response if any hw mode change is
7135  * in progress. Vdev delete will purge the serialization queue
7136  * for the vdev. It will cause issues when the fw event coming
7137  * up later and no active hw mode change req ser command in queue.
7138  *
7139  * Return void
7140  */
7141 static void hdd_check_wait_for_hw_mode_completion(struct hdd_context *hdd_ctx)
7142 {
7143 	QDF_STATUS status;
7144 
7145 	if (!wlan_hdd_validate_context(hdd_ctx) &&
7146 	    policy_mgr_is_hw_mode_change_in_progress(
7147 		hdd_ctx->psoc)) {
7148 		status = policy_mgr_wait_for_connection_update(
7149 			hdd_ctx->psoc);
7150 		if (!QDF_IS_STATUS_SUCCESS(status)) {
7151 			hdd_nofl_debug("qdf wait for hw mode event failed!!");
7152 		}
7153 	}
7154 }
7155 
7156 static void hdd_stop_last_active_connection(struct hdd_context *hdd_ctx,
7157 					    struct wlan_objmgr_vdev *vdev)
7158 {
7159 	enum policy_mgr_con_mode mode;
7160 	struct wlan_objmgr_psoc *psoc;
7161 	enum QDF_OPMODE op_mode;
7162 
7163 	/* If this is the last active connection check
7164 	 * and stop the opportunistic timer.
7165 	 */
7166 	psoc = wlan_vdev_get_psoc(vdev);
7167 	op_mode = wlan_vdev_mlme_get_opmode(vdev);
7168 	mode = policy_mgr_qdf_opmode_to_pm_con_mode(psoc, op_mode,
7169 						    wlan_vdev_get_id(vdev));
7170 	if ((policy_mgr_get_connection_count(psoc) == 1 &&
7171 	     policy_mgr_mode_specific_connection_count(psoc,
7172 						       mode, NULL) == 1) ||
7173 	     (!policy_mgr_get_connection_count(psoc) &&
7174 	     !hdd_is_any_sta_connecting(hdd_ctx))) {
7175 		policy_mgr_check_and_stop_opportunistic_timer(
7176 						psoc,
7177 						wlan_vdev_get_id(vdev));
7178 	}
7179 }
7180 
7181 static int hdd_vdev_destroy_event_wait(struct hdd_context *hdd_ctx,
7182 				       struct wlan_objmgr_vdev *vdev)
7183 {
7184 	long rc;
7185 	QDF_STATUS status;
7186 	uint8_t vdev_id;
7187 	struct wlan_hdd_link_info *link_info;
7188 	struct qdf_mac_addr *mld_addr;
7189 	struct wlan_objmgr_psoc *psoc = NULL;
7190 
7191 	vdev_id = wlan_vdev_get_id(vdev);
7192 	link_info = hdd_get_link_info_by_vdev(hdd_ctx, vdev_id);
7193 	if (!link_info) {
7194 		hdd_err("Invalid vdev");
7195 		return -EINVAL;
7196 	}
7197 
7198 	psoc = wlan_vdev_get_psoc(vdev);
7199 	if (!psoc) {
7200 		obj_mgr_err("Failed to get psoc");
7201 		return QDF_STATUS_E_FAILURE;
7202 	}
7203 
7204 	/* Detach DP vdev from DP MLO Device Context */
7205 	mld_addr = (struct qdf_mac_addr *)wlan_vdev_mlme_get_mldaddr(vdev);
7206 
7207 	if (!qdf_is_macaddr_zero(mld_addr)) {
7208 		/* only for MLO vdev's */
7209 
7210 		if (cdp_mlo_dev_ctxt_detach(wlan_psoc_get_dp_handle(psoc),
7211 					    wlan_vdev_get_id(vdev),
7212 					    (uint8_t *)mld_addr)
7213 					    != QDF_STATUS_SUCCESS) {
7214 			obj_mgr_err("Failed to detach DP vdev from DP MLO Dev ctxt");
7215 			QDF_BUG(0);
7216 			return QDF_STATUS_E_FAILURE;
7217 		}
7218 	}
7219 
7220 	/* close sme session (destroy vdev in firmware via legacy API) */
7221 	INIT_COMPLETION(link_info->vdev_destroy_event);
7222 	status = sme_vdev_delete(hdd_ctx->mac_handle, vdev);
7223 	if (QDF_IS_STATUS_ERROR(status)) {
7224 		hdd_err("vdev %d: failed to delete with status:%d",
7225 			vdev_id, status);
7226 		return -EAGAIN;
7227 	}
7228 
7229 	/* block on a completion variable until sme session is closed */
7230 	rc = wait_for_completion_timeout(
7231 			&link_info->vdev_destroy_event,
7232 			msecs_to_jiffies(SME_CMD_VDEV_CREATE_DELETE_TIMEOUT));
7233 	if (!rc) {
7234 		hdd_err("vdev %d: timed out waiting for delete", vdev_id);
7235 		clear_bit(SME_SESSION_OPENED, &link_info->link_flags);
7236 		sme_cleanup_session(hdd_ctx->mac_handle, vdev_id);
7237 		cds_flush_logs(WLAN_LOG_TYPE_FATAL,
7238 			       WLAN_LOG_INDICATOR_HOST_DRIVER,
7239 			       WLAN_LOG_REASON_VDEV_DELETE_RSP_TIMED_OUT,
7240 			       true, true);
7241 		return -EINVAL;
7242 	}
7243 
7244 	hdd_nofl_info("vdev %d destroyed successfully", vdev_id);
7245 	return 0;
7246 }
7247 
7248 static inline
7249 void hdd_vdev_deinit_components(struct wlan_objmgr_vdev *vdev)
7250 {
7251 	ucfg_pmo_del_wow_pattern(vdev);
7252 	ucfg_son_disable_cbs(vdev);
7253 }
7254 
7255 static inline
7256 void hdd_reset_vdev_info(struct wlan_hdd_link_info *link_info)
7257 {
7258 	qdf_spin_lock_bh(&link_info->vdev_lock);
7259 	link_info->vdev = NULL;
7260 	qdf_spin_unlock_bh(&link_info->vdev_lock);
7261 }
7262 
7263 int hdd_vdev_destroy(struct wlan_hdd_link_info *link_info)
7264 {
7265 	int ret;
7266 	uint8_t vdev_id;
7267 	struct hdd_context *hdd_ctx;
7268 	struct wlan_objmgr_vdev *vdev;
7269 	struct wlan_objmgr_psoc *psoc;
7270 	enum QDF_OPMODE op_mode;
7271 
7272 	vdev_id = link_info->vdev_id;
7273 	hdd_nofl_debug("destroying vdev %d", vdev_id);
7274 	/* vdev created sanity check */
7275 	if (!test_bit(SME_SESSION_OPENED, &link_info->link_flags)) {
7276 		hdd_nofl_debug("vdev %u does not exist", vdev_id);
7277 		return -EINVAL;
7278 	}
7279 
7280 	hdd_ctx = WLAN_HDD_GET_CTX(link_info->adapter);
7281 
7282 	vdev = hdd_objmgr_get_vdev_by_user(link_info, WLAN_OSIF_ID);
7283 	if (!vdev)
7284 		return -EINVAL;
7285 
7286 	psoc = wlan_vdev_get_psoc(vdev);
7287 	if (!psoc) {
7288 		hdd_err("invalid psoc");
7289 		return -EINVAL;
7290 	}
7291 	op_mode = wlan_vdev_mlme_get_opmode(vdev);
7292 
7293 	hdd_stop_last_active_connection(hdd_ctx, vdev);
7294 	hdd_check_wait_for_hw_mode_completion(hdd_ctx);
7295 	ucfg_scan_vdev_set_disable(vdev, REASON_VDEV_DOWN);
7296 	wlan_hdd_scan_abort(link_info);
7297 	hdd_vdev_deinit_components(vdev);
7298 	hdd_mlo_t2lm_unregister_callback(vdev);
7299 	hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_ID);
7300 
7301 	hdd_reset_vdev_info(link_info);
7302 	osif_cm_osif_priv_deinit(vdev);
7303 
7304 	/* Release the hdd reference */
7305 	wlan_objmgr_vdev_release_ref(vdev, WLAN_HDD_ID_OBJ_MGR);
7306 
7307 	/* Get runtime lock to prevent runtime suspend */
7308 	qdf_runtime_pm_prevent_suspend(&hdd_ctx->runtime_context.vdev_destroy);
7309 
7310 	ret = hdd_vdev_destroy_event_wait(hdd_ctx, vdev);
7311 
7312 	ucfg_reg_11d_vdev_delete_update(psoc, op_mode, vdev_id);
7313 
7314 	qdf_runtime_pm_allow_suspend(&hdd_ctx->runtime_context.vdev_destroy);
7315 	return ret;
7316 }
7317 
7318 void
7319 hdd_store_nss_chains_cfg_in_vdev(struct hdd_context *hdd_ctx,
7320 				 struct wlan_objmgr_vdev *vdev)
7321 {
7322 	struct wlan_mlme_nss_chains vdev_ini_cfg;
7323 
7324 	/* Populate the nss chain params from ini for this vdev type */
7325 	sme_populate_nss_chain_params(hdd_ctx->mac_handle, &vdev_ini_cfg,
7326 				      wlan_vdev_mlme_get_opmode(vdev),
7327 				      hdd_ctx->num_rf_chains);
7328 
7329 	/* Store the nss chain config into the vdev */
7330 	sme_store_nss_chains_cfg_in_vdev(vdev, &vdev_ini_cfg);
7331 }
7332 
7333 bool hdd_is_vdev_in_conn_state(struct wlan_hdd_link_info *link_info)
7334 {
7335 	switch (link_info->adapter->device_mode) {
7336 	case QDF_STA_MODE:
7337 	case QDF_P2P_CLIENT_MODE:
7338 	case QDF_P2P_DEVICE_MODE:
7339 		return hdd_cm_is_vdev_associated(link_info);
7340 	case QDF_SAP_MODE:
7341 	case QDF_P2P_GO_MODE:
7342 		return (test_bit(SOFTAP_BSS_STARTED,
7343 				 &link_info->link_flags));
7344 	default:
7345 		hdd_err("Device mode %d invalid",
7346 			link_info->adapter->device_mode);
7347 		return 0;
7348 	}
7349 }
7350 
7351 #define MAX_VDEV_RTT_PARAMS 2
7352 /* params being sent:
7353  * wmi_vdev_param_enable_disable_rtt_responder_role
7354  * wmi_vdev_param_enable_disable_rtt_initiator_role
7355  */
7356 static QDF_STATUS
7357 hdd_vdev_configure_rtt_params(struct wlan_objmgr_vdev *vdev)
7358 {
7359 	QDF_STATUS status;
7360 	struct wlan_objmgr_psoc *psoc;
7361 	uint32_t fine_time_meas_cap = 0;
7362 	uint8_t vdev_id = wlan_vdev_get_id(vdev);
7363 	struct dev_set_param vdevsetparam[MAX_VDEV_RTT_PARAMS] = {};
7364 	uint8_t index = 0;
7365 	WMI_FW_SUB_FEAT_CAPS wmi_fw_rtt_respr, wmi_fw_rtt_initr;
7366 
7367 	switch (wlan_vdev_mlme_get_opmode(vdev)) {
7368 	case QDF_STA_MODE:
7369 		wmi_fw_rtt_respr = WMI_FW_STA_RTT_RESPR;
7370 		wmi_fw_rtt_initr = WMI_FW_STA_RTT_INITR;
7371 		break;
7372 	case QDF_SAP_MODE:
7373 		wmi_fw_rtt_respr = WMI_FW_AP_RTT_RESPR;
7374 		wmi_fw_rtt_initr = WMI_FW_AP_RTT_INITR;
7375 		break;
7376 	default:
7377 		return QDF_STATUS_SUCCESS;
7378 	}
7379 
7380 	psoc = wlan_vdev_get_psoc(vdev);
7381 
7382 	ucfg_mlme_get_fine_time_meas_cap(psoc, &fine_time_meas_cap);
7383 	status = mlme_check_index_setparam(
7384 			vdevsetparam,
7385 			wmi_vdev_param_enable_disable_rtt_responder_role,
7386 			(fine_time_meas_cap & wmi_fw_rtt_respr), index++,
7387 			MAX_VDEV_RTT_PARAMS);
7388 	if (QDF_IS_STATUS_ERROR(status))
7389 		return status;
7390 
7391 	status = mlme_check_index_setparam(
7392 			vdevsetparam,
7393 			wmi_vdev_param_enable_disable_rtt_initiator_role,
7394 			(fine_time_meas_cap & wmi_fw_rtt_initr), index++,
7395 			MAX_VDEV_RTT_PARAMS);
7396 	if (QDF_IS_STATUS_ERROR(status))
7397 		return status;
7398 
7399 	status = sme_send_multi_pdev_vdev_set_params(MLME_VDEV_SETPARAM,
7400 						     vdev_id, vdevsetparam,
7401 						     index);
7402 	if (QDF_IS_STATUS_ERROR(status))
7403 		hdd_err("failed to set RTT_RESPONDER,INITIATOR params:%d",
7404 			status);
7405 
7406 	return status;
7407 }
7408 
7409 static void hdd_store_vdev_info(struct wlan_hdd_link_info *link_info,
7410 				struct wlan_objmgr_vdev *vdev)
7411 {
7412 	struct vdev_osif_priv *osif_priv;
7413 
7414 	osif_priv = wlan_vdev_get_ospriv(vdev);
7415 	if (osif_priv) {
7416 		osif_priv->wdev = link_info->adapter->dev->ieee80211_ptr;
7417 		osif_priv->legacy_osif_priv = link_info;
7418 	}
7419 
7420 	qdf_spin_lock_bh(&link_info->vdev_lock);
7421 	link_info->vdev_id = wlan_vdev_get_id(vdev);
7422 	link_info->vdev = vdev;
7423 	qdf_spin_unlock_bh(&link_info->vdev_lock);
7424 }
7425 
7426 static void
7427 hdd_init_station_context(struct wlan_hdd_link_info *link_info)
7428 {
7429 	struct hdd_station_ctx *sta_ctx;
7430 	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(link_info->adapter);
7431 
7432 	/* Set the default operation channel freq and auth type to open */
7433 	sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(link_info);
7434 	sta_ctx->conn_info.chan_freq = hdd_ctx->config->operating_chan_freq;
7435 	sta_ctx->conn_info.auth_type = eCSR_AUTH_TYPE_OPEN_SYSTEM;
7436 	hdd_roam_profile_init(link_info);
7437 }
7438 
7439 static void hdd_vdev_set_ht_vht_ies(mac_handle_t mac_handle,
7440 				    struct wlan_objmgr_vdev *vdev)
7441 {
7442 	QDF_STATUS status;
7443 	struct wlan_objmgr_psoc *psoc;
7444 	bool bval = false;
7445 
7446 	psoc = wlan_vdev_get_psoc(vdev);
7447 	status = ucfg_mlme_get_vht_enable2x2(psoc, &bval);
7448 	if (QDF_IS_STATUS_ERROR(status))
7449 		hdd_err("unable to get vht_enable2x2");
7450 
7451 	sme_set_pdev_ht_vht_ies(mac_handle, bval);
7452 	sme_set_vdev_ies_per_band(mac_handle, wlan_vdev_get_id(vdev),
7453 				  wlan_vdev_mlme_get_opmode(vdev));
7454 }
7455 
7456 static void
7457 hdd_vdev_configure_rtt_mac_randomization(struct wlan_objmgr_psoc *psoc,
7458 					 struct wlan_objmgr_vdev *vdev)
7459 {
7460 	int errno;
7461 	QDF_STATUS status;
7462 	bool bval = false;
7463 
7464 	status = ucfg_mlme_get_rtt_mac_randomization(psoc, &bval);
7465 	if (QDF_IS_STATUS_ERROR(status))
7466 		hdd_err("unable to get RTT MAC randomization value");
7467 
7468 	hdd_debug("setting RTT mac randomization param: %d", bval);
7469 	errno = sme_cli_set_command(
7470 			wlan_vdev_get_id(vdev),
7471 			wmi_vdev_param_enable_disable_rtt_initiator_random_mac,
7472 			bval, VDEV_CMD);
7473 
7474 	if (errno)
7475 		hdd_err("RTT mac randomization param set failed %d", errno);
7476 }
7477 
7478 static void
7479 hdd_vdev_configure_max_tdls_params(struct wlan_objmgr_psoc *psoc,
7480 				   struct wlan_objmgr_vdev *vdev)
7481 {
7482 	uint16_t max_peer_count;
7483 	bool target_bigtk_support = false;
7484 
7485 	/*
7486 	 * Max peer can be tdls peers + self peer + bss peer +
7487 	 * temp bss peer for roaming create/delete peer at same time
7488 	 */
7489 	max_peer_count = cfg_tdls_get_max_peer_count(psoc);
7490 	max_peer_count += 3;
7491 	wlan_vdev_set_max_peer_count(vdev, max_peer_count);
7492 
7493 	ucfg_mlme_get_bigtk_support(psoc, &target_bigtk_support);
7494 	if (target_bigtk_support)
7495 		mlme_set_bigtk_support(vdev, true);
7496 }
7497 
7498 static inline void
7499 hdd_vdev_configure_nan_params(struct wlan_objmgr_psoc *psoc,
7500 			      struct wlan_objmgr_vdev *vdev)
7501 {
7502 	sme_cli_set_command(
7503 		wlan_vdev_get_id(vdev),
7504 		wmi_vdev_param_allow_nan_initial_discovery_of_mp0_cluster,
7505 		cfg_nan_get_support_mp0_discovery(psoc), VDEV_CMD);
7506 }
7507 
7508 #if defined(WLAN_FEATURE_11BE_MLO) && defined(WLAN_EXTERNAL_AUTH_MLO_SUPPORT)
7509 static void
7510 hdd_set_vdev_mlo_external_sae_auth_conversion(struct wlan_objmgr_vdev *vdev,
7511 					      enum QDF_OPMODE mode)
7512 {
7513 	if (mode == QDF_STA_MODE || mode == QDF_SAP_MODE)
7514 		wlan_vdev_set_mlo_external_sae_auth_conversion(vdev, true);
7515 }
7516 #else
7517 static inline void
7518 hdd_set_vdev_mlo_external_sae_auth_conversion(struct wlan_objmgr_vdev *vdev,
7519 					      enum QDF_OPMODE mode)
7520 {
7521 }
7522 #endif
7523 
7524 static void
7525 hdd_vdev_configure_rtscts_enable(struct hdd_context *hdd_ctx,
7526 				 struct wlan_objmgr_vdev *vdev)
7527 {
7528 	int ret;
7529 	QDF_STATUS status;
7530 	uint16_t rts_profile = 0;
7531 
7532 	if (cds_get_conparam() == QDF_GLOBAL_FTM_MODE)
7533 		return;
7534 
7535 	status = ucfg_fwol_get_rts_profile(hdd_ctx->psoc, &rts_profile);
7536 	if (QDF_IS_STATUS_ERROR(status)) {
7537 		hdd_err("FAILED TO GET RTSCTS Profile status:%d", status);
7538 		return;
7539 	}
7540 
7541 	ret = sme_cli_set_command(wlan_vdev_get_id(vdev),
7542 				  wmi_vdev_param_enable_rtscts,
7543 				  rts_profile,
7544 				  VDEV_CMD);
7545 	if (ret)
7546 		hdd_err("FAILED TO SET RTSCTS Profile ret:%d", ret);
7547 }
7548 
7549 static void
7550 hdd_vdev_configure_usr_ps_params(struct wlan_objmgr_psoc *psoc,
7551 				 struct wlan_objmgr_vdev *vdev,
7552 				 struct wlan_hdd_link_info *link_info)
7553 {
7554 	struct hdd_adapter *adapter = link_info->adapter;
7555 
7556 	if (cds_get_conparam() == QDF_GLOBAL_FTM_MODE || !adapter)
7557 		return;
7558 
7559 	ucfg_mlme_set_user_ps(psoc, wlan_vdev_get_id(vdev),
7560 			      adapter->allow_power_save);
7561 }
7562 
7563 static void
7564 hdd_vdev_configure_opmode_params(struct hdd_context *hdd_ctx,
7565 				 struct wlan_objmgr_vdev *vdev,
7566 				 struct wlan_hdd_link_info *link_info)
7567 {
7568 	struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc;
7569 	enum QDF_OPMODE opmode = wlan_vdev_mlme_get_opmode(vdev);
7570 
7571 	switch (opmode) {
7572 	case QDF_STA_MODE:
7573 		hdd_vdev_configure_rtt_mac_randomization(psoc, vdev);
7574 		hdd_vdev_configure_max_tdls_params(psoc, vdev);
7575 		hdd_vdev_configure_usr_ps_params(psoc, vdev, link_info);
7576 		break;
7577 	case QDF_P2P_CLIENT_MODE:
7578 		hdd_vdev_configure_max_tdls_params(psoc, vdev);
7579 		hdd_vdev_configure_usr_ps_params(psoc, vdev, link_info);
7580 		break;
7581 	case QDF_NAN_DISC_MODE:
7582 		hdd_vdev_configure_nan_params(psoc, vdev);
7583 		break;
7584 	default:
7585 		break;
7586 	}
7587 
7588 	ucfg_fwol_configure_vdev_params(psoc, vdev);
7589 	hdd_set_vdev_mlo_external_sae_auth_conversion(vdev, opmode);
7590 	hdd_store_nss_chains_cfg_in_vdev(hdd_ctx, vdev);
7591 	hdd_vdev_configure_rtscts_enable(hdd_ctx, vdev);
7592 }
7593 
7594 #if defined(WLAN_FEATURE_11BE_MLO) && defined(CFG80211_11BE_BASIC) && \
7595 	defined(WLAN_HDD_MULTI_VDEV_SINGLE_NDEV)
7596 static int
7597 hdd_populate_vdev_create_params(struct wlan_hdd_link_info *link_info,
7598 				struct wlan_vdev_create_params *vdev_params)
7599 {
7600 	struct hdd_adapter *adapter = link_info->adapter;
7601 
7602 	vdev_params->opmode = adapter->device_mode;
7603 	vdev_params->size_vdev_priv = sizeof(struct vdev_osif_priv);
7604 
7605 	if (hdd_adapter_is_ml_adapter(adapter)) {
7606 		qdf_ether_addr_copy(vdev_params->mldaddr,
7607 				    adapter->mac_addr.bytes);
7608 		qdf_ether_addr_copy(vdev_params->macaddr,
7609 				    link_info->link_addr.bytes);
7610 	} else {
7611 		qdf_ether_addr_copy(vdev_params->macaddr,
7612 				    adapter->mac_addr.bytes);
7613 	}
7614 	return 0;
7615 }
7616 #elif defined(WLAN_FEATURE_11BE_MLO) && defined(CFG80211_11BE_BASIC)
7617 static int
7618 hdd_populate_vdev_create_params(struct wlan_hdd_link_info *link_info,
7619 				struct wlan_vdev_create_params *vdev_params)
7620 {
7621 	struct hdd_adapter *adapter = link_info->adapter;
7622 	struct hdd_mlo_adapter_info *mlo_adapter_info;
7623 	struct hdd_adapter *link_adapter;
7624 	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
7625 	bool eht_capab;
7626 
7627 	hdd_enter_dev(adapter->dev);
7628 	mlo_adapter_info = &adapter->mlo_adapter_info;
7629 
7630 	ucfg_psoc_mlme_get_11be_capab(hdd_ctx->psoc, &eht_capab);
7631 	if (mlo_adapter_info->is_ml_adapter && eht_capab &&
7632 	    adapter->device_mode == QDF_STA_MODE) {
7633 		link_adapter = hdd_get_assoc_link_adapter(adapter);
7634 		if (link_adapter) {
7635 			qdf_ether_addr_copy(vdev_params->macaddr,
7636 					    link_adapter->mac_addr.bytes);
7637 		} else {
7638 			return -EINVAL;
7639 		}
7640 	} else {
7641 		qdf_ether_addr_copy(vdev_params->macaddr,
7642 				    adapter->mac_addr.bytes);
7643 	}
7644 
7645 	vdev_params->opmode = adapter->device_mode;
7646 
7647 	if (eht_capab) {
7648 		qdf_ether_addr_copy(vdev_params->mldaddr,
7649 				    adapter->mld_addr.bytes);
7650 	}
7651 
7652 	vdev_params->size_vdev_priv = sizeof(struct vdev_osif_priv);
7653 	hdd_exit();
7654 
7655 	return 0;
7656 }
7657 #else
7658 static int
7659 hdd_populate_vdev_create_params(struct wlan_hdd_link_info *link_info,
7660 				struct wlan_vdev_create_params *vdev_params)
7661 {
7662 	struct hdd_adapter *adapter = link_info->adapter;
7663 
7664 	vdev_params->opmode = adapter->device_mode;
7665 	qdf_ether_addr_copy(vdev_params->macaddr, adapter->mac_addr.bytes);
7666 	vdev_params->size_vdev_priv = sizeof(struct vdev_osif_priv);
7667 	return 0;
7668 }
7669 #endif
7670 
7671 int hdd_vdev_create(struct wlan_hdd_link_info *link_info)
7672 {
7673 	QDF_STATUS status;
7674 	int errno = 0;
7675 	struct hdd_adapter *adapter = link_info->adapter;
7676 	struct hdd_context *hdd_ctx;
7677 	struct wlan_objmgr_vdev *vdev;
7678 	struct wlan_vdev_create_params vdev_params = {0};
7679 
7680 	hdd_nofl_debug("creating new vdev");
7681 
7682 	/* do vdev create via objmgr */
7683 	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
7684 
7685 	errno = hdd_populate_vdev_create_params(link_info, &vdev_params);
7686 	if (errno)
7687 		return errno;
7688 
7689 	vdev = sme_vdev_create(hdd_ctx->mac_handle, &vdev_params);
7690 	if (!vdev) {
7691 		hdd_err("failed to create vdev");
7692 		return -EINVAL;
7693 	}
7694 
7695 	if (wlan_objmgr_vdev_try_get_ref(vdev, WLAN_HDD_ID_OBJ_MGR) !=
7696 	    QDF_STATUS_SUCCESS) {
7697 		errno = QDF_STATUS_E_INVAL;
7698 		sme_vdev_delete(hdd_ctx->mac_handle, vdev);
7699 		return -EINVAL;
7700 	}
7701 
7702 	hdd_store_vdev_info(link_info, vdev);
7703 	osif_cm_osif_priv_init(vdev);
7704 
7705 	if (hdd_adapter_is_ml_adapter(adapter))
7706 		hdd_mlo_t2lm_register_callback(vdev);
7707 
7708 	set_bit(SME_SESSION_OPENED, &link_info->link_flags);
7709 	status = sme_vdev_post_vdev_create_setup(hdd_ctx->mac_handle, vdev);
7710 	if (QDF_IS_STATUS_ERROR(status)) {
7711 		hdd_err("Failed to setup the vdev");
7712 		errno = qdf_status_to_os_return(status);
7713 		goto hdd_vdev_destroy_procedure;
7714 	}
7715 
7716 	/* firmware ready for component communication, raise vdev_ready event */
7717 	errno = hdd_vdev_ready(vdev,
7718 			       (struct qdf_mac_addr *)hdd_ctx->bridgeaddr);
7719 	if (errno) {
7720 		hdd_err("failed to dispatch vdev ready event: %d", errno);
7721 		goto hdd_vdev_destroy_procedure;
7722 	}
7723 
7724 	hdd_vdev_configure_opmode_params(hdd_ctx, vdev, link_info);
7725 
7726 	hdd_nofl_debug("vdev %d created successfully", link_info->vdev_id);
7727 
7728 	return errno;
7729 
7730 hdd_vdev_destroy_procedure:
7731 	QDF_BUG(!hdd_vdev_destroy(link_info));
7732 
7733 	return errno;
7734 }
7735 
7736 QDF_STATUS hdd_init_station_mode(struct wlan_hdd_link_info *link_info)
7737 {
7738 	struct hdd_adapter *adapter = link_info->adapter;
7739 	struct hdd_context *hdd_ctx;
7740 	QDF_STATUS status;
7741 	mac_handle_t mac_handle;
7742 	uint32_t roam_triggers;
7743 	struct wlan_objmgr_vdev *vdev;
7744 
7745 	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
7746 	mac_handle = hdd_ctx->mac_handle;
7747 
7748 	vdev = hdd_objmgr_get_vdev_by_user(link_info, WLAN_INIT_DEINIT_ID);
7749 	if (!vdev) {
7750 		status = QDF_STATUS_E_NULL_VALUE;
7751 		goto vdev_destroy;
7752 	}
7753 
7754 	hdd_vdev_set_ht_vht_ies(mac_handle, vdev);
7755 	hdd_init_station_context(link_info);
7756 
7757 	status = hdd_wmm_adapter_init(adapter);
7758 	if (QDF_STATUS_SUCCESS != status) {
7759 		hdd_err("hdd_wmm_adapter_init() failed, status code %08d [x%08x]",
7760 			status, status);
7761 		goto error_wmm_init;
7762 	}
7763 	set_bit(WMM_INIT_DONE, &adapter->event_flags);
7764 
7765 	/* rcpi info initialization */
7766 	qdf_mem_zero(&adapter->rcpi, sizeof(adapter->rcpi));
7767 
7768 	if (adapter->device_mode == QDF_STA_MODE) {
7769 		roam_triggers = ucfg_mlme_get_roaming_triggers(hdd_ctx->psoc);
7770 		mlme_set_roam_trigger_bitmap(hdd_ctx->psoc,
7771 					     link_info->vdev_id,
7772 					     roam_triggers);
7773 
7774 		status = hdd_vdev_configure_rtt_params(vdev);
7775 		if (QDF_IS_STATUS_ERROR(status))
7776 			goto error_wmm_init;
7777 	}
7778 
7779 	hdd_tsf_auto_report_init(adapter);
7780 	hdd_objmgr_put_vdev_by_user(vdev, WLAN_INIT_DEINIT_ID);
7781 
7782 	return QDF_STATUS_SUCCESS;
7783 
7784 error_wmm_init:
7785 	hdd_objmgr_put_vdev_by_user(vdev, WLAN_INIT_DEINIT_ID);
7786 
7787 vdev_destroy:
7788 	QDF_BUG(!hdd_vdev_destroy(link_info));
7789 
7790 	return status;
7791 }
7792 
7793 static char *net_dev_ref_debug_string_from_id(wlan_net_dev_ref_dbgid dbgid)
7794 {
7795 	static const char *strings[] = {
7796 		"NET_DEV_HOLD_ID_RESERVED",
7797 		"NET_DEV_HOLD_GET_STA_CONNECTION_IN_PROGRESS",
7798 		"NET_DEV_HOLD_CHECK_DFS_CHANNEL_FOR_ADAPTER",
7799 		"NET_DEV_HOLD_GET_SAP_OPERATING_BAND",
7800 		"NET_DEV_HOLD_RECOVERY_NOTIFIER_CALL",
7801 		"NET_DEV_HOLD_IS_ANY_STA_CONNECTING",
7802 		"NET_DEV_HOLD_SAP_DESTROY_CTX_ALL",
7803 		"NET_DEV_HOLD_DRV_CMD_MAX_TX_POWER",
7804 		"NET_DEV_HOLD_IPA_SET_TX_FLOW_INFO",
7805 		"NET_DEV_HOLD_SET_RPS_CPU_MASK",
7806 		"NET_DEV_HOLD_DFS_INDICATE_RADAR",
7807 		"NET_DEV_HOLD_MAX_STA_INTERFACE_UP_COUNT_REACHED",
7808 		"NET_DEV_HOLD_IS_CHAN_SWITCH_IN_PROGRESS",
7809 		"NET_DEV_HOLD_STA_DESTROY_CTX_ALL",
7810 		"NET_DEV_HOLD_CHECK_FOR_EXISTING_MACADDR",
7811 		"NET_DEV_HOLD_DEINIT_ALL_ADAPTERS",
7812 		"NET_DEV_HOLD_STOP_ALL_ADAPTERS",
7813 		"NET_DEV_HOLD_RESET_ALL_ADAPTERS",
7814 		"NET_DEV_HOLD_IS_ANY_INTERFACE_OPEN",
7815 		"NET_DEV_HOLD_START_ALL_ADAPTERS",
7816 		"NET_DEV_HOLD_GET_ADAPTER_BY_RAND_MACADDR",
7817 		"NET_DEV_HOLD_GET_ADAPTER_BY_MACADDR",
7818 		"NET_DEV_HOLD_GET_ADAPTER_BY_VDEV",
7819 		"NET_DEV_HOLD_ADAPTER_GET_BY_REFERENCE",
7820 		"NET_DEV_HOLD_GET_ADAPTER_BY_IFACE_NAME",
7821 		"NET_DEV_HOLD_GET_ADAPTER",
7822 		"NET_DEV_HOLD_GET_OPERATING_CHAN_FREQ",
7823 		"NET_DEV_HOLD_UNREGISTER_WEXT_ALL_ADAPTERS",
7824 		"NET_DEV_HOLD_ABORT_MAC_SCAN_ALL_ADAPTERS",
7825 		"NET_DEV_HOLD_ABORT_SCHED_SCAN_ALL_ADAPTERS",
7826 		"NET_DEV_HOLD_GET_FIRST_VALID_ADAPTER",
7827 		"NET_DEV_HOLD_CLEAR_RPS_CPU_MASK",
7828 		"NET_DEV_HOLD_BUS_BW_WORK_HANDLER",
7829 		"NET_DEV_HOLD_DISPLAY_NETIF_QUEUE_HISTORY_COMPACT",
7830 		"NET_DEV_HOLD_DISPLAY_NETIF_QUEUE_HISTORY",
7831 		"NET_DEV_HOLD_CLEAR_NETIF_QUEUE_HISTORY",
7832 		"NET_DEV_HOLD_UNSAFE_CHANNEL_RESTART_SAP",
7833 		"NET_DEV_HOLD_INDICATE_MGMT_FRAME",
7834 		"NET_DEV_HOLD_STATE_INFO_DUMP",
7835 		"NET_DEV_HOLD_DISABLE_ROAMING",
7836 		"NET_DEV_HOLD_ENABLE_ROAMING",
7837 		"NET_DEV_HOLD_AUTO_SHUTDOWN_ENABLE",
7838 		"NET_DEV_HOLD_GET_CON_SAP_ADAPTER",
7839 		"NET_DEV_HOLD_IS_ANY_ADAPTER_CONNECTED",
7840 		"NET_DEV_HOLD_IS_ROAMING_IN_PROGRESS",
7841 		"NET_DEV_HOLD_DEL_P2P_INTERFACE",
7842 		"NET_DEV_HOLD_IS_NDP_ALLOWED",
7843 		"NET_DEV_HOLD_NDI_OPEN",
7844 		"NET_DEV_HOLD_SEND_OEM_REG_RSP_NLINK_MSG",
7845 		"NET_DEV_HOLD_PERIODIC_STA_STATS_DISPLAY",
7846 		"NET_DEV_HOLD_SUSPEND_WLAN",
7847 		"NET_DEV_HOLD_RESUME_WLAN",
7848 		"NET_DEV_HOLD_SSR_RESTART_SAP",
7849 		"NET_DEV_HOLD_SEND_DEFAULT_SCAN_IES",
7850 		"NET_DEV_HOLD_CFG80211_SUSPEND_WLAN",
7851 		"NET_DEV_HOLD_COUNTRY_CHANGE_UPDATE_STA",
7852 		"NET_DEV_HOLD_COUNTRY_CHANGE_UPDATE_SAP",
7853 		"NET_DEV_HOLD_CACHE_STATION_STATS_CB",
7854 		"NET_DEV_HOLD_DISPLAY_TXRX_STATS",
7855 		"NET_DEV_HOLD_START_PRE_CAC_TRANS",
7856 		"NET_DEV_HOLD_IS_ANY_STA_CONNECTED",
7857 		"NET_DEV_HOLD_GET_ADAPTER_BY_BSSID",
7858 		"NET_DEV_HOLD_ALLOW_NEW_INTF",
7859 		"NET_DEV_HOLD_ID_MAX"};
7860 	int32_t num_dbg_strings = QDF_ARRAY_SIZE(strings);
7861 
7862 	if (dbgid >= num_dbg_strings) {
7863 		char *ret = "";
7864 
7865 		hdd_err("Debug string not found for debug id %d", dbgid);
7866 		return ret;
7867 	}
7868 
7869 	return (char *)strings[dbgid];
7870 }
7871 
7872 void hdd_check_for_net_dev_ref_leak(struct hdd_adapter *adapter)
7873 {
7874 	int i, id;
7875 
7876 	for (id = 0; id < NET_DEV_HOLD_ID_MAX; id++) {
7877 		for (i = 0; i < MAX_NET_DEV_REF_LEAK_ITERATIONS; i++) {
7878 			if (!qdf_atomic_read(
7879 				&adapter->net_dev_hold_ref_count[id]))
7880 				break;
7881 			hdd_info("net_dev held for debug id %s",
7882 				 net_dev_ref_debug_string_from_id(id));
7883 			qdf_sleep(NET_DEV_REF_LEAK_ITERATION_SLEEP_TIME_MS);
7884 		}
7885 		if (i == MAX_NET_DEV_REF_LEAK_ITERATIONS) {
7886 			hdd_err("net_dev hold reference leak detected for debug id: %s",
7887 				net_dev_ref_debug_string_from_id(id));
7888 			QDF_BUG(0);
7889 		}
7890 	}
7891 }
7892 
7893 /**
7894  * hdd_deinit_station_mode() - De-initialize the station adapter
7895  * @adapter: HDD adapter pointer
7896  *
7897  * This function De-initializes the STA/P2P/OCB adapter.
7898  *
7899  * Return: None.
7900  */
7901 static void hdd_deinit_station_mode(struct hdd_adapter *adapter)
7902 {
7903 	if (test_bit(WMM_INIT_DONE, &adapter->event_flags)) {
7904 		hdd_wmm_adapter_close(adapter);
7905 		clear_bit(WMM_INIT_DONE, &adapter->event_flags);
7906 	}
7907 }
7908 
7909 void hdd_deinit_session(struct hdd_adapter *adapter)
7910 {
7911 	struct wlan_hdd_link_info *link_info;
7912 
7913 	hdd_enter();
7914 
7915 	switch (adapter->device_mode) {
7916 	case QDF_STA_MODE:
7917 	case QDF_P2P_CLIENT_MODE:
7918 	case QDF_MONITOR_MODE:
7919 	case QDF_P2P_DEVICE_MODE:
7920 	case QDF_NDI_MODE:
7921 	case QDF_NAN_DISC_MODE:
7922 	{
7923 		hdd_deinit_station_mode(adapter);
7924 		break;
7925 	}
7926 
7927 	case QDF_SAP_MODE:
7928 	case QDF_P2P_GO_MODE:
7929 	{
7930 		hdd_adapter_for_each_active_link_info(adapter, link_info)
7931 			hdd_deinit_ap_mode(link_info);
7932 		break;
7933 	}
7934 
7935 	default:
7936 		break;
7937 	}
7938 
7939 	if (adapter->scan_info.default_scan_ies) {
7940 		qdf_mem_free(adapter->scan_info.default_scan_ies);
7941 		adapter->scan_info.default_scan_ies = NULL;
7942 		adapter->scan_info.default_scan_ies_len = 0;
7943 	}
7944 
7945 	hdd_exit();
7946 }
7947 
7948 void hdd_deinit_adapter(struct hdd_context *hdd_ctx,
7949 			struct hdd_adapter *adapter,
7950 			bool rtnl_held)
7951 {
7952 	hdd_enter_dev(adapter->dev);
7953 
7954 	hdd_wext_unregister(adapter->dev, rtnl_held);
7955 	hdd_deinit_session(adapter);
7956 	hdd_exit();
7957 }
7958 
7959 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0)) && \
7960      defined(WLAN_FEATURE_11AX)
7961 /**
7962  * hdd_cleanup_he_operation_info() - cleanup he operation info
7963  * @link_info: pointer to link_info struct in adapter
7964  *
7965  * This function destroys he operation information
7966  *
7967  * Return: none
7968  */
7969 static void hdd_cleanup_he_operation_info(struct wlan_hdd_link_info *link_info)
7970 {
7971 	struct hdd_station_ctx *hdd_sta_ctx;
7972 
7973 	hdd_debug("cleanup he operation info");
7974 
7975 	hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(link_info);
7976 
7977 	if (hdd_sta_ctx->cache_conn_info.he_operation) {
7978 		qdf_mem_free(hdd_sta_ctx->cache_conn_info.he_operation);
7979 		hdd_sta_ctx->cache_conn_info.he_operation = NULL;
7980 	}
7981 }
7982 #else
7983 static inline void
7984 hdd_cleanup_he_operation_info(struct wlan_hdd_link_info *link_info)
7985 {
7986 }
7987 #endif
7988 
7989 /**
7990  * hdd_cleanup_prev_ap_bcn_ie() - cleanup previous ap beacon ie
7991  * @link_info: pointer to link_info struct in adapter
7992  *
7993  * This function destroys previous ap beacon information
7994  *
7995  * Return: none
7996  */
7997 static void hdd_cleanup_prev_ap_bcn_ie(struct wlan_hdd_link_info *link_info)
7998 {
7999 	struct hdd_station_ctx *hdd_sta_ctx;
8000 	struct element_info *bcn_ie;
8001 
8002 	hdd_debug("cleanup previous ap bcn ie");
8003 
8004 	hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(link_info);
8005 	bcn_ie = &hdd_sta_ctx->conn_info.prev_ap_bcn_ie;
8006 
8007 	if (bcn_ie->ptr) {
8008 		qdf_mem_free(bcn_ie->ptr);
8009 		bcn_ie->ptr = NULL;
8010 		bcn_ie->len = 0;
8011 	}
8012 }
8013 
8014 void hdd_cleanup_conn_info(struct wlan_hdd_link_info *link_info)
8015 {
8016 	hdd_cleanup_he_operation_info(link_info);
8017 	hdd_cleanup_prev_ap_bcn_ie(link_info);
8018 }
8019 
8020 /**
8021  * hdd_sta_destroy_ctx_all() - cleanup all station contexts
8022  * @hdd_ctx: Global HDD context
8023  *
8024  * This function destroys all the station contexts
8025  *
8026  * Return: none
8027  */
8028 static void hdd_sta_destroy_ctx_all(struct hdd_context *hdd_ctx)
8029 {
8030 	struct hdd_adapter *adapter, *next_adapter = NULL;
8031 	struct wlan_hdd_link_info *link_info;
8032 
8033 	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
8034 					   NET_DEV_HOLD_STA_DESTROY_CTX_ALL) {
8035 		if (adapter->device_mode == QDF_STA_MODE) {
8036 			hdd_adapter_for_each_link_info(adapter, link_info) {
8037 				hdd_cleanup_conn_info(link_info);
8038 			}
8039 		}
8040 		hdd_adapter_dev_put_debug(adapter,
8041 					  NET_DEV_HOLD_STA_DESTROY_CTX_ALL);
8042 	}
8043 }
8044 
8045 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 12, 0) || \
8046 	(defined CFG80211_CHANGE_NETDEV_REGISTRATION_SEMANTICS))
8047 static void
8048 hdd_unregister_netdevice(struct hdd_adapter *adapter, struct net_device *dev)
8049 {
8050 	if (adapter->is_virtual_iface) {
8051 		wlan_cfg80211_unregister_netdevice(dev);
8052 		adapter->is_virtual_iface = false;
8053 	} else {
8054 		unregister_netdevice(dev);
8055 	}
8056 }
8057 #else
8058 static void
8059 hdd_unregister_netdevice(struct hdd_adapter *adapter, struct net_device *dev)
8060 {
8061 	unregister_netdevice(dev);
8062 }
8063 #endif
8064 
8065 static inline void hdd_adapter_destroy_vdev_info(struct hdd_adapter *adapter)
8066 {
8067 	struct wlan_hdd_link_info *link_info;
8068 
8069 	hdd_adapter_for_each_link_info(adapter, link_info) {
8070 		qdf_event_destroy(&link_info->acs_complete_event);
8071 		qdf_spinlock_destroy(&link_info->vdev_lock);
8072 	}
8073 }
8074 
8075 static void hdd_cleanup_adapter(struct hdd_context *hdd_ctx,
8076 				struct hdd_adapter *adapter,
8077 				bool rtnl_held)
8078 {
8079 	struct net_device *dev = NULL;
8080 
8081 	if (adapter)
8082 		dev = adapter->dev;
8083 	else {
8084 		hdd_err("adapter is Null");
8085 		return;
8086 	}
8087 
8088 	hdd_apf_context_destroy(adapter);
8089 	qdf_spinlock_destroy(&adapter->mc_list_lock);
8090 	hdd_adapter_destroy_vdev_info(adapter);
8091 	hdd_sta_info_deinit(&adapter->sta_info_list);
8092 	hdd_sta_info_deinit(&adapter->cache_sta_info_list);
8093 
8094 	wlan_hdd_debugfs_csr_deinit(adapter);
8095 
8096 	hdd_debugfs_exit(adapter);
8097 
8098 	/*
8099 	 * The adapter is marked as closed. When hdd_wlan_exit() call returns,
8100 	 * the driver is almost closed and cannot handle either control
8101 	 * messages or data. However, unregister_netdevice() call above will
8102 	 * eventually invoke hdd_stop(ndo_close) driver callback, which attempts
8103 	 * to close the active connections(basically excites control path) which
8104 	 * is not right. Setting this flag helps hdd_stop() to recognize that
8105 	 * the interface is closed and restricts any operations on that
8106 	 */
8107 	clear_bit(DEVICE_IFACE_OPENED, &adapter->event_flags);
8108 
8109 	if (test_bit(NET_DEVICE_REGISTERED, &adapter->event_flags)) {
8110 		if (rtnl_held) {
8111 			hdd_debug("hdd_unregister_netdevice(%s) type:%d",
8112 				  dev->name, adapter->device_mode);
8113 			hdd_unregister_netdevice(adapter, dev);
8114 		} else {
8115 			hdd_debug("unregister_netdev(%s) type:%d", dev->name,
8116 				  adapter->device_mode);
8117 			unregister_netdev(dev);
8118 		}
8119 		/*
8120 		 * Note that the adapter is no longer valid at this point
8121 		 * since the memory has been reclaimed
8122 		 */
8123 	}
8124 }
8125 
8126 static QDF_STATUS hdd_check_for_existing_macaddr(struct hdd_context *hdd_ctx,
8127 						 tSirMacAddr mac_addr)
8128 {
8129 	struct hdd_adapter *adapter, *next_adapter = NULL;
8130 	wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_CHECK_FOR_EXISTING_MACADDR;
8131 
8132 	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
8133 					   dbgid) {
8134 		if (!qdf_mem_cmp(adapter->mac_addr.bytes,
8135 				 mac_addr, sizeof(tSirMacAddr))) {
8136 			hdd_adapter_dev_put_debug(adapter, dbgid);
8137 			if (next_adapter)
8138 				hdd_adapter_dev_put_debug(next_adapter,
8139 							  dbgid);
8140 			return QDF_STATUS_E_FAILURE;
8141 		}
8142 		hdd_adapter_dev_put_debug(adapter, dbgid);
8143 	}
8144 
8145 	return QDF_STATUS_SUCCESS;
8146 }
8147 
8148 /**
8149  * hdd_configure_chain_mask() - programs chain mask to firmware
8150  * @adapter: HDD adapter
8151  *
8152  * Return: 0 on success or errno on failure
8153  */
8154 static int hdd_configure_chain_mask(struct hdd_adapter *adapter)
8155 {
8156 	QDF_STATUS status;
8157 	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
8158 
8159 	status = ucfg_mlme_configure_chain_mask(hdd_ctx->psoc,
8160 						adapter->deflink->vdev_id);
8161 	if (QDF_IS_STATUS_ERROR(status))
8162 		goto error;
8163 
8164 	return 0;
8165 
8166 error:
8167 	hdd_debug("WMI PDEV set param failed");
8168 	return -EINVAL;
8169 }
8170 
8171 void hdd_adapter_update_mlo_mgr_mac_addr(struct hdd_adapter *adapter)
8172 {
8173 	int i = 0;
8174 	struct wlan_hdd_link_info *link_info;
8175 	struct wlan_mlo_link_mac_update link_mac = {0};
8176 
8177 	if (!hdd_adapter_is_ml_adapter(adapter))
8178 		return;
8179 
8180 	hdd_adapter_for_each_link_info(adapter, link_info) {
8181 		link_mac.link_mac_info[i].vdev_id = link_info->vdev_id;
8182 		qdf_copy_macaddr(&link_mac.link_mac_info[i++].link_mac_addr,
8183 				 &link_info->link_addr);
8184 	}
8185 
8186 	link_mac.num_mac_update = i;
8187 	mlo_mgr_update_link_info_mac_addr(adapter->deflink->vdev, &link_mac);
8188 }
8189 
8190 #ifdef FEATURE_COEX
8191 /**
8192  * hdd_send_coex_config_params() - Send coex config params to FW
8193  * @hdd_ctx: HDD context
8194  * @adapter: Primary adapter context
8195  *
8196  * This function is used to send all coex config related params to FW
8197  *
8198  * Return: 0 on success and -EINVAL on failure
8199  */
8200 static int hdd_send_coex_config_params(struct hdd_context *hdd_ctx,
8201 				       struct hdd_adapter *adapter)
8202 {
8203 	struct wlan_objmgr_vdev *vdev;
8204 	struct coex_config_params coex_cfg_params = {0};
8205 	struct coex_multi_config *coex_multi_cfg = NULL;
8206 	struct wlan_fwol_coex_config config = {0};
8207 	struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc;
8208 	enum coex_btc_chain_mode btc_chain_mode;
8209 	QDF_STATUS status;
8210 	uint32_t i = 0;
8211 
8212 	if (!adapter) {
8213 		hdd_err("adapter is invalid");
8214 		goto err;
8215 	}
8216 
8217 	if (!psoc) {
8218 		hdd_err("HDD psoc is invalid");
8219 		goto err;
8220 	}
8221 
8222 	status = ucfg_fwol_get_coex_config_params(psoc, &config);
8223 	if (QDF_IS_STATUS_ERROR(status)) {
8224 		hdd_err("Unable to get coex config params");
8225 		goto err;
8226 	}
8227 
8228 	coex_multi_cfg = qdf_mem_malloc(sizeof(*coex_multi_cfg));
8229 	if (!coex_multi_cfg)
8230 		goto err;
8231 
8232 	coex_multi_cfg->vdev_id = adapter->deflink->vdev_id;
8233 
8234 	coex_multi_cfg->cfg_items[i].config_type = WMI_COEX_CONFIG_TX_POWER;
8235 	coex_multi_cfg->cfg_items[i].config_arg1 = config.max_tx_power_for_btc;
8236 
8237 	wma_nofl_debug("TXP[W][send_coex_cfg]: %d",
8238 		       config.max_tx_power_for_btc);
8239 
8240 	if (++i > COEX_MULTI_CONFIG_MAX_CNT)
8241 		goto err;
8242 
8243 	coex_multi_cfg->cfg_items[i].config_type =
8244 					WMI_COEX_CONFIG_HANDOVER_RSSI;
8245 	coex_multi_cfg->cfg_items[i].config_arg1 =
8246 					config.wlan_low_rssi_threshold;
8247 
8248 	if (++i > COEX_MULTI_CONFIG_MAX_CNT)
8249 		goto err;
8250 
8251 	coex_multi_cfg->cfg_items[i].config_type = WMI_COEX_CONFIG_BTC_MODE;
8252 
8253 	/* Modify BTC_MODE according to BTC_CHAIN_MODE */
8254 	status = ucfg_coex_psoc_get_btc_chain_mode(psoc, &btc_chain_mode);
8255 	if (QDF_IS_STATUS_ERROR(status)) {
8256 		hdd_err("Failed to get btc chain mode");
8257 		btc_chain_mode = WLAN_COEX_BTC_CHAIN_MODE_UNSETTLED;
8258 	}
8259 
8260 	if (btc_chain_mode <= WLAN_COEX_BTC_CHAIN_MODE_HYBRID)
8261 		coex_multi_cfg->cfg_items[i].config_arg1 = btc_chain_mode;
8262 	else
8263 		coex_multi_cfg->cfg_items[i].config_arg1 = config.btc_mode;
8264 
8265 	hdd_debug("Configured BTC mode is %d, BTC chain mode is 0x%x, set BTC mode to %d",
8266 		  config.btc_mode, btc_chain_mode,
8267 		  coex_multi_cfg->cfg_items[i].config_arg1);
8268 
8269 	if (++i > COEX_MULTI_CONFIG_MAX_CNT)
8270 		goto err;
8271 
8272 	coex_multi_cfg->cfg_items[i].config_type =
8273 				WMI_COEX_CONFIG_ANTENNA_ISOLATION;
8274 	coex_multi_cfg->cfg_items[i].config_arg1 = config.antenna_isolation;
8275 	if (++i > COEX_MULTI_CONFIG_MAX_CNT)
8276 		goto err;
8277 
8278 	coex_multi_cfg->cfg_items[i].config_type =
8279 				WMI_COEX_CONFIG_BT_LOW_RSSI_THRESHOLD;
8280 	coex_multi_cfg->cfg_items[i].config_arg1 = config.bt_low_rssi_threshold;
8281 
8282 	if (++i > COEX_MULTI_CONFIG_MAX_CNT)
8283 		goto err;
8284 
8285 	coex_multi_cfg->cfg_items[i].config_type =
8286 				WMI_COEX_CONFIG_BT_INTERFERENCE_LEVEL;
8287 	coex_multi_cfg->cfg_items[i].config_arg1 =
8288 				config.bt_interference_low_ll;
8289 	coex_multi_cfg->cfg_items[i].config_arg2 =
8290 				config.bt_interference_low_ul;
8291 	coex_multi_cfg->cfg_items[i].config_arg3 =
8292 				config.bt_interference_medium_ll;
8293 	coex_multi_cfg->cfg_items[i].config_arg4 =
8294 				config.bt_interference_medium_ul;
8295 	coex_multi_cfg->cfg_items[i].config_arg5 =
8296 				config.bt_interference_high_ll;
8297 	coex_multi_cfg->cfg_items[i].config_arg6 =
8298 				config.bt_interference_high_ul;
8299 
8300 	if (++i > COEX_MULTI_CONFIG_MAX_CNT)
8301 		goto err;
8302 
8303 	if (wlan_hdd_mpta_helper_enable(&coex_cfg_params, &config))
8304 		goto err;
8305 
8306 	coex_multi_cfg->cfg_items[i].config_type =
8307 				WMI_COEX_CONFIG_BT_SCO_ALLOW_WLAN_2G_SCAN;
8308 	coex_multi_cfg->cfg_items[i].config_arg1 =
8309 				config.bt_sco_allow_wlan_2g_scan;
8310 
8311 	if (++i > COEX_MULTI_CONFIG_MAX_CNT)
8312 		goto err;
8313 
8314 	coex_multi_cfg->cfg_items[i].config_type =
8315 				WMI_COEX_CONFIG_LE_SCAN_POLICY;
8316 	coex_multi_cfg->cfg_items[i].config_arg1 = config.ble_scan_coex_policy;
8317 
8318 	if (++i > COEX_MULTI_CONFIG_MAX_CNT)
8319 		goto err;
8320 
8321 #ifdef FEATURE_COEX_TPUT_SHAPING_CONFIG
8322 	coex_multi_cfg->cfg_items[i].config_type =
8323 				WMI_COEX_CONFIG_ENABLE_TPUT_SHAPING;
8324 	coex_multi_cfg->cfg_items[i].config_arg1 =
8325 				config.coex_tput_shaping_enable;
8326 
8327 	if (++i > COEX_MULTI_CONFIG_MAX_CNT)
8328 		goto err;
8329 #endif
8330 
8331 	coex_multi_cfg->num_configs = i;
8332 
8333 	vdev = hdd_objmgr_get_vdev_by_user(adapter->deflink, WLAN_COEX_ID);
8334 	if (!vdev) {
8335 		hdd_err("vdev is null");
8336 		goto err;
8337 	}
8338 
8339 	ucfg_coex_send_multi_config(vdev, coex_multi_cfg);
8340 
8341 	hdd_objmgr_put_vdev_by_user(vdev, WLAN_COEX_ID);
8342 	qdf_mem_free(coex_multi_cfg);
8343 
8344 	return 0;
8345 err:
8346 	qdf_mem_free(coex_multi_cfg);
8347 	return -EINVAL;
8348 }
8349 #else
8350 /**
8351  * hdd_send_coex_config_params() - Send coex config params to FW
8352  * @hdd_ctx: HDD context
8353  * @adapter: Primary adapter context
8354  *
8355  * This function is used to send all coex config related params to FW
8356  *
8357  * Return: 0 on success and -EINVAL on failure
8358  */
8359 static int hdd_send_coex_config_params(struct hdd_context *hdd_ctx,
8360 				       struct hdd_adapter *adapter)
8361 {
8362 	struct coex_config_params coex_cfg_params = {0};
8363 	struct wlan_fwol_coex_config config = {0};
8364 	struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc;
8365 	enum coex_btc_chain_mode btc_chain_mode;
8366 	QDF_STATUS status;
8367 
8368 	if (!adapter) {
8369 		hdd_err("adapter is invalid");
8370 		goto err;
8371 	}
8372 
8373 	if (!psoc) {
8374 		hdd_err("HDD psoc is invalid");
8375 		goto err;
8376 	}
8377 
8378 	status = ucfg_fwol_get_coex_config_params(psoc, &config);
8379 	if (QDF_IS_STATUS_ERROR(status)) {
8380 		hdd_err("Unable to get coex config params");
8381 		goto err;
8382 	}
8383 
8384 	coex_cfg_params.vdev_id = adapter->deflink->vdev_id;
8385 	coex_cfg_params.config_type = WMI_COEX_CONFIG_TX_POWER;
8386 	coex_cfg_params.config_arg1 = config.max_tx_power_for_btc;
8387 
8388 	wma_nofl_debug("TXP[W][send_coex_cfg]: %d",
8389 		       config.max_tx_power_for_btc);
8390 
8391 	status = sme_send_coex_config_cmd(&coex_cfg_params);
8392 	if (QDF_IS_STATUS_ERROR(status)) {
8393 		hdd_err("Failed to send coex Tx power");
8394 		goto err;
8395 	}
8396 
8397 	coex_cfg_params.config_type = WMI_COEX_CONFIG_HANDOVER_RSSI;
8398 	coex_cfg_params.config_arg1 = config.wlan_low_rssi_threshold;
8399 
8400 	status = sme_send_coex_config_cmd(&coex_cfg_params);
8401 	if (QDF_IS_STATUS_ERROR(status)) {
8402 		hdd_err("Failed to send coex handover RSSI");
8403 		goto err;
8404 	}
8405 
8406 	coex_cfg_params.config_type = WMI_COEX_CONFIG_BTC_MODE;
8407 
8408 	/* Modify BTC_MODE according to BTC_CHAIN_MODE */
8409 	status = ucfg_coex_psoc_get_btc_chain_mode(psoc, &btc_chain_mode);
8410 	if (QDF_IS_STATUS_ERROR(status)) {
8411 		hdd_err("Failed to get btc chain mode");
8412 		btc_chain_mode = WLAN_COEX_BTC_CHAIN_MODE_UNSETTLED;
8413 	}
8414 
8415 	if (btc_chain_mode <= WLAN_COEX_BTC_CHAIN_MODE_HYBRID)
8416 		coex_cfg_params.config_arg1 = btc_chain_mode;
8417 	else
8418 		coex_cfg_params.config_arg1 = config.btc_mode;
8419 
8420 	hdd_debug("Configured BTC mode is %d, BTC chain mode is 0x%x, set BTC mode to %d",
8421 		  config.btc_mode, btc_chain_mode,
8422 		  coex_cfg_params.config_arg1);
8423 	status = sme_send_coex_config_cmd(&coex_cfg_params);
8424 	if (QDF_IS_STATUS_ERROR(status)) {
8425 		hdd_err("Failed to send coex BTC mode");
8426 		goto err;
8427 	}
8428 
8429 	coex_cfg_params.config_type = WMI_COEX_CONFIG_ANTENNA_ISOLATION;
8430 	coex_cfg_params.config_arg1 = config.antenna_isolation;
8431 
8432 	status = sme_send_coex_config_cmd(&coex_cfg_params);
8433 	if (QDF_IS_STATUS_ERROR(status)) {
8434 		hdd_err("Failed to send coex antenna isolation");
8435 		goto err;
8436 	}
8437 
8438 	coex_cfg_params.config_type = WMI_COEX_CONFIG_BT_LOW_RSSI_THRESHOLD;
8439 	coex_cfg_params.config_arg1 = config.bt_low_rssi_threshold;
8440 
8441 	status = sme_send_coex_config_cmd(&coex_cfg_params);
8442 	if (QDF_IS_STATUS_ERROR(status)) {
8443 		hdd_err("Failed to send coex BT low RSSI threshold");
8444 		goto err;
8445 	}
8446 
8447 	coex_cfg_params.config_type = WMI_COEX_CONFIG_BT_INTERFERENCE_LEVEL;
8448 	coex_cfg_params.config_arg1 = config.bt_interference_low_ll;
8449 	coex_cfg_params.config_arg2 = config.bt_interference_low_ul;
8450 	coex_cfg_params.config_arg3 = config.bt_interference_medium_ll;
8451 	coex_cfg_params.config_arg4 = config.bt_interference_medium_ul;
8452 	coex_cfg_params.config_arg5 = config.bt_interference_high_ll;
8453 	coex_cfg_params.config_arg6 = config.bt_interference_high_ul;
8454 
8455 	status = sme_send_coex_config_cmd(&coex_cfg_params);
8456 	if (QDF_IS_STATUS_ERROR(status)) {
8457 		hdd_err("Failed to send coex BT interference level");
8458 		goto err;
8459 	}
8460 
8461 	if (wlan_hdd_mpta_helper_enable(&coex_cfg_params, &config))
8462 		goto err;
8463 
8464 	coex_cfg_params.config_type =
8465 				WMI_COEX_CONFIG_BT_SCO_ALLOW_WLAN_2G_SCAN;
8466 	coex_cfg_params.config_arg1 = config.bt_sco_allow_wlan_2g_scan;
8467 
8468 	status = sme_send_coex_config_cmd(&coex_cfg_params);
8469 	if (QDF_IS_STATUS_ERROR(status)) {
8470 		hdd_err("Failed to send coex BT sco allow wlan 2g scan");
8471 		goto err;
8472 	}
8473 
8474 	coex_cfg_params.config_type =
8475 				WMI_COEX_CONFIG_LE_SCAN_POLICY;
8476 	coex_cfg_params.config_arg1 = config.ble_scan_coex_policy;
8477 
8478 	status = sme_send_coex_config_cmd(&coex_cfg_params);
8479 	if (QDF_IS_STATUS_ERROR(status)) {
8480 		hdd_err("Failed to send coex BLE scan policy");
8481 		goto err;
8482 	}
8483 
8484 #ifdef FEATURE_COEX_TPUT_SHAPING_CONFIG
8485 	coex_cfg_params.config_type =
8486 				WMI_COEX_CONFIG_ENABLE_TPUT_SHAPING;
8487 	coex_cfg_params.config_arg1 = config.coex_tput_shaping_enable;
8488 
8489 	status = sme_send_coex_config_cmd(&coex_cfg_params);
8490 	if (QDF_IS_STATUS_ERROR(status)) {
8491 		hdd_err("Failed to send coex traffic shaping value %d",
8492 			coex_cfg_params.config_arg1);
8493 		goto err;
8494 	}
8495 #endif
8496 	return 0;
8497 err:
8498 	return -EINVAL;
8499 }
8500 #endif
8501 
8502 /**
8503  * hdd_send_coex_traffic_shaping_mode() - Send coex traffic shaping mode
8504  * to FW
8505  * @vdev_id: vdev ID
8506  * @mode: traffic shaping mode
8507  *
8508  * This function is used to send coex traffic shaping mode to FW
8509  *
8510  * Return: 0 on success and -EINVAL on failure
8511  */
8512 int hdd_send_coex_traffic_shaping_mode(uint8_t vdev_id, uint8_t mode)
8513 {
8514 	struct coex_config_params coex_cfg_params = {0};
8515 
8516 	coex_cfg_params.config_type = WMI_COEX_SET_TRAFFIC_SHAPING_MODE;
8517 	coex_cfg_params.config_arg1 = mode;
8518 	coex_cfg_params.vdev_id     = vdev_id;
8519 
8520 	if (QDF_IS_STATUS_ERROR(sme_send_coex_config_cmd(&coex_cfg_params))) {
8521 		hdd_err_rl("Failed to send coex traffic shaping mode");
8522 		return -EINVAL;
8523 	}
8524 	return 0;
8525 }
8526 
8527 #define MAX_PDEV_SET_FW_PARAMS 7
8528 /* params being sent:
8529  * 1.wmi_pdev_param_dtim_synth
8530  * 2.wmi_pdev_param_1ch_dtim_optimized_chain_selection
8531  * 3.wmi_pdev_param_tx_sch_delay
8532  * 4.wmi_pdev_param_en_update_scram_seed
8533  * 5.wmi_pdev_param_secondary_retry_enable
8534  * 6.wmi_pdev_param_set_sap_xlna_bypass
8535  * 7.wmi_pdev_param_set_dfs_chan_ageout_time
8536  */
8537 
8538 /**
8539  * hdd_set_fw_params() - Set parameters to firmware
8540  * @adapter: HDD adapter
8541  *
8542  * This function Sets various parameters to fw once the
8543  * adapter is started.
8544  *
8545  * Return: 0 on success or errno on failure
8546  */
8547 int hdd_set_fw_params(struct hdd_adapter *adapter)
8548 {
8549 	int ret;
8550 	uint16_t upper_brssi_thresh, lower_brssi_thresh;
8551 	bool enable_dtim_1chrx;
8552 	QDF_STATUS status;
8553 	struct hdd_context *hdd_ctx;
8554 	bool is_lprx_enabled;
8555 	bool bval = false;
8556 	uint8_t enable_tx_sch_delay, dfs_chan_ageout_time;
8557 	uint32_t dtim_sel_diversity, enable_secondary_rate;
8558 	bool sap_xlna_bypass;
8559 	bool enable_ofdm_scrambler_seed = false;
8560 	struct dev_set_param setparam[MAX_PDEV_SET_FW_PARAMS] = { };
8561 	uint8_t index = 0;
8562 
8563 	hdd_enter_dev(adapter->dev);
8564 
8565 	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
8566 	if (!hdd_ctx)
8567 		return -EINVAL;
8568 
8569 	if (cds_get_conparam() == QDF_GLOBAL_FTM_MODE) {
8570 		hdd_debug("FTM Mode is active; nothing to do");
8571 		return 0;
8572 	}
8573 
8574 	/* The ini gEnableLPRx is deprecated. By default, the ini
8575 	 * is enabled. So, making the variable is_lprx_enabled true.
8576 	 */
8577 	is_lprx_enabled = true;
8578 
8579 	ret = mlme_check_index_setparam(setparam, wmi_pdev_param_dtim_synth,
8580 					is_lprx_enabled, index++,
8581 					MAX_PDEV_SET_FW_PARAMS);
8582 	if (QDF_IS_STATUS_ERROR(ret))
8583 		goto error;
8584 
8585 	ucfg_mlme_get_dtim_selection_diversity(hdd_ctx->psoc,
8586 					       &dtim_sel_diversity);
8587 	ret = mlme_check_index_setparam(
8588 			setparam,
8589 			wmi_pdev_param_1ch_dtim_optimized_chain_selection,
8590 			dtim_sel_diversity, index++, MAX_PDEV_SET_FW_PARAMS);
8591 	if (QDF_IS_STATUS_ERROR(ret))
8592 		goto error;
8593 
8594 	if (QDF_IS_STATUS_SUCCESS(ucfg_fwol_get_enable_tx_sch_delay(
8595 				  hdd_ctx->psoc, &enable_tx_sch_delay))) {
8596 		ret = mlme_check_index_setparam(
8597 					      setparam,
8598 					      wmi_pdev_param_tx_sch_delay,
8599 					      enable_tx_sch_delay, index++,
8600 					      MAX_PDEV_SET_FW_PARAMS);
8601 		if (QDF_IS_STATUS_ERROR(ret))
8602 			goto error;
8603 	}
8604 
8605 	if (QDF_IS_STATUS_SUCCESS(ucfg_fwol_get_ofdm_scrambler_seed(
8606 				hdd_ctx->psoc, &enable_ofdm_scrambler_seed))) {
8607 		ret = mlme_check_index_setparam(
8608 					setparam,
8609 					wmi_pdev_param_en_update_scram_seed,
8610 					enable_ofdm_scrambler_seed, index++,
8611 					MAX_PDEV_SET_FW_PARAMS);
8612 		if (QDF_IS_STATUS_ERROR(ret))
8613 			goto error;
8614 	}
8615 
8616 	if (QDF_IS_STATUS_SUCCESS(ucfg_fwol_get_enable_secondary_rate(
8617 				  hdd_ctx->psoc, &enable_secondary_rate))) {
8618 		ret = mlme_check_index_setparam(
8619 					setparam,
8620 					wmi_pdev_param_secondary_retry_enable,
8621 					enable_secondary_rate, index++,
8622 					MAX_PDEV_SET_FW_PARAMS);
8623 		if (QDF_IS_STATUS_ERROR(ret))
8624 			goto error;
8625 	}
8626 	if (QDF_IS_STATUS_SUCCESS(ucfg_fwol_get_sap_xlna_bypass(
8627 				  hdd_ctx->psoc, &sap_xlna_bypass))) {
8628 		ret = mlme_check_index_setparam(
8629 					setparam,
8630 					wmi_pdev_param_set_sap_xlna_bypass,
8631 					sap_xlna_bypass, index++,
8632 					MAX_PDEV_SET_FW_PARAMS);
8633 		if (QDF_IS_STATUS_ERROR(ret))
8634 			goto error;
8635 	}
8636 	wlan_mlme_get_dfs_chan_ageout_time(hdd_ctx->psoc,
8637 					   &dfs_chan_ageout_time);
8638 	ret = mlme_check_index_setparam(
8639 				      setparam,
8640 				      wmi_pdev_param_set_dfs_chan_ageout_time,
8641 				      dfs_chan_ageout_time, index++,
8642 				      MAX_PDEV_SET_FW_PARAMS);
8643 	if (QDF_IS_STATUS_ERROR(ret))
8644 		goto error;
8645 
8646 	ret = sme_send_multi_pdev_vdev_set_params(MLME_PDEV_SETPARAM,
8647 						  WMI_PDEV_ID_SOC, setparam,
8648 						  index);
8649 	if (QDF_IS_STATUS_ERROR(ret)) {
8650 		goto error;
8651 	}
8652 	if (adapter->device_mode == QDF_STA_MODE) {
8653 		status = ucfg_get_upper_brssi_thresh(hdd_ctx->psoc,
8654 						     &upper_brssi_thresh);
8655 		if (QDF_IS_STATUS_ERROR(status))
8656 			return -EINVAL;
8657 
8658 		sme_set_smps_cfg(adapter->deflink->vdev_id,
8659 				 HDD_STA_SMPS_PARAM_UPPER_BRSSI_THRESH,
8660 				 upper_brssi_thresh);
8661 
8662 		status = ucfg_get_lower_brssi_thresh(hdd_ctx->psoc,
8663 						     &lower_brssi_thresh);
8664 		if (QDF_IS_STATUS_ERROR(status))
8665 			return -EINVAL;
8666 
8667 		sme_set_smps_cfg(adapter->deflink->vdev_id,
8668 				 HDD_STA_SMPS_PARAM_LOWER_BRSSI_THRESH,
8669 				 lower_brssi_thresh);
8670 
8671 		status = ucfg_get_enable_dtim_1chrx(hdd_ctx->psoc,
8672 						    &enable_dtim_1chrx);
8673 		if (QDF_IS_STATUS_ERROR(status))
8674 			return -EINVAL;
8675 
8676 		sme_set_smps_cfg(adapter->deflink->vdev_id,
8677 				 HDD_STA_SMPS_PARAM_DTIM_1CHRX_ENABLE,
8678 				 enable_dtim_1chrx);
8679 	}
8680 
8681 	status = ucfg_mlme_get_vht_enable2x2(hdd_ctx->psoc, &bval);
8682 	if (!QDF_IS_STATUS_SUCCESS(status))
8683 		hdd_err("unable to get vht_enable2x2");
8684 
8685 	if (bval) {
8686 		hdd_debug("configuring 2x2 mode fw params");
8687 
8688 		ret = sme_set_cck_tx_fir_override(hdd_ctx->mac_handle,
8689 						  adapter->deflink->vdev_id);
8690 		if (ret) {
8691 			hdd_err("wmi_pdev_param_enable_cck_tfir_override set failed %d",
8692 				ret);
8693 			goto error;
8694 		}
8695 
8696 		hdd_configure_chain_mask(adapter);
8697 	} else {
8698 #define HDD_DTIM_1CHAIN_RX_ID 0x5
8699 #define HDD_SMPS_PARAM_VALUE_S 29
8700 		hdd_debug("configuring 1x1 mode fw params");
8701 
8702 		/*
8703 		 * Disable DTIM 1 chain Rx when in 1x1,
8704 		 * we are passing two value
8705 		 * as param_id << 29 | param_value.
8706 		 * Below param_value = 0(disable)
8707 		 */
8708 		ret = sme_cli_set_command(adapter->deflink->vdev_id,
8709 					  WMI_STA_SMPS_PARAM_CMDID,
8710 					  HDD_DTIM_1CHAIN_RX_ID <<
8711 					  HDD_SMPS_PARAM_VALUE_S,
8712 					  VDEV_CMD);
8713 		if (ret) {
8714 			hdd_err("DTIM 1 chain set failed %d", ret);
8715 			goto error;
8716 		}
8717 
8718 #undef HDD_DTIM_1CHAIN_RX_ID
8719 #undef HDD_SMPS_PARAM_VALUE_S
8720 
8721 		hdd_configure_chain_mask(adapter);
8722 	}
8723 
8724 	ret = sme_set_enable_mem_deep_sleep(hdd_ctx->mac_handle,
8725 					    adapter->deflink->vdev_id);
8726 	if (ret) {
8727 		hdd_err("wmi_pdev_param_hyst_en set failed %d", ret);
8728 		goto error;
8729 	}
8730 
8731 	if (!hdd_ctx->is_fw_dbg_log_levels_configured) {
8732 		hdd_set_fw_log_params(hdd_ctx, adapter->deflink->vdev_id);
8733 		hdd_ctx->is_fw_dbg_log_levels_configured = true;
8734 	}
8735 
8736 	ret = hdd_send_coex_config_params(hdd_ctx, adapter);
8737 	if (ret) {
8738 		hdd_warn("Error initializing coex config params");
8739 		goto error;
8740 	}
8741 
8742 	hdd_exit();
8743 
8744 	return 0;
8745 
8746 error:
8747 	return -EINVAL;
8748 }
8749 
8750 /**
8751  * hdd_init_completion() - Initialize Completion Variables
8752  * @adapter: HDD adapter
8753  *
8754  * This function Initialize the completion variables for
8755  * a particular adapter
8756  *
8757  * Return: None
8758  */
8759 static void hdd_init_completion(struct hdd_adapter *adapter)
8760 {
8761 	init_completion(&adapter->disconnect_comp_var);
8762 	init_completion(&adapter->linkup_event_var);
8763 	init_completion(&adapter->lfr_fw_status.disable_lfr_event);
8764 }
8765 
8766 static void hdd_reset_locally_admin_bit(struct hdd_context *hdd_ctx,
8767 					tSirMacAddr mac_addr)
8768 {
8769 	int i;
8770 	/*
8771 	 * Reset locally administered bit for dynamic_mac_list
8772 	 * also as while releasing the MAC address for any
8773 	 * interface mac will be compared with dynamic mac list
8774 	 */
8775 	for (i = 0; i < QDF_MAX_CONCURRENCY_PERSONA; i++) {
8776 		if (!qdf_mem_cmp(
8777 			mac_addr,
8778 			 &hdd_ctx->
8779 				dynamic_mac_list[i].dynamic_mac.bytes[0],
8780 				sizeof(struct qdf_mac_addr))) {
8781 			WLAN_HDD_RESET_LOCALLY_ADMINISTERED_BIT(
8782 				hdd_ctx->
8783 					dynamic_mac_list[i].dynamic_mac.bytes);
8784 			break;
8785 		}
8786 	}
8787 	/*
8788 	 * Reset locally administered bit if the device mode is
8789 	 * STA
8790 	 */
8791 	WLAN_HDD_RESET_LOCALLY_ADMINISTERED_BIT(mac_addr);
8792 	hdd_debug("locally administered bit reset in sta mode: "
8793 		 QDF_MAC_ADDR_FMT, QDF_MAC_ADDR_REF(mac_addr));
8794 }
8795 
8796 static void wlan_hdd_cfg80211_scan_block_cb(struct work_struct *work)
8797 {
8798 	struct hdd_adapter *adapter =
8799 		container_of(work, struct hdd_adapter, scan_block_work);
8800 	struct osif_vdev_sync *vdev_sync;
8801 
8802 	if (osif_vdev_sync_op_start(adapter->dev, &vdev_sync))
8803 		return;
8804 
8805 	wlan_hdd_cfg80211_scan_block(adapter);
8806 
8807 	osif_vdev_sync_op_stop(vdev_sync);
8808 }
8809 
8810 #if defined(WLAN_FEATURE_11BE_MLO) && \
8811 	defined(WLAN_HDD_MULTI_VDEV_SINGLE_NDEV)
8812 static inline void
8813 wlan_hdd_set_ml_cap_for_sap_intf(struct hdd_adapter_create_param *create_params,
8814 				 enum QDF_OPMODE mode)
8815 {
8816 	if (mode != QDF_SAP_MODE)
8817 		return;
8818 
8819 	create_params->is_ml_adapter = true;
8820 }
8821 #elif defined(WLAN_FEATURE_11BE_MLO)
8822 static inline void
8823 wlan_hdd_set_ml_cap_for_sap_intf(struct hdd_adapter_create_param *create_params,
8824 				 enum QDF_OPMODE mode)
8825 {
8826 	if (mode != QDF_SAP_MODE)
8827 		return;
8828 
8829 	create_params->is_ml_adapter = true;
8830 	create_params->is_single_link = true;
8831 }
8832 #else
8833 static inline void
8834 wlan_hdd_set_ml_cap_for_sap_intf(struct hdd_adapter_create_param *create_params,
8835 				 enum QDF_OPMODE mode)
8836 {
8837 	create_params->is_ml_adapter = false;
8838 }
8839 #endif /* WLAN_FEATURE_11BE_MLO */
8840 
8841 #if defined(WLAN_FEATURE_11BE_MLO) && defined(CFG80211_11BE_BASIC) && \
8842 	defined(WLAN_HDD_MULTI_VDEV_SINGLE_NDEV)
8843 void hdd_adapter_disable_all_links(struct hdd_adapter *adapter)
8844 {
8845 	uint8_t idx_pos;
8846 	struct wlan_hdd_link_info *link_info;
8847 
8848 	hdd_adapter_for_each_link_info(adapter, link_info) {
8849 		qdf_zero_macaddr(&link_info->link_addr);
8850 		idx_pos = hdd_adapter_get_index_of_link_info(link_info);
8851 		adapter->curr_link_info_map[idx_pos] = idx_pos;
8852 	}
8853 	adapter->deflink = &adapter->link_info[WLAN_HDD_DEFLINK_IDX];
8854 	if (adapter->device_mode == QDF_STA_MODE)
8855 		adapter->active_links = (1 << adapter->num_links_on_create) - 1;
8856 	else
8857 		adapter->active_links = 0x1;
8858 }
8859 #endif
8860 
8861 static void hdd_adapter_enable_links(struct hdd_adapter *adapter,
8862 				     struct hdd_adapter_create_param *params)
8863 {
8864 	uint8_t num, link_idx;
8865 
8866 	/* Default link is already set on adapter allocation, only
8867 	 * enable other links if requested links is greater than 1
8868 	 */
8869 	if (params->num_sessions <= 1) {
8870 		adapter->num_links_on_create = 1;
8871 		return;
8872 	}
8873 
8874 	num = QDF_MIN(params->num_sessions, WLAN_MAX_MLD);
8875 	for (link_idx = WLAN_HDD_DEFLINK_IDX; link_idx < num; link_idx++)
8876 		qdf_atomic_set_bit(link_idx, &adapter->active_links);
8877 
8878 	adapter->num_links_on_create = num;
8879 }
8880 
8881 static void hdd_adapter_init_link_info(struct hdd_adapter *adapter)
8882 {
8883 	uint8_t idx_pos;
8884 	struct wlan_hdd_link_info *link_info;
8885 
8886 	/* Initialize each member in link info array to default values */
8887 	hdd_adapter_for_each_link_info(adapter, link_info) {
8888 		link_info->adapter = adapter;
8889 		link_info->vdev_id = WLAN_UMAC_VDEV_ID_MAX;
8890 		qdf_spinlock_create(&link_info->vdev_lock);
8891 		init_completion(&link_info->vdev_destroy_event);
8892 		qdf_event_create(&link_info->acs_complete_event);
8893 
8894 		idx_pos = hdd_adapter_get_index_of_link_info(link_info);
8895 		adapter->curr_link_info_map[idx_pos] = idx_pos;
8896 		qdf_create_work(0, &link_info->chan_change_notify_work,
8897 				hdd_chan_change_notify_work_handler,
8898 				link_info);
8899 	}
8900 }
8901 
8902 /**
8903  * hdd_open_adapter() - open and setup the hdd adapter
8904  * @hdd_ctx: global hdd context
8905  * @session_type: type of the interface to be created
8906  * @iface_name: User-visible name of the interface
8907  * @mac_addr: MAC address to assign to the interface
8908  * @name_assign_type: the name of assign type of the netdev
8909  * @rtnl_held: the rtnl lock hold flag
8910  * @params: adapter create params
8911  *
8912  * This function open and setup the hdd adapter according to the device
8913  * type request, assign the name, the mac address assigned, and then prepared
8914  * the hdd related parameters, queue, lock and ready to start.
8915  *
8916  * Return: the pointer of hdd adapter, otherwise NULL.
8917  */
8918 struct hdd_adapter *hdd_open_adapter(struct hdd_context *hdd_ctx,
8919 				     uint8_t session_type,
8920 				     const char *iface_name,
8921 				     tSirMacAddr mac_addr,
8922 				     unsigned char name_assign_type,
8923 				     bool rtnl_held,
8924 				     struct hdd_adapter_create_param *params)
8925 {
8926 	struct net_device *ndev = NULL;
8927 	struct hdd_adapter *adapter = NULL, *sta_adapter = NULL;
8928 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
8929 	uint32_t i;
8930 	bool eht_capab = 0;
8931 
8932 	status = wlan_hdd_validate_mac_address((struct qdf_mac_addr *)mac_addr);
8933 	if (QDF_IS_STATUS_ERROR(status)) {
8934 		/* Not received valid mac_addr */
8935 		hdd_err("Unable to add virtual intf: Not able to get valid mac address");
8936 		return NULL;
8937 	}
8938 
8939 	status = hdd_check_for_existing_macaddr(hdd_ctx, mac_addr);
8940 	if (QDF_STATUS_E_FAILURE == status) {
8941 		hdd_err("Duplicate MAC addr: " QDF_MAC_ADDR_FMT
8942 				" already exists",
8943 				QDF_MAC_ADDR_REF(mac_addr));
8944 		return NULL;
8945 	}
8946 
8947 	if (params->only_wdev_register) {
8948 		sta_adapter = hdd_get_ml_adapter(hdd_ctx);
8949 		if (!sta_adapter) {
8950 			hdd_err("not able to find the sta adapter");
8951 			return NULL;
8952 		}
8953 	}
8954 
8955 	switch (session_type) {
8956 	case QDF_STA_MODE:
8957 		if (!(hdd_ctx->config->mac_provision ||
8958 		      params->only_wdev_register)) {
8959 			hdd_reset_locally_admin_bit(hdd_ctx, mac_addr);
8960 			/*
8961 			 * After resetting locally administered bit
8962 			 * again check if the new mac address is already
8963 			 * exists.
8964 			 */
8965 			status = hdd_check_for_existing_macaddr(hdd_ctx,
8966 								mac_addr);
8967 			if (QDF_STATUS_E_FAILURE == status) {
8968 				hdd_err("Duplicate MAC addr: " QDF_MAC_ADDR_FMT
8969 					" already exists",
8970 					QDF_MAC_ADDR_REF(mac_addr));
8971 				return NULL;
8972 			}
8973 		}
8974 
8975 		fallthrough;
8976 	case QDF_P2P_CLIENT_MODE:
8977 	case QDF_P2P_DEVICE_MODE:
8978 	case QDF_OCB_MODE:
8979 	case QDF_NDI_MODE:
8980 	case QDF_MONITOR_MODE:
8981 	case QDF_NAN_DISC_MODE:
8982 		adapter = hdd_alloc_station_adapter(hdd_ctx, mac_addr,
8983 						    name_assign_type,
8984 						    iface_name, session_type);
8985 
8986 		if (!adapter) {
8987 			hdd_err("failed to allocate adapter for session %d",
8988 					session_type);
8989 			return NULL;
8990 		}
8991 
8992 		ndev = adapter->dev;
8993 
8994 		status = ucfg_dp_create_intf(hdd_ctx->psoc, &adapter->mac_addr,
8995 					     (qdf_netdev_t)adapter->dev);
8996 		if (QDF_IS_STATUS_ERROR(status))
8997 			goto err_free_netdev;
8998 
8999 		if (QDF_P2P_CLIENT_MODE == session_type)
9000 			adapter->wdev.iftype = NL80211_IFTYPE_P2P_CLIENT;
9001 		else if (QDF_P2P_DEVICE_MODE == session_type)
9002 			adapter->wdev.iftype = NL80211_IFTYPE_P2P_DEVICE;
9003 		else if (QDF_MONITOR_MODE == session_type)
9004 			adapter->wdev.iftype = NL80211_IFTYPE_MONITOR;
9005 		else if (QDF_NAN_DISC_MODE == session_type)
9006 			wlan_hdd_set_nan_if_type(adapter);
9007 		else
9008 			adapter->wdev.iftype = NL80211_IFTYPE_STATION;
9009 
9010 		adapter->device_mode = session_type;
9011 
9012 
9013 		/*
9014 		 * Workqueue which gets scheduled in IPv4 notification
9015 		 * callback
9016 		 */
9017 		INIT_WORK(&adapter->ipv4_notifier_work,
9018 			  hdd_ipv4_notifier_work_queue);
9019 
9020 #ifdef WLAN_NS_OFFLOAD
9021 		/*
9022 		 * Workqueue which gets scheduled in IPv6
9023 		 * notification callback.
9024 		 */
9025 		INIT_WORK(&adapter->ipv6_notifier_work,
9026 			  hdd_ipv6_notifier_work_queue);
9027 #endif
9028 		if (params->only_wdev_register) {
9029 			hdd_register_wdev(sta_adapter, adapter, params);
9030 		} else {
9031 			status = hdd_register_interface(adapter, rtnl_held,
9032 							params);
9033 			if (QDF_STATUS_SUCCESS != status)
9034 				goto err_destroy_dp_intf;
9035 			/* Stop the Interface TX queue. */
9036 			hdd_debug("Disabling queues");
9037 			wlan_hdd_netif_queue_control(adapter,
9038 					WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER,
9039 					WLAN_CONTROL_PATH);
9040 		}
9041 		break;
9042 	case QDF_P2P_GO_MODE:
9043 	case QDF_SAP_MODE:
9044 		adapter = hdd_wlan_create_ap_dev(hdd_ctx, mac_addr,
9045 						 name_assign_type,
9046 						 (uint8_t *) iface_name);
9047 		if (!adapter) {
9048 			hdd_err("failed to allocate adapter for session %d",
9049 					  session_type);
9050 			return NULL;
9051 		}
9052 
9053 		ndev = adapter->dev;
9054 
9055 		status = ucfg_dp_create_intf(hdd_ctx->psoc, &adapter->mac_addr,
9056 					     (qdf_netdev_t)adapter->dev);
9057 		if (QDF_IS_STATUS_ERROR(status))
9058 			goto err_free_netdev;
9059 
9060 		adapter->wdev.iftype =
9061 			(session_type ==
9062 			 QDF_SAP_MODE) ? NL80211_IFTYPE_AP :
9063 			NL80211_IFTYPE_P2P_GO;
9064 		adapter->device_mode = session_type;
9065 
9066 		status = hdd_register_interface(adapter, rtnl_held, params);
9067 		if (QDF_STATUS_SUCCESS != status)
9068 			goto err_destroy_dp_intf;
9069 
9070 		hdd_debug("Disabling queues");
9071 		wlan_hdd_netif_queue_control(adapter,
9072 					WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER,
9073 					WLAN_CONTROL_PATH);
9074 
9075 		/*
9076 		 * Workqueue which gets scheduled in IPv4 notification
9077 		 * callback
9078 		 */
9079 		INIT_WORK(&adapter->ipv4_notifier_work,
9080 			  hdd_ipv4_notifier_work_queue);
9081 
9082 #ifdef WLAN_NS_OFFLOAD
9083 		/*
9084 		 * Workqueue which gets scheduled in IPv6
9085 		 * notification callback.
9086 		 */
9087 		INIT_WORK(&adapter->ipv6_notifier_work,
9088 			  hdd_ipv6_notifier_work_queue);
9089 #endif
9090 		if (!params->is_pre_cac_adapter)
9091 			wlan_hdd_set_ml_cap_for_sap_intf(params, session_type);
9092 		break;
9093 	case QDF_FTM_MODE:
9094 		adapter = hdd_alloc_station_adapter(hdd_ctx, mac_addr,
9095 						    name_assign_type,
9096 						    iface_name, session_type);
9097 		if (!adapter) {
9098 			hdd_err("Failed to allocate adapter for FTM mode");
9099 			return NULL;
9100 		}
9101 
9102 		ndev = adapter->dev;
9103 
9104 		status = ucfg_dp_create_intf(hdd_ctx->psoc, &adapter->mac_addr,
9105 					     (qdf_netdev_t)adapter->dev);
9106 		if (QDF_IS_STATUS_ERROR(status))
9107 			goto err_free_netdev;
9108 
9109 		adapter->wdev.iftype = NL80211_IFTYPE_STATION;
9110 		adapter->device_mode = session_type;
9111 		status = hdd_register_interface(adapter, rtnl_held, params);
9112 		if (QDF_STATUS_SUCCESS != status)
9113 			goto err_destroy_dp_intf;
9114 
9115 		/* Stop the Interface TX queue. */
9116 		hdd_debug("Disabling queues");
9117 		wlan_hdd_netif_queue_control(adapter,
9118 					WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER,
9119 					WLAN_CONTROL_PATH);
9120 
9121 		break;
9122 	default:
9123 		hdd_err("Invalid session type %d", session_type);
9124 		QDF_ASSERT(0);
9125 		return NULL;
9126 	}
9127 
9128 	hdd_adapter_init_link_info(adapter);
9129 	hdd_adapter_enable_links(adapter, params);
9130 
9131 	ucfg_psoc_mlme_get_11be_capab(hdd_ctx->psoc, &eht_capab);
9132 	if (params->is_ml_adapter && eht_capab) {
9133 		hdd_adapter_set_ml_adapter(adapter);
9134 		if (params->is_single_link)
9135 			hdd_adapter_set_sl_ml_adapter(adapter);
9136 	}
9137 
9138 	status = hdd_adapter_feature_update_work_init(adapter);
9139 	if (QDF_IS_STATUS_ERROR(status))
9140 		goto err_cleanup_adapter;
9141 
9142 	adapter->upgrade_udp_qos_threshold = QCA_WLAN_AC_BK;
9143 
9144 	hdd_init_completion(adapter);
9145 	INIT_WORK(&adapter->scan_block_work, wlan_hdd_cfg80211_scan_block_cb);
9146 	INIT_WORK(&adapter->sap_stop_bss_work,
9147 		  hdd_stop_sap_due_to_invalid_channel);
9148 	qdf_list_create(&adapter->blocked_scan_request_q, WLAN_MAX_SCAN_COUNT);
9149 	qdf_mutex_create(&adapter->blocked_scan_request_q_lock);
9150 	qdf_spinlock_create(&adapter->mc_list_lock);
9151 	qdf_event_create(&adapter->peer_cleanup_done);
9152 	hdd_sta_info_init(&adapter->sta_info_list);
9153 	hdd_sta_info_init(&adapter->cache_sta_info_list);
9154 
9155 	for (i = 0; i < NET_DEV_HOLD_ID_MAX; i++)
9156 		qdf_atomic_init(
9157 			&adapter->net_dev_hold_ref_count[NET_DEV_HOLD_ID_MAX]);
9158 
9159 	/* Add it to the hdd's session list. */
9160 	status = hdd_add_adapter_back(hdd_ctx, adapter);
9161 	if (QDF_STATUS_SUCCESS != status)
9162 		goto err_destroy_adapter_features_update_work;
9163 
9164 	hdd_apf_context_init(adapter);
9165 
9166 	policy_mgr_set_concurrency_mode(hdd_ctx->psoc, session_type);
9167 
9168 	if (QDF_STATUS_SUCCESS != hdd_debugfs_init(adapter))
9169 		hdd_err("debugfs: Interface %s init failed",
9170 			netdev_name(adapter->dev));
9171 
9172 	hdd_debug("%s interface created. iftype: %d", netdev_name(adapter->dev),
9173 		  session_type);
9174 
9175 	if (adapter->device_mode == QDF_STA_MODE)
9176 		wlan_hdd_debugfs_csr_init(adapter);
9177 
9178 	return adapter;
9179 
9180 err_destroy_adapter_features_update_work:
9181 	hdd_adapter_feature_update_work_deinit(adapter);
9182 
9183 err_cleanup_adapter:
9184 	if (adapter) {
9185 		hdd_cleanup_adapter(hdd_ctx, adapter, rtnl_held);
9186 		adapter = NULL;
9187 	}
9188 
9189 err_destroy_dp_intf:
9190 	ucfg_dp_destroy_intf(hdd_ctx->psoc, &adapter->mac_addr);
9191 
9192 err_free_netdev:
9193 	if (ndev)
9194 		free_netdev(ndev);
9195 
9196 	return NULL;
9197 }
9198 
9199 static void __hdd_close_adapter(struct hdd_context *hdd_ctx,
9200 				struct hdd_adapter *adapter,
9201 				bool rtnl_held)
9202 {
9203 	struct qdf_mac_addr adapter_mac;
9204 	struct wlan_hdd_link_info *link_info;
9205 
9206 	qdf_copy_macaddr(&adapter_mac, &adapter->mac_addr);
9207 	if (adapter->device_mode == QDF_STA_MODE) {
9208 		hdd_adapter_for_each_link_info(adapter, link_info)
9209 			hdd_cleanup_conn_info(link_info);
9210 	}
9211 
9212 	hdd_adapter_for_each_link_info(adapter, link_info)
9213 		qdf_flush_work(&link_info->chan_change_notify_work);
9214 
9215 	qdf_list_destroy(&adapter->blocked_scan_request_q);
9216 	qdf_mutex_destroy(&adapter->blocked_scan_request_q_lock);
9217 	policy_mgr_clear_concurrency_mode(hdd_ctx->psoc, adapter->device_mode);
9218 	qdf_event_destroy(&adapter->peer_cleanup_done);
9219 	hdd_adapter_feature_update_work_deinit(adapter);
9220 	hdd_cleanup_adapter(hdd_ctx, adapter, rtnl_held);
9221 	ucfg_dp_destroy_intf(hdd_ctx->psoc, &adapter_mac);
9222 }
9223 
9224 void hdd_close_adapter(struct hdd_context *hdd_ctx,
9225 		       struct hdd_adapter *adapter,
9226 		       bool rtnl_held)
9227 {
9228 	/*
9229 	 * Stop the global bus bandwidth timer while touching the adapter list
9230 	 * to avoid bad memory access by the timer handler.
9231 	 */
9232 	ucfg_dp_bus_bw_compute_timer_stop(hdd_ctx->psoc);
9233 
9234 	hdd_check_for_net_dev_ref_leak(adapter);
9235 	hdd_remove_adapter(hdd_ctx, adapter);
9236 	__hdd_close_adapter(hdd_ctx, adapter, rtnl_held);
9237 
9238 	/* conditionally restart the bw timer */
9239 	ucfg_dp_bus_bw_compute_timer_try_start(hdd_ctx->psoc);
9240 }
9241 
9242 void hdd_close_all_adapters(struct hdd_context *hdd_ctx, bool rtnl_held)
9243 {
9244 	struct hdd_adapter *adapter;
9245 	struct osif_vdev_sync *vdev_sync;
9246 	QDF_STATUS qdf_status;
9247 
9248 	hdd_enter();
9249 
9250 	while (QDF_IS_STATUS_SUCCESS(hdd_get_front_adapter(
9251 							hdd_ctx, &adapter))) {
9252 		/* If MLO is enabled unregister the link wdev's */
9253 		if (adapter->device_mode == QDF_STA_MODE ||
9254 		    adapter->device_mode == QDF_SAP_MODE) {
9255 			qdf_status = hdd_wlan_unregister_mlo_interfaces(adapter,
9256 								     rtnl_held);
9257 			if (QDF_IS_STATUS_ERROR(qdf_status))
9258 				continue;
9259 		}
9260 
9261 		hdd_check_for_net_dev_ref_leak(adapter);
9262 		hdd_remove_front_adapter(hdd_ctx, &adapter);
9263 		vdev_sync = osif_vdev_sync_unregister(adapter->dev);
9264 		if (vdev_sync)
9265 			osif_vdev_sync_wait_for_ops(vdev_sync);
9266 
9267 		wlan_hdd_release_intf_addr(hdd_ctx, adapter->mac_addr.bytes);
9268 		__hdd_close_adapter(hdd_ctx, adapter, rtnl_held);
9269 
9270 		if (vdev_sync)
9271 			osif_vdev_sync_destroy(vdev_sync);
9272 	}
9273 
9274 	hdd_exit();
9275 }
9276 
9277 void wlan_hdd_reset_prob_rspies(struct wlan_hdd_link_info *link_info)
9278 {
9279 	struct qdf_mac_addr *bssid = NULL;
9280 	tSirUpdateIE update_ie;
9281 	mac_handle_t mac_handle;
9282 	struct hdd_adapter *adapter = link_info->adapter;
9283 
9284 	switch (adapter->device_mode) {
9285 	case QDF_STA_MODE:
9286 	case QDF_P2P_CLIENT_MODE:
9287 	{
9288 		struct hdd_station_ctx *sta_ctx =
9289 			WLAN_HDD_GET_STATION_CTX_PTR(link_info);
9290 		bssid = &sta_ctx->conn_info.bssid;
9291 		break;
9292 	}
9293 	case QDF_SAP_MODE:
9294 	case QDF_P2P_GO_MODE:
9295 	{
9296 		bssid = &adapter->mac_addr;
9297 		break;
9298 	}
9299 	case QDF_FTM_MODE:
9300 	case QDF_P2P_DEVICE_MODE:
9301 	default:
9302 		/*
9303 		 * wlan_hdd_reset_prob_rspies should not have been called
9304 		 * for these kind of devices
9305 		 */
9306 		hdd_err("Unexpected request for the current device type %d",
9307 		       adapter->device_mode);
9308 		return;
9309 	}
9310 
9311 	qdf_copy_macaddr(&update_ie.bssid, bssid);
9312 	update_ie.vdev_id = link_info->vdev_id;
9313 	update_ie.ieBufferlength = 0;
9314 	update_ie.pAdditionIEBuffer = NULL;
9315 	update_ie.append = true;
9316 	update_ie.notify = false;
9317 	mac_handle = hdd_adapter_get_mac_handle(adapter);
9318 	if (sme_update_add_ie(mac_handle,
9319 			      &update_ie,
9320 			      eUPDATE_IE_PROBE_RESP) == QDF_STATUS_E_FAILURE) {
9321 		hdd_err("Could not pass on PROBE_RSP_BCN data to PE");
9322 	}
9323 }
9324 
9325 /**
9326  * hdd_ipa_ap_disconnect_evt() - Indicate wlan ipa ap disconnect event
9327  * @hdd_ctx: hdd context
9328  * @adapter: hdd adapter
9329  *
9330  * Return: None
9331  */
9332 static inline
9333 void hdd_ipa_ap_disconnect_evt(struct hdd_context *hdd_ctx,
9334 			       struct hdd_adapter *adapter)
9335 {
9336 	struct wlan_hdd_link_info *link_info;
9337 
9338 	link_info = adapter->deflink;
9339 	if (ucfg_ipa_is_enabled()) {
9340 		ucfg_ipa_uc_disconnect_ap(hdd_ctx->pdev,
9341 					  adapter->dev);
9342 		ucfg_ipa_cleanup_dev_iface(hdd_ctx->pdev,
9343 					   adapter->dev,
9344 					   link_info->vdev_id);
9345 	}
9346 }
9347 
9348 #ifdef WLAN_FEATURE_NAN
9349 /**
9350  * hdd_ndp_state_cleanup() - API to set NDP state to Disconnected
9351  * @psoc: pointer to psoc object
9352  * @ndi_vdev_id: vdev_id of the NDI
9353  *
9354  * Return: None
9355  */
9356 static void
9357 hdd_ndp_state_cleanup(struct wlan_objmgr_psoc *psoc, uint8_t ndi_vdev_id)
9358 {
9359 	struct wlan_objmgr_vdev *ndi_vdev;
9360 
9361 	ndi_vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, ndi_vdev_id,
9362 							WLAN_NAN_ID);
9363 	if (!ndi_vdev) {
9364 		hdd_err("Cannot obtain NDI vdev object!");
9365 		return;
9366 	}
9367 
9368 	ucfg_nan_set_ndi_state(ndi_vdev, NAN_DATA_DISCONNECTED_STATE);
9369 
9370 	wlan_objmgr_vdev_release_ref(ndi_vdev, WLAN_NAN_ID);
9371 }
9372 
9373 /**
9374  * hdd_peer_cleanup() - This API will delete NDP peer if exist and modifies
9375  * the NDP state.
9376  * @link_info: Link info pointer in HDD adapter
9377  *
9378  * Return: None
9379  */
9380 static void hdd_peer_cleanup(struct wlan_hdd_link_info *link_info)
9381 {
9382 	QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
9383 	struct hdd_adapter *adapter = link_info->adapter;
9384 	struct hdd_context *hdd_ctx = adapter->hdd_ctx;
9385 
9386 	/* Check if there is any peer present on the adapter */
9387 	if (!hdd_any_valid_peer_present(link_info)) {
9388 		/*
9389 		 * No peers are connected to the NDI. So, set the NDI state to
9390 		 * DISCONNECTED. If there are any peers, ucfg_nan_disable_ndi()
9391 		 * would take care of cleanup all the peers and setting the
9392 		 * state to DISCONNECTED.
9393 		 */
9394 		hdd_ndp_state_cleanup(hdd_ctx->psoc, link_info->vdev_id);
9395 		return;
9396 	}
9397 
9398 	if (adapter->device_mode == QDF_NDI_MODE)
9399 		qdf_status = ucfg_nan_disable_ndi(hdd_ctx->psoc,
9400 						  link_info->vdev_id);
9401 
9402 	if (QDF_IS_STATUS_ERROR(qdf_status))
9403 		return;
9404 
9405 	qdf_status = qdf_wait_for_event_completion(&adapter->peer_cleanup_done,
9406 						   WLAN_WAIT_PEER_CLEANUP);
9407 	if (QDF_IS_STATUS_ERROR(qdf_status))
9408 		hdd_debug("peer_cleanup_done wait fail");
9409 }
9410 #else
9411 static inline void
9412 hdd_ndp_state_cleanup(struct wlan_objmgr_psoc *psoc, uint8_t ndi_vdev_id)
9413 {
9414 }
9415 
9416 static inline void
9417 hdd_ndp_peer_cleanup(struct hdd_context *hdd_ctx, struct hdd_adapter *adapter)
9418 {
9419 }
9420 
9421 static inline void hdd_peer_cleanup(struct wlan_hdd_link_info *link_info)
9422 {
9423 }
9424 #endif /* WLAN_FEATURE_NAN */
9425 
9426 #ifdef FUNC_CALL_MAP
9427 
9428 /**
9429  * hdd_dump_func_call_map() - Dump the function call map
9430  *
9431  * Return: None
9432  */
9433 
9434 static void hdd_dump_func_call_map(void)
9435 {
9436 	char *cc_buf;
9437 
9438 	cc_buf = qdf_mem_malloc(QDF_FUNCTION_CALL_MAP_BUF_LEN);
9439 	/*
9440 	 * These logs are required as these indicates the start and end of the
9441 	 * dump for the auto script to parse
9442 	 */
9443 	hdd_info("Function call map dump start");
9444 	qdf_get_func_call_map(cc_buf);
9445 	qdf_trace_hex_dump(QDF_MODULE_ID_HDD,
9446 		QDF_TRACE_LEVEL_DEBUG, cc_buf, QDF_FUNCTION_CALL_MAP_BUF_LEN);
9447 	hdd_info("Function call map dump end");
9448 	qdf_mem_free(cc_buf);
9449 }
9450 #else
9451 static inline void hdd_dump_func_call_map(void)
9452 {
9453 }
9454 #endif
9455 
9456 static void hdd_reset_scan_operation(struct wlan_hdd_link_info *link_info)
9457 {
9458 	switch (link_info->adapter->device_mode) {
9459 	case QDF_STA_MODE:
9460 	case QDF_P2P_CLIENT_MODE:
9461 	case QDF_P2P_DEVICE_MODE:
9462 	case QDF_NDI_MODE:
9463 		wlan_hdd_scan_abort(link_info);
9464 		wlan_hdd_cleanup_remain_on_channel_ctx(link_info);
9465 		if (link_info->adapter->device_mode == QDF_STA_MODE) {
9466 			struct wlan_objmgr_vdev *vdev;
9467 
9468 			vdev = hdd_objmgr_get_vdev_by_user(link_info,
9469 							   WLAN_OSIF_SCAN_ID);
9470 			if (!vdev)
9471 				break;
9472 
9473 			wlan_cfg80211_sched_scan_stop(vdev);
9474 			hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_SCAN_ID);
9475 		}
9476 		break;
9477 	case QDF_P2P_GO_MODE:
9478 		wlan_hdd_cleanup_remain_on_channel_ctx(link_info);
9479 		break;
9480 	case QDF_SAP_MODE:
9481 		qdf_atomic_set(&link_info->session.ap.acs_in_progress, 0);
9482 		break;
9483 	default:
9484 		break;
9485 	}
9486 }
9487 
9488 #ifdef WLAN_OPEN_SOURCE
9489 void hdd_cancel_ip_notifier_work(struct hdd_adapter *adapter)
9490 {
9491 	cancel_work_sync(&adapter->ipv4_notifier_work);
9492 #ifdef WLAN_NS_OFFLOAD
9493 	cancel_work_sync(&adapter->ipv6_notifier_work);
9494 #endif
9495 }
9496 #endif
9497 
9498 void hdd_adapter_deregister_fc(struct hdd_adapter *adapter)
9499 {
9500 	hdd_deregister_hl_netdev_fc_timer(adapter);
9501 	hdd_deregister_tx_flow_control(adapter);
9502 }
9503 
9504 static void hdd_stop_and_cleanup_ndi(struct wlan_hdd_link_info *link_info)
9505 {
9506 	QDF_STATUS status;
9507 	unsigned long rc;
9508 	struct hdd_adapter *adapter = link_info->adapter;
9509 	struct hdd_context *hdd_ctx = adapter->hdd_ctx;
9510 
9511 	hdd_destroy_adapter_sysfs_files(adapter);
9512 	/* For NDI do not use roam_profile */
9513 	INIT_COMPLETION(adapter->disconnect_comp_var);
9514 	hdd_peer_cleanup(link_info);
9515 	status = sme_roam_ndi_stop(hdd_ctx->mac_handle, link_info->vdev_id);
9516 	if (QDF_IS_STATUS_SUCCESS(status)) {
9517 		rc = wait_for_completion_timeout(
9518 			&adapter->disconnect_comp_var,
9519 			msecs_to_jiffies(SME_CMD_STOP_BSS_TIMEOUT));
9520 		if (!rc)
9521 			hdd_warn("disconn_comp_var wait fail");
9522 		hdd_cleanup_ndi(link_info);
9523 	}
9524 }
9525 
9526 static void
9527 hdd_sta_disconnect_and_cleanup(struct wlan_hdd_link_info *link_info)
9528 {
9529 	QDF_STATUS status;
9530 	enum wlan_reason_code reason;
9531 	struct hdd_adapter *adapter = link_info->adapter;
9532 
9533 	/*
9534 	 * On vdev delete wait for disconnect to
9535 	 * complete. i.e use sync API, so that the
9536 	 * vdev ref of MLME are cleaned and disconnect
9537 	 * complete before vdev is moved to logically
9538 	 * deleted.
9539 	 */
9540 	if (cds_is_driver_recovering())
9541 		reason = REASON_DEVICE_RECOVERY;
9542 	else
9543 		reason = REASON_IFACE_DOWN;
9544 
9545 	status = wlan_hdd_cm_issue_disconnect(link_info, reason, true);
9546 	if (QDF_IS_STATUS_ERROR(status) && ucfg_ipa_is_enabled()) {
9547 		hdd_err("STA disconnect failed");
9548 		ucfg_ipa_uc_cleanup_sta(adapter->hdd_ctx->pdev, adapter->dev,
9549 					link_info->vdev_id);
9550 	}
9551 }
9552 
9553 static void
9554 hdd_disable_nan_active_disc(struct hdd_adapter *adapter)
9555 {
9556 	struct hdd_context *hdd_ctx = adapter->hdd_ctx;
9557 	enum QDF_OPMODE device_mode = adapter->device_mode;
9558 
9559 	if ((device_mode == QDF_NAN_DISC_MODE ||
9560 	     (device_mode == QDF_STA_MODE &&
9561 	      !ucfg_nan_is_vdev_creation_allowed(hdd_ctx->psoc))) &&
9562 	    ucfg_is_nan_conc_control_supported(hdd_ctx->psoc) &&
9563 	    ucfg_is_nan_disc_active(hdd_ctx->psoc))
9564 		ucfg_disable_nan_discovery(hdd_ctx->psoc, NULL, 0);
9565 }
9566 
9567 static void
9568 hdd_monitor_mode_release_wakelock(struct wlan_hdd_link_info *link_info)
9569 {
9570 	struct hdd_adapter *adapter = link_info->adapter;
9571 	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
9572 
9573 	if (wlan_hdd_is_session_type_monitor(adapter->device_mode) &&
9574 	    (ucfg_mlme_is_sta_mon_conc_supported(hdd_ctx->psoc) ||
9575 	     ucfg_dp_is_local_pkt_capture_enabled(hdd_ctx->psoc))) {
9576 		hdd_info("Release wakelock for STA + monitor mode!");
9577 		os_if_dp_local_pkt_capture_stop(link_info->vdev);
9578 		qdf_runtime_pm_allow_suspend(
9579 				&hdd_ctx->runtime_context.monitor_mode);
9580 		hdd_lpc_enable_powersave(hdd_ctx);
9581 		qdf_wake_lock_release(&hdd_ctx->monitor_mode_wakelock,
9582 				      WIFI_POWER_EVENT_WAKELOCK_MONITOR_MODE);
9583 	}
9584 }
9585 
9586 static void
9587 hdd_monitor_mode_disable_and_delete(struct wlan_hdd_link_info *link_info)
9588 {
9589 	QDF_STATUS status;
9590 	struct hdd_adapter *adapter = link_info->adapter;
9591 	struct hdd_context *hdd_ctx = adapter->hdd_ctx;
9592 
9593 	status = hdd_disable_monitor_mode();
9594 	if (QDF_IS_STATUS_ERROR(status))
9595 		hdd_err_rl("datapath reset failed for montior mode");
9596 	hdd_set_idle_ps_config(hdd_ctx, true);
9597 	status = hdd_monitor_mode_vdev_status(adapter);
9598 	if (QDF_IS_STATUS_ERROR(status))
9599 		hdd_err_rl("stop failed montior mode");
9600 	sme_delete_mon_session(hdd_ctx->mac_handle, link_info->vdev_id);
9601 }
9602 
9603 static void
9604 hdd_stop_and_close_pre_cac_adapter(struct hdd_context *hdd_ctx,
9605 				   struct wlan_objmgr_vdev *vdev)
9606 {
9607 	if (!vdev)
9608 		return;
9609 
9610 	if (!ucfg_pre_cac_adapter_is_active(vdev)) {
9611 		ucfg_pre_cac_stop(hdd_ctx->psoc);
9612 		hdd_close_pre_cac_adapter(hdd_ctx);
9613 	} else {
9614 		if (ucfg_pre_cac_set_status(vdev, false))
9615 			hdd_err("Failed to set is_pre_cac_on to false");
9616 	}
9617 }
9618 
9619 static void hdd_reset_ies_on_sap_stop(struct wlan_hdd_link_info *link_info)
9620 {
9621 	mac_handle_t mac_handle;
9622 	tSirUpdateIE update_ie;
9623 	QDF_STATUS status;
9624 	struct hdd_adapter *adapter = link_info->adapter;
9625 
9626 	mac_handle = hdd_adapter_get_mac_handle(adapter);
9627 	update_ie.vdev_id = link_info->vdev_id;
9628 	update_ie.ieBufferlength = 0;
9629 	update_ie.pAdditionIEBuffer = NULL;
9630 	update_ie.append = false;
9631 	update_ie.notify = false;
9632 
9633 	/* Probe bcn reset */
9634 	status = sme_update_add_ie(mac_handle, &update_ie,
9635 				   eUPDATE_IE_PROBE_BCN);
9636 	if (status == QDF_STATUS_E_FAILURE)
9637 		hdd_err("Could not pass PROBE_RSP_BCN to PE");
9638 
9639 	/* Assoc resp reset */
9640 	status = sme_update_add_ie(mac_handle, &update_ie,
9641 				   eUPDATE_IE_ASSOC_RESP);
9642 	if (status == QDF_STATUS_E_FAILURE)
9643 		hdd_err("Could not pass ASSOC_RSP to PE");
9644 
9645 	/* Reset WNI_CFG_PROBE_RSP Flags */
9646 	wlan_hdd_reset_prob_rspies(link_info);
9647 }
9648 
9649 static void hdd_stop_station_adapter(struct hdd_adapter *adapter)
9650 {
9651 	struct wlan_objmgr_vdev *vdev;
9652 	enum QDF_OPMODE mode;
9653 	struct wlan_hdd_link_info *link_info;
9654 
9655 	mode = adapter->device_mode;
9656 	hdd_adapter_for_each_active_link_info(adapter, link_info) {
9657 		vdev = hdd_objmgr_get_vdev_by_user(link_info,
9658 						   WLAN_INIT_DEINIT_ID);
9659 		if (!vdev)
9660 			continue;
9661 
9662 		if (mode == QDF_NDI_MODE)
9663 			hdd_stop_and_cleanup_ndi(link_info);
9664 		else if (!hdd_cm_is_disconnected(link_info))
9665 			hdd_sta_disconnect_and_cleanup(link_info);
9666 
9667 		hdd_reset_scan_operation(link_info);
9668 		wlan_hdd_cleanup_actionframe(link_info);
9669 		wlan_hdd_flush_pmksa_cache(link_info);
9670 
9671 		if (mode == QDF_STA_MODE)
9672 			ucfg_ipa_flush_pending_vdev_events(
9673 						wlan_vdev_get_pdev(vdev),
9674 						link_info->vdev_id);
9675 		hdd_objmgr_put_vdev_by_user(vdev, WLAN_INIT_DEINIT_ID);
9676 		hdd_vdev_destroy(link_info);
9677 	}
9678 
9679 	hdd_disable_nan_active_disc(adapter);
9680 	hdd_adapter_deregister_fc(adapter);
9681 	hdd_cancel_ip_notifier_work(adapter);
9682 }
9683 
9684 static int hdd_stop_mon_adapter(struct hdd_adapter *adapter)
9685 {
9686 	struct wlan_objmgr_vdev *vdev;
9687 	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
9688 	struct wlan_hdd_link_info *link_info = adapter->deflink;
9689 
9690 	vdev = hdd_objmgr_get_vdev_by_user(link_info,
9691 					   WLAN_INIT_DEINIT_ID);
9692 	if (wlan_hdd_is_session_type_monitor(adapter->device_mode) &&
9693 	    vdev &&
9694 	    ucfg_pkt_capture_get_mode(hdd_ctx->psoc) !=
9695 					PACKET_CAPTURE_MODE_DISABLE) {
9696 		struct hdd_adapter *sta_adapter;
9697 
9698 		ucfg_pkt_capture_deregister_callbacks(vdev);
9699 		hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_ID);
9700 		link_info->vdev = NULL;
9701 
9702 		sta_adapter = hdd_get_adapter(hdd_ctx, QDF_STA_MODE);
9703 		if (!sta_adapter) {
9704 			hdd_objmgr_put_vdev_by_user(vdev, WLAN_INIT_DEINIT_ID);
9705 			hdd_err("No station interface found");
9706 			return -EINVAL;
9707 		}
9708 		hdd_reset_monitor_interface(sta_adapter);
9709 	}
9710 
9711 	hdd_monitor_mode_release_wakelock(link_info);
9712 	wlan_hdd_scan_abort(link_info);
9713 	hdd_adapter_deregister_fc(adapter);
9714 	hdd_monitor_mode_disable_and_delete(link_info);
9715 	if (vdev)
9716 		hdd_objmgr_put_vdev_by_user(vdev, WLAN_INIT_DEINIT_ID);
9717 
9718 	hdd_vdev_destroy(link_info);
9719 
9720 	return 0;
9721 }
9722 
9723 static void hdd_stop_sap_go_adapter(struct hdd_adapter *adapter)
9724 {
9725 	enum QDF_OPMODE mode;
9726 	struct hdd_ap_ctx *ap_ctx;
9727 	struct sap_context *sap_ctx;
9728 	struct sap_config *sap_config;
9729 	struct hdd_hostapd_state *hostapd_state;
9730 	struct wlan_objmgr_vdev *vdev;
9731 	struct wlan_hdd_link_info *link_info = adapter->deflink;
9732 	QDF_STATUS status = QDF_STATUS_SUCCESS;
9733 	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
9734 	uint8_t link_id;
9735 
9736 	mode = adapter->device_mode;
9737 	ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(link_info);
9738 	sap_ctx = WLAN_HDD_GET_SAP_CTX_PTR(link_info);
9739 	vdev = hdd_objmgr_get_vdev_by_user(link_info, WLAN_INIT_DEINIT_ID);
9740 
9741 	if (mode == QDF_SAP_MODE) {
9742 		wlan_hdd_scan_abort(link_info);
9743 		hdd_abort_ongoing_sta_connection(hdd_ctx);
9744 		/* Diassociate with all the peers before stop ap post */
9745 		if (test_bit(SOFTAP_BSS_STARTED, &link_info->link_flags)) {
9746 			if (wlan_hdd_del_station(adapter, NULL))
9747 				hdd_sap_indicate_disconnect_for_sta(adapter);
9748 		}
9749 		wlan_hdd_flush_pmksa_cache(link_info);
9750 		sap_config = &ap_ctx->sap_config;
9751 		wlansap_reset_sap_config_add_ie(sap_config, eUPDATE_IE_ALL);
9752 		hdd_stop_and_close_pre_cac_adapter(hdd_ctx, vdev);
9753 	}
9754 	wlansap_cleanup_cac_timer(sap_ctx);
9755 	cds_flush_work(&adapter->sap_stop_bss_work);
9756 
9757 	if (qdf_atomic_read(&ap_ctx->acs_in_progress)) {
9758 		hdd_info("ACS in progress, wait for complete");
9759 		qdf_wait_for_event_completion(&link_info->acs_complete_event,
9760 					      ACS_COMPLETE_TIMEOUT);
9761 	}
9762 
9763 	if (mode == QDF_P2P_GO_MODE) {
9764 		wlan_hdd_cleanup_remain_on_channel_ctx(link_info);
9765 		hdd_abort_ongoing_sta_connection(hdd_ctx);
9766 	}
9767 
9768 	hdd_adapter_deregister_fc(adapter);
9769 	hdd_destroy_acs_timer(adapter);
9770 
9771 	mutex_lock(&hdd_ctx->sap_lock);
9772 	if (test_bit(SOFTAP_BSS_STARTED, &link_info->link_flags)) {
9773 		hostapd_state = WLAN_HDD_GET_HOSTAP_STATE_PTR(link_info);
9774 		qdf_event_reset(&hostapd_state->qdf_stop_bss_event);
9775 		status = wlansap_stop_bss(ap_ctx->sap_context);
9776 		if (QDF_IS_STATUS_SUCCESS(status)) {
9777 			status = qdf_wait_single_event(&hostapd_state->qdf_stop_bss_event,
9778 						       SME_CMD_STOP_BSS_TIMEOUT);
9779 			if (QDF_IS_STATUS_ERROR(status)) {
9780 				hdd_err("failure waiting for wlansap_stop_bss %d",
9781 					status);
9782 				hdd_ipa_ap_disconnect_evt(hdd_ctx, adapter);
9783 			}
9784 		} else {
9785 			hdd_err("failure in wlansap_stop_bss");
9786 		}
9787 
9788 		clear_bit(SOFTAP_BSS_STARTED, &link_info->link_flags);
9789 		policy_mgr_decr_session_set_pcl(hdd_ctx->psoc,
9790 						adapter->device_mode,
9791 						link_info->vdev_id);
9792 		hdd_green_ap_start_state_mc(hdd_ctx, adapter->device_mode,
9793 					    false);
9794 
9795 		hdd_reset_ies_on_sap_stop(link_info);
9796 	}
9797 
9798 	/*
9799 	 * Note to restart sap after SSR driver needs below information
9800 	 * and is not cleared/freed on purpose in case of SAP SSR
9801 	 */
9802 	if (!cds_is_driver_recovering()) {
9803 		clear_bit(SOFTAP_INIT_DONE, &link_info->link_flags);
9804 		qdf_mem_free(ap_ctx->beacon);
9805 		ap_ctx->beacon = NULL;
9806 
9807 		if (vdev) {
9808 			link_id = wlan_vdev_get_link_id(vdev);
9809 			ucfg_crypto_free_key_by_link_id(hdd_ctx->psoc,
9810 							&link_info->link_addr,
9811 							link_id);
9812 		}
9813 	}
9814 	/* Clear all the cached sta info */
9815 	hdd_clear_cached_sta_info(adapter);
9816 
9817 	if (vdev && policy_mgr_is_dnsc_set(vdev))
9818 		wlan_hdd_send_avoid_freq_for_dnbs(hdd_ctx, 0);
9819 
9820 	hdd_cancel_ip_notifier_work(adapter);
9821 	sap_release_vdev_ref(sap_ctx);
9822 
9823 	if (mode == QDF_SAP_MODE)
9824 		ucfg_ipa_flush_pending_vdev_events(hdd_ctx->pdev,
9825 						   link_info->vdev_id);
9826 	if (vdev)
9827 		hdd_objmgr_put_vdev_by_user(vdev, WLAN_INIT_DEINIT_ID);
9828 	hdd_vdev_destroy(link_info);
9829 	mutex_unlock(&hdd_ctx->sap_lock);
9830 	ucfg_ipa_flush(hdd_ctx->pdev);
9831 }
9832 
9833 static void hdd_stop_ocb_adapter(struct hdd_adapter *adapter)
9834 {
9835 	struct hdd_station_ctx *sta_ctx;
9836 	struct wlan_objmgr_vdev *vdev;
9837 	struct wlan_hdd_link_info *link_info = adapter->deflink;
9838 
9839 	vdev = hdd_objmgr_get_vdev_by_user(link_info, WLAN_INIT_DEINIT_ID);
9840 	sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(link_info);
9841 	cdp_clear_peer(cds_get_context(QDF_MODULE_ID_SOC), OL_TXRX_PDEV_ID,
9842 		       sta_ctx->conn_info.peer_macaddr[0]);
9843 	hdd_adapter_deregister_fc(adapter);
9844 	if (vdev)
9845 		hdd_objmgr_put_vdev_by_user(vdev, WLAN_INIT_DEINIT_ID);
9846 	hdd_vdev_destroy(link_info);
9847 }
9848 
9849 QDF_STATUS hdd_stop_adapter_ext(struct hdd_context *hdd_ctx,
9850 				struct hdd_adapter *adapter)
9851 {
9852 	QDF_STATUS status;
9853 	struct wlan_hdd_link_info *link_info = adapter->deflink;
9854 
9855 	hdd_enter();
9856 	hdd_destroy_adapter_sysfs_files(adapter);
9857 
9858 	if (adapter->device_mode == QDF_STA_MODE &&
9859 	    hdd_is_pkt_capture_mon_enable(adapter) &&
9860 	    ucfg_pkt_capture_get_mode(hdd_ctx->psoc) !=
9861 						PACKET_CAPTURE_MODE_DISABLE) {
9862 		hdd_unmap_monitor_interface_vdev(adapter);
9863 	}
9864 
9865 	if (link_info->vdev_id != WLAN_UMAC_VDEV_ID_MAX)
9866 		wlan_hdd_cfg80211_deregister_frames(adapter);
9867 
9868 	hdd_stop_tsf_sync(adapter);
9869 	cds_flush_work(&adapter->scan_block_work);
9870 	wlan_hdd_cfg80211_scan_block(adapter);
9871 	hdd_debug("Disabling queues");
9872 	wlan_hdd_netif_queue_control(adapter,
9873 				     WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER,
9874 				     WLAN_CONTROL_PATH);
9875 
9876 	switch (adapter->device_mode) {
9877 	case QDF_STA_MODE:
9878 	case QDF_P2P_CLIENT_MODE:
9879 	case QDF_NDI_MODE:
9880 	case QDF_P2P_DEVICE_MODE:
9881 	case QDF_NAN_DISC_MODE:
9882 		hdd_stop_station_adapter(adapter);
9883 		break;
9884 	case QDF_MONITOR_MODE:
9885 		status = hdd_stop_mon_adapter(adapter);
9886 		if (QDF_IS_STATUS_ERROR(status))
9887 			return status;
9888 
9889 		break;
9890 	case QDF_SAP_MODE:
9891 	case QDF_P2P_GO_MODE:
9892 		hdd_stop_sap_go_adapter(adapter);
9893 		break;
9894 	case QDF_OCB_MODE:
9895 		hdd_stop_ocb_adapter(adapter);
9896 		break;
9897 	default:
9898 		break;
9899 	}
9900 
9901 	/* Moved from vdev destroy as it is per adapter */
9902 	wlan_cfg80211_cleanup_scan_queue(hdd_ctx->pdev, adapter->dev);
9903 
9904 	/* Disable all links (expect default index) in adapter.
9905 	 * Set link address to NULL
9906 	 */
9907 	hdd_adapter_disable_all_links(adapter);
9908 
9909 	/* This function should be invoked at the end of this api*/
9910 	hdd_dump_func_call_map();
9911 	hdd_exit();
9912 
9913 	return QDF_STATUS_SUCCESS;
9914 }
9915 
9916 QDF_STATUS hdd_stop_adapter(struct hdd_context *hdd_ctx,
9917 			    struct hdd_adapter *adapter)
9918 {
9919 	QDF_STATUS status;
9920 
9921 	if (adapter->device_mode == QDF_STA_MODE)
9922 		status = hdd_stop_link_adapter(hdd_ctx, adapter);
9923 
9924 	status = hdd_stop_adapter_ext(hdd_ctx, adapter);
9925 
9926 	return status;
9927 }
9928 
9929 /**
9930  * hdd_deinit_all_adapters - deinit all adapters
9931  * @hdd_ctx:   HDD context
9932  * @rtnl_held: True if RTNL lock held
9933  *
9934  */
9935 void  hdd_deinit_all_adapters(struct hdd_context *hdd_ctx, bool rtnl_held)
9936 {
9937 	struct hdd_adapter *adapter, *next_adapter = NULL;
9938 
9939 	hdd_enter();
9940 
9941 	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
9942 					   NET_DEV_HOLD_DEINIT_ALL_ADAPTERS) {
9943 		hdd_deinit_adapter(hdd_ctx, adapter, rtnl_held);
9944 		hdd_adapter_dev_put_debug(adapter,
9945 					  NET_DEV_HOLD_DEINIT_ALL_ADAPTERS);
9946 	}
9947 
9948 	hdd_exit();
9949 }
9950 
9951 QDF_STATUS hdd_stop_all_adapters(struct hdd_context *hdd_ctx)
9952 {
9953 	struct hdd_adapter *adapter, *next_adapter = NULL;
9954 
9955 	hdd_enter();
9956 
9957 	ucfg_pre_cac_stop(hdd_ctx->psoc);
9958 	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
9959 					   NET_DEV_HOLD_STOP_ALL_ADAPTERS) {
9960 		hdd_stop_adapter(hdd_ctx, adapter);
9961 		hdd_adapter_dev_put_debug(adapter,
9962 					  NET_DEV_HOLD_STOP_ALL_ADAPTERS);
9963 	}
9964 
9965 	hdd_exit();
9966 
9967 	return QDF_STATUS_SUCCESS;
9968 }
9969 
9970 void hdd_set_netdev_flags(struct hdd_adapter *adapter)
9971 {
9972 	bool enable_csum = false;
9973 	bool enable_lro;
9974 	enum QDF_OPMODE device_mode;
9975 	struct hdd_context *hdd_ctx;
9976 	ol_txrx_soc_handle soc;
9977 	uint64_t temp;
9978 
9979 	if (!adapter || !adapter->dev) {
9980 		hdd_err("invalid input!");
9981 		return;
9982 	}
9983 	device_mode = adapter->device_mode;
9984 
9985 	hdd_ctx = adapter->hdd_ctx;
9986 	soc = cds_get_context(QDF_MODULE_ID_SOC);
9987 
9988 	if (!soc || !hdd_ctx) {
9989 		hdd_err("invalid SOC or HDD context!");
9990 		return;
9991 	}
9992 
9993 	/* Determine device_mode specific configuration */
9994 
9995 	enable_lro = !!cdp_cfg_get(soc, cfg_dp_lro_enable);
9996 	enable_csum = !!cdp_cfg_get(soc,
9997 				     cfg_dp_enable_ip_tcp_udp_checksum_offload);
9998 	switch (device_mode) {
9999 	case QDF_P2P_DEVICE_MODE:
10000 	case QDF_P2P_CLIENT_MODE:
10001 		enable_csum = !!cdp_cfg_get(soc,
10002 					    cfg_dp_enable_p2p_ip_tcp_udp_checksum_offload);
10003 		break;
10004 	case QDF_P2P_GO_MODE:
10005 		enable_csum = !!cdp_cfg_get(soc,
10006 					    cfg_dp_enable_p2p_ip_tcp_udp_checksum_offload);
10007 		enable_lro = false;
10008 		break;
10009 	case QDF_SAP_MODE:
10010 		enable_lro = false;
10011 		break;
10012 	case QDF_NDI_MODE:
10013 	case QDF_NAN_DISC_MODE:
10014 		enable_csum = !!cdp_cfg_get(soc,
10015 					    cfg_dp_enable_nan_ip_tcp_udp_checksum_offload);
10016 		break;
10017 	default:
10018 		break;
10019 	}
10020 
10021 	/* Set netdev flags */
10022 
10023 	/*
10024 	 * In case of USB tethering, LRO is disabled. If SSR happened
10025 	 * during that time, then as part of SSR init, do not enable
10026 	 * the LRO again. Keep the LRO state same as before SSR.
10027 	 */
10028 	if (enable_lro && !(qdf_atomic_read(&hdd_ctx->vendor_disable_lro_flag)))
10029 		adapter->dev->features |= NETIF_F_LRO;
10030 
10031 	if (enable_csum)
10032 		adapter->dev->features |=
10033 			(NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM);
10034 
10035 	if (cdp_cfg_get(soc, cfg_dp_tso_enable) && enable_csum) {
10036 		adapter->dev->features |= TSO_FEATURE_FLAGS;
10037 		adapter->tso_csum_feature_enabled = 1;
10038 	}
10039 
10040 	if (cdp_cfg_get(soc, cfg_dp_sg_enable))
10041 		adapter->dev->features |= NETIF_F_SG;
10042 
10043 	adapter->dev->features |= NETIF_F_RXCSUM;
10044 	temp = (uint64_t)adapter->dev->features;
10045 
10046 	hdd_debug("adapter mode %u dev feature 0x%llx", device_mode, temp);
10047 }
10048 
10049 #ifdef QCA_LL_LEGACY_TX_FLOW_CONTROL
10050 /**
10051  * hdd_adapter_abort_tx_flow() - Abort the tx flow control
10052  * @adapter: pointer to hdd adapter
10053  *
10054  * Resume tx and stop the tx flow control timer if the tx is paused
10055  * and the flow control timer is running. This function is called by
10056  * SSR to avoid the inconsistency of tx status before and after SSR.
10057  *
10058  * Return: void
10059  */
10060 static void hdd_adapter_abort_tx_flow(struct hdd_adapter *adapter)
10061 {
10062 	if (adapter->deflink->hdd_stats.tx_rx_stats.is_txflow_paused &&
10063 	    QDF_TIMER_STATE_RUNNING ==
10064 		qdf_mc_timer_get_current_state(
10065 			&adapter->tx_flow_control_timer)) {
10066 		hdd_tx_resume_timer_expired_handler(adapter);
10067 		qdf_mc_timer_stop(&adapter->tx_flow_control_timer);
10068 	}
10069 }
10070 #else
10071 static void hdd_adapter_abort_tx_flow(struct hdd_adapter *adapter)
10072 {
10073 }
10074 #endif
10075 
10076 QDF_STATUS hdd_reset_all_adapters(struct hdd_context *hdd_ctx)
10077 {
10078 	struct hdd_adapter *adapter, *next_adapter = NULL;
10079 	bool value;
10080 	struct wlan_objmgr_vdev *vdev;
10081 	struct wlan_hdd_link_info *link_info;
10082 
10083 	hdd_enter();
10084 
10085 	ucfg_mlme_get_sap_internal_restart(hdd_ctx->psoc, &value);
10086 
10087 
10088 	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
10089 					   NET_DEV_HOLD_RESET_ALL_ADAPTERS) {
10090 		hdd_info("[SSR] reset adapter with device mode %s(%d)",
10091 			 qdf_opmode_str(adapter->device_mode),
10092 			 adapter->device_mode);
10093 
10094 		hdd_adapter_for_each_active_link_info(adapter, link_info) {
10095 			hdd_adapter_abort_tx_flow(adapter);
10096 
10097 			if ((adapter->device_mode == QDF_STA_MODE) ||
10098 			    (adapter->device_mode == QDF_P2P_CLIENT_MODE)) {
10099 				hdd_send_twt_del_all_sessions_to_userspace(link_info);
10100 
10101 				/* Stop tdls timers */
10102 				vdev = hdd_objmgr_get_vdev_by_user(link_info,
10103 							   WLAN_OSIF_TDLS_ID);
10104 				if (vdev) {
10105 					hdd_notify_tdls_reset_adapter(vdev);
10106 					hdd_objmgr_put_vdev_by_user(vdev,
10107 							    WLAN_OSIF_TDLS_ID);
10108 				}
10109 			}
10110 
10111 			if (value &&
10112 			    adapter->device_mode == QDF_SAP_MODE) {
10113 				hdd_medium_assess_ssr_enable_flag();
10114 				wlan_hdd_netif_queue_control(adapter,
10115 						     WLAN_STOP_ALL_NETIF_QUEUE,
10116 						     WLAN_CONTROL_PATH);
10117 			} else {
10118 				wlan_hdd_netif_queue_control(adapter,
10119 					   WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER,
10120 					   WLAN_CONTROL_PATH);
10121 			}
10122 
10123 			/*
10124 			 * Clear fc flag if it was set before SSR to avoid
10125 			 * TX queues permanently stopped after SSR.
10126 			 * Here WLAN_START_ALL_NETIF_QUEUE will actually
10127 			 * not start any queue since it's blocked by reason
10128 			 * WLAN_CONTROL_PATH.
10129 			 */
10130 			if (adapter->pause_map & (1 << WLAN_DATA_FLOW_CONTROL))
10131 				wlan_hdd_netif_queue_control(adapter,
10132 						     WLAN_START_ALL_NETIF_QUEUE,
10133 						     WLAN_DATA_FLOW_CONTROL);
10134 
10135 			hdd_reset_scan_operation(link_info);
10136 			if (test_bit(WMM_INIT_DONE, &adapter->event_flags)) {
10137 				hdd_wmm_adapter_close(adapter);
10138 				clear_bit(WMM_INIT_DONE, &adapter->event_flags);
10139 			}
10140 
10141 			hdd_debug("Flush any mgmt references held by peer");
10142 			hdd_stop_adapter(hdd_ctx, adapter);
10143 		}
10144 		hdd_adapter_dev_put_debug(adapter,
10145 					  NET_DEV_HOLD_RESET_ALL_ADAPTERS);
10146 	}
10147 
10148 	hdd_exit();
10149 
10150 	return QDF_STATUS_SUCCESS;
10151 }
10152 
10153 static bool hdd_is_any_link_opened(struct hdd_adapter *adapter)
10154 {
10155 	struct wlan_hdd_link_info *link_info;
10156 
10157 	hdd_adapter_for_each_active_link_info(adapter, link_info) {
10158 		if (test_bit(SME_SESSION_OPENED, &link_info->link_flags))
10159 			return true;
10160 	}
10161 	return false;
10162 }
10163 
10164 bool hdd_is_any_interface_open(struct hdd_context *hdd_ctx)
10165 {
10166 	struct hdd_adapter *adapter, *next_adapter = NULL;
10167 	wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_IS_ANY_INTERFACE_OPEN;
10168 
10169 	if (hdd_get_conparam() == QDF_GLOBAL_FTM_MODE) {
10170 		hdd_info("FTM mode, don't close the module");
10171 		return true;
10172 	}
10173 
10174 	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
10175 					   dbgid) {
10176 		if (test_bit(DEVICE_IFACE_OPENED, &adapter->event_flags) ||
10177 		    hdd_is_any_link_opened(adapter)) {
10178 			hdd_adapter_dev_put_debug(adapter, dbgid);
10179 			if (next_adapter)
10180 				hdd_adapter_dev_put_debug(next_adapter, dbgid);
10181 			return true;
10182 		}
10183 		hdd_adapter_dev_put_debug(adapter, dbgid);
10184 	}
10185 
10186 	return false;
10187 }
10188 
10189 bool hdd_is_interface_up(struct hdd_adapter *adapter)
10190 {
10191 	if (test_bit(DEVICE_IFACE_OPENED, &adapter->event_flags))
10192 		return true;
10193 	else
10194 		return false;
10195 }
10196 
10197 #ifdef FEATURE_MONITOR_MODE_SUPPORT
10198 #ifdef WLAN_FEATURE_11BE
10199 static inline bool wlan_hdd_is_mon_channel_bw_valid(enum phy_ch_width ch_width)
10200 {
10201 	if (ch_width > CH_WIDTH_320MHZ ||
10202 	    (!cds_is_sub_20_mhz_enabled() && (ch_width == CH_WIDTH_5MHZ ||
10203 					      ch_width == CH_WIDTH_10MHZ)))
10204 		return false;
10205 
10206 	return true;
10207 }
10208 #else
10209 static inline bool wlan_hdd_is_mon_channel_bw_valid(enum phy_ch_width ch_width)
10210 {
10211 	if (ch_width > CH_WIDTH_10MHZ ||
10212 	    (!cds_is_sub_20_mhz_enabled() && (ch_width == CH_WIDTH_5MHZ ||
10213 					      ch_width == CH_WIDTH_10MHZ)))
10214 		return false;
10215 
10216 	return true;
10217 }
10218 #endif
10219 
10220 int wlan_hdd_set_mon_chan(struct hdd_adapter *adapter, qdf_freq_t freq,
10221 			  uint32_t bandwidth)
10222 {
10223 	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
10224 	struct hdd_station_ctx *sta_ctx;
10225 	struct hdd_mon_set_ch_info *ch_info;
10226 	QDF_STATUS status;
10227 	struct qdf_mac_addr bssid;
10228 	struct channel_change_req *req;
10229 	struct ch_params ch_params;
10230 	enum phy_ch_width max_fw_bw;
10231 	enum phy_ch_width ch_width;
10232 	int ret;
10233 
10234 	if ((hdd_get_conparam() != QDF_GLOBAL_MONITOR_MODE) &&
10235 	    (!policy_mgr_is_sta_mon_concurrency(hdd_ctx->psoc))) {
10236 		hdd_err("Not supported, device is not in monitor mode");
10237 		return -EINVAL;
10238 	}
10239 
10240 	if (adapter->device_mode != QDF_MONITOR_MODE) {
10241 		hdd_err_rl("Not supported, adapter is not in monitor mode");
10242 		return -EINVAL;
10243 	}
10244 
10245 	sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter->deflink);
10246 	ch_info = &sta_ctx->ch_info;
10247 
10248 	/* Verify the BW before accepting this request */
10249 	ch_width = bandwidth;
10250 
10251 	if (!wlan_hdd_is_mon_channel_bw_valid(ch_width)) {
10252 		hdd_err("invalid BW received %d", ch_width);
10253 		return -EINVAL;
10254 	}
10255 
10256 	max_fw_bw = sme_get_vht_ch_width();
10257 
10258 	hdd_debug("max fw BW %d ch width %d", max_fw_bw, ch_width);
10259 	if ((ch_width == CH_WIDTH_160MHZ &&
10260 	    max_fw_bw <= WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ) ||
10261 	    (ch_width == CH_WIDTH_80P80MHZ &&
10262 	    max_fw_bw <= WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ)) {
10263 		hdd_err("FW does not support this BW %d max BW supported %d",
10264 			ch_width, max_fw_bw);
10265 		return -EINVAL;
10266 	}
10267 
10268 	if (!hdd_is_target_eht_phy_ch_width_supported(ch_width))
10269 		return -EINVAL;
10270 
10271 	ret = hdd_validate_channel_and_bandwidth(adapter, freq, bandwidth);
10272 	if (ret) {
10273 		hdd_err("Invalid CH and BW combo");
10274 		return ret;
10275 	}
10276 
10277 	hdd_debug("Set monitor mode frequency %d", freq);
10278 	qdf_mem_copy(bssid.bytes, adapter->mac_addr.bytes,
10279 		     QDF_MAC_ADDR_SIZE);
10280 
10281 	ch_params.ch_width = bandwidth;
10282 	wlan_reg_set_channel_params_for_pwrmode(hdd_ctx->pdev, freq, 0,
10283 						&ch_params,
10284 						REG_CURRENT_PWR_MODE);
10285 
10286 	if (ch_params.ch_width == CH_WIDTH_INVALID) {
10287 		hdd_err("Invalid capture channel or bandwidth for a country");
10288 		return -EINVAL;
10289 	}
10290 	if (wlan_hdd_change_hw_mode_for_given_chnl(adapter, freq,
10291 						   POLICY_MGR_UPDATE_REASON_SET_OPER_CHAN)) {
10292 		hdd_err("Failed to change hw mode");
10293 		return -EINVAL;
10294 	}
10295 
10296 	if (adapter->monitor_mode_vdev_up_in_progress) {
10297 		hdd_err_rl("monitor mode vdev up in progress");
10298 		return -EBUSY;
10299 	}
10300 
10301 	status = qdf_event_reset(&adapter->qdf_monitor_mode_vdev_up_event);
10302 	if (QDF_IS_STATUS_ERROR(status)) {
10303 		hdd_err_rl("failed to reinit monitor mode vdev up event");
10304 		return qdf_status_to_os_return(status);
10305 	}
10306 	adapter->monitor_mode_vdev_up_in_progress = true;
10307 
10308 	qdf_mem_zero(&ch_params, sizeof(struct ch_params));
10309 
10310 	req = qdf_mem_malloc(sizeof(struct channel_change_req));
10311 	if (!req)
10312 		return -ENOMEM;
10313 	req->vdev_id = adapter->deflink->vdev_id;
10314 	req->target_chan_freq = freq;
10315 	req->ch_width = ch_width;
10316 
10317 	ch_params.ch_width = ch_width;
10318 	hdd_select_cbmode(adapter, freq, 0, &ch_params);
10319 
10320 	req->sec_ch_offset = ch_params.sec_ch_offset;
10321 	req->center_freq_seg0 = ch_params.center_freq_seg0;
10322 	req->center_freq_seg1 = ch_params.center_freq_seg1;
10323 
10324 	sme_fill_channel_change_request(hdd_ctx->mac_handle, req,
10325 					ch_info->phy_mode);
10326 	status = sme_send_channel_change_req(hdd_ctx->mac_handle, req);
10327 	qdf_mem_free(req);
10328 	if (status) {
10329 		hdd_err("Status: %d Failed to set sme_roam Channel for monitor mode",
10330 			status);
10331 		adapter->monitor_mode_vdev_up_in_progress = false;
10332 		return qdf_status_to_os_return(status);
10333 	}
10334 
10335 	adapter->mon_chan_freq = freq;
10336 	adapter->mon_bandwidth = bandwidth;
10337 
10338 	/* block on a completion variable until vdev up success*/
10339 	status = qdf_wait_for_event_completion(
10340 				       &adapter->qdf_monitor_mode_vdev_up_event,
10341 					WLAN_MONITOR_MODE_VDEV_UP_EVT);
10342 	if (QDF_IS_STATUS_ERROR(status)) {
10343 		hdd_err_rl("monitor vdev up event time out vdev id: %d",
10344 			    adapter->deflink->vdev_id);
10345 		if (adapter->qdf_monitor_mode_vdev_up_event.force_set)
10346 			/*
10347 			 * SSR/PDR has caused shutdown, which has
10348 			 * forcefully set the event.
10349 			 */
10350 			hdd_err_rl("monitor mode vdev up event forcefully set");
10351 		else if (status == QDF_STATUS_E_TIMEOUT)
10352 			hdd_err("monitor mode vdev up timed out");
10353 		else
10354 			hdd_err_rl("Failed monitor mode vdev up(status-%d)",
10355 				  status);
10356 
10357 		adapter->monitor_mode_vdev_up_in_progress = false;
10358 	}
10359 
10360 	return qdf_status_to_os_return(status);
10361 }
10362 #endif
10363 
10364 #if defined MSM_PLATFORM && (LINUX_VERSION_CODE <= KERNEL_VERSION(4, 19, 0))
10365 /**
10366  * hdd_stop_p2p_go() - call cfg80211 API to stop P2P GO
10367  * @adapter: pointer to adapter
10368  *
10369  * This function calls cfg80211 API to stop P2P GO
10370  *
10371  * Return: None
10372  */
10373 static void hdd_stop_p2p_go(struct hdd_adapter *adapter)
10374 {
10375 	hdd_debug("[SSR] send stop ap to supplicant");
10376 	cfg80211_ap_stopped(adapter->dev, GFP_KERNEL);
10377 }
10378 
10379 static inline void hdd_delete_sta(struct hdd_adapter *adapter)
10380 {
10381 }
10382 
10383 #else
10384 static void hdd_stop_p2p_go(struct hdd_adapter *adapter)
10385 {
10386 	hdd_debug("[SSR] send stop iface ap to supplicant");
10387 	cfg80211_stop_iface(adapter->hdd_ctx->wiphy, &adapter->wdev,
10388 			    GFP_KERNEL);
10389 }
10390 
10391 /**
10392  * hdd_delete_sta() - call cfg80211 API to delete STA
10393  * @adapter: pointer to adapter
10394  *
10395  * This function calls cfg80211 API to delete STA
10396  *
10397  * Return: None
10398  */
10399 static void hdd_delete_sta(struct hdd_adapter *adapter)
10400 {
10401 	struct qdf_mac_addr bcast_mac = QDF_MAC_ADDR_BCAST_INIT;
10402 
10403 	hdd_debug("[SSR] send restart supplicant");
10404 	/* event supplicant to restart */
10405 	cfg80211_del_sta(adapter->dev,
10406 			 (const u8 *)&bcast_mac.bytes[0],
10407 			 GFP_KERNEL);
10408 }
10409 #endif
10410 
10411 QDF_STATUS hdd_start_all_adapters(struct hdd_context *hdd_ctx, bool rtnl_held)
10412 {
10413 	struct hdd_adapter *adapter, *next_adapter = NULL;
10414 	bool value;
10415 	wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_START_ALL_ADAPTERS;
10416 	int ret;
10417 
10418 	hdd_enter();
10419 
10420 	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
10421 					   dbgid) {
10422 		if (!hdd_is_interface_up(adapter) &&
10423 		    adapter->device_mode != QDF_NDI_MODE) {
10424 			hdd_adapter_dev_put_debug(adapter, dbgid);
10425 			continue;
10426 		}
10427 
10428 		hdd_debug("[SSR] start adapter with device mode %s(%d)",
10429 			  qdf_opmode_str(adapter->device_mode),
10430 			  adapter->device_mode);
10431 
10432 		hdd_wmm_dscp_initial_state(adapter);
10433 
10434 		switch (adapter->device_mode) {
10435 		case QDF_STA_MODE:
10436 		case QDF_P2P_CLIENT_MODE:
10437 		case QDF_P2P_DEVICE_MODE:
10438 		case QDF_NAN_DISC_MODE:
10439 
10440 			ret = hdd_start_station_adapter(adapter);
10441 			if (ret) {
10442 				hdd_err("[SSR] Failed to start station adapter: %d",
10443 					ret);
10444 				hdd_adapter_dev_put_debug(adapter, dbgid);
10445 				continue;
10446 			}
10447 			if (adapter->device_mode == QDF_STA_MODE) {
10448 				ret = hdd_start_link_adapter(adapter);
10449 				if (ret) {
10450 					hdd_err("[SSR] Failed to start link adapter: %d",
10451 						ret);
10452 					hdd_stop_adapter(hdd_ctx, adapter);
10453 					hdd_adapter_dev_put_debug(adapter,
10454 								  dbgid);
10455 					continue;
10456 				}
10457 			}
10458 
10459 			/* Open the gates for HDD to receive Wext commands */
10460 			adapter->is_link_up_service_needed = false;
10461 
10462 			if ((adapter->device_mode == QDF_NAN_DISC_MODE ||
10463 			     (adapter->device_mode == QDF_STA_MODE &&
10464 			      !ucfg_nan_is_vdev_creation_allowed(
10465 							hdd_ctx->psoc))) &&
10466 			    cds_is_driver_recovering())
10467 				ucfg_nan_disable_ind_to_userspace(
10468 							hdd_ctx->psoc);
10469 
10470 			hdd_register_tx_flow_control(adapter,
10471 					hdd_tx_resume_timer_expired_handler,
10472 					hdd_tx_resume_cb,
10473 					hdd_tx_flow_control_is_pause);
10474 
10475 			hdd_register_hl_netdev_fc_timer(
10476 					adapter,
10477 					hdd_tx_resume_timer_expired_handler);
10478 
10479 			hdd_lpass_notify_start(adapter->deflink);
10480 			break;
10481 
10482 		case QDF_SAP_MODE:
10483 			ucfg_mlme_get_sap_internal_restart(hdd_ctx->psoc,
10484 							   &value);
10485 			if (value)
10486 				hdd_start_ap_adapter(adapter, rtnl_held);
10487 
10488 			break;
10489 
10490 		case QDF_P2P_GO_MODE:
10491 			hdd_delete_sta(adapter);
10492 			break;
10493 		case QDF_MONITOR_MODE:
10494 			if (wlan_hdd_is_session_type_monitor(
10495 			    adapter->device_mode) &&
10496 			    ucfg_pkt_capture_get_mode(hdd_ctx->psoc) !=
10497 						PACKET_CAPTURE_MODE_DISABLE) {
10498 				struct hdd_adapter *sta_adapter;
10499 
10500 				sta_adapter = hdd_get_adapter(hdd_ctx,
10501 							      QDF_STA_MODE);
10502 				if (!sta_adapter) {
10503 					hdd_err("No station interface found");
10504 					return -EINVAL;
10505 				}
10506 
10507 				hdd_map_monitor_interface_vdev(sta_adapter);
10508 				break;
10509 			}
10510 			hdd_start_station_adapter(adapter);
10511 			hdd_set_mon_rx_cb(adapter->dev);
10512 
10513 			wlan_hdd_set_mon_chan(
10514 					adapter, adapter->mon_chan_freq,
10515 					adapter->mon_bandwidth);
10516 			break;
10517 		case QDF_NDI_MODE:
10518 			hdd_ndi_start(adapter->dev->name, 0);
10519 			break;
10520 		default:
10521 			break;
10522 		}
10523 		/*
10524 		 * Action frame registered in one adapter which will
10525 		 * applicable to all interfaces
10526 		 */
10527 		if (hdd_set_fw_params(adapter))
10528 			hdd_err("Failed to set adapter FW params after SSR!");
10529 
10530 		wlan_hdd_cfg80211_register_frames(adapter);
10531 		hdd_create_adapter_sysfs_files(adapter);
10532 		hdd_adapter_dev_put_debug(adapter, dbgid);
10533 	}
10534 
10535 	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
10536 					   dbgid) {
10537 		if (!hdd_is_interface_up(adapter)) {
10538 			hdd_adapter_dev_put_debug(adapter, dbgid);
10539 			continue;
10540 		}
10541 
10542 		if (adapter->device_mode == QDF_P2P_GO_MODE)
10543 			hdd_stop_p2p_go(adapter);
10544 
10545 		hdd_adapter_dev_put_debug(adapter, dbgid);
10546 	}
10547 
10548 	hdd_exit();
10549 
10550 	return QDF_STATUS_SUCCESS;
10551 }
10552 
10553 void hdd_adapter_dev_hold_debug(struct hdd_adapter *adapter,
10554 				wlan_net_dev_ref_dbgid dbgid)
10555 {
10556 	if (dbgid >= NET_DEV_HOLD_ID_MAX) {
10557 		hdd_err("Invalid debug id: %d", dbgid);
10558 		QDF_BUG(0);
10559 	}
10560 	dev_hold(adapter->dev);
10561 	qdf_atomic_inc(&adapter->net_dev_hold_ref_count[dbgid]);
10562 }
10563 
10564 void hdd_adapter_dev_put_debug(struct hdd_adapter *adapter,
10565 			       wlan_net_dev_ref_dbgid dbgid)
10566 {
10567 	if (dbgid >= NET_DEV_HOLD_ID_MAX) {
10568 		hdd_err("Invalid debug id: %d", dbgid);
10569 		QDF_BUG(0);
10570 	}
10571 
10572 	if (qdf_atomic_dec_return(
10573 			&adapter->net_dev_hold_ref_count[dbgid]) < 0) {
10574 		hdd_err("dev_put detected without dev_hold for debug id: %s",
10575 			net_dev_ref_debug_string_from_id(dbgid));
10576 		QDF_BUG(0);
10577 	}
10578 
10579 	if (adapter->dev) {
10580 		dev_put(adapter->dev);
10581 	} else {
10582 		hdd_err("adapter->dev is NULL");
10583 		QDF_BUG(0);
10584 	}
10585 }
10586 
10587 QDF_STATUS hdd_get_front_adapter(struct hdd_context *hdd_ctx,
10588 				 struct hdd_adapter **out_adapter)
10589 {
10590 	QDF_STATUS status;
10591 	qdf_list_node_t *node;
10592 
10593 	*out_adapter = NULL;
10594 
10595 	qdf_spin_lock_bh(&hdd_ctx->hdd_adapter_lock);
10596 	status = qdf_list_peek_front(&hdd_ctx->hdd_adapters, &node);
10597 	qdf_spin_unlock_bh(&hdd_ctx->hdd_adapter_lock);
10598 
10599 	if (QDF_IS_STATUS_ERROR(status))
10600 		return status;
10601 
10602 	*out_adapter = qdf_container_of(node, struct hdd_adapter, node);
10603 
10604 	return QDF_STATUS_SUCCESS;
10605 }
10606 
10607 QDF_STATUS hdd_get_next_adapter(struct hdd_context *hdd_ctx,
10608 				struct hdd_adapter *current_adapter,
10609 				struct hdd_adapter **out_adapter)
10610 {
10611 	QDF_STATUS status;
10612 	qdf_list_node_t *node;
10613 
10614 	*out_adapter = NULL;
10615 
10616 	qdf_spin_lock_bh(&hdd_ctx->hdd_adapter_lock);
10617 	status = qdf_list_peek_next(&hdd_ctx->hdd_adapters,
10618 				    &current_adapter->node,
10619 				    &node);
10620 	qdf_spin_unlock_bh(&hdd_ctx->hdd_adapter_lock);
10621 
10622 	if (QDF_IS_STATUS_ERROR(status))
10623 		return status;
10624 
10625 	*out_adapter = qdf_container_of(node, struct hdd_adapter, node);
10626 
10627 	return status;
10628 }
10629 
10630 QDF_STATUS hdd_get_front_adapter_no_lock(struct hdd_context *hdd_ctx,
10631 					 struct hdd_adapter **out_adapter)
10632 {
10633 	QDF_STATUS status;
10634 	qdf_list_node_t *node;
10635 
10636 	*out_adapter = NULL;
10637 
10638 	status = qdf_list_peek_front(&hdd_ctx->hdd_adapters, &node);
10639 
10640 	if (QDF_IS_STATUS_ERROR(status))
10641 		return status;
10642 
10643 	*out_adapter = qdf_container_of(node, struct hdd_adapter, node);
10644 
10645 	return QDF_STATUS_SUCCESS;
10646 }
10647 
10648 QDF_STATUS hdd_get_next_adapter_no_lock(struct hdd_context *hdd_ctx,
10649 					struct hdd_adapter *current_adapter,
10650 					struct hdd_adapter **out_adapter)
10651 {
10652 	QDF_STATUS status;
10653 	qdf_list_node_t *node;
10654 
10655 	if (!current_adapter)
10656 		return QDF_STATUS_E_INVAL;
10657 
10658 	*out_adapter = NULL;
10659 
10660 	status = qdf_list_peek_next(&hdd_ctx->hdd_adapters,
10661 				    &current_adapter->node,
10662 				    &node);
10663 
10664 	if (QDF_IS_STATUS_ERROR(status))
10665 		return status;
10666 
10667 	*out_adapter = qdf_container_of(node, struct hdd_adapter, node);
10668 
10669 	return status;
10670 }
10671 
10672 QDF_STATUS hdd_remove_adapter(struct hdd_context *hdd_ctx,
10673 			      struct hdd_adapter *adapter)
10674 {
10675 	QDF_STATUS status;
10676 
10677 	qdf_spin_lock_bh(&hdd_ctx->hdd_adapter_lock);
10678 	status = qdf_list_remove_node(&hdd_ctx->hdd_adapters, &adapter->node);
10679 	qdf_spin_unlock_bh(&hdd_ctx->hdd_adapter_lock);
10680 
10681 	return status;
10682 }
10683 
10684 QDF_STATUS hdd_remove_front_adapter(struct hdd_context *hdd_ctx,
10685 				    struct hdd_adapter **out_adapter)
10686 {
10687 	QDF_STATUS status;
10688 	qdf_list_node_t *node;
10689 
10690 	*out_adapter = NULL;
10691 
10692 	qdf_spin_lock_bh(&hdd_ctx->hdd_adapter_lock);
10693 	status = qdf_list_remove_front(&hdd_ctx->hdd_adapters, &node);
10694 	qdf_spin_unlock_bh(&hdd_ctx->hdd_adapter_lock);
10695 
10696 	if (QDF_IS_STATUS_ERROR(status))
10697 		return status;
10698 
10699 	*out_adapter = qdf_container_of(node, struct hdd_adapter, node);
10700 
10701 	return status;
10702 }
10703 
10704 QDF_STATUS hdd_add_adapter_back(struct hdd_context *hdd_ctx,
10705 				struct hdd_adapter *adapter)
10706 {
10707 	QDF_STATUS status;
10708 
10709 	qdf_spin_lock_bh(&hdd_ctx->hdd_adapter_lock);
10710 	status = qdf_list_insert_back(&hdd_ctx->hdd_adapters, &adapter->node);
10711 	qdf_spin_unlock_bh(&hdd_ctx->hdd_adapter_lock);
10712 
10713 	return status;
10714 }
10715 
10716 QDF_STATUS hdd_add_adapter_front(struct hdd_context *hdd_ctx,
10717 				 struct hdd_adapter *adapter)
10718 {
10719 	QDF_STATUS status;
10720 
10721 	qdf_spin_lock_bh(&hdd_ctx->hdd_adapter_lock);
10722 	status = qdf_list_insert_front(&hdd_ctx->hdd_adapters, &adapter->node);
10723 	qdf_spin_unlock_bh(&hdd_ctx->hdd_adapter_lock);
10724 
10725 	return status;
10726 }
10727 
10728 void hdd_validate_next_adapter(struct hdd_adapter **curr,
10729 			       struct hdd_adapter **next,
10730 			       wlan_net_dev_ref_dbgid dbg_id)
10731 {
10732 	if (!*curr || !*next || *curr != *next)
10733 		return;
10734 
10735 	hdd_err("Validation failed");
10736 	hdd_adapter_dev_put_debug(*curr, dbg_id);
10737 	*curr = NULL;
10738 	*next = NULL;
10739 }
10740 
10741 QDF_STATUS hdd_adapter_iterate(hdd_adapter_iterate_cb cb, void *context)
10742 {
10743 	struct hdd_context *hdd_ctx;
10744 	struct hdd_adapter *cache[HDD_MAX_ADAPTERS];
10745 	struct hdd_adapter *adapter;
10746 	uint32_t n_cache = 0;
10747 	QDF_STATUS ret = QDF_STATUS_SUCCESS;
10748 	QDF_STATUS status;
10749 	int i;
10750 	struct wlan_hdd_link_info *link_info;
10751 
10752 	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
10753 	if (unlikely(!hdd_ctx))
10754 		return QDF_STATUS_E_FAILURE;
10755 
10756 	qdf_spin_lock_bh(&hdd_ctx->hdd_adapter_lock);
10757 	for (hdd_get_front_adapter_no_lock(hdd_ctx, &adapter); adapter;
10758 	     hdd_get_next_adapter_no_lock(hdd_ctx, adapter, &adapter)) {
10759 		cache[n_cache++] = adapter;
10760 	}
10761 	qdf_spin_unlock_bh(&hdd_ctx->hdd_adapter_lock);
10762 
10763 	for (i = 0; i < n_cache; i++) {
10764 		adapter = hdd_adapter_get_by_reference(hdd_ctx, cache[i]);
10765 		if (!adapter) {
10766 			/*
10767 			 * detected remove while iterating
10768 			 * concurrency failure
10769 			 */
10770 			ret = QDF_STATUS_E_FAILURE;
10771 			continue;
10772 		}
10773 		hdd_adapter_for_each_active_link_info(adapter, link_info) {
10774 			status = cb(link_info, context);
10775 			if (status != QDF_STATUS_SUCCESS) {
10776 				hdd_adapter_put(adapter);
10777 				return status;
10778 			}
10779 		}
10780 		hdd_adapter_put(adapter);
10781 	}
10782 
10783 	return ret;
10784 }
10785 
10786 struct hdd_adapter *hdd_get_adapter_by_rand_macaddr(
10787 	struct hdd_context *hdd_ctx, tSirMacAddr mac_addr)
10788 {
10789 	struct hdd_adapter *adapter, *next_adapter = NULL;
10790 	wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_GET_ADAPTER_BY_RAND_MACADDR;
10791 	struct wlan_hdd_link_info *link_info;
10792 
10793 	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
10794 					   dbgid) {
10795 		if (adapter->device_mode != QDF_STA_MODE &&
10796 		    adapter->device_mode != QDF_P2P_CLIENT_MODE &&
10797 		    adapter->device_mode != QDF_P2P_DEVICE_MODE) {
10798 			hdd_adapter_dev_put_debug(adapter, dbgid);
10799 			continue;
10800 		}
10801 
10802 		hdd_adapter_for_each_active_link_info(adapter, link_info) {
10803 			if (ucfg_p2p_check_random_mac(hdd_ctx->psoc,
10804 						      link_info->vdev_id,
10805 						      mac_addr)) {
10806 				hdd_adapter_dev_put_debug(adapter, dbgid);
10807 				if (next_adapter)
10808 					hdd_adapter_dev_put_debug(next_adapter,
10809 								  dbgid);
10810 				return adapter;
10811 			}
10812 		}
10813 		hdd_adapter_dev_put_debug(adapter, dbgid);
10814 	}
10815 
10816 	return NULL;
10817 }
10818 
10819 #ifdef WLAN_HDD_MULTI_VDEV_SINGLE_NDEV
10820 struct hdd_adapter *hdd_get_adapter_by_macaddr(struct hdd_context *hdd_ctx,
10821 					       tSirMacAddr mac_addr)
10822 {
10823 	struct hdd_adapter *adapter, *next_adapter = NULL;
10824 	wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_GET_ADAPTER_BY_MACADDR;
10825 	struct qdf_mac_addr zero_mac_addr = QDF_MAC_ADDR_ZERO_INIT;
10826 	struct wlan_hdd_link_info *link_info;
10827 
10828 	if (!qdf_mem_cmp(mac_addr, zero_mac_addr.bytes, sizeof(tSirMacAddr)))
10829 		return NULL;
10830 
10831 	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
10832 					   dbgid) {
10833 		if (!qdf_mem_cmp(adapter->mac_addr.bytes,
10834 				 mac_addr, sizeof(tSirMacAddr))) {
10835 			hdd_adapter_dev_put_debug(adapter, dbgid);
10836 			if (next_adapter)
10837 				hdd_adapter_dev_put_debug(next_adapter,
10838 							  dbgid);
10839 			return adapter;
10840 		}
10841 		hdd_adapter_for_each_active_link_info(adapter, link_info) {
10842 			if (!qdf_mem_cmp(link_info->link_addr.bytes,
10843 					 mac_addr, sizeof(tSirMacAddr))) {
10844 				hdd_adapter_dev_put_debug(adapter, dbgid);
10845 				if (next_adapter)
10846 					hdd_adapter_dev_put_debug(next_adapter,
10847 								  dbgid);
10848 				return adapter;
10849 			}
10850 		}
10851 		hdd_adapter_dev_put_debug(adapter, dbgid);
10852 	}
10853 
10854 	return NULL;
10855 }
10856 
10857 struct wlan_hdd_link_info *
10858 hdd_get_link_info_by_link_addr(struct hdd_context *hdd_ctx,
10859 			       struct qdf_mac_addr *link_addr)
10860 {
10861 	struct wlan_hdd_link_info *link_info;
10862 	struct hdd_adapter *adapter, *next_adapter = NULL;
10863 	wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_GET_ADAPTER_BY_MACADDR;
10864 
10865 	if (!link_addr || qdf_is_macaddr_zero(link_addr))
10866 		return NULL;
10867 
10868 	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
10869 					   dbgid) {
10870 		hdd_adapter_for_each_link_info(adapter, link_info) {
10871 			if (qdf_is_macaddr_equal(link_addr,
10872 						 &link_info->link_addr)) {
10873 				hdd_adapter_dev_put_debug(adapter, dbgid);
10874 				if (next_adapter)
10875 					hdd_adapter_dev_put_debug(next_adapter,
10876 								  dbgid);
10877 				return link_info;
10878 			}
10879 		}
10880 		hdd_adapter_dev_put_debug(adapter, dbgid);
10881 	}
10882 
10883 	return NULL;
10884 }
10885 #else
10886 struct hdd_adapter *hdd_get_adapter_by_macaddr(struct hdd_context *hdd_ctx,
10887 					       tSirMacAddr mac_addr)
10888 {
10889 	struct hdd_adapter *adapter, *next_adapter = NULL;
10890 	wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_GET_ADAPTER_BY_MACADDR;
10891 
10892 	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
10893 					   dbgid) {
10894 		if (!qdf_mem_cmp(adapter->mac_addr.bytes,
10895 				 mac_addr, sizeof(tSirMacAddr))) {
10896 			hdd_adapter_dev_put_debug(adapter, dbgid);
10897 			if (next_adapter)
10898 				hdd_adapter_dev_put_debug(next_adapter,
10899 							  dbgid);
10900 			return adapter;
10901 		}
10902 
10903 		if (hdd_adapter_is_sl_ml_adapter(adapter) &&
10904 		    !qdf_mem_cmp(adapter->mld_addr.bytes,
10905 				 mac_addr, sizeof(tSirMacAddr))) {
10906 			hdd_adapter_dev_put_debug(adapter, dbgid);
10907 			if (next_adapter)
10908 				hdd_adapter_dev_put_debug(next_adapter, dbgid);
10909 			return adapter;
10910 		}
10911 		hdd_adapter_dev_put_debug(adapter, dbgid);
10912 	}
10913 
10914 	return NULL;
10915 }
10916 
10917 struct wlan_hdd_link_info *
10918 hdd_get_link_info_by_link_addr(struct hdd_context *hdd_ctx,
10919 			       struct qdf_mac_addr *link_addr)
10920 {
10921 	return NULL;
10922 }
10923 #endif
10924 
10925 struct wlan_hdd_link_info *
10926 hdd_get_link_info_by_vdev(struct hdd_context *hdd_ctx, uint32_t vdev_id)
10927 {
10928 	struct hdd_adapter *adapter, *next_adapter = NULL;
10929 	wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_GET_ADAPTER_BY_VDEV;
10930 	struct wlan_hdd_link_info *link_info;
10931 
10932 	if (vdev_id == WLAN_INVALID_VDEV_ID)
10933 		return NULL;
10934 
10935 	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
10936 					   dbgid) {
10937 		hdd_adapter_for_each_active_link_info(adapter, link_info) {
10938 			if (link_info->vdev_id == vdev_id) {
10939 				hdd_adapter_dev_put_debug(adapter, dbgid);
10940 				if (next_adapter)
10941 					hdd_adapter_dev_put_debug(next_adapter,
10942 								  dbgid);
10943 				return link_info;
10944 			}
10945 		}
10946 		hdd_adapter_dev_put_debug(adapter, dbgid);
10947 	}
10948 
10949 	return NULL;
10950 }
10951 
10952 struct hdd_adapter *hdd_adapter_get_by_reference(struct hdd_context *hdd_ctx,
10953 						 struct hdd_adapter *reference)
10954 {
10955 	struct hdd_adapter *adapter, *next_adapter = NULL;
10956 	wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_ADAPTER_GET_BY_REFERENCE;
10957 
10958 	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
10959 					   dbgid) {
10960 		if (adapter == reference) {
10961 			dev_hold(adapter->dev);
10962 			hdd_adapter_dev_put_debug(adapter, dbgid);
10963 			if (next_adapter)
10964 				hdd_adapter_dev_put_debug(next_adapter,
10965 							  dbgid);
10966 			break;
10967 		}
10968 		hdd_adapter_dev_put_debug(adapter, dbgid);
10969 	}
10970 
10971 	return adapter;
10972 }
10973 
10974 void hdd_adapter_put(struct hdd_adapter *adapter)
10975 {
10976 	dev_put(adapter->dev);
10977 }
10978 
10979 struct hdd_adapter *hdd_get_adapter_by_iface_name(struct hdd_context *hdd_ctx,
10980 					     const char *iface_name)
10981 {
10982 	struct hdd_adapter *adapter, *next_adapter = NULL;
10983 	wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_GET_ADAPTER_BY_IFACE_NAME;
10984 
10985 	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
10986 					   dbgid) {
10987 		if (!qdf_str_cmp(adapter->dev->name, iface_name)) {
10988 			hdd_adapter_dev_put_debug(adapter, dbgid);
10989 			if (next_adapter)
10990 				hdd_adapter_dev_put_debug(next_adapter,
10991 							  dbgid);
10992 			return adapter;
10993 		}
10994 		hdd_adapter_dev_put_debug(adapter, dbgid);
10995 	}
10996 
10997 	return NULL;
10998 }
10999 
11000 struct hdd_adapter *hdd_get_adapter_by_ifindex(struct hdd_context *hdd_ctx,
11001 					       uint32_t if_index)
11002 {
11003 	struct hdd_adapter *adapter, *next_adapter = NULL;
11004 	wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_GET_ADAPTER;
11005 
11006 	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
11007 					   dbgid) {
11008 		if (adapter->dev->ifindex == if_index) {
11009 			hdd_adapter_dev_put_debug(adapter, dbgid);
11010 			if (next_adapter)
11011 				hdd_adapter_dev_put_debug(next_adapter,
11012 							  dbgid);
11013 			return adapter;
11014 		}
11015 		hdd_adapter_dev_put_debug(adapter, dbgid);
11016 	}
11017 
11018 	return NULL;
11019 }
11020 
11021 /**
11022  * hdd_get_adapter() - to get adapter matching the mode
11023  * @hdd_ctx: hdd context
11024  * @mode: adapter mode
11025  *
11026  * This routine will return the pointer to adapter matching
11027  * with the passed mode.
11028  *
11029  * Return: pointer to adapter or null
11030  */
11031 struct hdd_adapter *hdd_get_adapter(struct hdd_context *hdd_ctx,
11032 			enum QDF_OPMODE mode)
11033 {
11034 	struct hdd_adapter *adapter, *next_adapter = NULL;
11035 	wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_GET_ADAPTER;
11036 
11037 	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
11038 					   dbgid) {
11039 		if (adapter->device_mode == mode) {
11040 			hdd_adapter_dev_put_debug(adapter, dbgid);
11041 			if (next_adapter)
11042 				hdd_adapter_dev_put_debug(next_adapter,
11043 							  dbgid);
11044 			return adapter;
11045 		}
11046 		hdd_adapter_dev_put_debug(adapter, dbgid);
11047 	}
11048 
11049 	return NULL;
11050 }
11051 
11052 enum QDF_OPMODE hdd_get_device_mode(uint32_t vdev_id)
11053 {
11054 	struct hdd_context *hdd_ctx;
11055 	struct wlan_hdd_link_info *link_info;
11056 
11057 	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
11058 	if (!hdd_ctx)
11059 		return QDF_MAX_NO_OF_MODE;
11060 
11061 	link_info = hdd_get_link_info_by_vdev(hdd_ctx, vdev_id);
11062 	if (!link_info) {
11063 		hdd_err("Invalid vdev");
11064 		return QDF_MAX_NO_OF_MODE;
11065 	}
11066 
11067 	return link_info->adapter->device_mode;
11068 }
11069 
11070 uint32_t hdd_get_operating_chan_freq(struct hdd_context *hdd_ctx,
11071 				     enum QDF_OPMODE mode)
11072 {
11073 	struct hdd_adapter *adapter, *next_adapter = NULL;
11074 	uint32_t oper_chan_freq = 0;
11075 	wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_GET_OPERATING_CHAN_FREQ;
11076 
11077 	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
11078 					   dbgid) {
11079 		if (mode == adapter->device_mode) {
11080 			oper_chan_freq =
11081 			    hdd_get_link_info_home_channel(adapter->deflink);
11082 			hdd_adapter_dev_put_debug(adapter, dbgid);
11083 			if (next_adapter)
11084 				hdd_adapter_dev_put_debug(next_adapter,
11085 							  dbgid);
11086 			break;
11087 		}
11088 		hdd_adapter_dev_put_debug(adapter, dbgid);
11089 	}
11090 
11091 	return oper_chan_freq;
11092 }
11093 
11094 static inline QDF_STATUS hdd_unregister_wext_all_adapters(
11095 		struct hdd_context *hdd_ctx,
11096 		bool rtnl_held)
11097 {
11098 	struct hdd_adapter *adapter, *next_adapter = NULL;
11099 	wlan_net_dev_ref_dbgid dbgid =
11100 				NET_DEV_HOLD_UNREGISTER_WEXT_ALL_ADAPTERS;
11101 
11102 	hdd_enter();
11103 
11104 	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
11105 					   dbgid) {
11106 		if (adapter->device_mode == QDF_STA_MODE ||
11107 		    adapter->device_mode == QDF_P2P_CLIENT_MODE ||
11108 		    adapter->device_mode == QDF_P2P_DEVICE_MODE ||
11109 		    adapter->device_mode == QDF_SAP_MODE ||
11110 		    adapter->device_mode == QDF_P2P_GO_MODE) {
11111 			hdd_wext_unregister(adapter->dev, rtnl_held);
11112 		}
11113 		hdd_adapter_dev_put_debug(adapter, dbgid);
11114 	}
11115 
11116 	hdd_exit();
11117 
11118 	return QDF_STATUS_SUCCESS;
11119 }
11120 
11121 QDF_STATUS hdd_abort_mac_scan_all_adapters(struct hdd_context *hdd_ctx)
11122 {
11123 	struct hdd_adapter *adapter, *next_adapter = NULL;
11124 	wlan_net_dev_ref_dbgid dbgid =
11125 				NET_DEV_HOLD_ABORT_MAC_SCAN_ALL_ADAPTERS;
11126 	struct wlan_hdd_link_info *link_info;
11127 
11128 	hdd_enter();
11129 
11130 	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
11131 					   dbgid) {
11132 		if (adapter->device_mode == QDF_STA_MODE ||
11133 		    adapter->device_mode == QDF_P2P_CLIENT_MODE ||
11134 		    adapter->device_mode == QDF_P2P_DEVICE_MODE ||
11135 		    adapter->device_mode == QDF_SAP_MODE ||
11136 		    adapter->device_mode == QDF_P2P_GO_MODE) {
11137 			hdd_adapter_for_each_active_link_info(adapter,
11138 							      link_info) {
11139 				wlan_abort_scan(hdd_ctx->pdev, INVAL_PDEV_ID,
11140 						link_info->vdev_id,
11141 						INVALID_SCAN_ID, true);
11142 			}
11143 		}
11144 		hdd_adapter_dev_put_debug(adapter, dbgid);
11145 	}
11146 
11147 	hdd_exit();
11148 
11149 	return QDF_STATUS_SUCCESS;
11150 }
11151 
11152 /**
11153  * hdd_abort_sched_scan_all_adapters() - stops scheduled (PNO) scans for all
11154  * adapters
11155  * @hdd_ctx: The HDD context containing the adapters to operate on
11156  *
11157  * return: QDF_STATUS_SUCCESS
11158  */
11159 static QDF_STATUS hdd_abort_sched_scan_all_adapters(struct hdd_context *hdd_ctx)
11160 {
11161 	struct hdd_adapter *adapter, *next_adapter = NULL;
11162 	int err;
11163 	wlan_net_dev_ref_dbgid dbgid =
11164 				NET_DEV_HOLD_ABORT_SCHED_SCAN_ALL_ADAPTERS;
11165 
11166 	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
11167 					   dbgid) {
11168 		if (adapter->device_mode == QDF_STA_MODE ||
11169 		    adapter->device_mode == QDF_P2P_CLIENT_MODE ||
11170 		    adapter->device_mode == QDF_P2P_DEVICE_MODE ||
11171 		    adapter->device_mode == QDF_SAP_MODE ||
11172 		    adapter->device_mode == QDF_P2P_GO_MODE) {
11173 			err = wlan_hdd_sched_scan_stop(adapter->dev);
11174 			if (err)
11175 				hdd_err("Unable to stop scheduled scan");
11176 		}
11177 		hdd_adapter_dev_put_debug(adapter, dbgid);
11178 	}
11179 
11180 	return QDF_STATUS_SUCCESS;
11181 }
11182 
11183 /**
11184  * hdd_unregister_notifiers - Unregister netdev notifiers.
11185  * @hdd_ctx: HDD context
11186  *
11187  * Unregister netdev notifiers like IPv4 and IPv6.
11188  *
11189  * Return: None.
11190  */
11191 void hdd_unregister_notifiers(struct hdd_context *hdd_ctx)
11192 {
11193 	osif_dp_nud_unregister_netevent_notifier(hdd_ctx->psoc);
11194 	hdd_wlan_unregister_ip6_notifier(hdd_ctx);
11195 
11196 	unregister_inetaddr_notifier(&hdd_ctx->ipv4_notifier);
11197 }
11198 
11199 /**
11200  * hdd_exit_netlink_services - Exit netlink services
11201  * @hdd_ctx: HDD context
11202  *
11203  * Exit netlink services like cnss_diag, cesium netlink socket, ptt socket and
11204  * nl service.
11205  *
11206  * Return: None.
11207  */
11208 static void hdd_exit_netlink_services(struct hdd_context *hdd_ctx)
11209 {
11210 	spectral_scan_deactivate_service();
11211 	cnss_diag_deactivate_service();
11212 	hdd_close_cesium_nl_sock();
11213 	ptt_sock_deactivate_svc();
11214 	hdd_deactivate_wifi_pos();
11215 
11216 	nl_srv_exit();
11217 }
11218 
11219 /**
11220  * hdd_init_netlink_services- Init netlink services
11221  * @hdd_ctx: HDD context
11222  *
11223  * Init netlink services like cnss_diag, cesium netlink socket, ptt socket and
11224  * nl service.
11225  *
11226  * Return: 0 on success and errno on failure.
11227  */
11228 static int hdd_init_netlink_services(struct hdd_context *hdd_ctx)
11229 {
11230 	int ret;
11231 
11232 	ret = wlan_hdd_nl_init(hdd_ctx);
11233 	if (ret) {
11234 		hdd_err("nl_srv_init failed: %d", ret);
11235 		goto out;
11236 	}
11237 	cds_set_radio_index(hdd_ctx->radio_index);
11238 
11239 	ret = hdd_activate_wifi_pos(hdd_ctx);
11240 	if (ret) {
11241 		hdd_err("hdd_activate_wifi_pos failed: %d", ret);
11242 		goto err_nl_srv;
11243 	}
11244 
11245 	ptt_sock_activate_svc();
11246 
11247 	ret = hdd_open_cesium_nl_sock();
11248 	if (ret)
11249 		hdd_err("hdd_open_cesium_nl_sock failed ret: %d", ret);
11250 
11251 	ret = cnss_diag_activate_service();
11252 	if (ret) {
11253 		hdd_err("cnss_diag_activate_service failed: %d", ret);
11254 		goto err_close_cesium;
11255 	}
11256 
11257 	spectral_scan_activate_service(hdd_ctx);
11258 
11259 	return 0;
11260 
11261 err_close_cesium:
11262 	hdd_close_cesium_nl_sock();
11263 	ptt_sock_deactivate_svc();
11264 	hdd_deactivate_wifi_pos();
11265 err_nl_srv:
11266 	nl_srv_exit();
11267 out:
11268 	return ret;
11269 }
11270 
11271 #ifdef SHUTDOWN_WLAN_IN_SYSTEM_SUSPEND
11272 static QDF_STATUS
11273 hdd_shutdown_wlan_in_suspend_prepare(struct hdd_context *hdd_ctx)
11274 {
11275 #define SHUTDOWN_IN_SUSPEND_RETRY 30
11276 
11277 	int count = 0;
11278 	enum pmo_suspend_mode mode;
11279 
11280 	if (hdd_ctx->driver_status != DRIVER_MODULES_ENABLED) {
11281 		hdd_debug("Driver Modules not Enabled ");
11282 		return 0;
11283 	}
11284 
11285 	mode = ucfg_pmo_get_suspend_mode(hdd_ctx->psoc);
11286 	hdd_debug("suspend mode is %d", mode);
11287 
11288 	if (mode == PMO_SUSPEND_NONE || mode == PMO_SUSPEND_LEGENCY) {
11289 		hdd_debug("needn't shutdown in suspend");
11290 		return 0;
11291 	}
11292 
11293 	if (!hdd_is_any_interface_open(hdd_ctx)) {
11294 		return pld_idle_shutdown(hdd_ctx->parent_dev,
11295 					 hdd_psoc_idle_shutdown);
11296 	} else {
11297 		if (mode == PMO_SUSPEND_WOW)
11298 			return 0;
11299 	}
11300 
11301 	/*try to wait interface down for PMO_SUSPEND_SHUTDOWN mode*/
11302 	while (hdd_is_any_interface_open(hdd_ctx) &&
11303 	       count < SHUTDOWN_IN_SUSPEND_RETRY) {
11304 		count++;
11305 		hdd_debug_rl("sleep 50ms to wait adapters stopped, #%d", count);
11306 		msleep(50);
11307 	}
11308 	if (count >= SHUTDOWN_IN_SUSPEND_RETRY) {
11309 		hdd_err("some adapters not stopped");
11310 		return -EBUSY;
11311 	}
11312 	return pld_idle_shutdown(hdd_ctx->parent_dev, hdd_psoc_idle_shutdown);
11313 }
11314 
11315 static int hdd_pm_notify(struct notifier_block *b,
11316 			 unsigned long event, void *p)
11317 {
11318 	struct hdd_context *hdd_ctx = container_of(b, struct hdd_context,
11319 						   pm_notifier);
11320 
11321 	if (wlan_hdd_validate_context(hdd_ctx) != 0)
11322 		return NOTIFY_STOP;
11323 
11324 	hdd_debug("got PM event: %lu", event);
11325 
11326 	switch (event) {
11327 	case PM_SUSPEND_PREPARE:
11328 	case PM_HIBERNATION_PREPARE:
11329 		if (0 != hdd_shutdown_wlan_in_suspend_prepare(hdd_ctx))
11330 			return NOTIFY_STOP;
11331 		break;
11332 	case PM_POST_SUSPEND:
11333 	case PM_POST_HIBERNATION:
11334 		break;
11335 	}
11336 
11337 	return NOTIFY_DONE;
11338 }
11339 
11340 static void hdd_pm_notifier_init(struct hdd_context *hdd_ctx)
11341 {
11342 	hdd_ctx->pm_notifier.notifier_call = hdd_pm_notify;
11343 	register_pm_notifier(&hdd_ctx->pm_notifier);
11344 }
11345 
11346 static void hdd_pm_notifier_deinit(struct hdd_context *hdd_ctx)
11347 {
11348 	unregister_pm_notifier(&hdd_ctx->pm_notifier);
11349 }
11350 #else
11351 static inline void hdd_pm_notifier_init(struct hdd_context *hdd_ctx)
11352 {
11353 }
11354 
11355 static inline void hdd_pm_notifier_deinit(struct hdd_context *hdd_ctx)
11356 {
11357 }
11358 #endif
11359 
11360 /**
11361  * hdd_context_deinit() - Deinitialize HDD context
11362  * @hdd_ctx:    HDD context.
11363  *
11364  * Deinitialize HDD context along with all the feature specific contexts but
11365  * do not free hdd context itself. Caller of this API is supposed to free
11366  * HDD context.
11367  *
11368  * return: 0 on success and errno on failure.
11369  */
11370 static int hdd_context_deinit(struct hdd_context *hdd_ctx)
11371 {
11372 	hdd_lpc_delete_work(hdd_ctx);
11373 
11374 	qdf_wake_lock_destroy(&hdd_ctx->monitor_mode_wakelock);
11375 
11376 	wlan_hdd_cfg80211_deinit(hdd_ctx->wiphy);
11377 
11378 	ucfg_dp_bbm_context_deinit(hdd_ctx->psoc);
11379 
11380 	hdd_sap_context_destroy(hdd_ctx);
11381 
11382 	hdd_scan_context_destroy(hdd_ctx);
11383 
11384 	qdf_list_destroy(&hdd_ctx->hdd_adapters);
11385 
11386 	return 0;
11387 }
11388 
11389 void hdd_context_destroy(struct hdd_context *hdd_ctx)
11390 {
11391 	wlan_hdd_sar_timers_deinit(hdd_ctx);
11392 
11393 	cds_set_context(QDF_MODULE_ID_HDD, NULL);
11394 
11395 	hdd_exit_netlink_services(hdd_ctx);
11396 
11397 	hdd_context_deinit(hdd_ctx);
11398 
11399 	hdd_objmgr_release_and_destroy_psoc(hdd_ctx);
11400 
11401 	qdf_mem_free(hdd_ctx->config);
11402 	hdd_ctx->config = NULL;
11403 	cfg_release();
11404 
11405 	hdd_pm_notifier_deinit(hdd_ctx);
11406 	qdf_delayed_work_destroy(&hdd_ctx->psoc_idle_timeout_work);
11407 	wiphy_free(hdd_ctx->wiphy);
11408 }
11409 
11410 /**
11411  * wlan_destroy_bug_report_lock() - Destroy bug report lock
11412  *
11413  * This function is used to destroy bug report lock
11414  *
11415  * Return: None
11416  */
11417 static void wlan_destroy_bug_report_lock(void)
11418 {
11419 	struct cds_context *p_cds_context;
11420 
11421 	p_cds_context = cds_get_global_context();
11422 	if (!p_cds_context) {
11423 		hdd_err("cds context is NULL");
11424 		return;
11425 	}
11426 
11427 	qdf_spinlock_destroy(&p_cds_context->bug_report_lock);
11428 }
11429 
11430 #ifdef DISABLE_CHANNEL_LIST
11431 static void wlan_hdd_cache_chann_mutex_destroy(struct hdd_context *hdd_ctx)
11432 {
11433 	qdf_mutex_destroy(&hdd_ctx->cache_channel_lock);
11434 }
11435 #else
11436 static void wlan_hdd_cache_chann_mutex_destroy(struct hdd_context *hdd_ctx)
11437 {
11438 }
11439 #endif
11440 
11441 void hdd_wlan_exit(struct hdd_context *hdd_ctx)
11442 {
11443 	struct wiphy *wiphy = hdd_ctx->wiphy;
11444 
11445 	hdd_enter();
11446 
11447 	ucfg_dp_wait_complete_tasks();
11448 	wlan_hdd_destroy_mib_stats_lock();
11449 	hdd_debugfs_ini_config_deinit(hdd_ctx);
11450 	hdd_debugfs_mws_coex_info_deinit(hdd_ctx);
11451 	hdd_psoc_idle_timer_stop(hdd_ctx);
11452 	hdd_regulatory_deinit(hdd_ctx);
11453 
11454 	/*
11455 	 * Powersave Offload Case
11456 	 * Disable Idle Power Save Mode
11457 	 */
11458 	hdd_set_idle_ps_config(hdd_ctx, false);
11459 	/* clear the scan queue in all the scenarios */
11460 	wlan_cfg80211_cleanup_scan_queue(hdd_ctx->pdev, NULL);
11461 
11462 	if (hdd_ctx->driver_status != DRIVER_MODULES_CLOSED) {
11463 		hdd_unregister_wext_all_adapters(hdd_ctx, false);
11464 		/*
11465 		 * Cancel any outstanding scan requests.  We are about to close
11466 		 * all of our adapters, but an adapter structure is what SME
11467 		 * passes back to our callback function.  Hence if there
11468 		 * are any outstanding scan requests then there is a
11469 		 * race condition between when the adapter is closed and
11470 		 * when the callback is invoked.  We try to resolve that
11471 		 * race condition here by canceling any outstanding scans
11472 		 * before we close the adapters.
11473 		 * Note that the scans may be cancelled in an asynchronous
11474 		 * manner, so ideally there needs to be some kind of
11475 		 * synchronization.  Rather than introduce a new
11476 		 * synchronization here, we will utilize the fact that we are
11477 		 * about to Request Full Power, and since that is synchronized,
11478 		 * the expectation is that by the time Request Full Power has
11479 		 * completed, all scans will be cancelled
11480 		 */
11481 		hdd_abort_mac_scan_all_adapters(hdd_ctx);
11482 		hdd_abort_sched_scan_all_adapters(hdd_ctx);
11483 
11484 		hdd_stop_all_adapters(hdd_ctx);
11485 		hdd_deinit_all_adapters(hdd_ctx, false);
11486 	}
11487 
11488 	unregister_netdevice_notifier(&hdd_netdev_notifier);
11489 
11490 	qdf_dp_trace_deinit();
11491 
11492 	hdd_wlan_stop_modules(hdd_ctx, false);
11493 
11494 	hdd_driver_memdump_deinit();
11495 
11496 	qdf_nbuf_deinit_replenish_timer();
11497 
11498 	if (QDF_GLOBAL_MONITOR_MODE ==  hdd_get_conparam()) {
11499 		hdd_info("Release wakelock for monitor mode!");
11500 		qdf_wake_lock_release(&hdd_ctx->monitor_mode_wakelock,
11501 				      WIFI_POWER_EVENT_WAKELOCK_MONITOR_MODE);
11502 	}
11503 
11504 	qdf_spinlock_destroy(&hdd_ctx->hdd_adapter_lock);
11505 	qdf_spinlock_destroy(&hdd_ctx->connection_status_lock);
11506 	wlan_hdd_cache_chann_mutex_destroy(hdd_ctx);
11507 
11508 	osif_request_manager_deinit();
11509 
11510 	hdd_close_all_adapters(hdd_ctx, false);
11511 
11512 	wlansap_global_deinit();
11513 	/*
11514 	 * If there is re_init failure wiphy would have already de-registered
11515 	 * check the wiphy status before un-registering again
11516 	 */
11517 	if (wiphy && wiphy->registered) {
11518 		wiphy_unregister(wiphy);
11519 		wlan_hdd_cfg80211_deinit(wiphy);
11520 		hdd_lpass_notify_stop(hdd_ctx);
11521 	}
11522 
11523 	hdd_deinit_regulatory_update_event(hdd_ctx);
11524 	hdd_exit_netlink_services(hdd_ctx);
11525 #ifdef FEATURE_WLAN_CH_AVOID
11526 	mutex_destroy(&hdd_ctx->avoid_freq_lock);
11527 #endif
11528 
11529 	/* This function should be invoked at the end of this api*/
11530 	hdd_dump_func_call_map();
11531 }
11532 
11533 /**
11534  * hdd_wlan_notify_modem_power_state() - notify FW with modem power status
11535  * @state: state
11536  *
11537  * This function notifies FW with modem power status
11538  *
11539  * Return: 0 if successful, error number otherwise
11540  */
11541 int hdd_wlan_notify_modem_power_state(int state)
11542 {
11543 	int status;
11544 	QDF_STATUS qdf_status;
11545 	struct hdd_context *hdd_ctx;
11546 	mac_handle_t mac_handle;
11547 
11548 	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
11549 	status = wlan_hdd_validate_context(hdd_ctx);
11550 	if (status)
11551 		return status;
11552 
11553 	mac_handle = hdd_ctx->mac_handle;
11554 	if (!mac_handle)
11555 		return -EINVAL;
11556 
11557 	qdf_status = sme_notify_modem_power_state(mac_handle, state);
11558 	if (QDF_STATUS_SUCCESS != qdf_status) {
11559 		hdd_err("Fail to send notification with modem power state %d",
11560 		       state);
11561 		return -EINVAL;
11562 	}
11563 	return 0;
11564 }
11565 
11566 /**
11567  * hdd_post_cds_enable_config() - HDD post cds start config helper
11568  * @hdd_ctx: Pointer to the HDD
11569  *
11570  * Return: None
11571  */
11572 QDF_STATUS hdd_post_cds_enable_config(struct hdd_context *hdd_ctx)
11573 {
11574 	QDF_STATUS qdf_ret_status;
11575 
11576 	/*
11577 	 * Send ready indication to the HDD.  This will kick off the MAC
11578 	 * into a 'running' state and should kick off an initial scan.
11579 	 */
11580 	qdf_ret_status = sme_hdd_ready_ind(hdd_ctx->mac_handle);
11581 	if (!QDF_IS_STATUS_SUCCESS(qdf_ret_status)) {
11582 		hdd_err("sme_hdd_ready_ind() failed with status code %08d [x%08x]",
11583 			qdf_ret_status, qdf_ret_status);
11584 		return QDF_STATUS_E_FAILURE;
11585 	}
11586 
11587 	return QDF_STATUS_SUCCESS;
11588 }
11589 
11590 struct hdd_adapter *hdd_get_first_valid_adapter(struct hdd_context *hdd_ctx)
11591 {
11592 	struct hdd_adapter *adapter, *next_adapter = NULL;
11593 	wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_GET_FIRST_VALID_ADAPTER;
11594 
11595 	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
11596 					   dbgid) {
11597 		if (adapter && adapter->magic == WLAN_HDD_ADAPTER_MAGIC) {
11598 			hdd_adapter_dev_put_debug(adapter, dbgid);
11599 			if (next_adapter)
11600 				hdd_adapter_dev_put_debug(next_adapter,
11601 							  dbgid);
11602 			return adapter;
11603 		}
11604 		hdd_adapter_dev_put_debug(adapter, dbgid);
11605 	}
11606 
11607 	return NULL;
11608 }
11609 
11610 /* wake lock APIs for HDD */
11611 void hdd_prevent_suspend(uint32_t reason)
11612 {
11613 	qdf_wake_lock_acquire(&wlan_wake_lock, reason);
11614 }
11615 
11616 void hdd_allow_suspend(uint32_t reason)
11617 {
11618 	qdf_wake_lock_release(&wlan_wake_lock, reason);
11619 }
11620 
11621 void hdd_prevent_suspend_timeout(uint32_t timeout, uint32_t reason)
11622 {
11623 	cds_host_diag_log_work(&wlan_wake_lock, timeout, reason);
11624 	qdf_wake_lock_timeout_acquire(&wlan_wake_lock, timeout);
11625 }
11626 
11627 /* Initialize channel list in sme based on the country code */
11628 QDF_STATUS hdd_set_sme_chan_list(struct hdd_context *hdd_ctx)
11629 {
11630 	return sme_init_chan_list(hdd_ctx->mac_handle,
11631 				  hdd_ctx->reg.cc_src);
11632 }
11633 
11634 /**
11635  * hdd_is_5g_supported() - check if hardware supports 5GHz
11636  * @hdd_ctx:	Pointer to the hdd context
11637  *
11638  * HDD function to know if hardware supports 5GHz
11639  *
11640  * Return:  true if hardware supports 5GHz
11641  */
11642 bool hdd_is_5g_supported(struct hdd_context *hdd_ctx)
11643 {
11644 	if (!hdd_ctx)
11645 		return true;
11646 
11647 	if (hdd_ctx->curr_band != BAND_2G)
11648 		return true;
11649 	else
11650 		return false;
11651 }
11652 
11653 bool hdd_is_2g_supported(struct hdd_context *hdd_ctx)
11654 {
11655 	if (!hdd_ctx)
11656 		return false;
11657 
11658 	if (hdd_ctx->curr_band != BAND_5G)
11659 		return true;
11660 	else
11661 		return false;
11662 }
11663 
11664 static int hdd_wiphy_init(struct hdd_context *hdd_ctx)
11665 {
11666 	struct wiphy *wiphy;
11667 	int ret_val;
11668 	uint32_t channel_bonding_mode;
11669 
11670 	wiphy = hdd_ctx->wiphy;
11671 
11672 	/*
11673 	 * The channel information in
11674 	 * wiphy needs to be initialized before wiphy registration
11675 	 */
11676 	ret_val = hdd_regulatory_init(hdd_ctx, wiphy);
11677 	if (ret_val) {
11678 		hdd_err("regulatory init failed");
11679 		return ret_val;
11680 	}
11681 
11682 	if (ucfg_pmo_get_suspend_mode(hdd_ctx->psoc) == PMO_SUSPEND_WOW) {
11683 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
11684 		wiphy->wowlan = &wowlan_support_reg_init;
11685 #else
11686 		wiphy->wowlan.flags = WIPHY_WOWLAN_ANY |
11687 				      WIPHY_WOWLAN_MAGIC_PKT |
11688 				      WIPHY_WOWLAN_DISCONNECT |
11689 				      WIPHY_WOWLAN_SUPPORTS_GTK_REKEY |
11690 				      WIPHY_WOWLAN_GTK_REKEY_FAILURE |
11691 				      WIPHY_WOWLAN_EAP_IDENTITY_REQ |
11692 				      WIPHY_WOWLAN_4WAY_HANDSHAKE |
11693 				      WIPHY_WOWLAN_RFKILL_RELEASE;
11694 
11695 		wiphy->wowlan.n_patterns = (WOW_MAX_FILTER_LISTS *
11696 				    WOW_MAX_FILTERS_PER_LIST);
11697 		wiphy->wowlan.pattern_min_len = WOW_MIN_PATTERN_SIZE;
11698 		wiphy->wowlan.pattern_max_len = WOW_MAX_PATTERN_SIZE;
11699 #endif
11700 	}
11701 
11702 	ucfg_mlme_get_channel_bonding_24ghz(hdd_ctx->psoc,
11703 					    &channel_bonding_mode);
11704 	if (hdd_ctx->obss_scan_offload) {
11705 		hdd_debug("wmi_service_obss_scan supported");
11706 	} else if (channel_bonding_mode) {
11707 		hdd_debug("enable wpa_supp obss_scan");
11708 		wiphy->features |= NL80211_FEATURE_NEED_OBSS_SCAN;
11709 	}
11710 
11711 	if (hdd_ctx->num_rf_chains == HDD_ANTENNA_MODE_2X2 &&
11712 	    ucfg_mlme_is_chain_mask_supported(hdd_ctx->psoc)) {
11713 		wiphy->available_antennas_tx = HDD_CHAIN_MODE_2X2;
11714 		wiphy->available_antennas_rx = HDD_CHAIN_MODE_2X2;
11715 	}
11716 	/* registration of wiphy dev with cfg80211 */
11717 	ret_val = wlan_hdd_cfg80211_register(wiphy);
11718 	if (0 > ret_val) {
11719 		hdd_err("wiphy registration failed");
11720 		return ret_val;
11721 	}
11722 
11723 	/* Check the kernel version for upstream commit aced43ce780dc5 that
11724 	 * has support for processing user cell_base hints when wiphy is
11725 	 * self managed or check the backport flag for the same.
11726 	 */
11727 #if defined CFG80211_USER_HINT_CELL_BASE_SELF_MANAGED ||	\
11728 		(LINUX_VERSION_CODE >= KERNEL_VERSION(4, 18, 0))
11729 	hdd_send_wiphy_regd_sync_event(hdd_ctx);
11730 #endif
11731 
11732 	pld_increment_driver_load_cnt(hdd_ctx->parent_dev);
11733 
11734 	return ret_val;
11735 }
11736 
11737 #ifdef WLAN_FEATURE_DP_BUS_BANDWIDTH
11738 #ifdef CLD_PM_QOS
11739 #define PLD_REMOVE_PM_QOS(x)
11740 #define PLD_REQUEST_PM_QOS(x, y)
11741 #define HDD_PM_QOS_HIGH_TPUT_LATENCY_US 1
11742 
11743 /**
11744  * hdd_pm_qos_update_cpu_mask() - Prepare CPU mask for PM_qos voting
11745  * @mask: return variable of cpumask for the TPUT
11746  * @enable_perf_cluster: Enable PERF cluster or not
11747  *
11748  * By default, the function sets CPU mask for silver cluster unless
11749  * enable_perf_cluster is set as true.
11750  *
11751  * Return: none
11752  */
11753 static inline void hdd_pm_qos_update_cpu_mask(cpumask_t *mask,
11754 					      bool enable_perf_cluster)
11755 {
11756 	cpumask_set_cpu(0, mask);
11757 	cpumask_set_cpu(1, mask);
11758 	cpumask_set_cpu(2, mask);
11759 	cpumask_set_cpu(3, mask);
11760 
11761 	if (enable_perf_cluster) {
11762 		cpumask_set_cpu(4, mask);
11763 		cpumask_set_cpu(5, mask);
11764 		cpumask_set_cpu(6, mask);
11765 	}
11766 }
11767 
11768 #ifdef MSM_PLATFORM
11769 #define COPY_CPU_MASK(a, b) cpumask_copy(a, b)
11770 #define DUMP_CPU_AFFINE() hdd_info("Set cpu_mask %*pb for affine_cores", \
11771 			  cpumask_pr_args(&hdd_ctx->pm_qos_req.cpus_affine))
11772 #else
11773 #define COPY_CPU_MASK(a, b) /* no-op*/
11774 #define DUMP_CPU_AFFINE() /* no-op*/
11775 #endif
11776 
11777 #ifdef CLD_DEV_PM_QOS
11778 
11779 static inline void _hdd_pm_qos_update_request(struct hdd_context *hdd_ctx,
11780 					      cpumask_t *pm_qos_cpu_mask,
11781 					      unsigned int latency)
11782 {
11783 	int cpu;
11784 	uint32_t default_latency;
11785 
11786 	default_latency = wlan_hdd_get_default_pm_qos_cpu_latency();
11787 	qdf_cpumask_copy(&hdd_ctx->qos_cpu_mask, pm_qos_cpu_mask);
11788 
11789 	if (qdf_cpumask_empty(pm_qos_cpu_mask)) {
11790 		for_each_present_cpu(cpu) {
11791 			dev_pm_qos_update_request(
11792 				&hdd_ctx->pm_qos_req[cpu],
11793 				default_latency);
11794 		}
11795 		hdd_debug("Empty mask %*pb: Set latency %u",
11796 			  qdf_cpumask_pr_args(&hdd_ctx->qos_cpu_mask),
11797 			  default_latency);
11798 	} else { /* Set latency to default for CPUs not included in mask */
11799 		qdf_for_each_cpu_not(cpu, &hdd_ctx->qos_cpu_mask) {
11800 			dev_pm_qos_update_request(
11801 				&hdd_ctx->pm_qos_req[cpu],
11802 				default_latency);
11803 		}
11804 		/* Set latency for CPUs included in mask */
11805 		qdf_for_each_cpu(cpu, &hdd_ctx->qos_cpu_mask) {
11806 			dev_pm_qos_update_request(
11807 				&hdd_ctx->pm_qos_req[cpu],
11808 				latency);
11809 		}
11810 		hdd_debug("For qos_cpu_mask %*pb set latency %u",
11811 			  qdf_cpumask_pr_args(&hdd_ctx->qos_cpu_mask),
11812 			  latency);
11813 	}
11814 }
11815 
11816 /**
11817  * hdd_pm_qos_update_request() - API to request for pm_qos
11818  * @hdd_ctx: handle to hdd context
11819  * @pm_qos_cpu_mask: cpu_mask to apply
11820  *
11821  * Return: none
11822  */
11823 static void hdd_pm_qos_update_request(struct hdd_context *hdd_ctx,
11824 				      cpumask_t *pm_qos_cpu_mask)
11825 {
11826 	unsigned int latency;
11827 
11828 	if (qdf_cpumask_empty(pm_qos_cpu_mask))
11829 		latency = wlan_hdd_get_default_pm_qos_cpu_latency();
11830 	else
11831 		latency = HDD_PM_QOS_HIGH_TPUT_LATENCY_US;
11832 
11833 	_hdd_pm_qos_update_request(hdd_ctx, pm_qos_cpu_mask, latency);
11834 }
11835 
11836 static inline void hdd_pm_qos_add_request(struct hdd_context *hdd_ctx)
11837 {
11838 	struct device *cpu_dev;
11839 	int cpu;
11840 	uint32_t default_latency = wlan_hdd_get_default_pm_qos_cpu_latency();
11841 
11842 
11843 	qdf_cpumask_clear(&hdd_ctx->qos_cpu_mask);
11844 	hdd_pm_qos_update_cpu_mask(&hdd_ctx->qos_cpu_mask, false);
11845 
11846 	for_each_present_cpu(cpu) {
11847 		cpu_dev = get_cpu_device(cpu);
11848 		dev_pm_qos_add_request(cpu_dev, &hdd_ctx->pm_qos_req[cpu],
11849 				       DEV_PM_QOS_RESUME_LATENCY,
11850 				       default_latency);
11851 		hdd_debug("Set qos_cpu_mask %*pb for affine_cores",
11852 			 cpumask_pr_args(&hdd_ctx->qos_cpu_mask));
11853 	}
11854 }
11855 
11856 static inline void hdd_pm_qos_remove_request(struct hdd_context *hdd_ctx)
11857 {
11858 	int cpu;
11859 
11860 	for_each_present_cpu(cpu) {
11861 		dev_pm_qos_remove_request(&hdd_ctx->pm_qos_req[cpu]);
11862 		hdd_debug("Remove dev_pm_qos_request for all cpus: %d", cpu);
11863 	}
11864 	qdf_cpumask_clear(&hdd_ctx->qos_cpu_mask);
11865 }
11866 
11867 #else /* CLD_DEV_PM_QOS */
11868 
11869 #if defined(CONFIG_SMP) && defined(MSM_PLATFORM)
11870 /**
11871  * hdd_set_default_pm_qos_mask() - Update PM_qos request for AFFINE_CORES
11872  * @hdd_ctx: handle to hdd context
11873  *
11874  * Return: none
11875  */
11876 static inline void hdd_set_default_pm_qos_mask(struct hdd_context *hdd_ctx)
11877 {
11878 	hdd_ctx->pm_qos_req.type = PM_QOS_REQ_AFFINE_CORES;
11879 	qdf_cpumask_clear(&hdd_ctx->pm_qos_req.cpus_affine);
11880 	hdd_pm_qos_update_cpu_mask(&hdd_ctx->pm_qos_req.cpus_affine, false);
11881 }
11882 #else
11883 static inline void hdd_set_default_pm_qos_mask(struct hdd_context *hdd_ctx)
11884 {
11885 }
11886 #endif
11887 
11888 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 7, 0))
11889 /**
11890  * hdd_pm_qos_update_request() - API to request for pm_qos
11891  * @hdd_ctx: handle to hdd context
11892  * @pm_qos_cpu_mask: cpu_mask to apply
11893  *
11894  * Return: none
11895  */
11896 static inline void hdd_pm_qos_update_request(struct hdd_context *hdd_ctx,
11897 					     cpumask_t *pm_qos_cpu_mask)
11898 {
11899 	COPY_CPU_MASK(&hdd_ctx->pm_qos_req.cpus_affine, pm_qos_cpu_mask);
11900 
11901 	if (cpumask_empty(pm_qos_cpu_mask))
11902 		cpu_latency_qos_update_request(&hdd_ctx->pm_qos_req,
11903 					       PM_QOS_DEFAULT_VALUE);
11904 	else
11905 		cpu_latency_qos_update_request(&hdd_ctx->pm_qos_req, 1);
11906 }
11907 
11908 static inline void hdd_pm_qos_add_request(struct hdd_context *hdd_ctx)
11909 {
11910 	hdd_set_default_pm_qos_mask(hdd_ctx);
11911 	cpu_latency_qos_add_request(&hdd_ctx->pm_qos_req, PM_QOS_DEFAULT_VALUE);
11912 	DUMP_CPU_AFFINE();
11913 }
11914 
11915 static inline void hdd_pm_qos_remove_request(struct hdd_context *hdd_ctx)
11916 {
11917 	cpu_latency_qos_remove_request(&hdd_ctx->pm_qos_req);
11918 }
11919 #else
11920 static inline void hdd_pm_qos_update_request(struct hdd_context *hdd_ctx,
11921 					     cpumask_t *pm_qos_cpu_mask)
11922 {
11923 	COPY_CPU_MASK(&hdd_ctx->pm_qos_req.cpus_affine, pm_qos_cpu_mask);
11924 
11925 	if (cpumask_empty(pm_qos_cpu_mask))
11926 		pm_qos_update_request(&hdd_ctx->pm_qos_req,
11927 				      PM_QOS_DEFAULT_VALUE);
11928 	else
11929 		pm_qos_update_request(&hdd_ctx->pm_qos_req, 1);
11930 }
11931 
11932 static inline void hdd_pm_qos_add_request(struct hdd_context *hdd_ctx)
11933 {
11934 	hdd_set_default_pm_qos_mask(hdd_ctx);
11935 	pm_qos_add_request(&hdd_ctx->pm_qos_req, PM_QOS_CPU_DMA_LATENCY,
11936 			   PM_QOS_DEFAULT_VALUE);
11937 	DUMP_CPU_AFFINE();
11938 }
11939 
11940 static inline void hdd_pm_qos_remove_request(struct hdd_context *hdd_ctx)
11941 {
11942 	pm_qos_remove_request(&hdd_ctx->pm_qos_req);
11943 }
11944 #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(5, 7, 0) */
11945 #endif /* CLD_DEV_PM_QOS */
11946 
11947 #else /* CLD_PM_QOS */
11948 #define PLD_REMOVE_PM_QOS(x) pld_remove_pm_qos(x)
11949 #define PLD_REQUEST_PM_QOS(x, y) pld_request_pm_qos(x, y)
11950 
11951 static inline void hdd_pm_qos_add_request(struct hdd_context *hdd_ctx)
11952 {
11953 }
11954 
11955 static inline void hdd_pm_qos_remove_request(struct hdd_context *hdd_ctx)
11956 {
11957 }
11958 
11959 static inline void hdd_pm_qos_update_cpu_mask(cpumask_t *mask,
11960 					      bool high_throughput)
11961 {
11962 }
11963 
11964 static inline void hdd_pm_qos_update_request(struct hdd_context *hdd_ctx,
11965 					     cpumask_t *pm_qos_cpu_mask)
11966 {
11967 }
11968 #endif /* CLD_PM_QOS */
11969 
11970 #if defined(CLD_PM_QOS)
11971 #if defined(CLD_DEV_PM_QOS)
11972 void wlan_hdd_set_pm_qos_request(struct hdd_context *hdd_ctx,
11973 				 bool pm_qos_request)
11974 {
11975 	cpumask_t pm_qos_cpu_mask;
11976 
11977 	cpumask_clear(&pm_qos_cpu_mask);
11978 	if (pm_qos_request) {
11979 		hdd_ctx->pm_qos_request = true;
11980 		if (!hdd_ctx->hbw_requested) {
11981 			hdd_pm_qos_update_cpu_mask(&pm_qos_cpu_mask, true);
11982 			hdd_pm_qos_update_request(hdd_ctx, &pm_qos_cpu_mask);
11983 			hdd_ctx->hbw_requested = true;
11984 		}
11985 	} else {
11986 		if (hdd_ctx->hbw_requested) {
11987 			hdd_pm_qos_update_cpu_mask(&pm_qos_cpu_mask, false);
11988 			hdd_pm_qos_update_request(hdd_ctx, &pm_qos_cpu_mask);
11989 			hdd_ctx->hbw_requested = false;
11990 		}
11991 		hdd_ctx->pm_qos_request = false;
11992 	}
11993 }
11994 #else /* CLD_DEV_PM_QOS */
11995 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 7, 0))
11996 void wlan_hdd_set_pm_qos_request(struct hdd_context *hdd_ctx,
11997 				 bool pm_qos_request)
11998 {
11999 	if (pm_qos_request) {
12000 		hdd_ctx->pm_qos_request = true;
12001 		if (!hdd_ctx->hbw_requested) {
12002 			cpumask_setall(&hdd_ctx->pm_qos_req.cpus_affine);
12003 			cpu_latency_qos_update_request(
12004 				&hdd_ctx->pm_qos_req,
12005 				DISABLE_KRAIT_IDLE_PS_VAL);
12006 			hdd_ctx->hbw_requested = true;
12007 		}
12008 	} else {
12009 		if (hdd_ctx->hbw_requested) {
12010 			cpumask_clear(&hdd_ctx->pm_qos_req.cpus_affine);
12011 			cpu_latency_qos_update_request(&hdd_ctx->pm_qos_req,
12012 						       PM_QOS_DEFAULT_VALUE);
12013 			hdd_ctx->hbw_requested = false;
12014 		}
12015 		hdd_ctx->pm_qos_request = false;
12016 	}
12017 }
12018 #else /* (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 7, 0)) */
12019 void wlan_hdd_set_pm_qos_request(struct hdd_context *hdd_ctx,
12020 				 bool pm_qos_request)
12021 {
12022 	if (pm_qos_request) {
12023 		hdd_ctx->pm_qos_request = true;
12024 		if (!hdd_ctx->hbw_requested) {
12025 			cpumask_setall(&hdd_ctx->pm_qos_req.cpus_affine);
12026 			pm_qos_update_request(&hdd_ctx->pm_qos_req,
12027 					      DISABLE_KRAIT_IDLE_PS_VAL);
12028 			hdd_ctx->hbw_requested = true;
12029 		}
12030 	} else {
12031 		if (hdd_ctx->hbw_requested) {
12032 			cpumask_clear(&hdd_ctx->pm_qos_req.cpus_affine);
12033 			pm_qos_update_request(&hdd_ctx->pm_qos_req,
12034 					      PM_QOS_DEFAULT_VALUE);
12035 			hdd_ctx->hbw_requested = false;
12036 		}
12037 		hdd_ctx->pm_qos_request = false;
12038 	}
12039 }
12040 #endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 7, 0)) */
12041 #endif /* CLD_DEV_PM_QOS*/
12042 #endif /* CLD_PM_QOS */
12043 
12044 #define HDD_BW_GET_DIFF(_x, _y) (unsigned long)((ULONG_MAX - (_y)) + (_x) + 1)
12045 
12046 #ifdef WLAN_FEATURE_MSCS
12047 
12048 static
12049 void hdd_send_mscs_action_frame(struct wlan_hdd_link_info *link_info)
12050 {
12051 	struct hdd_context *hdd_ctx = link_info->adapter->hdd_ctx;
12052 	uint64_t mscs_vo_pkt_delta;
12053 	unsigned long tx_vo_pkts = 0;
12054 	unsigned int cpu;
12055 	struct hdd_tx_rx_stats *stats = &link_info->hdd_stats.tx_rx_stats;
12056 	uint32_t bus_bw_compute_interval;
12057 
12058 	/*
12059 	 * To disable MSCS feature in driver set mscs_pkt_threshold = 0
12060 	 * in ini file.
12061 	 */
12062 	if (!hdd_ctx->config->mscs_pkt_threshold)
12063 		return;
12064 
12065 	for (cpu = 0; cpu < NUM_CPUS; cpu++)
12066 		tx_vo_pkts += stats->per_cpu[cpu].tx_classified_ac[SME_AC_VO];
12067 
12068 	if (!link_info->mscs_counter)
12069 		link_info->mscs_prev_tx_vo_pkts = tx_vo_pkts;
12070 
12071 	link_info->mscs_counter++;
12072 	bus_bw_compute_interval =
12073 		ucfg_dp_get_bus_bw_compute_interval(hdd_ctx->psoc);
12074 	if (link_info->mscs_counter * bus_bw_compute_interval >=
12075 	    hdd_ctx->config->mscs_voice_interval * 1000) {
12076 		link_info->mscs_counter = 0;
12077 		mscs_vo_pkt_delta =
12078 			HDD_BW_GET_DIFF(tx_vo_pkts,
12079 					link_info->mscs_prev_tx_vo_pkts);
12080 		if (mscs_vo_pkt_delta > hdd_ctx->config->mscs_pkt_threshold &&
12081 		    !mlme_get_is_mscs_req_sent(link_info->vdev))
12082 			sme_send_mscs_action_frame(link_info->vdev_id);
12083 	}
12084 }
12085 #else
12086 static inline
12087 void hdd_send_mscs_action_frame(struct wlan_hdd_link_info *link_info)
12088 {
12089 }
12090 #endif
12091 #endif /*WLAN_FEATURE_DP_BUS_BANDWIDTH*/
12092 
12093 /**
12094  * wlan_hdd_sta_get_dot11mode() - GET AP client count
12095  * @context: HDD context
12096  * @netdev: netdev
12097  * @dot11_mode: variable in which mode need to update.
12098  *
12099  * Return: true on success else false
12100  */
12101 static inline
12102 bool wlan_hdd_sta_get_dot11mode(hdd_cb_handle context, qdf_netdev_t netdev,
12103 				enum qca_wlan_802_11_mode *dot11_mode)
12104 {
12105 	struct hdd_context *hdd_ctx;
12106 	struct wlan_hdd_link_info *link_info;
12107 	struct hdd_station_ctx *sta_ctx;
12108 	struct hdd_adapter *adapter;
12109 	enum csr_cfgdot11mode mode;
12110 
12111 	hdd_ctx = hdd_cb_handle_to_context(context);
12112 	if (!hdd_ctx)
12113 		return false;
12114 
12115 	adapter = WLAN_HDD_GET_PRIV_PTR(netdev);
12116 	if (!adapter)
12117 		return false;
12118 
12119 	link_info = adapter->deflink;
12120 
12121 	sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(link_info);
12122 	mode = sta_ctx->conn_info.dot11mode;
12123 	*dot11_mode = hdd_convert_cfgdot11mode_to_80211mode(mode);
12124 	return true;
12125 }
12126 
12127 /**
12128  * wlan_hdd_get_ap_client_count() - GET AP client count
12129  * @context: HDD context
12130  * @netdev: netdev
12131  * @client_count: variable in which number of client need to update.
12132  *
12133  * Return: true on success else false
12134  */
12135 static inline
12136 bool wlan_hdd_get_ap_client_count(hdd_cb_handle context, qdf_netdev_t netdev,
12137 				  uint16_t *client_count)
12138 {
12139 	struct hdd_context *hdd_ctx;
12140 	struct wlan_hdd_link_info *link_info;
12141 	struct hdd_adapter *adapter;
12142 	struct hdd_ap_ctx *ap_ctx;
12143 	enum qca_wlan_802_11_mode i;
12144 
12145 	hdd_ctx = hdd_cb_handle_to_context(context);
12146 	if (!hdd_ctx) {
12147 		hdd_err("hdd ctx is null");
12148 		return false;
12149 	}
12150 
12151 	adapter = WLAN_HDD_GET_PRIV_PTR(netdev);
12152 	if (!adapter) {
12153 		hdd_err("adapter is null");
12154 		return false;
12155 	}
12156 
12157 	link_info = adapter->deflink;
12158 	ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(link_info);
12159 	if (!ap_ctx->ap_active)
12160 		return false;
12161 
12162 	for (i = QCA_WLAN_802_11_MODE_11B; i < QCA_WLAN_802_11_MODE_INVALID;
12163 	     i++)
12164 		client_count[i] = ap_ctx->client_count[i];
12165 
12166 	return true;
12167 }
12168 
12169 /**
12170  * wlan_hdd_sta_ndi_connected() - Check if NDI connected
12171  * @context: HDD context
12172  * @netdev: netdev
12173  *
12174  * Return: true if NDI connected else false
12175  */
12176 static inline
12177 bool wlan_hdd_sta_ndi_connected(hdd_cb_handle context, qdf_netdev_t netdev)
12178 {
12179 	struct hdd_adapter *adapter;
12180 	struct hdd_context *hdd_ctx;
12181 	struct wlan_hdd_link_info *link_info;
12182 	struct hdd_station_ctx *sta_ctx;
12183 
12184 	hdd_ctx = hdd_cb_handle_to_context(context);
12185 	if (!hdd_ctx) {
12186 		hdd_err("hdd_ctx is null");
12187 		return false;
12188 	}
12189 
12190 	adapter = WLAN_HDD_GET_PRIV_PTR(netdev);
12191 	if (!adapter) {
12192 		hdd_err("adapter is null");
12193 		return false;
12194 	}
12195 
12196 	link_info = adapter->deflink;
12197 
12198 	sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(link_info);
12199 	if (sta_ctx->conn_info.conn_state != eConnectionState_NdiConnected)
12200 		return false;
12201 
12202 	return true;
12203 }
12204 
12205 /**
12206  * wlan_hdd_pktlog_enable_disable() - Enable/Disable packet logging
12207  * @context: HDD context
12208  * @enable_disable_flag: Flag to enable/disable
12209  * @user_triggered: triggered through iwpriv
12210  * @size: buffer size to be used for packetlog
12211  *
12212  * Return: 0 on success; error number otherwise
12213  */
12214 static inline
12215 int wlan_hdd_pktlog_enable_disable(hdd_cb_handle context,
12216 				   bool enable_disable_flag,
12217 				   uint8_t user_triggered, int size)
12218 {
12219 	struct hdd_context *hdd_ctx = hdd_cb_handle_to_context(context);
12220 
12221 	if (!hdd_ctx) {
12222 		hdd_err("hdd_ctx is null");
12223 		return -EINVAL;
12224 	}
12225 	return hdd_pktlog_enable_disable(hdd_ctx, enable_disable_flag,
12226 					 user_triggered, size);
12227 }
12228 
12229 /**
12230  * wlan_hdd_is_roaming_in_progress() - Check if roaming is in progress
12231  * @context: HDD context
12232  *
12233  * Return: true if roaming is in progress else false
12234  */
12235 static inline bool wlan_hdd_is_roaming_in_progress(hdd_cb_handle context)
12236 {
12237 	struct hdd_context *hdd_ctx = hdd_cb_handle_to_context(context);
12238 
12239 	if (!hdd_ctx) {
12240 		hdd_err("hdd_ctx is null");
12241 		return false;
12242 	}
12243 	return hdd_is_roaming_in_progress(hdd_ctx);
12244 }
12245 
12246 /**
12247  * hdd_is_ap_active() - Check if AP is active
12248  * @context: HDD context
12249  * @netdev: netdev
12250  *
12251  * Return: true if AP active else false
12252  */
12253 static inline bool hdd_is_ap_active(hdd_cb_handle context, qdf_netdev_t netdev)
12254 {
12255 	struct hdd_adapter *adapter;
12256 	struct hdd_context *hdd_ctx;
12257 	struct wlan_hdd_link_info *link_info;
12258 
12259 	hdd_ctx = hdd_cb_handle_to_context(context);
12260 	if (!hdd_ctx) {
12261 		hdd_err("hdd_ctx is null");
12262 		return false;
12263 	}
12264 
12265 	adapter = WLAN_HDD_GET_PRIV_PTR(netdev);
12266 	if (!adapter) {
12267 		hdd_err("adapter is null");
12268 		return false;
12269 	}
12270 
12271 	link_info = adapter->deflink;
12272 	return WLAN_HDD_GET_AP_CTX_PTR(link_info)->ap_active;
12273 }
12274 
12275 /**
12276  * wlan_hdd_napi_apply_throughput_policy() - Apply NAPI policy
12277  * @context: HDD context
12278  * @tx_packets: tx_packets
12279  * @rx_packets: rx_packets
12280  *
12281  * Return: 0 on success else error code
12282  */
12283 static inline
12284 int wlan_hdd_napi_apply_throughput_policy(hdd_cb_handle context,
12285 					  uint64_t tx_packets,
12286 					  uint64_t rx_packets)
12287 {
12288 	struct hdd_context *hdd_ctx = hdd_cb_handle_to_context(context);
12289 	int rc = 0;
12290 
12291 	if (!hdd_ctx) {
12292 		hdd_err("hdd_ctx is null");
12293 		return 0;
12294 	}
12295 	if (hdd_ctx->config->napi_cpu_affinity_mask)
12296 		rc = hdd_napi_apply_throughput_policy(hdd_ctx, tx_packets,
12297 						      rx_packets);
12298 	return rc;
12299 }
12300 
12301 /**
12302  * hdd_is_link_adapter() - Check if adapter is link adapter
12303  * @context: HDD context
12304  * @vdev_id: Vdev ID
12305  *
12306  * Return: true if link adapter else false
12307  */
12308 static inline bool hdd_is_link_adapter(hdd_cb_handle context, uint8_t vdev_id)
12309 {
12310 	struct hdd_context *hdd_ctx;
12311 	struct wlan_hdd_link_info *link_info;
12312 
12313 	hdd_ctx = hdd_cb_handle_to_context(context);
12314 	if (!hdd_ctx) {
12315 		hdd_err("hdd_ctx is null");
12316 		return false;
12317 	}
12318 
12319 	link_info = hdd_get_link_info_by_vdev(hdd_ctx, vdev_id);
12320 	if (!link_info) {
12321 		hdd_err("Invalid vdev");
12322 		return false;
12323 	}
12324 	return hdd_adapter_is_link_adapter(link_info->adapter);
12325 }
12326 
12327 /**
12328  * hdd_get_pause_map() - Get pause map value
12329  * @context: HDD context
12330  * @netdev: netdev
12331  *
12332  * Return: pause map value
12333  */
12334 static inline
12335 uint32_t hdd_get_pause_map(hdd_cb_handle context, qdf_netdev_t netdev)
12336 {
12337 	struct hdd_adapter *adapter;
12338 
12339 	adapter = WLAN_HDD_GET_PRIV_PTR(netdev);
12340 	if (!adapter) {
12341 		hdd_err("adapter is null");
12342 		return 0;
12343 	}
12344 
12345 	return adapter->pause_map;
12346 }
12347 
12348 /**
12349  * hdd_any_adapter_connected() - Check if any adapter connected.
12350  * @context: HDD context
12351  *
12352  * Return: True if connected else false.
12353  */
12354 static inline bool hdd_any_adapter_connected(hdd_cb_handle context)
12355 {
12356 	struct hdd_context *hdd_ctx = hdd_cb_handle_to_context(context);
12357 
12358 	if (!hdd_ctx) {
12359 		hdd_err("hdd_ctx is null");
12360 		return false;
12361 	}
12362 
12363 	return hdd_is_any_adapter_connected(hdd_ctx);
12364 }
12365 
12366 #ifdef WLAN_FEATURE_DP_BUS_BANDWIDTH
12367 /**
12368  * hdd_pld_request_pm_qos() - Request PLD PM QoS request
12369  * @context: HDD context
12370  *
12371  * Return: None
12372  */
12373 static inline void hdd_pld_request_pm_qos(hdd_cb_handle context)
12374 {
12375 	struct hdd_context *hdd_ctx = hdd_cb_handle_to_context(context);
12376 
12377 	if (!hdd_ctx) {
12378 		hdd_err("hdd_ctx is null");
12379 		return;
12380 	}
12381 
12382 	if (!hdd_ctx->hbw_requested) {
12383 		PLD_REQUEST_PM_QOS(hdd_ctx->parent_dev, 1);
12384 		hdd_ctx->hbw_requested = true;
12385 	}
12386 }
12387 
12388 /**
12389  * hdd_pld_remove_pm_qos() - Remove PLD PM QoS request
12390  * @context: HDD context
12391  *
12392  * Return: None
12393  */
12394 static inline void hdd_pld_remove_pm_qos(hdd_cb_handle context)
12395 {
12396 	struct hdd_context *hdd_ctx = hdd_cb_handle_to_context(context);
12397 
12398 	if (!hdd_ctx) {
12399 		hdd_err("hdd_ctx is null");
12400 		return;
12401 	}
12402 
12403 	if (hdd_ctx->hbw_requested &&
12404 	    !hdd_ctx->pm_qos_request) {
12405 		PLD_REMOVE_PM_QOS(hdd_ctx->parent_dev);
12406 		hdd_ctx->hbw_requested = false;
12407 	}
12408 }
12409 
12410 /**
12411  * wlan_hdd_pm_qos_update_request() - Update PM QoS request
12412  * @context: HDD context
12413  * @pm_qos_cpu_mask: CPU mask
12414  *
12415  * Return: None
12416  */
12417 static inline void
12418 wlan_hdd_pm_qos_update_request(hdd_cb_handle context,
12419 			       cpumask_t *pm_qos_cpu_mask)
12420 {
12421 	struct hdd_context *hdd_ctx = hdd_cb_handle_to_context(context);
12422 
12423 	if (!hdd_ctx) {
12424 		hdd_err("hdd_ctx is null");
12425 		return;
12426 	}
12427 
12428 	if (!hdd_ctx->pm_qos_request)
12429 		hdd_pm_qos_update_request(hdd_ctx, pm_qos_cpu_mask);
12430 }
12431 
12432 /**
12433  * wlan_hdd_pm_qos_add_request() - Add PM QoS request
12434  * @context: HDD context
12435  *
12436  * Return: None
12437  */
12438 static inline void wlan_hdd_pm_qos_add_request(hdd_cb_handle context)
12439 {
12440 	struct hdd_context *hdd_ctx = hdd_cb_handle_to_context(context);
12441 
12442 	if (!hdd_ctx) {
12443 		hdd_err("hdd_ctx is null");
12444 		return;
12445 	}
12446 
12447 	hdd_pm_qos_add_request(hdd_ctx);
12448 }
12449 
12450 /**
12451  * wlan_hdd_pm_qos_remove_request() - remove PM QoS request
12452  * @context: HDD context
12453  *
12454  * Return: None
12455  */
12456 static inline void wlan_hdd_pm_qos_remove_request(hdd_cb_handle context)
12457 {
12458 	struct hdd_context *hdd_ctx = hdd_cb_handle_to_context(context);
12459 
12460 	if (!hdd_ctx) {
12461 		hdd_err("hdd_ctx is null");
12462 		return;
12463 	}
12464 
12465 	hdd_pm_qos_remove_request(hdd_ctx);
12466 }
12467 
12468 /**
12469  * wlan_hdd_send_mscs_action_frame() - Send MSCS action frame
12470  * @context: HDD context
12471  * @netdev: netdev
12472  *
12473  * Return: None
12474  */
12475 static inline void wlan_hdd_send_mscs_action_frame(hdd_cb_handle context,
12476 						   qdf_netdev_t netdev)
12477 {
12478 	struct hdd_adapter *adapter;
12479 	struct wlan_hdd_link_info *link_info;
12480 
12481 	adapter = WLAN_HDD_GET_PRIV_PTR(netdev);
12482 	if (!adapter) {
12483 		hdd_err("adapter is null");
12484 		return;
12485 	}
12486 
12487 	link_info = adapter->deflink;
12488 	hdd_send_mscs_action_frame(link_info);
12489 }
12490 
12491 #else
12492 static inline void hdd_pld_remove_pm_qos(hdd_cb_handle context)
12493 {
12494 }
12495 
12496 static inline void hdd_pld_request_pm_qos(hdd_cb_handle context)
12497 {
12498 }
12499 
12500 static inline void
12501 wlan_hdd_pm_qos_update_request(hdd_cb_handle context,
12502 			       cpumask_t *pm_qos_cpu_mask)
12503 {
12504 }
12505 
12506 static inline void wlan_hdd_pm_qos_add_request(hdd_cb_handle context)
12507 {
12508 }
12509 
12510 static inline void wlan_hdd_pm_qos_remove_request(hdd_cb_handle context)
12511 {
12512 }
12513 
12514 static inline void wlan_hdd_send_mscs_action_frame(hdd_cb_handle context,
12515 						   qdf_netdev_t netdev)
12516 {
12517 }
12518 #endif
12519 
12520 #if defined(WLAN_FEATURE_ROAM_OFFLOAD) && \
12521 defined(FEATURE_RX_LINKSPEED_ROAM_TRIGGER)
12522 void wlan_hdd_link_speed_update(struct wlan_objmgr_psoc *psoc,
12523 				uint8_t vdev_id,
12524 				bool is_link_speed_good)
12525 {
12526 	ucfg_cm_roam_link_speed_update(psoc, vdev_id, is_link_speed_good);
12527 }
12528 #endif
12529 
12530 /**
12531  * hdd_dp_register_callbacks() - Register DP callbacks with HDD
12532  * @hdd_ctx: HDD context
12533  *
12534  * Return: None
12535  */
12536 static void hdd_dp_register_callbacks(struct hdd_context *hdd_ctx)
12537 {
12538 	struct wlan_dp_psoc_callbacks cb_obj = {0};
12539 
12540 	cb_obj.callback_ctx = (hdd_cb_handle)hdd_ctx;
12541 	cb_obj.wlan_dp_sta_get_dot11mode = wlan_hdd_sta_get_dot11mode;
12542 	cb_obj.wlan_dp_get_ap_client_count = wlan_hdd_get_ap_client_count;
12543 	cb_obj.wlan_dp_sta_ndi_connected = wlan_hdd_sta_ndi_connected;
12544 	cb_obj.dp_any_adapter_connected = hdd_any_adapter_connected;
12545 	cb_obj.dp_send_svc_nlink_msg = wlan_hdd_send_svc_nlink_msg;
12546 	cb_obj.dp_pld_remove_pm_qos = hdd_pld_remove_pm_qos;
12547 	cb_obj.dp_pld_request_pm_qos = hdd_pld_request_pm_qos;
12548 	cb_obj.dp_pktlog_enable_disable = wlan_hdd_pktlog_enable_disable;
12549 	cb_obj.dp_pm_qos_update_request = wlan_hdd_pm_qos_update_request;
12550 	cb_obj.dp_pm_qos_add_request = wlan_hdd_pm_qos_add_request;
12551 	cb_obj.dp_pm_qos_remove_request = wlan_hdd_pm_qos_remove_request;
12552 	cb_obj.dp_send_mscs_action_frame = wlan_hdd_send_mscs_action_frame;
12553 	cb_obj.dp_is_roaming_in_progress = wlan_hdd_is_roaming_in_progress;
12554 	cb_obj.wlan_dp_display_tx_multiq_stats =
12555 		wlan_hdd_display_tx_multiq_stats;
12556 	cb_obj.wlan_dp_display_netif_queue_history =
12557 		wlan_hdd_display_netif_queue_history;
12558 	cb_obj.dp_is_ap_active = hdd_is_ap_active;
12559 	cb_obj.dp_napi_apply_throughput_policy =
12560 		wlan_hdd_napi_apply_throughput_policy;
12561 	cb_obj.dp_is_link_adapter = hdd_is_link_adapter;
12562 	cb_obj.dp_nud_failure_work = hdd_nud_failure_work;
12563 	cb_obj.dp_get_pause_map = hdd_get_pause_map;
12564 
12565 	cb_obj.dp_get_netdev_by_vdev_mac =
12566 		hdd_get_netdev_by_vdev_mac;
12567 	cb_obj.dp_get_tx_resource = hdd_get_tx_resource;
12568 	cb_obj.dp_get_tx_flow_low_watermark = hdd_get_tx_flow_low_watermark;
12569 	cb_obj.dp_get_tsf_time = hdd_get_tsf_time_cb;
12570 	cb_obj.dp_tsf_timestamp_rx = hdd_tsf_timestamp_rx;
12571 	cb_obj.dp_gro_rx_legacy_get_napi = hdd_legacy_gro_get_napi;
12572 	cb_obj.link_monitoring_cb = wlan_hdd_link_speed_update;
12573 
12574 	os_if_dp_register_hdd_callbacks(hdd_ctx->psoc, &cb_obj);
12575 }
12576 
12577 /**
12578  * __hdd_adapter_param_update_work() - Gist of the work to process
12579  *				       netdev feature update.
12580  * @adapter: pointer to adapter structure
12581  *
12582  * This function assumes that the adapter pointer is always valid.
12583  * So the caller should always validate adapter pointer before calling
12584  * this function
12585  *
12586  * Returns: None
12587  */
12588 static inline void
12589 __hdd_adapter_param_update_work(struct hdd_adapter *adapter)
12590 {
12591 	/**
12592 	 * This check is needed in case the work got scheduled after the
12593 	 * interface got disconnected.
12594 	 * Netdev features update is to be done only after the connection,
12595 	 * since the connection mode plays an important role in identifying
12596 	 * the features that are to be updated.
12597 	 * So in case of interface disconnect skip feature update.
12598 	 */
12599 	if (!hdd_cm_is_vdev_associated(adapter->deflink))
12600 		return;
12601 
12602 	hdd_netdev_update_features(adapter);
12603 }
12604 
12605 /**
12606  * hdd_adapter_param_update_work() - work to process the netdev features
12607  *				     update.
12608  * @arg: private data passed to work
12609  *
12610  * Returns: None
12611  */
12612 static void hdd_adapter_param_update_work(void *arg)
12613 {
12614 	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
12615 	struct hdd_adapter *adapter = arg;
12616 	struct osif_vdev_sync *vdev_sync;
12617 	int errno;
12618 
12619 	if (!hdd_ctx)
12620 		return;
12621 
12622 	hdd_adapter_ops_record_event(hdd_ctx,
12623 				     WLAN_HDD_ADAPTER_OPS_WORK_SCHED,
12624 				     WLAN_INVALID_VDEV_ID);
12625 
12626 	if (hdd_validate_adapter(adapter))
12627 		return;
12628 
12629 	errno = osif_vdev_sync_op_start(adapter->dev, &vdev_sync);
12630 	if (errno)
12631 		return;
12632 
12633 	__hdd_adapter_param_update_work(adapter);
12634 
12635 	osif_vdev_sync_op_stop(vdev_sync);
12636 }
12637 
12638 QDF_STATUS hdd_init_adapter_ops_wq(struct hdd_context *hdd_ctx)
12639 {
12640 	hdd_enter();
12641 
12642 	hdd_ctx->adapter_ops_wq =
12643 		qdf_alloc_high_prior_ordered_workqueue("hdd_adapter_ops_wq");
12644 	if (!hdd_ctx->adapter_ops_wq)
12645 		return QDF_STATUS_E_NOMEM;
12646 
12647 	hdd_exit();
12648 
12649 	return QDF_STATUS_SUCCESS;
12650 }
12651 
12652 void hdd_deinit_adapter_ops_wq(struct hdd_context *hdd_ctx)
12653 {
12654 	hdd_enter();
12655 
12656 	qdf_flush_workqueue(0, hdd_ctx->adapter_ops_wq);
12657 	qdf_destroy_workqueue(0, hdd_ctx->adapter_ops_wq);
12658 
12659 	hdd_exit();
12660 }
12661 
12662 QDF_STATUS hdd_adapter_feature_update_work_init(struct hdd_adapter *adapter)
12663 {
12664 	QDF_STATUS status;
12665 
12666 	hdd_enter();
12667 
12668 	status = qdf_create_work(0, &adapter->netdev_features_update_work,
12669 				 hdd_adapter_param_update_work, adapter);
12670 	adapter->netdev_features_update_work_status = HDD_WORK_INITIALIZED;
12671 
12672 	hdd_exit();
12673 
12674 	return status;
12675 }
12676 
12677 void hdd_adapter_feature_update_work_deinit(struct hdd_adapter *adapter)
12678 {
12679 	hdd_enter();
12680 
12681 	if (adapter->netdev_features_update_work_status !=
12682 	    HDD_WORK_INITIALIZED) {
12683 		hdd_debug("work not yet init");
12684 		return;
12685 	}
12686 	qdf_cancel_work(&adapter->netdev_features_update_work);
12687 	qdf_flush_work(&adapter->netdev_features_update_work);
12688 	adapter->netdev_features_update_work_status = HDD_WORK_UNINITIALIZED;
12689 
12690 	hdd_exit();
12691 }
12692 
12693 #define HDD_DUMP_STAT_HELP(STAT_ID) \
12694 	hdd_nofl_debug("%u -- %s", STAT_ID, (# STAT_ID))
12695 /**
12696  * hdd_display_stats_help() - print statistics help
12697  *
12698  * Return: none
12699  */
12700 static void hdd_display_stats_help(void)
12701 {
12702 	hdd_nofl_debug("iwpriv wlan0 dumpStats [option] - dump statistics");
12703 	hdd_nofl_debug("iwpriv wlan0 clearStats [option] - clear statistics");
12704 	hdd_nofl_debug("options:");
12705 	HDD_DUMP_STAT_HELP(CDP_TXRX_PATH_STATS);
12706 	HDD_DUMP_STAT_HELP(CDP_TXRX_HIST_STATS);
12707 	HDD_DUMP_STAT_HELP(CDP_TXRX_TSO_STATS);
12708 	HDD_DUMP_STAT_HELP(CDP_HDD_NETIF_OPER_HISTORY);
12709 	HDD_DUMP_STAT_HELP(CDP_DUMP_TX_FLOW_POOL_INFO);
12710 	HDD_DUMP_STAT_HELP(CDP_TXRX_DESC_STATS);
12711 	HDD_DUMP_STAT_HELP(CDP_HIF_STATS);
12712 	HDD_DUMP_STAT_HELP(CDP_NAPI_STATS);
12713 	HDD_DUMP_STAT_HELP(CDP_DP_NAPI_STATS);
12714 	HDD_DUMP_STAT_HELP(CDP_DP_RX_THREAD_STATS);
12715 }
12716 
12717 int hdd_wlan_dump_stats(struct hdd_adapter *adapter, int stats_id)
12718 {
12719 	int ret = 0;
12720 	QDF_STATUS status;
12721 	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
12722 
12723 	hdd_debug("stats_id %d", stats_id);
12724 
12725 	switch (stats_id) {
12726 	case CDP_TXRX_HIST_STATS:
12727 		ucfg_wlan_dp_display_tx_rx_histogram(hdd_ctx->psoc);
12728 		break;
12729 	case CDP_HDD_NETIF_OPER_HISTORY:
12730 		wlan_hdd_display_adapter_netif_queue_history(adapter);
12731 		break;
12732 	case CDP_HIF_STATS:
12733 		hdd_display_hif_stats();
12734 		break;
12735 	case CDP_NAPI_STATS:
12736 		if (hdd_display_napi_stats()) {
12737 			hdd_err("error displaying napi stats");
12738 			ret = -EFAULT;
12739 		}
12740 		break;
12741 	case CDP_DP_RX_THREAD_STATS:
12742 		ucfg_dp_txrx_ext_dump_stats(cds_get_context(QDF_MODULE_ID_SOC),
12743 					    CDP_DP_RX_THREAD_STATS);
12744 		break;
12745 	case CDP_DISCONNECT_STATS:
12746 		sme_display_disconnect_stats(hdd_ctx->mac_handle,
12747 					     adapter->deflink->vdev_id);
12748 		break;
12749 	default:
12750 		status = cdp_display_stats(cds_get_context(QDF_MODULE_ID_SOC),
12751 					   stats_id,
12752 					   QDF_STATS_VERBOSITY_LEVEL_HIGH);
12753 		if (status == QDF_STATUS_E_INVAL) {
12754 			hdd_display_stats_help();
12755 			ret = -EINVAL;
12756 		}
12757 		break;
12758 	}
12759 	return ret;
12760 }
12761 
12762 int hdd_wlan_clear_stats(struct hdd_adapter *adapter, int stats_id)
12763 {
12764 	QDF_STATUS status = QDF_STATUS_SUCCESS;
12765 
12766 	hdd_debug("stats_id %d", stats_id);
12767 
12768 	switch (stats_id) {
12769 	case CDP_HDD_STATS:
12770 		ucfg_dp_clear_net_dev_stats(adapter->dev);
12771 		memset(&adapter->deflink->hdd_stats, 0,
12772 		       sizeof(adapter->deflink->hdd_stats));
12773 		break;
12774 	case CDP_TXRX_HIST_STATS:
12775 		ucfg_wlan_dp_clear_tx_rx_histogram(adapter->hdd_ctx->psoc);
12776 		break;
12777 	case CDP_HDD_NETIF_OPER_HISTORY:
12778 		wlan_hdd_clear_netif_queue_history(adapter->hdd_ctx);
12779 		break;
12780 	case CDP_HIF_STATS:
12781 		hdd_clear_hif_stats();
12782 		break;
12783 	case CDP_NAPI_STATS:
12784 		hdd_clear_napi_stats();
12785 		break;
12786 	default:
12787 		status = cdp_clear_stats(cds_get_context(QDF_MODULE_ID_SOC),
12788 					 OL_TXRX_PDEV_ID,
12789 					 stats_id);
12790 		if (status != QDF_STATUS_SUCCESS)
12791 			hdd_debug("Failed to dump stats for stats_id: %d",
12792 				  stats_id);
12793 		break;
12794 	}
12795 
12796 	return qdf_status_to_os_return(status);
12797 }
12798 
12799 /* length of the netif queue log needed per adapter */
12800 #define ADAP_NETIFQ_LOG_LEN ((20 * WLAN_REASON_TYPE_MAX) + 50)
12801 
12802 /**
12803  * hdd_display_netif_queue_history_compact() - display compact netifq history
12804  * @hdd_ctx: hdd context
12805  *
12806  * Return: none
12807  */
12808 static void
12809 hdd_display_netif_queue_history_compact(struct hdd_context *hdd_ctx)
12810 {
12811 	int adapter_num = 0;
12812 	int i;
12813 	int bytes_written;
12814 	u32 tbytes;
12815 	qdf_time_t total, pause, unpause, curr_time, delta;
12816 	char temp_str[20 * WLAN_REASON_TYPE_MAX];
12817 	char *comb_log_str;
12818 	uint32_t comb_log_str_size;
12819 	struct hdd_adapter *adapter = NULL, *next_adapter = NULL;
12820 	wlan_net_dev_ref_dbgid dbgid =
12821 			NET_DEV_HOLD_DISPLAY_NETIF_QUEUE_HISTORY_COMPACT;
12822 
12823 	comb_log_str_size = (ADAP_NETIFQ_LOG_LEN * WLAN_MAX_VDEVS) + 1;
12824 	comb_log_str = qdf_mem_malloc(comb_log_str_size);
12825 	if (!comb_log_str)
12826 		return;
12827 
12828 	bytes_written = 0;
12829 
12830 	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
12831 					   dbgid) {
12832 		curr_time = qdf_system_ticks();
12833 		total = curr_time - adapter->start_time;
12834 		delta = curr_time - adapter->last_time;
12835 
12836 		if (adapter->pause_map) {
12837 			pause = adapter->total_pause_time + delta;
12838 			unpause = adapter->total_unpause_time;
12839 		} else {
12840 			unpause = adapter->total_unpause_time + delta;
12841 			pause = adapter->total_pause_time;
12842 		}
12843 
12844 		tbytes = 0;
12845 		qdf_mem_zero(temp_str, sizeof(temp_str));
12846 		for (i = WLAN_CONTROL_PATH; i < WLAN_REASON_TYPE_MAX; i++) {
12847 			if (adapter->queue_oper_stats[i].pause_count == 0)
12848 				continue;
12849 			tbytes +=
12850 				snprintf(
12851 					&temp_str[tbytes],
12852 					(tbytes >= sizeof(temp_str) ?
12853 					0 : sizeof(temp_str) - tbytes),
12854 					"%d(%d,%d) ",
12855 					i,
12856 					adapter->queue_oper_stats[i].
12857 								pause_count,
12858 					adapter->queue_oper_stats[i].
12859 								unpause_count);
12860 		}
12861 		if (tbytes >= sizeof(temp_str))
12862 			hdd_warn("log truncated");
12863 
12864 		bytes_written += snprintf(&comb_log_str[bytes_written],
12865 			bytes_written >= comb_log_str_size ? 0 :
12866 					comb_log_str_size - bytes_written,
12867 			"[%d %d] (%d) %u/%ums %s|",
12868 			adapter->deflink->vdev_id, adapter->device_mode,
12869 			adapter->pause_map,
12870 			qdf_system_ticks_to_msecs(pause),
12871 			qdf_system_ticks_to_msecs(total),
12872 			temp_str);
12873 
12874 		adapter_num++;
12875 		/* dev_put has to be done here */
12876 		hdd_adapter_dev_put_debug(adapter, dbgid);
12877 	}
12878 
12879 	/* using QDF_TRACE to avoid printing function name */
12880 	QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_INFO_LOW,
12881 		  "STATS |%s", comb_log_str);
12882 
12883 	if (bytes_written >= comb_log_str_size)
12884 		hdd_warn("log string truncated");
12885 
12886 	qdf_mem_free(comb_log_str);
12887 }
12888 
12889 /* Max size of a single netdev tx queue state string. e.g. "1: 0x1" */
12890 #define HDD_NETDEV_TX_Q_STATE_STRLEN 15
12891 /**
12892  * wlan_hdd_display_adapter_netif_queue_stats() - display adapter based
12893  * netif queue stats
12894  * @adapter: hdd adapter
12895  *
12896  * Return: none
12897  */
12898 static void
12899 wlan_hdd_display_adapter_netif_queue_stats(struct hdd_adapter *adapter)
12900 {
12901 	int i;
12902 	qdf_time_t total, pause, unpause, curr_time, delta;
12903 	struct hdd_netif_queue_history *q_hist_ptr;
12904 	char q_status_buf[NUM_TX_QUEUES * HDD_NETDEV_TX_Q_STATE_STRLEN] = {0};
12905 
12906 	hdd_nofl_debug("Netif queue operation statistics:");
12907 	hdd_nofl_debug("vdev_id %d device mode %d",
12908 		       adapter->deflink->vdev_id, adapter->device_mode);
12909 	hdd_nofl_debug("Current pause_map %x", adapter->pause_map);
12910 	curr_time = qdf_system_ticks();
12911 	total = curr_time - adapter->start_time;
12912 	delta = curr_time - adapter->last_time;
12913 	if (adapter->pause_map) {
12914 		pause = adapter->total_pause_time + delta;
12915 		unpause = adapter->total_unpause_time;
12916 	} else {
12917 		unpause = adapter->total_unpause_time + delta;
12918 		pause = adapter->total_pause_time;
12919 	}
12920 	hdd_nofl_debug("Total: %ums Pause: %ums Unpause: %ums",
12921 		       qdf_system_ticks_to_msecs(total),
12922 		       qdf_system_ticks_to_msecs(pause),
12923 		       qdf_system_ticks_to_msecs(unpause));
12924 	hdd_nofl_debug("reason_type: pause_cnt: unpause_cnt: pause_time");
12925 
12926 	for (i = WLAN_CONTROL_PATH; i < WLAN_REASON_TYPE_MAX; i++) {
12927 		qdf_time_t pause_delta = 0;
12928 
12929 		if (adapter->pause_map & (1 << i))
12930 			pause_delta = delta;
12931 
12932 		/* using hdd_log to avoid printing function name */
12933 		hdd_nofl_debug("%s: %d: %d: %ums",
12934 			       hdd_reason_type_to_string(i),
12935 			       adapter->queue_oper_stats[i].pause_count,
12936 			       adapter->queue_oper_stats[i].
12937 			       unpause_count,
12938 			       qdf_system_ticks_to_msecs(
12939 			       adapter->queue_oper_stats[i].
12940 			       total_pause_time + pause_delta));
12941 	}
12942 
12943 	hdd_nofl_debug("Netif queue operation history: Total entries: %d current index %d(-1) time %u",
12944 		       WLAN_HDD_MAX_HISTORY_ENTRY,
12945 		       adapter->history_index,
12946 		       qdf_system_ticks_to_msecs(qdf_system_ticks()));
12947 
12948 	hdd_nofl_debug("%2s%20s%50s%30s%10s  %s",
12949 		       "#", "time(ms)", "action_type", "reason_type",
12950 		       "pause_map", "netdev-queue-status");
12951 
12952 	for (i = 0; i < WLAN_HDD_MAX_HISTORY_ENTRY; i++) {
12953 		/* using hdd_log to avoid printing function name */
12954 		if (adapter->queue_oper_history[i].time == 0)
12955 			continue;
12956 		q_hist_ptr = &adapter->queue_oper_history[i];
12957 		wlan_hdd_dump_queue_history_state(q_hist_ptr,
12958 						  q_status_buf,
12959 						  sizeof(q_status_buf));
12960 		hdd_nofl_debug("%2d%20u%50s%30s%10x  %s",
12961 			       i, qdf_system_ticks_to_msecs(
12962 				adapter->queue_oper_history[i].time),
12963 				   hdd_action_type_to_string(
12964 				adapter->queue_oper_history[i].
12965 					netif_action),
12966 				   hdd_reason_type_to_string(
12967 				adapter->queue_oper_history[i].
12968 					netif_reason),
12969 				   adapter->queue_oper_history[i].pause_map,
12970 				   q_status_buf);
12971 	}
12972 }
12973 
12974 void
12975 wlan_hdd_display_adapter_netif_queue_history(struct hdd_adapter *adapter)
12976 {
12977 	wlan_hdd_display_adapter_netif_queue_stats(adapter);
12978 }
12979 
12980 /**
12981  * wlan_hdd_display_netif_queue_history() - display netif queue history
12982  * @context: hdd context
12983  * @verb_lvl: verbosity level
12984  *
12985  * Return: none
12986  */
12987 void
12988 wlan_hdd_display_netif_queue_history(hdd_cb_handle context,
12989 				     enum qdf_stats_verbosity_level verb_lvl)
12990 {
12991 	struct hdd_adapter *adapter = NULL, *next_adapter = NULL;
12992 	struct hdd_context *hdd_ctx = hdd_cb_handle_to_context(context);
12993 	wlan_net_dev_ref_dbgid dbgid =
12994 				NET_DEV_HOLD_DISPLAY_NETIF_QUEUE_HISTORY;
12995 
12996 	if (!hdd_ctx) {
12997 		hdd_err("hdd_ctx is null");
12998 		return;
12999 	}
13000 
13001 	if (verb_lvl == QDF_STATS_VERBOSITY_LEVEL_LOW) {
13002 		hdd_display_netif_queue_history_compact(hdd_ctx);
13003 		return;
13004 	}
13005 
13006 	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
13007 					   dbgid) {
13008 		if (adapter->deflink->vdev_id == CDP_INVALID_VDEV_ID) {
13009 			hdd_adapter_dev_put_debug(adapter, dbgid);
13010 			continue;
13011 		}
13012 		wlan_hdd_display_adapter_netif_queue_stats(adapter);
13013 		/* dev_put has to be done here */
13014 		hdd_adapter_dev_put_debug(adapter, dbgid);
13015 	}
13016 }
13017 
13018 /**
13019  * wlan_hdd_clear_netif_queue_history() - clear netif queue operation history
13020  * @hdd_ctx: hdd context
13021  *
13022  * Return: none
13023  */
13024 void wlan_hdd_clear_netif_queue_history(struct hdd_context *hdd_ctx)
13025 {
13026 	struct hdd_adapter *adapter = NULL, *next_adapter = NULL;
13027 	wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_CLEAR_NETIF_QUEUE_HISTORY;
13028 
13029 	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
13030 					   dbgid) {
13031 		qdf_mem_zero(adapter->queue_oper_stats,
13032 					sizeof(adapter->queue_oper_stats));
13033 		qdf_mem_zero(adapter->queue_oper_history,
13034 					sizeof(adapter->queue_oper_history));
13035 		adapter->history_index = 0;
13036 		adapter->start_time = adapter->last_time = qdf_system_ticks();
13037 		adapter->total_pause_time = 0;
13038 		adapter->total_unpause_time = 0;
13039 		hdd_adapter_dev_put_debug(adapter, dbgid);
13040 	}
13041 }
13042 
13043 #ifdef WLAN_FEATURE_OFFLOAD_PACKETS
13044 /**
13045  * hdd_init_offloaded_packets_ctx() - Initialize offload packets context
13046  * @hdd_ctx: hdd global context
13047  *
13048  * Return: none
13049  */
13050 static void hdd_init_offloaded_packets_ctx(struct hdd_context *hdd_ctx)
13051 {
13052 	uint8_t i;
13053 
13054 	mutex_init(&hdd_ctx->op_ctx.op_lock);
13055 	for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++) {
13056 		hdd_ctx->op_ctx.op_table[i].request_id = MAX_REQUEST_ID;
13057 		hdd_ctx->op_ctx.op_table[i].pattern_id = i;
13058 	}
13059 }
13060 #else
13061 static void hdd_init_offloaded_packets_ctx(struct hdd_context *hdd_ctx)
13062 {
13063 }
13064 #endif
13065 
13066 #ifdef WLAN_FEATURE_WOW_PULSE
13067 /**
13068  * wlan_hdd_set_wow_pulse() - call SME to send wmi cmd of wow pulse
13069  * @hdd_ctx: struct hdd_context structure pointer
13070  * @enable: enable or disable this behaviour
13071  *
13072  * Return: int
13073  */
13074 static int wlan_hdd_set_wow_pulse(struct hdd_context *hdd_ctx, bool enable)
13075 {
13076 	struct wow_pulse_mode wow_pulse_set_info;
13077 	QDF_STATUS status;
13078 
13079 	hdd_debug("wow pulse enable flag is %d", enable);
13080 
13081 	if (!ucfg_pmo_is_wow_pulse_enabled(hdd_ctx->psoc))
13082 		return 0;
13083 
13084 	/* prepare the request to send to SME */
13085 	if (enable == true) {
13086 		wow_pulse_set_info.wow_pulse_enable = true;
13087 		wow_pulse_set_info.wow_pulse_pin =
13088 			ucfg_pmo_get_wow_pulse_pin(hdd_ctx->psoc);
13089 
13090 		wow_pulse_set_info.wow_pulse_interval_high =
13091 		    ucfg_pmo_get_wow_pulse_interval_high(hdd_ctx->psoc);
13092 
13093 		wow_pulse_set_info.wow_pulse_interval_low =
13094 		    ucfg_pmo_get_wow_pulse_interval_low(hdd_ctx->psoc);
13095 
13096 		wow_pulse_set_info.wow_pulse_repeat_count =
13097 		    ucfg_pmo_get_wow_pulse_repeat_count(hdd_ctx->psoc);
13098 
13099 		wow_pulse_set_info.wow_pulse_init_state =
13100 		    ucfg_pmo_get_wow_pulse_init_state(hdd_ctx->psoc);
13101 	} else {
13102 		wow_pulse_set_info.wow_pulse_enable = false;
13103 		wow_pulse_set_info.wow_pulse_pin = 0;
13104 		wow_pulse_set_info.wow_pulse_interval_low = 0;
13105 		wow_pulse_set_info.wow_pulse_interval_high = 0;
13106 		wow_pulse_set_info.wow_pulse_repeat_count = 0;
13107 		wow_pulse_set_info.wow_pulse_init_state = 0;
13108 	}
13109 	hdd_debug("enable %d pin %d low %d high %d count %d init %d",
13110 		  wow_pulse_set_info.wow_pulse_enable,
13111 		  wow_pulse_set_info.wow_pulse_pin,
13112 		  wow_pulse_set_info.wow_pulse_interval_low,
13113 		  wow_pulse_set_info.wow_pulse_interval_high,
13114 		  wow_pulse_set_info.wow_pulse_repeat_count,
13115 		  wow_pulse_set_info.wow_pulse_init_state);
13116 
13117 	status = sme_set_wow_pulse(&wow_pulse_set_info);
13118 	if (QDF_STATUS_E_FAILURE == status) {
13119 		hdd_debug("sme_set_wow_pulse failure!");
13120 		return -EIO;
13121 	}
13122 	hdd_debug("sme_set_wow_pulse success!");
13123 	return 0;
13124 }
13125 #else
13126 static inline int wlan_hdd_set_wow_pulse(struct hdd_context *hdd_ctx, bool enable)
13127 {
13128 	return 0;
13129 }
13130 #endif
13131 
13132 #ifdef WLAN_FEATURE_FASTPATH
13133 
13134 /**
13135  * hdd_enable_fastpath() - Enable fastpath if enabled in config INI
13136  * @hdd_ctx: hdd context
13137  * @context: lower layer context
13138  *
13139  * Return: none
13140  */
13141 void hdd_enable_fastpath(struct hdd_context *hdd_ctx,
13142 			 void *context)
13143 {
13144 	if (cfg_get(hdd_ctx->psoc, CFG_DP_ENABLE_FASTPATH))
13145 		hif_enable_fastpath(context);
13146 }
13147 #endif
13148 
13149 #if defined(FEATURE_WLAN_CH_AVOID)
13150 /**
13151  * hdd_set_thermal_level_cb() - set thermal level callback function
13152  * @hdd_handle:	opaque handle for the hdd context
13153  * @level:	thermal level
13154  *
13155  * Change IPA data path to SW path when the thermal throttle level greater
13156  * than 0, and restore the original data path when throttle level is 0
13157  *
13158  * Return: none
13159  */
13160 static void hdd_set_thermal_level_cb(hdd_handle_t hdd_handle, u_int8_t level)
13161 {
13162 	struct hdd_context *hdd_ctx = hdd_handle_to_context(hdd_handle);
13163 
13164 	/* Change IPA to SW path when throttle level greater than 0 */
13165 	if (level > THROTTLE_LEVEL_0)
13166 		ucfg_ipa_send_mcc_scc_msg(hdd_ctx->pdev, true);
13167 	else
13168 		/* restore original concurrency mode */
13169 		ucfg_ipa_send_mcc_scc_msg(hdd_ctx->pdev, hdd_ctx->mcc_mode);
13170 }
13171 #else
13172 /**
13173  * hdd_set_thermal_level_cb() - set thermal level callback function
13174  * @hdd_handle:	opaque handle for the hdd context
13175  * @level:	thermal level
13176  *
13177  * Change IPA data path to SW path when the thermal throttle level greater
13178  * than 0, and restore the original data path when throttle level is 0
13179  *
13180  * Return: none
13181  */
13182 static void hdd_set_thermal_level_cb(hdd_handle_t hdd_handle, u_int8_t level)
13183 {
13184 }
13185 #endif
13186 
13187 QDF_STATUS hdd_switch_sap_channel(struct wlan_hdd_link_info *link_info,
13188 				  uint8_t channel, bool forced)
13189 {
13190 	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(link_info->adapter);
13191 	mac_handle_t mac_handle;
13192 	struct sap_config *sap_cfg;
13193 	qdf_freq_t freq;
13194 
13195 	mac_handle = hdd_adapter_get_mac_handle(link_info->adapter);
13196 	if (!mac_handle) {
13197 		hdd_err("invalid MAC handle");
13198 		return QDF_STATUS_E_INVAL;
13199 	}
13200 
13201 	freq = wlan_reg_legacy_chan_to_freq(hdd_ctx->pdev, channel);
13202 	sap_cfg = &(WLAN_HDD_GET_AP_CTX_PTR(link_info)->sap_config);
13203 	hdd_debug("chan:%d width:%d", channel, sap_cfg->ch_width_orig);
13204 
13205 	return policy_mgr_change_sap_channel_with_csa(hdd_ctx->psoc,
13206 						      link_info->vdev_id, freq,
13207 						      sap_cfg->ch_width_orig,
13208 						      forced);
13209 }
13210 
13211 QDF_STATUS hdd_switch_sap_chan_freq(struct hdd_adapter *adapter,
13212 				    qdf_freq_t chan_freq,
13213 				    enum phy_ch_width ch_width,
13214 				    bool forced)
13215 {
13216 	struct hdd_ap_ctx *hdd_ap_ctx;
13217 	struct hdd_context *hdd_ctx;
13218 
13219 	if (hdd_validate_adapter(adapter))
13220 		return QDF_STATUS_E_INVAL;
13221 
13222 	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
13223 
13224 	if(wlan_hdd_validate_context(hdd_ctx))
13225 		return QDF_STATUS_E_INVAL;
13226 
13227 	hdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(adapter->deflink);
13228 
13229 	hdd_debug("chan freq:%d width:%d org bw %d",
13230 		  chan_freq, ch_width, hdd_ap_ctx->sap_config.ch_width_orig);
13231 
13232 	return policy_mgr_change_sap_channel_with_csa(hdd_ctx->psoc,
13233 						      adapter->deflink->vdev_id,
13234 						      chan_freq,
13235 						      ch_width,
13236 						      forced);
13237 }
13238 
13239 int hdd_update_acs_timer_reason(struct hdd_adapter *adapter, uint8_t reason)
13240 {
13241 	struct hdd_external_acs_timer_context *timer_context;
13242 	int status;
13243 	QDF_STATUS qdf_status;
13244 	qdf_mc_timer_t *vendor_acs_timer;
13245 
13246 	set_bit(VENDOR_ACS_RESPONSE_PENDING, &adapter->deflink->link_flags);
13247 
13248 	vendor_acs_timer = &adapter->deflink->session.ap.vendor_acs_timer;
13249 	if (QDF_TIMER_STATE_RUNNING ==
13250 	    qdf_mc_timer_get_current_state(vendor_acs_timer)) {
13251 		qdf_mc_timer_stop(vendor_acs_timer);
13252 	}
13253 	timer_context =
13254 		(struct hdd_external_acs_timer_context *)vendor_acs_timer->user_data;
13255 	timer_context->reason = reason;
13256 	qdf_status =
13257 		qdf_mc_timer_start(vendor_acs_timer, WLAN_VENDOR_ACS_WAIT_TIME);
13258 	if (qdf_status != QDF_STATUS_SUCCESS) {
13259 		hdd_err("failed to start external acs timer");
13260 		return -ENOSPC;
13261 	}
13262 	/* Update config to application */
13263 	status = hdd_cfg80211_update_acs_config(adapter, reason);
13264 	hdd_info("Updated ACS config to nl with reason %d", reason);
13265 
13266 	return status;
13267 }
13268 
13269 #ifdef FEATURE_WLAN_CH_AVOID_EXT
13270 uint32_t wlan_hdd_get_restriction_mask(struct hdd_context *hdd_ctx)
13271 {
13272 	return hdd_ctx->restriction_mask;
13273 }
13274 
13275 void wlan_hdd_set_restriction_mask(struct hdd_context *hdd_ctx)
13276 {
13277 	hdd_ctx->restriction_mask =
13278 		hdd_ctx->coex_avoid_freq_list.restriction_mask;
13279 }
13280 #else
13281 uint32_t wlan_hdd_get_restriction_mask(struct hdd_context *hdd_ctx)
13282 {
13283 	return -EINVAL;
13284 }
13285 
13286 void wlan_hdd_set_restriction_mask(struct hdd_context *hdd_ctx)
13287 {
13288 }
13289 #endif
13290 
13291 #if defined(FEATURE_WLAN_CH_AVOID)
13292 /**
13293  * hdd_store_sap_restart_channel() - store sap restart channel
13294  * @restart_chan: restart channel
13295  * @restart_chan_store: pointer to restart channel store
13296  *
13297  * The function will store new sap restart channel.
13298  *
13299  * Return - none
13300  */
13301 static void
13302 hdd_store_sap_restart_channel(qdf_freq_t restart_chan, qdf_freq_t *restart_chan_store)
13303 {
13304 	uint8_t i;
13305 
13306 	for (i = 0; i < SAP_MAX_NUM_SESSION; i++) {
13307 		if (*(restart_chan_store + i) == restart_chan)
13308 			return;
13309 
13310 		if (*(restart_chan_store + i))
13311 			continue;
13312 
13313 		*(restart_chan_store + i) = restart_chan;
13314 		return;
13315 	}
13316 }
13317 
13318 /**
13319  * hdd_check_chn_bw_boundary_unsafe() - check channel range unsafe
13320  * @hdd_ctxt: hdd context pointer
13321  * @adapter:  hdd adapter pointer
13322  *
13323  * hdd_check_chn_bw_boundary_unsafe check SAP channel range with certain
13324  * bandwidth whether cover all unsafe channel list.
13325  *
13326  * Return - bool
13327  */
13328 static bool
13329 hdd_check_chn_bw_boundary_unsafe(struct hdd_context *hdd_ctxt,
13330 				 struct hdd_adapter *adapter)
13331 {
13332 	uint32_t freq;
13333 	uint32_t start_freq = 0;
13334 	uint32_t end_freq = 0;
13335 	uint32_t i;
13336 	uint8_t ch_width;
13337 	const struct bonded_channel_freq *bonded_chan_ptr_ptr = NULL;
13338 
13339 	freq = adapter->deflink->session.ap.operating_chan_freq;
13340 	ch_width = adapter->deflink->session.ap.sap_config.acs_cfg.ch_width;
13341 
13342 	if (ch_width > CH_WIDTH_20MHZ)
13343 		bonded_chan_ptr_ptr =
13344 			wlan_reg_get_bonded_chan_entry(freq, ch_width, 0);
13345 
13346 	if (bonded_chan_ptr_ptr) {
13347 		start_freq = bonded_chan_ptr_ptr->start_freq;
13348 		end_freq   = bonded_chan_ptr_ptr->end_freq;
13349 	}
13350 
13351 	for (i = 0; i < hdd_ctxt->unsafe_channel_count; i++) {
13352 		if ((freq == hdd_ctxt->unsafe_channel_list[i]) ||
13353 		    (start_freq <= hdd_ctxt->unsafe_channel_list[i] &&
13354 		     hdd_ctxt->unsafe_channel_list[i] <= end_freq)) {
13355 			hdd_debug("op chn freq:%u is unsafe for chn list:%u",
13356 				  freq, hdd_ctxt->unsafe_channel_list[i]);
13357 			return true;
13358 		}
13359 	}
13360 
13361 	return false;
13362 }
13363 
13364 /**
13365  * hdd_unsafe_channel_restart_sap() - restart sap if sap is on unsafe channel
13366  * @hdd_ctx: hdd context pointer
13367  *
13368  * hdd_unsafe_channel_restart_sap check all unsafe channel list
13369  * and if ACS is enabled, driver will ask userspace to restart the
13370  * sap. User space on LTE coex indication restart driver.
13371  *
13372  * Return - none
13373  */
13374 QDF_STATUS hdd_unsafe_channel_restart_sap(struct hdd_context *hdd_ctx)
13375 {
13376 	struct hdd_adapter *adapter, *next_adapter = NULL;
13377 	struct hdd_ap_ctx *ap_ctx;
13378 	uint32_t i;
13379 	bool found = false;
13380 	qdf_freq_t restart_chan_store[SAP_MAX_NUM_SESSION] = {0};
13381 	uint8_t scc_on_lte_coex = 0;
13382 	uint32_t restart_freq, ap_chan_freq;
13383 	bool value;
13384 	QDF_STATUS status;
13385 	bool is_acs_support_for_dfs_ltecoex = cfg_default(CFG_USER_ACS_DFS_LTE);
13386 	bool is_vendor_acs_support =
13387 		cfg_default(CFG_USER_AUTO_CHANNEL_SELECTION);
13388 	wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_UNSAFE_CHANNEL_RESTART_SAP;
13389 	enum phy_ch_width ch_width;
13390 	struct wlan_hdd_link_info *link_info;
13391 
13392 	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
13393 					   dbgid) {
13394 		if (adapter->device_mode != QDF_SAP_MODE) {
13395 			hdd_debug_rl("skip device mode:%d",
13396 				     adapter->device_mode);
13397 			hdd_adapter_dev_put_debug(adapter, dbgid);
13398 			continue;
13399 		}
13400 
13401 		hdd_adapter_for_each_active_link_info(adapter, link_info) {
13402 			ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(link_info);
13403 			if (!ap_ctx->sap_config.acs_cfg.acs_mode) {
13404 				hdd_debug_rl("skip acs:%d",
13405 					     ap_ctx->sap_config.acs_cfg.acs_mode);
13406 				continue;
13407 			}
13408 
13409 			ap_chan_freq = ap_ctx->operating_chan_freq;
13410 			ch_width = ap_ctx->sap_config.ch_width_orig;
13411 			found = false;
13412 			status =
13413 			ucfg_policy_mgr_get_sta_sap_scc_lte_coex_chnl(hdd_ctx->psoc,
13414 								      &scc_on_lte_coex);
13415 			if (!QDF_IS_STATUS_SUCCESS(status))
13416 				hdd_err("can't get scc on lte coex chnl, use def");
13417 			/*
13418 			 * If STA+SAP is doing SCC &
13419 			 * g_sta_sap_scc_on_lte_coex_chan is set,
13420 			 * no need to move SAP.
13421 			 */
13422 			if ((policy_mgr_is_sta_sap_scc(hdd_ctx->psoc,
13423 						       ap_chan_freq) &&
13424 			     scc_on_lte_coex) ||
13425 			    policy_mgr_nan_sap_scc_on_unsafe_ch_chk(hdd_ctx->psoc,
13426 								    ap_chan_freq))
13427 				hdd_debug("SAP allowed in unsafe SCC channel");
13428 			else
13429 				found = hdd_check_chn_bw_boundary_unsafe(hdd_ctx,
13430 									 adapter);
13431 			if (!found) {
13432 				hdd_store_sap_restart_channel(ap_chan_freq,
13433 							      restart_chan_store);
13434 				hdd_debug("ch freq:%d is safe. no need to change channel",
13435 					  ap_chan_freq);
13436 				continue;
13437 			}
13438 
13439 			status = ucfg_mlme_get_acs_support_for_dfs_ltecoex(
13440 						hdd_ctx->psoc,
13441 						&is_acs_support_for_dfs_ltecoex);
13442 			if (!QDF_IS_STATUS_SUCCESS(status))
13443 				hdd_err("get_acs_support_for_dfs_ltecoex failed,set def");
13444 
13445 			status = ucfg_mlme_get_vendor_acs_support(
13446 						hdd_ctx->psoc,
13447 						&is_vendor_acs_support);
13448 			if (!QDF_IS_STATUS_SUCCESS(status))
13449 				hdd_err("get_vendor_acs_support failed, set default");
13450 
13451 			if (is_vendor_acs_support &&
13452 			    is_acs_support_for_dfs_ltecoex) {
13453 				hdd_update_acs_timer_reason(adapter,
13454 				    QCA_WLAN_VENDOR_ACS_SELECT_REASON_LTE_COEX);
13455 				continue;
13456 			}
13457 
13458 			restart_freq = 0;
13459 			for (i = 0; i < SAP_MAX_NUM_SESSION; i++) {
13460 				if (!restart_chan_store[i])
13461 					continue;
13462 
13463 				if (policy_mgr_is_force_scc(hdd_ctx->psoc) &&
13464 				    WLAN_REG_IS_SAME_BAND_FREQS(
13465 						restart_chan_store[i],
13466 						ap_chan_freq)) {
13467 					restart_freq = restart_chan_store[i];
13468 					break;
13469 				}
13470 			}
13471 			if (!restart_freq) {
13472 				restart_freq =
13473 					wlansap_get_safe_channel_from_pcl_and_acs_range(
13474 					    WLAN_HDD_GET_SAP_CTX_PTR(link_info),
13475 					    &ch_width);
13476 			}
13477 			if (!restart_freq) {
13478 				wlan_hdd_set_sap_csa_reason(hdd_ctx->psoc,
13479 							    link_info->vdev_id,
13480 							    CSA_REASON_UNSAFE_CHANNEL);
13481 				hdd_err("Unable to find safe chan, Stop the SAP if restriction mask is set else set txpower");
13482 				hdd_stop_sap_set_tx_power(hdd_ctx->psoc, adapter);
13483 				continue;
13484 			}
13485 			/*
13486 			 * SAP restart due to unsafe channel. While
13487 			 * restarting the SAP, make sure to clear
13488 			 * acs_channel, channel to reset to
13489 			 * 0. Otherwise these settings will override
13490 			 * the ACS while restart.
13491 			 */
13492 			hdd_ctx->acs_policy.acs_chan_freq =
13493 						AUTO_CHANNEL_SELECT;
13494 			ucfg_mlme_get_sap_internal_restart(hdd_ctx->psoc,
13495 							   &value);
13496 			if (value) {
13497 				wlan_hdd_set_sap_csa_reason(hdd_ctx->psoc,
13498 						    link_info->vdev_id,
13499 						    CSA_REASON_UNSAFE_CHANNEL);
13500 				status = hdd_switch_sap_chan_freq(adapter,
13501 								  restart_freq,
13502 								  ch_width,
13503 								  true);
13504 				if (QDF_IS_STATUS_SUCCESS(status)) {
13505 					hdd_adapter_dev_put_debug(adapter,
13506 								  dbgid);
13507 					if (next_adapter)
13508 						hdd_adapter_dev_put_debug(
13509 								next_adapter,
13510 								dbgid);
13511 					return QDF_STATUS_E_PENDING;
13512 				} else {
13513 					hdd_debug("CSA failed, check next SAP");
13514 				}
13515 			} else {
13516 				hdd_debug("sending coex indication");
13517 				wlan_hdd_send_svc_nlink_msg(
13518 						hdd_ctx->radio_index,
13519 						WLAN_SVC_LTE_COEX_IND, NULL, 0);
13520 				hdd_adapter_dev_put_debug(adapter, dbgid);
13521 				if (next_adapter)
13522 					hdd_adapter_dev_put_debug(next_adapter,
13523 								  dbgid);
13524 				return QDF_STATUS_SUCCESS;
13525 			}
13526 		}
13527 		/* dev_put has to be done here */
13528 		hdd_adapter_dev_put_debug(adapter, dbgid);
13529 	}
13530 
13531 	return QDF_STATUS_SUCCESS;
13532 }
13533 
13534 /**
13535  * hdd_init_channel_avoidance() - Initialize channel avoidance
13536  * @hdd_ctx:	HDD global context
13537  *
13538  * Initialize the channel avoidance logic by retrieving the unsafe
13539  * channel list from the platform driver and plumbing the data
13540  * down to the lower layers.  Then subscribe to subsequent channel
13541  * avoidance events.
13542  *
13543  * Return: None
13544  */
13545 static void hdd_init_channel_avoidance(struct hdd_context *hdd_ctx)
13546 {
13547 	uint16_t unsafe_channel_count;
13548 	int index;
13549 	qdf_freq_t *unsafe_freq_list;
13550 
13551 	pld_get_wlan_unsafe_channel(hdd_ctx->parent_dev,
13552 				    hdd_ctx->unsafe_channel_list,
13553 				     &(hdd_ctx->unsafe_channel_count),
13554 				     sizeof(uint16_t) * NUM_CHANNELS);
13555 
13556 	hdd_debug("num of unsafe channels is %d",
13557 	       hdd_ctx->unsafe_channel_count);
13558 
13559 	unsafe_channel_count = QDF_MIN((uint16_t)hdd_ctx->unsafe_channel_count,
13560 				       (uint16_t)NUM_CHANNELS);
13561 
13562 	if (!unsafe_channel_count)
13563 		return;
13564 
13565 	unsafe_freq_list = qdf_mem_malloc(
13566 			unsafe_channel_count * sizeof(*unsafe_freq_list));
13567 
13568 	if (!unsafe_freq_list)
13569 		return;
13570 
13571 	for (index = 0; index < unsafe_channel_count; index++) {
13572 		hdd_debug("channel frequency %d is not safe",
13573 			  hdd_ctx->unsafe_channel_list[index]);
13574 		unsafe_freq_list[index] =
13575 			(qdf_freq_t)hdd_ctx->unsafe_channel_list[index];
13576 	}
13577 
13578 	ucfg_policy_mgr_init_chan_avoidance(
13579 		hdd_ctx->psoc,
13580 		unsafe_freq_list,
13581 		unsafe_channel_count);
13582 
13583 	qdf_mem_free(unsafe_freq_list);
13584 }
13585 
13586 static void hdd_lte_coex_restart_sap(struct hdd_adapter *adapter,
13587 				     struct hdd_context *hdd_ctx)
13588 {
13589 	uint8_t restart_chan;
13590 	uint32_t restart_freq;
13591 
13592 	restart_freq = wlansap_get_safe_channel_from_pcl_and_acs_range(
13593 				WLAN_HDD_GET_SAP_CTX_PTR(adapter->deflink),
13594 				NULL);
13595 
13596 	restart_chan = wlan_reg_freq_to_chan(hdd_ctx->pdev,
13597 					     restart_freq);
13598 
13599 	if (!restart_chan) {
13600 		hdd_alert("fail to restart SAP");
13601 		return;
13602 	}
13603 
13604 	/* SAP restart due to unsafe channel. While restarting
13605 	 * the SAP, make sure to clear acs_channel, channel to
13606 	 * reset to 0. Otherwise these settings will override
13607 	 * the ACS while restart.
13608 	 */
13609 	hdd_ctx->acs_policy.acs_chan_freq = AUTO_CHANNEL_SELECT;
13610 
13611 	hdd_debug("sending coex indication");
13612 
13613 	wlan_hdd_send_svc_nlink_msg(hdd_ctx->radio_index,
13614 				    WLAN_SVC_LTE_COEX_IND, NULL, 0);
13615 	wlan_hdd_set_sap_csa_reason(hdd_ctx->psoc, adapter->deflink->vdev_id,
13616 				    CSA_REASON_LTE_COEX);
13617 	hdd_switch_sap_channel(adapter->deflink, restart_chan, true);
13618 }
13619 
13620 int hdd_clone_local_unsafe_chan(struct hdd_context *hdd_ctx,
13621 	uint16_t **local_unsafe_list, uint16_t *local_unsafe_list_count)
13622 {
13623 	uint32_t size;
13624 	uint16_t *unsafe_list;
13625 	uint16_t chan_count;
13626 
13627 	if (!hdd_ctx || !local_unsafe_list_count || !local_unsafe_list_count)
13628 		return -EINVAL;
13629 
13630 	chan_count = QDF_MIN(hdd_ctx->unsafe_channel_count,
13631 			     NUM_CHANNELS);
13632 	if (chan_count) {
13633 		size = chan_count * sizeof(hdd_ctx->unsafe_channel_list[0]);
13634 		unsafe_list = qdf_mem_malloc(size);
13635 		if (!unsafe_list)
13636 			return -ENOMEM;
13637 		qdf_mem_copy(unsafe_list, hdd_ctx->unsafe_channel_list, size);
13638 	} else {
13639 		unsafe_list = NULL;
13640 	}
13641 
13642 	*local_unsafe_list = unsafe_list;
13643 	*local_unsafe_list_count = chan_count;
13644 
13645 	return 0;
13646 }
13647 
13648 bool hdd_local_unsafe_channel_updated(
13649 	struct hdd_context *hdd_ctx, uint16_t *local_unsafe_list,
13650 	uint16_t local_unsafe_list_count, uint32_t restriction_mask)
13651 {
13652 	int i, j;
13653 
13654 	if (local_unsafe_list_count != hdd_ctx->unsafe_channel_count)
13655 		return true;
13656 	if (local_unsafe_list_count == 0)
13657 		return false;
13658 	for (i = 0; i < local_unsafe_list_count; i++) {
13659 		for (j = 0; j < local_unsafe_list_count; j++)
13660 			if (local_unsafe_list[i] ==
13661 			    hdd_ctx->unsafe_channel_list[j])
13662 				break;
13663 		if (j >= local_unsafe_list_count)
13664 			break;
13665 	}
13666 
13667 	if (ucfg_mlme_get_coex_unsafe_chan_nb_user_prefer(hdd_ctx->psoc)) {
13668 		/* Return false if current channel list is same as previous
13669 		 * and restriction mask is not altered
13670 		 */
13671 		if (i >= local_unsafe_list_count &&
13672 		    (restriction_mask ==
13673 		     wlan_hdd_get_restriction_mask(hdd_ctx))) {
13674 			hdd_info("unsafe chan list same");
13675 			return false;
13676 		}
13677 	} else if (i >= local_unsafe_list_count) {
13678 		hdd_info("unsafe chan list same");
13679 		return false;
13680 	}
13681 
13682 	return true;
13683 }
13684 #else
13685 static void hdd_init_channel_avoidance(struct hdd_context *hdd_ctx)
13686 {
13687 }
13688 
13689 static inline void hdd_lte_coex_restart_sap(struct hdd_adapter *adapter,
13690 					    struct hdd_context *hdd_ctx)
13691 {
13692 	hdd_debug("Channel avoidance is not enabled; Abort SAP restart");
13693 }
13694 #endif /* defined(FEATURE_WLAN_CH_AVOID) */
13695 
13696 struct wlan_hdd_link_info *
13697 wlan_hdd_get_link_info_from_objmgr(struct wlan_objmgr_vdev *vdev)
13698 {
13699 	if (!vdev) {
13700 		hdd_err("null vdev object");
13701 		return NULL;
13702 	}
13703 
13704 	if (vdev->vdev_nif.osdev)
13705 		return vdev->vdev_nif.osdev->legacy_osif_priv;
13706 
13707 	return NULL;
13708 }
13709 
13710 /**
13711  * hdd_indicate_mgmt_frame() - Wrapper to indicate management frame to
13712  * user space
13713  * @frame_ind: Management frame data to be informed.
13714  *
13715  * This function is used to indicate management frame to
13716  * user space
13717  *
13718  * Return: None
13719  *
13720  */
13721 void hdd_indicate_mgmt_frame(tSirSmeMgmtFrameInd *frame_ind)
13722 {
13723 	struct hdd_context *hdd_ctx = NULL;
13724 	struct hdd_adapter *adapter = NULL, *next_adapter = NULL;
13725 	int i, num_adapters;
13726 	uint8_t vdev_id[WLAN_MAX_VDEVS + WLAN_MAX_ML_VDEVS];
13727 	struct ieee80211_mgmt *mgmt =
13728 		(struct ieee80211_mgmt *)frame_ind->frameBuf;
13729 	struct wlan_objmgr_vdev *vdev;
13730 	wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_INDICATE_MGMT_FRAME;
13731 	struct wlan_hdd_link_info *link_info;
13732 
13733 	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
13734 	if (wlan_hdd_validate_context(hdd_ctx))
13735 		return;
13736 
13737 	if (frame_ind->frame_len < ieee80211_hdrlen(mgmt->frame_control)) {
13738 		hdd_err(" Invalid frame length");
13739 		return;
13740 	}
13741 
13742 	if (SME_SESSION_ID_ANY == frame_ind->sessionId) {
13743 		for (i = 0; i < WLAN_MAX_VDEVS; i++) {
13744 			link_info = hdd_get_link_info_by_vdev(hdd_ctx, i);
13745 			if (link_info) {
13746 				adapter = link_info->adapter;
13747 				break;
13748 			}
13749 		}
13750 	} else if (SME_SESSION_ID_BROADCAST == frame_ind->sessionId) {
13751 		num_adapters = 0;
13752 		hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter,
13753 						   next_adapter, dbgid) {
13754 			hdd_adapter_for_each_active_link_info(adapter,
13755 							      link_info) {
13756 				vdev_id[num_adapters] = link_info->vdev_id;
13757 				num_adapters++;
13758 			}
13759 			/* dev_put has to be done here */
13760 			hdd_adapter_dev_put_debug(adapter, dbgid);
13761 		}
13762 
13763 		adapter = NULL;
13764 
13765 		for (i = 0; i < num_adapters; i++) {
13766 			vdev = wlan_objmgr_get_vdev_by_id_from_psoc(
13767 							hdd_ctx->psoc,
13768 							vdev_id[i],
13769 							WLAN_OSIF_ID);
13770 
13771 			if (!vdev)
13772 				continue;
13773 
13774 			link_info = wlan_hdd_get_link_info_from_objmgr(vdev);
13775 			if (!link_info) {
13776 				wlan_objmgr_vdev_release_ref(vdev,
13777 							     WLAN_OSIF_ID);
13778 				continue;
13779 			}
13780 
13781 			hdd_indicate_mgmt_frame_to_user(link_info->adapter,
13782 							frame_ind->frame_len,
13783 							frame_ind->frameBuf,
13784 							frame_ind->frameType,
13785 							frame_ind->rx_freq,
13786 							frame_ind->rxRssi,
13787 							frame_ind->rx_flags);
13788 			wlan_objmgr_vdev_release_ref(vdev, WLAN_OSIF_ID);
13789 		}
13790 
13791 		adapter = NULL;
13792 	} else {
13793 		link_info = hdd_get_link_info_by_vdev(hdd_ctx,
13794 						      frame_ind->sessionId);
13795 
13796 		if (!link_info) {
13797 			hdd_err("Invalid vdev");
13798 			return;
13799 		}
13800 
13801 		adapter = link_info->adapter;
13802 	}
13803 
13804 	if ((adapter) &&
13805 		(WLAN_HDD_ADAPTER_MAGIC == adapter->magic))
13806 		hdd_indicate_mgmt_frame_to_user(adapter,
13807 						frame_ind->frame_len,
13808 						frame_ind->frameBuf,
13809 						frame_ind->frameType,
13810 						frame_ind->rx_freq,
13811 						frame_ind->rxRssi,
13812 						frame_ind->rx_flags);
13813 }
13814 
13815 void hdd_acs_response_timeout_handler(void *context)
13816 {
13817 	struct hdd_external_acs_timer_context *timer_context =
13818 			(struct hdd_external_acs_timer_context *)context;
13819 	struct hdd_adapter *adapter;
13820 	struct hdd_context *hdd_ctx;
13821 	uint8_t reason;
13822 	struct sap_context *sap_context;
13823 	struct wlan_hdd_link_info *link_info;
13824 
13825 	hdd_enter();
13826 	if (!timer_context) {
13827 		hdd_err("invalid timer context");
13828 		return;
13829 	}
13830 	adapter = timer_context->adapter;
13831 	reason = timer_context->reason;
13832 
13833 	if (!adapter || adapter->magic != WLAN_HDD_ADAPTER_MAGIC) {
13834 		hdd_err("invalid adapter or adapter has invalid magic");
13835 		return;
13836 	}
13837 
13838 	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
13839 	if (wlan_hdd_validate_context(hdd_ctx))
13840 		return;
13841 
13842 	link_info = adapter->deflink;
13843 	if (!test_bit(VENDOR_ACS_RESPONSE_PENDING, &link_info->link_flags))
13844 		return;
13845 
13846 	clear_bit(VENDOR_ACS_RESPONSE_PENDING, &link_info->link_flags);
13847 
13848 	hdd_err("ACS timeout happened for %s reason %d",
13849 		adapter->dev->name, reason);
13850 
13851 	sap_context = WLAN_HDD_GET_SAP_CTX_PTR(link_info);
13852 	switch (reason) {
13853 	/* SAP init case */
13854 	case QCA_WLAN_VENDOR_ACS_SELECT_REASON_INIT:
13855 		wlan_sap_set_vendor_acs(sap_context, false);
13856 		wlan_hdd_cfg80211_start_acs(link_info);
13857 		break;
13858 	/* DFS detected on current channel */
13859 	case QCA_WLAN_VENDOR_ACS_SELECT_REASON_DFS:
13860 		wlan_sap_update_next_channel(sap_context, 0, 0);
13861 		sme_update_new_channel_event(hdd_ctx->mac_handle,
13862 					     link_info->vdev_id);
13863 		break;
13864 	/* LTE coex event on current channel */
13865 	case QCA_WLAN_VENDOR_ACS_SELECT_REASON_LTE_COEX:
13866 		hdd_lte_coex_restart_sap(adapter, hdd_ctx);
13867 		break;
13868 	default:
13869 		hdd_info("invalid reason for timer invoke");
13870 	}
13871 }
13872 
13873 /**
13874  * hdd_override_ini_config - Override INI config
13875  * @hdd_ctx: HDD context
13876  *
13877  * Override INI config based on module parameter.
13878  *
13879  * Return: None
13880  */
13881 static void hdd_override_ini_config(struct hdd_context *hdd_ctx)
13882 {
13883 	QDF_STATUS status;
13884 
13885 	if (0 == enable_dfs_chan_scan || 1 == enable_dfs_chan_scan) {
13886 		ucfg_scan_cfg_set_dfs_chan_scan_allowed(hdd_ctx->psoc,
13887 							enable_dfs_chan_scan);
13888 		hdd_debug("Module enable_dfs_chan_scan set to %d",
13889 			   enable_dfs_chan_scan);
13890 	}
13891 	if (0 == enable_11d || 1 == enable_11d) {
13892 		status = ucfg_mlme_set_11d_enabled(hdd_ctx->psoc, enable_11d);
13893 		if (!QDF_IS_STATUS_SUCCESS(status))
13894 			hdd_err("Failed to set 11d_enable flag");
13895 	}
13896 }
13897 
13898 #ifdef ENABLE_MTRACE_LOG
13899 static void hdd_set_mtrace_for_each(struct hdd_context *hdd_ctx)
13900 {
13901 	uint8_t module_id = 0;
13902 	int qdf_print_idx = -1;
13903 
13904 	qdf_print_idx = qdf_get_pidx();
13905 	for (module_id = 0; module_id < QDF_MODULE_ID_MAX; module_id++)
13906 		qdf_print_set_category_verbose(
13907 					qdf_print_idx,
13908 					module_id, QDF_TRACE_LEVEL_TRACE,
13909 					hdd_ctx->config->enable_mtrace);
13910 }
13911 #else
13912 static void hdd_set_mtrace_for_each(struct hdd_context *hdd_ctx)
13913 {
13914 }
13915 
13916 #endif
13917 
13918 /**
13919  * hdd_log_level_to_bitmask() - user space log level to host log bitmask
13920  * @user_log_level: user space log level
13921  *
13922  * Convert log level from user space to host log level bitmask.
13923  *
13924  * Return: Bitmask of log levels to be enabled
13925  */
13926 static uint32_t hdd_log_level_to_bitmask(enum host_log_level user_log_level)
13927 {
13928 	QDF_TRACE_LEVEL host_trace_level;
13929 	uint32_t bitmask;
13930 
13931 	switch (user_log_level) {
13932 	case HOST_LOG_LEVEL_NONE:
13933 		host_trace_level = QDF_TRACE_LEVEL_NONE;
13934 		break;
13935 	case HOST_LOG_LEVEL_FATAL:
13936 		host_trace_level = QDF_TRACE_LEVEL_FATAL;
13937 		break;
13938 	case HOST_LOG_LEVEL_ERROR:
13939 		host_trace_level = QDF_TRACE_LEVEL_ERROR;
13940 		break;
13941 	case HOST_LOG_LEVEL_WARN:
13942 		host_trace_level = QDF_TRACE_LEVEL_WARN;
13943 		break;
13944 	case HOST_LOG_LEVEL_INFO:
13945 		host_trace_level = QDF_TRACE_LEVEL_INFO_LOW;
13946 		break;
13947 	case HOST_LOG_LEVEL_DEBUG:
13948 		host_trace_level = QDF_TRACE_LEVEL_DEBUG;
13949 		break;
13950 	case HOST_LOG_LEVEL_TRACE:
13951 		host_trace_level = QDF_TRACE_LEVEL_TRACE;
13952 		break;
13953 	default:
13954 		host_trace_level = QDF_TRACE_LEVEL_TRACE;
13955 		break;
13956 	}
13957 
13958 	bitmask = (1 << (host_trace_level + 1)) - 1;
13959 
13960 	return bitmask;
13961 }
13962 
13963 /**
13964  * hdd_set_trace_level_for_each - Set trace level for each INI config
13965  * @hdd_ctx: HDD context
13966  *
13967  * Set trace level for each module based on INI config.
13968  *
13969  * Return: None
13970  */
13971 static void hdd_set_trace_level_for_each(struct hdd_context *hdd_ctx)
13972 {
13973 	uint8_t host_module_log[QDF_MODULE_ID_MAX * 2];
13974 	qdf_size_t host_module_log_num = 0;
13975 	QDF_MODULE_ID module_id;
13976 	uint32_t bitmask;
13977 	uint32_t i;
13978 
13979 	qdf_uint8_array_parse(cfg_get(hdd_ctx->psoc,
13980 				      CFG_ENABLE_HOST_MODULE_LOG_LEVEL),
13981 			      host_module_log,
13982 			      QDF_MODULE_ID_MAX * 2,
13983 			      &host_module_log_num);
13984 
13985 	for (i = 0; i + 1 < host_module_log_num; i += 2) {
13986 		module_id = host_module_log[i];
13987 		bitmask = hdd_log_level_to_bitmask(host_module_log[i + 1]);
13988 		if (module_id < QDF_MODULE_ID_MAX &&
13989 		    module_id >= QDF_MODULE_ID_MIN)
13990 			hdd_qdf_trace_enable(module_id, bitmask);
13991 	}
13992 
13993 	hdd_set_mtrace_for_each(hdd_ctx);
13994 }
13995 
13996 /**
13997  * hdd_context_init() - Initialize HDD context
13998  * @hdd_ctx:	HDD context.
13999  *
14000  * Initialize HDD context along with all the feature specific contexts.
14001  *
14002  * return: 0 on success and errno on failure.
14003  */
14004 static int hdd_context_init(struct hdd_context *hdd_ctx)
14005 {
14006 	int ret;
14007 
14008 	hdd_ctx->ioctl_scan_mode = eSIR_ACTIVE_SCAN;
14009 	hdd_ctx->max_intf_count = WLAN_MAX_VDEVS;
14010 
14011 	init_completion(&hdd_ctx->mc_sus_event_var);
14012 	init_completion(&hdd_ctx->ready_to_suspend);
14013 
14014 	qdf_spinlock_create(&hdd_ctx->connection_status_lock);
14015 	qdf_spinlock_create(&hdd_ctx->hdd_adapter_lock);
14016 
14017 	qdf_list_create(&hdd_ctx->hdd_adapters, 0);
14018 
14019 	ret = hdd_scan_context_init(hdd_ctx);
14020 	if (ret)
14021 		goto list_destroy;
14022 
14023 	ret = hdd_sap_context_init(hdd_ctx);
14024 	if (ret)
14025 		goto scan_destroy;
14026 
14027 	ret = ucfg_dp_bbm_context_init(hdd_ctx->psoc);
14028 	if (ret)
14029 		goto sap_destroy;
14030 
14031 	wlan_hdd_cfg80211_extscan_init(hdd_ctx);
14032 
14033 	hdd_init_offloaded_packets_ctx(hdd_ctx);
14034 
14035 	ret = wlan_hdd_cfg80211_init(hdd_ctx->parent_dev, hdd_ctx->wiphy,
14036 				     hdd_ctx->config);
14037 	if (ret)
14038 		goto bbm_destroy;
14039 
14040 	qdf_wake_lock_create(&hdd_ctx->monitor_mode_wakelock,
14041 			     "monitor_mode_wakelock");
14042 	hdd_lp_create_work(hdd_ctx);
14043 
14044 	return 0;
14045 
14046 bbm_destroy:
14047 	ucfg_dp_bbm_context_deinit(hdd_ctx->psoc);
14048 
14049 sap_destroy:
14050 	hdd_sap_context_destroy(hdd_ctx);
14051 
14052 scan_destroy:
14053 	hdd_scan_context_destroy(hdd_ctx);
14054 list_destroy:
14055 	qdf_list_destroy(&hdd_ctx->hdd_adapters);
14056 
14057 	return ret;
14058 }
14059 
14060 #ifdef SHUTDOWN_WLAN_IN_SYSTEM_SUSPEND
14061 static void hdd_idle_timer_in_active(uint32_t timeout_ms)
14062 {
14063 	/* do nothing because idle shutdown will be called in system
14064 	 * suspend prepare
14065 	 */
14066 }
14067 #else
14068 /* ensure idle shutdown can be called/finished once timer started */
14069 static void hdd_idle_timer_in_active(uint32_t timeout_ms)
14070 {
14071 	uint32_t suspend_timeout_ms;
14072 	enum wake_lock_reason reason =
14073 		WIFI_POWER_EVENT_WAKELOCK_IFACE_CHANGE_TIMER;
14074 
14075 	suspend_timeout_ms = timeout_ms + HDD_PSOC_IDLE_SHUTDOWN_SUSPEND_DELAY;
14076 	hdd_prevent_suspend_timeout(suspend_timeout_ms, reason);
14077 }
14078 #endif
14079 
14080 void hdd_psoc_idle_timer_start(struct hdd_context *hdd_ctx)
14081 {
14082 	uint32_t timeout_ms = hdd_ctx->config->iface_change_wait_time;
14083 
14084 	if (!timeout_ms) {
14085 		hdd_info("psoc idle timer is disabled");
14086 		return;
14087 	}
14088 
14089 	hdd_debug("Starting psoc idle timer");
14090 
14091 	/* If PCIe gen speed change is requested, reduce idle shutdown
14092 	 * timeout to 100 ms
14093 	 */
14094 	if (hdd_ctx->current_pcie_gen_speed) {
14095 		timeout_ms = HDD_PCIE_GEN_SPEED_CHANGE_TIMEOUT_MS;
14096 		hdd_info("pcie gen speed change requested");
14097 	}
14098 
14099 	qdf_delayed_work_start(&hdd_ctx->psoc_idle_timeout_work, timeout_ms);
14100 	hdd_idle_timer_in_active(timeout_ms);
14101 }
14102 
14103 void hdd_psoc_idle_timer_stop(struct hdd_context *hdd_ctx)
14104 {
14105 	qdf_delayed_work_stop_sync(&hdd_ctx->psoc_idle_timeout_work);
14106 	hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_IFACE_CHANGE_TIMER);
14107 	hdd_debug("Stopped psoc idle timer");
14108 }
14109 
14110 
14111 /**
14112  * __hdd_psoc_idle_shutdown() - perform an idle shutdown on the given psoc
14113  * @hdd_ctx: the hdd context which should be shutdown
14114  *
14115  * When no interfaces are "up" on a psoc, an idle shutdown timer is started.
14116  * If no interfaces are brought up before the timer expires, we do an
14117  * "idle shutdown," cutting power to the physical SoC to save power. This is
14118  * done completely transparently from the perspective of userspace.
14119  *
14120  * Return: None
14121  */
14122 static int __hdd_psoc_idle_shutdown(struct hdd_context *hdd_ctx)
14123 {
14124 	struct osif_psoc_sync *psoc_sync;
14125 	int errno;
14126 
14127 	hdd_enter();
14128 
14129 	hdd_reg_wait_for_country_change(hdd_ctx);
14130 
14131 	errno = osif_psoc_sync_trans_start(hdd_ctx->parent_dev, &psoc_sync);
14132 	if (errno) {
14133 		hdd_info("psoc busy, abort idle shutdown; errno:%d", errno);
14134 		errno = -EAGAIN;
14135 		goto exit;
14136 	}
14137 
14138 	osif_psoc_sync_wait_for_ops(psoc_sync);
14139 	/*
14140 	 * This is to handle scenario in which platform driver triggers
14141 	 * idle_shutdown if Deep Sleep/Hibernate entry notification is
14142 	 * received from modem subsystem in wearable devices
14143 	 */
14144 	if (hdd_is_any_interface_open(hdd_ctx)) {
14145 		hdd_err_rl("all interfaces are not down, ignore idle shutdown");
14146 		errno = -EAGAIN;
14147 	} else {
14148 		errno = hdd_wlan_stop_modules(hdd_ctx, false);
14149 	}
14150 
14151 	osif_psoc_sync_trans_stop(psoc_sync);
14152 
14153 exit:
14154 	hdd_exit();
14155 	return errno;
14156 }
14157 
14158 static int __hdd_mode_change_psoc_idle_shutdown(struct hdd_context *hdd_ctx)
14159 {
14160 	is_mode_change_psoc_idle_shutdown = false;
14161 	return hdd_wlan_stop_modules(hdd_ctx, true);
14162 }
14163 
14164 int hdd_psoc_idle_shutdown(struct device *dev)
14165 {
14166 	int ret;
14167 	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
14168 
14169 	if (!hdd_ctx)
14170 		return -EINVAL;
14171 
14172 	if (is_mode_change_psoc_idle_shutdown)
14173 		ret = __hdd_mode_change_psoc_idle_shutdown(hdd_ctx);
14174 	else {
14175 		ret =  __hdd_psoc_idle_shutdown(hdd_ctx);
14176 	}
14177 
14178 	return ret;
14179 }
14180 
14181 static int __hdd_psoc_idle_restart(struct hdd_context *hdd_ctx)
14182 {
14183 	int ret;
14184 
14185 	ret = hdd_soc_idle_restart_lock(hdd_ctx->parent_dev);
14186 	if (ret)
14187 		return ret;
14188 
14189 	ret = hdd_wlan_start_modules(hdd_ctx, false);
14190 
14191 	if (!qdf_is_fw_down())
14192 		cds_set_recovery_in_progress(false);
14193 
14194 	hdd_soc_idle_restart_unlock();
14195 
14196 	return ret;
14197 }
14198 
14199 int hdd_psoc_idle_restart(struct device *dev)
14200 {
14201 	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
14202 
14203 	if (!hdd_ctx)
14204 		return -EINVAL;
14205 
14206 	return __hdd_psoc_idle_restart(hdd_ctx);
14207 }
14208 
14209 int hdd_trigger_psoc_idle_restart(struct hdd_context *hdd_ctx)
14210 {
14211 	int ret;
14212 
14213 	QDF_BUG(rtnl_is_locked());
14214 
14215 	hdd_psoc_idle_timer_stop(hdd_ctx);
14216 	if (hdd_ctx->driver_status == DRIVER_MODULES_ENABLED) {
14217 		hdd_nofl_debug("Driver modules already Enabled");
14218 		return 0;
14219 	}
14220 
14221 	ret = hdd_soc_idle_restart_lock(hdd_ctx->parent_dev);
14222 	if (ret)
14223 		return ret;
14224 
14225 	if (hdd_ctx->current_pcie_gen_speed) {
14226 		hdd_info("request pcie gen speed change to %d",
14227 			 hdd_ctx->current_pcie_gen_speed);
14228 
14229 		/* call pld api for pcie gen speed change */
14230 		ret  = pld_set_pcie_gen_speed(hdd_ctx->parent_dev,
14231 					      hdd_ctx->current_pcie_gen_speed);
14232 		if (ret)
14233 			hdd_err_rl("failed to set pcie gen speed");
14234 
14235 		hdd_ctx->current_pcie_gen_speed = 0;
14236 	}
14237 
14238 	qdf_event_reset(&hdd_ctx->regulatory_update_event);
14239 	qdf_mutex_acquire(&hdd_ctx->regulatory_status_lock);
14240 	hdd_ctx->is_regulatory_update_in_progress = true;
14241 	qdf_mutex_release(&hdd_ctx->regulatory_status_lock);
14242 
14243 	ret = pld_idle_restart(hdd_ctx->parent_dev, hdd_psoc_idle_restart);
14244 	hdd_soc_idle_restart_unlock();
14245 
14246 	return ret;
14247 }
14248 
14249 /**
14250  * hdd_psoc_idle_timeout_callback() - Handler for psoc idle timeout
14251  * @priv: pointer to hdd context
14252  *
14253  * Return: None
14254  */
14255 static void hdd_psoc_idle_timeout_callback(void *priv)
14256 {
14257 	int ret;
14258 	struct hdd_context *hdd_ctx = priv;
14259 	void *hif_ctx;
14260 
14261 	if (wlan_hdd_validate_context(hdd_ctx))
14262 		return;
14263 
14264 	hif_ctx = cds_get_context(QDF_MODULE_ID_HIF);
14265 	if (hif_ctx) {
14266 		/*
14267 		 * Trigger runtime sync resume before psoc_idle_shutdown
14268 		 * such that resume can happen successfully
14269 		 */
14270 		qdf_rtpm_sync_resume();
14271 	}
14272 
14273 	hdd_info("Psoc idle timeout elapsed; starting psoc shutdown");
14274 
14275 	ret = pld_idle_shutdown(hdd_ctx->parent_dev, hdd_psoc_idle_shutdown);
14276 	if (-EAGAIN == ret || hdd_ctx->is_wiphy_suspended) {
14277 		hdd_debug("System suspend in progress. Restart idle shutdown timer");
14278 		hdd_psoc_idle_timer_start(hdd_ctx);
14279 	}
14280 
14281 	/* Clear the recovery flag for PCIe discrete soc after idle shutdown*/
14282 	if (PLD_BUS_TYPE_PCIE == pld_get_bus_type(hdd_ctx->parent_dev) &&
14283 	    -EBUSY != ret)
14284 		cds_set_recovery_in_progress(false);
14285 }
14286 
14287 #ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
14288 static void hdd_set_wlan_logging(struct hdd_context *hdd_ctx)
14289 {
14290 	wlan_set_console_log_levels(hdd_ctx->config->wlan_console_log_levels);
14291 	wlan_logging_set_active(hdd_ctx->config->wlan_logging_enable);
14292 }
14293 #else
14294 static void hdd_set_wlan_logging(struct hdd_context *hdd_ctx)
14295 { }
14296 #endif
14297 
14298 #ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
14299 static void hdd_init_wlan_logging_params(struct hdd_config *config,
14300 					 struct wlan_objmgr_psoc *psoc)
14301 {
14302 	config->wlan_logging_enable = cfg_get(psoc, CFG_WLAN_LOGGING_SUPPORT);
14303 
14304 	config->wlan_console_log_levels =
14305 			cfg_get(psoc, CFG_WLAN_LOGGING_CONSOLE_SUPPORT);
14306 	config->host_log_custom_nl_proto =
14307 		cfg_get(psoc, CFG_HOST_LOG_CUSTOM_NETLINK_PROTO);
14308 }
14309 #else
14310 static void hdd_init_wlan_logging_params(struct hdd_config *config,
14311 					 struct wlan_objmgr_psoc *psoc)
14312 {
14313 }
14314 #endif
14315 
14316 #ifdef FEATURE_WLAN_AUTO_SHUTDOWN
14317 static void hdd_init_wlan_auto_shutdown(struct hdd_config *config,
14318 					struct wlan_objmgr_psoc *psoc)
14319 {
14320 	config->wlan_auto_shutdown = cfg_get(psoc, CFG_WLAN_AUTO_SHUTDOWN);
14321 }
14322 #else
14323 static void hdd_init_wlan_auto_shutdown(struct hdd_config *config,
14324 					struct wlan_objmgr_psoc *psoc)
14325 {
14326 }
14327 #endif
14328 
14329 #ifndef REMOVE_PKT_LOG
14330 static void hdd_init_packet_log(struct hdd_config *config,
14331 				struct wlan_objmgr_psoc *psoc)
14332 {
14333 	config->enable_packet_log = cfg_get(psoc, CFG_ENABLE_PACKET_LOG);
14334 }
14335 #else
14336 static void hdd_init_packet_log(struct hdd_config *config,
14337 				struct wlan_objmgr_psoc *psoc)
14338 {
14339 }
14340 #endif
14341 
14342 #ifdef ENABLE_MTRACE_LOG
14343 static void hdd_init_mtrace_log(struct hdd_config *config,
14344 				struct wlan_objmgr_psoc *psoc)
14345 {
14346 	config->enable_mtrace = cfg_get(psoc, CFG_ENABLE_MTRACE);
14347 }
14348 #else
14349 static void hdd_init_mtrace_log(struct hdd_config *config,
14350 				struct wlan_objmgr_psoc *psoc)
14351 {
14352 }
14353 #endif
14354 
14355 #ifdef FEATURE_RUNTIME_PM
14356 static void hdd_init_runtime_pm(struct hdd_config *config,
14357 				struct wlan_objmgr_psoc *psoc)
14358 {
14359 	config->runtime_pm = cfg_get(psoc, CFG_ENABLE_RUNTIME_PM);
14360 }
14361 
14362 bool hdd_is_runtime_pm_enabled(struct hdd_context *hdd_ctx)
14363 {
14364 	return hdd_ctx->config->runtime_pm != hdd_runtime_pm_disabled;
14365 }
14366 #else
14367 static void hdd_init_runtime_pm(struct hdd_config *config,
14368 				struct wlan_objmgr_psoc *psoc)
14369 
14370 {
14371 }
14372 
14373 bool hdd_is_runtime_pm_enabled(struct hdd_context *hdd_ctx)
14374 {
14375 	return false;
14376 }
14377 #endif
14378 
14379 #ifdef WLAN_FEATURE_WMI_SEND_RECV_QMI
14380 static void hdd_init_qmi_stats(struct hdd_config *config,
14381 			       struct wlan_objmgr_psoc *psoc)
14382 {
14383 	config->is_qmi_stats_enabled = cfg_get(psoc, CFG_ENABLE_QMI_STATS);
14384 }
14385 #else
14386 static void hdd_init_qmi_stats(struct hdd_config *config,
14387 			       struct wlan_objmgr_psoc *psoc)
14388 
14389 {
14390 }
14391 #endif
14392 
14393 #ifdef FEATURE_WLAN_DYNAMIC_CVM
14394 static void hdd_init_vc_mode_cfg_bitmap(struct hdd_config *config,
14395 					struct wlan_objmgr_psoc *psoc)
14396 {
14397 	config->vc_mode_cfg_bitmap = cfg_get(psoc, CFG_VC_MODE_BITMAP);
14398 }
14399 #else
14400 static void hdd_init_vc_mode_cfg_bitmap(struct hdd_config *config,
14401 					struct wlan_objmgr_psoc *psoc)
14402 {
14403 }
14404 #endif
14405 
14406 #ifdef DHCP_SERVER_OFFLOAD
14407 static void
14408 hdd_init_dhcp_server_ip(struct hdd_context *hdd_ctx)
14409 {
14410 	uint8_t num_entries;
14411 
14412 	hdd_ctx->config->dhcp_server_ip.is_dhcp_server_ip_valid = true;
14413 	hdd_string_to_u8_array(cfg_get(hdd_ctx->psoc, CFG_DHCP_SERVER_IP_NAME),
14414 			       hdd_ctx->config->dhcp_server_ip.dhcp_server_ip,
14415 			       &num_entries, IPADDR_NUM_ENTRIES);
14416 
14417 	if (num_entries != IPADDR_NUM_ENTRIES) {
14418 		hdd_err("Incorrect IP address (%s) assigned for DHCP server!",
14419 			cfg_get(hdd_ctx->psoc, CFG_DHCP_SERVER_IP_NAME));
14420 		hdd_config->dhcp_server_ip.is_dhcp_server_ip_valid = false;
14421 	}
14422 }
14423 #else
14424 static void
14425 hdd_init_dhcp_server_ip(struct hdd_context *hdd_ctx)
14426 {
14427 }
14428 #endif
14429 
14430 #ifdef SAR_SAFETY_FEATURE
14431 static void hdd_sar_cfg_update(struct hdd_config *config,
14432 			       struct wlan_objmgr_psoc *psoc)
14433 {
14434 	config->sar_safety_timeout = cfg_get(psoc, CFG_SAR_SAFETY_TIMEOUT);
14435 	config->sar_safety_unsolicited_timeout =
14436 			cfg_get(psoc, CFG_SAR_SAFETY_UNSOLICITED_TIMEOUT);
14437 	config->sar_safety_req_resp_timeout =
14438 				cfg_get(psoc, CFG_SAR_SAFETY_REQ_RESP_TIMEOUT);
14439 	config->sar_safety_req_resp_retry =
14440 				cfg_get(psoc, CFG_SAR_SAFETY_REQ_RESP_RETRIES);
14441 	config->sar_safety_index = cfg_get(psoc, CFG_SAR_SAFETY_INDEX);
14442 	config->sar_safety_sleep_index =
14443 				cfg_get(psoc, CFG_SAR_SAFETY_SLEEP_INDEX);
14444 	config->enable_sar_safety =
14445 				cfg_get(psoc, CFG_ENABLE_SAR_SAFETY_FEATURE);
14446 	config->config_sar_safety_sleep_index =
14447 			cfg_get(psoc, CFG_CONFIG_SAR_SAFETY_SLEEP_MODE_INDEX);
14448 }
14449 
14450 void hdd_set_sar_init_index(struct hdd_context *hdd_ctx)
14451 {
14452 	uint32_t index, enable = 0;
14453 
14454 	if (!hdd_ctx) {
14455 		hdd_err("hdd_ctx NULL");
14456 		return;
14457 	}
14458 	if (hdd_ctx->sar_version == SAR_VERSION_1) {
14459 		hdd_nofl_debug("FW SAR version: %d", hdd_ctx->sar_version);
14460 		return;
14461 	}
14462 
14463 	enable = hdd_ctx->config->enable_sar_safety;
14464 	index = hdd_ctx->config->sar_safety_index;
14465 	if (enable & SAR_SAFETY_ENABLED_INIT)
14466 		hdd_configure_sar_index(hdd_ctx, index);
14467 }
14468 #else
14469 static void hdd_sar_cfg_update(struct hdd_config *config,
14470 			       struct wlan_objmgr_psoc *psoc)
14471 {
14472 }
14473 #endif
14474 
14475 #ifdef FEATURE_SET
14476 /**
14477  * hdd_get_wifi_features_cfg_update() - Initialize get wifi features cfg
14478  * @config: Pointer to HDD config
14479  * @psoc: psoc pointer
14480  *
14481  * Return: None
14482  */
14483 static void hdd_get_wifi_features_cfg_update(struct hdd_config *config,
14484 					     struct wlan_objmgr_psoc *psoc)
14485 {
14486 	config->get_wifi_features = cfg_get(psoc, CFG_GET_WIFI_FEATURES);
14487 }
14488 #else
14489 static void hdd_get_wifi_features_cfg_update(struct hdd_config *config,
14490 					     struct wlan_objmgr_psoc *psoc)
14491 {
14492 }
14493 #endif
14494 
14495 #ifdef FEATURE_RUNTIME_PM
14496 /**
14497  * hdd_init_cpu_cxpc_threshold_cfg() - Initialize cpu cxpc threshold cfg
14498  * @config: Pointer to HDD config
14499  * @psoc: psoc pointer
14500  *
14501  * Return: None
14502  */
14503 static void hdd_init_cpu_cxpc_threshold_cfg(struct hdd_config *config,
14504 					    struct wlan_objmgr_psoc *psoc)
14505 {
14506 	config->cpu_cxpc_threshold = cfg_get(psoc, CFG_CPU_CXPC_THRESHOLD);
14507 }
14508 #else
14509 static void hdd_init_cpu_cxpc_threshold_cfg(struct hdd_config *config,
14510 					    struct wlan_objmgr_psoc *psoc)
14511 {
14512 }
14513 #endif
14514 
14515 /**
14516  * hdd_cfg_params_init() - Initialize hdd params in hdd_config structure
14517  * @hdd_ctx: Pointer to HDD context
14518  *
14519  * Return: None
14520  */
14521 static void hdd_cfg_params_init(struct hdd_context *hdd_ctx)
14522 {
14523 	struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc;
14524 	struct hdd_config *config = hdd_ctx->config;
14525 	if (!psoc) {
14526 		hdd_err("Invalid psoc");
14527 		return;
14528 	}
14529 
14530 	if (!config) {
14531 		hdd_err("Invalid hdd config");
14532 		return;
14533 	}
14534 
14535 	config->dot11Mode = cfg_get(psoc, CFG_HDD_DOT11_MODE);
14536 	config->bug_on_reinit_failure = cfg_get(psoc,
14537 						CFG_BUG_ON_REINIT_FAILURE);
14538 
14539 	config->is_ramdump_enabled = cfg_get(psoc,
14540 					     CFG_ENABLE_RAMDUMP_COLLECTION);
14541 
14542 	config->iface_change_wait_time = cfg_get(psoc,
14543 						 CFG_INTERFACE_CHANGE_WAIT);
14544 
14545 	config->multicast_host_fw_msgs = cfg_get(psoc,
14546 						 CFG_MULTICAST_HOST_FW_MSGS);
14547 
14548 	config->private_wext_control = cfg_get(psoc, CFG_PRIVATE_WEXT_CONTROL);
14549 	config->enablefwprint = cfg_get(psoc, CFG_ENABLE_FW_UART_PRINT);
14550 	config->enable_fw_log = cfg_get(psoc, CFG_ENABLE_FW_LOG);
14551 	config->operating_chan_freq = cfg_get(psoc, CFG_OPERATING_FREQUENCY);
14552 	config->num_vdevs = cfg_get(psoc, CFG_NUM_VDEV_ENABLE);
14553 	qdf_str_lcopy(config->enable_concurrent_sta,
14554 		      cfg_get(psoc, CFG_ENABLE_CONCURRENT_STA),
14555 		      CFG_CONCURRENT_IFACE_MAX_LEN);
14556 	qdf_str_lcopy(config->dbs_scan_selection,
14557 		      cfg_get(psoc, CFG_DBS_SCAN_SELECTION),
14558 		      CFG_DBS_SCAN_PARAM_LENGTH);
14559 	config->inform_bss_rssi_raw = cfg_get(psoc, CFG_INFORM_BSS_RSSI_RAW);
14560 	config->mac_provision = cfg_get(psoc, CFG_ENABLE_MAC_PROVISION);
14561 	config->provisioned_intf_pool =
14562 				cfg_get(psoc, CFG_PROVISION_INTERFACE_POOL);
14563 	config->derived_intf_pool = cfg_get(psoc, CFG_DERIVED_INTERFACE_POOL);
14564 	config->advertise_concurrent_operation =
14565 				cfg_get(psoc,
14566 					CFG_ADVERTISE_CONCURRENT_OPERATION);
14567 	config->is_unit_test_framework_enabled =
14568 			cfg_get(psoc, CFG_ENABLE_UNIT_TEST_FRAMEWORK);
14569 	config->disable_channel = cfg_get(psoc, CFG_ENABLE_DISABLE_CHANNEL);
14570 	config->enable_sar_conversion = cfg_get(psoc, CFG_SAR_CONVERSION);
14571 	config->nb_commands_interval =
14572 				cfg_get(psoc, CFG_NB_COMMANDS_RATE_LIMIT);
14573 
14574 	hdd_init_vc_mode_cfg_bitmap(config, psoc);
14575 	hdd_init_runtime_pm(config, psoc);
14576 	hdd_init_wlan_auto_shutdown(config, psoc);
14577 	hdd_init_wlan_logging_params(config, psoc);
14578 	hdd_init_packet_log(config, psoc);
14579 	hdd_init_mtrace_log(config, psoc);
14580 	hdd_init_dhcp_server_ip(hdd_ctx);
14581 	hdd_dp_cfg_update(psoc, hdd_ctx);
14582 	hdd_sar_cfg_update(config, psoc);
14583 	hdd_init_qmi_stats(config, psoc);
14584 	hdd_club_ll_stats_in_get_sta_cfg_update(config, psoc);
14585 	config->read_mac_addr_from_mac_file =
14586 			cfg_get(psoc, CFG_READ_MAC_ADDR_FROM_MAC_FILE);
14587 
14588 	hdd_get_wifi_features_cfg_update(config, psoc);
14589 	hdd_init_cpu_cxpc_threshold_cfg(config, psoc);
14590 
14591 	config->exclude_selftx_from_cca_busy =
14592 			cfg_get(psoc, CFG_EXCLUDE_SELFTX_FROM_CCA_BUSY_TIME);
14593 	hdd_init_link_state_cfg(config, psoc);
14594 }
14595 
14596 #ifdef CONNECTION_ROAMING_CFG
14597 static QDF_STATUS hdd_cfg_parse_connection_roaming_cfg(void)
14598 {
14599 	QDF_STATUS status = QDF_STATUS_E_INVAL;
14600 	bool is_valid;
14601 
14602 	is_valid = cfg_valid_ini_check(WLAN_CONNECTION_ROAMING_INI_FILE);
14603 
14604 	if (is_valid)
14605 		status = cfg_parse(WLAN_CONNECTION_ROAMING_INI_FILE);
14606 	if (QDF_IS_STATUS_ERROR(status)) {
14607 		is_valid = cfg_valid_ini_check(WLAN_CONNECTION_ROAMING_BACKUP_INI_FILE);
14608 		if (is_valid)
14609 			status = cfg_parse(WLAN_CONNECTION_ROAMING_BACKUP_INI_FILE);
14610 	}
14611 	return status;
14612 }
14613 #else
14614 static inline QDF_STATUS hdd_cfg_parse_connection_roaming_cfg(void)
14615 {
14616 	return QDF_STATUS_E_NOSUPPORT;
14617 }
14618 #endif
14619 
14620 struct hdd_context *hdd_context_create(struct device *dev)
14621 {
14622 	QDF_STATUS status;
14623 	int ret = 0;
14624 	struct hdd_context *hdd_ctx;
14625 
14626 	hdd_enter();
14627 
14628 	hdd_ctx = hdd_cfg80211_wiphy_alloc();
14629 	if (!hdd_ctx) {
14630 		ret = -ENOMEM;
14631 		goto err_out;
14632 	}
14633 
14634 	status = qdf_delayed_work_create(&hdd_ctx->psoc_idle_timeout_work,
14635 					 hdd_psoc_idle_timeout_callback,
14636 					 hdd_ctx);
14637 	if (QDF_IS_STATUS_ERROR(status)) {
14638 		ret = qdf_status_to_os_return(status);
14639 		goto wiphy_dealloc;
14640 	}
14641 
14642 	hdd_pm_notifier_init(hdd_ctx);
14643 
14644 	hdd_ctx->parent_dev = dev;
14645 	hdd_ctx->last_scan_reject_vdev_id = WLAN_UMAC_VDEV_ID_MAX;
14646 
14647 	hdd_ctx->config = qdf_mem_malloc(sizeof(struct hdd_config));
14648 	if (!hdd_ctx->config) {
14649 		ret = -ENOMEM;
14650 		goto err_free_hdd_context;
14651 	}
14652 
14653 	status = cfg_parse(WLAN_INI_FILE);
14654 	if (QDF_IS_STATUS_ERROR(status)) {
14655 		hdd_err("Failed to parse cfg %s; status:%d\n",
14656 			WLAN_INI_FILE, status);
14657 		/* Assert if failed to parse at least one INI parameter */
14658 		QDF_BUG(status != QDF_STATUS_E_INVAL);
14659 		ret = qdf_status_to_os_return(status);
14660 		goto err_free_config;
14661 	}
14662 
14663 	status = hdd_cfg_parse_connection_roaming_cfg();
14664 
14665 	ret = hdd_objmgr_create_and_store_psoc(hdd_ctx, DEFAULT_PSOC_ID);
14666 	if (ret) {
14667 		QDF_DEBUG_PANIC("Psoc creation fails!");
14668 		goto err_release_store;
14669 	}
14670 
14671 	if (QDF_IS_STATUS_SUCCESS(status))
14672 		ucfg_mlme_set_connection_roaming_ini_present(hdd_ctx->psoc,
14673 							     true);
14674 
14675 	hdd_cfg_params_init(hdd_ctx);
14676 
14677 	/* apply multiplier config, if not already set via module parameter */
14678 	if (qdf_timer_get_multiplier() == 1)
14679 		qdf_timer_set_multiplier(cfg_get(hdd_ctx->psoc,
14680 						 CFG_TIMER_MULTIPLIER));
14681 	hdd_debug("set timer multiplier: %u", qdf_timer_get_multiplier());
14682 
14683 	cds_set_fatal_event(cfg_get(hdd_ctx->psoc,
14684 				    CFG_ENABLE_FATAL_EVENT_TRIGGER));
14685 
14686 	hdd_override_ini_config(hdd_ctx);
14687 
14688 	ret = hdd_context_init(hdd_ctx);
14689 
14690 	if (ret)
14691 		goto err_hdd_objmgr_destroy;
14692 
14693 	if (hdd_get_conparam() == QDF_GLOBAL_EPPING_MODE)
14694 		goto skip_multicast_logging;
14695 
14696 	cds_set_multicast_logging(hdd_ctx->config->multicast_host_fw_msgs);
14697 	ret = hdd_init_netlink_services(hdd_ctx);
14698 	if (ret)
14699 		goto err_deinit_hdd_context;
14700 
14701 	hdd_set_wlan_logging(hdd_ctx);
14702 	qdf_atomic_init(&hdd_ctx->adapter_ops_history.index);
14703 
14704 skip_multicast_logging:
14705 	hdd_set_trace_level_for_each(hdd_ctx);
14706 
14707 	cds_set_context(QDF_MODULE_ID_HDD, hdd_ctx);
14708 
14709 	wlan_hdd_sar_timers_init(hdd_ctx);
14710 
14711 	hdd_exit();
14712 
14713 	return hdd_ctx;
14714 
14715 err_deinit_hdd_context:
14716 	hdd_context_deinit(hdd_ctx);
14717 
14718 err_hdd_objmgr_destroy:
14719 	hdd_objmgr_release_and_destroy_psoc(hdd_ctx);
14720 
14721 err_release_store:
14722 	cfg_release();
14723 
14724 err_free_config:
14725 	qdf_mem_free(hdd_ctx->config);
14726 
14727 err_free_hdd_context:
14728 	qdf_delayed_work_destroy(&hdd_ctx->psoc_idle_timeout_work);
14729 
14730 wiphy_dealloc:
14731 	wiphy_free(hdd_ctx->wiphy);
14732 
14733 err_out:
14734 	return ERR_PTR(ret);
14735 }
14736 
14737 #ifdef MULTI_CLIENT_LL_SUPPORT
14738 /**
14739  * wlan_hdd_init_multi_client_info_table()- Initialize the multi client info
14740  * table
14741  * @adapter: hdd adapter
14742  *
14743  * Return: none
14744  */
14745 static void
14746 wlan_hdd_init_multi_client_info_table(struct hdd_adapter *adapter)
14747 {
14748 	uint8_t i;
14749 
14750 	for (i = 0; i < WLM_MAX_HOST_CLIENT; i++) {
14751 		adapter->client_info[i].client_id = i;
14752 		adapter->client_info[i].port_id = 0;
14753 		adapter->client_info[i].in_use = false;
14754 	}
14755 }
14756 
14757 void wlan_hdd_deinit_multi_client_info_table(struct hdd_adapter *adapter)
14758 {
14759 	uint8_t i;
14760 
14761 	hdd_debug("deinitializing the client info table");
14762 	/* de-initialize the table for host driver client */
14763 	for (i = 0; i < WLM_MAX_HOST_CLIENT; i++) {
14764 		if (adapter->client_info[i].in_use) {
14765 			adapter->client_info[i].port_id = 0;
14766 			adapter->client_info[i].client_id = i;
14767 			adapter->client_info[i].in_use = false;
14768 		}
14769 	}
14770 }
14771 
14772 /**
14773  * wlan_hdd_get_host_driver_port_id()- get host driver port id
14774  * @port_id: argument to be filled
14775  *
14776  * Return: none
14777  */
14778 static void wlan_hdd_get_host_driver_port_id(uint32_t *port_id)
14779 {
14780 	*port_id = WLAM_WLM_HOST_DRIVER_PORT_ID;
14781 }
14782 
14783 #else
14784 static inline void
14785 wlan_hdd_init_multi_client_info_table(struct hdd_adapter *adapter)
14786 {
14787 }
14788 
14789 static inline void wlan_hdd_get_host_driver_port_id(uint32_t *port_id)
14790 {
14791 }
14792 #endif
14793 
14794 static void
14795 hdd_adapter_set_wlm_client_latency_level(struct hdd_adapter *adapter)
14796 {
14797 	QDF_STATUS status;
14798 	bool reset;
14799 	uint32_t port_id;
14800 	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
14801 
14802 	if (!hdd_ctx)
14803 		return;
14804 
14805 	status = ucfg_mlme_cfg_get_wlm_reset(hdd_ctx->psoc, &reset);
14806 	if (QDF_IS_STATUS_ERROR(status)) {
14807 		hdd_err("could not get the wlm reset flag");
14808 		reset = false;
14809 	}
14810 
14811 	if (reset)
14812 		goto out;
14813 
14814 	if (hdd_get_multi_client_ll_support(adapter)) {
14815 		wlan_hdd_get_host_driver_port_id(&port_id);
14816 		status = wlan_hdd_set_wlm_client_latency_level(
14817 						adapter, port_id,
14818 						adapter->latency_level);
14819 		if (QDF_IS_STATUS_ERROR(status))
14820 			hdd_warn("Fail to set latency level:%u", status);
14821 	} else {
14822 		status = sme_set_wlm_latency_level(hdd_ctx->mac_handle,
14823 						   adapter->deflink->vdev_id,
14824 						   adapter->latency_level,
14825 						   0, false);
14826 		if (QDF_IS_STATUS_ERROR(status))
14827 			hdd_warn("set wlm mode failed, %u", status);
14828 	}
14829 out:
14830 	hdd_debug("wlm initial mode %u", adapter->latency_level);
14831 }
14832 
14833 #ifdef WLAN_HDD_MULTI_VDEV_SINGLE_NDEV
14834 struct qdf_mac_addr *
14835 hdd_adapter_get_link_mac_addr(struct wlan_hdd_link_info *link_info)
14836 {
14837 	struct hdd_adapter *adapter;
14838 
14839 	if (!link_info)
14840 		return NULL;
14841 
14842 	adapter = link_info->adapter;
14843 	if (!hdd_adapter_is_ml_adapter(adapter) ||
14844 	    qdf_is_macaddr_zero(&link_info->link_addr) ||
14845 	    !wlan_vdev_mlme_is_mlo_vdev(link_info->vdev))
14846 		return &adapter->mac_addr;
14847 
14848 	return &link_info->link_addr;
14849 }
14850 #else
14851 struct qdf_mac_addr *
14852 hdd_adapter_get_link_mac_addr(struct wlan_hdd_link_info *link_info)
14853 {
14854 	if (!link_info)
14855 		return NULL;
14856 
14857 	return &link_info->adapter->mac_addr;
14858 }
14859 #endif
14860 
14861 #if defined(WLAN_FEATURE_11BE_MLO) && defined(CFG80211_11BE_BASIC) && \
14862 	defined(WLAN_HDD_MULTI_VDEV_SINGLE_NDEV)
14863 QDF_STATUS hdd_adapter_check_duplicate_session(struct hdd_adapter *adapter)
14864 {
14865 	int i = 0;
14866 	QDF_STATUS status;
14867 	uint8_t *addr_list[WLAN_MAX_MLD + 2] = {0};
14868 	struct wlan_hdd_link_info *link_info;
14869 
14870 	if (!hdd_adapter_is_ml_adapter(adapter) ||
14871 	    adapter->device_mode == QDF_SAP_MODE)
14872 		goto netdev_addr;
14873 
14874 	hdd_adapter_for_each_active_link_info(adapter, link_info)
14875 		addr_list[i++] = &link_info->link_addr.bytes[0];
14876 
14877 netdev_addr:
14878 	addr_list[i] = &adapter->mac_addr.bytes[0];
14879 	status = sme_check_for_duplicate_session(adapter->hdd_ctx->mac_handle,
14880 						 &addr_list[0]);
14881 	return status;
14882 }
14883 
14884 QDF_STATUS hdd_adapter_fill_link_address(struct hdd_adapter *adapter)
14885 {
14886 	int i = 0;
14887 	QDF_STATUS status;
14888 	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
14889 	enum QDF_OPMODE opmode = adapter->device_mode;
14890 	struct qdf_mac_addr link_addrs[WLAN_MAX_ML_BSS_LINKS] = {0};
14891 	struct wlan_hdd_link_info *link_info;
14892 
14893 	if (opmode != QDF_STA_MODE && opmode != QDF_SAP_MODE)
14894 		return QDF_STATUS_SUCCESS;
14895 
14896 	if (opmode == QDF_SAP_MODE) {
14897 		link_info = adapter->deflink;
14898 		qdf_copy_macaddr(&link_info->link_addr, &adapter->mac_addr);
14899 		return QDF_STATUS_SUCCESS;
14900 	}
14901 
14902 	if (!hdd_adapter_is_ml_adapter(adapter))
14903 		return QDF_STATUS_SUCCESS;
14904 
14905 	status = hdd_derive_link_address_from_mld(hdd_ctx->psoc,
14906 						  &adapter->mac_addr,
14907 						  &link_addrs[0],
14908 						  WLAN_MAX_ML_BSS_LINKS);
14909 	if (QDF_IS_STATUS_ERROR(status))
14910 		return status;
14911 
14912 	hdd_adapter_for_each_link_info(adapter, link_info)
14913 		qdf_copy_macaddr(&link_info->link_addr, &link_addrs[i++]);
14914 
14915 	return status;
14916 }
14917 #elif defined(WLAN_FEATURE_11BE_MLO) && defined(CFG80211_11BE_BASIC)
14918 QDF_STATUS hdd_adapter_check_duplicate_session(struct hdd_adapter *adapter)
14919 {
14920 	int i;
14921 	QDF_STATUS status;
14922 	uint8_t *addr_list[WLAN_MAX_MLD + 1] = {0};
14923 	struct hdd_adapter *link_adapter;
14924 	struct hdd_mlo_adapter_info *mlo_adapter_info;
14925 	mac_handle_t mac_handle = hdd_adapter_get_mac_handle(adapter);
14926 
14927 	if (hdd_adapter_is_ml_adapter(adapter) &&
14928 	    adapter->device_mode == QDF_STA_MODE) {
14929 		addr_list[0] = &adapter->mld_addr.bytes[0];
14930 		mlo_adapter_info = &adapter->mlo_adapter_info;
14931 		for (i = 0; i < WLAN_MAX_MLD; i++) {
14932 			link_adapter = mlo_adapter_info->link_adapter[i];
14933 			if (!link_adapter)
14934 				continue;
14935 			if (hdd_adapter_is_associated_with_ml_adapter(
14936 							link_adapter)) {
14937 				addr_list[1] = &link_adapter->mac_addr.bytes[0];
14938 			}
14939 		}
14940 	} else {
14941 		addr_list[0] = &adapter->mac_addr.bytes[0];
14942 	}
14943 
14944 	status = sme_check_for_duplicate_session(mac_handle, &addr_list[0]);
14945 	return status;
14946 }
14947 #else
14948 QDF_STATUS hdd_adapter_check_duplicate_session(struct hdd_adapter *adapter)
14949 {
14950 	QDF_STATUS status;
14951 	uint8_t *addr_list[2] = {0};
14952 	mac_handle_t mac_handle = hdd_adapter_get_mac_handle(adapter);
14953 
14954 	addr_list[0] = &adapter->mac_addr.bytes[0];
14955 	status = sme_check_for_duplicate_session(mac_handle, &addr_list[0]);
14956 
14957 	return status;
14958 }
14959 #endif
14960 
14961 static void hdd_restore_info_for_ssr(struct hdd_adapter *adapter)
14962 {
14963 	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
14964 
14965 	if (cds_is_driver_recovering()) {
14966 		/* ssr happens, recover the info */
14967 		hdd_set_vdev_phy_mode(adapter, adapter->user_phy_mode);
14968 		wlan_mlme_restore_user_set_link_num(hdd_ctx->psoc);
14969 	} else {
14970 		/* intf down/up happens, reset default info */
14971 		hdd_set_vdev_phy_mode(adapter, QCA_WLAN_VENDOR_PHY_MODE_AUTO);
14972 		wlan_mlme_clear_user_set_link_num(hdd_ctx->psoc);
14973 	}
14974 }
14975 
14976 void hdd_adapter_reset_station_ctx(struct hdd_adapter *adapter)
14977 {
14978 	struct wlan_hdd_link_info *link_info;
14979 	struct hdd_station_ctx *sta_ctx;
14980 
14981 	hdd_adapter_for_each_link_info(adapter, link_info) {
14982 		sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(link_info);
14983 		qdf_mem_zero(&sta_ctx->conn_info.bssid, QDF_MAC_ADDR_SIZE);
14984 
14985 		hdd_cm_clear_ieee_link_id(link_info);
14986 		sta_ctx->user_cfg_chn_width = CH_WIDTH_INVALID;
14987 	}
14988 }
14989 
14990 int hdd_start_station_adapter(struct hdd_adapter *adapter)
14991 {
14992 	QDF_STATUS status;
14993 	int ret;
14994 	struct wlan_hdd_link_info *link_info;
14995 
14996 	hdd_enter_dev(adapter->dev);
14997 	if (test_bit(SME_SESSION_OPENED, &adapter->deflink->link_flags)) {
14998 		hdd_err("session is already opened, %d",
14999 			adapter->deflink->vdev_id);
15000 		return qdf_status_to_os_return(QDF_STATUS_SUCCESS);
15001 	}
15002 
15003 	if ((adapter->device_mode == QDF_P2P_DEVICE_MODE) ||
15004 	    (adapter->device_mode == QDF_NAN_DISC_MODE))
15005 		wlan_hdd_lpc_del_monitor_interface(adapter->hdd_ctx, false);
15006 
15007 	status = hdd_adapter_fill_link_address(adapter);
15008 	if (QDF_IS_STATUS_ERROR(status)) {
15009 		hdd_debug("Link address derive failed");
15010 		return qdf_status_to_os_return(status);
15011 	}
15012 
15013 	status = hdd_adapter_check_duplicate_session(adapter);
15014 	if (QDF_IS_STATUS_ERROR(status)) {
15015 		hdd_err("Duplicate session is existing with same mac address");
15016 		return qdf_status_to_os_return(status);
15017 	}
15018 
15019 	hdd_adapter_for_each_active_link_info(adapter, link_info) {
15020 		ret = hdd_vdev_create(link_info);
15021 		if (ret) {
15022 			hdd_err("failed to create vdev: %d", ret);
15023 			goto fail;
15024 		}
15025 
15026 		status = hdd_init_station_mode(link_info);
15027 		if (QDF_STATUS_SUCCESS != status) {
15028 			hdd_err("Error Initializing station mode: %d", status);
15029 			ret = qdf_status_to_os_return(status);
15030 			goto fail;
15031 		}
15032 	}
15033 
15034 	hdd_adapter_reset_station_ctx(adapter);
15035 
15036 	hdd_register_wext(adapter->dev);
15037 	hdd_set_netdev_flags(adapter);
15038 
15039 	hdd_register_tx_flow_control(adapter,
15040 		hdd_tx_resume_timer_expired_handler,
15041 		hdd_tx_resume_cb,
15042 		hdd_tx_flow_control_is_pause);
15043 
15044 	hdd_register_hl_netdev_fc_timer(adapter,
15045 					hdd_tx_resume_timer_expired_handler);
15046 
15047 	if (hdd_get_multi_client_ll_support(adapter))
15048 		wlan_hdd_init_multi_client_info_table(adapter);
15049 
15050 	hdd_adapter_set_wlm_client_latency_level(adapter);
15051 	hdd_adapter_update_mlo_mgr_mac_addr(adapter);
15052 	hdd_restore_info_for_ssr(adapter);
15053 
15054 	hdd_exit();
15055 	return 0;
15056 
15057 fail:
15058 	hdd_adapter_for_each_active_link_info(adapter, link_info)
15059 		hdd_vdev_destroy(link_info);
15060 
15061 	return ret;
15062 }
15063 
15064 int hdd_start_ap_adapter(struct hdd_adapter *adapter, bool rtnl_held)
15065 {
15066 	QDF_STATUS status;
15067 	bool is_ssr = false;
15068 	int ret;
15069 	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
15070 	struct sap_context *sap_ctx;
15071 	struct wlan_hdd_link_info *link_info = adapter->deflink;
15072 
15073 	hdd_enter();
15074 
15075 	if (test_bit(SME_SESSION_OPENED, &link_info->link_flags)) {
15076 		hdd_err("session is already opened, %d",
15077 			link_info->vdev_id);
15078 		return qdf_status_to_os_return(QDF_STATUS_SUCCESS);
15079 	}
15080 
15081 	status = hdd_adapter_fill_link_address(adapter);
15082 	if (QDF_IS_STATUS_ERROR(status)) {
15083 		hdd_debug("Link address derive failed");
15084 		return qdf_status_to_os_return(status);
15085 	}
15086 
15087 	status = hdd_adapter_check_duplicate_session(adapter);
15088 	if (QDF_IS_STATUS_ERROR(status)) {
15089 		hdd_err("Duplicate session is existing with same mac address");
15090 		return qdf_status_to_os_return(status);
15091 	}
15092 
15093 	/*
15094 	 * In SSR case no need to create new sap context.
15095 	 * Otherwise create sap context first and then create
15096 	 * vdev as while creating the vdev, driver needs to
15097 	 * register SAP callback and that callback uses sap context
15098 	 */
15099 	if (WLAN_HDD_GET_SAP_CTX_PTR(link_info)) {
15100 		is_ssr = true;
15101 	} else if (!hdd_sap_create_ctx(adapter)) {
15102 		hdd_err("sap creation failed");
15103 		return qdf_status_to_os_return(QDF_STATUS_E_FAILURE);
15104 	}
15105 
15106 	ret = hdd_vdev_create(link_info);
15107 	if (ret) {
15108 		hdd_err("failed to create vdev, status:%d", ret);
15109 		goto sap_destroy_ctx;
15110 	}
15111 
15112 	sap_ctx = WLAN_HDD_GET_SAP_CTX_PTR(link_info);
15113 	status = sap_acquire_vdev_ref(hdd_ctx->psoc, sap_ctx,
15114 				      link_info->vdev_id);
15115 	if (!QDF_IS_STATUS_SUCCESS(status)) {
15116 		hdd_err("Failed to get vdev ref for sap for session_id: %u",
15117 			link_info->vdev_id);
15118 		ret = qdf_status_to_os_return(status);
15119 		goto sap_vdev_destroy;
15120 	}
15121 
15122 	if (adapter->device_mode == QDF_SAP_MODE) {
15123 		status = hdd_vdev_configure_rtt_params(sap_ctx->vdev);
15124 		if (QDF_IS_STATUS_ERROR(status))
15125 			goto sap_release_ref;
15126 	}
15127 
15128 	status = hdd_init_ap_mode(adapter, is_ssr, rtnl_held);
15129 	if (QDF_STATUS_SUCCESS != status) {
15130 		hdd_err("Error Initializing the AP mode: %d", status);
15131 		ret = qdf_status_to_os_return(status);
15132 		goto sap_release_ref;
15133 	}
15134 
15135 	hdd_register_tx_flow_control(adapter,
15136 		hdd_softap_tx_resume_timer_expired_handler,
15137 		hdd_softap_tx_resume_cb,
15138 		hdd_tx_flow_control_is_pause);
15139 
15140 	hdd_register_hl_netdev_fc_timer(adapter,
15141 					hdd_tx_resume_timer_expired_handler);
15142 
15143 	if (cds_is_driver_recovering())
15144 		hdd_medium_assess_ssr_reinit();
15145 
15146 	hdd_exit();
15147 	return 0;
15148 
15149 sap_release_ref:
15150 	sap_release_vdev_ref(sap_ctx);
15151 sap_vdev_destroy:
15152 	hdd_vdev_destroy(link_info);
15153 sap_destroy_ctx:
15154 	hdd_sap_destroy_ctx(link_info);
15155 	return ret;
15156 }
15157 
15158 #if defined(QCA_LL_TX_FLOW_CONTROL_V2) || defined(QCA_LL_PDEV_TX_FLOW_CONTROL)
15159 /**
15160  * hdd_txrx_populate_cds_config() - Populate txrx cds configuration
15161  * @cds_cfg: CDS Configuration
15162  * @hdd_ctx: Pointer to hdd context
15163  *
15164  * Return: none
15165  */
15166 static inline void hdd_txrx_populate_cds_config(struct cds_config_info
15167 						*cds_cfg,
15168 						struct hdd_context *hdd_ctx)
15169 {
15170 	cds_cfg->tx_flow_stop_queue_th =
15171 		cfg_get(hdd_ctx->psoc, CFG_DP_TX_FLOW_STOP_QUEUE_TH);
15172 	cds_cfg->tx_flow_start_queue_offset =
15173 		cfg_get(hdd_ctx->psoc, CFG_DP_TX_FLOW_START_QUEUE_OFFSET);
15174 	/* configuration for DP RX Threads */
15175 	cds_cfg->enable_dp_rx_threads =
15176 		ucfg_dp_is_rx_threads_enabled(hdd_ctx->psoc);
15177 }
15178 #else
15179 static inline void hdd_txrx_populate_cds_config(struct cds_config_info
15180 						*cds_cfg,
15181 						struct hdd_context *hdd_ctx)
15182 {
15183 }
15184 #endif
15185 
15186 /**
15187  * hdd_update_cds_config() - API to update cds configuration parameters
15188  * @hdd_ctx: HDD Context
15189  *
15190  * Return: 0 for Success, errno on failure
15191  */
15192 static int hdd_update_cds_config(struct hdd_context *hdd_ctx)
15193 {
15194 	struct cds_config_info *cds_cfg;
15195 	int value;
15196 	uint8_t band_capability;
15197 	uint32_t band_bitmap;
15198 	uint8_t ito_repeat_count;
15199 	bool crash_inject;
15200 	bool self_recovery;
15201 	bool fw_timeout_crash;
15202 	QDF_STATUS status;
15203 
15204 	cds_cfg = qdf_mem_malloc(sizeof(*cds_cfg));
15205 	if (!cds_cfg)
15206 		return -ENOMEM;
15207 
15208 	cds_cfg->driver_type = QDF_DRIVER_TYPE_PRODUCTION;
15209 	ucfg_mlme_get_sap_max_modulated_dtim(hdd_ctx->psoc,
15210 					     &cds_cfg->sta_maxlimod_dtim);
15211 
15212 	ucfg_mlme_get_max_modulated_dtim_ms(hdd_ctx->psoc,
15213 					    &cds_cfg->sta_maxlimod_dtim_ms);
15214 
15215 	status = ucfg_mlme_get_crash_inject(hdd_ctx->psoc, &crash_inject);
15216 	if (QDF_IS_STATUS_ERROR(status)) {
15217 		hdd_err("Failed to get crash inject ini config");
15218 		goto exit;
15219 	}
15220 
15221 	status = ucfg_mlme_get_self_recovery(hdd_ctx->psoc, &self_recovery);
15222 	if (QDF_IS_STATUS_ERROR(status)) {
15223 		hdd_err("Failed to get self recovery ini config");
15224 		goto exit;
15225 	}
15226 
15227 	status = ucfg_mlme_get_fw_timeout_crash(hdd_ctx->psoc,
15228 						&fw_timeout_crash);
15229 	if (QDF_IS_STATUS_ERROR(status)) {
15230 		hdd_err("Failed to get fw timeout crash ini config");
15231 		goto exit;
15232 	}
15233 
15234 	status = ucfg_mlme_get_ito_repeat_count(hdd_ctx->psoc,
15235 						&ito_repeat_count);
15236 	if (QDF_IS_STATUS_ERROR(status)) {
15237 		hdd_err("Failed to get ITO repeat count ini config");
15238 		goto exit;
15239 	}
15240 
15241 	cds_cfg->force_target_assert_enabled = crash_inject;
15242 
15243 	ucfg_mlme_get_sap_max_offload_peers(hdd_ctx->psoc, &value);
15244 	cds_cfg->ap_maxoffload_peers = value;
15245 	ucfg_mlme_get_sap_max_offload_reorder_buffs(hdd_ctx->psoc,
15246 						    &value);
15247 	cds_cfg->ap_maxoffload_reorderbuffs = value;
15248 
15249 	cds_cfg->reorder_offload = DP_REORDER_OFFLOAD_SUPPORT;
15250 
15251 	/* IPA micro controller data path offload resource config item */
15252 	cds_cfg->uc_offload_enabled = ucfg_ipa_uc_is_enabled();
15253 
15254 	cds_cfg->enable_rxthread =
15255 		ucfg_dp_is_rx_common_thread_enabled(hdd_ctx->psoc);
15256 	ucfg_mlme_get_sap_max_peers(hdd_ctx->psoc, &value);
15257 	cds_cfg->max_station = value;
15258 	cds_cfg->sub_20_channel_width = WLAN_SUB_20_CH_WIDTH_NONE;
15259 	cds_cfg->max_msdus_per_rxinorderind =
15260 		cfg_get(hdd_ctx->psoc, CFG_DP_MAX_MSDUS_PER_RXIND);
15261 	cds_cfg->self_recovery_enabled = self_recovery;
15262 	cds_cfg->fw_timeout_crash = fw_timeout_crash;
15263 
15264 	cds_cfg->ito_repeat_count = ito_repeat_count;
15265 
15266 	status = ucfg_mlme_get_band_capability(hdd_ctx->psoc, &band_bitmap);
15267 	if (QDF_IS_STATUS_ERROR(status))
15268 		goto exit;
15269 
15270 	band_capability = wlan_reg_band_bitmap_to_band_info(band_bitmap);
15271 	cds_cfg->bandcapability = band_capability;
15272 	cds_cfg->num_vdevs = hdd_ctx->config->num_vdevs;
15273 	cds_cfg->enable_tx_compl_tsf64 =
15274 		hdd_tsf_is_tsf64_tx_set(hdd_ctx);
15275 	hdd_txrx_populate_cds_config(cds_cfg, hdd_ctx);
15276 	hdd_lpass_populate_cds_config(cds_cfg, hdd_ctx);
15277 	cds_init_ini_config(cds_cfg);
15278 	return 0;
15279 
15280 exit:
15281 	qdf_mem_free(cds_cfg);
15282 	return -EINVAL;
15283 }
15284 
15285 /**
15286  * hdd_update_user_config() - API to update user configuration
15287  * parameters to obj mgr which are used by multiple components
15288  * @hdd_ctx: HDD Context
15289  *
15290  * Return: 0 for Success, errno on failure
15291  */
15292 static int hdd_update_user_config(struct hdd_context *hdd_ctx)
15293 {
15294 	struct wlan_objmgr_psoc_user_config *user_config;
15295 	uint8_t band_capability;
15296 	uint32_t band_bitmap;
15297 	QDF_STATUS status;
15298 	bool value = false;
15299 
15300 	status = ucfg_mlme_get_band_capability(hdd_ctx->psoc, &band_bitmap);
15301 	if (QDF_IS_STATUS_ERROR(status))
15302 		return -EIO;
15303 
15304 	user_config = qdf_mem_malloc(sizeof(*user_config));
15305 	if (!user_config)
15306 		return -ENOMEM;
15307 
15308 	user_config->dot11_mode = hdd_ctx->config->dot11Mode;
15309 	status = ucfg_mlme_is_11d_enabled(hdd_ctx->psoc, &value);
15310 	if (!QDF_IS_STATUS_SUCCESS(status))
15311 		hdd_err("Invalid 11d_enable flag");
15312 	user_config->is_11d_support_enabled = value;
15313 
15314 	value = false;
15315 	status = ucfg_mlme_is_11h_enabled(hdd_ctx->psoc, &value);
15316 	if (!QDF_IS_STATUS_SUCCESS(status))
15317 		hdd_err("Invalid 11h_enable flag");
15318 	user_config->is_11h_support_enabled = value;
15319 	band_capability = wlan_reg_band_bitmap_to_band_info(band_bitmap);
15320 	user_config->band_capability = band_capability;
15321 	wlan_objmgr_psoc_set_user_config(hdd_ctx->psoc, user_config);
15322 
15323 	qdf_mem_free(user_config);
15324 	return 0;
15325 }
15326 
15327 /**
15328  * hdd_init_thermal_info - Initialize thermal level
15329  * @hdd_ctx:	HDD context
15330  *
15331  * Initialize thermal level at SME layer and set the thermal level callback
15332  * which would be called when a configured thermal threshold is hit.
15333  *
15334  * Return: 0 on success and errno on failure
15335  */
15336 static int hdd_init_thermal_info(struct hdd_context *hdd_ctx)
15337 {
15338 	QDF_STATUS status;
15339 	mac_handle_t mac_handle = hdd_ctx->mac_handle;
15340 
15341 	status = sme_init_thermal_info(mac_handle);
15342 
15343 	if (!QDF_IS_STATUS_SUCCESS(status))
15344 		return qdf_status_to_os_return(status);
15345 
15346 	sme_add_set_thermal_level_callback(mac_handle,
15347 					   hdd_set_thermal_level_cb);
15348 
15349 	return 0;
15350 
15351 }
15352 
15353 #if defined(CONFIG_HDD_INIT_WITH_RTNL_LOCK)
15354 /**
15355  * hdd_hold_rtnl_lock - Hold RTNL lock
15356  *
15357  * Hold RTNL lock
15358  *
15359  * Return: True if held and false otherwise
15360  */
15361 static inline bool hdd_hold_rtnl_lock(void)
15362 {
15363 	rtnl_lock();
15364 	return true;
15365 }
15366 
15367 /**
15368  * hdd_release_rtnl_lock - Release RTNL lock
15369  *
15370  * Release RTNL lock
15371  *
15372  * Return: None
15373  */
15374 static inline void hdd_release_rtnl_lock(void)
15375 {
15376 	rtnl_unlock();
15377 }
15378 #else
15379 static inline bool hdd_hold_rtnl_lock(void) { return false; }
15380 static inline void hdd_release_rtnl_lock(void) { }
15381 #endif
15382 
15383 #if !defined(REMOVE_PKT_LOG)
15384 
15385 /* MAX iwpriv command support */
15386 #define PKTLOG_SET_BUFF_SIZE	3
15387 #define PKTLOG_CLEAR_BUFF	4
15388 /* Set Maximum pktlog file size to 64MB */
15389 #define MAX_PKTLOG_SIZE		64
15390 
15391 /**
15392  * hdd_pktlog_set_buff_size() - set pktlog buffer size
15393  * @hdd_ctx: hdd context
15394  * @set_value2: pktlog buffer size value
15395  *
15396  *
15397  * Return: 0 for success or error.
15398  */
15399 static int hdd_pktlog_set_buff_size(struct hdd_context *hdd_ctx, int set_value2)
15400 {
15401 	struct sir_wifi_start_log start_log = { 0 };
15402 	QDF_STATUS status;
15403 
15404 	start_log.ring_id = RING_ID_PER_PACKET_STATS;
15405 	start_log.verbose_level = WLAN_LOG_LEVEL_OFF;
15406 	start_log.ini_triggered = cds_is_packet_log_enabled();
15407 	start_log.user_triggered = 1;
15408 	start_log.size = set_value2;
15409 	start_log.is_pktlog_buff_clear = false;
15410 
15411 	status = sme_wifi_start_logger(hdd_ctx->mac_handle, start_log);
15412 	if (!QDF_IS_STATUS_SUCCESS(status)) {
15413 		hdd_err("sme_wifi_start_logger failed(err=%d)", status);
15414 		hdd_exit();
15415 		return -EINVAL;
15416 	}
15417 
15418 	return 0;
15419 }
15420 
15421 /**
15422  * hdd_pktlog_clear_buff() - clear pktlog buffer
15423  * @hdd_ctx: hdd context
15424  *
15425  * Return: 0 for success or error.
15426  */
15427 static int hdd_pktlog_clear_buff(struct hdd_context *hdd_ctx)
15428 {
15429 	struct sir_wifi_start_log start_log;
15430 	QDF_STATUS status;
15431 
15432 	start_log.ring_id = RING_ID_PER_PACKET_STATS;
15433 	start_log.verbose_level = WLAN_LOG_LEVEL_OFF;
15434 	start_log.ini_triggered = cds_is_packet_log_enabled();
15435 	start_log.user_triggered = 1;
15436 	start_log.size = 0;
15437 	start_log.is_pktlog_buff_clear = true;
15438 
15439 	status = sme_wifi_start_logger(hdd_ctx->mac_handle, start_log);
15440 	if (!QDF_IS_STATUS_SUCCESS(status)) {
15441 		hdd_err("sme_wifi_start_logger failed(err=%d)", status);
15442 		hdd_exit();
15443 		return -EINVAL;
15444 	}
15445 
15446 	return 0;
15447 }
15448 
15449 
15450 /**
15451  * hdd_process_pktlog_command() - process pktlog command
15452  * @hdd_ctx: hdd context
15453  * @set_value: value set by user
15454  * @set_value2: pktlog buffer size value
15455  *
15456  * This function process pktlog command.
15457  * set_value2 only matters when set_value is 3 (set buff size)
15458  * otherwise we ignore it.
15459  *
15460  * Return: 0 for success or error.
15461  */
15462 int hdd_process_pktlog_command(struct hdd_context *hdd_ctx, uint32_t set_value,
15463 			       int set_value2)
15464 {
15465 	int ret;
15466 	bool enable;
15467 	uint8_t user_triggered = 0;
15468 
15469 	ret = wlan_hdd_validate_context(hdd_ctx);
15470 	if (0 != ret)
15471 		return ret;
15472 
15473 	hdd_debug("set pktlog %d, set size %d", set_value, set_value2);
15474 
15475 	if (set_value > PKTLOG_CLEAR_BUFF) {
15476 		hdd_err("invalid pktlog value %d", set_value);
15477 		return -EINVAL;
15478 	}
15479 
15480 	if (set_value == PKTLOG_SET_BUFF_SIZE) {
15481 		if (set_value2 <= 0) {
15482 			hdd_err("invalid pktlog size %d", set_value2);
15483 			return -EINVAL;
15484 		} else if (set_value2 > MAX_PKTLOG_SIZE) {
15485 			hdd_err_rl("Pktlog size is large. max value is %uMB.",
15486 				   MAX_PKTLOG_SIZE);
15487 			return -EINVAL;
15488 		}
15489 		return hdd_pktlog_set_buff_size(hdd_ctx, set_value2);
15490 	} else if (set_value == PKTLOG_CLEAR_BUFF) {
15491 		return hdd_pktlog_clear_buff(hdd_ctx);
15492 	}
15493 
15494 	/*
15495 	 * set_value = 0 then disable packetlog
15496 	 * set_value = 1 enable packetlog forcefully
15497 	 * set_value = 2 then disable packetlog if disabled through ini or
15498 	 *                     enable packetlog with AUTO type.
15499 	 */
15500 	enable = ((set_value > 0) && cds_is_packet_log_enabled()) ?
15501 			 true : false;
15502 
15503 	if (1 == set_value) {
15504 		enable = true;
15505 		user_triggered = 1;
15506 	}
15507 
15508 	return hdd_pktlog_enable_disable(hdd_ctx, enable, user_triggered, 0);
15509 }
15510 
15511 /**
15512  * hdd_pktlog_enable_disable() - Enable/Disable packet logging
15513  * @hdd_ctx: HDD context
15514  * @enable_disable_flag: Flag to enable/disable
15515  * @user_triggered: triggered through iwpriv
15516  * @size: buffer size to be used for packetlog
15517  *
15518  * Return: 0 on success; error number otherwise
15519  */
15520 int hdd_pktlog_enable_disable(struct hdd_context *hdd_ctx,
15521 			      bool enable_disable_flag,
15522 			      uint8_t user_triggered, int size)
15523 {
15524 	struct sir_wifi_start_log start_log;
15525 	QDF_STATUS status;
15526 
15527 	if (hdd_ctx->is_pktlog_enabled && enable_disable_flag)
15528 		return 0;
15529 
15530 	if ((!hdd_ctx->is_pktlog_enabled) && (!enable_disable_flag))
15531 		return 0;
15532 
15533 	start_log.ring_id = RING_ID_PER_PACKET_STATS;
15534 	start_log.verbose_level =
15535 		enable_disable_flag ?
15536 			WLAN_LOG_LEVEL_ACTIVE : WLAN_LOG_LEVEL_OFF;
15537 	start_log.ini_triggered = cds_is_packet_log_enabled();
15538 	start_log.user_triggered = user_triggered;
15539 	start_log.size = size;
15540 	start_log.is_pktlog_buff_clear = false;
15541 	/*
15542 	 * Use "is_iwpriv_command" flag to distinguish iwpriv command from other
15543 	 * commands. Host uses this flag to decide whether to send pktlog
15544 	 * disable command to fw without sending pktlog enable command
15545 	 * previously. For eg, If vendor sends pktlog disable command without
15546 	 * sending pktlog enable command, then host discards the packet
15547 	 * but for iwpriv command, host will send it to fw.
15548 	 */
15549 	start_log.is_iwpriv_command = 1;
15550 
15551 	status = sme_wifi_start_logger(hdd_ctx->mac_handle, start_log);
15552 	if (!QDF_IS_STATUS_SUCCESS(status)) {
15553 		hdd_err("sme_wifi_start_logger failed(err=%d)", status);
15554 		hdd_exit();
15555 		return -EINVAL;
15556 	}
15557 
15558 	hdd_ctx->is_pktlog_enabled = enable_disable_flag;
15559 
15560 	return 0;
15561 }
15562 #endif /* REMOVE_PKT_LOG */
15563 
15564 void hdd_free_mac_address_lists(struct hdd_context *hdd_ctx)
15565 {
15566 	hdd_debug("Resetting MAC address lists");
15567 	qdf_mem_zero(hdd_ctx->provisioned_mac_addr,
15568 		    sizeof(hdd_ctx->provisioned_mac_addr));
15569 	qdf_mem_zero(hdd_ctx->derived_mac_addr,
15570 		    sizeof(hdd_ctx->derived_mac_addr));
15571 	hdd_ctx->num_provisioned_addr = 0;
15572 	hdd_ctx->num_derived_addr = 0;
15573 	hdd_ctx->provisioned_intf_addr_mask = 0;
15574 	hdd_ctx->derived_intf_addr_mask = 0;
15575 }
15576 
15577 /**
15578  * hdd_get_platform_wlan_mac_buff() - API to query platform driver
15579  *                                    for MAC address
15580  * @dev: Device Pointer
15581  * @num: Number of Valid Mac address
15582  *
15583  * Return: Pointer to MAC address buffer
15584  */
15585 static uint8_t *hdd_get_platform_wlan_mac_buff(struct device *dev,
15586 					       uint32_t *num)
15587 {
15588 	return pld_get_wlan_mac_address(dev, num);
15589 }
15590 
15591 /**
15592  * hdd_get_platform_wlan_derived_mac_buff() - API to query platform driver
15593  *                                    for derived MAC address
15594  * @dev: Device Pointer
15595  * @num: Number of Valid Mac address
15596  *
15597  * Return: Pointer to MAC address buffer
15598  */
15599 static uint8_t *hdd_get_platform_wlan_derived_mac_buff(struct device *dev,
15600 						       uint32_t *num)
15601 {
15602 	return pld_get_wlan_derived_mac_address(dev, num);
15603 }
15604 
15605 /**
15606  * hdd_populate_random_mac_addr() - API to populate random mac addresses
15607  * @hdd_ctx: HDD Context
15608  * @num: Number of random mac addresses needed
15609  *
15610  * Generate random addresses using bit manipulation on the base mac address
15611  *
15612  * Return: None
15613  */
15614 void hdd_populate_random_mac_addr(struct hdd_context *hdd_ctx, uint32_t num)
15615 {
15616 	uint32_t idx = hdd_ctx->num_derived_addr;
15617 	uint32_t iter;
15618 	uint8_t *buf = NULL;
15619 	uint8_t macaddr_b3, tmp_br3;
15620 	/*
15621 	 * Consider first provisioned mac address as source address to derive
15622 	 * remaining addresses
15623 	 */
15624 
15625 	uint8_t *src = hdd_ctx->provisioned_mac_addr[0].bytes;
15626 
15627 	for (iter = 0; iter < num; ++iter, ++idx) {
15628 		buf = hdd_ctx->derived_mac_addr[idx].bytes;
15629 		qdf_mem_copy(buf, src, QDF_MAC_ADDR_SIZE);
15630 		macaddr_b3 = buf[3];
15631 		tmp_br3 = ((macaddr_b3 >> 4 & INTF_MACADDR_MASK) + idx) &
15632 			INTF_MACADDR_MASK;
15633 		macaddr_b3 += tmp_br3;
15634 		macaddr_b3 ^= (1 << INTF_MACADDR_MASK);
15635 		buf[0] |= 0x02;
15636 		buf[3] = macaddr_b3;
15637 		hdd_debug(QDF_MAC_ADDR_FMT, QDF_MAC_ADDR_REF(buf));
15638 		hdd_ctx->num_derived_addr++;
15639 	}
15640 }
15641 
15642 /**
15643  * hdd_platform_wlan_mac() - API to get mac addresses from platform driver
15644  * @hdd_ctx: HDD Context
15645  *
15646  * API to get mac addresses from platform driver and update the driver
15647  * structures and configure FW with the base mac address.
15648  * Return: int
15649  */
15650 static int hdd_platform_wlan_mac(struct hdd_context *hdd_ctx)
15651 {
15652 	uint32_t no_of_mac_addr, iter;
15653 	uint32_t max_mac_addr = QDF_MAX_CONCURRENCY_PERSONA;
15654 	uint32_t mac_addr_size = QDF_MAC_ADDR_SIZE;
15655 	uint8_t *addr, *buf;
15656 	struct device *dev = hdd_ctx->parent_dev;
15657 	tSirMacAddr mac_addr;
15658 	QDF_STATUS status;
15659 
15660 	addr = hdd_get_platform_wlan_mac_buff(dev, &no_of_mac_addr);
15661 
15662 	if (no_of_mac_addr == 0 || !addr) {
15663 		hdd_debug("No mac configured from platform driver");
15664 		return -EINVAL;
15665 	}
15666 
15667 	hdd_free_mac_address_lists(hdd_ctx);
15668 
15669 	if (no_of_mac_addr > max_mac_addr)
15670 		no_of_mac_addr = max_mac_addr;
15671 
15672 	qdf_mem_copy(&mac_addr, addr, mac_addr_size);
15673 
15674 	for (iter = 0; iter < no_of_mac_addr; ++iter, addr += mac_addr_size) {
15675 		buf = hdd_ctx->provisioned_mac_addr[iter].bytes;
15676 		qdf_mem_copy(buf, addr, QDF_MAC_ADDR_SIZE);
15677 		hdd_info("provisioned MAC Addr [%d] "QDF_MAC_ADDR_FMT, iter,
15678 			 QDF_MAC_ADDR_REF(buf));
15679 	}
15680 
15681 	hdd_ctx->num_provisioned_addr = no_of_mac_addr;
15682 
15683 	if (hdd_ctx->config->mac_provision) {
15684 		addr = hdd_get_platform_wlan_derived_mac_buff(dev,
15685 							      &no_of_mac_addr);
15686 
15687 		if (no_of_mac_addr == 0 || !addr)
15688 			hdd_warn("No derived address from platform driver");
15689 		else if (no_of_mac_addr >
15690 			 (max_mac_addr - hdd_ctx->num_provisioned_addr))
15691 			no_of_mac_addr = (max_mac_addr -
15692 					  hdd_ctx->num_provisioned_addr);
15693 
15694 		for (iter = 0; iter < no_of_mac_addr; ++iter,
15695 		     addr += mac_addr_size) {
15696 			buf = hdd_ctx->derived_mac_addr[iter].bytes;
15697 			qdf_mem_copy(buf, addr, QDF_MAC_ADDR_SIZE);
15698 			hdd_debug("derived MAC Addr [%d] "QDF_MAC_ADDR_FMT, iter,
15699 				  QDF_MAC_ADDR_REF(buf));
15700 		}
15701 		hdd_ctx->num_derived_addr = no_of_mac_addr;
15702 	}
15703 
15704 	no_of_mac_addr = hdd_ctx->num_provisioned_addr +
15705 					 hdd_ctx->num_derived_addr;
15706 	if (no_of_mac_addr < max_mac_addr)
15707 		hdd_populate_random_mac_addr(hdd_ctx, max_mac_addr -
15708 					     no_of_mac_addr);
15709 
15710 	status = sme_set_custom_mac_addr(mac_addr);
15711 	if (!QDF_IS_STATUS_SUCCESS(status))
15712 		return -EAGAIN;
15713 
15714 	return 0;
15715 }
15716 
15717 /**
15718  * hdd_update_mac_addr_to_fw() - API to update wlan mac addresses to FW
15719  * @hdd_ctx: HDD Context
15720  *
15721  * Update MAC address to FW. If MAC address passed by FW is invalid, host
15722  * will generate its own MAC and update it to FW.
15723  *
15724  * Return: 0 for success
15725  *         Non-zero error code for failure
15726  */
15727 static int hdd_update_mac_addr_to_fw(struct hdd_context *hdd_ctx)
15728 {
15729 	tSirMacAddr custom_mac_addr;
15730 	QDF_STATUS status;
15731 
15732 	if (hdd_ctx->num_provisioned_addr)
15733 		qdf_mem_copy(&custom_mac_addr,
15734 			     &hdd_ctx->provisioned_mac_addr[0].bytes[0],
15735 			     sizeof(tSirMacAddr));
15736 	else
15737 		qdf_mem_copy(&custom_mac_addr,
15738 			     &hdd_ctx->derived_mac_addr[0].bytes[0],
15739 			     sizeof(tSirMacAddr));
15740 	status = sme_set_custom_mac_addr(custom_mac_addr);
15741 	if (!QDF_IS_STATUS_SUCCESS(status))
15742 		return -EAGAIN;
15743 	return 0;
15744 }
15745 
15746 /**
15747  * hdd_initialize_mac_address() - API to get wlan mac addresses
15748  * @hdd_ctx: HDD Context
15749  *
15750  * Get MAC addresses from platform driver or wlan_mac.bin. If platform driver
15751  * is provisioned with mac addresses, driver uses it, else it will use
15752  * wlan_mac.bin to update HW MAC addresses.
15753  *
15754  * Return: None
15755  */
15756 static int hdd_initialize_mac_address(struct hdd_context *hdd_ctx)
15757 {
15758 	QDF_STATUS status;
15759 	int ret;
15760 
15761 	ret = hdd_platform_wlan_mac(hdd_ctx);
15762 	if (!ret) {
15763 		hdd_info("using MAC address from platform driver");
15764 		return ret;
15765 	} else if (hdd_ctx->config->mac_provision) {
15766 		hdd_err("getting MAC address from platform driver failed");
15767 		return ret;
15768 	}
15769 
15770 	status = hdd_update_mac_config(hdd_ctx);
15771 	if (QDF_IS_STATUS_SUCCESS(status)) {
15772 		hdd_info("using MAC address from wlan_mac.bin");
15773 		return 0;
15774 	}
15775 
15776 	hdd_info("using default MAC address");
15777 
15778 	/* Use fw provided MAC */
15779 	if (!qdf_is_macaddr_zero(&hdd_ctx->hw_macaddr)) {
15780 		hdd_update_macaddr(hdd_ctx, hdd_ctx->hw_macaddr, false);
15781 		return 0;
15782 	} else if (hdd_generate_macaddr_auto(hdd_ctx) != 0) {
15783 		struct qdf_mac_addr mac_addr;
15784 
15785 		hdd_err("MAC failure from device serial no.");
15786 		qdf_get_random_bytes(&mac_addr, sizeof(mac_addr));
15787 		/*
15788 		 * Reset multicast bit (bit-0) and set
15789 		 * locally-administered bit
15790 		 */
15791 		mac_addr.bytes[0] = 0x2;
15792 		hdd_update_macaddr(hdd_ctx, mac_addr, true);
15793 	}
15794 
15795 	ret = hdd_update_mac_addr_to_fw(hdd_ctx);
15796 	if (ret)
15797 		hdd_err("MAC address out-of-sync, ret:%d", ret);
15798 	return ret;
15799 }
15800 
15801 /* params being sent:
15802  * wmi_pdev_param_tx_chain_mask_1ss
15803  * wmi_pdev_param_mgmt_retry_limit
15804  * wmi_pdev_param_default_6ghz_rate
15805  * wmi_pdev_param_pdev_stats_tx_xretry_ext
15806  * wmi_pdev_param_smart_chainmask_scheme
15807  * wmi_pdev_param_alternative_chainmask_scheme
15808  * wmi_pdev_param_ani_enable
15809  * wmi_pdev_param_pcie_config
15810  */
15811 /**
15812  * hdd_pre_enable_configure() - Configurations prior to cds_enable
15813  * @hdd_ctx:	HDD context
15814  *
15815  * Pre configurations to be done at lower layer before calling cds enable.
15816  *
15817  * Return: 0 on success and errno on failure.
15818  */
15819 static int hdd_pre_enable_configure(struct hdd_context *hdd_ctx)
15820 {
15821 	int ret;
15822 	uint8_t val = 0;
15823 	uint8_t max_retry = 0;
15824 	bool enable_he_mcs0_for_6ghz_mgmt = false;
15825 	uint32_t tx_retry_multiplier;
15826 	QDF_STATUS status;
15827 	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
15828 	struct dev_set_param setparam[MAX_PDEV_PRE_ENABLE_PARAMS] = {};
15829 	bool check_value;
15830 	uint8_t index = 0;
15831 
15832 	cdp_register_pause_cb(soc, wlan_hdd_txrx_pause_cb);
15833 	hdd_tx_latency_register_cb(soc);
15834 
15835 	/* Register HL netdev flow control callback */
15836 	cdp_hl_fc_register(soc, OL_TXRX_PDEV_ID, wlan_hdd_txrx_pause_cb);
15837 	/* Register rx mic error indication handler */
15838 	ucfg_dp_register_rx_mic_error_ind_handler(soc);
15839 
15840 	/*
15841 	 * Note that the cds_pre_enable() sequence triggers the cfg download.
15842 	 * The cfg download must occur before we update the SME config
15843 	 * since the SME config operation must access the cfg database
15844 	 */
15845 	status = hdd_set_sme_config(hdd_ctx);
15846 
15847 	if (QDF_STATUS_SUCCESS != status) {
15848 		hdd_err("Failed hdd_set_sme_config: %d", status);
15849 		ret = qdf_status_to_os_return(status);
15850 		goto out;
15851 	}
15852 
15853 	status = hdd_set_policy_mgr_user_cfg(hdd_ctx);
15854 	if (QDF_STATUS_SUCCESS != status) {
15855 		hdd_alert("Failed hdd_set_policy_mgr_user_cfg: %d", status);
15856 		ret = qdf_status_to_os_return(status);
15857 		goto out;
15858 	}
15859 
15860 	status = ucfg_mlme_get_tx_chainmask_1ss(hdd_ctx->psoc, &val);
15861 	if (QDF_STATUS_SUCCESS != status) {
15862 		hdd_err("Get tx_chainmask_1ss from mlme failed");
15863 		ret = qdf_status_to_os_return(status);
15864 		goto out;
15865 	}
15866 	ret = mlme_check_index_setparam(setparam,
15867 					wmi_pdev_param_tx_chain_mask_1ss,
15868 					val, index++,
15869 					MAX_PDEV_PRE_ENABLE_PARAMS);
15870 	if (QDF_IS_STATUS_ERROR(ret)) {
15871 		hdd_err("failed at wmi_pdev_param_tx_chain_mask_1ss");
15872 		goto out;
15873 
15874 	}
15875 
15876 	wlan_mlme_get_mgmt_max_retry(hdd_ctx->psoc, &max_retry);
15877 	ret = mlme_check_index_setparam(setparam,
15878 					wmi_pdev_param_mgmt_retry_limit,
15879 					max_retry, index++,
15880 					MAX_PDEV_PRE_ENABLE_PARAMS);
15881 	if (QDF_IS_STATUS_ERROR(ret)) {
15882 		hdd_err("failed at wmi_pdev_param_mgmt_retry_limit");
15883 		goto out;
15884 	}
15885 
15886 	wlan_mlme_get_mgmt_6ghz_rate_support(hdd_ctx->psoc,
15887 					     &enable_he_mcs0_for_6ghz_mgmt);
15888 	if (enable_he_mcs0_for_6ghz_mgmt) {
15889 		hdd_debug("HE rates for 6GHz mgmt frames are supported");
15890 		ret = mlme_check_index_setparam(
15891 					setparam,
15892 					wmi_pdev_param_default_6ghz_rate,
15893 					MGMT_DEFAULT_DATA_RATE_6GHZ, index++,
15894 					MAX_PDEV_PRE_ENABLE_PARAMS);
15895 		if (QDF_IS_STATUS_ERROR(ret)) {
15896 			hdd_err("wmi_pdev_param_default_6ghz_rate failed %d",
15897 				ret);
15898 			goto out;
15899 		}
15900 	}
15901 
15902 	wlan_mlme_get_tx_retry_multiplier(hdd_ctx->psoc,
15903 					  &tx_retry_multiplier);
15904 	ret = mlme_check_index_setparam(setparam,
15905 					wmi_pdev_param_pdev_stats_tx_xretry_ext,
15906 					tx_retry_multiplier, index++,
15907 					MAX_PDEV_PRE_ENABLE_PARAMS);
15908 	if (QDF_IS_STATUS_ERROR(ret)) {
15909 		hdd_err("failed at wmi_pdev_param_pdev_stats_tx_xretry_ext");
15910 		goto out;
15911 	}
15912 
15913 	ret = ucfg_get_smart_chainmask_enabled(hdd_ctx->psoc,
15914 					      &check_value);
15915 	if (QDF_IS_STATUS_SUCCESS(ret)) {
15916 		ret = mlme_check_index_setparam(
15917 					 setparam,
15918 					 wmi_pdev_param_smart_chainmask_scheme,
15919 					 (int)check_value, index++,
15920 					 MAX_PDEV_PRE_ENABLE_PARAMS);
15921 		if (QDF_IS_STATUS_ERROR(ret)) {
15922 			hdd_err("failed to set wmi_pdev_param_smart_chainmask_scheme");
15923 			goto out;
15924 		}
15925 	}
15926 
15927 	ret = ucfg_get_alternative_chainmask_enabled(hdd_ctx->psoc,
15928 						    &check_value);
15929 	if (QDF_IS_STATUS_SUCCESS(ret)) {
15930 		ret = mlme_check_index_setparam(
15931 				setparam,
15932 				wmi_pdev_param_alternative_chainmask_scheme,
15933 				(int)check_value, index++,
15934 				MAX_PDEV_PRE_ENABLE_PARAMS);
15935 		if (QDF_IS_STATUS_ERROR(ret)) {
15936 			hdd_err("failed to set wmi_pdev_param_alternative_chainmask_scheme");
15937 			goto out;
15938 		}
15939 	}
15940 
15941 	ret = ucfg_fwol_get_ani_enabled(hdd_ctx->psoc, &check_value);
15942 	if (QDF_IS_STATUS_SUCCESS(ret)) {
15943 		ret = mlme_check_index_setparam(setparam,
15944 						wmi_pdev_param_ani_enable,
15945 						(int)check_value, index++,
15946 						MAX_PDEV_PRE_ENABLE_PARAMS);
15947 		if (QDF_IS_STATUS_ERROR(ret)) {
15948 			hdd_err("failed to set wmi_pdev_param_ani_enable");
15949 			goto out;
15950 		}
15951 	}
15952 
15953 	ret = hdd_set_pcie_params(hdd_ctx, index, setparam);
15954 	if (QDF_IS_STATUS_ERROR(ret))
15955 		goto out;
15956 	else
15957 		index++;
15958 	ret = sme_send_multi_pdev_vdev_set_params(MLME_PDEV_SETPARAM,
15959 						  WMI_PDEV_ID_SOC, setparam,
15960 						  index);
15961 	if (QDF_IS_STATUS_ERROR(ret)) {
15962 		hdd_err("failed to send pdev set params");
15963 		goto out;
15964 	}
15965 
15966 	/* Configure global firmware params */
15967 	ret = ucfg_fwol_configure_global_params(hdd_ctx->psoc, hdd_ctx->pdev);
15968 	if (ret)
15969 		goto out;
15970 
15971 	status = hdd_set_sme_chan_list(hdd_ctx);
15972 	if (status != QDF_STATUS_SUCCESS) {
15973 		hdd_err("Failed to init channel list: %d", status);
15974 		ret = qdf_status_to_os_return(status);
15975 		goto out;
15976 	}
15977 
15978 	if (!hdd_update_config_cfg(hdd_ctx)) {
15979 		hdd_err("config update failed");
15980 		ret = -EINVAL;
15981 		goto out;
15982 	}
15983 	hdd_init_channel_avoidance(hdd_ctx);
15984 
15985 out:
15986 	return ret;
15987 }
15988 
15989 #ifdef FEATURE_P2P_LISTEN_OFFLOAD
15990 /**
15991  * wlan_hdd_p2p_lo_event_callback - P2P listen offload stop event handler
15992  * @context: context registered with sme_register_p2p_lo_event(). HDD
15993  *   always registers a hdd context pointer
15994  * @evt:event structure pointer
15995  *
15996  * This is the p2p listen offload stop event handler, it sends vendor
15997  * event back to supplicant to notify the stop reason.
15998  *
15999  * Return: None
16000  */
16001 static void wlan_hdd_p2p_lo_event_callback(void *context,
16002 					   struct sir_p2p_lo_event *evt)
16003 {
16004 	struct hdd_context *hdd_ctx = context;
16005 	struct sk_buff *vendor_event;
16006 	enum qca_nl80211_vendor_subcmds_index index =
16007 		QCA_NL80211_VENDOR_SUBCMD_P2P_LO_EVENT_INDEX;
16008 	struct wlan_hdd_link_info *link_info;
16009 
16010 	hdd_enter();
16011 
16012 	if (!hdd_ctx) {
16013 		hdd_err("Invalid HDD context pointer");
16014 		return;
16015 	}
16016 
16017 	link_info = hdd_get_link_info_by_vdev(hdd_ctx, evt->vdev_id);
16018 	if (!link_info) {
16019 		hdd_err("Cannot find adapter by vdev_id = %d",
16020 				evt->vdev_id);
16021 		return;
16022 	}
16023 
16024 	vendor_event =
16025 		wlan_cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
16026 						 &link_info->adapter->wdev,
16027 						 sizeof(uint32_t) +
16028 						 NLMSG_HDRLEN,
16029 						 index, GFP_KERNEL);
16030 	if (!vendor_event) {
16031 		hdd_err("wlan_cfg80211_vendor_event_alloc failed");
16032 		return;
16033 	}
16034 
16035 	if (nla_put_u32(vendor_event,
16036 			QCA_WLAN_VENDOR_ATTR_P2P_LISTEN_OFFLOAD_STOP_REASON,
16037 			evt->reason_code)) {
16038 		hdd_err("nla put failed");
16039 		wlan_cfg80211_vendor_free_skb(vendor_event);
16040 		return;
16041 	}
16042 
16043 	wlan_cfg80211_vendor_event(vendor_event, GFP_KERNEL);
16044 	hdd_debug("Sent P2P_LISTEN_OFFLOAD_STOP event for vdev_id = %d",
16045 			evt->vdev_id);
16046 }
16047 #else
16048 static void wlan_hdd_p2p_lo_event_callback(void *context,
16049 					   struct sir_p2p_lo_event *evt)
16050 {
16051 }
16052 #endif
16053 
16054 #ifdef FEATURE_WLAN_DYNAMIC_CVM
16055 static inline int hdd_set_vc_mode_config(struct hdd_context *hdd_ctx)
16056 {
16057 	return sme_set_vc_mode_config(hdd_ctx->config->vc_mode_cfg_bitmap);
16058 }
16059 #else
16060 static inline int hdd_set_vc_mode_config(struct hdd_context *hdd_ctx)
16061 {
16062 	return QDF_STATUS_SUCCESS;
16063 }
16064 #endif
16065 
16066 /**
16067  * hdd_adaptive_dwelltime_init() - initialization for adaptive dwell time config
16068  * @hdd_ctx: HDD context
16069  *
16070  * This function sends the adaptive dwell time config configuration to the
16071  * firmware via WMA
16072  *
16073  * Return: 0 - success, < 0 - failure
16074  */
16075 static int hdd_adaptive_dwelltime_init(struct hdd_context *hdd_ctx)
16076 {
16077 	QDF_STATUS status;
16078 	struct adaptive_dwelltime_params dwelltime_params;
16079 
16080 	status = ucfg_fwol_get_all_adaptive_dwelltime_params(hdd_ctx->psoc,
16081 							     &dwelltime_params);
16082 	status = ucfg_fwol_set_adaptive_dwelltime_config(&dwelltime_params);
16083 
16084 	hdd_debug("Sending Adaptive Dwelltime Configuration to fw");
16085 	if (!QDF_IS_STATUS_SUCCESS(status)) {
16086 		hdd_err("Failed to send Adaptive Dwelltime configuration!");
16087 		return -EAGAIN;
16088 	}
16089 	return 0;
16090 }
16091 
16092 int hdd_dbs_scan_selection_init(struct hdd_context *hdd_ctx)
16093 {
16094 	QDF_STATUS status;
16095 	struct wmi_dbs_scan_sel_params dbs_scan_params;
16096 	uint32_t i = 0;
16097 	uint8_t count = 0, numentries = 0;
16098 	uint8_t dual_mac_feature;
16099 	uint8_t dbs_scan_config[CDS_DBS_SCAN_PARAM_PER_CLIENT
16100 				* CDS_DBS_SCAN_CLIENTS_MAX];
16101 
16102 	status = ucfg_policy_mgr_get_dual_mac_feature(hdd_ctx->psoc,
16103 						      &dual_mac_feature);
16104 
16105 	if (status != QDF_STATUS_SUCCESS) {
16106 		hdd_err("can't get dual mac feature flag");
16107 		return -EINVAL;
16108 	}
16109 	/* check if DBS is enabled or supported */
16110 	if ((dual_mac_feature == DISABLE_DBS_CXN_AND_SCAN) ||
16111 	    (dual_mac_feature == ENABLE_DBS_CXN_AND_DISABLE_DBS_SCAN))
16112 		return -EINVAL;
16113 
16114 	hdd_string_to_u8_array(hdd_ctx->config->dbs_scan_selection,
16115 			       dbs_scan_config, &numentries,
16116 			       (CDS_DBS_SCAN_PARAM_PER_CLIENT
16117 				* CDS_DBS_SCAN_CLIENTS_MAX));
16118 
16119 	if (!numentries) {
16120 		hdd_debug("Do not send scan_selection_config");
16121 		return 0;
16122 	}
16123 
16124 	/* hdd_set_fw_log_params */
16125 	dbs_scan_params.num_clients = 0;
16126 	while (count < (numentries - 2)) {
16127 		dbs_scan_params.module_id[i] = dbs_scan_config[count];
16128 		dbs_scan_params.num_dbs_scans[i] = dbs_scan_config[count + 1];
16129 		dbs_scan_params.num_non_dbs_scans[i] =
16130 			dbs_scan_config[count + 2];
16131 		dbs_scan_params.num_clients++;
16132 		hdd_debug("module:%d NDS:%d NNDS:%d",
16133 			  dbs_scan_params.module_id[i],
16134 			  dbs_scan_params.num_dbs_scans[i],
16135 			  dbs_scan_params.num_non_dbs_scans[i]);
16136 		count += CDS_DBS_SCAN_PARAM_PER_CLIENT;
16137 		i++;
16138 	}
16139 
16140 	dbs_scan_params.pdev_id = 0;
16141 
16142 	hdd_debug("clients:%d pdev:%d",
16143 		  dbs_scan_params.num_clients, dbs_scan_params.pdev_id);
16144 
16145 	status = sme_set_dbs_scan_selection_config(hdd_ctx->mac_handle,
16146 						   &dbs_scan_params);
16147 	hdd_debug("Sending DBS Scan Selection Configuration to fw");
16148 	if (!QDF_IS_STATUS_SUCCESS(status)) {
16149 		hdd_err("Failed to send DBS Scan selection configuration!");
16150 		return -EAGAIN;
16151 	}
16152 	return 0;
16153 }
16154 
16155 #ifdef FEATURE_WLAN_AUTO_SHUTDOWN
16156 /**
16157  * hdd_set_auto_shutdown_cb() - Set auto shutdown callback
16158  * @hdd_ctx:	HDD context
16159  *
16160  * Set auto shutdown callback to get indications from firmware to indicate
16161  * userspace to shutdown WLAN after a configured amount of inactivity.
16162  *
16163  * Return: 0 on success and errno on failure.
16164  */
16165 static int hdd_set_auto_shutdown_cb(struct hdd_context *hdd_ctx)
16166 {
16167 	QDF_STATUS status;
16168 
16169 	if (!hdd_ctx->config->wlan_auto_shutdown)
16170 		return 0;
16171 
16172 	status = sme_set_auto_shutdown_cb(hdd_ctx->mac_handle,
16173 					  wlan_hdd_auto_shutdown_cb);
16174 	if (status != QDF_STATUS_SUCCESS)
16175 		hdd_err("Auto shutdown feature could not be enabled: %d",
16176 			status);
16177 
16178 	return qdf_status_to_os_return(status);
16179 }
16180 #else
16181 static int hdd_set_auto_shutdown_cb(struct hdd_context *hdd_ctx)
16182 {
16183 	return 0;
16184 }
16185 #endif
16186 
16187 #ifdef MWS_COEX
16188 #define MAX_PDEV_MWSCOEX_PARAMS 4
16189 /* params being sent:
16190  * wmi_pdev_param_mwscoex_4g_allow_quick_ftdm
16191  * wmi_pdev_param_mwscoex_set_5gnr_pwr_limit
16192  * wmi_pdev_param_mwscoex_pcc_chavd_delay
16193  * wmi_pdev_param_mwscoex_scc_chavd_delay
16194  */
16195 
16196 /**
16197  * hdd_init_mws_coex() - Initialize MWS coex configurations
16198  * @hdd_ctx:   HDD context
16199  *
16200  * This function sends MWS-COEX 4G quick FTDM and
16201  * MWS-COEX 5G-NR power limit to FW
16202  *
16203  * Return: 0 on success and errno on failure.
16204  */
16205 static int hdd_init_mws_coex(struct hdd_context *hdd_ctx)
16206 {
16207 	int ret = 0;
16208 	uint32_t mws_coex_4g_quick_tdm = 0, mws_coex_5g_nr_pwr_limit = 0;
16209 	uint32_t mws_coex_pcc_channel_avoid_delay = 0;
16210 	uint32_t mws_coex_scc_channel_avoid_delay = 0;
16211 	struct dev_set_param setparam[MAX_PDEV_MWSCOEX_PARAMS] = {};
16212 	uint8_t index = 0;
16213 
16214 	ucfg_mlme_get_mws_coex_4g_quick_tdm(hdd_ctx->psoc,
16215 					    &mws_coex_4g_quick_tdm);
16216 	ret = mlme_check_index_setparam(
16217 				setparam,
16218 				wmi_pdev_param_mwscoex_4g_allow_quick_ftdm,
16219 				mws_coex_4g_quick_tdm, index++,
16220 				MAX_PDEV_MWSCOEX_PARAMS);
16221 	if (QDF_IS_STATUS_ERROR(ret)) {
16222 		hdd_err("failed at wmi_pdev_param_mwscoex_4g_allow_quick_ftdm");
16223 		goto error;
16224 	}
16225 
16226 	ucfg_mlme_get_mws_coex_5g_nr_pwr_limit(hdd_ctx->psoc,
16227 					       &mws_coex_5g_nr_pwr_limit);
16228 	ret = mlme_check_index_setparam(
16229 				      setparam,
16230 				      wmi_pdev_param_mwscoex_set_5gnr_pwr_limit,
16231 				      mws_coex_5g_nr_pwr_limit, index++,
16232 				      MAX_PDEV_MWSCOEX_PARAMS);
16233 	if (QDF_IS_STATUS_ERROR(ret)) {
16234 		hdd_err("failed at wmi_pdev_param_mwscoex_set_5gnr_pwr_limit");
16235 		goto error;
16236 	}
16237 
16238 	ucfg_mlme_get_mws_coex_pcc_channel_avoid_delay(
16239 					hdd_ctx->psoc,
16240 					&mws_coex_pcc_channel_avoid_delay);
16241 	ret = mlme_check_index_setparam(setparam,
16242 					wmi_pdev_param_mwscoex_pcc_chavd_delay,
16243 					mws_coex_pcc_channel_avoid_delay,
16244 					index++, MAX_PDEV_MWSCOEX_PARAMS);
16245 	if (QDF_IS_STATUS_ERROR(ret)) {
16246 		hdd_err("failed at wmi_pdev_param_mwscoex_pcc_chavd_delay");
16247 		goto error;
16248 	}
16249 
16250 	ucfg_mlme_get_mws_coex_scc_channel_avoid_delay(
16251 					hdd_ctx->psoc,
16252 					&mws_coex_scc_channel_avoid_delay);
16253 	ret = mlme_check_index_setparam(setparam,
16254 					wmi_pdev_param_mwscoex_scc_chavd_delay,
16255 					mws_coex_scc_channel_avoid_delay,
16256 					index++, MAX_PDEV_MWSCOEX_PARAMS);
16257 	if (QDF_IS_STATUS_ERROR(ret)) {
16258 		hdd_err("failed at wmi_pdev_param_mwscoex_scc_chavd_delay");
16259 		goto error;
16260 	}
16261 	ret = sme_send_multi_pdev_vdev_set_params(MLME_PDEV_SETPARAM,
16262 						  WMI_PDEV_ID_SOC, setparam,
16263 						  index);
16264 	if (QDF_IS_STATUS_ERROR(ret))
16265 		hdd_err("failed to send pdev MWSCOEX set params");
16266 error:
16267 	return ret;
16268 }
16269 #else
16270 static int hdd_init_mws_coex(struct hdd_context *hdd_ctx)
16271 {
16272 	return 0;
16273 }
16274 #endif
16275 
16276 #ifdef THERMAL_STATS_SUPPORT
16277 static void hdd_thermal_stats_cmd_init(struct hdd_context *hdd_ctx)
16278 {
16279 	hdd_send_get_thermal_stats_cmd(hdd_ctx, thermal_stats_init, NULL, NULL);
16280 }
16281 #else
16282 static void hdd_thermal_stats_cmd_init(struct hdd_context *hdd_ctx)
16283 {
16284 }
16285 #endif
16286 
16287 #ifdef WLAN_FEATURE_CAL_FAILURE_TRIGGER
16288 /**
16289  * hdd_cal_fail_send_event()- send calibration failure information
16290  * @cal_type: calibration type
16291  * @reason: reason for calibration failure
16292  *
16293  * This Function sends calibration failure diag event
16294  *
16295  * Return: void.
16296  */
16297 static void hdd_cal_fail_send_event(uint8_t cal_type, uint8_t reason)
16298 {
16299 	/*
16300 	 * For now we are going with the print. Once CST APK has support to
16301 	 * read the diag events then we will add the diag event here.
16302 	 */
16303 	hdd_debug("Received cal failure event with cal_type:%x reason:%x",
16304 		  cal_type, reason);
16305 }
16306 #else
16307 static inline void hdd_cal_fail_send_event(uint8_t cal_type, uint8_t reason)
16308 {
16309 }
16310 #endif
16311 
16312 /**
16313  * hdd_features_init() - Init features
16314  * @hdd_ctx:	HDD context
16315  *
16316  * Initialize features and their feature context after WLAN firmware is up.
16317  *
16318  * Return: 0 on success and errno on failure.
16319  */
16320 static int hdd_features_init(struct hdd_context *hdd_ctx)
16321 {
16322 	struct tx_power_limit hddtxlimit;
16323 	QDF_STATUS status;
16324 	int ret;
16325 	mac_handle_t mac_handle;
16326 	bool b_cts2self, is_imps_enabled;
16327 	bool rf_test_mode;
16328 	bool std_6ghz_conn_policy;
16329 	uint32_t fw_data_stall_evt;
16330 	bool disable_vlp_sta_conn_sp_ap;
16331 
16332 	hdd_enter();
16333 
16334 	ret = hdd_init_mws_coex(hdd_ctx);
16335 	if (ret)
16336 		hdd_warn("Error initializing mws-coex");
16337 
16338 	/* FW capabilities received, Set the Dot11 mode */
16339 	mac_handle = hdd_ctx->mac_handle;
16340 	sme_setdef_dot11mode(mac_handle);
16341 
16342 	ucfg_mlme_is_imps_enabled(hdd_ctx->psoc, &is_imps_enabled);
16343 	hdd_set_idle_ps_config(hdd_ctx, is_imps_enabled);
16344 
16345 	fw_data_stall_evt = ucfg_dp_fw_data_stall_evt_enabled();
16346 
16347 	/* Send Enable/Disable data stall detection cmd to FW */
16348 	sme_cli_set_command(0, wmi_pdev_param_data_stall_detect_enable,
16349 			    fw_data_stall_evt, PDEV_CMD);
16350 
16351 	ucfg_mlme_get_go_cts2self_for_sta(hdd_ctx->psoc, &b_cts2self);
16352 	if (b_cts2self)
16353 		sme_set_cts2self_for_p2p_go(mac_handle);
16354 
16355 	if (hdd_set_vc_mode_config(hdd_ctx))
16356 		hdd_warn("Error in setting Voltage Corner mode config to FW");
16357 
16358 	if (ucfg_dp_rx_ol_init(hdd_ctx->psoc, hdd_ctx->is_wifi3_0_target))
16359 		hdd_err("Unable to initialize Rx LRO/GRO in fw");
16360 
16361 	if (hdd_adaptive_dwelltime_init(hdd_ctx))
16362 		hdd_err("Unable to send adaptive dwelltime setting to FW");
16363 
16364 	if (hdd_dbs_scan_selection_init(hdd_ctx))
16365 		hdd_err("Unable to send DBS scan selection setting to FW");
16366 
16367 	ret = hdd_init_thermal_info(hdd_ctx);
16368 	if (ret) {
16369 		hdd_err("Error while initializing thermal information");
16370 		return ret;
16371 	}
16372 
16373 	/**
16374 	 * In case of SSR/PDR, if pktlog was enabled manually before
16375 	 * SSR/PDR, then enable it again automatically after Wlan
16376 	 * device up.
16377 	 * During SSR/PDR, pktlog will be disabled as part of
16378 	 * hdd_features_deinit if pktlog is enabled in ini.
16379 	 * Re-enable pktlog in SSR case, if pktlog is enabled in ini.
16380 	 */
16381 	if (hdd_get_conparam() != QDF_GLOBAL_MONITOR_MODE &&
16382 	    (cds_is_packet_log_enabled() ||
16383 	    (cds_is_driver_recovering() && hdd_ctx->is_pktlog_enabled)))
16384 		hdd_pktlog_enable_disable(hdd_ctx, true, 0, 0);
16385 
16386 	hddtxlimit.txPower2g = ucfg_get_tx_power(hdd_ctx->psoc, BAND_2G);
16387 	hddtxlimit.txPower5g = ucfg_get_tx_power(hdd_ctx->psoc, BAND_5G);
16388 	status = sme_txpower_limit(mac_handle, &hddtxlimit);
16389 	if (!QDF_IS_STATUS_SUCCESS(status))
16390 		hdd_err("Error setting txlimit in sme: %d", status);
16391 
16392 	wlan_hdd_tsf_init(hdd_ctx);
16393 
16394 	status = sme_enable_disable_chanavoidind_event(mac_handle, 0);
16395 	if (QDF_IS_STATUS_ERROR(status) && (status != QDF_STATUS_E_NOSUPPORT)) {
16396 		hdd_err("Failed to disable Chan Avoidance Indication");
16397 		return -EINVAL;
16398 	}
16399 
16400 	/* register P2P Listen Offload event callback */
16401 	if (wma_is_p2p_lo_capable())
16402 		sme_register_p2p_lo_event(mac_handle, hdd_ctx,
16403 					  wlan_hdd_p2p_lo_event_callback);
16404 	wlan_hdd_register_mcc_quota_event_callback(hdd_ctx);
16405 	ret = hdd_set_auto_shutdown_cb(hdd_ctx);
16406 
16407 	if (ret)
16408 		return -EINVAL;
16409 
16410 	wlan_hdd_init_chan_info(hdd_ctx);
16411 	wlan_hdd_twt_init(hdd_ctx);
16412 	wlan_hdd_gpio_wakeup_init(hdd_ctx);
16413 
16414 	status = ucfg_mlme_is_rf_test_mode_enabled(hdd_ctx->psoc,
16415 						   &rf_test_mode);
16416 	if (!QDF_IS_STATUS_SUCCESS(status)) {
16417 		hdd_err("Get rf test mode failed");
16418 		return QDF_STATUS_E_FAILURE;
16419 	}
16420 
16421 	if (rf_test_mode) {
16422 		wlan_cm_set_check_6ghz_security(hdd_ctx->psoc, false);
16423 		wlan_cm_set_6ghz_key_mgmt_mask(hdd_ctx->psoc,
16424 					       DEFAULT_KEYMGMT_6G_MASK);
16425 	}
16426 
16427 	status = ucfg_mlme_is_standard_6ghz_conn_policy_enabled(hdd_ctx->psoc,
16428 							&std_6ghz_conn_policy);
16429 
16430 	if (!QDF_IS_STATUS_SUCCESS(status)) {
16431 		hdd_err("Get 6ghz standard connection policy failed");
16432 		return QDF_STATUS_E_FAILURE;
16433 	}
16434 	if (std_6ghz_conn_policy)
16435 		wlan_cm_set_standard_6ghz_conn_policy(hdd_ctx->psoc, true);
16436 
16437 	status = ucfg_mlme_is_disable_vlp_sta_conn_to_sp_ap_enabled(
16438 						hdd_ctx->psoc,
16439 						&disable_vlp_sta_conn_sp_ap);
16440 	if (!QDF_IS_STATUS_SUCCESS(status)) {
16441 		hdd_err("Get disable vlp sta conn to sp flag failed");
16442 		return QDF_STATUS_E_FAILURE;
16443 	}
16444 
16445 	if (disable_vlp_sta_conn_sp_ap)
16446 		wlan_cm_set_disable_vlp_sta_conn_to_sp_ap(hdd_ctx->psoc, true);
16447 
16448 	hdd_thermal_stats_cmd_init(hdd_ctx);
16449 	sme_set_cal_failure_event_cb(hdd_ctx->mac_handle,
16450 				     hdd_cal_fail_send_event);
16451 
16452 	hdd_exit();
16453 	return 0;
16454 }
16455 
16456 /**
16457  * hdd_register_bcn_cb() - register scan beacon callback
16458  * @hdd_ctx: Pointer to the HDD context
16459  *
16460  * Return: QDF_STATUS
16461  */
16462 static inline QDF_STATUS hdd_register_bcn_cb(struct hdd_context *hdd_ctx)
16463 {
16464 	QDF_STATUS status;
16465 
16466 	status = ucfg_scan_register_bcn_cb(hdd_ctx->psoc,
16467 		wlan_cfg80211_inform_bss_frame,
16468 		SCAN_CB_TYPE_INFORM_BCN);
16469 	if (!QDF_IS_STATUS_SUCCESS(status)) {
16470 		hdd_err("failed to register SCAN_CB_TYPE_INFORM_BCN with status code %08d [x%08x]",
16471 			status, status);
16472 		return status;
16473 	}
16474 
16475 	status = ucfg_scan_register_bcn_cb(hdd_ctx->psoc,
16476 		wlan_cfg80211_unlink_bss_list,
16477 		SCAN_CB_TYPE_UNLINK_BSS);
16478 	if (!QDF_IS_STATUS_SUCCESS(status)) {
16479 		hdd_err("failed to refister SCAN_CB_TYPE_FLUSH_BSS with status code %08d [x%08x]",
16480 			status, status);
16481 		return status;
16482 	}
16483 
16484 	return QDF_STATUS_SUCCESS;
16485 }
16486 
16487 /**
16488  * hdd_v2_flow_pool_map() - Flow pool create callback when vdev is active
16489  * @vdev_id: vdev_id, corresponds to flow_pool
16490  *
16491  * Return: none.
16492  */
16493 static void hdd_v2_flow_pool_map(int vdev_id)
16494 {
16495 	QDF_STATUS status;
16496 	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
16497 	struct wlan_objmgr_vdev *vdev;
16498 
16499 	if (!hdd_ctx) {
16500 		hdd_err("HDD context null");
16501 		return;
16502 	}
16503 
16504 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(hdd_ctx->psoc, vdev_id,
16505 						    WLAN_OSIF_ID);
16506 	if (!vdev) {
16507 		hdd_err("Invalid VDEV %d", vdev_id);
16508 		return;
16509 	}
16510 
16511 	if (wlan_vdev_mlme_is_mlo_link_switch_in_progress(vdev) ||
16512 	    policy_mgr_is_set_link_in_progress(wlan_vdev_get_psoc(vdev))) {
16513 		hdd_info_rl("Link switch/set_link is ongoing, do not invoke flow pool map");
16514 		goto release_ref;
16515 	}
16516 
16517 	status = cdp_flow_pool_map(cds_get_context(QDF_MODULE_ID_SOC),
16518 				   OL_TXRX_PDEV_ID, vdev_id);
16519 	/*
16520 	 * For Adrastea flow control v2 is based on FW MAP events,
16521 	 * so this above callback is not implemented.
16522 	 * Hence this is not actual failure. Dont return failure
16523 	 */
16524 	if ((status != QDF_STATUS_SUCCESS) &&
16525 	    (status != QDF_STATUS_E_INVAL)) {
16526 		hdd_err("vdev_id: %d, failed to create flow pool status %d",
16527 			vdev_id, status);
16528 	}
16529 
16530 release_ref:
16531 	wlan_objmgr_vdev_release_ref(vdev, WLAN_OSIF_ID);
16532 }
16533 
16534 /**
16535  * hdd_v2_flow_pool_unmap() - Flow pool create callback when vdev is not active
16536  * @vdev_id: vdev_id, corresponds to flow_pool
16537  *
16538  * Return: none.
16539  */
16540 static void hdd_v2_flow_pool_unmap(int vdev_id)
16541 {
16542 	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
16543 	struct wlan_objmgr_vdev *vdev;
16544 
16545 	if (!hdd_ctx) {
16546 		hdd_err("HDD context null");
16547 		return;
16548 	}
16549 
16550 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(hdd_ctx->psoc, vdev_id,
16551 						    WLAN_OSIF_ID);
16552 	if (!vdev) {
16553 		hdd_err("Invalid VDEV %d", vdev_id);
16554 		return;
16555 	}
16556 
16557 	if (wlan_vdev_mlme_is_mlo_link_switch_in_progress(vdev)) {
16558 		hdd_info("Link switch ongoing do not invoke flow pool unmap");
16559 		goto release_ref;
16560 	}
16561 
16562 	cdp_flow_pool_unmap(cds_get_context(QDF_MODULE_ID_SOC),
16563 			    OL_TXRX_PDEV_ID, vdev_id);
16564 release_ref:
16565 	wlan_objmgr_vdev_release_ref(vdev, WLAN_OSIF_ID);
16566 }
16567 
16568 static void hdd_hastings_bt_war_initialize(struct hdd_context *hdd_ctx)
16569 {
16570 	if (hdd_ctx->config->iface_change_wait_time)
16571 		hdd_hastings_bt_war_disable_fw(hdd_ctx);
16572 	else
16573 		hdd_hastings_bt_war_enable_fw(hdd_ctx);
16574 }
16575 
16576 #define MAX_PDEV_CFG_CDS_PARAMS 8
16577 /* params being sent:
16578  * wmi_pdev_param_set_iot_pattern
16579  * wmi_pdev_param_max_mpdus_in_ampdu
16580  * wmi_pdev_param_enable_rts_sifs_bursting
16581  * wmi_pdev_param_peer_stats_info_enable
16582  * wmi_pdev_param_abg_mode_tx_chain_num
16583  * wmi_pdev_param_gcmp_support_enable
16584  * wmi_pdev_auto_detect_power_failure
16585  * wmi_pdev_param_fast_pwr_transition
16586  */
16587 
16588 /**
16589  * hdd_configure_cds() - Configure cds modules
16590  * @hdd_ctx:	HDD context
16591  *
16592  * Enable Cds modules after WLAN firmware is up.
16593  *
16594  * Return: 0 on success and errno on failure.
16595  */
16596 int hdd_configure_cds(struct hdd_context *hdd_ctx)
16597 {
16598 	int ret;
16599 	QDF_STATUS status;
16600 	int set_value;
16601 	mac_handle_t mac_handle;
16602 	bool enable_rts_sifsbursting;
16603 	uint8_t enable_phy_reg_retention;
16604 	uint8_t max_mpdus_inampdu, is_force_1x1 = 0;
16605 	uint32_t num_abg_tx_chains = 0;
16606 	uint16_t num_11b_tx_chains = 0;
16607 	uint16_t num_11ag_tx_chains = 0;
16608 	struct policy_mgr_dp_cbacks dp_cbs = {0};
16609 	bool value;
16610 	enum pmo_auto_pwr_detect_failure_mode auto_power_fail_mode;
16611 	bool bval = false;
16612 	uint8_t max_index = MAX_PDEV_CFG_CDS_PARAMS;
16613 	struct dev_set_param setparam[MAX_PDEV_CFG_CDS_PARAMS] = {};
16614 	uint8_t index = 0;
16615 	uint8_t next_index = 0;
16616 	mac_handle = hdd_ctx->mac_handle;
16617 
16618 	status = ucfg_policy_mgr_get_force_1x1(hdd_ctx->psoc, &is_force_1x1);
16619 	if (status != QDF_STATUS_SUCCESS) {
16620 		hdd_err("Failed to get force 1x1 value");
16621 		goto out;
16622 	}
16623 	if (is_force_1x1) {
16624 		status = mlme_check_index_setparam(
16625 						setparam,
16626 						wmi_pdev_param_set_iot_pattern,
16627 						1, index++,
16628 						max_index);
16629 		if (QDF_IS_STATUS_ERROR(status)) {
16630 			hdd_err("failed at wmi_pdev_param_set_iot_pattern");
16631 			goto out;
16632 		}
16633 	}
16634 	/* set chip power save failure detected callback */
16635 	sme_set_chip_pwr_save_fail_cb(mac_handle,
16636 				      hdd_chip_pwr_save_fail_detected_cb);
16637 
16638 	status = ucfg_get_max_mpdus_inampdu(hdd_ctx->psoc,
16639 					    &max_mpdus_inampdu);
16640 	if (status) {
16641 		hdd_err("Failed to get max mpdus in ampdu value");
16642 		goto out;
16643 	}
16644 
16645 	if (max_mpdus_inampdu) {
16646 		set_value = max_mpdus_inampdu;
16647 		status = mlme_check_index_setparam(
16648 					      setparam,
16649 					      wmi_pdev_param_max_mpdus_in_ampdu,
16650 					      set_value, index++,
16651 					      max_index);
16652 		if (QDF_IS_STATUS_ERROR(status)) {
16653 			hdd_err("failed at  wmi_pdev_param_max_mpdus_in_ampdu");
16654 			goto out;
16655 		}
16656 	}
16657 
16658 	status = ucfg_get_enable_rts_sifsbursting(hdd_ctx->psoc,
16659 						  &enable_rts_sifsbursting);
16660 	if (status) {
16661 		hdd_err("Failed to get rts sifs bursting value");
16662 		goto out;
16663 	}
16664 
16665 	if (enable_rts_sifsbursting) {
16666 		set_value = enable_rts_sifsbursting;
16667 		status = mlme_check_index_setparam(
16668 					setparam,
16669 					wmi_pdev_param_enable_rts_sifs_bursting,
16670 					set_value, index++,
16671 					max_index);
16672 		if (QDF_IS_STATUS_ERROR(status)) {
16673 			hdd_err("Failed at wmi_pdev_param_enable_rts_sifs_bursting");
16674 			goto out;
16675 		}
16676 	}
16677 
16678 	ucfg_mlme_get_sap_get_peer_info(hdd_ctx->psoc, &value);
16679 	if (value) {
16680 		set_value = value;
16681 		status = mlme_check_index_setparam(
16682 					setparam,
16683 					wmi_pdev_param_peer_stats_info_enable,
16684 					set_value, index++,
16685 					max_index);
16686 		if (QDF_IS_STATUS_ERROR(status)) {
16687 			hdd_err("Failed at wmi_pdev_param_peer_stats_info_enable");
16688 			goto out;
16689 		}
16690 	}
16691 
16692 	status = ucfg_mlme_get_num_11b_tx_chains(hdd_ctx->psoc,
16693 						 &num_11b_tx_chains);
16694 	if (status != QDF_STATUS_SUCCESS) {
16695 		hdd_err("Failed to get num_11b_tx_chains");
16696 		goto out;
16697 	}
16698 
16699 	status = ucfg_mlme_get_num_11ag_tx_chains(hdd_ctx->psoc,
16700 						  &num_11ag_tx_chains);
16701 	if (status != QDF_STATUS_SUCCESS) {
16702 		hdd_err("Failed to get num_11ag_tx_chains");
16703 		goto out;
16704 	}
16705 
16706 	status = ucfg_mlme_get_vht_enable2x2(hdd_ctx->psoc, &bval);
16707 	if (!QDF_IS_STATUS_SUCCESS(status))
16708 		hdd_err("unable to get vht_enable2x2");
16709 
16710 	if (!bval) {
16711 		if (num_11b_tx_chains > 1)
16712 			num_11b_tx_chains = 1;
16713 		if (num_11ag_tx_chains > 1)
16714 			num_11ag_tx_chains = 1;
16715 	}
16716 	WMI_PDEV_PARAM_SET_11B_TX_CHAIN_NUM(num_abg_tx_chains,
16717 					    num_11b_tx_chains);
16718 	WMI_PDEV_PARAM_SET_11AG_TX_CHAIN_NUM(num_abg_tx_chains,
16719 					     num_11ag_tx_chains);
16720 	status = mlme_check_index_setparam(setparam,
16721 					   wmi_pdev_param_abg_mode_tx_chain_num,
16722 					   num_abg_tx_chains, index++,
16723 					   max_index);
16724 	if (QDF_IS_STATUS_ERROR(status)) {
16725 		hdd_err("Failed at wmi_pdev_param_abg_mode_tx_chain_num");
16726 		goto out;
16727 	}
16728 	/* Send some pdev params to maintain legacy order of pdev set params
16729 	 * at hdd_pre_enable_configure
16730 	 */
16731 	status = sme_send_multi_pdev_vdev_set_params(MLME_PDEV_SETPARAM,
16732 						     WMI_PDEV_ID_SOC, setparam,
16733 						     index);
16734 	if (QDF_IS_STATUS_ERROR(status)) {
16735 		hdd_err("Failed to send 1st set of pdev params");
16736 		goto out;
16737 	}
16738 	if (!ucfg_reg_is_regdb_offloaded(hdd_ctx->psoc))
16739 		ucfg_reg_program_default_cc(hdd_ctx->pdev,
16740 					    hdd_ctx->reg.reg_domain);
16741 
16742 	ret = hdd_pre_enable_configure(hdd_ctx);
16743 	if (ret) {
16744 		hdd_err("Failed to pre-configure cds");
16745 		goto out;
16746 	}
16747 
16748 	/* Always get latest IPA resources allocated from cds_open and configure
16749 	 * IPA module before configuring them to FW. Sequence required as crash
16750 	 * observed otherwise.
16751 	 */
16752 
16753 	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
16754 		ipa_disable_register_cb();
16755 	} else {
16756 		status = ipa_register_is_ipa_ready(hdd_ctx->pdev);
16757 		if (!QDF_IS_STATUS_SUCCESS(status)) {
16758 			hdd_err("ipa_register_is_ipa_ready failed");
16759 			goto out;
16760 		}
16761 	}
16762 
16763 	/*
16764 	 * Start CDS which starts up the SME/MAC/HAL modules and everything
16765 	 * else
16766 	 */
16767 	status = cds_enable(hdd_ctx->psoc);
16768 
16769 	if (!QDF_IS_STATUS_SUCCESS(status)) {
16770 		hdd_err("cds_enable failed");
16771 		goto out;
16772 	}
16773 
16774 	status = hdd_post_cds_enable_config(hdd_ctx);
16775 	if (!QDF_IS_STATUS_SUCCESS(status)) {
16776 		hdd_err("hdd_post_cds_enable_config failed");
16777 		goto cds_disable;
16778 	}
16779 	status = hdd_register_bcn_cb(hdd_ctx);
16780 	if (!QDF_IS_STATUS_SUCCESS(status)) {
16781 		hdd_err("hdd_register_bcn_cb failed");
16782 		goto cds_disable;
16783 	}
16784 
16785 	ret = hdd_features_init(hdd_ctx);
16786 	if (ret)
16787 		goto cds_disable;
16788 
16789 	/*
16790 	 * Donot disable rx offload on concurrency for lithium and
16791 	 * beryllium based targets
16792 	 */
16793 	if (!hdd_ctx->is_wifi3_0_target)
16794 		if (ucfg_dp_is_ol_enabled(hdd_ctx->psoc))
16795 			dp_cbs.hdd_disable_rx_ol_in_concurrency =
16796 					hdd_disable_rx_ol_in_concurrency;
16797 	dp_cbs.hdd_set_rx_mode_rps_cb = ucfg_dp_set_rx_mode_rps;
16798 	dp_cbs.hdd_ipa_set_mcc_mode_cb = hdd_ipa_set_mcc_mode;
16799 	dp_cbs.hdd_v2_flow_pool_map = hdd_v2_flow_pool_map;
16800 	dp_cbs.hdd_v2_flow_pool_unmap = hdd_v2_flow_pool_unmap;
16801 	if (ucfg_ipa_set_perf_level_bw_enabled(hdd_ctx->pdev))
16802 		dp_cbs.hdd_ipa_set_perf_level_bw = hdd_ipa_set_perf_level_bw;
16803 	status = policy_mgr_register_dp_cb(hdd_ctx->psoc, &dp_cbs);
16804 	if (!QDF_IS_STATUS_SUCCESS(status)) {
16805 		hdd_debug("Failed to register DP cb with Policy Manager");
16806 		goto cds_disable;
16807 	}
16808 	status = policy_mgr_register_mode_change_cb(hdd_ctx->psoc,
16809 					       wlan_hdd_send_mode_change_event);
16810 	if (!QDF_IS_STATUS_SUCCESS(status)) {
16811 		hdd_debug("Failed to register mode change cb with Policy Manager");
16812 		goto cds_disable;
16813 	}
16814 
16815 	if (hdd_green_ap_enable_egap(hdd_ctx))
16816 		hdd_debug("enhance green ap is not enabled");
16817 
16818 	hdd_register_green_ap_callback(hdd_ctx->pdev);
16819 
16820 	if (0 != wlan_hdd_set_wow_pulse(hdd_ctx, true))
16821 		hdd_debug("Failed to set wow pulse");
16822 
16823 	max_index = max_index - index;
16824 	status = mlme_check_index_setparam(
16825 				      setparam + index,
16826 				      wmi_pdev_param_gcmp_support_enable,
16827 				      ucfg_fwol_get_gcmp_enable(hdd_ctx->psoc),
16828 				      next_index++, max_index);
16829 	if (QDF_IS_STATUS_ERROR(status)) {
16830 		hdd_err("failed at wmi_pdev_param_gcmp_support_enable");
16831 		goto out;
16832 	}
16833 
16834 	 auto_power_fail_mode =
16835 		ucfg_pmo_get_auto_power_fail_mode(hdd_ctx->psoc);
16836 	status = mlme_check_index_setparam(
16837 				      setparam + index,
16838 				      wmi_pdev_auto_detect_power_failure,
16839 				      auto_power_fail_mode,
16840 				      next_index++, max_index);
16841 	if (QDF_IS_STATUS_ERROR(status)) {
16842 		hdd_err("failed at wmi_pdev_auto_detect_power_failure");
16843 		goto out;
16844 	}
16845 
16846 	status = ucfg_get_enable_phy_reg_retention(hdd_ctx->psoc,
16847 						   &enable_phy_reg_retention);
16848 
16849 	if (QDF_IS_STATUS_ERROR(status))
16850 		return -EINVAL;
16851 
16852 	if (enable_phy_reg_retention) {
16853 		status = mlme_check_index_setparam(
16854 					setparam + index,
16855 					wmi_pdev_param_fast_pwr_transition,
16856 					enable_phy_reg_retention,
16857 					next_index++, max_index);
16858 		if (QDF_IS_STATUS_ERROR(status)) {
16859 			hdd_err("failed at wmi_pdev_param_fast_pwr_transition");
16860 			goto out;
16861 		}
16862 	}
16863 	/*Send remaining pdev setparams from array*/
16864 	status = sme_send_multi_pdev_vdev_set_params(MLME_PDEV_SETPARAM,
16865 						     WMI_PDEV_ID_SOC,
16866 						     setparam + index,
16867 						     next_index);
16868 	if (QDF_IS_STATUS_ERROR(status)) {
16869 		hdd_err("failed to send 2nd set of pdev set params");
16870 		goto out;
16871 	}
16872 
16873 	hdd_hastings_bt_war_initialize(hdd_ctx);
16874 
16875 	wlan_hdd_hang_event_notifier_register(hdd_ctx);
16876 	return 0;
16877 
16878 cds_disable:
16879 	cds_disable(hdd_ctx->psoc);
16880 
16881 out:
16882 	return -EINVAL;
16883 }
16884 
16885 #ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
16886 static void hdd_deregister_policy_manager_callback(
16887 			struct wlan_objmgr_psoc *psoc)
16888 {
16889 	if (QDF_STATUS_SUCCESS !=
16890 	    policy_mgr_deregister_hdd_cb(psoc)) {
16891 		hdd_err("HDD callback deregister with policy manager failed");
16892 	}
16893 }
16894 #else
16895 static void hdd_deregister_policy_manager_callback(
16896 			struct wlan_objmgr_psoc *psoc)
16897 {
16898 }
16899 #endif
16900 
16901 int hdd_wlan_stop_modules(struct hdd_context *hdd_ctx, bool ftm_mode)
16902 {
16903 	void *hif_ctx;
16904 	qdf_device_t qdf_ctx;
16905 	QDF_STATUS qdf_status;
16906 	bool is_recovery_stop = cds_is_driver_recovering();
16907 	int ret = 0;
16908 	int debugfs_threads;
16909 	struct target_psoc_info *tgt_hdl;
16910 	struct bbm_params param = {0};
16911 
16912 	hdd_enter();
16913 	qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
16914 	if (!qdf_ctx)
16915 		return -EINVAL;
16916 
16917 	cds_set_driver_state_module_stop(true);
16918 
16919 	debugfs_threads = hdd_return_debugfs_threads_count();
16920 
16921 	if (debugfs_threads > 0 || hdd_ctx->is_wiphy_suspended) {
16922 		hdd_warn("Debugfs threads %d, wiphy suspend %d",
16923 			 debugfs_threads, hdd_ctx->is_wiphy_suspended);
16924 
16925 		if (IS_IDLE_STOP && !ftm_mode) {
16926 			hdd_psoc_idle_timer_start(hdd_ctx);
16927 			cds_set_driver_state_module_stop(false);
16928 
16929 			ucfg_dp_bus_bw_compute_timer_stop(hdd_ctx->psoc);
16930 			return -EAGAIN;
16931 		}
16932 	}
16933 
16934 	ucfg_dp_bus_bw_compute_timer_stop(hdd_ctx->psoc);
16935 	hdd_deregister_policy_manager_callback(hdd_ctx->psoc);
16936 
16937 	/* free user wowl patterns */
16938 	hdd_free_user_wowl_ptrns();
16939 
16940 	switch (hdd_ctx->driver_status) {
16941 	case DRIVER_MODULES_UNINITIALIZED:
16942 		hdd_debug("Modules not initialized just return");
16943 		goto done;
16944 	case DRIVER_MODULES_CLOSED:
16945 		hdd_debug("Modules already closed");
16946 		goto done;
16947 	case DRIVER_MODULES_ENABLED:
16948 		hdd_debug("Wlan transitioning (CLOSED <- ENABLED)");
16949 
16950 		if (hdd_get_conparam() == QDF_GLOBAL_FTM_MODE) {
16951 			hdd_disable_power_management(hdd_ctx);
16952 			break;
16953 		}
16954 
16955 		if (hdd_get_conparam() == QDF_GLOBAL_EPPING_MODE)
16956 			break;
16957 
16958 		hdd_skip_acs_scan_timer_deinit(hdd_ctx);
16959 
16960 		hdd_disable_power_management(hdd_ctx);
16961 
16962 		if (hdd_get_conparam() == QDF_GLOBAL_MISSION_MODE)
16963 			ucfg_dp_direct_link_deinit(hdd_ctx->psoc,
16964 						   is_recovery_stop);
16965 
16966 		if (hdd_deconfigure_cds(hdd_ctx)) {
16967 			hdd_err("Failed to de-configure CDS");
16968 			QDF_ASSERT(0);
16969 			ret = -EINVAL;
16970 		}
16971 		hdd_debug("successfully Disabled the CDS modules!");
16972 
16973 		break;
16974 	default:
16975 		QDF_DEBUG_PANIC("Unknown driver state:%d",
16976 				hdd_ctx->driver_status);
16977 		ret = -EINVAL;
16978 		goto done;
16979 	}
16980 
16981 	hdd_destroy_sysfs_files();
16982 	hdd_debug("Closing CDS modules!");
16983 
16984 	if (hdd_get_conparam() != QDF_GLOBAL_EPPING_MODE) {
16985 		qdf_status = cds_post_disable();
16986 		if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
16987 			hdd_err("Failed to process post CDS disable! :%d",
16988 				qdf_status);
16989 			ret = -EINVAL;
16990 			QDF_ASSERT(0);
16991 		}
16992 
16993 		hdd_unregister_notifiers(hdd_ctx);
16994 		/* De-register the SME callbacks */
16995 		hdd_deregister_cb(hdd_ctx);
16996 
16997 		hdd_runtime_suspend_context_deinit(hdd_ctx);
16998 
16999 		qdf_status = cds_dp_close(hdd_ctx->psoc);
17000 		if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
17001 			hdd_warn("Failed to stop CDS DP: %d", qdf_status);
17002 			ret = -EINVAL;
17003 			QDF_ASSERT(0);
17004 		}
17005 
17006 		hdd_component_pdev_close(hdd_ctx->pdev);
17007 		dispatcher_pdev_close(hdd_ctx->pdev);
17008 		ret = hdd_objmgr_release_and_destroy_pdev(hdd_ctx);
17009 		if (ret) {
17010 			hdd_err("Failed to destroy pdev; errno:%d", ret);
17011 			QDF_ASSERT(0);
17012 		}
17013 
17014 		qdf_status = cds_close(hdd_ctx->psoc);
17015 		if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
17016 			hdd_warn("Failed to stop CDS: %d", qdf_status);
17017 			ret = -EINVAL;
17018 			QDF_ASSERT(0);
17019 		}
17020 
17021 		qdf_status = wbuff_module_deinit();
17022 		if (!QDF_IS_STATUS_SUCCESS(qdf_status))
17023 			hdd_err("WBUFF de-init unsuccessful; status: %d",
17024 				qdf_status);
17025 
17026 		hdd_component_psoc_close(hdd_ctx->psoc);
17027 		/* pdev close and destroy use tx rx ops so call this here */
17028 		wlan_global_lmac_if_close(hdd_ctx->psoc);
17029 	}
17030 
17031 	/*
17032 	 * Reset total mac phy during module stop such that during
17033 	 * next module start same psoc is used to populate new service
17034 	 * ready data
17035 	 */
17036 	tgt_hdl = wlan_psoc_get_tgt_if_handle(hdd_ctx->psoc);
17037 	if (tgt_hdl)
17038 		target_psoc_set_total_mac_phy_cnt(tgt_hdl, 0);
17039 
17040 
17041 	hif_ctx = cds_get_context(QDF_MODULE_ID_HIF);
17042 	if (!hif_ctx)
17043 		ret = -EINVAL;
17044 
17045 	if (hdd_get_conparam() == QDF_GLOBAL_EPPING_MODE) {
17046 		epping_disable();
17047 		epping_close();
17048 	}
17049 
17050 	wlan_connectivity_logging_stop();
17051 
17052 	ucfg_ipa_component_config_free();
17053 
17054 	hdd_hif_close(hdd_ctx, hif_ctx);
17055 
17056 	ol_cds_free();
17057 
17058 	if (IS_IDLE_STOP) {
17059 		ret = pld_power_off(qdf_ctx->dev);
17060 		if (ret)
17061 			hdd_err("Failed to power down device; errno:%d", ret);
17062 	}
17063 
17064 	/* Free the cache channels of the command SET_DISABLE_CHANNEL_LIST */
17065 	wlan_hdd_free_cache_channels(hdd_ctx);
17066 	hdd_driver_mem_cleanup();
17067 
17068 	/* Free the resources allocated while storing SAR config. These needs
17069 	 * to be freed only in the case when it is not SSR. As in the case of
17070 	 * SSR, the values needs to be intact so that it can be restored during
17071 	 * reinit path.
17072 	 */
17073 	if (!is_recovery_stop)
17074 		wlan_hdd_free_sar_config(hdd_ctx);
17075 
17076 	hdd_sap_destroy_ctx_all(hdd_ctx, is_recovery_stop);
17077 	hdd_sta_destroy_ctx_all(hdd_ctx);
17078 
17079 	/*
17080 	 * Reset the driver mode specific bus bw level
17081 	 */
17082 	param.policy = BBM_DRIVER_MODE_POLICY;
17083 	param.policy_info.driver_mode = QDF_GLOBAL_MAX_MODE;
17084 	ucfg_dp_bbm_apply_independent_policy(hdd_ctx->psoc, &param);
17085 
17086 	hdd_deinit_adapter_ops_wq(hdd_ctx);
17087 	hdd_deinit_qdf_ctx(hdd_debug_domain_get());
17088 
17089 	hdd_check_for_leaks(hdd_ctx, is_recovery_stop);
17090 	hdd_debug_domain_set(QDF_DEBUG_DOMAIN_INIT);
17091 	hdd_deinit_qdf_ctx(hdd_debug_domain_get());
17092 	qdf_dma_invalid_buf_list_deinit();
17093 
17094 	/* Restore PS params for monitor mode */
17095 	if (hdd_get_conparam() == QDF_GLOBAL_MONITOR_MODE)
17096 		hdd_restore_all_ps(hdd_ctx);
17097 
17098 	/* Once the firmware sequence is completed reset this flag */
17099 	hdd_ctx->imps_enabled = false;
17100 	hdd_ctx->is_dual_mac_cfg_updated = false;
17101 	hdd_ctx->driver_status = DRIVER_MODULES_CLOSED;
17102 	hdd_ctx->is_fw_dbg_log_levels_configured = false;
17103 	hdd_debug("Wlan transitioned (now CLOSED)");
17104 
17105 done:
17106 	hdd_exit();
17107 
17108 	return ret;
17109 }
17110 
17111 #ifdef WLAN_FEATURE_MEMDUMP_ENABLE
17112 /**
17113  * hdd_state_info_dump() - prints state information of hdd layer
17114  * @buf_ptr: buffer pointer
17115  * @size: size of buffer to be filled
17116  *
17117  * This function is used to dump state information of hdd layer
17118  *
17119  * Return: None
17120  */
17121 static void hdd_state_info_dump(char **buf_ptr, uint16_t *size)
17122 {
17123 	struct hdd_context *hdd_ctx;
17124 	struct hdd_station_ctx *sta_ctx;
17125 	struct hdd_adapter *adapter, *next_adapter = NULL;
17126 	uint16_t len = 0;
17127 	char *buf = *buf_ptr;
17128 	wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_STATE_INFO_DUMP;
17129 	struct wlan_hdd_link_info *link_info;
17130 
17131 	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
17132 	if (!hdd_ctx)
17133 		return;
17134 
17135 	hdd_debug("size of buffer: %d", *size);
17136 
17137 	len += scnprintf(buf + len, *size - len, "\n is_wiphy_suspended %d",
17138 			 hdd_ctx->is_wiphy_suspended);
17139 	len += scnprintf(buf + len, *size - len, "\n is_scheduler_suspended %d",
17140 			 hdd_ctx->is_scheduler_suspended);
17141 
17142 	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
17143 					   dbgid) {
17144 		hdd_adapter_for_each_active_link_info(adapter, link_info) {
17145 			len +=
17146 			scnprintf(buf + len, *size - len, "\n device name: %s",
17147 				  adapter->dev->name);
17148 			len +=
17149 			scnprintf(buf + len, *size - len, "\n device_mode: %d",
17150 				  adapter->device_mode);
17151 			switch (adapter->device_mode) {
17152 			case QDF_STA_MODE:
17153 			case QDF_P2P_CLIENT_MODE:
17154 				sta_ctx =
17155 					WLAN_HDD_GET_STATION_CTX_PTR(link_info);
17156 				len += scnprintf(buf + len, *size - len,
17157 					"\n conn_state: %d",
17158 					sta_ctx->conn_info.conn_state);
17159 				break;
17160 			default:
17161 				break;
17162 			}
17163 		}
17164 		hdd_adapter_dev_put_debug(adapter, dbgid);
17165 	}
17166 
17167 	*size -= len;
17168 	*buf_ptr += len;
17169 }
17170 
17171 /**
17172  * hdd_register_debug_callback() - registration function for hdd layer
17173  * to print hdd state information
17174  *
17175  * Return: None
17176  */
17177 static void hdd_register_debug_callback(void)
17178 {
17179 	qdf_register_debug_callback(QDF_MODULE_ID_HDD, &hdd_state_info_dump);
17180 }
17181 #else /* WLAN_FEATURE_MEMDUMP_ENABLE */
17182 static void hdd_register_debug_callback(void)
17183 {
17184 }
17185 #endif /* WLAN_FEATURE_MEMDUMP_ENABLE */
17186 
17187 /*
17188  * wlan_init_bug_report_lock() - Initialize bug report lock
17189  *
17190  * This function is used to create bug report lock
17191  *
17192  * Return: None
17193  */
17194 static void wlan_init_bug_report_lock(void)
17195 {
17196 	struct cds_context *p_cds_context;
17197 
17198 	p_cds_context = cds_get_global_context();
17199 	if (!p_cds_context) {
17200 		hdd_err("cds context is NULL");
17201 		return;
17202 	}
17203 
17204 	qdf_spinlock_create(&p_cds_context->bug_report_lock);
17205 }
17206 
17207 #ifdef DISABLE_CHANNEL_LIST
17208 static QDF_STATUS wlan_hdd_cache_chann_mutex_create(struct hdd_context *hdd_ctx)
17209 {
17210 	return qdf_mutex_create(&hdd_ctx->cache_channel_lock);
17211 }
17212 #else
17213 static QDF_STATUS wlan_hdd_cache_chann_mutex_create(struct hdd_context *hdd_ctx)
17214 {
17215 	return QDF_STATUS_SUCCESS;
17216 }
17217 #endif
17218 
17219 QDF_STATUS hdd_open_adapter_no_trans(struct hdd_context *hdd_ctx,
17220 				     enum QDF_OPMODE op_mode,
17221 				     const char *iface_name,
17222 				     uint8_t *mac_addr_bytes,
17223 				     struct hdd_adapter_create_param *params)
17224 {
17225 	struct osif_vdev_sync *vdev_sync;
17226 	struct hdd_adapter *adapter;
17227 	QDF_STATUS status;
17228 	int errno;
17229 
17230 	QDF_BUG(rtnl_is_locked());
17231 
17232 	errno = osif_vdev_sync_create(hdd_ctx->parent_dev, &vdev_sync);
17233 	if (errno)
17234 		return qdf_status_from_os_return(errno);
17235 
17236 	adapter = hdd_open_adapter(hdd_ctx, op_mode, iface_name,
17237 				   mac_addr_bytes, NET_NAME_UNKNOWN, true,
17238 				   params);
17239 	if (!adapter) {
17240 		status = QDF_STATUS_E_INVAL;
17241 		goto destroy_sync;
17242 	}
17243 
17244 	osif_vdev_sync_register(adapter->dev, vdev_sync);
17245 
17246 	return QDF_STATUS_SUCCESS;
17247 
17248 destroy_sync:
17249 	osif_vdev_sync_destroy(vdev_sync);
17250 
17251 	return status;
17252 }
17253 
17254 #ifdef WLAN_OPEN_P2P_INTERFACE
17255 /**
17256  * hdd_open_p2p_interface - Open P2P interface
17257  * @hdd_ctx: HDD context
17258  *
17259  * Return: QDF_STATUS
17260  */
17261 static QDF_STATUS hdd_open_p2p_interface(struct hdd_context *hdd_ctx)
17262 {
17263 	QDF_STATUS status;
17264 	bool p2p_dev_addr_admin;
17265 	bool is_p2p_locally_administered = false;
17266 	struct hdd_adapter_create_param params = {0};
17267 
17268 	cfg_p2p_get_device_addr_admin(hdd_ctx->psoc, &p2p_dev_addr_admin);
17269 
17270 	if (p2p_dev_addr_admin) {
17271 		if (hdd_ctx->num_provisioned_addr &&
17272 		    !(hdd_ctx->provisioned_mac_addr[0].bytes[0] & 0x02)) {
17273 			hdd_ctx->p2p_device_address =
17274 					hdd_ctx->provisioned_mac_addr[0];
17275 
17276 			/*
17277 			 * Generate the P2P Device Address.  This consists of
17278 			 * the device's primary MAC address with the locally
17279 			 * administered bit set.
17280 			 */
17281 
17282 			hdd_ctx->p2p_device_address.bytes[0] |= 0x02;
17283 			is_p2p_locally_administered = true;
17284 		} else if (!(hdd_ctx->derived_mac_addr[0].bytes[0] & 0x02)) {
17285 			hdd_ctx->p2p_device_address =
17286 						hdd_ctx->derived_mac_addr[0];
17287 			/*
17288 			 * Generate the P2P Device Address.  This consists of
17289 			 * the device's primary MAC address with the locally
17290 			 * administered bit set.
17291 			 */
17292 			hdd_ctx->p2p_device_address.bytes[0] |= 0x02;
17293 			is_p2p_locally_administered = true;
17294 		}
17295 	}
17296 	if (!is_p2p_locally_administered) {
17297 		uint8_t *p2p_dev_addr;
17298 
17299 		p2p_dev_addr = wlan_hdd_get_intf_addr(hdd_ctx,
17300 						      QDF_P2P_DEVICE_MODE);
17301 		if (!p2p_dev_addr) {
17302 			hdd_err("Failed to get MAC address for new p2p device");
17303 			return QDF_STATUS_E_INVAL;
17304 		}
17305 
17306 		qdf_mem_copy(hdd_ctx->p2p_device_address.bytes,
17307 			     p2p_dev_addr, QDF_MAC_ADDR_SIZE);
17308 	}
17309 
17310 	status = hdd_open_adapter_no_trans(hdd_ctx, QDF_P2P_DEVICE_MODE,
17311 					   "p2p%d",
17312 					   hdd_ctx->p2p_device_address.bytes,
17313 					   &params);
17314 	if (QDF_IS_STATUS_ERROR(status)) {
17315 		if (!is_p2p_locally_administered)
17316 			wlan_hdd_release_intf_addr(hdd_ctx,
17317 					hdd_ctx->p2p_device_address.bytes);
17318 		hdd_err("Failed to open p2p interface");
17319 		return QDF_STATUS_E_INVAL;
17320 	}
17321 
17322 	return QDF_STATUS_SUCCESS;
17323 }
17324 #else
17325 static inline QDF_STATUS hdd_open_p2p_interface(struct hdd_context *hdd_ctx)
17326 {
17327 	return QDF_STATUS_SUCCESS;
17328 }
17329 #endif
17330 
17331 static QDF_STATUS hdd_open_ocb_interface(struct hdd_context *hdd_ctx)
17332 {
17333 	QDF_STATUS status;
17334 	uint8_t *mac_addr;
17335 	struct hdd_adapter_create_param params = {0};
17336 
17337 	mac_addr = wlan_hdd_get_intf_addr(hdd_ctx, QDF_OCB_MODE);
17338 	if (!mac_addr)
17339 		return QDF_STATUS_E_INVAL;
17340 
17341 	status = hdd_open_adapter_no_trans(hdd_ctx, QDF_OCB_MODE,
17342 					   "wlanocb%d", mac_addr,
17343 					   &params);
17344 	if (QDF_IS_STATUS_ERROR(status)) {
17345 		wlan_hdd_release_intf_addr(hdd_ctx, mac_addr);
17346 		hdd_err("Failed to open 802.11p interface");
17347 	}
17348 
17349 	return status;
17350 }
17351 
17352 static QDF_STATUS hdd_open_concurrent_interface(struct hdd_context *hdd_ctx)
17353 {
17354 	QDF_STATUS status;
17355 	const char *iface_name;
17356 	uint8_t *mac_addr;
17357 	struct hdd_adapter_create_param params = {0};
17358 
17359 	if (qdf_str_eq(hdd_ctx->config->enable_concurrent_sta, ""))
17360 		return QDF_STATUS_SUCCESS;
17361 
17362 	iface_name = hdd_ctx->config->enable_concurrent_sta;
17363 	mac_addr = wlan_hdd_get_intf_addr(hdd_ctx, QDF_STA_MODE);
17364 	if (!mac_addr)
17365 		return QDF_STATUS_E_INVAL;
17366 
17367 	status = hdd_open_adapter_no_trans(hdd_ctx, QDF_STA_MODE,
17368 					   iface_name, mac_addr,
17369 					   &params);
17370 	if (QDF_IS_STATUS_ERROR(status)) {
17371 		wlan_hdd_release_intf_addr(hdd_ctx, mac_addr);
17372 		hdd_err("Failed to open concurrent station interface");
17373 	}
17374 
17375 	return status;
17376 }
17377 
17378 #ifdef WLAN_HDD_MULTI_VDEV_SINGLE_NDEV
17379 static inline void
17380 hdd_adapter_open_set_max_active_links(struct hdd_adapter_create_param *params)
17381 {
17382 	if (params->is_add_virtual_iface || !params->is_ml_adapter)
17383 		params->num_sessions = 1;
17384 	else
17385 		params->num_sessions = 2;
17386 }
17387 #else
17388 static inline void
17389 hdd_adapter_open_set_max_active_links(struct hdd_adapter_create_param *params)
17390 {
17391 	params->num_sessions = 1;
17392 }
17393 #endif
17394 
17395 static QDF_STATUS
17396 hdd_open_adapters_for_mission_mode(struct hdd_context *hdd_ctx)
17397 {
17398 	enum dot11p_mode dot11p_mode;
17399 	QDF_STATUS status;
17400 	uint8_t *mac_addr;
17401 	struct hdd_adapter_create_param params = {0};
17402 	bool eht_capab = 0;
17403 
17404 	ucfg_mlme_get_dot11p_mode(hdd_ctx->psoc, &dot11p_mode);
17405 	ucfg_psoc_mlme_get_11be_capab(hdd_ctx->psoc, &eht_capab);
17406 
17407 	/* Create only 802.11p interface? */
17408 	if (dot11p_mode == CFG_11P_STANDALONE)
17409 		return hdd_open_ocb_interface(hdd_ctx);
17410 
17411 	mac_addr = wlan_hdd_get_intf_addr(hdd_ctx, QDF_STA_MODE);
17412 	if (!mac_addr)
17413 		return QDF_STATUS_E_INVAL;
17414 
17415 	if (eht_capab) {
17416 		params.is_ml_adapter = true;
17417 		hdd_adapter_open_set_max_active_links(&params);
17418 	}
17419 
17420 	status = hdd_open_adapter_no_trans(hdd_ctx, QDF_STA_MODE,
17421 					   "wlan%d", mac_addr,
17422 					   &params);
17423 	if (QDF_IS_STATUS_ERROR(status)) {
17424 		wlan_hdd_release_intf_addr(hdd_ctx, mac_addr);
17425 		return status;
17426 	}
17427 
17428 	/* opening concurrent STA is best effort, continue on error */
17429 	hdd_open_concurrent_interface(hdd_ctx);
17430 
17431 	status = hdd_open_p2p_interface(hdd_ctx);
17432 	if (status)
17433 		goto err_close_adapters;
17434 
17435 	/*
17436 	 * Create separate interface (wifi-aware0) for NAN. All NAN commands
17437 	 * should go on this new interface.
17438 	 */
17439 	if (wlan_hdd_is_vdev_creation_allowed(hdd_ctx->psoc)) {
17440 		qdf_mem_zero(&params, sizeof(params));
17441 		mac_addr = wlan_hdd_get_intf_addr(hdd_ctx, QDF_NAN_DISC_MODE);
17442 		if (!mac_addr)
17443 			goto err_close_adapters;
17444 
17445 		status = hdd_open_adapter_no_trans(hdd_ctx, QDF_NAN_DISC_MODE,
17446 						   "wifi-aware%d", mac_addr,
17447 						   &params);
17448 		if (status) {
17449 			wlan_hdd_release_intf_addr(hdd_ctx, mac_addr);
17450 			goto err_close_adapters;
17451 		}
17452 	}
17453 	/* Open 802.11p Interface */
17454 	if (dot11p_mode == CFG_11P_CONCURRENT) {
17455 		status = hdd_open_ocb_interface(hdd_ctx);
17456 		if (QDF_IS_STATUS_ERROR(status))
17457 			goto err_close_adapters;
17458 	}
17459 
17460 	if (eht_capab)
17461 		hdd_wlan_register_mlo_interfaces(hdd_ctx);
17462 
17463 	return QDF_STATUS_SUCCESS;
17464 
17465 err_close_adapters:
17466 	hdd_close_all_adapters(hdd_ctx, true);
17467 
17468 	return status;
17469 }
17470 
17471 static QDF_STATUS hdd_open_adapters_for_ftm_mode(struct hdd_context *hdd_ctx)
17472 {
17473 	QDF_STATUS status;
17474 	uint8_t *mac_addr;
17475 	struct hdd_adapter_create_param params = {0};
17476 
17477 	mac_addr = wlan_hdd_get_intf_addr(hdd_ctx, QDF_FTM_MODE);
17478 	if (!mac_addr)
17479 		return QDF_STATUS_E_INVAL;
17480 
17481 	status = hdd_open_adapter_no_trans(hdd_ctx, QDF_FTM_MODE,
17482 					   "wlan%d", mac_addr,
17483 					   &params);
17484 	if (QDF_IS_STATUS_ERROR(status)) {
17485 		wlan_hdd_release_intf_addr(hdd_ctx, mac_addr);
17486 		return status;
17487 	}
17488 
17489 	return QDF_STATUS_SUCCESS;
17490 }
17491 
17492 static QDF_STATUS
17493 hdd_open_adapters_for_monitor_mode(struct hdd_context *hdd_ctx)
17494 {
17495 	QDF_STATUS status;
17496 	uint8_t *mac_addr;
17497 	struct hdd_adapter_create_param params = {0};
17498 
17499 	mac_addr = wlan_hdd_get_intf_addr(hdd_ctx, QDF_MONITOR_MODE);
17500 	if (!mac_addr)
17501 		return QDF_STATUS_E_INVAL;
17502 
17503 	status = hdd_open_adapter_no_trans(hdd_ctx, QDF_MONITOR_MODE,
17504 					   "wlan%d", mac_addr,
17505 					   &params);
17506 	if (QDF_IS_STATUS_ERROR(status)) {
17507 		wlan_hdd_release_intf_addr(hdd_ctx, mac_addr);
17508 		return status;
17509 	}
17510 
17511 	return QDF_STATUS_SUCCESS;
17512 }
17513 
17514 static QDF_STATUS hdd_open_adapters_for_epping_mode(struct hdd_context *hdd_ctx)
17515 {
17516 	epping_enable_adapter();
17517 	return QDF_STATUS_SUCCESS;
17518 }
17519 
17520 typedef QDF_STATUS (*hdd_open_mode_handler)(struct hdd_context *hdd_ctx);
17521 
17522 static const hdd_open_mode_handler
17523 hdd_open_mode_handlers[QDF_GLOBAL_MAX_MODE] = {
17524 	[QDF_GLOBAL_MISSION_MODE] = hdd_open_adapters_for_mission_mode,
17525 	[QDF_GLOBAL_FTM_MODE] = hdd_open_adapters_for_ftm_mode,
17526 	[QDF_GLOBAL_MONITOR_MODE] = hdd_open_adapters_for_monitor_mode,
17527 	[QDF_GLOBAL_EPPING_MODE] = hdd_open_adapters_for_epping_mode,
17528 };
17529 
17530 static QDF_STATUS hdd_open_adapters_for_mode(struct hdd_context *hdd_ctx,
17531 					     enum QDF_GLOBAL_MODE driver_mode)
17532 {
17533 	QDF_STATUS status;
17534 
17535 	if (driver_mode < 0 ||
17536 	    driver_mode >= QDF_GLOBAL_MAX_MODE ||
17537 	    !hdd_open_mode_handlers[driver_mode]) {
17538 		hdd_err("Driver mode %d not supported", driver_mode);
17539 		return -ENOTSUPP;
17540 	}
17541 
17542 	hdd_hold_rtnl_lock();
17543 	status = hdd_open_mode_handlers[driver_mode](hdd_ctx);
17544 	hdd_release_rtnl_lock();
17545 
17546 	return status;
17547 }
17548 
17549 int hdd_wlan_startup(struct hdd_context *hdd_ctx)
17550 {
17551 	QDF_STATUS status;
17552 	int errno;
17553 	bool is_imps_enabled;
17554 
17555 	hdd_enter();
17556 
17557 	qdf_nbuf_init_replenish_timer();
17558 
17559 	status = wlan_hdd_cache_chann_mutex_create(hdd_ctx);
17560 	if (QDF_IS_STATUS_ERROR(status))
17561 		return qdf_status_to_os_return(status);
17562 
17563 #ifdef FEATURE_WLAN_CH_AVOID
17564 	mutex_init(&hdd_ctx->avoid_freq_lock);
17565 #endif
17566 
17567 	osif_request_manager_init();
17568 	hdd_driver_memdump_init();
17569 
17570 	errno = hdd_init_regulatory_update_event(hdd_ctx);
17571 	if (errno) {
17572 		hdd_err("Failed to initialize regulatory update event; errno:%d",
17573 			errno);
17574 		goto memdump_deinit;
17575 	}
17576 
17577 	errno = hdd_wlan_start_modules(hdd_ctx, false);
17578 	if (errno) {
17579 		hdd_err("Failed to start modules; errno:%d", errno);
17580 		goto memdump_deinit;
17581 	}
17582 
17583 	if (hdd_get_conparam() == QDF_GLOBAL_EPPING_MODE)
17584 		return 0;
17585 
17586 	wlan_hdd_update_wiphy(hdd_ctx);
17587 
17588 	hdd_ctx->mac_handle = cds_get_context(QDF_MODULE_ID_SME);
17589 	if (!hdd_ctx->mac_handle)
17590 		goto stop_modules;
17591 
17592 	errno = hdd_wiphy_init(hdd_ctx);
17593 	if (errno) {
17594 		hdd_err("Failed to initialize wiphy; errno:%d", errno);
17595 		goto stop_modules;
17596 	}
17597 
17598 	errno = hdd_initialize_mac_address(hdd_ctx);
17599 	if (errno) {
17600 		hdd_err("MAC initializtion failed: %d", errno);
17601 		goto unregister_wiphy;
17602 	}
17603 
17604 	errno = register_netdevice_notifier(&hdd_netdev_notifier);
17605 	if (errno) {
17606 		hdd_err("register_netdevice_notifier failed; errno:%d", errno);
17607 		goto unregister_wiphy;
17608 	}
17609 
17610 	wlan_hdd_update_11n_mode(hdd_ctx);
17611 
17612 	hdd_lpass_notify_wlan_version(hdd_ctx);
17613 
17614 	status = wlansap_global_init();
17615 	if (QDF_IS_STATUS_ERROR(status))
17616 		goto unregister_notifiers;
17617 
17618 	ucfg_mlme_is_imps_enabled(hdd_ctx->psoc, &is_imps_enabled);
17619 	hdd_set_idle_ps_config(hdd_ctx, is_imps_enabled);
17620 	hdd_debugfs_mws_coex_info_init(hdd_ctx);
17621 	hdd_debugfs_ini_config_init(hdd_ctx);
17622 	wlan_hdd_debugfs_unit_test_host_create(hdd_ctx);
17623 	wlan_hdd_create_mib_stats_lock();
17624 	wlan_cfg80211_init_interop_issues_ap(hdd_ctx->pdev);
17625 
17626 	hdd_exit();
17627 
17628 	return 0;
17629 
17630 unregister_notifiers:
17631 	unregister_netdevice_notifier(&hdd_netdev_notifier);
17632 
17633 unregister_wiphy:
17634 	qdf_dp_trace_deinit();
17635 	wiphy_unregister(hdd_ctx->wiphy);
17636 
17637 stop_modules:
17638 	hdd_wlan_stop_modules(hdd_ctx, false);
17639 
17640 memdump_deinit:
17641 	hdd_driver_memdump_deinit();
17642 	osif_request_manager_deinit();
17643 	qdf_nbuf_deinit_replenish_timer();
17644 
17645 	if (cds_is_fw_down())
17646 		hdd_err("Not setting the complete event as fw is down");
17647 	else
17648 		hdd_start_complete(errno);
17649 
17650 	hdd_exit();
17651 
17652 	return errno;
17653 }
17654 
17655 QDF_STATUS hdd_psoc_create_vdevs(struct hdd_context *hdd_ctx)
17656 {
17657 	enum QDF_GLOBAL_MODE driver_mode = hdd_get_conparam();
17658 	QDF_STATUS status;
17659 
17660 	status = hdd_open_adapters_for_mode(hdd_ctx, driver_mode);
17661 	if (QDF_IS_STATUS_ERROR(status)) {
17662 		hdd_err("Failed to create vdevs; status:%d", status);
17663 		return status;
17664 	}
17665 
17666 	ucfg_dp_try_set_rps_cpu_mask(hdd_ctx->psoc);
17667 
17668 	if (driver_mode != QDF_GLOBAL_FTM_MODE &&
17669 	    driver_mode != QDF_GLOBAL_EPPING_MODE)
17670 		hdd_psoc_idle_timer_start(hdd_ctx);
17671 
17672 	return QDF_STATUS_SUCCESS;
17673 }
17674 
17675 /**
17676  * hdd_wlan_update_target_info() - update target type info
17677  * @hdd_ctx: HDD context
17678  * @context: hif context
17679  *
17680  * Update target info received from firmware in hdd context
17681  * Return:None
17682  */
17683 
17684 void hdd_wlan_update_target_info(struct hdd_context *hdd_ctx, void *context)
17685 {
17686 	struct hif_target_info *tgt_info = hif_get_target_info_handle(context);
17687 
17688 	if (!tgt_info) {
17689 		hdd_err("Target info is Null");
17690 		return;
17691 	}
17692 
17693 	hdd_ctx->target_type = tgt_info->target_type;
17694 }
17695 
17696 #ifdef WLAN_FEATURE_MOTION_DETECTION
17697 /**
17698  * hdd_md_host_evt_cb - Callback for Motion Detection Event
17699  * @ctx: HDD context
17700  * @event: motion detect event
17701  *
17702  * Callback for Motion Detection Event. Re-enables Motion
17703  * Detection again upon event
17704  *
17705  * Return: QDF_STATUS QDF_STATUS_SUCCESS on Success and
17706  * QDF_STATUS_E_FAILURE on failure
17707  */
17708 QDF_STATUS hdd_md_host_evt_cb(void *ctx, struct sir_md_evt *event)
17709 {
17710 	struct hdd_adapter *adapter;
17711 	struct hdd_context *hdd_ctx;
17712 	struct sme_motion_det_en motion_det;
17713 	struct wlan_hdd_link_info *link_info;
17714 
17715 	if (!ctx || !event)
17716 		return QDF_STATUS_E_INVAL;
17717 
17718 	hdd_ctx = (struct hdd_context *)ctx;
17719 	if (wlan_hdd_validate_context(hdd_ctx))
17720 		return QDF_STATUS_E_INVAL;
17721 
17722 	link_info = hdd_get_link_info_by_vdev(hdd_ctx, event->vdev_id);
17723 	if (!link_info ||
17724 	    WLAN_HDD_ADAPTER_MAGIC != link_info->adapter->magic) {
17725 		hdd_err("Invalid adapter or adapter has invalid magic");
17726 		return QDF_STATUS_E_INVAL;
17727 	}
17728 
17729 	adapter = link_info->adapter;
17730 	/* When motion is detected, reset the motion_det_in_progress flag */
17731 	if (event->status)
17732 		adapter->motion_det_in_progress = false;
17733 
17734 	hdd_debug("Motion Detection CB vdev_id=%u, status=%u",
17735 		  event->vdev_id, event->status);
17736 
17737 	if (adapter->motion_detection_mode) {
17738 		motion_det.vdev_id = event->vdev_id;
17739 		motion_det.enable = 1;
17740 		hdd_debug("Motion Detect CB -> Enable Motion Detection again");
17741 		sme_motion_det_enable(hdd_ctx->mac_handle, &motion_det);
17742 	}
17743 
17744 	return QDF_STATUS_SUCCESS;
17745 }
17746 
17747 /**
17748  * hdd_md_bl_evt_cb - Callback for Motion Detection Baseline Event
17749  * @ctx: HDD context
17750  * @event: motion detect baseline event
17751  *
17752  * Callback for Motion Detection Baseline completion
17753  *
17754  * Return: QDF_STATUS QDF_STATUS_SUCCESS on Success and
17755  * QDF_STATUS_E_FAILURE on failure
17756  */
17757 QDF_STATUS hdd_md_bl_evt_cb(void *ctx, struct sir_md_bl_evt *event)
17758 {
17759 	struct hdd_context *hdd_ctx;
17760 	struct wlan_hdd_link_info *link_info;
17761 
17762 	if (!ctx || !event)
17763 		return QDF_STATUS_E_INVAL;
17764 
17765 	hdd_ctx = (struct hdd_context *)ctx;
17766 	if (wlan_hdd_validate_context(hdd_ctx))
17767 		return QDF_STATUS_E_INVAL;
17768 
17769 	link_info = hdd_get_link_info_by_vdev(hdd_ctx, event->vdev_id);
17770 	if (!link_info ||
17771 	    WLAN_HDD_ADAPTER_MAGIC != link_info->adapter->magic) {
17772 		hdd_err("Invalid adapter or adapter has invalid magic");
17773 		return QDF_STATUS_E_INVAL;
17774 	}
17775 
17776 	hdd_debug("Motion Detection Baseline CB vdev id=%u, baseline val = %d",
17777 		  event->vdev_id, event->bl_baseline_value);
17778 
17779 	link_info->adapter->motion_det_baseline_value =
17780 						event->bl_baseline_value;
17781 
17782 	return QDF_STATUS_SUCCESS;
17783 }
17784 #endif /* WLAN_FEATURE_MOTION_DETECTION */
17785 
17786 static QDF_STATUS hdd_ssr_on_pagefault_cb(struct hdd_context *hdd_ctx)
17787 {
17788 	uint32_t ssr_frequency_on_pagefault;
17789 	qdf_time_t curr_time, ssr_threshold;
17790 
17791 	hdd_enter();
17792 
17793 	if (!hdd_ctx)
17794 		return QDF_STATUS_E_NULL_VALUE;
17795 
17796 	ssr_frequency_on_pagefault =
17797 		ucfg_pmo_get_ssr_frequency_on_pagefault(hdd_ctx->psoc);
17798 
17799 	curr_time = qdf_get_system_uptime();
17800 	ssr_threshold = qdf_system_msecs_to_ticks(ssr_frequency_on_pagefault);
17801 
17802 	if (!hdd_ctx->last_pagefault_ssr_time ||
17803 	    (curr_time - hdd_ctx->last_pagefault_ssr_time) >= ssr_threshold) {
17804 		hdd_info("curr_time %lu last_pagefault_ssr_time %lu ssr_frequency %d",
17805 			 curr_time, hdd_ctx->last_pagefault_ssr_time,
17806 			 ssr_threshold);
17807 		hdd_ctx->last_pagefault_ssr_time = curr_time;
17808 		cds_trigger_recovery(QDF_HOST_WAKEUP_REASON_PAGEFAULT);
17809 
17810 		return QDF_STATUS_SUCCESS;
17811 	}
17812 
17813 	return QDF_STATUS_E_AGAIN;
17814 }
17815 
17816 #define FW_PAGE_FAULT_IDX QCA_NL80211_VENDOR_SUBCMD_FW_PAGE_FAULT_REPORT_INDEX
17817 static QDF_STATUS hdd_send_pagefault_report_to_user(struct hdd_context *hdd_ctx,
17818 						    void *buf, uint32_t buf_len)
17819 {
17820 	struct sk_buff *event_buf;
17821 	int flags = cds_get_gfp_flags();
17822 	uint8_t *ev_data = buf;
17823 	uint16_t event_len = NLMSG_HDRLEN + buf_len;
17824 
17825 	event_buf = wlan_cfg80211_vendor_event_alloc(hdd_ctx->wiphy, NULL,
17826 						     event_len,
17827 						     FW_PAGE_FAULT_IDX, flags);
17828 	if (!event_buf) {
17829 		hdd_err("wlan_cfg80211_vendor_event_alloc failed");
17830 		return QDF_STATUS_E_NOMEM;
17831 	}
17832 
17833 	if (nla_put(event_buf, QCA_WLAN_VENDOR_ATTR_FW_PAGE_FAULT_REPORT_DATA,
17834 		    buf_len, ev_data)) {
17835 		hdd_debug("Failed to fill pagefault blob data");
17836 		wlan_cfg80211_vendor_free_skb(event_buf);
17837 		return QDF_STATUS_E_FAILURE;
17838 	}
17839 
17840 	wlan_cfg80211_vendor_event(event_buf, flags);
17841 	return QDF_STATUS_SUCCESS;
17842 }
17843 
17844 static QDF_STATUS hdd_pagefault_action_cb(void *buf, uint32_t buf_len)
17845 {
17846 	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
17847 
17848 	if (!hdd_ctx)
17849 		return QDF_STATUS_E_NULL_VALUE;
17850 
17851 	if (wlan_pmo_enable_ssr_on_page_fault(hdd_ctx->psoc))
17852 		return hdd_ssr_on_pagefault_cb(hdd_ctx);
17853 
17854 	return hdd_send_pagefault_report_to_user(hdd_ctx, buf, buf_len);
17855 }
17856 
17857 /**
17858  * hdd_register_cb - Register HDD callbacks.
17859  * @hdd_ctx: HDD context
17860  *
17861  * Register the HDD callbacks to CDS/SME.
17862  *
17863  * Return: 0 for success or Error code for failure
17864  */
17865 int hdd_register_cb(struct hdd_context *hdd_ctx)
17866 {
17867 	QDF_STATUS status;
17868 	int ret = 0;
17869 	mac_handle_t mac_handle;
17870 
17871 	hdd_enter();
17872 	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
17873 		hdd_err("in ftm mode, no need to register callbacks");
17874 		return ret;
17875 	}
17876 
17877 	mac_handle = hdd_ctx->mac_handle;
17878 
17879 	sme_register_oem_data_rsp_callback(mac_handle,
17880 					   hdd_send_oem_data_rsp_msg);
17881 
17882 	sme_register_mgmt_frame_ind_callback(mac_handle,
17883 					     hdd_indicate_mgmt_frame);
17884 	sme_set_tsfcb(mac_handle, hdd_get_tsf_cb, hdd_ctx);
17885 	sme_stats_ext_register_callback(mac_handle,
17886 					wlan_hdd_cfg80211_stats_ext_callback);
17887 
17888 	sme_ext_scan_register_callback(mac_handle,
17889 					wlan_hdd_cfg80211_extscan_callback);
17890 	sme_stats_ext2_register_callback(mac_handle,
17891 					wlan_hdd_cfg80211_stats_ext2_callback);
17892 
17893 	sme_multi_client_ll_rsp_register_callback(mac_handle,
17894 					hdd_latency_level_event_handler_cb);
17895 
17896 	sme_set_rssi_threshold_breached_cb(mac_handle,
17897 					   hdd_rssi_threshold_breached);
17898 
17899 	sme_set_link_layer_stats_ind_cb(mac_handle,
17900 				wlan_hdd_cfg80211_link_layer_stats_callback);
17901 
17902 	sme_rso_cmd_status_cb(mac_handle, wlan_hdd_rso_cmd_status_cb);
17903 
17904 	sme_set_link_layer_ext_cb(mac_handle,
17905 			wlan_hdd_cfg80211_link_layer_stats_ext_callback);
17906 	sme_update_hidden_ssid_status_cb(mac_handle,
17907 					 hdd_hidden_ssid_enable_roaming);
17908 
17909 	status = sme_set_lost_link_info_cb(mac_handle,
17910 					   hdd_lost_link_info_cb);
17911 
17912 	wlan_hdd_register_cp_stats_cb(hdd_ctx);
17913 	hdd_dcs_register_cb(hdd_ctx);
17914 
17915 	hdd_thermal_register_callbacks(hdd_ctx);
17916 	/* print error and not block the startup process */
17917 	if (!QDF_IS_STATUS_SUCCESS(status))
17918 		hdd_err("set lost link info callback failed");
17919 
17920 	ret = hdd_register_data_stall_detect_cb();
17921 	if (ret) {
17922 		hdd_err("Register data stall detect detect callback failed.");
17923 		return ret;
17924 	}
17925 
17926 	wlan_hdd_dcc_register_for_dcc_stats_event(hdd_ctx);
17927 
17928 	sme_register_set_connection_info_cb(mac_handle,
17929 					    hdd_set_connection_in_progress,
17930 					    hdd_is_connection_in_progress);
17931 
17932 	status = sme_set_bt_activity_info_cb(mac_handle,
17933 					     hdd_bt_activity_cb);
17934 	if (!QDF_IS_STATUS_SUCCESS(status))
17935 		hdd_err("set bt activity info callback failed");
17936 
17937 	status = sme_register_tx_queue_cb(mac_handle,
17938 					  hdd_tx_queue_cb);
17939 	if (!QDF_IS_STATUS_SUCCESS(status))
17940 		hdd_err("Register tx queue callback failed");
17941 
17942 #ifdef WLAN_FEATURE_MOTION_DETECTION
17943 	sme_set_md_host_evt_cb(mac_handle, hdd_md_host_evt_cb, (void *)hdd_ctx);
17944 	sme_set_md_bl_evt_cb(mac_handle, hdd_md_bl_evt_cb, (void *)hdd_ctx);
17945 #endif /* WLAN_FEATURE_MOTION_DETECTION */
17946 
17947 	mac_register_session_open_close_cb(hdd_ctx->mac_handle,
17948 					   hdd_sme_close_session_callback,
17949 					   hdd_common_roam_callback);
17950 
17951 	sme_set_roam_scan_ch_event_cb(mac_handle, hdd_get_roam_scan_ch_cb);
17952 	status = sme_set_monitor_mode_cb(mac_handle,
17953 					 hdd_sme_monitor_mode_callback);
17954 	if (QDF_IS_STATUS_ERROR(status))
17955 		hdd_err_rl("Register monitor mode callback failed");
17956 
17957 	status = sme_set_beacon_latency_event_cb(mac_handle,
17958 						 hdd_beacon_latency_event_cb);
17959 	if (QDF_IS_STATUS_ERROR(status))
17960 		hdd_err_rl("Register beacon latency event callback failed");
17961 
17962 	sme_async_oem_event_init(mac_handle,
17963 				 hdd_oem_event_async_cb);
17964 
17965 	sme_register_pagefault_cb(mac_handle, hdd_pagefault_action_cb);
17966 
17967 	hdd_exit();
17968 
17969 	return ret;
17970 }
17971 
17972 /**
17973  * hdd_deregister_cb() - De-Register HDD callbacks.
17974  * @hdd_ctx: HDD context
17975  *
17976  * De-Register the HDD callbacks to CDS/SME.
17977  *
17978  * Return: void
17979  */
17980 void hdd_deregister_cb(struct hdd_context *hdd_ctx)
17981 {
17982 	QDF_STATUS status;
17983 	int ret;
17984 	mac_handle_t mac_handle;
17985 
17986 	hdd_enter();
17987 	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
17988 		hdd_err("in ftm mode, no need to deregister callbacks");
17989 		return;
17990 	}
17991 
17992 	mac_handle = hdd_ctx->mac_handle;
17993 
17994 	sme_deregister_ssr_on_pagefault_cb(mac_handle);
17995 
17996 	sme_async_oem_event_deinit(mac_handle);
17997 
17998 	sme_deregister_tx_queue_cb(mac_handle);
17999 
18000 	sme_reset_link_layer_stats_ind_cb(mac_handle);
18001 	sme_reset_rssi_threshold_breached_cb(mac_handle);
18002 
18003 	sme_stats_ext_deregister_callback(mac_handle);
18004 
18005 	status = sme_reset_tsfcb(mac_handle);
18006 	if (!QDF_IS_STATUS_SUCCESS(status))
18007 		hdd_err("Failed to de-register tsfcb the callback:%d",
18008 			status);
18009 
18010 	ret = hdd_deregister_data_stall_detect_cb();
18011 	if (ret)
18012 		hdd_err("Failed to de-register data stall detect event callback");
18013 	hdd_thermal_unregister_callbacks(hdd_ctx);
18014 	sme_deregister_oem_data_rsp_callback(mac_handle);
18015 	sme_multi_client_ll_rsp_deregister_callback(mac_handle);
18016 
18017 	hdd_exit();
18018 }
18019 
18020 /**
18021  * hdd_softap_sta_deauth() - handle deauth req from HDD
18022  * @adapter: Pointer to the HDD adapter
18023  * @param: Params to the operation
18024  *
18025  * This to take counter measure to handle deauth req from HDD
18026  *
18027  * Return: None
18028  */
18029 QDF_STATUS hdd_softap_sta_deauth(struct hdd_adapter *adapter,
18030 				 struct csr_del_sta_params *param)
18031 {
18032 	QDF_STATUS qdf_status = QDF_STATUS_E_FAULT;
18033 	struct hdd_context *hdd_ctx;
18034 	bool is_sap_bcast_deauth_enabled = false;
18035 
18036 	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
18037 	if (!hdd_ctx) {
18038 		hdd_err("hdd_ctx is NULL");
18039 		return QDF_STATUS_E_INVAL;
18040 	}
18041 
18042 	ucfg_mlme_get_sap_bcast_deauth_enabled(hdd_ctx->psoc,
18043 					       &is_sap_bcast_deauth_enabled);
18044 
18045 	hdd_enter();
18046 
18047 	hdd_debug("sap_bcast_deauth_enabled %d", is_sap_bcast_deauth_enabled);
18048 	/* Ignore request to deauth bcmc station */
18049 	if (!is_sap_bcast_deauth_enabled)
18050 		if (param->peerMacAddr.bytes[0] & 0x1)
18051 			return qdf_status;
18052 
18053 	qdf_status =
18054 		wlansap_deauth_sta(WLAN_HDD_GET_SAP_CTX_PTR(adapter->deflink),
18055 				   param);
18056 
18057 	hdd_exit();
18058 	return qdf_status;
18059 }
18060 
18061 /**
18062  * hdd_softap_sta_disassoc() - take counter measure to handle deauth req from HDD
18063  * @adapter: Pointer to the HDD
18064  * @param: pointer to station deletion parameters
18065  *
18066  * This to take counter measure to handle deauth req from HDD
18067  *
18068  * Return: None
18069  */
18070 void hdd_softap_sta_disassoc(struct hdd_adapter *adapter,
18071 			     struct csr_del_sta_params *param)
18072 {
18073 	hdd_enter();
18074 
18075 	/* Ignore request to disassoc bcmc station */
18076 	if (param->peerMacAddr.bytes[0] & 0x1)
18077 		return;
18078 
18079 	wlansap_disassoc_sta(WLAN_HDD_GET_SAP_CTX_PTR(adapter->deflink),
18080 			     param);
18081 }
18082 
18083 void
18084 wlan_hdd_set_roaming_state(struct wlan_hdd_link_info *cur_link_info,
18085 			   enum wlan_cm_rso_control_requestor rso_op_requestor,
18086 			   bool enab_roam)
18087 {
18088 	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(cur_link_info->adapter);
18089 	struct hdd_adapter *adapter = NULL, *next_adapter = NULL;
18090 	wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_DISABLE_ROAMING;
18091 	uint8_t vdev_id, cur_vdev_id = cur_link_info->vdev_id;
18092 	struct wlan_hdd_link_info *link_info;
18093 
18094 	if (!policy_mgr_is_sta_active_connection_exists(hdd_ctx->psoc))
18095 		return;
18096 
18097 	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
18098 					   dbgid) {
18099 		hdd_adapter_for_each_active_link_info(adapter, link_info) {
18100 			vdev_id = link_info->vdev_id;
18101 			if (cur_vdev_id != link_info->vdev_id &&
18102 			    adapter->device_mode == QDF_STA_MODE &&
18103 			    hdd_cm_is_vdev_associated(link_info)) {
18104 				if (enab_roam) {
18105 					hdd_debug("%d Enable roaming", vdev_id);
18106 					sme_start_roaming(hdd_ctx->mac_handle,
18107 							  vdev_id,
18108 							  REASON_DRIVER_ENABLED,
18109 							  rso_op_requestor);
18110 				} else {
18111 					hdd_debug("%d Disable roaming",
18112 						  vdev_id);
18113 					sme_stop_roaming(hdd_ctx->mac_handle,
18114 							 vdev_id,
18115 							 REASON_DRIVER_DISABLED,
18116 							 rso_op_requestor);
18117 				}
18118 			}
18119 		}
18120 		hdd_adapter_dev_put_debug(adapter, dbgid);
18121 	}
18122 }
18123 
18124 /**
18125  * nl_srv_bcast_svc() - Wrapper function to send bcast msgs to SVC mcast group
18126  * @skb: sk buffer pointer
18127  *
18128  * Sends the bcast message to SVC multicast group with generic nl socket
18129  * if CNSS_GENL is enabled. Else, use the legacy netlink socket to send.
18130  *
18131  * Return: None
18132  */
18133 static void nl_srv_bcast_svc(struct sk_buff *skb)
18134 {
18135 #ifdef CNSS_GENL
18136 	nl_srv_bcast(skb, CLD80211_MCGRP_SVC_MSGS, WLAN_NL_MSG_SVC);
18137 #else
18138 	nl_srv_bcast(skb);
18139 #endif
18140 }
18141 
18142 void wlan_hdd_send_svc_nlink_msg(int radio, int type, void *data, int len)
18143 {
18144 	struct sk_buff *skb;
18145 	struct nlmsghdr *nlh;
18146 	tAniMsgHdr *ani_hdr;
18147 	void *nl_data = NULL;
18148 	int flags = GFP_KERNEL;
18149 	struct radio_index_tlv *radio_info;
18150 	int tlv_len;
18151 
18152 	if (in_interrupt() || irqs_disabled() || in_atomic())
18153 		flags = GFP_ATOMIC;
18154 
18155 	skb = alloc_skb(NLMSG_SPACE(WLAN_NL_MAX_PAYLOAD), flags);
18156 
18157 	if (!skb)
18158 		return;
18159 
18160 	nlh = (struct nlmsghdr *)skb->data;
18161 	nlh->nlmsg_pid = 0;     /* from kernel */
18162 	nlh->nlmsg_flags = 0;
18163 	nlh->nlmsg_seq = 0;
18164 	nlh->nlmsg_type = WLAN_NL_MSG_SVC;
18165 
18166 	ani_hdr = NLMSG_DATA(nlh);
18167 	ani_hdr->type = type;
18168 
18169 	switch (type) {
18170 	case WLAN_SVC_FW_CRASHED_IND:
18171 	case WLAN_SVC_FW_SHUTDOWN_IND:
18172 	case WLAN_SVC_LTE_COEX_IND:
18173 	case WLAN_SVC_WLAN_AUTO_SHUTDOWN_IND:
18174 	case WLAN_SVC_WLAN_AUTO_SHUTDOWN_CANCEL_IND:
18175 		ani_hdr->length = 0;
18176 		nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr)));
18177 		break;
18178 	case WLAN_SVC_WLAN_STATUS_IND:
18179 	case WLAN_SVC_WLAN_VERSION_IND:
18180 	case WLAN_SVC_DFS_CAC_START_IND:
18181 	case WLAN_SVC_DFS_CAC_END_IND:
18182 	case WLAN_SVC_DFS_RADAR_DETECT_IND:
18183 	case WLAN_SVC_DFS_ALL_CHANNEL_UNAVAIL_IND:
18184 	case WLAN_SVC_WLAN_TP_IND:
18185 	case WLAN_SVC_WLAN_TP_TX_IND:
18186 	case WLAN_SVC_RPS_ENABLE_IND:
18187 	case WLAN_SVC_CORE_MINFREQ:
18188 		ani_hdr->length = len;
18189 		nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr) + len));
18190 		nl_data = (char *)ani_hdr + sizeof(tAniMsgHdr);
18191 		memcpy(nl_data, data, len);
18192 		break;
18193 
18194 	default:
18195 		hdd_err("WLAN SVC: Attempt to send unknown nlink message %d",
18196 		       type);
18197 		kfree_skb(skb);
18198 		return;
18199 	}
18200 
18201 	/*
18202 	 * Add radio index at the end of the svc event in TLV format
18203 	 * to maintain the backward compatibility with userspace
18204 	 * applications.
18205 	 */
18206 
18207 	tlv_len = 0;
18208 
18209 	if ((sizeof(*ani_hdr) + len + sizeof(struct radio_index_tlv))
18210 		< WLAN_NL_MAX_PAYLOAD) {
18211 		radio_info  = (struct radio_index_tlv *)((char *) ani_hdr +
18212 		sizeof(*ani_hdr) + len);
18213 		radio_info->type = (unsigned short) WLAN_SVC_WLAN_RADIO_INDEX;
18214 		radio_info->length = (unsigned short) sizeof(radio_info->radio);
18215 		radio_info->radio = radio;
18216 		tlv_len = sizeof(*radio_info);
18217 		hdd_debug("Added radio index tlv - radio index %d",
18218 			  radio_info->radio);
18219 	}
18220 
18221 	nlh->nlmsg_len += tlv_len;
18222 	skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr) + len + tlv_len));
18223 
18224 	nl_srv_bcast_svc(skb);
18225 }
18226 
18227 #ifdef FEATURE_WLAN_AUTO_SHUTDOWN
18228 void wlan_hdd_auto_shutdown_cb(void)
18229 {
18230 	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
18231 
18232 	if (!hdd_ctx)
18233 		return;
18234 
18235 	hdd_debug("Wlan Idle. Sending Shutdown event..");
18236 	wlan_hdd_send_svc_nlink_msg(hdd_ctx->radio_index,
18237 			WLAN_SVC_WLAN_AUTO_SHUTDOWN_IND, NULL, 0);
18238 }
18239 
18240 void wlan_hdd_auto_shutdown_enable(struct hdd_context *hdd_ctx, bool enable)
18241 {
18242 	struct hdd_adapter *adapter, *next_adapter = NULL;
18243 	bool ap_connected = false, sta_connected = false;
18244 	mac_handle_t mac_handle;
18245 	struct wlan_hdd_link_info *link_info;
18246 	struct hdd_ap_ctx *ap_ctx;
18247 	wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_AUTO_SHUTDOWN_ENABLE;
18248 
18249 	mac_handle = hdd_ctx->mac_handle;
18250 	if (!mac_handle)
18251 		return;
18252 
18253 	if (hdd_ctx->config->wlan_auto_shutdown == 0)
18254 		return;
18255 
18256 	if (enable == false) {
18257 		if (sme_set_auto_shutdown_timer(mac_handle, 0) !=
18258 							QDF_STATUS_SUCCESS) {
18259 			hdd_err("Failed to stop wlan auto shutdown timer");
18260 		}
18261 		wlan_hdd_send_svc_nlink_msg(hdd_ctx->radio_index,
18262 			WLAN_SVC_WLAN_AUTO_SHUTDOWN_CANCEL_IND, NULL, 0);
18263 		return;
18264 	}
18265 
18266 	/* To enable shutdown timer check conncurrency */
18267 	if (!policy_mgr_concurrent_open_sessions_running(hdd_ctx->psoc))
18268 		goto start_timer;
18269 
18270 	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter,
18271 					   next_adapter, dbgid) {
18272 		hdd_adapter_for_each_active_link_info(adapter, link_info) {
18273 			if (adapter->device_mode == QDF_STA_MODE &&
18274 			    hdd_cm_is_vdev_associated(link_info)) {
18275 				sta_connected = true;
18276 				hdd_adapter_dev_put_debug(adapter, dbgid);
18277 				if (next_adapter)
18278 					hdd_adapter_dev_put_debug(next_adapter,
18279 								  dbgid);
18280 				break;
18281 			}
18282 
18283 			if (adapter->device_mode == QDF_SAP_MODE) {
18284 				ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(link_info);
18285 				if (ap_ctx->ap_active == true) {
18286 					ap_connected = true;
18287 					hdd_adapter_dev_put_debug(adapter,
18288 								  dbgid);
18289 					if (next_adapter)
18290 						hdd_adapter_dev_put_debug(
18291 								next_adapter,
18292 								dbgid);
18293 					break;
18294 				}
18295 			}
18296 		}
18297 		hdd_adapter_dev_put_debug(adapter, dbgid);
18298 	}
18299 
18300 start_timer:
18301 	if (ap_connected == true || sta_connected == true) {
18302 		hdd_debug("CC Session active. Shutdown timer not enabled");
18303 		return;
18304 	}
18305 
18306 	if (sme_set_auto_shutdown_timer(mac_handle,
18307 					hdd_ctx->config->wlan_auto_shutdown)
18308 	    != QDF_STATUS_SUCCESS)
18309 		hdd_err("Failed to start wlan auto shutdown timer");
18310 	else
18311 		hdd_info("Auto Shutdown timer for %d seconds enabled",
18312 			 hdd_ctx->config->wlan_auto_shutdown);
18313 }
18314 #endif
18315 
18316 struct hdd_adapter *
18317 hdd_get_con_sap_adapter(struct hdd_adapter *this_sap_adapter,
18318 			bool check_start_bss)
18319 {
18320 	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(this_sap_adapter);
18321 	struct hdd_adapter *adapter, *next_adapter = NULL;
18322 	wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_GET_CON_SAP_ADAPTER;
18323 	struct wlan_hdd_link_info *link_info;
18324 
18325 	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
18326 					   dbgid) {
18327 		if ((adapter->device_mode == QDF_SAP_MODE ||
18328 		     adapter->device_mode == QDF_P2P_GO_MODE) &&
18329 		    adapter != this_sap_adapter) {
18330 			hdd_adapter_for_each_active_link_info(adapter,
18331 							      link_info) {
18332 				if (!check_start_bss) {
18333 					hdd_adapter_dev_put_debug(adapter,
18334 								  dbgid);
18335 					if (next_adapter)
18336 						hdd_adapter_dev_put_debug(
18337 								next_adapter,
18338 								dbgid);
18339 					return adapter;
18340 				}
18341 				if (test_bit(SOFTAP_BSS_STARTED,
18342 					     &link_info->link_flags)) {
18343 					hdd_adapter_dev_put_debug(adapter,
18344 								  dbgid);
18345 					if (next_adapter)
18346 						hdd_adapter_dev_put_debug(
18347 								next_adapter,
18348 								dbgid);
18349 					return adapter;
18350 				}
18351 			}
18352 		}
18353 		hdd_adapter_dev_put_debug(adapter, dbgid);
18354 	}
18355 
18356 	return NULL;
18357 }
18358 
18359 static inline bool hdd_adapter_is_sta(struct hdd_adapter *adapter)
18360 {
18361 	return adapter->device_mode == QDF_STA_MODE ||
18362 		adapter->device_mode == QDF_P2P_CLIENT_MODE;
18363 }
18364 
18365 bool hdd_is_any_adapter_connected(struct hdd_context *hdd_ctx)
18366 {
18367 	struct hdd_adapter *adapter, *next_adapter = NULL;
18368 	wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_IS_ANY_ADAPTER_CONNECTED;
18369 	struct wlan_hdd_link_info *link_info;
18370 
18371 	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
18372 					   dbgid) {
18373 		hdd_adapter_for_each_active_link_info(adapter, link_info) {
18374 			if (hdd_adapter_is_sta(adapter) &&
18375 			    hdd_cm_is_vdev_associated(link_info)) {
18376 				hdd_adapter_dev_put_debug(adapter, dbgid);
18377 				if (next_adapter)
18378 					hdd_adapter_dev_put_debug(next_adapter,
18379 								  dbgid);
18380 				return true;
18381 			}
18382 
18383 			if (hdd_adapter_is_ap(adapter) &&
18384 			    WLAN_HDD_GET_AP_CTX_PTR(link_info)->ap_active) {
18385 				hdd_adapter_dev_put_debug(adapter, dbgid);
18386 				if (next_adapter)
18387 					hdd_adapter_dev_put_debug(next_adapter,
18388 								  dbgid);
18389 				return true;
18390 			}
18391 
18392 			if (adapter->device_mode == QDF_NDI_MODE &&
18393 			    hdd_cm_is_vdev_associated(link_info)) {
18394 				hdd_adapter_dev_put_debug(adapter, dbgid);
18395 				if (next_adapter)
18396 					hdd_adapter_dev_put_debug(next_adapter,
18397 								  dbgid);
18398 				return true;
18399 			}
18400 		}
18401 		hdd_adapter_dev_put_debug(adapter, dbgid);
18402 	}
18403 
18404 	return false;
18405 }
18406 
18407 #if defined MSM_PLATFORM && (LINUX_VERSION_CODE <= KERNEL_VERSION(4, 19, 0))
18408 /**
18409  * hdd_inform_stop_sap() - call cfg80211 API to stop SAP
18410  * @adapter: pointer to adapter
18411  *
18412  * This function calls cfg80211 API to stop SAP
18413  *
18414  * Return: None
18415  */
18416 static void hdd_inform_stop_sap(struct hdd_adapter *adapter)
18417 {
18418 	hdd_debug("SAP stopped due to invalid channel vdev id %d",
18419 		  wlan_vdev_get_id(adapter->deflink->vdev));
18420 	cfg80211_ap_stopped(adapter->dev, GFP_KERNEL);
18421 }
18422 
18423 #else
18424 static void hdd_inform_stop_sap(struct hdd_adapter *adapter)
18425 {
18426 	hdd_debug("SAP stopped due to invalid channel vdev id %d",
18427 		  wlan_vdev_get_id(adapter->deflink->vdev));
18428 	cfg80211_stop_iface(adapter->hdd_ctx->wiphy, &adapter->wdev,
18429 			    GFP_KERNEL);
18430 }
18431 #endif
18432 
18433 /**
18434  * wlan_hdd_stop_sap() - This function stops bss of SAP.
18435  * @ap_adapter: SAP adapter
18436  *
18437  * This function will process the stopping of sap adapter.
18438  *
18439  * Return: None
18440  */
18441 void wlan_hdd_stop_sap(struct hdd_adapter *ap_adapter)
18442 {
18443 	struct hdd_ap_ctx *hdd_ap_ctx;
18444 	struct hdd_hostapd_state *hostapd_state;
18445 	QDF_STATUS qdf_status;
18446 	struct hdd_context *hdd_ctx;
18447 
18448 	if (!ap_adapter) {
18449 		hdd_err("ap_adapter is NULL here");
18450 		return;
18451 	}
18452 
18453 	hdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(ap_adapter->deflink);
18454 	hdd_ctx = WLAN_HDD_GET_CTX(ap_adapter);
18455 	if (wlan_hdd_validate_context(hdd_ctx))
18456 		return;
18457 
18458 	mutex_lock(&hdd_ctx->sap_lock);
18459 	if (test_bit(SOFTAP_BSS_STARTED, &ap_adapter->deflink->link_flags)) {
18460 		wlan_hdd_del_station(ap_adapter, NULL);
18461 		hostapd_state =
18462 			WLAN_HDD_GET_HOSTAP_STATE_PTR(ap_adapter->deflink);
18463 		hdd_debug("Now doing SAP STOPBSS");
18464 		qdf_event_reset(&hostapd_state->qdf_stop_bss_event);
18465 		if (QDF_STATUS_SUCCESS == wlansap_stop_bss(hdd_ap_ctx->
18466 							sap_context)) {
18467 			qdf_status = qdf_wait_single_event(&hostapd_state->
18468 					qdf_stop_bss_event,
18469 					SME_CMD_STOP_BSS_TIMEOUT);
18470 			if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
18471 				mutex_unlock(&hdd_ctx->sap_lock);
18472 				hdd_err("SAP Stop Failed");
18473 				return;
18474 			}
18475 		}
18476 		clear_bit(SOFTAP_BSS_STARTED, &ap_adapter->deflink->link_flags);
18477 		policy_mgr_decr_session_set_pcl(hdd_ctx->psoc,
18478 						ap_adapter->device_mode,
18479 						ap_adapter->deflink->vdev_id);
18480 		hdd_green_ap_start_state_mc(hdd_ctx, ap_adapter->device_mode,
18481 					    false);
18482 		hdd_inform_stop_sap(ap_adapter);
18483 		hdd_debug("SAP Stop Success");
18484 	} else {
18485 		hdd_err("Can't stop ap because its not started");
18486 	}
18487 	mutex_unlock(&hdd_ctx->sap_lock);
18488 }
18489 
18490 #if defined(WLAN_FEATURE_11BE_MLO) && defined(CFG80211_11BE_BASIC)
18491 /**
18492  * wlan_hdd_mlo_sap_reinit() - handle mlo scenario for ssr
18493  * @link_info: Pointer of link_info in adapter
18494  *
18495  * Return: QDF_STATUS
18496  */
18497 static QDF_STATUS wlan_hdd_mlo_sap_reinit(struct wlan_hdd_link_info *link_info)
18498 {
18499 	struct hdd_context *hdd_ctx = link_info->adapter->hdd_ctx;
18500 	struct sap_config *config = &link_info->session.ap.sap_config;
18501 
18502 	if (config->mlo_sap) {
18503 		if (!mlo_ap_vdev_attach(link_info->vdev, config->link_id,
18504 					config->num_link)) {
18505 			hdd_err("SAP mlo mgr attach fail");
18506 			return QDF_STATUS_E_INVAL;
18507 		}
18508 	}
18509 
18510 	if (!policy_mgr_is_mlo_sap_concurrency_allowed(hdd_ctx->psoc,
18511 						       config->mlo_sap,
18512 						       wlan_vdev_get_id(link_info->vdev))) {
18513 		hdd_err("MLO SAP concurrency check fails");
18514 		return QDF_STATUS_E_INVAL;
18515 	}
18516 
18517 	return QDF_STATUS_SUCCESS;
18518 }
18519 #else
18520 static inline QDF_STATUS
18521 wlan_hdd_mlo_sap_reinit(struct wlan_hdd_link_info *link_info)
18522 {
18523 	return QDF_STATUS_SUCCESS;
18524 }
18525 #endif
18526 
18527 void wlan_hdd_set_sap_beacon_protection(struct hdd_context *hdd_ctx,
18528 					struct wlan_hdd_link_info *link_info,
18529 					struct hdd_beacon_data *beacon)
18530 {
18531 	const uint8_t *ie = NULL;
18532 	struct s_ext_cap *p_ext_cap;
18533 	struct wlan_objmgr_vdev *vdev;
18534 	bool target_bigtk_support = false;
18535 	uint8_t vdev_id;
18536 	uint8_t ie_len;
18537 
18538 	if (!beacon) {
18539 		hdd_err("beacon is null");
18540 		return;
18541 	}
18542 
18543 	ie = wlan_get_ie_ptr_from_eid(DOT11F_EID_EXTCAP, beacon->tail,
18544 				      beacon->tail_len);
18545 	if (!ie) {
18546 		hdd_err("IE is null");
18547 		return;
18548 	}
18549 
18550 	if (ie[1] > DOT11F_IE_EXTCAP_MAX_LEN ||
18551 	    ie[1] < DOT11F_IE_EXTCAP_MIN_LEN) {
18552 		hdd_err("Invalid IEs eid: %d elem_len: %d", ie[0], ie[1]);
18553 		return;
18554 	}
18555 
18556 	p_ext_cap = qdf_mem_malloc(sizeof(*p_ext_cap));
18557 	if (!p_ext_cap)
18558 		return;
18559 
18560 	ie_len = (ie[1] > sizeof(*p_ext_cap)) ? sizeof(*p_ext_cap) : ie[1];
18561 
18562 	qdf_mem_copy(p_ext_cap, &ie[2], ie_len);
18563 
18564 	vdev = hdd_objmgr_get_vdev_by_user(link_info, WLAN_HDD_ID_OBJ_MGR);
18565 	if (!vdev) {
18566 		hdd_err("vdev is null");
18567 		goto end;
18568 	}
18569 
18570 	vdev_id = wlan_vdev_get_id(vdev);
18571 
18572 	hdd_debug("vdev %d beacon protection %d", vdev_id,
18573 		  p_ext_cap->beacon_protection_enable);
18574 
18575 	ucfg_mlme_get_bigtk_support(hdd_ctx->psoc, &target_bigtk_support);
18576 
18577 	if (target_bigtk_support && p_ext_cap->beacon_protection_enable)
18578 		mlme_set_bigtk_support(vdev, true);
18579 
18580 	hdd_objmgr_put_vdev_by_user(vdev, WLAN_HDD_ID_OBJ_MGR);
18581 
18582 end:
18583 	qdf_mem_free(p_ext_cap);
18584 }
18585 
18586 void wlan_hdd_start_sap(struct wlan_hdd_link_info *link_info, bool reinit)
18587 {
18588 	struct hdd_ap_ctx *ap_ctx;
18589 	struct hdd_hostapd_state *hostapd_state;
18590 	QDF_STATUS qdf_status;
18591 	struct hdd_context *hdd_ctx;
18592 	struct sap_config *sap_config;
18593 	struct hdd_adapter *ap_adapter = link_info->adapter;
18594 
18595 	if (QDF_SAP_MODE != ap_adapter->device_mode) {
18596 		hdd_err("SoftAp role has not been enabled");
18597 		return;
18598 	}
18599 
18600 	hdd_ctx = WLAN_HDD_GET_CTX(ap_adapter);
18601 	ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(link_info);
18602 	hostapd_state = WLAN_HDD_GET_HOSTAP_STATE_PTR(link_info);
18603 	sap_config = &ap_ctx->sap_config;
18604 
18605 	mutex_lock(&hdd_ctx->sap_lock);
18606 	if (test_bit(SOFTAP_BSS_STARTED, &link_info->link_flags))
18607 		goto end;
18608 
18609 	if (wlan_hdd_cfg80211_update_apies(link_info)) {
18610 		hdd_err("SAP Not able to set AP IEs");
18611 		goto end;
18612 	}
18613 	wlan_reg_set_channel_params_for_pwrmode(hdd_ctx->pdev,
18614 						sap_config->chan_freq, 0,
18615 						&sap_config->ch_params,
18616 						REG_CURRENT_PWR_MODE);
18617 	qdf_status = wlan_hdd_mlo_sap_reinit(link_info);
18618 	if (QDF_IS_STATUS_ERROR(qdf_status)) {
18619 		hdd_err("SAP Not able to do mlo attach");
18620 		goto end;
18621 	}
18622 
18623 	qdf_event_reset(&hostapd_state->qdf_event);
18624 	qdf_status = wlansap_start_bss(ap_ctx->sap_context,
18625 				       hdd_hostapd_sap_event_cb, sap_config,
18626 				       ap_adapter->dev);
18627 	if (QDF_IS_STATUS_ERROR(qdf_status))
18628 		goto end;
18629 
18630 	wlan_hdd_set_sap_beacon_protection(hdd_ctx, link_info, ap_ctx->beacon);
18631 
18632 	hdd_debug("Waiting for SAP to start");
18633 	qdf_status = qdf_wait_single_event(&hostapd_state->qdf_event,
18634 					SME_CMD_START_BSS_TIMEOUT);
18635 	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
18636 		hdd_err("SAP Start failed");
18637 		goto end;
18638 	}
18639 	hdd_info("SAP Start Success");
18640 
18641 	wlansap_reset_sap_config_add_ie(sap_config, eUPDATE_IE_ALL);
18642 	set_bit(SOFTAP_BSS_STARTED, &link_info->link_flags);
18643 	if (hostapd_state->bss_state == BSS_START) {
18644 		policy_mgr_incr_active_session(hdd_ctx->psoc,
18645 					ap_adapter->device_mode,
18646 					link_info->vdev_id);
18647 		hdd_green_ap_start_state_mc(hdd_ctx, ap_adapter->device_mode,
18648 					    true);
18649 	}
18650 	mutex_unlock(&hdd_ctx->sap_lock);
18651 
18652 	return;
18653 end:
18654 	wlan_hdd_mlo_reset(link_info);
18655 	wlansap_reset_sap_config_add_ie(sap_config, eUPDATE_IE_ALL);
18656 	mutex_unlock(&hdd_ctx->sap_lock);
18657 	/* SAP context and beacon cleanup will happen during driver unload
18658 	 * in hdd_stop_adapter
18659 	 */
18660 	hdd_err("SAP restart after SSR failed! Reload WLAN and try SAP again");
18661 	/* Free the beacon memory in case of failure in the sap restart */
18662 	qdf_mem_free(ap_ctx->beacon);
18663 	ap_ctx->beacon = NULL;
18664 }
18665 
18666 #ifdef QCA_CONFIG_SMP
18667 /**
18668  * wlan_hdd_get_cpu() - get cpu_index
18669  *
18670  * Return: cpu_index
18671  */
18672 int wlan_hdd_get_cpu(void)
18673 {
18674 	int cpu_index = get_cpu();
18675 
18676 	put_cpu();
18677 	return cpu_index;
18678 }
18679 #endif
18680 
18681 /**
18682  * hdd_get_fwpath() - get framework path
18683  *
18684  * This function is used to get the string written by
18685  * userspace to start the wlan driver
18686  *
18687  * Return: string
18688  */
18689 const char *hdd_get_fwpath(void)
18690 {
18691 	return fwpath.string;
18692 }
18693 
18694 static inline int hdd_state_query_cb(void)
18695 {
18696 	return !!wlan_hdd_validate_context(cds_get_context(QDF_MODULE_ID_HDD));
18697 }
18698 
18699 static int __hdd_op_protect_cb(void **out_sync, const char *func)
18700 {
18701 	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
18702 
18703 	if (!hdd_ctx)
18704 		return -EAGAIN;
18705 
18706 	return __osif_psoc_sync_op_start(hdd_ctx->parent_dev,
18707 					 (struct osif_psoc_sync **)out_sync,
18708 					 func);
18709 }
18710 
18711 static void __hdd_op_unprotect_cb(void *sync, const char *func)
18712 {
18713 	__osif_psoc_sync_op_stop(sync, func);
18714 }
18715 
18716 #ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
18717 /**
18718  * hdd_logging_sock_init_svc() - Initialize logging sock
18719  *
18720  * Return: 0 for success, errno on failure
18721  */
18722 static int
18723 hdd_logging_sock_init_svc(void)
18724 {
18725 	return wlan_logging_sock_init_svc();
18726 }
18727 #else
18728 static inline int
18729 hdd_logging_sock_init_svc(void)
18730 {
18731 	return 0;
18732 }
18733 #endif
18734 
18735 /**
18736  * hdd_init() - Initialize Driver
18737  *
18738  * This function initializes CDS global context with the help of cds_init. This
18739  * has to be the first function called after probe to get a valid global
18740  * context.
18741  *
18742  * Return: 0 for success, errno on failure
18743  */
18744 int hdd_init(void)
18745 {
18746 	QDF_STATUS status;
18747 
18748 	status = cds_init();
18749 	if (QDF_IS_STATUS_ERROR(status)) {
18750 		hdd_err("Failed to allocate CDS context");
18751 		return -ENOMEM;
18752 	}
18753 
18754 	qdf_op_callbacks_register(__hdd_op_protect_cb, __hdd_op_unprotect_cb);
18755 
18756 	wlan_init_bug_report_lock();
18757 
18758 	if (hdd_logging_sock_init_svc()) {
18759 		hdd_err("logging sock init failed.");
18760 		goto err;
18761 	}
18762 
18763 	hdd_trace_init();
18764 	hdd_register_debug_callback();
18765 	wlan_roam_debug_init();
18766 
18767 	return 0;
18768 
18769 err:
18770 	wlan_destroy_bug_report_lock();
18771 	qdf_op_callbacks_register(NULL, NULL);
18772 	cds_deinit();
18773 	return -ENOMEM;
18774 }
18775 
18776 /**
18777  * hdd_deinit() - Deinitialize Driver
18778  *
18779  * This function frees CDS global context with the help of cds_deinit. This
18780  * has to be the last function call in remove callback to free the global
18781  * context.
18782  */
18783 void hdd_deinit(void)
18784 {
18785 	wlan_roam_debug_deinit();
18786 
18787 #ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
18788 	wlan_logging_sock_deinit_svc();
18789 #endif
18790 
18791 	wlan_destroy_bug_report_lock();
18792 	qdf_op_callbacks_register(NULL, NULL);
18793 	cds_deinit();
18794 }
18795 
18796 #ifdef QCA_WIFI_EMULATION
18797 #define HDD_WLAN_START_WAIT_TIME ((CDS_WMA_TIMEOUT + 5000) * 100)
18798 #else
18799 #define HDD_WLAN_START_WAIT_TIME (CDS_WMA_TIMEOUT + 5000)
18800 #endif
18801 
18802 void hdd_init_start_completion(void)
18803 {
18804 	INIT_COMPLETION(wlan_start_comp);
18805 }
18806 
18807 #ifdef WLAN_CTRL_NAME
18808 static unsigned int dev_num = 1;
18809 static struct cdev wlan_hdd_state_cdev;
18810 static struct class *class;
18811 static dev_t device;
18812 
18813 static void hdd_set_adapter_wlm_def_level(struct hdd_context *hdd_ctx)
18814 {
18815 	struct hdd_adapter *adapter, *next_adapter = NULL;
18816 	wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_GET_ADAPTER;
18817 	int ret;
18818 	QDF_STATUS qdf_status;
18819 	uint8_t latency_level;
18820 	bool reset;
18821 
18822 	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam())
18823 		return;
18824 
18825 	ret = wlan_hdd_validate_context(hdd_ctx);
18826 	if (ret != 0)
18827 		return;
18828 
18829 	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
18830 					   dbgid) {
18831 		qdf_status = ucfg_mlme_cfg_get_wlm_level(hdd_ctx->psoc,
18832 							 &latency_level);
18833 		if (QDF_IS_STATUS_ERROR(qdf_status))
18834 			adapter->latency_level =
18835 			       QCA_WLAN_VENDOR_ATTR_CONFIG_LATENCY_LEVEL_NORMAL;
18836 		else
18837 			adapter->latency_level = latency_level;
18838 		qdf_status = ucfg_mlme_cfg_get_wlm_reset(hdd_ctx->psoc, &reset);
18839 		if (QDF_IS_STATUS_ERROR(qdf_status)) {
18840 			hdd_err("could not get the wlm reset flag");
18841 			reset = false;
18842 		}
18843 
18844 		if (hdd_get_multi_client_ll_support(adapter) && !reset)
18845 			wlan_hdd_deinit_multi_client_info_table(adapter);
18846 
18847 		adapter->upgrade_udp_qos_threshold = QCA_WLAN_AC_BK;
18848 		hdd_debug("UDP packets qos reset to: %d",
18849 			  adapter->upgrade_udp_qos_threshold);
18850 		hdd_adapter_dev_put_debug(adapter, dbgid);
18851 	}
18852 }
18853 
18854 static int wlan_hdd_state_ctrl_param_open(struct inode *inode,
18855 					  struct file *file)
18856 {
18857 	qdf_atomic_inc(&wlan_hdd_state_fops_ref);
18858 
18859 	return 0;
18860 }
18861 
18862 static void __hdd_inform_wifi_off(void)
18863 {
18864 	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
18865 	int ret;
18866 
18867 	ret = wlan_hdd_validate_context(hdd_ctx);
18868 	if (ret != 0)
18869 		return;
18870 
18871 	ucfg_dlm_wifi_off(hdd_ctx->pdev);
18872 
18873 	if (rtnl_trylock()) {
18874 		wlan_hdd_lpc_del_monitor_interface(hdd_ctx, false);
18875 		rtnl_unlock();
18876 	}
18877 }
18878 
18879 static void hdd_inform_wifi_off(void)
18880 {
18881 	int ret;
18882 	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
18883 	struct osif_psoc_sync *psoc_sync;
18884 
18885 	if (!hdd_ctx)
18886 		return;
18887 
18888 	ret = osif_psoc_sync_op_start(wiphy_dev(hdd_ctx->wiphy), &psoc_sync);
18889 	if (ret)
18890 		return;
18891 
18892 	hdd_set_adapter_wlm_def_level(hdd_ctx);
18893 	__hdd_inform_wifi_off();
18894 
18895 	osif_psoc_sync_op_stop(psoc_sync);
18896 }
18897 
18898 #if defined CFG80211_USER_HINT_CELL_BASE_SELF_MANAGED || \
18899 	(LINUX_VERSION_CODE >= KERNEL_VERSION(4, 18, 0))
18900 static void hdd_inform_wifi_on(void)
18901 {
18902 	int ret;
18903 	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
18904 	struct osif_psoc_sync *psoc_sync;
18905 
18906 	hdd_nofl_debug("inform regdomain for wifi on");
18907 	ret = wlan_hdd_validate_context(hdd_ctx);
18908 	if (ret)
18909 		return;
18910 	if (!wlan_hdd_validate_modules_state(hdd_ctx))
18911 		return;
18912 	if (!hdd_ctx->wiphy)
18913 		return;
18914 	ret = osif_psoc_sync_op_start(wiphy_dev(hdd_ctx->wiphy), &psoc_sync);
18915 	if (ret)
18916 		return;
18917 	if (hdd_ctx->wiphy->registered)
18918 		hdd_send_wiphy_regd_sync_event(hdd_ctx);
18919 
18920 	osif_psoc_sync_op_stop(psoc_sync);
18921 }
18922 #else
18923 static void hdd_inform_wifi_on(void)
18924 {
18925 }
18926 #endif
18927 
18928 static int hdd_validate_wlan_string(const char __user *user_buf)
18929 {
18930 	char buf[15];
18931 	int i;
18932 	static const char * const wlan_str[] = {
18933 		[WLAN_OFF_STR] = "OFF",
18934 		[WLAN_ON_STR] = "ON",
18935 		[WLAN_ENABLE_STR] = "ENABLE",
18936 		[WLAN_DISABLE_STR] = "DISABLE",
18937 		[WLAN_WAIT_FOR_READY_STR] = "WAIT_FOR_READY",
18938 		[WLAN_FORCE_DISABLE_STR] = "FORCE_DISABLE"
18939 	};
18940 
18941 	if (copy_from_user(buf, user_buf, sizeof(buf))) {
18942 		pr_err("Failed to read buffer\n");
18943 		return -EINVAL;
18944 	}
18945 
18946 	for (i = 0; i < ARRAY_SIZE(wlan_str); i++) {
18947 		if (qdf_str_ncmp(buf, wlan_str[i], strlen(wlan_str[i])) == 0)
18948 			return i;
18949 	}
18950 
18951 	return -EINVAL;
18952 }
18953 
18954 #ifdef FEATURE_CNSS_HW_SECURE_DISABLE
18955 #define WIFI_DISABLE_SLEEP (10)
18956 #define WIFI_DISABLE_MAX_RETRY_ATTEMPTS (10)
18957 static bool g_soft_unload;
18958 
18959 bool hdd_get_wlan_driver_status(void)
18960 {
18961 	return g_soft_unload;
18962 }
18963 
18964 static int hdd_wlan_soft_driver_load(void)
18965 {
18966 	if (!cds_is_driver_loaded()) {
18967 		hdd_debug("\nEnabling CNSS WLAN HW");
18968 		pld_wlan_hw_enable();
18969 		return 0;
18970 	}
18971 
18972 	if (!g_soft_unload) {
18973 		hdd_debug_rl("Enabling WiFi\n");
18974 		return -EINVAL;
18975 	}
18976 
18977 	hdd_driver_load();
18978 	g_soft_unload = false;
18979 	return 0;
18980 }
18981 
18982 static void hdd_wlan_soft_driver_unload(void)
18983 {
18984 	if (g_soft_unload) {
18985 		hdd_debug_rl("WiFi is already disabled");
18986 		return;
18987 	}
18988 	hdd_debug("Initiating soft driver unload\n");
18989 	g_soft_unload = true;
18990 	hdd_driver_unload();
18991 }
18992 
18993 static int hdd_wlan_idle_shutdown(struct hdd_context *hdd_ctx)
18994 {
18995 	int ret;
18996 	int retries = 0;
18997 	void *hif_ctx;
18998 
18999 	if (!hdd_ctx) {
19000 		hdd_err_rl("hdd_ctx is Null");
19001 		return -EINVAL;
19002 	}
19003 
19004 	hif_ctx = cds_get_context(QDF_MODULE_ID_HIF);
19005 
19006 	hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_IDLE_SHUTDOWN);
19007 
19008 	while (retries < WIFI_DISABLE_MAX_RETRY_ATTEMPTS) {
19009 		if (hif_ctx) {
19010 			/*
19011 			 * Trigger runtime sync resume before psoc_idle_shutdown
19012 			 * such that resume can happen successfully
19013 			 */
19014 			qdf_rtpm_sync_resume();
19015 		}
19016 		ret = pld_idle_shutdown(hdd_ctx->parent_dev,
19017 					hdd_psoc_idle_shutdown);
19018 
19019 		if (-EAGAIN == ret || hdd_ctx->is_wiphy_suspended) {
19020 			hdd_debug("System suspend in progress.Retries done:%d",
19021 				  retries);
19022 			msleep(WIFI_DISABLE_SLEEP);
19023 			retries++;
19024 			continue;
19025 		}
19026 		break;
19027 	}
19028 	hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_IDLE_SHUTDOWN);
19029 
19030 	if (retries > WIFI_DISABLE_MAX_RETRY_ATTEMPTS) {
19031 		hdd_debug("Max retries reached");
19032 		return -EINVAL;
19033 	}
19034 	hdd_debug_rl("WiFi is disabled");
19035 
19036 	return 0;
19037 }
19038 
19039 static int hdd_disable_wifi(struct hdd_context *hdd_ctx)
19040 {
19041 	int ret;
19042 
19043 	if (hdd_ctx->is_wlan_disabled) {
19044 		hdd_err_rl("Wifi is already disabled");
19045 		return 0;
19046 	}
19047 
19048 	hdd_debug("Initiating WLAN idle shutdown");
19049 	if (hdd_is_any_interface_open(hdd_ctx)) {
19050 		hdd_err("Interfaces still open, cannot process wifi disable");
19051 		return -EAGAIN;
19052 	}
19053 
19054 	hdd_ctx->is_wlan_disabled = true;
19055 
19056 	ret = hdd_wlan_idle_shutdown(hdd_ctx);
19057 	if (ret)
19058 		hdd_ctx->is_wlan_disabled = false;
19059 
19060 	return ret;
19061 }
19062 #else
19063 static int hdd_wlan_soft_driver_load(void)
19064 {
19065 	return -EINVAL;
19066 }
19067 
19068 static void hdd_wlan_soft_driver_unload(void)
19069 {
19070 }
19071 
19072 static int hdd_disable_wifi(struct hdd_context *hdd_ctx)
19073 {
19074 	return 0;
19075 }
19076 #endif /* FEATURE_CNSS_HW_SECURE_DISABLE */
19077 
19078 static ssize_t wlan_hdd_state_ctrl_param_write(struct file *filp,
19079 						const char __user *user_buf,
19080 						size_t count,
19081 						loff_t *f_pos)
19082 {
19083 	int id, ret;
19084 	unsigned long rc;
19085 	struct hdd_context *hdd_ctx;
19086 	bool is_wait_for_ready = false;
19087 	bool is_wlan_force_disabled;
19088 
19089 	hdd_enter();
19090 
19091 	id = hdd_validate_wlan_string(user_buf);
19092 
19093 	switch (id) {
19094 	case WLAN_OFF_STR:
19095 		hdd_info("Wifi turning off from UI\n");
19096 		hdd_inform_wifi_off();
19097 		goto exit;
19098 	case WLAN_ON_STR:
19099 		hdd_info("Wifi Turning On from UI\n");
19100 		break;
19101 	case WLAN_WAIT_FOR_READY_STR:
19102 		is_wait_for_ready = true;
19103 		hdd_info("Wifi wait for ready from UI\n");
19104 		break;
19105 	case WLAN_ENABLE_STR:
19106 		hdd_nofl_debug("Received WiFi enable from framework\n");
19107 		if (!hdd_wlan_soft_driver_load())
19108 			goto exit;
19109 		pr_info("Enabling WiFi\n");
19110 		break;
19111 	case WLAN_DISABLE_STR:
19112 		hdd_nofl_debug("Received WiFi disable from framework\n");
19113 		if (!cds_is_driver_loaded())
19114 			goto exit;
19115 
19116 		is_wlan_force_disabled = hdd_get_wlan_driver_status();
19117 		if (is_wlan_force_disabled)
19118 			goto exit;
19119 		pr_info("Disabling WiFi\n");
19120 		break;
19121 	case WLAN_FORCE_DISABLE_STR:
19122 		hdd_nofl_debug("Received Force WiFi disable from framework\n");
19123 		if (!cds_is_driver_loaded())
19124 			goto exit;
19125 
19126 		hdd_wlan_soft_driver_unload();
19127 		goto exit;
19128 	default:
19129 		hdd_err_rl("Invalid value received from framework");
19130 		return -EINVAL;
19131 	}
19132 
19133 	hdd_info("is_driver_loaded %d is_driver_recovering %d",
19134 		 cds_is_driver_loaded(), cds_is_driver_recovering());
19135 
19136 	if (!cds_is_driver_loaded() || cds_is_driver_recovering()) {
19137 		rc = wait_for_completion_timeout(&wlan_start_comp,
19138 				msecs_to_jiffies(HDD_WLAN_START_WAIT_TIME));
19139 		if (!rc) {
19140 			hdd_err("Driver Loading Timed-out!!");
19141 			ret = -EINVAL;
19142 			return ret;
19143 		}
19144 	}
19145 
19146 	if (is_wait_for_ready)
19147 		return count;
19148 	/*
19149 	 * Flush idle shutdown work for cases to synchronize the wifi on
19150 	 * during the idle shutdown.
19151 	 */
19152 	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
19153 	if (hdd_ctx)
19154 		hdd_psoc_idle_timer_stop(hdd_ctx);
19155 
19156 	if (id == WLAN_DISABLE_STR) {
19157 		if (!hdd_ctx) {
19158 			hdd_err_rl("hdd_ctx is Null");
19159 			goto exit;
19160 		}
19161 
19162 		ret = hdd_disable_wifi(hdd_ctx);
19163 		if (ret)
19164 			return ret;
19165 	}
19166 
19167 	if (id == WLAN_ENABLE_STR) {
19168 		if (!hdd_ctx) {
19169 			hdd_err_rl("hdd_ctx is Null");
19170 			goto exit;
19171 		}
19172 
19173 		if (!hdd_ctx->is_wlan_disabled) {
19174 			hdd_err_rl("WiFi is already enabled");
19175 			goto exit;
19176 		}
19177 		hdd_ctx->is_wlan_disabled = false;
19178 	}
19179 
19180 	if (id == WLAN_ON_STR)
19181 		hdd_inform_wifi_on();
19182 exit:
19183 	hdd_exit();
19184 	return count;
19185 }
19186 
19187 /**
19188  * wlan_hdd_state_ctrl_param_release() -  Release callback for /dev/wlan.
19189  *
19190  * @inode: struct inode pointer.
19191  * @file: struct file pointer.
19192  *
19193  * Release callback that would be invoked when the file operations has
19194  * completed fully. This is implemented to provide a reference count mechanism
19195  * via which the driver can wait till all possible usage of the /dev/wlan
19196  * file is completed.
19197  *
19198  * Return: Success
19199  */
19200 static int wlan_hdd_state_ctrl_param_release(struct inode *inode,
19201 					     struct file *file)
19202 {
19203 	qdf_atomic_dec(&wlan_hdd_state_fops_ref);
19204 
19205 	return 0;
19206 }
19207 
19208 const struct file_operations wlan_hdd_state_fops = {
19209 	.owner = THIS_MODULE,
19210 	.open = wlan_hdd_state_ctrl_param_open,
19211 	.write = wlan_hdd_state_ctrl_param_write,
19212 	.release = wlan_hdd_state_ctrl_param_release,
19213 };
19214 
19215 #if (LINUX_VERSION_CODE < KERNEL_VERSION(6, 2, 0))
19216 static struct class *wlan_hdd_class_create(const char *name)
19217 {
19218 	return class_create(THIS_MODULE, name);
19219 }
19220 #else
19221 static struct class *wlan_hdd_class_create(const char *name)
19222 {
19223 	return class_create(name);
19224 }
19225 #endif
19226 
19227 static int  wlan_hdd_state_ctrl_param_create(void)
19228 {
19229 	unsigned int wlan_hdd_state_major = 0;
19230 	int ret;
19231 	struct device *dev;
19232 
19233 	init_completion(&wlan_start_comp);
19234 	qdf_atomic_init(&wlan_hdd_state_fops_ref);
19235 
19236 	device = MKDEV(wlan_hdd_state_major, 0);
19237 
19238 	ret = alloc_chrdev_region(&device, 0, dev_num, "qcwlanstate");
19239 	if (ret) {
19240 		pr_err("Failed to register qcwlanstate");
19241 		goto dev_alloc_err;
19242 	}
19243 	wlan_hdd_state_major = MAJOR(device);
19244 	class = wlan_hdd_class_create(WLAN_CTRL_NAME);
19245 	if (IS_ERR(class)) {
19246 		pr_err("wlan_hdd_state class_create error");
19247 		goto class_err;
19248 	}
19249 
19250 	dev = device_create(class, NULL, device, NULL, WLAN_CTRL_NAME);
19251 	if (IS_ERR(dev)) {
19252 		pr_err("wlan_hdd_statedevice_create error");
19253 		goto err_class_destroy;
19254 	}
19255 
19256 	cdev_init(&wlan_hdd_state_cdev, &wlan_hdd_state_fops);
19257 
19258 	wlan_hdd_state_cdev.owner = THIS_MODULE;
19259 
19260 	ret = cdev_add(&wlan_hdd_state_cdev, device, dev_num);
19261 	if (ret) {
19262 		pr_err("Failed to add cdev error");
19263 		goto cdev_add_err;
19264 	}
19265 
19266 	pr_info("wlan_hdd_state %s major(%d) initialized",
19267 		WLAN_CTRL_NAME, wlan_hdd_state_major);
19268 
19269 	return 0;
19270 
19271 cdev_add_err:
19272 	device_destroy(class, device);
19273 err_class_destroy:
19274 	class_destroy(class);
19275 class_err:
19276 	unregister_chrdev_region(device, dev_num);
19277 dev_alloc_err:
19278 	return -ENODEV;
19279 }
19280 
19281 /*
19282  * When multiple instances of the driver are loaded in parallel, only
19283  * one can create and own the state ctrl param. An instance of the
19284  * driver that creates the state ctrl param will wait for
19285  * HDD_WLAN_START_WAIT_TIME to be probed. If it is probed, then that
19286  * instance of the driver will stay loaded and no other instances of
19287  * the driver can load. But if it is not probed, then that instance of
19288  * the driver will destroy the state ctrl param and exit, and another
19289  * instance of the driver can then create the state ctrl param.
19290  */
19291 
19292 /* max number of instances we expect (arbitrary) */
19293 #define WLAN_DRIVER_MAX_INSTANCES 5
19294 
19295 /* max amount of time an instance has to wait for all instances */
19296 #define CTRL_PARAM_WAIT (WLAN_DRIVER_MAX_INSTANCES * HDD_WLAN_START_WAIT_TIME)
19297 
19298 /* amount of time we sleep for each retry (arbitrary) */
19299 #define CTRL_PARAM_SLEEP 100
19300 
19301 static void wlan_hdd_state_ctrl_param_destroy(void)
19302 {
19303 	cdev_del(&wlan_hdd_state_cdev);
19304 	device_destroy(class, device);
19305 	class_destroy(class);
19306 	unregister_chrdev_region(device, dev_num);
19307 
19308 	pr_info("Device node unregistered");
19309 }
19310 
19311 #else /* WLAN_CTRL_NAME */
19312 
19313 static int wlan_hdd_state_ctrl_param_create(void)
19314 {
19315 	return 0;
19316 }
19317 
19318 static void wlan_hdd_state_ctrl_param_destroy(void)
19319 {
19320 }
19321 
19322 #endif /* WLAN_CTRL_NAME */
19323 
19324 /**
19325  * hdd_send_scan_done_complete_cb() - API to send scan done indication to upper
19326  * layer
19327  * @vdev_id: vdev id
19328  *
19329  * Return: none
19330  */
19331 static void hdd_send_scan_done_complete_cb(uint8_t vdev_id)
19332 {
19333 	struct hdd_context *hdd_ctx;
19334 	struct wlan_hdd_link_info *link_info;
19335 	struct hdd_adapter *adapter;
19336 	struct sk_buff *vendor_event;
19337 	uint32_t len;
19338 
19339 	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
19340 	if (!hdd_ctx)
19341 		return;
19342 
19343 	link_info = hdd_get_link_info_by_vdev(hdd_ctx, vdev_id);
19344 	if (!link_info) {
19345 		hdd_err("Invalid vdev id:%d", vdev_id);
19346 		return;
19347 	}
19348 
19349 	adapter = link_info->adapter;
19350 	len = NLMSG_HDRLEN;
19351 	vendor_event =
19352 		wlan_cfg80211_vendor_event_alloc(
19353 			hdd_ctx->wiphy, &adapter->wdev, len,
19354 			QCA_NL80211_VENDOR_SUBCMD_CONNECTED_CHANNEL_STATS_INDEX,
19355 			GFP_KERNEL);
19356 
19357 	if (!vendor_event) {
19358 		hdd_err("wlan_cfg80211_vendor_event_alloc failed");
19359 		return;
19360 	}
19361 
19362 	hdd_debug("sending scan done ind to upper layer for vdev_id:%d",
19363 		  vdev_id);
19364 	wlan_cfg80211_vendor_event(vendor_event, GFP_KERNEL);
19365 }
19366 
19367 struct osif_vdev_mgr_ops osif_vdev_mgrlegacy_ops = {
19368 #ifdef WLAN_FEATURE_DYNAMIC_MAC_ADDR_UPDATE
19369 	.osif_vdev_mgr_set_mac_addr_response = hdd_set_mac_addr_event_cb,
19370 #endif
19371 	.osif_vdev_mgr_send_scan_done_complete_cb =
19372 					hdd_send_scan_done_complete_cb,
19373 
19374 };
19375 
19376 static QDF_STATUS hdd_vdev_mgr_register_cb(void)
19377 {
19378 	osif_vdev_mgr_set_legacy_cb(&osif_vdev_mgrlegacy_ops);
19379 	return osif_vdev_mgr_register_cb();
19380 }
19381 
19382 static void hdd_vdev_mgr_unregister_cb(void)
19383 {
19384 	osif_vdev_mgr_reset_legacy_cb();
19385 }
19386 
19387 /**
19388  * hdd_ll_sap_register_cb() - Register ll_sap osif callbacks
19389  *
19390  * Return: QDF_STATUS
19391  */
19392 static QDF_STATUS hdd_ll_sap_register_cb(void)
19393 {
19394 	return osif_ll_sap_register_cb();
19395 }
19396 
19397 /**
19398  * hdd_ll_sap_unregister_cb() - Un-register ll_sap osif callbacks
19399  *
19400  * Return: void
19401  */
19402 static void hdd_ll_sap_unregister_cb(void)
19403 {
19404 	osif_ll_sap_unregister_cb();
19405 }
19406 
19407 /**
19408  * hdd_component_cb_init() - Initialize component callbacks
19409  *
19410  * This function initializes hdd callbacks to different
19411  * components
19412  *
19413  * Context: Any context.
19414  * Return: QDF_STATUS
19415  */
19416 static QDF_STATUS hdd_component_cb_init(void)
19417 {
19418 	QDF_STATUS status;
19419 
19420 	status = hdd_cm_register_cb();
19421 	if (QDF_IS_STATUS_ERROR(status))
19422 		return status;
19423 
19424 	status = hdd_vdev_mgr_register_cb();
19425 	if (QDF_IS_STATUS_ERROR(status))
19426 		goto cm_unregister_cb;
19427 
19428 	status = osif_twt_register_cb();
19429 	if (QDF_IS_STATUS_ERROR(status))
19430 		goto hdd_vdev_mgr_unregister_cb;
19431 
19432 	status = hdd_pre_cac_register_cb();
19433 	if (QDF_IS_STATUS_ERROR(status))
19434 		goto hdd_vdev_mgr_unregister_cb;
19435 
19436 	status = hdd_ll_sap_register_cb();
19437 	if (QDF_IS_STATUS_ERROR(status))
19438 		goto pre_cac_unregister_cb;
19439 
19440 	return QDF_STATUS_SUCCESS;
19441 
19442 pre_cac_unregister_cb:
19443 	hdd_pre_cac_unregister_cb();
19444 hdd_vdev_mgr_unregister_cb:
19445 	hdd_vdev_mgr_unregister_cb();
19446 cm_unregister_cb:
19447 	hdd_cm_unregister_cb();
19448 	return status;
19449 }
19450 
19451 /**
19452  * hdd_component_cb_deinit() - De-initialize component callbacks
19453  *
19454  * This function de-initializes hdd callbacks with different components
19455  *
19456  * Context: Any context.
19457  * Return: None`
19458  */
19459 static void hdd_component_cb_deinit(void)
19460 {
19461 	hdd_ll_sap_unregister_cb();
19462 	hdd_pre_cac_unregister_cb();
19463 	hdd_vdev_mgr_unregister_cb();
19464 	hdd_cm_unregister_cb();
19465 }
19466 
19467 /**
19468  * hdd_component_init() - Initialize all components
19469  *
19470  * Return: QDF_STATUS
19471  */
19472 static QDF_STATUS hdd_component_init(void)
19473 {
19474 	QDF_STATUS status;
19475 
19476 	/* initialize converged components */
19477 
19478 	status = ucfg_mlme_global_init();
19479 	if (QDF_IS_STATUS_ERROR(status))
19480 		return status;
19481 
19482 	status = dispatcher_init();
19483 	if (QDF_IS_STATUS_ERROR(status))
19484 		goto mlme_global_deinit;
19485 
19486 	status = target_if_init(wma_get_psoc_from_scn_handle);
19487 	if (QDF_IS_STATUS_ERROR(status))
19488 		goto dispatcher_deinit;
19489 
19490 	/* initialize non-converged components */
19491 	status = ucfg_mlme_init();
19492 	if (QDF_IS_STATUS_ERROR(status))
19493 		goto target_if_deinit;
19494 
19495 	status = ucfg_fwol_init();
19496 	if (QDF_IS_STATUS_ERROR(status))
19497 		goto mlme_deinit;
19498 
19499 	status = disa_init();
19500 	if (QDF_IS_STATUS_ERROR(status))
19501 		goto fwol_deinit;
19502 
19503 	status = pmo_init();
19504 	if (QDF_IS_STATUS_ERROR(status))
19505 		goto disa_deinit;
19506 
19507 	status = ucfg_ocb_init();
19508 	if (QDF_IS_STATUS_ERROR(status))
19509 		goto pmo_deinit;
19510 
19511 	status = ipa_init();
19512 	if (QDF_IS_STATUS_ERROR(status))
19513 		goto ocb_deinit;
19514 
19515 	status = ucfg_action_oui_init();
19516 	if (QDF_IS_STATUS_ERROR(status))
19517 		goto ipa_deinit;
19518 
19519 	status = nan_init();
19520 	if (QDF_IS_STATUS_ERROR(status))
19521 		goto action_oui_deinit;
19522 
19523 	status = ucfg_p2p_init();
19524 	if (QDF_IS_STATUS_ERROR(status))
19525 		goto nan_deinit;
19526 
19527 	status = ucfg_interop_issues_ap_init();
19528 	if (QDF_IS_STATUS_ERROR(status))
19529 		goto p2p_deinit;
19530 
19531 	status = policy_mgr_init();
19532 	if (QDF_IS_STATUS_ERROR(status))
19533 		goto interop_issues_ap_deinit;
19534 
19535 	status = ucfg_tdls_init();
19536 	if (QDF_IS_STATUS_ERROR(status))
19537 		goto policy_deinit;
19538 
19539 	status = ucfg_dlm_init();
19540 	if (QDF_IS_STATUS_ERROR(status))
19541 		goto tdls_deinit;
19542 
19543 	status = ucfg_pkt_capture_init();
19544 	if (QDF_IS_STATUS_ERROR(status))
19545 		goto dlm_deinit;
19546 
19547 	status = ucfg_ftm_time_sync_init();
19548 	if (QDF_IS_STATUS_ERROR(status))
19549 		goto pkt_capture_deinit;
19550 
19551 	status = ucfg_pre_cac_init();
19552 	if (QDF_IS_STATUS_ERROR(status))
19553 		goto pre_cac_deinit;
19554 
19555 	status = ucfg_dp_init();
19556 	if (QDF_IS_STATUS_ERROR(status))
19557 		goto pre_cac_deinit;
19558 
19559 	status = ucfg_qmi_init();
19560 	if (QDF_IS_STATUS_ERROR(status))
19561 		goto dp_deinit;
19562 
19563 	status = ucfg_ll_sap_init();
19564 	if (QDF_IS_STATUS_ERROR(status))
19565 		goto qmi_deinit;
19566 
19567 	status = ucfg_afc_init();
19568 	if (QDF_IS_STATUS_ERROR(status))
19569 		goto ll_sap_deinit;
19570 
19571 	status = hdd_mlo_mgr_register_osif_ops();
19572 	if (QDF_IS_STATUS_ERROR(status))
19573 		goto afc_deinit;
19574 
19575 	hdd_register_cstats_ops();
19576 
19577 	return QDF_STATUS_SUCCESS;
19578 
19579 afc_deinit:
19580 	ucfg_afc_deinit();
19581 ll_sap_deinit:
19582 	ucfg_ll_sap_deinit();
19583 qmi_deinit:
19584 	ucfg_qmi_deinit();
19585 dp_deinit:
19586 	ucfg_dp_deinit();
19587 pre_cac_deinit:
19588 	ucfg_pre_cac_deinit();
19589 pkt_capture_deinit:
19590 	ucfg_pkt_capture_deinit();
19591 dlm_deinit:
19592 	ucfg_dlm_deinit();
19593 tdls_deinit:
19594 	ucfg_tdls_deinit();
19595 policy_deinit:
19596 	policy_mgr_deinit();
19597 interop_issues_ap_deinit:
19598 	ucfg_interop_issues_ap_deinit();
19599 p2p_deinit:
19600 	ucfg_p2p_deinit();
19601 nan_deinit:
19602 	nan_deinit();
19603 action_oui_deinit:
19604 	ucfg_action_oui_deinit();
19605 ipa_deinit:
19606 	ipa_deinit();
19607 ocb_deinit:
19608 	ucfg_ocb_deinit();
19609 pmo_deinit:
19610 	pmo_deinit();
19611 disa_deinit:
19612 	disa_deinit();
19613 fwol_deinit:
19614 	ucfg_fwol_deinit();
19615 mlme_deinit:
19616 	ucfg_mlme_deinit();
19617 target_if_deinit:
19618 	target_if_deinit();
19619 dispatcher_deinit:
19620 	dispatcher_deinit();
19621 mlme_global_deinit:
19622 	ucfg_mlme_global_deinit();
19623 
19624 	return status;
19625 }
19626 
19627 /**
19628  * hdd_component_deinit() - Deinitialize all components
19629  *
19630  * Return: None
19631  */
19632 static void hdd_component_deinit(void)
19633 {
19634 	/* deinitialize non-converged components */
19635 	hdd_mlo_mgr_unregister_osif_ops();
19636 	ucfg_afc_deinit();
19637 	ucfg_ll_sap_deinit();
19638 	ucfg_qmi_deinit();
19639 	ucfg_dp_deinit();
19640 	ucfg_pre_cac_deinit();
19641 	ucfg_ftm_time_sync_deinit();
19642 	ucfg_pkt_capture_deinit();
19643 	ucfg_dlm_deinit();
19644 	ucfg_tdls_deinit();
19645 	policy_mgr_deinit();
19646 	ucfg_interop_issues_ap_deinit();
19647 	ucfg_p2p_deinit();
19648 	nan_deinit();
19649 	ucfg_action_oui_deinit();
19650 	ipa_deinit();
19651 	ucfg_ocb_deinit();
19652 	pmo_deinit();
19653 	disa_deinit();
19654 	ucfg_fwol_deinit();
19655 	ucfg_mlme_deinit();
19656 
19657 	/* deinitialize converged components */
19658 	target_if_deinit();
19659 	dispatcher_deinit();
19660 	ucfg_mlme_global_deinit();
19661 }
19662 
19663 QDF_STATUS hdd_component_psoc_open(struct wlan_objmgr_psoc *psoc)
19664 {
19665 	QDF_STATUS status;
19666 
19667 	status = ucfg_mlme_psoc_open(psoc);
19668 	if (QDF_IS_STATUS_ERROR(status))
19669 		return status;
19670 
19671 	status = ucfg_dlm_psoc_open(psoc);
19672 	if (QDF_IS_STATUS_ERROR(status))
19673 		goto err_dlm;
19674 
19675 	status = ucfg_fwol_psoc_open(psoc);
19676 	if (QDF_IS_STATUS_ERROR(status))
19677 		goto err_fwol;
19678 
19679 	status = ucfg_pmo_psoc_open(psoc);
19680 	if (QDF_IS_STATUS_ERROR(status))
19681 		goto err_pmo;
19682 
19683 	status = ucfg_policy_mgr_psoc_open(psoc);
19684 	if (QDF_IS_STATUS_ERROR(status))
19685 		goto err_plcy_mgr;
19686 
19687 	status = ucfg_p2p_psoc_open(psoc);
19688 	if (QDF_IS_STATUS_ERROR(status))
19689 		goto err_p2p;
19690 
19691 	status = ucfg_tdls_psoc_open(psoc);
19692 	if (QDF_IS_STATUS_ERROR(status))
19693 		goto err_tdls;
19694 
19695 	status = ucfg_nan_psoc_open(psoc);
19696 	if (QDF_IS_STATUS_ERROR(status))
19697 		goto err_nan;
19698 
19699 	status = ucfg_twt_psoc_open(psoc);
19700 	if (QDF_IS_STATUS_ERROR(status))
19701 		goto err_twt;
19702 
19703 	status = ucfg_wifi_pos_psoc_open(psoc);
19704 	if (QDF_IS_STATUS_ERROR(status))
19705 		goto err_wifi_pos;
19706 
19707 	status = ucfg_dp_psoc_open(psoc);
19708 	if (QDF_IS_STATUS_ERROR(status))
19709 		goto err_dp;
19710 
19711 	return status;
19712 
19713 err_dp:
19714 	ucfg_wifi_pos_psoc_close(psoc);
19715 err_wifi_pos:
19716 	ucfg_twt_psoc_close(psoc);
19717 err_twt:
19718 	ucfg_nan_psoc_close(psoc);
19719 err_nan:
19720 	ucfg_tdls_psoc_close(psoc);
19721 err_tdls:
19722 	ucfg_p2p_psoc_close(psoc);
19723 err_p2p:
19724 	ucfg_policy_mgr_psoc_close(psoc);
19725 err_plcy_mgr:
19726 	ucfg_pmo_psoc_close(psoc);
19727 err_pmo:
19728 	ucfg_fwol_psoc_close(psoc);
19729 err_fwol:
19730 	ucfg_dlm_psoc_close(psoc);
19731 err_dlm:
19732 	ucfg_mlme_psoc_close(psoc);
19733 
19734 	return status;
19735 }
19736 
19737 void hdd_component_psoc_close(struct wlan_objmgr_psoc *psoc)
19738 {
19739 	ucfg_dp_psoc_close(psoc);
19740 	ucfg_wifi_pos_psoc_close(psoc);
19741 	ucfg_twt_psoc_close(psoc);
19742 	ucfg_nan_psoc_close(psoc);
19743 	ucfg_tdls_psoc_close(psoc);
19744 	ucfg_p2p_psoc_close(psoc);
19745 	ucfg_policy_mgr_psoc_close(psoc);
19746 	ucfg_pmo_psoc_close(psoc);
19747 	ucfg_fwol_psoc_close(psoc);
19748 	ucfg_dlm_psoc_close(psoc);
19749 	ucfg_mlme_psoc_close(psoc);
19750 
19751 	if (!cds_is_driver_recovering())
19752 		ucfg_crypto_flush_entries(psoc);
19753 }
19754 
19755 void hdd_component_psoc_enable(struct wlan_objmgr_psoc *psoc)
19756 {
19757 	ocb_psoc_enable(psoc);
19758 	disa_psoc_enable(psoc);
19759 	nan_psoc_enable(psoc);
19760 	p2p_psoc_enable(psoc);
19761 	ucfg_interop_issues_ap_psoc_enable(psoc);
19762 	policy_mgr_psoc_enable(psoc);
19763 	ucfg_tdls_psoc_enable(psoc);
19764 	ucfg_fwol_psoc_enable(psoc);
19765 	ucfg_action_oui_psoc_enable(psoc);
19766 	ucfg_ll_sap_psoc_enable(psoc);
19767 }
19768 
19769 void hdd_component_psoc_disable(struct wlan_objmgr_psoc *psoc)
19770 {
19771 	ucfg_ll_sap_psoc_disable(psoc);
19772 	ucfg_action_oui_psoc_disable(psoc);
19773 	ucfg_fwol_psoc_disable(psoc);
19774 	ucfg_tdls_psoc_disable(psoc);
19775 	policy_mgr_psoc_disable(psoc);
19776 	ucfg_interop_issues_ap_psoc_disable(psoc);
19777 	p2p_psoc_disable(psoc);
19778 	nan_psoc_disable(psoc);
19779 	disa_psoc_disable(psoc);
19780 	ocb_psoc_disable(psoc);
19781 }
19782 
19783 QDF_STATUS hdd_component_pdev_open(struct wlan_objmgr_pdev *pdev)
19784 {
19785 	return ucfg_mlme_pdev_open(pdev);
19786 }
19787 
19788 void hdd_component_pdev_close(struct wlan_objmgr_pdev *pdev)
19789 {
19790 	ucfg_mlme_pdev_close(pdev);
19791 }
19792 
19793 static QDF_STATUS hdd_qdf_print_init(void)
19794 {
19795 	QDF_STATUS status;
19796 	int qdf_print_idx;
19797 
19798 	status = qdf_print_setup();
19799 	if (QDF_IS_STATUS_ERROR(status)) {
19800 		pr_err("Failed qdf_print_setup; status:%u\n", status);
19801 		return status;
19802 	}
19803 
19804 	qdf_print_idx = qdf_print_ctrl_register(cinfo, NULL, NULL, "MCL_WLAN");
19805 	if (qdf_print_idx < 0) {
19806 		pr_err("Failed to register for qdf_print_ctrl\n");
19807 		return QDF_STATUS_E_FAILURE;
19808 	}
19809 
19810 	qdf_set_pidx(qdf_print_idx);
19811 
19812 	return QDF_STATUS_SUCCESS;
19813 }
19814 
19815 static void hdd_qdf_print_deinit(void)
19816 {
19817 	int qdf_pidx = qdf_get_pidx();
19818 
19819 	qdf_set_pidx(-1);
19820 	qdf_print_ctrl_cleanup(qdf_pidx);
19821 
19822 	/* currently, no qdf print 'un-setup'*/
19823 }
19824 
19825 static QDF_STATUS hdd_qdf_init(void)
19826 {
19827 	QDF_STATUS status;
19828 
19829 	status = hdd_qdf_print_init();
19830 	if (QDF_IS_STATUS_ERROR(status))
19831 		goto exit;
19832 
19833 	status = qdf_debugfs_init();
19834 	if (QDF_IS_STATUS_ERROR(status)) {
19835 		hdd_err("Failed to init debugfs; status:%u", status);
19836 		goto print_deinit;
19837 	}
19838 
19839 	qdf_lock_stats_init();
19840 	qdf_mem_init();
19841 	qdf_delayed_work_feature_init();
19842 	qdf_periodic_work_feature_init();
19843 	qdf_wake_lock_feature_init();
19844 	qdf_mc_timer_manager_init();
19845 	qdf_event_list_init();
19846 
19847 	status = qdf_talloc_feature_init();
19848 	if (QDF_IS_STATUS_ERROR(status)) {
19849 		hdd_err("Failed to init talloc; status:%u", status);
19850 		goto event_deinit;
19851 	}
19852 
19853 	status = qdf_cpuhp_init();
19854 	if (QDF_IS_STATUS_ERROR(status)) {
19855 		hdd_err("Failed to init cpuhp; status:%u", status);
19856 		goto talloc_deinit;
19857 	}
19858 
19859 	status = qdf_trace_spin_lock_init();
19860 	if (QDF_IS_STATUS_ERROR(status)) {
19861 		hdd_err("Failed to init spinlock; status:%u", status);
19862 		goto cpuhp_deinit;
19863 	}
19864 
19865 	qdf_trace_init();
19866 	qdf_minidump_init();
19867 	qdf_ssr_driver_dump_init();
19868 	qdf_register_debugcb_init();
19869 
19870 	return QDF_STATUS_SUCCESS;
19871 
19872 cpuhp_deinit:
19873 	qdf_cpuhp_deinit();
19874 talloc_deinit:
19875 	qdf_talloc_feature_deinit();
19876 event_deinit:
19877 	qdf_event_list_destroy();
19878 	qdf_mc_timer_manager_exit();
19879 	qdf_wake_lock_feature_deinit();
19880 	qdf_periodic_work_feature_deinit();
19881 	qdf_delayed_work_feature_deinit();
19882 	qdf_mem_exit();
19883 	qdf_lock_stats_deinit();
19884 	qdf_debugfs_exit();
19885 print_deinit:
19886 	hdd_qdf_print_deinit();
19887 
19888 exit:
19889 	return status;
19890 }
19891 
19892 static void hdd_qdf_deinit(void)
19893 {
19894 	/* currently, no debugcb deinit */
19895 	qdf_ssr_driver_dump_deinit();
19896 	qdf_minidump_deinit();
19897 	qdf_trace_deinit();
19898 
19899 	/* currently, no trace spinlock deinit */
19900 
19901 	qdf_cpuhp_deinit();
19902 	qdf_talloc_feature_deinit();
19903 	qdf_event_list_destroy();
19904 	qdf_mc_timer_manager_exit();
19905 	qdf_wake_lock_feature_deinit();
19906 	qdf_periodic_work_feature_deinit();
19907 	qdf_delayed_work_feature_deinit();
19908 	qdf_mem_exit();
19909 	qdf_lock_stats_deinit();
19910 	qdf_debugfs_exit();
19911 	hdd_qdf_print_deinit();
19912 }
19913 
19914 #ifdef FEATURE_MONITOR_MODE_SUPPORT
19915 static bool is_monitor_mode_supported(void)
19916 {
19917 	return true;
19918 }
19919 #else
19920 static bool is_monitor_mode_supported(void)
19921 {
19922 	pr_err("Monitor mode not supported!");
19923 	return false;
19924 }
19925 #endif
19926 
19927 #ifdef WLAN_FEATURE_EPPING
19928 static bool is_epping_mode_supported(void)
19929 {
19930 	return true;
19931 }
19932 #else
19933 static bool is_epping_mode_supported(void)
19934 {
19935 	pr_err("Epping mode not supported!");
19936 	return false;
19937 }
19938 #endif
19939 
19940 #ifdef QCA_WIFI_FTM
19941 static bool is_ftm_mode_supported(void)
19942 {
19943 	return true;
19944 }
19945 #else
19946 static bool is_ftm_mode_supported(void)
19947 {
19948 	pr_err("FTM mode not supported!");
19949 	return false;
19950 }
19951 #endif
19952 
19953 /**
19954  * is_con_mode_valid() - check con mode is valid or not
19955  * @mode: global con mode
19956  *
19957  * Return: TRUE on success FALSE on failure
19958  */
19959 static bool is_con_mode_valid(enum QDF_GLOBAL_MODE mode)
19960 {
19961 	switch (mode) {
19962 	case QDF_GLOBAL_MONITOR_MODE:
19963 		return is_monitor_mode_supported();
19964 	case QDF_GLOBAL_EPPING_MODE:
19965 		return is_epping_mode_supported();
19966 	case QDF_GLOBAL_FTM_MODE:
19967 		return is_ftm_mode_supported();
19968 	case QDF_GLOBAL_MISSION_MODE:
19969 		return true;
19970 	default:
19971 		return false;
19972 	}
19973 }
19974 
19975 static void hdd_stop_present_mode(struct hdd_context *hdd_ctx,
19976 				  enum QDF_GLOBAL_MODE curr_mode)
19977 {
19978 	if (hdd_ctx->driver_status == DRIVER_MODULES_CLOSED)
19979 		return;
19980 
19981 	switch (curr_mode) {
19982 	case QDF_GLOBAL_MONITOR_MODE:
19983 		hdd_info("Release wakelock for monitor mode!");
19984 		qdf_wake_lock_release(&hdd_ctx->monitor_mode_wakelock,
19985 				      WIFI_POWER_EVENT_WAKELOCK_MONITOR_MODE);
19986 		fallthrough;
19987 	case QDF_GLOBAL_MISSION_MODE:
19988 	case QDF_GLOBAL_FTM_MODE:
19989 		hdd_abort_mac_scan_all_adapters(hdd_ctx);
19990 		wlan_cfg80211_cleanup_scan_queue(hdd_ctx->pdev, NULL);
19991 		hdd_stop_all_adapters(hdd_ctx);
19992 		hdd_deinit_all_adapters(hdd_ctx, false);
19993 
19994 		break;
19995 	default:
19996 		break;
19997 	}
19998 }
19999 
20000 static void hdd_cleanup_present_mode(struct hdd_context *hdd_ctx,
20001 				    enum QDF_GLOBAL_MODE curr_mode)
20002 {
20003 	switch (curr_mode) {
20004 	case QDF_GLOBAL_MISSION_MODE:
20005 	case QDF_GLOBAL_MONITOR_MODE:
20006 	case QDF_GLOBAL_FTM_MODE:
20007 		hdd_close_all_adapters(hdd_ctx, false);
20008 		break;
20009 	case QDF_GLOBAL_EPPING_MODE:
20010 		epping_disable();
20011 		epping_close();
20012 		break;
20013 	default:
20014 		return;
20015 	}
20016 }
20017 
20018 static int
20019 hdd_parse_driver_mode(const char *mode_str, enum QDF_GLOBAL_MODE *out_mode)
20020 {
20021 	QDF_STATUS status;
20022 	uint32_t mode;
20023 
20024 	*out_mode = QDF_GLOBAL_MAX_MODE;
20025 
20026 	status = qdf_uint32_parse(mode_str, &mode);
20027 	if (QDF_IS_STATUS_ERROR(status))
20028 		return qdf_status_to_os_return(status);
20029 
20030 	if (mode >= QDF_GLOBAL_MAX_MODE)
20031 		return -ERANGE;
20032 
20033 	*out_mode = (enum QDF_GLOBAL_MODE)mode;
20034 
20035 	return 0;
20036 }
20037 
20038 static int hdd_mode_change_psoc_idle_shutdown(struct device *dev)
20039 {
20040 	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
20041 
20042 	if (!hdd_ctx)
20043 		return -EINVAL;
20044 
20045 	return hdd_wlan_stop_modules(hdd_ctx, true);
20046 }
20047 
20048 static int hdd_mode_change_psoc_idle_restart(struct device *dev)
20049 {
20050 	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
20051 	int ret;
20052 
20053 	if (!hdd_ctx)
20054 		return -EINVAL;
20055 	ret = hdd_soc_idle_restart_lock(dev);
20056 	if (ret)
20057 		return ret;
20058 	ret = hdd_wlan_start_modules(hdd_ctx, false);
20059 	hdd_soc_idle_restart_unlock();
20060 
20061 	return ret;
20062 }
20063 
20064 /**
20065  * __hdd_driver_mode_change() - Handles a driver mode change
20066  * @hdd_ctx: Pointer to the global HDD context
20067  * @next_mode: the driver mode to transition to
20068  *
20069  * This function is invoked when user updates con_mode using sys entry,
20070  * to initialize and bring-up driver in that specific mode.
20071  *
20072  * Return: Errno
20073  */
20074 static int __hdd_driver_mode_change(struct hdd_context *hdd_ctx,
20075 				    enum QDF_GLOBAL_MODE next_mode)
20076 {
20077 	enum QDF_GLOBAL_MODE curr_mode;
20078 	int errno;
20079 	struct bbm_params param = {0};
20080 
20081 	hdd_info("Driver mode changing to %d", next_mode);
20082 
20083 	errno = wlan_hdd_validate_context(hdd_ctx);
20084 	if (errno)
20085 		return errno;
20086 
20087 	if (!is_con_mode_valid(next_mode)) {
20088 		hdd_err_rl("Requested driver mode is invalid");
20089 		return -EINVAL;
20090 	}
20091 
20092 	curr_mode = hdd_get_conparam();
20093 	if (curr_mode == next_mode) {
20094 		hdd_err_rl("Driver is already in the requested mode");
20095 		return 0;
20096 	}
20097 
20098 	hdd_psoc_idle_timer_stop(hdd_ctx);
20099 
20100 	/* ensure adapters are stopped */
20101 	hdd_stop_present_mode(hdd_ctx, curr_mode);
20102 
20103 	if (DRIVER_MODULES_CLOSED != hdd_ctx->driver_status) {
20104 		is_mode_change_psoc_idle_shutdown = true;
20105 		errno = pld_idle_shutdown(hdd_ctx->parent_dev,
20106 					  hdd_mode_change_psoc_idle_shutdown);
20107 		if (errno) {
20108 			is_mode_change_psoc_idle_shutdown = false;
20109 			hdd_err("Stop wlan modules failed");
20110 			return errno;
20111 		}
20112 	}
20113 
20114 	/* Cleanup present mode before switching to new mode */
20115 	hdd_cleanup_present_mode(hdd_ctx, curr_mode);
20116 
20117 	hdd_set_conparam(next_mode);
20118 	pld_set_mode(next_mode);
20119 
20120 	qdf_event_reset(&hdd_ctx->regulatory_update_event);
20121 	qdf_mutex_acquire(&hdd_ctx->regulatory_status_lock);
20122 	hdd_ctx->is_regulatory_update_in_progress = true;
20123 	qdf_mutex_release(&hdd_ctx->regulatory_status_lock);
20124 
20125 	errno = pld_idle_restart(hdd_ctx->parent_dev,
20126 				 hdd_mode_change_psoc_idle_restart);
20127 	if (errno) {
20128 		hdd_err("Start wlan modules failed: %d", errno);
20129 		return errno;
20130 	}
20131 
20132 	errno = hdd_open_adapters_for_mode(hdd_ctx, next_mode);
20133 	if (errno) {
20134 		hdd_err("Failed to open adapters");
20135 		return errno;
20136 	}
20137 
20138 	if (next_mode == QDF_GLOBAL_MONITOR_MODE) {
20139 		struct hdd_adapter *adapter =
20140 			hdd_get_adapter(hdd_ctx, QDF_MONITOR_MODE);
20141 
20142 		QDF_BUG(adapter);
20143 		if (!adapter) {
20144 			hdd_err("Failed to get monitor adapter");
20145 			return -EINVAL;
20146 		}
20147 
20148 		errno = hdd_start_adapter(adapter, false);
20149 		if (errno) {
20150 			hdd_err("Failed to start monitor adapter");
20151 			return errno;
20152 		}
20153 
20154 		hdd_info("Acquire wakelock for monitor mode");
20155 		qdf_wake_lock_acquire(&hdd_ctx->monitor_mode_wakelock,
20156 				      WIFI_POWER_EVENT_WAKELOCK_MONITOR_MODE);
20157 	}
20158 
20159 	/* con_mode is a global module parameter */
20160 	con_mode = next_mode;
20161 	hdd_info("Driver mode successfully changed to %d", next_mode);
20162 
20163 	param.policy = BBM_DRIVER_MODE_POLICY;
20164 	param.policy_info.driver_mode = con_mode;
20165 	ucfg_dp_bbm_apply_independent_policy(hdd_ctx->psoc, &param);
20166 
20167 	return 0;
20168 }
20169 
20170 static void hdd_pre_mode_change(enum QDF_GLOBAL_MODE mode)
20171 {
20172 	struct osif_psoc_sync *psoc_sync;
20173 	struct hdd_context *hdd_ctx;
20174 	int errno;
20175 	enum QDF_GLOBAL_MODE curr_mode;
20176 
20177 	curr_mode = hdd_get_conparam();
20178 	if (curr_mode != QDF_GLOBAL_MISSION_MODE)
20179 		return;
20180 
20181 	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
20182 	errno = wlan_hdd_validate_context(hdd_ctx);
20183 	if (errno)
20184 		return;
20185 
20186 	errno = osif_psoc_sync_op_start(hdd_ctx->parent_dev, &psoc_sync);
20187 	if (errno) {
20188 		hdd_err("psoc op start failed");
20189 		return;
20190 	}
20191 
20192 	hdd_debug("cleanup scan queue");
20193 	if (hdd_ctx && hdd_ctx->pdev)
20194 		wlan_cfg80211_cleanup_scan_queue(hdd_ctx->pdev, NULL);
20195 
20196 	osif_psoc_sync_op_stop(psoc_sync);
20197 }
20198 
20199 static int hdd_driver_mode_change(enum QDF_GLOBAL_MODE mode)
20200 {
20201 	struct osif_driver_sync *driver_sync;
20202 	struct hdd_context *hdd_ctx;
20203 	QDF_STATUS status;
20204 	int errno;
20205 
20206 	hdd_enter();
20207 
20208 	hdd_pre_mode_change(mode);
20209 
20210 	status = osif_driver_sync_trans_start_wait(&driver_sync);
20211 	if (QDF_IS_STATUS_ERROR(status)) {
20212 		hdd_err("Failed to start 'mode change'; status:%u", status);
20213 		errno = qdf_status_to_os_return(status);
20214 		goto exit;
20215 	}
20216 
20217 	osif_driver_sync_wait_for_ops(driver_sync);
20218 
20219 	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
20220 	errno = wlan_hdd_validate_context(hdd_ctx);
20221 	if (errno)
20222 		goto trans_stop;
20223 
20224 	errno = __hdd_driver_mode_change(hdd_ctx, mode);
20225 
20226 trans_stop:
20227 	osif_driver_sync_trans_stop(driver_sync);
20228 
20229 exit:
20230 	hdd_exit();
20231 
20232 	return errno;
20233 }
20234 
20235 static int hdd_set_con_mode(enum QDF_GLOBAL_MODE mode)
20236 {
20237 	con_mode = mode;
20238 
20239 	return 0;
20240 }
20241 
20242 static int (*hdd_set_con_mode_cb)(enum QDF_GLOBAL_MODE mode) = hdd_set_con_mode;
20243 
20244 static void hdd_driver_mode_change_register(void)
20245 {
20246 	hdd_set_con_mode_cb = hdd_driver_mode_change;
20247 }
20248 
20249 static void hdd_driver_mode_change_unregister(void)
20250 {
20251 	hdd_set_con_mode_cb = hdd_set_con_mode;
20252 }
20253 
20254 static int con_mode_handler(const char *kmessage, const struct kernel_param *kp)
20255 {
20256 	enum QDF_GLOBAL_MODE mode;
20257 	int errno;
20258 
20259 	errno = hdd_parse_driver_mode(kmessage, &mode);
20260 	if (errno) {
20261 		hdd_err_rl("Failed to parse driver mode '%s'", kmessage);
20262 		return errno;
20263 	}
20264 
20265 	return hdd_set_con_mode_cb(mode);
20266 }
20267 
20268 /*
20269  * If the wlan_hdd_register_driver will return an error
20270  * if the wlan driver tries to register with the
20271  * platform driver before cnss_probe is completed.
20272  * Depending on the error code, the wlan driver waits
20273  * and retries to register.
20274  */
20275 
20276 /* Max number of retries (arbitrary)*/
20277 #define HDD_MAX_PLD_REGISTER_RETRY (50)
20278 
20279 /* Max amount of time we sleep before each retry */
20280 #define HDD_PLD_REGISTER_FAIL_SLEEP_DURATION (100)
20281 
20282 static int hdd_register_driver_retry(void)
20283 {
20284 	int count = 0;
20285 	int errno;
20286 
20287 	while (true) {
20288 		errno = wlan_hdd_register_driver();
20289 		if (errno != -EAGAIN)
20290 			return errno;
20291 		hdd_nofl_info("Retry Platform Driver Registration; errno:%d count:%d",
20292 			      errno, count);
20293 		if (++count == HDD_MAX_PLD_REGISTER_RETRY)
20294 			return errno;
20295 		msleep(HDD_PLD_REGISTER_FAIL_SLEEP_DURATION);
20296 		continue;
20297 	}
20298 
20299 	return errno;
20300 }
20301 
20302 /**
20303  * hdd_create_wifi_feature_interface() - Create wifi feature interface
20304  *
20305  * Return: none
20306  */
20307 static void hdd_create_wifi_feature_interface(void)
20308 {
20309 	hdd_sysfs_create_wifi_root_obj();
20310 	hdd_create_wifi_feature_interface_sysfs_file();
20311 }
20312 
20313 int hdd_driver_load(void)
20314 {
20315 	struct osif_driver_sync *driver_sync;
20316 	QDF_STATUS status;
20317 	int errno;
20318 	bool soft_load;
20319 
20320 	pr_info("%s: Loading driver v%s\n", WLAN_MODULE_NAME,
20321 		g_wlan_driver_version);
20322 	hdd_place_marker(NULL, "START LOADING", NULL);
20323 
20324 	status = hdd_qdf_init();
20325 	if (QDF_IS_STATUS_ERROR(status)) {
20326 		errno = qdf_status_to_os_return(status);
20327 		goto exit;
20328 	}
20329 
20330 	osif_sync_init();
20331 
20332 	status = osif_driver_sync_create_and_trans(&driver_sync);
20333 	if (QDF_IS_STATUS_ERROR(status)) {
20334 		hdd_err("Failed to init driver sync; status:%u", status);
20335 		errno = qdf_status_to_os_return(status);
20336 		goto sync_deinit;
20337 	}
20338 
20339 	errno = hdd_init();
20340 	if (errno) {
20341 		hdd_err("Failed to init HDD; errno:%d", errno);
20342 		goto trans_stop;
20343 	}
20344 
20345 	status = hdd_component_cb_init();
20346 	if (QDF_IS_STATUS_ERROR(status)) {
20347 		hdd_err("Failed to init component cb; status:%u", status);
20348 		errno = qdf_status_to_os_return(status);
20349 		goto hdd_deinit;
20350 	}
20351 
20352 	status = hdd_component_init();
20353 	if (QDF_IS_STATUS_ERROR(status)) {
20354 		hdd_err("Failed to init components; status:%u", status);
20355 		errno = qdf_status_to_os_return(status);
20356 		goto comp_cb_deinit;
20357 	}
20358 
20359 	status = qdf_wake_lock_create(&wlan_wake_lock, "wlan");
20360 	if (QDF_IS_STATUS_ERROR(status)) {
20361 		hdd_err("Failed to create wake lock; status:%u", status);
20362 		errno = qdf_status_to_os_return(status);
20363 		goto comp_deinit;
20364 	}
20365 
20366 	hdd_set_conparam(con_mode);
20367 
20368 	errno = pld_init();
20369 	if (errno) {
20370 		hdd_err("Failed to init PLD; errno:%d", errno);
20371 		goto wakelock_destroy;
20372 	}
20373 
20374 	/* driver mode pass to cnss2 platform driver*/
20375 	errno = pld_set_mode(con_mode);
20376 	if (errno)
20377 		hdd_err("Failed to set mode in PLD; errno:%d", errno);
20378 
20379 	hdd_driver_mode_change_register();
20380 
20381 	osif_driver_sync_register(driver_sync);
20382 	osif_driver_sync_trans_stop(driver_sync);
20383 
20384 	/* psoc probe can happen in registration; do after 'load' transition */
20385 	errno = hdd_register_driver_retry();
20386 	if (errno) {
20387 		hdd_err("Failed to register driver; errno:%d", errno);
20388 		goto pld_deinit;
20389 	}
20390 
20391 	/* If a soft unload of driver is done, we don't call
20392 	 * wlan_hdd_state_ctrl_param_destroy() to maintain sync
20393 	 * with userspace. In Symmetry, during soft load, avoid
20394 	 * calling wlan_hdd_state_ctrl_param_create().
20395 	 */
20396 	soft_load = hdd_get_wlan_driver_status();
20397 	if (soft_load)
20398 		goto out;
20399 
20400 	errno = wlan_hdd_state_ctrl_param_create();
20401 	if (errno) {
20402 		hdd_err("Failed to create ctrl param; errno:%d", errno);
20403 		goto unregister_driver;
20404 	}
20405 	hdd_create_wifi_feature_interface();
20406 out:
20407 	hdd_debug("%s: driver loaded", WLAN_MODULE_NAME);
20408 	hdd_place_marker(NULL, "DRIVER LOADED", NULL);
20409 
20410 	return 0;
20411 
20412 unregister_driver:
20413 	wlan_hdd_unregister_driver();
20414 pld_deinit:
20415 	status = osif_driver_sync_trans_start(&driver_sync);
20416 	QDF_BUG(QDF_IS_STATUS_SUCCESS(status));
20417 
20418 	osif_driver_sync_unregister();
20419 	if (driver_sync)
20420 		osif_driver_sync_wait_for_ops(driver_sync);
20421 
20422 	hdd_driver_mode_change_unregister();
20423 	pld_deinit();
20424 
20425 	hdd_start_complete(errno);
20426 	/* Wait for any ref taken on /dev/wlan to be released */
20427 	while (qdf_atomic_read(&wlan_hdd_state_fops_ref))
20428 		;
20429 wakelock_destroy:
20430 	qdf_wake_lock_destroy(&wlan_wake_lock);
20431 comp_deinit:
20432 	hdd_component_deinit();
20433 comp_cb_deinit:
20434 	hdd_component_cb_deinit();
20435 hdd_deinit:
20436 	hdd_deinit();
20437 trans_stop:
20438 	if (driver_sync) {
20439 		osif_driver_sync_trans_stop(driver_sync);
20440 		osif_driver_sync_destroy(driver_sync);
20441 	}
20442 sync_deinit:
20443 	osif_sync_deinit();
20444 	hdd_qdf_deinit();
20445 
20446 exit:
20447 	return errno;
20448 }
20449 
20450 #ifdef FEATURE_WLAN_RESIDENT_DRIVER
20451 EXPORT_SYMBOL(hdd_driver_load);
20452 #endif
20453 
20454 /**
20455  * hdd_distroy_wifi_feature_interface() - Distroy wifi feature interface
20456  *
20457  * Return: none
20458  */
20459 static void hdd_distroy_wifi_feature_interface(void)
20460 {
20461 	hdd_destroy_wifi_feature_interface_sysfs_file();
20462 	hdd_sysfs_destroy_wifi_root_obj();
20463 }
20464 
20465 void hdd_driver_unload(void)
20466 {
20467 	struct osif_driver_sync *driver_sync;
20468 	struct hdd_context *hdd_ctx;
20469 	QDF_STATUS status;
20470 	void *hif_ctx;
20471 	bool soft_unload;
20472 
20473 	soft_unload = hdd_get_wlan_driver_status();
20474 	if (soft_unload) {
20475 		pr_info("%s: Soft Unloading driver v%s\n", WLAN_MODULE_NAME,
20476 			QWLAN_VERSIONSTR);
20477 	} else {
20478 		pr_info("%s: Hard Unloading driver v%s\n", WLAN_MODULE_NAME,
20479 			QWLAN_VERSIONSTR);
20480 	}
20481 
20482 	hdd_place_marker(NULL, "START UNLOADING", NULL);
20483 
20484 	/*
20485 	 * Wait for any trans to complete and then start the driver trans
20486 	 * for the unload. This will ensure that the driver trans proceeds only
20487 	 * after all trans have been completed. As a part of this trans, set
20488 	 * the driver load/unload flag to further ensure that any upcoming
20489 	 * trans are rejected via wlan_hdd_validate_context.
20490 	 */
20491 	status = osif_driver_sync_trans_start_wait(&driver_sync);
20492 	if (QDF_IS_STATUS_ERROR(status) && status != -ETIMEDOUT) {
20493 		QDF_BUG(QDF_IS_STATUS_SUCCESS(status));
20494 		hdd_err("Unable to unload wlan; status:%u", status);
20495 		hdd_place_marker(NULL, "UNLOAD FAILURE", NULL);
20496 		return;
20497 	}
20498 
20499 	hif_ctx = cds_get_context(QDF_MODULE_ID_HIF);
20500 	if (hif_ctx) {
20501 		/*
20502 		 * Trigger runtime sync resume before setting unload in progress
20503 		 * such that resume can happen successfully
20504 		 */
20505 		qdf_rtpm_sync_resume();
20506 	}
20507 
20508 	cds_set_driver_loaded(false);
20509 	cds_set_unload_in_progress(true);
20510 
20511 	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
20512 	if (hdd_ctx) {
20513 		hdd_psoc_idle_timer_stop(hdd_ctx);
20514 		/*
20515 		 * Runtime PM sync resume may have started the bus bandwidth
20516 		 * periodic work hence stop it.
20517 		 */
20518 		ucfg_dp_bus_bw_compute_timer_stop(hdd_ctx->psoc);
20519 	}
20520 
20521 	/*
20522 	 * Stop the trans before calling unregister_driver as that involves a
20523 	 * call to pld_remove which in itself is a psoc transaction
20524 	 */
20525 	if (driver_sync)
20526 		osif_driver_sync_trans_stop(driver_sync);
20527 
20528 	hdd_distroy_wifi_feature_interface();
20529 	if (!soft_unload)
20530 		wlan_hdd_state_ctrl_param_destroy();
20531 
20532 	/* trigger SoC remove */
20533 	wlan_hdd_unregister_driver();
20534 
20535 	status = osif_driver_sync_trans_start_wait(&driver_sync);
20536 	if (QDF_IS_STATUS_ERROR(status) && status != -ETIMEDOUT) {
20537 		QDF_BUG(QDF_IS_STATUS_SUCCESS(status));
20538 		hdd_err("Unable to unload wlan; status:%u", status);
20539 		hdd_place_marker(NULL, "UNLOAD FAILURE", NULL);
20540 		return;
20541 	}
20542 
20543 	osif_driver_sync_unregister();
20544 	if (driver_sync)
20545 		osif_driver_sync_wait_for_ops(driver_sync);
20546 
20547 	hdd_driver_mode_change_unregister();
20548 	pld_deinit();
20549 	hdd_set_conparam(0);
20550 	qdf_wake_lock_destroy(&wlan_wake_lock);
20551 	hdd_component_deinit();
20552 	hdd_component_cb_deinit();
20553 	hdd_deinit();
20554 
20555 	if (driver_sync) {
20556 		osif_driver_sync_trans_stop(driver_sync);
20557 		osif_driver_sync_destroy(driver_sync);
20558 	}
20559 	osif_sync_deinit();
20560 
20561 	hdd_qdf_deinit();
20562 	hdd_place_marker(NULL, "UNLOAD DONE", NULL);
20563 }
20564 
20565 #ifdef FEATURE_WLAN_RESIDENT_DRIVER
20566 EXPORT_SYMBOL(hdd_driver_unload);
20567 #endif
20568 
20569 #ifndef MODULE
20570 /**
20571  * wlan_boot_cb() - Wlan boot callback
20572  * @kobj:      object whose directory we're creating the link in.
20573  * @attr:      attribute the user is interacting with
20574  * @buf:       the buffer containing the user data
20575  * @count:     number of bytes in the buffer
20576  *
20577  * This callback is invoked when the fs is ready to start the
20578  * wlan driver initialization.
20579  *
20580  * Return: 'count' on success or a negative error code in case of failure
20581  */
20582 static ssize_t wlan_boot_cb(struct kobject *kobj,
20583 			    struct kobj_attribute *attr,
20584 			    const char *buf,
20585 			    size_t count)
20586 {
20587 
20588 	if (wlan_loader->loaded_state) {
20589 		hdd_err("wlan driver already initialized");
20590 		return -EALREADY;
20591 	}
20592 
20593 	if (hdd_driver_load())
20594 		return -EIO;
20595 
20596 	wlan_loader->loaded_state = MODULE_INITIALIZED;
20597 
20598 	return count;
20599 }
20600 
20601 /**
20602  * hdd_sysfs_cleanup() - cleanup sysfs
20603  *
20604  * Return: None
20605  *
20606  */
20607 static void hdd_sysfs_cleanup(void)
20608 {
20609 	/* remove from group */
20610 	if (wlan_loader->boot_wlan_obj && wlan_loader->attr_group)
20611 		sysfs_remove_group(wlan_loader->boot_wlan_obj,
20612 				   wlan_loader->attr_group);
20613 
20614 	/* unlink the object from parent */
20615 	kobject_del(wlan_loader->boot_wlan_obj);
20616 
20617 	/* free the object */
20618 	kobject_put(wlan_loader->boot_wlan_obj);
20619 
20620 	kfree(wlan_loader->attr_group);
20621 	kfree(wlan_loader);
20622 
20623 	wlan_loader = NULL;
20624 }
20625 
20626 /**
20627  * wlan_init_sysfs() - Creates the sysfs to be invoked when the fs is
20628  * ready
20629  *
20630  * This is creates the syfs entry boot_wlan. Which shall be invoked
20631  * when the filesystem is ready.
20632  *
20633  * QDF API cannot be used here since this function is called even before
20634  * initializing WLAN driver.
20635  *
20636  * Return: 0 for success, errno on failure
20637  */
20638 static int wlan_init_sysfs(void)
20639 {
20640 	int ret = -ENOMEM;
20641 
20642 	wlan_loader = kzalloc(sizeof(*wlan_loader), GFP_KERNEL);
20643 	if (!wlan_loader)
20644 		return -ENOMEM;
20645 
20646 	wlan_loader->boot_wlan_obj = NULL;
20647 	wlan_loader->attr_group = kzalloc(sizeof(*(wlan_loader->attr_group)),
20648 					  GFP_KERNEL);
20649 	if (!wlan_loader->attr_group)
20650 		goto error_return;
20651 
20652 	wlan_loader->loaded_state = 0;
20653 	wlan_loader->attr_group->attrs = attrs;
20654 
20655 	wlan_loader->boot_wlan_obj = kobject_create_and_add(WLAN_LOADER_NAME,
20656 							    kernel_kobj);
20657 	if (!wlan_loader->boot_wlan_obj) {
20658 		hdd_err("sysfs create and add failed");
20659 		goto error_return;
20660 	}
20661 
20662 	ret = sysfs_create_group(wlan_loader->boot_wlan_obj,
20663 				 wlan_loader->attr_group);
20664 	if (ret) {
20665 		hdd_err("sysfs create group failed; errno:%d", ret);
20666 		goto error_return;
20667 	}
20668 
20669 	return 0;
20670 
20671 error_return:
20672 	hdd_sysfs_cleanup();
20673 
20674 	return ret;
20675 }
20676 
20677 /**
20678  * wlan_deinit_sysfs() - Removes the sysfs created to initialize the wlan
20679  *
20680  * Return: 0 on success or errno on failure
20681  */
20682 static int wlan_deinit_sysfs(void)
20683 {
20684 	if (!wlan_loader) {
20685 		hdd_err("wlan_loader is null");
20686 		return -EINVAL;
20687 	}
20688 
20689 	hdd_sysfs_cleanup();
20690 	return 0;
20691 }
20692 
20693 #endif /* MODULE */
20694 
20695 #ifdef MODULE
20696 /**
20697  * hdd_module_init() - Module init helper
20698  *
20699  * Module init helper function used by both module and static driver.
20700  *
20701  * Return: 0 for success, errno on failure
20702  */
20703 #ifdef FEATURE_WLAN_RESIDENT_DRIVER
20704 static int hdd_module_init(void)
20705 {
20706 	return 0;
20707 }
20708 #else
20709 static int hdd_module_init(void)
20710 {
20711 	if (hdd_driver_load())
20712 		return -EINVAL;
20713 
20714 	return 0;
20715 }
20716 #endif
20717 #else
20718 static int __init hdd_module_init(void)
20719 {
20720 	int ret = -EINVAL;
20721 
20722 	ret = wlan_init_sysfs();
20723 	if (ret)
20724 		hdd_err("Failed to create sysfs entry");
20725 
20726 	return ret;
20727 }
20728 #endif
20729 
20730 
20731 #ifdef MODULE
20732 /**
20733  * hdd_module_exit() - Exit function
20734  *
20735  * This is the driver exit point (invoked when module is unloaded using rmmod)
20736  *
20737  * Return: None
20738  */
20739 #ifdef FEATURE_WLAN_RESIDENT_DRIVER
20740 static void __exit hdd_module_exit(void)
20741 {
20742 }
20743 #else
20744 static void __exit hdd_module_exit(void)
20745 {
20746 	hdd_driver_unload();
20747 }
20748 #endif
20749 #else
20750 static void __exit hdd_module_exit(void)
20751 {
20752 	hdd_driver_unload();
20753 	wlan_deinit_sysfs();
20754 }
20755 #endif
20756 
20757 static int fwpath_changed_handler(const char *kmessage,
20758 				  const struct kernel_param *kp)
20759 {
20760 	return param_set_copystring(kmessage, kp);
20761 }
20762 
20763 static int con_mode_handler_ftm(const char *kmessage,
20764 				const struct kernel_param *kp)
20765 {
20766 	int ret;
20767 
20768 	ret = param_set_int(kmessage, kp);
20769 
20770 	if (cds_is_driver_loaded() || cds_is_load_or_unload_in_progress()) {
20771 		pr_err("Driver already loaded or load/unload in progress");
20772 		return -ENOTSUPP;
20773 	}
20774 
20775 	if (con_mode_ftm != QDF_GLOBAL_FTM_MODE) {
20776 		pr_err("Only FTM mode supported!");
20777 		return -ENOTSUPP;
20778 	}
20779 
20780 	hdd_set_conparam(con_mode_ftm);
20781 	con_mode = con_mode_ftm;
20782 
20783 	return ret;
20784 }
20785 
20786 #ifdef WLAN_FEATURE_EPPING
20787 static int con_mode_handler_epping(const char *kmessage,
20788 				   const struct kernel_param *kp)
20789 {
20790 	int ret;
20791 
20792 	ret = param_set_int(kmessage, kp);
20793 
20794 	if (con_mode_epping != QDF_GLOBAL_EPPING_MODE) {
20795 		pr_err("Only EPPING mode supported!");
20796 		return -ENOTSUPP;
20797 	}
20798 
20799 	hdd_set_conparam(con_mode_epping);
20800 	con_mode = con_mode_epping;
20801 
20802 	return ret;
20803 }
20804 #endif
20805 
20806 /**
20807  * hdd_get_conparam() - driver exit point
20808  *
20809  * This is the driver exit point (invoked when module is unloaded using rmmod)
20810  *
20811  * Return: enum QDF_GLOBAL_MODE
20812  */
20813 enum QDF_GLOBAL_MODE hdd_get_conparam(void)
20814 {
20815 	return (enum QDF_GLOBAL_MODE) curr_con_mode;
20816 }
20817 
20818 void hdd_set_conparam(int32_t con_param)
20819 {
20820 	curr_con_mode = con_param;
20821 }
20822 
20823 /**
20824  * hdd_svc_fw_crashed_ind() - API to send FW CRASHED IND to Userspace
20825  *
20826  * Return: void
20827  */
20828 static void hdd_svc_fw_crashed_ind(void)
20829 {
20830 	struct hdd_context *hdd_ctx;
20831 
20832 	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
20833 
20834 	hdd_ctx ? wlan_hdd_send_svc_nlink_msg(hdd_ctx->radio_index,
20835 					      WLAN_SVC_FW_CRASHED_IND,
20836 					      NULL, 0) : 0;
20837 }
20838 
20839 /**
20840  * hdd_update_ol_config - API to update ol configuration parameters
20841  * @hdd_ctx: HDD context
20842  *
20843  * Return: void
20844  */
20845 static void hdd_update_ol_config(struct hdd_context *hdd_ctx)
20846 {
20847 	struct ol_config_info cfg = {0};
20848 	struct ol_context *ol_ctx = cds_get_context(QDF_MODULE_ID_BMI);
20849 	bool self_recovery = false;
20850 	QDF_STATUS status;
20851 
20852 	if (!ol_ctx)
20853 		return;
20854 
20855 	status = ucfg_mlme_get_self_recovery(hdd_ctx->psoc, &self_recovery);
20856 	if (QDF_IS_STATUS_ERROR(status))
20857 		hdd_err("Failed to get self recovery ini config");
20858 
20859 	cfg.enable_self_recovery = self_recovery;
20860 	cfg.enable_uart_print = hdd_ctx->config->enablefwprint;
20861 	cfg.enable_fw_log = hdd_ctx->config->enable_fw_log;
20862 	cfg.enable_ramdump_collection = hdd_ctx->config->is_ramdump_enabled;
20863 	cfg.enable_lpass_support = hdd_lpass_is_supported(hdd_ctx);
20864 
20865 	ol_init_ini_config(ol_ctx, &cfg);
20866 	ol_set_fw_crashed_cb(ol_ctx, hdd_svc_fw_crashed_ind);
20867 }
20868 
20869 #ifdef FEATURE_RUNTIME_PM
20870 /**
20871  * hdd_populate_runtime_cfg() - populate runtime configuration
20872  * @hdd_ctx: hdd context
20873  * @cfg: pointer to the configuration memory being populated
20874  *
20875  * Return: void
20876  */
20877 static void hdd_populate_runtime_cfg(struct hdd_context *hdd_ctx,
20878 				     struct hif_config_info *cfg)
20879 {
20880 	cfg->enable_runtime_pm = hdd_ctx->config->runtime_pm;
20881 	cfg->runtime_pm_delay =
20882 		ucfg_pmo_get_runtime_pm_delay(hdd_ctx->psoc);
20883 }
20884 #else
20885 static void hdd_populate_runtime_cfg(struct hdd_context *hdd_ctx,
20886 				     struct hif_config_info *cfg)
20887 {
20888 }
20889 #endif
20890 
20891 #ifdef FEATURE_ENABLE_CE_DP_IRQ_AFFINE
20892 /**
20893  * hdd_populate_ce_dp_irq_affine_cfg() - populate ce irq affine configuration
20894  * @hdd_ctx: hdd context
20895  * @cfg: pointer to the configuration memory being populated
20896  *
20897  * Return: void
20898  */
20899 static void hdd_populate_ce_dp_irq_affine_cfg(struct hdd_context *hdd_ctx,
20900 					      struct hif_config_info *cfg)
20901 {
20902 	cfg->enable_ce_dp_irq_affine = cfg_get(hdd_ctx->psoc,
20903 					       CFG_ENABLE_CE_DP_IRQ_AFFINE);
20904 }
20905 #else
20906 static void hdd_populate_ce_dp_irq_affine_cfg(struct hdd_context *hdd_ctx,
20907 					      struct hif_config_info *cfg)
20908 {
20909 }
20910 #endif
20911 
20912 /**
20913  * hdd_update_hif_config - API to update HIF configuration parameters
20914  * @hdd_ctx: HDD Context
20915  *
20916  * Return: void
20917  */
20918 static void hdd_update_hif_config(struct hdd_context *hdd_ctx)
20919 {
20920 	struct hif_opaque_softc *scn = cds_get_context(QDF_MODULE_ID_HIF);
20921 	struct hif_config_info cfg = {0};
20922 	bool prevent_link_down = false;
20923 	bool self_recovery = false;
20924 	QDF_STATUS status;
20925 
20926 	if (!scn)
20927 		return;
20928 
20929 	status = ucfg_mlme_get_prevent_link_down(hdd_ctx->psoc,
20930 						 &prevent_link_down);
20931 	if (QDF_IS_STATUS_ERROR(status))
20932 		hdd_err("Failed to get prevent_link_down config");
20933 
20934 	status = ucfg_mlme_get_self_recovery(hdd_ctx->psoc, &self_recovery);
20935 	if (QDF_IS_STATUS_ERROR(status))
20936 		hdd_err("Failed to get self recovery ini config");
20937 
20938 	cfg.enable_self_recovery = self_recovery;
20939 	hdd_populate_runtime_cfg(hdd_ctx, &cfg);
20940 	cfg.rx_softirq_max_yield_duration_ns =
20941 		ucfg_dp_get_rx_softirq_yield_duration(hdd_ctx->psoc);
20942 	hdd_populate_ce_dp_irq_affine_cfg(hdd_ctx, &cfg);
20943 
20944 	hif_init_ini_config(scn, &cfg);
20945 	hif_set_enable_rpm(scn);
20946 
20947 	if (prevent_link_down)
20948 		hif_vote_link_up(scn);
20949 }
20950 
20951 /**
20952  * hdd_update_dp_config() - Propagate config parameters to Lithium
20953  *                          datapath
20954  * @hdd_ctx: HDD Context
20955  *
20956  * Return: 0 for success/errno for failure
20957  */
20958 static int hdd_update_dp_config(struct hdd_context *hdd_ctx)
20959 {
20960 	struct wlan_dp_user_config dp_cfg;
20961 	QDF_STATUS status;
20962 
20963 	dp_cfg.ipa_enable = ucfg_ipa_is_enabled();
20964 	dp_cfg.arp_connectivity_map = CONNECTIVITY_CHECK_SET_ARP;
20965 
20966 	status = ucfg_dp_update_config(hdd_ctx->psoc, &dp_cfg);
20967 	if (status != QDF_STATUS_SUCCESS) {
20968 		hdd_err("failed DP PSOC configuration update");
20969 		return -EINVAL;
20970 	}
20971 
20972 	return 0;
20973 }
20974 
20975 /**
20976  * hdd_update_config() - Initialize driver per module ini parameters
20977  * @hdd_ctx: HDD Context
20978  *
20979  * API is used to initialize all driver per module configuration parameters
20980  * Return: 0 for success, errno for failure
20981  */
20982 int hdd_update_config(struct hdd_context *hdd_ctx)
20983 {
20984 	int ret;
20985 
20986 	if (ucfg_pmo_is_ns_offloaded(hdd_ctx->psoc))
20987 		hdd_ctx->ns_offload_enable = true;
20988 
20989 	hdd_update_ol_config(hdd_ctx);
20990 	hdd_update_hif_config(hdd_ctx);
20991 	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam())
20992 		ret = hdd_update_cds_config_ftm(hdd_ctx);
20993 	else
20994 		ret = hdd_update_cds_config(hdd_ctx);
20995 	ret = hdd_update_user_config(hdd_ctx);
20996 
20997 	hdd_update_regdb_offload_config(hdd_ctx);
20998 
20999 	return ret;
21000 }
21001 
21002 /**
21003  * hdd_update_pmo_config - API to update pmo configuration parameters
21004  * @hdd_ctx: HDD context
21005  *
21006  * Return: void
21007  */
21008 static int hdd_update_pmo_config(struct hdd_context *hdd_ctx)
21009 {
21010 	struct pmo_psoc_cfg psoc_cfg = {0};
21011 	QDF_STATUS status;
21012 	enum pmo_wow_enable_type wow_enable;
21013 
21014 	ucfg_pmo_get_psoc_config(hdd_ctx->psoc, &psoc_cfg);
21015 
21016 	/*
21017 	 * Value of hdd_ctx->wowEnable can be,
21018 	 * 0 - Disable both magic pattern match and pattern byte match.
21019 	 * 1 - Enable magic pattern match on all interfaces.
21020 	 * 2 - Enable pattern byte match on all interfaces.
21021 	 * 3 - Enable both magic pattern and pattern byte match on
21022 	 *     all interfaces.
21023 	 */
21024 	wow_enable = ucfg_pmo_get_wow_enable(hdd_ctx->psoc);
21025 	psoc_cfg.magic_ptrn_enable = (wow_enable & 0x01) ? true : false;
21026 	psoc_cfg.ptrn_match_enable_all_vdev =
21027 				(wow_enable & 0x02) ? true : false;
21028 	psoc_cfg.ap_arpns_support = hdd_ctx->ap_arpns_support;
21029 	psoc_cfg.d0_wow_supported = wma_d0_wow_is_supported();
21030 	ucfg_mlme_get_sap_max_modulated_dtim(hdd_ctx->psoc,
21031 					     &psoc_cfg.sta_max_li_mod_dtim);
21032 
21033 	hdd_lpass_populate_pmo_config(&psoc_cfg, hdd_ctx);
21034 
21035 	status = ucfg_pmo_update_psoc_config(hdd_ctx->psoc, &psoc_cfg);
21036 	if (QDF_IS_STATUS_ERROR(status))
21037 		hdd_err("failed pmo psoc configuration; status:%d", status);
21038 
21039 	return qdf_status_to_os_return(status);
21040 }
21041 
21042 void hdd_update_ie_allowlist_attr(struct probe_req_allowlist_attr *ie_allowlist,
21043 				  struct hdd_context *hdd_ctx)
21044 {
21045 	struct wlan_fwol_ie_allowlist allowlist = {0};
21046 	struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc;
21047 	QDF_STATUS status;
21048 	bool is_ie_allowlist_enable = false;
21049 	uint8_t i = 0;
21050 
21051 	status = ucfg_fwol_get_ie_allowlist(psoc, &is_ie_allowlist_enable);
21052 	if (QDF_IS_STATUS_ERROR(status)) {
21053 		hdd_err("Unable to get IE allowlist param");
21054 		return;
21055 	}
21056 
21057 	ie_allowlist->allow_list = is_ie_allowlist_enable;
21058 	if (!ie_allowlist->allow_list)
21059 		return;
21060 
21061 	status = ucfg_fwol_get_all_allowlist_params(psoc, &allowlist);
21062 	if (QDF_IS_STATUS_ERROR(status)) {
21063 		hdd_err("Unable to get all allowlist params");
21064 		return;
21065 	}
21066 
21067 	ie_allowlist->ie_bitmap[0] = allowlist.ie_bitmap_0;
21068 	ie_allowlist->ie_bitmap[1] = allowlist.ie_bitmap_1;
21069 	ie_allowlist->ie_bitmap[2] = allowlist.ie_bitmap_2;
21070 	ie_allowlist->ie_bitmap[3] = allowlist.ie_bitmap_3;
21071 	ie_allowlist->ie_bitmap[4] = allowlist.ie_bitmap_4;
21072 	ie_allowlist->ie_bitmap[5] = allowlist.ie_bitmap_5;
21073 	ie_allowlist->ie_bitmap[6] = allowlist.ie_bitmap_6;
21074 	ie_allowlist->ie_bitmap[7] = allowlist.ie_bitmap_7;
21075 
21076 	ie_allowlist->num_vendor_oui = allowlist.no_of_probe_req_ouis;
21077 	for (i = 0; i < ie_allowlist->num_vendor_oui; i++)
21078 		ie_allowlist->voui[i] = allowlist.probe_req_voui[i];
21079 }
21080 
21081 QDF_STATUS hdd_update_score_config(struct hdd_context *hdd_ctx)
21082 {
21083 	struct hdd_config *cfg = hdd_ctx->config;
21084 	eCsrPhyMode phy_mode = hdd_cfg_xlate_to_csr_phy_mode(cfg->dot11Mode);
21085 
21086 	sme_update_score_config(hdd_ctx->mac_handle, phy_mode,
21087 				hdd_ctx->num_rf_chains);
21088 
21089 	return QDF_STATUS_SUCCESS;
21090 }
21091 
21092 /**
21093  * hdd_update_dfs_config() - API to update dfs configuration parameters.
21094  * @hdd_ctx: HDD context
21095  *
21096  * Return: 0 if success else err
21097  */
21098 static int hdd_update_dfs_config(struct hdd_context *hdd_ctx)
21099 {
21100 	struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc;
21101 	struct dfs_user_config dfs_cfg = {0};
21102 	QDF_STATUS status;
21103 
21104 	ucfg_mlme_get_dfs_filter_offload(hdd_ctx->psoc,
21105 					 &dfs_cfg.dfs_is_phyerr_filter_offload);
21106 	status = ucfg_dfs_update_config(psoc, &dfs_cfg);
21107 	if (QDF_IS_STATUS_ERROR(status)) {
21108 		hdd_err("failed dfs psoc configuration");
21109 		return -EINVAL;
21110 	}
21111 
21112 	return 0;
21113 }
21114 
21115 /**
21116  * hdd_update_scan_config - API to update scan configuration parameters
21117  * @hdd_ctx: HDD context
21118  *
21119  * Return: 0 if success else err
21120  */
21121 int hdd_update_scan_config(struct hdd_context *hdd_ctx)
21122 {
21123 	struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc;
21124 	struct scan_user_cfg scan_cfg;
21125 	QDF_STATUS status;
21126 	uint32_t mcast_mcc_rest_time = 0;
21127 
21128 	qdf_mem_zero(&scan_cfg, sizeof(scan_cfg));
21129 	status = ucfg_mlme_get_sta_miracast_mcc_rest_time(hdd_ctx->psoc,
21130 							  &mcast_mcc_rest_time);
21131 	if (!QDF_IS_STATUS_SUCCESS(status)) {
21132 		hdd_err("ucfg_mlme_get_sta_miracast_mcc_rest_time, use def");
21133 		return -EIO;
21134 	}
21135 	scan_cfg.sta_miracast_mcc_rest_time = mcast_mcc_rest_time;
21136 	hdd_update_ie_allowlist_attr(&scan_cfg.ie_allowlist, hdd_ctx);
21137 
21138 	status = ucfg_scan_update_user_config(psoc, &scan_cfg);
21139 	if (status != QDF_STATUS_SUCCESS) {
21140 		hdd_err("failed pmo psoc configuration");
21141 		return -EINVAL;
21142 	}
21143 
21144 	return 0;
21145 }
21146 
21147 int hdd_update_components_config(struct hdd_context *hdd_ctx)
21148 {
21149 	int ret;
21150 
21151 	ret = hdd_update_pmo_config(hdd_ctx);
21152 	if (ret)
21153 		return ret;
21154 
21155 	ret = hdd_update_scan_config(hdd_ctx);
21156 	if (ret)
21157 		return ret;
21158 
21159 	ret = hdd_update_tdls_config(hdd_ctx);
21160 	if (ret)
21161 		return ret;
21162 
21163 	ret = hdd_update_dp_config(hdd_ctx);
21164 	if (ret)
21165 		return ret;
21166 
21167 	ret = hdd_update_dfs_config(hdd_ctx);
21168 	if (ret)
21169 		return ret;
21170 
21171 	ret = hdd_update_regulatory_config(hdd_ctx);
21172 	if (ret)
21173 		return ret;
21174 
21175 	return ret;
21176 }
21177 
21178 /**
21179  * wlan_hdd_get_dfs_mode() - get ACS DFS mode
21180  * @mode : cfg80211 DFS mode
21181  *
21182  * Return: return SAP ACS DFS mode else return ACS_DFS_MODE_NONE
21183  */
21184 enum  sap_acs_dfs_mode wlan_hdd_get_dfs_mode(enum dfs_mode mode)
21185 {
21186 	switch (mode) {
21187 	case DFS_MODE_ENABLE:
21188 		return ACS_DFS_MODE_ENABLE;
21189 	case DFS_MODE_DISABLE:
21190 		return ACS_DFS_MODE_DISABLE;
21191 	case DFS_MODE_DEPRIORITIZE:
21192 		return ACS_DFS_MODE_DEPRIORITIZE;
21193 	default:
21194 		hdd_debug("ACS dfs mode is NONE");
21195 		return ACS_DFS_MODE_NONE;
21196 	}
21197 }
21198 
21199 /**
21200  * hdd_enable_disable_ca_event() - enable/disable channel avoidance event
21201  * @hdd_ctx: pointer to hdd context
21202  * @set_value: enable/disable
21203  *
21204  * When Host sends vendor command enable, FW will send *ONE* CA ind to
21205  * Host(even though it is duplicate). When Host send vendor command
21206  * disable,FW doesn't perform any action. Whenever any change in
21207  * CA *and* WLAN is in SAP/P2P-GO mode, FW sends CA ind to host.
21208  *
21209  * return - 0 on success, appropriate error values on failure.
21210  */
21211 int hdd_enable_disable_ca_event(struct hdd_context *hdd_ctx, uint8_t set_value)
21212 {
21213 	QDF_STATUS status;
21214 
21215 	if (0 != wlan_hdd_validate_context(hdd_ctx))
21216 		return -EAGAIN;
21217 
21218 	status = sme_enable_disable_chanavoidind_event(hdd_ctx->mac_handle,
21219 						       set_value);
21220 	if (!QDF_IS_STATUS_SUCCESS(status)) {
21221 		hdd_err("Failed to send chan avoid command to SME");
21222 		return -EINVAL;
21223 	}
21224 	return 0;
21225 }
21226 
21227 bool hdd_is_roaming_in_progress(struct hdd_context *hdd_ctx)
21228 {
21229 	struct hdd_adapter *adapter = NULL, *next_adapter = NULL;
21230 	uint8_t vdev_id;
21231 	wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_IS_ROAMING_IN_PROGRESS;
21232 	struct wlan_hdd_link_info *link_info;
21233 
21234 	if (!hdd_ctx) {
21235 		hdd_err("HDD context is NULL");
21236 		return false;
21237 	}
21238 
21239 	if (!policy_mgr_is_sta_active_connection_exists(hdd_ctx->psoc))
21240 		return false;
21241 
21242 	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
21243 					   dbgid) {
21244 		if (adapter->device_mode != QDF_STA_MODE)
21245 			goto adapter_put;
21246 
21247 		hdd_adapter_for_each_active_link_info(adapter, link_info) {
21248 			vdev_id = link_info->vdev_id;
21249 			if (test_bit(SME_SESSION_OPENED,
21250 				     &link_info->link_flags) &&
21251 			    sme_roaming_in_progress(hdd_ctx->mac_handle,
21252 						    vdev_id)) {
21253 				hdd_debug("Roaming is in progress on:vdev_id:%d",
21254 					  link_info->vdev_id);
21255 				hdd_adapter_dev_put_debug(adapter, dbgid);
21256 				if (next_adapter)
21257 					hdd_adapter_dev_put_debug(next_adapter,
21258 								  dbgid);
21259 				return true;
21260 			}
21261 		}
21262 adapter_put:
21263 		hdd_adapter_dev_put_debug(adapter, dbgid);
21264 	}
21265 
21266 	return false;
21267 }
21268 
21269 /**
21270  * struct hdd_is_connection_in_progress_priv - adapter connection info
21271  * @out_vdev_id: id of vdev where connection is occurring
21272  * @out_reason: scan reject reason
21273  * @connection_in_progress: true if connection is in progress
21274  */
21275 struct hdd_is_connection_in_progress_priv {
21276 	uint8_t out_vdev_id;
21277 	enum scan_reject_states out_reason;
21278 	bool connection_in_progress;
21279 };
21280 
21281 /**
21282  * hdd_is_connection_in_progress_iterator() - Check adapter connection based
21283  * on device mode
21284  * @link_info: Link info pointer in HDD adapter
21285  * @ctx: user context supplied
21286  *
21287  * Check if connection is in progress for the current adapter according to the
21288  * device mode
21289  *
21290  * Return:
21291  * * QDF_STATUS_SUCCESS if iteration should continue
21292  * * QDF_STATUS_E_ABORTED if iteration should be aborted
21293  */
21294 static QDF_STATUS
21295 hdd_is_connection_in_progress_iterator(struct wlan_hdd_link_info *link_info,
21296 				       void *ctx)
21297 {
21298 	struct hdd_station_ctx *hdd_sta_ctx;
21299 	uint8_t *sta_mac;
21300 	struct hdd_context *hdd_ctx;
21301 	mac_handle_t mac_handle;
21302 	struct hdd_station_info *sta_info, *tmp = NULL;
21303 	struct hdd_is_connection_in_progress_priv *context = ctx;
21304 	struct hdd_adapter *adapter = link_info->adapter;
21305 
21306 	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
21307 	if (!hdd_ctx)
21308 		return QDF_STATUS_E_ABORTED;
21309 
21310 	mac_handle = hdd_ctx->mac_handle;
21311 
21312 	if (!test_bit(SME_SESSION_OPENED, &link_info->link_flags) &&
21313 	    (adapter->device_mode == QDF_STA_MODE ||
21314 	     adapter->device_mode == QDF_P2P_CLIENT_MODE ||
21315 	     adapter->device_mode == QDF_P2P_DEVICE_MODE ||
21316 	     adapter->device_mode == QDF_P2P_GO_MODE ||
21317 	     adapter->device_mode == QDF_SAP_MODE))
21318 		return QDF_STATUS_SUCCESS;
21319 
21320 	if ((QDF_STA_MODE == adapter->device_mode ||
21321 	     QDF_P2P_CLIENT_MODE == adapter->device_mode ||
21322 	     QDF_P2P_DEVICE_MODE == adapter->device_mode) &&
21323 	    hdd_cm_is_connecting(link_info)) {
21324 		hdd_debug("%pK(%d) mode %d Connection is in progress",
21325 			  WLAN_HDD_GET_STATION_CTX_PTR(link_info),
21326 			  link_info->vdev_id, adapter->device_mode);
21327 
21328 		context->out_vdev_id = link_info->vdev_id;
21329 		context->out_reason = CONNECTION_IN_PROGRESS;
21330 		context->connection_in_progress = true;
21331 
21332 		return QDF_STATUS_E_ABORTED;
21333 	}
21334 
21335 	if ((QDF_STA_MODE == adapter->device_mode) &&
21336 	     sme_roaming_in_progress(mac_handle, link_info->vdev_id)) {
21337 		hdd_debug("%pK(%d) mode %d Reassociation in progress",
21338 			  WLAN_HDD_GET_STATION_CTX_PTR(link_info),
21339 			  link_info->vdev_id, adapter->device_mode);
21340 
21341 		context->out_vdev_id = link_info->vdev_id;
21342 		context->out_reason = REASSOC_IN_PROGRESS;
21343 		context->connection_in_progress = true;
21344 		return QDF_STATUS_E_ABORTED;
21345 	}
21346 
21347 	if ((QDF_STA_MODE == adapter->device_mode) ||
21348 		(QDF_P2P_CLIENT_MODE == adapter->device_mode) ||
21349 		(QDF_P2P_DEVICE_MODE == adapter->device_mode)) {
21350 		hdd_sta_ctx =
21351 			WLAN_HDD_GET_STATION_CTX_PTR(link_info);
21352 		if (hdd_cm_is_vdev_associated(link_info)
21353 		    && sme_is_sta_key_exchange_in_progress(
21354 		    mac_handle, link_info->vdev_id)) {
21355 			sta_mac = (uint8_t *)&(adapter->mac_addr.bytes[0]);
21356 			hdd_debug("client " QDF_MAC_ADDR_FMT
21357 				  " is in middle of WPS/EAPOL exchange.",
21358 				  QDF_MAC_ADDR_REF(sta_mac));
21359 
21360 			context->out_vdev_id = link_info->vdev_id;
21361 			context->out_reason = EAPOL_IN_PROGRESS;
21362 			context->connection_in_progress = true;
21363 
21364 			return QDF_STATUS_E_ABORTED;
21365 		}
21366 	} else if ((QDF_SAP_MODE == adapter->device_mode) ||
21367 			(QDF_P2P_GO_MODE == adapter->device_mode)) {
21368 		hdd_for_each_sta_ref_safe(adapter->sta_info_list, sta_info, tmp,
21369 				     STA_INFO_CONNECTION_IN_PROGRESS_ITERATOR) {
21370 			if (sta_info->peer_state !=
21371 				OL_TXRX_PEER_STATE_CONN) {
21372 				hdd_put_sta_info_ref(
21373 				     &adapter->sta_info_list, &sta_info, true,
21374 				     STA_INFO_CONNECTION_IN_PROGRESS_ITERATOR);
21375 				continue;
21376 			}
21377 
21378 			sta_mac = sta_info->sta_mac.bytes;
21379 			hdd_debug("client " QDF_MAC_ADDR_FMT
21380 				  " of SAP/GO is in middle of WPS/EAPOL exchange",
21381 				  QDF_MAC_ADDR_REF(sta_mac));
21382 
21383 			context->out_vdev_id = link_info->vdev_id;
21384 			context->out_reason = SAP_EAPOL_IN_PROGRESS;
21385 			context->connection_in_progress = true;
21386 
21387 			hdd_put_sta_info_ref(
21388 				&adapter->sta_info_list, &sta_info, true,
21389 				STA_INFO_CONNECTION_IN_PROGRESS_ITERATOR);
21390 			if (tmp)
21391 				hdd_put_sta_info_ref(
21392 				    &adapter->sta_info_list, &tmp, true,
21393 				    STA_INFO_CONNECTION_IN_PROGRESS_ITERATOR);
21394 
21395 			return QDF_STATUS_E_ABORTED;
21396 		}
21397 		if (hdd_ctx->connection_in_progress) {
21398 			hdd_debug("AP/GO: vdev %d connection is in progress",
21399 				  link_info->vdev_id);
21400 			context->out_reason = SAP_CONNECTION_IN_PROGRESS;
21401 			context->out_vdev_id = link_info->vdev_id;
21402 			context->connection_in_progress = true;
21403 
21404 			return QDF_STATUS_E_ABORTED;
21405 		}
21406 	}
21407 
21408 	if (ucfg_nan_is_enable_disable_in_progress(hdd_ctx->psoc)) {
21409 		context->out_reason = NAN_ENABLE_DISABLE_IN_PROGRESS;
21410 		context->out_vdev_id = NAN_PSEUDO_VDEV_ID;
21411 		context->connection_in_progress = true;
21412 
21413 		return QDF_STATUS_E_ABORTED;
21414 	}
21415 
21416 	return QDF_STATUS_SUCCESS;
21417 }
21418 
21419 bool hdd_is_connection_in_progress(uint8_t *out_vdev_id,
21420 				   enum scan_reject_states *out_reason)
21421 {
21422 	struct hdd_is_connection_in_progress_priv hdd_conn;
21423 	hdd_adapter_iterate_cb cb;
21424 
21425 	hdd_conn.out_vdev_id = 0;
21426 	hdd_conn.out_reason = SCAN_REJECT_DEFAULT;
21427 	hdd_conn.connection_in_progress = false;
21428 
21429 	cb = hdd_is_connection_in_progress_iterator;
21430 
21431 	hdd_adapter_iterate(cb, &hdd_conn);
21432 
21433 	if (hdd_conn.connection_in_progress && out_vdev_id && out_reason) {
21434 		*out_vdev_id = hdd_conn.out_vdev_id;
21435 		*out_reason = hdd_conn.out_reason;
21436 	}
21437 
21438 	return hdd_conn.connection_in_progress;
21439 }
21440 
21441 void hdd_restart_sap(struct wlan_hdd_link_info *link_info)
21442 {
21443 	struct hdd_hostapd_state *hapd_state;
21444 	QDF_STATUS status;
21445 	struct hdd_adapter *ap_adapter = link_info->adapter;
21446 	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(ap_adapter);
21447 	struct sap_config *sap_config;
21448 	void *sap_ctx;
21449 
21450 	sap_config =
21451 		&(WLAN_HDD_GET_AP_CTX_PTR(link_info)->sap_config);
21452 	sap_ctx = WLAN_HDD_GET_SAP_CTX_PTR(link_info);
21453 
21454 	mutex_lock(&hdd_ctx->sap_lock);
21455 	if (test_bit(SOFTAP_BSS_STARTED, &link_info->link_flags)) {
21456 		wlan_hdd_del_station(ap_adapter, NULL);
21457 		hapd_state = WLAN_HDD_GET_HOSTAP_STATE_PTR(link_info);
21458 		qdf_event_reset(&hapd_state->qdf_stop_bss_event);
21459 		if (QDF_STATUS_SUCCESS == wlansap_stop_bss(sap_ctx)) {
21460 			status = qdf_wait_single_event(&hapd_state->qdf_stop_bss_event,
21461 						       SME_CMD_STOP_BSS_TIMEOUT);
21462 
21463 			if (!QDF_IS_STATUS_SUCCESS(status)) {
21464 				hdd_err("SAP Stop Failed");
21465 				goto end;
21466 			}
21467 		}
21468 		clear_bit(SOFTAP_BSS_STARTED, &link_info->link_flags);
21469 		policy_mgr_decr_session_set_pcl(hdd_ctx->psoc,
21470 			ap_adapter->device_mode, link_info->vdev_id);
21471 		hdd_green_ap_start_state_mc(hdd_ctx, ap_adapter->device_mode,
21472 					    false);
21473 		hdd_err("SAP Stop Success");
21474 
21475 		if (0 != wlan_hdd_cfg80211_update_apies(link_info)) {
21476 			hdd_err("SAP Not able to set AP IEs");
21477 			goto end;
21478 		}
21479 
21480 		status = wlan_hdd_mlo_sap_reinit(link_info);
21481 		if (QDF_IS_STATUS_ERROR(status)) {
21482 			hdd_err("SAP Not able to do mlo attach");
21483 			goto deinit_mlo;
21484 		}
21485 
21486 		qdf_event_reset(&hapd_state->qdf_event);
21487 		status = wlansap_start_bss(sap_ctx, hdd_hostapd_sap_event_cb,
21488 					   sap_config, ap_adapter->dev);
21489 		if (QDF_IS_STATUS_ERROR(status)) {
21490 			hdd_err("SAP Start Bss fail");
21491 			goto deinit_mlo;
21492 		}
21493 
21494 		hdd_info("Waiting for SAP to start");
21495 		status = qdf_wait_single_event(&hapd_state->qdf_event,
21496 					       SME_CMD_START_BSS_TIMEOUT);
21497 		if (!QDF_IS_STATUS_SUCCESS(status)) {
21498 			hdd_err("SAP Start failed");
21499 			goto deinit_mlo;
21500 		}
21501 		wlansap_reset_sap_config_add_ie(sap_config, eUPDATE_IE_ALL);
21502 		hdd_err("SAP Start Success");
21503 		set_bit(SOFTAP_BSS_STARTED, &link_info->link_flags);
21504 		if (hapd_state->bss_state == BSS_START) {
21505 			policy_mgr_incr_active_session(hdd_ctx->psoc,
21506 						ap_adapter->device_mode,
21507 						link_info->vdev_id);
21508 			hdd_green_ap_start_state_mc(hdd_ctx,
21509 						    ap_adapter->device_mode,
21510 						    true);
21511 		}
21512 	}
21513 	mutex_unlock(&hdd_ctx->sap_lock);
21514 	return;
21515 
21516 deinit_mlo:
21517 	wlan_hdd_mlo_reset(link_info);
21518 end:
21519 	wlansap_reset_sap_config_add_ie(sap_config, eUPDATE_IE_ALL);
21520 	mutex_unlock(&hdd_ctx->sap_lock);
21521 }
21522 
21523 /**
21524  * hdd_set_connection_in_progress() - to set the connection in
21525  * progress flag
21526  * @value: value to set
21527  *
21528  * This function will set the passed value to connection in progress flag.
21529  * If value is previously being set to true then no need to set it again.
21530  *
21531  * Return: true if value is being set correctly and false otherwise.
21532  */
21533 bool hdd_set_connection_in_progress(bool value)
21534 {
21535 	bool status = true;
21536 	struct hdd_context *hdd_ctx;
21537 
21538 	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
21539 	if (!hdd_ctx)
21540 		return false;
21541 
21542 	qdf_spin_lock(&hdd_ctx->connection_status_lock);
21543 	/*
21544 	 * if the value is set to true previously and if someone is
21545 	 * trying to make it true again then it could be some race
21546 	 * condition being triggered. Avoid this situation by returning
21547 	 * false
21548 	 */
21549 	if (hdd_ctx->connection_in_progress && value)
21550 		status = false;
21551 	else
21552 		hdd_ctx->connection_in_progress = value;
21553 	qdf_spin_unlock(&hdd_ctx->connection_status_lock);
21554 	return status;
21555 }
21556 
21557 int wlan_hdd_send_mcc_vdev_quota(struct hdd_adapter *adapter, int set_value)
21558 {
21559 	if (!adapter) {
21560 		hdd_err("Invalid adapter");
21561 		return -EINVAL;
21562 	}
21563 	hdd_info("send mcc vdev quota to fw: %d", set_value);
21564 	sme_cli_set_command(adapter->deflink->vdev_id,
21565 			    WMA_VDEV_MCC_SET_TIME_QUOTA,
21566 			    set_value, VDEV_CMD);
21567 	return 0;
21568 
21569 }
21570 
21571 int wlan_hdd_send_mcc_latency(struct hdd_adapter *adapter, int set_value)
21572 {
21573 	if (!adapter) {
21574 		hdd_err("Invalid adapter");
21575 		return -EINVAL;
21576 	}
21577 
21578 	hdd_info("Send MCC latency WMA: %d", set_value);
21579 	sme_cli_set_command(adapter->deflink->vdev_id,
21580 			    WMA_VDEV_MCC_SET_TIME_LATENCY,
21581 			    set_value, VDEV_CMD);
21582 	return 0;
21583 }
21584 
21585 struct wlan_hdd_link_info *
21586 wlan_hdd_get_link_info_from_vdev(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id)
21587 {
21588 	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
21589 	struct wlan_hdd_link_info *link_info;
21590 
21591 	/*
21592 	 * Currently PSOC is not being used. But this logic will
21593 	 * change once we have the converged implementation of
21594 	 * HDD context per PSOC in place. This would break if
21595 	 * multiple vdev objects reuse the vdev id.
21596 	 */
21597 	link_info = hdd_get_link_info_by_vdev(hdd_ctx, vdev_id);
21598 	if (!link_info) {
21599 		hdd_err("Get adapter by vdev id failed");
21600 		return NULL;
21601 	}
21602 
21603 	return link_info;
21604 }
21605 
21606 int hdd_get_rssi_snr_by_bssid(mac_handle_t mac_handle, const uint8_t *bssid,
21607 			      int8_t *rssi, int8_t *snr)
21608 {
21609 	QDF_STATUS status;
21610 
21611 	status = sme_get_rssi_snr_by_bssid(mac_handle, bssid, rssi, snr);
21612 	if (QDF_IS_STATUS_ERROR(status)) {
21613 		hdd_debug("sme_get_rssi_snr_by_bssid failed");
21614 		return -EINVAL;
21615 	}
21616 
21617 	return 0;
21618 }
21619 
21620 /**
21621  * hdd_reset_limit_off_chan() - reset limit off-channel command parameters
21622  * @adapter: HDD adapter
21623  *
21624  * Return: 0 on success and non zero value on failure
21625  */
21626 int hdd_reset_limit_off_chan(struct hdd_adapter *adapter)
21627 {
21628 	struct hdd_context *hdd_ctx;
21629 	int ret;
21630 	QDF_STATUS status;
21631 	uint8_t sys_pref = 0;
21632 
21633 	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
21634 	ret = wlan_hdd_validate_context(hdd_ctx);
21635 	if (ret < 0)
21636 		return ret;
21637 
21638 	ucfg_policy_mgr_get_sys_pref(hdd_ctx->psoc,
21639 				     &sys_pref);
21640 	/* set the system preferece to default */
21641 	policy_mgr_set_cur_conc_system_pref(hdd_ctx->psoc, sys_pref);
21642 
21643 	/* clear the bitmap */
21644 	adapter->active_ac = 0;
21645 
21646 	hdd_debug("reset ac_bitmap for session %hu active_ac %0x",
21647 		  adapter->deflink->vdev_id, adapter->active_ac);
21648 
21649 	status = sme_send_limit_off_channel_params(hdd_ctx->mac_handle,
21650 						   adapter->deflink->vdev_id,
21651 						   false, 0, 0, false);
21652 	if (!QDF_IS_STATUS_SUCCESS(status)) {
21653 		hdd_err("failed to reset limit off chan params");
21654 		ret = -EINVAL;
21655 	}
21656 
21657 	return ret;
21658 }
21659 
21660 void hdd_hidden_ssid_enable_roaming(hdd_handle_t hdd_handle, uint8_t vdev_id)
21661 {
21662 	struct hdd_context *hdd_ctx = hdd_handle_to_context(hdd_handle);
21663 	struct wlan_hdd_link_info *link_info;
21664 
21665 	link_info = hdd_get_link_info_by_vdev(hdd_ctx, vdev_id);
21666 	if (!link_info) {
21667 		hdd_err("Invalid vdev");
21668 		return;
21669 	}
21670 	/* enable roaming on all adapters once hdd get hidden ssid rsp */
21671 	wlan_hdd_set_roaming_state(link_info, RSO_START_BSS, true);
21672 }
21673 
21674 #ifdef WLAN_FEATURE_PKT_CAPTURE
21675 bool wlan_hdd_is_mon_concurrency(void)
21676 {
21677 	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
21678 
21679 	if (!hdd_ctx)
21680 		return -EINVAL;
21681 
21682 	if (ucfg_pkt_capture_get_mode(hdd_ctx->psoc) !=
21683 						PACKET_CAPTURE_MODE_DISABLE) {
21684 		if (policy_mgr_get_concurrency_mode(hdd_ctx->psoc) ==
21685 		    (QDF_STA_MASK | QDF_MONITOR_MASK)) {
21686 			hdd_err("STA + MON mode is UP");
21687 			return true;
21688 		}
21689 	}
21690 	return false;
21691 }
21692 
21693 void wlan_hdd_del_monitor(struct hdd_context *hdd_ctx,
21694 			  struct hdd_adapter *adapter, bool rtnl_held)
21695 {
21696 	wlan_hdd_release_intf_addr(hdd_ctx, adapter->mac_addr.bytes);
21697 	hdd_stop_adapter(hdd_ctx, adapter);
21698 	hdd_close_adapter(hdd_ctx, adapter, true);
21699 
21700 	hdd_open_p2p_interface(hdd_ctx);
21701 }
21702 
21703 void
21704 wlan_hdd_del_p2p_interface(struct hdd_context *hdd_ctx)
21705 {
21706 	struct hdd_adapter *adapter = NULL, *next_adapter = NULL;
21707 	struct osif_vdev_sync *vdev_sync;
21708 
21709 	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
21710 					   NET_DEV_HOLD_DEL_P2P_INTERFACE) {
21711 		if (adapter->device_mode == QDF_P2P_CLIENT_MODE ||
21712 		    adapter->device_mode == QDF_P2P_DEVICE_MODE ||
21713 		    adapter->device_mode == QDF_P2P_GO_MODE) {
21714 			vdev_sync = osif_vdev_sync_unregister(adapter->dev);
21715 			if (vdev_sync)
21716 				osif_vdev_sync_wait_for_ops(vdev_sync);
21717 
21718 			hdd_adapter_dev_put_debug(
21719 				adapter, NET_DEV_HOLD_DEL_P2P_INTERFACE);
21720 
21721 			hdd_clean_up_interface(hdd_ctx, adapter);
21722 
21723 			if (vdev_sync)
21724 				osif_vdev_sync_destroy(vdev_sync);
21725 		} else
21726 			hdd_adapter_dev_put_debug(
21727 				adapter, NET_DEV_HOLD_DEL_P2P_INTERFACE);
21728 	}
21729 }
21730 
21731 #endif /* WLAN_FEATURE_PKT_CAPTURE */
21732 
21733 bool wlan_hdd_is_session_type_monitor(uint8_t session_type)
21734 {
21735 	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
21736 
21737 	if (!hdd_ctx) {
21738 		cds_err("HDD context is NULL");
21739 		return false;
21740 	}
21741 
21742 	if (cds_get_conparam() != QDF_GLOBAL_MONITOR_MODE &&
21743 	    session_type == QDF_MONITOR_MODE)
21744 		return true;
21745 	else
21746 		return false;
21747 }
21748 
21749 int
21750 wlan_hdd_add_monitor_check(struct hdd_context *hdd_ctx,
21751 			   struct hdd_adapter **adapter,
21752 			   const char *name, bool rtnl_held,
21753 			   unsigned char name_assign_type)
21754 {
21755 	struct hdd_adapter *sta_adapter;
21756 	struct hdd_adapter *mon_adapter;
21757 	uint8_t num_open_session = 0;
21758 	QDF_STATUS status;
21759 	struct hdd_adapter_create_param params = {0};
21760 
21761 	sta_adapter = hdd_get_adapter(hdd_ctx, QDF_STA_MODE);
21762 	if (!sta_adapter) {
21763 		hdd_err("No station adapter");
21764 		return -EINVAL;
21765 	}
21766 
21767 	status = policy_mgr_check_mon_concurrency(hdd_ctx->psoc);
21768 
21769 	if (QDF_IS_STATUS_ERROR(status))
21770 		return -EINVAL;
21771 
21772 	if (hdd_is_connection_in_progress(NULL, NULL)) {
21773 		hdd_err("cannot add monitor mode, Connection in progress");
21774 		return -EINVAL;
21775 	}
21776 
21777 	if (!ucfg_dp_is_local_pkt_capture_enabled(hdd_ctx->psoc) &&
21778 	    ucfg_mlme_is_sta_mon_conc_supported(hdd_ctx->psoc)) {
21779 		num_open_session = policy_mgr_mode_specific_connection_count(
21780 						hdd_ctx->psoc,
21781 						PM_STA_MODE,
21782 						NULL);
21783 
21784 		if (num_open_session) {
21785 			/* Try disconnecting if already in connected state */
21786 			wlan_hdd_cm_issue_disconnect(sta_adapter->deflink,
21787 						     REASON_UNSPEC_FAILURE,
21788 						     true);
21789 		}
21790 	}
21791 
21792 	if (ucfg_pkt_capture_get_mode(hdd_ctx->psoc) !=
21793 						PACKET_CAPTURE_MODE_DISABLE)
21794 		wlan_hdd_del_p2p_interface(hdd_ctx);
21795 
21796 	params.is_add_virtual_iface = 1;
21797 
21798 	mon_adapter = hdd_open_adapter(hdd_ctx, QDF_MONITOR_MODE, name,
21799 				       wlan_hdd_get_intf_addr(
21800 				       hdd_ctx,
21801 				       QDF_MONITOR_MODE),
21802 				       name_assign_type, rtnl_held, &params);
21803 	if (!mon_adapter) {
21804 		hdd_err("hdd_open_adapter failed");
21805 		if (ucfg_pkt_capture_get_mode(hdd_ctx->psoc) !=
21806 						PACKET_CAPTURE_MODE_DISABLE)
21807 			hdd_open_p2p_interface(hdd_ctx);
21808 		return -EINVAL;
21809 	}
21810 
21811 	if (mon_adapter)
21812 		hdd_set_idle_ps_config(hdd_ctx, false);
21813 
21814 	*adapter = mon_adapter;
21815 	return 0;
21816 }
21817 
21818 #ifdef FEATURE_MONITOR_MODE_SUPPORT
21819 
21820 void hdd_sme_monitor_mode_callback(uint8_t vdev_id)
21821 {
21822 	struct hdd_context *hdd_ctx;
21823 	struct hdd_adapter *adapter;
21824 	struct wlan_hdd_link_info *link_info;
21825 
21826 	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
21827 	if (!hdd_ctx)
21828 		return;
21829 
21830 	link_info = hdd_get_link_info_by_vdev(hdd_ctx, vdev_id);
21831 	if (!link_info) {
21832 		hdd_err_rl("NULL adapter");
21833 		return;
21834 	}
21835 
21836 	adapter = link_info->adapter;
21837 	if (adapter->magic != WLAN_HDD_ADAPTER_MAGIC) {
21838 		hdd_err_rl("Invalid magic");
21839 		return;
21840 	}
21841 
21842 	qdf_event_set(&adapter->qdf_monitor_mode_vdev_up_event);
21843 
21844 	hdd_debug("monitor mode vdev up completed");
21845 	adapter->monitor_mode_vdev_up_in_progress = false;
21846 }
21847 
21848 QDF_STATUS hdd_monitor_mode_qdf_create_event(struct hdd_adapter *adapter,
21849 					     uint8_t session_type)
21850 {
21851 	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
21852 
21853 	if (session_type == QDF_MONITOR_MODE) {
21854 		qdf_status = qdf_event_create(
21855 				&adapter->qdf_monitor_mode_vdev_up_event);
21856 	}
21857 	return qdf_status;
21858 }
21859 
21860 QDF_STATUS hdd_monitor_mode_vdev_status(struct hdd_adapter *adapter)
21861 {
21862 	QDF_STATUS status = QDF_STATUS_SUCCESS;
21863 
21864 	if (!adapter->monitor_mode_vdev_up_in_progress)
21865 		return status;
21866 
21867 	/* block on a completion variable until vdev up success*/
21868 	status = qdf_wait_for_event_completion(
21869 				       &adapter->qdf_monitor_mode_vdev_up_event,
21870 					WLAN_MONITOR_MODE_VDEV_UP_EVT);
21871 	if (QDF_IS_STATUS_ERROR(status)) {
21872 		hdd_err_rl("monitor mode vdev up event time out vdev id: %d",
21873 			   adapter->deflink->vdev_id);
21874 		if (adapter->qdf_monitor_mode_vdev_up_event.force_set)
21875 			/*
21876 			 * SSR/PDR has caused shutdown, which has
21877 			 * forcefully set the event.
21878 			 */
21879 			hdd_err_rl("monitor mode vdev up event forcefully set");
21880 		else if (status == QDF_STATUS_E_TIMEOUT)
21881 			hdd_err_rl("mode vdev up event timed out");
21882 		else
21883 			hdd_err_rl("Failed to wait for monitor vdev up(status-%d)",
21884 				   status);
21885 
21886 		adapter->monitor_mode_vdev_up_in_progress = false;
21887 		return status;
21888 	}
21889 
21890 	return QDF_STATUS_SUCCESS;
21891 }
21892 #endif
21893 
21894 #if defined(CLD_PM_QOS) && defined(WLAN_FEATURE_LL_MODE)
21895 void hdd_beacon_latency_event_cb(uint32_t latency_level)
21896 {
21897 	struct hdd_context *hdd_ctx;
21898 
21899 	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
21900 	if (!hdd_ctx)
21901 		return;
21902 
21903 	if (latency_level ==
21904 		QCA_WLAN_VENDOR_ATTR_CONFIG_LATENCY_LEVEL_ULTRALOW)
21905 		wlan_hdd_set_pm_qos_request(hdd_ctx, true);
21906 	else
21907 		wlan_hdd_set_pm_qos_request(hdd_ctx, false);
21908 }
21909 #endif
21910 
21911 #ifdef CONFIG_WLAN_DEBUG_CRASH_INJECT
21912 int hdd_crash_inject(struct hdd_adapter *adapter, uint32_t v1, uint32_t v2)
21913 {
21914 	struct hdd_context *hdd_ctx;
21915 	int ret;
21916 	bool crash_inject;
21917 	QDF_STATUS status;
21918 
21919 	hdd_debug("v1: %d v2: %d", v1, v2);
21920 	pr_err("SSR is triggered by CRASH_INJECT: %d %d\n",
21921 	       v1, v2);
21922 	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
21923 
21924 	status = ucfg_mlme_get_crash_inject(hdd_ctx->psoc, &crash_inject);
21925 	if (QDF_IS_STATUS_ERROR(status)) {
21926 		hdd_err("Failed to get crash inject ini config");
21927 		return 0;
21928 	}
21929 
21930 	if (!crash_inject) {
21931 		hdd_err("Crash Inject ini disabled, Ignore Crash Inject");
21932 		return 0;
21933 	}
21934 
21935 	if (v1 == 3) {
21936 		cds_trigger_recovery(QDF_REASON_UNSPECIFIED);
21937 		return 0;
21938 	}
21939 	ret = wma_cli_set2_command(adapter->deflink->vdev_id,
21940 				   GEN_PARAM_CRASH_INJECT,
21941 				   v1, v2, GEN_CMD);
21942 	return ret;
21943 }
21944 #endif
21945 
21946 static const struct hdd_chwidth_info chwidth_info[] = {
21947 	[NL80211_CHAN_WIDTH_20_NOHT] = {
21948 		.ch_bw = HW_MODE_20_MHZ,
21949 		.ch_bw_str = "20MHz",
21950 		.phy_chwidth = CH_WIDTH_20MHZ,
21951 	},
21952 	[NL80211_CHAN_WIDTH_20] = {
21953 		.sir_chwidth_valid = true,
21954 		.sir_chwidth = eHT_CHANNEL_WIDTH_20MHZ,
21955 		.ch_bw = HW_MODE_20_MHZ,
21956 		.ch_bw_str = "20MHz",
21957 		.phy_chwidth = CH_WIDTH_20MHZ,
21958 		.bonding_mode = WNI_CFG_CHANNEL_BONDING_MODE_DISABLE,
21959 	},
21960 	[NL80211_CHAN_WIDTH_40] = {
21961 		.sir_chwidth_valid = true,
21962 		.sir_chwidth = eHT_CHANNEL_WIDTH_40MHZ,
21963 		.ch_bw = HW_MODE_40_MHZ,
21964 		.ch_bw_str = "40MHz",
21965 		.phy_chwidth = CH_WIDTH_40MHZ,
21966 		.bonding_mode = WNI_CFG_CHANNEL_BONDING_MODE_ENABLE,
21967 	},
21968 	[NL80211_CHAN_WIDTH_80] = {
21969 		.sir_chwidth_valid = true,
21970 		.sir_chwidth = eHT_CHANNEL_WIDTH_80MHZ,
21971 		.ch_bw = HW_MODE_80_MHZ,
21972 		.ch_bw_str = "80MHz",
21973 		.phy_chwidth = CH_WIDTH_80MHZ,
21974 		.bonding_mode = WNI_CFG_CHANNEL_BONDING_MODE_ENABLE,
21975 	},
21976 	[NL80211_CHAN_WIDTH_80P80] = {
21977 		.sir_chwidth_valid = true,
21978 		.sir_chwidth = eHT_CHANNEL_WIDTH_80P80MHZ,
21979 		.ch_bw = HW_MODE_80_PLUS_80_MHZ,
21980 		.ch_bw_str = "(80 + 80)MHz",
21981 		.phy_chwidth = CH_WIDTH_80P80MHZ,
21982 		.bonding_mode = WNI_CFG_CHANNEL_BONDING_MODE_ENABLE,
21983 	},
21984 	[NL80211_CHAN_WIDTH_160] = {
21985 		.sir_chwidth_valid = true,
21986 		.sir_chwidth = eHT_CHANNEL_WIDTH_160MHZ,
21987 		.ch_bw = HW_MODE_160_MHZ,
21988 		.ch_bw_str = "160MHz",
21989 		.phy_chwidth = CH_WIDTH_160MHZ,
21990 		.bonding_mode = WNI_CFG_CHANNEL_BONDING_MODE_ENABLE,
21991 	},
21992 	[NL80211_CHAN_WIDTH_5] = {
21993 		.ch_bw = HW_MODE_5_MHZ,
21994 		.ch_bw_str = "5MHz",
21995 		.phy_chwidth = CH_WIDTH_5MHZ,
21996 	},
21997 	[NL80211_CHAN_WIDTH_10] = {
21998 		.ch_bw = HW_MODE_10_MHZ,
21999 		.ch_bw_str = "10MHz",
22000 		.phy_chwidth = CH_WIDTH_10MHZ,
22001 	},
22002 #if defined(WLAN_FEATURE_11BE) && defined(CFG80211_11BE_BASIC)
22003 	[NL80211_CHAN_WIDTH_320] = {
22004 		.sir_chwidth_valid = true,
22005 		.sir_chwidth = eHT_CHANNEL_WIDTH_320MHZ,
22006 		.ch_bw = HW_MODE_320_MHZ,
22007 		.ch_bw_str = "320MHz",
22008 		.phy_chwidth = CH_WIDTH_320MHZ,
22009 		.bonding_mode = WNI_CFG_CHANNEL_BONDING_MODE_ENABLE,
22010 	},
22011 #endif
22012 };
22013 
22014 enum eSirMacHTChannelWidth
22015 hdd_nl80211_chwidth_to_chwidth(uint8_t nl80211_chwidth)
22016 {
22017 	if (nl80211_chwidth >= ARRAY_SIZE(chwidth_info) ||
22018 	    !chwidth_info[nl80211_chwidth].sir_chwidth_valid) {
22019 		hdd_err("Unsupported channel width %d", nl80211_chwidth);
22020 		return -EINVAL;
22021 	}
22022 
22023 	return chwidth_info[nl80211_chwidth].sir_chwidth;
22024 }
22025 
22026 uint8_t hdd_chwidth_to_nl80211_chwidth(enum eSirMacHTChannelWidth chwidth)
22027 {
22028 	int i;
22029 
22030 	for (i = 0; i < ARRAY_SIZE(chwidth_info); i++) {
22031 		if (chwidth_info[i].sir_chwidth_valid &&
22032 		    chwidth_info[i].sir_chwidth == chwidth)
22033 			return i;
22034 	}
22035 
22036 	hdd_err("Unsupported channel width %d", chwidth);
22037 	return 0xFF;
22038 }
22039 
22040 uint8_t hdd_phy_chwidth_to_nl80211_chwidth(enum phy_ch_width chwidth)
22041 {
22042 	int i;
22043 
22044 	for (i = 0; i < ARRAY_SIZE(chwidth_info); i++) {
22045 		if (chwidth_info[i].sir_chwidth_valid &&
22046 		    chwidth_info[i].phy_chwidth == chwidth)
22047 			return i;
22048 	}
22049 
22050 	hdd_err("Unsupported channel width %d", chwidth);
22051 	return 0xFF;
22052 }
22053 
22054 enum hw_mode_bandwidth wlan_hdd_get_channel_bw(enum nl80211_chan_width width)
22055 {
22056 	if (width >= ARRAY_SIZE(chwidth_info)) {
22057 		hdd_err("Invalid width: %d, using default 20MHz", width);
22058 		return HW_MODE_20_MHZ;
22059 	}
22060 
22061 	return chwidth_info[width].ch_bw;
22062 }
22063 
22064 uint8_t *hdd_ch_width_str(enum phy_ch_width ch_width)
22065 {
22066 	int i;
22067 
22068 	for (i = 0; i < ARRAY_SIZE(chwidth_info); i++) {
22069 		if (chwidth_info[i].phy_chwidth == ch_width)
22070 			return chwidth_info[i].ch_bw_str;
22071 	}
22072 
22073 	return "UNKNOWN";
22074 }
22075 
22076 int hdd_we_set_ch_width(struct wlan_hdd_link_info *link_info, int ch_width)
22077 {
22078 	int i;
22079 	uint8_t link_id = 0xFF;
22080 
22081 	/* updating channel bonding only on 5Ghz */
22082 	hdd_debug("wmi_vdev_param_chwidth val %d", ch_width);
22083 
22084 	for (i = 0; i < ARRAY_SIZE(chwidth_info); i++) {
22085 		if (!chwidth_info[i].sir_chwidth_valid ||
22086 		    chwidth_info[i].sir_chwidth != ch_width)
22087 			continue;
22088 
22089 		return hdd_update_channel_width(link_info, ch_width,
22090 						chwidth_info[i].bonding_mode,
22091 						link_id, false);
22092 	}
22093 
22094 	hdd_err("Invalid ch_width %d", ch_width);
22095 	return -EINVAL;
22096 }
22097 
22098 /* Register the module init/exit functions */
22099 module_init(hdd_module_init);
22100 module_exit(hdd_module_exit);
22101 
22102 MODULE_LICENSE("Dual BSD/GPL");
22103 MODULE_AUTHOR("Qualcomm Atheros, Inc.");
22104 MODULE_DESCRIPTION("WLAN HOST DEVICE DRIVER");
22105 
22106 const struct kernel_param_ops con_mode_ops = {
22107 	.set = con_mode_handler,
22108 	.get = param_get_int,
22109 };
22110 
22111 #ifdef FEATURE_WLAN_RESIDENT_DRIVER
22112 EXPORT_SYMBOL(con_mode_ops);
22113 #endif
22114 
22115 const struct kernel_param_ops con_mode_ftm_ops = {
22116 	.set = con_mode_handler_ftm,
22117 	.get = param_get_int,
22118 };
22119 
22120 #ifdef FEATURE_WLAN_RESIDENT_DRIVER
22121 EXPORT_SYMBOL(con_mode_ftm_ops);
22122 #endif
22123 
22124 #ifdef WLAN_FEATURE_EPPING
22125 static const struct kernel_param_ops con_mode_epping_ops = {
22126 	.set = con_mode_handler_epping,
22127 	.get = param_get_int,
22128 };
22129 #endif
22130 
22131 static const struct kernel_param_ops fwpath_ops = {
22132 	.set = fwpath_changed_handler,
22133 	.get = param_get_string,
22134 };
22135 
22136 static int __pcie_set_gen_speed_handler(void)
22137 {
22138 	int ret;
22139 	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
22140 
22141 	ret = wlan_hdd_validate_context(hdd_ctx);
22142 	if (ret)
22143 		return ret;
22144 
22145 	hdd_info_rl("Received PCIe gen speed %d", pcie_gen_speed);
22146 	if (pcie_gen_speed <= HDD_INVALID_MIN_PCIE_GEN_SPEED ||
22147 	    pcie_gen_speed >= HDD_INVALID_MAX_PCIE_GEN_SPEED) {
22148 		hdd_err_rl("invalid pcie gen speed %d", pcie_gen_speed);
22149 		return -EINVAL;
22150 	}
22151 
22152 	hdd_ctx->current_pcie_gen_speed = pcie_gen_speed;
22153 
22154 	return 0;
22155 }
22156 
22157 static int pcie_set_gen_speed_handler(const char *kmessage,
22158 				      const struct kernel_param *kp)
22159 {
22160 	struct osif_driver_sync *driver_sync;
22161 	int ret;
22162 
22163 	ret = osif_driver_sync_op_start(&driver_sync);
22164 	if (ret)
22165 		return ret;
22166 
22167 	ret = param_set_int(kmessage, kp);
22168 	if (ret) {
22169 		hdd_err_rl("param set int failed %d", ret);
22170 		goto out;
22171 	}
22172 
22173 	ret = __pcie_set_gen_speed_handler();
22174 
22175 out:
22176 	osif_driver_sync_op_stop(driver_sync);
22177 
22178 	return ret;
22179 }
22180 
22181 static const struct kernel_param_ops pcie_gen_speed_ops = {
22182 	.set = pcie_set_gen_speed_handler,
22183 	.get = param_get_int,
22184 };
22185 
22186 module_param_cb(con_mode, &con_mode_ops, &con_mode,
22187 		S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
22188 
22189 module_param_cb(con_mode_ftm, &con_mode_ftm_ops, &con_mode_ftm,
22190 		S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
22191 
22192 module_param_cb(pcie_gen_speed, &pcie_gen_speed_ops, &pcie_gen_speed,
22193 		S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
22194 
22195 #ifdef WLAN_FEATURE_EPPING
22196 module_param_cb(con_mode_epping, &con_mode_epping_ops,
22197 		&con_mode_epping, 0644);
22198 #endif
22199 
22200 module_param_cb(fwpath, &fwpath_ops, &fwpath,
22201 		S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
22202 
22203 module_param(enable_dfs_chan_scan, int, S_IRUSR | S_IRGRP | S_IROTH);
22204 
22205 module_param(enable_11d, int, S_IRUSR | S_IRGRP | S_IROTH);
22206 
22207 module_param(country_code, charp, S_IRUSR | S_IRGRP | S_IROTH);
22208 
22209 static int timer_multiplier_get_handler(char *buffer,
22210 					const struct kernel_param *kp)
22211 {
22212 	return scnprintf(buffer, PAGE_SIZE, "%u", qdf_timer_get_multiplier());
22213 }
22214 
22215 static int timer_multiplier_set_handler(const char *kmessage,
22216 					const struct kernel_param *kp)
22217 {
22218 	QDF_STATUS status;
22219 	uint32_t scalar;
22220 
22221 	status = qdf_uint32_parse(kmessage, &scalar);
22222 	if (QDF_IS_STATUS_ERROR(status))
22223 		return qdf_status_to_os_return(status);
22224 
22225 	if (!cfg_in_range(CFG_TIMER_MULTIPLIER, scalar))
22226 		return -ERANGE;
22227 
22228 	qdf_timer_set_multiplier(scalar);
22229 
22230 	return 0;
22231 }
22232 
22233 static const struct kernel_param_ops timer_multiplier_ops = {
22234 	.get = timer_multiplier_get_handler,
22235 	.set = timer_multiplier_set_handler,
22236 };
22237 
22238 module_param_cb(timer_multiplier, &timer_multiplier_ops, NULL, 0644);
22239