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