1 /* 2 * Copyright (c) 2012-2021 The Linux Foundation. All rights reserved. 3 * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved. 4 * 5 * Permission to use, copy, modify, and/or distribute this software for 6 * any purpose with or without fee is hereby granted, provided that the 7 * above copyright notice and this permission notice appear in all 8 * copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 11 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 12 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 13 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 14 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 15 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 16 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 17 * PERFORMANCE OF THIS SOFTWARE. 18 */ 19 20 /** 21 * DOC: wlan_hdd_main.c 22 * 23 * WLAN Host Device Driver implementation 24 * 25 */ 26 27 /* Include Files */ 28 #include <wbuff.h> 29 #include "cfg_ucfg_api.h" 30 #include <wlan_hdd_includes.h> 31 #include <cds_api.h> 32 #include <cds_sched.h> 33 #include <linux/cpu.h> 34 #include <linux/etherdevice.h> 35 #include <linux/firmware.h> 36 #include <linux/kernel.h> 37 #include <wlan_hdd_tx_rx.h> 38 #include <wni_api.h> 39 #include <wlan_hdd_cfg.h> 40 #include <wlan_ptt_sock_svc.h> 41 #include <dbglog_host.h> 42 #include <wlan_logging_sock_svc.h> 43 #include <wlan_roam_debug.h> 44 #include <wlan_hdd_connectivity_logging.h> 45 #include "osif_sync.h" 46 #include <wlan_hdd_wowl.h> 47 #include <wlan_hdd_misc.h> 48 #include <wlan_hdd_wext.h> 49 #include "wlan_hdd_trace.h" 50 #include "wlan_hdd_ioctl.h" 51 #include "wlan_hdd_ftm.h" 52 #include "wlan_hdd_power.h" 53 #include "wlan_hdd_stats.h" 54 #include "wlan_hdd_scan.h" 55 #include "wlan_policy_mgr_ucfg.h" 56 #include "wlan_osif_priv.h" 57 #include <wlan_osif_request_manager.h> 58 #ifdef CONFIG_LEAK_DETECTION 59 #include "qdf_debug_domain.h" 60 #endif 61 #include "qdf_delayed_work.h" 62 #include "qdf_periodic_work.h" 63 #include "qdf_str.h" 64 #include "qdf_talloc.h" 65 #include "qdf_trace.h" 66 #include "qdf_types.h" 67 #include "qdf_net_if.h" 68 #include <cdp_txrx_peer_ops.h> 69 #include <cdp_txrx_misc.h> 70 #include <cdp_txrx_stats.h> 71 #include "cdp_txrx_flow_ctrl_legacy.h" 72 #include "qdf_ssr_driver_dump.h" 73 74 #include <net/addrconf.h> 75 #include <linux/wireless.h> 76 #include <net/cfg80211.h> 77 #include <linux/inetdevice.h> 78 #include <net/addrconf.h> 79 #include "wlan_hdd_cfg80211.h" 80 #include "wlan_hdd_ext_scan.h" 81 #include "wlan_hdd_p2p.h" 82 #include <linux/rtnetlink.h> 83 #include "sap_api.h" 84 #include <sap_internal.h> 85 #include <linux/semaphore.h> 86 #include <linux/ctype.h> 87 #include <linux/compat.h> 88 #include <linux/ethtool.h> 89 #include <linux/suspend.h> 90 91 #ifdef WLAN_FEATURE_DP_BUS_BANDWIDTH 92 #include "qdf_periodic_work.h" 93 #endif 94 95 #include <wlan_hdd_hostapd.h> 96 #include <wlan_hdd_softap_tx_rx.h> 97 #include <wlan_hdd_green_ap.h> 98 #include "qwlan_version.h" 99 #include "wma_types.h" 100 #include "wlan_hdd_tdls.h" 101 #ifdef FEATURE_WLAN_CH_AVOID 102 #include "cds_regdomain.h" 103 #endif /* FEATURE_WLAN_CH_AVOID */ 104 #include "cdp_txrx_flow_ctrl_v2.h" 105 #include "pld_common.h" 106 #include "wlan_hdd_ocb.h" 107 #include "wlan_hdd_nan.h" 108 #include "wlan_hdd_debugfs.h" 109 #include "wlan_hdd_debugfs_csr.h" 110 #include "wlan_hdd_driver_ops.h" 111 #include "epping_main.h" 112 #include "wlan_hdd_data_stall_detection.h" 113 #include "wlan_hdd_mpta_helper.h" 114 115 #include <wlan_hdd_ipa.h> 116 #include "hif.h" 117 #include "wma.h" 118 #include "wlan_policy_mgr_api.h" 119 #include "wlan_hdd_tsf.h" 120 #include "bmi.h" 121 #include <wlan_hdd_regulatory.h> 122 #include "wlan_hdd_lpass.h" 123 #include "wlan_nan_api.h" 124 #include <wlan_hdd_napi.h> 125 #include "wlan_hdd_disa.h" 126 #include <dispatcher_init_deinit.h> 127 #include "wlan_hdd_object_manager.h" 128 #include "cds_utils.h" 129 #include <cdp_txrx_handle.h> 130 #include <qca_vendor.h> 131 #include "wlan_pmo_ucfg_api.h" 132 #include "sir_api.h" 133 #include "os_if_wifi_pos.h" 134 #include "wifi_pos_api.h" 135 #include "wlan_hdd_oemdata.h" 136 #include "wlan_hdd_he.h" 137 #include "os_if_nan.h" 138 #include "nan_public_structs.h" 139 #include "nan_ucfg_api.h" 140 #include "wlan_reg_ucfg_api.h" 141 #include "wlan_hdd_afc.h" 142 #include "wlan_afc_ucfg_api.h" 143 #include "wlan_dfs_ucfg_api.h" 144 #include "wlan_hdd_rx_monitor.h" 145 #include "sme_power_save_api.h" 146 #include "enet.h" 147 #include <cdp_txrx_cmn_struct.h> 148 #include "wlan_hdd_sysfs.h" 149 #include "wlan_disa_ucfg_api.h" 150 #include "wlan_disa_obj_mgmt_api.h" 151 #include "wlan_action_oui_ucfg_api.h" 152 #include "wlan_ipa_ucfg_api.h" 153 #include <target_if.h> 154 #include "wlan_hdd_nud_tracking.h" 155 #include "wlan_hdd_apf.h" 156 #include "wlan_hdd_twt.h" 157 #include "qc_sap_ioctl.h" 158 #include "wlan_mlme_main.h" 159 #include "wlan_p2p_cfg_api.h" 160 #include "wlan_cfg80211_p2p.h" 161 #include "wlan_cfg80211_interop_issues_ap.h" 162 #include "wlan_tdls_cfg_api.h" 163 #include <wlan_hdd_rssi_monitor.h> 164 #include "wlan_mlme_ucfg_api.h" 165 #include "wlan_mlme_twt_ucfg_api.h" 166 #include "wlan_fwol_ucfg_api.h" 167 #include "wlan_policy_mgr_ucfg.h" 168 #include "qdf_func_tracker.h" 169 #include "pld_common.h" 170 #include "wlan_hdd_pre_cac.h" 171 172 #include "sme_api.h" 173 174 #ifdef CNSS_GENL 175 #ifdef CONFIG_CNSS_OUT_OF_TREE 176 #include "cnss_nl.h" 177 #else 178 #include <net/cnss_nl.h> 179 #endif 180 #endif 181 #include "wlan_reg_ucfg_api.h" 182 #include "wlan_ocb_ucfg_api.h" 183 #include <wlan_hdd_spectralscan.h> 184 #include "wlan_green_ap_ucfg_api.h" 185 #include <wlan_p2p_ucfg_api.h> 186 #include <wlan_interop_issues_ap_ucfg_api.h> 187 #include <target_type.h> 188 #include <wlan_hdd_debugfs_coex.h> 189 #include <wlan_hdd_debugfs_config.h> 190 #include "wlan_dlm_ucfg_api.h" 191 #include "ftm_time_sync_ucfg_api.h" 192 #include "wlan_pre_cac_ucfg_api.h" 193 #include "ol_txrx.h" 194 #include "wlan_hdd_sta_info.h" 195 #include "mac_init_api.h" 196 #include "wlan_pkt_capture_ucfg_api.h" 197 #include <wlan_hdd_sar_limits.h> 198 #include "cfg_nan_api.h" 199 #include "wlan_hdd_btc_chain_mode.h" 200 #include <wlan_hdd_dcs.h> 201 #include "wlan_hdd_debugfs_unit_test.h" 202 #include "wlan_hdd_debugfs_mibstat.h" 203 #include <wlan_hdd_hang_event.h> 204 #include "wlan_global_lmac_if_api.h" 205 #include "wlan_coex_ucfg_api.h" 206 #include "wlan_cm_roam_api.h" 207 #include "wlan_cm_roam_ucfg_api.h" 208 #include <cdp_txrx_ctrl.h> 209 #include "qdf_lock.h" 210 #include "wlan_hdd_thermal.h" 211 #include "osif_cm_util.h" 212 #include "wlan_hdd_gpio_wakeup.h" 213 #include "wlan_hdd_bootup_marker.h" 214 #include "wlan_dp_ucfg_api.h" 215 #include "wlan_hdd_medium_assess.h" 216 #include "wlan_hdd_eht.h" 217 #include <linux/bitfield.h> 218 #include "wlan_hdd_mlo.h" 219 #include <wlan_hdd_son.h> 220 #ifdef WLAN_FEATURE_11BE_MLO 221 #include <wlan_mlo_mgr_ap.h> 222 #endif 223 #include "wlan_osif_features.h" 224 #include "wlan_vdev_mgr_ucfg_api.h" 225 #include <wlan_objmgr_psoc_obj_i.h> 226 #include <wlan_objmgr_vdev_obj_i.h> 227 #include "wifi_pos_ucfg_api.h" 228 #include "osif_vdev_mgr_util.h" 229 #include <son_ucfg_api.h> 230 #include "osif_twt_util.h" 231 #include "wlan_twt_ucfg_ext_api.h" 232 #include "wlan_hdd_mcc_quota.h" 233 #include "osif_pre_cac.h" 234 #include "wlan_hdd_pre_cac.h" 235 #include "wlan_osif_features.h" 236 #ifdef WLAN_FEATURE_DYNAMIC_RX_AGGREGATION 237 #include <net/pkt_cls.h> 238 #endif 239 #include "wlan_dp_public_struct.h" 240 #include "os_if_dp.h" 241 #include <wlan_dp_ucfg_api.h> 242 #include "wlan_psoc_mlme_ucfg_api.h" 243 #include "os_if_qmi.h" 244 #include "wlan_qmi_ucfg_api.h" 245 #include "wlan_psoc_mlme_ucfg_api.h" 246 #include "wlan_ll_sap_ucfg_api.h" 247 248 #include "os_if_dp_local_pkt_capture.h" 249 #include <wlan_mlo_mgr_link_switch.h> 250 #include "cdp_txrx_mon.h" 251 252 #ifdef MULTI_CLIENT_LL_SUPPORT 253 #define WLAM_WLM_HOST_DRIVER_PORT_ID 0xFFFFFF 254 #endif 255 256 #ifdef MODULE 257 #ifdef WLAN_WEAR_CHIPSET 258 #define WLAN_MODULE_NAME "wlan" 259 #else 260 #define WLAN_MODULE_NAME module_name(THIS_MODULE) 261 #endif 262 #else 263 #define WLAN_MODULE_NAME "wlan" 264 #endif 265 266 #ifdef TIMER_MANAGER 267 #define TIMER_MANAGER_STR " +TIMER_MANAGER" 268 #else 269 #define TIMER_MANAGER_STR "" 270 #endif 271 272 #ifdef MEMORY_DEBUG 273 #define MEMORY_DEBUG_STR " +MEMORY_DEBUG" 274 #else 275 #define MEMORY_DEBUG_STR "" 276 #endif 277 278 #ifdef PANIC_ON_BUG 279 #define PANIC_ON_BUG_STR " +PANIC_ON_BUG" 280 #else 281 #define PANIC_ON_BUG_STR "" 282 #endif 283 284 /* PCIe gen speed change idle shutdown timer 100 milliseconds */ 285 #define HDD_PCIE_GEN_SPEED_CHANGE_TIMEOUT_MS (100) 286 287 #define MAX_NET_DEV_REF_LEAK_ITERATIONS 10 288 #define NET_DEV_REF_LEAK_ITERATION_SLEEP_TIME_MS 10 289 290 #ifdef FEATURE_TSO 291 #define TSO_FEATURE_FLAGS (NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_SG) 292 #else 293 #define TSO_FEATURE_FLAGS 0 294 #endif 295 296 int wlan_start_ret_val; 297 static DECLARE_COMPLETION(wlan_start_comp); 298 static qdf_atomic_t wlan_hdd_state_fops_ref; 299 #ifndef MODULE 300 static struct gwlan_loader *wlan_loader; 301 static ssize_t wlan_boot_cb(struct kobject *kobj, 302 struct kobj_attribute *attr, 303 const char *buf, size_t count); 304 struct gwlan_loader { 305 bool loaded_state; 306 struct kobject *boot_wlan_obj; 307 struct attribute_group *attr_group; 308 }; 309 310 static struct kobj_attribute wlan_boot_attribute = 311 __ATTR(boot_wlan, 0220, NULL, wlan_boot_cb); 312 313 static struct attribute *attrs[] = { 314 &wlan_boot_attribute.attr, 315 NULL, 316 }; 317 #define MODULE_INITIALIZED 1 318 319 #ifdef MULTI_IF_NAME 320 #define WLAN_LOADER_NAME "boot_" MULTI_IF_NAME 321 #else 322 #define WLAN_LOADER_NAME "boot_wlan" 323 #endif 324 #endif 325 326 /* the Android framework expects this param even though we don't use it */ 327 #define BUF_LEN 20 328 static char fwpath_buffer[BUF_LEN]; 329 static struct kparam_string fwpath = { 330 .string = fwpath_buffer, 331 .maxlen = BUF_LEN, 332 }; 333 334 char *country_code; 335 #ifdef FEATURE_WLAN_RESIDENT_DRIVER 336 EXPORT_SYMBOL(country_code); 337 #endif 338 static int enable_11d = -1; 339 static int enable_dfs_chan_scan = -1; 340 static bool is_mode_change_psoc_idle_shutdown; 341 342 #define WLAN_NLINK_CESIUM 30 343 344 static qdf_wake_lock_t wlan_wake_lock; 345 346 /* The valid PCIe gen speeds are 1, 2, 3 */ 347 #define HDD_INVALID_MIN_PCIE_GEN_SPEED (0) 348 #define HDD_INVALID_MAX_PCIE_GEN_SPEED (4) 349 350 #define MAX_PDEV_PRE_ENABLE_PARAMS 8 351 #define FTM_MAX_PDEV_PARAMS 1 352 353 #define WOW_MAX_FILTER_LISTS 1 354 #define WOW_MAX_FILTERS_PER_LIST 4 355 #define WOW_MIN_PATTERN_SIZE 6 356 #define WOW_MAX_PATTERN_SIZE 64 357 #define MGMT_DEFAULT_DATA_RATE_6GHZ 0x400 /* This maps to 8.6Mbps data rate */ 358 359 #define IS_IDLE_STOP (!cds_is_driver_unloading() && \ 360 !cds_is_driver_recovering() && !cds_is_driver_loading()) 361 362 #define HDD_FW_VER_MAJOR_SPID(tgt_fw_ver) ((tgt_fw_ver & 0xf0000000) >> 28) 363 #define HDD_FW_VER_MINOR_SPID(tgt_fw_ver) ((tgt_fw_ver & 0xf000000) >> 24) 364 #define HDD_FW_VER_SIID(tgt_fw_ver) ((tgt_fw_ver & 0xf00000) >> 20) 365 #define HDD_FW_VER_CRM_ID(tgt_fw_ver) (tgt_fw_ver & 0x7fff) 366 #define HDD_FW_VER_SUB_ID(tgt_fw_ver_ext) \ 367 (((tgt_fw_ver_ext & 0x1c00) >> 6) | ((tgt_fw_ver_ext & 0xf0000000) >> 28)) 368 #define HDD_FW_VER_REL_ID(tgt_fw_ver_ext) \ 369 ((tgt_fw_ver_ext & 0xf800000) >> 23) 370 371 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0)) 372 static const struct wiphy_wowlan_support wowlan_support_reg_init = { 373 .flags = WIPHY_WOWLAN_ANY | 374 WIPHY_WOWLAN_MAGIC_PKT | 375 WIPHY_WOWLAN_DISCONNECT | 376 WIPHY_WOWLAN_SUPPORTS_GTK_REKEY | 377 WIPHY_WOWLAN_GTK_REKEY_FAILURE | 378 WIPHY_WOWLAN_EAP_IDENTITY_REQ | 379 WIPHY_WOWLAN_4WAY_HANDSHAKE | 380 WIPHY_WOWLAN_RFKILL_RELEASE, 381 .n_patterns = WOW_MAX_FILTER_LISTS * WOW_MAX_FILTERS_PER_LIST, 382 .pattern_min_len = WOW_MIN_PATTERN_SIZE, 383 .pattern_max_len = WOW_MAX_PATTERN_SIZE, 384 }; 385 #endif 386 387 static const struct category_info cinfo[MAX_SUPPORTED_CATEGORY] = { 388 [QDF_MODULE_ID_TLSHIM] = {QDF_TRACE_LEVEL_ALL}, 389 [QDF_MODULE_ID_WMI] = {QDF_TRACE_LEVEL_ALL}, 390 [QDF_MODULE_ID_HTT] = {QDF_TRACE_LEVEL_ALL}, 391 [QDF_MODULE_ID_HDD] = {QDF_TRACE_LEVEL_ALL}, 392 [QDF_MODULE_ID_SME] = {QDF_TRACE_LEVEL_ALL}, 393 [QDF_MODULE_ID_PE] = {QDF_TRACE_LEVEL_ALL}, 394 [QDF_MODULE_ID_WMA] = {QDF_TRACE_LEVEL_ALL}, 395 [QDF_MODULE_ID_SYS] = {QDF_TRACE_LEVEL_ALL}, 396 [QDF_MODULE_ID_QDF] = {QDF_TRACE_LEVEL_ALL}, 397 [QDF_MODULE_ID_SAP] = {QDF_TRACE_LEVEL_ALL}, 398 [QDF_MODULE_ID_HDD_SOFTAP] = {QDF_TRACE_LEVEL_ALL}, 399 [QDF_MODULE_ID_HDD_DATA] = {QDF_DATA_PATH_TRACE_LEVEL}, 400 [QDF_MODULE_ID_HDD_SAP_DATA] = {QDF_DATA_PATH_TRACE_LEVEL}, 401 [QDF_MODULE_ID_HIF] = {QDF_DATA_PATH_TRACE_LEVEL}, 402 [QDF_MODULE_ID_HTC] = {QDF_DATA_PATH_TRACE_LEVEL}, 403 [QDF_MODULE_ID_TXRX] = {QDF_DATA_PATH_TRACE_LEVEL}, 404 [QDF_MODULE_ID_HAL] = {QDF_DATA_PATH_TRACE_LEVEL}, 405 [QDF_MODULE_ID_QDF_DEVICE] = {QDF_TRACE_LEVEL_ALL}, 406 [QDF_MODULE_ID_CFG] = {QDF_TRACE_LEVEL_ALL}, 407 [QDF_MODULE_ID_BMI] = {QDF_TRACE_LEVEL_ALL}, 408 [QDF_MODULE_ID_EPPING] = {QDF_TRACE_LEVEL_ALL}, 409 [QDF_MODULE_ID_QVIT] = {QDF_TRACE_LEVEL_ALL}, 410 [QDF_MODULE_ID_DP] = {QDF_DATA_PATH_TRACE_LEVEL}, 411 [QDF_MODULE_ID_DP_TX_CAPTURE] = {QDF_DATA_PATH_TRACE_LEVEL}, 412 [QDF_MODULE_ID_DP_INIT] = {QDF_DATA_PATH_TRACE_LEVEL}, 413 [QDF_MODULE_ID_DP_STATS] = {QDF_DATA_PATH_TRACE_LEVEL}, 414 [QDF_MODULE_ID_DP_HTT] = {QDF_DATA_PATH_TRACE_LEVEL}, 415 [QDF_MODULE_ID_DP_PEER] = {QDF_DATA_PATH_TRACE_LEVEL}, 416 [QDF_MODULE_ID_DP_HTT_TX_STATS] = {QDF_DATA_PATH_TRACE_LEVEL}, 417 [QDF_MODULE_ID_DP_REO] = {QDF_DATA_PATH_TRACE_LEVEL}, 418 [QDF_MODULE_ID_DP_VDEV] = {QDF_DATA_PATH_TRACE_LEVEL}, 419 [QDF_MODULE_ID_DP_CDP] = {QDF_DATA_PATH_TRACE_LEVEL}, 420 [QDF_MODULE_ID_DP_UMAC_RESET] = {QDF_DATA_PATH_TRACE_LEVEL}, 421 [QDF_MODULE_ID_DP_SAWF] = {QDF_DATA_PATH_TRACE_LEVEL}, 422 [QDF_MODULE_ID_SOC] = {QDF_TRACE_LEVEL_ALL}, 423 [QDF_MODULE_ID_OS_IF] = {QDF_TRACE_LEVEL_ALL}, 424 [QDF_MODULE_ID_TARGET_IF] = {QDF_TRACE_LEVEL_ALL}, 425 [QDF_MODULE_ID_SCHEDULER] = {QDF_TRACE_LEVEL_ALL}, 426 [QDF_MODULE_ID_MGMT_TXRX] = {QDF_TRACE_LEVEL_ALL}, 427 [QDF_MODULE_ID_PMO] = {QDF_TRACE_LEVEL_ALL}, 428 [QDF_MODULE_ID_SCAN] = {QDF_TRACE_LEVEL_ALL}, 429 [QDF_MODULE_ID_POLICY_MGR] = {QDF_TRACE_LEVEL_ALL}, 430 [QDF_MODULE_ID_P2P] = {QDF_TRACE_LEVEL_ALL}, 431 [QDF_MODULE_ID_TDLS] = {QDF_TRACE_LEVEL_ALL}, 432 [QDF_MODULE_ID_REGULATORY] = {QDF_TRACE_LEVEL_ALL}, 433 [QDF_MODULE_ID_SERIALIZATION] = {QDF_TRACE_LEVEL_ALL}, 434 [QDF_MODULE_ID_DFS] = {QDF_TRACE_LEVEL_ALL}, 435 [QDF_MODULE_ID_OBJ_MGR] = {QDF_TRACE_LEVEL_ALL}, 436 [QDF_MODULE_ID_ROAM_DEBUG] = {QDF_TRACE_LEVEL_ALL}, 437 [QDF_MODULE_ID_GREEN_AP] = {QDF_TRACE_LEVEL_ALL}, 438 [QDF_MODULE_ID_OCB] = {QDF_TRACE_LEVEL_ALL}, 439 [QDF_MODULE_ID_IPA] = {QDF_TRACE_LEVEL_ALL}, 440 [QDF_MODULE_ID_ACTION_OUI] = {QDF_TRACE_LEVEL_ALL}, 441 [QDF_MODULE_ID_CONFIG] = {QDF_TRACE_LEVEL_ALL}, 442 [QDF_MODULE_ID_MLME] = {QDF_TRACE_LEVEL_ALL}, 443 [QDF_MODULE_ID_TARGET] = {QDF_TRACE_LEVEL_ALL}, 444 [QDF_MODULE_ID_CRYPTO] = {QDF_TRACE_LEVEL_ALL}, 445 [QDF_MODULE_ID_FWOL] = {QDF_TRACE_LEVEL_ALL}, 446 [QDF_MODULE_ID_SM_ENGINE] = {QDF_TRACE_LEVEL_ALL}, 447 [QDF_MODULE_ID_CMN_MLME] = {QDF_TRACE_LEVEL_ALL}, 448 [QDF_MODULE_ID_NAN] = {QDF_TRACE_LEVEL_ALL}, 449 [QDF_MODULE_ID_CP_STATS] = {QDF_TRACE_LEVEL_ALL}, 450 [QDF_MODULE_ID_DCS] = {QDF_TRACE_LEVEL_ALL}, 451 [QDF_MODULE_ID_INTEROP_ISSUES_AP] = {QDF_TRACE_LEVEL_ALL}, 452 [QDF_MODULE_ID_DENYLIST_MGR] = {QDF_TRACE_LEVEL_ALL}, 453 [QDF_MODULE_ID_DIRECT_BUF_RX] = {QDF_TRACE_LEVEL_ALL}, 454 [QDF_MODULE_ID_SPECTRAL] = {QDF_TRACE_LEVEL_ALL}, 455 [QDF_MODULE_ID_WIFIPOS] = {QDF_TRACE_LEVEL_ALL}, 456 [QDF_MODULE_ID_PKT_CAPTURE] = {QDF_TRACE_LEVEL_ALL}, 457 [QDF_MODULE_ID_FTM_TIME_SYNC] = {QDF_TRACE_LEVEL_ALL}, 458 [QDF_MODULE_ID_CFR] = {QDF_TRACE_LEVEL_ALL}, 459 [QDF_MODULE_ID_IFMGR] = {QDF_TRACE_LEVEL_ALL}, 460 [QDF_MODULE_ID_GPIO] = {QDF_TRACE_LEVEL_ALL}, 461 [QDF_MODULE_ID_T2LM] = {QDF_TRACE_LEVEL_ALL}, 462 [QDF_MODULE_ID_MLO] = {QDF_TRACE_LEVEL_ALL}, 463 [QDF_MODULE_ID_SON] = {QDF_TRACE_LEVEL_ALL}, 464 [QDF_MODULE_ID_TWT] = {QDF_TRACE_LEVEL_ALL}, 465 [QDF_MODULE_ID_WLAN_PRE_CAC] = {QDF_TRACE_LEVEL_ALL}, 466 [QDF_MODULE_ID_COAP] = {QDF_TRACE_LEVEL_ALL}, 467 [QDF_MODULE_ID_MON_FILTER] = {QDF_DATA_PATH_TRACE_LEVEL}, 468 [QDF_MODULE_ID_LL_SAP] = {QDF_TRACE_LEVEL_ALL}, 469 }; 470 471 struct notifier_block hdd_netdev_notifier; 472 473 struct sock *cesium_nl_srv_sock; 474 #ifdef FEATURE_WLAN_AUTO_SHUTDOWN 475 static void wlan_hdd_auto_shutdown_cb(void); 476 #endif 477 478 static void hdd_dp_register_callbacks(struct hdd_context *hdd_ctx); 479 480 bool hdd_adapter_is_ap(struct hdd_adapter *adapter) 481 { 482 if (!adapter) { 483 hdd_err("null adapter"); 484 return false; 485 } 486 487 return adapter->device_mode == QDF_SAP_MODE || 488 adapter->device_mode == QDF_P2P_GO_MODE; 489 } 490 491 QDF_STATUS hdd_common_roam_callback(struct wlan_objmgr_psoc *psoc, 492 uint8_t session_id, 493 struct csr_roam_info *roam_info, 494 eRoamCmdStatus roam_status, 495 eCsrRoamResult roam_result) 496 { 497 struct hdd_context *hdd_ctx; 498 struct hdd_adapter *adapter; 499 struct wlan_hdd_link_info *link_info; 500 QDF_STATUS status = QDF_STATUS_SUCCESS; 501 502 link_info = wlan_hdd_get_link_info_from_vdev(psoc, session_id); 503 if (!link_info) 504 return QDF_STATUS_E_INVAL; 505 506 adapter = link_info->adapter; 507 hdd_ctx = WLAN_HDD_GET_CTX(adapter); 508 if (!hdd_ctx) 509 return QDF_STATUS_E_INVAL; 510 511 switch (adapter->device_mode) { 512 case QDF_STA_MODE: 513 case QDF_NDI_MODE: 514 case QDF_P2P_CLIENT_MODE: 515 case QDF_P2P_DEVICE_MODE: 516 status = hdd_sme_roam_callback(link_info, roam_info, 517 roam_status, roam_result); 518 break; 519 case QDF_SAP_MODE: 520 case QDF_P2P_GO_MODE: 521 status = 522 wlansap_roam_callback(link_info->session.ap.sap_context, 523 roam_info, roam_status, 524 roam_result); 525 break; 526 default: 527 hdd_err("Wrong device mode"); 528 break; 529 } 530 531 return status; 532 } 533 534 void hdd_start_complete(int ret) 535 { 536 wlan_start_ret_val = ret; 537 complete_all(&wlan_start_comp); 538 } 539 540 #ifdef WLAN_FEATURE_LOCAL_PKT_CAPTURE 541 /** 542 * wlan_hdd_lpc_del_monitor_interface() - Delete monitor interface 543 * @hdd_ctx: hdd_ctx 544 * 545 * This function takes care of deleting monitor interface 546 * 547 * Return: none 548 */ 549 static void 550 wlan_hdd_lpc_del_monitor_interface(struct hdd_context *hdd_ctx) 551 { 552 struct hdd_adapter *adapter; 553 void *soc; 554 bool running; 555 556 if (!hdd_ctx) 557 return; 558 559 if (!ucfg_dp_is_local_pkt_capture_enabled(hdd_ctx->psoc)) 560 return; 561 562 soc = cds_get_context(QDF_MODULE_ID_SOC); 563 if (!soc) 564 return; 565 566 running = cdp_is_local_pkt_capture_running(soc, OL_TXRX_PDEV_ID); 567 if (!running) 568 return; 569 570 adapter = hdd_get_adapter(hdd_ctx, QDF_MONITOR_MODE); 571 if (!adapter) { 572 hdd_debug("There is no monitor adapter"); 573 return; 574 } 575 576 hdd_debug("lpc: Delete monitor interface"); 577 wlan_hdd_release_intf_addr(hdd_ctx, adapter->mac_addr.bytes); 578 hdd_stop_adapter(hdd_ctx, adapter); 579 hdd_close_adapter(hdd_ctx, adapter, true); 580 } 581 #else 582 static inline 583 void wlan_hdd_lpc_del_monitor_interface(struct hdd_context *hdd_ctx) 584 { 585 } 586 #endif 587 588 #ifdef QCA_HL_NETDEV_FLOW_CONTROL 589 void wlan_hdd_mod_fc_timer(struct hdd_adapter *adapter, 590 enum netif_action_type action) 591 { 592 struct hdd_stats *hdd_stats; 593 594 if (!adapter->tx_flow_timer_initialized) 595 return; 596 597 hdd_stats = &adapter->deflink->hdd_stats; 598 if (action == WLAN_WAKE_NON_PRIORITY_QUEUE) { 599 qdf_mc_timer_stop(&adapter->tx_flow_control_timer); 600 hdd_stats->tx_rx_stats.is_txflow_paused = false; 601 hdd_stats->tx_rx_stats.txflow_unpause_cnt++; 602 } else if (action == WLAN_STOP_NON_PRIORITY_QUEUE) { 603 QDF_STATUS status = 604 qdf_mc_timer_start(&adapter->tx_flow_control_timer, 605 WLAN_HDD_TX_FLOW_CONTROL_OS_Q_BLOCK_TIME); 606 607 if (!QDF_IS_STATUS_SUCCESS(status)) 608 hdd_err("Failed to start tx_flow_control_timer"); 609 else 610 hdd_stats->tx_rx_stats.txflow_timer_cnt++; 611 612 hdd_stats->tx_rx_stats.txflow_pause_cnt++; 613 hdd_stats->tx_rx_stats.is_txflow_paused = true; 614 } 615 } 616 #endif /* QCA_HL_NETDEV_FLOW_CONTROL */ 617 618 /** 619 * wlan_hdd_txrx_pause_cb() - pause callback from txrx layer 620 * @vdev_id: vdev_id 621 * @action: action type 622 * @reason: reason type 623 * 624 * Return: none 625 */ 626 void wlan_hdd_txrx_pause_cb(uint8_t vdev_id, 627 enum netif_action_type action, enum netif_reason_type reason) 628 { 629 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 630 struct hdd_adapter *adapter; 631 struct wlan_hdd_link_info *link_info; 632 633 if (!hdd_ctx) 634 return; 635 636 link_info = hdd_get_link_info_by_vdev(hdd_ctx, vdev_id); 637 if (!link_info) 638 return; 639 640 adapter = link_info->adapter; 641 wlan_hdd_mod_fc_timer(adapter, action); 642 wlan_hdd_netif_queue_control(adapter, action, reason); 643 } 644 645 /* 646 * Store WLAN driver version and timestamp info in global variables such that 647 * crash debugger can extract them from driver debug symbol and crashdump for 648 * post processing 649 */ 650 #ifdef BUILD_TAG 651 uint8_t g_wlan_driver_version[] = QWLAN_VERSIONSTR TIMER_MANAGER_STR MEMORY_DEBUG_STR PANIC_ON_BUG_STR "; " BUILD_TAG; 652 #else 653 uint8_t g_wlan_driver_version[] = QWLAN_VERSIONSTR TIMER_MANAGER_STR MEMORY_DEBUG_STR PANIC_ON_BUG_STR; 654 #endif 655 656 int hdd_validate_channel_and_bandwidth(struct hdd_adapter *adapter, 657 qdf_freq_t chan_freq, 658 enum phy_ch_width chan_bw) 659 { 660 struct ch_params ch_params = {0}; 661 struct hdd_context *hdd_ctx; 662 663 hdd_ctx = WLAN_HDD_GET_CTX(adapter); 664 if (!hdd_ctx) { 665 hdd_err("hdd context is NULL"); 666 return -EINVAL; 667 } 668 669 if (reg_is_chan_enum_invalid( 670 wlan_reg_get_chan_enum_for_freq(chan_freq))) { 671 hdd_err("Channel freq %d not in driver's valid channel list", chan_freq); 672 return -EOPNOTSUPP; 673 } 674 675 if ((!WLAN_REG_IS_24GHZ_CH_FREQ(chan_freq)) && 676 (!WLAN_REG_IS_5GHZ_CH_FREQ(chan_freq)) && 677 (!WLAN_REG_IS_6GHZ_CHAN_FREQ(chan_freq))) { 678 hdd_err("CH %d is not in 2.4GHz or 5GHz or 6GHz", chan_freq); 679 return -EINVAL; 680 } 681 ch_params.ch_width = CH_WIDTH_MAX; 682 wlan_reg_set_channel_params_for_pwrmode(hdd_ctx->pdev, chan_freq, 683 0, &ch_params, 684 REG_CURRENT_PWR_MODE); 685 if (ch_params.ch_width == CH_WIDTH_MAX) { 686 hdd_err("failed to get max bandwdith for %d", chan_freq); 687 return -EINVAL; 688 } 689 if (WLAN_REG_IS_24GHZ_CH_FREQ(chan_freq)) { 690 if (chan_bw == CH_WIDTH_80MHZ) { 691 hdd_err("BW80 not possible in 2.4GHz band"); 692 return -EINVAL; 693 } 694 if ((chan_bw != CH_WIDTH_20MHZ) && 695 (chan_freq == wlan_reg_ch_to_freq(CHAN_ENUM_2484)) && 696 (chan_bw != CH_WIDTH_MAX) && 697 (ch_params.ch_width == CH_WIDTH_20MHZ)) { 698 hdd_err("Only BW20 possible on channel freq 2484"); 699 return -EINVAL; 700 } 701 } 702 703 if (WLAN_REG_IS_5GHZ_CH_FREQ(chan_freq)) { 704 if ((chan_bw != CH_WIDTH_20MHZ) && 705 (chan_freq == wlan_reg_ch_to_freq(CHAN_ENUM_5825)) && 706 (chan_bw != CH_WIDTH_MAX) && 707 (ch_params.ch_width == CH_WIDTH_20MHZ)) { 708 hdd_err("Only BW20 possible on channel freq 5825"); 709 return -EINVAL; 710 } 711 } 712 713 return 0; 714 } 715 716 uint32_t hdd_get_link_info_home_channel(struct wlan_hdd_link_info *link_info) 717 { 718 uint32_t home_chan_freq = 0; 719 enum QDF_OPMODE opmode = link_info->adapter->device_mode; 720 721 switch (opmode) { 722 case QDF_SAP_MODE: 723 case QDF_P2P_GO_MODE: 724 if (test_bit(SOFTAP_BSS_STARTED, &link_info->link_flags)) { 725 home_chan_freq = 726 link_info->session.ap.operating_chan_freq; 727 } 728 break; 729 case QDF_STA_MODE: 730 case QDF_P2P_CLIENT_MODE: 731 if (hdd_cm_is_vdev_associated(link_info)) { 732 home_chan_freq = 733 link_info->session.station.conn_info.chan_freq; 734 } 735 break; 736 default: 737 break; 738 } 739 740 return home_chan_freq; 741 } 742 743 enum phy_ch_width hdd_get_link_info_width(struct wlan_hdd_link_info *link_info) 744 { 745 enum phy_ch_width width = CH_WIDTH_20MHZ; 746 enum QDF_OPMODE opmode = link_info->adapter->device_mode; 747 748 switch (opmode) { 749 case QDF_SAP_MODE: 750 case QDF_P2P_GO_MODE: 751 if (test_bit(SOFTAP_BSS_STARTED, &link_info->link_flags)) { 752 struct hdd_ap_ctx *ap_ctx = 753 WLAN_HDD_GET_AP_CTX_PTR(link_info); 754 755 width = ap_ctx->sap_config.ch_params.ch_width; 756 } 757 break; 758 case QDF_STA_MODE: 759 case QDF_P2P_CLIENT_MODE: 760 if (hdd_cm_is_vdev_associated(link_info)) 761 width = link_info->session.station.conn_info.ch_width; 762 break; 763 default: 764 break; 765 } 766 767 return width; 768 } 769 770 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0)) 771 static inline struct net_device *hdd_net_dev_from_notifier(void *context) 772 { 773 struct netdev_notifier_info *info = context; 774 775 return info->dev; 776 } 777 #else 778 static inline struct net_device *hdd_net_dev_from_notifier(void *context) 779 { 780 return context; 781 } 782 #endif 783 784 static int __hdd_netdev_notifier_call(struct net_device *net_dev, 785 unsigned long state) 786 { 787 struct hdd_adapter *adapter; 788 struct hdd_context *hdd_ctx; 789 struct wlan_objmgr_vdev *vdev; 790 791 hdd_enter_dev(net_dev); 792 793 if (!net_dev->ieee80211_ptr) { 794 hdd_debug("ieee80211_ptr is null"); 795 return NOTIFY_DONE; 796 } 797 798 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 799 if (!hdd_ctx) 800 return NOTIFY_DONE; 801 802 if (hdd_ctx->driver_status == DRIVER_MODULES_CLOSED) { 803 hdd_debug("Driver module is closed"); 804 return NOTIFY_DONE; 805 } 806 807 /* Make sure that this callback corresponds to our device. */ 808 adapter = hdd_get_adapter_by_iface_name(hdd_ctx, net_dev->name); 809 if (!adapter) { 810 hdd_debug("failed to look up adapter for '%s'", net_dev->name); 811 return NOTIFY_DONE; 812 } 813 814 if (adapter != WLAN_HDD_GET_PRIV_PTR(net_dev)) { 815 hdd_err("HDD adapter mismatch!"); 816 return NOTIFY_DONE; 817 } 818 819 if (cds_is_driver_recovering()) { 820 hdd_debug("Driver is recovering"); 821 return NOTIFY_DONE; 822 } 823 824 if (cds_is_driver_in_bad_state()) { 825 hdd_debug("Driver is in failed recovery state"); 826 return NOTIFY_DONE; 827 } 828 829 hdd_debug("%s New Net Device State = %lu, flags 0x%x", 830 net_dev->name, state, net_dev->flags); 831 832 switch (state) { 833 case NETDEV_REGISTER: 834 break; 835 836 case NETDEV_UNREGISTER: 837 break; 838 839 case NETDEV_UP: 840 sme_ch_avoid_update_req(hdd_ctx->mac_handle); 841 break; 842 843 case NETDEV_DOWN: 844 break; 845 846 case NETDEV_CHANGE: 847 if (adapter->is_link_up_service_needed) 848 complete(&adapter->linkup_event_var); 849 break; 850 851 case NETDEV_GOING_DOWN: 852 vdev = hdd_objmgr_get_vdev_by_user(adapter->deflink, 853 WLAN_OSIF_SCAN_ID); 854 if (!vdev) 855 break; 856 if (ucfg_scan_get_vdev_status(vdev) != 857 SCAN_NOT_IN_PROGRESS) { 858 wlan_abort_scan(hdd_ctx->pdev, INVAL_PDEV_ID, 859 adapter->deflink->vdev_id, 860 INVALID_SCAN_ID, true); 861 } 862 hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_SCAN_ID); 863 cds_flush_work(&adapter->scan_block_work); 864 /* Need to clean up blocked scan request */ 865 wlan_hdd_cfg80211_scan_block(adapter); 866 hdd_debug("Scan is not Pending from user"); 867 /* 868 * After NETDEV_GOING_DOWN, kernel calls hdd_stop.Irrespective 869 * of return status of hdd_stop call, kernel resets the IFF_UP 870 * flag after which driver does not send the cfg80211_scan_done. 871 * Ensure to cleanup the scan queue in NETDEV_GOING_DOWN 872 */ 873 wlan_cfg80211_cleanup_scan_queue(hdd_ctx->pdev, net_dev); 874 break; 875 case NETDEV_FEAT_CHANGE: 876 hdd_debug("vdev %d netdev Feature 0x%llx\n", 877 adapter->deflink->vdev_id, net_dev->features); 878 break; 879 default: 880 break; 881 } 882 883 return NOTIFY_DONE; 884 } 885 886 static int hdd_netdev_notifier_bridge_intf(struct net_device *net_dev, 887 unsigned long state) 888 { 889 struct hdd_adapter *adapter, *next_adapter = NULL; 890 wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_GET_ADAPTER; 891 struct hdd_context *hdd_ctx; 892 QDF_STATUS status; 893 894 hdd_enter_dev(net_dev); 895 896 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 897 if (wlan_hdd_validate_context(hdd_ctx)) 898 return NOTIFY_DONE; 899 900 hdd_debug("%s New Net Device State = %lu, flags 0x%x bridge mac address: "QDF_MAC_ADDR_FMT, 901 net_dev->name, state, net_dev->flags, QDF_MAC_ADDR_REF(net_dev->dev_addr)); 902 903 if (!qdf_mem_cmp(hdd_ctx->bridgeaddr, net_dev->dev_addr, 904 QDF_MAC_ADDR_SIZE)) 905 return NOTIFY_DONE; 906 907 switch (state) { 908 case NETDEV_REGISTER: 909 case NETDEV_CHANGEADDR: 910 /* Update FW WoW pattern with new MAC address */ 911 qdf_mem_copy(hdd_ctx->bridgeaddr, net_dev->dev_addr, 912 QDF_MAC_ADDR_SIZE); 913 914 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 915 dbgid) { 916 if (adapter->device_mode != QDF_SAP_MODE) 917 goto loop_next; 918 919 if (wlan_hdd_validate_vdev_id(adapter->deflink->vdev_id)) 920 goto loop_next; 921 922 status = wlan_objmgr_vdev_try_get_ref(adapter->deflink->vdev, 923 WLAN_HDD_ID_OBJ_MGR); 924 if (QDF_IS_STATUS_ERROR(status)) 925 goto loop_next; 926 927 ucfg_pmo_set_vdev_bridge_addr(adapter->deflink->vdev, 928 (struct qdf_mac_addr *)hdd_ctx->bridgeaddr); 929 ucfg_pmo_del_wow_pattern(adapter->deflink->vdev); 930 ucfg_pmo_register_wow_default_patterns(adapter->deflink->vdev); 931 932 wlan_objmgr_vdev_release_ref(adapter->deflink->vdev, 933 WLAN_HDD_ID_OBJ_MGR); 934 935 loop_next: 936 hdd_adapter_dev_put_debug(adapter, dbgid); 937 } 938 939 break; 940 case NETDEV_UNREGISTER: 941 qdf_zero_macaddr((struct qdf_mac_addr *)hdd_ctx->bridgeaddr); 942 break; 943 default: 944 break; 945 } 946 947 return NOTIFY_DONE; 948 } 949 950 /** 951 * hdd_netdev_notifier_call() - netdev notifier callback function 952 * @nb: pointer to notifier block 953 * @state: state 954 * @context: notifier callback context pointer 955 * 956 * Return: 0 on success, error number otherwise. 957 */ 958 static int hdd_netdev_notifier_call(struct notifier_block *nb, 959 unsigned long state, 960 void *context) 961 { 962 struct net_device *net_dev = hdd_net_dev_from_notifier(context); 963 struct osif_vdev_sync *vdev_sync; 964 int errno; 965 966 if (net_dev->priv_flags & IFF_EBRIDGE) { 967 errno = hdd_netdev_notifier_bridge_intf(net_dev, state); 968 if (errno) 969 return NOTIFY_DONE; 970 } 971 972 errno = osif_vdev_sync_op_start(net_dev, &vdev_sync); 973 if (errno) 974 return NOTIFY_DONE; 975 976 errno = __hdd_netdev_notifier_call(net_dev, state); 977 978 osif_vdev_sync_op_stop(vdev_sync); 979 980 return NOTIFY_DONE; 981 } 982 983 struct notifier_block hdd_netdev_notifier = { 984 .notifier_call = hdd_netdev_notifier_call, 985 }; 986 987 /* variable to hold the insmod parameters */ 988 int con_mode; 989 #ifdef FEATURE_WLAN_RESIDENT_DRIVER 990 EXPORT_SYMBOL(con_mode); 991 #endif 992 993 int con_mode_ftm; 994 #ifdef FEATURE_WLAN_RESIDENT_DRIVER 995 EXPORT_SYMBOL(con_mode_ftm); 996 #endif 997 int con_mode_epping; 998 999 static int pcie_gen_speed; 1000 1001 /* Variable to hold connection mode including module parameter con_mode */ 1002 static int curr_con_mode; 1003 1004 #if defined(WLAN_FEATURE_11BE) && defined(CFG80211_11BE_BASIC) 1005 static enum phy_ch_width hdd_get_eht_phy_ch_width_from_target(void) 1006 { 1007 uint32_t max_fw_bw = sme_get_eht_ch_width(); 1008 1009 if (max_fw_bw == WNI_CFG_EHT_CHANNEL_WIDTH_320MHZ) 1010 return CH_WIDTH_320MHZ; 1011 else if (max_fw_bw == WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ) 1012 return CH_WIDTH_160MHZ; 1013 else 1014 return CH_WIDTH_80MHZ; 1015 } 1016 1017 static bool hdd_is_target_eht_phy_ch_width_supported(enum phy_ch_width width) 1018 { 1019 enum phy_ch_width max_fw_bw = hdd_get_eht_phy_ch_width_from_target(); 1020 1021 if (width <= max_fw_bw) 1022 return true; 1023 1024 hdd_err("FW does not support this BW %d max BW supported %d", 1025 width, max_fw_bw); 1026 return false; 1027 } 1028 1029 static bool hdd_is_target_eht_160mhz_capable(void) 1030 { 1031 return hdd_is_target_eht_phy_ch_width_supported(CH_WIDTH_160MHZ); 1032 } 1033 1034 static enum phy_ch_width 1035 wlan_hdd_map_nl_chan_width(enum nl80211_chan_width width) 1036 { 1037 if (width == NL80211_CHAN_WIDTH_320) { 1038 return hdd_get_eht_phy_ch_width_from_target(); 1039 } else { 1040 hdd_err("Invalid channel width %d, setting to default", width); 1041 return CH_WIDTH_INVALID; 1042 } 1043 } 1044 1045 #else /* !WLAN_FEATURE_11BE */ 1046 static inline bool 1047 hdd_is_target_eht_phy_ch_width_supported(enum phy_ch_width width) 1048 { 1049 return true; 1050 } 1051 1052 static inline bool hdd_is_target_eht_160mhz_capable(void) 1053 { 1054 return false; 1055 } 1056 1057 static enum phy_ch_width 1058 wlan_hdd_map_nl_chan_width(enum nl80211_chan_width width) 1059 { 1060 hdd_err("Invalid channel width %d, setting to default", width); 1061 return CH_WIDTH_INVALID; 1062 } 1063 #endif /* WLAN_FEATURE_11BE */ 1064 1065 /** 1066 * hdd_map_nl_chan_width() - Map NL channel width to internal representation 1067 * @ch_width: NL channel width 1068 * 1069 * Converts the NL channel width to the driver's internal representation 1070 * 1071 * Return: Converted channel width. In case of non matching NL channel width, 1072 * CH_WIDTH_MAX will be returned. 1073 */ 1074 enum phy_ch_width hdd_map_nl_chan_width(enum nl80211_chan_width ch_width) 1075 { 1076 uint8_t fw_ch_bw; 1077 1078 fw_ch_bw = wma_get_vht_ch_width(); 1079 switch (ch_width) { 1080 case NL80211_CHAN_WIDTH_20_NOHT: 1081 case NL80211_CHAN_WIDTH_20: 1082 return CH_WIDTH_20MHZ; 1083 case NL80211_CHAN_WIDTH_40: 1084 return CH_WIDTH_40MHZ; 1085 case NL80211_CHAN_WIDTH_80: 1086 return CH_WIDTH_80MHZ; 1087 case NL80211_CHAN_WIDTH_80P80: 1088 if (fw_ch_bw == WNI_CFG_VHT_CHANNEL_WIDTH_80_PLUS_80MHZ) 1089 return CH_WIDTH_80P80MHZ; 1090 else if (fw_ch_bw == WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ) 1091 return CH_WIDTH_160MHZ; 1092 else 1093 return CH_WIDTH_80MHZ; 1094 case NL80211_CHAN_WIDTH_160: 1095 if (hdd_is_target_eht_160mhz_capable()) 1096 return CH_WIDTH_160MHZ; 1097 1098 if (fw_ch_bw >= WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ) 1099 return CH_WIDTH_160MHZ; 1100 else 1101 return CH_WIDTH_80MHZ; 1102 case NL80211_CHAN_WIDTH_5: 1103 return CH_WIDTH_5MHZ; 1104 case NL80211_CHAN_WIDTH_10: 1105 return CH_WIDTH_10MHZ; 1106 default: 1107 return wlan_hdd_map_nl_chan_width(ch_width); 1108 } 1109 } 1110 1111 #if defined(WLAN_FEATURE_NAN) && \ 1112 (KERNEL_VERSION(4, 9, 0) <= LINUX_VERSION_CODE) 1113 /** 1114 * wlan_hdd_convert_nan_type() - Convert nl type to qdf type 1115 * @nl_type: NL80211 interface type 1116 * @out_qdf_type: QDF type for the given nl_type 1117 * 1118 * Convert nl type to QDF type 1119 * 1120 * Return: QDF_STATUS_SUCCESS if converted, failure otherwise. 1121 */ 1122 static QDF_STATUS wlan_hdd_convert_nan_type(enum nl80211_iftype nl_type, 1123 enum QDF_OPMODE *out_qdf_type) 1124 { 1125 if (nl_type == NL80211_IFTYPE_NAN) { 1126 *out_qdf_type = QDF_NAN_DISC_MODE; 1127 return QDF_STATUS_SUCCESS; 1128 } 1129 return QDF_STATUS_E_INVAL; 1130 } 1131 1132 /** 1133 * wlan_hdd_set_nan_if_type() - Set the NAN iftype 1134 * @adapter: pointer to HDD adapter 1135 * 1136 * Set the NL80211_IFTYPE_NAN to wdev iftype. 1137 * 1138 * Return: None 1139 */ 1140 static void wlan_hdd_set_nan_if_type(struct hdd_adapter *adapter) 1141 { 1142 adapter->wdev.iftype = NL80211_IFTYPE_NAN; 1143 } 1144 1145 static bool wlan_hdd_is_vdev_creation_allowed(struct wlan_objmgr_psoc *psoc) 1146 { 1147 return ucfg_nan_is_vdev_creation_allowed(psoc); 1148 } 1149 #else 1150 static QDF_STATUS wlan_hdd_convert_nan_type(enum nl80211_iftype nl_type, 1151 enum QDF_OPMODE *out_qdf_type) 1152 { 1153 return QDF_STATUS_E_INVAL; 1154 } 1155 1156 static void wlan_hdd_set_nan_if_type(struct hdd_adapter *adapter) 1157 { 1158 } 1159 1160 static bool wlan_hdd_is_vdev_creation_allowed(struct wlan_objmgr_psoc *psoc) 1161 { 1162 return false; 1163 } 1164 #endif 1165 1166 QDF_STATUS hdd_nl_to_qdf_iface_type(enum nl80211_iftype nl_type, 1167 enum QDF_OPMODE *out_qdf_type) 1168 { 1169 QDF_STATUS status = QDF_STATUS_SUCCESS; 1170 1171 switch (nl_type) { 1172 case NL80211_IFTYPE_AP: 1173 *out_qdf_type = QDF_SAP_MODE; 1174 break; 1175 case NL80211_IFTYPE_MONITOR: 1176 *out_qdf_type = QDF_MONITOR_MODE; 1177 break; 1178 case NL80211_IFTYPE_OCB: 1179 *out_qdf_type = QDF_OCB_MODE; 1180 break; 1181 case NL80211_IFTYPE_P2P_CLIENT: 1182 *out_qdf_type = QDF_P2P_CLIENT_MODE; 1183 break; 1184 case NL80211_IFTYPE_P2P_DEVICE: 1185 *out_qdf_type = QDF_P2P_DEVICE_MODE; 1186 break; 1187 case NL80211_IFTYPE_P2P_GO: 1188 *out_qdf_type = QDF_P2P_GO_MODE; 1189 break; 1190 case NL80211_IFTYPE_STATION: 1191 *out_qdf_type = QDF_STA_MODE; 1192 break; 1193 case NL80211_IFTYPE_WDS: 1194 *out_qdf_type = QDF_WDS_MODE; 1195 break; 1196 default: 1197 status = wlan_hdd_convert_nan_type(nl_type, out_qdf_type); 1198 if (QDF_IS_STATUS_SUCCESS(status)) 1199 break; 1200 hdd_err("Invalid nl80211 interface type %d", nl_type); 1201 return QDF_STATUS_E_INVAL; 1202 } 1203 1204 return QDF_STATUS_SUCCESS; 1205 } 1206 1207 uint8_t wlan_hdd_find_opclass(mac_handle_t mac_handle, uint8_t channel, 1208 uint8_t bw_offset) 1209 { 1210 uint8_t opclass = 0; 1211 1212 sme_get_opclass(mac_handle, channel, bw_offset, &opclass); 1213 return opclass; 1214 } 1215 1216 /** 1217 * hdd_qdf_trace_enable() - configure initial QDF Trace enable 1218 * @module_id: Module whose trace level is being configured 1219 * @bitmask: Bitmask of log levels to be enabled 1220 * 1221 * Called immediately after the cfg.ini is read in order to configure 1222 * the desired trace levels. 1223 * 1224 * Return: None 1225 */ 1226 int hdd_qdf_trace_enable(QDF_MODULE_ID module_id, uint32_t bitmask) 1227 { 1228 QDF_TRACE_LEVEL level; 1229 int qdf_print_idx = -1; 1230 int status = -1; 1231 /* 1232 * if the bitmask is the default value, then a bitmask was not 1233 * specified in cfg.ini, so leave the logging level alone (it 1234 * will remain at the "compiled in" default value) 1235 */ 1236 if (CFG_QDF_TRACE_ENABLE_DEFAULT == bitmask) 1237 return 0; 1238 1239 qdf_print_idx = qdf_get_pidx(); 1240 1241 /* a mask was specified. start by disabling all logging */ 1242 status = qdf_print_set_category_verbose(qdf_print_idx, module_id, 1243 QDF_TRACE_LEVEL_NONE, 0); 1244 1245 if (QDF_STATUS_SUCCESS != status) 1246 return -EINVAL; 1247 /* now cycle through the bitmask until all "set" bits are serviced */ 1248 level = QDF_TRACE_LEVEL_NONE; 1249 while (0 != bitmask) { 1250 if (bitmask & 1) { 1251 status = qdf_print_set_category_verbose(qdf_print_idx, 1252 module_id, level, 1); 1253 if (QDF_STATUS_SUCCESS != status) 1254 return -EINVAL; 1255 } 1256 1257 level++; 1258 bitmask >>= 1; 1259 } 1260 return 0; 1261 } 1262 1263 int __wlan_hdd_validate_context(struct hdd_context *hdd_ctx, const char *func) 1264 { 1265 if (!hdd_ctx) { 1266 hdd_err("HDD context is null (via %s)", func); 1267 return -ENODEV; 1268 } 1269 1270 if (!hdd_ctx->config) { 1271 hdd_err("HDD config is null (via %s)", func); 1272 return -ENODEV; 1273 } 1274 1275 if (cds_is_driver_recovering()) { 1276 hdd_debug("Recovery in progress (via %s); state:0x%x", 1277 func, cds_get_driver_state()); 1278 return -EAGAIN; 1279 } 1280 1281 if (cds_is_load_or_unload_in_progress()) { 1282 hdd_debug("Load/unload in progress (via %s); state:0x%x", 1283 func, cds_get_driver_state()); 1284 return -EAGAIN; 1285 } 1286 1287 if (cds_is_driver_in_bad_state()) { 1288 hdd_debug("Driver in bad state (via %s); state:0x%x", 1289 func, cds_get_driver_state()); 1290 return -EAGAIN; 1291 } 1292 1293 if (cds_is_fw_down()) { 1294 hdd_debug("FW is down (via %s); state:0x%x", 1295 func, cds_get_driver_state()); 1296 return -EAGAIN; 1297 } 1298 1299 if (hdd_ctx->is_wlan_disabled) { 1300 hdd_debug("WLAN is disabled by user space"); 1301 return -EAGAIN; 1302 } 1303 1304 return 0; 1305 } 1306 1307 int __hdd_validate_adapter(struct hdd_adapter *adapter, const char *func) 1308 { 1309 if (!adapter) { 1310 hdd_err("adapter is null (via %s)", func); 1311 return -EINVAL; 1312 } 1313 1314 if (adapter->magic != WLAN_HDD_ADAPTER_MAGIC) { 1315 hdd_err("bad adapter magic (via %s)", func); 1316 return -EINVAL; 1317 } 1318 1319 if (!adapter->dev) { 1320 hdd_err("adapter net_device is null (via %s)", func); 1321 return -EINVAL; 1322 } 1323 1324 if (!(adapter->dev->flags & IFF_UP)) { 1325 hdd_debug_rl("adapter '%s' is not up (via %s)", 1326 adapter->dev->name, func); 1327 return -EAGAIN; 1328 } 1329 1330 return __wlan_hdd_validate_vdev_id(adapter->deflink->vdev_id, func); 1331 } 1332 1333 int __wlan_hdd_validate_vdev_id(uint8_t vdev_id, const char *func) 1334 { 1335 if (vdev_id == WLAN_UMAC_VDEV_ID_MAX) { 1336 hdd_debug_rl("adapter is not up (via %s)", func); 1337 return -EINVAL; 1338 } 1339 1340 if (vdev_id >= WLAN_MAX_VDEVS) { 1341 hdd_err("bad vdev Id:%u (via %s)", vdev_id, func); 1342 return -EINVAL; 1343 } 1344 1345 return 0; 1346 } 1347 1348 QDF_STATUS __wlan_hdd_validate_mac_address(struct qdf_mac_addr *mac_addr, 1349 const char *func) 1350 { 1351 if (!mac_addr) { 1352 hdd_err("Received NULL mac address (via %s)", func); 1353 return QDF_STATUS_E_INVAL; 1354 } 1355 1356 if (qdf_is_macaddr_zero(mac_addr)) { 1357 hdd_err("MAC is all zero (via %s)", func); 1358 return QDF_STATUS_E_INVAL; 1359 } 1360 1361 if (qdf_is_macaddr_broadcast(mac_addr)) { 1362 hdd_err("MAC is Broadcast (via %s)", func); 1363 return QDF_STATUS_E_INVAL; 1364 } 1365 1366 if (QDF_NET_IS_MAC_MULTICAST(mac_addr->bytes)) { 1367 hdd_err("MAC is Multicast (via %s)", func); 1368 return QDF_STATUS_E_INVAL; 1369 } 1370 1371 return QDF_STATUS_SUCCESS; 1372 } 1373 1374 /** 1375 * wlan_hdd_validate_modules_state() - Check modules status 1376 * @hdd_ctx: HDD context pointer 1377 * 1378 * Check's the driver module's state and returns true if the 1379 * modules are enabled returns false if modules are closed. 1380 * 1381 * Return: True if modules are enabled or false. 1382 */ 1383 bool wlan_hdd_validate_modules_state(struct hdd_context *hdd_ctx) 1384 { 1385 if (hdd_ctx->driver_status != DRIVER_MODULES_ENABLED) { 1386 hdd_info("Modules not enabled, Present status: %d", 1387 hdd_ctx->driver_status); 1388 return false; 1389 } 1390 1391 return true; 1392 } 1393 1394 #ifdef FEATURE_RUNTIME_PM 1395 /** 1396 * hdd_runtime_suspend_context_init() - API to initialize HDD Runtime Contexts 1397 * @hdd_ctx: HDD context 1398 * 1399 * Return: None 1400 */ 1401 static void hdd_runtime_suspend_context_init(struct hdd_context *hdd_ctx) 1402 { 1403 struct hdd_runtime_pm_context *ctx = &hdd_ctx->runtime_context; 1404 1405 qdf_runtime_lock_init(&ctx->dfs); 1406 qdf_runtime_lock_init(&ctx->connect); 1407 qdf_runtime_lock_init(&ctx->user); 1408 qdf_runtime_lock_init(&ctx->monitor_mode); 1409 qdf_runtime_lock_init(&ctx->wow_unit_test); 1410 qdf_runtime_lock_init(&ctx->system_suspend); 1411 qdf_runtime_lock_init(&ctx->dyn_mac_addr_update); 1412 qdf_runtime_lock_init(&ctx->vdev_destroy); 1413 qdf_runtime_lock_init(&ctx->oem_data_cmd); 1414 1415 qdf_rtpm_register(QDF_RTPM_ID_WIPHY_SUSPEND, NULL); 1416 qdf_rtpm_register(QDF_RTPM_ID_PM_QOS_NOTIFY, NULL); 1417 1418 ctx->is_user_wakelock_acquired = false; 1419 1420 wlan_scan_runtime_pm_init(hdd_ctx->pdev); 1421 } 1422 1423 /** 1424 * hdd_runtime_suspend_context_deinit() - API to deinit HDD runtime context 1425 * @hdd_ctx: HDD Context 1426 * 1427 * Return: None 1428 */ 1429 static void hdd_runtime_suspend_context_deinit(struct hdd_context *hdd_ctx) 1430 { 1431 struct hdd_runtime_pm_context *ctx = &hdd_ctx->runtime_context; 1432 1433 if (ctx->is_user_wakelock_acquired) 1434 qdf_runtime_pm_allow_suspend(&ctx->user); 1435 1436 qdf_runtime_lock_deinit(&ctx->oem_data_cmd); 1437 qdf_runtime_lock_deinit(&ctx->dyn_mac_addr_update); 1438 qdf_runtime_lock_deinit(&ctx->wow_unit_test); 1439 qdf_runtime_lock_deinit(&ctx->monitor_mode); 1440 qdf_runtime_lock_deinit(&ctx->user); 1441 qdf_runtime_lock_deinit(&ctx->connect); 1442 qdf_runtime_lock_deinit(&ctx->dfs); 1443 qdf_runtime_lock_deinit(&ctx->system_suspend); 1444 qdf_runtime_lock_deinit(&ctx->vdev_destroy); 1445 1446 qdf_rtpm_deregister(QDF_RTPM_ID_WIPHY_SUSPEND); 1447 qdf_rtpm_deregister(QDF_RTPM_ID_PM_QOS_NOTIFY); 1448 1449 wlan_scan_runtime_pm_deinit(hdd_ctx->pdev); 1450 } 1451 1452 #else /* FEATURE_RUNTIME_PM */ 1453 static void hdd_runtime_suspend_context_init(struct hdd_context *hdd_ctx) {} 1454 static void hdd_runtime_suspend_context_deinit(struct hdd_context *hdd_ctx) {} 1455 #endif /* FEATURE_RUNTIME_PM */ 1456 1457 void hdd_update_macaddr(struct hdd_context *hdd_ctx, 1458 struct qdf_mac_addr hw_macaddr, bool generate_mac_auto) 1459 { 1460 int8_t i; 1461 uint8_t macaddr_b3, tmp_br3; 1462 1463 /* 1464 * If "generate_mac_auto" is true, it indicates that all the 1465 * addresses are derived addresses, else the first addresses 1466 * is not derived address (It is provided by fw). 1467 */ 1468 if (!generate_mac_auto) { 1469 qdf_mem_copy(hdd_ctx->provisioned_mac_addr[0].bytes, 1470 hw_macaddr.bytes, QDF_MAC_ADDR_SIZE); 1471 hdd_ctx->num_provisioned_addr++; 1472 hdd_debug("hdd_ctx->provisioned_mac_addr[0]: " 1473 QDF_MAC_ADDR_FMT, 1474 QDF_MAC_ADDR_REF(hdd_ctx-> 1475 provisioned_mac_addr[0].bytes)); 1476 } else { 1477 qdf_mem_copy(hdd_ctx->derived_mac_addr[0].bytes, 1478 hw_macaddr.bytes, 1479 QDF_MAC_ADDR_SIZE); 1480 hdd_ctx->num_derived_addr++; 1481 hdd_debug("hdd_ctx->derived_mac_addr[0]: " 1482 QDF_MAC_ADDR_FMT, 1483 QDF_MAC_ADDR_REF(hdd_ctx->derived_mac_addr[0].bytes)); 1484 } 1485 for (i = hdd_ctx->num_derived_addr; i < (QDF_MAX_CONCURRENCY_PERSONA - 1486 hdd_ctx->num_provisioned_addr); 1487 i++) { 1488 qdf_mem_copy(hdd_ctx->derived_mac_addr[i].bytes, 1489 hw_macaddr.bytes, 1490 QDF_MAC_ADDR_SIZE); 1491 macaddr_b3 = hdd_ctx->derived_mac_addr[i].bytes[3]; 1492 tmp_br3 = ((macaddr_b3 >> 4 & INTF_MACADDR_MASK) + i) & 1493 INTF_MACADDR_MASK; 1494 macaddr_b3 += tmp_br3; 1495 1496 /* XOR-ing bit-24 of the mac address. This will give enough 1497 * mac address range before collision 1498 */ 1499 macaddr_b3 ^= (1 << 7); 1500 1501 /* Set locally administered bit */ 1502 hdd_ctx->derived_mac_addr[i].bytes[0] |= 0x02; 1503 hdd_ctx->derived_mac_addr[i].bytes[3] = macaddr_b3; 1504 hdd_debug("hdd_ctx->derived_mac_addr[%d]: " 1505 QDF_MAC_ADDR_FMT, i, 1506 QDF_MAC_ADDR_REF(hdd_ctx->derived_mac_addr[i].bytes)); 1507 hdd_ctx->num_derived_addr++; 1508 } 1509 } 1510 1511 #ifdef FEATURE_WLAN_TDLS 1512 static int hdd_update_tdls_config(struct hdd_context *hdd_ctx) 1513 { 1514 struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc; 1515 struct tdls_start_params tdls_cfg; 1516 QDF_STATUS status; 1517 struct wlan_mlme_nss_chains vdev_ini_cfg; 1518 1519 /* Populate the nss chain params from ini for this vdev type */ 1520 sme_populate_nss_chain_params(hdd_ctx->mac_handle, &vdev_ini_cfg, 1521 QDF_TDLS_MODE, 1522 hdd_ctx->num_rf_chains); 1523 1524 cfg_tdls_set_vdev_nss_2g(hdd_ctx->psoc, 1525 vdev_ini_cfg.rx_nss[NSS_CHAINS_BAND_2GHZ]); 1526 cfg_tdls_set_vdev_nss_5g(hdd_ctx->psoc, 1527 vdev_ini_cfg.rx_nss[NSS_CHAINS_BAND_5GHZ]); 1528 hdd_init_tdls_config(&tdls_cfg); 1529 tdls_cfg.tdls_del_all_peers = eWNI_SME_DEL_ALL_TDLS_PEERS; 1530 tdls_cfg.tdls_update_dp_vdev_flags = CDP_UPDATE_TDLS_FLAGS; 1531 tdls_cfg.tdls_event_cb = wlan_cfg80211_tdls_event_callback; 1532 tdls_cfg.tdls_evt_cb_data = psoc; 1533 tdls_cfg.tdls_peer_context = hdd_ctx; 1534 tdls_cfg.tdls_reg_peer = hdd_tdls_register_peer; 1535 tdls_cfg.tdls_wmm_cb = hdd_wmm_is_acm_allowed; 1536 tdls_cfg.tdls_wmm_cb_data = psoc; 1537 tdls_cfg.tdls_rx_cb = wlan_cfg80211_tdls_rx_callback; 1538 tdls_cfg.tdls_rx_cb_data = psoc; 1539 tdls_cfg.tdls_dp_vdev_update = hdd_update_dp_vdev_flags; 1540 tdls_cfg.tdls_osif_init_cb = wlan_cfg80211_tdls_osif_priv_init; 1541 tdls_cfg.tdls_osif_deinit_cb = wlan_cfg80211_tdls_osif_priv_deinit; 1542 tdls_cfg.tdls_osif_update_cb.tdls_osif_conn_update = 1543 hdd_check_and_set_tdls_conn_params; 1544 tdls_cfg.tdls_osif_update_cb.tdls_osif_disconn_update = 1545 hdd_check_and_set_tdls_disconn_params; 1546 1547 status = ucfg_tdls_update_config(psoc, &tdls_cfg); 1548 if (status != QDF_STATUS_SUCCESS) { 1549 hdd_err("failed pmo psoc configuration"); 1550 return -EINVAL; 1551 } 1552 1553 hdd_ctx->tdls_umac_comp_active = true; 1554 /* enable napier specific tdls data path */ 1555 hdd_ctx->tdls_nap_active = true; 1556 1557 return 0; 1558 } 1559 #else 1560 static int hdd_update_tdls_config(struct hdd_context *hdd_ctx) 1561 { 1562 return 0; 1563 } 1564 #endif 1565 1566 void hdd_indicate_active_ndp_cnt(struct wlan_objmgr_psoc *psoc, 1567 uint8_t vdev_id, uint8_t cnt) 1568 { 1569 struct wlan_hdd_link_info *link_info; 1570 1571 link_info = wlan_hdd_get_link_info_from_vdev(psoc, vdev_id); 1572 if (!link_info || !cfg_nan_is_roam_config_disabled(psoc)) 1573 return; 1574 1575 hdd_debug("vdev_id:%d%s active ndp sessions present", vdev_id, 1576 cnt ? "" : " no more"); 1577 if (!cnt) 1578 wlan_hdd_set_roaming_state(link_info, RSO_NDP_CON_ON_NDI, true); 1579 else 1580 wlan_hdd_set_roaming_state(link_info, RSO_NDP_CON_ON_NDI, 1581 false); 1582 } 1583 1584 #ifdef WLAN_FEATURE_ROAM_OFFLOAD 1585 static void hdd_update_roam_offload(struct hdd_context *hdd_ctx, 1586 struct wma_tgt_services *cfg) 1587 { 1588 bool roam_offload_enable; 1589 1590 ucfg_mlme_get_roaming_offload(hdd_ctx->psoc, &roam_offload_enable); 1591 ucfg_mlme_set_roaming_offload(hdd_ctx->psoc, 1592 roam_offload_enable & 1593 cfg->en_roam_offload); 1594 } 1595 #else 1596 static inline void hdd_update_roam_offload(struct hdd_context *hdd_ctx, 1597 struct wma_tgt_services *cfg) 1598 { 1599 } 1600 #endif 1601 1602 #ifdef FEATURE_CLUB_LL_STATS_AND_GET_STATION 1603 static void 1604 hdd_club_ll_stats_in_get_sta_cfg_update(struct hdd_config *config, 1605 struct wlan_objmgr_psoc *psoc) 1606 { 1607 config->sta_stats_cache_expiry_time = 1608 cfg_get(psoc, CFG_STA_STATS_CACHE_EXPIRY); 1609 } 1610 1611 static void 1612 hdd_update_feature_cfg_club_get_sta_in_ll_stats_req( 1613 struct hdd_context *hdd_ctx, 1614 struct wma_tgt_services *cfg) 1615 { 1616 hdd_ctx->is_get_station_clubbed_in_ll_stats_req = 1617 cfg->is_get_station_clubbed_in_ll_stats_req && 1618 cfg_get(hdd_ctx->psoc, 1619 CFG_CLUB_LL_STA_AND_GET_STATION); 1620 } 1621 1622 static void 1623 hdd_init_get_sta_in_ll_stats_config(struct hdd_adapter *adapter) 1624 { 1625 adapter->sta_stats_cached_timestamp = 0; 1626 } 1627 #else 1628 static void 1629 hdd_club_ll_stats_in_get_sta_cfg_update(struct hdd_config *config, 1630 struct wlan_objmgr_psoc *psoc) 1631 { 1632 } 1633 1634 static void 1635 hdd_update_feature_cfg_club_get_sta_in_ll_stats_req( 1636 struct hdd_context *hdd_ctx, 1637 struct wma_tgt_services *cfg) 1638 { 1639 } 1640 1641 static void 1642 hdd_init_get_sta_in_ll_stats_config(struct hdd_adapter *adapter) 1643 { 1644 } 1645 #endif /* FEATURE_CLUB_LL_STATS_AND_GET_STATION */ 1646 1647 #ifdef WLAN_FEATURE_IGMP_OFFLOAD 1648 static void 1649 hdd_intersect_igmp_offload_setting(struct wlan_objmgr_psoc *psoc, 1650 struct wma_tgt_services *cfg) 1651 { 1652 bool igmp_offload_enable; 1653 1654 igmp_offload_enable = 1655 ucfg_pmo_is_igmp_offload_enabled(psoc); 1656 ucfg_pmo_set_igmp_offload_enabled(psoc, 1657 igmp_offload_enable & 1658 cfg->igmp_offload_enable); 1659 hdd_info("fw cap to handle igmp %d igmp_offload_enable ini %d", 1660 cfg->igmp_offload_enable, igmp_offload_enable); 1661 } 1662 #else 1663 static inline void 1664 hdd_intersect_igmp_offload_setting(struct wlan_objmgr_psoc *psoc, 1665 struct wma_tgt_services *cfg) 1666 {} 1667 #endif 1668 1669 #ifdef FEATURE_WLAN_TDLS 1670 static void hdd_update_fw_tdls_wideband_capability(struct hdd_context *hdd_ctx, 1671 struct wma_tgt_services *cfg) 1672 { 1673 ucfg_tdls_update_fw_wideband_capability(hdd_ctx->psoc, 1674 cfg->en_tdls_wideband_support); 1675 } 1676 1677 #ifdef WLAN_FEATURE_11BE 1678 static void hdd_update_fw_tdls_mlo_capability(struct hdd_context *hdd_ctx, 1679 struct wma_tgt_services *cfg) 1680 { 1681 ucfg_tdls_update_fw_mlo_capability(hdd_ctx->psoc, 1682 cfg->en_tdls_mlo_support); 1683 } 1684 #else 1685 static inline 1686 void hdd_update_fw_tdls_mlo_capability(struct hdd_context *hdd_ctx, 1687 struct wma_tgt_services *cfg) 1688 {} 1689 #endif 1690 1691 #ifdef WLAN_FEATURE_11AX 1692 static void hdd_update_fw_tdls_11ax_capability(struct hdd_context *hdd_ctx, 1693 struct wma_tgt_services *cfg) 1694 { 1695 ucfg_tdls_update_fw_11ax_capability(hdd_ctx->psoc, 1696 cfg->en_tdls_11ax_support); 1697 } 1698 1699 static void hdd_update_fw_tdls_6g_capability(struct hdd_context *hdd_ctx, 1700 struct wma_tgt_services *cfg) 1701 { 1702 ucfg_update_fw_tdls_6g_capability(hdd_ctx->psoc, 1703 cfg->en_tdls_6g_support); 1704 } 1705 1706 #else 1707 static inline 1708 void hdd_update_fw_tdls_11ax_capability(struct hdd_context *hdd_ctx, 1709 struct wma_tgt_services *cfg) 1710 {} 1711 static inline 1712 void hdd_update_fw_tdls_6g_capability(struct hdd_context *hdd_ctx, 1713 struct wma_tgt_services *cfg) 1714 {} 1715 #endif 1716 #else 1717 static inline 1718 void hdd_update_fw_tdls_mlo_capability(struct hdd_context *hdd_ctx, 1719 struct wma_tgt_services *cfg) 1720 {} 1721 1722 static inline 1723 void hdd_update_fw_tdls_11ax_capability(struct hdd_context *hdd_ctx, 1724 struct wma_tgt_services *cfg) 1725 {} 1726 1727 static inline 1728 void hdd_update_fw_tdls_6g_capability(struct hdd_context *hdd_ctx, 1729 struct wma_tgt_services *cfg) 1730 {} 1731 1732 static inline 1733 void hdd_update_fw_tdls_wideband_capability(struct hdd_context *hdd_ctx, 1734 struct wma_tgt_services *cfg) 1735 {} 1736 #endif 1737 1738 #ifdef WLAN_FEATURE_DYNAMIC_MAC_ADDR_UPDATE 1739 static inline void 1740 hdd_set_dynamic_macaddr_update_capability(struct hdd_context *hdd_ctx, 1741 struct wma_tgt_services *cfg) 1742 { 1743 hdd_ctx->is_vdev_macaddr_dynamic_update_supported = 1744 cfg->dynamic_vdev_macaddr_support && 1745 cfg_get(hdd_ctx->psoc, 1746 CFG_DYNAMIC_MAC_ADDR_UPDATE_SUPPORTED); 1747 } 1748 #else 1749 static inline void 1750 hdd_set_dynamic_macaddr_update_capability(struct hdd_context *hdd_ctx, 1751 struct wma_tgt_services *cfg) 1752 { 1753 } 1754 #endif 1755 1756 #ifdef WLAN_FEATURE_11BE 1757 static bool hdd_dot11Mode_support_11be(enum hdd_dot11_mode dot11Mode) 1758 { 1759 if (dot11Mode != eHDD_DOT11_MODE_AUTO && 1760 dot11Mode < eHDD_DOT11_MODE_11be) 1761 return false; 1762 1763 return true; 1764 } 1765 #else 1766 static bool hdd_dot11Mode_support_11be(enum hdd_dot11_mode dot11Mode) 1767 { 1768 return false; 1769 } 1770 #endif 1771 1772 #ifdef WLAN_FEATURE_11BE_MLO 1773 static void 1774 hdd_update_mlo_per_link_stats_capability(struct hdd_context *hdd_ctx, 1775 struct wma_tgt_services *cfg) 1776 { 1777 hdd_ctx->is_mlo_per_link_stats_supported = 1778 cfg->is_mlo_per_link_stats_supported; 1779 } 1780 #else 1781 static void 1782 hdd_update_mlo_per_link_stats_capability(struct hdd_context *hdd_ctx, 1783 struct wma_tgt_services *cfg) 1784 { 1785 } 1786 #endif 1787 1788 static void hdd_update_tgt_services(struct hdd_context *hdd_ctx, 1789 struct wma_tgt_services *cfg) 1790 { 1791 struct hdd_config *config = hdd_ctx->config; 1792 bool arp_offload_enable; 1793 bool mawc_enabled; 1794 #ifdef FEATURE_WLAN_TDLS 1795 bool tdls_support; 1796 bool tdls_off_channel; 1797 bool tdls_buffer_sta; 1798 uint32_t tdls_uapsd_mask; 1799 #endif 1800 bool get_peer_info_enable; 1801 1802 /* Set up UAPSD */ 1803 ucfg_mlme_set_sap_uapsd_flag(hdd_ctx->psoc, cfg->uapsd); 1804 1805 /* 11AX mode support */ 1806 if ((config->dot11Mode == eHDD_DOT11_MODE_11ax || 1807 config->dot11Mode == eHDD_DOT11_MODE_11ax_ONLY) && !cfg->en_11ax) 1808 config->dot11Mode = eHDD_DOT11_MODE_11ac; 1809 1810 /* 11AC mode support */ 1811 if ((config->dot11Mode == eHDD_DOT11_MODE_11ac || 1812 config->dot11Mode == eHDD_DOT11_MODE_11ac_ONLY) && !cfg->en_11ac) 1813 config->dot11Mode = eHDD_DOT11_MODE_AUTO; 1814 /* 11BE mode support */ 1815 if (!hdd_dot11Mode_support_11be(config->dot11Mode) && 1816 cfg->en_11be) { 1817 hdd_debug("dot11Mode %d override target en_11be to false", 1818 config->dot11Mode); 1819 cfg->en_11be = false; 1820 } 1821 1822 /* ARP offload: override user setting if invalid */ 1823 arp_offload_enable = 1824 ucfg_pmo_is_arp_offload_enabled(hdd_ctx->psoc); 1825 ucfg_pmo_set_arp_offload_enabled(hdd_ctx->psoc, 1826 arp_offload_enable & cfg->arp_offload); 1827 1828 /* Intersect igmp offload ini configuration and fw cap*/ 1829 hdd_intersect_igmp_offload_setting(hdd_ctx->psoc, cfg); 1830 1831 #ifdef FEATURE_WLAN_SCAN_PNO 1832 /* PNO offload */ 1833 hdd_debug("PNO Capability in f/w = %d", cfg->pno_offload); 1834 if (cfg->pno_offload) 1835 ucfg_scan_set_pno_offload(hdd_ctx->psoc, true); 1836 #endif 1837 #ifdef FEATURE_WLAN_TDLS 1838 cfg_tdls_get_support_enable(hdd_ctx->psoc, &tdls_support); 1839 cfg_tdls_set_support_enable(hdd_ctx->psoc, 1840 tdls_support & cfg->en_tdls); 1841 1842 cfg_tdls_get_off_channel_enable(hdd_ctx->psoc, &tdls_off_channel); 1843 cfg_tdls_set_off_channel_enable(hdd_ctx->psoc, 1844 tdls_off_channel && 1845 cfg->en_tdls_offchan); 1846 1847 cfg_tdls_get_buffer_sta_enable(hdd_ctx->psoc, &tdls_buffer_sta); 1848 cfg_tdls_set_buffer_sta_enable(hdd_ctx->psoc, 1849 tdls_buffer_sta && 1850 cfg->en_tdls_uapsd_buf_sta); 1851 1852 cfg_tdls_get_uapsd_mask(hdd_ctx->psoc, &tdls_uapsd_mask); 1853 if (tdls_uapsd_mask && cfg->en_tdls_uapsd_sleep_sta) 1854 cfg_tdls_set_sleep_sta_enable(hdd_ctx->psoc, true); 1855 else 1856 cfg_tdls_set_sleep_sta_enable(hdd_ctx->psoc, false); 1857 #endif 1858 hdd_update_roam_offload(hdd_ctx, cfg); 1859 1860 if (ucfg_mlme_get_sap_get_peer_info( 1861 hdd_ctx->psoc, &get_peer_info_enable) == QDF_STATUS_SUCCESS) { 1862 get_peer_info_enable &= cfg->get_peer_info_enabled; 1863 ucfg_mlme_set_sap_get_peer_info(hdd_ctx->psoc, 1864 get_peer_info_enable); 1865 } 1866 1867 ucfg_mlme_is_mawc_enabled(hdd_ctx->psoc, &mawc_enabled); 1868 ucfg_mlme_set_mawc_enabled(hdd_ctx->psoc, 1869 mawc_enabled & cfg->is_fw_mawc_capable); 1870 hdd_update_tdls_config(hdd_ctx); 1871 sme_update_tgt_services(hdd_ctx->mac_handle, cfg); 1872 hdd_ctx->roam_ch_from_fw_supported = cfg->is_roam_scan_ch_to_host; 1873 hdd_ctx->ll_stats_per_chan_rx_tx_time = 1874 cfg->ll_stats_per_chan_rx_tx_time; 1875 1876 hdd_update_feature_cfg_club_get_sta_in_ll_stats_req(hdd_ctx, cfg); 1877 hdd_ctx->is_therm_cmd_supp = 1878 cfg->is_fw_therm_throt_supp && 1879 cfg_get(hdd_ctx->psoc, 1880 CFG_THERMAL_MITIGATION_ENABLE); 1881 hdd_update_fw_tdls_11ax_capability(hdd_ctx, cfg); 1882 hdd_update_fw_tdls_mlo_capability(hdd_ctx, cfg); 1883 hdd_set_dynamic_macaddr_update_capability(hdd_ctx, cfg); 1884 hdd_update_fw_tdls_6g_capability(hdd_ctx, cfg); 1885 hdd_update_fw_tdls_wideband_capability(hdd_ctx, cfg); 1886 ucfg_psoc_mlme_set_11be_capab(hdd_ctx->psoc, cfg->en_11be); 1887 hdd_update_mlo_per_link_stats_capability(hdd_ctx, cfg); 1888 } 1889 1890 /** 1891 * hdd_update_vdev_nss() - sets the vdev nss 1892 * @hdd_ctx: HDD context 1893 * 1894 * Sets the Nss per vdev type based on INI 1895 * 1896 * Return: None 1897 */ 1898 static void hdd_update_vdev_nss(struct hdd_context *hdd_ctx) 1899 { 1900 uint8_t max_supp_nss = 1; 1901 mac_handle_t mac_handle; 1902 QDF_STATUS status; 1903 bool bval; 1904 1905 status = ucfg_mlme_get_vht_enable2x2(hdd_ctx->psoc, &bval); 1906 if (!QDF_IS_STATUS_SUCCESS(status)) 1907 hdd_err("unable to get vht_enable2x2"); 1908 1909 if (bval && !cds_is_sub_20_mhz_enabled()) 1910 max_supp_nss = 2; 1911 1912 hdd_debug("max nss %d", max_supp_nss); 1913 1914 mac_handle = hdd_ctx->mac_handle; 1915 sme_update_vdev_type_nss(mac_handle, max_supp_nss, 1916 NSS_CHAINS_BAND_2GHZ); 1917 1918 sme_update_vdev_type_nss(mac_handle, max_supp_nss, 1919 NSS_CHAINS_BAND_5GHZ); 1920 } 1921 1922 /** 1923 * hdd_update_2g_wiphy_vhtcap() - Updates 2G wiphy vhtcap fields 1924 * @hdd_ctx: HDD context 1925 * 1926 * Updates 2G wiphy vhtcap fields 1927 * 1928 * Return: None 1929 */ 1930 static void hdd_update_2g_wiphy_vhtcap(struct hdd_context *hdd_ctx) 1931 { 1932 struct ieee80211_supported_band *band_2g = 1933 hdd_ctx->wiphy->bands[NL80211_BAND_2GHZ]; 1934 uint32_t value; 1935 bool is_vht_24ghz; 1936 1937 if (!band_2g) { 1938 hdd_debug("2GHz band disabled, skipping capability population"); 1939 return; 1940 } 1941 1942 ucfg_mlme_get_vht_for_24ghz(hdd_ctx->psoc, &is_vht_24ghz); 1943 1944 if (is_vht_24ghz) { 1945 ucfg_mlme_cfg_get_vht_tx_mcs_map(hdd_ctx->psoc, &value); 1946 band_2g->vht_cap.vht_mcs.tx_mcs_map = value; 1947 } 1948 } 1949 1950 /** 1951 * hdd_update_5g_wiphy_vhtcap() - Updates 5G wiphy vhtcap fields 1952 * @hdd_ctx: HDD context 1953 * 1954 * Updates 5G wiphy vhtcap fields 1955 * 1956 * Return: None 1957 */ 1958 static void hdd_update_5g_wiphy_vhtcap(struct hdd_context *hdd_ctx) 1959 { 1960 struct ieee80211_supported_band *band_5g = 1961 hdd_ctx->wiphy->bands[NL80211_BAND_5GHZ]; 1962 QDF_STATUS status; 1963 uint8_t value = 0, value1 = 0; 1964 uint32_t value2; 1965 1966 if (!band_5g) { 1967 hdd_debug("5GHz band disabled, skipping capability population"); 1968 return; 1969 } 1970 1971 status = ucfg_mlme_cfg_get_vht_tx_bfee_ant_supp(hdd_ctx->psoc, 1972 &value); 1973 if (!QDF_IS_STATUS_SUCCESS(status)) 1974 hdd_err("unable to get tx_bfee_ant_supp"); 1975 1976 band_5g->vht_cap.cap |= 1977 (value << IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT); 1978 1979 value1 = NUM_OF_SOUNDING_DIMENSIONS; 1980 band_5g->vht_cap.cap |= 1981 (value1 << IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_SHIFT); 1982 1983 hdd_debug("Updated wiphy vhtcap:0x%x, CSNAntSupp:%d, NumSoundDim:%d", 1984 band_5g->vht_cap.cap, value, value1); 1985 1986 ucfg_mlme_cfg_get_vht_rx_mcs_map(hdd_ctx->psoc, &value2); 1987 band_5g->vht_cap.vht_mcs.rx_mcs_map = value2; 1988 1989 ucfg_mlme_cfg_get_vht_tx_mcs_map(hdd_ctx->psoc, &value2); 1990 band_5g->vht_cap.vht_mcs.tx_mcs_map = value2; 1991 } 1992 1993 /** 1994 * hdd_update_wiphy_vhtcap() - Updates wiphy vhtcap fields 1995 * @hdd_ctx: HDD context 1996 * 1997 * Updates wiphy vhtcap fields 1998 * 1999 * Return: None 2000 */ 2001 static void hdd_update_wiphy_vhtcap(struct hdd_context *hdd_ctx) 2002 { 2003 hdd_update_2g_wiphy_vhtcap(hdd_ctx); 2004 hdd_update_5g_wiphy_vhtcap(hdd_ctx); 2005 } 2006 2007 static void hdd_update_tgt_ht_cap(struct hdd_context *hdd_ctx, 2008 struct wma_tgt_ht_cap *cfg) 2009 { 2010 QDF_STATUS status; 2011 qdf_size_t value_len; 2012 uint32_t value; 2013 uint8_t mpdu_density; 2014 struct mlme_ht_capabilities_info ht_cap_info; 2015 uint8_t mcs_set[SIZE_OF_SUPPORTED_MCS_SET]; 2016 bool b_enable1x1; 2017 2018 /* get the MPDU density */ 2019 status = ucfg_mlme_get_ht_mpdu_density(hdd_ctx->psoc, &mpdu_density); 2020 if (QDF_IS_STATUS_ERROR(status)) { 2021 hdd_err("could not get HT MPDU Density"); 2022 return; 2023 } 2024 2025 /* 2026 * MPDU density: 2027 * override user's setting if value is larger 2028 * than the one supported by target, 2029 * if target value is 0, then follow user's setting. 2030 */ 2031 if (cfg->mpdu_density && mpdu_density > cfg->mpdu_density) { 2032 status = ucfg_mlme_set_ht_mpdu_density(hdd_ctx->psoc, 2033 cfg->mpdu_density); 2034 if (QDF_IS_STATUS_ERROR(status)) 2035 hdd_err("could not set HT capability to CCM"); 2036 } 2037 2038 /* get the HT capability info */ 2039 status = ucfg_mlme_get_ht_cap_info(hdd_ctx->psoc, &ht_cap_info); 2040 if (QDF_STATUS_SUCCESS != status) { 2041 hdd_err("could not get HT capability info"); 2042 return; 2043 } 2044 2045 /* check and update RX STBC */ 2046 if (ht_cap_info.rx_stbc && !cfg->ht_rx_stbc) 2047 ht_cap_info.rx_stbc = cfg->ht_rx_stbc; 2048 2049 /* Set the LDPC capability */ 2050 if (ht_cap_info.adv_coding_cap && !cfg->ht_rx_ldpc) 2051 ht_cap_info.adv_coding_cap = cfg->ht_rx_ldpc; 2052 2053 if (ht_cap_info.short_gi_20_mhz && !cfg->ht_sgi_20) 2054 ht_cap_info.short_gi_20_mhz = cfg->ht_sgi_20; 2055 2056 if (ht_cap_info.short_gi_40_mhz && !cfg->ht_sgi_40) 2057 ht_cap_info.short_gi_40_mhz = cfg->ht_sgi_40; 2058 2059 hdd_ctx->num_rf_chains = cfg->num_rf_chains; 2060 hdd_ctx->ht_tx_stbc_supported = cfg->ht_tx_stbc; 2061 2062 status = ucfg_mlme_get_vht_enable2x2(hdd_ctx->psoc, &b_enable1x1); 2063 if (!QDF_IS_STATUS_SUCCESS(status)) 2064 hdd_err("unable to get vht_enable2x2"); 2065 2066 b_enable1x1 = b_enable1x1 && (cfg->num_rf_chains == 2); 2067 2068 status = ucfg_mlme_set_vht_enable2x2(hdd_ctx->psoc, b_enable1x1); 2069 if (!QDF_IS_STATUS_SUCCESS(status)) 2070 hdd_err("unable to set vht_enable2x2"); 2071 2072 if (!b_enable1x1) 2073 ht_cap_info.tx_stbc = 0; 2074 2075 if (!(cfg->ht_tx_stbc && b_enable1x1)) 2076 ht_cap_info.tx_stbc = 0; 2077 2078 status = ucfg_mlme_set_ht_cap_info(hdd_ctx->psoc, ht_cap_info); 2079 if (status != QDF_STATUS_SUCCESS) 2080 hdd_err("could not set HT capability to CCM"); 2081 #define WLAN_HDD_RX_MCS_ALL_NSTREAM_RATES 0xff 2082 value_len = SIZE_OF_SUPPORTED_MCS_SET; 2083 if (ucfg_mlme_get_supported_mcs_set( 2084 hdd_ctx->psoc, mcs_set, 2085 &value_len) == QDF_STATUS_SUCCESS) { 2086 hdd_debug("Read MCS rate set"); 2087 if (cfg->num_rf_chains > SIZE_OF_SUPPORTED_MCS_SET) 2088 cfg->num_rf_chains = SIZE_OF_SUPPORTED_MCS_SET; 2089 2090 if (b_enable1x1) { 2091 for (value = 0; value < cfg->num_rf_chains; value++) 2092 mcs_set[value] = 2093 WLAN_HDD_RX_MCS_ALL_NSTREAM_RATES; 2094 2095 status = ucfg_mlme_set_supported_mcs_set( 2096 hdd_ctx->psoc, 2097 mcs_set, 2098 (qdf_size_t)SIZE_OF_SUPPORTED_MCS_SET); 2099 if (QDF_IS_STATUS_ERROR(status)) 2100 hdd_err("could not set MCS SET to CCM"); 2101 } 2102 } 2103 #undef WLAN_HDD_RX_MCS_ALL_NSTREAM_RATES 2104 } 2105 2106 static void hdd_update_tgt_vht_cap(struct hdd_context *hdd_ctx, 2107 struct wma_tgt_vht_cap *cfg) 2108 { 2109 QDF_STATUS status; 2110 struct wiphy *wiphy = hdd_ctx->wiphy; 2111 struct ieee80211_supported_band *band_5g = 2112 wiphy->bands[HDD_NL80211_BAND_5GHZ]; 2113 uint32_t ch_width; 2114 struct wma_caps_per_phy caps_per_phy = {0}; 2115 bool vht_enable_2x2; 2116 uint32_t tx_highest_data_rate; 2117 uint32_t rx_highest_data_rate; 2118 2119 if (!band_5g) { 2120 hdd_debug("5GHz band disabled, skipping capability population"); 2121 return; 2122 } 2123 2124 status = ucfg_mlme_update_vht_cap(hdd_ctx->psoc, cfg); 2125 if (QDF_IS_STATUS_ERROR(status)) 2126 hdd_err("could not update vht capabilities"); 2127 2128 status = ucfg_mlme_get_vht_enable2x2(hdd_ctx->psoc, &vht_enable_2x2); 2129 if (!QDF_IS_STATUS_SUCCESS(status)) 2130 hdd_err("unable to get vht_enable2x2"); 2131 2132 if (vht_enable_2x2) { 2133 tx_highest_data_rate = 2134 VHT_TX_HIGHEST_SUPPORTED_DATA_RATE_2_2; 2135 rx_highest_data_rate = 2136 VHT_RX_HIGHEST_SUPPORTED_DATA_RATE_2_2; 2137 } else { 2138 tx_highest_data_rate = 2139 VHT_TX_HIGHEST_SUPPORTED_DATA_RATE_1_1; 2140 rx_highest_data_rate = 2141 VHT_RX_HIGHEST_SUPPORTED_DATA_RATE_1_1; 2142 } 2143 2144 status = ucfg_mlme_cfg_set_vht_rx_supp_data_rate(hdd_ctx->psoc, 2145 rx_highest_data_rate); 2146 if (!QDF_IS_STATUS_SUCCESS(status)) 2147 hdd_err("Failed to set rx_supp_data_rate"); 2148 2149 status = ucfg_mlme_cfg_set_vht_tx_supp_data_rate(hdd_ctx->psoc, 2150 tx_highest_data_rate); 2151 if (!QDF_IS_STATUS_SUCCESS(status)) 2152 hdd_err("Failed to set tx_supp_data_rate"); 2153 2154 /* Update the real highest data rate to wiphy */ 2155 if (cfg->vht_short_gi_80 & WMI_VHT_CAP_SGI_80MHZ) { 2156 if (vht_enable_2x2) { 2157 tx_highest_data_rate = 2158 VHT_TX_HIGHEST_SUPPORTED_DATA_RATE_2_2_SGI80; 2159 rx_highest_data_rate = 2160 VHT_RX_HIGHEST_SUPPORTED_DATA_RATE_2_2_SGI80; 2161 } else { 2162 tx_highest_data_rate = 2163 VHT_TX_HIGHEST_SUPPORTED_DATA_RATE_1_1_SGI80; 2164 rx_highest_data_rate = 2165 VHT_RX_HIGHEST_SUPPORTED_DATA_RATE_1_1_SGI80; 2166 } 2167 } 2168 2169 if (WMI_VHT_CAP_MAX_MPDU_LEN_11454 == cfg->vht_max_mpdu) 2170 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454; 2171 else if (WMI_VHT_CAP_MAX_MPDU_LEN_7935 == cfg->vht_max_mpdu) 2172 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_7991; 2173 else 2174 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_3895; 2175 2176 2177 if (cfg->supp_chan_width & (1 << eHT_CHANNEL_WIDTH_80P80MHZ)) { 2178 band_5g->vht_cap.cap |= 2179 IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ; 2180 ch_width = VHT_CAP_160_AND_80P80_SUPP; 2181 } else if (cfg->supp_chan_width & (1 << eHT_CHANNEL_WIDTH_160MHZ)) { 2182 band_5g->vht_cap.cap |= 2183 IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ; 2184 ch_width = VHT_CAP_160_SUPP; 2185 } else { 2186 ch_width = VHT_CAP_NO_160M_SUPP; 2187 } 2188 2189 status = ucfg_mlme_set_vht_ch_width(hdd_ctx->psoc, ch_width); 2190 if (QDF_IS_STATUS_ERROR(status)) 2191 hdd_err("could not set the channel width"); 2192 else 2193 hdd_debug("supported channel width %d", ch_width); 2194 2195 if (cfg->vht_rx_ldpc & WMI_VHT_CAP_RX_LDPC) { 2196 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_RXLDPC; 2197 hdd_debug("VHT RxLDPC capability is set"); 2198 } else { 2199 /* 2200 * Get the RX LDPC capability for the NON DBS 2201 * hardware mode for 5G band 2202 */ 2203 status = wma_get_caps_for_phyidx_hwmode(&caps_per_phy, 2204 HW_MODE_DBS_NONE, CDS_BAND_5GHZ); 2205 if ((QDF_IS_STATUS_SUCCESS(status)) && 2206 (caps_per_phy.vht_5g & WMI_VHT_CAP_RX_LDPC)) { 2207 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_RXLDPC; 2208 hdd_debug("VHT RX LDPC capability is set"); 2209 } 2210 } 2211 2212 if (cfg->vht_short_gi_80 & WMI_VHT_CAP_SGI_80MHZ) 2213 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_SHORT_GI_80; 2214 if (cfg->vht_short_gi_160 & WMI_VHT_CAP_SGI_160MHZ) 2215 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_SHORT_GI_160; 2216 2217 if (vht_enable_2x2 && (cfg->vht_tx_stbc & WMI_VHT_CAP_TX_STBC)) 2218 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_TXSTBC; 2219 2220 if (cfg->vht_rx_stbc & WMI_VHT_CAP_RX_STBC_1SS) 2221 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_RXSTBC_1; 2222 if (vht_enable_2x2 && (cfg->vht_rx_stbc & WMI_VHT_CAP_RX_STBC_2SS)) 2223 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_RXSTBC_2; 2224 if (cfg->vht_rx_stbc & WMI_VHT_CAP_RX_STBC_3SS) 2225 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_RXSTBC_3; 2226 2227 band_5g->vht_cap.cap |= 2228 (cfg->vht_max_ampdu_len_exp << 2229 IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT); 2230 2231 if (cfg->vht_su_bformer & WMI_VHT_CAP_SU_BFORMER) 2232 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE; 2233 if (cfg->vht_su_bformee & WMI_VHT_CAP_SU_BFORMEE) 2234 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE; 2235 if (cfg->vht_mu_bformer & WMI_VHT_CAP_MU_BFORMER) 2236 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE; 2237 if (cfg->vht_mu_bformee & WMI_VHT_CAP_MU_BFORMEE) 2238 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE; 2239 2240 if (cfg->vht_txop_ps & WMI_VHT_CAP_TXOP_PS) 2241 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_VHT_TXOP_PS; 2242 2243 band_5g->vht_cap.vht_mcs.rx_highest = cpu_to_le16(rx_highest_data_rate); 2244 band_5g->vht_cap.vht_mcs.tx_highest = cpu_to_le16(tx_highest_data_rate); 2245 } 2246 2247 /** 2248 * hdd_generate_macaddr_auto() - Auto-generate mac address 2249 * @hdd_ctx: Pointer to the HDD context 2250 * 2251 * Auto-generate mac address using device serial number. 2252 * Keep the first 3 bytes of OUI as before and replace 2253 * the last 3 bytes with the lower 3 bytes of serial number. 2254 * 2255 * Return: 0 for success 2256 * Non zero failure code for errors 2257 */ 2258 static int hdd_generate_macaddr_auto(struct hdd_context *hdd_ctx) 2259 { 2260 unsigned int serialno = 0; 2261 struct qdf_mac_addr mac_addr = { 2262 {0x00, 0x0A, 0xF5, 0x00, 0x00, 0x00} 2263 }; 2264 2265 serialno = pld_socinfo_get_serial_number(hdd_ctx->parent_dev); 2266 if (serialno == 0) 2267 return -EINVAL; 2268 2269 serialno &= 0x00ffffff; 2270 2271 mac_addr.bytes[3] = (serialno >> 16) & 0xff; 2272 mac_addr.bytes[4] = (serialno >> 8) & 0xff; 2273 mac_addr.bytes[5] = serialno & 0xff; 2274 2275 hdd_update_macaddr(hdd_ctx, mac_addr, true); 2276 return 0; 2277 } 2278 2279 static void hdd_sar_target_config(struct hdd_context *hdd_ctx, 2280 struct wma_tgt_cfg *cfg) 2281 { 2282 hdd_ctx->sar_version = cfg->sar_version; 2283 } 2284 2285 static void hdd_update_vhtcap_2g(struct hdd_context *hdd_ctx) 2286 { 2287 uint64_t chip_mode = 0; 2288 QDF_STATUS status; 2289 bool b2g_vht_cfg = false; 2290 bool b2g_vht_target = false; 2291 struct wma_caps_per_phy caps_per_phy = {0}; 2292 struct wmi_unified *wmi_handle; 2293 2294 wmi_handle = get_wmi_unified_hdl_from_psoc(hdd_ctx->psoc); 2295 if (!wmi_handle) { 2296 hdd_err("wmi handle is NULL"); 2297 return; 2298 } 2299 2300 status = ucfg_mlme_get_vht_for_24ghz(hdd_ctx->psoc, &b2g_vht_cfg); 2301 if (QDF_IS_STATUS_ERROR(status)) { 2302 hdd_err("Failed to get 2g vht mode"); 2303 return; 2304 } 2305 if (wmi_service_enabled(wmi_handle, wmi_service_ext_msg)) { 2306 status = wma_get_caps_for_phyidx_hwmode(&caps_per_phy, 2307 HW_MODE_DBS_NONE, 2308 CDS_BAND_2GHZ); 2309 if (QDF_IS_STATUS_ERROR(status)) { 2310 hdd_err("Failed to get phy caps"); 2311 return; 2312 } 2313 if (caps_per_phy.vht_2g) 2314 b2g_vht_target = true; 2315 } else { 2316 status = wlan_reg_get_chip_mode(hdd_ctx->pdev, &chip_mode); 2317 if (QDF_IS_STATUS_ERROR(status)) { 2318 hdd_err("Failed to get chip mode"); 2319 return; 2320 } 2321 b2g_vht_target = 2322 (chip_mode & HOST_REGDMN_MODE_11AC_VHT20_2G) ? 2323 true : false; 2324 } 2325 2326 b2g_vht_cfg = b2g_vht_cfg && b2g_vht_target; 2327 hdd_debug("vht 2g target: %d, cfg: %d", b2g_vht_target, b2g_vht_cfg); 2328 status = ucfg_mlme_set_vht_for_24ghz(hdd_ctx->psoc, b2g_vht_cfg); 2329 if (QDF_IS_STATUS_ERROR(status)) { 2330 hdd_err("Failed to update 2g vht mode"); 2331 return; 2332 } 2333 } 2334 2335 static void hdd_extract_fw_version_info(struct hdd_context *hdd_ctx) 2336 { 2337 hdd_ctx->fw_version_info.major_spid = 2338 HDD_FW_VER_MAJOR_SPID(hdd_ctx->target_fw_version); 2339 hdd_ctx->fw_version_info.minor_spid = 2340 HDD_FW_VER_MINOR_SPID(hdd_ctx->target_fw_version); 2341 hdd_ctx->fw_version_info.siid = 2342 HDD_FW_VER_SIID(hdd_ctx->target_fw_version); 2343 hdd_ctx->fw_version_info.crmid = 2344 HDD_FW_VER_CRM_ID(hdd_ctx->target_fw_version); 2345 hdd_ctx->fw_version_info.sub_id = 2346 HDD_FW_VER_SUB_ID(hdd_ctx->target_fw_vers_ext); 2347 hdd_ctx->fw_version_info.rel_id = 2348 HDD_FW_VER_REL_ID(hdd_ctx->target_fw_vers_ext); 2349 } 2350 2351 #if defined(WLAN_FEATURE_11AX) && \ 2352 (defined(CFG80211_SBAND_IFTYPE_DATA_BACKPORT) || \ 2353 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0))) 2354 2355 static void 2356 hdd_update_wiphy_he_mcs(struct ieee80211_sband_iftype_data *iftype_data, 2357 tDot11fIEhe_cap *he_cap_cfg) 2358 { 2359 if (!iftype_data || !he_cap_cfg) { 2360 hdd_err("Unable to update wiphy he_mcs"); 2361 return; 2362 } 2363 2364 iftype_data->he_cap.he_mcs_nss_supp.tx_mcs_80 = 2365 he_cap_cfg->tx_he_mcs_map_lt_80; 2366 iftype_data->he_cap.he_mcs_nss_supp.tx_mcs_160 = 2367 *((uint16_t *)he_cap_cfg->tx_he_mcs_map_160); 2368 iftype_data->he_cap.he_mcs_nss_supp.tx_mcs_80p80 = 2369 *((uint16_t *)he_cap_cfg->tx_he_mcs_map_80_80); 2370 } 2371 2372 #if defined(CONFIG_BAND_6GHZ) && (defined(IEEE80211_HE_6GHZ_CAP_MIN_MPDU_START)) 2373 static void hdd_update_wiphy_he_6ghz_capa(struct hdd_context *hdd_ctx) 2374 { 2375 uint16_t he_6ghz_capa = 0; 2376 uint8_t min_mpdu_start_spacing; 2377 uint8_t max_ampdu_len_exp; 2378 uint8_t max_mpdu_len; 2379 uint8_t sm_pow_save; 2380 2381 ucfg_mlme_get_ht_mpdu_density(hdd_ctx->psoc, &min_mpdu_start_spacing); 2382 he_6ghz_capa |= FIELD_PREP(IEEE80211_HE_6GHZ_CAP_MIN_MPDU_START, 2383 min_mpdu_start_spacing); 2384 2385 ucfg_mlme_cfg_get_vht_ampdu_len_exp(hdd_ctx->psoc, &max_ampdu_len_exp); 2386 he_6ghz_capa |= FIELD_PREP(IEEE80211_HE_6GHZ_CAP_MAX_AMPDU_LEN_EXP, 2387 max_ampdu_len_exp); 2388 2389 ucfg_mlme_cfg_get_vht_max_mpdu_len(hdd_ctx->psoc, &max_mpdu_len); 2390 he_6ghz_capa |= FIELD_PREP(IEEE80211_HE_6GHZ_CAP_MAX_MPDU_LEN, 2391 max_mpdu_len); 2392 2393 ucfg_mlme_cfg_get_ht_smps(hdd_ctx->psoc, &sm_pow_save); 2394 he_6ghz_capa |= FIELD_PREP(IEEE80211_HE_6GHZ_CAP_SM_PS, sm_pow_save); 2395 2396 he_6ghz_capa |= IEEE80211_HE_6GHZ_CAP_RX_ANTPAT_CONS; 2397 he_6ghz_capa |= IEEE80211_HE_6GHZ_CAP_TX_ANTPAT_CONS; 2398 2399 hdd_ctx->iftype_data_6g->he_6ghz_capa.capa = he_6ghz_capa; 2400 } 2401 #else 2402 static inline void hdd_update_wiphy_he_6ghz_capa(struct hdd_context *hdd_ctx) 2403 { 2404 } 2405 #endif 2406 2407 #if defined(CONFIG_BAND_6GHZ) && (defined(CFG80211_6GHZ_BAND_SUPPORTED) || \ 2408 (KERNEL_VERSION(5, 4, 0) <= LINUX_VERSION_CODE)) 2409 static void 2410 hdd_update_wiphy_he_caps_6ghz(struct hdd_context *hdd_ctx, 2411 tDot11fIEhe_cap *he_cap_cfg) 2412 { 2413 struct ieee80211_supported_band *band_6g = 2414 hdd_ctx->wiphy->bands[HDD_NL80211_BAND_6GHZ]; 2415 uint8_t *phy_info = 2416 hdd_ctx->iftype_data_6g->he_cap.he_cap_elem.phy_cap_info; 2417 uint8_t *mac_info_6g = 2418 hdd_ctx->iftype_data_6g->he_cap.he_cap_elem.mac_cap_info; 2419 uint8_t max_fw_bw = sme_get_vht_ch_width(); 2420 2421 if (!band_6g || !phy_info) { 2422 hdd_debug("6ghz not supported in wiphy"); 2423 return; 2424 } 2425 2426 hdd_ctx->iftype_data_6g->types_mask = 2427 (BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP)); 2428 hdd_ctx->iftype_data_6g->he_cap.has_he = true; 2429 band_6g->n_iftype_data = 1; 2430 2431 if (max_fw_bw >= WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ) 2432 phy_info[0] |= 2433 IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_80MHZ_IN_5G; 2434 if (max_fw_bw >= WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ) 2435 phy_info[0] |= 2436 IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_160MHZ_IN_5G; 2437 if (max_fw_bw >= WNI_CFG_VHT_CHANNEL_WIDTH_80_PLUS_80MHZ) 2438 phy_info[0] |= 2439 IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G; 2440 2441 if (he_cap_cfg->twt_request) 2442 mac_info_6g[0] |= IEEE80211_HE_MAC_CAP0_TWT_REQ; 2443 2444 if (he_cap_cfg->twt_responder) 2445 mac_info_6g[0] |= IEEE80211_HE_MAC_CAP0_TWT_RES; 2446 2447 hdd_update_wiphy_he_6ghz_capa(hdd_ctx); 2448 2449 hdd_update_wiphy_he_mcs(hdd_ctx->iftype_data_6g, he_cap_cfg); 2450 2451 band_6g->iftype_data = hdd_ctx->iftype_data_6g; 2452 } 2453 #else 2454 static inline void 2455 hdd_update_wiphy_he_caps_6ghz(struct hdd_context *hdd_ctx, 2456 tDot11fIEhe_cap *he_cap_cfg) 2457 { 2458 } 2459 #endif 2460 2461 static void hdd_update_wiphy_he_cap(struct hdd_context *hdd_ctx) 2462 { 2463 tDot11fIEhe_cap he_cap_cfg; 2464 struct ieee80211_supported_band *band_2g = 2465 hdd_ctx->wiphy->bands[HDD_NL80211_BAND_2GHZ]; 2466 struct ieee80211_supported_band *band_5g = 2467 hdd_ctx->wiphy->bands[HDD_NL80211_BAND_5GHZ]; 2468 QDF_STATUS status; 2469 uint8_t *phy_info_5g = 2470 hdd_ctx->iftype_data_5g->he_cap.he_cap_elem.phy_cap_info; 2471 uint8_t max_fw_bw = sme_get_vht_ch_width(); 2472 uint32_t channel_bonding_mode_2g; 2473 uint8_t *phy_info_2g = 2474 hdd_ctx->iftype_data_2g->he_cap.he_cap_elem.phy_cap_info; 2475 uint8_t *mac_info_2g = 2476 hdd_ctx->iftype_data_2g->he_cap.he_cap_elem.mac_cap_info; 2477 uint8_t *mac_info_5g = 2478 hdd_ctx->iftype_data_5g->he_cap.he_cap_elem.mac_cap_info; 2479 2480 status = ucfg_mlme_cfg_get_he_caps(hdd_ctx->psoc, &he_cap_cfg); 2481 2482 if (QDF_IS_STATUS_ERROR(status)) 2483 return; 2484 2485 if (band_2g) { 2486 hdd_ctx->iftype_data_2g->types_mask = 2487 (BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP)); 2488 hdd_ctx->iftype_data_2g->he_cap.has_he = he_cap_cfg.present; 2489 band_2g->n_iftype_data = 1; 2490 hdd_update_wiphy_he_mcs(hdd_ctx->iftype_data_2g, &he_cap_cfg); 2491 band_2g->iftype_data = hdd_ctx->iftype_data_2g; 2492 2493 ucfg_mlme_get_channel_bonding_24ghz(hdd_ctx->psoc, 2494 &channel_bonding_mode_2g); 2495 if (channel_bonding_mode_2g) 2496 phy_info_2g[0] |= 2497 IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_IN_2G; 2498 2499 if (he_cap_cfg.twt_request) 2500 mac_info_2g[0] |= IEEE80211_HE_MAC_CAP0_TWT_REQ; 2501 2502 if (he_cap_cfg.twt_responder) 2503 mac_info_2g[0] |= IEEE80211_HE_MAC_CAP0_TWT_RES; 2504 } 2505 if (band_5g) { 2506 hdd_ctx->iftype_data_5g->types_mask = 2507 (BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP)); 2508 hdd_ctx->iftype_data_5g->he_cap.has_he = he_cap_cfg.present; 2509 band_5g->n_iftype_data = 1; 2510 hdd_update_wiphy_he_mcs(hdd_ctx->iftype_data_5g, &he_cap_cfg); 2511 band_5g->iftype_data = hdd_ctx->iftype_data_5g; 2512 2513 if (max_fw_bw >= WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ) 2514 phy_info_5g[0] |= 2515 IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_80MHZ_IN_5G; 2516 if (max_fw_bw >= WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ) 2517 phy_info_5g[0] |= 2518 IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_160MHZ_IN_5G; 2519 if (max_fw_bw >= WNI_CFG_VHT_CHANNEL_WIDTH_80_PLUS_80MHZ) 2520 phy_info_5g[0] |= 2521 IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G; 2522 2523 if (he_cap_cfg.twt_request) 2524 mac_info_5g[0] |= IEEE80211_HE_MAC_CAP0_TWT_REQ; 2525 2526 if (he_cap_cfg.twt_responder) 2527 mac_info_5g[0] |= IEEE80211_HE_MAC_CAP0_TWT_RES; 2528 } 2529 2530 hdd_update_wiphy_he_caps_6ghz(hdd_ctx, &he_cap_cfg); 2531 } 2532 #else 2533 static void hdd_update_wiphy_he_cap(struct hdd_context *hdd_ctx) 2534 { 2535 } 2536 #endif 2537 2538 static void hdd_component_cfg_chan_to_freq(struct wlan_objmgr_pdev *pdev) 2539 { 2540 ucfg_mlme_cfg_chan_to_freq(pdev); 2541 } 2542 2543 static uint32_t hdd_update_band_cap_from_dot11mode( 2544 struct hdd_context *hdd_ctx, uint32_t band_capability) 2545 { 2546 if (hdd_ctx->config->dot11Mode == eHDD_DOT11_MODE_AUTO) 2547 return band_capability; 2548 2549 if (hdd_ctx->config->dot11Mode == eHDD_DOT11_MODE_11b || 2550 hdd_ctx->config->dot11Mode == eHDD_DOT11_MODE_11g || 2551 hdd_ctx->config->dot11Mode == eHDD_DOT11_MODE_11g_ONLY || 2552 hdd_ctx->config->dot11Mode == eHDD_DOT11_MODE_11b_ONLY) 2553 band_capability = (band_capability & (~BIT(REG_BAND_5G))); 2554 2555 if (hdd_ctx->config->dot11Mode == eHDD_DOT11_MODE_11a) 2556 band_capability = (band_capability & (~BIT(REG_BAND_2G))); 2557 2558 if (hdd_ctx->config->dot11Mode != eHDD_DOT11_MODE_11ax_ONLY && 2559 hdd_ctx->config->dot11Mode != eHDD_DOT11_MODE_11ax) 2560 band_capability = (band_capability & (~BIT(REG_BAND_6G))); 2561 2562 qdf_debug("Update band capability %x", band_capability); 2563 return band_capability; 2564 } 2565 2566 #ifdef FEATURE_WPSS_THERMAL_MITIGATION 2567 static inline 2568 void hdd_update_multi_client_thermal_support(struct hdd_context *hdd_ctx) 2569 { 2570 struct wmi_unified *wmi_handle; 2571 2572 wmi_handle = get_wmi_unified_hdl_from_psoc(hdd_ctx->psoc); 2573 if (!wmi_handle) 2574 return; 2575 2576 hdd_ctx->multi_client_thermal_mitigation = 2577 wmi_service_enabled(wmi_handle, 2578 wmi_service_thermal_multi_client_support); 2579 } 2580 #else 2581 static inline 2582 void hdd_update_multi_client_thermal_support(struct hdd_context *hdd_ctx) 2583 { 2584 } 2585 #endif 2586 2587 #ifdef WLAN_FEATURE_LOCAL_PKT_CAPTURE 2588 static void hdd_lpc_enable_powersave(struct hdd_context *hdd_ctx) 2589 { 2590 struct hdd_adapter *sta_adapter; 2591 2592 if (!ucfg_dp_is_local_pkt_capture_enabled(hdd_ctx->psoc)) 2593 return; 2594 2595 ucfg_fwol_configure_global_params(hdd_ctx->psoc, hdd_ctx->pdev); 2596 2597 sta_adapter = hdd_get_adapter(hdd_ctx, QDF_STA_MODE); 2598 if (!sta_adapter) { 2599 hdd_debug("STA adapter does not exist"); 2600 return; 2601 } 2602 2603 wlan_hdd_set_powersave(sta_adapter->deflink, true, 0); 2604 } 2605 2606 static void hdd_lpc_disable_powersave(struct hdd_context *hdd_ctx) 2607 { 2608 struct hdd_adapter *sta_adapter; 2609 2610 if (!ucfg_dp_is_local_pkt_capture_enabled(hdd_ctx->psoc)) 2611 return; 2612 2613 ucfg_fwol_set_ilp_config(hdd_ctx->psoc, hdd_ctx->pdev, 0); 2614 2615 sta_adapter = hdd_get_adapter(hdd_ctx, QDF_STA_MODE); 2616 if (!sta_adapter) { 2617 hdd_err("STA adapter does not exist"); 2618 return; 2619 } 2620 wlan_hdd_set_powersave(sta_adapter->deflink, false, 0); 2621 } 2622 #else 2623 static inline void hdd_lpc_enable_powersave(struct hdd_context *hdd_ctx) 2624 { 2625 } 2626 2627 static inline void hdd_lpc_disable_powersave(struct hdd_context *hdd_ctx) 2628 { 2629 } 2630 #endif 2631 2632 int hdd_update_tgt_cfg(hdd_handle_t hdd_handle, struct wma_tgt_cfg *cfg) 2633 { 2634 int ret; 2635 struct hdd_context *hdd_ctx = hdd_handle_to_context(hdd_handle); 2636 uint32_t temp_band_cap, band_capability; 2637 struct cds_config_info *cds_cfg = cds_get_ini_config(); 2638 uint8_t antenna_mode; 2639 uint8_t sub_20_chan_width; 2640 QDF_STATUS status; 2641 mac_handle_t mac_handle; 2642 bool bval = false; 2643 uint8_t value = 0; 2644 uint32_t fine_time_meas_cap = 0; 2645 enum nss_chains_band_info band; 2646 bool enable_dynamic_cfg; 2647 2648 if (!hdd_ctx) { 2649 hdd_err("HDD context is NULL"); 2650 return -EINVAL; 2651 } 2652 ret = hdd_objmgr_create_and_store_pdev(hdd_ctx); 2653 if (ret) { 2654 QDF_DEBUG_PANIC("Failed to create pdev; errno:%d", ret); 2655 return -EINVAL; 2656 } 2657 2658 hdd_debug("New pdev has been created with pdev_id = %u", 2659 hdd_ctx->pdev->pdev_objmgr.wlan_pdev_id); 2660 2661 status = dispatcher_pdev_open(hdd_ctx->pdev); 2662 if (QDF_IS_STATUS_ERROR(status)) { 2663 QDF_DEBUG_PANIC("dispatcher pdev open failed; status:%d", 2664 status); 2665 ret = qdf_status_to_os_return(status); 2666 goto exit; 2667 } 2668 2669 status = hdd_component_pdev_open(hdd_ctx->pdev); 2670 if (QDF_IS_STATUS_ERROR(status)) { 2671 QDF_DEBUG_PANIC("hdd component pdev open failed; status:%d", 2672 status); 2673 ret = qdf_status_to_os_return(status); 2674 goto dispatcher_close; 2675 } 2676 /* 2677 * For 6GHz support this api is added to convert mlme cfgs 2678 * channel numbers to frequency 2679 */ 2680 hdd_component_cfg_chan_to_freq(hdd_ctx->pdev); 2681 2682 hdd_objmgr_update_tgt_max_vdev_psoc(hdd_ctx, cfg->max_intf_count); 2683 2684 ucfg_ipa_set_dp_handle(hdd_ctx->psoc, 2685 cds_get_context(QDF_MODULE_ID_SOC)); 2686 ucfg_ipa_set_pdev_id(hdd_ctx->psoc, OL_TXRX_PDEV_ID); 2687 2688 status = ucfg_mlme_get_sub_20_chan_width(hdd_ctx->psoc, 2689 &sub_20_chan_width); 2690 if (QDF_IS_STATUS_ERROR(status)) { 2691 hdd_err("Failed to get sub_20_chan_width config"); 2692 ret = qdf_status_to_os_return(status); 2693 goto pdev_close; 2694 } 2695 2696 if (cds_cfg) { 2697 if (sub_20_chan_width != 2698 WLAN_SUB_20_CH_WIDTH_NONE && !cfg->sub_20_support) { 2699 hdd_err("User requested sub 20 MHz channel width but unsupported by FW."); 2700 cds_cfg->sub_20_channel_width = 2701 WLAN_SUB_20_CH_WIDTH_NONE; 2702 } else { 2703 cds_cfg->sub_20_channel_width = sub_20_chan_width; 2704 } 2705 } 2706 2707 status = ucfg_mlme_get_band_capability(hdd_ctx->psoc, &band_capability); 2708 if (QDF_IS_STATUS_ERROR(status)) { 2709 hdd_err("Failed to get MLME band capability"); 2710 ret = qdf_status_to_os_return(status); 2711 goto pdev_close; 2712 } 2713 2714 band_capability = 2715 hdd_update_band_cap_from_dot11mode(hdd_ctx, band_capability); 2716 2717 /* first store the INI band capability */ 2718 temp_band_cap = band_capability; 2719 2720 band_capability = cfg->band_cap; 2721 hdd_ctx->is_fils_roaming_supported = 2722 cfg->services.is_fils_roaming_supported; 2723 2724 hdd_ctx->config->is_11k_offload_supported = 2725 cfg->services.is_11k_offload_supported; 2726 2727 /* 2728 * merge the target band capability with INI setting if the merge has 2729 * at least 1 band enabled 2730 */ 2731 temp_band_cap &= band_capability; 2732 if (!temp_band_cap) 2733 hdd_warn("ini BandCapability not supported by the target"); 2734 else 2735 band_capability = temp_band_cap; 2736 2737 status = ucfg_mlme_set_band_capability(hdd_ctx->psoc, band_capability); 2738 if (QDF_IS_STATUS_ERROR(status)) { 2739 hdd_err("Failed to set MLME Band Capability"); 2740 ret = qdf_status_to_os_return(status); 2741 goto pdev_close; 2742 } 2743 2744 hdd_ctx->curr_band = band_capability; 2745 hdd_ctx->psoc->soc_nif.user_config.band_capability = hdd_ctx->curr_band; 2746 2747 status = wlan_hdd_update_wiphy_supported_band(hdd_ctx); 2748 if (QDF_IS_STATUS_ERROR(status)) { 2749 hdd_err("Failed to update wiphy band info"); 2750 goto pdev_close; 2751 } 2752 2753 status = ucfg_reg_set_band(hdd_ctx->pdev, band_capability); 2754 if (QDF_IS_STATUS_ERROR(status)) 2755 /* 2756 * Continue, Do not close the pdev from here as if host fails 2757 * to update band information if cc_list event is not received 2758 * by this time, then also driver load should happen. 2759 */ 2760 hdd_err("Failed to update regulatory band info"); 2761 2762 if (!cds_is_driver_recovering() || cds_is_driver_in_bad_state()) { 2763 hdd_ctx->reg.reg_domain = cfg->reg_domain; 2764 hdd_ctx->reg.eeprom_rd_ext = cfg->eeprom_rd_ext; 2765 } 2766 2767 /* This can be extended to other configurations like ht, vht cap... */ 2768 status = wlan_hdd_validate_mac_address(&cfg->hw_macaddr); 2769 if (QDF_IS_STATUS_SUCCESS(status)) 2770 qdf_mem_copy(&hdd_ctx->hw_macaddr, &cfg->hw_macaddr, 2771 QDF_MAC_ADDR_SIZE); 2772 2773 hdd_ctx->target_fw_version = cfg->target_fw_version; 2774 hdd_ctx->target_fw_vers_ext = cfg->target_fw_vers_ext; 2775 hdd_extract_fw_version_info(hdd_ctx); 2776 2777 hdd_ctx->hw_bd_id = cfg->hw_bd_id; 2778 qdf_mem_copy(&hdd_ctx->hw_bd_info, &cfg->hw_bd_info, 2779 sizeof(cfg->hw_bd_info)); 2780 2781 if (cfg->max_intf_count > WLAN_MAX_VDEVS) { 2782 hdd_err("fw max vdevs (%u) > host max vdevs (%u); using %u", 2783 cfg->max_intf_count, WLAN_MAX_VDEVS, WLAN_MAX_VDEVS); 2784 hdd_ctx->max_intf_count = WLAN_MAX_VDEVS; 2785 } else { 2786 hdd_ctx->max_intf_count = cfg->max_intf_count; 2787 } 2788 2789 hdd_sar_target_config(hdd_ctx, cfg); 2790 hdd_lpass_target_config(hdd_ctx, cfg); 2791 2792 hdd_ctx->ap_arpns_support = cfg->ap_arpns_support; 2793 2794 hdd_update_tgt_services(hdd_ctx, &cfg->services); 2795 2796 hdd_update_tgt_ht_cap(hdd_ctx, &cfg->ht_cap); 2797 2798 sme_update_bfer_caps_as_per_nss_chains(hdd_ctx->mac_handle, cfg); 2799 2800 hdd_update_tgt_vht_cap(hdd_ctx, &cfg->vht_cap); 2801 if (cfg->services.en_11ax && 2802 (hdd_ctx->config->dot11Mode == eHDD_DOT11_MODE_AUTO || 2803 hdd_ctx->config->dot11Mode == eHDD_DOT11_MODE_11ax || 2804 hdd_ctx->config->dot11Mode == eHDD_DOT11_MODE_11ax_ONLY)) { 2805 hdd_debug("11AX: 11ax is enabled - update HDD config"); 2806 hdd_update_tgt_he_cap(hdd_ctx, cfg); 2807 hdd_update_wiphy_he_cap(hdd_ctx); 2808 } 2809 hdd_update_tgt_twt_cap(hdd_ctx, cfg); 2810 hdd_update_tgt_eht_cap(hdd_ctx, cfg); 2811 hdd_update_wiphy_eht_cap(hdd_ctx); 2812 ucfg_mlme_update_tgt_mlo_cap(hdd_ctx->psoc); 2813 2814 for (band = NSS_CHAINS_BAND_2GHZ; band < NSS_CHAINS_BAND_MAX; band++) { 2815 sme_modify_nss_chains_tgt_cfg(hdd_ctx->mac_handle, 2816 QDF_STA_MODE, band); 2817 sme_modify_nss_chains_tgt_cfg(hdd_ctx->mac_handle, 2818 QDF_SAP_MODE, band); 2819 sme_modify_nss_chains_tgt_cfg(hdd_ctx->mac_handle, 2820 QDF_TDLS_MODE, band); 2821 sme_modify_nss_chains_tgt_cfg(hdd_ctx->mac_handle, 2822 QDF_P2P_DEVICE_MODE, 2823 band); 2824 sme_modify_nss_chains_tgt_cfg(hdd_ctx->mac_handle, 2825 QDF_OCB_MODE, band); 2826 sme_modify_nss_chains_tgt_cfg(hdd_ctx->mac_handle, 2827 QDF_TDLS_MODE, band); 2828 } 2829 2830 hdd_update_vdev_nss(hdd_ctx); 2831 2832 status = 2833 ucfg_mlme_get_enable_dynamic_nss_chains_cfg(hdd_ctx->psoc, 2834 &enable_dynamic_cfg); 2835 if (QDF_IS_STATUS_ERROR(status)) { 2836 hdd_err("unable to get enable dynamic config"); 2837 hdd_ctx->dynamic_nss_chains_support = false; 2838 } else { 2839 hdd_ctx->dynamic_nss_chains_support = 2840 cfg->dynamic_nss_chains_support & 2841 enable_dynamic_cfg; 2842 hdd_debug("Dynamic nss chain support FW %d driver %d", 2843 cfg->dynamic_nss_chains_support, enable_dynamic_cfg); 2844 } 2845 2846 status = ucfg_mlme_update_dynamic_nss_chains_support 2847 (hdd_ctx->psoc, hdd_ctx->dynamic_nss_chains_support); 2848 if (QDF_IS_STATUS_ERROR(status)) 2849 hdd_err("unable to set dynamic_nss_chains_support"); 2850 2851 ucfg_mlme_get_fine_time_meas_cap(hdd_ctx->psoc, &fine_time_meas_cap); 2852 fine_time_meas_cap &= cfg->fine_time_measurement_cap; 2853 status = ucfg_mlme_set_fine_time_meas_cap(hdd_ctx->psoc, 2854 fine_time_meas_cap); 2855 if (QDF_IS_STATUS_ERROR(status)) { 2856 hdd_err("failed to set fine_time_meas_cap, 0x%x, ox%x", 2857 fine_time_meas_cap, cfg->fine_time_measurement_cap); 2858 ucfg_mlme_get_fine_time_meas_cap(hdd_ctx->psoc, 2859 &fine_time_meas_cap); 2860 } 2861 2862 hdd_ctx->fine_time_meas_cap_target = cfg->fine_time_measurement_cap; 2863 hdd_debug("fine_time_meas_cap: 0x%x", fine_time_meas_cap); 2864 2865 status = ucfg_mlme_get_vht_enable2x2(hdd_ctx->psoc, &bval); 2866 if (!QDF_IS_STATUS_SUCCESS(status)) 2867 hdd_err("unable to get vht_enable2x2"); 2868 2869 antenna_mode = (bval == 0x01) ? 2870 HDD_ANTENNA_MODE_2X2 : HDD_ANTENNA_MODE_1X1; 2871 hdd_update_smps_antenna_mode(hdd_ctx, antenna_mode); 2872 hdd_debug("Init current antenna mode: %d", 2873 hdd_ctx->current_antenna_mode); 2874 2875 hdd_ctx->rcpi_enabled = cfg->rcpi_enabled; 2876 2877 status = ucfg_mlme_cfg_get_vht_tx_bfee_ant_supp(hdd_ctx->psoc, 2878 &value); 2879 if (QDF_IS_STATUS_ERROR(status)) { 2880 status = false; 2881 hdd_err("set tx_bfee_ant_supp failed"); 2882 } 2883 2884 status = ucfg_mlme_set_restricted_80p80_bw_supp(hdd_ctx->psoc, 2885 cfg->restricted_80p80_bw_supp); 2886 if (QDF_IS_STATUS_ERROR(status)) 2887 hdd_err("Failed to set MLME restircted 80p80 BW support"); 2888 2889 if ((value > MLME_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED_FW_DEF) && 2890 !cfg->tx_bfee_8ss_enabled) { 2891 status = ucfg_mlme_cfg_set_vht_tx_bfee_ant_supp(hdd_ctx->psoc, 2892 MLME_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED_FW_DEF); 2893 if (QDF_IS_STATUS_ERROR(status)) { 2894 status = false; 2895 hdd_err("set tx_bfee_ant_supp failed"); 2896 } 2897 } 2898 2899 mac_handle = hdd_ctx->mac_handle; 2900 2901 hdd_debug("txBFCsnValue %d", value); 2902 2903 /* 2904 * Update txBFCsnValue and NumSoundingDim values to vhtcap in wiphy 2905 */ 2906 hdd_update_wiphy_vhtcap(hdd_ctx); 2907 2908 hdd_update_vhtcap_2g(hdd_ctx); 2909 2910 hdd_ctx->wmi_max_len = cfg->wmi_max_len; 2911 2912 wlan_config_sched_scan_plans_to_wiphy(hdd_ctx->wiphy, hdd_ctx->psoc); 2913 /* 2914 * This needs to be done after HDD pdev is created and stored since 2915 * it will access the HDD pdev object lock. 2916 */ 2917 hdd_runtime_suspend_context_init(hdd_ctx); 2918 2919 /* Configure NAN datapath features */ 2920 hdd_nan_datapath_target_config(hdd_ctx, cfg); 2921 ucfg_nan_set_tgt_caps(hdd_ctx->psoc, &cfg->nan_caps); 2922 hdd_ctx->dfs_cac_offload = cfg->dfs_cac_offload; 2923 hdd_ctx->lte_coex_ant_share = cfg->services.lte_coex_ant_share; 2924 hdd_ctx->obss_scan_offload = cfg->services.obss_scan_offload; 2925 ucfg_scan_set_obss_scan_offload(hdd_ctx->psoc, 2926 hdd_ctx->obss_scan_offload); 2927 status = ucfg_mlme_set_obss_detection_offload_enabled( 2928 hdd_ctx->psoc, cfg->obss_detection_offloaded); 2929 if (QDF_IS_STATUS_ERROR(status)) 2930 hdd_err("Couldn't pass WNI_CFG_OBSS_DETECTION_OFFLOAD to CFG"); 2931 2932 status = ucfg_mlme_set_obss_color_collision_offload_enabled( 2933 hdd_ctx->psoc, cfg->obss_color_collision_offloaded); 2934 if (QDF_IS_STATUS_ERROR(status)) 2935 hdd_err("Failed to set WNI_CFG_OBSS_COLOR_COLLISION_OFFLOAD"); 2936 2937 ucfg_mlme_set_bss_color_collision_det_support( 2938 hdd_ctx->psoc, 2939 cfg->obss_color_collision_offloaded); 2940 if (!cfg->obss_color_collision_offloaded) { 2941 status = ucfg_mlme_set_bss_color_collision_det_sta( 2942 hdd_ctx->psoc, 2943 cfg->obss_color_collision_offloaded); 2944 if (QDF_IS_STATUS_ERROR(status)) 2945 hdd_err("Failed to set CFG_BSS_CLR_COLLISION_DET_STA"); 2946 } 2947 2948 hdd_update_score_config(hdd_ctx); 2949 hdd_update_multi_client_thermal_support(hdd_ctx); 2950 2951 ucfg_psoc_mlme_set_11be_capab(hdd_ctx->psoc, cfg->services.en_11be); 2952 return 0; 2953 2954 dispatcher_close: 2955 dispatcher_pdev_close(hdd_ctx->pdev); 2956 pdev_close: 2957 hdd_component_pdev_close(hdd_ctx->pdev); 2958 exit: 2959 hdd_objmgr_release_and_destroy_pdev(hdd_ctx); 2960 2961 return ret; 2962 } 2963 2964 bool hdd_dfs_indicate_radar(struct hdd_context *hdd_ctx) 2965 { 2966 struct hdd_adapter *adapter, *next_adapter = NULL; 2967 struct hdd_ap_ctx *ap_ctx; 2968 uint32_t ap_chan; 2969 bool dfs_disable_channel_switch = false; 2970 struct wlan_hdd_link_info *link_info; 2971 2972 if (!hdd_ctx) { 2973 hdd_info("Couldn't get hdd_ctx"); 2974 return true; 2975 } 2976 2977 ucfg_mlme_get_dfs_disable_channel_switch(hdd_ctx->psoc, 2978 &dfs_disable_channel_switch); 2979 if (dfs_disable_channel_switch) { 2980 hdd_info("skip tx block hdd_ctx=%pK, disableDFSChSwitch=%d", 2981 hdd_ctx, dfs_disable_channel_switch); 2982 return true; 2983 } 2984 2985 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 2986 NET_DEV_HOLD_DFS_INDICATE_RADAR) { 2987 2988 if (adapter->device_mode != QDF_SAP_MODE && 2989 adapter->device_mode != QDF_P2P_GO_MODE) 2990 goto next_adapter; 2991 2992 hdd_adapter_for_each_active_link_info(adapter, link_info) { 2993 ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(link_info); 2994 ap_chan = ap_ctx->operating_chan_freq; 2995 if (!wlan_reg_is_passive_or_disable_for_pwrmode(hdd_ctx->pdev, 2996 ap_chan, REG_CURRENT_PWR_MODE)) 2997 continue; 2998 2999 ap_ctx->dfs_cac_block_tx = true; 3000 hdd_info("tx blocked for vdev: %d", link_info->vdev_id); 3001 if (link_info->vdev_id != WLAN_UMAC_VDEV_ID_MAX) 3002 cdp_fc_vdev_flush( 3003 cds_get_context(QDF_MODULE_ID_SOC), 3004 link_info->vdev_id); 3005 } 3006 next_adapter: 3007 hdd_adapter_dev_put_debug(adapter, 3008 NET_DEV_HOLD_DFS_INDICATE_RADAR); 3009 } 3010 3011 return true; 3012 } 3013 3014 bool hdd_is_valid_mac_address(const uint8_t *mac_addr) 3015 { 3016 int xdigit = 0; 3017 int separator = 0; 3018 3019 while (*mac_addr) { 3020 if (isxdigit(*mac_addr)) { 3021 xdigit++; 3022 } else if (':' == *mac_addr) { 3023 if (0 == xdigit || ((xdigit / 2) - 1) != separator) 3024 break; 3025 3026 ++separator; 3027 } else { 3028 /* Invalid MAC found */ 3029 return false; 3030 } 3031 ++mac_addr; 3032 } 3033 return xdigit == 12 && (separator == 5 || separator == 0); 3034 } 3035 3036 /** 3037 * hdd_mon_mode_ether_setup() - Update monitor mode struct net_device. 3038 * @dev: Handle to struct net_device to be updated. 3039 * 3040 * Return: None 3041 */ 3042 static void hdd_mon_mode_ether_setup(struct net_device *dev) 3043 { 3044 dev->header_ops = NULL; 3045 dev->type = ARPHRD_IEEE80211_RADIOTAP; 3046 dev->hard_header_len = ETH_HLEN; 3047 dev->mtu = ETH_DATA_LEN; 3048 dev->addr_len = ETH_ALEN; 3049 dev->tx_queue_len = 1000; /* Ethernet wants good queues */ 3050 dev->flags = IFF_BROADCAST|IFF_MULTICAST; 3051 dev->priv_flags |= IFF_TX_SKB_SHARING; 3052 3053 memset(dev->broadcast, 0xFF, ETH_ALEN); 3054 } 3055 3056 #ifdef FEATURE_MONITOR_MODE_SUPPORT 3057 /** 3058 * hdd_mon_turn_off_ps_and_wow() - Update monitor mode struct net_device. 3059 * @hdd_ctx: Pointer to HDD context. 3060 * 3061 * Return: None 3062 */ 3063 static void hdd_mon_turn_off_ps_and_wow(struct hdd_context *hdd_ctx) 3064 { 3065 ucfg_pmo_set_power_save_mode(hdd_ctx->psoc, 3066 PMO_PS_ADVANCED_POWER_SAVE_DISABLE); 3067 ucfg_pmo_set_wow_enable(hdd_ctx->psoc, PMO_WOW_DISABLE_BOTH); 3068 } 3069 3070 /** 3071 * __hdd_mon_open() - HDD Open function 3072 * @dev: Pointer to net_device structure 3073 * 3074 * This is called in response to ifconfig up 3075 * 3076 * Return: 0 for success; non-zero for failure 3077 */ 3078 static int __hdd_mon_open(struct net_device *dev) 3079 { 3080 int ret; 3081 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev); 3082 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); 3083 struct bbm_params param = {0}; 3084 3085 hdd_enter_dev(dev); 3086 3087 if (test_bit(DEVICE_IFACE_OPENED, &adapter->event_flags)) { 3088 hdd_debug_rl("Monitor interface is already up"); 3089 return 0; 3090 } 3091 3092 ret = wlan_hdd_validate_context(hdd_ctx); 3093 if (ret) 3094 return ret; 3095 3096 hdd_mon_mode_ether_setup(dev); 3097 3098 if (con_mode == QDF_GLOBAL_MONITOR_MODE || 3099 ucfg_mlme_is_sta_mon_conc_supported(hdd_ctx->psoc) || 3100 ucfg_dp_is_local_pkt_capture_enabled(hdd_ctx->psoc)) { 3101 ret = hdd_trigger_psoc_idle_restart(hdd_ctx); 3102 if (ret) { 3103 hdd_err("Failed to start WLAN modules return"); 3104 return ret; 3105 } 3106 hdd_err("hdd_wlan_start_modules() successful !"); 3107 3108 if ((!test_bit(SME_SESSION_OPENED, 3109 &adapter->deflink->link_flags)) || 3110 (policy_mgr_is_sta_mon_concurrency(hdd_ctx->psoc))) { 3111 ret = hdd_start_adapter(adapter, true); 3112 if (ret) { 3113 hdd_err("Failed to start adapter :%d", 3114 adapter->device_mode); 3115 return ret; 3116 } 3117 hdd_err("hdd_start_adapters() successful !"); 3118 } 3119 hdd_mon_turn_off_ps_and_wow(hdd_ctx); 3120 set_bit(DEVICE_IFACE_OPENED, &adapter->event_flags); 3121 } 3122 3123 if (con_mode != QDF_GLOBAL_MONITOR_MODE && 3124 (ucfg_mlme_is_sta_mon_conc_supported(hdd_ctx->psoc) || 3125 ucfg_dp_is_local_pkt_capture_enabled(hdd_ctx->psoc))) { 3126 hdd_info("Acquire wakelock for STA + monitor mode"); 3127 3128 qdf_wake_lock_acquire(&hdd_ctx->monitor_mode_wakelock, 3129 WIFI_POWER_EVENT_WAKELOCK_MONITOR_MODE); 3130 hdd_lpc_disable_powersave(hdd_ctx); 3131 qdf_runtime_pm_prevent_suspend( 3132 &hdd_ctx->runtime_context.monitor_mode); 3133 } 3134 3135 ret = hdd_set_mon_rx_cb(dev); 3136 3137 if (!ret) 3138 ret = hdd_enable_monitor_mode(dev); 3139 3140 if (!ret) { 3141 param.policy = BBM_DRIVER_MODE_POLICY; 3142 param.policy_info.driver_mode = QDF_GLOBAL_MONITOR_MODE; 3143 ucfg_dp_bbm_apply_independent_policy(hdd_ctx->psoc, ¶m); 3144 ucfg_dp_set_current_throughput_level(hdd_ctx->psoc, 3145 PLD_BUS_WIDTH_VERY_HIGH); 3146 } 3147 3148 return ret; 3149 } 3150 3151 /** 3152 * hdd_mon_open() - Wrapper function for __hdd_mon_open to protect it from SSR 3153 * @net_dev: Pointer to net_device structure 3154 * 3155 * This is called in response to ifconfig up 3156 * 3157 * Return: 0 for success; non-zero for failure 3158 */ 3159 static int hdd_mon_open(struct net_device *net_dev) 3160 { 3161 int errno; 3162 struct osif_vdev_sync *vdev_sync; 3163 3164 errno = osif_vdev_sync_trans_start(net_dev, &vdev_sync); 3165 if (errno) 3166 return errno; 3167 3168 errno = __hdd_mon_open(net_dev); 3169 3170 osif_vdev_sync_trans_stop(vdev_sync); 3171 3172 return errno; 3173 } 3174 #endif 3175 3176 #ifdef WLAN_FEATURE_PKT_CAPTURE 3177 /** 3178 * __hdd_pktcapture_open() - HDD Open function 3179 * @dev: Pointer to net_device structure 3180 * 3181 * This is called in response to ifconfig up 3182 * 3183 * Return: 0 for success; non-zero for failure 3184 */ 3185 static int __hdd_pktcapture_open(struct net_device *dev) 3186 { 3187 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev); 3188 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); 3189 struct hdd_adapter *sta_adapter; 3190 QDF_STATUS status; 3191 struct wlan_objmgr_vdev *vdev; 3192 int ret; 3193 3194 hdd_enter_dev(dev); 3195 3196 ret = wlan_hdd_validate_context(hdd_ctx); 3197 if (ret) 3198 return ret; 3199 3200 sta_adapter = hdd_get_adapter(hdd_ctx, QDF_STA_MODE); 3201 if (!sta_adapter) { 3202 hdd_err("No station interface found"); 3203 return -EINVAL; 3204 } 3205 3206 vdev = hdd_objmgr_get_vdev_by_user(sta_adapter->deflink, WLAN_OSIF_ID); 3207 if (!vdev) 3208 return -EINVAL; 3209 3210 hdd_mon_mode_ether_setup(dev); 3211 3212 status = ucfg_dp_register_pkt_capture_callbacks(vdev); 3213 ret = qdf_status_to_os_return(status); 3214 if (ret) { 3215 hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_ID); 3216 return ret; 3217 } 3218 3219 adapter->deflink->vdev = vdev; 3220 set_bit(DEVICE_IFACE_OPENED, &adapter->event_flags); 3221 sta_adapter->mon_adapter = adapter; 3222 3223 return ret; 3224 } 3225 3226 /** 3227 * hdd_pktcapture_open() - Wrapper function for hdd_pktcapture_open to 3228 * protect it from SSR 3229 * @net_dev: Pointer to net_device structure 3230 * 3231 * This is called in response to ifconfig up 3232 * 3233 * Return: 0 for success; non-zero for failure 3234 */ 3235 static int hdd_pktcapture_open(struct net_device *net_dev) 3236 { 3237 int errno; 3238 struct osif_vdev_sync *vdev_sync; 3239 3240 errno = osif_vdev_sync_trans_start(net_dev, &vdev_sync); 3241 if (errno) 3242 return errno; 3243 3244 errno = __hdd_pktcapture_open(net_dev); 3245 3246 osif_vdev_sync_trans_stop(vdev_sync); 3247 3248 return errno; 3249 } 3250 3251 /** 3252 * hdd_unmap_monitor_interface_vdev() - unmap monitor interface vdev and 3253 * deregister packet capture callbacks 3254 * @sta_adapter: station adapter 3255 * 3256 * Return: void 3257 */ 3258 static void 3259 hdd_unmap_monitor_interface_vdev(struct hdd_adapter *sta_adapter) 3260 { 3261 struct hdd_adapter *mon_adapter = sta_adapter->mon_adapter; 3262 3263 if (mon_adapter && hdd_is_interface_up(mon_adapter)) { 3264 ucfg_pkt_capture_deregister_callbacks( 3265 mon_adapter->deflink->vdev); 3266 hdd_objmgr_put_vdev_by_user(mon_adapter->deflink->vdev, 3267 WLAN_OSIF_ID); 3268 mon_adapter->deflink->vdev = NULL; 3269 hdd_reset_monitor_interface(sta_adapter); 3270 } 3271 } 3272 3273 /** 3274 * hdd_map_monitor_interface_vdev() - Map monitor interface vdev and 3275 * register packet capture callbacks 3276 * @sta_adapter: Station adapter 3277 * 3278 * Return: None 3279 */ 3280 static void hdd_map_monitor_interface_vdev(struct hdd_adapter *sta_adapter) 3281 { 3282 struct hdd_adapter *mon_adapter; 3283 QDF_STATUS status; 3284 struct wlan_objmgr_vdev *vdev; 3285 int ret; 3286 3287 mon_adapter = hdd_get_adapter(sta_adapter->hdd_ctx, QDF_MONITOR_MODE); 3288 if (!mon_adapter) { 3289 hdd_debug("No monitor interface found"); 3290 return; 3291 } 3292 3293 if (!mon_adapter || !hdd_is_interface_up(mon_adapter)) { 3294 hdd_debug("Monitor interface is not up\n"); 3295 return; 3296 } 3297 3298 if (!wlan_hdd_is_session_type_monitor(mon_adapter->device_mode)) 3299 return; 3300 3301 vdev = hdd_objmgr_get_vdev_by_user(sta_adapter->deflink, WLAN_OSIF_ID); 3302 if (!vdev) 3303 return; 3304 3305 status = ucfg_dp_register_pkt_capture_callbacks(vdev); 3306 ret = qdf_status_to_os_return(status); 3307 if (ret) { 3308 hdd_err("Failed registering packet capture callbacks"); 3309 hdd_objmgr_put_vdev_by_user(vdev, 3310 WLAN_OSIF_ID); 3311 return; 3312 } 3313 3314 mon_adapter->deflink->vdev = vdev; 3315 sta_adapter->mon_adapter = mon_adapter; 3316 } 3317 3318 void hdd_reset_monitor_interface(struct hdd_adapter *sta_adapter) 3319 { 3320 sta_adapter->mon_adapter = NULL; 3321 } 3322 3323 struct hdd_adapter * 3324 hdd_is_pkt_capture_mon_enable(struct hdd_adapter *sta_adapter) 3325 { 3326 return sta_adapter->mon_adapter; 3327 } 3328 #else 3329 static inline void 3330 hdd_unmap_monitor_interface_vdev(struct hdd_adapter *sta_adapter) 3331 { 3332 } 3333 3334 static inline void 3335 hdd_map_monitor_interface_vdev(struct hdd_adapter *sta_adapter) 3336 { 3337 } 3338 #endif 3339 3340 static QDF_STATUS 3341 wlan_hdd_update_dbs_scan_and_fw_mode_config(void) 3342 { 3343 struct policy_mgr_dual_mac_config cfg = {0}; 3344 QDF_STATUS status; 3345 uint32_t chnl_sel_logic_conc = 0; 3346 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 3347 uint8_t dual_mac_feature = DISABLE_DBS_CXN_AND_SCAN; 3348 3349 if (!hdd_ctx) 3350 return QDF_STATUS_E_FAILURE; 3351 3352 /* 3353 * ROME platform doesn't support any DBS related commands in FW, 3354 * so if driver sends wmi command with dual_mac_config with all set to 3355 * 0 then FW wouldn't respond back and driver would timeout on waiting 3356 * for response. Check if FW supports DBS to eliminate ROME vs 3357 * NON-ROME platform. 3358 */ 3359 if (!policy_mgr_find_if_fw_supports_dbs(hdd_ctx->psoc)) 3360 return QDF_STATUS_SUCCESS; 3361 3362 if (hdd_ctx->is_dual_mac_cfg_updated) { 3363 hdd_debug("dual mac config has already been updated, skip"); 3364 return QDF_STATUS_SUCCESS; 3365 } 3366 3367 cfg.scan_config = 0; 3368 cfg.fw_mode_config = 0; 3369 cfg.set_dual_mac_cb = policy_mgr_soc_set_dual_mac_cfg_cb; 3370 if (policy_mgr_is_hw_dbs_capable(hdd_ctx->psoc)) { 3371 status = 3372 ucfg_policy_mgr_get_chnl_select_plcy(hdd_ctx->psoc, 3373 &chnl_sel_logic_conc); 3374 if (status != QDF_STATUS_SUCCESS) { 3375 hdd_err("can't get chnl sel policy, use def"); 3376 return status; 3377 } 3378 } 3379 status = 3380 ucfg_policy_mgr_get_dual_mac_feature(hdd_ctx->psoc, 3381 &dual_mac_feature); 3382 if (status != QDF_STATUS_SUCCESS) { 3383 hdd_err("ucfg_policy_mgr_get_dual_mac_feature failed, use def"); 3384 return status; 3385 } 3386 3387 if (dual_mac_feature != DISABLE_DBS_CXN_AND_SCAN) { 3388 status = policy_mgr_get_updated_scan_and_fw_mode_config( 3389 hdd_ctx->psoc, &cfg.scan_config, 3390 &cfg.fw_mode_config, 3391 dual_mac_feature, 3392 chnl_sel_logic_conc); 3393 3394 if (status != QDF_STATUS_SUCCESS) { 3395 hdd_err("wma_get_updated_scan_and_fw_mode_config failed %d", 3396 status); 3397 return status; 3398 } 3399 } 3400 3401 hdd_debug("send scan_cfg: 0x%x fw_mode_cfg: 0x%x to fw", 3402 cfg.scan_config, cfg.fw_mode_config); 3403 3404 status = sme_soc_set_dual_mac_config(cfg); 3405 if (QDF_IS_STATUS_ERROR(status)) { 3406 hdd_err("sme_soc_set_dual_mac_config failed %d", status); 3407 return status; 3408 } 3409 hdd_ctx->is_dual_mac_cfg_updated = true; 3410 3411 return QDF_STATUS_SUCCESS; 3412 } 3413 3414 /** 3415 * hdd_max_sta_interface_up_count_reached() - check sta/p2p_cli vdev count 3416 * @adapter: HDD adapter 3417 * 3418 * Return: true if vdev limit reached 3419 */ 3420 static bool hdd_max_sta_interface_up_count_reached(struct hdd_adapter *adapter) 3421 { 3422 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); 3423 struct hdd_adapter *temp_adapter = NULL, *next_adapter = NULL; 3424 uint8_t intf_count = 0; 3425 wlan_net_dev_ref_dbgid dbgid = 3426 NET_DEV_HOLD_MAX_STA_INTERFACE_UP_COUNT_REACHED; 3427 3428 if (0 == CFG_TGT_DEFAULT_MAX_STA_VDEVS) 3429 return false; 3430 3431 /* 3432 * Check for max no of supported STA/P2PCLI VDEVs before 3433 * creating another one. 3434 */ 3435 hdd_for_each_adapter_dev_held_safe(hdd_ctx, temp_adapter, 3436 next_adapter, dbgid) { 3437 if ((temp_adapter != adapter) && 3438 (temp_adapter->dev->flags & IFF_UP) && 3439 ((temp_adapter->device_mode == QDF_STA_MODE) || 3440 (temp_adapter->device_mode == QDF_P2P_CLIENT_MODE))) 3441 intf_count++; 3442 3443 hdd_adapter_dev_put_debug(temp_adapter, dbgid); 3444 } 3445 3446 if (intf_count >= CFG_TGT_DEFAULT_MAX_STA_VDEVS) { 3447 hdd_err("Max limit reached sta vdev-current %d max %d", 3448 intf_count, CFG_TGT_DEFAULT_MAX_STA_VDEVS); 3449 return true; 3450 } 3451 return false; 3452 } 3453 3454 #if (defined(WLAN_FEATURE_11BE_MLO) && defined(CFG80211_11BE_BASIC)) && \ 3455 (defined(CFG80211_IFTYPE_MLO_LINK_SUPPORT) || \ 3456 defined(CFG80211_SINGLE_NETDEV_MULTI_LINK_SUPPORT)) && \ 3457 !defined(WLAN_HDD_MULTI_VDEV_SINGLE_NDEV) 3458 static int hdd_start_link_adapter(struct hdd_adapter *sta_adapter) 3459 { 3460 int i, ret = 0; 3461 struct hdd_mlo_adapter_info *mlo_adapter_info; 3462 struct hdd_adapter *link_adapter; 3463 3464 hdd_enter_dev(sta_adapter->dev); 3465 mlo_adapter_info = &sta_adapter->mlo_adapter_info; 3466 3467 for (i = 0; i < WLAN_MAX_MLD; i++) { 3468 link_adapter = mlo_adapter_info->link_adapter[i]; 3469 if (!link_adapter) 3470 continue; 3471 if (link_adapter->mlo_adapter_info.associate_with_ml_adapter) { 3472 /* TODO have proper references here */ 3473 qdf_spin_lock_bh(&link_adapter->deflink->vdev_lock); 3474 link_adapter->deflink->vdev = 3475 sta_adapter->deflink->vdev; 3476 link_adapter->deflink->vdev_id = 3477 sta_adapter->deflink->vdev_id; 3478 qdf_spin_unlock_bh(&link_adapter->deflink->vdev_lock); 3479 3480 sta_adapter->link_info[i].vdev_id = 3481 sta_adapter->deflink->vdev_id; 3482 continue; 3483 } 3484 ret = hdd_start_station_adapter(link_adapter); 3485 if (!ret) { 3486 sta_adapter->link_info[i].vdev_id = 3487 link_adapter->deflink->vdev_id; 3488 } 3489 } 3490 3491 hdd_adapter_update_mlo_mgr_mac_addr(sta_adapter); 3492 3493 hdd_exit(); 3494 return ret; 3495 } 3496 3497 static int hdd_stop_link_adapter(struct hdd_context *hdd_ctx, 3498 struct hdd_adapter *sta_adapter) 3499 { 3500 int i, ret = 0; 3501 struct hdd_mlo_adapter_info *mlo_adapter_info; 3502 struct hdd_adapter *link_adapter; 3503 3504 hdd_enter_dev(sta_adapter->dev); 3505 hdd_debug("Stop adapter for link mode : %s(%d)", 3506 qdf_opmode_str(sta_adapter->device_mode), 3507 sta_adapter->deflink->vdev_id); 3508 3509 mlo_adapter_info = &sta_adapter->mlo_adapter_info; 3510 for (i = 0; i < WLAN_MAX_MLD; i++) { 3511 link_adapter = mlo_adapter_info->link_adapter[i]; 3512 if (!link_adapter) 3513 continue; 3514 3515 if (link_adapter->mlo_adapter_info.associate_with_ml_adapter) { 3516 /* TODO have proper references here */ 3517 qdf_spin_lock_bh(&link_adapter->deflink->vdev_lock); 3518 link_adapter->deflink->vdev = NULL; 3519 link_adapter->deflink->vdev_id = 0xff; 3520 qdf_spin_unlock_bh(&link_adapter->deflink->vdev_lock); 3521 continue; 3522 } 3523 ret = hdd_stop_adapter_ext(hdd_ctx, link_adapter); 3524 } 3525 3526 hdd_exit(); 3527 return ret; 3528 } 3529 #else 3530 static int hdd_start_link_adapter(struct hdd_adapter *link_adapter) 3531 { 3532 return 0; 3533 } 3534 3535 static int hdd_stop_link_adapter(struct hdd_context *hdd_ctx, 3536 struct hdd_adapter *link_adapter) 3537 { 3538 return 0; 3539 } 3540 #endif 3541 3542 /** 3543 * hdd_start_adapter() - Wrapper function for device specific adapter 3544 * @adapter: pointer to HDD adapter 3545 * @rtnl_held: true if rtnl lock is taken, otherwise false 3546 * 3547 * This function is called to start the device specific adapter for 3548 * the mode passed in the adapter's device_mode. 3549 * 3550 * Return: 0 for success; non-zero for failure 3551 */ 3552 int hdd_start_adapter(struct hdd_adapter *adapter, bool rtnl_held) 3553 { 3554 3555 int ret; 3556 enum QDF_OPMODE device_mode = adapter->device_mode; 3557 3558 hdd_enter_dev(adapter->dev); 3559 3560 switch (device_mode) { 3561 case QDF_STA_MODE: 3562 case QDF_P2P_CLIENT_MODE: 3563 if (hdd_max_sta_interface_up_count_reached(adapter)) 3564 goto err_start_adapter; 3565 3566 fallthrough; 3567 case QDF_P2P_DEVICE_MODE: 3568 case QDF_OCB_MODE: 3569 case QDF_MONITOR_MODE: 3570 case QDF_NAN_DISC_MODE: 3571 ret = hdd_start_station_adapter(adapter); 3572 if (ret) 3573 goto err_start_adapter; 3574 3575 if (device_mode == QDF_STA_MODE) { 3576 ret = hdd_start_link_adapter(adapter); 3577 if (ret) 3578 hdd_err("Failed to start link adapter:%d", ret); 3579 } 3580 break; 3581 case QDF_P2P_GO_MODE: 3582 case QDF_SAP_MODE: 3583 ret = hdd_start_ap_adapter(adapter, rtnl_held); 3584 if (ret) 3585 goto err_start_adapter; 3586 break; 3587 case QDF_FTM_MODE: 3588 /* vdevs are dynamically managed by firmware in FTM */ 3589 hdd_register_wext(adapter->dev); 3590 goto exit_with_success; 3591 default: 3592 hdd_err("Invalid session type %d", device_mode); 3593 QDF_ASSERT(0); 3594 goto err_start_adapter; 3595 } 3596 3597 if (hdd_set_fw_params(adapter)) 3598 hdd_err("Failed to set the FW params for the adapter!"); 3599 3600 if (adapter->deflink->vdev_id != WLAN_UMAC_VDEV_ID_MAX) { 3601 ret = wlan_hdd_cfg80211_register_frames(adapter); 3602 if (ret < 0) { 3603 hdd_err("Failed to register frames - ret %d", ret); 3604 goto err_start_adapter; 3605 } 3606 } 3607 3608 wlan_hdd_update_dbs_scan_and_fw_mode_config(); 3609 3610 exit_with_success: 3611 hdd_create_adapter_sysfs_files(adapter); 3612 3613 hdd_exit(); 3614 3615 return 0; 3616 3617 err_start_adapter: 3618 return -EINVAL; 3619 } 3620 3621 void hdd_update_hw_sw_info(struct hdd_context *hdd_ctx) 3622 { 3623 void *hif_sc; 3624 size_t target_hw_name_len; 3625 const char *target_hw_name; 3626 uint8_t *buf; 3627 uint32_t buf_len; 3628 3629 hif_sc = cds_get_context(QDF_MODULE_ID_HIF); 3630 if (!hif_sc) 3631 return; 3632 3633 hif_get_hw_info(hif_sc, &hdd_ctx->target_hw_version, 3634 &hdd_ctx->target_hw_revision, 3635 &target_hw_name); 3636 3637 qdf_mem_zero(hdd_ctx->target_hw_name, MAX_TGT_HW_NAME_LEN); 3638 3639 target_hw_name_len = strlen(target_hw_name) + 1; 3640 3641 if (target_hw_name_len <= MAX_TGT_HW_NAME_LEN) { 3642 qdf_mem_copy(hdd_ctx->target_hw_name, target_hw_name, 3643 target_hw_name_len); 3644 } else { 3645 hdd_err("target_hw_name_len is greater than MAX_TGT_HW_NAME_LEN"); 3646 return; 3647 } 3648 3649 hdd_debug("target_hw_name = %s", hdd_ctx->target_hw_name); 3650 3651 buf = qdf_mem_malloc(WE_MAX_STR_LEN); 3652 if (buf) { 3653 buf_len = hdd_wlan_get_version(hdd_ctx, WE_MAX_STR_LEN, buf); 3654 hdd_nofl_debug("%s", buf); 3655 qdf_mem_free(buf); 3656 } 3657 } 3658 3659 /** 3660 * hdd_update_cds_ac_specs_params() - update cds ac_specs params 3661 * @hdd_ctx: Pointer to hdd context 3662 * 3663 * Return: none 3664 */ 3665 static void 3666 hdd_update_cds_ac_specs_params(struct hdd_context *hdd_ctx) 3667 { 3668 uint8_t tx_sched_wrr_param[TX_SCHED_WRR_PARAMS_NUM] = {0}; 3669 qdf_size_t out_size = 0; 3670 int i; 3671 struct cds_context *cds_ctx; 3672 3673 if (!hdd_ctx) 3674 return; 3675 3676 if (!hdd_ctx->config) { 3677 /* Do nothing if hdd_ctx is invalid */ 3678 hdd_err("Warning: hdd_ctx->cfg_ini is NULL"); 3679 return; 3680 } 3681 3682 cds_ctx = cds_get_context(QDF_MODULE_ID_QDF); 3683 if (!cds_ctx) 3684 return; 3685 3686 for (i = 0; i < QCA_WLAN_AC_ALL; i++) { 3687 switch (i) { 3688 case QCA_WLAN_AC_BE: 3689 qdf_uint8_array_parse( 3690 cfg_get(hdd_ctx->psoc, 3691 CFG_DP_ENABLE_TX_SCHED_WRR_BE), 3692 tx_sched_wrr_param, 3693 sizeof(tx_sched_wrr_param), 3694 &out_size); 3695 break; 3696 case QCA_WLAN_AC_BK: 3697 qdf_uint8_array_parse( 3698 cfg_get(hdd_ctx->psoc, 3699 CFG_DP_ENABLE_TX_SCHED_WRR_BK), 3700 tx_sched_wrr_param, 3701 sizeof(tx_sched_wrr_param), 3702 &out_size); 3703 break; 3704 case QCA_WLAN_AC_VI: 3705 qdf_uint8_array_parse( 3706 cfg_get(hdd_ctx->psoc, 3707 CFG_DP_ENABLE_TX_SCHED_WRR_VI), 3708 tx_sched_wrr_param, 3709 sizeof(tx_sched_wrr_param), 3710 &out_size); 3711 break; 3712 case QCA_WLAN_AC_VO: 3713 qdf_uint8_array_parse( 3714 cfg_get(hdd_ctx->psoc, 3715 CFG_DP_ENABLE_TX_SCHED_WRR_VO), 3716 tx_sched_wrr_param, 3717 sizeof(tx_sched_wrr_param), 3718 &out_size); 3719 break; 3720 default: 3721 break; 3722 } 3723 3724 if (out_size == TX_SCHED_WRR_PARAMS_NUM) { 3725 cds_ctx->ac_specs[i].wrr_skip_weight = 3726 tx_sched_wrr_param[0]; 3727 cds_ctx->ac_specs[i].credit_threshold = 3728 tx_sched_wrr_param[1]; 3729 cds_ctx->ac_specs[i].send_limit = 3730 tx_sched_wrr_param[2]; 3731 cds_ctx->ac_specs[i].credit_reserve = 3732 tx_sched_wrr_param[3]; 3733 cds_ctx->ac_specs[i].discard_weight = 3734 tx_sched_wrr_param[4]; 3735 } 3736 3737 out_size = 0; 3738 } 3739 } 3740 3741 uint32_t hdd_wlan_get_version(struct hdd_context *hdd_ctx, 3742 const size_t version_len, uint8_t *version) 3743 { 3744 uint32_t size; 3745 uint8_t reg_major = 0, reg_minor = 0, bdf_major = 0, bdf_minor = 0; 3746 struct target_psoc_info *tgt_hdl; 3747 3748 if (!hdd_ctx) { 3749 hdd_err("Invalid context, HDD context is null"); 3750 return 0; 3751 } 3752 3753 if (!version || version_len == 0) { 3754 hdd_err("Invalid buffer pointr or buffer len\n"); 3755 return 0; 3756 } 3757 tgt_hdl = wlan_psoc_get_tgt_if_handle(hdd_ctx->psoc); 3758 if (tgt_hdl) 3759 target_psoc_get_version_info(tgt_hdl, ®_major, ®_minor, 3760 &bdf_major, &bdf_minor); 3761 3762 size = scnprintf(version, version_len, 3763 "Host SW:%s, FW:%d.%d.%d.%d.%d.%d, HW:%s, Board ver: %x Ref design id: %x, Customer id: %x, Project id: %x, Board Data Rev: %x, REG DB: %u:%u, BDF REG DB: %u:%u", 3764 QWLAN_VERSIONSTR, 3765 hdd_ctx->fw_version_info.major_spid, 3766 hdd_ctx->fw_version_info.minor_spid, 3767 hdd_ctx->fw_version_info.siid, 3768 hdd_ctx->fw_version_info.rel_id, 3769 hdd_ctx->fw_version_info.crmid, 3770 hdd_ctx->fw_version_info.sub_id, 3771 hdd_ctx->target_hw_name, 3772 hdd_ctx->hw_bd_info.bdf_version, 3773 hdd_ctx->hw_bd_info.ref_design_id, 3774 hdd_ctx->hw_bd_info.customer_id, 3775 hdd_ctx->hw_bd_info.project_id, 3776 hdd_ctx->hw_bd_info.board_data_rev, 3777 reg_major, reg_minor, bdf_major, bdf_minor); 3778 3779 return size; 3780 } 3781 3782 int hdd_set_11ax_rate(struct hdd_adapter *adapter, int set_value, 3783 struct sap_config *sap_config) 3784 { 3785 uint8_t preamble = 0, nss = 0, rix = 0; 3786 int ret; 3787 mac_handle_t mac_handle = adapter->hdd_ctx->mac_handle; 3788 3789 if (!sap_config) { 3790 if (!sme_is_feature_supported_by_fw(DOT11AX)) { 3791 hdd_err("Target does not support 11ax"); 3792 return -EIO; 3793 } 3794 } else if (sap_config->SapHw_mode != eCSR_DOT11_MODE_11ax && 3795 sap_config->SapHw_mode != eCSR_DOT11_MODE_11ax_ONLY) { 3796 hdd_err("Invalid hw mode, SAP hw_mode= 0x%x, ch_freq = %d", 3797 sap_config->SapHw_mode, sap_config->chan_freq); 3798 return -EIO; 3799 } 3800 3801 if (set_value != 0xffff) { 3802 rix = RC_2_RATE_IDX_11AX(set_value); 3803 preamble = WMI_RATE_PREAMBLE_HE; 3804 nss = HT_RC_2_STREAMS_11AX(set_value); 3805 3806 set_value = hdd_assemble_rate_code(preamble, nss, rix); 3807 } else { 3808 ret = sme_set_auto_rate_he_ltf(mac_handle, 3809 adapter->deflink->vdev_id, 3810 QCA_WLAN_HE_LTF_AUTO); 3811 } 3812 3813 hdd_info("SET_11AX_RATE val %d rix %d preamble %x nss %d", 3814 set_value, rix, preamble, nss); 3815 3816 ret = wma_cli_set_command(adapter->deflink->vdev_id, 3817 wmi_vdev_param_fixed_rate, 3818 set_value, VDEV_CMD); 3819 3820 return ret; 3821 } 3822 3823 int hdd_assemble_rate_code(uint8_t preamble, uint8_t nss, uint8_t rate) 3824 { 3825 int set_value; 3826 3827 if (sme_is_feature_supported_by_fw(DOT11AX)) 3828 set_value = WMI_ASSEMBLE_RATECODE_V1(rate, nss, preamble); 3829 else 3830 set_value = (preamble << 6) | (nss << 4) | rate; 3831 3832 return set_value; 3833 } 3834 3835 #ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH 3836 static enum policy_mgr_con_mode wlan_hdd_get_mode_for_non_connected_vdev( 3837 struct wlan_objmgr_psoc *psoc, uint8_t vdev_id) 3838 { 3839 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 3840 struct hdd_adapter *adapter; 3841 enum policy_mgr_con_mode mode; 3842 struct wlan_hdd_link_info *link_info; 3843 3844 link_info = hdd_get_link_info_by_vdev(hdd_ctx, vdev_id); 3845 if (!link_info) { 3846 hdd_err("Invalid vdev"); 3847 return PM_MAX_NUM_OF_MODE; 3848 } 3849 3850 adapter = link_info->adapter; 3851 mode = policy_mgr_qdf_opmode_to_pm_con_mode(psoc, 3852 adapter->device_mode, 3853 vdev_id); 3854 return mode; 3855 } 3856 3857 /** 3858 * hdd_is_chan_switch_in_progress() - Check if any adapter has channel switch in 3859 * progress 3860 * 3861 * Return: true, if any adapter has channel switch in 3862 * progress else false 3863 */ 3864 static bool hdd_is_chan_switch_in_progress(void) 3865 { 3866 struct hdd_adapter *adapter = NULL, *next_adapter = NULL; 3867 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 3868 wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_IS_CHAN_SWITCH_IN_PROGRESS; 3869 struct hdd_ap_ctx *ap_ctx; 3870 struct wlan_hdd_link_info *link_info; 3871 3872 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 3873 dbgid) { 3874 if (adapter->device_mode != QDF_SAP_MODE && 3875 adapter->device_mode != QDF_P2P_GO_MODE) 3876 goto next_adapter; 3877 3878 hdd_adapter_for_each_active_link_info(adapter, link_info) { 3879 ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(link_info); 3880 if (qdf_atomic_read(&ap_ctx->ch_switch_in_progress)) { 3881 hdd_debug("channel switch progress for vdev_id %d", 3882 link_info->vdev_id); 3883 hdd_adapter_dev_put_debug(adapter, dbgid); 3884 if (next_adapter) 3885 hdd_adapter_dev_put_debug(next_adapter, 3886 dbgid); 3887 return true; 3888 } 3889 } 3890 next_adapter: 3891 hdd_adapter_dev_put_debug(adapter, dbgid); 3892 } 3893 3894 return false; 3895 } 3896 3897 /** 3898 * hdd_is_cac_in_progress() - Check if any SAP connection is performing 3899 * CAC on DFS channel 3900 * 3901 * Return: true, if any of existing SAP is performing CAC 3902 * or else false 3903 */ 3904 static bool hdd_is_cac_in_progress(void) 3905 { 3906 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 3907 3908 if (!hdd_ctx) 3909 return false; 3910 3911 return (hdd_ctx->dev_dfs_cac_status == DFS_CAC_IN_PROGRESS); 3912 } 3913 3914 static void hdd_register_policy_manager_callback( 3915 struct wlan_objmgr_psoc *psoc) 3916 { 3917 struct policy_mgr_hdd_cbacks hdd_cbacks; 3918 3919 qdf_mem_zero(&hdd_cbacks, sizeof(hdd_cbacks)); 3920 hdd_cbacks.sap_restart_chan_switch_cb = 3921 hdd_sap_restart_chan_switch_cb; 3922 hdd_cbacks.wlan_hdd_get_channel_for_sap_restart = 3923 wlan_hdd_get_channel_for_sap_restart; 3924 hdd_cbacks.get_mode_for_non_connected_vdev = 3925 wlan_hdd_get_mode_for_non_connected_vdev; 3926 hdd_cbacks.hdd_get_device_mode = hdd_get_device_mode; 3927 hdd_cbacks.hdd_is_chan_switch_in_progress = 3928 hdd_is_chan_switch_in_progress; 3929 hdd_cbacks.hdd_is_cac_in_progress = 3930 hdd_is_cac_in_progress; 3931 hdd_cbacks.wlan_hdd_set_sap_csa_reason = 3932 wlan_hdd_set_sap_csa_reason; 3933 hdd_cbacks.hdd_get_ap_6ghz_capable = hdd_get_ap_6ghz_capable; 3934 hdd_cbacks.wlan_hdd_indicate_active_ndp_cnt = 3935 hdd_indicate_active_ndp_cnt; 3936 hdd_cbacks.wlan_get_ap_prefer_conc_ch_params = 3937 wlan_get_ap_prefer_conc_ch_params; 3938 hdd_cbacks.wlan_get_sap_acs_band = 3939 wlan_get_sap_acs_band; 3940 hdd_cbacks.wlan_check_cc_intf_cb = wlan_hdd_check_cc_intf_cb; 3941 3942 if (QDF_STATUS_SUCCESS != 3943 policy_mgr_register_hdd_cb(psoc, &hdd_cbacks)) { 3944 hdd_err("HDD callback registration with policy manager failed"); 3945 } 3946 } 3947 #else 3948 static void hdd_register_policy_manager_callback( 3949 struct wlan_objmgr_psoc *psoc) 3950 { 3951 } 3952 #endif 3953 3954 #ifdef WLAN_SUPPORT_GAP_LL_PS_MODE 3955 static void hdd_register_green_ap_callback(struct wlan_objmgr_pdev *pdev) 3956 { 3957 struct green_ap_hdd_callback hdd_cback; 3958 qdf_mem_zero(&hdd_cback, sizeof(hdd_cback)); 3959 3960 hdd_cback.send_event = wlan_hdd_send_green_ap_ll_ps_event; 3961 3962 if (QDF_STATUS_SUCCESS != 3963 green_ap_register_hdd_callback(pdev, &hdd_cback)) { 3964 hdd_err("HDD callback registration for Green AP failed"); 3965 } 3966 } 3967 #else 3968 static inline void hdd_register_green_ap_callback(struct wlan_objmgr_pdev *pdev) 3969 { 3970 } 3971 #endif 3972 3973 #ifdef WLAN_FEATURE_NAN 3974 #ifdef WLAN_FEATURE_SR 3975 static void hdd_register_sr_concurrency_cb(struct nan_callbacks *cb_obj) 3976 { 3977 cb_obj->nan_sr_concurrency_update = hdd_nan_sr_concurrency_update; 3978 } 3979 #else 3980 static void hdd_register_sr_concurrency_cb(struct nan_callbacks *cb_obj) 3981 {} 3982 #endif 3983 static void hdd_nan_register_callbacks(struct hdd_context *hdd_ctx) 3984 { 3985 struct nan_callbacks cb_obj = {0}; 3986 3987 cb_obj.ndi_open = hdd_ndi_open; 3988 cb_obj.ndi_close = hdd_ndi_close; 3989 cb_obj.ndi_set_mode = hdd_ndi_set_mode; 3990 cb_obj.ndi_start = hdd_ndi_start; 3991 cb_obj.ndi_delete = hdd_ndi_delete; 3992 cb_obj.drv_ndi_create_rsp_handler = hdd_ndi_drv_ndi_create_rsp_handler; 3993 cb_obj.drv_ndi_delete_rsp_handler = hdd_ndi_drv_ndi_delete_rsp_handler; 3994 3995 cb_obj.new_peer_ind = hdd_ndp_new_peer_handler; 3996 cb_obj.peer_departed_ind = hdd_ndp_peer_departed_handler; 3997 3998 cb_obj.nan_concurrency_update = hdd_nan_concurrency_update; 3999 cb_obj.set_mc_list = hdd_update_multicast_list; 4000 4001 hdd_register_sr_concurrency_cb(&cb_obj); 4002 4003 os_if_nan_register_hdd_callbacks(hdd_ctx->psoc, &cb_obj); 4004 } 4005 #else 4006 static inline void hdd_nan_register_callbacks(struct hdd_context *hdd_ctx) 4007 { 4008 } 4009 #endif 4010 4011 #ifdef CONFIG_LEAK_DETECTION 4012 /** 4013 * hdd_check_for_leaks() - Perform runtime memory leak checks 4014 * @hdd_ctx: the global HDD context 4015 * @is_ssr: true if SSR is in progress 4016 * 4017 * This API triggers runtime memory leak detection. This feature enforces the 4018 * policy that any memory allocated at runtime must also be released at runtime. 4019 * 4020 * Allocating memory at runtime and releasing it at unload is effectively a 4021 * memory leak for configurations which never unload (e.g. LONU, statically 4022 * compiled driver). Such memory leaks are NOT false positives, and must be 4023 * fixed. 4024 * 4025 * Return: None 4026 */ 4027 static void hdd_check_for_leaks(struct hdd_context *hdd_ctx, bool is_ssr) 4028 { 4029 /* DO NOT REMOVE these checks; for false positives, read above first */ 4030 4031 wlan_objmgr_psoc_check_for_leaks(hdd_ctx->psoc); 4032 4033 /* many adapter resources are not freed by design during SSR */ 4034 if (is_ssr) 4035 return; 4036 4037 qdf_wake_lock_check_for_leaks(); 4038 qdf_delayed_work_check_for_leaks(); 4039 qdf_mc_timer_check_for_leaks(); 4040 qdf_nbuf_map_check_for_leaks(); 4041 qdf_periodic_work_check_for_leaks(); 4042 qdf_mem_check_for_leaks(); 4043 } 4044 4045 /** 4046 * hdd_debug_domain_set() - Set qdf debug domain 4047 * @domain: debug domain to be set 4048 * 4049 * In the scenario of system reboot, it may have thread accessing debug domain 4050 * for memory allocation/free, other than the one trying to change it. 4051 * If debug domain is changed after a memory allocation but before the free, 4052 * it will hit debug domain mismatch assertion in memory free. 4053 * To avoid such assertion, skip debug domain transition if system reboot is 4054 * in progress. 4055 * 4056 * Return: 0 if the specified debug domain has been set, -EBUSY otherwise 4057 */ 4058 static int hdd_debug_domain_set(enum qdf_debug_domain domain) 4059 { 4060 int ret = 0; 4061 4062 if (cds_sys_reboot_protect()) { 4063 hdd_info("System is rebooting, skip debug domain transition"); 4064 ret = -EBUSY; 4065 } else { 4066 qdf_debug_domain_set(domain); 4067 } 4068 4069 cds_sys_reboot_unprotect(); 4070 4071 return ret; 4072 } 4073 4074 #define hdd_debug_domain_get() qdf_debug_domain_get() 4075 #else 4076 static void hdd_check_for_objmgr_peer_leaks(struct wlan_objmgr_psoc *psoc) 4077 { 4078 uint32_t vdev_id; 4079 struct wlan_objmgr_vdev *vdev; 4080 struct wlan_objmgr_peer *peer; 4081 4082 /* get module id which cause the leak and release ref */ 4083 wlan_objmgr_for_each_psoc_vdev(psoc, vdev_id, vdev) { 4084 wlan_vdev_obj_lock(vdev); 4085 wlan_objmgr_for_each_vdev_peer(vdev, peer) { 4086 qdf_atomic_t *ref_id_dbg; 4087 int ref_id; 4088 int32_t refs; 4089 4090 ref_id_dbg = vdev->vdev_objmgr.ref_id_dbg; 4091 wlan_objmgr_for_each_refs(ref_id_dbg, ref_id, refs) 4092 wlan_objmgr_peer_release_ref(peer, ref_id); 4093 } 4094 wlan_vdev_obj_unlock(vdev); 4095 } 4096 } 4097 4098 static void hdd_check_for_objmgr_leaks(struct hdd_context *hdd_ctx) 4099 { 4100 uint32_t vdev_id, pdev_id; 4101 struct wlan_objmgr_psoc *psoc; 4102 struct wlan_objmgr_vdev *vdev; 4103 struct wlan_objmgr_pdev *pdev; 4104 /* 4105 * leak detection is disabled, force release the references for the wlan 4106 * to recover cleanly. 4107 */ 4108 psoc = hdd_ctx->psoc; 4109 if (!psoc) 4110 return; 4111 4112 4113 hdd_check_for_objmgr_peer_leaks(psoc); 4114 4115 wlan_objmgr_for_each_psoc_vdev(psoc, vdev_id, vdev) { 4116 qdf_atomic_t *ref_id_dbg; 4117 int ref_id; 4118 int32_t refs; 4119 4120 ref_id_dbg = vdev->vdev_objmgr.ref_id_dbg; 4121 wlan_objmgr_for_each_refs(ref_id_dbg, ref_id, refs) { 4122 wlan_objmgr_vdev_release_ref(vdev, ref_id); 4123 } 4124 } 4125 4126 wlan_objmgr_for_each_psoc_pdev(psoc, pdev_id, pdev) { 4127 qdf_atomic_t *ref_id_dbg; 4128 int ref_id; 4129 int32_t refs; 4130 4131 ref_id_dbg = pdev->pdev_objmgr.ref_id_dbg; 4132 wlan_objmgr_for_each_refs(ref_id_dbg, ref_id, refs) 4133 wlan_objmgr_pdev_release_ref(pdev, ref_id); 4134 } 4135 } 4136 4137 static void hdd_check_for_leaks(struct hdd_context *hdd_ctx, bool is_ssr) 4138 { 4139 hdd_check_for_objmgr_leaks(hdd_ctx); 4140 } 4141 4142 #define hdd_debug_domain_set(domain) 0 4143 #define hdd_debug_domain_get() DEFAULT_DEBUG_DOMAIN_INIT 4144 #endif /* CONFIG_LEAK_DETECTION */ 4145 4146 #ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE 4147 /** 4148 * hdd_skip_acs_scan_timer_handler() - skip ACS scan timer timeout handler 4149 * @data: pointer to struct hdd_context 4150 * 4151 * This function will reset acs_scan_status to eSAP_DO_NEW_ACS_SCAN. 4152 * Then new ACS request will do a fresh scan without reusing the cached 4153 * scan information. 4154 * 4155 * Return: void 4156 */ 4157 static void hdd_skip_acs_scan_timer_handler(void *data) 4158 { 4159 struct hdd_context *hdd_ctx = data; 4160 mac_handle_t mac_handle; 4161 4162 hdd_debug("ACS Scan result expired. Reset ACS scan skip"); 4163 hdd_ctx->skip_acs_scan_status = eSAP_DO_NEW_ACS_SCAN; 4164 qdf_spin_lock(&hdd_ctx->acs_skip_lock); 4165 qdf_mem_free(hdd_ctx->last_acs_freq_list); 4166 hdd_ctx->last_acs_freq_list = NULL; 4167 hdd_ctx->num_of_channels = 0; 4168 qdf_spin_unlock(&hdd_ctx->acs_skip_lock); 4169 4170 mac_handle = hdd_ctx->mac_handle; 4171 if (!mac_handle) 4172 return; 4173 } 4174 4175 static void hdd_skip_acs_scan_timer_init(struct hdd_context *hdd_ctx) 4176 { 4177 QDF_STATUS status; 4178 4179 status = qdf_mc_timer_init(&hdd_ctx->skip_acs_scan_timer, 4180 QDF_TIMER_TYPE_SW, 4181 hdd_skip_acs_scan_timer_handler, 4182 hdd_ctx); 4183 if (QDF_IS_STATUS_ERROR(status)) 4184 hdd_err("Failed to init ACS Skip timer"); 4185 qdf_spinlock_create(&hdd_ctx->acs_skip_lock); 4186 } 4187 4188 static void hdd_skip_acs_scan_timer_deinit(struct hdd_context *hdd_ctx) 4189 { 4190 if (QDF_TIMER_STATE_RUNNING == 4191 qdf_mc_timer_get_current_state(&hdd_ctx->skip_acs_scan_timer)) { 4192 qdf_mc_timer_stop(&hdd_ctx->skip_acs_scan_timer); 4193 } 4194 4195 if (!QDF_IS_STATUS_SUCCESS 4196 (qdf_mc_timer_destroy(&hdd_ctx->skip_acs_scan_timer))) { 4197 hdd_err("Cannot deallocate ACS Skip timer"); 4198 } 4199 qdf_spin_lock(&hdd_ctx->acs_skip_lock); 4200 qdf_mem_free(hdd_ctx->last_acs_freq_list); 4201 hdd_ctx->last_acs_freq_list = NULL; 4202 hdd_ctx->num_of_channels = 0; 4203 qdf_spin_unlock(&hdd_ctx->acs_skip_lock); 4204 } 4205 #else 4206 static void hdd_skip_acs_scan_timer_init(struct hdd_context *hdd_ctx) {} 4207 static void hdd_skip_acs_scan_timer_deinit(struct hdd_context *hdd_ctx) {} 4208 #endif 4209 4210 /** 4211 * hdd_update_country_code - Update country code 4212 * @hdd_ctx: HDD context 4213 * 4214 * Update country code based on module parameter country_code 4215 * 4216 * Return: 0 on success and errno on failure 4217 */ 4218 int hdd_update_country_code(struct hdd_context *hdd_ctx) 4219 { 4220 if (!country_code || 4221 !ucfg_reg_is_user_country_set_allowed(hdd_ctx->psoc)) 4222 return 0; 4223 4224 return hdd_reg_set_country(hdd_ctx, country_code); 4225 } 4226 4227 #ifdef WLAN_NS_OFFLOAD 4228 /** 4229 * hdd_wlan_unregister_ip6_notifier() - unregister IPv6 change notifier 4230 * @hdd_ctx: Pointer to hdd context 4231 * 4232 * Unregister for IPv6 address change notifications. 4233 * 4234 * Return: None 4235 */ 4236 static void hdd_wlan_unregister_ip6_notifier(struct hdd_context *hdd_ctx) 4237 { 4238 unregister_inet6addr_notifier(&hdd_ctx->ipv6_notifier); 4239 } 4240 4241 /** 4242 * hdd_wlan_register_ip6_notifier() - register IPv6 change notifier 4243 * @hdd_ctx: Pointer to hdd context 4244 * 4245 * Register for IPv6 address change notifications. 4246 * 4247 * Return: 0 on success and errno on failure. 4248 */ 4249 static int hdd_wlan_register_ip6_notifier(struct hdd_context *hdd_ctx) 4250 { 4251 int ret; 4252 4253 hdd_ctx->ipv6_notifier.notifier_call = wlan_hdd_ipv6_changed; 4254 ret = register_inet6addr_notifier(&hdd_ctx->ipv6_notifier); 4255 if (ret) { 4256 hdd_err("Failed to register IPv6 notifier: %d", ret); 4257 goto out; 4258 } 4259 4260 hdd_debug("Registered IPv6 notifier"); 4261 out: 4262 return ret; 4263 } 4264 #else 4265 /** 4266 * hdd_wlan_unregister_ip6_notifier() - unregister IPv6 change notifier 4267 * @hdd_ctx: Pointer to hdd context 4268 * 4269 * Unregister for IPv6 address change notifications. 4270 * 4271 * Return: None 4272 */ 4273 static void hdd_wlan_unregister_ip6_notifier(struct hdd_context *hdd_ctx) 4274 { 4275 } 4276 4277 /** 4278 * hdd_wlan_register_ip6_notifier() - register IPv6 change notifier 4279 * @hdd_ctx: Pointer to hdd context 4280 * 4281 * Register for IPv6 address change notifications. 4282 * 4283 * Return: None 4284 */ 4285 static int hdd_wlan_register_ip6_notifier(struct hdd_context *hdd_ctx) 4286 { 4287 return 0; 4288 } 4289 #endif 4290 4291 #ifdef FEATURE_RUNTIME_PM 4292 #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 7, 0) 4293 static int hdd_pm_qos_add_notifier(struct hdd_context *hdd_ctx) 4294 { 4295 return dev_pm_qos_add_notifier(hdd_ctx->parent_dev, 4296 &hdd_ctx->pm_qos_notifier, 4297 DEV_PM_QOS_RESUME_LATENCY); 4298 } 4299 4300 static int hdd_pm_qos_remove_notifier(struct hdd_context *hdd_ctx) 4301 { 4302 return dev_pm_qos_remove_notifier(hdd_ctx->parent_dev, 4303 &hdd_ctx->pm_qos_notifier, 4304 DEV_PM_QOS_RESUME_LATENCY); 4305 } 4306 #else 4307 static int hdd_pm_qos_add_notifier(struct hdd_context *hdd_ctx) 4308 { 4309 return pm_qos_add_notifier(PM_QOS_CPU_DMA_LATENCY, 4310 &hdd_ctx->pm_qos_notifier); 4311 } 4312 4313 static int hdd_pm_qos_remove_notifier(struct hdd_context *hdd_ctx) 4314 { 4315 return pm_qos_remove_notifier(PM_QOS_CPU_DMA_LATENCY, 4316 &hdd_ctx->pm_qos_notifier); 4317 } 4318 #endif 4319 4320 /** 4321 * hdd_wlan_register_pm_qos_notifier() - register PM QOS notifier 4322 * @hdd_ctx: Pointer to hdd context 4323 * 4324 * Register for PM QOS change notifications. 4325 * 4326 * Return: None 4327 */ 4328 static int hdd_wlan_register_pm_qos_notifier(struct hdd_context *hdd_ctx) 4329 { 4330 int ret; 4331 4332 qdf_spinlock_create(&hdd_ctx->pm_qos_lock); 4333 4334 /* if gRuntimePM is 1 then feature is enabled without CXPC */ 4335 if (hdd_ctx->config->runtime_pm != hdd_runtime_pm_dynamic) { 4336 hdd_debug("Dynamic Runtime PM disabled"); 4337 return 0; 4338 } 4339 4340 hdd_ctx->pm_qos_notifier.notifier_call = wlan_hdd_pm_qos_notify; 4341 ret = hdd_pm_qos_add_notifier(hdd_ctx); 4342 if (ret) 4343 hdd_err("Failed to register PM_QOS notifier: %d", ret); 4344 else 4345 hdd_debug("PM QOS Notifier registered"); 4346 4347 return ret; 4348 } 4349 4350 /** 4351 * hdd_wlan_unregister_pm_qos_notifier() - unregister PM QOS notifier 4352 * @hdd_ctx: Pointer to hdd context 4353 * 4354 * Unregister for PM QOS change notifications. 4355 * 4356 * Return: None 4357 */ 4358 static void hdd_wlan_unregister_pm_qos_notifier(struct hdd_context *hdd_ctx) 4359 { 4360 int ret; 4361 4362 if (hdd_ctx->config->runtime_pm != hdd_runtime_pm_dynamic) { 4363 hdd_debug("Dynamic Runtime PM disabled"); 4364 qdf_spinlock_destroy(&hdd_ctx->pm_qos_lock); 4365 return; 4366 } 4367 4368 ret = hdd_pm_qos_remove_notifier(hdd_ctx); 4369 if (ret) 4370 hdd_warn("Failed to remove qos notifier, err = %d\n", ret); 4371 4372 qdf_spin_lock_irqsave(&hdd_ctx->pm_qos_lock); 4373 4374 if (hdd_ctx->runtime_pm_prevented) { 4375 hif_rtpm_put(HIF_RTPM_PUT_NOIDLE, HIF_RTPM_ID_PM_QOS_NOTIFY); 4376 hdd_ctx->runtime_pm_prevented = false; 4377 } 4378 4379 qdf_spin_unlock_irqrestore(&hdd_ctx->pm_qos_lock); 4380 4381 qdf_spinlock_destroy(&hdd_ctx->pm_qos_lock); 4382 } 4383 #else 4384 static int hdd_wlan_register_pm_qos_notifier(struct hdd_context *hdd_ctx) 4385 { 4386 return 0; 4387 } 4388 4389 static void hdd_wlan_unregister_pm_qos_notifier(struct hdd_context *hdd_ctx) 4390 { 4391 } 4392 #endif 4393 4394 /** 4395 * hdd_enable_power_management() - API to Enable Power Management 4396 * @hdd_ctx: HDD context 4397 * 4398 * API invokes Bus Interface Layer power management functionality 4399 * 4400 * Return: None 4401 */ 4402 static void hdd_enable_power_management(struct hdd_context *hdd_ctx) 4403 { 4404 void *hif_ctx = cds_get_context(QDF_MODULE_ID_HIF); 4405 4406 if (!hif_ctx) 4407 return; 4408 4409 hif_enable_power_management(hif_ctx, cds_is_packet_log_enabled()); 4410 hdd_wlan_register_pm_qos_notifier(hdd_ctx); 4411 } 4412 4413 /** 4414 * hdd_disable_power_management() - API to disable Power Management 4415 * @hdd_ctx: HDD context 4416 * 4417 * API disable Bus Interface Layer Power management functionality 4418 * 4419 * Return: None 4420 */ 4421 static void hdd_disable_power_management(struct hdd_context *hdd_ctx) 4422 { 4423 void *hif_ctx = cds_get_context(QDF_MODULE_ID_HIF); 4424 4425 if (!hif_ctx) 4426 return; 4427 4428 hdd_wlan_unregister_pm_qos_notifier(hdd_ctx); 4429 hif_disable_power_management(hif_ctx); 4430 } 4431 4432 /** 4433 * hdd_register_notifiers - Register netdev notifiers. 4434 * @hdd_ctx: HDD context 4435 * 4436 * Register netdev notifiers like IPv4 and IPv6. 4437 * 4438 * Return: 0 on success and errno on failure 4439 */ 4440 static int hdd_register_notifiers(struct hdd_context *hdd_ctx) 4441 { 4442 int ret; 4443 4444 ret = hdd_wlan_register_ip6_notifier(hdd_ctx); 4445 if (ret) 4446 goto out; 4447 4448 hdd_ctx->ipv4_notifier.notifier_call = wlan_hdd_ipv4_changed; 4449 ret = register_inetaddr_notifier(&hdd_ctx->ipv4_notifier); 4450 if (ret) { 4451 hdd_err("Failed to register IPv4 notifier: %d", ret); 4452 goto unregister_ip6_notifier; 4453 } 4454 4455 ret = osif_dp_nud_register_netevent_notifier(hdd_ctx->psoc); 4456 if (ret) { 4457 hdd_err("Failed to register netevent notifier: %d", 4458 ret); 4459 goto unregister_inetaddr_notifier; 4460 } 4461 4462 return 0; 4463 4464 unregister_inetaddr_notifier: 4465 unregister_inetaddr_notifier(&hdd_ctx->ipv4_notifier); 4466 unregister_ip6_notifier: 4467 hdd_wlan_unregister_ip6_notifier(hdd_ctx); 4468 out: 4469 return ret; 4470 } 4471 4472 #ifdef WLAN_FEATURE_WMI_SEND_RECV_QMI 4473 static inline 4474 void hdd_set_qmi_stats_enabled(struct hdd_context *hdd_ctx) 4475 { 4476 wmi_unified_t wmi_handle = get_wmi_unified_hdl_from_psoc(hdd_ctx->psoc); 4477 4478 if (!wmi_handle) { 4479 hdd_err("could not get wmi handle"); 4480 return; 4481 } 4482 4483 wmi_set_qmi_stats(wmi_handle, hdd_ctx->config->is_qmi_stats_enabled); 4484 } 4485 #else 4486 static inline 4487 void hdd_set_qmi_stats_enabled(struct hdd_context *hdd_ctx) 4488 { 4489 } 4490 #endif 4491 4492 #ifdef CONFIG_FW_LOGS_BASED_ON_INI 4493 /** 4494 * hdd_set_fw_log_params() - Set log parameters to FW 4495 * @hdd_ctx: HDD Context 4496 * @vdev_id: vdev_id 4497 * 4498 * This function set the FW Debug log level based on the INI. 4499 * 4500 * Return: None 4501 */ 4502 static void hdd_set_fw_log_params(struct hdd_context *hdd_ctx, 4503 uint8_t vdev_id) 4504 { 4505 QDF_STATUS status; 4506 uint16_t enable_fw_log_level, enable_fw_log_type; 4507 int ret; 4508 4509 if (!hdd_ctx->config->enable_fw_log) { 4510 hdd_debug("enable_fw_log not enabled in INI"); 4511 return; 4512 } 4513 4514 /* Enable FW logs based on INI configuration */ 4515 status = ucfg_fwol_get_enable_fw_log_type(hdd_ctx->psoc, 4516 &enable_fw_log_type); 4517 if (QDF_IS_STATUS_ERROR(status)) 4518 return; 4519 ret = sme_cli_set_command(vdev_id, WMI_DBGLOG_TYPE, 4520 enable_fw_log_type, DBG_CMD); 4521 if (ret != 0) 4522 hdd_err("Failed to enable FW log type ret %d", ret); 4523 4524 status = ucfg_fwol_get_enable_fw_log_level(hdd_ctx->psoc, 4525 &enable_fw_log_level); 4526 if (QDF_IS_STATUS_ERROR(status)) 4527 return; 4528 ret = sme_cli_set_command(vdev_id, WMI_DBGLOG_LOG_LEVEL, 4529 enable_fw_log_level, DBG_CMD); 4530 if (ret != 0) 4531 hdd_err("Failed to enable FW log level ret %d", ret); 4532 4533 sme_enable_fw_module_log_level(hdd_ctx->mac_handle, vdev_id); 4534 } 4535 #else 4536 static void hdd_set_fw_log_params(struct hdd_context *hdd_ctx, uint8_t vdev_id) 4537 { 4538 } 4539 4540 #endif 4541 4542 /** 4543 * hdd_features_deinit() - Deinit features 4544 * @hdd_ctx: HDD context 4545 * 4546 * De-Initialize features and their feature context. 4547 * 4548 * Return: none. 4549 */ 4550 static void hdd_features_deinit(struct hdd_context *hdd_ctx) 4551 { 4552 wlan_hdd_gpio_wakeup_deinit(hdd_ctx); 4553 wlan_hdd_twt_deinit(hdd_ctx); 4554 wlan_hdd_deinit_chan_info(hdd_ctx); 4555 wlan_hdd_tsf_deinit(hdd_ctx); 4556 if (cds_is_packet_log_enabled()) 4557 hdd_pktlog_enable_disable(hdd_ctx, false, 0, 0); 4558 } 4559 4560 /** 4561 * hdd_deconfigure_cds() -De-Configure cds 4562 * @hdd_ctx: HDD context 4563 * 4564 * Deconfigure Cds modules before WLAN firmware is down. 4565 * 4566 * Return: 0 on success and errno on failure. 4567 */ 4568 static int hdd_deconfigure_cds(struct hdd_context *hdd_ctx) 4569 { 4570 QDF_STATUS qdf_status; 4571 int ret = 0; 4572 4573 hdd_enter(); 4574 4575 wlan_hdd_hang_event_notifier_unregister(); 4576 /* De-init features */ 4577 hdd_features_deinit(hdd_ctx); 4578 4579 qdf_status = policy_mgr_deregister_mode_change_cb(hdd_ctx->psoc); 4580 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) 4581 hdd_debug("Failed to deregister mode change cb with Policy Manager"); 4582 4583 qdf_status = cds_disable(hdd_ctx->psoc); 4584 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { 4585 hdd_err("Failed to Disable the CDS Modules! :%d", 4586 qdf_status); 4587 ret = -EINVAL; 4588 } 4589 4590 if (ucfg_ipa_uc_ol_deinit(hdd_ctx->pdev) != QDF_STATUS_SUCCESS) { 4591 hdd_err("Failed to disconnect pipes"); 4592 ret = -EINVAL; 4593 } 4594 4595 hdd_exit(); 4596 return ret; 4597 } 4598 4599 /** 4600 * hdd_qmi_register_callbacks() - Register QMI callbacks 4601 * @hdd_ctx: HDD context 4602 * 4603 * Return: None 4604 */ 4605 static inline void hdd_qmi_register_callbacks(struct hdd_context *hdd_ctx) 4606 { 4607 struct wlan_qmi_psoc_callbacks cb_obj; 4608 4609 os_if_qmi_register_callbacks(hdd_ctx->psoc, &cb_obj); 4610 } 4611 4612 /** 4613 * hdd_set_pcie_params() - Set pcie params 4614 * @hdd_ctx: HDD context 4615 * @index: index value 4616 * @param: pointer to vdev/pdev set param info 4617 * 4618 * Checks for pcie_config value and sets 4619 * corresponding params 4620 * 4621 * Return: 0 on success and errno on failure. 4622 */ 4623 static int hdd_set_pcie_params(struct hdd_context *hdd_ctx, 4624 uint8_t index, struct dev_set_param *param) 4625 { 4626 int ret = 0; 4627 uint8_t check_value = 0; 4628 4629 ret = ucfg_fwol_get_pcie_config(hdd_ctx->psoc, &check_value); 4630 if (QDF_IS_STATUS_SUCCESS(ret)) { 4631 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) { 4632 ret = mlme_check_index_setparam(param, 4633 wmi_pdev_param_pcie_config, 4634 (int)check_value, index++, 4635 FTM_MAX_PDEV_PARAMS); 4636 } else { 4637 ret = mlme_check_index_setparam(param, 4638 wmi_pdev_param_pcie_config, 4639 (int)check_value, index++, 4640 MAX_PDEV_PRE_ENABLE_PARAMS); 4641 } 4642 if (QDF_IS_STATUS_ERROR(ret)) { 4643 hdd_err("failed to set wmi_pdev_param_pcie_config"); 4644 return ret; 4645 } 4646 } 4647 return ret; 4648 } 4649 4650 #ifdef FEATURE_SET 4651 #ifdef WLAN_FEATURE_11BE 4652 /** 4653 * hdd_is_cfg_dot11_mode_11be() - Check if dot11 mode is 11 be 4654 * @dot11_mode: Input dot11_mode which needs to be checked 4655 * 4656 * Return: True, ifinput dot11_mode is 11be dot11 mode else return false 4657 */ 4658 static bool hdd_is_cfg_dot11_mode_11be(enum hdd_dot11_mode dot11_mode) 4659 { 4660 return (dot11_mode == eHDD_DOT11_MODE_11be || 4661 dot11_mode == eHDD_DOT11_MODE_11be_ONLY); 4662 } 4663 4664 /** 4665 * hdd_is_11be_supported() - Check if 11be is supported or not 4666 * @hdd_ctx: Pointer to hdd context 4667 * 4668 * Return: True, if 11be is supported else return false 4669 */ 4670 static bool hdd_is_11be_supported(struct hdd_context *hdd_ctx) 4671 { 4672 bool mlo_capab; 4673 4674 ucfg_psoc_mlme_get_11be_capab(hdd_ctx->psoc, &mlo_capab); 4675 if (!mlo_capab) 4676 return false; 4677 4678 return true; 4679 } 4680 #else 4681 4682 static bool hdd_is_cfg_dot11_mode_11be(enum hdd_dot11_mode dot11_mode) 4683 { 4684 return false; 4685 } 4686 4687 static bool hdd_is_11be_supported(struct hdd_context *hdd_ctx) 4688 { 4689 return false; 4690 } 4691 #endif 4692 4693 WMI_HOST_WIFI_STANDARD 4694 hdd_get_wifi_standard(struct hdd_context *hdd_ctx, 4695 enum hdd_dot11_mode dot11_mode, uint32_t band_capability) 4696 { 4697 WMI_HOST_WIFI_STANDARD wifi_standard = WMI_HOST_WIFI_STANDARD_4; 4698 4699 if (dot11_mode == eHDD_DOT11_MODE_AUTO) { 4700 if (hdd_is_11be_supported(hdd_ctx)) 4701 wifi_standard = WMI_HOST_WIFI_STANDARD_7; 4702 else if (band_capability & BIT(REG_BAND_6G)) 4703 wifi_standard = WMI_HOST_WIFI_STANDARD_6E; 4704 else 4705 wifi_standard = WMI_HOST_WIFI_STANDARD_6; 4706 } else if (hdd_is_cfg_dot11_mode_11be(dot11_mode)) { 4707 wifi_standard = WMI_HOST_WIFI_STANDARD_7; 4708 } else if (dot11_mode == eHDD_DOT11_MODE_11ax || 4709 (dot11_mode == eHDD_DOT11_MODE_11ax_ONLY)) { 4710 if (band_capability & BIT(REG_BAND_6G)) 4711 wifi_standard = WMI_HOST_WIFI_STANDARD_6E; 4712 else 4713 wifi_standard = WMI_HOST_WIFI_STANDARD_6; 4714 } else if ((dot11_mode == eHDD_DOT11_MODE_11ac) || 4715 (dot11_mode == eHDD_DOT11_MODE_11ac_ONLY)) { 4716 wifi_standard = WMI_HOST_WIFI_STANDARD_5; 4717 } 4718 4719 return wifi_standard; 4720 } 4721 4722 /** 4723 * hdd_populate_feature_set_cds_config() - Populate cds feature set config 4724 * @hdd_ctx: hdd context pointer 4725 * 4726 * Return: None 4727 */ 4728 static void hdd_populate_feature_set_cds_config(struct hdd_context *hdd_ctx) 4729 { 4730 struct wlan_objmgr_psoc *psoc; 4731 uint32_t band_capability; 4732 QDF_STATUS status; 4733 struct cds_config_info *cds_cfg; 4734 4735 if (!hdd_ctx) 4736 return; 4737 4738 cds_cfg = cds_get_ini_config(); 4739 if (!cds_cfg) { 4740 hdd_err("CDS config is null."); 4741 return; 4742 } 4743 4744 psoc = hdd_ctx->psoc; 4745 4746 cds_cfg->get_wifi_features = hdd_ctx->config->get_wifi_features; 4747 4748 status = ucfg_mlme_get_band_capability(hdd_ctx->psoc, &band_capability); 4749 if (QDF_IS_STATUS_ERROR(status)) 4750 hdd_err("Failed to get MLME band capability"); 4751 4752 band_capability = 4753 hdd_update_band_cap_from_dot11mode(hdd_ctx, band_capability); 4754 4755 cds_cfg->cds_feature_set.wifi_standard = 4756 hdd_get_wifi_standard(hdd_ctx, 4757 hdd_ctx->config->dot11Mode, 4758 band_capability); 4759 4760 cds_cfg->cds_feature_set.sap_5g_supported = 4761 band_capability & BIT(REG_BAND_5G); 4762 4763 cds_cfg->cds_feature_set.sap_6g_supported = 4764 band_capability & BIT(REG_BAND_6G); 4765 cds_cfg->cds_feature_set.band_capability = band_capability; 4766 } 4767 #else 4768 WMI_HOST_WIFI_STANDARD 4769 hdd_get_wifi_standard(struct hdd_context *hdd_ctx, 4770 enum hdd_dot11_mode dot11_mode, uint32_t band_capability) 4771 { 4772 return WMI_HOST_WIFI_STANDARD_5; 4773 } 4774 4775 static inline void 4776 hdd_populate_feature_set_cds_config(struct hdd_context *hdd_ctx) 4777 { 4778 } 4779 #endif 4780 4781 int hdd_wlan_start_modules(struct hdd_context *hdd_ctx, bool reinit) 4782 { 4783 int ret = 0; 4784 qdf_device_t qdf_dev; 4785 QDF_STATUS status; 4786 bool unint = false; 4787 void *hif_ctx; 4788 struct target_psoc_info *tgt_hdl; 4789 unsigned long thermal_state = 0; 4790 uint8_t index = 0; 4791 struct dev_set_param setparam[MAX_PDEV_PRE_ENABLE_PARAMS] = {}; 4792 4793 hdd_enter(); 4794 qdf_dev = cds_get_context(QDF_MODULE_ID_QDF_DEVICE); 4795 if (!qdf_dev) { 4796 hdd_exit(); 4797 return -EINVAL; 4798 } 4799 4800 hdd_psoc_idle_timer_stop(hdd_ctx); 4801 4802 if (hdd_ctx->driver_status == DRIVER_MODULES_ENABLED) { 4803 hdd_debug("Driver modules already Enabled"); 4804 hdd_exit(); 4805 return 0; 4806 } 4807 4808 cds_set_driver_state_module_stop(false); 4809 4810 switch (hdd_ctx->driver_status) { 4811 case DRIVER_MODULES_UNINITIALIZED: 4812 hdd_nofl_debug("Wlan transitioning (UNINITIALIZED -> CLOSED)"); 4813 unint = true; 4814 fallthrough; 4815 case DRIVER_MODULES_CLOSED: 4816 hdd_nofl_debug("Wlan transitioning (CLOSED -> ENABLED)"); 4817 ret = hdd_debug_domain_set(QDF_DEBUG_DOMAIN_ACTIVE); 4818 if (ret) 4819 goto abort; 4820 4821 if (!reinit && !unint) { 4822 ret = pld_power_on(qdf_dev->dev); 4823 if (ret) { 4824 hdd_err("Failed to power up device; errno:%d", 4825 ret); 4826 goto release_lock; 4827 } 4828 } 4829 4830 hdd_init_adapter_ops_wq(hdd_ctx); 4831 pld_set_fw_log_mode(hdd_ctx->parent_dev, 4832 hdd_ctx->config->enable_fw_log); 4833 ret = hdd_hif_open(qdf_dev->dev, qdf_dev->drv_hdl, qdf_dev->bid, 4834 qdf_dev->bus_type, 4835 (reinit == true) ? HIF_ENABLE_TYPE_REINIT : 4836 HIF_ENABLE_TYPE_PROBE); 4837 if (ret) { 4838 hdd_err("Failed to open hif; errno: %d", ret); 4839 goto power_down; 4840 } 4841 4842 hif_ctx = cds_get_context(QDF_MODULE_ID_HIF); 4843 if (!hif_ctx) { 4844 ret = -EINVAL; 4845 goto power_down; 4846 } 4847 4848 status = ol_cds_init(qdf_dev, hif_ctx); 4849 if (status != QDF_STATUS_SUCCESS) { 4850 hdd_err("No Memory to Create BMI Context; status: %d", 4851 status); 4852 ret = qdf_status_to_os_return(status); 4853 goto hif_close; 4854 } 4855 4856 if (hdd_get_conparam() == QDF_GLOBAL_EPPING_MODE) { 4857 status = epping_open(); 4858 if (status) { 4859 hdd_err("Failed to open in epping mode: %d", 4860 status); 4861 ret = -EINVAL; 4862 goto cds_free; 4863 } 4864 4865 status = epping_enable(qdf_dev->dev, false); 4866 if (status) { 4867 hdd_err("Failed to enable in epping mode : %d", 4868 status); 4869 epping_close(); 4870 goto cds_free; 4871 } 4872 4873 hdd_info("epping mode enabled"); 4874 break; 4875 } 4876 4877 if (pld_is_ipa_offload_disabled(qdf_dev->dev)) 4878 ucfg_ipa_set_pld_enable(false); 4879 4880 ucfg_ipa_component_config_update(hdd_ctx->psoc); 4881 4882 hdd_update_cds_ac_specs_params(hdd_ctx); 4883 4884 hdd_dp_register_callbacks(hdd_ctx); 4885 4886 hdd_qmi_register_callbacks(hdd_ctx); 4887 4888 status = hdd_component_psoc_open(hdd_ctx->psoc); 4889 if (QDF_IS_STATUS_ERROR(status)) { 4890 hdd_err("Failed to Open legacy components; status: %d", 4891 status); 4892 ret = qdf_status_to_os_return(status); 4893 goto ipa_component_free; 4894 } 4895 4896 ret = hdd_update_config(hdd_ctx); 4897 if (ret) { 4898 hdd_err("Failed to update configuration; errno: %d", 4899 ret); 4900 goto ipa_component_free; 4901 } 4902 4903 status = wbuff_module_init(); 4904 if (QDF_IS_STATUS_ERROR(status)) 4905 hdd_err("WBUFF init unsuccessful; status: %d", status); 4906 4907 status = cds_open(hdd_ctx->psoc); 4908 if (QDF_IS_STATUS_ERROR(status)) { 4909 hdd_err("Failed to Open CDS; status: %d", status); 4910 ret = qdf_status_to_os_return(status); 4911 goto psoc_close; 4912 } 4913 4914 hdd_populate_feature_set_cds_config(hdd_ctx); 4915 4916 hdd_set_qmi_stats_enabled(hdd_ctx); 4917 4918 hdd_ctx->mac_handle = cds_get_context(QDF_MODULE_ID_SME); 4919 4920 ucfg_dp_set_rx_thread_affinity(hdd_ctx->psoc); 4921 4922 /* initialize components configurations after psoc open */ 4923 ret = hdd_update_components_config(hdd_ctx); 4924 if (ret) { 4925 hdd_err("Failed to update component configs; errno: %d", 4926 ret); 4927 goto close; 4928 } 4929 4930 /* Override PS params for monitor mode */ 4931 if (hdd_get_conparam() == QDF_GLOBAL_MONITOR_MODE) 4932 hdd_override_all_ps(hdd_ctx); 4933 4934 status = cds_dp_open(hdd_ctx->psoc); 4935 if (!QDF_IS_STATUS_SUCCESS(status)) { 4936 hdd_err("Failed to Open cds post open; status: %d", 4937 status); 4938 ret = qdf_status_to_os_return(status); 4939 goto close; 4940 } 4941 /* Set IRQ affinity for WLAN DP and CE IRQS */ 4942 hif_config_irq_set_perf_affinity_hint(hif_ctx); 4943 4944 ret = hdd_register_cb(hdd_ctx); 4945 if (ret) { 4946 hdd_err("Failed to register HDD callbacks!"); 4947 goto cds_txrx_free; 4948 } 4949 4950 ret = hdd_register_notifiers(hdd_ctx); 4951 if (ret) 4952 goto deregister_cb; 4953 4954 /* 4955 * NAN component requires certain operations like, open adapter, 4956 * close adapter, etc. to be initiated by HDD, for those 4957 * register HDD callbacks with UMAC's NAN component. 4958 */ 4959 hdd_nan_register_callbacks(hdd_ctx); 4960 4961 hdd_son_register_callbacks(hdd_ctx); 4962 4963 hdd_sr_register_callbacks(hdd_ctx); 4964 4965 wlan_hdd_register_btc_chain_mode_handler(hdd_ctx->psoc); 4966 4967 wlan_hdd_register_afc_pld_cb(hdd_ctx->psoc); 4968 4969 status = cds_pre_enable(); 4970 if (!QDF_IS_STATUS_SUCCESS(status)) { 4971 hdd_err("Failed to pre-enable CDS; status: %d", status); 4972 ret = qdf_status_to_os_return(status); 4973 goto unregister_notifiers; 4974 } 4975 4976 hdd_register_policy_manager_callback( 4977 hdd_ctx->psoc); 4978 4979 /* 4980 * Call this function before hdd_enable_power_management. Since 4981 * it is required to trigger WMI_PDEV_DMA_RING_CFG_REQ_CMDID 4982 * to FW when power save isn't enable. 4983 */ 4984 hdd_spectral_register_to_dbr(hdd_ctx); 4985 4986 hdd_create_sysfs_files(hdd_ctx); 4987 hdd_update_hw_sw_info(hdd_ctx); 4988 4989 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) { 4990 hdd_enable_power_management(hdd_ctx); 4991 hdd_err("in ftm mode, no need to configure cds modules"); 4992 hdd_info("Enable FW log in ftm mode"); 4993 /* 4994 * Since vdev is not created for FTM mode, 4995 * in FW use vdev_id = 0. 4996 */ 4997 hdd_set_fw_log_params(hdd_ctx, 0); 4998 ret = hdd_set_pcie_params(hdd_ctx, index, setparam); 4999 if (QDF_IS_STATUS_ERROR(ret)) 5000 break; 5001 index++; 5002 ret = sme_send_multi_pdev_vdev_set_params( 5003 MLME_PDEV_SETPARAM, 5004 WMI_PDEV_ID_SOC, setparam, index); 5005 if (QDF_IS_STATUS_ERROR(ret)) { 5006 hdd_err("failed to send pdev set params"); 5007 return ret; 5008 } 5009 5010 ret = -EINVAL; 5011 break; 5012 } 5013 5014 ret = hdd_configure_cds(hdd_ctx); 5015 if (ret) { 5016 hdd_err("Failed to Enable cds modules; errno: %d", ret); 5017 goto sched_disable; 5018 } 5019 5020 if (hdd_get_conparam() == QDF_GLOBAL_MISSION_MODE) { 5021 status = ucfg_dp_direct_link_init(hdd_ctx->psoc); 5022 if (QDF_IS_STATUS_ERROR(status)) { 5023 cds_err("Failed to initialize Direct Link datapath"); 5024 ret = -EINVAL; 5025 goto deconfigure_cds; 5026 } 5027 } 5028 5029 hdd_enable_power_management(hdd_ctx); 5030 5031 hdd_skip_acs_scan_timer_init(hdd_ctx); 5032 5033 hdd_set_hif_init_phase(hif_ctx, false); 5034 hdd_hif_set_enable_detection(hif_ctx, true); 5035 5036 wlan_hdd_start_connectivity_logging(hdd_ctx); 5037 5038 break; 5039 5040 default: 5041 QDF_DEBUG_PANIC("Unknown driver state:%d", 5042 hdd_ctx->driver_status); 5043 ret = -EINVAL; 5044 goto release_lock; 5045 } 5046 5047 hdd_ctx->driver_status = DRIVER_MODULES_ENABLED; 5048 hdd_nofl_debug("Wlan transitioned (now ENABLED)"); 5049 5050 ucfg_ipa_reg_is_driver_unloading_cb(hdd_ctx->pdev, 5051 cds_is_driver_unloading); 5052 ucfg_ipa_reg_sap_xmit_cb(hdd_ctx->pdev, 5053 hdd_softap_ipa_start_xmit); 5054 ucfg_ipa_reg_send_to_nw_cb(hdd_ctx->pdev, 5055 hdd_ipa_send_nbuf_to_network); 5056 ucfg_dp_reg_ipa_rsp_ind(hdd_ctx->pdev); 5057 5058 if (!pld_get_thermal_state(hdd_ctx->parent_dev, &thermal_state, 5059 THERMAL_MONITOR_APPS)) { 5060 if (thermal_state > QCA_WLAN_VENDOR_THERMAL_LEVEL_NONE) 5061 hdd_send_thermal_mitigation_val(hdd_ctx, 5062 thermal_state, 5063 THERMAL_MONITOR_APPS); 5064 } 5065 5066 if (!pld_get_thermal_state(hdd_ctx->parent_dev, &thermal_state, 5067 THERMAL_MONITOR_WPSS)) { 5068 if (thermal_state > QCA_WLAN_VENDOR_THERMAL_LEVEL_NONE) 5069 hdd_send_thermal_mitigation_val(hdd_ctx, thermal_state, 5070 THERMAL_MONITOR_WPSS); 5071 } 5072 5073 hdd_exit(); 5074 5075 return 0; 5076 5077 deconfigure_cds: 5078 hdd_deconfigure_cds(hdd_ctx); 5079 sched_disable: 5080 /* 5081 * Disable scheduler 1st so that scheduler thread doesn't send messages 5082 * to fw in parallel to the cleanup 5083 */ 5084 dispatcher_disable(); 5085 hdd_destroy_sysfs_files(); 5086 cds_post_disable(); 5087 unregister_notifiers: 5088 hdd_unregister_notifiers(hdd_ctx); 5089 5090 deregister_cb: 5091 hdd_deregister_cb(hdd_ctx); 5092 5093 cds_txrx_free: 5094 5095 tgt_hdl = wlan_psoc_get_tgt_if_handle(hdd_ctx->psoc); 5096 5097 if (tgt_hdl && target_psoc_get_wmi_ready(tgt_hdl)) 5098 hdd_runtime_suspend_context_deinit(hdd_ctx); 5099 5100 if (hdd_ctx->pdev) { 5101 dispatcher_pdev_close(hdd_ctx->pdev); 5102 hdd_objmgr_release_and_destroy_pdev(hdd_ctx); 5103 } 5104 5105 cds_dp_close(hdd_ctx->psoc); 5106 5107 close: 5108 dispatcher_disable(); 5109 hdd_ctx->driver_status = DRIVER_MODULES_CLOSED; 5110 hdd_info("Wlan transition aborted (now CLOSED)"); 5111 5112 cds_close(hdd_ctx->psoc); 5113 5114 psoc_close: 5115 hdd_component_psoc_close(hdd_ctx->psoc); 5116 wlan_global_lmac_if_close(hdd_ctx->psoc); 5117 cds_deinit_ini_config(); 5118 5119 ipa_component_free: 5120 ucfg_ipa_component_config_free(); 5121 5122 cds_free: 5123 ol_cds_free(); 5124 5125 hif_close: 5126 hif_ctx = cds_get_context(QDF_MODULE_ID_HIF); 5127 hdd_hif_close(hdd_ctx, hif_ctx); 5128 power_down: 5129 hdd_deinit_adapter_ops_wq(hdd_ctx); 5130 if (!reinit && !unint) 5131 pld_power_off(qdf_dev->dev); 5132 release_lock: 5133 cds_shutdown_notifier_purge(); 5134 hdd_check_for_leaks(hdd_ctx, reinit); 5135 hdd_debug_domain_set(QDF_DEBUG_DOMAIN_INIT); 5136 5137 abort: 5138 cds_set_driver_state_module_stop(true); 5139 5140 hdd_exit(); 5141 5142 return ret; 5143 } 5144 5145 #ifdef WIFI_POS_CONVERGED 5146 static int hdd_activate_wifi_pos(struct hdd_context *hdd_ctx) 5147 { 5148 int ret = os_if_wifi_pos_register_nl(); 5149 5150 if (ret) 5151 hdd_err("os_if_wifi_pos_register_nl failed"); 5152 5153 return ret; 5154 } 5155 5156 static int hdd_deactivate_wifi_pos(void) 5157 { 5158 int ret = os_if_wifi_pos_deregister_nl(); 5159 5160 if (ret) 5161 hdd_err("os_if_wifi_pos_deregister_nl failed"); 5162 5163 return ret; 5164 } 5165 5166 /** 5167 * hdd_populate_wifi_pos_cfg - populates wifi_pos parameters 5168 * @hdd_ctx: hdd context 5169 * 5170 * Return: status of operation 5171 */ 5172 static void hdd_populate_wifi_pos_cfg(struct hdd_context *hdd_ctx) 5173 { 5174 struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc; 5175 uint16_t neighbor_scan_max_chan_time; 5176 uint16_t neighbor_scan_min_chan_time; 5177 5178 wifi_pos_set_oem_target_type(psoc, hdd_ctx->target_type); 5179 wifi_pos_set_oem_fw_version(psoc, hdd_ctx->target_fw_version); 5180 wifi_pos_set_drv_ver_major(psoc, QWLAN_VERSION_MAJOR); 5181 wifi_pos_set_drv_ver_minor(psoc, QWLAN_VERSION_MINOR); 5182 wifi_pos_set_drv_ver_patch(psoc, QWLAN_VERSION_PATCH); 5183 wifi_pos_set_drv_ver_build(psoc, QWLAN_VERSION_BUILD); 5184 ucfg_mlme_get_neighbor_scan_max_chan_time(psoc, 5185 &neighbor_scan_max_chan_time); 5186 ucfg_mlme_get_neighbor_scan_min_chan_time(psoc, 5187 &neighbor_scan_min_chan_time); 5188 wifi_pos_set_dwell_time_min(psoc, neighbor_scan_min_chan_time); 5189 wifi_pos_set_dwell_time_max(psoc, neighbor_scan_max_chan_time); 5190 } 5191 #else 5192 static int hdd_activate_wifi_pos(struct hdd_context *hdd_ctx) 5193 { 5194 return oem_activate_service(hdd_ctx); 5195 } 5196 5197 static int hdd_deactivate_wifi_pos(void) 5198 { 5199 return oem_deactivate_service(); 5200 } 5201 5202 static void hdd_populate_wifi_pos_cfg(struct hdd_context *hdd_ctx) 5203 { 5204 } 5205 #endif 5206 5207 /** 5208 * __hdd_open() - HDD Open function 5209 * @dev: Pointer to net_device structure 5210 * 5211 * This is called in response to ifconfig up 5212 * 5213 * Return: 0 for success; non-zero for failure 5214 */ 5215 static int __hdd_open(struct net_device *dev) 5216 { 5217 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev); 5218 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); 5219 int ret; 5220 struct wlan_hdd_link_info *link_info = adapter->deflink; 5221 5222 hdd_enter_dev(dev); 5223 5224 qdf_mtrace(QDF_MODULE_ID_HDD, QDF_MODULE_ID_HDD, 5225 TRACE_CODE_HDD_OPEN_REQUEST, 5226 link_info->vdev_id, adapter->device_mode); 5227 5228 /* Nothing to be done if device is unloading */ 5229 if (cds_is_driver_unloading()) { 5230 hdd_err("Driver is unloading can not open the hdd"); 5231 return -EBUSY; 5232 } 5233 5234 if (cds_is_driver_recovering()) { 5235 hdd_err("WLAN is currently recovering; Please try again."); 5236 return -EBUSY; 5237 } 5238 5239 /* 5240 * This scenario can be hit in cases where in the wlan driver after 5241 * registering the netdevices and there is a failure in driver 5242 * initialization. So return error gracefully because the netdevices 5243 * will be de-registered as part of the load failure. 5244 */ 5245 5246 if (!cds_is_driver_loaded()) { 5247 hdd_err("Failed to start the wlan driver!!"); 5248 return -EIO; 5249 } 5250 5251 ret = wlan_hdd_validate_context(hdd_ctx); 5252 if (ret) { 5253 hdd_err("Can't start WLAN module, WiFi Disabled"); 5254 return ret; 5255 } 5256 5257 ret = hdd_trigger_psoc_idle_restart(hdd_ctx); 5258 if (ret) { 5259 hdd_err("Failed to start WLAN modules return"); 5260 return ret; 5261 } 5262 5263 if (!test_bit(SME_SESSION_OPENED, &link_info->link_flags)) { 5264 ret = hdd_start_adapter(adapter, true); 5265 if (ret) { 5266 hdd_err("Failed to start adapter :%d", 5267 adapter->device_mode); 5268 return ret; 5269 } 5270 } 5271 5272 set_bit(DEVICE_IFACE_OPENED, &adapter->event_flags); 5273 if (hdd_cm_is_vdev_associated(link_info)) { 5274 hdd_debug("Enabling Tx Queues"); 5275 /* Enable TX queues only when we are connected */ 5276 wlan_hdd_netif_queue_control(adapter, 5277 WLAN_START_ALL_NETIF_QUEUE, 5278 WLAN_CONTROL_PATH); 5279 } 5280 5281 /* Enable carrier and transmit queues for NDI */ 5282 if (WLAN_HDD_IS_NDI(adapter)) { 5283 hdd_debug("Enabling Tx Queues"); 5284 wlan_hdd_netif_queue_control(adapter, 5285 WLAN_START_ALL_NETIF_QUEUE_N_CARRIER, 5286 WLAN_CONTROL_PATH); 5287 } 5288 5289 hdd_populate_wifi_pos_cfg(hdd_ctx); 5290 hdd_lpass_notify_start(link_info); 5291 5292 if (ucfg_pkt_capture_get_mode(hdd_ctx->psoc) != 5293 PACKET_CAPTURE_MODE_DISABLE) 5294 hdd_map_monitor_interface_vdev(adapter); 5295 5296 return 0; 5297 } 5298 5299 /** 5300 * hdd_open() - Wrapper function for __hdd_open to protect it from SSR 5301 * @net_dev: Pointer to net_device structure 5302 * 5303 * This is called in response to ifconfig up 5304 * 5305 * Return: 0 for success; non-zero for failure 5306 */ 5307 static int hdd_open(struct net_device *net_dev) 5308 { 5309 int errno; 5310 struct osif_vdev_sync *vdev_sync; 5311 5312 errno = osif_vdev_sync_trans_start(net_dev, &vdev_sync); 5313 if (errno) 5314 return errno; 5315 5316 errno = __hdd_open(net_dev); 5317 if (!errno) 5318 osif_vdev_cache_command(vdev_sync, NO_COMMAND); 5319 5320 osif_vdev_sync_trans_stop(vdev_sync); 5321 5322 return errno; 5323 } 5324 5325 int hdd_stop_no_trans(struct net_device *dev) 5326 { 5327 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev); 5328 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); 5329 int ret; 5330 mac_handle_t mac_handle; 5331 5332 hdd_enter_dev(dev); 5333 5334 qdf_mtrace(QDF_MODULE_ID_HDD, QDF_MODULE_ID_HDD, 5335 TRACE_CODE_HDD_STOP_REQUEST, 5336 adapter->deflink->vdev_id, adapter->device_mode); 5337 5338 ret = wlan_hdd_validate_context(hdd_ctx); 5339 if (ret) 5340 return ret; 5341 5342 /* Nothing to be done if the interface is not opened */ 5343 if (false == test_bit(DEVICE_IFACE_OPENED, &adapter->event_flags)) { 5344 hdd_err("NETDEV Interface is not OPENED"); 5345 return -ENODEV; 5346 } 5347 5348 mac_handle = hdd_ctx->mac_handle; 5349 5350 if (!wlan_hdd_is_session_type_monitor(adapter->device_mode) && 5351 adapter->device_mode != QDF_FTM_MODE) { 5352 hdd_debug("Disabling Auto Power save timer"); 5353 sme_ps_disable_auto_ps_timer( 5354 mac_handle, 5355 adapter->deflink->vdev_id); 5356 } 5357 5358 /* 5359 * Disable TX on the interface, after this hard_start_xmit() will not 5360 * be called on that interface 5361 */ 5362 hdd_debug("Disabling queues, adapter device mode: %s(%d)", 5363 qdf_opmode_str(adapter->device_mode), adapter->device_mode); 5364 5365 wlan_hdd_netif_queue_control(adapter, 5366 WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER, 5367 WLAN_CONTROL_PATH); 5368 5369 if (adapter->device_mode == QDF_STA_MODE) 5370 hdd_lpass_notify_stop(hdd_ctx); 5371 5372 /* 5373 * NAN data interface is different in some sense. The traffic on NDI is 5374 * bursty in nature and depends on the need to transfer. The service 5375 * layer may down the interface after the usage and up again when 5376 * required. In some sense, the NDI is expected to be available 5377 * (like SAP) iface until NDI delete request is issued by the service 5378 * layer. Skip BSS termination and adapter deletion for NAN Data 5379 * interface (NDI). 5380 */ 5381 if (WLAN_HDD_IS_NDI(adapter)) 5382 goto reset_iface_opened; 5383 5384 /* 5385 * The interface is marked as down for outside world (aka kernel) 5386 * But the driver is pretty much alive inside. The driver needs to 5387 * tear down the existing connection on the netdev (session) 5388 * cleanup the data pipes and wait until the control plane is stabilized 5389 * for this interface. The call also needs to wait until the above 5390 * mentioned actions are completed before returning to the caller. 5391 * Notice that hdd_stop_adapter is requested not to close the session 5392 * That is intentional to be able to scan if it is a STA/P2P interface 5393 */ 5394 hdd_stop_adapter(hdd_ctx, adapter); 5395 5396 /* DeInit the adapter. This ensures datapath cleanup as well */ 5397 hdd_deinit_adapter(hdd_ctx, adapter, true); 5398 5399 reset_iface_opened: 5400 /* Make sure the interface is marked as closed */ 5401 clear_bit(DEVICE_IFACE_OPENED, &adapter->event_flags); 5402 if (!hdd_is_any_interface_open(hdd_ctx)) 5403 hdd_psoc_idle_timer_start(hdd_ctx); 5404 hdd_exit(); 5405 5406 return 0; 5407 } 5408 5409 /** 5410 * hdd_stop() - Wrapper function for __hdd_stop to protect it from SSR 5411 * @net_dev: pointer to net_device structure 5412 * 5413 * This is called in response to ifconfig down 5414 * 5415 * Return: 0 for success and error number for failure 5416 */ 5417 static int hdd_stop(struct net_device *net_dev) 5418 { 5419 int errno; 5420 struct osif_vdev_sync *vdev_sync; 5421 5422 errno = osif_vdev_sync_trans_start(net_dev, &vdev_sync); 5423 if (errno) { 5424 if (vdev_sync) 5425 osif_vdev_cache_command(vdev_sync, INTERFACE_DOWN); 5426 return errno; 5427 } 5428 5429 errno = hdd_stop_no_trans(net_dev); 5430 5431 osif_vdev_sync_trans_stop(vdev_sync); 5432 5433 return errno; 5434 } 5435 5436 /** 5437 * hdd_uninit() - HDD uninit function 5438 * @dev: Pointer to net_device structure 5439 * 5440 * This is called during the netdev unregister to uninitialize all data 5441 * associated with the device 5442 * 5443 * This function must be protected by a transition 5444 * 5445 * Return: None 5446 */ 5447 static void hdd_uninit(struct net_device *dev) 5448 { 5449 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev); 5450 struct hdd_context *hdd_ctx; 5451 5452 hdd_enter_dev(dev); 5453 5454 if (adapter->magic != WLAN_HDD_ADAPTER_MAGIC) { 5455 hdd_err("Invalid magic"); 5456 goto exit; 5457 } 5458 5459 hdd_ctx = WLAN_HDD_GET_CTX(adapter); 5460 if (!hdd_ctx) { 5461 hdd_err("NULL hdd_ctx"); 5462 goto exit; 5463 } 5464 5465 if (dev != adapter->dev) 5466 hdd_err("Invalid device reference"); 5467 5468 hdd_deinit_adapter(hdd_ctx, adapter, true); 5469 5470 /* after uninit our adapter structure will no longer be valid */ 5471 adapter->magic = 0; 5472 5473 exit: 5474 hdd_exit(); 5475 } 5476 5477 static int hdd_open_cesium_nl_sock(void) 5478 { 5479 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0)) 5480 struct netlink_kernel_cfg cfg = { 5481 .groups = WLAN_NLINK_MCAST_GRP_ID, 5482 .input = NULL 5483 }; 5484 #endif 5485 int ret = 0; 5486 5487 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0)) 5488 cesium_nl_srv_sock = netlink_kernel_create(&init_net, WLAN_NLINK_CESIUM, 5489 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 7, 0)) 5490 THIS_MODULE, 5491 #endif 5492 &cfg); 5493 #else 5494 cesium_nl_srv_sock = netlink_kernel_create(&init_net, WLAN_NLINK_CESIUM, 5495 WLAN_NLINK_MCAST_GRP_ID, 5496 NULL, NULL, THIS_MODULE); 5497 #endif 5498 5499 if (!cesium_nl_srv_sock) { 5500 hdd_err("NLINK: cesium netlink_kernel_create failed"); 5501 ret = -ECONNREFUSED; 5502 } 5503 5504 return ret; 5505 } 5506 5507 static void hdd_close_cesium_nl_sock(void) 5508 { 5509 if (cesium_nl_srv_sock) { 5510 netlink_kernel_release(cesium_nl_srv_sock); 5511 cesium_nl_srv_sock = NULL; 5512 } 5513 } 5514 5515 void hdd_update_dynamic_mac(struct hdd_context *hdd_ctx, 5516 struct qdf_mac_addr *curr_mac_addr, 5517 struct qdf_mac_addr *new_mac_addr) 5518 { 5519 uint8_t i; 5520 5521 hdd_enter(); 5522 5523 for (i = 0; i < QDF_MAX_CONCURRENCY_PERSONA; i++) { 5524 if (!qdf_mem_cmp( 5525 curr_mac_addr->bytes, 5526 &hdd_ctx->dynamic_mac_list[i].dynamic_mac.bytes[0], 5527 sizeof(struct qdf_mac_addr))) { 5528 qdf_mem_copy(&hdd_ctx->dynamic_mac_list[i].dynamic_mac, 5529 new_mac_addr->bytes, 5530 sizeof(struct qdf_mac_addr)); 5531 break; 5532 } 5533 } 5534 5535 hdd_exit(); 5536 } 5537 5538 #if defined(WLAN_FEATURE_11BE_MLO) && defined(CFG80211_11BE_BASIC) && \ 5539 !defined(WLAN_HDD_MULTI_VDEV_SINGLE_NDEV) 5540 void hdd_set_mld_address(struct hdd_adapter *adapter, 5541 const struct qdf_mac_addr *mac_addr) 5542 { 5543 int i; 5544 bool eht_capab; 5545 struct hdd_adapter *link_adapter; 5546 struct hdd_mlo_adapter_info *mlo_adapter_info; 5547 5548 ucfg_psoc_mlme_get_11be_capab(adapter->hdd_ctx->psoc, &eht_capab); 5549 if (adapter->mlo_adapter_info.is_ml_adapter && eht_capab) { 5550 mlo_adapter_info = &adapter->mlo_adapter_info; 5551 for (i = 0; i < WLAN_MAX_MLD; i++) { 5552 link_adapter = mlo_adapter_info->link_adapter[i]; 5553 if (link_adapter) 5554 qdf_copy_macaddr(&link_adapter->mld_addr, 5555 mac_addr); 5556 } 5557 qdf_copy_macaddr(&adapter->mld_addr, mac_addr); 5558 } 5559 } 5560 5561 /** 5562 * hdd_get_netdev_by_vdev_mac() - Get Netdev based on MAC 5563 * @mac_addr: Vdev MAC address 5564 * 5565 * Get netdev from adapter based upon Vdev MAC address. 5566 * 5567 * Return: netdev pointer. 5568 */ 5569 static qdf_netdev_t 5570 hdd_get_netdev_by_vdev_mac(struct qdf_mac_addr *mac_addr) 5571 { 5572 struct hdd_context *hdd_ctx; 5573 struct hdd_adapter *adapter; 5574 struct hdd_adapter *ml_adapter; 5575 5576 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 5577 if (!hdd_ctx) { 5578 hdd_err("Invalid HDD context"); 5579 return NULL; 5580 } 5581 5582 adapter = hdd_get_adapter_by_macaddr(hdd_ctx, mac_addr->bytes); 5583 if (!adapter) { 5584 hdd_err("Adapter not foud for MAC " QDF_MAC_ADDR_FMT "", 5585 QDF_MAC_ADDR_REF(mac_addr->bytes)); 5586 return NULL; 5587 } 5588 5589 if (adapter->mlo_adapter_info.is_link_adapter && 5590 adapter->mlo_adapter_info.associate_with_ml_adapter) { 5591 ml_adapter = adapter->mlo_adapter_info.ml_adapter; 5592 adapter = ml_adapter; 5593 } 5594 5595 return adapter->dev; 5596 } 5597 #else 5598 static qdf_netdev_t 5599 hdd_get_netdev_by_vdev_mac(struct qdf_mac_addr *mac_addr) 5600 { 5601 struct hdd_context *hdd_ctx; 5602 struct hdd_adapter *adapter; 5603 5604 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 5605 if (!hdd_ctx) { 5606 hdd_err("Invalid HDD context"); 5607 return NULL; 5608 } 5609 5610 adapter = hdd_get_adapter_by_macaddr(hdd_ctx, mac_addr->bytes); 5611 if (!adapter) { 5612 hdd_err("Adapter not foud for MAC " QDF_MAC_ADDR_FMT "", 5613 QDF_MAC_ADDR_REF(mac_addr->bytes)); 5614 return NULL; 5615 } 5616 5617 return adapter->dev; 5618 } 5619 #endif 5620 5621 #ifdef WLAN_FEATURE_DYNAMIC_MAC_ADDR_UPDATE 5622 #if defined(WLAN_FEATURE_11BE_MLO) && defined(CFG80211_11BE_BASIC) && \ 5623 !defined(WLAN_HDD_MULTI_VDEV_SINGLE_NDEV) 5624 static void hdd_update_set_mac_addr_req_ctx(struct hdd_adapter *adapter, 5625 void *req_ctx) 5626 { 5627 adapter->set_mac_addr_req_ctx = req_ctx; 5628 if (adapter->mlo_adapter_info.associate_with_ml_adapter) 5629 adapter->mlo_adapter_info.ml_adapter->set_mac_addr_req_ctx = 5630 req_ctx; 5631 } 5632 #else 5633 static void hdd_update_set_mac_addr_req_ctx(struct hdd_adapter *adapter, 5634 void *req_ctx) 5635 { 5636 adapter->set_mac_addr_req_ctx = req_ctx; 5637 } 5638 #endif 5639 5640 /** 5641 * hdd_is_dynamic_set_mac_addr_supported() - API to check dynamic MAC address 5642 * update is supported or not 5643 * @hdd_ctx: Pointer to the HDD context 5644 * 5645 * Return: true or false 5646 */ 5647 static inline bool 5648 hdd_is_dynamic_set_mac_addr_supported(struct hdd_context *hdd_ctx) 5649 { 5650 return hdd_ctx->is_vdev_macaddr_dynamic_update_supported; 5651 } 5652 5653 bool hdd_is_dynamic_set_mac_addr_allowed(struct hdd_adapter *adapter) 5654 { 5655 if (!adapter->deflink->vdev) { 5656 hdd_err("VDEV is NULL"); 5657 return false; 5658 } 5659 5660 if (!hdd_is_dynamic_set_mac_addr_supported(adapter->hdd_ctx)) { 5661 hdd_info_rl("On iface up, set mac address change isn't supported"); 5662 return false; 5663 } 5664 5665 switch (adapter->device_mode) { 5666 case QDF_STA_MODE: 5667 if (!cm_is_vdev_disconnected(adapter->deflink->vdev)) { 5668 hdd_info_rl("VDEV is not in disconnected state, set mac address isn't supported"); 5669 return false; 5670 } 5671 return true; 5672 case QDF_SAP_MODE: 5673 if (test_bit(SOFTAP_BSS_STARTED, 5674 &adapter->deflink->link_flags)) { 5675 hdd_info_rl("SAP is in up state, set mac address isn't supported"); 5676 return false; 5677 } else { 5678 return true; 5679 } 5680 default: 5681 hdd_info_rl("Dynamic set mac address isn't supported for opmode:%d", 5682 adapter->device_mode); 5683 return false; 5684 } 5685 } 5686 5687 int hdd_dynamic_mac_address_set(struct wlan_hdd_link_info *link_info, 5688 struct qdf_mac_addr mac_addr, 5689 struct qdf_mac_addr mld_addr, 5690 bool update_self_peer) 5691 { 5692 int ret; 5693 void *cookie; 5694 bool update_mld_addr; 5695 uint32_t *fw_resp_status; 5696 QDF_STATUS status; 5697 struct osif_request *request; 5698 struct wlan_objmgr_vdev *vdev; 5699 struct hdd_adapter *adapter = link_info->adapter; 5700 struct hdd_context *hdd_ctx = adapter->hdd_ctx; 5701 static const struct osif_request_params params = { 5702 .priv_size = sizeof(*fw_resp_status), 5703 .timeout_ms = WLAN_SET_MAC_ADDR_TIMEOUT 5704 }; 5705 5706 vdev = hdd_objmgr_get_vdev_by_user(link_info, WLAN_OSIF_ID); 5707 if (!vdev) 5708 return -EINVAL; 5709 5710 status = ucfg_vdev_mgr_cdp_vdev_detach(vdev); 5711 if (QDF_IS_STATUS_ERROR(status)) { 5712 hdd_err("Failed to detach CDP vdev. Status:%d", status); 5713 ret = qdf_status_to_os_return(status); 5714 goto vdev_ref; 5715 } 5716 5717 request = osif_request_alloc(¶ms); 5718 if (!request) { 5719 ret = -ENOMEM; 5720 goto status_ret; 5721 } 5722 5723 /* Host should hold a wake lock until the FW event response is received 5724 * the WMI event would not be a wake up event. 5725 */ 5726 qdf_runtime_pm_prevent_suspend( 5727 &hdd_ctx->runtime_context.dyn_mac_addr_update); 5728 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_DYN_MAC_ADDR_UPDATE); 5729 5730 cookie = osif_request_cookie(request); 5731 hdd_update_set_mac_addr_req_ctx(adapter, cookie); 5732 5733 status = sme_send_set_mac_addr(mac_addr, mld_addr, vdev); 5734 ret = qdf_status_to_os_return(status); 5735 if (QDF_IS_STATUS_ERROR(status)) { 5736 hdd_nofl_err("Failed to send set MAC address command. Status:%d", 5737 status); 5738 osif_request_put(request); 5739 goto status_ret; 5740 } else { 5741 ret = osif_request_wait_for_response(request); 5742 if (ret) { 5743 hdd_err("Set MAC address response timed out"); 5744 } else { 5745 fw_resp_status = (uint32_t *)osif_request_priv(request); 5746 if (*fw_resp_status) { 5747 hdd_err("Set MAC address failed in FW. Status: %d", 5748 *fw_resp_status); 5749 ret = -EAGAIN; 5750 } 5751 } 5752 } 5753 5754 osif_request_put(request); 5755 5756 if (qdf_is_macaddr_zero(&mld_addr)) 5757 update_mld_addr = false; 5758 else 5759 update_mld_addr = true; 5760 5761 status = sme_update_vdev_mac_addr(vdev, mac_addr, mld_addr, 5762 update_self_peer, update_mld_addr, 5763 ret); 5764 5765 if (QDF_IS_STATUS_ERROR(status)) 5766 ret = qdf_status_to_os_return(status); 5767 5768 status_ret: 5769 status = ucfg_vdev_mgr_cdp_vdev_attach(vdev); 5770 if (QDF_IS_STATUS_ERROR(status)) { 5771 hdd_err("Failed to attach CDP vdev. status:%d", status); 5772 ret = qdf_status_to_os_return(status); 5773 goto allow_suspend; 5774 } else if (!ret) { 5775 status = ucfg_dp_update_link_mac_addr(vdev, &mac_addr, false); 5776 if (QDF_IS_STATUS_ERROR(status)) { 5777 ret = qdf_status_to_os_return(status); 5778 hdd_err("DP link MAC update failed"); 5779 goto allow_suspend; 5780 } 5781 } 5782 sme_vdev_set_data_tx_callback(vdev); 5783 5784 /* Update FW WoW pattern with new MAC address */ 5785 ucfg_pmo_del_wow_pattern(vdev); 5786 ucfg_pmo_register_wow_default_patterns(vdev); 5787 5788 allow_suspend: 5789 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DYN_MAC_ADDR_UPDATE); 5790 qdf_runtime_pm_allow_suspend( 5791 &hdd_ctx->runtime_context.dyn_mac_addr_update); 5792 5793 vdev_ref: 5794 hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_ID); 5795 5796 return ret; 5797 } 5798 5799 static void hdd_set_mac_addr_event_cb(uint8_t vdev_id, uint8_t status) 5800 { 5801 struct hdd_context *hdd_ctx; 5802 struct wlan_hdd_link_info *link_info; 5803 struct osif_request *req; 5804 uint32_t *fw_response_status; 5805 5806 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 5807 if (!hdd_ctx) { 5808 hdd_err("Invalid HDD context"); 5809 return; 5810 } 5811 5812 link_info = hdd_get_link_info_by_vdev(hdd_ctx, vdev_id); 5813 if (!link_info) { 5814 hdd_err("No adapter found for VDEV ID:%d", vdev_id); 5815 return; 5816 } 5817 5818 req = osif_request_get(link_info->adapter->set_mac_addr_req_ctx); 5819 if (!req) { 5820 osif_err("Obsolete request for VDEV ID:%d", vdev_id); 5821 return; 5822 } 5823 5824 fw_response_status = (uint32_t *)osif_request_priv(req); 5825 *fw_response_status = status; 5826 5827 osif_request_complete(req); 5828 osif_request_put(req); 5829 } 5830 #else 5831 static inline bool 5832 hdd_is_dynamic_set_mac_addr_supported(struct hdd_context *hdd_ctx) 5833 { 5834 return false; 5835 } 5836 #endif 5837 5838 #if defined(WLAN_FEATURE_11BE_MLO) && defined(WLAN_HDD_MULTI_VDEV_SINGLE_NDEV) 5839 static QDF_STATUS 5840 hdd_adapter_update_links_on_link_switch(struct wlan_hdd_link_info *cur_link_info, 5841 struct wlan_hdd_link_info *new_link_info) 5842 { 5843 unsigned long link_flags; 5844 struct wlan_objmgr_vdev *vdev; 5845 int cur_link_idx, new_link_idx; 5846 uint8_t cur_old_pos, cur_new_pos; 5847 struct vdev_osif_priv *vdev_priv; 5848 struct hdd_adapter *adapter = cur_link_info->adapter; 5849 5850 /* Update the new position of current and new link info 5851 * in the link info array. 5852 */ 5853 cur_link_idx = hdd_adapter_get_index_of_link_info(cur_link_info); 5854 new_link_idx = hdd_adapter_get_index_of_link_info(new_link_info); 5855 5856 cur_old_pos = adapter->curr_link_info_map[cur_link_idx]; 5857 cur_new_pos = adapter->curr_link_info_map[new_link_idx]; 5858 5859 adapter->curr_link_info_map[new_link_idx] = cur_old_pos; 5860 adapter->curr_link_info_map[cur_link_idx] = cur_new_pos; 5861 5862 /* Move VDEV from current link info to new link info */ 5863 qdf_atomic_clear_bit(cur_link_idx, &adapter->active_links); 5864 qdf_spin_lock_bh(&cur_link_info->vdev_lock); 5865 vdev = cur_link_info->vdev; 5866 cur_link_info->vdev = NULL; 5867 cur_link_info->vdev_id = WLAN_INVALID_VDEV_ID; 5868 qdf_spin_unlock_bh(&cur_link_info->vdev_lock); 5869 5870 qdf_spin_lock_bh(&new_link_info->vdev_lock); 5871 new_link_info->vdev = vdev; 5872 new_link_info->vdev_id = wlan_vdev_get_id(vdev); 5873 qdf_spin_unlock_bh(&new_link_info->vdev_lock); 5874 qdf_atomic_set_bit(new_link_idx, &adapter->active_links); 5875 5876 /* Move the link flags between current and new link info */ 5877 link_flags = new_link_info->link_flags; 5878 new_link_info->link_flags = cur_link_info->link_flags; 5879 cur_link_info->link_flags = link_flags; 5880 5881 /* Update VDEV-OSIF priv pointer to new link info */ 5882 vdev_priv = wlan_vdev_get_ospriv(new_link_info->vdev); 5883 vdev_priv->legacy_osif_priv = new_link_info; 5884 5885 return QDF_STATUS_SUCCESS; 5886 } 5887 5888 struct wlan_hdd_link_info * 5889 hdd_get_link_info_by_ieee_link_id(struct hdd_adapter *adapter, int32_t link_id) 5890 { 5891 struct wlan_hdd_link_info *link_info; 5892 struct hdd_station_ctx *sta_ctx; 5893 5894 if (!adapter || link_id == WLAN_INVALID_LINK_ID) { 5895 hdd_err("NULL adapter or invalid link ID"); 5896 return NULL; 5897 } 5898 5899 hdd_adapter_for_each_link_info(adapter, link_info) { 5900 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(link_info); 5901 if (sta_ctx->conn_info.ieee_link_id == link_id) 5902 return link_info; 5903 } 5904 5905 return NULL; 5906 } 5907 5908 QDF_STATUS 5909 hdd_link_switch_vdev_mac_addr_update(int32_t ieee_old_link_id, 5910 int32_t ieee_new_link_id, uint8_t vdev_id) 5911 { 5912 QDF_STATUS status = QDF_STATUS_E_INVAL; 5913 struct hdd_context *hdd_ctx; 5914 struct hdd_adapter *adapter; 5915 struct wlan_objmgr_vdev *vdev; 5916 struct wlan_hdd_link_info *cur_link_info, *new_link_info; 5917 struct hdd_station_ctx *sta_ctx; 5918 5919 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 5920 if (!hdd_ctx) { 5921 hdd_err("HDD ctx NULL"); 5922 return QDF_STATUS_E_INVAL; 5923 } 5924 5925 cur_link_info = hdd_get_link_info_by_vdev(hdd_ctx, vdev_id); 5926 if (!cur_link_info) { 5927 hdd_err("VDEV %d not found", vdev_id); 5928 return status; 5929 } 5930 5931 vdev = hdd_objmgr_get_vdev_by_user(cur_link_info, WLAN_OSIF_ID); 5932 if (!vdev) { 5933 hdd_err("Invalid VDEV %d", vdev_id); 5934 return status; 5935 } 5936 5937 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(cur_link_info); 5938 if (sta_ctx->conn_info.ieee_link_id != ieee_old_link_id) { 5939 hdd_err("Link id %d mismatch", sta_ctx->conn_info.ieee_link_id); 5940 goto release_ref; 5941 } 5942 5943 adapter = cur_link_info->adapter; 5944 new_link_info = hdd_get_link_info_by_ieee_link_id(adapter, 5945 ieee_new_link_id); 5946 if (!new_link_info) { 5947 hdd_err("Link id %d not found", ieee_new_link_id); 5948 goto release_ref; 5949 } 5950 5951 status = ucfg_dp_update_link_mac_addr(vdev, &new_link_info->link_addr, 5952 true); 5953 if (QDF_IS_STATUS_ERROR(status)) { 5954 hdd_err("DP link MAC update failed"); 5955 goto release_ref; 5956 } 5957 5958 status = hdd_adapter_update_links_on_link_switch(cur_link_info, 5959 new_link_info); 5960 if (QDF_IS_STATUS_ERROR(status)) { 5961 hdd_err("Failed to update adapter link info"); 5962 goto release_ref; 5963 } 5964 5965 hdd_adapter_update_mlo_mgr_mac_addr(adapter); 5966 sme_vdev_set_data_tx_callback(vdev); 5967 ucfg_pmo_del_wow_pattern(vdev); 5968 ucfg_pmo_register_wow_default_patterns(vdev); 5969 5970 release_ref: 5971 hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_ID); 5972 return status; 5973 } 5974 #endif 5975 5976 /** 5977 * __hdd_set_mac_address() - set the user specified mac address 5978 * @dev: Pointer to the net device. 5979 * @addr: Pointer to the sockaddr. 5980 * 5981 * This function sets the user specified mac address using 5982 * the command ifconfig wlanX hw ether <mac address>. 5983 * 5984 * Return: 0 for success, non zero for failure 5985 */ 5986 static int __hdd_set_mac_address(struct net_device *dev, void *addr) 5987 { 5988 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev); 5989 struct hdd_adapter *adapter_temp; 5990 struct hdd_context *hdd_ctx; 5991 struct sockaddr *psta_mac_addr = addr; 5992 QDF_STATUS qdf_ret_status = QDF_STATUS_SUCCESS; 5993 int ret; 5994 struct qdf_mac_addr mac_addr; 5995 bool net_if_running = netif_running(dev); 5996 5997 hdd_enter_dev(dev); 5998 5999 hdd_ctx = WLAN_HDD_GET_CTX(adapter); 6000 ret = wlan_hdd_validate_context(hdd_ctx); 6001 if (0 != ret) 6002 return ret; 6003 6004 if (net_if_running) { 6005 if (!hdd_is_dynamic_set_mac_addr_allowed(adapter)) 6006 return -ENOTSUPP; 6007 } 6008 6009 qdf_mem_copy(&mac_addr, psta_mac_addr->sa_data, sizeof(mac_addr)); 6010 adapter_temp = hdd_get_adapter_by_macaddr(hdd_ctx, mac_addr.bytes); 6011 if (adapter_temp) { 6012 if (!qdf_str_cmp(adapter_temp->dev->name, dev->name)) 6013 return 0; 6014 hdd_err("%s adapter exist with same address " QDF_MAC_ADDR_FMT, 6015 adapter_temp->dev->name, 6016 QDF_MAC_ADDR_REF(mac_addr.bytes)); 6017 return -EINVAL; 6018 } 6019 qdf_ret_status = wlan_hdd_validate_mac_address(&mac_addr); 6020 if (QDF_IS_STATUS_ERROR(qdf_ret_status)) 6021 return -EINVAL; 6022 6023 hdd_nofl_debug("Changing MAC to " 6024 QDF_MAC_ADDR_FMT " of the interface %s ", 6025 QDF_MAC_ADDR_REF(mac_addr.bytes), dev->name); 6026 6027 if (net_if_running && adapter->deflink->vdev) { 6028 ret = hdd_update_vdev_mac_address(adapter, mac_addr); 6029 if (ret) 6030 return ret; 6031 } 6032 6033 hdd_set_mld_address(adapter, &mac_addr); 6034 6035 hdd_update_dynamic_mac(hdd_ctx, &adapter->mac_addr, &mac_addr); 6036 ucfg_dp_update_intf_mac(hdd_ctx->psoc, &adapter->mac_addr, &mac_addr, 6037 adapter->deflink->vdev); 6038 memcpy(&adapter->mac_addr, psta_mac_addr->sa_data, ETH_ALEN); 6039 qdf_net_update_net_device_dev_addr(dev, psta_mac_addr->sa_data, 6040 ETH_ALEN); 6041 6042 hdd_exit(); 6043 return ret; 6044 } 6045 6046 /** 6047 * hdd_set_mac_address() - Wrapper function to protect __hdd_set_mac_address() 6048 * function from SSR 6049 * @net_dev: pointer to net_device structure 6050 * @addr: Pointer to the sockaddr 6051 * 6052 * This function sets the user specified mac address using 6053 * the command ifconfig wlanX hw ether <mac address>. 6054 * 6055 * Return: 0 for success. 6056 */ 6057 static int hdd_set_mac_address(struct net_device *net_dev, void *addr) 6058 { 6059 struct osif_vdev_sync *vdev_sync; 6060 int errno; 6061 6062 errno = osif_vdev_sync_op_start(net_dev, &vdev_sync); 6063 if (errno) 6064 return errno; 6065 6066 errno = __hdd_set_mac_address(net_dev, addr); 6067 6068 osif_vdev_sync_op_stop(vdev_sync); 6069 6070 return errno; 6071 } 6072 6073 static uint8_t *wlan_hdd_get_derived_intf_addr(struct hdd_context *hdd_ctx) 6074 { 6075 int i, j; 6076 6077 i = qdf_ffz(hdd_ctx->derived_intf_addr_mask); 6078 if (i < 0 || i >= hdd_ctx->num_derived_addr) 6079 return NULL; 6080 qdf_atomic_set_bit(i, &hdd_ctx->derived_intf_addr_mask); 6081 hdd_nofl_debug("Assigning MAC from derived list "QDF_MAC_ADDR_FMT, 6082 QDF_MAC_ADDR_REF(hdd_ctx->derived_mac_addr[i].bytes)); 6083 6084 /* Copy the mac in dynamic mac list at first free position */ 6085 for (j = 0; j < QDF_MAX_CONCURRENCY_PERSONA; j++) { 6086 if (qdf_is_macaddr_zero(&hdd_ctx-> 6087 dynamic_mac_list[j].dynamic_mac)) 6088 break; 6089 } 6090 if (j == QDF_MAX_CONCURRENCY_PERSONA) { 6091 hdd_err("Max interfaces are up"); 6092 return NULL; 6093 } 6094 6095 qdf_mem_copy(&hdd_ctx->dynamic_mac_list[j].dynamic_mac.bytes, 6096 &hdd_ctx->derived_mac_addr[i].bytes, 6097 sizeof(struct qdf_mac_addr)); 6098 hdd_ctx->dynamic_mac_list[j].is_provisioned_mac = false; 6099 hdd_ctx->dynamic_mac_list[j].bit_position = i; 6100 6101 return hdd_ctx->derived_mac_addr[i].bytes; 6102 } 6103 6104 static uint8_t *wlan_hdd_get_provisioned_intf_addr(struct hdd_context *hdd_ctx) 6105 { 6106 int i, j; 6107 6108 i = qdf_ffz(hdd_ctx->provisioned_intf_addr_mask); 6109 if (i < 0 || i >= hdd_ctx->num_provisioned_addr) 6110 return NULL; 6111 qdf_atomic_set_bit(i, &hdd_ctx->provisioned_intf_addr_mask); 6112 hdd_debug("Assigning MAC from provisioned list "QDF_MAC_ADDR_FMT, 6113 QDF_MAC_ADDR_REF(hdd_ctx->provisioned_mac_addr[i].bytes)); 6114 6115 /* Copy the mac in dynamic mac list at first free position */ 6116 for (j = 0; j < QDF_MAX_CONCURRENCY_PERSONA; j++) { 6117 if (qdf_is_macaddr_zero(&hdd_ctx-> 6118 dynamic_mac_list[j].dynamic_mac)) 6119 break; 6120 } 6121 if (j == QDF_MAX_CONCURRENCY_PERSONA) { 6122 hdd_err("Max interfaces are up"); 6123 return NULL; 6124 } 6125 6126 qdf_mem_copy(&hdd_ctx->dynamic_mac_list[j].dynamic_mac.bytes, 6127 &hdd_ctx->provisioned_mac_addr[i].bytes, 6128 sizeof(struct qdf_mac_addr)); 6129 hdd_ctx->dynamic_mac_list[j].is_provisioned_mac = true; 6130 hdd_ctx->dynamic_mac_list[j].bit_position = i; 6131 return hdd_ctx->provisioned_mac_addr[i].bytes; 6132 } 6133 6134 uint8_t *wlan_hdd_get_intf_addr(struct hdd_context *hdd_ctx, 6135 enum QDF_OPMODE interface_type) 6136 { 6137 uint8_t *mac_addr = NULL; 6138 6139 if (qdf_atomic_test_bit(interface_type, 6140 (unsigned long *) 6141 (&hdd_ctx->config->provisioned_intf_pool))) 6142 mac_addr = wlan_hdd_get_provisioned_intf_addr(hdd_ctx); 6143 6144 if ((!mac_addr) && 6145 (qdf_atomic_test_bit(interface_type, 6146 (unsigned long *) 6147 (&hdd_ctx->config->derived_intf_pool)))) 6148 mac_addr = wlan_hdd_get_derived_intf_addr(hdd_ctx); 6149 6150 if (!mac_addr) 6151 hdd_err("MAC is not available in both the lists"); 6152 return mac_addr; 6153 } 6154 6155 void wlan_hdd_release_intf_addr(struct hdd_context *hdd_ctx, 6156 uint8_t *releaseAddr) 6157 { 6158 int i; 6159 int mac_pos_in_mask; 6160 6161 for (i = 0; i < QDF_MAX_CONCURRENCY_PERSONA; i++) { 6162 if (!memcmp(releaseAddr, 6163 hdd_ctx->dynamic_mac_list[i].dynamic_mac.bytes, 6164 QDF_MAC_ADDR_SIZE)) { 6165 mac_pos_in_mask = 6166 hdd_ctx->dynamic_mac_list[i].bit_position; 6167 if (hdd_ctx->dynamic_mac_list[i].is_provisioned_mac) { 6168 qdf_atomic_clear_bit( 6169 mac_pos_in_mask, 6170 &hdd_ctx-> 6171 provisioned_intf_addr_mask); 6172 hdd_debug("Releasing MAC from provisioned list"); 6173 hdd_debug( 6174 QDF_MAC_ADDR_FMT, 6175 QDF_MAC_ADDR_REF(releaseAddr)); 6176 } else { 6177 qdf_atomic_clear_bit( 6178 mac_pos_in_mask, &hdd_ctx-> 6179 derived_intf_addr_mask); 6180 hdd_debug("Releasing MAC from derived list"); 6181 hdd_debug(QDF_MAC_ADDR_FMT, 6182 QDF_MAC_ADDR_REF(releaseAddr)); 6183 } 6184 qdf_zero_macaddr(&hdd_ctx-> 6185 dynamic_mac_list[i].dynamic_mac); 6186 hdd_ctx->dynamic_mac_list[i].is_provisioned_mac = 6187 false; 6188 hdd_ctx->dynamic_mac_list[i].bit_position = 0; 6189 break; 6190 } 6191 6192 } 6193 if (i == QDF_MAX_CONCURRENCY_PERSONA) 6194 hdd_debug("Releasing non existing MAC " QDF_MAC_ADDR_FMT, 6195 QDF_MAC_ADDR_REF(releaseAddr)); 6196 } 6197 6198 /** 6199 * hdd_set_derived_multicast_list(): Add derived peer multicast address list in 6200 * multicast list request to the FW 6201 * @psoc: Pointer to psoc 6202 * @adapter: Pointer to hdd adapter 6203 * @mc_list_request: Multicast list request to the FW 6204 * @mc_count: number of multicast addresses received from the kernel 6205 * 6206 * Return: None 6207 */ 6208 static void 6209 hdd_set_derived_multicast_list(struct wlan_objmgr_psoc *psoc, 6210 struct hdd_adapter *adapter, 6211 struct pmo_mc_addr_list_params *mc_list_request, 6212 int *mc_count) 6213 { 6214 int i = 0, j = 0, list_count = *mc_count; 6215 struct qdf_mac_addr *peer_mc_addr_list = NULL; 6216 uint8_t driver_mc_cnt = 0; 6217 uint32_t max_ndp_sessions = 0; 6218 6219 cfg_nan_get_ndp_max_sessions(psoc, &max_ndp_sessions); 6220 6221 ucfg_nan_get_peer_mc_list(adapter->deflink->vdev, &peer_mc_addr_list); 6222 6223 for (j = 0; j < max_ndp_sessions; j++) { 6224 for (i = 0; i < list_count; i++) { 6225 if (qdf_is_macaddr_zero(&peer_mc_addr_list[j]) || 6226 qdf_is_macaddr_equal(&mc_list_request->mc_addr[i], 6227 &peer_mc_addr_list[j])) 6228 break; 6229 } 6230 if (i == list_count) { 6231 qdf_mem_copy( 6232 &(mc_list_request->mc_addr[list_count + 6233 driver_mc_cnt].bytes), 6234 peer_mc_addr_list[j].bytes, ETH_ALEN); 6235 hdd_debug("mlist[%d] = " QDF_MAC_ADDR_FMT, 6236 list_count + driver_mc_cnt, 6237 QDF_MAC_ADDR_REF( 6238 mc_list_request->mc_addr[list_count + 6239 driver_mc_cnt].bytes)); 6240 driver_mc_cnt++; 6241 } 6242 } 6243 *mc_count += driver_mc_cnt; 6244 } 6245 6246 /** 6247 * __hdd_set_multicast_list() - set the multicast address list 6248 * @dev: Pointer to the WLAN device. 6249 * 6250 * This function sets the multicast address list. 6251 * 6252 * Return: None 6253 */ 6254 static void __hdd_set_multicast_list(struct net_device *dev) 6255 { 6256 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev); 6257 int i = 0, errno; 6258 struct netdev_hw_addr *ha; 6259 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); 6260 struct pmo_mc_addr_list_params *mc_list_request = NULL; 6261 struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc; 6262 int mc_count = 0; 6263 6264 if (hdd_ctx->hdd_wlan_suspended) { 6265 hdd_err_rl("Device is system suspended"); 6266 return; 6267 } 6268 6269 hdd_enter_dev(dev); 6270 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) 6271 return; 6272 6273 errno = wlan_hdd_validate_context(hdd_ctx); 6274 if (errno) 6275 return; 6276 6277 errno = hdd_validate_adapter(adapter); 6278 if (errno) 6279 return; 6280 6281 if (hdd_ctx->driver_status == DRIVER_MODULES_CLOSED) { 6282 hdd_debug("Driver module is closed"); 6283 return; 6284 } 6285 6286 mc_list_request = qdf_mem_malloc(sizeof(*mc_list_request)); 6287 if (!mc_list_request) 6288 return; 6289 6290 qdf_spin_lock_bh(&adapter->mc_list_lock); 6291 /* Delete already configured multicast address list */ 6292 if (adapter->mc_addr_list.mc_cnt > 0) 6293 hdd_disable_and_flush_mc_addr_list(adapter, 6294 pmo_mc_list_change_notify); 6295 6296 if (dev->flags & IFF_ALLMULTI) { 6297 hdd_debug("allow all multicast frames"); 6298 hdd_disable_and_flush_mc_addr_list(adapter, 6299 pmo_mc_list_change_notify); 6300 } else { 6301 mc_count = netdev_mc_count(dev); 6302 if (mc_count > ucfg_pmo_max_mc_addr_supported(psoc)) { 6303 hdd_debug("Exceeded max MC filter addresses (%d). Allowing all MC frames by disabling MC address filtering", 6304 ucfg_pmo_max_mc_addr_supported(psoc)); 6305 hdd_disable_and_flush_mc_addr_list(adapter, 6306 pmo_mc_list_change_notify); 6307 adapter->mc_addr_list.mc_cnt = 0; 6308 goto free_req; 6309 } 6310 netdev_for_each_mc_addr(ha, dev) { 6311 if (i == mc_count) 6312 break; 6313 memset(&(mc_list_request->mc_addr[i].bytes), 6314 0, ETH_ALEN); 6315 memcpy(&(mc_list_request->mc_addr[i].bytes), 6316 ha->addr, ETH_ALEN); 6317 hdd_debug("mlist[%d] = "QDF_MAC_ADDR_FMT, i, 6318 QDF_MAC_ADDR_REF(mc_list_request->mc_addr[i].bytes)); 6319 i++; 6320 } 6321 6322 if (adapter->device_mode == QDF_NDI_MODE) 6323 hdd_set_derived_multicast_list(psoc, adapter, 6324 mc_list_request, 6325 &mc_count); 6326 } 6327 6328 adapter->mc_addr_list.mc_cnt = mc_count; 6329 mc_list_request->psoc = psoc; 6330 mc_list_request->vdev_id = adapter->deflink->vdev_id; 6331 mc_list_request->count = mc_count; 6332 6333 errno = hdd_cache_mc_addr_list(mc_list_request); 6334 if (errno) { 6335 hdd_debug("Failed to cache MC address list for vdev %u; errno:%d", 6336 adapter->deflink->vdev_id, errno); 6337 goto free_req; 6338 } 6339 6340 hdd_enable_mc_addr_filtering(adapter, pmo_mc_list_change_notify); 6341 6342 free_req: 6343 qdf_spin_unlock_bh(&adapter->mc_list_lock); 6344 qdf_mem_free(mc_list_request); 6345 } 6346 6347 /** 6348 * hdd_set_multicast_list() - SSR wrapper function for __hdd_set_multicast_list 6349 * @net_dev: pointer to net_device 6350 * 6351 * Return: none 6352 */ 6353 static void hdd_set_multicast_list(struct net_device *net_dev) 6354 { 6355 struct osif_vdev_sync *vdev_sync; 6356 6357 if (osif_vdev_sync_op_start(net_dev, &vdev_sync)) 6358 return; 6359 6360 __hdd_set_multicast_list(net_dev); 6361 6362 osif_vdev_sync_op_stop(vdev_sync); 6363 } 6364 6365 void hdd_update_multicast_list(struct wlan_objmgr_vdev *vdev) 6366 { 6367 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 6368 struct wlan_hdd_link_info *link_info; 6369 struct hdd_adapter *adapter; 6370 uint8_t vdev_id = wlan_vdev_get_id(vdev); 6371 struct net_device *net_dev; 6372 6373 if (!hdd_ctx) { 6374 hdd_err("hdd_ctx is null"); 6375 return; 6376 } 6377 6378 link_info = hdd_get_link_info_by_vdev(hdd_ctx, vdev_id); 6379 if (!link_info) { 6380 hdd_err("adapter is null for vdev_id %d", vdev_id); 6381 return; 6382 } 6383 6384 adapter = link_info->adapter; 6385 if (!adapter) { 6386 hdd_err("adapter is null for vdev_id %d", vdev_id); 6387 return; 6388 } 6389 6390 net_dev = adapter->dev; 6391 if (!net_dev) { 6392 hdd_err("netdev is null"); 6393 return; 6394 } 6395 6396 __hdd_set_multicast_list(net_dev); 6397 } 6398 6399 #ifdef WLAN_FEATURE_TSF_PTP 6400 static const struct ethtool_ops wlan_ethtool_ops = { 6401 .get_ts_info = wlan_get_ts_info, 6402 }; 6403 #endif 6404 6405 /** 6406 * __hdd_fix_features - Adjust the feature flags needed to be updated 6407 * @net_dev: Handle to net_device 6408 * @features: Currently enabled feature flags 6409 * 6410 * Return: Adjusted feature flags on success, old feature on failure 6411 */ 6412 static netdev_features_t __hdd_fix_features(struct net_device *net_dev, 6413 netdev_features_t features) 6414 { 6415 netdev_features_t feature_change_req = features; 6416 netdev_features_t feature_tso_csum; 6417 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(net_dev); 6418 6419 if (!adapter->handle_feature_update) { 6420 hdd_debug("Not triggered by hdd_netdev_update_features"); 6421 return features; 6422 } 6423 6424 feature_tso_csum = hdd_get_tso_csum_feature_flags(); 6425 if (hdd_is_legacy_connection(adapter->deflink)) { 6426 /* Disable checksum and TSO */ 6427 feature_change_req &= ~feature_tso_csum; 6428 adapter->tso_csum_feature_enabled = 0; 6429 } else { 6430 /* Enable checksum and TSO */ 6431 feature_change_req |= feature_tso_csum; 6432 adapter->tso_csum_feature_enabled = 1; 6433 } 6434 hdd_debug("vdev mode %d current features 0x%llx, requesting feature change 0x%llx", 6435 adapter->device_mode, net_dev->features, 6436 feature_change_req); 6437 6438 return feature_change_req; 6439 } 6440 6441 /** 6442 * hdd_fix_features() - Wrapper for __hdd_fix_features to protect it from SSR 6443 * @net_dev: Pointer to net_device structure 6444 * @features: Updated features set 6445 * 6446 * Adjusts the feature request, do not update the device yet. 6447 * 6448 * Return: updated feature for success, incoming feature as is on failure 6449 */ 6450 static netdev_features_t hdd_fix_features(struct net_device *net_dev, 6451 netdev_features_t features) 6452 { 6453 int errno; 6454 int changed_features = features; 6455 struct osif_vdev_sync *vdev_sync; 6456 6457 errno = osif_vdev_sync_op_start(net_dev, &vdev_sync); 6458 if (errno) 6459 return features; 6460 6461 changed_features = __hdd_fix_features(net_dev, features); 6462 6463 osif_vdev_sync_op_stop(vdev_sync); 6464 6465 return changed_features; 6466 } 6467 /** 6468 * __hdd_set_features - Notify device about change in features 6469 * @net_dev: Handle to net_device 6470 * @features: Existing + requested feature after resolving the dependency 6471 * 6472 * Return: 0 on success, non zero error on failure 6473 */ 6474 static int __hdd_set_features(struct net_device *net_dev, 6475 netdev_features_t features) 6476 { 6477 struct hdd_adapter *adapter = netdev_priv(net_dev); 6478 ol_txrx_soc_handle soc = cds_get_context(QDF_MODULE_ID_SOC); 6479 6480 if (!adapter->handle_feature_update) { 6481 hdd_debug("Not triggered by hdd_netdev_update_features"); 6482 return 0; 6483 } 6484 6485 if (!soc) 6486 return 0; 6487 6488 hdd_debug("vdev mode %d vdev_id %d current features 0x%llx, changed features 0x%llx", 6489 adapter->device_mode, adapter->deflink->vdev_id, 6490 net_dev->features, features); 6491 6492 return 0; 6493 } 6494 6495 /** 6496 * hdd_set_features() - Wrapper for __hdd_set_features to protect it from SSR 6497 * @net_dev: Pointer to net_device structure 6498 * @features: Updated features set 6499 * 6500 * Is called to update device configurations for changed features. 6501 * 6502 * Return: 0 for success, non-zero for failure 6503 */ 6504 static int hdd_set_features(struct net_device *net_dev, 6505 netdev_features_t features) 6506 { 6507 int errno; 6508 struct osif_vdev_sync *vdev_sync; 6509 6510 errno = osif_vdev_sync_op_start(net_dev, &vdev_sync); 6511 if (errno) { 6512 /* 6513 * Only invoke from netdev_feature_update_work expected, 6514 * which is from CLD inside. 6515 * Ignore others from upper stack during loading phase, 6516 * and return success to avoid failure print from kernel. 6517 */ 6518 hdd_debug("VDEV in transition, ignore set_features"); 6519 return 0; 6520 } 6521 6522 errno = __hdd_set_features(net_dev, features); 6523 6524 osif_vdev_sync_op_stop(vdev_sync); 6525 6526 return errno; 6527 } 6528 6529 #define HDD_NETDEV_FEATURES_UPDATE_MAX_WAIT_COUNT 10 6530 #define HDD_NETDEV_FEATURES_UPDATE_WAIT_INTERVAL_MS 20 6531 6532 void hdd_netdev_update_features(struct hdd_adapter *adapter) 6533 { 6534 struct net_device *net_dev = adapter->dev; 6535 ol_txrx_soc_handle soc = cds_get_context(QDF_MODULE_ID_SOC); 6536 bool request_feature_update = false; 6537 int wait_count = HDD_NETDEV_FEATURES_UPDATE_MAX_WAIT_COUNT; 6538 6539 if (!soc) 6540 return; 6541 6542 if (!cdp_cfg_get(soc, cfg_dp_disable_legacy_mode_csum_offload)) 6543 return; 6544 6545 switch (adapter->device_mode) { 6546 case QDF_STA_MODE: 6547 if (cdp_cfg_get(soc, cfg_dp_enable_ip_tcp_udp_checksum_offload)) 6548 request_feature_update = true; 6549 break; 6550 default: 6551 break; 6552 } 6553 6554 if (request_feature_update) { 6555 hdd_debug("Update net_dev features for device mode %d", 6556 adapter->device_mode); 6557 while (!adapter->delete_in_progress) { 6558 if (rtnl_trylock()) { 6559 adapter->handle_feature_update = true; 6560 netdev_update_features(net_dev); 6561 adapter->handle_feature_update = false; 6562 rtnl_unlock(); 6563 break; 6564 } 6565 6566 if (wait_count--) { 6567 qdf_sleep( 6568 HDD_NETDEV_FEATURES_UPDATE_WAIT_INTERVAL_MS); 6569 } else { 6570 /* 6571 * We have failed to updated the netdev 6572 * features for very long, so enable the queues 6573 * now. The impact of not being able to update 6574 * the netdev feature is lower TPUT when 6575 * switching from legacy to non-legacy mode. 6576 */ 6577 hdd_err("Failed to update netdev features for device mode %d", 6578 adapter->device_mode); 6579 break; 6580 } 6581 } 6582 } 6583 } 6584 6585 static const struct net_device_ops wlan_drv_ops = { 6586 .ndo_open = hdd_open, 6587 .ndo_stop = hdd_stop, 6588 .ndo_uninit = hdd_uninit, 6589 .ndo_start_xmit = hdd_hard_start_xmit, 6590 .ndo_fix_features = hdd_fix_features, 6591 .ndo_set_features = hdd_set_features, 6592 .ndo_tx_timeout = hdd_tx_timeout, 6593 .ndo_get_stats = hdd_get_stats, 6594 #if LINUX_VERSION_CODE < KERNEL_VERSION(5, 15, 0) 6595 .ndo_do_ioctl = hdd_ioctl, 6596 #endif 6597 .ndo_set_mac_address = hdd_set_mac_address, 6598 .ndo_select_queue = hdd_select_queue, 6599 .ndo_set_rx_mode = hdd_set_multicast_list, 6600 #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0) 6601 .ndo_siocdevprivate = hdd_dev_private_ioctl, 6602 #endif 6603 }; 6604 6605 #ifdef FEATURE_MONITOR_MODE_SUPPORT 6606 /* Monitor mode net_device_ops, does not Tx and most of operations. */ 6607 static const struct net_device_ops wlan_mon_drv_ops = { 6608 .ndo_open = hdd_mon_open, 6609 .ndo_stop = hdd_stop, 6610 .ndo_get_stats = hdd_get_stats, 6611 }; 6612 6613 /** 6614 * hdd_set_mon_ops() - update net_device ops for monitor mode 6615 * @dev: Handle to struct net_device to be updated. 6616 * Return: None 6617 */ 6618 static void hdd_set_mon_ops(struct net_device *dev) 6619 { 6620 dev->netdev_ops = &wlan_mon_drv_ops; 6621 } 6622 6623 #ifdef WLAN_FEATURE_TSF_PTP 6624 void hdd_set_station_ops(struct net_device *dev) 6625 { 6626 if (cds_get_conparam() == QDF_GLOBAL_MONITOR_MODE) { 6627 hdd_set_mon_ops(dev); 6628 } else { 6629 dev->netdev_ops = &wlan_drv_ops; 6630 dev->ethtool_ops = &wlan_ethtool_ops; 6631 } 6632 } 6633 #else 6634 void hdd_set_station_ops(struct net_device *dev) 6635 { 6636 if (cds_get_conparam() == QDF_GLOBAL_MONITOR_MODE) 6637 hdd_set_mon_ops(dev); 6638 else 6639 dev->netdev_ops = &wlan_drv_ops; 6640 } 6641 6642 #endif 6643 #else 6644 #ifdef WLAN_FEATURE_TSF_PTP 6645 void hdd_set_station_ops(struct net_device *dev) 6646 { 6647 dev->netdev_ops = &wlan_drv_ops; 6648 dev->ethtool_ops = &wlan_ethtool_ops; 6649 } 6650 #else 6651 void hdd_set_station_ops(struct net_device *dev) 6652 { 6653 dev->netdev_ops = &wlan_drv_ops; 6654 } 6655 #endif 6656 static void hdd_set_mon_ops(struct net_device *dev) 6657 { 6658 } 6659 #endif 6660 6661 #ifdef WLAN_FEATURE_PKT_CAPTURE 6662 /* Packet Capture mode net_device_ops, does not Tx and most of operations. */ 6663 static const struct net_device_ops wlan_pktcapture_drv_ops = { 6664 .ndo_open = hdd_pktcapture_open, 6665 .ndo_stop = hdd_stop, 6666 .ndo_get_stats = hdd_get_stats, 6667 }; 6668 6669 static void hdd_set_pktcapture_ops(struct net_device *dev) 6670 { 6671 dev->netdev_ops = &wlan_pktcapture_drv_ops; 6672 } 6673 #else 6674 static void hdd_set_pktcapture_ops(struct net_device *dev) 6675 { 6676 } 6677 #endif 6678 6679 #ifdef MULTI_CLIENT_LL_SUPPORT 6680 /** 6681 * hdd_set_multi_client_ll_support() - set multi client ll support flag in 6682 * allocated station hdd adapter 6683 * @adapter: pointer to hdd adapter 6684 * 6685 * Return: none 6686 */ 6687 static void hdd_set_multi_client_ll_support(struct hdd_adapter *adapter) 6688 { 6689 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); 6690 bool multi_client_ll_ini_support, multi_client_ll_caps; 6691 6692 ucfg_mlme_cfg_get_multi_client_ll_ini_support(hdd_ctx->psoc, 6693 &multi_client_ll_ini_support); 6694 multi_client_ll_caps = 6695 ucfg_mlme_get_wlm_multi_client_ll_caps(hdd_ctx->psoc); 6696 6697 hdd_debug("fw caps: %d, ini: %d", multi_client_ll_caps, 6698 multi_client_ll_ini_support); 6699 if (multi_client_ll_caps && multi_client_ll_ini_support) 6700 adapter->multi_client_ll_support = true; 6701 } 6702 #else 6703 static inline void 6704 hdd_set_multi_client_ll_support(struct hdd_adapter *adapter) 6705 { 6706 } 6707 #endif 6708 6709 /** 6710 * hdd_alloc_station_adapter() - allocate the station hdd adapter 6711 * @hdd_ctx: global hdd context 6712 * @mac_addr: mac address to assign to the interface 6713 * @name_assign_type: name assignment type 6714 * @name: User-visible name of the interface 6715 * @session_type: interface type to be created 6716 * 6717 * hdd adapter pointer would point to the netdev->priv space, this function 6718 * would retrieve the pointer, and setup the hdd adapter configuration. 6719 * 6720 * Return: the pointer to hdd adapter, otherwise NULL 6721 */ 6722 static struct hdd_adapter * 6723 hdd_alloc_station_adapter(struct hdd_context *hdd_ctx, tSirMacAddr mac_addr, 6724 unsigned char name_assign_type, const char *name, 6725 uint8_t session_type) 6726 { 6727 struct net_device *dev; 6728 struct hdd_adapter *adapter; 6729 QDF_STATUS qdf_status; 6730 uint8_t latency_level; 6731 6732 /* cfg80211 initialization and registration */ 6733 dev = alloc_netdev_mqs(sizeof(*adapter), name, 6734 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS) 6735 name_assign_type, 6736 #endif 6737 ((cds_get_conparam() == QDF_GLOBAL_MONITOR_MODE || 6738 wlan_hdd_is_session_type_monitor(session_type)) ? 6739 hdd_mon_mode_ether_setup : ether_setup), 6740 NUM_TX_QUEUES, NUM_RX_QUEUES); 6741 6742 if (!dev) { 6743 hdd_err("Failed to allocate new net_device '%s'", name); 6744 return NULL; 6745 } 6746 6747 adapter = netdev_priv(dev); 6748 6749 qdf_mem_zero(adapter, sizeof(*adapter)); 6750 adapter->dev = dev; 6751 adapter->deflink = &adapter->link_info[WLAN_HDD_DEFLINK_IDX]; 6752 adapter->hdd_ctx = hdd_ctx; 6753 adapter->magic = WLAN_HDD_ADAPTER_MAGIC; 6754 qdf_atomic_set_bit(WLAN_HDD_DEFLINK_IDX, &adapter->active_links); 6755 6756 qdf_status = hdd_monitor_mode_qdf_create_event(adapter, session_type); 6757 if (QDF_IS_STATUS_ERROR(qdf_status)) { 6758 hdd_err_rl("create monitor mode vdve up event failed"); 6759 goto free_net_dev; 6760 } 6761 6762 hdd_update_dynamic_tsf_sync(adapter); 6763 adapter->is_link_up_service_needed = false; 6764 adapter->send_mode_change = true; 6765 6766 /* Cache station count initialize to zero */ 6767 qdf_atomic_init(&adapter->cache_sta_count); 6768 6769 /* Init the net_device structure */ 6770 strlcpy(dev->name, name, IFNAMSIZ); 6771 6772 qdf_net_update_net_device_dev_addr(dev, mac_addr, sizeof(tSirMacAddr)); 6773 qdf_mem_copy(adapter->mac_addr.bytes, mac_addr, sizeof(tSirMacAddr)); 6774 dev->watchdog_timeo = HDD_TX_TIMEOUT; 6775 6776 if (wlan_hdd_is_session_type_monitor(session_type)) { 6777 if (ucfg_pkt_capture_get_mode(hdd_ctx->psoc) != 6778 PACKET_CAPTURE_MODE_DISABLE) 6779 hdd_set_pktcapture_ops(adapter->dev); 6780 if (ucfg_mlme_is_sta_mon_conc_supported(hdd_ctx->psoc) || 6781 ucfg_dp_is_local_pkt_capture_enabled(hdd_ctx->psoc)) 6782 hdd_set_mon_ops(adapter->dev); 6783 } else { 6784 hdd_set_station_ops(adapter->dev); 6785 } 6786 6787 hdd_dev_setup_destructor(dev); 6788 dev->ieee80211_ptr = &adapter->wdev; 6789 dev->tx_queue_len = HDD_NETDEV_TX_QUEUE_LEN; 6790 adapter->wdev.wiphy = hdd_ctx->wiphy; 6791 adapter->wdev.netdev = dev; 6792 qdf_status = ucfg_mlme_cfg_get_wlm_level(hdd_ctx->psoc, &latency_level); 6793 if (QDF_IS_STATUS_ERROR(qdf_status)) { 6794 hdd_debug("Can't get latency level"); 6795 latency_level = 6796 QCA_WLAN_VENDOR_ATTR_CONFIG_LATENCY_LEVEL_NORMAL; 6797 } 6798 adapter->latency_level = latency_level; 6799 hdd_set_multi_client_ll_support(adapter); 6800 6801 /* set dev's parent to underlying device */ 6802 SET_NETDEV_DEV(dev, hdd_ctx->parent_dev); 6803 spin_lock_init(&adapter->pause_map_lock); 6804 adapter->start_time = qdf_system_ticks(); 6805 adapter->last_time = adapter->start_time; 6806 6807 qdf_atomic_init(&adapter->is_ll_stats_req_pending); 6808 hdd_init_get_sta_in_ll_stats_config(adapter); 6809 6810 return adapter; 6811 6812 free_net_dev: 6813 free_netdev(adapter->dev); 6814 6815 return NULL; 6816 } 6817 6818 #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 12, 0) 6819 static int 6820 hdd_register_netdevice(struct hdd_adapter *adapter, struct net_device *dev, 6821 struct hdd_adapter_create_param *params) 6822 { 6823 int ret; 6824 6825 if (params->is_add_virtual_iface) 6826 ret = wlan_cfg80211_register_netdevice(dev); 6827 else 6828 ret = register_netdevice(dev); 6829 6830 return ret; 6831 } 6832 #else 6833 static int 6834 hdd_register_netdevice(struct hdd_adapter *adapter, struct net_device *dev, 6835 struct hdd_adapter_create_param *params) 6836 { 6837 return register_netdevice(dev); 6838 } 6839 #endif 6840 6841 static QDF_STATUS 6842 hdd_register_interface(struct hdd_adapter *adapter, bool rtnl_held, 6843 struct hdd_adapter_create_param *params) 6844 { 6845 struct net_device *dev = adapter->dev; 6846 int ret; 6847 6848 hdd_enter(); 6849 6850 if (rtnl_held) { 6851 if (strnchr(dev->name, IFNAMSIZ - 1, '%')) { 6852 6853 ret = dev_alloc_name(dev, dev->name); 6854 if (ret < 0) { 6855 hdd_err( 6856 "unable to get dev name: %s, err = 0x%x", 6857 dev->name, ret); 6858 return QDF_STATUS_E_FAILURE; 6859 } 6860 } 6861 hdd_debug("hdd_register_netdevice(%s) type:%d", dev->name, 6862 adapter->device_mode); 6863 ret = hdd_register_netdevice(adapter, dev, params); 6864 if (ret) { 6865 hdd_err("register_netdevice(%s) failed, err = 0x%x", 6866 dev->name, ret); 6867 return QDF_STATUS_E_FAILURE; 6868 } 6869 } else { 6870 hdd_debug("register_netdev(%s) type:%d", dev->name, 6871 adapter->device_mode); 6872 ret = register_netdev(dev); 6873 if (ret) { 6874 hdd_err("register_netdev(%s) failed, err = 0x%x", 6875 dev->name, ret); 6876 return QDF_STATUS_E_FAILURE; 6877 } 6878 } 6879 set_bit(NET_DEVICE_REGISTERED, &adapter->event_flags); 6880 6881 hdd_exit(); 6882 6883 return QDF_STATUS_SUCCESS; 6884 } 6885 6886 QDF_STATUS hdd_sme_close_session_callback(uint8_t vdev_id) 6887 { 6888 struct hdd_adapter *adapter; 6889 struct hdd_context *hdd_ctx; 6890 struct wlan_hdd_link_info *link_info; 6891 6892 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 6893 if (!hdd_ctx) 6894 return QDF_STATUS_E_FAILURE; 6895 6896 link_info = hdd_get_link_info_by_vdev(hdd_ctx, vdev_id); 6897 if (!link_info) { 6898 hdd_err("Invalid vdev %d", vdev_id); 6899 return QDF_STATUS_E_INVAL; 6900 } 6901 6902 adapter = link_info->adapter; 6903 if (WLAN_HDD_ADAPTER_MAGIC != adapter->magic) { 6904 hdd_err("Invalid magic"); 6905 return QDF_STATUS_NOT_INITIALIZED; 6906 } 6907 6908 clear_bit(SME_SESSION_OPENED, &link_info->link_flags); 6909 qdf_spin_lock_bh(&link_info->vdev_lock); 6910 link_info->vdev_id = WLAN_UMAC_VDEV_ID_MAX; 6911 qdf_spin_unlock_bh(&link_info->vdev_lock); 6912 6913 /* 6914 * We can be blocked while waiting for scheduled work to be 6915 * flushed, and the adapter structure can potentially be freed, in 6916 * which case the magic will have been reset. So make sure the 6917 * magic is still good, and hence the adapter structure is still 6918 * valid, before signaling completion 6919 */ 6920 if (WLAN_HDD_ADAPTER_MAGIC == adapter->magic) 6921 complete(&link_info->vdev_destroy_event); 6922 6923 return QDF_STATUS_SUCCESS; 6924 } 6925 6926 int hdd_vdev_ready(struct wlan_objmgr_vdev *vdev, 6927 struct qdf_mac_addr *bridgeaddr) 6928 { 6929 QDF_STATUS status; 6930 6931 status = pmo_vdev_ready(vdev, bridgeaddr); 6932 if (QDF_IS_STATUS_ERROR(status)) 6933 return qdf_status_to_os_return(status); 6934 6935 status = ucfg_reg_11d_vdev_created_update(vdev); 6936 if (QDF_IS_STATUS_ERROR(status)) 6937 return qdf_status_to_os_return(status); 6938 6939 if (wma_capability_enhanced_mcast_filter()) 6940 status = ucfg_pmo_enhanced_mc_filter_enable(vdev); 6941 else 6942 status = ucfg_pmo_enhanced_mc_filter_disable(vdev); 6943 6944 return qdf_status_to_os_return(status); 6945 } 6946 6947 /** 6948 * hdd_check_wait_for_hw_mode_completion - Check hw mode in progress 6949 * @hdd_ctx: hdd context 6950 * 6951 * Check and wait for hw mode response if any hw mode change is 6952 * in progress. Vdev delete will purge the serialization queue 6953 * for the vdev. It will cause issues when the fw event coming 6954 * up later and no active hw mode change req ser command in queue. 6955 * 6956 * Return void 6957 */ 6958 static void hdd_check_wait_for_hw_mode_completion(struct hdd_context *hdd_ctx) 6959 { 6960 QDF_STATUS status; 6961 6962 if (!wlan_hdd_validate_context(hdd_ctx) && 6963 policy_mgr_is_hw_mode_change_in_progress( 6964 hdd_ctx->psoc)) { 6965 status = policy_mgr_wait_for_connection_update( 6966 hdd_ctx->psoc); 6967 if (!QDF_IS_STATUS_SUCCESS(status)) { 6968 hdd_nofl_debug("qdf wait for hw mode event failed!!"); 6969 } 6970 } 6971 } 6972 6973 static void hdd_stop_last_active_connection(struct hdd_context *hdd_ctx, 6974 struct wlan_objmgr_vdev *vdev) 6975 { 6976 enum policy_mgr_con_mode mode; 6977 struct wlan_objmgr_psoc *psoc; 6978 enum QDF_OPMODE op_mode; 6979 6980 /* If this is the last active connection check 6981 * and stop the opportunistic timer. 6982 */ 6983 psoc = wlan_vdev_get_psoc(vdev); 6984 op_mode = wlan_vdev_mlme_get_opmode(vdev); 6985 mode = policy_mgr_qdf_opmode_to_pm_con_mode(psoc, op_mode, 6986 wlan_vdev_get_id(vdev)); 6987 if ((policy_mgr_get_connection_count(psoc) == 1 && 6988 policy_mgr_mode_specific_connection_count(psoc, 6989 mode, NULL) == 1) || 6990 (!policy_mgr_get_connection_count(psoc) && 6991 !hdd_is_any_sta_connecting(hdd_ctx))) { 6992 policy_mgr_check_and_stop_opportunistic_timer( 6993 psoc, 6994 wlan_vdev_get_id(vdev)); 6995 } 6996 } 6997 6998 static int hdd_vdev_destroy_event_wait(struct hdd_context *hdd_ctx, 6999 struct wlan_objmgr_vdev *vdev) 7000 { 7001 long rc; 7002 QDF_STATUS status; 7003 uint8_t vdev_id; 7004 struct wlan_hdd_link_info *link_info; 7005 7006 vdev_id = wlan_vdev_get_id(vdev); 7007 link_info = hdd_get_link_info_by_vdev(hdd_ctx, vdev_id); 7008 if (!link_info) { 7009 hdd_err("Invalid vdev"); 7010 return -EINVAL; 7011 } 7012 7013 /* close sme session (destroy vdev in firmware via legacy API) */ 7014 INIT_COMPLETION(link_info->vdev_destroy_event); 7015 status = sme_vdev_delete(hdd_ctx->mac_handle, vdev); 7016 if (QDF_IS_STATUS_ERROR(status)) { 7017 hdd_err("vdev %d: failed to delete with status:%d", 7018 vdev_id, status); 7019 return -EAGAIN; 7020 } 7021 7022 /* block on a completion variable until sme session is closed */ 7023 rc = wait_for_completion_timeout( 7024 &link_info->vdev_destroy_event, 7025 msecs_to_jiffies(SME_CMD_VDEV_CREATE_DELETE_TIMEOUT)); 7026 if (!rc) { 7027 hdd_err("vdev %d: timed out waiting for delete", vdev_id); 7028 clear_bit(SME_SESSION_OPENED, &link_info->link_flags); 7029 sme_cleanup_session(hdd_ctx->mac_handle, vdev_id); 7030 cds_flush_logs(WLAN_LOG_TYPE_FATAL, 7031 WLAN_LOG_INDICATOR_HOST_DRIVER, 7032 WLAN_LOG_REASON_VDEV_DELETE_RSP_TIMED_OUT, 7033 true, true); 7034 return -EINVAL; 7035 } 7036 7037 hdd_nofl_info("vdev %d destroyed successfully", vdev_id); 7038 return 0; 7039 } 7040 7041 static inline 7042 void hdd_vdev_deinit_components(struct wlan_objmgr_vdev *vdev) 7043 { 7044 ucfg_pmo_del_wow_pattern(vdev); 7045 ucfg_son_disable_cbs(vdev); 7046 } 7047 7048 static inline 7049 void hdd_reset_vdev_info(struct wlan_hdd_link_info *link_info) 7050 { 7051 qdf_spin_lock_bh(&link_info->vdev_lock); 7052 link_info->vdev = NULL; 7053 qdf_spin_unlock_bh(&link_info->vdev_lock); 7054 } 7055 7056 int hdd_vdev_destroy(struct wlan_hdd_link_info *link_info) 7057 { 7058 int ret; 7059 uint8_t vdev_id; 7060 struct hdd_context *hdd_ctx; 7061 struct wlan_objmgr_vdev *vdev; 7062 struct wlan_objmgr_psoc *psoc; 7063 enum QDF_OPMODE op_mode; 7064 7065 vdev_id = link_info->vdev_id; 7066 hdd_nofl_debug("destroying vdev %d", vdev_id); 7067 /* vdev created sanity check */ 7068 if (!test_bit(SME_SESSION_OPENED, &link_info->link_flags)) { 7069 hdd_nofl_debug("vdev %u does not exist", vdev_id); 7070 return -EINVAL; 7071 } 7072 7073 hdd_ctx = WLAN_HDD_GET_CTX(link_info->adapter); 7074 7075 vdev = hdd_objmgr_get_vdev_by_user(link_info, WLAN_OSIF_ID); 7076 if (!vdev) 7077 return -EINVAL; 7078 7079 psoc = wlan_vdev_get_psoc(vdev); 7080 if (!psoc) { 7081 hdd_err("invalid psoc"); 7082 return -EINVAL; 7083 } 7084 op_mode = wlan_vdev_mlme_get_opmode(vdev); 7085 7086 hdd_stop_last_active_connection(hdd_ctx, vdev); 7087 hdd_check_wait_for_hw_mode_completion(hdd_ctx); 7088 ucfg_scan_vdev_set_disable(vdev, REASON_VDEV_DOWN); 7089 wlan_hdd_scan_abort(link_info); 7090 hdd_vdev_deinit_components(vdev); 7091 hdd_mlo_t2lm_unregister_callback(vdev); 7092 hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_ID); 7093 7094 hdd_reset_vdev_info(link_info); 7095 osif_cm_osif_priv_deinit(vdev); 7096 7097 /* Release the hdd reference */ 7098 wlan_objmgr_vdev_release_ref(vdev, WLAN_HDD_ID_OBJ_MGR); 7099 7100 /* Get runtime lock to prevent runtime suspend */ 7101 qdf_runtime_pm_prevent_suspend(&hdd_ctx->runtime_context.vdev_destroy); 7102 7103 ret = hdd_vdev_destroy_event_wait(hdd_ctx, vdev); 7104 7105 ucfg_reg_11d_vdev_delete_update(psoc, op_mode, vdev_id); 7106 7107 qdf_runtime_pm_allow_suspend(&hdd_ctx->runtime_context.vdev_destroy); 7108 return ret; 7109 } 7110 7111 void 7112 hdd_store_nss_chains_cfg_in_vdev(struct hdd_context *hdd_ctx, 7113 struct wlan_objmgr_vdev *vdev) 7114 { 7115 struct wlan_mlme_nss_chains vdev_ini_cfg; 7116 7117 /* Populate the nss chain params from ini for this vdev type */ 7118 sme_populate_nss_chain_params(hdd_ctx->mac_handle, &vdev_ini_cfg, 7119 wlan_vdev_mlme_get_opmode(vdev), 7120 hdd_ctx->num_rf_chains); 7121 7122 /* Store the nss chain config into the vdev */ 7123 sme_store_nss_chains_cfg_in_vdev(vdev, &vdev_ini_cfg); 7124 } 7125 7126 bool hdd_is_vdev_in_conn_state(struct wlan_hdd_link_info *link_info) 7127 { 7128 switch (link_info->adapter->device_mode) { 7129 case QDF_STA_MODE: 7130 case QDF_P2P_CLIENT_MODE: 7131 case QDF_P2P_DEVICE_MODE: 7132 return hdd_cm_is_vdev_associated(link_info); 7133 case QDF_SAP_MODE: 7134 case QDF_P2P_GO_MODE: 7135 return (test_bit(SOFTAP_BSS_STARTED, 7136 &link_info->link_flags)); 7137 default: 7138 hdd_err("Device mode %d invalid", 7139 link_info->adapter->device_mode); 7140 return 0; 7141 } 7142 } 7143 7144 #define MAX_VDEV_RTT_PARAMS 2 7145 /* params being sent: 7146 * wmi_vdev_param_enable_disable_rtt_responder_role 7147 * wmi_vdev_param_enable_disable_rtt_initiator_role 7148 */ 7149 static QDF_STATUS 7150 hdd_vdev_configure_rtt_params(struct wlan_objmgr_vdev *vdev) 7151 { 7152 QDF_STATUS status; 7153 struct wlan_objmgr_psoc *psoc; 7154 uint32_t fine_time_meas_cap = 0; 7155 uint8_t vdev_id = wlan_vdev_get_id(vdev); 7156 struct dev_set_param vdevsetparam[MAX_VDEV_RTT_PARAMS] = {}; 7157 uint8_t index = 0; 7158 WMI_FW_SUB_FEAT_CAPS wmi_fw_rtt_respr, wmi_fw_rtt_initr; 7159 7160 switch (wlan_vdev_mlme_get_opmode(vdev)) { 7161 case QDF_STA_MODE: 7162 wmi_fw_rtt_respr = WMI_FW_STA_RTT_RESPR; 7163 wmi_fw_rtt_initr = WMI_FW_STA_RTT_INITR; 7164 break; 7165 case QDF_SAP_MODE: 7166 wmi_fw_rtt_respr = WMI_FW_AP_RTT_RESPR; 7167 wmi_fw_rtt_initr = WMI_FW_AP_RTT_INITR; 7168 break; 7169 default: 7170 return QDF_STATUS_SUCCESS; 7171 } 7172 7173 psoc = wlan_vdev_get_psoc(vdev); 7174 7175 ucfg_mlme_get_fine_time_meas_cap(psoc, &fine_time_meas_cap); 7176 status = mlme_check_index_setparam( 7177 vdevsetparam, 7178 wmi_vdev_param_enable_disable_rtt_responder_role, 7179 (fine_time_meas_cap & wmi_fw_rtt_respr), index++, 7180 MAX_VDEV_RTT_PARAMS); 7181 if (QDF_IS_STATUS_ERROR(status)) 7182 return status; 7183 7184 status = mlme_check_index_setparam( 7185 vdevsetparam, 7186 wmi_vdev_param_enable_disable_rtt_initiator_role, 7187 (fine_time_meas_cap & wmi_fw_rtt_initr), index++, 7188 MAX_VDEV_RTT_PARAMS); 7189 if (QDF_IS_STATUS_ERROR(status)) 7190 return status; 7191 7192 status = sme_send_multi_pdev_vdev_set_params(MLME_VDEV_SETPARAM, 7193 vdev_id, vdevsetparam, 7194 index); 7195 if (QDF_IS_STATUS_ERROR(status)) 7196 hdd_err("failed to set RTT_RESPONDER,INITIATOR params:%d", 7197 status); 7198 7199 return status; 7200 } 7201 7202 static void hdd_store_vdev_info(struct wlan_hdd_link_info *link_info, 7203 struct wlan_objmgr_vdev *vdev) 7204 { 7205 struct vdev_osif_priv *osif_priv; 7206 7207 osif_priv = wlan_vdev_get_ospriv(vdev); 7208 if (osif_priv) { 7209 osif_priv->wdev = link_info->adapter->dev->ieee80211_ptr; 7210 osif_priv->legacy_osif_priv = link_info; 7211 } 7212 7213 qdf_spin_lock_bh(&link_info->vdev_lock); 7214 link_info->vdev_id = wlan_vdev_get_id(vdev); 7215 link_info->vdev = vdev; 7216 qdf_spin_unlock_bh(&link_info->vdev_lock); 7217 } 7218 7219 static void 7220 hdd_init_station_context(struct wlan_hdd_link_info *link_info) 7221 { 7222 struct hdd_station_ctx *sta_ctx; 7223 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(link_info->adapter); 7224 7225 /* Set the default operation channel freq and auth type to open */ 7226 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(link_info); 7227 sta_ctx->conn_info.chan_freq = hdd_ctx->config->operating_chan_freq; 7228 sta_ctx->conn_info.auth_type = eCSR_AUTH_TYPE_OPEN_SYSTEM; 7229 hdd_roam_profile_init(link_info); 7230 } 7231 7232 static void hdd_vdev_set_ht_vht_ies(mac_handle_t mac_handle, 7233 struct wlan_objmgr_vdev *vdev) 7234 { 7235 QDF_STATUS status; 7236 struct wlan_objmgr_psoc *psoc; 7237 bool bval = false; 7238 7239 psoc = wlan_vdev_get_psoc(vdev); 7240 status = ucfg_mlme_get_vht_enable2x2(psoc, &bval); 7241 if (QDF_IS_STATUS_ERROR(status)) 7242 hdd_err("unable to get vht_enable2x2"); 7243 7244 sme_set_pdev_ht_vht_ies(mac_handle, bval); 7245 sme_set_vdev_ies_per_band(mac_handle, wlan_vdev_get_id(vdev), 7246 wlan_vdev_mlme_get_opmode(vdev)); 7247 } 7248 7249 static void 7250 hdd_vdev_configure_rtt_mac_randomization(struct wlan_objmgr_psoc *psoc, 7251 struct wlan_objmgr_vdev *vdev) 7252 { 7253 int errno; 7254 QDF_STATUS status; 7255 bool bval = false; 7256 7257 status = ucfg_mlme_get_rtt_mac_randomization(psoc, &bval); 7258 if (QDF_IS_STATUS_ERROR(status)) 7259 hdd_err("unable to get RTT MAC randomization value"); 7260 7261 hdd_debug("setting RTT mac randomization param: %d", bval); 7262 errno = sme_cli_set_command( 7263 wlan_vdev_get_id(vdev), 7264 wmi_vdev_param_enable_disable_rtt_initiator_random_mac, 7265 bval, VDEV_CMD); 7266 7267 if (errno) 7268 hdd_err("RTT mac randomization param set failed %d", errno); 7269 } 7270 7271 static void 7272 hdd_vdev_configure_max_tdls_params(struct wlan_objmgr_psoc *psoc, 7273 struct wlan_objmgr_vdev *vdev) 7274 { 7275 uint16_t max_peer_count; 7276 bool target_bigtk_support = false; 7277 7278 /* Max peer can be tdls peers + self peer + bss peer */ 7279 max_peer_count = cfg_tdls_get_max_peer_count(psoc); 7280 max_peer_count += 2; 7281 wlan_vdev_set_max_peer_count(vdev, max_peer_count); 7282 7283 ucfg_mlme_get_bigtk_support(psoc, &target_bigtk_support); 7284 if (target_bigtk_support) 7285 mlme_set_bigtk_support(vdev, true); 7286 } 7287 7288 static inline void 7289 hdd_vdev_configure_nan_params(struct wlan_objmgr_psoc *psoc, 7290 struct wlan_objmgr_vdev *vdev) 7291 { 7292 sme_cli_set_command( 7293 wlan_vdev_get_id(vdev), 7294 wmi_vdev_param_allow_nan_initial_discovery_of_mp0_cluster, 7295 cfg_nan_get_support_mp0_discovery(psoc), VDEV_CMD); 7296 } 7297 7298 #if defined(WLAN_FEATURE_11BE_MLO) && defined(WLAN_EXTERNAL_AUTH_MLO_SUPPORT) 7299 static void 7300 hdd_set_vdev_mlo_external_sae_auth_conversion(struct wlan_objmgr_vdev *vdev, 7301 enum QDF_OPMODE mode) 7302 { 7303 if (mode == QDF_STA_MODE || mode == QDF_SAP_MODE) 7304 wlan_vdev_set_mlo_external_sae_auth_conversion(vdev, true); 7305 } 7306 #else 7307 static inline void 7308 hdd_set_vdev_mlo_external_sae_auth_conversion(struct wlan_objmgr_vdev *vdev, 7309 enum QDF_OPMODE mode) 7310 { 7311 } 7312 #endif 7313 7314 static void 7315 hdd_vdev_configure_opmode_params(struct hdd_context *hdd_ctx, 7316 struct wlan_objmgr_vdev *vdev) 7317 { 7318 struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc; 7319 enum QDF_OPMODE opmode = wlan_vdev_mlme_get_opmode(vdev); 7320 7321 switch (opmode) { 7322 case QDF_STA_MODE: 7323 hdd_vdev_configure_rtt_mac_randomization(psoc, vdev); 7324 hdd_vdev_configure_max_tdls_params(psoc, vdev); 7325 break; 7326 case QDF_P2P_CLIENT_MODE: 7327 hdd_vdev_configure_max_tdls_params(psoc, vdev); 7328 break; 7329 case QDF_NAN_DISC_MODE: 7330 hdd_vdev_configure_nan_params(psoc, vdev); 7331 break; 7332 default: 7333 break; 7334 } 7335 7336 ucfg_fwol_configure_vdev_params(psoc, vdev); 7337 hdd_set_vdev_mlo_external_sae_auth_conversion(vdev, opmode); 7338 hdd_store_nss_chains_cfg_in_vdev(hdd_ctx, vdev); 7339 } 7340 7341 #if defined(WLAN_FEATURE_11BE_MLO) && defined(CFG80211_11BE_BASIC) && \ 7342 defined(WLAN_HDD_MULTI_VDEV_SINGLE_NDEV) 7343 static int 7344 hdd_populate_vdev_create_params(struct wlan_hdd_link_info *link_info, 7345 struct wlan_vdev_create_params *vdev_params) 7346 { 7347 struct hdd_adapter *adapter = link_info->adapter; 7348 7349 vdev_params->opmode = adapter->device_mode; 7350 vdev_params->size_vdev_priv = sizeof(struct vdev_osif_priv); 7351 7352 if (hdd_adapter_is_ml_adapter(adapter)) { 7353 qdf_ether_addr_copy(vdev_params->mldaddr, 7354 adapter->mac_addr.bytes); 7355 qdf_ether_addr_copy(vdev_params->macaddr, 7356 link_info->link_addr.bytes); 7357 } else { 7358 qdf_ether_addr_copy(vdev_params->macaddr, 7359 adapter->mac_addr.bytes); 7360 } 7361 return 0; 7362 } 7363 #elif defined(WLAN_FEATURE_11BE_MLO) && defined(CFG80211_11BE_BASIC) 7364 static int 7365 hdd_populate_vdev_create_params(struct wlan_hdd_link_info *link_info, 7366 struct wlan_vdev_create_params *vdev_params) 7367 { 7368 struct hdd_adapter *adapter = link_info->adapter; 7369 struct hdd_mlo_adapter_info *mlo_adapter_info; 7370 struct hdd_adapter *link_adapter; 7371 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); 7372 bool eht_capab; 7373 7374 hdd_enter_dev(adapter->dev); 7375 mlo_adapter_info = &adapter->mlo_adapter_info; 7376 7377 ucfg_psoc_mlme_get_11be_capab(hdd_ctx->psoc, &eht_capab); 7378 if (mlo_adapter_info->is_ml_adapter && eht_capab && 7379 adapter->device_mode == QDF_STA_MODE) { 7380 link_adapter = hdd_get_assoc_link_adapter(adapter); 7381 if (link_adapter) { 7382 qdf_ether_addr_copy(vdev_params->macaddr, 7383 link_adapter->mac_addr.bytes); 7384 } else { 7385 return -EINVAL; 7386 } 7387 } else { 7388 qdf_ether_addr_copy(vdev_params->macaddr, 7389 adapter->mac_addr.bytes); 7390 } 7391 7392 vdev_params->opmode = adapter->device_mode; 7393 7394 if (eht_capab) { 7395 qdf_ether_addr_copy(vdev_params->mldaddr, 7396 adapter->mld_addr.bytes); 7397 } 7398 7399 vdev_params->size_vdev_priv = sizeof(struct vdev_osif_priv); 7400 hdd_exit(); 7401 7402 return 0; 7403 } 7404 #else 7405 static int 7406 hdd_populate_vdev_create_params(struct wlan_hdd_link_info *link_info, 7407 struct wlan_vdev_create_params *vdev_params) 7408 { 7409 struct hdd_adapter *adapter = link_info->adapter; 7410 7411 vdev_params->opmode = adapter->device_mode; 7412 qdf_ether_addr_copy(vdev_params->macaddr, adapter->mac_addr.bytes); 7413 vdev_params->size_vdev_priv = sizeof(struct vdev_osif_priv); 7414 return 0; 7415 } 7416 #endif 7417 7418 int hdd_vdev_create(struct wlan_hdd_link_info *link_info) 7419 { 7420 QDF_STATUS status; 7421 int errno = 0; 7422 struct hdd_adapter *adapter = link_info->adapter; 7423 struct hdd_context *hdd_ctx; 7424 struct wlan_objmgr_vdev *vdev; 7425 struct wlan_vdev_create_params vdev_params = {0}; 7426 7427 hdd_nofl_debug("creating new vdev"); 7428 7429 /* do vdev create via objmgr */ 7430 hdd_ctx = WLAN_HDD_GET_CTX(adapter); 7431 7432 errno = hdd_populate_vdev_create_params(link_info, &vdev_params); 7433 if (errno) 7434 return errno; 7435 7436 vdev = sme_vdev_create(hdd_ctx->mac_handle, &vdev_params); 7437 if (!vdev) { 7438 hdd_err("failed to create vdev"); 7439 return -EINVAL; 7440 } 7441 7442 if (wlan_objmgr_vdev_try_get_ref(vdev, WLAN_HDD_ID_OBJ_MGR) != 7443 QDF_STATUS_SUCCESS) { 7444 errno = QDF_STATUS_E_INVAL; 7445 sme_vdev_delete(hdd_ctx->mac_handle, vdev); 7446 return -EINVAL; 7447 } 7448 7449 hdd_store_vdev_info(link_info, vdev); 7450 osif_cm_osif_priv_init(vdev); 7451 7452 if (hdd_adapter_is_ml_adapter(adapter)) 7453 hdd_mlo_t2lm_register_callback(vdev); 7454 7455 set_bit(SME_SESSION_OPENED, &link_info->link_flags); 7456 status = sme_vdev_post_vdev_create_setup(hdd_ctx->mac_handle, vdev); 7457 if (QDF_IS_STATUS_ERROR(status)) { 7458 hdd_err("Failed to setup the vdev"); 7459 errno = qdf_status_to_os_return(status); 7460 goto hdd_vdev_destroy_procedure; 7461 } 7462 7463 /* firmware ready for component communication, raise vdev_ready event */ 7464 errno = hdd_vdev_ready(vdev, 7465 (struct qdf_mac_addr *)hdd_ctx->bridgeaddr); 7466 if (errno) { 7467 hdd_err("failed to dispatch vdev ready event: %d", errno); 7468 goto hdd_vdev_destroy_procedure; 7469 } 7470 7471 hdd_vdev_configure_opmode_params(hdd_ctx, vdev); 7472 7473 hdd_nofl_debug("vdev %d created successfully", link_info->vdev_id); 7474 7475 return errno; 7476 7477 hdd_vdev_destroy_procedure: 7478 QDF_BUG(!hdd_vdev_destroy(link_info)); 7479 7480 return errno; 7481 } 7482 7483 QDF_STATUS hdd_init_station_mode(struct wlan_hdd_link_info *link_info) 7484 { 7485 struct hdd_adapter *adapter = link_info->adapter; 7486 struct hdd_context *hdd_ctx; 7487 QDF_STATUS status; 7488 mac_handle_t mac_handle; 7489 uint32_t roam_triggers; 7490 struct wlan_objmgr_vdev *vdev; 7491 7492 hdd_ctx = WLAN_HDD_GET_CTX(adapter); 7493 mac_handle = hdd_ctx->mac_handle; 7494 7495 vdev = hdd_objmgr_get_vdev_by_user(link_info, WLAN_INIT_DEINIT_ID); 7496 if (!vdev) { 7497 status = QDF_STATUS_E_NULL_VALUE; 7498 goto vdev_destroy; 7499 } 7500 7501 hdd_vdev_set_ht_vht_ies(mac_handle, vdev); 7502 hdd_init_station_context(link_info); 7503 7504 status = hdd_wmm_adapter_init(adapter); 7505 if (QDF_STATUS_SUCCESS != status) { 7506 hdd_err("hdd_wmm_adapter_init() failed, status code %08d [x%08x]", 7507 status, status); 7508 goto error_wmm_init; 7509 } 7510 set_bit(WMM_INIT_DONE, &adapter->event_flags); 7511 7512 /* rcpi info initialization */ 7513 qdf_mem_zero(&adapter->rcpi, sizeof(adapter->rcpi)); 7514 7515 if (adapter->device_mode == QDF_STA_MODE) { 7516 roam_triggers = ucfg_mlme_get_roaming_triggers(hdd_ctx->psoc); 7517 mlme_set_roam_trigger_bitmap(hdd_ctx->psoc, 7518 link_info->vdev_id, 7519 roam_triggers); 7520 7521 status = hdd_vdev_configure_rtt_params(vdev); 7522 if (QDF_IS_STATUS_ERROR(status)) 7523 goto error_wmm_init; 7524 } 7525 7526 hdd_objmgr_put_vdev_by_user(vdev, WLAN_INIT_DEINIT_ID); 7527 return QDF_STATUS_SUCCESS; 7528 7529 error_wmm_init: 7530 hdd_objmgr_put_vdev_by_user(vdev, WLAN_INIT_DEINIT_ID); 7531 7532 vdev_destroy: 7533 QDF_BUG(!hdd_vdev_destroy(link_info)); 7534 7535 return status; 7536 } 7537 7538 static char *net_dev_ref_debug_string_from_id(wlan_net_dev_ref_dbgid dbgid) 7539 { 7540 static const char *strings[] = { 7541 "NET_DEV_HOLD_ID_RESERVED", 7542 "NET_DEV_HOLD_GET_STA_CONNECTION_IN_PROGRESS", 7543 "NET_DEV_HOLD_CHECK_DFS_CHANNEL_FOR_ADAPTER", 7544 "NET_DEV_HOLD_GET_SAP_OPERATING_BAND", 7545 "NET_DEV_HOLD_RECOVERY_NOTIFIER_CALL", 7546 "NET_DEV_HOLD_IS_ANY_STA_CONNECTING", 7547 "NET_DEV_HOLD_SAP_DESTROY_CTX_ALL", 7548 "NET_DEV_HOLD_DRV_CMD_MAX_TX_POWER", 7549 "NET_DEV_HOLD_IPA_SET_TX_FLOW_INFO", 7550 "NET_DEV_HOLD_SET_RPS_CPU_MASK", 7551 "NET_DEV_HOLD_DFS_INDICATE_RADAR", 7552 "NET_DEV_HOLD_MAX_STA_INTERFACE_UP_COUNT_REACHED", 7553 "NET_DEV_HOLD_IS_CHAN_SWITCH_IN_PROGRESS", 7554 "NET_DEV_HOLD_STA_DESTROY_CTX_ALL", 7555 "NET_DEV_HOLD_CHECK_FOR_EXISTING_MACADDR", 7556 "NET_DEV_HOLD_DEINIT_ALL_ADAPTERS", 7557 "NET_DEV_HOLD_STOP_ALL_ADAPTERS", 7558 "NET_DEV_HOLD_RESET_ALL_ADAPTERS", 7559 "NET_DEV_HOLD_IS_ANY_INTERFACE_OPEN", 7560 "NET_DEV_HOLD_START_ALL_ADAPTERS", 7561 "NET_DEV_HOLD_GET_ADAPTER_BY_RAND_MACADDR", 7562 "NET_DEV_HOLD_GET_ADAPTER_BY_MACADDR", 7563 "NET_DEV_HOLD_GET_ADAPTER_BY_VDEV", 7564 "NET_DEV_HOLD_ADAPTER_GET_BY_REFERENCE", 7565 "NET_DEV_HOLD_GET_ADAPTER_BY_IFACE_NAME", 7566 "NET_DEV_HOLD_GET_ADAPTER", 7567 "NET_DEV_HOLD_GET_OPERATING_CHAN_FREQ", 7568 "NET_DEV_HOLD_UNREGISTER_WEXT_ALL_ADAPTERS", 7569 "NET_DEV_HOLD_ABORT_MAC_SCAN_ALL_ADAPTERS", 7570 "NET_DEV_HOLD_ABORT_SCHED_SCAN_ALL_ADAPTERS", 7571 "NET_DEV_HOLD_GET_FIRST_VALID_ADAPTER", 7572 "NET_DEV_HOLD_CLEAR_RPS_CPU_MASK", 7573 "NET_DEV_HOLD_BUS_BW_WORK_HANDLER", 7574 "NET_DEV_HOLD_DISPLAY_NETIF_QUEUE_HISTORY_COMPACT", 7575 "NET_DEV_HOLD_DISPLAY_NETIF_QUEUE_HISTORY", 7576 "NET_DEV_HOLD_CLEAR_NETIF_QUEUE_HISTORY", 7577 "NET_DEV_HOLD_UNSAFE_CHANNEL_RESTART_SAP", 7578 "NET_DEV_HOLD_INDICATE_MGMT_FRAME", 7579 "NET_DEV_HOLD_STATE_INFO_DUMP", 7580 "NET_DEV_HOLD_DISABLE_ROAMING", 7581 "NET_DEV_HOLD_ENABLE_ROAMING", 7582 "NET_DEV_HOLD_AUTO_SHUTDOWN_ENABLE", 7583 "NET_DEV_HOLD_GET_CON_SAP_ADAPTER", 7584 "NET_DEV_HOLD_IS_ANY_ADAPTER_CONNECTED", 7585 "NET_DEV_HOLD_IS_ROAMING_IN_PROGRESS", 7586 "NET_DEV_HOLD_DEL_P2P_INTERFACE", 7587 "NET_DEV_HOLD_IS_NDP_ALLOWED", 7588 "NET_DEV_HOLD_NDI_OPEN", 7589 "NET_DEV_HOLD_SEND_OEM_REG_RSP_NLINK_MSG", 7590 "NET_DEV_HOLD_PERIODIC_STA_STATS_DISPLAY", 7591 "NET_DEV_HOLD_SUSPEND_WLAN", 7592 "NET_DEV_HOLD_RESUME_WLAN", 7593 "NET_DEV_HOLD_SSR_RESTART_SAP", 7594 "NET_DEV_HOLD_SEND_DEFAULT_SCAN_IES", 7595 "NET_DEV_HOLD_CFG80211_SUSPEND_WLAN", 7596 "NET_DEV_HOLD_COUNTRY_CHANGE_UPDATE_STA", 7597 "NET_DEV_HOLD_COUNTRY_CHANGE_UPDATE_SAP", 7598 "NET_DEV_HOLD_CACHE_STATION_STATS_CB", 7599 "NET_DEV_HOLD_DISPLAY_TXRX_STATS", 7600 "NET_DEV_HOLD_START_PRE_CAC_TRANS", 7601 "NET_DEV_HOLD_IS_ANY_STA_CONNECTED", 7602 "NET_DEV_HOLD_GET_ADAPTER_BY_BSSID", 7603 "NET_DEV_HOLD_ID_MAX"}; 7604 int32_t num_dbg_strings = QDF_ARRAY_SIZE(strings); 7605 7606 if (dbgid >= num_dbg_strings) { 7607 char *ret = ""; 7608 7609 hdd_err("Debug string not found for debug id %d", dbgid); 7610 return ret; 7611 } 7612 7613 return (char *)strings[dbgid]; 7614 } 7615 7616 void hdd_check_for_net_dev_ref_leak(struct hdd_adapter *adapter) 7617 { 7618 int i, id; 7619 7620 for (id = 0; id < NET_DEV_HOLD_ID_MAX; id++) { 7621 for (i = 0; i < MAX_NET_DEV_REF_LEAK_ITERATIONS; i++) { 7622 if (!qdf_atomic_read( 7623 &adapter->net_dev_hold_ref_count[id])) 7624 break; 7625 hdd_info("net_dev held for debug id %s", 7626 net_dev_ref_debug_string_from_id(id)); 7627 qdf_sleep(NET_DEV_REF_LEAK_ITERATION_SLEEP_TIME_MS); 7628 } 7629 if (i == MAX_NET_DEV_REF_LEAK_ITERATIONS) { 7630 hdd_err("net_dev hold reference leak detected for debug id: %s", 7631 net_dev_ref_debug_string_from_id(id)); 7632 QDF_BUG(0); 7633 } 7634 } 7635 } 7636 7637 /** 7638 * hdd_deinit_station_mode() - De-initialize the station adapter 7639 * @adapter: HDD adapter pointer 7640 * 7641 * This function De-initializes the STA/P2P/OCB adapter. 7642 * 7643 * Return: None. 7644 */ 7645 static void hdd_deinit_station_mode(struct hdd_adapter *adapter) 7646 { 7647 if (test_bit(WMM_INIT_DONE, &adapter->event_flags)) { 7648 hdd_wmm_adapter_close(adapter); 7649 clear_bit(WMM_INIT_DONE, &adapter->event_flags); 7650 } 7651 } 7652 7653 void hdd_deinit_session(struct hdd_adapter *adapter) 7654 { 7655 struct wlan_hdd_link_info *link_info; 7656 7657 hdd_enter(); 7658 7659 switch (adapter->device_mode) { 7660 case QDF_STA_MODE: 7661 case QDF_P2P_CLIENT_MODE: 7662 case QDF_MONITOR_MODE: 7663 case QDF_P2P_DEVICE_MODE: 7664 case QDF_NDI_MODE: 7665 case QDF_NAN_DISC_MODE: 7666 { 7667 hdd_deinit_station_mode(adapter); 7668 break; 7669 } 7670 7671 case QDF_SAP_MODE: 7672 case QDF_P2P_GO_MODE: 7673 { 7674 hdd_adapter_for_each_active_link_info(adapter, link_info) 7675 hdd_deinit_ap_mode(link_info); 7676 break; 7677 } 7678 7679 default: 7680 break; 7681 } 7682 7683 if (adapter->scan_info.default_scan_ies) { 7684 qdf_mem_free(adapter->scan_info.default_scan_ies); 7685 adapter->scan_info.default_scan_ies = NULL; 7686 adapter->scan_info.default_scan_ies_len = 0; 7687 } 7688 7689 hdd_exit(); 7690 } 7691 7692 void hdd_deinit_adapter(struct hdd_context *hdd_ctx, 7693 struct hdd_adapter *adapter, 7694 bool rtnl_held) 7695 { 7696 hdd_enter_dev(adapter->dev); 7697 7698 hdd_wext_unregister(adapter->dev, rtnl_held); 7699 hdd_deinit_session(adapter); 7700 hdd_exit(); 7701 } 7702 7703 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0)) && \ 7704 defined(WLAN_FEATURE_11AX) 7705 /** 7706 * hdd_cleanup_he_operation_info() - cleanup he operation info 7707 * @link_info: pointer to link_info struct in adapter 7708 * 7709 * This function destroys he operation information 7710 * 7711 * Return: none 7712 */ 7713 static void hdd_cleanup_he_operation_info(struct wlan_hdd_link_info *link_info) 7714 { 7715 struct hdd_station_ctx *hdd_sta_ctx; 7716 7717 hdd_debug("cleanup he operation info"); 7718 7719 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(link_info); 7720 7721 if (hdd_sta_ctx->cache_conn_info.he_operation) { 7722 qdf_mem_free(hdd_sta_ctx->cache_conn_info.he_operation); 7723 hdd_sta_ctx->cache_conn_info.he_operation = NULL; 7724 } 7725 } 7726 #else 7727 static inline void 7728 hdd_cleanup_he_operation_info(struct wlan_hdd_link_info *link_info) 7729 { 7730 } 7731 #endif 7732 7733 /** 7734 * hdd_cleanup_prev_ap_bcn_ie() - cleanup previous ap beacon ie 7735 * @link_info: pointer to link_info struct in adapter 7736 * 7737 * This function destroys previous ap beacon information 7738 * 7739 * Return: none 7740 */ 7741 static void hdd_cleanup_prev_ap_bcn_ie(struct wlan_hdd_link_info *link_info) 7742 { 7743 struct hdd_station_ctx *hdd_sta_ctx; 7744 struct element_info *bcn_ie; 7745 7746 hdd_debug("cleanup previous ap bcn ie"); 7747 7748 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(link_info); 7749 bcn_ie = &hdd_sta_ctx->conn_info.prev_ap_bcn_ie; 7750 7751 if (bcn_ie->ptr) { 7752 qdf_mem_free(bcn_ie->ptr); 7753 bcn_ie->ptr = NULL; 7754 bcn_ie->len = 0; 7755 } 7756 } 7757 7758 void hdd_cleanup_conn_info(struct wlan_hdd_link_info *link_info) 7759 { 7760 hdd_cleanup_he_operation_info(link_info); 7761 hdd_cleanup_prev_ap_bcn_ie(link_info); 7762 } 7763 7764 /** 7765 * hdd_sta_destroy_ctx_all() - cleanup all station contexts 7766 * @hdd_ctx: Global HDD context 7767 * 7768 * This function destroys all the station contexts 7769 * 7770 * Return: none 7771 */ 7772 static void hdd_sta_destroy_ctx_all(struct hdd_context *hdd_ctx) 7773 { 7774 struct hdd_adapter *adapter, *next_adapter = NULL; 7775 struct wlan_hdd_link_info *link_info; 7776 7777 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 7778 NET_DEV_HOLD_STA_DESTROY_CTX_ALL) { 7779 if (adapter->device_mode == QDF_STA_MODE) { 7780 hdd_adapter_for_each_link_info(adapter, link_info) { 7781 hdd_cleanup_conn_info(link_info); 7782 } 7783 } 7784 hdd_adapter_dev_put_debug(adapter, 7785 NET_DEV_HOLD_STA_DESTROY_CTX_ALL); 7786 } 7787 } 7788 7789 #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 12, 0) 7790 static void 7791 hdd_unregister_netdevice(struct hdd_adapter *adapter, struct net_device *dev) 7792 { 7793 if (adapter->is_virtual_iface) { 7794 wlan_cfg80211_unregister_netdevice(dev); 7795 adapter->is_virtual_iface = false; 7796 } else { 7797 unregister_netdevice(dev); 7798 } 7799 } 7800 #else 7801 static void 7802 hdd_unregister_netdevice(struct hdd_adapter *adapter, struct net_device *dev) 7803 { 7804 unregister_netdevice(dev); 7805 } 7806 #endif 7807 7808 static inline void hdd_adapter_destroy_vdev_info(struct hdd_adapter *adapter) 7809 { 7810 struct wlan_hdd_link_info *link_info; 7811 7812 hdd_adapter_for_each_link_info(adapter, link_info) { 7813 qdf_event_destroy(&link_info->acs_complete_event); 7814 qdf_spinlock_destroy(&link_info->vdev_lock); 7815 } 7816 } 7817 7818 static void hdd_cleanup_adapter(struct hdd_context *hdd_ctx, 7819 struct hdd_adapter *adapter, 7820 bool rtnl_held) 7821 { 7822 struct net_device *dev = NULL; 7823 7824 if (adapter) 7825 dev = adapter->dev; 7826 else { 7827 hdd_err("adapter is Null"); 7828 return; 7829 } 7830 7831 hdd_apf_context_destroy(adapter); 7832 qdf_spinlock_destroy(&adapter->mc_list_lock); 7833 hdd_adapter_destroy_vdev_info(adapter); 7834 hdd_sta_info_deinit(&adapter->sta_info_list); 7835 hdd_sta_info_deinit(&adapter->cache_sta_info_list); 7836 7837 wlan_hdd_debugfs_csr_deinit(adapter); 7838 7839 hdd_debugfs_exit(adapter); 7840 7841 /* 7842 * The adapter is marked as closed. When hdd_wlan_exit() call returns, 7843 * the driver is almost closed and cannot handle either control 7844 * messages or data. However, unregister_netdevice() call above will 7845 * eventually invoke hdd_stop(ndo_close) driver callback, which attempts 7846 * to close the active connections(basically excites control path) which 7847 * is not right. Setting this flag helps hdd_stop() to recognize that 7848 * the interface is closed and restricts any operations on that 7849 */ 7850 clear_bit(DEVICE_IFACE_OPENED, &adapter->event_flags); 7851 7852 if (test_bit(NET_DEVICE_REGISTERED, &adapter->event_flags)) { 7853 if (rtnl_held) { 7854 hdd_debug("hdd_unregister_netdevice(%s) type:%d", 7855 dev->name, adapter->device_mode); 7856 hdd_unregister_netdevice(adapter, dev); 7857 } else { 7858 hdd_debug("unregister_netdev(%s) type:%d", dev->name, 7859 adapter->device_mode); 7860 unregister_netdev(dev); 7861 } 7862 /* 7863 * Note that the adapter is no longer valid at this point 7864 * since the memory has been reclaimed 7865 */ 7866 } 7867 } 7868 7869 static QDF_STATUS hdd_check_for_existing_macaddr(struct hdd_context *hdd_ctx, 7870 tSirMacAddr mac_addr) 7871 { 7872 struct hdd_adapter *adapter, *next_adapter = NULL; 7873 wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_CHECK_FOR_EXISTING_MACADDR; 7874 7875 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 7876 dbgid) { 7877 if (!qdf_mem_cmp(adapter->mac_addr.bytes, 7878 mac_addr, sizeof(tSirMacAddr))) { 7879 hdd_adapter_dev_put_debug(adapter, dbgid); 7880 if (next_adapter) 7881 hdd_adapter_dev_put_debug(next_adapter, 7882 dbgid); 7883 return QDF_STATUS_E_FAILURE; 7884 } 7885 hdd_adapter_dev_put_debug(adapter, dbgid); 7886 } 7887 7888 return QDF_STATUS_SUCCESS; 7889 } 7890 7891 /** 7892 * hdd_configure_chain_mask() - programs chain mask to firmware 7893 * @adapter: HDD adapter 7894 * 7895 * Return: 0 on success or errno on failure 7896 */ 7897 static int hdd_configure_chain_mask(struct hdd_adapter *adapter) 7898 { 7899 QDF_STATUS status; 7900 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); 7901 7902 status = ucfg_mlme_configure_chain_mask(hdd_ctx->psoc, 7903 adapter->deflink->vdev_id); 7904 if (QDF_IS_STATUS_ERROR(status)) 7905 goto error; 7906 7907 return 0; 7908 7909 error: 7910 hdd_debug("WMI PDEV set param failed"); 7911 return -EINVAL; 7912 } 7913 7914 void hdd_adapter_update_mlo_mgr_mac_addr(struct hdd_adapter *adapter) 7915 { 7916 int i = 0; 7917 struct wlan_hdd_link_info *link_info; 7918 struct wlan_mlo_link_mac_update link_mac = {0}; 7919 7920 if (!hdd_adapter_is_ml_adapter(adapter)) 7921 return; 7922 7923 hdd_adapter_for_each_link_info(adapter, link_info) { 7924 link_mac.link_mac_info[i].vdev_id = link_info->vdev_id; 7925 qdf_copy_macaddr(&link_mac.link_mac_info[i++].link_mac_addr, 7926 &link_info->link_addr); 7927 } 7928 7929 link_mac.num_mac_update = i; 7930 mlo_mgr_update_link_info_mac_addr(adapter->deflink->vdev, &link_mac); 7931 } 7932 7933 /** 7934 * hdd_send_coex_config_params() - Send coex config params to FW 7935 * @hdd_ctx: HDD context 7936 * @adapter: Primary adapter context 7937 * 7938 * This function is used to send all coex config related params to FW 7939 * 7940 * Return: 0 on success and -EINVAL on failure 7941 */ 7942 static int hdd_send_coex_config_params(struct hdd_context *hdd_ctx, 7943 struct hdd_adapter *adapter) 7944 { 7945 struct coex_config_params coex_cfg_params = {0}; 7946 struct wlan_fwol_coex_config config = {0}; 7947 struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc; 7948 enum coex_btc_chain_mode btc_chain_mode; 7949 QDF_STATUS status; 7950 7951 if (!adapter) { 7952 hdd_err("adapter is invalid"); 7953 goto err; 7954 } 7955 7956 if (!psoc) { 7957 hdd_err("HDD psoc is invalid"); 7958 goto err; 7959 } 7960 7961 status = ucfg_fwol_get_coex_config_params(psoc, &config); 7962 if (QDF_IS_STATUS_ERROR(status)) { 7963 hdd_err("Unable to get coex config params"); 7964 goto err; 7965 } 7966 7967 coex_cfg_params.vdev_id = adapter->deflink->vdev_id; 7968 coex_cfg_params.config_type = WMI_COEX_CONFIG_TX_POWER; 7969 coex_cfg_params.config_arg1 = config.max_tx_power_for_btc; 7970 7971 wma_nofl_debug("TXP[W][send_coex_cfg]: %d", 7972 config.max_tx_power_for_btc); 7973 7974 status = sme_send_coex_config_cmd(&coex_cfg_params); 7975 if (QDF_IS_STATUS_ERROR(status)) { 7976 hdd_err("Failed to send coex Tx power"); 7977 goto err; 7978 } 7979 7980 coex_cfg_params.config_type = WMI_COEX_CONFIG_HANDOVER_RSSI; 7981 coex_cfg_params.config_arg1 = config.wlan_low_rssi_threshold; 7982 7983 status = sme_send_coex_config_cmd(&coex_cfg_params); 7984 if (QDF_IS_STATUS_ERROR(status)) { 7985 hdd_err("Failed to send coex handover RSSI"); 7986 goto err; 7987 } 7988 7989 coex_cfg_params.config_type = WMI_COEX_CONFIG_BTC_MODE; 7990 7991 /* Modify BTC_MODE according to BTC_CHAIN_MODE */ 7992 status = ucfg_coex_psoc_get_btc_chain_mode(psoc, &btc_chain_mode); 7993 if (QDF_IS_STATUS_ERROR(status)) { 7994 hdd_err("Failed to get btc chain mode"); 7995 btc_chain_mode = WLAN_COEX_BTC_CHAIN_MODE_UNSETTLED; 7996 } 7997 7998 if (btc_chain_mode <= WLAN_COEX_BTC_CHAIN_MODE_HYBRID) 7999 coex_cfg_params.config_arg1 = btc_chain_mode; 8000 else 8001 coex_cfg_params.config_arg1 = config.btc_mode; 8002 8003 hdd_debug("Configured BTC mode is %d, BTC chain mode is 0x%x, set BTC mode to %d", 8004 config.btc_mode, btc_chain_mode, 8005 coex_cfg_params.config_arg1); 8006 status = sme_send_coex_config_cmd(&coex_cfg_params); 8007 if (QDF_IS_STATUS_ERROR(status)) { 8008 hdd_err("Failed to send coex BTC mode"); 8009 goto err; 8010 } 8011 8012 coex_cfg_params.config_type = WMI_COEX_CONFIG_ANTENNA_ISOLATION; 8013 coex_cfg_params.config_arg1 = config.antenna_isolation; 8014 8015 status = sme_send_coex_config_cmd(&coex_cfg_params); 8016 if (QDF_IS_STATUS_ERROR(status)) { 8017 hdd_err("Failed to send coex antenna isolation"); 8018 goto err; 8019 } 8020 8021 coex_cfg_params.config_type = WMI_COEX_CONFIG_BT_LOW_RSSI_THRESHOLD; 8022 coex_cfg_params.config_arg1 = config.bt_low_rssi_threshold; 8023 8024 status = sme_send_coex_config_cmd(&coex_cfg_params); 8025 if (QDF_IS_STATUS_ERROR(status)) { 8026 hdd_err("Failed to send coex BT low RSSI threshold"); 8027 goto err; 8028 } 8029 8030 coex_cfg_params.config_type = WMI_COEX_CONFIG_BT_INTERFERENCE_LEVEL; 8031 coex_cfg_params.config_arg1 = config.bt_interference_low_ll; 8032 coex_cfg_params.config_arg2 = config.bt_interference_low_ul; 8033 coex_cfg_params.config_arg3 = config.bt_interference_medium_ll; 8034 coex_cfg_params.config_arg4 = config.bt_interference_medium_ul; 8035 coex_cfg_params.config_arg5 = config.bt_interference_high_ll; 8036 coex_cfg_params.config_arg6 = config.bt_interference_high_ul; 8037 8038 status = sme_send_coex_config_cmd(&coex_cfg_params); 8039 if (QDF_IS_STATUS_ERROR(status)) { 8040 hdd_err("Failed to send coex BT interference level"); 8041 goto err; 8042 } 8043 8044 if (wlan_hdd_mpta_helper_enable(&coex_cfg_params, &config)) 8045 goto err; 8046 8047 coex_cfg_params.config_type = 8048 WMI_COEX_CONFIG_BT_SCO_ALLOW_WLAN_2G_SCAN; 8049 coex_cfg_params.config_arg1 = config.bt_sco_allow_wlan_2g_scan; 8050 8051 status = sme_send_coex_config_cmd(&coex_cfg_params); 8052 if (QDF_IS_STATUS_ERROR(status)) { 8053 hdd_err("Failed to send coex BT sco allow wlan 2g scan"); 8054 goto err; 8055 } 8056 8057 coex_cfg_params.config_type = 8058 WMI_COEX_CONFIG_LE_SCAN_POLICY; 8059 coex_cfg_params.config_arg1 = config.ble_scan_coex_policy; 8060 8061 status = sme_send_coex_config_cmd(&coex_cfg_params); 8062 if (QDF_IS_STATUS_ERROR(status)) { 8063 hdd_err("Failed to send coex BLE scan policy"); 8064 goto err; 8065 } 8066 8067 #ifdef FEATURE_COEX_TPUT_SHAPING_CONFIG 8068 coex_cfg_params.config_type = 8069 WMI_COEX_CONFIG_ENABLE_TPUT_SHAPING; 8070 coex_cfg_params.config_arg1 = config.coex_tput_shaping_enable; 8071 8072 status = sme_send_coex_config_cmd(&coex_cfg_params); 8073 if (QDF_IS_STATUS_ERROR(status)) { 8074 hdd_err("Failed to send coex traffic shaping value %d", 8075 coex_cfg_params.config_arg1); 8076 goto err; 8077 } 8078 #endif 8079 return 0; 8080 err: 8081 return -EINVAL; 8082 } 8083 8084 #define MAX_PDEV_SET_FW_PARAMS 7 8085 /* params being sent: 8086 * 1.wmi_pdev_param_dtim_synth 8087 * 2.wmi_pdev_param_1ch_dtim_optimized_chain_selection 8088 * 3.wmi_pdev_param_tx_sch_delay 8089 * 4.wmi_pdev_param_en_update_scram_seed 8090 * 5.wmi_pdev_param_secondary_retry_enable 8091 * 6.wmi_pdev_param_set_sap_xlna_bypass 8092 * 7.wmi_pdev_param_set_dfs_chan_ageout_time 8093 */ 8094 8095 /** 8096 * hdd_set_fw_params() - Set parameters to firmware 8097 * @adapter: HDD adapter 8098 * 8099 * This function Sets various parameters to fw once the 8100 * adapter is started. 8101 * 8102 * Return: 0 on success or errno on failure 8103 */ 8104 int hdd_set_fw_params(struct hdd_adapter *adapter) 8105 { 8106 int ret; 8107 uint16_t upper_brssi_thresh, lower_brssi_thresh, rts_profile; 8108 bool enable_dtim_1chrx; 8109 QDF_STATUS status; 8110 struct hdd_context *hdd_ctx; 8111 bool is_lprx_enabled; 8112 bool bval = false; 8113 uint8_t enable_tx_sch_delay, dfs_chan_ageout_time; 8114 uint32_t dtim_sel_diversity, enable_secondary_rate; 8115 bool sap_xlna_bypass; 8116 bool enable_ofdm_scrambler_seed = false; 8117 struct dev_set_param setparam[MAX_PDEV_SET_FW_PARAMS] = { }; 8118 uint8_t index = 0; 8119 8120 hdd_enter_dev(adapter->dev); 8121 8122 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 8123 if (!hdd_ctx) 8124 return -EINVAL; 8125 8126 if (cds_get_conparam() == QDF_GLOBAL_FTM_MODE) { 8127 hdd_debug("FTM Mode is active; nothing to do"); 8128 return 0; 8129 } 8130 8131 /* The ini gEnableLPRx is deprecated. By default, the ini 8132 * is enabled. So, making the variable is_lprx_enabled true. 8133 */ 8134 is_lprx_enabled = true; 8135 8136 ret = mlme_check_index_setparam(setparam, wmi_pdev_param_dtim_synth, 8137 is_lprx_enabled, index++, 8138 MAX_PDEV_SET_FW_PARAMS); 8139 if (QDF_IS_STATUS_ERROR(ret)) 8140 goto error; 8141 8142 ucfg_mlme_get_dtim_selection_diversity(hdd_ctx->psoc, 8143 &dtim_sel_diversity); 8144 ret = mlme_check_index_setparam( 8145 setparam, 8146 wmi_pdev_param_1ch_dtim_optimized_chain_selection, 8147 dtim_sel_diversity, index++, MAX_PDEV_SET_FW_PARAMS); 8148 if (QDF_IS_STATUS_ERROR(ret)) 8149 goto error; 8150 8151 if (QDF_IS_STATUS_SUCCESS(ucfg_fwol_get_enable_tx_sch_delay( 8152 hdd_ctx->psoc, &enable_tx_sch_delay))) { 8153 ret = mlme_check_index_setparam( 8154 setparam, 8155 wmi_pdev_param_tx_sch_delay, 8156 enable_tx_sch_delay, index++, 8157 MAX_PDEV_SET_FW_PARAMS); 8158 if (QDF_IS_STATUS_ERROR(ret)) 8159 goto error; 8160 } 8161 8162 if (QDF_IS_STATUS_SUCCESS(ucfg_fwol_get_ofdm_scrambler_seed( 8163 hdd_ctx->psoc, &enable_ofdm_scrambler_seed))) { 8164 ret = mlme_check_index_setparam( 8165 setparam, 8166 wmi_pdev_param_en_update_scram_seed, 8167 enable_ofdm_scrambler_seed, index++, 8168 MAX_PDEV_SET_FW_PARAMS); 8169 if (QDF_IS_STATUS_ERROR(ret)) 8170 goto error; 8171 } 8172 8173 if (QDF_IS_STATUS_SUCCESS(ucfg_fwol_get_enable_secondary_rate( 8174 hdd_ctx->psoc, &enable_secondary_rate))) { 8175 ret = mlme_check_index_setparam( 8176 setparam, 8177 wmi_pdev_param_secondary_retry_enable, 8178 enable_secondary_rate, index++, 8179 MAX_PDEV_SET_FW_PARAMS); 8180 if (QDF_IS_STATUS_ERROR(ret)) 8181 goto error; 8182 } 8183 if (QDF_IS_STATUS_SUCCESS(ucfg_fwol_get_sap_xlna_bypass( 8184 hdd_ctx->psoc, &sap_xlna_bypass))) { 8185 ret = mlme_check_index_setparam( 8186 setparam, 8187 wmi_pdev_param_set_sap_xlna_bypass, 8188 sap_xlna_bypass, index++, 8189 MAX_PDEV_SET_FW_PARAMS); 8190 if (QDF_IS_STATUS_ERROR(ret)) 8191 goto error; 8192 } 8193 wlan_mlme_get_dfs_chan_ageout_time(hdd_ctx->psoc, 8194 &dfs_chan_ageout_time); 8195 ret = mlme_check_index_setparam( 8196 setparam, 8197 wmi_pdev_param_set_dfs_chan_ageout_time, 8198 dfs_chan_ageout_time, index++, 8199 MAX_PDEV_SET_FW_PARAMS); 8200 if (QDF_IS_STATUS_ERROR(ret)) 8201 goto error; 8202 8203 ret = sme_send_multi_pdev_vdev_set_params(MLME_PDEV_SETPARAM, 8204 WMI_PDEV_ID_SOC, setparam, 8205 index); 8206 if (QDF_IS_STATUS_ERROR(ret)) { 8207 goto error; 8208 } 8209 if (adapter->device_mode == QDF_STA_MODE) { 8210 status = ucfg_get_upper_brssi_thresh(hdd_ctx->psoc, 8211 &upper_brssi_thresh); 8212 if (QDF_IS_STATUS_ERROR(status)) 8213 return -EINVAL; 8214 8215 sme_set_smps_cfg(adapter->deflink->vdev_id, 8216 HDD_STA_SMPS_PARAM_UPPER_BRSSI_THRESH, 8217 upper_brssi_thresh); 8218 8219 status = ucfg_get_lower_brssi_thresh(hdd_ctx->psoc, 8220 &lower_brssi_thresh); 8221 if (QDF_IS_STATUS_ERROR(status)) 8222 return -EINVAL; 8223 8224 sme_set_smps_cfg(adapter->deflink->vdev_id, 8225 HDD_STA_SMPS_PARAM_LOWER_BRSSI_THRESH, 8226 lower_brssi_thresh); 8227 8228 status = ucfg_get_enable_dtim_1chrx(hdd_ctx->psoc, 8229 &enable_dtim_1chrx); 8230 if (QDF_IS_STATUS_ERROR(status)) 8231 return -EINVAL; 8232 8233 sme_set_smps_cfg(adapter->deflink->vdev_id, 8234 HDD_STA_SMPS_PARAM_DTIM_1CHRX_ENABLE, 8235 enable_dtim_1chrx); 8236 } 8237 8238 status = ucfg_mlme_get_vht_enable2x2(hdd_ctx->psoc, &bval); 8239 if (!QDF_IS_STATUS_SUCCESS(status)) 8240 hdd_err("unable to get vht_enable2x2"); 8241 8242 if (bval) { 8243 hdd_debug("configuring 2x2 mode fw params"); 8244 8245 ret = sme_set_cck_tx_fir_override(hdd_ctx->mac_handle, 8246 adapter->deflink->vdev_id); 8247 if (ret) { 8248 hdd_err("wmi_pdev_param_enable_cck_tfir_override set failed %d", 8249 ret); 8250 goto error; 8251 } 8252 8253 hdd_configure_chain_mask(adapter); 8254 } else { 8255 #define HDD_DTIM_1CHAIN_RX_ID 0x5 8256 #define HDD_SMPS_PARAM_VALUE_S 29 8257 hdd_debug("configuring 1x1 mode fw params"); 8258 8259 /* 8260 * Disable DTIM 1 chain Rx when in 1x1, 8261 * we are passing two value 8262 * as param_id << 29 | param_value. 8263 * Below param_value = 0(disable) 8264 */ 8265 ret = sme_cli_set_command(adapter->deflink->vdev_id, 8266 WMI_STA_SMPS_PARAM_CMDID, 8267 HDD_DTIM_1CHAIN_RX_ID << 8268 HDD_SMPS_PARAM_VALUE_S, 8269 VDEV_CMD); 8270 if (ret) { 8271 hdd_err("DTIM 1 chain set failed %d", ret); 8272 goto error; 8273 } 8274 8275 #undef HDD_DTIM_1CHAIN_RX_ID 8276 #undef HDD_SMPS_PARAM_VALUE_S 8277 8278 hdd_configure_chain_mask(adapter); 8279 } 8280 8281 ret = sme_set_enable_mem_deep_sleep(hdd_ctx->mac_handle, 8282 adapter->deflink->vdev_id); 8283 if (ret) { 8284 hdd_err("wmi_pdev_param_hyst_en set failed %d", ret); 8285 goto error; 8286 } 8287 8288 status = ucfg_fwol_get_rts_profile(hdd_ctx->psoc, &rts_profile); 8289 if (QDF_IS_STATUS_ERROR(status)) 8290 return -EINVAL; 8291 8292 ret = sme_cli_set_command(adapter->deflink->vdev_id, 8293 wmi_vdev_param_enable_rtscts, 8294 rts_profile, 8295 VDEV_CMD); 8296 if (ret) { 8297 hdd_err("FAILED TO SET RTSCTS Profile ret:%d", ret); 8298 goto error; 8299 } 8300 8301 if (!hdd_ctx->is_fw_dbg_log_levels_configured) { 8302 hdd_set_fw_log_params(hdd_ctx, adapter->deflink->vdev_id); 8303 hdd_ctx->is_fw_dbg_log_levels_configured = true; 8304 } 8305 8306 ret = hdd_send_coex_config_params(hdd_ctx, adapter); 8307 if (ret) { 8308 hdd_warn("Error initializing coex config params"); 8309 goto error; 8310 } 8311 8312 hdd_exit(); 8313 8314 return 0; 8315 8316 error: 8317 return -EINVAL; 8318 } 8319 8320 /** 8321 * hdd_init_completion() - Initialize Completion Variables 8322 * @adapter: HDD adapter 8323 * 8324 * This function Initialize the completion variables for 8325 * a particular adapter 8326 * 8327 * Return: None 8328 */ 8329 static void hdd_init_completion(struct hdd_adapter *adapter) 8330 { 8331 init_completion(&adapter->disconnect_comp_var); 8332 init_completion(&adapter->linkup_event_var); 8333 init_completion(&adapter->lfr_fw_status.disable_lfr_event); 8334 } 8335 8336 static void hdd_reset_locally_admin_bit(struct hdd_context *hdd_ctx, 8337 tSirMacAddr mac_addr) 8338 { 8339 int i; 8340 /* 8341 * Reset locally administered bit for dynamic_mac_list 8342 * also as while releasing the MAC address for any 8343 * interface mac will be compared with dynamic mac list 8344 */ 8345 for (i = 0; i < QDF_MAX_CONCURRENCY_PERSONA; i++) { 8346 if (!qdf_mem_cmp( 8347 mac_addr, 8348 &hdd_ctx-> 8349 dynamic_mac_list[i].dynamic_mac.bytes[0], 8350 sizeof(struct qdf_mac_addr))) { 8351 WLAN_HDD_RESET_LOCALLY_ADMINISTERED_BIT( 8352 hdd_ctx-> 8353 dynamic_mac_list[i].dynamic_mac.bytes); 8354 break; 8355 } 8356 } 8357 /* 8358 * Reset locally administered bit if the device mode is 8359 * STA 8360 */ 8361 WLAN_HDD_RESET_LOCALLY_ADMINISTERED_BIT(mac_addr); 8362 hdd_debug("locally administered bit reset in sta mode: " 8363 QDF_MAC_ADDR_FMT, QDF_MAC_ADDR_REF(mac_addr)); 8364 } 8365 8366 static void wlan_hdd_cfg80211_scan_block_cb(struct work_struct *work) 8367 { 8368 struct hdd_adapter *adapter = 8369 container_of(work, struct hdd_adapter, scan_block_work); 8370 struct osif_vdev_sync *vdev_sync; 8371 8372 if (osif_vdev_sync_op_start(adapter->dev, &vdev_sync)) 8373 return; 8374 8375 wlan_hdd_cfg80211_scan_block(adapter); 8376 8377 osif_vdev_sync_op_stop(vdev_sync); 8378 } 8379 8380 #if defined(WLAN_FEATURE_11BE_MLO) && \ 8381 defined(WLAN_HDD_MULTI_VDEV_SINGLE_NDEV) 8382 static inline void 8383 wlan_hdd_set_ml_cap_for_sap_intf(struct hdd_adapter_create_param *create_params, 8384 enum QDF_OPMODE mode) 8385 { 8386 if (mode != QDF_SAP_MODE) 8387 return; 8388 8389 create_params->is_ml_adapter = true; 8390 } 8391 #elif defined(WLAN_FEATURE_11BE_MLO) 8392 static inline void 8393 wlan_hdd_set_ml_cap_for_sap_intf(struct hdd_adapter_create_param *create_params, 8394 enum QDF_OPMODE mode) 8395 { 8396 if (mode != QDF_SAP_MODE) 8397 return; 8398 8399 create_params->is_ml_adapter = true; 8400 create_params->is_single_link = true; 8401 } 8402 #else 8403 static inline void 8404 wlan_hdd_set_ml_cap_for_sap_intf(struct hdd_adapter_create_param *create_params, 8405 enum QDF_OPMODE mode) 8406 { 8407 create_params->is_ml_adapter = false; 8408 } 8409 #endif /* WLAN_FEATURE_11BE_MLO */ 8410 8411 #if defined(WLAN_FEATURE_11BE_MLO) && defined(CFG80211_11BE_BASIC) && \ 8412 defined(WLAN_HDD_MULTI_VDEV_SINGLE_NDEV) 8413 void hdd_adapter_disable_all_links(struct hdd_adapter *adapter) 8414 { 8415 uint8_t idx_pos; 8416 struct wlan_hdd_link_info *link_info; 8417 8418 hdd_adapter_for_each_link_info(adapter, link_info) { 8419 qdf_zero_macaddr(&link_info->link_addr); 8420 idx_pos = hdd_adapter_get_index_of_link_info(link_info); 8421 adapter->curr_link_info_map[idx_pos] = idx_pos; 8422 } 8423 adapter->deflink = &adapter->link_info[WLAN_HDD_DEFLINK_IDX]; 8424 if (adapter->device_mode == QDF_STA_MODE) 8425 adapter->active_links = (1 << adapter->num_links_on_create) - 1; 8426 else 8427 adapter->active_links = 0x1; 8428 } 8429 #endif 8430 8431 static void hdd_adapter_enable_links(struct hdd_adapter *adapter, 8432 struct hdd_adapter_create_param *params) 8433 { 8434 uint8_t num, link_idx; 8435 8436 /* Default link is already set on adapter allocation, only 8437 * enable other links if requested links is greater than 1 8438 */ 8439 if (params->num_sessions <= 1) { 8440 adapter->num_links_on_create = 1; 8441 return; 8442 } 8443 8444 num = QDF_MIN(params->num_sessions, WLAN_MAX_MLD); 8445 for (link_idx = WLAN_HDD_DEFLINK_IDX; link_idx < num; link_idx++) 8446 qdf_atomic_set_bit(link_idx, &adapter->active_links); 8447 8448 adapter->num_links_on_create = num; 8449 } 8450 8451 static void hdd_adapter_init_link_info(struct hdd_adapter *adapter) 8452 { 8453 uint8_t idx_pos; 8454 struct wlan_hdd_link_info *link_info; 8455 8456 /* Initialize each member in link info array to default values */ 8457 hdd_adapter_for_each_link_info(adapter, link_info) { 8458 link_info->adapter = adapter; 8459 link_info->vdev_id = WLAN_UMAC_VDEV_ID_MAX; 8460 qdf_spinlock_create(&link_info->vdev_lock); 8461 init_completion(&link_info->vdev_destroy_event); 8462 qdf_event_create(&link_info->acs_complete_event); 8463 8464 idx_pos = hdd_adapter_get_index_of_link_info(link_info); 8465 adapter->curr_link_info_map[idx_pos] = idx_pos; 8466 } 8467 } 8468 8469 /** 8470 * hdd_open_adapter() - open and setup the hdd adapter 8471 * @hdd_ctx: global hdd context 8472 * @session_type: type of the interface to be created 8473 * @iface_name: User-visible name of the interface 8474 * @mac_addr: MAC address to assign to the interface 8475 * @name_assign_type: the name of assign type of the netdev 8476 * @rtnl_held: the rtnl lock hold flag 8477 * @params: adapter create params 8478 * 8479 * This function open and setup the hdd adapter according to the device 8480 * type request, assign the name, the mac address assigned, and then prepared 8481 * the hdd related parameters, queue, lock and ready to start. 8482 * 8483 * Return: the pointer of hdd adapter, otherwise NULL. 8484 */ 8485 struct hdd_adapter *hdd_open_adapter(struct hdd_context *hdd_ctx, 8486 uint8_t session_type, 8487 const char *iface_name, 8488 tSirMacAddr mac_addr, 8489 unsigned char name_assign_type, 8490 bool rtnl_held, 8491 struct hdd_adapter_create_param *params) 8492 { 8493 struct net_device *ndev = NULL; 8494 struct hdd_adapter *adapter = NULL, *sta_adapter = NULL; 8495 QDF_STATUS status = QDF_STATUS_E_FAILURE; 8496 uint32_t i; 8497 bool eht_capab = 0; 8498 8499 status = wlan_hdd_validate_mac_address((struct qdf_mac_addr *)mac_addr); 8500 if (QDF_IS_STATUS_ERROR(status)) { 8501 /* Not received valid mac_addr */ 8502 hdd_err("Unable to add virtual intf: Not able to get valid mac address"); 8503 return NULL; 8504 } 8505 8506 status = hdd_check_for_existing_macaddr(hdd_ctx, mac_addr); 8507 if (QDF_STATUS_E_FAILURE == status) { 8508 hdd_err("Duplicate MAC addr: " QDF_MAC_ADDR_FMT 8509 " already exists", 8510 QDF_MAC_ADDR_REF(mac_addr)); 8511 return NULL; 8512 } 8513 8514 if (params->only_wdev_register) { 8515 sta_adapter = hdd_get_ml_adapter(hdd_ctx); 8516 if (!sta_adapter) { 8517 hdd_err("not able to find the sta adapter"); 8518 return NULL; 8519 } 8520 } 8521 8522 switch (session_type) { 8523 case QDF_STA_MODE: 8524 if (!(hdd_ctx->config->mac_provision || 8525 params->only_wdev_register)) { 8526 hdd_reset_locally_admin_bit(hdd_ctx, mac_addr); 8527 /* 8528 * After resetting locally administered bit 8529 * again check if the new mac address is already 8530 * exists. 8531 */ 8532 status = hdd_check_for_existing_macaddr(hdd_ctx, 8533 mac_addr); 8534 if (QDF_STATUS_E_FAILURE == status) { 8535 hdd_err("Duplicate MAC addr: " QDF_MAC_ADDR_FMT 8536 " already exists", 8537 QDF_MAC_ADDR_REF(mac_addr)); 8538 return NULL; 8539 } 8540 } 8541 8542 fallthrough; 8543 case QDF_P2P_CLIENT_MODE: 8544 case QDF_P2P_DEVICE_MODE: 8545 case QDF_OCB_MODE: 8546 case QDF_NDI_MODE: 8547 case QDF_MONITOR_MODE: 8548 case QDF_NAN_DISC_MODE: 8549 adapter = hdd_alloc_station_adapter(hdd_ctx, mac_addr, 8550 name_assign_type, 8551 iface_name, session_type); 8552 8553 if (!adapter) { 8554 hdd_err("failed to allocate adapter for session %d", 8555 session_type); 8556 return NULL; 8557 } 8558 8559 ndev = adapter->dev; 8560 8561 status = ucfg_dp_create_intf(hdd_ctx->psoc, &adapter->mac_addr, 8562 (qdf_netdev_t)adapter->dev); 8563 if (QDF_IS_STATUS_ERROR(status)) 8564 goto err_free_netdev; 8565 8566 if (QDF_P2P_CLIENT_MODE == session_type) 8567 adapter->wdev.iftype = NL80211_IFTYPE_P2P_CLIENT; 8568 else if (QDF_P2P_DEVICE_MODE == session_type) 8569 adapter->wdev.iftype = NL80211_IFTYPE_P2P_DEVICE; 8570 else if (QDF_MONITOR_MODE == session_type) 8571 adapter->wdev.iftype = NL80211_IFTYPE_MONITOR; 8572 else if (QDF_NAN_DISC_MODE == session_type) 8573 wlan_hdd_set_nan_if_type(adapter); 8574 else 8575 adapter->wdev.iftype = NL80211_IFTYPE_STATION; 8576 8577 adapter->device_mode = session_type; 8578 8579 8580 /* 8581 * Workqueue which gets scheduled in IPv4 notification 8582 * callback 8583 */ 8584 INIT_WORK(&adapter->ipv4_notifier_work, 8585 hdd_ipv4_notifier_work_queue); 8586 8587 #ifdef WLAN_NS_OFFLOAD 8588 /* 8589 * Workqueue which gets scheduled in IPv6 8590 * notification callback. 8591 */ 8592 INIT_WORK(&adapter->ipv6_notifier_work, 8593 hdd_ipv6_notifier_work_queue); 8594 #endif 8595 if (params->only_wdev_register) { 8596 hdd_register_wdev(sta_adapter, adapter, params); 8597 } else { 8598 status = hdd_register_interface(adapter, rtnl_held, 8599 params); 8600 if (QDF_STATUS_SUCCESS != status) 8601 goto err_destroy_dp_intf; 8602 /* Stop the Interface TX queue. */ 8603 hdd_debug("Disabling queues"); 8604 wlan_hdd_netif_queue_control(adapter, 8605 WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER, 8606 WLAN_CONTROL_PATH); 8607 } 8608 break; 8609 case QDF_P2P_GO_MODE: 8610 case QDF_SAP_MODE: 8611 adapter = hdd_wlan_create_ap_dev(hdd_ctx, mac_addr, 8612 name_assign_type, 8613 (uint8_t *) iface_name); 8614 if (!adapter) { 8615 hdd_err("failed to allocate adapter for session %d", 8616 session_type); 8617 return NULL; 8618 } 8619 8620 ndev = adapter->dev; 8621 8622 status = ucfg_dp_create_intf(hdd_ctx->psoc, &adapter->mac_addr, 8623 (qdf_netdev_t)adapter->dev); 8624 if (QDF_IS_STATUS_ERROR(status)) 8625 goto err_free_netdev; 8626 8627 adapter->wdev.iftype = 8628 (session_type == 8629 QDF_SAP_MODE) ? NL80211_IFTYPE_AP : 8630 NL80211_IFTYPE_P2P_GO; 8631 adapter->device_mode = session_type; 8632 8633 status = hdd_register_interface(adapter, rtnl_held, params); 8634 if (QDF_STATUS_SUCCESS != status) 8635 goto err_destroy_dp_intf; 8636 8637 hdd_debug("Disabling queues"); 8638 wlan_hdd_netif_queue_control(adapter, 8639 WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER, 8640 WLAN_CONTROL_PATH); 8641 8642 /* 8643 * Workqueue which gets scheduled in IPv4 notification 8644 * callback 8645 */ 8646 INIT_WORK(&adapter->ipv4_notifier_work, 8647 hdd_ipv4_notifier_work_queue); 8648 8649 #ifdef WLAN_NS_OFFLOAD 8650 /* 8651 * Workqueue which gets scheduled in IPv6 8652 * notification callback. 8653 */ 8654 INIT_WORK(&adapter->ipv6_notifier_work, 8655 hdd_ipv6_notifier_work_queue); 8656 #endif 8657 wlan_hdd_set_ml_cap_for_sap_intf(params, session_type); 8658 break; 8659 case QDF_FTM_MODE: 8660 adapter = hdd_alloc_station_adapter(hdd_ctx, mac_addr, 8661 name_assign_type, 8662 iface_name, session_type); 8663 if (!adapter) { 8664 hdd_err("Failed to allocate adapter for FTM mode"); 8665 return NULL; 8666 } 8667 8668 ndev = adapter->dev; 8669 8670 status = ucfg_dp_create_intf(hdd_ctx->psoc, &adapter->mac_addr, 8671 (qdf_netdev_t)adapter->dev); 8672 if (QDF_IS_STATUS_ERROR(status)) 8673 goto err_free_netdev; 8674 8675 adapter->wdev.iftype = NL80211_IFTYPE_STATION; 8676 adapter->device_mode = session_type; 8677 status = hdd_register_interface(adapter, rtnl_held, params); 8678 if (QDF_STATUS_SUCCESS != status) 8679 goto err_destroy_dp_intf; 8680 8681 /* Stop the Interface TX queue. */ 8682 hdd_debug("Disabling queues"); 8683 wlan_hdd_netif_queue_control(adapter, 8684 WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER, 8685 WLAN_CONTROL_PATH); 8686 8687 break; 8688 default: 8689 hdd_err("Invalid session type %d", session_type); 8690 QDF_ASSERT(0); 8691 return NULL; 8692 } 8693 8694 hdd_adapter_init_link_info(adapter); 8695 hdd_adapter_enable_links(adapter, params); 8696 8697 ucfg_psoc_mlme_get_11be_capab(hdd_ctx->psoc, &eht_capab); 8698 if (params->is_ml_adapter && eht_capab) { 8699 hdd_adapter_set_ml_adapter(adapter); 8700 if (params->is_single_link) 8701 hdd_adapter_set_sl_ml_adapter(adapter); 8702 } 8703 8704 status = hdd_adapter_feature_update_work_init(adapter); 8705 if (QDF_IS_STATUS_ERROR(status)) 8706 goto err_cleanup_adapter; 8707 8708 adapter->upgrade_udp_qos_threshold = QCA_WLAN_AC_BK; 8709 8710 hdd_init_completion(adapter); 8711 INIT_WORK(&adapter->scan_block_work, wlan_hdd_cfg80211_scan_block_cb); 8712 INIT_WORK(&adapter->sap_stop_bss_work, 8713 hdd_stop_sap_due_to_invalid_channel); 8714 qdf_list_create(&adapter->blocked_scan_request_q, WLAN_MAX_SCAN_COUNT); 8715 qdf_mutex_create(&adapter->blocked_scan_request_q_lock); 8716 qdf_spinlock_create(&adapter->mc_list_lock); 8717 qdf_event_create(&adapter->peer_cleanup_done); 8718 hdd_sta_info_init(&adapter->sta_info_list); 8719 hdd_sta_info_init(&adapter->cache_sta_info_list); 8720 8721 for (i = 0; i < NET_DEV_HOLD_ID_MAX; i++) 8722 qdf_atomic_init( 8723 &adapter->net_dev_hold_ref_count[NET_DEV_HOLD_ID_MAX]); 8724 8725 /* Add it to the hdd's session list. */ 8726 status = hdd_add_adapter_back(hdd_ctx, adapter); 8727 if (QDF_STATUS_SUCCESS != status) 8728 goto err_destroy_adapter_features_update_work; 8729 8730 hdd_apf_context_init(adapter); 8731 8732 policy_mgr_set_concurrency_mode(hdd_ctx->psoc, session_type); 8733 8734 if (QDF_STATUS_SUCCESS != hdd_debugfs_init(adapter)) 8735 hdd_err("debugfs: Interface %s init failed", 8736 netdev_name(adapter->dev)); 8737 8738 hdd_debug("%s interface created. iftype: %d", netdev_name(adapter->dev), 8739 session_type); 8740 8741 if (adapter->device_mode == QDF_STA_MODE) 8742 wlan_hdd_debugfs_csr_init(adapter); 8743 8744 return adapter; 8745 8746 err_destroy_adapter_features_update_work: 8747 hdd_adapter_feature_update_work_deinit(adapter); 8748 8749 err_cleanup_adapter: 8750 if (adapter) { 8751 hdd_cleanup_adapter(hdd_ctx, adapter, rtnl_held); 8752 adapter = NULL; 8753 } 8754 8755 err_destroy_dp_intf: 8756 ucfg_dp_destroy_intf(hdd_ctx->psoc, &adapter->mac_addr); 8757 8758 err_free_netdev: 8759 if (ndev) 8760 free_netdev(ndev); 8761 8762 return NULL; 8763 } 8764 8765 static void __hdd_close_adapter(struct hdd_context *hdd_ctx, 8766 struct hdd_adapter *adapter, 8767 bool rtnl_held) 8768 { 8769 struct qdf_mac_addr adapter_mac; 8770 struct wlan_hdd_link_info *link_info; 8771 8772 8773 qdf_copy_macaddr(&adapter_mac, &adapter->mac_addr); 8774 if (adapter->device_mode == QDF_STA_MODE) { 8775 hdd_adapter_for_each_link_info(adapter, link_info) 8776 hdd_cleanup_conn_info(link_info); 8777 } 8778 qdf_list_destroy(&adapter->blocked_scan_request_q); 8779 qdf_mutex_destroy(&adapter->blocked_scan_request_q_lock); 8780 policy_mgr_clear_concurrency_mode(hdd_ctx->psoc, adapter->device_mode); 8781 qdf_event_destroy(&adapter->peer_cleanup_done); 8782 hdd_adapter_feature_update_work_deinit(adapter); 8783 hdd_cleanup_adapter(hdd_ctx, adapter, rtnl_held); 8784 ucfg_dp_destroy_intf(hdd_ctx->psoc, &adapter_mac); 8785 } 8786 8787 void hdd_close_adapter(struct hdd_context *hdd_ctx, 8788 struct hdd_adapter *adapter, 8789 bool rtnl_held) 8790 { 8791 /* 8792 * Stop the global bus bandwidth timer while touching the adapter list 8793 * to avoid bad memory access by the timer handler. 8794 */ 8795 ucfg_dp_bus_bw_compute_timer_stop(hdd_ctx->psoc); 8796 8797 hdd_check_for_net_dev_ref_leak(adapter); 8798 hdd_remove_adapter(hdd_ctx, adapter); 8799 __hdd_close_adapter(hdd_ctx, adapter, rtnl_held); 8800 8801 /* conditionally restart the bw timer */ 8802 ucfg_dp_bus_bw_compute_timer_try_start(hdd_ctx->psoc); 8803 } 8804 8805 void hdd_close_all_adapters(struct hdd_context *hdd_ctx, bool rtnl_held) 8806 { 8807 struct hdd_adapter *adapter; 8808 struct osif_vdev_sync *vdev_sync; 8809 QDF_STATUS qdf_status; 8810 8811 hdd_enter(); 8812 8813 while (QDF_IS_STATUS_SUCCESS(hdd_get_front_adapter( 8814 hdd_ctx, &adapter))) { 8815 /* If MLO is enabled unregister the link wdev's */ 8816 if (adapter->device_mode == QDF_STA_MODE || 8817 adapter->device_mode == QDF_SAP_MODE) { 8818 qdf_status = hdd_wlan_unregister_mlo_interfaces(adapter, 8819 rtnl_held); 8820 if (QDF_IS_STATUS_ERROR(qdf_status)) 8821 continue; 8822 } 8823 8824 hdd_check_for_net_dev_ref_leak(adapter); 8825 hdd_remove_front_adapter(hdd_ctx, &adapter); 8826 vdev_sync = osif_vdev_sync_unregister(adapter->dev); 8827 if (vdev_sync) 8828 osif_vdev_sync_wait_for_ops(vdev_sync); 8829 8830 wlan_hdd_release_intf_addr(hdd_ctx, adapter->mac_addr.bytes); 8831 __hdd_close_adapter(hdd_ctx, adapter, rtnl_held); 8832 8833 if (vdev_sync) 8834 osif_vdev_sync_destroy(vdev_sync); 8835 } 8836 8837 hdd_exit(); 8838 } 8839 8840 void wlan_hdd_reset_prob_rspies(struct wlan_hdd_link_info *link_info) 8841 { 8842 struct qdf_mac_addr *bssid = NULL; 8843 tSirUpdateIE update_ie; 8844 mac_handle_t mac_handle; 8845 struct hdd_adapter *adapter = link_info->adapter; 8846 8847 switch (adapter->device_mode) { 8848 case QDF_STA_MODE: 8849 case QDF_P2P_CLIENT_MODE: 8850 { 8851 struct hdd_station_ctx *sta_ctx = 8852 WLAN_HDD_GET_STATION_CTX_PTR(link_info); 8853 bssid = &sta_ctx->conn_info.bssid; 8854 break; 8855 } 8856 case QDF_SAP_MODE: 8857 case QDF_P2P_GO_MODE: 8858 { 8859 bssid = &adapter->mac_addr; 8860 break; 8861 } 8862 case QDF_FTM_MODE: 8863 case QDF_P2P_DEVICE_MODE: 8864 default: 8865 /* 8866 * wlan_hdd_reset_prob_rspies should not have been called 8867 * for these kind of devices 8868 */ 8869 hdd_err("Unexpected request for the current device type %d", 8870 adapter->device_mode); 8871 return; 8872 } 8873 8874 qdf_copy_macaddr(&update_ie.bssid, bssid); 8875 update_ie.vdev_id = link_info->vdev_id; 8876 update_ie.ieBufferlength = 0; 8877 update_ie.pAdditionIEBuffer = NULL; 8878 update_ie.append = true; 8879 update_ie.notify = false; 8880 mac_handle = hdd_adapter_get_mac_handle(adapter); 8881 if (sme_update_add_ie(mac_handle, 8882 &update_ie, 8883 eUPDATE_IE_PROBE_RESP) == QDF_STATUS_E_FAILURE) { 8884 hdd_err("Could not pass on PROBE_RSP_BCN data to PE"); 8885 } 8886 } 8887 8888 /** 8889 * hdd_ipa_ap_disconnect_evt() - Indicate wlan ipa ap disconnect event 8890 * @hdd_ctx: hdd context 8891 * @adapter: hdd adapter 8892 * 8893 * Return: None 8894 */ 8895 static inline 8896 void hdd_ipa_ap_disconnect_evt(struct hdd_context *hdd_ctx, 8897 struct hdd_adapter *adapter) 8898 { 8899 if (ucfg_ipa_is_enabled()) { 8900 ucfg_ipa_uc_disconnect_ap(hdd_ctx->pdev, 8901 adapter->dev); 8902 ucfg_ipa_cleanup_dev_iface(hdd_ctx->pdev, 8903 adapter->dev); 8904 } 8905 } 8906 8907 #ifdef WLAN_FEATURE_NAN 8908 /** 8909 * hdd_ndp_state_cleanup() - API to set NDP state to Disconnected 8910 * @psoc: pointer to psoc object 8911 * @ndi_vdev_id: vdev_id of the NDI 8912 * 8913 * Return: None 8914 */ 8915 static void 8916 hdd_ndp_state_cleanup(struct wlan_objmgr_psoc *psoc, uint8_t ndi_vdev_id) 8917 { 8918 struct wlan_objmgr_vdev *ndi_vdev; 8919 8920 ndi_vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, ndi_vdev_id, 8921 WLAN_NAN_ID); 8922 if (!ndi_vdev) { 8923 hdd_err("Cannot obtain NDI vdev object!"); 8924 return; 8925 } 8926 8927 ucfg_nan_set_ndi_state(ndi_vdev, NAN_DATA_DISCONNECTED_STATE); 8928 8929 wlan_objmgr_vdev_release_ref(ndi_vdev, WLAN_NAN_ID); 8930 } 8931 8932 /** 8933 * hdd_peer_cleanup() - This API will delete NDP peer if exist and modifies 8934 * the NDP state. 8935 * @link_info: Link info pointer in HDD adapter 8936 * 8937 * Return: None 8938 */ 8939 static void hdd_peer_cleanup(struct wlan_hdd_link_info *link_info) 8940 { 8941 QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE; 8942 struct hdd_adapter *adapter = link_info->adapter; 8943 struct hdd_context *hdd_ctx = adapter->hdd_ctx; 8944 8945 /* Check if there is any peer present on the adapter */ 8946 if (!hdd_any_valid_peer_present(link_info)) { 8947 /* 8948 * No peers are connected to the NDI. So, set the NDI state to 8949 * DISCONNECTED. If there are any peers, ucfg_nan_disable_ndi() 8950 * would take care of cleanup all the peers and setting the 8951 * state to DISCONNECTED. 8952 */ 8953 hdd_ndp_state_cleanup(hdd_ctx->psoc, link_info->vdev_id); 8954 return; 8955 } 8956 8957 if (adapter->device_mode == QDF_NDI_MODE) 8958 qdf_status = ucfg_nan_disable_ndi(hdd_ctx->psoc, 8959 link_info->vdev_id); 8960 8961 if (QDF_IS_STATUS_ERROR(qdf_status)) 8962 return; 8963 8964 qdf_status = qdf_wait_for_event_completion(&adapter->peer_cleanup_done, 8965 WLAN_WAIT_PEER_CLEANUP); 8966 if (QDF_IS_STATUS_ERROR(qdf_status)) 8967 hdd_debug("peer_cleanup_done wait fail"); 8968 } 8969 #else 8970 static inline void 8971 hdd_ndp_state_cleanup(struct wlan_objmgr_psoc *psoc, uint8_t ndi_vdev_id) 8972 { 8973 } 8974 8975 static inline void 8976 hdd_ndp_peer_cleanup(struct hdd_context *hdd_ctx, struct hdd_adapter *adapter) 8977 { 8978 } 8979 8980 static inline void hdd_peer_cleanup(struct wlan_hdd_link_info *link_info) 8981 { 8982 } 8983 #endif /* WLAN_FEATURE_NAN */ 8984 8985 #ifdef FUNC_CALL_MAP 8986 8987 /** 8988 * hdd_dump_func_call_map() - Dump the function call map 8989 * 8990 * Return: None 8991 */ 8992 8993 static void hdd_dump_func_call_map(void) 8994 { 8995 char *cc_buf; 8996 8997 cc_buf = qdf_mem_malloc(QDF_FUNCTION_CALL_MAP_BUF_LEN); 8998 /* 8999 * These logs are required as these indicates the start and end of the 9000 * dump for the auto script to parse 9001 */ 9002 hdd_info("Function call map dump start"); 9003 qdf_get_func_call_map(cc_buf); 9004 qdf_trace_hex_dump(QDF_MODULE_ID_HDD, 9005 QDF_TRACE_LEVEL_DEBUG, cc_buf, QDF_FUNCTION_CALL_MAP_BUF_LEN); 9006 hdd_info("Function call map dump end"); 9007 qdf_mem_free(cc_buf); 9008 } 9009 #else 9010 static inline void hdd_dump_func_call_map(void) 9011 { 9012 } 9013 #endif 9014 9015 static void hdd_reset_scan_operation(struct wlan_hdd_link_info *link_info) 9016 { 9017 switch (link_info->adapter->device_mode) { 9018 case QDF_STA_MODE: 9019 case QDF_P2P_CLIENT_MODE: 9020 case QDF_P2P_DEVICE_MODE: 9021 case QDF_NDI_MODE: 9022 wlan_hdd_scan_abort(link_info); 9023 wlan_hdd_cleanup_remain_on_channel_ctx(link_info); 9024 if (link_info->adapter->device_mode == QDF_STA_MODE) { 9025 struct wlan_objmgr_vdev *vdev; 9026 9027 vdev = hdd_objmgr_get_vdev_by_user(link_info, 9028 WLAN_OSIF_SCAN_ID); 9029 if (!vdev) 9030 break; 9031 9032 wlan_cfg80211_sched_scan_stop(vdev); 9033 hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_SCAN_ID); 9034 } 9035 break; 9036 case QDF_P2P_GO_MODE: 9037 wlan_hdd_cleanup_remain_on_channel_ctx(link_info); 9038 break; 9039 case QDF_SAP_MODE: 9040 qdf_atomic_set(&link_info->session.ap.acs_in_progress, 0); 9041 break; 9042 default: 9043 break; 9044 } 9045 } 9046 9047 #ifdef WLAN_OPEN_SOURCE 9048 void hdd_cancel_ip_notifier_work(struct hdd_adapter *adapter) 9049 { 9050 cancel_work_sync(&adapter->ipv4_notifier_work); 9051 #ifdef WLAN_NS_OFFLOAD 9052 cancel_work_sync(&adapter->ipv6_notifier_work); 9053 #endif 9054 } 9055 #endif 9056 9057 void hdd_adapter_deregister_fc(struct hdd_adapter *adapter) 9058 { 9059 hdd_deregister_hl_netdev_fc_timer(adapter); 9060 hdd_deregister_tx_flow_control(adapter); 9061 } 9062 9063 static void hdd_stop_and_cleanup_ndi(struct wlan_hdd_link_info *link_info) 9064 { 9065 QDF_STATUS status; 9066 unsigned long rc; 9067 struct hdd_adapter *adapter = link_info->adapter; 9068 struct hdd_context *hdd_ctx = adapter->hdd_ctx; 9069 9070 /* For NDI do not use roam_profile */ 9071 INIT_COMPLETION(adapter->disconnect_comp_var); 9072 hdd_peer_cleanup(link_info); 9073 status = sme_roam_ndi_stop(hdd_ctx->mac_handle, link_info->vdev_id); 9074 if (QDF_IS_STATUS_SUCCESS(status)) { 9075 rc = wait_for_completion_timeout( 9076 &adapter->disconnect_comp_var, 9077 msecs_to_jiffies(SME_CMD_STOP_BSS_TIMEOUT)); 9078 if (!rc) 9079 hdd_warn("disconn_comp_var wait fail"); 9080 hdd_cleanup_ndi(link_info); 9081 } 9082 } 9083 9084 static void 9085 hdd_sta_disconnect_and_cleanup(struct wlan_hdd_link_info *link_info) 9086 { 9087 QDF_STATUS status; 9088 enum wlan_reason_code reason; 9089 struct hdd_adapter *adapter = link_info->adapter; 9090 9091 /* 9092 * On vdev delete wait for disconnect to 9093 * complete. i.e use sync API, so that the 9094 * vdev ref of MLME are cleaned and disconnect 9095 * complete before vdev is moved to logically 9096 * deleted. 9097 */ 9098 if (cds_is_driver_recovering()) 9099 reason = REASON_DEVICE_RECOVERY; 9100 else 9101 reason = REASON_IFACE_DOWN; 9102 9103 status = wlan_hdd_cm_issue_disconnect(link_info, reason, true); 9104 if (QDF_IS_STATUS_ERROR(status) && ucfg_ipa_is_enabled()) { 9105 hdd_err("STA disconnect failed"); 9106 ucfg_ipa_uc_cleanup_sta(adapter->hdd_ctx->pdev, adapter->dev); 9107 } 9108 } 9109 9110 static void 9111 hdd_disable_nan_active_disc(struct hdd_adapter *adapter) 9112 { 9113 struct hdd_context *hdd_ctx = adapter->hdd_ctx; 9114 enum QDF_OPMODE device_mode = adapter->device_mode; 9115 9116 if ((device_mode == QDF_NAN_DISC_MODE || 9117 (device_mode == QDF_STA_MODE && 9118 !ucfg_nan_is_vdev_creation_allowed(hdd_ctx->psoc))) && 9119 ucfg_is_nan_conc_control_supported(hdd_ctx->psoc) && 9120 ucfg_is_nan_disc_active(hdd_ctx->psoc)) 9121 ucfg_disable_nan_discovery(hdd_ctx->psoc, NULL, 0); 9122 } 9123 9124 static void 9125 hdd_monitor_mode_release_wakelock(struct wlan_hdd_link_info *link_info) 9126 { 9127 struct hdd_adapter *adapter = link_info->adapter; 9128 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); 9129 9130 if (wlan_hdd_is_session_type_monitor(adapter->device_mode) && 9131 (ucfg_mlme_is_sta_mon_conc_supported(hdd_ctx->psoc) || 9132 ucfg_dp_is_local_pkt_capture_enabled(hdd_ctx->psoc))) { 9133 hdd_info("Release wakelock for STA + monitor mode!"); 9134 os_if_dp_local_pkt_capture_stop(link_info->vdev); 9135 qdf_runtime_pm_allow_suspend( 9136 &hdd_ctx->runtime_context.monitor_mode); 9137 hdd_lpc_enable_powersave(hdd_ctx); 9138 qdf_wake_lock_release(&hdd_ctx->monitor_mode_wakelock, 9139 WIFI_POWER_EVENT_WAKELOCK_MONITOR_MODE); 9140 } 9141 } 9142 9143 static void 9144 hdd_monitor_mode_disable_and_delete(struct wlan_hdd_link_info *link_info) 9145 { 9146 QDF_STATUS status; 9147 struct hdd_adapter *adapter = link_info->adapter; 9148 struct hdd_context *hdd_ctx = adapter->hdd_ctx; 9149 9150 status = hdd_disable_monitor_mode(); 9151 if (QDF_IS_STATUS_ERROR(status)) 9152 hdd_err_rl("datapath reset failed for montior mode"); 9153 hdd_set_idle_ps_config(hdd_ctx, true); 9154 status = hdd_monitor_mode_vdev_status(adapter); 9155 if (QDF_IS_STATUS_ERROR(status)) 9156 hdd_err_rl("stop failed montior mode"); 9157 sme_delete_mon_session(hdd_ctx->mac_handle, link_info->vdev_id); 9158 } 9159 9160 static void 9161 hdd_stop_and_close_pre_cac_adapter(struct hdd_context *hdd_ctx, 9162 struct wlan_objmgr_vdev *vdev) 9163 { 9164 if (!vdev) 9165 return; 9166 9167 if (!ucfg_pre_cac_adapter_is_active(vdev)) { 9168 ucfg_pre_cac_stop(hdd_ctx->psoc); 9169 hdd_close_pre_cac_adapter(hdd_ctx); 9170 } else { 9171 if (ucfg_pre_cac_set_status(vdev, false)) 9172 hdd_err("Failed to set is_pre_cac_on to false"); 9173 } 9174 } 9175 9176 static void hdd_reset_ies_on_sap_stop(struct wlan_hdd_link_info *link_info) 9177 { 9178 mac_handle_t mac_handle; 9179 tSirUpdateIE update_ie; 9180 QDF_STATUS status; 9181 struct hdd_adapter *adapter = link_info->adapter; 9182 9183 mac_handle = hdd_adapter_get_mac_handle(adapter); 9184 update_ie.vdev_id = link_info->vdev_id; 9185 update_ie.ieBufferlength = 0; 9186 update_ie.pAdditionIEBuffer = NULL; 9187 update_ie.append = false; 9188 update_ie.notify = false; 9189 9190 /* Probe bcn reset */ 9191 status = sme_update_add_ie(mac_handle, &update_ie, 9192 eUPDATE_IE_PROBE_BCN); 9193 if (status == QDF_STATUS_E_FAILURE) 9194 hdd_err("Could not pass PROBE_RSP_BCN to PE"); 9195 9196 /* Assoc resp reset */ 9197 status = sme_update_add_ie(mac_handle, &update_ie, 9198 eUPDATE_IE_ASSOC_RESP); 9199 if (status == QDF_STATUS_E_FAILURE) 9200 hdd_err("Could not pass ASSOC_RSP to PE"); 9201 9202 /* Reset WNI_CFG_PROBE_RSP Flags */ 9203 wlan_hdd_reset_prob_rspies(link_info); 9204 } 9205 9206 static void hdd_stop_station_adapter(struct hdd_adapter *adapter) 9207 { 9208 struct wlan_objmgr_vdev *vdev; 9209 enum QDF_OPMODE mode; 9210 struct wlan_hdd_link_info *link_info; 9211 9212 mode = adapter->device_mode; 9213 hdd_adapter_for_each_active_link_info(adapter, link_info) { 9214 vdev = hdd_objmgr_get_vdev_by_user(link_info, 9215 WLAN_INIT_DEINIT_ID); 9216 if (!vdev) 9217 continue; 9218 9219 if (mode == QDF_NDI_MODE) 9220 hdd_stop_and_cleanup_ndi(link_info); 9221 else if (!hdd_cm_is_disconnected(link_info)) 9222 hdd_sta_disconnect_and_cleanup(link_info); 9223 9224 hdd_reset_scan_operation(link_info); 9225 wlan_hdd_cleanup_actionframe(link_info); 9226 wlan_hdd_flush_pmksa_cache(link_info); 9227 9228 if (mode == QDF_STA_MODE) 9229 ucfg_ipa_flush_pending_vdev_events( 9230 wlan_vdev_get_pdev(vdev), 9231 link_info->vdev_id); 9232 hdd_objmgr_put_vdev_by_user(vdev, WLAN_INIT_DEINIT_ID); 9233 hdd_vdev_destroy(link_info); 9234 } 9235 9236 hdd_disable_nan_active_disc(adapter); 9237 hdd_adapter_deregister_fc(adapter); 9238 hdd_cancel_ip_notifier_work(adapter); 9239 } 9240 9241 static int hdd_stop_mon_adapter(struct hdd_adapter *adapter) 9242 { 9243 struct wlan_objmgr_vdev *vdev; 9244 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); 9245 struct wlan_hdd_link_info *link_info = adapter->deflink; 9246 9247 vdev = hdd_objmgr_get_vdev_by_user(link_info, 9248 WLAN_INIT_DEINIT_ID); 9249 if (wlan_hdd_is_session_type_monitor(adapter->device_mode) && 9250 vdev && 9251 ucfg_pkt_capture_get_mode(hdd_ctx->psoc) != 9252 PACKET_CAPTURE_MODE_DISABLE) { 9253 struct hdd_adapter *sta_adapter; 9254 9255 ucfg_pkt_capture_deregister_callbacks(vdev); 9256 hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_ID); 9257 link_info->vdev = NULL; 9258 9259 sta_adapter = hdd_get_adapter(hdd_ctx, QDF_STA_MODE); 9260 if (!sta_adapter) { 9261 hdd_objmgr_put_vdev_by_user(vdev, WLAN_INIT_DEINIT_ID); 9262 hdd_err("No station interface found"); 9263 return -EINVAL; 9264 } 9265 hdd_reset_monitor_interface(sta_adapter); 9266 } 9267 9268 hdd_monitor_mode_release_wakelock(link_info); 9269 wlan_hdd_scan_abort(link_info); 9270 hdd_adapter_deregister_fc(adapter); 9271 hdd_monitor_mode_disable_and_delete(link_info); 9272 if (vdev) 9273 hdd_objmgr_put_vdev_by_user(vdev, WLAN_INIT_DEINIT_ID); 9274 9275 hdd_vdev_destroy(link_info); 9276 9277 return 0; 9278 } 9279 9280 static void hdd_stop_sap_go_adapter(struct hdd_adapter *adapter) 9281 { 9282 enum QDF_OPMODE mode; 9283 struct hdd_ap_ctx *ap_ctx; 9284 struct sap_context *sap_ctx; 9285 struct sap_config *sap_config; 9286 struct hdd_hostapd_state *hostapd_state; 9287 struct wlan_objmgr_vdev *vdev; 9288 struct wlan_hdd_link_info *link_info = adapter->deflink; 9289 QDF_STATUS status = QDF_STATUS_SUCCESS; 9290 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); 9291 9292 mode = adapter->device_mode; 9293 ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(link_info); 9294 sap_ctx = WLAN_HDD_GET_SAP_CTX_PTR(link_info); 9295 vdev = hdd_objmgr_get_vdev_by_user(link_info, WLAN_INIT_DEINIT_ID); 9296 9297 if (mode == QDF_SAP_MODE) { 9298 wlan_hdd_scan_abort(link_info); 9299 hdd_abort_ongoing_sta_connection(hdd_ctx); 9300 /* Diassociate with all the peers before stop ap post */ 9301 if (test_bit(SOFTAP_BSS_STARTED, &link_info->link_flags)) { 9302 if (wlan_hdd_del_station(adapter, NULL)) 9303 hdd_sap_indicate_disconnect_for_sta(adapter); 9304 } 9305 wlan_hdd_flush_pmksa_cache(link_info); 9306 sap_config = &ap_ctx->sap_config; 9307 wlansap_reset_sap_config_add_ie(sap_config, eUPDATE_IE_ALL); 9308 hdd_stop_and_close_pre_cac_adapter(hdd_ctx, vdev); 9309 } 9310 wlansap_cleanup_cac_timer(sap_ctx); 9311 cds_flush_work(&adapter->sap_stop_bss_work); 9312 9313 if (qdf_atomic_read(&ap_ctx->acs_in_progress)) { 9314 hdd_info("ACS in progress, wait for complete"); 9315 qdf_wait_for_event_completion(&link_info->acs_complete_event, 9316 ACS_COMPLETE_TIMEOUT); 9317 } 9318 9319 if (mode == QDF_P2P_GO_MODE) { 9320 wlan_hdd_cleanup_remain_on_channel_ctx(link_info); 9321 hdd_abort_ongoing_sta_connection(hdd_ctx); 9322 } 9323 9324 hdd_adapter_deregister_fc(adapter); 9325 hdd_destroy_acs_timer(adapter); 9326 9327 mutex_lock(&hdd_ctx->sap_lock); 9328 if (test_bit(SOFTAP_BSS_STARTED, &link_info->link_flags)) { 9329 hostapd_state = WLAN_HDD_GET_HOSTAP_STATE_PTR(link_info); 9330 qdf_event_reset(&hostapd_state->qdf_stop_bss_event); 9331 status = wlansap_stop_bss(ap_ctx->sap_context); 9332 if (QDF_IS_STATUS_SUCCESS(status)) { 9333 status = qdf_wait_single_event(&hostapd_state->qdf_stop_bss_event, 9334 SME_CMD_STOP_BSS_TIMEOUT); 9335 if (QDF_IS_STATUS_ERROR(status)) { 9336 hdd_err("failure waiting for wlansap_stop_bss %d", 9337 status); 9338 hdd_ipa_ap_disconnect_evt(hdd_ctx, adapter); 9339 } 9340 } else { 9341 hdd_err("failure in wlansap_stop_bss"); 9342 } 9343 9344 clear_bit(SOFTAP_BSS_STARTED, &link_info->link_flags); 9345 policy_mgr_decr_session_set_pcl(hdd_ctx->psoc, 9346 adapter->device_mode, 9347 link_info->vdev_id); 9348 hdd_green_ap_start_state_mc(hdd_ctx, adapter->device_mode, 9349 false); 9350 9351 hdd_reset_ies_on_sap_stop(link_info); 9352 } 9353 9354 /* 9355 * Note to restart sap after SSR driver needs below information 9356 * and is not cleared/freed on purpose in case of SAP SSR 9357 */ 9358 if (!cds_is_driver_recovering()) { 9359 clear_bit(SOFTAP_INIT_DONE, &link_info->link_flags); 9360 qdf_mem_free(ap_ctx->beacon); 9361 ap_ctx->beacon = NULL; 9362 } 9363 /* Clear all the cached sta info */ 9364 hdd_clear_cached_sta_info(adapter); 9365 9366 if (vdev && policy_mgr_is_dnsc_set(vdev)) 9367 wlan_hdd_send_avoid_freq_for_dnbs(hdd_ctx, 0); 9368 9369 hdd_cancel_ip_notifier_work(adapter); 9370 sap_release_vdev_ref(sap_ctx); 9371 9372 if (mode == QDF_SAP_MODE) 9373 ucfg_ipa_flush_pending_vdev_events(hdd_ctx->pdev, 9374 link_info->vdev_id); 9375 if (vdev) 9376 hdd_objmgr_put_vdev_by_user(vdev, WLAN_INIT_DEINIT_ID); 9377 hdd_vdev_destroy(link_info); 9378 mutex_unlock(&hdd_ctx->sap_lock); 9379 ucfg_ipa_flush(hdd_ctx->pdev); 9380 } 9381 9382 static void hdd_stop_ocb_adapter(struct hdd_adapter *adapter) 9383 { 9384 struct hdd_station_ctx *sta_ctx; 9385 struct wlan_objmgr_vdev *vdev; 9386 struct wlan_hdd_link_info *link_info = adapter->deflink; 9387 9388 vdev = hdd_objmgr_get_vdev_by_user(link_info, WLAN_INIT_DEINIT_ID); 9389 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(link_info); 9390 cdp_clear_peer(cds_get_context(QDF_MODULE_ID_SOC), OL_TXRX_PDEV_ID, 9391 sta_ctx->conn_info.peer_macaddr[0]); 9392 hdd_adapter_deregister_fc(adapter); 9393 if (vdev) 9394 hdd_objmgr_put_vdev_by_user(vdev, WLAN_INIT_DEINIT_ID); 9395 hdd_vdev_destroy(link_info); 9396 } 9397 9398 QDF_STATUS hdd_stop_adapter_ext(struct hdd_context *hdd_ctx, 9399 struct hdd_adapter *adapter) 9400 { 9401 QDF_STATUS status; 9402 struct wlan_hdd_link_info *link_info = adapter->deflink; 9403 9404 hdd_enter(); 9405 hdd_destroy_adapter_sysfs_files(adapter); 9406 9407 if (adapter->device_mode == QDF_STA_MODE && 9408 hdd_is_pkt_capture_mon_enable(adapter) && 9409 ucfg_pkt_capture_get_mode(hdd_ctx->psoc) != 9410 PACKET_CAPTURE_MODE_DISABLE) { 9411 hdd_unmap_monitor_interface_vdev(adapter); 9412 } 9413 9414 if (link_info->vdev_id != WLAN_UMAC_VDEV_ID_MAX) 9415 wlan_hdd_cfg80211_deregister_frames(adapter); 9416 9417 hdd_stop_tsf_sync(adapter); 9418 cds_flush_work(&adapter->scan_block_work); 9419 wlan_hdd_cfg80211_scan_block(adapter); 9420 hdd_debug("Disabling queues"); 9421 wlan_hdd_netif_queue_control(adapter, 9422 WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER, 9423 WLAN_CONTROL_PATH); 9424 9425 switch (adapter->device_mode) { 9426 case QDF_STA_MODE: 9427 case QDF_P2P_CLIENT_MODE: 9428 case QDF_NDI_MODE: 9429 case QDF_P2P_DEVICE_MODE: 9430 case QDF_NAN_DISC_MODE: 9431 hdd_stop_station_adapter(adapter); 9432 break; 9433 case QDF_MONITOR_MODE: 9434 status = hdd_stop_mon_adapter(adapter); 9435 if (QDF_IS_STATUS_ERROR(status)) 9436 return status; 9437 9438 break; 9439 case QDF_SAP_MODE: 9440 case QDF_P2P_GO_MODE: 9441 hdd_stop_sap_go_adapter(adapter); 9442 break; 9443 case QDF_OCB_MODE: 9444 hdd_stop_ocb_adapter(adapter); 9445 break; 9446 default: 9447 break; 9448 } 9449 9450 /* Moved from vdev destroy as it is per adapter */ 9451 wlan_cfg80211_cleanup_scan_queue(hdd_ctx->pdev, adapter->dev); 9452 9453 /* Disable all links (expect default index) in adapter. 9454 * Set link address to NULL 9455 */ 9456 hdd_adapter_disable_all_links(adapter); 9457 9458 /* This function should be invoked at the end of this api*/ 9459 hdd_dump_func_call_map(); 9460 hdd_exit(); 9461 9462 return QDF_STATUS_SUCCESS; 9463 } 9464 9465 QDF_STATUS hdd_stop_adapter(struct hdd_context *hdd_ctx, 9466 struct hdd_adapter *adapter) 9467 { 9468 QDF_STATUS status; 9469 9470 if (adapter->device_mode == QDF_STA_MODE) 9471 status = hdd_stop_link_adapter(hdd_ctx, adapter); 9472 9473 status = hdd_stop_adapter_ext(hdd_ctx, adapter); 9474 9475 return status; 9476 } 9477 9478 /** 9479 * hdd_deinit_all_adapters - deinit all adapters 9480 * @hdd_ctx: HDD context 9481 * @rtnl_held: True if RTNL lock held 9482 * 9483 */ 9484 void hdd_deinit_all_adapters(struct hdd_context *hdd_ctx, bool rtnl_held) 9485 { 9486 struct hdd_adapter *adapter, *next_adapter = NULL; 9487 9488 hdd_enter(); 9489 9490 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 9491 NET_DEV_HOLD_DEINIT_ALL_ADAPTERS) { 9492 hdd_deinit_adapter(hdd_ctx, adapter, rtnl_held); 9493 hdd_adapter_dev_put_debug(adapter, 9494 NET_DEV_HOLD_DEINIT_ALL_ADAPTERS); 9495 } 9496 9497 hdd_exit(); 9498 } 9499 9500 QDF_STATUS hdd_stop_all_adapters(struct hdd_context *hdd_ctx) 9501 { 9502 struct hdd_adapter *adapter, *next_adapter = NULL; 9503 9504 hdd_enter(); 9505 9506 ucfg_pre_cac_stop(hdd_ctx->psoc); 9507 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 9508 NET_DEV_HOLD_STOP_ALL_ADAPTERS) { 9509 hdd_stop_adapter(hdd_ctx, adapter); 9510 hdd_adapter_dev_put_debug(adapter, 9511 NET_DEV_HOLD_STOP_ALL_ADAPTERS); 9512 } 9513 9514 hdd_exit(); 9515 9516 return QDF_STATUS_SUCCESS; 9517 } 9518 9519 void hdd_set_netdev_flags(struct hdd_adapter *adapter) 9520 { 9521 bool enable_csum = false; 9522 bool enable_lro; 9523 enum QDF_OPMODE device_mode; 9524 struct hdd_context *hdd_ctx; 9525 ol_txrx_soc_handle soc; 9526 uint64_t temp; 9527 9528 if (!adapter || !adapter->dev) { 9529 hdd_err("invalid input!"); 9530 return; 9531 } 9532 device_mode = adapter->device_mode; 9533 9534 hdd_ctx = adapter->hdd_ctx; 9535 soc = cds_get_context(QDF_MODULE_ID_SOC); 9536 9537 if (!soc || !hdd_ctx) { 9538 hdd_err("invalid SOC or HDD context!"); 9539 return; 9540 } 9541 9542 /* Determine device_mode specific configuration */ 9543 9544 enable_lro = !!cdp_cfg_get(soc, cfg_dp_lro_enable); 9545 enable_csum = !!cdp_cfg_get(soc, 9546 cfg_dp_enable_ip_tcp_udp_checksum_offload); 9547 switch (device_mode) { 9548 case QDF_P2P_DEVICE_MODE: 9549 case QDF_P2P_CLIENT_MODE: 9550 enable_csum = !!cdp_cfg_get(soc, 9551 cfg_dp_enable_p2p_ip_tcp_udp_checksum_offload); 9552 break; 9553 case QDF_P2P_GO_MODE: 9554 enable_csum = !!cdp_cfg_get(soc, 9555 cfg_dp_enable_p2p_ip_tcp_udp_checksum_offload); 9556 enable_lro = false; 9557 break; 9558 case QDF_SAP_MODE: 9559 enable_lro = false; 9560 break; 9561 case QDF_NDI_MODE: 9562 case QDF_NAN_DISC_MODE: 9563 enable_csum = !!cdp_cfg_get(soc, 9564 cfg_dp_enable_nan_ip_tcp_udp_checksum_offload); 9565 break; 9566 default: 9567 break; 9568 } 9569 9570 /* Set netdev flags */ 9571 9572 /* 9573 * In case of USB tethering, LRO is disabled. If SSR happened 9574 * during that time, then as part of SSR init, do not enable 9575 * the LRO again. Keep the LRO state same as before SSR. 9576 */ 9577 if (enable_lro && !(qdf_atomic_read(&hdd_ctx->vendor_disable_lro_flag))) 9578 adapter->dev->features |= NETIF_F_LRO; 9579 9580 if (enable_csum) 9581 adapter->dev->features |= 9582 (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM); 9583 9584 if (cdp_cfg_get(soc, cfg_dp_tso_enable) && enable_csum) { 9585 adapter->dev->features |= TSO_FEATURE_FLAGS; 9586 adapter->tso_csum_feature_enabled = 1; 9587 } 9588 9589 if (cdp_cfg_get(soc, cfg_dp_sg_enable)) 9590 adapter->dev->features |= NETIF_F_SG; 9591 9592 adapter->dev->features |= NETIF_F_RXCSUM; 9593 temp = (uint64_t)adapter->dev->features; 9594 9595 hdd_debug("adapter mode %u dev feature 0x%llx", device_mode, temp); 9596 } 9597 9598 #ifdef QCA_LL_LEGACY_TX_FLOW_CONTROL 9599 /** 9600 * hdd_adapter_abort_tx_flow() - Abort the tx flow control 9601 * @adapter: pointer to hdd adapter 9602 * 9603 * Resume tx and stop the tx flow control timer if the tx is paused 9604 * and the flow control timer is running. This function is called by 9605 * SSR to avoid the inconsistency of tx status before and after SSR. 9606 * 9607 * Return: void 9608 */ 9609 static void hdd_adapter_abort_tx_flow(struct hdd_adapter *adapter) 9610 { 9611 if (adapter->deflink->hdd_stats.tx_rx_stats.is_txflow_paused && 9612 QDF_TIMER_STATE_RUNNING == 9613 qdf_mc_timer_get_current_state( 9614 &adapter->tx_flow_control_timer)) { 9615 hdd_tx_resume_timer_expired_handler(adapter); 9616 qdf_mc_timer_stop(&adapter->tx_flow_control_timer); 9617 } 9618 } 9619 #else 9620 static void hdd_adapter_abort_tx_flow(struct hdd_adapter *adapter) 9621 { 9622 } 9623 #endif 9624 9625 QDF_STATUS hdd_reset_all_adapters(struct hdd_context *hdd_ctx) 9626 { 9627 struct hdd_adapter *adapter, *next_adapter = NULL; 9628 bool value; 9629 struct wlan_objmgr_vdev *vdev; 9630 struct wlan_hdd_link_info *link_info; 9631 9632 hdd_enter(); 9633 9634 ucfg_mlme_get_sap_internal_restart(hdd_ctx->psoc, &value); 9635 9636 9637 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 9638 NET_DEV_HOLD_RESET_ALL_ADAPTERS) { 9639 hdd_info("[SSR] reset adapter with device mode %s(%d)", 9640 qdf_opmode_str(adapter->device_mode), 9641 adapter->device_mode); 9642 9643 hdd_adapter_for_each_active_link_info(adapter, link_info) { 9644 hdd_adapter_abort_tx_flow(adapter); 9645 9646 if ((adapter->device_mode == QDF_STA_MODE) || 9647 (adapter->device_mode == QDF_P2P_CLIENT_MODE)) { 9648 hdd_send_twt_del_all_sessions_to_userspace(link_info); 9649 9650 /* Stop tdls timers */ 9651 vdev = hdd_objmgr_get_vdev_by_user(link_info, 9652 WLAN_OSIF_TDLS_ID); 9653 if (vdev) { 9654 hdd_notify_tdls_reset_adapter(vdev); 9655 hdd_objmgr_put_vdev_by_user(vdev, 9656 WLAN_OSIF_TDLS_ID); 9657 } 9658 } 9659 9660 if (value && 9661 adapter->device_mode == QDF_SAP_MODE) { 9662 hdd_medium_assess_ssr_enable_flag(); 9663 wlan_hdd_netif_queue_control(adapter, 9664 WLAN_STOP_ALL_NETIF_QUEUE, 9665 WLAN_CONTROL_PATH); 9666 } else { 9667 wlan_hdd_netif_queue_control(adapter, 9668 WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER, 9669 WLAN_CONTROL_PATH); 9670 } 9671 9672 /* 9673 * Clear fc flag if it was set before SSR to avoid 9674 * TX queues permanently stopped after SSR. 9675 * Here WLAN_START_ALL_NETIF_QUEUE will actually 9676 * not start any queue since it's blocked by reason 9677 * WLAN_CONTROL_PATH. 9678 */ 9679 if (adapter->pause_map & (1 << WLAN_DATA_FLOW_CONTROL)) 9680 wlan_hdd_netif_queue_control(adapter, 9681 WLAN_START_ALL_NETIF_QUEUE, 9682 WLAN_DATA_FLOW_CONTROL); 9683 9684 hdd_reset_scan_operation(link_info); 9685 9686 if (test_bit(WMM_INIT_DONE, &adapter->event_flags)) { 9687 hdd_wmm_adapter_close(adapter); 9688 clear_bit(WMM_INIT_DONE, &adapter->event_flags); 9689 } 9690 9691 hdd_debug("Flush any mgmt references held by peer"); 9692 hdd_stop_adapter(hdd_ctx, adapter); 9693 } 9694 hdd_adapter_dev_put_debug(adapter, 9695 NET_DEV_HOLD_RESET_ALL_ADAPTERS); 9696 } 9697 9698 hdd_exit(); 9699 9700 return QDF_STATUS_SUCCESS; 9701 } 9702 9703 static bool hdd_is_any_link_opened(struct hdd_adapter *adapter) 9704 { 9705 struct wlan_hdd_link_info *link_info; 9706 9707 hdd_adapter_for_each_active_link_info(adapter, link_info) { 9708 if (test_bit(SME_SESSION_OPENED, &link_info->link_flags)) 9709 return true; 9710 } 9711 return false; 9712 } 9713 9714 bool hdd_is_any_interface_open(struct hdd_context *hdd_ctx) 9715 { 9716 struct hdd_adapter *adapter, *next_adapter = NULL; 9717 wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_IS_ANY_INTERFACE_OPEN; 9718 9719 if (hdd_get_conparam() == QDF_GLOBAL_FTM_MODE) { 9720 hdd_info("FTM mode, don't close the module"); 9721 return true; 9722 } 9723 9724 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 9725 dbgid) { 9726 if (test_bit(DEVICE_IFACE_OPENED, &adapter->event_flags) || 9727 hdd_is_any_link_opened(adapter)) { 9728 hdd_adapter_dev_put_debug(adapter, dbgid); 9729 if (next_adapter) 9730 hdd_adapter_dev_put_debug(next_adapter, dbgid); 9731 return true; 9732 } 9733 hdd_adapter_dev_put_debug(adapter, dbgid); 9734 } 9735 9736 return false; 9737 } 9738 9739 bool hdd_is_interface_up(struct hdd_adapter *adapter) 9740 { 9741 if (test_bit(DEVICE_IFACE_OPENED, &adapter->event_flags)) 9742 return true; 9743 else 9744 return false; 9745 } 9746 9747 #ifdef FEATURE_MONITOR_MODE_SUPPORT 9748 #ifdef WLAN_FEATURE_11BE 9749 static inline bool wlan_hdd_is_mon_channel_bw_valid(enum phy_ch_width ch_width) 9750 { 9751 if (ch_width > CH_WIDTH_320MHZ || 9752 (!cds_is_sub_20_mhz_enabled() && (ch_width == CH_WIDTH_5MHZ || 9753 ch_width == CH_WIDTH_10MHZ))) 9754 return false; 9755 9756 return true; 9757 } 9758 #else 9759 static inline bool wlan_hdd_is_mon_channel_bw_valid(enum phy_ch_width ch_width) 9760 { 9761 if (ch_width > CH_WIDTH_10MHZ || 9762 (!cds_is_sub_20_mhz_enabled() && (ch_width == CH_WIDTH_5MHZ || 9763 ch_width == CH_WIDTH_10MHZ))) 9764 return false; 9765 9766 return true; 9767 } 9768 #endif 9769 9770 int wlan_hdd_set_mon_chan(struct hdd_adapter *adapter, qdf_freq_t freq, 9771 uint32_t bandwidth) 9772 { 9773 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); 9774 struct hdd_station_ctx *sta_ctx; 9775 struct hdd_mon_set_ch_info *ch_info; 9776 QDF_STATUS status; 9777 struct qdf_mac_addr bssid; 9778 struct channel_change_req *req; 9779 struct ch_params ch_params; 9780 enum phy_ch_width max_fw_bw; 9781 enum phy_ch_width ch_width; 9782 int ret; 9783 9784 if ((hdd_get_conparam() != QDF_GLOBAL_MONITOR_MODE) && 9785 (!policy_mgr_is_sta_mon_concurrency(hdd_ctx->psoc))) { 9786 hdd_err("Not supported, device is not in monitor mode"); 9787 return -EINVAL; 9788 } 9789 9790 if (adapter->device_mode != QDF_MONITOR_MODE) { 9791 hdd_err_rl("Not supported, adapter is not in monitor mode"); 9792 return -EINVAL; 9793 } 9794 9795 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter->deflink); 9796 ch_info = &sta_ctx->ch_info; 9797 9798 /* Verify the BW before accepting this request */ 9799 ch_width = bandwidth; 9800 9801 if (!wlan_hdd_is_mon_channel_bw_valid(ch_width)) { 9802 hdd_err("invalid BW received %d", ch_width); 9803 return -EINVAL; 9804 } 9805 9806 max_fw_bw = sme_get_vht_ch_width(); 9807 9808 hdd_debug("max fw BW %d ch width %d", max_fw_bw, ch_width); 9809 if ((ch_width == CH_WIDTH_160MHZ && 9810 max_fw_bw <= WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ) || 9811 (ch_width == CH_WIDTH_80P80MHZ && 9812 max_fw_bw <= WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ)) { 9813 hdd_err("FW does not support this BW %d max BW supported %d", 9814 ch_width, max_fw_bw); 9815 return -EINVAL; 9816 } 9817 9818 if (!hdd_is_target_eht_phy_ch_width_supported(ch_width)) 9819 return -EINVAL; 9820 9821 ret = hdd_validate_channel_and_bandwidth(adapter, freq, bandwidth); 9822 if (ret) { 9823 hdd_err("Invalid CH and BW combo"); 9824 return ret; 9825 } 9826 9827 hdd_debug("Set monitor mode frequency %d", freq); 9828 qdf_mem_copy(bssid.bytes, adapter->mac_addr.bytes, 9829 QDF_MAC_ADDR_SIZE); 9830 9831 ch_params.ch_width = bandwidth; 9832 wlan_reg_set_channel_params_for_pwrmode(hdd_ctx->pdev, freq, 0, 9833 &ch_params, 9834 REG_CURRENT_PWR_MODE); 9835 9836 if (ch_params.ch_width == CH_WIDTH_INVALID) { 9837 hdd_err("Invalid capture channel or bandwidth for a country"); 9838 return -EINVAL; 9839 } 9840 if (wlan_hdd_change_hw_mode_for_given_chnl(adapter, freq, 9841 POLICY_MGR_UPDATE_REASON_SET_OPER_CHAN)) { 9842 hdd_err("Failed to change hw mode"); 9843 return -EINVAL; 9844 } 9845 9846 if (adapter->monitor_mode_vdev_up_in_progress) { 9847 hdd_err_rl("monitor mode vdev up in progress"); 9848 return -EBUSY; 9849 } 9850 9851 status = qdf_event_reset(&adapter->qdf_monitor_mode_vdev_up_event); 9852 if (QDF_IS_STATUS_ERROR(status)) { 9853 hdd_err_rl("failed to reinit monitor mode vdev up event"); 9854 return qdf_status_to_os_return(status); 9855 } 9856 adapter->monitor_mode_vdev_up_in_progress = true; 9857 9858 qdf_mem_zero(&ch_params, sizeof(struct ch_params)); 9859 9860 req = qdf_mem_malloc(sizeof(struct channel_change_req)); 9861 if (!req) 9862 return -ENOMEM; 9863 req->vdev_id = adapter->deflink->vdev_id; 9864 req->target_chan_freq = freq; 9865 req->ch_width = ch_width; 9866 9867 ch_params.ch_width = ch_width; 9868 hdd_select_cbmode(adapter, freq, 0, &ch_params); 9869 9870 req->sec_ch_offset = ch_params.sec_ch_offset; 9871 req->center_freq_seg0 = ch_params.center_freq_seg0; 9872 req->center_freq_seg1 = ch_params.center_freq_seg1; 9873 9874 sme_fill_channel_change_request(hdd_ctx->mac_handle, req, 9875 ch_info->phy_mode); 9876 status = sme_send_channel_change_req(hdd_ctx->mac_handle, req); 9877 qdf_mem_free(req); 9878 if (status) { 9879 hdd_err("Status: %d Failed to set sme_roam Channel for monitor mode", 9880 status); 9881 adapter->monitor_mode_vdev_up_in_progress = false; 9882 return qdf_status_to_os_return(status); 9883 } 9884 9885 adapter->mon_chan_freq = freq; 9886 adapter->mon_bandwidth = bandwidth; 9887 9888 /* block on a completion variable until vdev up success*/ 9889 status = qdf_wait_for_event_completion( 9890 &adapter->qdf_monitor_mode_vdev_up_event, 9891 WLAN_MONITOR_MODE_VDEV_UP_EVT); 9892 if (QDF_IS_STATUS_ERROR(status)) { 9893 hdd_err_rl("monitor vdev up event time out vdev id: %d", 9894 adapter->deflink->vdev_id); 9895 if (adapter->qdf_monitor_mode_vdev_up_event.force_set) 9896 /* 9897 * SSR/PDR has caused shutdown, which has 9898 * forcefully set the event. 9899 */ 9900 hdd_err_rl("monitor mode vdev up event forcefully set"); 9901 else if (status == QDF_STATUS_E_TIMEOUT) 9902 hdd_err("monitor mode vdev up timed out"); 9903 else 9904 hdd_err_rl("Failed monitor mode vdev up(status-%d)", 9905 status); 9906 9907 adapter->monitor_mode_vdev_up_in_progress = false; 9908 } 9909 9910 return qdf_status_to_os_return(status); 9911 } 9912 #endif 9913 9914 #if defined MSM_PLATFORM && (LINUX_VERSION_CODE <= KERNEL_VERSION(4, 19, 0)) 9915 /** 9916 * hdd_stop_p2p_go() - call cfg80211 API to stop P2P GO 9917 * @adapter: pointer to adapter 9918 * 9919 * This function calls cfg80211 API to stop P2P GO 9920 * 9921 * Return: None 9922 */ 9923 static void hdd_stop_p2p_go(struct hdd_adapter *adapter) 9924 { 9925 hdd_debug("[SSR] send stop ap to supplicant"); 9926 cfg80211_ap_stopped(adapter->dev, GFP_KERNEL); 9927 } 9928 9929 static inline void hdd_delete_sta(struct hdd_adapter *adapter) 9930 { 9931 } 9932 9933 #else 9934 static void hdd_stop_p2p_go(struct hdd_adapter *adapter) 9935 { 9936 hdd_debug("[SSR] send stop iface ap to supplicant"); 9937 cfg80211_stop_iface(adapter->hdd_ctx->wiphy, &adapter->wdev, 9938 GFP_KERNEL); 9939 } 9940 9941 /** 9942 * hdd_delete_sta() - call cfg80211 API to delete STA 9943 * @adapter: pointer to adapter 9944 * 9945 * This function calls cfg80211 API to delete STA 9946 * 9947 * Return: None 9948 */ 9949 static void hdd_delete_sta(struct hdd_adapter *adapter) 9950 { 9951 struct qdf_mac_addr bcast_mac = QDF_MAC_ADDR_BCAST_INIT; 9952 9953 hdd_debug("[SSR] send restart supplicant"); 9954 /* event supplicant to restart */ 9955 cfg80211_del_sta(adapter->dev, 9956 (const u8 *)&bcast_mac.bytes[0], 9957 GFP_KERNEL); 9958 } 9959 #endif 9960 9961 QDF_STATUS hdd_start_all_adapters(struct hdd_context *hdd_ctx, bool rtnl_held) 9962 { 9963 struct hdd_adapter *adapter, *next_adapter = NULL; 9964 bool value; 9965 wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_START_ALL_ADAPTERS; 9966 int ret; 9967 9968 hdd_enter(); 9969 9970 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 9971 dbgid) { 9972 if (!hdd_is_interface_up(adapter) && 9973 adapter->device_mode != QDF_NDI_MODE) { 9974 hdd_adapter_dev_put_debug(adapter, dbgid); 9975 continue; 9976 } 9977 9978 hdd_debug("[SSR] start adapter with device mode %s(%d)", 9979 qdf_opmode_str(adapter->device_mode), 9980 adapter->device_mode); 9981 9982 hdd_wmm_dscp_initial_state(adapter); 9983 9984 switch (adapter->device_mode) { 9985 case QDF_STA_MODE: 9986 case QDF_P2P_CLIENT_MODE: 9987 case QDF_P2P_DEVICE_MODE: 9988 case QDF_NAN_DISC_MODE: 9989 9990 ret = hdd_start_station_adapter(adapter); 9991 if (ret) { 9992 hdd_err("[SSR] Failed to start station adapter: %d", 9993 ret); 9994 hdd_adapter_dev_put_debug(adapter, dbgid); 9995 continue; 9996 } 9997 if (adapter->device_mode == QDF_STA_MODE) { 9998 ret = hdd_start_link_adapter(adapter); 9999 if (ret) { 10000 hdd_err("[SSR] Failed to start link adapter: %d", 10001 ret); 10002 hdd_stop_adapter(hdd_ctx, adapter); 10003 hdd_adapter_dev_put_debug(adapter, 10004 dbgid); 10005 continue; 10006 } 10007 } 10008 10009 /* Open the gates for HDD to receive Wext commands */ 10010 adapter->is_link_up_service_needed = false; 10011 10012 if ((adapter->device_mode == QDF_NAN_DISC_MODE || 10013 (adapter->device_mode == QDF_STA_MODE && 10014 !ucfg_nan_is_vdev_creation_allowed( 10015 hdd_ctx->psoc))) && 10016 cds_is_driver_recovering()) 10017 ucfg_nan_disable_ind_to_userspace( 10018 hdd_ctx->psoc); 10019 10020 hdd_register_tx_flow_control(adapter, 10021 hdd_tx_resume_timer_expired_handler, 10022 hdd_tx_resume_cb, 10023 hdd_tx_flow_control_is_pause); 10024 10025 hdd_register_hl_netdev_fc_timer( 10026 adapter, 10027 hdd_tx_resume_timer_expired_handler); 10028 10029 hdd_lpass_notify_start(adapter->deflink); 10030 break; 10031 10032 case QDF_SAP_MODE: 10033 ucfg_mlme_get_sap_internal_restart(hdd_ctx->psoc, 10034 &value); 10035 if (value) 10036 hdd_start_ap_adapter(adapter, rtnl_held); 10037 10038 break; 10039 10040 case QDF_P2P_GO_MODE: 10041 hdd_delete_sta(adapter); 10042 break; 10043 case QDF_MONITOR_MODE: 10044 if (wlan_hdd_is_session_type_monitor( 10045 adapter->device_mode) && 10046 ucfg_pkt_capture_get_mode(hdd_ctx->psoc) != 10047 PACKET_CAPTURE_MODE_DISABLE) { 10048 struct hdd_adapter *sta_adapter; 10049 10050 sta_adapter = hdd_get_adapter(hdd_ctx, 10051 QDF_STA_MODE); 10052 if (!sta_adapter) { 10053 hdd_err("No station interface found"); 10054 return -EINVAL; 10055 } 10056 10057 hdd_map_monitor_interface_vdev(sta_adapter); 10058 break; 10059 } 10060 hdd_start_station_adapter(adapter); 10061 hdd_set_mon_rx_cb(adapter->dev); 10062 10063 wlan_hdd_set_mon_chan( 10064 adapter, adapter->mon_chan_freq, 10065 adapter->mon_bandwidth); 10066 break; 10067 case QDF_NDI_MODE: 10068 hdd_ndi_start(adapter->dev->name, 0); 10069 break; 10070 default: 10071 break; 10072 } 10073 /* 10074 * Action frame registered in one adapter which will 10075 * applicable to all interfaces 10076 */ 10077 if (hdd_set_fw_params(adapter)) 10078 hdd_err("Failed to set adapter FW params after SSR!"); 10079 10080 wlan_hdd_cfg80211_register_frames(adapter); 10081 hdd_create_adapter_sysfs_files(adapter); 10082 hdd_adapter_dev_put_debug(adapter, dbgid); 10083 } 10084 10085 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 10086 dbgid) { 10087 if (!hdd_is_interface_up(adapter)) { 10088 hdd_adapter_dev_put_debug(adapter, dbgid); 10089 continue; 10090 } 10091 10092 if (adapter->device_mode == QDF_P2P_GO_MODE) 10093 hdd_stop_p2p_go(adapter); 10094 10095 hdd_adapter_dev_put_debug(adapter, dbgid); 10096 } 10097 10098 hdd_exit(); 10099 10100 return QDF_STATUS_SUCCESS; 10101 } 10102 10103 void hdd_adapter_dev_hold_debug(struct hdd_adapter *adapter, 10104 wlan_net_dev_ref_dbgid dbgid) 10105 { 10106 if (dbgid >= NET_DEV_HOLD_ID_MAX) { 10107 hdd_err("Invalid debug id: %d", dbgid); 10108 QDF_BUG(0); 10109 } 10110 dev_hold(adapter->dev); 10111 qdf_atomic_inc(&adapter->net_dev_hold_ref_count[dbgid]); 10112 } 10113 10114 void hdd_adapter_dev_put_debug(struct hdd_adapter *adapter, 10115 wlan_net_dev_ref_dbgid dbgid) 10116 { 10117 if (dbgid >= NET_DEV_HOLD_ID_MAX) { 10118 hdd_err("Invalid debug id: %d", dbgid); 10119 QDF_BUG(0); 10120 } 10121 10122 if (qdf_atomic_dec_return( 10123 &adapter->net_dev_hold_ref_count[dbgid]) < 0) { 10124 hdd_err("dev_put detected without dev_hold for debug id: %s", 10125 net_dev_ref_debug_string_from_id(dbgid)); 10126 QDF_BUG(0); 10127 } 10128 10129 if (adapter->dev) { 10130 dev_put(adapter->dev); 10131 } else { 10132 hdd_err("adapter->dev is NULL"); 10133 QDF_BUG(0); 10134 } 10135 } 10136 10137 QDF_STATUS hdd_get_front_adapter(struct hdd_context *hdd_ctx, 10138 struct hdd_adapter **out_adapter) 10139 { 10140 QDF_STATUS status; 10141 qdf_list_node_t *node; 10142 10143 *out_adapter = NULL; 10144 10145 qdf_spin_lock_bh(&hdd_ctx->hdd_adapter_lock); 10146 status = qdf_list_peek_front(&hdd_ctx->hdd_adapters, &node); 10147 qdf_spin_unlock_bh(&hdd_ctx->hdd_adapter_lock); 10148 10149 if (QDF_IS_STATUS_ERROR(status)) 10150 return status; 10151 10152 *out_adapter = qdf_container_of(node, struct hdd_adapter, node); 10153 10154 return QDF_STATUS_SUCCESS; 10155 } 10156 10157 QDF_STATUS hdd_get_next_adapter(struct hdd_context *hdd_ctx, 10158 struct hdd_adapter *current_adapter, 10159 struct hdd_adapter **out_adapter) 10160 { 10161 QDF_STATUS status; 10162 qdf_list_node_t *node; 10163 10164 *out_adapter = NULL; 10165 10166 qdf_spin_lock_bh(&hdd_ctx->hdd_adapter_lock); 10167 status = qdf_list_peek_next(&hdd_ctx->hdd_adapters, 10168 ¤t_adapter->node, 10169 &node); 10170 qdf_spin_unlock_bh(&hdd_ctx->hdd_adapter_lock); 10171 10172 if (QDF_IS_STATUS_ERROR(status)) 10173 return status; 10174 10175 *out_adapter = qdf_container_of(node, struct hdd_adapter, node); 10176 10177 return status; 10178 } 10179 10180 QDF_STATUS hdd_get_front_adapter_no_lock(struct hdd_context *hdd_ctx, 10181 struct hdd_adapter **out_adapter) 10182 { 10183 QDF_STATUS status; 10184 qdf_list_node_t *node; 10185 10186 *out_adapter = NULL; 10187 10188 status = qdf_list_peek_front(&hdd_ctx->hdd_adapters, &node); 10189 10190 if (QDF_IS_STATUS_ERROR(status)) 10191 return status; 10192 10193 *out_adapter = qdf_container_of(node, struct hdd_adapter, node); 10194 10195 return QDF_STATUS_SUCCESS; 10196 } 10197 10198 QDF_STATUS hdd_get_next_adapter_no_lock(struct hdd_context *hdd_ctx, 10199 struct hdd_adapter *current_adapter, 10200 struct hdd_adapter **out_adapter) 10201 { 10202 QDF_STATUS status; 10203 qdf_list_node_t *node; 10204 10205 if (!current_adapter) 10206 return QDF_STATUS_E_INVAL; 10207 10208 *out_adapter = NULL; 10209 10210 status = qdf_list_peek_next(&hdd_ctx->hdd_adapters, 10211 ¤t_adapter->node, 10212 &node); 10213 10214 if (QDF_IS_STATUS_ERROR(status)) 10215 return status; 10216 10217 *out_adapter = qdf_container_of(node, struct hdd_adapter, node); 10218 10219 return status; 10220 } 10221 10222 QDF_STATUS hdd_remove_adapter(struct hdd_context *hdd_ctx, 10223 struct hdd_adapter *adapter) 10224 { 10225 QDF_STATUS status; 10226 10227 qdf_spin_lock_bh(&hdd_ctx->hdd_adapter_lock); 10228 status = qdf_list_remove_node(&hdd_ctx->hdd_adapters, &adapter->node); 10229 qdf_spin_unlock_bh(&hdd_ctx->hdd_adapter_lock); 10230 10231 return status; 10232 } 10233 10234 QDF_STATUS hdd_remove_front_adapter(struct hdd_context *hdd_ctx, 10235 struct hdd_adapter **out_adapter) 10236 { 10237 QDF_STATUS status; 10238 qdf_list_node_t *node; 10239 10240 *out_adapter = NULL; 10241 10242 qdf_spin_lock_bh(&hdd_ctx->hdd_adapter_lock); 10243 status = qdf_list_remove_front(&hdd_ctx->hdd_adapters, &node); 10244 qdf_spin_unlock_bh(&hdd_ctx->hdd_adapter_lock); 10245 10246 if (QDF_IS_STATUS_ERROR(status)) 10247 return status; 10248 10249 *out_adapter = qdf_container_of(node, struct hdd_adapter, node); 10250 10251 return status; 10252 } 10253 10254 QDF_STATUS hdd_add_adapter_back(struct hdd_context *hdd_ctx, 10255 struct hdd_adapter *adapter) 10256 { 10257 QDF_STATUS status; 10258 10259 qdf_spin_lock_bh(&hdd_ctx->hdd_adapter_lock); 10260 status = qdf_list_insert_back(&hdd_ctx->hdd_adapters, &adapter->node); 10261 qdf_spin_unlock_bh(&hdd_ctx->hdd_adapter_lock); 10262 10263 return status; 10264 } 10265 10266 QDF_STATUS hdd_add_adapter_front(struct hdd_context *hdd_ctx, 10267 struct hdd_adapter *adapter) 10268 { 10269 QDF_STATUS status; 10270 10271 qdf_spin_lock_bh(&hdd_ctx->hdd_adapter_lock); 10272 status = qdf_list_insert_front(&hdd_ctx->hdd_adapters, &adapter->node); 10273 qdf_spin_unlock_bh(&hdd_ctx->hdd_adapter_lock); 10274 10275 return status; 10276 } 10277 10278 void hdd_validate_next_adapter(struct hdd_adapter **curr, 10279 struct hdd_adapter **next, 10280 wlan_net_dev_ref_dbgid dbg_id) 10281 { 10282 if (!*curr || !*next || *curr != *next) 10283 return; 10284 10285 hdd_err("Validation failed"); 10286 hdd_adapter_dev_put_debug(*curr, dbg_id); 10287 *curr = NULL; 10288 *next = NULL; 10289 } 10290 10291 QDF_STATUS hdd_adapter_iterate(hdd_adapter_iterate_cb cb, void *context) 10292 { 10293 struct hdd_context *hdd_ctx; 10294 struct hdd_adapter *cache[HDD_MAX_ADAPTERS]; 10295 struct hdd_adapter *adapter; 10296 uint32_t n_cache = 0; 10297 QDF_STATUS ret = QDF_STATUS_SUCCESS; 10298 QDF_STATUS status; 10299 int i; 10300 struct wlan_hdd_link_info *link_info; 10301 10302 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 10303 if (unlikely(!hdd_ctx)) 10304 return QDF_STATUS_E_FAILURE; 10305 10306 qdf_spin_lock_bh(&hdd_ctx->hdd_adapter_lock); 10307 for (hdd_get_front_adapter_no_lock(hdd_ctx, &adapter); adapter; 10308 hdd_get_next_adapter_no_lock(hdd_ctx, adapter, &adapter)) { 10309 cache[n_cache++] = adapter; 10310 } 10311 qdf_spin_unlock_bh(&hdd_ctx->hdd_adapter_lock); 10312 10313 for (i = 0; i < n_cache; i++) { 10314 adapter = hdd_adapter_get_by_reference(hdd_ctx, cache[i]); 10315 if (!adapter) { 10316 /* 10317 * detected remove while iterating 10318 * concurrency failure 10319 */ 10320 ret = QDF_STATUS_E_FAILURE; 10321 continue; 10322 } 10323 hdd_adapter_for_each_active_link_info(adapter, link_info) { 10324 status = cb(link_info, context); 10325 if (status != QDF_STATUS_SUCCESS) { 10326 hdd_adapter_put(adapter); 10327 return status; 10328 } 10329 } 10330 hdd_adapter_put(adapter); 10331 } 10332 10333 return ret; 10334 } 10335 10336 struct hdd_adapter *hdd_get_adapter_by_rand_macaddr( 10337 struct hdd_context *hdd_ctx, tSirMacAddr mac_addr) 10338 { 10339 struct hdd_adapter *adapter, *next_adapter = NULL; 10340 wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_GET_ADAPTER_BY_RAND_MACADDR; 10341 struct wlan_hdd_link_info *link_info; 10342 10343 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 10344 dbgid) { 10345 if (adapter->device_mode != QDF_STA_MODE && 10346 adapter->device_mode != QDF_P2P_CLIENT_MODE && 10347 adapter->device_mode != QDF_P2P_DEVICE_MODE) { 10348 hdd_adapter_dev_put_debug(adapter, dbgid); 10349 continue; 10350 } 10351 10352 hdd_adapter_for_each_active_link_info(adapter, link_info) { 10353 if (ucfg_p2p_check_random_mac(hdd_ctx->psoc, 10354 link_info->vdev_id, 10355 mac_addr)) { 10356 hdd_adapter_dev_put_debug(adapter, dbgid); 10357 if (next_adapter) 10358 hdd_adapter_dev_put_debug(next_adapter, 10359 dbgid); 10360 return adapter; 10361 } 10362 } 10363 hdd_adapter_dev_put_debug(adapter, dbgid); 10364 } 10365 10366 return NULL; 10367 } 10368 10369 #ifdef WLAN_HDD_MULTI_VDEV_SINGLE_NDEV 10370 struct hdd_adapter *hdd_get_adapter_by_macaddr(struct hdd_context *hdd_ctx, 10371 tSirMacAddr mac_addr) 10372 { 10373 struct hdd_adapter *adapter, *next_adapter = NULL; 10374 wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_GET_ADAPTER_BY_MACADDR; 10375 struct qdf_mac_addr zero_mac_addr = QDF_MAC_ADDR_ZERO_INIT; 10376 struct wlan_hdd_link_info *link_info; 10377 10378 if (!qdf_mem_cmp(mac_addr, zero_mac_addr.bytes, sizeof(tSirMacAddr))) 10379 return NULL; 10380 10381 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 10382 dbgid) { 10383 if (!qdf_mem_cmp(adapter->mac_addr.bytes, 10384 mac_addr, sizeof(tSirMacAddr))) { 10385 hdd_adapter_dev_put_debug(adapter, dbgid); 10386 if (next_adapter) 10387 hdd_adapter_dev_put_debug(next_adapter, 10388 dbgid); 10389 return adapter; 10390 } 10391 hdd_adapter_for_each_active_link_info(adapter, link_info) { 10392 if (!qdf_mem_cmp(link_info->link_addr.bytes, 10393 mac_addr, sizeof(tSirMacAddr))) { 10394 hdd_adapter_dev_put_debug(adapter, dbgid); 10395 if (next_adapter) 10396 hdd_adapter_dev_put_debug(next_adapter, 10397 dbgid); 10398 return adapter; 10399 } 10400 } 10401 hdd_adapter_dev_put_debug(adapter, dbgid); 10402 } 10403 10404 return NULL; 10405 } 10406 10407 struct wlan_hdd_link_info * 10408 hdd_get_link_info_by_link_addr(struct hdd_context *hdd_ctx, 10409 struct qdf_mac_addr *link_addr) 10410 { 10411 struct wlan_hdd_link_info *link_info; 10412 struct hdd_adapter *adapter, *next_adapter = NULL; 10413 wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_GET_ADAPTER_BY_MACADDR; 10414 10415 if (!link_addr || qdf_is_macaddr_zero(link_addr)) 10416 return NULL; 10417 10418 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 10419 dbgid) { 10420 hdd_adapter_for_each_link_info(adapter, link_info) { 10421 if (qdf_is_macaddr_equal(link_addr, 10422 &link_info->link_addr)) { 10423 hdd_adapter_dev_put_debug(adapter, dbgid); 10424 if (next_adapter) 10425 hdd_adapter_dev_put_debug(next_adapter, 10426 dbgid); 10427 return link_info; 10428 } 10429 } 10430 hdd_adapter_dev_put_debug(adapter, dbgid); 10431 } 10432 10433 return NULL; 10434 } 10435 #else 10436 struct hdd_adapter *hdd_get_adapter_by_macaddr(struct hdd_context *hdd_ctx, 10437 tSirMacAddr mac_addr) 10438 { 10439 struct hdd_adapter *adapter, *next_adapter = NULL; 10440 wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_GET_ADAPTER_BY_MACADDR; 10441 10442 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 10443 dbgid) { 10444 if (!qdf_mem_cmp(adapter->mac_addr.bytes, 10445 mac_addr, sizeof(tSirMacAddr))) { 10446 hdd_adapter_dev_put_debug(adapter, dbgid); 10447 if (next_adapter) 10448 hdd_adapter_dev_put_debug(next_adapter, 10449 dbgid); 10450 return adapter; 10451 } 10452 10453 if (hdd_adapter_is_sl_ml_adapter(adapter) && 10454 !qdf_mem_cmp(adapter->mld_addr.bytes, 10455 mac_addr, sizeof(tSirMacAddr))) { 10456 hdd_adapter_dev_put_debug(adapter, dbgid); 10457 if (next_adapter) 10458 hdd_adapter_dev_put_debug(next_adapter, dbgid); 10459 return adapter; 10460 } 10461 hdd_adapter_dev_put_debug(adapter, dbgid); 10462 } 10463 10464 return NULL; 10465 } 10466 10467 struct wlan_hdd_link_info * 10468 hdd_get_link_info_by_link_addr(struct hdd_context *hdd_ctx, 10469 struct qdf_mac_addr *link_addr) 10470 { 10471 return NULL; 10472 } 10473 #endif 10474 10475 struct wlan_hdd_link_info * 10476 hdd_get_link_info_by_vdev(struct hdd_context *hdd_ctx, uint32_t vdev_id) 10477 { 10478 struct hdd_adapter *adapter, *next_adapter = NULL; 10479 wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_GET_ADAPTER_BY_VDEV; 10480 struct wlan_hdd_link_info *link_info; 10481 10482 if (vdev_id == WLAN_INVALID_VDEV_ID) 10483 return NULL; 10484 10485 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 10486 dbgid) { 10487 hdd_adapter_for_each_active_link_info(adapter, link_info) { 10488 if (link_info->vdev_id == vdev_id) { 10489 hdd_adapter_dev_put_debug(adapter, dbgid); 10490 if (next_adapter) 10491 hdd_adapter_dev_put_debug(next_adapter, 10492 dbgid); 10493 return link_info; 10494 } 10495 } 10496 hdd_adapter_dev_put_debug(adapter, dbgid); 10497 } 10498 10499 return NULL; 10500 } 10501 10502 struct hdd_adapter *hdd_adapter_get_by_reference(struct hdd_context *hdd_ctx, 10503 struct hdd_adapter *reference) 10504 { 10505 struct hdd_adapter *adapter, *next_adapter = NULL; 10506 wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_ADAPTER_GET_BY_REFERENCE; 10507 10508 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 10509 dbgid) { 10510 if (adapter == reference) { 10511 dev_hold(adapter->dev); 10512 hdd_adapter_dev_put_debug(adapter, dbgid); 10513 if (next_adapter) 10514 hdd_adapter_dev_put_debug(next_adapter, 10515 dbgid); 10516 break; 10517 } 10518 hdd_adapter_dev_put_debug(adapter, dbgid); 10519 } 10520 10521 return adapter; 10522 } 10523 10524 void hdd_adapter_put(struct hdd_adapter *adapter) 10525 { 10526 dev_put(adapter->dev); 10527 } 10528 10529 struct hdd_adapter *hdd_get_adapter_by_iface_name(struct hdd_context *hdd_ctx, 10530 const char *iface_name) 10531 { 10532 struct hdd_adapter *adapter, *next_adapter = NULL; 10533 wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_GET_ADAPTER_BY_IFACE_NAME; 10534 10535 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 10536 dbgid) { 10537 if (!qdf_str_cmp(adapter->dev->name, iface_name)) { 10538 hdd_adapter_dev_put_debug(adapter, dbgid); 10539 if (next_adapter) 10540 hdd_adapter_dev_put_debug(next_adapter, 10541 dbgid); 10542 return adapter; 10543 } 10544 hdd_adapter_dev_put_debug(adapter, dbgid); 10545 } 10546 10547 return NULL; 10548 } 10549 10550 struct hdd_adapter *hdd_get_adapter_by_ifindex(struct hdd_context *hdd_ctx, 10551 uint32_t if_index) 10552 { 10553 struct hdd_adapter *adapter, *next_adapter = NULL; 10554 wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_GET_ADAPTER; 10555 10556 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 10557 dbgid) { 10558 if (adapter->dev->ifindex == if_index) { 10559 hdd_adapter_dev_put_debug(adapter, dbgid); 10560 if (next_adapter) 10561 hdd_adapter_dev_put_debug(next_adapter, 10562 dbgid); 10563 return adapter; 10564 } 10565 hdd_adapter_dev_put_debug(adapter, dbgid); 10566 } 10567 10568 return NULL; 10569 } 10570 10571 /** 10572 * hdd_get_adapter() - to get adapter matching the mode 10573 * @hdd_ctx: hdd context 10574 * @mode: adapter mode 10575 * 10576 * This routine will return the pointer to adapter matching 10577 * with the passed mode. 10578 * 10579 * Return: pointer to adapter or null 10580 */ 10581 struct hdd_adapter *hdd_get_adapter(struct hdd_context *hdd_ctx, 10582 enum QDF_OPMODE mode) 10583 { 10584 struct hdd_adapter *adapter, *next_adapter = NULL; 10585 wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_GET_ADAPTER; 10586 10587 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 10588 dbgid) { 10589 if (adapter->device_mode == mode) { 10590 hdd_adapter_dev_put_debug(adapter, dbgid); 10591 if (next_adapter) 10592 hdd_adapter_dev_put_debug(next_adapter, 10593 dbgid); 10594 return adapter; 10595 } 10596 hdd_adapter_dev_put_debug(adapter, dbgid); 10597 } 10598 10599 return NULL; 10600 } 10601 10602 enum QDF_OPMODE hdd_get_device_mode(uint32_t vdev_id) 10603 { 10604 struct hdd_context *hdd_ctx; 10605 struct wlan_hdd_link_info *link_info; 10606 10607 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 10608 if (!hdd_ctx) 10609 return QDF_MAX_NO_OF_MODE; 10610 10611 link_info = hdd_get_link_info_by_vdev(hdd_ctx, vdev_id); 10612 if (!link_info) { 10613 hdd_err("Invalid vdev"); 10614 return QDF_MAX_NO_OF_MODE; 10615 } 10616 10617 return link_info->adapter->device_mode; 10618 } 10619 10620 uint32_t hdd_get_operating_chan_freq(struct hdd_context *hdd_ctx, 10621 enum QDF_OPMODE mode) 10622 { 10623 struct hdd_adapter *adapter, *next_adapter = NULL; 10624 uint32_t oper_chan_freq = 0; 10625 wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_GET_OPERATING_CHAN_FREQ; 10626 10627 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 10628 dbgid) { 10629 if (mode == adapter->device_mode) { 10630 oper_chan_freq = 10631 hdd_get_link_info_home_channel(adapter->deflink); 10632 hdd_adapter_dev_put_debug(adapter, dbgid); 10633 if (next_adapter) 10634 hdd_adapter_dev_put_debug(next_adapter, 10635 dbgid); 10636 break; 10637 } 10638 hdd_adapter_dev_put_debug(adapter, dbgid); 10639 } 10640 10641 return oper_chan_freq; 10642 } 10643 10644 static inline QDF_STATUS hdd_unregister_wext_all_adapters( 10645 struct hdd_context *hdd_ctx, 10646 bool rtnl_held) 10647 { 10648 struct hdd_adapter *adapter, *next_adapter = NULL; 10649 wlan_net_dev_ref_dbgid dbgid = 10650 NET_DEV_HOLD_UNREGISTER_WEXT_ALL_ADAPTERS; 10651 10652 hdd_enter(); 10653 10654 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 10655 dbgid) { 10656 if (adapter->device_mode == QDF_STA_MODE || 10657 adapter->device_mode == QDF_P2P_CLIENT_MODE || 10658 adapter->device_mode == QDF_P2P_DEVICE_MODE || 10659 adapter->device_mode == QDF_SAP_MODE || 10660 adapter->device_mode == QDF_P2P_GO_MODE) { 10661 hdd_wext_unregister(adapter->dev, rtnl_held); 10662 } 10663 hdd_adapter_dev_put_debug(adapter, dbgid); 10664 } 10665 10666 hdd_exit(); 10667 10668 return QDF_STATUS_SUCCESS; 10669 } 10670 10671 QDF_STATUS hdd_abort_mac_scan_all_adapters(struct hdd_context *hdd_ctx) 10672 { 10673 struct hdd_adapter *adapter, *next_adapter = NULL; 10674 wlan_net_dev_ref_dbgid dbgid = 10675 NET_DEV_HOLD_ABORT_MAC_SCAN_ALL_ADAPTERS; 10676 struct wlan_hdd_link_info *link_info; 10677 10678 hdd_enter(); 10679 10680 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 10681 dbgid) { 10682 if (adapter->device_mode == QDF_STA_MODE || 10683 adapter->device_mode == QDF_P2P_CLIENT_MODE || 10684 adapter->device_mode == QDF_P2P_DEVICE_MODE || 10685 adapter->device_mode == QDF_SAP_MODE || 10686 adapter->device_mode == QDF_P2P_GO_MODE) { 10687 hdd_adapter_for_each_active_link_info(adapter, 10688 link_info) { 10689 wlan_abort_scan(hdd_ctx->pdev, INVAL_PDEV_ID, 10690 link_info->vdev_id, 10691 INVALID_SCAN_ID, true); 10692 } 10693 } 10694 hdd_adapter_dev_put_debug(adapter, dbgid); 10695 } 10696 10697 hdd_exit(); 10698 10699 return QDF_STATUS_SUCCESS; 10700 } 10701 10702 /** 10703 * hdd_abort_sched_scan_all_adapters() - stops scheduled (PNO) scans for all 10704 * adapters 10705 * @hdd_ctx: The HDD context containing the adapters to operate on 10706 * 10707 * return: QDF_STATUS_SUCCESS 10708 */ 10709 static QDF_STATUS hdd_abort_sched_scan_all_adapters(struct hdd_context *hdd_ctx) 10710 { 10711 struct hdd_adapter *adapter, *next_adapter = NULL; 10712 int err; 10713 wlan_net_dev_ref_dbgid dbgid = 10714 NET_DEV_HOLD_ABORT_SCHED_SCAN_ALL_ADAPTERS; 10715 10716 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 10717 dbgid) { 10718 if (adapter->device_mode == QDF_STA_MODE || 10719 adapter->device_mode == QDF_P2P_CLIENT_MODE || 10720 adapter->device_mode == QDF_P2P_DEVICE_MODE || 10721 adapter->device_mode == QDF_SAP_MODE || 10722 adapter->device_mode == QDF_P2P_GO_MODE) { 10723 err = wlan_hdd_sched_scan_stop(adapter->dev); 10724 if (err) 10725 hdd_err("Unable to stop scheduled scan"); 10726 } 10727 hdd_adapter_dev_put_debug(adapter, dbgid); 10728 } 10729 10730 return QDF_STATUS_SUCCESS; 10731 } 10732 10733 /** 10734 * hdd_unregister_notifiers - Unregister netdev notifiers. 10735 * @hdd_ctx: HDD context 10736 * 10737 * Unregister netdev notifiers like IPv4 and IPv6. 10738 * 10739 * Return: None. 10740 */ 10741 void hdd_unregister_notifiers(struct hdd_context *hdd_ctx) 10742 { 10743 osif_dp_nud_unregister_netevent_notifier(hdd_ctx->psoc); 10744 hdd_wlan_unregister_ip6_notifier(hdd_ctx); 10745 10746 unregister_inetaddr_notifier(&hdd_ctx->ipv4_notifier); 10747 } 10748 10749 /** 10750 * hdd_exit_netlink_services - Exit netlink services 10751 * @hdd_ctx: HDD context 10752 * 10753 * Exit netlink services like cnss_diag, cesium netlink socket, ptt socket and 10754 * nl service. 10755 * 10756 * Return: None. 10757 */ 10758 static void hdd_exit_netlink_services(struct hdd_context *hdd_ctx) 10759 { 10760 spectral_scan_deactivate_service(); 10761 cnss_diag_deactivate_service(); 10762 hdd_close_cesium_nl_sock(); 10763 ptt_sock_deactivate_svc(); 10764 hdd_deactivate_wifi_pos(); 10765 10766 nl_srv_exit(); 10767 } 10768 10769 /** 10770 * hdd_init_netlink_services- Init netlink services 10771 * @hdd_ctx: HDD context 10772 * 10773 * Init netlink services like cnss_diag, cesium netlink socket, ptt socket and 10774 * nl service. 10775 * 10776 * Return: 0 on success and errno on failure. 10777 */ 10778 static int hdd_init_netlink_services(struct hdd_context *hdd_ctx) 10779 { 10780 int ret; 10781 10782 ret = wlan_hdd_nl_init(hdd_ctx); 10783 if (ret) { 10784 hdd_err("nl_srv_init failed: %d", ret); 10785 goto out; 10786 } 10787 cds_set_radio_index(hdd_ctx->radio_index); 10788 10789 ret = hdd_activate_wifi_pos(hdd_ctx); 10790 if (ret) { 10791 hdd_err("hdd_activate_wifi_pos failed: %d", ret); 10792 goto err_nl_srv; 10793 } 10794 10795 ptt_sock_activate_svc(); 10796 10797 ret = hdd_open_cesium_nl_sock(); 10798 if (ret) 10799 hdd_err("hdd_open_cesium_nl_sock failed ret: %d", ret); 10800 10801 ret = cnss_diag_activate_service(); 10802 if (ret) { 10803 hdd_err("cnss_diag_activate_service failed: %d", ret); 10804 goto err_close_cesium; 10805 } 10806 10807 spectral_scan_activate_service(hdd_ctx); 10808 10809 return 0; 10810 10811 err_close_cesium: 10812 hdd_close_cesium_nl_sock(); 10813 ptt_sock_deactivate_svc(); 10814 hdd_deactivate_wifi_pos(); 10815 err_nl_srv: 10816 nl_srv_exit(); 10817 out: 10818 return ret; 10819 } 10820 10821 #ifdef SHUTDOWN_WLAN_IN_SYSTEM_SUSPEND 10822 static QDF_STATUS 10823 hdd_shutdown_wlan_in_suspend_prepare(struct hdd_context *hdd_ctx) 10824 { 10825 #define SHUTDOWN_IN_SUSPEND_RETRY 10 10826 10827 int count = 0; 10828 10829 if (ucfg_pmo_get_suspend_mode(hdd_ctx->psoc) != PMO_SUSPEND_SHUTDOWN) { 10830 hdd_debug("shutdown in suspend not supported"); 10831 return 0; 10832 } 10833 10834 while (hdd_is_any_interface_open(hdd_ctx) && 10835 count < SHUTDOWN_IN_SUSPEND_RETRY) { 10836 count++; 10837 hdd_debug_rl("sleep 50ms to wait adapters stopped, #%d", count); 10838 msleep(50); 10839 } 10840 if (count >= SHUTDOWN_IN_SUSPEND_RETRY) { 10841 hdd_err("some adapters not stopped"); 10842 return -EBUSY; 10843 } 10844 10845 hdd_debug("call pld idle shutdown directly"); 10846 return pld_idle_shutdown(hdd_ctx->parent_dev, hdd_psoc_idle_shutdown); 10847 } 10848 10849 static int hdd_pm_notify(struct notifier_block *b, 10850 unsigned long event, void *p) 10851 { 10852 struct hdd_context *hdd_ctx = container_of(b, struct hdd_context, 10853 pm_notifier); 10854 10855 if (wlan_hdd_validate_context(hdd_ctx) != 0) 10856 return NOTIFY_STOP; 10857 10858 hdd_debug("got PM event: %lu", event); 10859 10860 switch (event) { 10861 case PM_SUSPEND_PREPARE: 10862 case PM_HIBERNATION_PREPARE: 10863 if (0 != hdd_shutdown_wlan_in_suspend_prepare(hdd_ctx)) 10864 return NOTIFY_STOP; 10865 break; 10866 case PM_POST_SUSPEND: 10867 case PM_POST_HIBERNATION: 10868 break; 10869 } 10870 10871 return NOTIFY_DONE; 10872 } 10873 10874 static void hdd_pm_notifier_init(struct hdd_context *hdd_ctx) 10875 { 10876 hdd_ctx->pm_notifier.notifier_call = hdd_pm_notify; 10877 register_pm_notifier(&hdd_ctx->pm_notifier); 10878 } 10879 10880 static void hdd_pm_notifier_deinit(struct hdd_context *hdd_ctx) 10881 { 10882 unregister_pm_notifier(&hdd_ctx->pm_notifier); 10883 } 10884 #else 10885 static inline void hdd_pm_notifier_init(struct hdd_context *hdd_ctx) 10886 { 10887 } 10888 10889 static inline void hdd_pm_notifier_deinit(struct hdd_context *hdd_ctx) 10890 { 10891 } 10892 #endif 10893 10894 /** 10895 * hdd_context_deinit() - Deinitialize HDD context 10896 * @hdd_ctx: HDD context. 10897 * 10898 * Deinitialize HDD context along with all the feature specific contexts but 10899 * do not free hdd context itself. Caller of this API is supposed to free 10900 * HDD context. 10901 * 10902 * return: 0 on success and errno on failure. 10903 */ 10904 static int hdd_context_deinit(struct hdd_context *hdd_ctx) 10905 { 10906 qdf_wake_lock_destroy(&hdd_ctx->monitor_mode_wakelock); 10907 10908 wlan_hdd_cfg80211_deinit(hdd_ctx->wiphy); 10909 10910 ucfg_dp_bbm_context_deinit(hdd_ctx->psoc); 10911 10912 hdd_sap_context_destroy(hdd_ctx); 10913 10914 hdd_scan_context_destroy(hdd_ctx); 10915 10916 qdf_list_destroy(&hdd_ctx->hdd_adapters); 10917 10918 return 0; 10919 } 10920 10921 void hdd_context_destroy(struct hdd_context *hdd_ctx) 10922 { 10923 wlan_hdd_sar_timers_deinit(hdd_ctx); 10924 10925 cds_set_context(QDF_MODULE_ID_HDD, NULL); 10926 10927 hdd_exit_netlink_services(hdd_ctx); 10928 10929 hdd_context_deinit(hdd_ctx); 10930 10931 hdd_objmgr_release_and_destroy_psoc(hdd_ctx); 10932 10933 qdf_mem_free(hdd_ctx->config); 10934 hdd_ctx->config = NULL; 10935 cfg_release(); 10936 10937 hdd_pm_notifier_deinit(hdd_ctx); 10938 qdf_delayed_work_destroy(&hdd_ctx->psoc_idle_timeout_work); 10939 wiphy_free(hdd_ctx->wiphy); 10940 } 10941 10942 /** 10943 * wlan_destroy_bug_report_lock() - Destroy bug report lock 10944 * 10945 * This function is used to destroy bug report lock 10946 * 10947 * Return: None 10948 */ 10949 static void wlan_destroy_bug_report_lock(void) 10950 { 10951 struct cds_context *p_cds_context; 10952 10953 p_cds_context = cds_get_global_context(); 10954 if (!p_cds_context) { 10955 hdd_err("cds context is NULL"); 10956 return; 10957 } 10958 10959 qdf_spinlock_destroy(&p_cds_context->bug_report_lock); 10960 } 10961 10962 #ifdef DISABLE_CHANNEL_LIST 10963 static void wlan_hdd_cache_chann_mutex_destroy(struct hdd_context *hdd_ctx) 10964 { 10965 qdf_mutex_destroy(&hdd_ctx->cache_channel_lock); 10966 } 10967 #else 10968 static void wlan_hdd_cache_chann_mutex_destroy(struct hdd_context *hdd_ctx) 10969 { 10970 } 10971 #endif 10972 10973 void hdd_wlan_exit(struct hdd_context *hdd_ctx) 10974 { 10975 struct wiphy *wiphy = hdd_ctx->wiphy; 10976 10977 hdd_enter(); 10978 10979 ucfg_dp_wait_complete_tasks(); 10980 wlan_hdd_destroy_mib_stats_lock(); 10981 hdd_debugfs_ini_config_deinit(hdd_ctx); 10982 hdd_debugfs_mws_coex_info_deinit(hdd_ctx); 10983 hdd_psoc_idle_timer_stop(hdd_ctx); 10984 hdd_regulatory_deinit(hdd_ctx); 10985 10986 /* 10987 * Powersave Offload Case 10988 * Disable Idle Power Save Mode 10989 */ 10990 hdd_set_idle_ps_config(hdd_ctx, false); 10991 /* clear the scan queue in all the scenarios */ 10992 wlan_cfg80211_cleanup_scan_queue(hdd_ctx->pdev, NULL); 10993 10994 if (hdd_ctx->driver_status != DRIVER_MODULES_CLOSED) { 10995 hdd_unregister_wext_all_adapters(hdd_ctx, false); 10996 /* 10997 * Cancel any outstanding scan requests. We are about to close 10998 * all of our adapters, but an adapter structure is what SME 10999 * passes back to our callback function. Hence if there 11000 * are any outstanding scan requests then there is a 11001 * race condition between when the adapter is closed and 11002 * when the callback is invoked. We try to resolve that 11003 * race condition here by canceling any outstanding scans 11004 * before we close the adapters. 11005 * Note that the scans may be cancelled in an asynchronous 11006 * manner, so ideally there needs to be some kind of 11007 * synchronization. Rather than introduce a new 11008 * synchronization here, we will utilize the fact that we are 11009 * about to Request Full Power, and since that is synchronized, 11010 * the expectation is that by the time Request Full Power has 11011 * completed, all scans will be cancelled 11012 */ 11013 hdd_abort_mac_scan_all_adapters(hdd_ctx); 11014 hdd_abort_sched_scan_all_adapters(hdd_ctx); 11015 11016 hdd_stop_all_adapters(hdd_ctx); 11017 hdd_deinit_all_adapters(hdd_ctx, false); 11018 } 11019 11020 unregister_netdevice_notifier(&hdd_netdev_notifier); 11021 11022 qdf_dp_trace_deinit(); 11023 11024 hdd_wlan_stop_modules(hdd_ctx, false); 11025 11026 hdd_driver_memdump_deinit(); 11027 11028 qdf_nbuf_deinit_replenish_timer(); 11029 11030 if (QDF_GLOBAL_MONITOR_MODE == hdd_get_conparam()) { 11031 hdd_info("Release wakelock for monitor mode!"); 11032 qdf_wake_lock_release(&hdd_ctx->monitor_mode_wakelock, 11033 WIFI_POWER_EVENT_WAKELOCK_MONITOR_MODE); 11034 } 11035 11036 qdf_spinlock_destroy(&hdd_ctx->hdd_adapter_lock); 11037 qdf_spinlock_destroy(&hdd_ctx->connection_status_lock); 11038 wlan_hdd_cache_chann_mutex_destroy(hdd_ctx); 11039 11040 osif_request_manager_deinit(); 11041 11042 hdd_close_all_adapters(hdd_ctx, false); 11043 11044 wlansap_global_deinit(); 11045 /* 11046 * If there is re_init failure wiphy would have already de-registered 11047 * check the wiphy status before un-registering again 11048 */ 11049 if (wiphy && wiphy->registered) { 11050 wiphy_unregister(wiphy); 11051 wlan_hdd_cfg80211_deinit(wiphy); 11052 hdd_lpass_notify_stop(hdd_ctx); 11053 } 11054 11055 hdd_deinit_regulatory_update_event(hdd_ctx); 11056 hdd_exit_netlink_services(hdd_ctx); 11057 #ifdef FEATURE_WLAN_CH_AVOID 11058 mutex_destroy(&hdd_ctx->avoid_freq_lock); 11059 #endif 11060 11061 /* This function should be invoked at the end of this api*/ 11062 hdd_dump_func_call_map(); 11063 } 11064 11065 /** 11066 * hdd_wlan_notify_modem_power_state() - notify FW with modem power status 11067 * @state: state 11068 * 11069 * This function notifies FW with modem power status 11070 * 11071 * Return: 0 if successful, error number otherwise 11072 */ 11073 int hdd_wlan_notify_modem_power_state(int state) 11074 { 11075 int status; 11076 QDF_STATUS qdf_status; 11077 struct hdd_context *hdd_ctx; 11078 mac_handle_t mac_handle; 11079 11080 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 11081 status = wlan_hdd_validate_context(hdd_ctx); 11082 if (status) 11083 return status; 11084 11085 mac_handle = hdd_ctx->mac_handle; 11086 if (!mac_handle) 11087 return -EINVAL; 11088 11089 qdf_status = sme_notify_modem_power_state(mac_handle, state); 11090 if (QDF_STATUS_SUCCESS != qdf_status) { 11091 hdd_err("Fail to send notification with modem power state %d", 11092 state); 11093 return -EINVAL; 11094 } 11095 return 0; 11096 } 11097 11098 /** 11099 * hdd_post_cds_enable_config() - HDD post cds start config helper 11100 * @hdd_ctx: Pointer to the HDD 11101 * 11102 * Return: None 11103 */ 11104 QDF_STATUS hdd_post_cds_enable_config(struct hdd_context *hdd_ctx) 11105 { 11106 QDF_STATUS qdf_ret_status; 11107 11108 /* 11109 * Send ready indication to the HDD. This will kick off the MAC 11110 * into a 'running' state and should kick off an initial scan. 11111 */ 11112 qdf_ret_status = sme_hdd_ready_ind(hdd_ctx->mac_handle); 11113 if (!QDF_IS_STATUS_SUCCESS(qdf_ret_status)) { 11114 hdd_err("sme_hdd_ready_ind() failed with status code %08d [x%08x]", 11115 qdf_ret_status, qdf_ret_status); 11116 return QDF_STATUS_E_FAILURE; 11117 } 11118 11119 return QDF_STATUS_SUCCESS; 11120 } 11121 11122 struct hdd_adapter *hdd_get_first_valid_adapter(struct hdd_context *hdd_ctx) 11123 { 11124 struct hdd_adapter *adapter, *next_adapter = NULL; 11125 wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_GET_FIRST_VALID_ADAPTER; 11126 11127 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 11128 dbgid) { 11129 if (adapter && adapter->magic == WLAN_HDD_ADAPTER_MAGIC) { 11130 hdd_adapter_dev_put_debug(adapter, dbgid); 11131 if (next_adapter) 11132 hdd_adapter_dev_put_debug(next_adapter, 11133 dbgid); 11134 return adapter; 11135 } 11136 hdd_adapter_dev_put_debug(adapter, dbgid); 11137 } 11138 11139 return NULL; 11140 } 11141 11142 /* wake lock APIs for HDD */ 11143 void hdd_prevent_suspend(uint32_t reason) 11144 { 11145 qdf_wake_lock_acquire(&wlan_wake_lock, reason); 11146 } 11147 11148 void hdd_allow_suspend(uint32_t reason) 11149 { 11150 qdf_wake_lock_release(&wlan_wake_lock, reason); 11151 } 11152 11153 void hdd_prevent_suspend_timeout(uint32_t timeout, uint32_t reason) 11154 { 11155 cds_host_diag_log_work(&wlan_wake_lock, timeout, reason); 11156 qdf_wake_lock_timeout_acquire(&wlan_wake_lock, timeout); 11157 } 11158 11159 /* Initialize channel list in sme based on the country code */ 11160 QDF_STATUS hdd_set_sme_chan_list(struct hdd_context *hdd_ctx) 11161 { 11162 return sme_init_chan_list(hdd_ctx->mac_handle, 11163 hdd_ctx->reg.cc_src); 11164 } 11165 11166 /** 11167 * hdd_is_5g_supported() - check if hardware supports 5GHz 11168 * @hdd_ctx: Pointer to the hdd context 11169 * 11170 * HDD function to know if hardware supports 5GHz 11171 * 11172 * Return: true if hardware supports 5GHz 11173 */ 11174 bool hdd_is_5g_supported(struct hdd_context *hdd_ctx) 11175 { 11176 if (!hdd_ctx) 11177 return true; 11178 11179 if (hdd_ctx->curr_band != BAND_2G) 11180 return true; 11181 else 11182 return false; 11183 } 11184 11185 bool hdd_is_2g_supported(struct hdd_context *hdd_ctx) 11186 { 11187 if (!hdd_ctx) 11188 return false; 11189 11190 if (hdd_ctx->curr_band != BAND_5G) 11191 return true; 11192 else 11193 return false; 11194 } 11195 11196 static int hdd_wiphy_init(struct hdd_context *hdd_ctx) 11197 { 11198 struct wiphy *wiphy; 11199 int ret_val; 11200 uint32_t channel_bonding_mode; 11201 11202 wiphy = hdd_ctx->wiphy; 11203 11204 /* 11205 * The channel information in 11206 * wiphy needs to be initialized before wiphy registration 11207 */ 11208 ret_val = hdd_regulatory_init(hdd_ctx, wiphy); 11209 if (ret_val) { 11210 hdd_err("regulatory init failed"); 11211 return ret_val; 11212 } 11213 11214 if (ucfg_pmo_get_suspend_mode(hdd_ctx->psoc) == PMO_SUSPEND_WOW) { 11215 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0)) 11216 wiphy->wowlan = &wowlan_support_reg_init; 11217 #else 11218 wiphy->wowlan.flags = WIPHY_WOWLAN_ANY | 11219 WIPHY_WOWLAN_MAGIC_PKT | 11220 WIPHY_WOWLAN_DISCONNECT | 11221 WIPHY_WOWLAN_SUPPORTS_GTK_REKEY | 11222 WIPHY_WOWLAN_GTK_REKEY_FAILURE | 11223 WIPHY_WOWLAN_EAP_IDENTITY_REQ | 11224 WIPHY_WOWLAN_4WAY_HANDSHAKE | 11225 WIPHY_WOWLAN_RFKILL_RELEASE; 11226 11227 wiphy->wowlan.n_patterns = (WOW_MAX_FILTER_LISTS * 11228 WOW_MAX_FILTERS_PER_LIST); 11229 wiphy->wowlan.pattern_min_len = WOW_MIN_PATTERN_SIZE; 11230 wiphy->wowlan.pattern_max_len = WOW_MAX_PATTERN_SIZE; 11231 #endif 11232 } 11233 11234 ucfg_mlme_get_channel_bonding_24ghz(hdd_ctx->psoc, 11235 &channel_bonding_mode); 11236 if (hdd_ctx->obss_scan_offload) { 11237 hdd_debug("wmi_service_obss_scan supported"); 11238 } else if (channel_bonding_mode) { 11239 hdd_debug("enable wpa_supp obss_scan"); 11240 wiphy->features |= NL80211_FEATURE_NEED_OBSS_SCAN; 11241 } 11242 11243 if (hdd_ctx->num_rf_chains == HDD_ANTENNA_MODE_2X2 && 11244 ucfg_mlme_is_chain_mask_supported(hdd_ctx->psoc)) { 11245 wiphy->available_antennas_tx = HDD_CHAIN_MODE_2X2; 11246 wiphy->available_antennas_rx = HDD_CHAIN_MODE_2X2; 11247 } 11248 /* registration of wiphy dev with cfg80211 */ 11249 ret_val = wlan_hdd_cfg80211_register(wiphy); 11250 if (0 > ret_val) { 11251 hdd_err("wiphy registration failed"); 11252 return ret_val; 11253 } 11254 11255 /* Check the kernel version for upstream commit aced43ce780dc5 that 11256 * has support for processing user cell_base hints when wiphy is 11257 * self managed or check the backport flag for the same. 11258 */ 11259 #if defined CFG80211_USER_HINT_CELL_BASE_SELF_MANAGED || \ 11260 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 18, 0)) 11261 hdd_send_wiphy_regd_sync_event(hdd_ctx); 11262 #endif 11263 11264 pld_increment_driver_load_cnt(hdd_ctx->parent_dev); 11265 11266 return ret_val; 11267 } 11268 11269 #ifdef WLAN_FEATURE_DP_BUS_BANDWIDTH 11270 #ifdef CLD_PM_QOS 11271 #define PLD_REMOVE_PM_QOS(x) 11272 #define PLD_REQUEST_PM_QOS(x, y) 11273 #define HDD_PM_QOS_HIGH_TPUT_LATENCY_US 1 11274 11275 /** 11276 * hdd_pm_qos_update_cpu_mask() - Prepare CPU mask for PM_qos voting 11277 * @mask: return variable of cpumask for the TPUT 11278 * @enable_perf_cluster: Enable PERF cluster or not 11279 * 11280 * By default, the function sets CPU mask for silver cluster unless 11281 * enable_perf_cluster is set as true. 11282 * 11283 * Return: none 11284 */ 11285 static inline void hdd_pm_qos_update_cpu_mask(cpumask_t *mask, 11286 bool enable_perf_cluster) 11287 { 11288 cpumask_set_cpu(0, mask); 11289 cpumask_set_cpu(1, mask); 11290 cpumask_set_cpu(2, mask); 11291 cpumask_set_cpu(3, mask); 11292 11293 if (enable_perf_cluster) { 11294 cpumask_set_cpu(4, mask); 11295 cpumask_set_cpu(5, mask); 11296 cpumask_set_cpu(6, mask); 11297 } 11298 } 11299 11300 #ifdef MSM_PLATFORM 11301 #define COPY_CPU_MASK(a, b) cpumask_copy(a, b) 11302 #define DUMP_CPU_AFFINE() hdd_info("Set cpu_mask %*pb for affine_cores", \ 11303 cpumask_pr_args(&hdd_ctx->pm_qos_req.cpus_affine)) 11304 #else 11305 #define COPY_CPU_MASK(a, b) /* no-op*/ 11306 #define DUMP_CPU_AFFINE() /* no-op*/ 11307 #endif 11308 11309 #ifdef CLD_DEV_PM_QOS 11310 11311 static inline void _hdd_pm_qos_update_request(struct hdd_context *hdd_ctx, 11312 cpumask_t *pm_qos_cpu_mask, 11313 unsigned int latency) 11314 { 11315 int cpu; 11316 uint32_t default_latency; 11317 11318 default_latency = wlan_hdd_get_default_pm_qos_cpu_latency(); 11319 qdf_cpumask_copy(&hdd_ctx->qos_cpu_mask, pm_qos_cpu_mask); 11320 11321 if (qdf_cpumask_empty(pm_qos_cpu_mask)) { 11322 for_each_present_cpu(cpu) { 11323 dev_pm_qos_update_request( 11324 &hdd_ctx->pm_qos_req[cpu], 11325 default_latency); 11326 } 11327 hdd_debug("Empty mask %*pb: Set latency %u", 11328 qdf_cpumask_pr_args(&hdd_ctx->qos_cpu_mask), 11329 default_latency); 11330 } else { /* Set latency to default for CPUs not included in mask */ 11331 qdf_for_each_cpu_not(cpu, &hdd_ctx->qos_cpu_mask) { 11332 dev_pm_qos_update_request( 11333 &hdd_ctx->pm_qos_req[cpu], 11334 default_latency); 11335 } 11336 /* Set latency for CPUs included in mask */ 11337 qdf_for_each_cpu(cpu, &hdd_ctx->qos_cpu_mask) { 11338 dev_pm_qos_update_request( 11339 &hdd_ctx->pm_qos_req[cpu], 11340 latency); 11341 } 11342 hdd_debug("For qos_cpu_mask %*pb set latency %u", 11343 qdf_cpumask_pr_args(&hdd_ctx->qos_cpu_mask), 11344 latency); 11345 } 11346 } 11347 11348 /** 11349 * hdd_pm_qos_update_request() - API to request for pm_qos 11350 * @hdd_ctx: handle to hdd context 11351 * @pm_qos_cpu_mask: cpu_mask to apply 11352 * 11353 * Return: none 11354 */ 11355 static void hdd_pm_qos_update_request(struct hdd_context *hdd_ctx, 11356 cpumask_t *pm_qos_cpu_mask) 11357 { 11358 unsigned int latency; 11359 11360 if (qdf_cpumask_empty(pm_qos_cpu_mask)) 11361 latency = wlan_hdd_get_default_pm_qos_cpu_latency(); 11362 else 11363 latency = HDD_PM_QOS_HIGH_TPUT_LATENCY_US; 11364 11365 _hdd_pm_qos_update_request(hdd_ctx, pm_qos_cpu_mask, latency); 11366 } 11367 11368 static inline void hdd_pm_qos_add_request(struct hdd_context *hdd_ctx) 11369 { 11370 struct device *cpu_dev; 11371 int cpu; 11372 uint32_t default_latency = wlan_hdd_get_default_pm_qos_cpu_latency(); 11373 11374 11375 qdf_cpumask_clear(&hdd_ctx->qos_cpu_mask); 11376 hdd_pm_qos_update_cpu_mask(&hdd_ctx->qos_cpu_mask, false); 11377 11378 for_each_present_cpu(cpu) { 11379 cpu_dev = get_cpu_device(cpu); 11380 dev_pm_qos_add_request(cpu_dev, &hdd_ctx->pm_qos_req[cpu], 11381 DEV_PM_QOS_RESUME_LATENCY, 11382 default_latency); 11383 hdd_debug("Set qos_cpu_mask %*pb for affine_cores", 11384 cpumask_pr_args(&hdd_ctx->qos_cpu_mask)); 11385 } 11386 } 11387 11388 static inline void hdd_pm_qos_remove_request(struct hdd_context *hdd_ctx) 11389 { 11390 int cpu; 11391 11392 for_each_present_cpu(cpu) { 11393 dev_pm_qos_remove_request(&hdd_ctx->pm_qos_req[cpu]); 11394 hdd_debug("Remove dev_pm_qos_request for all cpus: %d", cpu); 11395 } 11396 qdf_cpumask_clear(&hdd_ctx->qos_cpu_mask); 11397 } 11398 11399 #else /* CLD_DEV_PM_QOS */ 11400 11401 #if defined(CONFIG_SMP) && defined(MSM_PLATFORM) 11402 /** 11403 * hdd_set_default_pm_qos_mask() - Update PM_qos request for AFFINE_CORES 11404 * @hdd_ctx: handle to hdd context 11405 * 11406 * Return: none 11407 */ 11408 static inline void hdd_set_default_pm_qos_mask(struct hdd_context *hdd_ctx) 11409 { 11410 hdd_ctx->pm_qos_req.type = PM_QOS_REQ_AFFINE_CORES; 11411 qdf_cpumask_clear(&hdd_ctx->pm_qos_req.cpus_affine); 11412 hdd_pm_qos_update_cpu_mask(&hdd_ctx->pm_qos_req.cpus_affine, false); 11413 } 11414 #else 11415 static inline void hdd_set_default_pm_qos_mask(struct hdd_context *hdd_ctx) 11416 { 11417 } 11418 #endif 11419 11420 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 7, 0)) 11421 /** 11422 * hdd_pm_qos_update_request() - API to request for pm_qos 11423 * @hdd_ctx: handle to hdd context 11424 * @pm_qos_cpu_mask: cpu_mask to apply 11425 * 11426 * Return: none 11427 */ 11428 static inline void hdd_pm_qos_update_request(struct hdd_context *hdd_ctx, 11429 cpumask_t *pm_qos_cpu_mask) 11430 { 11431 COPY_CPU_MASK(&hdd_ctx->pm_qos_req.cpus_affine, pm_qos_cpu_mask); 11432 11433 if (cpumask_empty(pm_qos_cpu_mask)) 11434 cpu_latency_qos_update_request(&hdd_ctx->pm_qos_req, 11435 PM_QOS_DEFAULT_VALUE); 11436 else 11437 cpu_latency_qos_update_request(&hdd_ctx->pm_qos_req, 1); 11438 } 11439 11440 static inline void hdd_pm_qos_add_request(struct hdd_context *hdd_ctx) 11441 { 11442 hdd_set_default_pm_qos_mask(hdd_ctx); 11443 cpu_latency_qos_add_request(&hdd_ctx->pm_qos_req, PM_QOS_DEFAULT_VALUE); 11444 DUMP_CPU_AFFINE(); 11445 } 11446 11447 static inline void hdd_pm_qos_remove_request(struct hdd_context *hdd_ctx) 11448 { 11449 cpu_latency_qos_remove_request(&hdd_ctx->pm_qos_req); 11450 } 11451 #else 11452 static inline void hdd_pm_qos_update_request(struct hdd_context *hdd_ctx, 11453 cpumask_t *pm_qos_cpu_mask) 11454 { 11455 COPY_CPU_MASK(&hdd_ctx->pm_qos_req.cpus_affine, pm_qos_cpu_mask); 11456 11457 if (cpumask_empty(pm_qos_cpu_mask)) 11458 pm_qos_update_request(&hdd_ctx->pm_qos_req, 11459 PM_QOS_DEFAULT_VALUE); 11460 else 11461 pm_qos_update_request(&hdd_ctx->pm_qos_req, 1); 11462 } 11463 11464 static inline void hdd_pm_qos_add_request(struct hdd_context *hdd_ctx) 11465 { 11466 hdd_set_default_pm_qos_mask(hdd_ctx); 11467 pm_qos_add_request(&hdd_ctx->pm_qos_req, PM_QOS_CPU_DMA_LATENCY, 11468 PM_QOS_DEFAULT_VALUE); 11469 DUMP_CPU_AFFINE(); 11470 } 11471 11472 static inline void hdd_pm_qos_remove_request(struct hdd_context *hdd_ctx) 11473 { 11474 pm_qos_remove_request(&hdd_ctx->pm_qos_req); 11475 } 11476 #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(5, 7, 0) */ 11477 #endif /* CLD_DEV_PM_QOS */ 11478 11479 #else /* CLD_PM_QOS */ 11480 #define PLD_REMOVE_PM_QOS(x) pld_remove_pm_qos(x) 11481 #define PLD_REQUEST_PM_QOS(x, y) pld_request_pm_qos(x, y) 11482 11483 static inline void hdd_pm_qos_add_request(struct hdd_context *hdd_ctx) 11484 { 11485 } 11486 11487 static inline void hdd_pm_qos_remove_request(struct hdd_context *hdd_ctx) 11488 { 11489 } 11490 11491 static inline void hdd_pm_qos_update_cpu_mask(cpumask_t *mask, 11492 bool high_throughput) 11493 { 11494 } 11495 11496 static inline void hdd_pm_qos_update_request(struct hdd_context *hdd_ctx, 11497 cpumask_t *pm_qos_cpu_mask) 11498 { 11499 } 11500 #endif /* CLD_PM_QOS */ 11501 11502 #if defined(CLD_PM_QOS) 11503 #if defined(CLD_DEV_PM_QOS) 11504 void wlan_hdd_set_pm_qos_request(struct hdd_context *hdd_ctx, 11505 bool pm_qos_request) 11506 { 11507 cpumask_t pm_qos_cpu_mask; 11508 11509 cpumask_clear(&pm_qos_cpu_mask); 11510 if (pm_qos_request) { 11511 hdd_ctx->pm_qos_request = true; 11512 if (!hdd_ctx->hbw_requested) { 11513 hdd_pm_qos_update_cpu_mask(&pm_qos_cpu_mask, true); 11514 hdd_pm_qos_update_request(hdd_ctx, &pm_qos_cpu_mask); 11515 hdd_ctx->hbw_requested = true; 11516 } 11517 } else { 11518 if (hdd_ctx->hbw_requested) { 11519 hdd_pm_qos_update_cpu_mask(&pm_qos_cpu_mask, false); 11520 hdd_pm_qos_update_request(hdd_ctx, &pm_qos_cpu_mask); 11521 hdd_ctx->hbw_requested = false; 11522 } 11523 hdd_ctx->pm_qos_request = false; 11524 } 11525 } 11526 #else /* CLD_DEV_PM_QOS */ 11527 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 7, 0)) 11528 void wlan_hdd_set_pm_qos_request(struct hdd_context *hdd_ctx, 11529 bool pm_qos_request) 11530 { 11531 if (pm_qos_request) { 11532 hdd_ctx->pm_qos_request = true; 11533 if (!hdd_ctx->hbw_requested) { 11534 cpumask_setall(&hdd_ctx->pm_qos_req.cpus_affine); 11535 cpu_latency_qos_update_request( 11536 &hdd_ctx->pm_qos_req, 11537 DISABLE_KRAIT_IDLE_PS_VAL); 11538 hdd_ctx->hbw_requested = true; 11539 } 11540 } else { 11541 if (hdd_ctx->hbw_requested) { 11542 cpumask_clear(&hdd_ctx->pm_qos_req.cpus_affine); 11543 cpu_latency_qos_update_request(&hdd_ctx->pm_qos_req, 11544 PM_QOS_DEFAULT_VALUE); 11545 hdd_ctx->hbw_requested = false; 11546 } 11547 hdd_ctx->pm_qos_request = false; 11548 } 11549 } 11550 #else /* (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 7, 0)) */ 11551 void wlan_hdd_set_pm_qos_request(struct hdd_context *hdd_ctx, 11552 bool pm_qos_request) 11553 { 11554 if (pm_qos_request) { 11555 hdd_ctx->pm_qos_request = true; 11556 if (!hdd_ctx->hbw_requested) { 11557 cpumask_setall(&hdd_ctx->pm_qos_req.cpus_affine); 11558 pm_qos_update_request(&hdd_ctx->pm_qos_req, 11559 DISABLE_KRAIT_IDLE_PS_VAL); 11560 hdd_ctx->hbw_requested = true; 11561 } 11562 } else { 11563 if (hdd_ctx->hbw_requested) { 11564 cpumask_clear(&hdd_ctx->pm_qos_req.cpus_affine); 11565 pm_qos_update_request(&hdd_ctx->pm_qos_req, 11566 PM_QOS_DEFAULT_VALUE); 11567 hdd_ctx->hbw_requested = false; 11568 } 11569 hdd_ctx->pm_qos_request = false; 11570 } 11571 } 11572 #endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 7, 0)) */ 11573 #endif /* CLD_DEV_PM_QOS*/ 11574 #endif /* CLD_PM_QOS */ 11575 11576 #define HDD_BW_GET_DIFF(_x, _y) (unsigned long)((ULONG_MAX - (_y)) + (_x) + 1) 11577 11578 #ifdef WLAN_FEATURE_MSCS 11579 11580 static 11581 void hdd_send_mscs_action_frame(struct wlan_hdd_link_info *link_info) 11582 { 11583 struct hdd_context *hdd_ctx = link_info->adapter->hdd_ctx; 11584 uint64_t mscs_vo_pkt_delta; 11585 unsigned long tx_vo_pkts = 0; 11586 unsigned int cpu; 11587 struct hdd_tx_rx_stats *stats = &link_info->hdd_stats.tx_rx_stats; 11588 uint32_t bus_bw_compute_interval; 11589 11590 /* 11591 * To disable MSCS feature in driver set mscs_pkt_threshold = 0 11592 * in ini file. 11593 */ 11594 if (!hdd_ctx->config->mscs_pkt_threshold) 11595 return; 11596 11597 for (cpu = 0; cpu < NUM_CPUS; cpu++) 11598 tx_vo_pkts += stats->per_cpu[cpu].tx_classified_ac[SME_AC_VO]; 11599 11600 if (!link_info->mscs_counter) 11601 link_info->mscs_prev_tx_vo_pkts = tx_vo_pkts; 11602 11603 link_info->mscs_counter++; 11604 bus_bw_compute_interval = 11605 ucfg_dp_get_bus_bw_compute_interval(hdd_ctx->psoc); 11606 if (link_info->mscs_counter * bus_bw_compute_interval >= 11607 hdd_ctx->config->mscs_voice_interval * 1000) { 11608 link_info->mscs_counter = 0; 11609 mscs_vo_pkt_delta = 11610 HDD_BW_GET_DIFF(tx_vo_pkts, 11611 link_info->mscs_prev_tx_vo_pkts); 11612 if (mscs_vo_pkt_delta > hdd_ctx->config->mscs_pkt_threshold && 11613 !mlme_get_is_mscs_req_sent(link_info->vdev)) 11614 sme_send_mscs_action_frame(link_info->vdev_id); 11615 } 11616 } 11617 #else 11618 static inline 11619 void hdd_send_mscs_action_frame(struct wlan_hdd_link_info *link_info) 11620 { 11621 } 11622 #endif 11623 #endif /*WLAN_FEATURE_DP_BUS_BANDWIDTH*/ 11624 11625 /** 11626 * wlan_hdd_sta_get_dot11mode() - GET AP client count 11627 * @context: HDD context 11628 * @netdev: netdev 11629 * @dot11_mode: variable in which mode need to update. 11630 * 11631 * Return: true on success else false 11632 */ 11633 static inline 11634 bool wlan_hdd_sta_get_dot11mode(hdd_cb_handle context, qdf_netdev_t netdev, 11635 enum qca_wlan_802_11_mode *dot11_mode) 11636 { 11637 struct hdd_context *hdd_ctx; 11638 struct wlan_hdd_link_info *link_info; 11639 struct hdd_station_ctx *sta_ctx; 11640 struct hdd_adapter *adapter; 11641 enum csr_cfgdot11mode mode; 11642 11643 hdd_ctx = hdd_cb_handle_to_context(context); 11644 if (!hdd_ctx) 11645 return false; 11646 11647 adapter = WLAN_HDD_GET_PRIV_PTR(netdev); 11648 if (!adapter) 11649 return false; 11650 11651 link_info = adapter->deflink; 11652 11653 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(link_info); 11654 mode = sta_ctx->conn_info.dot11mode; 11655 *dot11_mode = hdd_convert_cfgdot11mode_to_80211mode(mode); 11656 return true; 11657 } 11658 11659 /** 11660 * wlan_hdd_get_ap_client_count() - GET AP client count 11661 * @context: HDD context 11662 * @netdev: netdev 11663 * @client_count: variable in which number of client need to update. 11664 * 11665 * Return: true on success else false 11666 */ 11667 static inline 11668 bool wlan_hdd_get_ap_client_count(hdd_cb_handle context, qdf_netdev_t netdev, 11669 uint16_t *client_count) 11670 { 11671 struct hdd_context *hdd_ctx; 11672 struct wlan_hdd_link_info *link_info; 11673 struct hdd_adapter *adapter; 11674 struct hdd_ap_ctx *ap_ctx; 11675 enum qca_wlan_802_11_mode i; 11676 11677 hdd_ctx = hdd_cb_handle_to_context(context); 11678 if (!hdd_ctx) { 11679 hdd_err("hdd ctx is null"); 11680 return false; 11681 } 11682 11683 adapter = WLAN_HDD_GET_PRIV_PTR(netdev); 11684 if (!adapter) { 11685 hdd_err("adapter is null"); 11686 return false; 11687 } 11688 11689 link_info = adapter->deflink; 11690 ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(link_info); 11691 if (!ap_ctx->ap_active) 11692 return false; 11693 11694 for (i = QCA_WLAN_802_11_MODE_11B; i < QCA_WLAN_802_11_MODE_INVALID; 11695 i++) 11696 client_count[i] = ap_ctx->client_count[i]; 11697 11698 return true; 11699 } 11700 11701 /** 11702 * wlan_hdd_sta_ndi_connected() - Check if NDI connected 11703 * @context: HDD context 11704 * @netdev: netdev 11705 * 11706 * Return: true if NDI connected else false 11707 */ 11708 static inline 11709 bool wlan_hdd_sta_ndi_connected(hdd_cb_handle context, qdf_netdev_t netdev) 11710 { 11711 struct hdd_adapter *adapter; 11712 struct hdd_context *hdd_ctx; 11713 struct wlan_hdd_link_info *link_info; 11714 struct hdd_station_ctx *sta_ctx; 11715 11716 hdd_ctx = hdd_cb_handle_to_context(context); 11717 if (!hdd_ctx) { 11718 hdd_err("hdd_ctx is null"); 11719 return false; 11720 } 11721 11722 adapter = WLAN_HDD_GET_PRIV_PTR(netdev); 11723 if (!adapter) { 11724 hdd_err("adapter is null"); 11725 return false; 11726 } 11727 11728 link_info = adapter->deflink; 11729 11730 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(link_info); 11731 if (sta_ctx->conn_info.conn_state != eConnectionState_NdiConnected) 11732 return false; 11733 11734 return true; 11735 } 11736 11737 /** 11738 * wlan_hdd_pktlog_enable_disable() - Enable/Disable packet logging 11739 * @context: HDD context 11740 * @enable_disable_flag: Flag to enable/disable 11741 * @user_triggered: triggered through iwpriv 11742 * @size: buffer size to be used for packetlog 11743 * 11744 * Return: 0 on success; error number otherwise 11745 */ 11746 static inline 11747 int wlan_hdd_pktlog_enable_disable(hdd_cb_handle context, 11748 bool enable_disable_flag, 11749 uint8_t user_triggered, int size) 11750 { 11751 struct hdd_context *hdd_ctx = hdd_cb_handle_to_context(context); 11752 11753 if (!hdd_ctx) { 11754 hdd_err("hdd_ctx is null"); 11755 return -EINVAL; 11756 } 11757 return hdd_pktlog_enable_disable(hdd_ctx, enable_disable_flag, 11758 user_triggered, size); 11759 } 11760 11761 /** 11762 * wlan_hdd_is_roaming_in_progress() - Check if roaming is in progress 11763 * @context: HDD context 11764 * 11765 * Return: true if roaming is in progress else false 11766 */ 11767 static inline bool wlan_hdd_is_roaming_in_progress(hdd_cb_handle context) 11768 { 11769 struct hdd_context *hdd_ctx = hdd_cb_handle_to_context(context); 11770 11771 if (!hdd_ctx) { 11772 hdd_err("hdd_ctx is null"); 11773 return false; 11774 } 11775 return hdd_is_roaming_in_progress(hdd_ctx); 11776 } 11777 11778 /** 11779 * hdd_is_ap_active() - Check if AP is active 11780 * @context: HDD context 11781 * @netdev: netdev 11782 * 11783 * Return: true if AP active else false 11784 */ 11785 static inline bool hdd_is_ap_active(hdd_cb_handle context, qdf_netdev_t netdev) 11786 { 11787 struct hdd_adapter *adapter; 11788 struct hdd_context *hdd_ctx; 11789 struct wlan_hdd_link_info *link_info; 11790 11791 hdd_ctx = hdd_cb_handle_to_context(context); 11792 if (!hdd_ctx) { 11793 hdd_err("hdd_ctx is null"); 11794 return false; 11795 } 11796 11797 adapter = WLAN_HDD_GET_PRIV_PTR(netdev); 11798 if (!adapter) { 11799 hdd_err("adapter is null"); 11800 return false; 11801 } 11802 11803 link_info = adapter->deflink; 11804 return WLAN_HDD_GET_AP_CTX_PTR(link_info)->ap_active; 11805 } 11806 11807 /** 11808 * wlan_hdd_napi_apply_throughput_policy() - Apply NAPI policy 11809 * @context: HDD context 11810 * @tx_packets: tx_packets 11811 * @rx_packets: rx_packets 11812 * 11813 * Return: 0 on success else error code 11814 */ 11815 static inline 11816 int wlan_hdd_napi_apply_throughput_policy(hdd_cb_handle context, 11817 uint64_t tx_packets, 11818 uint64_t rx_packets) 11819 { 11820 struct hdd_context *hdd_ctx = hdd_cb_handle_to_context(context); 11821 int rc = 0; 11822 11823 if (!hdd_ctx) { 11824 hdd_err("hdd_ctx is null"); 11825 return 0; 11826 } 11827 if (hdd_ctx->config->napi_cpu_affinity_mask) 11828 rc = hdd_napi_apply_throughput_policy(hdd_ctx, tx_packets, 11829 rx_packets); 11830 return rc; 11831 } 11832 11833 /** 11834 * hdd_is_link_adapter() - Check if adapter is link adapter 11835 * @context: HDD context 11836 * @vdev_id: Vdev ID 11837 * 11838 * Return: true if link adapter else false 11839 */ 11840 static inline bool hdd_is_link_adapter(hdd_cb_handle context, uint8_t vdev_id) 11841 { 11842 struct hdd_context *hdd_ctx; 11843 struct wlan_hdd_link_info *link_info; 11844 11845 hdd_ctx = hdd_cb_handle_to_context(context); 11846 if (!hdd_ctx) { 11847 hdd_err("hdd_ctx is null"); 11848 return false; 11849 } 11850 11851 link_info = hdd_get_link_info_by_vdev(hdd_ctx, vdev_id); 11852 if (!link_info) { 11853 hdd_err("Invalid vdev"); 11854 return false; 11855 } 11856 return hdd_adapter_is_link_adapter(link_info->adapter); 11857 } 11858 11859 /** 11860 * hdd_get_pause_map() - Get pause map value 11861 * @context: HDD context 11862 * @netdev: netdev 11863 * 11864 * Return: pause map value 11865 */ 11866 static inline 11867 uint32_t hdd_get_pause_map(hdd_cb_handle context, qdf_netdev_t netdev) 11868 { 11869 struct hdd_adapter *adapter; 11870 11871 adapter = WLAN_HDD_GET_PRIV_PTR(netdev); 11872 if (!adapter) { 11873 hdd_err("adapter is null"); 11874 return 0; 11875 } 11876 11877 return adapter->pause_map; 11878 } 11879 11880 /** 11881 * hdd_any_adapter_connected() - Check if any adapter connected. 11882 * @context: HDD context 11883 * 11884 * Return: True if connected else false. 11885 */ 11886 static inline bool hdd_any_adapter_connected(hdd_cb_handle context) 11887 { 11888 struct hdd_context *hdd_ctx = hdd_cb_handle_to_context(context); 11889 11890 if (!hdd_ctx) { 11891 hdd_err("hdd_ctx is null"); 11892 return false; 11893 } 11894 11895 return hdd_is_any_adapter_connected(hdd_ctx); 11896 } 11897 11898 #ifdef WLAN_FEATURE_DP_BUS_BANDWIDTH 11899 /** 11900 * hdd_pld_request_pm_qos() - Request PLD PM QoS request 11901 * @context: HDD context 11902 * 11903 * Return: None 11904 */ 11905 static inline void hdd_pld_request_pm_qos(hdd_cb_handle context) 11906 { 11907 struct hdd_context *hdd_ctx = hdd_cb_handle_to_context(context); 11908 11909 if (!hdd_ctx) { 11910 hdd_err("hdd_ctx is null"); 11911 return; 11912 } 11913 11914 if (!hdd_ctx->hbw_requested) { 11915 PLD_REQUEST_PM_QOS(hdd_ctx->parent_dev, 1); 11916 hdd_ctx->hbw_requested = true; 11917 } 11918 } 11919 11920 /** 11921 * hdd_pld_remove_pm_qos() - Remove PLD PM QoS request 11922 * @context: HDD context 11923 * 11924 * Return: None 11925 */ 11926 static inline void hdd_pld_remove_pm_qos(hdd_cb_handle context) 11927 { 11928 struct hdd_context *hdd_ctx = hdd_cb_handle_to_context(context); 11929 11930 if (!hdd_ctx) { 11931 hdd_err("hdd_ctx is null"); 11932 return; 11933 } 11934 11935 if (hdd_ctx->hbw_requested && 11936 !hdd_ctx->pm_qos_request) { 11937 PLD_REMOVE_PM_QOS(hdd_ctx->parent_dev); 11938 hdd_ctx->hbw_requested = false; 11939 } 11940 } 11941 11942 /** 11943 * wlan_hdd_pm_qos_update_request() - Update PM QoS request 11944 * @context: HDD context 11945 * @pm_qos_cpu_mask: CPU mask 11946 * 11947 * Return: None 11948 */ 11949 static inline void 11950 wlan_hdd_pm_qos_update_request(hdd_cb_handle context, 11951 cpumask_t *pm_qos_cpu_mask) 11952 { 11953 struct hdd_context *hdd_ctx = hdd_cb_handle_to_context(context); 11954 11955 if (!hdd_ctx) { 11956 hdd_err("hdd_ctx is null"); 11957 return; 11958 } 11959 11960 if (!hdd_ctx->pm_qos_request) 11961 hdd_pm_qos_update_request(hdd_ctx, pm_qos_cpu_mask); 11962 } 11963 11964 /** 11965 * wlan_hdd_pm_qos_add_request() - Add PM QoS request 11966 * @context: HDD context 11967 * 11968 * Return: None 11969 */ 11970 static inline void wlan_hdd_pm_qos_add_request(hdd_cb_handle context) 11971 { 11972 struct hdd_context *hdd_ctx = hdd_cb_handle_to_context(context); 11973 11974 if (!hdd_ctx) { 11975 hdd_err("hdd_ctx is null"); 11976 return; 11977 } 11978 11979 hdd_pm_qos_add_request(hdd_ctx); 11980 } 11981 11982 /** 11983 * wlan_hdd_pm_qos_remove_request() - remove PM QoS request 11984 * @context: HDD context 11985 * 11986 * Return: None 11987 */ 11988 static inline void wlan_hdd_pm_qos_remove_request(hdd_cb_handle context) 11989 { 11990 struct hdd_context *hdd_ctx = hdd_cb_handle_to_context(context); 11991 11992 if (!hdd_ctx) { 11993 hdd_err("hdd_ctx is null"); 11994 return; 11995 } 11996 11997 hdd_pm_qos_remove_request(hdd_ctx); 11998 } 11999 12000 /** 12001 * wlan_hdd_send_mscs_action_frame() - Send MSCS action frame 12002 * @context: HDD context 12003 * @netdev: netdev 12004 * 12005 * Return: None 12006 */ 12007 static inline void wlan_hdd_send_mscs_action_frame(hdd_cb_handle context, 12008 qdf_netdev_t netdev) 12009 { 12010 struct hdd_adapter *adapter; 12011 struct wlan_hdd_link_info *link_info; 12012 12013 adapter = WLAN_HDD_GET_PRIV_PTR(netdev); 12014 if (!adapter) { 12015 hdd_err("adapter is null"); 12016 return; 12017 } 12018 12019 link_info = adapter->deflink; 12020 hdd_send_mscs_action_frame(link_info); 12021 } 12022 12023 #else 12024 static inline void hdd_pld_remove_pm_qos(hdd_cb_handle context) 12025 { 12026 } 12027 12028 static inline void hdd_pld_request_pm_qos(hdd_cb_handle context) 12029 { 12030 } 12031 12032 static inline void 12033 wlan_hdd_pm_qos_update_request(hdd_cb_handle context, 12034 cpumask_t *pm_qos_cpu_mask) 12035 { 12036 } 12037 12038 static inline void wlan_hdd_pm_qos_add_request(hdd_cb_handle context) 12039 { 12040 } 12041 12042 static inline void wlan_hdd_pm_qos_remove_request(hdd_cb_handle context) 12043 { 12044 } 12045 12046 static inline void wlan_hdd_send_mscs_action_frame(hdd_cb_handle context, 12047 qdf_netdev_t netdev) 12048 { 12049 } 12050 #endif 12051 12052 #if defined(WLAN_FEATURE_ROAM_OFFLOAD) && \ 12053 defined(FEATURE_RX_LINKSPEED_ROAM_TRIGGER) 12054 void wlan_hdd_link_speed_update(struct wlan_objmgr_psoc *psoc, 12055 uint8_t vdev_id, 12056 bool is_link_speed_good) 12057 { 12058 ucfg_cm_roam_link_speed_update(psoc, vdev_id, is_link_speed_good); 12059 } 12060 #endif 12061 12062 /** 12063 * hdd_dp_register_callbacks() - Register DP callbacks with HDD 12064 * @hdd_ctx: HDD context 12065 * 12066 * Return: None 12067 */ 12068 static void hdd_dp_register_callbacks(struct hdd_context *hdd_ctx) 12069 { 12070 struct wlan_dp_psoc_callbacks cb_obj = {0}; 12071 12072 cb_obj.callback_ctx = (hdd_cb_handle)hdd_ctx; 12073 cb_obj.wlan_dp_sta_get_dot11mode = wlan_hdd_sta_get_dot11mode; 12074 cb_obj.wlan_dp_get_ap_client_count = wlan_hdd_get_ap_client_count; 12075 cb_obj.wlan_dp_sta_ndi_connected = wlan_hdd_sta_ndi_connected; 12076 cb_obj.dp_any_adapter_connected = hdd_any_adapter_connected; 12077 cb_obj.dp_send_svc_nlink_msg = wlan_hdd_send_svc_nlink_msg; 12078 cb_obj.dp_pld_remove_pm_qos = hdd_pld_remove_pm_qos; 12079 cb_obj.dp_pld_request_pm_qos = hdd_pld_request_pm_qos; 12080 cb_obj.dp_pktlog_enable_disable = wlan_hdd_pktlog_enable_disable; 12081 cb_obj.dp_pm_qos_update_request = wlan_hdd_pm_qos_update_request; 12082 cb_obj.dp_pm_qos_add_request = wlan_hdd_pm_qos_add_request; 12083 cb_obj.dp_pm_qos_remove_request = wlan_hdd_pm_qos_remove_request; 12084 cb_obj.dp_send_mscs_action_frame = wlan_hdd_send_mscs_action_frame; 12085 cb_obj.dp_is_roaming_in_progress = wlan_hdd_is_roaming_in_progress; 12086 cb_obj.wlan_dp_display_tx_multiq_stats = 12087 wlan_hdd_display_tx_multiq_stats; 12088 cb_obj.wlan_dp_display_netif_queue_history = 12089 wlan_hdd_display_netif_queue_history; 12090 cb_obj.dp_is_ap_active = hdd_is_ap_active; 12091 cb_obj.dp_napi_apply_throughput_policy = 12092 wlan_hdd_napi_apply_throughput_policy; 12093 cb_obj.dp_is_link_adapter = hdd_is_link_adapter; 12094 cb_obj.dp_nud_failure_work = hdd_nud_failure_work; 12095 cb_obj.dp_get_pause_map = hdd_get_pause_map; 12096 12097 cb_obj.dp_get_netdev_by_vdev_mac = 12098 hdd_get_netdev_by_vdev_mac; 12099 cb_obj.dp_get_tx_resource = hdd_get_tx_resource; 12100 cb_obj.dp_get_tx_flow_low_watermark = hdd_get_tx_flow_low_watermark; 12101 cb_obj.dp_get_tsf_time = hdd_get_tsf_time_cb; 12102 cb_obj.dp_tsf_timestamp_rx = hdd_tsf_timestamp_rx; 12103 cb_obj.dp_gro_rx_legacy_get_napi = hdd_legacy_gro_get_napi; 12104 cb_obj.link_monitoring_cb = wlan_hdd_link_speed_update; 12105 12106 os_if_dp_register_hdd_callbacks(hdd_ctx->psoc, &cb_obj); 12107 } 12108 12109 /** 12110 * __hdd_adapter_param_update_work() - Gist of the work to process 12111 * netdev feature update. 12112 * @adapter: pointer to adapter structure 12113 * 12114 * This function assumes that the adapter pointer is always valid. 12115 * So the caller should always validate adapter pointer before calling 12116 * this function 12117 * 12118 * Returns: None 12119 */ 12120 static inline void 12121 __hdd_adapter_param_update_work(struct hdd_adapter *adapter) 12122 { 12123 /** 12124 * This check is needed in case the work got scheduled after the 12125 * interface got disconnected. 12126 * Netdev features update is to be done only after the connection, 12127 * since the connection mode plays an important role in identifying 12128 * the features that are to be updated. 12129 * So in case of interface disconnect skip feature update. 12130 */ 12131 if (!hdd_cm_is_vdev_associated(adapter->deflink)) 12132 return; 12133 12134 hdd_netdev_update_features(adapter); 12135 } 12136 12137 /** 12138 * hdd_adapter_param_update_work() - work to process the netdev features 12139 * update. 12140 * @arg: private data passed to work 12141 * 12142 * Returns: None 12143 */ 12144 static void hdd_adapter_param_update_work(void *arg) 12145 { 12146 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 12147 struct hdd_adapter *adapter = arg; 12148 struct osif_vdev_sync *vdev_sync; 12149 int errno; 12150 12151 if (!hdd_ctx) 12152 return; 12153 12154 hdd_adapter_ops_record_event(hdd_ctx, 12155 WLAN_HDD_ADAPTER_OPS_WORK_SCHED, 12156 WLAN_INVALID_VDEV_ID); 12157 12158 if (hdd_validate_adapter(adapter)) 12159 return; 12160 12161 errno = osif_vdev_sync_op_start(adapter->dev, &vdev_sync); 12162 if (errno) 12163 return; 12164 12165 __hdd_adapter_param_update_work(adapter); 12166 12167 osif_vdev_sync_op_stop(vdev_sync); 12168 } 12169 12170 QDF_STATUS hdd_init_adapter_ops_wq(struct hdd_context *hdd_ctx) 12171 { 12172 hdd_enter(); 12173 12174 hdd_ctx->adapter_ops_wq = 12175 qdf_alloc_high_prior_ordered_workqueue("hdd_adapter_ops_wq"); 12176 if (!hdd_ctx->adapter_ops_wq) 12177 return QDF_STATUS_E_NOMEM; 12178 12179 hdd_exit(); 12180 12181 return QDF_STATUS_SUCCESS; 12182 } 12183 12184 void hdd_deinit_adapter_ops_wq(struct hdd_context *hdd_ctx) 12185 { 12186 hdd_enter(); 12187 12188 qdf_flush_workqueue(0, hdd_ctx->adapter_ops_wq); 12189 qdf_destroy_workqueue(0, hdd_ctx->adapter_ops_wq); 12190 12191 hdd_exit(); 12192 } 12193 12194 QDF_STATUS hdd_adapter_feature_update_work_init(struct hdd_adapter *adapter) 12195 { 12196 QDF_STATUS status; 12197 12198 hdd_enter(); 12199 12200 status = qdf_create_work(0, &adapter->netdev_features_update_work, 12201 hdd_adapter_param_update_work, adapter); 12202 adapter->netdev_features_update_work_status = HDD_WORK_INITIALIZED; 12203 12204 hdd_exit(); 12205 12206 return status; 12207 } 12208 12209 void hdd_adapter_feature_update_work_deinit(struct hdd_adapter *adapter) 12210 { 12211 hdd_enter(); 12212 12213 if (adapter->netdev_features_update_work_status != 12214 HDD_WORK_INITIALIZED) { 12215 hdd_debug("work not yet init"); 12216 return; 12217 } 12218 qdf_cancel_work(&adapter->netdev_features_update_work); 12219 qdf_flush_work(&adapter->netdev_features_update_work); 12220 adapter->netdev_features_update_work_status = HDD_WORK_UNINITIALIZED; 12221 12222 hdd_exit(); 12223 } 12224 12225 #define HDD_DUMP_STAT_HELP(STAT_ID) \ 12226 hdd_nofl_debug("%u -- %s", STAT_ID, (# STAT_ID)) 12227 /** 12228 * hdd_display_stats_help() - print statistics help 12229 * 12230 * Return: none 12231 */ 12232 static void hdd_display_stats_help(void) 12233 { 12234 hdd_nofl_debug("iwpriv wlan0 dumpStats [option] - dump statistics"); 12235 hdd_nofl_debug("iwpriv wlan0 clearStats [option] - clear statistics"); 12236 hdd_nofl_debug("options:"); 12237 HDD_DUMP_STAT_HELP(CDP_TXRX_PATH_STATS); 12238 HDD_DUMP_STAT_HELP(CDP_TXRX_HIST_STATS); 12239 HDD_DUMP_STAT_HELP(CDP_TXRX_TSO_STATS); 12240 HDD_DUMP_STAT_HELP(CDP_HDD_NETIF_OPER_HISTORY); 12241 HDD_DUMP_STAT_HELP(CDP_DUMP_TX_FLOW_POOL_INFO); 12242 HDD_DUMP_STAT_HELP(CDP_TXRX_DESC_STATS); 12243 HDD_DUMP_STAT_HELP(CDP_HIF_STATS); 12244 HDD_DUMP_STAT_HELP(CDP_NAPI_STATS); 12245 HDD_DUMP_STAT_HELP(CDP_DP_NAPI_STATS); 12246 HDD_DUMP_STAT_HELP(CDP_DP_RX_THREAD_STATS); 12247 } 12248 12249 int hdd_wlan_dump_stats(struct hdd_adapter *adapter, int stats_id) 12250 { 12251 int ret = 0; 12252 QDF_STATUS status; 12253 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); 12254 12255 hdd_debug("stats_id %d", stats_id); 12256 12257 switch (stats_id) { 12258 case CDP_TXRX_HIST_STATS: 12259 ucfg_wlan_dp_display_tx_rx_histogram(hdd_ctx->psoc); 12260 break; 12261 case CDP_HDD_NETIF_OPER_HISTORY: 12262 wlan_hdd_display_adapter_netif_queue_history(adapter); 12263 break; 12264 case CDP_HIF_STATS: 12265 hdd_display_hif_stats(); 12266 break; 12267 case CDP_NAPI_STATS: 12268 if (hdd_display_napi_stats()) { 12269 hdd_err("error displaying napi stats"); 12270 ret = -EFAULT; 12271 } 12272 break; 12273 case CDP_DP_RX_THREAD_STATS: 12274 ucfg_dp_txrx_ext_dump_stats(cds_get_context(QDF_MODULE_ID_SOC), 12275 CDP_DP_RX_THREAD_STATS); 12276 break; 12277 case CDP_DISCONNECT_STATS: 12278 sme_display_disconnect_stats(hdd_ctx->mac_handle, 12279 adapter->deflink->vdev_id); 12280 break; 12281 default: 12282 status = cdp_display_stats(cds_get_context(QDF_MODULE_ID_SOC), 12283 stats_id, 12284 QDF_STATS_VERBOSITY_LEVEL_HIGH); 12285 if (status == QDF_STATUS_E_INVAL) { 12286 hdd_display_stats_help(); 12287 ret = -EINVAL; 12288 } 12289 break; 12290 } 12291 return ret; 12292 } 12293 12294 int hdd_wlan_clear_stats(struct hdd_adapter *adapter, int stats_id) 12295 { 12296 QDF_STATUS status = QDF_STATUS_SUCCESS; 12297 12298 hdd_debug("stats_id %d", stats_id); 12299 12300 switch (stats_id) { 12301 case CDP_HDD_STATS: 12302 ucfg_dp_clear_net_dev_stats(adapter->dev); 12303 memset(&adapter->deflink->hdd_stats, 0, 12304 sizeof(adapter->deflink->hdd_stats)); 12305 break; 12306 case CDP_TXRX_HIST_STATS: 12307 ucfg_wlan_dp_clear_tx_rx_histogram(adapter->hdd_ctx->psoc); 12308 break; 12309 case CDP_HDD_NETIF_OPER_HISTORY: 12310 wlan_hdd_clear_netif_queue_history(adapter->hdd_ctx); 12311 break; 12312 case CDP_HIF_STATS: 12313 hdd_clear_hif_stats(); 12314 break; 12315 case CDP_NAPI_STATS: 12316 hdd_clear_napi_stats(); 12317 break; 12318 default: 12319 status = cdp_clear_stats(cds_get_context(QDF_MODULE_ID_SOC), 12320 OL_TXRX_PDEV_ID, 12321 stats_id); 12322 if (status != QDF_STATUS_SUCCESS) 12323 hdd_debug("Failed to dump stats for stats_id: %d", 12324 stats_id); 12325 break; 12326 } 12327 12328 return qdf_status_to_os_return(status); 12329 } 12330 12331 /* length of the netif queue log needed per adapter */ 12332 #define ADAP_NETIFQ_LOG_LEN ((20 * WLAN_REASON_TYPE_MAX) + 50) 12333 12334 /** 12335 * hdd_display_netif_queue_history_compact() - display compact netifq history 12336 * @hdd_ctx: hdd context 12337 * 12338 * Return: none 12339 */ 12340 static void 12341 hdd_display_netif_queue_history_compact(struct hdd_context *hdd_ctx) 12342 { 12343 int adapter_num = 0; 12344 int i; 12345 int bytes_written; 12346 u32 tbytes; 12347 qdf_time_t total, pause, unpause, curr_time, delta; 12348 char temp_str[20 * WLAN_REASON_TYPE_MAX]; 12349 char *comb_log_str; 12350 uint32_t comb_log_str_size; 12351 struct hdd_adapter *adapter = NULL, *next_adapter = NULL; 12352 wlan_net_dev_ref_dbgid dbgid = 12353 NET_DEV_HOLD_DISPLAY_NETIF_QUEUE_HISTORY_COMPACT; 12354 12355 comb_log_str_size = (ADAP_NETIFQ_LOG_LEN * WLAN_MAX_VDEVS) + 1; 12356 comb_log_str = qdf_mem_malloc(comb_log_str_size); 12357 if (!comb_log_str) 12358 return; 12359 12360 bytes_written = 0; 12361 12362 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 12363 dbgid) { 12364 curr_time = qdf_system_ticks(); 12365 total = curr_time - adapter->start_time; 12366 delta = curr_time - adapter->last_time; 12367 12368 if (adapter->pause_map) { 12369 pause = adapter->total_pause_time + delta; 12370 unpause = adapter->total_unpause_time; 12371 } else { 12372 unpause = adapter->total_unpause_time + delta; 12373 pause = adapter->total_pause_time; 12374 } 12375 12376 tbytes = 0; 12377 qdf_mem_zero(temp_str, sizeof(temp_str)); 12378 for (i = WLAN_CONTROL_PATH; i < WLAN_REASON_TYPE_MAX; i++) { 12379 if (adapter->queue_oper_stats[i].pause_count == 0) 12380 continue; 12381 tbytes += 12382 snprintf( 12383 &temp_str[tbytes], 12384 (tbytes >= sizeof(temp_str) ? 12385 0 : sizeof(temp_str) - tbytes), 12386 "%d(%d,%d) ", 12387 i, 12388 adapter->queue_oper_stats[i]. 12389 pause_count, 12390 adapter->queue_oper_stats[i]. 12391 unpause_count); 12392 } 12393 if (tbytes >= sizeof(temp_str)) 12394 hdd_warn("log truncated"); 12395 12396 bytes_written += snprintf(&comb_log_str[bytes_written], 12397 bytes_written >= comb_log_str_size ? 0 : 12398 comb_log_str_size - bytes_written, 12399 "[%d %d] (%d) %u/%ums %s|", 12400 adapter->deflink->vdev_id, adapter->device_mode, 12401 adapter->pause_map, 12402 qdf_system_ticks_to_msecs(pause), 12403 qdf_system_ticks_to_msecs(total), 12404 temp_str); 12405 12406 adapter_num++; 12407 /* dev_put has to be done here */ 12408 hdd_adapter_dev_put_debug(adapter, dbgid); 12409 } 12410 12411 /* using QDF_TRACE to avoid printing function name */ 12412 QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_INFO_LOW, 12413 "STATS |%s", comb_log_str); 12414 12415 if (bytes_written >= comb_log_str_size) 12416 hdd_warn("log string truncated"); 12417 12418 qdf_mem_free(comb_log_str); 12419 } 12420 12421 /* Max size of a single netdev tx queue state string. e.g. "1: 0x1" */ 12422 #define HDD_NETDEV_TX_Q_STATE_STRLEN 15 12423 /** 12424 * wlan_hdd_display_adapter_netif_queue_stats() - display adapter based 12425 * netif queue stats 12426 * @adapter: hdd adapter 12427 * 12428 * Return: none 12429 */ 12430 static void 12431 wlan_hdd_display_adapter_netif_queue_stats(struct hdd_adapter *adapter) 12432 { 12433 int i; 12434 qdf_time_t total, pause, unpause, curr_time, delta; 12435 struct hdd_netif_queue_history *q_hist_ptr; 12436 char q_status_buf[NUM_TX_QUEUES * HDD_NETDEV_TX_Q_STATE_STRLEN] = {0}; 12437 12438 hdd_nofl_debug("Netif queue operation statistics:"); 12439 hdd_nofl_debug("vdev_id %d device mode %d", 12440 adapter->deflink->vdev_id, adapter->device_mode); 12441 hdd_nofl_debug("Current pause_map %x", adapter->pause_map); 12442 curr_time = qdf_system_ticks(); 12443 total = curr_time - adapter->start_time; 12444 delta = curr_time - adapter->last_time; 12445 if (adapter->pause_map) { 12446 pause = adapter->total_pause_time + delta; 12447 unpause = adapter->total_unpause_time; 12448 } else { 12449 unpause = adapter->total_unpause_time + delta; 12450 pause = adapter->total_pause_time; 12451 } 12452 hdd_nofl_debug("Total: %ums Pause: %ums Unpause: %ums", 12453 qdf_system_ticks_to_msecs(total), 12454 qdf_system_ticks_to_msecs(pause), 12455 qdf_system_ticks_to_msecs(unpause)); 12456 hdd_nofl_debug("reason_type: pause_cnt: unpause_cnt: pause_time"); 12457 12458 for (i = WLAN_CONTROL_PATH; i < WLAN_REASON_TYPE_MAX; i++) { 12459 qdf_time_t pause_delta = 0; 12460 12461 if (adapter->pause_map & (1 << i)) 12462 pause_delta = delta; 12463 12464 /* using hdd_log to avoid printing function name */ 12465 hdd_nofl_debug("%s: %d: %d: %ums", 12466 hdd_reason_type_to_string(i), 12467 adapter->queue_oper_stats[i].pause_count, 12468 adapter->queue_oper_stats[i]. 12469 unpause_count, 12470 qdf_system_ticks_to_msecs( 12471 adapter->queue_oper_stats[i]. 12472 total_pause_time + pause_delta)); 12473 } 12474 12475 hdd_nofl_debug("Netif queue operation history: Total entries: %d current index %d(-1) time %u", 12476 WLAN_HDD_MAX_HISTORY_ENTRY, 12477 adapter->history_index, 12478 qdf_system_ticks_to_msecs(qdf_system_ticks())); 12479 12480 hdd_nofl_debug("%2s%20s%50s%30s%10s %s", 12481 "#", "time(ms)", "action_type", "reason_type", 12482 "pause_map", "netdev-queue-status"); 12483 12484 for (i = 0; i < WLAN_HDD_MAX_HISTORY_ENTRY; i++) { 12485 /* using hdd_log to avoid printing function name */ 12486 if (adapter->queue_oper_history[i].time == 0) 12487 continue; 12488 q_hist_ptr = &adapter->queue_oper_history[i]; 12489 wlan_hdd_dump_queue_history_state(q_hist_ptr, 12490 q_status_buf, 12491 sizeof(q_status_buf)); 12492 hdd_nofl_debug("%2d%20u%50s%30s%10x %s", 12493 i, qdf_system_ticks_to_msecs( 12494 adapter->queue_oper_history[i].time), 12495 hdd_action_type_to_string( 12496 adapter->queue_oper_history[i]. 12497 netif_action), 12498 hdd_reason_type_to_string( 12499 adapter->queue_oper_history[i]. 12500 netif_reason), 12501 adapter->queue_oper_history[i].pause_map, 12502 q_status_buf); 12503 } 12504 } 12505 12506 void 12507 wlan_hdd_display_adapter_netif_queue_history(struct hdd_adapter *adapter) 12508 { 12509 wlan_hdd_display_adapter_netif_queue_stats(adapter); 12510 } 12511 12512 /** 12513 * wlan_hdd_display_netif_queue_history() - display netif queue history 12514 * @context: hdd context 12515 * @verb_lvl: verbosity level 12516 * 12517 * Return: none 12518 */ 12519 void 12520 wlan_hdd_display_netif_queue_history(hdd_cb_handle context, 12521 enum qdf_stats_verbosity_level verb_lvl) 12522 { 12523 struct hdd_adapter *adapter = NULL, *next_adapter = NULL; 12524 struct hdd_context *hdd_ctx = hdd_cb_handle_to_context(context); 12525 wlan_net_dev_ref_dbgid dbgid = 12526 NET_DEV_HOLD_DISPLAY_NETIF_QUEUE_HISTORY; 12527 12528 if (!hdd_ctx) { 12529 hdd_err("hdd_ctx is null"); 12530 return; 12531 } 12532 12533 if (verb_lvl == QDF_STATS_VERBOSITY_LEVEL_LOW) { 12534 hdd_display_netif_queue_history_compact(hdd_ctx); 12535 return; 12536 } 12537 12538 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 12539 dbgid) { 12540 if (adapter->deflink->vdev_id == CDP_INVALID_VDEV_ID) { 12541 hdd_adapter_dev_put_debug(adapter, dbgid); 12542 continue; 12543 } 12544 wlan_hdd_display_adapter_netif_queue_stats(adapter); 12545 /* dev_put has to be done here */ 12546 hdd_adapter_dev_put_debug(adapter, dbgid); 12547 } 12548 } 12549 12550 /** 12551 * wlan_hdd_clear_netif_queue_history() - clear netif queue operation history 12552 * @hdd_ctx: hdd context 12553 * 12554 * Return: none 12555 */ 12556 void wlan_hdd_clear_netif_queue_history(struct hdd_context *hdd_ctx) 12557 { 12558 struct hdd_adapter *adapter = NULL, *next_adapter = NULL; 12559 wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_CLEAR_NETIF_QUEUE_HISTORY; 12560 12561 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 12562 dbgid) { 12563 qdf_mem_zero(adapter->queue_oper_stats, 12564 sizeof(adapter->queue_oper_stats)); 12565 qdf_mem_zero(adapter->queue_oper_history, 12566 sizeof(adapter->queue_oper_history)); 12567 adapter->history_index = 0; 12568 adapter->start_time = adapter->last_time = qdf_system_ticks(); 12569 adapter->total_pause_time = 0; 12570 adapter->total_unpause_time = 0; 12571 hdd_adapter_dev_put_debug(adapter, dbgid); 12572 } 12573 } 12574 12575 #ifdef WLAN_FEATURE_OFFLOAD_PACKETS 12576 /** 12577 * hdd_init_offloaded_packets_ctx() - Initialize offload packets context 12578 * @hdd_ctx: hdd global context 12579 * 12580 * Return: none 12581 */ 12582 static void hdd_init_offloaded_packets_ctx(struct hdd_context *hdd_ctx) 12583 { 12584 uint8_t i; 12585 12586 mutex_init(&hdd_ctx->op_ctx.op_lock); 12587 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++) { 12588 hdd_ctx->op_ctx.op_table[i].request_id = MAX_REQUEST_ID; 12589 hdd_ctx->op_ctx.op_table[i].pattern_id = i; 12590 } 12591 } 12592 #else 12593 static void hdd_init_offloaded_packets_ctx(struct hdd_context *hdd_ctx) 12594 { 12595 } 12596 #endif 12597 12598 #ifdef WLAN_FEATURE_WOW_PULSE 12599 /** 12600 * wlan_hdd_set_wow_pulse() - call SME to send wmi cmd of wow pulse 12601 * @hdd_ctx: struct hdd_context structure pointer 12602 * @enable: enable or disable this behaviour 12603 * 12604 * Return: int 12605 */ 12606 static int wlan_hdd_set_wow_pulse(struct hdd_context *hdd_ctx, bool enable) 12607 { 12608 struct wow_pulse_mode wow_pulse_set_info; 12609 QDF_STATUS status; 12610 12611 hdd_debug("wow pulse enable flag is %d", enable); 12612 12613 if (!ucfg_pmo_is_wow_pulse_enabled(hdd_ctx->psoc)) 12614 return 0; 12615 12616 /* prepare the request to send to SME */ 12617 if (enable == true) { 12618 wow_pulse_set_info.wow_pulse_enable = true; 12619 wow_pulse_set_info.wow_pulse_pin = 12620 ucfg_pmo_get_wow_pulse_pin(hdd_ctx->psoc); 12621 12622 wow_pulse_set_info.wow_pulse_interval_high = 12623 ucfg_pmo_get_wow_pulse_interval_high(hdd_ctx->psoc); 12624 12625 wow_pulse_set_info.wow_pulse_interval_low = 12626 ucfg_pmo_get_wow_pulse_interval_low(hdd_ctx->psoc); 12627 12628 wow_pulse_set_info.wow_pulse_repeat_count = 12629 ucfg_pmo_get_wow_pulse_repeat_count(hdd_ctx->psoc); 12630 12631 wow_pulse_set_info.wow_pulse_init_state = 12632 ucfg_pmo_get_wow_pulse_init_state(hdd_ctx->psoc); 12633 } else { 12634 wow_pulse_set_info.wow_pulse_enable = false; 12635 wow_pulse_set_info.wow_pulse_pin = 0; 12636 wow_pulse_set_info.wow_pulse_interval_low = 0; 12637 wow_pulse_set_info.wow_pulse_interval_high = 0; 12638 wow_pulse_set_info.wow_pulse_repeat_count = 0; 12639 wow_pulse_set_info.wow_pulse_init_state = 0; 12640 } 12641 hdd_debug("enable %d pin %d low %d high %d count %d init %d", 12642 wow_pulse_set_info.wow_pulse_enable, 12643 wow_pulse_set_info.wow_pulse_pin, 12644 wow_pulse_set_info.wow_pulse_interval_low, 12645 wow_pulse_set_info.wow_pulse_interval_high, 12646 wow_pulse_set_info.wow_pulse_repeat_count, 12647 wow_pulse_set_info.wow_pulse_init_state); 12648 12649 status = sme_set_wow_pulse(&wow_pulse_set_info); 12650 if (QDF_STATUS_E_FAILURE == status) { 12651 hdd_debug("sme_set_wow_pulse failure!"); 12652 return -EIO; 12653 } 12654 hdd_debug("sme_set_wow_pulse success!"); 12655 return 0; 12656 } 12657 #else 12658 static inline int wlan_hdd_set_wow_pulse(struct hdd_context *hdd_ctx, bool enable) 12659 { 12660 return 0; 12661 } 12662 #endif 12663 12664 #ifdef WLAN_FEATURE_FASTPATH 12665 12666 /** 12667 * hdd_enable_fastpath() - Enable fastpath if enabled in config INI 12668 * @hdd_ctx: hdd context 12669 * @context: lower layer context 12670 * 12671 * Return: none 12672 */ 12673 void hdd_enable_fastpath(struct hdd_context *hdd_ctx, 12674 void *context) 12675 { 12676 if (cfg_get(hdd_ctx->psoc, CFG_DP_ENABLE_FASTPATH)) 12677 hif_enable_fastpath(context); 12678 } 12679 #endif 12680 12681 #if defined(FEATURE_WLAN_CH_AVOID) 12682 /** 12683 * hdd_set_thermal_level_cb() - set thermal level callback function 12684 * @hdd_handle: opaque handle for the hdd context 12685 * @level: thermal level 12686 * 12687 * Change IPA data path to SW path when the thermal throttle level greater 12688 * than 0, and restore the original data path when throttle level is 0 12689 * 12690 * Return: none 12691 */ 12692 static void hdd_set_thermal_level_cb(hdd_handle_t hdd_handle, u_int8_t level) 12693 { 12694 struct hdd_context *hdd_ctx = hdd_handle_to_context(hdd_handle); 12695 12696 /* Change IPA to SW path when throttle level greater than 0 */ 12697 if (level > THROTTLE_LEVEL_0) 12698 ucfg_ipa_send_mcc_scc_msg(hdd_ctx->pdev, true); 12699 else 12700 /* restore original concurrency mode */ 12701 ucfg_ipa_send_mcc_scc_msg(hdd_ctx->pdev, hdd_ctx->mcc_mode); 12702 } 12703 #else 12704 /** 12705 * hdd_set_thermal_level_cb() - set thermal level callback function 12706 * @hdd_handle: opaque handle for the hdd context 12707 * @level: thermal level 12708 * 12709 * Change IPA data path to SW path when the thermal throttle level greater 12710 * than 0, and restore the original data path when throttle level is 0 12711 * 12712 * Return: none 12713 */ 12714 static void hdd_set_thermal_level_cb(hdd_handle_t hdd_handle, u_int8_t level) 12715 { 12716 } 12717 #endif 12718 12719 QDF_STATUS hdd_switch_sap_channel(struct wlan_hdd_link_info *link_info, 12720 uint8_t channel, bool forced) 12721 { 12722 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(link_info->adapter); 12723 mac_handle_t mac_handle; 12724 struct sap_config *sap_cfg; 12725 qdf_freq_t freq; 12726 12727 mac_handle = hdd_adapter_get_mac_handle(link_info->adapter); 12728 if (!mac_handle) { 12729 hdd_err("invalid MAC handle"); 12730 return QDF_STATUS_E_INVAL; 12731 } 12732 12733 freq = wlan_reg_legacy_chan_to_freq(hdd_ctx->pdev, channel); 12734 sap_cfg = &(WLAN_HDD_GET_AP_CTX_PTR(link_info)->sap_config); 12735 hdd_debug("chan:%d width:%d", channel, sap_cfg->ch_width_orig); 12736 12737 return policy_mgr_change_sap_channel_with_csa(hdd_ctx->psoc, 12738 link_info->vdev_id, freq, 12739 sap_cfg->ch_width_orig, 12740 forced); 12741 } 12742 12743 QDF_STATUS hdd_switch_sap_chan_freq(struct hdd_adapter *adapter, 12744 qdf_freq_t chan_freq, 12745 enum phy_ch_width ch_width, 12746 bool forced) 12747 { 12748 struct hdd_ap_ctx *hdd_ap_ctx; 12749 struct hdd_context *hdd_ctx; 12750 12751 if (hdd_validate_adapter(adapter)) 12752 return QDF_STATUS_E_INVAL; 12753 12754 hdd_ctx = WLAN_HDD_GET_CTX(adapter); 12755 12756 if(wlan_hdd_validate_context(hdd_ctx)) 12757 return QDF_STATUS_E_INVAL; 12758 12759 hdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(adapter->deflink); 12760 12761 hdd_debug("chan freq:%d width:%d org bw %d", 12762 chan_freq, ch_width, hdd_ap_ctx->sap_config.ch_width_orig); 12763 12764 return policy_mgr_change_sap_channel_with_csa(hdd_ctx->psoc, 12765 adapter->deflink->vdev_id, 12766 chan_freq, 12767 ch_width, 12768 forced); 12769 } 12770 12771 int hdd_update_acs_timer_reason(struct hdd_adapter *adapter, uint8_t reason) 12772 { 12773 struct hdd_external_acs_timer_context *timer_context; 12774 int status; 12775 QDF_STATUS qdf_status; 12776 qdf_mc_timer_t *vendor_acs_timer; 12777 12778 set_bit(VENDOR_ACS_RESPONSE_PENDING, &adapter->deflink->link_flags); 12779 12780 vendor_acs_timer = &adapter->deflink->session.ap.vendor_acs_timer; 12781 if (QDF_TIMER_STATE_RUNNING == 12782 qdf_mc_timer_get_current_state(vendor_acs_timer)) { 12783 qdf_mc_timer_stop(vendor_acs_timer); 12784 } 12785 timer_context = 12786 (struct hdd_external_acs_timer_context *)vendor_acs_timer->user_data; 12787 timer_context->reason = reason; 12788 qdf_status = 12789 qdf_mc_timer_start(vendor_acs_timer, WLAN_VENDOR_ACS_WAIT_TIME); 12790 if (qdf_status != QDF_STATUS_SUCCESS) { 12791 hdd_err("failed to start external acs timer"); 12792 return -ENOSPC; 12793 } 12794 /* Update config to application */ 12795 status = hdd_cfg80211_update_acs_config(adapter, reason); 12796 hdd_info("Updated ACS config to nl with reason %d", reason); 12797 12798 return status; 12799 } 12800 12801 #ifdef FEATURE_WLAN_CH_AVOID_EXT 12802 uint32_t wlan_hdd_get_restriction_mask(struct hdd_context *hdd_ctx) 12803 { 12804 return hdd_ctx->restriction_mask; 12805 } 12806 12807 void wlan_hdd_set_restriction_mask(struct hdd_context *hdd_ctx) 12808 { 12809 hdd_ctx->restriction_mask = 12810 hdd_ctx->coex_avoid_freq_list.restriction_mask; 12811 } 12812 #else 12813 uint32_t wlan_hdd_get_restriction_mask(struct hdd_context *hdd_ctx) 12814 { 12815 return -EINVAL; 12816 } 12817 12818 void wlan_hdd_set_restriction_mask(struct hdd_context *hdd_ctx) 12819 { 12820 } 12821 #endif 12822 12823 #if defined(FEATURE_WLAN_CH_AVOID) 12824 /** 12825 * hdd_store_sap_restart_channel() - store sap restart channel 12826 * @restart_chan: restart channel 12827 * @restart_chan_store: pointer to restart channel store 12828 * 12829 * The function will store new sap restart channel. 12830 * 12831 * Return - none 12832 */ 12833 static void 12834 hdd_store_sap_restart_channel(qdf_freq_t restart_chan, qdf_freq_t *restart_chan_store) 12835 { 12836 uint8_t i; 12837 12838 for (i = 0; i < SAP_MAX_NUM_SESSION; i++) { 12839 if (*(restart_chan_store + i) == restart_chan) 12840 return; 12841 12842 if (*(restart_chan_store + i)) 12843 continue; 12844 12845 *(restart_chan_store + i) = restart_chan; 12846 return; 12847 } 12848 } 12849 12850 /** 12851 * hdd_check_chn_bw_boundary_unsafe() - check channel range unsafe 12852 * @hdd_ctxt: hdd context pointer 12853 * @adapter: hdd adapter pointer 12854 * 12855 * hdd_check_chn_bw_boundary_unsafe check SAP channel range with certain 12856 * bandwidth whether cover all unsafe channel list. 12857 * 12858 * Return - bool 12859 */ 12860 static bool 12861 hdd_check_chn_bw_boundary_unsafe(struct hdd_context *hdd_ctxt, 12862 struct hdd_adapter *adapter) 12863 { 12864 uint32_t freq; 12865 uint32_t start_freq = 0; 12866 uint32_t end_freq = 0; 12867 uint32_t i; 12868 uint8_t ch_width; 12869 const struct bonded_channel_freq *bonded_chan_ptr_ptr = NULL; 12870 12871 freq = adapter->deflink->session.ap.operating_chan_freq; 12872 ch_width = adapter->deflink->session.ap.sap_config.acs_cfg.ch_width; 12873 12874 if (ch_width > CH_WIDTH_20MHZ) 12875 bonded_chan_ptr_ptr = 12876 wlan_reg_get_bonded_chan_entry(freq, ch_width, 0); 12877 12878 if (bonded_chan_ptr_ptr) { 12879 start_freq = bonded_chan_ptr_ptr->start_freq; 12880 end_freq = bonded_chan_ptr_ptr->end_freq; 12881 } 12882 12883 for (i = 0; i < hdd_ctxt->unsafe_channel_count; i++) { 12884 if ((freq == hdd_ctxt->unsafe_channel_list[i]) || 12885 (start_freq <= hdd_ctxt->unsafe_channel_list[i] && 12886 hdd_ctxt->unsafe_channel_list[i] <= end_freq)) { 12887 hdd_debug("op chn freq:%u is unsafe for chn list:%u", 12888 freq, hdd_ctxt->unsafe_channel_list[i]); 12889 return true; 12890 } 12891 } 12892 12893 return false; 12894 } 12895 12896 /** 12897 * hdd_unsafe_channel_restart_sap() - restart sap if sap is on unsafe channel 12898 * @hdd_ctx: hdd context pointer 12899 * 12900 * hdd_unsafe_channel_restart_sap check all unsafe channel list 12901 * and if ACS is enabled, driver will ask userspace to restart the 12902 * sap. User space on LTE coex indication restart driver. 12903 * 12904 * Return - none 12905 */ 12906 QDF_STATUS hdd_unsafe_channel_restart_sap(struct hdd_context *hdd_ctx) 12907 { 12908 struct hdd_adapter *adapter, *next_adapter = NULL; 12909 struct hdd_ap_ctx *ap_ctx; 12910 uint32_t i; 12911 bool found = false; 12912 qdf_freq_t restart_chan_store[SAP_MAX_NUM_SESSION] = {0}; 12913 uint8_t scc_on_lte_coex = 0; 12914 uint32_t restart_freq, ap_chan_freq; 12915 bool value; 12916 QDF_STATUS status; 12917 bool is_acs_support_for_dfs_ltecoex = cfg_default(CFG_USER_ACS_DFS_LTE); 12918 bool is_vendor_acs_support = 12919 cfg_default(CFG_USER_AUTO_CHANNEL_SELECTION); 12920 wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_UNSAFE_CHANNEL_RESTART_SAP; 12921 enum phy_ch_width ch_width; 12922 struct wlan_hdd_link_info *link_info; 12923 12924 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 12925 dbgid) { 12926 if (adapter->device_mode != QDF_SAP_MODE) { 12927 hdd_debug_rl("skip device mode:%d", 12928 adapter->device_mode); 12929 hdd_adapter_dev_put_debug(adapter, dbgid); 12930 continue; 12931 } 12932 12933 hdd_adapter_for_each_active_link_info(adapter, link_info) { 12934 ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(link_info); 12935 if (!ap_ctx->sap_config.acs_cfg.acs_mode) { 12936 hdd_debug_rl("skip acs:%d", 12937 ap_ctx->sap_config.acs_cfg.acs_mode); 12938 continue; 12939 } 12940 12941 ap_chan_freq = ap_ctx->operating_chan_freq; 12942 ch_width = ap_ctx->sap_config.ch_width_orig; 12943 found = false; 12944 status = 12945 ucfg_policy_mgr_get_sta_sap_scc_lte_coex_chnl(hdd_ctx->psoc, 12946 &scc_on_lte_coex); 12947 if (!QDF_IS_STATUS_SUCCESS(status)) 12948 hdd_err("can't get scc on lte coex chnl, use def"); 12949 /* 12950 * If STA+SAP is doing SCC & 12951 * g_sta_sap_scc_on_lte_coex_chan is set, 12952 * no need to move SAP. 12953 */ 12954 if ((policy_mgr_is_sta_sap_scc(hdd_ctx->psoc, 12955 ap_chan_freq) && 12956 scc_on_lte_coex) || 12957 policy_mgr_nan_sap_scc_on_unsafe_ch_chk(hdd_ctx->psoc, 12958 ap_chan_freq)) 12959 hdd_debug("SAP allowed in unsafe SCC channel"); 12960 else 12961 found = hdd_check_chn_bw_boundary_unsafe(hdd_ctx, 12962 adapter); 12963 if (!found) { 12964 hdd_store_sap_restart_channel(ap_chan_freq, 12965 restart_chan_store); 12966 hdd_debug("ch freq:%d is safe. no need to change channel", 12967 ap_chan_freq); 12968 continue; 12969 } 12970 12971 status = ucfg_mlme_get_acs_support_for_dfs_ltecoex( 12972 hdd_ctx->psoc, 12973 &is_acs_support_for_dfs_ltecoex); 12974 if (!QDF_IS_STATUS_SUCCESS(status)) 12975 hdd_err("get_acs_support_for_dfs_ltecoex failed,set def"); 12976 12977 status = ucfg_mlme_get_vendor_acs_support( 12978 hdd_ctx->psoc, 12979 &is_vendor_acs_support); 12980 if (!QDF_IS_STATUS_SUCCESS(status)) 12981 hdd_err("get_vendor_acs_support failed, set default"); 12982 12983 if (is_vendor_acs_support && 12984 is_acs_support_for_dfs_ltecoex) { 12985 hdd_update_acs_timer_reason(adapter, 12986 QCA_WLAN_VENDOR_ACS_SELECT_REASON_LTE_COEX); 12987 continue; 12988 } 12989 12990 restart_freq = 0; 12991 for (i = 0; i < SAP_MAX_NUM_SESSION; i++) { 12992 if (!restart_chan_store[i]) 12993 continue; 12994 12995 if (policy_mgr_is_force_scc(hdd_ctx->psoc) && 12996 WLAN_REG_IS_SAME_BAND_FREQS( 12997 restart_chan_store[i], 12998 ap_chan_freq)) { 12999 restart_freq = restart_chan_store[i]; 13000 break; 13001 } 13002 } 13003 if (!restart_freq) { 13004 restart_freq = 13005 wlansap_get_safe_channel_from_pcl_and_acs_range( 13006 WLAN_HDD_GET_SAP_CTX_PTR(link_info), 13007 &ch_width); 13008 } 13009 if (!restart_freq) { 13010 wlan_hdd_set_sap_csa_reason(hdd_ctx->psoc, 13011 link_info->vdev_id, 13012 CSA_REASON_UNSAFE_CHANNEL); 13013 hdd_err("Unable to find safe chan, Stop the SAP if restriction mask is set else set txpower"); 13014 hdd_stop_sap_set_tx_power(hdd_ctx->psoc, adapter); 13015 continue; 13016 } 13017 /* 13018 * SAP restart due to unsafe channel. While 13019 * restarting the SAP, make sure to clear 13020 * acs_channel, channel to reset to 13021 * 0. Otherwise these settings will override 13022 * the ACS while restart. 13023 */ 13024 hdd_ctx->acs_policy.acs_chan_freq = 13025 AUTO_CHANNEL_SELECT; 13026 ucfg_mlme_get_sap_internal_restart(hdd_ctx->psoc, 13027 &value); 13028 if (value) { 13029 wlan_hdd_set_sap_csa_reason(hdd_ctx->psoc, 13030 link_info->vdev_id, 13031 CSA_REASON_UNSAFE_CHANNEL); 13032 status = hdd_switch_sap_chan_freq(adapter, 13033 restart_freq, 13034 ch_width, 13035 true); 13036 if (QDF_IS_STATUS_SUCCESS(status)) { 13037 hdd_adapter_dev_put_debug(adapter, 13038 dbgid); 13039 if (next_adapter) 13040 hdd_adapter_dev_put_debug( 13041 next_adapter, 13042 dbgid); 13043 return QDF_STATUS_E_PENDING; 13044 } else { 13045 hdd_debug("CSA failed, check next SAP"); 13046 } 13047 } else { 13048 hdd_debug("sending coex indication"); 13049 wlan_hdd_send_svc_nlink_msg( 13050 hdd_ctx->radio_index, 13051 WLAN_SVC_LTE_COEX_IND, NULL, 0); 13052 hdd_adapter_dev_put_debug(adapter, dbgid); 13053 if (next_adapter) 13054 hdd_adapter_dev_put_debug(next_adapter, 13055 dbgid); 13056 return QDF_STATUS_SUCCESS; 13057 } 13058 } 13059 /* dev_put has to be done here */ 13060 hdd_adapter_dev_put_debug(adapter, dbgid); 13061 } 13062 13063 return QDF_STATUS_SUCCESS; 13064 } 13065 13066 /** 13067 * hdd_init_channel_avoidance() - Initialize channel avoidance 13068 * @hdd_ctx: HDD global context 13069 * 13070 * Initialize the channel avoidance logic by retrieving the unsafe 13071 * channel list from the platform driver and plumbing the data 13072 * down to the lower layers. Then subscribe to subsequent channel 13073 * avoidance events. 13074 * 13075 * Return: None 13076 */ 13077 static void hdd_init_channel_avoidance(struct hdd_context *hdd_ctx) 13078 { 13079 uint16_t unsafe_channel_count; 13080 int index; 13081 qdf_freq_t *unsafe_freq_list; 13082 13083 pld_get_wlan_unsafe_channel(hdd_ctx->parent_dev, 13084 hdd_ctx->unsafe_channel_list, 13085 &(hdd_ctx->unsafe_channel_count), 13086 sizeof(uint16_t) * NUM_CHANNELS); 13087 13088 hdd_debug("num of unsafe channels is %d", 13089 hdd_ctx->unsafe_channel_count); 13090 13091 unsafe_channel_count = QDF_MIN((uint16_t)hdd_ctx->unsafe_channel_count, 13092 (uint16_t)NUM_CHANNELS); 13093 13094 if (!unsafe_channel_count) 13095 return; 13096 13097 unsafe_freq_list = qdf_mem_malloc( 13098 unsafe_channel_count * sizeof(*unsafe_freq_list)); 13099 13100 if (!unsafe_freq_list) 13101 return; 13102 13103 for (index = 0; index < unsafe_channel_count; index++) { 13104 hdd_debug("channel frequency %d is not safe", 13105 hdd_ctx->unsafe_channel_list[index]); 13106 unsafe_freq_list[index] = 13107 (qdf_freq_t)hdd_ctx->unsafe_channel_list[index]; 13108 } 13109 13110 ucfg_policy_mgr_init_chan_avoidance( 13111 hdd_ctx->psoc, 13112 unsafe_freq_list, 13113 unsafe_channel_count); 13114 13115 qdf_mem_free(unsafe_freq_list); 13116 } 13117 13118 static void hdd_lte_coex_restart_sap(struct hdd_adapter *adapter, 13119 struct hdd_context *hdd_ctx) 13120 { 13121 uint8_t restart_chan; 13122 uint32_t restart_freq; 13123 13124 restart_freq = wlansap_get_safe_channel_from_pcl_and_acs_range( 13125 WLAN_HDD_GET_SAP_CTX_PTR(adapter->deflink), 13126 NULL); 13127 13128 restart_chan = wlan_reg_freq_to_chan(hdd_ctx->pdev, 13129 restart_freq); 13130 13131 if (!restart_chan) { 13132 hdd_alert("fail to restart SAP"); 13133 return; 13134 } 13135 13136 /* SAP restart due to unsafe channel. While restarting 13137 * the SAP, make sure to clear acs_channel, channel to 13138 * reset to 0. Otherwise these settings will override 13139 * the ACS while restart. 13140 */ 13141 hdd_ctx->acs_policy.acs_chan_freq = AUTO_CHANNEL_SELECT; 13142 13143 hdd_debug("sending coex indication"); 13144 13145 wlan_hdd_send_svc_nlink_msg(hdd_ctx->radio_index, 13146 WLAN_SVC_LTE_COEX_IND, NULL, 0); 13147 wlan_hdd_set_sap_csa_reason(hdd_ctx->psoc, adapter->deflink->vdev_id, 13148 CSA_REASON_LTE_COEX); 13149 hdd_switch_sap_channel(adapter->deflink, restart_chan, true); 13150 } 13151 13152 int hdd_clone_local_unsafe_chan(struct hdd_context *hdd_ctx, 13153 uint16_t **local_unsafe_list, uint16_t *local_unsafe_list_count) 13154 { 13155 uint32_t size; 13156 uint16_t *unsafe_list; 13157 uint16_t chan_count; 13158 13159 if (!hdd_ctx || !local_unsafe_list_count || !local_unsafe_list_count) 13160 return -EINVAL; 13161 13162 chan_count = QDF_MIN(hdd_ctx->unsafe_channel_count, 13163 NUM_CHANNELS); 13164 if (chan_count) { 13165 size = chan_count * sizeof(hdd_ctx->unsafe_channel_list[0]); 13166 unsafe_list = qdf_mem_malloc(size); 13167 if (!unsafe_list) 13168 return -ENOMEM; 13169 qdf_mem_copy(unsafe_list, hdd_ctx->unsafe_channel_list, size); 13170 } else { 13171 unsafe_list = NULL; 13172 } 13173 13174 *local_unsafe_list = unsafe_list; 13175 *local_unsafe_list_count = chan_count; 13176 13177 return 0; 13178 } 13179 13180 bool hdd_local_unsafe_channel_updated( 13181 struct hdd_context *hdd_ctx, uint16_t *local_unsafe_list, 13182 uint16_t local_unsafe_list_count, uint32_t restriction_mask) 13183 { 13184 int i, j; 13185 13186 if (local_unsafe_list_count != hdd_ctx->unsafe_channel_count) 13187 return true; 13188 if (local_unsafe_list_count == 0) 13189 return false; 13190 for (i = 0; i < local_unsafe_list_count; i++) { 13191 for (j = 0; j < local_unsafe_list_count; j++) 13192 if (local_unsafe_list[i] == 13193 hdd_ctx->unsafe_channel_list[j]) 13194 break; 13195 if (j >= local_unsafe_list_count) 13196 break; 13197 } 13198 13199 if (ucfg_mlme_get_coex_unsafe_chan_nb_user_prefer(hdd_ctx->psoc)) { 13200 /* Return false if current channel list is same as previous 13201 * and restriction mask is not altered 13202 */ 13203 if (i >= local_unsafe_list_count && 13204 (restriction_mask == 13205 wlan_hdd_get_restriction_mask(hdd_ctx))) { 13206 hdd_info("unsafe chan list same"); 13207 return false; 13208 } 13209 } else if (i >= local_unsafe_list_count) { 13210 hdd_info("unsafe chan list same"); 13211 return false; 13212 } 13213 13214 return true; 13215 } 13216 #else 13217 static void hdd_init_channel_avoidance(struct hdd_context *hdd_ctx) 13218 { 13219 } 13220 13221 static inline void hdd_lte_coex_restart_sap(struct hdd_adapter *adapter, 13222 struct hdd_context *hdd_ctx) 13223 { 13224 hdd_debug("Channel avoidance is not enabled; Abort SAP restart"); 13225 } 13226 #endif /* defined(FEATURE_WLAN_CH_AVOID) */ 13227 13228 struct wlan_hdd_link_info * 13229 wlan_hdd_get_link_info_from_objmgr(struct wlan_objmgr_vdev *vdev) 13230 { 13231 if (!vdev) { 13232 hdd_err("null vdev object"); 13233 return NULL; 13234 } 13235 13236 if (vdev->vdev_nif.osdev) 13237 return vdev->vdev_nif.osdev->legacy_osif_priv; 13238 13239 return NULL; 13240 } 13241 13242 /** 13243 * hdd_indicate_mgmt_frame() - Wrapper to indicate management frame to 13244 * user space 13245 * @frame_ind: Management frame data to be informed. 13246 * 13247 * This function is used to indicate management frame to 13248 * user space 13249 * 13250 * Return: None 13251 * 13252 */ 13253 void hdd_indicate_mgmt_frame(tSirSmeMgmtFrameInd *frame_ind) 13254 { 13255 struct hdd_context *hdd_ctx = NULL; 13256 struct hdd_adapter *adapter = NULL, *next_adapter = NULL; 13257 int i, num_adapters; 13258 uint8_t vdev_id[WLAN_MAX_VDEVS + WLAN_MAX_ML_VDEVS]; 13259 struct ieee80211_mgmt *mgmt = 13260 (struct ieee80211_mgmt *)frame_ind->frameBuf; 13261 struct wlan_objmgr_vdev *vdev; 13262 wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_INDICATE_MGMT_FRAME; 13263 struct wlan_hdd_link_info *link_info; 13264 13265 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 13266 if (wlan_hdd_validate_context(hdd_ctx)) 13267 return; 13268 13269 if (frame_ind->frame_len < ieee80211_hdrlen(mgmt->frame_control)) { 13270 hdd_err(" Invalid frame length"); 13271 return; 13272 } 13273 13274 if (SME_SESSION_ID_ANY == frame_ind->sessionId) { 13275 for (i = 0; i < WLAN_MAX_VDEVS; i++) { 13276 link_info = hdd_get_link_info_by_vdev(hdd_ctx, i); 13277 if (link_info) { 13278 adapter = link_info->adapter; 13279 break; 13280 } 13281 } 13282 } else if (SME_SESSION_ID_BROADCAST == frame_ind->sessionId) { 13283 num_adapters = 0; 13284 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, 13285 next_adapter, dbgid) { 13286 hdd_adapter_for_each_active_link_info(adapter, 13287 link_info) { 13288 vdev_id[num_adapters] = link_info->vdev_id; 13289 num_adapters++; 13290 } 13291 /* dev_put has to be done here */ 13292 hdd_adapter_dev_put_debug(adapter, dbgid); 13293 } 13294 13295 adapter = NULL; 13296 13297 for (i = 0; i < num_adapters; i++) { 13298 vdev = wlan_objmgr_get_vdev_by_id_from_psoc( 13299 hdd_ctx->psoc, 13300 vdev_id[i], 13301 WLAN_OSIF_ID); 13302 13303 if (!vdev) 13304 continue; 13305 13306 link_info = wlan_hdd_get_link_info_from_objmgr(vdev); 13307 if (!link_info) { 13308 wlan_objmgr_vdev_release_ref(vdev, 13309 WLAN_OSIF_ID); 13310 continue; 13311 } 13312 13313 hdd_indicate_mgmt_frame_to_user(link_info->adapter, 13314 frame_ind->frame_len, 13315 frame_ind->frameBuf, 13316 frame_ind->frameType, 13317 frame_ind->rx_freq, 13318 frame_ind->rxRssi, 13319 frame_ind->rx_flags); 13320 wlan_objmgr_vdev_release_ref(vdev, WLAN_OSIF_ID); 13321 } 13322 13323 adapter = NULL; 13324 } else { 13325 link_info = hdd_get_link_info_by_vdev(hdd_ctx, 13326 frame_ind->sessionId); 13327 13328 if (!link_info) { 13329 hdd_err("Invalid vdev"); 13330 return; 13331 } 13332 13333 adapter = link_info->adapter; 13334 } 13335 13336 if ((adapter) && 13337 (WLAN_HDD_ADAPTER_MAGIC == adapter->magic)) 13338 hdd_indicate_mgmt_frame_to_user(adapter, 13339 frame_ind->frame_len, 13340 frame_ind->frameBuf, 13341 frame_ind->frameType, 13342 frame_ind->rx_freq, 13343 frame_ind->rxRssi, 13344 frame_ind->rx_flags); 13345 } 13346 13347 void hdd_acs_response_timeout_handler(void *context) 13348 { 13349 struct hdd_external_acs_timer_context *timer_context = 13350 (struct hdd_external_acs_timer_context *)context; 13351 struct hdd_adapter *adapter; 13352 struct hdd_context *hdd_ctx; 13353 uint8_t reason; 13354 struct sap_context *sap_context; 13355 struct wlan_hdd_link_info *link_info; 13356 13357 hdd_enter(); 13358 if (!timer_context) { 13359 hdd_err("invalid timer context"); 13360 return; 13361 } 13362 adapter = timer_context->adapter; 13363 reason = timer_context->reason; 13364 13365 if (!adapter || adapter->magic != WLAN_HDD_ADAPTER_MAGIC) { 13366 hdd_err("invalid adapter or adapter has invalid magic"); 13367 return; 13368 } 13369 13370 hdd_ctx = WLAN_HDD_GET_CTX(adapter); 13371 if (wlan_hdd_validate_context(hdd_ctx)) 13372 return; 13373 13374 link_info = adapter->deflink; 13375 if (!test_bit(VENDOR_ACS_RESPONSE_PENDING, &link_info->link_flags)) 13376 return; 13377 13378 clear_bit(VENDOR_ACS_RESPONSE_PENDING, &link_info->link_flags); 13379 13380 hdd_err("ACS timeout happened for %s reason %d", 13381 adapter->dev->name, reason); 13382 13383 sap_context = WLAN_HDD_GET_SAP_CTX_PTR(link_info); 13384 switch (reason) { 13385 /* SAP init case */ 13386 case QCA_WLAN_VENDOR_ACS_SELECT_REASON_INIT: 13387 wlan_sap_set_vendor_acs(sap_context, false); 13388 wlan_hdd_cfg80211_start_acs(link_info); 13389 break; 13390 /* DFS detected on current channel */ 13391 case QCA_WLAN_VENDOR_ACS_SELECT_REASON_DFS: 13392 wlan_sap_update_next_channel(sap_context, 0, 0); 13393 sme_update_new_channel_event(hdd_ctx->mac_handle, 13394 link_info->vdev_id); 13395 break; 13396 /* LTE coex event on current channel */ 13397 case QCA_WLAN_VENDOR_ACS_SELECT_REASON_LTE_COEX: 13398 hdd_lte_coex_restart_sap(adapter, hdd_ctx); 13399 break; 13400 default: 13401 hdd_info("invalid reason for timer invoke"); 13402 } 13403 } 13404 13405 /** 13406 * hdd_override_ini_config - Override INI config 13407 * @hdd_ctx: HDD context 13408 * 13409 * Override INI config based on module parameter. 13410 * 13411 * Return: None 13412 */ 13413 static void hdd_override_ini_config(struct hdd_context *hdd_ctx) 13414 { 13415 QDF_STATUS status; 13416 13417 if (0 == enable_dfs_chan_scan || 1 == enable_dfs_chan_scan) { 13418 ucfg_scan_cfg_set_dfs_chan_scan_allowed(hdd_ctx->psoc, 13419 enable_dfs_chan_scan); 13420 hdd_debug("Module enable_dfs_chan_scan set to %d", 13421 enable_dfs_chan_scan); 13422 } 13423 if (0 == enable_11d || 1 == enable_11d) { 13424 status = ucfg_mlme_set_11d_enabled(hdd_ctx->psoc, enable_11d); 13425 if (!QDF_IS_STATUS_SUCCESS(status)) 13426 hdd_err("Failed to set 11d_enable flag"); 13427 } 13428 } 13429 13430 #ifdef ENABLE_MTRACE_LOG 13431 static void hdd_set_mtrace_for_each(struct hdd_context *hdd_ctx) 13432 { 13433 uint8_t module_id = 0; 13434 int qdf_print_idx = -1; 13435 13436 qdf_print_idx = qdf_get_pidx(); 13437 for (module_id = 0; module_id < QDF_MODULE_ID_MAX; module_id++) 13438 qdf_print_set_category_verbose( 13439 qdf_print_idx, 13440 module_id, QDF_TRACE_LEVEL_TRACE, 13441 hdd_ctx->config->enable_mtrace); 13442 } 13443 #else 13444 static void hdd_set_mtrace_for_each(struct hdd_context *hdd_ctx) 13445 { 13446 } 13447 13448 #endif 13449 13450 /** 13451 * hdd_log_level_to_bitmask() - user space log level to host log bitmask 13452 * @user_log_level: user space log level 13453 * 13454 * Convert log level from user space to host log level bitmask. 13455 * 13456 * Return: Bitmask of log levels to be enabled 13457 */ 13458 static uint32_t hdd_log_level_to_bitmask(enum host_log_level user_log_level) 13459 { 13460 QDF_TRACE_LEVEL host_trace_level; 13461 uint32_t bitmask; 13462 13463 switch (user_log_level) { 13464 case HOST_LOG_LEVEL_NONE: 13465 host_trace_level = QDF_TRACE_LEVEL_NONE; 13466 break; 13467 case HOST_LOG_LEVEL_FATAL: 13468 host_trace_level = QDF_TRACE_LEVEL_FATAL; 13469 break; 13470 case HOST_LOG_LEVEL_ERROR: 13471 host_trace_level = QDF_TRACE_LEVEL_ERROR; 13472 break; 13473 case HOST_LOG_LEVEL_WARN: 13474 host_trace_level = QDF_TRACE_LEVEL_WARN; 13475 break; 13476 case HOST_LOG_LEVEL_INFO: 13477 host_trace_level = QDF_TRACE_LEVEL_INFO_LOW; 13478 break; 13479 case HOST_LOG_LEVEL_DEBUG: 13480 host_trace_level = QDF_TRACE_LEVEL_DEBUG; 13481 break; 13482 case HOST_LOG_LEVEL_TRACE: 13483 host_trace_level = QDF_TRACE_LEVEL_TRACE; 13484 break; 13485 default: 13486 host_trace_level = QDF_TRACE_LEVEL_TRACE; 13487 break; 13488 } 13489 13490 bitmask = (1 << (host_trace_level + 1)) - 1; 13491 13492 return bitmask; 13493 } 13494 13495 /** 13496 * hdd_set_trace_level_for_each - Set trace level for each INI config 13497 * @hdd_ctx: HDD context 13498 * 13499 * Set trace level for each module based on INI config. 13500 * 13501 * Return: None 13502 */ 13503 static void hdd_set_trace_level_for_each(struct hdd_context *hdd_ctx) 13504 { 13505 uint8_t host_module_log[QDF_MODULE_ID_MAX * 2]; 13506 qdf_size_t host_module_log_num = 0; 13507 QDF_MODULE_ID module_id; 13508 uint32_t bitmask; 13509 uint32_t i; 13510 13511 qdf_uint8_array_parse(cfg_get(hdd_ctx->psoc, 13512 CFG_ENABLE_HOST_MODULE_LOG_LEVEL), 13513 host_module_log, 13514 QDF_MODULE_ID_MAX * 2, 13515 &host_module_log_num); 13516 13517 for (i = 0; i + 1 < host_module_log_num; i += 2) { 13518 module_id = host_module_log[i]; 13519 bitmask = hdd_log_level_to_bitmask(host_module_log[i + 1]); 13520 if (module_id < QDF_MODULE_ID_MAX && 13521 module_id >= QDF_MODULE_ID_MIN) 13522 hdd_qdf_trace_enable(module_id, bitmask); 13523 } 13524 13525 hdd_set_mtrace_for_each(hdd_ctx); 13526 } 13527 13528 /** 13529 * hdd_context_init() - Initialize HDD context 13530 * @hdd_ctx: HDD context. 13531 * 13532 * Initialize HDD context along with all the feature specific contexts. 13533 * 13534 * return: 0 on success and errno on failure. 13535 */ 13536 static int hdd_context_init(struct hdd_context *hdd_ctx) 13537 { 13538 int ret; 13539 13540 hdd_ctx->ioctl_scan_mode = eSIR_ACTIVE_SCAN; 13541 hdd_ctx->max_intf_count = WLAN_MAX_VDEVS; 13542 13543 init_completion(&hdd_ctx->mc_sus_event_var); 13544 init_completion(&hdd_ctx->ready_to_suspend); 13545 13546 qdf_spinlock_create(&hdd_ctx->connection_status_lock); 13547 qdf_spinlock_create(&hdd_ctx->hdd_adapter_lock); 13548 13549 qdf_list_create(&hdd_ctx->hdd_adapters, 0); 13550 13551 ret = hdd_scan_context_init(hdd_ctx); 13552 if (ret) 13553 goto list_destroy; 13554 13555 ret = hdd_sap_context_init(hdd_ctx); 13556 if (ret) 13557 goto scan_destroy; 13558 13559 ret = ucfg_dp_bbm_context_init(hdd_ctx->psoc); 13560 if (ret) 13561 goto sap_destroy; 13562 13563 wlan_hdd_cfg80211_extscan_init(hdd_ctx); 13564 13565 hdd_init_offloaded_packets_ctx(hdd_ctx); 13566 13567 ret = wlan_hdd_cfg80211_init(hdd_ctx->parent_dev, hdd_ctx->wiphy, 13568 hdd_ctx->config); 13569 if (ret) 13570 goto bbm_destroy; 13571 13572 qdf_wake_lock_create(&hdd_ctx->monitor_mode_wakelock, 13573 "monitor_mode_wakelock"); 13574 13575 return 0; 13576 13577 bbm_destroy: 13578 ucfg_dp_bbm_context_deinit(hdd_ctx->psoc); 13579 13580 sap_destroy: 13581 hdd_sap_context_destroy(hdd_ctx); 13582 13583 scan_destroy: 13584 hdd_scan_context_destroy(hdd_ctx); 13585 list_destroy: 13586 qdf_list_destroy(&hdd_ctx->hdd_adapters); 13587 13588 return ret; 13589 } 13590 13591 void hdd_psoc_idle_timer_start(struct hdd_context *hdd_ctx) 13592 { 13593 uint32_t timeout_ms = hdd_ctx->config->iface_change_wait_time; 13594 uint32_t suspend_timeout_ms; 13595 enum wake_lock_reason reason = 13596 WIFI_POWER_EVENT_WAKELOCK_IFACE_CHANGE_TIMER; 13597 13598 if (!timeout_ms) { 13599 hdd_info("psoc idle timer is disabled"); 13600 return; 13601 } 13602 13603 hdd_debug("Starting psoc idle timer"); 13604 13605 /* If PCIe gen speed change is requested, reduce idle shutdown 13606 * timeout to 100 ms 13607 */ 13608 if (hdd_ctx->current_pcie_gen_speed) { 13609 timeout_ms = HDD_PCIE_GEN_SPEED_CHANGE_TIMEOUT_MS; 13610 hdd_info("pcie gen speed change requested"); 13611 } 13612 13613 qdf_delayed_work_start(&hdd_ctx->psoc_idle_timeout_work, timeout_ms); 13614 suspend_timeout_ms = timeout_ms + HDD_PSOC_IDLE_SHUTDOWN_SUSPEND_DELAY; 13615 hdd_prevent_suspend_timeout(suspend_timeout_ms, reason); 13616 } 13617 13618 void hdd_psoc_idle_timer_stop(struct hdd_context *hdd_ctx) 13619 { 13620 qdf_delayed_work_stop_sync(&hdd_ctx->psoc_idle_timeout_work); 13621 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_IFACE_CHANGE_TIMER); 13622 hdd_debug("Stopped psoc idle timer"); 13623 } 13624 13625 13626 /** 13627 * __hdd_psoc_idle_shutdown() - perform an idle shutdown on the given psoc 13628 * @hdd_ctx: the hdd context which should be shutdown 13629 * 13630 * When no interfaces are "up" on a psoc, an idle shutdown timer is started. 13631 * If no interfaces are brought up before the timer expires, we do an 13632 * "idle shutdown," cutting power to the physical SoC to save power. This is 13633 * done completely transparently from the perspective of userspace. 13634 * 13635 * Return: None 13636 */ 13637 static int __hdd_psoc_idle_shutdown(struct hdd_context *hdd_ctx) 13638 { 13639 struct osif_psoc_sync *psoc_sync; 13640 int errno; 13641 13642 hdd_enter(); 13643 13644 hdd_reg_wait_for_country_change(hdd_ctx); 13645 13646 errno = osif_psoc_sync_trans_start(hdd_ctx->parent_dev, &psoc_sync); 13647 if (errno) { 13648 hdd_info("psoc busy, abort idle shutdown; errno:%d", errno); 13649 errno = -EAGAIN; 13650 goto exit; 13651 } 13652 13653 osif_psoc_sync_wait_for_ops(psoc_sync); 13654 /* 13655 * This is to handle scenario in which platform driver triggers 13656 * idle_shutdown if Deep Sleep/Hibernate entry notification is 13657 * received from modem subsystem in wearable devices 13658 */ 13659 if (hdd_is_any_interface_open(hdd_ctx)) { 13660 hdd_err_rl("all interfaces are not down, ignore idle shutdown"); 13661 errno = -EAGAIN; 13662 } else { 13663 errno = hdd_wlan_stop_modules(hdd_ctx, false); 13664 } 13665 13666 osif_psoc_sync_trans_stop(psoc_sync); 13667 13668 exit: 13669 hdd_exit(); 13670 return errno; 13671 } 13672 13673 static int __hdd_mode_change_psoc_idle_shutdown(struct hdd_context *hdd_ctx) 13674 { 13675 is_mode_change_psoc_idle_shutdown = false; 13676 return hdd_wlan_stop_modules(hdd_ctx, true); 13677 } 13678 13679 int hdd_psoc_idle_shutdown(struct device *dev) 13680 { 13681 int ret; 13682 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 13683 13684 if (!hdd_ctx) 13685 return -EINVAL; 13686 13687 if (is_mode_change_psoc_idle_shutdown) 13688 ret = __hdd_mode_change_psoc_idle_shutdown(hdd_ctx); 13689 else { 13690 ret = __hdd_psoc_idle_shutdown(hdd_ctx); 13691 } 13692 13693 return ret; 13694 } 13695 13696 static int __hdd_psoc_idle_restart(struct hdd_context *hdd_ctx) 13697 { 13698 int ret; 13699 13700 ret = hdd_soc_idle_restart_lock(hdd_ctx->parent_dev); 13701 if (ret) 13702 return ret; 13703 13704 ret = hdd_wlan_start_modules(hdd_ctx, false); 13705 13706 hdd_soc_idle_restart_unlock(); 13707 13708 return ret; 13709 } 13710 13711 int hdd_psoc_idle_restart(struct device *dev) 13712 { 13713 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 13714 13715 if (!hdd_ctx) 13716 return -EINVAL; 13717 13718 return __hdd_psoc_idle_restart(hdd_ctx); 13719 } 13720 13721 int hdd_trigger_psoc_idle_restart(struct hdd_context *hdd_ctx) 13722 { 13723 int ret; 13724 13725 QDF_BUG(rtnl_is_locked()); 13726 13727 hdd_psoc_idle_timer_stop(hdd_ctx); 13728 if (hdd_ctx->driver_status == DRIVER_MODULES_ENABLED) { 13729 hdd_nofl_debug("Driver modules already Enabled"); 13730 return 0; 13731 } 13732 13733 ret = hdd_soc_idle_restart_lock(hdd_ctx->parent_dev); 13734 if (ret) 13735 return ret; 13736 13737 if (hdd_ctx->current_pcie_gen_speed) { 13738 hdd_info("request pcie gen speed change to %d", 13739 hdd_ctx->current_pcie_gen_speed); 13740 13741 /* call pld api for pcie gen speed change */ 13742 ret = pld_set_pcie_gen_speed(hdd_ctx->parent_dev, 13743 hdd_ctx->current_pcie_gen_speed); 13744 if (ret) 13745 hdd_err_rl("failed to set pcie gen speed"); 13746 13747 hdd_ctx->current_pcie_gen_speed = 0; 13748 } 13749 13750 qdf_event_reset(&hdd_ctx->regulatory_update_event); 13751 qdf_mutex_acquire(&hdd_ctx->regulatory_status_lock); 13752 hdd_ctx->is_regulatory_update_in_progress = true; 13753 qdf_mutex_release(&hdd_ctx->regulatory_status_lock); 13754 13755 ret = pld_idle_restart(hdd_ctx->parent_dev, hdd_psoc_idle_restart); 13756 hdd_soc_idle_restart_unlock(); 13757 13758 return ret; 13759 } 13760 13761 /** 13762 * hdd_psoc_idle_timeout_callback() - Handler for psoc idle timeout 13763 * @priv: pointer to hdd context 13764 * 13765 * Return: None 13766 */ 13767 static void hdd_psoc_idle_timeout_callback(void *priv) 13768 { 13769 int ret; 13770 struct hdd_context *hdd_ctx = priv; 13771 void *hif_ctx; 13772 13773 if (wlan_hdd_validate_context(hdd_ctx)) 13774 return; 13775 13776 hif_ctx = cds_get_context(QDF_MODULE_ID_HIF); 13777 if (hif_ctx) { 13778 /* 13779 * Trigger runtime sync resume before psoc_idle_shutdown 13780 * such that resume can happen successfully 13781 */ 13782 qdf_rtpm_sync_resume(); 13783 } 13784 13785 hdd_info("Psoc idle timeout elapsed; starting psoc shutdown"); 13786 13787 ret = pld_idle_shutdown(hdd_ctx->parent_dev, hdd_psoc_idle_shutdown); 13788 if (-EAGAIN == ret || hdd_ctx->is_wiphy_suspended) { 13789 hdd_debug("System suspend in progress. Restart idle shutdown timer"); 13790 hdd_psoc_idle_timer_start(hdd_ctx); 13791 } 13792 13793 /* Clear the recovery flag for PCIe discrete soc after idle shutdown*/ 13794 if (PLD_BUS_TYPE_PCIE == pld_get_bus_type(hdd_ctx->parent_dev) && 13795 -EBUSY != ret) 13796 cds_set_recovery_in_progress(false); 13797 } 13798 13799 #ifdef WLAN_LOGGING_SOCK_SVC_ENABLE 13800 static void hdd_set_wlan_logging(struct hdd_context *hdd_ctx) 13801 { 13802 wlan_set_console_log_levels(hdd_ctx->config->wlan_console_log_levels); 13803 wlan_logging_set_active(hdd_ctx->config->wlan_logging_enable); 13804 } 13805 #else 13806 static void hdd_set_wlan_logging(struct hdd_context *hdd_ctx) 13807 { } 13808 #endif 13809 13810 #ifdef WLAN_LOGGING_SOCK_SVC_ENABLE 13811 static void hdd_init_wlan_logging_params(struct hdd_config *config, 13812 struct wlan_objmgr_psoc *psoc) 13813 { 13814 config->wlan_logging_enable = cfg_get(psoc, CFG_WLAN_LOGGING_SUPPORT); 13815 13816 config->wlan_console_log_levels = 13817 cfg_get(psoc, CFG_WLAN_LOGGING_CONSOLE_SUPPORT); 13818 config->host_log_custom_nl_proto = 13819 cfg_get(psoc, CFG_HOST_LOG_CUSTOM_NETLINK_PROTO); 13820 } 13821 #else 13822 static void hdd_init_wlan_logging_params(struct hdd_config *config, 13823 struct wlan_objmgr_psoc *psoc) 13824 { 13825 } 13826 #endif 13827 13828 #ifdef FEATURE_WLAN_AUTO_SHUTDOWN 13829 static void hdd_init_wlan_auto_shutdown(struct hdd_config *config, 13830 struct wlan_objmgr_psoc *psoc) 13831 { 13832 config->wlan_auto_shutdown = cfg_get(psoc, CFG_WLAN_AUTO_SHUTDOWN); 13833 } 13834 #else 13835 static void hdd_init_wlan_auto_shutdown(struct hdd_config *config, 13836 struct wlan_objmgr_psoc *psoc) 13837 { 13838 } 13839 #endif 13840 13841 #ifndef REMOVE_PKT_LOG 13842 static void hdd_init_packet_log(struct hdd_config *config, 13843 struct wlan_objmgr_psoc *psoc) 13844 { 13845 config->enable_packet_log = cfg_get(psoc, CFG_ENABLE_PACKET_LOG); 13846 } 13847 #else 13848 static void hdd_init_packet_log(struct hdd_config *config, 13849 struct wlan_objmgr_psoc *psoc) 13850 { 13851 } 13852 #endif 13853 13854 #ifdef ENABLE_MTRACE_LOG 13855 static void hdd_init_mtrace_log(struct hdd_config *config, 13856 struct wlan_objmgr_psoc *psoc) 13857 { 13858 config->enable_mtrace = cfg_get(psoc, CFG_ENABLE_MTRACE); 13859 } 13860 #else 13861 static void hdd_init_mtrace_log(struct hdd_config *config, 13862 struct wlan_objmgr_psoc *psoc) 13863 { 13864 } 13865 #endif 13866 13867 #ifdef FEATURE_RUNTIME_PM 13868 static void hdd_init_runtime_pm(struct hdd_config *config, 13869 struct wlan_objmgr_psoc *psoc) 13870 { 13871 config->runtime_pm = cfg_get(psoc, CFG_ENABLE_RUNTIME_PM); 13872 } 13873 13874 bool hdd_is_runtime_pm_enabled(struct hdd_context *hdd_ctx) 13875 { 13876 return hdd_ctx->config->runtime_pm != hdd_runtime_pm_disabled; 13877 } 13878 #else 13879 static void hdd_init_runtime_pm(struct hdd_config *config, 13880 struct wlan_objmgr_psoc *psoc) 13881 13882 { 13883 } 13884 13885 bool hdd_is_runtime_pm_enabled(struct hdd_context *hdd_ctx) 13886 { 13887 return false; 13888 } 13889 #endif 13890 13891 #ifdef WLAN_FEATURE_WMI_SEND_RECV_QMI 13892 static void hdd_init_qmi_stats(struct hdd_config *config, 13893 struct wlan_objmgr_psoc *psoc) 13894 { 13895 config->is_qmi_stats_enabled = cfg_get(psoc, CFG_ENABLE_QMI_STATS); 13896 } 13897 #else 13898 static void hdd_init_qmi_stats(struct hdd_config *config, 13899 struct wlan_objmgr_psoc *psoc) 13900 13901 { 13902 } 13903 #endif 13904 13905 #ifdef FEATURE_WLAN_DYNAMIC_CVM 13906 static void hdd_init_vc_mode_cfg_bitmap(struct hdd_config *config, 13907 struct wlan_objmgr_psoc *psoc) 13908 { 13909 config->vc_mode_cfg_bitmap = cfg_get(psoc, CFG_VC_MODE_BITMAP); 13910 } 13911 #else 13912 static void hdd_init_vc_mode_cfg_bitmap(struct hdd_config *config, 13913 struct wlan_objmgr_psoc *psoc) 13914 { 13915 } 13916 #endif 13917 13918 #ifdef DHCP_SERVER_OFFLOAD 13919 static void 13920 hdd_init_dhcp_server_ip(struct hdd_context *hdd_ctx) 13921 { 13922 uint8_t num_entries; 13923 13924 hdd_ctx->config->dhcp_server_ip.is_dhcp_server_ip_valid = true; 13925 hdd_string_to_u8_array(cfg_get(hdd_ctx->psoc, CFG_DHCP_SERVER_IP_NAME), 13926 hdd_ctx->config->dhcp_server_ip.dhcp_server_ip, 13927 &num_entries, IPADDR_NUM_ENTRIES); 13928 13929 if (num_entries != IPADDR_NUM_ENTRIES) { 13930 hdd_err("Incorrect IP address (%s) assigned for DHCP server!", 13931 cfg_get(hdd_ctx->psoc, CFG_DHCP_SERVER_IP_NAME)); 13932 hdd_config->dhcp_server_ip.is_dhcp_server_ip_valid = false; 13933 } 13934 } 13935 #else 13936 static void 13937 hdd_init_dhcp_server_ip(struct hdd_context *hdd_ctx) 13938 { 13939 } 13940 #endif 13941 13942 #ifdef SAR_SAFETY_FEATURE 13943 static void hdd_sar_cfg_update(struct hdd_config *config, 13944 struct wlan_objmgr_psoc *psoc) 13945 { 13946 config->sar_safety_timeout = cfg_get(psoc, CFG_SAR_SAFETY_TIMEOUT); 13947 config->sar_safety_unsolicited_timeout = 13948 cfg_get(psoc, CFG_SAR_SAFETY_UNSOLICITED_TIMEOUT); 13949 config->sar_safety_req_resp_timeout = 13950 cfg_get(psoc, CFG_SAR_SAFETY_REQ_RESP_TIMEOUT); 13951 config->sar_safety_req_resp_retry = 13952 cfg_get(psoc, CFG_SAR_SAFETY_REQ_RESP_RETRIES); 13953 config->sar_safety_index = cfg_get(psoc, CFG_SAR_SAFETY_INDEX); 13954 config->sar_safety_sleep_index = 13955 cfg_get(psoc, CFG_SAR_SAFETY_SLEEP_INDEX); 13956 config->enable_sar_safety = 13957 cfg_get(psoc, CFG_ENABLE_SAR_SAFETY_FEATURE); 13958 config->config_sar_safety_sleep_index = 13959 cfg_get(psoc, CFG_CONFIG_SAR_SAFETY_SLEEP_MODE_INDEX); 13960 } 13961 #else 13962 static void hdd_sar_cfg_update(struct hdd_config *config, 13963 struct wlan_objmgr_psoc *psoc) 13964 { 13965 } 13966 #endif 13967 13968 #ifdef FEATURE_SET 13969 /** 13970 * hdd_get_wifi_features_cfg_update() - Initialize get wifi features cfg 13971 * @config: Pointer to HDD config 13972 * @psoc: psoc pointer 13973 * 13974 * Return: None 13975 */ 13976 static void hdd_get_wifi_features_cfg_update(struct hdd_config *config, 13977 struct wlan_objmgr_psoc *psoc) 13978 { 13979 config->get_wifi_features = cfg_get(psoc, CFG_GET_WIFI_FEATURES); 13980 } 13981 #else 13982 static void hdd_get_wifi_features_cfg_update(struct hdd_config *config, 13983 struct wlan_objmgr_psoc *psoc) 13984 { 13985 } 13986 #endif 13987 13988 #ifdef FEATURE_RUNTIME_PM 13989 /** 13990 * hdd_init_cpu_cxpc_threshold_cfg() - Initialize cpu cxpc threshold cfg 13991 * @config: Pointer to HDD config 13992 * @psoc: psoc pointer 13993 * 13994 * Return: None 13995 */ 13996 static void hdd_init_cpu_cxpc_threshold_cfg(struct hdd_config *config, 13997 struct wlan_objmgr_psoc *psoc) 13998 { 13999 config->cpu_cxpc_threshold = cfg_get(psoc, CFG_CPU_CXPC_THRESHOLD); 14000 } 14001 #else 14002 static void hdd_init_cpu_cxpc_threshold_cfg(struct hdd_config *config, 14003 struct wlan_objmgr_psoc *psoc) 14004 { 14005 } 14006 #endif 14007 14008 /** 14009 * hdd_cfg_params_init() - Initialize hdd params in hdd_config structure 14010 * @hdd_ctx: Pointer to HDD context 14011 * 14012 * Return: None 14013 */ 14014 static void hdd_cfg_params_init(struct hdd_context *hdd_ctx) 14015 { 14016 struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc; 14017 struct hdd_config *config = hdd_ctx->config; 14018 if (!psoc) { 14019 hdd_err("Invalid psoc"); 14020 return; 14021 } 14022 14023 if (!config) { 14024 hdd_err("Invalid hdd config"); 14025 return; 14026 } 14027 14028 config->dot11Mode = cfg_get(psoc, CFG_HDD_DOT11_MODE); 14029 config->bug_on_reinit_failure = cfg_get(psoc, 14030 CFG_BUG_ON_REINIT_FAILURE); 14031 14032 config->is_ramdump_enabled = cfg_get(psoc, 14033 CFG_ENABLE_RAMDUMP_COLLECTION); 14034 14035 config->iface_change_wait_time = cfg_get(psoc, 14036 CFG_INTERFACE_CHANGE_WAIT); 14037 14038 config->multicast_host_fw_msgs = cfg_get(psoc, 14039 CFG_MULTICAST_HOST_FW_MSGS); 14040 14041 config->private_wext_control = cfg_get(psoc, CFG_PRIVATE_WEXT_CONTROL); 14042 config->enablefwprint = cfg_get(psoc, CFG_ENABLE_FW_UART_PRINT); 14043 config->enable_fw_log = cfg_get(psoc, CFG_ENABLE_FW_LOG); 14044 config->operating_chan_freq = cfg_get(psoc, CFG_OPERATING_FREQUENCY); 14045 config->num_vdevs = cfg_get(psoc, CFG_NUM_VDEV_ENABLE); 14046 qdf_str_lcopy(config->enable_concurrent_sta, 14047 cfg_get(psoc, CFG_ENABLE_CONCURRENT_STA), 14048 CFG_CONCURRENT_IFACE_MAX_LEN); 14049 qdf_str_lcopy(config->dbs_scan_selection, 14050 cfg_get(psoc, CFG_DBS_SCAN_SELECTION), 14051 CFG_DBS_SCAN_PARAM_LENGTH); 14052 config->inform_bss_rssi_raw = cfg_get(psoc, CFG_INFORM_BSS_RSSI_RAW); 14053 config->mac_provision = cfg_get(psoc, CFG_ENABLE_MAC_PROVISION); 14054 config->provisioned_intf_pool = 14055 cfg_get(psoc, CFG_PROVISION_INTERFACE_POOL); 14056 config->derived_intf_pool = cfg_get(psoc, CFG_DERIVED_INTERFACE_POOL); 14057 config->advertise_concurrent_operation = 14058 cfg_get(psoc, 14059 CFG_ADVERTISE_CONCURRENT_OPERATION); 14060 config->is_unit_test_framework_enabled = 14061 cfg_get(psoc, CFG_ENABLE_UNIT_TEST_FRAMEWORK); 14062 config->disable_channel = cfg_get(psoc, CFG_ENABLE_DISABLE_CHANNEL); 14063 config->enable_sar_conversion = cfg_get(psoc, CFG_SAR_CONVERSION); 14064 config->nb_commands_interval = 14065 cfg_get(psoc, CFG_NB_COMMANDS_RATE_LIMIT); 14066 14067 hdd_init_vc_mode_cfg_bitmap(config, psoc); 14068 hdd_init_runtime_pm(config, psoc); 14069 hdd_init_wlan_auto_shutdown(config, psoc); 14070 hdd_init_wlan_logging_params(config, psoc); 14071 hdd_init_packet_log(config, psoc); 14072 hdd_init_mtrace_log(config, psoc); 14073 hdd_init_dhcp_server_ip(hdd_ctx); 14074 hdd_dp_cfg_update(psoc, hdd_ctx); 14075 hdd_sar_cfg_update(config, psoc); 14076 hdd_init_qmi_stats(config, psoc); 14077 hdd_club_ll_stats_in_get_sta_cfg_update(config, psoc); 14078 config->read_mac_addr_from_mac_file = 14079 cfg_get(psoc, CFG_READ_MAC_ADDR_FROM_MAC_FILE); 14080 14081 hdd_get_wifi_features_cfg_update(config, psoc); 14082 hdd_init_cpu_cxpc_threshold_cfg(config, psoc); 14083 } 14084 14085 #ifdef CONNECTION_ROAMING_CFG 14086 static QDF_STATUS hdd_cfg_parse_connection_roaming_cfg(void) 14087 { 14088 QDF_STATUS status = QDF_STATUS_E_INVAL; 14089 bool is_valid; 14090 14091 is_valid = cfg_valid_ini_check(WLAN_CONNECTION_ROAMING_INI_FILE); 14092 14093 if (is_valid) 14094 status = cfg_parse(WLAN_CONNECTION_ROAMING_INI_FILE); 14095 if (QDF_IS_STATUS_ERROR(status)) { 14096 is_valid = cfg_valid_ini_check(WLAN_CONNECTION_ROAMING_BACKUP_INI_FILE); 14097 if (is_valid) 14098 status = cfg_parse(WLAN_CONNECTION_ROAMING_BACKUP_INI_FILE); 14099 } 14100 return status; 14101 } 14102 #else 14103 static inline QDF_STATUS hdd_cfg_parse_connection_roaming_cfg(void) 14104 { 14105 return QDF_STATUS_E_NOSUPPORT; 14106 } 14107 #endif 14108 14109 struct hdd_context *hdd_context_create(struct device *dev) 14110 { 14111 QDF_STATUS status; 14112 int ret = 0; 14113 struct hdd_context *hdd_ctx; 14114 14115 hdd_enter(); 14116 14117 hdd_ctx = hdd_cfg80211_wiphy_alloc(); 14118 if (!hdd_ctx) { 14119 ret = -ENOMEM; 14120 goto err_out; 14121 } 14122 14123 status = qdf_delayed_work_create(&hdd_ctx->psoc_idle_timeout_work, 14124 hdd_psoc_idle_timeout_callback, 14125 hdd_ctx); 14126 if (QDF_IS_STATUS_ERROR(status)) { 14127 ret = qdf_status_to_os_return(status); 14128 goto wiphy_dealloc; 14129 } 14130 14131 hdd_pm_notifier_init(hdd_ctx); 14132 14133 hdd_ctx->parent_dev = dev; 14134 hdd_ctx->last_scan_reject_vdev_id = WLAN_UMAC_VDEV_ID_MAX; 14135 14136 hdd_ctx->config = qdf_mem_malloc(sizeof(struct hdd_config)); 14137 if (!hdd_ctx->config) { 14138 ret = -ENOMEM; 14139 goto err_free_hdd_context; 14140 } 14141 14142 status = cfg_parse(WLAN_INI_FILE); 14143 if (QDF_IS_STATUS_ERROR(status)) { 14144 hdd_err("Failed to parse cfg %s; status:%d\n", 14145 WLAN_INI_FILE, status); 14146 /* Assert if failed to parse at least one INI parameter */ 14147 QDF_BUG(status != QDF_STATUS_E_INVAL); 14148 ret = qdf_status_to_os_return(status); 14149 goto err_free_config; 14150 } 14151 14152 status = hdd_cfg_parse_connection_roaming_cfg(); 14153 14154 ret = hdd_objmgr_create_and_store_psoc(hdd_ctx, DEFAULT_PSOC_ID); 14155 if (ret) { 14156 QDF_DEBUG_PANIC("Psoc creation fails!"); 14157 goto err_release_store; 14158 } 14159 14160 if (QDF_IS_STATUS_SUCCESS(status)) 14161 ucfg_mlme_set_connection_roaming_ini_present(hdd_ctx->psoc, 14162 true); 14163 14164 hdd_cfg_params_init(hdd_ctx); 14165 14166 /* apply multiplier config, if not already set via module parameter */ 14167 if (qdf_timer_get_multiplier() == 1) 14168 qdf_timer_set_multiplier(cfg_get(hdd_ctx->psoc, 14169 CFG_TIMER_MULTIPLIER)); 14170 hdd_debug("set timer multiplier: %u", qdf_timer_get_multiplier()); 14171 14172 cds_set_fatal_event(cfg_get(hdd_ctx->psoc, 14173 CFG_ENABLE_FATAL_EVENT_TRIGGER)); 14174 14175 hdd_override_ini_config(hdd_ctx); 14176 14177 ret = hdd_context_init(hdd_ctx); 14178 14179 if (ret) 14180 goto err_hdd_objmgr_destroy; 14181 14182 if (hdd_get_conparam() == QDF_GLOBAL_EPPING_MODE) 14183 goto skip_multicast_logging; 14184 14185 cds_set_multicast_logging(hdd_ctx->config->multicast_host_fw_msgs); 14186 ret = hdd_init_netlink_services(hdd_ctx); 14187 if (ret) 14188 goto err_deinit_hdd_context; 14189 14190 hdd_set_wlan_logging(hdd_ctx); 14191 qdf_atomic_init(&hdd_ctx->adapter_ops_history.index); 14192 14193 skip_multicast_logging: 14194 hdd_set_trace_level_for_each(hdd_ctx); 14195 14196 cds_set_context(QDF_MODULE_ID_HDD, hdd_ctx); 14197 14198 wlan_hdd_sar_timers_init(hdd_ctx); 14199 14200 hdd_exit(); 14201 14202 return hdd_ctx; 14203 14204 err_deinit_hdd_context: 14205 hdd_context_deinit(hdd_ctx); 14206 14207 err_hdd_objmgr_destroy: 14208 hdd_objmgr_release_and_destroy_psoc(hdd_ctx); 14209 14210 err_release_store: 14211 cfg_release(); 14212 14213 err_free_config: 14214 qdf_mem_free(hdd_ctx->config); 14215 14216 err_free_hdd_context: 14217 qdf_delayed_work_destroy(&hdd_ctx->psoc_idle_timeout_work); 14218 14219 wiphy_dealloc: 14220 wiphy_free(hdd_ctx->wiphy); 14221 14222 err_out: 14223 return ERR_PTR(ret); 14224 } 14225 14226 #ifdef MULTI_CLIENT_LL_SUPPORT 14227 /** 14228 * wlan_hdd_init_multi_client_info_table()- Initialize the multi client info 14229 * table 14230 * @adapter: hdd adapter 14231 * 14232 * Return: none 14233 */ 14234 static void 14235 wlan_hdd_init_multi_client_info_table(struct hdd_adapter *adapter) 14236 { 14237 uint8_t i; 14238 14239 for (i = 0; i < WLM_MAX_HOST_CLIENT; i++) { 14240 adapter->client_info[i].client_id = i; 14241 adapter->client_info[i].port_id = 0; 14242 adapter->client_info[i].in_use = false; 14243 } 14244 } 14245 14246 void wlan_hdd_deinit_multi_client_info_table(struct hdd_adapter *adapter) 14247 { 14248 uint8_t i; 14249 14250 hdd_debug("deinitializing the client info table"); 14251 /* de-initialize the table for host driver client */ 14252 for (i = 0; i < WLM_MAX_HOST_CLIENT; i++) { 14253 if (adapter->client_info[i].in_use) { 14254 adapter->client_info[i].port_id = 0; 14255 adapter->client_info[i].client_id = i; 14256 adapter->client_info[i].in_use = false; 14257 } 14258 } 14259 } 14260 14261 /** 14262 * wlan_hdd_get_host_driver_port_id()- get host driver port id 14263 * @port_id: argument to be filled 14264 * 14265 * Return: none 14266 */ 14267 static void wlan_hdd_get_host_driver_port_id(uint32_t *port_id) 14268 { 14269 *port_id = WLAM_WLM_HOST_DRIVER_PORT_ID; 14270 } 14271 14272 #else 14273 static inline void 14274 wlan_hdd_init_multi_client_info_table(struct hdd_adapter *adapter) 14275 { 14276 } 14277 14278 static inline void wlan_hdd_get_host_driver_port_id(uint32_t *port_id) 14279 { 14280 } 14281 #endif 14282 14283 static void 14284 hdd_adapter_set_wlm_client_latency_level(struct hdd_adapter *adapter) 14285 { 14286 QDF_STATUS status; 14287 bool reset; 14288 uint32_t port_id; 14289 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); 14290 14291 if (!hdd_ctx) 14292 return; 14293 14294 status = ucfg_mlme_cfg_get_wlm_reset(hdd_ctx->psoc, &reset); 14295 if (QDF_IS_STATUS_ERROR(status)) { 14296 hdd_err("could not get the wlm reset flag"); 14297 reset = false; 14298 } 14299 14300 if (reset) 14301 goto out; 14302 14303 if (hdd_get_multi_client_ll_support(adapter)) { 14304 wlan_hdd_get_host_driver_port_id(&port_id); 14305 status = wlan_hdd_set_wlm_client_latency_level( 14306 adapter, port_id, 14307 adapter->latency_level); 14308 if (QDF_IS_STATUS_ERROR(status)) 14309 hdd_warn("Fail to set latency level:%u", status); 14310 } else { 14311 status = sme_set_wlm_latency_level(hdd_ctx->mac_handle, 14312 adapter->deflink->vdev_id, 14313 adapter->latency_level, 14314 0, false); 14315 if (QDF_IS_STATUS_ERROR(status)) 14316 hdd_warn("set wlm mode failed, %u", status); 14317 } 14318 out: 14319 hdd_debug("wlm initial mode %u", adapter->latency_level); 14320 } 14321 14322 #ifdef WLAN_HDD_MULTI_VDEV_SINGLE_NDEV 14323 struct qdf_mac_addr * 14324 hdd_adapter_get_link_mac_addr(struct wlan_hdd_link_info *link_info) 14325 { 14326 struct hdd_adapter *adapter; 14327 14328 if (!link_info) 14329 return NULL; 14330 14331 adapter = link_info->adapter; 14332 if (!hdd_adapter_is_ml_adapter(adapter) || 14333 qdf_is_macaddr_zero(&link_info->link_addr) || 14334 !wlan_vdev_mlme_is_mlo_vdev(link_info->vdev)) 14335 return &adapter->mac_addr; 14336 14337 return &link_info->link_addr; 14338 } 14339 #else 14340 struct qdf_mac_addr * 14341 hdd_adapter_get_link_mac_addr(struct wlan_hdd_link_info *link_info) 14342 { 14343 if (!link_info) 14344 return NULL; 14345 14346 return &link_info->adapter->mac_addr; 14347 } 14348 #endif 14349 14350 #if defined(WLAN_FEATURE_11BE_MLO) && defined(CFG80211_11BE_BASIC) && \ 14351 defined(WLAN_HDD_MULTI_VDEV_SINGLE_NDEV) 14352 QDF_STATUS hdd_adapter_check_duplicate_session(struct hdd_adapter *adapter) 14353 { 14354 int i = 0; 14355 QDF_STATUS status; 14356 uint8_t *addr_list[WLAN_MAX_MLD + 2] = {0}; 14357 struct wlan_hdd_link_info *link_info; 14358 14359 if (!hdd_adapter_is_ml_adapter(adapter) || 14360 adapter->device_mode == QDF_SAP_MODE) 14361 goto netdev_addr; 14362 14363 hdd_adapter_for_each_active_link_info(adapter, link_info) 14364 addr_list[i++] = &link_info->link_addr.bytes[0]; 14365 14366 netdev_addr: 14367 addr_list[i] = &adapter->mac_addr.bytes[0]; 14368 status = sme_check_for_duplicate_session(adapter->hdd_ctx->mac_handle, 14369 &addr_list[0]); 14370 return status; 14371 } 14372 14373 QDF_STATUS hdd_adapter_fill_link_address(struct hdd_adapter *adapter) 14374 { 14375 int i = 0; 14376 QDF_STATUS status; 14377 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); 14378 enum QDF_OPMODE opmode = adapter->device_mode; 14379 struct qdf_mac_addr link_addrs[WLAN_MAX_ML_BSS_LINKS] = {0}; 14380 struct wlan_hdd_link_info *link_info; 14381 14382 if (opmode != QDF_STA_MODE && opmode != QDF_SAP_MODE) 14383 return QDF_STATUS_SUCCESS; 14384 14385 if (opmode == QDF_SAP_MODE) { 14386 link_info = adapter->deflink; 14387 qdf_copy_macaddr(&link_info->link_addr, &adapter->mac_addr); 14388 return QDF_STATUS_SUCCESS; 14389 } 14390 14391 if (!hdd_adapter_is_ml_adapter(adapter)) 14392 return QDF_STATUS_SUCCESS; 14393 14394 status = hdd_derive_link_address_from_mld(hdd_ctx->psoc, 14395 &adapter->mac_addr, 14396 &link_addrs[0], 14397 WLAN_MAX_ML_BSS_LINKS); 14398 if (QDF_IS_STATUS_ERROR(status)) 14399 return status; 14400 14401 hdd_adapter_for_each_link_info(adapter, link_info) 14402 qdf_copy_macaddr(&link_info->link_addr, &link_addrs[i++]); 14403 14404 return status; 14405 } 14406 #elif defined(WLAN_FEATURE_11BE_MLO) && defined(CFG80211_11BE_BASIC) 14407 QDF_STATUS hdd_adapter_check_duplicate_session(struct hdd_adapter *adapter) 14408 { 14409 int i; 14410 QDF_STATUS status; 14411 uint8_t *addr_list[WLAN_MAX_MLD + 1] = {0}; 14412 struct hdd_adapter *link_adapter; 14413 struct hdd_mlo_adapter_info *mlo_adapter_info; 14414 mac_handle_t mac_handle = hdd_adapter_get_mac_handle(adapter); 14415 14416 if (hdd_adapter_is_ml_adapter(adapter) && 14417 adapter->device_mode == QDF_STA_MODE) { 14418 addr_list[0] = &adapter->mld_addr.bytes[0]; 14419 mlo_adapter_info = &adapter->mlo_adapter_info; 14420 for (i = 0; i < WLAN_MAX_MLD; i++) { 14421 link_adapter = mlo_adapter_info->link_adapter[i]; 14422 if (!link_adapter) 14423 continue; 14424 if (hdd_adapter_is_associated_with_ml_adapter( 14425 link_adapter)) { 14426 addr_list[1] = &link_adapter->mac_addr.bytes[0]; 14427 } 14428 } 14429 } else { 14430 addr_list[0] = &adapter->mac_addr.bytes[0]; 14431 } 14432 14433 status = sme_check_for_duplicate_session(mac_handle, &addr_list[0]); 14434 return status; 14435 } 14436 #else 14437 QDF_STATUS hdd_adapter_check_duplicate_session(struct hdd_adapter *adapter) 14438 { 14439 QDF_STATUS status; 14440 uint8_t *addr_list[2] = {0}; 14441 mac_handle_t mac_handle = hdd_adapter_get_mac_handle(adapter); 14442 14443 addr_list[0] = &adapter->mac_addr.bytes[0]; 14444 status = sme_check_for_duplicate_session(mac_handle, &addr_list[0]); 14445 14446 return status; 14447 } 14448 #endif 14449 14450 static void hdd_restore_info_for_ssr(struct hdd_adapter *adapter) 14451 { 14452 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); 14453 14454 if (cds_is_driver_recovering()) { 14455 /* ssr happens, recover the info */ 14456 hdd_set_vdev_phy_mode(adapter, adapter->user_phy_mode); 14457 wlan_mlme_restore_user_set_link_num(hdd_ctx->psoc); 14458 } else { 14459 /* intf down/up happens, reset default info */ 14460 hdd_set_vdev_phy_mode(adapter, QCA_WLAN_VENDOR_PHY_MODE_AUTO); 14461 wlan_mlme_clear_user_set_link_num(hdd_ctx->psoc); 14462 } 14463 } 14464 14465 void hdd_adapter_reset_station_ctx(struct hdd_adapter *adapter) 14466 { 14467 struct wlan_hdd_link_info *link_info; 14468 14469 hdd_adapter_for_each_link_info(adapter, link_info) 14470 hdd_cm_clear_ieee_link_id(link_info); 14471 } 14472 14473 int hdd_start_station_adapter(struct hdd_adapter *adapter) 14474 { 14475 QDF_STATUS status; 14476 int ret; 14477 struct wlan_hdd_link_info *link_info; 14478 14479 hdd_enter_dev(adapter->dev); 14480 if (test_bit(SME_SESSION_OPENED, &adapter->deflink->link_flags)) { 14481 hdd_err("session is already opened, %d", 14482 adapter->deflink->vdev_id); 14483 return qdf_status_to_os_return(QDF_STATUS_SUCCESS); 14484 } 14485 14486 if ((adapter->device_mode == QDF_P2P_DEVICE_MODE) || 14487 (adapter->device_mode == QDF_NAN_DISC_MODE)) 14488 wlan_hdd_lpc_del_monitor_interface(adapter->hdd_ctx); 14489 14490 status = hdd_adapter_fill_link_address(adapter); 14491 if (QDF_IS_STATUS_ERROR(status)) { 14492 hdd_debug("Link address derive failed"); 14493 return qdf_status_to_os_return(status); 14494 } 14495 14496 status = hdd_adapter_check_duplicate_session(adapter); 14497 if (QDF_IS_STATUS_ERROR(status)) { 14498 hdd_err("Duplicate session is existing with same mac address"); 14499 return qdf_status_to_os_return(status); 14500 } 14501 14502 hdd_adapter_for_each_active_link_info(adapter, link_info) { 14503 ret = hdd_vdev_create(link_info); 14504 if (ret) { 14505 hdd_err("failed to create vdev: %d", ret); 14506 goto fail; 14507 } 14508 14509 status = hdd_init_station_mode(link_info); 14510 if (QDF_STATUS_SUCCESS != status) { 14511 hdd_err("Error Initializing station mode: %d", status); 14512 ret = qdf_status_to_os_return(status); 14513 goto fail; 14514 } 14515 } 14516 14517 hdd_adapter_reset_station_ctx(adapter); 14518 14519 hdd_register_wext(adapter->dev); 14520 hdd_set_netdev_flags(adapter); 14521 14522 hdd_register_tx_flow_control(adapter, 14523 hdd_tx_resume_timer_expired_handler, 14524 hdd_tx_resume_cb, 14525 hdd_tx_flow_control_is_pause); 14526 14527 hdd_register_hl_netdev_fc_timer(adapter, 14528 hdd_tx_resume_timer_expired_handler); 14529 14530 if (hdd_get_multi_client_ll_support(adapter)) 14531 wlan_hdd_init_multi_client_info_table(adapter); 14532 14533 hdd_adapter_set_wlm_client_latency_level(adapter); 14534 hdd_adapter_update_mlo_mgr_mac_addr(adapter); 14535 hdd_restore_info_for_ssr(adapter); 14536 14537 hdd_exit(); 14538 return 0; 14539 14540 fail: 14541 hdd_adapter_for_each_active_link_info(adapter, link_info) 14542 hdd_vdev_destroy(link_info); 14543 14544 return ret; 14545 } 14546 14547 int hdd_start_ap_adapter(struct hdd_adapter *adapter, bool rtnl_held) 14548 { 14549 QDF_STATUS status; 14550 bool is_ssr = false; 14551 int ret; 14552 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); 14553 struct sap_context *sap_ctx; 14554 struct wlan_hdd_link_info *link_info = adapter->deflink; 14555 14556 hdd_enter(); 14557 14558 if (test_bit(SME_SESSION_OPENED, &link_info->link_flags)) { 14559 hdd_err("session is already opened, %d", 14560 link_info->vdev_id); 14561 return qdf_status_to_os_return(QDF_STATUS_SUCCESS); 14562 } 14563 14564 wlan_hdd_lpc_del_monitor_interface(hdd_ctx); 14565 14566 status = hdd_adapter_fill_link_address(adapter); 14567 if (QDF_IS_STATUS_ERROR(status)) { 14568 hdd_debug("Link address derive failed"); 14569 return qdf_status_to_os_return(status); 14570 } 14571 14572 status = hdd_adapter_check_duplicate_session(adapter); 14573 if (QDF_IS_STATUS_ERROR(status)) { 14574 hdd_err("Duplicate session is existing with same mac address"); 14575 return qdf_status_to_os_return(status); 14576 } 14577 14578 /* 14579 * In SSR case no need to create new sap context. 14580 * Otherwise create sap context first and then create 14581 * vdev as while creating the vdev, driver needs to 14582 * register SAP callback and that callback uses sap context 14583 */ 14584 if (WLAN_HDD_GET_SAP_CTX_PTR(link_info)) { 14585 is_ssr = true; 14586 } else if (!hdd_sap_create_ctx(adapter)) { 14587 hdd_err("sap creation failed"); 14588 return qdf_status_to_os_return(QDF_STATUS_E_FAILURE); 14589 } 14590 14591 ret = hdd_vdev_create(link_info); 14592 if (ret) { 14593 hdd_err("failed to create vdev, status:%d", ret); 14594 goto sap_destroy_ctx; 14595 } 14596 14597 sap_ctx = WLAN_HDD_GET_SAP_CTX_PTR(link_info); 14598 status = sap_acquire_vdev_ref(hdd_ctx->psoc, sap_ctx, 14599 link_info->vdev_id); 14600 if (!QDF_IS_STATUS_SUCCESS(status)) { 14601 hdd_err("Failed to get vdev ref for sap for session_id: %u", 14602 link_info->vdev_id); 14603 ret = qdf_status_to_os_return(status); 14604 goto sap_vdev_destroy; 14605 } 14606 14607 if (adapter->device_mode == QDF_SAP_MODE) { 14608 status = hdd_vdev_configure_rtt_params(sap_ctx->vdev); 14609 if (QDF_IS_STATUS_ERROR(status)) 14610 goto sap_release_ref; 14611 } 14612 14613 status = hdd_init_ap_mode(adapter, is_ssr, rtnl_held); 14614 if (QDF_STATUS_SUCCESS != status) { 14615 hdd_err("Error Initializing the AP mode: %d", status); 14616 ret = qdf_status_to_os_return(status); 14617 goto sap_release_ref; 14618 } 14619 14620 hdd_register_tx_flow_control(adapter, 14621 hdd_softap_tx_resume_timer_expired_handler, 14622 hdd_softap_tx_resume_cb, 14623 hdd_tx_flow_control_is_pause); 14624 14625 hdd_register_hl_netdev_fc_timer(adapter, 14626 hdd_tx_resume_timer_expired_handler); 14627 14628 if (cds_is_driver_recovering()) 14629 hdd_medium_assess_ssr_reinit(); 14630 14631 hdd_exit(); 14632 return 0; 14633 14634 sap_release_ref: 14635 sap_release_vdev_ref(sap_ctx); 14636 sap_vdev_destroy: 14637 hdd_vdev_destroy(link_info); 14638 sap_destroy_ctx: 14639 hdd_sap_destroy_ctx(link_info); 14640 return ret; 14641 } 14642 14643 #if defined(QCA_LL_TX_FLOW_CONTROL_V2) || defined(QCA_LL_PDEV_TX_FLOW_CONTROL) 14644 /** 14645 * hdd_txrx_populate_cds_config() - Populate txrx cds configuration 14646 * @cds_cfg: CDS Configuration 14647 * @hdd_ctx: Pointer to hdd context 14648 * 14649 * Return: none 14650 */ 14651 static inline void hdd_txrx_populate_cds_config(struct cds_config_info 14652 *cds_cfg, 14653 struct hdd_context *hdd_ctx) 14654 { 14655 cds_cfg->tx_flow_stop_queue_th = 14656 cfg_get(hdd_ctx->psoc, CFG_DP_TX_FLOW_STOP_QUEUE_TH); 14657 cds_cfg->tx_flow_start_queue_offset = 14658 cfg_get(hdd_ctx->psoc, CFG_DP_TX_FLOW_START_QUEUE_OFFSET); 14659 /* configuration for DP RX Threads */ 14660 cds_cfg->enable_dp_rx_threads = 14661 ucfg_dp_is_rx_threads_enabled(hdd_ctx->psoc); 14662 } 14663 #else 14664 static inline void hdd_txrx_populate_cds_config(struct cds_config_info 14665 *cds_cfg, 14666 struct hdd_context *hdd_ctx) 14667 { 14668 } 14669 #endif 14670 14671 /** 14672 * hdd_update_cds_config() - API to update cds configuration parameters 14673 * @hdd_ctx: HDD Context 14674 * 14675 * Return: 0 for Success, errno on failure 14676 */ 14677 static int hdd_update_cds_config(struct hdd_context *hdd_ctx) 14678 { 14679 struct cds_config_info *cds_cfg; 14680 int value; 14681 uint8_t band_capability; 14682 uint32_t band_bitmap; 14683 uint8_t ito_repeat_count; 14684 bool crash_inject; 14685 bool self_recovery; 14686 bool fw_timeout_crash; 14687 QDF_STATUS status; 14688 14689 cds_cfg = qdf_mem_malloc(sizeof(*cds_cfg)); 14690 if (!cds_cfg) 14691 return -ENOMEM; 14692 14693 cds_cfg->driver_type = QDF_DRIVER_TYPE_PRODUCTION; 14694 ucfg_mlme_get_sap_max_modulated_dtim(hdd_ctx->psoc, 14695 &cds_cfg->sta_maxlimod_dtim); 14696 14697 ucfg_mlme_get_max_modulated_dtim_ms(hdd_ctx->psoc, 14698 &cds_cfg->sta_maxlimod_dtim_ms); 14699 14700 status = ucfg_mlme_get_crash_inject(hdd_ctx->psoc, &crash_inject); 14701 if (QDF_IS_STATUS_ERROR(status)) { 14702 hdd_err("Failed to get crash inject ini config"); 14703 goto exit; 14704 } 14705 14706 status = ucfg_mlme_get_self_recovery(hdd_ctx->psoc, &self_recovery); 14707 if (QDF_IS_STATUS_ERROR(status)) { 14708 hdd_err("Failed to get self recovery ini config"); 14709 goto exit; 14710 } 14711 14712 status = ucfg_mlme_get_fw_timeout_crash(hdd_ctx->psoc, 14713 &fw_timeout_crash); 14714 if (QDF_IS_STATUS_ERROR(status)) { 14715 hdd_err("Failed to get fw timeout crash ini config"); 14716 goto exit; 14717 } 14718 14719 status = ucfg_mlme_get_ito_repeat_count(hdd_ctx->psoc, 14720 &ito_repeat_count); 14721 if (QDF_IS_STATUS_ERROR(status)) { 14722 hdd_err("Failed to get ITO repeat count ini config"); 14723 goto exit; 14724 } 14725 14726 cds_cfg->force_target_assert_enabled = crash_inject; 14727 14728 ucfg_mlme_get_sap_max_offload_peers(hdd_ctx->psoc, &value); 14729 cds_cfg->ap_maxoffload_peers = value; 14730 ucfg_mlme_get_sap_max_offload_reorder_buffs(hdd_ctx->psoc, 14731 &value); 14732 cds_cfg->ap_maxoffload_reorderbuffs = value; 14733 14734 cds_cfg->reorder_offload = DP_REORDER_OFFLOAD_SUPPORT; 14735 14736 /* IPA micro controller data path offload resource config item */ 14737 cds_cfg->uc_offload_enabled = ucfg_ipa_uc_is_enabled(); 14738 14739 cds_cfg->enable_rxthread = 14740 ucfg_dp_is_rx_common_thread_enabled(hdd_ctx->psoc); 14741 ucfg_mlme_get_sap_max_peers(hdd_ctx->psoc, &value); 14742 cds_cfg->max_station = value; 14743 cds_cfg->sub_20_channel_width = WLAN_SUB_20_CH_WIDTH_NONE; 14744 cds_cfg->max_msdus_per_rxinorderind = 14745 cfg_get(hdd_ctx->psoc, CFG_DP_MAX_MSDUS_PER_RXIND); 14746 cds_cfg->self_recovery_enabled = self_recovery; 14747 cds_cfg->fw_timeout_crash = fw_timeout_crash; 14748 14749 cds_cfg->ito_repeat_count = ito_repeat_count; 14750 14751 status = ucfg_mlme_get_band_capability(hdd_ctx->psoc, &band_bitmap); 14752 if (QDF_IS_STATUS_ERROR(status)) 14753 goto exit; 14754 14755 band_capability = wlan_reg_band_bitmap_to_band_info(band_bitmap); 14756 cds_cfg->bandcapability = band_capability; 14757 cds_cfg->num_vdevs = hdd_ctx->config->num_vdevs; 14758 cds_cfg->enable_tx_compl_tsf64 = 14759 hdd_tsf_is_tsf64_tx_set(hdd_ctx); 14760 hdd_txrx_populate_cds_config(cds_cfg, hdd_ctx); 14761 hdd_lpass_populate_cds_config(cds_cfg, hdd_ctx); 14762 cds_init_ini_config(cds_cfg); 14763 return 0; 14764 14765 exit: 14766 qdf_mem_free(cds_cfg); 14767 return -EINVAL; 14768 } 14769 14770 /** 14771 * hdd_update_user_config() - API to update user configuration 14772 * parameters to obj mgr which are used by multiple components 14773 * @hdd_ctx: HDD Context 14774 * 14775 * Return: 0 for Success, errno on failure 14776 */ 14777 static int hdd_update_user_config(struct hdd_context *hdd_ctx) 14778 { 14779 struct wlan_objmgr_psoc_user_config *user_config; 14780 uint8_t band_capability; 14781 uint32_t band_bitmap; 14782 QDF_STATUS status; 14783 bool value = false; 14784 14785 status = ucfg_mlme_get_band_capability(hdd_ctx->psoc, &band_bitmap); 14786 if (QDF_IS_STATUS_ERROR(status)) 14787 return -EIO; 14788 14789 user_config = qdf_mem_malloc(sizeof(*user_config)); 14790 if (!user_config) 14791 return -ENOMEM; 14792 14793 user_config->dot11_mode = hdd_ctx->config->dot11Mode; 14794 status = ucfg_mlme_is_11d_enabled(hdd_ctx->psoc, &value); 14795 if (!QDF_IS_STATUS_SUCCESS(status)) 14796 hdd_err("Invalid 11d_enable flag"); 14797 user_config->is_11d_support_enabled = value; 14798 14799 value = false; 14800 status = ucfg_mlme_is_11h_enabled(hdd_ctx->psoc, &value); 14801 if (!QDF_IS_STATUS_SUCCESS(status)) 14802 hdd_err("Invalid 11h_enable flag"); 14803 user_config->is_11h_support_enabled = value; 14804 band_capability = wlan_reg_band_bitmap_to_band_info(band_bitmap); 14805 user_config->band_capability = band_capability; 14806 wlan_objmgr_psoc_set_user_config(hdd_ctx->psoc, user_config); 14807 14808 qdf_mem_free(user_config); 14809 return 0; 14810 } 14811 14812 /** 14813 * hdd_init_thermal_info - Initialize thermal level 14814 * @hdd_ctx: HDD context 14815 * 14816 * Initialize thermal level at SME layer and set the thermal level callback 14817 * which would be called when a configured thermal threshold is hit. 14818 * 14819 * Return: 0 on success and errno on failure 14820 */ 14821 static int hdd_init_thermal_info(struct hdd_context *hdd_ctx) 14822 { 14823 QDF_STATUS status; 14824 mac_handle_t mac_handle = hdd_ctx->mac_handle; 14825 14826 status = sme_init_thermal_info(mac_handle); 14827 14828 if (!QDF_IS_STATUS_SUCCESS(status)) 14829 return qdf_status_to_os_return(status); 14830 14831 sme_add_set_thermal_level_callback(mac_handle, 14832 hdd_set_thermal_level_cb); 14833 14834 return 0; 14835 14836 } 14837 14838 #if defined(CONFIG_HDD_INIT_WITH_RTNL_LOCK) 14839 /** 14840 * hdd_hold_rtnl_lock - Hold RTNL lock 14841 * 14842 * Hold RTNL lock 14843 * 14844 * Return: True if held and false otherwise 14845 */ 14846 static inline bool hdd_hold_rtnl_lock(void) 14847 { 14848 rtnl_lock(); 14849 return true; 14850 } 14851 14852 /** 14853 * hdd_release_rtnl_lock - Release RTNL lock 14854 * 14855 * Release RTNL lock 14856 * 14857 * Return: None 14858 */ 14859 static inline void hdd_release_rtnl_lock(void) 14860 { 14861 rtnl_unlock(); 14862 } 14863 #else 14864 static inline bool hdd_hold_rtnl_lock(void) { return false; } 14865 static inline void hdd_release_rtnl_lock(void) { } 14866 #endif 14867 14868 #if !defined(REMOVE_PKT_LOG) 14869 14870 /* MAX iwpriv command support */ 14871 #define PKTLOG_SET_BUFF_SIZE 3 14872 #define PKTLOG_CLEAR_BUFF 4 14873 /* Set Maximum pktlog file size to 64MB */ 14874 #define MAX_PKTLOG_SIZE 64 14875 14876 /** 14877 * hdd_pktlog_set_buff_size() - set pktlog buffer size 14878 * @hdd_ctx: hdd context 14879 * @set_value2: pktlog buffer size value 14880 * 14881 * 14882 * Return: 0 for success or error. 14883 */ 14884 static int hdd_pktlog_set_buff_size(struct hdd_context *hdd_ctx, int set_value2) 14885 { 14886 struct sir_wifi_start_log start_log = { 0 }; 14887 QDF_STATUS status; 14888 14889 start_log.ring_id = RING_ID_PER_PACKET_STATS; 14890 start_log.verbose_level = WLAN_LOG_LEVEL_OFF; 14891 start_log.ini_triggered = cds_is_packet_log_enabled(); 14892 start_log.user_triggered = 1; 14893 start_log.size = set_value2; 14894 start_log.is_pktlog_buff_clear = false; 14895 14896 status = sme_wifi_start_logger(hdd_ctx->mac_handle, start_log); 14897 if (!QDF_IS_STATUS_SUCCESS(status)) { 14898 hdd_err("sme_wifi_start_logger failed(err=%d)", status); 14899 hdd_exit(); 14900 return -EINVAL; 14901 } 14902 14903 return 0; 14904 } 14905 14906 /** 14907 * hdd_pktlog_clear_buff() - clear pktlog buffer 14908 * @hdd_ctx: hdd context 14909 * 14910 * Return: 0 for success or error. 14911 */ 14912 static int hdd_pktlog_clear_buff(struct hdd_context *hdd_ctx) 14913 { 14914 struct sir_wifi_start_log start_log; 14915 QDF_STATUS status; 14916 14917 start_log.ring_id = RING_ID_PER_PACKET_STATS; 14918 start_log.verbose_level = WLAN_LOG_LEVEL_OFF; 14919 start_log.ini_triggered = cds_is_packet_log_enabled(); 14920 start_log.user_triggered = 1; 14921 start_log.size = 0; 14922 start_log.is_pktlog_buff_clear = true; 14923 14924 status = sme_wifi_start_logger(hdd_ctx->mac_handle, start_log); 14925 if (!QDF_IS_STATUS_SUCCESS(status)) { 14926 hdd_err("sme_wifi_start_logger failed(err=%d)", status); 14927 hdd_exit(); 14928 return -EINVAL; 14929 } 14930 14931 return 0; 14932 } 14933 14934 14935 /** 14936 * hdd_process_pktlog_command() - process pktlog command 14937 * @hdd_ctx: hdd context 14938 * @set_value: value set by user 14939 * @set_value2: pktlog buffer size value 14940 * 14941 * This function process pktlog command. 14942 * set_value2 only matters when set_value is 3 (set buff size) 14943 * otherwise we ignore it. 14944 * 14945 * Return: 0 for success or error. 14946 */ 14947 int hdd_process_pktlog_command(struct hdd_context *hdd_ctx, uint32_t set_value, 14948 int set_value2) 14949 { 14950 int ret; 14951 bool enable; 14952 uint8_t user_triggered = 0; 14953 14954 ret = wlan_hdd_validate_context(hdd_ctx); 14955 if (0 != ret) 14956 return ret; 14957 14958 hdd_debug("set pktlog %d, set size %d", set_value, set_value2); 14959 14960 if (set_value > PKTLOG_CLEAR_BUFF) { 14961 hdd_err("invalid pktlog value %d", set_value); 14962 return -EINVAL; 14963 } 14964 14965 if (set_value == PKTLOG_SET_BUFF_SIZE) { 14966 if (set_value2 <= 0) { 14967 hdd_err("invalid pktlog size %d", set_value2); 14968 return -EINVAL; 14969 } else if (set_value2 > MAX_PKTLOG_SIZE) { 14970 hdd_err_rl("Pktlog size is large. max value is %uMB.", 14971 MAX_PKTLOG_SIZE); 14972 return -EINVAL; 14973 } 14974 return hdd_pktlog_set_buff_size(hdd_ctx, set_value2); 14975 } else if (set_value == PKTLOG_CLEAR_BUFF) { 14976 return hdd_pktlog_clear_buff(hdd_ctx); 14977 } 14978 14979 /* 14980 * set_value = 0 then disable packetlog 14981 * set_value = 1 enable packetlog forcefully 14982 * set_value = 2 then disable packetlog if disabled through ini or 14983 * enable packetlog with AUTO type. 14984 */ 14985 enable = ((set_value > 0) && cds_is_packet_log_enabled()) ? 14986 true : false; 14987 14988 if (1 == set_value) { 14989 enable = true; 14990 user_triggered = 1; 14991 } 14992 14993 return hdd_pktlog_enable_disable(hdd_ctx, enable, user_triggered, 0); 14994 } 14995 14996 /** 14997 * hdd_pktlog_enable_disable() - Enable/Disable packet logging 14998 * @hdd_ctx: HDD context 14999 * @enable_disable_flag: Flag to enable/disable 15000 * @user_triggered: triggered through iwpriv 15001 * @size: buffer size to be used for packetlog 15002 * 15003 * Return: 0 on success; error number otherwise 15004 */ 15005 int hdd_pktlog_enable_disable(struct hdd_context *hdd_ctx, 15006 bool enable_disable_flag, 15007 uint8_t user_triggered, int size) 15008 { 15009 struct sir_wifi_start_log start_log; 15010 QDF_STATUS status; 15011 15012 if (hdd_ctx->is_pktlog_enabled && enable_disable_flag) 15013 return 0; 15014 15015 if ((!hdd_ctx->is_pktlog_enabled) && (!enable_disable_flag)) 15016 return 0; 15017 15018 start_log.ring_id = RING_ID_PER_PACKET_STATS; 15019 start_log.verbose_level = 15020 enable_disable_flag ? 15021 WLAN_LOG_LEVEL_ACTIVE : WLAN_LOG_LEVEL_OFF; 15022 start_log.ini_triggered = cds_is_packet_log_enabled(); 15023 start_log.user_triggered = user_triggered; 15024 start_log.size = size; 15025 start_log.is_pktlog_buff_clear = false; 15026 /* 15027 * Use "is_iwpriv_command" flag to distinguish iwpriv command from other 15028 * commands. Host uses this flag to decide whether to send pktlog 15029 * disable command to fw without sending pktlog enable command 15030 * previously. For eg, If vendor sends pktlog disable command without 15031 * sending pktlog enable command, then host discards the packet 15032 * but for iwpriv command, host will send it to fw. 15033 */ 15034 start_log.is_iwpriv_command = 1; 15035 15036 status = sme_wifi_start_logger(hdd_ctx->mac_handle, start_log); 15037 if (!QDF_IS_STATUS_SUCCESS(status)) { 15038 hdd_err("sme_wifi_start_logger failed(err=%d)", status); 15039 hdd_exit(); 15040 return -EINVAL; 15041 } 15042 15043 hdd_ctx->is_pktlog_enabled = enable_disable_flag; 15044 15045 return 0; 15046 } 15047 #endif /* REMOVE_PKT_LOG */ 15048 15049 void hdd_free_mac_address_lists(struct hdd_context *hdd_ctx) 15050 { 15051 hdd_debug("Resetting MAC address lists"); 15052 qdf_mem_zero(hdd_ctx->provisioned_mac_addr, 15053 sizeof(hdd_ctx->provisioned_mac_addr)); 15054 qdf_mem_zero(hdd_ctx->derived_mac_addr, 15055 sizeof(hdd_ctx->derived_mac_addr)); 15056 hdd_ctx->num_provisioned_addr = 0; 15057 hdd_ctx->num_derived_addr = 0; 15058 hdd_ctx->provisioned_intf_addr_mask = 0; 15059 hdd_ctx->derived_intf_addr_mask = 0; 15060 } 15061 15062 /** 15063 * hdd_get_platform_wlan_mac_buff() - API to query platform driver 15064 * for MAC address 15065 * @dev: Device Pointer 15066 * @num: Number of Valid Mac address 15067 * 15068 * Return: Pointer to MAC address buffer 15069 */ 15070 static uint8_t *hdd_get_platform_wlan_mac_buff(struct device *dev, 15071 uint32_t *num) 15072 { 15073 return pld_get_wlan_mac_address(dev, num); 15074 } 15075 15076 /** 15077 * hdd_get_platform_wlan_derived_mac_buff() - API to query platform driver 15078 * for derived MAC address 15079 * @dev: Device Pointer 15080 * @num: Number of Valid Mac address 15081 * 15082 * Return: Pointer to MAC address buffer 15083 */ 15084 static uint8_t *hdd_get_platform_wlan_derived_mac_buff(struct device *dev, 15085 uint32_t *num) 15086 { 15087 return pld_get_wlan_derived_mac_address(dev, num); 15088 } 15089 15090 /** 15091 * hdd_populate_random_mac_addr() - API to populate random mac addresses 15092 * @hdd_ctx: HDD Context 15093 * @num: Number of random mac addresses needed 15094 * 15095 * Generate random addresses using bit manipulation on the base mac address 15096 * 15097 * Return: None 15098 */ 15099 void hdd_populate_random_mac_addr(struct hdd_context *hdd_ctx, uint32_t num) 15100 { 15101 uint32_t idx = hdd_ctx->num_derived_addr; 15102 uint32_t iter; 15103 uint8_t *buf = NULL; 15104 uint8_t macaddr_b3, tmp_br3; 15105 /* 15106 * Consider first provisioned mac address as source address to derive 15107 * remaining addresses 15108 */ 15109 15110 uint8_t *src = hdd_ctx->provisioned_mac_addr[0].bytes; 15111 15112 for (iter = 0; iter < num; ++iter, ++idx) { 15113 buf = hdd_ctx->derived_mac_addr[idx].bytes; 15114 qdf_mem_copy(buf, src, QDF_MAC_ADDR_SIZE); 15115 macaddr_b3 = buf[3]; 15116 tmp_br3 = ((macaddr_b3 >> 4 & INTF_MACADDR_MASK) + idx) & 15117 INTF_MACADDR_MASK; 15118 macaddr_b3 += tmp_br3; 15119 macaddr_b3 ^= (1 << INTF_MACADDR_MASK); 15120 buf[0] |= 0x02; 15121 buf[3] = macaddr_b3; 15122 hdd_debug(QDF_MAC_ADDR_FMT, QDF_MAC_ADDR_REF(buf)); 15123 hdd_ctx->num_derived_addr++; 15124 } 15125 } 15126 15127 /** 15128 * hdd_platform_wlan_mac() - API to get mac addresses from platform driver 15129 * @hdd_ctx: HDD Context 15130 * 15131 * API to get mac addresses from platform driver and update the driver 15132 * structures and configure FW with the base mac address. 15133 * Return: int 15134 */ 15135 static int hdd_platform_wlan_mac(struct hdd_context *hdd_ctx) 15136 { 15137 uint32_t no_of_mac_addr, iter; 15138 uint32_t max_mac_addr = QDF_MAX_CONCURRENCY_PERSONA; 15139 uint32_t mac_addr_size = QDF_MAC_ADDR_SIZE; 15140 uint8_t *addr, *buf; 15141 struct device *dev = hdd_ctx->parent_dev; 15142 tSirMacAddr mac_addr; 15143 QDF_STATUS status; 15144 15145 addr = hdd_get_platform_wlan_mac_buff(dev, &no_of_mac_addr); 15146 15147 if (no_of_mac_addr == 0 || !addr) { 15148 hdd_debug("No mac configured from platform driver"); 15149 return -EINVAL; 15150 } 15151 15152 hdd_free_mac_address_lists(hdd_ctx); 15153 15154 if (no_of_mac_addr > max_mac_addr) 15155 no_of_mac_addr = max_mac_addr; 15156 15157 qdf_mem_copy(&mac_addr, addr, mac_addr_size); 15158 15159 for (iter = 0; iter < no_of_mac_addr; ++iter, addr += mac_addr_size) { 15160 buf = hdd_ctx->provisioned_mac_addr[iter].bytes; 15161 qdf_mem_copy(buf, addr, QDF_MAC_ADDR_SIZE); 15162 hdd_info("provisioned MAC Addr [%d] "QDF_MAC_ADDR_FMT, iter, 15163 QDF_MAC_ADDR_REF(buf)); 15164 } 15165 15166 hdd_ctx->num_provisioned_addr = no_of_mac_addr; 15167 15168 if (hdd_ctx->config->mac_provision) { 15169 addr = hdd_get_platform_wlan_derived_mac_buff(dev, 15170 &no_of_mac_addr); 15171 15172 if (no_of_mac_addr == 0 || !addr) 15173 hdd_warn("No derived address from platform driver"); 15174 else if (no_of_mac_addr > 15175 (max_mac_addr - hdd_ctx->num_provisioned_addr)) 15176 no_of_mac_addr = (max_mac_addr - 15177 hdd_ctx->num_provisioned_addr); 15178 15179 for (iter = 0; iter < no_of_mac_addr; ++iter, 15180 addr += mac_addr_size) { 15181 buf = hdd_ctx->derived_mac_addr[iter].bytes; 15182 qdf_mem_copy(buf, addr, QDF_MAC_ADDR_SIZE); 15183 hdd_debug("derived MAC Addr [%d] "QDF_MAC_ADDR_FMT, iter, 15184 QDF_MAC_ADDR_REF(buf)); 15185 } 15186 hdd_ctx->num_derived_addr = no_of_mac_addr; 15187 } 15188 15189 no_of_mac_addr = hdd_ctx->num_provisioned_addr + 15190 hdd_ctx->num_derived_addr; 15191 if (no_of_mac_addr < max_mac_addr) 15192 hdd_populate_random_mac_addr(hdd_ctx, max_mac_addr - 15193 no_of_mac_addr); 15194 15195 status = sme_set_custom_mac_addr(mac_addr); 15196 if (!QDF_IS_STATUS_SUCCESS(status)) 15197 return -EAGAIN; 15198 15199 return 0; 15200 } 15201 15202 /** 15203 * hdd_update_mac_addr_to_fw() - API to update wlan mac addresses to FW 15204 * @hdd_ctx: HDD Context 15205 * 15206 * Update MAC address to FW. If MAC address passed by FW is invalid, host 15207 * will generate its own MAC and update it to FW. 15208 * 15209 * Return: 0 for success 15210 * Non-zero error code for failure 15211 */ 15212 static int hdd_update_mac_addr_to_fw(struct hdd_context *hdd_ctx) 15213 { 15214 tSirMacAddr custom_mac_addr; 15215 QDF_STATUS status; 15216 15217 if (hdd_ctx->num_provisioned_addr) 15218 qdf_mem_copy(&custom_mac_addr, 15219 &hdd_ctx->provisioned_mac_addr[0].bytes[0], 15220 sizeof(tSirMacAddr)); 15221 else 15222 qdf_mem_copy(&custom_mac_addr, 15223 &hdd_ctx->derived_mac_addr[0].bytes[0], 15224 sizeof(tSirMacAddr)); 15225 status = sme_set_custom_mac_addr(custom_mac_addr); 15226 if (!QDF_IS_STATUS_SUCCESS(status)) 15227 return -EAGAIN; 15228 return 0; 15229 } 15230 15231 /** 15232 * hdd_initialize_mac_address() - API to get wlan mac addresses 15233 * @hdd_ctx: HDD Context 15234 * 15235 * Get MAC addresses from platform driver or wlan_mac.bin. If platform driver 15236 * is provisioned with mac addresses, driver uses it, else it will use 15237 * wlan_mac.bin to update HW MAC addresses. 15238 * 15239 * Return: None 15240 */ 15241 static int hdd_initialize_mac_address(struct hdd_context *hdd_ctx) 15242 { 15243 QDF_STATUS status; 15244 int ret; 15245 15246 ret = hdd_platform_wlan_mac(hdd_ctx); 15247 if (!ret) { 15248 hdd_info("using MAC address from platform driver"); 15249 return ret; 15250 } else if (hdd_ctx->config->mac_provision) { 15251 hdd_err("getting MAC address from platform driver failed"); 15252 return ret; 15253 } 15254 15255 status = hdd_update_mac_config(hdd_ctx); 15256 if (QDF_IS_STATUS_SUCCESS(status)) { 15257 hdd_info("using MAC address from wlan_mac.bin"); 15258 return 0; 15259 } 15260 15261 hdd_info("using default MAC address"); 15262 15263 /* Use fw provided MAC */ 15264 if (!qdf_is_macaddr_zero(&hdd_ctx->hw_macaddr)) { 15265 hdd_update_macaddr(hdd_ctx, hdd_ctx->hw_macaddr, false); 15266 return 0; 15267 } else if (hdd_generate_macaddr_auto(hdd_ctx) != 0) { 15268 struct qdf_mac_addr mac_addr; 15269 15270 hdd_err("MAC failure from device serial no."); 15271 qdf_get_random_bytes(&mac_addr, sizeof(mac_addr)); 15272 /* 15273 * Reset multicast bit (bit-0) and set 15274 * locally-administered bit 15275 */ 15276 mac_addr.bytes[0] = 0x2; 15277 hdd_update_macaddr(hdd_ctx, mac_addr, true); 15278 } 15279 15280 ret = hdd_update_mac_addr_to_fw(hdd_ctx); 15281 if (ret) 15282 hdd_err("MAC address out-of-sync, ret:%d", ret); 15283 return ret; 15284 } 15285 15286 /* params being sent: 15287 * wmi_pdev_param_tx_chain_mask_1ss 15288 * wmi_pdev_param_mgmt_retry_limit 15289 * wmi_pdev_param_default_6ghz_rate 15290 * wmi_pdev_param_pdev_stats_tx_xretry_ext 15291 * wmi_pdev_param_smart_chainmask_scheme 15292 * wmi_pdev_param_alternative_chainmask_scheme 15293 * wmi_pdev_param_ani_enable 15294 * wmi_pdev_param_pcie_config 15295 */ 15296 /** 15297 * hdd_pre_enable_configure() - Configurations prior to cds_enable 15298 * @hdd_ctx: HDD context 15299 * 15300 * Pre configurations to be done at lower layer before calling cds enable. 15301 * 15302 * Return: 0 on success and errno on failure. 15303 */ 15304 static int hdd_pre_enable_configure(struct hdd_context *hdd_ctx) 15305 { 15306 int ret; 15307 uint8_t val = 0; 15308 uint8_t max_retry = 0; 15309 bool enable_he_mcs0_for_6ghz_mgmt = false; 15310 uint32_t tx_retry_multiplier; 15311 QDF_STATUS status; 15312 void *soc = cds_get_context(QDF_MODULE_ID_SOC); 15313 struct dev_set_param setparam[MAX_PDEV_PRE_ENABLE_PARAMS] = {}; 15314 bool check_value; 15315 uint8_t index = 0; 15316 15317 cdp_register_pause_cb(soc, wlan_hdd_txrx_pause_cb); 15318 /* Register HL netdev flow control callback */ 15319 cdp_hl_fc_register(soc, OL_TXRX_PDEV_ID, wlan_hdd_txrx_pause_cb); 15320 /* Register rx mic error indication handler */ 15321 ucfg_dp_register_rx_mic_error_ind_handler(soc); 15322 15323 /* 15324 * Note that the cds_pre_enable() sequence triggers the cfg download. 15325 * The cfg download must occur before we update the SME config 15326 * since the SME config operation must access the cfg database 15327 */ 15328 status = hdd_set_sme_config(hdd_ctx); 15329 15330 if (QDF_STATUS_SUCCESS != status) { 15331 hdd_err("Failed hdd_set_sme_config: %d", status); 15332 ret = qdf_status_to_os_return(status); 15333 goto out; 15334 } 15335 15336 status = hdd_set_policy_mgr_user_cfg(hdd_ctx); 15337 if (QDF_STATUS_SUCCESS != status) { 15338 hdd_alert("Failed hdd_set_policy_mgr_user_cfg: %d", status); 15339 ret = qdf_status_to_os_return(status); 15340 goto out; 15341 } 15342 15343 status = ucfg_mlme_get_tx_chainmask_1ss(hdd_ctx->psoc, &val); 15344 if (QDF_STATUS_SUCCESS != status) { 15345 hdd_err("Get tx_chainmask_1ss from mlme failed"); 15346 ret = qdf_status_to_os_return(status); 15347 goto out; 15348 } 15349 ret = mlme_check_index_setparam(setparam, 15350 wmi_pdev_param_tx_chain_mask_1ss, 15351 val, index++, 15352 MAX_PDEV_PRE_ENABLE_PARAMS); 15353 if (QDF_IS_STATUS_ERROR(ret)) { 15354 hdd_err("failed at wmi_pdev_param_tx_chain_mask_1ss"); 15355 goto out; 15356 15357 } 15358 15359 wlan_mlme_get_mgmt_max_retry(hdd_ctx->psoc, &max_retry); 15360 ret = mlme_check_index_setparam(setparam, 15361 wmi_pdev_param_mgmt_retry_limit, 15362 max_retry, index++, 15363 MAX_PDEV_PRE_ENABLE_PARAMS); 15364 if (QDF_IS_STATUS_ERROR(ret)) { 15365 hdd_err("failed at wmi_pdev_param_mgmt_retry_limit"); 15366 goto out; 15367 } 15368 15369 wlan_mlme_get_mgmt_6ghz_rate_support(hdd_ctx->psoc, 15370 &enable_he_mcs0_for_6ghz_mgmt); 15371 if (enable_he_mcs0_for_6ghz_mgmt) { 15372 hdd_debug("HE rates for 6GHz mgmt frames are supported"); 15373 ret = mlme_check_index_setparam( 15374 setparam, 15375 wmi_pdev_param_default_6ghz_rate, 15376 MGMT_DEFAULT_DATA_RATE_6GHZ, index++, 15377 MAX_PDEV_PRE_ENABLE_PARAMS); 15378 if (QDF_IS_STATUS_ERROR(ret)) { 15379 hdd_err("wmi_pdev_param_default_6ghz_rate failed %d", 15380 ret); 15381 goto out; 15382 } 15383 } 15384 15385 wlan_mlme_get_tx_retry_multiplier(hdd_ctx->psoc, 15386 &tx_retry_multiplier); 15387 ret = mlme_check_index_setparam(setparam, 15388 wmi_pdev_param_pdev_stats_tx_xretry_ext, 15389 tx_retry_multiplier, index++, 15390 MAX_PDEV_PRE_ENABLE_PARAMS); 15391 if (QDF_IS_STATUS_ERROR(ret)) { 15392 hdd_err("failed at wmi_pdev_param_pdev_stats_tx_xretry_ext"); 15393 goto out; 15394 } 15395 15396 ret = ucfg_get_smart_chainmask_enabled(hdd_ctx->psoc, 15397 &check_value); 15398 if (QDF_IS_STATUS_SUCCESS(ret)) { 15399 ret = mlme_check_index_setparam( 15400 setparam, 15401 wmi_pdev_param_smart_chainmask_scheme, 15402 (int)check_value, index++, 15403 MAX_PDEV_PRE_ENABLE_PARAMS); 15404 if (QDF_IS_STATUS_ERROR(ret)) { 15405 hdd_err("failed to set wmi_pdev_param_smart_chainmask_scheme"); 15406 goto out; 15407 } 15408 } 15409 15410 ret = ucfg_get_alternative_chainmask_enabled(hdd_ctx->psoc, 15411 &check_value); 15412 if (QDF_IS_STATUS_SUCCESS(ret)) { 15413 ret = mlme_check_index_setparam( 15414 setparam, 15415 wmi_pdev_param_alternative_chainmask_scheme, 15416 (int)check_value, index++, 15417 MAX_PDEV_PRE_ENABLE_PARAMS); 15418 if (QDF_IS_STATUS_ERROR(ret)) { 15419 hdd_err("failed to set wmi_pdev_param_alternative_chainmask_scheme"); 15420 goto out; 15421 } 15422 } 15423 15424 ret = ucfg_fwol_get_ani_enabled(hdd_ctx->psoc, &check_value); 15425 if (QDF_IS_STATUS_SUCCESS(ret)) { 15426 ret = mlme_check_index_setparam(setparam, 15427 wmi_pdev_param_ani_enable, 15428 (int)check_value, index++, 15429 MAX_PDEV_PRE_ENABLE_PARAMS); 15430 if (QDF_IS_STATUS_ERROR(ret)) { 15431 hdd_err("failed to set wmi_pdev_param_ani_enable"); 15432 goto out; 15433 } 15434 } 15435 15436 ret = hdd_set_pcie_params(hdd_ctx, index, setparam); 15437 if (QDF_IS_STATUS_ERROR(ret)) 15438 goto out; 15439 else 15440 index++; 15441 ret = sme_send_multi_pdev_vdev_set_params(MLME_PDEV_SETPARAM, 15442 WMI_PDEV_ID_SOC, setparam, 15443 index); 15444 if (QDF_IS_STATUS_ERROR(ret)) { 15445 hdd_err("failed to send pdev set params"); 15446 goto out; 15447 } 15448 15449 /* Configure global firmware params */ 15450 ret = ucfg_fwol_configure_global_params(hdd_ctx->psoc, hdd_ctx->pdev); 15451 if (ret) 15452 goto out; 15453 15454 status = hdd_set_sme_chan_list(hdd_ctx); 15455 if (status != QDF_STATUS_SUCCESS) { 15456 hdd_err("Failed to init channel list: %d", status); 15457 ret = qdf_status_to_os_return(status); 15458 goto out; 15459 } 15460 15461 if (!hdd_update_config_cfg(hdd_ctx)) { 15462 hdd_err("config update failed"); 15463 ret = -EINVAL; 15464 goto out; 15465 } 15466 hdd_init_channel_avoidance(hdd_ctx); 15467 15468 out: 15469 return ret; 15470 } 15471 15472 #ifdef FEATURE_P2P_LISTEN_OFFLOAD 15473 /** 15474 * wlan_hdd_p2p_lo_event_callback - P2P listen offload stop event handler 15475 * @context: context registered with sme_register_p2p_lo_event(). HDD 15476 * always registers a hdd context pointer 15477 * @evt:event structure pointer 15478 * 15479 * This is the p2p listen offload stop event handler, it sends vendor 15480 * event back to supplicant to notify the stop reason. 15481 * 15482 * Return: None 15483 */ 15484 static void wlan_hdd_p2p_lo_event_callback(void *context, 15485 struct sir_p2p_lo_event *evt) 15486 { 15487 struct hdd_context *hdd_ctx = context; 15488 struct sk_buff *vendor_event; 15489 enum qca_nl80211_vendor_subcmds_index index = 15490 QCA_NL80211_VENDOR_SUBCMD_P2P_LO_EVENT_INDEX; 15491 struct wlan_hdd_link_info *link_info; 15492 15493 hdd_enter(); 15494 15495 if (!hdd_ctx) { 15496 hdd_err("Invalid HDD context pointer"); 15497 return; 15498 } 15499 15500 link_info = hdd_get_link_info_by_vdev(hdd_ctx, evt->vdev_id); 15501 if (!link_info) { 15502 hdd_err("Cannot find adapter by vdev_id = %d", 15503 evt->vdev_id); 15504 return; 15505 } 15506 15507 vendor_event = 15508 wlan_cfg80211_vendor_event_alloc(hdd_ctx->wiphy, 15509 &link_info->adapter->wdev, 15510 sizeof(uint32_t) + 15511 NLMSG_HDRLEN, 15512 index, GFP_KERNEL); 15513 if (!vendor_event) { 15514 hdd_err("wlan_cfg80211_vendor_event_alloc failed"); 15515 return; 15516 } 15517 15518 if (nla_put_u32(vendor_event, 15519 QCA_WLAN_VENDOR_ATTR_P2P_LISTEN_OFFLOAD_STOP_REASON, 15520 evt->reason_code)) { 15521 hdd_err("nla put failed"); 15522 wlan_cfg80211_vendor_free_skb(vendor_event); 15523 return; 15524 } 15525 15526 wlan_cfg80211_vendor_event(vendor_event, GFP_KERNEL); 15527 hdd_debug("Sent P2P_LISTEN_OFFLOAD_STOP event for vdev_id = %d", 15528 evt->vdev_id); 15529 } 15530 #else 15531 static void wlan_hdd_p2p_lo_event_callback(void *context, 15532 struct sir_p2p_lo_event *evt) 15533 { 15534 } 15535 #endif 15536 15537 #ifdef FEATURE_WLAN_DYNAMIC_CVM 15538 static inline int hdd_set_vc_mode_config(struct hdd_context *hdd_ctx) 15539 { 15540 return sme_set_vc_mode_config(hdd_ctx->config->vc_mode_cfg_bitmap); 15541 } 15542 #else 15543 static inline int hdd_set_vc_mode_config(struct hdd_context *hdd_ctx) 15544 { 15545 return QDF_STATUS_SUCCESS; 15546 } 15547 #endif 15548 15549 /** 15550 * hdd_adaptive_dwelltime_init() - initialization for adaptive dwell time config 15551 * @hdd_ctx: HDD context 15552 * 15553 * This function sends the adaptive dwell time config configuration to the 15554 * firmware via WMA 15555 * 15556 * Return: 0 - success, < 0 - failure 15557 */ 15558 static int hdd_adaptive_dwelltime_init(struct hdd_context *hdd_ctx) 15559 { 15560 QDF_STATUS status; 15561 struct adaptive_dwelltime_params dwelltime_params; 15562 15563 status = ucfg_fwol_get_all_adaptive_dwelltime_params(hdd_ctx->psoc, 15564 &dwelltime_params); 15565 status = ucfg_fwol_set_adaptive_dwelltime_config(&dwelltime_params); 15566 15567 hdd_debug("Sending Adaptive Dwelltime Configuration to fw"); 15568 if (!QDF_IS_STATUS_SUCCESS(status)) { 15569 hdd_err("Failed to send Adaptive Dwelltime configuration!"); 15570 return -EAGAIN; 15571 } 15572 return 0; 15573 } 15574 15575 int hdd_dbs_scan_selection_init(struct hdd_context *hdd_ctx) 15576 { 15577 QDF_STATUS status; 15578 struct wmi_dbs_scan_sel_params dbs_scan_params; 15579 uint32_t i = 0; 15580 uint8_t count = 0, numentries = 0; 15581 uint8_t dual_mac_feature; 15582 uint8_t dbs_scan_config[CDS_DBS_SCAN_PARAM_PER_CLIENT 15583 * CDS_DBS_SCAN_CLIENTS_MAX]; 15584 15585 status = ucfg_policy_mgr_get_dual_mac_feature(hdd_ctx->psoc, 15586 &dual_mac_feature); 15587 15588 if (status != QDF_STATUS_SUCCESS) { 15589 hdd_err("can't get dual mac feature flag"); 15590 return -EINVAL; 15591 } 15592 /* check if DBS is enabled or supported */ 15593 if ((dual_mac_feature == DISABLE_DBS_CXN_AND_SCAN) || 15594 (dual_mac_feature == ENABLE_DBS_CXN_AND_DISABLE_DBS_SCAN)) 15595 return -EINVAL; 15596 15597 hdd_string_to_u8_array(hdd_ctx->config->dbs_scan_selection, 15598 dbs_scan_config, &numentries, 15599 (CDS_DBS_SCAN_PARAM_PER_CLIENT 15600 * CDS_DBS_SCAN_CLIENTS_MAX)); 15601 15602 if (!numentries) { 15603 hdd_debug("Do not send scan_selection_config"); 15604 return 0; 15605 } 15606 15607 /* hdd_set_fw_log_params */ 15608 dbs_scan_params.num_clients = 0; 15609 while (count < (numentries - 2)) { 15610 dbs_scan_params.module_id[i] = dbs_scan_config[count]; 15611 dbs_scan_params.num_dbs_scans[i] = dbs_scan_config[count + 1]; 15612 dbs_scan_params.num_non_dbs_scans[i] = 15613 dbs_scan_config[count + 2]; 15614 dbs_scan_params.num_clients++; 15615 hdd_debug("module:%d NDS:%d NNDS:%d", 15616 dbs_scan_params.module_id[i], 15617 dbs_scan_params.num_dbs_scans[i], 15618 dbs_scan_params.num_non_dbs_scans[i]); 15619 count += CDS_DBS_SCAN_PARAM_PER_CLIENT; 15620 i++; 15621 } 15622 15623 dbs_scan_params.pdev_id = 0; 15624 15625 hdd_debug("clients:%d pdev:%d", 15626 dbs_scan_params.num_clients, dbs_scan_params.pdev_id); 15627 15628 status = sme_set_dbs_scan_selection_config(hdd_ctx->mac_handle, 15629 &dbs_scan_params); 15630 hdd_debug("Sending DBS Scan Selection Configuration to fw"); 15631 if (!QDF_IS_STATUS_SUCCESS(status)) { 15632 hdd_err("Failed to send DBS Scan selection configuration!"); 15633 return -EAGAIN; 15634 } 15635 return 0; 15636 } 15637 15638 #ifdef FEATURE_WLAN_AUTO_SHUTDOWN 15639 /** 15640 * hdd_set_auto_shutdown_cb() - Set auto shutdown callback 15641 * @hdd_ctx: HDD context 15642 * 15643 * Set auto shutdown callback to get indications from firmware to indicate 15644 * userspace to shutdown WLAN after a configured amount of inactivity. 15645 * 15646 * Return: 0 on success and errno on failure. 15647 */ 15648 static int hdd_set_auto_shutdown_cb(struct hdd_context *hdd_ctx) 15649 { 15650 QDF_STATUS status; 15651 15652 if (!hdd_ctx->config->wlan_auto_shutdown) 15653 return 0; 15654 15655 status = sme_set_auto_shutdown_cb(hdd_ctx->mac_handle, 15656 wlan_hdd_auto_shutdown_cb); 15657 if (status != QDF_STATUS_SUCCESS) 15658 hdd_err("Auto shutdown feature could not be enabled: %d", 15659 status); 15660 15661 return qdf_status_to_os_return(status); 15662 } 15663 #else 15664 static int hdd_set_auto_shutdown_cb(struct hdd_context *hdd_ctx) 15665 { 15666 return 0; 15667 } 15668 #endif 15669 15670 #ifdef MWS_COEX 15671 #define MAX_PDEV_MWSCOEX_PARAMS 4 15672 /* params being sent: 15673 * wmi_pdev_param_mwscoex_4g_allow_quick_ftdm 15674 * wmi_pdev_param_mwscoex_set_5gnr_pwr_limit 15675 * wmi_pdev_param_mwscoex_pcc_chavd_delay 15676 * wmi_pdev_param_mwscoex_scc_chavd_delay 15677 */ 15678 15679 /** 15680 * hdd_init_mws_coex() - Initialize MWS coex configurations 15681 * @hdd_ctx: HDD context 15682 * 15683 * This function sends MWS-COEX 4G quick FTDM and 15684 * MWS-COEX 5G-NR power limit to FW 15685 * 15686 * Return: 0 on success and errno on failure. 15687 */ 15688 static int hdd_init_mws_coex(struct hdd_context *hdd_ctx) 15689 { 15690 int ret = 0; 15691 uint32_t mws_coex_4g_quick_tdm = 0, mws_coex_5g_nr_pwr_limit = 0; 15692 uint32_t mws_coex_pcc_channel_avoid_delay = 0; 15693 uint32_t mws_coex_scc_channel_avoid_delay = 0; 15694 struct dev_set_param setparam[MAX_PDEV_MWSCOEX_PARAMS] = {}; 15695 uint8_t index = 0; 15696 15697 ucfg_mlme_get_mws_coex_4g_quick_tdm(hdd_ctx->psoc, 15698 &mws_coex_4g_quick_tdm); 15699 ret = mlme_check_index_setparam( 15700 setparam, 15701 wmi_pdev_param_mwscoex_4g_allow_quick_ftdm, 15702 mws_coex_4g_quick_tdm, index++, 15703 MAX_PDEV_MWSCOEX_PARAMS); 15704 if (QDF_IS_STATUS_ERROR(ret)) { 15705 hdd_err("failed at wmi_pdev_param_mwscoex_4g_allow_quick_ftdm"); 15706 goto error; 15707 } 15708 15709 ucfg_mlme_get_mws_coex_5g_nr_pwr_limit(hdd_ctx->psoc, 15710 &mws_coex_5g_nr_pwr_limit); 15711 ret = mlme_check_index_setparam( 15712 setparam, 15713 wmi_pdev_param_mwscoex_set_5gnr_pwr_limit, 15714 mws_coex_5g_nr_pwr_limit, index++, 15715 MAX_PDEV_MWSCOEX_PARAMS); 15716 if (QDF_IS_STATUS_ERROR(ret)) { 15717 hdd_err("failed at wmi_pdev_param_mwscoex_set_5gnr_pwr_limit"); 15718 goto error; 15719 } 15720 15721 ucfg_mlme_get_mws_coex_pcc_channel_avoid_delay( 15722 hdd_ctx->psoc, 15723 &mws_coex_pcc_channel_avoid_delay); 15724 ret = mlme_check_index_setparam(setparam, 15725 wmi_pdev_param_mwscoex_pcc_chavd_delay, 15726 mws_coex_pcc_channel_avoid_delay, 15727 index++, MAX_PDEV_MWSCOEX_PARAMS); 15728 if (QDF_IS_STATUS_ERROR(ret)) { 15729 hdd_err("failed at wmi_pdev_param_mwscoex_pcc_chavd_delay"); 15730 goto error; 15731 } 15732 15733 ucfg_mlme_get_mws_coex_scc_channel_avoid_delay( 15734 hdd_ctx->psoc, 15735 &mws_coex_scc_channel_avoid_delay); 15736 ret = mlme_check_index_setparam(setparam, 15737 wmi_pdev_param_mwscoex_scc_chavd_delay, 15738 mws_coex_scc_channel_avoid_delay, 15739 index++, MAX_PDEV_MWSCOEX_PARAMS); 15740 if (QDF_IS_STATUS_ERROR(ret)) { 15741 hdd_err("failed at wmi_pdev_param_mwscoex_scc_chavd_delay"); 15742 goto error; 15743 } 15744 ret = sme_send_multi_pdev_vdev_set_params(MLME_PDEV_SETPARAM, 15745 WMI_PDEV_ID_SOC, setparam, 15746 index); 15747 if (QDF_IS_STATUS_ERROR(ret)) 15748 hdd_err("failed to send pdev MWSCOEX set params"); 15749 error: 15750 return ret; 15751 } 15752 #else 15753 static int hdd_init_mws_coex(struct hdd_context *hdd_ctx) 15754 { 15755 return 0; 15756 } 15757 #endif 15758 15759 #ifdef THERMAL_STATS_SUPPORT 15760 static void hdd_thermal_stats_cmd_init(struct hdd_context *hdd_ctx) 15761 { 15762 hdd_send_get_thermal_stats_cmd(hdd_ctx, thermal_stats_init, NULL, NULL); 15763 } 15764 #else 15765 static void hdd_thermal_stats_cmd_init(struct hdd_context *hdd_ctx) 15766 { 15767 } 15768 #endif 15769 15770 #ifdef WLAN_FEATURE_CAL_FAILURE_TRIGGER 15771 /** 15772 * hdd_cal_fail_send_event()- send calibration failure information 15773 * @cal_type: calibration type 15774 * @reason: reason for calibration failure 15775 * 15776 * This Function sends calibration failure diag event 15777 * 15778 * Return: void. 15779 */ 15780 static void hdd_cal_fail_send_event(uint8_t cal_type, uint8_t reason) 15781 { 15782 /* 15783 * For now we are going with the print. Once CST APK has support to 15784 * read the diag events then we will add the diag event here. 15785 */ 15786 hdd_debug("Received cal failure event with cal_type:%x reason:%x", 15787 cal_type, reason); 15788 } 15789 #else 15790 static inline void hdd_cal_fail_send_event(uint8_t cal_type, uint8_t reason) 15791 { 15792 } 15793 #endif 15794 15795 /** 15796 * hdd_features_init() - Init features 15797 * @hdd_ctx: HDD context 15798 * 15799 * Initialize features and their feature context after WLAN firmware is up. 15800 * 15801 * Return: 0 on success and errno on failure. 15802 */ 15803 static int hdd_features_init(struct hdd_context *hdd_ctx) 15804 { 15805 struct tx_power_limit hddtxlimit; 15806 QDF_STATUS status; 15807 int ret; 15808 mac_handle_t mac_handle; 15809 bool b_cts2self, is_imps_enabled; 15810 bool rf_test_mode; 15811 bool std_6ghz_conn_policy; 15812 uint32_t fw_data_stall_evt; 15813 bool disable_vlp_sta_conn_sp_ap; 15814 15815 hdd_enter(); 15816 15817 ret = hdd_init_mws_coex(hdd_ctx); 15818 if (ret) 15819 hdd_warn("Error initializing mws-coex"); 15820 15821 /* FW capabilities received, Set the Dot11 mode */ 15822 mac_handle = hdd_ctx->mac_handle; 15823 sme_setdef_dot11mode(mac_handle); 15824 15825 ucfg_mlme_is_imps_enabled(hdd_ctx->psoc, &is_imps_enabled); 15826 hdd_set_idle_ps_config(hdd_ctx, is_imps_enabled); 15827 15828 fw_data_stall_evt = ucfg_dp_fw_data_stall_evt_enabled(); 15829 15830 /* Send Enable/Disable data stall detection cmd to FW */ 15831 sme_cli_set_command(0, wmi_pdev_param_data_stall_detect_enable, 15832 fw_data_stall_evt, PDEV_CMD); 15833 15834 ucfg_mlme_get_go_cts2self_for_sta(hdd_ctx->psoc, &b_cts2self); 15835 if (b_cts2self) 15836 sme_set_cts2self_for_p2p_go(mac_handle); 15837 15838 if (hdd_set_vc_mode_config(hdd_ctx)) 15839 hdd_warn("Error in setting Voltage Corner mode config to FW"); 15840 15841 if (ucfg_dp_rx_ol_init(hdd_ctx->psoc, hdd_ctx->is_wifi3_0_target)) 15842 hdd_err("Unable to initialize Rx LRO/GRO in fw"); 15843 15844 if (hdd_adaptive_dwelltime_init(hdd_ctx)) 15845 hdd_err("Unable to send adaptive dwelltime setting to FW"); 15846 15847 if (hdd_dbs_scan_selection_init(hdd_ctx)) 15848 hdd_err("Unable to send DBS scan selection setting to FW"); 15849 15850 ret = hdd_init_thermal_info(hdd_ctx); 15851 if (ret) { 15852 hdd_err("Error while initializing thermal information"); 15853 return ret; 15854 } 15855 15856 /** 15857 * In case of SSR/PDR, if pktlog was enabled manually before 15858 * SSR/PDR, then enable it again automatically after Wlan 15859 * device up. 15860 * During SSR/PDR, pktlog will be disabled as part of 15861 * hdd_features_deinit if pktlog is enabled in ini. 15862 * Re-enable pktlog in SSR case, if pktlog is enabled in ini. 15863 */ 15864 if (hdd_get_conparam() != QDF_GLOBAL_MONITOR_MODE && 15865 (cds_is_packet_log_enabled() || 15866 (cds_is_driver_recovering() && hdd_ctx->is_pktlog_enabled))) 15867 hdd_pktlog_enable_disable(hdd_ctx, true, 0, 0); 15868 15869 hddtxlimit.txPower2g = ucfg_get_tx_power(hdd_ctx->psoc, BAND_2G); 15870 hddtxlimit.txPower5g = ucfg_get_tx_power(hdd_ctx->psoc, BAND_5G); 15871 status = sme_txpower_limit(mac_handle, &hddtxlimit); 15872 if (!QDF_IS_STATUS_SUCCESS(status)) 15873 hdd_err("Error setting txlimit in sme: %d", status); 15874 15875 wlan_hdd_tsf_init(hdd_ctx); 15876 15877 status = sme_enable_disable_chanavoidind_event(mac_handle, 0); 15878 if (QDF_IS_STATUS_ERROR(status) && (status != QDF_STATUS_E_NOSUPPORT)) { 15879 hdd_err("Failed to disable Chan Avoidance Indication"); 15880 return -EINVAL; 15881 } 15882 15883 /* register P2P Listen Offload event callback */ 15884 if (wma_is_p2p_lo_capable()) 15885 sme_register_p2p_lo_event(mac_handle, hdd_ctx, 15886 wlan_hdd_p2p_lo_event_callback); 15887 wlan_hdd_register_mcc_quota_event_callback(hdd_ctx); 15888 ret = hdd_set_auto_shutdown_cb(hdd_ctx); 15889 15890 if (ret) 15891 return -EINVAL; 15892 15893 wlan_hdd_init_chan_info(hdd_ctx); 15894 wlan_hdd_twt_init(hdd_ctx); 15895 wlan_hdd_gpio_wakeup_init(hdd_ctx); 15896 15897 status = ucfg_mlme_is_rf_test_mode_enabled(hdd_ctx->psoc, 15898 &rf_test_mode); 15899 if (!QDF_IS_STATUS_SUCCESS(status)) { 15900 hdd_err("Get rf test mode failed"); 15901 return QDF_STATUS_E_FAILURE; 15902 } 15903 15904 if (rf_test_mode) { 15905 wlan_cm_set_check_6ghz_security(hdd_ctx->psoc, false); 15906 wlan_cm_set_6ghz_key_mgmt_mask(hdd_ctx->psoc, 15907 DEFAULT_KEYMGMT_6G_MASK); 15908 } 15909 15910 status = ucfg_mlme_is_standard_6ghz_conn_policy_enabled(hdd_ctx->psoc, 15911 &std_6ghz_conn_policy); 15912 15913 if (!QDF_IS_STATUS_SUCCESS(status)) { 15914 hdd_err("Get 6ghz standard connection policy failed"); 15915 return QDF_STATUS_E_FAILURE; 15916 } 15917 if (std_6ghz_conn_policy) 15918 wlan_cm_set_standard_6ghz_conn_policy(hdd_ctx->psoc, true); 15919 15920 status = ucfg_mlme_is_disable_vlp_sta_conn_to_sp_ap_enabled( 15921 hdd_ctx->psoc, 15922 &disable_vlp_sta_conn_sp_ap); 15923 if (!QDF_IS_STATUS_SUCCESS(status)) { 15924 hdd_err("Get disable vlp sta conn to sp flag failed"); 15925 return QDF_STATUS_E_FAILURE; 15926 } 15927 15928 if (disable_vlp_sta_conn_sp_ap) 15929 wlan_cm_set_disable_vlp_sta_conn_to_sp_ap(hdd_ctx->psoc, true); 15930 15931 hdd_thermal_stats_cmd_init(hdd_ctx); 15932 sme_set_cal_failure_event_cb(hdd_ctx->mac_handle, 15933 hdd_cal_fail_send_event); 15934 15935 hdd_exit(); 15936 return 0; 15937 } 15938 15939 /** 15940 * hdd_register_bcn_cb() - register scan beacon callback 15941 * @hdd_ctx: Pointer to the HDD context 15942 * 15943 * Return: QDF_STATUS 15944 */ 15945 static inline QDF_STATUS hdd_register_bcn_cb(struct hdd_context *hdd_ctx) 15946 { 15947 QDF_STATUS status; 15948 15949 status = ucfg_scan_register_bcn_cb(hdd_ctx->psoc, 15950 wlan_cfg80211_inform_bss_frame, 15951 SCAN_CB_TYPE_INFORM_BCN); 15952 if (!QDF_IS_STATUS_SUCCESS(status)) { 15953 hdd_err("failed to register SCAN_CB_TYPE_INFORM_BCN with status code %08d [x%08x]", 15954 status, status); 15955 return status; 15956 } 15957 15958 status = ucfg_scan_register_bcn_cb(hdd_ctx->psoc, 15959 wlan_cfg80211_unlink_bss_list, 15960 SCAN_CB_TYPE_UNLINK_BSS); 15961 if (!QDF_IS_STATUS_SUCCESS(status)) { 15962 hdd_err("failed to refister SCAN_CB_TYPE_FLUSH_BSS with status code %08d [x%08x]", 15963 status, status); 15964 return status; 15965 } 15966 15967 return QDF_STATUS_SUCCESS; 15968 } 15969 15970 /** 15971 * hdd_v2_flow_pool_map() - Flow pool create callback when vdev is active 15972 * @vdev_id: vdev_id, corresponds to flow_pool 15973 * 15974 * Return: none. 15975 */ 15976 static void hdd_v2_flow_pool_map(int vdev_id) 15977 { 15978 QDF_STATUS status; 15979 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 15980 struct wlan_objmgr_vdev *vdev; 15981 15982 if (!hdd_ctx) { 15983 hdd_err("HDD context null"); 15984 return; 15985 } 15986 15987 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(hdd_ctx->psoc, vdev_id, 15988 WLAN_OSIF_ID); 15989 if (!vdev) { 15990 hdd_err("Invalid VDEV %d", vdev_id); 15991 return; 15992 } 15993 15994 if (wlan_vdev_mlme_is_mlo_link_switch_in_progress(vdev)) { 15995 hdd_info("Link switch ongoing, do not invoke flow pool map"); 15996 goto release_ref; 15997 } 15998 15999 status = cdp_flow_pool_map(cds_get_context(QDF_MODULE_ID_SOC), 16000 OL_TXRX_PDEV_ID, vdev_id); 16001 /* 16002 * For Adrastea flow control v2 is based on FW MAP events, 16003 * so this above callback is not implemented. 16004 * Hence this is not actual failure. Dont return failure 16005 */ 16006 if ((status != QDF_STATUS_SUCCESS) && 16007 (status != QDF_STATUS_E_INVAL)) { 16008 hdd_err("vdev_id: %d, failed to create flow pool status %d", 16009 vdev_id, status); 16010 } 16011 16012 release_ref: 16013 wlan_objmgr_vdev_release_ref(vdev, WLAN_OSIF_ID); 16014 } 16015 16016 /** 16017 * hdd_v2_flow_pool_unmap() - Flow pool create callback when vdev is not active 16018 * @vdev_id: vdev_id, corresponds to flow_pool 16019 * 16020 * Return: none. 16021 */ 16022 static void hdd_v2_flow_pool_unmap(int vdev_id) 16023 { 16024 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 16025 struct wlan_objmgr_vdev *vdev; 16026 16027 if (!hdd_ctx) { 16028 hdd_err("HDD context null"); 16029 return; 16030 } 16031 16032 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(hdd_ctx->psoc, vdev_id, 16033 WLAN_OSIF_ID); 16034 if (!vdev) { 16035 hdd_err("Invalid VDEV %d", vdev_id); 16036 return; 16037 } 16038 16039 if (wlan_vdev_mlme_is_mlo_link_switch_in_progress(vdev)) { 16040 hdd_info("Link switch ongoing do not invoke flow pool unmap"); 16041 goto release_ref; 16042 } 16043 16044 cdp_flow_pool_unmap(cds_get_context(QDF_MODULE_ID_SOC), 16045 OL_TXRX_PDEV_ID, vdev_id); 16046 release_ref: 16047 wlan_objmgr_vdev_release_ref(vdev, WLAN_OSIF_ID); 16048 } 16049 16050 static void hdd_hastings_bt_war_initialize(struct hdd_context *hdd_ctx) 16051 { 16052 if (hdd_ctx->config->iface_change_wait_time) 16053 hdd_hastings_bt_war_disable_fw(hdd_ctx); 16054 else 16055 hdd_hastings_bt_war_enable_fw(hdd_ctx); 16056 } 16057 16058 #define MAX_PDEV_CFG_CDS_PARAMS 8 16059 /* params being sent: 16060 * wmi_pdev_param_set_iot_pattern 16061 * wmi_pdev_param_max_mpdus_in_ampdu 16062 * wmi_pdev_param_enable_rts_sifs_bursting 16063 * wmi_pdev_param_peer_stats_info_enable 16064 * wmi_pdev_param_abg_mode_tx_chain_num 16065 * wmi_pdev_param_gcmp_support_enable 16066 * wmi_pdev_auto_detect_power_failure 16067 * wmi_pdev_param_fast_pwr_transition 16068 */ 16069 16070 /** 16071 * hdd_configure_cds() - Configure cds modules 16072 * @hdd_ctx: HDD context 16073 * 16074 * Enable Cds modules after WLAN firmware is up. 16075 * 16076 * Return: 0 on success and errno on failure. 16077 */ 16078 int hdd_configure_cds(struct hdd_context *hdd_ctx) 16079 { 16080 int ret; 16081 QDF_STATUS status; 16082 int set_value; 16083 mac_handle_t mac_handle; 16084 bool enable_rts_sifsbursting; 16085 uint8_t enable_phy_reg_retention; 16086 uint8_t max_mpdus_inampdu, is_force_1x1 = 0; 16087 uint32_t num_abg_tx_chains = 0; 16088 uint16_t num_11b_tx_chains = 0; 16089 uint16_t num_11ag_tx_chains = 0; 16090 struct policy_mgr_dp_cbacks dp_cbs = {0}; 16091 bool value; 16092 enum pmo_auto_pwr_detect_failure_mode auto_power_fail_mode; 16093 bool bval = false; 16094 uint8_t max_index = MAX_PDEV_CFG_CDS_PARAMS; 16095 struct dev_set_param setparam[MAX_PDEV_CFG_CDS_PARAMS] = {}; 16096 uint8_t index = 0; 16097 uint8_t next_index = 0; 16098 mac_handle = hdd_ctx->mac_handle; 16099 16100 status = ucfg_policy_mgr_get_force_1x1(hdd_ctx->psoc, &is_force_1x1); 16101 if (status != QDF_STATUS_SUCCESS) { 16102 hdd_err("Failed to get force 1x1 value"); 16103 goto out; 16104 } 16105 if (is_force_1x1) { 16106 status = mlme_check_index_setparam( 16107 setparam, 16108 wmi_pdev_param_set_iot_pattern, 16109 1, index++, 16110 max_index); 16111 if (QDF_IS_STATUS_ERROR(status)) { 16112 hdd_err("failed at wmi_pdev_param_set_iot_pattern"); 16113 goto out; 16114 } 16115 } 16116 /* set chip power save failure detected callback */ 16117 sme_set_chip_pwr_save_fail_cb(mac_handle, 16118 hdd_chip_pwr_save_fail_detected_cb); 16119 16120 status = ucfg_get_max_mpdus_inampdu(hdd_ctx->psoc, 16121 &max_mpdus_inampdu); 16122 if (status) { 16123 hdd_err("Failed to get max mpdus in ampdu value"); 16124 goto out; 16125 } 16126 16127 if (max_mpdus_inampdu) { 16128 set_value = max_mpdus_inampdu; 16129 status = mlme_check_index_setparam( 16130 setparam, 16131 wmi_pdev_param_max_mpdus_in_ampdu, 16132 set_value, index++, 16133 max_index); 16134 if (QDF_IS_STATUS_ERROR(status)) { 16135 hdd_err("failed at wmi_pdev_param_max_mpdus_in_ampdu"); 16136 goto out; 16137 } 16138 } 16139 16140 status = ucfg_get_enable_rts_sifsbursting(hdd_ctx->psoc, 16141 &enable_rts_sifsbursting); 16142 if (status) { 16143 hdd_err("Failed to get rts sifs bursting value"); 16144 goto out; 16145 } 16146 16147 if (enable_rts_sifsbursting) { 16148 set_value = enable_rts_sifsbursting; 16149 status = mlme_check_index_setparam( 16150 setparam, 16151 wmi_pdev_param_enable_rts_sifs_bursting, 16152 set_value, index++, 16153 max_index); 16154 if (QDF_IS_STATUS_ERROR(status)) { 16155 hdd_err("Failed at wmi_pdev_param_enable_rts_sifs_bursting"); 16156 goto out; 16157 } 16158 } 16159 16160 ucfg_mlme_get_sap_get_peer_info(hdd_ctx->psoc, &value); 16161 if (value) { 16162 set_value = value; 16163 status = mlme_check_index_setparam( 16164 setparam, 16165 wmi_pdev_param_peer_stats_info_enable, 16166 set_value, index++, 16167 max_index); 16168 if (QDF_IS_STATUS_ERROR(status)) { 16169 hdd_err("Failed at wmi_pdev_param_peer_stats_info_enable"); 16170 goto out; 16171 } 16172 } 16173 16174 status = ucfg_mlme_get_num_11b_tx_chains(hdd_ctx->psoc, 16175 &num_11b_tx_chains); 16176 if (status != QDF_STATUS_SUCCESS) { 16177 hdd_err("Failed to get num_11b_tx_chains"); 16178 goto out; 16179 } 16180 16181 status = ucfg_mlme_get_num_11ag_tx_chains(hdd_ctx->psoc, 16182 &num_11ag_tx_chains); 16183 if (status != QDF_STATUS_SUCCESS) { 16184 hdd_err("Failed to get num_11ag_tx_chains"); 16185 goto out; 16186 } 16187 16188 status = ucfg_mlme_get_vht_enable2x2(hdd_ctx->psoc, &bval); 16189 if (!QDF_IS_STATUS_SUCCESS(status)) 16190 hdd_err("unable to get vht_enable2x2"); 16191 16192 if (!bval) { 16193 if (num_11b_tx_chains > 1) 16194 num_11b_tx_chains = 1; 16195 if (num_11ag_tx_chains > 1) 16196 num_11ag_tx_chains = 1; 16197 } 16198 WMI_PDEV_PARAM_SET_11B_TX_CHAIN_NUM(num_abg_tx_chains, 16199 num_11b_tx_chains); 16200 WMI_PDEV_PARAM_SET_11AG_TX_CHAIN_NUM(num_abg_tx_chains, 16201 num_11ag_tx_chains); 16202 status = mlme_check_index_setparam(setparam, 16203 wmi_pdev_param_abg_mode_tx_chain_num, 16204 num_abg_tx_chains, index++, 16205 max_index); 16206 if (QDF_IS_STATUS_ERROR(status)) { 16207 hdd_err("Failed at wmi_pdev_param_abg_mode_tx_chain_num"); 16208 goto out; 16209 } 16210 /* Send some pdev params to maintain legacy order of pdev set params 16211 * at hdd_pre_enable_configure 16212 */ 16213 status = sme_send_multi_pdev_vdev_set_params(MLME_PDEV_SETPARAM, 16214 WMI_PDEV_ID_SOC, setparam, 16215 index); 16216 if (QDF_IS_STATUS_ERROR(status)) { 16217 hdd_err("Failed to send 1st set of pdev params"); 16218 goto out; 16219 } 16220 if (!ucfg_reg_is_regdb_offloaded(hdd_ctx->psoc)) 16221 ucfg_reg_program_default_cc(hdd_ctx->pdev, 16222 hdd_ctx->reg.reg_domain); 16223 16224 ret = hdd_pre_enable_configure(hdd_ctx); 16225 if (ret) { 16226 hdd_err("Failed to pre-configure cds"); 16227 goto out; 16228 } 16229 16230 /* Always get latest IPA resources allocated from cds_open and configure 16231 * IPA module before configuring them to FW. Sequence required as crash 16232 * observed otherwise. 16233 */ 16234 16235 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) { 16236 ipa_disable_register_cb(); 16237 } else { 16238 status = ipa_register_is_ipa_ready(hdd_ctx->pdev); 16239 if (!QDF_IS_STATUS_SUCCESS(status)) { 16240 hdd_err("ipa_register_is_ipa_ready failed"); 16241 goto out; 16242 } 16243 } 16244 16245 /* 16246 * Start CDS which starts up the SME/MAC/HAL modules and everything 16247 * else 16248 */ 16249 status = cds_enable(hdd_ctx->psoc); 16250 16251 if (!QDF_IS_STATUS_SUCCESS(status)) { 16252 hdd_err("cds_enable failed"); 16253 goto out; 16254 } 16255 16256 status = hdd_post_cds_enable_config(hdd_ctx); 16257 if (!QDF_IS_STATUS_SUCCESS(status)) { 16258 hdd_err("hdd_post_cds_enable_config failed"); 16259 goto cds_disable; 16260 } 16261 status = hdd_register_bcn_cb(hdd_ctx); 16262 if (!QDF_IS_STATUS_SUCCESS(status)) { 16263 hdd_err("hdd_register_bcn_cb failed"); 16264 goto cds_disable; 16265 } 16266 16267 ret = hdd_features_init(hdd_ctx); 16268 if (ret) 16269 goto cds_disable; 16270 16271 /* 16272 * Donot disable rx offload on concurrency for lithium and 16273 * beryllium based targets 16274 */ 16275 if (!hdd_ctx->is_wifi3_0_target) 16276 if (ucfg_dp_is_ol_enabled(hdd_ctx->psoc)) 16277 dp_cbs.hdd_disable_rx_ol_in_concurrency = 16278 hdd_disable_rx_ol_in_concurrency; 16279 dp_cbs.hdd_set_rx_mode_rps_cb = ucfg_dp_set_rx_mode_rps; 16280 dp_cbs.hdd_ipa_set_mcc_mode_cb = hdd_ipa_set_mcc_mode; 16281 dp_cbs.hdd_v2_flow_pool_map = hdd_v2_flow_pool_map; 16282 dp_cbs.hdd_v2_flow_pool_unmap = hdd_v2_flow_pool_unmap; 16283 status = policy_mgr_register_dp_cb(hdd_ctx->psoc, &dp_cbs); 16284 if (!QDF_IS_STATUS_SUCCESS(status)) { 16285 hdd_debug("Failed to register DP cb with Policy Manager"); 16286 goto cds_disable; 16287 } 16288 status = policy_mgr_register_mode_change_cb(hdd_ctx->psoc, 16289 wlan_hdd_send_mode_change_event); 16290 if (!QDF_IS_STATUS_SUCCESS(status)) { 16291 hdd_debug("Failed to register mode change cb with Policy Manager"); 16292 goto cds_disable; 16293 } 16294 16295 if (hdd_green_ap_enable_egap(hdd_ctx)) 16296 hdd_debug("enhance green ap is not enabled"); 16297 16298 hdd_register_green_ap_callback(hdd_ctx->pdev); 16299 16300 if (0 != wlan_hdd_set_wow_pulse(hdd_ctx, true)) 16301 hdd_debug("Failed to set wow pulse"); 16302 16303 max_index = max_index - index; 16304 status = mlme_check_index_setparam( 16305 setparam + index, 16306 wmi_pdev_param_gcmp_support_enable, 16307 ucfg_fwol_get_gcmp_enable(hdd_ctx->psoc), 16308 next_index++, max_index); 16309 if (QDF_IS_STATUS_ERROR(status)) { 16310 hdd_err("failed at wmi_pdev_param_gcmp_support_enable"); 16311 goto out; 16312 } 16313 16314 auto_power_fail_mode = 16315 ucfg_pmo_get_auto_power_fail_mode(hdd_ctx->psoc); 16316 status = mlme_check_index_setparam( 16317 setparam + index, 16318 wmi_pdev_auto_detect_power_failure, 16319 auto_power_fail_mode, 16320 next_index++, max_index); 16321 if (QDF_IS_STATUS_ERROR(status)) { 16322 hdd_err("failed at wmi_pdev_auto_detect_power_failure"); 16323 goto out; 16324 } 16325 16326 status = ucfg_get_enable_phy_reg_retention(hdd_ctx->psoc, 16327 &enable_phy_reg_retention); 16328 16329 if (QDF_IS_STATUS_ERROR(status)) 16330 return -EINVAL; 16331 16332 if (enable_phy_reg_retention) { 16333 status = mlme_check_index_setparam( 16334 setparam + index, 16335 wmi_pdev_param_fast_pwr_transition, 16336 enable_phy_reg_retention, 16337 next_index++, max_index); 16338 if (QDF_IS_STATUS_ERROR(status)) { 16339 hdd_err("failed at wmi_pdev_param_fast_pwr_transition"); 16340 goto out; 16341 } 16342 } 16343 /*Send remaining pdev setparams from array*/ 16344 status = sme_send_multi_pdev_vdev_set_params(MLME_PDEV_SETPARAM, 16345 WMI_PDEV_ID_SOC, 16346 setparam + index, 16347 next_index); 16348 if (QDF_IS_STATUS_ERROR(status)) { 16349 hdd_err("failed to send 2nd set of pdev set params"); 16350 goto out; 16351 } 16352 16353 hdd_hastings_bt_war_initialize(hdd_ctx); 16354 16355 wlan_hdd_hang_event_notifier_register(hdd_ctx); 16356 return 0; 16357 16358 cds_disable: 16359 cds_disable(hdd_ctx->psoc); 16360 16361 out: 16362 return -EINVAL; 16363 } 16364 16365 #ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH 16366 static void hdd_deregister_policy_manager_callback( 16367 struct wlan_objmgr_psoc *psoc) 16368 { 16369 if (QDF_STATUS_SUCCESS != 16370 policy_mgr_deregister_hdd_cb(psoc)) { 16371 hdd_err("HDD callback deregister with policy manager failed"); 16372 } 16373 } 16374 #else 16375 static void hdd_deregister_policy_manager_callback( 16376 struct wlan_objmgr_psoc *psoc) 16377 { 16378 } 16379 #endif 16380 16381 int hdd_wlan_stop_modules(struct hdd_context *hdd_ctx, bool ftm_mode) 16382 { 16383 void *hif_ctx; 16384 qdf_device_t qdf_ctx; 16385 QDF_STATUS qdf_status; 16386 bool is_recovery_stop = cds_is_driver_recovering(); 16387 int ret = 0; 16388 int debugfs_threads; 16389 struct target_psoc_info *tgt_hdl; 16390 struct bbm_params param = {0}; 16391 16392 hdd_enter(); 16393 qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE); 16394 if (!qdf_ctx) 16395 return -EINVAL; 16396 16397 cds_set_driver_state_module_stop(true); 16398 16399 debugfs_threads = hdd_return_debugfs_threads_count(); 16400 16401 if (debugfs_threads > 0 || hdd_ctx->is_wiphy_suspended) { 16402 hdd_warn("Debugfs threads %d, wiphy suspend %d", 16403 debugfs_threads, hdd_ctx->is_wiphy_suspended); 16404 16405 if (IS_IDLE_STOP && !ftm_mode) { 16406 hdd_psoc_idle_timer_start(hdd_ctx); 16407 cds_set_driver_state_module_stop(false); 16408 16409 ucfg_dp_bus_bw_compute_timer_stop(hdd_ctx->psoc); 16410 return -EAGAIN; 16411 } 16412 } 16413 16414 ucfg_dp_bus_bw_compute_timer_stop(hdd_ctx->psoc); 16415 hdd_deregister_policy_manager_callback(hdd_ctx->psoc); 16416 16417 /* free user wowl patterns */ 16418 hdd_free_user_wowl_ptrns(); 16419 16420 switch (hdd_ctx->driver_status) { 16421 case DRIVER_MODULES_UNINITIALIZED: 16422 hdd_debug("Modules not initialized just return"); 16423 goto done; 16424 case DRIVER_MODULES_CLOSED: 16425 hdd_debug("Modules already closed"); 16426 goto done; 16427 case DRIVER_MODULES_ENABLED: 16428 hdd_debug("Wlan transitioning (CLOSED <- ENABLED)"); 16429 16430 if (hdd_get_conparam() == QDF_GLOBAL_FTM_MODE) { 16431 hdd_disable_power_management(hdd_ctx); 16432 break; 16433 } 16434 16435 if (hdd_get_conparam() == QDF_GLOBAL_EPPING_MODE) 16436 break; 16437 16438 hdd_skip_acs_scan_timer_deinit(hdd_ctx); 16439 16440 hdd_disable_power_management(hdd_ctx); 16441 16442 if (hdd_get_conparam() == QDF_GLOBAL_MISSION_MODE) 16443 ucfg_dp_direct_link_deinit(hdd_ctx->psoc, 16444 is_recovery_stop); 16445 16446 if (hdd_deconfigure_cds(hdd_ctx)) { 16447 hdd_err("Failed to de-configure CDS"); 16448 QDF_ASSERT(0); 16449 ret = -EINVAL; 16450 } 16451 hdd_debug("successfully Disabled the CDS modules!"); 16452 16453 break; 16454 default: 16455 QDF_DEBUG_PANIC("Unknown driver state:%d", 16456 hdd_ctx->driver_status); 16457 ret = -EINVAL; 16458 goto done; 16459 } 16460 16461 hdd_destroy_sysfs_files(); 16462 hdd_debug("Closing CDS modules!"); 16463 16464 if (hdd_get_conparam() != QDF_GLOBAL_EPPING_MODE) { 16465 qdf_status = cds_post_disable(); 16466 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { 16467 hdd_err("Failed to process post CDS disable! :%d", 16468 qdf_status); 16469 ret = -EINVAL; 16470 QDF_ASSERT(0); 16471 } 16472 16473 hdd_unregister_notifiers(hdd_ctx); 16474 /* De-register the SME callbacks */ 16475 hdd_deregister_cb(hdd_ctx); 16476 16477 hdd_runtime_suspend_context_deinit(hdd_ctx); 16478 16479 qdf_status = cds_dp_close(hdd_ctx->psoc); 16480 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { 16481 hdd_warn("Failed to stop CDS DP: %d", qdf_status); 16482 ret = -EINVAL; 16483 QDF_ASSERT(0); 16484 } 16485 16486 hdd_component_pdev_close(hdd_ctx->pdev); 16487 dispatcher_pdev_close(hdd_ctx->pdev); 16488 ret = hdd_objmgr_release_and_destroy_pdev(hdd_ctx); 16489 if (ret) { 16490 hdd_err("Failed to destroy pdev; errno:%d", ret); 16491 QDF_ASSERT(0); 16492 } 16493 16494 qdf_status = cds_close(hdd_ctx->psoc); 16495 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { 16496 hdd_warn("Failed to stop CDS: %d", qdf_status); 16497 ret = -EINVAL; 16498 QDF_ASSERT(0); 16499 } 16500 16501 qdf_status = wbuff_module_deinit(); 16502 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) 16503 hdd_err("WBUFF de-init unsuccessful; status: %d", 16504 qdf_status); 16505 16506 hdd_component_psoc_close(hdd_ctx->psoc); 16507 /* pdev close and destroy use tx rx ops so call this here */ 16508 wlan_global_lmac_if_close(hdd_ctx->psoc); 16509 } 16510 16511 /* 16512 * Reset total mac phy during module stop such that during 16513 * next module start same psoc is used to populate new service 16514 * ready data 16515 */ 16516 tgt_hdl = wlan_psoc_get_tgt_if_handle(hdd_ctx->psoc); 16517 if (tgt_hdl) 16518 target_psoc_set_total_mac_phy_cnt(tgt_hdl, 0); 16519 16520 16521 hif_ctx = cds_get_context(QDF_MODULE_ID_HIF); 16522 if (!hif_ctx) 16523 ret = -EINVAL; 16524 16525 if (hdd_get_conparam() == QDF_GLOBAL_EPPING_MODE) { 16526 epping_disable(); 16527 epping_close(); 16528 } 16529 16530 wlan_connectivity_logging_stop(); 16531 16532 ucfg_ipa_component_config_free(); 16533 16534 hdd_hif_close(hdd_ctx, hif_ctx); 16535 16536 ol_cds_free(); 16537 16538 if (IS_IDLE_STOP) { 16539 ret = pld_power_off(qdf_ctx->dev); 16540 if (ret) 16541 hdd_err("Failed to power down device; errno:%d", ret); 16542 } 16543 16544 /* Free the cache channels of the command SET_DISABLE_CHANNEL_LIST */ 16545 wlan_hdd_free_cache_channels(hdd_ctx); 16546 hdd_driver_mem_cleanup(); 16547 16548 /* Free the resources allocated while storing SAR config. These needs 16549 * to be freed only in the case when it is not SSR. As in the case of 16550 * SSR, the values needs to be intact so that it can be restored during 16551 * reinit path. 16552 */ 16553 if (!is_recovery_stop) 16554 wlan_hdd_free_sar_config(hdd_ctx); 16555 16556 hdd_sap_destroy_ctx_all(hdd_ctx, is_recovery_stop); 16557 hdd_sta_destroy_ctx_all(hdd_ctx); 16558 16559 /* 16560 * Reset the driver mode specific bus bw level 16561 */ 16562 param.policy = BBM_DRIVER_MODE_POLICY; 16563 param.policy_info.driver_mode = QDF_GLOBAL_MAX_MODE; 16564 ucfg_dp_bbm_apply_independent_policy(hdd_ctx->psoc, ¶m); 16565 16566 hdd_deinit_adapter_ops_wq(hdd_ctx); 16567 hdd_deinit_qdf_ctx(hdd_debug_domain_get()); 16568 16569 hdd_check_for_leaks(hdd_ctx, is_recovery_stop); 16570 hdd_debug_domain_set(QDF_DEBUG_DOMAIN_INIT); 16571 hdd_deinit_qdf_ctx(hdd_debug_domain_get()); 16572 qdf_dma_invalid_buf_list_deinit(); 16573 16574 /* Restore PS params for monitor mode */ 16575 if (hdd_get_conparam() == QDF_GLOBAL_MONITOR_MODE) 16576 hdd_restore_all_ps(hdd_ctx); 16577 16578 /* Once the firmware sequence is completed reset this flag */ 16579 hdd_ctx->imps_enabled = false; 16580 hdd_ctx->is_dual_mac_cfg_updated = false; 16581 hdd_ctx->driver_status = DRIVER_MODULES_CLOSED; 16582 hdd_ctx->is_fw_dbg_log_levels_configured = false; 16583 hdd_debug("Wlan transitioned (now CLOSED)"); 16584 16585 done: 16586 hdd_exit(); 16587 16588 return ret; 16589 } 16590 16591 #ifdef WLAN_FEATURE_MEMDUMP_ENABLE 16592 /** 16593 * hdd_state_info_dump() - prints state information of hdd layer 16594 * @buf_ptr: buffer pointer 16595 * @size: size of buffer to be filled 16596 * 16597 * This function is used to dump state information of hdd layer 16598 * 16599 * Return: None 16600 */ 16601 static void hdd_state_info_dump(char **buf_ptr, uint16_t *size) 16602 { 16603 struct hdd_context *hdd_ctx; 16604 struct hdd_station_ctx *sta_ctx; 16605 struct hdd_adapter *adapter, *next_adapter = NULL; 16606 uint16_t len = 0; 16607 char *buf = *buf_ptr; 16608 wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_STATE_INFO_DUMP; 16609 struct wlan_hdd_link_info *link_info; 16610 16611 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 16612 if (!hdd_ctx) 16613 return; 16614 16615 hdd_debug("size of buffer: %d", *size); 16616 16617 len += scnprintf(buf + len, *size - len, "\n is_wiphy_suspended %d", 16618 hdd_ctx->is_wiphy_suspended); 16619 len += scnprintf(buf + len, *size - len, "\n is_scheduler_suspended %d", 16620 hdd_ctx->is_scheduler_suspended); 16621 16622 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 16623 dbgid) { 16624 hdd_adapter_for_each_active_link_info(adapter, link_info) { 16625 len += 16626 scnprintf(buf + len, *size - len, "\n device name: %s", 16627 adapter->dev->name); 16628 len += 16629 scnprintf(buf + len, *size - len, "\n device_mode: %d", 16630 adapter->device_mode); 16631 switch (adapter->device_mode) { 16632 case QDF_STA_MODE: 16633 case QDF_P2P_CLIENT_MODE: 16634 sta_ctx = 16635 WLAN_HDD_GET_STATION_CTX_PTR(link_info); 16636 len += scnprintf(buf + len, *size - len, 16637 "\n conn_state: %d", 16638 sta_ctx->conn_info.conn_state); 16639 break; 16640 default: 16641 break; 16642 } 16643 } 16644 hdd_adapter_dev_put_debug(adapter, dbgid); 16645 } 16646 16647 *size -= len; 16648 *buf_ptr += len; 16649 } 16650 16651 /** 16652 * hdd_register_debug_callback() - registration function for hdd layer 16653 * to print hdd state information 16654 * 16655 * Return: None 16656 */ 16657 static void hdd_register_debug_callback(void) 16658 { 16659 qdf_register_debug_callback(QDF_MODULE_ID_HDD, &hdd_state_info_dump); 16660 } 16661 #else /* WLAN_FEATURE_MEMDUMP_ENABLE */ 16662 static void hdd_register_debug_callback(void) 16663 { 16664 } 16665 #endif /* WLAN_FEATURE_MEMDUMP_ENABLE */ 16666 16667 /* 16668 * wlan_init_bug_report_lock() - Initialize bug report lock 16669 * 16670 * This function is used to create bug report lock 16671 * 16672 * Return: None 16673 */ 16674 static void wlan_init_bug_report_lock(void) 16675 { 16676 struct cds_context *p_cds_context; 16677 16678 p_cds_context = cds_get_global_context(); 16679 if (!p_cds_context) { 16680 hdd_err("cds context is NULL"); 16681 return; 16682 } 16683 16684 qdf_spinlock_create(&p_cds_context->bug_report_lock); 16685 } 16686 16687 #ifdef DISABLE_CHANNEL_LIST 16688 static QDF_STATUS wlan_hdd_cache_chann_mutex_create(struct hdd_context *hdd_ctx) 16689 { 16690 return qdf_mutex_create(&hdd_ctx->cache_channel_lock); 16691 } 16692 #else 16693 static QDF_STATUS wlan_hdd_cache_chann_mutex_create(struct hdd_context *hdd_ctx) 16694 { 16695 return QDF_STATUS_SUCCESS; 16696 } 16697 #endif 16698 16699 QDF_STATUS hdd_open_adapter_no_trans(struct hdd_context *hdd_ctx, 16700 enum QDF_OPMODE op_mode, 16701 const char *iface_name, 16702 uint8_t *mac_addr_bytes, 16703 struct hdd_adapter_create_param *params) 16704 { 16705 struct osif_vdev_sync *vdev_sync; 16706 struct hdd_adapter *adapter; 16707 QDF_STATUS status; 16708 int errno; 16709 16710 QDF_BUG(rtnl_is_locked()); 16711 16712 errno = osif_vdev_sync_create(hdd_ctx->parent_dev, &vdev_sync); 16713 if (errno) 16714 return qdf_status_from_os_return(errno); 16715 16716 adapter = hdd_open_adapter(hdd_ctx, op_mode, iface_name, 16717 mac_addr_bytes, NET_NAME_UNKNOWN, true, 16718 params); 16719 if (!adapter) { 16720 status = QDF_STATUS_E_INVAL; 16721 goto destroy_sync; 16722 } 16723 16724 osif_vdev_sync_register(adapter->dev, vdev_sync); 16725 16726 return QDF_STATUS_SUCCESS; 16727 16728 destroy_sync: 16729 osif_vdev_sync_destroy(vdev_sync); 16730 16731 return status; 16732 } 16733 16734 #ifdef WLAN_OPEN_P2P_INTERFACE 16735 /** 16736 * hdd_open_p2p_interface - Open P2P interface 16737 * @hdd_ctx: HDD context 16738 * 16739 * Return: QDF_STATUS 16740 */ 16741 static QDF_STATUS hdd_open_p2p_interface(struct hdd_context *hdd_ctx) 16742 { 16743 QDF_STATUS status; 16744 bool p2p_dev_addr_admin; 16745 bool is_p2p_locally_administered = false; 16746 struct hdd_adapter_create_param params = {0}; 16747 16748 cfg_p2p_get_device_addr_admin(hdd_ctx->psoc, &p2p_dev_addr_admin); 16749 16750 if (p2p_dev_addr_admin) { 16751 if (hdd_ctx->num_provisioned_addr && 16752 !(hdd_ctx->provisioned_mac_addr[0].bytes[0] & 0x02)) { 16753 hdd_ctx->p2p_device_address = 16754 hdd_ctx->provisioned_mac_addr[0]; 16755 16756 /* 16757 * Generate the P2P Device Address. This consists of 16758 * the device's primary MAC address with the locally 16759 * administered bit set. 16760 */ 16761 16762 hdd_ctx->p2p_device_address.bytes[0] |= 0x02; 16763 is_p2p_locally_administered = true; 16764 } else if (!(hdd_ctx->derived_mac_addr[0].bytes[0] & 0x02)) { 16765 hdd_ctx->p2p_device_address = 16766 hdd_ctx->derived_mac_addr[0]; 16767 /* 16768 * Generate the P2P Device Address. This consists of 16769 * the device's primary MAC address with the locally 16770 * administered bit set. 16771 */ 16772 hdd_ctx->p2p_device_address.bytes[0] |= 0x02; 16773 is_p2p_locally_administered = true; 16774 } 16775 } 16776 if (!is_p2p_locally_administered) { 16777 uint8_t *p2p_dev_addr; 16778 16779 p2p_dev_addr = wlan_hdd_get_intf_addr(hdd_ctx, 16780 QDF_P2P_DEVICE_MODE); 16781 if (!p2p_dev_addr) { 16782 hdd_err("Failed to get MAC address for new p2p device"); 16783 return QDF_STATUS_E_INVAL; 16784 } 16785 16786 qdf_mem_copy(hdd_ctx->p2p_device_address.bytes, 16787 p2p_dev_addr, QDF_MAC_ADDR_SIZE); 16788 } 16789 16790 status = hdd_open_adapter_no_trans(hdd_ctx, QDF_P2P_DEVICE_MODE, 16791 "p2p%d", 16792 hdd_ctx->p2p_device_address.bytes, 16793 ¶ms); 16794 if (QDF_IS_STATUS_ERROR(status)) { 16795 if (!is_p2p_locally_administered) 16796 wlan_hdd_release_intf_addr(hdd_ctx, 16797 hdd_ctx->p2p_device_address.bytes); 16798 hdd_err("Failed to open p2p interface"); 16799 return QDF_STATUS_E_INVAL; 16800 } 16801 16802 return QDF_STATUS_SUCCESS; 16803 } 16804 #else 16805 static inline QDF_STATUS hdd_open_p2p_interface(struct hdd_context *hdd_ctx) 16806 { 16807 return QDF_STATUS_SUCCESS; 16808 } 16809 #endif 16810 16811 static QDF_STATUS hdd_open_ocb_interface(struct hdd_context *hdd_ctx) 16812 { 16813 QDF_STATUS status; 16814 uint8_t *mac_addr; 16815 struct hdd_adapter_create_param params = {0}; 16816 16817 mac_addr = wlan_hdd_get_intf_addr(hdd_ctx, QDF_OCB_MODE); 16818 if (!mac_addr) 16819 return QDF_STATUS_E_INVAL; 16820 16821 status = hdd_open_adapter_no_trans(hdd_ctx, QDF_OCB_MODE, 16822 "wlanocb%d", mac_addr, 16823 ¶ms); 16824 if (QDF_IS_STATUS_ERROR(status)) { 16825 wlan_hdd_release_intf_addr(hdd_ctx, mac_addr); 16826 hdd_err("Failed to open 802.11p interface"); 16827 } 16828 16829 return status; 16830 } 16831 16832 static QDF_STATUS hdd_open_concurrent_interface(struct hdd_context *hdd_ctx) 16833 { 16834 QDF_STATUS status; 16835 const char *iface_name; 16836 uint8_t *mac_addr; 16837 struct hdd_adapter_create_param params = {0}; 16838 16839 if (qdf_str_eq(hdd_ctx->config->enable_concurrent_sta, "")) 16840 return QDF_STATUS_SUCCESS; 16841 16842 iface_name = hdd_ctx->config->enable_concurrent_sta; 16843 mac_addr = wlan_hdd_get_intf_addr(hdd_ctx, QDF_STA_MODE); 16844 if (!mac_addr) 16845 return QDF_STATUS_E_INVAL; 16846 16847 status = hdd_open_adapter_no_trans(hdd_ctx, QDF_STA_MODE, 16848 iface_name, mac_addr, 16849 ¶ms); 16850 if (QDF_IS_STATUS_ERROR(status)) { 16851 wlan_hdd_release_intf_addr(hdd_ctx, mac_addr); 16852 hdd_err("Failed to open concurrent station interface"); 16853 } 16854 16855 return status; 16856 } 16857 16858 #ifdef WLAN_HDD_MULTI_VDEV_SINGLE_NDEV 16859 static inline void 16860 hdd_adapter_open_set_max_active_links(struct hdd_adapter_create_param *params) 16861 { 16862 if (params->is_add_virtual_iface || !params->is_ml_adapter) 16863 params->num_sessions = 1; 16864 else 16865 params->num_sessions = 2; 16866 } 16867 #else 16868 static inline void 16869 hdd_adapter_open_set_max_active_links(struct hdd_adapter_create_param *params) 16870 { 16871 params->num_sessions = 1; 16872 } 16873 #endif 16874 16875 static QDF_STATUS 16876 hdd_open_adapters_for_mission_mode(struct hdd_context *hdd_ctx) 16877 { 16878 enum dot11p_mode dot11p_mode; 16879 QDF_STATUS status; 16880 uint8_t *mac_addr; 16881 struct hdd_adapter_create_param params = {0}; 16882 bool eht_capab = 0; 16883 16884 ucfg_mlme_get_dot11p_mode(hdd_ctx->psoc, &dot11p_mode); 16885 ucfg_psoc_mlme_get_11be_capab(hdd_ctx->psoc, &eht_capab); 16886 16887 /* Create only 802.11p interface? */ 16888 if (dot11p_mode == CFG_11P_STANDALONE) 16889 return hdd_open_ocb_interface(hdd_ctx); 16890 16891 mac_addr = wlan_hdd_get_intf_addr(hdd_ctx, QDF_STA_MODE); 16892 if (!mac_addr) 16893 return QDF_STATUS_E_INVAL; 16894 16895 if (eht_capab) { 16896 params.is_ml_adapter = true; 16897 hdd_adapter_open_set_max_active_links(¶ms); 16898 } 16899 16900 status = hdd_open_adapter_no_trans(hdd_ctx, QDF_STA_MODE, 16901 "wlan%d", mac_addr, 16902 ¶ms); 16903 if (QDF_IS_STATUS_ERROR(status)) { 16904 wlan_hdd_release_intf_addr(hdd_ctx, mac_addr); 16905 return status; 16906 } 16907 16908 /* opening concurrent STA is best effort, continue on error */ 16909 hdd_open_concurrent_interface(hdd_ctx); 16910 16911 status = hdd_open_p2p_interface(hdd_ctx); 16912 if (status) 16913 goto err_close_adapters; 16914 16915 /* 16916 * Create separate interface (wifi-aware0) for NAN. All NAN commands 16917 * should go on this new interface. 16918 */ 16919 if (wlan_hdd_is_vdev_creation_allowed(hdd_ctx->psoc)) { 16920 qdf_mem_zero(¶ms, sizeof(params)); 16921 mac_addr = wlan_hdd_get_intf_addr(hdd_ctx, QDF_NAN_DISC_MODE); 16922 if (!mac_addr) 16923 goto err_close_adapters; 16924 16925 status = hdd_open_adapter_no_trans(hdd_ctx, QDF_NAN_DISC_MODE, 16926 "wifi-aware%d", mac_addr, 16927 ¶ms); 16928 if (status) { 16929 wlan_hdd_release_intf_addr(hdd_ctx, mac_addr); 16930 goto err_close_adapters; 16931 } 16932 } 16933 /* Open 802.11p Interface */ 16934 if (dot11p_mode == CFG_11P_CONCURRENT) { 16935 status = hdd_open_ocb_interface(hdd_ctx); 16936 if (QDF_IS_STATUS_ERROR(status)) 16937 goto err_close_adapters; 16938 } 16939 16940 if (eht_capab) 16941 hdd_wlan_register_mlo_interfaces(hdd_ctx); 16942 16943 return QDF_STATUS_SUCCESS; 16944 16945 err_close_adapters: 16946 hdd_close_all_adapters(hdd_ctx, true); 16947 16948 return status; 16949 } 16950 16951 static QDF_STATUS hdd_open_adapters_for_ftm_mode(struct hdd_context *hdd_ctx) 16952 { 16953 QDF_STATUS status; 16954 uint8_t *mac_addr; 16955 struct hdd_adapter_create_param params = {0}; 16956 16957 mac_addr = wlan_hdd_get_intf_addr(hdd_ctx, QDF_FTM_MODE); 16958 if (!mac_addr) 16959 return QDF_STATUS_E_INVAL; 16960 16961 status = hdd_open_adapter_no_trans(hdd_ctx, QDF_FTM_MODE, 16962 "wlan%d", mac_addr, 16963 ¶ms); 16964 if (QDF_IS_STATUS_ERROR(status)) { 16965 wlan_hdd_release_intf_addr(hdd_ctx, mac_addr); 16966 return status; 16967 } 16968 16969 return QDF_STATUS_SUCCESS; 16970 } 16971 16972 static QDF_STATUS 16973 hdd_open_adapters_for_monitor_mode(struct hdd_context *hdd_ctx) 16974 { 16975 QDF_STATUS status; 16976 uint8_t *mac_addr; 16977 struct hdd_adapter_create_param params = {0}; 16978 16979 mac_addr = wlan_hdd_get_intf_addr(hdd_ctx, QDF_MONITOR_MODE); 16980 if (!mac_addr) 16981 return QDF_STATUS_E_INVAL; 16982 16983 status = hdd_open_adapter_no_trans(hdd_ctx, QDF_MONITOR_MODE, 16984 "wlan%d", mac_addr, 16985 ¶ms); 16986 if (QDF_IS_STATUS_ERROR(status)) { 16987 wlan_hdd_release_intf_addr(hdd_ctx, mac_addr); 16988 return status; 16989 } 16990 16991 return QDF_STATUS_SUCCESS; 16992 } 16993 16994 static QDF_STATUS hdd_open_adapters_for_epping_mode(struct hdd_context *hdd_ctx) 16995 { 16996 epping_enable_adapter(); 16997 return QDF_STATUS_SUCCESS; 16998 } 16999 17000 typedef QDF_STATUS (*hdd_open_mode_handler)(struct hdd_context *hdd_ctx); 17001 17002 static const hdd_open_mode_handler 17003 hdd_open_mode_handlers[QDF_GLOBAL_MAX_MODE] = { 17004 [QDF_GLOBAL_MISSION_MODE] = hdd_open_adapters_for_mission_mode, 17005 [QDF_GLOBAL_FTM_MODE] = hdd_open_adapters_for_ftm_mode, 17006 [QDF_GLOBAL_MONITOR_MODE] = hdd_open_adapters_for_monitor_mode, 17007 [QDF_GLOBAL_EPPING_MODE] = hdd_open_adapters_for_epping_mode, 17008 }; 17009 17010 static QDF_STATUS hdd_open_adapters_for_mode(struct hdd_context *hdd_ctx, 17011 enum QDF_GLOBAL_MODE driver_mode) 17012 { 17013 QDF_STATUS status; 17014 17015 if (driver_mode < 0 || 17016 driver_mode >= QDF_GLOBAL_MAX_MODE || 17017 !hdd_open_mode_handlers[driver_mode]) { 17018 hdd_err("Driver mode %d not supported", driver_mode); 17019 return -ENOTSUPP; 17020 } 17021 17022 hdd_hold_rtnl_lock(); 17023 status = hdd_open_mode_handlers[driver_mode](hdd_ctx); 17024 hdd_release_rtnl_lock(); 17025 17026 return status; 17027 } 17028 17029 int hdd_wlan_startup(struct hdd_context *hdd_ctx) 17030 { 17031 QDF_STATUS status; 17032 int errno; 17033 bool is_imps_enabled; 17034 17035 hdd_enter(); 17036 17037 qdf_nbuf_init_replenish_timer(); 17038 17039 status = wlan_hdd_cache_chann_mutex_create(hdd_ctx); 17040 if (QDF_IS_STATUS_ERROR(status)) 17041 return qdf_status_to_os_return(status); 17042 17043 #ifdef FEATURE_WLAN_CH_AVOID 17044 mutex_init(&hdd_ctx->avoid_freq_lock); 17045 #endif 17046 17047 osif_request_manager_init(); 17048 hdd_driver_memdump_init(); 17049 17050 errno = hdd_init_regulatory_update_event(hdd_ctx); 17051 if (errno) { 17052 hdd_err("Failed to initialize regulatory update event; errno:%d", 17053 errno); 17054 goto memdump_deinit; 17055 } 17056 17057 errno = hdd_wlan_start_modules(hdd_ctx, false); 17058 if (errno) { 17059 hdd_err("Failed to start modules; errno:%d", errno); 17060 goto memdump_deinit; 17061 } 17062 17063 if (hdd_get_conparam() == QDF_GLOBAL_EPPING_MODE) 17064 return 0; 17065 17066 wlan_hdd_update_wiphy(hdd_ctx); 17067 17068 hdd_ctx->mac_handle = cds_get_context(QDF_MODULE_ID_SME); 17069 if (!hdd_ctx->mac_handle) 17070 goto stop_modules; 17071 17072 errno = hdd_wiphy_init(hdd_ctx); 17073 if (errno) { 17074 hdd_err("Failed to initialize wiphy; errno:%d", errno); 17075 goto stop_modules; 17076 } 17077 17078 errno = hdd_initialize_mac_address(hdd_ctx); 17079 if (errno) { 17080 hdd_err("MAC initializtion failed: %d", errno); 17081 goto unregister_wiphy; 17082 } 17083 17084 errno = register_netdevice_notifier(&hdd_netdev_notifier); 17085 if (errno) { 17086 hdd_err("register_netdevice_notifier failed; errno:%d", errno); 17087 goto unregister_wiphy; 17088 } 17089 17090 wlan_hdd_update_11n_mode(hdd_ctx); 17091 17092 hdd_lpass_notify_wlan_version(hdd_ctx); 17093 17094 status = wlansap_global_init(); 17095 if (QDF_IS_STATUS_ERROR(status)) 17096 goto unregister_notifiers; 17097 17098 ucfg_mlme_is_imps_enabled(hdd_ctx->psoc, &is_imps_enabled); 17099 hdd_set_idle_ps_config(hdd_ctx, is_imps_enabled); 17100 hdd_debugfs_mws_coex_info_init(hdd_ctx); 17101 hdd_debugfs_ini_config_init(hdd_ctx); 17102 wlan_hdd_debugfs_unit_test_host_create(hdd_ctx); 17103 wlan_hdd_create_mib_stats_lock(); 17104 wlan_cfg80211_init_interop_issues_ap(hdd_ctx->pdev); 17105 17106 hdd_exit(); 17107 17108 return 0; 17109 17110 unregister_notifiers: 17111 unregister_netdevice_notifier(&hdd_netdev_notifier); 17112 17113 unregister_wiphy: 17114 qdf_dp_trace_deinit(); 17115 wiphy_unregister(hdd_ctx->wiphy); 17116 17117 stop_modules: 17118 hdd_wlan_stop_modules(hdd_ctx, false); 17119 17120 memdump_deinit: 17121 hdd_driver_memdump_deinit(); 17122 osif_request_manager_deinit(); 17123 qdf_nbuf_deinit_replenish_timer(); 17124 17125 if (cds_is_fw_down()) 17126 hdd_err("Not setting the complete event as fw is down"); 17127 else 17128 hdd_start_complete(errno); 17129 17130 hdd_exit(); 17131 17132 return errno; 17133 } 17134 17135 QDF_STATUS hdd_psoc_create_vdevs(struct hdd_context *hdd_ctx) 17136 { 17137 enum QDF_GLOBAL_MODE driver_mode = hdd_get_conparam(); 17138 QDF_STATUS status; 17139 17140 status = hdd_open_adapters_for_mode(hdd_ctx, driver_mode); 17141 if (QDF_IS_STATUS_ERROR(status)) { 17142 hdd_err("Failed to create vdevs; status:%d", status); 17143 return status; 17144 } 17145 17146 ucfg_dp_try_set_rps_cpu_mask(hdd_ctx->psoc); 17147 17148 if (driver_mode != QDF_GLOBAL_FTM_MODE && 17149 driver_mode != QDF_GLOBAL_EPPING_MODE) 17150 hdd_psoc_idle_timer_start(hdd_ctx); 17151 17152 return QDF_STATUS_SUCCESS; 17153 } 17154 17155 /** 17156 * hdd_wlan_update_target_info() - update target type info 17157 * @hdd_ctx: HDD context 17158 * @context: hif context 17159 * 17160 * Update target info received from firmware in hdd context 17161 * Return:None 17162 */ 17163 17164 void hdd_wlan_update_target_info(struct hdd_context *hdd_ctx, void *context) 17165 { 17166 struct hif_target_info *tgt_info = hif_get_target_info_handle(context); 17167 17168 if (!tgt_info) { 17169 hdd_err("Target info is Null"); 17170 return; 17171 } 17172 17173 hdd_ctx->target_type = tgt_info->target_type; 17174 } 17175 17176 #ifdef WLAN_FEATURE_MOTION_DETECTION 17177 /** 17178 * hdd_md_host_evt_cb - Callback for Motion Detection Event 17179 * @ctx: HDD context 17180 * @event: motion detect event 17181 * 17182 * Callback for Motion Detection Event. Re-enables Motion 17183 * Detection again upon event 17184 * 17185 * Return: QDF_STATUS QDF_STATUS_SUCCESS on Success and 17186 * QDF_STATUS_E_FAILURE on failure 17187 */ 17188 QDF_STATUS hdd_md_host_evt_cb(void *ctx, struct sir_md_evt *event) 17189 { 17190 struct hdd_adapter *adapter; 17191 struct hdd_context *hdd_ctx; 17192 struct sme_motion_det_en motion_det; 17193 struct wlan_hdd_link_info *link_info; 17194 17195 if (!ctx || !event) 17196 return QDF_STATUS_E_INVAL; 17197 17198 hdd_ctx = (struct hdd_context *)ctx; 17199 if (wlan_hdd_validate_context(hdd_ctx)) 17200 return QDF_STATUS_E_INVAL; 17201 17202 link_info = hdd_get_link_info_by_vdev(hdd_ctx, event->vdev_id); 17203 if (!link_info || 17204 WLAN_HDD_ADAPTER_MAGIC != link_info->adapter->magic) { 17205 hdd_err("Invalid adapter or adapter has invalid magic"); 17206 return QDF_STATUS_E_INVAL; 17207 } 17208 17209 adapter = link_info->adapter; 17210 /* When motion is detected, reset the motion_det_in_progress flag */ 17211 if (event->status) 17212 adapter->motion_det_in_progress = false; 17213 17214 hdd_debug("Motion Detection CB vdev_id=%u, status=%u", 17215 event->vdev_id, event->status); 17216 17217 if (adapter->motion_detection_mode) { 17218 motion_det.vdev_id = event->vdev_id; 17219 motion_det.enable = 1; 17220 hdd_debug("Motion Detect CB -> Enable Motion Detection again"); 17221 sme_motion_det_enable(hdd_ctx->mac_handle, &motion_det); 17222 } 17223 17224 return QDF_STATUS_SUCCESS; 17225 } 17226 17227 /** 17228 * hdd_md_bl_evt_cb - Callback for Motion Detection Baseline Event 17229 * @ctx: HDD context 17230 * @event: motion detect baseline event 17231 * 17232 * Callback for Motion Detection Baseline completion 17233 * 17234 * Return: QDF_STATUS QDF_STATUS_SUCCESS on Success and 17235 * QDF_STATUS_E_FAILURE on failure 17236 */ 17237 QDF_STATUS hdd_md_bl_evt_cb(void *ctx, struct sir_md_bl_evt *event) 17238 { 17239 struct hdd_context *hdd_ctx; 17240 struct wlan_hdd_link_info *link_info; 17241 17242 if (!ctx || !event) 17243 return QDF_STATUS_E_INVAL; 17244 17245 hdd_ctx = (struct hdd_context *)ctx; 17246 if (wlan_hdd_validate_context(hdd_ctx)) 17247 return QDF_STATUS_E_INVAL; 17248 17249 link_info = hdd_get_link_info_by_vdev(hdd_ctx, event->vdev_id); 17250 if (!link_info || 17251 WLAN_HDD_ADAPTER_MAGIC != link_info->adapter->magic) { 17252 hdd_err("Invalid adapter or adapter has invalid magic"); 17253 return QDF_STATUS_E_INVAL; 17254 } 17255 17256 hdd_debug("Motion Detection Baseline CB vdev id=%u, baseline val = %d", 17257 event->vdev_id, event->bl_baseline_value); 17258 17259 link_info->adapter->motion_det_baseline_value = 17260 event->bl_baseline_value; 17261 17262 return QDF_STATUS_SUCCESS; 17263 } 17264 #endif /* WLAN_FEATURE_MOTION_DETECTION */ 17265 17266 /** 17267 * hdd_ssr_on_pagefault_cb - Callback to trigger SSR because 17268 * of host wake up by firmware with reason pagefault 17269 * 17270 * Return: None 17271 */ 17272 static void hdd_ssr_on_pagefault_cb(void) 17273 { 17274 uint32_t ssr_frequency_on_pagefault; 17275 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 17276 qdf_time_t curr_time; 17277 17278 hdd_enter(); 17279 17280 if (!hdd_ctx) 17281 return; 17282 17283 ssr_frequency_on_pagefault = 17284 ucfg_pmo_get_ssr_frequency_on_pagefault(hdd_ctx->psoc); 17285 17286 curr_time = qdf_get_time_of_the_day_ms(); 17287 17288 if (!hdd_ctx->last_pagefault_ssr_time || 17289 (curr_time - hdd_ctx->last_pagefault_ssr_time) >= 17290 ssr_frequency_on_pagefault) { 17291 hdd_info("curr_time %lu last_pagefault_ssr_time %lu ssr_frequency %d", 17292 curr_time, hdd_ctx->last_pagefault_ssr_time, 17293 ssr_frequency_on_pagefault); 17294 hdd_ctx->last_pagefault_ssr_time = curr_time; 17295 cds_trigger_recovery(QDF_HOST_WAKEUP_REASON_PAGEFAULT); 17296 } 17297 } 17298 17299 /** 17300 * hdd_register_cb - Register HDD callbacks. 17301 * @hdd_ctx: HDD context 17302 * 17303 * Register the HDD callbacks to CDS/SME. 17304 * 17305 * Return: 0 for success or Error code for failure 17306 */ 17307 int hdd_register_cb(struct hdd_context *hdd_ctx) 17308 { 17309 QDF_STATUS status; 17310 int ret = 0; 17311 mac_handle_t mac_handle; 17312 17313 hdd_enter(); 17314 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) { 17315 hdd_err("in ftm mode, no need to register callbacks"); 17316 return ret; 17317 } 17318 17319 mac_handle = hdd_ctx->mac_handle; 17320 17321 sme_register_oem_data_rsp_callback(mac_handle, 17322 hdd_send_oem_data_rsp_msg); 17323 17324 sme_register_mgmt_frame_ind_callback(mac_handle, 17325 hdd_indicate_mgmt_frame); 17326 sme_set_tsfcb(mac_handle, hdd_get_tsf_cb, hdd_ctx); 17327 sme_stats_ext_register_callback(mac_handle, 17328 wlan_hdd_cfg80211_stats_ext_callback); 17329 17330 sme_ext_scan_register_callback(mac_handle, 17331 wlan_hdd_cfg80211_extscan_callback); 17332 sme_stats_ext2_register_callback(mac_handle, 17333 wlan_hdd_cfg80211_stats_ext2_callback); 17334 17335 sme_multi_client_ll_rsp_register_callback(mac_handle, 17336 hdd_latency_level_event_handler_cb); 17337 17338 sme_set_rssi_threshold_breached_cb(mac_handle, 17339 hdd_rssi_threshold_breached); 17340 17341 sme_set_link_layer_stats_ind_cb(mac_handle, 17342 wlan_hdd_cfg80211_link_layer_stats_callback); 17343 17344 sme_rso_cmd_status_cb(mac_handle, wlan_hdd_rso_cmd_status_cb); 17345 17346 sme_set_link_layer_ext_cb(mac_handle, 17347 wlan_hdd_cfg80211_link_layer_stats_ext_callback); 17348 sme_update_hidden_ssid_status_cb(mac_handle, 17349 hdd_hidden_ssid_enable_roaming); 17350 17351 status = sme_set_lost_link_info_cb(mac_handle, 17352 hdd_lost_link_info_cb); 17353 17354 wlan_hdd_register_cp_stats_cb(hdd_ctx); 17355 hdd_dcs_register_cb(hdd_ctx); 17356 17357 hdd_thermal_register_callbacks(hdd_ctx); 17358 /* print error and not block the startup process */ 17359 if (!QDF_IS_STATUS_SUCCESS(status)) 17360 hdd_err("set lost link info callback failed"); 17361 17362 ret = hdd_register_data_stall_detect_cb(); 17363 if (ret) { 17364 hdd_err("Register data stall detect detect callback failed."); 17365 return ret; 17366 } 17367 17368 wlan_hdd_dcc_register_for_dcc_stats_event(hdd_ctx); 17369 17370 sme_register_set_connection_info_cb(mac_handle, 17371 hdd_set_connection_in_progress, 17372 hdd_is_connection_in_progress); 17373 17374 status = sme_set_bt_activity_info_cb(mac_handle, 17375 hdd_bt_activity_cb); 17376 if (!QDF_IS_STATUS_SUCCESS(status)) 17377 hdd_err("set bt activity info callback failed"); 17378 17379 status = sme_register_tx_queue_cb(mac_handle, 17380 hdd_tx_queue_cb); 17381 if (!QDF_IS_STATUS_SUCCESS(status)) 17382 hdd_err("Register tx queue callback failed"); 17383 17384 #ifdef WLAN_FEATURE_MOTION_DETECTION 17385 sme_set_md_host_evt_cb(mac_handle, hdd_md_host_evt_cb, (void *)hdd_ctx); 17386 sme_set_md_bl_evt_cb(mac_handle, hdd_md_bl_evt_cb, (void *)hdd_ctx); 17387 #endif /* WLAN_FEATURE_MOTION_DETECTION */ 17388 17389 mac_register_session_open_close_cb(hdd_ctx->mac_handle, 17390 hdd_sme_close_session_callback, 17391 hdd_common_roam_callback); 17392 17393 sme_set_roam_scan_ch_event_cb(mac_handle, hdd_get_roam_scan_ch_cb); 17394 status = sme_set_monitor_mode_cb(mac_handle, 17395 hdd_sme_monitor_mode_callback); 17396 if (QDF_IS_STATUS_ERROR(status)) 17397 hdd_err_rl("Register monitor mode callback failed"); 17398 17399 status = sme_set_beacon_latency_event_cb(mac_handle, 17400 hdd_beacon_latency_event_cb); 17401 if (QDF_IS_STATUS_ERROR(status)) 17402 hdd_err_rl("Register beacon latency event callback failed"); 17403 17404 sme_async_oem_event_init(mac_handle, 17405 hdd_oem_event_async_cb); 17406 17407 sme_register_ssr_on_pagefault_cb(mac_handle, hdd_ssr_on_pagefault_cb); 17408 17409 hdd_exit(); 17410 17411 return ret; 17412 } 17413 17414 /** 17415 * hdd_deregister_cb() - De-Register HDD callbacks. 17416 * @hdd_ctx: HDD context 17417 * 17418 * De-Register the HDD callbacks to CDS/SME. 17419 * 17420 * Return: void 17421 */ 17422 void hdd_deregister_cb(struct hdd_context *hdd_ctx) 17423 { 17424 QDF_STATUS status; 17425 int ret; 17426 mac_handle_t mac_handle; 17427 17428 hdd_enter(); 17429 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) { 17430 hdd_err("in ftm mode, no need to deregister callbacks"); 17431 return; 17432 } 17433 17434 mac_handle = hdd_ctx->mac_handle; 17435 17436 sme_deregister_ssr_on_pagefault_cb(mac_handle); 17437 17438 sme_async_oem_event_deinit(mac_handle); 17439 17440 sme_deregister_tx_queue_cb(mac_handle); 17441 17442 sme_reset_link_layer_stats_ind_cb(mac_handle); 17443 sme_reset_rssi_threshold_breached_cb(mac_handle); 17444 17445 sme_stats_ext_deregister_callback(mac_handle); 17446 17447 status = sme_reset_tsfcb(mac_handle); 17448 if (!QDF_IS_STATUS_SUCCESS(status)) 17449 hdd_err("Failed to de-register tsfcb the callback:%d", 17450 status); 17451 17452 ret = hdd_deregister_data_stall_detect_cb(); 17453 if (ret) 17454 hdd_err("Failed to de-register data stall detect event callback"); 17455 hdd_thermal_unregister_callbacks(hdd_ctx); 17456 sme_deregister_oem_data_rsp_callback(mac_handle); 17457 sme_multi_client_ll_rsp_deregister_callback(mac_handle); 17458 17459 hdd_exit(); 17460 } 17461 17462 /** 17463 * hdd_softap_sta_deauth() - handle deauth req from HDD 17464 * @adapter: Pointer to the HDD adapter 17465 * @param: Params to the operation 17466 * 17467 * This to take counter measure to handle deauth req from HDD 17468 * 17469 * Return: None 17470 */ 17471 QDF_STATUS hdd_softap_sta_deauth(struct hdd_adapter *adapter, 17472 struct csr_del_sta_params *param) 17473 { 17474 QDF_STATUS qdf_status = QDF_STATUS_E_FAULT; 17475 struct hdd_context *hdd_ctx; 17476 bool is_sap_bcast_deauth_enabled = false; 17477 17478 hdd_ctx = WLAN_HDD_GET_CTX(adapter); 17479 if (!hdd_ctx) { 17480 hdd_err("hdd_ctx is NULL"); 17481 return QDF_STATUS_E_INVAL; 17482 } 17483 17484 ucfg_mlme_get_sap_bcast_deauth_enabled(hdd_ctx->psoc, 17485 &is_sap_bcast_deauth_enabled); 17486 17487 hdd_enter(); 17488 17489 hdd_debug("sap_bcast_deauth_enabled %d", is_sap_bcast_deauth_enabled); 17490 /* Ignore request to deauth bcmc station */ 17491 if (!is_sap_bcast_deauth_enabled) 17492 if (param->peerMacAddr.bytes[0] & 0x1) 17493 return qdf_status; 17494 17495 qdf_status = 17496 wlansap_deauth_sta(WLAN_HDD_GET_SAP_CTX_PTR(adapter->deflink), 17497 param); 17498 17499 hdd_exit(); 17500 return qdf_status; 17501 } 17502 17503 /** 17504 * hdd_softap_sta_disassoc() - take counter measure to handle deauth req from HDD 17505 * @adapter: Pointer to the HDD 17506 * @param: pointer to station deletion parameters 17507 * 17508 * This to take counter measure to handle deauth req from HDD 17509 * 17510 * Return: None 17511 */ 17512 void hdd_softap_sta_disassoc(struct hdd_adapter *adapter, 17513 struct csr_del_sta_params *param) 17514 { 17515 hdd_enter(); 17516 17517 /* Ignore request to disassoc bcmc station */ 17518 if (param->peerMacAddr.bytes[0] & 0x1) 17519 return; 17520 17521 wlansap_disassoc_sta(WLAN_HDD_GET_SAP_CTX_PTR(adapter->deflink), 17522 param); 17523 } 17524 17525 void 17526 wlan_hdd_set_roaming_state(struct wlan_hdd_link_info *cur_link_info, 17527 enum wlan_cm_rso_control_requestor rso_op_requestor, 17528 bool enab_roam) 17529 { 17530 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(cur_link_info->adapter); 17531 struct hdd_adapter *adapter = NULL, *next_adapter = NULL; 17532 wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_DISABLE_ROAMING; 17533 uint8_t vdev_id, cur_vdev_id = cur_link_info->vdev_id; 17534 struct wlan_hdd_link_info *link_info; 17535 17536 if (!policy_mgr_is_sta_active_connection_exists(hdd_ctx->psoc)) 17537 return; 17538 17539 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 17540 dbgid) { 17541 hdd_adapter_for_each_active_link_info(adapter, link_info) { 17542 vdev_id = link_info->vdev_id; 17543 if (cur_vdev_id != link_info->vdev_id && 17544 adapter->device_mode == QDF_STA_MODE && 17545 hdd_cm_is_vdev_associated(link_info)) { 17546 if (enab_roam) { 17547 hdd_debug("%d Enable roaming", vdev_id); 17548 sme_start_roaming(hdd_ctx->mac_handle, 17549 vdev_id, 17550 REASON_DRIVER_ENABLED, 17551 rso_op_requestor); 17552 } else { 17553 hdd_debug("%d Disable roaming", 17554 vdev_id); 17555 sme_stop_roaming(hdd_ctx->mac_handle, 17556 vdev_id, 17557 REASON_DRIVER_DISABLED, 17558 rso_op_requestor); 17559 } 17560 } 17561 } 17562 hdd_adapter_dev_put_debug(adapter, dbgid); 17563 } 17564 } 17565 17566 /** 17567 * nl_srv_bcast_svc() - Wrapper function to send bcast msgs to SVC mcast group 17568 * @skb: sk buffer pointer 17569 * 17570 * Sends the bcast message to SVC multicast group with generic nl socket 17571 * if CNSS_GENL is enabled. Else, use the legacy netlink socket to send. 17572 * 17573 * Return: None 17574 */ 17575 static void nl_srv_bcast_svc(struct sk_buff *skb) 17576 { 17577 #ifdef CNSS_GENL 17578 nl_srv_bcast(skb, CLD80211_MCGRP_SVC_MSGS, WLAN_NL_MSG_SVC); 17579 #else 17580 nl_srv_bcast(skb); 17581 #endif 17582 } 17583 17584 void wlan_hdd_send_svc_nlink_msg(int radio, int type, void *data, int len) 17585 { 17586 struct sk_buff *skb; 17587 struct nlmsghdr *nlh; 17588 tAniMsgHdr *ani_hdr; 17589 void *nl_data = NULL; 17590 int flags = GFP_KERNEL; 17591 struct radio_index_tlv *radio_info; 17592 int tlv_len; 17593 17594 if (in_interrupt() || irqs_disabled() || in_atomic()) 17595 flags = GFP_ATOMIC; 17596 17597 skb = alloc_skb(NLMSG_SPACE(WLAN_NL_MAX_PAYLOAD), flags); 17598 17599 if (!skb) 17600 return; 17601 17602 nlh = (struct nlmsghdr *)skb->data; 17603 nlh->nlmsg_pid = 0; /* from kernel */ 17604 nlh->nlmsg_flags = 0; 17605 nlh->nlmsg_seq = 0; 17606 nlh->nlmsg_type = WLAN_NL_MSG_SVC; 17607 17608 ani_hdr = NLMSG_DATA(nlh); 17609 ani_hdr->type = type; 17610 17611 switch (type) { 17612 case WLAN_SVC_FW_CRASHED_IND: 17613 case WLAN_SVC_FW_SHUTDOWN_IND: 17614 case WLAN_SVC_LTE_COEX_IND: 17615 case WLAN_SVC_WLAN_AUTO_SHUTDOWN_IND: 17616 case WLAN_SVC_WLAN_AUTO_SHUTDOWN_CANCEL_IND: 17617 ani_hdr->length = 0; 17618 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr))); 17619 break; 17620 case WLAN_SVC_WLAN_STATUS_IND: 17621 case WLAN_SVC_WLAN_VERSION_IND: 17622 case WLAN_SVC_DFS_CAC_START_IND: 17623 case WLAN_SVC_DFS_CAC_END_IND: 17624 case WLAN_SVC_DFS_RADAR_DETECT_IND: 17625 case WLAN_SVC_DFS_ALL_CHANNEL_UNAVAIL_IND: 17626 case WLAN_SVC_WLAN_TP_IND: 17627 case WLAN_SVC_WLAN_TP_TX_IND: 17628 case WLAN_SVC_RPS_ENABLE_IND: 17629 case WLAN_SVC_CORE_MINFREQ: 17630 ani_hdr->length = len; 17631 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr) + len)); 17632 nl_data = (char *)ani_hdr + sizeof(tAniMsgHdr); 17633 memcpy(nl_data, data, len); 17634 break; 17635 17636 default: 17637 hdd_err("WLAN SVC: Attempt to send unknown nlink message %d", 17638 type); 17639 kfree_skb(skb); 17640 return; 17641 } 17642 17643 /* 17644 * Add radio index at the end of the svc event in TLV format 17645 * to maintain the backward compatibility with userspace 17646 * applications. 17647 */ 17648 17649 tlv_len = 0; 17650 17651 if ((sizeof(*ani_hdr) + len + sizeof(struct radio_index_tlv)) 17652 < WLAN_NL_MAX_PAYLOAD) { 17653 radio_info = (struct radio_index_tlv *)((char *) ani_hdr + 17654 sizeof(*ani_hdr) + len); 17655 radio_info->type = (unsigned short) WLAN_SVC_WLAN_RADIO_INDEX; 17656 radio_info->length = (unsigned short) sizeof(radio_info->radio); 17657 radio_info->radio = radio; 17658 tlv_len = sizeof(*radio_info); 17659 hdd_debug("Added radio index tlv - radio index %d", 17660 radio_info->radio); 17661 } 17662 17663 nlh->nlmsg_len += tlv_len; 17664 skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr) + len + tlv_len)); 17665 17666 nl_srv_bcast_svc(skb); 17667 } 17668 17669 #ifdef FEATURE_WLAN_AUTO_SHUTDOWN 17670 void wlan_hdd_auto_shutdown_cb(void) 17671 { 17672 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 17673 17674 if (!hdd_ctx) 17675 return; 17676 17677 hdd_debug("Wlan Idle. Sending Shutdown event.."); 17678 wlan_hdd_send_svc_nlink_msg(hdd_ctx->radio_index, 17679 WLAN_SVC_WLAN_AUTO_SHUTDOWN_IND, NULL, 0); 17680 } 17681 17682 void wlan_hdd_auto_shutdown_enable(struct hdd_context *hdd_ctx, bool enable) 17683 { 17684 struct hdd_adapter *adapter, *next_adapter = NULL; 17685 bool ap_connected = false, sta_connected = false; 17686 mac_handle_t mac_handle; 17687 struct wlan_hdd_link_info *link_info; 17688 struct hdd_ap_ctx *ap_ctx; 17689 wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_AUTO_SHUTDOWN_ENABLE; 17690 17691 mac_handle = hdd_ctx->mac_handle; 17692 if (!mac_handle) 17693 return; 17694 17695 if (hdd_ctx->config->wlan_auto_shutdown == 0) 17696 return; 17697 17698 if (enable == false) { 17699 if (sme_set_auto_shutdown_timer(mac_handle, 0) != 17700 QDF_STATUS_SUCCESS) { 17701 hdd_err("Failed to stop wlan auto shutdown timer"); 17702 } 17703 wlan_hdd_send_svc_nlink_msg(hdd_ctx->radio_index, 17704 WLAN_SVC_WLAN_AUTO_SHUTDOWN_CANCEL_IND, NULL, 0); 17705 return; 17706 } 17707 17708 /* To enable shutdown timer check conncurrency */ 17709 if (!policy_mgr_concurrent_open_sessions_running(hdd_ctx->psoc)) 17710 goto start_timer; 17711 17712 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, 17713 next_adapter, dbgid) { 17714 hdd_adapter_for_each_active_link_info(adapter, link_info) { 17715 if (adapter->device_mode == QDF_STA_MODE && 17716 hdd_cm_is_vdev_associated(link_info)) { 17717 sta_connected = true; 17718 hdd_adapter_dev_put_debug(adapter, dbgid); 17719 if (next_adapter) 17720 hdd_adapter_dev_put_debug(next_adapter, 17721 dbgid); 17722 break; 17723 } 17724 17725 if (adapter->device_mode == QDF_SAP_MODE) { 17726 ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(link_info); 17727 if (ap_ctx->ap_active == true) { 17728 ap_connected = true; 17729 hdd_adapter_dev_put_debug(adapter, 17730 dbgid); 17731 if (next_adapter) 17732 hdd_adapter_dev_put_debug( 17733 next_adapter, 17734 dbgid); 17735 break; 17736 } 17737 } 17738 } 17739 hdd_adapter_dev_put_debug(adapter, dbgid); 17740 } 17741 17742 start_timer: 17743 if (ap_connected == true || sta_connected == true) { 17744 hdd_debug("CC Session active. Shutdown timer not enabled"); 17745 return; 17746 } 17747 17748 if (sme_set_auto_shutdown_timer(mac_handle, 17749 hdd_ctx->config->wlan_auto_shutdown) 17750 != QDF_STATUS_SUCCESS) 17751 hdd_err("Failed to start wlan auto shutdown timer"); 17752 else 17753 hdd_info("Auto Shutdown timer for %d seconds enabled", 17754 hdd_ctx->config->wlan_auto_shutdown); 17755 } 17756 #endif 17757 17758 struct hdd_adapter * 17759 hdd_get_con_sap_adapter(struct hdd_adapter *this_sap_adapter, 17760 bool check_start_bss) 17761 { 17762 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(this_sap_adapter); 17763 struct hdd_adapter *adapter, *next_adapter = NULL; 17764 wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_GET_CON_SAP_ADAPTER; 17765 struct wlan_hdd_link_info *link_info; 17766 17767 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 17768 dbgid) { 17769 if ((adapter->device_mode == QDF_SAP_MODE || 17770 adapter->device_mode == QDF_P2P_GO_MODE) && 17771 adapter != this_sap_adapter) { 17772 hdd_adapter_for_each_active_link_info(adapter, 17773 link_info) { 17774 if (!check_start_bss) { 17775 hdd_adapter_dev_put_debug(adapter, 17776 dbgid); 17777 if (next_adapter) 17778 hdd_adapter_dev_put_debug( 17779 next_adapter, 17780 dbgid); 17781 return adapter; 17782 } 17783 if (test_bit(SOFTAP_BSS_STARTED, 17784 &link_info->link_flags)) { 17785 hdd_adapter_dev_put_debug(adapter, 17786 dbgid); 17787 if (next_adapter) 17788 hdd_adapter_dev_put_debug( 17789 next_adapter, 17790 dbgid); 17791 return adapter; 17792 } 17793 } 17794 } 17795 hdd_adapter_dev_put_debug(adapter, dbgid); 17796 } 17797 17798 return NULL; 17799 } 17800 17801 static inline bool hdd_adapter_is_sta(struct hdd_adapter *adapter) 17802 { 17803 return adapter->device_mode == QDF_STA_MODE || 17804 adapter->device_mode == QDF_P2P_CLIENT_MODE; 17805 } 17806 17807 bool hdd_is_any_adapter_connected(struct hdd_context *hdd_ctx) 17808 { 17809 struct hdd_adapter *adapter, *next_adapter = NULL; 17810 wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_IS_ANY_ADAPTER_CONNECTED; 17811 struct wlan_hdd_link_info *link_info; 17812 17813 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 17814 dbgid) { 17815 hdd_adapter_for_each_active_link_info(adapter, link_info) { 17816 if (hdd_adapter_is_sta(adapter) && 17817 hdd_cm_is_vdev_associated(link_info)) { 17818 hdd_adapter_dev_put_debug(adapter, dbgid); 17819 if (next_adapter) 17820 hdd_adapter_dev_put_debug(next_adapter, 17821 dbgid); 17822 return true; 17823 } 17824 17825 if (hdd_adapter_is_ap(adapter) && 17826 WLAN_HDD_GET_AP_CTX_PTR(link_info)->ap_active) { 17827 hdd_adapter_dev_put_debug(adapter, dbgid); 17828 if (next_adapter) 17829 hdd_adapter_dev_put_debug(next_adapter, 17830 dbgid); 17831 return true; 17832 } 17833 17834 if (adapter->device_mode == QDF_NDI_MODE && 17835 hdd_cm_is_vdev_associated(link_info)) { 17836 hdd_adapter_dev_put_debug(adapter, dbgid); 17837 if (next_adapter) 17838 hdd_adapter_dev_put_debug(next_adapter, 17839 dbgid); 17840 return true; 17841 } 17842 } 17843 hdd_adapter_dev_put_debug(adapter, dbgid); 17844 } 17845 17846 return false; 17847 } 17848 17849 #if defined MSM_PLATFORM && (LINUX_VERSION_CODE <= KERNEL_VERSION(4, 19, 0)) 17850 /** 17851 * hdd_inform_stop_sap() - call cfg80211 API to stop SAP 17852 * @adapter: pointer to adapter 17853 * 17854 * This function calls cfg80211 API to stop SAP 17855 * 17856 * Return: None 17857 */ 17858 static void hdd_inform_stop_sap(struct hdd_adapter *adapter) 17859 { 17860 hdd_debug("SAP stopped due to invalid channel vdev id %d", 17861 wlan_vdev_get_id(adapter->deflink->vdev)); 17862 cfg80211_ap_stopped(adapter->dev, GFP_KERNEL); 17863 } 17864 17865 #else 17866 static void hdd_inform_stop_sap(struct hdd_adapter *adapter) 17867 { 17868 hdd_debug("SAP stopped due to invalid channel vdev id %d", 17869 wlan_vdev_get_id(adapter->deflink->vdev)); 17870 cfg80211_stop_iface(adapter->hdd_ctx->wiphy, &adapter->wdev, 17871 GFP_KERNEL); 17872 } 17873 #endif 17874 17875 /** 17876 * wlan_hdd_stop_sap() - This function stops bss of SAP. 17877 * @ap_adapter: SAP adapter 17878 * 17879 * This function will process the stopping of sap adapter. 17880 * 17881 * Return: None 17882 */ 17883 void wlan_hdd_stop_sap(struct hdd_adapter *ap_adapter) 17884 { 17885 struct hdd_ap_ctx *hdd_ap_ctx; 17886 struct hdd_hostapd_state *hostapd_state; 17887 QDF_STATUS qdf_status; 17888 struct hdd_context *hdd_ctx; 17889 17890 if (!ap_adapter) { 17891 hdd_err("ap_adapter is NULL here"); 17892 return; 17893 } 17894 17895 hdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(ap_adapter->deflink); 17896 hdd_ctx = WLAN_HDD_GET_CTX(ap_adapter); 17897 if (wlan_hdd_validate_context(hdd_ctx)) 17898 return; 17899 17900 mutex_lock(&hdd_ctx->sap_lock); 17901 if (test_bit(SOFTAP_BSS_STARTED, &ap_adapter->deflink->link_flags)) { 17902 wlan_hdd_del_station(ap_adapter, NULL); 17903 hostapd_state = 17904 WLAN_HDD_GET_HOSTAP_STATE_PTR(ap_adapter->deflink); 17905 hdd_debug("Now doing SAP STOPBSS"); 17906 qdf_event_reset(&hostapd_state->qdf_stop_bss_event); 17907 if (QDF_STATUS_SUCCESS == wlansap_stop_bss(hdd_ap_ctx-> 17908 sap_context)) { 17909 qdf_status = qdf_wait_single_event(&hostapd_state-> 17910 qdf_stop_bss_event, 17911 SME_CMD_STOP_BSS_TIMEOUT); 17912 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { 17913 mutex_unlock(&hdd_ctx->sap_lock); 17914 hdd_err("SAP Stop Failed"); 17915 return; 17916 } 17917 } 17918 clear_bit(SOFTAP_BSS_STARTED, &ap_adapter->deflink->link_flags); 17919 policy_mgr_decr_session_set_pcl(hdd_ctx->psoc, 17920 ap_adapter->device_mode, 17921 ap_adapter->deflink->vdev_id); 17922 hdd_green_ap_start_state_mc(hdd_ctx, ap_adapter->device_mode, 17923 false); 17924 hdd_inform_stop_sap(ap_adapter); 17925 hdd_debug("SAP Stop Success"); 17926 } else { 17927 hdd_err("Can't stop ap because its not started"); 17928 } 17929 mutex_unlock(&hdd_ctx->sap_lock); 17930 } 17931 17932 #if defined(WLAN_FEATURE_11BE_MLO) && defined(CFG80211_11BE_BASIC) 17933 /** 17934 * wlan_hdd_mlo_sap_reinit() - handle mlo scenario for ssr 17935 * @link_info: Pointer of link_info in adapter 17936 * 17937 * Return: QDF_STATUS 17938 */ 17939 static QDF_STATUS wlan_hdd_mlo_sap_reinit(struct wlan_hdd_link_info *link_info) 17940 { 17941 struct hdd_context *hdd_ctx = link_info->adapter->hdd_ctx; 17942 struct sap_config *config = &link_info->session.ap.sap_config; 17943 17944 if (config->mlo_sap) { 17945 if (!mlo_ap_vdev_attach(link_info->vdev, config->link_id, 17946 config->num_link)) { 17947 hdd_err("SAP mlo mgr attach fail"); 17948 return QDF_STATUS_E_INVAL; 17949 } 17950 } 17951 17952 if (!policy_mgr_is_mlo_sap_concurrency_allowed(hdd_ctx->psoc, 17953 config->mlo_sap, 17954 wlan_vdev_get_id(link_info->vdev))) { 17955 hdd_err("MLO SAP concurrency check fails"); 17956 return QDF_STATUS_E_INVAL; 17957 } 17958 17959 return QDF_STATUS_SUCCESS; 17960 } 17961 #else 17962 static inline QDF_STATUS 17963 wlan_hdd_mlo_sap_reinit(struct wlan_hdd_link_info *link_info) 17964 { 17965 return QDF_STATUS_SUCCESS; 17966 } 17967 #endif 17968 17969 void wlan_hdd_start_sap(struct wlan_hdd_link_info *link_info, bool reinit) 17970 { 17971 struct hdd_ap_ctx *ap_ctx; 17972 struct hdd_hostapd_state *hostapd_state; 17973 QDF_STATUS qdf_status; 17974 struct hdd_context *hdd_ctx; 17975 struct sap_config *sap_config; 17976 struct hdd_adapter *ap_adapter = link_info->adapter; 17977 17978 if (QDF_SAP_MODE != ap_adapter->device_mode) { 17979 hdd_err("SoftAp role has not been enabled"); 17980 return; 17981 } 17982 17983 hdd_ctx = WLAN_HDD_GET_CTX(ap_adapter); 17984 ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(link_info); 17985 hostapd_state = WLAN_HDD_GET_HOSTAP_STATE_PTR(link_info); 17986 sap_config = &ap_ctx->sap_config; 17987 17988 mutex_lock(&hdd_ctx->sap_lock); 17989 if (test_bit(SOFTAP_BSS_STARTED, &link_info->link_flags)) 17990 goto end; 17991 17992 if (wlan_hdd_cfg80211_update_apies(link_info)) { 17993 hdd_err("SAP Not able to set AP IEs"); 17994 goto end; 17995 } 17996 wlan_reg_set_channel_params_for_pwrmode(hdd_ctx->pdev, 17997 sap_config->chan_freq, 0, 17998 &sap_config->ch_params, 17999 REG_CURRENT_PWR_MODE); 18000 qdf_status = wlan_hdd_mlo_sap_reinit(link_info); 18001 if (QDF_IS_STATUS_ERROR(qdf_status)) { 18002 hdd_err("SAP Not able to do mlo attach"); 18003 goto end; 18004 } 18005 18006 qdf_event_reset(&hostapd_state->qdf_event); 18007 qdf_status = wlansap_start_bss(ap_ctx->sap_context, 18008 hdd_hostapd_sap_event_cb, sap_config, 18009 ap_adapter->dev); 18010 if (QDF_IS_STATUS_ERROR(qdf_status)) 18011 goto end; 18012 18013 hdd_debug("Waiting for SAP to start"); 18014 qdf_status = qdf_wait_single_event(&hostapd_state->qdf_event, 18015 SME_CMD_START_BSS_TIMEOUT); 18016 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { 18017 hdd_err("SAP Start failed"); 18018 goto end; 18019 } 18020 hdd_info("SAP Start Success"); 18021 18022 wlansap_reset_sap_config_add_ie(sap_config, eUPDATE_IE_ALL); 18023 set_bit(SOFTAP_BSS_STARTED, &link_info->link_flags); 18024 if (hostapd_state->bss_state == BSS_START) { 18025 policy_mgr_incr_active_session(hdd_ctx->psoc, 18026 ap_adapter->device_mode, 18027 link_info->vdev_id); 18028 hdd_green_ap_start_state_mc(hdd_ctx, ap_adapter->device_mode, 18029 true); 18030 } 18031 mutex_unlock(&hdd_ctx->sap_lock); 18032 18033 return; 18034 end: 18035 wlan_hdd_mlo_reset(link_info); 18036 wlansap_reset_sap_config_add_ie(sap_config, eUPDATE_IE_ALL); 18037 mutex_unlock(&hdd_ctx->sap_lock); 18038 /* SAP context and beacon cleanup will happen during driver unload 18039 * in hdd_stop_adapter 18040 */ 18041 hdd_err("SAP restart after SSR failed! Reload WLAN and try SAP again"); 18042 /* Free the beacon memory in case of failure in the sap restart */ 18043 qdf_mem_free(ap_ctx->beacon); 18044 ap_ctx->beacon = NULL; 18045 } 18046 18047 #ifdef QCA_CONFIG_SMP 18048 /** 18049 * wlan_hdd_get_cpu() - get cpu_index 18050 * 18051 * Return: cpu_index 18052 */ 18053 int wlan_hdd_get_cpu(void) 18054 { 18055 int cpu_index = get_cpu(); 18056 18057 put_cpu(); 18058 return cpu_index; 18059 } 18060 #endif 18061 18062 /** 18063 * hdd_get_fwpath() - get framework path 18064 * 18065 * This function is used to get the string written by 18066 * userspace to start the wlan driver 18067 * 18068 * Return: string 18069 */ 18070 const char *hdd_get_fwpath(void) 18071 { 18072 return fwpath.string; 18073 } 18074 18075 static inline int hdd_state_query_cb(void) 18076 { 18077 return !!wlan_hdd_validate_context(cds_get_context(QDF_MODULE_ID_HDD)); 18078 } 18079 18080 static int __hdd_op_protect_cb(void **out_sync, const char *func) 18081 { 18082 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 18083 18084 if (!hdd_ctx) 18085 return -EAGAIN; 18086 18087 return __osif_psoc_sync_op_start(hdd_ctx->parent_dev, 18088 (struct osif_psoc_sync **)out_sync, 18089 func); 18090 } 18091 18092 static void __hdd_op_unprotect_cb(void *sync, const char *func) 18093 { 18094 __osif_psoc_sync_op_stop(sync, func); 18095 } 18096 18097 #ifdef WLAN_LOGGING_SOCK_SVC_ENABLE 18098 /** 18099 * hdd_logging_sock_init_svc() - Initialize logging sock 18100 * 18101 * Return: 0 for success, errno on failure 18102 */ 18103 static int 18104 hdd_logging_sock_init_svc(void) 18105 { 18106 return wlan_logging_sock_init_svc(); 18107 } 18108 #else 18109 static inline int 18110 hdd_logging_sock_init_svc(void) 18111 { 18112 return 0; 18113 } 18114 #endif 18115 18116 /** 18117 * hdd_init() - Initialize Driver 18118 * 18119 * This function initializes CDS global context with the help of cds_init. This 18120 * has to be the first function called after probe to get a valid global 18121 * context. 18122 * 18123 * Return: 0 for success, errno on failure 18124 */ 18125 int hdd_init(void) 18126 { 18127 QDF_STATUS status; 18128 18129 status = cds_init(); 18130 if (QDF_IS_STATUS_ERROR(status)) { 18131 hdd_err("Failed to allocate CDS context"); 18132 return -ENOMEM; 18133 } 18134 18135 qdf_op_callbacks_register(__hdd_op_protect_cb, __hdd_op_unprotect_cb); 18136 18137 wlan_init_bug_report_lock(); 18138 18139 if (hdd_logging_sock_init_svc()) { 18140 hdd_err("logging sock init failed."); 18141 goto err; 18142 } 18143 18144 hdd_trace_init(); 18145 hdd_register_debug_callback(); 18146 wlan_roam_debug_init(); 18147 18148 return 0; 18149 18150 err: 18151 wlan_destroy_bug_report_lock(); 18152 qdf_op_callbacks_register(NULL, NULL); 18153 cds_deinit(); 18154 return -ENOMEM; 18155 } 18156 18157 /** 18158 * hdd_deinit() - Deinitialize Driver 18159 * 18160 * This function frees CDS global context with the help of cds_deinit. This 18161 * has to be the last function call in remove callback to free the global 18162 * context. 18163 */ 18164 void hdd_deinit(void) 18165 { 18166 wlan_roam_debug_deinit(); 18167 18168 #ifdef WLAN_LOGGING_SOCK_SVC_ENABLE 18169 wlan_logging_sock_deinit_svc(); 18170 #endif 18171 18172 wlan_destroy_bug_report_lock(); 18173 qdf_op_callbacks_register(NULL, NULL); 18174 cds_deinit(); 18175 } 18176 18177 #ifdef QCA_WIFI_EMULATION 18178 #define HDD_WLAN_START_WAIT_TIME ((CDS_WMA_TIMEOUT + 5000) * 100) 18179 #else 18180 #define HDD_WLAN_START_WAIT_TIME (CDS_WMA_TIMEOUT + 5000) 18181 #endif 18182 18183 void hdd_init_start_completion(void) 18184 { 18185 INIT_COMPLETION(wlan_start_comp); 18186 } 18187 18188 #ifdef WLAN_CTRL_NAME 18189 static unsigned int dev_num = 1; 18190 static struct cdev wlan_hdd_state_cdev; 18191 static struct class *class; 18192 static dev_t device; 18193 18194 static void hdd_set_adapter_wlm_def_level(struct hdd_context *hdd_ctx) 18195 { 18196 struct hdd_adapter *adapter, *next_adapter = NULL; 18197 wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_GET_ADAPTER; 18198 int ret; 18199 QDF_STATUS qdf_status; 18200 uint8_t latency_level; 18201 bool reset; 18202 18203 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) 18204 return; 18205 18206 ret = wlan_hdd_validate_context(hdd_ctx); 18207 if (ret != 0) 18208 return; 18209 18210 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 18211 dbgid) { 18212 qdf_status = ucfg_mlme_cfg_get_wlm_level(hdd_ctx->psoc, 18213 &latency_level); 18214 if (QDF_IS_STATUS_ERROR(qdf_status)) 18215 adapter->latency_level = 18216 QCA_WLAN_VENDOR_ATTR_CONFIG_LATENCY_LEVEL_NORMAL; 18217 else 18218 adapter->latency_level = latency_level; 18219 qdf_status = ucfg_mlme_cfg_get_wlm_reset(hdd_ctx->psoc, &reset); 18220 if (QDF_IS_STATUS_ERROR(qdf_status)) { 18221 hdd_err("could not get the wlm reset flag"); 18222 reset = false; 18223 } 18224 18225 if (hdd_get_multi_client_ll_support(adapter) && !reset) 18226 wlan_hdd_deinit_multi_client_info_table(adapter); 18227 18228 adapter->upgrade_udp_qos_threshold = QCA_WLAN_AC_BK; 18229 hdd_debug("UDP packets qos reset to: %d", 18230 adapter->upgrade_udp_qos_threshold); 18231 hdd_adapter_dev_put_debug(adapter, dbgid); 18232 } 18233 } 18234 18235 static int wlan_hdd_state_ctrl_param_open(struct inode *inode, 18236 struct file *file) 18237 { 18238 qdf_atomic_inc(&wlan_hdd_state_fops_ref); 18239 18240 return 0; 18241 } 18242 18243 static void __hdd_inform_wifi_off(void) 18244 { 18245 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 18246 int ret; 18247 18248 ret = wlan_hdd_validate_context(hdd_ctx); 18249 if (ret != 0) 18250 return; 18251 18252 ucfg_dlm_wifi_off(hdd_ctx->pdev); 18253 } 18254 18255 static void hdd_inform_wifi_off(void) 18256 { 18257 int ret; 18258 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 18259 struct osif_psoc_sync *psoc_sync; 18260 18261 if (!hdd_ctx) 18262 return; 18263 18264 ret = osif_psoc_sync_op_start(wiphy_dev(hdd_ctx->wiphy), &psoc_sync); 18265 if (ret) 18266 return; 18267 18268 hdd_set_adapter_wlm_def_level(hdd_ctx); 18269 __hdd_inform_wifi_off(); 18270 18271 osif_psoc_sync_op_stop(psoc_sync); 18272 } 18273 18274 #if defined CFG80211_USER_HINT_CELL_BASE_SELF_MANAGED || \ 18275 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 18, 0)) 18276 static void hdd_inform_wifi_on(void) 18277 { 18278 int ret; 18279 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 18280 struct osif_psoc_sync *psoc_sync; 18281 18282 hdd_nofl_debug("inform regdomain for wifi on"); 18283 ret = wlan_hdd_validate_context(hdd_ctx); 18284 if (ret) 18285 return; 18286 if (!wlan_hdd_validate_modules_state(hdd_ctx)) 18287 return; 18288 if (!hdd_ctx->wiphy) 18289 return; 18290 ret = osif_psoc_sync_op_start(wiphy_dev(hdd_ctx->wiphy), &psoc_sync); 18291 if (ret) 18292 return; 18293 if (hdd_ctx->wiphy->registered) 18294 hdd_send_wiphy_regd_sync_event(hdd_ctx); 18295 18296 osif_psoc_sync_op_stop(psoc_sync); 18297 } 18298 #else 18299 static void hdd_inform_wifi_on(void) 18300 { 18301 } 18302 #endif 18303 18304 static int hdd_validate_wlan_string(const char __user *user_buf) 18305 { 18306 char buf[15]; 18307 int i; 18308 static const char * const wlan_str[] = { 18309 [WLAN_OFF_STR] = "OFF", 18310 [WLAN_ON_STR] = "ON", 18311 [WLAN_ENABLE_STR] = "ENABLE", 18312 [WLAN_DISABLE_STR] = "DISABLE", 18313 [WLAN_WAIT_FOR_READY_STR] = "WAIT_FOR_READY", 18314 [WLAN_FORCE_DISABLE_STR] = "FORCE_DISABLE" 18315 }; 18316 18317 if (copy_from_user(buf, user_buf, sizeof(buf))) { 18318 pr_err("Failed to read buffer\n"); 18319 return -EINVAL; 18320 } 18321 18322 for (i = 0; i < ARRAY_SIZE(wlan_str); i++) { 18323 if (qdf_str_ncmp(buf, wlan_str[i], strlen(wlan_str[i])) == 0) 18324 return i; 18325 } 18326 18327 return -EINVAL; 18328 } 18329 18330 #ifdef FEATURE_CNSS_HW_SECURE_DISABLE 18331 #define WIFI_DISABLE_SLEEP (10) 18332 #define WIFI_DISABLE_MAX_RETRY_ATTEMPTS (10) 18333 static bool g_soft_unload; 18334 18335 bool hdd_get_wlan_driver_status(void) 18336 { 18337 return g_soft_unload; 18338 } 18339 18340 static int hdd_wlan_soft_driver_load(void) 18341 { 18342 if (!cds_is_driver_loaded()) { 18343 hdd_debug("\nEnabling CNSS WLAN HW"); 18344 pld_wlan_hw_enable(); 18345 return 0; 18346 } 18347 18348 if (!g_soft_unload) { 18349 hdd_debug_rl("Enabling WiFi\n"); 18350 return -EINVAL; 18351 } 18352 18353 hdd_driver_load(); 18354 g_soft_unload = false; 18355 return 0; 18356 } 18357 18358 static void hdd_wlan_soft_driver_unload(void) 18359 { 18360 if (g_soft_unload) { 18361 hdd_debug_rl("WiFi is already disabled"); 18362 return; 18363 } 18364 hdd_debug("Initiating soft driver unload\n"); 18365 g_soft_unload = true; 18366 hdd_driver_unload(); 18367 } 18368 18369 static int hdd_wlan_idle_shutdown(struct hdd_context *hdd_ctx) 18370 { 18371 int ret; 18372 int retries = 0; 18373 void *hif_ctx; 18374 18375 if (!hdd_ctx) { 18376 hdd_err_rl("hdd_ctx is Null"); 18377 return -EINVAL; 18378 } 18379 18380 hif_ctx = cds_get_context(QDF_MODULE_ID_HIF); 18381 18382 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_IDLE_SHUTDOWN); 18383 18384 while (retries < WIFI_DISABLE_MAX_RETRY_ATTEMPTS) { 18385 if (hif_ctx) { 18386 /* 18387 * Trigger runtime sync resume before psoc_idle_shutdown 18388 * such that resume can happen successfully 18389 */ 18390 qdf_rtpm_sync_resume(); 18391 } 18392 ret = pld_idle_shutdown(hdd_ctx->parent_dev, 18393 hdd_psoc_idle_shutdown); 18394 18395 if (-EAGAIN == ret || hdd_ctx->is_wiphy_suspended) { 18396 hdd_debug("System suspend in progress.Retries done:%d", 18397 retries); 18398 msleep(WIFI_DISABLE_SLEEP); 18399 retries++; 18400 continue; 18401 } 18402 break; 18403 } 18404 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_IDLE_SHUTDOWN); 18405 18406 if (retries > WIFI_DISABLE_MAX_RETRY_ATTEMPTS) { 18407 hdd_debug("Max retries reached"); 18408 return -EINVAL; 18409 } 18410 hdd_debug_rl("WiFi is disabled"); 18411 18412 return 0; 18413 } 18414 18415 static int hdd_disable_wifi(struct hdd_context *hdd_ctx) 18416 { 18417 int ret; 18418 18419 if (hdd_ctx->is_wlan_disabled) { 18420 hdd_err_rl("Wifi is already disabled"); 18421 return 0; 18422 } 18423 18424 hdd_debug("Initiating WLAN idle shutdown"); 18425 if (hdd_is_any_interface_open(hdd_ctx)) { 18426 hdd_err("Interfaces still open, cannot process wifi disable"); 18427 return -EAGAIN; 18428 } 18429 18430 hdd_ctx->is_wlan_disabled = true; 18431 18432 ret = hdd_wlan_idle_shutdown(hdd_ctx); 18433 if (ret) 18434 hdd_ctx->is_wlan_disabled = false; 18435 18436 return ret; 18437 } 18438 #else 18439 static int hdd_wlan_soft_driver_load(void) 18440 { 18441 return -EINVAL; 18442 } 18443 18444 static void hdd_wlan_soft_driver_unload(void) 18445 { 18446 } 18447 18448 static int hdd_disable_wifi(struct hdd_context *hdd_ctx) 18449 { 18450 return 0; 18451 } 18452 #endif /* FEATURE_CNSS_HW_SECURE_DISABLE */ 18453 18454 static ssize_t wlan_hdd_state_ctrl_param_write(struct file *filp, 18455 const char __user *user_buf, 18456 size_t count, 18457 loff_t *f_pos) 18458 { 18459 int id, ret; 18460 unsigned long rc; 18461 struct hdd_context *hdd_ctx; 18462 bool is_wait_for_ready = false; 18463 bool is_wlan_force_disabled; 18464 18465 hdd_enter(); 18466 18467 id = hdd_validate_wlan_string(user_buf); 18468 18469 switch (id) { 18470 case WLAN_OFF_STR: 18471 hdd_info("Wifi turning off from UI\n"); 18472 hdd_inform_wifi_off(); 18473 goto exit; 18474 case WLAN_ON_STR: 18475 hdd_info("Wifi Turning On from UI\n"); 18476 break; 18477 case WLAN_WAIT_FOR_READY_STR: 18478 is_wait_for_ready = true; 18479 hdd_info("Wifi wait for ready from UI\n"); 18480 break; 18481 case WLAN_ENABLE_STR: 18482 hdd_nofl_debug("Received WiFi enable from framework\n"); 18483 if (!hdd_wlan_soft_driver_load()) 18484 goto exit; 18485 pr_info("Enabling WiFi\n"); 18486 break; 18487 case WLAN_DISABLE_STR: 18488 hdd_nofl_debug("Received WiFi disable from framework\n"); 18489 if (!cds_is_driver_loaded()) 18490 goto exit; 18491 18492 is_wlan_force_disabled = hdd_get_wlan_driver_status(); 18493 if (is_wlan_force_disabled) 18494 goto exit; 18495 pr_info("Disabling WiFi\n"); 18496 break; 18497 case WLAN_FORCE_DISABLE_STR: 18498 hdd_nofl_debug("Received Force WiFi disable from framework\n"); 18499 if (!cds_is_driver_loaded()) 18500 goto exit; 18501 18502 hdd_wlan_soft_driver_unload(); 18503 goto exit; 18504 default: 18505 hdd_err_rl("Invalid value received from framework"); 18506 return -EINVAL; 18507 } 18508 18509 hdd_info("is_driver_loaded %d is_driver_recovering %d", 18510 cds_is_driver_loaded(), cds_is_driver_recovering()); 18511 18512 if (!cds_is_driver_loaded() || cds_is_driver_recovering()) { 18513 rc = wait_for_completion_timeout(&wlan_start_comp, 18514 msecs_to_jiffies(HDD_WLAN_START_WAIT_TIME)); 18515 if (!rc) { 18516 hdd_err("Driver Loading Timed-out!!"); 18517 ret = -EINVAL; 18518 return ret; 18519 } 18520 } 18521 18522 if (is_wait_for_ready) 18523 return count; 18524 /* 18525 * Flush idle shutdown work for cases to synchronize the wifi on 18526 * during the idle shutdown. 18527 */ 18528 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 18529 if (hdd_ctx) 18530 hdd_psoc_idle_timer_stop(hdd_ctx); 18531 18532 if (id == WLAN_DISABLE_STR) { 18533 if (!hdd_ctx) { 18534 hdd_err_rl("hdd_ctx is Null"); 18535 goto exit; 18536 } 18537 18538 ret = hdd_disable_wifi(hdd_ctx); 18539 if (ret) 18540 return ret; 18541 } 18542 18543 if (id == WLAN_ENABLE_STR) { 18544 if (!hdd_ctx) { 18545 hdd_err_rl("hdd_ctx is Null"); 18546 goto exit; 18547 } 18548 18549 if (!hdd_ctx->is_wlan_disabled) { 18550 hdd_err_rl("WiFi is already enabled"); 18551 goto exit; 18552 } 18553 hdd_ctx->is_wlan_disabled = false; 18554 } 18555 18556 if (id == WLAN_ON_STR) 18557 hdd_inform_wifi_on(); 18558 exit: 18559 hdd_exit(); 18560 return count; 18561 } 18562 18563 /** 18564 * wlan_hdd_state_ctrl_param_release() - Release callback for /dev/wlan. 18565 * 18566 * @inode: struct inode pointer. 18567 * @file: struct file pointer. 18568 * 18569 * Release callback that would be invoked when the file operations has 18570 * completed fully. This is implemented to provide a reference count mechanism 18571 * via which the driver can wait till all possible usage of the /dev/wlan 18572 * file is completed. 18573 * 18574 * Return: Success 18575 */ 18576 static int wlan_hdd_state_ctrl_param_release(struct inode *inode, 18577 struct file *file) 18578 { 18579 qdf_atomic_dec(&wlan_hdd_state_fops_ref); 18580 18581 return 0; 18582 } 18583 18584 const struct file_operations wlan_hdd_state_fops = { 18585 .owner = THIS_MODULE, 18586 .open = wlan_hdd_state_ctrl_param_open, 18587 .write = wlan_hdd_state_ctrl_param_write, 18588 .release = wlan_hdd_state_ctrl_param_release, 18589 }; 18590 18591 static int wlan_hdd_state_ctrl_param_create(void) 18592 { 18593 unsigned int wlan_hdd_state_major = 0; 18594 int ret; 18595 struct device *dev; 18596 18597 init_completion(&wlan_start_comp); 18598 qdf_atomic_init(&wlan_hdd_state_fops_ref); 18599 18600 device = MKDEV(wlan_hdd_state_major, 0); 18601 18602 ret = alloc_chrdev_region(&device, 0, dev_num, "qcwlanstate"); 18603 if (ret) { 18604 pr_err("Failed to register qcwlanstate"); 18605 goto dev_alloc_err; 18606 } 18607 wlan_hdd_state_major = MAJOR(device); 18608 18609 class = class_create(THIS_MODULE, WLAN_CTRL_NAME); 18610 if (IS_ERR(class)) { 18611 pr_err("wlan_hdd_state class_create error"); 18612 goto class_err; 18613 } 18614 18615 dev = device_create(class, NULL, device, NULL, WLAN_CTRL_NAME); 18616 if (IS_ERR(dev)) { 18617 pr_err("wlan_hdd_statedevice_create error"); 18618 goto err_class_destroy; 18619 } 18620 18621 cdev_init(&wlan_hdd_state_cdev, &wlan_hdd_state_fops); 18622 18623 wlan_hdd_state_cdev.owner = THIS_MODULE; 18624 18625 ret = cdev_add(&wlan_hdd_state_cdev, device, dev_num); 18626 if (ret) { 18627 pr_err("Failed to add cdev error"); 18628 goto cdev_add_err; 18629 } 18630 18631 pr_info("wlan_hdd_state %s major(%d) initialized", 18632 WLAN_CTRL_NAME, wlan_hdd_state_major); 18633 18634 return 0; 18635 18636 cdev_add_err: 18637 device_destroy(class, device); 18638 err_class_destroy: 18639 class_destroy(class); 18640 class_err: 18641 unregister_chrdev_region(device, dev_num); 18642 dev_alloc_err: 18643 return -ENODEV; 18644 } 18645 18646 /* 18647 * When multiple instances of the driver are loaded in parallel, only 18648 * one can create and own the state ctrl param. An instance of the 18649 * driver that creates the state ctrl param will wait for 18650 * HDD_WLAN_START_WAIT_TIME to be probed. If it is probed, then that 18651 * instance of the driver will stay loaded and no other instances of 18652 * the driver can load. But if it is not probed, then that instance of 18653 * the driver will destroy the state ctrl param and exit, and another 18654 * instance of the driver can then create the state ctrl param. 18655 */ 18656 18657 /* max number of instances we expect (arbitrary) */ 18658 #define WLAN_DRIVER_MAX_INSTANCES 5 18659 18660 /* max amount of time an instance has to wait for all instances */ 18661 #define CTRL_PARAM_WAIT (WLAN_DRIVER_MAX_INSTANCES * HDD_WLAN_START_WAIT_TIME) 18662 18663 /* amount of time we sleep for each retry (arbitrary) */ 18664 #define CTRL_PARAM_SLEEP 100 18665 18666 static void wlan_hdd_state_ctrl_param_destroy(void) 18667 { 18668 cdev_del(&wlan_hdd_state_cdev); 18669 device_destroy(class, device); 18670 class_destroy(class); 18671 unregister_chrdev_region(device, dev_num); 18672 18673 pr_info("Device node unregistered"); 18674 } 18675 18676 #else /* WLAN_CTRL_NAME */ 18677 18678 static int wlan_hdd_state_ctrl_param_create(void) 18679 { 18680 return 0; 18681 } 18682 18683 static void wlan_hdd_state_ctrl_param_destroy(void) 18684 { 18685 } 18686 18687 #endif /* WLAN_CTRL_NAME */ 18688 18689 /** 18690 * hdd_send_scan_done_complete_cb() - API to send scan done indication to upper 18691 * layer 18692 * @vdev_id: vdev id 18693 * 18694 * Return: none 18695 */ 18696 static void hdd_send_scan_done_complete_cb(uint8_t vdev_id) 18697 { 18698 struct hdd_context *hdd_ctx; 18699 struct wlan_hdd_link_info *link_info; 18700 struct hdd_adapter *adapter; 18701 struct sk_buff *vendor_event; 18702 uint32_t len; 18703 18704 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 18705 if (!hdd_ctx) 18706 return; 18707 18708 link_info = hdd_get_link_info_by_vdev(hdd_ctx, vdev_id); 18709 if (!link_info) { 18710 hdd_err("Invalid vdev id:%d", vdev_id); 18711 return; 18712 } 18713 18714 adapter = link_info->adapter; 18715 len = NLMSG_HDRLEN; 18716 vendor_event = 18717 wlan_cfg80211_vendor_event_alloc( 18718 hdd_ctx->wiphy, &adapter->wdev, len, 18719 QCA_NL80211_VENDOR_SUBCMD_CONNECTED_CHANNEL_STATS_INDEX, 18720 GFP_KERNEL); 18721 18722 if (!vendor_event) { 18723 hdd_err("wlan_cfg80211_vendor_event_alloc failed"); 18724 return; 18725 } 18726 18727 hdd_debug("sending scan done ind to upper layer for vdev_id:%d", 18728 vdev_id); 18729 wlan_cfg80211_vendor_event(vendor_event, GFP_KERNEL); 18730 } 18731 18732 struct osif_vdev_mgr_ops osif_vdev_mgrlegacy_ops = { 18733 #ifdef WLAN_FEATURE_DYNAMIC_MAC_ADDR_UPDATE 18734 .osif_vdev_mgr_set_mac_addr_response = hdd_set_mac_addr_event_cb, 18735 #endif 18736 .osif_vdev_mgr_send_scan_done_complete_cb = 18737 hdd_send_scan_done_complete_cb, 18738 18739 }; 18740 18741 static QDF_STATUS hdd_vdev_mgr_register_cb(void) 18742 { 18743 osif_vdev_mgr_set_legacy_cb(&osif_vdev_mgrlegacy_ops); 18744 return osif_vdev_mgr_register_cb(); 18745 } 18746 18747 static void hdd_vdev_mgr_unregister_cb(void) 18748 { 18749 osif_vdev_mgr_reset_legacy_cb(); 18750 } 18751 18752 /** 18753 * hdd_component_cb_init() - Initialize component callbacks 18754 * 18755 * This function initializes hdd callbacks to different 18756 * components 18757 * 18758 * Context: Any context. 18759 * Return: QDF_STATUS 18760 */ 18761 static QDF_STATUS hdd_component_cb_init(void) 18762 { 18763 QDF_STATUS status; 18764 18765 status = hdd_cm_register_cb(); 18766 if (QDF_IS_STATUS_ERROR(status)) 18767 return status; 18768 18769 status = hdd_vdev_mgr_register_cb(); 18770 if (QDF_IS_STATUS_ERROR(status)) 18771 goto cm_unregister_cb; 18772 18773 status = osif_twt_register_cb(); 18774 if (QDF_IS_STATUS_ERROR(status)) 18775 goto hdd_vdev_mgr_unregister_cb; 18776 18777 status = hdd_pre_cac_register_cb(); 18778 if (QDF_IS_STATUS_ERROR(status)) 18779 goto hdd_vdev_mgr_unregister_cb; 18780 18781 return QDF_STATUS_SUCCESS; 18782 18783 hdd_vdev_mgr_unregister_cb: 18784 hdd_vdev_mgr_unregister_cb(); 18785 cm_unregister_cb: 18786 hdd_cm_unregister_cb(); 18787 return status; 18788 } 18789 18790 /** 18791 * hdd_component_cb_deinit() - De-initialize component callbacks 18792 * 18793 * This function de-initializes hdd callbacks with different components 18794 * 18795 * Context: Any context. 18796 * Return: None` 18797 */ 18798 static void hdd_component_cb_deinit(void) 18799 { 18800 hdd_pre_cac_unregister_cb(); 18801 hdd_vdev_mgr_unregister_cb(); 18802 hdd_cm_unregister_cb(); 18803 } 18804 18805 /** 18806 * hdd_component_init() - Initialize all components 18807 * 18808 * Return: QDF_STATUS 18809 */ 18810 static QDF_STATUS hdd_component_init(void) 18811 { 18812 QDF_STATUS status; 18813 18814 /* initialize converged components */ 18815 18816 status = ucfg_mlme_global_init(); 18817 if (QDF_IS_STATUS_ERROR(status)) 18818 return status; 18819 18820 status = dispatcher_init(); 18821 if (QDF_IS_STATUS_ERROR(status)) 18822 goto mlme_global_deinit; 18823 18824 status = target_if_init(wma_get_psoc_from_scn_handle); 18825 if (QDF_IS_STATUS_ERROR(status)) 18826 goto dispatcher_deinit; 18827 18828 /* initialize non-converged components */ 18829 status = ucfg_mlme_init(); 18830 if (QDF_IS_STATUS_ERROR(status)) 18831 goto target_if_deinit; 18832 18833 status = ucfg_fwol_init(); 18834 if (QDF_IS_STATUS_ERROR(status)) 18835 goto mlme_deinit; 18836 18837 status = disa_init(); 18838 if (QDF_IS_STATUS_ERROR(status)) 18839 goto fwol_deinit; 18840 18841 status = pmo_init(); 18842 if (QDF_IS_STATUS_ERROR(status)) 18843 goto disa_deinit; 18844 18845 status = ucfg_ocb_init(); 18846 if (QDF_IS_STATUS_ERROR(status)) 18847 goto pmo_deinit; 18848 18849 status = ipa_init(); 18850 if (QDF_IS_STATUS_ERROR(status)) 18851 goto ocb_deinit; 18852 18853 status = ucfg_action_oui_init(); 18854 if (QDF_IS_STATUS_ERROR(status)) 18855 goto ipa_deinit; 18856 18857 status = nan_init(); 18858 if (QDF_IS_STATUS_ERROR(status)) 18859 goto action_oui_deinit; 18860 18861 status = ucfg_p2p_init(); 18862 if (QDF_IS_STATUS_ERROR(status)) 18863 goto nan_deinit; 18864 18865 status = ucfg_interop_issues_ap_init(); 18866 if (QDF_IS_STATUS_ERROR(status)) 18867 goto p2p_deinit; 18868 18869 status = policy_mgr_init(); 18870 if (QDF_IS_STATUS_ERROR(status)) 18871 goto interop_issues_ap_deinit; 18872 18873 status = ucfg_tdls_init(); 18874 if (QDF_IS_STATUS_ERROR(status)) 18875 goto policy_deinit; 18876 18877 status = ucfg_dlm_init(); 18878 if (QDF_IS_STATUS_ERROR(status)) 18879 goto tdls_deinit; 18880 18881 status = ucfg_pkt_capture_init(); 18882 if (QDF_IS_STATUS_ERROR(status)) 18883 goto dlm_deinit; 18884 18885 status = ucfg_ftm_time_sync_init(); 18886 if (QDF_IS_STATUS_ERROR(status)) 18887 goto pkt_capture_deinit; 18888 18889 status = ucfg_pre_cac_init(); 18890 if (QDF_IS_STATUS_ERROR(status)) 18891 goto pre_cac_deinit; 18892 18893 status = ucfg_dp_init(); 18894 if (QDF_IS_STATUS_ERROR(status)) 18895 goto pre_cac_deinit; 18896 18897 status = ucfg_qmi_init(); 18898 if (QDF_IS_STATUS_ERROR(status)) 18899 goto dp_deinit; 18900 18901 status = ucfg_ll_sap_init(); 18902 if (QDF_IS_STATUS_ERROR(status)) 18903 goto qmi_deinit; 18904 18905 status = ucfg_afc_init(); 18906 if (QDF_IS_STATUS_ERROR(status)) 18907 goto ll_sap_deinit; 18908 18909 status = hdd_mlo_mgr_register_osif_ops(); 18910 if (QDF_IS_STATUS_ERROR(status)) 18911 goto afc_deinit; 18912 18913 return QDF_STATUS_SUCCESS; 18914 18915 afc_deinit: 18916 ucfg_afc_deinit(); 18917 ll_sap_deinit: 18918 ucfg_ll_sap_deinit(); 18919 qmi_deinit: 18920 ucfg_qmi_deinit(); 18921 dp_deinit: 18922 ucfg_dp_deinit(); 18923 pre_cac_deinit: 18924 ucfg_pre_cac_deinit(); 18925 pkt_capture_deinit: 18926 ucfg_pkt_capture_deinit(); 18927 dlm_deinit: 18928 ucfg_dlm_deinit(); 18929 tdls_deinit: 18930 ucfg_tdls_deinit(); 18931 policy_deinit: 18932 policy_mgr_deinit(); 18933 interop_issues_ap_deinit: 18934 ucfg_interop_issues_ap_deinit(); 18935 p2p_deinit: 18936 ucfg_p2p_deinit(); 18937 nan_deinit: 18938 nan_deinit(); 18939 action_oui_deinit: 18940 ucfg_action_oui_deinit(); 18941 ipa_deinit: 18942 ipa_deinit(); 18943 ocb_deinit: 18944 ucfg_ocb_deinit(); 18945 pmo_deinit: 18946 pmo_deinit(); 18947 disa_deinit: 18948 disa_deinit(); 18949 fwol_deinit: 18950 ucfg_fwol_deinit(); 18951 mlme_deinit: 18952 ucfg_mlme_deinit(); 18953 target_if_deinit: 18954 target_if_deinit(); 18955 dispatcher_deinit: 18956 dispatcher_deinit(); 18957 mlme_global_deinit: 18958 ucfg_mlme_global_deinit(); 18959 18960 return status; 18961 } 18962 18963 /** 18964 * hdd_component_deinit() - Deinitialize all components 18965 * 18966 * Return: None 18967 */ 18968 static void hdd_component_deinit(void) 18969 { 18970 /* deinitialize non-converged components */ 18971 hdd_mlo_mgr_unregister_osif_ops(); 18972 ucfg_afc_deinit(); 18973 ucfg_ll_sap_deinit(); 18974 ucfg_qmi_deinit(); 18975 ucfg_dp_deinit(); 18976 ucfg_pre_cac_deinit(); 18977 ucfg_ftm_time_sync_deinit(); 18978 ucfg_pkt_capture_deinit(); 18979 ucfg_dlm_deinit(); 18980 ucfg_tdls_deinit(); 18981 policy_mgr_deinit(); 18982 ucfg_interop_issues_ap_deinit(); 18983 ucfg_p2p_deinit(); 18984 nan_deinit(); 18985 ucfg_action_oui_deinit(); 18986 ipa_deinit(); 18987 ucfg_ocb_deinit(); 18988 pmo_deinit(); 18989 disa_deinit(); 18990 ucfg_fwol_deinit(); 18991 ucfg_mlme_deinit(); 18992 18993 /* deinitialize converged components */ 18994 target_if_deinit(); 18995 dispatcher_deinit(); 18996 ucfg_mlme_global_deinit(); 18997 } 18998 18999 QDF_STATUS hdd_component_psoc_open(struct wlan_objmgr_psoc *psoc) 19000 { 19001 QDF_STATUS status; 19002 19003 status = ucfg_mlme_psoc_open(psoc); 19004 if (QDF_IS_STATUS_ERROR(status)) 19005 return status; 19006 19007 status = ucfg_dlm_psoc_open(psoc); 19008 if (QDF_IS_STATUS_ERROR(status)) 19009 goto err_dlm; 19010 19011 status = ucfg_fwol_psoc_open(psoc); 19012 if (QDF_IS_STATUS_ERROR(status)) 19013 goto err_fwol; 19014 19015 status = ucfg_pmo_psoc_open(psoc); 19016 if (QDF_IS_STATUS_ERROR(status)) 19017 goto err_pmo; 19018 19019 status = ucfg_policy_mgr_psoc_open(psoc); 19020 if (QDF_IS_STATUS_ERROR(status)) 19021 goto err_plcy_mgr; 19022 19023 status = ucfg_p2p_psoc_open(psoc); 19024 if (QDF_IS_STATUS_ERROR(status)) 19025 goto err_p2p; 19026 19027 status = ucfg_tdls_psoc_open(psoc); 19028 if (QDF_IS_STATUS_ERROR(status)) 19029 goto err_tdls; 19030 19031 status = ucfg_nan_psoc_open(psoc); 19032 if (QDF_IS_STATUS_ERROR(status)) 19033 goto err_nan; 19034 19035 status = ucfg_twt_psoc_open(psoc); 19036 if (QDF_IS_STATUS_ERROR(status)) 19037 goto err_twt; 19038 19039 status = ucfg_wifi_pos_psoc_open(psoc); 19040 if (QDF_IS_STATUS_ERROR(status)) 19041 goto err_wifi_pos; 19042 19043 status = ucfg_dp_psoc_open(psoc); 19044 if (QDF_IS_STATUS_ERROR(status)) 19045 goto err_dp; 19046 19047 return status; 19048 19049 err_dp: 19050 ucfg_wifi_pos_psoc_close(psoc); 19051 err_wifi_pos: 19052 ucfg_twt_psoc_close(psoc); 19053 err_twt: 19054 ucfg_nan_psoc_close(psoc); 19055 err_nan: 19056 ucfg_tdls_psoc_close(psoc); 19057 err_tdls: 19058 ucfg_p2p_psoc_close(psoc); 19059 err_p2p: 19060 ucfg_policy_mgr_psoc_close(psoc); 19061 err_plcy_mgr: 19062 ucfg_pmo_psoc_close(psoc); 19063 err_pmo: 19064 ucfg_fwol_psoc_close(psoc); 19065 err_fwol: 19066 ucfg_dlm_psoc_close(psoc); 19067 err_dlm: 19068 ucfg_mlme_psoc_close(psoc); 19069 19070 return status; 19071 } 19072 19073 void hdd_component_psoc_close(struct wlan_objmgr_psoc *psoc) 19074 { 19075 ucfg_dp_psoc_close(psoc); 19076 ucfg_wifi_pos_psoc_close(psoc); 19077 ucfg_twt_psoc_close(psoc); 19078 ucfg_nan_psoc_close(psoc); 19079 ucfg_tdls_psoc_close(psoc); 19080 ucfg_p2p_psoc_close(psoc); 19081 ucfg_policy_mgr_psoc_close(psoc); 19082 ucfg_pmo_psoc_close(psoc); 19083 ucfg_fwol_psoc_close(psoc); 19084 ucfg_dlm_psoc_close(psoc); 19085 ucfg_mlme_psoc_close(psoc); 19086 } 19087 19088 void hdd_component_psoc_enable(struct wlan_objmgr_psoc *psoc) 19089 { 19090 ocb_psoc_enable(psoc); 19091 disa_psoc_enable(psoc); 19092 nan_psoc_enable(psoc); 19093 p2p_psoc_enable(psoc); 19094 ucfg_interop_issues_ap_psoc_enable(psoc); 19095 policy_mgr_psoc_enable(psoc); 19096 ucfg_tdls_psoc_enable(psoc); 19097 ucfg_fwol_psoc_enable(psoc); 19098 ucfg_action_oui_psoc_enable(psoc); 19099 } 19100 19101 void hdd_component_psoc_disable(struct wlan_objmgr_psoc *psoc) 19102 { 19103 ucfg_action_oui_psoc_disable(psoc); 19104 ucfg_fwol_psoc_disable(psoc); 19105 ucfg_tdls_psoc_disable(psoc); 19106 policy_mgr_psoc_disable(psoc); 19107 ucfg_interop_issues_ap_psoc_disable(psoc); 19108 p2p_psoc_disable(psoc); 19109 nan_psoc_disable(psoc); 19110 disa_psoc_disable(psoc); 19111 ocb_psoc_disable(psoc); 19112 } 19113 19114 QDF_STATUS hdd_component_pdev_open(struct wlan_objmgr_pdev *pdev) 19115 { 19116 return ucfg_mlme_pdev_open(pdev); 19117 } 19118 19119 void hdd_component_pdev_close(struct wlan_objmgr_pdev *pdev) 19120 { 19121 ucfg_mlme_pdev_close(pdev); 19122 } 19123 19124 static QDF_STATUS hdd_qdf_print_init(void) 19125 { 19126 QDF_STATUS status; 19127 int qdf_print_idx; 19128 19129 status = qdf_print_setup(); 19130 if (QDF_IS_STATUS_ERROR(status)) { 19131 pr_err("Failed qdf_print_setup; status:%u\n", status); 19132 return status; 19133 } 19134 19135 qdf_print_idx = qdf_print_ctrl_register(cinfo, NULL, NULL, "MCL_WLAN"); 19136 if (qdf_print_idx < 0) { 19137 pr_err("Failed to register for qdf_print_ctrl\n"); 19138 return QDF_STATUS_E_FAILURE; 19139 } 19140 19141 qdf_set_pidx(qdf_print_idx); 19142 19143 return QDF_STATUS_SUCCESS; 19144 } 19145 19146 static void hdd_qdf_print_deinit(void) 19147 { 19148 int qdf_pidx = qdf_get_pidx(); 19149 19150 qdf_set_pidx(-1); 19151 qdf_print_ctrl_cleanup(qdf_pidx); 19152 19153 /* currently, no qdf print 'un-setup'*/ 19154 } 19155 19156 static QDF_STATUS hdd_qdf_init(void) 19157 { 19158 QDF_STATUS status; 19159 19160 status = hdd_qdf_print_init(); 19161 if (QDF_IS_STATUS_ERROR(status)) 19162 goto exit; 19163 19164 status = qdf_debugfs_init(); 19165 if (QDF_IS_STATUS_ERROR(status)) { 19166 hdd_err("Failed to init debugfs; status:%u", status); 19167 goto print_deinit; 19168 } 19169 19170 qdf_lock_stats_init(); 19171 qdf_mem_init(); 19172 qdf_delayed_work_feature_init(); 19173 qdf_periodic_work_feature_init(); 19174 qdf_wake_lock_feature_init(); 19175 qdf_mc_timer_manager_init(); 19176 qdf_event_list_init(); 19177 19178 status = qdf_talloc_feature_init(); 19179 if (QDF_IS_STATUS_ERROR(status)) { 19180 hdd_err("Failed to init talloc; status:%u", status); 19181 goto event_deinit; 19182 } 19183 19184 status = qdf_cpuhp_init(); 19185 if (QDF_IS_STATUS_ERROR(status)) { 19186 hdd_err("Failed to init cpuhp; status:%u", status); 19187 goto talloc_deinit; 19188 } 19189 19190 status = qdf_trace_spin_lock_init(); 19191 if (QDF_IS_STATUS_ERROR(status)) { 19192 hdd_err("Failed to init spinlock; status:%u", status); 19193 goto cpuhp_deinit; 19194 } 19195 19196 qdf_trace_init(); 19197 qdf_minidump_init(); 19198 qdf_ssr_driver_dump_init(); 19199 qdf_register_debugcb_init(); 19200 19201 return QDF_STATUS_SUCCESS; 19202 19203 cpuhp_deinit: 19204 qdf_cpuhp_deinit(); 19205 talloc_deinit: 19206 qdf_talloc_feature_deinit(); 19207 event_deinit: 19208 qdf_event_list_destroy(); 19209 qdf_mc_timer_manager_exit(); 19210 qdf_wake_lock_feature_deinit(); 19211 qdf_periodic_work_feature_deinit(); 19212 qdf_delayed_work_feature_deinit(); 19213 qdf_mem_exit(); 19214 qdf_lock_stats_deinit(); 19215 qdf_debugfs_exit(); 19216 print_deinit: 19217 hdd_qdf_print_deinit(); 19218 19219 exit: 19220 return status; 19221 } 19222 19223 static void hdd_qdf_deinit(void) 19224 { 19225 /* currently, no debugcb deinit */ 19226 qdf_ssr_driver_dump_deinit(); 19227 qdf_minidump_deinit(); 19228 qdf_trace_deinit(); 19229 19230 /* currently, no trace spinlock deinit */ 19231 19232 qdf_cpuhp_deinit(); 19233 qdf_talloc_feature_deinit(); 19234 qdf_event_list_destroy(); 19235 qdf_mc_timer_manager_exit(); 19236 qdf_wake_lock_feature_deinit(); 19237 qdf_periodic_work_feature_deinit(); 19238 qdf_delayed_work_feature_deinit(); 19239 qdf_mem_exit(); 19240 qdf_lock_stats_deinit(); 19241 qdf_debugfs_exit(); 19242 hdd_qdf_print_deinit(); 19243 } 19244 19245 #ifdef FEATURE_MONITOR_MODE_SUPPORT 19246 static bool is_monitor_mode_supported(void) 19247 { 19248 return true; 19249 } 19250 #else 19251 static bool is_monitor_mode_supported(void) 19252 { 19253 pr_err("Monitor mode not supported!"); 19254 return false; 19255 } 19256 #endif 19257 19258 #ifdef WLAN_FEATURE_EPPING 19259 static bool is_epping_mode_supported(void) 19260 { 19261 return true; 19262 } 19263 #else 19264 static bool is_epping_mode_supported(void) 19265 { 19266 pr_err("Epping mode not supported!"); 19267 return false; 19268 } 19269 #endif 19270 19271 #ifdef QCA_WIFI_FTM 19272 static bool is_ftm_mode_supported(void) 19273 { 19274 return true; 19275 } 19276 #else 19277 static bool is_ftm_mode_supported(void) 19278 { 19279 pr_err("FTM mode not supported!"); 19280 return false; 19281 } 19282 #endif 19283 19284 /** 19285 * is_con_mode_valid() - check con mode is valid or not 19286 * @mode: global con mode 19287 * 19288 * Return: TRUE on success FALSE on failure 19289 */ 19290 static bool is_con_mode_valid(enum QDF_GLOBAL_MODE mode) 19291 { 19292 switch (mode) { 19293 case QDF_GLOBAL_MONITOR_MODE: 19294 return is_monitor_mode_supported(); 19295 case QDF_GLOBAL_EPPING_MODE: 19296 return is_epping_mode_supported(); 19297 case QDF_GLOBAL_FTM_MODE: 19298 return is_ftm_mode_supported(); 19299 case QDF_GLOBAL_MISSION_MODE: 19300 return true; 19301 default: 19302 return false; 19303 } 19304 } 19305 19306 static void hdd_stop_present_mode(struct hdd_context *hdd_ctx, 19307 enum QDF_GLOBAL_MODE curr_mode) 19308 { 19309 if (hdd_ctx->driver_status == DRIVER_MODULES_CLOSED) 19310 return; 19311 19312 switch (curr_mode) { 19313 case QDF_GLOBAL_MONITOR_MODE: 19314 hdd_info("Release wakelock for monitor mode!"); 19315 qdf_wake_lock_release(&hdd_ctx->monitor_mode_wakelock, 19316 WIFI_POWER_EVENT_WAKELOCK_MONITOR_MODE); 19317 fallthrough; 19318 case QDF_GLOBAL_MISSION_MODE: 19319 case QDF_GLOBAL_FTM_MODE: 19320 hdd_abort_mac_scan_all_adapters(hdd_ctx); 19321 wlan_cfg80211_cleanup_scan_queue(hdd_ctx->pdev, NULL); 19322 hdd_stop_all_adapters(hdd_ctx); 19323 hdd_deinit_all_adapters(hdd_ctx, false); 19324 19325 break; 19326 default: 19327 break; 19328 } 19329 } 19330 19331 static void hdd_cleanup_present_mode(struct hdd_context *hdd_ctx, 19332 enum QDF_GLOBAL_MODE curr_mode) 19333 { 19334 switch (curr_mode) { 19335 case QDF_GLOBAL_MISSION_MODE: 19336 case QDF_GLOBAL_MONITOR_MODE: 19337 case QDF_GLOBAL_FTM_MODE: 19338 hdd_close_all_adapters(hdd_ctx, false); 19339 break; 19340 case QDF_GLOBAL_EPPING_MODE: 19341 epping_disable(); 19342 epping_close(); 19343 break; 19344 default: 19345 return; 19346 } 19347 } 19348 19349 static int 19350 hdd_parse_driver_mode(const char *mode_str, enum QDF_GLOBAL_MODE *out_mode) 19351 { 19352 QDF_STATUS status; 19353 uint32_t mode; 19354 19355 *out_mode = QDF_GLOBAL_MAX_MODE; 19356 19357 status = qdf_uint32_parse(mode_str, &mode); 19358 if (QDF_IS_STATUS_ERROR(status)) 19359 return qdf_status_to_os_return(status); 19360 19361 if (mode >= QDF_GLOBAL_MAX_MODE) 19362 return -ERANGE; 19363 19364 *out_mode = (enum QDF_GLOBAL_MODE)mode; 19365 19366 return 0; 19367 } 19368 19369 static int hdd_mode_change_psoc_idle_shutdown(struct device *dev) 19370 { 19371 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 19372 19373 if (!hdd_ctx) 19374 return -EINVAL; 19375 19376 return hdd_wlan_stop_modules(hdd_ctx, true); 19377 } 19378 19379 static int hdd_mode_change_psoc_idle_restart(struct device *dev) 19380 { 19381 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 19382 int ret; 19383 19384 if (!hdd_ctx) 19385 return -EINVAL; 19386 ret = hdd_soc_idle_restart_lock(dev); 19387 if (ret) 19388 return ret; 19389 ret = hdd_wlan_start_modules(hdd_ctx, false); 19390 hdd_soc_idle_restart_unlock(); 19391 19392 return ret; 19393 } 19394 19395 /** 19396 * __hdd_driver_mode_change() - Handles a driver mode change 19397 * @hdd_ctx: Pointer to the global HDD context 19398 * @next_mode: the driver mode to transition to 19399 * 19400 * This function is invoked when user updates con_mode using sys entry, 19401 * to initialize and bring-up driver in that specific mode. 19402 * 19403 * Return: Errno 19404 */ 19405 static int __hdd_driver_mode_change(struct hdd_context *hdd_ctx, 19406 enum QDF_GLOBAL_MODE next_mode) 19407 { 19408 enum QDF_GLOBAL_MODE curr_mode; 19409 int errno; 19410 struct bbm_params param = {0}; 19411 19412 hdd_info("Driver mode changing to %d", next_mode); 19413 19414 errno = wlan_hdd_validate_context(hdd_ctx); 19415 if (errno) 19416 return errno; 19417 19418 if (!is_con_mode_valid(next_mode)) { 19419 hdd_err_rl("Requested driver mode is invalid"); 19420 return -EINVAL; 19421 } 19422 19423 curr_mode = hdd_get_conparam(); 19424 if (curr_mode == next_mode) { 19425 hdd_err_rl("Driver is already in the requested mode"); 19426 return 0; 19427 } 19428 19429 hdd_psoc_idle_timer_stop(hdd_ctx); 19430 19431 /* ensure adapters are stopped */ 19432 hdd_stop_present_mode(hdd_ctx, curr_mode); 19433 19434 if (DRIVER_MODULES_CLOSED != hdd_ctx->driver_status) { 19435 is_mode_change_psoc_idle_shutdown = true; 19436 errno = pld_idle_shutdown(hdd_ctx->parent_dev, 19437 hdd_mode_change_psoc_idle_shutdown); 19438 if (errno) { 19439 is_mode_change_psoc_idle_shutdown = false; 19440 hdd_err("Stop wlan modules failed"); 19441 return errno; 19442 } 19443 } 19444 19445 /* Cleanup present mode before switching to new mode */ 19446 hdd_cleanup_present_mode(hdd_ctx, curr_mode); 19447 19448 hdd_set_conparam(next_mode); 19449 pld_set_mode(next_mode); 19450 19451 qdf_event_reset(&hdd_ctx->regulatory_update_event); 19452 qdf_mutex_acquire(&hdd_ctx->regulatory_status_lock); 19453 hdd_ctx->is_regulatory_update_in_progress = true; 19454 qdf_mutex_release(&hdd_ctx->regulatory_status_lock); 19455 19456 errno = pld_idle_restart(hdd_ctx->parent_dev, 19457 hdd_mode_change_psoc_idle_restart); 19458 if (errno) { 19459 hdd_err("Start wlan modules failed: %d", errno); 19460 return errno; 19461 } 19462 19463 errno = hdd_open_adapters_for_mode(hdd_ctx, next_mode); 19464 if (errno) { 19465 hdd_err("Failed to open adapters"); 19466 return errno; 19467 } 19468 19469 if (next_mode == QDF_GLOBAL_MONITOR_MODE) { 19470 struct hdd_adapter *adapter = 19471 hdd_get_adapter(hdd_ctx, QDF_MONITOR_MODE); 19472 19473 QDF_BUG(adapter); 19474 if (!adapter) { 19475 hdd_err("Failed to get monitor adapter"); 19476 return -EINVAL; 19477 } 19478 19479 errno = hdd_start_adapter(adapter, false); 19480 if (errno) { 19481 hdd_err("Failed to start monitor adapter"); 19482 return errno; 19483 } 19484 19485 hdd_info("Acquire wakelock for monitor mode"); 19486 qdf_wake_lock_acquire(&hdd_ctx->monitor_mode_wakelock, 19487 WIFI_POWER_EVENT_WAKELOCK_MONITOR_MODE); 19488 } 19489 19490 /* con_mode is a global module parameter */ 19491 con_mode = next_mode; 19492 hdd_info("Driver mode successfully changed to %d", next_mode); 19493 19494 param.policy = BBM_DRIVER_MODE_POLICY; 19495 param.policy_info.driver_mode = con_mode; 19496 ucfg_dp_bbm_apply_independent_policy(hdd_ctx->psoc, ¶m); 19497 19498 return 0; 19499 } 19500 19501 static int hdd_driver_mode_change(enum QDF_GLOBAL_MODE mode) 19502 { 19503 struct osif_driver_sync *driver_sync; 19504 struct hdd_context *hdd_ctx; 19505 QDF_STATUS status; 19506 int errno; 19507 19508 hdd_enter(); 19509 19510 status = osif_driver_sync_trans_start_wait(&driver_sync); 19511 if (QDF_IS_STATUS_ERROR(status)) { 19512 hdd_err("Failed to start 'mode change'; status:%u", status); 19513 errno = qdf_status_to_os_return(status); 19514 goto exit; 19515 } 19516 19517 osif_driver_sync_wait_for_ops(driver_sync); 19518 19519 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 19520 errno = wlan_hdd_validate_context(hdd_ctx); 19521 if (errno) 19522 goto trans_stop; 19523 19524 errno = __hdd_driver_mode_change(hdd_ctx, mode); 19525 19526 trans_stop: 19527 osif_driver_sync_trans_stop(driver_sync); 19528 19529 exit: 19530 hdd_exit(); 19531 19532 return errno; 19533 } 19534 19535 static int hdd_set_con_mode(enum QDF_GLOBAL_MODE mode) 19536 { 19537 con_mode = mode; 19538 19539 return 0; 19540 } 19541 19542 static int (*hdd_set_con_mode_cb)(enum QDF_GLOBAL_MODE mode) = hdd_set_con_mode; 19543 19544 static void hdd_driver_mode_change_register(void) 19545 { 19546 hdd_set_con_mode_cb = hdd_driver_mode_change; 19547 } 19548 19549 static void hdd_driver_mode_change_unregister(void) 19550 { 19551 hdd_set_con_mode_cb = hdd_set_con_mode; 19552 } 19553 19554 static int con_mode_handler(const char *kmessage, const struct kernel_param *kp) 19555 { 19556 enum QDF_GLOBAL_MODE mode; 19557 int errno; 19558 19559 errno = hdd_parse_driver_mode(kmessage, &mode); 19560 if (errno) { 19561 hdd_err_rl("Failed to parse driver mode '%s'", kmessage); 19562 return errno; 19563 } 19564 19565 return hdd_set_con_mode_cb(mode); 19566 } 19567 19568 /* 19569 * If the wlan_hdd_register_driver will return an error 19570 * if the wlan driver tries to register with the 19571 * platform driver before cnss_probe is completed. 19572 * Depending on the error code, the wlan driver waits 19573 * and retries to register. 19574 */ 19575 19576 /* Max number of retries (arbitrary)*/ 19577 #define HDD_MAX_PLD_REGISTER_RETRY (50) 19578 19579 /* Max amount of time we sleep before each retry */ 19580 #define HDD_PLD_REGISTER_FAIL_SLEEP_DURATION (100) 19581 19582 static int hdd_register_driver_retry(void) 19583 { 19584 int count = 0; 19585 int errno; 19586 19587 while (true) { 19588 errno = wlan_hdd_register_driver(); 19589 if (errno != -EAGAIN) 19590 return errno; 19591 hdd_nofl_info("Retry Platform Driver Registration; errno:%d count:%d", 19592 errno, count); 19593 if (++count == HDD_MAX_PLD_REGISTER_RETRY) 19594 return errno; 19595 msleep(HDD_PLD_REGISTER_FAIL_SLEEP_DURATION); 19596 continue; 19597 } 19598 19599 return errno; 19600 } 19601 19602 /** 19603 * hdd_create_wifi_feature_interface() - Create wifi feature interface 19604 * 19605 * Return: none 19606 */ 19607 static void hdd_create_wifi_feature_interface(void) 19608 { 19609 hdd_sysfs_create_wifi_root_obj(); 19610 hdd_create_wifi_feature_interface_sysfs_file(); 19611 } 19612 19613 int hdd_driver_load(void) 19614 { 19615 struct osif_driver_sync *driver_sync; 19616 QDF_STATUS status; 19617 int errno; 19618 bool soft_load; 19619 19620 pr_info("%s: Loading driver v%s\n", WLAN_MODULE_NAME, 19621 g_wlan_driver_version); 19622 hdd_place_marker(NULL, "START LOADING", NULL); 19623 19624 status = hdd_qdf_init(); 19625 if (QDF_IS_STATUS_ERROR(status)) { 19626 errno = qdf_status_to_os_return(status); 19627 goto exit; 19628 } 19629 19630 osif_sync_init(); 19631 19632 status = osif_driver_sync_create_and_trans(&driver_sync); 19633 if (QDF_IS_STATUS_ERROR(status)) { 19634 hdd_err("Failed to init driver sync; status:%u", status); 19635 errno = qdf_status_to_os_return(status); 19636 goto sync_deinit; 19637 } 19638 19639 errno = hdd_init(); 19640 if (errno) { 19641 hdd_err("Failed to init HDD; errno:%d", errno); 19642 goto trans_stop; 19643 } 19644 19645 status = hdd_component_cb_init(); 19646 if (QDF_IS_STATUS_ERROR(status)) { 19647 hdd_err("Failed to init component cb; status:%u", status); 19648 errno = qdf_status_to_os_return(status); 19649 goto hdd_deinit; 19650 } 19651 19652 status = hdd_component_init(); 19653 if (QDF_IS_STATUS_ERROR(status)) { 19654 hdd_err("Failed to init components; status:%u", status); 19655 errno = qdf_status_to_os_return(status); 19656 goto comp_cb_deinit; 19657 } 19658 19659 status = qdf_wake_lock_create(&wlan_wake_lock, "wlan"); 19660 if (QDF_IS_STATUS_ERROR(status)) { 19661 hdd_err("Failed to create wake lock; status:%u", status); 19662 errno = qdf_status_to_os_return(status); 19663 goto comp_deinit; 19664 } 19665 19666 hdd_set_conparam(con_mode); 19667 19668 errno = pld_init(); 19669 if (errno) { 19670 hdd_err("Failed to init PLD; errno:%d", errno); 19671 goto wakelock_destroy; 19672 } 19673 19674 /* driver mode pass to cnss2 platform driver*/ 19675 errno = pld_set_mode(con_mode); 19676 if (errno) 19677 hdd_err("Failed to set mode in PLD; errno:%d", errno); 19678 19679 hdd_driver_mode_change_register(); 19680 19681 osif_driver_sync_register(driver_sync); 19682 osif_driver_sync_trans_stop(driver_sync); 19683 19684 /* psoc probe can happen in registration; do after 'load' transition */ 19685 errno = hdd_register_driver_retry(); 19686 if (errno) { 19687 hdd_err("Failed to register driver; errno:%d", errno); 19688 goto pld_deinit; 19689 } 19690 19691 /* If a soft unload of driver is done, we don't call 19692 * wlan_hdd_state_ctrl_param_destroy() to maintain sync 19693 * with userspace. In Symmetry, during soft load, avoid 19694 * calling wlan_hdd_state_ctrl_param_create(). 19695 */ 19696 soft_load = hdd_get_wlan_driver_status(); 19697 if (soft_load) 19698 goto out; 19699 19700 errno = wlan_hdd_state_ctrl_param_create(); 19701 if (errno) { 19702 hdd_err("Failed to create ctrl param; errno:%d", errno); 19703 goto unregister_driver; 19704 } 19705 hdd_create_wifi_feature_interface(); 19706 out: 19707 hdd_debug("%s: driver loaded", WLAN_MODULE_NAME); 19708 hdd_place_marker(NULL, "DRIVER LOADED", NULL); 19709 19710 return 0; 19711 19712 unregister_driver: 19713 wlan_hdd_unregister_driver(); 19714 pld_deinit: 19715 status = osif_driver_sync_trans_start(&driver_sync); 19716 QDF_BUG(QDF_IS_STATUS_SUCCESS(status)); 19717 19718 osif_driver_sync_unregister(); 19719 if (driver_sync) 19720 osif_driver_sync_wait_for_ops(driver_sync); 19721 19722 hdd_driver_mode_change_unregister(); 19723 pld_deinit(); 19724 19725 hdd_start_complete(errno); 19726 /* Wait for any ref taken on /dev/wlan to be released */ 19727 while (qdf_atomic_read(&wlan_hdd_state_fops_ref)) 19728 ; 19729 wakelock_destroy: 19730 qdf_wake_lock_destroy(&wlan_wake_lock); 19731 comp_deinit: 19732 hdd_component_deinit(); 19733 comp_cb_deinit: 19734 hdd_component_cb_deinit(); 19735 hdd_deinit: 19736 hdd_deinit(); 19737 trans_stop: 19738 if (driver_sync) { 19739 osif_driver_sync_trans_stop(driver_sync); 19740 osif_driver_sync_destroy(driver_sync); 19741 } 19742 sync_deinit: 19743 osif_sync_deinit(); 19744 hdd_qdf_deinit(); 19745 19746 exit: 19747 return errno; 19748 } 19749 19750 #ifdef FEATURE_WLAN_RESIDENT_DRIVER 19751 EXPORT_SYMBOL(hdd_driver_load); 19752 #endif 19753 19754 /** 19755 * hdd_distroy_wifi_feature_interface() - Distroy wifi feature interface 19756 * 19757 * Return: none 19758 */ 19759 static void hdd_distroy_wifi_feature_interface(void) 19760 { 19761 hdd_destroy_wifi_feature_interface_sysfs_file(); 19762 hdd_sysfs_destroy_wifi_root_obj(); 19763 } 19764 19765 void hdd_driver_unload(void) 19766 { 19767 struct osif_driver_sync *driver_sync; 19768 struct hdd_context *hdd_ctx; 19769 QDF_STATUS status; 19770 void *hif_ctx; 19771 bool soft_unload; 19772 19773 soft_unload = hdd_get_wlan_driver_status(); 19774 if (soft_unload) { 19775 pr_info("%s: Soft Unloading driver v%s\n", WLAN_MODULE_NAME, 19776 QWLAN_VERSIONSTR); 19777 } else { 19778 pr_info("%s: Hard Unloading driver v%s\n", WLAN_MODULE_NAME, 19779 QWLAN_VERSIONSTR); 19780 } 19781 19782 hdd_place_marker(NULL, "START UNLOADING", NULL); 19783 19784 /* 19785 * Wait for any trans to complete and then start the driver trans 19786 * for the unload. This will ensure that the driver trans proceeds only 19787 * after all trans have been completed. As a part of this trans, set 19788 * the driver load/unload flag to further ensure that any upcoming 19789 * trans are rejected via wlan_hdd_validate_context. 19790 */ 19791 status = osif_driver_sync_trans_start_wait(&driver_sync); 19792 QDF_BUG(QDF_IS_STATUS_SUCCESS(status)); 19793 if (QDF_IS_STATUS_ERROR(status)) { 19794 hdd_err("Unable to unload wlan; status:%u", status); 19795 hdd_place_marker(NULL, "UNLOAD FAILURE", NULL); 19796 return; 19797 } 19798 19799 hif_ctx = cds_get_context(QDF_MODULE_ID_HIF); 19800 if (hif_ctx) { 19801 /* 19802 * Trigger runtime sync resume before setting unload in progress 19803 * such that resume can happen successfully 19804 */ 19805 qdf_rtpm_sync_resume(); 19806 } 19807 19808 cds_set_driver_loaded(false); 19809 cds_set_unload_in_progress(true); 19810 19811 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 19812 if (hdd_ctx) { 19813 hdd_psoc_idle_timer_stop(hdd_ctx); 19814 /* 19815 * Runtime PM sync resume may have started the bus bandwidth 19816 * periodic work hence stop it. 19817 */ 19818 ucfg_dp_bus_bw_compute_timer_stop(hdd_ctx->psoc); 19819 } 19820 19821 /* 19822 * Stop the trans before calling unregister_driver as that involves a 19823 * call to pld_remove which in itself is a psoc transaction 19824 */ 19825 osif_driver_sync_trans_stop(driver_sync); 19826 19827 hdd_distroy_wifi_feature_interface(); 19828 if (!soft_unload) 19829 wlan_hdd_state_ctrl_param_destroy(); 19830 19831 /* trigger SoC remove */ 19832 wlan_hdd_unregister_driver(); 19833 19834 status = osif_driver_sync_trans_start_wait(&driver_sync); 19835 QDF_BUG(QDF_IS_STATUS_SUCCESS(status)); 19836 if (QDF_IS_STATUS_ERROR(status)) { 19837 hdd_err("Unable to unload wlan; status:%u", status); 19838 hdd_place_marker(NULL, "UNLOAD FAILURE", NULL); 19839 return; 19840 } 19841 19842 osif_driver_sync_unregister(); 19843 osif_driver_sync_wait_for_ops(driver_sync); 19844 19845 hdd_driver_mode_change_unregister(); 19846 pld_deinit(); 19847 hdd_set_conparam(0); 19848 qdf_wake_lock_destroy(&wlan_wake_lock); 19849 hdd_component_deinit(); 19850 hdd_component_cb_deinit(); 19851 hdd_deinit(); 19852 19853 osif_driver_sync_trans_stop(driver_sync); 19854 osif_driver_sync_destroy(driver_sync); 19855 19856 osif_sync_deinit(); 19857 19858 hdd_qdf_deinit(); 19859 hdd_place_marker(NULL, "UNLOAD DONE", NULL); 19860 } 19861 19862 #ifdef FEATURE_WLAN_RESIDENT_DRIVER 19863 EXPORT_SYMBOL(hdd_driver_unload); 19864 #endif 19865 19866 #ifndef MODULE 19867 /** 19868 * wlan_boot_cb() - Wlan boot callback 19869 * @kobj: object whose directory we're creating the link in. 19870 * @attr: attribute the user is interacting with 19871 * @buf: the buffer containing the user data 19872 * @count: number of bytes in the buffer 19873 * 19874 * This callback is invoked when the fs is ready to start the 19875 * wlan driver initialization. 19876 * 19877 * Return: 'count' on success or a negative error code in case of failure 19878 */ 19879 static ssize_t wlan_boot_cb(struct kobject *kobj, 19880 struct kobj_attribute *attr, 19881 const char *buf, 19882 size_t count) 19883 { 19884 19885 if (wlan_loader->loaded_state) { 19886 hdd_err("wlan driver already initialized"); 19887 return -EALREADY; 19888 } 19889 19890 if (hdd_driver_load()) 19891 return -EIO; 19892 19893 wlan_loader->loaded_state = MODULE_INITIALIZED; 19894 19895 return count; 19896 } 19897 19898 /** 19899 * hdd_sysfs_cleanup() - cleanup sysfs 19900 * 19901 * Return: None 19902 * 19903 */ 19904 static void hdd_sysfs_cleanup(void) 19905 { 19906 /* remove from group */ 19907 if (wlan_loader->boot_wlan_obj && wlan_loader->attr_group) 19908 sysfs_remove_group(wlan_loader->boot_wlan_obj, 19909 wlan_loader->attr_group); 19910 19911 /* unlink the object from parent */ 19912 kobject_del(wlan_loader->boot_wlan_obj); 19913 19914 /* free the object */ 19915 kobject_put(wlan_loader->boot_wlan_obj); 19916 19917 kfree(wlan_loader->attr_group); 19918 kfree(wlan_loader); 19919 19920 wlan_loader = NULL; 19921 } 19922 19923 /** 19924 * wlan_init_sysfs() - Creates the sysfs to be invoked when the fs is 19925 * ready 19926 * 19927 * This is creates the syfs entry boot_wlan. Which shall be invoked 19928 * when the filesystem is ready. 19929 * 19930 * QDF API cannot be used here since this function is called even before 19931 * initializing WLAN driver. 19932 * 19933 * Return: 0 for success, errno on failure 19934 */ 19935 static int wlan_init_sysfs(void) 19936 { 19937 int ret = -ENOMEM; 19938 19939 wlan_loader = kzalloc(sizeof(*wlan_loader), GFP_KERNEL); 19940 if (!wlan_loader) 19941 return -ENOMEM; 19942 19943 wlan_loader->boot_wlan_obj = NULL; 19944 wlan_loader->attr_group = kzalloc(sizeof(*(wlan_loader->attr_group)), 19945 GFP_KERNEL); 19946 if (!wlan_loader->attr_group) 19947 goto error_return; 19948 19949 wlan_loader->loaded_state = 0; 19950 wlan_loader->attr_group->attrs = attrs; 19951 19952 wlan_loader->boot_wlan_obj = kobject_create_and_add(WLAN_LOADER_NAME, 19953 kernel_kobj); 19954 if (!wlan_loader->boot_wlan_obj) { 19955 hdd_err("sysfs create and add failed"); 19956 goto error_return; 19957 } 19958 19959 ret = sysfs_create_group(wlan_loader->boot_wlan_obj, 19960 wlan_loader->attr_group); 19961 if (ret) { 19962 hdd_err("sysfs create group failed; errno:%d", ret); 19963 goto error_return; 19964 } 19965 19966 return 0; 19967 19968 error_return: 19969 hdd_sysfs_cleanup(); 19970 19971 return ret; 19972 } 19973 19974 /** 19975 * wlan_deinit_sysfs() - Removes the sysfs created to initialize the wlan 19976 * 19977 * Return: 0 on success or errno on failure 19978 */ 19979 static int wlan_deinit_sysfs(void) 19980 { 19981 if (!wlan_loader) { 19982 hdd_err("wlan_loader is null"); 19983 return -EINVAL; 19984 } 19985 19986 hdd_sysfs_cleanup(); 19987 return 0; 19988 } 19989 19990 #endif /* MODULE */ 19991 19992 #ifdef MODULE 19993 /** 19994 * hdd_module_init() - Module init helper 19995 * 19996 * Module init helper function used by both module and static driver. 19997 * 19998 * Return: 0 for success, errno on failure 19999 */ 20000 #ifdef FEATURE_WLAN_RESIDENT_DRIVER 20001 static int hdd_module_init(void) 20002 { 20003 return 0; 20004 } 20005 #else 20006 static int hdd_module_init(void) 20007 { 20008 if (hdd_driver_load()) 20009 return -EINVAL; 20010 20011 return 0; 20012 } 20013 #endif 20014 #else 20015 static int __init hdd_module_init(void) 20016 { 20017 int ret = -EINVAL; 20018 20019 ret = wlan_init_sysfs(); 20020 if (ret) 20021 hdd_err("Failed to create sysfs entry"); 20022 20023 return ret; 20024 } 20025 #endif 20026 20027 20028 #ifdef MODULE 20029 /** 20030 * hdd_module_exit() - Exit function 20031 * 20032 * This is the driver exit point (invoked when module is unloaded using rmmod) 20033 * 20034 * Return: None 20035 */ 20036 #ifdef FEATURE_WLAN_RESIDENT_DRIVER 20037 static void __exit hdd_module_exit(void) 20038 { 20039 } 20040 #else 20041 static void __exit hdd_module_exit(void) 20042 { 20043 hdd_driver_unload(); 20044 } 20045 #endif 20046 #else 20047 static void __exit hdd_module_exit(void) 20048 { 20049 hdd_driver_unload(); 20050 wlan_deinit_sysfs(); 20051 } 20052 #endif 20053 20054 static int fwpath_changed_handler(const char *kmessage, 20055 const struct kernel_param *kp) 20056 { 20057 return param_set_copystring(kmessage, kp); 20058 } 20059 20060 static int con_mode_handler_ftm(const char *kmessage, 20061 const struct kernel_param *kp) 20062 { 20063 int ret; 20064 20065 ret = param_set_int(kmessage, kp); 20066 20067 if (cds_is_driver_loaded() || cds_is_load_or_unload_in_progress()) { 20068 pr_err("Driver already loaded or load/unload in progress"); 20069 return -ENOTSUPP; 20070 } 20071 20072 if (con_mode_ftm != QDF_GLOBAL_FTM_MODE) { 20073 pr_err("Only FTM mode supported!"); 20074 return -ENOTSUPP; 20075 } 20076 20077 hdd_set_conparam(con_mode_ftm); 20078 con_mode = con_mode_ftm; 20079 20080 return ret; 20081 } 20082 20083 #ifdef WLAN_FEATURE_EPPING 20084 static int con_mode_handler_epping(const char *kmessage, 20085 const struct kernel_param *kp) 20086 { 20087 int ret; 20088 20089 ret = param_set_int(kmessage, kp); 20090 20091 if (con_mode_epping != QDF_GLOBAL_EPPING_MODE) { 20092 pr_err("Only EPPING mode supported!"); 20093 return -ENOTSUPP; 20094 } 20095 20096 hdd_set_conparam(con_mode_epping); 20097 con_mode = con_mode_epping; 20098 20099 return ret; 20100 } 20101 #endif 20102 20103 /** 20104 * hdd_get_conparam() - driver exit point 20105 * 20106 * This is the driver exit point (invoked when module is unloaded using rmmod) 20107 * 20108 * Return: enum QDF_GLOBAL_MODE 20109 */ 20110 enum QDF_GLOBAL_MODE hdd_get_conparam(void) 20111 { 20112 return (enum QDF_GLOBAL_MODE) curr_con_mode; 20113 } 20114 20115 void hdd_set_conparam(int32_t con_param) 20116 { 20117 curr_con_mode = con_param; 20118 } 20119 20120 /** 20121 * hdd_svc_fw_crashed_ind() - API to send FW CRASHED IND to Userspace 20122 * 20123 * Return: void 20124 */ 20125 static void hdd_svc_fw_crashed_ind(void) 20126 { 20127 struct hdd_context *hdd_ctx; 20128 20129 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 20130 20131 hdd_ctx ? wlan_hdd_send_svc_nlink_msg(hdd_ctx->radio_index, 20132 WLAN_SVC_FW_CRASHED_IND, 20133 NULL, 0) : 0; 20134 } 20135 20136 /** 20137 * hdd_update_ol_config - API to update ol configuration parameters 20138 * @hdd_ctx: HDD context 20139 * 20140 * Return: void 20141 */ 20142 static void hdd_update_ol_config(struct hdd_context *hdd_ctx) 20143 { 20144 struct ol_config_info cfg = {0}; 20145 struct ol_context *ol_ctx = cds_get_context(QDF_MODULE_ID_BMI); 20146 bool self_recovery = false; 20147 QDF_STATUS status; 20148 20149 if (!ol_ctx) 20150 return; 20151 20152 status = ucfg_mlme_get_self_recovery(hdd_ctx->psoc, &self_recovery); 20153 if (QDF_IS_STATUS_ERROR(status)) 20154 hdd_err("Failed to get self recovery ini config"); 20155 20156 cfg.enable_self_recovery = self_recovery; 20157 cfg.enable_uart_print = hdd_ctx->config->enablefwprint; 20158 cfg.enable_fw_log = hdd_ctx->config->enable_fw_log; 20159 cfg.enable_ramdump_collection = hdd_ctx->config->is_ramdump_enabled; 20160 cfg.enable_lpass_support = hdd_lpass_is_supported(hdd_ctx); 20161 20162 ol_init_ini_config(ol_ctx, &cfg); 20163 ol_set_fw_crashed_cb(ol_ctx, hdd_svc_fw_crashed_ind); 20164 } 20165 20166 #ifdef FEATURE_RUNTIME_PM 20167 /** 20168 * hdd_populate_runtime_cfg() - populate runtime configuration 20169 * @hdd_ctx: hdd context 20170 * @cfg: pointer to the configuration memory being populated 20171 * 20172 * Return: void 20173 */ 20174 static void hdd_populate_runtime_cfg(struct hdd_context *hdd_ctx, 20175 struct hif_config_info *cfg) 20176 { 20177 cfg->enable_runtime_pm = hdd_ctx->config->runtime_pm; 20178 cfg->runtime_pm_delay = 20179 ucfg_pmo_get_runtime_pm_delay(hdd_ctx->psoc); 20180 } 20181 #else 20182 static void hdd_populate_runtime_cfg(struct hdd_context *hdd_ctx, 20183 struct hif_config_info *cfg) 20184 { 20185 } 20186 #endif 20187 20188 /** 20189 * hdd_update_hif_config - API to update HIF configuration parameters 20190 * @hdd_ctx: HDD Context 20191 * 20192 * Return: void 20193 */ 20194 static void hdd_update_hif_config(struct hdd_context *hdd_ctx) 20195 { 20196 struct hif_opaque_softc *scn = cds_get_context(QDF_MODULE_ID_HIF); 20197 struct hif_config_info cfg = {0}; 20198 bool prevent_link_down = false; 20199 bool self_recovery = false; 20200 QDF_STATUS status; 20201 20202 if (!scn) 20203 return; 20204 20205 status = ucfg_mlme_get_prevent_link_down(hdd_ctx->psoc, 20206 &prevent_link_down); 20207 if (QDF_IS_STATUS_ERROR(status)) 20208 hdd_err("Failed to get prevent_link_down config"); 20209 20210 status = ucfg_mlme_get_self_recovery(hdd_ctx->psoc, &self_recovery); 20211 if (QDF_IS_STATUS_ERROR(status)) 20212 hdd_err("Failed to get self recovery ini config"); 20213 20214 cfg.enable_self_recovery = self_recovery; 20215 hdd_populate_runtime_cfg(hdd_ctx, &cfg); 20216 cfg.rx_softirq_max_yield_duration_ns = 20217 ucfg_dp_get_rx_softirq_yield_duration(hdd_ctx->psoc); 20218 20219 hif_init_ini_config(scn, &cfg); 20220 20221 if (prevent_link_down) 20222 hif_vote_link_up(scn); 20223 } 20224 20225 /** 20226 * hdd_update_dp_config() - Propagate config parameters to Lithium 20227 * datapath 20228 * @hdd_ctx: HDD Context 20229 * 20230 * Return: 0 for success/errno for failure 20231 */ 20232 static int hdd_update_dp_config(struct hdd_context *hdd_ctx) 20233 { 20234 struct wlan_dp_user_config dp_cfg; 20235 QDF_STATUS status; 20236 20237 dp_cfg.ipa_enable = ucfg_ipa_is_enabled(); 20238 dp_cfg.arp_connectivity_map = CONNECTIVITY_CHECK_SET_ARP; 20239 20240 status = ucfg_dp_update_config(hdd_ctx->psoc, &dp_cfg); 20241 if (status != QDF_STATUS_SUCCESS) { 20242 hdd_err("failed DP PSOC configuration update"); 20243 return -EINVAL; 20244 } 20245 20246 return 0; 20247 } 20248 20249 /** 20250 * hdd_update_config() - Initialize driver per module ini parameters 20251 * @hdd_ctx: HDD Context 20252 * 20253 * API is used to initialize all driver per module configuration parameters 20254 * Return: 0 for success, errno for failure 20255 */ 20256 int hdd_update_config(struct hdd_context *hdd_ctx) 20257 { 20258 int ret; 20259 20260 if (ucfg_pmo_is_ns_offloaded(hdd_ctx->psoc)) 20261 hdd_ctx->ns_offload_enable = true; 20262 20263 hdd_update_ol_config(hdd_ctx); 20264 hdd_update_hif_config(hdd_ctx); 20265 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) 20266 ret = hdd_update_cds_config_ftm(hdd_ctx); 20267 else 20268 ret = hdd_update_cds_config(hdd_ctx); 20269 ret = hdd_update_user_config(hdd_ctx); 20270 20271 hdd_update_regdb_offload_config(hdd_ctx); 20272 20273 return ret; 20274 } 20275 20276 /** 20277 * hdd_update_pmo_config - API to update pmo configuration parameters 20278 * @hdd_ctx: HDD context 20279 * 20280 * Return: void 20281 */ 20282 static int hdd_update_pmo_config(struct hdd_context *hdd_ctx) 20283 { 20284 struct pmo_psoc_cfg psoc_cfg = {0}; 20285 QDF_STATUS status; 20286 enum pmo_wow_enable_type wow_enable; 20287 20288 ucfg_pmo_get_psoc_config(hdd_ctx->psoc, &psoc_cfg); 20289 20290 /* 20291 * Value of hdd_ctx->wowEnable can be, 20292 * 0 - Disable both magic pattern match and pattern byte match. 20293 * 1 - Enable magic pattern match on all interfaces. 20294 * 2 - Enable pattern byte match on all interfaces. 20295 * 3 - Enable both magic pattern and pattern byte match on 20296 * all interfaces. 20297 */ 20298 wow_enable = ucfg_pmo_get_wow_enable(hdd_ctx->psoc); 20299 psoc_cfg.magic_ptrn_enable = (wow_enable & 0x01) ? true : false; 20300 psoc_cfg.ptrn_match_enable_all_vdev = 20301 (wow_enable & 0x02) ? true : false; 20302 psoc_cfg.ap_arpns_support = hdd_ctx->ap_arpns_support; 20303 psoc_cfg.d0_wow_supported = wma_d0_wow_is_supported(); 20304 ucfg_mlme_get_sap_max_modulated_dtim(hdd_ctx->psoc, 20305 &psoc_cfg.sta_max_li_mod_dtim); 20306 20307 hdd_lpass_populate_pmo_config(&psoc_cfg, hdd_ctx); 20308 20309 status = ucfg_pmo_update_psoc_config(hdd_ctx->psoc, &psoc_cfg); 20310 if (QDF_IS_STATUS_ERROR(status)) 20311 hdd_err("failed pmo psoc configuration; status:%d", status); 20312 20313 return qdf_status_to_os_return(status); 20314 } 20315 20316 void hdd_update_ie_allowlist_attr(struct probe_req_allowlist_attr *ie_allowlist, 20317 struct hdd_context *hdd_ctx) 20318 { 20319 struct wlan_fwol_ie_allowlist allowlist = {0}; 20320 struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc; 20321 QDF_STATUS status; 20322 bool is_ie_allowlist_enable = false; 20323 uint8_t i = 0; 20324 20325 status = ucfg_fwol_get_ie_allowlist(psoc, &is_ie_allowlist_enable); 20326 if (QDF_IS_STATUS_ERROR(status)) { 20327 hdd_err("Unable to get IE allowlist param"); 20328 return; 20329 } 20330 20331 ie_allowlist->allow_list = is_ie_allowlist_enable; 20332 if (!ie_allowlist->allow_list) 20333 return; 20334 20335 status = ucfg_fwol_get_all_allowlist_params(psoc, &allowlist); 20336 if (QDF_IS_STATUS_ERROR(status)) { 20337 hdd_err("Unable to get all allowlist params"); 20338 return; 20339 } 20340 20341 ie_allowlist->ie_bitmap[0] = allowlist.ie_bitmap_0; 20342 ie_allowlist->ie_bitmap[1] = allowlist.ie_bitmap_1; 20343 ie_allowlist->ie_bitmap[2] = allowlist.ie_bitmap_2; 20344 ie_allowlist->ie_bitmap[3] = allowlist.ie_bitmap_3; 20345 ie_allowlist->ie_bitmap[4] = allowlist.ie_bitmap_4; 20346 ie_allowlist->ie_bitmap[5] = allowlist.ie_bitmap_5; 20347 ie_allowlist->ie_bitmap[6] = allowlist.ie_bitmap_6; 20348 ie_allowlist->ie_bitmap[7] = allowlist.ie_bitmap_7; 20349 20350 ie_allowlist->num_vendor_oui = allowlist.no_of_probe_req_ouis; 20351 for (i = 0; i < ie_allowlist->num_vendor_oui; i++) 20352 ie_allowlist->voui[i] = allowlist.probe_req_voui[i]; 20353 } 20354 20355 QDF_STATUS hdd_update_score_config(struct hdd_context *hdd_ctx) 20356 { 20357 struct hdd_config *cfg = hdd_ctx->config; 20358 eCsrPhyMode phy_mode = hdd_cfg_xlate_to_csr_phy_mode(cfg->dot11Mode); 20359 20360 sme_update_score_config(hdd_ctx->mac_handle, phy_mode, 20361 hdd_ctx->num_rf_chains); 20362 20363 return QDF_STATUS_SUCCESS; 20364 } 20365 20366 /** 20367 * hdd_update_dfs_config() - API to update dfs configuration parameters. 20368 * @hdd_ctx: HDD context 20369 * 20370 * Return: 0 if success else err 20371 */ 20372 static int hdd_update_dfs_config(struct hdd_context *hdd_ctx) 20373 { 20374 struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc; 20375 struct dfs_user_config dfs_cfg = {0}; 20376 QDF_STATUS status; 20377 20378 ucfg_mlme_get_dfs_filter_offload(hdd_ctx->psoc, 20379 &dfs_cfg.dfs_is_phyerr_filter_offload); 20380 status = ucfg_dfs_update_config(psoc, &dfs_cfg); 20381 if (QDF_IS_STATUS_ERROR(status)) { 20382 hdd_err("failed dfs psoc configuration"); 20383 return -EINVAL; 20384 } 20385 20386 return 0; 20387 } 20388 20389 /** 20390 * hdd_update_scan_config - API to update scan configuration parameters 20391 * @hdd_ctx: HDD context 20392 * 20393 * Return: 0 if success else err 20394 */ 20395 int hdd_update_scan_config(struct hdd_context *hdd_ctx) 20396 { 20397 struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc; 20398 struct scan_user_cfg scan_cfg; 20399 QDF_STATUS status; 20400 uint32_t mcast_mcc_rest_time = 0; 20401 20402 qdf_mem_zero(&scan_cfg, sizeof(scan_cfg)); 20403 status = ucfg_mlme_get_sta_miracast_mcc_rest_time(hdd_ctx->psoc, 20404 &mcast_mcc_rest_time); 20405 if (!QDF_IS_STATUS_SUCCESS(status)) { 20406 hdd_err("ucfg_mlme_get_sta_miracast_mcc_rest_time, use def"); 20407 return -EIO; 20408 } 20409 scan_cfg.sta_miracast_mcc_rest_time = mcast_mcc_rest_time; 20410 hdd_update_ie_allowlist_attr(&scan_cfg.ie_allowlist, hdd_ctx); 20411 20412 status = ucfg_scan_update_user_config(psoc, &scan_cfg); 20413 if (status != QDF_STATUS_SUCCESS) { 20414 hdd_err("failed pmo psoc configuration"); 20415 return -EINVAL; 20416 } 20417 20418 return 0; 20419 } 20420 20421 int hdd_update_components_config(struct hdd_context *hdd_ctx) 20422 { 20423 int ret; 20424 20425 ret = hdd_update_pmo_config(hdd_ctx); 20426 if (ret) 20427 return ret; 20428 20429 ret = hdd_update_scan_config(hdd_ctx); 20430 if (ret) 20431 return ret; 20432 20433 ret = hdd_update_tdls_config(hdd_ctx); 20434 if (ret) 20435 return ret; 20436 20437 ret = hdd_update_dp_config(hdd_ctx); 20438 if (ret) 20439 return ret; 20440 20441 ret = hdd_update_dfs_config(hdd_ctx); 20442 if (ret) 20443 return ret; 20444 20445 ret = hdd_update_regulatory_config(hdd_ctx); 20446 if (ret) 20447 return ret; 20448 20449 return ret; 20450 } 20451 20452 /** 20453 * wlan_hdd_get_dfs_mode() - get ACS DFS mode 20454 * @mode : cfg80211 DFS mode 20455 * 20456 * Return: return SAP ACS DFS mode else return ACS_DFS_MODE_NONE 20457 */ 20458 enum sap_acs_dfs_mode wlan_hdd_get_dfs_mode(enum dfs_mode mode) 20459 { 20460 switch (mode) { 20461 case DFS_MODE_ENABLE: 20462 return ACS_DFS_MODE_ENABLE; 20463 case DFS_MODE_DISABLE: 20464 return ACS_DFS_MODE_DISABLE; 20465 case DFS_MODE_DEPRIORITIZE: 20466 return ACS_DFS_MODE_DEPRIORITIZE; 20467 default: 20468 hdd_debug("ACS dfs mode is NONE"); 20469 return ACS_DFS_MODE_NONE; 20470 } 20471 } 20472 20473 /** 20474 * hdd_enable_disable_ca_event() - enable/disable channel avoidance event 20475 * @hdd_ctx: pointer to hdd context 20476 * @set_value: enable/disable 20477 * 20478 * When Host sends vendor command enable, FW will send *ONE* CA ind to 20479 * Host(even though it is duplicate). When Host send vendor command 20480 * disable,FW doesn't perform any action. Whenever any change in 20481 * CA *and* WLAN is in SAP/P2P-GO mode, FW sends CA ind to host. 20482 * 20483 * return - 0 on success, appropriate error values on failure. 20484 */ 20485 int hdd_enable_disable_ca_event(struct hdd_context *hdd_ctx, uint8_t set_value) 20486 { 20487 QDF_STATUS status; 20488 20489 if (0 != wlan_hdd_validate_context(hdd_ctx)) 20490 return -EAGAIN; 20491 20492 status = sme_enable_disable_chanavoidind_event(hdd_ctx->mac_handle, 20493 set_value); 20494 if (!QDF_IS_STATUS_SUCCESS(status)) { 20495 hdd_err("Failed to send chan avoid command to SME"); 20496 return -EINVAL; 20497 } 20498 return 0; 20499 } 20500 20501 bool hdd_is_roaming_in_progress(struct hdd_context *hdd_ctx) 20502 { 20503 struct hdd_adapter *adapter = NULL, *next_adapter = NULL; 20504 uint8_t vdev_id; 20505 wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_IS_ROAMING_IN_PROGRESS; 20506 struct wlan_hdd_link_info *link_info; 20507 20508 if (!hdd_ctx) { 20509 hdd_err("HDD context is NULL"); 20510 return false; 20511 } 20512 20513 if (!policy_mgr_is_sta_active_connection_exists(hdd_ctx->psoc)) 20514 return false; 20515 20516 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 20517 dbgid) { 20518 if (adapter->device_mode != QDF_STA_MODE) 20519 goto adapter_put; 20520 20521 hdd_adapter_for_each_active_link_info(adapter, link_info) { 20522 vdev_id = link_info->vdev_id; 20523 if (test_bit(SME_SESSION_OPENED, 20524 &link_info->link_flags) && 20525 sme_roaming_in_progress(hdd_ctx->mac_handle, 20526 vdev_id)) { 20527 hdd_debug("Roaming is in progress on:vdev_id:%d", 20528 link_info->vdev_id); 20529 hdd_adapter_dev_put_debug(adapter, dbgid); 20530 if (next_adapter) 20531 hdd_adapter_dev_put_debug(next_adapter, 20532 dbgid); 20533 return true; 20534 } 20535 } 20536 adapter_put: 20537 hdd_adapter_dev_put_debug(adapter, dbgid); 20538 } 20539 20540 return false; 20541 } 20542 20543 /** 20544 * struct hdd_is_connection_in_progress_priv - adapter connection info 20545 * @out_vdev_id: id of vdev where connection is occurring 20546 * @out_reason: scan reject reason 20547 * @connection_in_progress: true if connection is in progress 20548 */ 20549 struct hdd_is_connection_in_progress_priv { 20550 uint8_t out_vdev_id; 20551 enum scan_reject_states out_reason; 20552 bool connection_in_progress; 20553 }; 20554 20555 /** 20556 * hdd_is_connection_in_progress_iterator() - Check adapter connection based 20557 * on device mode 20558 * @link_info: Link info pointer in HDD adapter 20559 * @ctx: user context supplied 20560 * 20561 * Check if connection is in progress for the current adapter according to the 20562 * device mode 20563 * 20564 * Return: 20565 * * QDF_STATUS_SUCCESS if iteration should continue 20566 * * QDF_STATUS_E_ABORTED if iteration should be aborted 20567 */ 20568 static QDF_STATUS 20569 hdd_is_connection_in_progress_iterator(struct wlan_hdd_link_info *link_info, 20570 void *ctx) 20571 { 20572 struct hdd_station_ctx *hdd_sta_ctx; 20573 uint8_t *sta_mac; 20574 struct hdd_context *hdd_ctx; 20575 mac_handle_t mac_handle; 20576 struct hdd_station_info *sta_info, *tmp = NULL; 20577 struct hdd_is_connection_in_progress_priv *context = ctx; 20578 struct hdd_adapter *adapter = link_info->adapter; 20579 20580 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 20581 if (!hdd_ctx) 20582 return QDF_STATUS_E_ABORTED; 20583 20584 mac_handle = hdd_ctx->mac_handle; 20585 20586 if (!test_bit(SME_SESSION_OPENED, &link_info->link_flags) && 20587 (adapter->device_mode == QDF_STA_MODE || 20588 adapter->device_mode == QDF_P2P_CLIENT_MODE || 20589 adapter->device_mode == QDF_P2P_DEVICE_MODE || 20590 adapter->device_mode == QDF_P2P_GO_MODE || 20591 adapter->device_mode == QDF_SAP_MODE)) 20592 return QDF_STATUS_SUCCESS; 20593 20594 if ((QDF_STA_MODE == adapter->device_mode || 20595 QDF_P2P_CLIENT_MODE == adapter->device_mode || 20596 QDF_P2P_DEVICE_MODE == adapter->device_mode) && 20597 hdd_cm_is_connecting(link_info)) { 20598 hdd_debug("%pK(%d) mode %d Connection is in progress", 20599 WLAN_HDD_GET_STATION_CTX_PTR(link_info), 20600 link_info->vdev_id, adapter->device_mode); 20601 20602 context->out_vdev_id = link_info->vdev_id; 20603 context->out_reason = CONNECTION_IN_PROGRESS; 20604 context->connection_in_progress = true; 20605 20606 return QDF_STATUS_E_ABORTED; 20607 } 20608 20609 if ((QDF_STA_MODE == adapter->device_mode) && 20610 sme_roaming_in_progress(mac_handle, link_info->vdev_id)) { 20611 hdd_debug("%pK(%d) mode %d Reassociation in progress", 20612 WLAN_HDD_GET_STATION_CTX_PTR(link_info), 20613 link_info->vdev_id, adapter->device_mode); 20614 20615 context->out_vdev_id = link_info->vdev_id; 20616 context->out_reason = REASSOC_IN_PROGRESS; 20617 context->connection_in_progress = true; 20618 return QDF_STATUS_E_ABORTED; 20619 } 20620 20621 if ((QDF_STA_MODE == adapter->device_mode) || 20622 (QDF_P2P_CLIENT_MODE == adapter->device_mode) || 20623 (QDF_P2P_DEVICE_MODE == adapter->device_mode)) { 20624 hdd_sta_ctx = 20625 WLAN_HDD_GET_STATION_CTX_PTR(link_info); 20626 if (hdd_cm_is_vdev_associated(link_info) 20627 && sme_is_sta_key_exchange_in_progress( 20628 mac_handle, link_info->vdev_id)) { 20629 sta_mac = (uint8_t *)&(adapter->mac_addr.bytes[0]); 20630 hdd_debug("client " QDF_MAC_ADDR_FMT 20631 " is in middle of WPS/EAPOL exchange.", 20632 QDF_MAC_ADDR_REF(sta_mac)); 20633 20634 context->out_vdev_id = link_info->vdev_id; 20635 context->out_reason = EAPOL_IN_PROGRESS; 20636 context->connection_in_progress = true; 20637 20638 return QDF_STATUS_E_ABORTED; 20639 } 20640 } else if ((QDF_SAP_MODE == adapter->device_mode) || 20641 (QDF_P2P_GO_MODE == adapter->device_mode)) { 20642 hdd_for_each_sta_ref_safe(adapter->sta_info_list, sta_info, tmp, 20643 STA_INFO_CONNECTION_IN_PROGRESS_ITERATOR) { 20644 if (sta_info->peer_state != 20645 OL_TXRX_PEER_STATE_CONN) { 20646 hdd_put_sta_info_ref( 20647 &adapter->sta_info_list, &sta_info, true, 20648 STA_INFO_CONNECTION_IN_PROGRESS_ITERATOR); 20649 continue; 20650 } 20651 20652 sta_mac = sta_info->sta_mac.bytes; 20653 hdd_debug("client " QDF_MAC_ADDR_FMT 20654 " of SAP/GO is in middle of WPS/EAPOL exchange", 20655 QDF_MAC_ADDR_REF(sta_mac)); 20656 20657 context->out_vdev_id = link_info->vdev_id; 20658 context->out_reason = SAP_EAPOL_IN_PROGRESS; 20659 context->connection_in_progress = true; 20660 20661 hdd_put_sta_info_ref( 20662 &adapter->sta_info_list, &sta_info, true, 20663 STA_INFO_CONNECTION_IN_PROGRESS_ITERATOR); 20664 if (tmp) 20665 hdd_put_sta_info_ref( 20666 &adapter->sta_info_list, &tmp, true, 20667 STA_INFO_CONNECTION_IN_PROGRESS_ITERATOR); 20668 20669 return QDF_STATUS_E_ABORTED; 20670 } 20671 if (hdd_ctx->connection_in_progress) { 20672 hdd_debug("AP/GO: vdev %d connection is in progress", 20673 link_info->vdev_id); 20674 context->out_reason = SAP_CONNECTION_IN_PROGRESS; 20675 context->out_vdev_id = link_info->vdev_id; 20676 context->connection_in_progress = true; 20677 20678 return QDF_STATUS_E_ABORTED; 20679 } 20680 } 20681 20682 if (ucfg_nan_is_enable_disable_in_progress(hdd_ctx->psoc)) { 20683 context->out_reason = NAN_ENABLE_DISABLE_IN_PROGRESS; 20684 context->out_vdev_id = NAN_PSEUDO_VDEV_ID; 20685 context->connection_in_progress = true; 20686 20687 return QDF_STATUS_E_ABORTED; 20688 } 20689 20690 return QDF_STATUS_SUCCESS; 20691 } 20692 20693 bool hdd_is_connection_in_progress(uint8_t *out_vdev_id, 20694 enum scan_reject_states *out_reason) 20695 { 20696 struct hdd_is_connection_in_progress_priv hdd_conn; 20697 hdd_adapter_iterate_cb cb; 20698 20699 hdd_conn.out_vdev_id = 0; 20700 hdd_conn.out_reason = SCAN_REJECT_DEFAULT; 20701 hdd_conn.connection_in_progress = false; 20702 20703 cb = hdd_is_connection_in_progress_iterator; 20704 20705 hdd_adapter_iterate(cb, &hdd_conn); 20706 20707 if (hdd_conn.connection_in_progress && out_vdev_id && out_reason) { 20708 *out_vdev_id = hdd_conn.out_vdev_id; 20709 *out_reason = hdd_conn.out_reason; 20710 } 20711 20712 return hdd_conn.connection_in_progress; 20713 } 20714 20715 void hdd_restart_sap(struct wlan_hdd_link_info *link_info) 20716 { 20717 struct hdd_hostapd_state *hapd_state; 20718 QDF_STATUS status; 20719 struct hdd_adapter *ap_adapter = link_info->adapter; 20720 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(ap_adapter); 20721 struct sap_config *sap_config; 20722 void *sap_ctx; 20723 20724 sap_config = 20725 &(WLAN_HDD_GET_AP_CTX_PTR(link_info)->sap_config); 20726 sap_ctx = WLAN_HDD_GET_SAP_CTX_PTR(link_info); 20727 20728 mutex_lock(&hdd_ctx->sap_lock); 20729 if (test_bit(SOFTAP_BSS_STARTED, &link_info->link_flags)) { 20730 wlan_hdd_del_station(ap_adapter, NULL); 20731 hapd_state = WLAN_HDD_GET_HOSTAP_STATE_PTR(link_info); 20732 qdf_event_reset(&hapd_state->qdf_stop_bss_event); 20733 if (QDF_STATUS_SUCCESS == wlansap_stop_bss(sap_ctx)) { 20734 status = qdf_wait_single_event(&hapd_state->qdf_stop_bss_event, 20735 SME_CMD_STOP_BSS_TIMEOUT); 20736 20737 if (!QDF_IS_STATUS_SUCCESS(status)) { 20738 hdd_err("SAP Stop Failed"); 20739 goto end; 20740 } 20741 } 20742 clear_bit(SOFTAP_BSS_STARTED, &link_info->link_flags); 20743 policy_mgr_decr_session_set_pcl(hdd_ctx->psoc, 20744 ap_adapter->device_mode, link_info->vdev_id); 20745 hdd_green_ap_start_state_mc(hdd_ctx, ap_adapter->device_mode, 20746 false); 20747 hdd_err("SAP Stop Success"); 20748 20749 if (0 != wlan_hdd_cfg80211_update_apies(link_info)) { 20750 hdd_err("SAP Not able to set AP IEs"); 20751 goto end; 20752 } 20753 20754 status = wlan_hdd_mlo_sap_reinit(link_info); 20755 if (QDF_IS_STATUS_ERROR(status)) { 20756 hdd_err("SAP Not able to do mlo attach"); 20757 goto deinit_mlo; 20758 } 20759 20760 qdf_event_reset(&hapd_state->qdf_event); 20761 status = wlansap_start_bss(sap_ctx, hdd_hostapd_sap_event_cb, 20762 sap_config, ap_adapter->dev); 20763 if (QDF_IS_STATUS_ERROR(status)) { 20764 hdd_err("SAP Start Bss fail"); 20765 goto deinit_mlo; 20766 } 20767 20768 hdd_info("Waiting for SAP to start"); 20769 status = qdf_wait_single_event(&hapd_state->qdf_event, 20770 SME_CMD_START_BSS_TIMEOUT); 20771 if (!QDF_IS_STATUS_SUCCESS(status)) { 20772 hdd_err("SAP Start failed"); 20773 goto deinit_mlo; 20774 } 20775 wlansap_reset_sap_config_add_ie(sap_config, eUPDATE_IE_ALL); 20776 hdd_err("SAP Start Success"); 20777 set_bit(SOFTAP_BSS_STARTED, &link_info->link_flags); 20778 if (hapd_state->bss_state == BSS_START) { 20779 policy_mgr_incr_active_session(hdd_ctx->psoc, 20780 ap_adapter->device_mode, 20781 link_info->vdev_id); 20782 hdd_green_ap_start_state_mc(hdd_ctx, 20783 ap_adapter->device_mode, 20784 true); 20785 } 20786 } 20787 mutex_unlock(&hdd_ctx->sap_lock); 20788 return; 20789 20790 deinit_mlo: 20791 wlan_hdd_mlo_reset(link_info); 20792 end: 20793 wlansap_reset_sap_config_add_ie(sap_config, eUPDATE_IE_ALL); 20794 mutex_unlock(&hdd_ctx->sap_lock); 20795 } 20796 20797 /** 20798 * hdd_set_connection_in_progress() - to set the connection in 20799 * progress flag 20800 * @value: value to set 20801 * 20802 * This function will set the passed value to connection in progress flag. 20803 * If value is previously being set to true then no need to set it again. 20804 * 20805 * Return: true if value is being set correctly and false otherwise. 20806 */ 20807 bool hdd_set_connection_in_progress(bool value) 20808 { 20809 bool status = true; 20810 struct hdd_context *hdd_ctx; 20811 20812 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 20813 if (!hdd_ctx) 20814 return false; 20815 20816 qdf_spin_lock(&hdd_ctx->connection_status_lock); 20817 /* 20818 * if the value is set to true previously and if someone is 20819 * trying to make it true again then it could be some race 20820 * condition being triggered. Avoid this situation by returning 20821 * false 20822 */ 20823 if (hdd_ctx->connection_in_progress && value) 20824 status = false; 20825 else 20826 hdd_ctx->connection_in_progress = value; 20827 qdf_spin_unlock(&hdd_ctx->connection_status_lock); 20828 return status; 20829 } 20830 20831 int wlan_hdd_send_mcc_vdev_quota(struct hdd_adapter *adapter, int set_value) 20832 { 20833 if (!adapter) { 20834 hdd_err("Invalid adapter"); 20835 return -EINVAL; 20836 } 20837 hdd_info("send mcc vdev quota to fw: %d", set_value); 20838 sme_cli_set_command(adapter->deflink->vdev_id, 20839 WMA_VDEV_MCC_SET_TIME_QUOTA, 20840 set_value, VDEV_CMD); 20841 return 0; 20842 20843 } 20844 20845 int wlan_hdd_send_mcc_latency(struct hdd_adapter *adapter, int set_value) 20846 { 20847 if (!adapter) { 20848 hdd_err("Invalid adapter"); 20849 return -EINVAL; 20850 } 20851 20852 hdd_info("Send MCC latency WMA: %d", set_value); 20853 sme_cli_set_command(adapter->deflink->vdev_id, 20854 WMA_VDEV_MCC_SET_TIME_LATENCY, 20855 set_value, VDEV_CMD); 20856 return 0; 20857 } 20858 20859 struct wlan_hdd_link_info * 20860 wlan_hdd_get_link_info_from_vdev(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id) 20861 { 20862 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 20863 struct wlan_hdd_link_info *link_info; 20864 20865 /* 20866 * Currently PSOC is not being used. But this logic will 20867 * change once we have the converged implementation of 20868 * HDD context per PSOC in place. This would break if 20869 * multiple vdev objects reuse the vdev id. 20870 */ 20871 link_info = hdd_get_link_info_by_vdev(hdd_ctx, vdev_id); 20872 if (!link_info) { 20873 hdd_err("Get adapter by vdev id failed"); 20874 return NULL; 20875 } 20876 20877 return link_info; 20878 } 20879 20880 int hdd_get_rssi_snr_by_bssid(mac_handle_t mac_handle, const uint8_t *bssid, 20881 int8_t *rssi, int8_t *snr) 20882 { 20883 QDF_STATUS status; 20884 20885 status = sme_get_rssi_snr_by_bssid(mac_handle, bssid, rssi, snr); 20886 if (QDF_IS_STATUS_ERROR(status)) { 20887 hdd_debug("sme_get_rssi_snr_by_bssid failed"); 20888 return -EINVAL; 20889 } 20890 20891 return 0; 20892 } 20893 20894 /** 20895 * hdd_reset_limit_off_chan() - reset limit off-channel command parameters 20896 * @adapter: HDD adapter 20897 * 20898 * Return: 0 on success and non zero value on failure 20899 */ 20900 int hdd_reset_limit_off_chan(struct hdd_adapter *adapter) 20901 { 20902 struct hdd_context *hdd_ctx; 20903 int ret; 20904 QDF_STATUS status; 20905 uint8_t sys_pref = 0; 20906 20907 hdd_ctx = WLAN_HDD_GET_CTX(adapter); 20908 ret = wlan_hdd_validate_context(hdd_ctx); 20909 if (ret < 0) 20910 return ret; 20911 20912 ucfg_policy_mgr_get_sys_pref(hdd_ctx->psoc, 20913 &sys_pref); 20914 /* set the system preferece to default */ 20915 policy_mgr_set_cur_conc_system_pref(hdd_ctx->psoc, sys_pref); 20916 20917 /* clear the bitmap */ 20918 adapter->active_ac = 0; 20919 20920 hdd_debug("reset ac_bitmap for session %hu active_ac %0x", 20921 adapter->deflink->vdev_id, adapter->active_ac); 20922 20923 status = sme_send_limit_off_channel_params(hdd_ctx->mac_handle, 20924 adapter->deflink->vdev_id, 20925 false, 0, 0, false); 20926 if (!QDF_IS_STATUS_SUCCESS(status)) { 20927 hdd_err("failed to reset limit off chan params"); 20928 ret = -EINVAL; 20929 } 20930 20931 return ret; 20932 } 20933 20934 void hdd_hidden_ssid_enable_roaming(hdd_handle_t hdd_handle, uint8_t vdev_id) 20935 { 20936 struct hdd_context *hdd_ctx = hdd_handle_to_context(hdd_handle); 20937 struct wlan_hdd_link_info *link_info; 20938 20939 link_info = hdd_get_link_info_by_vdev(hdd_ctx, vdev_id); 20940 if (!link_info) { 20941 hdd_err("Invalid vdev"); 20942 return; 20943 } 20944 /* enable roaming on all adapters once hdd get hidden ssid rsp */ 20945 wlan_hdd_set_roaming_state(link_info, RSO_START_BSS, true); 20946 } 20947 20948 #ifdef WLAN_FEATURE_PKT_CAPTURE 20949 bool wlan_hdd_is_mon_concurrency(void) 20950 { 20951 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 20952 20953 if (!hdd_ctx) 20954 return -EINVAL; 20955 20956 if (ucfg_pkt_capture_get_mode(hdd_ctx->psoc) != 20957 PACKET_CAPTURE_MODE_DISABLE) { 20958 if (policy_mgr_get_concurrency_mode(hdd_ctx->psoc) == 20959 (QDF_STA_MASK | QDF_MONITOR_MASK)) { 20960 hdd_err("STA + MON mode is UP"); 20961 return true; 20962 } 20963 } 20964 return false; 20965 } 20966 20967 void wlan_hdd_del_monitor(struct hdd_context *hdd_ctx, 20968 struct hdd_adapter *adapter, bool rtnl_held) 20969 { 20970 wlan_hdd_release_intf_addr(hdd_ctx, adapter->mac_addr.bytes); 20971 hdd_stop_adapter(hdd_ctx, adapter); 20972 hdd_close_adapter(hdd_ctx, adapter, true); 20973 20974 hdd_open_p2p_interface(hdd_ctx); 20975 } 20976 20977 void 20978 wlan_hdd_del_p2p_interface(struct hdd_context *hdd_ctx) 20979 { 20980 struct hdd_adapter *adapter = NULL, *next_adapter = NULL; 20981 struct osif_vdev_sync *vdev_sync; 20982 20983 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 20984 NET_DEV_HOLD_DEL_P2P_INTERFACE) { 20985 if (adapter->device_mode == QDF_P2P_CLIENT_MODE || 20986 adapter->device_mode == QDF_P2P_DEVICE_MODE || 20987 adapter->device_mode == QDF_P2P_GO_MODE) { 20988 vdev_sync = osif_vdev_sync_unregister(adapter->dev); 20989 if (vdev_sync) 20990 osif_vdev_sync_wait_for_ops(vdev_sync); 20991 20992 hdd_adapter_dev_put_debug( 20993 adapter, NET_DEV_HOLD_DEL_P2P_INTERFACE); 20994 20995 hdd_clean_up_interface(hdd_ctx, adapter); 20996 20997 if (vdev_sync) 20998 osif_vdev_sync_destroy(vdev_sync); 20999 } else 21000 hdd_adapter_dev_put_debug( 21001 adapter, NET_DEV_HOLD_DEL_P2P_INTERFACE); 21002 } 21003 } 21004 21005 #endif /* WLAN_FEATURE_PKT_CAPTURE */ 21006 21007 bool wlan_hdd_is_session_type_monitor(uint8_t session_type) 21008 { 21009 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 21010 21011 if (!hdd_ctx) { 21012 cds_err("HDD context is NULL"); 21013 return false; 21014 } 21015 21016 if (cds_get_conparam() != QDF_GLOBAL_MONITOR_MODE && 21017 session_type == QDF_MONITOR_MODE) 21018 return true; 21019 else 21020 return false; 21021 } 21022 21023 int 21024 wlan_hdd_add_monitor_check(struct hdd_context *hdd_ctx, 21025 struct hdd_adapter **adapter, 21026 const char *name, bool rtnl_held, 21027 unsigned char name_assign_type) 21028 { 21029 struct hdd_adapter *sta_adapter; 21030 struct hdd_adapter *mon_adapter; 21031 uint8_t num_open_session = 0; 21032 QDF_STATUS status; 21033 struct hdd_adapter_create_param params = {0}; 21034 21035 sta_adapter = hdd_get_adapter(hdd_ctx, QDF_STA_MODE); 21036 if (!sta_adapter) { 21037 hdd_err("No station adapter"); 21038 return -EINVAL; 21039 } 21040 21041 status = policy_mgr_check_mon_concurrency(hdd_ctx->psoc); 21042 21043 if (QDF_IS_STATUS_ERROR(status)) 21044 return -EINVAL; 21045 21046 if (hdd_is_connection_in_progress(NULL, NULL)) { 21047 hdd_err("cannot add monitor mode, Connection in progress"); 21048 return -EINVAL; 21049 } 21050 21051 if (!ucfg_dp_is_local_pkt_capture_enabled(hdd_ctx->psoc) && 21052 ucfg_mlme_is_sta_mon_conc_supported(hdd_ctx->psoc)) { 21053 num_open_session = policy_mgr_mode_specific_connection_count( 21054 hdd_ctx->psoc, 21055 PM_STA_MODE, 21056 NULL); 21057 21058 if (num_open_session) { 21059 /* Try disconnecting if already in connected state */ 21060 wlan_hdd_cm_issue_disconnect(sta_adapter->deflink, 21061 REASON_UNSPEC_FAILURE, 21062 true); 21063 } 21064 } 21065 21066 if (ucfg_pkt_capture_get_mode(hdd_ctx->psoc) != 21067 PACKET_CAPTURE_MODE_DISABLE) 21068 wlan_hdd_del_p2p_interface(hdd_ctx); 21069 21070 params.is_add_virtual_iface = 1; 21071 21072 mon_adapter = hdd_open_adapter(hdd_ctx, QDF_MONITOR_MODE, name, 21073 wlan_hdd_get_intf_addr( 21074 hdd_ctx, 21075 QDF_MONITOR_MODE), 21076 name_assign_type, rtnl_held, ¶ms); 21077 if (!mon_adapter) { 21078 hdd_err("hdd_open_adapter failed"); 21079 if (ucfg_pkt_capture_get_mode(hdd_ctx->psoc) != 21080 PACKET_CAPTURE_MODE_DISABLE) 21081 hdd_open_p2p_interface(hdd_ctx); 21082 return -EINVAL; 21083 } 21084 21085 if (mon_adapter) 21086 hdd_set_idle_ps_config(hdd_ctx, false); 21087 21088 *adapter = mon_adapter; 21089 return 0; 21090 } 21091 21092 #ifdef FEATURE_MONITOR_MODE_SUPPORT 21093 21094 void hdd_sme_monitor_mode_callback(uint8_t vdev_id) 21095 { 21096 struct hdd_context *hdd_ctx; 21097 struct hdd_adapter *adapter; 21098 struct wlan_hdd_link_info *link_info; 21099 21100 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 21101 if (!hdd_ctx) 21102 return; 21103 21104 link_info = hdd_get_link_info_by_vdev(hdd_ctx, vdev_id); 21105 if (!link_info) { 21106 hdd_err_rl("NULL adapter"); 21107 return; 21108 } 21109 21110 adapter = link_info->adapter; 21111 if (adapter->magic != WLAN_HDD_ADAPTER_MAGIC) { 21112 hdd_err_rl("Invalid magic"); 21113 return; 21114 } 21115 21116 qdf_event_set(&adapter->qdf_monitor_mode_vdev_up_event); 21117 21118 hdd_debug("monitor mode vdev up completed"); 21119 adapter->monitor_mode_vdev_up_in_progress = false; 21120 } 21121 21122 QDF_STATUS hdd_monitor_mode_qdf_create_event(struct hdd_adapter *adapter, 21123 uint8_t session_type) 21124 { 21125 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; 21126 21127 if (session_type == QDF_MONITOR_MODE) { 21128 qdf_status = qdf_event_create( 21129 &adapter->qdf_monitor_mode_vdev_up_event); 21130 } 21131 return qdf_status; 21132 } 21133 21134 QDF_STATUS hdd_monitor_mode_vdev_status(struct hdd_adapter *adapter) 21135 { 21136 QDF_STATUS status = QDF_STATUS_SUCCESS; 21137 21138 if (!adapter->monitor_mode_vdev_up_in_progress) 21139 return status; 21140 21141 /* block on a completion variable until vdev up success*/ 21142 status = qdf_wait_for_event_completion( 21143 &adapter->qdf_monitor_mode_vdev_up_event, 21144 WLAN_MONITOR_MODE_VDEV_UP_EVT); 21145 if (QDF_IS_STATUS_ERROR(status)) { 21146 hdd_err_rl("monitor mode vdev up event time out vdev id: %d", 21147 adapter->deflink->vdev_id); 21148 if (adapter->qdf_monitor_mode_vdev_up_event.force_set) 21149 /* 21150 * SSR/PDR has caused shutdown, which has 21151 * forcefully set the event. 21152 */ 21153 hdd_err_rl("monitor mode vdev up event forcefully set"); 21154 else if (status == QDF_STATUS_E_TIMEOUT) 21155 hdd_err_rl("mode vdev up event timed out"); 21156 else 21157 hdd_err_rl("Failed to wait for monitor vdev up(status-%d)", 21158 status); 21159 21160 adapter->monitor_mode_vdev_up_in_progress = false; 21161 return status; 21162 } 21163 21164 return QDF_STATUS_SUCCESS; 21165 } 21166 #endif 21167 21168 #if defined(CLD_PM_QOS) && defined(WLAN_FEATURE_LL_MODE) 21169 void hdd_beacon_latency_event_cb(uint32_t latency_level) 21170 { 21171 struct hdd_context *hdd_ctx; 21172 21173 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 21174 if (!hdd_ctx) 21175 return; 21176 21177 if (latency_level == 21178 QCA_WLAN_VENDOR_ATTR_CONFIG_LATENCY_LEVEL_ULTRALOW) 21179 wlan_hdd_set_pm_qos_request(hdd_ctx, true); 21180 else 21181 wlan_hdd_set_pm_qos_request(hdd_ctx, false); 21182 } 21183 #endif 21184 21185 #ifdef CONFIG_WLAN_DEBUG_CRASH_INJECT 21186 int hdd_crash_inject(struct hdd_adapter *adapter, uint32_t v1, uint32_t v2) 21187 { 21188 struct hdd_context *hdd_ctx; 21189 int ret; 21190 bool crash_inject; 21191 QDF_STATUS status; 21192 21193 hdd_debug("v1: %d v2: %d", v1, v2); 21194 pr_err("SSR is triggered by CRASH_INJECT: %d %d\n", 21195 v1, v2); 21196 hdd_ctx = WLAN_HDD_GET_CTX(adapter); 21197 21198 status = ucfg_mlme_get_crash_inject(hdd_ctx->psoc, &crash_inject); 21199 if (QDF_IS_STATUS_ERROR(status)) { 21200 hdd_err("Failed to get crash inject ini config"); 21201 return 0; 21202 } 21203 21204 if (!crash_inject) { 21205 hdd_err("Crash Inject ini disabled, Ignore Crash Inject"); 21206 return 0; 21207 } 21208 21209 if (v1 == 3) { 21210 cds_trigger_recovery(QDF_REASON_UNSPECIFIED); 21211 return 0; 21212 } 21213 ret = wma_cli_set2_command(adapter->deflink->vdev_id, 21214 GEN_PARAM_CRASH_INJECT, 21215 v1, v2, GEN_CMD); 21216 return ret; 21217 } 21218 #endif 21219 21220 static const struct hdd_chwidth_info chwidth_info[] = { 21221 [NL80211_CHAN_WIDTH_20_NOHT] = { 21222 .ch_bw = HW_MODE_20_MHZ, 21223 .ch_bw_str = "20MHz", 21224 .phy_chwidth = CH_WIDTH_20MHZ, 21225 }, 21226 [NL80211_CHAN_WIDTH_20] = { 21227 .sir_chwidth_valid = true, 21228 .sir_chwidth = eHT_CHANNEL_WIDTH_20MHZ, 21229 .ch_bw = HW_MODE_20_MHZ, 21230 .ch_bw_str = "20MHz", 21231 .phy_chwidth = CH_WIDTH_20MHZ, 21232 .bonding_mode = WNI_CFG_CHANNEL_BONDING_MODE_DISABLE, 21233 }, 21234 [NL80211_CHAN_WIDTH_40] = { 21235 .sir_chwidth_valid = true, 21236 .sir_chwidth = eHT_CHANNEL_WIDTH_40MHZ, 21237 .ch_bw = HW_MODE_40_MHZ, 21238 .ch_bw_str = "40MHz", 21239 .phy_chwidth = CH_WIDTH_40MHZ, 21240 .bonding_mode = WNI_CFG_CHANNEL_BONDING_MODE_ENABLE, 21241 }, 21242 [NL80211_CHAN_WIDTH_80] = { 21243 .sir_chwidth_valid = true, 21244 .sir_chwidth = eHT_CHANNEL_WIDTH_80MHZ, 21245 .ch_bw = HW_MODE_80_MHZ, 21246 .ch_bw_str = "80MHz", 21247 .phy_chwidth = CH_WIDTH_80MHZ, 21248 .bonding_mode = WNI_CFG_CHANNEL_BONDING_MODE_ENABLE, 21249 }, 21250 [NL80211_CHAN_WIDTH_80P80] = { 21251 .sir_chwidth_valid = true, 21252 .sir_chwidth = eHT_CHANNEL_WIDTH_80P80MHZ, 21253 .ch_bw = HW_MODE_80_PLUS_80_MHZ, 21254 .ch_bw_str = "(80 + 80)MHz", 21255 .phy_chwidth = CH_WIDTH_80P80MHZ, 21256 .bonding_mode = WNI_CFG_CHANNEL_BONDING_MODE_ENABLE, 21257 }, 21258 [NL80211_CHAN_WIDTH_160] = { 21259 .sir_chwidth_valid = true, 21260 .sir_chwidth = eHT_CHANNEL_WIDTH_160MHZ, 21261 .ch_bw = HW_MODE_160_MHZ, 21262 .ch_bw_str = "160MHz", 21263 .phy_chwidth = CH_WIDTH_160MHZ, 21264 .bonding_mode = WNI_CFG_CHANNEL_BONDING_MODE_ENABLE, 21265 }, 21266 [NL80211_CHAN_WIDTH_5] = { 21267 .ch_bw = HW_MODE_5_MHZ, 21268 .ch_bw_str = "5MHz", 21269 .phy_chwidth = CH_WIDTH_5MHZ, 21270 }, 21271 [NL80211_CHAN_WIDTH_10] = { 21272 .ch_bw = HW_MODE_10_MHZ, 21273 .ch_bw_str = "10MHz", 21274 .phy_chwidth = CH_WIDTH_10MHZ, 21275 }, 21276 #if defined(WLAN_FEATURE_11BE) && defined(CFG80211_11BE_BASIC) 21277 [NL80211_CHAN_WIDTH_320] = { 21278 .sir_chwidth_valid = true, 21279 .sir_chwidth = eHT_CHANNEL_WIDTH_320MHZ, 21280 .ch_bw = HW_MODE_320_MHZ, 21281 .ch_bw_str = "320MHz", 21282 .phy_chwidth = CH_WIDTH_320MHZ, 21283 .bonding_mode = WNI_CFG_CHANNEL_BONDING_MODE_ENABLE, 21284 }, 21285 #endif 21286 }; 21287 21288 enum eSirMacHTChannelWidth 21289 hdd_nl80211_chwidth_to_chwidth(uint8_t nl80211_chwidth) 21290 { 21291 if (nl80211_chwidth >= ARRAY_SIZE(chwidth_info) || 21292 !chwidth_info[nl80211_chwidth].sir_chwidth_valid) { 21293 hdd_err("Unsupported channel width %d", nl80211_chwidth); 21294 return -EINVAL; 21295 } 21296 21297 return chwidth_info[nl80211_chwidth].sir_chwidth; 21298 } 21299 21300 uint8_t hdd_chwidth_to_nl80211_chwidth(enum eSirMacHTChannelWidth chwidth) 21301 { 21302 int i; 21303 21304 for (i = 0; i < ARRAY_SIZE(chwidth_info); i++) { 21305 if (chwidth_info[i].sir_chwidth_valid && 21306 chwidth_info[i].sir_chwidth == chwidth) 21307 return i; 21308 } 21309 21310 hdd_err("Unsupported channel width %d", chwidth); 21311 return 0xFF; 21312 } 21313 21314 enum hw_mode_bandwidth wlan_hdd_get_channel_bw(enum nl80211_chan_width width) 21315 { 21316 if (width >= ARRAY_SIZE(chwidth_info)) { 21317 hdd_err("Invalid width: %d, using default 20MHz", width); 21318 return HW_MODE_20_MHZ; 21319 } 21320 21321 return chwidth_info[width].ch_bw; 21322 } 21323 21324 uint8_t *hdd_ch_width_str(enum phy_ch_width ch_width) 21325 { 21326 int i; 21327 21328 for (i = 0; i < ARRAY_SIZE(chwidth_info); i++) { 21329 if (chwidth_info[i].phy_chwidth == ch_width) 21330 return chwidth_info[i].ch_bw_str; 21331 } 21332 21333 return "UNKNOWN"; 21334 } 21335 21336 int hdd_we_set_ch_width(struct wlan_hdd_link_info *link_info, int ch_width) 21337 { 21338 int i; 21339 21340 /* updating channel bonding only on 5Ghz */ 21341 hdd_debug("wmi_vdev_param_chwidth val %d", ch_width); 21342 21343 for (i = 0; i < ARRAY_SIZE(chwidth_info); i++) { 21344 if (!chwidth_info[i].sir_chwidth_valid || 21345 chwidth_info[i].sir_chwidth != ch_width) 21346 continue; 21347 21348 return hdd_update_channel_width(link_info->adapter, ch_width, 21349 chwidth_info[i].bonding_mode); 21350 } 21351 21352 hdd_err("Invalid ch_width %d", ch_width); 21353 return -EINVAL; 21354 } 21355 21356 /* Register the module init/exit functions */ 21357 module_init(hdd_module_init); 21358 module_exit(hdd_module_exit); 21359 21360 MODULE_LICENSE("Dual BSD/GPL"); 21361 MODULE_AUTHOR("Qualcomm Atheros, Inc."); 21362 MODULE_DESCRIPTION("WLAN HOST DEVICE DRIVER"); 21363 21364 const struct kernel_param_ops con_mode_ops = { 21365 .set = con_mode_handler, 21366 .get = param_get_int, 21367 }; 21368 21369 #ifdef FEATURE_WLAN_RESIDENT_DRIVER 21370 EXPORT_SYMBOL(con_mode_ops); 21371 #endif 21372 21373 const struct kernel_param_ops con_mode_ftm_ops = { 21374 .set = con_mode_handler_ftm, 21375 .get = param_get_int, 21376 }; 21377 21378 #ifdef FEATURE_WLAN_RESIDENT_DRIVER 21379 EXPORT_SYMBOL(con_mode_ftm_ops); 21380 #endif 21381 21382 #ifdef WLAN_FEATURE_EPPING 21383 static const struct kernel_param_ops con_mode_epping_ops = { 21384 .set = con_mode_handler_epping, 21385 .get = param_get_int, 21386 }; 21387 #endif 21388 21389 static const struct kernel_param_ops fwpath_ops = { 21390 .set = fwpath_changed_handler, 21391 .get = param_get_string, 21392 }; 21393 21394 static int __pcie_set_gen_speed_handler(void) 21395 { 21396 int ret; 21397 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 21398 21399 ret = wlan_hdd_validate_context(hdd_ctx); 21400 if (ret) 21401 return ret; 21402 21403 hdd_info_rl("Received PCIe gen speed %d", pcie_gen_speed); 21404 if (pcie_gen_speed <= HDD_INVALID_MIN_PCIE_GEN_SPEED || 21405 pcie_gen_speed >= HDD_INVALID_MAX_PCIE_GEN_SPEED) { 21406 hdd_err_rl("invalid pcie gen speed %d", pcie_gen_speed); 21407 return -EINVAL; 21408 } 21409 21410 hdd_ctx->current_pcie_gen_speed = pcie_gen_speed; 21411 21412 return 0; 21413 } 21414 21415 static int pcie_set_gen_speed_handler(const char *kmessage, 21416 const struct kernel_param *kp) 21417 { 21418 struct osif_driver_sync *driver_sync; 21419 int ret; 21420 21421 ret = osif_driver_sync_op_start(&driver_sync); 21422 if (ret) 21423 return ret; 21424 21425 ret = param_set_int(kmessage, kp); 21426 if (ret) { 21427 hdd_err_rl("param set int failed %d", ret); 21428 goto out; 21429 } 21430 21431 ret = __pcie_set_gen_speed_handler(); 21432 21433 out: 21434 osif_driver_sync_op_stop(driver_sync); 21435 21436 return ret; 21437 } 21438 21439 static const struct kernel_param_ops pcie_gen_speed_ops = { 21440 .set = pcie_set_gen_speed_handler, 21441 .get = param_get_int, 21442 }; 21443 21444 module_param_cb(con_mode, &con_mode_ops, &con_mode, 21445 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); 21446 21447 module_param_cb(con_mode_ftm, &con_mode_ftm_ops, &con_mode_ftm, 21448 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); 21449 21450 module_param_cb(pcie_gen_speed, &pcie_gen_speed_ops, &pcie_gen_speed, 21451 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); 21452 21453 #ifdef WLAN_FEATURE_EPPING 21454 module_param_cb(con_mode_epping, &con_mode_epping_ops, 21455 &con_mode_epping, 0644); 21456 #endif 21457 21458 module_param_cb(fwpath, &fwpath_ops, &fwpath, 21459 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); 21460 21461 module_param(enable_dfs_chan_scan, int, S_IRUSR | S_IRGRP | S_IROTH); 21462 21463 module_param(enable_11d, int, S_IRUSR | S_IRGRP | S_IROTH); 21464 21465 module_param(country_code, charp, S_IRUSR | S_IRGRP | S_IROTH); 21466 21467 static int timer_multiplier_get_handler(char *buffer, 21468 const struct kernel_param *kp) 21469 { 21470 return scnprintf(buffer, PAGE_SIZE, "%u", qdf_timer_get_multiplier()); 21471 } 21472 21473 static int timer_multiplier_set_handler(const char *kmessage, 21474 const struct kernel_param *kp) 21475 { 21476 QDF_STATUS status; 21477 uint32_t scalar; 21478 21479 status = qdf_uint32_parse(kmessage, &scalar); 21480 if (QDF_IS_STATUS_ERROR(status)) 21481 return qdf_status_to_os_return(status); 21482 21483 if (!cfg_in_range(CFG_TIMER_MULTIPLIER, scalar)) 21484 return -ERANGE; 21485 21486 qdf_timer_set_multiplier(scalar); 21487 21488 return 0; 21489 } 21490 21491 static const struct kernel_param_ops timer_multiplier_ops = { 21492 .get = timer_multiplier_get_handler, 21493 .set = timer_multiplier_set_handler, 21494 }; 21495 21496 module_param_cb(timer_multiplier, &timer_multiplier_ops, NULL, 0644); 21497