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 
hdd_adapter_is_ap(struct hdd_adapter * adapter)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 
hdd_common_roam_callback(struct wlan_objmgr_psoc * psoc,uint8_t session_id,struct csr_roam_info * roam_info,eRoamCmdStatus roam_status,eCsrRoamResult roam_result)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 
hdd_start_complete(int ret)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
wlan_hdd_lpc_del_monitor_interface(struct hdd_context * hdd_ctx,bool is_virtual_iface)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 
wlan_hdd_lpc_handle_concurrency(struct hdd_context * hdd_ctx,bool is_virtual_iface)594 void wlan_hdd_lpc_handle_concurrency(struct hdd_context *hdd_ctx,
595 				     bool is_virtual_iface)
596 {
597 	wlan_hdd_lpc_del_monitor_interface(hdd_ctx, is_virtual_iface);
598 }
599 
hdd_lpc_is_work_scheduled(struct hdd_context * hdd_ctx)600 bool hdd_lpc_is_work_scheduled(struct hdd_context *hdd_ctx)
601 {
602 	return hdd_ctx->lpc_info.lpc_wk_scheduled;
603 }
604 
hdd_lpc_work_handler(void * arg)605 static void hdd_lpc_work_handler(void *arg)
606 {
607 	struct hdd_context *hdd_ctx = (struct hdd_context *)arg;
608 	struct hdd_adapter *adapter;
609 	struct osif_vdev_sync *vdev_sync;
610 	int errno;
611 
612 	if (!hdd_ctx)
613 		return;
614 
615 	adapter = hdd_ctx->lpc_info.mon_adapter;
616 	if (!adapter) {
617 		hdd_err("There is no monitor adapter");
618 		return;
619 	}
620 
621 	errno = osif_vdev_sync_trans_start_wait(adapter->dev, &vdev_sync);
622 	if (errno)
623 		return;
624 
625 	osif_vdev_sync_unregister(adapter->dev);
626 	osif_vdev_sync_wait_for_ops(vdev_sync);
627 
628 	hdd_close_adapter(hdd_ctx, adapter, true);
629 	hdd_ctx->lpc_info.lpc_wk_scheduled = false;
630 
631 	osif_vdev_sync_trans_stop(vdev_sync);
632 	osif_vdev_sync_destroy(vdev_sync);
633 }
634 
635 static inline
hdd_lp_create_work(struct hdd_context * hdd_ctx)636 void hdd_lp_create_work(struct hdd_context *hdd_ctx)
637 {
638 	hdd_ctx->lpc_info.lpc_wk_scheduled = false;
639 	qdf_create_work(0, &hdd_ctx->lpc_info.lpc_wk, hdd_lpc_work_handler,
640 			hdd_ctx);
641 }
642 
643 static inline
hdd_lpc_delete_work(struct hdd_context * hdd_ctx)644 void hdd_lpc_delete_work(struct hdd_context *hdd_ctx)
645 {
646 	qdf_flush_work(&hdd_ctx->lpc_info.lpc_wk);
647 	hdd_ctx->lpc_info.lpc_wk_scheduled = false;
648 	qdf_destroy_work(NULL, &hdd_ctx->lpc_info.lpc_wk);
649 }
650 
651 #else
652 static inline
hdd_lp_create_work(struct hdd_context * hdd_ctx)653 void hdd_lp_create_work(struct hdd_context *hdd_ctx)
654 {
655 }
656 
657 static inline
hdd_lpc_delete_work(struct hdd_context * hdd_ctx)658 void hdd_lpc_delete_work(struct hdd_context *hdd_ctx)
659 {
660 }
661 
662 static inline
wlan_hdd_lpc_del_monitor_interface(struct hdd_context * hdd_ctx,bool is_virtual_iface)663 void wlan_hdd_lpc_del_monitor_interface(struct hdd_context *hdd_ctx,
664 					bool is_virtual_iface)
665 {
666 }
667 #endif
668 
669 #ifdef QCA_HL_NETDEV_FLOW_CONTROL
wlan_hdd_mod_fc_timer(struct hdd_adapter * adapter,enum netif_action_type action)670 void wlan_hdd_mod_fc_timer(struct hdd_adapter *adapter,
671 			   enum netif_action_type action)
672 {
673 	struct hdd_stats *hdd_stats;
674 
675 	if (!adapter->tx_flow_timer_initialized)
676 		return;
677 
678 	hdd_stats = &adapter->deflink->hdd_stats;
679 	if (action == WLAN_WAKE_NON_PRIORITY_QUEUE) {
680 		qdf_mc_timer_stop(&adapter->tx_flow_control_timer);
681 		hdd_stats->tx_rx_stats.is_txflow_paused = false;
682 		hdd_stats->tx_rx_stats.txflow_unpause_cnt++;
683 	} else if (action == WLAN_STOP_NON_PRIORITY_QUEUE) {
684 		QDF_STATUS status =
685 		qdf_mc_timer_start(&adapter->tx_flow_control_timer,
686 				   WLAN_HDD_TX_FLOW_CONTROL_OS_Q_BLOCK_TIME);
687 
688 		if (!QDF_IS_STATUS_SUCCESS(status))
689 			hdd_err("Failed to start tx_flow_control_timer");
690 		else
691 			hdd_stats->tx_rx_stats.txflow_timer_cnt++;
692 
693 		hdd_stats->tx_rx_stats.txflow_pause_cnt++;
694 		hdd_stats->tx_rx_stats.is_txflow_paused = true;
695 	}
696 }
697 #endif /* QCA_HL_NETDEV_FLOW_CONTROL */
698 
699 /**
700  * wlan_hdd_txrx_pause_cb() - pause callback from txrx layer
701  * @vdev_id: vdev_id
702  * @action: action type
703  * @reason: reason type
704  *
705  * Return: none
706  */
wlan_hdd_txrx_pause_cb(uint8_t vdev_id,enum netif_action_type action,enum netif_reason_type reason)707 void wlan_hdd_txrx_pause_cb(uint8_t vdev_id,
708 		enum netif_action_type action, enum netif_reason_type reason)
709 {
710 	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
711 	struct hdd_adapter *adapter;
712 	struct wlan_hdd_link_info *link_info;
713 
714 	if (!hdd_ctx)
715 		return;
716 
717 	link_info = hdd_get_link_info_by_vdev(hdd_ctx, vdev_id);
718 	if (!link_info)
719 		return;
720 
721 	adapter =  link_info->adapter;
722 	wlan_hdd_mod_fc_timer(adapter, action);
723 	wlan_hdd_netif_queue_control(adapter, action, reason);
724 }
725 
726 /*
727  * Store WLAN driver version and timestamp info in global variables such that
728  * crash debugger can extract them from driver debug symbol and crashdump for
729  * post processing
730  */
731 #ifdef BUILD_TAG
732 uint8_t g_wlan_driver_version[] = QWLAN_VERSIONSTR TIMER_MANAGER_STR MEMORY_DEBUG_STR PANIC_ON_BUG_STR "; " BUILD_TAG;
733 #else
734 uint8_t g_wlan_driver_version[] = QWLAN_VERSIONSTR TIMER_MANAGER_STR MEMORY_DEBUG_STR PANIC_ON_BUG_STR;
735 #endif
736 
hdd_validate_channel_and_bandwidth(struct hdd_adapter * adapter,qdf_freq_t chan_freq,enum phy_ch_width chan_bw)737 int hdd_validate_channel_and_bandwidth(struct hdd_adapter *adapter,
738 				       qdf_freq_t chan_freq,
739 				       enum phy_ch_width chan_bw)
740 {
741 	struct ch_params ch_params = {0};
742 	struct hdd_context *hdd_ctx;
743 
744 	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
745 	if (!hdd_ctx) {
746 		hdd_err("hdd context is NULL");
747 		return -EINVAL;
748 	}
749 
750 	if (reg_is_chan_enum_invalid(
751 			wlan_reg_get_chan_enum_for_freq(chan_freq))) {
752 		hdd_err("Channel freq %d not in driver's valid channel list", chan_freq);
753 		return -EOPNOTSUPP;
754 	}
755 
756 	if ((!WLAN_REG_IS_24GHZ_CH_FREQ(chan_freq)) &&
757 	    (!WLAN_REG_IS_5GHZ_CH_FREQ(chan_freq)) &&
758 	    (!WLAN_REG_IS_6GHZ_CHAN_FREQ(chan_freq))) {
759 		hdd_err("CH %d is not in 2.4GHz or 5GHz or 6GHz", chan_freq);
760 		return -EINVAL;
761 	}
762 	ch_params.ch_width = CH_WIDTH_MAX;
763 	wlan_reg_set_channel_params_for_pwrmode(hdd_ctx->pdev, chan_freq,
764 						0, &ch_params,
765 						REG_CURRENT_PWR_MODE);
766 	if (ch_params.ch_width == CH_WIDTH_MAX) {
767 		hdd_err("failed to get max bandwdith for %d", chan_freq);
768 		return -EINVAL;
769 	}
770 	if (WLAN_REG_IS_24GHZ_CH_FREQ(chan_freq)) {
771 		if (chan_bw == CH_WIDTH_80MHZ) {
772 			hdd_err("BW80 not possible in 2.4GHz band");
773 			return -EINVAL;
774 		}
775 		if ((chan_bw != CH_WIDTH_20MHZ) &&
776 		    (chan_freq == wlan_reg_ch_to_freq(CHAN_ENUM_2484)) &&
777 		    (chan_bw != CH_WIDTH_MAX) &&
778 		    (ch_params.ch_width == CH_WIDTH_20MHZ)) {
779 			hdd_err("Only BW20 possible on channel freq 2484");
780 			return -EINVAL;
781 		}
782 	}
783 
784 	if (WLAN_REG_IS_5GHZ_CH_FREQ(chan_freq)) {
785 		if ((chan_bw != CH_WIDTH_20MHZ) &&
786 		    (chan_freq == wlan_reg_ch_to_freq(CHAN_ENUM_5825)) &&
787 		    (chan_bw != CH_WIDTH_MAX) &&
788 		    (ch_params.ch_width == CH_WIDTH_20MHZ)) {
789 			hdd_err("Only BW20 possible on channel freq 5825");
790 			return -EINVAL;
791 		}
792 	}
793 
794 	return 0;
795 }
796 
hdd_get_link_info_home_channel(struct wlan_hdd_link_info * link_info)797 uint32_t hdd_get_link_info_home_channel(struct wlan_hdd_link_info *link_info)
798 {
799 	uint32_t home_chan_freq = 0;
800 	enum QDF_OPMODE opmode = link_info->adapter->device_mode;
801 
802 	switch (opmode) {
803 	case QDF_SAP_MODE:
804 	case QDF_P2P_GO_MODE:
805 		if (test_bit(SOFTAP_BSS_STARTED, &link_info->link_flags)) {
806 			home_chan_freq =
807 				link_info->session.ap.operating_chan_freq;
808 		}
809 		break;
810 	case QDF_STA_MODE:
811 	case QDF_P2P_CLIENT_MODE:
812 		if (hdd_cm_is_vdev_associated(link_info)) {
813 			home_chan_freq =
814 				link_info->session.station.conn_info.chan_freq;
815 		}
816 		break;
817 	default:
818 		break;
819 	}
820 
821 	return home_chan_freq;
822 }
823 
hdd_get_link_info_width(struct wlan_hdd_link_info * link_info)824 enum phy_ch_width hdd_get_link_info_width(struct wlan_hdd_link_info *link_info)
825 {
826 	enum phy_ch_width width = CH_WIDTH_20MHZ;
827 	enum QDF_OPMODE opmode = link_info->adapter->device_mode;
828 
829 	switch (opmode) {
830 	case QDF_SAP_MODE:
831 	case QDF_P2P_GO_MODE:
832 		if (test_bit(SOFTAP_BSS_STARTED, &link_info->link_flags)) {
833 			struct hdd_ap_ctx *ap_ctx =
834 					WLAN_HDD_GET_AP_CTX_PTR(link_info);
835 
836 			width = ap_ctx->sap_config.ch_params.ch_width;
837 		}
838 		break;
839 	case QDF_STA_MODE:
840 	case QDF_P2P_CLIENT_MODE:
841 		if (hdd_cm_is_vdev_associated(link_info))
842 			width = link_info->session.station.conn_info.ch_width;
843 		break;
844 	default:
845 		break;
846 	}
847 
848 	return width;
849 }
850 
851 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
hdd_net_dev_from_notifier(void * context)852 static inline struct net_device *hdd_net_dev_from_notifier(void *context)
853 {
854 	struct netdev_notifier_info *info = context;
855 
856 	return info->dev;
857 }
858 #else
hdd_net_dev_from_notifier(void * context)859 static inline struct net_device *hdd_net_dev_from_notifier(void *context)
860 {
861 	return context;
862 }
863 #endif
864 
__hdd_netdev_notifier_call(struct net_device * net_dev,unsigned long state)865 static int __hdd_netdev_notifier_call(struct net_device *net_dev,
866 				      unsigned long state)
867 {
868 	struct hdd_adapter *adapter;
869 	struct hdd_context *hdd_ctx;
870 	struct wlan_objmgr_vdev *vdev;
871 
872 	hdd_enter_dev(net_dev);
873 
874 	if (!net_dev->ieee80211_ptr) {
875 		hdd_debug("ieee80211_ptr is null");
876 		return NOTIFY_DONE;
877 	}
878 
879 	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
880 	if (!hdd_ctx)
881 		return NOTIFY_DONE;
882 
883 	if (hdd_ctx->driver_status == DRIVER_MODULES_CLOSED) {
884 		hdd_debug("Driver module is closed");
885 		return NOTIFY_DONE;
886 	}
887 
888 	/* Make sure that this callback corresponds to our device. */
889 	adapter = hdd_get_adapter_by_iface_name(hdd_ctx, net_dev->name);
890 	if (!adapter) {
891 		hdd_debug("failed to look up adapter for '%s'", net_dev->name);
892 		return NOTIFY_DONE;
893 	}
894 
895 	if (adapter != WLAN_HDD_GET_PRIV_PTR(net_dev)) {
896 		hdd_err("HDD adapter mismatch!");
897 		return NOTIFY_DONE;
898 	}
899 
900 	if (cds_is_driver_recovering()) {
901 		hdd_debug("Driver is recovering");
902 		return NOTIFY_DONE;
903 	}
904 
905 	if (cds_is_driver_in_bad_state()) {
906 		hdd_debug("Driver is in failed recovery state");
907 		return NOTIFY_DONE;
908 	}
909 
910 	hdd_debug("%s New Net Device State = %lu, flags 0x%x",
911 		  net_dev->name, state, net_dev->flags);
912 
913 	switch (state) {
914 	case NETDEV_REGISTER:
915 		break;
916 
917 	case NETDEV_UNREGISTER:
918 		break;
919 
920 	case NETDEV_UP:
921 		sme_ch_avoid_update_req(hdd_ctx->mac_handle);
922 		break;
923 
924 	case NETDEV_DOWN:
925 		break;
926 
927 	case NETDEV_CHANGE:
928 		if (adapter->is_link_up_service_needed)
929 			complete(&adapter->linkup_event_var);
930 		break;
931 
932 	case NETDEV_GOING_DOWN:
933 		vdev = hdd_objmgr_get_vdev_by_user(adapter->deflink,
934 						   WLAN_OSIF_SCAN_ID);
935 		if (!vdev)
936 			break;
937 		if (ucfg_scan_get_vdev_status(vdev) !=
938 				SCAN_NOT_IN_PROGRESS) {
939 			wlan_abort_scan(hdd_ctx->pdev, INVAL_PDEV_ID,
940 					adapter->deflink->vdev_id,
941 					INVALID_SCAN_ID, true);
942 		}
943 		hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_SCAN_ID);
944 		cds_flush_work(&adapter->scan_block_work);
945 		/* Need to clean up blocked scan request */
946 		wlan_hdd_cfg80211_scan_block(adapter);
947 		hdd_debug("Scan is not Pending from user");
948 		/*
949 		 * After NETDEV_GOING_DOWN, kernel calls hdd_stop.Irrespective
950 		 * of return status of hdd_stop call, kernel resets the IFF_UP
951 		 * flag after which driver does not send the cfg80211_scan_done.
952 		 * Ensure to cleanup the scan queue in NETDEV_GOING_DOWN
953 		 */
954 		wlan_cfg80211_cleanup_scan_queue(hdd_ctx->pdev, net_dev);
955 		break;
956 	case NETDEV_FEAT_CHANGE:
957 		hdd_debug("vdev %d netdev Feature 0x%llx\n",
958 			  adapter->deflink->vdev_id, net_dev->features);
959 		break;
960 	default:
961 		break;
962 	}
963 
964 	return NOTIFY_DONE;
965 }
966 
hdd_netdev_notifier_bridge_intf(struct net_device * net_dev,unsigned long state)967 static int hdd_netdev_notifier_bridge_intf(struct net_device *net_dev,
968 					   unsigned long state)
969 {
970 	struct hdd_adapter *adapter, *next_adapter = NULL;
971 	wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_GET_ADAPTER;
972 	struct hdd_context *hdd_ctx;
973 	QDF_STATUS status;
974 
975 	hdd_enter_dev(net_dev);
976 
977 	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
978 	if (wlan_hdd_validate_context(hdd_ctx))
979 		return NOTIFY_DONE;
980 
981 	hdd_debug("%s New Net Device State = %lu, flags 0x%x bridge mac address: "QDF_MAC_ADDR_FMT,
982 		  net_dev->name, state, net_dev->flags, QDF_MAC_ADDR_REF(net_dev->dev_addr));
983 
984 	if (!qdf_mem_cmp(hdd_ctx->bridgeaddr, net_dev->dev_addr,
985 			 QDF_MAC_ADDR_SIZE))
986 		return NOTIFY_DONE;
987 
988 	switch (state) {
989 	case NETDEV_REGISTER:
990 	case NETDEV_CHANGEADDR:
991 		/* Update FW WoW pattern with new MAC address */
992 		qdf_mem_copy(hdd_ctx->bridgeaddr, net_dev->dev_addr,
993 			     QDF_MAC_ADDR_SIZE);
994 
995 		hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
996 						   dbgid) {
997 			if (adapter->device_mode != QDF_SAP_MODE)
998 				goto loop_next;
999 
1000 			if (wlan_hdd_validate_vdev_id(adapter->deflink->vdev_id))
1001 				goto loop_next;
1002 
1003 			status = wlan_objmgr_vdev_try_get_ref(adapter->deflink->vdev,
1004 							      WLAN_HDD_ID_OBJ_MGR);
1005 			if (QDF_IS_STATUS_ERROR(status))
1006 				goto loop_next;
1007 
1008 			ucfg_pmo_set_vdev_bridge_addr(adapter->deflink->vdev,
1009 				(struct qdf_mac_addr *)hdd_ctx->bridgeaddr);
1010 			ucfg_pmo_del_wow_pattern(adapter->deflink->vdev);
1011 			ucfg_pmo_register_wow_default_patterns(adapter->deflink->vdev);
1012 
1013 			wlan_objmgr_vdev_release_ref(adapter->deflink->vdev,
1014 						     WLAN_HDD_ID_OBJ_MGR);
1015 
1016 loop_next:
1017 			hdd_adapter_dev_put_debug(adapter, dbgid);
1018 		}
1019 
1020 		break;
1021 	case NETDEV_UNREGISTER:
1022 		qdf_zero_macaddr((struct qdf_mac_addr *)hdd_ctx->bridgeaddr);
1023 		break;
1024 	default:
1025 		break;
1026 	}
1027 
1028 	return NOTIFY_DONE;
1029 }
1030 
1031 /**
1032  * hdd_netdev_notifier_call() - netdev notifier callback function
1033  * @nb: pointer to notifier block
1034  * @state: state
1035  * @context: notifier callback context pointer
1036  *
1037  * Return: 0 on success, error number otherwise.
1038  */
hdd_netdev_notifier_call(struct notifier_block * nb,unsigned long state,void * context)1039 static int hdd_netdev_notifier_call(struct notifier_block *nb,
1040 					unsigned long state,
1041 					void *context)
1042 {
1043 	struct net_device *net_dev = hdd_net_dev_from_notifier(context);
1044 	struct osif_vdev_sync *vdev_sync;
1045 	int errno;
1046 
1047 	if (net_dev->priv_flags & IFF_EBRIDGE) {
1048 		errno = hdd_netdev_notifier_bridge_intf(net_dev, state);
1049 		if (errno)
1050 			return NOTIFY_DONE;
1051 	}
1052 
1053 	errno = osif_vdev_sync_op_start(net_dev, &vdev_sync);
1054 	if (errno) {
1055 		hdd_debug("%s New Net Device State = %lu, flags 0x%x NOTIFY_DONE",
1056 			  net_dev->name, state, net_dev->flags);
1057 		return NOTIFY_DONE;
1058 	}
1059 
1060 	errno = __hdd_netdev_notifier_call(net_dev, state);
1061 
1062 	osif_vdev_sync_op_stop(vdev_sync);
1063 
1064 	return NOTIFY_DONE;
1065 }
1066 
1067 struct notifier_block hdd_netdev_notifier = {
1068 	.notifier_call = hdd_netdev_notifier_call,
1069 };
1070 
1071 /* variable to hold the insmod parameters */
1072 int con_mode;
1073 #ifdef FEATURE_WLAN_RESIDENT_DRIVER
1074 EXPORT_SYMBOL(con_mode);
1075 #endif
1076 
1077 int con_mode_ftm;
1078 #ifdef FEATURE_WLAN_RESIDENT_DRIVER
1079 EXPORT_SYMBOL(con_mode_ftm);
1080 #endif
1081 int con_mode_epping;
1082 
1083 static int pcie_gen_speed;
1084 
1085 /* Variable to hold connection mode including module parameter con_mode */
1086 static int curr_con_mode;
1087 
1088 #if defined(WLAN_FEATURE_11BE) && defined(CFG80211_11BE_BASIC)
hdd_get_eht_phy_ch_width_from_target(void)1089 static enum phy_ch_width hdd_get_eht_phy_ch_width_from_target(void)
1090 {
1091 	uint32_t max_fw_bw = sme_get_eht_ch_width();
1092 
1093 	if (max_fw_bw == WNI_CFG_EHT_CHANNEL_WIDTH_320MHZ)
1094 		return CH_WIDTH_320MHZ;
1095 	else if (max_fw_bw == WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ)
1096 		return CH_WIDTH_160MHZ;
1097 	else
1098 		return CH_WIDTH_80MHZ;
1099 }
1100 
hdd_is_target_eht_phy_ch_width_supported(enum phy_ch_width width)1101 static bool hdd_is_target_eht_phy_ch_width_supported(enum phy_ch_width width)
1102 {
1103 	enum phy_ch_width max_fw_bw = hdd_get_eht_phy_ch_width_from_target();
1104 
1105 	if (width <= max_fw_bw)
1106 		return true;
1107 
1108 	hdd_err("FW does not support this BW %d max BW supported %d",
1109 		width, max_fw_bw);
1110 	return false;
1111 }
1112 
hdd_is_target_eht_160mhz_capable(void)1113 static bool hdd_is_target_eht_160mhz_capable(void)
1114 {
1115 	return hdd_is_target_eht_phy_ch_width_supported(CH_WIDTH_160MHZ);
1116 }
1117 
1118 static enum phy_ch_width
wlan_hdd_map_nl_chan_width(enum nl80211_chan_width width)1119 wlan_hdd_map_nl_chan_width(enum nl80211_chan_width width)
1120 {
1121 	if (width == NL80211_CHAN_WIDTH_320) {
1122 		return hdd_get_eht_phy_ch_width_from_target();
1123 	} else {
1124 		hdd_err("Invalid channel width %d, setting to default", width);
1125 		return CH_WIDTH_INVALID;
1126 	}
1127 }
1128 
1129 #else /* !WLAN_FEATURE_11BE */
1130 static inline bool
hdd_is_target_eht_phy_ch_width_supported(enum phy_ch_width width)1131 hdd_is_target_eht_phy_ch_width_supported(enum phy_ch_width width)
1132 {
1133 	return true;
1134 }
1135 
hdd_is_target_eht_160mhz_capable(void)1136 static inline bool hdd_is_target_eht_160mhz_capable(void)
1137 {
1138 	return false;
1139 }
1140 
1141 static enum phy_ch_width
wlan_hdd_map_nl_chan_width(enum nl80211_chan_width width)1142 wlan_hdd_map_nl_chan_width(enum nl80211_chan_width width)
1143 {
1144 	hdd_err("Invalid channel width %d, setting to default", width);
1145 	return CH_WIDTH_INVALID;
1146 }
1147 #endif /* WLAN_FEATURE_11BE */
1148 
1149 /**
1150  * hdd_map_nl_chan_width() - Map NL channel width to internal representation
1151  * @ch_width: NL channel width
1152  *
1153  * Converts the NL channel width to the driver's internal representation
1154  *
1155  * Return: Converted channel width. In case of non matching NL channel width,
1156  * CH_WIDTH_MAX will be returned.
1157  */
hdd_map_nl_chan_width(enum nl80211_chan_width ch_width)1158 enum phy_ch_width hdd_map_nl_chan_width(enum nl80211_chan_width ch_width)
1159 {
1160 	uint8_t fw_ch_bw;
1161 
1162 	fw_ch_bw = wma_get_vht_ch_width();
1163 	switch (ch_width) {
1164 	case NL80211_CHAN_WIDTH_20_NOHT:
1165 	case NL80211_CHAN_WIDTH_20:
1166 		return CH_WIDTH_20MHZ;
1167 	case NL80211_CHAN_WIDTH_40:
1168 		return CH_WIDTH_40MHZ;
1169 	case NL80211_CHAN_WIDTH_80:
1170 		return CH_WIDTH_80MHZ;
1171 	case NL80211_CHAN_WIDTH_80P80:
1172 		if (fw_ch_bw == WNI_CFG_VHT_CHANNEL_WIDTH_80_PLUS_80MHZ)
1173 			return CH_WIDTH_80P80MHZ;
1174 		else if (fw_ch_bw == WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ)
1175 			return CH_WIDTH_160MHZ;
1176 		else
1177 			return CH_WIDTH_80MHZ;
1178 	case NL80211_CHAN_WIDTH_160:
1179 		if (hdd_is_target_eht_160mhz_capable())
1180 			return CH_WIDTH_160MHZ;
1181 
1182 		if (fw_ch_bw >= WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ)
1183 			return CH_WIDTH_160MHZ;
1184 		else
1185 			return CH_WIDTH_80MHZ;
1186 	case NL80211_CHAN_WIDTH_5:
1187 		return CH_WIDTH_5MHZ;
1188 	case NL80211_CHAN_WIDTH_10:
1189 		return CH_WIDTH_10MHZ;
1190 	default:
1191 		return wlan_hdd_map_nl_chan_width(ch_width);
1192 	}
1193 }
1194 
1195 #if defined(WLAN_FEATURE_NAN) && \
1196 	   (KERNEL_VERSION(4, 9, 0) <= LINUX_VERSION_CODE)
1197 /**
1198  * wlan_hdd_convert_nan_type() - Convert nl type to qdf type
1199  * @nl_type: NL80211 interface type
1200  * @out_qdf_type: QDF type for the given nl_type
1201  *
1202  * Convert nl type to QDF type
1203  *
1204  * Return: QDF_STATUS_SUCCESS if converted, failure otherwise.
1205  */
wlan_hdd_convert_nan_type(enum nl80211_iftype nl_type,enum QDF_OPMODE * out_qdf_type)1206 static QDF_STATUS wlan_hdd_convert_nan_type(enum nl80211_iftype nl_type,
1207 					    enum QDF_OPMODE *out_qdf_type)
1208 {
1209 	if (nl_type == NL80211_IFTYPE_NAN) {
1210 		*out_qdf_type = QDF_NAN_DISC_MODE;
1211 		return QDF_STATUS_SUCCESS;
1212 	}
1213 	return QDF_STATUS_E_INVAL;
1214 }
1215 
1216 /**
1217  * wlan_hdd_set_nan_if_type() - Set the NAN iftype
1218  * @adapter: pointer to HDD adapter
1219  *
1220  * Set the NL80211_IFTYPE_NAN to wdev iftype.
1221  *
1222  * Return: None
1223  */
wlan_hdd_set_nan_if_type(struct hdd_adapter * adapter)1224 static void wlan_hdd_set_nan_if_type(struct hdd_adapter *adapter)
1225 {
1226 	adapter->wdev.iftype = NL80211_IFTYPE_NAN;
1227 }
1228 
wlan_hdd_is_vdev_creation_allowed(struct wlan_objmgr_psoc * psoc)1229 static bool wlan_hdd_is_vdev_creation_allowed(struct wlan_objmgr_psoc *psoc)
1230 {
1231 	return ucfg_nan_is_vdev_creation_allowed(psoc);
1232 }
1233 #else
wlan_hdd_convert_nan_type(enum nl80211_iftype nl_type,enum QDF_OPMODE * out_qdf_type)1234 static QDF_STATUS wlan_hdd_convert_nan_type(enum nl80211_iftype nl_type,
1235 					    enum QDF_OPMODE *out_qdf_type)
1236 {
1237 	return QDF_STATUS_E_INVAL;
1238 }
1239 
wlan_hdd_set_nan_if_type(struct hdd_adapter * adapter)1240 static void wlan_hdd_set_nan_if_type(struct hdd_adapter *adapter)
1241 {
1242 }
1243 
wlan_hdd_is_vdev_creation_allowed(struct wlan_objmgr_psoc * psoc)1244 static bool wlan_hdd_is_vdev_creation_allowed(struct wlan_objmgr_psoc *psoc)
1245 {
1246 	return false;
1247 }
1248 #endif
1249 
hdd_nl_to_qdf_iface_type(enum nl80211_iftype nl_type,enum QDF_OPMODE * out_qdf_type)1250 QDF_STATUS hdd_nl_to_qdf_iface_type(enum nl80211_iftype nl_type,
1251 				    enum QDF_OPMODE *out_qdf_type)
1252 {
1253 	QDF_STATUS status = QDF_STATUS_SUCCESS;
1254 
1255 	switch (nl_type) {
1256 	case NL80211_IFTYPE_AP:
1257 		*out_qdf_type = QDF_SAP_MODE;
1258 		break;
1259 	case NL80211_IFTYPE_MONITOR:
1260 		*out_qdf_type = QDF_MONITOR_MODE;
1261 		break;
1262 	case NL80211_IFTYPE_OCB:
1263 		*out_qdf_type = QDF_OCB_MODE;
1264 		break;
1265 	case NL80211_IFTYPE_P2P_CLIENT:
1266 		*out_qdf_type = QDF_P2P_CLIENT_MODE;
1267 		break;
1268 	case NL80211_IFTYPE_P2P_DEVICE:
1269 		*out_qdf_type = QDF_P2P_DEVICE_MODE;
1270 		break;
1271 	case NL80211_IFTYPE_P2P_GO:
1272 		*out_qdf_type = QDF_P2P_GO_MODE;
1273 		break;
1274 	case NL80211_IFTYPE_STATION:
1275 		*out_qdf_type = QDF_STA_MODE;
1276 		break;
1277 	case NL80211_IFTYPE_WDS:
1278 		*out_qdf_type = QDF_WDS_MODE;
1279 		break;
1280 	default:
1281 		status = wlan_hdd_convert_nan_type(nl_type, out_qdf_type);
1282 		if (QDF_IS_STATUS_SUCCESS(status))
1283 			break;
1284 		hdd_err("Invalid nl80211 interface type %d", nl_type);
1285 		return QDF_STATUS_E_INVAL;
1286 	}
1287 
1288 	return QDF_STATUS_SUCCESS;
1289 }
1290 
wlan_hdd_find_opclass(mac_handle_t mac_handle,uint8_t channel,uint8_t bw_offset)1291 uint8_t wlan_hdd_find_opclass(mac_handle_t mac_handle, uint8_t channel,
1292 			      uint8_t bw_offset)
1293 {
1294 	uint8_t opclass = 0;
1295 
1296 	sme_get_opclass(mac_handle, channel, bw_offset, &opclass);
1297 	return opclass;
1298 }
1299 
1300 /**
1301  * hdd_qdf_trace_enable() - configure initial QDF Trace enable
1302  * @module_id:	Module whose trace level is being configured
1303  * @bitmask:	Bitmask of log levels to be enabled
1304  *
1305  * Called immediately after the cfg.ini is read in order to configure
1306  * the desired trace levels.
1307  *
1308  * Return: None
1309  */
hdd_qdf_trace_enable(QDF_MODULE_ID module_id,uint32_t bitmask)1310 int hdd_qdf_trace_enable(QDF_MODULE_ID module_id, uint32_t bitmask)
1311 {
1312 	QDF_TRACE_LEVEL level;
1313 	int qdf_print_idx = -1;
1314 	int status = -1;
1315 	/*
1316 	 * if the bitmask is the default value, then a bitmask was not
1317 	 * specified in cfg.ini, so leave the logging level alone (it
1318 	 * will remain at the "compiled in" default value)
1319 	 */
1320 	if (CFG_QDF_TRACE_ENABLE_DEFAULT == bitmask)
1321 		return 0;
1322 
1323 	qdf_print_idx = qdf_get_pidx();
1324 
1325 	/* a mask was specified.  start by disabling all logging */
1326 	status = qdf_print_set_category_verbose(qdf_print_idx, module_id,
1327 					QDF_TRACE_LEVEL_NONE, 0);
1328 
1329 	if (QDF_STATUS_SUCCESS != status)
1330 		return -EINVAL;
1331 	/* now cycle through the bitmask until all "set" bits are serviced */
1332 	level = QDF_TRACE_LEVEL_NONE;
1333 	while (0 != bitmask) {
1334 		if (bitmask & 1) {
1335 			status = qdf_print_set_category_verbose(qdf_print_idx,
1336 							module_id, level, 1);
1337 			if (QDF_STATUS_SUCCESS != status)
1338 				return -EINVAL;
1339 		}
1340 
1341 		level++;
1342 		bitmask >>= 1;
1343 	}
1344 	return 0;
1345 }
1346 
__wlan_hdd_validate_context(struct hdd_context * hdd_ctx,const char * func)1347 int __wlan_hdd_validate_context(struct hdd_context *hdd_ctx, const char *func)
1348 {
1349 	if (!hdd_ctx) {
1350 		hdd_err("HDD context is null (via %s)", func);
1351 		return -ENODEV;
1352 	}
1353 
1354 	if (!hdd_ctx->config) {
1355 		hdd_err("HDD config is null (via %s)", func);
1356 		return -ENODEV;
1357 	}
1358 
1359 	if (cds_is_driver_recovering()) {
1360 		hdd_debug("Recovery in progress (via %s); state:0x%x",
1361 			  func, cds_get_driver_state());
1362 		return -EAGAIN;
1363 	}
1364 
1365 	if (cds_is_load_or_unload_in_progress()) {
1366 		hdd_debug("Load/unload in progress (via %s); state:0x%x",
1367 			  func, cds_get_driver_state());
1368 		return -EAGAIN;
1369 	}
1370 
1371 	if (cds_is_driver_in_bad_state()) {
1372 		hdd_debug("Driver in bad state (via %s); state:0x%x",
1373 			  func, cds_get_driver_state());
1374 		return -EAGAIN;
1375 	}
1376 
1377 	if (cds_is_fw_down()) {
1378 		hdd_debug("FW is down (via %s); state:0x%x",
1379 			  func, cds_get_driver_state());
1380 		return -EAGAIN;
1381 	}
1382 
1383 	if (hdd_ctx->is_wlan_disabled) {
1384 		hdd_debug("WLAN is disabled by user space");
1385 		return -EAGAIN;
1386 	}
1387 
1388 	return 0;
1389 }
1390 
__hdd_validate_adapter(struct hdd_adapter * adapter,const char * func)1391 int __hdd_validate_adapter(struct hdd_adapter *adapter, const char *func)
1392 {
1393 	if (!adapter) {
1394 		hdd_err("adapter is null (via %s)", func);
1395 		return -EINVAL;
1396 	}
1397 
1398 	if (adapter->magic != WLAN_HDD_ADAPTER_MAGIC) {
1399 		hdd_err("bad adapter magic (via %s)", func);
1400 		return -EINVAL;
1401 	}
1402 
1403 	if (!adapter->dev) {
1404 		hdd_err("adapter net_device is null (via %s)", func);
1405 		return -EINVAL;
1406 	}
1407 
1408 	if (!(adapter->dev->flags & IFF_UP)) {
1409 		hdd_debug_rl("adapter '%s' is not up (via %s)",
1410 			     adapter->dev->name, func);
1411 		return -EAGAIN;
1412 	}
1413 
1414 	return __wlan_hdd_validate_vdev_id(adapter->deflink->vdev_id, func);
1415 }
1416 
__wlan_hdd_validate_vdev_id(uint8_t vdev_id,const char * func)1417 int __wlan_hdd_validate_vdev_id(uint8_t vdev_id, const char *func)
1418 {
1419 	if (vdev_id == WLAN_UMAC_VDEV_ID_MAX) {
1420 		hdd_debug_rl("adapter is not up (via %s)", func);
1421 		return -EINVAL;
1422 	}
1423 
1424 	if (vdev_id >= WLAN_MAX_VDEVS) {
1425 		hdd_err("bad vdev Id:%u (via %s)", vdev_id, func);
1426 		return -EINVAL;
1427 	}
1428 
1429 	return 0;
1430 }
1431 
__wlan_hdd_validate_mac_address(struct qdf_mac_addr * mac_addr,const char * func)1432 QDF_STATUS __wlan_hdd_validate_mac_address(struct qdf_mac_addr *mac_addr,
1433 					   const char *func)
1434 {
1435 	if (!mac_addr) {
1436 		hdd_err("Received NULL mac address (via %s)", func);
1437 		return QDF_STATUS_E_INVAL;
1438 	}
1439 
1440 	if (qdf_is_macaddr_zero(mac_addr)) {
1441 		hdd_err("MAC is all zero (via %s)", func);
1442 		return QDF_STATUS_E_INVAL;
1443 	}
1444 
1445 	if (qdf_is_macaddr_broadcast(mac_addr)) {
1446 		hdd_err("MAC is Broadcast (via %s)", func);
1447 		return QDF_STATUS_E_INVAL;
1448 	}
1449 
1450 	if (QDF_NET_IS_MAC_MULTICAST(mac_addr->bytes)) {
1451 		hdd_err("MAC is Multicast (via %s)", func);
1452 		return QDF_STATUS_E_INVAL;
1453 	}
1454 
1455 	return QDF_STATUS_SUCCESS;
1456 }
1457 
1458 /**
1459  * wlan_hdd_validate_modules_state() - Check modules status
1460  * @hdd_ctx: HDD context pointer
1461  *
1462  * Check's the driver module's state and returns true if the
1463  * modules are enabled returns false if modules are closed.
1464  *
1465  * Return: True if modules are enabled or false.
1466  */
wlan_hdd_validate_modules_state(struct hdd_context * hdd_ctx)1467 bool wlan_hdd_validate_modules_state(struct hdd_context *hdd_ctx)
1468 {
1469 	if (hdd_ctx->driver_status != DRIVER_MODULES_ENABLED) {
1470 		hdd_info("Modules not enabled, Present status: %d",
1471 			 hdd_ctx->driver_status);
1472 		return false;
1473 	}
1474 
1475 	return true;
1476 }
1477 
1478 #ifdef FEATURE_RUNTIME_PM
1479 /**
1480  * hdd_runtime_suspend_context_init() - API to initialize HDD Runtime Contexts
1481  * @hdd_ctx: HDD context
1482  *
1483  * Return: None
1484  */
hdd_runtime_suspend_context_init(struct hdd_context * hdd_ctx)1485 static void hdd_runtime_suspend_context_init(struct hdd_context *hdd_ctx)
1486 {
1487 	struct hdd_runtime_pm_context *ctx = &hdd_ctx->runtime_context;
1488 
1489 	qdf_runtime_lock_init(&ctx->dfs);
1490 	qdf_runtime_lock_init(&ctx->connect);
1491 	qdf_runtime_lock_init(&ctx->user);
1492 	qdf_runtime_lock_init(&ctx->monitor_mode);
1493 	qdf_runtime_lock_init(&ctx->wow_unit_test);
1494 	qdf_runtime_lock_init(&ctx->system_suspend);
1495 	qdf_runtime_lock_init(&ctx->dyn_mac_addr_update);
1496 	qdf_runtime_lock_init(&ctx->vdev_destroy);
1497 	qdf_runtime_lock_init(&ctx->oem_data_cmd);
1498 
1499 	qdf_rtpm_register(QDF_RTPM_ID_WIPHY_SUSPEND, NULL);
1500 	qdf_rtpm_register(QDF_RTPM_ID_PM_QOS_NOTIFY, NULL);
1501 
1502 	ctx->is_user_wakelock_acquired = false;
1503 
1504 	wlan_scan_runtime_pm_init(hdd_ctx->pdev);
1505 }
1506 
1507 /**
1508  * hdd_runtime_suspend_context_deinit() - API to deinit HDD runtime context
1509  * @hdd_ctx: HDD Context
1510  *
1511  * Return: None
1512  */
hdd_runtime_suspend_context_deinit(struct hdd_context * hdd_ctx)1513 static void hdd_runtime_suspend_context_deinit(struct hdd_context *hdd_ctx)
1514 {
1515 	struct hdd_runtime_pm_context *ctx = &hdd_ctx->runtime_context;
1516 
1517 	if (ctx->is_user_wakelock_acquired)
1518 		qdf_runtime_pm_allow_suspend(&ctx->user);
1519 
1520 	qdf_runtime_lock_deinit(&ctx->oem_data_cmd);
1521 	qdf_runtime_lock_deinit(&ctx->dyn_mac_addr_update);
1522 	qdf_runtime_lock_deinit(&ctx->wow_unit_test);
1523 	qdf_runtime_lock_deinit(&ctx->monitor_mode);
1524 	qdf_runtime_lock_deinit(&ctx->user);
1525 	qdf_runtime_lock_deinit(&ctx->connect);
1526 	qdf_runtime_lock_deinit(&ctx->dfs);
1527 	qdf_runtime_lock_deinit(&ctx->system_suspend);
1528 	qdf_runtime_lock_deinit(&ctx->vdev_destroy);
1529 
1530 	qdf_rtpm_deregister(QDF_RTPM_ID_WIPHY_SUSPEND);
1531 	qdf_rtpm_deregister(QDF_RTPM_ID_PM_QOS_NOTIFY);
1532 
1533 	wlan_scan_runtime_pm_deinit(hdd_ctx->pdev);
1534 }
1535 
1536 #else /* FEATURE_RUNTIME_PM */
hdd_runtime_suspend_context_init(struct hdd_context * hdd_ctx)1537 static void hdd_runtime_suspend_context_init(struct hdd_context *hdd_ctx) {}
hdd_runtime_suspend_context_deinit(struct hdd_context * hdd_ctx)1538 static void hdd_runtime_suspend_context_deinit(struct hdd_context *hdd_ctx) {}
1539 #endif /* FEATURE_RUNTIME_PM */
1540 
hdd_update_macaddr(struct hdd_context * hdd_ctx,struct qdf_mac_addr hw_macaddr,bool generate_mac_auto)1541 void hdd_update_macaddr(struct hdd_context *hdd_ctx,
1542 			struct qdf_mac_addr hw_macaddr, bool generate_mac_auto)
1543 {
1544 	int8_t i;
1545 	uint8_t macaddr_b3, tmp_br3;
1546 
1547 	/*
1548 	 * If "generate_mac_auto" is true, it indicates that all the
1549 	 * addresses are derived addresses, else the first addresses
1550 	 * is not derived address (It is provided by fw).
1551 	 */
1552 	if (!generate_mac_auto) {
1553 		qdf_mem_copy(hdd_ctx->provisioned_mac_addr[0].bytes,
1554 			     hw_macaddr.bytes, QDF_MAC_ADDR_SIZE);
1555 		hdd_ctx->num_provisioned_addr++;
1556 		hdd_debug("hdd_ctx->provisioned_mac_addr[0]: "
1557 			 QDF_MAC_ADDR_FMT,
1558 			 QDF_MAC_ADDR_REF(hdd_ctx->
1559 					provisioned_mac_addr[0].bytes));
1560 	} else {
1561 		qdf_mem_copy(hdd_ctx->derived_mac_addr[0].bytes,
1562 			     hw_macaddr.bytes,
1563 			     QDF_MAC_ADDR_SIZE);
1564 		hdd_ctx->num_derived_addr++;
1565 		hdd_debug("hdd_ctx->derived_mac_addr[0]: "
1566 			 QDF_MAC_ADDR_FMT,
1567 			 QDF_MAC_ADDR_REF(hdd_ctx->derived_mac_addr[0].bytes));
1568 	}
1569 	for (i = hdd_ctx->num_derived_addr; i < (QDF_MAX_CONCURRENCY_PERSONA -
1570 						hdd_ctx->num_provisioned_addr);
1571 			i++) {
1572 		qdf_mem_copy(hdd_ctx->derived_mac_addr[i].bytes,
1573 			     hw_macaddr.bytes,
1574 			     QDF_MAC_ADDR_SIZE);
1575 		macaddr_b3 = hdd_ctx->derived_mac_addr[i].bytes[3];
1576 		tmp_br3 = ((macaddr_b3 >> 4 & INTF_MACADDR_MASK) + i) &
1577 			  INTF_MACADDR_MASK;
1578 		macaddr_b3 += tmp_br3;
1579 
1580 		/* XOR-ing bit-24 of the mac address. This will give enough
1581 		 * mac address range before collision
1582 		 */
1583 		macaddr_b3 ^= (1 << 7);
1584 
1585 		/* Set locally administered bit */
1586 		hdd_ctx->derived_mac_addr[i].bytes[0] |= 0x02;
1587 		hdd_ctx->derived_mac_addr[i].bytes[3] = macaddr_b3;
1588 		hdd_debug("hdd_ctx->derived_mac_addr[%d]: "
1589 			QDF_MAC_ADDR_FMT, i,
1590 			QDF_MAC_ADDR_REF(hdd_ctx->derived_mac_addr[i].bytes));
1591 		hdd_ctx->num_derived_addr++;
1592 	}
1593 }
1594 
1595 #ifdef FEATURE_WLAN_TDLS
hdd_update_tdls_config(struct hdd_context * hdd_ctx)1596 static int hdd_update_tdls_config(struct hdd_context *hdd_ctx)
1597 {
1598 	struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc;
1599 	struct tdls_start_params tdls_cfg;
1600 	QDF_STATUS status;
1601 	struct wlan_mlme_nss_chains vdev_ini_cfg;
1602 
1603 	/* Populate the nss chain params from ini for this vdev type */
1604 	sme_populate_nss_chain_params(hdd_ctx->mac_handle, &vdev_ini_cfg,
1605 				      QDF_TDLS_MODE,
1606 				      hdd_ctx->num_rf_chains);
1607 
1608 	cfg_tdls_set_vdev_nss_2g(hdd_ctx->psoc,
1609 				 vdev_ini_cfg.rx_nss[NSS_CHAINS_BAND_2GHZ]);
1610 	cfg_tdls_set_vdev_nss_5g(hdd_ctx->psoc,
1611 				 vdev_ini_cfg.rx_nss[NSS_CHAINS_BAND_5GHZ]);
1612 	hdd_init_tdls_config(&tdls_cfg);
1613 	tdls_cfg.tdls_del_all_peers = eWNI_SME_DEL_ALL_TDLS_PEERS;
1614 	tdls_cfg.tdls_update_dp_vdev_flags = CDP_UPDATE_TDLS_FLAGS;
1615 	tdls_cfg.tdls_event_cb = wlan_cfg80211_tdls_event_callback;
1616 	tdls_cfg.tdls_evt_cb_data = psoc;
1617 	tdls_cfg.tdls_peer_context = hdd_ctx;
1618 	tdls_cfg.tdls_reg_peer = hdd_tdls_register_peer;
1619 	tdls_cfg.tdls_wmm_cb = hdd_wmm_is_acm_allowed;
1620 	tdls_cfg.tdls_wmm_cb_data = psoc;
1621 	tdls_cfg.tdls_rx_cb = wlan_cfg80211_tdls_rx_callback;
1622 	tdls_cfg.tdls_rx_cb_data = psoc;
1623 	tdls_cfg.tdls_dp_vdev_update = hdd_update_dp_vdev_flags;
1624 	tdls_cfg.tdls_osif_init_cb = wlan_cfg80211_tdls_osif_priv_init;
1625 	tdls_cfg.tdls_osif_deinit_cb = wlan_cfg80211_tdls_osif_priv_deinit;
1626 	tdls_cfg.tdls_osif_update_cb.tdls_osif_conn_update =
1627 					hdd_check_and_set_tdls_conn_params;
1628 	tdls_cfg.tdls_osif_update_cb.tdls_osif_disconn_update =
1629 					hdd_check_and_set_tdls_disconn_params;
1630 
1631 	status = ucfg_tdls_update_config(psoc, &tdls_cfg);
1632 	if (status != QDF_STATUS_SUCCESS) {
1633 		hdd_err("failed pmo psoc configuration");
1634 		return -EINVAL;
1635 	}
1636 
1637 	hdd_ctx->tdls_umac_comp_active = true;
1638 	/* enable napier specific tdls data path */
1639 	hdd_ctx->tdls_nap_active = true;
1640 
1641 	return 0;
1642 }
1643 #else
hdd_update_tdls_config(struct hdd_context * hdd_ctx)1644 static int hdd_update_tdls_config(struct hdd_context *hdd_ctx)
1645 {
1646 	return 0;
1647 }
1648 #endif
1649 
hdd_indicate_active_ndp_cnt(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id,uint8_t cnt)1650 void hdd_indicate_active_ndp_cnt(struct wlan_objmgr_psoc *psoc,
1651 				 uint8_t vdev_id, uint8_t cnt)
1652 {
1653 	struct wlan_hdd_link_info *link_info;
1654 
1655 	link_info = wlan_hdd_get_link_info_from_vdev(psoc, vdev_id);
1656 	if (!link_info || !cfg_nan_is_roam_config_disabled(psoc))
1657 		return;
1658 
1659 	hdd_debug("vdev_id:%d%s active ndp sessions present", vdev_id,
1660 		  cnt ? "" : " no more");
1661 	if (!cnt)
1662 		wlan_hdd_set_roaming_state(link_info, RSO_NDP_CON_ON_NDI, true);
1663 	else
1664 		wlan_hdd_set_roaming_state(link_info, RSO_NDP_CON_ON_NDI,
1665 					   false);
1666 }
1667 
1668 #ifdef WLAN_FEATURE_ROAM_OFFLOAD
hdd_update_roam_offload(struct hdd_context * hdd_ctx,struct wma_tgt_services * cfg)1669 static void hdd_update_roam_offload(struct hdd_context *hdd_ctx,
1670 				    struct wma_tgt_services *cfg)
1671 {
1672 	bool roam_offload_enable;
1673 
1674 	ucfg_mlme_get_roaming_offload(hdd_ctx->psoc, &roam_offload_enable);
1675 	ucfg_mlme_set_roaming_offload(hdd_ctx->psoc,
1676 				      roam_offload_enable &
1677 				      cfg->en_roam_offload);
1678 }
1679 #else
hdd_update_roam_offload(struct hdd_context * hdd_ctx,struct wma_tgt_services * cfg)1680 static inline void hdd_update_roam_offload(struct hdd_context *hdd_ctx,
1681 					   struct wma_tgt_services *cfg)
1682 {
1683 }
1684 #endif
1685 
1686 #ifdef FEATURE_CLUB_LL_STATS_AND_GET_STATION
1687 static void
hdd_club_ll_stats_in_get_sta_cfg_update(struct hdd_config * config,struct wlan_objmgr_psoc * psoc)1688 hdd_club_ll_stats_in_get_sta_cfg_update(struct hdd_config *config,
1689 					struct wlan_objmgr_psoc *psoc)
1690 {
1691 	config->sta_stats_cache_expiry_time =
1692 			cfg_get(psoc, CFG_STA_STATS_CACHE_EXPIRY);
1693 }
1694 
1695 static void
hdd_update_feature_cfg_club_get_sta_in_ll_stats_req(struct hdd_context * hdd_ctx,struct wma_tgt_services * cfg)1696 hdd_update_feature_cfg_club_get_sta_in_ll_stats_req(
1697 					struct hdd_context *hdd_ctx,
1698 					struct wma_tgt_services *cfg)
1699 {
1700 	hdd_ctx->is_get_station_clubbed_in_ll_stats_req =
1701 				cfg->is_get_station_clubbed_in_ll_stats_req &&
1702 				cfg_get(hdd_ctx->psoc,
1703 					CFG_CLUB_LL_STA_AND_GET_STATION);
1704 }
1705 
1706 static void
hdd_init_get_sta_in_ll_stats_config(struct hdd_adapter * adapter)1707 hdd_init_get_sta_in_ll_stats_config(struct hdd_adapter *adapter)
1708 {
1709 	adapter->sta_stats_cached_timestamp = 0;
1710 }
1711 #else
1712 static void
hdd_club_ll_stats_in_get_sta_cfg_update(struct hdd_config * config,struct wlan_objmgr_psoc * psoc)1713 hdd_club_ll_stats_in_get_sta_cfg_update(struct hdd_config *config,
1714 					struct wlan_objmgr_psoc *psoc)
1715 {
1716 }
1717 
1718 static void
hdd_update_feature_cfg_club_get_sta_in_ll_stats_req(struct hdd_context * hdd_ctx,struct wma_tgt_services * cfg)1719 hdd_update_feature_cfg_club_get_sta_in_ll_stats_req(
1720 					struct hdd_context *hdd_ctx,
1721 					struct wma_tgt_services *cfg)
1722 {
1723 }
1724 
1725 static void
hdd_init_get_sta_in_ll_stats_config(struct hdd_adapter * adapter)1726 hdd_init_get_sta_in_ll_stats_config(struct hdd_adapter *adapter)
1727 {
1728 }
1729 #endif /* FEATURE_CLUB_LL_STATS_AND_GET_STATION */
1730 
1731 #ifdef WLAN_FEATURE_11BE_MLO
1732 
1733 static void
hdd_init_link_state_cfg(struct hdd_config * config,struct wlan_objmgr_psoc * psoc)1734 hdd_init_link_state_cfg(struct hdd_config *config,
1735 			struct wlan_objmgr_psoc *psoc)
1736 {
1737 	config->link_state_cache_expiry_time =
1738 		cfg_get(psoc, CFG_LINK_STATE_CACHE_EXPIRY);
1739 }
1740 
1741 static void
hdd_init_link_state_config(struct hdd_adapter * adapter)1742 hdd_init_link_state_config(struct hdd_adapter *adapter)
1743 {
1744 	adapter->link_state_cached_timestamp = 0;
1745 }
1746 
1747 #else
1748 static void
hdd_init_link_state_cfg(struct hdd_config * config,struct wlan_objmgr_psoc * psoc)1749 hdd_init_link_state_cfg(struct hdd_config *config,
1750 			struct wlan_objmgr_psoc *psoc)
1751 {
1752 }
1753 
1754 static void
hdd_init_link_state_config(struct hdd_adapter * adapter)1755 hdd_init_link_state_config(struct hdd_adapter *adapter)
1756 {
1757 }
1758 #endif /* WLAN_FEATURE_11BE_MLO */
1759 
1760 #ifdef WLAN_FEATURE_IGMP_OFFLOAD
1761 static void
hdd_intersect_igmp_offload_setting(struct wlan_objmgr_psoc * psoc,struct wma_tgt_services * cfg)1762 hdd_intersect_igmp_offload_setting(struct wlan_objmgr_psoc *psoc,
1763 				   struct wma_tgt_services *cfg)
1764 {
1765 	bool igmp_offload_enable;
1766 
1767 	igmp_offload_enable =
1768 		ucfg_pmo_is_igmp_offload_enabled(psoc);
1769 	ucfg_pmo_set_igmp_offload_enabled(psoc,
1770 					  igmp_offload_enable &
1771 					  cfg->igmp_offload_enable);
1772 	hdd_info("fw cap to handle igmp %d igmp_offload_enable ini %d",
1773 		 cfg->igmp_offload_enable, igmp_offload_enable);
1774 }
1775 #else
1776 static inline void
hdd_intersect_igmp_offload_setting(struct wlan_objmgr_psoc * psoc,struct wma_tgt_services * cfg)1777 hdd_intersect_igmp_offload_setting(struct wlan_objmgr_psoc *psoc,
1778 				   struct wma_tgt_services *cfg)
1779 {}
1780 #endif
1781 
1782 #ifdef FEATURE_WLAN_TDLS
hdd_update_fw_tdls_wideband_capability(struct hdd_context * hdd_ctx,struct wma_tgt_services * cfg)1783 static void hdd_update_fw_tdls_wideband_capability(struct hdd_context *hdd_ctx,
1784 						   struct wma_tgt_services *cfg)
1785 {
1786 	ucfg_tdls_update_fw_wideband_capability(hdd_ctx->psoc,
1787 						cfg->en_tdls_wideband_support);
1788 }
1789 
1790 #ifdef WLAN_FEATURE_11BE
hdd_update_fw_tdls_mlo_capability(struct hdd_context * hdd_ctx,struct wma_tgt_services * cfg)1791 static void hdd_update_fw_tdls_mlo_capability(struct hdd_context *hdd_ctx,
1792 					      struct wma_tgt_services *cfg)
1793 {
1794 	ucfg_tdls_update_fw_mlo_capability(hdd_ctx->psoc,
1795 					   cfg->en_tdls_mlo_support);
1796 }
1797 #else
1798 static inline
hdd_update_fw_tdls_mlo_capability(struct hdd_context * hdd_ctx,struct wma_tgt_services * cfg)1799 void hdd_update_fw_tdls_mlo_capability(struct hdd_context *hdd_ctx,
1800 				       struct wma_tgt_services *cfg)
1801 {}
1802 #endif
1803 
1804 #ifdef WLAN_FEATURE_11AX
hdd_update_fw_tdls_11ax_capability(struct hdd_context * hdd_ctx,struct wma_tgt_services * cfg)1805 static void hdd_update_fw_tdls_11ax_capability(struct hdd_context *hdd_ctx,
1806 					       struct wma_tgt_services *cfg)
1807 {
1808 	ucfg_tdls_update_fw_11ax_capability(hdd_ctx->psoc,
1809 					    cfg->en_tdls_11ax_support);
1810 }
1811 
hdd_update_fw_tdls_6g_capability(struct hdd_context * hdd_ctx,struct wma_tgt_services * cfg)1812 static void hdd_update_fw_tdls_6g_capability(struct hdd_context *hdd_ctx,
1813 					     struct wma_tgt_services *cfg)
1814 {
1815 	ucfg_update_fw_tdls_6g_capability(hdd_ctx->psoc,
1816 					  cfg->en_tdls_6g_support);
1817 }
1818 
1819 #else
1820 static inline
hdd_update_fw_tdls_11ax_capability(struct hdd_context * hdd_ctx,struct wma_tgt_services * cfg)1821 void hdd_update_fw_tdls_11ax_capability(struct hdd_context *hdd_ctx,
1822 					struct wma_tgt_services *cfg)
1823 {}
1824 static inline
hdd_update_fw_tdls_6g_capability(struct hdd_context * hdd_ctx,struct wma_tgt_services * cfg)1825 void hdd_update_fw_tdls_6g_capability(struct hdd_context *hdd_ctx,
1826 				      struct wma_tgt_services *cfg)
1827 {}
1828 #endif
1829 #else
1830 static inline
hdd_update_fw_tdls_mlo_capability(struct hdd_context * hdd_ctx,struct wma_tgt_services * cfg)1831 void hdd_update_fw_tdls_mlo_capability(struct hdd_context *hdd_ctx,
1832 				       struct wma_tgt_services *cfg)
1833 {}
1834 
1835 static inline
hdd_update_fw_tdls_11ax_capability(struct hdd_context * hdd_ctx,struct wma_tgt_services * cfg)1836 void hdd_update_fw_tdls_11ax_capability(struct hdd_context *hdd_ctx,
1837 					struct wma_tgt_services *cfg)
1838 {}
1839 
1840 static inline
hdd_update_fw_tdls_6g_capability(struct hdd_context * hdd_ctx,struct wma_tgt_services * cfg)1841 void hdd_update_fw_tdls_6g_capability(struct hdd_context *hdd_ctx,
1842 				      struct wma_tgt_services *cfg)
1843 {}
1844 
1845 static inline
hdd_update_fw_tdls_wideband_capability(struct hdd_context * hdd_ctx,struct wma_tgt_services * cfg)1846 void hdd_update_fw_tdls_wideband_capability(struct hdd_context *hdd_ctx,
1847 					    struct wma_tgt_services *cfg)
1848 {}
1849 #endif
1850 
1851 #ifdef WLAN_FEATURE_DYNAMIC_MAC_ADDR_UPDATE
1852 static inline void
hdd_set_dynamic_macaddr_update_capability(struct hdd_context * hdd_ctx,struct wma_tgt_services * cfg)1853 hdd_set_dynamic_macaddr_update_capability(struct hdd_context *hdd_ctx,
1854 					  struct wma_tgt_services *cfg)
1855 {
1856 	hdd_ctx->is_vdev_macaddr_dynamic_update_supported =
1857 				cfg->dynamic_vdev_macaddr_support &&
1858 				cfg_get(hdd_ctx->psoc,
1859 					CFG_DYNAMIC_MAC_ADDR_UPDATE_SUPPORTED);
1860 }
1861 #else
1862 static inline void
hdd_set_dynamic_macaddr_update_capability(struct hdd_context * hdd_ctx,struct wma_tgt_services * cfg)1863 hdd_set_dynamic_macaddr_update_capability(struct hdd_context *hdd_ctx,
1864 					  struct wma_tgt_services *cfg)
1865 {
1866 }
1867 #endif
1868 
1869 #ifdef WLAN_FEATURE_11BE
hdd_dot11Mode_support_11be(enum hdd_dot11_mode dot11Mode)1870 static bool hdd_dot11Mode_support_11be(enum hdd_dot11_mode dot11Mode)
1871 {
1872 	if (dot11Mode != eHDD_DOT11_MODE_AUTO &&
1873 	    dot11Mode < eHDD_DOT11_MODE_11be)
1874 		return false;
1875 
1876 	return true;
1877 }
1878 
1879 static void
hdd_update_tid_to_link_supported(struct hdd_context * hdd_ctx,struct wma_tgt_services * cfg)1880 hdd_update_tid_to_link_supported(struct hdd_context *hdd_ctx,
1881 				 struct wma_tgt_services *cfg)
1882 {
1883 	if (!cfg->en_mlo_tid_to_link_support)
1884 		ucfg_mlme_set_t2lm_negotiation_supported(hdd_ctx->psoc,
1885 							 T2LM_NEGOTIATION_DISABLED);
1886 }
1887 
1888 #else
hdd_dot11Mode_support_11be(enum hdd_dot11_mode dot11Mode)1889 static bool hdd_dot11Mode_support_11be(enum hdd_dot11_mode dot11Mode)
1890 {
1891 	return false;
1892 }
1893 
1894 static inline void
hdd_update_tid_to_link_supported(struct hdd_context * hdd_ctx,struct wma_tgt_services * cfg)1895 hdd_update_tid_to_link_supported(struct hdd_context *hdd_ctx,
1896 				 struct wma_tgt_services *cfg)
1897 {
1898 }
1899 #endif
1900 
1901 #ifdef WLAN_FEATURE_11BE_MLO
1902 static void
hdd_update_mlo_per_link_stats_capability(struct hdd_context * hdd_ctx,struct wma_tgt_services * cfg)1903 hdd_update_mlo_per_link_stats_capability(struct hdd_context *hdd_ctx,
1904 					 struct wma_tgt_services *cfg)
1905 {
1906 	hdd_ctx->is_mlo_per_link_stats_supported =
1907 				cfg->is_mlo_per_link_stats_supported;
1908 }
1909 #else
1910 static void
hdd_update_mlo_per_link_stats_capability(struct hdd_context * hdd_ctx,struct wma_tgt_services * cfg)1911 hdd_update_mlo_per_link_stats_capability(struct hdd_context *hdd_ctx,
1912 					 struct wma_tgt_services *cfg)
1913 {
1914 }
1915 #endif
1916 
hdd_update_tgt_services(struct hdd_context * hdd_ctx,struct wma_tgt_services * cfg)1917 static void hdd_update_tgt_services(struct hdd_context *hdd_ctx,
1918 				    struct wma_tgt_services *cfg)
1919 {
1920 	struct hdd_config *config = hdd_ctx->config;
1921 	bool arp_offload_enable;
1922 	bool mawc_enabled;
1923 #ifdef FEATURE_WLAN_TDLS
1924 	bool tdls_support;
1925 	bool tdls_off_channel;
1926 	bool tdls_buffer_sta;
1927 	uint32_t tdls_uapsd_mask;
1928 #endif
1929 	bool get_peer_info_enable;
1930 
1931 	/* Set up UAPSD */
1932 	ucfg_mlme_set_sap_uapsd_flag(hdd_ctx->psoc, cfg->uapsd);
1933 
1934 	/* 11AX mode support */
1935 	if ((config->dot11Mode == eHDD_DOT11_MODE_11ax ||
1936 	     config->dot11Mode == eHDD_DOT11_MODE_11ax_ONLY) && !cfg->en_11ax)
1937 		config->dot11Mode = eHDD_DOT11_MODE_11ac;
1938 
1939 	/* 11AC mode support */
1940 	if ((config->dot11Mode == eHDD_DOT11_MODE_11ac ||
1941 	     config->dot11Mode == eHDD_DOT11_MODE_11ac_ONLY) && !cfg->en_11ac)
1942 		config->dot11Mode = eHDD_DOT11_MODE_AUTO;
1943 
1944 	/* 11BE mode support */
1945 	if (cfg->en_11be &&
1946 	    (!hdd_dot11Mode_support_11be(config->dot11Mode) ||
1947 	     !wlan_reg_phybitmap_support_11be(hdd_ctx->pdev))) {
1948 		hdd_debug("dot11Mode %d override target en_11be to false",
1949 			  config->dot11Mode);
1950 		cfg->en_11be = false;
1951 	}
1952 
1953 	/* ARP offload: override user setting if invalid  */
1954 	arp_offload_enable =
1955 			ucfg_pmo_is_arp_offload_enabled(hdd_ctx->psoc);
1956 	ucfg_pmo_set_arp_offload_enabled(hdd_ctx->psoc,
1957 					 arp_offload_enable & cfg->arp_offload);
1958 
1959 	/* Intersect igmp offload ini configuration and fw cap*/
1960 	hdd_intersect_igmp_offload_setting(hdd_ctx->psoc, cfg);
1961 
1962 #ifdef FEATURE_WLAN_SCAN_PNO
1963 	/* PNO offload */
1964 	hdd_debug("PNO Capability in f/w = %d", cfg->pno_offload);
1965 	if (cfg->pno_offload)
1966 		ucfg_scan_set_pno_offload(hdd_ctx->psoc, true);
1967 #endif
1968 #ifdef FEATURE_WLAN_TDLS
1969 	cfg_tdls_get_support_enable(hdd_ctx->psoc, &tdls_support);
1970 	cfg_tdls_set_support_enable(hdd_ctx->psoc,
1971 				    tdls_support & cfg->en_tdls);
1972 
1973 	cfg_tdls_get_off_channel_enable(hdd_ctx->psoc, &tdls_off_channel);
1974 	cfg_tdls_set_off_channel_enable(hdd_ctx->psoc,
1975 					tdls_off_channel &&
1976 					cfg->en_tdls_offchan);
1977 
1978 	cfg_tdls_get_buffer_sta_enable(hdd_ctx->psoc, &tdls_buffer_sta);
1979 	cfg_tdls_set_buffer_sta_enable(hdd_ctx->psoc,
1980 				       tdls_buffer_sta &&
1981 				       cfg->en_tdls_uapsd_buf_sta);
1982 
1983 	cfg_tdls_get_uapsd_mask(hdd_ctx->psoc, &tdls_uapsd_mask);
1984 	if (tdls_uapsd_mask && cfg->en_tdls_uapsd_sleep_sta)
1985 		cfg_tdls_set_sleep_sta_enable(hdd_ctx->psoc, true);
1986 	else
1987 		cfg_tdls_set_sleep_sta_enable(hdd_ctx->psoc, false);
1988 #endif
1989 	hdd_update_roam_offload(hdd_ctx, cfg);
1990 
1991 	if (ucfg_mlme_get_sap_get_peer_info(
1992 		hdd_ctx->psoc, &get_peer_info_enable) == QDF_STATUS_SUCCESS) {
1993 		get_peer_info_enable &= cfg->get_peer_info_enabled;
1994 		ucfg_mlme_set_sap_get_peer_info(hdd_ctx->psoc,
1995 						get_peer_info_enable);
1996 	}
1997 
1998 	ucfg_mlme_is_mawc_enabled(hdd_ctx->psoc, &mawc_enabled);
1999 	ucfg_mlme_set_mawc_enabled(hdd_ctx->psoc,
2000 				   mawc_enabled & cfg->is_fw_mawc_capable);
2001 	hdd_update_tdls_config(hdd_ctx);
2002 	sme_update_tgt_services(hdd_ctx->mac_handle, cfg);
2003 	hdd_ctx->roam_ch_from_fw_supported = cfg->is_roam_scan_ch_to_host;
2004 	hdd_ctx->ll_stats_per_chan_rx_tx_time =
2005 					cfg->ll_stats_per_chan_rx_tx_time;
2006 
2007 	hdd_update_feature_cfg_club_get_sta_in_ll_stats_req(hdd_ctx, cfg);
2008 	hdd_ctx->is_therm_cmd_supp =
2009 				cfg->is_fw_therm_throt_supp &&
2010 				cfg_get(hdd_ctx->psoc,
2011 					CFG_THERMAL_MITIGATION_ENABLE);
2012 	hdd_update_fw_tdls_11ax_capability(hdd_ctx, cfg);
2013 	hdd_update_fw_tdls_mlo_capability(hdd_ctx, cfg);
2014 	hdd_set_dynamic_macaddr_update_capability(hdd_ctx, cfg);
2015 	hdd_update_fw_tdls_6g_capability(hdd_ctx, cfg);
2016 	hdd_update_fw_tdls_wideband_capability(hdd_ctx, cfg);
2017 	ucfg_psoc_mlme_set_11be_capab(hdd_ctx->psoc, cfg->en_11be);
2018 	hdd_update_mlo_per_link_stats_capability(hdd_ctx, cfg);
2019 }
2020 
2021 /**
2022  * hdd_update_vdev_nss() - sets the vdev nss
2023  * @hdd_ctx: HDD context
2024  *
2025  * Sets the Nss per vdev type based on INI
2026  *
2027  * Return: None
2028  */
hdd_update_vdev_nss(struct hdd_context * hdd_ctx)2029 static void hdd_update_vdev_nss(struct hdd_context *hdd_ctx)
2030 {
2031 	uint8_t max_supp_nss = 1;
2032 	mac_handle_t mac_handle;
2033 	QDF_STATUS status;
2034 	bool bval;
2035 
2036 	status = ucfg_mlme_get_vht_enable2x2(hdd_ctx->psoc, &bval);
2037 	if (!QDF_IS_STATUS_SUCCESS(status))
2038 		hdd_err("unable to get vht_enable2x2");
2039 
2040 	if (bval && !cds_is_sub_20_mhz_enabled())
2041 		max_supp_nss = 2;
2042 
2043 	hdd_debug("max nss %d", max_supp_nss);
2044 
2045 	mac_handle = hdd_ctx->mac_handle;
2046 	sme_update_vdev_type_nss(mac_handle, max_supp_nss,
2047 				 NSS_CHAINS_BAND_2GHZ);
2048 
2049 	sme_update_vdev_type_nss(mac_handle, max_supp_nss,
2050 				 NSS_CHAINS_BAND_5GHZ);
2051 }
2052 
2053 /**
2054  * hdd_update_2g_wiphy_vhtcap() - Updates 2G wiphy vhtcap fields
2055  * @hdd_ctx: HDD context
2056  *
2057  * Updates 2G wiphy vhtcap fields
2058  *
2059  * Return: None
2060  */
hdd_update_2g_wiphy_vhtcap(struct hdd_context * hdd_ctx)2061 static void hdd_update_2g_wiphy_vhtcap(struct hdd_context *hdd_ctx)
2062 {
2063 	struct ieee80211_supported_band *band_2g =
2064 		hdd_ctx->wiphy->bands[NL80211_BAND_2GHZ];
2065 	uint32_t value;
2066 	bool is_vht_24ghz;
2067 
2068 	if (!band_2g) {
2069 		hdd_debug("2GHz band disabled, skipping capability population");
2070 		return;
2071 	}
2072 
2073 	ucfg_mlme_get_vht_for_24ghz(hdd_ctx->psoc, &is_vht_24ghz);
2074 
2075 	if (is_vht_24ghz) {
2076 		ucfg_mlme_cfg_get_vht_tx_mcs_map(hdd_ctx->psoc, &value);
2077 		band_2g->vht_cap.vht_mcs.tx_mcs_map = value;
2078 	}
2079 }
2080 
2081 /**
2082  * hdd_update_5g_wiphy_vhtcap() - Updates 5G wiphy vhtcap fields
2083  * @hdd_ctx: HDD context
2084  *
2085  * Updates 5G wiphy vhtcap fields
2086  *
2087  * Return: None
2088  */
hdd_update_5g_wiphy_vhtcap(struct hdd_context * hdd_ctx)2089 static void hdd_update_5g_wiphy_vhtcap(struct hdd_context *hdd_ctx)
2090 {
2091 	struct ieee80211_supported_band *band_5g =
2092 		hdd_ctx->wiphy->bands[NL80211_BAND_5GHZ];
2093 	QDF_STATUS status;
2094 	uint8_t value = 0, value1 = 0;
2095 	uint32_t value2;
2096 
2097 	if (!band_5g) {
2098 		hdd_debug("5GHz band disabled, skipping capability population");
2099 		return;
2100 	}
2101 
2102 	status = ucfg_mlme_cfg_get_vht_tx_bfee_ant_supp(hdd_ctx->psoc,
2103 							&value);
2104 	if (!QDF_IS_STATUS_SUCCESS(status))
2105 		hdd_err("unable to get tx_bfee_ant_supp");
2106 
2107 	band_5g->vht_cap.cap |=
2108 			(value << IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT);
2109 
2110 	value1 = NUM_OF_SOUNDING_DIMENSIONS;
2111 	band_5g->vht_cap.cap |=
2112 		(value1 << IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_SHIFT);
2113 
2114 	hdd_debug("Updated wiphy vhtcap:0x%x, CSNAntSupp:%d, NumSoundDim:%d",
2115 		  band_5g->vht_cap.cap, value, value1);
2116 
2117 	ucfg_mlme_cfg_get_vht_rx_mcs_map(hdd_ctx->psoc, &value2);
2118 	band_5g->vht_cap.vht_mcs.rx_mcs_map = value2;
2119 
2120 	ucfg_mlme_cfg_get_vht_tx_mcs_map(hdd_ctx->psoc, &value2);
2121 	band_5g->vht_cap.vht_mcs.tx_mcs_map = value2;
2122 }
2123 
2124 /**
2125  * hdd_update_wiphy_vhtcap() - Updates wiphy vhtcap fields
2126  * @hdd_ctx: HDD context
2127  *
2128  * Updates wiphy vhtcap fields
2129  *
2130  * Return: None
2131  */
hdd_update_wiphy_vhtcap(struct hdd_context * hdd_ctx)2132 static void hdd_update_wiphy_vhtcap(struct hdd_context *hdd_ctx)
2133 {
2134 	hdd_update_2g_wiphy_vhtcap(hdd_ctx);
2135 	hdd_update_5g_wiphy_vhtcap(hdd_ctx);
2136 }
2137 
hdd_update_tgt_ht_cap(struct hdd_context * hdd_ctx,struct wma_tgt_ht_cap * cfg)2138 static void hdd_update_tgt_ht_cap(struct hdd_context *hdd_ctx,
2139 				  struct wma_tgt_ht_cap *cfg)
2140 {
2141 	QDF_STATUS status;
2142 	qdf_size_t value_len;
2143 	uint32_t value;
2144 	uint8_t mpdu_density;
2145 	struct mlme_ht_capabilities_info ht_cap_info;
2146 	uint8_t mcs_set[SIZE_OF_SUPPORTED_MCS_SET];
2147 	bool b_enable1x1;
2148 
2149 	/* get the MPDU density */
2150 	status = ucfg_mlme_get_ht_mpdu_density(hdd_ctx->psoc, &mpdu_density);
2151 	if (QDF_IS_STATUS_ERROR(status)) {
2152 		hdd_err("could not get HT MPDU Density");
2153 		return;
2154 	}
2155 
2156 	/*
2157 	 * MPDU density:
2158 	 * override user's setting if value is larger
2159 	 * than the one supported by target,
2160 	 * if target value is 0, then follow user's setting.
2161 	 */
2162 	if (cfg->mpdu_density && mpdu_density > cfg->mpdu_density) {
2163 		status = ucfg_mlme_set_ht_mpdu_density(hdd_ctx->psoc,
2164 						       cfg->mpdu_density);
2165 		if (QDF_IS_STATUS_ERROR(status))
2166 			hdd_err("could not set HT capability to CCM");
2167 	}
2168 
2169 	/* get the HT capability info */
2170 	status = ucfg_mlme_get_ht_cap_info(hdd_ctx->psoc, &ht_cap_info);
2171 	if (QDF_STATUS_SUCCESS != status) {
2172 		hdd_err("could not get HT capability info");
2173 		return;
2174 	}
2175 
2176 	/* check and update RX STBC */
2177 	if (ht_cap_info.rx_stbc && !cfg->ht_rx_stbc)
2178 		ht_cap_info.rx_stbc = cfg->ht_rx_stbc;
2179 
2180 	/* Set the LDPC capability */
2181 	if (ht_cap_info.adv_coding_cap && !cfg->ht_rx_ldpc)
2182 		ht_cap_info.adv_coding_cap = cfg->ht_rx_ldpc;
2183 
2184 	if (ht_cap_info.short_gi_20_mhz && !cfg->ht_sgi_20)
2185 		ht_cap_info.short_gi_20_mhz = cfg->ht_sgi_20;
2186 
2187 	if (ht_cap_info.short_gi_40_mhz && !cfg->ht_sgi_40)
2188 		ht_cap_info.short_gi_40_mhz = cfg->ht_sgi_40;
2189 
2190 	hdd_debug("gHtSMPS ini: %d, dynamic_smps fw cap: %d",
2191 		  ht_cap_info.mimo_power_save, cfg->dynamic_smps);
2192 	if (ht_cap_info.mimo_power_save == HDD_SMPS_MODE_DYNAMIC) {
2193 		if (cfg->dynamic_smps)
2194 			ht_cap_info.mimo_power_save = HDD_SMPS_MODE_DYNAMIC;
2195 		else
2196 			ht_cap_info.mimo_power_save = HDD_SMPS_MODE_DISABLED;
2197 	}
2198 
2199 	hdd_ctx->num_rf_chains = cfg->num_rf_chains;
2200 	hdd_ctx->ht_tx_stbc_supported = cfg->ht_tx_stbc;
2201 
2202 	status = ucfg_mlme_get_vht_enable2x2(hdd_ctx->psoc, &b_enable1x1);
2203 	if (!QDF_IS_STATUS_SUCCESS(status))
2204 		hdd_err("unable to get vht_enable2x2");
2205 
2206 	b_enable1x1 = b_enable1x1 && (cfg->num_rf_chains == 2);
2207 
2208 	status = ucfg_mlme_set_vht_enable2x2(hdd_ctx->psoc, b_enable1x1);
2209 	if (!QDF_IS_STATUS_SUCCESS(status))
2210 		hdd_err("unable to set vht_enable2x2");
2211 
2212 	if (!b_enable1x1)
2213 		ht_cap_info.tx_stbc = 0;
2214 
2215 	if (!(cfg->ht_tx_stbc && b_enable1x1))
2216 		ht_cap_info.tx_stbc = 0;
2217 
2218 	status = ucfg_mlme_set_ht_cap_info(hdd_ctx->psoc, ht_cap_info);
2219 	if (status != QDF_STATUS_SUCCESS)
2220 		hdd_err("could not set HT capability to CCM");
2221 #define WLAN_HDD_RX_MCS_ALL_NSTREAM_RATES 0xff
2222 	value_len = SIZE_OF_SUPPORTED_MCS_SET;
2223 	if (ucfg_mlme_get_supported_mcs_set(
2224 				hdd_ctx->psoc, mcs_set,
2225 				&value_len) == QDF_STATUS_SUCCESS) {
2226 		hdd_debug("Read MCS rate set");
2227 		if (cfg->num_rf_chains > SIZE_OF_SUPPORTED_MCS_SET)
2228 			cfg->num_rf_chains = SIZE_OF_SUPPORTED_MCS_SET;
2229 
2230 		if (b_enable1x1) {
2231 			for (value = 0; value < cfg->num_rf_chains; value++)
2232 				mcs_set[value] =
2233 					WLAN_HDD_RX_MCS_ALL_NSTREAM_RATES;
2234 
2235 			status = ucfg_mlme_set_supported_mcs_set(
2236 					hdd_ctx->psoc,
2237 					mcs_set,
2238 					(qdf_size_t)SIZE_OF_SUPPORTED_MCS_SET);
2239 			if (QDF_IS_STATUS_ERROR(status))
2240 				hdd_err("could not set MCS SET to CCM");
2241 		}
2242 	}
2243 #undef WLAN_HDD_RX_MCS_ALL_NSTREAM_RATES
2244 }
2245 
hdd_update_tgt_vht_cap(struct hdd_context * hdd_ctx,struct wma_tgt_vht_cap * cfg)2246 static void hdd_update_tgt_vht_cap(struct hdd_context *hdd_ctx,
2247 				   struct wma_tgt_vht_cap *cfg)
2248 {
2249 	QDF_STATUS status;
2250 	struct wiphy *wiphy = hdd_ctx->wiphy;
2251 	struct ieee80211_supported_band *band_5g =
2252 		wiphy->bands[HDD_NL80211_BAND_5GHZ];
2253 	uint32_t ch_width;
2254 	struct wma_caps_per_phy caps_per_phy = {0};
2255 	bool vht_enable_2x2;
2256 	uint32_t tx_highest_data_rate;
2257 	uint32_t rx_highest_data_rate;
2258 
2259 	if (!band_5g) {
2260 		hdd_debug("5GHz band disabled, skipping capability population");
2261 		return;
2262 	}
2263 
2264 	status = ucfg_mlme_update_vht_cap(hdd_ctx->psoc, cfg);
2265 	if (QDF_IS_STATUS_ERROR(status))
2266 		hdd_err("could not update vht capabilities");
2267 
2268 	status = ucfg_mlme_get_vht_enable2x2(hdd_ctx->psoc, &vht_enable_2x2);
2269 	if (!QDF_IS_STATUS_SUCCESS(status))
2270 		hdd_err("unable to get vht_enable2x2");
2271 
2272 	if (vht_enable_2x2) {
2273 		tx_highest_data_rate =
2274 				VHT_TX_HIGHEST_SUPPORTED_DATA_RATE_2_2;
2275 		rx_highest_data_rate =
2276 				VHT_RX_HIGHEST_SUPPORTED_DATA_RATE_2_2;
2277 	} else {
2278 		tx_highest_data_rate =
2279 				VHT_TX_HIGHEST_SUPPORTED_DATA_RATE_1_1;
2280 		rx_highest_data_rate =
2281 				VHT_RX_HIGHEST_SUPPORTED_DATA_RATE_1_1;
2282 	}
2283 
2284 	status = ucfg_mlme_cfg_set_vht_rx_supp_data_rate(hdd_ctx->psoc,
2285 							 rx_highest_data_rate);
2286 	if (!QDF_IS_STATUS_SUCCESS(status))
2287 		hdd_err("Failed to set rx_supp_data_rate");
2288 
2289 	status = ucfg_mlme_cfg_set_vht_tx_supp_data_rate(hdd_ctx->psoc,
2290 							 tx_highest_data_rate);
2291 	if (!QDF_IS_STATUS_SUCCESS(status))
2292 		hdd_err("Failed to set tx_supp_data_rate");
2293 
2294 	/* Update the real highest data rate to wiphy */
2295 	if (cfg->vht_short_gi_80 & WMI_VHT_CAP_SGI_80MHZ) {
2296 		if (vht_enable_2x2) {
2297 			tx_highest_data_rate =
2298 				VHT_TX_HIGHEST_SUPPORTED_DATA_RATE_2_2_SGI80;
2299 			rx_highest_data_rate =
2300 				VHT_RX_HIGHEST_SUPPORTED_DATA_RATE_2_2_SGI80;
2301 		} else {
2302 			tx_highest_data_rate =
2303 				VHT_TX_HIGHEST_SUPPORTED_DATA_RATE_1_1_SGI80;
2304 			rx_highest_data_rate =
2305 				VHT_RX_HIGHEST_SUPPORTED_DATA_RATE_1_1_SGI80;
2306 		}
2307 	}
2308 
2309 	if (WMI_VHT_CAP_MAX_MPDU_LEN_11454 == cfg->vht_max_mpdu)
2310 		band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454;
2311 	else if (WMI_VHT_CAP_MAX_MPDU_LEN_7935 == cfg->vht_max_mpdu)
2312 		band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_7991;
2313 	else
2314 		band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_3895;
2315 
2316 
2317 	if (cfg->supp_chan_width & (1 << eHT_CHANNEL_WIDTH_80P80MHZ)) {
2318 		band_5g->vht_cap.cap |=
2319 			IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ;
2320 		ch_width = VHT_CAP_160_AND_80P80_SUPP;
2321 	} else if (cfg->supp_chan_width & (1 << eHT_CHANNEL_WIDTH_160MHZ)) {
2322 		band_5g->vht_cap.cap |=
2323 			IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ;
2324 		ch_width = VHT_CAP_160_SUPP;
2325 	} else {
2326 		ch_width = VHT_CAP_NO_160M_SUPP;
2327 	}
2328 
2329 	status = ucfg_mlme_set_vht_ch_width(hdd_ctx->psoc, ch_width);
2330 	if (QDF_IS_STATUS_ERROR(status))
2331 		hdd_err("could not set the channel width");
2332 	else
2333 		hdd_debug("supported channel width %d", ch_width);
2334 
2335 	if (cfg->vht_rx_ldpc & WMI_VHT_CAP_RX_LDPC) {
2336 		band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_RXLDPC;
2337 		hdd_debug("VHT RxLDPC capability is set");
2338 	} else {
2339 		/*
2340 		 * Get the RX LDPC capability for the NON DBS
2341 		 * hardware mode for 5G band
2342 		 */
2343 		status = wma_get_caps_for_phyidx_hwmode(&caps_per_phy,
2344 					HW_MODE_DBS_NONE, CDS_BAND_5GHZ);
2345 		if ((QDF_IS_STATUS_SUCCESS(status)) &&
2346 			(caps_per_phy.vht_5g & WMI_VHT_CAP_RX_LDPC)) {
2347 			band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_RXLDPC;
2348 			hdd_debug("VHT RX LDPC capability is set");
2349 		}
2350 	}
2351 
2352 	if (cfg->vht_short_gi_80 & WMI_VHT_CAP_SGI_80MHZ)
2353 		band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_SHORT_GI_80;
2354 	if (cfg->vht_short_gi_160 & WMI_VHT_CAP_SGI_160MHZ)
2355 		band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_SHORT_GI_160;
2356 
2357 	if (vht_enable_2x2 && (cfg->vht_tx_stbc & WMI_VHT_CAP_TX_STBC))
2358 		band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_TXSTBC;
2359 
2360 	if (cfg->vht_rx_stbc & WMI_VHT_CAP_RX_STBC_1SS)
2361 		band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_RXSTBC_1;
2362 	if (vht_enable_2x2 && (cfg->vht_rx_stbc & WMI_VHT_CAP_RX_STBC_2SS))
2363 		band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_RXSTBC_2;
2364 	if (cfg->vht_rx_stbc & WMI_VHT_CAP_RX_STBC_3SS)
2365 		band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_RXSTBC_3;
2366 
2367 	band_5g->vht_cap.cap |=
2368 		(cfg->vht_max_ampdu_len_exp <<
2369 		 IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT);
2370 
2371 	if (cfg->vht_su_bformer & WMI_VHT_CAP_SU_BFORMER)
2372 		band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE;
2373 	if (cfg->vht_su_bformee & WMI_VHT_CAP_SU_BFORMEE)
2374 		band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE;
2375 	if (cfg->vht_mu_bformer & WMI_VHT_CAP_MU_BFORMER)
2376 		band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE;
2377 	if (cfg->vht_mu_bformee & WMI_VHT_CAP_MU_BFORMEE)
2378 		band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE;
2379 
2380 	if (cfg->vht_txop_ps & WMI_VHT_CAP_TXOP_PS)
2381 		band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_VHT_TXOP_PS;
2382 
2383 	band_5g->vht_cap.vht_mcs.rx_highest = cpu_to_le16(rx_highest_data_rate);
2384 	band_5g->vht_cap.vht_mcs.tx_highest = cpu_to_le16(tx_highest_data_rate);
2385 }
2386 
2387 /**
2388  * hdd_generate_macaddr_auto() - Auto-generate mac address
2389  * @hdd_ctx: Pointer to the HDD context
2390  *
2391  * Auto-generate mac address using device serial number.
2392  * Keep the first 3 bytes of OUI as before and replace
2393  * the last 3 bytes with the lower 3 bytes of serial number.
2394  *
2395  * Return: 0 for success
2396  *         Non zero failure code for errors
2397  */
hdd_generate_macaddr_auto(struct hdd_context * hdd_ctx)2398 static int hdd_generate_macaddr_auto(struct hdd_context *hdd_ctx)
2399 {
2400 	unsigned int serialno = 0;
2401 	struct qdf_mac_addr mac_addr = {
2402 		{0x00, 0x0A, 0xF5, 0x00, 0x00, 0x00}
2403 	};
2404 
2405 	serialno = pld_socinfo_get_serial_number(hdd_ctx->parent_dev);
2406 	if (serialno == 0)
2407 		return -EINVAL;
2408 
2409 	serialno &= 0x00ffffff;
2410 
2411 	mac_addr.bytes[3] = (serialno >> 16) & 0xff;
2412 	mac_addr.bytes[4] = (serialno >> 8) & 0xff;
2413 	mac_addr.bytes[5] = serialno & 0xff;
2414 
2415 	hdd_update_macaddr(hdd_ctx, mac_addr, true);
2416 	return 0;
2417 }
2418 
hdd_sar_target_config(struct hdd_context * hdd_ctx,struct wma_tgt_cfg * cfg)2419 static void hdd_sar_target_config(struct hdd_context *hdd_ctx,
2420 				  struct wma_tgt_cfg *cfg)
2421 {
2422 	hdd_ctx->sar_version = cfg->sar_version;
2423 }
2424 
hdd_update_vhtcap_2g(struct hdd_context * hdd_ctx)2425 static void hdd_update_vhtcap_2g(struct hdd_context *hdd_ctx)
2426 {
2427 	uint64_t chip_mode = 0;
2428 	QDF_STATUS status;
2429 	bool b2g_vht_cfg = false;
2430 	bool b2g_vht_target = false;
2431 	struct wma_caps_per_phy caps_per_phy = {0};
2432 	struct wmi_unified *wmi_handle;
2433 
2434 	wmi_handle = get_wmi_unified_hdl_from_psoc(hdd_ctx->psoc);
2435 	if (!wmi_handle) {
2436 		hdd_err("wmi handle is NULL");
2437 		return;
2438 	}
2439 
2440 	status = ucfg_mlme_get_vht_for_24ghz(hdd_ctx->psoc, &b2g_vht_cfg);
2441 	if (QDF_IS_STATUS_ERROR(status)) {
2442 		hdd_err("Failed to get 2g vht mode");
2443 		return;
2444 	}
2445 	if (wmi_service_enabled(wmi_handle, wmi_service_ext_msg)) {
2446 		status = wma_get_caps_for_phyidx_hwmode(&caps_per_phy,
2447 							HW_MODE_DBS_NONE,
2448 							CDS_BAND_2GHZ);
2449 		if (QDF_IS_STATUS_ERROR(status)) {
2450 			hdd_err("Failed to get phy caps");
2451 			return;
2452 		}
2453 		if (caps_per_phy.vht_2g)
2454 			b2g_vht_target = true;
2455 	} else {
2456 		status = wlan_reg_get_chip_mode(hdd_ctx->pdev, &chip_mode);
2457 		if (QDF_IS_STATUS_ERROR(status)) {
2458 			hdd_err("Failed to get chip mode");
2459 			return;
2460 		}
2461 		b2g_vht_target =
2462 		(chip_mode & HOST_REGDMN_MODE_11AC_VHT20_2G) ?
2463 		true : false;
2464 	}
2465 
2466 	b2g_vht_cfg = b2g_vht_cfg && b2g_vht_target;
2467 	hdd_debug("vht 2g target: %d, cfg: %d", b2g_vht_target, b2g_vht_cfg);
2468 	status = ucfg_mlme_set_vht_for_24ghz(hdd_ctx->psoc, b2g_vht_cfg);
2469 	if (QDF_IS_STATUS_ERROR(status)) {
2470 		hdd_err("Failed to update 2g vht mode");
2471 		return;
2472 	}
2473 }
2474 
hdd_extract_fw_version_info(struct hdd_context * hdd_ctx)2475 static void hdd_extract_fw_version_info(struct hdd_context *hdd_ctx)
2476 {
2477 	hdd_ctx->fw_version_info.major_spid =
2478 			HDD_FW_VER_MAJOR_SPID(hdd_ctx->target_fw_version);
2479 	hdd_ctx->fw_version_info.minor_spid =
2480 			HDD_FW_VER_MINOR_SPID(hdd_ctx->target_fw_version);
2481 	hdd_ctx->fw_version_info.siid =
2482 			HDD_FW_VER_SIID(hdd_ctx->target_fw_version);
2483 	hdd_ctx->fw_version_info.crmid =
2484 			HDD_FW_VER_CRM_ID(hdd_ctx->target_fw_version);
2485 	hdd_ctx->fw_version_info.sub_id =
2486 			HDD_FW_VER_SUB_ID(hdd_ctx->target_fw_vers_ext);
2487 	hdd_ctx->fw_version_info.rel_id =
2488 			HDD_FW_VER_REL_ID(hdd_ctx->target_fw_vers_ext);
2489 }
2490 
2491 #if defined(WLAN_FEATURE_11AX) && \
2492 	(defined(CFG80211_SBAND_IFTYPE_DATA_BACKPORT) || \
2493 	 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0)))
2494 
2495 static void
hdd_update_wiphy_he_mcs(struct ieee80211_sband_iftype_data * iftype_data,tDot11fIEhe_cap * he_cap_cfg)2496 hdd_update_wiphy_he_mcs(struct ieee80211_sband_iftype_data *iftype_data,
2497 			tDot11fIEhe_cap *he_cap_cfg)
2498 {
2499 	if (!iftype_data || !he_cap_cfg) {
2500 		hdd_err("Unable to update wiphy he_mcs");
2501 		return;
2502 	}
2503 
2504 	iftype_data->he_cap.he_mcs_nss_supp.tx_mcs_80 =
2505 		he_cap_cfg->tx_he_mcs_map_lt_80;
2506 	iftype_data->he_cap.he_mcs_nss_supp.tx_mcs_160 =
2507 		*((uint16_t *)he_cap_cfg->tx_he_mcs_map_160);
2508 	iftype_data->he_cap.he_mcs_nss_supp.tx_mcs_80p80 =
2509 		*((uint16_t *)he_cap_cfg->tx_he_mcs_map_80_80);
2510 }
2511 
2512 #if defined(CONFIG_BAND_6GHZ) && (defined(IEEE80211_HE_6GHZ_CAP_MIN_MPDU_START))
hdd_update_wiphy_he_6ghz_capa(struct hdd_context * hdd_ctx)2513 static void hdd_update_wiphy_he_6ghz_capa(struct hdd_context *hdd_ctx)
2514 {
2515 	uint16_t he_6ghz_capa = 0;
2516 	uint8_t min_mpdu_start_spacing;
2517 	uint8_t max_ampdu_len_exp;
2518 	uint8_t max_mpdu_len;
2519 	uint8_t sm_pow_save;
2520 
2521 	ucfg_mlme_get_ht_mpdu_density(hdd_ctx->psoc, &min_mpdu_start_spacing);
2522 	he_6ghz_capa |= FIELD_PREP(IEEE80211_HE_6GHZ_CAP_MIN_MPDU_START,
2523 				   min_mpdu_start_spacing);
2524 
2525 	ucfg_mlme_cfg_get_vht_ampdu_len_exp(hdd_ctx->psoc, &max_ampdu_len_exp);
2526 	he_6ghz_capa |= FIELD_PREP(IEEE80211_HE_6GHZ_CAP_MAX_AMPDU_LEN_EXP,
2527 				   max_ampdu_len_exp);
2528 
2529 	ucfg_mlme_cfg_get_vht_max_mpdu_len(hdd_ctx->psoc, &max_mpdu_len);
2530 	he_6ghz_capa |= FIELD_PREP(IEEE80211_HE_6GHZ_CAP_MAX_MPDU_LEN,
2531 				   max_mpdu_len);
2532 
2533 	ucfg_mlme_cfg_get_ht_smps(hdd_ctx->psoc, &sm_pow_save);
2534 	he_6ghz_capa |= FIELD_PREP(IEEE80211_HE_6GHZ_CAP_SM_PS, sm_pow_save);
2535 
2536 	he_6ghz_capa |= IEEE80211_HE_6GHZ_CAP_RX_ANTPAT_CONS;
2537 	he_6ghz_capa |= IEEE80211_HE_6GHZ_CAP_TX_ANTPAT_CONS;
2538 
2539 	hdd_ctx->iftype_data_6g->he_6ghz_capa.capa = he_6ghz_capa;
2540 }
2541 #else
hdd_update_wiphy_he_6ghz_capa(struct hdd_context * hdd_ctx)2542 static inline void hdd_update_wiphy_he_6ghz_capa(struct hdd_context *hdd_ctx)
2543 {
2544 }
2545 #endif
2546 
2547 #if defined(CONFIG_BAND_6GHZ) && (defined(CFG80211_6GHZ_BAND_SUPPORTED) || \
2548       (KERNEL_VERSION(5, 4, 0) <= LINUX_VERSION_CODE))
2549 static void
hdd_update_wiphy_he_caps_6ghz(struct hdd_context * hdd_ctx,tDot11fIEhe_cap * he_cap_cfg)2550 hdd_update_wiphy_he_caps_6ghz(struct hdd_context *hdd_ctx,
2551 			      tDot11fIEhe_cap *he_cap_cfg)
2552 {
2553 	struct ieee80211_supported_band *band_6g =
2554 		   hdd_ctx->wiphy->bands[HDD_NL80211_BAND_6GHZ];
2555 	uint8_t *phy_info =
2556 		    hdd_ctx->iftype_data_6g->he_cap.he_cap_elem.phy_cap_info;
2557 	uint8_t *mac_info_6g =
2558 		hdd_ctx->iftype_data_6g->he_cap.he_cap_elem.mac_cap_info;
2559 	uint8_t max_fw_bw = sme_get_vht_ch_width();
2560 
2561 	if (!band_6g || !phy_info) {
2562 		hdd_debug("6ghz not supported in wiphy");
2563 		return;
2564 	}
2565 
2566 	hdd_ctx->iftype_data_6g->types_mask =
2567 		(BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP));
2568 	hdd_ctx->iftype_data_6g->he_cap.has_he = true;
2569 	band_6g->n_iftype_data = 1;
2570 
2571 	if (max_fw_bw >= WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ)
2572 		phy_info[0] |=
2573 		      IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_80MHZ_IN_5G;
2574 	if (max_fw_bw >= WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ)
2575 		phy_info[0] |=
2576 			IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_160MHZ_IN_5G;
2577 	if (max_fw_bw >= WNI_CFG_VHT_CHANNEL_WIDTH_80_PLUS_80MHZ)
2578 		phy_info[0] |=
2579 		     IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G;
2580 
2581 	if (he_cap_cfg->twt_request)
2582 		mac_info_6g[0] |= IEEE80211_HE_MAC_CAP0_TWT_REQ;
2583 
2584 	if (he_cap_cfg->twt_responder)
2585 		mac_info_6g[0] |= IEEE80211_HE_MAC_CAP0_TWT_RES;
2586 
2587 	hdd_update_wiphy_he_6ghz_capa(hdd_ctx);
2588 
2589 	hdd_update_wiphy_he_mcs(hdd_ctx->iftype_data_6g, he_cap_cfg);
2590 
2591 	band_6g->iftype_data = hdd_ctx->iftype_data_6g;
2592 }
2593 #else
2594 static inline void
hdd_update_wiphy_he_caps_6ghz(struct hdd_context * hdd_ctx,tDot11fIEhe_cap * he_cap_cfg)2595 hdd_update_wiphy_he_caps_6ghz(struct hdd_context *hdd_ctx,
2596 			      tDot11fIEhe_cap *he_cap_cfg)
2597 {
2598 }
2599 #endif
2600 
hdd_update_wiphy_he_cap(struct hdd_context * hdd_ctx)2601 static void hdd_update_wiphy_he_cap(struct hdd_context *hdd_ctx)
2602 {
2603 	tDot11fIEhe_cap he_cap_cfg;
2604 	struct ieee80211_supported_band *band_2g =
2605 			hdd_ctx->wiphy->bands[HDD_NL80211_BAND_2GHZ];
2606 	struct ieee80211_supported_band *band_5g =
2607 			hdd_ctx->wiphy->bands[HDD_NL80211_BAND_5GHZ];
2608 	QDF_STATUS status;
2609 	uint8_t *phy_info_5g =
2610 		    hdd_ctx->iftype_data_5g->he_cap.he_cap_elem.phy_cap_info;
2611 	uint8_t max_fw_bw = sme_get_vht_ch_width();
2612 	uint32_t channel_bonding_mode_2g;
2613 	uint8_t *phy_info_2g =
2614 		    hdd_ctx->iftype_data_2g->he_cap.he_cap_elem.phy_cap_info;
2615 	uint8_t *mac_info_2g =
2616 		hdd_ctx->iftype_data_2g->he_cap.he_cap_elem.mac_cap_info;
2617 	uint8_t *mac_info_5g =
2618 		hdd_ctx->iftype_data_5g->he_cap.he_cap_elem.mac_cap_info;
2619 
2620 	status = ucfg_mlme_cfg_get_he_caps(hdd_ctx->psoc, &he_cap_cfg);
2621 
2622 	if (QDF_IS_STATUS_ERROR(status))
2623 		return;
2624 
2625 	if (band_2g) {
2626 		hdd_ctx->iftype_data_2g->types_mask =
2627 			(BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP));
2628 		hdd_ctx->iftype_data_2g->he_cap.has_he = he_cap_cfg.present;
2629 		band_2g->n_iftype_data = 1;
2630 		hdd_update_wiphy_he_mcs(hdd_ctx->iftype_data_2g, &he_cap_cfg);
2631 		band_2g->iftype_data = hdd_ctx->iftype_data_2g;
2632 
2633 		ucfg_mlme_get_channel_bonding_24ghz(hdd_ctx->psoc,
2634 						    &channel_bonding_mode_2g);
2635 		if (channel_bonding_mode_2g)
2636 			phy_info_2g[0] |=
2637 			    IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_IN_2G;
2638 
2639 		if (he_cap_cfg.twt_request)
2640 			mac_info_2g[0] |= IEEE80211_HE_MAC_CAP0_TWT_REQ;
2641 
2642 		if (he_cap_cfg.twt_responder)
2643 			mac_info_2g[0] |= IEEE80211_HE_MAC_CAP0_TWT_RES;
2644 	}
2645 	if (band_5g) {
2646 		hdd_ctx->iftype_data_5g->types_mask =
2647 			(BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP));
2648 		hdd_ctx->iftype_data_5g->he_cap.has_he = he_cap_cfg.present;
2649 		band_5g->n_iftype_data = 1;
2650 		hdd_update_wiphy_he_mcs(hdd_ctx->iftype_data_5g, &he_cap_cfg);
2651 		band_5g->iftype_data = hdd_ctx->iftype_data_5g;
2652 
2653 		if (max_fw_bw >= WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ)
2654 			phy_info_5g[0] |=
2655 				IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_80MHZ_IN_5G;
2656 		if (max_fw_bw >= WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ)
2657 			phy_info_5g[0] |=
2658 				IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_160MHZ_IN_5G;
2659 		if (max_fw_bw >= WNI_CFG_VHT_CHANNEL_WIDTH_80_PLUS_80MHZ)
2660 			phy_info_5g[0] |=
2661 			     IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G;
2662 
2663 		if (he_cap_cfg.twt_request)
2664 			mac_info_5g[0] |= IEEE80211_HE_MAC_CAP0_TWT_REQ;
2665 
2666 		if (he_cap_cfg.twt_responder)
2667 			mac_info_5g[0] |= IEEE80211_HE_MAC_CAP0_TWT_RES;
2668 	}
2669 
2670 	hdd_update_wiphy_he_caps_6ghz(hdd_ctx, &he_cap_cfg);
2671 }
2672 #else
hdd_update_wiphy_he_cap(struct hdd_context * hdd_ctx)2673 static void hdd_update_wiphy_he_cap(struct hdd_context *hdd_ctx)
2674 {
2675 }
2676 #endif
2677 
hdd_component_cfg_chan_to_freq(struct wlan_objmgr_pdev * pdev)2678 static void hdd_component_cfg_chan_to_freq(struct wlan_objmgr_pdev *pdev)
2679 {
2680 	ucfg_mlme_cfg_chan_to_freq(pdev);
2681 }
2682 
hdd_update_band_cap_from_dot11mode(struct hdd_context * hdd_ctx,uint32_t band_capability)2683 static uint32_t hdd_update_band_cap_from_dot11mode(
2684 		struct hdd_context *hdd_ctx, uint32_t band_capability)
2685 {
2686 	if (hdd_ctx->config->dot11Mode == eHDD_DOT11_MODE_AUTO)
2687 		return band_capability;
2688 
2689 	if (hdd_ctx->config->dot11Mode == eHDD_DOT11_MODE_11b ||
2690 	    hdd_ctx->config->dot11Mode == eHDD_DOT11_MODE_11g ||
2691 	    hdd_ctx->config->dot11Mode == eHDD_DOT11_MODE_11g_ONLY ||
2692 	    hdd_ctx->config->dot11Mode == eHDD_DOT11_MODE_11b_ONLY)
2693 		band_capability = (band_capability & (~BIT(REG_BAND_5G)));
2694 
2695 	if (hdd_ctx->config->dot11Mode == eHDD_DOT11_MODE_11a)
2696 		band_capability = (band_capability & (~BIT(REG_BAND_2G)));
2697 
2698 	if (hdd_ctx->config->dot11Mode != eHDD_DOT11_MODE_11ax_ONLY &&
2699 	    hdd_ctx->config->dot11Mode != eHDD_DOT11_MODE_11ax)
2700 		band_capability = (band_capability & (~BIT(REG_BAND_6G)));
2701 
2702 	qdf_debug("Update band capability %x", band_capability);
2703 	return band_capability;
2704 }
2705 
2706 #ifdef FEATURE_WPSS_THERMAL_MITIGATION
2707 static inline
hdd_update_multi_client_thermal_support(struct hdd_context * hdd_ctx)2708 void hdd_update_multi_client_thermal_support(struct hdd_context *hdd_ctx)
2709 {
2710 	struct wmi_unified *wmi_handle;
2711 
2712 	wmi_handle = get_wmi_unified_hdl_from_psoc(hdd_ctx->psoc);
2713 	if (!wmi_handle)
2714 		return;
2715 
2716 	hdd_ctx->multi_client_thermal_mitigation =
2717 		wmi_service_enabled(wmi_handle,
2718 				    wmi_service_thermal_multi_client_support);
2719 }
2720 #else
2721 static inline
hdd_update_multi_client_thermal_support(struct hdd_context * hdd_ctx)2722 void hdd_update_multi_client_thermal_support(struct hdd_context *hdd_ctx)
2723 {
2724 }
2725 #endif
2726 
2727 #ifdef WLAN_FEATURE_LOCAL_PKT_CAPTURE
hdd_lpc_enable_powersave(struct hdd_context * hdd_ctx)2728 static void hdd_lpc_enable_powersave(struct hdd_context *hdd_ctx)
2729 {
2730 	struct hdd_adapter *sta_adapter;
2731 
2732 	if (!ucfg_dp_is_local_pkt_capture_enabled(hdd_ctx->psoc))
2733 		return;
2734 
2735 	ucfg_fwol_configure_global_params(hdd_ctx->psoc, hdd_ctx->pdev);
2736 
2737 	if (wma_enable_disable_imps(hdd_ctx->pdev->pdev_objmgr.wlan_pdev_id, 1))
2738 		hdd_err("IMPS feature enable failed");
2739 
2740 	sta_adapter = hdd_get_adapter(hdd_ctx, QDF_STA_MODE);
2741 	if (!sta_adapter) {
2742 		hdd_debug("STA adapter does not exist");
2743 		return;
2744 	}
2745 
2746 	wlan_hdd_set_powersave(sta_adapter->deflink, true, 0);
2747 }
2748 
hdd_lpc_disable_powersave(struct hdd_context * hdd_ctx)2749 static void hdd_lpc_disable_powersave(struct hdd_context *hdd_ctx)
2750 {
2751 	struct hdd_adapter *sta_adapter;
2752 
2753 	if (!ucfg_dp_is_local_pkt_capture_enabled(hdd_ctx->psoc))
2754 		return;
2755 
2756 	ucfg_fwol_set_ilp_config(hdd_ctx->psoc, hdd_ctx->pdev, 0);
2757 
2758 	if (wma_enable_disable_imps(hdd_ctx->pdev->pdev_objmgr.wlan_pdev_id, 0))
2759 		hdd_err("IMPS feature disable failed");
2760 
2761 	sta_adapter = hdd_get_adapter(hdd_ctx, QDF_STA_MODE);
2762 	if (!sta_adapter) {
2763 		hdd_err("STA adapter does not exist");
2764 		return;
2765 	}
2766 	wlan_hdd_set_powersave(sta_adapter->deflink, false, 0);
2767 }
2768 #else
hdd_lpc_enable_powersave(struct hdd_context * hdd_ctx)2769 static inline void hdd_lpc_enable_powersave(struct hdd_context *hdd_ctx)
2770 {
2771 }
2772 
hdd_lpc_disable_powersave(struct hdd_context * hdd_ctx)2773 static inline void hdd_lpc_disable_powersave(struct hdd_context *hdd_ctx)
2774 {
2775 }
2776 #endif
2777 
hdd_update_tgt_cfg(hdd_handle_t hdd_handle,struct wma_tgt_cfg * cfg)2778 int hdd_update_tgt_cfg(hdd_handle_t hdd_handle, struct wma_tgt_cfg *cfg)
2779 {
2780 	int ret;
2781 	struct hdd_context *hdd_ctx = hdd_handle_to_context(hdd_handle);
2782 	uint32_t temp_band_cap, band_capability;
2783 	struct cds_config_info *cds_cfg = cds_get_ini_config();
2784 	uint8_t antenna_mode;
2785 	uint8_t sub_20_chan_width;
2786 	QDF_STATUS status;
2787 	mac_handle_t mac_handle;
2788 	bool bval = false;
2789 	uint8_t value = 0;
2790 	uint32_t fine_time_meas_cap = 0;
2791 	enum nss_chains_band_info band;
2792 	bool enable_dynamic_cfg;
2793 
2794 	if (!hdd_ctx) {
2795 		hdd_err("HDD context is NULL");
2796 		return -EINVAL;
2797 	}
2798 	ret = hdd_objmgr_create_and_store_pdev(hdd_ctx);
2799 	if (ret) {
2800 		QDF_DEBUG_PANIC("Failed to create pdev; errno:%d", ret);
2801 		return -EINVAL;
2802 	}
2803 
2804 	hdd_debug("New pdev has been created with pdev_id = %u",
2805 		  hdd_ctx->pdev->pdev_objmgr.wlan_pdev_id);
2806 
2807 	status = dispatcher_pdev_open(hdd_ctx->pdev);
2808 	if (QDF_IS_STATUS_ERROR(status)) {
2809 		QDF_DEBUG_PANIC("dispatcher pdev open failed; status:%d",
2810 				status);
2811 		ret = qdf_status_to_os_return(status);
2812 		goto exit;
2813 	}
2814 
2815 	status = hdd_component_pdev_open(hdd_ctx->pdev);
2816 	if (QDF_IS_STATUS_ERROR(status)) {
2817 		QDF_DEBUG_PANIC("hdd component pdev open failed; status:%d",
2818 				status);
2819 		ret = qdf_status_to_os_return(status);
2820 		goto dispatcher_close;
2821 	}
2822 	/*
2823 	 * For 6GHz support this api is added to convert mlme cfgs
2824 	 * channel numbers to frequency
2825 	 */
2826 	hdd_component_cfg_chan_to_freq(hdd_ctx->pdev);
2827 
2828 	hdd_objmgr_update_tgt_max_vdev_psoc(hdd_ctx, cfg->max_intf_count);
2829 
2830 	ucfg_ipa_set_dp_handle(hdd_ctx->psoc,
2831 			       cds_get_context(QDF_MODULE_ID_SOC));
2832 	ucfg_ipa_set_pdev_id(hdd_ctx->psoc, OL_TXRX_PDEV_ID);
2833 
2834 	status = ucfg_mlme_get_sub_20_chan_width(hdd_ctx->psoc,
2835 						 &sub_20_chan_width);
2836 	if (QDF_IS_STATUS_ERROR(status)) {
2837 		hdd_err("Failed to get sub_20_chan_width config");
2838 		ret = qdf_status_to_os_return(status);
2839 		goto pdev_close;
2840 	}
2841 
2842 	if (cds_cfg) {
2843 		if (sub_20_chan_width !=
2844 		    WLAN_SUB_20_CH_WIDTH_NONE && !cfg->sub_20_support) {
2845 			hdd_err("User requested sub 20 MHz channel width but unsupported by FW.");
2846 			cds_cfg->sub_20_channel_width =
2847 				WLAN_SUB_20_CH_WIDTH_NONE;
2848 		} else {
2849 			cds_cfg->sub_20_channel_width = sub_20_chan_width;
2850 		}
2851 	}
2852 
2853 	status = ucfg_mlme_get_band_capability(hdd_ctx->psoc, &band_capability);
2854 	if (QDF_IS_STATUS_ERROR(status)) {
2855 		hdd_err("Failed to get MLME band capability");
2856 		ret = qdf_status_to_os_return(status);
2857 		goto pdev_close;
2858 	}
2859 
2860 	band_capability =
2861 		hdd_update_band_cap_from_dot11mode(hdd_ctx, band_capability);
2862 
2863 	/* first store the INI band capability */
2864 	temp_band_cap = band_capability;
2865 
2866 	band_capability = cfg->band_cap;
2867 	hdd_ctx->is_fils_roaming_supported =
2868 			cfg->services.is_fils_roaming_supported;
2869 
2870 	hdd_ctx->config->is_11k_offload_supported =
2871 			cfg->services.is_11k_offload_supported;
2872 
2873 	/*
2874 	 * merge the target band capability with INI setting if the merge has
2875 	 * at least 1 band enabled
2876 	 */
2877 	temp_band_cap &= band_capability;
2878 	if (!temp_band_cap)
2879 		hdd_warn("ini BandCapability not supported by the target");
2880 	else
2881 		band_capability = temp_band_cap;
2882 
2883 	status = ucfg_mlme_set_band_capability(hdd_ctx->psoc, band_capability);
2884 	if (QDF_IS_STATUS_ERROR(status)) {
2885 		hdd_err("Failed to set MLME Band Capability");
2886 		ret = qdf_status_to_os_return(status);
2887 		goto pdev_close;
2888 	}
2889 
2890 	hdd_ctx->curr_band = band_capability;
2891 	hdd_ctx->psoc->soc_nif.user_config.band_capability = hdd_ctx->curr_band;
2892 
2893 	status = wlan_hdd_update_wiphy_supported_band(hdd_ctx);
2894 	if (QDF_IS_STATUS_ERROR(status)) {
2895 		hdd_err("Failed to update wiphy band info");
2896 		goto pdev_close;
2897 	}
2898 
2899 	status = ucfg_reg_set_band(hdd_ctx->pdev, band_capability);
2900 	if (QDF_IS_STATUS_ERROR(status))
2901 		/*
2902 		 * Continue, Do not close the pdev from here as if host fails
2903 		 * to update band information if cc_list event is not received
2904 		 * by this time, then also driver load should happen.
2905 		 */
2906 		hdd_err("Failed to update regulatory band info");
2907 
2908 	if (!cds_is_driver_recovering() || cds_is_driver_in_bad_state()) {
2909 		hdd_ctx->reg.reg_domain = cfg->reg_domain;
2910 		hdd_ctx->reg.eeprom_rd_ext = cfg->eeprom_rd_ext;
2911 	}
2912 
2913 	/* This can be extended to other configurations like ht, vht cap... */
2914 	status = wlan_hdd_validate_mac_address(&cfg->hw_macaddr);
2915 	if (QDF_IS_STATUS_SUCCESS(status))
2916 		qdf_mem_copy(&hdd_ctx->hw_macaddr, &cfg->hw_macaddr,
2917 			     QDF_MAC_ADDR_SIZE);
2918 
2919 	hdd_ctx->target_fw_version = cfg->target_fw_version;
2920 	hdd_ctx->target_fw_vers_ext = cfg->target_fw_vers_ext;
2921 	hdd_extract_fw_version_info(hdd_ctx);
2922 
2923 	hdd_ctx->hw_bd_id = cfg->hw_bd_id;
2924 	qdf_mem_copy(&hdd_ctx->hw_bd_info, &cfg->hw_bd_info,
2925 		     sizeof(cfg->hw_bd_info));
2926 
2927 	if (cfg->max_intf_count > WLAN_MAX_VDEVS) {
2928 		hdd_err("fw max vdevs (%u) > host max vdevs (%u); using %u",
2929 			cfg->max_intf_count, WLAN_MAX_VDEVS, WLAN_MAX_VDEVS);
2930 		hdd_ctx->max_intf_count = WLAN_MAX_VDEVS;
2931 	} else {
2932 		hdd_ctx->max_intf_count = cfg->max_intf_count;
2933 	}
2934 
2935 	hdd_sar_target_config(hdd_ctx, cfg);
2936 	hdd_lpass_target_config(hdd_ctx, cfg);
2937 
2938 	hdd_ctx->ap_arpns_support = cfg->ap_arpns_support;
2939 
2940 	hdd_update_tgt_services(hdd_ctx, &cfg->services);
2941 
2942 	hdd_update_tgt_ht_cap(hdd_ctx, &cfg->ht_cap);
2943 
2944 	sme_update_bfer_caps_as_per_nss_chains(hdd_ctx->mac_handle, cfg);
2945 
2946 	hdd_update_tgt_vht_cap(hdd_ctx, &cfg->vht_cap);
2947 	if (cfg->services.en_11ax  &&
2948 	    (hdd_ctx->config->dot11Mode == eHDD_DOT11_MODE_AUTO ||
2949 	     hdd_ctx->config->dot11Mode == eHDD_DOT11_MODE_11ax ||
2950 	     hdd_ctx->config->dot11Mode == eHDD_DOT11_MODE_11ax_ONLY)) {
2951 		hdd_debug("11AX: 11ax is enabled - update HDD config");
2952 		hdd_update_tgt_he_cap(hdd_ctx, cfg);
2953 		hdd_update_wiphy_he_cap(hdd_ctx);
2954 	}
2955 	hdd_update_tgt_twt_cap(hdd_ctx, cfg);
2956 	hdd_update_tgt_eht_cap(hdd_ctx, cfg);
2957 	hdd_update_wiphy_eht_cap(hdd_ctx);
2958 	ucfg_mlme_update_tgt_mlo_cap(hdd_ctx->psoc);
2959 
2960 	for (band = NSS_CHAINS_BAND_2GHZ; band < NSS_CHAINS_BAND_MAX; band++) {
2961 		sme_modify_nss_chains_tgt_cfg(hdd_ctx->mac_handle,
2962 					      QDF_STA_MODE, band);
2963 		sme_modify_nss_chains_tgt_cfg(hdd_ctx->mac_handle,
2964 					      QDF_SAP_MODE, band);
2965 		sme_modify_nss_chains_tgt_cfg(hdd_ctx->mac_handle,
2966 					      QDF_TDLS_MODE, band);
2967 		sme_modify_nss_chains_tgt_cfg(hdd_ctx->mac_handle,
2968 					      QDF_P2P_DEVICE_MODE,
2969 					      band);
2970 		sme_modify_nss_chains_tgt_cfg(hdd_ctx->mac_handle,
2971 					      QDF_OCB_MODE, band);
2972 		sme_modify_nss_chains_tgt_cfg(hdd_ctx->mac_handle,
2973 					      QDF_TDLS_MODE, band);
2974 	}
2975 
2976 	hdd_update_vdev_nss(hdd_ctx);
2977 
2978 	status =
2979 	  ucfg_mlme_get_enable_dynamic_nss_chains_cfg(hdd_ctx->psoc,
2980 						      &enable_dynamic_cfg);
2981 	if (QDF_IS_STATUS_ERROR(status)) {
2982 		hdd_err("unable to get enable dynamic config");
2983 		hdd_ctx->dynamic_nss_chains_support = false;
2984 	} else {
2985 		hdd_ctx->dynamic_nss_chains_support =
2986 					cfg->dynamic_nss_chains_support &
2987 					enable_dynamic_cfg;
2988 		hdd_debug("Dynamic nss chain support FW %d driver %d",
2989 			   cfg->dynamic_nss_chains_support, enable_dynamic_cfg);
2990 	}
2991 
2992 	status = ucfg_mlme_update_dynamic_nss_chains_support
2993 			(hdd_ctx->psoc, hdd_ctx->dynamic_nss_chains_support);
2994 	if (QDF_IS_STATUS_ERROR(status))
2995 		hdd_err("unable to set dynamic_nss_chains_support");
2996 
2997 	ucfg_mlme_get_fine_time_meas_cap(hdd_ctx->psoc, &fine_time_meas_cap);
2998 	fine_time_meas_cap &= cfg->fine_time_measurement_cap;
2999 	status = ucfg_mlme_set_fine_time_meas_cap(hdd_ctx->psoc,
3000 						  fine_time_meas_cap);
3001 	if (QDF_IS_STATUS_ERROR(status)) {
3002 		hdd_err("failed to set fine_time_meas_cap, 0x%x, ox%x",
3003 			fine_time_meas_cap, cfg->fine_time_measurement_cap);
3004 		ucfg_mlme_get_fine_time_meas_cap(hdd_ctx->psoc,
3005 						 &fine_time_meas_cap);
3006 	}
3007 
3008 	hdd_ctx->fine_time_meas_cap_target = cfg->fine_time_measurement_cap;
3009 	hdd_debug("fine_time_meas_cap: 0x%x", fine_time_meas_cap);
3010 
3011 	status = ucfg_mlme_get_vht_enable2x2(hdd_ctx->psoc, &bval);
3012 	if (!QDF_IS_STATUS_SUCCESS(status))
3013 		hdd_err("unable to get vht_enable2x2");
3014 
3015 	antenna_mode = (bval == 0x01) ?
3016 			HDD_ANTENNA_MODE_2X2 : HDD_ANTENNA_MODE_1X1;
3017 	hdd_update_smps_antenna_mode(hdd_ctx, antenna_mode);
3018 	hdd_debug("Init current antenna mode: %d",
3019 		  hdd_ctx->current_antenna_mode);
3020 
3021 	hdd_ctx->rcpi_enabled = cfg->rcpi_enabled;
3022 
3023 	status = ucfg_mlme_cfg_get_vht_tx_bfee_ant_supp(hdd_ctx->psoc,
3024 							&value);
3025 	if (QDF_IS_STATUS_ERROR(status)) {
3026 		status = false;
3027 		hdd_err("set tx_bfee_ant_supp failed");
3028 	}
3029 
3030 	status = ucfg_mlme_set_restricted_80p80_bw_supp(hdd_ctx->psoc,
3031 							cfg->restricted_80p80_bw_supp);
3032 	if (QDF_IS_STATUS_ERROR(status))
3033 		hdd_err("Failed to set MLME restircted 80p80 BW support");
3034 
3035 	if ((value > MLME_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED_FW_DEF) &&
3036 	    !cfg->tx_bfee_8ss_enabled) {
3037 		status = ucfg_mlme_cfg_set_vht_tx_bfee_ant_supp(hdd_ctx->psoc,
3038 				MLME_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED_FW_DEF);
3039 		if (QDF_IS_STATUS_ERROR(status)) {
3040 			status = false;
3041 			hdd_err("set tx_bfee_ant_supp failed");
3042 		}
3043 	}
3044 
3045 	hdd_update_tid_to_link_supported(hdd_ctx, &cfg->services);
3046 	mac_handle = hdd_ctx->mac_handle;
3047 
3048 	hdd_debug("txBFCsnValue %d", value);
3049 
3050 	/*
3051 	 * Update txBFCsnValue and NumSoundingDim values to vhtcap in wiphy
3052 	 */
3053 	hdd_update_wiphy_vhtcap(hdd_ctx);
3054 
3055 	hdd_update_vhtcap_2g(hdd_ctx);
3056 
3057 	hdd_ctx->wmi_max_len = cfg->wmi_max_len;
3058 
3059 	wlan_config_sched_scan_plans_to_wiphy(hdd_ctx->wiphy, hdd_ctx->psoc);
3060 	/*
3061 	 * This needs to be done after HDD pdev is created and stored since
3062 	 * it will access the HDD pdev object lock.
3063 	 */
3064 	hdd_runtime_suspend_context_init(hdd_ctx);
3065 
3066 	/* Configure NAN datapath features */
3067 	hdd_nan_datapath_target_config(hdd_ctx, cfg);
3068 	ucfg_nan_set_tgt_caps(hdd_ctx->psoc, &cfg->nan_caps);
3069 	hdd_ctx->dfs_cac_offload = cfg->dfs_cac_offload;
3070 	hdd_ctx->lte_coex_ant_share = cfg->services.lte_coex_ant_share;
3071 	hdd_ctx->obss_scan_offload = cfg->services.obss_scan_offload;
3072 	ucfg_scan_set_obss_scan_offload(hdd_ctx->psoc,
3073 					hdd_ctx->obss_scan_offload);
3074 	status = ucfg_mlme_set_obss_detection_offload_enabled(
3075 			hdd_ctx->psoc, cfg->obss_detection_offloaded);
3076 	if (QDF_IS_STATUS_ERROR(status))
3077 		hdd_err("Couldn't pass WNI_CFG_OBSS_DETECTION_OFFLOAD to CFG");
3078 
3079 	status = ucfg_mlme_set_obss_color_collision_offload_enabled(
3080 			hdd_ctx->psoc, cfg->obss_color_collision_offloaded);
3081 	if (QDF_IS_STATUS_ERROR(status))
3082 		hdd_err("Failed to set WNI_CFG_OBSS_COLOR_COLLISION_OFFLOAD");
3083 
3084 	ucfg_mlme_set_bss_color_collision_det_support(
3085 					hdd_ctx->psoc,
3086 					cfg->obss_color_collision_offloaded);
3087 	if (!cfg->obss_color_collision_offloaded) {
3088 		status = ucfg_mlme_set_bss_color_collision_det_sta(
3089 				hdd_ctx->psoc,
3090 				cfg->obss_color_collision_offloaded);
3091 		if (QDF_IS_STATUS_ERROR(status))
3092 			hdd_err("Failed to set CFG_BSS_CLR_COLLISION_DET_STA");
3093 	}
3094 
3095 	hdd_update_score_config(hdd_ctx);
3096 	hdd_update_multi_client_thermal_support(hdd_ctx);
3097 
3098 	ucfg_psoc_mlme_set_11be_capab(hdd_ctx->psoc, cfg->services.en_11be);
3099 	return 0;
3100 
3101 dispatcher_close:
3102 	dispatcher_pdev_close(hdd_ctx->pdev);
3103 pdev_close:
3104 	hdd_component_pdev_close(hdd_ctx->pdev);
3105 exit:
3106 	hdd_objmgr_release_and_destroy_pdev(hdd_ctx);
3107 
3108 	return ret;
3109 }
3110 
hdd_dfs_indicate_radar(struct hdd_context * hdd_ctx)3111 bool hdd_dfs_indicate_radar(struct hdd_context *hdd_ctx)
3112 {
3113 	struct hdd_adapter *adapter, *next_adapter = NULL;
3114 	struct hdd_ap_ctx *ap_ctx;
3115 	uint32_t ap_chan;
3116 	bool dfs_disable_channel_switch = false;
3117 	struct wlan_hdd_link_info *link_info;
3118 
3119 	if (!hdd_ctx) {
3120 		hdd_info("Couldn't get hdd_ctx");
3121 		return true;
3122 	}
3123 
3124 	ucfg_mlme_get_dfs_disable_channel_switch(hdd_ctx->psoc,
3125 						 &dfs_disable_channel_switch);
3126 	if (dfs_disable_channel_switch) {
3127 		hdd_info("skip tx block hdd_ctx=%pK, disableDFSChSwitch=%d",
3128 			 hdd_ctx, dfs_disable_channel_switch);
3129 		return true;
3130 	}
3131 
3132 	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
3133 					   NET_DEV_HOLD_DFS_INDICATE_RADAR) {
3134 
3135 		if (adapter->device_mode != QDF_SAP_MODE &&
3136 		    adapter->device_mode != QDF_P2P_GO_MODE)
3137 			goto next_adapter;
3138 
3139 		hdd_adapter_for_each_active_link_info(adapter, link_info) {
3140 			ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(link_info);
3141 			ap_chan = ap_ctx->operating_chan_freq;
3142 			if (!wlan_reg_is_passive_or_disable_for_pwrmode(hdd_ctx->pdev,
3143 							ap_chan, REG_CURRENT_PWR_MODE))
3144 				continue;
3145 
3146 			ap_ctx->dfs_cac_block_tx = true;
3147 			hdd_info("tx blocked for vdev: %d", link_info->vdev_id);
3148 			if (link_info->vdev_id != WLAN_UMAC_VDEV_ID_MAX)
3149 				cdp_fc_vdev_flush(
3150 					cds_get_context(QDF_MODULE_ID_SOC),
3151 					link_info->vdev_id);
3152 		}
3153 next_adapter:
3154 		hdd_adapter_dev_put_debug(adapter,
3155 					  NET_DEV_HOLD_DFS_INDICATE_RADAR);
3156 	}
3157 
3158 	return true;
3159 }
3160 
hdd_is_valid_mac_address(const uint8_t * mac_addr)3161 bool hdd_is_valid_mac_address(const uint8_t *mac_addr)
3162 {
3163 	int xdigit = 0;
3164 	int separator = 0;
3165 
3166 	while (*mac_addr) {
3167 		if (isxdigit(*mac_addr)) {
3168 			xdigit++;
3169 		} else if (':' == *mac_addr) {
3170 			if (0 == xdigit || ((xdigit / 2) - 1) != separator)
3171 				break;
3172 
3173 			++separator;
3174 		} else {
3175 			/* Invalid MAC found */
3176 			return false;
3177 		}
3178 		++mac_addr;
3179 	}
3180 	return xdigit == 12 && (separator == 5 || separator == 0);
3181 }
3182 
3183 /**
3184  * hdd_mon_mode_ether_setup() - Update monitor mode struct net_device.
3185  * @dev: Handle to struct net_device to be updated.
3186  *
3187  * Return: None
3188  */
hdd_mon_mode_ether_setup(struct net_device * dev)3189 static void hdd_mon_mode_ether_setup(struct net_device *dev)
3190 {
3191 	dev->header_ops         = NULL;
3192 	dev->type               = ARPHRD_IEEE80211_RADIOTAP;
3193 	dev->hard_header_len    = ETH_HLEN;
3194 	dev->mtu                = ETH_DATA_LEN;
3195 	dev->addr_len           = ETH_ALEN;
3196 	dev->tx_queue_len       = 1000; /* Ethernet wants good queues */
3197 	dev->flags              = IFF_BROADCAST|IFF_MULTICAST;
3198 	dev->priv_flags        |= IFF_TX_SKB_SHARING;
3199 
3200 	memset(dev->broadcast, 0xFF, ETH_ALEN);
3201 }
3202 
3203 #ifdef FEATURE_MONITOR_MODE_SUPPORT
3204 /**
3205  * hdd_mon_turn_off_ps_and_wow() - Update monitor mode struct net_device.
3206  * @hdd_ctx: Pointer to HDD context.
3207  *
3208  * Return: None
3209  */
hdd_mon_turn_off_ps_and_wow(struct hdd_context * hdd_ctx)3210 static void hdd_mon_turn_off_ps_and_wow(struct hdd_context *hdd_ctx)
3211 {
3212 	ucfg_pmo_set_power_save_mode(hdd_ctx->psoc,
3213 				     PMO_PS_ADVANCED_POWER_SAVE_DISABLE);
3214 	ucfg_pmo_set_wow_enable(hdd_ctx->psoc, PMO_WOW_DISABLE_BOTH);
3215 }
3216 
3217 /**
3218  * __hdd_mon_open() - HDD Open function
3219  * @dev: Pointer to net_device structure
3220  *
3221  * This is called in response to ifconfig up
3222  *
3223  * Return: 0 for success; non-zero for failure
3224  */
__hdd_mon_open(struct net_device * dev)3225 static int __hdd_mon_open(struct net_device *dev)
3226 {
3227 	int ret;
3228 	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
3229 	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
3230 	struct bbm_params param = {0};
3231 
3232 	hdd_enter_dev(dev);
3233 
3234 	if (test_bit(DEVICE_IFACE_OPENED, &adapter->event_flags)) {
3235 		hdd_debug_rl("Monitor interface is already up");
3236 		return 0;
3237 	}
3238 
3239 	ret = wlan_hdd_validate_context(hdd_ctx);
3240 	if (ret)
3241 		return ret;
3242 
3243 	hdd_mon_mode_ether_setup(dev);
3244 
3245 	if (con_mode == QDF_GLOBAL_MONITOR_MODE ||
3246 	    ucfg_mlme_is_sta_mon_conc_supported(hdd_ctx->psoc) ||
3247 	    ucfg_dp_is_local_pkt_capture_enabled(hdd_ctx->psoc)) {
3248 		ret = hdd_trigger_psoc_idle_restart(hdd_ctx);
3249 		if (ret) {
3250 			hdd_err("Failed to start WLAN modules return");
3251 			return ret;
3252 		}
3253 		hdd_err("hdd_wlan_start_modules() successful !");
3254 
3255 		if ((!test_bit(SME_SESSION_OPENED,
3256 			       &adapter->deflink->link_flags)) ||
3257 		    (policy_mgr_is_sta_mon_concurrency(hdd_ctx->psoc))) {
3258 			ret = hdd_start_adapter(adapter, true);
3259 			if (ret) {
3260 				hdd_err("Failed to start adapter :%d",
3261 						adapter->device_mode);
3262 				return ret;
3263 			}
3264 			hdd_err("hdd_start_adapters() successful !");
3265 		}
3266 		hdd_mon_turn_off_ps_and_wow(hdd_ctx);
3267 		set_bit(DEVICE_IFACE_OPENED, &adapter->event_flags);
3268 	}
3269 
3270 	if (con_mode != QDF_GLOBAL_MONITOR_MODE &&
3271 	    (ucfg_mlme_is_sta_mon_conc_supported(hdd_ctx->psoc) ||
3272 	     ucfg_dp_is_local_pkt_capture_enabled(hdd_ctx->psoc))) {
3273 		hdd_info("Acquire wakelock for STA + monitor mode");
3274 
3275 		qdf_wake_lock_acquire(&hdd_ctx->monitor_mode_wakelock,
3276 				      WIFI_POWER_EVENT_WAKELOCK_MONITOR_MODE);
3277 		hdd_lpc_disable_powersave(hdd_ctx);
3278 		qdf_runtime_pm_prevent_suspend(
3279 			&hdd_ctx->runtime_context.monitor_mode);
3280 	}
3281 
3282 	ret = hdd_set_mon_rx_cb(dev);
3283 
3284 	if (!ret)
3285 		ret = hdd_enable_monitor_mode(dev);
3286 
3287 	if (!ret) {
3288 		param.policy = BBM_DRIVER_MODE_POLICY;
3289 		param.policy_info.driver_mode = QDF_GLOBAL_MONITOR_MODE;
3290 		ucfg_dp_bbm_apply_independent_policy(hdd_ctx->psoc, &param);
3291 		ucfg_dp_set_current_throughput_level(hdd_ctx->psoc,
3292 						     PLD_BUS_WIDTH_VERY_HIGH);
3293 	}
3294 
3295 	return ret;
3296 }
3297 
3298 /**
3299  * hdd_mon_open() - Wrapper function for __hdd_mon_open to protect it from SSR
3300  * @net_dev: Pointer to net_device structure
3301  *
3302  * This is called in response to ifconfig up
3303  *
3304  * Return: 0 for success; non-zero for failure
3305  */
hdd_mon_open(struct net_device * net_dev)3306 static int hdd_mon_open(struct net_device *net_dev)
3307 {
3308 	int errno;
3309 	struct osif_vdev_sync *vdev_sync;
3310 
3311 	errno = osif_vdev_sync_trans_start(net_dev, &vdev_sync);
3312 	if (errno)
3313 		return errno;
3314 
3315 	errno = __hdd_mon_open(net_dev);
3316 
3317 	osif_vdev_sync_trans_stop(vdev_sync);
3318 
3319 	return errno;
3320 }
3321 #endif
3322 
3323 #ifdef WLAN_FEATURE_PKT_CAPTURE
3324 /**
3325  * __hdd_pktcapture_open() - HDD Open function
3326  * @dev: Pointer to net_device structure
3327  *
3328  * This is called in response to ifconfig up
3329  *
3330  * Return: 0 for success; non-zero for failure
3331  */
__hdd_pktcapture_open(struct net_device * dev)3332 static int __hdd_pktcapture_open(struct net_device *dev)
3333 {
3334 	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
3335 	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
3336 	struct hdd_adapter *sta_adapter;
3337 	QDF_STATUS status;
3338 	struct wlan_objmgr_vdev *vdev;
3339 	int ret;
3340 
3341 	hdd_enter_dev(dev);
3342 
3343 	ret = wlan_hdd_validate_context(hdd_ctx);
3344 	if (ret)
3345 		return ret;
3346 
3347 	sta_adapter = hdd_get_adapter(hdd_ctx, QDF_STA_MODE);
3348 	if (!sta_adapter) {
3349 		hdd_err("No station interface found");
3350 		return -EINVAL;
3351 	}
3352 
3353 	vdev = hdd_objmgr_get_vdev_by_user(sta_adapter->deflink, WLAN_OSIF_ID);
3354 	if (!vdev)
3355 		return -EINVAL;
3356 
3357 	hdd_mon_mode_ether_setup(dev);
3358 
3359 	status = ucfg_dp_register_pkt_capture_callbacks(vdev);
3360 	ret = qdf_status_to_os_return(status);
3361 	if (ret) {
3362 		hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_ID);
3363 		return ret;
3364 	}
3365 
3366 	adapter->deflink->vdev = vdev;
3367 	set_bit(DEVICE_IFACE_OPENED, &adapter->event_flags);
3368 	sta_adapter->mon_adapter = adapter;
3369 
3370 	return ret;
3371 }
3372 
3373 /**
3374  * hdd_pktcapture_open() - Wrapper function for hdd_pktcapture_open to
3375  * protect it from SSR
3376  * @net_dev: Pointer to net_device structure
3377  *
3378  * This is called in response to ifconfig up
3379  *
3380  * Return: 0 for success; non-zero for failure
3381  */
hdd_pktcapture_open(struct net_device * net_dev)3382 static int hdd_pktcapture_open(struct net_device *net_dev)
3383 {
3384 	int errno;
3385 	struct osif_vdev_sync *vdev_sync;
3386 
3387 	errno = osif_vdev_sync_trans_start(net_dev, &vdev_sync);
3388 	if (errno)
3389 		return errno;
3390 
3391 	errno = __hdd_pktcapture_open(net_dev);
3392 
3393 	osif_vdev_sync_trans_stop(vdev_sync);
3394 
3395 	return errno;
3396 }
3397 
3398 /**
3399  * hdd_unmap_monitor_interface_vdev() - unmap monitor interface vdev and
3400  * deregister packet capture callbacks
3401  * @sta_adapter: station adapter
3402  *
3403  * Return: void
3404  */
3405 static void
hdd_unmap_monitor_interface_vdev(struct hdd_adapter * sta_adapter)3406 hdd_unmap_monitor_interface_vdev(struct hdd_adapter *sta_adapter)
3407 {
3408 	struct hdd_adapter *mon_adapter = sta_adapter->mon_adapter;
3409 
3410 	if (mon_adapter && hdd_is_interface_up(mon_adapter)) {
3411 		ucfg_pkt_capture_deregister_callbacks(
3412 						mon_adapter->deflink->vdev);
3413 		hdd_objmgr_put_vdev_by_user(mon_adapter->deflink->vdev,
3414 					    WLAN_OSIF_ID);
3415 		mon_adapter->deflink->vdev = NULL;
3416 		hdd_reset_monitor_interface(sta_adapter);
3417 	}
3418 }
3419 
3420 /**
3421  * hdd_map_monitor_interface_vdev() - Map monitor interface vdev and
3422  * register packet capture callbacks
3423  * @sta_adapter: Station adapter
3424  *
3425  * Return: None
3426  */
hdd_map_monitor_interface_vdev(struct hdd_adapter * sta_adapter)3427 static void hdd_map_monitor_interface_vdev(struct hdd_adapter *sta_adapter)
3428 {
3429 	struct hdd_adapter *mon_adapter;
3430 	QDF_STATUS status;
3431 	struct wlan_objmgr_vdev *vdev;
3432 	int ret;
3433 
3434 	mon_adapter = hdd_get_adapter(sta_adapter->hdd_ctx, QDF_MONITOR_MODE);
3435 	if (!mon_adapter) {
3436 		hdd_debug("No monitor interface found");
3437 		return;
3438 	}
3439 
3440 	if (!mon_adapter || !hdd_is_interface_up(mon_adapter)) {
3441 		hdd_debug("Monitor interface is not up\n");
3442 		return;
3443 	}
3444 
3445 	if (!wlan_hdd_is_session_type_monitor(mon_adapter->device_mode))
3446 		return;
3447 
3448 	vdev = hdd_objmgr_get_vdev_by_user(sta_adapter->deflink, WLAN_OSIF_ID);
3449 	if (!vdev)
3450 		return;
3451 
3452 	status = ucfg_dp_register_pkt_capture_callbacks(vdev);
3453 	ret = qdf_status_to_os_return(status);
3454 	if (ret) {
3455 		hdd_err("Failed registering packet capture callbacks");
3456 		hdd_objmgr_put_vdev_by_user(vdev,
3457 					    WLAN_OSIF_ID);
3458 		return;
3459 	}
3460 
3461 	mon_adapter->deflink->vdev = vdev;
3462 	sta_adapter->mon_adapter = mon_adapter;
3463 }
3464 
hdd_reset_monitor_interface(struct hdd_adapter * sta_adapter)3465 void hdd_reset_monitor_interface(struct hdd_adapter *sta_adapter)
3466 {
3467 	sta_adapter->mon_adapter = NULL;
3468 }
3469 
3470 struct hdd_adapter *
hdd_is_pkt_capture_mon_enable(struct hdd_adapter * sta_adapter)3471 hdd_is_pkt_capture_mon_enable(struct hdd_adapter *sta_adapter)
3472 {
3473 	return sta_adapter->mon_adapter;
3474 }
3475 #else
3476 static inline void
hdd_unmap_monitor_interface_vdev(struct hdd_adapter * sta_adapter)3477 hdd_unmap_monitor_interface_vdev(struct hdd_adapter *sta_adapter)
3478 {
3479 }
3480 
3481 static inline void
hdd_map_monitor_interface_vdev(struct hdd_adapter * sta_adapter)3482 hdd_map_monitor_interface_vdev(struct hdd_adapter *sta_adapter)
3483 {
3484 }
3485 #endif
3486 
3487 static QDF_STATUS
wlan_hdd_update_dbs_scan_and_fw_mode_config(void)3488 wlan_hdd_update_dbs_scan_and_fw_mode_config(void)
3489 {
3490 	struct policy_mgr_dual_mac_config cfg = {0};
3491 	QDF_STATUS status;
3492 	uint32_t chnl_sel_logic_conc = 0;
3493 	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
3494 	uint8_t dual_mac_feature = DISABLE_DBS_CXN_AND_SCAN;
3495 
3496 	if (!hdd_ctx)
3497 		return QDF_STATUS_E_FAILURE;
3498 
3499 	/*
3500 	 * ROME platform doesn't support any DBS related commands in FW,
3501 	 * so if driver sends wmi command with dual_mac_config with all set to
3502 	 * 0 then FW wouldn't respond back and driver would timeout on waiting
3503 	 * for response. Check if FW supports DBS to eliminate ROME vs
3504 	 * NON-ROME platform.
3505 	 */
3506 	if (!policy_mgr_find_if_fw_supports_dbs(hdd_ctx->psoc))
3507 		return QDF_STATUS_SUCCESS;
3508 
3509 	if (hdd_ctx->is_dual_mac_cfg_updated) {
3510 		hdd_debug("dual mac config has already been updated, skip");
3511 		return QDF_STATUS_SUCCESS;
3512 	}
3513 
3514 	cfg.scan_config = 0;
3515 	cfg.fw_mode_config = 0;
3516 	cfg.set_dual_mac_cb = policy_mgr_soc_set_dual_mac_cfg_cb;
3517 	if (policy_mgr_is_hw_dbs_capable(hdd_ctx->psoc)) {
3518 		status =
3519 		ucfg_policy_mgr_get_chnl_select_plcy(hdd_ctx->psoc,
3520 						     &chnl_sel_logic_conc);
3521 		if (status != QDF_STATUS_SUCCESS) {
3522 			hdd_err("can't get chnl sel policy, use def");
3523 			return status;
3524 		}
3525 	}
3526 	status =
3527 	ucfg_policy_mgr_get_dual_mac_feature(hdd_ctx->psoc,
3528 					     &dual_mac_feature);
3529 	if (status != QDF_STATUS_SUCCESS) {
3530 		hdd_err("ucfg_policy_mgr_get_dual_mac_feature failed, use def");
3531 		return status;
3532 	}
3533 
3534 	if (dual_mac_feature != DISABLE_DBS_CXN_AND_SCAN) {
3535 		status = policy_mgr_get_updated_scan_and_fw_mode_config(
3536 				hdd_ctx->psoc, &cfg.scan_config,
3537 				&cfg.fw_mode_config,
3538 				dual_mac_feature,
3539 				chnl_sel_logic_conc);
3540 
3541 		if (status != QDF_STATUS_SUCCESS) {
3542 			hdd_err("wma_get_updated_scan_and_fw_mode_config failed %d",
3543 				status);
3544 			return status;
3545 		}
3546 	}
3547 
3548 	hdd_debug("send scan_cfg: 0x%x fw_mode_cfg: 0x%x to fw",
3549 		cfg.scan_config, cfg.fw_mode_config);
3550 
3551 	status = sme_soc_set_dual_mac_config(cfg);
3552 	if (QDF_IS_STATUS_ERROR(status)) {
3553 		hdd_err("sme_soc_set_dual_mac_config failed %d", status);
3554 		return status;
3555 	}
3556 	hdd_ctx->is_dual_mac_cfg_updated = true;
3557 
3558 	return QDF_STATUS_SUCCESS;
3559 }
3560 
3561 /**
3562  * hdd_max_sta_interface_up_count_reached() - check sta/p2p_cli vdev count
3563  * @adapter: HDD adapter
3564  *
3565  * Return: true if vdev limit reached
3566  */
hdd_max_sta_interface_up_count_reached(struct hdd_adapter * adapter)3567 static bool hdd_max_sta_interface_up_count_reached(struct hdd_adapter *adapter)
3568 {
3569 	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
3570 	struct hdd_adapter *temp_adapter = NULL, *next_adapter = NULL;
3571 	uint8_t intf_count = 0;
3572 	wlan_net_dev_ref_dbgid dbgid =
3573 				NET_DEV_HOLD_MAX_STA_INTERFACE_UP_COUNT_REACHED;
3574 
3575 	if (0 == CFG_TGT_DEFAULT_MAX_STA_VDEVS)
3576 		return false;
3577 
3578 	/*
3579 	 * Check for max no of supported STA/P2PCLI VDEVs before
3580 	 * creating another one.
3581 	 */
3582 	hdd_for_each_adapter_dev_held_safe(hdd_ctx, temp_adapter,
3583 					   next_adapter, dbgid) {
3584 		if ((temp_adapter != adapter) &&
3585 		    (temp_adapter->dev->flags & IFF_UP) &&
3586 		    ((temp_adapter->device_mode == QDF_STA_MODE) ||
3587 		     (temp_adapter->device_mode == QDF_P2P_CLIENT_MODE)))
3588 			intf_count++;
3589 
3590 		hdd_adapter_dev_put_debug(temp_adapter, dbgid);
3591 	}
3592 
3593 	if (intf_count >= CFG_TGT_DEFAULT_MAX_STA_VDEVS) {
3594 		hdd_err("Max limit reached sta vdev-current %d max %d",
3595 			intf_count, CFG_TGT_DEFAULT_MAX_STA_VDEVS);
3596 		return true;
3597 	}
3598 	return false;
3599 }
3600 
3601 #if (defined(WLAN_FEATURE_11BE_MLO) && defined(CFG80211_11BE_BASIC)) && \
3602 (defined(CFG80211_IFTYPE_MLO_LINK_SUPPORT) || \
3603 defined(CFG80211_SINGLE_NETDEV_MULTI_LINK_SUPPORT)) && \
3604 !defined(WLAN_HDD_MULTI_VDEV_SINGLE_NDEV)
hdd_start_link_adapter(struct hdd_adapter * sta_adapter)3605 static int hdd_start_link_adapter(struct hdd_adapter *sta_adapter)
3606 {
3607 	int i, ret = 0;
3608 	struct hdd_mlo_adapter_info *mlo_adapter_info;
3609 	struct hdd_adapter *link_adapter;
3610 
3611 	hdd_enter_dev(sta_adapter->dev);
3612 	mlo_adapter_info = &sta_adapter->mlo_adapter_info;
3613 
3614 	for (i = 0; i < WLAN_MAX_MLD; i++) {
3615 		link_adapter = mlo_adapter_info->link_adapter[i];
3616 		if (!link_adapter)
3617 			continue;
3618 		if (link_adapter->mlo_adapter_info.associate_with_ml_adapter) {
3619 			/* TODO have proper references here */
3620 			qdf_spin_lock_bh(&link_adapter->deflink->vdev_lock);
3621 			link_adapter->deflink->vdev =
3622 						sta_adapter->deflink->vdev;
3623 			link_adapter->deflink->vdev_id =
3624 						sta_adapter->deflink->vdev_id;
3625 			qdf_spin_unlock_bh(&link_adapter->deflink->vdev_lock);
3626 
3627 			sta_adapter->link_info[i].vdev_id =
3628 						sta_adapter->deflink->vdev_id;
3629 			continue;
3630 		}
3631 		ret = hdd_start_station_adapter(link_adapter);
3632 		if (!ret) {
3633 			sta_adapter->link_info[i].vdev_id =
3634 						link_adapter->deflink->vdev_id;
3635 		}
3636 	}
3637 
3638 	hdd_adapter_update_mlo_mgr_mac_addr(sta_adapter);
3639 
3640 	hdd_exit();
3641 	return ret;
3642 }
3643 
hdd_stop_link_adapter(struct hdd_context * hdd_ctx,struct hdd_adapter * sta_adapter)3644 static int hdd_stop_link_adapter(struct hdd_context *hdd_ctx,
3645 				 struct hdd_adapter *sta_adapter)
3646 {
3647 	int i, ret = 0;
3648 	struct hdd_mlo_adapter_info *mlo_adapter_info;
3649 	struct hdd_adapter *link_adapter;
3650 
3651 	hdd_enter_dev(sta_adapter->dev);
3652 	hdd_debug("Stop adapter for link mode : %s(%d)",
3653 		  qdf_opmode_str(sta_adapter->device_mode),
3654 		  sta_adapter->deflink->vdev_id);
3655 
3656 	mlo_adapter_info = &sta_adapter->mlo_adapter_info;
3657 	for (i = 0; i < WLAN_MAX_MLD; i++) {
3658 		link_adapter = mlo_adapter_info->link_adapter[i];
3659 		if (!link_adapter)
3660 			continue;
3661 
3662 		if (link_adapter->mlo_adapter_info.associate_with_ml_adapter) {
3663 			/* TODO have proper references here */
3664 			qdf_spin_lock_bh(&link_adapter->deflink->vdev_lock);
3665 			link_adapter->deflink->vdev = NULL;
3666 			link_adapter->deflink->vdev_id = 0xff;
3667 			qdf_spin_unlock_bh(&link_adapter->deflink->vdev_lock);
3668 			continue;
3669 		}
3670 		ret = hdd_stop_adapter_ext(hdd_ctx, link_adapter);
3671 	}
3672 
3673 	hdd_exit();
3674 	return ret;
3675 }
3676 #else
hdd_start_link_adapter(struct hdd_adapter * link_adapter)3677 static int hdd_start_link_adapter(struct hdd_adapter *link_adapter)
3678 {
3679 	return 0;
3680 }
3681 
hdd_stop_link_adapter(struct hdd_context * hdd_ctx,struct hdd_adapter * link_adapter)3682 static int hdd_stop_link_adapter(struct hdd_context *hdd_ctx,
3683 				 struct hdd_adapter *link_adapter)
3684 {
3685 	return 0;
3686 }
3687 #endif
3688 
3689 /**
3690  * hdd_start_adapter() - Wrapper function for device specific adapter
3691  * @adapter: pointer to HDD adapter
3692  * @rtnl_held: true if rtnl lock is taken, otherwise false
3693  *
3694  * This function is called to start the device specific adapter for
3695  * the mode passed in the adapter's device_mode.
3696  *
3697  * Return: 0 for success; non-zero for failure
3698  */
hdd_start_adapter(struct hdd_adapter * adapter,bool rtnl_held)3699 int hdd_start_adapter(struct hdd_adapter *adapter, bool rtnl_held)
3700 {
3701 
3702 	int ret;
3703 	enum QDF_OPMODE device_mode = adapter->device_mode;
3704 
3705 	hdd_enter_dev(adapter->dev);
3706 
3707 	switch (device_mode) {
3708 	case QDF_MONITOR_MODE:
3709 		ret = hdd_start_station_adapter(adapter);
3710 		if (ret)
3711 			goto err_start_adapter;
3712 		hdd_set_idle_ps_config(adapter->hdd_ctx, false);
3713 		break;
3714 	case QDF_STA_MODE:
3715 	case QDF_P2P_CLIENT_MODE:
3716 		if (hdd_max_sta_interface_up_count_reached(adapter))
3717 			goto err_start_adapter;
3718 		fallthrough;
3719 	case QDF_P2P_DEVICE_MODE:
3720 	case QDF_OCB_MODE:
3721 	case QDF_NAN_DISC_MODE:
3722 		ret = hdd_start_station_adapter(adapter);
3723 		if (ret)
3724 			goto err_start_adapter;
3725 
3726 		if (device_mode == QDF_STA_MODE) {
3727 			ret = hdd_start_link_adapter(adapter);
3728 			if (ret)
3729 				hdd_err("Failed to start link adapter:%d", ret);
3730 		}
3731 		break;
3732 	case QDF_P2P_GO_MODE:
3733 	case QDF_SAP_MODE:
3734 		ret = hdd_start_ap_adapter(adapter, rtnl_held);
3735 		if (ret)
3736 			goto err_start_adapter;
3737 		break;
3738 	case QDF_FTM_MODE:
3739 		/* vdevs are dynamically managed by firmware in FTM */
3740 		hdd_register_wext(adapter->dev);
3741 		goto exit_with_success;
3742 	default:
3743 		hdd_err("Invalid session type %d", device_mode);
3744 		QDF_ASSERT(0);
3745 		goto err_start_adapter;
3746 	}
3747 
3748 	if (hdd_set_fw_params(adapter))
3749 		hdd_err("Failed to set the FW params for the adapter!");
3750 
3751 	if (adapter->deflink->vdev_id != WLAN_UMAC_VDEV_ID_MAX) {
3752 		ret = wlan_hdd_cfg80211_register_frames(adapter);
3753 		if (ret < 0) {
3754 			hdd_err("Failed to register frames - ret %d", ret);
3755 			goto err_start_adapter;
3756 		}
3757 	}
3758 
3759 	wlan_hdd_update_dbs_scan_and_fw_mode_config();
3760 
3761 exit_with_success:
3762 	hdd_create_adapter_sysfs_files(adapter);
3763 
3764 	hdd_exit();
3765 
3766 	return 0;
3767 
3768 err_start_adapter:
3769 	return -EINVAL;
3770 }
3771 
hdd_update_hw_sw_info(struct hdd_context * hdd_ctx)3772 void hdd_update_hw_sw_info(struct hdd_context *hdd_ctx)
3773 {
3774 	void *hif_sc;
3775 	size_t target_hw_name_len;
3776 	const char *target_hw_name;
3777 	uint8_t *buf;
3778 	uint32_t buf_len;
3779 
3780 	hif_sc = cds_get_context(QDF_MODULE_ID_HIF);
3781 	if (!hif_sc)
3782 		return;
3783 
3784 	hif_get_hw_info(hif_sc, &hdd_ctx->target_hw_version,
3785 			&hdd_ctx->target_hw_revision,
3786 			&target_hw_name);
3787 
3788 	qdf_mem_zero(hdd_ctx->target_hw_name, MAX_TGT_HW_NAME_LEN);
3789 
3790 	target_hw_name_len = strlen(target_hw_name) + 1;
3791 
3792 	if (target_hw_name_len <= MAX_TGT_HW_NAME_LEN) {
3793 		qdf_mem_copy(hdd_ctx->target_hw_name, target_hw_name,
3794 			     target_hw_name_len);
3795 	} else {
3796 		hdd_err("target_hw_name_len is greater than MAX_TGT_HW_NAME_LEN");
3797 		return;
3798 	}
3799 
3800 	hdd_debug("target_hw_name = %s", hdd_ctx->target_hw_name);
3801 
3802 	buf = qdf_mem_malloc(WE_MAX_STR_LEN);
3803 	if (buf) {
3804 		buf_len = hdd_wlan_get_version(hdd_ctx, WE_MAX_STR_LEN, buf);
3805 		hdd_nofl_debug("%s", buf);
3806 		qdf_mem_free(buf);
3807 	}
3808 }
3809 
3810 /**
3811  * hdd_update_cds_ac_specs_params() - update cds ac_specs params
3812  * @hdd_ctx: Pointer to hdd context
3813  *
3814  * Return: none
3815  */
3816 static void
hdd_update_cds_ac_specs_params(struct hdd_context * hdd_ctx)3817 hdd_update_cds_ac_specs_params(struct hdd_context *hdd_ctx)
3818 {
3819 	uint8_t tx_sched_wrr_param[TX_SCHED_WRR_PARAMS_NUM] = {0};
3820 	qdf_size_t out_size = 0;
3821 	int i;
3822 	struct cds_context *cds_ctx;
3823 
3824 	if (!hdd_ctx)
3825 		return;
3826 
3827 	if (!hdd_ctx->config) {
3828 		/* Do nothing if hdd_ctx is invalid */
3829 		hdd_err("Warning: hdd_ctx->cfg_ini is NULL");
3830 		return;
3831 	}
3832 
3833 	cds_ctx = cds_get_context(QDF_MODULE_ID_QDF);
3834 	if (!cds_ctx)
3835 		return;
3836 
3837 	for (i = 0; i < QCA_WLAN_AC_ALL; i++) {
3838 		switch (i) {
3839 		case QCA_WLAN_AC_BE:
3840 			qdf_uint8_array_parse(
3841 				cfg_get(hdd_ctx->psoc,
3842 					CFG_DP_ENABLE_TX_SCHED_WRR_BE),
3843 				tx_sched_wrr_param,
3844 				sizeof(tx_sched_wrr_param),
3845 				&out_size);
3846 			break;
3847 		case QCA_WLAN_AC_BK:
3848 			qdf_uint8_array_parse(
3849 				cfg_get(hdd_ctx->psoc,
3850 					CFG_DP_ENABLE_TX_SCHED_WRR_BK),
3851 				tx_sched_wrr_param,
3852 				sizeof(tx_sched_wrr_param),
3853 				&out_size);
3854 			break;
3855 		case QCA_WLAN_AC_VI:
3856 			qdf_uint8_array_parse(
3857 				cfg_get(hdd_ctx->psoc,
3858 					CFG_DP_ENABLE_TX_SCHED_WRR_VI),
3859 				tx_sched_wrr_param,
3860 				sizeof(tx_sched_wrr_param),
3861 				&out_size);
3862 			break;
3863 		case QCA_WLAN_AC_VO:
3864 			qdf_uint8_array_parse(
3865 				cfg_get(hdd_ctx->psoc,
3866 					CFG_DP_ENABLE_TX_SCHED_WRR_VO),
3867 				tx_sched_wrr_param,
3868 				sizeof(tx_sched_wrr_param),
3869 				&out_size);
3870 			break;
3871 		default:
3872 			break;
3873 		}
3874 
3875 		if (out_size == TX_SCHED_WRR_PARAMS_NUM) {
3876 			cds_ctx->ac_specs[i].wrr_skip_weight =
3877 						tx_sched_wrr_param[0];
3878 			cds_ctx->ac_specs[i].credit_threshold =
3879 						tx_sched_wrr_param[1];
3880 			cds_ctx->ac_specs[i].send_limit =
3881 						tx_sched_wrr_param[2];
3882 			cds_ctx->ac_specs[i].credit_reserve =
3883 						tx_sched_wrr_param[3];
3884 			cds_ctx->ac_specs[i].discard_weight =
3885 						tx_sched_wrr_param[4];
3886 		}
3887 
3888 		out_size = 0;
3889 	}
3890 }
3891 
hdd_wlan_get_version(struct hdd_context * hdd_ctx,const size_t version_len,uint8_t * version)3892 uint32_t hdd_wlan_get_version(struct hdd_context *hdd_ctx,
3893 			      const size_t version_len, uint8_t *version)
3894 {
3895 	uint32_t size;
3896 	uint8_t reg_major = 0, reg_minor = 0, bdf_major = 0, bdf_minor = 0;
3897 	struct target_psoc_info *tgt_hdl;
3898 
3899 	if (!hdd_ctx) {
3900 		hdd_err("Invalid context, HDD context is null");
3901 		return 0;
3902 	}
3903 
3904 	if (!version || version_len == 0) {
3905 		hdd_err("Invalid buffer pointr or buffer len\n");
3906 		return 0;
3907 	}
3908 	tgt_hdl = wlan_psoc_get_tgt_if_handle(hdd_ctx->psoc);
3909 	if (tgt_hdl)
3910 		target_psoc_get_version_info(tgt_hdl, &reg_major, &reg_minor,
3911 					     &bdf_major, &bdf_minor);
3912 
3913 	size = scnprintf(version, version_len,
3914 			 "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",
3915 			 QWLAN_VERSIONSTR,
3916 			 hdd_ctx->fw_version_info.major_spid,
3917 			 hdd_ctx->fw_version_info.minor_spid,
3918 			 hdd_ctx->fw_version_info.siid,
3919 			 hdd_ctx->fw_version_info.rel_id,
3920 			 hdd_ctx->fw_version_info.crmid,
3921 			 hdd_ctx->fw_version_info.sub_id,
3922 			 hdd_ctx->target_hw_name,
3923 			 hdd_ctx->hw_bd_info.bdf_version,
3924 			 hdd_ctx->hw_bd_info.ref_design_id,
3925 			 hdd_ctx->hw_bd_info.customer_id,
3926 			 hdd_ctx->hw_bd_info.project_id,
3927 			 hdd_ctx->hw_bd_info.board_data_rev,
3928 			 reg_major, reg_minor, bdf_major, bdf_minor);
3929 
3930 	return size;
3931 }
3932 
hdd_set_11ax_rate(struct hdd_adapter * adapter,int set_value,struct sap_config * sap_config)3933 int hdd_set_11ax_rate(struct hdd_adapter *adapter, int set_value,
3934 		      struct sap_config *sap_config)
3935 {
3936 	uint8_t preamble = 0, nss = 0, rix = 0;
3937 	int ret;
3938 	mac_handle_t mac_handle = adapter->hdd_ctx->mac_handle;
3939 
3940 	if (!sap_config) {
3941 		if (!sme_is_feature_supported_by_fw(DOT11AX)) {
3942 			hdd_err("Target does not support 11ax");
3943 			return -EIO;
3944 		}
3945 	} else if (sap_config->SapHw_mode != eCSR_DOT11_MODE_11ax &&
3946 		   sap_config->SapHw_mode != eCSR_DOT11_MODE_11ax_ONLY) {
3947 		hdd_err("Invalid hw mode, SAP hw_mode= 0x%x, ch_freq = %d",
3948 			sap_config->SapHw_mode, sap_config->chan_freq);
3949 		return -EIO;
3950 	}
3951 
3952 	if (set_value != 0xffff) {
3953 		rix = RC_2_RATE_IDX_11AX(set_value);
3954 		preamble = WMI_RATE_PREAMBLE_HE;
3955 		nss = HT_RC_2_STREAMS_11AX(set_value);
3956 
3957 		set_value = hdd_assemble_rate_code(preamble, nss, rix);
3958 	} else {
3959 		ret = sme_set_auto_rate_he_ltf(mac_handle,
3960 					       adapter->deflink->vdev_id,
3961 					       QCA_WLAN_HE_LTF_AUTO);
3962 	}
3963 
3964 	hdd_info("SET_11AX_RATE val %d rix %d preamble %x nss %d",
3965 		 set_value, rix, preamble, nss);
3966 
3967 	ret = wma_cli_set_command(adapter->deflink->vdev_id,
3968 				  wmi_vdev_param_fixed_rate,
3969 				  set_value, VDEV_CMD);
3970 
3971 	return ret;
3972 }
3973 
hdd_assemble_rate_code(uint8_t preamble,uint8_t nss,uint8_t rate)3974 int hdd_assemble_rate_code(uint8_t preamble, uint8_t nss, uint8_t rate)
3975 {
3976 	return ucfg_mlme_assemble_rate_code(preamble, nss, rate);
3977 }
3978 
3979 #ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
wlan_hdd_get_mode_for_non_connected_vdev(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id)3980 static enum policy_mgr_con_mode wlan_hdd_get_mode_for_non_connected_vdev(
3981 			struct wlan_objmgr_psoc *psoc, uint8_t vdev_id)
3982 {
3983 	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
3984 	struct hdd_adapter *adapter;
3985 	enum policy_mgr_con_mode mode;
3986 	struct wlan_hdd_link_info *link_info;
3987 
3988 	link_info = hdd_get_link_info_by_vdev(hdd_ctx, vdev_id);
3989 	if (!link_info) {
3990 		hdd_err("Invalid vdev");
3991 		return PM_MAX_NUM_OF_MODE;
3992 	}
3993 
3994 	adapter = link_info->adapter;
3995 	mode = policy_mgr_qdf_opmode_to_pm_con_mode(psoc,
3996 						    adapter->device_mode,
3997 						    vdev_id);
3998 	return mode;
3999 }
4000 
4001 /**
4002  * hdd_is_chan_switch_in_progress() - Check if any adapter has channel switch in
4003  * progress
4004  *
4005  * Return: true, if any adapter has channel switch in
4006  * progress else false
4007  */
hdd_is_chan_switch_in_progress(void)4008 static bool hdd_is_chan_switch_in_progress(void)
4009 {
4010 	struct hdd_adapter *adapter = NULL, *next_adapter = NULL;
4011 	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
4012 	wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_IS_CHAN_SWITCH_IN_PROGRESS;
4013 	struct hdd_ap_ctx *ap_ctx;
4014 	struct wlan_hdd_link_info *link_info;
4015 	bool is_restart;
4016 	struct wlan_objmgr_vdev *vdev;
4017 
4018 	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
4019 					   dbgid) {
4020 		if (adapter->device_mode != QDF_SAP_MODE &&
4021 		    adapter->device_mode != QDF_P2P_GO_MODE)
4022 			goto next_adapter;
4023 
4024 		hdd_adapter_for_each_active_link_info(adapter, link_info) {
4025 			ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(link_info);
4026 			vdev = hdd_objmgr_get_vdev_by_user(link_info,
4027 							   WLAN_OSIF_ID);
4028 			if (!vdev)
4029 				continue;
4030 			is_restart = false;
4031 			if (wlan_vdev_is_restart_progress(vdev) ==
4032 			    QDF_STATUS_SUCCESS) {
4033 				hdd_debug("vdev: %d restart in progress",
4034 					  wlan_vdev_get_id(vdev));
4035 				is_restart = true;
4036 			}
4037 			hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_ID);
4038 
4039 			if (is_restart ||
4040 			    qdf_atomic_read(&ap_ctx->ch_switch_in_progress)) {
4041 				hdd_debug("channel switch progress for vdev_id %d",
4042 					  link_info->vdev_id);
4043 				hdd_adapter_dev_put_debug(adapter, dbgid);
4044 				if (next_adapter)
4045 					hdd_adapter_dev_put_debug(next_adapter,
4046 								  dbgid);
4047 				return true;
4048 			}
4049 		}
4050 next_adapter:
4051 		hdd_adapter_dev_put_debug(adapter, dbgid);
4052 	}
4053 
4054 	return false;
4055 }
4056 
4057 /**
4058  * hdd_is_cac_in_progress() - Check if any SAP connection is performing
4059  * CAC on DFS channel
4060  *
4061  * Return: true, if any of existing SAP is performing CAC
4062  * or else false
4063  */
hdd_is_cac_in_progress(void)4064 static bool hdd_is_cac_in_progress(void)
4065 {
4066 	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
4067 
4068 	if (!hdd_ctx)
4069 		return false;
4070 
4071 	return (hdd_ctx->dev_dfs_cac_status == DFS_CAC_IN_PROGRESS);
4072 }
4073 
4074 static QDF_STATUS
wlan_hdd_set_tx_rx_nss_cb(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id,uint8_t tx_nss,uint8_t rx_nss)4075 wlan_hdd_set_tx_rx_nss_cb(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id,
4076 			  uint8_t tx_nss, uint8_t rx_nss)
4077 {
4078 	struct wlan_hdd_link_info *link_info;
4079 
4080 	link_info = wlan_hdd_get_link_info_from_vdev(psoc, vdev_id);
4081 	if (!link_info) {
4082 		hdd_err("Invalid vdev %d", vdev_id);
4083 		return QDF_STATUS_E_FAILURE;
4084 	}
4085 
4086 	return hdd_update_nss(link_info, tx_nss, rx_nss);
4087 }
4088 
hdd_register_policy_manager_callback(struct wlan_objmgr_psoc * psoc)4089 static void hdd_register_policy_manager_callback(
4090 			struct wlan_objmgr_psoc *psoc)
4091 {
4092 	struct policy_mgr_hdd_cbacks hdd_cbacks;
4093 
4094 	qdf_mem_zero(&hdd_cbacks, sizeof(hdd_cbacks));
4095 	hdd_cbacks.sap_restart_chan_switch_cb =
4096 		hdd_sap_restart_chan_switch_cb;
4097 	hdd_cbacks.wlan_hdd_get_channel_for_sap_restart =
4098 		wlan_hdd_get_channel_for_sap_restart;
4099 	hdd_cbacks.get_mode_for_non_connected_vdev =
4100 		wlan_hdd_get_mode_for_non_connected_vdev;
4101 	hdd_cbacks.hdd_get_device_mode = hdd_get_device_mode;
4102 	hdd_cbacks.hdd_is_chan_switch_in_progress =
4103 				hdd_is_chan_switch_in_progress;
4104 	hdd_cbacks.hdd_is_cac_in_progress =
4105 				hdd_is_cac_in_progress;
4106 	hdd_cbacks.wlan_hdd_set_sap_csa_reason =
4107 				wlan_hdd_set_sap_csa_reason;
4108 	hdd_cbacks.hdd_get_ap_6ghz_capable = hdd_get_ap_6ghz_capable;
4109 	hdd_cbacks.wlan_hdd_indicate_active_ndp_cnt =
4110 				hdd_indicate_active_ndp_cnt;
4111 	hdd_cbacks.wlan_get_ap_prefer_conc_ch_params =
4112 			wlan_get_ap_prefer_conc_ch_params;
4113 	hdd_cbacks.wlan_get_sap_acs_band =
4114 			wlan_get_sap_acs_band;
4115 	hdd_cbacks.wlan_check_cc_intf_cb = wlan_hdd_check_cc_intf_cb;
4116 	hdd_cbacks.wlan_set_tx_rx_nss_cb = wlan_hdd_set_tx_rx_nss_cb;
4117 
4118 	if (QDF_STATUS_SUCCESS !=
4119 	    policy_mgr_register_hdd_cb(psoc, &hdd_cbacks)) {
4120 		hdd_err("HDD callback registration with policy manager failed");
4121 	}
4122 }
4123 #else
hdd_register_policy_manager_callback(struct wlan_objmgr_psoc * psoc)4124 static void hdd_register_policy_manager_callback(
4125 			struct wlan_objmgr_psoc *psoc)
4126 {
4127 }
4128 #endif
4129 
4130 #ifdef WLAN_SUPPORT_GAP_LL_PS_MODE
hdd_register_green_ap_callback(struct wlan_objmgr_pdev * pdev)4131 static void hdd_register_green_ap_callback(struct wlan_objmgr_pdev *pdev)
4132 {
4133 	struct green_ap_hdd_callback hdd_cback;
4134 	qdf_mem_zero(&hdd_cback, sizeof(hdd_cback));
4135 
4136 	hdd_cback.send_event = wlan_hdd_send_green_ap_ll_ps_event;
4137 
4138 	if (QDF_STATUS_SUCCESS !=
4139 			green_ap_register_hdd_callback(pdev, &hdd_cback)) {
4140 		hdd_err("HDD callback registration for Green AP failed");
4141 	}
4142 }
4143 #else
hdd_register_green_ap_callback(struct wlan_objmgr_pdev * pdev)4144 static inline void hdd_register_green_ap_callback(struct wlan_objmgr_pdev *pdev)
4145 {
4146 }
4147 #endif
4148 
4149 #ifdef WLAN_FEATURE_NAN
4150 #ifdef WLAN_FEATURE_SR
hdd_register_sr_concurrency_cb(struct nan_callbacks * cb_obj)4151 static void hdd_register_sr_concurrency_cb(struct nan_callbacks *cb_obj)
4152 {
4153 	cb_obj->nan_sr_concurrency_update = hdd_nan_sr_concurrency_update;
4154 }
4155 #else
hdd_register_sr_concurrency_cb(struct nan_callbacks * cb_obj)4156 static void hdd_register_sr_concurrency_cb(struct nan_callbacks *cb_obj)
4157 {}
4158 #endif
hdd_nan_register_callbacks(struct hdd_context * hdd_ctx)4159 static void hdd_nan_register_callbacks(struct hdd_context *hdd_ctx)
4160 {
4161 	struct nan_callbacks cb_obj = {0};
4162 
4163 	cb_obj.ndi_open = hdd_ndi_open;
4164 	cb_obj.ndi_close = hdd_ndi_close;
4165 	cb_obj.ndi_set_mode = hdd_ndi_set_mode;
4166 	cb_obj.ndi_start = hdd_ndi_start;
4167 	cb_obj.ndi_delete = hdd_ndi_delete;
4168 	cb_obj.drv_ndi_create_rsp_handler = hdd_ndi_drv_ndi_create_rsp_handler;
4169 	cb_obj.drv_ndi_delete_rsp_handler = hdd_ndi_drv_ndi_delete_rsp_handler;
4170 
4171 	cb_obj.new_peer_ind = hdd_ndp_new_peer_handler;
4172 	cb_obj.peer_departed_ind = hdd_ndp_peer_departed_handler;
4173 
4174 	cb_obj.nan_concurrency_update = hdd_nan_concurrency_update;
4175 	cb_obj.set_mc_list = hdd_update_multicast_list;
4176 
4177 	hdd_register_sr_concurrency_cb(&cb_obj);
4178 
4179 	os_if_nan_register_hdd_callbacks(hdd_ctx->psoc, &cb_obj);
4180 }
4181 #else
hdd_nan_register_callbacks(struct hdd_context * hdd_ctx)4182 static inline void hdd_nan_register_callbacks(struct hdd_context *hdd_ctx)
4183 {
4184 }
4185 #endif
4186 
4187 #ifdef CONFIG_LEAK_DETECTION
4188 /**
4189  * hdd_check_for_leaks() - Perform runtime memory leak checks
4190  * @hdd_ctx: the global HDD context
4191  * @is_ssr: true if SSR is in progress
4192  *
4193  * This API triggers runtime memory leak detection. This feature enforces the
4194  * policy that any memory allocated at runtime must also be released at runtime.
4195  *
4196  * Allocating memory at runtime and releasing it at unload is effectively a
4197  * memory leak for configurations which never unload (e.g. LONU, statically
4198  * compiled driver). Such memory leaks are NOT false positives, and must be
4199  * fixed.
4200  *
4201  * Return: None
4202  */
hdd_check_for_leaks(struct hdd_context * hdd_ctx,bool is_ssr)4203 static void hdd_check_for_leaks(struct hdd_context *hdd_ctx, bool is_ssr)
4204 {
4205 	/* DO NOT REMOVE these checks; for false positives, read above first */
4206 
4207 	wlan_objmgr_psoc_check_for_leaks(hdd_ctx->psoc);
4208 
4209 	/* many adapter resources are not freed by design during SSR */
4210 	if (is_ssr)
4211 		return;
4212 
4213 	qdf_wake_lock_check_for_leaks();
4214 	qdf_delayed_work_check_for_leaks();
4215 	qdf_mc_timer_check_for_leaks();
4216 	qdf_nbuf_map_check_for_leaks();
4217 	qdf_periodic_work_check_for_leaks();
4218 	qdf_mem_check_for_leaks();
4219 }
4220 
4221 /**
4222  * hdd_debug_domain_set() - Set qdf debug domain
4223  * @domain: debug domain to be set
4224  *
4225  * In the scenario of system reboot, it may have thread accessing debug domain
4226  * for memory allocation/free, other than the one trying to change it.
4227  * If debug domain is changed after a memory allocation but before the free,
4228  * it will hit debug domain mismatch assertion in memory free.
4229  * To avoid such assertion, skip debug domain transition if system reboot is
4230  * in progress.
4231  *
4232  * Return: 0 if the specified debug domain has been set, -EBUSY otherwise
4233  */
hdd_debug_domain_set(enum qdf_debug_domain domain)4234 static int hdd_debug_domain_set(enum qdf_debug_domain domain)
4235 {
4236 	int ret = 0;
4237 
4238 	if (cds_sys_reboot_protect()) {
4239 		hdd_info("System is rebooting, skip debug domain transition");
4240 		ret = -EBUSY;
4241 	} else {
4242 		qdf_debug_domain_set(domain);
4243 	}
4244 
4245 	cds_sys_reboot_unprotect();
4246 
4247 	return ret;
4248 }
4249 
4250 #define hdd_debug_domain_get() qdf_debug_domain_get()
4251 #else
hdd_check_for_objmgr_peer_leaks(struct wlan_objmgr_psoc * psoc)4252 static void hdd_check_for_objmgr_peer_leaks(struct wlan_objmgr_psoc *psoc)
4253 {
4254 	uint32_t vdev_id;
4255 	struct wlan_objmgr_vdev *vdev;
4256 	struct wlan_objmgr_peer *peer;
4257 
4258 	/* get module id which cause the leak and release ref */
4259 	wlan_objmgr_for_each_psoc_vdev(psoc, vdev_id, vdev) {
4260 		wlan_objmgr_for_each_vdev_peer(vdev, peer) {
4261 			qdf_atomic_t *ref_id_dbg;
4262 			int ref_id;
4263 			int32_t refs;
4264 
4265 			ref_id_dbg = vdev->vdev_objmgr.ref_id_dbg;
4266 			wlan_objmgr_for_each_refs(ref_id_dbg, ref_id, refs)
4267 				wlan_objmgr_peer_release_ref(peer, ref_id);
4268 		}
4269 	}
4270 }
4271 
hdd_check_for_objmgr_leaks(struct hdd_context * hdd_ctx)4272 static void hdd_check_for_objmgr_leaks(struct hdd_context *hdd_ctx)
4273 {
4274 	uint32_t vdev_id, pdev_id;
4275 	struct wlan_objmgr_psoc *psoc;
4276 	struct wlan_objmgr_vdev *vdev;
4277 	struct wlan_objmgr_pdev *pdev;
4278 	/*
4279 	 * leak detection is disabled, force release the references for the wlan
4280 	 * to recover cleanly.
4281 	 */
4282 	psoc = hdd_ctx->psoc;
4283 	if (!psoc)
4284 		return;
4285 
4286 
4287 	hdd_check_for_objmgr_peer_leaks(psoc);
4288 
4289 	wlan_objmgr_for_each_psoc_vdev(psoc, vdev_id, vdev) {
4290 		qdf_atomic_t *ref_id_dbg;
4291 		int ref_id;
4292 		int32_t refs;
4293 
4294 		ref_id_dbg = vdev->vdev_objmgr.ref_id_dbg;
4295 		wlan_objmgr_for_each_refs(ref_id_dbg, ref_id, refs) {
4296 			wlan_objmgr_vdev_release_ref(vdev, ref_id);
4297 		}
4298 	}
4299 
4300 	wlan_objmgr_for_each_psoc_pdev(psoc, pdev_id, pdev) {
4301 		qdf_atomic_t *ref_id_dbg;
4302 		int ref_id;
4303 		int32_t refs;
4304 
4305 		ref_id_dbg = pdev->pdev_objmgr.ref_id_dbg;
4306 		wlan_objmgr_for_each_refs(ref_id_dbg, ref_id, refs)
4307 			wlan_objmgr_pdev_release_ref(pdev, ref_id);
4308 	}
4309 }
4310 
hdd_check_for_leaks(struct hdd_context * hdd_ctx,bool is_ssr)4311 static void hdd_check_for_leaks(struct hdd_context *hdd_ctx, bool is_ssr)
4312 {
4313 	hdd_check_for_objmgr_leaks(hdd_ctx);
4314 }
4315 
4316 #define hdd_debug_domain_set(domain) 0
4317 #define hdd_debug_domain_get() DEFAULT_DEBUG_DOMAIN_INIT
4318 #endif /* CONFIG_LEAK_DETECTION */
4319 
4320 #ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE
4321 /**
4322  * hdd_skip_acs_scan_timer_handler() - skip ACS scan timer timeout handler
4323  * @data: pointer to struct hdd_context
4324  *
4325  * This function will reset acs_scan_status to eSAP_DO_NEW_ACS_SCAN.
4326  * Then new ACS request will do a fresh scan without reusing the cached
4327  * scan information.
4328  *
4329  * Return: void
4330  */
hdd_skip_acs_scan_timer_handler(void * data)4331 static void hdd_skip_acs_scan_timer_handler(void *data)
4332 {
4333 	struct hdd_context *hdd_ctx = data;
4334 	mac_handle_t mac_handle;
4335 
4336 	hdd_debug("ACS Scan result expired. Reset ACS scan skip");
4337 	hdd_ctx->skip_acs_scan_status = eSAP_DO_NEW_ACS_SCAN;
4338 	qdf_spin_lock(&hdd_ctx->acs_skip_lock);
4339 	qdf_mem_free(hdd_ctx->last_acs_freq_list);
4340 	hdd_ctx->last_acs_freq_list = NULL;
4341 	hdd_ctx->num_of_channels = 0;
4342 	qdf_spin_unlock(&hdd_ctx->acs_skip_lock);
4343 
4344 	mac_handle = hdd_ctx->mac_handle;
4345 	if (!mac_handle)
4346 		return;
4347 }
4348 
hdd_skip_acs_scan_timer_init(struct hdd_context * hdd_ctx)4349 static void hdd_skip_acs_scan_timer_init(struct hdd_context *hdd_ctx)
4350 {
4351 	QDF_STATUS status;
4352 
4353 	status = qdf_mc_timer_init(&hdd_ctx->skip_acs_scan_timer,
4354 				   QDF_TIMER_TYPE_SW,
4355 				   hdd_skip_acs_scan_timer_handler,
4356 				   hdd_ctx);
4357 	if (QDF_IS_STATUS_ERROR(status))
4358 		hdd_err("Failed to init ACS Skip timer");
4359 	qdf_spinlock_create(&hdd_ctx->acs_skip_lock);
4360 }
4361 
hdd_skip_acs_scan_timer_deinit(struct hdd_context * hdd_ctx)4362 static void hdd_skip_acs_scan_timer_deinit(struct hdd_context *hdd_ctx)
4363 {
4364 	if (QDF_TIMER_STATE_RUNNING ==
4365 	    qdf_mc_timer_get_current_state(&hdd_ctx->skip_acs_scan_timer)) {
4366 		qdf_mc_timer_stop(&hdd_ctx->skip_acs_scan_timer);
4367 	}
4368 
4369 	if (!QDF_IS_STATUS_SUCCESS
4370 		    (qdf_mc_timer_destroy(&hdd_ctx->skip_acs_scan_timer))) {
4371 		hdd_err("Cannot deallocate ACS Skip timer");
4372 	}
4373 	qdf_spin_lock(&hdd_ctx->acs_skip_lock);
4374 	qdf_mem_free(hdd_ctx->last_acs_freq_list);
4375 	hdd_ctx->last_acs_freq_list = NULL;
4376 	hdd_ctx->num_of_channels = 0;
4377 	qdf_spin_unlock(&hdd_ctx->acs_skip_lock);
4378 }
4379 #else
hdd_skip_acs_scan_timer_init(struct hdd_context * hdd_ctx)4380 static void hdd_skip_acs_scan_timer_init(struct hdd_context *hdd_ctx) {}
hdd_skip_acs_scan_timer_deinit(struct hdd_context * hdd_ctx)4381 static void hdd_skip_acs_scan_timer_deinit(struct hdd_context *hdd_ctx) {}
4382 #endif
4383 
4384 /**
4385  * hdd_update_country_code - Update country code
4386  * @hdd_ctx: HDD context
4387  *
4388  * Update country code based on module parameter country_code
4389  *
4390  * Return: 0 on success and errno on failure
4391  */
hdd_update_country_code(struct hdd_context * hdd_ctx)4392 int hdd_update_country_code(struct hdd_context *hdd_ctx)
4393 {
4394 	if (!country_code ||
4395 	    !ucfg_reg_is_user_country_set_allowed(hdd_ctx->psoc))
4396 		return 0;
4397 
4398 	return hdd_reg_set_country(hdd_ctx, country_code);
4399 }
4400 
4401 #ifdef WLAN_NS_OFFLOAD
4402 /**
4403  * hdd_wlan_unregister_ip6_notifier() - unregister IPv6 change notifier
4404  * @hdd_ctx: Pointer to hdd context
4405  *
4406  * Unregister for IPv6 address change notifications.
4407  *
4408  * Return: None
4409  */
hdd_wlan_unregister_ip6_notifier(struct hdd_context * hdd_ctx)4410 static void hdd_wlan_unregister_ip6_notifier(struct hdd_context *hdd_ctx)
4411 {
4412 	unregister_inet6addr_notifier(&hdd_ctx->ipv6_notifier);
4413 }
4414 
4415 /**
4416  * hdd_wlan_register_ip6_notifier() - register IPv6 change notifier
4417  * @hdd_ctx: Pointer to hdd context
4418  *
4419  * Register for IPv6 address change notifications.
4420  *
4421  * Return: 0 on success and errno on failure.
4422  */
hdd_wlan_register_ip6_notifier(struct hdd_context * hdd_ctx)4423 static int hdd_wlan_register_ip6_notifier(struct hdd_context *hdd_ctx)
4424 {
4425 	int ret;
4426 
4427 	hdd_ctx->ipv6_notifier.notifier_call = wlan_hdd_ipv6_changed;
4428 	ret = register_inet6addr_notifier(&hdd_ctx->ipv6_notifier);
4429 	if (ret) {
4430 		hdd_err("Failed to register IPv6 notifier: %d", ret);
4431 		goto out;
4432 	}
4433 
4434 	hdd_debug("Registered IPv6 notifier");
4435 out:
4436 	return ret;
4437 }
4438 #else
4439 /**
4440  * hdd_wlan_unregister_ip6_notifier() - unregister IPv6 change notifier
4441  * @hdd_ctx: Pointer to hdd context
4442  *
4443  * Unregister for IPv6 address change notifications.
4444  *
4445  * Return: None
4446  */
hdd_wlan_unregister_ip6_notifier(struct hdd_context * hdd_ctx)4447 static void hdd_wlan_unregister_ip6_notifier(struct hdd_context *hdd_ctx)
4448 {
4449 }
4450 
4451 /**
4452  * hdd_wlan_register_ip6_notifier() - register IPv6 change notifier
4453  * @hdd_ctx: Pointer to hdd context
4454  *
4455  * Register for IPv6 address change notifications.
4456  *
4457  * Return: None
4458  */
hdd_wlan_register_ip6_notifier(struct hdd_context * hdd_ctx)4459 static int hdd_wlan_register_ip6_notifier(struct hdd_context *hdd_ctx)
4460 {
4461 	return 0;
4462 }
4463 #endif
4464 
4465 #ifdef FEATURE_RUNTIME_PM
4466 #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 7, 0)
hdd_pm_qos_add_notifier(struct hdd_context * hdd_ctx)4467 static int hdd_pm_qos_add_notifier(struct hdd_context *hdd_ctx)
4468 {
4469 	return dev_pm_qos_add_notifier(hdd_ctx->parent_dev,
4470 				       &hdd_ctx->pm_qos_notifier,
4471 				       DEV_PM_QOS_RESUME_LATENCY);
4472 }
4473 
hdd_pm_qos_remove_notifier(struct hdd_context * hdd_ctx)4474 static int hdd_pm_qos_remove_notifier(struct hdd_context *hdd_ctx)
4475 {
4476 	return dev_pm_qos_remove_notifier(hdd_ctx->parent_dev,
4477 					  &hdd_ctx->pm_qos_notifier,
4478 					  DEV_PM_QOS_RESUME_LATENCY);
4479 }
4480 #else
hdd_pm_qos_add_notifier(struct hdd_context * hdd_ctx)4481 static int hdd_pm_qos_add_notifier(struct hdd_context *hdd_ctx)
4482 {
4483 	return pm_qos_add_notifier(PM_QOS_CPU_DMA_LATENCY,
4484 				   &hdd_ctx->pm_qos_notifier);
4485 }
4486 
hdd_pm_qos_remove_notifier(struct hdd_context * hdd_ctx)4487 static int hdd_pm_qos_remove_notifier(struct hdd_context *hdd_ctx)
4488 {
4489 	return pm_qos_remove_notifier(PM_QOS_CPU_DMA_LATENCY,
4490 				      &hdd_ctx->pm_qos_notifier);
4491 }
4492 #endif
4493 
4494 /**
4495  * hdd_wlan_register_pm_qos_notifier() - register PM QOS notifier
4496  * @hdd_ctx: Pointer to hdd context
4497  *
4498  * Register for PM QOS change notifications.
4499  *
4500  * Return: None
4501  */
hdd_wlan_register_pm_qos_notifier(struct hdd_context * hdd_ctx)4502 static int hdd_wlan_register_pm_qos_notifier(struct hdd_context *hdd_ctx)
4503 {
4504 	int ret;
4505 
4506 	qdf_spinlock_create(&hdd_ctx->pm_qos_lock);
4507 
4508 	/* if gRuntimePM is 1 then feature is enabled without CXPC */
4509 	if (hdd_ctx->config->runtime_pm != hdd_runtime_pm_dynamic) {
4510 		hdd_debug("Dynamic Runtime PM disabled");
4511 		return 0;
4512 	}
4513 
4514 	hdd_ctx->pm_qos_notifier.notifier_call = wlan_hdd_pm_qos_notify;
4515 	ret = hdd_pm_qos_add_notifier(hdd_ctx);
4516 	if (ret)
4517 		hdd_err("Failed to register PM_QOS notifier: %d", ret);
4518 	else
4519 		hdd_debug("PM QOS Notifier registered");
4520 
4521 	return ret;
4522 }
4523 
4524 /**
4525  * hdd_wlan_unregister_pm_qos_notifier() - unregister PM QOS notifier
4526  * @hdd_ctx: Pointer to hdd context
4527  *
4528  * Unregister for PM QOS change notifications.
4529  *
4530  * Return: None
4531  */
hdd_wlan_unregister_pm_qos_notifier(struct hdd_context * hdd_ctx)4532 static void hdd_wlan_unregister_pm_qos_notifier(struct hdd_context *hdd_ctx)
4533 {
4534 	int ret;
4535 
4536 	if (hdd_ctx->config->runtime_pm != hdd_runtime_pm_dynamic) {
4537 		hdd_debug("Dynamic Runtime PM disabled");
4538 		qdf_spinlock_destroy(&hdd_ctx->pm_qos_lock);
4539 		return;
4540 	}
4541 
4542 	ret = hdd_pm_qos_remove_notifier(hdd_ctx);
4543 	if (ret)
4544 		hdd_warn("Failed to remove qos notifier, err = %d\n", ret);
4545 
4546 	qdf_spin_lock_irqsave(&hdd_ctx->pm_qos_lock);
4547 
4548 	if (hdd_ctx->runtime_pm_prevented) {
4549 		hif_rtpm_put(HIF_RTPM_PUT_NOIDLE, HIF_RTPM_ID_PM_QOS_NOTIFY);
4550 		hdd_ctx->runtime_pm_prevented = false;
4551 	}
4552 
4553 	qdf_spin_unlock_irqrestore(&hdd_ctx->pm_qos_lock);
4554 
4555 	qdf_spinlock_destroy(&hdd_ctx->pm_qos_lock);
4556 }
4557 #else
hdd_wlan_register_pm_qos_notifier(struct hdd_context * hdd_ctx)4558 static int hdd_wlan_register_pm_qos_notifier(struct hdd_context *hdd_ctx)
4559 {
4560 	return 0;
4561 }
4562 
hdd_wlan_unregister_pm_qos_notifier(struct hdd_context * hdd_ctx)4563 static void hdd_wlan_unregister_pm_qos_notifier(struct hdd_context *hdd_ctx)
4564 {
4565 }
4566 #endif
4567 
4568 /**
4569  * hdd_enable_power_management() - API to Enable Power Management
4570  * @hdd_ctx: HDD context
4571  *
4572  * API invokes Bus Interface Layer power management functionality
4573  *
4574  * Return: None
4575  */
hdd_enable_power_management(struct hdd_context * hdd_ctx)4576 static void hdd_enable_power_management(struct hdd_context *hdd_ctx)
4577 {
4578 	void *hif_ctx = cds_get_context(QDF_MODULE_ID_HIF);
4579 
4580 	if (!hif_ctx)
4581 		return;
4582 
4583 	hif_enable_power_management(hif_ctx, cds_is_packet_log_enabled());
4584 	hdd_wlan_register_pm_qos_notifier(hdd_ctx);
4585 }
4586 
4587 /**
4588  * hdd_disable_power_management() - API to disable Power Management
4589  * @hdd_ctx: HDD context
4590  *
4591  * API disable Bus Interface Layer Power management functionality
4592  *
4593  * Return: None
4594  */
hdd_disable_power_management(struct hdd_context * hdd_ctx)4595 static void hdd_disable_power_management(struct hdd_context *hdd_ctx)
4596 {
4597 	void *hif_ctx = cds_get_context(QDF_MODULE_ID_HIF);
4598 
4599 	if (!hif_ctx)
4600 		return;
4601 
4602 	hdd_wlan_unregister_pm_qos_notifier(hdd_ctx);
4603 	hif_disable_power_management(hif_ctx);
4604 }
4605 
4606 /**
4607  * hdd_register_notifiers - Register netdev notifiers.
4608  * @hdd_ctx: HDD context
4609  *
4610  * Register netdev notifiers like IPv4 and IPv6.
4611  *
4612  * Return: 0 on success and errno on failure
4613  */
hdd_register_notifiers(struct hdd_context * hdd_ctx)4614 static int hdd_register_notifiers(struct hdd_context *hdd_ctx)
4615 {
4616 	int ret;
4617 
4618 	ret = hdd_wlan_register_ip6_notifier(hdd_ctx);
4619 	if (ret)
4620 		goto out;
4621 
4622 	hdd_ctx->ipv4_notifier.notifier_call = wlan_hdd_ipv4_changed;
4623 	ret = register_inetaddr_notifier(&hdd_ctx->ipv4_notifier);
4624 	if (ret) {
4625 		hdd_err("Failed to register IPv4 notifier: %d", ret);
4626 		goto unregister_ip6_notifier;
4627 	}
4628 
4629 	ret = osif_dp_nud_register_netevent_notifier(hdd_ctx->psoc);
4630 	if (ret) {
4631 		hdd_err("Failed to register netevent notifier: %d",
4632 			ret);
4633 		goto unregister_inetaddr_notifier;
4634 	}
4635 
4636 	return 0;
4637 
4638 unregister_inetaddr_notifier:
4639 	unregister_inetaddr_notifier(&hdd_ctx->ipv4_notifier);
4640 unregister_ip6_notifier:
4641 	hdd_wlan_unregister_ip6_notifier(hdd_ctx);
4642 out:
4643 	return ret;
4644 }
4645 
4646 #ifdef WLAN_FEATURE_WMI_SEND_RECV_QMI
4647 static inline
hdd_set_qmi_stats_enabled(struct hdd_context * hdd_ctx)4648 void hdd_set_qmi_stats_enabled(struct hdd_context *hdd_ctx)
4649 {
4650 	wmi_unified_t wmi_handle = get_wmi_unified_hdl_from_psoc(hdd_ctx->psoc);
4651 
4652 	if (!wmi_handle) {
4653 		hdd_err("could not get wmi handle");
4654 		return;
4655 	}
4656 
4657 	wmi_set_qmi_stats(wmi_handle, hdd_ctx->config->is_qmi_stats_enabled);
4658 }
4659 #else
4660 static inline
hdd_set_qmi_stats_enabled(struct hdd_context * hdd_ctx)4661 void hdd_set_qmi_stats_enabled(struct hdd_context *hdd_ctx)
4662 {
4663 }
4664 #endif
4665 
4666 #ifdef CONFIG_FW_LOGS_BASED_ON_INI
4667 /**
4668  * hdd_set_fw_log_params() - Set log parameters to FW
4669  * @hdd_ctx: HDD Context
4670  * @vdev_id: vdev_id
4671  *
4672  * This function set the FW Debug log level based on the INI.
4673  *
4674  * Return: None
4675  */
hdd_set_fw_log_params(struct hdd_context * hdd_ctx,uint8_t vdev_id)4676 static void hdd_set_fw_log_params(struct hdd_context *hdd_ctx,
4677 				  uint8_t vdev_id)
4678 {
4679 	QDF_STATUS status;
4680 	uint16_t enable_fw_log_level, enable_fw_log_type;
4681 	int ret;
4682 
4683 	if (!hdd_ctx->config->enable_fw_log) {
4684 		hdd_debug("enable_fw_log not enabled in INI");
4685 		return;
4686 	}
4687 
4688 	/* Enable FW logs based on INI configuration */
4689 	status = ucfg_fwol_get_enable_fw_log_type(hdd_ctx->psoc,
4690 						  &enable_fw_log_type);
4691 	if (QDF_IS_STATUS_ERROR(status))
4692 		return;
4693 	ret = sme_cli_set_command(vdev_id, WMI_DBGLOG_TYPE,
4694 				  enable_fw_log_type, DBG_CMD);
4695 	if (ret != 0)
4696 		hdd_err("Failed to enable FW log type ret %d", ret);
4697 
4698 	status = ucfg_fwol_get_enable_fw_log_level(hdd_ctx->psoc,
4699 						   &enable_fw_log_level);
4700 	if (QDF_IS_STATUS_ERROR(status))
4701 		return;
4702 	ret = sme_cli_set_command(vdev_id, WMI_DBGLOG_LOG_LEVEL,
4703 				  enable_fw_log_level, DBG_CMD);
4704 	if (ret != 0)
4705 		hdd_err("Failed to enable FW log level ret %d", ret);
4706 
4707 	sme_enable_fw_module_log_level(hdd_ctx->mac_handle, vdev_id);
4708 }
4709 #else
hdd_set_fw_log_params(struct hdd_context * hdd_ctx,uint8_t vdev_id)4710 static void hdd_set_fw_log_params(struct hdd_context *hdd_ctx, uint8_t vdev_id)
4711 {
4712 }
4713 
4714 #endif
4715 
4716 /**
4717  * hdd_features_deinit() - Deinit features
4718  * @hdd_ctx:	HDD context
4719  *
4720  * De-Initialize features and their feature context.
4721  *
4722  * Return: none.
4723  */
hdd_features_deinit(struct hdd_context * hdd_ctx)4724 static void hdd_features_deinit(struct hdd_context *hdd_ctx)
4725 {
4726 	wlan_hdd_gpio_wakeup_deinit(hdd_ctx);
4727 	wlan_hdd_twt_deinit(hdd_ctx);
4728 	wlan_hdd_deinit_chan_info(hdd_ctx);
4729 	wlan_hdd_tsf_deinit(hdd_ctx);
4730 	if (cds_is_packet_log_enabled())
4731 		hdd_pktlog_enable_disable(hdd_ctx, false, 0, 0);
4732 }
4733 
4734 /**
4735  * hdd_deconfigure_cds() -De-Configure cds
4736  * @hdd_ctx:	HDD context
4737  *
4738  * Deconfigure Cds modules before WLAN firmware is down.
4739  *
4740  * Return: 0 on success and errno on failure.
4741  */
hdd_deconfigure_cds(struct hdd_context * hdd_ctx)4742 static int hdd_deconfigure_cds(struct hdd_context *hdd_ctx)
4743 {
4744 	QDF_STATUS qdf_status;
4745 	int ret = 0;
4746 
4747 	hdd_enter();
4748 
4749 	wlan_hdd_hang_event_notifier_unregister();
4750 	/* De-init features */
4751 	hdd_features_deinit(hdd_ctx);
4752 
4753 	qdf_status = policy_mgr_deregister_mode_change_cb(hdd_ctx->psoc);
4754 	if (!QDF_IS_STATUS_SUCCESS(qdf_status))
4755 		hdd_debug("Failed to deregister mode change cb with Policy Manager");
4756 
4757 	qdf_status = cds_disable(hdd_ctx->psoc);
4758 	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
4759 		hdd_err("Failed to Disable the CDS Modules! :%d",
4760 			qdf_status);
4761 		ret = -EINVAL;
4762 	}
4763 
4764 	if (ucfg_ipa_uc_ol_deinit(hdd_ctx->pdev) != QDF_STATUS_SUCCESS) {
4765 		hdd_err("Failed to disconnect pipes");
4766 		ret = -EINVAL;
4767 	}
4768 
4769 	hdd_exit();
4770 	return ret;
4771 }
4772 
4773 /**
4774  * hdd_qmi_register_callbacks() - Register QMI callbacks
4775  * @hdd_ctx: HDD context
4776  *
4777  * Return: None
4778  */
hdd_qmi_register_callbacks(struct hdd_context * hdd_ctx)4779 static inline void hdd_qmi_register_callbacks(struct hdd_context *hdd_ctx)
4780 {
4781 	struct wlan_qmi_psoc_callbacks cb_obj;
4782 
4783 	os_if_qmi_register_callbacks(hdd_ctx->psoc, &cb_obj);
4784 }
4785 
4786 /**
4787  * hdd_set_pcie_params() - Set pcie params
4788  * @hdd_ctx: HDD context
4789  * @index: index value
4790  * @param: pointer to vdev/pdev set param info
4791  *
4792  * Checks for pcie_config value and sets
4793  * corresponding params
4794  *
4795  * Return: 0 on success and errno on failure.
4796  */
hdd_set_pcie_params(struct hdd_context * hdd_ctx,uint8_t index,struct dev_set_param * param)4797 static int hdd_set_pcie_params(struct hdd_context *hdd_ctx,
4798 			       uint8_t index, struct dev_set_param *param)
4799 {
4800 	int ret = 0;
4801 	uint8_t check_value = 0;
4802 
4803 	ret = ucfg_fwol_get_pcie_config(hdd_ctx->psoc, &check_value);
4804 	if (QDF_IS_STATUS_SUCCESS(ret)) {
4805 		if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
4806 			ret = mlme_check_index_setparam(param,
4807 					wmi_pdev_param_pcie_config,
4808 					(int)check_value, index++,
4809 					FTM_MAX_PDEV_PARAMS);
4810 		} else {
4811 			ret = mlme_check_index_setparam(param,
4812 					wmi_pdev_param_pcie_config,
4813 					(int)check_value, index++,
4814 					MAX_PDEV_PRE_ENABLE_PARAMS);
4815 		}
4816 		if (QDF_IS_STATUS_ERROR(ret)) {
4817 			hdd_err("failed to set wmi_pdev_param_pcie_config");
4818 			return ret;
4819 		}
4820 	}
4821 	return ret;
4822 }
4823 
4824 #ifdef FEATURE_SET
4825 #ifdef WLAN_FEATURE_11BE
4826 /**
4827  * hdd_is_cfg_dot11_mode_11be() - Check if dot11 mode is 11 be
4828  * @dot11_mode: Input dot11_mode which needs to be checked
4829  *
4830  * Return: True, ifinput dot11_mode is 11be dot11 mode else return false
4831  */
hdd_is_cfg_dot11_mode_11be(enum hdd_dot11_mode dot11_mode)4832 static bool hdd_is_cfg_dot11_mode_11be(enum hdd_dot11_mode dot11_mode)
4833 {
4834 	return (dot11_mode == eHDD_DOT11_MODE_11be ||
4835 		dot11_mode == eHDD_DOT11_MODE_11be_ONLY);
4836 }
4837 
4838 /**
4839  * hdd_is_11be_supported() - Check if 11be is supported or not
4840  * @hdd_ctx: Pointer to hdd context
4841  *
4842  * Return: True, if 11be is supported else return false
4843  */
hdd_is_11be_supported(struct hdd_context * hdd_ctx)4844 static bool hdd_is_11be_supported(struct hdd_context *hdd_ctx)
4845 {
4846 	bool mlo_capab;
4847 
4848 	ucfg_psoc_mlme_get_11be_capab(hdd_ctx->psoc, &mlo_capab);
4849 	if (!mlo_capab)
4850 		return false;
4851 
4852 	return true;
4853 }
4854 #else
4855 
hdd_is_cfg_dot11_mode_11be(enum hdd_dot11_mode dot11_mode)4856 static bool hdd_is_cfg_dot11_mode_11be(enum hdd_dot11_mode dot11_mode)
4857 {
4858 	return false;
4859 }
4860 
hdd_is_11be_supported(struct hdd_context * hdd_ctx)4861 static bool hdd_is_11be_supported(struct hdd_context *hdd_ctx)
4862 {
4863 	return false;
4864 }
4865 #endif
4866 
4867 WMI_HOST_WIFI_STANDARD
hdd_get_wifi_standard(struct hdd_context * hdd_ctx,enum hdd_dot11_mode dot11_mode,uint32_t band_capability)4868 hdd_get_wifi_standard(struct hdd_context *hdd_ctx,
4869 		      enum hdd_dot11_mode dot11_mode, uint32_t band_capability)
4870 {
4871 	WMI_HOST_WIFI_STANDARD wifi_standard = WMI_HOST_WIFI_STANDARD_4;
4872 
4873 	if (dot11_mode == eHDD_DOT11_MODE_AUTO) {
4874 		if (hdd_is_11be_supported(hdd_ctx))
4875 			wifi_standard = WMI_HOST_WIFI_STANDARD_7;
4876 		else if (band_capability & BIT(REG_BAND_6G))
4877 			wifi_standard = WMI_HOST_WIFI_STANDARD_6E;
4878 		else
4879 			wifi_standard = WMI_HOST_WIFI_STANDARD_6;
4880 	} else if (hdd_is_cfg_dot11_mode_11be(dot11_mode)) {
4881 		wifi_standard = WMI_HOST_WIFI_STANDARD_7;
4882 	} else if (dot11_mode == eHDD_DOT11_MODE_11ax ||
4883 		   (dot11_mode == eHDD_DOT11_MODE_11ax_ONLY)) {
4884 		if (band_capability & BIT(REG_BAND_6G))
4885 			wifi_standard = WMI_HOST_WIFI_STANDARD_6E;
4886 		else
4887 			wifi_standard = WMI_HOST_WIFI_STANDARD_6;
4888 	} else if ((dot11_mode == eHDD_DOT11_MODE_11ac) ||
4889 		   (dot11_mode == eHDD_DOT11_MODE_11ac_ONLY)) {
4890 		wifi_standard = WMI_HOST_WIFI_STANDARD_5;
4891 	}
4892 
4893 	return wifi_standard;
4894 }
4895 
4896 /**
4897  * hdd_populate_feature_set_cds_config() - Populate cds feature set config
4898  * @hdd_ctx: hdd context pointer
4899  *
4900  * Return: None
4901  */
hdd_populate_feature_set_cds_config(struct hdd_context * hdd_ctx)4902 static void hdd_populate_feature_set_cds_config(struct hdd_context *hdd_ctx)
4903 {
4904 	struct wlan_objmgr_psoc *psoc;
4905 	uint32_t band_capability;
4906 	QDF_STATUS status;
4907 	struct cds_config_info *cds_cfg;
4908 
4909 	if (!hdd_ctx)
4910 		return;
4911 
4912 	cds_cfg = cds_get_ini_config();
4913 	if (!cds_cfg) {
4914 		hdd_err("CDS config is null.");
4915 		return;
4916 	}
4917 
4918 	psoc = hdd_ctx->psoc;
4919 
4920 	cds_cfg->get_wifi_features = hdd_ctx->config->get_wifi_features;
4921 
4922 	status = ucfg_mlme_get_band_capability(hdd_ctx->psoc, &band_capability);
4923 	if (QDF_IS_STATUS_ERROR(status))
4924 		hdd_err("Failed to get MLME band capability");
4925 
4926 	band_capability =
4927 		hdd_update_band_cap_from_dot11mode(hdd_ctx, band_capability);
4928 
4929 	cds_cfg->cds_feature_set.wifi_standard =
4930 			  hdd_get_wifi_standard(hdd_ctx,
4931 						hdd_ctx->config->dot11Mode,
4932 						band_capability);
4933 
4934 	cds_cfg->cds_feature_set.sap_5g_supported =
4935 					band_capability & BIT(REG_BAND_5G);
4936 
4937 	cds_cfg->cds_feature_set.sap_6g_supported =
4938 					band_capability & BIT(REG_BAND_6G);
4939 	cds_cfg->cds_feature_set.band_capability = band_capability;
4940 }
4941 #else
4942 WMI_HOST_WIFI_STANDARD
hdd_get_wifi_standard(struct hdd_context * hdd_ctx,enum hdd_dot11_mode dot11_mode,uint32_t band_capability)4943 hdd_get_wifi_standard(struct hdd_context *hdd_ctx,
4944 		      enum hdd_dot11_mode dot11_mode, uint32_t band_capability)
4945 {
4946 	return WMI_HOST_WIFI_STANDARD_5;
4947 }
4948 
4949 static inline void
hdd_populate_feature_set_cds_config(struct hdd_context * hdd_ctx)4950 hdd_populate_feature_set_cds_config(struct hdd_context *hdd_ctx)
4951 {
4952 }
4953 #endif
4954 
hdd_wlan_start_modules(struct hdd_context * hdd_ctx,bool reinit)4955 int hdd_wlan_start_modules(struct hdd_context *hdd_ctx, bool reinit)
4956 {
4957 	int ret = 0;
4958 	qdf_device_t qdf_dev;
4959 	QDF_STATUS status;
4960 	bool unint = false;
4961 	void *hif_ctx;
4962 	struct target_psoc_info *tgt_hdl;
4963 	unsigned long thermal_state = 0;
4964 	uint8_t index = 0;
4965 	struct dev_set_param setparam[MAX_PDEV_PRE_ENABLE_PARAMS] = {};
4966 
4967 	hdd_enter();
4968 	qdf_dev = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
4969 	if (!qdf_dev) {
4970 		hdd_exit();
4971 		return -EINVAL;
4972 	}
4973 
4974 	hdd_psoc_idle_timer_stop(hdd_ctx);
4975 
4976 	if (hdd_ctx->driver_status == DRIVER_MODULES_ENABLED) {
4977 		hdd_debug("Driver modules already Enabled");
4978 		hdd_exit();
4979 		return 0;
4980 	}
4981 
4982 	cds_set_driver_state_module_stop(false);
4983 
4984 	switch (hdd_ctx->driver_status) {
4985 	case DRIVER_MODULES_UNINITIALIZED:
4986 		hdd_nofl_debug("Wlan transitioning (UNINITIALIZED -> CLOSED)");
4987 		unint = true;
4988 		fallthrough;
4989 	case DRIVER_MODULES_CLOSED:
4990 		hdd_nofl_debug("Wlan transitioning (CLOSED -> ENABLED)");
4991 		ret = hdd_debug_domain_set(QDF_DEBUG_DOMAIN_ACTIVE);
4992 		if (ret)
4993 			goto abort;
4994 
4995 		if (!reinit && !unint) {
4996 			ret = pld_power_on(qdf_dev->dev);
4997 			if (ret) {
4998 				hdd_err("Failed to power up device; errno:%d",
4999 					ret);
5000 				goto release_lock;
5001 			}
5002 		}
5003 
5004 		hdd_init_adapter_ops_wq(hdd_ctx);
5005 		pld_set_fw_log_mode(hdd_ctx->parent_dev,
5006 				    hdd_ctx->config->enable_fw_log);
5007 		ret = hdd_hif_open(qdf_dev->dev, qdf_dev->drv_hdl, qdf_dev->bid,
5008 				   qdf_dev->bus_type,
5009 				   (reinit == true) ?  HIF_ENABLE_TYPE_REINIT :
5010 				   HIF_ENABLE_TYPE_PROBE);
5011 		if (ret) {
5012 			hdd_err("Failed to open hif; errno: %d", ret);
5013 			goto power_down;
5014 		}
5015 
5016 		hif_ctx = cds_get_context(QDF_MODULE_ID_HIF);
5017 		if (!hif_ctx) {
5018 			ret = -EINVAL;
5019 			goto power_down;
5020 		}
5021 
5022 		status = ol_cds_init(qdf_dev, hif_ctx);
5023 		if (status != QDF_STATUS_SUCCESS) {
5024 			hdd_err("No Memory to Create BMI Context; status: %d",
5025 				status);
5026 			ret = qdf_status_to_os_return(status);
5027 			goto hif_close;
5028 		}
5029 
5030 		if (hdd_get_conparam() == QDF_GLOBAL_EPPING_MODE) {
5031 			status = epping_open();
5032 			if (status) {
5033 				hdd_err("Failed to open in epping mode: %d",
5034 					status);
5035 				ret = -EINVAL;
5036 				goto cds_free;
5037 			}
5038 
5039 			status = epping_enable(qdf_dev->dev, false);
5040 			if (status) {
5041 				hdd_err("Failed to enable in epping mode : %d",
5042 					status);
5043 				epping_close();
5044 				goto cds_free;
5045 			}
5046 
5047 			hdd_info("epping mode enabled");
5048 			break;
5049 		}
5050 
5051 		if (pld_is_ipa_offload_disabled(qdf_dev->dev))
5052 			ucfg_ipa_set_pld_enable(false);
5053 
5054 		ucfg_ipa_component_config_update(hdd_ctx->psoc);
5055 
5056 		hdd_update_cds_ac_specs_params(hdd_ctx);
5057 
5058 		hdd_dp_register_callbacks(hdd_ctx);
5059 
5060 		hdd_qmi_register_callbacks(hdd_ctx);
5061 
5062 		status = hdd_component_psoc_open(hdd_ctx->psoc);
5063 		if (QDF_IS_STATUS_ERROR(status)) {
5064 			hdd_err("Failed to Open legacy components; status: %d",
5065 				status);
5066 			ret = qdf_status_to_os_return(status);
5067 			goto ipa_component_free;
5068 		}
5069 
5070 		ret = hdd_update_config(hdd_ctx);
5071 		if (ret) {
5072 			hdd_err("Failed to update configuration; errno: %d",
5073 				ret);
5074 			goto ipa_component_free;
5075 		}
5076 
5077 		status = wbuff_module_init();
5078 		if (QDF_IS_STATUS_ERROR(status))
5079 			hdd_err("WBUFF init unsuccessful; status: %d", status);
5080 
5081 		status = cds_open(hdd_ctx->psoc);
5082 		if (QDF_IS_STATUS_ERROR(status)) {
5083 			hdd_err("Failed to Open CDS; status: %d", status);
5084 			ret = qdf_status_to_os_return(status);
5085 			goto psoc_close;
5086 		}
5087 
5088 		hdd_populate_feature_set_cds_config(hdd_ctx);
5089 
5090 		hdd_set_qmi_stats_enabled(hdd_ctx);
5091 
5092 		hdd_ctx->mac_handle = cds_get_context(QDF_MODULE_ID_SME);
5093 
5094 		ucfg_dp_set_rx_thread_affinity(hdd_ctx->psoc);
5095 
5096 		/* initialize components configurations after psoc open */
5097 		ret = hdd_update_components_config(hdd_ctx);
5098 		if (ret) {
5099 			hdd_err("Failed to update component configs; errno: %d",
5100 				ret);
5101 			goto close;
5102 		}
5103 
5104 		/* Override PS params for monitor mode */
5105 		if (hdd_get_conparam() == QDF_GLOBAL_MONITOR_MODE)
5106 			hdd_override_all_ps(hdd_ctx);
5107 
5108 		status = cds_dp_open(hdd_ctx->psoc);
5109 		if (!QDF_IS_STATUS_SUCCESS(status)) {
5110 			hdd_err("Failed to Open cds post open; status: %d",
5111 				status);
5112 			ret = qdf_status_to_os_return(status);
5113 			goto close;
5114 		}
5115 		/* Set IRQ affinity for WLAN DP and CE IRQS */
5116 		hif_config_irq_set_perf_affinity_hint(hif_ctx);
5117 
5118 		ret = hdd_register_cb(hdd_ctx);
5119 		if (ret) {
5120 			hdd_err("Failed to register HDD callbacks!");
5121 			goto cds_txrx_free;
5122 		}
5123 
5124 		ret = hdd_register_notifiers(hdd_ctx);
5125 		if (ret)
5126 			goto deregister_cb;
5127 
5128 		/*
5129 		 * NAN component requires certain operations like, open adapter,
5130 		 * close adapter, etc. to be initiated by HDD, for those
5131 		 * register HDD callbacks with UMAC's NAN component.
5132 		 */
5133 		hdd_nan_register_callbacks(hdd_ctx);
5134 
5135 		hdd_son_register_callbacks(hdd_ctx);
5136 
5137 		hdd_sr_register_callbacks(hdd_ctx);
5138 
5139 		wlan_hdd_register_btc_chain_mode_handler(hdd_ctx->psoc);
5140 
5141 		wlan_hdd_register_afc_pld_cb(hdd_ctx->psoc);
5142 
5143 		status = cds_pre_enable();
5144 		if (!QDF_IS_STATUS_SUCCESS(status)) {
5145 			hdd_err("Failed to pre-enable CDS; status: %d", status);
5146 			ret = qdf_status_to_os_return(status);
5147 			goto unregister_notifiers;
5148 		}
5149 
5150 		hdd_register_policy_manager_callback(
5151 			hdd_ctx->psoc);
5152 
5153 		/*
5154 		 * Call this function before hdd_enable_power_management. Since
5155 		 * it is required to trigger WMI_PDEV_DMA_RING_CFG_REQ_CMDID
5156 		 * to FW when power save isn't enable.
5157 		 */
5158 		hdd_spectral_register_to_dbr(hdd_ctx);
5159 
5160 		hdd_create_sysfs_files(hdd_ctx);
5161 		hdd_update_hw_sw_info(hdd_ctx);
5162 
5163 		if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
5164 			hdd_enable_power_management(hdd_ctx);
5165 			hdd_err("in ftm mode, no need to configure cds modules");
5166 			hdd_info("Enable FW log in ftm mode");
5167 			/*
5168 			 * Since vdev is not created for FTM mode,
5169 			 * in FW use vdev_id = 0.
5170 			 */
5171 			hdd_set_fw_log_params(hdd_ctx, 0);
5172 			ret = hdd_set_pcie_params(hdd_ctx, index, setparam);
5173 			if (QDF_IS_STATUS_ERROR(ret))
5174 				break;
5175 			index++;
5176 			ret = sme_send_multi_pdev_vdev_set_params(
5177 					MLME_PDEV_SETPARAM,
5178 					WMI_PDEV_ID_SOC, setparam, index);
5179 			if (QDF_IS_STATUS_ERROR(ret)) {
5180 				hdd_err("failed to send pdev set params");
5181 				return ret;
5182 			}
5183 
5184 			ret = -EINVAL;
5185 			break;
5186 		}
5187 
5188 		ret = hdd_configure_cds(hdd_ctx);
5189 		if (ret) {
5190 			hdd_err("Failed to Enable cds modules; errno: %d", ret);
5191 			goto sched_disable;
5192 		}
5193 
5194 		if (hdd_get_conparam() == QDF_GLOBAL_MISSION_MODE) {
5195 			status = ucfg_dp_direct_link_init(hdd_ctx->psoc);
5196 			if (QDF_IS_STATUS_ERROR(status)) {
5197 				cds_err("Failed to initialize Direct Link datapath");
5198 				ret = -EINVAL;
5199 				goto deconfigure_cds;
5200 			}
5201 		}
5202 
5203 		hdd_enable_power_management(hdd_ctx);
5204 
5205 		hdd_skip_acs_scan_timer_init(hdd_ctx);
5206 
5207 		hdd_set_hif_init_phase(hif_ctx, false);
5208 		hdd_hif_set_enable_detection(hif_ctx, true);
5209 
5210 		wlan_hdd_start_connectivity_logging(hdd_ctx);
5211 
5212 		break;
5213 
5214 	default:
5215 		QDF_DEBUG_PANIC("Unknown driver state:%d",
5216 				hdd_ctx->driver_status);
5217 		ret = -EINVAL;
5218 		goto release_lock;
5219 	}
5220 
5221 	hdd_ctx->driver_status = DRIVER_MODULES_ENABLED;
5222 	hdd_nofl_debug("Wlan transitioned (now ENABLED)");
5223 
5224 	ucfg_ipa_reg_is_driver_unloading_cb(hdd_ctx->pdev,
5225 					    cds_is_driver_unloading);
5226 	ucfg_ipa_reg_sap_xmit_cb(hdd_ctx->pdev,
5227 				 hdd_softap_ipa_start_xmit);
5228 	ucfg_ipa_reg_send_to_nw_cb(hdd_ctx->pdev,
5229 				   hdd_ipa_send_nbuf_to_network);
5230 	ucfg_dp_reg_ipa_rsp_ind(hdd_ctx->pdev);
5231 
5232 	if (!pld_get_thermal_state(hdd_ctx->parent_dev, &thermal_state,
5233 				   THERMAL_MONITOR_APPS)) {
5234 		if (thermal_state > QCA_WLAN_VENDOR_THERMAL_LEVEL_NONE)
5235 			hdd_send_thermal_mitigation_val(hdd_ctx,
5236 							thermal_state,
5237 							THERMAL_MONITOR_APPS);
5238 	}
5239 
5240 	if (!pld_get_thermal_state(hdd_ctx->parent_dev, &thermal_state,
5241 				   THERMAL_MONITOR_WPSS)) {
5242 		if (thermal_state > QCA_WLAN_VENDOR_THERMAL_LEVEL_NONE)
5243 			hdd_send_thermal_mitigation_val(hdd_ctx, thermal_state,
5244 							THERMAL_MONITOR_WPSS);
5245 	}
5246 
5247 	hdd_exit();
5248 
5249 	return 0;
5250 
5251 deconfigure_cds:
5252 	hdd_deconfigure_cds(hdd_ctx);
5253 sched_disable:
5254 	/*
5255 	 * Disable scheduler 1st so that scheduler thread doesn't send messages
5256 	 * to fw in parallel to the cleanup
5257 	 */
5258 	dispatcher_disable();
5259 	hdd_destroy_sysfs_files();
5260 	cds_post_disable();
5261 unregister_notifiers:
5262 	hdd_unregister_notifiers(hdd_ctx);
5263 
5264 deregister_cb:
5265 	hdd_deregister_cb(hdd_ctx);
5266 
5267 cds_txrx_free:
5268 
5269 	tgt_hdl = wlan_psoc_get_tgt_if_handle(hdd_ctx->psoc);
5270 
5271 	if (tgt_hdl && target_psoc_get_wmi_ready(tgt_hdl))
5272 		hdd_runtime_suspend_context_deinit(hdd_ctx);
5273 
5274 	if (hdd_ctx->pdev) {
5275 		dispatcher_pdev_close(hdd_ctx->pdev);
5276 		hdd_objmgr_release_and_destroy_pdev(hdd_ctx);
5277 	}
5278 
5279 	cds_dp_close(hdd_ctx->psoc);
5280 
5281 close:
5282 	dispatcher_disable();
5283 	hdd_ctx->driver_status = DRIVER_MODULES_CLOSED;
5284 	hdd_info("Wlan transition aborted (now CLOSED)");
5285 
5286 	cds_close(hdd_ctx->psoc);
5287 
5288 psoc_close:
5289 	hdd_component_psoc_close(hdd_ctx->psoc);
5290 	wlan_global_lmac_if_close(hdd_ctx->psoc);
5291 	cds_deinit_ini_config();
5292 
5293 ipa_component_free:
5294 	ucfg_ipa_component_config_free();
5295 
5296 cds_free:
5297 	ol_cds_free();
5298 
5299 hif_close:
5300 	hif_ctx = cds_get_context(QDF_MODULE_ID_HIF);
5301 	hdd_hif_close(hdd_ctx, hif_ctx);
5302 power_down:
5303 	hdd_deinit_adapter_ops_wq(hdd_ctx);
5304 	if (!reinit && !unint)
5305 		pld_power_off(qdf_dev->dev);
5306 release_lock:
5307 	cds_shutdown_notifier_purge();
5308 	hdd_check_for_leaks(hdd_ctx, reinit);
5309 	hdd_debug_domain_set(QDF_DEBUG_DOMAIN_INIT);
5310 
5311 abort:
5312 	cds_set_driver_state_module_stop(true);
5313 
5314 	hdd_exit();
5315 
5316 	return ret;
5317 }
5318 
5319 #ifdef WIFI_POS_CONVERGED
hdd_activate_wifi_pos(struct hdd_context * hdd_ctx)5320 static int hdd_activate_wifi_pos(struct hdd_context *hdd_ctx)
5321 {
5322 	int ret = os_if_wifi_pos_register_nl();
5323 
5324 	if (ret)
5325 		hdd_err("os_if_wifi_pos_register_nl failed");
5326 
5327 	return ret;
5328 }
5329 
hdd_deactivate_wifi_pos(void)5330 static int hdd_deactivate_wifi_pos(void)
5331 {
5332 	int ret = os_if_wifi_pos_deregister_nl();
5333 
5334 	if (ret)
5335 		hdd_err("os_if_wifi_pos_deregister_nl failed");
5336 
5337 	return ret;
5338 }
5339 
5340 /**
5341  * hdd_populate_wifi_pos_cfg - populates wifi_pos parameters
5342  * @hdd_ctx: hdd context
5343  *
5344  * Return: status of operation
5345  */
hdd_populate_wifi_pos_cfg(struct hdd_context * hdd_ctx)5346 static void hdd_populate_wifi_pos_cfg(struct hdd_context *hdd_ctx)
5347 {
5348 	struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc;
5349 	uint16_t neighbor_scan_max_chan_time;
5350 	uint16_t neighbor_scan_min_chan_time;
5351 
5352 	wifi_pos_set_oem_target_type(psoc, hdd_ctx->target_type);
5353 	wifi_pos_set_oem_fw_version(psoc, hdd_ctx->target_fw_version);
5354 	wifi_pos_set_drv_ver_major(psoc, QWLAN_VERSION_MAJOR);
5355 	wifi_pos_set_drv_ver_minor(psoc, QWLAN_VERSION_MINOR);
5356 	wifi_pos_set_drv_ver_patch(psoc, QWLAN_VERSION_PATCH);
5357 	wifi_pos_set_drv_ver_build(psoc, QWLAN_VERSION_BUILD);
5358 	ucfg_mlme_get_neighbor_scan_max_chan_time(psoc,
5359 						  &neighbor_scan_max_chan_time);
5360 	ucfg_mlme_get_neighbor_scan_min_chan_time(psoc,
5361 						  &neighbor_scan_min_chan_time);
5362 	wifi_pos_set_dwell_time_min(psoc, neighbor_scan_min_chan_time);
5363 	wifi_pos_set_dwell_time_max(psoc, neighbor_scan_max_chan_time);
5364 }
5365 #else
hdd_activate_wifi_pos(struct hdd_context * hdd_ctx)5366 static int hdd_activate_wifi_pos(struct hdd_context *hdd_ctx)
5367 {
5368 	return oem_activate_service(hdd_ctx);
5369 }
5370 
hdd_deactivate_wifi_pos(void)5371 static int hdd_deactivate_wifi_pos(void)
5372 {
5373 	return oem_deactivate_service();
5374 }
5375 
hdd_populate_wifi_pos_cfg(struct hdd_context * hdd_ctx)5376 static void hdd_populate_wifi_pos_cfg(struct hdd_context *hdd_ctx)
5377 {
5378 }
5379 #endif
5380 
5381 /**
5382  * __hdd_open() - HDD Open function
5383  * @dev:	Pointer to net_device structure
5384  *
5385  * This is called in response to ifconfig up
5386  *
5387  * Return: 0 for success; non-zero for failure
5388  */
__hdd_open(struct net_device * dev)5389 static int __hdd_open(struct net_device *dev)
5390 {
5391 	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
5392 	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
5393 	int ret;
5394 	struct wlan_hdd_link_info *link_info = adapter->deflink;
5395 
5396 	hdd_enter_dev(dev);
5397 
5398 	qdf_mtrace(QDF_MODULE_ID_HDD, QDF_MODULE_ID_HDD,
5399 		   TRACE_CODE_HDD_OPEN_REQUEST,
5400 		   link_info->vdev_id, adapter->device_mode);
5401 
5402 	/* Nothing to be done if device is unloading */
5403 	if (cds_is_driver_unloading()) {
5404 		hdd_err("Driver is unloading can not open the hdd");
5405 		return -EBUSY;
5406 	}
5407 
5408 	if (cds_is_driver_recovering()) {
5409 		hdd_err("WLAN is currently recovering; Please try again.");
5410 		return -EBUSY;
5411 	}
5412 
5413 	/*
5414 	 * This scenario can be hit in cases where in the wlan driver after
5415 	 * registering the netdevices and there is a failure in driver
5416 	 * initialization. So return error gracefully because the netdevices
5417 	 * will be de-registered as part of the load failure.
5418 	 */
5419 
5420 	if (!cds_is_driver_loaded()) {
5421 		hdd_err("Failed to start the wlan driver!!");
5422 		return -EIO;
5423 	}
5424 
5425 	ret = wlan_hdd_validate_context(hdd_ctx);
5426 	if (ret) {
5427 		hdd_err("Can't start WLAN module, WiFi Disabled");
5428 		return ret;
5429 	}
5430 
5431 	ret = hdd_trigger_psoc_idle_restart(hdd_ctx);
5432 	if (ret) {
5433 		hdd_err("Failed to start WLAN modules return");
5434 		return ret;
5435 	}
5436 
5437 	if (!test_bit(SME_SESSION_OPENED, &link_info->link_flags)) {
5438 		ret = hdd_start_adapter(adapter, true);
5439 		if (ret) {
5440 			hdd_err("Failed to start adapter :%d",
5441 				adapter->device_mode);
5442 			return ret;
5443 		}
5444 	}
5445 
5446 	set_bit(DEVICE_IFACE_OPENED, &adapter->event_flags);
5447 	if (hdd_cm_is_vdev_associated(link_info)) {
5448 		hdd_debug("Enabling Tx Queues");
5449 		/* Enable TX queues only when we are connected */
5450 		wlan_hdd_netif_queue_control(adapter,
5451 					     WLAN_START_ALL_NETIF_QUEUE,
5452 					     WLAN_CONTROL_PATH);
5453 	}
5454 
5455 	/* Enable carrier and transmit queues for NDI */
5456 	if (WLAN_HDD_IS_NDI(adapter)) {
5457 		hdd_debug("Enabling Tx Queues");
5458 		wlan_hdd_netif_queue_control(adapter,
5459 			WLAN_START_ALL_NETIF_QUEUE_N_CARRIER,
5460 			WLAN_CONTROL_PATH);
5461 	}
5462 
5463 	hdd_populate_wifi_pos_cfg(hdd_ctx);
5464 	hdd_lpass_notify_start(link_info);
5465 
5466 	if (ucfg_pkt_capture_get_mode(hdd_ctx->psoc) !=
5467 				      PACKET_CAPTURE_MODE_DISABLE)
5468 		hdd_map_monitor_interface_vdev(adapter);
5469 
5470 	return 0;
5471 }
5472 
5473 /**
5474  * hdd_open() - Wrapper function for __hdd_open to protect it from SSR
5475  * @net_dev: Pointer to net_device structure
5476  *
5477  * This is called in response to ifconfig up
5478  *
5479  * Return: 0 for success; non-zero for failure
5480  */
hdd_open(struct net_device * net_dev)5481 static int hdd_open(struct net_device *net_dev)
5482 {
5483 	int errno;
5484 	struct osif_vdev_sync *vdev_sync;
5485 
5486 	errno = osif_vdev_sync_trans_start(net_dev, &vdev_sync);
5487 	if (errno)
5488 		return errno;
5489 
5490 	errno = __hdd_open(net_dev);
5491 	if (!errno)
5492 		osif_vdev_cache_command(vdev_sync, NO_COMMAND);
5493 
5494 	osif_vdev_sync_trans_stop(vdev_sync);
5495 
5496 	return errno;
5497 }
5498 
hdd_stop_no_trans(struct net_device * dev)5499 int hdd_stop_no_trans(struct net_device *dev)
5500 {
5501 	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
5502 	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
5503 	int ret;
5504 	mac_handle_t mac_handle;
5505 
5506 	hdd_enter_dev(dev);
5507 
5508 	qdf_mtrace(QDF_MODULE_ID_HDD, QDF_MODULE_ID_HDD,
5509 		   TRACE_CODE_HDD_STOP_REQUEST,
5510 		   adapter->deflink->vdev_id, adapter->device_mode);
5511 
5512 	ret = wlan_hdd_validate_context(hdd_ctx);
5513 	if (ret)
5514 		return ret;
5515 
5516 	/* Nothing to be done if the interface is not opened */
5517 	if (false == test_bit(DEVICE_IFACE_OPENED, &adapter->event_flags)) {
5518 		hdd_err("NETDEV Interface is not OPENED");
5519 		return -ENODEV;
5520 	}
5521 
5522 	mac_handle = hdd_ctx->mac_handle;
5523 
5524 	if (!wlan_hdd_is_session_type_monitor(adapter->device_mode) &&
5525 	    adapter->device_mode != QDF_FTM_MODE) {
5526 		hdd_debug("Disabling Auto Power save timer");
5527 		sme_ps_disable_auto_ps_timer(
5528 			mac_handle,
5529 			adapter->deflink->vdev_id);
5530 	}
5531 
5532 	/*
5533 	 * Disable TX on the interface, after this hard_start_xmit() will not
5534 	 * be called on that interface
5535 	 */
5536 	hdd_debug("Disabling queues, adapter device mode: %s(%d)",
5537 		  qdf_opmode_str(adapter->device_mode), adapter->device_mode);
5538 
5539 	wlan_hdd_netif_queue_control(adapter,
5540 				     WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER,
5541 				     WLAN_CONTROL_PATH);
5542 
5543 	if (adapter->device_mode == QDF_STA_MODE)
5544 		hdd_lpass_notify_stop(hdd_ctx);
5545 
5546 	/*
5547 	 * NAN data interface is different in some sense. The traffic on NDI is
5548 	 * bursty in nature and depends on the need to transfer. The service
5549 	 * layer may down the interface after the usage and up again when
5550 	 * required. In some sense, the NDI is expected to be available
5551 	 * (like SAP) iface until NDI delete request is issued by the service
5552 	 * layer. Skip BSS termination and adapter deletion for NAN Data
5553 	 * interface (NDI).
5554 	 */
5555 	if (WLAN_HDD_IS_NDI(adapter))
5556 		goto reset_iface_opened;
5557 
5558 	/*
5559 	 * The interface is marked as down for outside world (aka kernel)
5560 	 * But the driver is pretty much alive inside. The driver needs to
5561 	 * tear down the existing connection on the netdev (session)
5562 	 * cleanup the data pipes and wait until the control plane is stabilized
5563 	 * for this interface. The call also needs to wait until the above
5564 	 * mentioned actions are completed before returning to the caller.
5565 	 * Notice that hdd_stop_adapter is requested not to close the session
5566 	 * That is intentional to be able to scan if it is a STA/P2P interface
5567 	 */
5568 	hdd_stop_adapter(hdd_ctx, adapter);
5569 
5570 	/* DeInit the adapter. This ensures datapath cleanup as well */
5571 	hdd_deinit_adapter(hdd_ctx, adapter, true);
5572 
5573 reset_iface_opened:
5574 	/* Make sure the interface is marked as closed */
5575 	clear_bit(DEVICE_IFACE_OPENED, &adapter->event_flags);
5576 	if (!hdd_is_any_interface_open(hdd_ctx))
5577 		hdd_psoc_idle_timer_start(hdd_ctx);
5578 	hdd_exit();
5579 
5580 	return 0;
5581 }
5582 
5583 /**
5584  * hdd_stop() - Wrapper function for __hdd_stop to protect it from SSR
5585  * @net_dev: pointer to net_device structure
5586  *
5587  * This is called in response to ifconfig down
5588  *
5589  * Return: 0 for success and error number for failure
5590  */
hdd_stop(struct net_device * net_dev)5591 static int hdd_stop(struct net_device *net_dev)
5592 {
5593 	int errno;
5594 	struct osif_vdev_sync *vdev_sync;
5595 
5596 	errno = osif_vdev_sync_trans_start(net_dev, &vdev_sync);
5597 	if (errno) {
5598 		if (vdev_sync)
5599 			osif_vdev_cache_command(vdev_sync, INTERFACE_DOWN);
5600 		return errno;
5601 	}
5602 
5603 	errno = hdd_stop_no_trans(net_dev);
5604 
5605 	osif_vdev_sync_trans_stop(vdev_sync);
5606 
5607 	return errno;
5608 }
5609 
5610 /**
5611  * hdd_uninit() - HDD uninit function
5612  * @dev: Pointer to net_device structure
5613  *
5614  * This is called during the netdev unregister to uninitialize all data
5615  * associated with the device
5616  *
5617  * This function must be protected by a transition
5618  *
5619  * Return: None
5620  */
hdd_uninit(struct net_device * dev)5621 static void hdd_uninit(struct net_device *dev)
5622 {
5623 	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
5624 	struct hdd_context *hdd_ctx;
5625 
5626 	hdd_enter_dev(dev);
5627 
5628 	if (adapter->magic != WLAN_HDD_ADAPTER_MAGIC) {
5629 		hdd_err("Invalid magic");
5630 		goto exit;
5631 	}
5632 
5633 	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
5634 	if (!hdd_ctx) {
5635 		hdd_err("NULL hdd_ctx");
5636 		goto exit;
5637 	}
5638 
5639 	if (dev != adapter->dev)
5640 		hdd_err("Invalid device reference");
5641 
5642 	hdd_deinit_adapter(hdd_ctx, adapter, true);
5643 
5644 	/* after uninit our adapter structure will no longer be valid */
5645 	adapter->magic = 0;
5646 
5647 exit:
5648 	hdd_exit();
5649 }
5650 
hdd_open_cesium_nl_sock(void)5651 static int hdd_open_cesium_nl_sock(void)
5652 {
5653 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
5654 	struct netlink_kernel_cfg cfg = {
5655 		.groups = WLAN_NLINK_MCAST_GRP_ID,
5656 		.input = NULL
5657 	};
5658 #endif
5659 	int ret = 0;
5660 
5661 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
5662 	cesium_nl_srv_sock = netlink_kernel_create(&init_net, WLAN_NLINK_CESIUM,
5663 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 7, 0))
5664 						   THIS_MODULE,
5665 #endif
5666 						   &cfg);
5667 #else
5668 	cesium_nl_srv_sock = netlink_kernel_create(&init_net, WLAN_NLINK_CESIUM,
5669 						   WLAN_NLINK_MCAST_GRP_ID,
5670 						   NULL, NULL, THIS_MODULE);
5671 #endif
5672 
5673 	if (!cesium_nl_srv_sock) {
5674 		hdd_err("NLINK:  cesium netlink_kernel_create failed");
5675 		ret = -ECONNREFUSED;
5676 	}
5677 
5678 	return ret;
5679 }
5680 
hdd_close_cesium_nl_sock(void)5681 static void hdd_close_cesium_nl_sock(void)
5682 {
5683 	if (cesium_nl_srv_sock) {
5684 		netlink_kernel_release(cesium_nl_srv_sock);
5685 		cesium_nl_srv_sock = NULL;
5686 	}
5687 }
5688 
hdd_update_dynamic_mac(struct hdd_context * hdd_ctx,struct qdf_mac_addr * curr_mac_addr,struct qdf_mac_addr * new_mac_addr)5689 void hdd_update_dynamic_mac(struct hdd_context *hdd_ctx,
5690 			    struct qdf_mac_addr *curr_mac_addr,
5691 			    struct qdf_mac_addr *new_mac_addr)
5692 {
5693 	uint8_t i;
5694 
5695 	hdd_enter();
5696 
5697 	for (i = 0; i < QDF_MAX_CONCURRENCY_PERSONA; i++) {
5698 		if (!qdf_mem_cmp(
5699 			curr_mac_addr->bytes,
5700 			&hdd_ctx->dynamic_mac_list[i].dynamic_mac.bytes[0],
5701 				 sizeof(struct qdf_mac_addr))) {
5702 			qdf_mem_copy(&hdd_ctx->dynamic_mac_list[i].dynamic_mac,
5703 				     new_mac_addr->bytes,
5704 				     sizeof(struct qdf_mac_addr));
5705 			break;
5706 		}
5707 	}
5708 
5709 	hdd_exit();
5710 }
5711 
5712 #if defined(WLAN_FEATURE_11BE_MLO) && defined(CFG80211_11BE_BASIC) && \
5713 	!defined(WLAN_HDD_MULTI_VDEV_SINGLE_NDEV)
hdd_set_mld_address(struct hdd_adapter * adapter,const struct qdf_mac_addr * mac_addr)5714 void hdd_set_mld_address(struct hdd_adapter *adapter,
5715 			 const struct qdf_mac_addr *mac_addr)
5716 {
5717 	int i;
5718 	bool eht_capab;
5719 	struct hdd_adapter *link_adapter;
5720 	struct hdd_mlo_adapter_info *mlo_adapter_info;
5721 
5722 	ucfg_psoc_mlme_get_11be_capab(adapter->hdd_ctx->psoc, &eht_capab);
5723 	if (adapter->mlo_adapter_info.is_ml_adapter && eht_capab) {
5724 		mlo_adapter_info = &adapter->mlo_adapter_info;
5725 		for (i = 0; i < WLAN_MAX_MLD; i++) {
5726 			link_adapter = mlo_adapter_info->link_adapter[i];
5727 			if (link_adapter)
5728 				qdf_copy_macaddr(&link_adapter->mld_addr,
5729 						 mac_addr);
5730 		}
5731 		qdf_copy_macaddr(&adapter->mld_addr, mac_addr);
5732 	}
5733 }
5734 
5735 /**
5736  * hdd_get_netdev_by_vdev_mac() - Get Netdev based on MAC
5737  * @mac_addr: Vdev MAC address
5738  *
5739  * Get netdev from adapter based upon Vdev MAC address.
5740  *
5741  * Return: netdev pointer.
5742  */
5743 static qdf_netdev_t
hdd_get_netdev_by_vdev_mac(struct qdf_mac_addr * mac_addr)5744 hdd_get_netdev_by_vdev_mac(struct qdf_mac_addr *mac_addr)
5745 {
5746 	struct hdd_context *hdd_ctx;
5747 	struct hdd_adapter *adapter;
5748 	struct hdd_adapter *ml_adapter;
5749 
5750 	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
5751 	if (!hdd_ctx) {
5752 		hdd_err("Invalid HDD context");
5753 		return NULL;
5754 	}
5755 
5756 	adapter = hdd_get_adapter_by_macaddr(hdd_ctx, mac_addr->bytes);
5757 	if (!adapter) {
5758 		hdd_err("Adapter not foud for MAC " QDF_MAC_ADDR_FMT "",
5759 			QDF_MAC_ADDR_REF(mac_addr->bytes));
5760 		return NULL;
5761 	}
5762 
5763 	if (adapter->mlo_adapter_info.is_link_adapter &&
5764 	    adapter->mlo_adapter_info.associate_with_ml_adapter) {
5765 		ml_adapter = adapter->mlo_adapter_info.ml_adapter;
5766 		adapter =  ml_adapter;
5767 	}
5768 
5769 	return adapter->dev;
5770 }
5771 #else
5772 static qdf_netdev_t
hdd_get_netdev_by_vdev_mac(struct qdf_mac_addr * mac_addr)5773 hdd_get_netdev_by_vdev_mac(struct qdf_mac_addr *mac_addr)
5774 {
5775 	struct hdd_context *hdd_ctx;
5776 	struct hdd_adapter *adapter;
5777 
5778 	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
5779 	if (!hdd_ctx) {
5780 		hdd_err("Invalid HDD context");
5781 		return NULL;
5782 	}
5783 
5784 	adapter = hdd_get_adapter_by_macaddr(hdd_ctx, mac_addr->bytes);
5785 	if (!adapter) {
5786 		hdd_err("Adapter not foud for MAC " QDF_MAC_ADDR_FMT "",
5787 			QDF_MAC_ADDR_REF(mac_addr->bytes));
5788 		return NULL;
5789 	}
5790 
5791 	return adapter->dev;
5792 }
5793 #endif
5794 
5795 #ifdef WLAN_FEATURE_DYNAMIC_MAC_ADDR_UPDATE
5796 #if defined(WLAN_FEATURE_11BE_MLO) && defined(CFG80211_11BE_BASIC) && \
5797 	!defined(WLAN_HDD_MULTI_VDEV_SINGLE_NDEV)
hdd_update_set_mac_addr_req_ctx(struct hdd_adapter * adapter,void * req_ctx)5798 static void hdd_update_set_mac_addr_req_ctx(struct hdd_adapter *adapter,
5799 					    void *req_ctx)
5800 {
5801 	adapter->set_mac_addr_req_ctx = req_ctx;
5802 	if (adapter->mlo_adapter_info.associate_with_ml_adapter)
5803 		adapter->mlo_adapter_info.ml_adapter->set_mac_addr_req_ctx =
5804 									req_ctx;
5805 }
5806 #else
hdd_update_set_mac_addr_req_ctx(struct hdd_adapter * adapter,void * req_ctx)5807 static void hdd_update_set_mac_addr_req_ctx(struct hdd_adapter *adapter,
5808 					    void *req_ctx)
5809 {
5810 	adapter->set_mac_addr_req_ctx = req_ctx;
5811 }
5812 #endif
5813 
5814 /**
5815  * hdd_is_dynamic_set_mac_addr_supported() - API to check dynamic MAC address
5816  *				             update is supported or not
5817  * @hdd_ctx: Pointer to the HDD context
5818  *
5819  * Return: true or false
5820  */
5821 static inline bool
hdd_is_dynamic_set_mac_addr_supported(struct hdd_context * hdd_ctx)5822 hdd_is_dynamic_set_mac_addr_supported(struct hdd_context *hdd_ctx)
5823 {
5824 	return hdd_ctx->is_vdev_macaddr_dynamic_update_supported;
5825 }
5826 
hdd_is_dynamic_set_mac_addr_allowed(struct hdd_adapter * adapter)5827 bool hdd_is_dynamic_set_mac_addr_allowed(struct hdd_adapter *adapter)
5828 {
5829 	if (!adapter->deflink->vdev) {
5830 		hdd_err("VDEV is NULL");
5831 		return false;
5832 	}
5833 
5834 	if (!hdd_is_dynamic_set_mac_addr_supported(adapter->hdd_ctx)) {
5835 		hdd_info_rl("On iface up, set mac address change isn't supported");
5836 		return false;
5837 	}
5838 
5839 	switch (adapter->device_mode) {
5840 	case QDF_STA_MODE:
5841 		if (!cm_is_vdev_disconnected(adapter->deflink->vdev)) {
5842 			hdd_info_rl("VDEV is not in disconnected state, set mac address isn't supported");
5843 			return false;
5844 		}
5845 		return true;
5846 	case QDF_P2P_DEVICE_MODE:
5847 		return ucfg_is_p2p_device_dynamic_set_mac_addr_supported(adapter->hdd_ctx->psoc);
5848 	case QDF_SAP_MODE:
5849 		if (test_bit(SOFTAP_BSS_STARTED,
5850 			     &adapter->deflink->link_flags)) {
5851 			hdd_info_rl("SAP is in up state, set mac address isn't supported");
5852 			return false;
5853 		} else {
5854 			return true;
5855 		}
5856 	default:
5857 		hdd_info_rl("Dynamic set mac address isn't supported for opmode:%d",
5858 			adapter->device_mode);
5859 		return false;
5860 	}
5861 }
5862 
hdd_dynamic_mac_address_set(struct wlan_hdd_link_info * link_info,struct qdf_mac_addr mac_addr,struct qdf_mac_addr mld_addr,bool update_self_peer)5863 int hdd_dynamic_mac_address_set(struct wlan_hdd_link_info *link_info,
5864 				struct qdf_mac_addr mac_addr,
5865 				struct qdf_mac_addr mld_addr,
5866 				bool update_self_peer)
5867 {
5868 	int ret;
5869 	void *cookie;
5870 	bool update_mld_addr;
5871 	uint32_t fw_resp_status;
5872 	QDF_STATUS status = QDF_STATUS_SUCCESS;
5873 	struct osif_request *request;
5874 	struct wlan_objmgr_vdev *vdev;
5875 	struct hdd_adapter *adapter = link_info->adapter;
5876 	struct hdd_context *hdd_ctx = adapter->hdd_ctx;
5877 	struct mac_addr_set_priv *priv;
5878 	static const struct osif_request_params params = {
5879 		.priv_size = sizeof(*priv),
5880 		.timeout_ms = WLAN_SET_MAC_ADDR_TIMEOUT
5881 	};
5882 
5883 	vdev = hdd_objmgr_get_vdev_by_user(link_info, WLAN_OSIF_ID);
5884 	if (!vdev)
5885 		return -EINVAL;
5886 
5887 	if (wlan_vdev_mlme_get_opmode(vdev) != QDF_P2P_DEVICE_MODE) {
5888 		status = ucfg_vdev_mgr_cdp_vdev_detach(vdev);
5889 		if (QDF_IS_STATUS_ERROR(status)) {
5890 			hdd_err("Failed to detach CDP vdev. Status:%d", status);
5891 			ret = qdf_status_to_os_return(status);
5892 			goto vdev_ref;
5893 		}
5894 	}
5895 	request = osif_request_alloc(&params);
5896 	if (!request) {
5897 		hdd_err("request alloc fail");
5898 		status = QDF_STATUS_E_NOMEM;
5899 		ret = -ENOMEM;
5900 		goto status_ret;
5901 	}
5902 
5903 	/* Host should hold a wake lock until the FW event response is received
5904 	 * the WMI event would not be a wake up event.
5905 	 */
5906 	qdf_runtime_pm_prevent_suspend(
5907 			&hdd_ctx->runtime_context.dyn_mac_addr_update);
5908 	hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_DYN_MAC_ADDR_UPDATE);
5909 
5910 	cookie = osif_request_cookie(request);
5911 	hdd_update_set_mac_addr_req_ctx(adapter, cookie);
5912 
5913 	priv = (struct mac_addr_set_priv *)osif_request_priv(request);
5914 
5915 	/* For p2p device mode, need send delete self peer cmd to F/W,
5916 	 * To avoid p2p new DP vdev is created before old DP vdev deleted,
5917 	 * don't create new DP vdev until both self peer delete rsp and set
5918 	 * mac addr rsp received, so initialize pending_rsp_cnt as 2.
5919 	 *
5920 	 * For other mode like STA/SAP, don't need send delete self peer cmd
5921 	 * to F/W, only need wait set mad addr rsp, so initialize
5922 	 * pending_rsp_cnt as 1.
5923 	 */
5924 	if (wlan_vdev_mlme_get_opmode(vdev) == QDF_P2P_DEVICE_MODE)
5925 		qdf_atomic_set(&priv->pending_rsp_cnt, 2);
5926 	else
5927 		qdf_atomic_set(&priv->pending_rsp_cnt, 1);
5928 
5929 	status = sme_send_set_mac_addr(mac_addr, mld_addr, vdev);
5930 	ret = qdf_status_to_os_return(status);
5931 	if (QDF_IS_STATUS_ERROR(status)) {
5932 		hdd_nofl_err("Failed to send set MAC address command. Status:%d",
5933 			     status);
5934 		osif_request_put(request);
5935 		goto status_ret;
5936 	} else {
5937 		ret = osif_request_wait_for_response(request);
5938 		if (ret) {
5939 			hdd_err("Set MAC address response timed out");
5940 		} else {
5941 			fw_resp_status = priv->fw_resp_status;
5942 			if (fw_resp_status) {
5943 				hdd_err("Set MAC address failed in FW. Status: %d",
5944 					fw_resp_status);
5945 				ret = -EAGAIN;
5946 			}
5947 		}
5948 	}
5949 
5950 	osif_request_put(request);
5951 
5952 	if (qdf_is_macaddr_zero(&mld_addr))
5953 		update_mld_addr = false;
5954 	else
5955 		update_mld_addr = true;
5956 
5957 	status = sme_update_vdev_mac_addr(vdev, mac_addr, mld_addr,
5958 					  update_self_peer, update_mld_addr,
5959 					  ret);
5960 
5961 status_ret:
5962 	if (QDF_IS_STATUS_ERROR(status)) {
5963 		ret = qdf_status_to_os_return(status);
5964 		goto allow_suspend;
5965 	} else if (!ret) {
5966 		status = ucfg_dp_update_link_mac_addr(vdev, &mac_addr, false);
5967 		if (QDF_IS_STATUS_ERROR(status)) {
5968 			ret = qdf_status_to_os_return(status);
5969 			hdd_err("DP link MAC update failed");
5970 			goto allow_suspend;
5971 		}
5972 	}
5973 	sme_vdev_set_data_tx_callback(vdev);
5974 
5975 	/* Update FW WoW pattern with new MAC address */
5976 	ucfg_pmo_del_wow_pattern(vdev);
5977 	ucfg_pmo_register_wow_default_patterns(vdev);
5978 	hdd_tx_latency_restore_config(link_info);
5979 
5980 allow_suspend:
5981 	hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DYN_MAC_ADDR_UPDATE);
5982 	qdf_runtime_pm_allow_suspend(
5983 			&hdd_ctx->runtime_context.dyn_mac_addr_update);
5984 
5985 vdev_ref:
5986 	hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_ID);
5987 
5988 	return ret;
5989 }
5990 
hdd_set_mac_addr_event_cb(uint8_t vdev_id,uint8_t status)5991 static void hdd_set_mac_addr_event_cb(uint8_t vdev_id, uint8_t status)
5992 {
5993 	struct hdd_context *hdd_ctx;
5994 	struct wlan_hdd_link_info *link_info;
5995 	struct osif_request *req;
5996 	struct mac_addr_set_priv *priv;
5997 
5998 	osif_debug("enter");
5999 	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
6000 	if (!hdd_ctx) {
6001 		hdd_err("Invalid HDD context");
6002 		return;
6003 	}
6004 
6005 	link_info = hdd_get_link_info_by_vdev(hdd_ctx, vdev_id);
6006 	if (!link_info) {
6007 		hdd_err("No adapter found for VDEV ID:%d", vdev_id);
6008 		return;
6009 	}
6010 
6011 	req = osif_request_get(link_info->adapter->set_mac_addr_req_ctx);
6012 	if (!req) {
6013 		osif_err("Obsolete request for VDEV ID:%d", vdev_id);
6014 		return;
6015 	}
6016 
6017 	priv = (struct mac_addr_set_priv *)osif_request_priv(req);
6018 
6019 	if (qdf_atomic_dec_and_test(&priv->pending_rsp_cnt)) {
6020 		priv->fw_resp_status = status;
6021 		osif_request_complete(req);
6022 	}
6023 
6024 	osif_request_put(req);
6025 }
6026 #else
6027 static inline bool
hdd_is_dynamic_set_mac_addr_supported(struct hdd_context * hdd_ctx)6028 hdd_is_dynamic_set_mac_addr_supported(struct hdd_context *hdd_ctx)
6029 {
6030 	return false;
6031 }
6032 #endif
6033 
6034 #if defined(WLAN_FEATURE_11BE_MLO) && defined(WLAN_HDD_MULTI_VDEV_SINGLE_NDEV)
6035 static QDF_STATUS
hdd_adapter_update_links_on_link_switch(struct wlan_hdd_link_info * cur_link_info,struct wlan_hdd_link_info * new_link_info)6036 hdd_adapter_update_links_on_link_switch(struct wlan_hdd_link_info *cur_link_info,
6037 					struct wlan_hdd_link_info *new_link_info)
6038 {
6039 	unsigned long link_flags;
6040 	struct wlan_objmgr_vdev *vdev;
6041 	int cur_link_idx, new_link_idx;
6042 	uint8_t cur_old_pos, cur_new_pos;
6043 	struct vdev_osif_priv *vdev_priv;
6044 	struct hdd_adapter *adapter = cur_link_info->adapter;
6045 
6046 	/* Update the new position of current and new link info
6047 	 * in the link info array.
6048 	 */
6049 	cur_link_idx = hdd_adapter_get_index_of_link_info(cur_link_info);
6050 	new_link_idx = hdd_adapter_get_index_of_link_info(new_link_info);
6051 
6052 	cur_old_pos = adapter->curr_link_info_map[cur_link_idx];
6053 	cur_new_pos = adapter->curr_link_info_map[new_link_idx];
6054 
6055 	adapter->curr_link_info_map[new_link_idx] = cur_old_pos;
6056 	adapter->curr_link_info_map[cur_link_idx] = cur_new_pos;
6057 
6058 	/* Move VDEV from current link info to new link info */
6059 	qdf_atomic_clear_bit(cur_link_idx, &adapter->active_links);
6060 	qdf_spin_lock_bh(&cur_link_info->vdev_lock);
6061 	vdev = cur_link_info->vdev;
6062 	cur_link_info->vdev = NULL;
6063 	cur_link_info->vdev_id = WLAN_INVALID_VDEV_ID;
6064 	qdf_spin_unlock_bh(&cur_link_info->vdev_lock);
6065 
6066 	qdf_spin_lock_bh(&new_link_info->vdev_lock);
6067 	new_link_info->vdev = vdev;
6068 	new_link_info->vdev_id = wlan_vdev_get_id(vdev);
6069 	qdf_spin_unlock_bh(&new_link_info->vdev_lock);
6070 	qdf_atomic_set_bit(new_link_idx, &adapter->active_links);
6071 
6072 	/* Move the link flags between current and new link info */
6073 	link_flags = new_link_info->link_flags;
6074 	new_link_info->link_flags = cur_link_info->link_flags;
6075 	cur_link_info->link_flags = link_flags;
6076 
6077 	/* Update VDEV-OSIF priv pointer to new link info */
6078 	vdev_priv = wlan_vdev_get_ospriv(new_link_info->vdev);
6079 	vdev_priv->legacy_osif_priv = new_link_info;
6080 
6081 	return QDF_STATUS_SUCCESS;
6082 }
6083 
6084 struct wlan_hdd_link_info *
hdd_get_link_info_by_ieee_link_id(struct hdd_adapter * adapter,int32_t link_id)6085 hdd_get_link_info_by_ieee_link_id(struct hdd_adapter *adapter, int32_t link_id)
6086 {
6087 	struct wlan_hdd_link_info *link_info;
6088 	struct hdd_station_ctx *sta_ctx;
6089 
6090 	if (!adapter || link_id == WLAN_INVALID_LINK_ID) {
6091 		hdd_err("NULL adapter or invalid link ID");
6092 		return NULL;
6093 	}
6094 
6095 	hdd_adapter_for_each_link_info(adapter, link_info) {
6096 		sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(link_info);
6097 		if (sta_ctx->conn_info.ieee_link_id == link_id)
6098 			return link_info;
6099 	}
6100 
6101 	return NULL;
6102 }
6103 
6104 QDF_STATUS
hdd_link_switch_vdev_mac_addr_update(int32_t ieee_old_link_id,int32_t ieee_new_link_id,uint8_t vdev_id)6105 hdd_link_switch_vdev_mac_addr_update(int32_t ieee_old_link_id,
6106 				     int32_t ieee_new_link_id, uint8_t vdev_id)
6107 {
6108 	QDF_STATUS status = QDF_STATUS_E_INVAL;
6109 	struct hdd_context *hdd_ctx;
6110 	struct hdd_adapter *adapter;
6111 	struct wlan_objmgr_vdev *vdev;
6112 	struct wlan_hdd_link_info *cur_link_info, *new_link_info;
6113 	struct hdd_station_ctx *sta_ctx;
6114 
6115 	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
6116 	if (!hdd_ctx) {
6117 		hdd_err("HDD ctx NULL");
6118 		return QDF_STATUS_E_INVAL;
6119 	}
6120 
6121 	cur_link_info = hdd_get_link_info_by_vdev(hdd_ctx, vdev_id);
6122 	if (!cur_link_info) {
6123 		hdd_err("VDEV %d not found", vdev_id);
6124 		return status;
6125 	}
6126 
6127 	vdev = hdd_objmgr_get_vdev_by_user(cur_link_info, WLAN_OSIF_ID);
6128 	if (!vdev) {
6129 		hdd_err("Invalid VDEV %d", vdev_id);
6130 		return status;
6131 	}
6132 
6133 	sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(cur_link_info);
6134 	if (sta_ctx->conn_info.ieee_link_id != ieee_old_link_id) {
6135 		hdd_err("Link id %d mismatch", sta_ctx->conn_info.ieee_link_id);
6136 		goto release_ref;
6137 	}
6138 
6139 	adapter = cur_link_info->adapter;
6140 	new_link_info = hdd_get_link_info_by_ieee_link_id(adapter,
6141 							  ieee_new_link_id);
6142 	if (!new_link_info) {
6143 		hdd_err("Link id %d not found", ieee_new_link_id);
6144 		goto release_ref;
6145 	}
6146 
6147 	status = ucfg_dp_update_link_mac_addr(vdev, &new_link_info->link_addr,
6148 					      true);
6149 	if (QDF_IS_STATUS_ERROR(status)) {
6150 		hdd_err("DP link MAC update failed");
6151 		goto release_ref;
6152 	}
6153 
6154 	status = hdd_adapter_update_links_on_link_switch(cur_link_info,
6155 							 new_link_info);
6156 	if (QDF_IS_STATUS_ERROR(status)) {
6157 		hdd_err("Failed to update adapter link info");
6158 		goto release_ref;
6159 	}
6160 
6161 	hdd_adapter_update_mlo_mgr_mac_addr(adapter);
6162 	sme_vdev_set_data_tx_callback(vdev);
6163 	ucfg_pmo_del_wow_pattern(vdev);
6164 	ucfg_pmo_register_wow_default_patterns(vdev);
6165 
6166 release_ref:
6167 	hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_ID);
6168 	return status;
6169 }
6170 #endif
6171 
6172 /**
6173  * __hdd_set_mac_address() - set the user specified mac address
6174  * @dev:	Pointer to the net device.
6175  * @addr:	Pointer to the sockaddr.
6176  *
6177  * This function sets the user specified mac address using
6178  * the command ifconfig wlanX hw ether <mac address>.
6179  *
6180  * Return: 0 for success, non zero for failure
6181  */
__hdd_set_mac_address(struct net_device * dev,void * addr)6182 static int __hdd_set_mac_address(struct net_device *dev, void *addr)
6183 {
6184 	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
6185 	struct hdd_adapter *adapter_temp;
6186 	struct hdd_context *hdd_ctx;
6187 	struct sockaddr *psta_mac_addr = addr;
6188 	QDF_STATUS qdf_ret_status = QDF_STATUS_SUCCESS;
6189 	int ret;
6190 	struct qdf_mac_addr mac_addr;
6191 	bool net_if_running = netif_running(dev);
6192 
6193 	hdd_enter_dev(dev);
6194 
6195 	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
6196 	ret = wlan_hdd_validate_context(hdd_ctx);
6197 	if (0 != ret)
6198 		return ret;
6199 
6200 	if (net_if_running) {
6201 		if (!hdd_is_dynamic_set_mac_addr_allowed(adapter))
6202 			return -ENOTSUPP;
6203 	}
6204 
6205 	qdf_mem_copy(&mac_addr, psta_mac_addr->sa_data, sizeof(mac_addr));
6206 	adapter_temp = hdd_get_adapter_by_macaddr(hdd_ctx, mac_addr.bytes);
6207 	if (adapter_temp) {
6208 		if (!qdf_str_cmp(adapter_temp->dev->name, dev->name))
6209 			return 0;
6210 		hdd_err("%s adapter exist with same address " QDF_MAC_ADDR_FMT,
6211 			adapter_temp->dev->name,
6212 			QDF_MAC_ADDR_REF(mac_addr.bytes));
6213 		return -EINVAL;
6214 	}
6215 	qdf_ret_status = wlan_hdd_validate_mac_address(&mac_addr);
6216 	if (QDF_IS_STATUS_ERROR(qdf_ret_status))
6217 		return -EINVAL;
6218 
6219 	hdd_nofl_debug("Changing MAC to "
6220 		       QDF_MAC_ADDR_FMT " of the interface %s ",
6221 		       QDF_MAC_ADDR_REF(mac_addr.bytes), dev->name);
6222 
6223 	if (net_if_running && adapter->deflink->vdev) {
6224 		ret = hdd_update_vdev_mac_address(adapter, mac_addr);
6225 		if (ret)
6226 			return ret;
6227 	}
6228 
6229 	hdd_set_mld_address(adapter, &mac_addr);
6230 
6231 	hdd_update_dynamic_mac(hdd_ctx, &adapter->mac_addr, &mac_addr);
6232 	ucfg_dp_update_intf_mac(hdd_ctx->psoc, &adapter->mac_addr, &mac_addr,
6233 				adapter->deflink->vdev);
6234 	memcpy(&adapter->mac_addr, psta_mac_addr->sa_data, ETH_ALEN);
6235 	qdf_net_update_net_device_dev_addr(dev, psta_mac_addr->sa_data,
6236 					   ETH_ALEN);
6237 
6238 	hdd_exit();
6239 	return ret;
6240 }
6241 
6242 /**
6243  * hdd_set_mac_address() - Wrapper function to protect __hdd_set_mac_address()
6244  *	function from SSR
6245  * @net_dev: pointer to net_device structure
6246  * @addr: Pointer to the sockaddr
6247  *
6248  * This function sets the user specified mac address using
6249  * the command ifconfig wlanX hw ether <mac address>.
6250  *
6251  * Return: 0 for success.
6252  */
hdd_set_mac_address(struct net_device * net_dev,void * addr)6253 static int hdd_set_mac_address(struct net_device *net_dev, void *addr)
6254 {
6255 	struct osif_vdev_sync *vdev_sync;
6256 	int errno;
6257 
6258 	errno = osif_vdev_sync_op_start(net_dev, &vdev_sync);
6259 	if (errno)
6260 		return errno;
6261 
6262 	errno = __hdd_set_mac_address(net_dev, addr);
6263 
6264 	osif_vdev_sync_op_stop(vdev_sync);
6265 
6266 	return errno;
6267 }
6268 
wlan_hdd_get_derived_intf_addr(struct hdd_context * hdd_ctx)6269 static uint8_t *wlan_hdd_get_derived_intf_addr(struct hdd_context *hdd_ctx)
6270 {
6271 	int i, j;
6272 
6273 	i = qdf_ffz(hdd_ctx->derived_intf_addr_mask);
6274 	if (i < 0 || i >= hdd_ctx->num_derived_addr)
6275 		return NULL;
6276 	qdf_atomic_set_bit(i, &hdd_ctx->derived_intf_addr_mask);
6277 	hdd_nofl_debug("Assigning MAC from derived list "QDF_MAC_ADDR_FMT,
6278 		       QDF_MAC_ADDR_REF(hdd_ctx->derived_mac_addr[i].bytes));
6279 
6280 	/* Copy the mac in dynamic mac list at first free position */
6281 	for (j = 0; j < QDF_MAX_CONCURRENCY_PERSONA; j++) {
6282 		if (qdf_is_macaddr_zero(&hdd_ctx->
6283 					dynamic_mac_list[j].dynamic_mac))
6284 			break;
6285 	}
6286 	if (j == QDF_MAX_CONCURRENCY_PERSONA) {
6287 		hdd_err("Max interfaces are up");
6288 		return NULL;
6289 	}
6290 
6291 	qdf_mem_copy(&hdd_ctx->dynamic_mac_list[j].dynamic_mac.bytes,
6292 		     &hdd_ctx->derived_mac_addr[i].bytes,
6293 		     sizeof(struct qdf_mac_addr));
6294 	hdd_ctx->dynamic_mac_list[j].is_provisioned_mac = false;
6295 	hdd_ctx->dynamic_mac_list[j].bit_position = i;
6296 
6297 	return hdd_ctx->derived_mac_addr[i].bytes;
6298 }
6299 
wlan_hdd_get_provisioned_intf_addr(struct hdd_context * hdd_ctx)6300 static uint8_t *wlan_hdd_get_provisioned_intf_addr(struct hdd_context *hdd_ctx)
6301 {
6302 	int i, j;
6303 
6304 	i = qdf_ffz(hdd_ctx->provisioned_intf_addr_mask);
6305 	if (i < 0 || i >= hdd_ctx->num_provisioned_addr)
6306 		return NULL;
6307 	qdf_atomic_set_bit(i, &hdd_ctx->provisioned_intf_addr_mask);
6308 	hdd_debug("Assigning MAC from provisioned list "QDF_MAC_ADDR_FMT,
6309 		  QDF_MAC_ADDR_REF(hdd_ctx->provisioned_mac_addr[i].bytes));
6310 
6311 	/* Copy the mac in dynamic mac list at first free position */
6312 	for (j = 0; j < QDF_MAX_CONCURRENCY_PERSONA; j++) {
6313 		if (qdf_is_macaddr_zero(&hdd_ctx->
6314 					dynamic_mac_list[j].dynamic_mac))
6315 			break;
6316 	}
6317 	if (j == QDF_MAX_CONCURRENCY_PERSONA) {
6318 		hdd_err("Max interfaces are up");
6319 		return NULL;
6320 	}
6321 
6322 	qdf_mem_copy(&hdd_ctx->dynamic_mac_list[j].dynamic_mac.bytes,
6323 		     &hdd_ctx->provisioned_mac_addr[i].bytes,
6324 		     sizeof(struct qdf_mac_addr));
6325 	hdd_ctx->dynamic_mac_list[j].is_provisioned_mac = true;
6326 	hdd_ctx->dynamic_mac_list[j].bit_position = i;
6327 	return hdd_ctx->provisioned_mac_addr[i].bytes;
6328 }
6329 
wlan_hdd_get_intf_addr(struct hdd_context * hdd_ctx,enum QDF_OPMODE interface_type)6330 uint8_t *wlan_hdd_get_intf_addr(struct hdd_context *hdd_ctx,
6331 				enum QDF_OPMODE interface_type)
6332 {
6333 	uint8_t *mac_addr = NULL;
6334 
6335 	if (qdf_atomic_test_bit(interface_type,
6336 				(unsigned long *)
6337 				(&hdd_ctx->config->provisioned_intf_pool)))
6338 		mac_addr = wlan_hdd_get_provisioned_intf_addr(hdd_ctx);
6339 
6340 	if ((!mac_addr) &&
6341 	    (qdf_atomic_test_bit(interface_type,
6342 				 (unsigned long *)
6343 				 (&hdd_ctx->config->derived_intf_pool))))
6344 		mac_addr = wlan_hdd_get_derived_intf_addr(hdd_ctx);
6345 
6346 	if (!mac_addr)
6347 		hdd_err("MAC is not available in both the lists");
6348 	return mac_addr;
6349 }
6350 
wlan_hdd_release_intf_addr(struct hdd_context * hdd_ctx,uint8_t * releaseAddr)6351 void wlan_hdd_release_intf_addr(struct hdd_context *hdd_ctx,
6352 				uint8_t *releaseAddr)
6353 {
6354 	int i;
6355 	int mac_pos_in_mask;
6356 
6357 	for (i = 0; i < QDF_MAX_CONCURRENCY_PERSONA; i++) {
6358 		if (!memcmp(releaseAddr,
6359 		    hdd_ctx->dynamic_mac_list[i].dynamic_mac.bytes,
6360 		    QDF_MAC_ADDR_SIZE)) {
6361 			mac_pos_in_mask =
6362 				hdd_ctx->dynamic_mac_list[i].bit_position;
6363 			if (hdd_ctx->dynamic_mac_list[i].is_provisioned_mac) {
6364 				qdf_atomic_clear_bit(
6365 						mac_pos_in_mask,
6366 						&hdd_ctx->
6367 						   provisioned_intf_addr_mask);
6368 				hdd_debug("Releasing MAC from provisioned list");
6369 				hdd_debug(
6370 					  QDF_MAC_ADDR_FMT,
6371 					  QDF_MAC_ADDR_REF(releaseAddr));
6372 			} else {
6373 				qdf_atomic_clear_bit(
6374 						mac_pos_in_mask, &hdd_ctx->
6375 						derived_intf_addr_mask);
6376 				hdd_debug("Releasing MAC from derived list");
6377 				hdd_debug(QDF_MAC_ADDR_FMT,
6378 					  QDF_MAC_ADDR_REF(releaseAddr));
6379 			}
6380 			qdf_zero_macaddr(&hdd_ctx->
6381 					    dynamic_mac_list[i].dynamic_mac);
6382 			hdd_ctx->dynamic_mac_list[i].is_provisioned_mac =
6383 									false;
6384 			hdd_ctx->dynamic_mac_list[i].bit_position = 0;
6385 			break;
6386 		}
6387 
6388 	}
6389 	if (i == QDF_MAX_CONCURRENCY_PERSONA)
6390 		hdd_debug("Releasing non existing MAC " QDF_MAC_ADDR_FMT,
6391 			  QDF_MAC_ADDR_REF(releaseAddr));
6392 }
6393 
6394 /**
6395  * hdd_set_derived_multicast_list(): Add derived peer multicast address list in
6396  *                                   multicast list request to the FW
6397  * @psoc: Pointer to psoc
6398  * @adapter: Pointer to hdd adapter
6399  * @mc_list_request: Multicast list request to the FW
6400  * @mc_count: number of multicast addresses received from the kernel
6401  *
6402  * Return: None
6403  */
6404 static void
hdd_set_derived_multicast_list(struct wlan_objmgr_psoc * psoc,struct hdd_adapter * adapter,struct pmo_mc_addr_list_params * mc_list_request,int * mc_count)6405 hdd_set_derived_multicast_list(struct wlan_objmgr_psoc *psoc,
6406 			       struct hdd_adapter *adapter,
6407 			       struct pmo_mc_addr_list_params *mc_list_request,
6408 			       int *mc_count)
6409 {
6410 	int i = 0, j = 0, list_count = *mc_count;
6411 	struct qdf_mac_addr *peer_mc_addr_list = NULL;
6412 	uint8_t  driver_mc_cnt = 0;
6413 	uint32_t max_ndp_sessions = 0;
6414 
6415 	cfg_nan_get_ndp_max_sessions(psoc, &max_ndp_sessions);
6416 
6417 	ucfg_nan_get_peer_mc_list(adapter->deflink->vdev, &peer_mc_addr_list);
6418 
6419 	for (j = 0; j < max_ndp_sessions; j++) {
6420 		for (i = 0; i < list_count; i++) {
6421 			if (qdf_is_macaddr_zero(&peer_mc_addr_list[j]) ||
6422 			    qdf_is_macaddr_equal(&mc_list_request->mc_addr[i],
6423 						 &peer_mc_addr_list[j]))
6424 				break;
6425 		}
6426 		if (i == list_count) {
6427 			qdf_mem_copy(
6428 			   &(mc_list_request->mc_addr[list_count +
6429 						driver_mc_cnt].bytes),
6430 			   peer_mc_addr_list[j].bytes, ETH_ALEN);
6431 			hdd_debug("mlist[%d] = " QDF_MAC_ADDR_FMT,
6432 				  list_count + driver_mc_cnt,
6433 				  QDF_MAC_ADDR_REF(
6434 					mc_list_request->mc_addr[list_count +
6435 					driver_mc_cnt].bytes));
6436 			driver_mc_cnt++;
6437 		}
6438 	}
6439 	*mc_count += driver_mc_cnt;
6440 }
6441 
6442 /**
6443  * __hdd_set_multicast_list() - set the multicast address list
6444  * @dev: Pointer to the WLAN device.
6445  *
6446  * This function sets the multicast address list.
6447  *
6448  * Return: None
6449  */
__hdd_set_multicast_list(struct net_device * dev)6450 static void __hdd_set_multicast_list(struct net_device *dev)
6451 {
6452 	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
6453 	int i = 0, errno;
6454 	struct netdev_hw_addr *ha;
6455 	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
6456 	struct pmo_mc_addr_list_params *mc_list_request = NULL;
6457 	struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc;
6458 	int mc_count = 0;
6459 
6460 	if (hdd_ctx->hdd_wlan_suspended) {
6461 		hdd_err_rl("Device is system suspended");
6462 		return;
6463 	}
6464 
6465 	hdd_enter_dev(dev);
6466 	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam())
6467 		return;
6468 
6469 	errno = wlan_hdd_validate_context(hdd_ctx);
6470 	if (errno)
6471 		return;
6472 
6473 	errno = hdd_validate_adapter(adapter);
6474 	if (errno)
6475 		return;
6476 
6477 	if (hdd_ctx->driver_status == DRIVER_MODULES_CLOSED) {
6478 		hdd_debug("Driver module is closed");
6479 		return;
6480 	}
6481 
6482 	mc_list_request = qdf_mem_malloc(sizeof(*mc_list_request));
6483 	if (!mc_list_request)
6484 		return;
6485 
6486 	qdf_spin_lock_bh(&adapter->mc_list_lock);
6487 	/* Delete already configured multicast address list */
6488 	if (adapter->mc_addr_list.mc_cnt > 0)
6489 		hdd_disable_and_flush_mc_addr_list(adapter,
6490 			pmo_mc_list_change_notify);
6491 
6492 	if (dev->flags & IFF_ALLMULTI) {
6493 		hdd_debug("allow all multicast frames");
6494 		hdd_disable_and_flush_mc_addr_list(adapter,
6495 			pmo_mc_list_change_notify);
6496 	} else {
6497 		mc_count = netdev_mc_count(dev);
6498 		if (mc_count > ucfg_pmo_max_mc_addr_supported(psoc)) {
6499 			hdd_debug("Exceeded max MC filter addresses (%d). Allowing all MC frames by disabling MC address filtering",
6500 				  ucfg_pmo_max_mc_addr_supported(psoc));
6501 			hdd_disable_and_flush_mc_addr_list(adapter,
6502 				pmo_mc_list_change_notify);
6503 			adapter->mc_addr_list.mc_cnt = 0;
6504 			goto free_req;
6505 		}
6506 		netdev_for_each_mc_addr(ha, dev) {
6507 			if (i == mc_count)
6508 				break;
6509 			memset(&(mc_list_request->mc_addr[i].bytes),
6510 				0, ETH_ALEN);
6511 			memcpy(&(mc_list_request->mc_addr[i].bytes),
6512 				ha->addr, ETH_ALEN);
6513 			hdd_debug("mlist[%d] = "QDF_MAC_ADDR_FMT, i,
6514 				  QDF_MAC_ADDR_REF(mc_list_request->mc_addr[i].bytes));
6515 			i++;
6516 		}
6517 
6518 		if (adapter->device_mode == QDF_NDI_MODE)
6519 			hdd_set_derived_multicast_list(psoc, adapter,
6520 						       mc_list_request,
6521 						       &mc_count);
6522 	}
6523 
6524 	adapter->mc_addr_list.mc_cnt = mc_count;
6525 	mc_list_request->psoc = psoc;
6526 	mc_list_request->vdev_id = adapter->deflink->vdev_id;
6527 	mc_list_request->count = mc_count;
6528 
6529 	errno = hdd_cache_mc_addr_list(mc_list_request);
6530 	if (errno) {
6531 		hdd_debug("Failed to cache MC address list for vdev %u; errno:%d",
6532 			  adapter->deflink->vdev_id, errno);
6533 		goto free_req;
6534 	}
6535 
6536 	hdd_enable_mc_addr_filtering(adapter, pmo_mc_list_change_notify);
6537 
6538 free_req:
6539 	qdf_spin_unlock_bh(&adapter->mc_list_lock);
6540 	qdf_mem_free(mc_list_request);
6541 }
6542 
6543 /**
6544  * hdd_set_multicast_list() - SSR wrapper function for __hdd_set_multicast_list
6545  * @net_dev: pointer to net_device
6546  *
6547  * Return: none
6548  */
hdd_set_multicast_list(struct net_device * net_dev)6549 static void hdd_set_multicast_list(struct net_device *net_dev)
6550 {
6551 	struct osif_vdev_sync *vdev_sync;
6552 
6553 	if (osif_vdev_sync_op_start(net_dev, &vdev_sync))
6554 		return;
6555 
6556 	__hdd_set_multicast_list(net_dev);
6557 
6558 	osif_vdev_sync_op_stop(vdev_sync);
6559 }
6560 
hdd_update_multicast_list(struct wlan_objmgr_vdev * vdev)6561 void hdd_update_multicast_list(struct wlan_objmgr_vdev *vdev)
6562 {
6563 	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
6564 	struct wlan_hdd_link_info *link_info;
6565 	struct hdd_adapter *adapter;
6566 	uint8_t vdev_id = wlan_vdev_get_id(vdev);
6567 	struct net_device *net_dev;
6568 
6569 	if (!hdd_ctx) {
6570 		hdd_err("hdd_ctx is null");
6571 		return;
6572 	}
6573 
6574 	link_info = hdd_get_link_info_by_vdev(hdd_ctx, vdev_id);
6575 	if (!link_info) {
6576 		hdd_err("adapter is null for vdev_id %d", vdev_id);
6577 		return;
6578 	}
6579 
6580 	adapter = link_info->adapter;
6581 	if (!adapter) {
6582 		hdd_err("adapter is null for vdev_id %d", vdev_id);
6583 		return;
6584 	}
6585 
6586 	net_dev = adapter->dev;
6587 	if (!net_dev) {
6588 		hdd_err("netdev is null");
6589 		return;
6590 	}
6591 
6592 	__hdd_set_multicast_list(net_dev);
6593 }
6594 
6595 #ifdef WLAN_FEATURE_TSF_PTP
6596 static const struct ethtool_ops wlan_ethtool_ops = {
6597 	.get_ts_info = wlan_get_ts_info,
6598 };
6599 #endif
6600 
6601 /**
6602  * __hdd_fix_features - Adjust the feature flags needed to be updated
6603  * @net_dev: Handle to net_device
6604  * @features: Currently enabled feature flags
6605  *
6606  * Return: Adjusted feature flags on success, old feature on failure
6607  */
__hdd_fix_features(struct net_device * net_dev,netdev_features_t features)6608 static netdev_features_t __hdd_fix_features(struct net_device *net_dev,
6609 					    netdev_features_t features)
6610 {
6611 	netdev_features_t feature_change_req = features;
6612 	netdev_features_t feature_tso_csum;
6613 	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(net_dev);
6614 
6615 	if (!adapter->handle_feature_update) {
6616 		hdd_debug("Not triggered by hdd_netdev_update_features");
6617 		return features;
6618 	}
6619 
6620 	feature_tso_csum = hdd_get_tso_csum_feature_flags();
6621 	if (hdd_is_legacy_connection(adapter->deflink)) {
6622 		/* Disable checksum and TSO */
6623 		feature_change_req &= ~feature_tso_csum;
6624 		adapter->tso_csum_feature_enabled = 0;
6625 	} else {
6626 		/* Enable checksum and TSO */
6627 		feature_change_req |= feature_tso_csum;
6628 		adapter->tso_csum_feature_enabled = 1;
6629 	}
6630 	hdd_debug("vdev mode %d current features 0x%llx, requesting feature change 0x%llx",
6631 		  adapter->device_mode, net_dev->features,
6632 		  feature_change_req);
6633 
6634 	return feature_change_req;
6635 }
6636 
6637 /**
6638  * hdd_fix_features() - Wrapper for __hdd_fix_features to protect it from SSR
6639  * @net_dev: Pointer to net_device structure
6640  * @features: Updated features set
6641  *
6642  * Adjusts the feature request, do not update the device yet.
6643  *
6644  * Return: updated feature for success, incoming feature as is on failure
6645  */
hdd_fix_features(struct net_device * net_dev,netdev_features_t features)6646 static netdev_features_t hdd_fix_features(struct net_device *net_dev,
6647 					  netdev_features_t features)
6648 {
6649 	int errno;
6650 	int changed_features = features;
6651 	struct osif_vdev_sync *vdev_sync;
6652 
6653 	errno = osif_vdev_sync_op_start(net_dev, &vdev_sync);
6654 	if (errno)
6655 		return features;
6656 
6657 	changed_features = __hdd_fix_features(net_dev, features);
6658 
6659 	osif_vdev_sync_op_stop(vdev_sync);
6660 
6661 	return changed_features;
6662 }
6663 /**
6664  * __hdd_set_features - Notify device about change in features
6665  * @net_dev: Handle to net_device
6666  * @features: Existing + requested feature after resolving the dependency
6667  *
6668  * Return: 0 on success, non zero error on failure
6669  */
__hdd_set_features(struct net_device * net_dev,netdev_features_t features)6670 static int __hdd_set_features(struct net_device *net_dev,
6671 			      netdev_features_t features)
6672 {
6673 	struct hdd_adapter *adapter = netdev_priv(net_dev);
6674 	ol_txrx_soc_handle soc = cds_get_context(QDF_MODULE_ID_SOC);
6675 
6676 	if (!adapter->handle_feature_update) {
6677 		hdd_debug("Not triggered by hdd_netdev_update_features");
6678 		return 0;
6679 	}
6680 
6681 	if (!soc)
6682 		return 0;
6683 
6684 	hdd_debug("vdev mode %d vdev_id %d current features 0x%llx, changed features 0x%llx",
6685 		  adapter->device_mode, adapter->deflink->vdev_id,
6686 		  net_dev->features, features);
6687 
6688 	return 0;
6689 }
6690 
6691 /**
6692  * hdd_set_features() - Wrapper for __hdd_set_features to protect it from SSR
6693  * @net_dev: Pointer to net_device structure
6694  * @features: Updated features set
6695  *
6696  * Is called to update device configurations for changed features.
6697  *
6698  * Return: 0 for success, non-zero for failure
6699  */
hdd_set_features(struct net_device * net_dev,netdev_features_t features)6700 static int hdd_set_features(struct net_device *net_dev,
6701 			    netdev_features_t features)
6702 {
6703 	int errno;
6704 	struct osif_vdev_sync *vdev_sync;
6705 
6706 	errno = osif_vdev_sync_op_start(net_dev, &vdev_sync);
6707 	if (errno) {
6708 		/*
6709 		 * Only invoke from netdev_feature_update_work expected,
6710 		 * which is from CLD inside.
6711 		 * Ignore others from upper stack during loading phase,
6712 		 * and return success to avoid failure print from kernel.
6713 		 */
6714 		hdd_debug("VDEV in transition, ignore set_features");
6715 		return 0;
6716 	}
6717 
6718 	errno = __hdd_set_features(net_dev, features);
6719 
6720 	osif_vdev_sync_op_stop(vdev_sync);
6721 
6722 	return errno;
6723 }
6724 
6725 #define HDD_NETDEV_FEATURES_UPDATE_MAX_WAIT_COUNT	10
6726 #define HDD_NETDEV_FEATURES_UPDATE_WAIT_INTERVAL_MS	20
6727 
hdd_netdev_update_features(struct hdd_adapter * adapter)6728 void hdd_netdev_update_features(struct hdd_adapter *adapter)
6729 {
6730 	struct net_device *net_dev = adapter->dev;
6731 	ol_txrx_soc_handle soc = cds_get_context(QDF_MODULE_ID_SOC);
6732 	bool request_feature_update = false;
6733 	int wait_count = HDD_NETDEV_FEATURES_UPDATE_MAX_WAIT_COUNT;
6734 
6735 	if (!soc)
6736 		return;
6737 
6738 	if (!cdp_cfg_get(soc, cfg_dp_disable_legacy_mode_csum_offload))
6739 		return;
6740 
6741 	switch (adapter->device_mode) {
6742 	case QDF_STA_MODE:
6743 		if (cdp_cfg_get(soc, cfg_dp_enable_ip_tcp_udp_checksum_offload))
6744 			request_feature_update = true;
6745 		break;
6746 	default:
6747 		break;
6748 	}
6749 
6750 	if (request_feature_update) {
6751 		hdd_debug("Update net_dev features for device mode %d",
6752 			  adapter->device_mode);
6753 		while (!adapter->delete_in_progress) {
6754 			if (rtnl_trylock()) {
6755 				adapter->handle_feature_update = true;
6756 				netdev_update_features(net_dev);
6757 				adapter->handle_feature_update = false;
6758 				rtnl_unlock();
6759 				break;
6760 			}
6761 
6762 			if (wait_count--) {
6763 				qdf_sleep(
6764 				HDD_NETDEV_FEATURES_UPDATE_WAIT_INTERVAL_MS);
6765 			} else {
6766 				/*
6767 				 * We have failed to updated the netdev
6768 				 * features for very long, so enable the queues
6769 				 * now. The impact of not being able to update
6770 				 * the netdev feature is lower TPUT when
6771 				 * switching from legacy to non-legacy mode.
6772 				 */
6773 				hdd_err("Failed to update netdev features for device mode %d",
6774 					adapter->device_mode);
6775 				break;
6776 			}
6777 		}
6778 	}
6779 }
6780 
6781 static const struct net_device_ops wlan_drv_ops = {
6782 	.ndo_open = hdd_open,
6783 	.ndo_stop = hdd_stop,
6784 	.ndo_uninit = hdd_uninit,
6785 	.ndo_start_xmit = hdd_hard_start_xmit,
6786 	.ndo_fix_features = hdd_fix_features,
6787 	.ndo_set_features = hdd_set_features,
6788 	.ndo_tx_timeout = hdd_tx_timeout,
6789 	.ndo_get_stats = hdd_get_stats,
6790 #if LINUX_VERSION_CODE < KERNEL_VERSION(5, 15, 0)
6791 	.ndo_do_ioctl = hdd_ioctl,
6792 #endif
6793 	.ndo_set_mac_address = hdd_set_mac_address,
6794 	.ndo_select_queue = hdd_select_queue,
6795 	.ndo_set_rx_mode = hdd_set_multicast_list,
6796 #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0)
6797 	.ndo_siocdevprivate = hdd_dev_private_ioctl,
6798 #endif
6799 };
6800 
6801 #ifdef FEATURE_MONITOR_MODE_SUPPORT
6802 /* Monitor mode net_device_ops, does not Tx and most of operations. */
6803 static const struct net_device_ops wlan_mon_drv_ops = {
6804 	.ndo_open = hdd_mon_open,
6805 	.ndo_stop = hdd_stop,
6806 	.ndo_get_stats = hdd_get_stats,
6807 };
6808 
6809 /**
6810  * hdd_set_mon_ops() - update net_device ops for monitor mode
6811  * @dev: Handle to struct net_device to be updated.
6812  * Return: None
6813  */
hdd_set_mon_ops(struct net_device * dev)6814 static void hdd_set_mon_ops(struct net_device *dev)
6815 {
6816 	dev->netdev_ops = &wlan_mon_drv_ops;
6817 }
6818 
6819 #ifdef WLAN_FEATURE_TSF_PTP
hdd_set_station_ops(struct net_device * dev)6820 void hdd_set_station_ops(struct net_device *dev)
6821 {
6822 	if (cds_get_conparam() == QDF_GLOBAL_MONITOR_MODE) {
6823 		hdd_set_mon_ops(dev);
6824 	} else {
6825 		dev->netdev_ops = &wlan_drv_ops;
6826 		dev->ethtool_ops = &wlan_ethtool_ops;
6827 	}
6828 }
6829 #else
hdd_set_station_ops(struct net_device * dev)6830 void hdd_set_station_ops(struct net_device *dev)
6831 {
6832 	if (cds_get_conparam() == QDF_GLOBAL_MONITOR_MODE)
6833 		hdd_set_mon_ops(dev);
6834 	else
6835 		dev->netdev_ops = &wlan_drv_ops;
6836 }
6837 
6838 #endif
6839 #else
6840 #ifdef WLAN_FEATURE_TSF_PTP
hdd_set_station_ops(struct net_device * dev)6841 void hdd_set_station_ops(struct net_device *dev)
6842 {
6843 	dev->netdev_ops = &wlan_drv_ops;
6844 	dev->ethtool_ops = &wlan_ethtool_ops;
6845 }
6846 #else
hdd_set_station_ops(struct net_device * dev)6847 void hdd_set_station_ops(struct net_device *dev)
6848 {
6849 	dev->netdev_ops = &wlan_drv_ops;
6850 }
6851 #endif
hdd_set_mon_ops(struct net_device * dev)6852 static void hdd_set_mon_ops(struct net_device *dev)
6853 {
6854 }
6855 #endif
6856 
6857 #ifdef WLAN_FEATURE_PKT_CAPTURE
6858 /* Packet Capture mode net_device_ops, does not Tx and most of operations. */
6859 static const struct net_device_ops wlan_pktcapture_drv_ops = {
6860 	.ndo_open = hdd_pktcapture_open,
6861 	.ndo_stop = hdd_stop,
6862 	.ndo_get_stats = hdd_get_stats,
6863 };
6864 
hdd_set_pktcapture_ops(struct net_device * dev)6865 static void hdd_set_pktcapture_ops(struct net_device *dev)
6866 {
6867 	dev->netdev_ops = &wlan_pktcapture_drv_ops;
6868 }
6869 #else
hdd_set_pktcapture_ops(struct net_device * dev)6870 static void hdd_set_pktcapture_ops(struct net_device *dev)
6871 {
6872 }
6873 #endif
6874 
6875 #ifdef MULTI_CLIENT_LL_SUPPORT
6876 /**
6877  * hdd_set_multi_client_ll_support() - set multi client ll support flag in
6878  * allocated station hdd adapter
6879  * @adapter: pointer to hdd adapter
6880  *
6881  * Return: none
6882  */
hdd_set_multi_client_ll_support(struct hdd_adapter * adapter)6883 static void hdd_set_multi_client_ll_support(struct hdd_adapter *adapter)
6884 {
6885 	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
6886 	bool multi_client_ll_ini_support, multi_client_ll_caps;
6887 
6888 	ucfg_mlme_cfg_get_multi_client_ll_ini_support(hdd_ctx->psoc,
6889 						&multi_client_ll_ini_support);
6890 	multi_client_ll_caps =
6891 		ucfg_mlme_get_wlm_multi_client_ll_caps(hdd_ctx->psoc);
6892 
6893 	hdd_debug("fw caps: %d, ini: %d", multi_client_ll_caps,
6894 		  multi_client_ll_ini_support);
6895 	if (multi_client_ll_caps && multi_client_ll_ini_support)
6896 		adapter->multi_client_ll_support = true;
6897 }
6898 #else
6899 static inline void
hdd_set_multi_client_ll_support(struct hdd_adapter * adapter)6900 hdd_set_multi_client_ll_support(struct hdd_adapter *adapter)
6901 {
6902 }
6903 #endif
6904 
6905 /**
6906  * hdd_alloc_station_adapter() - allocate the station hdd adapter
6907  * @hdd_ctx: global hdd context
6908  * @mac_addr: mac address to assign to the interface
6909  * @name_assign_type: name assignment type
6910  * @name: User-visible name of the interface
6911  * @session_type: interface type to be created
6912  *
6913  * hdd adapter pointer would point to the netdev->priv space, this function
6914  * would retrieve the pointer, and setup the hdd adapter configuration.
6915  *
6916  * Return: the pointer to hdd adapter, otherwise NULL
6917  */
6918 static struct hdd_adapter *
hdd_alloc_station_adapter(struct hdd_context * hdd_ctx,tSirMacAddr mac_addr,unsigned char name_assign_type,const char * name,uint8_t session_type)6919 hdd_alloc_station_adapter(struct hdd_context *hdd_ctx, tSirMacAddr mac_addr,
6920 			  unsigned char name_assign_type, const char *name,
6921 			  uint8_t session_type)
6922 {
6923 	struct net_device *dev;
6924 	struct hdd_adapter *adapter;
6925 	QDF_STATUS qdf_status;
6926 	uint8_t latency_level;
6927 
6928 	/* cfg80211 initialization and registration */
6929 	dev = alloc_netdev_mqs(sizeof(*adapter), name,
6930 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
6931 			      name_assign_type,
6932 #endif
6933 			      ((cds_get_conparam() == QDF_GLOBAL_MONITOR_MODE ||
6934 			       wlan_hdd_is_session_type_monitor(session_type)) ?
6935 			       hdd_mon_mode_ether_setup : ether_setup),
6936 			      NUM_TX_QUEUES, NUM_RX_QUEUES);
6937 
6938 	if (!dev) {
6939 		hdd_err("Failed to allocate new net_device '%s'", name);
6940 		return NULL;
6941 	}
6942 
6943 	adapter = netdev_priv(dev);
6944 
6945 	qdf_mem_zero(adapter, sizeof(*adapter));
6946 	adapter->dev = dev;
6947 	adapter->deflink = &adapter->link_info[WLAN_HDD_DEFLINK_IDX];
6948 	adapter->hdd_ctx = hdd_ctx;
6949 	adapter->magic = WLAN_HDD_ADAPTER_MAGIC;
6950 	qdf_atomic_set_bit(WLAN_HDD_DEFLINK_IDX, &adapter->active_links);
6951 
6952 	qdf_status = hdd_monitor_mode_qdf_create_event(adapter, session_type);
6953 	if (QDF_IS_STATUS_ERROR(qdf_status)) {
6954 		hdd_err_rl("create monitor mode vdve up event failed");
6955 		goto free_net_dev;
6956 	}
6957 
6958 	hdd_update_dynamic_tsf_sync(adapter);
6959 	adapter->is_link_up_service_needed = false;
6960 	adapter->send_mode_change = true;
6961 
6962 	/* Cache station count initialize to zero */
6963 	qdf_atomic_init(&adapter->cache_sta_count);
6964 
6965 	/* Init the net_device structure */
6966 	strlcpy(dev->name, name, IFNAMSIZ);
6967 
6968 	qdf_net_update_net_device_dev_addr(dev, mac_addr, sizeof(tSirMacAddr));
6969 	qdf_mem_copy(adapter->mac_addr.bytes, mac_addr, sizeof(tSirMacAddr));
6970 	dev->watchdog_timeo = HDD_TX_TIMEOUT;
6971 
6972 	if (wlan_hdd_is_session_type_monitor(session_type)) {
6973 		if (ucfg_pkt_capture_get_mode(hdd_ctx->psoc) !=
6974 						PACKET_CAPTURE_MODE_DISABLE)
6975 			hdd_set_pktcapture_ops(adapter->dev);
6976 		if (ucfg_mlme_is_sta_mon_conc_supported(hdd_ctx->psoc) ||
6977 		    ucfg_dp_is_local_pkt_capture_enabled(hdd_ctx->psoc))
6978 			hdd_set_mon_ops(adapter->dev);
6979 	} else {
6980 		hdd_set_station_ops(adapter->dev);
6981 	}
6982 
6983 	hdd_dev_setup_destructor(dev);
6984 	dev->ieee80211_ptr = &adapter->wdev;
6985 	dev->tx_queue_len = HDD_NETDEV_TX_QUEUE_LEN;
6986 	adapter->wdev.wiphy = hdd_ctx->wiphy;
6987 	adapter->wdev.netdev = dev;
6988 	qdf_status = ucfg_mlme_cfg_get_wlm_level(hdd_ctx->psoc, &latency_level);
6989 	if (QDF_IS_STATUS_ERROR(qdf_status)) {
6990 		hdd_debug("Can't get latency level");
6991 		latency_level =
6992 			QCA_WLAN_VENDOR_ATTR_CONFIG_LATENCY_LEVEL_NORMAL;
6993 	}
6994 	adapter->latency_level = latency_level;
6995 	hdd_set_multi_client_ll_support(adapter);
6996 
6997 	/* set dev's parent to underlying device */
6998 	SET_NETDEV_DEV(dev, hdd_ctx->parent_dev);
6999 	spin_lock_init(&adapter->pause_map_lock);
7000 	adapter->start_time = qdf_system_ticks();
7001 	adapter->last_time = adapter->start_time;
7002 
7003 	qdf_atomic_init(&adapter->is_ll_stats_req_pending);
7004 	hdd_init_get_sta_in_ll_stats_config(adapter);
7005 	hdd_init_link_state_config(adapter);
7006 
7007 	return adapter;
7008 
7009 free_net_dev:
7010 	free_netdev(adapter->dev);
7011 
7012 	return NULL;
7013 }
7014 
7015 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 12, 0) || \
7016 	(defined CFG80211_CHANGE_NETDEV_REGISTRATION_SEMANTICS))
7017 static int
hdd_register_netdevice(struct hdd_adapter * adapter,struct net_device * dev,struct hdd_adapter_create_param * params)7018 hdd_register_netdevice(struct hdd_adapter *adapter, struct net_device *dev,
7019 		       struct hdd_adapter_create_param *params)
7020 {
7021 	int ret;
7022 
7023 	if (params->is_add_virtual_iface)
7024 		ret = wlan_cfg80211_register_netdevice(dev);
7025 	else
7026 		ret = register_netdevice(dev);
7027 
7028 	return ret;
7029 }
7030 #else
7031 static int
hdd_register_netdevice(struct hdd_adapter * adapter,struct net_device * dev,struct hdd_adapter_create_param * params)7032 hdd_register_netdevice(struct hdd_adapter *adapter, struct net_device *dev,
7033 		       struct hdd_adapter_create_param *params)
7034 {
7035 	return register_netdevice(dev);
7036 }
7037 #endif
7038 
7039 static QDF_STATUS
hdd_register_interface(struct hdd_adapter * adapter,bool rtnl_held,struct hdd_adapter_create_param * params)7040 hdd_register_interface(struct hdd_adapter *adapter, bool rtnl_held,
7041 		       struct hdd_adapter_create_param *params)
7042 {
7043 	struct net_device *dev = adapter->dev;
7044 	int ret;
7045 
7046 	hdd_enter();
7047 
7048 	if (rtnl_held) {
7049 		if (strnchr(dev->name, IFNAMSIZ - 1, '%')) {
7050 
7051 			ret = dev_alloc_name(dev, dev->name);
7052 			if (ret < 0) {
7053 				hdd_err(
7054 				    "unable to get dev name: %s, err = 0x%x",
7055 				    dev->name, ret);
7056 				return QDF_STATUS_E_FAILURE;
7057 			}
7058 		}
7059 		hdd_debug("hdd_register_netdevice(%s) type:%d", dev->name,
7060 			  adapter->device_mode);
7061 		ret = hdd_register_netdevice(adapter, dev, params);
7062 		if (ret) {
7063 			hdd_err("register_netdevice(%s) failed, err = 0x%x",
7064 				dev->name, ret);
7065 			return QDF_STATUS_E_FAILURE;
7066 		}
7067 	} else {
7068 		hdd_debug("register_netdev(%s) type:%d", dev->name,
7069 			  adapter->device_mode);
7070 		ret = register_netdev(dev);
7071 		if (ret) {
7072 			hdd_err("register_netdev(%s) failed, err = 0x%x",
7073 				dev->name, ret);
7074 			return QDF_STATUS_E_FAILURE;
7075 		}
7076 	}
7077 	set_bit(NET_DEVICE_REGISTERED, &adapter->event_flags);
7078 
7079 	hdd_exit();
7080 
7081 	return QDF_STATUS_SUCCESS;
7082 }
7083 
hdd_sme_close_session_callback(uint8_t vdev_id)7084 QDF_STATUS hdd_sme_close_session_callback(uint8_t vdev_id)
7085 {
7086 	struct hdd_adapter *adapter;
7087 	struct hdd_context *hdd_ctx;
7088 	struct wlan_hdd_link_info *link_info;
7089 
7090 	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
7091 	if (!hdd_ctx)
7092 		return QDF_STATUS_E_FAILURE;
7093 
7094 	link_info = hdd_get_link_info_by_vdev(hdd_ctx, vdev_id);
7095 	if (!link_info) {
7096 		hdd_err("Invalid vdev %d", vdev_id);
7097 		return QDF_STATUS_E_INVAL;
7098 	}
7099 
7100 	adapter = link_info->adapter;
7101 	if (WLAN_HDD_ADAPTER_MAGIC != adapter->magic) {
7102 		hdd_err("Invalid magic");
7103 		return QDF_STATUS_NOT_INITIALIZED;
7104 	}
7105 
7106 	clear_bit(SME_SESSION_OPENED, &link_info->link_flags);
7107 	qdf_spin_lock_bh(&link_info->vdev_lock);
7108 	link_info->vdev_id = WLAN_UMAC_VDEV_ID_MAX;
7109 	qdf_spin_unlock_bh(&link_info->vdev_lock);
7110 
7111 	/*
7112 	 * We can be blocked while waiting for scheduled work to be
7113 	 * flushed, and the adapter structure can potentially be freed, in
7114 	 * which case the magic will have been reset.  So make sure the
7115 	 * magic is still good, and hence the adapter structure is still
7116 	 * valid, before signaling completion
7117 	 */
7118 	if (WLAN_HDD_ADAPTER_MAGIC == adapter->magic)
7119 		complete(&link_info->vdev_destroy_event);
7120 
7121 	return QDF_STATUS_SUCCESS;
7122 }
7123 
hdd_vdev_ready(struct wlan_objmgr_vdev * vdev,struct qdf_mac_addr * bridgeaddr)7124 int hdd_vdev_ready(struct wlan_objmgr_vdev *vdev,
7125 		   struct qdf_mac_addr *bridgeaddr)
7126 {
7127 	QDF_STATUS status;
7128 
7129 	status = pmo_vdev_ready(vdev, bridgeaddr);
7130 	if (QDF_IS_STATUS_ERROR(status))
7131 		return qdf_status_to_os_return(status);
7132 
7133 	status = ucfg_reg_11d_vdev_created_update(vdev);
7134 	if (QDF_IS_STATUS_ERROR(status))
7135 		return qdf_status_to_os_return(status);
7136 
7137 	if (wma_capability_enhanced_mcast_filter())
7138 		status = ucfg_pmo_enhanced_mc_filter_enable(vdev);
7139 	else
7140 		status = ucfg_pmo_enhanced_mc_filter_disable(vdev);
7141 
7142 	return qdf_status_to_os_return(status);
7143 }
7144 
7145 /**
7146  * hdd_check_wait_for_hw_mode_completion - Check hw mode in progress
7147  * @hdd_ctx: hdd context
7148  *
7149  * Check and wait for hw mode response if any hw mode change is
7150  * in progress. Vdev delete will purge the serialization queue
7151  * for the vdev. It will cause issues when the fw event coming
7152  * up later and no active hw mode change req ser command in queue.
7153  *
7154  * Return void
7155  */
hdd_check_wait_for_hw_mode_completion(struct hdd_context * hdd_ctx)7156 static void hdd_check_wait_for_hw_mode_completion(struct hdd_context *hdd_ctx)
7157 {
7158 	QDF_STATUS status;
7159 
7160 	if (!wlan_hdd_validate_context(hdd_ctx) &&
7161 	    policy_mgr_is_hw_mode_change_in_progress(
7162 		hdd_ctx->psoc)) {
7163 		status = policy_mgr_wait_for_connection_update(
7164 			hdd_ctx->psoc);
7165 		if (!QDF_IS_STATUS_SUCCESS(status)) {
7166 			hdd_nofl_debug("qdf wait for hw mode event failed!!");
7167 		}
7168 	}
7169 }
7170 
hdd_stop_last_active_connection(struct hdd_context * hdd_ctx,struct wlan_objmgr_vdev * vdev)7171 static void hdd_stop_last_active_connection(struct hdd_context *hdd_ctx,
7172 					    struct wlan_objmgr_vdev *vdev)
7173 {
7174 	enum policy_mgr_con_mode mode;
7175 	struct wlan_objmgr_psoc *psoc;
7176 	enum QDF_OPMODE op_mode;
7177 
7178 	/* If this is the last active connection check
7179 	 * and stop the opportunistic timer.
7180 	 */
7181 	psoc = wlan_vdev_get_psoc(vdev);
7182 	op_mode = wlan_vdev_mlme_get_opmode(vdev);
7183 	mode = policy_mgr_qdf_opmode_to_pm_con_mode(psoc, op_mode,
7184 						    wlan_vdev_get_id(vdev));
7185 	if ((policy_mgr_get_connection_count(psoc) == 1 &&
7186 	     policy_mgr_mode_specific_connection_count(psoc,
7187 						       mode, NULL) == 1) ||
7188 	     (!policy_mgr_get_connection_count(psoc) &&
7189 	     !hdd_is_any_sta_connecting(hdd_ctx))) {
7190 		policy_mgr_check_and_stop_opportunistic_timer(
7191 						psoc,
7192 						wlan_vdev_get_id(vdev));
7193 	}
7194 }
7195 
hdd_vdev_destroy_event_wait(struct hdd_context * hdd_ctx,struct wlan_objmgr_vdev * vdev)7196 static int hdd_vdev_destroy_event_wait(struct hdd_context *hdd_ctx,
7197 				       struct wlan_objmgr_vdev *vdev)
7198 {
7199 	long rc;
7200 	QDF_STATUS status;
7201 	uint8_t vdev_id;
7202 	struct wlan_hdd_link_info *link_info;
7203 	struct qdf_mac_addr *mld_addr;
7204 	struct wlan_objmgr_psoc *psoc = NULL;
7205 
7206 	vdev_id = wlan_vdev_get_id(vdev);
7207 	link_info = hdd_get_link_info_by_vdev(hdd_ctx, vdev_id);
7208 	if (!link_info) {
7209 		hdd_err("Invalid vdev");
7210 		return -EINVAL;
7211 	}
7212 
7213 	psoc = wlan_vdev_get_psoc(vdev);
7214 	if (!psoc) {
7215 		obj_mgr_err("Failed to get psoc");
7216 		return QDF_STATUS_E_FAILURE;
7217 	}
7218 
7219 	/* Detach DP vdev from DP MLO Device Context */
7220 	mld_addr = (struct qdf_mac_addr *)wlan_vdev_mlme_get_mldaddr(vdev);
7221 
7222 	if (!qdf_is_macaddr_zero(mld_addr)) {
7223 		/* only for MLO vdev's */
7224 
7225 		if (cdp_mlo_dev_ctxt_detach(wlan_psoc_get_dp_handle(psoc),
7226 					    wlan_vdev_get_id(vdev),
7227 					    (uint8_t *)mld_addr)
7228 					    != QDF_STATUS_SUCCESS) {
7229 			obj_mgr_err("Failed to detach DP vdev from DP MLO Dev ctxt");
7230 			QDF_BUG(0);
7231 			return QDF_STATUS_E_FAILURE;
7232 		}
7233 	}
7234 
7235 	/* close sme session (destroy vdev in firmware via legacy API) */
7236 	INIT_COMPLETION(link_info->vdev_destroy_event);
7237 	status = sme_vdev_delete(hdd_ctx->mac_handle, vdev);
7238 	if (QDF_IS_STATUS_ERROR(status)) {
7239 		hdd_err("vdev %d: failed to delete with status:%d",
7240 			vdev_id, status);
7241 		return -EAGAIN;
7242 	}
7243 
7244 	/* block on a completion variable until sme session is closed */
7245 	rc = wait_for_completion_timeout(
7246 			&link_info->vdev_destroy_event,
7247 			msecs_to_jiffies(SME_CMD_VDEV_CREATE_DELETE_TIMEOUT));
7248 	if (!rc) {
7249 		hdd_err("vdev %d: timed out waiting for delete", vdev_id);
7250 		clear_bit(SME_SESSION_OPENED, &link_info->link_flags);
7251 		sme_cleanup_session(hdd_ctx->mac_handle, vdev_id);
7252 		cds_flush_logs(WLAN_LOG_TYPE_FATAL,
7253 			       WLAN_LOG_INDICATOR_HOST_DRIVER,
7254 			       WLAN_LOG_REASON_VDEV_DELETE_RSP_TIMED_OUT,
7255 			       true, true);
7256 		return -EINVAL;
7257 	}
7258 
7259 	hdd_nofl_info("vdev %d destroyed successfully", vdev_id);
7260 	return 0;
7261 }
7262 
7263 static inline
hdd_vdev_deinit_components(struct wlan_objmgr_vdev * vdev)7264 void hdd_vdev_deinit_components(struct wlan_objmgr_vdev *vdev)
7265 {
7266 	ucfg_pmo_del_wow_pattern(vdev);
7267 	ucfg_son_disable_cbs(vdev);
7268 }
7269 
7270 static inline
hdd_reset_vdev_info(struct wlan_hdd_link_info * link_info)7271 void hdd_reset_vdev_info(struct wlan_hdd_link_info *link_info)
7272 {
7273 	qdf_spin_lock_bh(&link_info->vdev_lock);
7274 	link_info->vdev = NULL;
7275 	qdf_spin_unlock_bh(&link_info->vdev_lock);
7276 }
7277 
hdd_vdev_destroy(struct wlan_hdd_link_info * link_info)7278 int hdd_vdev_destroy(struct wlan_hdd_link_info *link_info)
7279 {
7280 	int ret;
7281 	uint8_t vdev_id;
7282 	struct hdd_context *hdd_ctx;
7283 	struct wlan_objmgr_vdev *vdev;
7284 	struct wlan_objmgr_psoc *psoc;
7285 	enum QDF_OPMODE op_mode;
7286 
7287 	vdev_id = link_info->vdev_id;
7288 	hdd_nofl_debug("destroying vdev %d", vdev_id);
7289 	/* vdev created sanity check */
7290 	if (!test_bit(SME_SESSION_OPENED, &link_info->link_flags)) {
7291 		hdd_nofl_debug("vdev %u does not exist", vdev_id);
7292 		return -EINVAL;
7293 	}
7294 
7295 	hdd_ctx = WLAN_HDD_GET_CTX(link_info->adapter);
7296 
7297 	vdev = hdd_objmgr_get_vdev_by_user(link_info, WLAN_OSIF_ID);
7298 	if (!vdev)
7299 		return -EINVAL;
7300 
7301 	psoc = wlan_vdev_get_psoc(vdev);
7302 	if (!psoc) {
7303 		hdd_err("invalid psoc");
7304 		return -EINVAL;
7305 	}
7306 	op_mode = wlan_vdev_mlme_get_opmode(vdev);
7307 
7308 	hdd_stop_last_active_connection(hdd_ctx, vdev);
7309 	hdd_check_wait_for_hw_mode_completion(hdd_ctx);
7310 	ucfg_scan_vdev_set_disable(vdev, REASON_VDEV_DOWN);
7311 	wlan_hdd_scan_abort(link_info);
7312 	hdd_vdev_deinit_components(vdev);
7313 	hdd_mlo_t2lm_unregister_callback(vdev);
7314 	hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_ID);
7315 
7316 	hdd_reset_vdev_info(link_info);
7317 	osif_cm_osif_priv_deinit(vdev);
7318 
7319 	/* Release the hdd reference */
7320 	wlan_objmgr_vdev_release_ref(vdev, WLAN_HDD_ID_OBJ_MGR);
7321 
7322 	/* Get runtime lock to prevent runtime suspend */
7323 	qdf_runtime_pm_prevent_suspend(&hdd_ctx->runtime_context.vdev_destroy);
7324 
7325 	ret = hdd_vdev_destroy_event_wait(hdd_ctx, vdev);
7326 
7327 	ucfg_reg_11d_vdev_delete_update(psoc, op_mode, vdev_id);
7328 
7329 	qdf_runtime_pm_allow_suspend(&hdd_ctx->runtime_context.vdev_destroy);
7330 	return ret;
7331 }
7332 
7333 void
hdd_store_nss_chains_cfg_in_vdev(struct hdd_context * hdd_ctx,struct wlan_objmgr_vdev * vdev)7334 hdd_store_nss_chains_cfg_in_vdev(struct hdd_context *hdd_ctx,
7335 				 struct wlan_objmgr_vdev *vdev)
7336 {
7337 	struct wlan_mlme_nss_chains vdev_ini_cfg;
7338 
7339 	/* Populate the nss chain params from ini for this vdev type */
7340 	sme_populate_nss_chain_params(hdd_ctx->mac_handle, &vdev_ini_cfg,
7341 				      wlan_vdev_mlme_get_opmode(vdev),
7342 				      hdd_ctx->num_rf_chains);
7343 
7344 	/* Store the nss chain config into the vdev */
7345 	sme_store_nss_chains_cfg_in_vdev(vdev, &vdev_ini_cfg);
7346 }
7347 
hdd_is_vdev_in_conn_state(struct wlan_hdd_link_info * link_info)7348 bool hdd_is_vdev_in_conn_state(struct wlan_hdd_link_info *link_info)
7349 {
7350 	switch (link_info->adapter->device_mode) {
7351 	case QDF_STA_MODE:
7352 	case QDF_P2P_CLIENT_MODE:
7353 	case QDF_P2P_DEVICE_MODE:
7354 		return hdd_cm_is_vdev_associated(link_info);
7355 	case QDF_SAP_MODE:
7356 	case QDF_P2P_GO_MODE:
7357 		return (test_bit(SOFTAP_BSS_STARTED,
7358 				 &link_info->link_flags));
7359 	default:
7360 		hdd_err("Device mode %d invalid",
7361 			link_info->adapter->device_mode);
7362 		return 0;
7363 	}
7364 }
7365 
7366 #define MAX_VDEV_RTT_PARAMS 2
7367 /* params being sent:
7368  * wmi_vdev_param_enable_disable_rtt_responder_role
7369  * wmi_vdev_param_enable_disable_rtt_initiator_role
7370  */
7371 static QDF_STATUS
hdd_vdev_configure_rtt_params(struct wlan_objmgr_vdev * vdev)7372 hdd_vdev_configure_rtt_params(struct wlan_objmgr_vdev *vdev)
7373 {
7374 	QDF_STATUS status;
7375 	struct wlan_objmgr_psoc *psoc;
7376 	uint32_t fine_time_meas_cap = 0;
7377 	uint8_t vdev_id = wlan_vdev_get_id(vdev);
7378 	struct dev_set_param vdevsetparam[MAX_VDEV_RTT_PARAMS] = {};
7379 	uint8_t index = 0;
7380 	WMI_FW_SUB_FEAT_CAPS wmi_fw_rtt_respr, wmi_fw_rtt_initr;
7381 
7382 	switch (wlan_vdev_mlme_get_opmode(vdev)) {
7383 	case QDF_STA_MODE:
7384 		wmi_fw_rtt_respr = WMI_FW_STA_RTT_RESPR;
7385 		wmi_fw_rtt_initr = WMI_FW_STA_RTT_INITR;
7386 		break;
7387 	case QDF_SAP_MODE:
7388 		wmi_fw_rtt_respr = WMI_FW_AP_RTT_RESPR;
7389 		wmi_fw_rtt_initr = WMI_FW_AP_RTT_INITR;
7390 		break;
7391 	default:
7392 		return QDF_STATUS_SUCCESS;
7393 	}
7394 
7395 	psoc = wlan_vdev_get_psoc(vdev);
7396 
7397 	ucfg_mlme_get_fine_time_meas_cap(psoc, &fine_time_meas_cap);
7398 	status = mlme_check_index_setparam(
7399 			vdevsetparam,
7400 			wmi_vdev_param_enable_disable_rtt_responder_role,
7401 			(fine_time_meas_cap & wmi_fw_rtt_respr), index++,
7402 			MAX_VDEV_RTT_PARAMS);
7403 	if (QDF_IS_STATUS_ERROR(status))
7404 		return status;
7405 
7406 	status = mlme_check_index_setparam(
7407 			vdevsetparam,
7408 			wmi_vdev_param_enable_disable_rtt_initiator_role,
7409 			(fine_time_meas_cap & wmi_fw_rtt_initr), index++,
7410 			MAX_VDEV_RTT_PARAMS);
7411 	if (QDF_IS_STATUS_ERROR(status))
7412 		return status;
7413 
7414 	status = sme_send_multi_pdev_vdev_set_params(MLME_VDEV_SETPARAM,
7415 						     vdev_id, vdevsetparam,
7416 						     index);
7417 	if (QDF_IS_STATUS_ERROR(status))
7418 		hdd_err("failed to set RTT_RESPONDER,INITIATOR params:%d",
7419 			status);
7420 
7421 	return status;
7422 }
7423 
hdd_store_vdev_info(struct wlan_hdd_link_info * link_info,struct wlan_objmgr_vdev * vdev)7424 static void hdd_store_vdev_info(struct wlan_hdd_link_info *link_info,
7425 				struct wlan_objmgr_vdev *vdev)
7426 {
7427 	struct vdev_osif_priv *osif_priv;
7428 
7429 	osif_priv = wlan_vdev_get_ospriv(vdev);
7430 	if (osif_priv) {
7431 		osif_priv->wdev = link_info->adapter->dev->ieee80211_ptr;
7432 		osif_priv->legacy_osif_priv = link_info;
7433 	}
7434 
7435 	qdf_spin_lock_bh(&link_info->vdev_lock);
7436 	link_info->vdev_id = wlan_vdev_get_id(vdev);
7437 	link_info->vdev = vdev;
7438 	qdf_spin_unlock_bh(&link_info->vdev_lock);
7439 }
7440 
7441 static void
hdd_init_station_context(struct wlan_hdd_link_info * link_info)7442 hdd_init_station_context(struct wlan_hdd_link_info *link_info)
7443 {
7444 	struct hdd_station_ctx *sta_ctx;
7445 	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(link_info->adapter);
7446 
7447 	/* Set the default operation channel freq and auth type to open */
7448 	sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(link_info);
7449 	sta_ctx->conn_info.chan_freq = hdd_ctx->config->operating_chan_freq;
7450 	sta_ctx->conn_info.auth_type = eCSR_AUTH_TYPE_OPEN_SYSTEM;
7451 	hdd_roam_profile_init(link_info);
7452 }
7453 
hdd_vdev_set_ht_vht_ies(mac_handle_t mac_handle,struct wlan_objmgr_vdev * vdev)7454 static void hdd_vdev_set_ht_vht_ies(mac_handle_t mac_handle,
7455 				    struct wlan_objmgr_vdev *vdev)
7456 {
7457 	QDF_STATUS status;
7458 	struct wlan_objmgr_psoc *psoc;
7459 	bool bval = false;
7460 
7461 	psoc = wlan_vdev_get_psoc(vdev);
7462 	status = ucfg_mlme_get_vht_enable2x2(psoc, &bval);
7463 	if (QDF_IS_STATUS_ERROR(status))
7464 		hdd_err("unable to get vht_enable2x2");
7465 
7466 	sme_set_pdev_ht_vht_ies(mac_handle, bval);
7467 	sme_set_vdev_ies_per_band(mac_handle, wlan_vdev_get_id(vdev),
7468 				  wlan_vdev_mlme_get_opmode(vdev));
7469 }
7470 
7471 static void
hdd_vdev_configure_rtt_mac_randomization(struct wlan_objmgr_psoc * psoc,struct wlan_objmgr_vdev * vdev)7472 hdd_vdev_configure_rtt_mac_randomization(struct wlan_objmgr_psoc *psoc,
7473 					 struct wlan_objmgr_vdev *vdev)
7474 {
7475 	int errno;
7476 	QDF_STATUS status;
7477 	bool bval = false;
7478 
7479 	status = ucfg_mlme_get_rtt_mac_randomization(psoc, &bval);
7480 	if (QDF_IS_STATUS_ERROR(status))
7481 		hdd_err("unable to get RTT MAC randomization value");
7482 
7483 	hdd_debug("setting RTT mac randomization param: %d", bval);
7484 	errno = sme_cli_set_command(
7485 			wlan_vdev_get_id(vdev),
7486 			wmi_vdev_param_enable_disable_rtt_initiator_random_mac,
7487 			bval, VDEV_CMD);
7488 
7489 	if (errno)
7490 		hdd_err("RTT mac randomization param set failed %d", errno);
7491 }
7492 
7493 static void
hdd_vdev_configure_max_tdls_params(struct wlan_objmgr_psoc * psoc,struct wlan_objmgr_vdev * vdev)7494 hdd_vdev_configure_max_tdls_params(struct wlan_objmgr_psoc *psoc,
7495 				   struct wlan_objmgr_vdev *vdev)
7496 {
7497 	uint16_t max_peer_count;
7498 	bool target_bigtk_support = false;
7499 
7500 	/*
7501 	 * Max peer can be tdls peers + self peer + bss peer +
7502 	 * temp bss peer for roaming create/delete peer at same time
7503 	 */
7504 	max_peer_count = cfg_tdls_get_max_peer_count(psoc);
7505 	max_peer_count += 3;
7506 	wlan_vdev_set_max_peer_count(vdev, max_peer_count);
7507 
7508 	ucfg_mlme_get_bigtk_support(psoc, &target_bigtk_support);
7509 	if (target_bigtk_support)
7510 		mlme_set_bigtk_support(vdev, true);
7511 }
7512 
7513 static inline void
hdd_vdev_configure_nan_params(struct wlan_objmgr_psoc * psoc,struct wlan_objmgr_vdev * vdev)7514 hdd_vdev_configure_nan_params(struct wlan_objmgr_psoc *psoc,
7515 			      struct wlan_objmgr_vdev *vdev)
7516 {
7517 	sme_cli_set_command(
7518 		wlan_vdev_get_id(vdev),
7519 		wmi_vdev_param_allow_nan_initial_discovery_of_mp0_cluster,
7520 		cfg_nan_get_support_mp0_discovery(psoc), VDEV_CMD);
7521 }
7522 
7523 #if defined(WLAN_FEATURE_11BE_MLO) && defined(WLAN_EXTERNAL_AUTH_MLO_SUPPORT)
7524 static void
hdd_set_vdev_mlo_external_sae_auth_conversion(struct wlan_objmgr_vdev * vdev,enum QDF_OPMODE mode)7525 hdd_set_vdev_mlo_external_sae_auth_conversion(struct wlan_objmgr_vdev *vdev,
7526 					      enum QDF_OPMODE mode)
7527 {
7528 	if (mode == QDF_STA_MODE || mode == QDF_SAP_MODE)
7529 		wlan_vdev_set_mlo_external_sae_auth_conversion(vdev, true);
7530 }
7531 #else
7532 static inline void
hdd_set_vdev_mlo_external_sae_auth_conversion(struct wlan_objmgr_vdev * vdev,enum QDF_OPMODE mode)7533 hdd_set_vdev_mlo_external_sae_auth_conversion(struct wlan_objmgr_vdev *vdev,
7534 					      enum QDF_OPMODE mode)
7535 {
7536 }
7537 #endif
7538 
7539 static void
hdd_vdev_configure_rtscts_enable(struct hdd_context * hdd_ctx,struct wlan_objmgr_vdev * vdev)7540 hdd_vdev_configure_rtscts_enable(struct hdd_context *hdd_ctx,
7541 				 struct wlan_objmgr_vdev *vdev)
7542 {
7543 	int ret;
7544 	QDF_STATUS status;
7545 	uint16_t rts_profile = 0;
7546 
7547 	if (cds_get_conparam() == QDF_GLOBAL_FTM_MODE)
7548 		return;
7549 
7550 	status = ucfg_fwol_get_rts_profile(hdd_ctx->psoc, &rts_profile);
7551 	if (QDF_IS_STATUS_ERROR(status)) {
7552 		hdd_err("FAILED TO GET RTSCTS Profile status:%d", status);
7553 		return;
7554 	}
7555 
7556 	ret = sme_cli_set_command(wlan_vdev_get_id(vdev),
7557 				  wmi_vdev_param_enable_rtscts,
7558 				  rts_profile,
7559 				  VDEV_CMD);
7560 	if (ret)
7561 		hdd_err("FAILED TO SET RTSCTS Profile ret:%d", ret);
7562 }
7563 
7564 static void
hdd_vdev_configure_usr_ps_params(struct wlan_objmgr_psoc * psoc,struct wlan_objmgr_vdev * vdev,struct wlan_hdd_link_info * link_info)7565 hdd_vdev_configure_usr_ps_params(struct wlan_objmgr_psoc *psoc,
7566 				 struct wlan_objmgr_vdev *vdev,
7567 				 struct wlan_hdd_link_info *link_info)
7568 {
7569 	struct hdd_adapter *adapter = link_info->adapter;
7570 
7571 	if (cds_get_conparam() == QDF_GLOBAL_FTM_MODE || !adapter)
7572 		return;
7573 
7574 	ucfg_mlme_set_user_ps(psoc, wlan_vdev_get_id(vdev),
7575 			      adapter->allow_power_save);
7576 }
7577 
7578 static void
hdd_vdev_configure_opmode_params(struct hdd_context * hdd_ctx,struct wlan_objmgr_vdev * vdev,struct wlan_hdd_link_info * link_info)7579 hdd_vdev_configure_opmode_params(struct hdd_context *hdd_ctx,
7580 				 struct wlan_objmgr_vdev *vdev,
7581 				 struct wlan_hdd_link_info *link_info)
7582 {
7583 	struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc;
7584 	enum QDF_OPMODE opmode = wlan_vdev_mlme_get_opmode(vdev);
7585 
7586 	switch (opmode) {
7587 	case QDF_STA_MODE:
7588 		hdd_vdev_configure_rtt_mac_randomization(psoc, vdev);
7589 		hdd_vdev_configure_max_tdls_params(psoc, vdev);
7590 		hdd_vdev_configure_usr_ps_params(psoc, vdev, link_info);
7591 		break;
7592 	case QDF_P2P_CLIENT_MODE:
7593 		hdd_vdev_configure_max_tdls_params(psoc, vdev);
7594 		hdd_vdev_configure_usr_ps_params(psoc, vdev, link_info);
7595 		break;
7596 	case QDF_NAN_DISC_MODE:
7597 		hdd_vdev_configure_nan_params(psoc, vdev);
7598 		break;
7599 	default:
7600 		break;
7601 	}
7602 
7603 	ucfg_fwol_configure_vdev_params(psoc, vdev);
7604 	hdd_set_vdev_mlo_external_sae_auth_conversion(vdev, opmode);
7605 	hdd_store_nss_chains_cfg_in_vdev(hdd_ctx, vdev);
7606 	hdd_vdev_configure_rtscts_enable(hdd_ctx, vdev);
7607 }
7608 
7609 #if defined(WLAN_FEATURE_11BE_MLO) && defined(CFG80211_11BE_BASIC) && \
7610 	defined(WLAN_HDD_MULTI_VDEV_SINGLE_NDEV)
7611 static int
hdd_populate_vdev_create_params(struct wlan_hdd_link_info * link_info,struct wlan_vdev_create_params * vdev_params)7612 hdd_populate_vdev_create_params(struct wlan_hdd_link_info *link_info,
7613 				struct wlan_vdev_create_params *vdev_params)
7614 {
7615 	struct hdd_adapter *adapter = link_info->adapter;
7616 
7617 	vdev_params->opmode = adapter->device_mode;
7618 	vdev_params->size_vdev_priv = sizeof(struct vdev_osif_priv);
7619 
7620 	if (hdd_adapter_is_ml_adapter(adapter)) {
7621 		qdf_ether_addr_copy(vdev_params->mldaddr,
7622 				    adapter->mac_addr.bytes);
7623 		qdf_ether_addr_copy(vdev_params->macaddr,
7624 				    link_info->link_addr.bytes);
7625 	} else {
7626 		qdf_ether_addr_copy(vdev_params->macaddr,
7627 				    adapter->mac_addr.bytes);
7628 	}
7629 	return 0;
7630 }
7631 #elif defined(WLAN_FEATURE_11BE_MLO) && defined(CFG80211_11BE_BASIC)
7632 static int
hdd_populate_vdev_create_params(struct wlan_hdd_link_info * link_info,struct wlan_vdev_create_params * vdev_params)7633 hdd_populate_vdev_create_params(struct wlan_hdd_link_info *link_info,
7634 				struct wlan_vdev_create_params *vdev_params)
7635 {
7636 	struct hdd_adapter *adapter = link_info->adapter;
7637 	struct hdd_mlo_adapter_info *mlo_adapter_info;
7638 	struct hdd_adapter *link_adapter;
7639 	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
7640 	bool eht_capab;
7641 
7642 	hdd_enter_dev(adapter->dev);
7643 	mlo_adapter_info = &adapter->mlo_adapter_info;
7644 
7645 	ucfg_psoc_mlme_get_11be_capab(hdd_ctx->psoc, &eht_capab);
7646 	if (mlo_adapter_info->is_ml_adapter && eht_capab &&
7647 	    adapter->device_mode == QDF_STA_MODE) {
7648 		link_adapter = hdd_get_assoc_link_adapter(adapter);
7649 		if (link_adapter) {
7650 			qdf_ether_addr_copy(vdev_params->macaddr,
7651 					    link_adapter->mac_addr.bytes);
7652 		} else {
7653 			return -EINVAL;
7654 		}
7655 	} else {
7656 		qdf_ether_addr_copy(vdev_params->macaddr,
7657 				    adapter->mac_addr.bytes);
7658 	}
7659 
7660 	vdev_params->opmode = adapter->device_mode;
7661 
7662 	if (eht_capab) {
7663 		qdf_ether_addr_copy(vdev_params->mldaddr,
7664 				    adapter->mld_addr.bytes);
7665 	}
7666 
7667 	vdev_params->size_vdev_priv = sizeof(struct vdev_osif_priv);
7668 	hdd_exit();
7669 
7670 	return 0;
7671 }
7672 #else
7673 static int
hdd_populate_vdev_create_params(struct wlan_hdd_link_info * link_info,struct wlan_vdev_create_params * vdev_params)7674 hdd_populate_vdev_create_params(struct wlan_hdd_link_info *link_info,
7675 				struct wlan_vdev_create_params *vdev_params)
7676 {
7677 	struct hdd_adapter *adapter = link_info->adapter;
7678 
7679 	vdev_params->opmode = adapter->device_mode;
7680 	qdf_ether_addr_copy(vdev_params->macaddr, adapter->mac_addr.bytes);
7681 	vdev_params->size_vdev_priv = sizeof(struct vdev_osif_priv);
7682 	return 0;
7683 }
7684 #endif
7685 
hdd_vdev_create(struct wlan_hdd_link_info * link_info)7686 int hdd_vdev_create(struct wlan_hdd_link_info *link_info)
7687 {
7688 	QDF_STATUS status;
7689 	int errno = 0;
7690 	struct hdd_adapter *adapter = link_info->adapter;
7691 	struct hdd_context *hdd_ctx;
7692 	struct wlan_objmgr_vdev *vdev;
7693 	struct wlan_vdev_create_params vdev_params = {0};
7694 
7695 	hdd_nofl_debug("creating new vdev");
7696 
7697 	/* do vdev create via objmgr */
7698 	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
7699 
7700 	errno = hdd_populate_vdev_create_params(link_info, &vdev_params);
7701 	if (errno)
7702 		return errno;
7703 
7704 	vdev = sme_vdev_create(hdd_ctx->mac_handle, &vdev_params);
7705 	if (!vdev) {
7706 		hdd_err("failed to create vdev");
7707 		return -EINVAL;
7708 	}
7709 
7710 	if (wlan_objmgr_vdev_try_get_ref(vdev, WLAN_HDD_ID_OBJ_MGR) !=
7711 	    QDF_STATUS_SUCCESS) {
7712 		errno = QDF_STATUS_E_INVAL;
7713 		sme_vdev_delete(hdd_ctx->mac_handle, vdev);
7714 		return -EINVAL;
7715 	}
7716 
7717 	hdd_store_vdev_info(link_info, vdev);
7718 	osif_cm_osif_priv_init(vdev);
7719 
7720 	if (hdd_adapter_is_ml_adapter(adapter))
7721 		hdd_mlo_t2lm_register_callback(vdev);
7722 
7723 	set_bit(SME_SESSION_OPENED, &link_info->link_flags);
7724 	status = sme_vdev_post_vdev_create_setup(hdd_ctx->mac_handle, vdev);
7725 	if (QDF_IS_STATUS_ERROR(status)) {
7726 		hdd_err("Failed to setup the vdev");
7727 		errno = qdf_status_to_os_return(status);
7728 		goto hdd_vdev_destroy_procedure;
7729 	}
7730 
7731 	/* firmware ready for component communication, raise vdev_ready event */
7732 	errno = hdd_vdev_ready(vdev,
7733 			       (struct qdf_mac_addr *)hdd_ctx->bridgeaddr);
7734 	if (errno) {
7735 		hdd_err("failed to dispatch vdev ready event: %d", errno);
7736 		goto hdd_vdev_destroy_procedure;
7737 	}
7738 
7739 	hdd_vdev_configure_opmode_params(hdd_ctx, vdev, link_info);
7740 
7741 	hdd_nofl_debug("vdev %d created successfully", link_info->vdev_id);
7742 
7743 	return errno;
7744 
7745 hdd_vdev_destroy_procedure:
7746 	QDF_BUG(!hdd_vdev_destroy(link_info));
7747 
7748 	return errno;
7749 }
7750 
hdd_init_station_mode(struct wlan_hdd_link_info * link_info)7751 QDF_STATUS hdd_init_station_mode(struct wlan_hdd_link_info *link_info)
7752 {
7753 	struct hdd_adapter *adapter = link_info->adapter;
7754 	struct hdd_context *hdd_ctx;
7755 	QDF_STATUS status;
7756 	mac_handle_t mac_handle;
7757 	uint32_t roam_triggers;
7758 	struct wlan_objmgr_vdev *vdev;
7759 
7760 	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
7761 	mac_handle = hdd_ctx->mac_handle;
7762 
7763 	vdev = hdd_objmgr_get_vdev_by_user(link_info, WLAN_INIT_DEINIT_ID);
7764 	if (!vdev) {
7765 		status = QDF_STATUS_E_NULL_VALUE;
7766 		goto vdev_destroy;
7767 	}
7768 
7769 	hdd_vdev_set_ht_vht_ies(mac_handle, vdev);
7770 	hdd_init_station_context(link_info);
7771 
7772 	status = hdd_wmm_adapter_init(adapter);
7773 	if (QDF_STATUS_SUCCESS != status) {
7774 		hdd_err("hdd_wmm_adapter_init() failed, status code %08d [x%08x]",
7775 			status, status);
7776 		goto error_wmm_init;
7777 	}
7778 	set_bit(WMM_INIT_DONE, &adapter->event_flags);
7779 
7780 	/* rcpi info initialization */
7781 	qdf_mem_zero(&adapter->rcpi, sizeof(adapter->rcpi));
7782 
7783 	if (adapter->device_mode == QDF_STA_MODE) {
7784 		roam_triggers = ucfg_mlme_get_roaming_triggers(hdd_ctx->psoc);
7785 		mlme_set_roam_trigger_bitmap(hdd_ctx->psoc,
7786 					     link_info->vdev_id,
7787 					     roam_triggers);
7788 
7789 		status = hdd_vdev_configure_rtt_params(vdev);
7790 		if (QDF_IS_STATUS_ERROR(status))
7791 			goto error_wmm_init;
7792 	}
7793 
7794 	hdd_tsf_auto_report_init(adapter);
7795 	hdd_objmgr_put_vdev_by_user(vdev, WLAN_INIT_DEINIT_ID);
7796 
7797 	return QDF_STATUS_SUCCESS;
7798 
7799 error_wmm_init:
7800 	hdd_objmgr_put_vdev_by_user(vdev, WLAN_INIT_DEINIT_ID);
7801 
7802 vdev_destroy:
7803 	QDF_BUG(!hdd_vdev_destroy(link_info));
7804 
7805 	return status;
7806 }
7807 
net_dev_ref_debug_string_from_id(wlan_net_dev_ref_dbgid dbgid)7808 static char *net_dev_ref_debug_string_from_id(wlan_net_dev_ref_dbgid dbgid)
7809 {
7810 	static const char *strings[] = {
7811 		"NET_DEV_HOLD_ID_RESERVED",
7812 		"NET_DEV_HOLD_GET_STA_CONNECTION_IN_PROGRESS",
7813 		"NET_DEV_HOLD_CHECK_DFS_CHANNEL_FOR_ADAPTER",
7814 		"NET_DEV_HOLD_GET_SAP_OPERATING_BAND",
7815 		"NET_DEV_HOLD_RECOVERY_NOTIFIER_CALL",
7816 		"NET_DEV_HOLD_IS_ANY_STA_CONNECTING",
7817 		"NET_DEV_HOLD_SAP_DESTROY_CTX_ALL",
7818 		"NET_DEV_HOLD_DRV_CMD_MAX_TX_POWER",
7819 		"NET_DEV_HOLD_IPA_SET_TX_FLOW_INFO",
7820 		"NET_DEV_HOLD_SET_RPS_CPU_MASK",
7821 		"NET_DEV_HOLD_DFS_INDICATE_RADAR",
7822 		"NET_DEV_HOLD_MAX_STA_INTERFACE_UP_COUNT_REACHED",
7823 		"NET_DEV_HOLD_IS_CHAN_SWITCH_IN_PROGRESS",
7824 		"NET_DEV_HOLD_STA_DESTROY_CTX_ALL",
7825 		"NET_DEV_HOLD_CHECK_FOR_EXISTING_MACADDR",
7826 		"NET_DEV_HOLD_DEINIT_ALL_ADAPTERS",
7827 		"NET_DEV_HOLD_STOP_ALL_ADAPTERS",
7828 		"NET_DEV_HOLD_RESET_ALL_ADAPTERS",
7829 		"NET_DEV_HOLD_IS_ANY_INTERFACE_OPEN",
7830 		"NET_DEV_HOLD_START_ALL_ADAPTERS",
7831 		"NET_DEV_HOLD_GET_ADAPTER_BY_RAND_MACADDR",
7832 		"NET_DEV_HOLD_GET_ADAPTER_BY_MACADDR",
7833 		"NET_DEV_HOLD_GET_ADAPTER_BY_VDEV",
7834 		"NET_DEV_HOLD_ADAPTER_GET_BY_REFERENCE",
7835 		"NET_DEV_HOLD_GET_ADAPTER_BY_IFACE_NAME",
7836 		"NET_DEV_HOLD_GET_ADAPTER",
7837 		"NET_DEV_HOLD_GET_OPERATING_CHAN_FREQ",
7838 		"NET_DEV_HOLD_UNREGISTER_WEXT_ALL_ADAPTERS",
7839 		"NET_DEV_HOLD_ABORT_MAC_SCAN_ALL_ADAPTERS",
7840 		"NET_DEV_HOLD_ABORT_SCHED_SCAN_ALL_ADAPTERS",
7841 		"NET_DEV_HOLD_GET_FIRST_VALID_ADAPTER",
7842 		"NET_DEV_HOLD_CLEAR_RPS_CPU_MASK",
7843 		"NET_DEV_HOLD_BUS_BW_WORK_HANDLER",
7844 		"NET_DEV_HOLD_DISPLAY_NETIF_QUEUE_HISTORY_COMPACT",
7845 		"NET_DEV_HOLD_DISPLAY_NETIF_QUEUE_HISTORY",
7846 		"NET_DEV_HOLD_CLEAR_NETIF_QUEUE_HISTORY",
7847 		"NET_DEV_HOLD_UNSAFE_CHANNEL_RESTART_SAP",
7848 		"NET_DEV_HOLD_INDICATE_MGMT_FRAME",
7849 		"NET_DEV_HOLD_STATE_INFO_DUMP",
7850 		"NET_DEV_HOLD_DISABLE_ROAMING",
7851 		"NET_DEV_HOLD_ENABLE_ROAMING",
7852 		"NET_DEV_HOLD_AUTO_SHUTDOWN_ENABLE",
7853 		"NET_DEV_HOLD_GET_CON_SAP_ADAPTER",
7854 		"NET_DEV_HOLD_IS_ANY_ADAPTER_CONNECTED",
7855 		"NET_DEV_HOLD_IS_ROAMING_IN_PROGRESS",
7856 		"NET_DEV_HOLD_DEL_P2P_INTERFACE",
7857 		"NET_DEV_HOLD_IS_NDP_ALLOWED",
7858 		"NET_DEV_HOLD_NDI_OPEN",
7859 		"NET_DEV_HOLD_SEND_OEM_REG_RSP_NLINK_MSG",
7860 		"NET_DEV_HOLD_PERIODIC_STA_STATS_DISPLAY",
7861 		"NET_DEV_HOLD_SUSPEND_WLAN",
7862 		"NET_DEV_HOLD_RESUME_WLAN",
7863 		"NET_DEV_HOLD_SSR_RESTART_SAP",
7864 		"NET_DEV_HOLD_SEND_DEFAULT_SCAN_IES",
7865 		"NET_DEV_HOLD_CFG80211_SUSPEND_WLAN",
7866 		"NET_DEV_HOLD_COUNTRY_CHANGE_UPDATE_STA",
7867 		"NET_DEV_HOLD_COUNTRY_CHANGE_UPDATE_SAP",
7868 		"NET_DEV_HOLD_CACHE_STATION_STATS_CB",
7869 		"NET_DEV_HOLD_DISPLAY_TXRX_STATS",
7870 		"NET_DEV_HOLD_START_PRE_CAC_TRANS",
7871 		"NET_DEV_HOLD_IS_ANY_STA_CONNECTED",
7872 		"NET_DEV_HOLD_GET_ADAPTER_BY_BSSID",
7873 		"NET_DEV_HOLD_ALLOW_NEW_INTF",
7874 		"NET_DEV_HOLD_ID_MAX"};
7875 	int32_t num_dbg_strings = QDF_ARRAY_SIZE(strings);
7876 
7877 	if (dbgid >= num_dbg_strings) {
7878 		char *ret = "";
7879 
7880 		hdd_err("Debug string not found for debug id %d", dbgid);
7881 		return ret;
7882 	}
7883 
7884 	return (char *)strings[dbgid];
7885 }
7886 
hdd_check_for_net_dev_ref_leak(struct hdd_adapter * adapter)7887 void hdd_check_for_net_dev_ref_leak(struct hdd_adapter *adapter)
7888 {
7889 	int i, id;
7890 
7891 	for (id = 0; id < NET_DEV_HOLD_ID_MAX; id++) {
7892 		for (i = 0; i < MAX_NET_DEV_REF_LEAK_ITERATIONS; i++) {
7893 			if (!qdf_atomic_read(
7894 				&adapter->net_dev_hold_ref_count[id]))
7895 				break;
7896 			hdd_info("net_dev held for debug id %s",
7897 				 net_dev_ref_debug_string_from_id(id));
7898 			qdf_sleep(NET_DEV_REF_LEAK_ITERATION_SLEEP_TIME_MS);
7899 		}
7900 		if (i == MAX_NET_DEV_REF_LEAK_ITERATIONS) {
7901 			hdd_err("net_dev hold reference leak detected for debug id: %s",
7902 				net_dev_ref_debug_string_from_id(id));
7903 			QDF_BUG(0);
7904 		}
7905 	}
7906 }
7907 
7908 /**
7909  * hdd_deinit_station_mode() - De-initialize the station adapter
7910  * @adapter: HDD adapter pointer
7911  *
7912  * This function De-initializes the STA/P2P/OCB adapter.
7913  *
7914  * Return: None.
7915  */
hdd_deinit_station_mode(struct hdd_adapter * adapter)7916 static void hdd_deinit_station_mode(struct hdd_adapter *adapter)
7917 {
7918 	if (test_bit(WMM_INIT_DONE, &adapter->event_flags)) {
7919 		hdd_wmm_adapter_close(adapter);
7920 		clear_bit(WMM_INIT_DONE, &adapter->event_flags);
7921 	}
7922 }
7923 
hdd_deinit_session(struct hdd_adapter * adapter)7924 void hdd_deinit_session(struct hdd_adapter *adapter)
7925 {
7926 	struct wlan_hdd_link_info *link_info;
7927 
7928 	hdd_enter();
7929 
7930 	switch (adapter->device_mode) {
7931 	case QDF_STA_MODE:
7932 	case QDF_P2P_CLIENT_MODE:
7933 	case QDF_MONITOR_MODE:
7934 	case QDF_P2P_DEVICE_MODE:
7935 	case QDF_NDI_MODE:
7936 	case QDF_NAN_DISC_MODE:
7937 	{
7938 		hdd_deinit_station_mode(adapter);
7939 		break;
7940 	}
7941 
7942 	case QDF_SAP_MODE:
7943 	case QDF_P2P_GO_MODE:
7944 	{
7945 		hdd_adapter_for_each_active_link_info(adapter, link_info)
7946 			hdd_deinit_ap_mode(link_info);
7947 		break;
7948 	}
7949 
7950 	default:
7951 		break;
7952 	}
7953 
7954 	if (adapter->scan_info.default_scan_ies) {
7955 		qdf_mem_free(adapter->scan_info.default_scan_ies);
7956 		adapter->scan_info.default_scan_ies = NULL;
7957 		adapter->scan_info.default_scan_ies_len = 0;
7958 	}
7959 
7960 	hdd_exit();
7961 }
7962 
hdd_deinit_adapter(struct hdd_context * hdd_ctx,struct hdd_adapter * adapter,bool rtnl_held)7963 void hdd_deinit_adapter(struct hdd_context *hdd_ctx,
7964 			struct hdd_adapter *adapter,
7965 			bool rtnl_held)
7966 {
7967 	hdd_enter_dev(adapter->dev);
7968 
7969 	hdd_wext_unregister(adapter->dev, rtnl_held);
7970 	hdd_deinit_session(adapter);
7971 	hdd_exit();
7972 }
7973 
7974 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0)) && \
7975      defined(WLAN_FEATURE_11AX)
7976 /**
7977  * hdd_cleanup_he_operation_info() - cleanup he operation info
7978  * @link_info: pointer to link_info struct in adapter
7979  *
7980  * This function destroys he operation information
7981  *
7982  * Return: none
7983  */
hdd_cleanup_he_operation_info(struct wlan_hdd_link_info * link_info)7984 static void hdd_cleanup_he_operation_info(struct wlan_hdd_link_info *link_info)
7985 {
7986 	struct hdd_station_ctx *hdd_sta_ctx;
7987 
7988 	hdd_debug("cleanup he operation info");
7989 
7990 	hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(link_info);
7991 
7992 	if (hdd_sta_ctx->cache_conn_info.he_operation) {
7993 		qdf_mem_free(hdd_sta_ctx->cache_conn_info.he_operation);
7994 		hdd_sta_ctx->cache_conn_info.he_operation = NULL;
7995 	}
7996 }
7997 #else
7998 static inline void
hdd_cleanup_he_operation_info(struct wlan_hdd_link_info * link_info)7999 hdd_cleanup_he_operation_info(struct wlan_hdd_link_info *link_info)
8000 {
8001 }
8002 #endif
8003 
8004 /**
8005  * hdd_cleanup_prev_ap_bcn_ie() - cleanup previous ap beacon ie
8006  * @link_info: pointer to link_info struct in adapter
8007  *
8008  * This function destroys previous ap beacon information
8009  *
8010  * Return: none
8011  */
hdd_cleanup_prev_ap_bcn_ie(struct wlan_hdd_link_info * link_info)8012 static void hdd_cleanup_prev_ap_bcn_ie(struct wlan_hdd_link_info *link_info)
8013 {
8014 	struct hdd_station_ctx *hdd_sta_ctx;
8015 	struct element_info *bcn_ie;
8016 
8017 	hdd_debug("cleanup previous ap bcn ie");
8018 
8019 	hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(link_info);
8020 	bcn_ie = &hdd_sta_ctx->conn_info.prev_ap_bcn_ie;
8021 
8022 	if (bcn_ie->ptr) {
8023 		qdf_mem_free(bcn_ie->ptr);
8024 		bcn_ie->ptr = NULL;
8025 		bcn_ie->len = 0;
8026 	}
8027 }
8028 
hdd_cleanup_conn_info(struct wlan_hdd_link_info * link_info)8029 void hdd_cleanup_conn_info(struct wlan_hdd_link_info *link_info)
8030 {
8031 	hdd_cleanup_he_operation_info(link_info);
8032 	hdd_cleanup_prev_ap_bcn_ie(link_info);
8033 }
8034 
8035 /**
8036  * hdd_sta_destroy_ctx_all() - cleanup all station contexts
8037  * @hdd_ctx: Global HDD context
8038  *
8039  * This function destroys all the station contexts
8040  *
8041  * Return: none
8042  */
hdd_sta_destroy_ctx_all(struct hdd_context * hdd_ctx)8043 static void hdd_sta_destroy_ctx_all(struct hdd_context *hdd_ctx)
8044 {
8045 	struct hdd_adapter *adapter, *next_adapter = NULL;
8046 	struct wlan_hdd_link_info *link_info;
8047 
8048 	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
8049 					   NET_DEV_HOLD_STA_DESTROY_CTX_ALL) {
8050 		if (adapter->device_mode == QDF_STA_MODE) {
8051 			hdd_adapter_for_each_link_info(adapter, link_info) {
8052 				hdd_cleanup_conn_info(link_info);
8053 			}
8054 		}
8055 		hdd_adapter_dev_put_debug(adapter,
8056 					  NET_DEV_HOLD_STA_DESTROY_CTX_ALL);
8057 	}
8058 }
8059 
8060 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 12, 0) || \
8061 	(defined CFG80211_CHANGE_NETDEV_REGISTRATION_SEMANTICS))
8062 static void
hdd_unregister_netdevice(struct hdd_adapter * adapter,struct net_device * dev)8063 hdd_unregister_netdevice(struct hdd_adapter *adapter, struct net_device *dev)
8064 {
8065 	if (adapter->is_virtual_iface) {
8066 		wlan_cfg80211_unregister_netdevice(dev);
8067 		adapter->is_virtual_iface = false;
8068 	} else {
8069 		unregister_netdevice(dev);
8070 	}
8071 }
8072 #else
8073 static void
hdd_unregister_netdevice(struct hdd_adapter * adapter,struct net_device * dev)8074 hdd_unregister_netdevice(struct hdd_adapter *adapter, struct net_device *dev)
8075 {
8076 	unregister_netdevice(dev);
8077 }
8078 #endif
8079 
hdd_adapter_destroy_vdev_info(struct hdd_adapter * adapter)8080 static inline void hdd_adapter_destroy_vdev_info(struct hdd_adapter *adapter)
8081 {
8082 	struct wlan_hdd_link_info *link_info;
8083 
8084 	hdd_adapter_for_each_link_info(adapter, link_info) {
8085 		qdf_event_destroy(&link_info->acs_complete_event);
8086 		qdf_spinlock_destroy(&link_info->vdev_lock);
8087 	}
8088 }
8089 
hdd_cleanup_adapter(struct hdd_context * hdd_ctx,struct hdd_adapter * adapter,bool rtnl_held)8090 static void hdd_cleanup_adapter(struct hdd_context *hdd_ctx,
8091 				struct hdd_adapter *adapter,
8092 				bool rtnl_held)
8093 {
8094 	struct net_device *dev = NULL;
8095 
8096 	if (adapter)
8097 		dev = adapter->dev;
8098 	else {
8099 		hdd_err("adapter is Null");
8100 		return;
8101 	}
8102 
8103 	hdd_apf_context_destroy(adapter);
8104 	qdf_spinlock_destroy(&adapter->mc_list_lock);
8105 	hdd_adapter_destroy_vdev_info(adapter);
8106 	hdd_sta_info_deinit(&adapter->sta_info_list);
8107 	hdd_sta_info_deinit(&adapter->cache_sta_info_list);
8108 
8109 	wlan_hdd_debugfs_csr_deinit(adapter);
8110 
8111 	hdd_debugfs_exit(adapter);
8112 
8113 	/*
8114 	 * The adapter is marked as closed. When hdd_wlan_exit() call returns,
8115 	 * the driver is almost closed and cannot handle either control
8116 	 * messages or data. However, unregister_netdevice() call above will
8117 	 * eventually invoke hdd_stop(ndo_close) driver callback, which attempts
8118 	 * to close the active connections(basically excites control path) which
8119 	 * is not right. Setting this flag helps hdd_stop() to recognize that
8120 	 * the interface is closed and restricts any operations on that
8121 	 */
8122 	clear_bit(DEVICE_IFACE_OPENED, &adapter->event_flags);
8123 
8124 	if (test_bit(NET_DEVICE_REGISTERED, &adapter->event_flags)) {
8125 		if (rtnl_held) {
8126 			hdd_debug("hdd_unregister_netdevice(%s) type:%d",
8127 				  dev->name, adapter->device_mode);
8128 			hdd_unregister_netdevice(adapter, dev);
8129 		} else {
8130 			hdd_debug("unregister_netdev(%s) type:%d", dev->name,
8131 				  adapter->device_mode);
8132 			unregister_netdev(dev);
8133 		}
8134 		/*
8135 		 * Note that the adapter is no longer valid at this point
8136 		 * since the memory has been reclaimed
8137 		 */
8138 	}
8139 }
8140 
hdd_check_for_existing_macaddr(struct hdd_context * hdd_ctx,tSirMacAddr mac_addr)8141 static QDF_STATUS hdd_check_for_existing_macaddr(struct hdd_context *hdd_ctx,
8142 						 tSirMacAddr mac_addr)
8143 {
8144 	struct hdd_adapter *adapter, *next_adapter = NULL;
8145 	wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_CHECK_FOR_EXISTING_MACADDR;
8146 
8147 	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
8148 					   dbgid) {
8149 		if (!qdf_mem_cmp(adapter->mac_addr.bytes,
8150 				 mac_addr, sizeof(tSirMacAddr))) {
8151 			hdd_adapter_dev_put_debug(adapter, dbgid);
8152 			if (next_adapter)
8153 				hdd_adapter_dev_put_debug(next_adapter,
8154 							  dbgid);
8155 			return QDF_STATUS_E_FAILURE;
8156 		}
8157 		hdd_adapter_dev_put_debug(adapter, dbgid);
8158 	}
8159 
8160 	return QDF_STATUS_SUCCESS;
8161 }
8162 
8163 /**
8164  * hdd_configure_chain_mask() - programs chain mask to firmware
8165  * @adapter: HDD adapter
8166  *
8167  * Return: 0 on success or errno on failure
8168  */
hdd_configure_chain_mask(struct hdd_adapter * adapter)8169 static int hdd_configure_chain_mask(struct hdd_adapter *adapter)
8170 {
8171 	QDF_STATUS status;
8172 	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
8173 
8174 	status = ucfg_mlme_configure_chain_mask(hdd_ctx->psoc,
8175 						adapter->deflink->vdev_id);
8176 	if (QDF_IS_STATUS_ERROR(status))
8177 		goto error;
8178 
8179 	return 0;
8180 
8181 error:
8182 	hdd_debug("WMI PDEV set param failed");
8183 	return -EINVAL;
8184 }
8185 
hdd_adapter_update_mlo_mgr_mac_addr(struct hdd_adapter * adapter)8186 void hdd_adapter_update_mlo_mgr_mac_addr(struct hdd_adapter *adapter)
8187 {
8188 	int i = 0;
8189 	struct wlan_hdd_link_info *link_info;
8190 	struct wlan_mlo_link_mac_update link_mac = {0};
8191 
8192 	if (!hdd_adapter_is_ml_adapter(adapter))
8193 		return;
8194 
8195 	hdd_adapter_for_each_link_info(adapter, link_info) {
8196 		link_mac.link_mac_info[i].vdev_id = link_info->vdev_id;
8197 		qdf_copy_macaddr(&link_mac.link_mac_info[i++].link_mac_addr,
8198 				 &link_info->link_addr);
8199 	}
8200 
8201 	link_mac.num_mac_update = i;
8202 	mlo_mgr_update_link_info_mac_addr(adapter->deflink->vdev, &link_mac);
8203 }
8204 
8205 #ifdef FEATURE_COEX
8206 /**
8207  * hdd_send_coex_config_params() - Send coex config params to FW
8208  * @hdd_ctx: HDD context
8209  * @adapter: Primary adapter context
8210  *
8211  * This function is used to send all coex config related params to FW
8212  *
8213  * Return: 0 on success and -EINVAL on failure
8214  */
hdd_send_coex_config_params(struct hdd_context * hdd_ctx,struct hdd_adapter * adapter)8215 static int hdd_send_coex_config_params(struct hdd_context *hdd_ctx,
8216 				       struct hdd_adapter *adapter)
8217 {
8218 	struct wlan_objmgr_vdev *vdev;
8219 	struct coex_config_params coex_cfg_params = {0};
8220 	struct coex_multi_config *coex_multi_cfg = NULL;
8221 	struct wlan_fwol_coex_config config = {0};
8222 	struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc;
8223 	enum coex_btc_chain_mode btc_chain_mode;
8224 	QDF_STATUS status;
8225 	uint32_t i = 0;
8226 
8227 	if (!adapter) {
8228 		hdd_err("adapter is invalid");
8229 		goto err;
8230 	}
8231 
8232 	if (!psoc) {
8233 		hdd_err("HDD psoc is invalid");
8234 		goto err;
8235 	}
8236 
8237 	status = ucfg_fwol_get_coex_config_params(psoc, &config);
8238 	if (QDF_IS_STATUS_ERROR(status)) {
8239 		hdd_err("Unable to get coex config params");
8240 		goto err;
8241 	}
8242 
8243 	coex_multi_cfg = qdf_mem_malloc(sizeof(*coex_multi_cfg));
8244 	if (!coex_multi_cfg)
8245 		goto err;
8246 
8247 	coex_multi_cfg->vdev_id = adapter->deflink->vdev_id;
8248 
8249 	coex_multi_cfg->cfg_items[i].config_type = WMI_COEX_CONFIG_TX_POWER;
8250 	coex_multi_cfg->cfg_items[i].config_arg1 = config.max_tx_power_for_btc;
8251 
8252 	wma_nofl_debug("TXP[W][send_coex_cfg]: %d",
8253 		       config.max_tx_power_for_btc);
8254 
8255 	if (++i > COEX_MULTI_CONFIG_MAX_CNT)
8256 		goto err;
8257 
8258 	coex_multi_cfg->cfg_items[i].config_type =
8259 					WMI_COEX_CONFIG_HANDOVER_RSSI;
8260 	coex_multi_cfg->cfg_items[i].config_arg1 =
8261 					config.wlan_low_rssi_threshold;
8262 
8263 	if (++i > COEX_MULTI_CONFIG_MAX_CNT)
8264 		goto err;
8265 
8266 	coex_multi_cfg->cfg_items[i].config_type = WMI_COEX_CONFIG_BTC_MODE;
8267 
8268 	/* Modify BTC_MODE according to BTC_CHAIN_MODE */
8269 	status = ucfg_coex_psoc_get_btc_chain_mode(psoc, &btc_chain_mode);
8270 	if (QDF_IS_STATUS_ERROR(status)) {
8271 		hdd_err("Failed to get btc chain mode");
8272 		btc_chain_mode = WLAN_COEX_BTC_CHAIN_MODE_UNSETTLED;
8273 	}
8274 
8275 	if (btc_chain_mode <= WLAN_COEX_BTC_CHAIN_MODE_HYBRID)
8276 		coex_multi_cfg->cfg_items[i].config_arg1 = btc_chain_mode;
8277 	else
8278 		coex_multi_cfg->cfg_items[i].config_arg1 = config.btc_mode;
8279 
8280 	hdd_debug("Configured BTC mode is %d, BTC chain mode is 0x%x, set BTC mode to %d",
8281 		  config.btc_mode, btc_chain_mode,
8282 		  coex_multi_cfg->cfg_items[i].config_arg1);
8283 
8284 	if (++i > COEX_MULTI_CONFIG_MAX_CNT)
8285 		goto err;
8286 
8287 	coex_multi_cfg->cfg_items[i].config_type =
8288 				WMI_COEX_CONFIG_ANTENNA_ISOLATION;
8289 	coex_multi_cfg->cfg_items[i].config_arg1 = config.antenna_isolation;
8290 	if (++i > COEX_MULTI_CONFIG_MAX_CNT)
8291 		goto err;
8292 
8293 	coex_multi_cfg->cfg_items[i].config_type =
8294 				WMI_COEX_CONFIG_BT_LOW_RSSI_THRESHOLD;
8295 	coex_multi_cfg->cfg_items[i].config_arg1 = config.bt_low_rssi_threshold;
8296 
8297 	if (++i > COEX_MULTI_CONFIG_MAX_CNT)
8298 		goto err;
8299 
8300 	coex_multi_cfg->cfg_items[i].config_type =
8301 				WMI_COEX_CONFIG_BT_INTERFERENCE_LEVEL;
8302 	coex_multi_cfg->cfg_items[i].config_arg1 =
8303 				config.bt_interference_low_ll;
8304 	coex_multi_cfg->cfg_items[i].config_arg2 =
8305 				config.bt_interference_low_ul;
8306 	coex_multi_cfg->cfg_items[i].config_arg3 =
8307 				config.bt_interference_medium_ll;
8308 	coex_multi_cfg->cfg_items[i].config_arg4 =
8309 				config.bt_interference_medium_ul;
8310 	coex_multi_cfg->cfg_items[i].config_arg5 =
8311 				config.bt_interference_high_ll;
8312 	coex_multi_cfg->cfg_items[i].config_arg6 =
8313 				config.bt_interference_high_ul;
8314 
8315 	if (++i > COEX_MULTI_CONFIG_MAX_CNT)
8316 		goto err;
8317 
8318 	if (wlan_hdd_mpta_helper_enable(&coex_cfg_params, &config))
8319 		goto err;
8320 
8321 	coex_multi_cfg->cfg_items[i].config_type =
8322 				WMI_COEX_CONFIG_BT_SCO_ALLOW_WLAN_2G_SCAN;
8323 	coex_multi_cfg->cfg_items[i].config_arg1 =
8324 				config.bt_sco_allow_wlan_2g_scan;
8325 
8326 	if (++i > COEX_MULTI_CONFIG_MAX_CNT)
8327 		goto err;
8328 
8329 	coex_multi_cfg->cfg_items[i].config_type =
8330 				WMI_COEX_CONFIG_LE_SCAN_POLICY;
8331 	coex_multi_cfg->cfg_items[i].config_arg1 = config.ble_scan_coex_policy;
8332 
8333 	if (++i > COEX_MULTI_CONFIG_MAX_CNT)
8334 		goto err;
8335 
8336 #ifdef FEATURE_COEX_TPUT_SHAPING_CONFIG
8337 	coex_multi_cfg->cfg_items[i].config_type =
8338 				WMI_COEX_CONFIG_ENABLE_TPUT_SHAPING;
8339 	coex_multi_cfg->cfg_items[i].config_arg1 =
8340 				config.coex_tput_shaping_enable;
8341 
8342 	if (++i > COEX_MULTI_CONFIG_MAX_CNT)
8343 		goto err;
8344 #endif
8345 
8346 	coex_multi_cfg->num_configs = i;
8347 
8348 	vdev = hdd_objmgr_get_vdev_by_user(adapter->deflink, WLAN_COEX_ID);
8349 	if (!vdev) {
8350 		hdd_err("vdev is null");
8351 		goto err;
8352 	}
8353 
8354 	ucfg_coex_send_multi_config(vdev, coex_multi_cfg);
8355 
8356 	hdd_objmgr_put_vdev_by_user(vdev, WLAN_COEX_ID);
8357 	qdf_mem_free(coex_multi_cfg);
8358 
8359 	return 0;
8360 err:
8361 	qdf_mem_free(coex_multi_cfg);
8362 	return -EINVAL;
8363 }
8364 #else
8365 /**
8366  * hdd_send_coex_config_params() - Send coex config params to FW
8367  * @hdd_ctx: HDD context
8368  * @adapter: Primary adapter context
8369  *
8370  * This function is used to send all coex config related params to FW
8371  *
8372  * Return: 0 on success and -EINVAL on failure
8373  */
hdd_send_coex_config_params(struct hdd_context * hdd_ctx,struct hdd_adapter * adapter)8374 static int hdd_send_coex_config_params(struct hdd_context *hdd_ctx,
8375 				       struct hdd_adapter *adapter)
8376 {
8377 	struct coex_config_params coex_cfg_params = {0};
8378 	struct wlan_fwol_coex_config config = {0};
8379 	struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc;
8380 	enum coex_btc_chain_mode btc_chain_mode;
8381 	QDF_STATUS status;
8382 
8383 	if (!adapter) {
8384 		hdd_err("adapter is invalid");
8385 		goto err;
8386 	}
8387 
8388 	if (!psoc) {
8389 		hdd_err("HDD psoc is invalid");
8390 		goto err;
8391 	}
8392 
8393 	status = ucfg_fwol_get_coex_config_params(psoc, &config);
8394 	if (QDF_IS_STATUS_ERROR(status)) {
8395 		hdd_err("Unable to get coex config params");
8396 		goto err;
8397 	}
8398 
8399 	coex_cfg_params.vdev_id = adapter->deflink->vdev_id;
8400 	coex_cfg_params.config_type = WMI_COEX_CONFIG_TX_POWER;
8401 	coex_cfg_params.config_arg1 = config.max_tx_power_for_btc;
8402 
8403 	wma_nofl_debug("TXP[W][send_coex_cfg]: %d",
8404 		       config.max_tx_power_for_btc);
8405 
8406 	status = sme_send_coex_config_cmd(&coex_cfg_params);
8407 	if (QDF_IS_STATUS_ERROR(status)) {
8408 		hdd_err("Failed to send coex Tx power");
8409 		goto err;
8410 	}
8411 
8412 	coex_cfg_params.config_type = WMI_COEX_CONFIG_HANDOVER_RSSI;
8413 	coex_cfg_params.config_arg1 = config.wlan_low_rssi_threshold;
8414 
8415 	status = sme_send_coex_config_cmd(&coex_cfg_params);
8416 	if (QDF_IS_STATUS_ERROR(status)) {
8417 		hdd_err("Failed to send coex handover RSSI");
8418 		goto err;
8419 	}
8420 
8421 	coex_cfg_params.config_type = WMI_COEX_CONFIG_BTC_MODE;
8422 
8423 	/* Modify BTC_MODE according to BTC_CHAIN_MODE */
8424 	status = ucfg_coex_psoc_get_btc_chain_mode(psoc, &btc_chain_mode);
8425 	if (QDF_IS_STATUS_ERROR(status)) {
8426 		hdd_err("Failed to get btc chain mode");
8427 		btc_chain_mode = WLAN_COEX_BTC_CHAIN_MODE_UNSETTLED;
8428 	}
8429 
8430 	if (btc_chain_mode <= WLAN_COEX_BTC_CHAIN_MODE_HYBRID)
8431 		coex_cfg_params.config_arg1 = btc_chain_mode;
8432 	else
8433 		coex_cfg_params.config_arg1 = config.btc_mode;
8434 
8435 	hdd_debug("Configured BTC mode is %d, BTC chain mode is 0x%x, set BTC mode to %d",
8436 		  config.btc_mode, btc_chain_mode,
8437 		  coex_cfg_params.config_arg1);
8438 	status = sme_send_coex_config_cmd(&coex_cfg_params);
8439 	if (QDF_IS_STATUS_ERROR(status)) {
8440 		hdd_err("Failed to send coex BTC mode");
8441 		goto err;
8442 	}
8443 
8444 	coex_cfg_params.config_type = WMI_COEX_CONFIG_ANTENNA_ISOLATION;
8445 	coex_cfg_params.config_arg1 = config.antenna_isolation;
8446 
8447 	status = sme_send_coex_config_cmd(&coex_cfg_params);
8448 	if (QDF_IS_STATUS_ERROR(status)) {
8449 		hdd_err("Failed to send coex antenna isolation");
8450 		goto err;
8451 	}
8452 
8453 	coex_cfg_params.config_type = WMI_COEX_CONFIG_BT_LOW_RSSI_THRESHOLD;
8454 	coex_cfg_params.config_arg1 = config.bt_low_rssi_threshold;
8455 
8456 	status = sme_send_coex_config_cmd(&coex_cfg_params);
8457 	if (QDF_IS_STATUS_ERROR(status)) {
8458 		hdd_err("Failed to send coex BT low RSSI threshold");
8459 		goto err;
8460 	}
8461 
8462 	coex_cfg_params.config_type = WMI_COEX_CONFIG_BT_INTERFERENCE_LEVEL;
8463 	coex_cfg_params.config_arg1 = config.bt_interference_low_ll;
8464 	coex_cfg_params.config_arg2 = config.bt_interference_low_ul;
8465 	coex_cfg_params.config_arg3 = config.bt_interference_medium_ll;
8466 	coex_cfg_params.config_arg4 = config.bt_interference_medium_ul;
8467 	coex_cfg_params.config_arg5 = config.bt_interference_high_ll;
8468 	coex_cfg_params.config_arg6 = config.bt_interference_high_ul;
8469 
8470 	status = sme_send_coex_config_cmd(&coex_cfg_params);
8471 	if (QDF_IS_STATUS_ERROR(status)) {
8472 		hdd_err("Failed to send coex BT interference level");
8473 		goto err;
8474 	}
8475 
8476 	if (wlan_hdd_mpta_helper_enable(&coex_cfg_params, &config))
8477 		goto err;
8478 
8479 	coex_cfg_params.config_type =
8480 				WMI_COEX_CONFIG_BT_SCO_ALLOW_WLAN_2G_SCAN;
8481 	coex_cfg_params.config_arg1 = config.bt_sco_allow_wlan_2g_scan;
8482 
8483 	status = sme_send_coex_config_cmd(&coex_cfg_params);
8484 	if (QDF_IS_STATUS_ERROR(status)) {
8485 		hdd_err("Failed to send coex BT sco allow wlan 2g scan");
8486 		goto err;
8487 	}
8488 
8489 	coex_cfg_params.config_type =
8490 				WMI_COEX_CONFIG_LE_SCAN_POLICY;
8491 	coex_cfg_params.config_arg1 = config.ble_scan_coex_policy;
8492 
8493 	status = sme_send_coex_config_cmd(&coex_cfg_params);
8494 	if (QDF_IS_STATUS_ERROR(status)) {
8495 		hdd_err("Failed to send coex BLE scan policy");
8496 		goto err;
8497 	}
8498 
8499 #ifdef FEATURE_COEX_TPUT_SHAPING_CONFIG
8500 	coex_cfg_params.config_type =
8501 				WMI_COEX_CONFIG_ENABLE_TPUT_SHAPING;
8502 	coex_cfg_params.config_arg1 = config.coex_tput_shaping_enable;
8503 
8504 	status = sme_send_coex_config_cmd(&coex_cfg_params);
8505 	if (QDF_IS_STATUS_ERROR(status)) {
8506 		hdd_err("Failed to send coex traffic shaping value %d",
8507 			coex_cfg_params.config_arg1);
8508 		goto err;
8509 	}
8510 #endif
8511 	return 0;
8512 err:
8513 	return -EINVAL;
8514 }
8515 #endif
8516 
8517 /**
8518  * hdd_send_coex_traffic_shaping_mode() - Send coex traffic shaping mode
8519  * to FW
8520  * @vdev_id: vdev ID
8521  * @mode: traffic shaping mode
8522  *
8523  * This function is used to send coex traffic shaping mode to FW
8524  *
8525  * Return: 0 on success and -EINVAL on failure
8526  */
hdd_send_coex_traffic_shaping_mode(uint8_t vdev_id,uint8_t mode)8527 int hdd_send_coex_traffic_shaping_mode(uint8_t vdev_id, uint8_t mode)
8528 {
8529 	struct coex_config_params coex_cfg_params = {0};
8530 
8531 	coex_cfg_params.config_type = WMI_COEX_SET_TRAFFIC_SHAPING_MODE;
8532 	coex_cfg_params.config_arg1 = mode;
8533 	coex_cfg_params.vdev_id     = vdev_id;
8534 
8535 	if (QDF_IS_STATUS_ERROR(sme_send_coex_config_cmd(&coex_cfg_params))) {
8536 		hdd_err_rl("Failed to send coex traffic shaping mode");
8537 		return -EINVAL;
8538 	}
8539 	return 0;
8540 }
8541 
8542 #define MAX_PDEV_SET_FW_PARAMS 7
8543 /* params being sent:
8544  * 1.wmi_pdev_param_dtim_synth
8545  * 2.wmi_pdev_param_1ch_dtim_optimized_chain_selection
8546  * 3.wmi_pdev_param_tx_sch_delay
8547  * 4.wmi_pdev_param_en_update_scram_seed
8548  * 5.wmi_pdev_param_secondary_retry_enable
8549  * 6.wmi_pdev_param_set_sap_xlna_bypass
8550  * 7.wmi_pdev_param_set_dfs_chan_ageout_time
8551  */
8552 
8553 /**
8554  * hdd_set_fw_params() - Set parameters to firmware
8555  * @adapter: HDD adapter
8556  *
8557  * This function Sets various parameters to fw once the
8558  * adapter is started.
8559  *
8560  * Return: 0 on success or errno on failure
8561  */
hdd_set_fw_params(struct hdd_adapter * adapter)8562 int hdd_set_fw_params(struct hdd_adapter *adapter)
8563 {
8564 	int ret;
8565 	uint16_t upper_brssi_thresh, lower_brssi_thresh;
8566 	bool enable_dtim_1chrx;
8567 	QDF_STATUS status;
8568 	struct hdd_context *hdd_ctx;
8569 	bool is_lprx_enabled;
8570 	bool bval = false;
8571 	uint8_t enable_tx_sch_delay, dfs_chan_ageout_time;
8572 	uint32_t dtim_sel_diversity, enable_secondary_rate;
8573 	bool sap_xlna_bypass;
8574 	bool enable_ofdm_scrambler_seed = false;
8575 	struct dev_set_param setparam[MAX_PDEV_SET_FW_PARAMS] = { };
8576 	uint8_t index = 0;
8577 
8578 	hdd_enter_dev(adapter->dev);
8579 
8580 	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
8581 	if (!hdd_ctx)
8582 		return -EINVAL;
8583 
8584 	if (cds_get_conparam() == QDF_GLOBAL_FTM_MODE) {
8585 		hdd_debug("FTM Mode is active; nothing to do");
8586 		return 0;
8587 	}
8588 
8589 	/* The ini gEnableLPRx is deprecated. By default, the ini
8590 	 * is enabled. So, making the variable is_lprx_enabled true.
8591 	 */
8592 	is_lprx_enabled = true;
8593 
8594 	ret = mlme_check_index_setparam(setparam, wmi_pdev_param_dtim_synth,
8595 					is_lprx_enabled, index++,
8596 					MAX_PDEV_SET_FW_PARAMS);
8597 	if (QDF_IS_STATUS_ERROR(ret))
8598 		goto error;
8599 
8600 	ucfg_mlme_get_dtim_selection_diversity(hdd_ctx->psoc,
8601 					       &dtim_sel_diversity);
8602 	ret = mlme_check_index_setparam(
8603 			setparam,
8604 			wmi_pdev_param_1ch_dtim_optimized_chain_selection,
8605 			dtim_sel_diversity, index++, MAX_PDEV_SET_FW_PARAMS);
8606 	if (QDF_IS_STATUS_ERROR(ret))
8607 		goto error;
8608 
8609 	if (QDF_IS_STATUS_SUCCESS(ucfg_fwol_get_enable_tx_sch_delay(
8610 				  hdd_ctx->psoc, &enable_tx_sch_delay))) {
8611 		ret = mlme_check_index_setparam(
8612 					      setparam,
8613 					      wmi_pdev_param_tx_sch_delay,
8614 					      enable_tx_sch_delay, index++,
8615 					      MAX_PDEV_SET_FW_PARAMS);
8616 		if (QDF_IS_STATUS_ERROR(ret))
8617 			goto error;
8618 	}
8619 
8620 	if (QDF_IS_STATUS_SUCCESS(ucfg_fwol_get_ofdm_scrambler_seed(
8621 				hdd_ctx->psoc, &enable_ofdm_scrambler_seed))) {
8622 		ret = mlme_check_index_setparam(
8623 					setparam,
8624 					wmi_pdev_param_en_update_scram_seed,
8625 					enable_ofdm_scrambler_seed, index++,
8626 					MAX_PDEV_SET_FW_PARAMS);
8627 		if (QDF_IS_STATUS_ERROR(ret))
8628 			goto error;
8629 	}
8630 
8631 	if (QDF_IS_STATUS_SUCCESS(ucfg_fwol_get_enable_secondary_rate(
8632 				  hdd_ctx->psoc, &enable_secondary_rate))) {
8633 		ret = mlme_check_index_setparam(
8634 					setparam,
8635 					wmi_pdev_param_secondary_retry_enable,
8636 					enable_secondary_rate, index++,
8637 					MAX_PDEV_SET_FW_PARAMS);
8638 		if (QDF_IS_STATUS_ERROR(ret))
8639 			goto error;
8640 	}
8641 	if (QDF_IS_STATUS_SUCCESS(ucfg_fwol_get_sap_xlna_bypass(
8642 				  hdd_ctx->psoc, &sap_xlna_bypass))) {
8643 		ret = mlme_check_index_setparam(
8644 					setparam,
8645 					wmi_pdev_param_set_sap_xlna_bypass,
8646 					sap_xlna_bypass, index++,
8647 					MAX_PDEV_SET_FW_PARAMS);
8648 		if (QDF_IS_STATUS_ERROR(ret))
8649 			goto error;
8650 	}
8651 	wlan_mlme_get_dfs_chan_ageout_time(hdd_ctx->psoc,
8652 					   &dfs_chan_ageout_time);
8653 	ret = mlme_check_index_setparam(
8654 				      setparam,
8655 				      wmi_pdev_param_set_dfs_chan_ageout_time,
8656 				      dfs_chan_ageout_time, index++,
8657 				      MAX_PDEV_SET_FW_PARAMS);
8658 	if (QDF_IS_STATUS_ERROR(ret))
8659 		goto error;
8660 
8661 	ret = sme_send_multi_pdev_vdev_set_params(MLME_PDEV_SETPARAM,
8662 						  WMI_PDEV_ID_SOC, setparam,
8663 						  index);
8664 	if (QDF_IS_STATUS_ERROR(ret)) {
8665 		goto error;
8666 	}
8667 	if (adapter->device_mode == QDF_STA_MODE) {
8668 		status = ucfg_get_upper_brssi_thresh(hdd_ctx->psoc,
8669 						     &upper_brssi_thresh);
8670 		if (QDF_IS_STATUS_ERROR(status))
8671 			return -EINVAL;
8672 
8673 		sme_set_smps_cfg(adapter->deflink->vdev_id,
8674 				 HDD_STA_SMPS_PARAM_UPPER_BRSSI_THRESH,
8675 				 upper_brssi_thresh);
8676 
8677 		status = ucfg_get_lower_brssi_thresh(hdd_ctx->psoc,
8678 						     &lower_brssi_thresh);
8679 		if (QDF_IS_STATUS_ERROR(status))
8680 			return -EINVAL;
8681 
8682 		sme_set_smps_cfg(adapter->deflink->vdev_id,
8683 				 HDD_STA_SMPS_PARAM_LOWER_BRSSI_THRESH,
8684 				 lower_brssi_thresh);
8685 
8686 		status = ucfg_get_enable_dtim_1chrx(hdd_ctx->psoc,
8687 						    &enable_dtim_1chrx);
8688 		if (QDF_IS_STATUS_ERROR(status))
8689 			return -EINVAL;
8690 
8691 		sme_set_smps_cfg(adapter->deflink->vdev_id,
8692 				 HDD_STA_SMPS_PARAM_DTIM_1CHRX_ENABLE,
8693 				 enable_dtim_1chrx);
8694 	}
8695 
8696 	status = ucfg_mlme_get_vht_enable2x2(hdd_ctx->psoc, &bval);
8697 	if (!QDF_IS_STATUS_SUCCESS(status))
8698 		hdd_err("unable to get vht_enable2x2");
8699 
8700 	if (bval) {
8701 		hdd_debug("configuring 2x2 mode fw params");
8702 
8703 		ret = sme_set_cck_tx_fir_override(hdd_ctx->mac_handle,
8704 						  adapter->deflink->vdev_id);
8705 		if (ret) {
8706 			hdd_err("wmi_pdev_param_enable_cck_tfir_override set failed %d",
8707 				ret);
8708 			goto error;
8709 		}
8710 
8711 		hdd_configure_chain_mask(adapter);
8712 	} else {
8713 #define HDD_DTIM_1CHAIN_RX_ID 0x5
8714 #define HDD_SMPS_PARAM_VALUE_S 29
8715 		hdd_debug("configuring 1x1 mode fw params");
8716 
8717 		/*
8718 		 * Disable DTIM 1 chain Rx when in 1x1,
8719 		 * we are passing two value
8720 		 * as param_id << 29 | param_value.
8721 		 * Below param_value = 0(disable)
8722 		 */
8723 		ret = sme_cli_set_command(adapter->deflink->vdev_id,
8724 					  WMI_STA_SMPS_PARAM_CMDID,
8725 					  HDD_DTIM_1CHAIN_RX_ID <<
8726 					  HDD_SMPS_PARAM_VALUE_S,
8727 					  VDEV_CMD);
8728 		if (ret) {
8729 			hdd_err("DTIM 1 chain set failed %d", ret);
8730 			goto error;
8731 		}
8732 
8733 #undef HDD_DTIM_1CHAIN_RX_ID
8734 #undef HDD_SMPS_PARAM_VALUE_S
8735 
8736 		hdd_configure_chain_mask(adapter);
8737 	}
8738 
8739 	ret = sme_set_enable_mem_deep_sleep(hdd_ctx->mac_handle,
8740 					    adapter->deflink->vdev_id);
8741 	if (ret) {
8742 		hdd_err("wmi_pdev_param_hyst_en set failed %d", ret);
8743 		goto error;
8744 	}
8745 
8746 	if (!hdd_ctx->is_fw_dbg_log_levels_configured) {
8747 		hdd_set_fw_log_params(hdd_ctx, adapter->deflink->vdev_id);
8748 		hdd_ctx->is_fw_dbg_log_levels_configured = true;
8749 	}
8750 
8751 	ret = hdd_send_coex_config_params(hdd_ctx, adapter);
8752 	if (ret) {
8753 		hdd_warn("Error initializing coex config params");
8754 		goto error;
8755 	}
8756 
8757 	hdd_exit();
8758 
8759 	return 0;
8760 
8761 error:
8762 	return -EINVAL;
8763 }
8764 
8765 /**
8766  * hdd_init_completion() - Initialize Completion Variables
8767  * @adapter: HDD adapter
8768  *
8769  * This function Initialize the completion variables for
8770  * a particular adapter
8771  *
8772  * Return: None
8773  */
hdd_init_completion(struct hdd_adapter * adapter)8774 static void hdd_init_completion(struct hdd_adapter *adapter)
8775 {
8776 	init_completion(&adapter->disconnect_comp_var);
8777 	init_completion(&adapter->linkup_event_var);
8778 	init_completion(&adapter->lfr_fw_status.disable_lfr_event);
8779 }
8780 
hdd_reset_locally_admin_bit(struct hdd_context * hdd_ctx,tSirMacAddr mac_addr)8781 static void hdd_reset_locally_admin_bit(struct hdd_context *hdd_ctx,
8782 					tSirMacAddr mac_addr)
8783 {
8784 	int i;
8785 	/*
8786 	 * Reset locally administered bit for dynamic_mac_list
8787 	 * also as while releasing the MAC address for any
8788 	 * interface mac will be compared with dynamic mac list
8789 	 */
8790 	for (i = 0; i < QDF_MAX_CONCURRENCY_PERSONA; i++) {
8791 		if (!qdf_mem_cmp(
8792 			mac_addr,
8793 			 &hdd_ctx->
8794 				dynamic_mac_list[i].dynamic_mac.bytes[0],
8795 				sizeof(struct qdf_mac_addr))) {
8796 			WLAN_HDD_RESET_LOCALLY_ADMINISTERED_BIT(
8797 				hdd_ctx->
8798 					dynamic_mac_list[i].dynamic_mac.bytes);
8799 			break;
8800 		}
8801 	}
8802 	/*
8803 	 * Reset locally administered bit if the device mode is
8804 	 * STA
8805 	 */
8806 	WLAN_HDD_RESET_LOCALLY_ADMINISTERED_BIT(mac_addr);
8807 	hdd_debug("locally administered bit reset in sta mode: "
8808 		 QDF_MAC_ADDR_FMT, QDF_MAC_ADDR_REF(mac_addr));
8809 }
8810 
wlan_hdd_cfg80211_scan_block_cb(struct work_struct * work)8811 static void wlan_hdd_cfg80211_scan_block_cb(struct work_struct *work)
8812 {
8813 	struct hdd_adapter *adapter =
8814 		container_of(work, struct hdd_adapter, scan_block_work);
8815 	struct osif_vdev_sync *vdev_sync;
8816 
8817 	if (osif_vdev_sync_op_start(adapter->dev, &vdev_sync))
8818 		return;
8819 
8820 	wlan_hdd_cfg80211_scan_block(adapter);
8821 
8822 	osif_vdev_sync_op_stop(vdev_sync);
8823 }
8824 
8825 #if defined(WLAN_FEATURE_11BE_MLO) && \
8826 	defined(WLAN_HDD_MULTI_VDEV_SINGLE_NDEV)
8827 static inline void
wlan_hdd_set_ml_cap_for_sap_intf(struct hdd_adapter_create_param * create_params,enum QDF_OPMODE mode)8828 wlan_hdd_set_ml_cap_for_sap_intf(struct hdd_adapter_create_param *create_params,
8829 				 enum QDF_OPMODE mode)
8830 {
8831 	if (mode != QDF_SAP_MODE)
8832 		return;
8833 
8834 	create_params->is_ml_adapter = true;
8835 }
8836 #elif defined(WLAN_FEATURE_11BE_MLO)
8837 static inline void
wlan_hdd_set_ml_cap_for_sap_intf(struct hdd_adapter_create_param * create_params,enum QDF_OPMODE mode)8838 wlan_hdd_set_ml_cap_for_sap_intf(struct hdd_adapter_create_param *create_params,
8839 				 enum QDF_OPMODE mode)
8840 {
8841 	if (mode != QDF_SAP_MODE)
8842 		return;
8843 
8844 	create_params->is_ml_adapter = true;
8845 	create_params->is_single_link = true;
8846 }
8847 #else
8848 static inline void
wlan_hdd_set_ml_cap_for_sap_intf(struct hdd_adapter_create_param * create_params,enum QDF_OPMODE mode)8849 wlan_hdd_set_ml_cap_for_sap_intf(struct hdd_adapter_create_param *create_params,
8850 				 enum QDF_OPMODE mode)
8851 {
8852 	create_params->is_ml_adapter = false;
8853 }
8854 #endif /* WLAN_FEATURE_11BE_MLO */
8855 
8856 #if defined(WLAN_FEATURE_11BE_MLO) && defined(CFG80211_11BE_BASIC) && \
8857 	defined(WLAN_HDD_MULTI_VDEV_SINGLE_NDEV)
8858 void
hdd_adapter_disable_all_links(struct hdd_adapter * adapter,bool clear_macaddr)8859 hdd_adapter_disable_all_links(struct hdd_adapter *adapter, bool clear_macaddr)
8860 {
8861 	uint8_t idx_pos;
8862 	struct wlan_hdd_link_info *link_info;
8863 
8864 	hdd_adapter_for_each_link_info(adapter, link_info) {
8865 		if (clear_macaddr)
8866 			qdf_zero_macaddr(&link_info->link_addr);
8867 		idx_pos = hdd_adapter_get_index_of_link_info(link_info);
8868 		adapter->curr_link_info_map[idx_pos] = idx_pos;
8869 	}
8870 
8871 	adapter->deflink = &adapter->link_info[WLAN_HDD_DEFLINK_IDX];
8872 	adapter->active_links = (1 << adapter->num_links_on_create) - 1;
8873 }
8874 #endif
8875 
hdd_adapter_enable_links(struct hdd_adapter * adapter,struct hdd_adapter_create_param * params)8876 static void hdd_adapter_enable_links(struct hdd_adapter *adapter,
8877 				     struct hdd_adapter_create_param *params)
8878 {
8879 	uint8_t num, link_idx;
8880 
8881 	/* Default link is already set on adapter allocation, only
8882 	 * enable other links if requested links is greater than 1
8883 	 */
8884 	if (params->num_sessions <= 1) {
8885 		adapter->num_links_on_create = 1;
8886 		return;
8887 	}
8888 
8889 	num = QDF_MIN(params->num_sessions, WLAN_MAX_MLD);
8890 	for (link_idx = WLAN_HDD_DEFLINK_IDX; link_idx < num; link_idx++)
8891 		qdf_atomic_set_bit(link_idx, &adapter->active_links);
8892 
8893 	adapter->num_links_on_create = num;
8894 }
8895 
hdd_adapter_init_link_info(struct hdd_adapter * adapter)8896 static void hdd_adapter_init_link_info(struct hdd_adapter *adapter)
8897 {
8898 	uint8_t idx_pos;
8899 	struct wlan_hdd_link_info *link_info;
8900 
8901 	/* Initialize each member in link info array to default values */
8902 	hdd_adapter_for_each_link_info(adapter, link_info) {
8903 		link_info->adapter = adapter;
8904 		link_info->vdev_id = WLAN_UMAC_VDEV_ID_MAX;
8905 		qdf_spinlock_create(&link_info->vdev_lock);
8906 		init_completion(&link_info->vdev_destroy_event);
8907 		qdf_event_create(&link_info->acs_complete_event);
8908 
8909 		idx_pos = hdd_adapter_get_index_of_link_info(link_info);
8910 		adapter->curr_link_info_map[idx_pos] = idx_pos;
8911 		qdf_create_work(0, &link_info->chan_change_notify_work,
8912 				hdd_chan_change_notify_work_handler,
8913 				link_info);
8914 	}
8915 }
8916 
8917 /**
8918  * hdd_open_adapter() - open and setup the hdd adapter
8919  * @hdd_ctx: global hdd context
8920  * @session_type: type of the interface to be created
8921  * @iface_name: User-visible name of the interface
8922  * @mac_addr: MAC address to assign to the interface
8923  * @name_assign_type: the name of assign type of the netdev
8924  * @rtnl_held: the rtnl lock hold flag
8925  * @params: adapter create params
8926  *
8927  * This function open and setup the hdd adapter according to the device
8928  * type request, assign the name, the mac address assigned, and then prepared
8929  * the hdd related parameters, queue, lock and ready to start.
8930  *
8931  * Return: the pointer of hdd adapter, otherwise NULL.
8932  */
hdd_open_adapter(struct hdd_context * hdd_ctx,uint8_t session_type,const char * iface_name,tSirMacAddr mac_addr,unsigned char name_assign_type,bool rtnl_held,struct hdd_adapter_create_param * params)8933 struct hdd_adapter *hdd_open_adapter(struct hdd_context *hdd_ctx,
8934 				     uint8_t session_type,
8935 				     const char *iface_name,
8936 				     tSirMacAddr mac_addr,
8937 				     unsigned char name_assign_type,
8938 				     bool rtnl_held,
8939 				     struct hdd_adapter_create_param *params)
8940 {
8941 	struct net_device *ndev = NULL;
8942 	struct hdd_adapter *adapter = NULL, *sta_adapter = NULL;
8943 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
8944 	uint32_t i;
8945 	bool eht_capab = 0;
8946 
8947 	status = wlan_hdd_validate_mac_address((struct qdf_mac_addr *)mac_addr);
8948 	if (QDF_IS_STATUS_ERROR(status)) {
8949 		/* Not received valid mac_addr */
8950 		hdd_err("Unable to add virtual intf: Not able to get valid mac address");
8951 		return NULL;
8952 	}
8953 
8954 	status = hdd_check_for_existing_macaddr(hdd_ctx, mac_addr);
8955 	if (QDF_STATUS_E_FAILURE == status) {
8956 		hdd_err("Duplicate MAC addr: " QDF_MAC_ADDR_FMT
8957 				" already exists",
8958 				QDF_MAC_ADDR_REF(mac_addr));
8959 		return NULL;
8960 	}
8961 
8962 	if (params->only_wdev_register) {
8963 		sta_adapter = hdd_get_ml_adapter(hdd_ctx);
8964 		if (!sta_adapter) {
8965 			hdd_err("not able to find the sta adapter");
8966 			return NULL;
8967 		}
8968 	}
8969 
8970 	switch (session_type) {
8971 	case QDF_STA_MODE:
8972 		if (!(hdd_ctx->config->mac_provision ||
8973 		      params->only_wdev_register)) {
8974 			hdd_reset_locally_admin_bit(hdd_ctx, mac_addr);
8975 			/*
8976 			 * After resetting locally administered bit
8977 			 * again check if the new mac address is already
8978 			 * exists.
8979 			 */
8980 			status = hdd_check_for_existing_macaddr(hdd_ctx,
8981 								mac_addr);
8982 			if (QDF_STATUS_E_FAILURE == status) {
8983 				hdd_err("Duplicate MAC addr: " QDF_MAC_ADDR_FMT
8984 					" already exists",
8985 					QDF_MAC_ADDR_REF(mac_addr));
8986 				return NULL;
8987 			}
8988 		}
8989 
8990 		fallthrough;
8991 	case QDF_P2P_CLIENT_MODE:
8992 	case QDF_P2P_DEVICE_MODE:
8993 	case QDF_OCB_MODE:
8994 	case QDF_NDI_MODE:
8995 	case QDF_MONITOR_MODE:
8996 	case QDF_NAN_DISC_MODE:
8997 		adapter = hdd_alloc_station_adapter(hdd_ctx, mac_addr,
8998 						    name_assign_type,
8999 						    iface_name, session_type);
9000 
9001 		if (!adapter) {
9002 			hdd_err("failed to allocate adapter for session %d",
9003 					session_type);
9004 			return NULL;
9005 		}
9006 
9007 		ndev = adapter->dev;
9008 
9009 		status = ucfg_dp_create_intf(hdd_ctx->psoc, &adapter->mac_addr,
9010 					     (qdf_netdev_t)adapter->dev);
9011 		if (QDF_IS_STATUS_ERROR(status))
9012 			goto err_free_netdev;
9013 
9014 		if (QDF_P2P_CLIENT_MODE == session_type)
9015 			adapter->wdev.iftype = NL80211_IFTYPE_P2P_CLIENT;
9016 		else if (QDF_P2P_DEVICE_MODE == session_type)
9017 			adapter->wdev.iftype = NL80211_IFTYPE_P2P_DEVICE;
9018 		else if (QDF_MONITOR_MODE == session_type)
9019 			adapter->wdev.iftype = NL80211_IFTYPE_MONITOR;
9020 		else if (QDF_NAN_DISC_MODE == session_type)
9021 			wlan_hdd_set_nan_if_type(adapter);
9022 		else
9023 			adapter->wdev.iftype = NL80211_IFTYPE_STATION;
9024 
9025 		adapter->device_mode = session_type;
9026 
9027 
9028 		/*
9029 		 * Workqueue which gets scheduled in IPv4 notification
9030 		 * callback
9031 		 */
9032 		INIT_WORK(&adapter->ipv4_notifier_work,
9033 			  hdd_ipv4_notifier_work_queue);
9034 
9035 #ifdef WLAN_NS_OFFLOAD
9036 		/*
9037 		 * Workqueue which gets scheduled in IPv6
9038 		 * notification callback.
9039 		 */
9040 		INIT_WORK(&adapter->ipv6_notifier_work,
9041 			  hdd_ipv6_notifier_work_queue);
9042 #endif
9043 		if (params->only_wdev_register) {
9044 			hdd_register_wdev(sta_adapter, adapter, params);
9045 		} else {
9046 			status = hdd_register_interface(adapter, rtnl_held,
9047 							params);
9048 			if (QDF_STATUS_SUCCESS != status)
9049 				goto err_destroy_dp_intf;
9050 			/* Stop the Interface TX queue. */
9051 			hdd_debug("Disabling queues");
9052 			wlan_hdd_netif_queue_control(adapter,
9053 					WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER,
9054 					WLAN_CONTROL_PATH);
9055 		}
9056 		break;
9057 	case QDF_P2P_GO_MODE:
9058 	case QDF_SAP_MODE:
9059 		adapter = hdd_wlan_create_ap_dev(hdd_ctx, mac_addr,
9060 						 name_assign_type,
9061 						 (uint8_t *) iface_name);
9062 		if (!adapter) {
9063 			hdd_err("failed to allocate adapter for session %d",
9064 					  session_type);
9065 			return NULL;
9066 		}
9067 
9068 		ndev = adapter->dev;
9069 
9070 		status = ucfg_dp_create_intf(hdd_ctx->psoc, &adapter->mac_addr,
9071 					     (qdf_netdev_t)adapter->dev);
9072 		if (QDF_IS_STATUS_ERROR(status))
9073 			goto err_free_netdev;
9074 
9075 		adapter->wdev.iftype =
9076 			(session_type ==
9077 			 QDF_SAP_MODE) ? NL80211_IFTYPE_AP :
9078 			NL80211_IFTYPE_P2P_GO;
9079 		adapter->device_mode = session_type;
9080 
9081 		status = hdd_register_interface(adapter, rtnl_held, params);
9082 		if (QDF_STATUS_SUCCESS != status)
9083 			goto err_destroy_dp_intf;
9084 
9085 		hdd_debug("Disabling queues");
9086 		wlan_hdd_netif_queue_control(adapter,
9087 					WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER,
9088 					WLAN_CONTROL_PATH);
9089 
9090 		/*
9091 		 * Workqueue which gets scheduled in IPv4 notification
9092 		 * callback
9093 		 */
9094 		INIT_WORK(&adapter->ipv4_notifier_work,
9095 			  hdd_ipv4_notifier_work_queue);
9096 
9097 #ifdef WLAN_NS_OFFLOAD
9098 		/*
9099 		 * Workqueue which gets scheduled in IPv6
9100 		 * notification callback.
9101 		 */
9102 		INIT_WORK(&adapter->ipv6_notifier_work,
9103 			  hdd_ipv6_notifier_work_queue);
9104 #endif
9105 		if (!params->is_pre_cac_adapter)
9106 			wlan_hdd_set_ml_cap_for_sap_intf(params, session_type);
9107 		break;
9108 	case QDF_FTM_MODE:
9109 		adapter = hdd_alloc_station_adapter(hdd_ctx, mac_addr,
9110 						    name_assign_type,
9111 						    iface_name, session_type);
9112 		if (!adapter) {
9113 			hdd_err("Failed to allocate adapter for FTM mode");
9114 			return NULL;
9115 		}
9116 
9117 		ndev = adapter->dev;
9118 
9119 		status = ucfg_dp_create_intf(hdd_ctx->psoc, &adapter->mac_addr,
9120 					     (qdf_netdev_t)adapter->dev);
9121 		if (QDF_IS_STATUS_ERROR(status))
9122 			goto err_free_netdev;
9123 
9124 		adapter->wdev.iftype = NL80211_IFTYPE_STATION;
9125 		adapter->device_mode = session_type;
9126 		status = hdd_register_interface(adapter, rtnl_held, params);
9127 		if (QDF_STATUS_SUCCESS != status)
9128 			goto err_destroy_dp_intf;
9129 
9130 		/* Stop the Interface TX queue. */
9131 		hdd_debug("Disabling queues");
9132 		wlan_hdd_netif_queue_control(adapter,
9133 					WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER,
9134 					WLAN_CONTROL_PATH);
9135 
9136 		break;
9137 	default:
9138 		hdd_err("Invalid session type %d", session_type);
9139 		QDF_ASSERT(0);
9140 		return NULL;
9141 	}
9142 
9143 	hdd_adapter_init_link_info(adapter);
9144 	hdd_adapter_enable_links(adapter, params);
9145 
9146 	ucfg_psoc_mlme_get_11be_capab(hdd_ctx->psoc, &eht_capab);
9147 	if (params->is_ml_adapter && eht_capab) {
9148 		hdd_adapter_set_ml_adapter(adapter);
9149 		if (params->is_single_link)
9150 			hdd_adapter_set_sl_ml_adapter(adapter);
9151 	}
9152 
9153 	status = hdd_adapter_feature_update_work_init(adapter);
9154 	if (QDF_IS_STATUS_ERROR(status))
9155 		goto err_cleanup_adapter;
9156 
9157 	adapter->upgrade_udp_qos_threshold = QCA_WLAN_AC_BK;
9158 
9159 	hdd_init_completion(adapter);
9160 	INIT_WORK(&adapter->scan_block_work, wlan_hdd_cfg80211_scan_block_cb);
9161 	INIT_WORK(&adapter->sap_stop_bss_work,
9162 		  hdd_stop_sap_due_to_invalid_channel);
9163 	qdf_list_create(&adapter->blocked_scan_request_q, WLAN_MAX_SCAN_COUNT);
9164 	qdf_mutex_create(&adapter->blocked_scan_request_q_lock);
9165 	qdf_spinlock_create(&adapter->mc_list_lock);
9166 	qdf_event_create(&adapter->peer_cleanup_done);
9167 	hdd_sta_info_init(&adapter->sta_info_list);
9168 	hdd_sta_info_init(&adapter->cache_sta_info_list);
9169 
9170 	for (i = 0; i < NET_DEV_HOLD_ID_MAX; i++)
9171 		qdf_atomic_init(
9172 			&adapter->net_dev_hold_ref_count[NET_DEV_HOLD_ID_MAX]);
9173 
9174 	/* Add it to the hdd's session list. */
9175 	status = hdd_add_adapter_back(hdd_ctx, adapter);
9176 	if (QDF_STATUS_SUCCESS != status)
9177 		goto err_destroy_adapter_features_update_work;
9178 
9179 	hdd_apf_context_init(adapter);
9180 
9181 	policy_mgr_set_concurrency_mode(hdd_ctx->psoc, session_type);
9182 
9183 	if (QDF_STATUS_SUCCESS != hdd_debugfs_init(adapter))
9184 		hdd_err("debugfs: Interface %s init failed",
9185 			netdev_name(adapter->dev));
9186 
9187 	hdd_debug("%s interface created. iftype: %d", netdev_name(adapter->dev),
9188 		  session_type);
9189 
9190 	if (adapter->device_mode == QDF_STA_MODE)
9191 		wlan_hdd_debugfs_csr_init(adapter);
9192 
9193 	return adapter;
9194 
9195 err_destroy_adapter_features_update_work:
9196 	hdd_adapter_feature_update_work_deinit(adapter);
9197 
9198 err_cleanup_adapter:
9199 	if (adapter) {
9200 		hdd_cleanup_adapter(hdd_ctx, adapter, rtnl_held);
9201 		adapter = NULL;
9202 	}
9203 
9204 err_destroy_dp_intf:
9205 	ucfg_dp_destroy_intf(hdd_ctx->psoc, &adapter->mac_addr);
9206 
9207 err_free_netdev:
9208 	if (ndev)
9209 		free_netdev(ndev);
9210 
9211 	return NULL;
9212 }
9213 
__hdd_close_adapter(struct hdd_context * hdd_ctx,struct hdd_adapter * adapter,bool rtnl_held)9214 static void __hdd_close_adapter(struct hdd_context *hdd_ctx,
9215 				struct hdd_adapter *adapter,
9216 				bool rtnl_held)
9217 {
9218 	struct qdf_mac_addr adapter_mac;
9219 	struct wlan_hdd_link_info *link_info;
9220 
9221 	qdf_copy_macaddr(&adapter_mac, &adapter->mac_addr);
9222 	if (adapter->device_mode == QDF_STA_MODE) {
9223 		hdd_adapter_for_each_link_info(adapter, link_info)
9224 			hdd_cleanup_conn_info(link_info);
9225 	}
9226 
9227 	hdd_adapter_for_each_link_info(adapter, link_info)
9228 		qdf_flush_work(&link_info->chan_change_notify_work);
9229 
9230 	qdf_list_destroy(&adapter->blocked_scan_request_q);
9231 	qdf_mutex_destroy(&adapter->blocked_scan_request_q_lock);
9232 	policy_mgr_clear_concurrency_mode(hdd_ctx->psoc, adapter->device_mode);
9233 	qdf_event_destroy(&adapter->peer_cleanup_done);
9234 	hdd_adapter_feature_update_work_deinit(adapter);
9235 	hdd_cleanup_adapter(hdd_ctx, adapter, rtnl_held);
9236 	ucfg_dp_destroy_intf(hdd_ctx->psoc, &adapter_mac);
9237 }
9238 
hdd_close_adapter(struct hdd_context * hdd_ctx,struct hdd_adapter * adapter,bool rtnl_held)9239 void hdd_close_adapter(struct hdd_context *hdd_ctx,
9240 		       struct hdd_adapter *adapter,
9241 		       bool rtnl_held)
9242 {
9243 	/*
9244 	 * Stop the global bus bandwidth timer while touching the adapter list
9245 	 * to avoid bad memory access by the timer handler.
9246 	 */
9247 	ucfg_dp_bus_bw_compute_timer_stop(hdd_ctx->psoc);
9248 
9249 	hdd_check_for_net_dev_ref_leak(adapter);
9250 	hdd_remove_adapter(hdd_ctx, adapter);
9251 	__hdd_close_adapter(hdd_ctx, adapter, rtnl_held);
9252 
9253 	/* conditionally restart the bw timer */
9254 	ucfg_dp_bus_bw_compute_timer_try_start(hdd_ctx->psoc);
9255 }
9256 
hdd_close_all_adapters(struct hdd_context * hdd_ctx,bool rtnl_held)9257 void hdd_close_all_adapters(struct hdd_context *hdd_ctx, bool rtnl_held)
9258 {
9259 	struct hdd_adapter *adapter;
9260 	struct osif_vdev_sync *vdev_sync;
9261 	QDF_STATUS qdf_status;
9262 
9263 	hdd_enter();
9264 
9265 	while (QDF_IS_STATUS_SUCCESS(hdd_get_front_adapter(
9266 							hdd_ctx, &adapter))) {
9267 		/* If MLO is enabled unregister the link wdev's */
9268 		if (adapter->device_mode == QDF_STA_MODE ||
9269 		    adapter->device_mode == QDF_SAP_MODE) {
9270 			qdf_status = hdd_wlan_unregister_mlo_interfaces(adapter,
9271 								     rtnl_held);
9272 			if (QDF_IS_STATUS_ERROR(qdf_status))
9273 				continue;
9274 		}
9275 
9276 		hdd_check_for_net_dev_ref_leak(adapter);
9277 		hdd_remove_front_adapter(hdd_ctx, &adapter);
9278 		vdev_sync = osif_vdev_sync_unregister(adapter->dev);
9279 		if (vdev_sync)
9280 			osif_vdev_sync_wait_for_ops(vdev_sync);
9281 
9282 		wlan_hdd_release_intf_addr(hdd_ctx, adapter->mac_addr.bytes);
9283 		__hdd_close_adapter(hdd_ctx, adapter, rtnl_held);
9284 
9285 		if (vdev_sync)
9286 			osif_vdev_sync_destroy(vdev_sync);
9287 	}
9288 
9289 	hdd_exit();
9290 }
9291 
wlan_hdd_reset_prob_rspies(struct wlan_hdd_link_info * link_info)9292 void wlan_hdd_reset_prob_rspies(struct wlan_hdd_link_info *link_info)
9293 {
9294 	struct qdf_mac_addr *bssid = NULL;
9295 	tSirUpdateIE update_ie;
9296 	mac_handle_t mac_handle;
9297 	struct hdd_adapter *adapter = link_info->adapter;
9298 
9299 	switch (adapter->device_mode) {
9300 	case QDF_STA_MODE:
9301 	case QDF_P2P_CLIENT_MODE:
9302 	{
9303 		struct hdd_station_ctx *sta_ctx =
9304 			WLAN_HDD_GET_STATION_CTX_PTR(link_info);
9305 		bssid = &sta_ctx->conn_info.bssid;
9306 		break;
9307 	}
9308 	case QDF_SAP_MODE:
9309 	case QDF_P2P_GO_MODE:
9310 	{
9311 		bssid = &adapter->mac_addr;
9312 		break;
9313 	}
9314 	case QDF_FTM_MODE:
9315 	case QDF_P2P_DEVICE_MODE:
9316 	default:
9317 		/*
9318 		 * wlan_hdd_reset_prob_rspies should not have been called
9319 		 * for these kind of devices
9320 		 */
9321 		hdd_err("Unexpected request for the current device type %d",
9322 		       adapter->device_mode);
9323 		return;
9324 	}
9325 
9326 	qdf_copy_macaddr(&update_ie.bssid, bssid);
9327 	update_ie.vdev_id = link_info->vdev_id;
9328 	update_ie.ieBufferlength = 0;
9329 	update_ie.pAdditionIEBuffer = NULL;
9330 	update_ie.append = true;
9331 	update_ie.notify = false;
9332 	mac_handle = hdd_adapter_get_mac_handle(adapter);
9333 	if (sme_update_add_ie(mac_handle,
9334 			      &update_ie,
9335 			      eUPDATE_IE_PROBE_RESP) == QDF_STATUS_E_FAILURE) {
9336 		hdd_err("Could not pass on PROBE_RSP_BCN data to PE");
9337 	}
9338 }
9339 
9340 /**
9341  * hdd_ipa_ap_disconnect_evt() - Indicate wlan ipa ap disconnect event
9342  * @hdd_ctx: hdd context
9343  * @adapter: hdd adapter
9344  *
9345  * Return: None
9346  */
9347 static inline
hdd_ipa_ap_disconnect_evt(struct hdd_context * hdd_ctx,struct hdd_adapter * adapter)9348 void hdd_ipa_ap_disconnect_evt(struct hdd_context *hdd_ctx,
9349 			       struct hdd_adapter *adapter)
9350 {
9351 	struct wlan_hdd_link_info *link_info;
9352 
9353 	link_info = adapter->deflink;
9354 	if (ucfg_ipa_is_enabled()) {
9355 		ucfg_ipa_uc_disconnect_ap(hdd_ctx->pdev,
9356 					  adapter->dev);
9357 		ucfg_ipa_cleanup_dev_iface(hdd_ctx->pdev,
9358 					   adapter->dev,
9359 					   link_info->vdev_id);
9360 	}
9361 }
9362 
9363 #ifdef WLAN_FEATURE_NAN
9364 /**
9365  * hdd_ndp_state_cleanup() - API to set NDP state to Disconnected
9366  * @psoc: pointer to psoc object
9367  * @ndi_vdev_id: vdev_id of the NDI
9368  *
9369  * Return: None
9370  */
9371 static void
hdd_ndp_state_cleanup(struct wlan_objmgr_psoc * psoc,uint8_t ndi_vdev_id)9372 hdd_ndp_state_cleanup(struct wlan_objmgr_psoc *psoc, uint8_t ndi_vdev_id)
9373 {
9374 	struct wlan_objmgr_vdev *ndi_vdev;
9375 
9376 	ndi_vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, ndi_vdev_id,
9377 							WLAN_NAN_ID);
9378 	if (!ndi_vdev) {
9379 		hdd_err("Cannot obtain NDI vdev object!");
9380 		return;
9381 	}
9382 
9383 	ucfg_nan_set_ndi_state(ndi_vdev, NAN_DATA_DISCONNECTED_STATE);
9384 
9385 	wlan_objmgr_vdev_release_ref(ndi_vdev, WLAN_NAN_ID);
9386 }
9387 
9388 /**
9389  * hdd_peer_cleanup() - This API will delete NDP peer if exist and modifies
9390  * the NDP state.
9391  * @link_info: Link info pointer in HDD adapter
9392  *
9393  * Return: None
9394  */
hdd_peer_cleanup(struct wlan_hdd_link_info * link_info)9395 static void hdd_peer_cleanup(struct wlan_hdd_link_info *link_info)
9396 {
9397 	QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
9398 	struct hdd_adapter *adapter = link_info->adapter;
9399 	struct hdd_context *hdd_ctx = adapter->hdd_ctx;
9400 
9401 	/* Check if there is any peer present on the adapter */
9402 	if (!hdd_any_valid_peer_present(link_info)) {
9403 		/*
9404 		 * No peers are connected to the NDI. So, set the NDI state to
9405 		 * DISCONNECTED. If there are any peers, ucfg_nan_disable_ndi()
9406 		 * would take care of cleanup all the peers and setting the
9407 		 * state to DISCONNECTED.
9408 		 */
9409 		hdd_ndp_state_cleanup(hdd_ctx->psoc, link_info->vdev_id);
9410 		return;
9411 	}
9412 
9413 	if (adapter->device_mode == QDF_NDI_MODE)
9414 		qdf_status = ucfg_nan_disable_ndi(hdd_ctx->psoc,
9415 						  link_info->vdev_id);
9416 
9417 	if (QDF_IS_STATUS_ERROR(qdf_status))
9418 		return;
9419 
9420 	qdf_status = qdf_wait_for_event_completion(&adapter->peer_cleanup_done,
9421 						   WLAN_WAIT_PEER_CLEANUP);
9422 	if (QDF_IS_STATUS_ERROR(qdf_status))
9423 		hdd_debug("peer_cleanup_done wait fail");
9424 }
9425 #else
9426 static inline void
hdd_ndp_state_cleanup(struct wlan_objmgr_psoc * psoc,uint8_t ndi_vdev_id)9427 hdd_ndp_state_cleanup(struct wlan_objmgr_psoc *psoc, uint8_t ndi_vdev_id)
9428 {
9429 }
9430 
9431 static inline void
hdd_ndp_peer_cleanup(struct hdd_context * hdd_ctx,struct hdd_adapter * adapter)9432 hdd_ndp_peer_cleanup(struct hdd_context *hdd_ctx, struct hdd_adapter *adapter)
9433 {
9434 }
9435 
hdd_peer_cleanup(struct wlan_hdd_link_info * link_info)9436 static inline void hdd_peer_cleanup(struct wlan_hdd_link_info *link_info)
9437 {
9438 }
9439 #endif /* WLAN_FEATURE_NAN */
9440 
9441 #ifdef FUNC_CALL_MAP
9442 
9443 /**
9444  * hdd_dump_func_call_map() - Dump the function call map
9445  *
9446  * Return: None
9447  */
9448 
hdd_dump_func_call_map(void)9449 static void hdd_dump_func_call_map(void)
9450 {
9451 	char *cc_buf;
9452 
9453 	cc_buf = qdf_mem_malloc(QDF_FUNCTION_CALL_MAP_BUF_LEN);
9454 	/*
9455 	 * These logs are required as these indicates the start and end of the
9456 	 * dump for the auto script to parse
9457 	 */
9458 	hdd_info("Function call map dump start");
9459 	qdf_get_func_call_map(cc_buf);
9460 	qdf_trace_hex_dump(QDF_MODULE_ID_HDD,
9461 		QDF_TRACE_LEVEL_DEBUG, cc_buf, QDF_FUNCTION_CALL_MAP_BUF_LEN);
9462 	hdd_info("Function call map dump end");
9463 	qdf_mem_free(cc_buf);
9464 }
9465 #else
hdd_dump_func_call_map(void)9466 static inline void hdd_dump_func_call_map(void)
9467 {
9468 }
9469 #endif
9470 
hdd_reset_scan_operation(struct wlan_hdd_link_info * link_info)9471 static void hdd_reset_scan_operation(struct wlan_hdd_link_info *link_info)
9472 {
9473 	switch (link_info->adapter->device_mode) {
9474 	case QDF_STA_MODE:
9475 	case QDF_P2P_CLIENT_MODE:
9476 	case QDF_P2P_DEVICE_MODE:
9477 	case QDF_NDI_MODE:
9478 		wlan_hdd_scan_abort(link_info);
9479 		wlan_hdd_cleanup_remain_on_channel_ctx(link_info);
9480 		if (link_info->adapter->device_mode == QDF_STA_MODE) {
9481 			struct wlan_objmgr_vdev *vdev;
9482 
9483 			vdev = hdd_objmgr_get_vdev_by_user(link_info,
9484 							   WLAN_OSIF_SCAN_ID);
9485 			if (!vdev)
9486 				break;
9487 
9488 			wlan_cfg80211_sched_scan_stop(vdev);
9489 			hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_SCAN_ID);
9490 		}
9491 		break;
9492 	case QDF_P2P_GO_MODE:
9493 		wlan_hdd_cleanup_remain_on_channel_ctx(link_info);
9494 		break;
9495 	case QDF_SAP_MODE:
9496 		qdf_atomic_set(&link_info->session.ap.acs_in_progress, 0);
9497 		break;
9498 	default:
9499 		break;
9500 	}
9501 }
9502 
9503 #ifdef WLAN_OPEN_SOURCE
hdd_cancel_ip_notifier_work(struct hdd_adapter * adapter)9504 void hdd_cancel_ip_notifier_work(struct hdd_adapter *adapter)
9505 {
9506 	cancel_work_sync(&adapter->ipv4_notifier_work);
9507 #ifdef WLAN_NS_OFFLOAD
9508 	cancel_work_sync(&adapter->ipv6_notifier_work);
9509 #endif
9510 }
9511 #endif
9512 
hdd_adapter_deregister_fc(struct hdd_adapter * adapter)9513 void hdd_adapter_deregister_fc(struct hdd_adapter *adapter)
9514 {
9515 	hdd_deregister_hl_netdev_fc_timer(adapter);
9516 	hdd_deregister_tx_flow_control(adapter);
9517 }
9518 
hdd_stop_and_cleanup_ndi(struct wlan_hdd_link_info * link_info)9519 static void hdd_stop_and_cleanup_ndi(struct wlan_hdd_link_info *link_info)
9520 {
9521 	QDF_STATUS status;
9522 	unsigned long rc;
9523 	struct hdd_adapter *adapter = link_info->adapter;
9524 	struct hdd_context *hdd_ctx = adapter->hdd_ctx;
9525 
9526 	hdd_destroy_adapter_sysfs_files(adapter);
9527 	/* For NDI do not use roam_profile */
9528 	INIT_COMPLETION(adapter->disconnect_comp_var);
9529 	hdd_peer_cleanup(link_info);
9530 	status = sme_roam_ndi_stop(hdd_ctx->mac_handle, link_info->vdev_id);
9531 	if (QDF_IS_STATUS_SUCCESS(status)) {
9532 		rc = wait_for_completion_timeout(
9533 			&adapter->disconnect_comp_var,
9534 			msecs_to_jiffies(SME_CMD_STOP_BSS_TIMEOUT));
9535 		if (!rc)
9536 			hdd_warn("disconn_comp_var wait fail");
9537 		hdd_cleanup_ndi(link_info);
9538 	}
9539 }
9540 
9541 static void
hdd_sta_disconnect_and_cleanup(struct wlan_hdd_link_info * link_info)9542 hdd_sta_disconnect_and_cleanup(struct wlan_hdd_link_info *link_info)
9543 {
9544 	QDF_STATUS status;
9545 	enum wlan_reason_code reason;
9546 	struct hdd_adapter *adapter = link_info->adapter;
9547 
9548 	/*
9549 	 * On vdev delete wait for disconnect to
9550 	 * complete. i.e use sync API, so that the
9551 	 * vdev ref of MLME are cleaned and disconnect
9552 	 * complete before vdev is moved to logically
9553 	 * deleted.
9554 	 */
9555 	if (cds_is_driver_recovering())
9556 		reason = REASON_DEVICE_RECOVERY;
9557 	else
9558 		reason = REASON_IFACE_DOWN;
9559 
9560 	status = wlan_hdd_cm_issue_disconnect(link_info, reason, true);
9561 	if (QDF_IS_STATUS_ERROR(status) && ucfg_ipa_is_enabled()) {
9562 		hdd_err("STA disconnect failed");
9563 		ucfg_ipa_uc_cleanup_sta(adapter->hdd_ctx->pdev, adapter->dev,
9564 					link_info->vdev_id);
9565 	}
9566 }
9567 
9568 static void
hdd_disable_nan_active_disc(struct hdd_adapter * adapter)9569 hdd_disable_nan_active_disc(struct hdd_adapter *adapter)
9570 {
9571 	struct hdd_context *hdd_ctx = adapter->hdd_ctx;
9572 	enum QDF_OPMODE device_mode = adapter->device_mode;
9573 
9574 	if ((device_mode == QDF_NAN_DISC_MODE ||
9575 	     (device_mode == QDF_STA_MODE &&
9576 	      !ucfg_nan_is_vdev_creation_allowed(hdd_ctx->psoc))) &&
9577 	    ucfg_is_nan_conc_control_supported(hdd_ctx->psoc) &&
9578 	    ucfg_is_nan_disc_active(hdd_ctx->psoc))
9579 		ucfg_disable_nan_discovery(hdd_ctx->psoc, NULL, 0);
9580 }
9581 
9582 static void
hdd_monitor_mode_release_wakelock(struct wlan_hdd_link_info * link_info)9583 hdd_monitor_mode_release_wakelock(struct wlan_hdd_link_info *link_info)
9584 {
9585 	struct hdd_adapter *adapter = link_info->adapter;
9586 	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
9587 
9588 	if (wlan_hdd_is_session_type_monitor(adapter->device_mode) &&
9589 	    (ucfg_mlme_is_sta_mon_conc_supported(hdd_ctx->psoc) ||
9590 	     ucfg_dp_is_local_pkt_capture_enabled(hdd_ctx->psoc))) {
9591 		hdd_info("Release wakelock for STA + monitor mode!");
9592 		os_if_dp_local_pkt_capture_stop(link_info->vdev);
9593 		qdf_runtime_pm_allow_suspend(
9594 				&hdd_ctx->runtime_context.monitor_mode);
9595 		hdd_lpc_enable_powersave(hdd_ctx);
9596 		qdf_wake_lock_release(&hdd_ctx->monitor_mode_wakelock,
9597 				      WIFI_POWER_EVENT_WAKELOCK_MONITOR_MODE);
9598 	}
9599 }
9600 
9601 static void
hdd_monitor_mode_disable_and_delete(struct wlan_hdd_link_info * link_info)9602 hdd_monitor_mode_disable_and_delete(struct wlan_hdd_link_info *link_info)
9603 {
9604 	QDF_STATUS status;
9605 	struct hdd_adapter *adapter = link_info->adapter;
9606 	struct hdd_context *hdd_ctx = adapter->hdd_ctx;
9607 
9608 	status = hdd_disable_monitor_mode();
9609 	if (QDF_IS_STATUS_ERROR(status))
9610 		hdd_err_rl("datapath reset failed for montior mode");
9611 	hdd_set_idle_ps_config(hdd_ctx, true);
9612 	status = hdd_monitor_mode_vdev_status(adapter);
9613 	if (QDF_IS_STATUS_ERROR(status))
9614 		hdd_err_rl("stop failed montior mode");
9615 	sme_delete_mon_session(hdd_ctx->mac_handle, link_info->vdev_id);
9616 }
9617 
9618 static void
hdd_stop_and_close_pre_cac_adapter(struct hdd_context * hdd_ctx,struct wlan_objmgr_vdev * vdev)9619 hdd_stop_and_close_pre_cac_adapter(struct hdd_context *hdd_ctx,
9620 				   struct wlan_objmgr_vdev *vdev)
9621 {
9622 	if (!vdev)
9623 		return;
9624 
9625 	if (!ucfg_pre_cac_adapter_is_active(vdev)) {
9626 		ucfg_pre_cac_stop(hdd_ctx->psoc);
9627 		hdd_close_pre_cac_adapter(hdd_ctx);
9628 	} else {
9629 		if (ucfg_pre_cac_set_status(vdev, false))
9630 			hdd_err("Failed to set is_pre_cac_on to false");
9631 	}
9632 }
9633 
hdd_reset_ies_on_sap_stop(struct wlan_hdd_link_info * link_info)9634 static void hdd_reset_ies_on_sap_stop(struct wlan_hdd_link_info *link_info)
9635 {
9636 	mac_handle_t mac_handle;
9637 	tSirUpdateIE update_ie;
9638 	QDF_STATUS status;
9639 	struct hdd_adapter *adapter = link_info->adapter;
9640 
9641 	mac_handle = hdd_adapter_get_mac_handle(adapter);
9642 	update_ie.vdev_id = link_info->vdev_id;
9643 	update_ie.ieBufferlength = 0;
9644 	update_ie.pAdditionIEBuffer = NULL;
9645 	update_ie.append = false;
9646 	update_ie.notify = false;
9647 
9648 	/* Probe bcn reset */
9649 	status = sme_update_add_ie(mac_handle, &update_ie,
9650 				   eUPDATE_IE_PROBE_BCN);
9651 	if (status == QDF_STATUS_E_FAILURE)
9652 		hdd_err("Could not pass PROBE_RSP_BCN to PE");
9653 
9654 	/* Assoc resp reset */
9655 	status = sme_update_add_ie(mac_handle, &update_ie,
9656 				   eUPDATE_IE_ASSOC_RESP);
9657 	if (status == QDF_STATUS_E_FAILURE)
9658 		hdd_err("Could not pass ASSOC_RSP to PE");
9659 
9660 	/* Reset WNI_CFG_PROBE_RSP Flags */
9661 	wlan_hdd_reset_prob_rspies(link_info);
9662 }
9663 
hdd_stop_station_adapter(struct hdd_adapter * adapter)9664 static void hdd_stop_station_adapter(struct hdd_adapter *adapter)
9665 {
9666 	struct wlan_objmgr_vdev *vdev;
9667 	enum QDF_OPMODE mode;
9668 	struct wlan_hdd_link_info *link_info;
9669 
9670 	mode = adapter->device_mode;
9671 	hdd_adapter_for_each_active_link_info(adapter, link_info) {
9672 		vdev = hdd_objmgr_get_vdev_by_user(link_info,
9673 						   WLAN_INIT_DEINIT_ID);
9674 		if (!vdev)
9675 			continue;
9676 
9677 		if (mode == QDF_NDI_MODE)
9678 			hdd_stop_and_cleanup_ndi(link_info);
9679 		else if (!hdd_cm_is_disconnected(link_info))
9680 			hdd_sta_disconnect_and_cleanup(link_info);
9681 
9682 		hdd_reset_scan_operation(link_info);
9683 		wlan_hdd_cleanup_actionframe(link_info);
9684 		wlan_hdd_flush_pmksa_cache(link_info);
9685 
9686 		if (mode == QDF_STA_MODE)
9687 			ucfg_ipa_flush_pending_vdev_events(
9688 						wlan_vdev_get_pdev(vdev),
9689 						link_info->vdev_id);
9690 		hdd_objmgr_put_vdev_by_user(vdev, WLAN_INIT_DEINIT_ID);
9691 		hdd_vdev_destroy(link_info);
9692 	}
9693 
9694 	hdd_disable_nan_active_disc(adapter);
9695 	hdd_adapter_deregister_fc(adapter);
9696 	hdd_cancel_ip_notifier_work(adapter);
9697 }
9698 
hdd_stop_mon_adapter(struct hdd_adapter * adapter)9699 static int hdd_stop_mon_adapter(struct hdd_adapter *adapter)
9700 {
9701 	struct wlan_objmgr_vdev *vdev;
9702 	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
9703 	struct wlan_hdd_link_info *link_info = adapter->deflink;
9704 
9705 	vdev = hdd_objmgr_get_vdev_by_user(link_info,
9706 					   WLAN_INIT_DEINIT_ID);
9707 	if (wlan_hdd_is_session_type_monitor(adapter->device_mode) &&
9708 	    vdev &&
9709 	    ucfg_pkt_capture_get_mode(hdd_ctx->psoc) !=
9710 					PACKET_CAPTURE_MODE_DISABLE) {
9711 		struct hdd_adapter *sta_adapter;
9712 
9713 		ucfg_pkt_capture_deregister_callbacks(vdev);
9714 		hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_ID);
9715 		link_info->vdev = NULL;
9716 
9717 		sta_adapter = hdd_get_adapter(hdd_ctx, QDF_STA_MODE);
9718 		if (!sta_adapter) {
9719 			hdd_objmgr_put_vdev_by_user(vdev, WLAN_INIT_DEINIT_ID);
9720 			hdd_err("No station interface found");
9721 			return -EINVAL;
9722 		}
9723 		hdd_reset_monitor_interface(sta_adapter);
9724 	}
9725 
9726 	hdd_monitor_mode_release_wakelock(link_info);
9727 	wlan_hdd_scan_abort(link_info);
9728 	hdd_adapter_deregister_fc(adapter);
9729 	hdd_monitor_mode_disable_and_delete(link_info);
9730 	if (vdev)
9731 		hdd_objmgr_put_vdev_by_user(vdev, WLAN_INIT_DEINIT_ID);
9732 
9733 	hdd_vdev_destroy(link_info);
9734 
9735 	return 0;
9736 }
9737 
hdd_stop_sap_go_adapter(struct hdd_adapter * adapter)9738 static void hdd_stop_sap_go_adapter(struct hdd_adapter *adapter)
9739 {
9740 	enum QDF_OPMODE mode;
9741 	struct hdd_ap_ctx *ap_ctx;
9742 	struct sap_context *sap_ctx;
9743 	struct sap_config *sap_config;
9744 	struct hdd_hostapd_state *hostapd_state;
9745 	struct wlan_objmgr_vdev *vdev;
9746 	struct wlan_hdd_link_info *link_info = adapter->deflink;
9747 	QDF_STATUS status = QDF_STATUS_SUCCESS;
9748 	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
9749 	uint8_t link_id;
9750 
9751 	mode = adapter->device_mode;
9752 	ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(link_info);
9753 	sap_ctx = WLAN_HDD_GET_SAP_CTX_PTR(link_info);
9754 	vdev = hdd_objmgr_get_vdev_by_user(link_info, WLAN_INIT_DEINIT_ID);
9755 
9756 	if (mode == QDF_SAP_MODE) {
9757 		wlan_hdd_scan_abort(link_info);
9758 		hdd_abort_ongoing_sta_connection(hdd_ctx);
9759 		/* Diassociate with all the peers before stop ap post */
9760 		if (test_bit(SOFTAP_BSS_STARTED, &link_info->link_flags)) {
9761 			if (wlan_hdd_del_station(adapter, NULL))
9762 				hdd_sap_indicate_disconnect_for_sta(adapter);
9763 		}
9764 		wlan_hdd_flush_pmksa_cache(link_info);
9765 		sap_config = &ap_ctx->sap_config;
9766 		wlansap_reset_sap_config_add_ie(sap_config, eUPDATE_IE_ALL);
9767 		hdd_stop_and_close_pre_cac_adapter(hdd_ctx, vdev);
9768 	}
9769 	wlansap_cleanup_cac_timer(sap_ctx);
9770 	cds_flush_work(&adapter->sap_stop_bss_work);
9771 
9772 	if (qdf_atomic_read(&ap_ctx->acs_in_progress)) {
9773 		hdd_info("ACS in progress, wait for complete");
9774 		qdf_wait_for_event_completion(&link_info->acs_complete_event,
9775 					      ACS_COMPLETE_TIMEOUT);
9776 	}
9777 
9778 	if (mode == QDF_P2P_GO_MODE) {
9779 		wlan_hdd_cleanup_remain_on_channel_ctx(link_info);
9780 		hdd_abort_ongoing_sta_connection(hdd_ctx);
9781 	}
9782 
9783 	hdd_adapter_deregister_fc(adapter);
9784 	hdd_destroy_acs_timer(adapter);
9785 
9786 	mutex_lock(&hdd_ctx->sap_lock);
9787 	if (test_bit(SOFTAP_BSS_STARTED, &link_info->link_flags)) {
9788 		hostapd_state = WLAN_HDD_GET_HOSTAP_STATE_PTR(link_info);
9789 		qdf_event_reset(&hostapd_state->qdf_stop_bss_event);
9790 		status = wlansap_stop_bss(ap_ctx->sap_context);
9791 		if (QDF_IS_STATUS_SUCCESS(status)) {
9792 			status = qdf_wait_single_event(&hostapd_state->qdf_stop_bss_event,
9793 						       SME_CMD_STOP_BSS_TIMEOUT);
9794 			if (QDF_IS_STATUS_ERROR(status)) {
9795 				hdd_err("failure waiting for wlansap_stop_bss %d",
9796 					status);
9797 				hdd_ipa_ap_disconnect_evt(hdd_ctx, adapter);
9798 			}
9799 		} else {
9800 			hdd_err("failure in wlansap_stop_bss");
9801 		}
9802 
9803 		clear_bit(SOFTAP_BSS_STARTED, &link_info->link_flags);
9804 		policy_mgr_decr_session_set_pcl(hdd_ctx->psoc,
9805 						adapter->device_mode,
9806 						link_info->vdev_id);
9807 		hdd_green_ap_start_state_mc(hdd_ctx, adapter->device_mode,
9808 					    false);
9809 
9810 		hdd_reset_ies_on_sap_stop(link_info);
9811 	}
9812 
9813 	/*
9814 	 * Note to restart sap after SSR driver needs below information
9815 	 * and is not cleared/freed on purpose in case of SAP SSR
9816 	 */
9817 	if (!cds_is_driver_recovering()) {
9818 		clear_bit(SOFTAP_INIT_DONE, &link_info->link_flags);
9819 		qdf_mem_free(ap_ctx->beacon);
9820 		ap_ctx->beacon = NULL;
9821 
9822 		if (vdev) {
9823 			link_id = wlan_vdev_get_link_id(vdev);
9824 			ucfg_crypto_free_key_by_link_id(hdd_ctx->psoc,
9825 							&link_info->link_addr,
9826 							link_id);
9827 		}
9828 	}
9829 	/* Clear all the cached sta info */
9830 	hdd_clear_cached_sta_info(adapter);
9831 
9832 	if (vdev && policy_mgr_is_dnsc_set(vdev))
9833 		wlan_hdd_send_avoid_freq_for_dnbs(hdd_ctx, 0);
9834 
9835 	hdd_cancel_ip_notifier_work(adapter);
9836 	sap_release_vdev_ref(sap_ctx);
9837 
9838 	if (mode == QDF_SAP_MODE)
9839 		ucfg_ipa_flush_pending_vdev_events(hdd_ctx->pdev,
9840 						   link_info->vdev_id);
9841 	if (vdev)
9842 		hdd_objmgr_put_vdev_by_user(vdev, WLAN_INIT_DEINIT_ID);
9843 	hdd_vdev_destroy(link_info);
9844 	mutex_unlock(&hdd_ctx->sap_lock);
9845 	ucfg_ipa_flush(hdd_ctx->pdev);
9846 }
9847 
hdd_stop_ocb_adapter(struct hdd_adapter * adapter)9848 static void hdd_stop_ocb_adapter(struct hdd_adapter *adapter)
9849 {
9850 	struct hdd_station_ctx *sta_ctx;
9851 	struct wlan_objmgr_vdev *vdev;
9852 	struct wlan_hdd_link_info *link_info = adapter->deflink;
9853 
9854 	vdev = hdd_objmgr_get_vdev_by_user(link_info, WLAN_INIT_DEINIT_ID);
9855 	sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(link_info);
9856 	cdp_clear_peer(cds_get_context(QDF_MODULE_ID_SOC), OL_TXRX_PDEV_ID,
9857 		       sta_ctx->conn_info.peer_macaddr[0]);
9858 	hdd_adapter_deregister_fc(adapter);
9859 	if (vdev)
9860 		hdd_objmgr_put_vdev_by_user(vdev, WLAN_INIT_DEINIT_ID);
9861 	hdd_vdev_destroy(link_info);
9862 }
9863 
hdd_stop_adapter_ext(struct hdd_context * hdd_ctx,struct hdd_adapter * adapter)9864 QDF_STATUS hdd_stop_adapter_ext(struct hdd_context *hdd_ctx,
9865 				struct hdd_adapter *adapter)
9866 {
9867 	QDF_STATUS status;
9868 	struct wlan_hdd_link_info *link_info = adapter->deflink;
9869 
9870 	hdd_enter();
9871 	hdd_destroy_adapter_sysfs_files(adapter);
9872 
9873 	if (adapter->device_mode == QDF_STA_MODE &&
9874 	    hdd_is_pkt_capture_mon_enable(adapter) &&
9875 	    ucfg_pkt_capture_get_mode(hdd_ctx->psoc) !=
9876 						PACKET_CAPTURE_MODE_DISABLE) {
9877 		hdd_unmap_monitor_interface_vdev(adapter);
9878 	}
9879 
9880 	if (link_info->vdev_id != WLAN_UMAC_VDEV_ID_MAX)
9881 		wlan_hdd_cfg80211_deregister_frames(adapter);
9882 
9883 	hdd_stop_tsf_sync(adapter);
9884 	cds_flush_work(&adapter->scan_block_work);
9885 	wlan_hdd_cfg80211_scan_block(adapter);
9886 	hdd_debug("Disabling queues");
9887 	wlan_hdd_netif_queue_control(adapter,
9888 				     WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER,
9889 				     WLAN_CONTROL_PATH);
9890 
9891 	switch (adapter->device_mode) {
9892 	case QDF_STA_MODE:
9893 	case QDF_P2P_CLIENT_MODE:
9894 	case QDF_NDI_MODE:
9895 	case QDF_P2P_DEVICE_MODE:
9896 	case QDF_NAN_DISC_MODE:
9897 		hdd_stop_station_adapter(adapter);
9898 		break;
9899 	case QDF_MONITOR_MODE:
9900 		status = hdd_stop_mon_adapter(adapter);
9901 		if (QDF_IS_STATUS_ERROR(status))
9902 			return status;
9903 
9904 		break;
9905 	case QDF_SAP_MODE:
9906 	case QDF_P2P_GO_MODE:
9907 		hdd_stop_sap_go_adapter(adapter);
9908 		break;
9909 	case QDF_OCB_MODE:
9910 		hdd_stop_ocb_adapter(adapter);
9911 		break;
9912 	default:
9913 		break;
9914 	}
9915 
9916 	/* Moved from vdev destroy as it is per adapter */
9917 	wlan_cfg80211_cleanup_scan_queue(hdd_ctx->pdev, adapter->dev);
9918 
9919 	/* Disable all links (expect default index) in adapter.
9920 	 * Set link address to NULL
9921 	 */
9922 	hdd_adapter_disable_all_links(adapter, true);
9923 
9924 	/* This function should be invoked at the end of this api*/
9925 	hdd_dump_func_call_map();
9926 	hdd_exit();
9927 
9928 	return QDF_STATUS_SUCCESS;
9929 }
9930 
hdd_stop_adapter(struct hdd_context * hdd_ctx,struct hdd_adapter * adapter)9931 QDF_STATUS hdd_stop_adapter(struct hdd_context *hdd_ctx,
9932 			    struct hdd_adapter *adapter)
9933 {
9934 	QDF_STATUS status;
9935 
9936 	if (adapter->device_mode == QDF_STA_MODE)
9937 		status = hdd_stop_link_adapter(hdd_ctx, adapter);
9938 
9939 	status = hdd_stop_adapter_ext(hdd_ctx, adapter);
9940 
9941 	return status;
9942 }
9943 
9944 /**
9945  * hdd_deinit_all_adapters - deinit all adapters
9946  * @hdd_ctx:   HDD context
9947  * @rtnl_held: True if RTNL lock held
9948  *
9949  */
hdd_deinit_all_adapters(struct hdd_context * hdd_ctx,bool rtnl_held)9950 void  hdd_deinit_all_adapters(struct hdd_context *hdd_ctx, bool rtnl_held)
9951 {
9952 	struct hdd_adapter *adapter, *next_adapter = NULL;
9953 
9954 	hdd_enter();
9955 
9956 	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
9957 					   NET_DEV_HOLD_DEINIT_ALL_ADAPTERS) {
9958 		hdd_deinit_adapter(hdd_ctx, adapter, rtnl_held);
9959 		hdd_adapter_dev_put_debug(adapter,
9960 					  NET_DEV_HOLD_DEINIT_ALL_ADAPTERS);
9961 	}
9962 
9963 	hdd_exit();
9964 }
9965 
hdd_stop_all_adapters(struct hdd_context * hdd_ctx)9966 QDF_STATUS hdd_stop_all_adapters(struct hdd_context *hdd_ctx)
9967 {
9968 	struct hdd_adapter *adapter, *next_adapter = NULL;
9969 
9970 	hdd_enter();
9971 
9972 	ucfg_pre_cac_stop(hdd_ctx->psoc);
9973 	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
9974 					   NET_DEV_HOLD_STOP_ALL_ADAPTERS) {
9975 		hdd_stop_adapter(hdd_ctx, adapter);
9976 		hdd_adapter_dev_put_debug(adapter,
9977 					  NET_DEV_HOLD_STOP_ALL_ADAPTERS);
9978 	}
9979 
9980 	hdd_exit();
9981 
9982 	return QDF_STATUS_SUCCESS;
9983 }
9984 
hdd_set_netdev_flags(struct hdd_adapter * adapter)9985 void hdd_set_netdev_flags(struct hdd_adapter *adapter)
9986 {
9987 	bool enable_csum = false;
9988 	bool enable_lro;
9989 	enum QDF_OPMODE device_mode;
9990 	struct hdd_context *hdd_ctx;
9991 	ol_txrx_soc_handle soc;
9992 	uint64_t temp;
9993 
9994 	if (!adapter || !adapter->dev) {
9995 		hdd_err("invalid input!");
9996 		return;
9997 	}
9998 	device_mode = adapter->device_mode;
9999 
10000 	hdd_ctx = adapter->hdd_ctx;
10001 	soc = cds_get_context(QDF_MODULE_ID_SOC);
10002 
10003 	if (!soc || !hdd_ctx) {
10004 		hdd_err("invalid SOC or HDD context!");
10005 		return;
10006 	}
10007 
10008 	/* Determine device_mode specific configuration */
10009 
10010 	enable_lro = !!cdp_cfg_get(soc, cfg_dp_lro_enable);
10011 	enable_csum = !!cdp_cfg_get(soc,
10012 				     cfg_dp_enable_ip_tcp_udp_checksum_offload);
10013 	switch (device_mode) {
10014 	case QDF_P2P_DEVICE_MODE:
10015 	case QDF_P2P_CLIENT_MODE:
10016 		enable_csum = !!cdp_cfg_get(soc,
10017 					    cfg_dp_enable_p2p_ip_tcp_udp_checksum_offload);
10018 		break;
10019 	case QDF_P2P_GO_MODE:
10020 		enable_csum = !!cdp_cfg_get(soc,
10021 					    cfg_dp_enable_p2p_ip_tcp_udp_checksum_offload);
10022 		enable_lro = false;
10023 		break;
10024 	case QDF_SAP_MODE:
10025 		enable_lro = false;
10026 		break;
10027 	case QDF_NDI_MODE:
10028 	case QDF_NAN_DISC_MODE:
10029 		enable_csum = !!cdp_cfg_get(soc,
10030 					    cfg_dp_enable_nan_ip_tcp_udp_checksum_offload);
10031 		break;
10032 	default:
10033 		break;
10034 	}
10035 
10036 	/* Set netdev flags */
10037 
10038 	/*
10039 	 * In case of USB tethering, LRO is disabled. If SSR happened
10040 	 * during that time, then as part of SSR init, do not enable
10041 	 * the LRO again. Keep the LRO state same as before SSR.
10042 	 */
10043 	if (enable_lro && !(qdf_atomic_read(&hdd_ctx->vendor_disable_lro_flag)))
10044 		adapter->dev->features |= NETIF_F_LRO;
10045 
10046 	if (enable_csum)
10047 		adapter->dev->features |=
10048 			(NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM);
10049 
10050 	if (cdp_cfg_get(soc, cfg_dp_tso_enable) && enable_csum) {
10051 		adapter->dev->features |= TSO_FEATURE_FLAGS;
10052 		adapter->tso_csum_feature_enabled = 1;
10053 	}
10054 
10055 	if (cdp_cfg_get(soc, cfg_dp_sg_enable))
10056 		adapter->dev->features |= NETIF_F_SG;
10057 
10058 	adapter->dev->features |= NETIF_F_RXCSUM;
10059 	temp = (uint64_t)adapter->dev->features;
10060 
10061 	hdd_debug("adapter mode %u dev feature 0x%llx", device_mode, temp);
10062 }
10063 
10064 #ifdef QCA_LL_LEGACY_TX_FLOW_CONTROL
10065 /**
10066  * hdd_adapter_abort_tx_flow() - Abort the tx flow control
10067  * @adapter: pointer to hdd adapter
10068  *
10069  * Resume tx and stop the tx flow control timer if the tx is paused
10070  * and the flow control timer is running. This function is called by
10071  * SSR to avoid the inconsistency of tx status before and after SSR.
10072  *
10073  * Return: void
10074  */
hdd_adapter_abort_tx_flow(struct hdd_adapter * adapter)10075 static void hdd_adapter_abort_tx_flow(struct hdd_adapter *adapter)
10076 {
10077 	if (adapter->deflink->hdd_stats.tx_rx_stats.is_txflow_paused &&
10078 	    QDF_TIMER_STATE_RUNNING ==
10079 		qdf_mc_timer_get_current_state(
10080 			&adapter->tx_flow_control_timer)) {
10081 		hdd_tx_resume_timer_expired_handler(adapter);
10082 		qdf_mc_timer_stop(&adapter->tx_flow_control_timer);
10083 	}
10084 }
10085 #else
hdd_adapter_abort_tx_flow(struct hdd_adapter * adapter)10086 static void hdd_adapter_abort_tx_flow(struct hdd_adapter *adapter)
10087 {
10088 }
10089 #endif
10090 
hdd_reset_all_adapters(struct hdd_context * hdd_ctx)10091 QDF_STATUS hdd_reset_all_adapters(struct hdd_context *hdd_ctx)
10092 {
10093 	struct hdd_adapter *adapter, *next_adapter = NULL;
10094 	bool value;
10095 	struct wlan_objmgr_vdev *vdev;
10096 	struct wlan_hdd_link_info *link_info;
10097 
10098 	hdd_enter();
10099 
10100 	ucfg_mlme_get_sap_internal_restart(hdd_ctx->psoc, &value);
10101 
10102 
10103 	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
10104 					   NET_DEV_HOLD_RESET_ALL_ADAPTERS) {
10105 		hdd_info("[SSR] reset adapter with device mode %s(%d)",
10106 			 qdf_opmode_str(adapter->device_mode),
10107 			 adapter->device_mode);
10108 
10109 		hdd_adapter_for_each_active_link_info(adapter, link_info) {
10110 			hdd_adapter_abort_tx_flow(adapter);
10111 
10112 			if ((adapter->device_mode == QDF_STA_MODE) ||
10113 			    (adapter->device_mode == QDF_P2P_CLIENT_MODE)) {
10114 				hdd_send_twt_del_all_sessions_to_userspace(link_info);
10115 
10116 				/* Stop tdls timers */
10117 				vdev = hdd_objmgr_get_vdev_by_user(link_info,
10118 							   WLAN_OSIF_TDLS_ID);
10119 				if (vdev) {
10120 					hdd_notify_tdls_reset_adapter(vdev);
10121 					hdd_objmgr_put_vdev_by_user(vdev,
10122 							    WLAN_OSIF_TDLS_ID);
10123 				}
10124 			}
10125 
10126 			if (value &&
10127 			    adapter->device_mode == QDF_SAP_MODE) {
10128 				hdd_medium_assess_ssr_enable_flag();
10129 				wlan_hdd_netif_queue_control(adapter,
10130 						     WLAN_STOP_ALL_NETIF_QUEUE,
10131 						     WLAN_CONTROL_PATH);
10132 			} else {
10133 				wlan_hdd_netif_queue_control(adapter,
10134 					   WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER,
10135 					   WLAN_CONTROL_PATH);
10136 			}
10137 
10138 			/*
10139 			 * Clear fc flag if it was set before SSR to avoid
10140 			 * TX queues permanently stopped after SSR.
10141 			 * Here WLAN_START_ALL_NETIF_QUEUE will actually
10142 			 * not start any queue since it's blocked by reason
10143 			 * WLAN_CONTROL_PATH.
10144 			 */
10145 			if (adapter->pause_map & (1 << WLAN_DATA_FLOW_CONTROL))
10146 				wlan_hdd_netif_queue_control(adapter,
10147 						     WLAN_START_ALL_NETIF_QUEUE,
10148 						     WLAN_DATA_FLOW_CONTROL);
10149 
10150 			hdd_reset_scan_operation(link_info);
10151 			if (test_bit(WMM_INIT_DONE, &adapter->event_flags)) {
10152 				hdd_wmm_adapter_close(adapter);
10153 				clear_bit(WMM_INIT_DONE, &adapter->event_flags);
10154 			}
10155 
10156 			hdd_debug("Flush any mgmt references held by peer");
10157 			hdd_stop_adapter(hdd_ctx, adapter);
10158 		}
10159 		hdd_adapter_dev_put_debug(adapter,
10160 					  NET_DEV_HOLD_RESET_ALL_ADAPTERS);
10161 	}
10162 
10163 	hdd_exit();
10164 
10165 	return QDF_STATUS_SUCCESS;
10166 }
10167 
hdd_is_any_link_opened(struct hdd_adapter * adapter)10168 static bool hdd_is_any_link_opened(struct hdd_adapter *adapter)
10169 {
10170 	struct wlan_hdd_link_info *link_info;
10171 
10172 	hdd_adapter_for_each_active_link_info(adapter, link_info) {
10173 		if (test_bit(SME_SESSION_OPENED, &link_info->link_flags))
10174 			return true;
10175 	}
10176 	return false;
10177 }
10178 
hdd_is_any_interface_open(struct hdd_context * hdd_ctx)10179 bool hdd_is_any_interface_open(struct hdd_context *hdd_ctx)
10180 {
10181 	struct hdd_adapter *adapter, *next_adapter = NULL;
10182 	wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_IS_ANY_INTERFACE_OPEN;
10183 
10184 	if (hdd_get_conparam() == QDF_GLOBAL_FTM_MODE) {
10185 		hdd_info("FTM mode, don't close the module");
10186 		return true;
10187 	}
10188 
10189 	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
10190 					   dbgid) {
10191 		if (test_bit(DEVICE_IFACE_OPENED, &adapter->event_flags) ||
10192 		    hdd_is_any_link_opened(adapter)) {
10193 			hdd_adapter_dev_put_debug(adapter, dbgid);
10194 			if (next_adapter)
10195 				hdd_adapter_dev_put_debug(next_adapter, dbgid);
10196 			return true;
10197 		}
10198 		hdd_adapter_dev_put_debug(adapter, dbgid);
10199 	}
10200 
10201 	return false;
10202 }
10203 
hdd_is_interface_up(struct hdd_adapter * adapter)10204 bool hdd_is_interface_up(struct hdd_adapter *adapter)
10205 {
10206 	if (test_bit(DEVICE_IFACE_OPENED, &adapter->event_flags))
10207 		return true;
10208 	else
10209 		return false;
10210 }
10211 
10212 #ifdef FEATURE_MONITOR_MODE_SUPPORT
10213 #ifdef WLAN_FEATURE_11BE
wlan_hdd_is_mon_channel_bw_valid(enum phy_ch_width ch_width)10214 static inline bool wlan_hdd_is_mon_channel_bw_valid(enum phy_ch_width ch_width)
10215 {
10216 	if (ch_width > CH_WIDTH_320MHZ ||
10217 	    (!cds_is_sub_20_mhz_enabled() && (ch_width == CH_WIDTH_5MHZ ||
10218 					      ch_width == CH_WIDTH_10MHZ)))
10219 		return false;
10220 
10221 	return true;
10222 }
10223 #else
wlan_hdd_is_mon_channel_bw_valid(enum phy_ch_width ch_width)10224 static inline bool wlan_hdd_is_mon_channel_bw_valid(enum phy_ch_width ch_width)
10225 {
10226 	if (ch_width > CH_WIDTH_10MHZ ||
10227 	    (!cds_is_sub_20_mhz_enabled() && (ch_width == CH_WIDTH_5MHZ ||
10228 					      ch_width == CH_WIDTH_10MHZ)))
10229 		return false;
10230 
10231 	return true;
10232 }
10233 #endif
10234 
wlan_hdd_set_mon_chan(struct hdd_adapter * adapter,qdf_freq_t freq,uint32_t bandwidth)10235 int wlan_hdd_set_mon_chan(struct hdd_adapter *adapter, qdf_freq_t freq,
10236 			  uint32_t bandwidth)
10237 {
10238 	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
10239 	struct hdd_station_ctx *sta_ctx;
10240 	struct hdd_mon_set_ch_info *ch_info;
10241 	QDF_STATUS status;
10242 	struct qdf_mac_addr bssid;
10243 	struct channel_change_req *req;
10244 	struct ch_params ch_params;
10245 	enum phy_ch_width max_fw_bw;
10246 	enum phy_ch_width ch_width;
10247 	int ret;
10248 
10249 	if ((hdd_get_conparam() != QDF_GLOBAL_MONITOR_MODE) &&
10250 	    (!policy_mgr_is_sta_mon_concurrency(hdd_ctx->psoc))) {
10251 		hdd_err("Not supported, device is not in monitor mode");
10252 		return -EINVAL;
10253 	}
10254 
10255 	if (adapter->device_mode != QDF_MONITOR_MODE) {
10256 		hdd_err_rl("Not supported, adapter is not in monitor mode");
10257 		return -EINVAL;
10258 	}
10259 
10260 	sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter->deflink);
10261 	ch_info = &sta_ctx->ch_info;
10262 
10263 	/* Verify the BW before accepting this request */
10264 	ch_width = bandwidth;
10265 
10266 	if (!wlan_hdd_is_mon_channel_bw_valid(ch_width)) {
10267 		hdd_err("invalid BW received %d", ch_width);
10268 		return -EINVAL;
10269 	}
10270 
10271 	max_fw_bw = sme_get_vht_ch_width();
10272 
10273 	hdd_debug("max fw BW %d ch width %d", max_fw_bw, ch_width);
10274 	if ((ch_width == CH_WIDTH_160MHZ &&
10275 	    max_fw_bw <= WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ) ||
10276 	    (ch_width == CH_WIDTH_80P80MHZ &&
10277 	    max_fw_bw <= WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ)) {
10278 		hdd_err("FW does not support this BW %d max BW supported %d",
10279 			ch_width, max_fw_bw);
10280 		return -EINVAL;
10281 	}
10282 
10283 	if (!hdd_is_target_eht_phy_ch_width_supported(ch_width))
10284 		return -EINVAL;
10285 
10286 	ret = hdd_validate_channel_and_bandwidth(adapter, freq, bandwidth);
10287 	if (ret) {
10288 		hdd_err("Invalid CH and BW combo");
10289 		return ret;
10290 	}
10291 
10292 	hdd_debug("Set monitor mode frequency %d", freq);
10293 	qdf_mem_copy(bssid.bytes, adapter->mac_addr.bytes,
10294 		     QDF_MAC_ADDR_SIZE);
10295 
10296 	ch_params.ch_width = bandwidth;
10297 	wlan_reg_set_channel_params_for_pwrmode(hdd_ctx->pdev, freq, 0,
10298 						&ch_params,
10299 						REG_CURRENT_PWR_MODE);
10300 
10301 	if (ch_params.ch_width == CH_WIDTH_INVALID) {
10302 		hdd_err("Invalid capture channel or bandwidth for a country");
10303 		return -EINVAL;
10304 	}
10305 	if (wlan_hdd_change_hw_mode_for_given_chnl(adapter, freq,
10306 						   POLICY_MGR_UPDATE_REASON_SET_OPER_CHAN)) {
10307 		hdd_err("Failed to change hw mode");
10308 		return -EINVAL;
10309 	}
10310 
10311 	if (adapter->monitor_mode_vdev_up_in_progress) {
10312 		hdd_err_rl("monitor mode vdev up in progress");
10313 		return -EBUSY;
10314 	}
10315 
10316 	status = qdf_event_reset(&adapter->qdf_monitor_mode_vdev_up_event);
10317 	if (QDF_IS_STATUS_ERROR(status)) {
10318 		hdd_err_rl("failed to reinit monitor mode vdev up event");
10319 		return qdf_status_to_os_return(status);
10320 	}
10321 	adapter->monitor_mode_vdev_up_in_progress = true;
10322 
10323 	qdf_mem_zero(&ch_params, sizeof(struct ch_params));
10324 
10325 	req = qdf_mem_malloc(sizeof(struct channel_change_req));
10326 	if (!req)
10327 		return -ENOMEM;
10328 	req->vdev_id = adapter->deflink->vdev_id;
10329 	req->target_chan_freq = freq;
10330 	req->ch_width = ch_width;
10331 
10332 	ch_params.ch_width = ch_width;
10333 	hdd_select_cbmode(adapter, freq, 0, &ch_params);
10334 
10335 	req->sec_ch_offset = ch_params.sec_ch_offset;
10336 	req->center_freq_seg0 = ch_params.center_freq_seg0;
10337 	req->center_freq_seg1 = ch_params.center_freq_seg1;
10338 
10339 	sme_fill_channel_change_request(hdd_ctx->mac_handle, req,
10340 					ch_info->phy_mode);
10341 	status = sme_send_channel_change_req(hdd_ctx->mac_handle, req);
10342 	qdf_mem_free(req);
10343 	if (status) {
10344 		hdd_err("Status: %d Failed to set sme_roam Channel for monitor mode",
10345 			status);
10346 		adapter->monitor_mode_vdev_up_in_progress = false;
10347 		return qdf_status_to_os_return(status);
10348 	}
10349 
10350 	adapter->mon_chan_freq = freq;
10351 	adapter->mon_bandwidth = bandwidth;
10352 
10353 	/* block on a completion variable until vdev up success*/
10354 	status = qdf_wait_for_event_completion(
10355 				       &adapter->qdf_monitor_mode_vdev_up_event,
10356 					WLAN_MONITOR_MODE_VDEV_UP_EVT);
10357 	if (QDF_IS_STATUS_ERROR(status)) {
10358 		hdd_err_rl("monitor vdev up event time out vdev id: %d",
10359 			    adapter->deflink->vdev_id);
10360 		if (adapter->qdf_monitor_mode_vdev_up_event.force_set)
10361 			/*
10362 			 * SSR/PDR has caused shutdown, which has
10363 			 * forcefully set the event.
10364 			 */
10365 			hdd_err_rl("monitor mode vdev up event forcefully set");
10366 		else if (status == QDF_STATUS_E_TIMEOUT)
10367 			hdd_err("monitor mode vdev up timed out");
10368 		else
10369 			hdd_err_rl("Failed monitor mode vdev up(status-%d)",
10370 				  status);
10371 
10372 		adapter->monitor_mode_vdev_up_in_progress = false;
10373 	}
10374 
10375 	return qdf_status_to_os_return(status);
10376 }
10377 #endif
10378 
10379 #if defined MSM_PLATFORM && (LINUX_VERSION_CODE <= KERNEL_VERSION(4, 19, 0))
10380 /**
10381  * hdd_stop_p2p_go() - call cfg80211 API to stop P2P GO
10382  * @adapter: pointer to adapter
10383  *
10384  * This function calls cfg80211 API to stop P2P GO
10385  *
10386  * Return: None
10387  */
hdd_stop_p2p_go(struct hdd_adapter * adapter)10388 static void hdd_stop_p2p_go(struct hdd_adapter *adapter)
10389 {
10390 	hdd_debug("[SSR] send stop ap to supplicant");
10391 	cfg80211_ap_stopped(adapter->dev, GFP_KERNEL);
10392 }
10393 
hdd_delete_sta(struct hdd_adapter * adapter)10394 static inline void hdd_delete_sta(struct hdd_adapter *adapter)
10395 {
10396 }
10397 
10398 #else
hdd_stop_p2p_go(struct hdd_adapter * adapter)10399 static void hdd_stop_p2p_go(struct hdd_adapter *adapter)
10400 {
10401 	hdd_debug("[SSR] send stop iface ap to supplicant");
10402 	cfg80211_stop_iface(adapter->hdd_ctx->wiphy, &adapter->wdev,
10403 			    GFP_KERNEL);
10404 }
10405 
10406 /**
10407  * hdd_delete_sta() - call cfg80211 API to delete STA
10408  * @adapter: pointer to adapter
10409  *
10410  * This function calls cfg80211 API to delete STA
10411  *
10412  * Return: None
10413  */
hdd_delete_sta(struct hdd_adapter * adapter)10414 static void hdd_delete_sta(struct hdd_adapter *adapter)
10415 {
10416 	struct qdf_mac_addr bcast_mac = QDF_MAC_ADDR_BCAST_INIT;
10417 
10418 	hdd_debug("[SSR] send restart supplicant");
10419 	/* event supplicant to restart */
10420 	cfg80211_del_sta(adapter->dev,
10421 			 (const u8 *)&bcast_mac.bytes[0],
10422 			 GFP_KERNEL);
10423 }
10424 #endif
10425 
hdd_start_all_adapters(struct hdd_context * hdd_ctx,bool rtnl_held)10426 QDF_STATUS hdd_start_all_adapters(struct hdd_context *hdd_ctx, bool rtnl_held)
10427 {
10428 	struct hdd_adapter *adapter, *next_adapter = NULL;
10429 	bool value;
10430 	wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_START_ALL_ADAPTERS;
10431 	int ret;
10432 
10433 	hdd_enter();
10434 
10435 	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
10436 					   dbgid) {
10437 		if (!hdd_is_interface_up(adapter) &&
10438 		    adapter->device_mode != QDF_NDI_MODE) {
10439 			hdd_adapter_dev_put_debug(adapter, dbgid);
10440 			continue;
10441 		}
10442 
10443 		hdd_debug("[SSR] start adapter with device mode %s(%d)",
10444 			  qdf_opmode_str(adapter->device_mode),
10445 			  adapter->device_mode);
10446 
10447 		hdd_wmm_dscp_initial_state(adapter);
10448 
10449 		switch (adapter->device_mode) {
10450 		case QDF_STA_MODE:
10451 		case QDF_P2P_CLIENT_MODE:
10452 		case QDF_P2P_DEVICE_MODE:
10453 		case QDF_NAN_DISC_MODE:
10454 
10455 			ret = hdd_start_station_adapter(adapter);
10456 			if (ret) {
10457 				hdd_err("[SSR] Failed to start station adapter: %d",
10458 					ret);
10459 				hdd_adapter_dev_put_debug(adapter, dbgid);
10460 				continue;
10461 			}
10462 			if (adapter->device_mode == QDF_STA_MODE) {
10463 				ret = hdd_start_link_adapter(adapter);
10464 				if (ret) {
10465 					hdd_err("[SSR] Failed to start link adapter: %d",
10466 						ret);
10467 					hdd_stop_adapter(hdd_ctx, adapter);
10468 					hdd_adapter_dev_put_debug(adapter,
10469 								  dbgid);
10470 					continue;
10471 				}
10472 			}
10473 
10474 			/* Open the gates for HDD to receive Wext commands */
10475 			adapter->is_link_up_service_needed = false;
10476 
10477 			if ((adapter->device_mode == QDF_NAN_DISC_MODE ||
10478 			     (adapter->device_mode == QDF_STA_MODE &&
10479 			      !ucfg_nan_is_vdev_creation_allowed(
10480 							hdd_ctx->psoc))) &&
10481 			    cds_is_driver_recovering())
10482 				ucfg_nan_disable_ind_to_userspace(
10483 							hdd_ctx->psoc);
10484 
10485 			hdd_register_tx_flow_control(adapter,
10486 					hdd_tx_resume_timer_expired_handler,
10487 					hdd_tx_resume_cb,
10488 					hdd_tx_flow_control_is_pause);
10489 
10490 			hdd_register_hl_netdev_fc_timer(
10491 					adapter,
10492 					hdd_tx_resume_timer_expired_handler);
10493 
10494 			hdd_lpass_notify_start(adapter->deflink);
10495 			break;
10496 
10497 		case QDF_SAP_MODE:
10498 			ucfg_mlme_get_sap_internal_restart(hdd_ctx->psoc,
10499 							   &value);
10500 			if (value)
10501 				hdd_start_ap_adapter(adapter, rtnl_held);
10502 
10503 			break;
10504 
10505 		case QDF_P2P_GO_MODE:
10506 			hdd_delete_sta(adapter);
10507 			break;
10508 		case QDF_MONITOR_MODE:
10509 			if (wlan_hdd_is_session_type_monitor(
10510 			    adapter->device_mode) &&
10511 			    ucfg_pkt_capture_get_mode(hdd_ctx->psoc) !=
10512 						PACKET_CAPTURE_MODE_DISABLE) {
10513 				struct hdd_adapter *sta_adapter;
10514 
10515 				sta_adapter = hdd_get_adapter(hdd_ctx,
10516 							      QDF_STA_MODE);
10517 				if (!sta_adapter) {
10518 					hdd_err("No station interface found");
10519 					return -EINVAL;
10520 				}
10521 
10522 				hdd_map_monitor_interface_vdev(sta_adapter);
10523 				break;
10524 			}
10525 			hdd_start_station_adapter(adapter);
10526 			hdd_set_mon_rx_cb(adapter->dev);
10527 
10528 			wlan_hdd_set_mon_chan(
10529 					adapter, adapter->mon_chan_freq,
10530 					adapter->mon_bandwidth);
10531 			break;
10532 		case QDF_NDI_MODE:
10533 			hdd_ndi_start(adapter->dev->name, 0);
10534 			break;
10535 		default:
10536 			break;
10537 		}
10538 		/*
10539 		 * Action frame registered in one adapter which will
10540 		 * applicable to all interfaces
10541 		 */
10542 		if (hdd_set_fw_params(adapter))
10543 			hdd_err("Failed to set adapter FW params after SSR!");
10544 
10545 		wlan_hdd_cfg80211_register_frames(adapter);
10546 		hdd_create_adapter_sysfs_files(adapter);
10547 		hdd_adapter_dev_put_debug(adapter, dbgid);
10548 	}
10549 
10550 	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
10551 					   dbgid) {
10552 		if (!hdd_is_interface_up(adapter)) {
10553 			hdd_adapter_dev_put_debug(adapter, dbgid);
10554 			continue;
10555 		}
10556 
10557 		if (adapter->device_mode == QDF_P2P_GO_MODE)
10558 			hdd_stop_p2p_go(adapter);
10559 
10560 		hdd_adapter_dev_put_debug(adapter, dbgid);
10561 	}
10562 
10563 	hdd_exit();
10564 
10565 	return QDF_STATUS_SUCCESS;
10566 }
10567 
hdd_adapter_dev_hold_debug(struct hdd_adapter * adapter,wlan_net_dev_ref_dbgid dbgid)10568 void hdd_adapter_dev_hold_debug(struct hdd_adapter *adapter,
10569 				wlan_net_dev_ref_dbgid dbgid)
10570 {
10571 	if (dbgid >= NET_DEV_HOLD_ID_MAX) {
10572 		hdd_err("Invalid debug id: %d", dbgid);
10573 		QDF_BUG(0);
10574 	}
10575 	dev_hold(adapter->dev);
10576 	qdf_atomic_inc(&adapter->net_dev_hold_ref_count[dbgid]);
10577 }
10578 
hdd_adapter_dev_put_debug(struct hdd_adapter * adapter,wlan_net_dev_ref_dbgid dbgid)10579 void hdd_adapter_dev_put_debug(struct hdd_adapter *adapter,
10580 			       wlan_net_dev_ref_dbgid dbgid)
10581 {
10582 	if (dbgid >= NET_DEV_HOLD_ID_MAX) {
10583 		hdd_err("Invalid debug id: %d", dbgid);
10584 		QDF_BUG(0);
10585 	}
10586 
10587 	if (qdf_atomic_dec_return(
10588 			&adapter->net_dev_hold_ref_count[dbgid]) < 0) {
10589 		hdd_err("dev_put detected without dev_hold for debug id: %s",
10590 			net_dev_ref_debug_string_from_id(dbgid));
10591 		QDF_BUG(0);
10592 	}
10593 
10594 	if (adapter->dev) {
10595 		dev_put(adapter->dev);
10596 	} else {
10597 		hdd_err("adapter->dev is NULL");
10598 		QDF_BUG(0);
10599 	}
10600 }
10601 
hdd_get_front_adapter(struct hdd_context * hdd_ctx,struct hdd_adapter ** out_adapter)10602 QDF_STATUS hdd_get_front_adapter(struct hdd_context *hdd_ctx,
10603 				 struct hdd_adapter **out_adapter)
10604 {
10605 	QDF_STATUS status;
10606 	qdf_list_node_t *node;
10607 
10608 	*out_adapter = NULL;
10609 
10610 	qdf_spin_lock_bh(&hdd_ctx->hdd_adapter_lock);
10611 	status = qdf_list_peek_front(&hdd_ctx->hdd_adapters, &node);
10612 	qdf_spin_unlock_bh(&hdd_ctx->hdd_adapter_lock);
10613 
10614 	if (QDF_IS_STATUS_ERROR(status))
10615 		return status;
10616 
10617 	*out_adapter = qdf_container_of(node, struct hdd_adapter, node);
10618 
10619 	return QDF_STATUS_SUCCESS;
10620 }
10621 
hdd_get_next_adapter(struct hdd_context * hdd_ctx,struct hdd_adapter * current_adapter,struct hdd_adapter ** out_adapter)10622 QDF_STATUS hdd_get_next_adapter(struct hdd_context *hdd_ctx,
10623 				struct hdd_adapter *current_adapter,
10624 				struct hdd_adapter **out_adapter)
10625 {
10626 	QDF_STATUS status;
10627 	qdf_list_node_t *node;
10628 
10629 	*out_adapter = NULL;
10630 
10631 	qdf_spin_lock_bh(&hdd_ctx->hdd_adapter_lock);
10632 	status = qdf_list_peek_next(&hdd_ctx->hdd_adapters,
10633 				    &current_adapter->node,
10634 				    &node);
10635 	qdf_spin_unlock_bh(&hdd_ctx->hdd_adapter_lock);
10636 
10637 	if (QDF_IS_STATUS_ERROR(status))
10638 		return status;
10639 
10640 	*out_adapter = qdf_container_of(node, struct hdd_adapter, node);
10641 
10642 	return status;
10643 }
10644 
hdd_get_front_adapter_no_lock(struct hdd_context * hdd_ctx,struct hdd_adapter ** out_adapter)10645 QDF_STATUS hdd_get_front_adapter_no_lock(struct hdd_context *hdd_ctx,
10646 					 struct hdd_adapter **out_adapter)
10647 {
10648 	QDF_STATUS status;
10649 	qdf_list_node_t *node;
10650 
10651 	*out_adapter = NULL;
10652 
10653 	status = qdf_list_peek_front(&hdd_ctx->hdd_adapters, &node);
10654 
10655 	if (QDF_IS_STATUS_ERROR(status))
10656 		return status;
10657 
10658 	*out_adapter = qdf_container_of(node, struct hdd_adapter, node);
10659 
10660 	return QDF_STATUS_SUCCESS;
10661 }
10662 
hdd_get_next_adapter_no_lock(struct hdd_context * hdd_ctx,struct hdd_adapter * current_adapter,struct hdd_adapter ** out_adapter)10663 QDF_STATUS hdd_get_next_adapter_no_lock(struct hdd_context *hdd_ctx,
10664 					struct hdd_adapter *current_adapter,
10665 					struct hdd_adapter **out_adapter)
10666 {
10667 	QDF_STATUS status;
10668 	qdf_list_node_t *node;
10669 
10670 	if (!current_adapter)
10671 		return QDF_STATUS_E_INVAL;
10672 
10673 	*out_adapter = NULL;
10674 
10675 	status = qdf_list_peek_next(&hdd_ctx->hdd_adapters,
10676 				    &current_adapter->node,
10677 				    &node);
10678 
10679 	if (QDF_IS_STATUS_ERROR(status))
10680 		return status;
10681 
10682 	*out_adapter = qdf_container_of(node, struct hdd_adapter, node);
10683 
10684 	return status;
10685 }
10686 
hdd_remove_adapter(struct hdd_context * hdd_ctx,struct hdd_adapter * adapter)10687 QDF_STATUS hdd_remove_adapter(struct hdd_context *hdd_ctx,
10688 			      struct hdd_adapter *adapter)
10689 {
10690 	QDF_STATUS status;
10691 
10692 	qdf_spin_lock_bh(&hdd_ctx->hdd_adapter_lock);
10693 	status = qdf_list_remove_node(&hdd_ctx->hdd_adapters, &adapter->node);
10694 	qdf_spin_unlock_bh(&hdd_ctx->hdd_adapter_lock);
10695 
10696 	return status;
10697 }
10698 
hdd_remove_front_adapter(struct hdd_context * hdd_ctx,struct hdd_adapter ** out_adapter)10699 QDF_STATUS hdd_remove_front_adapter(struct hdd_context *hdd_ctx,
10700 				    struct hdd_adapter **out_adapter)
10701 {
10702 	QDF_STATUS status;
10703 	qdf_list_node_t *node;
10704 
10705 	*out_adapter = NULL;
10706 
10707 	qdf_spin_lock_bh(&hdd_ctx->hdd_adapter_lock);
10708 	status = qdf_list_remove_front(&hdd_ctx->hdd_adapters, &node);
10709 	qdf_spin_unlock_bh(&hdd_ctx->hdd_adapter_lock);
10710 
10711 	if (QDF_IS_STATUS_ERROR(status))
10712 		return status;
10713 
10714 	*out_adapter = qdf_container_of(node, struct hdd_adapter, node);
10715 
10716 	return status;
10717 }
10718 
hdd_add_adapter_back(struct hdd_context * hdd_ctx,struct hdd_adapter * adapter)10719 QDF_STATUS hdd_add_adapter_back(struct hdd_context *hdd_ctx,
10720 				struct hdd_adapter *adapter)
10721 {
10722 	QDF_STATUS status;
10723 
10724 	qdf_spin_lock_bh(&hdd_ctx->hdd_adapter_lock);
10725 	status = qdf_list_insert_back(&hdd_ctx->hdd_adapters, &adapter->node);
10726 	qdf_spin_unlock_bh(&hdd_ctx->hdd_adapter_lock);
10727 
10728 	return status;
10729 }
10730 
hdd_add_adapter_front(struct hdd_context * hdd_ctx,struct hdd_adapter * adapter)10731 QDF_STATUS hdd_add_adapter_front(struct hdd_context *hdd_ctx,
10732 				 struct hdd_adapter *adapter)
10733 {
10734 	QDF_STATUS status;
10735 
10736 	qdf_spin_lock_bh(&hdd_ctx->hdd_adapter_lock);
10737 	status = qdf_list_insert_front(&hdd_ctx->hdd_adapters, &adapter->node);
10738 	qdf_spin_unlock_bh(&hdd_ctx->hdd_adapter_lock);
10739 
10740 	return status;
10741 }
10742 
hdd_validate_next_adapter(struct hdd_adapter ** curr,struct hdd_adapter ** next,wlan_net_dev_ref_dbgid dbg_id)10743 void hdd_validate_next_adapter(struct hdd_adapter **curr,
10744 			       struct hdd_adapter **next,
10745 			       wlan_net_dev_ref_dbgid dbg_id)
10746 {
10747 	if (!*curr || !*next || *curr != *next)
10748 		return;
10749 
10750 	hdd_err("Validation failed");
10751 	hdd_adapter_dev_put_debug(*curr, dbg_id);
10752 	*curr = NULL;
10753 	*next = NULL;
10754 }
10755 
hdd_adapter_iterate(hdd_adapter_iterate_cb cb,void * context)10756 QDF_STATUS hdd_adapter_iterate(hdd_adapter_iterate_cb cb, void *context)
10757 {
10758 	struct hdd_context *hdd_ctx;
10759 	struct hdd_adapter *cache[HDD_MAX_ADAPTERS];
10760 	struct hdd_adapter *adapter;
10761 	uint32_t n_cache = 0;
10762 	QDF_STATUS ret = QDF_STATUS_SUCCESS;
10763 	QDF_STATUS status;
10764 	int i;
10765 	struct wlan_hdd_link_info *link_info;
10766 
10767 	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
10768 	if (unlikely(!hdd_ctx))
10769 		return QDF_STATUS_E_FAILURE;
10770 
10771 	qdf_spin_lock_bh(&hdd_ctx->hdd_adapter_lock);
10772 	for (hdd_get_front_adapter_no_lock(hdd_ctx, &adapter); adapter;
10773 	     hdd_get_next_adapter_no_lock(hdd_ctx, adapter, &adapter)) {
10774 		cache[n_cache++] = adapter;
10775 	}
10776 	qdf_spin_unlock_bh(&hdd_ctx->hdd_adapter_lock);
10777 
10778 	for (i = 0; i < n_cache; i++) {
10779 		adapter = hdd_adapter_get_by_reference(hdd_ctx, cache[i]);
10780 		if (!adapter) {
10781 			/*
10782 			 * detected remove while iterating
10783 			 * concurrency failure
10784 			 */
10785 			ret = QDF_STATUS_E_FAILURE;
10786 			continue;
10787 		}
10788 		hdd_adapter_for_each_active_link_info(adapter, link_info) {
10789 			status = cb(link_info, context);
10790 			if (status != QDF_STATUS_SUCCESS) {
10791 				hdd_adapter_put(adapter);
10792 				return status;
10793 			}
10794 		}
10795 		hdd_adapter_put(adapter);
10796 	}
10797 
10798 	return ret;
10799 }
10800 
hdd_get_adapter_by_rand_macaddr(struct hdd_context * hdd_ctx,tSirMacAddr mac_addr)10801 struct hdd_adapter *hdd_get_adapter_by_rand_macaddr(
10802 	struct hdd_context *hdd_ctx, tSirMacAddr mac_addr)
10803 {
10804 	struct hdd_adapter *adapter, *next_adapter = NULL;
10805 	wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_GET_ADAPTER_BY_RAND_MACADDR;
10806 	struct wlan_hdd_link_info *link_info;
10807 
10808 	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
10809 					   dbgid) {
10810 		if (adapter->device_mode != QDF_STA_MODE &&
10811 		    adapter->device_mode != QDF_P2P_CLIENT_MODE &&
10812 		    adapter->device_mode != QDF_P2P_DEVICE_MODE) {
10813 			hdd_adapter_dev_put_debug(adapter, dbgid);
10814 			continue;
10815 		}
10816 
10817 		hdd_adapter_for_each_active_link_info(adapter, link_info) {
10818 			if (ucfg_p2p_check_random_mac(hdd_ctx->psoc,
10819 						      link_info->vdev_id,
10820 						      mac_addr)) {
10821 				hdd_adapter_dev_put_debug(adapter, dbgid);
10822 				if (next_adapter)
10823 					hdd_adapter_dev_put_debug(next_adapter,
10824 								  dbgid);
10825 				return adapter;
10826 			}
10827 		}
10828 		hdd_adapter_dev_put_debug(adapter, dbgid);
10829 	}
10830 
10831 	return NULL;
10832 }
10833 
10834 #ifdef WLAN_HDD_MULTI_VDEV_SINGLE_NDEV
hdd_get_adapter_by_macaddr(struct hdd_context * hdd_ctx,tSirMacAddr mac_addr)10835 struct hdd_adapter *hdd_get_adapter_by_macaddr(struct hdd_context *hdd_ctx,
10836 					       tSirMacAddr mac_addr)
10837 {
10838 	struct hdd_adapter *adapter, *next_adapter = NULL;
10839 	wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_GET_ADAPTER_BY_MACADDR;
10840 	struct qdf_mac_addr zero_mac_addr = QDF_MAC_ADDR_ZERO_INIT;
10841 	struct wlan_hdd_link_info *link_info;
10842 
10843 	if (!qdf_mem_cmp(mac_addr, zero_mac_addr.bytes, sizeof(tSirMacAddr)))
10844 		return NULL;
10845 
10846 	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
10847 					   dbgid) {
10848 		if (!qdf_mem_cmp(adapter->mac_addr.bytes,
10849 				 mac_addr, sizeof(tSirMacAddr))) {
10850 			hdd_adapter_dev_put_debug(adapter, dbgid);
10851 			if (next_adapter)
10852 				hdd_adapter_dev_put_debug(next_adapter,
10853 							  dbgid);
10854 			return adapter;
10855 		}
10856 		hdd_adapter_for_each_active_link_info(adapter, link_info) {
10857 			if (!qdf_mem_cmp(link_info->link_addr.bytes,
10858 					 mac_addr, sizeof(tSirMacAddr))) {
10859 				hdd_adapter_dev_put_debug(adapter, dbgid);
10860 				if (next_adapter)
10861 					hdd_adapter_dev_put_debug(next_adapter,
10862 								  dbgid);
10863 				return adapter;
10864 			}
10865 		}
10866 		hdd_adapter_dev_put_debug(adapter, dbgid);
10867 	}
10868 
10869 	return NULL;
10870 }
10871 
10872 struct wlan_hdd_link_info *
hdd_get_link_info_by_link_addr(struct hdd_context * hdd_ctx,struct qdf_mac_addr * link_addr)10873 hdd_get_link_info_by_link_addr(struct hdd_context *hdd_ctx,
10874 			       struct qdf_mac_addr *link_addr)
10875 {
10876 	struct wlan_hdd_link_info *link_info;
10877 	struct hdd_adapter *adapter, *next_adapter = NULL;
10878 	wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_GET_ADAPTER_BY_MACADDR;
10879 
10880 	if (!link_addr || qdf_is_macaddr_zero(link_addr))
10881 		return NULL;
10882 
10883 	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
10884 					   dbgid) {
10885 		hdd_adapter_for_each_link_info(adapter, link_info) {
10886 			if (qdf_is_macaddr_equal(link_addr,
10887 						 &link_info->link_addr)) {
10888 				hdd_adapter_dev_put_debug(adapter, dbgid);
10889 				if (next_adapter)
10890 					hdd_adapter_dev_put_debug(next_adapter,
10891 								  dbgid);
10892 				return link_info;
10893 			}
10894 		}
10895 		hdd_adapter_dev_put_debug(adapter, dbgid);
10896 	}
10897 
10898 	return NULL;
10899 }
10900 #else
hdd_get_adapter_by_macaddr(struct hdd_context * hdd_ctx,tSirMacAddr mac_addr)10901 struct hdd_adapter *hdd_get_adapter_by_macaddr(struct hdd_context *hdd_ctx,
10902 					       tSirMacAddr mac_addr)
10903 {
10904 	struct hdd_adapter *adapter, *next_adapter = NULL;
10905 	wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_GET_ADAPTER_BY_MACADDR;
10906 
10907 	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
10908 					   dbgid) {
10909 		if (!qdf_mem_cmp(adapter->mac_addr.bytes,
10910 				 mac_addr, sizeof(tSirMacAddr))) {
10911 			hdd_adapter_dev_put_debug(adapter, dbgid);
10912 			if (next_adapter)
10913 				hdd_adapter_dev_put_debug(next_adapter,
10914 							  dbgid);
10915 			return adapter;
10916 		}
10917 
10918 		if (hdd_adapter_is_sl_ml_adapter(adapter) &&
10919 		    !qdf_mem_cmp(adapter->mld_addr.bytes,
10920 				 mac_addr, sizeof(tSirMacAddr))) {
10921 			hdd_adapter_dev_put_debug(adapter, dbgid);
10922 			if (next_adapter)
10923 				hdd_adapter_dev_put_debug(next_adapter, dbgid);
10924 			return adapter;
10925 		}
10926 		hdd_adapter_dev_put_debug(adapter, dbgid);
10927 	}
10928 
10929 	return NULL;
10930 }
10931 
10932 struct wlan_hdd_link_info *
hdd_get_link_info_by_link_addr(struct hdd_context * hdd_ctx,struct qdf_mac_addr * link_addr)10933 hdd_get_link_info_by_link_addr(struct hdd_context *hdd_ctx,
10934 			       struct qdf_mac_addr *link_addr)
10935 {
10936 	return NULL;
10937 }
10938 #endif
10939 
10940 struct wlan_hdd_link_info *
hdd_get_link_info_by_vdev(struct hdd_context * hdd_ctx,uint32_t vdev_id)10941 hdd_get_link_info_by_vdev(struct hdd_context *hdd_ctx, uint32_t vdev_id)
10942 {
10943 	struct hdd_adapter *adapter, *next_adapter = NULL;
10944 	wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_GET_ADAPTER_BY_VDEV;
10945 	struct wlan_hdd_link_info *link_info;
10946 
10947 	if (vdev_id == WLAN_INVALID_VDEV_ID)
10948 		return NULL;
10949 
10950 	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
10951 					   dbgid) {
10952 		hdd_adapter_for_each_active_link_info(adapter, link_info) {
10953 			if (link_info->vdev_id == vdev_id) {
10954 				hdd_adapter_dev_put_debug(adapter, dbgid);
10955 				if (next_adapter)
10956 					hdd_adapter_dev_put_debug(next_adapter,
10957 								  dbgid);
10958 				return link_info;
10959 			}
10960 		}
10961 		hdd_adapter_dev_put_debug(adapter, dbgid);
10962 	}
10963 
10964 	return NULL;
10965 }
10966 
hdd_adapter_get_by_reference(struct hdd_context * hdd_ctx,struct hdd_adapter * reference)10967 struct hdd_adapter *hdd_adapter_get_by_reference(struct hdd_context *hdd_ctx,
10968 						 struct hdd_adapter *reference)
10969 {
10970 	struct hdd_adapter *adapter, *next_adapter = NULL;
10971 	wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_ADAPTER_GET_BY_REFERENCE;
10972 
10973 	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
10974 					   dbgid) {
10975 		if (adapter == reference) {
10976 			dev_hold(adapter->dev);
10977 			hdd_adapter_dev_put_debug(adapter, dbgid);
10978 			if (next_adapter)
10979 				hdd_adapter_dev_put_debug(next_adapter,
10980 							  dbgid);
10981 			break;
10982 		}
10983 		hdd_adapter_dev_put_debug(adapter, dbgid);
10984 	}
10985 
10986 	return adapter;
10987 }
10988 
hdd_adapter_put(struct hdd_adapter * adapter)10989 void hdd_adapter_put(struct hdd_adapter *adapter)
10990 {
10991 	dev_put(adapter->dev);
10992 }
10993 
hdd_get_adapter_by_iface_name(struct hdd_context * hdd_ctx,const char * iface_name)10994 struct hdd_adapter *hdd_get_adapter_by_iface_name(struct hdd_context *hdd_ctx,
10995 					     const char *iface_name)
10996 {
10997 	struct hdd_adapter *adapter, *next_adapter = NULL;
10998 	wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_GET_ADAPTER_BY_IFACE_NAME;
10999 
11000 	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
11001 					   dbgid) {
11002 		if (!qdf_str_cmp(adapter->dev->name, iface_name)) {
11003 			hdd_adapter_dev_put_debug(adapter, dbgid);
11004 			if (next_adapter)
11005 				hdd_adapter_dev_put_debug(next_adapter,
11006 							  dbgid);
11007 			return adapter;
11008 		}
11009 		hdd_adapter_dev_put_debug(adapter, dbgid);
11010 	}
11011 
11012 	return NULL;
11013 }
11014 
hdd_get_adapter_by_ifindex(struct hdd_context * hdd_ctx,uint32_t if_index)11015 struct hdd_adapter *hdd_get_adapter_by_ifindex(struct hdd_context *hdd_ctx,
11016 					       uint32_t if_index)
11017 {
11018 	struct hdd_adapter *adapter, *next_adapter = NULL;
11019 	wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_GET_ADAPTER;
11020 
11021 	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
11022 					   dbgid) {
11023 		if (adapter->dev->ifindex == if_index) {
11024 			hdd_adapter_dev_put_debug(adapter, dbgid);
11025 			if (next_adapter)
11026 				hdd_adapter_dev_put_debug(next_adapter,
11027 							  dbgid);
11028 			return adapter;
11029 		}
11030 		hdd_adapter_dev_put_debug(adapter, dbgid);
11031 	}
11032 
11033 	return NULL;
11034 }
11035 
11036 /**
11037  * hdd_get_adapter() - to get adapter matching the mode
11038  * @hdd_ctx: hdd context
11039  * @mode: adapter mode
11040  *
11041  * This routine will return the pointer to adapter matching
11042  * with the passed mode.
11043  *
11044  * Return: pointer to adapter or null
11045  */
hdd_get_adapter(struct hdd_context * hdd_ctx,enum QDF_OPMODE mode)11046 struct hdd_adapter *hdd_get_adapter(struct hdd_context *hdd_ctx,
11047 			enum QDF_OPMODE mode)
11048 {
11049 	struct hdd_adapter *adapter, *next_adapter = NULL;
11050 	wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_GET_ADAPTER;
11051 
11052 	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
11053 					   dbgid) {
11054 		if (adapter->device_mode == mode) {
11055 			hdd_adapter_dev_put_debug(adapter, dbgid);
11056 			if (next_adapter)
11057 				hdd_adapter_dev_put_debug(next_adapter,
11058 							  dbgid);
11059 			return adapter;
11060 		}
11061 		hdd_adapter_dev_put_debug(adapter, dbgid);
11062 	}
11063 
11064 	return NULL;
11065 }
11066 
hdd_get_device_mode(uint32_t vdev_id)11067 enum QDF_OPMODE hdd_get_device_mode(uint32_t vdev_id)
11068 {
11069 	struct hdd_context *hdd_ctx;
11070 	struct wlan_hdd_link_info *link_info;
11071 
11072 	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
11073 	if (!hdd_ctx)
11074 		return QDF_MAX_NO_OF_MODE;
11075 
11076 	link_info = hdd_get_link_info_by_vdev(hdd_ctx, vdev_id);
11077 	if (!link_info) {
11078 		hdd_err("Invalid vdev");
11079 		return QDF_MAX_NO_OF_MODE;
11080 	}
11081 
11082 	return link_info->adapter->device_mode;
11083 }
11084 
hdd_get_operating_chan_freq(struct hdd_context * hdd_ctx,enum QDF_OPMODE mode)11085 uint32_t hdd_get_operating_chan_freq(struct hdd_context *hdd_ctx,
11086 				     enum QDF_OPMODE mode)
11087 {
11088 	struct hdd_adapter *adapter, *next_adapter = NULL;
11089 	uint32_t oper_chan_freq = 0;
11090 	wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_GET_OPERATING_CHAN_FREQ;
11091 
11092 	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
11093 					   dbgid) {
11094 		if (mode == adapter->device_mode) {
11095 			oper_chan_freq =
11096 			    hdd_get_link_info_home_channel(adapter->deflink);
11097 			hdd_adapter_dev_put_debug(adapter, dbgid);
11098 			if (next_adapter)
11099 				hdd_adapter_dev_put_debug(next_adapter,
11100 							  dbgid);
11101 			break;
11102 		}
11103 		hdd_adapter_dev_put_debug(adapter, dbgid);
11104 	}
11105 
11106 	return oper_chan_freq;
11107 }
11108 
hdd_unregister_wext_all_adapters(struct hdd_context * hdd_ctx,bool rtnl_held)11109 static inline QDF_STATUS hdd_unregister_wext_all_adapters(
11110 		struct hdd_context *hdd_ctx,
11111 		bool rtnl_held)
11112 {
11113 	struct hdd_adapter *adapter, *next_adapter = NULL;
11114 	wlan_net_dev_ref_dbgid dbgid =
11115 				NET_DEV_HOLD_UNREGISTER_WEXT_ALL_ADAPTERS;
11116 
11117 	hdd_enter();
11118 
11119 	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
11120 					   dbgid) {
11121 		if (adapter->device_mode == QDF_STA_MODE ||
11122 		    adapter->device_mode == QDF_P2P_CLIENT_MODE ||
11123 		    adapter->device_mode == QDF_P2P_DEVICE_MODE ||
11124 		    adapter->device_mode == QDF_SAP_MODE ||
11125 		    adapter->device_mode == QDF_P2P_GO_MODE) {
11126 			hdd_wext_unregister(adapter->dev, rtnl_held);
11127 		}
11128 		hdd_adapter_dev_put_debug(adapter, dbgid);
11129 	}
11130 
11131 	hdd_exit();
11132 
11133 	return QDF_STATUS_SUCCESS;
11134 }
11135 
hdd_abort_mac_scan_all_adapters(struct hdd_context * hdd_ctx)11136 QDF_STATUS hdd_abort_mac_scan_all_adapters(struct hdd_context *hdd_ctx)
11137 {
11138 	struct hdd_adapter *adapter, *next_adapter = NULL;
11139 	wlan_net_dev_ref_dbgid dbgid =
11140 				NET_DEV_HOLD_ABORT_MAC_SCAN_ALL_ADAPTERS;
11141 	struct wlan_hdd_link_info *link_info;
11142 
11143 	hdd_enter();
11144 
11145 	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
11146 					   dbgid) {
11147 		if (adapter->device_mode == QDF_STA_MODE ||
11148 		    adapter->device_mode == QDF_P2P_CLIENT_MODE ||
11149 		    adapter->device_mode == QDF_P2P_DEVICE_MODE ||
11150 		    adapter->device_mode == QDF_SAP_MODE ||
11151 		    adapter->device_mode == QDF_P2P_GO_MODE) {
11152 			hdd_adapter_for_each_active_link_info(adapter,
11153 							      link_info) {
11154 				wlan_abort_scan(hdd_ctx->pdev, INVAL_PDEV_ID,
11155 						link_info->vdev_id,
11156 						INVALID_SCAN_ID, true);
11157 			}
11158 		}
11159 		hdd_adapter_dev_put_debug(adapter, dbgid);
11160 	}
11161 
11162 	hdd_exit();
11163 
11164 	return QDF_STATUS_SUCCESS;
11165 }
11166 
11167 /**
11168  * hdd_abort_sched_scan_all_adapters() - stops scheduled (PNO) scans for all
11169  * adapters
11170  * @hdd_ctx: The HDD context containing the adapters to operate on
11171  *
11172  * return: QDF_STATUS_SUCCESS
11173  */
hdd_abort_sched_scan_all_adapters(struct hdd_context * hdd_ctx)11174 static QDF_STATUS hdd_abort_sched_scan_all_adapters(struct hdd_context *hdd_ctx)
11175 {
11176 	struct hdd_adapter *adapter, *next_adapter = NULL;
11177 	int err;
11178 	wlan_net_dev_ref_dbgid dbgid =
11179 				NET_DEV_HOLD_ABORT_SCHED_SCAN_ALL_ADAPTERS;
11180 
11181 	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
11182 					   dbgid) {
11183 		if (adapter->device_mode == QDF_STA_MODE ||
11184 		    adapter->device_mode == QDF_P2P_CLIENT_MODE ||
11185 		    adapter->device_mode == QDF_P2P_DEVICE_MODE ||
11186 		    adapter->device_mode == QDF_SAP_MODE ||
11187 		    adapter->device_mode == QDF_P2P_GO_MODE) {
11188 			err = wlan_hdd_sched_scan_stop(adapter->dev);
11189 			if (err)
11190 				hdd_err("Unable to stop scheduled scan");
11191 		}
11192 		hdd_adapter_dev_put_debug(adapter, dbgid);
11193 	}
11194 
11195 	return QDF_STATUS_SUCCESS;
11196 }
11197 
11198 /**
11199  * hdd_unregister_notifiers - Unregister netdev notifiers.
11200  * @hdd_ctx: HDD context
11201  *
11202  * Unregister netdev notifiers like IPv4 and IPv6.
11203  *
11204  * Return: None.
11205  */
hdd_unregister_notifiers(struct hdd_context * hdd_ctx)11206 void hdd_unregister_notifiers(struct hdd_context *hdd_ctx)
11207 {
11208 	osif_dp_nud_unregister_netevent_notifier(hdd_ctx->psoc);
11209 	hdd_wlan_unregister_ip6_notifier(hdd_ctx);
11210 
11211 	unregister_inetaddr_notifier(&hdd_ctx->ipv4_notifier);
11212 }
11213 
11214 /**
11215  * hdd_exit_netlink_services - Exit netlink services
11216  * @hdd_ctx: HDD context
11217  *
11218  * Exit netlink services like cnss_diag, cesium netlink socket, ptt socket and
11219  * nl service.
11220  *
11221  * Return: None.
11222  */
hdd_exit_netlink_services(struct hdd_context * hdd_ctx)11223 static void hdd_exit_netlink_services(struct hdd_context *hdd_ctx)
11224 {
11225 	spectral_scan_deactivate_service();
11226 	cnss_diag_deactivate_service();
11227 	hdd_close_cesium_nl_sock();
11228 	ptt_sock_deactivate_svc();
11229 	hdd_deactivate_wifi_pos();
11230 
11231 	nl_srv_exit();
11232 }
11233 
11234 /**
11235  * hdd_init_netlink_services- Init netlink services
11236  * @hdd_ctx: HDD context
11237  *
11238  * Init netlink services like cnss_diag, cesium netlink socket, ptt socket and
11239  * nl service.
11240  *
11241  * Return: 0 on success and errno on failure.
11242  */
hdd_init_netlink_services(struct hdd_context * hdd_ctx)11243 static int hdd_init_netlink_services(struct hdd_context *hdd_ctx)
11244 {
11245 	int ret;
11246 
11247 	ret = wlan_hdd_nl_init(hdd_ctx);
11248 	if (ret) {
11249 		hdd_err("nl_srv_init failed: %d", ret);
11250 		goto out;
11251 	}
11252 	cds_set_radio_index(hdd_ctx->radio_index);
11253 
11254 	ret = hdd_activate_wifi_pos(hdd_ctx);
11255 	if (ret) {
11256 		hdd_err("hdd_activate_wifi_pos failed: %d", ret);
11257 		goto err_nl_srv;
11258 	}
11259 
11260 	ptt_sock_activate_svc();
11261 
11262 	ret = hdd_open_cesium_nl_sock();
11263 	if (ret)
11264 		hdd_err("hdd_open_cesium_nl_sock failed ret: %d", ret);
11265 
11266 	ret = cnss_diag_activate_service();
11267 	if (ret) {
11268 		hdd_err("cnss_diag_activate_service failed: %d", ret);
11269 		goto err_close_cesium;
11270 	}
11271 
11272 	spectral_scan_activate_service(hdd_ctx);
11273 
11274 	return 0;
11275 
11276 err_close_cesium:
11277 	hdd_close_cesium_nl_sock();
11278 	ptt_sock_deactivate_svc();
11279 	hdd_deactivate_wifi_pos();
11280 err_nl_srv:
11281 	nl_srv_exit();
11282 out:
11283 	return ret;
11284 }
11285 
11286 #ifdef SHUTDOWN_WLAN_IN_SYSTEM_SUSPEND
11287 static QDF_STATUS
hdd_shutdown_wlan_in_suspend_prepare(struct hdd_context * hdd_ctx)11288 hdd_shutdown_wlan_in_suspend_prepare(struct hdd_context *hdd_ctx)
11289 {
11290 #define SHUTDOWN_IN_SUSPEND_RETRY 30
11291 
11292 	int count = 0;
11293 	enum pmo_suspend_mode mode;
11294 
11295 	if (hdd_ctx->driver_status != DRIVER_MODULES_ENABLED) {
11296 		hdd_debug("Driver Modules not Enabled ");
11297 		return 0;
11298 	}
11299 
11300 	mode = ucfg_pmo_get_suspend_mode(hdd_ctx->psoc);
11301 	hdd_debug("suspend mode is %d", mode);
11302 
11303 	if (mode == PMO_SUSPEND_NONE || mode == PMO_SUSPEND_LEGENCY) {
11304 		hdd_debug("needn't shutdown in suspend");
11305 		return 0;
11306 	}
11307 
11308 	if (!hdd_is_any_interface_open(hdd_ctx)) {
11309 		return pld_idle_shutdown(hdd_ctx->parent_dev,
11310 					 hdd_psoc_idle_shutdown);
11311 	} else {
11312 		if (mode == PMO_SUSPEND_WOW)
11313 			return 0;
11314 	}
11315 
11316 	/*try to wait interface down for PMO_SUSPEND_SHUTDOWN mode*/
11317 	while (hdd_is_any_interface_open(hdd_ctx) &&
11318 	       count < SHUTDOWN_IN_SUSPEND_RETRY) {
11319 		count++;
11320 		hdd_debug_rl("sleep 50ms to wait adapters stopped, #%d", count);
11321 		msleep(50);
11322 	}
11323 	if (count >= SHUTDOWN_IN_SUSPEND_RETRY) {
11324 		hdd_err("some adapters not stopped");
11325 		return -EBUSY;
11326 	}
11327 	return pld_idle_shutdown(hdd_ctx->parent_dev, hdd_psoc_idle_shutdown);
11328 }
11329 
hdd_pm_notify(struct notifier_block * b,unsigned long event,void * p)11330 static int hdd_pm_notify(struct notifier_block *b,
11331 			 unsigned long event, void *p)
11332 {
11333 	struct hdd_context *hdd_ctx = container_of(b, struct hdd_context,
11334 						   pm_notifier);
11335 
11336 	if (wlan_hdd_validate_context(hdd_ctx) != 0)
11337 		return NOTIFY_STOP;
11338 
11339 	hdd_debug("got PM event: %lu", event);
11340 
11341 	switch (event) {
11342 	case PM_SUSPEND_PREPARE:
11343 	case PM_HIBERNATION_PREPARE:
11344 		if (0 != hdd_shutdown_wlan_in_suspend_prepare(hdd_ctx))
11345 			return NOTIFY_STOP;
11346 		break;
11347 	case PM_POST_SUSPEND:
11348 	case PM_POST_HIBERNATION:
11349 		break;
11350 	}
11351 
11352 	return NOTIFY_DONE;
11353 }
11354 
hdd_pm_notifier_init(struct hdd_context * hdd_ctx)11355 static void hdd_pm_notifier_init(struct hdd_context *hdd_ctx)
11356 {
11357 	hdd_ctx->pm_notifier.notifier_call = hdd_pm_notify;
11358 	register_pm_notifier(&hdd_ctx->pm_notifier);
11359 }
11360 
hdd_pm_notifier_deinit(struct hdd_context * hdd_ctx)11361 static void hdd_pm_notifier_deinit(struct hdd_context *hdd_ctx)
11362 {
11363 	unregister_pm_notifier(&hdd_ctx->pm_notifier);
11364 }
11365 #else
hdd_pm_notifier_init(struct hdd_context * hdd_ctx)11366 static inline void hdd_pm_notifier_init(struct hdd_context *hdd_ctx)
11367 {
11368 }
11369 
hdd_pm_notifier_deinit(struct hdd_context * hdd_ctx)11370 static inline void hdd_pm_notifier_deinit(struct hdd_context *hdd_ctx)
11371 {
11372 }
11373 #endif
11374 
11375 /**
11376  * hdd_context_deinit() - Deinitialize HDD context
11377  * @hdd_ctx:    HDD context.
11378  *
11379  * Deinitialize HDD context along with all the feature specific contexts but
11380  * do not free hdd context itself. Caller of this API is supposed to free
11381  * HDD context.
11382  *
11383  * return: 0 on success and errno on failure.
11384  */
hdd_context_deinit(struct hdd_context * hdd_ctx)11385 static int hdd_context_deinit(struct hdd_context *hdd_ctx)
11386 {
11387 	hdd_lpc_delete_work(hdd_ctx);
11388 
11389 	qdf_wake_lock_destroy(&hdd_ctx->monitor_mode_wakelock);
11390 
11391 	wlan_hdd_cfg80211_deinit(hdd_ctx->wiphy);
11392 
11393 	ucfg_dp_bbm_context_deinit(hdd_ctx->psoc);
11394 
11395 	hdd_sap_context_destroy(hdd_ctx);
11396 
11397 	hdd_scan_context_destroy(hdd_ctx);
11398 
11399 	qdf_list_destroy(&hdd_ctx->hdd_adapters);
11400 
11401 	return 0;
11402 }
11403 
hdd_context_destroy(struct hdd_context * hdd_ctx)11404 void hdd_context_destroy(struct hdd_context *hdd_ctx)
11405 {
11406 	wlan_hdd_sar_timers_deinit(hdd_ctx);
11407 
11408 	cds_set_context(QDF_MODULE_ID_HDD, NULL);
11409 
11410 	hdd_exit_netlink_services(hdd_ctx);
11411 
11412 	hdd_context_deinit(hdd_ctx);
11413 
11414 	hdd_objmgr_release_and_destroy_psoc(hdd_ctx);
11415 
11416 	qdf_mem_free(hdd_ctx->config);
11417 	hdd_ctx->config = NULL;
11418 	cfg_release();
11419 
11420 	hdd_pm_notifier_deinit(hdd_ctx);
11421 	qdf_delayed_work_destroy(&hdd_ctx->psoc_idle_timeout_work);
11422 	wiphy_free(hdd_ctx->wiphy);
11423 }
11424 
11425 /**
11426  * wlan_destroy_bug_report_lock() - Destroy bug report lock
11427  *
11428  * This function is used to destroy bug report lock
11429  *
11430  * Return: None
11431  */
wlan_destroy_bug_report_lock(void)11432 static void wlan_destroy_bug_report_lock(void)
11433 {
11434 	struct cds_context *p_cds_context;
11435 
11436 	p_cds_context = cds_get_global_context();
11437 	if (!p_cds_context) {
11438 		hdd_err("cds context is NULL");
11439 		return;
11440 	}
11441 
11442 	qdf_spinlock_destroy(&p_cds_context->bug_report_lock);
11443 }
11444 
11445 #ifdef DISABLE_CHANNEL_LIST
wlan_hdd_cache_chann_mutex_destroy(struct hdd_context * hdd_ctx)11446 static void wlan_hdd_cache_chann_mutex_destroy(struct hdd_context *hdd_ctx)
11447 {
11448 	qdf_mutex_destroy(&hdd_ctx->cache_channel_lock);
11449 }
11450 #else
wlan_hdd_cache_chann_mutex_destroy(struct hdd_context * hdd_ctx)11451 static void wlan_hdd_cache_chann_mutex_destroy(struct hdd_context *hdd_ctx)
11452 {
11453 }
11454 #endif
11455 
hdd_wlan_exit(struct hdd_context * hdd_ctx)11456 void hdd_wlan_exit(struct hdd_context *hdd_ctx)
11457 {
11458 	struct wiphy *wiphy = hdd_ctx->wiphy;
11459 
11460 	hdd_enter();
11461 
11462 	ucfg_dp_wait_complete_tasks();
11463 	wlan_hdd_destroy_mib_stats_lock();
11464 	hdd_debugfs_ini_config_deinit(hdd_ctx);
11465 	hdd_debugfs_mws_coex_info_deinit(hdd_ctx);
11466 	hdd_psoc_idle_timer_stop(hdd_ctx);
11467 	hdd_regulatory_deinit(hdd_ctx);
11468 
11469 	/*
11470 	 * Powersave Offload Case
11471 	 * Disable Idle Power Save Mode
11472 	 */
11473 	hdd_set_idle_ps_config(hdd_ctx, false);
11474 	/* clear the scan queue in all the scenarios */
11475 	wlan_cfg80211_cleanup_scan_queue(hdd_ctx->pdev, NULL);
11476 
11477 	if (hdd_ctx->driver_status != DRIVER_MODULES_CLOSED) {
11478 		hdd_unregister_wext_all_adapters(hdd_ctx, false);
11479 		/*
11480 		 * Cancel any outstanding scan requests.  We are about to close
11481 		 * all of our adapters, but an adapter structure is what SME
11482 		 * passes back to our callback function.  Hence if there
11483 		 * are any outstanding scan requests then there is a
11484 		 * race condition between when the adapter is closed and
11485 		 * when the callback is invoked.  We try to resolve that
11486 		 * race condition here by canceling any outstanding scans
11487 		 * before we close the adapters.
11488 		 * Note that the scans may be cancelled in an asynchronous
11489 		 * manner, so ideally there needs to be some kind of
11490 		 * synchronization.  Rather than introduce a new
11491 		 * synchronization here, we will utilize the fact that we are
11492 		 * about to Request Full Power, and since that is synchronized,
11493 		 * the expectation is that by the time Request Full Power has
11494 		 * completed, all scans will be cancelled
11495 		 */
11496 		hdd_abort_mac_scan_all_adapters(hdd_ctx);
11497 		hdd_abort_sched_scan_all_adapters(hdd_ctx);
11498 
11499 		hdd_stop_all_adapters(hdd_ctx);
11500 		hdd_deinit_all_adapters(hdd_ctx, false);
11501 	}
11502 
11503 	unregister_netdevice_notifier(&hdd_netdev_notifier);
11504 
11505 	qdf_dp_trace_deinit();
11506 
11507 	hdd_wlan_stop_modules(hdd_ctx, false);
11508 
11509 	hdd_driver_memdump_deinit();
11510 
11511 	qdf_nbuf_deinit_replenish_timer();
11512 
11513 	if (QDF_GLOBAL_MONITOR_MODE ==  hdd_get_conparam()) {
11514 		hdd_info("Release wakelock for monitor mode!");
11515 		qdf_wake_lock_release(&hdd_ctx->monitor_mode_wakelock,
11516 				      WIFI_POWER_EVENT_WAKELOCK_MONITOR_MODE);
11517 	}
11518 
11519 	qdf_spinlock_destroy(&hdd_ctx->hdd_adapter_lock);
11520 	qdf_spinlock_destroy(&hdd_ctx->connection_status_lock);
11521 	wlan_hdd_cache_chann_mutex_destroy(hdd_ctx);
11522 
11523 	osif_request_manager_deinit();
11524 
11525 	hdd_close_all_adapters(hdd_ctx, false);
11526 
11527 	wlansap_global_deinit();
11528 	/*
11529 	 * If there is re_init failure wiphy would have already de-registered
11530 	 * check the wiphy status before un-registering again
11531 	 */
11532 	if (wiphy && wiphy->registered) {
11533 		wiphy_unregister(wiphy);
11534 		wlan_hdd_cfg80211_deinit(wiphy);
11535 		hdd_lpass_notify_stop(hdd_ctx);
11536 	}
11537 
11538 	hdd_deinit_regulatory_update_event(hdd_ctx);
11539 	hdd_exit_netlink_services(hdd_ctx);
11540 #ifdef FEATURE_WLAN_CH_AVOID
11541 	mutex_destroy(&hdd_ctx->avoid_freq_lock);
11542 #endif
11543 
11544 	/* This function should be invoked at the end of this api*/
11545 	hdd_dump_func_call_map();
11546 }
11547 
11548 /**
11549  * hdd_wlan_notify_modem_power_state() - notify FW with modem power status
11550  * @state: state
11551  *
11552  * This function notifies FW with modem power status
11553  *
11554  * Return: 0 if successful, error number otherwise
11555  */
hdd_wlan_notify_modem_power_state(int state)11556 int hdd_wlan_notify_modem_power_state(int state)
11557 {
11558 	int status;
11559 	QDF_STATUS qdf_status;
11560 	struct hdd_context *hdd_ctx;
11561 	mac_handle_t mac_handle;
11562 
11563 	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
11564 	status = wlan_hdd_validate_context(hdd_ctx);
11565 	if (status)
11566 		return status;
11567 
11568 	mac_handle = hdd_ctx->mac_handle;
11569 	if (!mac_handle)
11570 		return -EINVAL;
11571 
11572 	qdf_status = sme_notify_modem_power_state(mac_handle, state);
11573 	if (QDF_STATUS_SUCCESS != qdf_status) {
11574 		hdd_err("Fail to send notification with modem power state %d",
11575 		       state);
11576 		return -EINVAL;
11577 	}
11578 	return 0;
11579 }
11580 
11581 /**
11582  * hdd_post_cds_enable_config() - HDD post cds start config helper
11583  * @hdd_ctx: Pointer to the HDD
11584  *
11585  * Return: None
11586  */
hdd_post_cds_enable_config(struct hdd_context * hdd_ctx)11587 QDF_STATUS hdd_post_cds_enable_config(struct hdd_context *hdd_ctx)
11588 {
11589 	QDF_STATUS qdf_ret_status;
11590 
11591 	/*
11592 	 * Send ready indication to the HDD.  This will kick off the MAC
11593 	 * into a 'running' state and should kick off an initial scan.
11594 	 */
11595 	qdf_ret_status = sme_hdd_ready_ind(hdd_ctx->mac_handle);
11596 	if (!QDF_IS_STATUS_SUCCESS(qdf_ret_status)) {
11597 		hdd_err("sme_hdd_ready_ind() failed with status code %08d [x%08x]",
11598 			qdf_ret_status, qdf_ret_status);
11599 		return QDF_STATUS_E_FAILURE;
11600 	}
11601 
11602 	return QDF_STATUS_SUCCESS;
11603 }
11604 
hdd_get_first_valid_adapter(struct hdd_context * hdd_ctx)11605 struct hdd_adapter *hdd_get_first_valid_adapter(struct hdd_context *hdd_ctx)
11606 {
11607 	struct hdd_adapter *adapter, *next_adapter = NULL;
11608 	wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_GET_FIRST_VALID_ADAPTER;
11609 
11610 	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
11611 					   dbgid) {
11612 		if (adapter && adapter->magic == WLAN_HDD_ADAPTER_MAGIC) {
11613 			hdd_adapter_dev_put_debug(adapter, dbgid);
11614 			if (next_adapter)
11615 				hdd_adapter_dev_put_debug(next_adapter,
11616 							  dbgid);
11617 			return adapter;
11618 		}
11619 		hdd_adapter_dev_put_debug(adapter, dbgid);
11620 	}
11621 
11622 	return NULL;
11623 }
11624 
11625 /* wake lock APIs for HDD */
hdd_prevent_suspend(uint32_t reason)11626 void hdd_prevent_suspend(uint32_t reason)
11627 {
11628 	qdf_wake_lock_acquire(&wlan_wake_lock, reason);
11629 }
11630 
hdd_allow_suspend(uint32_t reason)11631 void hdd_allow_suspend(uint32_t reason)
11632 {
11633 	qdf_wake_lock_release(&wlan_wake_lock, reason);
11634 }
11635 
hdd_prevent_suspend_timeout(uint32_t timeout,uint32_t reason)11636 void hdd_prevent_suspend_timeout(uint32_t timeout, uint32_t reason)
11637 {
11638 	cds_host_diag_log_work(&wlan_wake_lock, timeout, reason);
11639 	qdf_wake_lock_timeout_acquire(&wlan_wake_lock, timeout);
11640 }
11641 
11642 /* Initialize channel list in sme based on the country code */
hdd_set_sme_chan_list(struct hdd_context * hdd_ctx)11643 QDF_STATUS hdd_set_sme_chan_list(struct hdd_context *hdd_ctx)
11644 {
11645 	return sme_init_chan_list(hdd_ctx->mac_handle,
11646 				  hdd_ctx->reg.cc_src);
11647 }
11648 
11649 /**
11650  * hdd_is_5g_supported() - check if hardware supports 5GHz
11651  * @hdd_ctx:	Pointer to the hdd context
11652  *
11653  * HDD function to know if hardware supports 5GHz
11654  *
11655  * Return:  true if hardware supports 5GHz
11656  */
hdd_is_5g_supported(struct hdd_context * hdd_ctx)11657 bool hdd_is_5g_supported(struct hdd_context *hdd_ctx)
11658 {
11659 	if (!hdd_ctx)
11660 		return true;
11661 
11662 	if (hdd_ctx->curr_band != BAND_2G)
11663 		return true;
11664 	else
11665 		return false;
11666 }
11667 
hdd_is_2g_supported(struct hdd_context * hdd_ctx)11668 bool hdd_is_2g_supported(struct hdd_context *hdd_ctx)
11669 {
11670 	if (!hdd_ctx)
11671 		return false;
11672 
11673 	if (hdd_ctx->curr_band != BAND_5G)
11674 		return true;
11675 	else
11676 		return false;
11677 }
11678 
hdd_wiphy_init(struct hdd_context * hdd_ctx)11679 static int hdd_wiphy_init(struct hdd_context *hdd_ctx)
11680 {
11681 	struct wiphy *wiphy;
11682 	int ret_val;
11683 	uint32_t channel_bonding_mode;
11684 
11685 	wiphy = hdd_ctx->wiphy;
11686 
11687 	/*
11688 	 * The channel information in
11689 	 * wiphy needs to be initialized before wiphy registration
11690 	 */
11691 	ret_val = hdd_regulatory_init(hdd_ctx, wiphy);
11692 	if (ret_val) {
11693 		hdd_err("regulatory init failed");
11694 		return ret_val;
11695 	}
11696 
11697 	if (ucfg_pmo_get_suspend_mode(hdd_ctx->psoc) == PMO_SUSPEND_WOW) {
11698 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
11699 		wiphy->wowlan = &wowlan_support_reg_init;
11700 #else
11701 		wiphy->wowlan.flags = WIPHY_WOWLAN_ANY |
11702 				      WIPHY_WOWLAN_MAGIC_PKT |
11703 				      WIPHY_WOWLAN_DISCONNECT |
11704 				      WIPHY_WOWLAN_SUPPORTS_GTK_REKEY |
11705 				      WIPHY_WOWLAN_GTK_REKEY_FAILURE |
11706 				      WIPHY_WOWLAN_EAP_IDENTITY_REQ |
11707 				      WIPHY_WOWLAN_4WAY_HANDSHAKE |
11708 				      WIPHY_WOWLAN_RFKILL_RELEASE;
11709 
11710 		wiphy->wowlan.n_patterns = (WOW_MAX_FILTER_LISTS *
11711 				    WOW_MAX_FILTERS_PER_LIST);
11712 		wiphy->wowlan.pattern_min_len = WOW_MIN_PATTERN_SIZE;
11713 		wiphy->wowlan.pattern_max_len = WOW_MAX_PATTERN_SIZE;
11714 #endif
11715 	}
11716 
11717 	ucfg_mlme_get_channel_bonding_24ghz(hdd_ctx->psoc,
11718 					    &channel_bonding_mode);
11719 	if (hdd_ctx->obss_scan_offload) {
11720 		hdd_debug("wmi_service_obss_scan supported");
11721 	} else if (channel_bonding_mode) {
11722 		hdd_debug("enable wpa_supp obss_scan");
11723 		wiphy->features |= NL80211_FEATURE_NEED_OBSS_SCAN;
11724 	}
11725 
11726 	if (hdd_ctx->num_rf_chains == HDD_ANTENNA_MODE_2X2 &&
11727 	    ucfg_mlme_is_chain_mask_supported(hdd_ctx->psoc)) {
11728 		wiphy->available_antennas_tx = HDD_CHAIN_MODE_2X2;
11729 		wiphy->available_antennas_rx = HDD_CHAIN_MODE_2X2;
11730 	}
11731 	/* registration of wiphy dev with cfg80211 */
11732 	ret_val = wlan_hdd_cfg80211_register(wiphy);
11733 	if (0 > ret_val) {
11734 		hdd_err("wiphy registration failed");
11735 		return ret_val;
11736 	}
11737 
11738 	/* Check the kernel version for upstream commit aced43ce780dc5 that
11739 	 * has support for processing user cell_base hints when wiphy is
11740 	 * self managed or check the backport flag for the same.
11741 	 */
11742 #if defined CFG80211_USER_HINT_CELL_BASE_SELF_MANAGED ||	\
11743 		(LINUX_VERSION_CODE >= KERNEL_VERSION(4, 18, 0))
11744 	hdd_send_wiphy_regd_sync_event(hdd_ctx);
11745 #endif
11746 
11747 	pld_increment_driver_load_cnt(hdd_ctx->parent_dev);
11748 
11749 	return ret_val;
11750 }
11751 
11752 #ifdef WLAN_FEATURE_DP_BUS_BANDWIDTH
11753 #ifdef CLD_PM_QOS
11754 #define PLD_REMOVE_PM_QOS(x)
11755 #define PLD_REQUEST_PM_QOS(x, y)
11756 #define HDD_PM_QOS_HIGH_TPUT_LATENCY_US 1
11757 
11758 /**
11759  * hdd_pm_qos_update_cpu_mask() - Prepare CPU mask for PM_qos voting
11760  * @mask: return variable of cpumask for the TPUT
11761  * @enable_perf_cluster: Enable PERF cluster or not
11762  *
11763  * By default, the function sets CPU mask for silver cluster unless
11764  * enable_perf_cluster is set as true.
11765  *
11766  * Return: none
11767  */
hdd_pm_qos_update_cpu_mask(cpumask_t * mask,bool enable_perf_cluster)11768 static inline void hdd_pm_qos_update_cpu_mask(cpumask_t *mask,
11769 					      bool enable_perf_cluster)
11770 {
11771 	cpumask_set_cpu(0, mask);
11772 	cpumask_set_cpu(1, mask);
11773 	cpumask_set_cpu(2, mask);
11774 	cpumask_set_cpu(3, mask);
11775 
11776 	if (enable_perf_cluster) {
11777 		cpumask_set_cpu(4, mask);
11778 		cpumask_set_cpu(5, mask);
11779 		cpumask_set_cpu(6, mask);
11780 	}
11781 }
11782 
11783 #ifdef MSM_PLATFORM
11784 #define COPY_CPU_MASK(a, b) cpumask_copy(a, b)
11785 #define DUMP_CPU_AFFINE() hdd_info("Set cpu_mask %*pb for affine_cores", \
11786 			  cpumask_pr_args(&hdd_ctx->pm_qos_req.cpus_affine))
11787 #else
11788 #define COPY_CPU_MASK(a, b) /* no-op*/
11789 #define DUMP_CPU_AFFINE() /* no-op*/
11790 #endif
11791 
11792 #ifdef CLD_DEV_PM_QOS
11793 
_hdd_pm_qos_update_request(struct hdd_context * hdd_ctx,cpumask_t * pm_qos_cpu_mask,unsigned int latency)11794 static inline void _hdd_pm_qos_update_request(struct hdd_context *hdd_ctx,
11795 					      cpumask_t *pm_qos_cpu_mask,
11796 					      unsigned int latency)
11797 {
11798 	int cpu;
11799 	uint32_t default_latency;
11800 
11801 	default_latency = wlan_hdd_get_default_pm_qos_cpu_latency();
11802 	qdf_cpumask_copy(&hdd_ctx->qos_cpu_mask, pm_qos_cpu_mask);
11803 
11804 	if (qdf_cpumask_empty(pm_qos_cpu_mask)) {
11805 		for_each_present_cpu(cpu) {
11806 			dev_pm_qos_update_request(
11807 				&hdd_ctx->pm_qos_req[cpu],
11808 				default_latency);
11809 		}
11810 		hdd_debug("Empty mask %*pb: Set latency %u",
11811 			  qdf_cpumask_pr_args(&hdd_ctx->qos_cpu_mask),
11812 			  default_latency);
11813 	} else { /* Set latency to default for CPUs not included in mask */
11814 		qdf_for_each_cpu_not(cpu, &hdd_ctx->qos_cpu_mask) {
11815 			dev_pm_qos_update_request(
11816 				&hdd_ctx->pm_qos_req[cpu],
11817 				default_latency);
11818 		}
11819 		/* Set latency for CPUs included in mask */
11820 		qdf_for_each_cpu(cpu, &hdd_ctx->qos_cpu_mask) {
11821 			dev_pm_qos_update_request(
11822 				&hdd_ctx->pm_qos_req[cpu],
11823 				latency);
11824 		}
11825 		hdd_debug("For qos_cpu_mask %*pb set latency %u",
11826 			  qdf_cpumask_pr_args(&hdd_ctx->qos_cpu_mask),
11827 			  latency);
11828 	}
11829 }
11830 
11831 /**
11832  * hdd_pm_qos_update_request() - API to request for pm_qos
11833  * @hdd_ctx: handle to hdd context
11834  * @pm_qos_cpu_mask: cpu_mask to apply
11835  *
11836  * Return: none
11837  */
hdd_pm_qos_update_request(struct hdd_context * hdd_ctx,cpumask_t * pm_qos_cpu_mask)11838 static void hdd_pm_qos_update_request(struct hdd_context *hdd_ctx,
11839 				      cpumask_t *pm_qos_cpu_mask)
11840 {
11841 	unsigned int latency;
11842 
11843 	if (qdf_cpumask_empty(pm_qos_cpu_mask))
11844 		latency = wlan_hdd_get_default_pm_qos_cpu_latency();
11845 	else
11846 		latency = HDD_PM_QOS_HIGH_TPUT_LATENCY_US;
11847 
11848 	_hdd_pm_qos_update_request(hdd_ctx, pm_qos_cpu_mask, latency);
11849 }
11850 
hdd_pm_qos_add_request(struct hdd_context * hdd_ctx)11851 static inline void hdd_pm_qos_add_request(struct hdd_context *hdd_ctx)
11852 {
11853 	struct device *cpu_dev;
11854 	int cpu;
11855 	uint32_t default_latency = wlan_hdd_get_default_pm_qos_cpu_latency();
11856 
11857 
11858 	qdf_cpumask_clear(&hdd_ctx->qos_cpu_mask);
11859 	hdd_pm_qos_update_cpu_mask(&hdd_ctx->qos_cpu_mask, false);
11860 
11861 	for_each_present_cpu(cpu) {
11862 		cpu_dev = get_cpu_device(cpu);
11863 		dev_pm_qos_add_request(cpu_dev, &hdd_ctx->pm_qos_req[cpu],
11864 				       DEV_PM_QOS_RESUME_LATENCY,
11865 				       default_latency);
11866 		hdd_debug("Set qos_cpu_mask %*pb for affine_cores",
11867 			 cpumask_pr_args(&hdd_ctx->qos_cpu_mask));
11868 	}
11869 }
11870 
hdd_pm_qos_remove_request(struct hdd_context * hdd_ctx)11871 static inline void hdd_pm_qos_remove_request(struct hdd_context *hdd_ctx)
11872 {
11873 	int cpu;
11874 
11875 	for_each_present_cpu(cpu) {
11876 		dev_pm_qos_remove_request(&hdd_ctx->pm_qos_req[cpu]);
11877 		hdd_debug("Remove dev_pm_qos_request for all cpus: %d", cpu);
11878 	}
11879 	qdf_cpumask_clear(&hdd_ctx->qos_cpu_mask);
11880 }
11881 
11882 #else /* CLD_DEV_PM_QOS */
11883 
11884 #if defined(CONFIG_SMP) && defined(MSM_PLATFORM)
11885 /**
11886  * hdd_set_default_pm_qos_mask() - Update PM_qos request for AFFINE_CORES
11887  * @hdd_ctx: handle to hdd context
11888  *
11889  * Return: none
11890  */
hdd_set_default_pm_qos_mask(struct hdd_context * hdd_ctx)11891 static inline void hdd_set_default_pm_qos_mask(struct hdd_context *hdd_ctx)
11892 {
11893 	hdd_ctx->pm_qos_req.type = PM_QOS_REQ_AFFINE_CORES;
11894 	qdf_cpumask_clear(&hdd_ctx->pm_qos_req.cpus_affine);
11895 	hdd_pm_qos_update_cpu_mask(&hdd_ctx->pm_qos_req.cpus_affine, false);
11896 }
11897 #else
hdd_set_default_pm_qos_mask(struct hdd_context * hdd_ctx)11898 static inline void hdd_set_default_pm_qos_mask(struct hdd_context *hdd_ctx)
11899 {
11900 }
11901 #endif
11902 
11903 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 7, 0))
11904 /**
11905  * hdd_pm_qos_update_request() - API to request for pm_qos
11906  * @hdd_ctx: handle to hdd context
11907  * @pm_qos_cpu_mask: cpu_mask to apply
11908  *
11909  * Return: none
11910  */
hdd_pm_qos_update_request(struct hdd_context * hdd_ctx,cpumask_t * pm_qos_cpu_mask)11911 static inline void hdd_pm_qos_update_request(struct hdd_context *hdd_ctx,
11912 					     cpumask_t *pm_qos_cpu_mask)
11913 {
11914 	COPY_CPU_MASK(&hdd_ctx->pm_qos_req.cpus_affine, pm_qos_cpu_mask);
11915 
11916 	if (cpumask_empty(pm_qos_cpu_mask))
11917 		cpu_latency_qos_update_request(&hdd_ctx->pm_qos_req,
11918 					       PM_QOS_DEFAULT_VALUE);
11919 	else
11920 		cpu_latency_qos_update_request(&hdd_ctx->pm_qos_req, 1);
11921 }
11922 
hdd_pm_qos_add_request(struct hdd_context * hdd_ctx)11923 static inline void hdd_pm_qos_add_request(struct hdd_context *hdd_ctx)
11924 {
11925 	hdd_set_default_pm_qos_mask(hdd_ctx);
11926 	cpu_latency_qos_add_request(&hdd_ctx->pm_qos_req, PM_QOS_DEFAULT_VALUE);
11927 	DUMP_CPU_AFFINE();
11928 }
11929 
hdd_pm_qos_remove_request(struct hdd_context * hdd_ctx)11930 static inline void hdd_pm_qos_remove_request(struct hdd_context *hdd_ctx)
11931 {
11932 	cpu_latency_qos_remove_request(&hdd_ctx->pm_qos_req);
11933 }
11934 #else
hdd_pm_qos_update_request(struct hdd_context * hdd_ctx,cpumask_t * pm_qos_cpu_mask)11935 static inline void hdd_pm_qos_update_request(struct hdd_context *hdd_ctx,
11936 					     cpumask_t *pm_qos_cpu_mask)
11937 {
11938 	COPY_CPU_MASK(&hdd_ctx->pm_qos_req.cpus_affine, pm_qos_cpu_mask);
11939 
11940 	if (cpumask_empty(pm_qos_cpu_mask))
11941 		pm_qos_update_request(&hdd_ctx->pm_qos_req,
11942 				      PM_QOS_DEFAULT_VALUE);
11943 	else
11944 		pm_qos_update_request(&hdd_ctx->pm_qos_req, 1);
11945 }
11946 
hdd_pm_qos_add_request(struct hdd_context * hdd_ctx)11947 static inline void hdd_pm_qos_add_request(struct hdd_context *hdd_ctx)
11948 {
11949 	hdd_set_default_pm_qos_mask(hdd_ctx);
11950 	pm_qos_add_request(&hdd_ctx->pm_qos_req, PM_QOS_CPU_DMA_LATENCY,
11951 			   PM_QOS_DEFAULT_VALUE);
11952 	DUMP_CPU_AFFINE();
11953 }
11954 
hdd_pm_qos_remove_request(struct hdd_context * hdd_ctx)11955 static inline void hdd_pm_qos_remove_request(struct hdd_context *hdd_ctx)
11956 {
11957 	pm_qos_remove_request(&hdd_ctx->pm_qos_req);
11958 }
11959 #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(5, 7, 0) */
11960 #endif /* CLD_DEV_PM_QOS */
11961 
11962 #else /* CLD_PM_QOS */
11963 #define PLD_REMOVE_PM_QOS(x) pld_remove_pm_qos(x)
11964 #define PLD_REQUEST_PM_QOS(x, y) pld_request_pm_qos(x, y)
11965 
hdd_pm_qos_add_request(struct hdd_context * hdd_ctx)11966 static inline void hdd_pm_qos_add_request(struct hdd_context *hdd_ctx)
11967 {
11968 }
11969 
hdd_pm_qos_remove_request(struct hdd_context * hdd_ctx)11970 static inline void hdd_pm_qos_remove_request(struct hdd_context *hdd_ctx)
11971 {
11972 }
11973 
hdd_pm_qos_update_cpu_mask(cpumask_t * mask,bool high_throughput)11974 static inline void hdd_pm_qos_update_cpu_mask(cpumask_t *mask,
11975 					      bool high_throughput)
11976 {
11977 }
11978 
hdd_pm_qos_update_request(struct hdd_context * hdd_ctx,cpumask_t * pm_qos_cpu_mask)11979 static inline void hdd_pm_qos_update_request(struct hdd_context *hdd_ctx,
11980 					     cpumask_t *pm_qos_cpu_mask)
11981 {
11982 }
11983 #endif /* CLD_PM_QOS */
11984 
11985 #if defined(CLD_PM_QOS)
11986 #if defined(CLD_DEV_PM_QOS)
wlan_hdd_set_pm_qos_request(struct hdd_context * hdd_ctx,bool pm_qos_request)11987 void wlan_hdd_set_pm_qos_request(struct hdd_context *hdd_ctx,
11988 				 bool pm_qos_request)
11989 {
11990 	cpumask_t pm_qos_cpu_mask;
11991 
11992 	cpumask_clear(&pm_qos_cpu_mask);
11993 	if (pm_qos_request) {
11994 		hdd_ctx->pm_qos_request = true;
11995 		if (!hdd_ctx->hbw_requested) {
11996 			hdd_pm_qos_update_cpu_mask(&pm_qos_cpu_mask, true);
11997 			hdd_pm_qos_update_request(hdd_ctx, &pm_qos_cpu_mask);
11998 			hdd_ctx->hbw_requested = true;
11999 		}
12000 	} else {
12001 		if (hdd_ctx->hbw_requested) {
12002 			hdd_pm_qos_update_cpu_mask(&pm_qos_cpu_mask, false);
12003 			hdd_pm_qos_update_request(hdd_ctx, &pm_qos_cpu_mask);
12004 			hdd_ctx->hbw_requested = false;
12005 		}
12006 		hdd_ctx->pm_qos_request = false;
12007 	}
12008 }
12009 #else /* CLD_DEV_PM_QOS */
12010 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 7, 0))
wlan_hdd_set_pm_qos_request(struct hdd_context * hdd_ctx,bool pm_qos_request)12011 void wlan_hdd_set_pm_qos_request(struct hdd_context *hdd_ctx,
12012 				 bool pm_qos_request)
12013 {
12014 	if (pm_qos_request) {
12015 		hdd_ctx->pm_qos_request = true;
12016 		if (!hdd_ctx->hbw_requested) {
12017 			cpumask_setall(&hdd_ctx->pm_qos_req.cpus_affine);
12018 			cpu_latency_qos_update_request(
12019 				&hdd_ctx->pm_qos_req,
12020 				DISABLE_KRAIT_IDLE_PS_VAL);
12021 			hdd_ctx->hbw_requested = true;
12022 		}
12023 	} else {
12024 		if (hdd_ctx->hbw_requested) {
12025 			cpumask_clear(&hdd_ctx->pm_qos_req.cpus_affine);
12026 			cpu_latency_qos_update_request(&hdd_ctx->pm_qos_req,
12027 						       PM_QOS_DEFAULT_VALUE);
12028 			hdd_ctx->hbw_requested = false;
12029 		}
12030 		hdd_ctx->pm_qos_request = false;
12031 	}
12032 }
12033 #else /* (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 7, 0)) */
wlan_hdd_set_pm_qos_request(struct hdd_context * hdd_ctx,bool pm_qos_request)12034 void wlan_hdd_set_pm_qos_request(struct hdd_context *hdd_ctx,
12035 				 bool pm_qos_request)
12036 {
12037 	if (pm_qos_request) {
12038 		hdd_ctx->pm_qos_request = true;
12039 		if (!hdd_ctx->hbw_requested) {
12040 			cpumask_setall(&hdd_ctx->pm_qos_req.cpus_affine);
12041 			pm_qos_update_request(&hdd_ctx->pm_qos_req,
12042 					      DISABLE_KRAIT_IDLE_PS_VAL);
12043 			hdd_ctx->hbw_requested = true;
12044 		}
12045 	} else {
12046 		if (hdd_ctx->hbw_requested) {
12047 			cpumask_clear(&hdd_ctx->pm_qos_req.cpus_affine);
12048 			pm_qos_update_request(&hdd_ctx->pm_qos_req,
12049 					      PM_QOS_DEFAULT_VALUE);
12050 			hdd_ctx->hbw_requested = false;
12051 		}
12052 		hdd_ctx->pm_qos_request = false;
12053 	}
12054 }
12055 #endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 7, 0)) */
12056 #endif /* CLD_DEV_PM_QOS*/
12057 #endif /* CLD_PM_QOS */
12058 
12059 #define HDD_BW_GET_DIFF(_x, _y) (unsigned long)((ULONG_MAX - (_y)) + (_x) + 1)
12060 
12061 #ifdef WLAN_FEATURE_MSCS
12062 
12063 static
hdd_send_mscs_action_frame(struct wlan_hdd_link_info * link_info)12064 void hdd_send_mscs_action_frame(struct wlan_hdd_link_info *link_info)
12065 {
12066 	struct hdd_context *hdd_ctx = link_info->adapter->hdd_ctx;
12067 	uint64_t mscs_vo_pkt_delta;
12068 	unsigned long tx_vo_pkts = 0;
12069 	unsigned int cpu;
12070 	struct hdd_tx_rx_stats *stats = &link_info->hdd_stats.tx_rx_stats;
12071 	uint32_t bus_bw_compute_interval;
12072 
12073 	/*
12074 	 * To disable MSCS feature in driver set mscs_pkt_threshold = 0
12075 	 * in ini file.
12076 	 */
12077 	if (!hdd_ctx->config->mscs_pkt_threshold)
12078 		return;
12079 
12080 	for (cpu = 0; cpu < NUM_CPUS; cpu++)
12081 		tx_vo_pkts += stats->per_cpu[cpu].tx_classified_ac[SME_AC_VO];
12082 
12083 	if (!link_info->mscs_counter)
12084 		link_info->mscs_prev_tx_vo_pkts = tx_vo_pkts;
12085 
12086 	link_info->mscs_counter++;
12087 	bus_bw_compute_interval =
12088 		ucfg_dp_get_bus_bw_compute_interval(hdd_ctx->psoc);
12089 	if (link_info->mscs_counter * bus_bw_compute_interval >=
12090 	    hdd_ctx->config->mscs_voice_interval * 1000) {
12091 		link_info->mscs_counter = 0;
12092 		mscs_vo_pkt_delta =
12093 			HDD_BW_GET_DIFF(tx_vo_pkts,
12094 					link_info->mscs_prev_tx_vo_pkts);
12095 		if (mscs_vo_pkt_delta > hdd_ctx->config->mscs_pkt_threshold &&
12096 		    !mlme_get_is_mscs_req_sent(link_info->vdev))
12097 			sme_send_mscs_action_frame(link_info->vdev_id);
12098 	}
12099 }
12100 #else
12101 static inline
hdd_send_mscs_action_frame(struct wlan_hdd_link_info * link_info)12102 void hdd_send_mscs_action_frame(struct wlan_hdd_link_info *link_info)
12103 {
12104 }
12105 #endif
12106 #endif /*WLAN_FEATURE_DP_BUS_BANDWIDTH*/
12107 
12108 /**
12109  * wlan_hdd_sta_get_dot11mode() - GET AP client count
12110  * @context: HDD context
12111  * @netdev: netdev
12112  * @dot11_mode: variable in which mode need to update.
12113  *
12114  * Return: true on success else false
12115  */
12116 static inline
wlan_hdd_sta_get_dot11mode(hdd_cb_handle context,qdf_netdev_t netdev,enum qca_wlan_802_11_mode * dot11_mode)12117 bool wlan_hdd_sta_get_dot11mode(hdd_cb_handle context, qdf_netdev_t netdev,
12118 				enum qca_wlan_802_11_mode *dot11_mode)
12119 {
12120 	struct hdd_context *hdd_ctx;
12121 	struct wlan_hdd_link_info *link_info;
12122 	struct hdd_station_ctx *sta_ctx;
12123 	struct hdd_adapter *adapter;
12124 	enum csr_cfgdot11mode mode;
12125 
12126 	hdd_ctx = hdd_cb_handle_to_context(context);
12127 	if (!hdd_ctx)
12128 		return false;
12129 
12130 	adapter = WLAN_HDD_GET_PRIV_PTR(netdev);
12131 	if (!adapter)
12132 		return false;
12133 
12134 	link_info = adapter->deflink;
12135 
12136 	sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(link_info);
12137 	mode = sta_ctx->conn_info.dot11mode;
12138 	*dot11_mode = hdd_convert_cfgdot11mode_to_80211mode(mode);
12139 	return true;
12140 }
12141 
12142 /**
12143  * wlan_hdd_get_ap_client_count() - GET AP client count
12144  * @context: HDD context
12145  * @netdev: netdev
12146  * @client_count: variable in which number of client need to update.
12147  *
12148  * Return: true on success else false
12149  */
12150 static inline
wlan_hdd_get_ap_client_count(hdd_cb_handle context,qdf_netdev_t netdev,uint16_t * client_count)12151 bool wlan_hdd_get_ap_client_count(hdd_cb_handle context, qdf_netdev_t netdev,
12152 				  uint16_t *client_count)
12153 {
12154 	struct hdd_context *hdd_ctx;
12155 	struct wlan_hdd_link_info *link_info;
12156 	struct hdd_adapter *adapter;
12157 	struct hdd_ap_ctx *ap_ctx;
12158 	enum qca_wlan_802_11_mode i;
12159 
12160 	hdd_ctx = hdd_cb_handle_to_context(context);
12161 	if (!hdd_ctx) {
12162 		hdd_err("hdd ctx is null");
12163 		return false;
12164 	}
12165 
12166 	adapter = WLAN_HDD_GET_PRIV_PTR(netdev);
12167 	if (!adapter) {
12168 		hdd_err("adapter is null");
12169 		return false;
12170 	}
12171 
12172 	link_info = adapter->deflink;
12173 	ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(link_info);
12174 	if (!ap_ctx->ap_active)
12175 		return false;
12176 
12177 	for (i = QCA_WLAN_802_11_MODE_11B; i < QCA_WLAN_802_11_MODE_INVALID;
12178 	     i++)
12179 		client_count[i] = ap_ctx->client_count[i];
12180 
12181 	return true;
12182 }
12183 
12184 /**
12185  * wlan_hdd_sta_ndi_connected() - Check if NDI connected
12186  * @context: HDD context
12187  * @netdev: netdev
12188  *
12189  * Return: true if NDI connected else false
12190  */
12191 static inline
wlan_hdd_sta_ndi_connected(hdd_cb_handle context,qdf_netdev_t netdev)12192 bool wlan_hdd_sta_ndi_connected(hdd_cb_handle context, qdf_netdev_t netdev)
12193 {
12194 	struct hdd_adapter *adapter;
12195 	struct hdd_context *hdd_ctx;
12196 	struct wlan_hdd_link_info *link_info;
12197 	struct hdd_station_ctx *sta_ctx;
12198 
12199 	hdd_ctx = hdd_cb_handle_to_context(context);
12200 	if (!hdd_ctx) {
12201 		hdd_err("hdd_ctx is null");
12202 		return false;
12203 	}
12204 
12205 	adapter = WLAN_HDD_GET_PRIV_PTR(netdev);
12206 	if (!adapter) {
12207 		hdd_err("adapter is null");
12208 		return false;
12209 	}
12210 
12211 	link_info = adapter->deflink;
12212 
12213 	sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(link_info);
12214 	if (sta_ctx->conn_info.conn_state != eConnectionState_NdiConnected)
12215 		return false;
12216 
12217 	return true;
12218 }
12219 
12220 /**
12221  * wlan_hdd_pktlog_enable_disable() - Enable/Disable packet logging
12222  * @context: HDD context
12223  * @enable_disable_flag: Flag to enable/disable
12224  * @user_triggered: triggered through iwpriv
12225  * @size: buffer size to be used for packetlog
12226  *
12227  * Return: 0 on success; error number otherwise
12228  */
12229 static inline
wlan_hdd_pktlog_enable_disable(hdd_cb_handle context,bool enable_disable_flag,uint8_t user_triggered,int size)12230 int wlan_hdd_pktlog_enable_disable(hdd_cb_handle context,
12231 				   bool enable_disable_flag,
12232 				   uint8_t user_triggered, int size)
12233 {
12234 	struct hdd_context *hdd_ctx = hdd_cb_handle_to_context(context);
12235 
12236 	if (!hdd_ctx) {
12237 		hdd_err("hdd_ctx is null");
12238 		return -EINVAL;
12239 	}
12240 	return hdd_pktlog_enable_disable(hdd_ctx, enable_disable_flag,
12241 					 user_triggered, size);
12242 }
12243 
12244 /**
12245  * wlan_hdd_is_roaming_in_progress() - Check if roaming is in progress
12246  * @context: HDD context
12247  *
12248  * Return: true if roaming is in progress else false
12249  */
wlan_hdd_is_roaming_in_progress(hdd_cb_handle context)12250 static inline bool wlan_hdd_is_roaming_in_progress(hdd_cb_handle context)
12251 {
12252 	struct hdd_context *hdd_ctx = hdd_cb_handle_to_context(context);
12253 
12254 	if (!hdd_ctx) {
12255 		hdd_err("hdd_ctx is null");
12256 		return false;
12257 	}
12258 	return hdd_is_roaming_in_progress(hdd_ctx);
12259 }
12260 
12261 /**
12262  * hdd_is_ap_active() - Check if AP is active
12263  * @context: HDD context
12264  * @netdev: netdev
12265  *
12266  * Return: true if AP active else false
12267  */
hdd_is_ap_active(hdd_cb_handle context,qdf_netdev_t netdev)12268 static inline bool hdd_is_ap_active(hdd_cb_handle context, qdf_netdev_t netdev)
12269 {
12270 	struct hdd_adapter *adapter;
12271 	struct hdd_context *hdd_ctx;
12272 	struct wlan_hdd_link_info *link_info;
12273 
12274 	hdd_ctx = hdd_cb_handle_to_context(context);
12275 	if (!hdd_ctx) {
12276 		hdd_err("hdd_ctx is null");
12277 		return false;
12278 	}
12279 
12280 	adapter = WLAN_HDD_GET_PRIV_PTR(netdev);
12281 	if (!adapter) {
12282 		hdd_err("adapter is null");
12283 		return false;
12284 	}
12285 
12286 	link_info = adapter->deflink;
12287 	return WLAN_HDD_GET_AP_CTX_PTR(link_info)->ap_active;
12288 }
12289 
12290 /**
12291  * wlan_hdd_napi_apply_throughput_policy() - Apply NAPI policy
12292  * @context: HDD context
12293  * @tx_packets: tx_packets
12294  * @rx_packets: rx_packets
12295  *
12296  * Return: 0 on success else error code
12297  */
12298 static inline
wlan_hdd_napi_apply_throughput_policy(hdd_cb_handle context,uint64_t tx_packets,uint64_t rx_packets)12299 int wlan_hdd_napi_apply_throughput_policy(hdd_cb_handle context,
12300 					  uint64_t tx_packets,
12301 					  uint64_t rx_packets)
12302 {
12303 	struct hdd_context *hdd_ctx = hdd_cb_handle_to_context(context);
12304 	int rc = 0;
12305 
12306 	if (!hdd_ctx) {
12307 		hdd_err("hdd_ctx is null");
12308 		return 0;
12309 	}
12310 	if (hdd_ctx->config->napi_cpu_affinity_mask)
12311 		rc = hdd_napi_apply_throughput_policy(hdd_ctx, tx_packets,
12312 						      rx_packets);
12313 	return rc;
12314 }
12315 
12316 /**
12317  * hdd_is_link_adapter() - Check if adapter is link adapter
12318  * @context: HDD context
12319  * @vdev_id: Vdev ID
12320  *
12321  * Return: true if link adapter else false
12322  */
hdd_is_link_adapter(hdd_cb_handle context,uint8_t vdev_id)12323 static inline bool hdd_is_link_adapter(hdd_cb_handle context, uint8_t vdev_id)
12324 {
12325 	struct hdd_context *hdd_ctx;
12326 	struct wlan_hdd_link_info *link_info;
12327 
12328 	hdd_ctx = hdd_cb_handle_to_context(context);
12329 	if (!hdd_ctx) {
12330 		hdd_err("hdd_ctx is null");
12331 		return false;
12332 	}
12333 
12334 	link_info = hdd_get_link_info_by_vdev(hdd_ctx, vdev_id);
12335 	if (!link_info) {
12336 		hdd_err("Invalid vdev");
12337 		return false;
12338 	}
12339 	return hdd_adapter_is_link_adapter(link_info->adapter);
12340 }
12341 
12342 /**
12343  * hdd_get_pause_map() - Get pause map value
12344  * @context: HDD context
12345  * @netdev: netdev
12346  *
12347  * Return: pause map value
12348  */
12349 static inline
hdd_get_pause_map(hdd_cb_handle context,qdf_netdev_t netdev)12350 uint32_t hdd_get_pause_map(hdd_cb_handle context, qdf_netdev_t netdev)
12351 {
12352 	struct hdd_adapter *adapter;
12353 
12354 	adapter = WLAN_HDD_GET_PRIV_PTR(netdev);
12355 	if (!adapter) {
12356 		hdd_err("adapter is null");
12357 		return 0;
12358 	}
12359 
12360 	return adapter->pause_map;
12361 }
12362 
12363 /**
12364  * hdd_any_adapter_connected() - Check if any adapter connected.
12365  * @context: HDD context
12366  *
12367  * Return: True if connected else false.
12368  */
hdd_any_adapter_connected(hdd_cb_handle context)12369 static inline bool hdd_any_adapter_connected(hdd_cb_handle context)
12370 {
12371 	struct hdd_context *hdd_ctx = hdd_cb_handle_to_context(context);
12372 
12373 	if (!hdd_ctx) {
12374 		hdd_err("hdd_ctx is null");
12375 		return false;
12376 	}
12377 
12378 	return hdd_is_any_adapter_connected(hdd_ctx);
12379 }
12380 
12381 #ifdef WLAN_FEATURE_DP_BUS_BANDWIDTH
12382 /**
12383  * hdd_pld_request_pm_qos() - Request PLD PM QoS request
12384  * @context: HDD context
12385  *
12386  * Return: None
12387  */
hdd_pld_request_pm_qos(hdd_cb_handle context)12388 static inline void hdd_pld_request_pm_qos(hdd_cb_handle context)
12389 {
12390 	struct hdd_context *hdd_ctx = hdd_cb_handle_to_context(context);
12391 
12392 	if (!hdd_ctx) {
12393 		hdd_err("hdd_ctx is null");
12394 		return;
12395 	}
12396 
12397 	if (!hdd_ctx->hbw_requested) {
12398 		PLD_REQUEST_PM_QOS(hdd_ctx->parent_dev, 1);
12399 		hdd_ctx->hbw_requested = true;
12400 	}
12401 }
12402 
12403 /**
12404  * hdd_pld_remove_pm_qos() - Remove PLD PM QoS request
12405  * @context: HDD context
12406  *
12407  * Return: None
12408  */
hdd_pld_remove_pm_qos(hdd_cb_handle context)12409 static inline void hdd_pld_remove_pm_qos(hdd_cb_handle context)
12410 {
12411 	struct hdd_context *hdd_ctx = hdd_cb_handle_to_context(context);
12412 
12413 	if (!hdd_ctx) {
12414 		hdd_err("hdd_ctx is null");
12415 		return;
12416 	}
12417 
12418 	if (hdd_ctx->hbw_requested &&
12419 	    !hdd_ctx->pm_qos_request) {
12420 		PLD_REMOVE_PM_QOS(hdd_ctx->parent_dev);
12421 		hdd_ctx->hbw_requested = false;
12422 	}
12423 }
12424 
12425 /**
12426  * wlan_hdd_pm_qos_update_request() - Update PM QoS request
12427  * @context: HDD context
12428  * @pm_qos_cpu_mask: CPU mask
12429  *
12430  * Return: None
12431  */
12432 static inline void
wlan_hdd_pm_qos_update_request(hdd_cb_handle context,cpumask_t * pm_qos_cpu_mask)12433 wlan_hdd_pm_qos_update_request(hdd_cb_handle context,
12434 			       cpumask_t *pm_qos_cpu_mask)
12435 {
12436 	struct hdd_context *hdd_ctx = hdd_cb_handle_to_context(context);
12437 
12438 	if (!hdd_ctx) {
12439 		hdd_err("hdd_ctx is null");
12440 		return;
12441 	}
12442 
12443 	if (!hdd_ctx->pm_qos_request)
12444 		hdd_pm_qos_update_request(hdd_ctx, pm_qos_cpu_mask);
12445 }
12446 
12447 /**
12448  * wlan_hdd_pm_qos_add_request() - Add PM QoS request
12449  * @context: HDD context
12450  *
12451  * Return: None
12452  */
wlan_hdd_pm_qos_add_request(hdd_cb_handle context)12453 static inline void wlan_hdd_pm_qos_add_request(hdd_cb_handle context)
12454 {
12455 	struct hdd_context *hdd_ctx = hdd_cb_handle_to_context(context);
12456 
12457 	if (!hdd_ctx) {
12458 		hdd_err("hdd_ctx is null");
12459 		return;
12460 	}
12461 
12462 	hdd_pm_qos_add_request(hdd_ctx);
12463 }
12464 
12465 /**
12466  * wlan_hdd_pm_qos_remove_request() - remove PM QoS request
12467  * @context: HDD context
12468  *
12469  * Return: None
12470  */
wlan_hdd_pm_qos_remove_request(hdd_cb_handle context)12471 static inline void wlan_hdd_pm_qos_remove_request(hdd_cb_handle context)
12472 {
12473 	struct hdd_context *hdd_ctx = hdd_cb_handle_to_context(context);
12474 
12475 	if (!hdd_ctx) {
12476 		hdd_err("hdd_ctx is null");
12477 		return;
12478 	}
12479 
12480 	hdd_pm_qos_remove_request(hdd_ctx);
12481 }
12482 
12483 /**
12484  * wlan_hdd_send_mscs_action_frame() - Send MSCS action frame
12485  * @context: HDD context
12486  * @netdev: netdev
12487  *
12488  * Return: None
12489  */
wlan_hdd_send_mscs_action_frame(hdd_cb_handle context,qdf_netdev_t netdev)12490 static inline void wlan_hdd_send_mscs_action_frame(hdd_cb_handle context,
12491 						   qdf_netdev_t netdev)
12492 {
12493 	struct hdd_adapter *adapter;
12494 	struct wlan_hdd_link_info *link_info;
12495 
12496 	adapter = WLAN_HDD_GET_PRIV_PTR(netdev);
12497 	if (!adapter) {
12498 		hdd_err("adapter is null");
12499 		return;
12500 	}
12501 
12502 	link_info = adapter->deflink;
12503 	hdd_send_mscs_action_frame(link_info);
12504 }
12505 
12506 #else
hdd_pld_remove_pm_qos(hdd_cb_handle context)12507 static inline void hdd_pld_remove_pm_qos(hdd_cb_handle context)
12508 {
12509 }
12510 
hdd_pld_request_pm_qos(hdd_cb_handle context)12511 static inline void hdd_pld_request_pm_qos(hdd_cb_handle context)
12512 {
12513 }
12514 
12515 static inline void
wlan_hdd_pm_qos_update_request(hdd_cb_handle context,cpumask_t * pm_qos_cpu_mask)12516 wlan_hdd_pm_qos_update_request(hdd_cb_handle context,
12517 			       cpumask_t *pm_qos_cpu_mask)
12518 {
12519 }
12520 
wlan_hdd_pm_qos_add_request(hdd_cb_handle context)12521 static inline void wlan_hdd_pm_qos_add_request(hdd_cb_handle context)
12522 {
12523 }
12524 
wlan_hdd_pm_qos_remove_request(hdd_cb_handle context)12525 static inline void wlan_hdd_pm_qos_remove_request(hdd_cb_handle context)
12526 {
12527 }
12528 
wlan_hdd_send_mscs_action_frame(hdd_cb_handle context,qdf_netdev_t netdev)12529 static inline void wlan_hdd_send_mscs_action_frame(hdd_cb_handle context,
12530 						   qdf_netdev_t netdev)
12531 {
12532 }
12533 #endif
12534 
12535 #if defined(WLAN_FEATURE_ROAM_OFFLOAD) && \
12536 defined(FEATURE_RX_LINKSPEED_ROAM_TRIGGER)
wlan_hdd_link_speed_update(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id,bool is_link_speed_good)12537 void wlan_hdd_link_speed_update(struct wlan_objmgr_psoc *psoc,
12538 				uint8_t vdev_id,
12539 				bool is_link_speed_good)
12540 {
12541 	ucfg_cm_roam_link_speed_update(psoc, vdev_id, is_link_speed_good);
12542 }
12543 #endif
12544 
12545 /**
12546  * hdd_dp_register_callbacks() - Register DP callbacks with HDD
12547  * @hdd_ctx: HDD context
12548  *
12549  * Return: None
12550  */
hdd_dp_register_callbacks(struct hdd_context * hdd_ctx)12551 static void hdd_dp_register_callbacks(struct hdd_context *hdd_ctx)
12552 {
12553 	struct wlan_dp_psoc_callbacks cb_obj = {0};
12554 
12555 	cb_obj.callback_ctx = (hdd_cb_handle)hdd_ctx;
12556 	cb_obj.wlan_dp_sta_get_dot11mode = wlan_hdd_sta_get_dot11mode;
12557 	cb_obj.wlan_dp_get_ap_client_count = wlan_hdd_get_ap_client_count;
12558 	cb_obj.wlan_dp_sta_ndi_connected = wlan_hdd_sta_ndi_connected;
12559 	cb_obj.dp_any_adapter_connected = hdd_any_adapter_connected;
12560 	cb_obj.dp_send_svc_nlink_msg = wlan_hdd_send_svc_nlink_msg;
12561 	cb_obj.dp_pld_remove_pm_qos = hdd_pld_remove_pm_qos;
12562 	cb_obj.dp_pld_request_pm_qos = hdd_pld_request_pm_qos;
12563 	cb_obj.dp_pktlog_enable_disable = wlan_hdd_pktlog_enable_disable;
12564 	cb_obj.dp_pm_qos_update_request = wlan_hdd_pm_qos_update_request;
12565 	cb_obj.dp_pm_qos_add_request = wlan_hdd_pm_qos_add_request;
12566 	cb_obj.dp_pm_qos_remove_request = wlan_hdd_pm_qos_remove_request;
12567 	cb_obj.dp_send_mscs_action_frame = wlan_hdd_send_mscs_action_frame;
12568 	cb_obj.dp_is_roaming_in_progress = wlan_hdd_is_roaming_in_progress;
12569 	cb_obj.wlan_dp_display_tx_multiq_stats =
12570 		wlan_hdd_display_tx_multiq_stats;
12571 	cb_obj.wlan_dp_display_netif_queue_history =
12572 		wlan_hdd_display_netif_queue_history;
12573 	cb_obj.dp_is_ap_active = hdd_is_ap_active;
12574 	cb_obj.dp_napi_apply_throughput_policy =
12575 		wlan_hdd_napi_apply_throughput_policy;
12576 	cb_obj.dp_is_link_adapter = hdd_is_link_adapter;
12577 	cb_obj.dp_nud_failure_work = hdd_nud_failure_work;
12578 	cb_obj.dp_get_pause_map = hdd_get_pause_map;
12579 
12580 	cb_obj.dp_get_netdev_by_vdev_mac =
12581 		hdd_get_netdev_by_vdev_mac;
12582 	cb_obj.dp_get_tx_resource = hdd_get_tx_resource;
12583 	cb_obj.dp_get_tx_flow_low_watermark = hdd_get_tx_flow_low_watermark;
12584 	cb_obj.dp_get_tsf_time = hdd_get_tsf_time_cb;
12585 	cb_obj.dp_tsf_timestamp_rx = hdd_tsf_timestamp_rx;
12586 	cb_obj.dp_gro_rx_legacy_get_napi = hdd_legacy_gro_get_napi;
12587 	cb_obj.link_monitoring_cb = wlan_hdd_link_speed_update;
12588 
12589 	os_if_dp_register_hdd_callbacks(hdd_ctx->psoc, &cb_obj);
12590 }
12591 
12592 /**
12593  * __hdd_adapter_param_update_work() - Gist of the work to process
12594  *				       netdev feature update.
12595  * @adapter: pointer to adapter structure
12596  *
12597  * This function assumes that the adapter pointer is always valid.
12598  * So the caller should always validate adapter pointer before calling
12599  * this function
12600  *
12601  * Returns: None
12602  */
12603 static inline void
__hdd_adapter_param_update_work(struct hdd_adapter * adapter)12604 __hdd_adapter_param_update_work(struct hdd_adapter *adapter)
12605 {
12606 	/**
12607 	 * This check is needed in case the work got scheduled after the
12608 	 * interface got disconnected.
12609 	 * Netdev features update is to be done only after the connection,
12610 	 * since the connection mode plays an important role in identifying
12611 	 * the features that are to be updated.
12612 	 * So in case of interface disconnect skip feature update.
12613 	 */
12614 	if (!hdd_cm_is_vdev_associated(adapter->deflink))
12615 		return;
12616 
12617 	hdd_netdev_update_features(adapter);
12618 }
12619 
12620 /**
12621  * hdd_adapter_param_update_work() - work to process the netdev features
12622  *				     update.
12623  * @arg: private data passed to work
12624  *
12625  * Returns: None
12626  */
hdd_adapter_param_update_work(void * arg)12627 static void hdd_adapter_param_update_work(void *arg)
12628 {
12629 	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
12630 	struct hdd_adapter *adapter = arg;
12631 	struct osif_vdev_sync *vdev_sync;
12632 	int errno;
12633 
12634 	if (!hdd_ctx)
12635 		return;
12636 
12637 	hdd_adapter_ops_record_event(hdd_ctx,
12638 				     WLAN_HDD_ADAPTER_OPS_WORK_SCHED,
12639 				     WLAN_INVALID_VDEV_ID);
12640 
12641 	if (hdd_validate_adapter(adapter))
12642 		return;
12643 
12644 	errno = osif_vdev_sync_op_start(adapter->dev, &vdev_sync);
12645 	if (errno)
12646 		return;
12647 
12648 	__hdd_adapter_param_update_work(adapter);
12649 
12650 	osif_vdev_sync_op_stop(vdev_sync);
12651 }
12652 
hdd_init_adapter_ops_wq(struct hdd_context * hdd_ctx)12653 QDF_STATUS hdd_init_adapter_ops_wq(struct hdd_context *hdd_ctx)
12654 {
12655 	hdd_enter();
12656 
12657 	hdd_ctx->adapter_ops_wq =
12658 		qdf_alloc_high_prior_ordered_workqueue("hdd_adapter_ops_wq");
12659 	if (!hdd_ctx->adapter_ops_wq)
12660 		return QDF_STATUS_E_NOMEM;
12661 
12662 	hdd_exit();
12663 
12664 	return QDF_STATUS_SUCCESS;
12665 }
12666 
hdd_deinit_adapter_ops_wq(struct hdd_context * hdd_ctx)12667 void hdd_deinit_adapter_ops_wq(struct hdd_context *hdd_ctx)
12668 {
12669 	hdd_enter();
12670 
12671 	qdf_flush_workqueue(0, hdd_ctx->adapter_ops_wq);
12672 	qdf_destroy_workqueue(0, hdd_ctx->adapter_ops_wq);
12673 
12674 	hdd_exit();
12675 }
12676 
hdd_adapter_feature_update_work_init(struct hdd_adapter * adapter)12677 QDF_STATUS hdd_adapter_feature_update_work_init(struct hdd_adapter *adapter)
12678 {
12679 	QDF_STATUS status;
12680 
12681 	hdd_enter();
12682 
12683 	status = qdf_create_work(0, &adapter->netdev_features_update_work,
12684 				 hdd_adapter_param_update_work, adapter);
12685 	adapter->netdev_features_update_work_status = HDD_WORK_INITIALIZED;
12686 
12687 	hdd_exit();
12688 
12689 	return status;
12690 }
12691 
hdd_adapter_feature_update_work_deinit(struct hdd_adapter * adapter)12692 void hdd_adapter_feature_update_work_deinit(struct hdd_adapter *adapter)
12693 {
12694 	hdd_enter();
12695 
12696 	if (adapter->netdev_features_update_work_status !=
12697 	    HDD_WORK_INITIALIZED) {
12698 		hdd_debug("work not yet init");
12699 		return;
12700 	}
12701 	qdf_cancel_work(&adapter->netdev_features_update_work);
12702 	qdf_flush_work(&adapter->netdev_features_update_work);
12703 	adapter->netdev_features_update_work_status = HDD_WORK_UNINITIALIZED;
12704 
12705 	hdd_exit();
12706 }
12707 
12708 #define HDD_DUMP_STAT_HELP(STAT_ID) \
12709 	hdd_nofl_debug("%u -- %s", STAT_ID, (# STAT_ID))
12710 /**
12711  * hdd_display_stats_help() - print statistics help
12712  *
12713  * Return: none
12714  */
hdd_display_stats_help(void)12715 static void hdd_display_stats_help(void)
12716 {
12717 	hdd_nofl_debug("iwpriv wlan0 dumpStats [option] - dump statistics");
12718 	hdd_nofl_debug("iwpriv wlan0 clearStats [option] - clear statistics");
12719 	hdd_nofl_debug("options:");
12720 	HDD_DUMP_STAT_HELP(CDP_TXRX_PATH_STATS);
12721 	HDD_DUMP_STAT_HELP(CDP_TXRX_HIST_STATS);
12722 	HDD_DUMP_STAT_HELP(CDP_TXRX_TSO_STATS);
12723 	HDD_DUMP_STAT_HELP(CDP_HDD_NETIF_OPER_HISTORY);
12724 	HDD_DUMP_STAT_HELP(CDP_DUMP_TX_FLOW_POOL_INFO);
12725 	HDD_DUMP_STAT_HELP(CDP_TXRX_DESC_STATS);
12726 	HDD_DUMP_STAT_HELP(CDP_HIF_STATS);
12727 	HDD_DUMP_STAT_HELP(CDP_NAPI_STATS);
12728 	HDD_DUMP_STAT_HELP(CDP_DP_NAPI_STATS);
12729 	HDD_DUMP_STAT_HELP(CDP_DP_RX_THREAD_STATS);
12730 }
12731 
hdd_wlan_dump_stats(struct hdd_adapter * adapter,int stats_id)12732 int hdd_wlan_dump_stats(struct hdd_adapter *adapter, int stats_id)
12733 {
12734 	int ret = 0;
12735 	QDF_STATUS status;
12736 	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
12737 
12738 	hdd_debug("stats_id %d", stats_id);
12739 
12740 	switch (stats_id) {
12741 	case CDP_TXRX_HIST_STATS:
12742 		ucfg_wlan_dp_display_tx_rx_histogram(hdd_ctx->psoc);
12743 		break;
12744 	case CDP_HDD_NETIF_OPER_HISTORY:
12745 		wlan_hdd_display_adapter_netif_queue_history(adapter);
12746 		break;
12747 	case CDP_HIF_STATS:
12748 		hdd_display_hif_stats();
12749 		break;
12750 	case CDP_NAPI_STATS:
12751 		if (hdd_display_napi_stats()) {
12752 			hdd_err("error displaying napi stats");
12753 			ret = -EFAULT;
12754 		}
12755 		break;
12756 	case CDP_DP_RX_THREAD_STATS:
12757 		ucfg_dp_txrx_ext_dump_stats(cds_get_context(QDF_MODULE_ID_SOC),
12758 					    CDP_DP_RX_THREAD_STATS);
12759 		break;
12760 	case CDP_DISCONNECT_STATS:
12761 		sme_display_disconnect_stats(hdd_ctx->mac_handle,
12762 					     adapter->deflink->vdev_id);
12763 		break;
12764 	default:
12765 		status = cdp_display_stats(cds_get_context(QDF_MODULE_ID_SOC),
12766 					   stats_id,
12767 					   QDF_STATS_VERBOSITY_LEVEL_HIGH);
12768 		if (status == QDF_STATUS_E_INVAL) {
12769 			hdd_display_stats_help();
12770 			ret = -EINVAL;
12771 		}
12772 		break;
12773 	}
12774 	return ret;
12775 }
12776 
hdd_wlan_clear_stats(struct hdd_adapter * adapter,int stats_id)12777 int hdd_wlan_clear_stats(struct hdd_adapter *adapter, int stats_id)
12778 {
12779 	QDF_STATUS status = QDF_STATUS_SUCCESS;
12780 
12781 	hdd_debug("stats_id %d", stats_id);
12782 
12783 	switch (stats_id) {
12784 	case CDP_HDD_STATS:
12785 		ucfg_dp_clear_net_dev_stats(adapter->dev);
12786 		memset(&adapter->deflink->hdd_stats, 0,
12787 		       sizeof(adapter->deflink->hdd_stats));
12788 		break;
12789 	case CDP_TXRX_HIST_STATS:
12790 		ucfg_wlan_dp_clear_tx_rx_histogram(adapter->hdd_ctx->psoc);
12791 		break;
12792 	case CDP_HDD_NETIF_OPER_HISTORY:
12793 		wlan_hdd_clear_netif_queue_history(adapter->hdd_ctx);
12794 		break;
12795 	case CDP_HIF_STATS:
12796 		hdd_clear_hif_stats();
12797 		break;
12798 	case CDP_NAPI_STATS:
12799 		hdd_clear_napi_stats();
12800 		break;
12801 	default:
12802 		status = cdp_clear_stats(cds_get_context(QDF_MODULE_ID_SOC),
12803 					 OL_TXRX_PDEV_ID,
12804 					 stats_id);
12805 		if (status != QDF_STATUS_SUCCESS)
12806 			hdd_debug("Failed to dump stats for stats_id: %d",
12807 				  stats_id);
12808 		break;
12809 	}
12810 
12811 	return qdf_status_to_os_return(status);
12812 }
12813 
12814 /* length of the netif queue log needed per adapter */
12815 #define ADAP_NETIFQ_LOG_LEN ((20 * WLAN_REASON_TYPE_MAX) + 50)
12816 
12817 /**
12818  * hdd_display_netif_queue_history_compact() - display compact netifq history
12819  * @hdd_ctx: hdd context
12820  *
12821  * Return: none
12822  */
12823 static void
hdd_display_netif_queue_history_compact(struct hdd_context * hdd_ctx)12824 hdd_display_netif_queue_history_compact(struct hdd_context *hdd_ctx)
12825 {
12826 	int adapter_num = 0;
12827 	int i;
12828 	int bytes_written;
12829 	u32 tbytes;
12830 	qdf_time_t total, pause, unpause, curr_time, delta;
12831 	char temp_str[20 * WLAN_REASON_TYPE_MAX];
12832 	char *comb_log_str;
12833 	uint32_t comb_log_str_size;
12834 	struct hdd_adapter *adapter = NULL, *next_adapter = NULL;
12835 	wlan_net_dev_ref_dbgid dbgid =
12836 			NET_DEV_HOLD_DISPLAY_NETIF_QUEUE_HISTORY_COMPACT;
12837 
12838 	comb_log_str_size = (ADAP_NETIFQ_LOG_LEN * WLAN_MAX_VDEVS) + 1;
12839 	comb_log_str = qdf_mem_malloc(comb_log_str_size);
12840 	if (!comb_log_str)
12841 		return;
12842 
12843 	bytes_written = 0;
12844 
12845 	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
12846 					   dbgid) {
12847 		curr_time = qdf_system_ticks();
12848 		total = curr_time - adapter->start_time;
12849 		delta = curr_time - adapter->last_time;
12850 
12851 		if (adapter->pause_map) {
12852 			pause = adapter->total_pause_time + delta;
12853 			unpause = adapter->total_unpause_time;
12854 		} else {
12855 			unpause = adapter->total_unpause_time + delta;
12856 			pause = adapter->total_pause_time;
12857 		}
12858 
12859 		tbytes = 0;
12860 		qdf_mem_zero(temp_str, sizeof(temp_str));
12861 		for (i = WLAN_CONTROL_PATH; i < WLAN_REASON_TYPE_MAX; i++) {
12862 			if (adapter->queue_oper_stats[i].pause_count == 0)
12863 				continue;
12864 			tbytes +=
12865 				snprintf(
12866 					&temp_str[tbytes],
12867 					(tbytes >= sizeof(temp_str) ?
12868 					0 : sizeof(temp_str) - tbytes),
12869 					"%d(%d,%d) ",
12870 					i,
12871 					adapter->queue_oper_stats[i].
12872 								pause_count,
12873 					adapter->queue_oper_stats[i].
12874 								unpause_count);
12875 		}
12876 		if (tbytes >= sizeof(temp_str))
12877 			hdd_warn("log truncated");
12878 
12879 		bytes_written += snprintf(&comb_log_str[bytes_written],
12880 			bytes_written >= comb_log_str_size ? 0 :
12881 					comb_log_str_size - bytes_written,
12882 			"[%d %d] (%d) %u/%ums %s|",
12883 			adapter->deflink->vdev_id, adapter->device_mode,
12884 			adapter->pause_map,
12885 			qdf_system_ticks_to_msecs(pause),
12886 			qdf_system_ticks_to_msecs(total),
12887 			temp_str);
12888 
12889 		adapter_num++;
12890 		/* dev_put has to be done here */
12891 		hdd_adapter_dev_put_debug(adapter, dbgid);
12892 	}
12893 
12894 	/* using QDF_TRACE to avoid printing function name */
12895 	QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_INFO_LOW,
12896 		  "STATS |%s", comb_log_str);
12897 
12898 	if (bytes_written >= comb_log_str_size)
12899 		hdd_warn("log string truncated");
12900 
12901 	qdf_mem_free(comb_log_str);
12902 }
12903 
12904 /* Max size of a single netdev tx queue state string. e.g. "1: 0x1" */
12905 #define HDD_NETDEV_TX_Q_STATE_STRLEN 15
12906 /**
12907  * wlan_hdd_display_adapter_netif_queue_stats() - display adapter based
12908  * netif queue stats
12909  * @adapter: hdd adapter
12910  *
12911  * Return: none
12912  */
12913 static void
wlan_hdd_display_adapter_netif_queue_stats(struct hdd_adapter * adapter)12914 wlan_hdd_display_adapter_netif_queue_stats(struct hdd_adapter *adapter)
12915 {
12916 	int i;
12917 	qdf_time_t total, pause, unpause, curr_time, delta;
12918 	struct hdd_netif_queue_history *q_hist_ptr;
12919 	char q_status_buf[NUM_TX_QUEUES * HDD_NETDEV_TX_Q_STATE_STRLEN] = {0};
12920 
12921 	hdd_nofl_debug("Netif queue operation statistics:");
12922 	hdd_nofl_debug("vdev_id %d device mode %d",
12923 		       adapter->deflink->vdev_id, adapter->device_mode);
12924 	hdd_nofl_debug("Current pause_map %x", adapter->pause_map);
12925 	curr_time = qdf_system_ticks();
12926 	total = curr_time - adapter->start_time;
12927 	delta = curr_time - adapter->last_time;
12928 	if (adapter->pause_map) {
12929 		pause = adapter->total_pause_time + delta;
12930 		unpause = adapter->total_unpause_time;
12931 	} else {
12932 		unpause = adapter->total_unpause_time + delta;
12933 		pause = adapter->total_pause_time;
12934 	}
12935 	hdd_nofl_debug("Total: %ums Pause: %ums Unpause: %ums",
12936 		       qdf_system_ticks_to_msecs(total),
12937 		       qdf_system_ticks_to_msecs(pause),
12938 		       qdf_system_ticks_to_msecs(unpause));
12939 	hdd_nofl_debug("reason_type: pause_cnt: unpause_cnt: pause_time");
12940 
12941 	for (i = WLAN_CONTROL_PATH; i < WLAN_REASON_TYPE_MAX; i++) {
12942 		qdf_time_t pause_delta = 0;
12943 
12944 		if (adapter->pause_map & (1 << i))
12945 			pause_delta = delta;
12946 
12947 		/* using hdd_log to avoid printing function name */
12948 		hdd_nofl_debug("%s: %d: %d: %ums",
12949 			       hdd_reason_type_to_string(i),
12950 			       adapter->queue_oper_stats[i].pause_count,
12951 			       adapter->queue_oper_stats[i].
12952 			       unpause_count,
12953 			       qdf_system_ticks_to_msecs(
12954 			       adapter->queue_oper_stats[i].
12955 			       total_pause_time + pause_delta));
12956 	}
12957 
12958 	hdd_nofl_debug("Netif queue operation history: Total entries: %d current index %d(-1) time %u",
12959 		       WLAN_HDD_MAX_HISTORY_ENTRY,
12960 		       adapter->history_index,
12961 		       qdf_system_ticks_to_msecs(qdf_system_ticks()));
12962 
12963 	hdd_nofl_debug("%2s%20s%50s%30s%10s  %s",
12964 		       "#", "time(ms)", "action_type", "reason_type",
12965 		       "pause_map", "netdev-queue-status");
12966 
12967 	for (i = 0; i < WLAN_HDD_MAX_HISTORY_ENTRY; i++) {
12968 		/* using hdd_log to avoid printing function name */
12969 		if (adapter->queue_oper_history[i].time == 0)
12970 			continue;
12971 		q_hist_ptr = &adapter->queue_oper_history[i];
12972 		wlan_hdd_dump_queue_history_state(q_hist_ptr,
12973 						  q_status_buf,
12974 						  sizeof(q_status_buf));
12975 		hdd_nofl_debug("%2d%20u%50s%30s%10x  %s",
12976 			       i, qdf_system_ticks_to_msecs(
12977 				adapter->queue_oper_history[i].time),
12978 				   hdd_action_type_to_string(
12979 				adapter->queue_oper_history[i].
12980 					netif_action),
12981 				   hdd_reason_type_to_string(
12982 				adapter->queue_oper_history[i].
12983 					netif_reason),
12984 				   adapter->queue_oper_history[i].pause_map,
12985 				   q_status_buf);
12986 	}
12987 }
12988 
12989 void
wlan_hdd_display_adapter_netif_queue_history(struct hdd_adapter * adapter)12990 wlan_hdd_display_adapter_netif_queue_history(struct hdd_adapter *adapter)
12991 {
12992 	wlan_hdd_display_adapter_netif_queue_stats(adapter);
12993 }
12994 
12995 /**
12996  * wlan_hdd_display_netif_queue_history() - display netif queue history
12997  * @context: hdd context
12998  * @verb_lvl: verbosity level
12999  *
13000  * Return: none
13001  */
13002 void
wlan_hdd_display_netif_queue_history(hdd_cb_handle context,enum qdf_stats_verbosity_level verb_lvl)13003 wlan_hdd_display_netif_queue_history(hdd_cb_handle context,
13004 				     enum qdf_stats_verbosity_level verb_lvl)
13005 {
13006 	struct hdd_adapter *adapter = NULL, *next_adapter = NULL;
13007 	struct hdd_context *hdd_ctx = hdd_cb_handle_to_context(context);
13008 	wlan_net_dev_ref_dbgid dbgid =
13009 				NET_DEV_HOLD_DISPLAY_NETIF_QUEUE_HISTORY;
13010 
13011 	if (!hdd_ctx) {
13012 		hdd_err("hdd_ctx is null");
13013 		return;
13014 	}
13015 
13016 	if (verb_lvl == QDF_STATS_VERBOSITY_LEVEL_LOW) {
13017 		hdd_display_netif_queue_history_compact(hdd_ctx);
13018 		return;
13019 	}
13020 
13021 	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
13022 					   dbgid) {
13023 		if (adapter->deflink->vdev_id == CDP_INVALID_VDEV_ID) {
13024 			hdd_adapter_dev_put_debug(adapter, dbgid);
13025 			continue;
13026 		}
13027 		wlan_hdd_display_adapter_netif_queue_stats(adapter);
13028 		/* dev_put has to be done here */
13029 		hdd_adapter_dev_put_debug(adapter, dbgid);
13030 	}
13031 }
13032 
13033 /**
13034  * wlan_hdd_clear_netif_queue_history() - clear netif queue operation history
13035  * @hdd_ctx: hdd context
13036  *
13037  * Return: none
13038  */
wlan_hdd_clear_netif_queue_history(struct hdd_context * hdd_ctx)13039 void wlan_hdd_clear_netif_queue_history(struct hdd_context *hdd_ctx)
13040 {
13041 	struct hdd_adapter *adapter = NULL, *next_adapter = NULL;
13042 	wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_CLEAR_NETIF_QUEUE_HISTORY;
13043 
13044 	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
13045 					   dbgid) {
13046 		qdf_mem_zero(adapter->queue_oper_stats,
13047 					sizeof(adapter->queue_oper_stats));
13048 		qdf_mem_zero(adapter->queue_oper_history,
13049 					sizeof(adapter->queue_oper_history));
13050 		adapter->history_index = 0;
13051 		adapter->start_time = adapter->last_time = qdf_system_ticks();
13052 		adapter->total_pause_time = 0;
13053 		adapter->total_unpause_time = 0;
13054 		hdd_adapter_dev_put_debug(adapter, dbgid);
13055 	}
13056 }
13057 
13058 #ifdef WLAN_FEATURE_OFFLOAD_PACKETS
13059 /**
13060  * hdd_init_offloaded_packets_ctx() - Initialize offload packets context
13061  * @hdd_ctx: hdd global context
13062  *
13063  * Return: none
13064  */
hdd_init_offloaded_packets_ctx(struct hdd_context * hdd_ctx)13065 static void hdd_init_offloaded_packets_ctx(struct hdd_context *hdd_ctx)
13066 {
13067 	uint8_t i;
13068 
13069 	mutex_init(&hdd_ctx->op_ctx.op_lock);
13070 	for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++) {
13071 		hdd_ctx->op_ctx.op_table[i].request_id = MAX_REQUEST_ID;
13072 		hdd_ctx->op_ctx.op_table[i].pattern_id = i;
13073 	}
13074 }
13075 #else
hdd_init_offloaded_packets_ctx(struct hdd_context * hdd_ctx)13076 static void hdd_init_offloaded_packets_ctx(struct hdd_context *hdd_ctx)
13077 {
13078 }
13079 #endif
13080 
13081 #ifdef WLAN_FEATURE_WOW_PULSE
13082 /**
13083  * wlan_hdd_set_wow_pulse() - call SME to send wmi cmd of wow pulse
13084  * @hdd_ctx: struct hdd_context structure pointer
13085  * @enable: enable or disable this behaviour
13086  *
13087  * Return: int
13088  */
wlan_hdd_set_wow_pulse(struct hdd_context * hdd_ctx,bool enable)13089 static int wlan_hdd_set_wow_pulse(struct hdd_context *hdd_ctx, bool enable)
13090 {
13091 	struct wow_pulse_mode wow_pulse_set_info;
13092 	QDF_STATUS status;
13093 
13094 	hdd_debug("wow pulse enable flag is %d", enable);
13095 
13096 	if (!ucfg_pmo_is_wow_pulse_enabled(hdd_ctx->psoc))
13097 		return 0;
13098 
13099 	/* prepare the request to send to SME */
13100 	if (enable == true) {
13101 		wow_pulse_set_info.wow_pulse_enable = true;
13102 		wow_pulse_set_info.wow_pulse_pin =
13103 			ucfg_pmo_get_wow_pulse_pin(hdd_ctx->psoc);
13104 
13105 		wow_pulse_set_info.wow_pulse_interval_high =
13106 		    ucfg_pmo_get_wow_pulse_interval_high(hdd_ctx->psoc);
13107 
13108 		wow_pulse_set_info.wow_pulse_interval_low =
13109 		    ucfg_pmo_get_wow_pulse_interval_low(hdd_ctx->psoc);
13110 
13111 		wow_pulse_set_info.wow_pulse_repeat_count =
13112 		    ucfg_pmo_get_wow_pulse_repeat_count(hdd_ctx->psoc);
13113 
13114 		wow_pulse_set_info.wow_pulse_init_state =
13115 		    ucfg_pmo_get_wow_pulse_init_state(hdd_ctx->psoc);
13116 	} else {
13117 		wow_pulse_set_info.wow_pulse_enable = false;
13118 		wow_pulse_set_info.wow_pulse_pin = 0;
13119 		wow_pulse_set_info.wow_pulse_interval_low = 0;
13120 		wow_pulse_set_info.wow_pulse_interval_high = 0;
13121 		wow_pulse_set_info.wow_pulse_repeat_count = 0;
13122 		wow_pulse_set_info.wow_pulse_init_state = 0;
13123 	}
13124 	hdd_debug("enable %d pin %d low %d high %d count %d init %d",
13125 		  wow_pulse_set_info.wow_pulse_enable,
13126 		  wow_pulse_set_info.wow_pulse_pin,
13127 		  wow_pulse_set_info.wow_pulse_interval_low,
13128 		  wow_pulse_set_info.wow_pulse_interval_high,
13129 		  wow_pulse_set_info.wow_pulse_repeat_count,
13130 		  wow_pulse_set_info.wow_pulse_init_state);
13131 
13132 	status = sme_set_wow_pulse(&wow_pulse_set_info);
13133 	if (QDF_STATUS_E_FAILURE == status) {
13134 		hdd_debug("sme_set_wow_pulse failure!");
13135 		return -EIO;
13136 	}
13137 	hdd_debug("sme_set_wow_pulse success!");
13138 	return 0;
13139 }
13140 #else
wlan_hdd_set_wow_pulse(struct hdd_context * hdd_ctx,bool enable)13141 static inline int wlan_hdd_set_wow_pulse(struct hdd_context *hdd_ctx, bool enable)
13142 {
13143 	return 0;
13144 }
13145 #endif
13146 
13147 #ifdef WLAN_FEATURE_FASTPATH
13148 
13149 /**
13150  * hdd_enable_fastpath() - Enable fastpath if enabled in config INI
13151  * @hdd_ctx: hdd context
13152  * @context: lower layer context
13153  *
13154  * Return: none
13155  */
hdd_enable_fastpath(struct hdd_context * hdd_ctx,void * context)13156 void hdd_enable_fastpath(struct hdd_context *hdd_ctx,
13157 			 void *context)
13158 {
13159 	if (cfg_get(hdd_ctx->psoc, CFG_DP_ENABLE_FASTPATH))
13160 		hif_enable_fastpath(context);
13161 }
13162 #endif
13163 
13164 #if defined(FEATURE_WLAN_CH_AVOID)
13165 /**
13166  * hdd_set_thermal_level_cb() - set thermal level callback function
13167  * @hdd_handle:	opaque handle for the hdd context
13168  * @level:	thermal level
13169  *
13170  * Change IPA data path to SW path when the thermal throttle level greater
13171  * than 0, and restore the original data path when throttle level is 0
13172  *
13173  * Return: none
13174  */
hdd_set_thermal_level_cb(hdd_handle_t hdd_handle,u_int8_t level)13175 static void hdd_set_thermal_level_cb(hdd_handle_t hdd_handle, u_int8_t level)
13176 {
13177 	struct hdd_context *hdd_ctx = hdd_handle_to_context(hdd_handle);
13178 
13179 	/* Change IPA to SW path when throttle level greater than 0 */
13180 	if (level > THROTTLE_LEVEL_0)
13181 		ucfg_ipa_send_mcc_scc_msg(hdd_ctx->pdev, true);
13182 	else
13183 		/* restore original concurrency mode */
13184 		ucfg_ipa_send_mcc_scc_msg(hdd_ctx->pdev, hdd_ctx->mcc_mode);
13185 }
13186 #else
13187 /**
13188  * hdd_set_thermal_level_cb() - set thermal level callback function
13189  * @hdd_handle:	opaque handle for the hdd context
13190  * @level:	thermal level
13191  *
13192  * Change IPA data path to SW path when the thermal throttle level greater
13193  * than 0, and restore the original data path when throttle level is 0
13194  *
13195  * Return: none
13196  */
hdd_set_thermal_level_cb(hdd_handle_t hdd_handle,u_int8_t level)13197 static void hdd_set_thermal_level_cb(hdd_handle_t hdd_handle, u_int8_t level)
13198 {
13199 }
13200 #endif
13201 
hdd_switch_sap_channel(struct wlan_hdd_link_info * link_info,uint8_t channel,bool forced)13202 QDF_STATUS hdd_switch_sap_channel(struct wlan_hdd_link_info *link_info,
13203 				  uint8_t channel, bool forced)
13204 {
13205 	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(link_info->adapter);
13206 	mac_handle_t mac_handle;
13207 	struct sap_config *sap_cfg;
13208 	qdf_freq_t freq;
13209 
13210 	mac_handle = hdd_adapter_get_mac_handle(link_info->adapter);
13211 	if (!mac_handle) {
13212 		hdd_err("invalid MAC handle");
13213 		return QDF_STATUS_E_INVAL;
13214 	}
13215 
13216 	freq = wlan_reg_legacy_chan_to_freq(hdd_ctx->pdev, channel);
13217 	sap_cfg = &(WLAN_HDD_GET_AP_CTX_PTR(link_info)->sap_config);
13218 	hdd_debug("chan:%d width:%d", channel, sap_cfg->ch_width_orig);
13219 
13220 	return policy_mgr_change_sap_channel_with_csa(hdd_ctx->psoc,
13221 						      link_info->vdev_id, freq,
13222 						      sap_cfg->ch_width_orig,
13223 						      forced);
13224 }
13225 
hdd_switch_sap_chan_freq(struct hdd_adapter * adapter,qdf_freq_t chan_freq,enum phy_ch_width ch_width,bool forced)13226 QDF_STATUS hdd_switch_sap_chan_freq(struct hdd_adapter *adapter,
13227 				    qdf_freq_t chan_freq,
13228 				    enum phy_ch_width ch_width,
13229 				    bool forced)
13230 {
13231 	struct hdd_ap_ctx *hdd_ap_ctx;
13232 	struct hdd_context *hdd_ctx;
13233 
13234 	if (hdd_validate_adapter(adapter))
13235 		return QDF_STATUS_E_INVAL;
13236 
13237 	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
13238 
13239 	if(wlan_hdd_validate_context(hdd_ctx))
13240 		return QDF_STATUS_E_INVAL;
13241 
13242 	hdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(adapter->deflink);
13243 
13244 	hdd_debug("chan freq:%d width:%d org bw %d",
13245 		  chan_freq, ch_width, hdd_ap_ctx->sap_config.ch_width_orig);
13246 
13247 	return policy_mgr_change_sap_channel_with_csa(hdd_ctx->psoc,
13248 						      adapter->deflink->vdev_id,
13249 						      chan_freq,
13250 						      ch_width,
13251 						      forced);
13252 }
13253 
hdd_update_acs_timer_reason(struct hdd_adapter * adapter,uint8_t reason)13254 int hdd_update_acs_timer_reason(struct hdd_adapter *adapter, uint8_t reason)
13255 {
13256 	struct hdd_external_acs_timer_context *timer_context;
13257 	int status;
13258 	QDF_STATUS qdf_status;
13259 	qdf_mc_timer_t *vendor_acs_timer;
13260 
13261 	set_bit(VENDOR_ACS_RESPONSE_PENDING, &adapter->deflink->link_flags);
13262 
13263 	vendor_acs_timer = &adapter->deflink->session.ap.vendor_acs_timer;
13264 	if (QDF_TIMER_STATE_RUNNING ==
13265 	    qdf_mc_timer_get_current_state(vendor_acs_timer)) {
13266 		qdf_mc_timer_stop(vendor_acs_timer);
13267 	}
13268 	timer_context =
13269 		(struct hdd_external_acs_timer_context *)vendor_acs_timer->user_data;
13270 	timer_context->reason = reason;
13271 	qdf_status =
13272 		qdf_mc_timer_start(vendor_acs_timer, WLAN_VENDOR_ACS_WAIT_TIME);
13273 	if (qdf_status != QDF_STATUS_SUCCESS) {
13274 		hdd_err("failed to start external acs timer");
13275 		return -ENOSPC;
13276 	}
13277 	/* Update config to application */
13278 	status = hdd_cfg80211_update_acs_config(adapter, reason);
13279 	hdd_info("Updated ACS config to nl with reason %d", reason);
13280 
13281 	return status;
13282 }
13283 
13284 #ifdef FEATURE_WLAN_CH_AVOID_EXT
wlan_hdd_get_restriction_mask(struct hdd_context * hdd_ctx)13285 uint32_t wlan_hdd_get_restriction_mask(struct hdd_context *hdd_ctx)
13286 {
13287 	return hdd_ctx->restriction_mask;
13288 }
13289 
wlan_hdd_set_restriction_mask(struct hdd_context * hdd_ctx)13290 void wlan_hdd_set_restriction_mask(struct hdd_context *hdd_ctx)
13291 {
13292 	hdd_ctx->restriction_mask =
13293 		hdd_ctx->coex_avoid_freq_list.restriction_mask;
13294 }
13295 #else
wlan_hdd_get_restriction_mask(struct hdd_context * hdd_ctx)13296 uint32_t wlan_hdd_get_restriction_mask(struct hdd_context *hdd_ctx)
13297 {
13298 	return -EINVAL;
13299 }
13300 
wlan_hdd_set_restriction_mask(struct hdd_context * hdd_ctx)13301 void wlan_hdd_set_restriction_mask(struct hdd_context *hdd_ctx)
13302 {
13303 }
13304 #endif
13305 
13306 #if defined(FEATURE_WLAN_CH_AVOID)
13307 /**
13308  * hdd_store_sap_restart_channel() - store sap restart channel
13309  * @restart_chan: restart channel
13310  * @restart_chan_store: pointer to restart channel store
13311  *
13312  * The function will store new sap restart channel.
13313  *
13314  * Return - none
13315  */
13316 static void
hdd_store_sap_restart_channel(qdf_freq_t restart_chan,qdf_freq_t * restart_chan_store)13317 hdd_store_sap_restart_channel(qdf_freq_t restart_chan, qdf_freq_t *restart_chan_store)
13318 {
13319 	uint8_t i;
13320 
13321 	for (i = 0; i < SAP_MAX_NUM_SESSION; i++) {
13322 		if (*(restart_chan_store + i) == restart_chan)
13323 			return;
13324 
13325 		if (*(restart_chan_store + i))
13326 			continue;
13327 
13328 		*(restart_chan_store + i) = restart_chan;
13329 		return;
13330 	}
13331 }
13332 
13333 /**
13334  * hdd_check_chn_bw_boundary_unsafe() - check channel range unsafe
13335  * @hdd_ctxt: hdd context pointer
13336  * @adapter:  hdd adapter pointer
13337  *
13338  * hdd_check_chn_bw_boundary_unsafe check SAP channel range with certain
13339  * bandwidth whether cover all unsafe channel list.
13340  *
13341  * Return - bool
13342  */
13343 static bool
hdd_check_chn_bw_boundary_unsafe(struct hdd_context * hdd_ctxt,struct hdd_adapter * adapter)13344 hdd_check_chn_bw_boundary_unsafe(struct hdd_context *hdd_ctxt,
13345 				 struct hdd_adapter *adapter)
13346 {
13347 	uint32_t freq;
13348 	uint32_t start_freq = 0;
13349 	uint32_t end_freq = 0;
13350 	uint32_t i;
13351 	uint8_t ch_width;
13352 	const struct bonded_channel_freq *bonded_chan_ptr_ptr = NULL;
13353 
13354 	freq = adapter->deflink->session.ap.operating_chan_freq;
13355 	ch_width = adapter->deflink->session.ap.sap_config.acs_cfg.ch_width;
13356 
13357 	if (ch_width > CH_WIDTH_20MHZ)
13358 		bonded_chan_ptr_ptr =
13359 			wlan_reg_get_bonded_chan_entry(freq, ch_width, 0);
13360 
13361 	if (bonded_chan_ptr_ptr) {
13362 		start_freq = bonded_chan_ptr_ptr->start_freq;
13363 		end_freq   = bonded_chan_ptr_ptr->end_freq;
13364 	}
13365 
13366 	for (i = 0; i < hdd_ctxt->unsafe_channel_count; i++) {
13367 		if ((freq == hdd_ctxt->unsafe_channel_list[i]) ||
13368 		    (start_freq <= hdd_ctxt->unsafe_channel_list[i] &&
13369 		     hdd_ctxt->unsafe_channel_list[i] <= end_freq)) {
13370 			hdd_debug("op chn freq:%u is unsafe for chn list:%u",
13371 				  freq, hdd_ctxt->unsafe_channel_list[i]);
13372 			return true;
13373 		}
13374 	}
13375 
13376 	return false;
13377 }
13378 
13379 /**
13380  * hdd_unsafe_channel_restart_sap() - restart sap if sap is on unsafe channel
13381  * @hdd_ctx: hdd context pointer
13382  *
13383  * hdd_unsafe_channel_restart_sap check all unsafe channel list
13384  * and if ACS is enabled, driver will ask userspace to restart the
13385  * sap. User space on LTE coex indication restart driver.
13386  *
13387  * Return - none
13388  */
hdd_unsafe_channel_restart_sap(struct hdd_context * hdd_ctx)13389 QDF_STATUS hdd_unsafe_channel_restart_sap(struct hdd_context *hdd_ctx)
13390 {
13391 	struct hdd_adapter *adapter, *next_adapter = NULL;
13392 	struct hdd_ap_ctx *ap_ctx;
13393 	uint32_t i;
13394 	bool found = false;
13395 	qdf_freq_t restart_chan_store[SAP_MAX_NUM_SESSION] = {0};
13396 	uint8_t scc_on_lte_coex = 0;
13397 	uint32_t restart_freq, ap_chan_freq;
13398 	bool value;
13399 	QDF_STATUS status;
13400 	bool is_acs_support_for_dfs_ltecoex = cfg_default(CFG_USER_ACS_DFS_LTE);
13401 	bool is_vendor_acs_support =
13402 		cfg_default(CFG_USER_AUTO_CHANNEL_SELECTION);
13403 	wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_UNSAFE_CHANNEL_RESTART_SAP;
13404 	enum phy_ch_width ch_width;
13405 	struct wlan_hdd_link_info *link_info;
13406 
13407 	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
13408 					   dbgid) {
13409 		if (adapter->device_mode != QDF_SAP_MODE) {
13410 			hdd_debug_rl("skip device mode:%d",
13411 				     adapter->device_mode);
13412 			hdd_adapter_dev_put_debug(adapter, dbgid);
13413 			continue;
13414 		}
13415 
13416 		hdd_adapter_for_each_active_link_info(adapter, link_info) {
13417 			ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(link_info);
13418 			if (!ap_ctx->sap_config.acs_cfg.acs_mode) {
13419 				hdd_debug_rl("skip acs:%d",
13420 					     ap_ctx->sap_config.acs_cfg.acs_mode);
13421 				continue;
13422 			}
13423 
13424 			ap_chan_freq = ap_ctx->operating_chan_freq;
13425 			ch_width = ap_ctx->sap_config.ch_width_orig;
13426 			found = false;
13427 			status =
13428 			ucfg_policy_mgr_get_sta_sap_scc_lte_coex_chnl(hdd_ctx->psoc,
13429 								      &scc_on_lte_coex);
13430 			if (!QDF_IS_STATUS_SUCCESS(status))
13431 				hdd_err("can't get scc on lte coex chnl, use def");
13432 			/*
13433 			 * If STA+SAP is doing SCC &
13434 			 * g_sta_sap_scc_on_lte_coex_chan is set,
13435 			 * no need to move SAP.
13436 			 */
13437 			if ((policy_mgr_is_sta_sap_scc(hdd_ctx->psoc,
13438 						       ap_chan_freq) &&
13439 			     scc_on_lte_coex) ||
13440 			    policy_mgr_nan_sap_scc_on_unsafe_ch_chk(hdd_ctx->psoc,
13441 								    ap_chan_freq))
13442 				hdd_debug("SAP allowed in unsafe SCC channel");
13443 			else
13444 				found = hdd_check_chn_bw_boundary_unsafe(hdd_ctx,
13445 									 adapter);
13446 			if (!found) {
13447 				hdd_store_sap_restart_channel(ap_chan_freq,
13448 							      restart_chan_store);
13449 				hdd_debug("ch freq:%d is safe. no need to change channel",
13450 					  ap_chan_freq);
13451 				continue;
13452 			}
13453 
13454 			status = ucfg_mlme_get_acs_support_for_dfs_ltecoex(
13455 						hdd_ctx->psoc,
13456 						&is_acs_support_for_dfs_ltecoex);
13457 			if (!QDF_IS_STATUS_SUCCESS(status))
13458 				hdd_err("get_acs_support_for_dfs_ltecoex failed,set def");
13459 
13460 			status = ucfg_mlme_get_vendor_acs_support(
13461 						hdd_ctx->psoc,
13462 						&is_vendor_acs_support);
13463 			if (!QDF_IS_STATUS_SUCCESS(status))
13464 				hdd_err("get_vendor_acs_support failed, set default");
13465 
13466 			if (is_vendor_acs_support &&
13467 			    is_acs_support_for_dfs_ltecoex) {
13468 				hdd_update_acs_timer_reason(adapter,
13469 				    QCA_WLAN_VENDOR_ACS_SELECT_REASON_LTE_COEX);
13470 				continue;
13471 			}
13472 
13473 			restart_freq = 0;
13474 			for (i = 0; i < SAP_MAX_NUM_SESSION; i++) {
13475 				if (!restart_chan_store[i])
13476 					continue;
13477 
13478 				if (policy_mgr_is_force_scc(hdd_ctx->psoc) &&
13479 				    WLAN_REG_IS_SAME_BAND_FREQS(
13480 						restart_chan_store[i],
13481 						ap_chan_freq)) {
13482 					restart_freq = restart_chan_store[i];
13483 					break;
13484 				}
13485 			}
13486 			if (!restart_freq) {
13487 				restart_freq =
13488 					wlansap_get_safe_channel_from_pcl_and_acs_range(
13489 					    WLAN_HDD_GET_SAP_CTX_PTR(link_info),
13490 					    &ch_width);
13491 			}
13492 			if (!restart_freq) {
13493 				wlan_hdd_set_sap_csa_reason(hdd_ctx->psoc,
13494 							    link_info->vdev_id,
13495 							    CSA_REASON_UNSAFE_CHANNEL);
13496 				hdd_err("Unable to find safe chan, Stop the SAP if restriction mask is set else set txpower");
13497 				hdd_stop_sap_set_tx_power(hdd_ctx->psoc, adapter);
13498 				continue;
13499 			}
13500 			/*
13501 			 * SAP restart due to unsafe channel. While
13502 			 * restarting the SAP, make sure to clear
13503 			 * acs_channel, channel to reset to
13504 			 * 0. Otherwise these settings will override
13505 			 * the ACS while restart.
13506 			 */
13507 			hdd_ctx->acs_policy.acs_chan_freq =
13508 						AUTO_CHANNEL_SELECT;
13509 			ucfg_mlme_get_sap_internal_restart(hdd_ctx->psoc,
13510 							   &value);
13511 			if (value) {
13512 				wlan_hdd_set_sap_csa_reason(hdd_ctx->psoc,
13513 						    link_info->vdev_id,
13514 						    CSA_REASON_UNSAFE_CHANNEL);
13515 				status = hdd_switch_sap_chan_freq(adapter,
13516 								  restart_freq,
13517 								  ch_width,
13518 								  true);
13519 				if (QDF_IS_STATUS_SUCCESS(status)) {
13520 					hdd_adapter_dev_put_debug(adapter,
13521 								  dbgid);
13522 					if (next_adapter)
13523 						hdd_adapter_dev_put_debug(
13524 								next_adapter,
13525 								dbgid);
13526 					return QDF_STATUS_E_PENDING;
13527 				} else {
13528 					hdd_debug("CSA failed, check next SAP");
13529 				}
13530 			} else {
13531 				hdd_debug("sending coex indication");
13532 				wlan_hdd_send_svc_nlink_msg(
13533 						hdd_ctx->radio_index,
13534 						WLAN_SVC_LTE_COEX_IND, NULL, 0);
13535 				hdd_adapter_dev_put_debug(adapter, dbgid);
13536 				if (next_adapter)
13537 					hdd_adapter_dev_put_debug(next_adapter,
13538 								  dbgid);
13539 				return QDF_STATUS_SUCCESS;
13540 			}
13541 		}
13542 		/* dev_put has to be done here */
13543 		hdd_adapter_dev_put_debug(adapter, dbgid);
13544 	}
13545 
13546 	return QDF_STATUS_SUCCESS;
13547 }
13548 
13549 /**
13550  * hdd_init_channel_avoidance() - Initialize channel avoidance
13551  * @hdd_ctx:	HDD global context
13552  *
13553  * Initialize the channel avoidance logic by retrieving the unsafe
13554  * channel list from the platform driver and plumbing the data
13555  * down to the lower layers.  Then subscribe to subsequent channel
13556  * avoidance events.
13557  *
13558  * Return: None
13559  */
hdd_init_channel_avoidance(struct hdd_context * hdd_ctx)13560 static void hdd_init_channel_avoidance(struct hdd_context *hdd_ctx)
13561 {
13562 	uint16_t unsafe_channel_count;
13563 	int index;
13564 	qdf_freq_t *unsafe_freq_list;
13565 
13566 	pld_get_wlan_unsafe_channel(hdd_ctx->parent_dev,
13567 				    hdd_ctx->unsafe_channel_list,
13568 				     &(hdd_ctx->unsafe_channel_count),
13569 				     sizeof(uint16_t) * NUM_CHANNELS);
13570 
13571 	hdd_debug("num of unsafe channels is %d",
13572 	       hdd_ctx->unsafe_channel_count);
13573 
13574 	unsafe_channel_count = QDF_MIN((uint16_t)hdd_ctx->unsafe_channel_count,
13575 				       (uint16_t)NUM_CHANNELS);
13576 
13577 	if (!unsafe_channel_count)
13578 		return;
13579 
13580 	unsafe_freq_list = qdf_mem_malloc(
13581 			unsafe_channel_count * sizeof(*unsafe_freq_list));
13582 
13583 	if (!unsafe_freq_list)
13584 		return;
13585 
13586 	for (index = 0; index < unsafe_channel_count; index++) {
13587 		hdd_debug("channel frequency %d is not safe",
13588 			  hdd_ctx->unsafe_channel_list[index]);
13589 		unsafe_freq_list[index] =
13590 			(qdf_freq_t)hdd_ctx->unsafe_channel_list[index];
13591 	}
13592 
13593 	ucfg_policy_mgr_init_chan_avoidance(
13594 		hdd_ctx->psoc,
13595 		unsafe_freq_list,
13596 		unsafe_channel_count);
13597 
13598 	qdf_mem_free(unsafe_freq_list);
13599 }
13600 
hdd_lte_coex_restart_sap(struct hdd_adapter * adapter,struct hdd_context * hdd_ctx)13601 static void hdd_lte_coex_restart_sap(struct hdd_adapter *adapter,
13602 				     struct hdd_context *hdd_ctx)
13603 {
13604 	uint8_t restart_chan;
13605 	uint32_t restart_freq;
13606 
13607 	restart_freq = wlansap_get_safe_channel_from_pcl_and_acs_range(
13608 				WLAN_HDD_GET_SAP_CTX_PTR(adapter->deflink),
13609 				NULL);
13610 
13611 	restart_chan = wlan_reg_freq_to_chan(hdd_ctx->pdev,
13612 					     restart_freq);
13613 
13614 	if (!restart_chan) {
13615 		hdd_alert("fail to restart SAP");
13616 		return;
13617 	}
13618 
13619 	/* SAP restart due to unsafe channel. While restarting
13620 	 * the SAP, make sure to clear acs_channel, channel to
13621 	 * reset to 0. Otherwise these settings will override
13622 	 * the ACS while restart.
13623 	 */
13624 	hdd_ctx->acs_policy.acs_chan_freq = AUTO_CHANNEL_SELECT;
13625 
13626 	hdd_debug("sending coex indication");
13627 
13628 	wlan_hdd_send_svc_nlink_msg(hdd_ctx->radio_index,
13629 				    WLAN_SVC_LTE_COEX_IND, NULL, 0);
13630 	wlan_hdd_set_sap_csa_reason(hdd_ctx->psoc, adapter->deflink->vdev_id,
13631 				    CSA_REASON_LTE_COEX);
13632 	hdd_switch_sap_channel(adapter->deflink, restart_chan, true);
13633 }
13634 
hdd_clone_local_unsafe_chan(struct hdd_context * hdd_ctx,uint16_t ** local_unsafe_list,uint16_t * local_unsafe_list_count)13635 int hdd_clone_local_unsafe_chan(struct hdd_context *hdd_ctx,
13636 	uint16_t **local_unsafe_list, uint16_t *local_unsafe_list_count)
13637 {
13638 	uint32_t size;
13639 	uint16_t *unsafe_list;
13640 	uint16_t chan_count;
13641 
13642 	if (!hdd_ctx || !local_unsafe_list_count || !local_unsafe_list_count)
13643 		return -EINVAL;
13644 
13645 	chan_count = QDF_MIN(hdd_ctx->unsafe_channel_count,
13646 			     NUM_CHANNELS);
13647 	if (chan_count) {
13648 		size = chan_count * sizeof(hdd_ctx->unsafe_channel_list[0]);
13649 		unsafe_list = qdf_mem_malloc(size);
13650 		if (!unsafe_list)
13651 			return -ENOMEM;
13652 		qdf_mem_copy(unsafe_list, hdd_ctx->unsafe_channel_list, size);
13653 	} else {
13654 		unsafe_list = NULL;
13655 	}
13656 
13657 	*local_unsafe_list = unsafe_list;
13658 	*local_unsafe_list_count = chan_count;
13659 
13660 	return 0;
13661 }
13662 
hdd_local_unsafe_channel_updated(struct hdd_context * hdd_ctx,uint16_t * local_unsafe_list,uint16_t local_unsafe_list_count,uint32_t restriction_mask)13663 bool hdd_local_unsafe_channel_updated(
13664 	struct hdd_context *hdd_ctx, uint16_t *local_unsafe_list,
13665 	uint16_t local_unsafe_list_count, uint32_t restriction_mask)
13666 {
13667 	int i, j;
13668 
13669 	if (local_unsafe_list_count != hdd_ctx->unsafe_channel_count)
13670 		return true;
13671 	if (local_unsafe_list_count == 0)
13672 		return false;
13673 	for (i = 0; i < local_unsafe_list_count; i++) {
13674 		for (j = 0; j < local_unsafe_list_count; j++)
13675 			if (local_unsafe_list[i] ==
13676 			    hdd_ctx->unsafe_channel_list[j])
13677 				break;
13678 		if (j >= local_unsafe_list_count)
13679 			break;
13680 	}
13681 
13682 	if (ucfg_mlme_get_coex_unsafe_chan_nb_user_prefer(hdd_ctx->psoc)) {
13683 		/* Return false if current channel list is same as previous
13684 		 * and restriction mask is not altered
13685 		 */
13686 		if (i >= local_unsafe_list_count &&
13687 		    (restriction_mask ==
13688 		     wlan_hdd_get_restriction_mask(hdd_ctx))) {
13689 			hdd_info("unsafe chan list same");
13690 			return false;
13691 		}
13692 	} else if (i >= local_unsafe_list_count) {
13693 		hdd_info("unsafe chan list same");
13694 		return false;
13695 	}
13696 
13697 	return true;
13698 }
13699 #else
hdd_init_channel_avoidance(struct hdd_context * hdd_ctx)13700 static void hdd_init_channel_avoidance(struct hdd_context *hdd_ctx)
13701 {
13702 }
13703 
hdd_lte_coex_restart_sap(struct hdd_adapter * adapter,struct hdd_context * hdd_ctx)13704 static inline void hdd_lte_coex_restart_sap(struct hdd_adapter *adapter,
13705 					    struct hdd_context *hdd_ctx)
13706 {
13707 	hdd_debug("Channel avoidance is not enabled; Abort SAP restart");
13708 }
13709 #endif /* defined(FEATURE_WLAN_CH_AVOID) */
13710 
13711 struct wlan_hdd_link_info *
wlan_hdd_get_link_info_from_objmgr(struct wlan_objmgr_vdev * vdev)13712 wlan_hdd_get_link_info_from_objmgr(struct wlan_objmgr_vdev *vdev)
13713 {
13714 	if (!vdev) {
13715 		hdd_err("null vdev object");
13716 		return NULL;
13717 	}
13718 
13719 	if (vdev->vdev_nif.osdev)
13720 		return vdev->vdev_nif.osdev->legacy_osif_priv;
13721 
13722 	return NULL;
13723 }
13724 
13725 /**
13726  * hdd_indicate_mgmt_frame() - Wrapper to indicate management frame to
13727  * user space
13728  * @frame_ind: Management frame data to be informed.
13729  *
13730  * This function is used to indicate management frame to
13731  * user space
13732  *
13733  * Return: None
13734  *
13735  */
hdd_indicate_mgmt_frame(tSirSmeMgmtFrameInd * frame_ind)13736 void hdd_indicate_mgmt_frame(tSirSmeMgmtFrameInd *frame_ind)
13737 {
13738 	struct hdd_context *hdd_ctx = NULL;
13739 	struct hdd_adapter *adapter = NULL, *next_adapter = NULL;
13740 	int i, num_adapters;
13741 	uint8_t vdev_id[WLAN_MAX_VDEVS + WLAN_MAX_ML_VDEVS];
13742 	struct ieee80211_mgmt *mgmt =
13743 		(struct ieee80211_mgmt *)frame_ind->frameBuf;
13744 	struct wlan_objmgr_vdev *vdev;
13745 	wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_INDICATE_MGMT_FRAME;
13746 	struct wlan_hdd_link_info *link_info;
13747 
13748 	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
13749 	if (wlan_hdd_validate_context(hdd_ctx))
13750 		return;
13751 
13752 	if (frame_ind->frame_len < ieee80211_hdrlen(mgmt->frame_control)) {
13753 		hdd_err(" Invalid frame length");
13754 		return;
13755 	}
13756 
13757 	if (SME_SESSION_ID_ANY == frame_ind->sessionId) {
13758 		for (i = 0; i < WLAN_MAX_VDEVS; i++) {
13759 			link_info = hdd_get_link_info_by_vdev(hdd_ctx, i);
13760 			if (link_info) {
13761 				adapter = link_info->adapter;
13762 				break;
13763 			}
13764 		}
13765 	} else if (SME_SESSION_ID_BROADCAST == frame_ind->sessionId) {
13766 		num_adapters = 0;
13767 		hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter,
13768 						   next_adapter, dbgid) {
13769 			hdd_adapter_for_each_active_link_info(adapter,
13770 							      link_info) {
13771 				vdev_id[num_adapters] = link_info->vdev_id;
13772 				num_adapters++;
13773 			}
13774 			/* dev_put has to be done here */
13775 			hdd_adapter_dev_put_debug(adapter, dbgid);
13776 		}
13777 
13778 		adapter = NULL;
13779 
13780 		for (i = 0; i < num_adapters; i++) {
13781 			vdev = wlan_objmgr_get_vdev_by_id_from_psoc(
13782 							hdd_ctx->psoc,
13783 							vdev_id[i],
13784 							WLAN_OSIF_ID);
13785 
13786 			if (!vdev)
13787 				continue;
13788 
13789 			link_info = wlan_hdd_get_link_info_from_objmgr(vdev);
13790 			if (!link_info) {
13791 				wlan_objmgr_vdev_release_ref(vdev,
13792 							     WLAN_OSIF_ID);
13793 				continue;
13794 			}
13795 
13796 			hdd_indicate_mgmt_frame_to_user(link_info->adapter,
13797 							frame_ind->frame_len,
13798 							frame_ind->frameBuf,
13799 							frame_ind->frameType,
13800 							frame_ind->rx_freq,
13801 							frame_ind->rxRssi,
13802 							frame_ind->rx_flags);
13803 			wlan_objmgr_vdev_release_ref(vdev, WLAN_OSIF_ID);
13804 		}
13805 
13806 		adapter = NULL;
13807 	} else {
13808 		link_info = hdd_get_link_info_by_vdev(hdd_ctx,
13809 						      frame_ind->sessionId);
13810 
13811 		if (!link_info) {
13812 			hdd_err("Invalid vdev");
13813 			return;
13814 		}
13815 
13816 		adapter = link_info->adapter;
13817 	}
13818 
13819 	if ((adapter) &&
13820 		(WLAN_HDD_ADAPTER_MAGIC == adapter->magic))
13821 		hdd_indicate_mgmt_frame_to_user(adapter,
13822 						frame_ind->frame_len,
13823 						frame_ind->frameBuf,
13824 						frame_ind->frameType,
13825 						frame_ind->rx_freq,
13826 						frame_ind->rxRssi,
13827 						frame_ind->rx_flags);
13828 }
13829 
hdd_acs_response_timeout_handler(void * context)13830 void hdd_acs_response_timeout_handler(void *context)
13831 {
13832 	struct hdd_external_acs_timer_context *timer_context =
13833 			(struct hdd_external_acs_timer_context *)context;
13834 	struct hdd_adapter *adapter;
13835 	struct hdd_context *hdd_ctx;
13836 	uint8_t reason;
13837 	struct sap_context *sap_context;
13838 	struct wlan_hdd_link_info *link_info;
13839 
13840 	hdd_enter();
13841 	if (!timer_context) {
13842 		hdd_err("invalid timer context");
13843 		return;
13844 	}
13845 	adapter = timer_context->adapter;
13846 	reason = timer_context->reason;
13847 
13848 	if (!adapter || adapter->magic != WLAN_HDD_ADAPTER_MAGIC) {
13849 		hdd_err("invalid adapter or adapter has invalid magic");
13850 		return;
13851 	}
13852 
13853 	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
13854 	if (wlan_hdd_validate_context(hdd_ctx))
13855 		return;
13856 
13857 	link_info = adapter->deflink;
13858 	if (!test_bit(VENDOR_ACS_RESPONSE_PENDING, &link_info->link_flags))
13859 		return;
13860 
13861 	clear_bit(VENDOR_ACS_RESPONSE_PENDING, &link_info->link_flags);
13862 
13863 	hdd_err("ACS timeout happened for %s reason %d",
13864 		adapter->dev->name, reason);
13865 
13866 	sap_context = WLAN_HDD_GET_SAP_CTX_PTR(link_info);
13867 	switch (reason) {
13868 	/* SAP init case */
13869 	case QCA_WLAN_VENDOR_ACS_SELECT_REASON_INIT:
13870 		wlan_sap_set_vendor_acs(sap_context, false);
13871 		wlan_hdd_cfg80211_start_acs(link_info);
13872 		break;
13873 	/* DFS detected on current channel */
13874 	case QCA_WLAN_VENDOR_ACS_SELECT_REASON_DFS:
13875 		wlan_sap_update_next_channel(sap_context, 0, 0);
13876 		sme_update_new_channel_event(hdd_ctx->mac_handle,
13877 					     link_info->vdev_id);
13878 		break;
13879 	/* LTE coex event on current channel */
13880 	case QCA_WLAN_VENDOR_ACS_SELECT_REASON_LTE_COEX:
13881 		hdd_lte_coex_restart_sap(adapter, hdd_ctx);
13882 		break;
13883 	default:
13884 		hdd_info("invalid reason for timer invoke");
13885 	}
13886 }
13887 
13888 /**
13889  * hdd_override_ini_config - Override INI config
13890  * @hdd_ctx: HDD context
13891  *
13892  * Override INI config based on module parameter.
13893  *
13894  * Return: None
13895  */
hdd_override_ini_config(struct hdd_context * hdd_ctx)13896 static void hdd_override_ini_config(struct hdd_context *hdd_ctx)
13897 {
13898 	QDF_STATUS status;
13899 
13900 	if (0 == enable_dfs_chan_scan || 1 == enable_dfs_chan_scan) {
13901 		ucfg_scan_cfg_set_dfs_chan_scan_allowed(hdd_ctx->psoc,
13902 							enable_dfs_chan_scan);
13903 		hdd_debug("Module enable_dfs_chan_scan set to %d",
13904 			   enable_dfs_chan_scan);
13905 	}
13906 	if (0 == enable_11d || 1 == enable_11d) {
13907 		status = ucfg_mlme_set_11d_enabled(hdd_ctx->psoc, enable_11d);
13908 		if (!QDF_IS_STATUS_SUCCESS(status))
13909 			hdd_err("Failed to set 11d_enable flag");
13910 	}
13911 }
13912 
13913 #ifdef ENABLE_MTRACE_LOG
hdd_set_mtrace_for_each(struct hdd_context * hdd_ctx)13914 static void hdd_set_mtrace_for_each(struct hdd_context *hdd_ctx)
13915 {
13916 	uint8_t module_id = 0;
13917 	int qdf_print_idx = -1;
13918 
13919 	qdf_print_idx = qdf_get_pidx();
13920 	for (module_id = 0; module_id < QDF_MODULE_ID_MAX; module_id++)
13921 		qdf_print_set_category_verbose(
13922 					qdf_print_idx,
13923 					module_id, QDF_TRACE_LEVEL_TRACE,
13924 					hdd_ctx->config->enable_mtrace);
13925 }
13926 #else
hdd_set_mtrace_for_each(struct hdd_context * hdd_ctx)13927 static void hdd_set_mtrace_for_each(struct hdd_context *hdd_ctx)
13928 {
13929 }
13930 
13931 #endif
13932 
13933 /**
13934  * hdd_log_level_to_bitmask() - user space log level to host log bitmask
13935  * @user_log_level: user space log level
13936  *
13937  * Convert log level from user space to host log level bitmask.
13938  *
13939  * Return: Bitmask of log levels to be enabled
13940  */
hdd_log_level_to_bitmask(enum host_log_level user_log_level)13941 static uint32_t hdd_log_level_to_bitmask(enum host_log_level user_log_level)
13942 {
13943 	QDF_TRACE_LEVEL host_trace_level;
13944 	uint32_t bitmask;
13945 
13946 	switch (user_log_level) {
13947 	case HOST_LOG_LEVEL_NONE:
13948 		host_trace_level = QDF_TRACE_LEVEL_NONE;
13949 		break;
13950 	case HOST_LOG_LEVEL_FATAL:
13951 		host_trace_level = QDF_TRACE_LEVEL_FATAL;
13952 		break;
13953 	case HOST_LOG_LEVEL_ERROR:
13954 		host_trace_level = QDF_TRACE_LEVEL_ERROR;
13955 		break;
13956 	case HOST_LOG_LEVEL_WARN:
13957 		host_trace_level = QDF_TRACE_LEVEL_WARN;
13958 		break;
13959 	case HOST_LOG_LEVEL_INFO:
13960 		host_trace_level = QDF_TRACE_LEVEL_INFO_LOW;
13961 		break;
13962 	case HOST_LOG_LEVEL_DEBUG:
13963 		host_trace_level = QDF_TRACE_LEVEL_DEBUG;
13964 		break;
13965 	case HOST_LOG_LEVEL_TRACE:
13966 		host_trace_level = QDF_TRACE_LEVEL_TRACE;
13967 		break;
13968 	default:
13969 		host_trace_level = QDF_TRACE_LEVEL_TRACE;
13970 		break;
13971 	}
13972 
13973 	bitmask = (1 << (host_trace_level + 1)) - 1;
13974 
13975 	return bitmask;
13976 }
13977 
13978 /**
13979  * hdd_set_trace_level_for_each - Set trace level for each INI config
13980  * @hdd_ctx: HDD context
13981  *
13982  * Set trace level for each module based on INI config.
13983  *
13984  * Return: None
13985  */
hdd_set_trace_level_for_each(struct hdd_context * hdd_ctx)13986 static void hdd_set_trace_level_for_each(struct hdd_context *hdd_ctx)
13987 {
13988 	uint8_t host_module_log[QDF_MODULE_ID_MAX * 2];
13989 	qdf_size_t host_module_log_num = 0;
13990 	QDF_MODULE_ID module_id;
13991 	uint32_t bitmask;
13992 	uint32_t i;
13993 
13994 	qdf_uint8_array_parse(cfg_get(hdd_ctx->psoc,
13995 				      CFG_ENABLE_HOST_MODULE_LOG_LEVEL),
13996 			      host_module_log,
13997 			      QDF_MODULE_ID_MAX * 2,
13998 			      &host_module_log_num);
13999 
14000 	for (i = 0; i + 1 < host_module_log_num; i += 2) {
14001 		module_id = host_module_log[i];
14002 		bitmask = hdd_log_level_to_bitmask(host_module_log[i + 1]);
14003 		if (module_id < QDF_MODULE_ID_MAX &&
14004 		    module_id >= QDF_MODULE_ID_MIN)
14005 			hdd_qdf_trace_enable(module_id, bitmask);
14006 	}
14007 
14008 	hdd_set_mtrace_for_each(hdd_ctx);
14009 }
14010 
14011 /**
14012  * hdd_context_init() - Initialize HDD context
14013  * @hdd_ctx:	HDD context.
14014  *
14015  * Initialize HDD context along with all the feature specific contexts.
14016  *
14017  * return: 0 on success and errno on failure.
14018  */
hdd_context_init(struct hdd_context * hdd_ctx)14019 static int hdd_context_init(struct hdd_context *hdd_ctx)
14020 {
14021 	int ret;
14022 
14023 	hdd_ctx->ioctl_scan_mode = eSIR_ACTIVE_SCAN;
14024 	hdd_ctx->max_intf_count = WLAN_MAX_VDEVS;
14025 
14026 	init_completion(&hdd_ctx->mc_sus_event_var);
14027 	init_completion(&hdd_ctx->ready_to_suspend);
14028 
14029 	qdf_spinlock_create(&hdd_ctx->connection_status_lock);
14030 	qdf_spinlock_create(&hdd_ctx->hdd_adapter_lock);
14031 
14032 	qdf_list_create(&hdd_ctx->hdd_adapters, 0);
14033 
14034 	ret = hdd_scan_context_init(hdd_ctx);
14035 	if (ret)
14036 		goto list_destroy;
14037 
14038 	ret = hdd_sap_context_init(hdd_ctx);
14039 	if (ret)
14040 		goto scan_destroy;
14041 
14042 	ret = ucfg_dp_bbm_context_init(hdd_ctx->psoc);
14043 	if (ret)
14044 		goto sap_destroy;
14045 
14046 	wlan_hdd_cfg80211_extscan_init(hdd_ctx);
14047 
14048 	hdd_init_offloaded_packets_ctx(hdd_ctx);
14049 
14050 	ret = wlan_hdd_cfg80211_init(hdd_ctx->parent_dev, hdd_ctx->wiphy,
14051 				     hdd_ctx->config);
14052 	if (ret)
14053 		goto bbm_destroy;
14054 
14055 	qdf_wake_lock_create(&hdd_ctx->monitor_mode_wakelock,
14056 			     "monitor_mode_wakelock");
14057 	hdd_lp_create_work(hdd_ctx);
14058 
14059 	return 0;
14060 
14061 bbm_destroy:
14062 	ucfg_dp_bbm_context_deinit(hdd_ctx->psoc);
14063 
14064 sap_destroy:
14065 	hdd_sap_context_destroy(hdd_ctx);
14066 
14067 scan_destroy:
14068 	hdd_scan_context_destroy(hdd_ctx);
14069 list_destroy:
14070 	qdf_list_destroy(&hdd_ctx->hdd_adapters);
14071 
14072 	return ret;
14073 }
14074 
14075 #ifdef SHUTDOWN_WLAN_IN_SYSTEM_SUSPEND
hdd_idle_timer_in_active(uint32_t timeout_ms)14076 static void hdd_idle_timer_in_active(uint32_t timeout_ms)
14077 {
14078 	/* do nothing because idle shutdown will be called in system
14079 	 * suspend prepare
14080 	 */
14081 }
14082 #else
14083 /* ensure idle shutdown can be called/finished once timer started */
hdd_idle_timer_in_active(uint32_t timeout_ms)14084 static void hdd_idle_timer_in_active(uint32_t timeout_ms)
14085 {
14086 	uint32_t suspend_timeout_ms;
14087 	enum wake_lock_reason reason =
14088 		WIFI_POWER_EVENT_WAKELOCK_IFACE_CHANGE_TIMER;
14089 
14090 	suspend_timeout_ms = timeout_ms + HDD_PSOC_IDLE_SHUTDOWN_SUSPEND_DELAY;
14091 	hdd_prevent_suspend_timeout(suspend_timeout_ms, reason);
14092 }
14093 #endif
14094 
hdd_psoc_idle_timer_start(struct hdd_context * hdd_ctx)14095 void hdd_psoc_idle_timer_start(struct hdd_context *hdd_ctx)
14096 {
14097 	uint32_t timeout_ms = hdd_ctx->config->iface_change_wait_time;
14098 
14099 	if (!timeout_ms) {
14100 		hdd_info("psoc idle timer is disabled");
14101 		return;
14102 	}
14103 
14104 	hdd_debug("Starting psoc idle timer");
14105 
14106 	/* If PCIe gen speed change is requested, reduce idle shutdown
14107 	 * timeout to 100 ms
14108 	 */
14109 	if (hdd_ctx->current_pcie_gen_speed) {
14110 		timeout_ms = HDD_PCIE_GEN_SPEED_CHANGE_TIMEOUT_MS;
14111 		hdd_info("pcie gen speed change requested");
14112 	}
14113 
14114 	qdf_delayed_work_start(&hdd_ctx->psoc_idle_timeout_work, timeout_ms);
14115 	hdd_idle_timer_in_active(timeout_ms);
14116 }
14117 
hdd_psoc_idle_timer_stop(struct hdd_context * hdd_ctx)14118 void hdd_psoc_idle_timer_stop(struct hdd_context *hdd_ctx)
14119 {
14120 	qdf_delayed_work_stop_sync(&hdd_ctx->psoc_idle_timeout_work);
14121 	hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_IFACE_CHANGE_TIMER);
14122 	hdd_debug("Stopped psoc idle timer");
14123 }
14124 
14125 
14126 /**
14127  * __hdd_psoc_idle_shutdown() - perform an idle shutdown on the given psoc
14128  * @hdd_ctx: the hdd context which should be shutdown
14129  *
14130  * When no interfaces are "up" on a psoc, an idle shutdown timer is started.
14131  * If no interfaces are brought up before the timer expires, we do an
14132  * "idle shutdown," cutting power to the physical SoC to save power. This is
14133  * done completely transparently from the perspective of userspace.
14134  *
14135  * Return: None
14136  */
__hdd_psoc_idle_shutdown(struct hdd_context * hdd_ctx)14137 static int __hdd_psoc_idle_shutdown(struct hdd_context *hdd_ctx)
14138 {
14139 	struct osif_psoc_sync *psoc_sync;
14140 	int errno;
14141 
14142 	hdd_enter();
14143 
14144 	hdd_reg_wait_for_country_change(hdd_ctx);
14145 
14146 	errno = osif_psoc_sync_trans_start(hdd_ctx->parent_dev, &psoc_sync);
14147 	if (errno) {
14148 		hdd_info("psoc busy, abort idle shutdown; errno:%d", errno);
14149 		errno = -EAGAIN;
14150 		goto exit;
14151 	}
14152 
14153 	osif_psoc_sync_wait_for_ops(psoc_sync);
14154 	/*
14155 	 * This is to handle scenario in which platform driver triggers
14156 	 * idle_shutdown if Deep Sleep/Hibernate entry notification is
14157 	 * received from modem subsystem in wearable devices
14158 	 */
14159 	if (hdd_is_any_interface_open(hdd_ctx)) {
14160 		hdd_err_rl("all interfaces are not down, ignore idle shutdown");
14161 		errno = -EAGAIN;
14162 	} else {
14163 		errno = hdd_wlan_stop_modules(hdd_ctx, false);
14164 	}
14165 
14166 	osif_psoc_sync_trans_stop(psoc_sync);
14167 
14168 exit:
14169 	hdd_exit();
14170 	return errno;
14171 }
14172 
__hdd_mode_change_psoc_idle_shutdown(struct hdd_context * hdd_ctx)14173 static int __hdd_mode_change_psoc_idle_shutdown(struct hdd_context *hdd_ctx)
14174 {
14175 	is_mode_change_psoc_idle_shutdown = false;
14176 	return hdd_wlan_stop_modules(hdd_ctx, true);
14177 }
14178 
hdd_psoc_idle_shutdown(struct device * dev)14179 int hdd_psoc_idle_shutdown(struct device *dev)
14180 {
14181 	int ret;
14182 	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
14183 
14184 	if (!hdd_ctx)
14185 		return -EINVAL;
14186 
14187 	if (is_mode_change_psoc_idle_shutdown)
14188 		ret = __hdd_mode_change_psoc_idle_shutdown(hdd_ctx);
14189 	else {
14190 		ret =  __hdd_psoc_idle_shutdown(hdd_ctx);
14191 	}
14192 
14193 	return ret;
14194 }
14195 
__hdd_psoc_idle_restart(struct hdd_context * hdd_ctx)14196 static int __hdd_psoc_idle_restart(struct hdd_context *hdd_ctx)
14197 {
14198 	int ret;
14199 
14200 	ret = hdd_soc_idle_restart_lock(hdd_ctx->parent_dev);
14201 	if (ret)
14202 		return ret;
14203 
14204 	ret = hdd_wlan_start_modules(hdd_ctx, false);
14205 
14206 	if (!qdf_is_fw_down())
14207 		cds_set_recovery_in_progress(false);
14208 
14209 	hdd_soc_idle_restart_unlock();
14210 
14211 	return ret;
14212 }
14213 
hdd_psoc_idle_restart(struct device * dev)14214 int hdd_psoc_idle_restart(struct device *dev)
14215 {
14216 	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
14217 
14218 	if (!hdd_ctx)
14219 		return -EINVAL;
14220 
14221 	return __hdd_psoc_idle_restart(hdd_ctx);
14222 }
14223 
hdd_trigger_psoc_idle_restart(struct hdd_context * hdd_ctx)14224 int hdd_trigger_psoc_idle_restart(struct hdd_context *hdd_ctx)
14225 {
14226 	int ret;
14227 
14228 	QDF_BUG(rtnl_is_locked());
14229 
14230 	hdd_psoc_idle_timer_stop(hdd_ctx);
14231 	if (hdd_ctx->driver_status == DRIVER_MODULES_ENABLED) {
14232 		hdd_nofl_debug("Driver modules already Enabled");
14233 		return 0;
14234 	}
14235 
14236 	ret = hdd_soc_idle_restart_lock(hdd_ctx->parent_dev);
14237 	if (ret)
14238 		return ret;
14239 
14240 	if (hdd_ctx->current_pcie_gen_speed) {
14241 		hdd_info("request pcie gen speed change to %d",
14242 			 hdd_ctx->current_pcie_gen_speed);
14243 
14244 		/* call pld api for pcie gen speed change */
14245 		ret  = pld_set_pcie_gen_speed(hdd_ctx->parent_dev,
14246 					      hdd_ctx->current_pcie_gen_speed);
14247 		if (ret)
14248 			hdd_err_rl("failed to set pcie gen speed");
14249 
14250 		hdd_ctx->current_pcie_gen_speed = 0;
14251 	}
14252 
14253 	qdf_event_reset(&hdd_ctx->regulatory_update_event);
14254 	qdf_mutex_acquire(&hdd_ctx->regulatory_status_lock);
14255 	hdd_ctx->is_regulatory_update_in_progress = true;
14256 	qdf_mutex_release(&hdd_ctx->regulatory_status_lock);
14257 
14258 	ret = pld_idle_restart(hdd_ctx->parent_dev, hdd_psoc_idle_restart);
14259 	hdd_soc_idle_restart_unlock();
14260 
14261 	return ret;
14262 }
14263 
14264 /**
14265  * hdd_psoc_idle_timeout_callback() - Handler for psoc idle timeout
14266  * @priv: pointer to hdd context
14267  *
14268  * Return: None
14269  */
hdd_psoc_idle_timeout_callback(void * priv)14270 static void hdd_psoc_idle_timeout_callback(void *priv)
14271 {
14272 	int ret;
14273 	struct hdd_context *hdd_ctx = priv;
14274 	void *hif_ctx;
14275 
14276 	if (wlan_hdd_validate_context(hdd_ctx))
14277 		return;
14278 
14279 	hif_ctx = cds_get_context(QDF_MODULE_ID_HIF);
14280 	if (hif_ctx) {
14281 		/*
14282 		 * Trigger runtime sync resume before psoc_idle_shutdown
14283 		 * such that resume can happen successfully
14284 		 */
14285 		qdf_rtpm_sync_resume();
14286 	}
14287 
14288 	hdd_info("Psoc idle timeout elapsed; starting psoc shutdown");
14289 
14290 	ret = pld_idle_shutdown(hdd_ctx->parent_dev, hdd_psoc_idle_shutdown);
14291 	if (-EAGAIN == ret || hdd_ctx->is_wiphy_suspended) {
14292 		hdd_debug("System suspend in progress. Restart idle shutdown timer");
14293 		hdd_psoc_idle_timer_start(hdd_ctx);
14294 	}
14295 
14296 	/* Clear the recovery flag for PCIe discrete soc after idle shutdown*/
14297 	if (PLD_BUS_TYPE_PCIE == pld_get_bus_type(hdd_ctx->parent_dev) &&
14298 	    -EBUSY != ret)
14299 		cds_set_recovery_in_progress(false);
14300 }
14301 
14302 #ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
hdd_set_wlan_logging(struct hdd_context * hdd_ctx)14303 static void hdd_set_wlan_logging(struct hdd_context *hdd_ctx)
14304 {
14305 	wlan_set_console_log_levels(hdd_ctx->config->wlan_console_log_levels);
14306 	wlan_logging_set_active(hdd_ctx->config->wlan_logging_enable);
14307 }
14308 #else
hdd_set_wlan_logging(struct hdd_context * hdd_ctx)14309 static void hdd_set_wlan_logging(struct hdd_context *hdd_ctx)
14310 { }
14311 #endif
14312 
14313 #ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
hdd_init_wlan_logging_params(struct hdd_config * config,struct wlan_objmgr_psoc * psoc)14314 static void hdd_init_wlan_logging_params(struct hdd_config *config,
14315 					 struct wlan_objmgr_psoc *psoc)
14316 {
14317 	config->wlan_logging_enable = cfg_get(psoc, CFG_WLAN_LOGGING_SUPPORT);
14318 
14319 	config->wlan_console_log_levels =
14320 			cfg_get(psoc, CFG_WLAN_LOGGING_CONSOLE_SUPPORT);
14321 	config->host_log_custom_nl_proto =
14322 		cfg_get(psoc, CFG_HOST_LOG_CUSTOM_NETLINK_PROTO);
14323 }
14324 #else
hdd_init_wlan_logging_params(struct hdd_config * config,struct wlan_objmgr_psoc * psoc)14325 static void hdd_init_wlan_logging_params(struct hdd_config *config,
14326 					 struct wlan_objmgr_psoc *psoc)
14327 {
14328 }
14329 #endif
14330 
14331 #ifdef FEATURE_WLAN_AUTO_SHUTDOWN
hdd_init_wlan_auto_shutdown(struct hdd_config * config,struct wlan_objmgr_psoc * psoc)14332 static void hdd_init_wlan_auto_shutdown(struct hdd_config *config,
14333 					struct wlan_objmgr_psoc *psoc)
14334 {
14335 	config->wlan_auto_shutdown = cfg_get(psoc, CFG_WLAN_AUTO_SHUTDOWN);
14336 }
14337 #else
hdd_init_wlan_auto_shutdown(struct hdd_config * config,struct wlan_objmgr_psoc * psoc)14338 static void hdd_init_wlan_auto_shutdown(struct hdd_config *config,
14339 					struct wlan_objmgr_psoc *psoc)
14340 {
14341 }
14342 #endif
14343 
14344 #ifndef REMOVE_PKT_LOG
hdd_init_packet_log(struct hdd_config * config,struct wlan_objmgr_psoc * psoc)14345 static void hdd_init_packet_log(struct hdd_config *config,
14346 				struct wlan_objmgr_psoc *psoc)
14347 {
14348 	config->enable_packet_log = cfg_get(psoc, CFG_ENABLE_PACKET_LOG);
14349 }
14350 #else
hdd_init_packet_log(struct hdd_config * config,struct wlan_objmgr_psoc * psoc)14351 static void hdd_init_packet_log(struct hdd_config *config,
14352 				struct wlan_objmgr_psoc *psoc)
14353 {
14354 }
14355 #endif
14356 
14357 #ifdef ENABLE_MTRACE_LOG
hdd_init_mtrace_log(struct hdd_config * config,struct wlan_objmgr_psoc * psoc)14358 static void hdd_init_mtrace_log(struct hdd_config *config,
14359 				struct wlan_objmgr_psoc *psoc)
14360 {
14361 	config->enable_mtrace = cfg_get(psoc, CFG_ENABLE_MTRACE);
14362 }
14363 #else
hdd_init_mtrace_log(struct hdd_config * config,struct wlan_objmgr_psoc * psoc)14364 static void hdd_init_mtrace_log(struct hdd_config *config,
14365 				struct wlan_objmgr_psoc *psoc)
14366 {
14367 }
14368 #endif
14369 
14370 #ifdef FEATURE_RUNTIME_PM
hdd_init_runtime_pm(struct hdd_config * config,struct wlan_objmgr_psoc * psoc)14371 static void hdd_init_runtime_pm(struct hdd_config *config,
14372 				struct wlan_objmgr_psoc *psoc)
14373 {
14374 	config->runtime_pm = cfg_get(psoc, CFG_ENABLE_RUNTIME_PM);
14375 }
14376 
hdd_is_runtime_pm_enabled(struct hdd_context * hdd_ctx)14377 bool hdd_is_runtime_pm_enabled(struct hdd_context *hdd_ctx)
14378 {
14379 	return hdd_ctx->config->runtime_pm != hdd_runtime_pm_disabled;
14380 }
14381 #else
hdd_init_runtime_pm(struct hdd_config * config,struct wlan_objmgr_psoc * psoc)14382 static void hdd_init_runtime_pm(struct hdd_config *config,
14383 				struct wlan_objmgr_psoc *psoc)
14384 
14385 {
14386 }
14387 
hdd_is_runtime_pm_enabled(struct hdd_context * hdd_ctx)14388 bool hdd_is_runtime_pm_enabled(struct hdd_context *hdd_ctx)
14389 {
14390 	return false;
14391 }
14392 #endif
14393 
14394 #ifdef WLAN_FEATURE_WMI_SEND_RECV_QMI
hdd_init_qmi_stats(struct hdd_config * config,struct wlan_objmgr_psoc * psoc)14395 static void hdd_init_qmi_stats(struct hdd_config *config,
14396 			       struct wlan_objmgr_psoc *psoc)
14397 {
14398 	config->is_qmi_stats_enabled = cfg_get(psoc, CFG_ENABLE_QMI_STATS);
14399 }
14400 #else
hdd_init_qmi_stats(struct hdd_config * config,struct wlan_objmgr_psoc * psoc)14401 static void hdd_init_qmi_stats(struct hdd_config *config,
14402 			       struct wlan_objmgr_psoc *psoc)
14403 
14404 {
14405 }
14406 #endif
14407 
14408 #ifdef FEATURE_WLAN_DYNAMIC_CVM
hdd_init_vc_mode_cfg_bitmap(struct hdd_config * config,struct wlan_objmgr_psoc * psoc)14409 static void hdd_init_vc_mode_cfg_bitmap(struct hdd_config *config,
14410 					struct wlan_objmgr_psoc *psoc)
14411 {
14412 	config->vc_mode_cfg_bitmap = cfg_get(psoc, CFG_VC_MODE_BITMAP);
14413 }
14414 #else
hdd_init_vc_mode_cfg_bitmap(struct hdd_config * config,struct wlan_objmgr_psoc * psoc)14415 static void hdd_init_vc_mode_cfg_bitmap(struct hdd_config *config,
14416 					struct wlan_objmgr_psoc *psoc)
14417 {
14418 }
14419 #endif
14420 
14421 #ifdef DHCP_SERVER_OFFLOAD
14422 static void
hdd_init_dhcp_server_ip(struct hdd_context * hdd_ctx)14423 hdd_init_dhcp_server_ip(struct hdd_context *hdd_ctx)
14424 {
14425 	uint8_t num_entries;
14426 
14427 	hdd_ctx->config->dhcp_server_ip.is_dhcp_server_ip_valid = true;
14428 	hdd_string_to_u8_array(cfg_get(hdd_ctx->psoc, CFG_DHCP_SERVER_IP_NAME),
14429 			       hdd_ctx->config->dhcp_server_ip.dhcp_server_ip,
14430 			       &num_entries, IPADDR_NUM_ENTRIES);
14431 
14432 	if (num_entries != IPADDR_NUM_ENTRIES) {
14433 		hdd_err("Incorrect IP address (%s) assigned for DHCP server!",
14434 			cfg_get(hdd_ctx->psoc, CFG_DHCP_SERVER_IP_NAME));
14435 		hdd_config->dhcp_server_ip.is_dhcp_server_ip_valid = false;
14436 	}
14437 }
14438 #else
14439 static void
hdd_init_dhcp_server_ip(struct hdd_context * hdd_ctx)14440 hdd_init_dhcp_server_ip(struct hdd_context *hdd_ctx)
14441 {
14442 }
14443 #endif
14444 
14445 #ifdef SAR_SAFETY_FEATURE
hdd_sar_cfg_update(struct hdd_config * config,struct wlan_objmgr_psoc * psoc)14446 static void hdd_sar_cfg_update(struct hdd_config *config,
14447 			       struct wlan_objmgr_psoc *psoc)
14448 {
14449 	config->sar_safety_timeout = cfg_get(psoc, CFG_SAR_SAFETY_TIMEOUT);
14450 	config->sar_safety_unsolicited_timeout =
14451 			cfg_get(psoc, CFG_SAR_SAFETY_UNSOLICITED_TIMEOUT);
14452 	config->sar_safety_req_resp_timeout =
14453 				cfg_get(psoc, CFG_SAR_SAFETY_REQ_RESP_TIMEOUT);
14454 	config->sar_safety_req_resp_retry =
14455 				cfg_get(psoc, CFG_SAR_SAFETY_REQ_RESP_RETRIES);
14456 	config->sar_safety_index = cfg_get(psoc, CFG_SAR_SAFETY_INDEX);
14457 	config->sar_safety_sleep_index =
14458 				cfg_get(psoc, CFG_SAR_SAFETY_SLEEP_INDEX);
14459 	config->enable_sar_safety =
14460 				cfg_get(psoc, CFG_ENABLE_SAR_SAFETY_FEATURE);
14461 	config->config_sar_safety_sleep_index =
14462 			cfg_get(psoc, CFG_CONFIG_SAR_SAFETY_SLEEP_MODE_INDEX);
14463 }
14464 
hdd_set_sar_init_index(struct hdd_context * hdd_ctx)14465 void hdd_set_sar_init_index(struct hdd_context *hdd_ctx)
14466 {
14467 	uint32_t index, enable = 0;
14468 
14469 	if (!hdd_ctx) {
14470 		hdd_err("hdd_ctx NULL");
14471 		return;
14472 	}
14473 	if (hdd_ctx->sar_version == SAR_VERSION_1) {
14474 		hdd_nofl_debug("FW SAR version: %d", hdd_ctx->sar_version);
14475 		return;
14476 	}
14477 
14478 	enable = hdd_ctx->config->enable_sar_safety;
14479 	index = hdd_ctx->config->sar_safety_index;
14480 	if (enable & SAR_SAFETY_ENABLED_INIT)
14481 		hdd_configure_sar_index(hdd_ctx, index);
14482 }
14483 #else
hdd_sar_cfg_update(struct hdd_config * config,struct wlan_objmgr_psoc * psoc)14484 static void hdd_sar_cfg_update(struct hdd_config *config,
14485 			       struct wlan_objmgr_psoc *psoc)
14486 {
14487 }
14488 #endif
14489 
14490 #ifdef FEATURE_SET
14491 /**
14492  * hdd_get_wifi_features_cfg_update() - Initialize get wifi features cfg
14493  * @config: Pointer to HDD config
14494  * @psoc: psoc pointer
14495  *
14496  * Return: None
14497  */
hdd_get_wifi_features_cfg_update(struct hdd_config * config,struct wlan_objmgr_psoc * psoc)14498 static void hdd_get_wifi_features_cfg_update(struct hdd_config *config,
14499 					     struct wlan_objmgr_psoc *psoc)
14500 {
14501 	config->get_wifi_features = cfg_get(psoc, CFG_GET_WIFI_FEATURES);
14502 }
14503 #else
hdd_get_wifi_features_cfg_update(struct hdd_config * config,struct wlan_objmgr_psoc * psoc)14504 static void hdd_get_wifi_features_cfg_update(struct hdd_config *config,
14505 					     struct wlan_objmgr_psoc *psoc)
14506 {
14507 }
14508 #endif
14509 
14510 #ifdef FEATURE_RUNTIME_PM
14511 /**
14512  * hdd_init_cpu_cxpc_threshold_cfg() - Initialize cpu cxpc threshold cfg
14513  * @config: Pointer to HDD config
14514  * @psoc: psoc pointer
14515  *
14516  * Return: None
14517  */
hdd_init_cpu_cxpc_threshold_cfg(struct hdd_config * config,struct wlan_objmgr_psoc * psoc)14518 static void hdd_init_cpu_cxpc_threshold_cfg(struct hdd_config *config,
14519 					    struct wlan_objmgr_psoc *psoc)
14520 {
14521 	config->cpu_cxpc_threshold = cfg_get(psoc, CFG_CPU_CXPC_THRESHOLD);
14522 }
14523 #else
hdd_init_cpu_cxpc_threshold_cfg(struct hdd_config * config,struct wlan_objmgr_psoc * psoc)14524 static void hdd_init_cpu_cxpc_threshold_cfg(struct hdd_config *config,
14525 					    struct wlan_objmgr_psoc *psoc)
14526 {
14527 }
14528 #endif
14529 
14530 /**
14531  * hdd_cfg_params_init() - Initialize hdd params in hdd_config structure
14532  * @hdd_ctx: Pointer to HDD context
14533  *
14534  * Return: None
14535  */
hdd_cfg_params_init(struct hdd_context * hdd_ctx)14536 static void hdd_cfg_params_init(struct hdd_context *hdd_ctx)
14537 {
14538 	struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc;
14539 	struct hdd_config *config = hdd_ctx->config;
14540 	if (!psoc) {
14541 		hdd_err("Invalid psoc");
14542 		return;
14543 	}
14544 
14545 	if (!config) {
14546 		hdd_err("Invalid hdd config");
14547 		return;
14548 	}
14549 
14550 	config->dot11Mode = cfg_get(psoc, CFG_HDD_DOT11_MODE);
14551 	config->bug_on_reinit_failure = cfg_get(psoc,
14552 						CFG_BUG_ON_REINIT_FAILURE);
14553 
14554 	config->is_ramdump_enabled = cfg_get(psoc,
14555 					     CFG_ENABLE_RAMDUMP_COLLECTION);
14556 
14557 	config->iface_change_wait_time = cfg_get(psoc,
14558 						 CFG_INTERFACE_CHANGE_WAIT);
14559 
14560 	config->multicast_host_fw_msgs = cfg_get(psoc,
14561 						 CFG_MULTICAST_HOST_FW_MSGS);
14562 
14563 	config->private_wext_control = cfg_get(psoc, CFG_PRIVATE_WEXT_CONTROL);
14564 	config->enablefwprint = cfg_get(psoc, CFG_ENABLE_FW_UART_PRINT);
14565 	config->enable_fw_log = cfg_get(psoc, CFG_ENABLE_FW_LOG);
14566 	config->operating_chan_freq = cfg_get(psoc, CFG_OPERATING_FREQUENCY);
14567 	config->num_vdevs = cfg_get(psoc, CFG_NUM_VDEV_ENABLE);
14568 	qdf_str_lcopy(config->enable_concurrent_sta,
14569 		      cfg_get(psoc, CFG_ENABLE_CONCURRENT_STA),
14570 		      CFG_CONCURRENT_IFACE_MAX_LEN);
14571 	qdf_str_lcopy(config->dbs_scan_selection,
14572 		      cfg_get(psoc, CFG_DBS_SCAN_SELECTION),
14573 		      CFG_DBS_SCAN_PARAM_LENGTH);
14574 	config->inform_bss_rssi_raw = cfg_get(psoc, CFG_INFORM_BSS_RSSI_RAW);
14575 	config->mac_provision = cfg_get(psoc, CFG_ENABLE_MAC_PROVISION);
14576 	config->provisioned_intf_pool =
14577 				cfg_get(psoc, CFG_PROVISION_INTERFACE_POOL);
14578 	config->derived_intf_pool = cfg_get(psoc, CFG_DERIVED_INTERFACE_POOL);
14579 	config->advertise_concurrent_operation =
14580 				cfg_get(psoc,
14581 					CFG_ADVERTISE_CONCURRENT_OPERATION);
14582 	config->is_unit_test_framework_enabled =
14583 			cfg_get(psoc, CFG_ENABLE_UNIT_TEST_FRAMEWORK);
14584 	config->disable_channel = cfg_get(psoc, CFG_ENABLE_DISABLE_CHANNEL);
14585 	config->enable_sar_conversion = cfg_get(psoc, CFG_SAR_CONVERSION);
14586 	config->nb_commands_interval =
14587 				cfg_get(psoc, CFG_NB_COMMANDS_RATE_LIMIT);
14588 
14589 	hdd_init_vc_mode_cfg_bitmap(config, psoc);
14590 	hdd_init_runtime_pm(config, psoc);
14591 	hdd_init_wlan_auto_shutdown(config, psoc);
14592 	hdd_init_wlan_logging_params(config, psoc);
14593 	hdd_init_packet_log(config, psoc);
14594 	hdd_init_mtrace_log(config, psoc);
14595 	hdd_init_dhcp_server_ip(hdd_ctx);
14596 	hdd_dp_cfg_update(psoc, hdd_ctx);
14597 	hdd_sar_cfg_update(config, psoc);
14598 	hdd_init_qmi_stats(config, psoc);
14599 	hdd_club_ll_stats_in_get_sta_cfg_update(config, psoc);
14600 	config->read_mac_addr_from_mac_file =
14601 			cfg_get(psoc, CFG_READ_MAC_ADDR_FROM_MAC_FILE);
14602 
14603 	hdd_get_wifi_features_cfg_update(config, psoc);
14604 	hdd_init_cpu_cxpc_threshold_cfg(config, psoc);
14605 
14606 	config->exclude_selftx_from_cca_busy =
14607 			cfg_get(psoc, CFG_EXCLUDE_SELFTX_FROM_CCA_BUSY_TIME);
14608 	hdd_init_link_state_cfg(config, psoc);
14609 }
14610 
14611 #ifdef CONNECTION_ROAMING_CFG
hdd_cfg_parse_connection_roaming_cfg(void)14612 static QDF_STATUS hdd_cfg_parse_connection_roaming_cfg(void)
14613 {
14614 	QDF_STATUS status = QDF_STATUS_E_INVAL;
14615 	bool is_valid;
14616 
14617 	is_valid = cfg_valid_ini_check(WLAN_CONNECTION_ROAMING_INI_FILE);
14618 
14619 	if (is_valid)
14620 		status = cfg_parse(WLAN_CONNECTION_ROAMING_INI_FILE);
14621 	if (QDF_IS_STATUS_ERROR(status)) {
14622 		is_valid = cfg_valid_ini_check(WLAN_CONNECTION_ROAMING_BACKUP_INI_FILE);
14623 		if (is_valid)
14624 			status = cfg_parse(WLAN_CONNECTION_ROAMING_BACKUP_INI_FILE);
14625 	}
14626 	return status;
14627 }
14628 #else
hdd_cfg_parse_connection_roaming_cfg(void)14629 static inline QDF_STATUS hdd_cfg_parse_connection_roaming_cfg(void)
14630 {
14631 	return QDF_STATUS_E_NOSUPPORT;
14632 }
14633 #endif
14634 
hdd_context_create(struct device * dev)14635 struct hdd_context *hdd_context_create(struct device *dev)
14636 {
14637 	QDF_STATUS status;
14638 	int ret = 0;
14639 	struct hdd_context *hdd_ctx;
14640 
14641 	hdd_enter();
14642 
14643 	hdd_ctx = hdd_cfg80211_wiphy_alloc();
14644 	if (!hdd_ctx) {
14645 		ret = -ENOMEM;
14646 		goto err_out;
14647 	}
14648 
14649 	status = qdf_delayed_work_create(&hdd_ctx->psoc_idle_timeout_work,
14650 					 hdd_psoc_idle_timeout_callback,
14651 					 hdd_ctx);
14652 	if (QDF_IS_STATUS_ERROR(status)) {
14653 		ret = qdf_status_to_os_return(status);
14654 		goto wiphy_dealloc;
14655 	}
14656 
14657 	hdd_pm_notifier_init(hdd_ctx);
14658 
14659 	hdd_ctx->parent_dev = dev;
14660 	hdd_ctx->last_scan_reject_vdev_id = WLAN_UMAC_VDEV_ID_MAX;
14661 
14662 	hdd_ctx->config = qdf_mem_malloc(sizeof(struct hdd_config));
14663 	if (!hdd_ctx->config) {
14664 		ret = -ENOMEM;
14665 		goto err_free_hdd_context;
14666 	}
14667 
14668 	status = cfg_parse(WLAN_INI_FILE);
14669 	if (QDF_IS_STATUS_ERROR(status)) {
14670 		hdd_err("Failed to parse cfg %s; status:%d\n",
14671 			WLAN_INI_FILE, status);
14672 		/* Assert if failed to parse at least one INI parameter */
14673 		QDF_BUG(status != QDF_STATUS_E_INVAL);
14674 		ret = qdf_status_to_os_return(status);
14675 		goto err_free_config;
14676 	}
14677 
14678 	status = hdd_cfg_parse_connection_roaming_cfg();
14679 
14680 	ret = hdd_objmgr_create_and_store_psoc(hdd_ctx, DEFAULT_PSOC_ID);
14681 	if (ret) {
14682 		QDF_DEBUG_PANIC("Psoc creation fails!");
14683 		goto err_release_store;
14684 	}
14685 
14686 	if (QDF_IS_STATUS_SUCCESS(status))
14687 		ucfg_mlme_set_connection_roaming_ini_present(hdd_ctx->psoc,
14688 							     true);
14689 
14690 	hdd_cfg_params_init(hdd_ctx);
14691 
14692 	/* apply multiplier config, if not already set via module parameter */
14693 	if (qdf_timer_get_multiplier() == 1)
14694 		qdf_timer_set_multiplier(cfg_get(hdd_ctx->psoc,
14695 						 CFG_TIMER_MULTIPLIER));
14696 	hdd_debug("set timer multiplier: %u", qdf_timer_get_multiplier());
14697 
14698 	cds_set_fatal_event(cfg_get(hdd_ctx->psoc,
14699 				    CFG_ENABLE_FATAL_EVENT_TRIGGER));
14700 
14701 	hdd_override_ini_config(hdd_ctx);
14702 
14703 	ret = hdd_context_init(hdd_ctx);
14704 
14705 	if (ret)
14706 		goto err_hdd_objmgr_destroy;
14707 
14708 	if (hdd_get_conparam() == QDF_GLOBAL_EPPING_MODE)
14709 		goto skip_multicast_logging;
14710 
14711 	cds_set_multicast_logging(hdd_ctx->config->multicast_host_fw_msgs);
14712 	ret = hdd_init_netlink_services(hdd_ctx);
14713 	if (ret)
14714 		goto err_deinit_hdd_context;
14715 
14716 	hdd_set_wlan_logging(hdd_ctx);
14717 	qdf_atomic_init(&hdd_ctx->adapter_ops_history.index);
14718 
14719 skip_multicast_logging:
14720 	hdd_set_trace_level_for_each(hdd_ctx);
14721 
14722 	cds_set_context(QDF_MODULE_ID_HDD, hdd_ctx);
14723 
14724 	wlan_hdd_sar_timers_init(hdd_ctx);
14725 
14726 	hdd_exit();
14727 
14728 	return hdd_ctx;
14729 
14730 err_deinit_hdd_context:
14731 	hdd_context_deinit(hdd_ctx);
14732 
14733 err_hdd_objmgr_destroy:
14734 	hdd_objmgr_release_and_destroy_psoc(hdd_ctx);
14735 
14736 err_release_store:
14737 	cfg_release();
14738 
14739 err_free_config:
14740 	qdf_mem_free(hdd_ctx->config);
14741 
14742 err_free_hdd_context:
14743 	qdf_delayed_work_destroy(&hdd_ctx->psoc_idle_timeout_work);
14744 
14745 wiphy_dealloc:
14746 	wiphy_free(hdd_ctx->wiphy);
14747 
14748 err_out:
14749 	return ERR_PTR(ret);
14750 }
14751 
14752 #ifdef MULTI_CLIENT_LL_SUPPORT
14753 /**
14754  * wlan_hdd_init_multi_client_info_table()- Initialize the multi client info
14755  * table
14756  * @adapter: hdd adapter
14757  *
14758  * Return: none
14759  */
14760 static void
wlan_hdd_init_multi_client_info_table(struct hdd_adapter * adapter)14761 wlan_hdd_init_multi_client_info_table(struct hdd_adapter *adapter)
14762 {
14763 	uint8_t i;
14764 
14765 	for (i = 0; i < WLM_MAX_HOST_CLIENT; i++) {
14766 		adapter->client_info[i].client_id = i;
14767 		adapter->client_info[i].port_id = 0;
14768 		adapter->client_info[i].in_use = false;
14769 	}
14770 }
14771 
wlan_hdd_deinit_multi_client_info_table(struct hdd_adapter * adapter)14772 void wlan_hdd_deinit_multi_client_info_table(struct hdd_adapter *adapter)
14773 {
14774 	uint8_t i;
14775 
14776 	hdd_debug("deinitializing the client info table");
14777 	/* de-initialize the table for host driver client */
14778 	for (i = 0; i < WLM_MAX_HOST_CLIENT; i++) {
14779 		if (adapter->client_info[i].in_use) {
14780 			adapter->client_info[i].port_id = 0;
14781 			adapter->client_info[i].client_id = i;
14782 			adapter->client_info[i].in_use = false;
14783 		}
14784 	}
14785 }
14786 
14787 /**
14788  * wlan_hdd_get_host_driver_port_id()- get host driver port id
14789  * @port_id: argument to be filled
14790  *
14791  * Return: none
14792  */
wlan_hdd_get_host_driver_port_id(uint32_t * port_id)14793 static void wlan_hdd_get_host_driver_port_id(uint32_t *port_id)
14794 {
14795 	*port_id = WLAM_WLM_HOST_DRIVER_PORT_ID;
14796 }
14797 
14798 #else
14799 static inline void
wlan_hdd_init_multi_client_info_table(struct hdd_adapter * adapter)14800 wlan_hdd_init_multi_client_info_table(struct hdd_adapter *adapter)
14801 {
14802 }
14803 
wlan_hdd_get_host_driver_port_id(uint32_t * port_id)14804 static inline void wlan_hdd_get_host_driver_port_id(uint32_t *port_id)
14805 {
14806 }
14807 #endif
14808 
14809 static void
hdd_adapter_set_wlm_client_latency_level(struct hdd_adapter * adapter)14810 hdd_adapter_set_wlm_client_latency_level(struct hdd_adapter *adapter)
14811 {
14812 	QDF_STATUS status;
14813 	bool reset;
14814 	uint32_t port_id;
14815 	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
14816 
14817 	if (!hdd_ctx)
14818 		return;
14819 
14820 	status = ucfg_mlme_cfg_get_wlm_reset(hdd_ctx->psoc, &reset);
14821 	if (QDF_IS_STATUS_ERROR(status)) {
14822 		hdd_err("could not get the wlm reset flag");
14823 		reset = false;
14824 	}
14825 
14826 	if (reset)
14827 		goto out;
14828 
14829 	if (hdd_get_multi_client_ll_support(adapter)) {
14830 		wlan_hdd_get_host_driver_port_id(&port_id);
14831 		status = wlan_hdd_set_wlm_client_latency_level(
14832 						adapter, port_id,
14833 						adapter->latency_level);
14834 		if (QDF_IS_STATUS_ERROR(status))
14835 			hdd_warn("Fail to set latency level:%u", status);
14836 	} else {
14837 		status = sme_set_wlm_latency_level(hdd_ctx->mac_handle,
14838 						   adapter->deflink->vdev_id,
14839 						   adapter->latency_level,
14840 						   0, false);
14841 		if (QDF_IS_STATUS_ERROR(status))
14842 			hdd_warn("set wlm mode failed, %u", status);
14843 	}
14844 out:
14845 	hdd_debug("wlm initial mode %u", adapter->latency_level);
14846 }
14847 
14848 #ifdef WLAN_HDD_MULTI_VDEV_SINGLE_NDEV
14849 struct qdf_mac_addr *
hdd_adapter_get_link_mac_addr(struct wlan_hdd_link_info * link_info)14850 hdd_adapter_get_link_mac_addr(struct wlan_hdd_link_info *link_info)
14851 {
14852 	struct hdd_adapter *adapter;
14853 
14854 	if (!link_info)
14855 		return NULL;
14856 
14857 	adapter = link_info->adapter;
14858 	if (!hdd_adapter_is_ml_adapter(adapter) ||
14859 	    qdf_is_macaddr_zero(&link_info->link_addr) ||
14860 	    !wlan_vdev_mlme_is_mlo_vdev(link_info->vdev))
14861 		return &adapter->mac_addr;
14862 
14863 	return &link_info->link_addr;
14864 }
14865 #else
14866 struct qdf_mac_addr *
hdd_adapter_get_link_mac_addr(struct wlan_hdd_link_info * link_info)14867 hdd_adapter_get_link_mac_addr(struct wlan_hdd_link_info *link_info)
14868 {
14869 	if (!link_info)
14870 		return NULL;
14871 
14872 	return &link_info->adapter->mac_addr;
14873 }
14874 #endif
14875 
14876 #if defined(WLAN_FEATURE_11BE_MLO) && defined(CFG80211_11BE_BASIC) && \
14877 	defined(WLAN_HDD_MULTI_VDEV_SINGLE_NDEV)
hdd_adapter_check_duplicate_session(struct hdd_adapter * adapter)14878 QDF_STATUS hdd_adapter_check_duplicate_session(struct hdd_adapter *adapter)
14879 {
14880 	int i = 0;
14881 	QDF_STATUS status;
14882 	uint8_t *addr_list[WLAN_MAX_MLD + 2] = {0};
14883 	struct wlan_hdd_link_info *link_info;
14884 
14885 	if (!hdd_adapter_is_ml_adapter(adapter) ||
14886 	    adapter->device_mode == QDF_SAP_MODE)
14887 		goto netdev_addr;
14888 
14889 	hdd_adapter_for_each_active_link_info(adapter, link_info)
14890 		addr_list[i++] = &link_info->link_addr.bytes[0];
14891 
14892 netdev_addr:
14893 	addr_list[i] = &adapter->mac_addr.bytes[0];
14894 	status = sme_check_for_duplicate_session(adapter->hdd_ctx->mac_handle,
14895 						 &addr_list[0]);
14896 	return status;
14897 }
14898 
hdd_adapter_fill_link_address(struct hdd_adapter * adapter)14899 QDF_STATUS hdd_adapter_fill_link_address(struct hdd_adapter *adapter)
14900 {
14901 	int i = 0;
14902 	QDF_STATUS status;
14903 	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
14904 	enum QDF_OPMODE opmode = adapter->device_mode;
14905 	struct qdf_mac_addr link_addrs[WLAN_MAX_ML_BSS_LINKS] = {0};
14906 	struct wlan_hdd_link_info *link_info;
14907 
14908 	if (opmode != QDF_STA_MODE && opmode != QDF_SAP_MODE)
14909 		return QDF_STATUS_SUCCESS;
14910 
14911 	if (opmode == QDF_SAP_MODE) {
14912 		link_info = adapter->deflink;
14913 		qdf_copy_macaddr(&link_info->link_addr, &adapter->mac_addr);
14914 		return QDF_STATUS_SUCCESS;
14915 	}
14916 
14917 	if (!hdd_adapter_is_ml_adapter(adapter))
14918 		return QDF_STATUS_SUCCESS;
14919 
14920 	status = hdd_derive_link_address_from_mld(hdd_ctx->psoc,
14921 						  &adapter->mac_addr,
14922 						  &link_addrs[0],
14923 						  WLAN_MAX_ML_BSS_LINKS);
14924 	if (QDF_IS_STATUS_ERROR(status))
14925 		return status;
14926 
14927 	hdd_adapter_for_each_link_info(adapter, link_info)
14928 		qdf_copy_macaddr(&link_info->link_addr, &link_addrs[i++]);
14929 
14930 	return status;
14931 }
14932 #elif defined(WLAN_FEATURE_11BE_MLO) && defined(CFG80211_11BE_BASIC)
hdd_adapter_check_duplicate_session(struct hdd_adapter * adapter)14933 QDF_STATUS hdd_adapter_check_duplicate_session(struct hdd_adapter *adapter)
14934 {
14935 	int i;
14936 	QDF_STATUS status;
14937 	uint8_t *addr_list[WLAN_MAX_MLD + 1] = {0};
14938 	struct hdd_adapter *link_adapter;
14939 	struct hdd_mlo_adapter_info *mlo_adapter_info;
14940 	mac_handle_t mac_handle = hdd_adapter_get_mac_handle(adapter);
14941 
14942 	if (hdd_adapter_is_ml_adapter(adapter) &&
14943 	    adapter->device_mode == QDF_STA_MODE) {
14944 		addr_list[0] = &adapter->mld_addr.bytes[0];
14945 		mlo_adapter_info = &adapter->mlo_adapter_info;
14946 		for (i = 0; i < WLAN_MAX_MLD; i++) {
14947 			link_adapter = mlo_adapter_info->link_adapter[i];
14948 			if (!link_adapter)
14949 				continue;
14950 			if (hdd_adapter_is_associated_with_ml_adapter(
14951 							link_adapter)) {
14952 				addr_list[1] = &link_adapter->mac_addr.bytes[0];
14953 			}
14954 		}
14955 	} else {
14956 		addr_list[0] = &adapter->mac_addr.bytes[0];
14957 	}
14958 
14959 	status = sme_check_for_duplicate_session(mac_handle, &addr_list[0]);
14960 	return status;
14961 }
14962 #else
hdd_adapter_check_duplicate_session(struct hdd_adapter * adapter)14963 QDF_STATUS hdd_adapter_check_duplicate_session(struct hdd_adapter *adapter)
14964 {
14965 	QDF_STATUS status;
14966 	uint8_t *addr_list[2] = {0};
14967 	mac_handle_t mac_handle = hdd_adapter_get_mac_handle(adapter);
14968 
14969 	addr_list[0] = &adapter->mac_addr.bytes[0];
14970 	status = sme_check_for_duplicate_session(mac_handle, &addr_list[0]);
14971 
14972 	return status;
14973 }
14974 #endif
14975 
hdd_restore_info_for_ssr(struct hdd_adapter * adapter)14976 static void hdd_restore_info_for_ssr(struct hdd_adapter *adapter)
14977 {
14978 	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
14979 
14980 	if (cds_is_driver_recovering()) {
14981 		/* ssr happens, recover the info */
14982 		hdd_set_vdev_phy_mode(adapter, adapter->user_phy_mode);
14983 		wlan_mlme_restore_user_set_link_num(hdd_ctx->psoc);
14984 	} else {
14985 		/* intf down/up happens, reset default info */
14986 		hdd_set_vdev_phy_mode(adapter, QCA_WLAN_VENDOR_PHY_MODE_AUTO);
14987 		wlan_mlme_clear_user_set_link_num(hdd_ctx->psoc);
14988 	}
14989 }
14990 
hdd_adapter_reset_station_ctx(struct hdd_adapter * adapter)14991 void hdd_adapter_reset_station_ctx(struct hdd_adapter *adapter)
14992 {
14993 	struct wlan_hdd_link_info *link_info;
14994 	struct hdd_station_ctx *sta_ctx;
14995 
14996 	hdd_adapter_for_each_link_info(adapter, link_info) {
14997 		sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(link_info);
14998 		qdf_mem_zero(&sta_ctx->conn_info.bssid, QDF_MAC_ADDR_SIZE);
14999 
15000 		hdd_cm_clear_ieee_link_id(link_info);
15001 		sta_ctx->user_cfg_chn_width = CH_WIDTH_INVALID;
15002 	}
15003 }
15004 
hdd_start_station_adapter(struct hdd_adapter * adapter)15005 int hdd_start_station_adapter(struct hdd_adapter *adapter)
15006 {
15007 	QDF_STATUS status;
15008 	int ret;
15009 	struct wlan_hdd_link_info *link_info;
15010 
15011 	hdd_enter_dev(adapter->dev);
15012 	if (test_bit(SME_SESSION_OPENED, &adapter->deflink->link_flags)) {
15013 		hdd_err("session is already opened, %d",
15014 			adapter->deflink->vdev_id);
15015 		return qdf_status_to_os_return(QDF_STATUS_SUCCESS);
15016 	}
15017 
15018 	if ((adapter->device_mode == QDF_P2P_DEVICE_MODE) ||
15019 	    (adapter->device_mode == QDF_NAN_DISC_MODE))
15020 		wlan_hdd_lpc_del_monitor_interface(adapter->hdd_ctx, false);
15021 
15022 	status = hdd_adapter_fill_link_address(adapter);
15023 	if (QDF_IS_STATUS_ERROR(status)) {
15024 		hdd_debug("Link address derive failed");
15025 		return qdf_status_to_os_return(status);
15026 	}
15027 
15028 	status = hdd_adapter_check_duplicate_session(adapter);
15029 	if (QDF_IS_STATUS_ERROR(status)) {
15030 		hdd_err("Duplicate session is existing with same mac address");
15031 		return qdf_status_to_os_return(status);
15032 	}
15033 
15034 	hdd_adapter_for_each_active_link_info(adapter, link_info) {
15035 		ret = hdd_vdev_create(link_info);
15036 		if (ret) {
15037 			hdd_err("failed to create vdev: %d", ret);
15038 			goto fail;
15039 		}
15040 
15041 		status = hdd_init_station_mode(link_info);
15042 		if (QDF_STATUS_SUCCESS != status) {
15043 			hdd_err("Error Initializing station mode: %d", status);
15044 			ret = qdf_status_to_os_return(status);
15045 			goto fail;
15046 		}
15047 	}
15048 
15049 	hdd_adapter_reset_station_ctx(adapter);
15050 
15051 	hdd_register_wext(adapter->dev);
15052 	hdd_set_netdev_flags(adapter);
15053 
15054 	hdd_register_tx_flow_control(adapter,
15055 		hdd_tx_resume_timer_expired_handler,
15056 		hdd_tx_resume_cb,
15057 		hdd_tx_flow_control_is_pause);
15058 
15059 	hdd_register_hl_netdev_fc_timer(adapter,
15060 					hdd_tx_resume_timer_expired_handler);
15061 
15062 	if (hdd_get_multi_client_ll_support(adapter))
15063 		wlan_hdd_init_multi_client_info_table(adapter);
15064 
15065 	hdd_adapter_set_wlm_client_latency_level(adapter);
15066 	hdd_adapter_update_mlo_mgr_mac_addr(adapter);
15067 	hdd_restore_info_for_ssr(adapter);
15068 
15069 	hdd_exit();
15070 	return 0;
15071 
15072 fail:
15073 	hdd_adapter_for_each_active_link_info(adapter, link_info)
15074 		hdd_vdev_destroy(link_info);
15075 
15076 	return ret;
15077 }
15078 
hdd_start_ap_adapter(struct hdd_adapter * adapter,bool rtnl_held)15079 int hdd_start_ap_adapter(struct hdd_adapter *adapter, bool rtnl_held)
15080 {
15081 	QDF_STATUS status;
15082 	bool is_ssr = false;
15083 	int ret;
15084 	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
15085 	struct sap_context *sap_ctx;
15086 	struct wlan_hdd_link_info *link_info = adapter->deflink;
15087 
15088 	hdd_enter();
15089 
15090 	if (test_bit(SME_SESSION_OPENED, &link_info->link_flags)) {
15091 		hdd_err("session is already opened, %d",
15092 			link_info->vdev_id);
15093 		return qdf_status_to_os_return(QDF_STATUS_SUCCESS);
15094 	}
15095 
15096 	status = hdd_adapter_fill_link_address(adapter);
15097 	if (QDF_IS_STATUS_ERROR(status)) {
15098 		hdd_debug("Link address derive failed");
15099 		return qdf_status_to_os_return(status);
15100 	}
15101 
15102 	status = hdd_adapter_check_duplicate_session(adapter);
15103 	if (QDF_IS_STATUS_ERROR(status)) {
15104 		hdd_err("Duplicate session is existing with same mac address");
15105 		return qdf_status_to_os_return(status);
15106 	}
15107 
15108 	/*
15109 	 * In SSR case no need to create new sap context.
15110 	 * Otherwise create sap context first and then create
15111 	 * vdev as while creating the vdev, driver needs to
15112 	 * register SAP callback and that callback uses sap context
15113 	 */
15114 	if (WLAN_HDD_GET_SAP_CTX_PTR(link_info)) {
15115 		is_ssr = true;
15116 	} else if (!hdd_sap_create_ctx(adapter)) {
15117 		hdd_err("sap creation failed");
15118 		return qdf_status_to_os_return(QDF_STATUS_E_FAILURE);
15119 	}
15120 
15121 	ret = hdd_vdev_create(link_info);
15122 	if (ret) {
15123 		hdd_err("failed to create vdev, status:%d", ret);
15124 		goto sap_destroy_ctx;
15125 	}
15126 
15127 	sap_ctx = WLAN_HDD_GET_SAP_CTX_PTR(link_info);
15128 	status = sap_acquire_vdev_ref(hdd_ctx->psoc, sap_ctx,
15129 				      link_info->vdev_id);
15130 	if (!QDF_IS_STATUS_SUCCESS(status)) {
15131 		hdd_err("Failed to get vdev ref for sap for session_id: %u",
15132 			link_info->vdev_id);
15133 		ret = qdf_status_to_os_return(status);
15134 		goto sap_vdev_destroy;
15135 	}
15136 
15137 	if (adapter->device_mode == QDF_SAP_MODE) {
15138 		status = hdd_vdev_configure_rtt_params(sap_ctx->vdev);
15139 		if (QDF_IS_STATUS_ERROR(status))
15140 			goto sap_release_ref;
15141 	}
15142 
15143 	status = hdd_init_ap_mode(adapter, is_ssr, rtnl_held);
15144 	if (QDF_STATUS_SUCCESS != status) {
15145 		hdd_err("Error Initializing the AP mode: %d", status);
15146 		ret = qdf_status_to_os_return(status);
15147 		goto sap_release_ref;
15148 	}
15149 
15150 	hdd_register_tx_flow_control(adapter,
15151 		hdd_softap_tx_resume_timer_expired_handler,
15152 		hdd_softap_tx_resume_cb,
15153 		hdd_tx_flow_control_is_pause);
15154 
15155 	hdd_register_hl_netdev_fc_timer(adapter,
15156 					hdd_tx_resume_timer_expired_handler);
15157 
15158 	if (cds_is_driver_recovering())
15159 		hdd_medium_assess_ssr_reinit();
15160 
15161 	hdd_exit();
15162 	return 0;
15163 
15164 sap_release_ref:
15165 	sap_release_vdev_ref(sap_ctx);
15166 sap_vdev_destroy:
15167 	hdd_vdev_destroy(link_info);
15168 sap_destroy_ctx:
15169 	hdd_sap_destroy_ctx(link_info);
15170 	return ret;
15171 }
15172 
15173 #if defined(QCA_LL_TX_FLOW_CONTROL_V2) || defined(QCA_LL_PDEV_TX_FLOW_CONTROL)
15174 /**
15175  * hdd_txrx_populate_cds_config() - Populate txrx cds configuration
15176  * @cds_cfg: CDS Configuration
15177  * @hdd_ctx: Pointer to hdd context
15178  *
15179  * Return: none
15180  */
hdd_txrx_populate_cds_config(struct cds_config_info * cds_cfg,struct hdd_context * hdd_ctx)15181 static inline void hdd_txrx_populate_cds_config(struct cds_config_info
15182 						*cds_cfg,
15183 						struct hdd_context *hdd_ctx)
15184 {
15185 	cds_cfg->tx_flow_stop_queue_th =
15186 		cfg_get(hdd_ctx->psoc, CFG_DP_TX_FLOW_STOP_QUEUE_TH);
15187 	cds_cfg->tx_flow_start_queue_offset =
15188 		cfg_get(hdd_ctx->psoc, CFG_DP_TX_FLOW_START_QUEUE_OFFSET);
15189 	/* configuration for DP RX Threads */
15190 	cds_cfg->enable_dp_rx_threads =
15191 		ucfg_dp_is_rx_threads_enabled(hdd_ctx->psoc);
15192 }
15193 #else
hdd_txrx_populate_cds_config(struct cds_config_info * cds_cfg,struct hdd_context * hdd_ctx)15194 static inline void hdd_txrx_populate_cds_config(struct cds_config_info
15195 						*cds_cfg,
15196 						struct hdd_context *hdd_ctx)
15197 {
15198 }
15199 #endif
15200 
15201 /**
15202  * hdd_update_cds_config() - API to update cds configuration parameters
15203  * @hdd_ctx: HDD Context
15204  *
15205  * Return: 0 for Success, errno on failure
15206  */
hdd_update_cds_config(struct hdd_context * hdd_ctx)15207 static int hdd_update_cds_config(struct hdd_context *hdd_ctx)
15208 {
15209 	struct cds_config_info *cds_cfg;
15210 	int value;
15211 	uint8_t band_capability;
15212 	uint32_t band_bitmap;
15213 	uint8_t ito_repeat_count;
15214 	bool crash_inject;
15215 	bool self_recovery;
15216 	bool fw_timeout_crash;
15217 	QDF_STATUS status;
15218 
15219 	cds_cfg = qdf_mem_malloc(sizeof(*cds_cfg));
15220 	if (!cds_cfg)
15221 		return -ENOMEM;
15222 
15223 	cds_cfg->driver_type = QDF_DRIVER_TYPE_PRODUCTION;
15224 	ucfg_mlme_get_sap_max_modulated_dtim(hdd_ctx->psoc,
15225 					     &cds_cfg->sta_maxlimod_dtim);
15226 
15227 	ucfg_mlme_get_max_modulated_dtim_ms(hdd_ctx->psoc,
15228 					    &cds_cfg->sta_maxlimod_dtim_ms);
15229 
15230 	status = ucfg_mlme_get_crash_inject(hdd_ctx->psoc, &crash_inject);
15231 	if (QDF_IS_STATUS_ERROR(status)) {
15232 		hdd_err("Failed to get crash inject ini config");
15233 		goto exit;
15234 	}
15235 
15236 	status = ucfg_mlme_get_self_recovery(hdd_ctx->psoc, &self_recovery);
15237 	if (QDF_IS_STATUS_ERROR(status)) {
15238 		hdd_err("Failed to get self recovery ini config");
15239 		goto exit;
15240 	}
15241 
15242 	status = ucfg_mlme_get_fw_timeout_crash(hdd_ctx->psoc,
15243 						&fw_timeout_crash);
15244 	if (QDF_IS_STATUS_ERROR(status)) {
15245 		hdd_err("Failed to get fw timeout crash ini config");
15246 		goto exit;
15247 	}
15248 
15249 	status = ucfg_mlme_get_ito_repeat_count(hdd_ctx->psoc,
15250 						&ito_repeat_count);
15251 	if (QDF_IS_STATUS_ERROR(status)) {
15252 		hdd_err("Failed to get ITO repeat count ini config");
15253 		goto exit;
15254 	}
15255 
15256 	cds_cfg->force_target_assert_enabled = crash_inject;
15257 
15258 	ucfg_mlme_get_sap_max_offload_peers(hdd_ctx->psoc, &value);
15259 	cds_cfg->ap_maxoffload_peers = value;
15260 	ucfg_mlme_get_sap_max_offload_reorder_buffs(hdd_ctx->psoc,
15261 						    &value);
15262 	cds_cfg->ap_maxoffload_reorderbuffs = value;
15263 
15264 	cds_cfg->reorder_offload = DP_REORDER_OFFLOAD_SUPPORT;
15265 
15266 	/* IPA micro controller data path offload resource config item */
15267 	cds_cfg->uc_offload_enabled = ucfg_ipa_uc_is_enabled();
15268 
15269 	cds_cfg->enable_rxthread =
15270 		ucfg_dp_is_rx_common_thread_enabled(hdd_ctx->psoc);
15271 	ucfg_mlme_get_sap_max_peers(hdd_ctx->psoc, &value);
15272 	cds_cfg->max_station = value;
15273 	cds_cfg->sub_20_channel_width = WLAN_SUB_20_CH_WIDTH_NONE;
15274 	cds_cfg->max_msdus_per_rxinorderind =
15275 		cfg_get(hdd_ctx->psoc, CFG_DP_MAX_MSDUS_PER_RXIND);
15276 	cds_cfg->self_recovery_enabled = self_recovery;
15277 	cds_cfg->fw_timeout_crash = fw_timeout_crash;
15278 
15279 	cds_cfg->ito_repeat_count = ito_repeat_count;
15280 
15281 	status = ucfg_mlme_get_band_capability(hdd_ctx->psoc, &band_bitmap);
15282 	if (QDF_IS_STATUS_ERROR(status))
15283 		goto exit;
15284 
15285 	band_capability = wlan_reg_band_bitmap_to_band_info(band_bitmap);
15286 	cds_cfg->bandcapability = band_capability;
15287 	cds_cfg->num_vdevs = hdd_ctx->config->num_vdevs;
15288 	cds_cfg->enable_tx_compl_tsf64 =
15289 		hdd_tsf_is_tsf64_tx_set(hdd_ctx);
15290 	hdd_txrx_populate_cds_config(cds_cfg, hdd_ctx);
15291 	hdd_lpass_populate_cds_config(cds_cfg, hdd_ctx);
15292 	cds_init_ini_config(cds_cfg);
15293 	return 0;
15294 
15295 exit:
15296 	qdf_mem_free(cds_cfg);
15297 	return -EINVAL;
15298 }
15299 
15300 /**
15301  * hdd_update_user_config() - API to update user configuration
15302  * parameters to obj mgr which are used by multiple components
15303  * @hdd_ctx: HDD Context
15304  *
15305  * Return: 0 for Success, errno on failure
15306  */
hdd_update_user_config(struct hdd_context * hdd_ctx)15307 static int hdd_update_user_config(struct hdd_context *hdd_ctx)
15308 {
15309 	struct wlan_objmgr_psoc_user_config *user_config;
15310 	uint8_t band_capability;
15311 	uint32_t band_bitmap;
15312 	QDF_STATUS status;
15313 	bool value = false;
15314 
15315 	status = ucfg_mlme_get_band_capability(hdd_ctx->psoc, &band_bitmap);
15316 	if (QDF_IS_STATUS_ERROR(status))
15317 		return -EIO;
15318 
15319 	user_config = qdf_mem_malloc(sizeof(*user_config));
15320 	if (!user_config)
15321 		return -ENOMEM;
15322 
15323 	user_config->dot11_mode = hdd_ctx->config->dot11Mode;
15324 	status = ucfg_mlme_is_11d_enabled(hdd_ctx->psoc, &value);
15325 	if (!QDF_IS_STATUS_SUCCESS(status))
15326 		hdd_err("Invalid 11d_enable flag");
15327 	user_config->is_11d_support_enabled = value;
15328 
15329 	value = false;
15330 	status = ucfg_mlme_is_11h_enabled(hdd_ctx->psoc, &value);
15331 	if (!QDF_IS_STATUS_SUCCESS(status))
15332 		hdd_err("Invalid 11h_enable flag");
15333 	user_config->is_11h_support_enabled = value;
15334 	band_capability = wlan_reg_band_bitmap_to_band_info(band_bitmap);
15335 	user_config->band_capability = band_capability;
15336 	wlan_objmgr_psoc_set_user_config(hdd_ctx->psoc, user_config);
15337 
15338 	qdf_mem_free(user_config);
15339 	return 0;
15340 }
15341 
15342 /**
15343  * hdd_init_thermal_info - Initialize thermal level
15344  * @hdd_ctx:	HDD context
15345  *
15346  * Initialize thermal level at SME layer and set the thermal level callback
15347  * which would be called when a configured thermal threshold is hit.
15348  *
15349  * Return: 0 on success and errno on failure
15350  */
hdd_init_thermal_info(struct hdd_context * hdd_ctx)15351 static int hdd_init_thermal_info(struct hdd_context *hdd_ctx)
15352 {
15353 	QDF_STATUS status;
15354 	mac_handle_t mac_handle = hdd_ctx->mac_handle;
15355 
15356 	status = sme_init_thermal_info(mac_handle);
15357 
15358 	if (!QDF_IS_STATUS_SUCCESS(status))
15359 		return qdf_status_to_os_return(status);
15360 
15361 	sme_add_set_thermal_level_callback(mac_handle,
15362 					   hdd_set_thermal_level_cb);
15363 
15364 	return 0;
15365 
15366 }
15367 
15368 #if defined(CONFIG_HDD_INIT_WITH_RTNL_LOCK)
15369 /**
15370  * hdd_hold_rtnl_lock - Hold RTNL lock
15371  *
15372  * Hold RTNL lock
15373  *
15374  * Return: True if held and false otherwise
15375  */
hdd_hold_rtnl_lock(void)15376 static inline bool hdd_hold_rtnl_lock(void)
15377 {
15378 	rtnl_lock();
15379 	return true;
15380 }
15381 
15382 /**
15383  * hdd_release_rtnl_lock - Release RTNL lock
15384  *
15385  * Release RTNL lock
15386  *
15387  * Return: None
15388  */
hdd_release_rtnl_lock(void)15389 static inline void hdd_release_rtnl_lock(void)
15390 {
15391 	rtnl_unlock();
15392 }
15393 #else
hdd_hold_rtnl_lock(void)15394 static inline bool hdd_hold_rtnl_lock(void) { return false; }
hdd_release_rtnl_lock(void)15395 static inline void hdd_release_rtnl_lock(void) { }
15396 #endif
15397 
15398 #if !defined(REMOVE_PKT_LOG)
15399 
15400 /* MAX iwpriv command support */
15401 #define PKTLOG_SET_BUFF_SIZE	3
15402 #define PKTLOG_CLEAR_BUFF	4
15403 /* Set Maximum pktlog file size to 64MB */
15404 #define MAX_PKTLOG_SIZE		64
15405 
15406 /**
15407  * hdd_pktlog_set_buff_size() - set pktlog buffer size
15408  * @hdd_ctx: hdd context
15409  * @set_value2: pktlog buffer size value
15410  *
15411  *
15412  * Return: 0 for success or error.
15413  */
hdd_pktlog_set_buff_size(struct hdd_context * hdd_ctx,int set_value2)15414 static int hdd_pktlog_set_buff_size(struct hdd_context *hdd_ctx, int set_value2)
15415 {
15416 	struct sir_wifi_start_log start_log = { 0 };
15417 	QDF_STATUS status;
15418 
15419 	start_log.ring_id = RING_ID_PER_PACKET_STATS;
15420 	start_log.verbose_level = WLAN_LOG_LEVEL_OFF;
15421 	start_log.ini_triggered = cds_is_packet_log_enabled();
15422 	start_log.user_triggered = 1;
15423 	start_log.size = set_value2;
15424 	start_log.is_pktlog_buff_clear = false;
15425 
15426 	status = sme_wifi_start_logger(hdd_ctx->mac_handle, start_log);
15427 	if (!QDF_IS_STATUS_SUCCESS(status)) {
15428 		hdd_err("sme_wifi_start_logger failed(err=%d)", status);
15429 		hdd_exit();
15430 		return -EINVAL;
15431 	}
15432 
15433 	return 0;
15434 }
15435 
15436 /**
15437  * hdd_pktlog_clear_buff() - clear pktlog buffer
15438  * @hdd_ctx: hdd context
15439  *
15440  * Return: 0 for success or error.
15441  */
hdd_pktlog_clear_buff(struct hdd_context * hdd_ctx)15442 static int hdd_pktlog_clear_buff(struct hdd_context *hdd_ctx)
15443 {
15444 	struct sir_wifi_start_log start_log;
15445 	QDF_STATUS status;
15446 
15447 	start_log.ring_id = RING_ID_PER_PACKET_STATS;
15448 	start_log.verbose_level = WLAN_LOG_LEVEL_OFF;
15449 	start_log.ini_triggered = cds_is_packet_log_enabled();
15450 	start_log.user_triggered = 1;
15451 	start_log.size = 0;
15452 	start_log.is_pktlog_buff_clear = true;
15453 
15454 	status = sme_wifi_start_logger(hdd_ctx->mac_handle, start_log);
15455 	if (!QDF_IS_STATUS_SUCCESS(status)) {
15456 		hdd_err("sme_wifi_start_logger failed(err=%d)", status);
15457 		hdd_exit();
15458 		return -EINVAL;
15459 	}
15460 
15461 	return 0;
15462 }
15463 
15464 
15465 /**
15466  * hdd_process_pktlog_command() - process pktlog command
15467  * @hdd_ctx: hdd context
15468  * @set_value: value set by user
15469  * @set_value2: pktlog buffer size value
15470  *
15471  * This function process pktlog command.
15472  * set_value2 only matters when set_value is 3 (set buff size)
15473  * otherwise we ignore it.
15474  *
15475  * Return: 0 for success or error.
15476  */
hdd_process_pktlog_command(struct hdd_context * hdd_ctx,uint32_t set_value,int set_value2)15477 int hdd_process_pktlog_command(struct hdd_context *hdd_ctx, uint32_t set_value,
15478 			       int set_value2)
15479 {
15480 	int ret;
15481 	bool enable;
15482 	uint8_t user_triggered = 0;
15483 
15484 	ret = wlan_hdd_validate_context(hdd_ctx);
15485 	if (0 != ret)
15486 		return ret;
15487 
15488 	hdd_debug("set pktlog %d, set size %d", set_value, set_value2);
15489 
15490 	if (set_value > PKTLOG_CLEAR_BUFF) {
15491 		hdd_err("invalid pktlog value %d", set_value);
15492 		return -EINVAL;
15493 	}
15494 
15495 	if (set_value == PKTLOG_SET_BUFF_SIZE) {
15496 		if (set_value2 <= 0) {
15497 			hdd_err("invalid pktlog size %d", set_value2);
15498 			return -EINVAL;
15499 		} else if (set_value2 > MAX_PKTLOG_SIZE) {
15500 			hdd_err_rl("Pktlog size is large. max value is %uMB.",
15501 				   MAX_PKTLOG_SIZE);
15502 			return -EINVAL;
15503 		}
15504 		return hdd_pktlog_set_buff_size(hdd_ctx, set_value2);
15505 	} else if (set_value == PKTLOG_CLEAR_BUFF) {
15506 		return hdd_pktlog_clear_buff(hdd_ctx);
15507 	}
15508 
15509 	/*
15510 	 * set_value = 0 then disable packetlog
15511 	 * set_value = 1 enable packetlog forcefully
15512 	 * set_value = 2 then disable packetlog if disabled through ini or
15513 	 *                     enable packetlog with AUTO type.
15514 	 */
15515 	enable = ((set_value > 0) && cds_is_packet_log_enabled()) ?
15516 			 true : false;
15517 
15518 	if (1 == set_value) {
15519 		enable = true;
15520 		user_triggered = 1;
15521 	}
15522 
15523 	return hdd_pktlog_enable_disable(hdd_ctx, enable, user_triggered, 0);
15524 }
15525 
15526 /**
15527  * hdd_pktlog_enable_disable() - Enable/Disable packet logging
15528  * @hdd_ctx: HDD context
15529  * @enable_disable_flag: Flag to enable/disable
15530  * @user_triggered: triggered through iwpriv
15531  * @size: buffer size to be used for packetlog
15532  *
15533  * Return: 0 on success; error number otherwise
15534  */
hdd_pktlog_enable_disable(struct hdd_context * hdd_ctx,bool enable_disable_flag,uint8_t user_triggered,int size)15535 int hdd_pktlog_enable_disable(struct hdd_context *hdd_ctx,
15536 			      bool enable_disable_flag,
15537 			      uint8_t user_triggered, int size)
15538 {
15539 	struct sir_wifi_start_log start_log;
15540 	QDF_STATUS status;
15541 
15542 	if (hdd_ctx->is_pktlog_enabled && enable_disable_flag)
15543 		return 0;
15544 
15545 	if ((!hdd_ctx->is_pktlog_enabled) && (!enable_disable_flag))
15546 		return 0;
15547 
15548 	start_log.ring_id = RING_ID_PER_PACKET_STATS;
15549 	start_log.verbose_level =
15550 		enable_disable_flag ?
15551 			WLAN_LOG_LEVEL_ACTIVE : WLAN_LOG_LEVEL_OFF;
15552 	start_log.ini_triggered = cds_is_packet_log_enabled();
15553 	start_log.user_triggered = user_triggered;
15554 	start_log.size = size;
15555 	start_log.is_pktlog_buff_clear = false;
15556 	/*
15557 	 * Use "is_iwpriv_command" flag to distinguish iwpriv command from other
15558 	 * commands. Host uses this flag to decide whether to send pktlog
15559 	 * disable command to fw without sending pktlog enable command
15560 	 * previously. For eg, If vendor sends pktlog disable command without
15561 	 * sending pktlog enable command, then host discards the packet
15562 	 * but for iwpriv command, host will send it to fw.
15563 	 */
15564 	start_log.is_iwpriv_command = 1;
15565 
15566 	status = sme_wifi_start_logger(hdd_ctx->mac_handle, start_log);
15567 	if (!QDF_IS_STATUS_SUCCESS(status)) {
15568 		hdd_err("sme_wifi_start_logger failed(err=%d)", status);
15569 		hdd_exit();
15570 		return -EINVAL;
15571 	}
15572 
15573 	hdd_ctx->is_pktlog_enabled = enable_disable_flag;
15574 
15575 	return 0;
15576 }
15577 #endif /* REMOVE_PKT_LOG */
15578 
hdd_free_mac_address_lists(struct hdd_context * hdd_ctx)15579 void hdd_free_mac_address_lists(struct hdd_context *hdd_ctx)
15580 {
15581 	hdd_debug("Resetting MAC address lists");
15582 	qdf_mem_zero(hdd_ctx->provisioned_mac_addr,
15583 		    sizeof(hdd_ctx->provisioned_mac_addr));
15584 	qdf_mem_zero(hdd_ctx->derived_mac_addr,
15585 		    sizeof(hdd_ctx->derived_mac_addr));
15586 	hdd_ctx->num_provisioned_addr = 0;
15587 	hdd_ctx->num_derived_addr = 0;
15588 	hdd_ctx->provisioned_intf_addr_mask = 0;
15589 	hdd_ctx->derived_intf_addr_mask = 0;
15590 }
15591 
15592 /**
15593  * hdd_get_platform_wlan_mac_buff() - API to query platform driver
15594  *                                    for MAC address
15595  * @dev: Device Pointer
15596  * @num: Number of Valid Mac address
15597  *
15598  * Return: Pointer to MAC address buffer
15599  */
hdd_get_platform_wlan_mac_buff(struct device * dev,uint32_t * num)15600 static uint8_t *hdd_get_platform_wlan_mac_buff(struct device *dev,
15601 					       uint32_t *num)
15602 {
15603 	return pld_get_wlan_mac_address(dev, num);
15604 }
15605 
15606 /**
15607  * hdd_get_platform_wlan_derived_mac_buff() - API to query platform driver
15608  *                                    for derived MAC address
15609  * @dev: Device Pointer
15610  * @num: Number of Valid Mac address
15611  *
15612  * Return: Pointer to MAC address buffer
15613  */
hdd_get_platform_wlan_derived_mac_buff(struct device * dev,uint32_t * num)15614 static uint8_t *hdd_get_platform_wlan_derived_mac_buff(struct device *dev,
15615 						       uint32_t *num)
15616 {
15617 	return pld_get_wlan_derived_mac_address(dev, num);
15618 }
15619 
15620 /**
15621  * hdd_populate_random_mac_addr() - API to populate random mac addresses
15622  * @hdd_ctx: HDD Context
15623  * @num: Number of random mac addresses needed
15624  *
15625  * Generate random addresses using bit manipulation on the base mac address
15626  *
15627  * Return: None
15628  */
hdd_populate_random_mac_addr(struct hdd_context * hdd_ctx,uint32_t num)15629 void hdd_populate_random_mac_addr(struct hdd_context *hdd_ctx, uint32_t num)
15630 {
15631 	uint32_t idx = hdd_ctx->num_derived_addr;
15632 	uint32_t iter;
15633 	uint8_t *buf = NULL;
15634 	uint8_t macaddr_b3, tmp_br3;
15635 	/*
15636 	 * Consider first provisioned mac address as source address to derive
15637 	 * remaining addresses
15638 	 */
15639 
15640 	uint8_t *src = hdd_ctx->provisioned_mac_addr[0].bytes;
15641 
15642 	for (iter = 0; iter < num; ++iter, ++idx) {
15643 		buf = hdd_ctx->derived_mac_addr[idx].bytes;
15644 		qdf_mem_copy(buf, src, QDF_MAC_ADDR_SIZE);
15645 		macaddr_b3 = buf[3];
15646 		tmp_br3 = ((macaddr_b3 >> 4 & INTF_MACADDR_MASK) + idx) &
15647 			INTF_MACADDR_MASK;
15648 		macaddr_b3 += tmp_br3;
15649 		macaddr_b3 ^= (1 << INTF_MACADDR_MASK);
15650 		buf[0] |= 0x02;
15651 		buf[3] = macaddr_b3;
15652 		hdd_debug(QDF_MAC_ADDR_FMT, QDF_MAC_ADDR_REF(buf));
15653 		hdd_ctx->num_derived_addr++;
15654 	}
15655 }
15656 
15657 /**
15658  * hdd_platform_wlan_mac() - API to get mac addresses from platform driver
15659  * @hdd_ctx: HDD Context
15660  *
15661  * API to get mac addresses from platform driver and update the driver
15662  * structures and configure FW with the base mac address.
15663  * Return: int
15664  */
hdd_platform_wlan_mac(struct hdd_context * hdd_ctx)15665 static int hdd_platform_wlan_mac(struct hdd_context *hdd_ctx)
15666 {
15667 	uint32_t no_of_mac_addr, iter;
15668 	uint32_t max_mac_addr = QDF_MAX_CONCURRENCY_PERSONA;
15669 	uint32_t mac_addr_size = QDF_MAC_ADDR_SIZE;
15670 	uint8_t *addr, *buf;
15671 	struct device *dev = hdd_ctx->parent_dev;
15672 	tSirMacAddr mac_addr;
15673 	QDF_STATUS status;
15674 
15675 	addr = hdd_get_platform_wlan_mac_buff(dev, &no_of_mac_addr);
15676 
15677 	if (no_of_mac_addr == 0 || !addr) {
15678 		hdd_debug("No mac configured from platform driver");
15679 		return -EINVAL;
15680 	}
15681 
15682 	hdd_free_mac_address_lists(hdd_ctx);
15683 
15684 	if (no_of_mac_addr > max_mac_addr)
15685 		no_of_mac_addr = max_mac_addr;
15686 
15687 	qdf_mem_copy(&mac_addr, addr, mac_addr_size);
15688 
15689 	for (iter = 0; iter < no_of_mac_addr; ++iter, addr += mac_addr_size) {
15690 		buf = hdd_ctx->provisioned_mac_addr[iter].bytes;
15691 		qdf_mem_copy(buf, addr, QDF_MAC_ADDR_SIZE);
15692 		hdd_info("provisioned MAC Addr [%d] "QDF_MAC_ADDR_FMT, iter,
15693 			 QDF_MAC_ADDR_REF(buf));
15694 	}
15695 
15696 	hdd_ctx->num_provisioned_addr = no_of_mac_addr;
15697 
15698 	if (hdd_ctx->config->mac_provision) {
15699 		addr = hdd_get_platform_wlan_derived_mac_buff(dev,
15700 							      &no_of_mac_addr);
15701 
15702 		if (no_of_mac_addr == 0 || !addr)
15703 			hdd_warn("No derived address from platform driver");
15704 		else if (no_of_mac_addr >
15705 			 (max_mac_addr - hdd_ctx->num_provisioned_addr))
15706 			no_of_mac_addr = (max_mac_addr -
15707 					  hdd_ctx->num_provisioned_addr);
15708 
15709 		for (iter = 0; iter < no_of_mac_addr; ++iter,
15710 		     addr += mac_addr_size) {
15711 			buf = hdd_ctx->derived_mac_addr[iter].bytes;
15712 			qdf_mem_copy(buf, addr, QDF_MAC_ADDR_SIZE);
15713 			hdd_debug("derived MAC Addr [%d] "QDF_MAC_ADDR_FMT, iter,
15714 				  QDF_MAC_ADDR_REF(buf));
15715 		}
15716 		hdd_ctx->num_derived_addr = no_of_mac_addr;
15717 	}
15718 
15719 	no_of_mac_addr = hdd_ctx->num_provisioned_addr +
15720 					 hdd_ctx->num_derived_addr;
15721 	if (no_of_mac_addr < max_mac_addr)
15722 		hdd_populate_random_mac_addr(hdd_ctx, max_mac_addr -
15723 					     no_of_mac_addr);
15724 
15725 	status = sme_set_custom_mac_addr(mac_addr);
15726 	if (!QDF_IS_STATUS_SUCCESS(status))
15727 		return -EAGAIN;
15728 
15729 	return 0;
15730 }
15731 
15732 /**
15733  * hdd_update_mac_addr_to_fw() - API to update wlan mac addresses to FW
15734  * @hdd_ctx: HDD Context
15735  *
15736  * Update MAC address to FW. If MAC address passed by FW is invalid, host
15737  * will generate its own MAC and update it to FW.
15738  *
15739  * Return: 0 for success
15740  *         Non-zero error code for failure
15741  */
hdd_update_mac_addr_to_fw(struct hdd_context * hdd_ctx)15742 static int hdd_update_mac_addr_to_fw(struct hdd_context *hdd_ctx)
15743 {
15744 	tSirMacAddr custom_mac_addr;
15745 	QDF_STATUS status;
15746 
15747 	if (hdd_ctx->num_provisioned_addr)
15748 		qdf_mem_copy(&custom_mac_addr,
15749 			     &hdd_ctx->provisioned_mac_addr[0].bytes[0],
15750 			     sizeof(tSirMacAddr));
15751 	else
15752 		qdf_mem_copy(&custom_mac_addr,
15753 			     &hdd_ctx->derived_mac_addr[0].bytes[0],
15754 			     sizeof(tSirMacAddr));
15755 	status = sme_set_custom_mac_addr(custom_mac_addr);
15756 	if (!QDF_IS_STATUS_SUCCESS(status))
15757 		return -EAGAIN;
15758 	return 0;
15759 }
15760 
15761 /**
15762  * hdd_initialize_mac_address() - API to get wlan mac addresses
15763  * @hdd_ctx: HDD Context
15764  *
15765  * Get MAC addresses from platform driver or wlan_mac.bin. If platform driver
15766  * is provisioned with mac addresses, driver uses it, else it will use
15767  * wlan_mac.bin to update HW MAC addresses.
15768  *
15769  * Return: None
15770  */
hdd_initialize_mac_address(struct hdd_context * hdd_ctx)15771 static int hdd_initialize_mac_address(struct hdd_context *hdd_ctx)
15772 {
15773 	QDF_STATUS status;
15774 	int ret;
15775 
15776 	ret = hdd_platform_wlan_mac(hdd_ctx);
15777 	if (!ret) {
15778 		hdd_info("using MAC address from platform driver");
15779 		return ret;
15780 	} else if (hdd_ctx->config->mac_provision) {
15781 		hdd_err("getting MAC address from platform driver failed");
15782 		return ret;
15783 	}
15784 
15785 	status = hdd_update_mac_config(hdd_ctx);
15786 	if (QDF_IS_STATUS_SUCCESS(status)) {
15787 		hdd_info("using MAC address from wlan_mac.bin");
15788 		return 0;
15789 	}
15790 
15791 	hdd_info("using default MAC address");
15792 
15793 	/* Use fw provided MAC */
15794 	if (!qdf_is_macaddr_zero(&hdd_ctx->hw_macaddr)) {
15795 		hdd_update_macaddr(hdd_ctx, hdd_ctx->hw_macaddr, false);
15796 		return 0;
15797 	} else if (hdd_generate_macaddr_auto(hdd_ctx) != 0) {
15798 		struct qdf_mac_addr mac_addr;
15799 
15800 		hdd_err("MAC failure from device serial no.");
15801 		qdf_get_random_bytes(&mac_addr, sizeof(mac_addr));
15802 		/*
15803 		 * Reset multicast bit (bit-0) and set
15804 		 * locally-administered bit
15805 		 */
15806 		mac_addr.bytes[0] = 0x2;
15807 		hdd_update_macaddr(hdd_ctx, mac_addr, true);
15808 	}
15809 
15810 	ret = hdd_update_mac_addr_to_fw(hdd_ctx);
15811 	if (ret)
15812 		hdd_err("MAC address out-of-sync, ret:%d", ret);
15813 	return ret;
15814 }
15815 
15816 /* params being sent:
15817  * wmi_pdev_param_tx_chain_mask_1ss
15818  * wmi_pdev_param_mgmt_retry_limit
15819  * wmi_pdev_param_default_6ghz_rate
15820  * wmi_pdev_param_pdev_stats_tx_xretry_ext
15821  * wmi_pdev_param_smart_chainmask_scheme
15822  * wmi_pdev_param_alternative_chainmask_scheme
15823  * wmi_pdev_param_ani_enable
15824  * wmi_pdev_param_pcie_config
15825  */
15826 /**
15827  * hdd_pre_enable_configure() - Configurations prior to cds_enable
15828  * @hdd_ctx:	HDD context
15829  *
15830  * Pre configurations to be done at lower layer before calling cds enable.
15831  *
15832  * Return: 0 on success and errno on failure.
15833  */
hdd_pre_enable_configure(struct hdd_context * hdd_ctx)15834 static int hdd_pre_enable_configure(struct hdd_context *hdd_ctx)
15835 {
15836 	int ret;
15837 	uint8_t val = 0;
15838 	uint8_t max_retry = 0;
15839 	bool enable_he_mcs0_for_6ghz_mgmt = false;
15840 	uint32_t tx_retry_multiplier;
15841 	QDF_STATUS status;
15842 	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
15843 	struct dev_set_param setparam[MAX_PDEV_PRE_ENABLE_PARAMS] = {};
15844 	bool check_value;
15845 	uint8_t index = 0;
15846 
15847 	cdp_register_pause_cb(soc, wlan_hdd_txrx_pause_cb);
15848 	hdd_tx_latency_register_cb(soc);
15849 
15850 	/* Register HL netdev flow control callback */
15851 	cdp_hl_fc_register(soc, OL_TXRX_PDEV_ID, wlan_hdd_txrx_pause_cb);
15852 	/* Register rx mic error indication handler */
15853 	ucfg_dp_register_rx_mic_error_ind_handler(soc);
15854 
15855 	/*
15856 	 * Note that the cds_pre_enable() sequence triggers the cfg download.
15857 	 * The cfg download must occur before we update the SME config
15858 	 * since the SME config operation must access the cfg database
15859 	 */
15860 	status = hdd_set_sme_config(hdd_ctx);
15861 
15862 	if (QDF_STATUS_SUCCESS != status) {
15863 		hdd_err("Failed hdd_set_sme_config: %d", status);
15864 		ret = qdf_status_to_os_return(status);
15865 		goto out;
15866 	}
15867 
15868 	status = hdd_set_policy_mgr_user_cfg(hdd_ctx);
15869 	if (QDF_STATUS_SUCCESS != status) {
15870 		hdd_alert("Failed hdd_set_policy_mgr_user_cfg: %d", status);
15871 		ret = qdf_status_to_os_return(status);
15872 		goto out;
15873 	}
15874 
15875 	status = ucfg_mlme_get_tx_chainmask_1ss(hdd_ctx->psoc, &val);
15876 	if (QDF_STATUS_SUCCESS != status) {
15877 		hdd_err("Get tx_chainmask_1ss from mlme failed");
15878 		ret = qdf_status_to_os_return(status);
15879 		goto out;
15880 	}
15881 	ret = mlme_check_index_setparam(setparam,
15882 					wmi_pdev_param_tx_chain_mask_1ss,
15883 					val, index++,
15884 					MAX_PDEV_PRE_ENABLE_PARAMS);
15885 	if (QDF_IS_STATUS_ERROR(ret)) {
15886 		hdd_err("failed at wmi_pdev_param_tx_chain_mask_1ss");
15887 		goto out;
15888 
15889 	}
15890 
15891 	wlan_mlme_get_mgmt_max_retry(hdd_ctx->psoc, &max_retry);
15892 	ret = mlme_check_index_setparam(setparam,
15893 					wmi_pdev_param_mgmt_retry_limit,
15894 					max_retry, index++,
15895 					MAX_PDEV_PRE_ENABLE_PARAMS);
15896 	if (QDF_IS_STATUS_ERROR(ret)) {
15897 		hdd_err("failed at wmi_pdev_param_mgmt_retry_limit");
15898 		goto out;
15899 	}
15900 
15901 	wlan_mlme_get_mgmt_6ghz_rate_support(hdd_ctx->psoc,
15902 					     &enable_he_mcs0_for_6ghz_mgmt);
15903 	if (enable_he_mcs0_for_6ghz_mgmt) {
15904 		hdd_debug("HE rates for 6GHz mgmt frames are supported");
15905 		ret = mlme_check_index_setparam(
15906 					setparam,
15907 					wmi_pdev_param_default_6ghz_rate,
15908 					MGMT_DEFAULT_DATA_RATE_6GHZ, index++,
15909 					MAX_PDEV_PRE_ENABLE_PARAMS);
15910 		if (QDF_IS_STATUS_ERROR(ret)) {
15911 			hdd_err("wmi_pdev_param_default_6ghz_rate failed %d",
15912 				ret);
15913 			goto out;
15914 		}
15915 	}
15916 
15917 	wlan_mlme_get_tx_retry_multiplier(hdd_ctx->psoc,
15918 					  &tx_retry_multiplier);
15919 	ret = mlme_check_index_setparam(setparam,
15920 					wmi_pdev_param_pdev_stats_tx_xretry_ext,
15921 					tx_retry_multiplier, index++,
15922 					MAX_PDEV_PRE_ENABLE_PARAMS);
15923 	if (QDF_IS_STATUS_ERROR(ret)) {
15924 		hdd_err("failed at wmi_pdev_param_pdev_stats_tx_xretry_ext");
15925 		goto out;
15926 	}
15927 
15928 	ret = ucfg_get_smart_chainmask_enabled(hdd_ctx->psoc,
15929 					      &check_value);
15930 	if (QDF_IS_STATUS_SUCCESS(ret)) {
15931 		ret = mlme_check_index_setparam(
15932 					 setparam,
15933 					 wmi_pdev_param_smart_chainmask_scheme,
15934 					 (int)check_value, index++,
15935 					 MAX_PDEV_PRE_ENABLE_PARAMS);
15936 		if (QDF_IS_STATUS_ERROR(ret)) {
15937 			hdd_err("failed to set wmi_pdev_param_smart_chainmask_scheme");
15938 			goto out;
15939 		}
15940 	}
15941 
15942 	ret = ucfg_get_alternative_chainmask_enabled(hdd_ctx->psoc,
15943 						    &check_value);
15944 	if (QDF_IS_STATUS_SUCCESS(ret)) {
15945 		ret = mlme_check_index_setparam(
15946 				setparam,
15947 				wmi_pdev_param_alternative_chainmask_scheme,
15948 				(int)check_value, index++,
15949 				MAX_PDEV_PRE_ENABLE_PARAMS);
15950 		if (QDF_IS_STATUS_ERROR(ret)) {
15951 			hdd_err("failed to set wmi_pdev_param_alternative_chainmask_scheme");
15952 			goto out;
15953 		}
15954 	}
15955 
15956 	ret = ucfg_fwol_get_ani_enabled(hdd_ctx->psoc, &check_value);
15957 	if (QDF_IS_STATUS_SUCCESS(ret)) {
15958 		ret = mlme_check_index_setparam(setparam,
15959 						wmi_pdev_param_ani_enable,
15960 						(int)check_value, index++,
15961 						MAX_PDEV_PRE_ENABLE_PARAMS);
15962 		if (QDF_IS_STATUS_ERROR(ret)) {
15963 			hdd_err("failed to set wmi_pdev_param_ani_enable");
15964 			goto out;
15965 		}
15966 	}
15967 
15968 	ret = hdd_set_pcie_params(hdd_ctx, index, setparam);
15969 	if (QDF_IS_STATUS_ERROR(ret))
15970 		goto out;
15971 	else
15972 		index++;
15973 	ret = sme_send_multi_pdev_vdev_set_params(MLME_PDEV_SETPARAM,
15974 						  WMI_PDEV_ID_SOC, setparam,
15975 						  index);
15976 	if (QDF_IS_STATUS_ERROR(ret)) {
15977 		hdd_err("failed to send pdev set params");
15978 		goto out;
15979 	}
15980 
15981 	/* Configure global firmware params */
15982 	ret = ucfg_fwol_configure_global_params(hdd_ctx->psoc, hdd_ctx->pdev);
15983 	if (ret)
15984 		goto out;
15985 
15986 	status = hdd_set_sme_chan_list(hdd_ctx);
15987 	if (status != QDF_STATUS_SUCCESS) {
15988 		hdd_err("Failed to init channel list: %d", status);
15989 		ret = qdf_status_to_os_return(status);
15990 		goto out;
15991 	}
15992 
15993 	if (!hdd_update_config_cfg(hdd_ctx)) {
15994 		hdd_err("config update failed");
15995 		ret = -EINVAL;
15996 		goto out;
15997 	}
15998 	hdd_init_channel_avoidance(hdd_ctx);
15999 
16000 out:
16001 	return ret;
16002 }
16003 
16004 #ifdef FEATURE_P2P_LISTEN_OFFLOAD
16005 /**
16006  * wlan_hdd_p2p_lo_event_callback - P2P listen offload stop event handler
16007  * @context: context registered with sme_register_p2p_lo_event(). HDD
16008  *   always registers a hdd context pointer
16009  * @evt:event structure pointer
16010  *
16011  * This is the p2p listen offload stop event handler, it sends vendor
16012  * event back to supplicant to notify the stop reason.
16013  *
16014  * Return: None
16015  */
wlan_hdd_p2p_lo_event_callback(void * context,struct sir_p2p_lo_event * evt)16016 static void wlan_hdd_p2p_lo_event_callback(void *context,
16017 					   struct sir_p2p_lo_event *evt)
16018 {
16019 	struct hdd_context *hdd_ctx = context;
16020 	struct sk_buff *vendor_event;
16021 	enum qca_nl80211_vendor_subcmds_index index =
16022 		QCA_NL80211_VENDOR_SUBCMD_P2P_LO_EVENT_INDEX;
16023 	struct wlan_hdd_link_info *link_info;
16024 
16025 	hdd_enter();
16026 
16027 	if (!hdd_ctx) {
16028 		hdd_err("Invalid HDD context pointer");
16029 		return;
16030 	}
16031 
16032 	link_info = hdd_get_link_info_by_vdev(hdd_ctx, evt->vdev_id);
16033 	if (!link_info) {
16034 		hdd_err("Cannot find adapter by vdev_id = %d",
16035 				evt->vdev_id);
16036 		return;
16037 	}
16038 
16039 	vendor_event =
16040 		wlan_cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
16041 						 &link_info->adapter->wdev,
16042 						 sizeof(uint32_t) +
16043 						 NLMSG_HDRLEN,
16044 						 index, GFP_KERNEL);
16045 	if (!vendor_event) {
16046 		hdd_err("wlan_cfg80211_vendor_event_alloc failed");
16047 		return;
16048 	}
16049 
16050 	if (nla_put_u32(vendor_event,
16051 			QCA_WLAN_VENDOR_ATTR_P2P_LISTEN_OFFLOAD_STOP_REASON,
16052 			evt->reason_code)) {
16053 		hdd_err("nla put failed");
16054 		wlan_cfg80211_vendor_free_skb(vendor_event);
16055 		return;
16056 	}
16057 
16058 	wlan_cfg80211_vendor_event(vendor_event, GFP_KERNEL);
16059 	hdd_debug("Sent P2P_LISTEN_OFFLOAD_STOP event for vdev_id = %d",
16060 			evt->vdev_id);
16061 }
16062 #else
wlan_hdd_p2p_lo_event_callback(void * context,struct sir_p2p_lo_event * evt)16063 static void wlan_hdd_p2p_lo_event_callback(void *context,
16064 					   struct sir_p2p_lo_event *evt)
16065 {
16066 }
16067 #endif
16068 
16069 #ifdef FEATURE_WLAN_DYNAMIC_CVM
hdd_set_vc_mode_config(struct hdd_context * hdd_ctx)16070 static inline int hdd_set_vc_mode_config(struct hdd_context *hdd_ctx)
16071 {
16072 	return sme_set_vc_mode_config(hdd_ctx->config->vc_mode_cfg_bitmap);
16073 }
16074 #else
hdd_set_vc_mode_config(struct hdd_context * hdd_ctx)16075 static inline int hdd_set_vc_mode_config(struct hdd_context *hdd_ctx)
16076 {
16077 	return QDF_STATUS_SUCCESS;
16078 }
16079 #endif
16080 
16081 /**
16082  * hdd_adaptive_dwelltime_init() - initialization for adaptive dwell time config
16083  * @hdd_ctx: HDD context
16084  *
16085  * This function sends the adaptive dwell time config configuration to the
16086  * firmware via WMA
16087  *
16088  * Return: 0 - success, < 0 - failure
16089  */
hdd_adaptive_dwelltime_init(struct hdd_context * hdd_ctx)16090 static int hdd_adaptive_dwelltime_init(struct hdd_context *hdd_ctx)
16091 {
16092 	QDF_STATUS status;
16093 	struct adaptive_dwelltime_params dwelltime_params;
16094 
16095 	status = ucfg_fwol_get_all_adaptive_dwelltime_params(hdd_ctx->psoc,
16096 							     &dwelltime_params);
16097 	status = ucfg_fwol_set_adaptive_dwelltime_config(&dwelltime_params);
16098 
16099 	hdd_debug("Sending Adaptive Dwelltime Configuration to fw");
16100 	if (!QDF_IS_STATUS_SUCCESS(status)) {
16101 		hdd_err("Failed to send Adaptive Dwelltime configuration!");
16102 		return -EAGAIN;
16103 	}
16104 	return 0;
16105 }
16106 
hdd_dbs_scan_selection_init(struct hdd_context * hdd_ctx)16107 int hdd_dbs_scan_selection_init(struct hdd_context *hdd_ctx)
16108 {
16109 	QDF_STATUS status;
16110 	struct wmi_dbs_scan_sel_params dbs_scan_params;
16111 	uint32_t i = 0;
16112 	uint8_t count = 0, numentries = 0;
16113 	uint8_t dual_mac_feature;
16114 	uint8_t dbs_scan_config[CDS_DBS_SCAN_PARAM_PER_CLIENT
16115 				* CDS_DBS_SCAN_CLIENTS_MAX];
16116 
16117 	status = ucfg_policy_mgr_get_dual_mac_feature(hdd_ctx->psoc,
16118 						      &dual_mac_feature);
16119 
16120 	if (status != QDF_STATUS_SUCCESS) {
16121 		hdd_err("can't get dual mac feature flag");
16122 		return -EINVAL;
16123 	}
16124 	/* check if DBS is enabled or supported */
16125 	if ((dual_mac_feature == DISABLE_DBS_CXN_AND_SCAN) ||
16126 	    (dual_mac_feature == ENABLE_DBS_CXN_AND_DISABLE_DBS_SCAN))
16127 		return -EINVAL;
16128 
16129 	hdd_string_to_u8_array(hdd_ctx->config->dbs_scan_selection,
16130 			       dbs_scan_config, &numentries,
16131 			       (CDS_DBS_SCAN_PARAM_PER_CLIENT
16132 				* CDS_DBS_SCAN_CLIENTS_MAX));
16133 
16134 	if (!numentries) {
16135 		hdd_debug("Do not send scan_selection_config");
16136 		return 0;
16137 	}
16138 
16139 	/* hdd_set_fw_log_params */
16140 	dbs_scan_params.num_clients = 0;
16141 	while (count < (numentries - 2)) {
16142 		dbs_scan_params.module_id[i] = dbs_scan_config[count];
16143 		dbs_scan_params.num_dbs_scans[i] = dbs_scan_config[count + 1];
16144 		dbs_scan_params.num_non_dbs_scans[i] =
16145 			dbs_scan_config[count + 2];
16146 		dbs_scan_params.num_clients++;
16147 		hdd_debug("module:%d NDS:%d NNDS:%d",
16148 			  dbs_scan_params.module_id[i],
16149 			  dbs_scan_params.num_dbs_scans[i],
16150 			  dbs_scan_params.num_non_dbs_scans[i]);
16151 		count += CDS_DBS_SCAN_PARAM_PER_CLIENT;
16152 		i++;
16153 	}
16154 
16155 	dbs_scan_params.pdev_id = 0;
16156 
16157 	hdd_debug("clients:%d pdev:%d",
16158 		  dbs_scan_params.num_clients, dbs_scan_params.pdev_id);
16159 
16160 	status = sme_set_dbs_scan_selection_config(hdd_ctx->mac_handle,
16161 						   &dbs_scan_params);
16162 	hdd_debug("Sending DBS Scan Selection Configuration to fw");
16163 	if (!QDF_IS_STATUS_SUCCESS(status)) {
16164 		hdd_err("Failed to send DBS Scan selection configuration!");
16165 		return -EAGAIN;
16166 	}
16167 	return 0;
16168 }
16169 
16170 #ifdef FEATURE_WLAN_AUTO_SHUTDOWN
16171 /**
16172  * hdd_set_auto_shutdown_cb() - Set auto shutdown callback
16173  * @hdd_ctx:	HDD context
16174  *
16175  * Set auto shutdown callback to get indications from firmware to indicate
16176  * userspace to shutdown WLAN after a configured amount of inactivity.
16177  *
16178  * Return: 0 on success and errno on failure.
16179  */
hdd_set_auto_shutdown_cb(struct hdd_context * hdd_ctx)16180 static int hdd_set_auto_shutdown_cb(struct hdd_context *hdd_ctx)
16181 {
16182 	QDF_STATUS status;
16183 
16184 	if (!hdd_ctx->config->wlan_auto_shutdown)
16185 		return 0;
16186 
16187 	status = sme_set_auto_shutdown_cb(hdd_ctx->mac_handle,
16188 					  wlan_hdd_auto_shutdown_cb);
16189 	if (status != QDF_STATUS_SUCCESS)
16190 		hdd_err("Auto shutdown feature could not be enabled: %d",
16191 			status);
16192 
16193 	return qdf_status_to_os_return(status);
16194 }
16195 #else
hdd_set_auto_shutdown_cb(struct hdd_context * hdd_ctx)16196 static int hdd_set_auto_shutdown_cb(struct hdd_context *hdd_ctx)
16197 {
16198 	return 0;
16199 }
16200 #endif
16201 
16202 #ifdef MWS_COEX
16203 #define MAX_PDEV_MWSCOEX_PARAMS 4
16204 /* params being sent:
16205  * wmi_pdev_param_mwscoex_4g_allow_quick_ftdm
16206  * wmi_pdev_param_mwscoex_set_5gnr_pwr_limit
16207  * wmi_pdev_param_mwscoex_pcc_chavd_delay
16208  * wmi_pdev_param_mwscoex_scc_chavd_delay
16209  */
16210 
16211 /**
16212  * hdd_init_mws_coex() - Initialize MWS coex configurations
16213  * @hdd_ctx:   HDD context
16214  *
16215  * This function sends MWS-COEX 4G quick FTDM and
16216  * MWS-COEX 5G-NR power limit to FW
16217  *
16218  * Return: 0 on success and errno on failure.
16219  */
hdd_init_mws_coex(struct hdd_context * hdd_ctx)16220 static int hdd_init_mws_coex(struct hdd_context *hdd_ctx)
16221 {
16222 	int ret = 0;
16223 	uint32_t mws_coex_4g_quick_tdm = 0, mws_coex_5g_nr_pwr_limit = 0;
16224 	uint32_t mws_coex_pcc_channel_avoid_delay = 0;
16225 	uint32_t mws_coex_scc_channel_avoid_delay = 0;
16226 	struct dev_set_param setparam[MAX_PDEV_MWSCOEX_PARAMS] = {};
16227 	uint8_t index = 0;
16228 
16229 	ucfg_mlme_get_mws_coex_4g_quick_tdm(hdd_ctx->psoc,
16230 					    &mws_coex_4g_quick_tdm);
16231 	ret = mlme_check_index_setparam(
16232 				setparam,
16233 				wmi_pdev_param_mwscoex_4g_allow_quick_ftdm,
16234 				mws_coex_4g_quick_tdm, index++,
16235 				MAX_PDEV_MWSCOEX_PARAMS);
16236 	if (QDF_IS_STATUS_ERROR(ret)) {
16237 		hdd_err("failed at wmi_pdev_param_mwscoex_4g_allow_quick_ftdm");
16238 		goto error;
16239 	}
16240 
16241 	ucfg_mlme_get_mws_coex_5g_nr_pwr_limit(hdd_ctx->psoc,
16242 					       &mws_coex_5g_nr_pwr_limit);
16243 	ret = mlme_check_index_setparam(
16244 				      setparam,
16245 				      wmi_pdev_param_mwscoex_set_5gnr_pwr_limit,
16246 				      mws_coex_5g_nr_pwr_limit, index++,
16247 				      MAX_PDEV_MWSCOEX_PARAMS);
16248 	if (QDF_IS_STATUS_ERROR(ret)) {
16249 		hdd_err("failed at wmi_pdev_param_mwscoex_set_5gnr_pwr_limit");
16250 		goto error;
16251 	}
16252 
16253 	ucfg_mlme_get_mws_coex_pcc_channel_avoid_delay(
16254 					hdd_ctx->psoc,
16255 					&mws_coex_pcc_channel_avoid_delay);
16256 	ret = mlme_check_index_setparam(setparam,
16257 					wmi_pdev_param_mwscoex_pcc_chavd_delay,
16258 					mws_coex_pcc_channel_avoid_delay,
16259 					index++, MAX_PDEV_MWSCOEX_PARAMS);
16260 	if (QDF_IS_STATUS_ERROR(ret)) {
16261 		hdd_err("failed at wmi_pdev_param_mwscoex_pcc_chavd_delay");
16262 		goto error;
16263 	}
16264 
16265 	ucfg_mlme_get_mws_coex_scc_channel_avoid_delay(
16266 					hdd_ctx->psoc,
16267 					&mws_coex_scc_channel_avoid_delay);
16268 	ret = mlme_check_index_setparam(setparam,
16269 					wmi_pdev_param_mwscoex_scc_chavd_delay,
16270 					mws_coex_scc_channel_avoid_delay,
16271 					index++, MAX_PDEV_MWSCOEX_PARAMS);
16272 	if (QDF_IS_STATUS_ERROR(ret)) {
16273 		hdd_err("failed at wmi_pdev_param_mwscoex_scc_chavd_delay");
16274 		goto error;
16275 	}
16276 	ret = sme_send_multi_pdev_vdev_set_params(MLME_PDEV_SETPARAM,
16277 						  WMI_PDEV_ID_SOC, setparam,
16278 						  index);
16279 	if (QDF_IS_STATUS_ERROR(ret))
16280 		hdd_err("failed to send pdev MWSCOEX set params");
16281 error:
16282 	return ret;
16283 }
16284 #else
hdd_init_mws_coex(struct hdd_context * hdd_ctx)16285 static int hdd_init_mws_coex(struct hdd_context *hdd_ctx)
16286 {
16287 	return 0;
16288 }
16289 #endif
16290 
16291 #ifdef THERMAL_STATS_SUPPORT
hdd_thermal_stats_cmd_init(struct hdd_context * hdd_ctx)16292 static void hdd_thermal_stats_cmd_init(struct hdd_context *hdd_ctx)
16293 {
16294 	hdd_send_get_thermal_stats_cmd(hdd_ctx, thermal_stats_init, NULL, NULL);
16295 }
16296 #else
hdd_thermal_stats_cmd_init(struct hdd_context * hdd_ctx)16297 static void hdd_thermal_stats_cmd_init(struct hdd_context *hdd_ctx)
16298 {
16299 }
16300 #endif
16301 
16302 #ifdef WLAN_FEATURE_CAL_FAILURE_TRIGGER
16303 /**
16304  * hdd_cal_fail_send_event()- send calibration failure information
16305  * @cal_type: calibration type
16306  * @reason: reason for calibration failure
16307  *
16308  * This Function sends calibration failure diag event
16309  *
16310  * Return: void.
16311  */
hdd_cal_fail_send_event(uint8_t cal_type,uint8_t reason)16312 static void hdd_cal_fail_send_event(uint8_t cal_type, uint8_t reason)
16313 {
16314 	/*
16315 	 * For now we are going with the print. Once CST APK has support to
16316 	 * read the diag events then we will add the diag event here.
16317 	 */
16318 	hdd_debug("Received cal failure event with cal_type:%x reason:%x",
16319 		  cal_type, reason);
16320 }
16321 #else
hdd_cal_fail_send_event(uint8_t cal_type,uint8_t reason)16322 static inline void hdd_cal_fail_send_event(uint8_t cal_type, uint8_t reason)
16323 {
16324 }
16325 #endif
16326 
16327 /**
16328  * hdd_features_init() - Init features
16329  * @hdd_ctx:	HDD context
16330  *
16331  * Initialize features and their feature context after WLAN firmware is up.
16332  *
16333  * Return: 0 on success and errno on failure.
16334  */
hdd_features_init(struct hdd_context * hdd_ctx)16335 static int hdd_features_init(struct hdd_context *hdd_ctx)
16336 {
16337 	struct tx_power_limit hddtxlimit;
16338 	QDF_STATUS status;
16339 	int ret;
16340 	mac_handle_t mac_handle;
16341 	bool b_cts2self, is_imps_enabled;
16342 	bool rf_test_mode;
16343 	bool std_6ghz_conn_policy;
16344 	uint32_t fw_data_stall_evt;
16345 	bool disable_vlp_sta_conn_sp_ap;
16346 
16347 	hdd_enter();
16348 
16349 	ret = hdd_init_mws_coex(hdd_ctx);
16350 	if (ret)
16351 		hdd_warn("Error initializing mws-coex");
16352 
16353 	/* FW capabilities received, Set the Dot11 mode */
16354 	mac_handle = hdd_ctx->mac_handle;
16355 	sme_setdef_dot11mode(mac_handle);
16356 
16357 	ucfg_mlme_is_imps_enabled(hdd_ctx->psoc, &is_imps_enabled);
16358 	hdd_set_idle_ps_config(hdd_ctx, is_imps_enabled);
16359 
16360 	fw_data_stall_evt = ucfg_dp_fw_data_stall_evt_enabled();
16361 
16362 	/* Send Enable/Disable data stall detection cmd to FW */
16363 	sme_cli_set_command(0, wmi_pdev_param_data_stall_detect_enable,
16364 			    fw_data_stall_evt, PDEV_CMD);
16365 
16366 	ucfg_mlme_get_go_cts2self_for_sta(hdd_ctx->psoc, &b_cts2self);
16367 	if (b_cts2self)
16368 		sme_set_cts2self_for_p2p_go(mac_handle);
16369 
16370 	if (hdd_set_vc_mode_config(hdd_ctx))
16371 		hdd_warn("Error in setting Voltage Corner mode config to FW");
16372 
16373 	if (ucfg_dp_rx_ol_init(hdd_ctx->psoc, hdd_ctx->is_wifi3_0_target))
16374 		hdd_err("Unable to initialize Rx LRO/GRO in fw");
16375 
16376 	if (hdd_adaptive_dwelltime_init(hdd_ctx))
16377 		hdd_err("Unable to send adaptive dwelltime setting to FW");
16378 
16379 	if (hdd_dbs_scan_selection_init(hdd_ctx))
16380 		hdd_err("Unable to send DBS scan selection setting to FW");
16381 
16382 	ret = hdd_init_thermal_info(hdd_ctx);
16383 	if (ret) {
16384 		hdd_err("Error while initializing thermal information");
16385 		return ret;
16386 	}
16387 
16388 	/**
16389 	 * In case of SSR/PDR, if pktlog was enabled manually before
16390 	 * SSR/PDR, then enable it again automatically after Wlan
16391 	 * device up.
16392 	 * During SSR/PDR, pktlog will be disabled as part of
16393 	 * hdd_features_deinit if pktlog is enabled in ini.
16394 	 * Re-enable pktlog in SSR case, if pktlog is enabled in ini.
16395 	 */
16396 	if (hdd_get_conparam() != QDF_GLOBAL_MONITOR_MODE &&
16397 	    (cds_is_packet_log_enabled() ||
16398 	    (cds_is_driver_recovering() && hdd_ctx->is_pktlog_enabled)))
16399 		hdd_pktlog_enable_disable(hdd_ctx, true, 0, 0);
16400 
16401 	hddtxlimit.txPower2g = ucfg_get_tx_power(hdd_ctx->psoc, BAND_2G);
16402 	hddtxlimit.txPower5g = ucfg_get_tx_power(hdd_ctx->psoc, BAND_5G);
16403 	status = sme_txpower_limit(mac_handle, &hddtxlimit);
16404 	if (!QDF_IS_STATUS_SUCCESS(status))
16405 		hdd_err("Error setting txlimit in sme: %d", status);
16406 
16407 	wlan_hdd_tsf_init(hdd_ctx);
16408 
16409 	status = sme_enable_disable_chanavoidind_event(mac_handle, 0);
16410 	if (QDF_IS_STATUS_ERROR(status) && (status != QDF_STATUS_E_NOSUPPORT)) {
16411 		hdd_err("Failed to disable Chan Avoidance Indication");
16412 		return -EINVAL;
16413 	}
16414 
16415 	/* register P2P Listen Offload event callback */
16416 	if (wma_is_p2p_lo_capable())
16417 		sme_register_p2p_lo_event(mac_handle, hdd_ctx,
16418 					  wlan_hdd_p2p_lo_event_callback);
16419 	wlan_hdd_register_mcc_quota_event_callback(hdd_ctx);
16420 	ret = hdd_set_auto_shutdown_cb(hdd_ctx);
16421 
16422 	if (ret)
16423 		return -EINVAL;
16424 
16425 	wlan_hdd_init_chan_info(hdd_ctx);
16426 	wlan_hdd_twt_init(hdd_ctx);
16427 	wlan_hdd_gpio_wakeup_init(hdd_ctx);
16428 
16429 	status = ucfg_mlme_is_rf_test_mode_enabled(hdd_ctx->psoc,
16430 						   &rf_test_mode);
16431 	if (!QDF_IS_STATUS_SUCCESS(status)) {
16432 		hdd_err("Get rf test mode failed");
16433 		return QDF_STATUS_E_FAILURE;
16434 	}
16435 
16436 	if (rf_test_mode) {
16437 		wlan_cm_set_check_6ghz_security(hdd_ctx->psoc, false);
16438 		wlan_cm_set_6ghz_key_mgmt_mask(hdd_ctx->psoc,
16439 					       DEFAULT_KEYMGMT_6G_MASK);
16440 	}
16441 
16442 	status = ucfg_mlme_is_standard_6ghz_conn_policy_enabled(hdd_ctx->psoc,
16443 							&std_6ghz_conn_policy);
16444 
16445 	if (!QDF_IS_STATUS_SUCCESS(status)) {
16446 		hdd_err("Get 6ghz standard connection policy failed");
16447 		return QDF_STATUS_E_FAILURE;
16448 	}
16449 	if (std_6ghz_conn_policy)
16450 		wlan_cm_set_standard_6ghz_conn_policy(hdd_ctx->psoc, true);
16451 
16452 	status = ucfg_mlme_is_disable_vlp_sta_conn_to_sp_ap_enabled(
16453 						hdd_ctx->psoc,
16454 						&disable_vlp_sta_conn_sp_ap);
16455 	if (!QDF_IS_STATUS_SUCCESS(status)) {
16456 		hdd_err("Get disable vlp sta conn to sp flag failed");
16457 		return QDF_STATUS_E_FAILURE;
16458 	}
16459 
16460 	if (disable_vlp_sta_conn_sp_ap)
16461 		wlan_cm_set_disable_vlp_sta_conn_to_sp_ap(hdd_ctx->psoc, true);
16462 
16463 	hdd_thermal_stats_cmd_init(hdd_ctx);
16464 	sme_set_cal_failure_event_cb(hdd_ctx->mac_handle,
16465 				     hdd_cal_fail_send_event);
16466 
16467 	hdd_exit();
16468 	return 0;
16469 }
16470 
16471 /**
16472  * hdd_register_bcn_cb() - register scan beacon callback
16473  * @hdd_ctx: Pointer to the HDD context
16474  *
16475  * Return: QDF_STATUS
16476  */
hdd_register_bcn_cb(struct hdd_context * hdd_ctx)16477 static inline QDF_STATUS hdd_register_bcn_cb(struct hdd_context *hdd_ctx)
16478 {
16479 	QDF_STATUS status;
16480 
16481 	status = ucfg_scan_register_bcn_cb(hdd_ctx->psoc,
16482 		wlan_cfg80211_inform_bss_frame,
16483 		SCAN_CB_TYPE_INFORM_BCN);
16484 	if (!QDF_IS_STATUS_SUCCESS(status)) {
16485 		hdd_err("failed to register SCAN_CB_TYPE_INFORM_BCN with status code %08d [x%08x]",
16486 			status, status);
16487 		return status;
16488 	}
16489 
16490 	status = ucfg_scan_register_bcn_cb(hdd_ctx->psoc,
16491 		wlan_cfg80211_unlink_bss_list,
16492 		SCAN_CB_TYPE_UNLINK_BSS);
16493 	if (!QDF_IS_STATUS_SUCCESS(status)) {
16494 		hdd_err("failed to refister SCAN_CB_TYPE_FLUSH_BSS with status code %08d [x%08x]",
16495 			status, status);
16496 		return status;
16497 	}
16498 
16499 	return QDF_STATUS_SUCCESS;
16500 }
16501 
16502 /**
16503  * hdd_v2_flow_pool_map() - Flow pool create callback when vdev is active
16504  * @vdev_id: vdev_id, corresponds to flow_pool
16505  *
16506  * Return: none.
16507  */
hdd_v2_flow_pool_map(int vdev_id)16508 static void hdd_v2_flow_pool_map(int vdev_id)
16509 {
16510 	QDF_STATUS status;
16511 	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
16512 	struct wlan_objmgr_vdev *vdev;
16513 
16514 	if (!hdd_ctx) {
16515 		hdd_err("HDD context null");
16516 		return;
16517 	}
16518 
16519 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(hdd_ctx->psoc, vdev_id,
16520 						    WLAN_OSIF_ID);
16521 	if (!vdev) {
16522 		hdd_err("Invalid VDEV %d", vdev_id);
16523 		return;
16524 	}
16525 
16526 	if (wlan_vdev_mlme_is_mlo_link_switch_in_progress(vdev) ||
16527 	    policy_mgr_is_set_link_in_progress(wlan_vdev_get_psoc(vdev))) {
16528 		hdd_info_rl("Link switch/set_link is ongoing, do not invoke flow pool map");
16529 		goto release_ref;
16530 	}
16531 
16532 	status = cdp_flow_pool_map(cds_get_context(QDF_MODULE_ID_SOC),
16533 				   OL_TXRX_PDEV_ID, vdev_id);
16534 	/*
16535 	 * For Adrastea flow control v2 is based on FW MAP events,
16536 	 * so this above callback is not implemented.
16537 	 * Hence this is not actual failure. Dont return failure
16538 	 */
16539 	if ((status != QDF_STATUS_SUCCESS) &&
16540 	    (status != QDF_STATUS_E_INVAL)) {
16541 		hdd_err("vdev_id: %d, failed to create flow pool status %d",
16542 			vdev_id, status);
16543 	}
16544 
16545 release_ref:
16546 	wlan_objmgr_vdev_release_ref(vdev, WLAN_OSIF_ID);
16547 }
16548 
16549 /**
16550  * hdd_v2_flow_pool_unmap() - Flow pool create callback when vdev is not active
16551  * @vdev_id: vdev_id, corresponds to flow_pool
16552  *
16553  * Return: none.
16554  */
hdd_v2_flow_pool_unmap(int vdev_id)16555 static void hdd_v2_flow_pool_unmap(int vdev_id)
16556 {
16557 	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
16558 	struct wlan_objmgr_vdev *vdev;
16559 
16560 	if (!hdd_ctx) {
16561 		hdd_err("HDD context null");
16562 		return;
16563 	}
16564 
16565 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(hdd_ctx->psoc, vdev_id,
16566 						    WLAN_OSIF_ID);
16567 	if (!vdev) {
16568 		hdd_err("Invalid VDEV %d", vdev_id);
16569 		return;
16570 	}
16571 
16572 	if (wlan_vdev_mlme_is_mlo_link_switch_in_progress(vdev)) {
16573 		hdd_info("Link switch ongoing do not invoke flow pool unmap");
16574 		goto release_ref;
16575 	}
16576 
16577 	cdp_flow_pool_unmap(cds_get_context(QDF_MODULE_ID_SOC),
16578 			    OL_TXRX_PDEV_ID, vdev_id);
16579 release_ref:
16580 	wlan_objmgr_vdev_release_ref(vdev, WLAN_OSIF_ID);
16581 }
16582 
hdd_hastings_bt_war_initialize(struct hdd_context * hdd_ctx)16583 static void hdd_hastings_bt_war_initialize(struct hdd_context *hdd_ctx)
16584 {
16585 	if (hdd_ctx->config->iface_change_wait_time)
16586 		hdd_hastings_bt_war_disable_fw(hdd_ctx);
16587 	else
16588 		hdd_hastings_bt_war_enable_fw(hdd_ctx);
16589 }
16590 
16591 #define MAX_PDEV_CFG_CDS_PARAMS 8
16592 /* params being sent:
16593  * wmi_pdev_param_set_iot_pattern
16594  * wmi_pdev_param_max_mpdus_in_ampdu
16595  * wmi_pdev_param_enable_rts_sifs_bursting
16596  * wmi_pdev_param_peer_stats_info_enable
16597  * wmi_pdev_param_abg_mode_tx_chain_num
16598  * wmi_pdev_param_gcmp_support_enable
16599  * wmi_pdev_auto_detect_power_failure
16600  * wmi_pdev_param_fast_pwr_transition
16601  */
16602 
16603 /**
16604  * hdd_configure_cds() - Configure cds modules
16605  * @hdd_ctx:	HDD context
16606  *
16607  * Enable Cds modules after WLAN firmware is up.
16608  *
16609  * Return: 0 on success and errno on failure.
16610  */
hdd_configure_cds(struct hdd_context * hdd_ctx)16611 int hdd_configure_cds(struct hdd_context *hdd_ctx)
16612 {
16613 	int ret;
16614 	QDF_STATUS status;
16615 	int set_value;
16616 	mac_handle_t mac_handle;
16617 	bool enable_rts_sifsbursting;
16618 	uint8_t enable_phy_reg_retention;
16619 	uint8_t max_mpdus_inampdu, is_force_1x1 = 0;
16620 	uint32_t num_abg_tx_chains = 0;
16621 	uint16_t num_11b_tx_chains = 0;
16622 	uint16_t num_11ag_tx_chains = 0;
16623 	struct policy_mgr_dp_cbacks dp_cbs = {0};
16624 	bool value;
16625 	enum pmo_auto_pwr_detect_failure_mode auto_power_fail_mode;
16626 	bool bval = false;
16627 	uint8_t max_index = MAX_PDEV_CFG_CDS_PARAMS;
16628 	struct dev_set_param setparam[MAX_PDEV_CFG_CDS_PARAMS] = {};
16629 	uint8_t index = 0;
16630 	uint8_t next_index = 0;
16631 	mac_handle = hdd_ctx->mac_handle;
16632 
16633 	status = ucfg_policy_mgr_get_force_1x1(hdd_ctx->psoc, &is_force_1x1);
16634 	if (status != QDF_STATUS_SUCCESS) {
16635 		hdd_err("Failed to get force 1x1 value");
16636 		goto out;
16637 	}
16638 	if (is_force_1x1) {
16639 		status = mlme_check_index_setparam(
16640 						setparam,
16641 						wmi_pdev_param_set_iot_pattern,
16642 						1, index++,
16643 						max_index);
16644 		if (QDF_IS_STATUS_ERROR(status)) {
16645 			hdd_err("failed at wmi_pdev_param_set_iot_pattern");
16646 			goto out;
16647 		}
16648 	}
16649 	/* set chip power save failure detected callback */
16650 	sme_set_chip_pwr_save_fail_cb(mac_handle,
16651 				      hdd_chip_pwr_save_fail_detected_cb);
16652 
16653 	status = ucfg_get_max_mpdus_inampdu(hdd_ctx->psoc,
16654 					    &max_mpdus_inampdu);
16655 	if (status) {
16656 		hdd_err("Failed to get max mpdus in ampdu value");
16657 		goto out;
16658 	}
16659 
16660 	if (max_mpdus_inampdu) {
16661 		set_value = max_mpdus_inampdu;
16662 		status = mlme_check_index_setparam(
16663 					      setparam,
16664 					      wmi_pdev_param_max_mpdus_in_ampdu,
16665 					      set_value, index++,
16666 					      max_index);
16667 		if (QDF_IS_STATUS_ERROR(status)) {
16668 			hdd_err("failed at  wmi_pdev_param_max_mpdus_in_ampdu");
16669 			goto out;
16670 		}
16671 	}
16672 
16673 	status = ucfg_get_enable_rts_sifsbursting(hdd_ctx->psoc,
16674 						  &enable_rts_sifsbursting);
16675 	if (status) {
16676 		hdd_err("Failed to get rts sifs bursting value");
16677 		goto out;
16678 	}
16679 
16680 	if (enable_rts_sifsbursting) {
16681 		set_value = enable_rts_sifsbursting;
16682 		status = mlme_check_index_setparam(
16683 					setparam,
16684 					wmi_pdev_param_enable_rts_sifs_bursting,
16685 					set_value, index++,
16686 					max_index);
16687 		if (QDF_IS_STATUS_ERROR(status)) {
16688 			hdd_err("Failed at wmi_pdev_param_enable_rts_sifs_bursting");
16689 			goto out;
16690 		}
16691 	}
16692 
16693 	ucfg_mlme_get_sap_get_peer_info(hdd_ctx->psoc, &value);
16694 	if (value) {
16695 		set_value = value;
16696 		status = mlme_check_index_setparam(
16697 					setparam,
16698 					wmi_pdev_param_peer_stats_info_enable,
16699 					set_value, index++,
16700 					max_index);
16701 		if (QDF_IS_STATUS_ERROR(status)) {
16702 			hdd_err("Failed at wmi_pdev_param_peer_stats_info_enable");
16703 			goto out;
16704 		}
16705 	}
16706 
16707 	status = ucfg_mlme_get_num_11b_tx_chains(hdd_ctx->psoc,
16708 						 &num_11b_tx_chains);
16709 	if (status != QDF_STATUS_SUCCESS) {
16710 		hdd_err("Failed to get num_11b_tx_chains");
16711 		goto out;
16712 	}
16713 
16714 	status = ucfg_mlme_get_num_11ag_tx_chains(hdd_ctx->psoc,
16715 						  &num_11ag_tx_chains);
16716 	if (status != QDF_STATUS_SUCCESS) {
16717 		hdd_err("Failed to get num_11ag_tx_chains");
16718 		goto out;
16719 	}
16720 
16721 	status = ucfg_mlme_get_vht_enable2x2(hdd_ctx->psoc, &bval);
16722 	if (!QDF_IS_STATUS_SUCCESS(status))
16723 		hdd_err("unable to get vht_enable2x2");
16724 
16725 	if (!bval) {
16726 		if (num_11b_tx_chains > 1)
16727 			num_11b_tx_chains = 1;
16728 		if (num_11ag_tx_chains > 1)
16729 			num_11ag_tx_chains = 1;
16730 	}
16731 	WMI_PDEV_PARAM_SET_11B_TX_CHAIN_NUM(num_abg_tx_chains,
16732 					    num_11b_tx_chains);
16733 	WMI_PDEV_PARAM_SET_11AG_TX_CHAIN_NUM(num_abg_tx_chains,
16734 					     num_11ag_tx_chains);
16735 	status = mlme_check_index_setparam(setparam,
16736 					   wmi_pdev_param_abg_mode_tx_chain_num,
16737 					   num_abg_tx_chains, index++,
16738 					   max_index);
16739 	if (QDF_IS_STATUS_ERROR(status)) {
16740 		hdd_err("Failed at wmi_pdev_param_abg_mode_tx_chain_num");
16741 		goto out;
16742 	}
16743 	/* Send some pdev params to maintain legacy order of pdev set params
16744 	 * at hdd_pre_enable_configure
16745 	 */
16746 	status = sme_send_multi_pdev_vdev_set_params(MLME_PDEV_SETPARAM,
16747 						     WMI_PDEV_ID_SOC, setparam,
16748 						     index);
16749 	if (QDF_IS_STATUS_ERROR(status)) {
16750 		hdd_err("Failed to send 1st set of pdev params");
16751 		goto out;
16752 	}
16753 	if (!ucfg_reg_is_regdb_offloaded(hdd_ctx->psoc))
16754 		ucfg_reg_program_default_cc(hdd_ctx->pdev,
16755 					    hdd_ctx->reg.reg_domain);
16756 
16757 	ret = hdd_pre_enable_configure(hdd_ctx);
16758 	if (ret) {
16759 		hdd_err("Failed to pre-configure cds");
16760 		goto out;
16761 	}
16762 
16763 	/* Always get latest IPA resources allocated from cds_open and configure
16764 	 * IPA module before configuring them to FW. Sequence required as crash
16765 	 * observed otherwise.
16766 	 */
16767 
16768 	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
16769 		ipa_disable_register_cb();
16770 	} else {
16771 		status = ipa_register_is_ipa_ready(hdd_ctx->pdev);
16772 		if (!QDF_IS_STATUS_SUCCESS(status)) {
16773 			hdd_err("ipa_register_is_ipa_ready failed");
16774 			goto out;
16775 		}
16776 	}
16777 
16778 	/*
16779 	 * Start CDS which starts up the SME/MAC/HAL modules and everything
16780 	 * else
16781 	 */
16782 	status = cds_enable(hdd_ctx->psoc);
16783 
16784 	if (!QDF_IS_STATUS_SUCCESS(status)) {
16785 		hdd_err("cds_enable failed");
16786 		goto out;
16787 	}
16788 
16789 	status = hdd_post_cds_enable_config(hdd_ctx);
16790 	if (!QDF_IS_STATUS_SUCCESS(status)) {
16791 		hdd_err("hdd_post_cds_enable_config failed");
16792 		goto cds_disable;
16793 	}
16794 	status = hdd_register_bcn_cb(hdd_ctx);
16795 	if (!QDF_IS_STATUS_SUCCESS(status)) {
16796 		hdd_err("hdd_register_bcn_cb failed");
16797 		goto cds_disable;
16798 	}
16799 
16800 	ret = hdd_features_init(hdd_ctx);
16801 	if (ret)
16802 		goto cds_disable;
16803 
16804 	/*
16805 	 * Donot disable rx offload on concurrency for lithium and
16806 	 * beryllium based targets
16807 	 */
16808 	if (!hdd_ctx->is_wifi3_0_target)
16809 		if (ucfg_dp_is_ol_enabled(hdd_ctx->psoc))
16810 			dp_cbs.hdd_disable_rx_ol_in_concurrency =
16811 					hdd_disable_rx_ol_in_concurrency;
16812 	dp_cbs.hdd_set_rx_mode_rps_cb = ucfg_dp_set_rx_mode_rps;
16813 	dp_cbs.hdd_ipa_set_mcc_mode_cb = hdd_ipa_set_mcc_mode;
16814 	dp_cbs.hdd_v2_flow_pool_map = hdd_v2_flow_pool_map;
16815 	dp_cbs.hdd_v2_flow_pool_unmap = hdd_v2_flow_pool_unmap;
16816 	if (ucfg_ipa_set_perf_level_bw_enabled(hdd_ctx->pdev))
16817 		dp_cbs.hdd_ipa_set_perf_level_bw = hdd_ipa_set_perf_level_bw;
16818 	status = policy_mgr_register_dp_cb(hdd_ctx->psoc, &dp_cbs);
16819 	if (!QDF_IS_STATUS_SUCCESS(status)) {
16820 		hdd_debug("Failed to register DP cb with Policy Manager");
16821 		goto cds_disable;
16822 	}
16823 	status = policy_mgr_register_mode_change_cb(hdd_ctx->psoc,
16824 					       wlan_hdd_send_mode_change_event);
16825 	if (!QDF_IS_STATUS_SUCCESS(status)) {
16826 		hdd_debug("Failed to register mode change cb with Policy Manager");
16827 		goto cds_disable;
16828 	}
16829 
16830 	if (hdd_green_ap_enable_egap(hdd_ctx))
16831 		hdd_debug("enhance green ap is not enabled");
16832 
16833 	hdd_register_green_ap_callback(hdd_ctx->pdev);
16834 
16835 	if (0 != wlan_hdd_set_wow_pulse(hdd_ctx, true))
16836 		hdd_debug("Failed to set wow pulse");
16837 
16838 	max_index = max_index - index;
16839 	status = mlme_check_index_setparam(
16840 				      setparam + index,
16841 				      wmi_pdev_param_gcmp_support_enable,
16842 				      ucfg_fwol_get_gcmp_enable(hdd_ctx->psoc),
16843 				      next_index++, max_index);
16844 	if (QDF_IS_STATUS_ERROR(status)) {
16845 		hdd_err("failed at wmi_pdev_param_gcmp_support_enable");
16846 		goto out;
16847 	}
16848 
16849 	 auto_power_fail_mode =
16850 		ucfg_pmo_get_auto_power_fail_mode(hdd_ctx->psoc);
16851 	status = mlme_check_index_setparam(
16852 				      setparam + index,
16853 				      wmi_pdev_auto_detect_power_failure,
16854 				      auto_power_fail_mode,
16855 				      next_index++, max_index);
16856 	if (QDF_IS_STATUS_ERROR(status)) {
16857 		hdd_err("failed at wmi_pdev_auto_detect_power_failure");
16858 		goto out;
16859 	}
16860 
16861 	status = ucfg_get_enable_phy_reg_retention(hdd_ctx->psoc,
16862 						   &enable_phy_reg_retention);
16863 
16864 	if (QDF_IS_STATUS_ERROR(status))
16865 		return -EINVAL;
16866 
16867 	if (enable_phy_reg_retention) {
16868 		status = mlme_check_index_setparam(
16869 					setparam + index,
16870 					wmi_pdev_param_fast_pwr_transition,
16871 					enable_phy_reg_retention,
16872 					next_index++, max_index);
16873 		if (QDF_IS_STATUS_ERROR(status)) {
16874 			hdd_err("failed at wmi_pdev_param_fast_pwr_transition");
16875 			goto out;
16876 		}
16877 	}
16878 	/*Send remaining pdev setparams from array*/
16879 	status = sme_send_multi_pdev_vdev_set_params(MLME_PDEV_SETPARAM,
16880 						     WMI_PDEV_ID_SOC,
16881 						     setparam + index,
16882 						     next_index);
16883 	if (QDF_IS_STATUS_ERROR(status)) {
16884 		hdd_err("failed to send 2nd set of pdev set params");
16885 		goto out;
16886 	}
16887 
16888 	hdd_hastings_bt_war_initialize(hdd_ctx);
16889 
16890 	wlan_hdd_hang_event_notifier_register(hdd_ctx);
16891 	return 0;
16892 
16893 cds_disable:
16894 	cds_disable(hdd_ctx->psoc);
16895 
16896 out:
16897 	return -EINVAL;
16898 }
16899 
16900 #ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
hdd_deregister_policy_manager_callback(struct wlan_objmgr_psoc * psoc)16901 static void hdd_deregister_policy_manager_callback(
16902 			struct wlan_objmgr_psoc *psoc)
16903 {
16904 	if (QDF_STATUS_SUCCESS !=
16905 	    policy_mgr_deregister_hdd_cb(psoc)) {
16906 		hdd_err("HDD callback deregister with policy manager failed");
16907 	}
16908 }
16909 #else
hdd_deregister_policy_manager_callback(struct wlan_objmgr_psoc * psoc)16910 static void hdd_deregister_policy_manager_callback(
16911 			struct wlan_objmgr_psoc *psoc)
16912 {
16913 }
16914 #endif
16915 
hdd_wlan_stop_modules(struct hdd_context * hdd_ctx,bool ftm_mode)16916 int hdd_wlan_stop_modules(struct hdd_context *hdd_ctx, bool ftm_mode)
16917 {
16918 	void *hif_ctx;
16919 	qdf_device_t qdf_ctx;
16920 	QDF_STATUS qdf_status;
16921 	bool is_recovery_stop = cds_is_driver_recovering();
16922 	int ret = 0;
16923 	int debugfs_threads;
16924 	struct target_psoc_info *tgt_hdl;
16925 	struct bbm_params param = {0};
16926 
16927 	hdd_enter();
16928 	qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
16929 	if (!qdf_ctx)
16930 		return -EINVAL;
16931 
16932 	cds_set_driver_state_module_stop(true);
16933 
16934 	debugfs_threads = hdd_return_debugfs_threads_count();
16935 
16936 	if (debugfs_threads > 0 || hdd_ctx->is_wiphy_suspended) {
16937 		hdd_warn("Debugfs threads %d, wiphy suspend %d",
16938 			 debugfs_threads, hdd_ctx->is_wiphy_suspended);
16939 
16940 		if (IS_IDLE_STOP && !ftm_mode) {
16941 			hdd_psoc_idle_timer_start(hdd_ctx);
16942 			cds_set_driver_state_module_stop(false);
16943 
16944 			ucfg_dp_bus_bw_compute_timer_stop(hdd_ctx->psoc);
16945 			return -EAGAIN;
16946 		}
16947 	}
16948 
16949 	ucfg_dp_bus_bw_compute_timer_stop(hdd_ctx->psoc);
16950 	hdd_deregister_policy_manager_callback(hdd_ctx->psoc);
16951 
16952 	/* free user wowl patterns */
16953 	hdd_free_user_wowl_ptrns();
16954 
16955 	switch (hdd_ctx->driver_status) {
16956 	case DRIVER_MODULES_UNINITIALIZED:
16957 		hdd_debug("Modules not initialized just return");
16958 		goto done;
16959 	case DRIVER_MODULES_CLOSED:
16960 		hdd_debug("Modules already closed");
16961 		goto done;
16962 	case DRIVER_MODULES_ENABLED:
16963 		hdd_debug("Wlan transitioning (CLOSED <- ENABLED)");
16964 
16965 		if (hdd_get_conparam() == QDF_GLOBAL_FTM_MODE) {
16966 			hdd_disable_power_management(hdd_ctx);
16967 			break;
16968 		}
16969 
16970 		if (hdd_get_conparam() == QDF_GLOBAL_EPPING_MODE)
16971 			break;
16972 
16973 		hdd_skip_acs_scan_timer_deinit(hdd_ctx);
16974 
16975 		hdd_disable_power_management(hdd_ctx);
16976 
16977 		if (hdd_get_conparam() == QDF_GLOBAL_MISSION_MODE)
16978 			ucfg_dp_direct_link_deinit(hdd_ctx->psoc,
16979 						   is_recovery_stop);
16980 
16981 		if (hdd_deconfigure_cds(hdd_ctx)) {
16982 			hdd_err("Failed to de-configure CDS");
16983 			QDF_ASSERT(0);
16984 			ret = -EINVAL;
16985 		}
16986 		hdd_debug("successfully Disabled the CDS modules!");
16987 
16988 		break;
16989 	default:
16990 		QDF_DEBUG_PANIC("Unknown driver state:%d",
16991 				hdd_ctx->driver_status);
16992 		ret = -EINVAL;
16993 		goto done;
16994 	}
16995 
16996 	hdd_destroy_sysfs_files();
16997 	hdd_debug("Closing CDS modules!");
16998 
16999 	if (hdd_get_conparam() != QDF_GLOBAL_EPPING_MODE) {
17000 		qdf_status = cds_post_disable();
17001 		if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
17002 			hdd_err("Failed to process post CDS disable! :%d",
17003 				qdf_status);
17004 			ret = -EINVAL;
17005 			QDF_ASSERT(0);
17006 		}
17007 
17008 		hdd_unregister_notifiers(hdd_ctx);
17009 		/* De-register the SME callbacks */
17010 		hdd_deregister_cb(hdd_ctx);
17011 
17012 		hdd_runtime_suspend_context_deinit(hdd_ctx);
17013 
17014 		qdf_status = cds_dp_close(hdd_ctx->psoc);
17015 		if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
17016 			hdd_warn("Failed to stop CDS DP: %d", qdf_status);
17017 			ret = -EINVAL;
17018 			QDF_ASSERT(0);
17019 		}
17020 
17021 		hdd_component_pdev_close(hdd_ctx->pdev);
17022 		dispatcher_pdev_close(hdd_ctx->pdev);
17023 		ret = hdd_objmgr_release_and_destroy_pdev(hdd_ctx);
17024 		if (ret) {
17025 			hdd_err("Failed to destroy pdev; errno:%d", ret);
17026 			QDF_ASSERT(0);
17027 		}
17028 
17029 		qdf_status = cds_close(hdd_ctx->psoc);
17030 		if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
17031 			hdd_warn("Failed to stop CDS: %d", qdf_status);
17032 			ret = -EINVAL;
17033 			QDF_ASSERT(0);
17034 		}
17035 
17036 		qdf_status = wbuff_module_deinit();
17037 		if (!QDF_IS_STATUS_SUCCESS(qdf_status))
17038 			hdd_err("WBUFF de-init unsuccessful; status: %d",
17039 				qdf_status);
17040 
17041 		hdd_component_psoc_close(hdd_ctx->psoc);
17042 		/* pdev close and destroy use tx rx ops so call this here */
17043 		wlan_global_lmac_if_close(hdd_ctx->psoc);
17044 	}
17045 
17046 	/*
17047 	 * Reset total mac phy during module stop such that during
17048 	 * next module start same psoc is used to populate new service
17049 	 * ready data
17050 	 */
17051 	tgt_hdl = wlan_psoc_get_tgt_if_handle(hdd_ctx->psoc);
17052 	if (tgt_hdl)
17053 		target_psoc_set_total_mac_phy_cnt(tgt_hdl, 0);
17054 
17055 
17056 	hif_ctx = cds_get_context(QDF_MODULE_ID_HIF);
17057 	if (!hif_ctx)
17058 		ret = -EINVAL;
17059 
17060 	if (hdd_get_conparam() == QDF_GLOBAL_EPPING_MODE) {
17061 		epping_disable();
17062 		epping_close();
17063 	}
17064 
17065 	wlan_connectivity_logging_stop();
17066 
17067 	ucfg_ipa_component_config_free();
17068 
17069 	hdd_hif_close(hdd_ctx, hif_ctx);
17070 
17071 	ol_cds_free();
17072 
17073 	if (IS_IDLE_STOP) {
17074 		ret = pld_power_off(qdf_ctx->dev);
17075 		if (ret)
17076 			hdd_err("Failed to power down device; errno:%d", ret);
17077 	}
17078 
17079 	/* Free the cache channels of the command SET_DISABLE_CHANNEL_LIST */
17080 	wlan_hdd_free_cache_channels(hdd_ctx);
17081 	hdd_driver_mem_cleanup();
17082 
17083 	/* Free the resources allocated while storing SAR config. These needs
17084 	 * to be freed only in the case when it is not SSR. As in the case of
17085 	 * SSR, the values needs to be intact so that it can be restored during
17086 	 * reinit path.
17087 	 */
17088 	if (!is_recovery_stop)
17089 		wlan_hdd_free_sar_config(hdd_ctx);
17090 
17091 	hdd_sap_destroy_ctx_all(hdd_ctx, is_recovery_stop);
17092 	hdd_sta_destroy_ctx_all(hdd_ctx);
17093 
17094 	/*
17095 	 * Reset the driver mode specific bus bw level
17096 	 */
17097 	param.policy = BBM_DRIVER_MODE_POLICY;
17098 	param.policy_info.driver_mode = QDF_GLOBAL_MAX_MODE;
17099 	ucfg_dp_bbm_apply_independent_policy(hdd_ctx->psoc, &param);
17100 
17101 	hdd_deinit_adapter_ops_wq(hdd_ctx);
17102 	hdd_deinit_qdf_ctx(hdd_debug_domain_get());
17103 
17104 	hdd_check_for_leaks(hdd_ctx, is_recovery_stop);
17105 	hdd_debug_domain_set(QDF_DEBUG_DOMAIN_INIT);
17106 	hdd_deinit_qdf_ctx(hdd_debug_domain_get());
17107 	qdf_dma_invalid_buf_list_deinit();
17108 
17109 	/* Restore PS params for monitor mode */
17110 	if (hdd_get_conparam() == QDF_GLOBAL_MONITOR_MODE)
17111 		hdd_restore_all_ps(hdd_ctx);
17112 
17113 	/* Once the firmware sequence is completed reset this flag */
17114 	hdd_ctx->imps_enabled = false;
17115 	hdd_ctx->is_dual_mac_cfg_updated = false;
17116 	hdd_ctx->driver_status = DRIVER_MODULES_CLOSED;
17117 	hdd_ctx->is_fw_dbg_log_levels_configured = false;
17118 	hdd_debug("Wlan transitioned (now CLOSED)");
17119 
17120 done:
17121 	hdd_exit();
17122 
17123 	return ret;
17124 }
17125 
17126 #ifdef WLAN_FEATURE_MEMDUMP_ENABLE
17127 /**
17128  * hdd_state_info_dump() - prints state information of hdd layer
17129  * @buf_ptr: buffer pointer
17130  * @size: size of buffer to be filled
17131  *
17132  * This function is used to dump state information of hdd layer
17133  *
17134  * Return: None
17135  */
hdd_state_info_dump(char ** buf_ptr,uint16_t * size)17136 static void hdd_state_info_dump(char **buf_ptr, uint16_t *size)
17137 {
17138 	struct hdd_context *hdd_ctx;
17139 	struct hdd_station_ctx *sta_ctx;
17140 	struct hdd_adapter *adapter, *next_adapter = NULL;
17141 	uint16_t len = 0;
17142 	char *buf = *buf_ptr;
17143 	wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_STATE_INFO_DUMP;
17144 	struct wlan_hdd_link_info *link_info;
17145 
17146 	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
17147 	if (!hdd_ctx)
17148 		return;
17149 
17150 	hdd_debug("size of buffer: %d", *size);
17151 
17152 	len += scnprintf(buf + len, *size - len, "\n is_wiphy_suspended %d",
17153 			 hdd_ctx->is_wiphy_suspended);
17154 	len += scnprintf(buf + len, *size - len, "\n is_scheduler_suspended %d",
17155 			 hdd_ctx->is_scheduler_suspended);
17156 
17157 	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
17158 					   dbgid) {
17159 		hdd_adapter_for_each_active_link_info(adapter, link_info) {
17160 			len +=
17161 			scnprintf(buf + len, *size - len, "\n device name: %s",
17162 				  adapter->dev->name);
17163 			len +=
17164 			scnprintf(buf + len, *size - len, "\n device_mode: %d",
17165 				  adapter->device_mode);
17166 			switch (adapter->device_mode) {
17167 			case QDF_STA_MODE:
17168 			case QDF_P2P_CLIENT_MODE:
17169 				sta_ctx =
17170 					WLAN_HDD_GET_STATION_CTX_PTR(link_info);
17171 				len += scnprintf(buf + len, *size - len,
17172 					"\n conn_state: %d",
17173 					sta_ctx->conn_info.conn_state);
17174 				break;
17175 			default:
17176 				break;
17177 			}
17178 		}
17179 		hdd_adapter_dev_put_debug(adapter, dbgid);
17180 	}
17181 
17182 	*size -= len;
17183 	*buf_ptr += len;
17184 }
17185 
17186 /**
17187  * hdd_register_debug_callback() - registration function for hdd layer
17188  * to print hdd state information
17189  *
17190  * Return: None
17191  */
hdd_register_debug_callback(void)17192 static void hdd_register_debug_callback(void)
17193 {
17194 	qdf_register_debug_callback(QDF_MODULE_ID_HDD, &hdd_state_info_dump);
17195 }
17196 #else /* WLAN_FEATURE_MEMDUMP_ENABLE */
hdd_register_debug_callback(void)17197 static void hdd_register_debug_callback(void)
17198 {
17199 }
17200 #endif /* WLAN_FEATURE_MEMDUMP_ENABLE */
17201 
17202 /*
17203  * wlan_init_bug_report_lock() - Initialize bug report lock
17204  *
17205  * This function is used to create bug report lock
17206  *
17207  * Return: None
17208  */
wlan_init_bug_report_lock(void)17209 static void wlan_init_bug_report_lock(void)
17210 {
17211 	struct cds_context *p_cds_context;
17212 
17213 	p_cds_context = cds_get_global_context();
17214 	if (!p_cds_context) {
17215 		hdd_err("cds context is NULL");
17216 		return;
17217 	}
17218 
17219 	qdf_spinlock_create(&p_cds_context->bug_report_lock);
17220 }
17221 
17222 #ifdef DISABLE_CHANNEL_LIST
wlan_hdd_cache_chann_mutex_create(struct hdd_context * hdd_ctx)17223 static QDF_STATUS wlan_hdd_cache_chann_mutex_create(struct hdd_context *hdd_ctx)
17224 {
17225 	return qdf_mutex_create(&hdd_ctx->cache_channel_lock);
17226 }
17227 #else
wlan_hdd_cache_chann_mutex_create(struct hdd_context * hdd_ctx)17228 static QDF_STATUS wlan_hdd_cache_chann_mutex_create(struct hdd_context *hdd_ctx)
17229 {
17230 	return QDF_STATUS_SUCCESS;
17231 }
17232 #endif
17233 
hdd_open_adapter_no_trans(struct hdd_context * hdd_ctx,enum QDF_OPMODE op_mode,const char * iface_name,uint8_t * mac_addr_bytes,struct hdd_adapter_create_param * params)17234 QDF_STATUS hdd_open_adapter_no_trans(struct hdd_context *hdd_ctx,
17235 				     enum QDF_OPMODE op_mode,
17236 				     const char *iface_name,
17237 				     uint8_t *mac_addr_bytes,
17238 				     struct hdd_adapter_create_param *params)
17239 {
17240 	struct osif_vdev_sync *vdev_sync;
17241 	struct hdd_adapter *adapter;
17242 	QDF_STATUS status;
17243 	int errno;
17244 
17245 	QDF_BUG(rtnl_is_locked());
17246 
17247 	errno = osif_vdev_sync_create(hdd_ctx->parent_dev, &vdev_sync);
17248 	if (errno)
17249 		return qdf_status_from_os_return(errno);
17250 
17251 	adapter = hdd_open_adapter(hdd_ctx, op_mode, iface_name,
17252 				   mac_addr_bytes, NET_NAME_UNKNOWN, true,
17253 				   params);
17254 	if (!adapter) {
17255 		status = QDF_STATUS_E_INVAL;
17256 		goto destroy_sync;
17257 	}
17258 
17259 	osif_vdev_sync_register(adapter->dev, vdev_sync);
17260 
17261 	return QDF_STATUS_SUCCESS;
17262 
17263 destroy_sync:
17264 	osif_vdev_sync_destroy(vdev_sync);
17265 
17266 	return status;
17267 }
17268 
17269 #ifdef WLAN_OPEN_P2P_INTERFACE
17270 /**
17271  * hdd_open_p2p_interface - Open P2P interface
17272  * @hdd_ctx: HDD context
17273  *
17274  * Return: QDF_STATUS
17275  */
hdd_open_p2p_interface(struct hdd_context * hdd_ctx)17276 static QDF_STATUS hdd_open_p2p_interface(struct hdd_context *hdd_ctx)
17277 {
17278 	QDF_STATUS status;
17279 	bool p2p_dev_addr_admin;
17280 	bool is_p2p_locally_administered = false;
17281 	struct hdd_adapter_create_param params = {0};
17282 
17283 	cfg_p2p_get_device_addr_admin(hdd_ctx->psoc, &p2p_dev_addr_admin);
17284 
17285 	if (p2p_dev_addr_admin) {
17286 		if (hdd_ctx->num_provisioned_addr &&
17287 		    !(hdd_ctx->provisioned_mac_addr[0].bytes[0] & 0x02)) {
17288 			hdd_ctx->p2p_device_address =
17289 					hdd_ctx->provisioned_mac_addr[0];
17290 
17291 			/*
17292 			 * Generate the P2P Device Address.  This consists of
17293 			 * the device's primary MAC address with the locally
17294 			 * administered bit set.
17295 			 */
17296 
17297 			hdd_ctx->p2p_device_address.bytes[0] |= 0x02;
17298 			is_p2p_locally_administered = true;
17299 		} else if (!(hdd_ctx->derived_mac_addr[0].bytes[0] & 0x02)) {
17300 			hdd_ctx->p2p_device_address =
17301 						hdd_ctx->derived_mac_addr[0];
17302 			/*
17303 			 * Generate the P2P Device Address.  This consists of
17304 			 * the device's primary MAC address with the locally
17305 			 * administered bit set.
17306 			 */
17307 			hdd_ctx->p2p_device_address.bytes[0] |= 0x02;
17308 			is_p2p_locally_administered = true;
17309 		}
17310 	}
17311 	if (!is_p2p_locally_administered) {
17312 		uint8_t *p2p_dev_addr;
17313 
17314 		p2p_dev_addr = wlan_hdd_get_intf_addr(hdd_ctx,
17315 						      QDF_P2P_DEVICE_MODE);
17316 		if (!p2p_dev_addr) {
17317 			hdd_err("Failed to get MAC address for new p2p device");
17318 			return QDF_STATUS_E_INVAL;
17319 		}
17320 
17321 		qdf_mem_copy(hdd_ctx->p2p_device_address.bytes,
17322 			     p2p_dev_addr, QDF_MAC_ADDR_SIZE);
17323 	}
17324 
17325 	status = hdd_open_adapter_no_trans(hdd_ctx, QDF_P2P_DEVICE_MODE,
17326 					   "p2p%d",
17327 					   hdd_ctx->p2p_device_address.bytes,
17328 					   &params);
17329 	if (QDF_IS_STATUS_ERROR(status)) {
17330 		if (!is_p2p_locally_administered)
17331 			wlan_hdd_release_intf_addr(hdd_ctx,
17332 					hdd_ctx->p2p_device_address.bytes);
17333 		hdd_err("Failed to open p2p interface");
17334 		return QDF_STATUS_E_INVAL;
17335 	}
17336 
17337 	return QDF_STATUS_SUCCESS;
17338 }
17339 #else
hdd_open_p2p_interface(struct hdd_context * hdd_ctx)17340 static inline QDF_STATUS hdd_open_p2p_interface(struct hdd_context *hdd_ctx)
17341 {
17342 	return QDF_STATUS_SUCCESS;
17343 }
17344 #endif
17345 
hdd_open_ocb_interface(struct hdd_context * hdd_ctx)17346 static QDF_STATUS hdd_open_ocb_interface(struct hdd_context *hdd_ctx)
17347 {
17348 	QDF_STATUS status;
17349 	uint8_t *mac_addr;
17350 	struct hdd_adapter_create_param params = {0};
17351 
17352 	mac_addr = wlan_hdd_get_intf_addr(hdd_ctx, QDF_OCB_MODE);
17353 	if (!mac_addr)
17354 		return QDF_STATUS_E_INVAL;
17355 
17356 	status = hdd_open_adapter_no_trans(hdd_ctx, QDF_OCB_MODE,
17357 					   "wlanocb%d", mac_addr,
17358 					   &params);
17359 	if (QDF_IS_STATUS_ERROR(status)) {
17360 		wlan_hdd_release_intf_addr(hdd_ctx, mac_addr);
17361 		hdd_err("Failed to open 802.11p interface");
17362 	}
17363 
17364 	return status;
17365 }
17366 
hdd_open_concurrent_interface(struct hdd_context * hdd_ctx)17367 static QDF_STATUS hdd_open_concurrent_interface(struct hdd_context *hdd_ctx)
17368 {
17369 	QDF_STATUS status;
17370 	const char *iface_name;
17371 	uint8_t *mac_addr;
17372 	struct hdd_adapter_create_param params = {0};
17373 
17374 	if (qdf_str_eq(hdd_ctx->config->enable_concurrent_sta, ""))
17375 		return QDF_STATUS_SUCCESS;
17376 
17377 	iface_name = hdd_ctx->config->enable_concurrent_sta;
17378 	mac_addr = wlan_hdd_get_intf_addr(hdd_ctx, QDF_STA_MODE);
17379 	if (!mac_addr)
17380 		return QDF_STATUS_E_INVAL;
17381 
17382 	status = hdd_open_adapter_no_trans(hdd_ctx, QDF_STA_MODE,
17383 					   iface_name, mac_addr,
17384 					   &params);
17385 	if (QDF_IS_STATUS_ERROR(status)) {
17386 		wlan_hdd_release_intf_addr(hdd_ctx, mac_addr);
17387 		hdd_err("Failed to open concurrent station interface");
17388 	}
17389 
17390 	return status;
17391 }
17392 
17393 #ifdef WLAN_HDD_MULTI_VDEV_SINGLE_NDEV
17394 static inline void
hdd_adapter_open_set_max_active_links(struct hdd_adapter_create_param * params)17395 hdd_adapter_open_set_max_active_links(struct hdd_adapter_create_param *params)
17396 {
17397 	if (params->is_add_virtual_iface || !params->is_ml_adapter)
17398 		params->num_sessions = 1;
17399 	else
17400 		params->num_sessions = 2;
17401 }
17402 #else
17403 static inline void
hdd_adapter_open_set_max_active_links(struct hdd_adapter_create_param * params)17404 hdd_adapter_open_set_max_active_links(struct hdd_adapter_create_param *params)
17405 {
17406 	params->num_sessions = 1;
17407 }
17408 #endif
17409 
17410 static QDF_STATUS
hdd_open_adapters_for_mission_mode(struct hdd_context * hdd_ctx)17411 hdd_open_adapters_for_mission_mode(struct hdd_context *hdd_ctx)
17412 {
17413 	enum dot11p_mode dot11p_mode;
17414 	QDF_STATUS status;
17415 	uint8_t *mac_addr;
17416 	struct hdd_adapter_create_param params = {0};
17417 	bool eht_capab = 0;
17418 
17419 	ucfg_mlme_get_dot11p_mode(hdd_ctx->psoc, &dot11p_mode);
17420 	ucfg_psoc_mlme_get_11be_capab(hdd_ctx->psoc, &eht_capab);
17421 
17422 	/* Create only 802.11p interface? */
17423 	if (dot11p_mode == CFG_11P_STANDALONE)
17424 		return hdd_open_ocb_interface(hdd_ctx);
17425 
17426 	mac_addr = wlan_hdd_get_intf_addr(hdd_ctx, QDF_STA_MODE);
17427 	if (!mac_addr)
17428 		return QDF_STATUS_E_INVAL;
17429 
17430 	if (eht_capab) {
17431 		params.is_ml_adapter = true;
17432 		hdd_adapter_open_set_max_active_links(&params);
17433 	}
17434 
17435 	status = hdd_open_adapter_no_trans(hdd_ctx, QDF_STA_MODE,
17436 					   "wlan%d", mac_addr,
17437 					   &params);
17438 	if (QDF_IS_STATUS_ERROR(status)) {
17439 		wlan_hdd_release_intf_addr(hdd_ctx, mac_addr);
17440 		return status;
17441 	}
17442 
17443 	/* opening concurrent STA is best effort, continue on error */
17444 	hdd_open_concurrent_interface(hdd_ctx);
17445 
17446 	status = hdd_open_p2p_interface(hdd_ctx);
17447 	if (status)
17448 		goto err_close_adapters;
17449 
17450 	/*
17451 	 * Create separate interface (wifi-aware0) for NAN. All NAN commands
17452 	 * should go on this new interface.
17453 	 */
17454 	if (wlan_hdd_is_vdev_creation_allowed(hdd_ctx->psoc)) {
17455 		qdf_mem_zero(&params, sizeof(params));
17456 		mac_addr = wlan_hdd_get_intf_addr(hdd_ctx, QDF_NAN_DISC_MODE);
17457 		if (!mac_addr)
17458 			goto err_close_adapters;
17459 
17460 		status = hdd_open_adapter_no_trans(hdd_ctx, QDF_NAN_DISC_MODE,
17461 						   "wifi-aware%d", mac_addr,
17462 						   &params);
17463 		if (status) {
17464 			wlan_hdd_release_intf_addr(hdd_ctx, mac_addr);
17465 			goto err_close_adapters;
17466 		}
17467 	}
17468 	/* Open 802.11p Interface */
17469 	if (dot11p_mode == CFG_11P_CONCURRENT) {
17470 		status = hdd_open_ocb_interface(hdd_ctx);
17471 		if (QDF_IS_STATUS_ERROR(status))
17472 			goto err_close_adapters;
17473 	}
17474 
17475 	if (eht_capab)
17476 		hdd_wlan_register_mlo_interfaces(hdd_ctx);
17477 
17478 	return QDF_STATUS_SUCCESS;
17479 
17480 err_close_adapters:
17481 	hdd_close_all_adapters(hdd_ctx, true);
17482 
17483 	return status;
17484 }
17485 
hdd_open_adapters_for_ftm_mode(struct hdd_context * hdd_ctx)17486 static QDF_STATUS hdd_open_adapters_for_ftm_mode(struct hdd_context *hdd_ctx)
17487 {
17488 	QDF_STATUS status;
17489 	uint8_t *mac_addr;
17490 	struct hdd_adapter_create_param params = {0};
17491 
17492 	mac_addr = wlan_hdd_get_intf_addr(hdd_ctx, QDF_FTM_MODE);
17493 	if (!mac_addr)
17494 		return QDF_STATUS_E_INVAL;
17495 
17496 	status = hdd_open_adapter_no_trans(hdd_ctx, QDF_FTM_MODE,
17497 					   "wlan%d", mac_addr,
17498 					   &params);
17499 	if (QDF_IS_STATUS_ERROR(status)) {
17500 		wlan_hdd_release_intf_addr(hdd_ctx, mac_addr);
17501 		return status;
17502 	}
17503 
17504 	return QDF_STATUS_SUCCESS;
17505 }
17506 
17507 static QDF_STATUS
hdd_open_adapters_for_monitor_mode(struct hdd_context * hdd_ctx)17508 hdd_open_adapters_for_monitor_mode(struct hdd_context *hdd_ctx)
17509 {
17510 	QDF_STATUS status;
17511 	uint8_t *mac_addr;
17512 	struct hdd_adapter_create_param params = {0};
17513 
17514 	mac_addr = wlan_hdd_get_intf_addr(hdd_ctx, QDF_MONITOR_MODE);
17515 	if (!mac_addr)
17516 		return QDF_STATUS_E_INVAL;
17517 
17518 	status = hdd_open_adapter_no_trans(hdd_ctx, QDF_MONITOR_MODE,
17519 					   "wlan%d", mac_addr,
17520 					   &params);
17521 	if (QDF_IS_STATUS_ERROR(status)) {
17522 		wlan_hdd_release_intf_addr(hdd_ctx, mac_addr);
17523 		return status;
17524 	}
17525 
17526 	return QDF_STATUS_SUCCESS;
17527 }
17528 
hdd_open_adapters_for_epping_mode(struct hdd_context * hdd_ctx)17529 static QDF_STATUS hdd_open_adapters_for_epping_mode(struct hdd_context *hdd_ctx)
17530 {
17531 	epping_enable_adapter();
17532 	return QDF_STATUS_SUCCESS;
17533 }
17534 
17535 typedef QDF_STATUS (*hdd_open_mode_handler)(struct hdd_context *hdd_ctx);
17536 
17537 static const hdd_open_mode_handler
17538 hdd_open_mode_handlers[QDF_GLOBAL_MAX_MODE] = {
17539 	[QDF_GLOBAL_MISSION_MODE] = hdd_open_adapters_for_mission_mode,
17540 	[QDF_GLOBAL_FTM_MODE] = hdd_open_adapters_for_ftm_mode,
17541 	[QDF_GLOBAL_MONITOR_MODE] = hdd_open_adapters_for_monitor_mode,
17542 	[QDF_GLOBAL_EPPING_MODE] = hdd_open_adapters_for_epping_mode,
17543 };
17544 
hdd_open_adapters_for_mode(struct hdd_context * hdd_ctx,enum QDF_GLOBAL_MODE driver_mode)17545 static QDF_STATUS hdd_open_adapters_for_mode(struct hdd_context *hdd_ctx,
17546 					     enum QDF_GLOBAL_MODE driver_mode)
17547 {
17548 	QDF_STATUS status;
17549 
17550 	if (driver_mode < 0 ||
17551 	    driver_mode >= QDF_GLOBAL_MAX_MODE ||
17552 	    !hdd_open_mode_handlers[driver_mode]) {
17553 		hdd_err("Driver mode %d not supported", driver_mode);
17554 		return -ENOTSUPP;
17555 	}
17556 
17557 	hdd_hold_rtnl_lock();
17558 	status = hdd_open_mode_handlers[driver_mode](hdd_ctx);
17559 	hdd_release_rtnl_lock();
17560 
17561 	return status;
17562 }
17563 
hdd_wlan_startup(struct hdd_context * hdd_ctx)17564 int hdd_wlan_startup(struct hdd_context *hdd_ctx)
17565 {
17566 	QDF_STATUS status;
17567 	int errno;
17568 	bool is_imps_enabled;
17569 
17570 	hdd_enter();
17571 
17572 	qdf_nbuf_init_replenish_timer();
17573 
17574 	status = wlan_hdd_cache_chann_mutex_create(hdd_ctx);
17575 	if (QDF_IS_STATUS_ERROR(status))
17576 		return qdf_status_to_os_return(status);
17577 
17578 #ifdef FEATURE_WLAN_CH_AVOID
17579 	mutex_init(&hdd_ctx->avoid_freq_lock);
17580 #endif
17581 
17582 	osif_request_manager_init();
17583 	hdd_driver_memdump_init();
17584 
17585 	errno = hdd_init_regulatory_update_event(hdd_ctx);
17586 	if (errno) {
17587 		hdd_err("Failed to initialize regulatory update event; errno:%d",
17588 			errno);
17589 		goto memdump_deinit;
17590 	}
17591 
17592 	errno = hdd_wlan_start_modules(hdd_ctx, false);
17593 	if (errno) {
17594 		hdd_err("Failed to start modules; errno:%d", errno);
17595 		goto memdump_deinit;
17596 	}
17597 
17598 	if (hdd_get_conparam() == QDF_GLOBAL_EPPING_MODE)
17599 		return 0;
17600 
17601 	wlan_hdd_update_wiphy(hdd_ctx);
17602 
17603 	hdd_ctx->mac_handle = cds_get_context(QDF_MODULE_ID_SME);
17604 	if (!hdd_ctx->mac_handle)
17605 		goto stop_modules;
17606 
17607 	errno = hdd_wiphy_init(hdd_ctx);
17608 	if (errno) {
17609 		hdd_err("Failed to initialize wiphy; errno:%d", errno);
17610 		goto stop_modules;
17611 	}
17612 
17613 	errno = hdd_initialize_mac_address(hdd_ctx);
17614 	if (errno) {
17615 		hdd_err("MAC initializtion failed: %d", errno);
17616 		goto unregister_wiphy;
17617 	}
17618 
17619 	errno = register_netdevice_notifier(&hdd_netdev_notifier);
17620 	if (errno) {
17621 		hdd_err("register_netdevice_notifier failed; errno:%d", errno);
17622 		goto unregister_wiphy;
17623 	}
17624 
17625 	wlan_hdd_update_11n_mode(hdd_ctx);
17626 
17627 	hdd_lpass_notify_wlan_version(hdd_ctx);
17628 
17629 	status = wlansap_global_init();
17630 	if (QDF_IS_STATUS_ERROR(status))
17631 		goto unregister_notifiers;
17632 
17633 	ucfg_mlme_is_imps_enabled(hdd_ctx->psoc, &is_imps_enabled);
17634 	hdd_set_idle_ps_config(hdd_ctx, is_imps_enabled);
17635 	hdd_debugfs_mws_coex_info_init(hdd_ctx);
17636 	hdd_debugfs_ini_config_init(hdd_ctx);
17637 	wlan_hdd_debugfs_unit_test_host_create(hdd_ctx);
17638 	wlan_hdd_create_mib_stats_lock();
17639 	wlan_cfg80211_init_interop_issues_ap(hdd_ctx->pdev);
17640 
17641 	hdd_exit();
17642 
17643 	return 0;
17644 
17645 unregister_notifiers:
17646 	unregister_netdevice_notifier(&hdd_netdev_notifier);
17647 
17648 unregister_wiphy:
17649 	qdf_dp_trace_deinit();
17650 	wiphy_unregister(hdd_ctx->wiphy);
17651 
17652 stop_modules:
17653 	hdd_wlan_stop_modules(hdd_ctx, false);
17654 
17655 memdump_deinit:
17656 	hdd_driver_memdump_deinit();
17657 	osif_request_manager_deinit();
17658 	qdf_nbuf_deinit_replenish_timer();
17659 
17660 	if (cds_is_fw_down())
17661 		hdd_err("Not setting the complete event as fw is down");
17662 	else
17663 		hdd_start_complete(errno);
17664 
17665 	hdd_exit();
17666 
17667 	return errno;
17668 }
17669 
hdd_psoc_create_vdevs(struct hdd_context * hdd_ctx)17670 QDF_STATUS hdd_psoc_create_vdevs(struct hdd_context *hdd_ctx)
17671 {
17672 	enum QDF_GLOBAL_MODE driver_mode = hdd_get_conparam();
17673 	QDF_STATUS status;
17674 
17675 	status = hdd_open_adapters_for_mode(hdd_ctx, driver_mode);
17676 	if (QDF_IS_STATUS_ERROR(status)) {
17677 		hdd_err("Failed to create vdevs; status:%d", status);
17678 		return status;
17679 	}
17680 
17681 	ucfg_dp_try_set_rps_cpu_mask(hdd_ctx->psoc);
17682 
17683 	if (driver_mode != QDF_GLOBAL_FTM_MODE &&
17684 	    driver_mode != QDF_GLOBAL_EPPING_MODE)
17685 		hdd_psoc_idle_timer_start(hdd_ctx);
17686 
17687 	return QDF_STATUS_SUCCESS;
17688 }
17689 
17690 /**
17691  * hdd_wlan_update_target_info() - update target type info
17692  * @hdd_ctx: HDD context
17693  * @context: hif context
17694  *
17695  * Update target info received from firmware in hdd context
17696  * Return:None
17697  */
17698 
hdd_wlan_update_target_info(struct hdd_context * hdd_ctx,void * context)17699 void hdd_wlan_update_target_info(struct hdd_context *hdd_ctx, void *context)
17700 {
17701 	struct hif_target_info *tgt_info = hif_get_target_info_handle(context);
17702 
17703 	if (!tgt_info) {
17704 		hdd_err("Target info is Null");
17705 		return;
17706 	}
17707 
17708 	hdd_ctx->target_type = tgt_info->target_type;
17709 }
17710 
17711 #ifdef WLAN_FEATURE_MOTION_DETECTION
17712 /**
17713  * hdd_md_host_evt_cb - Callback for Motion Detection Event
17714  * @ctx: HDD context
17715  * @event: motion detect event
17716  *
17717  * Callback for Motion Detection Event. Re-enables Motion
17718  * Detection again upon event
17719  *
17720  * Return: QDF_STATUS QDF_STATUS_SUCCESS on Success and
17721  * QDF_STATUS_E_FAILURE on failure
17722  */
hdd_md_host_evt_cb(void * ctx,struct sir_md_evt * event)17723 QDF_STATUS hdd_md_host_evt_cb(void *ctx, struct sir_md_evt *event)
17724 {
17725 	struct hdd_adapter *adapter;
17726 	struct hdd_context *hdd_ctx;
17727 	struct sme_motion_det_en motion_det;
17728 	struct wlan_hdd_link_info *link_info;
17729 
17730 	if (!ctx || !event)
17731 		return QDF_STATUS_E_INVAL;
17732 
17733 	hdd_ctx = (struct hdd_context *)ctx;
17734 	if (wlan_hdd_validate_context(hdd_ctx))
17735 		return QDF_STATUS_E_INVAL;
17736 
17737 	link_info = hdd_get_link_info_by_vdev(hdd_ctx, event->vdev_id);
17738 	if (!link_info ||
17739 	    WLAN_HDD_ADAPTER_MAGIC != link_info->adapter->magic) {
17740 		hdd_err("Invalid adapter or adapter has invalid magic");
17741 		return QDF_STATUS_E_INVAL;
17742 	}
17743 
17744 	adapter = link_info->adapter;
17745 	/* When motion is detected, reset the motion_det_in_progress flag */
17746 	if (event->status)
17747 		adapter->motion_det_in_progress = false;
17748 
17749 	hdd_debug("Motion Detection CB vdev_id=%u, status=%u",
17750 		  event->vdev_id, event->status);
17751 
17752 	if (adapter->motion_detection_mode) {
17753 		motion_det.vdev_id = event->vdev_id;
17754 		motion_det.enable = 1;
17755 		hdd_debug("Motion Detect CB -> Enable Motion Detection again");
17756 		sme_motion_det_enable(hdd_ctx->mac_handle, &motion_det);
17757 	}
17758 
17759 	return QDF_STATUS_SUCCESS;
17760 }
17761 
17762 /**
17763  * hdd_md_bl_evt_cb - Callback for Motion Detection Baseline Event
17764  * @ctx: HDD context
17765  * @event: motion detect baseline event
17766  *
17767  * Callback for Motion Detection Baseline completion
17768  *
17769  * Return: QDF_STATUS QDF_STATUS_SUCCESS on Success and
17770  * QDF_STATUS_E_FAILURE on failure
17771  */
hdd_md_bl_evt_cb(void * ctx,struct sir_md_bl_evt * event)17772 QDF_STATUS hdd_md_bl_evt_cb(void *ctx, struct sir_md_bl_evt *event)
17773 {
17774 	struct hdd_context *hdd_ctx;
17775 	struct wlan_hdd_link_info *link_info;
17776 
17777 	if (!ctx || !event)
17778 		return QDF_STATUS_E_INVAL;
17779 
17780 	hdd_ctx = (struct hdd_context *)ctx;
17781 	if (wlan_hdd_validate_context(hdd_ctx))
17782 		return QDF_STATUS_E_INVAL;
17783 
17784 	link_info = hdd_get_link_info_by_vdev(hdd_ctx, event->vdev_id);
17785 	if (!link_info ||
17786 	    WLAN_HDD_ADAPTER_MAGIC != link_info->adapter->magic) {
17787 		hdd_err("Invalid adapter or adapter has invalid magic");
17788 		return QDF_STATUS_E_INVAL;
17789 	}
17790 
17791 	hdd_debug("Motion Detection Baseline CB vdev id=%u, baseline val = %d",
17792 		  event->vdev_id, event->bl_baseline_value);
17793 
17794 	link_info->adapter->motion_det_baseline_value =
17795 						event->bl_baseline_value;
17796 
17797 	return QDF_STATUS_SUCCESS;
17798 }
17799 #endif /* WLAN_FEATURE_MOTION_DETECTION */
17800 
hdd_ssr_on_pagefault_cb(struct hdd_context * hdd_ctx)17801 static QDF_STATUS hdd_ssr_on_pagefault_cb(struct hdd_context *hdd_ctx)
17802 {
17803 	uint32_t ssr_frequency_on_pagefault;
17804 	qdf_time_t curr_time, ssr_threshold;
17805 
17806 	hdd_enter();
17807 
17808 	if (!hdd_ctx)
17809 		return QDF_STATUS_E_NULL_VALUE;
17810 
17811 	ssr_frequency_on_pagefault =
17812 		ucfg_pmo_get_ssr_frequency_on_pagefault(hdd_ctx->psoc);
17813 
17814 	curr_time = qdf_get_system_uptime();
17815 	ssr_threshold = qdf_system_msecs_to_ticks(ssr_frequency_on_pagefault);
17816 
17817 	if (!hdd_ctx->last_pagefault_ssr_time ||
17818 	    (curr_time - hdd_ctx->last_pagefault_ssr_time) >= ssr_threshold) {
17819 		hdd_info("curr_time %lu last_pagefault_ssr_time %lu ssr_frequency %lu",
17820 			 curr_time, hdd_ctx->last_pagefault_ssr_time,
17821 			 ssr_threshold);
17822 		hdd_ctx->last_pagefault_ssr_time = curr_time;
17823 		cds_trigger_recovery(QDF_HOST_WAKEUP_REASON_PAGEFAULT);
17824 
17825 		return QDF_STATUS_SUCCESS;
17826 	}
17827 
17828 	return QDF_STATUS_E_AGAIN;
17829 }
17830 
17831 #define FW_PAGE_FAULT_IDX QCA_NL80211_VENDOR_SUBCMD_FW_PAGE_FAULT_REPORT_INDEX
hdd_send_pagefault_report_to_user(struct hdd_context * hdd_ctx,void * buf,uint32_t buf_len)17832 static QDF_STATUS hdd_send_pagefault_report_to_user(struct hdd_context *hdd_ctx,
17833 						    void *buf, uint32_t buf_len)
17834 {
17835 	struct sk_buff *event_buf;
17836 	int flags = cds_get_gfp_flags();
17837 	uint8_t *ev_data = buf;
17838 	uint16_t event_len = NLMSG_HDRLEN + buf_len;
17839 
17840 	event_buf = wlan_cfg80211_vendor_event_alloc(hdd_ctx->wiphy, NULL,
17841 						     event_len,
17842 						     FW_PAGE_FAULT_IDX, flags);
17843 	if (!event_buf) {
17844 		hdd_err("wlan_cfg80211_vendor_event_alloc failed");
17845 		return QDF_STATUS_E_NOMEM;
17846 	}
17847 
17848 	if (nla_put(event_buf, QCA_WLAN_VENDOR_ATTR_FW_PAGE_FAULT_REPORT_DATA,
17849 		    buf_len, ev_data)) {
17850 		hdd_debug("Failed to fill pagefault blob data");
17851 		wlan_cfg80211_vendor_free_skb(event_buf);
17852 		return QDF_STATUS_E_FAILURE;
17853 	}
17854 
17855 	wlan_cfg80211_vendor_event(event_buf, flags);
17856 	return QDF_STATUS_SUCCESS;
17857 }
17858 
hdd_pagefault_action_cb(void * buf,uint32_t buf_len)17859 static QDF_STATUS hdd_pagefault_action_cb(void *buf, uint32_t buf_len)
17860 {
17861 	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
17862 
17863 	if (!hdd_ctx)
17864 		return QDF_STATUS_E_NULL_VALUE;
17865 
17866 	if (wlan_pmo_enable_ssr_on_page_fault(hdd_ctx->psoc))
17867 		return hdd_ssr_on_pagefault_cb(hdd_ctx);
17868 
17869 	return hdd_send_pagefault_report_to_user(hdd_ctx, buf, buf_len);
17870 }
17871 
17872 /**
17873  * hdd_register_cb - Register HDD callbacks.
17874  * @hdd_ctx: HDD context
17875  *
17876  * Register the HDD callbacks to CDS/SME.
17877  *
17878  * Return: 0 for success or Error code for failure
17879  */
hdd_register_cb(struct hdd_context * hdd_ctx)17880 int hdd_register_cb(struct hdd_context *hdd_ctx)
17881 {
17882 	QDF_STATUS status;
17883 	int ret = 0;
17884 	mac_handle_t mac_handle;
17885 
17886 	hdd_enter();
17887 	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
17888 		hdd_err("in ftm mode, no need to register callbacks");
17889 		return ret;
17890 	}
17891 
17892 	mac_handle = hdd_ctx->mac_handle;
17893 
17894 	sme_register_oem_data_rsp_callback(mac_handle,
17895 					   hdd_send_oem_data_rsp_msg);
17896 
17897 	sme_register_mgmt_frame_ind_callback(mac_handle,
17898 					     hdd_indicate_mgmt_frame);
17899 	sme_set_tsfcb(mac_handle, hdd_get_tsf_cb, hdd_ctx);
17900 	sme_stats_ext_register_callback(mac_handle,
17901 					wlan_hdd_cfg80211_stats_ext_callback);
17902 
17903 	sme_ext_scan_register_callback(mac_handle,
17904 					wlan_hdd_cfg80211_extscan_callback);
17905 	sme_stats_ext2_register_callback(mac_handle,
17906 					wlan_hdd_cfg80211_stats_ext2_callback);
17907 
17908 	sme_multi_client_ll_rsp_register_callback(mac_handle,
17909 					hdd_latency_level_event_handler_cb);
17910 
17911 	sme_set_rssi_threshold_breached_cb(mac_handle,
17912 					   hdd_rssi_threshold_breached);
17913 
17914 	sme_set_link_layer_stats_ind_cb(mac_handle,
17915 				wlan_hdd_cfg80211_link_layer_stats_callback);
17916 
17917 	sme_rso_cmd_status_cb(mac_handle, wlan_hdd_rso_cmd_status_cb);
17918 
17919 	sme_set_link_layer_ext_cb(mac_handle,
17920 			wlan_hdd_cfg80211_link_layer_stats_ext_callback);
17921 	sme_update_hidden_ssid_status_cb(mac_handle,
17922 					 hdd_hidden_ssid_enable_roaming);
17923 
17924 	status = sme_set_lost_link_info_cb(mac_handle,
17925 					   hdd_lost_link_info_cb);
17926 
17927 	wlan_hdd_register_cp_stats_cb(hdd_ctx);
17928 	hdd_dcs_register_cb(hdd_ctx);
17929 
17930 	hdd_thermal_register_callbacks(hdd_ctx);
17931 	/* print error and not block the startup process */
17932 	if (!QDF_IS_STATUS_SUCCESS(status))
17933 		hdd_err("set lost link info callback failed");
17934 
17935 	ret = hdd_register_data_stall_detect_cb();
17936 	if (ret) {
17937 		hdd_err("Register data stall detect detect callback failed.");
17938 		return ret;
17939 	}
17940 
17941 	wlan_hdd_dcc_register_for_dcc_stats_event(hdd_ctx);
17942 
17943 	sme_register_set_connection_info_cb(mac_handle,
17944 					    hdd_set_connection_in_progress,
17945 					    hdd_is_connection_in_progress);
17946 
17947 	status = sme_set_bt_activity_info_cb(mac_handle,
17948 					     hdd_bt_activity_cb);
17949 	if (!QDF_IS_STATUS_SUCCESS(status))
17950 		hdd_err("set bt activity info callback failed");
17951 
17952 	status = sme_register_tx_queue_cb(mac_handle,
17953 					  hdd_tx_queue_cb);
17954 	if (!QDF_IS_STATUS_SUCCESS(status))
17955 		hdd_err("Register tx queue callback failed");
17956 
17957 #ifdef WLAN_FEATURE_MOTION_DETECTION
17958 	sme_set_md_host_evt_cb(mac_handle, hdd_md_host_evt_cb, (void *)hdd_ctx);
17959 	sme_set_md_bl_evt_cb(mac_handle, hdd_md_bl_evt_cb, (void *)hdd_ctx);
17960 #endif /* WLAN_FEATURE_MOTION_DETECTION */
17961 
17962 	mac_register_session_open_close_cb(hdd_ctx->mac_handle,
17963 					   hdd_sme_close_session_callback,
17964 					   hdd_common_roam_callback);
17965 
17966 	sme_set_roam_scan_ch_event_cb(mac_handle, hdd_get_roam_scan_ch_cb);
17967 	status = sme_set_monitor_mode_cb(mac_handle,
17968 					 hdd_sme_monitor_mode_callback);
17969 	if (QDF_IS_STATUS_ERROR(status))
17970 		hdd_err_rl("Register monitor mode callback failed");
17971 
17972 	status = sme_set_beacon_latency_event_cb(mac_handle,
17973 						 hdd_beacon_latency_event_cb);
17974 	if (QDF_IS_STATUS_ERROR(status))
17975 		hdd_err_rl("Register beacon latency event callback failed");
17976 
17977 	sme_async_oem_event_init(mac_handle,
17978 				 hdd_oem_event_async_cb);
17979 
17980 	sme_register_pagefault_cb(mac_handle, hdd_pagefault_action_cb);
17981 
17982 	hdd_exit();
17983 
17984 	return ret;
17985 }
17986 
17987 /**
17988  * hdd_deregister_cb() - De-Register HDD callbacks.
17989  * @hdd_ctx: HDD context
17990  *
17991  * De-Register the HDD callbacks to CDS/SME.
17992  *
17993  * Return: void
17994  */
hdd_deregister_cb(struct hdd_context * hdd_ctx)17995 void hdd_deregister_cb(struct hdd_context *hdd_ctx)
17996 {
17997 	QDF_STATUS status;
17998 	int ret;
17999 	mac_handle_t mac_handle;
18000 
18001 	hdd_enter();
18002 	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
18003 		hdd_err("in ftm mode, no need to deregister callbacks");
18004 		return;
18005 	}
18006 
18007 	mac_handle = hdd_ctx->mac_handle;
18008 
18009 	sme_deregister_ssr_on_pagefault_cb(mac_handle);
18010 
18011 	sme_async_oem_event_deinit(mac_handle);
18012 
18013 	sme_deregister_tx_queue_cb(mac_handle);
18014 
18015 	sme_reset_link_layer_stats_ind_cb(mac_handle);
18016 	sme_reset_rssi_threshold_breached_cb(mac_handle);
18017 
18018 	sme_stats_ext_deregister_callback(mac_handle);
18019 
18020 	status = sme_reset_tsfcb(mac_handle);
18021 	if (!QDF_IS_STATUS_SUCCESS(status))
18022 		hdd_err("Failed to de-register tsfcb the callback:%d",
18023 			status);
18024 
18025 	ret = hdd_deregister_data_stall_detect_cb();
18026 	if (ret)
18027 		hdd_err("Failed to de-register data stall detect event callback");
18028 	hdd_thermal_unregister_callbacks(hdd_ctx);
18029 	sme_deregister_oem_data_rsp_callback(mac_handle);
18030 	sme_multi_client_ll_rsp_deregister_callback(mac_handle);
18031 
18032 	hdd_exit();
18033 }
18034 
18035 /**
18036  * hdd_softap_sta_deauth() - handle deauth req from HDD
18037  * @adapter: Pointer to the HDD adapter
18038  * @param: Params to the operation
18039  *
18040  * This to take counter measure to handle deauth req from HDD
18041  *
18042  * Return: None
18043  */
hdd_softap_sta_deauth(struct hdd_adapter * adapter,struct csr_del_sta_params * param)18044 QDF_STATUS hdd_softap_sta_deauth(struct hdd_adapter *adapter,
18045 				 struct csr_del_sta_params *param)
18046 {
18047 	QDF_STATUS qdf_status = QDF_STATUS_E_FAULT;
18048 	struct hdd_context *hdd_ctx;
18049 	bool is_sap_bcast_deauth_enabled = false;
18050 
18051 	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
18052 	if (!hdd_ctx) {
18053 		hdd_err("hdd_ctx is NULL");
18054 		return QDF_STATUS_E_INVAL;
18055 	}
18056 
18057 	ucfg_mlme_get_sap_bcast_deauth_enabled(hdd_ctx->psoc,
18058 					       &is_sap_bcast_deauth_enabled);
18059 
18060 	hdd_enter();
18061 
18062 	hdd_debug("sap_bcast_deauth_enabled %d", is_sap_bcast_deauth_enabled);
18063 	/* Ignore request to deauth bcmc station */
18064 	if (!is_sap_bcast_deauth_enabled)
18065 		if (param->peerMacAddr.bytes[0] & 0x1)
18066 			return qdf_status;
18067 
18068 	qdf_status =
18069 		wlansap_deauth_sta(WLAN_HDD_GET_SAP_CTX_PTR(adapter->deflink),
18070 				   param);
18071 
18072 	hdd_exit();
18073 	return qdf_status;
18074 }
18075 
18076 /**
18077  * hdd_softap_sta_disassoc() - take counter measure to handle deauth req from HDD
18078  * @adapter: Pointer to the HDD
18079  * @param: pointer to station deletion parameters
18080  *
18081  * This to take counter measure to handle deauth req from HDD
18082  *
18083  * Return: None
18084  */
hdd_softap_sta_disassoc(struct hdd_adapter * adapter,struct csr_del_sta_params * param)18085 void hdd_softap_sta_disassoc(struct hdd_adapter *adapter,
18086 			     struct csr_del_sta_params *param)
18087 {
18088 	hdd_enter();
18089 
18090 	/* Ignore request to disassoc bcmc station */
18091 	if (param->peerMacAddr.bytes[0] & 0x1)
18092 		return;
18093 
18094 	wlansap_disassoc_sta(WLAN_HDD_GET_SAP_CTX_PTR(adapter->deflink),
18095 			     param);
18096 }
18097 
18098 void
wlan_hdd_set_roaming_state(struct wlan_hdd_link_info * cur_link_info,enum wlan_cm_rso_control_requestor rso_op_requestor,bool enab_roam)18099 wlan_hdd_set_roaming_state(struct wlan_hdd_link_info *cur_link_info,
18100 			   enum wlan_cm_rso_control_requestor rso_op_requestor,
18101 			   bool enab_roam)
18102 {
18103 	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(cur_link_info->adapter);
18104 	struct hdd_adapter *adapter = NULL, *next_adapter = NULL;
18105 	wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_DISABLE_ROAMING;
18106 	uint8_t vdev_id, cur_vdev_id = cur_link_info->vdev_id;
18107 	struct wlan_hdd_link_info *link_info;
18108 
18109 	if (!policy_mgr_is_sta_active_connection_exists(hdd_ctx->psoc))
18110 		return;
18111 
18112 	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
18113 					   dbgid) {
18114 		hdd_adapter_for_each_active_link_info(adapter, link_info) {
18115 			vdev_id = link_info->vdev_id;
18116 			if (cur_vdev_id != link_info->vdev_id &&
18117 			    adapter->device_mode == QDF_STA_MODE &&
18118 			    hdd_cm_is_vdev_associated(link_info)) {
18119 				if (enab_roam) {
18120 					hdd_debug("%d Enable roaming", vdev_id);
18121 					sme_start_roaming(hdd_ctx->mac_handle,
18122 							  vdev_id,
18123 							  REASON_DRIVER_ENABLED,
18124 							  rso_op_requestor);
18125 				} else {
18126 					hdd_debug("%d Disable roaming",
18127 						  vdev_id);
18128 					sme_stop_roaming(hdd_ctx->mac_handle,
18129 							 vdev_id,
18130 							 REASON_DRIVER_DISABLED,
18131 							 rso_op_requestor);
18132 				}
18133 			}
18134 		}
18135 		hdd_adapter_dev_put_debug(adapter, dbgid);
18136 	}
18137 }
18138 
18139 /**
18140  * nl_srv_bcast_svc() - Wrapper function to send bcast msgs to SVC mcast group
18141  * @skb: sk buffer pointer
18142  *
18143  * Sends the bcast message to SVC multicast group with generic nl socket
18144  * if CNSS_GENL is enabled. Else, use the legacy netlink socket to send.
18145  *
18146  * Return: None
18147  */
nl_srv_bcast_svc(struct sk_buff * skb)18148 static void nl_srv_bcast_svc(struct sk_buff *skb)
18149 {
18150 #ifdef CNSS_GENL
18151 	nl_srv_bcast(skb, CLD80211_MCGRP_SVC_MSGS, WLAN_NL_MSG_SVC);
18152 #else
18153 	nl_srv_bcast(skb);
18154 #endif
18155 }
18156 
wlan_hdd_send_svc_nlink_msg(int radio,int type,void * data,int len)18157 void wlan_hdd_send_svc_nlink_msg(int radio, int type, void *data, int len)
18158 {
18159 	struct sk_buff *skb;
18160 	struct nlmsghdr *nlh;
18161 	tAniMsgHdr *ani_hdr;
18162 	void *nl_data = NULL;
18163 	int flags = GFP_KERNEL;
18164 	struct radio_index_tlv *radio_info;
18165 	int tlv_len;
18166 
18167 	if (in_interrupt() || irqs_disabled() || in_atomic())
18168 		flags = GFP_ATOMIC;
18169 
18170 	skb = alloc_skb(NLMSG_SPACE(WLAN_NL_MAX_PAYLOAD), flags);
18171 
18172 	if (!skb)
18173 		return;
18174 
18175 	nlh = (struct nlmsghdr *)skb->data;
18176 	nlh->nlmsg_pid = 0;     /* from kernel */
18177 	nlh->nlmsg_flags = 0;
18178 	nlh->nlmsg_seq = 0;
18179 	nlh->nlmsg_type = WLAN_NL_MSG_SVC;
18180 
18181 	ani_hdr = NLMSG_DATA(nlh);
18182 	ani_hdr->type = type;
18183 
18184 	switch (type) {
18185 	case WLAN_SVC_FW_CRASHED_IND:
18186 	case WLAN_SVC_FW_SHUTDOWN_IND:
18187 	case WLAN_SVC_LTE_COEX_IND:
18188 	case WLAN_SVC_WLAN_AUTO_SHUTDOWN_IND:
18189 	case WLAN_SVC_WLAN_AUTO_SHUTDOWN_CANCEL_IND:
18190 		ani_hdr->length = 0;
18191 		nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr)));
18192 		break;
18193 	case WLAN_SVC_WLAN_STATUS_IND:
18194 	case WLAN_SVC_WLAN_VERSION_IND:
18195 	case WLAN_SVC_DFS_CAC_START_IND:
18196 	case WLAN_SVC_DFS_CAC_END_IND:
18197 	case WLAN_SVC_DFS_RADAR_DETECT_IND:
18198 	case WLAN_SVC_DFS_ALL_CHANNEL_UNAVAIL_IND:
18199 	case WLAN_SVC_WLAN_TP_IND:
18200 	case WLAN_SVC_WLAN_TP_TX_IND:
18201 	case WLAN_SVC_RPS_ENABLE_IND:
18202 	case WLAN_SVC_CORE_MINFREQ:
18203 		ani_hdr->length = len;
18204 		nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr) + len));
18205 		nl_data = (char *)ani_hdr + sizeof(tAniMsgHdr);
18206 		memcpy(nl_data, data, len);
18207 		break;
18208 
18209 	default:
18210 		hdd_err("WLAN SVC: Attempt to send unknown nlink message %d",
18211 		       type);
18212 		kfree_skb(skb);
18213 		return;
18214 	}
18215 
18216 	/*
18217 	 * Add radio index at the end of the svc event in TLV format
18218 	 * to maintain the backward compatibility with userspace
18219 	 * applications.
18220 	 */
18221 
18222 	tlv_len = 0;
18223 
18224 	if ((sizeof(*ani_hdr) + len + sizeof(struct radio_index_tlv))
18225 		< WLAN_NL_MAX_PAYLOAD) {
18226 		radio_info  = (struct radio_index_tlv *)((char *) ani_hdr +
18227 		sizeof(*ani_hdr) + len);
18228 		radio_info->type = (unsigned short) WLAN_SVC_WLAN_RADIO_INDEX;
18229 		radio_info->length = (unsigned short) sizeof(radio_info->radio);
18230 		radio_info->radio = radio;
18231 		tlv_len = sizeof(*radio_info);
18232 		hdd_debug("Added radio index tlv - radio index %d",
18233 			  radio_info->radio);
18234 	}
18235 
18236 	nlh->nlmsg_len += tlv_len;
18237 	skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr) + len + tlv_len));
18238 
18239 	nl_srv_bcast_svc(skb);
18240 }
18241 
18242 #ifdef FEATURE_WLAN_AUTO_SHUTDOWN
wlan_hdd_auto_shutdown_cb(void)18243 void wlan_hdd_auto_shutdown_cb(void)
18244 {
18245 	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
18246 
18247 	if (!hdd_ctx)
18248 		return;
18249 
18250 	hdd_debug("Wlan Idle. Sending Shutdown event..");
18251 	wlan_hdd_send_svc_nlink_msg(hdd_ctx->radio_index,
18252 			WLAN_SVC_WLAN_AUTO_SHUTDOWN_IND, NULL, 0);
18253 }
18254 
wlan_hdd_auto_shutdown_enable(struct hdd_context * hdd_ctx,bool enable)18255 void wlan_hdd_auto_shutdown_enable(struct hdd_context *hdd_ctx, bool enable)
18256 {
18257 	struct hdd_adapter *adapter, *next_adapter = NULL;
18258 	bool ap_connected = false, sta_connected = false;
18259 	mac_handle_t mac_handle;
18260 	struct wlan_hdd_link_info *link_info;
18261 	struct hdd_ap_ctx *ap_ctx;
18262 	wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_AUTO_SHUTDOWN_ENABLE;
18263 
18264 	mac_handle = hdd_ctx->mac_handle;
18265 	if (!mac_handle)
18266 		return;
18267 
18268 	if (hdd_ctx->config->wlan_auto_shutdown == 0)
18269 		return;
18270 
18271 	if (enable == false) {
18272 		if (sme_set_auto_shutdown_timer(mac_handle, 0) !=
18273 							QDF_STATUS_SUCCESS) {
18274 			hdd_err("Failed to stop wlan auto shutdown timer");
18275 		}
18276 		wlan_hdd_send_svc_nlink_msg(hdd_ctx->radio_index,
18277 			WLAN_SVC_WLAN_AUTO_SHUTDOWN_CANCEL_IND, NULL, 0);
18278 		return;
18279 	}
18280 
18281 	/* To enable shutdown timer check conncurrency */
18282 	if (!policy_mgr_concurrent_open_sessions_running(hdd_ctx->psoc))
18283 		goto start_timer;
18284 
18285 	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter,
18286 					   next_adapter, dbgid) {
18287 		hdd_adapter_for_each_active_link_info(adapter, link_info) {
18288 			if (adapter->device_mode == QDF_STA_MODE &&
18289 			    hdd_cm_is_vdev_associated(link_info)) {
18290 				sta_connected = true;
18291 				hdd_adapter_dev_put_debug(adapter, dbgid);
18292 				if (next_adapter)
18293 					hdd_adapter_dev_put_debug(next_adapter,
18294 								  dbgid);
18295 				break;
18296 			}
18297 
18298 			if (adapter->device_mode == QDF_SAP_MODE) {
18299 				ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(link_info);
18300 				if (ap_ctx->ap_active == true) {
18301 					ap_connected = true;
18302 					hdd_adapter_dev_put_debug(adapter,
18303 								  dbgid);
18304 					if (next_adapter)
18305 						hdd_adapter_dev_put_debug(
18306 								next_adapter,
18307 								dbgid);
18308 					break;
18309 				}
18310 			}
18311 		}
18312 		hdd_adapter_dev_put_debug(adapter, dbgid);
18313 	}
18314 
18315 start_timer:
18316 	if (ap_connected == true || sta_connected == true) {
18317 		hdd_debug("CC Session active. Shutdown timer not enabled");
18318 		return;
18319 	}
18320 
18321 	if (sme_set_auto_shutdown_timer(mac_handle,
18322 					hdd_ctx->config->wlan_auto_shutdown)
18323 	    != QDF_STATUS_SUCCESS)
18324 		hdd_err("Failed to start wlan auto shutdown timer");
18325 	else
18326 		hdd_info("Auto Shutdown timer for %d seconds enabled",
18327 			 hdd_ctx->config->wlan_auto_shutdown);
18328 }
18329 #endif
18330 
18331 struct hdd_adapter *
hdd_get_con_sap_adapter(struct hdd_adapter * this_sap_adapter,bool check_start_bss)18332 hdd_get_con_sap_adapter(struct hdd_adapter *this_sap_adapter,
18333 			bool check_start_bss)
18334 {
18335 	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(this_sap_adapter);
18336 	struct hdd_adapter *adapter, *next_adapter = NULL;
18337 	wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_GET_CON_SAP_ADAPTER;
18338 	struct wlan_hdd_link_info *link_info;
18339 
18340 	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
18341 					   dbgid) {
18342 		if ((adapter->device_mode == QDF_SAP_MODE ||
18343 		     adapter->device_mode == QDF_P2P_GO_MODE) &&
18344 		    adapter != this_sap_adapter) {
18345 			hdd_adapter_for_each_active_link_info(adapter,
18346 							      link_info) {
18347 				if (!check_start_bss) {
18348 					hdd_adapter_dev_put_debug(adapter,
18349 								  dbgid);
18350 					if (next_adapter)
18351 						hdd_adapter_dev_put_debug(
18352 								next_adapter,
18353 								dbgid);
18354 					return adapter;
18355 				}
18356 				if (test_bit(SOFTAP_BSS_STARTED,
18357 					     &link_info->link_flags)) {
18358 					hdd_adapter_dev_put_debug(adapter,
18359 								  dbgid);
18360 					if (next_adapter)
18361 						hdd_adapter_dev_put_debug(
18362 								next_adapter,
18363 								dbgid);
18364 					return adapter;
18365 				}
18366 			}
18367 		}
18368 		hdd_adapter_dev_put_debug(adapter, dbgid);
18369 	}
18370 
18371 	return NULL;
18372 }
18373 
hdd_adapter_is_sta(struct hdd_adapter * adapter)18374 static inline bool hdd_adapter_is_sta(struct hdd_adapter *adapter)
18375 {
18376 	return adapter->device_mode == QDF_STA_MODE ||
18377 		adapter->device_mode == QDF_P2P_CLIENT_MODE;
18378 }
18379 
hdd_is_any_adapter_connected(struct hdd_context * hdd_ctx)18380 bool hdd_is_any_adapter_connected(struct hdd_context *hdd_ctx)
18381 {
18382 	struct hdd_adapter *adapter, *next_adapter = NULL;
18383 	wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_IS_ANY_ADAPTER_CONNECTED;
18384 	struct wlan_hdd_link_info *link_info;
18385 
18386 	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
18387 					   dbgid) {
18388 		hdd_adapter_for_each_active_link_info(adapter, link_info) {
18389 			if (hdd_adapter_is_sta(adapter) &&
18390 			    hdd_cm_is_vdev_associated(link_info)) {
18391 				hdd_adapter_dev_put_debug(adapter, dbgid);
18392 				if (next_adapter)
18393 					hdd_adapter_dev_put_debug(next_adapter,
18394 								  dbgid);
18395 				return true;
18396 			}
18397 
18398 			if (hdd_adapter_is_ap(adapter) &&
18399 			    WLAN_HDD_GET_AP_CTX_PTR(link_info)->ap_active) {
18400 				hdd_adapter_dev_put_debug(adapter, dbgid);
18401 				if (next_adapter)
18402 					hdd_adapter_dev_put_debug(next_adapter,
18403 								  dbgid);
18404 				return true;
18405 			}
18406 
18407 			if (adapter->device_mode == QDF_NDI_MODE &&
18408 			    hdd_cm_is_vdev_associated(link_info)) {
18409 				hdd_adapter_dev_put_debug(adapter, dbgid);
18410 				if (next_adapter)
18411 					hdd_adapter_dev_put_debug(next_adapter,
18412 								  dbgid);
18413 				return true;
18414 			}
18415 		}
18416 		hdd_adapter_dev_put_debug(adapter, dbgid);
18417 	}
18418 
18419 	return false;
18420 }
18421 
18422 #if defined MSM_PLATFORM && (LINUX_VERSION_CODE <= KERNEL_VERSION(4, 19, 0))
18423 /**
18424  * hdd_inform_stop_sap() - call cfg80211 API to stop SAP
18425  * @adapter: pointer to adapter
18426  *
18427  * This function calls cfg80211 API to stop SAP
18428  *
18429  * Return: None
18430  */
hdd_inform_stop_sap(struct hdd_adapter * adapter)18431 static void hdd_inform_stop_sap(struct hdd_adapter *adapter)
18432 {
18433 	hdd_debug("SAP stopped due to invalid channel vdev id %d",
18434 		  wlan_vdev_get_id(adapter->deflink->vdev));
18435 	cfg80211_ap_stopped(adapter->dev, GFP_KERNEL);
18436 }
18437 
18438 #else
hdd_inform_stop_sap(struct hdd_adapter * adapter)18439 static void hdd_inform_stop_sap(struct hdd_adapter *adapter)
18440 {
18441 	hdd_debug("SAP stopped due to invalid channel vdev id %d",
18442 		  wlan_vdev_get_id(adapter->deflink->vdev));
18443 	cfg80211_stop_iface(adapter->hdd_ctx->wiphy, &adapter->wdev,
18444 			    GFP_KERNEL);
18445 }
18446 #endif
18447 
18448 /**
18449  * wlan_hdd_stop_sap() - This function stops bss of SAP.
18450  * @ap_adapter: SAP adapter
18451  *
18452  * This function will process the stopping of sap adapter.
18453  *
18454  * Return: None
18455  */
wlan_hdd_stop_sap(struct hdd_adapter * ap_adapter)18456 void wlan_hdd_stop_sap(struct hdd_adapter *ap_adapter)
18457 {
18458 	struct hdd_ap_ctx *hdd_ap_ctx;
18459 	struct hdd_hostapd_state *hostapd_state;
18460 	QDF_STATUS qdf_status;
18461 	struct hdd_context *hdd_ctx;
18462 
18463 	if (!ap_adapter) {
18464 		hdd_err("ap_adapter is NULL here");
18465 		return;
18466 	}
18467 
18468 	hdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(ap_adapter->deflink);
18469 	hdd_ctx = WLAN_HDD_GET_CTX(ap_adapter);
18470 	if (wlan_hdd_validate_context(hdd_ctx))
18471 		return;
18472 
18473 	mutex_lock(&hdd_ctx->sap_lock);
18474 	if (test_bit(SOFTAP_BSS_STARTED, &ap_adapter->deflink->link_flags)) {
18475 		wlan_hdd_del_station(ap_adapter, NULL);
18476 		hostapd_state =
18477 			WLAN_HDD_GET_HOSTAP_STATE_PTR(ap_adapter->deflink);
18478 		hdd_debug("Now doing SAP STOPBSS");
18479 		qdf_event_reset(&hostapd_state->qdf_stop_bss_event);
18480 		if (QDF_STATUS_SUCCESS == wlansap_stop_bss(hdd_ap_ctx->
18481 							sap_context)) {
18482 			qdf_status = qdf_wait_single_event(&hostapd_state->
18483 					qdf_stop_bss_event,
18484 					SME_CMD_STOP_BSS_TIMEOUT);
18485 			if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
18486 				mutex_unlock(&hdd_ctx->sap_lock);
18487 				hdd_err("SAP Stop Failed");
18488 				return;
18489 			}
18490 		}
18491 		clear_bit(SOFTAP_BSS_STARTED, &ap_adapter->deflink->link_flags);
18492 		policy_mgr_decr_session_set_pcl(hdd_ctx->psoc,
18493 						ap_adapter->device_mode,
18494 						ap_adapter->deflink->vdev_id);
18495 		hdd_green_ap_start_state_mc(hdd_ctx, ap_adapter->device_mode,
18496 					    false);
18497 		hdd_inform_stop_sap(ap_adapter);
18498 		hdd_debug("SAP Stop Success");
18499 	} else {
18500 		hdd_err("Can't stop ap because its not started");
18501 	}
18502 	mutex_unlock(&hdd_ctx->sap_lock);
18503 }
18504 
18505 #if defined(WLAN_FEATURE_11BE_MLO) && defined(CFG80211_11BE_BASIC)
18506 /**
18507  * wlan_hdd_mlo_sap_reinit() - handle mlo scenario for ssr
18508  * @link_info: Pointer of link_info in adapter
18509  *
18510  * Return: QDF_STATUS
18511  */
wlan_hdd_mlo_sap_reinit(struct wlan_hdd_link_info * link_info)18512 static QDF_STATUS wlan_hdd_mlo_sap_reinit(struct wlan_hdd_link_info *link_info)
18513 {
18514 	struct hdd_context *hdd_ctx = link_info->adapter->hdd_ctx;
18515 	struct sap_config *config = &link_info->session.ap.sap_config;
18516 
18517 	if (config->mlo_sap) {
18518 		if (!mlo_ap_vdev_attach(link_info->vdev, config->link_id,
18519 					config->num_link)) {
18520 			hdd_err("SAP mlo mgr attach fail");
18521 			return QDF_STATUS_E_INVAL;
18522 		}
18523 	}
18524 
18525 	if (!policy_mgr_is_mlo_sap_concurrency_allowed(hdd_ctx->psoc,
18526 						       config->mlo_sap,
18527 						       wlan_vdev_get_id(link_info->vdev))) {
18528 		hdd_err("MLO SAP concurrency check fails");
18529 		return QDF_STATUS_E_INVAL;
18530 	}
18531 
18532 	return QDF_STATUS_SUCCESS;
18533 }
18534 #else
18535 static inline QDF_STATUS
wlan_hdd_mlo_sap_reinit(struct wlan_hdd_link_info * link_info)18536 wlan_hdd_mlo_sap_reinit(struct wlan_hdd_link_info *link_info)
18537 {
18538 	return QDF_STATUS_SUCCESS;
18539 }
18540 #endif
18541 
wlan_hdd_set_sap_beacon_protection(struct hdd_context * hdd_ctx,struct wlan_hdd_link_info * link_info,struct hdd_beacon_data * beacon)18542 void wlan_hdd_set_sap_beacon_protection(struct hdd_context *hdd_ctx,
18543 					struct wlan_hdd_link_info *link_info,
18544 					struct hdd_beacon_data *beacon)
18545 {
18546 	const uint8_t *ie = NULL;
18547 	struct s_ext_cap *p_ext_cap;
18548 	struct wlan_objmgr_vdev *vdev;
18549 	bool target_bigtk_support = false;
18550 	uint8_t vdev_id;
18551 	uint8_t ie_len;
18552 
18553 	if (!beacon) {
18554 		hdd_err("beacon is null");
18555 		return;
18556 	}
18557 
18558 	ie = wlan_get_ie_ptr_from_eid(DOT11F_EID_EXTCAP, beacon->tail,
18559 				      beacon->tail_len);
18560 	if (!ie) {
18561 		hdd_err("IE is null");
18562 		return;
18563 	}
18564 
18565 	if (ie[1] > DOT11F_IE_EXTCAP_MAX_LEN ||
18566 	    ie[1] < DOT11F_IE_EXTCAP_MIN_LEN) {
18567 		hdd_err("Invalid IEs eid: %d elem_len: %d", ie[0], ie[1]);
18568 		return;
18569 	}
18570 
18571 	p_ext_cap = qdf_mem_malloc(sizeof(*p_ext_cap));
18572 	if (!p_ext_cap)
18573 		return;
18574 
18575 	ie_len = (ie[1] > sizeof(*p_ext_cap)) ? sizeof(*p_ext_cap) : ie[1];
18576 
18577 	qdf_mem_copy(p_ext_cap, &ie[2], ie_len);
18578 
18579 	vdev = hdd_objmgr_get_vdev_by_user(link_info, WLAN_HDD_ID_OBJ_MGR);
18580 	if (!vdev) {
18581 		hdd_err("vdev is null");
18582 		goto end;
18583 	}
18584 
18585 	vdev_id = wlan_vdev_get_id(vdev);
18586 
18587 	hdd_debug("vdev %d beacon protection %d", vdev_id,
18588 		  p_ext_cap->beacon_protection_enable);
18589 
18590 	ucfg_mlme_get_bigtk_support(hdd_ctx->psoc, &target_bigtk_support);
18591 
18592 	if (target_bigtk_support && p_ext_cap->beacon_protection_enable)
18593 		mlme_set_bigtk_support(vdev, true);
18594 
18595 	hdd_objmgr_put_vdev_by_user(vdev, WLAN_HDD_ID_OBJ_MGR);
18596 
18597 end:
18598 	qdf_mem_free(p_ext_cap);
18599 }
18600 
wlan_hdd_start_sap(struct wlan_hdd_link_info * link_info,bool reinit)18601 void wlan_hdd_start_sap(struct wlan_hdd_link_info *link_info, bool reinit)
18602 {
18603 	struct hdd_ap_ctx *ap_ctx;
18604 	struct hdd_hostapd_state *hostapd_state;
18605 	QDF_STATUS qdf_status;
18606 	struct hdd_context *hdd_ctx;
18607 	struct sap_config *sap_config;
18608 	struct hdd_adapter *ap_adapter = link_info->adapter;
18609 
18610 	if (QDF_SAP_MODE != ap_adapter->device_mode) {
18611 		hdd_err("SoftAp role has not been enabled");
18612 		return;
18613 	}
18614 
18615 	hdd_ctx = WLAN_HDD_GET_CTX(ap_adapter);
18616 	ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(link_info);
18617 	hostapd_state = WLAN_HDD_GET_HOSTAP_STATE_PTR(link_info);
18618 	sap_config = &ap_ctx->sap_config;
18619 
18620 	mutex_lock(&hdd_ctx->sap_lock);
18621 	if (test_bit(SOFTAP_BSS_STARTED, &link_info->link_flags))
18622 		goto end;
18623 
18624 	if (wlan_hdd_cfg80211_update_apies(link_info)) {
18625 		hdd_err("SAP Not able to set AP IEs");
18626 		goto end;
18627 	}
18628 	wlan_reg_set_channel_params_for_pwrmode(hdd_ctx->pdev,
18629 						sap_config->chan_freq, 0,
18630 						&sap_config->ch_params,
18631 						REG_CURRENT_PWR_MODE);
18632 	qdf_status = wlan_hdd_mlo_sap_reinit(link_info);
18633 	if (QDF_IS_STATUS_ERROR(qdf_status)) {
18634 		hdd_err("SAP Not able to do mlo attach");
18635 		goto end;
18636 	}
18637 
18638 	qdf_event_reset(&hostapd_state->qdf_event);
18639 	qdf_status = wlansap_start_bss(ap_ctx->sap_context,
18640 				       hdd_hostapd_sap_event_cb, sap_config,
18641 				       ap_adapter->dev);
18642 	if (QDF_IS_STATUS_ERROR(qdf_status))
18643 		goto end;
18644 
18645 	wlan_hdd_set_sap_beacon_protection(hdd_ctx, link_info, ap_ctx->beacon);
18646 
18647 	hdd_debug("Waiting for SAP to start");
18648 	qdf_status = qdf_wait_single_event(&hostapd_state->qdf_event,
18649 					SME_CMD_START_BSS_TIMEOUT);
18650 	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
18651 		hdd_err("SAP Start failed");
18652 		goto end;
18653 	}
18654 	hdd_info("SAP Start Success");
18655 
18656 	wlansap_reset_sap_config_add_ie(sap_config, eUPDATE_IE_ALL);
18657 	set_bit(SOFTAP_BSS_STARTED, &link_info->link_flags);
18658 	if (hostapd_state->bss_state == BSS_START) {
18659 		policy_mgr_incr_active_session(hdd_ctx->psoc,
18660 					ap_adapter->device_mode,
18661 					link_info->vdev_id);
18662 		hdd_green_ap_start_state_mc(hdd_ctx, ap_adapter->device_mode,
18663 					    true);
18664 	}
18665 	mutex_unlock(&hdd_ctx->sap_lock);
18666 
18667 	return;
18668 end:
18669 	wlan_hdd_mlo_reset(link_info);
18670 	wlansap_reset_sap_config_add_ie(sap_config, eUPDATE_IE_ALL);
18671 	mutex_unlock(&hdd_ctx->sap_lock);
18672 	/* SAP context and beacon cleanup will happen during driver unload
18673 	 * in hdd_stop_adapter
18674 	 */
18675 	hdd_err("SAP restart after SSR failed! Reload WLAN and try SAP again");
18676 	/* Free the beacon memory in case of failure in the sap restart */
18677 	qdf_mem_free(ap_ctx->beacon);
18678 	ap_ctx->beacon = NULL;
18679 }
18680 
18681 #ifdef QCA_CONFIG_SMP
18682 /**
18683  * wlan_hdd_get_cpu() - get cpu_index
18684  *
18685  * Return: cpu_index
18686  */
wlan_hdd_get_cpu(void)18687 int wlan_hdd_get_cpu(void)
18688 {
18689 	int cpu_index = get_cpu();
18690 
18691 	put_cpu();
18692 	return cpu_index;
18693 }
18694 #endif
18695 
18696 /**
18697  * hdd_get_fwpath() - get framework path
18698  *
18699  * This function is used to get the string written by
18700  * userspace to start the wlan driver
18701  *
18702  * Return: string
18703  */
hdd_get_fwpath(void)18704 const char *hdd_get_fwpath(void)
18705 {
18706 	return fwpath.string;
18707 }
18708 
hdd_state_query_cb(void)18709 static inline int hdd_state_query_cb(void)
18710 {
18711 	return !!wlan_hdd_validate_context(cds_get_context(QDF_MODULE_ID_HDD));
18712 }
18713 
__hdd_op_protect_cb(void ** out_sync,const char * func)18714 static int __hdd_op_protect_cb(void **out_sync, const char *func)
18715 {
18716 	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
18717 
18718 	if (!hdd_ctx)
18719 		return -EAGAIN;
18720 
18721 	return __osif_psoc_sync_op_start(hdd_ctx->parent_dev,
18722 					 (struct osif_psoc_sync **)out_sync,
18723 					 func);
18724 }
18725 
__hdd_op_unprotect_cb(void * sync,const char * func)18726 static void __hdd_op_unprotect_cb(void *sync, const char *func)
18727 {
18728 	__osif_psoc_sync_op_stop(sync, func);
18729 }
18730 
18731 #ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
18732 /**
18733  * hdd_logging_sock_init_svc() - Initialize logging sock
18734  *
18735  * Return: 0 for success, errno on failure
18736  */
18737 static int
hdd_logging_sock_init_svc(void)18738 hdd_logging_sock_init_svc(void)
18739 {
18740 	return wlan_logging_sock_init_svc();
18741 }
18742 #else
18743 static inline int
hdd_logging_sock_init_svc(void)18744 hdd_logging_sock_init_svc(void)
18745 {
18746 	return 0;
18747 }
18748 #endif
18749 
18750 /**
18751  * hdd_init() - Initialize Driver
18752  *
18753  * This function initializes CDS global context with the help of cds_init. This
18754  * has to be the first function called after probe to get a valid global
18755  * context.
18756  *
18757  * Return: 0 for success, errno on failure
18758  */
hdd_init(void)18759 int hdd_init(void)
18760 {
18761 	QDF_STATUS status;
18762 
18763 	status = cds_init();
18764 	if (QDF_IS_STATUS_ERROR(status)) {
18765 		hdd_err("Failed to allocate CDS context");
18766 		return -ENOMEM;
18767 	}
18768 
18769 	qdf_op_callbacks_register(__hdd_op_protect_cb, __hdd_op_unprotect_cb);
18770 
18771 	wlan_init_bug_report_lock();
18772 
18773 	if (hdd_logging_sock_init_svc()) {
18774 		hdd_err("logging sock init failed.");
18775 		goto err;
18776 	}
18777 
18778 	hdd_trace_init();
18779 	hdd_register_debug_callback();
18780 	wlan_roam_debug_init();
18781 
18782 	return 0;
18783 
18784 err:
18785 	wlan_destroy_bug_report_lock();
18786 	qdf_op_callbacks_register(NULL, NULL);
18787 	cds_deinit();
18788 	return -ENOMEM;
18789 }
18790 
18791 /**
18792  * hdd_deinit() - Deinitialize Driver
18793  *
18794  * This function frees CDS global context with the help of cds_deinit. This
18795  * has to be the last function call in remove callback to free the global
18796  * context.
18797  */
hdd_deinit(void)18798 void hdd_deinit(void)
18799 {
18800 	wlan_roam_debug_deinit();
18801 
18802 #ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
18803 	wlan_logging_sock_deinit_svc();
18804 #endif
18805 
18806 	wlan_destroy_bug_report_lock();
18807 	qdf_op_callbacks_register(NULL, NULL);
18808 	cds_deinit();
18809 }
18810 
18811 #ifdef QCA_WIFI_EMULATION
18812 #define HDD_WLAN_START_WAIT_TIME ((CDS_WMA_TIMEOUT + 5000) * 100)
18813 #else
18814 #define HDD_WLAN_START_WAIT_TIME (CDS_WMA_TIMEOUT + 5000)
18815 #endif
18816 
hdd_init_start_completion(void)18817 void hdd_init_start_completion(void)
18818 {
18819 	INIT_COMPLETION(wlan_start_comp);
18820 }
18821 
18822 #ifdef WLAN_CTRL_NAME
18823 static unsigned int dev_num = 1;
18824 static struct cdev wlan_hdd_state_cdev;
18825 static struct class *class;
18826 static dev_t device;
18827 
hdd_set_adapter_wlm_def_level(struct hdd_context * hdd_ctx)18828 static void hdd_set_adapter_wlm_def_level(struct hdd_context *hdd_ctx)
18829 {
18830 	struct hdd_adapter *adapter, *next_adapter = NULL;
18831 	wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_GET_ADAPTER;
18832 	int ret;
18833 	QDF_STATUS qdf_status;
18834 	uint8_t latency_level;
18835 	bool reset;
18836 
18837 	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam())
18838 		return;
18839 
18840 	ret = wlan_hdd_validate_context(hdd_ctx);
18841 	if (ret != 0)
18842 		return;
18843 
18844 	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
18845 					   dbgid) {
18846 		qdf_status = ucfg_mlme_cfg_get_wlm_level(hdd_ctx->psoc,
18847 							 &latency_level);
18848 		if (QDF_IS_STATUS_ERROR(qdf_status))
18849 			adapter->latency_level =
18850 			       QCA_WLAN_VENDOR_ATTR_CONFIG_LATENCY_LEVEL_NORMAL;
18851 		else
18852 			adapter->latency_level = latency_level;
18853 		qdf_status = ucfg_mlme_cfg_get_wlm_reset(hdd_ctx->psoc, &reset);
18854 		if (QDF_IS_STATUS_ERROR(qdf_status)) {
18855 			hdd_err("could not get the wlm reset flag");
18856 			reset = false;
18857 		}
18858 
18859 		if (hdd_get_multi_client_ll_support(adapter) && !reset)
18860 			wlan_hdd_deinit_multi_client_info_table(adapter);
18861 
18862 		adapter->upgrade_udp_qos_threshold = QCA_WLAN_AC_BK;
18863 		hdd_debug("UDP packets qos reset to: %d",
18864 			  adapter->upgrade_udp_qos_threshold);
18865 		hdd_adapter_dev_put_debug(adapter, dbgid);
18866 	}
18867 }
18868 
wlan_hdd_state_ctrl_param_open(struct inode * inode,struct file * file)18869 static int wlan_hdd_state_ctrl_param_open(struct inode *inode,
18870 					  struct file *file)
18871 {
18872 	qdf_atomic_inc(&wlan_hdd_state_fops_ref);
18873 
18874 	return 0;
18875 }
18876 
__hdd_inform_wifi_off(void)18877 static void __hdd_inform_wifi_off(void)
18878 {
18879 	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
18880 	int ret;
18881 
18882 	ret = wlan_hdd_validate_context(hdd_ctx);
18883 	if (ret != 0)
18884 		return;
18885 
18886 	ucfg_dlm_wifi_off(hdd_ctx->pdev);
18887 
18888 	if (rtnl_trylock()) {
18889 		wlan_hdd_lpc_del_monitor_interface(hdd_ctx, false);
18890 		rtnl_unlock();
18891 	}
18892 }
18893 
hdd_inform_wifi_off(void)18894 static void hdd_inform_wifi_off(void)
18895 {
18896 	int ret;
18897 	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
18898 	struct osif_psoc_sync *psoc_sync;
18899 
18900 	if (!hdd_ctx)
18901 		return;
18902 
18903 	ret = osif_psoc_sync_op_start(wiphy_dev(hdd_ctx->wiphy), &psoc_sync);
18904 	if (ret)
18905 		return;
18906 
18907 	hdd_set_adapter_wlm_def_level(hdd_ctx);
18908 	__hdd_inform_wifi_off();
18909 
18910 	osif_psoc_sync_op_stop(psoc_sync);
18911 }
18912 
18913 #if defined CFG80211_USER_HINT_CELL_BASE_SELF_MANAGED || \
18914 	(LINUX_VERSION_CODE >= KERNEL_VERSION(4, 18, 0))
hdd_inform_wifi_on(void)18915 static void hdd_inform_wifi_on(void)
18916 {
18917 	int ret;
18918 	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
18919 	struct osif_psoc_sync *psoc_sync;
18920 
18921 	hdd_nofl_debug("inform regdomain for wifi on");
18922 	ret = wlan_hdd_validate_context(hdd_ctx);
18923 	if (ret)
18924 		return;
18925 	if (!wlan_hdd_validate_modules_state(hdd_ctx))
18926 		return;
18927 	if (!hdd_ctx->wiphy)
18928 		return;
18929 	ret = osif_psoc_sync_op_start(wiphy_dev(hdd_ctx->wiphy), &psoc_sync);
18930 	if (ret)
18931 		return;
18932 	if (hdd_ctx->wiphy->registered)
18933 		hdd_send_wiphy_regd_sync_event(hdd_ctx);
18934 
18935 	osif_psoc_sync_op_stop(psoc_sync);
18936 }
18937 #else
hdd_inform_wifi_on(void)18938 static void hdd_inform_wifi_on(void)
18939 {
18940 }
18941 #endif
18942 
hdd_validate_wlan_string(const char __user * user_buf)18943 static int hdd_validate_wlan_string(const char __user *user_buf)
18944 {
18945 	char buf[15];
18946 	int i;
18947 	static const char * const wlan_str[] = {
18948 		[WLAN_OFF_STR] = "OFF",
18949 		[WLAN_ON_STR] = "ON",
18950 		[WLAN_ENABLE_STR] = "ENABLE",
18951 		[WLAN_DISABLE_STR] = "DISABLE",
18952 		[WLAN_WAIT_FOR_READY_STR] = "WAIT_FOR_READY",
18953 		[WLAN_FORCE_DISABLE_STR] = "FORCE_DISABLE"
18954 	};
18955 
18956 	if (copy_from_user(buf, user_buf, sizeof(buf))) {
18957 		pr_err("Failed to read buffer\n");
18958 		return -EINVAL;
18959 	}
18960 
18961 	for (i = 0; i < ARRAY_SIZE(wlan_str); i++) {
18962 		if (qdf_str_ncmp(buf, wlan_str[i], strlen(wlan_str[i])) == 0)
18963 			return i;
18964 	}
18965 
18966 	return -EINVAL;
18967 }
18968 
18969 #ifdef FEATURE_CNSS_HW_SECURE_DISABLE
18970 #define WIFI_DISABLE_SLEEP (10)
18971 #define WIFI_DISABLE_MAX_RETRY_ATTEMPTS (10)
18972 static bool g_soft_unload;
18973 
hdd_get_wlan_driver_status(void)18974 bool hdd_get_wlan_driver_status(void)
18975 {
18976 	return g_soft_unload;
18977 }
18978 
hdd_wlan_soft_driver_load(void)18979 static int hdd_wlan_soft_driver_load(void)
18980 {
18981 	if (!cds_is_driver_loaded()) {
18982 		hdd_debug("\nEnabling CNSS WLAN HW");
18983 		pld_wlan_hw_enable();
18984 		return 0;
18985 	}
18986 
18987 	if (!g_soft_unload) {
18988 		hdd_debug_rl("Enabling WiFi\n");
18989 		return -EINVAL;
18990 	}
18991 
18992 	hdd_driver_load();
18993 	g_soft_unload = false;
18994 	return 0;
18995 }
18996 
hdd_wlan_soft_driver_unload(void)18997 static void hdd_wlan_soft_driver_unload(void)
18998 {
18999 	if (g_soft_unload) {
19000 		hdd_debug_rl("WiFi is already disabled");
19001 		return;
19002 	}
19003 	hdd_debug("Initiating soft driver unload\n");
19004 	g_soft_unload = true;
19005 	hdd_driver_unload();
19006 }
19007 
hdd_wlan_idle_shutdown(struct hdd_context * hdd_ctx)19008 static int hdd_wlan_idle_shutdown(struct hdd_context *hdd_ctx)
19009 {
19010 	int ret;
19011 	int retries = 0;
19012 	void *hif_ctx;
19013 
19014 	if (!hdd_ctx) {
19015 		hdd_err_rl("hdd_ctx is Null");
19016 		return -EINVAL;
19017 	}
19018 
19019 	hif_ctx = cds_get_context(QDF_MODULE_ID_HIF);
19020 
19021 	hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_IDLE_SHUTDOWN);
19022 
19023 	while (retries < WIFI_DISABLE_MAX_RETRY_ATTEMPTS) {
19024 		if (hif_ctx) {
19025 			/*
19026 			 * Trigger runtime sync resume before psoc_idle_shutdown
19027 			 * such that resume can happen successfully
19028 			 */
19029 			qdf_rtpm_sync_resume();
19030 		}
19031 		ret = pld_idle_shutdown(hdd_ctx->parent_dev,
19032 					hdd_psoc_idle_shutdown);
19033 
19034 		if (-EAGAIN == ret || hdd_ctx->is_wiphy_suspended) {
19035 			hdd_debug("System suspend in progress.Retries done:%d",
19036 				  retries);
19037 			msleep(WIFI_DISABLE_SLEEP);
19038 			retries++;
19039 			continue;
19040 		}
19041 		break;
19042 	}
19043 	hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_IDLE_SHUTDOWN);
19044 
19045 	if (retries > WIFI_DISABLE_MAX_RETRY_ATTEMPTS) {
19046 		hdd_debug("Max retries reached");
19047 		return -EINVAL;
19048 	}
19049 	hdd_debug_rl("WiFi is disabled");
19050 
19051 	return 0;
19052 }
19053 
hdd_disable_wifi(struct hdd_context * hdd_ctx)19054 static int hdd_disable_wifi(struct hdd_context *hdd_ctx)
19055 {
19056 	int ret;
19057 
19058 	if (hdd_ctx->is_wlan_disabled) {
19059 		hdd_err_rl("Wifi is already disabled");
19060 		return 0;
19061 	}
19062 
19063 	hdd_debug("Initiating WLAN idle shutdown");
19064 	if (hdd_is_any_interface_open(hdd_ctx)) {
19065 		hdd_err("Interfaces still open, cannot process wifi disable");
19066 		return -EAGAIN;
19067 	}
19068 
19069 	hdd_ctx->is_wlan_disabled = true;
19070 
19071 	ret = hdd_wlan_idle_shutdown(hdd_ctx);
19072 	if (ret)
19073 		hdd_ctx->is_wlan_disabled = false;
19074 
19075 	return ret;
19076 }
19077 #else
hdd_wlan_soft_driver_load(void)19078 static int hdd_wlan_soft_driver_load(void)
19079 {
19080 	return -EINVAL;
19081 }
19082 
hdd_wlan_soft_driver_unload(void)19083 static void hdd_wlan_soft_driver_unload(void)
19084 {
19085 }
19086 
hdd_disable_wifi(struct hdd_context * hdd_ctx)19087 static int hdd_disable_wifi(struct hdd_context *hdd_ctx)
19088 {
19089 	return 0;
19090 }
19091 #endif /* FEATURE_CNSS_HW_SECURE_DISABLE */
19092 
wlan_hdd_state_ctrl_param_write(struct file * filp,const char __user * user_buf,size_t count,loff_t * f_pos)19093 static ssize_t wlan_hdd_state_ctrl_param_write(struct file *filp,
19094 						const char __user *user_buf,
19095 						size_t count,
19096 						loff_t *f_pos)
19097 {
19098 	int id, ret;
19099 	unsigned long rc;
19100 	struct hdd_context *hdd_ctx;
19101 	bool is_wait_for_ready = false;
19102 	bool is_wlan_force_disabled;
19103 
19104 	hdd_enter();
19105 
19106 	id = hdd_validate_wlan_string(user_buf);
19107 
19108 	switch (id) {
19109 	case WLAN_OFF_STR:
19110 		hdd_info("Wifi turning off from UI\n");
19111 		hdd_inform_wifi_off();
19112 		goto exit;
19113 	case WLAN_ON_STR:
19114 		hdd_info("Wifi Turning On from UI\n");
19115 		break;
19116 	case WLAN_WAIT_FOR_READY_STR:
19117 		is_wait_for_ready = true;
19118 		hdd_info("Wifi wait for ready from UI\n");
19119 		break;
19120 	case WLAN_ENABLE_STR:
19121 		hdd_nofl_debug("Received WiFi enable from framework\n");
19122 		if (!hdd_wlan_soft_driver_load())
19123 			goto exit;
19124 		pr_info("Enabling WiFi\n");
19125 		break;
19126 	case WLAN_DISABLE_STR:
19127 		hdd_nofl_debug("Received WiFi disable from framework\n");
19128 		if (!cds_is_driver_loaded())
19129 			goto exit;
19130 
19131 		is_wlan_force_disabled = hdd_get_wlan_driver_status();
19132 		if (is_wlan_force_disabled)
19133 			goto exit;
19134 		pr_info("Disabling WiFi\n");
19135 		break;
19136 	case WLAN_FORCE_DISABLE_STR:
19137 		hdd_nofl_debug("Received Force WiFi disable from framework\n");
19138 		if (!cds_is_driver_loaded())
19139 			goto exit;
19140 
19141 		hdd_wlan_soft_driver_unload();
19142 		goto exit;
19143 	default:
19144 		hdd_err_rl("Invalid value received from framework");
19145 		return -EINVAL;
19146 	}
19147 
19148 	hdd_info("is_driver_loaded %d is_driver_recovering %d",
19149 		 cds_is_driver_loaded(), cds_is_driver_recovering());
19150 
19151 	if (!cds_is_driver_loaded() || cds_is_driver_recovering()) {
19152 		rc = wait_for_completion_timeout(&wlan_start_comp,
19153 				msecs_to_jiffies(HDD_WLAN_START_WAIT_TIME));
19154 		if (!rc) {
19155 			hdd_err("Driver Loading Timed-out!!");
19156 			ret = -EINVAL;
19157 			return ret;
19158 		}
19159 	}
19160 
19161 	if (is_wait_for_ready)
19162 		return count;
19163 	/*
19164 	 * Flush idle shutdown work for cases to synchronize the wifi on
19165 	 * during the idle shutdown.
19166 	 */
19167 	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
19168 	if (hdd_ctx)
19169 		hdd_psoc_idle_timer_stop(hdd_ctx);
19170 
19171 	if (id == WLAN_DISABLE_STR) {
19172 		if (!hdd_ctx) {
19173 			hdd_err_rl("hdd_ctx is Null");
19174 			goto exit;
19175 		}
19176 
19177 		ret = hdd_disable_wifi(hdd_ctx);
19178 		if (ret)
19179 			return ret;
19180 	}
19181 
19182 	if (id == WLAN_ENABLE_STR) {
19183 		if (!hdd_ctx) {
19184 			hdd_err_rl("hdd_ctx is Null");
19185 			goto exit;
19186 		}
19187 
19188 		if (!hdd_ctx->is_wlan_disabled) {
19189 			hdd_err_rl("WiFi is already enabled");
19190 			goto exit;
19191 		}
19192 		hdd_ctx->is_wlan_disabled = false;
19193 	}
19194 
19195 	if (id == WLAN_ON_STR)
19196 		hdd_inform_wifi_on();
19197 exit:
19198 	hdd_exit();
19199 	return count;
19200 }
19201 
19202 /**
19203  * wlan_hdd_state_ctrl_param_release() -  Release callback for /dev/wlan.
19204  *
19205  * @inode: struct inode pointer.
19206  * @file: struct file pointer.
19207  *
19208  * Release callback that would be invoked when the file operations has
19209  * completed fully. This is implemented to provide a reference count mechanism
19210  * via which the driver can wait till all possible usage of the /dev/wlan
19211  * file is completed.
19212  *
19213  * Return: Success
19214  */
wlan_hdd_state_ctrl_param_release(struct inode * inode,struct file * file)19215 static int wlan_hdd_state_ctrl_param_release(struct inode *inode,
19216 					     struct file *file)
19217 {
19218 	qdf_atomic_dec(&wlan_hdd_state_fops_ref);
19219 
19220 	return 0;
19221 }
19222 
19223 const struct file_operations wlan_hdd_state_fops = {
19224 	.owner = THIS_MODULE,
19225 	.open = wlan_hdd_state_ctrl_param_open,
19226 	.write = wlan_hdd_state_ctrl_param_write,
19227 	.release = wlan_hdd_state_ctrl_param_release,
19228 };
19229 
19230 #if (LINUX_VERSION_CODE < KERNEL_VERSION(6, 2, 0))
wlan_hdd_class_create(const char * name)19231 static struct class *wlan_hdd_class_create(const char *name)
19232 {
19233 	return class_create(THIS_MODULE, name);
19234 }
19235 #else
wlan_hdd_class_create(const char * name)19236 static struct class *wlan_hdd_class_create(const char *name)
19237 {
19238 	return class_create(name);
19239 }
19240 #endif
19241 
wlan_hdd_state_ctrl_param_create(void)19242 static int  wlan_hdd_state_ctrl_param_create(void)
19243 {
19244 	unsigned int wlan_hdd_state_major = 0;
19245 	int ret;
19246 	struct device *dev;
19247 
19248 	init_completion(&wlan_start_comp);
19249 	qdf_atomic_init(&wlan_hdd_state_fops_ref);
19250 
19251 	device = MKDEV(wlan_hdd_state_major, 0);
19252 
19253 	ret = alloc_chrdev_region(&device, 0, dev_num, "qcwlanstate");
19254 	if (ret) {
19255 		pr_err("Failed to register qcwlanstate");
19256 		goto dev_alloc_err;
19257 	}
19258 	wlan_hdd_state_major = MAJOR(device);
19259 	class = wlan_hdd_class_create(WLAN_CTRL_NAME);
19260 	if (IS_ERR(class)) {
19261 		pr_err("wlan_hdd_state class_create error");
19262 		goto class_err;
19263 	}
19264 
19265 	dev = device_create(class, NULL, device, NULL, WLAN_CTRL_NAME);
19266 	if (IS_ERR(dev)) {
19267 		pr_err("wlan_hdd_statedevice_create error");
19268 		goto err_class_destroy;
19269 	}
19270 
19271 	cdev_init(&wlan_hdd_state_cdev, &wlan_hdd_state_fops);
19272 
19273 	wlan_hdd_state_cdev.owner = THIS_MODULE;
19274 
19275 	ret = cdev_add(&wlan_hdd_state_cdev, device, dev_num);
19276 	if (ret) {
19277 		pr_err("Failed to add cdev error");
19278 		goto cdev_add_err;
19279 	}
19280 
19281 	pr_info("wlan_hdd_state %s major(%d) initialized",
19282 		WLAN_CTRL_NAME, wlan_hdd_state_major);
19283 
19284 	return 0;
19285 
19286 cdev_add_err:
19287 	device_destroy(class, device);
19288 err_class_destroy:
19289 	class_destroy(class);
19290 class_err:
19291 	unregister_chrdev_region(device, dev_num);
19292 dev_alloc_err:
19293 	return -ENODEV;
19294 }
19295 
19296 /*
19297  * When multiple instances of the driver are loaded in parallel, only
19298  * one can create and own the state ctrl param. An instance of the
19299  * driver that creates the state ctrl param will wait for
19300  * HDD_WLAN_START_WAIT_TIME to be probed. If it is probed, then that
19301  * instance of the driver will stay loaded and no other instances of
19302  * the driver can load. But if it is not probed, then that instance of
19303  * the driver will destroy the state ctrl param and exit, and another
19304  * instance of the driver can then create the state ctrl param.
19305  */
19306 
19307 /* max number of instances we expect (arbitrary) */
19308 #define WLAN_DRIVER_MAX_INSTANCES 5
19309 
19310 /* max amount of time an instance has to wait for all instances */
19311 #define CTRL_PARAM_WAIT (WLAN_DRIVER_MAX_INSTANCES * HDD_WLAN_START_WAIT_TIME)
19312 
19313 /* amount of time we sleep for each retry (arbitrary) */
19314 #define CTRL_PARAM_SLEEP 100
19315 
wlan_hdd_state_ctrl_param_destroy(void)19316 static void wlan_hdd_state_ctrl_param_destroy(void)
19317 {
19318 	cdev_del(&wlan_hdd_state_cdev);
19319 	device_destroy(class, device);
19320 	class_destroy(class);
19321 	unregister_chrdev_region(device, dev_num);
19322 
19323 	pr_info("Device node unregistered");
19324 }
19325 
19326 #else /* WLAN_CTRL_NAME */
19327 
wlan_hdd_state_ctrl_param_create(void)19328 static int wlan_hdd_state_ctrl_param_create(void)
19329 {
19330 	return 0;
19331 }
19332 
wlan_hdd_state_ctrl_param_destroy(void)19333 static void wlan_hdd_state_ctrl_param_destroy(void)
19334 {
19335 }
19336 
19337 #endif /* WLAN_CTRL_NAME */
19338 
19339 /**
19340  * hdd_send_scan_done_complete_cb() - API to send scan done indication to upper
19341  * layer
19342  * @vdev_id: vdev id
19343  *
19344  * Return: none
19345  */
hdd_send_scan_done_complete_cb(uint8_t vdev_id)19346 static void hdd_send_scan_done_complete_cb(uint8_t vdev_id)
19347 {
19348 	struct hdd_context *hdd_ctx;
19349 	struct wlan_hdd_link_info *link_info;
19350 	struct hdd_adapter *adapter;
19351 	struct sk_buff *vendor_event;
19352 	uint32_t len;
19353 
19354 	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
19355 	if (!hdd_ctx)
19356 		return;
19357 
19358 	link_info = hdd_get_link_info_by_vdev(hdd_ctx, vdev_id);
19359 	if (!link_info) {
19360 		hdd_err("Invalid vdev id:%d", vdev_id);
19361 		return;
19362 	}
19363 
19364 	adapter = link_info->adapter;
19365 	len = NLMSG_HDRLEN;
19366 	vendor_event =
19367 		wlan_cfg80211_vendor_event_alloc(
19368 			hdd_ctx->wiphy, &adapter->wdev, len,
19369 			QCA_NL80211_VENDOR_SUBCMD_CONNECTED_CHANNEL_STATS_INDEX,
19370 			GFP_KERNEL);
19371 
19372 	if (!vendor_event) {
19373 		hdd_err("wlan_cfg80211_vendor_event_alloc failed");
19374 		return;
19375 	}
19376 
19377 	hdd_debug("sending scan done ind to upper layer for vdev_id:%d",
19378 		  vdev_id);
19379 	wlan_cfg80211_vendor_event(vendor_event, GFP_KERNEL);
19380 }
19381 
19382 struct osif_vdev_mgr_ops osif_vdev_mgrlegacy_ops = {
19383 #ifdef WLAN_FEATURE_DYNAMIC_MAC_ADDR_UPDATE
19384 	.osif_vdev_mgr_set_mac_addr_response = hdd_set_mac_addr_event_cb,
19385 #endif
19386 	.osif_vdev_mgr_send_scan_done_complete_cb =
19387 					hdd_send_scan_done_complete_cb,
19388 
19389 };
19390 
hdd_vdev_mgr_register_cb(void)19391 static QDF_STATUS hdd_vdev_mgr_register_cb(void)
19392 {
19393 	osif_vdev_mgr_set_legacy_cb(&osif_vdev_mgrlegacy_ops);
19394 	return osif_vdev_mgr_register_cb();
19395 }
19396 
hdd_vdev_mgr_unregister_cb(void)19397 static void hdd_vdev_mgr_unregister_cb(void)
19398 {
19399 	osif_vdev_mgr_reset_legacy_cb();
19400 }
19401 
19402 /**
19403  * hdd_ll_sap_register_cb() - Register ll_sap osif callbacks
19404  *
19405  * Return: QDF_STATUS
19406  */
hdd_ll_sap_register_cb(void)19407 static QDF_STATUS hdd_ll_sap_register_cb(void)
19408 {
19409 	return osif_ll_sap_register_cb();
19410 }
19411 
19412 /**
19413  * hdd_ll_sap_unregister_cb() - Un-register ll_sap osif callbacks
19414  *
19415  * Return: void
19416  */
hdd_ll_sap_unregister_cb(void)19417 static void hdd_ll_sap_unregister_cb(void)
19418 {
19419 	osif_ll_sap_unregister_cb();
19420 }
19421 
19422 /**
19423  * hdd_component_cb_init() - Initialize component callbacks
19424  *
19425  * This function initializes hdd callbacks to different
19426  * components
19427  *
19428  * Context: Any context.
19429  * Return: QDF_STATUS
19430  */
hdd_component_cb_init(void)19431 static QDF_STATUS hdd_component_cb_init(void)
19432 {
19433 	QDF_STATUS status;
19434 
19435 	status = hdd_cm_register_cb();
19436 	if (QDF_IS_STATUS_ERROR(status))
19437 		return status;
19438 
19439 	status = hdd_vdev_mgr_register_cb();
19440 	if (QDF_IS_STATUS_ERROR(status))
19441 		goto cm_unregister_cb;
19442 
19443 	status = osif_twt_register_cb();
19444 	if (QDF_IS_STATUS_ERROR(status))
19445 		goto hdd_vdev_mgr_unregister_cb;
19446 
19447 	status = hdd_pre_cac_register_cb();
19448 	if (QDF_IS_STATUS_ERROR(status))
19449 		goto hdd_vdev_mgr_unregister_cb;
19450 
19451 	status = hdd_ll_sap_register_cb();
19452 	if (QDF_IS_STATUS_ERROR(status))
19453 		goto pre_cac_unregister_cb;
19454 
19455 	return QDF_STATUS_SUCCESS;
19456 
19457 pre_cac_unregister_cb:
19458 	hdd_pre_cac_unregister_cb();
19459 hdd_vdev_mgr_unregister_cb:
19460 	hdd_vdev_mgr_unregister_cb();
19461 cm_unregister_cb:
19462 	hdd_cm_unregister_cb();
19463 	return status;
19464 }
19465 
19466 /**
19467  * hdd_component_cb_deinit() - De-initialize component callbacks
19468  *
19469  * This function de-initializes hdd callbacks with different components
19470  *
19471  * Context: Any context.
19472  * Return: None`
19473  */
hdd_component_cb_deinit(void)19474 static void hdd_component_cb_deinit(void)
19475 {
19476 	hdd_ll_sap_unregister_cb();
19477 	hdd_pre_cac_unregister_cb();
19478 	hdd_vdev_mgr_unregister_cb();
19479 	hdd_cm_unregister_cb();
19480 }
19481 
19482 /**
19483  * hdd_component_init() - Initialize all components
19484  *
19485  * Return: QDF_STATUS
19486  */
hdd_component_init(void)19487 static QDF_STATUS hdd_component_init(void)
19488 {
19489 	QDF_STATUS status;
19490 
19491 	/* initialize converged components */
19492 
19493 	status = ucfg_mlme_global_init();
19494 	if (QDF_IS_STATUS_ERROR(status))
19495 		return status;
19496 
19497 	status = dispatcher_init();
19498 	if (QDF_IS_STATUS_ERROR(status))
19499 		goto mlme_global_deinit;
19500 
19501 	status = target_if_init(wma_get_psoc_from_scn_handle);
19502 	if (QDF_IS_STATUS_ERROR(status))
19503 		goto dispatcher_deinit;
19504 
19505 	/* initialize non-converged components */
19506 	status = ucfg_mlme_init();
19507 	if (QDF_IS_STATUS_ERROR(status))
19508 		goto target_if_deinit;
19509 
19510 	status = ucfg_fwol_init();
19511 	if (QDF_IS_STATUS_ERROR(status))
19512 		goto mlme_deinit;
19513 
19514 	status = disa_init();
19515 	if (QDF_IS_STATUS_ERROR(status))
19516 		goto fwol_deinit;
19517 
19518 	status = pmo_init();
19519 	if (QDF_IS_STATUS_ERROR(status))
19520 		goto disa_deinit;
19521 
19522 	status = ucfg_ocb_init();
19523 	if (QDF_IS_STATUS_ERROR(status))
19524 		goto pmo_deinit;
19525 
19526 	status = ipa_init();
19527 	if (QDF_IS_STATUS_ERROR(status))
19528 		goto ocb_deinit;
19529 
19530 	status = ucfg_action_oui_init();
19531 	if (QDF_IS_STATUS_ERROR(status))
19532 		goto ipa_deinit;
19533 
19534 	status = nan_init();
19535 	if (QDF_IS_STATUS_ERROR(status))
19536 		goto action_oui_deinit;
19537 
19538 	status = ucfg_p2p_init();
19539 	if (QDF_IS_STATUS_ERROR(status))
19540 		goto nan_deinit;
19541 
19542 	status = ucfg_interop_issues_ap_init();
19543 	if (QDF_IS_STATUS_ERROR(status))
19544 		goto p2p_deinit;
19545 
19546 	status = policy_mgr_init();
19547 	if (QDF_IS_STATUS_ERROR(status))
19548 		goto interop_issues_ap_deinit;
19549 
19550 	status = ucfg_tdls_init();
19551 	if (QDF_IS_STATUS_ERROR(status))
19552 		goto policy_deinit;
19553 
19554 	status = ucfg_dlm_init();
19555 	if (QDF_IS_STATUS_ERROR(status))
19556 		goto tdls_deinit;
19557 
19558 	status = ucfg_pkt_capture_init();
19559 	if (QDF_IS_STATUS_ERROR(status))
19560 		goto dlm_deinit;
19561 
19562 	status = ucfg_ftm_time_sync_init();
19563 	if (QDF_IS_STATUS_ERROR(status))
19564 		goto pkt_capture_deinit;
19565 
19566 	status = ucfg_pre_cac_init();
19567 	if (QDF_IS_STATUS_ERROR(status))
19568 		goto pre_cac_deinit;
19569 
19570 	status = ucfg_dp_init();
19571 	if (QDF_IS_STATUS_ERROR(status))
19572 		goto pre_cac_deinit;
19573 
19574 	status = ucfg_qmi_init();
19575 	if (QDF_IS_STATUS_ERROR(status))
19576 		goto dp_deinit;
19577 
19578 	status = ucfg_ll_sap_init();
19579 	if (QDF_IS_STATUS_ERROR(status))
19580 		goto qmi_deinit;
19581 
19582 	status = ucfg_afc_init();
19583 	if (QDF_IS_STATUS_ERROR(status))
19584 		goto ll_sap_deinit;
19585 
19586 	status = hdd_mlo_mgr_register_osif_ops();
19587 	if (QDF_IS_STATUS_ERROR(status))
19588 		goto afc_deinit;
19589 
19590 	hdd_register_cstats_ops();
19591 
19592 	return QDF_STATUS_SUCCESS;
19593 
19594 afc_deinit:
19595 	ucfg_afc_deinit();
19596 ll_sap_deinit:
19597 	ucfg_ll_sap_deinit();
19598 qmi_deinit:
19599 	ucfg_qmi_deinit();
19600 dp_deinit:
19601 	ucfg_dp_deinit();
19602 pre_cac_deinit:
19603 	ucfg_pre_cac_deinit();
19604 pkt_capture_deinit:
19605 	ucfg_pkt_capture_deinit();
19606 dlm_deinit:
19607 	ucfg_dlm_deinit();
19608 tdls_deinit:
19609 	ucfg_tdls_deinit();
19610 policy_deinit:
19611 	policy_mgr_deinit();
19612 interop_issues_ap_deinit:
19613 	ucfg_interop_issues_ap_deinit();
19614 p2p_deinit:
19615 	ucfg_p2p_deinit();
19616 nan_deinit:
19617 	nan_deinit();
19618 action_oui_deinit:
19619 	ucfg_action_oui_deinit();
19620 ipa_deinit:
19621 	ipa_deinit();
19622 ocb_deinit:
19623 	ucfg_ocb_deinit();
19624 pmo_deinit:
19625 	pmo_deinit();
19626 disa_deinit:
19627 	disa_deinit();
19628 fwol_deinit:
19629 	ucfg_fwol_deinit();
19630 mlme_deinit:
19631 	ucfg_mlme_deinit();
19632 target_if_deinit:
19633 	target_if_deinit();
19634 dispatcher_deinit:
19635 	dispatcher_deinit();
19636 mlme_global_deinit:
19637 	ucfg_mlme_global_deinit();
19638 
19639 	return status;
19640 }
19641 
19642 /**
19643  * hdd_component_deinit() - Deinitialize all components
19644  *
19645  * Return: None
19646  */
hdd_component_deinit(void)19647 static void hdd_component_deinit(void)
19648 {
19649 	/* deinitialize non-converged components */
19650 	hdd_mlo_mgr_unregister_osif_ops();
19651 	ucfg_afc_deinit();
19652 	ucfg_ll_sap_deinit();
19653 	ucfg_qmi_deinit();
19654 	ucfg_dp_deinit();
19655 	ucfg_pre_cac_deinit();
19656 	ucfg_ftm_time_sync_deinit();
19657 	ucfg_pkt_capture_deinit();
19658 	ucfg_dlm_deinit();
19659 	ucfg_tdls_deinit();
19660 	policy_mgr_deinit();
19661 	ucfg_interop_issues_ap_deinit();
19662 	ucfg_p2p_deinit();
19663 	nan_deinit();
19664 	ucfg_action_oui_deinit();
19665 	ipa_deinit();
19666 	ucfg_ocb_deinit();
19667 	pmo_deinit();
19668 	disa_deinit();
19669 	ucfg_fwol_deinit();
19670 	ucfg_mlme_deinit();
19671 
19672 	/* deinitialize converged components */
19673 	target_if_deinit();
19674 	dispatcher_deinit();
19675 	ucfg_mlme_global_deinit();
19676 }
19677 
hdd_component_psoc_open(struct wlan_objmgr_psoc * psoc)19678 QDF_STATUS hdd_component_psoc_open(struct wlan_objmgr_psoc *psoc)
19679 {
19680 	QDF_STATUS status;
19681 
19682 	status = ucfg_mlme_psoc_open(psoc);
19683 	if (QDF_IS_STATUS_ERROR(status))
19684 		return status;
19685 
19686 	status = ucfg_dlm_psoc_open(psoc);
19687 	if (QDF_IS_STATUS_ERROR(status))
19688 		goto err_dlm;
19689 
19690 	status = ucfg_fwol_psoc_open(psoc);
19691 	if (QDF_IS_STATUS_ERROR(status))
19692 		goto err_fwol;
19693 
19694 	status = ucfg_pmo_psoc_open(psoc);
19695 	if (QDF_IS_STATUS_ERROR(status))
19696 		goto err_pmo;
19697 
19698 	status = ucfg_policy_mgr_psoc_open(psoc);
19699 	if (QDF_IS_STATUS_ERROR(status))
19700 		goto err_plcy_mgr;
19701 
19702 	status = ucfg_p2p_psoc_open(psoc);
19703 	if (QDF_IS_STATUS_ERROR(status))
19704 		goto err_p2p;
19705 
19706 	status = ucfg_tdls_psoc_open(psoc);
19707 	if (QDF_IS_STATUS_ERROR(status))
19708 		goto err_tdls;
19709 
19710 	status = ucfg_nan_psoc_open(psoc);
19711 	if (QDF_IS_STATUS_ERROR(status))
19712 		goto err_nan;
19713 
19714 	status = ucfg_twt_psoc_open(psoc);
19715 	if (QDF_IS_STATUS_ERROR(status))
19716 		goto err_twt;
19717 
19718 	status = ucfg_wifi_pos_psoc_open(psoc);
19719 	if (QDF_IS_STATUS_ERROR(status))
19720 		goto err_wifi_pos;
19721 
19722 	status = ucfg_dp_psoc_open(psoc);
19723 	if (QDF_IS_STATUS_ERROR(status))
19724 		goto err_dp;
19725 
19726 	return status;
19727 
19728 err_dp:
19729 	ucfg_wifi_pos_psoc_close(psoc);
19730 err_wifi_pos:
19731 	ucfg_twt_psoc_close(psoc);
19732 err_twt:
19733 	ucfg_nan_psoc_close(psoc);
19734 err_nan:
19735 	ucfg_tdls_psoc_close(psoc);
19736 err_tdls:
19737 	ucfg_p2p_psoc_close(psoc);
19738 err_p2p:
19739 	ucfg_policy_mgr_psoc_close(psoc);
19740 err_plcy_mgr:
19741 	ucfg_pmo_psoc_close(psoc);
19742 err_pmo:
19743 	ucfg_fwol_psoc_close(psoc);
19744 err_fwol:
19745 	ucfg_dlm_psoc_close(psoc);
19746 err_dlm:
19747 	ucfg_mlme_psoc_close(psoc);
19748 
19749 	return status;
19750 }
19751 
hdd_component_psoc_close(struct wlan_objmgr_psoc * psoc)19752 void hdd_component_psoc_close(struct wlan_objmgr_psoc *psoc)
19753 {
19754 	ucfg_dp_psoc_close(psoc);
19755 	ucfg_wifi_pos_psoc_close(psoc);
19756 	ucfg_twt_psoc_close(psoc);
19757 	ucfg_nan_psoc_close(psoc);
19758 	ucfg_tdls_psoc_close(psoc);
19759 	ucfg_p2p_psoc_close(psoc);
19760 	ucfg_policy_mgr_psoc_close(psoc);
19761 	ucfg_pmo_psoc_close(psoc);
19762 	ucfg_fwol_psoc_close(psoc);
19763 	ucfg_dlm_psoc_close(psoc);
19764 	ucfg_mlme_psoc_close(psoc);
19765 
19766 	if (!cds_is_driver_recovering())
19767 		ucfg_crypto_flush_entries(psoc);
19768 }
19769 
hdd_component_psoc_enable(struct wlan_objmgr_psoc * psoc)19770 void hdd_component_psoc_enable(struct wlan_objmgr_psoc *psoc)
19771 {
19772 	ocb_psoc_enable(psoc);
19773 	disa_psoc_enable(psoc);
19774 	nan_psoc_enable(psoc);
19775 	p2p_psoc_enable(psoc);
19776 	ucfg_interop_issues_ap_psoc_enable(psoc);
19777 	policy_mgr_psoc_enable(psoc);
19778 	ucfg_tdls_psoc_enable(psoc);
19779 	ucfg_fwol_psoc_enable(psoc);
19780 	ucfg_action_oui_psoc_enable(psoc);
19781 	ucfg_ll_sap_psoc_enable(psoc);
19782 }
19783 
hdd_component_psoc_disable(struct wlan_objmgr_psoc * psoc)19784 void hdd_component_psoc_disable(struct wlan_objmgr_psoc *psoc)
19785 {
19786 	ucfg_ll_sap_psoc_disable(psoc);
19787 	ucfg_action_oui_psoc_disable(psoc);
19788 	ucfg_fwol_psoc_disable(psoc);
19789 	ucfg_tdls_psoc_disable(psoc);
19790 	policy_mgr_psoc_disable(psoc);
19791 	ucfg_interop_issues_ap_psoc_disable(psoc);
19792 	p2p_psoc_disable(psoc);
19793 	nan_psoc_disable(psoc);
19794 	disa_psoc_disable(psoc);
19795 	ocb_psoc_disable(psoc);
19796 }
19797 
hdd_component_pdev_open(struct wlan_objmgr_pdev * pdev)19798 QDF_STATUS hdd_component_pdev_open(struct wlan_objmgr_pdev *pdev)
19799 {
19800 	return ucfg_mlme_pdev_open(pdev);
19801 }
19802 
hdd_component_pdev_close(struct wlan_objmgr_pdev * pdev)19803 void hdd_component_pdev_close(struct wlan_objmgr_pdev *pdev)
19804 {
19805 	ucfg_mlme_pdev_close(pdev);
19806 }
19807 
hdd_qdf_print_init(void)19808 static QDF_STATUS hdd_qdf_print_init(void)
19809 {
19810 	QDF_STATUS status;
19811 	int qdf_print_idx;
19812 
19813 	status = qdf_print_setup();
19814 	if (QDF_IS_STATUS_ERROR(status)) {
19815 		pr_err("Failed qdf_print_setup; status:%u\n", status);
19816 		return status;
19817 	}
19818 
19819 	qdf_print_idx = qdf_print_ctrl_register(cinfo, NULL, NULL, "MCL_WLAN");
19820 	if (qdf_print_idx < 0) {
19821 		pr_err("Failed to register for qdf_print_ctrl\n");
19822 		return QDF_STATUS_E_FAILURE;
19823 	}
19824 
19825 	qdf_set_pidx(qdf_print_idx);
19826 
19827 	return QDF_STATUS_SUCCESS;
19828 }
19829 
hdd_qdf_print_deinit(void)19830 static void hdd_qdf_print_deinit(void)
19831 {
19832 	int qdf_pidx = qdf_get_pidx();
19833 
19834 	qdf_set_pidx(-1);
19835 	qdf_print_ctrl_cleanup(qdf_pidx);
19836 
19837 	/* currently, no qdf print 'un-setup'*/
19838 }
19839 
hdd_qdf_init(void)19840 static QDF_STATUS hdd_qdf_init(void)
19841 {
19842 	QDF_STATUS status;
19843 
19844 	status = hdd_qdf_print_init();
19845 	if (QDF_IS_STATUS_ERROR(status))
19846 		goto exit;
19847 
19848 	status = qdf_debugfs_init();
19849 	if (QDF_IS_STATUS_ERROR(status)) {
19850 		hdd_err("Failed to init debugfs; status:%u", status);
19851 		goto print_deinit;
19852 	}
19853 
19854 	qdf_lock_stats_init();
19855 	qdf_mem_init();
19856 	qdf_delayed_work_feature_init();
19857 	qdf_periodic_work_feature_init();
19858 	qdf_wake_lock_feature_init();
19859 	qdf_mc_timer_manager_init();
19860 	qdf_event_list_init();
19861 
19862 	status = qdf_talloc_feature_init();
19863 	if (QDF_IS_STATUS_ERROR(status)) {
19864 		hdd_err("Failed to init talloc; status:%u", status);
19865 		goto event_deinit;
19866 	}
19867 
19868 	status = qdf_cpuhp_init();
19869 	if (QDF_IS_STATUS_ERROR(status)) {
19870 		hdd_err("Failed to init cpuhp; status:%u", status);
19871 		goto talloc_deinit;
19872 	}
19873 
19874 	status = qdf_trace_spin_lock_init();
19875 	if (QDF_IS_STATUS_ERROR(status)) {
19876 		hdd_err("Failed to init spinlock; status:%u", status);
19877 		goto cpuhp_deinit;
19878 	}
19879 
19880 	qdf_trace_init();
19881 	qdf_minidump_init();
19882 	qdf_ssr_driver_dump_init();
19883 	qdf_register_debugcb_init();
19884 
19885 	return QDF_STATUS_SUCCESS;
19886 
19887 cpuhp_deinit:
19888 	qdf_cpuhp_deinit();
19889 talloc_deinit:
19890 	qdf_talloc_feature_deinit();
19891 event_deinit:
19892 	qdf_event_list_destroy();
19893 	qdf_mc_timer_manager_exit();
19894 	qdf_wake_lock_feature_deinit();
19895 	qdf_periodic_work_feature_deinit();
19896 	qdf_delayed_work_feature_deinit();
19897 	qdf_mem_exit();
19898 	qdf_lock_stats_deinit();
19899 	qdf_debugfs_exit();
19900 print_deinit:
19901 	hdd_qdf_print_deinit();
19902 
19903 exit:
19904 	return status;
19905 }
19906 
hdd_qdf_deinit(void)19907 static void hdd_qdf_deinit(void)
19908 {
19909 	/* currently, no debugcb deinit */
19910 	qdf_ssr_driver_dump_deinit();
19911 	qdf_minidump_deinit();
19912 	qdf_trace_deinit();
19913 
19914 	/* currently, no trace spinlock deinit */
19915 
19916 	qdf_cpuhp_deinit();
19917 	qdf_talloc_feature_deinit();
19918 	qdf_event_list_destroy();
19919 	qdf_mc_timer_manager_exit();
19920 	qdf_wake_lock_feature_deinit();
19921 	qdf_periodic_work_feature_deinit();
19922 	qdf_delayed_work_feature_deinit();
19923 	qdf_mem_exit();
19924 	qdf_lock_stats_deinit();
19925 	qdf_debugfs_exit();
19926 	hdd_qdf_print_deinit();
19927 }
19928 
19929 #ifdef FEATURE_MONITOR_MODE_SUPPORT
is_monitor_mode_supported(void)19930 static bool is_monitor_mode_supported(void)
19931 {
19932 	return true;
19933 }
19934 #else
is_monitor_mode_supported(void)19935 static bool is_monitor_mode_supported(void)
19936 {
19937 	pr_err("Monitor mode not supported!");
19938 	return false;
19939 }
19940 #endif
19941 
19942 #ifdef WLAN_FEATURE_EPPING
is_epping_mode_supported(void)19943 static bool is_epping_mode_supported(void)
19944 {
19945 	return true;
19946 }
19947 #else
is_epping_mode_supported(void)19948 static bool is_epping_mode_supported(void)
19949 {
19950 	pr_err("Epping mode not supported!");
19951 	return false;
19952 }
19953 #endif
19954 
19955 #ifdef QCA_WIFI_FTM
is_ftm_mode_supported(void)19956 static bool is_ftm_mode_supported(void)
19957 {
19958 	return true;
19959 }
19960 #else
is_ftm_mode_supported(void)19961 static bool is_ftm_mode_supported(void)
19962 {
19963 	pr_err("FTM mode not supported!");
19964 	return false;
19965 }
19966 #endif
19967 
19968 /**
19969  * is_con_mode_valid() - check con mode is valid or not
19970  * @mode: global con mode
19971  *
19972  * Return: TRUE on success FALSE on failure
19973  */
is_con_mode_valid(enum QDF_GLOBAL_MODE mode)19974 static bool is_con_mode_valid(enum QDF_GLOBAL_MODE mode)
19975 {
19976 	switch (mode) {
19977 	case QDF_GLOBAL_MONITOR_MODE:
19978 		return is_monitor_mode_supported();
19979 	case QDF_GLOBAL_EPPING_MODE:
19980 		return is_epping_mode_supported();
19981 	case QDF_GLOBAL_FTM_MODE:
19982 		return is_ftm_mode_supported();
19983 	case QDF_GLOBAL_MISSION_MODE:
19984 		return true;
19985 	default:
19986 		return false;
19987 	}
19988 }
19989 
hdd_stop_present_mode(struct hdd_context * hdd_ctx,enum QDF_GLOBAL_MODE curr_mode)19990 static void hdd_stop_present_mode(struct hdd_context *hdd_ctx,
19991 				  enum QDF_GLOBAL_MODE curr_mode)
19992 {
19993 	if (hdd_ctx->driver_status == DRIVER_MODULES_CLOSED)
19994 		return;
19995 
19996 	switch (curr_mode) {
19997 	case QDF_GLOBAL_MONITOR_MODE:
19998 		hdd_info("Release wakelock for monitor mode!");
19999 		qdf_wake_lock_release(&hdd_ctx->monitor_mode_wakelock,
20000 				      WIFI_POWER_EVENT_WAKELOCK_MONITOR_MODE);
20001 		fallthrough;
20002 	case QDF_GLOBAL_MISSION_MODE:
20003 	case QDF_GLOBAL_FTM_MODE:
20004 		hdd_abort_mac_scan_all_adapters(hdd_ctx);
20005 		wlan_cfg80211_cleanup_scan_queue(hdd_ctx->pdev, NULL);
20006 		hdd_stop_all_adapters(hdd_ctx);
20007 		hdd_deinit_all_adapters(hdd_ctx, false);
20008 
20009 		break;
20010 	default:
20011 		break;
20012 	}
20013 }
20014 
hdd_cleanup_present_mode(struct hdd_context * hdd_ctx,enum QDF_GLOBAL_MODE curr_mode)20015 static void hdd_cleanup_present_mode(struct hdd_context *hdd_ctx,
20016 				    enum QDF_GLOBAL_MODE curr_mode)
20017 {
20018 	switch (curr_mode) {
20019 	case QDF_GLOBAL_MISSION_MODE:
20020 	case QDF_GLOBAL_MONITOR_MODE:
20021 	case QDF_GLOBAL_FTM_MODE:
20022 		hdd_close_all_adapters(hdd_ctx, false);
20023 		break;
20024 	case QDF_GLOBAL_EPPING_MODE:
20025 		epping_disable();
20026 		epping_close();
20027 		break;
20028 	default:
20029 		return;
20030 	}
20031 }
20032 
20033 static int
hdd_parse_driver_mode(const char * mode_str,enum QDF_GLOBAL_MODE * out_mode)20034 hdd_parse_driver_mode(const char *mode_str, enum QDF_GLOBAL_MODE *out_mode)
20035 {
20036 	QDF_STATUS status;
20037 	uint32_t mode;
20038 
20039 	*out_mode = QDF_GLOBAL_MAX_MODE;
20040 
20041 	status = qdf_uint32_parse(mode_str, &mode);
20042 	if (QDF_IS_STATUS_ERROR(status))
20043 		return qdf_status_to_os_return(status);
20044 
20045 	if (mode >= QDF_GLOBAL_MAX_MODE)
20046 		return -ERANGE;
20047 
20048 	*out_mode = (enum QDF_GLOBAL_MODE)mode;
20049 
20050 	return 0;
20051 }
20052 
hdd_mode_change_psoc_idle_shutdown(struct device * dev)20053 static int hdd_mode_change_psoc_idle_shutdown(struct device *dev)
20054 {
20055 	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
20056 
20057 	if (!hdd_ctx)
20058 		return -EINVAL;
20059 
20060 	return hdd_wlan_stop_modules(hdd_ctx, true);
20061 }
20062 
hdd_mode_change_psoc_idle_restart(struct device * dev)20063 static int hdd_mode_change_psoc_idle_restart(struct device *dev)
20064 {
20065 	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
20066 	int ret;
20067 
20068 	if (!hdd_ctx)
20069 		return -EINVAL;
20070 	ret = hdd_soc_idle_restart_lock(dev);
20071 	if (ret)
20072 		return ret;
20073 	ret = hdd_wlan_start_modules(hdd_ctx, false);
20074 	hdd_soc_idle_restart_unlock();
20075 
20076 	return ret;
20077 }
20078 
20079 /**
20080  * __hdd_driver_mode_change() - Handles a driver mode change
20081  * @hdd_ctx: Pointer to the global HDD context
20082  * @next_mode: the driver mode to transition to
20083  *
20084  * This function is invoked when user updates con_mode using sys entry,
20085  * to initialize and bring-up driver in that specific mode.
20086  *
20087  * Return: Errno
20088  */
__hdd_driver_mode_change(struct hdd_context * hdd_ctx,enum QDF_GLOBAL_MODE next_mode)20089 static int __hdd_driver_mode_change(struct hdd_context *hdd_ctx,
20090 				    enum QDF_GLOBAL_MODE next_mode)
20091 {
20092 	enum QDF_GLOBAL_MODE curr_mode;
20093 	int errno;
20094 	struct bbm_params param = {0};
20095 
20096 	hdd_info("Driver mode changing to %d", next_mode);
20097 
20098 	errno = wlan_hdd_validate_context(hdd_ctx);
20099 	if (errno)
20100 		return errno;
20101 
20102 	if (!is_con_mode_valid(next_mode)) {
20103 		hdd_err_rl("Requested driver mode is invalid");
20104 		return -EINVAL;
20105 	}
20106 
20107 	curr_mode = hdd_get_conparam();
20108 	if (curr_mode == next_mode) {
20109 		hdd_err_rl("Driver is already in the requested mode");
20110 		return 0;
20111 	}
20112 
20113 	hdd_psoc_idle_timer_stop(hdd_ctx);
20114 
20115 	/* ensure adapters are stopped */
20116 	hdd_stop_present_mode(hdd_ctx, curr_mode);
20117 
20118 	if (DRIVER_MODULES_CLOSED != hdd_ctx->driver_status) {
20119 		is_mode_change_psoc_idle_shutdown = true;
20120 		errno = pld_idle_shutdown(hdd_ctx->parent_dev,
20121 					  hdd_mode_change_psoc_idle_shutdown);
20122 		if (errno) {
20123 			is_mode_change_psoc_idle_shutdown = false;
20124 			hdd_err("Stop wlan modules failed");
20125 			return errno;
20126 		}
20127 	}
20128 
20129 	/* Cleanup present mode before switching to new mode */
20130 	hdd_cleanup_present_mode(hdd_ctx, curr_mode);
20131 
20132 	hdd_set_conparam(next_mode);
20133 	pld_set_mode(next_mode);
20134 
20135 	qdf_event_reset(&hdd_ctx->regulatory_update_event);
20136 	qdf_mutex_acquire(&hdd_ctx->regulatory_status_lock);
20137 	hdd_ctx->is_regulatory_update_in_progress = true;
20138 	qdf_mutex_release(&hdd_ctx->regulatory_status_lock);
20139 
20140 	errno = pld_idle_restart(hdd_ctx->parent_dev,
20141 				 hdd_mode_change_psoc_idle_restart);
20142 	if (errno) {
20143 		hdd_err("Start wlan modules failed: %d", errno);
20144 		return errno;
20145 	}
20146 
20147 	errno = hdd_open_adapters_for_mode(hdd_ctx, next_mode);
20148 	if (errno) {
20149 		hdd_err("Failed to open adapters");
20150 		return errno;
20151 	}
20152 
20153 	if (next_mode == QDF_GLOBAL_MONITOR_MODE) {
20154 		struct hdd_adapter *adapter =
20155 			hdd_get_adapter(hdd_ctx, QDF_MONITOR_MODE);
20156 
20157 		QDF_BUG(adapter);
20158 		if (!adapter) {
20159 			hdd_err("Failed to get monitor adapter");
20160 			return -EINVAL;
20161 		}
20162 
20163 		errno = hdd_start_adapter(adapter, false);
20164 		if (errno) {
20165 			hdd_err("Failed to start monitor adapter");
20166 			return errno;
20167 		}
20168 
20169 		hdd_info("Acquire wakelock for monitor mode");
20170 		qdf_wake_lock_acquire(&hdd_ctx->monitor_mode_wakelock,
20171 				      WIFI_POWER_EVENT_WAKELOCK_MONITOR_MODE);
20172 	}
20173 
20174 	/* con_mode is a global module parameter */
20175 	con_mode = next_mode;
20176 	hdd_info("Driver mode successfully changed to %d", next_mode);
20177 
20178 	param.policy = BBM_DRIVER_MODE_POLICY;
20179 	param.policy_info.driver_mode = con_mode;
20180 	ucfg_dp_bbm_apply_independent_policy(hdd_ctx->psoc, &param);
20181 
20182 	return 0;
20183 }
20184 
hdd_pre_mode_change(enum QDF_GLOBAL_MODE mode)20185 static void hdd_pre_mode_change(enum QDF_GLOBAL_MODE mode)
20186 {
20187 	struct osif_psoc_sync *psoc_sync;
20188 	struct hdd_context *hdd_ctx;
20189 	int errno;
20190 	enum QDF_GLOBAL_MODE curr_mode;
20191 
20192 	curr_mode = hdd_get_conparam();
20193 	if (curr_mode != QDF_GLOBAL_MISSION_MODE)
20194 		return;
20195 
20196 	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
20197 	errno = wlan_hdd_validate_context(hdd_ctx);
20198 	if (errno)
20199 		return;
20200 
20201 	errno = osif_psoc_sync_op_start(hdd_ctx->parent_dev, &psoc_sync);
20202 	if (errno) {
20203 		hdd_err("psoc op start failed");
20204 		return;
20205 	}
20206 
20207 	hdd_debug("cleanup scan queue");
20208 	if (hdd_ctx && hdd_ctx->pdev)
20209 		wlan_cfg80211_cleanup_scan_queue(hdd_ctx->pdev, NULL);
20210 
20211 	osif_psoc_sync_op_stop(psoc_sync);
20212 }
20213 
hdd_driver_mode_change(enum QDF_GLOBAL_MODE mode)20214 static int hdd_driver_mode_change(enum QDF_GLOBAL_MODE mode)
20215 {
20216 	struct osif_driver_sync *driver_sync;
20217 	struct hdd_context *hdd_ctx;
20218 	QDF_STATUS status;
20219 	int errno;
20220 
20221 	hdd_enter();
20222 
20223 	hdd_pre_mode_change(mode);
20224 
20225 	status = osif_driver_sync_trans_start_wait(&driver_sync);
20226 	if (QDF_IS_STATUS_ERROR(status)) {
20227 		hdd_err("Failed to start 'mode change'; status:%u", status);
20228 		errno = qdf_status_to_os_return(status);
20229 		goto exit;
20230 	}
20231 
20232 	osif_driver_sync_wait_for_ops(driver_sync);
20233 
20234 	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
20235 	errno = wlan_hdd_validate_context(hdd_ctx);
20236 	if (errno)
20237 		goto trans_stop;
20238 
20239 	errno = __hdd_driver_mode_change(hdd_ctx, mode);
20240 
20241 trans_stop:
20242 	osif_driver_sync_trans_stop(driver_sync);
20243 
20244 exit:
20245 	hdd_exit();
20246 
20247 	return errno;
20248 }
20249 
hdd_set_con_mode(enum QDF_GLOBAL_MODE mode)20250 static int hdd_set_con_mode(enum QDF_GLOBAL_MODE mode)
20251 {
20252 	con_mode = mode;
20253 
20254 	return 0;
20255 }
20256 
20257 static int (*hdd_set_con_mode_cb)(enum QDF_GLOBAL_MODE mode) = hdd_set_con_mode;
20258 
hdd_driver_mode_change_register(void)20259 static void hdd_driver_mode_change_register(void)
20260 {
20261 	hdd_set_con_mode_cb = hdd_driver_mode_change;
20262 }
20263 
hdd_driver_mode_change_unregister(void)20264 static void hdd_driver_mode_change_unregister(void)
20265 {
20266 	hdd_set_con_mode_cb = hdd_set_con_mode;
20267 }
20268 
con_mode_handler(const char * kmessage,const struct kernel_param * kp)20269 static int con_mode_handler(const char *kmessage, const struct kernel_param *kp)
20270 {
20271 	enum QDF_GLOBAL_MODE mode;
20272 	int errno;
20273 
20274 	errno = hdd_parse_driver_mode(kmessage, &mode);
20275 	if (errno) {
20276 		hdd_err_rl("Failed to parse driver mode '%s'", kmessage);
20277 		return errno;
20278 	}
20279 
20280 	return hdd_set_con_mode_cb(mode);
20281 }
20282 
20283 /*
20284  * If the wlan_hdd_register_driver will return an error
20285  * if the wlan driver tries to register with the
20286  * platform driver before cnss_probe is completed.
20287  * Depending on the error code, the wlan driver waits
20288  * and retries to register.
20289  */
20290 
20291 /* Max number of retries (arbitrary)*/
20292 #define HDD_MAX_PLD_REGISTER_RETRY (50)
20293 
20294 /* Max amount of time we sleep before each retry */
20295 #define HDD_PLD_REGISTER_FAIL_SLEEP_DURATION (100)
20296 
hdd_register_driver_retry(void)20297 static int hdd_register_driver_retry(void)
20298 {
20299 	int count = 0;
20300 	int errno;
20301 
20302 	while (true) {
20303 		errno = wlan_hdd_register_driver();
20304 		if (errno != -EAGAIN)
20305 			return errno;
20306 		hdd_nofl_info("Retry Platform Driver Registration; errno:%d count:%d",
20307 			      errno, count);
20308 		if (++count == HDD_MAX_PLD_REGISTER_RETRY)
20309 			return errno;
20310 		msleep(HDD_PLD_REGISTER_FAIL_SLEEP_DURATION);
20311 		continue;
20312 	}
20313 
20314 	return errno;
20315 }
20316 
20317 /**
20318  * hdd_create_wifi_feature_interface() - Create wifi feature interface
20319  *
20320  * Return: none
20321  */
hdd_create_wifi_feature_interface(void)20322 static void hdd_create_wifi_feature_interface(void)
20323 {
20324 	hdd_sysfs_create_wifi_root_obj();
20325 	hdd_create_wifi_feature_interface_sysfs_file();
20326 }
20327 
hdd_driver_load(void)20328 int hdd_driver_load(void)
20329 {
20330 	struct osif_driver_sync *driver_sync;
20331 	QDF_STATUS status;
20332 	int errno;
20333 	bool soft_load;
20334 
20335 	pr_info("%s: Loading driver v%s\n", WLAN_MODULE_NAME,
20336 		g_wlan_driver_version);
20337 	hdd_place_marker(NULL, "START LOADING", NULL);
20338 
20339 	status = hdd_qdf_init();
20340 	if (QDF_IS_STATUS_ERROR(status)) {
20341 		errno = qdf_status_to_os_return(status);
20342 		goto exit;
20343 	}
20344 
20345 	osif_sync_init();
20346 
20347 	status = osif_driver_sync_create_and_trans(&driver_sync);
20348 	if (QDF_IS_STATUS_ERROR(status)) {
20349 		hdd_err("Failed to init driver sync; status:%u", status);
20350 		errno = qdf_status_to_os_return(status);
20351 		goto sync_deinit;
20352 	}
20353 
20354 	errno = hdd_init();
20355 	if (errno) {
20356 		hdd_err("Failed to init HDD; errno:%d", errno);
20357 		goto trans_stop;
20358 	}
20359 
20360 	status = hdd_component_cb_init();
20361 	if (QDF_IS_STATUS_ERROR(status)) {
20362 		hdd_err("Failed to init component cb; status:%u", status);
20363 		errno = qdf_status_to_os_return(status);
20364 		goto hdd_deinit;
20365 	}
20366 
20367 	status = hdd_component_init();
20368 	if (QDF_IS_STATUS_ERROR(status)) {
20369 		hdd_err("Failed to init components; status:%u", status);
20370 		errno = qdf_status_to_os_return(status);
20371 		goto comp_cb_deinit;
20372 	}
20373 
20374 	status = qdf_wake_lock_create(&wlan_wake_lock, "wlan");
20375 	if (QDF_IS_STATUS_ERROR(status)) {
20376 		hdd_err("Failed to create wake lock; status:%u", status);
20377 		errno = qdf_status_to_os_return(status);
20378 		goto comp_deinit;
20379 	}
20380 
20381 	hdd_set_conparam(con_mode);
20382 
20383 	errno = pld_init();
20384 	if (errno) {
20385 		hdd_err("Failed to init PLD; errno:%d", errno);
20386 		goto wakelock_destroy;
20387 	}
20388 
20389 	/* driver mode pass to cnss2 platform driver*/
20390 	errno = pld_set_mode(con_mode);
20391 	if (errno)
20392 		hdd_err("Failed to set mode in PLD; errno:%d", errno);
20393 
20394 	hdd_driver_mode_change_register();
20395 
20396 	osif_driver_sync_register(driver_sync);
20397 	osif_driver_sync_trans_stop(driver_sync);
20398 
20399 	/* psoc probe can happen in registration; do after 'load' transition */
20400 	errno = hdd_register_driver_retry();
20401 	if (errno) {
20402 		hdd_err("Failed to register driver; errno:%d", errno);
20403 		goto pld_deinit;
20404 	}
20405 
20406 	/* If a soft unload of driver is done, we don't call
20407 	 * wlan_hdd_state_ctrl_param_destroy() to maintain sync
20408 	 * with userspace. In Symmetry, during soft load, avoid
20409 	 * calling wlan_hdd_state_ctrl_param_create().
20410 	 */
20411 	soft_load = hdd_get_wlan_driver_status();
20412 	if (soft_load)
20413 		goto out;
20414 
20415 	errno = wlan_hdd_state_ctrl_param_create();
20416 	if (errno) {
20417 		hdd_err("Failed to create ctrl param; errno:%d", errno);
20418 		goto unregister_driver;
20419 	}
20420 	hdd_create_wifi_feature_interface();
20421 out:
20422 	hdd_debug("%s: driver loaded", WLAN_MODULE_NAME);
20423 	hdd_place_marker(NULL, "DRIVER LOADED", NULL);
20424 
20425 	return 0;
20426 
20427 unregister_driver:
20428 	wlan_hdd_unregister_driver();
20429 pld_deinit:
20430 	status = osif_driver_sync_trans_start(&driver_sync);
20431 	QDF_BUG(QDF_IS_STATUS_SUCCESS(status));
20432 
20433 	osif_driver_sync_unregister();
20434 	if (driver_sync)
20435 		osif_driver_sync_wait_for_ops(driver_sync);
20436 
20437 	hdd_driver_mode_change_unregister();
20438 	pld_deinit();
20439 
20440 	hdd_start_complete(errno);
20441 	/* Wait for any ref taken on /dev/wlan to be released */
20442 	while (qdf_atomic_read(&wlan_hdd_state_fops_ref))
20443 		;
20444 wakelock_destroy:
20445 	qdf_wake_lock_destroy(&wlan_wake_lock);
20446 comp_deinit:
20447 	hdd_component_deinit();
20448 comp_cb_deinit:
20449 	hdd_component_cb_deinit();
20450 hdd_deinit:
20451 	hdd_deinit();
20452 trans_stop:
20453 	if (driver_sync) {
20454 		osif_driver_sync_trans_stop(driver_sync);
20455 		osif_driver_sync_destroy(driver_sync);
20456 	}
20457 sync_deinit:
20458 	osif_sync_deinit();
20459 	hdd_qdf_deinit();
20460 
20461 exit:
20462 	return errno;
20463 }
20464 
20465 #ifdef FEATURE_WLAN_RESIDENT_DRIVER
20466 EXPORT_SYMBOL(hdd_driver_load);
20467 #endif
20468 
20469 /**
20470  * hdd_distroy_wifi_feature_interface() - Distroy wifi feature interface
20471  *
20472  * Return: none
20473  */
hdd_distroy_wifi_feature_interface(void)20474 static void hdd_distroy_wifi_feature_interface(void)
20475 {
20476 	hdd_destroy_wifi_feature_interface_sysfs_file();
20477 	hdd_sysfs_destroy_wifi_root_obj();
20478 }
20479 
hdd_driver_unload(void)20480 void hdd_driver_unload(void)
20481 {
20482 	struct osif_driver_sync *driver_sync;
20483 	struct hdd_context *hdd_ctx;
20484 	QDF_STATUS status;
20485 	void *hif_ctx;
20486 	bool soft_unload;
20487 
20488 	soft_unload = hdd_get_wlan_driver_status();
20489 	if (soft_unload) {
20490 		pr_info("%s: Soft Unloading driver v%s\n", WLAN_MODULE_NAME,
20491 			QWLAN_VERSIONSTR);
20492 	} else {
20493 		pr_info("%s: Hard Unloading driver v%s\n", WLAN_MODULE_NAME,
20494 			QWLAN_VERSIONSTR);
20495 	}
20496 
20497 	hdd_place_marker(NULL, "START UNLOADING", NULL);
20498 
20499 	/*
20500 	 * Wait for any trans to complete and then start the driver trans
20501 	 * for the unload. This will ensure that the driver trans proceeds only
20502 	 * after all trans have been completed. As a part of this trans, set
20503 	 * the driver load/unload flag to further ensure that any upcoming
20504 	 * trans are rejected via wlan_hdd_validate_context.
20505 	 */
20506 	status = osif_driver_sync_trans_start_wait(&driver_sync);
20507 	if (QDF_IS_STATUS_ERROR(status) && status != -ETIMEDOUT) {
20508 		QDF_BUG(QDF_IS_STATUS_SUCCESS(status));
20509 		hdd_err("Unable to unload wlan; status:%u", status);
20510 		hdd_place_marker(NULL, "UNLOAD FAILURE", NULL);
20511 		return;
20512 	}
20513 
20514 	hif_ctx = cds_get_context(QDF_MODULE_ID_HIF);
20515 	if (hif_ctx) {
20516 		/*
20517 		 * Trigger runtime sync resume before setting unload in progress
20518 		 * such that resume can happen successfully
20519 		 */
20520 		qdf_rtpm_sync_resume();
20521 	}
20522 
20523 	cds_set_driver_loaded(false);
20524 	cds_set_unload_in_progress(true);
20525 
20526 	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
20527 	if (hdd_ctx) {
20528 		hdd_psoc_idle_timer_stop(hdd_ctx);
20529 		/*
20530 		 * Runtime PM sync resume may have started the bus bandwidth
20531 		 * periodic work hence stop it.
20532 		 */
20533 		ucfg_dp_bus_bw_compute_timer_stop(hdd_ctx->psoc);
20534 	}
20535 
20536 	/*
20537 	 * Stop the trans before calling unregister_driver as that involves a
20538 	 * call to pld_remove which in itself is a psoc transaction
20539 	 */
20540 	if (driver_sync)
20541 		osif_driver_sync_trans_stop(driver_sync);
20542 
20543 	hdd_distroy_wifi_feature_interface();
20544 	if (!soft_unload)
20545 		wlan_hdd_state_ctrl_param_destroy();
20546 
20547 	/* trigger SoC remove */
20548 	wlan_hdd_unregister_driver();
20549 
20550 	status = osif_driver_sync_trans_start_wait(&driver_sync);
20551 	if (QDF_IS_STATUS_ERROR(status) && status != -ETIMEDOUT) {
20552 		QDF_BUG(QDF_IS_STATUS_SUCCESS(status));
20553 		hdd_err("Unable to unload wlan; status:%u", status);
20554 		hdd_place_marker(NULL, "UNLOAD FAILURE", NULL);
20555 		return;
20556 	}
20557 
20558 	osif_driver_sync_unregister();
20559 	if (driver_sync)
20560 		osif_driver_sync_wait_for_ops(driver_sync);
20561 
20562 	hdd_driver_mode_change_unregister();
20563 	pld_deinit();
20564 	hdd_set_conparam(0);
20565 	qdf_wake_lock_destroy(&wlan_wake_lock);
20566 	hdd_component_deinit();
20567 	hdd_component_cb_deinit();
20568 	hdd_deinit();
20569 
20570 	if (driver_sync) {
20571 		osif_driver_sync_trans_stop(driver_sync);
20572 		osif_driver_sync_destroy(driver_sync);
20573 	}
20574 	osif_sync_deinit();
20575 
20576 	hdd_qdf_deinit();
20577 	hdd_place_marker(NULL, "UNLOAD DONE", NULL);
20578 }
20579 
20580 #ifdef FEATURE_WLAN_RESIDENT_DRIVER
20581 EXPORT_SYMBOL(hdd_driver_unload);
20582 #endif
20583 
20584 #ifndef MODULE
20585 /**
20586  * wlan_boot_cb() - Wlan boot callback
20587  * @kobj:      object whose directory we're creating the link in.
20588  * @attr:      attribute the user is interacting with
20589  * @buf:       the buffer containing the user data
20590  * @count:     number of bytes in the buffer
20591  *
20592  * This callback is invoked when the fs is ready to start the
20593  * wlan driver initialization.
20594  *
20595  * Return: 'count' on success or a negative error code in case of failure
20596  */
wlan_boot_cb(struct kobject * kobj,struct kobj_attribute * attr,const char * buf,size_t count)20597 static ssize_t wlan_boot_cb(struct kobject *kobj,
20598 			    struct kobj_attribute *attr,
20599 			    const char *buf,
20600 			    size_t count)
20601 {
20602 
20603 	if (wlan_loader->loaded_state) {
20604 		hdd_err("wlan driver already initialized");
20605 		return -EALREADY;
20606 	}
20607 
20608 	if (hdd_driver_load())
20609 		return -EIO;
20610 
20611 	wlan_loader->loaded_state = MODULE_INITIALIZED;
20612 
20613 	return count;
20614 }
20615 
20616 /**
20617  * hdd_sysfs_cleanup() - cleanup sysfs
20618  *
20619  * Return: None
20620  *
20621  */
hdd_sysfs_cleanup(void)20622 static void hdd_sysfs_cleanup(void)
20623 {
20624 	/* remove from group */
20625 	if (wlan_loader->boot_wlan_obj && wlan_loader->attr_group)
20626 		sysfs_remove_group(wlan_loader->boot_wlan_obj,
20627 				   wlan_loader->attr_group);
20628 
20629 	/* unlink the object from parent */
20630 	kobject_del(wlan_loader->boot_wlan_obj);
20631 
20632 	/* free the object */
20633 	kobject_put(wlan_loader->boot_wlan_obj);
20634 
20635 	kfree(wlan_loader->attr_group);
20636 	kfree(wlan_loader);
20637 
20638 	wlan_loader = NULL;
20639 }
20640 
20641 /**
20642  * wlan_init_sysfs() - Creates the sysfs to be invoked when the fs is
20643  * ready
20644  *
20645  * This is creates the syfs entry boot_wlan. Which shall be invoked
20646  * when the filesystem is ready.
20647  *
20648  * QDF API cannot be used here since this function is called even before
20649  * initializing WLAN driver.
20650  *
20651  * Return: 0 for success, errno on failure
20652  */
wlan_init_sysfs(void)20653 static int wlan_init_sysfs(void)
20654 {
20655 	int ret = -ENOMEM;
20656 
20657 	wlan_loader = kzalloc(sizeof(*wlan_loader), GFP_KERNEL);
20658 	if (!wlan_loader)
20659 		return -ENOMEM;
20660 
20661 	wlan_loader->boot_wlan_obj = NULL;
20662 	wlan_loader->attr_group = kzalloc(sizeof(*(wlan_loader->attr_group)),
20663 					  GFP_KERNEL);
20664 	if (!wlan_loader->attr_group)
20665 		goto error_return;
20666 
20667 	wlan_loader->loaded_state = 0;
20668 	wlan_loader->attr_group->attrs = attrs;
20669 
20670 	wlan_loader->boot_wlan_obj = kobject_create_and_add(WLAN_LOADER_NAME,
20671 							    kernel_kobj);
20672 	if (!wlan_loader->boot_wlan_obj) {
20673 		hdd_err("sysfs create and add failed");
20674 		goto error_return;
20675 	}
20676 
20677 	ret = sysfs_create_group(wlan_loader->boot_wlan_obj,
20678 				 wlan_loader->attr_group);
20679 	if (ret) {
20680 		hdd_err("sysfs create group failed; errno:%d", ret);
20681 		goto error_return;
20682 	}
20683 
20684 	return 0;
20685 
20686 error_return:
20687 	hdd_sysfs_cleanup();
20688 
20689 	return ret;
20690 }
20691 
20692 /**
20693  * wlan_deinit_sysfs() - Removes the sysfs created to initialize the wlan
20694  *
20695  * Return: 0 on success or errno on failure
20696  */
wlan_deinit_sysfs(void)20697 static int wlan_deinit_sysfs(void)
20698 {
20699 	if (!wlan_loader) {
20700 		hdd_err("wlan_loader is null");
20701 		return -EINVAL;
20702 	}
20703 
20704 	hdd_sysfs_cleanup();
20705 	return 0;
20706 }
20707 
20708 #endif /* MODULE */
20709 
20710 #ifdef MODULE
20711 /**
20712  * hdd_module_init() - Module init helper
20713  *
20714  * Module init helper function used by both module and static driver.
20715  *
20716  * Return: 0 for success, errno on failure
20717  */
20718 #ifdef FEATURE_WLAN_RESIDENT_DRIVER
hdd_module_init(void)20719 static int hdd_module_init(void)
20720 {
20721 	return 0;
20722 }
20723 #else
hdd_module_init(void)20724 static int hdd_module_init(void)
20725 {
20726 	if (hdd_driver_load())
20727 		return -EINVAL;
20728 
20729 	return 0;
20730 }
20731 #endif
20732 #else
hdd_module_init(void)20733 static int __init hdd_module_init(void)
20734 {
20735 	int ret = -EINVAL;
20736 
20737 	ret = wlan_init_sysfs();
20738 	if (ret)
20739 		hdd_err("Failed to create sysfs entry");
20740 
20741 	return ret;
20742 }
20743 #endif
20744 
20745 
20746 #ifdef MODULE
20747 /**
20748  * hdd_module_exit() - Exit function
20749  *
20750  * This is the driver exit point (invoked when module is unloaded using rmmod)
20751  *
20752  * Return: None
20753  */
20754 #ifdef FEATURE_WLAN_RESIDENT_DRIVER
hdd_module_exit(void)20755 static void __exit hdd_module_exit(void)
20756 {
20757 }
20758 #else
hdd_module_exit(void)20759 static void __exit hdd_module_exit(void)
20760 {
20761 	hdd_driver_unload();
20762 }
20763 #endif
20764 #else
hdd_module_exit(void)20765 static void __exit hdd_module_exit(void)
20766 {
20767 	hdd_driver_unload();
20768 	wlan_deinit_sysfs();
20769 }
20770 #endif
20771 
fwpath_changed_handler(const char * kmessage,const struct kernel_param * kp)20772 static int fwpath_changed_handler(const char *kmessage,
20773 				  const struct kernel_param *kp)
20774 {
20775 	return param_set_copystring(kmessage, kp);
20776 }
20777 
con_mode_handler_ftm(const char * kmessage,const struct kernel_param * kp)20778 static int con_mode_handler_ftm(const char *kmessage,
20779 				const struct kernel_param *kp)
20780 {
20781 	int ret;
20782 
20783 	ret = param_set_int(kmessage, kp);
20784 
20785 	if (cds_is_driver_loaded() || cds_is_load_or_unload_in_progress()) {
20786 		pr_err("Driver already loaded or load/unload in progress");
20787 		return -ENOTSUPP;
20788 	}
20789 
20790 	if (con_mode_ftm != QDF_GLOBAL_FTM_MODE) {
20791 		pr_err("Only FTM mode supported!");
20792 		return -ENOTSUPP;
20793 	}
20794 
20795 	hdd_set_conparam(con_mode_ftm);
20796 	con_mode = con_mode_ftm;
20797 
20798 	return ret;
20799 }
20800 
20801 #ifdef WLAN_FEATURE_EPPING
con_mode_handler_epping(const char * kmessage,const struct kernel_param * kp)20802 static int con_mode_handler_epping(const char *kmessage,
20803 				   const struct kernel_param *kp)
20804 {
20805 	int ret;
20806 
20807 	ret = param_set_int(kmessage, kp);
20808 
20809 	if (con_mode_epping != QDF_GLOBAL_EPPING_MODE) {
20810 		pr_err("Only EPPING mode supported!");
20811 		return -ENOTSUPP;
20812 	}
20813 
20814 	hdd_set_conparam(con_mode_epping);
20815 	con_mode = con_mode_epping;
20816 
20817 	return ret;
20818 }
20819 #endif
20820 
20821 /**
20822  * hdd_get_conparam() - driver exit point
20823  *
20824  * This is the driver exit point (invoked when module is unloaded using rmmod)
20825  *
20826  * Return: enum QDF_GLOBAL_MODE
20827  */
hdd_get_conparam(void)20828 enum QDF_GLOBAL_MODE hdd_get_conparam(void)
20829 {
20830 	return (enum QDF_GLOBAL_MODE) curr_con_mode;
20831 }
20832 
hdd_set_conparam(int32_t con_param)20833 void hdd_set_conparam(int32_t con_param)
20834 {
20835 	curr_con_mode = con_param;
20836 }
20837 
20838 /**
20839  * hdd_svc_fw_crashed_ind() - API to send FW CRASHED IND to Userspace
20840  *
20841  * Return: void
20842  */
hdd_svc_fw_crashed_ind(void)20843 static void hdd_svc_fw_crashed_ind(void)
20844 {
20845 	struct hdd_context *hdd_ctx;
20846 
20847 	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
20848 
20849 	hdd_ctx ? wlan_hdd_send_svc_nlink_msg(hdd_ctx->radio_index,
20850 					      WLAN_SVC_FW_CRASHED_IND,
20851 					      NULL, 0) : 0;
20852 }
20853 
20854 /**
20855  * hdd_update_ol_config - API to update ol configuration parameters
20856  * @hdd_ctx: HDD context
20857  *
20858  * Return: void
20859  */
hdd_update_ol_config(struct hdd_context * hdd_ctx)20860 static void hdd_update_ol_config(struct hdd_context *hdd_ctx)
20861 {
20862 	struct ol_config_info cfg = {0};
20863 	struct ol_context *ol_ctx = cds_get_context(QDF_MODULE_ID_BMI);
20864 	bool self_recovery = false;
20865 	QDF_STATUS status;
20866 
20867 	if (!ol_ctx)
20868 		return;
20869 
20870 	status = ucfg_mlme_get_self_recovery(hdd_ctx->psoc, &self_recovery);
20871 	if (QDF_IS_STATUS_ERROR(status))
20872 		hdd_err("Failed to get self recovery ini config");
20873 
20874 	cfg.enable_self_recovery = self_recovery;
20875 	cfg.enable_uart_print = hdd_ctx->config->enablefwprint;
20876 	cfg.enable_fw_log = hdd_ctx->config->enable_fw_log;
20877 	cfg.enable_ramdump_collection = hdd_ctx->config->is_ramdump_enabled;
20878 	cfg.enable_lpass_support = hdd_lpass_is_supported(hdd_ctx);
20879 
20880 	ol_init_ini_config(ol_ctx, &cfg);
20881 	ol_set_fw_crashed_cb(ol_ctx, hdd_svc_fw_crashed_ind);
20882 }
20883 
20884 #ifdef FEATURE_RUNTIME_PM
20885 /**
20886  * hdd_populate_runtime_cfg() - populate runtime configuration
20887  * @hdd_ctx: hdd context
20888  * @cfg: pointer to the configuration memory being populated
20889  *
20890  * Return: void
20891  */
hdd_populate_runtime_cfg(struct hdd_context * hdd_ctx,struct hif_config_info * cfg)20892 static void hdd_populate_runtime_cfg(struct hdd_context *hdd_ctx,
20893 				     struct hif_config_info *cfg)
20894 {
20895 	cfg->enable_runtime_pm = hdd_ctx->config->runtime_pm;
20896 	cfg->runtime_pm_delay =
20897 		ucfg_pmo_get_runtime_pm_delay(hdd_ctx->psoc);
20898 }
20899 #else
hdd_populate_runtime_cfg(struct hdd_context * hdd_ctx,struct hif_config_info * cfg)20900 static void hdd_populate_runtime_cfg(struct hdd_context *hdd_ctx,
20901 				     struct hif_config_info *cfg)
20902 {
20903 }
20904 #endif
20905 
20906 #ifdef FEATURE_ENABLE_CE_DP_IRQ_AFFINE
20907 /**
20908  * hdd_populate_ce_dp_irq_affine_cfg() - populate ce irq affine configuration
20909  * @hdd_ctx: hdd context
20910  * @cfg: pointer to the configuration memory being populated
20911  *
20912  * Return: void
20913  */
hdd_populate_ce_dp_irq_affine_cfg(struct hdd_context * hdd_ctx,struct hif_config_info * cfg)20914 static void hdd_populate_ce_dp_irq_affine_cfg(struct hdd_context *hdd_ctx,
20915 					      struct hif_config_info *cfg)
20916 {
20917 	cfg->enable_ce_dp_irq_affine = cfg_get(hdd_ctx->psoc,
20918 					       CFG_ENABLE_CE_DP_IRQ_AFFINE);
20919 }
20920 #else
hdd_populate_ce_dp_irq_affine_cfg(struct hdd_context * hdd_ctx,struct hif_config_info * cfg)20921 static void hdd_populate_ce_dp_irq_affine_cfg(struct hdd_context *hdd_ctx,
20922 					      struct hif_config_info *cfg)
20923 {
20924 }
20925 #endif
20926 
20927 /**
20928  * hdd_update_hif_config - API to update HIF configuration parameters
20929  * @hdd_ctx: HDD Context
20930  *
20931  * Return: void
20932  */
hdd_update_hif_config(struct hdd_context * hdd_ctx)20933 static void hdd_update_hif_config(struct hdd_context *hdd_ctx)
20934 {
20935 	struct hif_opaque_softc *scn = cds_get_context(QDF_MODULE_ID_HIF);
20936 	struct hif_config_info cfg = {0};
20937 	bool prevent_link_down = false;
20938 	bool self_recovery = false;
20939 	QDF_STATUS status;
20940 
20941 	if (!scn)
20942 		return;
20943 
20944 	status = ucfg_mlme_get_prevent_link_down(hdd_ctx->psoc,
20945 						 &prevent_link_down);
20946 	if (QDF_IS_STATUS_ERROR(status))
20947 		hdd_err("Failed to get prevent_link_down config");
20948 
20949 	status = ucfg_mlme_get_self_recovery(hdd_ctx->psoc, &self_recovery);
20950 	if (QDF_IS_STATUS_ERROR(status))
20951 		hdd_err("Failed to get self recovery ini config");
20952 
20953 	cfg.enable_self_recovery = self_recovery;
20954 	hdd_populate_runtime_cfg(hdd_ctx, &cfg);
20955 	cfg.rx_softirq_max_yield_duration_ns =
20956 		ucfg_dp_get_rx_softirq_yield_duration(hdd_ctx->psoc);
20957 	hdd_populate_ce_dp_irq_affine_cfg(hdd_ctx, &cfg);
20958 
20959 	hif_init_ini_config(scn, &cfg);
20960 	hif_set_enable_rpm(scn);
20961 
20962 	if (prevent_link_down)
20963 		hif_vote_link_up(scn);
20964 }
20965 
20966 /**
20967  * hdd_update_dp_config() - Propagate config parameters to Lithium
20968  *                          datapath
20969  * @hdd_ctx: HDD Context
20970  *
20971  * Return: 0 for success/errno for failure
20972  */
hdd_update_dp_config(struct hdd_context * hdd_ctx)20973 static int hdd_update_dp_config(struct hdd_context *hdd_ctx)
20974 {
20975 	struct wlan_dp_user_config dp_cfg;
20976 	QDF_STATUS status;
20977 
20978 	dp_cfg.ipa_enable = ucfg_ipa_is_enabled();
20979 	dp_cfg.arp_connectivity_map = CONNECTIVITY_CHECK_SET_ARP;
20980 
20981 	status = ucfg_dp_update_config(hdd_ctx->psoc, &dp_cfg);
20982 	if (status != QDF_STATUS_SUCCESS) {
20983 		hdd_err("failed DP PSOC configuration update");
20984 		return -EINVAL;
20985 	}
20986 
20987 	return 0;
20988 }
20989 
20990 /**
20991  * hdd_update_config() - Initialize driver per module ini parameters
20992  * @hdd_ctx: HDD Context
20993  *
20994  * API is used to initialize all driver per module configuration parameters
20995  * Return: 0 for success, errno for failure
20996  */
hdd_update_config(struct hdd_context * hdd_ctx)20997 int hdd_update_config(struct hdd_context *hdd_ctx)
20998 {
20999 	int ret;
21000 
21001 	if (ucfg_pmo_is_ns_offloaded(hdd_ctx->psoc))
21002 		hdd_ctx->ns_offload_enable = true;
21003 
21004 	hdd_update_ol_config(hdd_ctx);
21005 	hdd_update_hif_config(hdd_ctx);
21006 	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam())
21007 		ret = hdd_update_cds_config_ftm(hdd_ctx);
21008 	else
21009 		ret = hdd_update_cds_config(hdd_ctx);
21010 	ret = hdd_update_user_config(hdd_ctx);
21011 
21012 	hdd_update_regdb_offload_config(hdd_ctx);
21013 
21014 	return ret;
21015 }
21016 
21017 /**
21018  * hdd_update_pmo_config - API to update pmo configuration parameters
21019  * @hdd_ctx: HDD context
21020  *
21021  * Return: void
21022  */
hdd_update_pmo_config(struct hdd_context * hdd_ctx)21023 static int hdd_update_pmo_config(struct hdd_context *hdd_ctx)
21024 {
21025 	struct pmo_psoc_cfg psoc_cfg = {0};
21026 	QDF_STATUS status;
21027 	enum pmo_wow_enable_type wow_enable;
21028 
21029 	ucfg_pmo_get_psoc_config(hdd_ctx->psoc, &psoc_cfg);
21030 
21031 	/*
21032 	 * Value of hdd_ctx->wowEnable can be,
21033 	 * 0 - Disable both magic pattern match and pattern byte match.
21034 	 * 1 - Enable magic pattern match on all interfaces.
21035 	 * 2 - Enable pattern byte match on all interfaces.
21036 	 * 3 - Enable both magic pattern and pattern byte match on
21037 	 *     all interfaces.
21038 	 */
21039 	wow_enable = ucfg_pmo_get_wow_enable(hdd_ctx->psoc);
21040 	psoc_cfg.magic_ptrn_enable = (wow_enable & 0x01) ? true : false;
21041 	psoc_cfg.ptrn_match_enable_all_vdev =
21042 				(wow_enable & 0x02) ? true : false;
21043 	psoc_cfg.ap_arpns_support = hdd_ctx->ap_arpns_support;
21044 	psoc_cfg.d0_wow_supported = wma_d0_wow_is_supported();
21045 	ucfg_mlme_get_sap_max_modulated_dtim(hdd_ctx->psoc,
21046 					     &psoc_cfg.sta_max_li_mod_dtim);
21047 
21048 	hdd_lpass_populate_pmo_config(&psoc_cfg, hdd_ctx);
21049 
21050 	status = ucfg_pmo_update_psoc_config(hdd_ctx->psoc, &psoc_cfg);
21051 	if (QDF_IS_STATUS_ERROR(status))
21052 		hdd_err("failed pmo psoc configuration; status:%d", status);
21053 
21054 	return qdf_status_to_os_return(status);
21055 }
21056 
hdd_update_ie_allowlist_attr(struct probe_req_allowlist_attr * ie_allowlist,struct hdd_context * hdd_ctx)21057 void hdd_update_ie_allowlist_attr(struct probe_req_allowlist_attr *ie_allowlist,
21058 				  struct hdd_context *hdd_ctx)
21059 {
21060 	struct wlan_fwol_ie_allowlist allowlist = {0};
21061 	struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc;
21062 	QDF_STATUS status;
21063 	bool is_ie_allowlist_enable = false;
21064 	uint8_t i = 0;
21065 
21066 	status = ucfg_fwol_get_ie_allowlist(psoc, &is_ie_allowlist_enable);
21067 	if (QDF_IS_STATUS_ERROR(status)) {
21068 		hdd_err("Unable to get IE allowlist param");
21069 		return;
21070 	}
21071 
21072 	ie_allowlist->allow_list = is_ie_allowlist_enable;
21073 	if (!ie_allowlist->allow_list)
21074 		return;
21075 
21076 	status = ucfg_fwol_get_all_allowlist_params(psoc, &allowlist);
21077 	if (QDF_IS_STATUS_ERROR(status)) {
21078 		hdd_err("Unable to get all allowlist params");
21079 		return;
21080 	}
21081 
21082 	ie_allowlist->ie_bitmap[0] = allowlist.ie_bitmap_0;
21083 	ie_allowlist->ie_bitmap[1] = allowlist.ie_bitmap_1;
21084 	ie_allowlist->ie_bitmap[2] = allowlist.ie_bitmap_2;
21085 	ie_allowlist->ie_bitmap[3] = allowlist.ie_bitmap_3;
21086 	ie_allowlist->ie_bitmap[4] = allowlist.ie_bitmap_4;
21087 	ie_allowlist->ie_bitmap[5] = allowlist.ie_bitmap_5;
21088 	ie_allowlist->ie_bitmap[6] = allowlist.ie_bitmap_6;
21089 	ie_allowlist->ie_bitmap[7] = allowlist.ie_bitmap_7;
21090 
21091 	ie_allowlist->num_vendor_oui = allowlist.no_of_probe_req_ouis;
21092 	for (i = 0; i < ie_allowlist->num_vendor_oui; i++)
21093 		ie_allowlist->voui[i] = allowlist.probe_req_voui[i];
21094 }
21095 
hdd_update_score_config(struct hdd_context * hdd_ctx)21096 QDF_STATUS hdd_update_score_config(struct hdd_context *hdd_ctx)
21097 {
21098 	struct hdd_config *cfg = hdd_ctx->config;
21099 	eCsrPhyMode phy_mode = hdd_cfg_xlate_to_csr_phy_mode(cfg->dot11Mode);
21100 
21101 	sme_update_score_config(hdd_ctx->mac_handle, phy_mode,
21102 				hdd_ctx->num_rf_chains);
21103 
21104 	return QDF_STATUS_SUCCESS;
21105 }
21106 
21107 /**
21108  * hdd_update_dfs_config() - API to update dfs configuration parameters.
21109  * @hdd_ctx: HDD context
21110  *
21111  * Return: 0 if success else err
21112  */
hdd_update_dfs_config(struct hdd_context * hdd_ctx)21113 static int hdd_update_dfs_config(struct hdd_context *hdd_ctx)
21114 {
21115 	struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc;
21116 	struct dfs_user_config dfs_cfg = {0};
21117 	QDF_STATUS status;
21118 
21119 	ucfg_mlme_get_dfs_filter_offload(hdd_ctx->psoc,
21120 					 &dfs_cfg.dfs_is_phyerr_filter_offload);
21121 	status = ucfg_dfs_update_config(psoc, &dfs_cfg);
21122 	if (QDF_IS_STATUS_ERROR(status)) {
21123 		hdd_err("failed dfs psoc configuration");
21124 		return -EINVAL;
21125 	}
21126 
21127 	return 0;
21128 }
21129 
21130 /**
21131  * hdd_update_scan_config - API to update scan configuration parameters
21132  * @hdd_ctx: HDD context
21133  *
21134  * Return: 0 if success else err
21135  */
hdd_update_scan_config(struct hdd_context * hdd_ctx)21136 int hdd_update_scan_config(struct hdd_context *hdd_ctx)
21137 {
21138 	struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc;
21139 	struct scan_user_cfg scan_cfg;
21140 	QDF_STATUS status;
21141 	uint32_t mcast_mcc_rest_time = 0;
21142 
21143 	qdf_mem_zero(&scan_cfg, sizeof(scan_cfg));
21144 	status = ucfg_mlme_get_sta_miracast_mcc_rest_time(hdd_ctx->psoc,
21145 							  &mcast_mcc_rest_time);
21146 	if (!QDF_IS_STATUS_SUCCESS(status)) {
21147 		hdd_err("ucfg_mlme_get_sta_miracast_mcc_rest_time, use def");
21148 		return -EIO;
21149 	}
21150 	scan_cfg.sta_miracast_mcc_rest_time = mcast_mcc_rest_time;
21151 	hdd_update_ie_allowlist_attr(&scan_cfg.ie_allowlist, hdd_ctx);
21152 
21153 	status = ucfg_scan_update_user_config(psoc, &scan_cfg);
21154 	if (status != QDF_STATUS_SUCCESS) {
21155 		hdd_err("failed pmo psoc configuration");
21156 		return -EINVAL;
21157 	}
21158 
21159 	return 0;
21160 }
21161 
hdd_update_components_config(struct hdd_context * hdd_ctx)21162 int hdd_update_components_config(struct hdd_context *hdd_ctx)
21163 {
21164 	int ret;
21165 
21166 	ret = hdd_update_pmo_config(hdd_ctx);
21167 	if (ret)
21168 		return ret;
21169 
21170 	ret = hdd_update_scan_config(hdd_ctx);
21171 	if (ret)
21172 		return ret;
21173 
21174 	ret = hdd_update_tdls_config(hdd_ctx);
21175 	if (ret)
21176 		return ret;
21177 
21178 	ret = hdd_update_dp_config(hdd_ctx);
21179 	if (ret)
21180 		return ret;
21181 
21182 	ret = hdd_update_dfs_config(hdd_ctx);
21183 	if (ret)
21184 		return ret;
21185 
21186 	ret = hdd_update_regulatory_config(hdd_ctx);
21187 	if (ret)
21188 		return ret;
21189 
21190 	return ret;
21191 }
21192 
21193 /**
21194  * wlan_hdd_get_dfs_mode() - get ACS DFS mode
21195  * @mode : cfg80211 DFS mode
21196  *
21197  * Return: return SAP ACS DFS mode else return ACS_DFS_MODE_NONE
21198  */
wlan_hdd_get_dfs_mode(enum dfs_mode mode)21199 enum  sap_acs_dfs_mode wlan_hdd_get_dfs_mode(enum dfs_mode mode)
21200 {
21201 	switch (mode) {
21202 	case DFS_MODE_ENABLE:
21203 		return ACS_DFS_MODE_ENABLE;
21204 	case DFS_MODE_DISABLE:
21205 		return ACS_DFS_MODE_DISABLE;
21206 	case DFS_MODE_DEPRIORITIZE:
21207 		return ACS_DFS_MODE_DEPRIORITIZE;
21208 	default:
21209 		hdd_debug("ACS dfs mode is NONE");
21210 		return ACS_DFS_MODE_NONE;
21211 	}
21212 }
21213 
21214 /**
21215  * hdd_enable_disable_ca_event() - enable/disable channel avoidance event
21216  * @hdd_ctx: pointer to hdd context
21217  * @set_value: enable/disable
21218  *
21219  * When Host sends vendor command enable, FW will send *ONE* CA ind to
21220  * Host(even though it is duplicate). When Host send vendor command
21221  * disable,FW doesn't perform any action. Whenever any change in
21222  * CA *and* WLAN is in SAP/P2P-GO mode, FW sends CA ind to host.
21223  *
21224  * return - 0 on success, appropriate error values on failure.
21225  */
hdd_enable_disable_ca_event(struct hdd_context * hdd_ctx,uint8_t set_value)21226 int hdd_enable_disable_ca_event(struct hdd_context *hdd_ctx, uint8_t set_value)
21227 {
21228 	QDF_STATUS status;
21229 
21230 	if (0 != wlan_hdd_validate_context(hdd_ctx))
21231 		return -EAGAIN;
21232 
21233 	status = sme_enable_disable_chanavoidind_event(hdd_ctx->mac_handle,
21234 						       set_value);
21235 	if (!QDF_IS_STATUS_SUCCESS(status)) {
21236 		hdd_err("Failed to send chan avoid command to SME");
21237 		return -EINVAL;
21238 	}
21239 	return 0;
21240 }
21241 
hdd_is_roaming_in_progress(struct hdd_context * hdd_ctx)21242 bool hdd_is_roaming_in_progress(struct hdd_context *hdd_ctx)
21243 {
21244 	struct hdd_adapter *adapter = NULL, *next_adapter = NULL;
21245 	uint8_t vdev_id;
21246 	wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_IS_ROAMING_IN_PROGRESS;
21247 	struct wlan_hdd_link_info *link_info;
21248 
21249 	if (!hdd_ctx) {
21250 		hdd_err("HDD context is NULL");
21251 		return false;
21252 	}
21253 
21254 	if (!policy_mgr_is_sta_active_connection_exists(hdd_ctx->psoc))
21255 		return false;
21256 
21257 	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
21258 					   dbgid) {
21259 		if (adapter->device_mode != QDF_STA_MODE)
21260 			goto adapter_put;
21261 
21262 		hdd_adapter_for_each_active_link_info(adapter, link_info) {
21263 			vdev_id = link_info->vdev_id;
21264 			if (test_bit(SME_SESSION_OPENED,
21265 				     &link_info->link_flags) &&
21266 			    sme_roaming_in_progress(hdd_ctx->mac_handle,
21267 						    vdev_id)) {
21268 				hdd_debug("Roaming is in progress on:vdev_id:%d",
21269 					  link_info->vdev_id);
21270 				hdd_adapter_dev_put_debug(adapter, dbgid);
21271 				if (next_adapter)
21272 					hdd_adapter_dev_put_debug(next_adapter,
21273 								  dbgid);
21274 				return true;
21275 			}
21276 		}
21277 adapter_put:
21278 		hdd_adapter_dev_put_debug(adapter, dbgid);
21279 	}
21280 
21281 	return false;
21282 }
21283 
21284 /**
21285  * struct hdd_is_connection_in_progress_priv - adapter connection info
21286  * @out_vdev_id: id of vdev where connection is occurring
21287  * @out_reason: scan reject reason
21288  * @connection_in_progress: true if connection is in progress
21289  */
21290 struct hdd_is_connection_in_progress_priv {
21291 	uint8_t out_vdev_id;
21292 	enum scan_reject_states out_reason;
21293 	bool connection_in_progress;
21294 };
21295 
21296 /**
21297  * hdd_is_connection_in_progress_iterator() - Check adapter connection based
21298  * on device mode
21299  * @link_info: Link info pointer in HDD adapter
21300  * @ctx: user context supplied
21301  *
21302  * Check if connection is in progress for the current adapter according to the
21303  * device mode
21304  *
21305  * Return:
21306  * * QDF_STATUS_SUCCESS if iteration should continue
21307  * * QDF_STATUS_E_ABORTED if iteration should be aborted
21308  */
21309 static QDF_STATUS
hdd_is_connection_in_progress_iterator(struct wlan_hdd_link_info * link_info,void * ctx)21310 hdd_is_connection_in_progress_iterator(struct wlan_hdd_link_info *link_info,
21311 				       void *ctx)
21312 {
21313 	struct hdd_station_ctx *hdd_sta_ctx;
21314 	uint8_t *sta_mac;
21315 	struct hdd_context *hdd_ctx;
21316 	mac_handle_t mac_handle;
21317 	struct hdd_station_info *sta_info, *tmp = NULL;
21318 	struct hdd_is_connection_in_progress_priv *context = ctx;
21319 	struct hdd_adapter *adapter = link_info->adapter;
21320 
21321 	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
21322 	if (!hdd_ctx)
21323 		return QDF_STATUS_E_ABORTED;
21324 
21325 	mac_handle = hdd_ctx->mac_handle;
21326 
21327 	if (!test_bit(SME_SESSION_OPENED, &link_info->link_flags) &&
21328 	    (adapter->device_mode == QDF_STA_MODE ||
21329 	     adapter->device_mode == QDF_P2P_CLIENT_MODE ||
21330 	     adapter->device_mode == QDF_P2P_DEVICE_MODE ||
21331 	     adapter->device_mode == QDF_P2P_GO_MODE ||
21332 	     adapter->device_mode == QDF_SAP_MODE))
21333 		return QDF_STATUS_SUCCESS;
21334 
21335 	if ((QDF_STA_MODE == adapter->device_mode ||
21336 	     QDF_P2P_CLIENT_MODE == adapter->device_mode ||
21337 	     QDF_P2P_DEVICE_MODE == adapter->device_mode) &&
21338 	    hdd_cm_is_connecting(link_info)) {
21339 		hdd_debug("%pK(%d) mode %d Connection is in progress",
21340 			  WLAN_HDD_GET_STATION_CTX_PTR(link_info),
21341 			  link_info->vdev_id, adapter->device_mode);
21342 
21343 		context->out_vdev_id = link_info->vdev_id;
21344 		context->out_reason = CONNECTION_IN_PROGRESS;
21345 		context->connection_in_progress = true;
21346 
21347 		return QDF_STATUS_E_ABORTED;
21348 	}
21349 
21350 	if ((QDF_STA_MODE == adapter->device_mode) &&
21351 	     sme_roaming_in_progress(mac_handle, link_info->vdev_id)) {
21352 		hdd_debug("%pK(%d) mode %d Reassociation in progress",
21353 			  WLAN_HDD_GET_STATION_CTX_PTR(link_info),
21354 			  link_info->vdev_id, adapter->device_mode);
21355 
21356 		context->out_vdev_id = link_info->vdev_id;
21357 		context->out_reason = REASSOC_IN_PROGRESS;
21358 		context->connection_in_progress = true;
21359 		return QDF_STATUS_E_ABORTED;
21360 	}
21361 
21362 	if ((QDF_STA_MODE == adapter->device_mode) ||
21363 		(QDF_P2P_CLIENT_MODE == adapter->device_mode) ||
21364 		(QDF_P2P_DEVICE_MODE == adapter->device_mode)) {
21365 		hdd_sta_ctx =
21366 			WLAN_HDD_GET_STATION_CTX_PTR(link_info);
21367 		if (hdd_cm_is_vdev_associated(link_info)
21368 		    && sme_is_sta_key_exchange_in_progress(
21369 		    mac_handle, link_info->vdev_id)) {
21370 			sta_mac = (uint8_t *)&(adapter->mac_addr.bytes[0]);
21371 			hdd_debug("client " QDF_MAC_ADDR_FMT
21372 				  " is in middle of WPS/EAPOL exchange.",
21373 				  QDF_MAC_ADDR_REF(sta_mac));
21374 
21375 			context->out_vdev_id = link_info->vdev_id;
21376 			context->out_reason = EAPOL_IN_PROGRESS;
21377 			context->connection_in_progress = true;
21378 
21379 			return QDF_STATUS_E_ABORTED;
21380 		}
21381 	} else if ((QDF_SAP_MODE == adapter->device_mode) ||
21382 			(QDF_P2P_GO_MODE == adapter->device_mode)) {
21383 		hdd_for_each_sta_ref_safe(adapter->sta_info_list, sta_info, tmp,
21384 				     STA_INFO_CONNECTION_IN_PROGRESS_ITERATOR) {
21385 			if (sta_info->peer_state !=
21386 				OL_TXRX_PEER_STATE_CONN) {
21387 				hdd_put_sta_info_ref(
21388 				     &adapter->sta_info_list, &sta_info, true,
21389 				     STA_INFO_CONNECTION_IN_PROGRESS_ITERATOR);
21390 				continue;
21391 			}
21392 
21393 			sta_mac = sta_info->sta_mac.bytes;
21394 			hdd_debug("client " QDF_MAC_ADDR_FMT
21395 				  " of SAP/GO is in middle of WPS/EAPOL exchange",
21396 				  QDF_MAC_ADDR_REF(sta_mac));
21397 
21398 			context->out_vdev_id = link_info->vdev_id;
21399 			context->out_reason = SAP_EAPOL_IN_PROGRESS;
21400 			context->connection_in_progress = true;
21401 
21402 			hdd_put_sta_info_ref(
21403 				&adapter->sta_info_list, &sta_info, true,
21404 				STA_INFO_CONNECTION_IN_PROGRESS_ITERATOR);
21405 			if (tmp)
21406 				hdd_put_sta_info_ref(
21407 				    &adapter->sta_info_list, &tmp, true,
21408 				    STA_INFO_CONNECTION_IN_PROGRESS_ITERATOR);
21409 
21410 			return QDF_STATUS_E_ABORTED;
21411 		}
21412 		if (hdd_ctx->connection_in_progress) {
21413 			hdd_debug("AP/GO: vdev %d connection is in progress",
21414 				  link_info->vdev_id);
21415 			context->out_reason = SAP_CONNECTION_IN_PROGRESS;
21416 			context->out_vdev_id = link_info->vdev_id;
21417 			context->connection_in_progress = true;
21418 
21419 			return QDF_STATUS_E_ABORTED;
21420 		}
21421 	}
21422 
21423 	if (ucfg_nan_is_enable_disable_in_progress(hdd_ctx->psoc)) {
21424 		context->out_reason = NAN_ENABLE_DISABLE_IN_PROGRESS;
21425 		context->out_vdev_id = NAN_PSEUDO_VDEV_ID;
21426 		context->connection_in_progress = true;
21427 
21428 		return QDF_STATUS_E_ABORTED;
21429 	}
21430 
21431 	return QDF_STATUS_SUCCESS;
21432 }
21433 
hdd_is_connection_in_progress(uint8_t * out_vdev_id,enum scan_reject_states * out_reason)21434 bool hdd_is_connection_in_progress(uint8_t *out_vdev_id,
21435 				   enum scan_reject_states *out_reason)
21436 {
21437 	struct hdd_is_connection_in_progress_priv hdd_conn;
21438 	hdd_adapter_iterate_cb cb;
21439 
21440 	hdd_conn.out_vdev_id = 0;
21441 	hdd_conn.out_reason = SCAN_REJECT_DEFAULT;
21442 	hdd_conn.connection_in_progress = false;
21443 
21444 	cb = hdd_is_connection_in_progress_iterator;
21445 
21446 	hdd_adapter_iterate(cb, &hdd_conn);
21447 
21448 	if (hdd_conn.connection_in_progress && out_vdev_id && out_reason) {
21449 		*out_vdev_id = hdd_conn.out_vdev_id;
21450 		*out_reason = hdd_conn.out_reason;
21451 	}
21452 
21453 	return hdd_conn.connection_in_progress;
21454 }
21455 
hdd_restart_sap(struct wlan_hdd_link_info * link_info)21456 void hdd_restart_sap(struct wlan_hdd_link_info *link_info)
21457 {
21458 	struct hdd_hostapd_state *hapd_state;
21459 	QDF_STATUS status;
21460 	struct hdd_adapter *ap_adapter = link_info->adapter;
21461 	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(ap_adapter);
21462 	struct sap_config *sap_config;
21463 	void *sap_ctx;
21464 
21465 	sap_config =
21466 		&(WLAN_HDD_GET_AP_CTX_PTR(link_info)->sap_config);
21467 	sap_ctx = WLAN_HDD_GET_SAP_CTX_PTR(link_info);
21468 
21469 	mutex_lock(&hdd_ctx->sap_lock);
21470 	if (test_bit(SOFTAP_BSS_STARTED, &link_info->link_flags)) {
21471 		wlan_hdd_del_station(ap_adapter, NULL);
21472 		hapd_state = WLAN_HDD_GET_HOSTAP_STATE_PTR(link_info);
21473 		qdf_event_reset(&hapd_state->qdf_stop_bss_event);
21474 		if (QDF_STATUS_SUCCESS == wlansap_stop_bss(sap_ctx)) {
21475 			status = qdf_wait_single_event(&hapd_state->qdf_stop_bss_event,
21476 						       SME_CMD_STOP_BSS_TIMEOUT);
21477 
21478 			if (!QDF_IS_STATUS_SUCCESS(status)) {
21479 				hdd_err("SAP Stop Failed");
21480 				goto end;
21481 			}
21482 		}
21483 		clear_bit(SOFTAP_BSS_STARTED, &link_info->link_flags);
21484 		policy_mgr_decr_session_set_pcl(hdd_ctx->psoc,
21485 			ap_adapter->device_mode, link_info->vdev_id);
21486 		hdd_green_ap_start_state_mc(hdd_ctx, ap_adapter->device_mode,
21487 					    false);
21488 		hdd_err("SAP Stop Success");
21489 
21490 		if (0 != wlan_hdd_cfg80211_update_apies(link_info)) {
21491 			hdd_err("SAP Not able to set AP IEs");
21492 			goto end;
21493 		}
21494 
21495 		status = wlan_hdd_mlo_sap_reinit(link_info);
21496 		if (QDF_IS_STATUS_ERROR(status)) {
21497 			hdd_err("SAP Not able to do mlo attach");
21498 			goto deinit_mlo;
21499 		}
21500 
21501 		qdf_event_reset(&hapd_state->qdf_event);
21502 		status = wlansap_start_bss(sap_ctx, hdd_hostapd_sap_event_cb,
21503 					   sap_config, ap_adapter->dev);
21504 		if (QDF_IS_STATUS_ERROR(status)) {
21505 			hdd_err("SAP Start Bss fail");
21506 			goto deinit_mlo;
21507 		}
21508 
21509 		hdd_info("Waiting for SAP to start");
21510 		status = qdf_wait_single_event(&hapd_state->qdf_event,
21511 					       SME_CMD_START_BSS_TIMEOUT);
21512 		if (!QDF_IS_STATUS_SUCCESS(status)) {
21513 			hdd_err("SAP Start failed");
21514 			goto deinit_mlo;
21515 		}
21516 		wlansap_reset_sap_config_add_ie(sap_config, eUPDATE_IE_ALL);
21517 		hdd_err("SAP Start Success");
21518 		set_bit(SOFTAP_BSS_STARTED, &link_info->link_flags);
21519 		if (hapd_state->bss_state == BSS_START) {
21520 			policy_mgr_incr_active_session(hdd_ctx->psoc,
21521 						ap_adapter->device_mode,
21522 						link_info->vdev_id);
21523 			hdd_green_ap_start_state_mc(hdd_ctx,
21524 						    ap_adapter->device_mode,
21525 						    true);
21526 		}
21527 	}
21528 	mutex_unlock(&hdd_ctx->sap_lock);
21529 	return;
21530 
21531 deinit_mlo:
21532 	wlan_hdd_mlo_reset(link_info);
21533 end:
21534 	wlansap_reset_sap_config_add_ie(sap_config, eUPDATE_IE_ALL);
21535 	mutex_unlock(&hdd_ctx->sap_lock);
21536 }
21537 
21538 /**
21539  * hdd_set_connection_in_progress() - to set the connection in
21540  * progress flag
21541  * @value: value to set
21542  *
21543  * This function will set the passed value to connection in progress flag.
21544  * If value is previously being set to true then no need to set it again.
21545  *
21546  * Return: true if value is being set correctly and false otherwise.
21547  */
hdd_set_connection_in_progress(bool value)21548 bool hdd_set_connection_in_progress(bool value)
21549 {
21550 	bool status = true;
21551 	struct hdd_context *hdd_ctx;
21552 
21553 	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
21554 	if (!hdd_ctx)
21555 		return false;
21556 
21557 	qdf_spin_lock(&hdd_ctx->connection_status_lock);
21558 	/*
21559 	 * if the value is set to true previously and if someone is
21560 	 * trying to make it true again then it could be some race
21561 	 * condition being triggered. Avoid this situation by returning
21562 	 * false
21563 	 */
21564 	if (hdd_ctx->connection_in_progress && value)
21565 		status = false;
21566 	else
21567 		hdd_ctx->connection_in_progress = value;
21568 	qdf_spin_unlock(&hdd_ctx->connection_status_lock);
21569 	return status;
21570 }
21571 
wlan_hdd_send_mcc_vdev_quota(struct hdd_adapter * adapter,int set_value)21572 int wlan_hdd_send_mcc_vdev_quota(struct hdd_adapter *adapter, int set_value)
21573 {
21574 	if (!adapter) {
21575 		hdd_err("Invalid adapter");
21576 		return -EINVAL;
21577 	}
21578 	hdd_info("send mcc vdev quota to fw: %d", set_value);
21579 	sme_cli_set_command(adapter->deflink->vdev_id,
21580 			    WMA_VDEV_MCC_SET_TIME_QUOTA,
21581 			    set_value, VDEV_CMD);
21582 	return 0;
21583 
21584 }
21585 
wlan_hdd_send_mcc_latency(struct hdd_adapter * adapter,int set_value)21586 int wlan_hdd_send_mcc_latency(struct hdd_adapter *adapter, int set_value)
21587 {
21588 	if (!adapter) {
21589 		hdd_err("Invalid adapter");
21590 		return -EINVAL;
21591 	}
21592 
21593 	hdd_info("Send MCC latency WMA: %d", set_value);
21594 	sme_cli_set_command(adapter->deflink->vdev_id,
21595 			    WMA_VDEV_MCC_SET_TIME_LATENCY,
21596 			    set_value, VDEV_CMD);
21597 	return 0;
21598 }
21599 
21600 struct wlan_hdd_link_info *
wlan_hdd_get_link_info_from_vdev(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id)21601 wlan_hdd_get_link_info_from_vdev(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id)
21602 {
21603 	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
21604 	struct wlan_hdd_link_info *link_info;
21605 
21606 	/*
21607 	 * Currently PSOC is not being used. But this logic will
21608 	 * change once we have the converged implementation of
21609 	 * HDD context per PSOC in place. This would break if
21610 	 * multiple vdev objects reuse the vdev id.
21611 	 */
21612 	link_info = hdd_get_link_info_by_vdev(hdd_ctx, vdev_id);
21613 	if (!link_info) {
21614 		hdd_err("Get adapter by vdev id failed");
21615 		return NULL;
21616 	}
21617 
21618 	return link_info;
21619 }
21620 
hdd_get_rssi_snr_by_bssid(mac_handle_t mac_handle,const uint8_t * bssid,int8_t * rssi,int8_t * snr)21621 int hdd_get_rssi_snr_by_bssid(mac_handle_t mac_handle, const uint8_t *bssid,
21622 			      int8_t *rssi, int8_t *snr)
21623 {
21624 	QDF_STATUS status;
21625 
21626 	status = sme_get_rssi_snr_by_bssid(mac_handle, bssid, rssi, snr);
21627 	if (QDF_IS_STATUS_ERROR(status)) {
21628 		hdd_debug("sme_get_rssi_snr_by_bssid failed");
21629 		return -EINVAL;
21630 	}
21631 
21632 	return 0;
21633 }
21634 
21635 /**
21636  * hdd_reset_limit_off_chan() - reset limit off-channel command parameters
21637  * @adapter: HDD adapter
21638  *
21639  * Return: 0 on success and non zero value on failure
21640  */
hdd_reset_limit_off_chan(struct hdd_adapter * adapter)21641 int hdd_reset_limit_off_chan(struct hdd_adapter *adapter)
21642 {
21643 	struct hdd_context *hdd_ctx;
21644 	int ret;
21645 	QDF_STATUS status;
21646 	uint8_t sys_pref = 0;
21647 
21648 	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
21649 	ret = wlan_hdd_validate_context(hdd_ctx);
21650 	if (ret < 0)
21651 		return ret;
21652 
21653 	ucfg_policy_mgr_get_sys_pref(hdd_ctx->psoc,
21654 				     &sys_pref);
21655 	/* set the system preferece to default */
21656 	policy_mgr_set_cur_conc_system_pref(hdd_ctx->psoc, sys_pref);
21657 
21658 	/* clear the bitmap */
21659 	adapter->active_ac = 0;
21660 
21661 	hdd_debug("reset ac_bitmap for session %hu active_ac %0x",
21662 		  adapter->deflink->vdev_id, adapter->active_ac);
21663 
21664 	status = sme_send_limit_off_channel_params(hdd_ctx->mac_handle,
21665 						   adapter->deflink->vdev_id,
21666 						   false, 0, 0, false);
21667 	if (!QDF_IS_STATUS_SUCCESS(status)) {
21668 		hdd_err("failed to reset limit off chan params");
21669 		ret = -EINVAL;
21670 	}
21671 
21672 	return ret;
21673 }
21674 
hdd_hidden_ssid_enable_roaming(hdd_handle_t hdd_handle,uint8_t vdev_id)21675 void hdd_hidden_ssid_enable_roaming(hdd_handle_t hdd_handle, uint8_t vdev_id)
21676 {
21677 	struct hdd_context *hdd_ctx = hdd_handle_to_context(hdd_handle);
21678 	struct wlan_hdd_link_info *link_info;
21679 
21680 	link_info = hdd_get_link_info_by_vdev(hdd_ctx, vdev_id);
21681 	if (!link_info) {
21682 		hdd_err("Invalid vdev");
21683 		return;
21684 	}
21685 	/* enable roaming on all adapters once hdd get hidden ssid rsp */
21686 	wlan_hdd_set_roaming_state(link_info, RSO_START_BSS, true);
21687 }
21688 
21689 #ifdef WLAN_FEATURE_PKT_CAPTURE
wlan_hdd_is_mon_concurrency(void)21690 bool wlan_hdd_is_mon_concurrency(void)
21691 {
21692 	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
21693 
21694 	if (!hdd_ctx)
21695 		return -EINVAL;
21696 
21697 	if (ucfg_pkt_capture_get_mode(hdd_ctx->psoc) !=
21698 						PACKET_CAPTURE_MODE_DISABLE) {
21699 		if (policy_mgr_get_concurrency_mode(hdd_ctx->psoc) ==
21700 		    (QDF_STA_MASK | QDF_MONITOR_MASK)) {
21701 			hdd_err("STA + MON mode is UP");
21702 			return true;
21703 		}
21704 	}
21705 	return false;
21706 }
21707 
wlan_hdd_del_monitor(struct hdd_context * hdd_ctx,struct hdd_adapter * adapter,bool rtnl_held)21708 void wlan_hdd_del_monitor(struct hdd_context *hdd_ctx,
21709 			  struct hdd_adapter *adapter, bool rtnl_held)
21710 {
21711 	wlan_hdd_release_intf_addr(hdd_ctx, adapter->mac_addr.bytes);
21712 	hdd_stop_adapter(hdd_ctx, adapter);
21713 	hdd_close_adapter(hdd_ctx, adapter, true);
21714 
21715 	hdd_open_p2p_interface(hdd_ctx);
21716 }
21717 
21718 void
wlan_hdd_del_p2p_interface(struct hdd_context * hdd_ctx)21719 wlan_hdd_del_p2p_interface(struct hdd_context *hdd_ctx)
21720 {
21721 	struct hdd_adapter *adapter = NULL, *next_adapter = NULL;
21722 	struct osif_vdev_sync *vdev_sync;
21723 
21724 	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
21725 					   NET_DEV_HOLD_DEL_P2P_INTERFACE) {
21726 		if (adapter->device_mode == QDF_P2P_CLIENT_MODE ||
21727 		    adapter->device_mode == QDF_P2P_DEVICE_MODE ||
21728 		    adapter->device_mode == QDF_P2P_GO_MODE) {
21729 			vdev_sync = osif_vdev_sync_unregister(adapter->dev);
21730 			if (vdev_sync)
21731 				osif_vdev_sync_wait_for_ops(vdev_sync);
21732 
21733 			hdd_adapter_dev_put_debug(
21734 				adapter, NET_DEV_HOLD_DEL_P2P_INTERFACE);
21735 
21736 			hdd_clean_up_interface(hdd_ctx, adapter);
21737 
21738 			if (vdev_sync)
21739 				osif_vdev_sync_destroy(vdev_sync);
21740 		} else
21741 			hdd_adapter_dev_put_debug(
21742 				adapter, NET_DEV_HOLD_DEL_P2P_INTERFACE);
21743 	}
21744 }
21745 
21746 #endif /* WLAN_FEATURE_PKT_CAPTURE */
21747 
wlan_hdd_is_session_type_monitor(uint8_t session_type)21748 bool wlan_hdd_is_session_type_monitor(uint8_t session_type)
21749 {
21750 	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
21751 
21752 	if (!hdd_ctx) {
21753 		cds_err("HDD context is NULL");
21754 		return false;
21755 	}
21756 
21757 	if (cds_get_conparam() != QDF_GLOBAL_MONITOR_MODE &&
21758 	    session_type == QDF_MONITOR_MODE)
21759 		return true;
21760 	else
21761 		return false;
21762 }
21763 
21764 int
wlan_hdd_add_monitor_check(struct hdd_context * hdd_ctx,struct hdd_adapter ** adapter,const char * name,bool rtnl_held,unsigned char name_assign_type,bool is_rx_mon)21765 wlan_hdd_add_monitor_check(struct hdd_context *hdd_ctx,
21766 			   struct hdd_adapter **adapter,
21767 			   const char *name, bool rtnl_held,
21768 			   unsigned char name_assign_type, bool is_rx_mon)
21769 {
21770 	struct hdd_adapter *sta_adapter;
21771 	struct hdd_adapter *mon_adapter;
21772 	uint8_t num_open_session = 0;
21773 	QDF_STATUS status;
21774 	struct hdd_adapter_create_param params = {0};
21775 
21776 	sta_adapter = hdd_get_adapter(hdd_ctx, QDF_STA_MODE);
21777 	if (!sta_adapter) {
21778 		hdd_err("No station adapter");
21779 		return -EINVAL;
21780 	}
21781 
21782 	status = policy_mgr_check_mon_concurrency(hdd_ctx->psoc);
21783 
21784 	if (QDF_IS_STATUS_ERROR(status))
21785 		return -EINVAL;
21786 
21787 	if (hdd_is_connection_in_progress(NULL, NULL)) {
21788 		hdd_err("cannot add monitor mode, Connection in progress");
21789 		return -EINVAL;
21790 	}
21791 
21792 	if (is_rx_mon) {
21793 		num_open_session = policy_mgr_mode_specific_connection_count(
21794 						hdd_ctx->psoc,
21795 						PM_STA_MODE,
21796 						NULL);
21797 
21798 		if (num_open_session) {
21799 			/* Try disconnecting if already in connected state */
21800 			wlan_hdd_cm_issue_disconnect(sta_adapter->deflink,
21801 						     REASON_UNSPEC_FAILURE,
21802 						     true);
21803 		}
21804 	}
21805 
21806 	if (ucfg_pkt_capture_get_mode(hdd_ctx->psoc) !=
21807 						PACKET_CAPTURE_MODE_DISABLE)
21808 		wlan_hdd_del_p2p_interface(hdd_ctx);
21809 
21810 	params.is_add_virtual_iface = 1;
21811 
21812 	mon_adapter = hdd_open_adapter(hdd_ctx, QDF_MONITOR_MODE, name,
21813 				       wlan_hdd_get_intf_addr(
21814 				       hdd_ctx,
21815 				       QDF_MONITOR_MODE),
21816 				       name_assign_type, rtnl_held, &params);
21817 	if (!mon_adapter) {
21818 		hdd_err("hdd_open_adapter failed");
21819 		if (ucfg_pkt_capture_get_mode(hdd_ctx->psoc) !=
21820 						PACKET_CAPTURE_MODE_DISABLE)
21821 			hdd_open_p2p_interface(hdd_ctx);
21822 		return -EINVAL;
21823 	}
21824 
21825 	if (mon_adapter)
21826 		hdd_set_idle_ps_config(hdd_ctx, false);
21827 
21828 	*adapter = mon_adapter;
21829 	return 0;
21830 }
21831 
21832 #ifdef FEATURE_MONITOR_MODE_SUPPORT
21833 
hdd_sme_monitor_mode_callback(uint8_t vdev_id)21834 void hdd_sme_monitor_mode_callback(uint8_t vdev_id)
21835 {
21836 	struct hdd_context *hdd_ctx;
21837 	struct hdd_adapter *adapter;
21838 	struct wlan_hdd_link_info *link_info;
21839 
21840 	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
21841 	if (!hdd_ctx)
21842 		return;
21843 
21844 	link_info = hdd_get_link_info_by_vdev(hdd_ctx, vdev_id);
21845 	if (!link_info) {
21846 		hdd_err_rl("NULL adapter");
21847 		return;
21848 	}
21849 
21850 	adapter = link_info->adapter;
21851 	if (adapter->magic != WLAN_HDD_ADAPTER_MAGIC) {
21852 		hdd_err_rl("Invalid magic");
21853 		return;
21854 	}
21855 
21856 	qdf_event_set(&adapter->qdf_monitor_mode_vdev_up_event);
21857 
21858 	hdd_debug("monitor mode vdev up completed");
21859 	adapter->monitor_mode_vdev_up_in_progress = false;
21860 }
21861 
hdd_monitor_mode_qdf_create_event(struct hdd_adapter * adapter,uint8_t session_type)21862 QDF_STATUS hdd_monitor_mode_qdf_create_event(struct hdd_adapter *adapter,
21863 					     uint8_t session_type)
21864 {
21865 	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
21866 
21867 	if (session_type == QDF_MONITOR_MODE) {
21868 		qdf_status = qdf_event_create(
21869 				&adapter->qdf_monitor_mode_vdev_up_event);
21870 	}
21871 	return qdf_status;
21872 }
21873 
hdd_monitor_mode_vdev_status(struct hdd_adapter * adapter)21874 QDF_STATUS hdd_monitor_mode_vdev_status(struct hdd_adapter *adapter)
21875 {
21876 	QDF_STATUS status = QDF_STATUS_SUCCESS;
21877 
21878 	if (!adapter->monitor_mode_vdev_up_in_progress)
21879 		return status;
21880 
21881 	/* block on a completion variable until vdev up success*/
21882 	status = qdf_wait_for_event_completion(
21883 				       &adapter->qdf_monitor_mode_vdev_up_event,
21884 					WLAN_MONITOR_MODE_VDEV_UP_EVT);
21885 	if (QDF_IS_STATUS_ERROR(status)) {
21886 		hdd_err_rl("monitor mode vdev up event time out vdev id: %d",
21887 			   adapter->deflink->vdev_id);
21888 		if (adapter->qdf_monitor_mode_vdev_up_event.force_set)
21889 			/*
21890 			 * SSR/PDR has caused shutdown, which has
21891 			 * forcefully set the event.
21892 			 */
21893 			hdd_err_rl("monitor mode vdev up event forcefully set");
21894 		else if (status == QDF_STATUS_E_TIMEOUT)
21895 			hdd_err_rl("mode vdev up event timed out");
21896 		else
21897 			hdd_err_rl("Failed to wait for monitor vdev up(status-%d)",
21898 				   status);
21899 
21900 		adapter->monitor_mode_vdev_up_in_progress = false;
21901 		return status;
21902 	}
21903 
21904 	return QDF_STATUS_SUCCESS;
21905 }
21906 #endif
21907 
21908 #if defined(CLD_PM_QOS) && defined(WLAN_FEATURE_LL_MODE)
hdd_beacon_latency_event_cb(uint32_t latency_level)21909 void hdd_beacon_latency_event_cb(uint32_t latency_level)
21910 {
21911 	struct hdd_context *hdd_ctx;
21912 
21913 	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
21914 	if (!hdd_ctx)
21915 		return;
21916 
21917 	if (latency_level ==
21918 		QCA_WLAN_VENDOR_ATTR_CONFIG_LATENCY_LEVEL_ULTRALOW)
21919 		wlan_hdd_set_pm_qos_request(hdd_ctx, true);
21920 	else
21921 		wlan_hdd_set_pm_qos_request(hdd_ctx, false);
21922 }
21923 #endif
21924 
21925 #ifdef CONFIG_WLAN_DEBUG_CRASH_INJECT
hdd_crash_inject(struct hdd_adapter * adapter,uint32_t v1,uint32_t v2)21926 int hdd_crash_inject(struct hdd_adapter *adapter, uint32_t v1, uint32_t v2)
21927 {
21928 	struct hdd_context *hdd_ctx;
21929 	int ret;
21930 	bool crash_inject;
21931 	QDF_STATUS status;
21932 
21933 	hdd_debug("v1: %d v2: %d", v1, v2);
21934 	pr_err("SSR is triggered by CRASH_INJECT: %d %d\n",
21935 	       v1, v2);
21936 	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
21937 
21938 	status = ucfg_mlme_get_crash_inject(hdd_ctx->psoc, &crash_inject);
21939 	if (QDF_IS_STATUS_ERROR(status)) {
21940 		hdd_err("Failed to get crash inject ini config");
21941 		return 0;
21942 	}
21943 
21944 	if (!crash_inject) {
21945 		hdd_err("Crash Inject ini disabled, Ignore Crash Inject");
21946 		return 0;
21947 	}
21948 
21949 	if (v1 == 3) {
21950 		cds_trigger_recovery(QDF_REASON_UNSPECIFIED);
21951 		return 0;
21952 	}
21953 	ret = wma_cli_set2_command(adapter->deflink->vdev_id,
21954 				   GEN_PARAM_CRASH_INJECT,
21955 				   v1, v2, GEN_CMD);
21956 	return ret;
21957 }
21958 #endif
21959 
21960 static const struct hdd_chwidth_info chwidth_info[] = {
21961 	[NL80211_CHAN_WIDTH_20_NOHT] = {
21962 		.ch_bw = HW_MODE_20_MHZ,
21963 		.ch_bw_str = "20MHz",
21964 		.phy_chwidth = CH_WIDTH_20MHZ,
21965 	},
21966 	[NL80211_CHAN_WIDTH_20] = {
21967 		.sir_chwidth_valid = true,
21968 		.sir_chwidth = eHT_CHANNEL_WIDTH_20MHZ,
21969 		.ch_bw = HW_MODE_20_MHZ,
21970 		.ch_bw_str = "20MHz",
21971 		.phy_chwidth = CH_WIDTH_20MHZ,
21972 		.bonding_mode = WNI_CFG_CHANNEL_BONDING_MODE_DISABLE,
21973 	},
21974 	[NL80211_CHAN_WIDTH_40] = {
21975 		.sir_chwidth_valid = true,
21976 		.sir_chwidth = eHT_CHANNEL_WIDTH_40MHZ,
21977 		.ch_bw = HW_MODE_40_MHZ,
21978 		.ch_bw_str = "40MHz",
21979 		.phy_chwidth = CH_WIDTH_40MHZ,
21980 		.bonding_mode = WNI_CFG_CHANNEL_BONDING_MODE_ENABLE,
21981 	},
21982 	[NL80211_CHAN_WIDTH_80] = {
21983 		.sir_chwidth_valid = true,
21984 		.sir_chwidth = eHT_CHANNEL_WIDTH_80MHZ,
21985 		.ch_bw = HW_MODE_80_MHZ,
21986 		.ch_bw_str = "80MHz",
21987 		.phy_chwidth = CH_WIDTH_80MHZ,
21988 		.bonding_mode = WNI_CFG_CHANNEL_BONDING_MODE_ENABLE,
21989 	},
21990 	[NL80211_CHAN_WIDTH_80P80] = {
21991 		.sir_chwidth_valid = true,
21992 		.sir_chwidth = eHT_CHANNEL_WIDTH_80P80MHZ,
21993 		.ch_bw = HW_MODE_80_PLUS_80_MHZ,
21994 		.ch_bw_str = "(80 + 80)MHz",
21995 		.phy_chwidth = CH_WIDTH_80P80MHZ,
21996 		.bonding_mode = WNI_CFG_CHANNEL_BONDING_MODE_ENABLE,
21997 	},
21998 	[NL80211_CHAN_WIDTH_160] = {
21999 		.sir_chwidth_valid = true,
22000 		.sir_chwidth = eHT_CHANNEL_WIDTH_160MHZ,
22001 		.ch_bw = HW_MODE_160_MHZ,
22002 		.ch_bw_str = "160MHz",
22003 		.phy_chwidth = CH_WIDTH_160MHZ,
22004 		.bonding_mode = WNI_CFG_CHANNEL_BONDING_MODE_ENABLE,
22005 	},
22006 	[NL80211_CHAN_WIDTH_5] = {
22007 		.ch_bw = HW_MODE_5_MHZ,
22008 		.ch_bw_str = "5MHz",
22009 		.phy_chwidth = CH_WIDTH_5MHZ,
22010 	},
22011 	[NL80211_CHAN_WIDTH_10] = {
22012 		.ch_bw = HW_MODE_10_MHZ,
22013 		.ch_bw_str = "10MHz",
22014 		.phy_chwidth = CH_WIDTH_10MHZ,
22015 	},
22016 #if defined(WLAN_FEATURE_11BE) && defined(CFG80211_11BE_BASIC)
22017 	[NL80211_CHAN_WIDTH_320] = {
22018 		.sir_chwidth_valid = true,
22019 		.sir_chwidth = eHT_CHANNEL_WIDTH_320MHZ,
22020 		.ch_bw = HW_MODE_320_MHZ,
22021 		.ch_bw_str = "320MHz",
22022 		.phy_chwidth = CH_WIDTH_320MHZ,
22023 		.bonding_mode = WNI_CFG_CHANNEL_BONDING_MODE_ENABLE,
22024 	},
22025 #endif
22026 };
22027 
22028 enum eSirMacHTChannelWidth
hdd_nl80211_chwidth_to_chwidth(uint8_t nl80211_chwidth)22029 hdd_nl80211_chwidth_to_chwidth(uint8_t nl80211_chwidth)
22030 {
22031 	if (nl80211_chwidth >= ARRAY_SIZE(chwidth_info) ||
22032 	    !chwidth_info[nl80211_chwidth].sir_chwidth_valid) {
22033 		hdd_err("Unsupported channel width %d", nl80211_chwidth);
22034 		return -EINVAL;
22035 	}
22036 
22037 	return chwidth_info[nl80211_chwidth].sir_chwidth;
22038 }
22039 
hdd_chwidth_to_nl80211_chwidth(enum eSirMacHTChannelWidth chwidth)22040 uint8_t hdd_chwidth_to_nl80211_chwidth(enum eSirMacHTChannelWidth 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].sir_chwidth == chwidth)
22047 			return i;
22048 	}
22049 
22050 	hdd_err("Unsupported channel width %d", chwidth);
22051 	return 0xFF;
22052 }
22053 
hdd_phy_chwidth_to_nl80211_chwidth(enum phy_ch_width chwidth)22054 uint8_t hdd_phy_chwidth_to_nl80211_chwidth(enum phy_ch_width chwidth)
22055 {
22056 	int i;
22057 
22058 	for (i = 0; i < ARRAY_SIZE(chwidth_info); i++) {
22059 		if (chwidth_info[i].sir_chwidth_valid &&
22060 		    chwidth_info[i].phy_chwidth == chwidth)
22061 			return i;
22062 	}
22063 
22064 	hdd_err("Unsupported channel width %d", chwidth);
22065 	return 0xFF;
22066 }
22067 
wlan_hdd_get_channel_bw(enum nl80211_chan_width width)22068 enum hw_mode_bandwidth wlan_hdd_get_channel_bw(enum nl80211_chan_width width)
22069 {
22070 	if (width >= ARRAY_SIZE(chwidth_info)) {
22071 		hdd_err("Invalid width: %d, using default 20MHz", width);
22072 		return HW_MODE_20_MHZ;
22073 	}
22074 
22075 	return chwidth_info[width].ch_bw;
22076 }
22077 
hdd_ch_width_str(enum phy_ch_width ch_width)22078 uint8_t *hdd_ch_width_str(enum phy_ch_width ch_width)
22079 {
22080 	int i;
22081 
22082 	for (i = 0; i < ARRAY_SIZE(chwidth_info); i++) {
22083 		if (chwidth_info[i].phy_chwidth == ch_width)
22084 			return chwidth_info[i].ch_bw_str;
22085 	}
22086 
22087 	return "UNKNOWN";
22088 }
22089 
hdd_we_set_ch_width(struct wlan_hdd_link_info * link_info,int ch_width)22090 int hdd_we_set_ch_width(struct wlan_hdd_link_info *link_info, int ch_width)
22091 {
22092 	int i;
22093 	uint8_t link_id = 0xFF;
22094 
22095 	/* updating channel bonding only on 5Ghz */
22096 	hdd_debug("wmi_vdev_param_chwidth val %d", ch_width);
22097 
22098 	for (i = 0; i < ARRAY_SIZE(chwidth_info); i++) {
22099 		if (!chwidth_info[i].sir_chwidth_valid ||
22100 		    chwidth_info[i].sir_chwidth != ch_width)
22101 			continue;
22102 
22103 		return hdd_update_channel_width(link_info, ch_width,
22104 						chwidth_info[i].bonding_mode,
22105 						link_id, false);
22106 	}
22107 
22108 	hdd_err("Invalid ch_width %d", ch_width);
22109 	return -EINVAL;
22110 }
22111 
22112 /* Register the module init/exit functions */
22113 module_init(hdd_module_init);
22114 module_exit(hdd_module_exit);
22115 
22116 MODULE_LICENSE("Dual BSD/GPL");
22117 MODULE_AUTHOR("Qualcomm Atheros, Inc.");
22118 MODULE_DESCRIPTION("WLAN HOST DEVICE DRIVER");
22119 
22120 const struct kernel_param_ops con_mode_ops = {
22121 	.set = con_mode_handler,
22122 	.get = param_get_int,
22123 };
22124 
22125 #ifdef FEATURE_WLAN_RESIDENT_DRIVER
22126 EXPORT_SYMBOL(con_mode_ops);
22127 #endif
22128 
22129 const struct kernel_param_ops con_mode_ftm_ops = {
22130 	.set = con_mode_handler_ftm,
22131 	.get = param_get_int,
22132 };
22133 
22134 #ifdef FEATURE_WLAN_RESIDENT_DRIVER
22135 EXPORT_SYMBOL(con_mode_ftm_ops);
22136 #endif
22137 
22138 #ifdef WLAN_FEATURE_EPPING
22139 static const struct kernel_param_ops con_mode_epping_ops = {
22140 	.set = con_mode_handler_epping,
22141 	.get = param_get_int,
22142 };
22143 #endif
22144 
22145 static const struct kernel_param_ops fwpath_ops = {
22146 	.set = fwpath_changed_handler,
22147 	.get = param_get_string,
22148 };
22149 
__pcie_set_gen_speed_handler(void)22150 static int __pcie_set_gen_speed_handler(void)
22151 {
22152 	int ret;
22153 	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
22154 
22155 	ret = wlan_hdd_validate_context(hdd_ctx);
22156 	if (ret)
22157 		return ret;
22158 
22159 	hdd_info_rl("Received PCIe gen speed %d", pcie_gen_speed);
22160 	if (pcie_gen_speed <= HDD_INVALID_MIN_PCIE_GEN_SPEED ||
22161 	    pcie_gen_speed >= HDD_INVALID_MAX_PCIE_GEN_SPEED) {
22162 		hdd_err_rl("invalid pcie gen speed %d", pcie_gen_speed);
22163 		return -EINVAL;
22164 	}
22165 
22166 	hdd_ctx->current_pcie_gen_speed = pcie_gen_speed;
22167 
22168 	return 0;
22169 }
22170 
pcie_set_gen_speed_handler(const char * kmessage,const struct kernel_param * kp)22171 static int pcie_set_gen_speed_handler(const char *kmessage,
22172 				      const struct kernel_param *kp)
22173 {
22174 	struct osif_driver_sync *driver_sync;
22175 	int ret;
22176 
22177 	ret = osif_driver_sync_op_start(&driver_sync);
22178 	if (ret)
22179 		return ret;
22180 
22181 	ret = param_set_int(kmessage, kp);
22182 	if (ret) {
22183 		hdd_err_rl("param set int failed %d", ret);
22184 		goto out;
22185 	}
22186 
22187 	ret = __pcie_set_gen_speed_handler();
22188 
22189 out:
22190 	osif_driver_sync_op_stop(driver_sync);
22191 
22192 	return ret;
22193 }
22194 
22195 static const struct kernel_param_ops pcie_gen_speed_ops = {
22196 	.set = pcie_set_gen_speed_handler,
22197 	.get = param_get_int,
22198 };
22199 
22200 module_param_cb(con_mode, &con_mode_ops, &con_mode,
22201 		S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
22202 
22203 module_param_cb(con_mode_ftm, &con_mode_ftm_ops, &con_mode_ftm,
22204 		S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
22205 
22206 module_param_cb(pcie_gen_speed, &pcie_gen_speed_ops, &pcie_gen_speed,
22207 		S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
22208 
22209 #ifdef WLAN_FEATURE_EPPING
22210 module_param_cb(con_mode_epping, &con_mode_epping_ops,
22211 		&con_mode_epping, 0644);
22212 #endif
22213 
22214 module_param_cb(fwpath, &fwpath_ops, &fwpath,
22215 		S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
22216 
22217 module_param(enable_dfs_chan_scan, int, S_IRUSR | S_IRGRP | S_IROTH);
22218 
22219 module_param(enable_11d, int, S_IRUSR | S_IRGRP | S_IROTH);
22220 
22221 module_param(country_code, charp, S_IRUSR | S_IRGRP | S_IROTH);
22222 
timer_multiplier_get_handler(char * buffer,const struct kernel_param * kp)22223 static int timer_multiplier_get_handler(char *buffer,
22224 					const struct kernel_param *kp)
22225 {
22226 	return scnprintf(buffer, PAGE_SIZE, "%u", qdf_timer_get_multiplier());
22227 }
22228 
timer_multiplier_set_handler(const char * kmessage,const struct kernel_param * kp)22229 static int timer_multiplier_set_handler(const char *kmessage,
22230 					const struct kernel_param *kp)
22231 {
22232 	QDF_STATUS status;
22233 	uint32_t scalar;
22234 
22235 	status = qdf_uint32_parse(kmessage, &scalar);
22236 	if (QDF_IS_STATUS_ERROR(status))
22237 		return qdf_status_to_os_return(status);
22238 
22239 	if (!cfg_in_range(CFG_TIMER_MULTIPLIER, scalar))
22240 		return -ERANGE;
22241 
22242 	qdf_timer_set_multiplier(scalar);
22243 
22244 	return 0;
22245 }
22246 
22247 static const struct kernel_param_ops timer_multiplier_ops = {
22248 	.get = timer_multiplier_get_handler,
22249 	.set = timer_multiplier_set_handler,
22250 };
22251 
22252 module_param_cb(timer_multiplier, &timer_multiplier_ops, NULL, 0644);
22253