1 /* 2 * Copyright (c) 2012-2021 The Linux Foundation. All rights reserved. 3 * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved. 4 * 5 * Permission to use, copy, modify, and/or distribute this software for 6 * any purpose with or without fee is hereby granted, provided that the 7 * above copyright notice and this permission notice appear in all 8 * copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 11 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 12 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 13 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 14 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 15 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 16 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 17 * PERFORMANCE OF THIS SOFTWARE. 18 */ 19 20 /** 21 * DOC: wlan_hdd_main.c 22 * 23 * WLAN Host Device Driver implementation 24 * 25 */ 26 27 /* Include Files */ 28 #include <wbuff.h> 29 #include "cfg_ucfg_api.h" 30 #include <wlan_hdd_includes.h> 31 #include <cds_api.h> 32 #include <cds_sched.h> 33 #include <linux/cpu.h> 34 #include <linux/etherdevice.h> 35 #include <linux/firmware.h> 36 #include <linux/kernel.h> 37 #include <wlan_hdd_tx_rx.h> 38 #include <wni_api.h> 39 #include <wlan_hdd_cfg.h> 40 #include <wlan_ptt_sock_svc.h> 41 #include <dbglog_host.h> 42 #include <wlan_logging_sock_svc.h> 43 #include <wlan_roam_debug.h> 44 #include <wlan_hdd_connectivity_logging.h> 45 #include "osif_sync.h" 46 #include <wlan_hdd_wowl.h> 47 #include <wlan_hdd_misc.h> 48 #include <wlan_hdd_wext.h> 49 #include "wlan_hdd_trace.h" 50 #include "wlan_hdd_ioctl.h" 51 #include "wlan_hdd_ftm.h" 52 #include "wlan_hdd_power.h" 53 #include "wlan_hdd_stats.h" 54 #include "wlan_hdd_scan.h" 55 #include "wlan_policy_mgr_ucfg.h" 56 #include "wlan_osif_priv.h" 57 #include <wlan_osif_request_manager.h> 58 #ifdef CONFIG_LEAK_DETECTION 59 #include "qdf_debug_domain.h" 60 #endif 61 #include "qdf_delayed_work.h" 62 #include "qdf_periodic_work.h" 63 #include "qdf_str.h" 64 #include "qdf_talloc.h" 65 #include "qdf_trace.h" 66 #include "qdf_types.h" 67 #include "qdf_net_if.h" 68 #include <cdp_txrx_peer_ops.h> 69 #include <cdp_txrx_misc.h> 70 #include <cdp_txrx_stats.h> 71 #include "cdp_txrx_flow_ctrl_legacy.h" 72 #include "qdf_ssr_driver_dump.h" 73 74 #include <net/addrconf.h> 75 #include <linux/wireless.h> 76 #include <net/cfg80211.h> 77 #include <linux/inetdevice.h> 78 #include <net/addrconf.h> 79 #include "wlan_hdd_cfg80211.h" 80 #include "wlan_hdd_ext_scan.h" 81 #include "wlan_hdd_p2p.h" 82 #include <linux/rtnetlink.h> 83 #include "sap_api.h" 84 #include <sap_internal.h> 85 #include <linux/semaphore.h> 86 #include <linux/ctype.h> 87 #include <linux/compat.h> 88 #include <linux/ethtool.h> 89 #include <linux/suspend.h> 90 91 #ifdef WLAN_FEATURE_DP_BUS_BANDWIDTH 92 #include "qdf_periodic_work.h" 93 #endif 94 95 #include <wlan_hdd_hostapd.h> 96 #include <wlan_hdd_softap_tx_rx.h> 97 #include <wlan_hdd_green_ap.h> 98 #include "qwlan_version.h" 99 #include "wma_types.h" 100 #include "wlan_hdd_tdls.h" 101 #ifdef FEATURE_WLAN_CH_AVOID 102 #include "cds_regdomain.h" 103 #endif /* FEATURE_WLAN_CH_AVOID */ 104 #include "cdp_txrx_flow_ctrl_v2.h" 105 #include "pld_common.h" 106 #include "wlan_hdd_ocb.h" 107 #include "wlan_hdd_nan.h" 108 #include "wlan_hdd_debugfs.h" 109 #include "wlan_hdd_debugfs_csr.h" 110 #include "wlan_hdd_driver_ops.h" 111 #include "epping_main.h" 112 #include "wlan_hdd_data_stall_detection.h" 113 #include "wlan_hdd_mpta_helper.h" 114 115 #include <wlan_hdd_ipa.h> 116 #include "hif.h" 117 #include "wma.h" 118 #include "wlan_policy_mgr_api.h" 119 #include "wlan_hdd_tsf.h" 120 #include "bmi.h" 121 #include <wlan_hdd_regulatory.h> 122 #include "wlan_hdd_lpass.h" 123 #include "wlan_nan_api.h" 124 #include <wlan_hdd_napi.h> 125 #include "wlan_hdd_disa.h" 126 #include <dispatcher_init_deinit.h> 127 #include "wlan_hdd_object_manager.h" 128 #include "cds_utils.h" 129 #include <cdp_txrx_handle.h> 130 #include <qca_vendor.h> 131 #include "wlan_pmo_ucfg_api.h" 132 #include "sir_api.h" 133 #include "os_if_wifi_pos.h" 134 #include "wifi_pos_api.h" 135 #include "wlan_hdd_oemdata.h" 136 #include "wlan_hdd_he.h" 137 #include "os_if_nan.h" 138 #include "nan_public_structs.h" 139 #include "nan_ucfg_api.h" 140 #include "wlan_reg_ucfg_api.h" 141 #include "wlan_hdd_afc.h" 142 #include "wlan_afc_ucfg_api.h" 143 #include "wlan_dfs_ucfg_api.h" 144 #include "wlan_hdd_rx_monitor.h" 145 #include "sme_power_save_api.h" 146 #include "enet.h" 147 #include <cdp_txrx_cmn_struct.h> 148 #include "wlan_hdd_sysfs.h" 149 #include "wlan_disa_ucfg_api.h" 150 #include "wlan_disa_obj_mgmt_api.h" 151 #include "wlan_action_oui_ucfg_api.h" 152 #include "wlan_ipa_ucfg_api.h" 153 #include <target_if.h> 154 #include "wlan_hdd_nud_tracking.h" 155 #include "wlan_hdd_apf.h" 156 #include "wlan_hdd_twt.h" 157 #include "qc_sap_ioctl.h" 158 #include "wlan_mlme_main.h" 159 #include "wlan_p2p_cfg_api.h" 160 #include "wlan_cfg80211_p2p.h" 161 #include "wlan_cfg80211_interop_issues_ap.h" 162 #include "wlan_tdls_cfg_api.h" 163 #include <wlan_hdd_rssi_monitor.h> 164 #include "wlan_mlme_ucfg_api.h" 165 #include "wlan_mlme_twt_ucfg_api.h" 166 #include "wlan_fwol_ucfg_api.h" 167 #include "wlan_policy_mgr_ucfg.h" 168 #include "qdf_func_tracker.h" 169 #include "pld_common.h" 170 #include "wlan_hdd_pre_cac.h" 171 172 #include "sme_api.h" 173 174 #ifdef CNSS_GENL 175 #ifdef CONFIG_CNSS_OUT_OF_TREE 176 #include "cnss_nl.h" 177 #else 178 #include <net/cnss_nl.h> 179 #endif 180 #endif 181 #include "wlan_reg_ucfg_api.h" 182 #include "wlan_ocb_ucfg_api.h" 183 #include <wlan_hdd_spectralscan.h> 184 #include "wlan_green_ap_ucfg_api.h" 185 #include <wlan_p2p_ucfg_api.h> 186 #include <wlan_interop_issues_ap_ucfg_api.h> 187 #include <target_type.h> 188 #include <wlan_hdd_debugfs_coex.h> 189 #include <wlan_hdd_debugfs_config.h> 190 #include "wlan_dlm_ucfg_api.h" 191 #include "ftm_time_sync_ucfg_api.h" 192 #include "wlan_pre_cac_ucfg_api.h" 193 #include "ol_txrx.h" 194 #include "wlan_hdd_sta_info.h" 195 #include "mac_init_api.h" 196 #include "wlan_pkt_capture_ucfg_api.h" 197 #include <wlan_hdd_sar_limits.h> 198 #include "cfg_nan_api.h" 199 #include "wlan_hdd_btc_chain_mode.h" 200 #include <wlan_hdd_dcs.h> 201 #include "wlan_hdd_debugfs_unit_test.h" 202 #include "wlan_hdd_debugfs_mibstat.h" 203 #include <wlan_hdd_hang_event.h> 204 #include "wlan_global_lmac_if_api.h" 205 #include "wlan_coex_ucfg_api.h" 206 #include "wlan_cm_roam_api.h" 207 #include "wlan_cm_roam_ucfg_api.h" 208 #include <cdp_txrx_ctrl.h> 209 #include "qdf_lock.h" 210 #include "wlan_hdd_thermal.h" 211 #include "osif_cm_util.h" 212 #include "wlan_hdd_gpio_wakeup.h" 213 #include "wlan_hdd_bootup_marker.h" 214 #include "wlan_dp_ucfg_api.h" 215 #include "wlan_hdd_medium_assess.h" 216 #include "wlan_hdd_eht.h" 217 #include <linux/bitfield.h> 218 #include "wlan_hdd_mlo.h" 219 #include <wlan_hdd_son.h> 220 #ifdef WLAN_FEATURE_11BE_MLO 221 #include <wlan_mlo_mgr_ap.h> 222 #endif 223 #include "wlan_osif_features.h" 224 #include "wlan_vdev_mgr_ucfg_api.h" 225 #include <wlan_objmgr_psoc_obj_i.h> 226 #include <wlan_objmgr_vdev_obj_i.h> 227 #include "wifi_pos_ucfg_api.h" 228 #include "osif_vdev_mgr_util.h" 229 #include <son_ucfg_api.h> 230 #include "osif_twt_util.h" 231 #include "wlan_twt_ucfg_ext_api.h" 232 #include "wlan_hdd_mcc_quota.h" 233 #include "osif_pre_cac.h" 234 #include "wlan_hdd_pre_cac.h" 235 #include "wlan_osif_features.h" 236 #ifdef WLAN_FEATURE_DYNAMIC_RX_AGGREGATION 237 #include <net/pkt_cls.h> 238 #endif 239 #include "wlan_dp_public_struct.h" 240 #include "os_if_dp.h" 241 #include <wlan_dp_ucfg_api.h> 242 #include "wlan_psoc_mlme_ucfg_api.h" 243 #include "os_if_qmi.h" 244 #include "wlan_qmi_ucfg_api.h" 245 #include "wlan_psoc_mlme_ucfg_api.h" 246 #include "wlan_ll_sap_ucfg_api.h" 247 248 #include "os_if_dp_local_pkt_capture.h" 249 #include <wlan_mlo_mgr_link_switch.h> 250 #include "cdp_txrx_mon.h" 251 #include "os_if_ll_sap.h" 252 #include "wlan_p2p_ucfg_api.h" 253 #include "wlan_crypto_obj_mgr_i.h" 254 255 #ifdef MULTI_CLIENT_LL_SUPPORT 256 #define WLAM_WLM_HOST_DRIVER_PORT_ID 0xFFFFFF 257 #endif 258 259 #ifdef MODULE 260 #ifdef WLAN_WEAR_CHIPSET 261 #define WLAN_MODULE_NAME "wlan" 262 #else 263 #define WLAN_MODULE_NAME module_name(THIS_MODULE) 264 #endif 265 #else 266 #define WLAN_MODULE_NAME "wlan" 267 #endif 268 269 #ifdef TIMER_MANAGER 270 #define TIMER_MANAGER_STR " +TIMER_MANAGER" 271 #else 272 #define TIMER_MANAGER_STR "" 273 #endif 274 275 #ifdef MEMORY_DEBUG 276 #define MEMORY_DEBUG_STR " +MEMORY_DEBUG" 277 #else 278 #define MEMORY_DEBUG_STR "" 279 #endif 280 281 #ifdef PANIC_ON_BUG 282 #define PANIC_ON_BUG_STR " +PANIC_ON_BUG" 283 #else 284 #define PANIC_ON_BUG_STR "" 285 #endif 286 287 /* PCIe gen speed change idle shutdown timer 100 milliseconds */ 288 #define HDD_PCIE_GEN_SPEED_CHANGE_TIMEOUT_MS (100) 289 290 #define MAX_NET_DEV_REF_LEAK_ITERATIONS 10 291 #define NET_DEV_REF_LEAK_ITERATION_SLEEP_TIME_MS 10 292 293 #ifdef FEATURE_TSO 294 #define TSO_FEATURE_FLAGS (NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_SG) 295 #else 296 #define TSO_FEATURE_FLAGS 0 297 #endif 298 299 int wlan_start_ret_val; 300 static DECLARE_COMPLETION(wlan_start_comp); 301 static qdf_atomic_t wlan_hdd_state_fops_ref; 302 #ifndef MODULE 303 static struct gwlan_loader *wlan_loader; 304 static ssize_t wlan_boot_cb(struct kobject *kobj, 305 struct kobj_attribute *attr, 306 const char *buf, size_t count); 307 struct gwlan_loader { 308 bool loaded_state; 309 struct kobject *boot_wlan_obj; 310 struct attribute_group *attr_group; 311 }; 312 313 static struct kobj_attribute wlan_boot_attribute = 314 __ATTR(boot_wlan, 0220, NULL, wlan_boot_cb); 315 316 static struct attribute *attrs[] = { 317 &wlan_boot_attribute.attr, 318 NULL, 319 }; 320 #define MODULE_INITIALIZED 1 321 322 #ifdef MULTI_IF_NAME 323 #define WLAN_LOADER_NAME "boot_" MULTI_IF_NAME 324 #else 325 #define WLAN_LOADER_NAME "boot_wlan" 326 #endif 327 #endif 328 329 /* the Android framework expects this param even though we don't use it */ 330 #define BUF_LEN 20 331 static char fwpath_buffer[BUF_LEN]; 332 static struct kparam_string fwpath = { 333 .string = fwpath_buffer, 334 .maxlen = BUF_LEN, 335 }; 336 337 char *country_code; 338 #ifdef FEATURE_WLAN_RESIDENT_DRIVER 339 EXPORT_SYMBOL(country_code); 340 #endif 341 static int enable_11d = -1; 342 static int enable_dfs_chan_scan = -1; 343 static bool is_mode_change_psoc_idle_shutdown; 344 345 #define WLAN_NLINK_CESIUM 30 346 347 static qdf_wake_lock_t wlan_wake_lock; 348 349 /* The valid PCIe gen speeds are 1, 2, 3 */ 350 #define HDD_INVALID_MIN_PCIE_GEN_SPEED (0) 351 #define HDD_INVALID_MAX_PCIE_GEN_SPEED (4) 352 353 #define MAX_PDEV_PRE_ENABLE_PARAMS 8 354 #define FTM_MAX_PDEV_PARAMS 1 355 356 #define WOW_MAX_FILTER_LISTS 1 357 #define WOW_MAX_FILTERS_PER_LIST 4 358 #define WOW_MIN_PATTERN_SIZE 6 359 #define WOW_MAX_PATTERN_SIZE 64 360 #define MGMT_DEFAULT_DATA_RATE_6GHZ 0x400 /* This maps to 8.6Mbps data rate */ 361 362 #define IS_IDLE_STOP (!cds_is_driver_unloading() && \ 363 !cds_is_driver_recovering() && !cds_is_driver_loading()) 364 365 #define HDD_FW_VER_MAJOR_SPID(tgt_fw_ver) ((tgt_fw_ver & 0xf0000000) >> 28) 366 #define HDD_FW_VER_MINOR_SPID(tgt_fw_ver) ((tgt_fw_ver & 0xf000000) >> 24) 367 #define HDD_FW_VER_SIID(tgt_fw_ver) ((tgt_fw_ver & 0xf00000) >> 20) 368 #define HDD_FW_VER_CRM_ID(tgt_fw_ver) (tgt_fw_ver & 0x7fff) 369 #define HDD_FW_VER_SUB_ID(tgt_fw_ver_ext) \ 370 (((tgt_fw_ver_ext & 0x1c00) >> 6) | ((tgt_fw_ver_ext & 0xf0000000) >> 28)) 371 #define HDD_FW_VER_REL_ID(tgt_fw_ver_ext) \ 372 ((tgt_fw_ver_ext & 0xf800000) >> 23) 373 374 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0)) 375 static const struct wiphy_wowlan_support wowlan_support_reg_init = { 376 .flags = WIPHY_WOWLAN_ANY | 377 WIPHY_WOWLAN_MAGIC_PKT | 378 WIPHY_WOWLAN_DISCONNECT | 379 WIPHY_WOWLAN_SUPPORTS_GTK_REKEY | 380 WIPHY_WOWLAN_GTK_REKEY_FAILURE | 381 WIPHY_WOWLAN_EAP_IDENTITY_REQ | 382 WIPHY_WOWLAN_4WAY_HANDSHAKE | 383 WIPHY_WOWLAN_RFKILL_RELEASE, 384 .n_patterns = WOW_MAX_FILTER_LISTS * WOW_MAX_FILTERS_PER_LIST, 385 .pattern_min_len = WOW_MIN_PATTERN_SIZE, 386 .pattern_max_len = WOW_MAX_PATTERN_SIZE, 387 }; 388 #endif 389 390 static const struct category_info cinfo[MAX_SUPPORTED_CATEGORY] = { 391 [QDF_MODULE_ID_TLSHIM] = {QDF_TRACE_LEVEL_ALL}, 392 [QDF_MODULE_ID_WMI] = {QDF_TRACE_LEVEL_ALL}, 393 [QDF_MODULE_ID_HTT] = {QDF_TRACE_LEVEL_ALL}, 394 [QDF_MODULE_ID_HDD] = {QDF_TRACE_LEVEL_ALL}, 395 [QDF_MODULE_ID_SME] = {QDF_TRACE_LEVEL_ALL}, 396 [QDF_MODULE_ID_PE] = {QDF_TRACE_LEVEL_ALL}, 397 [QDF_MODULE_ID_WMA] = {QDF_TRACE_LEVEL_ALL}, 398 [QDF_MODULE_ID_SYS] = {QDF_TRACE_LEVEL_ALL}, 399 [QDF_MODULE_ID_QDF] = {QDF_TRACE_LEVEL_ALL}, 400 [QDF_MODULE_ID_SAP] = {QDF_TRACE_LEVEL_ALL}, 401 [QDF_MODULE_ID_HDD_SOFTAP] = {QDF_TRACE_LEVEL_ALL}, 402 [QDF_MODULE_ID_HDD_DATA] = {QDF_DATA_PATH_TRACE_LEVEL}, 403 [QDF_MODULE_ID_HDD_SAP_DATA] = {QDF_DATA_PATH_TRACE_LEVEL}, 404 [QDF_MODULE_ID_HIF] = {QDF_DATA_PATH_TRACE_LEVEL}, 405 [QDF_MODULE_ID_HTC] = {QDF_DATA_PATH_TRACE_LEVEL}, 406 [QDF_MODULE_ID_TXRX] = {QDF_DATA_PATH_TRACE_LEVEL}, 407 [QDF_MODULE_ID_HAL] = {QDF_DATA_PATH_TRACE_LEVEL}, 408 [QDF_MODULE_ID_QDF_DEVICE] = {QDF_TRACE_LEVEL_ALL}, 409 [QDF_MODULE_ID_CFG] = {QDF_TRACE_LEVEL_ALL}, 410 [QDF_MODULE_ID_BMI] = {QDF_TRACE_LEVEL_ALL}, 411 [QDF_MODULE_ID_EPPING] = {QDF_TRACE_LEVEL_ALL}, 412 [QDF_MODULE_ID_QVIT] = {QDF_TRACE_LEVEL_ALL}, 413 [QDF_MODULE_ID_DP] = {QDF_DATA_PATH_TRACE_LEVEL}, 414 [QDF_MODULE_ID_DP_TX_CAPTURE] = {QDF_DATA_PATH_TRACE_LEVEL}, 415 [QDF_MODULE_ID_DP_INIT] = {QDF_DATA_PATH_TRACE_LEVEL}, 416 [QDF_MODULE_ID_DP_STATS] = {QDF_DATA_PATH_TRACE_LEVEL}, 417 [QDF_MODULE_ID_DP_HTT] = {QDF_DATA_PATH_TRACE_LEVEL}, 418 [QDF_MODULE_ID_DP_PEER] = {QDF_DATA_PATH_TRACE_LEVEL}, 419 [QDF_MODULE_ID_DP_HTT_TX_STATS] = {QDF_DATA_PATH_TRACE_LEVEL}, 420 [QDF_MODULE_ID_DP_REO] = {QDF_DATA_PATH_TRACE_LEVEL}, 421 [QDF_MODULE_ID_DP_VDEV] = {QDF_DATA_PATH_TRACE_LEVEL}, 422 [QDF_MODULE_ID_DP_CDP] = {QDF_DATA_PATH_TRACE_LEVEL}, 423 [QDF_MODULE_ID_DP_UMAC_RESET] = {QDF_DATA_PATH_TRACE_LEVEL}, 424 [QDF_MODULE_ID_DP_SAWF] = {QDF_DATA_PATH_TRACE_LEVEL}, 425 [QDF_MODULE_ID_SOC] = {QDF_TRACE_LEVEL_ALL}, 426 [QDF_MODULE_ID_OS_IF] = {QDF_TRACE_LEVEL_ALL}, 427 [QDF_MODULE_ID_TARGET_IF] = {QDF_TRACE_LEVEL_ALL}, 428 [QDF_MODULE_ID_SCHEDULER] = {QDF_TRACE_LEVEL_ALL}, 429 [QDF_MODULE_ID_MGMT_TXRX] = {QDF_TRACE_LEVEL_ALL}, 430 [QDF_MODULE_ID_PMO] = {QDF_TRACE_LEVEL_ALL}, 431 [QDF_MODULE_ID_SCAN] = {QDF_TRACE_LEVEL_ALL}, 432 [QDF_MODULE_ID_POLICY_MGR] = {QDF_TRACE_LEVEL_ALL}, 433 [QDF_MODULE_ID_P2P] = {QDF_TRACE_LEVEL_ALL}, 434 [QDF_MODULE_ID_TDLS] = {QDF_TRACE_LEVEL_ALL}, 435 [QDF_MODULE_ID_REGULATORY] = {QDF_TRACE_LEVEL_ALL}, 436 [QDF_MODULE_ID_SERIALIZATION] = {QDF_TRACE_LEVEL_ALL}, 437 [QDF_MODULE_ID_DFS] = {QDF_TRACE_LEVEL_ALL}, 438 [QDF_MODULE_ID_OBJ_MGR] = {QDF_TRACE_LEVEL_ALL}, 439 [QDF_MODULE_ID_ROAM_DEBUG] = {QDF_TRACE_LEVEL_ALL}, 440 [QDF_MODULE_ID_GREEN_AP] = {QDF_TRACE_LEVEL_ALL}, 441 [QDF_MODULE_ID_OCB] = {QDF_TRACE_LEVEL_ALL}, 442 [QDF_MODULE_ID_IPA] = {QDF_TRACE_LEVEL_ALL}, 443 [QDF_MODULE_ID_ACTION_OUI] = {QDF_TRACE_LEVEL_ALL}, 444 [QDF_MODULE_ID_CONFIG] = {QDF_TRACE_LEVEL_ALL}, 445 [QDF_MODULE_ID_MLME] = {QDF_TRACE_LEVEL_ALL}, 446 [QDF_MODULE_ID_TARGET] = {QDF_TRACE_LEVEL_ALL}, 447 [QDF_MODULE_ID_CRYPTO] = {QDF_TRACE_LEVEL_ALL}, 448 [QDF_MODULE_ID_FWOL] = {QDF_TRACE_LEVEL_ALL}, 449 [QDF_MODULE_ID_SM_ENGINE] = {QDF_TRACE_LEVEL_ALL}, 450 [QDF_MODULE_ID_CMN_MLME] = {QDF_TRACE_LEVEL_ALL}, 451 [QDF_MODULE_ID_NAN] = {QDF_TRACE_LEVEL_ALL}, 452 [QDF_MODULE_ID_CP_STATS] = {QDF_TRACE_LEVEL_ALL}, 453 [QDF_MODULE_ID_DCS] = {QDF_TRACE_LEVEL_ALL}, 454 [QDF_MODULE_ID_INTEROP_ISSUES_AP] = {QDF_TRACE_LEVEL_ALL}, 455 [QDF_MODULE_ID_DENYLIST_MGR] = {QDF_TRACE_LEVEL_ALL}, 456 [QDF_MODULE_ID_DIRECT_BUF_RX] = {QDF_TRACE_LEVEL_ALL}, 457 [QDF_MODULE_ID_SPECTRAL] = {QDF_TRACE_LEVEL_ALL}, 458 [QDF_MODULE_ID_WIFIPOS] = {QDF_TRACE_LEVEL_ALL}, 459 [QDF_MODULE_ID_PKT_CAPTURE] = {QDF_TRACE_LEVEL_ALL}, 460 [QDF_MODULE_ID_FTM_TIME_SYNC] = {QDF_TRACE_LEVEL_ALL}, 461 [QDF_MODULE_ID_CFR] = {QDF_TRACE_LEVEL_ALL}, 462 [QDF_MODULE_ID_IFMGR] = {QDF_TRACE_LEVEL_ALL}, 463 [QDF_MODULE_ID_GPIO] = {QDF_TRACE_LEVEL_ALL}, 464 [QDF_MODULE_ID_T2LM] = {QDF_TRACE_LEVEL_ALL}, 465 [QDF_MODULE_ID_MLO] = {QDF_TRACE_LEVEL_ALL}, 466 [QDF_MODULE_ID_SON] = {QDF_TRACE_LEVEL_ALL}, 467 [QDF_MODULE_ID_TWT] = {QDF_TRACE_LEVEL_ALL}, 468 [QDF_MODULE_ID_WLAN_PRE_CAC] = {QDF_TRACE_LEVEL_ALL}, 469 [QDF_MODULE_ID_COAP] = {QDF_TRACE_LEVEL_ALL}, 470 [QDF_MODULE_ID_MON_FILTER] = {QDF_DATA_PATH_TRACE_LEVEL}, 471 [QDF_MODULE_ID_LL_SAP] = {QDF_TRACE_LEVEL_ALL}, 472 }; 473 474 struct notifier_block hdd_netdev_notifier; 475 476 struct sock *cesium_nl_srv_sock; 477 #ifdef FEATURE_WLAN_AUTO_SHUTDOWN 478 static void wlan_hdd_auto_shutdown_cb(void); 479 #endif 480 481 static void hdd_dp_register_callbacks(struct hdd_context *hdd_ctx); 482 483 bool hdd_adapter_is_ap(struct hdd_adapter *adapter) 484 { 485 if (!adapter) { 486 hdd_err("null adapter"); 487 return false; 488 } 489 490 return adapter->device_mode == QDF_SAP_MODE || 491 adapter->device_mode == QDF_P2P_GO_MODE; 492 } 493 494 QDF_STATUS hdd_common_roam_callback(struct wlan_objmgr_psoc *psoc, 495 uint8_t session_id, 496 struct csr_roam_info *roam_info, 497 eRoamCmdStatus roam_status, 498 eCsrRoamResult roam_result) 499 { 500 struct hdd_context *hdd_ctx; 501 struct hdd_adapter *adapter; 502 struct wlan_hdd_link_info *link_info; 503 QDF_STATUS status = QDF_STATUS_SUCCESS; 504 505 link_info = wlan_hdd_get_link_info_from_vdev(psoc, session_id); 506 if (!link_info) 507 return QDF_STATUS_E_INVAL; 508 509 adapter = link_info->adapter; 510 hdd_ctx = WLAN_HDD_GET_CTX(adapter); 511 if (!hdd_ctx) 512 return QDF_STATUS_E_INVAL; 513 514 switch (adapter->device_mode) { 515 case QDF_STA_MODE: 516 case QDF_NDI_MODE: 517 case QDF_P2P_CLIENT_MODE: 518 case QDF_P2P_DEVICE_MODE: 519 status = hdd_sme_roam_callback(link_info, roam_info, 520 roam_status, roam_result); 521 break; 522 case QDF_SAP_MODE: 523 case QDF_P2P_GO_MODE: 524 status = 525 wlansap_roam_callback(link_info->session.ap.sap_context, 526 roam_info, roam_status, 527 roam_result); 528 break; 529 default: 530 hdd_err("Wrong device mode"); 531 break; 532 } 533 534 return status; 535 } 536 537 void hdd_start_complete(int ret) 538 { 539 wlan_start_ret_val = ret; 540 complete_all(&wlan_start_comp); 541 } 542 543 #ifdef WLAN_FEATURE_LOCAL_PKT_CAPTURE 544 /** 545 * wlan_hdd_lpc_del_monitor_interface() - Delete monitor interface 546 * @hdd_ctx: hdd_ctx 547 * @is_virtual_iface: Is virtual interface 548 * 549 * This function takes care of deleting monitor interface 550 * 551 * Return: none 552 */ 553 static void 554 wlan_hdd_lpc_del_monitor_interface(struct hdd_context *hdd_ctx, 555 bool is_virtual_iface) 556 { 557 struct hdd_adapter *adapter; 558 void *soc; 559 bool running; 560 561 if (!hdd_ctx) 562 return; 563 564 if (!ucfg_dp_is_local_pkt_capture_enabled(hdd_ctx->psoc)) 565 return; 566 567 soc = cds_get_context(QDF_MODULE_ID_SOC); 568 if (!soc) 569 return; 570 571 running = cdp_is_local_pkt_capture_running(soc, OL_TXRX_PDEV_ID); 572 if (!running) 573 return; 574 575 adapter = hdd_get_adapter(hdd_ctx, QDF_MONITOR_MODE); 576 if (!adapter) { 577 hdd_debug("There is no monitor adapter"); 578 return; 579 } 580 581 hdd_debug("lpc: Delete monitor interface"); 582 583 wlan_hdd_release_intf_addr(hdd_ctx, adapter->mac_addr.bytes); 584 qdf_zero_macaddr(&adapter->mac_addr); 585 hdd_stop_adapter(hdd_ctx, adapter); 586 hdd_deinit_adapter(hdd_ctx, adapter, true); 587 adapter->is_virtual_iface = is_virtual_iface; 588 hdd_ctx->lpc_info.mon_adapter = adapter; 589 590 hdd_ctx->lpc_info.lpc_wk_scheduled = true; 591 qdf_sched_work(0, &hdd_ctx->lpc_info.lpc_wk); 592 } 593 594 void wlan_hdd_lpc_handle_concurrency(struct hdd_context *hdd_ctx, 595 bool is_virtual_iface) 596 { 597 if (policy_mgr_is_sta_mon_concurrency(hdd_ctx->psoc)) 598 wlan_hdd_lpc_del_monitor_interface(hdd_ctx, is_virtual_iface); 599 } 600 601 bool hdd_lpc_is_work_scheduled(struct hdd_context *hdd_ctx) 602 { 603 return hdd_ctx->lpc_info.lpc_wk_scheduled; 604 } 605 606 static void hdd_lpc_work_handler(void *arg) 607 { 608 struct hdd_context *hdd_ctx = (struct hdd_context *)arg; 609 struct hdd_adapter *adapter; 610 struct osif_vdev_sync *vdev_sync; 611 int errno; 612 613 if (!hdd_ctx) 614 return; 615 616 adapter = hdd_ctx->lpc_info.mon_adapter; 617 if (!adapter) { 618 hdd_err("There is no monitor adapter"); 619 return; 620 } 621 622 errno = osif_vdev_sync_trans_start_wait(adapter->dev, &vdev_sync); 623 if (errno) 624 return; 625 626 osif_vdev_sync_unregister(adapter->dev); 627 osif_vdev_sync_wait_for_ops(vdev_sync); 628 629 hdd_close_adapter(hdd_ctx, adapter, true); 630 hdd_ctx->lpc_info.lpc_wk_scheduled = false; 631 632 osif_vdev_sync_trans_stop(vdev_sync); 633 osif_vdev_sync_destroy(vdev_sync); 634 } 635 636 static inline 637 void hdd_lp_create_work(struct hdd_context *hdd_ctx) 638 { 639 hdd_ctx->lpc_info.lpc_wk_scheduled = false; 640 qdf_create_work(0, &hdd_ctx->lpc_info.lpc_wk, hdd_lpc_work_handler, 641 hdd_ctx); 642 } 643 644 static inline 645 void hdd_lpc_delete_work(struct hdd_context *hdd_ctx) 646 { 647 qdf_flush_work(&hdd_ctx->lpc_info.lpc_wk); 648 hdd_ctx->lpc_info.lpc_wk_scheduled = false; 649 qdf_destroy_work(NULL, &hdd_ctx->lpc_info.lpc_wk); 650 } 651 652 #else 653 static inline 654 void hdd_lp_create_work(struct hdd_context *hdd_ctx) 655 { 656 } 657 658 static inline 659 void hdd_lpc_delete_work(struct hdd_context *hdd_ctx) 660 { 661 } 662 663 static inline 664 void wlan_hdd_lpc_del_monitor_interface(struct hdd_context *hdd_ctx, 665 bool is_virtual_iface) 666 { 667 } 668 #endif 669 670 #ifdef QCA_HL_NETDEV_FLOW_CONTROL 671 void wlan_hdd_mod_fc_timer(struct hdd_adapter *adapter, 672 enum netif_action_type action) 673 { 674 struct hdd_stats *hdd_stats; 675 676 if (!adapter->tx_flow_timer_initialized) 677 return; 678 679 hdd_stats = &adapter->deflink->hdd_stats; 680 if (action == WLAN_WAKE_NON_PRIORITY_QUEUE) { 681 qdf_mc_timer_stop(&adapter->tx_flow_control_timer); 682 hdd_stats->tx_rx_stats.is_txflow_paused = false; 683 hdd_stats->tx_rx_stats.txflow_unpause_cnt++; 684 } else if (action == WLAN_STOP_NON_PRIORITY_QUEUE) { 685 QDF_STATUS status = 686 qdf_mc_timer_start(&adapter->tx_flow_control_timer, 687 WLAN_HDD_TX_FLOW_CONTROL_OS_Q_BLOCK_TIME); 688 689 if (!QDF_IS_STATUS_SUCCESS(status)) 690 hdd_err("Failed to start tx_flow_control_timer"); 691 else 692 hdd_stats->tx_rx_stats.txflow_timer_cnt++; 693 694 hdd_stats->tx_rx_stats.txflow_pause_cnt++; 695 hdd_stats->tx_rx_stats.is_txflow_paused = true; 696 } 697 } 698 #endif /* QCA_HL_NETDEV_FLOW_CONTROL */ 699 700 /** 701 * wlan_hdd_txrx_pause_cb() - pause callback from txrx layer 702 * @vdev_id: vdev_id 703 * @action: action type 704 * @reason: reason type 705 * 706 * Return: none 707 */ 708 void wlan_hdd_txrx_pause_cb(uint8_t vdev_id, 709 enum netif_action_type action, enum netif_reason_type reason) 710 { 711 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 712 struct hdd_adapter *adapter; 713 struct wlan_hdd_link_info *link_info; 714 715 if (!hdd_ctx) 716 return; 717 718 link_info = hdd_get_link_info_by_vdev(hdd_ctx, vdev_id); 719 if (!link_info) 720 return; 721 722 adapter = link_info->adapter; 723 wlan_hdd_mod_fc_timer(adapter, action); 724 wlan_hdd_netif_queue_control(adapter, action, reason); 725 } 726 727 /* 728 * Store WLAN driver version and timestamp info in global variables such that 729 * crash debugger can extract them from driver debug symbol and crashdump for 730 * post processing 731 */ 732 #ifdef BUILD_TAG 733 uint8_t g_wlan_driver_version[] = QWLAN_VERSIONSTR TIMER_MANAGER_STR MEMORY_DEBUG_STR PANIC_ON_BUG_STR "; " BUILD_TAG; 734 #else 735 uint8_t g_wlan_driver_version[] = QWLAN_VERSIONSTR TIMER_MANAGER_STR MEMORY_DEBUG_STR PANIC_ON_BUG_STR; 736 #endif 737 738 int hdd_validate_channel_and_bandwidth(struct hdd_adapter *adapter, 739 qdf_freq_t chan_freq, 740 enum phy_ch_width chan_bw) 741 { 742 struct ch_params ch_params = {0}; 743 struct hdd_context *hdd_ctx; 744 745 hdd_ctx = WLAN_HDD_GET_CTX(adapter); 746 if (!hdd_ctx) { 747 hdd_err("hdd context is NULL"); 748 return -EINVAL; 749 } 750 751 if (reg_is_chan_enum_invalid( 752 wlan_reg_get_chan_enum_for_freq(chan_freq))) { 753 hdd_err("Channel freq %d not in driver's valid channel list", chan_freq); 754 return -EOPNOTSUPP; 755 } 756 757 if ((!WLAN_REG_IS_24GHZ_CH_FREQ(chan_freq)) && 758 (!WLAN_REG_IS_5GHZ_CH_FREQ(chan_freq)) && 759 (!WLAN_REG_IS_6GHZ_CHAN_FREQ(chan_freq))) { 760 hdd_err("CH %d is not in 2.4GHz or 5GHz or 6GHz", chan_freq); 761 return -EINVAL; 762 } 763 ch_params.ch_width = CH_WIDTH_MAX; 764 wlan_reg_set_channel_params_for_pwrmode(hdd_ctx->pdev, chan_freq, 765 0, &ch_params, 766 REG_CURRENT_PWR_MODE); 767 if (ch_params.ch_width == CH_WIDTH_MAX) { 768 hdd_err("failed to get max bandwdith for %d", chan_freq); 769 return -EINVAL; 770 } 771 if (WLAN_REG_IS_24GHZ_CH_FREQ(chan_freq)) { 772 if (chan_bw == CH_WIDTH_80MHZ) { 773 hdd_err("BW80 not possible in 2.4GHz band"); 774 return -EINVAL; 775 } 776 if ((chan_bw != CH_WIDTH_20MHZ) && 777 (chan_freq == wlan_reg_ch_to_freq(CHAN_ENUM_2484)) && 778 (chan_bw != CH_WIDTH_MAX) && 779 (ch_params.ch_width == CH_WIDTH_20MHZ)) { 780 hdd_err("Only BW20 possible on channel freq 2484"); 781 return -EINVAL; 782 } 783 } 784 785 if (WLAN_REG_IS_5GHZ_CH_FREQ(chan_freq)) { 786 if ((chan_bw != CH_WIDTH_20MHZ) && 787 (chan_freq == wlan_reg_ch_to_freq(CHAN_ENUM_5825)) && 788 (chan_bw != CH_WIDTH_MAX) && 789 (ch_params.ch_width == CH_WIDTH_20MHZ)) { 790 hdd_err("Only BW20 possible on channel freq 5825"); 791 return -EINVAL; 792 } 793 } 794 795 return 0; 796 } 797 798 uint32_t hdd_get_link_info_home_channel(struct wlan_hdd_link_info *link_info) 799 { 800 uint32_t home_chan_freq = 0; 801 enum QDF_OPMODE opmode = link_info->adapter->device_mode; 802 803 switch (opmode) { 804 case QDF_SAP_MODE: 805 case QDF_P2P_GO_MODE: 806 if (test_bit(SOFTAP_BSS_STARTED, &link_info->link_flags)) { 807 home_chan_freq = 808 link_info->session.ap.operating_chan_freq; 809 } 810 break; 811 case QDF_STA_MODE: 812 case QDF_P2P_CLIENT_MODE: 813 if (hdd_cm_is_vdev_associated(link_info)) { 814 home_chan_freq = 815 link_info->session.station.conn_info.chan_freq; 816 } 817 break; 818 default: 819 break; 820 } 821 822 return home_chan_freq; 823 } 824 825 enum phy_ch_width hdd_get_link_info_width(struct wlan_hdd_link_info *link_info) 826 { 827 enum phy_ch_width width = CH_WIDTH_20MHZ; 828 enum QDF_OPMODE opmode = link_info->adapter->device_mode; 829 830 switch (opmode) { 831 case QDF_SAP_MODE: 832 case QDF_P2P_GO_MODE: 833 if (test_bit(SOFTAP_BSS_STARTED, &link_info->link_flags)) { 834 struct hdd_ap_ctx *ap_ctx = 835 WLAN_HDD_GET_AP_CTX_PTR(link_info); 836 837 width = ap_ctx->sap_config.ch_params.ch_width; 838 } 839 break; 840 case QDF_STA_MODE: 841 case QDF_P2P_CLIENT_MODE: 842 if (hdd_cm_is_vdev_associated(link_info)) 843 width = link_info->session.station.conn_info.ch_width; 844 break; 845 default: 846 break; 847 } 848 849 return width; 850 } 851 852 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0)) 853 static inline struct net_device *hdd_net_dev_from_notifier(void *context) 854 { 855 struct netdev_notifier_info *info = context; 856 857 return info->dev; 858 } 859 #else 860 static inline struct net_device *hdd_net_dev_from_notifier(void *context) 861 { 862 return context; 863 } 864 #endif 865 866 static int __hdd_netdev_notifier_call(struct net_device *net_dev, 867 unsigned long state) 868 { 869 struct hdd_adapter *adapter; 870 struct hdd_context *hdd_ctx; 871 struct wlan_objmgr_vdev *vdev; 872 873 hdd_enter_dev(net_dev); 874 875 if (!net_dev->ieee80211_ptr) { 876 hdd_debug("ieee80211_ptr is null"); 877 return NOTIFY_DONE; 878 } 879 880 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 881 if (!hdd_ctx) 882 return NOTIFY_DONE; 883 884 if (hdd_ctx->driver_status == DRIVER_MODULES_CLOSED) { 885 hdd_debug("Driver module is closed"); 886 return NOTIFY_DONE; 887 } 888 889 /* Make sure that this callback corresponds to our device. */ 890 adapter = hdd_get_adapter_by_iface_name(hdd_ctx, net_dev->name); 891 if (!adapter) { 892 hdd_debug("failed to look up adapter for '%s'", net_dev->name); 893 return NOTIFY_DONE; 894 } 895 896 if (adapter != WLAN_HDD_GET_PRIV_PTR(net_dev)) { 897 hdd_err("HDD adapter mismatch!"); 898 return NOTIFY_DONE; 899 } 900 901 if (cds_is_driver_recovering()) { 902 hdd_debug("Driver is recovering"); 903 return NOTIFY_DONE; 904 } 905 906 if (cds_is_driver_in_bad_state()) { 907 hdd_debug("Driver is in failed recovery state"); 908 return NOTIFY_DONE; 909 } 910 911 hdd_debug("%s New Net Device State = %lu, flags 0x%x", 912 net_dev->name, state, net_dev->flags); 913 914 switch (state) { 915 case NETDEV_REGISTER: 916 break; 917 918 case NETDEV_UNREGISTER: 919 break; 920 921 case NETDEV_UP: 922 sme_ch_avoid_update_req(hdd_ctx->mac_handle); 923 break; 924 925 case NETDEV_DOWN: 926 break; 927 928 case NETDEV_CHANGE: 929 if (adapter->is_link_up_service_needed) 930 complete(&adapter->linkup_event_var); 931 break; 932 933 case NETDEV_GOING_DOWN: 934 vdev = hdd_objmgr_get_vdev_by_user(adapter->deflink, 935 WLAN_OSIF_SCAN_ID); 936 if (!vdev) 937 break; 938 if (ucfg_scan_get_vdev_status(vdev) != 939 SCAN_NOT_IN_PROGRESS) { 940 wlan_abort_scan(hdd_ctx->pdev, INVAL_PDEV_ID, 941 adapter->deflink->vdev_id, 942 INVALID_SCAN_ID, true); 943 } 944 hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_SCAN_ID); 945 cds_flush_work(&adapter->scan_block_work); 946 /* Need to clean up blocked scan request */ 947 wlan_hdd_cfg80211_scan_block(adapter); 948 hdd_debug("Scan is not Pending from user"); 949 /* 950 * After NETDEV_GOING_DOWN, kernel calls hdd_stop.Irrespective 951 * of return status of hdd_stop call, kernel resets the IFF_UP 952 * flag after which driver does not send the cfg80211_scan_done. 953 * Ensure to cleanup the scan queue in NETDEV_GOING_DOWN 954 */ 955 wlan_cfg80211_cleanup_scan_queue(hdd_ctx->pdev, net_dev); 956 break; 957 case NETDEV_FEAT_CHANGE: 958 hdd_debug("vdev %d netdev Feature 0x%llx\n", 959 adapter->deflink->vdev_id, net_dev->features); 960 break; 961 default: 962 break; 963 } 964 965 return NOTIFY_DONE; 966 } 967 968 static int hdd_netdev_notifier_bridge_intf(struct net_device *net_dev, 969 unsigned long state) 970 { 971 struct hdd_adapter *adapter, *next_adapter = NULL; 972 wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_GET_ADAPTER; 973 struct hdd_context *hdd_ctx; 974 QDF_STATUS status; 975 976 hdd_enter_dev(net_dev); 977 978 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 979 if (wlan_hdd_validate_context(hdd_ctx)) 980 return NOTIFY_DONE; 981 982 hdd_debug("%s New Net Device State = %lu, flags 0x%x bridge mac address: "QDF_MAC_ADDR_FMT, 983 net_dev->name, state, net_dev->flags, QDF_MAC_ADDR_REF(net_dev->dev_addr)); 984 985 if (!qdf_mem_cmp(hdd_ctx->bridgeaddr, net_dev->dev_addr, 986 QDF_MAC_ADDR_SIZE)) 987 return NOTIFY_DONE; 988 989 switch (state) { 990 case NETDEV_REGISTER: 991 case NETDEV_CHANGEADDR: 992 /* Update FW WoW pattern with new MAC address */ 993 qdf_mem_copy(hdd_ctx->bridgeaddr, net_dev->dev_addr, 994 QDF_MAC_ADDR_SIZE); 995 996 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 997 dbgid) { 998 if (adapter->device_mode != QDF_SAP_MODE) 999 goto loop_next; 1000 1001 if (wlan_hdd_validate_vdev_id(adapter->deflink->vdev_id)) 1002 goto loop_next; 1003 1004 status = wlan_objmgr_vdev_try_get_ref(adapter->deflink->vdev, 1005 WLAN_HDD_ID_OBJ_MGR); 1006 if (QDF_IS_STATUS_ERROR(status)) 1007 goto loop_next; 1008 1009 ucfg_pmo_set_vdev_bridge_addr(adapter->deflink->vdev, 1010 (struct qdf_mac_addr *)hdd_ctx->bridgeaddr); 1011 ucfg_pmo_del_wow_pattern(adapter->deflink->vdev); 1012 ucfg_pmo_register_wow_default_patterns(adapter->deflink->vdev); 1013 1014 wlan_objmgr_vdev_release_ref(adapter->deflink->vdev, 1015 WLAN_HDD_ID_OBJ_MGR); 1016 1017 loop_next: 1018 hdd_adapter_dev_put_debug(adapter, dbgid); 1019 } 1020 1021 break; 1022 case NETDEV_UNREGISTER: 1023 qdf_zero_macaddr((struct qdf_mac_addr *)hdd_ctx->bridgeaddr); 1024 break; 1025 default: 1026 break; 1027 } 1028 1029 return NOTIFY_DONE; 1030 } 1031 1032 /** 1033 * hdd_netdev_notifier_call() - netdev notifier callback function 1034 * @nb: pointer to notifier block 1035 * @state: state 1036 * @context: notifier callback context pointer 1037 * 1038 * Return: 0 on success, error number otherwise. 1039 */ 1040 static int hdd_netdev_notifier_call(struct notifier_block *nb, 1041 unsigned long state, 1042 void *context) 1043 { 1044 struct net_device *net_dev = hdd_net_dev_from_notifier(context); 1045 struct osif_vdev_sync *vdev_sync; 1046 int errno; 1047 1048 if (net_dev->priv_flags & IFF_EBRIDGE) { 1049 errno = hdd_netdev_notifier_bridge_intf(net_dev, state); 1050 if (errno) 1051 return NOTIFY_DONE; 1052 } 1053 1054 errno = osif_vdev_sync_op_start(net_dev, &vdev_sync); 1055 if (errno) { 1056 hdd_debug("%s New Net Device State = %lu, flags 0x%x NOTIFY_DONE", 1057 net_dev->name, state, net_dev->flags); 1058 return NOTIFY_DONE; 1059 } 1060 1061 errno = __hdd_netdev_notifier_call(net_dev, state); 1062 1063 osif_vdev_sync_op_stop(vdev_sync); 1064 1065 return NOTIFY_DONE; 1066 } 1067 1068 struct notifier_block hdd_netdev_notifier = { 1069 .notifier_call = hdd_netdev_notifier_call, 1070 }; 1071 1072 /* variable to hold the insmod parameters */ 1073 int con_mode; 1074 #ifdef FEATURE_WLAN_RESIDENT_DRIVER 1075 EXPORT_SYMBOL(con_mode); 1076 #endif 1077 1078 int con_mode_ftm; 1079 #ifdef FEATURE_WLAN_RESIDENT_DRIVER 1080 EXPORT_SYMBOL(con_mode_ftm); 1081 #endif 1082 int con_mode_epping; 1083 1084 static int pcie_gen_speed; 1085 1086 /* Variable to hold connection mode including module parameter con_mode */ 1087 static int curr_con_mode; 1088 1089 #if defined(WLAN_FEATURE_11BE) && defined(CFG80211_11BE_BASIC) 1090 static enum phy_ch_width hdd_get_eht_phy_ch_width_from_target(void) 1091 { 1092 uint32_t max_fw_bw = sme_get_eht_ch_width(); 1093 1094 if (max_fw_bw == WNI_CFG_EHT_CHANNEL_WIDTH_320MHZ) 1095 return CH_WIDTH_320MHZ; 1096 else if (max_fw_bw == WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ) 1097 return CH_WIDTH_160MHZ; 1098 else 1099 return CH_WIDTH_80MHZ; 1100 } 1101 1102 static bool hdd_is_target_eht_phy_ch_width_supported(enum phy_ch_width width) 1103 { 1104 enum phy_ch_width max_fw_bw = hdd_get_eht_phy_ch_width_from_target(); 1105 1106 if (width <= max_fw_bw) 1107 return true; 1108 1109 hdd_err("FW does not support this BW %d max BW supported %d", 1110 width, max_fw_bw); 1111 return false; 1112 } 1113 1114 static bool hdd_is_target_eht_160mhz_capable(void) 1115 { 1116 return hdd_is_target_eht_phy_ch_width_supported(CH_WIDTH_160MHZ); 1117 } 1118 1119 static enum phy_ch_width 1120 wlan_hdd_map_nl_chan_width(enum nl80211_chan_width width) 1121 { 1122 if (width == NL80211_CHAN_WIDTH_320) { 1123 return hdd_get_eht_phy_ch_width_from_target(); 1124 } else { 1125 hdd_err("Invalid channel width %d, setting to default", width); 1126 return CH_WIDTH_INVALID; 1127 } 1128 } 1129 1130 #else /* !WLAN_FEATURE_11BE */ 1131 static inline bool 1132 hdd_is_target_eht_phy_ch_width_supported(enum phy_ch_width width) 1133 { 1134 return true; 1135 } 1136 1137 static inline bool hdd_is_target_eht_160mhz_capable(void) 1138 { 1139 return false; 1140 } 1141 1142 static enum phy_ch_width 1143 wlan_hdd_map_nl_chan_width(enum nl80211_chan_width width) 1144 { 1145 hdd_err("Invalid channel width %d, setting to default", width); 1146 return CH_WIDTH_INVALID; 1147 } 1148 #endif /* WLAN_FEATURE_11BE */ 1149 1150 /** 1151 * hdd_map_nl_chan_width() - Map NL channel width to internal representation 1152 * @ch_width: NL channel width 1153 * 1154 * Converts the NL channel width to the driver's internal representation 1155 * 1156 * Return: Converted channel width. In case of non matching NL channel width, 1157 * CH_WIDTH_MAX will be returned. 1158 */ 1159 enum phy_ch_width hdd_map_nl_chan_width(enum nl80211_chan_width ch_width) 1160 { 1161 uint8_t fw_ch_bw; 1162 1163 fw_ch_bw = wma_get_vht_ch_width(); 1164 switch (ch_width) { 1165 case NL80211_CHAN_WIDTH_20_NOHT: 1166 case NL80211_CHAN_WIDTH_20: 1167 return CH_WIDTH_20MHZ; 1168 case NL80211_CHAN_WIDTH_40: 1169 return CH_WIDTH_40MHZ; 1170 case NL80211_CHAN_WIDTH_80: 1171 return CH_WIDTH_80MHZ; 1172 case NL80211_CHAN_WIDTH_80P80: 1173 if (fw_ch_bw == WNI_CFG_VHT_CHANNEL_WIDTH_80_PLUS_80MHZ) 1174 return CH_WIDTH_80P80MHZ; 1175 else if (fw_ch_bw == WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ) 1176 return CH_WIDTH_160MHZ; 1177 else 1178 return CH_WIDTH_80MHZ; 1179 case NL80211_CHAN_WIDTH_160: 1180 if (hdd_is_target_eht_160mhz_capable()) 1181 return CH_WIDTH_160MHZ; 1182 1183 if (fw_ch_bw >= WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ) 1184 return CH_WIDTH_160MHZ; 1185 else 1186 return CH_WIDTH_80MHZ; 1187 case NL80211_CHAN_WIDTH_5: 1188 return CH_WIDTH_5MHZ; 1189 case NL80211_CHAN_WIDTH_10: 1190 return CH_WIDTH_10MHZ; 1191 default: 1192 return wlan_hdd_map_nl_chan_width(ch_width); 1193 } 1194 } 1195 1196 #if defined(WLAN_FEATURE_NAN) && \ 1197 (KERNEL_VERSION(4, 9, 0) <= LINUX_VERSION_CODE) 1198 /** 1199 * wlan_hdd_convert_nan_type() - Convert nl type to qdf type 1200 * @nl_type: NL80211 interface type 1201 * @out_qdf_type: QDF type for the given nl_type 1202 * 1203 * Convert nl type to QDF type 1204 * 1205 * Return: QDF_STATUS_SUCCESS if converted, failure otherwise. 1206 */ 1207 static QDF_STATUS wlan_hdd_convert_nan_type(enum nl80211_iftype nl_type, 1208 enum QDF_OPMODE *out_qdf_type) 1209 { 1210 if (nl_type == NL80211_IFTYPE_NAN) { 1211 *out_qdf_type = QDF_NAN_DISC_MODE; 1212 return QDF_STATUS_SUCCESS; 1213 } 1214 return QDF_STATUS_E_INVAL; 1215 } 1216 1217 /** 1218 * wlan_hdd_set_nan_if_type() - Set the NAN iftype 1219 * @adapter: pointer to HDD adapter 1220 * 1221 * Set the NL80211_IFTYPE_NAN to wdev iftype. 1222 * 1223 * Return: None 1224 */ 1225 static void wlan_hdd_set_nan_if_type(struct hdd_adapter *adapter) 1226 { 1227 adapter->wdev.iftype = NL80211_IFTYPE_NAN; 1228 } 1229 1230 static bool wlan_hdd_is_vdev_creation_allowed(struct wlan_objmgr_psoc *psoc) 1231 { 1232 return ucfg_nan_is_vdev_creation_allowed(psoc); 1233 } 1234 #else 1235 static QDF_STATUS wlan_hdd_convert_nan_type(enum nl80211_iftype nl_type, 1236 enum QDF_OPMODE *out_qdf_type) 1237 { 1238 return QDF_STATUS_E_INVAL; 1239 } 1240 1241 static void wlan_hdd_set_nan_if_type(struct hdd_adapter *adapter) 1242 { 1243 } 1244 1245 static bool wlan_hdd_is_vdev_creation_allowed(struct wlan_objmgr_psoc *psoc) 1246 { 1247 return false; 1248 } 1249 #endif 1250 1251 QDF_STATUS hdd_nl_to_qdf_iface_type(enum nl80211_iftype nl_type, 1252 enum QDF_OPMODE *out_qdf_type) 1253 { 1254 QDF_STATUS status = QDF_STATUS_SUCCESS; 1255 1256 switch (nl_type) { 1257 case NL80211_IFTYPE_AP: 1258 *out_qdf_type = QDF_SAP_MODE; 1259 break; 1260 case NL80211_IFTYPE_MONITOR: 1261 *out_qdf_type = QDF_MONITOR_MODE; 1262 break; 1263 case NL80211_IFTYPE_OCB: 1264 *out_qdf_type = QDF_OCB_MODE; 1265 break; 1266 case NL80211_IFTYPE_P2P_CLIENT: 1267 *out_qdf_type = QDF_P2P_CLIENT_MODE; 1268 break; 1269 case NL80211_IFTYPE_P2P_DEVICE: 1270 *out_qdf_type = QDF_P2P_DEVICE_MODE; 1271 break; 1272 case NL80211_IFTYPE_P2P_GO: 1273 *out_qdf_type = QDF_P2P_GO_MODE; 1274 break; 1275 case NL80211_IFTYPE_STATION: 1276 *out_qdf_type = QDF_STA_MODE; 1277 break; 1278 case NL80211_IFTYPE_WDS: 1279 *out_qdf_type = QDF_WDS_MODE; 1280 break; 1281 default: 1282 status = wlan_hdd_convert_nan_type(nl_type, out_qdf_type); 1283 if (QDF_IS_STATUS_SUCCESS(status)) 1284 break; 1285 hdd_err("Invalid nl80211 interface type %d", nl_type); 1286 return QDF_STATUS_E_INVAL; 1287 } 1288 1289 return QDF_STATUS_SUCCESS; 1290 } 1291 1292 uint8_t wlan_hdd_find_opclass(mac_handle_t mac_handle, uint8_t channel, 1293 uint8_t bw_offset) 1294 { 1295 uint8_t opclass = 0; 1296 1297 sme_get_opclass(mac_handle, channel, bw_offset, &opclass); 1298 return opclass; 1299 } 1300 1301 /** 1302 * hdd_qdf_trace_enable() - configure initial QDF Trace enable 1303 * @module_id: Module whose trace level is being configured 1304 * @bitmask: Bitmask of log levels to be enabled 1305 * 1306 * Called immediately after the cfg.ini is read in order to configure 1307 * the desired trace levels. 1308 * 1309 * Return: None 1310 */ 1311 int hdd_qdf_trace_enable(QDF_MODULE_ID module_id, uint32_t bitmask) 1312 { 1313 QDF_TRACE_LEVEL level; 1314 int qdf_print_idx = -1; 1315 int status = -1; 1316 /* 1317 * if the bitmask is the default value, then a bitmask was not 1318 * specified in cfg.ini, so leave the logging level alone (it 1319 * will remain at the "compiled in" default value) 1320 */ 1321 if (CFG_QDF_TRACE_ENABLE_DEFAULT == bitmask) 1322 return 0; 1323 1324 qdf_print_idx = qdf_get_pidx(); 1325 1326 /* a mask was specified. start by disabling all logging */ 1327 status = qdf_print_set_category_verbose(qdf_print_idx, module_id, 1328 QDF_TRACE_LEVEL_NONE, 0); 1329 1330 if (QDF_STATUS_SUCCESS != status) 1331 return -EINVAL; 1332 /* now cycle through the bitmask until all "set" bits are serviced */ 1333 level = QDF_TRACE_LEVEL_NONE; 1334 while (0 != bitmask) { 1335 if (bitmask & 1) { 1336 status = qdf_print_set_category_verbose(qdf_print_idx, 1337 module_id, level, 1); 1338 if (QDF_STATUS_SUCCESS != status) 1339 return -EINVAL; 1340 } 1341 1342 level++; 1343 bitmask >>= 1; 1344 } 1345 return 0; 1346 } 1347 1348 int __wlan_hdd_validate_context(struct hdd_context *hdd_ctx, const char *func) 1349 { 1350 if (!hdd_ctx) { 1351 hdd_err("HDD context is null (via %s)", func); 1352 return -ENODEV; 1353 } 1354 1355 if (!hdd_ctx->config) { 1356 hdd_err("HDD config is null (via %s)", func); 1357 return -ENODEV; 1358 } 1359 1360 if (cds_is_driver_recovering()) { 1361 hdd_debug("Recovery in progress (via %s); state:0x%x", 1362 func, cds_get_driver_state()); 1363 return -EAGAIN; 1364 } 1365 1366 if (cds_is_load_or_unload_in_progress()) { 1367 hdd_debug("Load/unload in progress (via %s); state:0x%x", 1368 func, cds_get_driver_state()); 1369 return -EAGAIN; 1370 } 1371 1372 if (cds_is_driver_in_bad_state()) { 1373 hdd_debug("Driver in bad state (via %s); state:0x%x", 1374 func, cds_get_driver_state()); 1375 return -EAGAIN; 1376 } 1377 1378 if (cds_is_fw_down()) { 1379 hdd_debug("FW is down (via %s); state:0x%x", 1380 func, cds_get_driver_state()); 1381 return -EAGAIN; 1382 } 1383 1384 if (hdd_ctx->is_wlan_disabled) { 1385 hdd_debug("WLAN is disabled by user space"); 1386 return -EAGAIN; 1387 } 1388 1389 return 0; 1390 } 1391 1392 int __hdd_validate_adapter(struct hdd_adapter *adapter, const char *func) 1393 { 1394 if (!adapter) { 1395 hdd_err("adapter is null (via %s)", func); 1396 return -EINVAL; 1397 } 1398 1399 if (adapter->magic != WLAN_HDD_ADAPTER_MAGIC) { 1400 hdd_err("bad adapter magic (via %s)", func); 1401 return -EINVAL; 1402 } 1403 1404 if (!adapter->dev) { 1405 hdd_err("adapter net_device is null (via %s)", func); 1406 return -EINVAL; 1407 } 1408 1409 if (!(adapter->dev->flags & IFF_UP)) { 1410 hdd_debug_rl("adapter '%s' is not up (via %s)", 1411 adapter->dev->name, func); 1412 return -EAGAIN; 1413 } 1414 1415 return __wlan_hdd_validate_vdev_id(adapter->deflink->vdev_id, func); 1416 } 1417 1418 int __wlan_hdd_validate_vdev_id(uint8_t vdev_id, const char *func) 1419 { 1420 if (vdev_id == WLAN_UMAC_VDEV_ID_MAX) { 1421 hdd_debug_rl("adapter is not up (via %s)", func); 1422 return -EINVAL; 1423 } 1424 1425 if (vdev_id >= WLAN_MAX_VDEVS) { 1426 hdd_err("bad vdev Id:%u (via %s)", vdev_id, func); 1427 return -EINVAL; 1428 } 1429 1430 return 0; 1431 } 1432 1433 QDF_STATUS __wlan_hdd_validate_mac_address(struct qdf_mac_addr *mac_addr, 1434 const char *func) 1435 { 1436 if (!mac_addr) { 1437 hdd_err("Received NULL mac address (via %s)", func); 1438 return QDF_STATUS_E_INVAL; 1439 } 1440 1441 if (qdf_is_macaddr_zero(mac_addr)) { 1442 hdd_err("MAC is all zero (via %s)", func); 1443 return QDF_STATUS_E_INVAL; 1444 } 1445 1446 if (qdf_is_macaddr_broadcast(mac_addr)) { 1447 hdd_err("MAC is Broadcast (via %s)", func); 1448 return QDF_STATUS_E_INVAL; 1449 } 1450 1451 if (QDF_NET_IS_MAC_MULTICAST(mac_addr->bytes)) { 1452 hdd_err("MAC is Multicast (via %s)", func); 1453 return QDF_STATUS_E_INVAL; 1454 } 1455 1456 return QDF_STATUS_SUCCESS; 1457 } 1458 1459 /** 1460 * wlan_hdd_validate_modules_state() - Check modules status 1461 * @hdd_ctx: HDD context pointer 1462 * 1463 * Check's the driver module's state and returns true if the 1464 * modules are enabled returns false if modules are closed. 1465 * 1466 * Return: True if modules are enabled or false. 1467 */ 1468 bool wlan_hdd_validate_modules_state(struct hdd_context *hdd_ctx) 1469 { 1470 if (hdd_ctx->driver_status != DRIVER_MODULES_ENABLED) { 1471 hdd_info("Modules not enabled, Present status: %d", 1472 hdd_ctx->driver_status); 1473 return false; 1474 } 1475 1476 return true; 1477 } 1478 1479 #ifdef FEATURE_RUNTIME_PM 1480 /** 1481 * hdd_runtime_suspend_context_init() - API to initialize HDD Runtime Contexts 1482 * @hdd_ctx: HDD context 1483 * 1484 * Return: None 1485 */ 1486 static void hdd_runtime_suspend_context_init(struct hdd_context *hdd_ctx) 1487 { 1488 struct hdd_runtime_pm_context *ctx = &hdd_ctx->runtime_context; 1489 1490 qdf_runtime_lock_init(&ctx->dfs); 1491 qdf_runtime_lock_init(&ctx->connect); 1492 qdf_runtime_lock_init(&ctx->user); 1493 qdf_runtime_lock_init(&ctx->monitor_mode); 1494 qdf_runtime_lock_init(&ctx->wow_unit_test); 1495 qdf_runtime_lock_init(&ctx->system_suspend); 1496 qdf_runtime_lock_init(&ctx->dyn_mac_addr_update); 1497 qdf_runtime_lock_init(&ctx->vdev_destroy); 1498 qdf_runtime_lock_init(&ctx->oem_data_cmd); 1499 1500 qdf_rtpm_register(QDF_RTPM_ID_WIPHY_SUSPEND, NULL); 1501 qdf_rtpm_register(QDF_RTPM_ID_PM_QOS_NOTIFY, NULL); 1502 1503 ctx->is_user_wakelock_acquired = false; 1504 1505 wlan_scan_runtime_pm_init(hdd_ctx->pdev); 1506 } 1507 1508 /** 1509 * hdd_runtime_suspend_context_deinit() - API to deinit HDD runtime context 1510 * @hdd_ctx: HDD Context 1511 * 1512 * Return: None 1513 */ 1514 static void hdd_runtime_suspend_context_deinit(struct hdd_context *hdd_ctx) 1515 { 1516 struct hdd_runtime_pm_context *ctx = &hdd_ctx->runtime_context; 1517 1518 if (ctx->is_user_wakelock_acquired) 1519 qdf_runtime_pm_allow_suspend(&ctx->user); 1520 1521 qdf_runtime_lock_deinit(&ctx->oem_data_cmd); 1522 qdf_runtime_lock_deinit(&ctx->dyn_mac_addr_update); 1523 qdf_runtime_lock_deinit(&ctx->wow_unit_test); 1524 qdf_runtime_lock_deinit(&ctx->monitor_mode); 1525 qdf_runtime_lock_deinit(&ctx->user); 1526 qdf_runtime_lock_deinit(&ctx->connect); 1527 qdf_runtime_lock_deinit(&ctx->dfs); 1528 qdf_runtime_lock_deinit(&ctx->system_suspend); 1529 qdf_runtime_lock_deinit(&ctx->vdev_destroy); 1530 1531 qdf_rtpm_deregister(QDF_RTPM_ID_WIPHY_SUSPEND); 1532 qdf_rtpm_deregister(QDF_RTPM_ID_PM_QOS_NOTIFY); 1533 1534 wlan_scan_runtime_pm_deinit(hdd_ctx->pdev); 1535 } 1536 1537 #else /* FEATURE_RUNTIME_PM */ 1538 static void hdd_runtime_suspend_context_init(struct hdd_context *hdd_ctx) {} 1539 static void hdd_runtime_suspend_context_deinit(struct hdd_context *hdd_ctx) {} 1540 #endif /* FEATURE_RUNTIME_PM */ 1541 1542 void hdd_update_macaddr(struct hdd_context *hdd_ctx, 1543 struct qdf_mac_addr hw_macaddr, bool generate_mac_auto) 1544 { 1545 int8_t i; 1546 uint8_t macaddr_b3, tmp_br3; 1547 1548 /* 1549 * If "generate_mac_auto" is true, it indicates that all the 1550 * addresses are derived addresses, else the first addresses 1551 * is not derived address (It is provided by fw). 1552 */ 1553 if (!generate_mac_auto) { 1554 qdf_mem_copy(hdd_ctx->provisioned_mac_addr[0].bytes, 1555 hw_macaddr.bytes, QDF_MAC_ADDR_SIZE); 1556 hdd_ctx->num_provisioned_addr++; 1557 hdd_debug("hdd_ctx->provisioned_mac_addr[0]: " 1558 QDF_MAC_ADDR_FMT, 1559 QDF_MAC_ADDR_REF(hdd_ctx-> 1560 provisioned_mac_addr[0].bytes)); 1561 } else { 1562 qdf_mem_copy(hdd_ctx->derived_mac_addr[0].bytes, 1563 hw_macaddr.bytes, 1564 QDF_MAC_ADDR_SIZE); 1565 hdd_ctx->num_derived_addr++; 1566 hdd_debug("hdd_ctx->derived_mac_addr[0]: " 1567 QDF_MAC_ADDR_FMT, 1568 QDF_MAC_ADDR_REF(hdd_ctx->derived_mac_addr[0].bytes)); 1569 } 1570 for (i = hdd_ctx->num_derived_addr; i < (QDF_MAX_CONCURRENCY_PERSONA - 1571 hdd_ctx->num_provisioned_addr); 1572 i++) { 1573 qdf_mem_copy(hdd_ctx->derived_mac_addr[i].bytes, 1574 hw_macaddr.bytes, 1575 QDF_MAC_ADDR_SIZE); 1576 macaddr_b3 = hdd_ctx->derived_mac_addr[i].bytes[3]; 1577 tmp_br3 = ((macaddr_b3 >> 4 & INTF_MACADDR_MASK) + i) & 1578 INTF_MACADDR_MASK; 1579 macaddr_b3 += tmp_br3; 1580 1581 /* XOR-ing bit-24 of the mac address. This will give enough 1582 * mac address range before collision 1583 */ 1584 macaddr_b3 ^= (1 << 7); 1585 1586 /* Set locally administered bit */ 1587 hdd_ctx->derived_mac_addr[i].bytes[0] |= 0x02; 1588 hdd_ctx->derived_mac_addr[i].bytes[3] = macaddr_b3; 1589 hdd_debug("hdd_ctx->derived_mac_addr[%d]: " 1590 QDF_MAC_ADDR_FMT, i, 1591 QDF_MAC_ADDR_REF(hdd_ctx->derived_mac_addr[i].bytes)); 1592 hdd_ctx->num_derived_addr++; 1593 } 1594 } 1595 1596 #ifdef FEATURE_WLAN_TDLS 1597 static int hdd_update_tdls_config(struct hdd_context *hdd_ctx) 1598 { 1599 struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc; 1600 struct tdls_start_params tdls_cfg; 1601 QDF_STATUS status; 1602 struct wlan_mlme_nss_chains vdev_ini_cfg; 1603 1604 /* Populate the nss chain params from ini for this vdev type */ 1605 sme_populate_nss_chain_params(hdd_ctx->mac_handle, &vdev_ini_cfg, 1606 QDF_TDLS_MODE, 1607 hdd_ctx->num_rf_chains); 1608 1609 cfg_tdls_set_vdev_nss_2g(hdd_ctx->psoc, 1610 vdev_ini_cfg.rx_nss[NSS_CHAINS_BAND_2GHZ]); 1611 cfg_tdls_set_vdev_nss_5g(hdd_ctx->psoc, 1612 vdev_ini_cfg.rx_nss[NSS_CHAINS_BAND_5GHZ]); 1613 hdd_init_tdls_config(&tdls_cfg); 1614 tdls_cfg.tdls_del_all_peers = eWNI_SME_DEL_ALL_TDLS_PEERS; 1615 tdls_cfg.tdls_update_dp_vdev_flags = CDP_UPDATE_TDLS_FLAGS; 1616 tdls_cfg.tdls_event_cb = wlan_cfg80211_tdls_event_callback; 1617 tdls_cfg.tdls_evt_cb_data = psoc; 1618 tdls_cfg.tdls_peer_context = hdd_ctx; 1619 tdls_cfg.tdls_reg_peer = hdd_tdls_register_peer; 1620 tdls_cfg.tdls_wmm_cb = hdd_wmm_is_acm_allowed; 1621 tdls_cfg.tdls_wmm_cb_data = psoc; 1622 tdls_cfg.tdls_rx_cb = wlan_cfg80211_tdls_rx_callback; 1623 tdls_cfg.tdls_rx_cb_data = psoc; 1624 tdls_cfg.tdls_dp_vdev_update = hdd_update_dp_vdev_flags; 1625 tdls_cfg.tdls_osif_init_cb = wlan_cfg80211_tdls_osif_priv_init; 1626 tdls_cfg.tdls_osif_deinit_cb = wlan_cfg80211_tdls_osif_priv_deinit; 1627 tdls_cfg.tdls_osif_update_cb.tdls_osif_conn_update = 1628 hdd_check_and_set_tdls_conn_params; 1629 tdls_cfg.tdls_osif_update_cb.tdls_osif_disconn_update = 1630 hdd_check_and_set_tdls_disconn_params; 1631 1632 status = ucfg_tdls_update_config(psoc, &tdls_cfg); 1633 if (status != QDF_STATUS_SUCCESS) { 1634 hdd_err("failed pmo psoc configuration"); 1635 return -EINVAL; 1636 } 1637 1638 hdd_ctx->tdls_umac_comp_active = true; 1639 /* enable napier specific tdls data path */ 1640 hdd_ctx->tdls_nap_active = true; 1641 1642 return 0; 1643 } 1644 #else 1645 static int hdd_update_tdls_config(struct hdd_context *hdd_ctx) 1646 { 1647 return 0; 1648 } 1649 #endif 1650 1651 void hdd_indicate_active_ndp_cnt(struct wlan_objmgr_psoc *psoc, 1652 uint8_t vdev_id, uint8_t cnt) 1653 { 1654 struct wlan_hdd_link_info *link_info; 1655 1656 link_info = wlan_hdd_get_link_info_from_vdev(psoc, vdev_id); 1657 if (!link_info || !cfg_nan_is_roam_config_disabled(psoc)) 1658 return; 1659 1660 hdd_debug("vdev_id:%d%s active ndp sessions present", vdev_id, 1661 cnt ? "" : " no more"); 1662 if (!cnt) 1663 wlan_hdd_set_roaming_state(link_info, RSO_NDP_CON_ON_NDI, true); 1664 else 1665 wlan_hdd_set_roaming_state(link_info, RSO_NDP_CON_ON_NDI, 1666 false); 1667 } 1668 1669 #ifdef WLAN_FEATURE_ROAM_OFFLOAD 1670 static void hdd_update_roam_offload(struct hdd_context *hdd_ctx, 1671 struct wma_tgt_services *cfg) 1672 { 1673 bool roam_offload_enable; 1674 1675 ucfg_mlme_get_roaming_offload(hdd_ctx->psoc, &roam_offload_enable); 1676 ucfg_mlme_set_roaming_offload(hdd_ctx->psoc, 1677 roam_offload_enable & 1678 cfg->en_roam_offload); 1679 } 1680 #else 1681 static inline void hdd_update_roam_offload(struct hdd_context *hdd_ctx, 1682 struct wma_tgt_services *cfg) 1683 { 1684 } 1685 #endif 1686 1687 #ifdef FEATURE_CLUB_LL_STATS_AND_GET_STATION 1688 static void 1689 hdd_club_ll_stats_in_get_sta_cfg_update(struct hdd_config *config, 1690 struct wlan_objmgr_psoc *psoc) 1691 { 1692 config->sta_stats_cache_expiry_time = 1693 cfg_get(psoc, CFG_STA_STATS_CACHE_EXPIRY); 1694 } 1695 1696 static void 1697 hdd_update_feature_cfg_club_get_sta_in_ll_stats_req( 1698 struct hdd_context *hdd_ctx, 1699 struct wma_tgt_services *cfg) 1700 { 1701 hdd_ctx->is_get_station_clubbed_in_ll_stats_req = 1702 cfg->is_get_station_clubbed_in_ll_stats_req && 1703 cfg_get(hdd_ctx->psoc, 1704 CFG_CLUB_LL_STA_AND_GET_STATION); 1705 } 1706 1707 static void 1708 hdd_init_get_sta_in_ll_stats_config(struct hdd_adapter *adapter) 1709 { 1710 adapter->sta_stats_cached_timestamp = 0; 1711 } 1712 #else 1713 static void 1714 hdd_club_ll_stats_in_get_sta_cfg_update(struct hdd_config *config, 1715 struct wlan_objmgr_psoc *psoc) 1716 { 1717 } 1718 1719 static void 1720 hdd_update_feature_cfg_club_get_sta_in_ll_stats_req( 1721 struct hdd_context *hdd_ctx, 1722 struct wma_tgt_services *cfg) 1723 { 1724 } 1725 1726 static void 1727 hdd_init_get_sta_in_ll_stats_config(struct hdd_adapter *adapter) 1728 { 1729 } 1730 #endif /* FEATURE_CLUB_LL_STATS_AND_GET_STATION */ 1731 1732 #ifdef WLAN_FEATURE_11BE_MLO 1733 1734 static void 1735 hdd_init_link_state_cfg(struct hdd_config *config, 1736 struct wlan_objmgr_psoc *psoc) 1737 { 1738 config->link_state_cache_expiry_time = 1739 cfg_get(psoc, CFG_LINK_STATE_CACHE_EXPIRY); 1740 } 1741 1742 static void 1743 hdd_init_link_state_config(struct hdd_adapter *adapter) 1744 { 1745 adapter->link_state_cached_timestamp = 0; 1746 } 1747 1748 #else 1749 static void 1750 hdd_init_link_state_cfg(struct hdd_config *config, 1751 struct wlan_objmgr_psoc *psoc) 1752 { 1753 } 1754 1755 static void 1756 hdd_init_link_state_config(struct hdd_adapter *adapter) 1757 { 1758 } 1759 #endif /* WLAN_FEATURE_11BE_MLO */ 1760 1761 #ifdef WLAN_FEATURE_IGMP_OFFLOAD 1762 static void 1763 hdd_intersect_igmp_offload_setting(struct wlan_objmgr_psoc *psoc, 1764 struct wma_tgt_services *cfg) 1765 { 1766 bool igmp_offload_enable; 1767 1768 igmp_offload_enable = 1769 ucfg_pmo_is_igmp_offload_enabled(psoc); 1770 ucfg_pmo_set_igmp_offload_enabled(psoc, 1771 igmp_offload_enable & 1772 cfg->igmp_offload_enable); 1773 hdd_info("fw cap to handle igmp %d igmp_offload_enable ini %d", 1774 cfg->igmp_offload_enable, igmp_offload_enable); 1775 } 1776 #else 1777 static inline void 1778 hdd_intersect_igmp_offload_setting(struct wlan_objmgr_psoc *psoc, 1779 struct wma_tgt_services *cfg) 1780 {} 1781 #endif 1782 1783 #ifdef FEATURE_WLAN_TDLS 1784 static void hdd_update_fw_tdls_wideband_capability(struct hdd_context *hdd_ctx, 1785 struct wma_tgt_services *cfg) 1786 { 1787 ucfg_tdls_update_fw_wideband_capability(hdd_ctx->psoc, 1788 cfg->en_tdls_wideband_support); 1789 } 1790 1791 #ifdef WLAN_FEATURE_11BE 1792 static void hdd_update_fw_tdls_mlo_capability(struct hdd_context *hdd_ctx, 1793 struct wma_tgt_services *cfg) 1794 { 1795 ucfg_tdls_update_fw_mlo_capability(hdd_ctx->psoc, 1796 cfg->en_tdls_mlo_support); 1797 } 1798 #else 1799 static inline 1800 void hdd_update_fw_tdls_mlo_capability(struct hdd_context *hdd_ctx, 1801 struct wma_tgt_services *cfg) 1802 {} 1803 #endif 1804 1805 #ifdef WLAN_FEATURE_11AX 1806 static void hdd_update_fw_tdls_11ax_capability(struct hdd_context *hdd_ctx, 1807 struct wma_tgt_services *cfg) 1808 { 1809 ucfg_tdls_update_fw_11ax_capability(hdd_ctx->psoc, 1810 cfg->en_tdls_11ax_support); 1811 } 1812 1813 static void hdd_update_fw_tdls_6g_capability(struct hdd_context *hdd_ctx, 1814 struct wma_tgt_services *cfg) 1815 { 1816 ucfg_update_fw_tdls_6g_capability(hdd_ctx->psoc, 1817 cfg->en_tdls_6g_support); 1818 } 1819 1820 #else 1821 static inline 1822 void hdd_update_fw_tdls_11ax_capability(struct hdd_context *hdd_ctx, 1823 struct wma_tgt_services *cfg) 1824 {} 1825 static inline 1826 void hdd_update_fw_tdls_6g_capability(struct hdd_context *hdd_ctx, 1827 struct wma_tgt_services *cfg) 1828 {} 1829 #endif 1830 #else 1831 static inline 1832 void hdd_update_fw_tdls_mlo_capability(struct hdd_context *hdd_ctx, 1833 struct wma_tgt_services *cfg) 1834 {} 1835 1836 static inline 1837 void hdd_update_fw_tdls_11ax_capability(struct hdd_context *hdd_ctx, 1838 struct wma_tgt_services *cfg) 1839 {} 1840 1841 static inline 1842 void hdd_update_fw_tdls_6g_capability(struct hdd_context *hdd_ctx, 1843 struct wma_tgt_services *cfg) 1844 {} 1845 1846 static inline 1847 void hdd_update_fw_tdls_wideband_capability(struct hdd_context *hdd_ctx, 1848 struct wma_tgt_services *cfg) 1849 {} 1850 #endif 1851 1852 #ifdef WLAN_FEATURE_DYNAMIC_MAC_ADDR_UPDATE 1853 static inline void 1854 hdd_set_dynamic_macaddr_update_capability(struct hdd_context *hdd_ctx, 1855 struct wma_tgt_services *cfg) 1856 { 1857 hdd_ctx->is_vdev_macaddr_dynamic_update_supported = 1858 cfg->dynamic_vdev_macaddr_support && 1859 cfg_get(hdd_ctx->psoc, 1860 CFG_DYNAMIC_MAC_ADDR_UPDATE_SUPPORTED); 1861 } 1862 #else 1863 static inline void 1864 hdd_set_dynamic_macaddr_update_capability(struct hdd_context *hdd_ctx, 1865 struct wma_tgt_services *cfg) 1866 { 1867 } 1868 #endif 1869 1870 #ifdef WLAN_FEATURE_11BE 1871 static bool hdd_dot11Mode_support_11be(enum hdd_dot11_mode dot11Mode) 1872 { 1873 if (dot11Mode != eHDD_DOT11_MODE_AUTO && 1874 dot11Mode < eHDD_DOT11_MODE_11be) 1875 return false; 1876 1877 return true; 1878 } 1879 1880 static void 1881 hdd_update_tid_to_link_supported(struct hdd_context *hdd_ctx, 1882 struct wma_tgt_services *cfg) 1883 { 1884 if (!cfg->en_mlo_tid_to_link_support) 1885 ucfg_mlme_set_t2lm_negotiation_supported(hdd_ctx->psoc, 1886 T2LM_NEGOTIATION_DISABLED); 1887 } 1888 1889 #else 1890 static bool hdd_dot11Mode_support_11be(enum hdd_dot11_mode dot11Mode) 1891 { 1892 return false; 1893 } 1894 1895 static inline void 1896 hdd_update_tid_to_link_supported(struct hdd_context *hdd_ctx, 1897 struct wma_tgt_services *cfg) 1898 { 1899 } 1900 #endif 1901 1902 #ifdef WLAN_FEATURE_11BE_MLO 1903 static void 1904 hdd_update_mlo_per_link_stats_capability(struct hdd_context *hdd_ctx, 1905 struct wma_tgt_services *cfg) 1906 { 1907 hdd_ctx->is_mlo_per_link_stats_supported = 1908 cfg->is_mlo_per_link_stats_supported; 1909 } 1910 #else 1911 static void 1912 hdd_update_mlo_per_link_stats_capability(struct hdd_context *hdd_ctx, 1913 struct wma_tgt_services *cfg) 1914 { 1915 } 1916 #endif 1917 1918 static void hdd_update_tgt_services(struct hdd_context *hdd_ctx, 1919 struct wma_tgt_services *cfg) 1920 { 1921 struct hdd_config *config = hdd_ctx->config; 1922 bool arp_offload_enable; 1923 bool mawc_enabled; 1924 #ifdef FEATURE_WLAN_TDLS 1925 bool tdls_support; 1926 bool tdls_off_channel; 1927 bool tdls_buffer_sta; 1928 uint32_t tdls_uapsd_mask; 1929 #endif 1930 bool get_peer_info_enable; 1931 1932 /* Set up UAPSD */ 1933 ucfg_mlme_set_sap_uapsd_flag(hdd_ctx->psoc, cfg->uapsd); 1934 1935 /* 11AX mode support */ 1936 if ((config->dot11Mode == eHDD_DOT11_MODE_11ax || 1937 config->dot11Mode == eHDD_DOT11_MODE_11ax_ONLY) && !cfg->en_11ax) 1938 config->dot11Mode = eHDD_DOT11_MODE_11ac; 1939 1940 /* 11AC mode support */ 1941 if ((config->dot11Mode == eHDD_DOT11_MODE_11ac || 1942 config->dot11Mode == eHDD_DOT11_MODE_11ac_ONLY) && !cfg->en_11ac) 1943 config->dot11Mode = eHDD_DOT11_MODE_AUTO; 1944 1945 /* 11BE mode support */ 1946 if (cfg->en_11be && 1947 (!hdd_dot11Mode_support_11be(config->dot11Mode) || 1948 !wlan_reg_phybitmap_support_11be(hdd_ctx->pdev))) { 1949 hdd_debug("dot11Mode %d override target en_11be to false", 1950 config->dot11Mode); 1951 cfg->en_11be = false; 1952 } 1953 1954 /* ARP offload: override user setting if invalid */ 1955 arp_offload_enable = 1956 ucfg_pmo_is_arp_offload_enabled(hdd_ctx->psoc); 1957 ucfg_pmo_set_arp_offload_enabled(hdd_ctx->psoc, 1958 arp_offload_enable & cfg->arp_offload); 1959 1960 /* Intersect igmp offload ini configuration and fw cap*/ 1961 hdd_intersect_igmp_offload_setting(hdd_ctx->psoc, cfg); 1962 1963 #ifdef FEATURE_WLAN_SCAN_PNO 1964 /* PNO offload */ 1965 hdd_debug("PNO Capability in f/w = %d", cfg->pno_offload); 1966 if (cfg->pno_offload) 1967 ucfg_scan_set_pno_offload(hdd_ctx->psoc, true); 1968 #endif 1969 #ifdef FEATURE_WLAN_TDLS 1970 cfg_tdls_get_support_enable(hdd_ctx->psoc, &tdls_support); 1971 cfg_tdls_set_support_enable(hdd_ctx->psoc, 1972 tdls_support & cfg->en_tdls); 1973 1974 cfg_tdls_get_off_channel_enable(hdd_ctx->psoc, &tdls_off_channel); 1975 cfg_tdls_set_off_channel_enable(hdd_ctx->psoc, 1976 tdls_off_channel && 1977 cfg->en_tdls_offchan); 1978 1979 cfg_tdls_get_buffer_sta_enable(hdd_ctx->psoc, &tdls_buffer_sta); 1980 cfg_tdls_set_buffer_sta_enable(hdd_ctx->psoc, 1981 tdls_buffer_sta && 1982 cfg->en_tdls_uapsd_buf_sta); 1983 1984 cfg_tdls_get_uapsd_mask(hdd_ctx->psoc, &tdls_uapsd_mask); 1985 if (tdls_uapsd_mask && cfg->en_tdls_uapsd_sleep_sta) 1986 cfg_tdls_set_sleep_sta_enable(hdd_ctx->psoc, true); 1987 else 1988 cfg_tdls_set_sleep_sta_enable(hdd_ctx->psoc, false); 1989 #endif 1990 hdd_update_roam_offload(hdd_ctx, cfg); 1991 1992 if (ucfg_mlme_get_sap_get_peer_info( 1993 hdd_ctx->psoc, &get_peer_info_enable) == QDF_STATUS_SUCCESS) { 1994 get_peer_info_enable &= cfg->get_peer_info_enabled; 1995 ucfg_mlme_set_sap_get_peer_info(hdd_ctx->psoc, 1996 get_peer_info_enable); 1997 } 1998 1999 ucfg_mlme_is_mawc_enabled(hdd_ctx->psoc, &mawc_enabled); 2000 ucfg_mlme_set_mawc_enabled(hdd_ctx->psoc, 2001 mawc_enabled & cfg->is_fw_mawc_capable); 2002 hdd_update_tdls_config(hdd_ctx); 2003 sme_update_tgt_services(hdd_ctx->mac_handle, cfg); 2004 hdd_ctx->roam_ch_from_fw_supported = cfg->is_roam_scan_ch_to_host; 2005 hdd_ctx->ll_stats_per_chan_rx_tx_time = 2006 cfg->ll_stats_per_chan_rx_tx_time; 2007 2008 hdd_update_feature_cfg_club_get_sta_in_ll_stats_req(hdd_ctx, cfg); 2009 hdd_ctx->is_therm_cmd_supp = 2010 cfg->is_fw_therm_throt_supp && 2011 cfg_get(hdd_ctx->psoc, 2012 CFG_THERMAL_MITIGATION_ENABLE); 2013 hdd_update_fw_tdls_11ax_capability(hdd_ctx, cfg); 2014 hdd_update_fw_tdls_mlo_capability(hdd_ctx, cfg); 2015 hdd_set_dynamic_macaddr_update_capability(hdd_ctx, cfg); 2016 hdd_update_fw_tdls_6g_capability(hdd_ctx, cfg); 2017 hdd_update_fw_tdls_wideband_capability(hdd_ctx, cfg); 2018 ucfg_psoc_mlme_set_11be_capab(hdd_ctx->psoc, cfg->en_11be); 2019 hdd_update_mlo_per_link_stats_capability(hdd_ctx, cfg); 2020 } 2021 2022 /** 2023 * hdd_update_vdev_nss() - sets the vdev nss 2024 * @hdd_ctx: HDD context 2025 * 2026 * Sets the Nss per vdev type based on INI 2027 * 2028 * Return: None 2029 */ 2030 static void hdd_update_vdev_nss(struct hdd_context *hdd_ctx) 2031 { 2032 uint8_t max_supp_nss = 1; 2033 mac_handle_t mac_handle; 2034 QDF_STATUS status; 2035 bool bval; 2036 2037 status = ucfg_mlme_get_vht_enable2x2(hdd_ctx->psoc, &bval); 2038 if (!QDF_IS_STATUS_SUCCESS(status)) 2039 hdd_err("unable to get vht_enable2x2"); 2040 2041 if (bval && !cds_is_sub_20_mhz_enabled()) 2042 max_supp_nss = 2; 2043 2044 hdd_debug("max nss %d", max_supp_nss); 2045 2046 mac_handle = hdd_ctx->mac_handle; 2047 sme_update_vdev_type_nss(mac_handle, max_supp_nss, 2048 NSS_CHAINS_BAND_2GHZ); 2049 2050 sme_update_vdev_type_nss(mac_handle, max_supp_nss, 2051 NSS_CHAINS_BAND_5GHZ); 2052 } 2053 2054 /** 2055 * hdd_update_2g_wiphy_vhtcap() - Updates 2G wiphy vhtcap fields 2056 * @hdd_ctx: HDD context 2057 * 2058 * Updates 2G wiphy vhtcap fields 2059 * 2060 * Return: None 2061 */ 2062 static void hdd_update_2g_wiphy_vhtcap(struct hdd_context *hdd_ctx) 2063 { 2064 struct ieee80211_supported_band *band_2g = 2065 hdd_ctx->wiphy->bands[NL80211_BAND_2GHZ]; 2066 uint32_t value; 2067 bool is_vht_24ghz; 2068 2069 if (!band_2g) { 2070 hdd_debug("2GHz band disabled, skipping capability population"); 2071 return; 2072 } 2073 2074 ucfg_mlme_get_vht_for_24ghz(hdd_ctx->psoc, &is_vht_24ghz); 2075 2076 if (is_vht_24ghz) { 2077 ucfg_mlme_cfg_get_vht_tx_mcs_map(hdd_ctx->psoc, &value); 2078 band_2g->vht_cap.vht_mcs.tx_mcs_map = value; 2079 } 2080 } 2081 2082 /** 2083 * hdd_update_5g_wiphy_vhtcap() - Updates 5G wiphy vhtcap fields 2084 * @hdd_ctx: HDD context 2085 * 2086 * Updates 5G wiphy vhtcap fields 2087 * 2088 * Return: None 2089 */ 2090 static void hdd_update_5g_wiphy_vhtcap(struct hdd_context *hdd_ctx) 2091 { 2092 struct ieee80211_supported_band *band_5g = 2093 hdd_ctx->wiphy->bands[NL80211_BAND_5GHZ]; 2094 QDF_STATUS status; 2095 uint8_t value = 0, value1 = 0; 2096 uint32_t value2; 2097 2098 if (!band_5g) { 2099 hdd_debug("5GHz band disabled, skipping capability population"); 2100 return; 2101 } 2102 2103 status = ucfg_mlme_cfg_get_vht_tx_bfee_ant_supp(hdd_ctx->psoc, 2104 &value); 2105 if (!QDF_IS_STATUS_SUCCESS(status)) 2106 hdd_err("unable to get tx_bfee_ant_supp"); 2107 2108 band_5g->vht_cap.cap |= 2109 (value << IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT); 2110 2111 value1 = NUM_OF_SOUNDING_DIMENSIONS; 2112 band_5g->vht_cap.cap |= 2113 (value1 << IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_SHIFT); 2114 2115 hdd_debug("Updated wiphy vhtcap:0x%x, CSNAntSupp:%d, NumSoundDim:%d", 2116 band_5g->vht_cap.cap, value, value1); 2117 2118 ucfg_mlme_cfg_get_vht_rx_mcs_map(hdd_ctx->psoc, &value2); 2119 band_5g->vht_cap.vht_mcs.rx_mcs_map = value2; 2120 2121 ucfg_mlme_cfg_get_vht_tx_mcs_map(hdd_ctx->psoc, &value2); 2122 band_5g->vht_cap.vht_mcs.tx_mcs_map = value2; 2123 } 2124 2125 /** 2126 * hdd_update_wiphy_vhtcap() - Updates wiphy vhtcap fields 2127 * @hdd_ctx: HDD context 2128 * 2129 * Updates wiphy vhtcap fields 2130 * 2131 * Return: None 2132 */ 2133 static void hdd_update_wiphy_vhtcap(struct hdd_context *hdd_ctx) 2134 { 2135 hdd_update_2g_wiphy_vhtcap(hdd_ctx); 2136 hdd_update_5g_wiphy_vhtcap(hdd_ctx); 2137 } 2138 2139 static void hdd_update_tgt_ht_cap(struct hdd_context *hdd_ctx, 2140 struct wma_tgt_ht_cap *cfg) 2141 { 2142 QDF_STATUS status; 2143 qdf_size_t value_len; 2144 uint32_t value; 2145 uint8_t mpdu_density; 2146 struct mlme_ht_capabilities_info ht_cap_info; 2147 uint8_t mcs_set[SIZE_OF_SUPPORTED_MCS_SET]; 2148 bool b_enable1x1; 2149 2150 /* get the MPDU density */ 2151 status = ucfg_mlme_get_ht_mpdu_density(hdd_ctx->psoc, &mpdu_density); 2152 if (QDF_IS_STATUS_ERROR(status)) { 2153 hdd_err("could not get HT MPDU Density"); 2154 return; 2155 } 2156 2157 /* 2158 * MPDU density: 2159 * override user's setting if value is larger 2160 * than the one supported by target, 2161 * if target value is 0, then follow user's setting. 2162 */ 2163 if (cfg->mpdu_density && mpdu_density > cfg->mpdu_density) { 2164 status = ucfg_mlme_set_ht_mpdu_density(hdd_ctx->psoc, 2165 cfg->mpdu_density); 2166 if (QDF_IS_STATUS_ERROR(status)) 2167 hdd_err("could not set HT capability to CCM"); 2168 } 2169 2170 /* get the HT capability info */ 2171 status = ucfg_mlme_get_ht_cap_info(hdd_ctx->psoc, &ht_cap_info); 2172 if (QDF_STATUS_SUCCESS != status) { 2173 hdd_err("could not get HT capability info"); 2174 return; 2175 } 2176 2177 /* check and update RX STBC */ 2178 if (ht_cap_info.rx_stbc && !cfg->ht_rx_stbc) 2179 ht_cap_info.rx_stbc = cfg->ht_rx_stbc; 2180 2181 /* Set the LDPC capability */ 2182 if (ht_cap_info.adv_coding_cap && !cfg->ht_rx_ldpc) 2183 ht_cap_info.adv_coding_cap = cfg->ht_rx_ldpc; 2184 2185 if (ht_cap_info.short_gi_20_mhz && !cfg->ht_sgi_20) 2186 ht_cap_info.short_gi_20_mhz = cfg->ht_sgi_20; 2187 2188 if (ht_cap_info.short_gi_40_mhz && !cfg->ht_sgi_40) 2189 ht_cap_info.short_gi_40_mhz = cfg->ht_sgi_40; 2190 2191 hdd_debug("gHtSMPS ini: %d, dynamic_smps fw cap: %d", 2192 ht_cap_info.mimo_power_save, cfg->dynamic_smps); 2193 if (ht_cap_info.mimo_power_save == HDD_SMPS_MODE_DYNAMIC) { 2194 if (cfg->dynamic_smps) 2195 ht_cap_info.mimo_power_save = HDD_SMPS_MODE_DYNAMIC; 2196 else 2197 ht_cap_info.mimo_power_save = HDD_SMPS_MODE_DISABLED; 2198 } 2199 2200 hdd_ctx->num_rf_chains = cfg->num_rf_chains; 2201 hdd_ctx->ht_tx_stbc_supported = cfg->ht_tx_stbc; 2202 2203 status = ucfg_mlme_get_vht_enable2x2(hdd_ctx->psoc, &b_enable1x1); 2204 if (!QDF_IS_STATUS_SUCCESS(status)) 2205 hdd_err("unable to get vht_enable2x2"); 2206 2207 b_enable1x1 = b_enable1x1 && (cfg->num_rf_chains == 2); 2208 2209 status = ucfg_mlme_set_vht_enable2x2(hdd_ctx->psoc, b_enable1x1); 2210 if (!QDF_IS_STATUS_SUCCESS(status)) 2211 hdd_err("unable to set vht_enable2x2"); 2212 2213 if (!b_enable1x1) 2214 ht_cap_info.tx_stbc = 0; 2215 2216 if (!(cfg->ht_tx_stbc && b_enable1x1)) 2217 ht_cap_info.tx_stbc = 0; 2218 2219 status = ucfg_mlme_set_ht_cap_info(hdd_ctx->psoc, ht_cap_info); 2220 if (status != QDF_STATUS_SUCCESS) 2221 hdd_err("could not set HT capability to CCM"); 2222 #define WLAN_HDD_RX_MCS_ALL_NSTREAM_RATES 0xff 2223 value_len = SIZE_OF_SUPPORTED_MCS_SET; 2224 if (ucfg_mlme_get_supported_mcs_set( 2225 hdd_ctx->psoc, mcs_set, 2226 &value_len) == QDF_STATUS_SUCCESS) { 2227 hdd_debug("Read MCS rate set"); 2228 if (cfg->num_rf_chains > SIZE_OF_SUPPORTED_MCS_SET) 2229 cfg->num_rf_chains = SIZE_OF_SUPPORTED_MCS_SET; 2230 2231 if (b_enable1x1) { 2232 for (value = 0; value < cfg->num_rf_chains; value++) 2233 mcs_set[value] = 2234 WLAN_HDD_RX_MCS_ALL_NSTREAM_RATES; 2235 2236 status = ucfg_mlme_set_supported_mcs_set( 2237 hdd_ctx->psoc, 2238 mcs_set, 2239 (qdf_size_t)SIZE_OF_SUPPORTED_MCS_SET); 2240 if (QDF_IS_STATUS_ERROR(status)) 2241 hdd_err("could not set MCS SET to CCM"); 2242 } 2243 } 2244 #undef WLAN_HDD_RX_MCS_ALL_NSTREAM_RATES 2245 } 2246 2247 static void hdd_update_tgt_vht_cap(struct hdd_context *hdd_ctx, 2248 struct wma_tgt_vht_cap *cfg) 2249 { 2250 QDF_STATUS status; 2251 struct wiphy *wiphy = hdd_ctx->wiphy; 2252 struct ieee80211_supported_band *band_5g = 2253 wiphy->bands[HDD_NL80211_BAND_5GHZ]; 2254 uint32_t ch_width; 2255 struct wma_caps_per_phy caps_per_phy = {0}; 2256 bool vht_enable_2x2; 2257 uint32_t tx_highest_data_rate; 2258 uint32_t rx_highest_data_rate; 2259 2260 if (!band_5g) { 2261 hdd_debug("5GHz band disabled, skipping capability population"); 2262 return; 2263 } 2264 2265 status = ucfg_mlme_update_vht_cap(hdd_ctx->psoc, cfg); 2266 if (QDF_IS_STATUS_ERROR(status)) 2267 hdd_err("could not update vht capabilities"); 2268 2269 status = ucfg_mlme_get_vht_enable2x2(hdd_ctx->psoc, &vht_enable_2x2); 2270 if (!QDF_IS_STATUS_SUCCESS(status)) 2271 hdd_err("unable to get vht_enable2x2"); 2272 2273 if (vht_enable_2x2) { 2274 tx_highest_data_rate = 2275 VHT_TX_HIGHEST_SUPPORTED_DATA_RATE_2_2; 2276 rx_highest_data_rate = 2277 VHT_RX_HIGHEST_SUPPORTED_DATA_RATE_2_2; 2278 } else { 2279 tx_highest_data_rate = 2280 VHT_TX_HIGHEST_SUPPORTED_DATA_RATE_1_1; 2281 rx_highest_data_rate = 2282 VHT_RX_HIGHEST_SUPPORTED_DATA_RATE_1_1; 2283 } 2284 2285 status = ucfg_mlme_cfg_set_vht_rx_supp_data_rate(hdd_ctx->psoc, 2286 rx_highest_data_rate); 2287 if (!QDF_IS_STATUS_SUCCESS(status)) 2288 hdd_err("Failed to set rx_supp_data_rate"); 2289 2290 status = ucfg_mlme_cfg_set_vht_tx_supp_data_rate(hdd_ctx->psoc, 2291 tx_highest_data_rate); 2292 if (!QDF_IS_STATUS_SUCCESS(status)) 2293 hdd_err("Failed to set tx_supp_data_rate"); 2294 2295 /* Update the real highest data rate to wiphy */ 2296 if (cfg->vht_short_gi_80 & WMI_VHT_CAP_SGI_80MHZ) { 2297 if (vht_enable_2x2) { 2298 tx_highest_data_rate = 2299 VHT_TX_HIGHEST_SUPPORTED_DATA_RATE_2_2_SGI80; 2300 rx_highest_data_rate = 2301 VHT_RX_HIGHEST_SUPPORTED_DATA_RATE_2_2_SGI80; 2302 } else { 2303 tx_highest_data_rate = 2304 VHT_TX_HIGHEST_SUPPORTED_DATA_RATE_1_1_SGI80; 2305 rx_highest_data_rate = 2306 VHT_RX_HIGHEST_SUPPORTED_DATA_RATE_1_1_SGI80; 2307 } 2308 } 2309 2310 if (WMI_VHT_CAP_MAX_MPDU_LEN_11454 == cfg->vht_max_mpdu) 2311 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454; 2312 else if (WMI_VHT_CAP_MAX_MPDU_LEN_7935 == cfg->vht_max_mpdu) 2313 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_7991; 2314 else 2315 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_3895; 2316 2317 2318 if (cfg->supp_chan_width & (1 << eHT_CHANNEL_WIDTH_80P80MHZ)) { 2319 band_5g->vht_cap.cap |= 2320 IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ; 2321 ch_width = VHT_CAP_160_AND_80P80_SUPP; 2322 } else if (cfg->supp_chan_width & (1 << eHT_CHANNEL_WIDTH_160MHZ)) { 2323 band_5g->vht_cap.cap |= 2324 IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ; 2325 ch_width = VHT_CAP_160_SUPP; 2326 } else { 2327 ch_width = VHT_CAP_NO_160M_SUPP; 2328 } 2329 2330 status = ucfg_mlme_set_vht_ch_width(hdd_ctx->psoc, ch_width); 2331 if (QDF_IS_STATUS_ERROR(status)) 2332 hdd_err("could not set the channel width"); 2333 else 2334 hdd_debug("supported channel width %d", ch_width); 2335 2336 if (cfg->vht_rx_ldpc & WMI_VHT_CAP_RX_LDPC) { 2337 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_RXLDPC; 2338 hdd_debug("VHT RxLDPC capability is set"); 2339 } else { 2340 /* 2341 * Get the RX LDPC capability for the NON DBS 2342 * hardware mode for 5G band 2343 */ 2344 status = wma_get_caps_for_phyidx_hwmode(&caps_per_phy, 2345 HW_MODE_DBS_NONE, CDS_BAND_5GHZ); 2346 if ((QDF_IS_STATUS_SUCCESS(status)) && 2347 (caps_per_phy.vht_5g & WMI_VHT_CAP_RX_LDPC)) { 2348 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_RXLDPC; 2349 hdd_debug("VHT RX LDPC capability is set"); 2350 } 2351 } 2352 2353 if (cfg->vht_short_gi_80 & WMI_VHT_CAP_SGI_80MHZ) 2354 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_SHORT_GI_80; 2355 if (cfg->vht_short_gi_160 & WMI_VHT_CAP_SGI_160MHZ) 2356 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_SHORT_GI_160; 2357 2358 if (vht_enable_2x2 && (cfg->vht_tx_stbc & WMI_VHT_CAP_TX_STBC)) 2359 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_TXSTBC; 2360 2361 if (cfg->vht_rx_stbc & WMI_VHT_CAP_RX_STBC_1SS) 2362 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_RXSTBC_1; 2363 if (vht_enable_2x2 && (cfg->vht_rx_stbc & WMI_VHT_CAP_RX_STBC_2SS)) 2364 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_RXSTBC_2; 2365 if (cfg->vht_rx_stbc & WMI_VHT_CAP_RX_STBC_3SS) 2366 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_RXSTBC_3; 2367 2368 band_5g->vht_cap.cap |= 2369 (cfg->vht_max_ampdu_len_exp << 2370 IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT); 2371 2372 if (cfg->vht_su_bformer & WMI_VHT_CAP_SU_BFORMER) 2373 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE; 2374 if (cfg->vht_su_bformee & WMI_VHT_CAP_SU_BFORMEE) 2375 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE; 2376 if (cfg->vht_mu_bformer & WMI_VHT_CAP_MU_BFORMER) 2377 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE; 2378 if (cfg->vht_mu_bformee & WMI_VHT_CAP_MU_BFORMEE) 2379 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE; 2380 2381 if (cfg->vht_txop_ps & WMI_VHT_CAP_TXOP_PS) 2382 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_VHT_TXOP_PS; 2383 2384 band_5g->vht_cap.vht_mcs.rx_highest = cpu_to_le16(rx_highest_data_rate); 2385 band_5g->vht_cap.vht_mcs.tx_highest = cpu_to_le16(tx_highest_data_rate); 2386 } 2387 2388 /** 2389 * hdd_generate_macaddr_auto() - Auto-generate mac address 2390 * @hdd_ctx: Pointer to the HDD context 2391 * 2392 * Auto-generate mac address using device serial number. 2393 * Keep the first 3 bytes of OUI as before and replace 2394 * the last 3 bytes with the lower 3 bytes of serial number. 2395 * 2396 * Return: 0 for success 2397 * Non zero failure code for errors 2398 */ 2399 static int hdd_generate_macaddr_auto(struct hdd_context *hdd_ctx) 2400 { 2401 unsigned int serialno = 0; 2402 struct qdf_mac_addr mac_addr = { 2403 {0x00, 0x0A, 0xF5, 0x00, 0x00, 0x00} 2404 }; 2405 2406 serialno = pld_socinfo_get_serial_number(hdd_ctx->parent_dev); 2407 if (serialno == 0) 2408 return -EINVAL; 2409 2410 serialno &= 0x00ffffff; 2411 2412 mac_addr.bytes[3] = (serialno >> 16) & 0xff; 2413 mac_addr.bytes[4] = (serialno >> 8) & 0xff; 2414 mac_addr.bytes[5] = serialno & 0xff; 2415 2416 hdd_update_macaddr(hdd_ctx, mac_addr, true); 2417 return 0; 2418 } 2419 2420 static void hdd_sar_target_config(struct hdd_context *hdd_ctx, 2421 struct wma_tgt_cfg *cfg) 2422 { 2423 hdd_ctx->sar_version = cfg->sar_version; 2424 } 2425 2426 static void hdd_update_vhtcap_2g(struct hdd_context *hdd_ctx) 2427 { 2428 uint64_t chip_mode = 0; 2429 QDF_STATUS status; 2430 bool b2g_vht_cfg = false; 2431 bool b2g_vht_target = false; 2432 struct wma_caps_per_phy caps_per_phy = {0}; 2433 struct wmi_unified *wmi_handle; 2434 2435 wmi_handle = get_wmi_unified_hdl_from_psoc(hdd_ctx->psoc); 2436 if (!wmi_handle) { 2437 hdd_err("wmi handle is NULL"); 2438 return; 2439 } 2440 2441 status = ucfg_mlme_get_vht_for_24ghz(hdd_ctx->psoc, &b2g_vht_cfg); 2442 if (QDF_IS_STATUS_ERROR(status)) { 2443 hdd_err("Failed to get 2g vht mode"); 2444 return; 2445 } 2446 if (wmi_service_enabled(wmi_handle, wmi_service_ext_msg)) { 2447 status = wma_get_caps_for_phyidx_hwmode(&caps_per_phy, 2448 HW_MODE_DBS_NONE, 2449 CDS_BAND_2GHZ); 2450 if (QDF_IS_STATUS_ERROR(status)) { 2451 hdd_err("Failed to get phy caps"); 2452 return; 2453 } 2454 if (caps_per_phy.vht_2g) 2455 b2g_vht_target = true; 2456 } else { 2457 status = wlan_reg_get_chip_mode(hdd_ctx->pdev, &chip_mode); 2458 if (QDF_IS_STATUS_ERROR(status)) { 2459 hdd_err("Failed to get chip mode"); 2460 return; 2461 } 2462 b2g_vht_target = 2463 (chip_mode & HOST_REGDMN_MODE_11AC_VHT20_2G) ? 2464 true : false; 2465 } 2466 2467 b2g_vht_cfg = b2g_vht_cfg && b2g_vht_target; 2468 hdd_debug("vht 2g target: %d, cfg: %d", b2g_vht_target, b2g_vht_cfg); 2469 status = ucfg_mlme_set_vht_for_24ghz(hdd_ctx->psoc, b2g_vht_cfg); 2470 if (QDF_IS_STATUS_ERROR(status)) { 2471 hdd_err("Failed to update 2g vht mode"); 2472 return; 2473 } 2474 } 2475 2476 static void hdd_extract_fw_version_info(struct hdd_context *hdd_ctx) 2477 { 2478 hdd_ctx->fw_version_info.major_spid = 2479 HDD_FW_VER_MAJOR_SPID(hdd_ctx->target_fw_version); 2480 hdd_ctx->fw_version_info.minor_spid = 2481 HDD_FW_VER_MINOR_SPID(hdd_ctx->target_fw_version); 2482 hdd_ctx->fw_version_info.siid = 2483 HDD_FW_VER_SIID(hdd_ctx->target_fw_version); 2484 hdd_ctx->fw_version_info.crmid = 2485 HDD_FW_VER_CRM_ID(hdd_ctx->target_fw_version); 2486 hdd_ctx->fw_version_info.sub_id = 2487 HDD_FW_VER_SUB_ID(hdd_ctx->target_fw_vers_ext); 2488 hdd_ctx->fw_version_info.rel_id = 2489 HDD_FW_VER_REL_ID(hdd_ctx->target_fw_vers_ext); 2490 } 2491 2492 #if defined(WLAN_FEATURE_11AX) && \ 2493 (defined(CFG80211_SBAND_IFTYPE_DATA_BACKPORT) || \ 2494 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0))) 2495 2496 static void 2497 hdd_update_wiphy_he_mcs(struct ieee80211_sband_iftype_data *iftype_data, 2498 tDot11fIEhe_cap *he_cap_cfg) 2499 { 2500 if (!iftype_data || !he_cap_cfg) { 2501 hdd_err("Unable to update wiphy he_mcs"); 2502 return; 2503 } 2504 2505 iftype_data->he_cap.he_mcs_nss_supp.tx_mcs_80 = 2506 he_cap_cfg->tx_he_mcs_map_lt_80; 2507 iftype_data->he_cap.he_mcs_nss_supp.tx_mcs_160 = 2508 *((uint16_t *)he_cap_cfg->tx_he_mcs_map_160); 2509 iftype_data->he_cap.he_mcs_nss_supp.tx_mcs_80p80 = 2510 *((uint16_t *)he_cap_cfg->tx_he_mcs_map_80_80); 2511 } 2512 2513 #if defined(CONFIG_BAND_6GHZ) && (defined(IEEE80211_HE_6GHZ_CAP_MIN_MPDU_START)) 2514 static void hdd_update_wiphy_he_6ghz_capa(struct hdd_context *hdd_ctx) 2515 { 2516 uint16_t he_6ghz_capa = 0; 2517 uint8_t min_mpdu_start_spacing; 2518 uint8_t max_ampdu_len_exp; 2519 uint8_t max_mpdu_len; 2520 uint8_t sm_pow_save; 2521 2522 ucfg_mlme_get_ht_mpdu_density(hdd_ctx->psoc, &min_mpdu_start_spacing); 2523 he_6ghz_capa |= FIELD_PREP(IEEE80211_HE_6GHZ_CAP_MIN_MPDU_START, 2524 min_mpdu_start_spacing); 2525 2526 ucfg_mlme_cfg_get_vht_ampdu_len_exp(hdd_ctx->psoc, &max_ampdu_len_exp); 2527 he_6ghz_capa |= FIELD_PREP(IEEE80211_HE_6GHZ_CAP_MAX_AMPDU_LEN_EXP, 2528 max_ampdu_len_exp); 2529 2530 ucfg_mlme_cfg_get_vht_max_mpdu_len(hdd_ctx->psoc, &max_mpdu_len); 2531 he_6ghz_capa |= FIELD_PREP(IEEE80211_HE_6GHZ_CAP_MAX_MPDU_LEN, 2532 max_mpdu_len); 2533 2534 ucfg_mlme_cfg_get_ht_smps(hdd_ctx->psoc, &sm_pow_save); 2535 he_6ghz_capa |= FIELD_PREP(IEEE80211_HE_6GHZ_CAP_SM_PS, sm_pow_save); 2536 2537 he_6ghz_capa |= IEEE80211_HE_6GHZ_CAP_RX_ANTPAT_CONS; 2538 he_6ghz_capa |= IEEE80211_HE_6GHZ_CAP_TX_ANTPAT_CONS; 2539 2540 hdd_ctx->iftype_data_6g->he_6ghz_capa.capa = he_6ghz_capa; 2541 } 2542 #else 2543 static inline void hdd_update_wiphy_he_6ghz_capa(struct hdd_context *hdd_ctx) 2544 { 2545 } 2546 #endif 2547 2548 #if defined(CONFIG_BAND_6GHZ) && (defined(CFG80211_6GHZ_BAND_SUPPORTED) || \ 2549 (KERNEL_VERSION(5, 4, 0) <= LINUX_VERSION_CODE)) 2550 static void 2551 hdd_update_wiphy_he_caps_6ghz(struct hdd_context *hdd_ctx, 2552 tDot11fIEhe_cap *he_cap_cfg) 2553 { 2554 struct ieee80211_supported_band *band_6g = 2555 hdd_ctx->wiphy->bands[HDD_NL80211_BAND_6GHZ]; 2556 uint8_t *phy_info = 2557 hdd_ctx->iftype_data_6g->he_cap.he_cap_elem.phy_cap_info; 2558 uint8_t *mac_info_6g = 2559 hdd_ctx->iftype_data_6g->he_cap.he_cap_elem.mac_cap_info; 2560 uint8_t max_fw_bw = sme_get_vht_ch_width(); 2561 2562 if (!band_6g || !phy_info) { 2563 hdd_debug("6ghz not supported in wiphy"); 2564 return; 2565 } 2566 2567 hdd_ctx->iftype_data_6g->types_mask = 2568 (BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP)); 2569 hdd_ctx->iftype_data_6g->he_cap.has_he = true; 2570 band_6g->n_iftype_data = 1; 2571 2572 if (max_fw_bw >= WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ) 2573 phy_info[0] |= 2574 IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_80MHZ_IN_5G; 2575 if (max_fw_bw >= WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ) 2576 phy_info[0] |= 2577 IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_160MHZ_IN_5G; 2578 if (max_fw_bw >= WNI_CFG_VHT_CHANNEL_WIDTH_80_PLUS_80MHZ) 2579 phy_info[0] |= 2580 IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G; 2581 2582 if (he_cap_cfg->twt_request) 2583 mac_info_6g[0] |= IEEE80211_HE_MAC_CAP0_TWT_REQ; 2584 2585 if (he_cap_cfg->twt_responder) 2586 mac_info_6g[0] |= IEEE80211_HE_MAC_CAP0_TWT_RES; 2587 2588 hdd_update_wiphy_he_6ghz_capa(hdd_ctx); 2589 2590 hdd_update_wiphy_he_mcs(hdd_ctx->iftype_data_6g, he_cap_cfg); 2591 2592 band_6g->iftype_data = hdd_ctx->iftype_data_6g; 2593 } 2594 #else 2595 static inline void 2596 hdd_update_wiphy_he_caps_6ghz(struct hdd_context *hdd_ctx, 2597 tDot11fIEhe_cap *he_cap_cfg) 2598 { 2599 } 2600 #endif 2601 2602 static void hdd_update_wiphy_he_cap(struct hdd_context *hdd_ctx) 2603 { 2604 tDot11fIEhe_cap he_cap_cfg; 2605 struct ieee80211_supported_band *band_2g = 2606 hdd_ctx->wiphy->bands[HDD_NL80211_BAND_2GHZ]; 2607 struct ieee80211_supported_band *band_5g = 2608 hdd_ctx->wiphy->bands[HDD_NL80211_BAND_5GHZ]; 2609 QDF_STATUS status; 2610 uint8_t *phy_info_5g = 2611 hdd_ctx->iftype_data_5g->he_cap.he_cap_elem.phy_cap_info; 2612 uint8_t max_fw_bw = sme_get_vht_ch_width(); 2613 uint32_t channel_bonding_mode_2g; 2614 uint8_t *phy_info_2g = 2615 hdd_ctx->iftype_data_2g->he_cap.he_cap_elem.phy_cap_info; 2616 uint8_t *mac_info_2g = 2617 hdd_ctx->iftype_data_2g->he_cap.he_cap_elem.mac_cap_info; 2618 uint8_t *mac_info_5g = 2619 hdd_ctx->iftype_data_5g->he_cap.he_cap_elem.mac_cap_info; 2620 2621 status = ucfg_mlme_cfg_get_he_caps(hdd_ctx->psoc, &he_cap_cfg); 2622 2623 if (QDF_IS_STATUS_ERROR(status)) 2624 return; 2625 2626 if (band_2g) { 2627 hdd_ctx->iftype_data_2g->types_mask = 2628 (BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP)); 2629 hdd_ctx->iftype_data_2g->he_cap.has_he = he_cap_cfg.present; 2630 band_2g->n_iftype_data = 1; 2631 hdd_update_wiphy_he_mcs(hdd_ctx->iftype_data_2g, &he_cap_cfg); 2632 band_2g->iftype_data = hdd_ctx->iftype_data_2g; 2633 2634 ucfg_mlme_get_channel_bonding_24ghz(hdd_ctx->psoc, 2635 &channel_bonding_mode_2g); 2636 if (channel_bonding_mode_2g) 2637 phy_info_2g[0] |= 2638 IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_IN_2G; 2639 2640 if (he_cap_cfg.twt_request) 2641 mac_info_2g[0] |= IEEE80211_HE_MAC_CAP0_TWT_REQ; 2642 2643 if (he_cap_cfg.twt_responder) 2644 mac_info_2g[0] |= IEEE80211_HE_MAC_CAP0_TWT_RES; 2645 } 2646 if (band_5g) { 2647 hdd_ctx->iftype_data_5g->types_mask = 2648 (BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP)); 2649 hdd_ctx->iftype_data_5g->he_cap.has_he = he_cap_cfg.present; 2650 band_5g->n_iftype_data = 1; 2651 hdd_update_wiphy_he_mcs(hdd_ctx->iftype_data_5g, &he_cap_cfg); 2652 band_5g->iftype_data = hdd_ctx->iftype_data_5g; 2653 2654 if (max_fw_bw >= WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ) 2655 phy_info_5g[0] |= 2656 IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_80MHZ_IN_5G; 2657 if (max_fw_bw >= WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ) 2658 phy_info_5g[0] |= 2659 IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_160MHZ_IN_5G; 2660 if (max_fw_bw >= WNI_CFG_VHT_CHANNEL_WIDTH_80_PLUS_80MHZ) 2661 phy_info_5g[0] |= 2662 IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G; 2663 2664 if (he_cap_cfg.twt_request) 2665 mac_info_5g[0] |= IEEE80211_HE_MAC_CAP0_TWT_REQ; 2666 2667 if (he_cap_cfg.twt_responder) 2668 mac_info_5g[0] |= IEEE80211_HE_MAC_CAP0_TWT_RES; 2669 } 2670 2671 hdd_update_wiphy_he_caps_6ghz(hdd_ctx, &he_cap_cfg); 2672 } 2673 #else 2674 static void hdd_update_wiphy_he_cap(struct hdd_context *hdd_ctx) 2675 { 2676 } 2677 #endif 2678 2679 static void hdd_component_cfg_chan_to_freq(struct wlan_objmgr_pdev *pdev) 2680 { 2681 ucfg_mlme_cfg_chan_to_freq(pdev); 2682 } 2683 2684 static uint32_t hdd_update_band_cap_from_dot11mode( 2685 struct hdd_context *hdd_ctx, uint32_t band_capability) 2686 { 2687 if (hdd_ctx->config->dot11Mode == eHDD_DOT11_MODE_AUTO) 2688 return band_capability; 2689 2690 if (hdd_ctx->config->dot11Mode == eHDD_DOT11_MODE_11b || 2691 hdd_ctx->config->dot11Mode == eHDD_DOT11_MODE_11g || 2692 hdd_ctx->config->dot11Mode == eHDD_DOT11_MODE_11g_ONLY || 2693 hdd_ctx->config->dot11Mode == eHDD_DOT11_MODE_11b_ONLY) 2694 band_capability = (band_capability & (~BIT(REG_BAND_5G))); 2695 2696 if (hdd_ctx->config->dot11Mode == eHDD_DOT11_MODE_11a) 2697 band_capability = (band_capability & (~BIT(REG_BAND_2G))); 2698 2699 if (hdd_ctx->config->dot11Mode != eHDD_DOT11_MODE_11ax_ONLY && 2700 hdd_ctx->config->dot11Mode != eHDD_DOT11_MODE_11ax) 2701 band_capability = (band_capability & (~BIT(REG_BAND_6G))); 2702 2703 qdf_debug("Update band capability %x", band_capability); 2704 return band_capability; 2705 } 2706 2707 #ifdef FEATURE_WPSS_THERMAL_MITIGATION 2708 static inline 2709 void hdd_update_multi_client_thermal_support(struct hdd_context *hdd_ctx) 2710 { 2711 struct wmi_unified *wmi_handle; 2712 2713 wmi_handle = get_wmi_unified_hdl_from_psoc(hdd_ctx->psoc); 2714 if (!wmi_handle) 2715 return; 2716 2717 hdd_ctx->multi_client_thermal_mitigation = 2718 wmi_service_enabled(wmi_handle, 2719 wmi_service_thermal_multi_client_support); 2720 } 2721 #else 2722 static inline 2723 void hdd_update_multi_client_thermal_support(struct hdd_context *hdd_ctx) 2724 { 2725 } 2726 #endif 2727 2728 #ifdef WLAN_FEATURE_LOCAL_PKT_CAPTURE 2729 static void hdd_lpc_enable_powersave(struct hdd_context *hdd_ctx) 2730 { 2731 struct hdd_adapter *sta_adapter; 2732 2733 if (!ucfg_dp_is_local_pkt_capture_enabled(hdd_ctx->psoc)) 2734 return; 2735 2736 ucfg_fwol_configure_global_params(hdd_ctx->psoc, hdd_ctx->pdev); 2737 2738 if (wma_enable_disable_imps(hdd_ctx->pdev->pdev_objmgr.wlan_pdev_id, 1)) 2739 hdd_err("IMPS feature enable failed"); 2740 2741 sta_adapter = hdd_get_adapter(hdd_ctx, QDF_STA_MODE); 2742 if (!sta_adapter) { 2743 hdd_debug("STA adapter does not exist"); 2744 return; 2745 } 2746 2747 wlan_hdd_set_powersave(sta_adapter->deflink, true, 0); 2748 } 2749 2750 static void hdd_lpc_disable_powersave(struct hdd_context *hdd_ctx) 2751 { 2752 struct hdd_adapter *sta_adapter; 2753 2754 if (!ucfg_dp_is_local_pkt_capture_enabled(hdd_ctx->psoc)) 2755 return; 2756 2757 ucfg_fwol_set_ilp_config(hdd_ctx->psoc, hdd_ctx->pdev, 0); 2758 2759 if (wma_enable_disable_imps(hdd_ctx->pdev->pdev_objmgr.wlan_pdev_id, 0)) 2760 hdd_err("IMPS feature disable failed"); 2761 2762 sta_adapter = hdd_get_adapter(hdd_ctx, QDF_STA_MODE); 2763 if (!sta_adapter) { 2764 hdd_err("STA adapter does not exist"); 2765 return; 2766 } 2767 wlan_hdd_set_powersave(sta_adapter->deflink, false, 0); 2768 } 2769 #else 2770 static inline void hdd_lpc_enable_powersave(struct hdd_context *hdd_ctx) 2771 { 2772 } 2773 2774 static inline void hdd_lpc_disable_powersave(struct hdd_context *hdd_ctx) 2775 { 2776 } 2777 #endif 2778 2779 int hdd_update_tgt_cfg(hdd_handle_t hdd_handle, struct wma_tgt_cfg *cfg) 2780 { 2781 int ret; 2782 struct hdd_context *hdd_ctx = hdd_handle_to_context(hdd_handle); 2783 uint32_t temp_band_cap, band_capability; 2784 struct cds_config_info *cds_cfg = cds_get_ini_config(); 2785 uint8_t antenna_mode; 2786 uint8_t sub_20_chan_width; 2787 QDF_STATUS status; 2788 mac_handle_t mac_handle; 2789 bool bval = false; 2790 uint8_t value = 0; 2791 uint32_t fine_time_meas_cap = 0; 2792 enum nss_chains_band_info band; 2793 bool enable_dynamic_cfg; 2794 2795 if (!hdd_ctx) { 2796 hdd_err("HDD context is NULL"); 2797 return -EINVAL; 2798 } 2799 ret = hdd_objmgr_create_and_store_pdev(hdd_ctx); 2800 if (ret) { 2801 QDF_DEBUG_PANIC("Failed to create pdev; errno:%d", ret); 2802 return -EINVAL; 2803 } 2804 2805 hdd_debug("New pdev has been created with pdev_id = %u", 2806 hdd_ctx->pdev->pdev_objmgr.wlan_pdev_id); 2807 2808 status = dispatcher_pdev_open(hdd_ctx->pdev); 2809 if (QDF_IS_STATUS_ERROR(status)) { 2810 QDF_DEBUG_PANIC("dispatcher pdev open failed; status:%d", 2811 status); 2812 ret = qdf_status_to_os_return(status); 2813 goto exit; 2814 } 2815 2816 status = hdd_component_pdev_open(hdd_ctx->pdev); 2817 if (QDF_IS_STATUS_ERROR(status)) { 2818 QDF_DEBUG_PANIC("hdd component pdev open failed; status:%d", 2819 status); 2820 ret = qdf_status_to_os_return(status); 2821 goto dispatcher_close; 2822 } 2823 /* 2824 * For 6GHz support this api is added to convert mlme cfgs 2825 * channel numbers to frequency 2826 */ 2827 hdd_component_cfg_chan_to_freq(hdd_ctx->pdev); 2828 2829 hdd_objmgr_update_tgt_max_vdev_psoc(hdd_ctx, cfg->max_intf_count); 2830 2831 ucfg_ipa_set_dp_handle(hdd_ctx->psoc, 2832 cds_get_context(QDF_MODULE_ID_SOC)); 2833 ucfg_ipa_set_pdev_id(hdd_ctx->psoc, OL_TXRX_PDEV_ID); 2834 2835 status = ucfg_mlme_get_sub_20_chan_width(hdd_ctx->psoc, 2836 &sub_20_chan_width); 2837 if (QDF_IS_STATUS_ERROR(status)) { 2838 hdd_err("Failed to get sub_20_chan_width config"); 2839 ret = qdf_status_to_os_return(status); 2840 goto pdev_close; 2841 } 2842 2843 if (cds_cfg) { 2844 if (sub_20_chan_width != 2845 WLAN_SUB_20_CH_WIDTH_NONE && !cfg->sub_20_support) { 2846 hdd_err("User requested sub 20 MHz channel width but unsupported by FW."); 2847 cds_cfg->sub_20_channel_width = 2848 WLAN_SUB_20_CH_WIDTH_NONE; 2849 } else { 2850 cds_cfg->sub_20_channel_width = sub_20_chan_width; 2851 } 2852 } 2853 2854 status = ucfg_mlme_get_band_capability(hdd_ctx->psoc, &band_capability); 2855 if (QDF_IS_STATUS_ERROR(status)) { 2856 hdd_err("Failed to get MLME band capability"); 2857 ret = qdf_status_to_os_return(status); 2858 goto pdev_close; 2859 } 2860 2861 band_capability = 2862 hdd_update_band_cap_from_dot11mode(hdd_ctx, band_capability); 2863 2864 /* first store the INI band capability */ 2865 temp_band_cap = band_capability; 2866 2867 band_capability = cfg->band_cap; 2868 hdd_ctx->is_fils_roaming_supported = 2869 cfg->services.is_fils_roaming_supported; 2870 2871 hdd_ctx->config->is_11k_offload_supported = 2872 cfg->services.is_11k_offload_supported; 2873 2874 /* 2875 * merge the target band capability with INI setting if the merge has 2876 * at least 1 band enabled 2877 */ 2878 temp_band_cap &= band_capability; 2879 if (!temp_band_cap) 2880 hdd_warn("ini BandCapability not supported by the target"); 2881 else 2882 band_capability = temp_band_cap; 2883 2884 status = ucfg_mlme_set_band_capability(hdd_ctx->psoc, band_capability); 2885 if (QDF_IS_STATUS_ERROR(status)) { 2886 hdd_err("Failed to set MLME Band Capability"); 2887 ret = qdf_status_to_os_return(status); 2888 goto pdev_close; 2889 } 2890 2891 hdd_ctx->curr_band = band_capability; 2892 hdd_ctx->psoc->soc_nif.user_config.band_capability = hdd_ctx->curr_band; 2893 2894 status = wlan_hdd_update_wiphy_supported_band(hdd_ctx); 2895 if (QDF_IS_STATUS_ERROR(status)) { 2896 hdd_err("Failed to update wiphy band info"); 2897 goto pdev_close; 2898 } 2899 2900 status = ucfg_reg_set_band(hdd_ctx->pdev, band_capability); 2901 if (QDF_IS_STATUS_ERROR(status)) 2902 /* 2903 * Continue, Do not close the pdev from here as if host fails 2904 * to update band information if cc_list event is not received 2905 * by this time, then also driver load should happen. 2906 */ 2907 hdd_err("Failed to update regulatory band info"); 2908 2909 if (!cds_is_driver_recovering() || cds_is_driver_in_bad_state()) { 2910 hdd_ctx->reg.reg_domain = cfg->reg_domain; 2911 hdd_ctx->reg.eeprom_rd_ext = cfg->eeprom_rd_ext; 2912 } 2913 2914 /* This can be extended to other configurations like ht, vht cap... */ 2915 status = wlan_hdd_validate_mac_address(&cfg->hw_macaddr); 2916 if (QDF_IS_STATUS_SUCCESS(status)) 2917 qdf_mem_copy(&hdd_ctx->hw_macaddr, &cfg->hw_macaddr, 2918 QDF_MAC_ADDR_SIZE); 2919 2920 hdd_ctx->target_fw_version = cfg->target_fw_version; 2921 hdd_ctx->target_fw_vers_ext = cfg->target_fw_vers_ext; 2922 hdd_extract_fw_version_info(hdd_ctx); 2923 2924 hdd_ctx->hw_bd_id = cfg->hw_bd_id; 2925 qdf_mem_copy(&hdd_ctx->hw_bd_info, &cfg->hw_bd_info, 2926 sizeof(cfg->hw_bd_info)); 2927 2928 if (cfg->max_intf_count > WLAN_MAX_VDEVS) { 2929 hdd_err("fw max vdevs (%u) > host max vdevs (%u); using %u", 2930 cfg->max_intf_count, WLAN_MAX_VDEVS, WLAN_MAX_VDEVS); 2931 hdd_ctx->max_intf_count = WLAN_MAX_VDEVS; 2932 } else { 2933 hdd_ctx->max_intf_count = cfg->max_intf_count; 2934 } 2935 2936 hdd_sar_target_config(hdd_ctx, cfg); 2937 hdd_lpass_target_config(hdd_ctx, cfg); 2938 2939 hdd_ctx->ap_arpns_support = cfg->ap_arpns_support; 2940 2941 hdd_update_tgt_services(hdd_ctx, &cfg->services); 2942 2943 hdd_update_tgt_ht_cap(hdd_ctx, &cfg->ht_cap); 2944 2945 sme_update_bfer_caps_as_per_nss_chains(hdd_ctx->mac_handle, cfg); 2946 2947 hdd_update_tgt_vht_cap(hdd_ctx, &cfg->vht_cap); 2948 if (cfg->services.en_11ax && 2949 (hdd_ctx->config->dot11Mode == eHDD_DOT11_MODE_AUTO || 2950 hdd_ctx->config->dot11Mode == eHDD_DOT11_MODE_11ax || 2951 hdd_ctx->config->dot11Mode == eHDD_DOT11_MODE_11ax_ONLY)) { 2952 hdd_debug("11AX: 11ax is enabled - update HDD config"); 2953 hdd_update_tgt_he_cap(hdd_ctx, cfg); 2954 hdd_update_wiphy_he_cap(hdd_ctx); 2955 } 2956 hdd_update_tgt_twt_cap(hdd_ctx, cfg); 2957 hdd_update_tgt_eht_cap(hdd_ctx, cfg); 2958 hdd_update_wiphy_eht_cap(hdd_ctx); 2959 ucfg_mlme_update_tgt_mlo_cap(hdd_ctx->psoc); 2960 2961 for (band = NSS_CHAINS_BAND_2GHZ; band < NSS_CHAINS_BAND_MAX; band++) { 2962 sme_modify_nss_chains_tgt_cfg(hdd_ctx->mac_handle, 2963 QDF_STA_MODE, band); 2964 sme_modify_nss_chains_tgt_cfg(hdd_ctx->mac_handle, 2965 QDF_SAP_MODE, band); 2966 sme_modify_nss_chains_tgt_cfg(hdd_ctx->mac_handle, 2967 QDF_TDLS_MODE, band); 2968 sme_modify_nss_chains_tgt_cfg(hdd_ctx->mac_handle, 2969 QDF_P2P_DEVICE_MODE, 2970 band); 2971 sme_modify_nss_chains_tgt_cfg(hdd_ctx->mac_handle, 2972 QDF_OCB_MODE, band); 2973 sme_modify_nss_chains_tgt_cfg(hdd_ctx->mac_handle, 2974 QDF_TDLS_MODE, band); 2975 } 2976 2977 hdd_update_vdev_nss(hdd_ctx); 2978 2979 status = 2980 ucfg_mlme_get_enable_dynamic_nss_chains_cfg(hdd_ctx->psoc, 2981 &enable_dynamic_cfg); 2982 if (QDF_IS_STATUS_ERROR(status)) { 2983 hdd_err("unable to get enable dynamic config"); 2984 hdd_ctx->dynamic_nss_chains_support = false; 2985 } else { 2986 hdd_ctx->dynamic_nss_chains_support = 2987 cfg->dynamic_nss_chains_support & 2988 enable_dynamic_cfg; 2989 hdd_debug("Dynamic nss chain support FW %d driver %d", 2990 cfg->dynamic_nss_chains_support, enable_dynamic_cfg); 2991 } 2992 2993 status = ucfg_mlme_update_dynamic_nss_chains_support 2994 (hdd_ctx->psoc, hdd_ctx->dynamic_nss_chains_support); 2995 if (QDF_IS_STATUS_ERROR(status)) 2996 hdd_err("unable to set dynamic_nss_chains_support"); 2997 2998 ucfg_mlme_get_fine_time_meas_cap(hdd_ctx->psoc, &fine_time_meas_cap); 2999 fine_time_meas_cap &= cfg->fine_time_measurement_cap; 3000 status = ucfg_mlme_set_fine_time_meas_cap(hdd_ctx->psoc, 3001 fine_time_meas_cap); 3002 if (QDF_IS_STATUS_ERROR(status)) { 3003 hdd_err("failed to set fine_time_meas_cap, 0x%x, ox%x", 3004 fine_time_meas_cap, cfg->fine_time_measurement_cap); 3005 ucfg_mlme_get_fine_time_meas_cap(hdd_ctx->psoc, 3006 &fine_time_meas_cap); 3007 } 3008 3009 hdd_ctx->fine_time_meas_cap_target = cfg->fine_time_measurement_cap; 3010 hdd_debug("fine_time_meas_cap: 0x%x", fine_time_meas_cap); 3011 3012 status = ucfg_mlme_get_vht_enable2x2(hdd_ctx->psoc, &bval); 3013 if (!QDF_IS_STATUS_SUCCESS(status)) 3014 hdd_err("unable to get vht_enable2x2"); 3015 3016 antenna_mode = (bval == 0x01) ? 3017 HDD_ANTENNA_MODE_2X2 : HDD_ANTENNA_MODE_1X1; 3018 hdd_update_smps_antenna_mode(hdd_ctx, antenna_mode); 3019 hdd_debug("Init current antenna mode: %d", 3020 hdd_ctx->current_antenna_mode); 3021 3022 hdd_ctx->rcpi_enabled = cfg->rcpi_enabled; 3023 3024 status = ucfg_mlme_cfg_get_vht_tx_bfee_ant_supp(hdd_ctx->psoc, 3025 &value); 3026 if (QDF_IS_STATUS_ERROR(status)) { 3027 status = false; 3028 hdd_err("set tx_bfee_ant_supp failed"); 3029 } 3030 3031 status = ucfg_mlme_set_restricted_80p80_bw_supp(hdd_ctx->psoc, 3032 cfg->restricted_80p80_bw_supp); 3033 if (QDF_IS_STATUS_ERROR(status)) 3034 hdd_err("Failed to set MLME restircted 80p80 BW support"); 3035 3036 if ((value > MLME_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED_FW_DEF) && 3037 !cfg->tx_bfee_8ss_enabled) { 3038 status = ucfg_mlme_cfg_set_vht_tx_bfee_ant_supp(hdd_ctx->psoc, 3039 MLME_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED_FW_DEF); 3040 if (QDF_IS_STATUS_ERROR(status)) { 3041 status = false; 3042 hdd_err("set tx_bfee_ant_supp failed"); 3043 } 3044 } 3045 3046 hdd_update_tid_to_link_supported(hdd_ctx, &cfg->services); 3047 mac_handle = hdd_ctx->mac_handle; 3048 3049 hdd_debug("txBFCsnValue %d", value); 3050 3051 /* 3052 * Update txBFCsnValue and NumSoundingDim values to vhtcap in wiphy 3053 */ 3054 hdd_update_wiphy_vhtcap(hdd_ctx); 3055 3056 hdd_update_vhtcap_2g(hdd_ctx); 3057 3058 hdd_ctx->wmi_max_len = cfg->wmi_max_len; 3059 3060 wlan_config_sched_scan_plans_to_wiphy(hdd_ctx->wiphy, hdd_ctx->psoc); 3061 /* 3062 * This needs to be done after HDD pdev is created and stored since 3063 * it will access the HDD pdev object lock. 3064 */ 3065 hdd_runtime_suspend_context_init(hdd_ctx); 3066 3067 /* Configure NAN datapath features */ 3068 hdd_nan_datapath_target_config(hdd_ctx, cfg); 3069 ucfg_nan_set_tgt_caps(hdd_ctx->psoc, &cfg->nan_caps); 3070 hdd_ctx->dfs_cac_offload = cfg->dfs_cac_offload; 3071 hdd_ctx->lte_coex_ant_share = cfg->services.lte_coex_ant_share; 3072 hdd_ctx->obss_scan_offload = cfg->services.obss_scan_offload; 3073 ucfg_scan_set_obss_scan_offload(hdd_ctx->psoc, 3074 hdd_ctx->obss_scan_offload); 3075 status = ucfg_mlme_set_obss_detection_offload_enabled( 3076 hdd_ctx->psoc, cfg->obss_detection_offloaded); 3077 if (QDF_IS_STATUS_ERROR(status)) 3078 hdd_err("Couldn't pass WNI_CFG_OBSS_DETECTION_OFFLOAD to CFG"); 3079 3080 status = ucfg_mlme_set_obss_color_collision_offload_enabled( 3081 hdd_ctx->psoc, cfg->obss_color_collision_offloaded); 3082 if (QDF_IS_STATUS_ERROR(status)) 3083 hdd_err("Failed to set WNI_CFG_OBSS_COLOR_COLLISION_OFFLOAD"); 3084 3085 ucfg_mlme_set_bss_color_collision_det_support( 3086 hdd_ctx->psoc, 3087 cfg->obss_color_collision_offloaded); 3088 if (!cfg->obss_color_collision_offloaded) { 3089 status = ucfg_mlme_set_bss_color_collision_det_sta( 3090 hdd_ctx->psoc, 3091 cfg->obss_color_collision_offloaded); 3092 if (QDF_IS_STATUS_ERROR(status)) 3093 hdd_err("Failed to set CFG_BSS_CLR_COLLISION_DET_STA"); 3094 } 3095 3096 hdd_update_score_config(hdd_ctx); 3097 hdd_update_multi_client_thermal_support(hdd_ctx); 3098 3099 ucfg_psoc_mlme_set_11be_capab(hdd_ctx->psoc, cfg->services.en_11be); 3100 return 0; 3101 3102 dispatcher_close: 3103 dispatcher_pdev_close(hdd_ctx->pdev); 3104 pdev_close: 3105 hdd_component_pdev_close(hdd_ctx->pdev); 3106 exit: 3107 hdd_objmgr_release_and_destroy_pdev(hdd_ctx); 3108 3109 return ret; 3110 } 3111 3112 bool hdd_dfs_indicate_radar(struct hdd_context *hdd_ctx) 3113 { 3114 struct hdd_adapter *adapter, *next_adapter = NULL; 3115 struct hdd_ap_ctx *ap_ctx; 3116 uint32_t ap_chan; 3117 bool dfs_disable_channel_switch = false; 3118 struct wlan_hdd_link_info *link_info; 3119 3120 if (!hdd_ctx) { 3121 hdd_info("Couldn't get hdd_ctx"); 3122 return true; 3123 } 3124 3125 ucfg_mlme_get_dfs_disable_channel_switch(hdd_ctx->psoc, 3126 &dfs_disable_channel_switch); 3127 if (dfs_disable_channel_switch) { 3128 hdd_info("skip tx block hdd_ctx=%pK, disableDFSChSwitch=%d", 3129 hdd_ctx, dfs_disable_channel_switch); 3130 return true; 3131 } 3132 3133 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 3134 NET_DEV_HOLD_DFS_INDICATE_RADAR) { 3135 3136 if (adapter->device_mode != QDF_SAP_MODE && 3137 adapter->device_mode != QDF_P2P_GO_MODE) 3138 goto next_adapter; 3139 3140 hdd_adapter_for_each_active_link_info(adapter, link_info) { 3141 ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(link_info); 3142 ap_chan = ap_ctx->operating_chan_freq; 3143 if (!wlan_reg_is_passive_or_disable_for_pwrmode(hdd_ctx->pdev, 3144 ap_chan, REG_CURRENT_PWR_MODE)) 3145 continue; 3146 3147 ap_ctx->dfs_cac_block_tx = true; 3148 hdd_info("tx blocked for vdev: %d", link_info->vdev_id); 3149 if (link_info->vdev_id != WLAN_UMAC_VDEV_ID_MAX) 3150 cdp_fc_vdev_flush( 3151 cds_get_context(QDF_MODULE_ID_SOC), 3152 link_info->vdev_id); 3153 } 3154 next_adapter: 3155 hdd_adapter_dev_put_debug(adapter, 3156 NET_DEV_HOLD_DFS_INDICATE_RADAR); 3157 } 3158 3159 return true; 3160 } 3161 3162 bool hdd_is_valid_mac_address(const uint8_t *mac_addr) 3163 { 3164 int xdigit = 0; 3165 int separator = 0; 3166 3167 while (*mac_addr) { 3168 if (isxdigit(*mac_addr)) { 3169 xdigit++; 3170 } else if (':' == *mac_addr) { 3171 if (0 == xdigit || ((xdigit / 2) - 1) != separator) 3172 break; 3173 3174 ++separator; 3175 } else { 3176 /* Invalid MAC found */ 3177 return false; 3178 } 3179 ++mac_addr; 3180 } 3181 return xdigit == 12 && (separator == 5 || separator == 0); 3182 } 3183 3184 /** 3185 * hdd_mon_mode_ether_setup() - Update monitor mode struct net_device. 3186 * @dev: Handle to struct net_device to be updated. 3187 * 3188 * Return: None 3189 */ 3190 static void hdd_mon_mode_ether_setup(struct net_device *dev) 3191 { 3192 dev->header_ops = NULL; 3193 dev->type = ARPHRD_IEEE80211_RADIOTAP; 3194 dev->hard_header_len = ETH_HLEN; 3195 dev->mtu = ETH_DATA_LEN; 3196 dev->addr_len = ETH_ALEN; 3197 dev->tx_queue_len = 1000; /* Ethernet wants good queues */ 3198 dev->flags = IFF_BROADCAST|IFF_MULTICAST; 3199 dev->priv_flags |= IFF_TX_SKB_SHARING; 3200 3201 memset(dev->broadcast, 0xFF, ETH_ALEN); 3202 } 3203 3204 #ifdef FEATURE_MONITOR_MODE_SUPPORT 3205 /** 3206 * hdd_mon_turn_off_ps_and_wow() - Update monitor mode struct net_device. 3207 * @hdd_ctx: Pointer to HDD context. 3208 * 3209 * Return: None 3210 */ 3211 static void hdd_mon_turn_off_ps_and_wow(struct hdd_context *hdd_ctx) 3212 { 3213 ucfg_pmo_set_power_save_mode(hdd_ctx->psoc, 3214 PMO_PS_ADVANCED_POWER_SAVE_DISABLE); 3215 ucfg_pmo_set_wow_enable(hdd_ctx->psoc, PMO_WOW_DISABLE_BOTH); 3216 } 3217 3218 /** 3219 * __hdd_mon_open() - HDD Open function 3220 * @dev: Pointer to net_device structure 3221 * 3222 * This is called in response to ifconfig up 3223 * 3224 * Return: 0 for success; non-zero for failure 3225 */ 3226 static int __hdd_mon_open(struct net_device *dev) 3227 { 3228 int ret; 3229 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev); 3230 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); 3231 struct bbm_params param = {0}; 3232 3233 hdd_enter_dev(dev); 3234 3235 if (test_bit(DEVICE_IFACE_OPENED, &adapter->event_flags)) { 3236 hdd_debug_rl("Monitor interface is already up"); 3237 return 0; 3238 } 3239 3240 ret = wlan_hdd_validate_context(hdd_ctx); 3241 if (ret) 3242 return ret; 3243 3244 hdd_mon_mode_ether_setup(dev); 3245 3246 if (con_mode == QDF_GLOBAL_MONITOR_MODE || 3247 ucfg_mlme_is_sta_mon_conc_supported(hdd_ctx->psoc) || 3248 ucfg_dp_is_local_pkt_capture_enabled(hdd_ctx->psoc)) { 3249 ret = hdd_trigger_psoc_idle_restart(hdd_ctx); 3250 if (ret) { 3251 hdd_err("Failed to start WLAN modules return"); 3252 return ret; 3253 } 3254 hdd_err("hdd_wlan_start_modules() successful !"); 3255 3256 if ((!test_bit(SME_SESSION_OPENED, 3257 &adapter->deflink->link_flags)) || 3258 (policy_mgr_is_sta_mon_concurrency(hdd_ctx->psoc))) { 3259 ret = hdd_start_adapter(adapter, true); 3260 if (ret) { 3261 hdd_err("Failed to start adapter :%d", 3262 adapter->device_mode); 3263 return ret; 3264 } 3265 hdd_err("hdd_start_adapters() successful !"); 3266 } 3267 hdd_mon_turn_off_ps_and_wow(hdd_ctx); 3268 set_bit(DEVICE_IFACE_OPENED, &adapter->event_flags); 3269 } 3270 3271 if (con_mode != QDF_GLOBAL_MONITOR_MODE && 3272 (ucfg_mlme_is_sta_mon_conc_supported(hdd_ctx->psoc) || 3273 ucfg_dp_is_local_pkt_capture_enabled(hdd_ctx->psoc))) { 3274 hdd_info("Acquire wakelock for STA + monitor mode"); 3275 3276 qdf_wake_lock_acquire(&hdd_ctx->monitor_mode_wakelock, 3277 WIFI_POWER_EVENT_WAKELOCK_MONITOR_MODE); 3278 hdd_lpc_disable_powersave(hdd_ctx); 3279 qdf_runtime_pm_prevent_suspend( 3280 &hdd_ctx->runtime_context.monitor_mode); 3281 } 3282 3283 ret = hdd_set_mon_rx_cb(dev); 3284 3285 if (!ret) 3286 ret = hdd_enable_monitor_mode(dev); 3287 3288 if (!ret) { 3289 param.policy = BBM_DRIVER_MODE_POLICY; 3290 param.policy_info.driver_mode = QDF_GLOBAL_MONITOR_MODE; 3291 ucfg_dp_bbm_apply_independent_policy(hdd_ctx->psoc, ¶m); 3292 ucfg_dp_set_current_throughput_level(hdd_ctx->psoc, 3293 PLD_BUS_WIDTH_VERY_HIGH); 3294 } 3295 3296 return ret; 3297 } 3298 3299 /** 3300 * hdd_mon_open() - Wrapper function for __hdd_mon_open to protect it from SSR 3301 * @net_dev: Pointer to net_device structure 3302 * 3303 * This is called in response to ifconfig up 3304 * 3305 * Return: 0 for success; non-zero for failure 3306 */ 3307 static int hdd_mon_open(struct net_device *net_dev) 3308 { 3309 int errno; 3310 struct osif_vdev_sync *vdev_sync; 3311 3312 errno = osif_vdev_sync_trans_start(net_dev, &vdev_sync); 3313 if (errno) 3314 return errno; 3315 3316 errno = __hdd_mon_open(net_dev); 3317 3318 osif_vdev_sync_trans_stop(vdev_sync); 3319 3320 return errno; 3321 } 3322 #endif 3323 3324 #ifdef WLAN_FEATURE_PKT_CAPTURE 3325 /** 3326 * __hdd_pktcapture_open() - HDD Open function 3327 * @dev: Pointer to net_device structure 3328 * 3329 * This is called in response to ifconfig up 3330 * 3331 * Return: 0 for success; non-zero for failure 3332 */ 3333 static int __hdd_pktcapture_open(struct net_device *dev) 3334 { 3335 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev); 3336 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); 3337 struct hdd_adapter *sta_adapter; 3338 QDF_STATUS status; 3339 struct wlan_objmgr_vdev *vdev; 3340 int ret; 3341 3342 hdd_enter_dev(dev); 3343 3344 ret = wlan_hdd_validate_context(hdd_ctx); 3345 if (ret) 3346 return ret; 3347 3348 sta_adapter = hdd_get_adapter(hdd_ctx, QDF_STA_MODE); 3349 if (!sta_adapter) { 3350 hdd_err("No station interface found"); 3351 return -EINVAL; 3352 } 3353 3354 vdev = hdd_objmgr_get_vdev_by_user(sta_adapter->deflink, WLAN_OSIF_ID); 3355 if (!vdev) 3356 return -EINVAL; 3357 3358 hdd_mon_mode_ether_setup(dev); 3359 3360 status = ucfg_dp_register_pkt_capture_callbacks(vdev); 3361 ret = qdf_status_to_os_return(status); 3362 if (ret) { 3363 hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_ID); 3364 return ret; 3365 } 3366 3367 adapter->deflink->vdev = vdev; 3368 set_bit(DEVICE_IFACE_OPENED, &adapter->event_flags); 3369 sta_adapter->mon_adapter = adapter; 3370 3371 return ret; 3372 } 3373 3374 /** 3375 * hdd_pktcapture_open() - Wrapper function for hdd_pktcapture_open to 3376 * protect it from SSR 3377 * @net_dev: Pointer to net_device structure 3378 * 3379 * This is called in response to ifconfig up 3380 * 3381 * Return: 0 for success; non-zero for failure 3382 */ 3383 static int hdd_pktcapture_open(struct net_device *net_dev) 3384 { 3385 int errno; 3386 struct osif_vdev_sync *vdev_sync; 3387 3388 errno = osif_vdev_sync_trans_start(net_dev, &vdev_sync); 3389 if (errno) 3390 return errno; 3391 3392 errno = __hdd_pktcapture_open(net_dev); 3393 3394 osif_vdev_sync_trans_stop(vdev_sync); 3395 3396 return errno; 3397 } 3398 3399 /** 3400 * hdd_unmap_monitor_interface_vdev() - unmap monitor interface vdev and 3401 * deregister packet capture callbacks 3402 * @sta_adapter: station adapter 3403 * 3404 * Return: void 3405 */ 3406 static void 3407 hdd_unmap_monitor_interface_vdev(struct hdd_adapter *sta_adapter) 3408 { 3409 struct hdd_adapter *mon_adapter = sta_adapter->mon_adapter; 3410 3411 if (mon_adapter && hdd_is_interface_up(mon_adapter)) { 3412 ucfg_pkt_capture_deregister_callbacks( 3413 mon_adapter->deflink->vdev); 3414 hdd_objmgr_put_vdev_by_user(mon_adapter->deflink->vdev, 3415 WLAN_OSIF_ID); 3416 mon_adapter->deflink->vdev = NULL; 3417 hdd_reset_monitor_interface(sta_adapter); 3418 } 3419 } 3420 3421 /** 3422 * hdd_map_monitor_interface_vdev() - Map monitor interface vdev and 3423 * register packet capture callbacks 3424 * @sta_adapter: Station adapter 3425 * 3426 * Return: None 3427 */ 3428 static void hdd_map_monitor_interface_vdev(struct hdd_adapter *sta_adapter) 3429 { 3430 struct hdd_adapter *mon_adapter; 3431 QDF_STATUS status; 3432 struct wlan_objmgr_vdev *vdev; 3433 int ret; 3434 3435 mon_adapter = hdd_get_adapter(sta_adapter->hdd_ctx, QDF_MONITOR_MODE); 3436 if (!mon_adapter) { 3437 hdd_debug("No monitor interface found"); 3438 return; 3439 } 3440 3441 if (!mon_adapter || !hdd_is_interface_up(mon_adapter)) { 3442 hdd_debug("Monitor interface is not up\n"); 3443 return; 3444 } 3445 3446 if (!wlan_hdd_is_session_type_monitor(mon_adapter->device_mode)) 3447 return; 3448 3449 vdev = hdd_objmgr_get_vdev_by_user(sta_adapter->deflink, WLAN_OSIF_ID); 3450 if (!vdev) 3451 return; 3452 3453 status = ucfg_dp_register_pkt_capture_callbacks(vdev); 3454 ret = qdf_status_to_os_return(status); 3455 if (ret) { 3456 hdd_err("Failed registering packet capture callbacks"); 3457 hdd_objmgr_put_vdev_by_user(vdev, 3458 WLAN_OSIF_ID); 3459 return; 3460 } 3461 3462 mon_adapter->deflink->vdev = vdev; 3463 sta_adapter->mon_adapter = mon_adapter; 3464 } 3465 3466 void hdd_reset_monitor_interface(struct hdd_adapter *sta_adapter) 3467 { 3468 sta_adapter->mon_adapter = NULL; 3469 } 3470 3471 struct hdd_adapter * 3472 hdd_is_pkt_capture_mon_enable(struct hdd_adapter *sta_adapter) 3473 { 3474 return sta_adapter->mon_adapter; 3475 } 3476 #else 3477 static inline void 3478 hdd_unmap_monitor_interface_vdev(struct hdd_adapter *sta_adapter) 3479 { 3480 } 3481 3482 static inline void 3483 hdd_map_monitor_interface_vdev(struct hdd_adapter *sta_adapter) 3484 { 3485 } 3486 #endif 3487 3488 static QDF_STATUS 3489 wlan_hdd_update_dbs_scan_and_fw_mode_config(void) 3490 { 3491 struct policy_mgr_dual_mac_config cfg = {0}; 3492 QDF_STATUS status; 3493 uint32_t chnl_sel_logic_conc = 0; 3494 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 3495 uint8_t dual_mac_feature = DISABLE_DBS_CXN_AND_SCAN; 3496 3497 if (!hdd_ctx) 3498 return QDF_STATUS_E_FAILURE; 3499 3500 /* 3501 * ROME platform doesn't support any DBS related commands in FW, 3502 * so if driver sends wmi command with dual_mac_config with all set to 3503 * 0 then FW wouldn't respond back and driver would timeout on waiting 3504 * for response. Check if FW supports DBS to eliminate ROME vs 3505 * NON-ROME platform. 3506 */ 3507 if (!policy_mgr_find_if_fw_supports_dbs(hdd_ctx->psoc)) 3508 return QDF_STATUS_SUCCESS; 3509 3510 if (hdd_ctx->is_dual_mac_cfg_updated) { 3511 hdd_debug("dual mac config has already been updated, skip"); 3512 return QDF_STATUS_SUCCESS; 3513 } 3514 3515 cfg.scan_config = 0; 3516 cfg.fw_mode_config = 0; 3517 cfg.set_dual_mac_cb = policy_mgr_soc_set_dual_mac_cfg_cb; 3518 if (policy_mgr_is_hw_dbs_capable(hdd_ctx->psoc)) { 3519 status = 3520 ucfg_policy_mgr_get_chnl_select_plcy(hdd_ctx->psoc, 3521 &chnl_sel_logic_conc); 3522 if (status != QDF_STATUS_SUCCESS) { 3523 hdd_err("can't get chnl sel policy, use def"); 3524 return status; 3525 } 3526 } 3527 status = 3528 ucfg_policy_mgr_get_dual_mac_feature(hdd_ctx->psoc, 3529 &dual_mac_feature); 3530 if (status != QDF_STATUS_SUCCESS) { 3531 hdd_err("ucfg_policy_mgr_get_dual_mac_feature failed, use def"); 3532 return status; 3533 } 3534 3535 if (dual_mac_feature != DISABLE_DBS_CXN_AND_SCAN) { 3536 status = policy_mgr_get_updated_scan_and_fw_mode_config( 3537 hdd_ctx->psoc, &cfg.scan_config, 3538 &cfg.fw_mode_config, 3539 dual_mac_feature, 3540 chnl_sel_logic_conc); 3541 3542 if (status != QDF_STATUS_SUCCESS) { 3543 hdd_err("wma_get_updated_scan_and_fw_mode_config failed %d", 3544 status); 3545 return status; 3546 } 3547 } 3548 3549 hdd_debug("send scan_cfg: 0x%x fw_mode_cfg: 0x%x to fw", 3550 cfg.scan_config, cfg.fw_mode_config); 3551 3552 status = sme_soc_set_dual_mac_config(cfg); 3553 if (QDF_IS_STATUS_ERROR(status)) { 3554 hdd_err("sme_soc_set_dual_mac_config failed %d", status); 3555 return status; 3556 } 3557 hdd_ctx->is_dual_mac_cfg_updated = true; 3558 3559 return QDF_STATUS_SUCCESS; 3560 } 3561 3562 /** 3563 * hdd_max_sta_interface_up_count_reached() - check sta/p2p_cli vdev count 3564 * @adapter: HDD adapter 3565 * 3566 * Return: true if vdev limit reached 3567 */ 3568 static bool hdd_max_sta_interface_up_count_reached(struct hdd_adapter *adapter) 3569 { 3570 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); 3571 struct hdd_adapter *temp_adapter = NULL, *next_adapter = NULL; 3572 uint8_t intf_count = 0; 3573 wlan_net_dev_ref_dbgid dbgid = 3574 NET_DEV_HOLD_MAX_STA_INTERFACE_UP_COUNT_REACHED; 3575 3576 if (0 == CFG_TGT_DEFAULT_MAX_STA_VDEVS) 3577 return false; 3578 3579 /* 3580 * Check for max no of supported STA/P2PCLI VDEVs before 3581 * creating another one. 3582 */ 3583 hdd_for_each_adapter_dev_held_safe(hdd_ctx, temp_adapter, 3584 next_adapter, dbgid) { 3585 if ((temp_adapter != adapter) && 3586 (temp_adapter->dev->flags & IFF_UP) && 3587 ((temp_adapter->device_mode == QDF_STA_MODE) || 3588 (temp_adapter->device_mode == QDF_P2P_CLIENT_MODE))) 3589 intf_count++; 3590 3591 hdd_adapter_dev_put_debug(temp_adapter, dbgid); 3592 } 3593 3594 if (intf_count >= CFG_TGT_DEFAULT_MAX_STA_VDEVS) { 3595 hdd_err("Max limit reached sta vdev-current %d max %d", 3596 intf_count, CFG_TGT_DEFAULT_MAX_STA_VDEVS); 3597 return true; 3598 } 3599 return false; 3600 } 3601 3602 #if (defined(WLAN_FEATURE_11BE_MLO) && defined(CFG80211_11BE_BASIC)) && \ 3603 (defined(CFG80211_IFTYPE_MLO_LINK_SUPPORT) || \ 3604 defined(CFG80211_SINGLE_NETDEV_MULTI_LINK_SUPPORT)) && \ 3605 !defined(WLAN_HDD_MULTI_VDEV_SINGLE_NDEV) 3606 static int hdd_start_link_adapter(struct hdd_adapter *sta_adapter) 3607 { 3608 int i, ret = 0; 3609 struct hdd_mlo_adapter_info *mlo_adapter_info; 3610 struct hdd_adapter *link_adapter; 3611 3612 hdd_enter_dev(sta_adapter->dev); 3613 mlo_adapter_info = &sta_adapter->mlo_adapter_info; 3614 3615 for (i = 0; i < WLAN_MAX_MLD; i++) { 3616 link_adapter = mlo_adapter_info->link_adapter[i]; 3617 if (!link_adapter) 3618 continue; 3619 if (link_adapter->mlo_adapter_info.associate_with_ml_adapter) { 3620 /* TODO have proper references here */ 3621 qdf_spin_lock_bh(&link_adapter->deflink->vdev_lock); 3622 link_adapter->deflink->vdev = 3623 sta_adapter->deflink->vdev; 3624 link_adapter->deflink->vdev_id = 3625 sta_adapter->deflink->vdev_id; 3626 qdf_spin_unlock_bh(&link_adapter->deflink->vdev_lock); 3627 3628 sta_adapter->link_info[i].vdev_id = 3629 sta_adapter->deflink->vdev_id; 3630 continue; 3631 } 3632 ret = hdd_start_station_adapter(link_adapter); 3633 if (!ret) { 3634 sta_adapter->link_info[i].vdev_id = 3635 link_adapter->deflink->vdev_id; 3636 } 3637 } 3638 3639 hdd_adapter_update_mlo_mgr_mac_addr(sta_adapter); 3640 3641 hdd_exit(); 3642 return ret; 3643 } 3644 3645 static int hdd_stop_link_adapter(struct hdd_context *hdd_ctx, 3646 struct hdd_adapter *sta_adapter) 3647 { 3648 int i, ret = 0; 3649 struct hdd_mlo_adapter_info *mlo_adapter_info; 3650 struct hdd_adapter *link_adapter; 3651 3652 hdd_enter_dev(sta_adapter->dev); 3653 hdd_debug("Stop adapter for link mode : %s(%d)", 3654 qdf_opmode_str(sta_adapter->device_mode), 3655 sta_adapter->deflink->vdev_id); 3656 3657 mlo_adapter_info = &sta_adapter->mlo_adapter_info; 3658 for (i = 0; i < WLAN_MAX_MLD; i++) { 3659 link_adapter = mlo_adapter_info->link_adapter[i]; 3660 if (!link_adapter) 3661 continue; 3662 3663 if (link_adapter->mlo_adapter_info.associate_with_ml_adapter) { 3664 /* TODO have proper references here */ 3665 qdf_spin_lock_bh(&link_adapter->deflink->vdev_lock); 3666 link_adapter->deflink->vdev = NULL; 3667 link_adapter->deflink->vdev_id = 0xff; 3668 qdf_spin_unlock_bh(&link_adapter->deflink->vdev_lock); 3669 continue; 3670 } 3671 ret = hdd_stop_adapter_ext(hdd_ctx, link_adapter); 3672 } 3673 3674 hdd_exit(); 3675 return ret; 3676 } 3677 #else 3678 static int hdd_start_link_adapter(struct hdd_adapter *link_adapter) 3679 { 3680 return 0; 3681 } 3682 3683 static int hdd_stop_link_adapter(struct hdd_context *hdd_ctx, 3684 struct hdd_adapter *link_adapter) 3685 { 3686 return 0; 3687 } 3688 #endif 3689 3690 /** 3691 * hdd_start_adapter() - Wrapper function for device specific adapter 3692 * @adapter: pointer to HDD adapter 3693 * @rtnl_held: true if rtnl lock is taken, otherwise false 3694 * 3695 * This function is called to start the device specific adapter for 3696 * the mode passed in the adapter's device_mode. 3697 * 3698 * Return: 0 for success; non-zero for failure 3699 */ 3700 int hdd_start_adapter(struct hdd_adapter *adapter, bool rtnl_held) 3701 { 3702 3703 int ret; 3704 enum QDF_OPMODE device_mode = adapter->device_mode; 3705 3706 hdd_enter_dev(adapter->dev); 3707 3708 switch (device_mode) { 3709 case QDF_MONITOR_MODE: 3710 ret = hdd_start_station_adapter(adapter); 3711 if (ret) 3712 goto err_start_adapter; 3713 hdd_set_idle_ps_config(adapter->hdd_ctx, false); 3714 break; 3715 case QDF_STA_MODE: 3716 case QDF_P2P_CLIENT_MODE: 3717 if (hdd_max_sta_interface_up_count_reached(adapter)) 3718 goto err_start_adapter; 3719 fallthrough; 3720 case QDF_P2P_DEVICE_MODE: 3721 case QDF_OCB_MODE: 3722 case QDF_NAN_DISC_MODE: 3723 ret = hdd_start_station_adapter(adapter); 3724 if (ret) 3725 goto err_start_adapter; 3726 3727 if (device_mode == QDF_STA_MODE) { 3728 ret = hdd_start_link_adapter(adapter); 3729 if (ret) 3730 hdd_err("Failed to start link adapter:%d", ret); 3731 } 3732 break; 3733 case QDF_P2P_GO_MODE: 3734 case QDF_SAP_MODE: 3735 ret = hdd_start_ap_adapter(adapter, rtnl_held); 3736 if (ret) 3737 goto err_start_adapter; 3738 break; 3739 case QDF_FTM_MODE: 3740 /* vdevs are dynamically managed by firmware in FTM */ 3741 hdd_register_wext(adapter->dev); 3742 goto exit_with_success; 3743 default: 3744 hdd_err("Invalid session type %d", device_mode); 3745 QDF_ASSERT(0); 3746 goto err_start_adapter; 3747 } 3748 3749 if (hdd_set_fw_params(adapter)) 3750 hdd_err("Failed to set the FW params for the adapter!"); 3751 3752 if (adapter->deflink->vdev_id != WLAN_UMAC_VDEV_ID_MAX) { 3753 ret = wlan_hdd_cfg80211_register_frames(adapter); 3754 if (ret < 0) { 3755 hdd_err("Failed to register frames - ret %d", ret); 3756 goto err_start_adapter; 3757 } 3758 } 3759 3760 wlan_hdd_update_dbs_scan_and_fw_mode_config(); 3761 3762 exit_with_success: 3763 hdd_create_adapter_sysfs_files(adapter); 3764 3765 hdd_exit(); 3766 3767 return 0; 3768 3769 err_start_adapter: 3770 return -EINVAL; 3771 } 3772 3773 void hdd_update_hw_sw_info(struct hdd_context *hdd_ctx) 3774 { 3775 void *hif_sc; 3776 size_t target_hw_name_len; 3777 const char *target_hw_name; 3778 uint8_t *buf; 3779 uint32_t buf_len; 3780 3781 hif_sc = cds_get_context(QDF_MODULE_ID_HIF); 3782 if (!hif_sc) 3783 return; 3784 3785 hif_get_hw_info(hif_sc, &hdd_ctx->target_hw_version, 3786 &hdd_ctx->target_hw_revision, 3787 &target_hw_name); 3788 3789 qdf_mem_zero(hdd_ctx->target_hw_name, MAX_TGT_HW_NAME_LEN); 3790 3791 target_hw_name_len = strlen(target_hw_name) + 1; 3792 3793 if (target_hw_name_len <= MAX_TGT_HW_NAME_LEN) { 3794 qdf_mem_copy(hdd_ctx->target_hw_name, target_hw_name, 3795 target_hw_name_len); 3796 } else { 3797 hdd_err("target_hw_name_len is greater than MAX_TGT_HW_NAME_LEN"); 3798 return; 3799 } 3800 3801 hdd_debug("target_hw_name = %s", hdd_ctx->target_hw_name); 3802 3803 buf = qdf_mem_malloc(WE_MAX_STR_LEN); 3804 if (buf) { 3805 buf_len = hdd_wlan_get_version(hdd_ctx, WE_MAX_STR_LEN, buf); 3806 hdd_nofl_debug("%s", buf); 3807 qdf_mem_free(buf); 3808 } 3809 } 3810 3811 /** 3812 * hdd_update_cds_ac_specs_params() - update cds ac_specs params 3813 * @hdd_ctx: Pointer to hdd context 3814 * 3815 * Return: none 3816 */ 3817 static void 3818 hdd_update_cds_ac_specs_params(struct hdd_context *hdd_ctx) 3819 { 3820 uint8_t tx_sched_wrr_param[TX_SCHED_WRR_PARAMS_NUM] = {0}; 3821 qdf_size_t out_size = 0; 3822 int i; 3823 struct cds_context *cds_ctx; 3824 3825 if (!hdd_ctx) 3826 return; 3827 3828 if (!hdd_ctx->config) { 3829 /* Do nothing if hdd_ctx is invalid */ 3830 hdd_err("Warning: hdd_ctx->cfg_ini is NULL"); 3831 return; 3832 } 3833 3834 cds_ctx = cds_get_context(QDF_MODULE_ID_QDF); 3835 if (!cds_ctx) 3836 return; 3837 3838 for (i = 0; i < QCA_WLAN_AC_ALL; i++) { 3839 switch (i) { 3840 case QCA_WLAN_AC_BE: 3841 qdf_uint8_array_parse( 3842 cfg_get(hdd_ctx->psoc, 3843 CFG_DP_ENABLE_TX_SCHED_WRR_BE), 3844 tx_sched_wrr_param, 3845 sizeof(tx_sched_wrr_param), 3846 &out_size); 3847 break; 3848 case QCA_WLAN_AC_BK: 3849 qdf_uint8_array_parse( 3850 cfg_get(hdd_ctx->psoc, 3851 CFG_DP_ENABLE_TX_SCHED_WRR_BK), 3852 tx_sched_wrr_param, 3853 sizeof(tx_sched_wrr_param), 3854 &out_size); 3855 break; 3856 case QCA_WLAN_AC_VI: 3857 qdf_uint8_array_parse( 3858 cfg_get(hdd_ctx->psoc, 3859 CFG_DP_ENABLE_TX_SCHED_WRR_VI), 3860 tx_sched_wrr_param, 3861 sizeof(tx_sched_wrr_param), 3862 &out_size); 3863 break; 3864 case QCA_WLAN_AC_VO: 3865 qdf_uint8_array_parse( 3866 cfg_get(hdd_ctx->psoc, 3867 CFG_DP_ENABLE_TX_SCHED_WRR_VO), 3868 tx_sched_wrr_param, 3869 sizeof(tx_sched_wrr_param), 3870 &out_size); 3871 break; 3872 default: 3873 break; 3874 } 3875 3876 if (out_size == TX_SCHED_WRR_PARAMS_NUM) { 3877 cds_ctx->ac_specs[i].wrr_skip_weight = 3878 tx_sched_wrr_param[0]; 3879 cds_ctx->ac_specs[i].credit_threshold = 3880 tx_sched_wrr_param[1]; 3881 cds_ctx->ac_specs[i].send_limit = 3882 tx_sched_wrr_param[2]; 3883 cds_ctx->ac_specs[i].credit_reserve = 3884 tx_sched_wrr_param[3]; 3885 cds_ctx->ac_specs[i].discard_weight = 3886 tx_sched_wrr_param[4]; 3887 } 3888 3889 out_size = 0; 3890 } 3891 } 3892 3893 uint32_t hdd_wlan_get_version(struct hdd_context *hdd_ctx, 3894 const size_t version_len, uint8_t *version) 3895 { 3896 uint32_t size; 3897 uint8_t reg_major = 0, reg_minor = 0, bdf_major = 0, bdf_minor = 0; 3898 struct target_psoc_info *tgt_hdl; 3899 3900 if (!hdd_ctx) { 3901 hdd_err("Invalid context, HDD context is null"); 3902 return 0; 3903 } 3904 3905 if (!version || version_len == 0) { 3906 hdd_err("Invalid buffer pointr or buffer len\n"); 3907 return 0; 3908 } 3909 tgt_hdl = wlan_psoc_get_tgt_if_handle(hdd_ctx->psoc); 3910 if (tgt_hdl) 3911 target_psoc_get_version_info(tgt_hdl, ®_major, ®_minor, 3912 &bdf_major, &bdf_minor); 3913 3914 size = scnprintf(version, version_len, 3915 "Host SW:%s, FW:%d.%d.%d.%d.%d.%d, HW:%s, Board ver: %x Ref design id: %x, Customer id: %x, Project id: %x, Board Data Rev: %x, REG DB: %u:%u, BDF REG DB: %u:%u", 3916 QWLAN_VERSIONSTR, 3917 hdd_ctx->fw_version_info.major_spid, 3918 hdd_ctx->fw_version_info.minor_spid, 3919 hdd_ctx->fw_version_info.siid, 3920 hdd_ctx->fw_version_info.rel_id, 3921 hdd_ctx->fw_version_info.crmid, 3922 hdd_ctx->fw_version_info.sub_id, 3923 hdd_ctx->target_hw_name, 3924 hdd_ctx->hw_bd_info.bdf_version, 3925 hdd_ctx->hw_bd_info.ref_design_id, 3926 hdd_ctx->hw_bd_info.customer_id, 3927 hdd_ctx->hw_bd_info.project_id, 3928 hdd_ctx->hw_bd_info.board_data_rev, 3929 reg_major, reg_minor, bdf_major, bdf_minor); 3930 3931 return size; 3932 } 3933 3934 int hdd_set_11ax_rate(struct hdd_adapter *adapter, int set_value, 3935 struct sap_config *sap_config) 3936 { 3937 uint8_t preamble = 0, nss = 0, rix = 0; 3938 int ret; 3939 mac_handle_t mac_handle = adapter->hdd_ctx->mac_handle; 3940 3941 if (!sap_config) { 3942 if (!sme_is_feature_supported_by_fw(DOT11AX)) { 3943 hdd_err("Target does not support 11ax"); 3944 return -EIO; 3945 } 3946 } else if (sap_config->SapHw_mode != eCSR_DOT11_MODE_11ax && 3947 sap_config->SapHw_mode != eCSR_DOT11_MODE_11ax_ONLY) { 3948 hdd_err("Invalid hw mode, SAP hw_mode= 0x%x, ch_freq = %d", 3949 sap_config->SapHw_mode, sap_config->chan_freq); 3950 return -EIO; 3951 } 3952 3953 if (set_value != 0xffff) { 3954 rix = RC_2_RATE_IDX_11AX(set_value); 3955 preamble = WMI_RATE_PREAMBLE_HE; 3956 nss = HT_RC_2_STREAMS_11AX(set_value); 3957 3958 set_value = hdd_assemble_rate_code(preamble, nss, rix); 3959 } else { 3960 ret = sme_set_auto_rate_he_ltf(mac_handle, 3961 adapter->deflink->vdev_id, 3962 QCA_WLAN_HE_LTF_AUTO); 3963 } 3964 3965 hdd_info("SET_11AX_RATE val %d rix %d preamble %x nss %d", 3966 set_value, rix, preamble, nss); 3967 3968 ret = wma_cli_set_command(adapter->deflink->vdev_id, 3969 wmi_vdev_param_fixed_rate, 3970 set_value, VDEV_CMD); 3971 3972 return ret; 3973 } 3974 3975 int hdd_assemble_rate_code(uint8_t preamble, uint8_t nss, uint8_t rate) 3976 { 3977 return ucfg_mlme_assemble_rate_code(preamble, nss, rate); 3978 } 3979 3980 #ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH 3981 static enum policy_mgr_con_mode wlan_hdd_get_mode_for_non_connected_vdev( 3982 struct wlan_objmgr_psoc *psoc, uint8_t vdev_id) 3983 { 3984 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 3985 struct hdd_adapter *adapter; 3986 enum policy_mgr_con_mode mode; 3987 struct wlan_hdd_link_info *link_info; 3988 3989 link_info = hdd_get_link_info_by_vdev(hdd_ctx, vdev_id); 3990 if (!link_info) { 3991 hdd_err("Invalid vdev"); 3992 return PM_MAX_NUM_OF_MODE; 3993 } 3994 3995 adapter = link_info->adapter; 3996 mode = policy_mgr_qdf_opmode_to_pm_con_mode(psoc, 3997 adapter->device_mode, 3998 vdev_id); 3999 return mode; 4000 } 4001 4002 /** 4003 * hdd_is_chan_switch_in_progress() - Check if any adapter has channel switch in 4004 * progress 4005 * 4006 * Return: true, if any adapter has channel switch in 4007 * progress else false 4008 */ 4009 static bool hdd_is_chan_switch_in_progress(void) 4010 { 4011 struct hdd_adapter *adapter = NULL, *next_adapter = NULL; 4012 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 4013 wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_IS_CHAN_SWITCH_IN_PROGRESS; 4014 struct hdd_ap_ctx *ap_ctx; 4015 struct wlan_hdd_link_info *link_info; 4016 bool is_restart; 4017 struct wlan_objmgr_vdev *vdev; 4018 4019 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 4020 dbgid) { 4021 if (adapter->device_mode != QDF_SAP_MODE && 4022 adapter->device_mode != QDF_P2P_GO_MODE) 4023 goto next_adapter; 4024 4025 hdd_adapter_for_each_active_link_info(adapter, link_info) { 4026 ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(link_info); 4027 vdev = hdd_objmgr_get_vdev_by_user(link_info, 4028 WLAN_OSIF_ID); 4029 if (!vdev) 4030 continue; 4031 is_restart = false; 4032 if (wlan_vdev_is_restart_progress(vdev) == 4033 QDF_STATUS_SUCCESS) { 4034 hdd_debug("vdev: %d restart in progress", 4035 wlan_vdev_get_id(vdev)); 4036 is_restart = true; 4037 } 4038 hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_ID); 4039 4040 if (is_restart || 4041 qdf_atomic_read(&ap_ctx->ch_switch_in_progress)) { 4042 hdd_debug("channel switch progress for vdev_id %d", 4043 link_info->vdev_id); 4044 hdd_adapter_dev_put_debug(adapter, dbgid); 4045 if (next_adapter) 4046 hdd_adapter_dev_put_debug(next_adapter, 4047 dbgid); 4048 return true; 4049 } 4050 } 4051 next_adapter: 4052 hdd_adapter_dev_put_debug(adapter, dbgid); 4053 } 4054 4055 return false; 4056 } 4057 4058 /** 4059 * hdd_is_cac_in_progress() - Check if any SAP connection is performing 4060 * CAC on DFS channel 4061 * 4062 * Return: true, if any of existing SAP is performing CAC 4063 * or else false 4064 */ 4065 static bool hdd_is_cac_in_progress(void) 4066 { 4067 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 4068 4069 if (!hdd_ctx) 4070 return false; 4071 4072 return (hdd_ctx->dev_dfs_cac_status == DFS_CAC_IN_PROGRESS); 4073 } 4074 4075 static void hdd_register_policy_manager_callback( 4076 struct wlan_objmgr_psoc *psoc) 4077 { 4078 struct policy_mgr_hdd_cbacks hdd_cbacks; 4079 4080 qdf_mem_zero(&hdd_cbacks, sizeof(hdd_cbacks)); 4081 hdd_cbacks.sap_restart_chan_switch_cb = 4082 hdd_sap_restart_chan_switch_cb; 4083 hdd_cbacks.wlan_hdd_get_channel_for_sap_restart = 4084 wlan_hdd_get_channel_for_sap_restart; 4085 hdd_cbacks.get_mode_for_non_connected_vdev = 4086 wlan_hdd_get_mode_for_non_connected_vdev; 4087 hdd_cbacks.hdd_get_device_mode = hdd_get_device_mode; 4088 hdd_cbacks.hdd_is_chan_switch_in_progress = 4089 hdd_is_chan_switch_in_progress; 4090 hdd_cbacks.hdd_is_cac_in_progress = 4091 hdd_is_cac_in_progress; 4092 hdd_cbacks.wlan_hdd_set_sap_csa_reason = 4093 wlan_hdd_set_sap_csa_reason; 4094 hdd_cbacks.hdd_get_ap_6ghz_capable = hdd_get_ap_6ghz_capable; 4095 hdd_cbacks.wlan_hdd_indicate_active_ndp_cnt = 4096 hdd_indicate_active_ndp_cnt; 4097 hdd_cbacks.wlan_get_ap_prefer_conc_ch_params = 4098 wlan_get_ap_prefer_conc_ch_params; 4099 hdd_cbacks.wlan_get_sap_acs_band = 4100 wlan_get_sap_acs_band; 4101 hdd_cbacks.wlan_check_cc_intf_cb = wlan_hdd_check_cc_intf_cb; 4102 4103 if (QDF_STATUS_SUCCESS != 4104 policy_mgr_register_hdd_cb(psoc, &hdd_cbacks)) { 4105 hdd_err("HDD callback registration with policy manager failed"); 4106 } 4107 } 4108 #else 4109 static void hdd_register_policy_manager_callback( 4110 struct wlan_objmgr_psoc *psoc) 4111 { 4112 } 4113 #endif 4114 4115 #ifdef WLAN_SUPPORT_GAP_LL_PS_MODE 4116 static void hdd_register_green_ap_callback(struct wlan_objmgr_pdev *pdev) 4117 { 4118 struct green_ap_hdd_callback hdd_cback; 4119 qdf_mem_zero(&hdd_cback, sizeof(hdd_cback)); 4120 4121 hdd_cback.send_event = wlan_hdd_send_green_ap_ll_ps_event; 4122 4123 if (QDF_STATUS_SUCCESS != 4124 green_ap_register_hdd_callback(pdev, &hdd_cback)) { 4125 hdd_err("HDD callback registration for Green AP failed"); 4126 } 4127 } 4128 #else 4129 static inline void hdd_register_green_ap_callback(struct wlan_objmgr_pdev *pdev) 4130 { 4131 } 4132 #endif 4133 4134 #ifdef WLAN_FEATURE_NAN 4135 #ifdef WLAN_FEATURE_SR 4136 static void hdd_register_sr_concurrency_cb(struct nan_callbacks *cb_obj) 4137 { 4138 cb_obj->nan_sr_concurrency_update = hdd_nan_sr_concurrency_update; 4139 } 4140 #else 4141 static void hdd_register_sr_concurrency_cb(struct nan_callbacks *cb_obj) 4142 {} 4143 #endif 4144 static void hdd_nan_register_callbacks(struct hdd_context *hdd_ctx) 4145 { 4146 struct nan_callbacks cb_obj = {0}; 4147 4148 cb_obj.ndi_open = hdd_ndi_open; 4149 cb_obj.ndi_close = hdd_ndi_close; 4150 cb_obj.ndi_set_mode = hdd_ndi_set_mode; 4151 cb_obj.ndi_start = hdd_ndi_start; 4152 cb_obj.ndi_delete = hdd_ndi_delete; 4153 cb_obj.drv_ndi_create_rsp_handler = hdd_ndi_drv_ndi_create_rsp_handler; 4154 cb_obj.drv_ndi_delete_rsp_handler = hdd_ndi_drv_ndi_delete_rsp_handler; 4155 4156 cb_obj.new_peer_ind = hdd_ndp_new_peer_handler; 4157 cb_obj.peer_departed_ind = hdd_ndp_peer_departed_handler; 4158 4159 cb_obj.nan_concurrency_update = hdd_nan_concurrency_update; 4160 cb_obj.set_mc_list = hdd_update_multicast_list; 4161 4162 hdd_register_sr_concurrency_cb(&cb_obj); 4163 4164 os_if_nan_register_hdd_callbacks(hdd_ctx->psoc, &cb_obj); 4165 } 4166 #else 4167 static inline void hdd_nan_register_callbacks(struct hdd_context *hdd_ctx) 4168 { 4169 } 4170 #endif 4171 4172 #ifdef CONFIG_LEAK_DETECTION 4173 /** 4174 * hdd_check_for_leaks() - Perform runtime memory leak checks 4175 * @hdd_ctx: the global HDD context 4176 * @is_ssr: true if SSR is in progress 4177 * 4178 * This API triggers runtime memory leak detection. This feature enforces the 4179 * policy that any memory allocated at runtime must also be released at runtime. 4180 * 4181 * Allocating memory at runtime and releasing it at unload is effectively a 4182 * memory leak for configurations which never unload (e.g. LONU, statically 4183 * compiled driver). Such memory leaks are NOT false positives, and must be 4184 * fixed. 4185 * 4186 * Return: None 4187 */ 4188 static void hdd_check_for_leaks(struct hdd_context *hdd_ctx, bool is_ssr) 4189 { 4190 /* DO NOT REMOVE these checks; for false positives, read above first */ 4191 4192 wlan_objmgr_psoc_check_for_leaks(hdd_ctx->psoc); 4193 4194 /* many adapter resources are not freed by design during SSR */ 4195 if (is_ssr) 4196 return; 4197 4198 qdf_wake_lock_check_for_leaks(); 4199 qdf_delayed_work_check_for_leaks(); 4200 qdf_mc_timer_check_for_leaks(); 4201 qdf_nbuf_map_check_for_leaks(); 4202 qdf_periodic_work_check_for_leaks(); 4203 qdf_mem_check_for_leaks(); 4204 } 4205 4206 /** 4207 * hdd_debug_domain_set() - Set qdf debug domain 4208 * @domain: debug domain to be set 4209 * 4210 * In the scenario of system reboot, it may have thread accessing debug domain 4211 * for memory allocation/free, other than the one trying to change it. 4212 * If debug domain is changed after a memory allocation but before the free, 4213 * it will hit debug domain mismatch assertion in memory free. 4214 * To avoid such assertion, skip debug domain transition if system reboot is 4215 * in progress. 4216 * 4217 * Return: 0 if the specified debug domain has been set, -EBUSY otherwise 4218 */ 4219 static int hdd_debug_domain_set(enum qdf_debug_domain domain) 4220 { 4221 int ret = 0; 4222 4223 if (cds_sys_reboot_protect()) { 4224 hdd_info("System is rebooting, skip debug domain transition"); 4225 ret = -EBUSY; 4226 } else { 4227 qdf_debug_domain_set(domain); 4228 } 4229 4230 cds_sys_reboot_unprotect(); 4231 4232 return ret; 4233 } 4234 4235 #define hdd_debug_domain_get() qdf_debug_domain_get() 4236 #else 4237 static void hdd_check_for_objmgr_peer_leaks(struct wlan_objmgr_psoc *psoc) 4238 { 4239 uint32_t vdev_id; 4240 struct wlan_objmgr_vdev *vdev; 4241 struct wlan_objmgr_peer *peer; 4242 4243 /* get module id which cause the leak and release ref */ 4244 wlan_objmgr_for_each_psoc_vdev(psoc, vdev_id, vdev) { 4245 wlan_objmgr_for_each_vdev_peer(vdev, peer) { 4246 qdf_atomic_t *ref_id_dbg; 4247 int ref_id; 4248 int32_t refs; 4249 4250 ref_id_dbg = vdev->vdev_objmgr.ref_id_dbg; 4251 wlan_objmgr_for_each_refs(ref_id_dbg, ref_id, refs) 4252 wlan_objmgr_peer_release_ref(peer, ref_id); 4253 } 4254 } 4255 } 4256 4257 static void hdd_check_for_objmgr_leaks(struct hdd_context *hdd_ctx) 4258 { 4259 uint32_t vdev_id, pdev_id; 4260 struct wlan_objmgr_psoc *psoc; 4261 struct wlan_objmgr_vdev *vdev; 4262 struct wlan_objmgr_pdev *pdev; 4263 /* 4264 * leak detection is disabled, force release the references for the wlan 4265 * to recover cleanly. 4266 */ 4267 psoc = hdd_ctx->psoc; 4268 if (!psoc) 4269 return; 4270 4271 4272 hdd_check_for_objmgr_peer_leaks(psoc); 4273 4274 wlan_objmgr_for_each_psoc_vdev(psoc, vdev_id, vdev) { 4275 qdf_atomic_t *ref_id_dbg; 4276 int ref_id; 4277 int32_t refs; 4278 4279 ref_id_dbg = vdev->vdev_objmgr.ref_id_dbg; 4280 wlan_objmgr_for_each_refs(ref_id_dbg, ref_id, refs) { 4281 wlan_objmgr_vdev_release_ref(vdev, ref_id); 4282 } 4283 } 4284 4285 wlan_objmgr_for_each_psoc_pdev(psoc, pdev_id, pdev) { 4286 qdf_atomic_t *ref_id_dbg; 4287 int ref_id; 4288 int32_t refs; 4289 4290 ref_id_dbg = pdev->pdev_objmgr.ref_id_dbg; 4291 wlan_objmgr_for_each_refs(ref_id_dbg, ref_id, refs) 4292 wlan_objmgr_pdev_release_ref(pdev, ref_id); 4293 } 4294 } 4295 4296 static void hdd_check_for_leaks(struct hdd_context *hdd_ctx, bool is_ssr) 4297 { 4298 hdd_check_for_objmgr_leaks(hdd_ctx); 4299 } 4300 4301 #define hdd_debug_domain_set(domain) 0 4302 #define hdd_debug_domain_get() DEFAULT_DEBUG_DOMAIN_INIT 4303 #endif /* CONFIG_LEAK_DETECTION */ 4304 4305 #ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE 4306 /** 4307 * hdd_skip_acs_scan_timer_handler() - skip ACS scan timer timeout handler 4308 * @data: pointer to struct hdd_context 4309 * 4310 * This function will reset acs_scan_status to eSAP_DO_NEW_ACS_SCAN. 4311 * Then new ACS request will do a fresh scan without reusing the cached 4312 * scan information. 4313 * 4314 * Return: void 4315 */ 4316 static void hdd_skip_acs_scan_timer_handler(void *data) 4317 { 4318 struct hdd_context *hdd_ctx = data; 4319 mac_handle_t mac_handle; 4320 4321 hdd_debug("ACS Scan result expired. Reset ACS scan skip"); 4322 hdd_ctx->skip_acs_scan_status = eSAP_DO_NEW_ACS_SCAN; 4323 qdf_spin_lock(&hdd_ctx->acs_skip_lock); 4324 qdf_mem_free(hdd_ctx->last_acs_freq_list); 4325 hdd_ctx->last_acs_freq_list = NULL; 4326 hdd_ctx->num_of_channels = 0; 4327 qdf_spin_unlock(&hdd_ctx->acs_skip_lock); 4328 4329 mac_handle = hdd_ctx->mac_handle; 4330 if (!mac_handle) 4331 return; 4332 } 4333 4334 static void hdd_skip_acs_scan_timer_init(struct hdd_context *hdd_ctx) 4335 { 4336 QDF_STATUS status; 4337 4338 status = qdf_mc_timer_init(&hdd_ctx->skip_acs_scan_timer, 4339 QDF_TIMER_TYPE_SW, 4340 hdd_skip_acs_scan_timer_handler, 4341 hdd_ctx); 4342 if (QDF_IS_STATUS_ERROR(status)) 4343 hdd_err("Failed to init ACS Skip timer"); 4344 qdf_spinlock_create(&hdd_ctx->acs_skip_lock); 4345 } 4346 4347 static void hdd_skip_acs_scan_timer_deinit(struct hdd_context *hdd_ctx) 4348 { 4349 if (QDF_TIMER_STATE_RUNNING == 4350 qdf_mc_timer_get_current_state(&hdd_ctx->skip_acs_scan_timer)) { 4351 qdf_mc_timer_stop(&hdd_ctx->skip_acs_scan_timer); 4352 } 4353 4354 if (!QDF_IS_STATUS_SUCCESS 4355 (qdf_mc_timer_destroy(&hdd_ctx->skip_acs_scan_timer))) { 4356 hdd_err("Cannot deallocate ACS Skip timer"); 4357 } 4358 qdf_spin_lock(&hdd_ctx->acs_skip_lock); 4359 qdf_mem_free(hdd_ctx->last_acs_freq_list); 4360 hdd_ctx->last_acs_freq_list = NULL; 4361 hdd_ctx->num_of_channels = 0; 4362 qdf_spin_unlock(&hdd_ctx->acs_skip_lock); 4363 } 4364 #else 4365 static void hdd_skip_acs_scan_timer_init(struct hdd_context *hdd_ctx) {} 4366 static void hdd_skip_acs_scan_timer_deinit(struct hdd_context *hdd_ctx) {} 4367 #endif 4368 4369 /** 4370 * hdd_update_country_code - Update country code 4371 * @hdd_ctx: HDD context 4372 * 4373 * Update country code based on module parameter country_code 4374 * 4375 * Return: 0 on success and errno on failure 4376 */ 4377 int hdd_update_country_code(struct hdd_context *hdd_ctx) 4378 { 4379 if (!country_code || 4380 !ucfg_reg_is_user_country_set_allowed(hdd_ctx->psoc)) 4381 return 0; 4382 4383 return hdd_reg_set_country(hdd_ctx, country_code); 4384 } 4385 4386 #ifdef WLAN_NS_OFFLOAD 4387 /** 4388 * hdd_wlan_unregister_ip6_notifier() - unregister IPv6 change notifier 4389 * @hdd_ctx: Pointer to hdd context 4390 * 4391 * Unregister for IPv6 address change notifications. 4392 * 4393 * Return: None 4394 */ 4395 static void hdd_wlan_unregister_ip6_notifier(struct hdd_context *hdd_ctx) 4396 { 4397 unregister_inet6addr_notifier(&hdd_ctx->ipv6_notifier); 4398 } 4399 4400 /** 4401 * hdd_wlan_register_ip6_notifier() - register IPv6 change notifier 4402 * @hdd_ctx: Pointer to hdd context 4403 * 4404 * Register for IPv6 address change notifications. 4405 * 4406 * Return: 0 on success and errno on failure. 4407 */ 4408 static int hdd_wlan_register_ip6_notifier(struct hdd_context *hdd_ctx) 4409 { 4410 int ret; 4411 4412 hdd_ctx->ipv6_notifier.notifier_call = wlan_hdd_ipv6_changed; 4413 ret = register_inet6addr_notifier(&hdd_ctx->ipv6_notifier); 4414 if (ret) { 4415 hdd_err("Failed to register IPv6 notifier: %d", ret); 4416 goto out; 4417 } 4418 4419 hdd_debug("Registered IPv6 notifier"); 4420 out: 4421 return ret; 4422 } 4423 #else 4424 /** 4425 * hdd_wlan_unregister_ip6_notifier() - unregister IPv6 change notifier 4426 * @hdd_ctx: Pointer to hdd context 4427 * 4428 * Unregister for IPv6 address change notifications. 4429 * 4430 * Return: None 4431 */ 4432 static void hdd_wlan_unregister_ip6_notifier(struct hdd_context *hdd_ctx) 4433 { 4434 } 4435 4436 /** 4437 * hdd_wlan_register_ip6_notifier() - register IPv6 change notifier 4438 * @hdd_ctx: Pointer to hdd context 4439 * 4440 * Register for IPv6 address change notifications. 4441 * 4442 * Return: None 4443 */ 4444 static int hdd_wlan_register_ip6_notifier(struct hdd_context *hdd_ctx) 4445 { 4446 return 0; 4447 } 4448 #endif 4449 4450 #ifdef FEATURE_RUNTIME_PM 4451 #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 7, 0) 4452 static int hdd_pm_qos_add_notifier(struct hdd_context *hdd_ctx) 4453 { 4454 return dev_pm_qos_add_notifier(hdd_ctx->parent_dev, 4455 &hdd_ctx->pm_qos_notifier, 4456 DEV_PM_QOS_RESUME_LATENCY); 4457 } 4458 4459 static int hdd_pm_qos_remove_notifier(struct hdd_context *hdd_ctx) 4460 { 4461 return dev_pm_qos_remove_notifier(hdd_ctx->parent_dev, 4462 &hdd_ctx->pm_qos_notifier, 4463 DEV_PM_QOS_RESUME_LATENCY); 4464 } 4465 #else 4466 static int hdd_pm_qos_add_notifier(struct hdd_context *hdd_ctx) 4467 { 4468 return pm_qos_add_notifier(PM_QOS_CPU_DMA_LATENCY, 4469 &hdd_ctx->pm_qos_notifier); 4470 } 4471 4472 static int hdd_pm_qos_remove_notifier(struct hdd_context *hdd_ctx) 4473 { 4474 return pm_qos_remove_notifier(PM_QOS_CPU_DMA_LATENCY, 4475 &hdd_ctx->pm_qos_notifier); 4476 } 4477 #endif 4478 4479 /** 4480 * hdd_wlan_register_pm_qos_notifier() - register PM QOS notifier 4481 * @hdd_ctx: Pointer to hdd context 4482 * 4483 * Register for PM QOS change notifications. 4484 * 4485 * Return: None 4486 */ 4487 static int hdd_wlan_register_pm_qos_notifier(struct hdd_context *hdd_ctx) 4488 { 4489 int ret; 4490 4491 qdf_spinlock_create(&hdd_ctx->pm_qos_lock); 4492 4493 /* if gRuntimePM is 1 then feature is enabled without CXPC */ 4494 if (hdd_ctx->config->runtime_pm != hdd_runtime_pm_dynamic) { 4495 hdd_debug("Dynamic Runtime PM disabled"); 4496 return 0; 4497 } 4498 4499 hdd_ctx->pm_qos_notifier.notifier_call = wlan_hdd_pm_qos_notify; 4500 ret = hdd_pm_qos_add_notifier(hdd_ctx); 4501 if (ret) 4502 hdd_err("Failed to register PM_QOS notifier: %d", ret); 4503 else 4504 hdd_debug("PM QOS Notifier registered"); 4505 4506 return ret; 4507 } 4508 4509 /** 4510 * hdd_wlan_unregister_pm_qos_notifier() - unregister PM QOS notifier 4511 * @hdd_ctx: Pointer to hdd context 4512 * 4513 * Unregister for PM QOS change notifications. 4514 * 4515 * Return: None 4516 */ 4517 static void hdd_wlan_unregister_pm_qos_notifier(struct hdd_context *hdd_ctx) 4518 { 4519 int ret; 4520 4521 if (hdd_ctx->config->runtime_pm != hdd_runtime_pm_dynamic) { 4522 hdd_debug("Dynamic Runtime PM disabled"); 4523 qdf_spinlock_destroy(&hdd_ctx->pm_qos_lock); 4524 return; 4525 } 4526 4527 ret = hdd_pm_qos_remove_notifier(hdd_ctx); 4528 if (ret) 4529 hdd_warn("Failed to remove qos notifier, err = %d\n", ret); 4530 4531 qdf_spin_lock_irqsave(&hdd_ctx->pm_qos_lock); 4532 4533 if (hdd_ctx->runtime_pm_prevented) { 4534 hif_rtpm_put(HIF_RTPM_PUT_NOIDLE, HIF_RTPM_ID_PM_QOS_NOTIFY); 4535 hdd_ctx->runtime_pm_prevented = false; 4536 } 4537 4538 qdf_spin_unlock_irqrestore(&hdd_ctx->pm_qos_lock); 4539 4540 qdf_spinlock_destroy(&hdd_ctx->pm_qos_lock); 4541 } 4542 #else 4543 static int hdd_wlan_register_pm_qos_notifier(struct hdd_context *hdd_ctx) 4544 { 4545 return 0; 4546 } 4547 4548 static void hdd_wlan_unregister_pm_qos_notifier(struct hdd_context *hdd_ctx) 4549 { 4550 } 4551 #endif 4552 4553 /** 4554 * hdd_enable_power_management() - API to Enable Power Management 4555 * @hdd_ctx: HDD context 4556 * 4557 * API invokes Bus Interface Layer power management functionality 4558 * 4559 * Return: None 4560 */ 4561 static void hdd_enable_power_management(struct hdd_context *hdd_ctx) 4562 { 4563 void *hif_ctx = cds_get_context(QDF_MODULE_ID_HIF); 4564 4565 if (!hif_ctx) 4566 return; 4567 4568 hif_enable_power_management(hif_ctx, cds_is_packet_log_enabled()); 4569 hdd_wlan_register_pm_qos_notifier(hdd_ctx); 4570 } 4571 4572 /** 4573 * hdd_disable_power_management() - API to disable Power Management 4574 * @hdd_ctx: HDD context 4575 * 4576 * API disable Bus Interface Layer Power management functionality 4577 * 4578 * Return: None 4579 */ 4580 static void hdd_disable_power_management(struct hdd_context *hdd_ctx) 4581 { 4582 void *hif_ctx = cds_get_context(QDF_MODULE_ID_HIF); 4583 4584 if (!hif_ctx) 4585 return; 4586 4587 hdd_wlan_unregister_pm_qos_notifier(hdd_ctx); 4588 hif_disable_power_management(hif_ctx); 4589 } 4590 4591 /** 4592 * hdd_register_notifiers - Register netdev notifiers. 4593 * @hdd_ctx: HDD context 4594 * 4595 * Register netdev notifiers like IPv4 and IPv6. 4596 * 4597 * Return: 0 on success and errno on failure 4598 */ 4599 static int hdd_register_notifiers(struct hdd_context *hdd_ctx) 4600 { 4601 int ret; 4602 4603 ret = hdd_wlan_register_ip6_notifier(hdd_ctx); 4604 if (ret) 4605 goto out; 4606 4607 hdd_ctx->ipv4_notifier.notifier_call = wlan_hdd_ipv4_changed; 4608 ret = register_inetaddr_notifier(&hdd_ctx->ipv4_notifier); 4609 if (ret) { 4610 hdd_err("Failed to register IPv4 notifier: %d", ret); 4611 goto unregister_ip6_notifier; 4612 } 4613 4614 ret = osif_dp_nud_register_netevent_notifier(hdd_ctx->psoc); 4615 if (ret) { 4616 hdd_err("Failed to register netevent notifier: %d", 4617 ret); 4618 goto unregister_inetaddr_notifier; 4619 } 4620 4621 return 0; 4622 4623 unregister_inetaddr_notifier: 4624 unregister_inetaddr_notifier(&hdd_ctx->ipv4_notifier); 4625 unregister_ip6_notifier: 4626 hdd_wlan_unregister_ip6_notifier(hdd_ctx); 4627 out: 4628 return ret; 4629 } 4630 4631 #ifdef WLAN_FEATURE_WMI_SEND_RECV_QMI 4632 static inline 4633 void hdd_set_qmi_stats_enabled(struct hdd_context *hdd_ctx) 4634 { 4635 wmi_unified_t wmi_handle = get_wmi_unified_hdl_from_psoc(hdd_ctx->psoc); 4636 4637 if (!wmi_handle) { 4638 hdd_err("could not get wmi handle"); 4639 return; 4640 } 4641 4642 wmi_set_qmi_stats(wmi_handle, hdd_ctx->config->is_qmi_stats_enabled); 4643 } 4644 #else 4645 static inline 4646 void hdd_set_qmi_stats_enabled(struct hdd_context *hdd_ctx) 4647 { 4648 } 4649 #endif 4650 4651 #ifdef CONFIG_FW_LOGS_BASED_ON_INI 4652 /** 4653 * hdd_set_fw_log_params() - Set log parameters to FW 4654 * @hdd_ctx: HDD Context 4655 * @vdev_id: vdev_id 4656 * 4657 * This function set the FW Debug log level based on the INI. 4658 * 4659 * Return: None 4660 */ 4661 static void hdd_set_fw_log_params(struct hdd_context *hdd_ctx, 4662 uint8_t vdev_id) 4663 { 4664 QDF_STATUS status; 4665 uint16_t enable_fw_log_level, enable_fw_log_type; 4666 int ret; 4667 4668 if (!hdd_ctx->config->enable_fw_log) { 4669 hdd_debug("enable_fw_log not enabled in INI"); 4670 return; 4671 } 4672 4673 /* Enable FW logs based on INI configuration */ 4674 status = ucfg_fwol_get_enable_fw_log_type(hdd_ctx->psoc, 4675 &enable_fw_log_type); 4676 if (QDF_IS_STATUS_ERROR(status)) 4677 return; 4678 ret = sme_cli_set_command(vdev_id, WMI_DBGLOG_TYPE, 4679 enable_fw_log_type, DBG_CMD); 4680 if (ret != 0) 4681 hdd_err("Failed to enable FW log type ret %d", ret); 4682 4683 status = ucfg_fwol_get_enable_fw_log_level(hdd_ctx->psoc, 4684 &enable_fw_log_level); 4685 if (QDF_IS_STATUS_ERROR(status)) 4686 return; 4687 ret = sme_cli_set_command(vdev_id, WMI_DBGLOG_LOG_LEVEL, 4688 enable_fw_log_level, DBG_CMD); 4689 if (ret != 0) 4690 hdd_err("Failed to enable FW log level ret %d", ret); 4691 4692 sme_enable_fw_module_log_level(hdd_ctx->mac_handle, vdev_id); 4693 } 4694 #else 4695 static void hdd_set_fw_log_params(struct hdd_context *hdd_ctx, uint8_t vdev_id) 4696 { 4697 } 4698 4699 #endif 4700 4701 /** 4702 * hdd_features_deinit() - Deinit features 4703 * @hdd_ctx: HDD context 4704 * 4705 * De-Initialize features and their feature context. 4706 * 4707 * Return: none. 4708 */ 4709 static void hdd_features_deinit(struct hdd_context *hdd_ctx) 4710 { 4711 wlan_hdd_gpio_wakeup_deinit(hdd_ctx); 4712 wlan_hdd_twt_deinit(hdd_ctx); 4713 wlan_hdd_deinit_chan_info(hdd_ctx); 4714 wlan_hdd_tsf_deinit(hdd_ctx); 4715 if (cds_is_packet_log_enabled()) 4716 hdd_pktlog_enable_disable(hdd_ctx, false, 0, 0); 4717 } 4718 4719 /** 4720 * hdd_deconfigure_cds() -De-Configure cds 4721 * @hdd_ctx: HDD context 4722 * 4723 * Deconfigure Cds modules before WLAN firmware is down. 4724 * 4725 * Return: 0 on success and errno on failure. 4726 */ 4727 static int hdd_deconfigure_cds(struct hdd_context *hdd_ctx) 4728 { 4729 QDF_STATUS qdf_status; 4730 int ret = 0; 4731 4732 hdd_enter(); 4733 4734 wlan_hdd_hang_event_notifier_unregister(); 4735 /* De-init features */ 4736 hdd_features_deinit(hdd_ctx); 4737 4738 qdf_status = policy_mgr_deregister_mode_change_cb(hdd_ctx->psoc); 4739 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) 4740 hdd_debug("Failed to deregister mode change cb with Policy Manager"); 4741 4742 qdf_status = cds_disable(hdd_ctx->psoc); 4743 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { 4744 hdd_err("Failed to Disable the CDS Modules! :%d", 4745 qdf_status); 4746 ret = -EINVAL; 4747 } 4748 4749 if (ucfg_ipa_uc_ol_deinit(hdd_ctx->pdev) != QDF_STATUS_SUCCESS) { 4750 hdd_err("Failed to disconnect pipes"); 4751 ret = -EINVAL; 4752 } 4753 4754 hdd_exit(); 4755 return ret; 4756 } 4757 4758 /** 4759 * hdd_qmi_register_callbacks() - Register QMI callbacks 4760 * @hdd_ctx: HDD context 4761 * 4762 * Return: None 4763 */ 4764 static inline void hdd_qmi_register_callbacks(struct hdd_context *hdd_ctx) 4765 { 4766 struct wlan_qmi_psoc_callbacks cb_obj; 4767 4768 os_if_qmi_register_callbacks(hdd_ctx->psoc, &cb_obj); 4769 } 4770 4771 /** 4772 * hdd_set_pcie_params() - Set pcie params 4773 * @hdd_ctx: HDD context 4774 * @index: index value 4775 * @param: pointer to vdev/pdev set param info 4776 * 4777 * Checks for pcie_config value and sets 4778 * corresponding params 4779 * 4780 * Return: 0 on success and errno on failure. 4781 */ 4782 static int hdd_set_pcie_params(struct hdd_context *hdd_ctx, 4783 uint8_t index, struct dev_set_param *param) 4784 { 4785 int ret = 0; 4786 uint8_t check_value = 0; 4787 4788 ret = ucfg_fwol_get_pcie_config(hdd_ctx->psoc, &check_value); 4789 if (QDF_IS_STATUS_SUCCESS(ret)) { 4790 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) { 4791 ret = mlme_check_index_setparam(param, 4792 wmi_pdev_param_pcie_config, 4793 (int)check_value, index++, 4794 FTM_MAX_PDEV_PARAMS); 4795 } else { 4796 ret = mlme_check_index_setparam(param, 4797 wmi_pdev_param_pcie_config, 4798 (int)check_value, index++, 4799 MAX_PDEV_PRE_ENABLE_PARAMS); 4800 } 4801 if (QDF_IS_STATUS_ERROR(ret)) { 4802 hdd_err("failed to set wmi_pdev_param_pcie_config"); 4803 return ret; 4804 } 4805 } 4806 return ret; 4807 } 4808 4809 #ifdef FEATURE_SET 4810 #ifdef WLAN_FEATURE_11BE 4811 /** 4812 * hdd_is_cfg_dot11_mode_11be() - Check if dot11 mode is 11 be 4813 * @dot11_mode: Input dot11_mode which needs to be checked 4814 * 4815 * Return: True, ifinput dot11_mode is 11be dot11 mode else return false 4816 */ 4817 static bool hdd_is_cfg_dot11_mode_11be(enum hdd_dot11_mode dot11_mode) 4818 { 4819 return (dot11_mode == eHDD_DOT11_MODE_11be || 4820 dot11_mode == eHDD_DOT11_MODE_11be_ONLY); 4821 } 4822 4823 /** 4824 * hdd_is_11be_supported() - Check if 11be is supported or not 4825 * @hdd_ctx: Pointer to hdd context 4826 * 4827 * Return: True, if 11be is supported else return false 4828 */ 4829 static bool hdd_is_11be_supported(struct hdd_context *hdd_ctx) 4830 { 4831 bool mlo_capab; 4832 4833 ucfg_psoc_mlme_get_11be_capab(hdd_ctx->psoc, &mlo_capab); 4834 if (!mlo_capab) 4835 return false; 4836 4837 return true; 4838 } 4839 #else 4840 4841 static bool hdd_is_cfg_dot11_mode_11be(enum hdd_dot11_mode dot11_mode) 4842 { 4843 return false; 4844 } 4845 4846 static bool hdd_is_11be_supported(struct hdd_context *hdd_ctx) 4847 { 4848 return false; 4849 } 4850 #endif 4851 4852 WMI_HOST_WIFI_STANDARD 4853 hdd_get_wifi_standard(struct hdd_context *hdd_ctx, 4854 enum hdd_dot11_mode dot11_mode, uint32_t band_capability) 4855 { 4856 WMI_HOST_WIFI_STANDARD wifi_standard = WMI_HOST_WIFI_STANDARD_4; 4857 4858 if (dot11_mode == eHDD_DOT11_MODE_AUTO) { 4859 if (hdd_is_11be_supported(hdd_ctx)) 4860 wifi_standard = WMI_HOST_WIFI_STANDARD_7; 4861 else if (band_capability & BIT(REG_BAND_6G)) 4862 wifi_standard = WMI_HOST_WIFI_STANDARD_6E; 4863 else 4864 wifi_standard = WMI_HOST_WIFI_STANDARD_6; 4865 } else if (hdd_is_cfg_dot11_mode_11be(dot11_mode)) { 4866 wifi_standard = WMI_HOST_WIFI_STANDARD_7; 4867 } else if (dot11_mode == eHDD_DOT11_MODE_11ax || 4868 (dot11_mode == eHDD_DOT11_MODE_11ax_ONLY)) { 4869 if (band_capability & BIT(REG_BAND_6G)) 4870 wifi_standard = WMI_HOST_WIFI_STANDARD_6E; 4871 else 4872 wifi_standard = WMI_HOST_WIFI_STANDARD_6; 4873 } else if ((dot11_mode == eHDD_DOT11_MODE_11ac) || 4874 (dot11_mode == eHDD_DOT11_MODE_11ac_ONLY)) { 4875 wifi_standard = WMI_HOST_WIFI_STANDARD_5; 4876 } 4877 4878 return wifi_standard; 4879 } 4880 4881 /** 4882 * hdd_populate_feature_set_cds_config() - Populate cds feature set config 4883 * @hdd_ctx: hdd context pointer 4884 * 4885 * Return: None 4886 */ 4887 static void hdd_populate_feature_set_cds_config(struct hdd_context *hdd_ctx) 4888 { 4889 struct wlan_objmgr_psoc *psoc; 4890 uint32_t band_capability; 4891 QDF_STATUS status; 4892 struct cds_config_info *cds_cfg; 4893 4894 if (!hdd_ctx) 4895 return; 4896 4897 cds_cfg = cds_get_ini_config(); 4898 if (!cds_cfg) { 4899 hdd_err("CDS config is null."); 4900 return; 4901 } 4902 4903 psoc = hdd_ctx->psoc; 4904 4905 cds_cfg->get_wifi_features = hdd_ctx->config->get_wifi_features; 4906 4907 status = ucfg_mlme_get_band_capability(hdd_ctx->psoc, &band_capability); 4908 if (QDF_IS_STATUS_ERROR(status)) 4909 hdd_err("Failed to get MLME band capability"); 4910 4911 band_capability = 4912 hdd_update_band_cap_from_dot11mode(hdd_ctx, band_capability); 4913 4914 cds_cfg->cds_feature_set.wifi_standard = 4915 hdd_get_wifi_standard(hdd_ctx, 4916 hdd_ctx->config->dot11Mode, 4917 band_capability); 4918 4919 cds_cfg->cds_feature_set.sap_5g_supported = 4920 band_capability & BIT(REG_BAND_5G); 4921 4922 cds_cfg->cds_feature_set.sap_6g_supported = 4923 band_capability & BIT(REG_BAND_6G); 4924 cds_cfg->cds_feature_set.band_capability = band_capability; 4925 } 4926 #else 4927 WMI_HOST_WIFI_STANDARD 4928 hdd_get_wifi_standard(struct hdd_context *hdd_ctx, 4929 enum hdd_dot11_mode dot11_mode, uint32_t band_capability) 4930 { 4931 return WMI_HOST_WIFI_STANDARD_5; 4932 } 4933 4934 static inline void 4935 hdd_populate_feature_set_cds_config(struct hdd_context *hdd_ctx) 4936 { 4937 } 4938 #endif 4939 4940 int hdd_wlan_start_modules(struct hdd_context *hdd_ctx, bool reinit) 4941 { 4942 int ret = 0; 4943 qdf_device_t qdf_dev; 4944 QDF_STATUS status; 4945 bool unint = false; 4946 void *hif_ctx; 4947 struct target_psoc_info *tgt_hdl; 4948 unsigned long thermal_state = 0; 4949 uint8_t index = 0; 4950 struct dev_set_param setparam[MAX_PDEV_PRE_ENABLE_PARAMS] = {}; 4951 4952 hdd_enter(); 4953 qdf_dev = cds_get_context(QDF_MODULE_ID_QDF_DEVICE); 4954 if (!qdf_dev) { 4955 hdd_exit(); 4956 return -EINVAL; 4957 } 4958 4959 hdd_psoc_idle_timer_stop(hdd_ctx); 4960 4961 if (hdd_ctx->driver_status == DRIVER_MODULES_ENABLED) { 4962 hdd_debug("Driver modules already Enabled"); 4963 hdd_exit(); 4964 return 0; 4965 } 4966 4967 cds_set_driver_state_module_stop(false); 4968 4969 switch (hdd_ctx->driver_status) { 4970 case DRIVER_MODULES_UNINITIALIZED: 4971 hdd_nofl_debug("Wlan transitioning (UNINITIALIZED -> CLOSED)"); 4972 unint = true; 4973 fallthrough; 4974 case DRIVER_MODULES_CLOSED: 4975 hdd_nofl_debug("Wlan transitioning (CLOSED -> ENABLED)"); 4976 ret = hdd_debug_domain_set(QDF_DEBUG_DOMAIN_ACTIVE); 4977 if (ret) 4978 goto abort; 4979 4980 if (!reinit && !unint) { 4981 ret = pld_power_on(qdf_dev->dev); 4982 if (ret) { 4983 hdd_err("Failed to power up device; errno:%d", 4984 ret); 4985 goto release_lock; 4986 } 4987 } 4988 4989 hdd_init_adapter_ops_wq(hdd_ctx); 4990 pld_set_fw_log_mode(hdd_ctx->parent_dev, 4991 hdd_ctx->config->enable_fw_log); 4992 ret = hdd_hif_open(qdf_dev->dev, qdf_dev->drv_hdl, qdf_dev->bid, 4993 qdf_dev->bus_type, 4994 (reinit == true) ? HIF_ENABLE_TYPE_REINIT : 4995 HIF_ENABLE_TYPE_PROBE); 4996 if (ret) { 4997 hdd_err("Failed to open hif; errno: %d", ret); 4998 goto power_down; 4999 } 5000 5001 hif_ctx = cds_get_context(QDF_MODULE_ID_HIF); 5002 if (!hif_ctx) { 5003 ret = -EINVAL; 5004 goto power_down; 5005 } 5006 5007 status = ol_cds_init(qdf_dev, hif_ctx); 5008 if (status != QDF_STATUS_SUCCESS) { 5009 hdd_err("No Memory to Create BMI Context; status: %d", 5010 status); 5011 ret = qdf_status_to_os_return(status); 5012 goto hif_close; 5013 } 5014 5015 if (hdd_get_conparam() == QDF_GLOBAL_EPPING_MODE) { 5016 status = epping_open(); 5017 if (status) { 5018 hdd_err("Failed to open in epping mode: %d", 5019 status); 5020 ret = -EINVAL; 5021 goto cds_free; 5022 } 5023 5024 status = epping_enable(qdf_dev->dev, false); 5025 if (status) { 5026 hdd_err("Failed to enable in epping mode : %d", 5027 status); 5028 epping_close(); 5029 goto cds_free; 5030 } 5031 5032 hdd_info("epping mode enabled"); 5033 break; 5034 } 5035 5036 if (pld_is_ipa_offload_disabled(qdf_dev->dev)) 5037 ucfg_ipa_set_pld_enable(false); 5038 5039 ucfg_ipa_component_config_update(hdd_ctx->psoc); 5040 5041 hdd_update_cds_ac_specs_params(hdd_ctx); 5042 5043 hdd_dp_register_callbacks(hdd_ctx); 5044 5045 hdd_qmi_register_callbacks(hdd_ctx); 5046 5047 status = hdd_component_psoc_open(hdd_ctx->psoc); 5048 if (QDF_IS_STATUS_ERROR(status)) { 5049 hdd_err("Failed to Open legacy components; status: %d", 5050 status); 5051 ret = qdf_status_to_os_return(status); 5052 goto ipa_component_free; 5053 } 5054 5055 ret = hdd_update_config(hdd_ctx); 5056 if (ret) { 5057 hdd_err("Failed to update configuration; errno: %d", 5058 ret); 5059 goto ipa_component_free; 5060 } 5061 5062 status = wbuff_module_init(); 5063 if (QDF_IS_STATUS_ERROR(status)) 5064 hdd_err("WBUFF init unsuccessful; status: %d", status); 5065 5066 status = cds_open(hdd_ctx->psoc); 5067 if (QDF_IS_STATUS_ERROR(status)) { 5068 hdd_err("Failed to Open CDS; status: %d", status); 5069 ret = qdf_status_to_os_return(status); 5070 goto psoc_close; 5071 } 5072 5073 hdd_populate_feature_set_cds_config(hdd_ctx); 5074 5075 hdd_set_qmi_stats_enabled(hdd_ctx); 5076 5077 hdd_ctx->mac_handle = cds_get_context(QDF_MODULE_ID_SME); 5078 5079 ucfg_dp_set_rx_thread_affinity(hdd_ctx->psoc); 5080 5081 /* initialize components configurations after psoc open */ 5082 ret = hdd_update_components_config(hdd_ctx); 5083 if (ret) { 5084 hdd_err("Failed to update component configs; errno: %d", 5085 ret); 5086 goto close; 5087 } 5088 5089 /* Override PS params for monitor mode */ 5090 if (hdd_get_conparam() == QDF_GLOBAL_MONITOR_MODE) 5091 hdd_override_all_ps(hdd_ctx); 5092 5093 status = cds_dp_open(hdd_ctx->psoc); 5094 if (!QDF_IS_STATUS_SUCCESS(status)) { 5095 hdd_err("Failed to Open cds post open; status: %d", 5096 status); 5097 ret = qdf_status_to_os_return(status); 5098 goto close; 5099 } 5100 /* Set IRQ affinity for WLAN DP and CE IRQS */ 5101 hif_config_irq_set_perf_affinity_hint(hif_ctx); 5102 5103 ret = hdd_register_cb(hdd_ctx); 5104 if (ret) { 5105 hdd_err("Failed to register HDD callbacks!"); 5106 goto cds_txrx_free; 5107 } 5108 5109 ret = hdd_register_notifiers(hdd_ctx); 5110 if (ret) 5111 goto deregister_cb; 5112 5113 /* 5114 * NAN component requires certain operations like, open adapter, 5115 * close adapter, etc. to be initiated by HDD, for those 5116 * register HDD callbacks with UMAC's NAN component. 5117 */ 5118 hdd_nan_register_callbacks(hdd_ctx); 5119 5120 hdd_son_register_callbacks(hdd_ctx); 5121 5122 hdd_sr_register_callbacks(hdd_ctx); 5123 5124 wlan_hdd_register_btc_chain_mode_handler(hdd_ctx->psoc); 5125 5126 wlan_hdd_register_afc_pld_cb(hdd_ctx->psoc); 5127 5128 status = cds_pre_enable(); 5129 if (!QDF_IS_STATUS_SUCCESS(status)) { 5130 hdd_err("Failed to pre-enable CDS; status: %d", status); 5131 ret = qdf_status_to_os_return(status); 5132 goto unregister_notifiers; 5133 } 5134 5135 hdd_register_policy_manager_callback( 5136 hdd_ctx->psoc); 5137 5138 /* 5139 * Call this function before hdd_enable_power_management. Since 5140 * it is required to trigger WMI_PDEV_DMA_RING_CFG_REQ_CMDID 5141 * to FW when power save isn't enable. 5142 */ 5143 hdd_spectral_register_to_dbr(hdd_ctx); 5144 5145 hdd_create_sysfs_files(hdd_ctx); 5146 hdd_update_hw_sw_info(hdd_ctx); 5147 5148 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) { 5149 hdd_enable_power_management(hdd_ctx); 5150 hdd_err("in ftm mode, no need to configure cds modules"); 5151 hdd_info("Enable FW log in ftm mode"); 5152 /* 5153 * Since vdev is not created for FTM mode, 5154 * in FW use vdev_id = 0. 5155 */ 5156 hdd_set_fw_log_params(hdd_ctx, 0); 5157 ret = hdd_set_pcie_params(hdd_ctx, index, setparam); 5158 if (QDF_IS_STATUS_ERROR(ret)) 5159 break; 5160 index++; 5161 ret = sme_send_multi_pdev_vdev_set_params( 5162 MLME_PDEV_SETPARAM, 5163 WMI_PDEV_ID_SOC, setparam, index); 5164 if (QDF_IS_STATUS_ERROR(ret)) { 5165 hdd_err("failed to send pdev set params"); 5166 return ret; 5167 } 5168 5169 ret = -EINVAL; 5170 break; 5171 } 5172 5173 ret = hdd_configure_cds(hdd_ctx); 5174 if (ret) { 5175 hdd_err("Failed to Enable cds modules; errno: %d", ret); 5176 goto sched_disable; 5177 } 5178 5179 if (hdd_get_conparam() == QDF_GLOBAL_MISSION_MODE) { 5180 status = ucfg_dp_direct_link_init(hdd_ctx->psoc); 5181 if (QDF_IS_STATUS_ERROR(status)) { 5182 cds_err("Failed to initialize Direct Link datapath"); 5183 ret = -EINVAL; 5184 goto deconfigure_cds; 5185 } 5186 } 5187 5188 hdd_enable_power_management(hdd_ctx); 5189 5190 hdd_skip_acs_scan_timer_init(hdd_ctx); 5191 5192 hdd_set_hif_init_phase(hif_ctx, false); 5193 hdd_hif_set_enable_detection(hif_ctx, true); 5194 5195 wlan_hdd_start_connectivity_logging(hdd_ctx); 5196 5197 break; 5198 5199 default: 5200 QDF_DEBUG_PANIC("Unknown driver state:%d", 5201 hdd_ctx->driver_status); 5202 ret = -EINVAL; 5203 goto release_lock; 5204 } 5205 5206 hdd_ctx->driver_status = DRIVER_MODULES_ENABLED; 5207 hdd_nofl_debug("Wlan transitioned (now ENABLED)"); 5208 5209 ucfg_ipa_reg_is_driver_unloading_cb(hdd_ctx->pdev, 5210 cds_is_driver_unloading); 5211 ucfg_ipa_reg_sap_xmit_cb(hdd_ctx->pdev, 5212 hdd_softap_ipa_start_xmit); 5213 ucfg_ipa_reg_send_to_nw_cb(hdd_ctx->pdev, 5214 hdd_ipa_send_nbuf_to_network); 5215 ucfg_dp_reg_ipa_rsp_ind(hdd_ctx->pdev); 5216 5217 if (!pld_get_thermal_state(hdd_ctx->parent_dev, &thermal_state, 5218 THERMAL_MONITOR_APPS)) { 5219 if (thermal_state > QCA_WLAN_VENDOR_THERMAL_LEVEL_NONE) 5220 hdd_send_thermal_mitigation_val(hdd_ctx, 5221 thermal_state, 5222 THERMAL_MONITOR_APPS); 5223 } 5224 5225 if (!pld_get_thermal_state(hdd_ctx->parent_dev, &thermal_state, 5226 THERMAL_MONITOR_WPSS)) { 5227 if (thermal_state > QCA_WLAN_VENDOR_THERMAL_LEVEL_NONE) 5228 hdd_send_thermal_mitigation_val(hdd_ctx, thermal_state, 5229 THERMAL_MONITOR_WPSS); 5230 } 5231 5232 hdd_exit(); 5233 5234 return 0; 5235 5236 deconfigure_cds: 5237 hdd_deconfigure_cds(hdd_ctx); 5238 sched_disable: 5239 /* 5240 * Disable scheduler 1st so that scheduler thread doesn't send messages 5241 * to fw in parallel to the cleanup 5242 */ 5243 dispatcher_disable(); 5244 hdd_destroy_sysfs_files(); 5245 cds_post_disable(); 5246 unregister_notifiers: 5247 hdd_unregister_notifiers(hdd_ctx); 5248 5249 deregister_cb: 5250 hdd_deregister_cb(hdd_ctx); 5251 5252 cds_txrx_free: 5253 5254 tgt_hdl = wlan_psoc_get_tgt_if_handle(hdd_ctx->psoc); 5255 5256 if (tgt_hdl && target_psoc_get_wmi_ready(tgt_hdl)) 5257 hdd_runtime_suspend_context_deinit(hdd_ctx); 5258 5259 if (hdd_ctx->pdev) { 5260 dispatcher_pdev_close(hdd_ctx->pdev); 5261 hdd_objmgr_release_and_destroy_pdev(hdd_ctx); 5262 } 5263 5264 cds_dp_close(hdd_ctx->psoc); 5265 5266 close: 5267 dispatcher_disable(); 5268 hdd_ctx->driver_status = DRIVER_MODULES_CLOSED; 5269 hdd_info("Wlan transition aborted (now CLOSED)"); 5270 5271 cds_close(hdd_ctx->psoc); 5272 5273 psoc_close: 5274 hdd_component_psoc_close(hdd_ctx->psoc); 5275 wlan_global_lmac_if_close(hdd_ctx->psoc); 5276 cds_deinit_ini_config(); 5277 5278 ipa_component_free: 5279 ucfg_ipa_component_config_free(); 5280 5281 cds_free: 5282 ol_cds_free(); 5283 5284 hif_close: 5285 hif_ctx = cds_get_context(QDF_MODULE_ID_HIF); 5286 hdd_hif_close(hdd_ctx, hif_ctx); 5287 power_down: 5288 hdd_deinit_adapter_ops_wq(hdd_ctx); 5289 if (!reinit && !unint) 5290 pld_power_off(qdf_dev->dev); 5291 release_lock: 5292 cds_shutdown_notifier_purge(); 5293 hdd_check_for_leaks(hdd_ctx, reinit); 5294 hdd_debug_domain_set(QDF_DEBUG_DOMAIN_INIT); 5295 5296 abort: 5297 cds_set_driver_state_module_stop(true); 5298 5299 hdd_exit(); 5300 5301 return ret; 5302 } 5303 5304 #ifdef WIFI_POS_CONVERGED 5305 static int hdd_activate_wifi_pos(struct hdd_context *hdd_ctx) 5306 { 5307 int ret = os_if_wifi_pos_register_nl(); 5308 5309 if (ret) 5310 hdd_err("os_if_wifi_pos_register_nl failed"); 5311 5312 return ret; 5313 } 5314 5315 static int hdd_deactivate_wifi_pos(void) 5316 { 5317 int ret = os_if_wifi_pos_deregister_nl(); 5318 5319 if (ret) 5320 hdd_err("os_if_wifi_pos_deregister_nl failed"); 5321 5322 return ret; 5323 } 5324 5325 /** 5326 * hdd_populate_wifi_pos_cfg - populates wifi_pos parameters 5327 * @hdd_ctx: hdd context 5328 * 5329 * Return: status of operation 5330 */ 5331 static void hdd_populate_wifi_pos_cfg(struct hdd_context *hdd_ctx) 5332 { 5333 struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc; 5334 uint16_t neighbor_scan_max_chan_time; 5335 uint16_t neighbor_scan_min_chan_time; 5336 5337 wifi_pos_set_oem_target_type(psoc, hdd_ctx->target_type); 5338 wifi_pos_set_oem_fw_version(psoc, hdd_ctx->target_fw_version); 5339 wifi_pos_set_drv_ver_major(psoc, QWLAN_VERSION_MAJOR); 5340 wifi_pos_set_drv_ver_minor(psoc, QWLAN_VERSION_MINOR); 5341 wifi_pos_set_drv_ver_patch(psoc, QWLAN_VERSION_PATCH); 5342 wifi_pos_set_drv_ver_build(psoc, QWLAN_VERSION_BUILD); 5343 ucfg_mlme_get_neighbor_scan_max_chan_time(psoc, 5344 &neighbor_scan_max_chan_time); 5345 ucfg_mlme_get_neighbor_scan_min_chan_time(psoc, 5346 &neighbor_scan_min_chan_time); 5347 wifi_pos_set_dwell_time_min(psoc, neighbor_scan_min_chan_time); 5348 wifi_pos_set_dwell_time_max(psoc, neighbor_scan_max_chan_time); 5349 } 5350 #else 5351 static int hdd_activate_wifi_pos(struct hdd_context *hdd_ctx) 5352 { 5353 return oem_activate_service(hdd_ctx); 5354 } 5355 5356 static int hdd_deactivate_wifi_pos(void) 5357 { 5358 return oem_deactivate_service(); 5359 } 5360 5361 static void hdd_populate_wifi_pos_cfg(struct hdd_context *hdd_ctx) 5362 { 5363 } 5364 #endif 5365 5366 /** 5367 * __hdd_open() - HDD Open function 5368 * @dev: Pointer to net_device structure 5369 * 5370 * This is called in response to ifconfig up 5371 * 5372 * Return: 0 for success; non-zero for failure 5373 */ 5374 static int __hdd_open(struct net_device *dev) 5375 { 5376 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev); 5377 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); 5378 int ret; 5379 struct wlan_hdd_link_info *link_info = adapter->deflink; 5380 5381 hdd_enter_dev(dev); 5382 5383 qdf_mtrace(QDF_MODULE_ID_HDD, QDF_MODULE_ID_HDD, 5384 TRACE_CODE_HDD_OPEN_REQUEST, 5385 link_info->vdev_id, adapter->device_mode); 5386 5387 /* Nothing to be done if device is unloading */ 5388 if (cds_is_driver_unloading()) { 5389 hdd_err("Driver is unloading can not open the hdd"); 5390 return -EBUSY; 5391 } 5392 5393 if (cds_is_driver_recovering()) { 5394 hdd_err("WLAN is currently recovering; Please try again."); 5395 return -EBUSY; 5396 } 5397 5398 /* 5399 * This scenario can be hit in cases where in the wlan driver after 5400 * registering the netdevices and there is a failure in driver 5401 * initialization. So return error gracefully because the netdevices 5402 * will be de-registered as part of the load failure. 5403 */ 5404 5405 if (!cds_is_driver_loaded()) { 5406 hdd_err("Failed to start the wlan driver!!"); 5407 return -EIO; 5408 } 5409 5410 ret = wlan_hdd_validate_context(hdd_ctx); 5411 if (ret) { 5412 hdd_err("Can't start WLAN module, WiFi Disabled"); 5413 return ret; 5414 } 5415 5416 ret = hdd_trigger_psoc_idle_restart(hdd_ctx); 5417 if (ret) { 5418 hdd_err("Failed to start WLAN modules return"); 5419 return ret; 5420 } 5421 5422 if (!test_bit(SME_SESSION_OPENED, &link_info->link_flags)) { 5423 ret = hdd_start_adapter(adapter, true); 5424 if (ret) { 5425 hdd_err("Failed to start adapter :%d", 5426 adapter->device_mode); 5427 return ret; 5428 } 5429 } 5430 5431 set_bit(DEVICE_IFACE_OPENED, &adapter->event_flags); 5432 if (hdd_cm_is_vdev_associated(link_info)) { 5433 hdd_debug("Enabling Tx Queues"); 5434 /* Enable TX queues only when we are connected */ 5435 wlan_hdd_netif_queue_control(adapter, 5436 WLAN_START_ALL_NETIF_QUEUE, 5437 WLAN_CONTROL_PATH); 5438 } 5439 5440 /* Enable carrier and transmit queues for NDI */ 5441 if (WLAN_HDD_IS_NDI(adapter)) { 5442 hdd_debug("Enabling Tx Queues"); 5443 wlan_hdd_netif_queue_control(adapter, 5444 WLAN_START_ALL_NETIF_QUEUE_N_CARRIER, 5445 WLAN_CONTROL_PATH); 5446 } 5447 5448 hdd_populate_wifi_pos_cfg(hdd_ctx); 5449 hdd_lpass_notify_start(link_info); 5450 5451 if (ucfg_pkt_capture_get_mode(hdd_ctx->psoc) != 5452 PACKET_CAPTURE_MODE_DISABLE) 5453 hdd_map_monitor_interface_vdev(adapter); 5454 5455 return 0; 5456 } 5457 5458 /** 5459 * hdd_open() - Wrapper function for __hdd_open to protect it from SSR 5460 * @net_dev: Pointer to net_device structure 5461 * 5462 * This is called in response to ifconfig up 5463 * 5464 * Return: 0 for success; non-zero for failure 5465 */ 5466 static int hdd_open(struct net_device *net_dev) 5467 { 5468 int errno; 5469 struct osif_vdev_sync *vdev_sync; 5470 5471 errno = osif_vdev_sync_trans_start(net_dev, &vdev_sync); 5472 if (errno) 5473 return errno; 5474 5475 errno = __hdd_open(net_dev); 5476 if (!errno) 5477 osif_vdev_cache_command(vdev_sync, NO_COMMAND); 5478 5479 osif_vdev_sync_trans_stop(vdev_sync); 5480 5481 return errno; 5482 } 5483 5484 int hdd_stop_no_trans(struct net_device *dev) 5485 { 5486 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev); 5487 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); 5488 int ret; 5489 mac_handle_t mac_handle; 5490 5491 hdd_enter_dev(dev); 5492 5493 qdf_mtrace(QDF_MODULE_ID_HDD, QDF_MODULE_ID_HDD, 5494 TRACE_CODE_HDD_STOP_REQUEST, 5495 adapter->deflink->vdev_id, adapter->device_mode); 5496 5497 ret = wlan_hdd_validate_context(hdd_ctx); 5498 if (ret) 5499 return ret; 5500 5501 /* Nothing to be done if the interface is not opened */ 5502 if (false == test_bit(DEVICE_IFACE_OPENED, &adapter->event_flags)) { 5503 hdd_err("NETDEV Interface is not OPENED"); 5504 return -ENODEV; 5505 } 5506 5507 mac_handle = hdd_ctx->mac_handle; 5508 5509 if (!wlan_hdd_is_session_type_monitor(adapter->device_mode) && 5510 adapter->device_mode != QDF_FTM_MODE) { 5511 hdd_debug("Disabling Auto Power save timer"); 5512 sme_ps_disable_auto_ps_timer( 5513 mac_handle, 5514 adapter->deflink->vdev_id); 5515 } 5516 5517 /* 5518 * Disable TX on the interface, after this hard_start_xmit() will not 5519 * be called on that interface 5520 */ 5521 hdd_debug("Disabling queues, adapter device mode: %s(%d)", 5522 qdf_opmode_str(adapter->device_mode), adapter->device_mode); 5523 5524 wlan_hdd_netif_queue_control(adapter, 5525 WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER, 5526 WLAN_CONTROL_PATH); 5527 5528 if (adapter->device_mode == QDF_STA_MODE) 5529 hdd_lpass_notify_stop(hdd_ctx); 5530 5531 /* 5532 * NAN data interface is different in some sense. The traffic on NDI is 5533 * bursty in nature and depends on the need to transfer. The service 5534 * layer may down the interface after the usage and up again when 5535 * required. In some sense, the NDI is expected to be available 5536 * (like SAP) iface until NDI delete request is issued by the service 5537 * layer. Skip BSS termination and adapter deletion for NAN Data 5538 * interface (NDI). 5539 */ 5540 if (WLAN_HDD_IS_NDI(adapter)) 5541 goto reset_iface_opened; 5542 5543 /* 5544 * The interface is marked as down for outside world (aka kernel) 5545 * But the driver is pretty much alive inside. The driver needs to 5546 * tear down the existing connection on the netdev (session) 5547 * cleanup the data pipes and wait until the control plane is stabilized 5548 * for this interface. The call also needs to wait until the above 5549 * mentioned actions are completed before returning to the caller. 5550 * Notice that hdd_stop_adapter is requested not to close the session 5551 * That is intentional to be able to scan if it is a STA/P2P interface 5552 */ 5553 hdd_stop_adapter(hdd_ctx, adapter); 5554 5555 /* DeInit the adapter. This ensures datapath cleanup as well */ 5556 hdd_deinit_adapter(hdd_ctx, adapter, true); 5557 5558 reset_iface_opened: 5559 /* Make sure the interface is marked as closed */ 5560 clear_bit(DEVICE_IFACE_OPENED, &adapter->event_flags); 5561 if (!hdd_is_any_interface_open(hdd_ctx)) 5562 hdd_psoc_idle_timer_start(hdd_ctx); 5563 hdd_exit(); 5564 5565 return 0; 5566 } 5567 5568 /** 5569 * hdd_stop() - Wrapper function for __hdd_stop to protect it from SSR 5570 * @net_dev: pointer to net_device structure 5571 * 5572 * This is called in response to ifconfig down 5573 * 5574 * Return: 0 for success and error number for failure 5575 */ 5576 static int hdd_stop(struct net_device *net_dev) 5577 { 5578 int errno; 5579 struct osif_vdev_sync *vdev_sync; 5580 5581 errno = osif_vdev_sync_trans_start(net_dev, &vdev_sync); 5582 if (errno) { 5583 if (vdev_sync) 5584 osif_vdev_cache_command(vdev_sync, INTERFACE_DOWN); 5585 return errno; 5586 } 5587 5588 errno = hdd_stop_no_trans(net_dev); 5589 5590 osif_vdev_sync_trans_stop(vdev_sync); 5591 5592 return errno; 5593 } 5594 5595 /** 5596 * hdd_uninit() - HDD uninit function 5597 * @dev: Pointer to net_device structure 5598 * 5599 * This is called during the netdev unregister to uninitialize all data 5600 * associated with the device 5601 * 5602 * This function must be protected by a transition 5603 * 5604 * Return: None 5605 */ 5606 static void hdd_uninit(struct net_device *dev) 5607 { 5608 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev); 5609 struct hdd_context *hdd_ctx; 5610 5611 hdd_enter_dev(dev); 5612 5613 if (adapter->magic != WLAN_HDD_ADAPTER_MAGIC) { 5614 hdd_err("Invalid magic"); 5615 goto exit; 5616 } 5617 5618 hdd_ctx = WLAN_HDD_GET_CTX(adapter); 5619 if (!hdd_ctx) { 5620 hdd_err("NULL hdd_ctx"); 5621 goto exit; 5622 } 5623 5624 if (dev != adapter->dev) 5625 hdd_err("Invalid device reference"); 5626 5627 hdd_deinit_adapter(hdd_ctx, adapter, true); 5628 5629 /* after uninit our adapter structure will no longer be valid */ 5630 adapter->magic = 0; 5631 5632 exit: 5633 hdd_exit(); 5634 } 5635 5636 static int hdd_open_cesium_nl_sock(void) 5637 { 5638 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0)) 5639 struct netlink_kernel_cfg cfg = { 5640 .groups = WLAN_NLINK_MCAST_GRP_ID, 5641 .input = NULL 5642 }; 5643 #endif 5644 int ret = 0; 5645 5646 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0)) 5647 cesium_nl_srv_sock = netlink_kernel_create(&init_net, WLAN_NLINK_CESIUM, 5648 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 7, 0)) 5649 THIS_MODULE, 5650 #endif 5651 &cfg); 5652 #else 5653 cesium_nl_srv_sock = netlink_kernel_create(&init_net, WLAN_NLINK_CESIUM, 5654 WLAN_NLINK_MCAST_GRP_ID, 5655 NULL, NULL, THIS_MODULE); 5656 #endif 5657 5658 if (!cesium_nl_srv_sock) { 5659 hdd_err("NLINK: cesium netlink_kernel_create failed"); 5660 ret = -ECONNREFUSED; 5661 } 5662 5663 return ret; 5664 } 5665 5666 static void hdd_close_cesium_nl_sock(void) 5667 { 5668 if (cesium_nl_srv_sock) { 5669 netlink_kernel_release(cesium_nl_srv_sock); 5670 cesium_nl_srv_sock = NULL; 5671 } 5672 } 5673 5674 void hdd_update_dynamic_mac(struct hdd_context *hdd_ctx, 5675 struct qdf_mac_addr *curr_mac_addr, 5676 struct qdf_mac_addr *new_mac_addr) 5677 { 5678 uint8_t i; 5679 5680 hdd_enter(); 5681 5682 for (i = 0; i < QDF_MAX_CONCURRENCY_PERSONA; i++) { 5683 if (!qdf_mem_cmp( 5684 curr_mac_addr->bytes, 5685 &hdd_ctx->dynamic_mac_list[i].dynamic_mac.bytes[0], 5686 sizeof(struct qdf_mac_addr))) { 5687 qdf_mem_copy(&hdd_ctx->dynamic_mac_list[i].dynamic_mac, 5688 new_mac_addr->bytes, 5689 sizeof(struct qdf_mac_addr)); 5690 break; 5691 } 5692 } 5693 5694 hdd_exit(); 5695 } 5696 5697 #if defined(WLAN_FEATURE_11BE_MLO) && defined(CFG80211_11BE_BASIC) && \ 5698 !defined(WLAN_HDD_MULTI_VDEV_SINGLE_NDEV) 5699 void hdd_set_mld_address(struct hdd_adapter *adapter, 5700 const struct qdf_mac_addr *mac_addr) 5701 { 5702 int i; 5703 bool eht_capab; 5704 struct hdd_adapter *link_adapter; 5705 struct hdd_mlo_adapter_info *mlo_adapter_info; 5706 5707 ucfg_psoc_mlme_get_11be_capab(adapter->hdd_ctx->psoc, &eht_capab); 5708 if (adapter->mlo_adapter_info.is_ml_adapter && eht_capab) { 5709 mlo_adapter_info = &adapter->mlo_adapter_info; 5710 for (i = 0; i < WLAN_MAX_MLD; i++) { 5711 link_adapter = mlo_adapter_info->link_adapter[i]; 5712 if (link_adapter) 5713 qdf_copy_macaddr(&link_adapter->mld_addr, 5714 mac_addr); 5715 } 5716 qdf_copy_macaddr(&adapter->mld_addr, mac_addr); 5717 } 5718 } 5719 5720 /** 5721 * hdd_get_netdev_by_vdev_mac() - Get Netdev based on MAC 5722 * @mac_addr: Vdev MAC address 5723 * 5724 * Get netdev from adapter based upon Vdev MAC address. 5725 * 5726 * Return: netdev pointer. 5727 */ 5728 static qdf_netdev_t 5729 hdd_get_netdev_by_vdev_mac(struct qdf_mac_addr *mac_addr) 5730 { 5731 struct hdd_context *hdd_ctx; 5732 struct hdd_adapter *adapter; 5733 struct hdd_adapter *ml_adapter; 5734 5735 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 5736 if (!hdd_ctx) { 5737 hdd_err("Invalid HDD context"); 5738 return NULL; 5739 } 5740 5741 adapter = hdd_get_adapter_by_macaddr(hdd_ctx, mac_addr->bytes); 5742 if (!adapter) { 5743 hdd_err("Adapter not foud for MAC " QDF_MAC_ADDR_FMT "", 5744 QDF_MAC_ADDR_REF(mac_addr->bytes)); 5745 return NULL; 5746 } 5747 5748 if (adapter->mlo_adapter_info.is_link_adapter && 5749 adapter->mlo_adapter_info.associate_with_ml_adapter) { 5750 ml_adapter = adapter->mlo_adapter_info.ml_adapter; 5751 adapter = ml_adapter; 5752 } 5753 5754 return adapter->dev; 5755 } 5756 #else 5757 static qdf_netdev_t 5758 hdd_get_netdev_by_vdev_mac(struct qdf_mac_addr *mac_addr) 5759 { 5760 struct hdd_context *hdd_ctx; 5761 struct hdd_adapter *adapter; 5762 5763 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 5764 if (!hdd_ctx) { 5765 hdd_err("Invalid HDD context"); 5766 return NULL; 5767 } 5768 5769 adapter = hdd_get_adapter_by_macaddr(hdd_ctx, mac_addr->bytes); 5770 if (!adapter) { 5771 hdd_err("Adapter not foud for MAC " QDF_MAC_ADDR_FMT "", 5772 QDF_MAC_ADDR_REF(mac_addr->bytes)); 5773 return NULL; 5774 } 5775 5776 return adapter->dev; 5777 } 5778 #endif 5779 5780 #ifdef WLAN_FEATURE_DYNAMIC_MAC_ADDR_UPDATE 5781 #if defined(WLAN_FEATURE_11BE_MLO) && defined(CFG80211_11BE_BASIC) && \ 5782 !defined(WLAN_HDD_MULTI_VDEV_SINGLE_NDEV) 5783 static void hdd_update_set_mac_addr_req_ctx(struct hdd_adapter *adapter, 5784 void *req_ctx) 5785 { 5786 adapter->set_mac_addr_req_ctx = req_ctx; 5787 if (adapter->mlo_adapter_info.associate_with_ml_adapter) 5788 adapter->mlo_adapter_info.ml_adapter->set_mac_addr_req_ctx = 5789 req_ctx; 5790 } 5791 #else 5792 static void hdd_update_set_mac_addr_req_ctx(struct hdd_adapter *adapter, 5793 void *req_ctx) 5794 { 5795 adapter->set_mac_addr_req_ctx = req_ctx; 5796 } 5797 #endif 5798 5799 /** 5800 * hdd_is_dynamic_set_mac_addr_supported() - API to check dynamic MAC address 5801 * update is supported or not 5802 * @hdd_ctx: Pointer to the HDD context 5803 * 5804 * Return: true or false 5805 */ 5806 static inline bool 5807 hdd_is_dynamic_set_mac_addr_supported(struct hdd_context *hdd_ctx) 5808 { 5809 return hdd_ctx->is_vdev_macaddr_dynamic_update_supported; 5810 } 5811 5812 bool hdd_is_dynamic_set_mac_addr_allowed(struct hdd_adapter *adapter) 5813 { 5814 if (!adapter->deflink->vdev) { 5815 hdd_err("VDEV is NULL"); 5816 return false; 5817 } 5818 5819 if (!hdd_is_dynamic_set_mac_addr_supported(adapter->hdd_ctx)) { 5820 hdd_info_rl("On iface up, set mac address change isn't supported"); 5821 return false; 5822 } 5823 5824 switch (adapter->device_mode) { 5825 case QDF_STA_MODE: 5826 if (!cm_is_vdev_disconnected(adapter->deflink->vdev)) { 5827 hdd_info_rl("VDEV is not in disconnected state, set mac address isn't supported"); 5828 return false; 5829 } 5830 return true; 5831 case QDF_P2P_DEVICE_MODE: 5832 return ucfg_is_p2p_device_dynamic_set_mac_addr_supported(adapter->hdd_ctx->psoc); 5833 case QDF_SAP_MODE: 5834 if (test_bit(SOFTAP_BSS_STARTED, 5835 &adapter->deflink->link_flags)) { 5836 hdd_info_rl("SAP is in up state, set mac address isn't supported"); 5837 return false; 5838 } else { 5839 return true; 5840 } 5841 default: 5842 hdd_info_rl("Dynamic set mac address isn't supported for opmode:%d", 5843 adapter->device_mode); 5844 return false; 5845 } 5846 } 5847 5848 int hdd_dynamic_mac_address_set(struct wlan_hdd_link_info *link_info, 5849 struct qdf_mac_addr mac_addr, 5850 struct qdf_mac_addr mld_addr, 5851 bool update_self_peer) 5852 { 5853 int ret; 5854 void *cookie; 5855 bool update_mld_addr; 5856 uint32_t fw_resp_status; 5857 QDF_STATUS status = QDF_STATUS_SUCCESS; 5858 struct osif_request *request; 5859 struct wlan_objmgr_vdev *vdev; 5860 struct hdd_adapter *adapter = link_info->adapter; 5861 struct hdd_context *hdd_ctx = adapter->hdd_ctx; 5862 struct mac_addr_set_priv *priv; 5863 static const struct osif_request_params params = { 5864 .priv_size = sizeof(*priv), 5865 .timeout_ms = WLAN_SET_MAC_ADDR_TIMEOUT 5866 }; 5867 5868 vdev = hdd_objmgr_get_vdev_by_user(link_info, WLAN_OSIF_ID); 5869 if (!vdev) 5870 return -EINVAL; 5871 5872 if (wlan_vdev_mlme_get_opmode(vdev) != QDF_P2P_DEVICE_MODE) { 5873 status = ucfg_vdev_mgr_cdp_vdev_detach(vdev); 5874 if (QDF_IS_STATUS_ERROR(status)) { 5875 hdd_err("Failed to detach CDP vdev. Status:%d", status); 5876 ret = qdf_status_to_os_return(status); 5877 goto vdev_ref; 5878 } 5879 } 5880 request = osif_request_alloc(¶ms); 5881 if (!request) { 5882 hdd_err("request alloc fail"); 5883 status = QDF_STATUS_E_NOMEM; 5884 ret = -ENOMEM; 5885 goto status_ret; 5886 } 5887 5888 /* Host should hold a wake lock until the FW event response is received 5889 * the WMI event would not be a wake up event. 5890 */ 5891 qdf_runtime_pm_prevent_suspend( 5892 &hdd_ctx->runtime_context.dyn_mac_addr_update); 5893 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_DYN_MAC_ADDR_UPDATE); 5894 5895 cookie = osif_request_cookie(request); 5896 hdd_update_set_mac_addr_req_ctx(adapter, cookie); 5897 5898 priv = (struct mac_addr_set_priv *)osif_request_priv(request); 5899 5900 /* For p2p device mode, need send delete self peer cmd to F/W, 5901 * To avoid p2p new DP vdev is created before old DP vdev deleted, 5902 * don't create new DP vdev until both self peer delete rsp and set 5903 * mac addr rsp received, so initialize pending_rsp_cnt as 2. 5904 * 5905 * For other mode like STA/SAP, don't need send delete self peer cmd 5906 * to F/W, only need wait set mad addr rsp, so initialize 5907 * pending_rsp_cnt as 1. 5908 */ 5909 if (wlan_vdev_mlme_get_opmode(vdev) == QDF_P2P_DEVICE_MODE) 5910 qdf_atomic_set(&priv->pending_rsp_cnt, 2); 5911 else 5912 qdf_atomic_set(&priv->pending_rsp_cnt, 1); 5913 5914 status = sme_send_set_mac_addr(mac_addr, mld_addr, vdev); 5915 ret = qdf_status_to_os_return(status); 5916 if (QDF_IS_STATUS_ERROR(status)) { 5917 hdd_nofl_err("Failed to send set MAC address command. Status:%d", 5918 status); 5919 osif_request_put(request); 5920 goto status_ret; 5921 } else { 5922 ret = osif_request_wait_for_response(request); 5923 if (ret) { 5924 hdd_err("Set MAC address response timed out"); 5925 } else { 5926 fw_resp_status = priv->fw_resp_status; 5927 if (fw_resp_status) { 5928 hdd_err("Set MAC address failed in FW. Status: %d", 5929 fw_resp_status); 5930 ret = -EAGAIN; 5931 } 5932 } 5933 } 5934 5935 osif_request_put(request); 5936 5937 if (qdf_is_macaddr_zero(&mld_addr)) 5938 update_mld_addr = false; 5939 else 5940 update_mld_addr = true; 5941 5942 status = sme_update_vdev_mac_addr(vdev, mac_addr, mld_addr, 5943 update_self_peer, update_mld_addr, 5944 ret); 5945 5946 status_ret: 5947 if (QDF_IS_STATUS_ERROR(status)) { 5948 ret = qdf_status_to_os_return(status); 5949 goto allow_suspend; 5950 } else if (!ret) { 5951 status = ucfg_dp_update_link_mac_addr(vdev, &mac_addr, false); 5952 if (QDF_IS_STATUS_ERROR(status)) { 5953 ret = qdf_status_to_os_return(status); 5954 hdd_err("DP link MAC update failed"); 5955 goto allow_suspend; 5956 } 5957 } 5958 sme_vdev_set_data_tx_callback(vdev); 5959 5960 /* Update FW WoW pattern with new MAC address */ 5961 ucfg_pmo_del_wow_pattern(vdev); 5962 ucfg_pmo_register_wow_default_patterns(vdev); 5963 hdd_tx_latency_restore_config(link_info); 5964 5965 allow_suspend: 5966 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DYN_MAC_ADDR_UPDATE); 5967 qdf_runtime_pm_allow_suspend( 5968 &hdd_ctx->runtime_context.dyn_mac_addr_update); 5969 5970 vdev_ref: 5971 hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_ID); 5972 5973 return ret; 5974 } 5975 5976 static void hdd_set_mac_addr_event_cb(uint8_t vdev_id, uint8_t status) 5977 { 5978 struct hdd_context *hdd_ctx; 5979 struct wlan_hdd_link_info *link_info; 5980 struct osif_request *req; 5981 struct mac_addr_set_priv *priv; 5982 5983 osif_debug("enter"); 5984 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 5985 if (!hdd_ctx) { 5986 hdd_err("Invalid HDD context"); 5987 return; 5988 } 5989 5990 link_info = hdd_get_link_info_by_vdev(hdd_ctx, vdev_id); 5991 if (!link_info) { 5992 hdd_err("No adapter found for VDEV ID:%d", vdev_id); 5993 return; 5994 } 5995 5996 req = osif_request_get(link_info->adapter->set_mac_addr_req_ctx); 5997 if (!req) { 5998 osif_err("Obsolete request for VDEV ID:%d", vdev_id); 5999 return; 6000 } 6001 6002 priv = (struct mac_addr_set_priv *)osif_request_priv(req); 6003 6004 if (qdf_atomic_dec_and_test(&priv->pending_rsp_cnt)) { 6005 priv->fw_resp_status = status; 6006 osif_request_complete(req); 6007 } 6008 6009 osif_request_put(req); 6010 } 6011 #else 6012 static inline bool 6013 hdd_is_dynamic_set_mac_addr_supported(struct hdd_context *hdd_ctx) 6014 { 6015 return false; 6016 } 6017 #endif 6018 6019 #if defined(WLAN_FEATURE_11BE_MLO) && defined(WLAN_HDD_MULTI_VDEV_SINGLE_NDEV) 6020 static QDF_STATUS 6021 hdd_adapter_update_links_on_link_switch(struct wlan_hdd_link_info *cur_link_info, 6022 struct wlan_hdd_link_info *new_link_info) 6023 { 6024 unsigned long link_flags; 6025 struct wlan_objmgr_vdev *vdev; 6026 int cur_link_idx, new_link_idx; 6027 uint8_t cur_old_pos, cur_new_pos; 6028 struct vdev_osif_priv *vdev_priv; 6029 struct hdd_adapter *adapter = cur_link_info->adapter; 6030 6031 /* Update the new position of current and new link info 6032 * in the link info array. 6033 */ 6034 cur_link_idx = hdd_adapter_get_index_of_link_info(cur_link_info); 6035 new_link_idx = hdd_adapter_get_index_of_link_info(new_link_info); 6036 6037 cur_old_pos = adapter->curr_link_info_map[cur_link_idx]; 6038 cur_new_pos = adapter->curr_link_info_map[new_link_idx]; 6039 6040 adapter->curr_link_info_map[new_link_idx] = cur_old_pos; 6041 adapter->curr_link_info_map[cur_link_idx] = cur_new_pos; 6042 6043 /* Move VDEV from current link info to new link info */ 6044 qdf_atomic_clear_bit(cur_link_idx, &adapter->active_links); 6045 qdf_spin_lock_bh(&cur_link_info->vdev_lock); 6046 vdev = cur_link_info->vdev; 6047 cur_link_info->vdev = NULL; 6048 cur_link_info->vdev_id = WLAN_INVALID_VDEV_ID; 6049 qdf_spin_unlock_bh(&cur_link_info->vdev_lock); 6050 6051 qdf_spin_lock_bh(&new_link_info->vdev_lock); 6052 new_link_info->vdev = vdev; 6053 new_link_info->vdev_id = wlan_vdev_get_id(vdev); 6054 qdf_spin_unlock_bh(&new_link_info->vdev_lock); 6055 qdf_atomic_set_bit(new_link_idx, &adapter->active_links); 6056 6057 /* Move the link flags between current and new link info */ 6058 link_flags = new_link_info->link_flags; 6059 new_link_info->link_flags = cur_link_info->link_flags; 6060 cur_link_info->link_flags = link_flags; 6061 6062 /* Update VDEV-OSIF priv pointer to new link info */ 6063 vdev_priv = wlan_vdev_get_ospriv(new_link_info->vdev); 6064 vdev_priv->legacy_osif_priv = new_link_info; 6065 6066 return QDF_STATUS_SUCCESS; 6067 } 6068 6069 struct wlan_hdd_link_info * 6070 hdd_get_link_info_by_ieee_link_id(struct hdd_adapter *adapter, int32_t link_id) 6071 { 6072 struct wlan_hdd_link_info *link_info; 6073 struct hdd_station_ctx *sta_ctx; 6074 6075 if (!adapter || link_id == WLAN_INVALID_LINK_ID) { 6076 hdd_err("NULL adapter or invalid link ID"); 6077 return NULL; 6078 } 6079 6080 hdd_adapter_for_each_link_info(adapter, link_info) { 6081 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(link_info); 6082 if (sta_ctx->conn_info.ieee_link_id == link_id) 6083 return link_info; 6084 } 6085 6086 return NULL; 6087 } 6088 6089 QDF_STATUS 6090 hdd_link_switch_vdev_mac_addr_update(int32_t ieee_old_link_id, 6091 int32_t ieee_new_link_id, uint8_t vdev_id) 6092 { 6093 QDF_STATUS status = QDF_STATUS_E_INVAL; 6094 struct hdd_context *hdd_ctx; 6095 struct hdd_adapter *adapter; 6096 struct wlan_objmgr_vdev *vdev; 6097 struct wlan_hdd_link_info *cur_link_info, *new_link_info; 6098 struct hdd_station_ctx *sta_ctx; 6099 6100 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 6101 if (!hdd_ctx) { 6102 hdd_err("HDD ctx NULL"); 6103 return QDF_STATUS_E_INVAL; 6104 } 6105 6106 cur_link_info = hdd_get_link_info_by_vdev(hdd_ctx, vdev_id); 6107 if (!cur_link_info) { 6108 hdd_err("VDEV %d not found", vdev_id); 6109 return status; 6110 } 6111 6112 vdev = hdd_objmgr_get_vdev_by_user(cur_link_info, WLAN_OSIF_ID); 6113 if (!vdev) { 6114 hdd_err("Invalid VDEV %d", vdev_id); 6115 return status; 6116 } 6117 6118 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(cur_link_info); 6119 if (sta_ctx->conn_info.ieee_link_id != ieee_old_link_id) { 6120 hdd_err("Link id %d mismatch", sta_ctx->conn_info.ieee_link_id); 6121 goto release_ref; 6122 } 6123 6124 adapter = cur_link_info->adapter; 6125 new_link_info = hdd_get_link_info_by_ieee_link_id(adapter, 6126 ieee_new_link_id); 6127 if (!new_link_info) { 6128 hdd_err("Link id %d not found", ieee_new_link_id); 6129 goto release_ref; 6130 } 6131 6132 status = ucfg_dp_update_link_mac_addr(vdev, &new_link_info->link_addr, 6133 true); 6134 if (QDF_IS_STATUS_ERROR(status)) { 6135 hdd_err("DP link MAC update failed"); 6136 goto release_ref; 6137 } 6138 6139 status = hdd_adapter_update_links_on_link_switch(cur_link_info, 6140 new_link_info); 6141 if (QDF_IS_STATUS_ERROR(status)) { 6142 hdd_err("Failed to update adapter link info"); 6143 goto release_ref; 6144 } 6145 6146 hdd_adapter_update_mlo_mgr_mac_addr(adapter); 6147 sme_vdev_set_data_tx_callback(vdev); 6148 ucfg_pmo_del_wow_pattern(vdev); 6149 ucfg_pmo_register_wow_default_patterns(vdev); 6150 6151 release_ref: 6152 hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_ID); 6153 return status; 6154 } 6155 #endif 6156 6157 /** 6158 * __hdd_set_mac_address() - set the user specified mac address 6159 * @dev: Pointer to the net device. 6160 * @addr: Pointer to the sockaddr. 6161 * 6162 * This function sets the user specified mac address using 6163 * the command ifconfig wlanX hw ether <mac address>. 6164 * 6165 * Return: 0 for success, non zero for failure 6166 */ 6167 static int __hdd_set_mac_address(struct net_device *dev, void *addr) 6168 { 6169 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev); 6170 struct hdd_adapter *adapter_temp; 6171 struct hdd_context *hdd_ctx; 6172 struct sockaddr *psta_mac_addr = addr; 6173 QDF_STATUS qdf_ret_status = QDF_STATUS_SUCCESS; 6174 int ret; 6175 struct qdf_mac_addr mac_addr; 6176 bool net_if_running = netif_running(dev); 6177 6178 hdd_enter_dev(dev); 6179 6180 hdd_ctx = WLAN_HDD_GET_CTX(adapter); 6181 ret = wlan_hdd_validate_context(hdd_ctx); 6182 if (0 != ret) 6183 return ret; 6184 6185 if (net_if_running) { 6186 if (!hdd_is_dynamic_set_mac_addr_allowed(adapter)) 6187 return -ENOTSUPP; 6188 } 6189 6190 qdf_mem_copy(&mac_addr, psta_mac_addr->sa_data, sizeof(mac_addr)); 6191 adapter_temp = hdd_get_adapter_by_macaddr(hdd_ctx, mac_addr.bytes); 6192 if (adapter_temp) { 6193 if (!qdf_str_cmp(adapter_temp->dev->name, dev->name)) 6194 return 0; 6195 hdd_err("%s adapter exist with same address " QDF_MAC_ADDR_FMT, 6196 adapter_temp->dev->name, 6197 QDF_MAC_ADDR_REF(mac_addr.bytes)); 6198 return -EINVAL; 6199 } 6200 qdf_ret_status = wlan_hdd_validate_mac_address(&mac_addr); 6201 if (QDF_IS_STATUS_ERROR(qdf_ret_status)) 6202 return -EINVAL; 6203 6204 hdd_nofl_debug("Changing MAC to " 6205 QDF_MAC_ADDR_FMT " of the interface %s ", 6206 QDF_MAC_ADDR_REF(mac_addr.bytes), dev->name); 6207 6208 if (net_if_running && adapter->deflink->vdev) { 6209 ret = hdd_update_vdev_mac_address(adapter, mac_addr); 6210 if (ret) 6211 return ret; 6212 } 6213 6214 hdd_set_mld_address(adapter, &mac_addr); 6215 6216 hdd_update_dynamic_mac(hdd_ctx, &adapter->mac_addr, &mac_addr); 6217 ucfg_dp_update_intf_mac(hdd_ctx->psoc, &adapter->mac_addr, &mac_addr, 6218 adapter->deflink->vdev); 6219 memcpy(&adapter->mac_addr, psta_mac_addr->sa_data, ETH_ALEN); 6220 qdf_net_update_net_device_dev_addr(dev, psta_mac_addr->sa_data, 6221 ETH_ALEN); 6222 6223 hdd_exit(); 6224 return ret; 6225 } 6226 6227 /** 6228 * hdd_set_mac_address() - Wrapper function to protect __hdd_set_mac_address() 6229 * function from SSR 6230 * @net_dev: pointer to net_device structure 6231 * @addr: Pointer to the sockaddr 6232 * 6233 * This function sets the user specified mac address using 6234 * the command ifconfig wlanX hw ether <mac address>. 6235 * 6236 * Return: 0 for success. 6237 */ 6238 static int hdd_set_mac_address(struct net_device *net_dev, void *addr) 6239 { 6240 struct osif_vdev_sync *vdev_sync; 6241 int errno; 6242 6243 errno = osif_vdev_sync_op_start(net_dev, &vdev_sync); 6244 if (errno) 6245 return errno; 6246 6247 errno = __hdd_set_mac_address(net_dev, addr); 6248 6249 osif_vdev_sync_op_stop(vdev_sync); 6250 6251 return errno; 6252 } 6253 6254 static uint8_t *wlan_hdd_get_derived_intf_addr(struct hdd_context *hdd_ctx) 6255 { 6256 int i, j; 6257 6258 i = qdf_ffz(hdd_ctx->derived_intf_addr_mask); 6259 if (i < 0 || i >= hdd_ctx->num_derived_addr) 6260 return NULL; 6261 qdf_atomic_set_bit(i, &hdd_ctx->derived_intf_addr_mask); 6262 hdd_nofl_debug("Assigning MAC from derived list "QDF_MAC_ADDR_FMT, 6263 QDF_MAC_ADDR_REF(hdd_ctx->derived_mac_addr[i].bytes)); 6264 6265 /* Copy the mac in dynamic mac list at first free position */ 6266 for (j = 0; j < QDF_MAX_CONCURRENCY_PERSONA; j++) { 6267 if (qdf_is_macaddr_zero(&hdd_ctx-> 6268 dynamic_mac_list[j].dynamic_mac)) 6269 break; 6270 } 6271 if (j == QDF_MAX_CONCURRENCY_PERSONA) { 6272 hdd_err("Max interfaces are up"); 6273 return NULL; 6274 } 6275 6276 qdf_mem_copy(&hdd_ctx->dynamic_mac_list[j].dynamic_mac.bytes, 6277 &hdd_ctx->derived_mac_addr[i].bytes, 6278 sizeof(struct qdf_mac_addr)); 6279 hdd_ctx->dynamic_mac_list[j].is_provisioned_mac = false; 6280 hdd_ctx->dynamic_mac_list[j].bit_position = i; 6281 6282 return hdd_ctx->derived_mac_addr[i].bytes; 6283 } 6284 6285 static uint8_t *wlan_hdd_get_provisioned_intf_addr(struct hdd_context *hdd_ctx) 6286 { 6287 int i, j; 6288 6289 i = qdf_ffz(hdd_ctx->provisioned_intf_addr_mask); 6290 if (i < 0 || i >= hdd_ctx->num_provisioned_addr) 6291 return NULL; 6292 qdf_atomic_set_bit(i, &hdd_ctx->provisioned_intf_addr_mask); 6293 hdd_debug("Assigning MAC from provisioned list "QDF_MAC_ADDR_FMT, 6294 QDF_MAC_ADDR_REF(hdd_ctx->provisioned_mac_addr[i].bytes)); 6295 6296 /* Copy the mac in dynamic mac list at first free position */ 6297 for (j = 0; j < QDF_MAX_CONCURRENCY_PERSONA; j++) { 6298 if (qdf_is_macaddr_zero(&hdd_ctx-> 6299 dynamic_mac_list[j].dynamic_mac)) 6300 break; 6301 } 6302 if (j == QDF_MAX_CONCURRENCY_PERSONA) { 6303 hdd_err("Max interfaces are up"); 6304 return NULL; 6305 } 6306 6307 qdf_mem_copy(&hdd_ctx->dynamic_mac_list[j].dynamic_mac.bytes, 6308 &hdd_ctx->provisioned_mac_addr[i].bytes, 6309 sizeof(struct qdf_mac_addr)); 6310 hdd_ctx->dynamic_mac_list[j].is_provisioned_mac = true; 6311 hdd_ctx->dynamic_mac_list[j].bit_position = i; 6312 return hdd_ctx->provisioned_mac_addr[i].bytes; 6313 } 6314 6315 uint8_t *wlan_hdd_get_intf_addr(struct hdd_context *hdd_ctx, 6316 enum QDF_OPMODE interface_type) 6317 { 6318 uint8_t *mac_addr = NULL; 6319 6320 if (qdf_atomic_test_bit(interface_type, 6321 (unsigned long *) 6322 (&hdd_ctx->config->provisioned_intf_pool))) 6323 mac_addr = wlan_hdd_get_provisioned_intf_addr(hdd_ctx); 6324 6325 if ((!mac_addr) && 6326 (qdf_atomic_test_bit(interface_type, 6327 (unsigned long *) 6328 (&hdd_ctx->config->derived_intf_pool)))) 6329 mac_addr = wlan_hdd_get_derived_intf_addr(hdd_ctx); 6330 6331 if (!mac_addr) 6332 hdd_err("MAC is not available in both the lists"); 6333 return mac_addr; 6334 } 6335 6336 void wlan_hdd_release_intf_addr(struct hdd_context *hdd_ctx, 6337 uint8_t *releaseAddr) 6338 { 6339 int i; 6340 int mac_pos_in_mask; 6341 6342 for (i = 0; i < QDF_MAX_CONCURRENCY_PERSONA; i++) { 6343 if (!memcmp(releaseAddr, 6344 hdd_ctx->dynamic_mac_list[i].dynamic_mac.bytes, 6345 QDF_MAC_ADDR_SIZE)) { 6346 mac_pos_in_mask = 6347 hdd_ctx->dynamic_mac_list[i].bit_position; 6348 if (hdd_ctx->dynamic_mac_list[i].is_provisioned_mac) { 6349 qdf_atomic_clear_bit( 6350 mac_pos_in_mask, 6351 &hdd_ctx-> 6352 provisioned_intf_addr_mask); 6353 hdd_debug("Releasing MAC from provisioned list"); 6354 hdd_debug( 6355 QDF_MAC_ADDR_FMT, 6356 QDF_MAC_ADDR_REF(releaseAddr)); 6357 } else { 6358 qdf_atomic_clear_bit( 6359 mac_pos_in_mask, &hdd_ctx-> 6360 derived_intf_addr_mask); 6361 hdd_debug("Releasing MAC from derived list"); 6362 hdd_debug(QDF_MAC_ADDR_FMT, 6363 QDF_MAC_ADDR_REF(releaseAddr)); 6364 } 6365 qdf_zero_macaddr(&hdd_ctx-> 6366 dynamic_mac_list[i].dynamic_mac); 6367 hdd_ctx->dynamic_mac_list[i].is_provisioned_mac = 6368 false; 6369 hdd_ctx->dynamic_mac_list[i].bit_position = 0; 6370 break; 6371 } 6372 6373 } 6374 if (i == QDF_MAX_CONCURRENCY_PERSONA) 6375 hdd_debug("Releasing non existing MAC " QDF_MAC_ADDR_FMT, 6376 QDF_MAC_ADDR_REF(releaseAddr)); 6377 } 6378 6379 /** 6380 * hdd_set_derived_multicast_list(): Add derived peer multicast address list in 6381 * multicast list request to the FW 6382 * @psoc: Pointer to psoc 6383 * @adapter: Pointer to hdd adapter 6384 * @mc_list_request: Multicast list request to the FW 6385 * @mc_count: number of multicast addresses received from the kernel 6386 * 6387 * Return: None 6388 */ 6389 static void 6390 hdd_set_derived_multicast_list(struct wlan_objmgr_psoc *psoc, 6391 struct hdd_adapter *adapter, 6392 struct pmo_mc_addr_list_params *mc_list_request, 6393 int *mc_count) 6394 { 6395 int i = 0, j = 0, list_count = *mc_count; 6396 struct qdf_mac_addr *peer_mc_addr_list = NULL; 6397 uint8_t driver_mc_cnt = 0; 6398 uint32_t max_ndp_sessions = 0; 6399 6400 cfg_nan_get_ndp_max_sessions(psoc, &max_ndp_sessions); 6401 6402 ucfg_nan_get_peer_mc_list(adapter->deflink->vdev, &peer_mc_addr_list); 6403 6404 for (j = 0; j < max_ndp_sessions; j++) { 6405 for (i = 0; i < list_count; i++) { 6406 if (qdf_is_macaddr_zero(&peer_mc_addr_list[j]) || 6407 qdf_is_macaddr_equal(&mc_list_request->mc_addr[i], 6408 &peer_mc_addr_list[j])) 6409 break; 6410 } 6411 if (i == list_count) { 6412 qdf_mem_copy( 6413 &(mc_list_request->mc_addr[list_count + 6414 driver_mc_cnt].bytes), 6415 peer_mc_addr_list[j].bytes, ETH_ALEN); 6416 hdd_debug("mlist[%d] = " QDF_MAC_ADDR_FMT, 6417 list_count + driver_mc_cnt, 6418 QDF_MAC_ADDR_REF( 6419 mc_list_request->mc_addr[list_count + 6420 driver_mc_cnt].bytes)); 6421 driver_mc_cnt++; 6422 } 6423 } 6424 *mc_count += driver_mc_cnt; 6425 } 6426 6427 /** 6428 * __hdd_set_multicast_list() - set the multicast address list 6429 * @dev: Pointer to the WLAN device. 6430 * 6431 * This function sets the multicast address list. 6432 * 6433 * Return: None 6434 */ 6435 static void __hdd_set_multicast_list(struct net_device *dev) 6436 { 6437 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev); 6438 int i = 0, errno; 6439 struct netdev_hw_addr *ha; 6440 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); 6441 struct pmo_mc_addr_list_params *mc_list_request = NULL; 6442 struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc; 6443 int mc_count = 0; 6444 6445 if (hdd_ctx->hdd_wlan_suspended) { 6446 hdd_err_rl("Device is system suspended"); 6447 return; 6448 } 6449 6450 hdd_enter_dev(dev); 6451 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) 6452 return; 6453 6454 errno = wlan_hdd_validate_context(hdd_ctx); 6455 if (errno) 6456 return; 6457 6458 errno = hdd_validate_adapter(adapter); 6459 if (errno) 6460 return; 6461 6462 if (hdd_ctx->driver_status == DRIVER_MODULES_CLOSED) { 6463 hdd_debug("Driver module is closed"); 6464 return; 6465 } 6466 6467 mc_list_request = qdf_mem_malloc(sizeof(*mc_list_request)); 6468 if (!mc_list_request) 6469 return; 6470 6471 qdf_spin_lock_bh(&adapter->mc_list_lock); 6472 /* Delete already configured multicast address list */ 6473 if (adapter->mc_addr_list.mc_cnt > 0) 6474 hdd_disable_and_flush_mc_addr_list(adapter, 6475 pmo_mc_list_change_notify); 6476 6477 if (dev->flags & IFF_ALLMULTI) { 6478 hdd_debug("allow all multicast frames"); 6479 hdd_disable_and_flush_mc_addr_list(adapter, 6480 pmo_mc_list_change_notify); 6481 } else { 6482 mc_count = netdev_mc_count(dev); 6483 if (mc_count > ucfg_pmo_max_mc_addr_supported(psoc)) { 6484 hdd_debug("Exceeded max MC filter addresses (%d). Allowing all MC frames by disabling MC address filtering", 6485 ucfg_pmo_max_mc_addr_supported(psoc)); 6486 hdd_disable_and_flush_mc_addr_list(adapter, 6487 pmo_mc_list_change_notify); 6488 adapter->mc_addr_list.mc_cnt = 0; 6489 goto free_req; 6490 } 6491 netdev_for_each_mc_addr(ha, dev) { 6492 if (i == mc_count) 6493 break; 6494 memset(&(mc_list_request->mc_addr[i].bytes), 6495 0, ETH_ALEN); 6496 memcpy(&(mc_list_request->mc_addr[i].bytes), 6497 ha->addr, ETH_ALEN); 6498 hdd_debug("mlist[%d] = "QDF_MAC_ADDR_FMT, i, 6499 QDF_MAC_ADDR_REF(mc_list_request->mc_addr[i].bytes)); 6500 i++; 6501 } 6502 6503 if (adapter->device_mode == QDF_NDI_MODE) 6504 hdd_set_derived_multicast_list(psoc, adapter, 6505 mc_list_request, 6506 &mc_count); 6507 } 6508 6509 adapter->mc_addr_list.mc_cnt = mc_count; 6510 mc_list_request->psoc = psoc; 6511 mc_list_request->vdev_id = adapter->deflink->vdev_id; 6512 mc_list_request->count = mc_count; 6513 6514 errno = hdd_cache_mc_addr_list(mc_list_request); 6515 if (errno) { 6516 hdd_debug("Failed to cache MC address list for vdev %u; errno:%d", 6517 adapter->deflink->vdev_id, errno); 6518 goto free_req; 6519 } 6520 6521 hdd_enable_mc_addr_filtering(adapter, pmo_mc_list_change_notify); 6522 6523 free_req: 6524 qdf_spin_unlock_bh(&adapter->mc_list_lock); 6525 qdf_mem_free(mc_list_request); 6526 } 6527 6528 /** 6529 * hdd_set_multicast_list() - SSR wrapper function for __hdd_set_multicast_list 6530 * @net_dev: pointer to net_device 6531 * 6532 * Return: none 6533 */ 6534 static void hdd_set_multicast_list(struct net_device *net_dev) 6535 { 6536 struct osif_vdev_sync *vdev_sync; 6537 6538 if (osif_vdev_sync_op_start(net_dev, &vdev_sync)) 6539 return; 6540 6541 __hdd_set_multicast_list(net_dev); 6542 6543 osif_vdev_sync_op_stop(vdev_sync); 6544 } 6545 6546 void hdd_update_multicast_list(struct wlan_objmgr_vdev *vdev) 6547 { 6548 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 6549 struct wlan_hdd_link_info *link_info; 6550 struct hdd_adapter *adapter; 6551 uint8_t vdev_id = wlan_vdev_get_id(vdev); 6552 struct net_device *net_dev; 6553 6554 if (!hdd_ctx) { 6555 hdd_err("hdd_ctx is null"); 6556 return; 6557 } 6558 6559 link_info = hdd_get_link_info_by_vdev(hdd_ctx, vdev_id); 6560 if (!link_info) { 6561 hdd_err("adapter is null for vdev_id %d", vdev_id); 6562 return; 6563 } 6564 6565 adapter = link_info->adapter; 6566 if (!adapter) { 6567 hdd_err("adapter is null for vdev_id %d", vdev_id); 6568 return; 6569 } 6570 6571 net_dev = adapter->dev; 6572 if (!net_dev) { 6573 hdd_err("netdev is null"); 6574 return; 6575 } 6576 6577 __hdd_set_multicast_list(net_dev); 6578 } 6579 6580 #ifdef WLAN_FEATURE_TSF_PTP 6581 static const struct ethtool_ops wlan_ethtool_ops = { 6582 .get_ts_info = wlan_get_ts_info, 6583 }; 6584 #endif 6585 6586 /** 6587 * __hdd_fix_features - Adjust the feature flags needed to be updated 6588 * @net_dev: Handle to net_device 6589 * @features: Currently enabled feature flags 6590 * 6591 * Return: Adjusted feature flags on success, old feature on failure 6592 */ 6593 static netdev_features_t __hdd_fix_features(struct net_device *net_dev, 6594 netdev_features_t features) 6595 { 6596 netdev_features_t feature_change_req = features; 6597 netdev_features_t feature_tso_csum; 6598 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(net_dev); 6599 6600 if (!adapter->handle_feature_update) { 6601 hdd_debug("Not triggered by hdd_netdev_update_features"); 6602 return features; 6603 } 6604 6605 feature_tso_csum = hdd_get_tso_csum_feature_flags(); 6606 if (hdd_is_legacy_connection(adapter->deflink)) { 6607 /* Disable checksum and TSO */ 6608 feature_change_req &= ~feature_tso_csum; 6609 adapter->tso_csum_feature_enabled = 0; 6610 } else { 6611 /* Enable checksum and TSO */ 6612 feature_change_req |= feature_tso_csum; 6613 adapter->tso_csum_feature_enabled = 1; 6614 } 6615 hdd_debug("vdev mode %d current features 0x%llx, requesting feature change 0x%llx", 6616 adapter->device_mode, net_dev->features, 6617 feature_change_req); 6618 6619 return feature_change_req; 6620 } 6621 6622 /** 6623 * hdd_fix_features() - Wrapper for __hdd_fix_features to protect it from SSR 6624 * @net_dev: Pointer to net_device structure 6625 * @features: Updated features set 6626 * 6627 * Adjusts the feature request, do not update the device yet. 6628 * 6629 * Return: updated feature for success, incoming feature as is on failure 6630 */ 6631 static netdev_features_t hdd_fix_features(struct net_device *net_dev, 6632 netdev_features_t features) 6633 { 6634 int errno; 6635 int changed_features = features; 6636 struct osif_vdev_sync *vdev_sync; 6637 6638 errno = osif_vdev_sync_op_start(net_dev, &vdev_sync); 6639 if (errno) 6640 return features; 6641 6642 changed_features = __hdd_fix_features(net_dev, features); 6643 6644 osif_vdev_sync_op_stop(vdev_sync); 6645 6646 return changed_features; 6647 } 6648 /** 6649 * __hdd_set_features - Notify device about change in features 6650 * @net_dev: Handle to net_device 6651 * @features: Existing + requested feature after resolving the dependency 6652 * 6653 * Return: 0 on success, non zero error on failure 6654 */ 6655 static int __hdd_set_features(struct net_device *net_dev, 6656 netdev_features_t features) 6657 { 6658 struct hdd_adapter *adapter = netdev_priv(net_dev); 6659 ol_txrx_soc_handle soc = cds_get_context(QDF_MODULE_ID_SOC); 6660 6661 if (!adapter->handle_feature_update) { 6662 hdd_debug("Not triggered by hdd_netdev_update_features"); 6663 return 0; 6664 } 6665 6666 if (!soc) 6667 return 0; 6668 6669 hdd_debug("vdev mode %d vdev_id %d current features 0x%llx, changed features 0x%llx", 6670 adapter->device_mode, adapter->deflink->vdev_id, 6671 net_dev->features, features); 6672 6673 return 0; 6674 } 6675 6676 /** 6677 * hdd_set_features() - Wrapper for __hdd_set_features to protect it from SSR 6678 * @net_dev: Pointer to net_device structure 6679 * @features: Updated features set 6680 * 6681 * Is called to update device configurations for changed features. 6682 * 6683 * Return: 0 for success, non-zero for failure 6684 */ 6685 static int hdd_set_features(struct net_device *net_dev, 6686 netdev_features_t features) 6687 { 6688 int errno; 6689 struct osif_vdev_sync *vdev_sync; 6690 6691 errno = osif_vdev_sync_op_start(net_dev, &vdev_sync); 6692 if (errno) { 6693 /* 6694 * Only invoke from netdev_feature_update_work expected, 6695 * which is from CLD inside. 6696 * Ignore others from upper stack during loading phase, 6697 * and return success to avoid failure print from kernel. 6698 */ 6699 hdd_debug("VDEV in transition, ignore set_features"); 6700 return 0; 6701 } 6702 6703 errno = __hdd_set_features(net_dev, features); 6704 6705 osif_vdev_sync_op_stop(vdev_sync); 6706 6707 return errno; 6708 } 6709 6710 #define HDD_NETDEV_FEATURES_UPDATE_MAX_WAIT_COUNT 10 6711 #define HDD_NETDEV_FEATURES_UPDATE_WAIT_INTERVAL_MS 20 6712 6713 void hdd_netdev_update_features(struct hdd_adapter *adapter) 6714 { 6715 struct net_device *net_dev = adapter->dev; 6716 ol_txrx_soc_handle soc = cds_get_context(QDF_MODULE_ID_SOC); 6717 bool request_feature_update = false; 6718 int wait_count = HDD_NETDEV_FEATURES_UPDATE_MAX_WAIT_COUNT; 6719 6720 if (!soc) 6721 return; 6722 6723 if (!cdp_cfg_get(soc, cfg_dp_disable_legacy_mode_csum_offload)) 6724 return; 6725 6726 switch (adapter->device_mode) { 6727 case QDF_STA_MODE: 6728 if (cdp_cfg_get(soc, cfg_dp_enable_ip_tcp_udp_checksum_offload)) 6729 request_feature_update = true; 6730 break; 6731 default: 6732 break; 6733 } 6734 6735 if (request_feature_update) { 6736 hdd_debug("Update net_dev features for device mode %d", 6737 adapter->device_mode); 6738 while (!adapter->delete_in_progress) { 6739 if (rtnl_trylock()) { 6740 adapter->handle_feature_update = true; 6741 netdev_update_features(net_dev); 6742 adapter->handle_feature_update = false; 6743 rtnl_unlock(); 6744 break; 6745 } 6746 6747 if (wait_count--) { 6748 qdf_sleep( 6749 HDD_NETDEV_FEATURES_UPDATE_WAIT_INTERVAL_MS); 6750 } else { 6751 /* 6752 * We have failed to updated the netdev 6753 * features for very long, so enable the queues 6754 * now. The impact of not being able to update 6755 * the netdev feature is lower TPUT when 6756 * switching from legacy to non-legacy mode. 6757 */ 6758 hdd_err("Failed to update netdev features for device mode %d", 6759 adapter->device_mode); 6760 break; 6761 } 6762 } 6763 } 6764 } 6765 6766 static const struct net_device_ops wlan_drv_ops = { 6767 .ndo_open = hdd_open, 6768 .ndo_stop = hdd_stop, 6769 .ndo_uninit = hdd_uninit, 6770 .ndo_start_xmit = hdd_hard_start_xmit, 6771 .ndo_fix_features = hdd_fix_features, 6772 .ndo_set_features = hdd_set_features, 6773 .ndo_tx_timeout = hdd_tx_timeout, 6774 .ndo_get_stats = hdd_get_stats, 6775 #if LINUX_VERSION_CODE < KERNEL_VERSION(5, 15, 0) 6776 .ndo_do_ioctl = hdd_ioctl, 6777 #endif 6778 .ndo_set_mac_address = hdd_set_mac_address, 6779 .ndo_select_queue = hdd_select_queue, 6780 .ndo_set_rx_mode = hdd_set_multicast_list, 6781 #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0) 6782 .ndo_siocdevprivate = hdd_dev_private_ioctl, 6783 #endif 6784 }; 6785 6786 #ifdef FEATURE_MONITOR_MODE_SUPPORT 6787 /* Monitor mode net_device_ops, does not Tx and most of operations. */ 6788 static const struct net_device_ops wlan_mon_drv_ops = { 6789 .ndo_open = hdd_mon_open, 6790 .ndo_stop = hdd_stop, 6791 .ndo_get_stats = hdd_get_stats, 6792 }; 6793 6794 /** 6795 * hdd_set_mon_ops() - update net_device ops for monitor mode 6796 * @dev: Handle to struct net_device to be updated. 6797 * Return: None 6798 */ 6799 static void hdd_set_mon_ops(struct net_device *dev) 6800 { 6801 dev->netdev_ops = &wlan_mon_drv_ops; 6802 } 6803 6804 #ifdef WLAN_FEATURE_TSF_PTP 6805 void hdd_set_station_ops(struct net_device *dev) 6806 { 6807 if (cds_get_conparam() == QDF_GLOBAL_MONITOR_MODE) { 6808 hdd_set_mon_ops(dev); 6809 } else { 6810 dev->netdev_ops = &wlan_drv_ops; 6811 dev->ethtool_ops = &wlan_ethtool_ops; 6812 } 6813 } 6814 #else 6815 void hdd_set_station_ops(struct net_device *dev) 6816 { 6817 if (cds_get_conparam() == QDF_GLOBAL_MONITOR_MODE) 6818 hdd_set_mon_ops(dev); 6819 else 6820 dev->netdev_ops = &wlan_drv_ops; 6821 } 6822 6823 #endif 6824 #else 6825 #ifdef WLAN_FEATURE_TSF_PTP 6826 void hdd_set_station_ops(struct net_device *dev) 6827 { 6828 dev->netdev_ops = &wlan_drv_ops; 6829 dev->ethtool_ops = &wlan_ethtool_ops; 6830 } 6831 #else 6832 void hdd_set_station_ops(struct net_device *dev) 6833 { 6834 dev->netdev_ops = &wlan_drv_ops; 6835 } 6836 #endif 6837 static void hdd_set_mon_ops(struct net_device *dev) 6838 { 6839 } 6840 #endif 6841 6842 #ifdef WLAN_FEATURE_PKT_CAPTURE 6843 /* Packet Capture mode net_device_ops, does not Tx and most of operations. */ 6844 static const struct net_device_ops wlan_pktcapture_drv_ops = { 6845 .ndo_open = hdd_pktcapture_open, 6846 .ndo_stop = hdd_stop, 6847 .ndo_get_stats = hdd_get_stats, 6848 }; 6849 6850 static void hdd_set_pktcapture_ops(struct net_device *dev) 6851 { 6852 dev->netdev_ops = &wlan_pktcapture_drv_ops; 6853 } 6854 #else 6855 static void hdd_set_pktcapture_ops(struct net_device *dev) 6856 { 6857 } 6858 #endif 6859 6860 #ifdef MULTI_CLIENT_LL_SUPPORT 6861 /** 6862 * hdd_set_multi_client_ll_support() - set multi client ll support flag in 6863 * allocated station hdd adapter 6864 * @adapter: pointer to hdd adapter 6865 * 6866 * Return: none 6867 */ 6868 static void hdd_set_multi_client_ll_support(struct hdd_adapter *adapter) 6869 { 6870 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); 6871 bool multi_client_ll_ini_support, multi_client_ll_caps; 6872 6873 ucfg_mlme_cfg_get_multi_client_ll_ini_support(hdd_ctx->psoc, 6874 &multi_client_ll_ini_support); 6875 multi_client_ll_caps = 6876 ucfg_mlme_get_wlm_multi_client_ll_caps(hdd_ctx->psoc); 6877 6878 hdd_debug("fw caps: %d, ini: %d", multi_client_ll_caps, 6879 multi_client_ll_ini_support); 6880 if (multi_client_ll_caps && multi_client_ll_ini_support) 6881 adapter->multi_client_ll_support = true; 6882 } 6883 #else 6884 static inline void 6885 hdd_set_multi_client_ll_support(struct hdd_adapter *adapter) 6886 { 6887 } 6888 #endif 6889 6890 /** 6891 * hdd_alloc_station_adapter() - allocate the station hdd adapter 6892 * @hdd_ctx: global hdd context 6893 * @mac_addr: mac address to assign to the interface 6894 * @name_assign_type: name assignment type 6895 * @name: User-visible name of the interface 6896 * @session_type: interface type to be created 6897 * 6898 * hdd adapter pointer would point to the netdev->priv space, this function 6899 * would retrieve the pointer, and setup the hdd adapter configuration. 6900 * 6901 * Return: the pointer to hdd adapter, otherwise NULL 6902 */ 6903 static struct hdd_adapter * 6904 hdd_alloc_station_adapter(struct hdd_context *hdd_ctx, tSirMacAddr mac_addr, 6905 unsigned char name_assign_type, const char *name, 6906 uint8_t session_type) 6907 { 6908 struct net_device *dev; 6909 struct hdd_adapter *adapter; 6910 QDF_STATUS qdf_status; 6911 uint8_t latency_level; 6912 6913 /* cfg80211 initialization and registration */ 6914 dev = alloc_netdev_mqs(sizeof(*adapter), name, 6915 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS) 6916 name_assign_type, 6917 #endif 6918 ((cds_get_conparam() == QDF_GLOBAL_MONITOR_MODE || 6919 wlan_hdd_is_session_type_monitor(session_type)) ? 6920 hdd_mon_mode_ether_setup : ether_setup), 6921 NUM_TX_QUEUES, NUM_RX_QUEUES); 6922 6923 if (!dev) { 6924 hdd_err("Failed to allocate new net_device '%s'", name); 6925 return NULL; 6926 } 6927 6928 adapter = netdev_priv(dev); 6929 6930 qdf_mem_zero(adapter, sizeof(*adapter)); 6931 adapter->dev = dev; 6932 adapter->deflink = &adapter->link_info[WLAN_HDD_DEFLINK_IDX]; 6933 adapter->hdd_ctx = hdd_ctx; 6934 adapter->magic = WLAN_HDD_ADAPTER_MAGIC; 6935 qdf_atomic_set_bit(WLAN_HDD_DEFLINK_IDX, &adapter->active_links); 6936 6937 qdf_status = hdd_monitor_mode_qdf_create_event(adapter, session_type); 6938 if (QDF_IS_STATUS_ERROR(qdf_status)) { 6939 hdd_err_rl("create monitor mode vdve up event failed"); 6940 goto free_net_dev; 6941 } 6942 6943 hdd_update_dynamic_tsf_sync(adapter); 6944 adapter->is_link_up_service_needed = false; 6945 adapter->send_mode_change = true; 6946 6947 /* Cache station count initialize to zero */ 6948 qdf_atomic_init(&adapter->cache_sta_count); 6949 6950 /* Init the net_device structure */ 6951 strlcpy(dev->name, name, IFNAMSIZ); 6952 6953 qdf_net_update_net_device_dev_addr(dev, mac_addr, sizeof(tSirMacAddr)); 6954 qdf_mem_copy(adapter->mac_addr.bytes, mac_addr, sizeof(tSirMacAddr)); 6955 dev->watchdog_timeo = HDD_TX_TIMEOUT; 6956 6957 if (wlan_hdd_is_session_type_monitor(session_type)) { 6958 if (ucfg_pkt_capture_get_mode(hdd_ctx->psoc) != 6959 PACKET_CAPTURE_MODE_DISABLE) 6960 hdd_set_pktcapture_ops(adapter->dev); 6961 if (ucfg_mlme_is_sta_mon_conc_supported(hdd_ctx->psoc) || 6962 ucfg_dp_is_local_pkt_capture_enabled(hdd_ctx->psoc)) 6963 hdd_set_mon_ops(adapter->dev); 6964 } else { 6965 hdd_set_station_ops(adapter->dev); 6966 } 6967 6968 hdd_dev_setup_destructor(dev); 6969 dev->ieee80211_ptr = &adapter->wdev; 6970 dev->tx_queue_len = HDD_NETDEV_TX_QUEUE_LEN; 6971 adapter->wdev.wiphy = hdd_ctx->wiphy; 6972 adapter->wdev.netdev = dev; 6973 qdf_status = ucfg_mlme_cfg_get_wlm_level(hdd_ctx->psoc, &latency_level); 6974 if (QDF_IS_STATUS_ERROR(qdf_status)) { 6975 hdd_debug("Can't get latency level"); 6976 latency_level = 6977 QCA_WLAN_VENDOR_ATTR_CONFIG_LATENCY_LEVEL_NORMAL; 6978 } 6979 adapter->latency_level = latency_level; 6980 hdd_set_multi_client_ll_support(adapter); 6981 6982 /* set dev's parent to underlying device */ 6983 SET_NETDEV_DEV(dev, hdd_ctx->parent_dev); 6984 spin_lock_init(&adapter->pause_map_lock); 6985 adapter->start_time = qdf_system_ticks(); 6986 adapter->last_time = adapter->start_time; 6987 6988 qdf_atomic_init(&adapter->is_ll_stats_req_pending); 6989 hdd_init_get_sta_in_ll_stats_config(adapter); 6990 hdd_init_link_state_config(adapter); 6991 6992 return adapter; 6993 6994 free_net_dev: 6995 free_netdev(adapter->dev); 6996 6997 return NULL; 6998 } 6999 7000 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 12, 0) || \ 7001 (defined CFG80211_CHANGE_NETDEV_REGISTRATION_SEMANTICS)) 7002 static int 7003 hdd_register_netdevice(struct hdd_adapter *adapter, struct net_device *dev, 7004 struct hdd_adapter_create_param *params) 7005 { 7006 int ret; 7007 7008 if (params->is_add_virtual_iface) 7009 ret = wlan_cfg80211_register_netdevice(dev); 7010 else 7011 ret = register_netdevice(dev); 7012 7013 return ret; 7014 } 7015 #else 7016 static int 7017 hdd_register_netdevice(struct hdd_adapter *adapter, struct net_device *dev, 7018 struct hdd_adapter_create_param *params) 7019 { 7020 return register_netdevice(dev); 7021 } 7022 #endif 7023 7024 static QDF_STATUS 7025 hdd_register_interface(struct hdd_adapter *adapter, bool rtnl_held, 7026 struct hdd_adapter_create_param *params) 7027 { 7028 struct net_device *dev = adapter->dev; 7029 int ret; 7030 7031 hdd_enter(); 7032 7033 if (rtnl_held) { 7034 if (strnchr(dev->name, IFNAMSIZ - 1, '%')) { 7035 7036 ret = dev_alloc_name(dev, dev->name); 7037 if (ret < 0) { 7038 hdd_err( 7039 "unable to get dev name: %s, err = 0x%x", 7040 dev->name, ret); 7041 return QDF_STATUS_E_FAILURE; 7042 } 7043 } 7044 hdd_debug("hdd_register_netdevice(%s) type:%d", dev->name, 7045 adapter->device_mode); 7046 ret = hdd_register_netdevice(adapter, dev, params); 7047 if (ret) { 7048 hdd_err("register_netdevice(%s) failed, err = 0x%x", 7049 dev->name, ret); 7050 return QDF_STATUS_E_FAILURE; 7051 } 7052 } else { 7053 hdd_debug("register_netdev(%s) type:%d", dev->name, 7054 adapter->device_mode); 7055 ret = register_netdev(dev); 7056 if (ret) { 7057 hdd_err("register_netdev(%s) failed, err = 0x%x", 7058 dev->name, ret); 7059 return QDF_STATUS_E_FAILURE; 7060 } 7061 } 7062 set_bit(NET_DEVICE_REGISTERED, &adapter->event_flags); 7063 7064 hdd_exit(); 7065 7066 return QDF_STATUS_SUCCESS; 7067 } 7068 7069 QDF_STATUS hdd_sme_close_session_callback(uint8_t vdev_id) 7070 { 7071 struct hdd_adapter *adapter; 7072 struct hdd_context *hdd_ctx; 7073 struct wlan_hdd_link_info *link_info; 7074 7075 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 7076 if (!hdd_ctx) 7077 return QDF_STATUS_E_FAILURE; 7078 7079 link_info = hdd_get_link_info_by_vdev(hdd_ctx, vdev_id); 7080 if (!link_info) { 7081 hdd_err("Invalid vdev %d", vdev_id); 7082 return QDF_STATUS_E_INVAL; 7083 } 7084 7085 adapter = link_info->adapter; 7086 if (WLAN_HDD_ADAPTER_MAGIC != adapter->magic) { 7087 hdd_err("Invalid magic"); 7088 return QDF_STATUS_NOT_INITIALIZED; 7089 } 7090 7091 clear_bit(SME_SESSION_OPENED, &link_info->link_flags); 7092 qdf_spin_lock_bh(&link_info->vdev_lock); 7093 link_info->vdev_id = WLAN_UMAC_VDEV_ID_MAX; 7094 qdf_spin_unlock_bh(&link_info->vdev_lock); 7095 7096 /* 7097 * We can be blocked while waiting for scheduled work to be 7098 * flushed, and the adapter structure can potentially be freed, in 7099 * which case the magic will have been reset. So make sure the 7100 * magic is still good, and hence the adapter structure is still 7101 * valid, before signaling completion 7102 */ 7103 if (WLAN_HDD_ADAPTER_MAGIC == adapter->magic) 7104 complete(&link_info->vdev_destroy_event); 7105 7106 return QDF_STATUS_SUCCESS; 7107 } 7108 7109 int hdd_vdev_ready(struct wlan_objmgr_vdev *vdev, 7110 struct qdf_mac_addr *bridgeaddr) 7111 { 7112 QDF_STATUS status; 7113 7114 status = pmo_vdev_ready(vdev, bridgeaddr); 7115 if (QDF_IS_STATUS_ERROR(status)) 7116 return qdf_status_to_os_return(status); 7117 7118 status = ucfg_reg_11d_vdev_created_update(vdev); 7119 if (QDF_IS_STATUS_ERROR(status)) 7120 return qdf_status_to_os_return(status); 7121 7122 if (wma_capability_enhanced_mcast_filter()) 7123 status = ucfg_pmo_enhanced_mc_filter_enable(vdev); 7124 else 7125 status = ucfg_pmo_enhanced_mc_filter_disable(vdev); 7126 7127 return qdf_status_to_os_return(status); 7128 } 7129 7130 /** 7131 * hdd_check_wait_for_hw_mode_completion - Check hw mode in progress 7132 * @hdd_ctx: hdd context 7133 * 7134 * Check and wait for hw mode response if any hw mode change is 7135 * in progress. Vdev delete will purge the serialization queue 7136 * for the vdev. It will cause issues when the fw event coming 7137 * up later and no active hw mode change req ser command in queue. 7138 * 7139 * Return void 7140 */ 7141 static void hdd_check_wait_for_hw_mode_completion(struct hdd_context *hdd_ctx) 7142 { 7143 QDF_STATUS status; 7144 7145 if (!wlan_hdd_validate_context(hdd_ctx) && 7146 policy_mgr_is_hw_mode_change_in_progress( 7147 hdd_ctx->psoc)) { 7148 status = policy_mgr_wait_for_connection_update( 7149 hdd_ctx->psoc); 7150 if (!QDF_IS_STATUS_SUCCESS(status)) { 7151 hdd_nofl_debug("qdf wait for hw mode event failed!!"); 7152 } 7153 } 7154 } 7155 7156 static void hdd_stop_last_active_connection(struct hdd_context *hdd_ctx, 7157 struct wlan_objmgr_vdev *vdev) 7158 { 7159 enum policy_mgr_con_mode mode; 7160 struct wlan_objmgr_psoc *psoc; 7161 enum QDF_OPMODE op_mode; 7162 7163 /* If this is the last active connection check 7164 * and stop the opportunistic timer. 7165 */ 7166 psoc = wlan_vdev_get_psoc(vdev); 7167 op_mode = wlan_vdev_mlme_get_opmode(vdev); 7168 mode = policy_mgr_qdf_opmode_to_pm_con_mode(psoc, op_mode, 7169 wlan_vdev_get_id(vdev)); 7170 if ((policy_mgr_get_connection_count(psoc) == 1 && 7171 policy_mgr_mode_specific_connection_count(psoc, 7172 mode, NULL) == 1) || 7173 (!policy_mgr_get_connection_count(psoc) && 7174 !hdd_is_any_sta_connecting(hdd_ctx))) { 7175 policy_mgr_check_and_stop_opportunistic_timer( 7176 psoc, 7177 wlan_vdev_get_id(vdev)); 7178 } 7179 } 7180 7181 static int hdd_vdev_destroy_event_wait(struct hdd_context *hdd_ctx, 7182 struct wlan_objmgr_vdev *vdev) 7183 { 7184 long rc; 7185 QDF_STATUS status; 7186 uint8_t vdev_id; 7187 struct wlan_hdd_link_info *link_info; 7188 struct qdf_mac_addr *mld_addr; 7189 struct wlan_objmgr_psoc *psoc = NULL; 7190 7191 vdev_id = wlan_vdev_get_id(vdev); 7192 link_info = hdd_get_link_info_by_vdev(hdd_ctx, vdev_id); 7193 if (!link_info) { 7194 hdd_err("Invalid vdev"); 7195 return -EINVAL; 7196 } 7197 7198 psoc = wlan_vdev_get_psoc(vdev); 7199 if (!psoc) { 7200 obj_mgr_err("Failed to get psoc"); 7201 return QDF_STATUS_E_FAILURE; 7202 } 7203 7204 /* Detach DP vdev from DP MLO Device Context */ 7205 mld_addr = (struct qdf_mac_addr *)wlan_vdev_mlme_get_mldaddr(vdev); 7206 7207 if (!qdf_is_macaddr_zero(mld_addr)) { 7208 /* only for MLO vdev's */ 7209 7210 if (cdp_mlo_dev_ctxt_detach(wlan_psoc_get_dp_handle(psoc), 7211 wlan_vdev_get_id(vdev), 7212 (uint8_t *)mld_addr) 7213 != QDF_STATUS_SUCCESS) { 7214 obj_mgr_err("Failed to detach DP vdev from DP MLO Dev ctxt"); 7215 QDF_BUG(0); 7216 return QDF_STATUS_E_FAILURE; 7217 } 7218 } 7219 7220 /* close sme session (destroy vdev in firmware via legacy API) */ 7221 INIT_COMPLETION(link_info->vdev_destroy_event); 7222 status = sme_vdev_delete(hdd_ctx->mac_handle, vdev); 7223 if (QDF_IS_STATUS_ERROR(status)) { 7224 hdd_err("vdev %d: failed to delete with status:%d", 7225 vdev_id, status); 7226 return -EAGAIN; 7227 } 7228 7229 /* block on a completion variable until sme session is closed */ 7230 rc = wait_for_completion_timeout( 7231 &link_info->vdev_destroy_event, 7232 msecs_to_jiffies(SME_CMD_VDEV_CREATE_DELETE_TIMEOUT)); 7233 if (!rc) { 7234 hdd_err("vdev %d: timed out waiting for delete", vdev_id); 7235 clear_bit(SME_SESSION_OPENED, &link_info->link_flags); 7236 sme_cleanup_session(hdd_ctx->mac_handle, vdev_id); 7237 cds_flush_logs(WLAN_LOG_TYPE_FATAL, 7238 WLAN_LOG_INDICATOR_HOST_DRIVER, 7239 WLAN_LOG_REASON_VDEV_DELETE_RSP_TIMED_OUT, 7240 true, true); 7241 return -EINVAL; 7242 } 7243 7244 hdd_nofl_info("vdev %d destroyed successfully", vdev_id); 7245 return 0; 7246 } 7247 7248 static inline 7249 void hdd_vdev_deinit_components(struct wlan_objmgr_vdev *vdev) 7250 { 7251 ucfg_pmo_del_wow_pattern(vdev); 7252 ucfg_son_disable_cbs(vdev); 7253 } 7254 7255 static inline 7256 void hdd_reset_vdev_info(struct wlan_hdd_link_info *link_info) 7257 { 7258 qdf_spin_lock_bh(&link_info->vdev_lock); 7259 link_info->vdev = NULL; 7260 qdf_spin_unlock_bh(&link_info->vdev_lock); 7261 } 7262 7263 int hdd_vdev_destroy(struct wlan_hdd_link_info *link_info) 7264 { 7265 int ret; 7266 uint8_t vdev_id; 7267 struct hdd_context *hdd_ctx; 7268 struct wlan_objmgr_vdev *vdev; 7269 struct wlan_objmgr_psoc *psoc; 7270 enum QDF_OPMODE op_mode; 7271 7272 vdev_id = link_info->vdev_id; 7273 hdd_nofl_debug("destroying vdev %d", vdev_id); 7274 /* vdev created sanity check */ 7275 if (!test_bit(SME_SESSION_OPENED, &link_info->link_flags)) { 7276 hdd_nofl_debug("vdev %u does not exist", vdev_id); 7277 return -EINVAL; 7278 } 7279 7280 hdd_ctx = WLAN_HDD_GET_CTX(link_info->adapter); 7281 7282 vdev = hdd_objmgr_get_vdev_by_user(link_info, WLAN_OSIF_ID); 7283 if (!vdev) 7284 return -EINVAL; 7285 7286 psoc = wlan_vdev_get_psoc(vdev); 7287 if (!psoc) { 7288 hdd_err("invalid psoc"); 7289 return -EINVAL; 7290 } 7291 op_mode = wlan_vdev_mlme_get_opmode(vdev); 7292 7293 hdd_stop_last_active_connection(hdd_ctx, vdev); 7294 hdd_check_wait_for_hw_mode_completion(hdd_ctx); 7295 ucfg_scan_vdev_set_disable(vdev, REASON_VDEV_DOWN); 7296 wlan_hdd_scan_abort(link_info); 7297 hdd_vdev_deinit_components(vdev); 7298 hdd_mlo_t2lm_unregister_callback(vdev); 7299 hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_ID); 7300 7301 hdd_reset_vdev_info(link_info); 7302 osif_cm_osif_priv_deinit(vdev); 7303 7304 /* Release the hdd reference */ 7305 wlan_objmgr_vdev_release_ref(vdev, WLAN_HDD_ID_OBJ_MGR); 7306 7307 /* Get runtime lock to prevent runtime suspend */ 7308 qdf_runtime_pm_prevent_suspend(&hdd_ctx->runtime_context.vdev_destroy); 7309 7310 ret = hdd_vdev_destroy_event_wait(hdd_ctx, vdev); 7311 7312 ucfg_reg_11d_vdev_delete_update(psoc, op_mode, vdev_id); 7313 7314 qdf_runtime_pm_allow_suspend(&hdd_ctx->runtime_context.vdev_destroy); 7315 return ret; 7316 } 7317 7318 void 7319 hdd_store_nss_chains_cfg_in_vdev(struct hdd_context *hdd_ctx, 7320 struct wlan_objmgr_vdev *vdev) 7321 { 7322 struct wlan_mlme_nss_chains vdev_ini_cfg; 7323 7324 /* Populate the nss chain params from ini for this vdev type */ 7325 sme_populate_nss_chain_params(hdd_ctx->mac_handle, &vdev_ini_cfg, 7326 wlan_vdev_mlme_get_opmode(vdev), 7327 hdd_ctx->num_rf_chains); 7328 7329 /* Store the nss chain config into the vdev */ 7330 sme_store_nss_chains_cfg_in_vdev(vdev, &vdev_ini_cfg); 7331 } 7332 7333 bool hdd_is_vdev_in_conn_state(struct wlan_hdd_link_info *link_info) 7334 { 7335 switch (link_info->adapter->device_mode) { 7336 case QDF_STA_MODE: 7337 case QDF_P2P_CLIENT_MODE: 7338 case QDF_P2P_DEVICE_MODE: 7339 return hdd_cm_is_vdev_associated(link_info); 7340 case QDF_SAP_MODE: 7341 case QDF_P2P_GO_MODE: 7342 return (test_bit(SOFTAP_BSS_STARTED, 7343 &link_info->link_flags)); 7344 default: 7345 hdd_err("Device mode %d invalid", 7346 link_info->adapter->device_mode); 7347 return 0; 7348 } 7349 } 7350 7351 #define MAX_VDEV_RTT_PARAMS 2 7352 /* params being sent: 7353 * wmi_vdev_param_enable_disable_rtt_responder_role 7354 * wmi_vdev_param_enable_disable_rtt_initiator_role 7355 */ 7356 static QDF_STATUS 7357 hdd_vdev_configure_rtt_params(struct wlan_objmgr_vdev *vdev) 7358 { 7359 QDF_STATUS status; 7360 struct wlan_objmgr_psoc *psoc; 7361 uint32_t fine_time_meas_cap = 0; 7362 uint8_t vdev_id = wlan_vdev_get_id(vdev); 7363 struct dev_set_param vdevsetparam[MAX_VDEV_RTT_PARAMS] = {}; 7364 uint8_t index = 0; 7365 WMI_FW_SUB_FEAT_CAPS wmi_fw_rtt_respr, wmi_fw_rtt_initr; 7366 7367 switch (wlan_vdev_mlme_get_opmode(vdev)) { 7368 case QDF_STA_MODE: 7369 wmi_fw_rtt_respr = WMI_FW_STA_RTT_RESPR; 7370 wmi_fw_rtt_initr = WMI_FW_STA_RTT_INITR; 7371 break; 7372 case QDF_SAP_MODE: 7373 wmi_fw_rtt_respr = WMI_FW_AP_RTT_RESPR; 7374 wmi_fw_rtt_initr = WMI_FW_AP_RTT_INITR; 7375 break; 7376 default: 7377 return QDF_STATUS_SUCCESS; 7378 } 7379 7380 psoc = wlan_vdev_get_psoc(vdev); 7381 7382 ucfg_mlme_get_fine_time_meas_cap(psoc, &fine_time_meas_cap); 7383 status = mlme_check_index_setparam( 7384 vdevsetparam, 7385 wmi_vdev_param_enable_disable_rtt_responder_role, 7386 (fine_time_meas_cap & wmi_fw_rtt_respr), index++, 7387 MAX_VDEV_RTT_PARAMS); 7388 if (QDF_IS_STATUS_ERROR(status)) 7389 return status; 7390 7391 status = mlme_check_index_setparam( 7392 vdevsetparam, 7393 wmi_vdev_param_enable_disable_rtt_initiator_role, 7394 (fine_time_meas_cap & wmi_fw_rtt_initr), index++, 7395 MAX_VDEV_RTT_PARAMS); 7396 if (QDF_IS_STATUS_ERROR(status)) 7397 return status; 7398 7399 status = sme_send_multi_pdev_vdev_set_params(MLME_VDEV_SETPARAM, 7400 vdev_id, vdevsetparam, 7401 index); 7402 if (QDF_IS_STATUS_ERROR(status)) 7403 hdd_err("failed to set RTT_RESPONDER,INITIATOR params:%d", 7404 status); 7405 7406 return status; 7407 } 7408 7409 static void hdd_store_vdev_info(struct wlan_hdd_link_info *link_info, 7410 struct wlan_objmgr_vdev *vdev) 7411 { 7412 struct vdev_osif_priv *osif_priv; 7413 7414 osif_priv = wlan_vdev_get_ospriv(vdev); 7415 if (osif_priv) { 7416 osif_priv->wdev = link_info->adapter->dev->ieee80211_ptr; 7417 osif_priv->legacy_osif_priv = link_info; 7418 } 7419 7420 qdf_spin_lock_bh(&link_info->vdev_lock); 7421 link_info->vdev_id = wlan_vdev_get_id(vdev); 7422 link_info->vdev = vdev; 7423 qdf_spin_unlock_bh(&link_info->vdev_lock); 7424 } 7425 7426 static void 7427 hdd_init_station_context(struct wlan_hdd_link_info *link_info) 7428 { 7429 struct hdd_station_ctx *sta_ctx; 7430 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(link_info->adapter); 7431 7432 /* Set the default operation channel freq and auth type to open */ 7433 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(link_info); 7434 sta_ctx->conn_info.chan_freq = hdd_ctx->config->operating_chan_freq; 7435 sta_ctx->conn_info.auth_type = eCSR_AUTH_TYPE_OPEN_SYSTEM; 7436 hdd_roam_profile_init(link_info); 7437 } 7438 7439 static void hdd_vdev_set_ht_vht_ies(mac_handle_t mac_handle, 7440 struct wlan_objmgr_vdev *vdev) 7441 { 7442 QDF_STATUS status; 7443 struct wlan_objmgr_psoc *psoc; 7444 bool bval = false; 7445 7446 psoc = wlan_vdev_get_psoc(vdev); 7447 status = ucfg_mlme_get_vht_enable2x2(psoc, &bval); 7448 if (QDF_IS_STATUS_ERROR(status)) 7449 hdd_err("unable to get vht_enable2x2"); 7450 7451 sme_set_pdev_ht_vht_ies(mac_handle, bval); 7452 sme_set_vdev_ies_per_band(mac_handle, wlan_vdev_get_id(vdev), 7453 wlan_vdev_mlme_get_opmode(vdev)); 7454 } 7455 7456 static void 7457 hdd_vdev_configure_rtt_mac_randomization(struct wlan_objmgr_psoc *psoc, 7458 struct wlan_objmgr_vdev *vdev) 7459 { 7460 int errno; 7461 QDF_STATUS status; 7462 bool bval = false; 7463 7464 status = ucfg_mlme_get_rtt_mac_randomization(psoc, &bval); 7465 if (QDF_IS_STATUS_ERROR(status)) 7466 hdd_err("unable to get RTT MAC randomization value"); 7467 7468 hdd_debug("setting RTT mac randomization param: %d", bval); 7469 errno = sme_cli_set_command( 7470 wlan_vdev_get_id(vdev), 7471 wmi_vdev_param_enable_disable_rtt_initiator_random_mac, 7472 bval, VDEV_CMD); 7473 7474 if (errno) 7475 hdd_err("RTT mac randomization param set failed %d", errno); 7476 } 7477 7478 static void 7479 hdd_vdev_configure_max_tdls_params(struct wlan_objmgr_psoc *psoc, 7480 struct wlan_objmgr_vdev *vdev) 7481 { 7482 uint16_t max_peer_count; 7483 bool target_bigtk_support = false; 7484 7485 /* 7486 * Max peer can be tdls peers + self peer + bss peer + 7487 * temp bss peer for roaming create/delete peer at same time 7488 */ 7489 max_peer_count = cfg_tdls_get_max_peer_count(psoc); 7490 max_peer_count += 3; 7491 wlan_vdev_set_max_peer_count(vdev, max_peer_count); 7492 7493 ucfg_mlme_get_bigtk_support(psoc, &target_bigtk_support); 7494 if (target_bigtk_support) 7495 mlme_set_bigtk_support(vdev, true); 7496 } 7497 7498 static inline void 7499 hdd_vdev_configure_nan_params(struct wlan_objmgr_psoc *psoc, 7500 struct wlan_objmgr_vdev *vdev) 7501 { 7502 sme_cli_set_command( 7503 wlan_vdev_get_id(vdev), 7504 wmi_vdev_param_allow_nan_initial_discovery_of_mp0_cluster, 7505 cfg_nan_get_support_mp0_discovery(psoc), VDEV_CMD); 7506 } 7507 7508 #if defined(WLAN_FEATURE_11BE_MLO) && defined(WLAN_EXTERNAL_AUTH_MLO_SUPPORT) 7509 static void 7510 hdd_set_vdev_mlo_external_sae_auth_conversion(struct wlan_objmgr_vdev *vdev, 7511 enum QDF_OPMODE mode) 7512 { 7513 if (mode == QDF_STA_MODE || mode == QDF_SAP_MODE) 7514 wlan_vdev_set_mlo_external_sae_auth_conversion(vdev, true); 7515 } 7516 #else 7517 static inline void 7518 hdd_set_vdev_mlo_external_sae_auth_conversion(struct wlan_objmgr_vdev *vdev, 7519 enum QDF_OPMODE mode) 7520 { 7521 } 7522 #endif 7523 7524 static void 7525 hdd_vdev_configure_rtscts_enable(struct hdd_context *hdd_ctx, 7526 struct wlan_objmgr_vdev *vdev) 7527 { 7528 int ret; 7529 QDF_STATUS status; 7530 uint16_t rts_profile = 0; 7531 7532 if (cds_get_conparam() == QDF_GLOBAL_FTM_MODE) 7533 return; 7534 7535 status = ucfg_fwol_get_rts_profile(hdd_ctx->psoc, &rts_profile); 7536 if (QDF_IS_STATUS_ERROR(status)) { 7537 hdd_err("FAILED TO GET RTSCTS Profile status:%d", status); 7538 return; 7539 } 7540 7541 ret = sme_cli_set_command(wlan_vdev_get_id(vdev), 7542 wmi_vdev_param_enable_rtscts, 7543 rts_profile, 7544 VDEV_CMD); 7545 if (ret) 7546 hdd_err("FAILED TO SET RTSCTS Profile ret:%d", ret); 7547 } 7548 7549 static void 7550 hdd_vdev_configure_usr_ps_params(struct wlan_objmgr_psoc *psoc, 7551 struct wlan_objmgr_vdev *vdev, 7552 struct wlan_hdd_link_info *link_info) 7553 { 7554 struct hdd_adapter *adapter = link_info->adapter; 7555 7556 if (cds_get_conparam() == QDF_GLOBAL_FTM_MODE || !adapter) 7557 return; 7558 7559 ucfg_mlme_set_user_ps(psoc, wlan_vdev_get_id(vdev), 7560 adapter->allow_power_save); 7561 } 7562 7563 static void 7564 hdd_vdev_configure_opmode_params(struct hdd_context *hdd_ctx, 7565 struct wlan_objmgr_vdev *vdev, 7566 struct wlan_hdd_link_info *link_info) 7567 { 7568 struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc; 7569 enum QDF_OPMODE opmode = wlan_vdev_mlme_get_opmode(vdev); 7570 7571 switch (opmode) { 7572 case QDF_STA_MODE: 7573 hdd_vdev_configure_rtt_mac_randomization(psoc, vdev); 7574 hdd_vdev_configure_max_tdls_params(psoc, vdev); 7575 hdd_vdev_configure_usr_ps_params(psoc, vdev, link_info); 7576 break; 7577 case QDF_P2P_CLIENT_MODE: 7578 hdd_vdev_configure_max_tdls_params(psoc, vdev); 7579 hdd_vdev_configure_usr_ps_params(psoc, vdev, link_info); 7580 break; 7581 case QDF_NAN_DISC_MODE: 7582 hdd_vdev_configure_nan_params(psoc, vdev); 7583 break; 7584 default: 7585 break; 7586 } 7587 7588 ucfg_fwol_configure_vdev_params(psoc, vdev); 7589 hdd_set_vdev_mlo_external_sae_auth_conversion(vdev, opmode); 7590 hdd_store_nss_chains_cfg_in_vdev(hdd_ctx, vdev); 7591 hdd_vdev_configure_rtscts_enable(hdd_ctx, vdev); 7592 } 7593 7594 #if defined(WLAN_FEATURE_11BE_MLO) && defined(CFG80211_11BE_BASIC) && \ 7595 defined(WLAN_HDD_MULTI_VDEV_SINGLE_NDEV) 7596 static int 7597 hdd_populate_vdev_create_params(struct wlan_hdd_link_info *link_info, 7598 struct wlan_vdev_create_params *vdev_params) 7599 { 7600 struct hdd_adapter *adapter = link_info->adapter; 7601 7602 vdev_params->opmode = adapter->device_mode; 7603 vdev_params->size_vdev_priv = sizeof(struct vdev_osif_priv); 7604 7605 if (hdd_adapter_is_ml_adapter(adapter)) { 7606 qdf_ether_addr_copy(vdev_params->mldaddr, 7607 adapter->mac_addr.bytes); 7608 qdf_ether_addr_copy(vdev_params->macaddr, 7609 link_info->link_addr.bytes); 7610 } else { 7611 qdf_ether_addr_copy(vdev_params->macaddr, 7612 adapter->mac_addr.bytes); 7613 } 7614 return 0; 7615 } 7616 #elif defined(WLAN_FEATURE_11BE_MLO) && defined(CFG80211_11BE_BASIC) 7617 static int 7618 hdd_populate_vdev_create_params(struct wlan_hdd_link_info *link_info, 7619 struct wlan_vdev_create_params *vdev_params) 7620 { 7621 struct hdd_adapter *adapter = link_info->adapter; 7622 struct hdd_mlo_adapter_info *mlo_adapter_info; 7623 struct hdd_adapter *link_adapter; 7624 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); 7625 bool eht_capab; 7626 7627 hdd_enter_dev(adapter->dev); 7628 mlo_adapter_info = &adapter->mlo_adapter_info; 7629 7630 ucfg_psoc_mlme_get_11be_capab(hdd_ctx->psoc, &eht_capab); 7631 if (mlo_adapter_info->is_ml_adapter && eht_capab && 7632 adapter->device_mode == QDF_STA_MODE) { 7633 link_adapter = hdd_get_assoc_link_adapter(adapter); 7634 if (link_adapter) { 7635 qdf_ether_addr_copy(vdev_params->macaddr, 7636 link_adapter->mac_addr.bytes); 7637 } else { 7638 return -EINVAL; 7639 } 7640 } else { 7641 qdf_ether_addr_copy(vdev_params->macaddr, 7642 adapter->mac_addr.bytes); 7643 } 7644 7645 vdev_params->opmode = adapter->device_mode; 7646 7647 if (eht_capab) { 7648 qdf_ether_addr_copy(vdev_params->mldaddr, 7649 adapter->mld_addr.bytes); 7650 } 7651 7652 vdev_params->size_vdev_priv = sizeof(struct vdev_osif_priv); 7653 hdd_exit(); 7654 7655 return 0; 7656 } 7657 #else 7658 static int 7659 hdd_populate_vdev_create_params(struct wlan_hdd_link_info *link_info, 7660 struct wlan_vdev_create_params *vdev_params) 7661 { 7662 struct hdd_adapter *adapter = link_info->adapter; 7663 7664 vdev_params->opmode = adapter->device_mode; 7665 qdf_ether_addr_copy(vdev_params->macaddr, adapter->mac_addr.bytes); 7666 vdev_params->size_vdev_priv = sizeof(struct vdev_osif_priv); 7667 return 0; 7668 } 7669 #endif 7670 7671 int hdd_vdev_create(struct wlan_hdd_link_info *link_info) 7672 { 7673 QDF_STATUS status; 7674 int errno = 0; 7675 struct hdd_adapter *adapter = link_info->adapter; 7676 struct hdd_context *hdd_ctx; 7677 struct wlan_objmgr_vdev *vdev; 7678 struct wlan_vdev_create_params vdev_params = {0}; 7679 7680 hdd_nofl_debug("creating new vdev"); 7681 7682 /* do vdev create via objmgr */ 7683 hdd_ctx = WLAN_HDD_GET_CTX(adapter); 7684 7685 errno = hdd_populate_vdev_create_params(link_info, &vdev_params); 7686 if (errno) 7687 return errno; 7688 7689 vdev = sme_vdev_create(hdd_ctx->mac_handle, &vdev_params); 7690 if (!vdev) { 7691 hdd_err("failed to create vdev"); 7692 return -EINVAL; 7693 } 7694 7695 if (wlan_objmgr_vdev_try_get_ref(vdev, WLAN_HDD_ID_OBJ_MGR) != 7696 QDF_STATUS_SUCCESS) { 7697 errno = QDF_STATUS_E_INVAL; 7698 sme_vdev_delete(hdd_ctx->mac_handle, vdev); 7699 return -EINVAL; 7700 } 7701 7702 hdd_store_vdev_info(link_info, vdev); 7703 osif_cm_osif_priv_init(vdev); 7704 7705 if (hdd_adapter_is_ml_adapter(adapter)) 7706 hdd_mlo_t2lm_register_callback(vdev); 7707 7708 set_bit(SME_SESSION_OPENED, &link_info->link_flags); 7709 status = sme_vdev_post_vdev_create_setup(hdd_ctx->mac_handle, vdev); 7710 if (QDF_IS_STATUS_ERROR(status)) { 7711 hdd_err("Failed to setup the vdev"); 7712 errno = qdf_status_to_os_return(status); 7713 goto hdd_vdev_destroy_procedure; 7714 } 7715 7716 /* firmware ready for component communication, raise vdev_ready event */ 7717 errno = hdd_vdev_ready(vdev, 7718 (struct qdf_mac_addr *)hdd_ctx->bridgeaddr); 7719 if (errno) { 7720 hdd_err("failed to dispatch vdev ready event: %d", errno); 7721 goto hdd_vdev_destroy_procedure; 7722 } 7723 7724 hdd_vdev_configure_opmode_params(hdd_ctx, vdev, link_info); 7725 7726 hdd_nofl_debug("vdev %d created successfully", link_info->vdev_id); 7727 7728 return errno; 7729 7730 hdd_vdev_destroy_procedure: 7731 QDF_BUG(!hdd_vdev_destroy(link_info)); 7732 7733 return errno; 7734 } 7735 7736 QDF_STATUS hdd_init_station_mode(struct wlan_hdd_link_info *link_info) 7737 { 7738 struct hdd_adapter *adapter = link_info->adapter; 7739 struct hdd_context *hdd_ctx; 7740 QDF_STATUS status; 7741 mac_handle_t mac_handle; 7742 uint32_t roam_triggers; 7743 struct wlan_objmgr_vdev *vdev; 7744 7745 hdd_ctx = WLAN_HDD_GET_CTX(adapter); 7746 mac_handle = hdd_ctx->mac_handle; 7747 7748 vdev = hdd_objmgr_get_vdev_by_user(link_info, WLAN_INIT_DEINIT_ID); 7749 if (!vdev) { 7750 status = QDF_STATUS_E_NULL_VALUE; 7751 goto vdev_destroy; 7752 } 7753 7754 hdd_vdev_set_ht_vht_ies(mac_handle, vdev); 7755 hdd_init_station_context(link_info); 7756 7757 status = hdd_wmm_adapter_init(adapter); 7758 if (QDF_STATUS_SUCCESS != status) { 7759 hdd_err("hdd_wmm_adapter_init() failed, status code %08d [x%08x]", 7760 status, status); 7761 goto error_wmm_init; 7762 } 7763 set_bit(WMM_INIT_DONE, &adapter->event_flags); 7764 7765 /* rcpi info initialization */ 7766 qdf_mem_zero(&adapter->rcpi, sizeof(adapter->rcpi)); 7767 7768 if (adapter->device_mode == QDF_STA_MODE) { 7769 roam_triggers = ucfg_mlme_get_roaming_triggers(hdd_ctx->psoc); 7770 mlme_set_roam_trigger_bitmap(hdd_ctx->psoc, 7771 link_info->vdev_id, 7772 roam_triggers); 7773 7774 status = hdd_vdev_configure_rtt_params(vdev); 7775 if (QDF_IS_STATUS_ERROR(status)) 7776 goto error_wmm_init; 7777 } 7778 7779 hdd_tsf_auto_report_init(adapter); 7780 hdd_objmgr_put_vdev_by_user(vdev, WLAN_INIT_DEINIT_ID); 7781 7782 return QDF_STATUS_SUCCESS; 7783 7784 error_wmm_init: 7785 hdd_objmgr_put_vdev_by_user(vdev, WLAN_INIT_DEINIT_ID); 7786 7787 vdev_destroy: 7788 QDF_BUG(!hdd_vdev_destroy(link_info)); 7789 7790 return status; 7791 } 7792 7793 static char *net_dev_ref_debug_string_from_id(wlan_net_dev_ref_dbgid dbgid) 7794 { 7795 static const char *strings[] = { 7796 "NET_DEV_HOLD_ID_RESERVED", 7797 "NET_DEV_HOLD_GET_STA_CONNECTION_IN_PROGRESS", 7798 "NET_DEV_HOLD_CHECK_DFS_CHANNEL_FOR_ADAPTER", 7799 "NET_DEV_HOLD_GET_SAP_OPERATING_BAND", 7800 "NET_DEV_HOLD_RECOVERY_NOTIFIER_CALL", 7801 "NET_DEV_HOLD_IS_ANY_STA_CONNECTING", 7802 "NET_DEV_HOLD_SAP_DESTROY_CTX_ALL", 7803 "NET_DEV_HOLD_DRV_CMD_MAX_TX_POWER", 7804 "NET_DEV_HOLD_IPA_SET_TX_FLOW_INFO", 7805 "NET_DEV_HOLD_SET_RPS_CPU_MASK", 7806 "NET_DEV_HOLD_DFS_INDICATE_RADAR", 7807 "NET_DEV_HOLD_MAX_STA_INTERFACE_UP_COUNT_REACHED", 7808 "NET_DEV_HOLD_IS_CHAN_SWITCH_IN_PROGRESS", 7809 "NET_DEV_HOLD_STA_DESTROY_CTX_ALL", 7810 "NET_DEV_HOLD_CHECK_FOR_EXISTING_MACADDR", 7811 "NET_DEV_HOLD_DEINIT_ALL_ADAPTERS", 7812 "NET_DEV_HOLD_STOP_ALL_ADAPTERS", 7813 "NET_DEV_HOLD_RESET_ALL_ADAPTERS", 7814 "NET_DEV_HOLD_IS_ANY_INTERFACE_OPEN", 7815 "NET_DEV_HOLD_START_ALL_ADAPTERS", 7816 "NET_DEV_HOLD_GET_ADAPTER_BY_RAND_MACADDR", 7817 "NET_DEV_HOLD_GET_ADAPTER_BY_MACADDR", 7818 "NET_DEV_HOLD_GET_ADAPTER_BY_VDEV", 7819 "NET_DEV_HOLD_ADAPTER_GET_BY_REFERENCE", 7820 "NET_DEV_HOLD_GET_ADAPTER_BY_IFACE_NAME", 7821 "NET_DEV_HOLD_GET_ADAPTER", 7822 "NET_DEV_HOLD_GET_OPERATING_CHAN_FREQ", 7823 "NET_DEV_HOLD_UNREGISTER_WEXT_ALL_ADAPTERS", 7824 "NET_DEV_HOLD_ABORT_MAC_SCAN_ALL_ADAPTERS", 7825 "NET_DEV_HOLD_ABORT_SCHED_SCAN_ALL_ADAPTERS", 7826 "NET_DEV_HOLD_GET_FIRST_VALID_ADAPTER", 7827 "NET_DEV_HOLD_CLEAR_RPS_CPU_MASK", 7828 "NET_DEV_HOLD_BUS_BW_WORK_HANDLER", 7829 "NET_DEV_HOLD_DISPLAY_NETIF_QUEUE_HISTORY_COMPACT", 7830 "NET_DEV_HOLD_DISPLAY_NETIF_QUEUE_HISTORY", 7831 "NET_DEV_HOLD_CLEAR_NETIF_QUEUE_HISTORY", 7832 "NET_DEV_HOLD_UNSAFE_CHANNEL_RESTART_SAP", 7833 "NET_DEV_HOLD_INDICATE_MGMT_FRAME", 7834 "NET_DEV_HOLD_STATE_INFO_DUMP", 7835 "NET_DEV_HOLD_DISABLE_ROAMING", 7836 "NET_DEV_HOLD_ENABLE_ROAMING", 7837 "NET_DEV_HOLD_AUTO_SHUTDOWN_ENABLE", 7838 "NET_DEV_HOLD_GET_CON_SAP_ADAPTER", 7839 "NET_DEV_HOLD_IS_ANY_ADAPTER_CONNECTED", 7840 "NET_DEV_HOLD_IS_ROAMING_IN_PROGRESS", 7841 "NET_DEV_HOLD_DEL_P2P_INTERFACE", 7842 "NET_DEV_HOLD_IS_NDP_ALLOWED", 7843 "NET_DEV_HOLD_NDI_OPEN", 7844 "NET_DEV_HOLD_SEND_OEM_REG_RSP_NLINK_MSG", 7845 "NET_DEV_HOLD_PERIODIC_STA_STATS_DISPLAY", 7846 "NET_DEV_HOLD_SUSPEND_WLAN", 7847 "NET_DEV_HOLD_RESUME_WLAN", 7848 "NET_DEV_HOLD_SSR_RESTART_SAP", 7849 "NET_DEV_HOLD_SEND_DEFAULT_SCAN_IES", 7850 "NET_DEV_HOLD_CFG80211_SUSPEND_WLAN", 7851 "NET_DEV_HOLD_COUNTRY_CHANGE_UPDATE_STA", 7852 "NET_DEV_HOLD_COUNTRY_CHANGE_UPDATE_SAP", 7853 "NET_DEV_HOLD_CACHE_STATION_STATS_CB", 7854 "NET_DEV_HOLD_DISPLAY_TXRX_STATS", 7855 "NET_DEV_HOLD_START_PRE_CAC_TRANS", 7856 "NET_DEV_HOLD_IS_ANY_STA_CONNECTED", 7857 "NET_DEV_HOLD_GET_ADAPTER_BY_BSSID", 7858 "NET_DEV_HOLD_ALLOW_NEW_INTF", 7859 "NET_DEV_HOLD_ID_MAX"}; 7860 int32_t num_dbg_strings = QDF_ARRAY_SIZE(strings); 7861 7862 if (dbgid >= num_dbg_strings) { 7863 char *ret = ""; 7864 7865 hdd_err("Debug string not found for debug id %d", dbgid); 7866 return ret; 7867 } 7868 7869 return (char *)strings[dbgid]; 7870 } 7871 7872 void hdd_check_for_net_dev_ref_leak(struct hdd_adapter *adapter) 7873 { 7874 int i, id; 7875 7876 for (id = 0; id < NET_DEV_HOLD_ID_MAX; id++) { 7877 for (i = 0; i < MAX_NET_DEV_REF_LEAK_ITERATIONS; i++) { 7878 if (!qdf_atomic_read( 7879 &adapter->net_dev_hold_ref_count[id])) 7880 break; 7881 hdd_info("net_dev held for debug id %s", 7882 net_dev_ref_debug_string_from_id(id)); 7883 qdf_sleep(NET_DEV_REF_LEAK_ITERATION_SLEEP_TIME_MS); 7884 } 7885 if (i == MAX_NET_DEV_REF_LEAK_ITERATIONS) { 7886 hdd_err("net_dev hold reference leak detected for debug id: %s", 7887 net_dev_ref_debug_string_from_id(id)); 7888 QDF_BUG(0); 7889 } 7890 } 7891 } 7892 7893 /** 7894 * hdd_deinit_station_mode() - De-initialize the station adapter 7895 * @adapter: HDD adapter pointer 7896 * 7897 * This function De-initializes the STA/P2P/OCB adapter. 7898 * 7899 * Return: None. 7900 */ 7901 static void hdd_deinit_station_mode(struct hdd_adapter *adapter) 7902 { 7903 if (test_bit(WMM_INIT_DONE, &adapter->event_flags)) { 7904 hdd_wmm_adapter_close(adapter); 7905 clear_bit(WMM_INIT_DONE, &adapter->event_flags); 7906 } 7907 } 7908 7909 void hdd_deinit_session(struct hdd_adapter *adapter) 7910 { 7911 struct wlan_hdd_link_info *link_info; 7912 7913 hdd_enter(); 7914 7915 switch (adapter->device_mode) { 7916 case QDF_STA_MODE: 7917 case QDF_P2P_CLIENT_MODE: 7918 case QDF_MONITOR_MODE: 7919 case QDF_P2P_DEVICE_MODE: 7920 case QDF_NDI_MODE: 7921 case QDF_NAN_DISC_MODE: 7922 { 7923 hdd_deinit_station_mode(adapter); 7924 break; 7925 } 7926 7927 case QDF_SAP_MODE: 7928 case QDF_P2P_GO_MODE: 7929 { 7930 hdd_adapter_for_each_active_link_info(adapter, link_info) 7931 hdd_deinit_ap_mode(link_info); 7932 break; 7933 } 7934 7935 default: 7936 break; 7937 } 7938 7939 if (adapter->scan_info.default_scan_ies) { 7940 qdf_mem_free(adapter->scan_info.default_scan_ies); 7941 adapter->scan_info.default_scan_ies = NULL; 7942 adapter->scan_info.default_scan_ies_len = 0; 7943 } 7944 7945 hdd_exit(); 7946 } 7947 7948 void hdd_deinit_adapter(struct hdd_context *hdd_ctx, 7949 struct hdd_adapter *adapter, 7950 bool rtnl_held) 7951 { 7952 hdd_enter_dev(adapter->dev); 7953 7954 hdd_wext_unregister(adapter->dev, rtnl_held); 7955 hdd_deinit_session(adapter); 7956 hdd_exit(); 7957 } 7958 7959 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0)) && \ 7960 defined(WLAN_FEATURE_11AX) 7961 /** 7962 * hdd_cleanup_he_operation_info() - cleanup he operation info 7963 * @link_info: pointer to link_info struct in adapter 7964 * 7965 * This function destroys he operation information 7966 * 7967 * Return: none 7968 */ 7969 static void hdd_cleanup_he_operation_info(struct wlan_hdd_link_info *link_info) 7970 { 7971 struct hdd_station_ctx *hdd_sta_ctx; 7972 7973 hdd_debug("cleanup he operation info"); 7974 7975 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(link_info); 7976 7977 if (hdd_sta_ctx->cache_conn_info.he_operation) { 7978 qdf_mem_free(hdd_sta_ctx->cache_conn_info.he_operation); 7979 hdd_sta_ctx->cache_conn_info.he_operation = NULL; 7980 } 7981 } 7982 #else 7983 static inline void 7984 hdd_cleanup_he_operation_info(struct wlan_hdd_link_info *link_info) 7985 { 7986 } 7987 #endif 7988 7989 /** 7990 * hdd_cleanup_prev_ap_bcn_ie() - cleanup previous ap beacon ie 7991 * @link_info: pointer to link_info struct in adapter 7992 * 7993 * This function destroys previous ap beacon information 7994 * 7995 * Return: none 7996 */ 7997 static void hdd_cleanup_prev_ap_bcn_ie(struct wlan_hdd_link_info *link_info) 7998 { 7999 struct hdd_station_ctx *hdd_sta_ctx; 8000 struct element_info *bcn_ie; 8001 8002 hdd_debug("cleanup previous ap bcn ie"); 8003 8004 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(link_info); 8005 bcn_ie = &hdd_sta_ctx->conn_info.prev_ap_bcn_ie; 8006 8007 if (bcn_ie->ptr) { 8008 qdf_mem_free(bcn_ie->ptr); 8009 bcn_ie->ptr = NULL; 8010 bcn_ie->len = 0; 8011 } 8012 } 8013 8014 void hdd_cleanup_conn_info(struct wlan_hdd_link_info *link_info) 8015 { 8016 hdd_cleanup_he_operation_info(link_info); 8017 hdd_cleanup_prev_ap_bcn_ie(link_info); 8018 } 8019 8020 /** 8021 * hdd_sta_destroy_ctx_all() - cleanup all station contexts 8022 * @hdd_ctx: Global HDD context 8023 * 8024 * This function destroys all the station contexts 8025 * 8026 * Return: none 8027 */ 8028 static void hdd_sta_destroy_ctx_all(struct hdd_context *hdd_ctx) 8029 { 8030 struct hdd_adapter *adapter, *next_adapter = NULL; 8031 struct wlan_hdd_link_info *link_info; 8032 8033 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 8034 NET_DEV_HOLD_STA_DESTROY_CTX_ALL) { 8035 if (adapter->device_mode == QDF_STA_MODE) { 8036 hdd_adapter_for_each_link_info(adapter, link_info) { 8037 hdd_cleanup_conn_info(link_info); 8038 } 8039 } 8040 hdd_adapter_dev_put_debug(adapter, 8041 NET_DEV_HOLD_STA_DESTROY_CTX_ALL); 8042 } 8043 } 8044 8045 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 12, 0) || \ 8046 (defined CFG80211_CHANGE_NETDEV_REGISTRATION_SEMANTICS)) 8047 static void 8048 hdd_unregister_netdevice(struct hdd_adapter *adapter, struct net_device *dev) 8049 { 8050 if (adapter->is_virtual_iface) { 8051 wlan_cfg80211_unregister_netdevice(dev); 8052 adapter->is_virtual_iface = false; 8053 } else { 8054 unregister_netdevice(dev); 8055 } 8056 } 8057 #else 8058 static void 8059 hdd_unregister_netdevice(struct hdd_adapter *adapter, struct net_device *dev) 8060 { 8061 unregister_netdevice(dev); 8062 } 8063 #endif 8064 8065 static inline void hdd_adapter_destroy_vdev_info(struct hdd_adapter *adapter) 8066 { 8067 struct wlan_hdd_link_info *link_info; 8068 8069 hdd_adapter_for_each_link_info(adapter, link_info) { 8070 qdf_event_destroy(&link_info->acs_complete_event); 8071 qdf_spinlock_destroy(&link_info->vdev_lock); 8072 } 8073 } 8074 8075 static void hdd_cleanup_adapter(struct hdd_context *hdd_ctx, 8076 struct hdd_adapter *adapter, 8077 bool rtnl_held) 8078 { 8079 struct net_device *dev = NULL; 8080 8081 if (adapter) 8082 dev = adapter->dev; 8083 else { 8084 hdd_err("adapter is Null"); 8085 return; 8086 } 8087 8088 hdd_apf_context_destroy(adapter); 8089 qdf_spinlock_destroy(&adapter->mc_list_lock); 8090 hdd_adapter_destroy_vdev_info(adapter); 8091 hdd_sta_info_deinit(&adapter->sta_info_list); 8092 hdd_sta_info_deinit(&adapter->cache_sta_info_list); 8093 8094 wlan_hdd_debugfs_csr_deinit(adapter); 8095 8096 hdd_debugfs_exit(adapter); 8097 8098 /* 8099 * The adapter is marked as closed. When hdd_wlan_exit() call returns, 8100 * the driver is almost closed and cannot handle either control 8101 * messages or data. However, unregister_netdevice() call above will 8102 * eventually invoke hdd_stop(ndo_close) driver callback, which attempts 8103 * to close the active connections(basically excites control path) which 8104 * is not right. Setting this flag helps hdd_stop() to recognize that 8105 * the interface is closed and restricts any operations on that 8106 */ 8107 clear_bit(DEVICE_IFACE_OPENED, &adapter->event_flags); 8108 8109 if (test_bit(NET_DEVICE_REGISTERED, &adapter->event_flags)) { 8110 if (rtnl_held) { 8111 hdd_debug("hdd_unregister_netdevice(%s) type:%d", 8112 dev->name, adapter->device_mode); 8113 hdd_unregister_netdevice(adapter, dev); 8114 } else { 8115 hdd_debug("unregister_netdev(%s) type:%d", dev->name, 8116 adapter->device_mode); 8117 unregister_netdev(dev); 8118 } 8119 /* 8120 * Note that the adapter is no longer valid at this point 8121 * since the memory has been reclaimed 8122 */ 8123 } 8124 } 8125 8126 static QDF_STATUS hdd_check_for_existing_macaddr(struct hdd_context *hdd_ctx, 8127 tSirMacAddr mac_addr) 8128 { 8129 struct hdd_adapter *adapter, *next_adapter = NULL; 8130 wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_CHECK_FOR_EXISTING_MACADDR; 8131 8132 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 8133 dbgid) { 8134 if (!qdf_mem_cmp(adapter->mac_addr.bytes, 8135 mac_addr, sizeof(tSirMacAddr))) { 8136 hdd_adapter_dev_put_debug(adapter, dbgid); 8137 if (next_adapter) 8138 hdd_adapter_dev_put_debug(next_adapter, 8139 dbgid); 8140 return QDF_STATUS_E_FAILURE; 8141 } 8142 hdd_adapter_dev_put_debug(adapter, dbgid); 8143 } 8144 8145 return QDF_STATUS_SUCCESS; 8146 } 8147 8148 /** 8149 * hdd_configure_chain_mask() - programs chain mask to firmware 8150 * @adapter: HDD adapter 8151 * 8152 * Return: 0 on success or errno on failure 8153 */ 8154 static int hdd_configure_chain_mask(struct hdd_adapter *adapter) 8155 { 8156 QDF_STATUS status; 8157 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); 8158 8159 status = ucfg_mlme_configure_chain_mask(hdd_ctx->psoc, 8160 adapter->deflink->vdev_id); 8161 if (QDF_IS_STATUS_ERROR(status)) 8162 goto error; 8163 8164 return 0; 8165 8166 error: 8167 hdd_debug("WMI PDEV set param failed"); 8168 return -EINVAL; 8169 } 8170 8171 void hdd_adapter_update_mlo_mgr_mac_addr(struct hdd_adapter *adapter) 8172 { 8173 int i = 0; 8174 struct wlan_hdd_link_info *link_info; 8175 struct wlan_mlo_link_mac_update link_mac = {0}; 8176 8177 if (!hdd_adapter_is_ml_adapter(adapter)) 8178 return; 8179 8180 hdd_adapter_for_each_link_info(adapter, link_info) { 8181 link_mac.link_mac_info[i].vdev_id = link_info->vdev_id; 8182 qdf_copy_macaddr(&link_mac.link_mac_info[i++].link_mac_addr, 8183 &link_info->link_addr); 8184 } 8185 8186 link_mac.num_mac_update = i; 8187 mlo_mgr_update_link_info_mac_addr(adapter->deflink->vdev, &link_mac); 8188 } 8189 8190 #ifdef FEATURE_COEX 8191 /** 8192 * hdd_send_coex_config_params() - Send coex config params to FW 8193 * @hdd_ctx: HDD context 8194 * @adapter: Primary adapter context 8195 * 8196 * This function is used to send all coex config related params to FW 8197 * 8198 * Return: 0 on success and -EINVAL on failure 8199 */ 8200 static int hdd_send_coex_config_params(struct hdd_context *hdd_ctx, 8201 struct hdd_adapter *adapter) 8202 { 8203 struct wlan_objmgr_vdev *vdev; 8204 struct coex_config_params coex_cfg_params = {0}; 8205 struct coex_multi_config *coex_multi_cfg = NULL; 8206 struct wlan_fwol_coex_config config = {0}; 8207 struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc; 8208 enum coex_btc_chain_mode btc_chain_mode; 8209 QDF_STATUS status; 8210 uint32_t i = 0; 8211 8212 if (!adapter) { 8213 hdd_err("adapter is invalid"); 8214 goto err; 8215 } 8216 8217 if (!psoc) { 8218 hdd_err("HDD psoc is invalid"); 8219 goto err; 8220 } 8221 8222 status = ucfg_fwol_get_coex_config_params(psoc, &config); 8223 if (QDF_IS_STATUS_ERROR(status)) { 8224 hdd_err("Unable to get coex config params"); 8225 goto err; 8226 } 8227 8228 coex_multi_cfg = qdf_mem_malloc(sizeof(*coex_multi_cfg)); 8229 if (!coex_multi_cfg) 8230 goto err; 8231 8232 coex_multi_cfg->vdev_id = adapter->deflink->vdev_id; 8233 8234 coex_multi_cfg->cfg_items[i].config_type = WMI_COEX_CONFIG_TX_POWER; 8235 coex_multi_cfg->cfg_items[i].config_arg1 = config.max_tx_power_for_btc; 8236 8237 wma_nofl_debug("TXP[W][send_coex_cfg]: %d", 8238 config.max_tx_power_for_btc); 8239 8240 if (++i > COEX_MULTI_CONFIG_MAX_CNT) 8241 goto err; 8242 8243 coex_multi_cfg->cfg_items[i].config_type = 8244 WMI_COEX_CONFIG_HANDOVER_RSSI; 8245 coex_multi_cfg->cfg_items[i].config_arg1 = 8246 config.wlan_low_rssi_threshold; 8247 8248 if (++i > COEX_MULTI_CONFIG_MAX_CNT) 8249 goto err; 8250 8251 coex_multi_cfg->cfg_items[i].config_type = WMI_COEX_CONFIG_BTC_MODE; 8252 8253 /* Modify BTC_MODE according to BTC_CHAIN_MODE */ 8254 status = ucfg_coex_psoc_get_btc_chain_mode(psoc, &btc_chain_mode); 8255 if (QDF_IS_STATUS_ERROR(status)) { 8256 hdd_err("Failed to get btc chain mode"); 8257 btc_chain_mode = WLAN_COEX_BTC_CHAIN_MODE_UNSETTLED; 8258 } 8259 8260 if (btc_chain_mode <= WLAN_COEX_BTC_CHAIN_MODE_HYBRID) 8261 coex_multi_cfg->cfg_items[i].config_arg1 = btc_chain_mode; 8262 else 8263 coex_multi_cfg->cfg_items[i].config_arg1 = config.btc_mode; 8264 8265 hdd_debug("Configured BTC mode is %d, BTC chain mode is 0x%x, set BTC mode to %d", 8266 config.btc_mode, btc_chain_mode, 8267 coex_multi_cfg->cfg_items[i].config_arg1); 8268 8269 if (++i > COEX_MULTI_CONFIG_MAX_CNT) 8270 goto err; 8271 8272 coex_multi_cfg->cfg_items[i].config_type = 8273 WMI_COEX_CONFIG_ANTENNA_ISOLATION; 8274 coex_multi_cfg->cfg_items[i].config_arg1 = config.antenna_isolation; 8275 if (++i > COEX_MULTI_CONFIG_MAX_CNT) 8276 goto err; 8277 8278 coex_multi_cfg->cfg_items[i].config_type = 8279 WMI_COEX_CONFIG_BT_LOW_RSSI_THRESHOLD; 8280 coex_multi_cfg->cfg_items[i].config_arg1 = config.bt_low_rssi_threshold; 8281 8282 if (++i > COEX_MULTI_CONFIG_MAX_CNT) 8283 goto err; 8284 8285 coex_multi_cfg->cfg_items[i].config_type = 8286 WMI_COEX_CONFIG_BT_INTERFERENCE_LEVEL; 8287 coex_multi_cfg->cfg_items[i].config_arg1 = 8288 config.bt_interference_low_ll; 8289 coex_multi_cfg->cfg_items[i].config_arg2 = 8290 config.bt_interference_low_ul; 8291 coex_multi_cfg->cfg_items[i].config_arg3 = 8292 config.bt_interference_medium_ll; 8293 coex_multi_cfg->cfg_items[i].config_arg4 = 8294 config.bt_interference_medium_ul; 8295 coex_multi_cfg->cfg_items[i].config_arg5 = 8296 config.bt_interference_high_ll; 8297 coex_multi_cfg->cfg_items[i].config_arg6 = 8298 config.bt_interference_high_ul; 8299 8300 if (++i > COEX_MULTI_CONFIG_MAX_CNT) 8301 goto err; 8302 8303 if (wlan_hdd_mpta_helper_enable(&coex_cfg_params, &config)) 8304 goto err; 8305 8306 coex_multi_cfg->cfg_items[i].config_type = 8307 WMI_COEX_CONFIG_BT_SCO_ALLOW_WLAN_2G_SCAN; 8308 coex_multi_cfg->cfg_items[i].config_arg1 = 8309 config.bt_sco_allow_wlan_2g_scan; 8310 8311 if (++i > COEX_MULTI_CONFIG_MAX_CNT) 8312 goto err; 8313 8314 coex_multi_cfg->cfg_items[i].config_type = 8315 WMI_COEX_CONFIG_LE_SCAN_POLICY; 8316 coex_multi_cfg->cfg_items[i].config_arg1 = config.ble_scan_coex_policy; 8317 8318 if (++i > COEX_MULTI_CONFIG_MAX_CNT) 8319 goto err; 8320 8321 #ifdef FEATURE_COEX_TPUT_SHAPING_CONFIG 8322 coex_multi_cfg->cfg_items[i].config_type = 8323 WMI_COEX_CONFIG_ENABLE_TPUT_SHAPING; 8324 coex_multi_cfg->cfg_items[i].config_arg1 = 8325 config.coex_tput_shaping_enable; 8326 8327 if (++i > COEX_MULTI_CONFIG_MAX_CNT) 8328 goto err; 8329 #endif 8330 8331 coex_multi_cfg->num_configs = i; 8332 8333 vdev = hdd_objmgr_get_vdev_by_user(adapter->deflink, WLAN_COEX_ID); 8334 if (!vdev) { 8335 hdd_err("vdev is null"); 8336 goto err; 8337 } 8338 8339 ucfg_coex_send_multi_config(vdev, coex_multi_cfg); 8340 8341 hdd_objmgr_put_vdev_by_user(vdev, WLAN_COEX_ID); 8342 qdf_mem_free(coex_multi_cfg); 8343 8344 return 0; 8345 err: 8346 qdf_mem_free(coex_multi_cfg); 8347 return -EINVAL; 8348 } 8349 #else 8350 /** 8351 * hdd_send_coex_config_params() - Send coex config params to FW 8352 * @hdd_ctx: HDD context 8353 * @adapter: Primary adapter context 8354 * 8355 * This function is used to send all coex config related params to FW 8356 * 8357 * Return: 0 on success and -EINVAL on failure 8358 */ 8359 static int hdd_send_coex_config_params(struct hdd_context *hdd_ctx, 8360 struct hdd_adapter *adapter) 8361 { 8362 struct coex_config_params coex_cfg_params = {0}; 8363 struct wlan_fwol_coex_config config = {0}; 8364 struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc; 8365 enum coex_btc_chain_mode btc_chain_mode; 8366 QDF_STATUS status; 8367 8368 if (!adapter) { 8369 hdd_err("adapter is invalid"); 8370 goto err; 8371 } 8372 8373 if (!psoc) { 8374 hdd_err("HDD psoc is invalid"); 8375 goto err; 8376 } 8377 8378 status = ucfg_fwol_get_coex_config_params(psoc, &config); 8379 if (QDF_IS_STATUS_ERROR(status)) { 8380 hdd_err("Unable to get coex config params"); 8381 goto err; 8382 } 8383 8384 coex_cfg_params.vdev_id = adapter->deflink->vdev_id; 8385 coex_cfg_params.config_type = WMI_COEX_CONFIG_TX_POWER; 8386 coex_cfg_params.config_arg1 = config.max_tx_power_for_btc; 8387 8388 wma_nofl_debug("TXP[W][send_coex_cfg]: %d", 8389 config.max_tx_power_for_btc); 8390 8391 status = sme_send_coex_config_cmd(&coex_cfg_params); 8392 if (QDF_IS_STATUS_ERROR(status)) { 8393 hdd_err("Failed to send coex Tx power"); 8394 goto err; 8395 } 8396 8397 coex_cfg_params.config_type = WMI_COEX_CONFIG_HANDOVER_RSSI; 8398 coex_cfg_params.config_arg1 = config.wlan_low_rssi_threshold; 8399 8400 status = sme_send_coex_config_cmd(&coex_cfg_params); 8401 if (QDF_IS_STATUS_ERROR(status)) { 8402 hdd_err("Failed to send coex handover RSSI"); 8403 goto err; 8404 } 8405 8406 coex_cfg_params.config_type = WMI_COEX_CONFIG_BTC_MODE; 8407 8408 /* Modify BTC_MODE according to BTC_CHAIN_MODE */ 8409 status = ucfg_coex_psoc_get_btc_chain_mode(psoc, &btc_chain_mode); 8410 if (QDF_IS_STATUS_ERROR(status)) { 8411 hdd_err("Failed to get btc chain mode"); 8412 btc_chain_mode = WLAN_COEX_BTC_CHAIN_MODE_UNSETTLED; 8413 } 8414 8415 if (btc_chain_mode <= WLAN_COEX_BTC_CHAIN_MODE_HYBRID) 8416 coex_cfg_params.config_arg1 = btc_chain_mode; 8417 else 8418 coex_cfg_params.config_arg1 = config.btc_mode; 8419 8420 hdd_debug("Configured BTC mode is %d, BTC chain mode is 0x%x, set BTC mode to %d", 8421 config.btc_mode, btc_chain_mode, 8422 coex_cfg_params.config_arg1); 8423 status = sme_send_coex_config_cmd(&coex_cfg_params); 8424 if (QDF_IS_STATUS_ERROR(status)) { 8425 hdd_err("Failed to send coex BTC mode"); 8426 goto err; 8427 } 8428 8429 coex_cfg_params.config_type = WMI_COEX_CONFIG_ANTENNA_ISOLATION; 8430 coex_cfg_params.config_arg1 = config.antenna_isolation; 8431 8432 status = sme_send_coex_config_cmd(&coex_cfg_params); 8433 if (QDF_IS_STATUS_ERROR(status)) { 8434 hdd_err("Failed to send coex antenna isolation"); 8435 goto err; 8436 } 8437 8438 coex_cfg_params.config_type = WMI_COEX_CONFIG_BT_LOW_RSSI_THRESHOLD; 8439 coex_cfg_params.config_arg1 = config.bt_low_rssi_threshold; 8440 8441 status = sme_send_coex_config_cmd(&coex_cfg_params); 8442 if (QDF_IS_STATUS_ERROR(status)) { 8443 hdd_err("Failed to send coex BT low RSSI threshold"); 8444 goto err; 8445 } 8446 8447 coex_cfg_params.config_type = WMI_COEX_CONFIG_BT_INTERFERENCE_LEVEL; 8448 coex_cfg_params.config_arg1 = config.bt_interference_low_ll; 8449 coex_cfg_params.config_arg2 = config.bt_interference_low_ul; 8450 coex_cfg_params.config_arg3 = config.bt_interference_medium_ll; 8451 coex_cfg_params.config_arg4 = config.bt_interference_medium_ul; 8452 coex_cfg_params.config_arg5 = config.bt_interference_high_ll; 8453 coex_cfg_params.config_arg6 = config.bt_interference_high_ul; 8454 8455 status = sme_send_coex_config_cmd(&coex_cfg_params); 8456 if (QDF_IS_STATUS_ERROR(status)) { 8457 hdd_err("Failed to send coex BT interference level"); 8458 goto err; 8459 } 8460 8461 if (wlan_hdd_mpta_helper_enable(&coex_cfg_params, &config)) 8462 goto err; 8463 8464 coex_cfg_params.config_type = 8465 WMI_COEX_CONFIG_BT_SCO_ALLOW_WLAN_2G_SCAN; 8466 coex_cfg_params.config_arg1 = config.bt_sco_allow_wlan_2g_scan; 8467 8468 status = sme_send_coex_config_cmd(&coex_cfg_params); 8469 if (QDF_IS_STATUS_ERROR(status)) { 8470 hdd_err("Failed to send coex BT sco allow wlan 2g scan"); 8471 goto err; 8472 } 8473 8474 coex_cfg_params.config_type = 8475 WMI_COEX_CONFIG_LE_SCAN_POLICY; 8476 coex_cfg_params.config_arg1 = config.ble_scan_coex_policy; 8477 8478 status = sme_send_coex_config_cmd(&coex_cfg_params); 8479 if (QDF_IS_STATUS_ERROR(status)) { 8480 hdd_err("Failed to send coex BLE scan policy"); 8481 goto err; 8482 } 8483 8484 #ifdef FEATURE_COEX_TPUT_SHAPING_CONFIG 8485 coex_cfg_params.config_type = 8486 WMI_COEX_CONFIG_ENABLE_TPUT_SHAPING; 8487 coex_cfg_params.config_arg1 = config.coex_tput_shaping_enable; 8488 8489 status = sme_send_coex_config_cmd(&coex_cfg_params); 8490 if (QDF_IS_STATUS_ERROR(status)) { 8491 hdd_err("Failed to send coex traffic shaping value %d", 8492 coex_cfg_params.config_arg1); 8493 goto err; 8494 } 8495 #endif 8496 return 0; 8497 err: 8498 return -EINVAL; 8499 } 8500 #endif 8501 8502 /** 8503 * hdd_send_coex_traffic_shaping_mode() - Send coex traffic shaping mode 8504 * to FW 8505 * @vdev_id: vdev ID 8506 * @mode: traffic shaping mode 8507 * 8508 * This function is used to send coex traffic shaping mode to FW 8509 * 8510 * Return: 0 on success and -EINVAL on failure 8511 */ 8512 int hdd_send_coex_traffic_shaping_mode(uint8_t vdev_id, uint8_t mode) 8513 { 8514 struct coex_config_params coex_cfg_params = {0}; 8515 8516 coex_cfg_params.config_type = WMI_COEX_SET_TRAFFIC_SHAPING_MODE; 8517 coex_cfg_params.config_arg1 = mode; 8518 coex_cfg_params.vdev_id = vdev_id; 8519 8520 if (QDF_IS_STATUS_ERROR(sme_send_coex_config_cmd(&coex_cfg_params))) { 8521 hdd_err_rl("Failed to send coex traffic shaping mode"); 8522 return -EINVAL; 8523 } 8524 return 0; 8525 } 8526 8527 #define MAX_PDEV_SET_FW_PARAMS 7 8528 /* params being sent: 8529 * 1.wmi_pdev_param_dtim_synth 8530 * 2.wmi_pdev_param_1ch_dtim_optimized_chain_selection 8531 * 3.wmi_pdev_param_tx_sch_delay 8532 * 4.wmi_pdev_param_en_update_scram_seed 8533 * 5.wmi_pdev_param_secondary_retry_enable 8534 * 6.wmi_pdev_param_set_sap_xlna_bypass 8535 * 7.wmi_pdev_param_set_dfs_chan_ageout_time 8536 */ 8537 8538 /** 8539 * hdd_set_fw_params() - Set parameters to firmware 8540 * @adapter: HDD adapter 8541 * 8542 * This function Sets various parameters to fw once the 8543 * adapter is started. 8544 * 8545 * Return: 0 on success or errno on failure 8546 */ 8547 int hdd_set_fw_params(struct hdd_adapter *adapter) 8548 { 8549 int ret; 8550 uint16_t upper_brssi_thresh, lower_brssi_thresh; 8551 bool enable_dtim_1chrx; 8552 QDF_STATUS status; 8553 struct hdd_context *hdd_ctx; 8554 bool is_lprx_enabled; 8555 bool bval = false; 8556 uint8_t enable_tx_sch_delay, dfs_chan_ageout_time; 8557 uint32_t dtim_sel_diversity, enable_secondary_rate; 8558 bool sap_xlna_bypass; 8559 bool enable_ofdm_scrambler_seed = false; 8560 struct dev_set_param setparam[MAX_PDEV_SET_FW_PARAMS] = { }; 8561 uint8_t index = 0; 8562 8563 hdd_enter_dev(adapter->dev); 8564 8565 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 8566 if (!hdd_ctx) 8567 return -EINVAL; 8568 8569 if (cds_get_conparam() == QDF_GLOBAL_FTM_MODE) { 8570 hdd_debug("FTM Mode is active; nothing to do"); 8571 return 0; 8572 } 8573 8574 /* The ini gEnableLPRx is deprecated. By default, the ini 8575 * is enabled. So, making the variable is_lprx_enabled true. 8576 */ 8577 is_lprx_enabled = true; 8578 8579 ret = mlme_check_index_setparam(setparam, wmi_pdev_param_dtim_synth, 8580 is_lprx_enabled, index++, 8581 MAX_PDEV_SET_FW_PARAMS); 8582 if (QDF_IS_STATUS_ERROR(ret)) 8583 goto error; 8584 8585 ucfg_mlme_get_dtim_selection_diversity(hdd_ctx->psoc, 8586 &dtim_sel_diversity); 8587 ret = mlme_check_index_setparam( 8588 setparam, 8589 wmi_pdev_param_1ch_dtim_optimized_chain_selection, 8590 dtim_sel_diversity, index++, MAX_PDEV_SET_FW_PARAMS); 8591 if (QDF_IS_STATUS_ERROR(ret)) 8592 goto error; 8593 8594 if (QDF_IS_STATUS_SUCCESS(ucfg_fwol_get_enable_tx_sch_delay( 8595 hdd_ctx->psoc, &enable_tx_sch_delay))) { 8596 ret = mlme_check_index_setparam( 8597 setparam, 8598 wmi_pdev_param_tx_sch_delay, 8599 enable_tx_sch_delay, index++, 8600 MAX_PDEV_SET_FW_PARAMS); 8601 if (QDF_IS_STATUS_ERROR(ret)) 8602 goto error; 8603 } 8604 8605 if (QDF_IS_STATUS_SUCCESS(ucfg_fwol_get_ofdm_scrambler_seed( 8606 hdd_ctx->psoc, &enable_ofdm_scrambler_seed))) { 8607 ret = mlme_check_index_setparam( 8608 setparam, 8609 wmi_pdev_param_en_update_scram_seed, 8610 enable_ofdm_scrambler_seed, index++, 8611 MAX_PDEV_SET_FW_PARAMS); 8612 if (QDF_IS_STATUS_ERROR(ret)) 8613 goto error; 8614 } 8615 8616 if (QDF_IS_STATUS_SUCCESS(ucfg_fwol_get_enable_secondary_rate( 8617 hdd_ctx->psoc, &enable_secondary_rate))) { 8618 ret = mlme_check_index_setparam( 8619 setparam, 8620 wmi_pdev_param_secondary_retry_enable, 8621 enable_secondary_rate, index++, 8622 MAX_PDEV_SET_FW_PARAMS); 8623 if (QDF_IS_STATUS_ERROR(ret)) 8624 goto error; 8625 } 8626 if (QDF_IS_STATUS_SUCCESS(ucfg_fwol_get_sap_xlna_bypass( 8627 hdd_ctx->psoc, &sap_xlna_bypass))) { 8628 ret = mlme_check_index_setparam( 8629 setparam, 8630 wmi_pdev_param_set_sap_xlna_bypass, 8631 sap_xlna_bypass, index++, 8632 MAX_PDEV_SET_FW_PARAMS); 8633 if (QDF_IS_STATUS_ERROR(ret)) 8634 goto error; 8635 } 8636 wlan_mlme_get_dfs_chan_ageout_time(hdd_ctx->psoc, 8637 &dfs_chan_ageout_time); 8638 ret = mlme_check_index_setparam( 8639 setparam, 8640 wmi_pdev_param_set_dfs_chan_ageout_time, 8641 dfs_chan_ageout_time, index++, 8642 MAX_PDEV_SET_FW_PARAMS); 8643 if (QDF_IS_STATUS_ERROR(ret)) 8644 goto error; 8645 8646 ret = sme_send_multi_pdev_vdev_set_params(MLME_PDEV_SETPARAM, 8647 WMI_PDEV_ID_SOC, setparam, 8648 index); 8649 if (QDF_IS_STATUS_ERROR(ret)) { 8650 goto error; 8651 } 8652 if (adapter->device_mode == QDF_STA_MODE) { 8653 status = ucfg_get_upper_brssi_thresh(hdd_ctx->psoc, 8654 &upper_brssi_thresh); 8655 if (QDF_IS_STATUS_ERROR(status)) 8656 return -EINVAL; 8657 8658 sme_set_smps_cfg(adapter->deflink->vdev_id, 8659 HDD_STA_SMPS_PARAM_UPPER_BRSSI_THRESH, 8660 upper_brssi_thresh); 8661 8662 status = ucfg_get_lower_brssi_thresh(hdd_ctx->psoc, 8663 &lower_brssi_thresh); 8664 if (QDF_IS_STATUS_ERROR(status)) 8665 return -EINVAL; 8666 8667 sme_set_smps_cfg(adapter->deflink->vdev_id, 8668 HDD_STA_SMPS_PARAM_LOWER_BRSSI_THRESH, 8669 lower_brssi_thresh); 8670 8671 status = ucfg_get_enable_dtim_1chrx(hdd_ctx->psoc, 8672 &enable_dtim_1chrx); 8673 if (QDF_IS_STATUS_ERROR(status)) 8674 return -EINVAL; 8675 8676 sme_set_smps_cfg(adapter->deflink->vdev_id, 8677 HDD_STA_SMPS_PARAM_DTIM_1CHRX_ENABLE, 8678 enable_dtim_1chrx); 8679 } 8680 8681 status = ucfg_mlme_get_vht_enable2x2(hdd_ctx->psoc, &bval); 8682 if (!QDF_IS_STATUS_SUCCESS(status)) 8683 hdd_err("unable to get vht_enable2x2"); 8684 8685 if (bval) { 8686 hdd_debug("configuring 2x2 mode fw params"); 8687 8688 ret = sme_set_cck_tx_fir_override(hdd_ctx->mac_handle, 8689 adapter->deflink->vdev_id); 8690 if (ret) { 8691 hdd_err("wmi_pdev_param_enable_cck_tfir_override set failed %d", 8692 ret); 8693 goto error; 8694 } 8695 8696 hdd_configure_chain_mask(adapter); 8697 } else { 8698 #define HDD_DTIM_1CHAIN_RX_ID 0x5 8699 #define HDD_SMPS_PARAM_VALUE_S 29 8700 hdd_debug("configuring 1x1 mode fw params"); 8701 8702 /* 8703 * Disable DTIM 1 chain Rx when in 1x1, 8704 * we are passing two value 8705 * as param_id << 29 | param_value. 8706 * Below param_value = 0(disable) 8707 */ 8708 ret = sme_cli_set_command(adapter->deflink->vdev_id, 8709 WMI_STA_SMPS_PARAM_CMDID, 8710 HDD_DTIM_1CHAIN_RX_ID << 8711 HDD_SMPS_PARAM_VALUE_S, 8712 VDEV_CMD); 8713 if (ret) { 8714 hdd_err("DTIM 1 chain set failed %d", ret); 8715 goto error; 8716 } 8717 8718 #undef HDD_DTIM_1CHAIN_RX_ID 8719 #undef HDD_SMPS_PARAM_VALUE_S 8720 8721 hdd_configure_chain_mask(adapter); 8722 } 8723 8724 ret = sme_set_enable_mem_deep_sleep(hdd_ctx->mac_handle, 8725 adapter->deflink->vdev_id); 8726 if (ret) { 8727 hdd_err("wmi_pdev_param_hyst_en set failed %d", ret); 8728 goto error; 8729 } 8730 8731 if (!hdd_ctx->is_fw_dbg_log_levels_configured) { 8732 hdd_set_fw_log_params(hdd_ctx, adapter->deflink->vdev_id); 8733 hdd_ctx->is_fw_dbg_log_levels_configured = true; 8734 } 8735 8736 ret = hdd_send_coex_config_params(hdd_ctx, adapter); 8737 if (ret) { 8738 hdd_warn("Error initializing coex config params"); 8739 goto error; 8740 } 8741 8742 hdd_exit(); 8743 8744 return 0; 8745 8746 error: 8747 return -EINVAL; 8748 } 8749 8750 /** 8751 * hdd_init_completion() - Initialize Completion Variables 8752 * @adapter: HDD adapter 8753 * 8754 * This function Initialize the completion variables for 8755 * a particular adapter 8756 * 8757 * Return: None 8758 */ 8759 static void hdd_init_completion(struct hdd_adapter *adapter) 8760 { 8761 init_completion(&adapter->disconnect_comp_var); 8762 init_completion(&adapter->linkup_event_var); 8763 init_completion(&adapter->lfr_fw_status.disable_lfr_event); 8764 } 8765 8766 static void hdd_reset_locally_admin_bit(struct hdd_context *hdd_ctx, 8767 tSirMacAddr mac_addr) 8768 { 8769 int i; 8770 /* 8771 * Reset locally administered bit for dynamic_mac_list 8772 * also as while releasing the MAC address for any 8773 * interface mac will be compared with dynamic mac list 8774 */ 8775 for (i = 0; i < QDF_MAX_CONCURRENCY_PERSONA; i++) { 8776 if (!qdf_mem_cmp( 8777 mac_addr, 8778 &hdd_ctx-> 8779 dynamic_mac_list[i].dynamic_mac.bytes[0], 8780 sizeof(struct qdf_mac_addr))) { 8781 WLAN_HDD_RESET_LOCALLY_ADMINISTERED_BIT( 8782 hdd_ctx-> 8783 dynamic_mac_list[i].dynamic_mac.bytes); 8784 break; 8785 } 8786 } 8787 /* 8788 * Reset locally administered bit if the device mode is 8789 * STA 8790 */ 8791 WLAN_HDD_RESET_LOCALLY_ADMINISTERED_BIT(mac_addr); 8792 hdd_debug("locally administered bit reset in sta mode: " 8793 QDF_MAC_ADDR_FMT, QDF_MAC_ADDR_REF(mac_addr)); 8794 } 8795 8796 static void wlan_hdd_cfg80211_scan_block_cb(struct work_struct *work) 8797 { 8798 struct hdd_adapter *adapter = 8799 container_of(work, struct hdd_adapter, scan_block_work); 8800 struct osif_vdev_sync *vdev_sync; 8801 8802 if (osif_vdev_sync_op_start(adapter->dev, &vdev_sync)) 8803 return; 8804 8805 wlan_hdd_cfg80211_scan_block(adapter); 8806 8807 osif_vdev_sync_op_stop(vdev_sync); 8808 } 8809 8810 #if defined(WLAN_FEATURE_11BE_MLO) && \ 8811 defined(WLAN_HDD_MULTI_VDEV_SINGLE_NDEV) 8812 static inline void 8813 wlan_hdd_set_ml_cap_for_sap_intf(struct hdd_adapter_create_param *create_params, 8814 enum QDF_OPMODE mode) 8815 { 8816 if (mode != QDF_SAP_MODE) 8817 return; 8818 8819 create_params->is_ml_adapter = true; 8820 } 8821 #elif defined(WLAN_FEATURE_11BE_MLO) 8822 static inline void 8823 wlan_hdd_set_ml_cap_for_sap_intf(struct hdd_adapter_create_param *create_params, 8824 enum QDF_OPMODE mode) 8825 { 8826 if (mode != QDF_SAP_MODE) 8827 return; 8828 8829 create_params->is_ml_adapter = true; 8830 create_params->is_single_link = true; 8831 } 8832 #else 8833 static inline void 8834 wlan_hdd_set_ml_cap_for_sap_intf(struct hdd_adapter_create_param *create_params, 8835 enum QDF_OPMODE mode) 8836 { 8837 create_params->is_ml_adapter = false; 8838 } 8839 #endif /* WLAN_FEATURE_11BE_MLO */ 8840 8841 #if defined(WLAN_FEATURE_11BE_MLO) && defined(CFG80211_11BE_BASIC) && \ 8842 defined(WLAN_HDD_MULTI_VDEV_SINGLE_NDEV) 8843 void hdd_adapter_disable_all_links(struct hdd_adapter *adapter) 8844 { 8845 uint8_t idx_pos; 8846 struct wlan_hdd_link_info *link_info; 8847 8848 hdd_adapter_for_each_link_info(adapter, link_info) { 8849 qdf_zero_macaddr(&link_info->link_addr); 8850 idx_pos = hdd_adapter_get_index_of_link_info(link_info); 8851 adapter->curr_link_info_map[idx_pos] = idx_pos; 8852 } 8853 adapter->deflink = &adapter->link_info[WLAN_HDD_DEFLINK_IDX]; 8854 if (adapter->device_mode == QDF_STA_MODE) 8855 adapter->active_links = (1 << adapter->num_links_on_create) - 1; 8856 else 8857 adapter->active_links = 0x1; 8858 } 8859 #endif 8860 8861 static void hdd_adapter_enable_links(struct hdd_adapter *adapter, 8862 struct hdd_adapter_create_param *params) 8863 { 8864 uint8_t num, link_idx; 8865 8866 /* Default link is already set on adapter allocation, only 8867 * enable other links if requested links is greater than 1 8868 */ 8869 if (params->num_sessions <= 1) { 8870 adapter->num_links_on_create = 1; 8871 return; 8872 } 8873 8874 num = QDF_MIN(params->num_sessions, WLAN_MAX_MLD); 8875 for (link_idx = WLAN_HDD_DEFLINK_IDX; link_idx < num; link_idx++) 8876 qdf_atomic_set_bit(link_idx, &adapter->active_links); 8877 8878 adapter->num_links_on_create = num; 8879 } 8880 8881 static void hdd_adapter_init_link_info(struct hdd_adapter *adapter) 8882 { 8883 uint8_t idx_pos; 8884 struct wlan_hdd_link_info *link_info; 8885 8886 /* Initialize each member in link info array to default values */ 8887 hdd_adapter_for_each_link_info(adapter, link_info) { 8888 link_info->adapter = adapter; 8889 link_info->vdev_id = WLAN_UMAC_VDEV_ID_MAX; 8890 qdf_spinlock_create(&link_info->vdev_lock); 8891 init_completion(&link_info->vdev_destroy_event); 8892 qdf_event_create(&link_info->acs_complete_event); 8893 8894 idx_pos = hdd_adapter_get_index_of_link_info(link_info); 8895 adapter->curr_link_info_map[idx_pos] = idx_pos; 8896 qdf_create_work(0, &link_info->chan_change_notify_work, 8897 hdd_chan_change_notify_work_handler, 8898 link_info); 8899 } 8900 } 8901 8902 /** 8903 * hdd_open_adapter() - open and setup the hdd adapter 8904 * @hdd_ctx: global hdd context 8905 * @session_type: type of the interface to be created 8906 * @iface_name: User-visible name of the interface 8907 * @mac_addr: MAC address to assign to the interface 8908 * @name_assign_type: the name of assign type of the netdev 8909 * @rtnl_held: the rtnl lock hold flag 8910 * @params: adapter create params 8911 * 8912 * This function open and setup the hdd adapter according to the device 8913 * type request, assign the name, the mac address assigned, and then prepared 8914 * the hdd related parameters, queue, lock and ready to start. 8915 * 8916 * Return: the pointer of hdd adapter, otherwise NULL. 8917 */ 8918 struct hdd_adapter *hdd_open_adapter(struct hdd_context *hdd_ctx, 8919 uint8_t session_type, 8920 const char *iface_name, 8921 tSirMacAddr mac_addr, 8922 unsigned char name_assign_type, 8923 bool rtnl_held, 8924 struct hdd_adapter_create_param *params) 8925 { 8926 struct net_device *ndev = NULL; 8927 struct hdd_adapter *adapter = NULL, *sta_adapter = NULL; 8928 QDF_STATUS status = QDF_STATUS_E_FAILURE; 8929 uint32_t i; 8930 bool eht_capab = 0; 8931 8932 status = wlan_hdd_validate_mac_address((struct qdf_mac_addr *)mac_addr); 8933 if (QDF_IS_STATUS_ERROR(status)) { 8934 /* Not received valid mac_addr */ 8935 hdd_err("Unable to add virtual intf: Not able to get valid mac address"); 8936 return NULL; 8937 } 8938 8939 status = hdd_check_for_existing_macaddr(hdd_ctx, mac_addr); 8940 if (QDF_STATUS_E_FAILURE == status) { 8941 hdd_err("Duplicate MAC addr: " QDF_MAC_ADDR_FMT 8942 " already exists", 8943 QDF_MAC_ADDR_REF(mac_addr)); 8944 return NULL; 8945 } 8946 8947 if (params->only_wdev_register) { 8948 sta_adapter = hdd_get_ml_adapter(hdd_ctx); 8949 if (!sta_adapter) { 8950 hdd_err("not able to find the sta adapter"); 8951 return NULL; 8952 } 8953 } 8954 8955 switch (session_type) { 8956 case QDF_STA_MODE: 8957 if (!(hdd_ctx->config->mac_provision || 8958 params->only_wdev_register)) { 8959 hdd_reset_locally_admin_bit(hdd_ctx, mac_addr); 8960 /* 8961 * After resetting locally administered bit 8962 * again check if the new mac address is already 8963 * exists. 8964 */ 8965 status = hdd_check_for_existing_macaddr(hdd_ctx, 8966 mac_addr); 8967 if (QDF_STATUS_E_FAILURE == status) { 8968 hdd_err("Duplicate MAC addr: " QDF_MAC_ADDR_FMT 8969 " already exists", 8970 QDF_MAC_ADDR_REF(mac_addr)); 8971 return NULL; 8972 } 8973 } 8974 8975 fallthrough; 8976 case QDF_P2P_CLIENT_MODE: 8977 case QDF_P2P_DEVICE_MODE: 8978 case QDF_OCB_MODE: 8979 case QDF_NDI_MODE: 8980 case QDF_MONITOR_MODE: 8981 case QDF_NAN_DISC_MODE: 8982 adapter = hdd_alloc_station_adapter(hdd_ctx, mac_addr, 8983 name_assign_type, 8984 iface_name, session_type); 8985 8986 if (!adapter) { 8987 hdd_err("failed to allocate adapter for session %d", 8988 session_type); 8989 return NULL; 8990 } 8991 8992 ndev = adapter->dev; 8993 8994 status = ucfg_dp_create_intf(hdd_ctx->psoc, &adapter->mac_addr, 8995 (qdf_netdev_t)adapter->dev); 8996 if (QDF_IS_STATUS_ERROR(status)) 8997 goto err_free_netdev; 8998 8999 if (QDF_P2P_CLIENT_MODE == session_type) 9000 adapter->wdev.iftype = NL80211_IFTYPE_P2P_CLIENT; 9001 else if (QDF_P2P_DEVICE_MODE == session_type) 9002 adapter->wdev.iftype = NL80211_IFTYPE_P2P_DEVICE; 9003 else if (QDF_MONITOR_MODE == session_type) 9004 adapter->wdev.iftype = NL80211_IFTYPE_MONITOR; 9005 else if (QDF_NAN_DISC_MODE == session_type) 9006 wlan_hdd_set_nan_if_type(adapter); 9007 else 9008 adapter->wdev.iftype = NL80211_IFTYPE_STATION; 9009 9010 adapter->device_mode = session_type; 9011 9012 9013 /* 9014 * Workqueue which gets scheduled in IPv4 notification 9015 * callback 9016 */ 9017 INIT_WORK(&adapter->ipv4_notifier_work, 9018 hdd_ipv4_notifier_work_queue); 9019 9020 #ifdef WLAN_NS_OFFLOAD 9021 /* 9022 * Workqueue which gets scheduled in IPv6 9023 * notification callback. 9024 */ 9025 INIT_WORK(&adapter->ipv6_notifier_work, 9026 hdd_ipv6_notifier_work_queue); 9027 #endif 9028 if (params->only_wdev_register) { 9029 hdd_register_wdev(sta_adapter, adapter, params); 9030 } else { 9031 status = hdd_register_interface(adapter, rtnl_held, 9032 params); 9033 if (QDF_STATUS_SUCCESS != status) 9034 goto err_destroy_dp_intf; 9035 /* Stop the Interface TX queue. */ 9036 hdd_debug("Disabling queues"); 9037 wlan_hdd_netif_queue_control(adapter, 9038 WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER, 9039 WLAN_CONTROL_PATH); 9040 } 9041 break; 9042 case QDF_P2P_GO_MODE: 9043 case QDF_SAP_MODE: 9044 adapter = hdd_wlan_create_ap_dev(hdd_ctx, mac_addr, 9045 name_assign_type, 9046 (uint8_t *) iface_name); 9047 if (!adapter) { 9048 hdd_err("failed to allocate adapter for session %d", 9049 session_type); 9050 return NULL; 9051 } 9052 9053 ndev = adapter->dev; 9054 9055 status = ucfg_dp_create_intf(hdd_ctx->psoc, &adapter->mac_addr, 9056 (qdf_netdev_t)adapter->dev); 9057 if (QDF_IS_STATUS_ERROR(status)) 9058 goto err_free_netdev; 9059 9060 adapter->wdev.iftype = 9061 (session_type == 9062 QDF_SAP_MODE) ? NL80211_IFTYPE_AP : 9063 NL80211_IFTYPE_P2P_GO; 9064 adapter->device_mode = session_type; 9065 9066 status = hdd_register_interface(adapter, rtnl_held, params); 9067 if (QDF_STATUS_SUCCESS != status) 9068 goto err_destroy_dp_intf; 9069 9070 hdd_debug("Disabling queues"); 9071 wlan_hdd_netif_queue_control(adapter, 9072 WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER, 9073 WLAN_CONTROL_PATH); 9074 9075 /* 9076 * Workqueue which gets scheduled in IPv4 notification 9077 * callback 9078 */ 9079 INIT_WORK(&adapter->ipv4_notifier_work, 9080 hdd_ipv4_notifier_work_queue); 9081 9082 #ifdef WLAN_NS_OFFLOAD 9083 /* 9084 * Workqueue which gets scheduled in IPv6 9085 * notification callback. 9086 */ 9087 INIT_WORK(&adapter->ipv6_notifier_work, 9088 hdd_ipv6_notifier_work_queue); 9089 #endif 9090 if (!params->is_pre_cac_adapter) 9091 wlan_hdd_set_ml_cap_for_sap_intf(params, session_type); 9092 break; 9093 case QDF_FTM_MODE: 9094 adapter = hdd_alloc_station_adapter(hdd_ctx, mac_addr, 9095 name_assign_type, 9096 iface_name, session_type); 9097 if (!adapter) { 9098 hdd_err("Failed to allocate adapter for FTM mode"); 9099 return NULL; 9100 } 9101 9102 ndev = adapter->dev; 9103 9104 status = ucfg_dp_create_intf(hdd_ctx->psoc, &adapter->mac_addr, 9105 (qdf_netdev_t)adapter->dev); 9106 if (QDF_IS_STATUS_ERROR(status)) 9107 goto err_free_netdev; 9108 9109 adapter->wdev.iftype = NL80211_IFTYPE_STATION; 9110 adapter->device_mode = session_type; 9111 status = hdd_register_interface(adapter, rtnl_held, params); 9112 if (QDF_STATUS_SUCCESS != status) 9113 goto err_destroy_dp_intf; 9114 9115 /* Stop the Interface TX queue. */ 9116 hdd_debug("Disabling queues"); 9117 wlan_hdd_netif_queue_control(adapter, 9118 WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER, 9119 WLAN_CONTROL_PATH); 9120 9121 break; 9122 default: 9123 hdd_err("Invalid session type %d", session_type); 9124 QDF_ASSERT(0); 9125 return NULL; 9126 } 9127 9128 hdd_adapter_init_link_info(adapter); 9129 hdd_adapter_enable_links(adapter, params); 9130 9131 ucfg_psoc_mlme_get_11be_capab(hdd_ctx->psoc, &eht_capab); 9132 if (params->is_ml_adapter && eht_capab) { 9133 hdd_adapter_set_ml_adapter(adapter); 9134 if (params->is_single_link) 9135 hdd_adapter_set_sl_ml_adapter(adapter); 9136 } 9137 9138 status = hdd_adapter_feature_update_work_init(adapter); 9139 if (QDF_IS_STATUS_ERROR(status)) 9140 goto err_cleanup_adapter; 9141 9142 adapter->upgrade_udp_qos_threshold = QCA_WLAN_AC_BK; 9143 9144 hdd_init_completion(adapter); 9145 INIT_WORK(&adapter->scan_block_work, wlan_hdd_cfg80211_scan_block_cb); 9146 INIT_WORK(&adapter->sap_stop_bss_work, 9147 hdd_stop_sap_due_to_invalid_channel); 9148 qdf_list_create(&adapter->blocked_scan_request_q, WLAN_MAX_SCAN_COUNT); 9149 qdf_mutex_create(&adapter->blocked_scan_request_q_lock); 9150 qdf_spinlock_create(&adapter->mc_list_lock); 9151 qdf_event_create(&adapter->peer_cleanup_done); 9152 hdd_sta_info_init(&adapter->sta_info_list); 9153 hdd_sta_info_init(&adapter->cache_sta_info_list); 9154 9155 for (i = 0; i < NET_DEV_HOLD_ID_MAX; i++) 9156 qdf_atomic_init( 9157 &adapter->net_dev_hold_ref_count[NET_DEV_HOLD_ID_MAX]); 9158 9159 /* Add it to the hdd's session list. */ 9160 status = hdd_add_adapter_back(hdd_ctx, adapter); 9161 if (QDF_STATUS_SUCCESS != status) 9162 goto err_destroy_adapter_features_update_work; 9163 9164 hdd_apf_context_init(adapter); 9165 9166 policy_mgr_set_concurrency_mode(hdd_ctx->psoc, session_type); 9167 9168 if (QDF_STATUS_SUCCESS != hdd_debugfs_init(adapter)) 9169 hdd_err("debugfs: Interface %s init failed", 9170 netdev_name(adapter->dev)); 9171 9172 hdd_debug("%s interface created. iftype: %d", netdev_name(adapter->dev), 9173 session_type); 9174 9175 if (adapter->device_mode == QDF_STA_MODE) 9176 wlan_hdd_debugfs_csr_init(adapter); 9177 9178 return adapter; 9179 9180 err_destroy_adapter_features_update_work: 9181 hdd_adapter_feature_update_work_deinit(adapter); 9182 9183 err_cleanup_adapter: 9184 if (adapter) { 9185 hdd_cleanup_adapter(hdd_ctx, adapter, rtnl_held); 9186 adapter = NULL; 9187 } 9188 9189 err_destroy_dp_intf: 9190 ucfg_dp_destroy_intf(hdd_ctx->psoc, &adapter->mac_addr); 9191 9192 err_free_netdev: 9193 if (ndev) 9194 free_netdev(ndev); 9195 9196 return NULL; 9197 } 9198 9199 static void __hdd_close_adapter(struct hdd_context *hdd_ctx, 9200 struct hdd_adapter *adapter, 9201 bool rtnl_held) 9202 { 9203 struct qdf_mac_addr adapter_mac; 9204 struct wlan_hdd_link_info *link_info; 9205 9206 qdf_copy_macaddr(&adapter_mac, &adapter->mac_addr); 9207 if (adapter->device_mode == QDF_STA_MODE) { 9208 hdd_adapter_for_each_link_info(adapter, link_info) 9209 hdd_cleanup_conn_info(link_info); 9210 } 9211 9212 hdd_adapter_for_each_link_info(adapter, link_info) 9213 qdf_flush_work(&link_info->chan_change_notify_work); 9214 9215 qdf_list_destroy(&adapter->blocked_scan_request_q); 9216 qdf_mutex_destroy(&adapter->blocked_scan_request_q_lock); 9217 policy_mgr_clear_concurrency_mode(hdd_ctx->psoc, adapter->device_mode); 9218 qdf_event_destroy(&adapter->peer_cleanup_done); 9219 hdd_adapter_feature_update_work_deinit(adapter); 9220 hdd_cleanup_adapter(hdd_ctx, adapter, rtnl_held); 9221 ucfg_dp_destroy_intf(hdd_ctx->psoc, &adapter_mac); 9222 } 9223 9224 void hdd_close_adapter(struct hdd_context *hdd_ctx, 9225 struct hdd_adapter *adapter, 9226 bool rtnl_held) 9227 { 9228 /* 9229 * Stop the global bus bandwidth timer while touching the adapter list 9230 * to avoid bad memory access by the timer handler. 9231 */ 9232 ucfg_dp_bus_bw_compute_timer_stop(hdd_ctx->psoc); 9233 9234 hdd_check_for_net_dev_ref_leak(adapter); 9235 hdd_remove_adapter(hdd_ctx, adapter); 9236 __hdd_close_adapter(hdd_ctx, adapter, rtnl_held); 9237 9238 /* conditionally restart the bw timer */ 9239 ucfg_dp_bus_bw_compute_timer_try_start(hdd_ctx->psoc); 9240 } 9241 9242 void hdd_close_all_adapters(struct hdd_context *hdd_ctx, bool rtnl_held) 9243 { 9244 struct hdd_adapter *adapter; 9245 struct osif_vdev_sync *vdev_sync; 9246 QDF_STATUS qdf_status; 9247 9248 hdd_enter(); 9249 9250 while (QDF_IS_STATUS_SUCCESS(hdd_get_front_adapter( 9251 hdd_ctx, &adapter))) { 9252 /* If MLO is enabled unregister the link wdev's */ 9253 if (adapter->device_mode == QDF_STA_MODE || 9254 adapter->device_mode == QDF_SAP_MODE) { 9255 qdf_status = hdd_wlan_unregister_mlo_interfaces(adapter, 9256 rtnl_held); 9257 if (QDF_IS_STATUS_ERROR(qdf_status)) 9258 continue; 9259 } 9260 9261 hdd_check_for_net_dev_ref_leak(adapter); 9262 hdd_remove_front_adapter(hdd_ctx, &adapter); 9263 vdev_sync = osif_vdev_sync_unregister(adapter->dev); 9264 if (vdev_sync) 9265 osif_vdev_sync_wait_for_ops(vdev_sync); 9266 9267 wlan_hdd_release_intf_addr(hdd_ctx, adapter->mac_addr.bytes); 9268 __hdd_close_adapter(hdd_ctx, adapter, rtnl_held); 9269 9270 if (vdev_sync) 9271 osif_vdev_sync_destroy(vdev_sync); 9272 } 9273 9274 hdd_exit(); 9275 } 9276 9277 void wlan_hdd_reset_prob_rspies(struct wlan_hdd_link_info *link_info) 9278 { 9279 struct qdf_mac_addr *bssid = NULL; 9280 tSirUpdateIE update_ie; 9281 mac_handle_t mac_handle; 9282 struct hdd_adapter *adapter = link_info->adapter; 9283 9284 switch (adapter->device_mode) { 9285 case QDF_STA_MODE: 9286 case QDF_P2P_CLIENT_MODE: 9287 { 9288 struct hdd_station_ctx *sta_ctx = 9289 WLAN_HDD_GET_STATION_CTX_PTR(link_info); 9290 bssid = &sta_ctx->conn_info.bssid; 9291 break; 9292 } 9293 case QDF_SAP_MODE: 9294 case QDF_P2P_GO_MODE: 9295 { 9296 bssid = &adapter->mac_addr; 9297 break; 9298 } 9299 case QDF_FTM_MODE: 9300 case QDF_P2P_DEVICE_MODE: 9301 default: 9302 /* 9303 * wlan_hdd_reset_prob_rspies should not have been called 9304 * for these kind of devices 9305 */ 9306 hdd_err("Unexpected request for the current device type %d", 9307 adapter->device_mode); 9308 return; 9309 } 9310 9311 qdf_copy_macaddr(&update_ie.bssid, bssid); 9312 update_ie.vdev_id = link_info->vdev_id; 9313 update_ie.ieBufferlength = 0; 9314 update_ie.pAdditionIEBuffer = NULL; 9315 update_ie.append = true; 9316 update_ie.notify = false; 9317 mac_handle = hdd_adapter_get_mac_handle(adapter); 9318 if (sme_update_add_ie(mac_handle, 9319 &update_ie, 9320 eUPDATE_IE_PROBE_RESP) == QDF_STATUS_E_FAILURE) { 9321 hdd_err("Could not pass on PROBE_RSP_BCN data to PE"); 9322 } 9323 } 9324 9325 /** 9326 * hdd_ipa_ap_disconnect_evt() - Indicate wlan ipa ap disconnect event 9327 * @hdd_ctx: hdd context 9328 * @adapter: hdd adapter 9329 * 9330 * Return: None 9331 */ 9332 static inline 9333 void hdd_ipa_ap_disconnect_evt(struct hdd_context *hdd_ctx, 9334 struct hdd_adapter *adapter) 9335 { 9336 struct wlan_hdd_link_info *link_info; 9337 9338 link_info = adapter->deflink; 9339 if (ucfg_ipa_is_enabled()) { 9340 ucfg_ipa_uc_disconnect_ap(hdd_ctx->pdev, 9341 adapter->dev); 9342 ucfg_ipa_cleanup_dev_iface(hdd_ctx->pdev, 9343 adapter->dev, 9344 link_info->vdev_id); 9345 } 9346 } 9347 9348 #ifdef WLAN_FEATURE_NAN 9349 /** 9350 * hdd_ndp_state_cleanup() - API to set NDP state to Disconnected 9351 * @psoc: pointer to psoc object 9352 * @ndi_vdev_id: vdev_id of the NDI 9353 * 9354 * Return: None 9355 */ 9356 static void 9357 hdd_ndp_state_cleanup(struct wlan_objmgr_psoc *psoc, uint8_t ndi_vdev_id) 9358 { 9359 struct wlan_objmgr_vdev *ndi_vdev; 9360 9361 ndi_vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, ndi_vdev_id, 9362 WLAN_NAN_ID); 9363 if (!ndi_vdev) { 9364 hdd_err("Cannot obtain NDI vdev object!"); 9365 return; 9366 } 9367 9368 ucfg_nan_set_ndi_state(ndi_vdev, NAN_DATA_DISCONNECTED_STATE); 9369 9370 wlan_objmgr_vdev_release_ref(ndi_vdev, WLAN_NAN_ID); 9371 } 9372 9373 /** 9374 * hdd_peer_cleanup() - This API will delete NDP peer if exist and modifies 9375 * the NDP state. 9376 * @link_info: Link info pointer in HDD adapter 9377 * 9378 * Return: None 9379 */ 9380 static void hdd_peer_cleanup(struct wlan_hdd_link_info *link_info) 9381 { 9382 QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE; 9383 struct hdd_adapter *adapter = link_info->adapter; 9384 struct hdd_context *hdd_ctx = adapter->hdd_ctx; 9385 9386 /* Check if there is any peer present on the adapter */ 9387 if (!hdd_any_valid_peer_present(link_info)) { 9388 /* 9389 * No peers are connected to the NDI. So, set the NDI state to 9390 * DISCONNECTED. If there are any peers, ucfg_nan_disable_ndi() 9391 * would take care of cleanup all the peers and setting the 9392 * state to DISCONNECTED. 9393 */ 9394 hdd_ndp_state_cleanup(hdd_ctx->psoc, link_info->vdev_id); 9395 return; 9396 } 9397 9398 if (adapter->device_mode == QDF_NDI_MODE) 9399 qdf_status = ucfg_nan_disable_ndi(hdd_ctx->psoc, 9400 link_info->vdev_id); 9401 9402 if (QDF_IS_STATUS_ERROR(qdf_status)) 9403 return; 9404 9405 qdf_status = qdf_wait_for_event_completion(&adapter->peer_cleanup_done, 9406 WLAN_WAIT_PEER_CLEANUP); 9407 if (QDF_IS_STATUS_ERROR(qdf_status)) 9408 hdd_debug("peer_cleanup_done wait fail"); 9409 } 9410 #else 9411 static inline void 9412 hdd_ndp_state_cleanup(struct wlan_objmgr_psoc *psoc, uint8_t ndi_vdev_id) 9413 { 9414 } 9415 9416 static inline void 9417 hdd_ndp_peer_cleanup(struct hdd_context *hdd_ctx, struct hdd_adapter *adapter) 9418 { 9419 } 9420 9421 static inline void hdd_peer_cleanup(struct wlan_hdd_link_info *link_info) 9422 { 9423 } 9424 #endif /* WLAN_FEATURE_NAN */ 9425 9426 #ifdef FUNC_CALL_MAP 9427 9428 /** 9429 * hdd_dump_func_call_map() - Dump the function call map 9430 * 9431 * Return: None 9432 */ 9433 9434 static void hdd_dump_func_call_map(void) 9435 { 9436 char *cc_buf; 9437 9438 cc_buf = qdf_mem_malloc(QDF_FUNCTION_CALL_MAP_BUF_LEN); 9439 /* 9440 * These logs are required as these indicates the start and end of the 9441 * dump for the auto script to parse 9442 */ 9443 hdd_info("Function call map dump start"); 9444 qdf_get_func_call_map(cc_buf); 9445 qdf_trace_hex_dump(QDF_MODULE_ID_HDD, 9446 QDF_TRACE_LEVEL_DEBUG, cc_buf, QDF_FUNCTION_CALL_MAP_BUF_LEN); 9447 hdd_info("Function call map dump end"); 9448 qdf_mem_free(cc_buf); 9449 } 9450 #else 9451 static inline void hdd_dump_func_call_map(void) 9452 { 9453 } 9454 #endif 9455 9456 static void hdd_reset_scan_operation(struct wlan_hdd_link_info *link_info) 9457 { 9458 switch (link_info->adapter->device_mode) { 9459 case QDF_STA_MODE: 9460 case QDF_P2P_CLIENT_MODE: 9461 case QDF_P2P_DEVICE_MODE: 9462 case QDF_NDI_MODE: 9463 wlan_hdd_scan_abort(link_info); 9464 wlan_hdd_cleanup_remain_on_channel_ctx(link_info); 9465 if (link_info->adapter->device_mode == QDF_STA_MODE) { 9466 struct wlan_objmgr_vdev *vdev; 9467 9468 vdev = hdd_objmgr_get_vdev_by_user(link_info, 9469 WLAN_OSIF_SCAN_ID); 9470 if (!vdev) 9471 break; 9472 9473 wlan_cfg80211_sched_scan_stop(vdev); 9474 hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_SCAN_ID); 9475 } 9476 break; 9477 case QDF_P2P_GO_MODE: 9478 wlan_hdd_cleanup_remain_on_channel_ctx(link_info); 9479 break; 9480 case QDF_SAP_MODE: 9481 qdf_atomic_set(&link_info->session.ap.acs_in_progress, 0); 9482 break; 9483 default: 9484 break; 9485 } 9486 } 9487 9488 #ifdef WLAN_OPEN_SOURCE 9489 void hdd_cancel_ip_notifier_work(struct hdd_adapter *adapter) 9490 { 9491 cancel_work_sync(&adapter->ipv4_notifier_work); 9492 #ifdef WLAN_NS_OFFLOAD 9493 cancel_work_sync(&adapter->ipv6_notifier_work); 9494 #endif 9495 } 9496 #endif 9497 9498 void hdd_adapter_deregister_fc(struct hdd_adapter *adapter) 9499 { 9500 hdd_deregister_hl_netdev_fc_timer(adapter); 9501 hdd_deregister_tx_flow_control(adapter); 9502 } 9503 9504 static void hdd_stop_and_cleanup_ndi(struct wlan_hdd_link_info *link_info) 9505 { 9506 QDF_STATUS status; 9507 unsigned long rc; 9508 struct hdd_adapter *adapter = link_info->adapter; 9509 struct hdd_context *hdd_ctx = adapter->hdd_ctx; 9510 9511 hdd_destroy_adapter_sysfs_files(adapter); 9512 /* For NDI do not use roam_profile */ 9513 INIT_COMPLETION(adapter->disconnect_comp_var); 9514 hdd_peer_cleanup(link_info); 9515 status = sme_roam_ndi_stop(hdd_ctx->mac_handle, link_info->vdev_id); 9516 if (QDF_IS_STATUS_SUCCESS(status)) { 9517 rc = wait_for_completion_timeout( 9518 &adapter->disconnect_comp_var, 9519 msecs_to_jiffies(SME_CMD_STOP_BSS_TIMEOUT)); 9520 if (!rc) 9521 hdd_warn("disconn_comp_var wait fail"); 9522 hdd_cleanup_ndi(link_info); 9523 } 9524 } 9525 9526 static void 9527 hdd_sta_disconnect_and_cleanup(struct wlan_hdd_link_info *link_info) 9528 { 9529 QDF_STATUS status; 9530 enum wlan_reason_code reason; 9531 struct hdd_adapter *adapter = link_info->adapter; 9532 9533 /* 9534 * On vdev delete wait for disconnect to 9535 * complete. i.e use sync API, so that the 9536 * vdev ref of MLME are cleaned and disconnect 9537 * complete before vdev is moved to logically 9538 * deleted. 9539 */ 9540 if (cds_is_driver_recovering()) 9541 reason = REASON_DEVICE_RECOVERY; 9542 else 9543 reason = REASON_IFACE_DOWN; 9544 9545 status = wlan_hdd_cm_issue_disconnect(link_info, reason, true); 9546 if (QDF_IS_STATUS_ERROR(status) && ucfg_ipa_is_enabled()) { 9547 hdd_err("STA disconnect failed"); 9548 ucfg_ipa_uc_cleanup_sta(adapter->hdd_ctx->pdev, adapter->dev, 9549 link_info->vdev_id); 9550 } 9551 } 9552 9553 static void 9554 hdd_disable_nan_active_disc(struct hdd_adapter *adapter) 9555 { 9556 struct hdd_context *hdd_ctx = adapter->hdd_ctx; 9557 enum QDF_OPMODE device_mode = adapter->device_mode; 9558 9559 if ((device_mode == QDF_NAN_DISC_MODE || 9560 (device_mode == QDF_STA_MODE && 9561 !ucfg_nan_is_vdev_creation_allowed(hdd_ctx->psoc))) && 9562 ucfg_is_nan_conc_control_supported(hdd_ctx->psoc) && 9563 ucfg_is_nan_disc_active(hdd_ctx->psoc)) 9564 ucfg_disable_nan_discovery(hdd_ctx->psoc, NULL, 0); 9565 } 9566 9567 static void 9568 hdd_monitor_mode_release_wakelock(struct wlan_hdd_link_info *link_info) 9569 { 9570 struct hdd_adapter *adapter = link_info->adapter; 9571 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); 9572 9573 if (wlan_hdd_is_session_type_monitor(adapter->device_mode) && 9574 (ucfg_mlme_is_sta_mon_conc_supported(hdd_ctx->psoc) || 9575 ucfg_dp_is_local_pkt_capture_enabled(hdd_ctx->psoc))) { 9576 hdd_info("Release wakelock for STA + monitor mode!"); 9577 os_if_dp_local_pkt_capture_stop(link_info->vdev); 9578 qdf_runtime_pm_allow_suspend( 9579 &hdd_ctx->runtime_context.monitor_mode); 9580 hdd_lpc_enable_powersave(hdd_ctx); 9581 qdf_wake_lock_release(&hdd_ctx->monitor_mode_wakelock, 9582 WIFI_POWER_EVENT_WAKELOCK_MONITOR_MODE); 9583 } 9584 } 9585 9586 static void 9587 hdd_monitor_mode_disable_and_delete(struct wlan_hdd_link_info *link_info) 9588 { 9589 QDF_STATUS status; 9590 struct hdd_adapter *adapter = link_info->adapter; 9591 struct hdd_context *hdd_ctx = adapter->hdd_ctx; 9592 9593 status = hdd_disable_monitor_mode(); 9594 if (QDF_IS_STATUS_ERROR(status)) 9595 hdd_err_rl("datapath reset failed for montior mode"); 9596 hdd_set_idle_ps_config(hdd_ctx, true); 9597 status = hdd_monitor_mode_vdev_status(adapter); 9598 if (QDF_IS_STATUS_ERROR(status)) 9599 hdd_err_rl("stop failed montior mode"); 9600 sme_delete_mon_session(hdd_ctx->mac_handle, link_info->vdev_id); 9601 } 9602 9603 static void 9604 hdd_stop_and_close_pre_cac_adapter(struct hdd_context *hdd_ctx, 9605 struct wlan_objmgr_vdev *vdev) 9606 { 9607 if (!vdev) 9608 return; 9609 9610 if (!ucfg_pre_cac_adapter_is_active(vdev)) { 9611 ucfg_pre_cac_stop(hdd_ctx->psoc); 9612 hdd_close_pre_cac_adapter(hdd_ctx); 9613 } else { 9614 if (ucfg_pre_cac_set_status(vdev, false)) 9615 hdd_err("Failed to set is_pre_cac_on to false"); 9616 } 9617 } 9618 9619 static void hdd_reset_ies_on_sap_stop(struct wlan_hdd_link_info *link_info) 9620 { 9621 mac_handle_t mac_handle; 9622 tSirUpdateIE update_ie; 9623 QDF_STATUS status; 9624 struct hdd_adapter *adapter = link_info->adapter; 9625 9626 mac_handle = hdd_adapter_get_mac_handle(adapter); 9627 update_ie.vdev_id = link_info->vdev_id; 9628 update_ie.ieBufferlength = 0; 9629 update_ie.pAdditionIEBuffer = NULL; 9630 update_ie.append = false; 9631 update_ie.notify = false; 9632 9633 /* Probe bcn reset */ 9634 status = sme_update_add_ie(mac_handle, &update_ie, 9635 eUPDATE_IE_PROBE_BCN); 9636 if (status == QDF_STATUS_E_FAILURE) 9637 hdd_err("Could not pass PROBE_RSP_BCN to PE"); 9638 9639 /* Assoc resp reset */ 9640 status = sme_update_add_ie(mac_handle, &update_ie, 9641 eUPDATE_IE_ASSOC_RESP); 9642 if (status == QDF_STATUS_E_FAILURE) 9643 hdd_err("Could not pass ASSOC_RSP to PE"); 9644 9645 /* Reset WNI_CFG_PROBE_RSP Flags */ 9646 wlan_hdd_reset_prob_rspies(link_info); 9647 } 9648 9649 static void hdd_stop_station_adapter(struct hdd_adapter *adapter) 9650 { 9651 struct wlan_objmgr_vdev *vdev; 9652 enum QDF_OPMODE mode; 9653 struct wlan_hdd_link_info *link_info; 9654 9655 mode = adapter->device_mode; 9656 hdd_adapter_for_each_active_link_info(adapter, link_info) { 9657 vdev = hdd_objmgr_get_vdev_by_user(link_info, 9658 WLAN_INIT_DEINIT_ID); 9659 if (!vdev) 9660 continue; 9661 9662 if (mode == QDF_NDI_MODE) 9663 hdd_stop_and_cleanup_ndi(link_info); 9664 else if (!hdd_cm_is_disconnected(link_info)) 9665 hdd_sta_disconnect_and_cleanup(link_info); 9666 9667 hdd_reset_scan_operation(link_info); 9668 wlan_hdd_cleanup_actionframe(link_info); 9669 wlan_hdd_flush_pmksa_cache(link_info); 9670 9671 if (mode == QDF_STA_MODE) 9672 ucfg_ipa_flush_pending_vdev_events( 9673 wlan_vdev_get_pdev(vdev), 9674 link_info->vdev_id); 9675 hdd_objmgr_put_vdev_by_user(vdev, WLAN_INIT_DEINIT_ID); 9676 hdd_vdev_destroy(link_info); 9677 } 9678 9679 hdd_disable_nan_active_disc(adapter); 9680 hdd_adapter_deregister_fc(adapter); 9681 hdd_cancel_ip_notifier_work(adapter); 9682 } 9683 9684 static int hdd_stop_mon_adapter(struct hdd_adapter *adapter) 9685 { 9686 struct wlan_objmgr_vdev *vdev; 9687 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); 9688 struct wlan_hdd_link_info *link_info = adapter->deflink; 9689 9690 vdev = hdd_objmgr_get_vdev_by_user(link_info, 9691 WLAN_INIT_DEINIT_ID); 9692 if (wlan_hdd_is_session_type_monitor(adapter->device_mode) && 9693 vdev && 9694 ucfg_pkt_capture_get_mode(hdd_ctx->psoc) != 9695 PACKET_CAPTURE_MODE_DISABLE) { 9696 struct hdd_adapter *sta_adapter; 9697 9698 ucfg_pkt_capture_deregister_callbacks(vdev); 9699 hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_ID); 9700 link_info->vdev = NULL; 9701 9702 sta_adapter = hdd_get_adapter(hdd_ctx, QDF_STA_MODE); 9703 if (!sta_adapter) { 9704 hdd_objmgr_put_vdev_by_user(vdev, WLAN_INIT_DEINIT_ID); 9705 hdd_err("No station interface found"); 9706 return -EINVAL; 9707 } 9708 hdd_reset_monitor_interface(sta_adapter); 9709 } 9710 9711 hdd_monitor_mode_release_wakelock(link_info); 9712 wlan_hdd_scan_abort(link_info); 9713 hdd_adapter_deregister_fc(adapter); 9714 hdd_monitor_mode_disable_and_delete(link_info); 9715 if (vdev) 9716 hdd_objmgr_put_vdev_by_user(vdev, WLAN_INIT_DEINIT_ID); 9717 9718 hdd_vdev_destroy(link_info); 9719 9720 return 0; 9721 } 9722 9723 static void hdd_stop_sap_go_adapter(struct hdd_adapter *adapter) 9724 { 9725 enum QDF_OPMODE mode; 9726 struct hdd_ap_ctx *ap_ctx; 9727 struct sap_context *sap_ctx; 9728 struct sap_config *sap_config; 9729 struct hdd_hostapd_state *hostapd_state; 9730 struct wlan_objmgr_vdev *vdev; 9731 struct wlan_hdd_link_info *link_info = adapter->deflink; 9732 QDF_STATUS status = QDF_STATUS_SUCCESS; 9733 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); 9734 uint8_t link_id; 9735 9736 mode = adapter->device_mode; 9737 ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(link_info); 9738 sap_ctx = WLAN_HDD_GET_SAP_CTX_PTR(link_info); 9739 vdev = hdd_objmgr_get_vdev_by_user(link_info, WLAN_INIT_DEINIT_ID); 9740 9741 if (mode == QDF_SAP_MODE) { 9742 wlan_hdd_scan_abort(link_info); 9743 hdd_abort_ongoing_sta_connection(hdd_ctx); 9744 /* Diassociate with all the peers before stop ap post */ 9745 if (test_bit(SOFTAP_BSS_STARTED, &link_info->link_flags)) { 9746 if (wlan_hdd_del_station(adapter, NULL)) 9747 hdd_sap_indicate_disconnect_for_sta(adapter); 9748 } 9749 wlan_hdd_flush_pmksa_cache(link_info); 9750 sap_config = &ap_ctx->sap_config; 9751 wlansap_reset_sap_config_add_ie(sap_config, eUPDATE_IE_ALL); 9752 hdd_stop_and_close_pre_cac_adapter(hdd_ctx, vdev); 9753 } 9754 wlansap_cleanup_cac_timer(sap_ctx); 9755 cds_flush_work(&adapter->sap_stop_bss_work); 9756 9757 if (qdf_atomic_read(&ap_ctx->acs_in_progress)) { 9758 hdd_info("ACS in progress, wait for complete"); 9759 qdf_wait_for_event_completion(&link_info->acs_complete_event, 9760 ACS_COMPLETE_TIMEOUT); 9761 } 9762 9763 if (mode == QDF_P2P_GO_MODE) { 9764 wlan_hdd_cleanup_remain_on_channel_ctx(link_info); 9765 hdd_abort_ongoing_sta_connection(hdd_ctx); 9766 } 9767 9768 hdd_adapter_deregister_fc(adapter); 9769 hdd_destroy_acs_timer(adapter); 9770 9771 mutex_lock(&hdd_ctx->sap_lock); 9772 if (test_bit(SOFTAP_BSS_STARTED, &link_info->link_flags)) { 9773 hostapd_state = WLAN_HDD_GET_HOSTAP_STATE_PTR(link_info); 9774 qdf_event_reset(&hostapd_state->qdf_stop_bss_event); 9775 status = wlansap_stop_bss(ap_ctx->sap_context); 9776 if (QDF_IS_STATUS_SUCCESS(status)) { 9777 status = qdf_wait_single_event(&hostapd_state->qdf_stop_bss_event, 9778 SME_CMD_STOP_BSS_TIMEOUT); 9779 if (QDF_IS_STATUS_ERROR(status)) { 9780 hdd_err("failure waiting for wlansap_stop_bss %d", 9781 status); 9782 hdd_ipa_ap_disconnect_evt(hdd_ctx, adapter); 9783 } 9784 } else { 9785 hdd_err("failure in wlansap_stop_bss"); 9786 } 9787 9788 clear_bit(SOFTAP_BSS_STARTED, &link_info->link_flags); 9789 policy_mgr_decr_session_set_pcl(hdd_ctx->psoc, 9790 adapter->device_mode, 9791 link_info->vdev_id); 9792 hdd_green_ap_start_state_mc(hdd_ctx, adapter->device_mode, 9793 false); 9794 9795 hdd_reset_ies_on_sap_stop(link_info); 9796 } 9797 9798 /* 9799 * Note to restart sap after SSR driver needs below information 9800 * and is not cleared/freed on purpose in case of SAP SSR 9801 */ 9802 if (!cds_is_driver_recovering()) { 9803 clear_bit(SOFTAP_INIT_DONE, &link_info->link_flags); 9804 qdf_mem_free(ap_ctx->beacon); 9805 ap_ctx->beacon = NULL; 9806 9807 if (vdev) { 9808 link_id = wlan_vdev_get_link_id(vdev); 9809 ucfg_crypto_free_key_by_link_id(hdd_ctx->psoc, 9810 &link_info->link_addr, 9811 link_id); 9812 } 9813 } 9814 /* Clear all the cached sta info */ 9815 hdd_clear_cached_sta_info(adapter); 9816 9817 if (vdev && policy_mgr_is_dnsc_set(vdev)) 9818 wlan_hdd_send_avoid_freq_for_dnbs(hdd_ctx, 0); 9819 9820 hdd_cancel_ip_notifier_work(adapter); 9821 sap_release_vdev_ref(sap_ctx); 9822 9823 if (mode == QDF_SAP_MODE) 9824 ucfg_ipa_flush_pending_vdev_events(hdd_ctx->pdev, 9825 link_info->vdev_id); 9826 if (vdev) 9827 hdd_objmgr_put_vdev_by_user(vdev, WLAN_INIT_DEINIT_ID); 9828 hdd_vdev_destroy(link_info); 9829 mutex_unlock(&hdd_ctx->sap_lock); 9830 ucfg_ipa_flush(hdd_ctx->pdev); 9831 } 9832 9833 static void hdd_stop_ocb_adapter(struct hdd_adapter *adapter) 9834 { 9835 struct hdd_station_ctx *sta_ctx; 9836 struct wlan_objmgr_vdev *vdev; 9837 struct wlan_hdd_link_info *link_info = adapter->deflink; 9838 9839 vdev = hdd_objmgr_get_vdev_by_user(link_info, WLAN_INIT_DEINIT_ID); 9840 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(link_info); 9841 cdp_clear_peer(cds_get_context(QDF_MODULE_ID_SOC), OL_TXRX_PDEV_ID, 9842 sta_ctx->conn_info.peer_macaddr[0]); 9843 hdd_adapter_deregister_fc(adapter); 9844 if (vdev) 9845 hdd_objmgr_put_vdev_by_user(vdev, WLAN_INIT_DEINIT_ID); 9846 hdd_vdev_destroy(link_info); 9847 } 9848 9849 QDF_STATUS hdd_stop_adapter_ext(struct hdd_context *hdd_ctx, 9850 struct hdd_adapter *adapter) 9851 { 9852 QDF_STATUS status; 9853 struct wlan_hdd_link_info *link_info = adapter->deflink; 9854 9855 hdd_enter(); 9856 hdd_destroy_adapter_sysfs_files(adapter); 9857 9858 if (adapter->device_mode == QDF_STA_MODE && 9859 hdd_is_pkt_capture_mon_enable(adapter) && 9860 ucfg_pkt_capture_get_mode(hdd_ctx->psoc) != 9861 PACKET_CAPTURE_MODE_DISABLE) { 9862 hdd_unmap_monitor_interface_vdev(adapter); 9863 } 9864 9865 if (link_info->vdev_id != WLAN_UMAC_VDEV_ID_MAX) 9866 wlan_hdd_cfg80211_deregister_frames(adapter); 9867 9868 hdd_stop_tsf_sync(adapter); 9869 cds_flush_work(&adapter->scan_block_work); 9870 wlan_hdd_cfg80211_scan_block(adapter); 9871 hdd_debug("Disabling queues"); 9872 wlan_hdd_netif_queue_control(adapter, 9873 WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER, 9874 WLAN_CONTROL_PATH); 9875 9876 switch (adapter->device_mode) { 9877 case QDF_STA_MODE: 9878 case QDF_P2P_CLIENT_MODE: 9879 case QDF_NDI_MODE: 9880 case QDF_P2P_DEVICE_MODE: 9881 case QDF_NAN_DISC_MODE: 9882 hdd_stop_station_adapter(adapter); 9883 break; 9884 case QDF_MONITOR_MODE: 9885 status = hdd_stop_mon_adapter(adapter); 9886 if (QDF_IS_STATUS_ERROR(status)) 9887 return status; 9888 9889 break; 9890 case QDF_SAP_MODE: 9891 case QDF_P2P_GO_MODE: 9892 hdd_stop_sap_go_adapter(adapter); 9893 break; 9894 case QDF_OCB_MODE: 9895 hdd_stop_ocb_adapter(adapter); 9896 break; 9897 default: 9898 break; 9899 } 9900 9901 /* Moved from vdev destroy as it is per adapter */ 9902 wlan_cfg80211_cleanup_scan_queue(hdd_ctx->pdev, adapter->dev); 9903 9904 /* Disable all links (expect default index) in adapter. 9905 * Set link address to NULL 9906 */ 9907 hdd_adapter_disable_all_links(adapter); 9908 9909 /* This function should be invoked at the end of this api*/ 9910 hdd_dump_func_call_map(); 9911 hdd_exit(); 9912 9913 return QDF_STATUS_SUCCESS; 9914 } 9915 9916 QDF_STATUS hdd_stop_adapter(struct hdd_context *hdd_ctx, 9917 struct hdd_adapter *adapter) 9918 { 9919 QDF_STATUS status; 9920 9921 if (adapter->device_mode == QDF_STA_MODE) 9922 status = hdd_stop_link_adapter(hdd_ctx, adapter); 9923 9924 status = hdd_stop_adapter_ext(hdd_ctx, adapter); 9925 9926 return status; 9927 } 9928 9929 /** 9930 * hdd_deinit_all_adapters - deinit all adapters 9931 * @hdd_ctx: HDD context 9932 * @rtnl_held: True if RTNL lock held 9933 * 9934 */ 9935 void hdd_deinit_all_adapters(struct hdd_context *hdd_ctx, bool rtnl_held) 9936 { 9937 struct hdd_adapter *adapter, *next_adapter = NULL; 9938 9939 hdd_enter(); 9940 9941 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 9942 NET_DEV_HOLD_DEINIT_ALL_ADAPTERS) { 9943 hdd_deinit_adapter(hdd_ctx, adapter, rtnl_held); 9944 hdd_adapter_dev_put_debug(adapter, 9945 NET_DEV_HOLD_DEINIT_ALL_ADAPTERS); 9946 } 9947 9948 hdd_exit(); 9949 } 9950 9951 QDF_STATUS hdd_stop_all_adapters(struct hdd_context *hdd_ctx) 9952 { 9953 struct hdd_adapter *adapter, *next_adapter = NULL; 9954 9955 hdd_enter(); 9956 9957 ucfg_pre_cac_stop(hdd_ctx->psoc); 9958 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 9959 NET_DEV_HOLD_STOP_ALL_ADAPTERS) { 9960 hdd_stop_adapter(hdd_ctx, adapter); 9961 hdd_adapter_dev_put_debug(adapter, 9962 NET_DEV_HOLD_STOP_ALL_ADAPTERS); 9963 } 9964 9965 hdd_exit(); 9966 9967 return QDF_STATUS_SUCCESS; 9968 } 9969 9970 void hdd_set_netdev_flags(struct hdd_adapter *adapter) 9971 { 9972 bool enable_csum = false; 9973 bool enable_lro; 9974 enum QDF_OPMODE device_mode; 9975 struct hdd_context *hdd_ctx; 9976 ol_txrx_soc_handle soc; 9977 uint64_t temp; 9978 9979 if (!adapter || !adapter->dev) { 9980 hdd_err("invalid input!"); 9981 return; 9982 } 9983 device_mode = adapter->device_mode; 9984 9985 hdd_ctx = adapter->hdd_ctx; 9986 soc = cds_get_context(QDF_MODULE_ID_SOC); 9987 9988 if (!soc || !hdd_ctx) { 9989 hdd_err("invalid SOC or HDD context!"); 9990 return; 9991 } 9992 9993 /* Determine device_mode specific configuration */ 9994 9995 enable_lro = !!cdp_cfg_get(soc, cfg_dp_lro_enable); 9996 enable_csum = !!cdp_cfg_get(soc, 9997 cfg_dp_enable_ip_tcp_udp_checksum_offload); 9998 switch (device_mode) { 9999 case QDF_P2P_DEVICE_MODE: 10000 case QDF_P2P_CLIENT_MODE: 10001 enable_csum = !!cdp_cfg_get(soc, 10002 cfg_dp_enable_p2p_ip_tcp_udp_checksum_offload); 10003 break; 10004 case QDF_P2P_GO_MODE: 10005 enable_csum = !!cdp_cfg_get(soc, 10006 cfg_dp_enable_p2p_ip_tcp_udp_checksum_offload); 10007 enable_lro = false; 10008 break; 10009 case QDF_SAP_MODE: 10010 enable_lro = false; 10011 break; 10012 case QDF_NDI_MODE: 10013 case QDF_NAN_DISC_MODE: 10014 enable_csum = !!cdp_cfg_get(soc, 10015 cfg_dp_enable_nan_ip_tcp_udp_checksum_offload); 10016 break; 10017 default: 10018 break; 10019 } 10020 10021 /* Set netdev flags */ 10022 10023 /* 10024 * In case of USB tethering, LRO is disabled. If SSR happened 10025 * during that time, then as part of SSR init, do not enable 10026 * the LRO again. Keep the LRO state same as before SSR. 10027 */ 10028 if (enable_lro && !(qdf_atomic_read(&hdd_ctx->vendor_disable_lro_flag))) 10029 adapter->dev->features |= NETIF_F_LRO; 10030 10031 if (enable_csum) 10032 adapter->dev->features |= 10033 (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM); 10034 10035 if (cdp_cfg_get(soc, cfg_dp_tso_enable) && enable_csum) { 10036 adapter->dev->features |= TSO_FEATURE_FLAGS; 10037 adapter->tso_csum_feature_enabled = 1; 10038 } 10039 10040 if (cdp_cfg_get(soc, cfg_dp_sg_enable)) 10041 adapter->dev->features |= NETIF_F_SG; 10042 10043 adapter->dev->features |= NETIF_F_RXCSUM; 10044 temp = (uint64_t)adapter->dev->features; 10045 10046 hdd_debug("adapter mode %u dev feature 0x%llx", device_mode, temp); 10047 } 10048 10049 #ifdef QCA_LL_LEGACY_TX_FLOW_CONTROL 10050 /** 10051 * hdd_adapter_abort_tx_flow() - Abort the tx flow control 10052 * @adapter: pointer to hdd adapter 10053 * 10054 * Resume tx and stop the tx flow control timer if the tx is paused 10055 * and the flow control timer is running. This function is called by 10056 * SSR to avoid the inconsistency of tx status before and after SSR. 10057 * 10058 * Return: void 10059 */ 10060 static void hdd_adapter_abort_tx_flow(struct hdd_adapter *adapter) 10061 { 10062 if (adapter->deflink->hdd_stats.tx_rx_stats.is_txflow_paused && 10063 QDF_TIMER_STATE_RUNNING == 10064 qdf_mc_timer_get_current_state( 10065 &adapter->tx_flow_control_timer)) { 10066 hdd_tx_resume_timer_expired_handler(adapter); 10067 qdf_mc_timer_stop(&adapter->tx_flow_control_timer); 10068 } 10069 } 10070 #else 10071 static void hdd_adapter_abort_tx_flow(struct hdd_adapter *adapter) 10072 { 10073 } 10074 #endif 10075 10076 QDF_STATUS hdd_reset_all_adapters(struct hdd_context *hdd_ctx) 10077 { 10078 struct hdd_adapter *adapter, *next_adapter = NULL; 10079 bool value; 10080 struct wlan_objmgr_vdev *vdev; 10081 struct wlan_hdd_link_info *link_info; 10082 10083 hdd_enter(); 10084 10085 ucfg_mlme_get_sap_internal_restart(hdd_ctx->psoc, &value); 10086 10087 10088 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 10089 NET_DEV_HOLD_RESET_ALL_ADAPTERS) { 10090 hdd_info("[SSR] reset adapter with device mode %s(%d)", 10091 qdf_opmode_str(adapter->device_mode), 10092 adapter->device_mode); 10093 10094 hdd_adapter_for_each_active_link_info(adapter, link_info) { 10095 hdd_adapter_abort_tx_flow(adapter); 10096 10097 if ((adapter->device_mode == QDF_STA_MODE) || 10098 (adapter->device_mode == QDF_P2P_CLIENT_MODE)) { 10099 hdd_send_twt_del_all_sessions_to_userspace(link_info); 10100 10101 /* Stop tdls timers */ 10102 vdev = hdd_objmgr_get_vdev_by_user(link_info, 10103 WLAN_OSIF_TDLS_ID); 10104 if (vdev) { 10105 hdd_notify_tdls_reset_adapter(vdev); 10106 hdd_objmgr_put_vdev_by_user(vdev, 10107 WLAN_OSIF_TDLS_ID); 10108 } 10109 } 10110 10111 if (value && 10112 adapter->device_mode == QDF_SAP_MODE) { 10113 hdd_medium_assess_ssr_enable_flag(); 10114 wlan_hdd_netif_queue_control(adapter, 10115 WLAN_STOP_ALL_NETIF_QUEUE, 10116 WLAN_CONTROL_PATH); 10117 } else { 10118 wlan_hdd_netif_queue_control(adapter, 10119 WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER, 10120 WLAN_CONTROL_PATH); 10121 } 10122 10123 /* 10124 * Clear fc flag if it was set before SSR to avoid 10125 * TX queues permanently stopped after SSR. 10126 * Here WLAN_START_ALL_NETIF_QUEUE will actually 10127 * not start any queue since it's blocked by reason 10128 * WLAN_CONTROL_PATH. 10129 */ 10130 if (adapter->pause_map & (1 << WLAN_DATA_FLOW_CONTROL)) 10131 wlan_hdd_netif_queue_control(adapter, 10132 WLAN_START_ALL_NETIF_QUEUE, 10133 WLAN_DATA_FLOW_CONTROL); 10134 10135 hdd_reset_scan_operation(link_info); 10136 if (test_bit(WMM_INIT_DONE, &adapter->event_flags)) { 10137 hdd_wmm_adapter_close(adapter); 10138 clear_bit(WMM_INIT_DONE, &adapter->event_flags); 10139 } 10140 10141 hdd_debug("Flush any mgmt references held by peer"); 10142 hdd_stop_adapter(hdd_ctx, adapter); 10143 } 10144 hdd_adapter_dev_put_debug(adapter, 10145 NET_DEV_HOLD_RESET_ALL_ADAPTERS); 10146 } 10147 10148 hdd_exit(); 10149 10150 return QDF_STATUS_SUCCESS; 10151 } 10152 10153 static bool hdd_is_any_link_opened(struct hdd_adapter *adapter) 10154 { 10155 struct wlan_hdd_link_info *link_info; 10156 10157 hdd_adapter_for_each_active_link_info(adapter, link_info) { 10158 if (test_bit(SME_SESSION_OPENED, &link_info->link_flags)) 10159 return true; 10160 } 10161 return false; 10162 } 10163 10164 bool hdd_is_any_interface_open(struct hdd_context *hdd_ctx) 10165 { 10166 struct hdd_adapter *adapter, *next_adapter = NULL; 10167 wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_IS_ANY_INTERFACE_OPEN; 10168 10169 if (hdd_get_conparam() == QDF_GLOBAL_FTM_MODE) { 10170 hdd_info("FTM mode, don't close the module"); 10171 return true; 10172 } 10173 10174 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 10175 dbgid) { 10176 if (test_bit(DEVICE_IFACE_OPENED, &adapter->event_flags) || 10177 hdd_is_any_link_opened(adapter)) { 10178 hdd_adapter_dev_put_debug(adapter, dbgid); 10179 if (next_adapter) 10180 hdd_adapter_dev_put_debug(next_adapter, dbgid); 10181 return true; 10182 } 10183 hdd_adapter_dev_put_debug(adapter, dbgid); 10184 } 10185 10186 return false; 10187 } 10188 10189 bool hdd_is_interface_up(struct hdd_adapter *adapter) 10190 { 10191 if (test_bit(DEVICE_IFACE_OPENED, &adapter->event_flags)) 10192 return true; 10193 else 10194 return false; 10195 } 10196 10197 #ifdef FEATURE_MONITOR_MODE_SUPPORT 10198 #ifdef WLAN_FEATURE_11BE 10199 static inline bool wlan_hdd_is_mon_channel_bw_valid(enum phy_ch_width ch_width) 10200 { 10201 if (ch_width > CH_WIDTH_320MHZ || 10202 (!cds_is_sub_20_mhz_enabled() && (ch_width == CH_WIDTH_5MHZ || 10203 ch_width == CH_WIDTH_10MHZ))) 10204 return false; 10205 10206 return true; 10207 } 10208 #else 10209 static inline bool wlan_hdd_is_mon_channel_bw_valid(enum phy_ch_width ch_width) 10210 { 10211 if (ch_width > CH_WIDTH_10MHZ || 10212 (!cds_is_sub_20_mhz_enabled() && (ch_width == CH_WIDTH_5MHZ || 10213 ch_width == CH_WIDTH_10MHZ))) 10214 return false; 10215 10216 return true; 10217 } 10218 #endif 10219 10220 int wlan_hdd_set_mon_chan(struct hdd_adapter *adapter, qdf_freq_t freq, 10221 uint32_t bandwidth) 10222 { 10223 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); 10224 struct hdd_station_ctx *sta_ctx; 10225 struct hdd_mon_set_ch_info *ch_info; 10226 QDF_STATUS status; 10227 struct qdf_mac_addr bssid; 10228 struct channel_change_req *req; 10229 struct ch_params ch_params; 10230 enum phy_ch_width max_fw_bw; 10231 enum phy_ch_width ch_width; 10232 int ret; 10233 10234 if ((hdd_get_conparam() != QDF_GLOBAL_MONITOR_MODE) && 10235 (!policy_mgr_is_sta_mon_concurrency(hdd_ctx->psoc))) { 10236 hdd_err("Not supported, device is not in monitor mode"); 10237 return -EINVAL; 10238 } 10239 10240 if (adapter->device_mode != QDF_MONITOR_MODE) { 10241 hdd_err_rl("Not supported, adapter is not in monitor mode"); 10242 return -EINVAL; 10243 } 10244 10245 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter->deflink); 10246 ch_info = &sta_ctx->ch_info; 10247 10248 /* Verify the BW before accepting this request */ 10249 ch_width = bandwidth; 10250 10251 if (!wlan_hdd_is_mon_channel_bw_valid(ch_width)) { 10252 hdd_err("invalid BW received %d", ch_width); 10253 return -EINVAL; 10254 } 10255 10256 max_fw_bw = sme_get_vht_ch_width(); 10257 10258 hdd_debug("max fw BW %d ch width %d", max_fw_bw, ch_width); 10259 if ((ch_width == CH_WIDTH_160MHZ && 10260 max_fw_bw <= WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ) || 10261 (ch_width == CH_WIDTH_80P80MHZ && 10262 max_fw_bw <= WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ)) { 10263 hdd_err("FW does not support this BW %d max BW supported %d", 10264 ch_width, max_fw_bw); 10265 return -EINVAL; 10266 } 10267 10268 if (!hdd_is_target_eht_phy_ch_width_supported(ch_width)) 10269 return -EINVAL; 10270 10271 ret = hdd_validate_channel_and_bandwidth(adapter, freq, bandwidth); 10272 if (ret) { 10273 hdd_err("Invalid CH and BW combo"); 10274 return ret; 10275 } 10276 10277 hdd_debug("Set monitor mode frequency %d", freq); 10278 qdf_mem_copy(bssid.bytes, adapter->mac_addr.bytes, 10279 QDF_MAC_ADDR_SIZE); 10280 10281 ch_params.ch_width = bandwidth; 10282 wlan_reg_set_channel_params_for_pwrmode(hdd_ctx->pdev, freq, 0, 10283 &ch_params, 10284 REG_CURRENT_PWR_MODE); 10285 10286 if (ch_params.ch_width == CH_WIDTH_INVALID) { 10287 hdd_err("Invalid capture channel or bandwidth for a country"); 10288 return -EINVAL; 10289 } 10290 if (wlan_hdd_change_hw_mode_for_given_chnl(adapter, freq, 10291 POLICY_MGR_UPDATE_REASON_SET_OPER_CHAN)) { 10292 hdd_err("Failed to change hw mode"); 10293 return -EINVAL; 10294 } 10295 10296 if (adapter->monitor_mode_vdev_up_in_progress) { 10297 hdd_err_rl("monitor mode vdev up in progress"); 10298 return -EBUSY; 10299 } 10300 10301 status = qdf_event_reset(&adapter->qdf_monitor_mode_vdev_up_event); 10302 if (QDF_IS_STATUS_ERROR(status)) { 10303 hdd_err_rl("failed to reinit monitor mode vdev up event"); 10304 return qdf_status_to_os_return(status); 10305 } 10306 adapter->monitor_mode_vdev_up_in_progress = true; 10307 10308 qdf_mem_zero(&ch_params, sizeof(struct ch_params)); 10309 10310 req = qdf_mem_malloc(sizeof(struct channel_change_req)); 10311 if (!req) 10312 return -ENOMEM; 10313 req->vdev_id = adapter->deflink->vdev_id; 10314 req->target_chan_freq = freq; 10315 req->ch_width = ch_width; 10316 10317 ch_params.ch_width = ch_width; 10318 hdd_select_cbmode(adapter, freq, 0, &ch_params); 10319 10320 req->sec_ch_offset = ch_params.sec_ch_offset; 10321 req->center_freq_seg0 = ch_params.center_freq_seg0; 10322 req->center_freq_seg1 = ch_params.center_freq_seg1; 10323 10324 sme_fill_channel_change_request(hdd_ctx->mac_handle, req, 10325 ch_info->phy_mode); 10326 status = sme_send_channel_change_req(hdd_ctx->mac_handle, req); 10327 qdf_mem_free(req); 10328 if (status) { 10329 hdd_err("Status: %d Failed to set sme_roam Channel for monitor mode", 10330 status); 10331 adapter->monitor_mode_vdev_up_in_progress = false; 10332 return qdf_status_to_os_return(status); 10333 } 10334 10335 adapter->mon_chan_freq = freq; 10336 adapter->mon_bandwidth = bandwidth; 10337 10338 /* block on a completion variable until vdev up success*/ 10339 status = qdf_wait_for_event_completion( 10340 &adapter->qdf_monitor_mode_vdev_up_event, 10341 WLAN_MONITOR_MODE_VDEV_UP_EVT); 10342 if (QDF_IS_STATUS_ERROR(status)) { 10343 hdd_err_rl("monitor vdev up event time out vdev id: %d", 10344 adapter->deflink->vdev_id); 10345 if (adapter->qdf_monitor_mode_vdev_up_event.force_set) 10346 /* 10347 * SSR/PDR has caused shutdown, which has 10348 * forcefully set the event. 10349 */ 10350 hdd_err_rl("monitor mode vdev up event forcefully set"); 10351 else if (status == QDF_STATUS_E_TIMEOUT) 10352 hdd_err("monitor mode vdev up timed out"); 10353 else 10354 hdd_err_rl("Failed monitor mode vdev up(status-%d)", 10355 status); 10356 10357 adapter->monitor_mode_vdev_up_in_progress = false; 10358 } 10359 10360 return qdf_status_to_os_return(status); 10361 } 10362 #endif 10363 10364 #if defined MSM_PLATFORM && (LINUX_VERSION_CODE <= KERNEL_VERSION(4, 19, 0)) 10365 /** 10366 * hdd_stop_p2p_go() - call cfg80211 API to stop P2P GO 10367 * @adapter: pointer to adapter 10368 * 10369 * This function calls cfg80211 API to stop P2P GO 10370 * 10371 * Return: None 10372 */ 10373 static void hdd_stop_p2p_go(struct hdd_adapter *adapter) 10374 { 10375 hdd_debug("[SSR] send stop ap to supplicant"); 10376 cfg80211_ap_stopped(adapter->dev, GFP_KERNEL); 10377 } 10378 10379 static inline void hdd_delete_sta(struct hdd_adapter *adapter) 10380 { 10381 } 10382 10383 #else 10384 static void hdd_stop_p2p_go(struct hdd_adapter *adapter) 10385 { 10386 hdd_debug("[SSR] send stop iface ap to supplicant"); 10387 cfg80211_stop_iface(adapter->hdd_ctx->wiphy, &adapter->wdev, 10388 GFP_KERNEL); 10389 } 10390 10391 /** 10392 * hdd_delete_sta() - call cfg80211 API to delete STA 10393 * @adapter: pointer to adapter 10394 * 10395 * This function calls cfg80211 API to delete STA 10396 * 10397 * Return: None 10398 */ 10399 static void hdd_delete_sta(struct hdd_adapter *adapter) 10400 { 10401 struct qdf_mac_addr bcast_mac = QDF_MAC_ADDR_BCAST_INIT; 10402 10403 hdd_debug("[SSR] send restart supplicant"); 10404 /* event supplicant to restart */ 10405 cfg80211_del_sta(adapter->dev, 10406 (const u8 *)&bcast_mac.bytes[0], 10407 GFP_KERNEL); 10408 } 10409 #endif 10410 10411 QDF_STATUS hdd_start_all_adapters(struct hdd_context *hdd_ctx, bool rtnl_held) 10412 { 10413 struct hdd_adapter *adapter, *next_adapter = NULL; 10414 bool value; 10415 wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_START_ALL_ADAPTERS; 10416 int ret; 10417 10418 hdd_enter(); 10419 10420 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 10421 dbgid) { 10422 if (!hdd_is_interface_up(adapter) && 10423 adapter->device_mode != QDF_NDI_MODE) { 10424 hdd_adapter_dev_put_debug(adapter, dbgid); 10425 continue; 10426 } 10427 10428 hdd_debug("[SSR] start adapter with device mode %s(%d)", 10429 qdf_opmode_str(adapter->device_mode), 10430 adapter->device_mode); 10431 10432 hdd_wmm_dscp_initial_state(adapter); 10433 10434 switch (adapter->device_mode) { 10435 case QDF_STA_MODE: 10436 case QDF_P2P_CLIENT_MODE: 10437 case QDF_P2P_DEVICE_MODE: 10438 case QDF_NAN_DISC_MODE: 10439 10440 ret = hdd_start_station_adapter(adapter); 10441 if (ret) { 10442 hdd_err("[SSR] Failed to start station adapter: %d", 10443 ret); 10444 hdd_adapter_dev_put_debug(adapter, dbgid); 10445 continue; 10446 } 10447 if (adapter->device_mode == QDF_STA_MODE) { 10448 ret = hdd_start_link_adapter(adapter); 10449 if (ret) { 10450 hdd_err("[SSR] Failed to start link adapter: %d", 10451 ret); 10452 hdd_stop_adapter(hdd_ctx, adapter); 10453 hdd_adapter_dev_put_debug(adapter, 10454 dbgid); 10455 continue; 10456 } 10457 } 10458 10459 /* Open the gates for HDD to receive Wext commands */ 10460 adapter->is_link_up_service_needed = false; 10461 10462 if ((adapter->device_mode == QDF_NAN_DISC_MODE || 10463 (adapter->device_mode == QDF_STA_MODE && 10464 !ucfg_nan_is_vdev_creation_allowed( 10465 hdd_ctx->psoc))) && 10466 cds_is_driver_recovering()) 10467 ucfg_nan_disable_ind_to_userspace( 10468 hdd_ctx->psoc); 10469 10470 hdd_register_tx_flow_control(adapter, 10471 hdd_tx_resume_timer_expired_handler, 10472 hdd_tx_resume_cb, 10473 hdd_tx_flow_control_is_pause); 10474 10475 hdd_register_hl_netdev_fc_timer( 10476 adapter, 10477 hdd_tx_resume_timer_expired_handler); 10478 10479 hdd_lpass_notify_start(adapter->deflink); 10480 break; 10481 10482 case QDF_SAP_MODE: 10483 ucfg_mlme_get_sap_internal_restart(hdd_ctx->psoc, 10484 &value); 10485 if (value) 10486 hdd_start_ap_adapter(adapter, rtnl_held); 10487 10488 break; 10489 10490 case QDF_P2P_GO_MODE: 10491 hdd_delete_sta(adapter); 10492 break; 10493 case QDF_MONITOR_MODE: 10494 if (wlan_hdd_is_session_type_monitor( 10495 adapter->device_mode) && 10496 ucfg_pkt_capture_get_mode(hdd_ctx->psoc) != 10497 PACKET_CAPTURE_MODE_DISABLE) { 10498 struct hdd_adapter *sta_adapter; 10499 10500 sta_adapter = hdd_get_adapter(hdd_ctx, 10501 QDF_STA_MODE); 10502 if (!sta_adapter) { 10503 hdd_err("No station interface found"); 10504 return -EINVAL; 10505 } 10506 10507 hdd_map_monitor_interface_vdev(sta_adapter); 10508 break; 10509 } 10510 hdd_start_station_adapter(adapter); 10511 hdd_set_mon_rx_cb(adapter->dev); 10512 10513 wlan_hdd_set_mon_chan( 10514 adapter, adapter->mon_chan_freq, 10515 adapter->mon_bandwidth); 10516 break; 10517 case QDF_NDI_MODE: 10518 hdd_ndi_start(adapter->dev->name, 0); 10519 break; 10520 default: 10521 break; 10522 } 10523 /* 10524 * Action frame registered in one adapter which will 10525 * applicable to all interfaces 10526 */ 10527 if (hdd_set_fw_params(adapter)) 10528 hdd_err("Failed to set adapter FW params after SSR!"); 10529 10530 wlan_hdd_cfg80211_register_frames(adapter); 10531 hdd_create_adapter_sysfs_files(adapter); 10532 hdd_adapter_dev_put_debug(adapter, dbgid); 10533 } 10534 10535 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 10536 dbgid) { 10537 if (!hdd_is_interface_up(adapter)) { 10538 hdd_adapter_dev_put_debug(adapter, dbgid); 10539 continue; 10540 } 10541 10542 if (adapter->device_mode == QDF_P2P_GO_MODE) 10543 hdd_stop_p2p_go(adapter); 10544 10545 hdd_adapter_dev_put_debug(adapter, dbgid); 10546 } 10547 10548 hdd_exit(); 10549 10550 return QDF_STATUS_SUCCESS; 10551 } 10552 10553 void hdd_adapter_dev_hold_debug(struct hdd_adapter *adapter, 10554 wlan_net_dev_ref_dbgid dbgid) 10555 { 10556 if (dbgid >= NET_DEV_HOLD_ID_MAX) { 10557 hdd_err("Invalid debug id: %d", dbgid); 10558 QDF_BUG(0); 10559 } 10560 dev_hold(adapter->dev); 10561 qdf_atomic_inc(&adapter->net_dev_hold_ref_count[dbgid]); 10562 } 10563 10564 void hdd_adapter_dev_put_debug(struct hdd_adapter *adapter, 10565 wlan_net_dev_ref_dbgid dbgid) 10566 { 10567 if (dbgid >= NET_DEV_HOLD_ID_MAX) { 10568 hdd_err("Invalid debug id: %d", dbgid); 10569 QDF_BUG(0); 10570 } 10571 10572 if (qdf_atomic_dec_return( 10573 &adapter->net_dev_hold_ref_count[dbgid]) < 0) { 10574 hdd_err("dev_put detected without dev_hold for debug id: %s", 10575 net_dev_ref_debug_string_from_id(dbgid)); 10576 QDF_BUG(0); 10577 } 10578 10579 if (adapter->dev) { 10580 dev_put(adapter->dev); 10581 } else { 10582 hdd_err("adapter->dev is NULL"); 10583 QDF_BUG(0); 10584 } 10585 } 10586 10587 QDF_STATUS hdd_get_front_adapter(struct hdd_context *hdd_ctx, 10588 struct hdd_adapter **out_adapter) 10589 { 10590 QDF_STATUS status; 10591 qdf_list_node_t *node; 10592 10593 *out_adapter = NULL; 10594 10595 qdf_spin_lock_bh(&hdd_ctx->hdd_adapter_lock); 10596 status = qdf_list_peek_front(&hdd_ctx->hdd_adapters, &node); 10597 qdf_spin_unlock_bh(&hdd_ctx->hdd_adapter_lock); 10598 10599 if (QDF_IS_STATUS_ERROR(status)) 10600 return status; 10601 10602 *out_adapter = qdf_container_of(node, struct hdd_adapter, node); 10603 10604 return QDF_STATUS_SUCCESS; 10605 } 10606 10607 QDF_STATUS hdd_get_next_adapter(struct hdd_context *hdd_ctx, 10608 struct hdd_adapter *current_adapter, 10609 struct hdd_adapter **out_adapter) 10610 { 10611 QDF_STATUS status; 10612 qdf_list_node_t *node; 10613 10614 *out_adapter = NULL; 10615 10616 qdf_spin_lock_bh(&hdd_ctx->hdd_adapter_lock); 10617 status = qdf_list_peek_next(&hdd_ctx->hdd_adapters, 10618 ¤t_adapter->node, 10619 &node); 10620 qdf_spin_unlock_bh(&hdd_ctx->hdd_adapter_lock); 10621 10622 if (QDF_IS_STATUS_ERROR(status)) 10623 return status; 10624 10625 *out_adapter = qdf_container_of(node, struct hdd_adapter, node); 10626 10627 return status; 10628 } 10629 10630 QDF_STATUS hdd_get_front_adapter_no_lock(struct hdd_context *hdd_ctx, 10631 struct hdd_adapter **out_adapter) 10632 { 10633 QDF_STATUS status; 10634 qdf_list_node_t *node; 10635 10636 *out_adapter = NULL; 10637 10638 status = qdf_list_peek_front(&hdd_ctx->hdd_adapters, &node); 10639 10640 if (QDF_IS_STATUS_ERROR(status)) 10641 return status; 10642 10643 *out_adapter = qdf_container_of(node, struct hdd_adapter, node); 10644 10645 return QDF_STATUS_SUCCESS; 10646 } 10647 10648 QDF_STATUS hdd_get_next_adapter_no_lock(struct hdd_context *hdd_ctx, 10649 struct hdd_adapter *current_adapter, 10650 struct hdd_adapter **out_adapter) 10651 { 10652 QDF_STATUS status; 10653 qdf_list_node_t *node; 10654 10655 if (!current_adapter) 10656 return QDF_STATUS_E_INVAL; 10657 10658 *out_adapter = NULL; 10659 10660 status = qdf_list_peek_next(&hdd_ctx->hdd_adapters, 10661 ¤t_adapter->node, 10662 &node); 10663 10664 if (QDF_IS_STATUS_ERROR(status)) 10665 return status; 10666 10667 *out_adapter = qdf_container_of(node, struct hdd_adapter, node); 10668 10669 return status; 10670 } 10671 10672 QDF_STATUS hdd_remove_adapter(struct hdd_context *hdd_ctx, 10673 struct hdd_adapter *adapter) 10674 { 10675 QDF_STATUS status; 10676 10677 qdf_spin_lock_bh(&hdd_ctx->hdd_adapter_lock); 10678 status = qdf_list_remove_node(&hdd_ctx->hdd_adapters, &adapter->node); 10679 qdf_spin_unlock_bh(&hdd_ctx->hdd_adapter_lock); 10680 10681 return status; 10682 } 10683 10684 QDF_STATUS hdd_remove_front_adapter(struct hdd_context *hdd_ctx, 10685 struct hdd_adapter **out_adapter) 10686 { 10687 QDF_STATUS status; 10688 qdf_list_node_t *node; 10689 10690 *out_adapter = NULL; 10691 10692 qdf_spin_lock_bh(&hdd_ctx->hdd_adapter_lock); 10693 status = qdf_list_remove_front(&hdd_ctx->hdd_adapters, &node); 10694 qdf_spin_unlock_bh(&hdd_ctx->hdd_adapter_lock); 10695 10696 if (QDF_IS_STATUS_ERROR(status)) 10697 return status; 10698 10699 *out_adapter = qdf_container_of(node, struct hdd_adapter, node); 10700 10701 return status; 10702 } 10703 10704 QDF_STATUS hdd_add_adapter_back(struct hdd_context *hdd_ctx, 10705 struct hdd_adapter *adapter) 10706 { 10707 QDF_STATUS status; 10708 10709 qdf_spin_lock_bh(&hdd_ctx->hdd_adapter_lock); 10710 status = qdf_list_insert_back(&hdd_ctx->hdd_adapters, &adapter->node); 10711 qdf_spin_unlock_bh(&hdd_ctx->hdd_adapter_lock); 10712 10713 return status; 10714 } 10715 10716 QDF_STATUS hdd_add_adapter_front(struct hdd_context *hdd_ctx, 10717 struct hdd_adapter *adapter) 10718 { 10719 QDF_STATUS status; 10720 10721 qdf_spin_lock_bh(&hdd_ctx->hdd_adapter_lock); 10722 status = qdf_list_insert_front(&hdd_ctx->hdd_adapters, &adapter->node); 10723 qdf_spin_unlock_bh(&hdd_ctx->hdd_adapter_lock); 10724 10725 return status; 10726 } 10727 10728 void hdd_validate_next_adapter(struct hdd_adapter **curr, 10729 struct hdd_adapter **next, 10730 wlan_net_dev_ref_dbgid dbg_id) 10731 { 10732 if (!*curr || !*next || *curr != *next) 10733 return; 10734 10735 hdd_err("Validation failed"); 10736 hdd_adapter_dev_put_debug(*curr, dbg_id); 10737 *curr = NULL; 10738 *next = NULL; 10739 } 10740 10741 QDF_STATUS hdd_adapter_iterate(hdd_adapter_iterate_cb cb, void *context) 10742 { 10743 struct hdd_context *hdd_ctx; 10744 struct hdd_adapter *cache[HDD_MAX_ADAPTERS]; 10745 struct hdd_adapter *adapter; 10746 uint32_t n_cache = 0; 10747 QDF_STATUS ret = QDF_STATUS_SUCCESS; 10748 QDF_STATUS status; 10749 int i; 10750 struct wlan_hdd_link_info *link_info; 10751 10752 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 10753 if (unlikely(!hdd_ctx)) 10754 return QDF_STATUS_E_FAILURE; 10755 10756 qdf_spin_lock_bh(&hdd_ctx->hdd_adapter_lock); 10757 for (hdd_get_front_adapter_no_lock(hdd_ctx, &adapter); adapter; 10758 hdd_get_next_adapter_no_lock(hdd_ctx, adapter, &adapter)) { 10759 cache[n_cache++] = adapter; 10760 } 10761 qdf_spin_unlock_bh(&hdd_ctx->hdd_adapter_lock); 10762 10763 for (i = 0; i < n_cache; i++) { 10764 adapter = hdd_adapter_get_by_reference(hdd_ctx, cache[i]); 10765 if (!adapter) { 10766 /* 10767 * detected remove while iterating 10768 * concurrency failure 10769 */ 10770 ret = QDF_STATUS_E_FAILURE; 10771 continue; 10772 } 10773 hdd_adapter_for_each_active_link_info(adapter, link_info) { 10774 status = cb(link_info, context); 10775 if (status != QDF_STATUS_SUCCESS) { 10776 hdd_adapter_put(adapter); 10777 return status; 10778 } 10779 } 10780 hdd_adapter_put(adapter); 10781 } 10782 10783 return ret; 10784 } 10785 10786 struct hdd_adapter *hdd_get_adapter_by_rand_macaddr( 10787 struct hdd_context *hdd_ctx, tSirMacAddr mac_addr) 10788 { 10789 struct hdd_adapter *adapter, *next_adapter = NULL; 10790 wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_GET_ADAPTER_BY_RAND_MACADDR; 10791 struct wlan_hdd_link_info *link_info; 10792 10793 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 10794 dbgid) { 10795 if (adapter->device_mode != QDF_STA_MODE && 10796 adapter->device_mode != QDF_P2P_CLIENT_MODE && 10797 adapter->device_mode != QDF_P2P_DEVICE_MODE) { 10798 hdd_adapter_dev_put_debug(adapter, dbgid); 10799 continue; 10800 } 10801 10802 hdd_adapter_for_each_active_link_info(adapter, link_info) { 10803 if (ucfg_p2p_check_random_mac(hdd_ctx->psoc, 10804 link_info->vdev_id, 10805 mac_addr)) { 10806 hdd_adapter_dev_put_debug(adapter, dbgid); 10807 if (next_adapter) 10808 hdd_adapter_dev_put_debug(next_adapter, 10809 dbgid); 10810 return adapter; 10811 } 10812 } 10813 hdd_adapter_dev_put_debug(adapter, dbgid); 10814 } 10815 10816 return NULL; 10817 } 10818 10819 #ifdef WLAN_HDD_MULTI_VDEV_SINGLE_NDEV 10820 struct hdd_adapter *hdd_get_adapter_by_macaddr(struct hdd_context *hdd_ctx, 10821 tSirMacAddr mac_addr) 10822 { 10823 struct hdd_adapter *adapter, *next_adapter = NULL; 10824 wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_GET_ADAPTER_BY_MACADDR; 10825 struct qdf_mac_addr zero_mac_addr = QDF_MAC_ADDR_ZERO_INIT; 10826 struct wlan_hdd_link_info *link_info; 10827 10828 if (!qdf_mem_cmp(mac_addr, zero_mac_addr.bytes, sizeof(tSirMacAddr))) 10829 return NULL; 10830 10831 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 10832 dbgid) { 10833 if (!qdf_mem_cmp(adapter->mac_addr.bytes, 10834 mac_addr, sizeof(tSirMacAddr))) { 10835 hdd_adapter_dev_put_debug(adapter, dbgid); 10836 if (next_adapter) 10837 hdd_adapter_dev_put_debug(next_adapter, 10838 dbgid); 10839 return adapter; 10840 } 10841 hdd_adapter_for_each_active_link_info(adapter, link_info) { 10842 if (!qdf_mem_cmp(link_info->link_addr.bytes, 10843 mac_addr, sizeof(tSirMacAddr))) { 10844 hdd_adapter_dev_put_debug(adapter, dbgid); 10845 if (next_adapter) 10846 hdd_adapter_dev_put_debug(next_adapter, 10847 dbgid); 10848 return adapter; 10849 } 10850 } 10851 hdd_adapter_dev_put_debug(adapter, dbgid); 10852 } 10853 10854 return NULL; 10855 } 10856 10857 struct wlan_hdd_link_info * 10858 hdd_get_link_info_by_link_addr(struct hdd_context *hdd_ctx, 10859 struct qdf_mac_addr *link_addr) 10860 { 10861 struct wlan_hdd_link_info *link_info; 10862 struct hdd_adapter *adapter, *next_adapter = NULL; 10863 wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_GET_ADAPTER_BY_MACADDR; 10864 10865 if (!link_addr || qdf_is_macaddr_zero(link_addr)) 10866 return NULL; 10867 10868 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 10869 dbgid) { 10870 hdd_adapter_for_each_link_info(adapter, link_info) { 10871 if (qdf_is_macaddr_equal(link_addr, 10872 &link_info->link_addr)) { 10873 hdd_adapter_dev_put_debug(adapter, dbgid); 10874 if (next_adapter) 10875 hdd_adapter_dev_put_debug(next_adapter, 10876 dbgid); 10877 return link_info; 10878 } 10879 } 10880 hdd_adapter_dev_put_debug(adapter, dbgid); 10881 } 10882 10883 return NULL; 10884 } 10885 #else 10886 struct hdd_adapter *hdd_get_adapter_by_macaddr(struct hdd_context *hdd_ctx, 10887 tSirMacAddr mac_addr) 10888 { 10889 struct hdd_adapter *adapter, *next_adapter = NULL; 10890 wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_GET_ADAPTER_BY_MACADDR; 10891 10892 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 10893 dbgid) { 10894 if (!qdf_mem_cmp(adapter->mac_addr.bytes, 10895 mac_addr, sizeof(tSirMacAddr))) { 10896 hdd_adapter_dev_put_debug(adapter, dbgid); 10897 if (next_adapter) 10898 hdd_adapter_dev_put_debug(next_adapter, 10899 dbgid); 10900 return adapter; 10901 } 10902 10903 if (hdd_adapter_is_sl_ml_adapter(adapter) && 10904 !qdf_mem_cmp(adapter->mld_addr.bytes, 10905 mac_addr, sizeof(tSirMacAddr))) { 10906 hdd_adapter_dev_put_debug(adapter, dbgid); 10907 if (next_adapter) 10908 hdd_adapter_dev_put_debug(next_adapter, dbgid); 10909 return adapter; 10910 } 10911 hdd_adapter_dev_put_debug(adapter, dbgid); 10912 } 10913 10914 return NULL; 10915 } 10916 10917 struct wlan_hdd_link_info * 10918 hdd_get_link_info_by_link_addr(struct hdd_context *hdd_ctx, 10919 struct qdf_mac_addr *link_addr) 10920 { 10921 return NULL; 10922 } 10923 #endif 10924 10925 struct wlan_hdd_link_info * 10926 hdd_get_link_info_by_vdev(struct hdd_context *hdd_ctx, uint32_t vdev_id) 10927 { 10928 struct hdd_adapter *adapter, *next_adapter = NULL; 10929 wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_GET_ADAPTER_BY_VDEV; 10930 struct wlan_hdd_link_info *link_info; 10931 10932 if (vdev_id == WLAN_INVALID_VDEV_ID) 10933 return NULL; 10934 10935 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 10936 dbgid) { 10937 hdd_adapter_for_each_active_link_info(adapter, link_info) { 10938 if (link_info->vdev_id == vdev_id) { 10939 hdd_adapter_dev_put_debug(adapter, dbgid); 10940 if (next_adapter) 10941 hdd_adapter_dev_put_debug(next_adapter, 10942 dbgid); 10943 return link_info; 10944 } 10945 } 10946 hdd_adapter_dev_put_debug(adapter, dbgid); 10947 } 10948 10949 return NULL; 10950 } 10951 10952 struct hdd_adapter *hdd_adapter_get_by_reference(struct hdd_context *hdd_ctx, 10953 struct hdd_adapter *reference) 10954 { 10955 struct hdd_adapter *adapter, *next_adapter = NULL; 10956 wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_ADAPTER_GET_BY_REFERENCE; 10957 10958 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 10959 dbgid) { 10960 if (adapter == reference) { 10961 dev_hold(adapter->dev); 10962 hdd_adapter_dev_put_debug(adapter, dbgid); 10963 if (next_adapter) 10964 hdd_adapter_dev_put_debug(next_adapter, 10965 dbgid); 10966 break; 10967 } 10968 hdd_adapter_dev_put_debug(adapter, dbgid); 10969 } 10970 10971 return adapter; 10972 } 10973 10974 void hdd_adapter_put(struct hdd_adapter *adapter) 10975 { 10976 dev_put(adapter->dev); 10977 } 10978 10979 struct hdd_adapter *hdd_get_adapter_by_iface_name(struct hdd_context *hdd_ctx, 10980 const char *iface_name) 10981 { 10982 struct hdd_adapter *adapter, *next_adapter = NULL; 10983 wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_GET_ADAPTER_BY_IFACE_NAME; 10984 10985 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 10986 dbgid) { 10987 if (!qdf_str_cmp(adapter->dev->name, iface_name)) { 10988 hdd_adapter_dev_put_debug(adapter, dbgid); 10989 if (next_adapter) 10990 hdd_adapter_dev_put_debug(next_adapter, 10991 dbgid); 10992 return adapter; 10993 } 10994 hdd_adapter_dev_put_debug(adapter, dbgid); 10995 } 10996 10997 return NULL; 10998 } 10999 11000 struct hdd_adapter *hdd_get_adapter_by_ifindex(struct hdd_context *hdd_ctx, 11001 uint32_t if_index) 11002 { 11003 struct hdd_adapter *adapter, *next_adapter = NULL; 11004 wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_GET_ADAPTER; 11005 11006 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 11007 dbgid) { 11008 if (adapter->dev->ifindex == if_index) { 11009 hdd_adapter_dev_put_debug(adapter, dbgid); 11010 if (next_adapter) 11011 hdd_adapter_dev_put_debug(next_adapter, 11012 dbgid); 11013 return adapter; 11014 } 11015 hdd_adapter_dev_put_debug(adapter, dbgid); 11016 } 11017 11018 return NULL; 11019 } 11020 11021 /** 11022 * hdd_get_adapter() - to get adapter matching the mode 11023 * @hdd_ctx: hdd context 11024 * @mode: adapter mode 11025 * 11026 * This routine will return the pointer to adapter matching 11027 * with the passed mode. 11028 * 11029 * Return: pointer to adapter or null 11030 */ 11031 struct hdd_adapter *hdd_get_adapter(struct hdd_context *hdd_ctx, 11032 enum QDF_OPMODE mode) 11033 { 11034 struct hdd_adapter *adapter, *next_adapter = NULL; 11035 wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_GET_ADAPTER; 11036 11037 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 11038 dbgid) { 11039 if (adapter->device_mode == mode) { 11040 hdd_adapter_dev_put_debug(adapter, dbgid); 11041 if (next_adapter) 11042 hdd_adapter_dev_put_debug(next_adapter, 11043 dbgid); 11044 return adapter; 11045 } 11046 hdd_adapter_dev_put_debug(adapter, dbgid); 11047 } 11048 11049 return NULL; 11050 } 11051 11052 enum QDF_OPMODE hdd_get_device_mode(uint32_t vdev_id) 11053 { 11054 struct hdd_context *hdd_ctx; 11055 struct wlan_hdd_link_info *link_info; 11056 11057 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 11058 if (!hdd_ctx) 11059 return QDF_MAX_NO_OF_MODE; 11060 11061 link_info = hdd_get_link_info_by_vdev(hdd_ctx, vdev_id); 11062 if (!link_info) { 11063 hdd_err("Invalid vdev"); 11064 return QDF_MAX_NO_OF_MODE; 11065 } 11066 11067 return link_info->adapter->device_mode; 11068 } 11069 11070 uint32_t hdd_get_operating_chan_freq(struct hdd_context *hdd_ctx, 11071 enum QDF_OPMODE mode) 11072 { 11073 struct hdd_adapter *adapter, *next_adapter = NULL; 11074 uint32_t oper_chan_freq = 0; 11075 wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_GET_OPERATING_CHAN_FREQ; 11076 11077 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 11078 dbgid) { 11079 if (mode == adapter->device_mode) { 11080 oper_chan_freq = 11081 hdd_get_link_info_home_channel(adapter->deflink); 11082 hdd_adapter_dev_put_debug(adapter, dbgid); 11083 if (next_adapter) 11084 hdd_adapter_dev_put_debug(next_adapter, 11085 dbgid); 11086 break; 11087 } 11088 hdd_adapter_dev_put_debug(adapter, dbgid); 11089 } 11090 11091 return oper_chan_freq; 11092 } 11093 11094 static inline QDF_STATUS hdd_unregister_wext_all_adapters( 11095 struct hdd_context *hdd_ctx, 11096 bool rtnl_held) 11097 { 11098 struct hdd_adapter *adapter, *next_adapter = NULL; 11099 wlan_net_dev_ref_dbgid dbgid = 11100 NET_DEV_HOLD_UNREGISTER_WEXT_ALL_ADAPTERS; 11101 11102 hdd_enter(); 11103 11104 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 11105 dbgid) { 11106 if (adapter->device_mode == QDF_STA_MODE || 11107 adapter->device_mode == QDF_P2P_CLIENT_MODE || 11108 adapter->device_mode == QDF_P2P_DEVICE_MODE || 11109 adapter->device_mode == QDF_SAP_MODE || 11110 adapter->device_mode == QDF_P2P_GO_MODE) { 11111 hdd_wext_unregister(adapter->dev, rtnl_held); 11112 } 11113 hdd_adapter_dev_put_debug(adapter, dbgid); 11114 } 11115 11116 hdd_exit(); 11117 11118 return QDF_STATUS_SUCCESS; 11119 } 11120 11121 QDF_STATUS hdd_abort_mac_scan_all_adapters(struct hdd_context *hdd_ctx) 11122 { 11123 struct hdd_adapter *adapter, *next_adapter = NULL; 11124 wlan_net_dev_ref_dbgid dbgid = 11125 NET_DEV_HOLD_ABORT_MAC_SCAN_ALL_ADAPTERS; 11126 struct wlan_hdd_link_info *link_info; 11127 11128 hdd_enter(); 11129 11130 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 11131 dbgid) { 11132 if (adapter->device_mode == QDF_STA_MODE || 11133 adapter->device_mode == QDF_P2P_CLIENT_MODE || 11134 adapter->device_mode == QDF_P2P_DEVICE_MODE || 11135 adapter->device_mode == QDF_SAP_MODE || 11136 adapter->device_mode == QDF_P2P_GO_MODE) { 11137 hdd_adapter_for_each_active_link_info(adapter, 11138 link_info) { 11139 wlan_abort_scan(hdd_ctx->pdev, INVAL_PDEV_ID, 11140 link_info->vdev_id, 11141 INVALID_SCAN_ID, true); 11142 } 11143 } 11144 hdd_adapter_dev_put_debug(adapter, dbgid); 11145 } 11146 11147 hdd_exit(); 11148 11149 return QDF_STATUS_SUCCESS; 11150 } 11151 11152 /** 11153 * hdd_abort_sched_scan_all_adapters() - stops scheduled (PNO) scans for all 11154 * adapters 11155 * @hdd_ctx: The HDD context containing the adapters to operate on 11156 * 11157 * return: QDF_STATUS_SUCCESS 11158 */ 11159 static QDF_STATUS hdd_abort_sched_scan_all_adapters(struct hdd_context *hdd_ctx) 11160 { 11161 struct hdd_adapter *adapter, *next_adapter = NULL; 11162 int err; 11163 wlan_net_dev_ref_dbgid dbgid = 11164 NET_DEV_HOLD_ABORT_SCHED_SCAN_ALL_ADAPTERS; 11165 11166 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 11167 dbgid) { 11168 if (adapter->device_mode == QDF_STA_MODE || 11169 adapter->device_mode == QDF_P2P_CLIENT_MODE || 11170 adapter->device_mode == QDF_P2P_DEVICE_MODE || 11171 adapter->device_mode == QDF_SAP_MODE || 11172 adapter->device_mode == QDF_P2P_GO_MODE) { 11173 err = wlan_hdd_sched_scan_stop(adapter->dev); 11174 if (err) 11175 hdd_err("Unable to stop scheduled scan"); 11176 } 11177 hdd_adapter_dev_put_debug(adapter, dbgid); 11178 } 11179 11180 return QDF_STATUS_SUCCESS; 11181 } 11182 11183 /** 11184 * hdd_unregister_notifiers - Unregister netdev notifiers. 11185 * @hdd_ctx: HDD context 11186 * 11187 * Unregister netdev notifiers like IPv4 and IPv6. 11188 * 11189 * Return: None. 11190 */ 11191 void hdd_unregister_notifiers(struct hdd_context *hdd_ctx) 11192 { 11193 osif_dp_nud_unregister_netevent_notifier(hdd_ctx->psoc); 11194 hdd_wlan_unregister_ip6_notifier(hdd_ctx); 11195 11196 unregister_inetaddr_notifier(&hdd_ctx->ipv4_notifier); 11197 } 11198 11199 /** 11200 * hdd_exit_netlink_services - Exit netlink services 11201 * @hdd_ctx: HDD context 11202 * 11203 * Exit netlink services like cnss_diag, cesium netlink socket, ptt socket and 11204 * nl service. 11205 * 11206 * Return: None. 11207 */ 11208 static void hdd_exit_netlink_services(struct hdd_context *hdd_ctx) 11209 { 11210 spectral_scan_deactivate_service(); 11211 cnss_diag_deactivate_service(); 11212 hdd_close_cesium_nl_sock(); 11213 ptt_sock_deactivate_svc(); 11214 hdd_deactivate_wifi_pos(); 11215 11216 nl_srv_exit(); 11217 } 11218 11219 /** 11220 * hdd_init_netlink_services- Init netlink services 11221 * @hdd_ctx: HDD context 11222 * 11223 * Init netlink services like cnss_diag, cesium netlink socket, ptt socket and 11224 * nl service. 11225 * 11226 * Return: 0 on success and errno on failure. 11227 */ 11228 static int hdd_init_netlink_services(struct hdd_context *hdd_ctx) 11229 { 11230 int ret; 11231 11232 ret = wlan_hdd_nl_init(hdd_ctx); 11233 if (ret) { 11234 hdd_err("nl_srv_init failed: %d", ret); 11235 goto out; 11236 } 11237 cds_set_radio_index(hdd_ctx->radio_index); 11238 11239 ret = hdd_activate_wifi_pos(hdd_ctx); 11240 if (ret) { 11241 hdd_err("hdd_activate_wifi_pos failed: %d", ret); 11242 goto err_nl_srv; 11243 } 11244 11245 ptt_sock_activate_svc(); 11246 11247 ret = hdd_open_cesium_nl_sock(); 11248 if (ret) 11249 hdd_err("hdd_open_cesium_nl_sock failed ret: %d", ret); 11250 11251 ret = cnss_diag_activate_service(); 11252 if (ret) { 11253 hdd_err("cnss_diag_activate_service failed: %d", ret); 11254 goto err_close_cesium; 11255 } 11256 11257 spectral_scan_activate_service(hdd_ctx); 11258 11259 return 0; 11260 11261 err_close_cesium: 11262 hdd_close_cesium_nl_sock(); 11263 ptt_sock_deactivate_svc(); 11264 hdd_deactivate_wifi_pos(); 11265 err_nl_srv: 11266 nl_srv_exit(); 11267 out: 11268 return ret; 11269 } 11270 11271 #ifdef SHUTDOWN_WLAN_IN_SYSTEM_SUSPEND 11272 static QDF_STATUS 11273 hdd_shutdown_wlan_in_suspend_prepare(struct hdd_context *hdd_ctx) 11274 { 11275 #define SHUTDOWN_IN_SUSPEND_RETRY 30 11276 11277 int count = 0; 11278 enum pmo_suspend_mode mode; 11279 11280 if (hdd_ctx->driver_status != DRIVER_MODULES_ENABLED) { 11281 hdd_debug("Driver Modules not Enabled "); 11282 return 0; 11283 } 11284 11285 mode = ucfg_pmo_get_suspend_mode(hdd_ctx->psoc); 11286 hdd_debug("suspend mode is %d", mode); 11287 11288 if (mode == PMO_SUSPEND_NONE || mode == PMO_SUSPEND_LEGENCY) { 11289 hdd_debug("needn't shutdown in suspend"); 11290 return 0; 11291 } 11292 11293 if (!hdd_is_any_interface_open(hdd_ctx)) { 11294 return pld_idle_shutdown(hdd_ctx->parent_dev, 11295 hdd_psoc_idle_shutdown); 11296 } else { 11297 if (mode == PMO_SUSPEND_WOW) 11298 return 0; 11299 } 11300 11301 /*try to wait interface down for PMO_SUSPEND_SHUTDOWN mode*/ 11302 while (hdd_is_any_interface_open(hdd_ctx) && 11303 count < SHUTDOWN_IN_SUSPEND_RETRY) { 11304 count++; 11305 hdd_debug_rl("sleep 50ms to wait adapters stopped, #%d", count); 11306 msleep(50); 11307 } 11308 if (count >= SHUTDOWN_IN_SUSPEND_RETRY) { 11309 hdd_err("some adapters not stopped"); 11310 return -EBUSY; 11311 } 11312 return pld_idle_shutdown(hdd_ctx->parent_dev, hdd_psoc_idle_shutdown); 11313 } 11314 11315 static int hdd_pm_notify(struct notifier_block *b, 11316 unsigned long event, void *p) 11317 { 11318 struct hdd_context *hdd_ctx = container_of(b, struct hdd_context, 11319 pm_notifier); 11320 11321 if (wlan_hdd_validate_context(hdd_ctx) != 0) 11322 return NOTIFY_STOP; 11323 11324 hdd_debug("got PM event: %lu", event); 11325 11326 switch (event) { 11327 case PM_SUSPEND_PREPARE: 11328 case PM_HIBERNATION_PREPARE: 11329 if (0 != hdd_shutdown_wlan_in_suspend_prepare(hdd_ctx)) 11330 return NOTIFY_STOP; 11331 break; 11332 case PM_POST_SUSPEND: 11333 case PM_POST_HIBERNATION: 11334 break; 11335 } 11336 11337 return NOTIFY_DONE; 11338 } 11339 11340 static void hdd_pm_notifier_init(struct hdd_context *hdd_ctx) 11341 { 11342 hdd_ctx->pm_notifier.notifier_call = hdd_pm_notify; 11343 register_pm_notifier(&hdd_ctx->pm_notifier); 11344 } 11345 11346 static void hdd_pm_notifier_deinit(struct hdd_context *hdd_ctx) 11347 { 11348 unregister_pm_notifier(&hdd_ctx->pm_notifier); 11349 } 11350 #else 11351 static inline void hdd_pm_notifier_init(struct hdd_context *hdd_ctx) 11352 { 11353 } 11354 11355 static inline void hdd_pm_notifier_deinit(struct hdd_context *hdd_ctx) 11356 { 11357 } 11358 #endif 11359 11360 /** 11361 * hdd_context_deinit() - Deinitialize HDD context 11362 * @hdd_ctx: HDD context. 11363 * 11364 * Deinitialize HDD context along with all the feature specific contexts but 11365 * do not free hdd context itself. Caller of this API is supposed to free 11366 * HDD context. 11367 * 11368 * return: 0 on success and errno on failure. 11369 */ 11370 static int hdd_context_deinit(struct hdd_context *hdd_ctx) 11371 { 11372 hdd_lpc_delete_work(hdd_ctx); 11373 11374 qdf_wake_lock_destroy(&hdd_ctx->monitor_mode_wakelock); 11375 11376 wlan_hdd_cfg80211_deinit(hdd_ctx->wiphy); 11377 11378 ucfg_dp_bbm_context_deinit(hdd_ctx->psoc); 11379 11380 hdd_sap_context_destroy(hdd_ctx); 11381 11382 hdd_scan_context_destroy(hdd_ctx); 11383 11384 qdf_list_destroy(&hdd_ctx->hdd_adapters); 11385 11386 return 0; 11387 } 11388 11389 void hdd_context_destroy(struct hdd_context *hdd_ctx) 11390 { 11391 wlan_hdd_sar_timers_deinit(hdd_ctx); 11392 11393 cds_set_context(QDF_MODULE_ID_HDD, NULL); 11394 11395 hdd_exit_netlink_services(hdd_ctx); 11396 11397 hdd_context_deinit(hdd_ctx); 11398 11399 hdd_objmgr_release_and_destroy_psoc(hdd_ctx); 11400 11401 qdf_mem_free(hdd_ctx->config); 11402 hdd_ctx->config = NULL; 11403 cfg_release(); 11404 11405 hdd_pm_notifier_deinit(hdd_ctx); 11406 qdf_delayed_work_destroy(&hdd_ctx->psoc_idle_timeout_work); 11407 wiphy_free(hdd_ctx->wiphy); 11408 } 11409 11410 /** 11411 * wlan_destroy_bug_report_lock() - Destroy bug report lock 11412 * 11413 * This function is used to destroy bug report lock 11414 * 11415 * Return: None 11416 */ 11417 static void wlan_destroy_bug_report_lock(void) 11418 { 11419 struct cds_context *p_cds_context; 11420 11421 p_cds_context = cds_get_global_context(); 11422 if (!p_cds_context) { 11423 hdd_err("cds context is NULL"); 11424 return; 11425 } 11426 11427 qdf_spinlock_destroy(&p_cds_context->bug_report_lock); 11428 } 11429 11430 #ifdef DISABLE_CHANNEL_LIST 11431 static void wlan_hdd_cache_chann_mutex_destroy(struct hdd_context *hdd_ctx) 11432 { 11433 qdf_mutex_destroy(&hdd_ctx->cache_channel_lock); 11434 } 11435 #else 11436 static void wlan_hdd_cache_chann_mutex_destroy(struct hdd_context *hdd_ctx) 11437 { 11438 } 11439 #endif 11440 11441 void hdd_wlan_exit(struct hdd_context *hdd_ctx) 11442 { 11443 struct wiphy *wiphy = hdd_ctx->wiphy; 11444 11445 hdd_enter(); 11446 11447 ucfg_dp_wait_complete_tasks(); 11448 wlan_hdd_destroy_mib_stats_lock(); 11449 hdd_debugfs_ini_config_deinit(hdd_ctx); 11450 hdd_debugfs_mws_coex_info_deinit(hdd_ctx); 11451 hdd_psoc_idle_timer_stop(hdd_ctx); 11452 hdd_regulatory_deinit(hdd_ctx); 11453 11454 /* 11455 * Powersave Offload Case 11456 * Disable Idle Power Save Mode 11457 */ 11458 hdd_set_idle_ps_config(hdd_ctx, false); 11459 /* clear the scan queue in all the scenarios */ 11460 wlan_cfg80211_cleanup_scan_queue(hdd_ctx->pdev, NULL); 11461 11462 if (hdd_ctx->driver_status != DRIVER_MODULES_CLOSED) { 11463 hdd_unregister_wext_all_adapters(hdd_ctx, false); 11464 /* 11465 * Cancel any outstanding scan requests. We are about to close 11466 * all of our adapters, but an adapter structure is what SME 11467 * passes back to our callback function. Hence if there 11468 * are any outstanding scan requests then there is a 11469 * race condition between when the adapter is closed and 11470 * when the callback is invoked. We try to resolve that 11471 * race condition here by canceling any outstanding scans 11472 * before we close the adapters. 11473 * Note that the scans may be cancelled in an asynchronous 11474 * manner, so ideally there needs to be some kind of 11475 * synchronization. Rather than introduce a new 11476 * synchronization here, we will utilize the fact that we are 11477 * about to Request Full Power, and since that is synchronized, 11478 * the expectation is that by the time Request Full Power has 11479 * completed, all scans will be cancelled 11480 */ 11481 hdd_abort_mac_scan_all_adapters(hdd_ctx); 11482 hdd_abort_sched_scan_all_adapters(hdd_ctx); 11483 11484 hdd_stop_all_adapters(hdd_ctx); 11485 hdd_deinit_all_adapters(hdd_ctx, false); 11486 } 11487 11488 unregister_netdevice_notifier(&hdd_netdev_notifier); 11489 11490 qdf_dp_trace_deinit(); 11491 11492 hdd_wlan_stop_modules(hdd_ctx, false); 11493 11494 hdd_driver_memdump_deinit(); 11495 11496 qdf_nbuf_deinit_replenish_timer(); 11497 11498 if (QDF_GLOBAL_MONITOR_MODE == hdd_get_conparam()) { 11499 hdd_info("Release wakelock for monitor mode!"); 11500 qdf_wake_lock_release(&hdd_ctx->monitor_mode_wakelock, 11501 WIFI_POWER_EVENT_WAKELOCK_MONITOR_MODE); 11502 } 11503 11504 qdf_spinlock_destroy(&hdd_ctx->hdd_adapter_lock); 11505 qdf_spinlock_destroy(&hdd_ctx->connection_status_lock); 11506 wlan_hdd_cache_chann_mutex_destroy(hdd_ctx); 11507 11508 osif_request_manager_deinit(); 11509 11510 hdd_close_all_adapters(hdd_ctx, false); 11511 11512 wlansap_global_deinit(); 11513 /* 11514 * If there is re_init failure wiphy would have already de-registered 11515 * check the wiphy status before un-registering again 11516 */ 11517 if (wiphy && wiphy->registered) { 11518 wiphy_unregister(wiphy); 11519 wlan_hdd_cfg80211_deinit(wiphy); 11520 hdd_lpass_notify_stop(hdd_ctx); 11521 } 11522 11523 hdd_deinit_regulatory_update_event(hdd_ctx); 11524 hdd_exit_netlink_services(hdd_ctx); 11525 #ifdef FEATURE_WLAN_CH_AVOID 11526 mutex_destroy(&hdd_ctx->avoid_freq_lock); 11527 #endif 11528 11529 /* This function should be invoked at the end of this api*/ 11530 hdd_dump_func_call_map(); 11531 } 11532 11533 /** 11534 * hdd_wlan_notify_modem_power_state() - notify FW with modem power status 11535 * @state: state 11536 * 11537 * This function notifies FW with modem power status 11538 * 11539 * Return: 0 if successful, error number otherwise 11540 */ 11541 int hdd_wlan_notify_modem_power_state(int state) 11542 { 11543 int status; 11544 QDF_STATUS qdf_status; 11545 struct hdd_context *hdd_ctx; 11546 mac_handle_t mac_handle; 11547 11548 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 11549 status = wlan_hdd_validate_context(hdd_ctx); 11550 if (status) 11551 return status; 11552 11553 mac_handle = hdd_ctx->mac_handle; 11554 if (!mac_handle) 11555 return -EINVAL; 11556 11557 qdf_status = sme_notify_modem_power_state(mac_handle, state); 11558 if (QDF_STATUS_SUCCESS != qdf_status) { 11559 hdd_err("Fail to send notification with modem power state %d", 11560 state); 11561 return -EINVAL; 11562 } 11563 return 0; 11564 } 11565 11566 /** 11567 * hdd_post_cds_enable_config() - HDD post cds start config helper 11568 * @hdd_ctx: Pointer to the HDD 11569 * 11570 * Return: None 11571 */ 11572 QDF_STATUS hdd_post_cds_enable_config(struct hdd_context *hdd_ctx) 11573 { 11574 QDF_STATUS qdf_ret_status; 11575 11576 /* 11577 * Send ready indication to the HDD. This will kick off the MAC 11578 * into a 'running' state and should kick off an initial scan. 11579 */ 11580 qdf_ret_status = sme_hdd_ready_ind(hdd_ctx->mac_handle); 11581 if (!QDF_IS_STATUS_SUCCESS(qdf_ret_status)) { 11582 hdd_err("sme_hdd_ready_ind() failed with status code %08d [x%08x]", 11583 qdf_ret_status, qdf_ret_status); 11584 return QDF_STATUS_E_FAILURE; 11585 } 11586 11587 return QDF_STATUS_SUCCESS; 11588 } 11589 11590 struct hdd_adapter *hdd_get_first_valid_adapter(struct hdd_context *hdd_ctx) 11591 { 11592 struct hdd_adapter *adapter, *next_adapter = NULL; 11593 wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_GET_FIRST_VALID_ADAPTER; 11594 11595 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 11596 dbgid) { 11597 if (adapter && adapter->magic == WLAN_HDD_ADAPTER_MAGIC) { 11598 hdd_adapter_dev_put_debug(adapter, dbgid); 11599 if (next_adapter) 11600 hdd_adapter_dev_put_debug(next_adapter, 11601 dbgid); 11602 return adapter; 11603 } 11604 hdd_adapter_dev_put_debug(adapter, dbgid); 11605 } 11606 11607 return NULL; 11608 } 11609 11610 /* wake lock APIs for HDD */ 11611 void hdd_prevent_suspend(uint32_t reason) 11612 { 11613 qdf_wake_lock_acquire(&wlan_wake_lock, reason); 11614 } 11615 11616 void hdd_allow_suspend(uint32_t reason) 11617 { 11618 qdf_wake_lock_release(&wlan_wake_lock, reason); 11619 } 11620 11621 void hdd_prevent_suspend_timeout(uint32_t timeout, uint32_t reason) 11622 { 11623 cds_host_diag_log_work(&wlan_wake_lock, timeout, reason); 11624 qdf_wake_lock_timeout_acquire(&wlan_wake_lock, timeout); 11625 } 11626 11627 /* Initialize channel list in sme based on the country code */ 11628 QDF_STATUS hdd_set_sme_chan_list(struct hdd_context *hdd_ctx) 11629 { 11630 return sme_init_chan_list(hdd_ctx->mac_handle, 11631 hdd_ctx->reg.cc_src); 11632 } 11633 11634 /** 11635 * hdd_is_5g_supported() - check if hardware supports 5GHz 11636 * @hdd_ctx: Pointer to the hdd context 11637 * 11638 * HDD function to know if hardware supports 5GHz 11639 * 11640 * Return: true if hardware supports 5GHz 11641 */ 11642 bool hdd_is_5g_supported(struct hdd_context *hdd_ctx) 11643 { 11644 if (!hdd_ctx) 11645 return true; 11646 11647 if (hdd_ctx->curr_band != BAND_2G) 11648 return true; 11649 else 11650 return false; 11651 } 11652 11653 bool hdd_is_2g_supported(struct hdd_context *hdd_ctx) 11654 { 11655 if (!hdd_ctx) 11656 return false; 11657 11658 if (hdd_ctx->curr_band != BAND_5G) 11659 return true; 11660 else 11661 return false; 11662 } 11663 11664 static int hdd_wiphy_init(struct hdd_context *hdd_ctx) 11665 { 11666 struct wiphy *wiphy; 11667 int ret_val; 11668 uint32_t channel_bonding_mode; 11669 11670 wiphy = hdd_ctx->wiphy; 11671 11672 /* 11673 * The channel information in 11674 * wiphy needs to be initialized before wiphy registration 11675 */ 11676 ret_val = hdd_regulatory_init(hdd_ctx, wiphy); 11677 if (ret_val) { 11678 hdd_err("regulatory init failed"); 11679 return ret_val; 11680 } 11681 11682 if (ucfg_pmo_get_suspend_mode(hdd_ctx->psoc) == PMO_SUSPEND_WOW) { 11683 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0)) 11684 wiphy->wowlan = &wowlan_support_reg_init; 11685 #else 11686 wiphy->wowlan.flags = WIPHY_WOWLAN_ANY | 11687 WIPHY_WOWLAN_MAGIC_PKT | 11688 WIPHY_WOWLAN_DISCONNECT | 11689 WIPHY_WOWLAN_SUPPORTS_GTK_REKEY | 11690 WIPHY_WOWLAN_GTK_REKEY_FAILURE | 11691 WIPHY_WOWLAN_EAP_IDENTITY_REQ | 11692 WIPHY_WOWLAN_4WAY_HANDSHAKE | 11693 WIPHY_WOWLAN_RFKILL_RELEASE; 11694 11695 wiphy->wowlan.n_patterns = (WOW_MAX_FILTER_LISTS * 11696 WOW_MAX_FILTERS_PER_LIST); 11697 wiphy->wowlan.pattern_min_len = WOW_MIN_PATTERN_SIZE; 11698 wiphy->wowlan.pattern_max_len = WOW_MAX_PATTERN_SIZE; 11699 #endif 11700 } 11701 11702 ucfg_mlme_get_channel_bonding_24ghz(hdd_ctx->psoc, 11703 &channel_bonding_mode); 11704 if (hdd_ctx->obss_scan_offload) { 11705 hdd_debug("wmi_service_obss_scan supported"); 11706 } else if (channel_bonding_mode) { 11707 hdd_debug("enable wpa_supp obss_scan"); 11708 wiphy->features |= NL80211_FEATURE_NEED_OBSS_SCAN; 11709 } 11710 11711 if (hdd_ctx->num_rf_chains == HDD_ANTENNA_MODE_2X2 && 11712 ucfg_mlme_is_chain_mask_supported(hdd_ctx->psoc)) { 11713 wiphy->available_antennas_tx = HDD_CHAIN_MODE_2X2; 11714 wiphy->available_antennas_rx = HDD_CHAIN_MODE_2X2; 11715 } 11716 /* registration of wiphy dev with cfg80211 */ 11717 ret_val = wlan_hdd_cfg80211_register(wiphy); 11718 if (0 > ret_val) { 11719 hdd_err("wiphy registration failed"); 11720 return ret_val; 11721 } 11722 11723 /* Check the kernel version for upstream commit aced43ce780dc5 that 11724 * has support for processing user cell_base hints when wiphy is 11725 * self managed or check the backport flag for the same. 11726 */ 11727 #if defined CFG80211_USER_HINT_CELL_BASE_SELF_MANAGED || \ 11728 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 18, 0)) 11729 hdd_send_wiphy_regd_sync_event(hdd_ctx); 11730 #endif 11731 11732 pld_increment_driver_load_cnt(hdd_ctx->parent_dev); 11733 11734 return ret_val; 11735 } 11736 11737 #ifdef WLAN_FEATURE_DP_BUS_BANDWIDTH 11738 #ifdef CLD_PM_QOS 11739 #define PLD_REMOVE_PM_QOS(x) 11740 #define PLD_REQUEST_PM_QOS(x, y) 11741 #define HDD_PM_QOS_HIGH_TPUT_LATENCY_US 1 11742 11743 /** 11744 * hdd_pm_qos_update_cpu_mask() - Prepare CPU mask for PM_qos voting 11745 * @mask: return variable of cpumask for the TPUT 11746 * @enable_perf_cluster: Enable PERF cluster or not 11747 * 11748 * By default, the function sets CPU mask for silver cluster unless 11749 * enable_perf_cluster is set as true. 11750 * 11751 * Return: none 11752 */ 11753 static inline void hdd_pm_qos_update_cpu_mask(cpumask_t *mask, 11754 bool enable_perf_cluster) 11755 { 11756 cpumask_set_cpu(0, mask); 11757 cpumask_set_cpu(1, mask); 11758 cpumask_set_cpu(2, mask); 11759 cpumask_set_cpu(3, mask); 11760 11761 if (enable_perf_cluster) { 11762 cpumask_set_cpu(4, mask); 11763 cpumask_set_cpu(5, mask); 11764 cpumask_set_cpu(6, mask); 11765 } 11766 } 11767 11768 #ifdef MSM_PLATFORM 11769 #define COPY_CPU_MASK(a, b) cpumask_copy(a, b) 11770 #define DUMP_CPU_AFFINE() hdd_info("Set cpu_mask %*pb for affine_cores", \ 11771 cpumask_pr_args(&hdd_ctx->pm_qos_req.cpus_affine)) 11772 #else 11773 #define COPY_CPU_MASK(a, b) /* no-op*/ 11774 #define DUMP_CPU_AFFINE() /* no-op*/ 11775 #endif 11776 11777 #ifdef CLD_DEV_PM_QOS 11778 11779 static inline void _hdd_pm_qos_update_request(struct hdd_context *hdd_ctx, 11780 cpumask_t *pm_qos_cpu_mask, 11781 unsigned int latency) 11782 { 11783 int cpu; 11784 uint32_t default_latency; 11785 11786 default_latency = wlan_hdd_get_default_pm_qos_cpu_latency(); 11787 qdf_cpumask_copy(&hdd_ctx->qos_cpu_mask, pm_qos_cpu_mask); 11788 11789 if (qdf_cpumask_empty(pm_qos_cpu_mask)) { 11790 for_each_present_cpu(cpu) { 11791 dev_pm_qos_update_request( 11792 &hdd_ctx->pm_qos_req[cpu], 11793 default_latency); 11794 } 11795 hdd_debug("Empty mask %*pb: Set latency %u", 11796 qdf_cpumask_pr_args(&hdd_ctx->qos_cpu_mask), 11797 default_latency); 11798 } else { /* Set latency to default for CPUs not included in mask */ 11799 qdf_for_each_cpu_not(cpu, &hdd_ctx->qos_cpu_mask) { 11800 dev_pm_qos_update_request( 11801 &hdd_ctx->pm_qos_req[cpu], 11802 default_latency); 11803 } 11804 /* Set latency for CPUs included in mask */ 11805 qdf_for_each_cpu(cpu, &hdd_ctx->qos_cpu_mask) { 11806 dev_pm_qos_update_request( 11807 &hdd_ctx->pm_qos_req[cpu], 11808 latency); 11809 } 11810 hdd_debug("For qos_cpu_mask %*pb set latency %u", 11811 qdf_cpumask_pr_args(&hdd_ctx->qos_cpu_mask), 11812 latency); 11813 } 11814 } 11815 11816 /** 11817 * hdd_pm_qos_update_request() - API to request for pm_qos 11818 * @hdd_ctx: handle to hdd context 11819 * @pm_qos_cpu_mask: cpu_mask to apply 11820 * 11821 * Return: none 11822 */ 11823 static void hdd_pm_qos_update_request(struct hdd_context *hdd_ctx, 11824 cpumask_t *pm_qos_cpu_mask) 11825 { 11826 unsigned int latency; 11827 11828 if (qdf_cpumask_empty(pm_qos_cpu_mask)) 11829 latency = wlan_hdd_get_default_pm_qos_cpu_latency(); 11830 else 11831 latency = HDD_PM_QOS_HIGH_TPUT_LATENCY_US; 11832 11833 _hdd_pm_qos_update_request(hdd_ctx, pm_qos_cpu_mask, latency); 11834 } 11835 11836 static inline void hdd_pm_qos_add_request(struct hdd_context *hdd_ctx) 11837 { 11838 struct device *cpu_dev; 11839 int cpu; 11840 uint32_t default_latency = wlan_hdd_get_default_pm_qos_cpu_latency(); 11841 11842 11843 qdf_cpumask_clear(&hdd_ctx->qos_cpu_mask); 11844 hdd_pm_qos_update_cpu_mask(&hdd_ctx->qos_cpu_mask, false); 11845 11846 for_each_present_cpu(cpu) { 11847 cpu_dev = get_cpu_device(cpu); 11848 dev_pm_qos_add_request(cpu_dev, &hdd_ctx->pm_qos_req[cpu], 11849 DEV_PM_QOS_RESUME_LATENCY, 11850 default_latency); 11851 hdd_debug("Set qos_cpu_mask %*pb for affine_cores", 11852 cpumask_pr_args(&hdd_ctx->qos_cpu_mask)); 11853 } 11854 } 11855 11856 static inline void hdd_pm_qos_remove_request(struct hdd_context *hdd_ctx) 11857 { 11858 int cpu; 11859 11860 for_each_present_cpu(cpu) { 11861 dev_pm_qos_remove_request(&hdd_ctx->pm_qos_req[cpu]); 11862 hdd_debug("Remove dev_pm_qos_request for all cpus: %d", cpu); 11863 } 11864 qdf_cpumask_clear(&hdd_ctx->qos_cpu_mask); 11865 } 11866 11867 #else /* CLD_DEV_PM_QOS */ 11868 11869 #if defined(CONFIG_SMP) && defined(MSM_PLATFORM) 11870 /** 11871 * hdd_set_default_pm_qos_mask() - Update PM_qos request for AFFINE_CORES 11872 * @hdd_ctx: handle to hdd context 11873 * 11874 * Return: none 11875 */ 11876 static inline void hdd_set_default_pm_qos_mask(struct hdd_context *hdd_ctx) 11877 { 11878 hdd_ctx->pm_qos_req.type = PM_QOS_REQ_AFFINE_CORES; 11879 qdf_cpumask_clear(&hdd_ctx->pm_qos_req.cpus_affine); 11880 hdd_pm_qos_update_cpu_mask(&hdd_ctx->pm_qos_req.cpus_affine, false); 11881 } 11882 #else 11883 static inline void hdd_set_default_pm_qos_mask(struct hdd_context *hdd_ctx) 11884 { 11885 } 11886 #endif 11887 11888 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 7, 0)) 11889 /** 11890 * hdd_pm_qos_update_request() - API to request for pm_qos 11891 * @hdd_ctx: handle to hdd context 11892 * @pm_qos_cpu_mask: cpu_mask to apply 11893 * 11894 * Return: none 11895 */ 11896 static inline void hdd_pm_qos_update_request(struct hdd_context *hdd_ctx, 11897 cpumask_t *pm_qos_cpu_mask) 11898 { 11899 COPY_CPU_MASK(&hdd_ctx->pm_qos_req.cpus_affine, pm_qos_cpu_mask); 11900 11901 if (cpumask_empty(pm_qos_cpu_mask)) 11902 cpu_latency_qos_update_request(&hdd_ctx->pm_qos_req, 11903 PM_QOS_DEFAULT_VALUE); 11904 else 11905 cpu_latency_qos_update_request(&hdd_ctx->pm_qos_req, 1); 11906 } 11907 11908 static inline void hdd_pm_qos_add_request(struct hdd_context *hdd_ctx) 11909 { 11910 hdd_set_default_pm_qos_mask(hdd_ctx); 11911 cpu_latency_qos_add_request(&hdd_ctx->pm_qos_req, PM_QOS_DEFAULT_VALUE); 11912 DUMP_CPU_AFFINE(); 11913 } 11914 11915 static inline void hdd_pm_qos_remove_request(struct hdd_context *hdd_ctx) 11916 { 11917 cpu_latency_qos_remove_request(&hdd_ctx->pm_qos_req); 11918 } 11919 #else 11920 static inline void hdd_pm_qos_update_request(struct hdd_context *hdd_ctx, 11921 cpumask_t *pm_qos_cpu_mask) 11922 { 11923 COPY_CPU_MASK(&hdd_ctx->pm_qos_req.cpus_affine, pm_qos_cpu_mask); 11924 11925 if (cpumask_empty(pm_qos_cpu_mask)) 11926 pm_qos_update_request(&hdd_ctx->pm_qos_req, 11927 PM_QOS_DEFAULT_VALUE); 11928 else 11929 pm_qos_update_request(&hdd_ctx->pm_qos_req, 1); 11930 } 11931 11932 static inline void hdd_pm_qos_add_request(struct hdd_context *hdd_ctx) 11933 { 11934 hdd_set_default_pm_qos_mask(hdd_ctx); 11935 pm_qos_add_request(&hdd_ctx->pm_qos_req, PM_QOS_CPU_DMA_LATENCY, 11936 PM_QOS_DEFAULT_VALUE); 11937 DUMP_CPU_AFFINE(); 11938 } 11939 11940 static inline void hdd_pm_qos_remove_request(struct hdd_context *hdd_ctx) 11941 { 11942 pm_qos_remove_request(&hdd_ctx->pm_qos_req); 11943 } 11944 #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(5, 7, 0) */ 11945 #endif /* CLD_DEV_PM_QOS */ 11946 11947 #else /* CLD_PM_QOS */ 11948 #define PLD_REMOVE_PM_QOS(x) pld_remove_pm_qos(x) 11949 #define PLD_REQUEST_PM_QOS(x, y) pld_request_pm_qos(x, y) 11950 11951 static inline void hdd_pm_qos_add_request(struct hdd_context *hdd_ctx) 11952 { 11953 } 11954 11955 static inline void hdd_pm_qos_remove_request(struct hdd_context *hdd_ctx) 11956 { 11957 } 11958 11959 static inline void hdd_pm_qos_update_cpu_mask(cpumask_t *mask, 11960 bool high_throughput) 11961 { 11962 } 11963 11964 static inline void hdd_pm_qos_update_request(struct hdd_context *hdd_ctx, 11965 cpumask_t *pm_qos_cpu_mask) 11966 { 11967 } 11968 #endif /* CLD_PM_QOS */ 11969 11970 #if defined(CLD_PM_QOS) 11971 #if defined(CLD_DEV_PM_QOS) 11972 void wlan_hdd_set_pm_qos_request(struct hdd_context *hdd_ctx, 11973 bool pm_qos_request) 11974 { 11975 cpumask_t pm_qos_cpu_mask; 11976 11977 cpumask_clear(&pm_qos_cpu_mask); 11978 if (pm_qos_request) { 11979 hdd_ctx->pm_qos_request = true; 11980 if (!hdd_ctx->hbw_requested) { 11981 hdd_pm_qos_update_cpu_mask(&pm_qos_cpu_mask, true); 11982 hdd_pm_qos_update_request(hdd_ctx, &pm_qos_cpu_mask); 11983 hdd_ctx->hbw_requested = true; 11984 } 11985 } else { 11986 if (hdd_ctx->hbw_requested) { 11987 hdd_pm_qos_update_cpu_mask(&pm_qos_cpu_mask, false); 11988 hdd_pm_qos_update_request(hdd_ctx, &pm_qos_cpu_mask); 11989 hdd_ctx->hbw_requested = false; 11990 } 11991 hdd_ctx->pm_qos_request = false; 11992 } 11993 } 11994 #else /* CLD_DEV_PM_QOS */ 11995 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 7, 0)) 11996 void wlan_hdd_set_pm_qos_request(struct hdd_context *hdd_ctx, 11997 bool pm_qos_request) 11998 { 11999 if (pm_qos_request) { 12000 hdd_ctx->pm_qos_request = true; 12001 if (!hdd_ctx->hbw_requested) { 12002 cpumask_setall(&hdd_ctx->pm_qos_req.cpus_affine); 12003 cpu_latency_qos_update_request( 12004 &hdd_ctx->pm_qos_req, 12005 DISABLE_KRAIT_IDLE_PS_VAL); 12006 hdd_ctx->hbw_requested = true; 12007 } 12008 } else { 12009 if (hdd_ctx->hbw_requested) { 12010 cpumask_clear(&hdd_ctx->pm_qos_req.cpus_affine); 12011 cpu_latency_qos_update_request(&hdd_ctx->pm_qos_req, 12012 PM_QOS_DEFAULT_VALUE); 12013 hdd_ctx->hbw_requested = false; 12014 } 12015 hdd_ctx->pm_qos_request = false; 12016 } 12017 } 12018 #else /* (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 7, 0)) */ 12019 void wlan_hdd_set_pm_qos_request(struct hdd_context *hdd_ctx, 12020 bool pm_qos_request) 12021 { 12022 if (pm_qos_request) { 12023 hdd_ctx->pm_qos_request = true; 12024 if (!hdd_ctx->hbw_requested) { 12025 cpumask_setall(&hdd_ctx->pm_qos_req.cpus_affine); 12026 pm_qos_update_request(&hdd_ctx->pm_qos_req, 12027 DISABLE_KRAIT_IDLE_PS_VAL); 12028 hdd_ctx->hbw_requested = true; 12029 } 12030 } else { 12031 if (hdd_ctx->hbw_requested) { 12032 cpumask_clear(&hdd_ctx->pm_qos_req.cpus_affine); 12033 pm_qos_update_request(&hdd_ctx->pm_qos_req, 12034 PM_QOS_DEFAULT_VALUE); 12035 hdd_ctx->hbw_requested = false; 12036 } 12037 hdd_ctx->pm_qos_request = false; 12038 } 12039 } 12040 #endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 7, 0)) */ 12041 #endif /* CLD_DEV_PM_QOS*/ 12042 #endif /* CLD_PM_QOS */ 12043 12044 #define HDD_BW_GET_DIFF(_x, _y) (unsigned long)((ULONG_MAX - (_y)) + (_x) + 1) 12045 12046 #ifdef WLAN_FEATURE_MSCS 12047 12048 static 12049 void hdd_send_mscs_action_frame(struct wlan_hdd_link_info *link_info) 12050 { 12051 struct hdd_context *hdd_ctx = link_info->adapter->hdd_ctx; 12052 uint64_t mscs_vo_pkt_delta; 12053 unsigned long tx_vo_pkts = 0; 12054 unsigned int cpu; 12055 struct hdd_tx_rx_stats *stats = &link_info->hdd_stats.tx_rx_stats; 12056 uint32_t bus_bw_compute_interval; 12057 12058 /* 12059 * To disable MSCS feature in driver set mscs_pkt_threshold = 0 12060 * in ini file. 12061 */ 12062 if (!hdd_ctx->config->mscs_pkt_threshold) 12063 return; 12064 12065 for (cpu = 0; cpu < NUM_CPUS; cpu++) 12066 tx_vo_pkts += stats->per_cpu[cpu].tx_classified_ac[SME_AC_VO]; 12067 12068 if (!link_info->mscs_counter) 12069 link_info->mscs_prev_tx_vo_pkts = tx_vo_pkts; 12070 12071 link_info->mscs_counter++; 12072 bus_bw_compute_interval = 12073 ucfg_dp_get_bus_bw_compute_interval(hdd_ctx->psoc); 12074 if (link_info->mscs_counter * bus_bw_compute_interval >= 12075 hdd_ctx->config->mscs_voice_interval * 1000) { 12076 link_info->mscs_counter = 0; 12077 mscs_vo_pkt_delta = 12078 HDD_BW_GET_DIFF(tx_vo_pkts, 12079 link_info->mscs_prev_tx_vo_pkts); 12080 if (mscs_vo_pkt_delta > hdd_ctx->config->mscs_pkt_threshold && 12081 !mlme_get_is_mscs_req_sent(link_info->vdev)) 12082 sme_send_mscs_action_frame(link_info->vdev_id); 12083 } 12084 } 12085 #else 12086 static inline 12087 void hdd_send_mscs_action_frame(struct wlan_hdd_link_info *link_info) 12088 { 12089 } 12090 #endif 12091 #endif /*WLAN_FEATURE_DP_BUS_BANDWIDTH*/ 12092 12093 /** 12094 * wlan_hdd_sta_get_dot11mode() - GET AP client count 12095 * @context: HDD context 12096 * @netdev: netdev 12097 * @dot11_mode: variable in which mode need to update. 12098 * 12099 * Return: true on success else false 12100 */ 12101 static inline 12102 bool wlan_hdd_sta_get_dot11mode(hdd_cb_handle context, qdf_netdev_t netdev, 12103 enum qca_wlan_802_11_mode *dot11_mode) 12104 { 12105 struct hdd_context *hdd_ctx; 12106 struct wlan_hdd_link_info *link_info; 12107 struct hdd_station_ctx *sta_ctx; 12108 struct hdd_adapter *adapter; 12109 enum csr_cfgdot11mode mode; 12110 12111 hdd_ctx = hdd_cb_handle_to_context(context); 12112 if (!hdd_ctx) 12113 return false; 12114 12115 adapter = WLAN_HDD_GET_PRIV_PTR(netdev); 12116 if (!adapter) 12117 return false; 12118 12119 link_info = adapter->deflink; 12120 12121 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(link_info); 12122 mode = sta_ctx->conn_info.dot11mode; 12123 *dot11_mode = hdd_convert_cfgdot11mode_to_80211mode(mode); 12124 return true; 12125 } 12126 12127 /** 12128 * wlan_hdd_get_ap_client_count() - GET AP client count 12129 * @context: HDD context 12130 * @netdev: netdev 12131 * @client_count: variable in which number of client need to update. 12132 * 12133 * Return: true on success else false 12134 */ 12135 static inline 12136 bool wlan_hdd_get_ap_client_count(hdd_cb_handle context, qdf_netdev_t netdev, 12137 uint16_t *client_count) 12138 { 12139 struct hdd_context *hdd_ctx; 12140 struct wlan_hdd_link_info *link_info; 12141 struct hdd_adapter *adapter; 12142 struct hdd_ap_ctx *ap_ctx; 12143 enum qca_wlan_802_11_mode i; 12144 12145 hdd_ctx = hdd_cb_handle_to_context(context); 12146 if (!hdd_ctx) { 12147 hdd_err("hdd ctx is null"); 12148 return false; 12149 } 12150 12151 adapter = WLAN_HDD_GET_PRIV_PTR(netdev); 12152 if (!adapter) { 12153 hdd_err("adapter is null"); 12154 return false; 12155 } 12156 12157 link_info = adapter->deflink; 12158 ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(link_info); 12159 if (!ap_ctx->ap_active) 12160 return false; 12161 12162 for (i = QCA_WLAN_802_11_MODE_11B; i < QCA_WLAN_802_11_MODE_INVALID; 12163 i++) 12164 client_count[i] = ap_ctx->client_count[i]; 12165 12166 return true; 12167 } 12168 12169 /** 12170 * wlan_hdd_sta_ndi_connected() - Check if NDI connected 12171 * @context: HDD context 12172 * @netdev: netdev 12173 * 12174 * Return: true if NDI connected else false 12175 */ 12176 static inline 12177 bool wlan_hdd_sta_ndi_connected(hdd_cb_handle context, qdf_netdev_t netdev) 12178 { 12179 struct hdd_adapter *adapter; 12180 struct hdd_context *hdd_ctx; 12181 struct wlan_hdd_link_info *link_info; 12182 struct hdd_station_ctx *sta_ctx; 12183 12184 hdd_ctx = hdd_cb_handle_to_context(context); 12185 if (!hdd_ctx) { 12186 hdd_err("hdd_ctx is null"); 12187 return false; 12188 } 12189 12190 adapter = WLAN_HDD_GET_PRIV_PTR(netdev); 12191 if (!adapter) { 12192 hdd_err("adapter is null"); 12193 return false; 12194 } 12195 12196 link_info = adapter->deflink; 12197 12198 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(link_info); 12199 if (sta_ctx->conn_info.conn_state != eConnectionState_NdiConnected) 12200 return false; 12201 12202 return true; 12203 } 12204 12205 /** 12206 * wlan_hdd_pktlog_enable_disable() - Enable/Disable packet logging 12207 * @context: HDD context 12208 * @enable_disable_flag: Flag to enable/disable 12209 * @user_triggered: triggered through iwpriv 12210 * @size: buffer size to be used for packetlog 12211 * 12212 * Return: 0 on success; error number otherwise 12213 */ 12214 static inline 12215 int wlan_hdd_pktlog_enable_disable(hdd_cb_handle context, 12216 bool enable_disable_flag, 12217 uint8_t user_triggered, int size) 12218 { 12219 struct hdd_context *hdd_ctx = hdd_cb_handle_to_context(context); 12220 12221 if (!hdd_ctx) { 12222 hdd_err("hdd_ctx is null"); 12223 return -EINVAL; 12224 } 12225 return hdd_pktlog_enable_disable(hdd_ctx, enable_disable_flag, 12226 user_triggered, size); 12227 } 12228 12229 /** 12230 * wlan_hdd_is_roaming_in_progress() - Check if roaming is in progress 12231 * @context: HDD context 12232 * 12233 * Return: true if roaming is in progress else false 12234 */ 12235 static inline bool wlan_hdd_is_roaming_in_progress(hdd_cb_handle context) 12236 { 12237 struct hdd_context *hdd_ctx = hdd_cb_handle_to_context(context); 12238 12239 if (!hdd_ctx) { 12240 hdd_err("hdd_ctx is null"); 12241 return false; 12242 } 12243 return hdd_is_roaming_in_progress(hdd_ctx); 12244 } 12245 12246 /** 12247 * hdd_is_ap_active() - Check if AP is active 12248 * @context: HDD context 12249 * @netdev: netdev 12250 * 12251 * Return: true if AP active else false 12252 */ 12253 static inline bool hdd_is_ap_active(hdd_cb_handle context, qdf_netdev_t netdev) 12254 { 12255 struct hdd_adapter *adapter; 12256 struct hdd_context *hdd_ctx; 12257 struct wlan_hdd_link_info *link_info; 12258 12259 hdd_ctx = hdd_cb_handle_to_context(context); 12260 if (!hdd_ctx) { 12261 hdd_err("hdd_ctx is null"); 12262 return false; 12263 } 12264 12265 adapter = WLAN_HDD_GET_PRIV_PTR(netdev); 12266 if (!adapter) { 12267 hdd_err("adapter is null"); 12268 return false; 12269 } 12270 12271 link_info = adapter->deflink; 12272 return WLAN_HDD_GET_AP_CTX_PTR(link_info)->ap_active; 12273 } 12274 12275 /** 12276 * wlan_hdd_napi_apply_throughput_policy() - Apply NAPI policy 12277 * @context: HDD context 12278 * @tx_packets: tx_packets 12279 * @rx_packets: rx_packets 12280 * 12281 * Return: 0 on success else error code 12282 */ 12283 static inline 12284 int wlan_hdd_napi_apply_throughput_policy(hdd_cb_handle context, 12285 uint64_t tx_packets, 12286 uint64_t rx_packets) 12287 { 12288 struct hdd_context *hdd_ctx = hdd_cb_handle_to_context(context); 12289 int rc = 0; 12290 12291 if (!hdd_ctx) { 12292 hdd_err("hdd_ctx is null"); 12293 return 0; 12294 } 12295 if (hdd_ctx->config->napi_cpu_affinity_mask) 12296 rc = hdd_napi_apply_throughput_policy(hdd_ctx, tx_packets, 12297 rx_packets); 12298 return rc; 12299 } 12300 12301 /** 12302 * hdd_is_link_adapter() - Check if adapter is link adapter 12303 * @context: HDD context 12304 * @vdev_id: Vdev ID 12305 * 12306 * Return: true if link adapter else false 12307 */ 12308 static inline bool hdd_is_link_adapter(hdd_cb_handle context, uint8_t vdev_id) 12309 { 12310 struct hdd_context *hdd_ctx; 12311 struct wlan_hdd_link_info *link_info; 12312 12313 hdd_ctx = hdd_cb_handle_to_context(context); 12314 if (!hdd_ctx) { 12315 hdd_err("hdd_ctx is null"); 12316 return false; 12317 } 12318 12319 link_info = hdd_get_link_info_by_vdev(hdd_ctx, vdev_id); 12320 if (!link_info) { 12321 hdd_err("Invalid vdev"); 12322 return false; 12323 } 12324 return hdd_adapter_is_link_adapter(link_info->adapter); 12325 } 12326 12327 /** 12328 * hdd_get_pause_map() - Get pause map value 12329 * @context: HDD context 12330 * @netdev: netdev 12331 * 12332 * Return: pause map value 12333 */ 12334 static inline 12335 uint32_t hdd_get_pause_map(hdd_cb_handle context, qdf_netdev_t netdev) 12336 { 12337 struct hdd_adapter *adapter; 12338 12339 adapter = WLAN_HDD_GET_PRIV_PTR(netdev); 12340 if (!adapter) { 12341 hdd_err("adapter is null"); 12342 return 0; 12343 } 12344 12345 return adapter->pause_map; 12346 } 12347 12348 /** 12349 * hdd_any_adapter_connected() - Check if any adapter connected. 12350 * @context: HDD context 12351 * 12352 * Return: True if connected else false. 12353 */ 12354 static inline bool hdd_any_adapter_connected(hdd_cb_handle context) 12355 { 12356 struct hdd_context *hdd_ctx = hdd_cb_handle_to_context(context); 12357 12358 if (!hdd_ctx) { 12359 hdd_err("hdd_ctx is null"); 12360 return false; 12361 } 12362 12363 return hdd_is_any_adapter_connected(hdd_ctx); 12364 } 12365 12366 #ifdef WLAN_FEATURE_DP_BUS_BANDWIDTH 12367 /** 12368 * hdd_pld_request_pm_qos() - Request PLD PM QoS request 12369 * @context: HDD context 12370 * 12371 * Return: None 12372 */ 12373 static inline void hdd_pld_request_pm_qos(hdd_cb_handle context) 12374 { 12375 struct hdd_context *hdd_ctx = hdd_cb_handle_to_context(context); 12376 12377 if (!hdd_ctx) { 12378 hdd_err("hdd_ctx is null"); 12379 return; 12380 } 12381 12382 if (!hdd_ctx->hbw_requested) { 12383 PLD_REQUEST_PM_QOS(hdd_ctx->parent_dev, 1); 12384 hdd_ctx->hbw_requested = true; 12385 } 12386 } 12387 12388 /** 12389 * hdd_pld_remove_pm_qos() - Remove PLD PM QoS request 12390 * @context: HDD context 12391 * 12392 * Return: None 12393 */ 12394 static inline void hdd_pld_remove_pm_qos(hdd_cb_handle context) 12395 { 12396 struct hdd_context *hdd_ctx = hdd_cb_handle_to_context(context); 12397 12398 if (!hdd_ctx) { 12399 hdd_err("hdd_ctx is null"); 12400 return; 12401 } 12402 12403 if (hdd_ctx->hbw_requested && 12404 !hdd_ctx->pm_qos_request) { 12405 PLD_REMOVE_PM_QOS(hdd_ctx->parent_dev); 12406 hdd_ctx->hbw_requested = false; 12407 } 12408 } 12409 12410 /** 12411 * wlan_hdd_pm_qos_update_request() - Update PM QoS request 12412 * @context: HDD context 12413 * @pm_qos_cpu_mask: CPU mask 12414 * 12415 * Return: None 12416 */ 12417 static inline void 12418 wlan_hdd_pm_qos_update_request(hdd_cb_handle context, 12419 cpumask_t *pm_qos_cpu_mask) 12420 { 12421 struct hdd_context *hdd_ctx = hdd_cb_handle_to_context(context); 12422 12423 if (!hdd_ctx) { 12424 hdd_err("hdd_ctx is null"); 12425 return; 12426 } 12427 12428 if (!hdd_ctx->pm_qos_request) 12429 hdd_pm_qos_update_request(hdd_ctx, pm_qos_cpu_mask); 12430 } 12431 12432 /** 12433 * wlan_hdd_pm_qos_add_request() - Add PM QoS request 12434 * @context: HDD context 12435 * 12436 * Return: None 12437 */ 12438 static inline void wlan_hdd_pm_qos_add_request(hdd_cb_handle context) 12439 { 12440 struct hdd_context *hdd_ctx = hdd_cb_handle_to_context(context); 12441 12442 if (!hdd_ctx) { 12443 hdd_err("hdd_ctx is null"); 12444 return; 12445 } 12446 12447 hdd_pm_qos_add_request(hdd_ctx); 12448 } 12449 12450 /** 12451 * wlan_hdd_pm_qos_remove_request() - remove PM QoS request 12452 * @context: HDD context 12453 * 12454 * Return: None 12455 */ 12456 static inline void wlan_hdd_pm_qos_remove_request(hdd_cb_handle context) 12457 { 12458 struct hdd_context *hdd_ctx = hdd_cb_handle_to_context(context); 12459 12460 if (!hdd_ctx) { 12461 hdd_err("hdd_ctx is null"); 12462 return; 12463 } 12464 12465 hdd_pm_qos_remove_request(hdd_ctx); 12466 } 12467 12468 /** 12469 * wlan_hdd_send_mscs_action_frame() - Send MSCS action frame 12470 * @context: HDD context 12471 * @netdev: netdev 12472 * 12473 * Return: None 12474 */ 12475 static inline void wlan_hdd_send_mscs_action_frame(hdd_cb_handle context, 12476 qdf_netdev_t netdev) 12477 { 12478 struct hdd_adapter *adapter; 12479 struct wlan_hdd_link_info *link_info; 12480 12481 adapter = WLAN_HDD_GET_PRIV_PTR(netdev); 12482 if (!adapter) { 12483 hdd_err("adapter is null"); 12484 return; 12485 } 12486 12487 link_info = adapter->deflink; 12488 hdd_send_mscs_action_frame(link_info); 12489 } 12490 12491 #else 12492 static inline void hdd_pld_remove_pm_qos(hdd_cb_handle context) 12493 { 12494 } 12495 12496 static inline void hdd_pld_request_pm_qos(hdd_cb_handle context) 12497 { 12498 } 12499 12500 static inline void 12501 wlan_hdd_pm_qos_update_request(hdd_cb_handle context, 12502 cpumask_t *pm_qos_cpu_mask) 12503 { 12504 } 12505 12506 static inline void wlan_hdd_pm_qos_add_request(hdd_cb_handle context) 12507 { 12508 } 12509 12510 static inline void wlan_hdd_pm_qos_remove_request(hdd_cb_handle context) 12511 { 12512 } 12513 12514 static inline void wlan_hdd_send_mscs_action_frame(hdd_cb_handle context, 12515 qdf_netdev_t netdev) 12516 { 12517 } 12518 #endif 12519 12520 #if defined(WLAN_FEATURE_ROAM_OFFLOAD) && \ 12521 defined(FEATURE_RX_LINKSPEED_ROAM_TRIGGER) 12522 void wlan_hdd_link_speed_update(struct wlan_objmgr_psoc *psoc, 12523 uint8_t vdev_id, 12524 bool is_link_speed_good) 12525 { 12526 ucfg_cm_roam_link_speed_update(psoc, vdev_id, is_link_speed_good); 12527 } 12528 #endif 12529 12530 /** 12531 * hdd_dp_register_callbacks() - Register DP callbacks with HDD 12532 * @hdd_ctx: HDD context 12533 * 12534 * Return: None 12535 */ 12536 static void hdd_dp_register_callbacks(struct hdd_context *hdd_ctx) 12537 { 12538 struct wlan_dp_psoc_callbacks cb_obj = {0}; 12539 12540 cb_obj.callback_ctx = (hdd_cb_handle)hdd_ctx; 12541 cb_obj.wlan_dp_sta_get_dot11mode = wlan_hdd_sta_get_dot11mode; 12542 cb_obj.wlan_dp_get_ap_client_count = wlan_hdd_get_ap_client_count; 12543 cb_obj.wlan_dp_sta_ndi_connected = wlan_hdd_sta_ndi_connected; 12544 cb_obj.dp_any_adapter_connected = hdd_any_adapter_connected; 12545 cb_obj.dp_send_svc_nlink_msg = wlan_hdd_send_svc_nlink_msg; 12546 cb_obj.dp_pld_remove_pm_qos = hdd_pld_remove_pm_qos; 12547 cb_obj.dp_pld_request_pm_qos = hdd_pld_request_pm_qos; 12548 cb_obj.dp_pktlog_enable_disable = wlan_hdd_pktlog_enable_disable; 12549 cb_obj.dp_pm_qos_update_request = wlan_hdd_pm_qos_update_request; 12550 cb_obj.dp_pm_qos_add_request = wlan_hdd_pm_qos_add_request; 12551 cb_obj.dp_pm_qos_remove_request = wlan_hdd_pm_qos_remove_request; 12552 cb_obj.dp_send_mscs_action_frame = wlan_hdd_send_mscs_action_frame; 12553 cb_obj.dp_is_roaming_in_progress = wlan_hdd_is_roaming_in_progress; 12554 cb_obj.wlan_dp_display_tx_multiq_stats = 12555 wlan_hdd_display_tx_multiq_stats; 12556 cb_obj.wlan_dp_display_netif_queue_history = 12557 wlan_hdd_display_netif_queue_history; 12558 cb_obj.dp_is_ap_active = hdd_is_ap_active; 12559 cb_obj.dp_napi_apply_throughput_policy = 12560 wlan_hdd_napi_apply_throughput_policy; 12561 cb_obj.dp_is_link_adapter = hdd_is_link_adapter; 12562 cb_obj.dp_nud_failure_work = hdd_nud_failure_work; 12563 cb_obj.dp_get_pause_map = hdd_get_pause_map; 12564 12565 cb_obj.dp_get_netdev_by_vdev_mac = 12566 hdd_get_netdev_by_vdev_mac; 12567 cb_obj.dp_get_tx_resource = hdd_get_tx_resource; 12568 cb_obj.dp_get_tx_flow_low_watermark = hdd_get_tx_flow_low_watermark; 12569 cb_obj.dp_get_tsf_time = hdd_get_tsf_time_cb; 12570 cb_obj.dp_tsf_timestamp_rx = hdd_tsf_timestamp_rx; 12571 cb_obj.dp_gro_rx_legacy_get_napi = hdd_legacy_gro_get_napi; 12572 cb_obj.link_monitoring_cb = wlan_hdd_link_speed_update; 12573 12574 os_if_dp_register_hdd_callbacks(hdd_ctx->psoc, &cb_obj); 12575 } 12576 12577 /** 12578 * __hdd_adapter_param_update_work() - Gist of the work to process 12579 * netdev feature update. 12580 * @adapter: pointer to adapter structure 12581 * 12582 * This function assumes that the adapter pointer is always valid. 12583 * So the caller should always validate adapter pointer before calling 12584 * this function 12585 * 12586 * Returns: None 12587 */ 12588 static inline void 12589 __hdd_adapter_param_update_work(struct hdd_adapter *adapter) 12590 { 12591 /** 12592 * This check is needed in case the work got scheduled after the 12593 * interface got disconnected. 12594 * Netdev features update is to be done only after the connection, 12595 * since the connection mode plays an important role in identifying 12596 * the features that are to be updated. 12597 * So in case of interface disconnect skip feature update. 12598 */ 12599 if (!hdd_cm_is_vdev_associated(adapter->deflink)) 12600 return; 12601 12602 hdd_netdev_update_features(adapter); 12603 } 12604 12605 /** 12606 * hdd_adapter_param_update_work() - work to process the netdev features 12607 * update. 12608 * @arg: private data passed to work 12609 * 12610 * Returns: None 12611 */ 12612 static void hdd_adapter_param_update_work(void *arg) 12613 { 12614 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 12615 struct hdd_adapter *adapter = arg; 12616 struct osif_vdev_sync *vdev_sync; 12617 int errno; 12618 12619 if (!hdd_ctx) 12620 return; 12621 12622 hdd_adapter_ops_record_event(hdd_ctx, 12623 WLAN_HDD_ADAPTER_OPS_WORK_SCHED, 12624 WLAN_INVALID_VDEV_ID); 12625 12626 if (hdd_validate_adapter(adapter)) 12627 return; 12628 12629 errno = osif_vdev_sync_op_start(adapter->dev, &vdev_sync); 12630 if (errno) 12631 return; 12632 12633 __hdd_adapter_param_update_work(adapter); 12634 12635 osif_vdev_sync_op_stop(vdev_sync); 12636 } 12637 12638 QDF_STATUS hdd_init_adapter_ops_wq(struct hdd_context *hdd_ctx) 12639 { 12640 hdd_enter(); 12641 12642 hdd_ctx->adapter_ops_wq = 12643 qdf_alloc_high_prior_ordered_workqueue("hdd_adapter_ops_wq"); 12644 if (!hdd_ctx->adapter_ops_wq) 12645 return QDF_STATUS_E_NOMEM; 12646 12647 hdd_exit(); 12648 12649 return QDF_STATUS_SUCCESS; 12650 } 12651 12652 void hdd_deinit_adapter_ops_wq(struct hdd_context *hdd_ctx) 12653 { 12654 hdd_enter(); 12655 12656 qdf_flush_workqueue(0, hdd_ctx->adapter_ops_wq); 12657 qdf_destroy_workqueue(0, hdd_ctx->adapter_ops_wq); 12658 12659 hdd_exit(); 12660 } 12661 12662 QDF_STATUS hdd_adapter_feature_update_work_init(struct hdd_adapter *adapter) 12663 { 12664 QDF_STATUS status; 12665 12666 hdd_enter(); 12667 12668 status = qdf_create_work(0, &adapter->netdev_features_update_work, 12669 hdd_adapter_param_update_work, adapter); 12670 adapter->netdev_features_update_work_status = HDD_WORK_INITIALIZED; 12671 12672 hdd_exit(); 12673 12674 return status; 12675 } 12676 12677 void hdd_adapter_feature_update_work_deinit(struct hdd_adapter *adapter) 12678 { 12679 hdd_enter(); 12680 12681 if (adapter->netdev_features_update_work_status != 12682 HDD_WORK_INITIALIZED) { 12683 hdd_debug("work not yet init"); 12684 return; 12685 } 12686 qdf_cancel_work(&adapter->netdev_features_update_work); 12687 qdf_flush_work(&adapter->netdev_features_update_work); 12688 adapter->netdev_features_update_work_status = HDD_WORK_UNINITIALIZED; 12689 12690 hdd_exit(); 12691 } 12692 12693 #define HDD_DUMP_STAT_HELP(STAT_ID) \ 12694 hdd_nofl_debug("%u -- %s", STAT_ID, (# STAT_ID)) 12695 /** 12696 * hdd_display_stats_help() - print statistics help 12697 * 12698 * Return: none 12699 */ 12700 static void hdd_display_stats_help(void) 12701 { 12702 hdd_nofl_debug("iwpriv wlan0 dumpStats [option] - dump statistics"); 12703 hdd_nofl_debug("iwpriv wlan0 clearStats [option] - clear statistics"); 12704 hdd_nofl_debug("options:"); 12705 HDD_DUMP_STAT_HELP(CDP_TXRX_PATH_STATS); 12706 HDD_DUMP_STAT_HELP(CDP_TXRX_HIST_STATS); 12707 HDD_DUMP_STAT_HELP(CDP_TXRX_TSO_STATS); 12708 HDD_DUMP_STAT_HELP(CDP_HDD_NETIF_OPER_HISTORY); 12709 HDD_DUMP_STAT_HELP(CDP_DUMP_TX_FLOW_POOL_INFO); 12710 HDD_DUMP_STAT_HELP(CDP_TXRX_DESC_STATS); 12711 HDD_DUMP_STAT_HELP(CDP_HIF_STATS); 12712 HDD_DUMP_STAT_HELP(CDP_NAPI_STATS); 12713 HDD_DUMP_STAT_HELP(CDP_DP_NAPI_STATS); 12714 HDD_DUMP_STAT_HELP(CDP_DP_RX_THREAD_STATS); 12715 } 12716 12717 int hdd_wlan_dump_stats(struct hdd_adapter *adapter, int stats_id) 12718 { 12719 int ret = 0; 12720 QDF_STATUS status; 12721 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); 12722 12723 hdd_debug("stats_id %d", stats_id); 12724 12725 switch (stats_id) { 12726 case CDP_TXRX_HIST_STATS: 12727 ucfg_wlan_dp_display_tx_rx_histogram(hdd_ctx->psoc); 12728 break; 12729 case CDP_HDD_NETIF_OPER_HISTORY: 12730 wlan_hdd_display_adapter_netif_queue_history(adapter); 12731 break; 12732 case CDP_HIF_STATS: 12733 hdd_display_hif_stats(); 12734 break; 12735 case CDP_NAPI_STATS: 12736 if (hdd_display_napi_stats()) { 12737 hdd_err("error displaying napi stats"); 12738 ret = -EFAULT; 12739 } 12740 break; 12741 case CDP_DP_RX_THREAD_STATS: 12742 ucfg_dp_txrx_ext_dump_stats(cds_get_context(QDF_MODULE_ID_SOC), 12743 CDP_DP_RX_THREAD_STATS); 12744 break; 12745 case CDP_DISCONNECT_STATS: 12746 sme_display_disconnect_stats(hdd_ctx->mac_handle, 12747 adapter->deflink->vdev_id); 12748 break; 12749 default: 12750 status = cdp_display_stats(cds_get_context(QDF_MODULE_ID_SOC), 12751 stats_id, 12752 QDF_STATS_VERBOSITY_LEVEL_HIGH); 12753 if (status == QDF_STATUS_E_INVAL) { 12754 hdd_display_stats_help(); 12755 ret = -EINVAL; 12756 } 12757 break; 12758 } 12759 return ret; 12760 } 12761 12762 int hdd_wlan_clear_stats(struct hdd_adapter *adapter, int stats_id) 12763 { 12764 QDF_STATUS status = QDF_STATUS_SUCCESS; 12765 12766 hdd_debug("stats_id %d", stats_id); 12767 12768 switch (stats_id) { 12769 case CDP_HDD_STATS: 12770 ucfg_dp_clear_net_dev_stats(adapter->dev); 12771 memset(&adapter->deflink->hdd_stats, 0, 12772 sizeof(adapter->deflink->hdd_stats)); 12773 break; 12774 case CDP_TXRX_HIST_STATS: 12775 ucfg_wlan_dp_clear_tx_rx_histogram(adapter->hdd_ctx->psoc); 12776 break; 12777 case CDP_HDD_NETIF_OPER_HISTORY: 12778 wlan_hdd_clear_netif_queue_history(adapter->hdd_ctx); 12779 break; 12780 case CDP_HIF_STATS: 12781 hdd_clear_hif_stats(); 12782 break; 12783 case CDP_NAPI_STATS: 12784 hdd_clear_napi_stats(); 12785 break; 12786 default: 12787 status = cdp_clear_stats(cds_get_context(QDF_MODULE_ID_SOC), 12788 OL_TXRX_PDEV_ID, 12789 stats_id); 12790 if (status != QDF_STATUS_SUCCESS) 12791 hdd_debug("Failed to dump stats for stats_id: %d", 12792 stats_id); 12793 break; 12794 } 12795 12796 return qdf_status_to_os_return(status); 12797 } 12798 12799 /* length of the netif queue log needed per adapter */ 12800 #define ADAP_NETIFQ_LOG_LEN ((20 * WLAN_REASON_TYPE_MAX) + 50) 12801 12802 /** 12803 * hdd_display_netif_queue_history_compact() - display compact netifq history 12804 * @hdd_ctx: hdd context 12805 * 12806 * Return: none 12807 */ 12808 static void 12809 hdd_display_netif_queue_history_compact(struct hdd_context *hdd_ctx) 12810 { 12811 int adapter_num = 0; 12812 int i; 12813 int bytes_written; 12814 u32 tbytes; 12815 qdf_time_t total, pause, unpause, curr_time, delta; 12816 char temp_str[20 * WLAN_REASON_TYPE_MAX]; 12817 char *comb_log_str; 12818 uint32_t comb_log_str_size; 12819 struct hdd_adapter *adapter = NULL, *next_adapter = NULL; 12820 wlan_net_dev_ref_dbgid dbgid = 12821 NET_DEV_HOLD_DISPLAY_NETIF_QUEUE_HISTORY_COMPACT; 12822 12823 comb_log_str_size = (ADAP_NETIFQ_LOG_LEN * WLAN_MAX_VDEVS) + 1; 12824 comb_log_str = qdf_mem_malloc(comb_log_str_size); 12825 if (!comb_log_str) 12826 return; 12827 12828 bytes_written = 0; 12829 12830 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 12831 dbgid) { 12832 curr_time = qdf_system_ticks(); 12833 total = curr_time - adapter->start_time; 12834 delta = curr_time - adapter->last_time; 12835 12836 if (adapter->pause_map) { 12837 pause = adapter->total_pause_time + delta; 12838 unpause = adapter->total_unpause_time; 12839 } else { 12840 unpause = adapter->total_unpause_time + delta; 12841 pause = adapter->total_pause_time; 12842 } 12843 12844 tbytes = 0; 12845 qdf_mem_zero(temp_str, sizeof(temp_str)); 12846 for (i = WLAN_CONTROL_PATH; i < WLAN_REASON_TYPE_MAX; i++) { 12847 if (adapter->queue_oper_stats[i].pause_count == 0) 12848 continue; 12849 tbytes += 12850 snprintf( 12851 &temp_str[tbytes], 12852 (tbytes >= sizeof(temp_str) ? 12853 0 : sizeof(temp_str) - tbytes), 12854 "%d(%d,%d) ", 12855 i, 12856 adapter->queue_oper_stats[i]. 12857 pause_count, 12858 adapter->queue_oper_stats[i]. 12859 unpause_count); 12860 } 12861 if (tbytes >= sizeof(temp_str)) 12862 hdd_warn("log truncated"); 12863 12864 bytes_written += snprintf(&comb_log_str[bytes_written], 12865 bytes_written >= comb_log_str_size ? 0 : 12866 comb_log_str_size - bytes_written, 12867 "[%d %d] (%d) %u/%ums %s|", 12868 adapter->deflink->vdev_id, adapter->device_mode, 12869 adapter->pause_map, 12870 qdf_system_ticks_to_msecs(pause), 12871 qdf_system_ticks_to_msecs(total), 12872 temp_str); 12873 12874 adapter_num++; 12875 /* dev_put has to be done here */ 12876 hdd_adapter_dev_put_debug(adapter, dbgid); 12877 } 12878 12879 /* using QDF_TRACE to avoid printing function name */ 12880 QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_INFO_LOW, 12881 "STATS |%s", comb_log_str); 12882 12883 if (bytes_written >= comb_log_str_size) 12884 hdd_warn("log string truncated"); 12885 12886 qdf_mem_free(comb_log_str); 12887 } 12888 12889 /* Max size of a single netdev tx queue state string. e.g. "1: 0x1" */ 12890 #define HDD_NETDEV_TX_Q_STATE_STRLEN 15 12891 /** 12892 * wlan_hdd_display_adapter_netif_queue_stats() - display adapter based 12893 * netif queue stats 12894 * @adapter: hdd adapter 12895 * 12896 * Return: none 12897 */ 12898 static void 12899 wlan_hdd_display_adapter_netif_queue_stats(struct hdd_adapter *adapter) 12900 { 12901 int i; 12902 qdf_time_t total, pause, unpause, curr_time, delta; 12903 struct hdd_netif_queue_history *q_hist_ptr; 12904 char q_status_buf[NUM_TX_QUEUES * HDD_NETDEV_TX_Q_STATE_STRLEN] = {0}; 12905 12906 hdd_nofl_debug("Netif queue operation statistics:"); 12907 hdd_nofl_debug("vdev_id %d device mode %d", 12908 adapter->deflink->vdev_id, adapter->device_mode); 12909 hdd_nofl_debug("Current pause_map %x", adapter->pause_map); 12910 curr_time = qdf_system_ticks(); 12911 total = curr_time - adapter->start_time; 12912 delta = curr_time - adapter->last_time; 12913 if (adapter->pause_map) { 12914 pause = adapter->total_pause_time + delta; 12915 unpause = adapter->total_unpause_time; 12916 } else { 12917 unpause = adapter->total_unpause_time + delta; 12918 pause = adapter->total_pause_time; 12919 } 12920 hdd_nofl_debug("Total: %ums Pause: %ums Unpause: %ums", 12921 qdf_system_ticks_to_msecs(total), 12922 qdf_system_ticks_to_msecs(pause), 12923 qdf_system_ticks_to_msecs(unpause)); 12924 hdd_nofl_debug("reason_type: pause_cnt: unpause_cnt: pause_time"); 12925 12926 for (i = WLAN_CONTROL_PATH; i < WLAN_REASON_TYPE_MAX; i++) { 12927 qdf_time_t pause_delta = 0; 12928 12929 if (adapter->pause_map & (1 << i)) 12930 pause_delta = delta; 12931 12932 /* using hdd_log to avoid printing function name */ 12933 hdd_nofl_debug("%s: %d: %d: %ums", 12934 hdd_reason_type_to_string(i), 12935 adapter->queue_oper_stats[i].pause_count, 12936 adapter->queue_oper_stats[i]. 12937 unpause_count, 12938 qdf_system_ticks_to_msecs( 12939 adapter->queue_oper_stats[i]. 12940 total_pause_time + pause_delta)); 12941 } 12942 12943 hdd_nofl_debug("Netif queue operation history: Total entries: %d current index %d(-1) time %u", 12944 WLAN_HDD_MAX_HISTORY_ENTRY, 12945 adapter->history_index, 12946 qdf_system_ticks_to_msecs(qdf_system_ticks())); 12947 12948 hdd_nofl_debug("%2s%20s%50s%30s%10s %s", 12949 "#", "time(ms)", "action_type", "reason_type", 12950 "pause_map", "netdev-queue-status"); 12951 12952 for (i = 0; i < WLAN_HDD_MAX_HISTORY_ENTRY; i++) { 12953 /* using hdd_log to avoid printing function name */ 12954 if (adapter->queue_oper_history[i].time == 0) 12955 continue; 12956 q_hist_ptr = &adapter->queue_oper_history[i]; 12957 wlan_hdd_dump_queue_history_state(q_hist_ptr, 12958 q_status_buf, 12959 sizeof(q_status_buf)); 12960 hdd_nofl_debug("%2d%20u%50s%30s%10x %s", 12961 i, qdf_system_ticks_to_msecs( 12962 adapter->queue_oper_history[i].time), 12963 hdd_action_type_to_string( 12964 adapter->queue_oper_history[i]. 12965 netif_action), 12966 hdd_reason_type_to_string( 12967 adapter->queue_oper_history[i]. 12968 netif_reason), 12969 adapter->queue_oper_history[i].pause_map, 12970 q_status_buf); 12971 } 12972 } 12973 12974 void 12975 wlan_hdd_display_adapter_netif_queue_history(struct hdd_adapter *adapter) 12976 { 12977 wlan_hdd_display_adapter_netif_queue_stats(adapter); 12978 } 12979 12980 /** 12981 * wlan_hdd_display_netif_queue_history() - display netif queue history 12982 * @context: hdd context 12983 * @verb_lvl: verbosity level 12984 * 12985 * Return: none 12986 */ 12987 void 12988 wlan_hdd_display_netif_queue_history(hdd_cb_handle context, 12989 enum qdf_stats_verbosity_level verb_lvl) 12990 { 12991 struct hdd_adapter *adapter = NULL, *next_adapter = NULL; 12992 struct hdd_context *hdd_ctx = hdd_cb_handle_to_context(context); 12993 wlan_net_dev_ref_dbgid dbgid = 12994 NET_DEV_HOLD_DISPLAY_NETIF_QUEUE_HISTORY; 12995 12996 if (!hdd_ctx) { 12997 hdd_err("hdd_ctx is null"); 12998 return; 12999 } 13000 13001 if (verb_lvl == QDF_STATS_VERBOSITY_LEVEL_LOW) { 13002 hdd_display_netif_queue_history_compact(hdd_ctx); 13003 return; 13004 } 13005 13006 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 13007 dbgid) { 13008 if (adapter->deflink->vdev_id == CDP_INVALID_VDEV_ID) { 13009 hdd_adapter_dev_put_debug(adapter, dbgid); 13010 continue; 13011 } 13012 wlan_hdd_display_adapter_netif_queue_stats(adapter); 13013 /* dev_put has to be done here */ 13014 hdd_adapter_dev_put_debug(adapter, dbgid); 13015 } 13016 } 13017 13018 /** 13019 * wlan_hdd_clear_netif_queue_history() - clear netif queue operation history 13020 * @hdd_ctx: hdd context 13021 * 13022 * Return: none 13023 */ 13024 void wlan_hdd_clear_netif_queue_history(struct hdd_context *hdd_ctx) 13025 { 13026 struct hdd_adapter *adapter = NULL, *next_adapter = NULL; 13027 wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_CLEAR_NETIF_QUEUE_HISTORY; 13028 13029 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 13030 dbgid) { 13031 qdf_mem_zero(adapter->queue_oper_stats, 13032 sizeof(adapter->queue_oper_stats)); 13033 qdf_mem_zero(adapter->queue_oper_history, 13034 sizeof(adapter->queue_oper_history)); 13035 adapter->history_index = 0; 13036 adapter->start_time = adapter->last_time = qdf_system_ticks(); 13037 adapter->total_pause_time = 0; 13038 adapter->total_unpause_time = 0; 13039 hdd_adapter_dev_put_debug(adapter, dbgid); 13040 } 13041 } 13042 13043 #ifdef WLAN_FEATURE_OFFLOAD_PACKETS 13044 /** 13045 * hdd_init_offloaded_packets_ctx() - Initialize offload packets context 13046 * @hdd_ctx: hdd global context 13047 * 13048 * Return: none 13049 */ 13050 static void hdd_init_offloaded_packets_ctx(struct hdd_context *hdd_ctx) 13051 { 13052 uint8_t i; 13053 13054 mutex_init(&hdd_ctx->op_ctx.op_lock); 13055 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++) { 13056 hdd_ctx->op_ctx.op_table[i].request_id = MAX_REQUEST_ID; 13057 hdd_ctx->op_ctx.op_table[i].pattern_id = i; 13058 } 13059 } 13060 #else 13061 static void hdd_init_offloaded_packets_ctx(struct hdd_context *hdd_ctx) 13062 { 13063 } 13064 #endif 13065 13066 #ifdef WLAN_FEATURE_WOW_PULSE 13067 /** 13068 * wlan_hdd_set_wow_pulse() - call SME to send wmi cmd of wow pulse 13069 * @hdd_ctx: struct hdd_context structure pointer 13070 * @enable: enable or disable this behaviour 13071 * 13072 * Return: int 13073 */ 13074 static int wlan_hdd_set_wow_pulse(struct hdd_context *hdd_ctx, bool enable) 13075 { 13076 struct wow_pulse_mode wow_pulse_set_info; 13077 QDF_STATUS status; 13078 13079 hdd_debug("wow pulse enable flag is %d", enable); 13080 13081 if (!ucfg_pmo_is_wow_pulse_enabled(hdd_ctx->psoc)) 13082 return 0; 13083 13084 /* prepare the request to send to SME */ 13085 if (enable == true) { 13086 wow_pulse_set_info.wow_pulse_enable = true; 13087 wow_pulse_set_info.wow_pulse_pin = 13088 ucfg_pmo_get_wow_pulse_pin(hdd_ctx->psoc); 13089 13090 wow_pulse_set_info.wow_pulse_interval_high = 13091 ucfg_pmo_get_wow_pulse_interval_high(hdd_ctx->psoc); 13092 13093 wow_pulse_set_info.wow_pulse_interval_low = 13094 ucfg_pmo_get_wow_pulse_interval_low(hdd_ctx->psoc); 13095 13096 wow_pulse_set_info.wow_pulse_repeat_count = 13097 ucfg_pmo_get_wow_pulse_repeat_count(hdd_ctx->psoc); 13098 13099 wow_pulse_set_info.wow_pulse_init_state = 13100 ucfg_pmo_get_wow_pulse_init_state(hdd_ctx->psoc); 13101 } else { 13102 wow_pulse_set_info.wow_pulse_enable = false; 13103 wow_pulse_set_info.wow_pulse_pin = 0; 13104 wow_pulse_set_info.wow_pulse_interval_low = 0; 13105 wow_pulse_set_info.wow_pulse_interval_high = 0; 13106 wow_pulse_set_info.wow_pulse_repeat_count = 0; 13107 wow_pulse_set_info.wow_pulse_init_state = 0; 13108 } 13109 hdd_debug("enable %d pin %d low %d high %d count %d init %d", 13110 wow_pulse_set_info.wow_pulse_enable, 13111 wow_pulse_set_info.wow_pulse_pin, 13112 wow_pulse_set_info.wow_pulse_interval_low, 13113 wow_pulse_set_info.wow_pulse_interval_high, 13114 wow_pulse_set_info.wow_pulse_repeat_count, 13115 wow_pulse_set_info.wow_pulse_init_state); 13116 13117 status = sme_set_wow_pulse(&wow_pulse_set_info); 13118 if (QDF_STATUS_E_FAILURE == status) { 13119 hdd_debug("sme_set_wow_pulse failure!"); 13120 return -EIO; 13121 } 13122 hdd_debug("sme_set_wow_pulse success!"); 13123 return 0; 13124 } 13125 #else 13126 static inline int wlan_hdd_set_wow_pulse(struct hdd_context *hdd_ctx, bool enable) 13127 { 13128 return 0; 13129 } 13130 #endif 13131 13132 #ifdef WLAN_FEATURE_FASTPATH 13133 13134 /** 13135 * hdd_enable_fastpath() - Enable fastpath if enabled in config INI 13136 * @hdd_ctx: hdd context 13137 * @context: lower layer context 13138 * 13139 * Return: none 13140 */ 13141 void hdd_enable_fastpath(struct hdd_context *hdd_ctx, 13142 void *context) 13143 { 13144 if (cfg_get(hdd_ctx->psoc, CFG_DP_ENABLE_FASTPATH)) 13145 hif_enable_fastpath(context); 13146 } 13147 #endif 13148 13149 #if defined(FEATURE_WLAN_CH_AVOID) 13150 /** 13151 * hdd_set_thermal_level_cb() - set thermal level callback function 13152 * @hdd_handle: opaque handle for the hdd context 13153 * @level: thermal level 13154 * 13155 * Change IPA data path to SW path when the thermal throttle level greater 13156 * than 0, and restore the original data path when throttle level is 0 13157 * 13158 * Return: none 13159 */ 13160 static void hdd_set_thermal_level_cb(hdd_handle_t hdd_handle, u_int8_t level) 13161 { 13162 struct hdd_context *hdd_ctx = hdd_handle_to_context(hdd_handle); 13163 13164 /* Change IPA to SW path when throttle level greater than 0 */ 13165 if (level > THROTTLE_LEVEL_0) 13166 ucfg_ipa_send_mcc_scc_msg(hdd_ctx->pdev, true); 13167 else 13168 /* restore original concurrency mode */ 13169 ucfg_ipa_send_mcc_scc_msg(hdd_ctx->pdev, hdd_ctx->mcc_mode); 13170 } 13171 #else 13172 /** 13173 * hdd_set_thermal_level_cb() - set thermal level callback function 13174 * @hdd_handle: opaque handle for the hdd context 13175 * @level: thermal level 13176 * 13177 * Change IPA data path to SW path when the thermal throttle level greater 13178 * than 0, and restore the original data path when throttle level is 0 13179 * 13180 * Return: none 13181 */ 13182 static void hdd_set_thermal_level_cb(hdd_handle_t hdd_handle, u_int8_t level) 13183 { 13184 } 13185 #endif 13186 13187 QDF_STATUS hdd_switch_sap_channel(struct wlan_hdd_link_info *link_info, 13188 uint8_t channel, bool forced) 13189 { 13190 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(link_info->adapter); 13191 mac_handle_t mac_handle; 13192 struct sap_config *sap_cfg; 13193 qdf_freq_t freq; 13194 13195 mac_handle = hdd_adapter_get_mac_handle(link_info->adapter); 13196 if (!mac_handle) { 13197 hdd_err("invalid MAC handle"); 13198 return QDF_STATUS_E_INVAL; 13199 } 13200 13201 freq = wlan_reg_legacy_chan_to_freq(hdd_ctx->pdev, channel); 13202 sap_cfg = &(WLAN_HDD_GET_AP_CTX_PTR(link_info)->sap_config); 13203 hdd_debug("chan:%d width:%d", channel, sap_cfg->ch_width_orig); 13204 13205 return policy_mgr_change_sap_channel_with_csa(hdd_ctx->psoc, 13206 link_info->vdev_id, freq, 13207 sap_cfg->ch_width_orig, 13208 forced); 13209 } 13210 13211 QDF_STATUS hdd_switch_sap_chan_freq(struct hdd_adapter *adapter, 13212 qdf_freq_t chan_freq, 13213 enum phy_ch_width ch_width, 13214 bool forced) 13215 { 13216 struct hdd_ap_ctx *hdd_ap_ctx; 13217 struct hdd_context *hdd_ctx; 13218 13219 if (hdd_validate_adapter(adapter)) 13220 return QDF_STATUS_E_INVAL; 13221 13222 hdd_ctx = WLAN_HDD_GET_CTX(adapter); 13223 13224 if(wlan_hdd_validate_context(hdd_ctx)) 13225 return QDF_STATUS_E_INVAL; 13226 13227 hdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(adapter->deflink); 13228 13229 hdd_debug("chan freq:%d width:%d org bw %d", 13230 chan_freq, ch_width, hdd_ap_ctx->sap_config.ch_width_orig); 13231 13232 return policy_mgr_change_sap_channel_with_csa(hdd_ctx->psoc, 13233 adapter->deflink->vdev_id, 13234 chan_freq, 13235 ch_width, 13236 forced); 13237 } 13238 13239 int hdd_update_acs_timer_reason(struct hdd_adapter *adapter, uint8_t reason) 13240 { 13241 struct hdd_external_acs_timer_context *timer_context; 13242 int status; 13243 QDF_STATUS qdf_status; 13244 qdf_mc_timer_t *vendor_acs_timer; 13245 13246 set_bit(VENDOR_ACS_RESPONSE_PENDING, &adapter->deflink->link_flags); 13247 13248 vendor_acs_timer = &adapter->deflink->session.ap.vendor_acs_timer; 13249 if (QDF_TIMER_STATE_RUNNING == 13250 qdf_mc_timer_get_current_state(vendor_acs_timer)) { 13251 qdf_mc_timer_stop(vendor_acs_timer); 13252 } 13253 timer_context = 13254 (struct hdd_external_acs_timer_context *)vendor_acs_timer->user_data; 13255 timer_context->reason = reason; 13256 qdf_status = 13257 qdf_mc_timer_start(vendor_acs_timer, WLAN_VENDOR_ACS_WAIT_TIME); 13258 if (qdf_status != QDF_STATUS_SUCCESS) { 13259 hdd_err("failed to start external acs timer"); 13260 return -ENOSPC; 13261 } 13262 /* Update config to application */ 13263 status = hdd_cfg80211_update_acs_config(adapter, reason); 13264 hdd_info("Updated ACS config to nl with reason %d", reason); 13265 13266 return status; 13267 } 13268 13269 #ifdef FEATURE_WLAN_CH_AVOID_EXT 13270 uint32_t wlan_hdd_get_restriction_mask(struct hdd_context *hdd_ctx) 13271 { 13272 return hdd_ctx->restriction_mask; 13273 } 13274 13275 void wlan_hdd_set_restriction_mask(struct hdd_context *hdd_ctx) 13276 { 13277 hdd_ctx->restriction_mask = 13278 hdd_ctx->coex_avoid_freq_list.restriction_mask; 13279 } 13280 #else 13281 uint32_t wlan_hdd_get_restriction_mask(struct hdd_context *hdd_ctx) 13282 { 13283 return -EINVAL; 13284 } 13285 13286 void wlan_hdd_set_restriction_mask(struct hdd_context *hdd_ctx) 13287 { 13288 } 13289 #endif 13290 13291 #if defined(FEATURE_WLAN_CH_AVOID) 13292 /** 13293 * hdd_store_sap_restart_channel() - store sap restart channel 13294 * @restart_chan: restart channel 13295 * @restart_chan_store: pointer to restart channel store 13296 * 13297 * The function will store new sap restart channel. 13298 * 13299 * Return - none 13300 */ 13301 static void 13302 hdd_store_sap_restart_channel(qdf_freq_t restart_chan, qdf_freq_t *restart_chan_store) 13303 { 13304 uint8_t i; 13305 13306 for (i = 0; i < SAP_MAX_NUM_SESSION; i++) { 13307 if (*(restart_chan_store + i) == restart_chan) 13308 return; 13309 13310 if (*(restart_chan_store + i)) 13311 continue; 13312 13313 *(restart_chan_store + i) = restart_chan; 13314 return; 13315 } 13316 } 13317 13318 /** 13319 * hdd_check_chn_bw_boundary_unsafe() - check channel range unsafe 13320 * @hdd_ctxt: hdd context pointer 13321 * @adapter: hdd adapter pointer 13322 * 13323 * hdd_check_chn_bw_boundary_unsafe check SAP channel range with certain 13324 * bandwidth whether cover all unsafe channel list. 13325 * 13326 * Return - bool 13327 */ 13328 static bool 13329 hdd_check_chn_bw_boundary_unsafe(struct hdd_context *hdd_ctxt, 13330 struct hdd_adapter *adapter) 13331 { 13332 uint32_t freq; 13333 uint32_t start_freq = 0; 13334 uint32_t end_freq = 0; 13335 uint32_t i; 13336 uint8_t ch_width; 13337 const struct bonded_channel_freq *bonded_chan_ptr_ptr = NULL; 13338 13339 freq = adapter->deflink->session.ap.operating_chan_freq; 13340 ch_width = adapter->deflink->session.ap.sap_config.acs_cfg.ch_width; 13341 13342 if (ch_width > CH_WIDTH_20MHZ) 13343 bonded_chan_ptr_ptr = 13344 wlan_reg_get_bonded_chan_entry(freq, ch_width, 0); 13345 13346 if (bonded_chan_ptr_ptr) { 13347 start_freq = bonded_chan_ptr_ptr->start_freq; 13348 end_freq = bonded_chan_ptr_ptr->end_freq; 13349 } 13350 13351 for (i = 0; i < hdd_ctxt->unsafe_channel_count; i++) { 13352 if ((freq == hdd_ctxt->unsafe_channel_list[i]) || 13353 (start_freq <= hdd_ctxt->unsafe_channel_list[i] && 13354 hdd_ctxt->unsafe_channel_list[i] <= end_freq)) { 13355 hdd_debug("op chn freq:%u is unsafe for chn list:%u", 13356 freq, hdd_ctxt->unsafe_channel_list[i]); 13357 return true; 13358 } 13359 } 13360 13361 return false; 13362 } 13363 13364 /** 13365 * hdd_unsafe_channel_restart_sap() - restart sap if sap is on unsafe channel 13366 * @hdd_ctx: hdd context pointer 13367 * 13368 * hdd_unsafe_channel_restart_sap check all unsafe channel list 13369 * and if ACS is enabled, driver will ask userspace to restart the 13370 * sap. User space on LTE coex indication restart driver. 13371 * 13372 * Return - none 13373 */ 13374 QDF_STATUS hdd_unsafe_channel_restart_sap(struct hdd_context *hdd_ctx) 13375 { 13376 struct hdd_adapter *adapter, *next_adapter = NULL; 13377 struct hdd_ap_ctx *ap_ctx; 13378 uint32_t i; 13379 bool found = false; 13380 qdf_freq_t restart_chan_store[SAP_MAX_NUM_SESSION] = {0}; 13381 uint8_t scc_on_lte_coex = 0; 13382 uint32_t restart_freq, ap_chan_freq; 13383 bool value; 13384 QDF_STATUS status; 13385 bool is_acs_support_for_dfs_ltecoex = cfg_default(CFG_USER_ACS_DFS_LTE); 13386 bool is_vendor_acs_support = 13387 cfg_default(CFG_USER_AUTO_CHANNEL_SELECTION); 13388 wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_UNSAFE_CHANNEL_RESTART_SAP; 13389 enum phy_ch_width ch_width; 13390 struct wlan_hdd_link_info *link_info; 13391 13392 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 13393 dbgid) { 13394 if (adapter->device_mode != QDF_SAP_MODE) { 13395 hdd_debug_rl("skip device mode:%d", 13396 adapter->device_mode); 13397 hdd_adapter_dev_put_debug(adapter, dbgid); 13398 continue; 13399 } 13400 13401 hdd_adapter_for_each_active_link_info(adapter, link_info) { 13402 ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(link_info); 13403 if (!ap_ctx->sap_config.acs_cfg.acs_mode) { 13404 hdd_debug_rl("skip acs:%d", 13405 ap_ctx->sap_config.acs_cfg.acs_mode); 13406 continue; 13407 } 13408 13409 ap_chan_freq = ap_ctx->operating_chan_freq; 13410 ch_width = ap_ctx->sap_config.ch_width_orig; 13411 found = false; 13412 status = 13413 ucfg_policy_mgr_get_sta_sap_scc_lte_coex_chnl(hdd_ctx->psoc, 13414 &scc_on_lte_coex); 13415 if (!QDF_IS_STATUS_SUCCESS(status)) 13416 hdd_err("can't get scc on lte coex chnl, use def"); 13417 /* 13418 * If STA+SAP is doing SCC & 13419 * g_sta_sap_scc_on_lte_coex_chan is set, 13420 * no need to move SAP. 13421 */ 13422 if ((policy_mgr_is_sta_sap_scc(hdd_ctx->psoc, 13423 ap_chan_freq) && 13424 scc_on_lte_coex) || 13425 policy_mgr_nan_sap_scc_on_unsafe_ch_chk(hdd_ctx->psoc, 13426 ap_chan_freq)) 13427 hdd_debug("SAP allowed in unsafe SCC channel"); 13428 else 13429 found = hdd_check_chn_bw_boundary_unsafe(hdd_ctx, 13430 adapter); 13431 if (!found) { 13432 hdd_store_sap_restart_channel(ap_chan_freq, 13433 restart_chan_store); 13434 hdd_debug("ch freq:%d is safe. no need to change channel", 13435 ap_chan_freq); 13436 continue; 13437 } 13438 13439 status = ucfg_mlme_get_acs_support_for_dfs_ltecoex( 13440 hdd_ctx->psoc, 13441 &is_acs_support_for_dfs_ltecoex); 13442 if (!QDF_IS_STATUS_SUCCESS(status)) 13443 hdd_err("get_acs_support_for_dfs_ltecoex failed,set def"); 13444 13445 status = ucfg_mlme_get_vendor_acs_support( 13446 hdd_ctx->psoc, 13447 &is_vendor_acs_support); 13448 if (!QDF_IS_STATUS_SUCCESS(status)) 13449 hdd_err("get_vendor_acs_support failed, set default"); 13450 13451 if (is_vendor_acs_support && 13452 is_acs_support_for_dfs_ltecoex) { 13453 hdd_update_acs_timer_reason(adapter, 13454 QCA_WLAN_VENDOR_ACS_SELECT_REASON_LTE_COEX); 13455 continue; 13456 } 13457 13458 restart_freq = 0; 13459 for (i = 0; i < SAP_MAX_NUM_SESSION; i++) { 13460 if (!restart_chan_store[i]) 13461 continue; 13462 13463 if (policy_mgr_is_force_scc(hdd_ctx->psoc) && 13464 WLAN_REG_IS_SAME_BAND_FREQS( 13465 restart_chan_store[i], 13466 ap_chan_freq)) { 13467 restart_freq = restart_chan_store[i]; 13468 break; 13469 } 13470 } 13471 if (!restart_freq) { 13472 restart_freq = 13473 wlansap_get_safe_channel_from_pcl_and_acs_range( 13474 WLAN_HDD_GET_SAP_CTX_PTR(link_info), 13475 &ch_width); 13476 } 13477 if (!restart_freq) { 13478 wlan_hdd_set_sap_csa_reason(hdd_ctx->psoc, 13479 link_info->vdev_id, 13480 CSA_REASON_UNSAFE_CHANNEL); 13481 hdd_err("Unable to find safe chan, Stop the SAP if restriction mask is set else set txpower"); 13482 hdd_stop_sap_set_tx_power(hdd_ctx->psoc, adapter); 13483 continue; 13484 } 13485 /* 13486 * SAP restart due to unsafe channel. While 13487 * restarting the SAP, make sure to clear 13488 * acs_channel, channel to reset to 13489 * 0. Otherwise these settings will override 13490 * the ACS while restart. 13491 */ 13492 hdd_ctx->acs_policy.acs_chan_freq = 13493 AUTO_CHANNEL_SELECT; 13494 ucfg_mlme_get_sap_internal_restart(hdd_ctx->psoc, 13495 &value); 13496 if (value) { 13497 wlan_hdd_set_sap_csa_reason(hdd_ctx->psoc, 13498 link_info->vdev_id, 13499 CSA_REASON_UNSAFE_CHANNEL); 13500 status = hdd_switch_sap_chan_freq(adapter, 13501 restart_freq, 13502 ch_width, 13503 true); 13504 if (QDF_IS_STATUS_SUCCESS(status)) { 13505 hdd_adapter_dev_put_debug(adapter, 13506 dbgid); 13507 if (next_adapter) 13508 hdd_adapter_dev_put_debug( 13509 next_adapter, 13510 dbgid); 13511 return QDF_STATUS_E_PENDING; 13512 } else { 13513 hdd_debug("CSA failed, check next SAP"); 13514 } 13515 } else { 13516 hdd_debug("sending coex indication"); 13517 wlan_hdd_send_svc_nlink_msg( 13518 hdd_ctx->radio_index, 13519 WLAN_SVC_LTE_COEX_IND, NULL, 0); 13520 hdd_adapter_dev_put_debug(adapter, dbgid); 13521 if (next_adapter) 13522 hdd_adapter_dev_put_debug(next_adapter, 13523 dbgid); 13524 return QDF_STATUS_SUCCESS; 13525 } 13526 } 13527 /* dev_put has to be done here */ 13528 hdd_adapter_dev_put_debug(adapter, dbgid); 13529 } 13530 13531 return QDF_STATUS_SUCCESS; 13532 } 13533 13534 /** 13535 * hdd_init_channel_avoidance() - Initialize channel avoidance 13536 * @hdd_ctx: HDD global context 13537 * 13538 * Initialize the channel avoidance logic by retrieving the unsafe 13539 * channel list from the platform driver and plumbing the data 13540 * down to the lower layers. Then subscribe to subsequent channel 13541 * avoidance events. 13542 * 13543 * Return: None 13544 */ 13545 static void hdd_init_channel_avoidance(struct hdd_context *hdd_ctx) 13546 { 13547 uint16_t unsafe_channel_count; 13548 int index; 13549 qdf_freq_t *unsafe_freq_list; 13550 13551 pld_get_wlan_unsafe_channel(hdd_ctx->parent_dev, 13552 hdd_ctx->unsafe_channel_list, 13553 &(hdd_ctx->unsafe_channel_count), 13554 sizeof(uint16_t) * NUM_CHANNELS); 13555 13556 hdd_debug("num of unsafe channels is %d", 13557 hdd_ctx->unsafe_channel_count); 13558 13559 unsafe_channel_count = QDF_MIN((uint16_t)hdd_ctx->unsafe_channel_count, 13560 (uint16_t)NUM_CHANNELS); 13561 13562 if (!unsafe_channel_count) 13563 return; 13564 13565 unsafe_freq_list = qdf_mem_malloc( 13566 unsafe_channel_count * sizeof(*unsafe_freq_list)); 13567 13568 if (!unsafe_freq_list) 13569 return; 13570 13571 for (index = 0; index < unsafe_channel_count; index++) { 13572 hdd_debug("channel frequency %d is not safe", 13573 hdd_ctx->unsafe_channel_list[index]); 13574 unsafe_freq_list[index] = 13575 (qdf_freq_t)hdd_ctx->unsafe_channel_list[index]; 13576 } 13577 13578 ucfg_policy_mgr_init_chan_avoidance( 13579 hdd_ctx->psoc, 13580 unsafe_freq_list, 13581 unsafe_channel_count); 13582 13583 qdf_mem_free(unsafe_freq_list); 13584 } 13585 13586 static void hdd_lte_coex_restart_sap(struct hdd_adapter *adapter, 13587 struct hdd_context *hdd_ctx) 13588 { 13589 uint8_t restart_chan; 13590 uint32_t restart_freq; 13591 13592 restart_freq = wlansap_get_safe_channel_from_pcl_and_acs_range( 13593 WLAN_HDD_GET_SAP_CTX_PTR(adapter->deflink), 13594 NULL); 13595 13596 restart_chan = wlan_reg_freq_to_chan(hdd_ctx->pdev, 13597 restart_freq); 13598 13599 if (!restart_chan) { 13600 hdd_alert("fail to restart SAP"); 13601 return; 13602 } 13603 13604 /* SAP restart due to unsafe channel. While restarting 13605 * the SAP, make sure to clear acs_channel, channel to 13606 * reset to 0. Otherwise these settings will override 13607 * the ACS while restart. 13608 */ 13609 hdd_ctx->acs_policy.acs_chan_freq = AUTO_CHANNEL_SELECT; 13610 13611 hdd_debug("sending coex indication"); 13612 13613 wlan_hdd_send_svc_nlink_msg(hdd_ctx->radio_index, 13614 WLAN_SVC_LTE_COEX_IND, NULL, 0); 13615 wlan_hdd_set_sap_csa_reason(hdd_ctx->psoc, adapter->deflink->vdev_id, 13616 CSA_REASON_LTE_COEX); 13617 hdd_switch_sap_channel(adapter->deflink, restart_chan, true); 13618 } 13619 13620 int hdd_clone_local_unsafe_chan(struct hdd_context *hdd_ctx, 13621 uint16_t **local_unsafe_list, uint16_t *local_unsafe_list_count) 13622 { 13623 uint32_t size; 13624 uint16_t *unsafe_list; 13625 uint16_t chan_count; 13626 13627 if (!hdd_ctx || !local_unsafe_list_count || !local_unsafe_list_count) 13628 return -EINVAL; 13629 13630 chan_count = QDF_MIN(hdd_ctx->unsafe_channel_count, 13631 NUM_CHANNELS); 13632 if (chan_count) { 13633 size = chan_count * sizeof(hdd_ctx->unsafe_channel_list[0]); 13634 unsafe_list = qdf_mem_malloc(size); 13635 if (!unsafe_list) 13636 return -ENOMEM; 13637 qdf_mem_copy(unsafe_list, hdd_ctx->unsafe_channel_list, size); 13638 } else { 13639 unsafe_list = NULL; 13640 } 13641 13642 *local_unsafe_list = unsafe_list; 13643 *local_unsafe_list_count = chan_count; 13644 13645 return 0; 13646 } 13647 13648 bool hdd_local_unsafe_channel_updated( 13649 struct hdd_context *hdd_ctx, uint16_t *local_unsafe_list, 13650 uint16_t local_unsafe_list_count, uint32_t restriction_mask) 13651 { 13652 int i, j; 13653 13654 if (local_unsafe_list_count != hdd_ctx->unsafe_channel_count) 13655 return true; 13656 if (local_unsafe_list_count == 0) 13657 return false; 13658 for (i = 0; i < local_unsafe_list_count; i++) { 13659 for (j = 0; j < local_unsafe_list_count; j++) 13660 if (local_unsafe_list[i] == 13661 hdd_ctx->unsafe_channel_list[j]) 13662 break; 13663 if (j >= local_unsafe_list_count) 13664 break; 13665 } 13666 13667 if (ucfg_mlme_get_coex_unsafe_chan_nb_user_prefer(hdd_ctx->psoc)) { 13668 /* Return false if current channel list is same as previous 13669 * and restriction mask is not altered 13670 */ 13671 if (i >= local_unsafe_list_count && 13672 (restriction_mask == 13673 wlan_hdd_get_restriction_mask(hdd_ctx))) { 13674 hdd_info("unsafe chan list same"); 13675 return false; 13676 } 13677 } else if (i >= local_unsafe_list_count) { 13678 hdd_info("unsafe chan list same"); 13679 return false; 13680 } 13681 13682 return true; 13683 } 13684 #else 13685 static void hdd_init_channel_avoidance(struct hdd_context *hdd_ctx) 13686 { 13687 } 13688 13689 static inline void hdd_lte_coex_restart_sap(struct hdd_adapter *adapter, 13690 struct hdd_context *hdd_ctx) 13691 { 13692 hdd_debug("Channel avoidance is not enabled; Abort SAP restart"); 13693 } 13694 #endif /* defined(FEATURE_WLAN_CH_AVOID) */ 13695 13696 struct wlan_hdd_link_info * 13697 wlan_hdd_get_link_info_from_objmgr(struct wlan_objmgr_vdev *vdev) 13698 { 13699 if (!vdev) { 13700 hdd_err("null vdev object"); 13701 return NULL; 13702 } 13703 13704 if (vdev->vdev_nif.osdev) 13705 return vdev->vdev_nif.osdev->legacy_osif_priv; 13706 13707 return NULL; 13708 } 13709 13710 /** 13711 * hdd_indicate_mgmt_frame() - Wrapper to indicate management frame to 13712 * user space 13713 * @frame_ind: Management frame data to be informed. 13714 * 13715 * This function is used to indicate management frame to 13716 * user space 13717 * 13718 * Return: None 13719 * 13720 */ 13721 void hdd_indicate_mgmt_frame(tSirSmeMgmtFrameInd *frame_ind) 13722 { 13723 struct hdd_context *hdd_ctx = NULL; 13724 struct hdd_adapter *adapter = NULL, *next_adapter = NULL; 13725 int i, num_adapters; 13726 uint8_t vdev_id[WLAN_MAX_VDEVS + WLAN_MAX_ML_VDEVS]; 13727 struct ieee80211_mgmt *mgmt = 13728 (struct ieee80211_mgmt *)frame_ind->frameBuf; 13729 struct wlan_objmgr_vdev *vdev; 13730 wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_INDICATE_MGMT_FRAME; 13731 struct wlan_hdd_link_info *link_info; 13732 13733 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 13734 if (wlan_hdd_validate_context(hdd_ctx)) 13735 return; 13736 13737 if (frame_ind->frame_len < ieee80211_hdrlen(mgmt->frame_control)) { 13738 hdd_err(" Invalid frame length"); 13739 return; 13740 } 13741 13742 if (SME_SESSION_ID_ANY == frame_ind->sessionId) { 13743 for (i = 0; i < WLAN_MAX_VDEVS; i++) { 13744 link_info = hdd_get_link_info_by_vdev(hdd_ctx, i); 13745 if (link_info) { 13746 adapter = link_info->adapter; 13747 break; 13748 } 13749 } 13750 } else if (SME_SESSION_ID_BROADCAST == frame_ind->sessionId) { 13751 num_adapters = 0; 13752 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, 13753 next_adapter, dbgid) { 13754 hdd_adapter_for_each_active_link_info(adapter, 13755 link_info) { 13756 vdev_id[num_adapters] = link_info->vdev_id; 13757 num_adapters++; 13758 } 13759 /* dev_put has to be done here */ 13760 hdd_adapter_dev_put_debug(adapter, dbgid); 13761 } 13762 13763 adapter = NULL; 13764 13765 for (i = 0; i < num_adapters; i++) { 13766 vdev = wlan_objmgr_get_vdev_by_id_from_psoc( 13767 hdd_ctx->psoc, 13768 vdev_id[i], 13769 WLAN_OSIF_ID); 13770 13771 if (!vdev) 13772 continue; 13773 13774 link_info = wlan_hdd_get_link_info_from_objmgr(vdev); 13775 if (!link_info) { 13776 wlan_objmgr_vdev_release_ref(vdev, 13777 WLAN_OSIF_ID); 13778 continue; 13779 } 13780 13781 hdd_indicate_mgmt_frame_to_user(link_info->adapter, 13782 frame_ind->frame_len, 13783 frame_ind->frameBuf, 13784 frame_ind->frameType, 13785 frame_ind->rx_freq, 13786 frame_ind->rxRssi, 13787 frame_ind->rx_flags); 13788 wlan_objmgr_vdev_release_ref(vdev, WLAN_OSIF_ID); 13789 } 13790 13791 adapter = NULL; 13792 } else { 13793 link_info = hdd_get_link_info_by_vdev(hdd_ctx, 13794 frame_ind->sessionId); 13795 13796 if (!link_info) { 13797 hdd_err("Invalid vdev"); 13798 return; 13799 } 13800 13801 adapter = link_info->adapter; 13802 } 13803 13804 if ((adapter) && 13805 (WLAN_HDD_ADAPTER_MAGIC == adapter->magic)) 13806 hdd_indicate_mgmt_frame_to_user(adapter, 13807 frame_ind->frame_len, 13808 frame_ind->frameBuf, 13809 frame_ind->frameType, 13810 frame_ind->rx_freq, 13811 frame_ind->rxRssi, 13812 frame_ind->rx_flags); 13813 } 13814 13815 void hdd_acs_response_timeout_handler(void *context) 13816 { 13817 struct hdd_external_acs_timer_context *timer_context = 13818 (struct hdd_external_acs_timer_context *)context; 13819 struct hdd_adapter *adapter; 13820 struct hdd_context *hdd_ctx; 13821 uint8_t reason; 13822 struct sap_context *sap_context; 13823 struct wlan_hdd_link_info *link_info; 13824 13825 hdd_enter(); 13826 if (!timer_context) { 13827 hdd_err("invalid timer context"); 13828 return; 13829 } 13830 adapter = timer_context->adapter; 13831 reason = timer_context->reason; 13832 13833 if (!adapter || adapter->magic != WLAN_HDD_ADAPTER_MAGIC) { 13834 hdd_err("invalid adapter or adapter has invalid magic"); 13835 return; 13836 } 13837 13838 hdd_ctx = WLAN_HDD_GET_CTX(adapter); 13839 if (wlan_hdd_validate_context(hdd_ctx)) 13840 return; 13841 13842 link_info = adapter->deflink; 13843 if (!test_bit(VENDOR_ACS_RESPONSE_PENDING, &link_info->link_flags)) 13844 return; 13845 13846 clear_bit(VENDOR_ACS_RESPONSE_PENDING, &link_info->link_flags); 13847 13848 hdd_err("ACS timeout happened for %s reason %d", 13849 adapter->dev->name, reason); 13850 13851 sap_context = WLAN_HDD_GET_SAP_CTX_PTR(link_info); 13852 switch (reason) { 13853 /* SAP init case */ 13854 case QCA_WLAN_VENDOR_ACS_SELECT_REASON_INIT: 13855 wlan_sap_set_vendor_acs(sap_context, false); 13856 wlan_hdd_cfg80211_start_acs(link_info); 13857 break; 13858 /* DFS detected on current channel */ 13859 case QCA_WLAN_VENDOR_ACS_SELECT_REASON_DFS: 13860 wlan_sap_update_next_channel(sap_context, 0, 0); 13861 sme_update_new_channel_event(hdd_ctx->mac_handle, 13862 link_info->vdev_id); 13863 break; 13864 /* LTE coex event on current channel */ 13865 case QCA_WLAN_VENDOR_ACS_SELECT_REASON_LTE_COEX: 13866 hdd_lte_coex_restart_sap(adapter, hdd_ctx); 13867 break; 13868 default: 13869 hdd_info("invalid reason for timer invoke"); 13870 } 13871 } 13872 13873 /** 13874 * hdd_override_ini_config - Override INI config 13875 * @hdd_ctx: HDD context 13876 * 13877 * Override INI config based on module parameter. 13878 * 13879 * Return: None 13880 */ 13881 static void hdd_override_ini_config(struct hdd_context *hdd_ctx) 13882 { 13883 QDF_STATUS status; 13884 13885 if (0 == enable_dfs_chan_scan || 1 == enable_dfs_chan_scan) { 13886 ucfg_scan_cfg_set_dfs_chan_scan_allowed(hdd_ctx->psoc, 13887 enable_dfs_chan_scan); 13888 hdd_debug("Module enable_dfs_chan_scan set to %d", 13889 enable_dfs_chan_scan); 13890 } 13891 if (0 == enable_11d || 1 == enable_11d) { 13892 status = ucfg_mlme_set_11d_enabled(hdd_ctx->psoc, enable_11d); 13893 if (!QDF_IS_STATUS_SUCCESS(status)) 13894 hdd_err("Failed to set 11d_enable flag"); 13895 } 13896 } 13897 13898 #ifdef ENABLE_MTRACE_LOG 13899 static void hdd_set_mtrace_for_each(struct hdd_context *hdd_ctx) 13900 { 13901 uint8_t module_id = 0; 13902 int qdf_print_idx = -1; 13903 13904 qdf_print_idx = qdf_get_pidx(); 13905 for (module_id = 0; module_id < QDF_MODULE_ID_MAX; module_id++) 13906 qdf_print_set_category_verbose( 13907 qdf_print_idx, 13908 module_id, QDF_TRACE_LEVEL_TRACE, 13909 hdd_ctx->config->enable_mtrace); 13910 } 13911 #else 13912 static void hdd_set_mtrace_for_each(struct hdd_context *hdd_ctx) 13913 { 13914 } 13915 13916 #endif 13917 13918 /** 13919 * hdd_log_level_to_bitmask() - user space log level to host log bitmask 13920 * @user_log_level: user space log level 13921 * 13922 * Convert log level from user space to host log level bitmask. 13923 * 13924 * Return: Bitmask of log levels to be enabled 13925 */ 13926 static uint32_t hdd_log_level_to_bitmask(enum host_log_level user_log_level) 13927 { 13928 QDF_TRACE_LEVEL host_trace_level; 13929 uint32_t bitmask; 13930 13931 switch (user_log_level) { 13932 case HOST_LOG_LEVEL_NONE: 13933 host_trace_level = QDF_TRACE_LEVEL_NONE; 13934 break; 13935 case HOST_LOG_LEVEL_FATAL: 13936 host_trace_level = QDF_TRACE_LEVEL_FATAL; 13937 break; 13938 case HOST_LOG_LEVEL_ERROR: 13939 host_trace_level = QDF_TRACE_LEVEL_ERROR; 13940 break; 13941 case HOST_LOG_LEVEL_WARN: 13942 host_trace_level = QDF_TRACE_LEVEL_WARN; 13943 break; 13944 case HOST_LOG_LEVEL_INFO: 13945 host_trace_level = QDF_TRACE_LEVEL_INFO_LOW; 13946 break; 13947 case HOST_LOG_LEVEL_DEBUG: 13948 host_trace_level = QDF_TRACE_LEVEL_DEBUG; 13949 break; 13950 case HOST_LOG_LEVEL_TRACE: 13951 host_trace_level = QDF_TRACE_LEVEL_TRACE; 13952 break; 13953 default: 13954 host_trace_level = QDF_TRACE_LEVEL_TRACE; 13955 break; 13956 } 13957 13958 bitmask = (1 << (host_trace_level + 1)) - 1; 13959 13960 return bitmask; 13961 } 13962 13963 /** 13964 * hdd_set_trace_level_for_each - Set trace level for each INI config 13965 * @hdd_ctx: HDD context 13966 * 13967 * Set trace level for each module based on INI config. 13968 * 13969 * Return: None 13970 */ 13971 static void hdd_set_trace_level_for_each(struct hdd_context *hdd_ctx) 13972 { 13973 uint8_t host_module_log[QDF_MODULE_ID_MAX * 2]; 13974 qdf_size_t host_module_log_num = 0; 13975 QDF_MODULE_ID module_id; 13976 uint32_t bitmask; 13977 uint32_t i; 13978 13979 qdf_uint8_array_parse(cfg_get(hdd_ctx->psoc, 13980 CFG_ENABLE_HOST_MODULE_LOG_LEVEL), 13981 host_module_log, 13982 QDF_MODULE_ID_MAX * 2, 13983 &host_module_log_num); 13984 13985 for (i = 0; i + 1 < host_module_log_num; i += 2) { 13986 module_id = host_module_log[i]; 13987 bitmask = hdd_log_level_to_bitmask(host_module_log[i + 1]); 13988 if (module_id < QDF_MODULE_ID_MAX && 13989 module_id >= QDF_MODULE_ID_MIN) 13990 hdd_qdf_trace_enable(module_id, bitmask); 13991 } 13992 13993 hdd_set_mtrace_for_each(hdd_ctx); 13994 } 13995 13996 /** 13997 * hdd_context_init() - Initialize HDD context 13998 * @hdd_ctx: HDD context. 13999 * 14000 * Initialize HDD context along with all the feature specific contexts. 14001 * 14002 * return: 0 on success and errno on failure. 14003 */ 14004 static int hdd_context_init(struct hdd_context *hdd_ctx) 14005 { 14006 int ret; 14007 14008 hdd_ctx->ioctl_scan_mode = eSIR_ACTIVE_SCAN; 14009 hdd_ctx->max_intf_count = WLAN_MAX_VDEVS; 14010 14011 init_completion(&hdd_ctx->mc_sus_event_var); 14012 init_completion(&hdd_ctx->ready_to_suspend); 14013 14014 qdf_spinlock_create(&hdd_ctx->connection_status_lock); 14015 qdf_spinlock_create(&hdd_ctx->hdd_adapter_lock); 14016 14017 qdf_list_create(&hdd_ctx->hdd_adapters, 0); 14018 14019 ret = hdd_scan_context_init(hdd_ctx); 14020 if (ret) 14021 goto list_destroy; 14022 14023 ret = hdd_sap_context_init(hdd_ctx); 14024 if (ret) 14025 goto scan_destroy; 14026 14027 ret = ucfg_dp_bbm_context_init(hdd_ctx->psoc); 14028 if (ret) 14029 goto sap_destroy; 14030 14031 wlan_hdd_cfg80211_extscan_init(hdd_ctx); 14032 14033 hdd_init_offloaded_packets_ctx(hdd_ctx); 14034 14035 ret = wlan_hdd_cfg80211_init(hdd_ctx->parent_dev, hdd_ctx->wiphy, 14036 hdd_ctx->config); 14037 if (ret) 14038 goto bbm_destroy; 14039 14040 qdf_wake_lock_create(&hdd_ctx->monitor_mode_wakelock, 14041 "monitor_mode_wakelock"); 14042 hdd_lp_create_work(hdd_ctx); 14043 14044 return 0; 14045 14046 bbm_destroy: 14047 ucfg_dp_bbm_context_deinit(hdd_ctx->psoc); 14048 14049 sap_destroy: 14050 hdd_sap_context_destroy(hdd_ctx); 14051 14052 scan_destroy: 14053 hdd_scan_context_destroy(hdd_ctx); 14054 list_destroy: 14055 qdf_list_destroy(&hdd_ctx->hdd_adapters); 14056 14057 return ret; 14058 } 14059 14060 #ifdef SHUTDOWN_WLAN_IN_SYSTEM_SUSPEND 14061 static void hdd_idle_timer_in_active(uint32_t timeout_ms) 14062 { 14063 /* do nothing because idle shutdown will be called in system 14064 * suspend prepare 14065 */ 14066 } 14067 #else 14068 /* ensure idle shutdown can be called/finished once timer started */ 14069 static void hdd_idle_timer_in_active(uint32_t timeout_ms) 14070 { 14071 uint32_t suspend_timeout_ms; 14072 enum wake_lock_reason reason = 14073 WIFI_POWER_EVENT_WAKELOCK_IFACE_CHANGE_TIMER; 14074 14075 suspend_timeout_ms = timeout_ms + HDD_PSOC_IDLE_SHUTDOWN_SUSPEND_DELAY; 14076 hdd_prevent_suspend_timeout(suspend_timeout_ms, reason); 14077 } 14078 #endif 14079 14080 void hdd_psoc_idle_timer_start(struct hdd_context *hdd_ctx) 14081 { 14082 uint32_t timeout_ms = hdd_ctx->config->iface_change_wait_time; 14083 14084 if (!timeout_ms) { 14085 hdd_info("psoc idle timer is disabled"); 14086 return; 14087 } 14088 14089 hdd_debug("Starting psoc idle timer"); 14090 14091 /* If PCIe gen speed change is requested, reduce idle shutdown 14092 * timeout to 100 ms 14093 */ 14094 if (hdd_ctx->current_pcie_gen_speed) { 14095 timeout_ms = HDD_PCIE_GEN_SPEED_CHANGE_TIMEOUT_MS; 14096 hdd_info("pcie gen speed change requested"); 14097 } 14098 14099 qdf_delayed_work_start(&hdd_ctx->psoc_idle_timeout_work, timeout_ms); 14100 hdd_idle_timer_in_active(timeout_ms); 14101 } 14102 14103 void hdd_psoc_idle_timer_stop(struct hdd_context *hdd_ctx) 14104 { 14105 qdf_delayed_work_stop_sync(&hdd_ctx->psoc_idle_timeout_work); 14106 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_IFACE_CHANGE_TIMER); 14107 hdd_debug("Stopped psoc idle timer"); 14108 } 14109 14110 14111 /** 14112 * __hdd_psoc_idle_shutdown() - perform an idle shutdown on the given psoc 14113 * @hdd_ctx: the hdd context which should be shutdown 14114 * 14115 * When no interfaces are "up" on a psoc, an idle shutdown timer is started. 14116 * If no interfaces are brought up before the timer expires, we do an 14117 * "idle shutdown," cutting power to the physical SoC to save power. This is 14118 * done completely transparently from the perspective of userspace. 14119 * 14120 * Return: None 14121 */ 14122 static int __hdd_psoc_idle_shutdown(struct hdd_context *hdd_ctx) 14123 { 14124 struct osif_psoc_sync *psoc_sync; 14125 int errno; 14126 14127 hdd_enter(); 14128 14129 hdd_reg_wait_for_country_change(hdd_ctx); 14130 14131 errno = osif_psoc_sync_trans_start(hdd_ctx->parent_dev, &psoc_sync); 14132 if (errno) { 14133 hdd_info("psoc busy, abort idle shutdown; errno:%d", errno); 14134 errno = -EAGAIN; 14135 goto exit; 14136 } 14137 14138 osif_psoc_sync_wait_for_ops(psoc_sync); 14139 /* 14140 * This is to handle scenario in which platform driver triggers 14141 * idle_shutdown if Deep Sleep/Hibernate entry notification is 14142 * received from modem subsystem in wearable devices 14143 */ 14144 if (hdd_is_any_interface_open(hdd_ctx)) { 14145 hdd_err_rl("all interfaces are not down, ignore idle shutdown"); 14146 errno = -EAGAIN; 14147 } else { 14148 errno = hdd_wlan_stop_modules(hdd_ctx, false); 14149 } 14150 14151 osif_psoc_sync_trans_stop(psoc_sync); 14152 14153 exit: 14154 hdd_exit(); 14155 return errno; 14156 } 14157 14158 static int __hdd_mode_change_psoc_idle_shutdown(struct hdd_context *hdd_ctx) 14159 { 14160 is_mode_change_psoc_idle_shutdown = false; 14161 return hdd_wlan_stop_modules(hdd_ctx, true); 14162 } 14163 14164 int hdd_psoc_idle_shutdown(struct device *dev) 14165 { 14166 int ret; 14167 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 14168 14169 if (!hdd_ctx) 14170 return -EINVAL; 14171 14172 if (is_mode_change_psoc_idle_shutdown) 14173 ret = __hdd_mode_change_psoc_idle_shutdown(hdd_ctx); 14174 else { 14175 ret = __hdd_psoc_idle_shutdown(hdd_ctx); 14176 } 14177 14178 return ret; 14179 } 14180 14181 static int __hdd_psoc_idle_restart(struct hdd_context *hdd_ctx) 14182 { 14183 int ret; 14184 14185 ret = hdd_soc_idle_restart_lock(hdd_ctx->parent_dev); 14186 if (ret) 14187 return ret; 14188 14189 ret = hdd_wlan_start_modules(hdd_ctx, false); 14190 14191 if (!qdf_is_fw_down()) 14192 cds_set_recovery_in_progress(false); 14193 14194 hdd_soc_idle_restart_unlock(); 14195 14196 return ret; 14197 } 14198 14199 int hdd_psoc_idle_restart(struct device *dev) 14200 { 14201 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 14202 14203 if (!hdd_ctx) 14204 return -EINVAL; 14205 14206 return __hdd_psoc_idle_restart(hdd_ctx); 14207 } 14208 14209 int hdd_trigger_psoc_idle_restart(struct hdd_context *hdd_ctx) 14210 { 14211 int ret; 14212 14213 QDF_BUG(rtnl_is_locked()); 14214 14215 hdd_psoc_idle_timer_stop(hdd_ctx); 14216 if (hdd_ctx->driver_status == DRIVER_MODULES_ENABLED) { 14217 hdd_nofl_debug("Driver modules already Enabled"); 14218 return 0; 14219 } 14220 14221 ret = hdd_soc_idle_restart_lock(hdd_ctx->parent_dev); 14222 if (ret) 14223 return ret; 14224 14225 if (hdd_ctx->current_pcie_gen_speed) { 14226 hdd_info("request pcie gen speed change to %d", 14227 hdd_ctx->current_pcie_gen_speed); 14228 14229 /* call pld api for pcie gen speed change */ 14230 ret = pld_set_pcie_gen_speed(hdd_ctx->parent_dev, 14231 hdd_ctx->current_pcie_gen_speed); 14232 if (ret) 14233 hdd_err_rl("failed to set pcie gen speed"); 14234 14235 hdd_ctx->current_pcie_gen_speed = 0; 14236 } 14237 14238 qdf_event_reset(&hdd_ctx->regulatory_update_event); 14239 qdf_mutex_acquire(&hdd_ctx->regulatory_status_lock); 14240 hdd_ctx->is_regulatory_update_in_progress = true; 14241 qdf_mutex_release(&hdd_ctx->regulatory_status_lock); 14242 14243 ret = pld_idle_restart(hdd_ctx->parent_dev, hdd_psoc_idle_restart); 14244 hdd_soc_idle_restart_unlock(); 14245 14246 return ret; 14247 } 14248 14249 /** 14250 * hdd_psoc_idle_timeout_callback() - Handler for psoc idle timeout 14251 * @priv: pointer to hdd context 14252 * 14253 * Return: None 14254 */ 14255 static void hdd_psoc_idle_timeout_callback(void *priv) 14256 { 14257 int ret; 14258 struct hdd_context *hdd_ctx = priv; 14259 void *hif_ctx; 14260 14261 if (wlan_hdd_validate_context(hdd_ctx)) 14262 return; 14263 14264 hif_ctx = cds_get_context(QDF_MODULE_ID_HIF); 14265 if (hif_ctx) { 14266 /* 14267 * Trigger runtime sync resume before psoc_idle_shutdown 14268 * such that resume can happen successfully 14269 */ 14270 qdf_rtpm_sync_resume(); 14271 } 14272 14273 hdd_info("Psoc idle timeout elapsed; starting psoc shutdown"); 14274 14275 ret = pld_idle_shutdown(hdd_ctx->parent_dev, hdd_psoc_idle_shutdown); 14276 if (-EAGAIN == ret || hdd_ctx->is_wiphy_suspended) { 14277 hdd_debug("System suspend in progress. Restart idle shutdown timer"); 14278 hdd_psoc_idle_timer_start(hdd_ctx); 14279 } 14280 14281 /* Clear the recovery flag for PCIe discrete soc after idle shutdown*/ 14282 if (PLD_BUS_TYPE_PCIE == pld_get_bus_type(hdd_ctx->parent_dev) && 14283 -EBUSY != ret) 14284 cds_set_recovery_in_progress(false); 14285 } 14286 14287 #ifdef WLAN_LOGGING_SOCK_SVC_ENABLE 14288 static void hdd_set_wlan_logging(struct hdd_context *hdd_ctx) 14289 { 14290 wlan_set_console_log_levels(hdd_ctx->config->wlan_console_log_levels); 14291 wlan_logging_set_active(hdd_ctx->config->wlan_logging_enable); 14292 } 14293 #else 14294 static void hdd_set_wlan_logging(struct hdd_context *hdd_ctx) 14295 { } 14296 #endif 14297 14298 #ifdef WLAN_LOGGING_SOCK_SVC_ENABLE 14299 static void hdd_init_wlan_logging_params(struct hdd_config *config, 14300 struct wlan_objmgr_psoc *psoc) 14301 { 14302 config->wlan_logging_enable = cfg_get(psoc, CFG_WLAN_LOGGING_SUPPORT); 14303 14304 config->wlan_console_log_levels = 14305 cfg_get(psoc, CFG_WLAN_LOGGING_CONSOLE_SUPPORT); 14306 config->host_log_custom_nl_proto = 14307 cfg_get(psoc, CFG_HOST_LOG_CUSTOM_NETLINK_PROTO); 14308 } 14309 #else 14310 static void hdd_init_wlan_logging_params(struct hdd_config *config, 14311 struct wlan_objmgr_psoc *psoc) 14312 { 14313 } 14314 #endif 14315 14316 #ifdef FEATURE_WLAN_AUTO_SHUTDOWN 14317 static void hdd_init_wlan_auto_shutdown(struct hdd_config *config, 14318 struct wlan_objmgr_psoc *psoc) 14319 { 14320 config->wlan_auto_shutdown = cfg_get(psoc, CFG_WLAN_AUTO_SHUTDOWN); 14321 } 14322 #else 14323 static void hdd_init_wlan_auto_shutdown(struct hdd_config *config, 14324 struct wlan_objmgr_psoc *psoc) 14325 { 14326 } 14327 #endif 14328 14329 #ifndef REMOVE_PKT_LOG 14330 static void hdd_init_packet_log(struct hdd_config *config, 14331 struct wlan_objmgr_psoc *psoc) 14332 { 14333 config->enable_packet_log = cfg_get(psoc, CFG_ENABLE_PACKET_LOG); 14334 } 14335 #else 14336 static void hdd_init_packet_log(struct hdd_config *config, 14337 struct wlan_objmgr_psoc *psoc) 14338 { 14339 } 14340 #endif 14341 14342 #ifdef ENABLE_MTRACE_LOG 14343 static void hdd_init_mtrace_log(struct hdd_config *config, 14344 struct wlan_objmgr_psoc *psoc) 14345 { 14346 config->enable_mtrace = cfg_get(psoc, CFG_ENABLE_MTRACE); 14347 } 14348 #else 14349 static void hdd_init_mtrace_log(struct hdd_config *config, 14350 struct wlan_objmgr_psoc *psoc) 14351 { 14352 } 14353 #endif 14354 14355 #ifdef FEATURE_RUNTIME_PM 14356 static void hdd_init_runtime_pm(struct hdd_config *config, 14357 struct wlan_objmgr_psoc *psoc) 14358 { 14359 config->runtime_pm = cfg_get(psoc, CFG_ENABLE_RUNTIME_PM); 14360 } 14361 14362 bool hdd_is_runtime_pm_enabled(struct hdd_context *hdd_ctx) 14363 { 14364 return hdd_ctx->config->runtime_pm != hdd_runtime_pm_disabled; 14365 } 14366 #else 14367 static void hdd_init_runtime_pm(struct hdd_config *config, 14368 struct wlan_objmgr_psoc *psoc) 14369 14370 { 14371 } 14372 14373 bool hdd_is_runtime_pm_enabled(struct hdd_context *hdd_ctx) 14374 { 14375 return false; 14376 } 14377 #endif 14378 14379 #ifdef WLAN_FEATURE_WMI_SEND_RECV_QMI 14380 static void hdd_init_qmi_stats(struct hdd_config *config, 14381 struct wlan_objmgr_psoc *psoc) 14382 { 14383 config->is_qmi_stats_enabled = cfg_get(psoc, CFG_ENABLE_QMI_STATS); 14384 } 14385 #else 14386 static void hdd_init_qmi_stats(struct hdd_config *config, 14387 struct wlan_objmgr_psoc *psoc) 14388 14389 { 14390 } 14391 #endif 14392 14393 #ifdef FEATURE_WLAN_DYNAMIC_CVM 14394 static void hdd_init_vc_mode_cfg_bitmap(struct hdd_config *config, 14395 struct wlan_objmgr_psoc *psoc) 14396 { 14397 config->vc_mode_cfg_bitmap = cfg_get(psoc, CFG_VC_MODE_BITMAP); 14398 } 14399 #else 14400 static void hdd_init_vc_mode_cfg_bitmap(struct hdd_config *config, 14401 struct wlan_objmgr_psoc *psoc) 14402 { 14403 } 14404 #endif 14405 14406 #ifdef DHCP_SERVER_OFFLOAD 14407 static void 14408 hdd_init_dhcp_server_ip(struct hdd_context *hdd_ctx) 14409 { 14410 uint8_t num_entries; 14411 14412 hdd_ctx->config->dhcp_server_ip.is_dhcp_server_ip_valid = true; 14413 hdd_string_to_u8_array(cfg_get(hdd_ctx->psoc, CFG_DHCP_SERVER_IP_NAME), 14414 hdd_ctx->config->dhcp_server_ip.dhcp_server_ip, 14415 &num_entries, IPADDR_NUM_ENTRIES); 14416 14417 if (num_entries != IPADDR_NUM_ENTRIES) { 14418 hdd_err("Incorrect IP address (%s) assigned for DHCP server!", 14419 cfg_get(hdd_ctx->psoc, CFG_DHCP_SERVER_IP_NAME)); 14420 hdd_config->dhcp_server_ip.is_dhcp_server_ip_valid = false; 14421 } 14422 } 14423 #else 14424 static void 14425 hdd_init_dhcp_server_ip(struct hdd_context *hdd_ctx) 14426 { 14427 } 14428 #endif 14429 14430 #ifdef SAR_SAFETY_FEATURE 14431 static void hdd_sar_cfg_update(struct hdd_config *config, 14432 struct wlan_objmgr_psoc *psoc) 14433 { 14434 config->sar_safety_timeout = cfg_get(psoc, CFG_SAR_SAFETY_TIMEOUT); 14435 config->sar_safety_unsolicited_timeout = 14436 cfg_get(psoc, CFG_SAR_SAFETY_UNSOLICITED_TIMEOUT); 14437 config->sar_safety_req_resp_timeout = 14438 cfg_get(psoc, CFG_SAR_SAFETY_REQ_RESP_TIMEOUT); 14439 config->sar_safety_req_resp_retry = 14440 cfg_get(psoc, CFG_SAR_SAFETY_REQ_RESP_RETRIES); 14441 config->sar_safety_index = cfg_get(psoc, CFG_SAR_SAFETY_INDEX); 14442 config->sar_safety_sleep_index = 14443 cfg_get(psoc, CFG_SAR_SAFETY_SLEEP_INDEX); 14444 config->enable_sar_safety = 14445 cfg_get(psoc, CFG_ENABLE_SAR_SAFETY_FEATURE); 14446 config->config_sar_safety_sleep_index = 14447 cfg_get(psoc, CFG_CONFIG_SAR_SAFETY_SLEEP_MODE_INDEX); 14448 } 14449 14450 void hdd_set_sar_init_index(struct hdd_context *hdd_ctx) 14451 { 14452 uint32_t index, enable = 0; 14453 14454 if (!hdd_ctx) { 14455 hdd_err("hdd_ctx NULL"); 14456 return; 14457 } 14458 if (hdd_ctx->sar_version == SAR_VERSION_1) { 14459 hdd_nofl_debug("FW SAR version: %d", hdd_ctx->sar_version); 14460 return; 14461 } 14462 14463 enable = hdd_ctx->config->enable_sar_safety; 14464 index = hdd_ctx->config->sar_safety_index; 14465 if (enable & SAR_SAFETY_ENABLED_INIT) 14466 hdd_configure_sar_index(hdd_ctx, index); 14467 } 14468 #else 14469 static void hdd_sar_cfg_update(struct hdd_config *config, 14470 struct wlan_objmgr_psoc *psoc) 14471 { 14472 } 14473 #endif 14474 14475 #ifdef FEATURE_SET 14476 /** 14477 * hdd_get_wifi_features_cfg_update() - Initialize get wifi features cfg 14478 * @config: Pointer to HDD config 14479 * @psoc: psoc pointer 14480 * 14481 * Return: None 14482 */ 14483 static void hdd_get_wifi_features_cfg_update(struct hdd_config *config, 14484 struct wlan_objmgr_psoc *psoc) 14485 { 14486 config->get_wifi_features = cfg_get(psoc, CFG_GET_WIFI_FEATURES); 14487 } 14488 #else 14489 static void hdd_get_wifi_features_cfg_update(struct hdd_config *config, 14490 struct wlan_objmgr_psoc *psoc) 14491 { 14492 } 14493 #endif 14494 14495 #ifdef FEATURE_RUNTIME_PM 14496 /** 14497 * hdd_init_cpu_cxpc_threshold_cfg() - Initialize cpu cxpc threshold cfg 14498 * @config: Pointer to HDD config 14499 * @psoc: psoc pointer 14500 * 14501 * Return: None 14502 */ 14503 static void hdd_init_cpu_cxpc_threshold_cfg(struct hdd_config *config, 14504 struct wlan_objmgr_psoc *psoc) 14505 { 14506 config->cpu_cxpc_threshold = cfg_get(psoc, CFG_CPU_CXPC_THRESHOLD); 14507 } 14508 #else 14509 static void hdd_init_cpu_cxpc_threshold_cfg(struct hdd_config *config, 14510 struct wlan_objmgr_psoc *psoc) 14511 { 14512 } 14513 #endif 14514 14515 /** 14516 * hdd_cfg_params_init() - Initialize hdd params in hdd_config structure 14517 * @hdd_ctx: Pointer to HDD context 14518 * 14519 * Return: None 14520 */ 14521 static void hdd_cfg_params_init(struct hdd_context *hdd_ctx) 14522 { 14523 struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc; 14524 struct hdd_config *config = hdd_ctx->config; 14525 if (!psoc) { 14526 hdd_err("Invalid psoc"); 14527 return; 14528 } 14529 14530 if (!config) { 14531 hdd_err("Invalid hdd config"); 14532 return; 14533 } 14534 14535 config->dot11Mode = cfg_get(psoc, CFG_HDD_DOT11_MODE); 14536 config->bug_on_reinit_failure = cfg_get(psoc, 14537 CFG_BUG_ON_REINIT_FAILURE); 14538 14539 config->is_ramdump_enabled = cfg_get(psoc, 14540 CFG_ENABLE_RAMDUMP_COLLECTION); 14541 14542 config->iface_change_wait_time = cfg_get(psoc, 14543 CFG_INTERFACE_CHANGE_WAIT); 14544 14545 config->multicast_host_fw_msgs = cfg_get(psoc, 14546 CFG_MULTICAST_HOST_FW_MSGS); 14547 14548 config->private_wext_control = cfg_get(psoc, CFG_PRIVATE_WEXT_CONTROL); 14549 config->enablefwprint = cfg_get(psoc, CFG_ENABLE_FW_UART_PRINT); 14550 config->enable_fw_log = cfg_get(psoc, CFG_ENABLE_FW_LOG); 14551 config->operating_chan_freq = cfg_get(psoc, CFG_OPERATING_FREQUENCY); 14552 config->num_vdevs = cfg_get(psoc, CFG_NUM_VDEV_ENABLE); 14553 qdf_str_lcopy(config->enable_concurrent_sta, 14554 cfg_get(psoc, CFG_ENABLE_CONCURRENT_STA), 14555 CFG_CONCURRENT_IFACE_MAX_LEN); 14556 qdf_str_lcopy(config->dbs_scan_selection, 14557 cfg_get(psoc, CFG_DBS_SCAN_SELECTION), 14558 CFG_DBS_SCAN_PARAM_LENGTH); 14559 config->inform_bss_rssi_raw = cfg_get(psoc, CFG_INFORM_BSS_RSSI_RAW); 14560 config->mac_provision = cfg_get(psoc, CFG_ENABLE_MAC_PROVISION); 14561 config->provisioned_intf_pool = 14562 cfg_get(psoc, CFG_PROVISION_INTERFACE_POOL); 14563 config->derived_intf_pool = cfg_get(psoc, CFG_DERIVED_INTERFACE_POOL); 14564 config->advertise_concurrent_operation = 14565 cfg_get(psoc, 14566 CFG_ADVERTISE_CONCURRENT_OPERATION); 14567 config->is_unit_test_framework_enabled = 14568 cfg_get(psoc, CFG_ENABLE_UNIT_TEST_FRAMEWORK); 14569 config->disable_channel = cfg_get(psoc, CFG_ENABLE_DISABLE_CHANNEL); 14570 config->enable_sar_conversion = cfg_get(psoc, CFG_SAR_CONVERSION); 14571 config->nb_commands_interval = 14572 cfg_get(psoc, CFG_NB_COMMANDS_RATE_LIMIT); 14573 14574 hdd_init_vc_mode_cfg_bitmap(config, psoc); 14575 hdd_init_runtime_pm(config, psoc); 14576 hdd_init_wlan_auto_shutdown(config, psoc); 14577 hdd_init_wlan_logging_params(config, psoc); 14578 hdd_init_packet_log(config, psoc); 14579 hdd_init_mtrace_log(config, psoc); 14580 hdd_init_dhcp_server_ip(hdd_ctx); 14581 hdd_dp_cfg_update(psoc, hdd_ctx); 14582 hdd_sar_cfg_update(config, psoc); 14583 hdd_init_qmi_stats(config, psoc); 14584 hdd_club_ll_stats_in_get_sta_cfg_update(config, psoc); 14585 config->read_mac_addr_from_mac_file = 14586 cfg_get(psoc, CFG_READ_MAC_ADDR_FROM_MAC_FILE); 14587 14588 hdd_get_wifi_features_cfg_update(config, psoc); 14589 hdd_init_cpu_cxpc_threshold_cfg(config, psoc); 14590 14591 config->exclude_selftx_from_cca_busy = 14592 cfg_get(psoc, CFG_EXCLUDE_SELFTX_FROM_CCA_BUSY_TIME); 14593 hdd_init_link_state_cfg(config, psoc); 14594 } 14595 14596 #ifdef CONNECTION_ROAMING_CFG 14597 static QDF_STATUS hdd_cfg_parse_connection_roaming_cfg(void) 14598 { 14599 QDF_STATUS status = QDF_STATUS_E_INVAL; 14600 bool is_valid; 14601 14602 is_valid = cfg_valid_ini_check(WLAN_CONNECTION_ROAMING_INI_FILE); 14603 14604 if (is_valid) 14605 status = cfg_parse(WLAN_CONNECTION_ROAMING_INI_FILE); 14606 if (QDF_IS_STATUS_ERROR(status)) { 14607 is_valid = cfg_valid_ini_check(WLAN_CONNECTION_ROAMING_BACKUP_INI_FILE); 14608 if (is_valid) 14609 status = cfg_parse(WLAN_CONNECTION_ROAMING_BACKUP_INI_FILE); 14610 } 14611 return status; 14612 } 14613 #else 14614 static inline QDF_STATUS hdd_cfg_parse_connection_roaming_cfg(void) 14615 { 14616 return QDF_STATUS_E_NOSUPPORT; 14617 } 14618 #endif 14619 14620 struct hdd_context *hdd_context_create(struct device *dev) 14621 { 14622 QDF_STATUS status; 14623 int ret = 0; 14624 struct hdd_context *hdd_ctx; 14625 14626 hdd_enter(); 14627 14628 hdd_ctx = hdd_cfg80211_wiphy_alloc(); 14629 if (!hdd_ctx) { 14630 ret = -ENOMEM; 14631 goto err_out; 14632 } 14633 14634 status = qdf_delayed_work_create(&hdd_ctx->psoc_idle_timeout_work, 14635 hdd_psoc_idle_timeout_callback, 14636 hdd_ctx); 14637 if (QDF_IS_STATUS_ERROR(status)) { 14638 ret = qdf_status_to_os_return(status); 14639 goto wiphy_dealloc; 14640 } 14641 14642 hdd_pm_notifier_init(hdd_ctx); 14643 14644 hdd_ctx->parent_dev = dev; 14645 hdd_ctx->last_scan_reject_vdev_id = WLAN_UMAC_VDEV_ID_MAX; 14646 14647 hdd_ctx->config = qdf_mem_malloc(sizeof(struct hdd_config)); 14648 if (!hdd_ctx->config) { 14649 ret = -ENOMEM; 14650 goto err_free_hdd_context; 14651 } 14652 14653 status = cfg_parse(WLAN_INI_FILE); 14654 if (QDF_IS_STATUS_ERROR(status)) { 14655 hdd_err("Failed to parse cfg %s; status:%d\n", 14656 WLAN_INI_FILE, status); 14657 /* Assert if failed to parse at least one INI parameter */ 14658 QDF_BUG(status != QDF_STATUS_E_INVAL); 14659 ret = qdf_status_to_os_return(status); 14660 goto err_free_config; 14661 } 14662 14663 status = hdd_cfg_parse_connection_roaming_cfg(); 14664 14665 ret = hdd_objmgr_create_and_store_psoc(hdd_ctx, DEFAULT_PSOC_ID); 14666 if (ret) { 14667 QDF_DEBUG_PANIC("Psoc creation fails!"); 14668 goto err_release_store; 14669 } 14670 14671 if (QDF_IS_STATUS_SUCCESS(status)) 14672 ucfg_mlme_set_connection_roaming_ini_present(hdd_ctx->psoc, 14673 true); 14674 14675 hdd_cfg_params_init(hdd_ctx); 14676 14677 /* apply multiplier config, if not already set via module parameter */ 14678 if (qdf_timer_get_multiplier() == 1) 14679 qdf_timer_set_multiplier(cfg_get(hdd_ctx->psoc, 14680 CFG_TIMER_MULTIPLIER)); 14681 hdd_debug("set timer multiplier: %u", qdf_timer_get_multiplier()); 14682 14683 cds_set_fatal_event(cfg_get(hdd_ctx->psoc, 14684 CFG_ENABLE_FATAL_EVENT_TRIGGER)); 14685 14686 hdd_override_ini_config(hdd_ctx); 14687 14688 ret = hdd_context_init(hdd_ctx); 14689 14690 if (ret) 14691 goto err_hdd_objmgr_destroy; 14692 14693 if (hdd_get_conparam() == QDF_GLOBAL_EPPING_MODE) 14694 goto skip_multicast_logging; 14695 14696 cds_set_multicast_logging(hdd_ctx->config->multicast_host_fw_msgs); 14697 ret = hdd_init_netlink_services(hdd_ctx); 14698 if (ret) 14699 goto err_deinit_hdd_context; 14700 14701 hdd_set_wlan_logging(hdd_ctx); 14702 qdf_atomic_init(&hdd_ctx->adapter_ops_history.index); 14703 14704 skip_multicast_logging: 14705 hdd_set_trace_level_for_each(hdd_ctx); 14706 14707 cds_set_context(QDF_MODULE_ID_HDD, hdd_ctx); 14708 14709 wlan_hdd_sar_timers_init(hdd_ctx); 14710 14711 hdd_exit(); 14712 14713 return hdd_ctx; 14714 14715 err_deinit_hdd_context: 14716 hdd_context_deinit(hdd_ctx); 14717 14718 err_hdd_objmgr_destroy: 14719 hdd_objmgr_release_and_destroy_psoc(hdd_ctx); 14720 14721 err_release_store: 14722 cfg_release(); 14723 14724 err_free_config: 14725 qdf_mem_free(hdd_ctx->config); 14726 14727 err_free_hdd_context: 14728 qdf_delayed_work_destroy(&hdd_ctx->psoc_idle_timeout_work); 14729 14730 wiphy_dealloc: 14731 wiphy_free(hdd_ctx->wiphy); 14732 14733 err_out: 14734 return ERR_PTR(ret); 14735 } 14736 14737 #ifdef MULTI_CLIENT_LL_SUPPORT 14738 /** 14739 * wlan_hdd_init_multi_client_info_table()- Initialize the multi client info 14740 * table 14741 * @adapter: hdd adapter 14742 * 14743 * Return: none 14744 */ 14745 static void 14746 wlan_hdd_init_multi_client_info_table(struct hdd_adapter *adapter) 14747 { 14748 uint8_t i; 14749 14750 for (i = 0; i < WLM_MAX_HOST_CLIENT; i++) { 14751 adapter->client_info[i].client_id = i; 14752 adapter->client_info[i].port_id = 0; 14753 adapter->client_info[i].in_use = false; 14754 } 14755 } 14756 14757 void wlan_hdd_deinit_multi_client_info_table(struct hdd_adapter *adapter) 14758 { 14759 uint8_t i; 14760 14761 hdd_debug("deinitializing the client info table"); 14762 /* de-initialize the table for host driver client */ 14763 for (i = 0; i < WLM_MAX_HOST_CLIENT; i++) { 14764 if (adapter->client_info[i].in_use) { 14765 adapter->client_info[i].port_id = 0; 14766 adapter->client_info[i].client_id = i; 14767 adapter->client_info[i].in_use = false; 14768 } 14769 } 14770 } 14771 14772 /** 14773 * wlan_hdd_get_host_driver_port_id()- get host driver port id 14774 * @port_id: argument to be filled 14775 * 14776 * Return: none 14777 */ 14778 static void wlan_hdd_get_host_driver_port_id(uint32_t *port_id) 14779 { 14780 *port_id = WLAM_WLM_HOST_DRIVER_PORT_ID; 14781 } 14782 14783 #else 14784 static inline void 14785 wlan_hdd_init_multi_client_info_table(struct hdd_adapter *adapter) 14786 { 14787 } 14788 14789 static inline void wlan_hdd_get_host_driver_port_id(uint32_t *port_id) 14790 { 14791 } 14792 #endif 14793 14794 static void 14795 hdd_adapter_set_wlm_client_latency_level(struct hdd_adapter *adapter) 14796 { 14797 QDF_STATUS status; 14798 bool reset; 14799 uint32_t port_id; 14800 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); 14801 14802 if (!hdd_ctx) 14803 return; 14804 14805 status = ucfg_mlme_cfg_get_wlm_reset(hdd_ctx->psoc, &reset); 14806 if (QDF_IS_STATUS_ERROR(status)) { 14807 hdd_err("could not get the wlm reset flag"); 14808 reset = false; 14809 } 14810 14811 if (reset) 14812 goto out; 14813 14814 if (hdd_get_multi_client_ll_support(adapter)) { 14815 wlan_hdd_get_host_driver_port_id(&port_id); 14816 status = wlan_hdd_set_wlm_client_latency_level( 14817 adapter, port_id, 14818 adapter->latency_level); 14819 if (QDF_IS_STATUS_ERROR(status)) 14820 hdd_warn("Fail to set latency level:%u", status); 14821 } else { 14822 status = sme_set_wlm_latency_level(hdd_ctx->mac_handle, 14823 adapter->deflink->vdev_id, 14824 adapter->latency_level, 14825 0, false); 14826 if (QDF_IS_STATUS_ERROR(status)) 14827 hdd_warn("set wlm mode failed, %u", status); 14828 } 14829 out: 14830 hdd_debug("wlm initial mode %u", adapter->latency_level); 14831 } 14832 14833 #ifdef WLAN_HDD_MULTI_VDEV_SINGLE_NDEV 14834 struct qdf_mac_addr * 14835 hdd_adapter_get_link_mac_addr(struct wlan_hdd_link_info *link_info) 14836 { 14837 struct hdd_adapter *adapter; 14838 14839 if (!link_info) 14840 return NULL; 14841 14842 adapter = link_info->adapter; 14843 if (!hdd_adapter_is_ml_adapter(adapter) || 14844 qdf_is_macaddr_zero(&link_info->link_addr) || 14845 !wlan_vdev_mlme_is_mlo_vdev(link_info->vdev)) 14846 return &adapter->mac_addr; 14847 14848 return &link_info->link_addr; 14849 } 14850 #else 14851 struct qdf_mac_addr * 14852 hdd_adapter_get_link_mac_addr(struct wlan_hdd_link_info *link_info) 14853 { 14854 if (!link_info) 14855 return NULL; 14856 14857 return &link_info->adapter->mac_addr; 14858 } 14859 #endif 14860 14861 #if defined(WLAN_FEATURE_11BE_MLO) && defined(CFG80211_11BE_BASIC) && \ 14862 defined(WLAN_HDD_MULTI_VDEV_SINGLE_NDEV) 14863 QDF_STATUS hdd_adapter_check_duplicate_session(struct hdd_adapter *adapter) 14864 { 14865 int i = 0; 14866 QDF_STATUS status; 14867 uint8_t *addr_list[WLAN_MAX_MLD + 2] = {0}; 14868 struct wlan_hdd_link_info *link_info; 14869 14870 if (!hdd_adapter_is_ml_adapter(adapter) || 14871 adapter->device_mode == QDF_SAP_MODE) 14872 goto netdev_addr; 14873 14874 hdd_adapter_for_each_active_link_info(adapter, link_info) 14875 addr_list[i++] = &link_info->link_addr.bytes[0]; 14876 14877 netdev_addr: 14878 addr_list[i] = &adapter->mac_addr.bytes[0]; 14879 status = sme_check_for_duplicate_session(adapter->hdd_ctx->mac_handle, 14880 &addr_list[0]); 14881 return status; 14882 } 14883 14884 QDF_STATUS hdd_adapter_fill_link_address(struct hdd_adapter *adapter) 14885 { 14886 int i = 0; 14887 QDF_STATUS status; 14888 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); 14889 enum QDF_OPMODE opmode = adapter->device_mode; 14890 struct qdf_mac_addr link_addrs[WLAN_MAX_ML_BSS_LINKS] = {0}; 14891 struct wlan_hdd_link_info *link_info; 14892 14893 if (opmode != QDF_STA_MODE && opmode != QDF_SAP_MODE) 14894 return QDF_STATUS_SUCCESS; 14895 14896 if (opmode == QDF_SAP_MODE) { 14897 link_info = adapter->deflink; 14898 qdf_copy_macaddr(&link_info->link_addr, &adapter->mac_addr); 14899 return QDF_STATUS_SUCCESS; 14900 } 14901 14902 if (!hdd_adapter_is_ml_adapter(adapter)) 14903 return QDF_STATUS_SUCCESS; 14904 14905 status = hdd_derive_link_address_from_mld(hdd_ctx->psoc, 14906 &adapter->mac_addr, 14907 &link_addrs[0], 14908 WLAN_MAX_ML_BSS_LINKS); 14909 if (QDF_IS_STATUS_ERROR(status)) 14910 return status; 14911 14912 hdd_adapter_for_each_link_info(adapter, link_info) 14913 qdf_copy_macaddr(&link_info->link_addr, &link_addrs[i++]); 14914 14915 return status; 14916 } 14917 #elif defined(WLAN_FEATURE_11BE_MLO) && defined(CFG80211_11BE_BASIC) 14918 QDF_STATUS hdd_adapter_check_duplicate_session(struct hdd_adapter *adapter) 14919 { 14920 int i; 14921 QDF_STATUS status; 14922 uint8_t *addr_list[WLAN_MAX_MLD + 1] = {0}; 14923 struct hdd_adapter *link_adapter; 14924 struct hdd_mlo_adapter_info *mlo_adapter_info; 14925 mac_handle_t mac_handle = hdd_adapter_get_mac_handle(adapter); 14926 14927 if (hdd_adapter_is_ml_adapter(adapter) && 14928 adapter->device_mode == QDF_STA_MODE) { 14929 addr_list[0] = &adapter->mld_addr.bytes[0]; 14930 mlo_adapter_info = &adapter->mlo_adapter_info; 14931 for (i = 0; i < WLAN_MAX_MLD; i++) { 14932 link_adapter = mlo_adapter_info->link_adapter[i]; 14933 if (!link_adapter) 14934 continue; 14935 if (hdd_adapter_is_associated_with_ml_adapter( 14936 link_adapter)) { 14937 addr_list[1] = &link_adapter->mac_addr.bytes[0]; 14938 } 14939 } 14940 } else { 14941 addr_list[0] = &adapter->mac_addr.bytes[0]; 14942 } 14943 14944 status = sme_check_for_duplicate_session(mac_handle, &addr_list[0]); 14945 return status; 14946 } 14947 #else 14948 QDF_STATUS hdd_adapter_check_duplicate_session(struct hdd_adapter *adapter) 14949 { 14950 QDF_STATUS status; 14951 uint8_t *addr_list[2] = {0}; 14952 mac_handle_t mac_handle = hdd_adapter_get_mac_handle(adapter); 14953 14954 addr_list[0] = &adapter->mac_addr.bytes[0]; 14955 status = sme_check_for_duplicate_session(mac_handle, &addr_list[0]); 14956 14957 return status; 14958 } 14959 #endif 14960 14961 static void hdd_restore_info_for_ssr(struct hdd_adapter *adapter) 14962 { 14963 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); 14964 14965 if (cds_is_driver_recovering()) { 14966 /* ssr happens, recover the info */ 14967 hdd_set_vdev_phy_mode(adapter, adapter->user_phy_mode); 14968 wlan_mlme_restore_user_set_link_num(hdd_ctx->psoc); 14969 } else { 14970 /* intf down/up happens, reset default info */ 14971 hdd_set_vdev_phy_mode(adapter, QCA_WLAN_VENDOR_PHY_MODE_AUTO); 14972 wlan_mlme_clear_user_set_link_num(hdd_ctx->psoc); 14973 } 14974 } 14975 14976 void hdd_adapter_reset_station_ctx(struct hdd_adapter *adapter) 14977 { 14978 struct wlan_hdd_link_info *link_info; 14979 struct hdd_station_ctx *sta_ctx; 14980 14981 hdd_adapter_for_each_link_info(adapter, link_info) { 14982 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(link_info); 14983 qdf_mem_zero(&sta_ctx->conn_info.bssid, QDF_MAC_ADDR_SIZE); 14984 14985 hdd_cm_clear_ieee_link_id(link_info); 14986 sta_ctx->user_cfg_chn_width = CH_WIDTH_INVALID; 14987 } 14988 } 14989 14990 int hdd_start_station_adapter(struct hdd_adapter *adapter) 14991 { 14992 QDF_STATUS status; 14993 int ret; 14994 struct wlan_hdd_link_info *link_info; 14995 14996 hdd_enter_dev(adapter->dev); 14997 if (test_bit(SME_SESSION_OPENED, &adapter->deflink->link_flags)) { 14998 hdd_err("session is already opened, %d", 14999 adapter->deflink->vdev_id); 15000 return qdf_status_to_os_return(QDF_STATUS_SUCCESS); 15001 } 15002 15003 if ((adapter->device_mode == QDF_P2P_DEVICE_MODE) || 15004 (adapter->device_mode == QDF_NAN_DISC_MODE)) 15005 wlan_hdd_lpc_del_monitor_interface(adapter->hdd_ctx, false); 15006 15007 status = hdd_adapter_fill_link_address(adapter); 15008 if (QDF_IS_STATUS_ERROR(status)) { 15009 hdd_debug("Link address derive failed"); 15010 return qdf_status_to_os_return(status); 15011 } 15012 15013 status = hdd_adapter_check_duplicate_session(adapter); 15014 if (QDF_IS_STATUS_ERROR(status)) { 15015 hdd_err("Duplicate session is existing with same mac address"); 15016 return qdf_status_to_os_return(status); 15017 } 15018 15019 hdd_adapter_for_each_active_link_info(adapter, link_info) { 15020 ret = hdd_vdev_create(link_info); 15021 if (ret) { 15022 hdd_err("failed to create vdev: %d", ret); 15023 goto fail; 15024 } 15025 15026 status = hdd_init_station_mode(link_info); 15027 if (QDF_STATUS_SUCCESS != status) { 15028 hdd_err("Error Initializing station mode: %d", status); 15029 ret = qdf_status_to_os_return(status); 15030 goto fail; 15031 } 15032 } 15033 15034 hdd_adapter_reset_station_ctx(adapter); 15035 15036 hdd_register_wext(adapter->dev); 15037 hdd_set_netdev_flags(adapter); 15038 15039 hdd_register_tx_flow_control(adapter, 15040 hdd_tx_resume_timer_expired_handler, 15041 hdd_tx_resume_cb, 15042 hdd_tx_flow_control_is_pause); 15043 15044 hdd_register_hl_netdev_fc_timer(adapter, 15045 hdd_tx_resume_timer_expired_handler); 15046 15047 if (hdd_get_multi_client_ll_support(adapter)) 15048 wlan_hdd_init_multi_client_info_table(adapter); 15049 15050 hdd_adapter_set_wlm_client_latency_level(adapter); 15051 hdd_adapter_update_mlo_mgr_mac_addr(adapter); 15052 hdd_restore_info_for_ssr(adapter); 15053 15054 hdd_exit(); 15055 return 0; 15056 15057 fail: 15058 hdd_adapter_for_each_active_link_info(adapter, link_info) 15059 hdd_vdev_destroy(link_info); 15060 15061 return ret; 15062 } 15063 15064 int hdd_start_ap_adapter(struct hdd_adapter *adapter, bool rtnl_held) 15065 { 15066 QDF_STATUS status; 15067 bool is_ssr = false; 15068 int ret; 15069 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); 15070 struct sap_context *sap_ctx; 15071 struct wlan_hdd_link_info *link_info = adapter->deflink; 15072 15073 hdd_enter(); 15074 15075 if (test_bit(SME_SESSION_OPENED, &link_info->link_flags)) { 15076 hdd_err("session is already opened, %d", 15077 link_info->vdev_id); 15078 return qdf_status_to_os_return(QDF_STATUS_SUCCESS); 15079 } 15080 15081 status = hdd_adapter_fill_link_address(adapter); 15082 if (QDF_IS_STATUS_ERROR(status)) { 15083 hdd_debug("Link address derive failed"); 15084 return qdf_status_to_os_return(status); 15085 } 15086 15087 status = hdd_adapter_check_duplicate_session(adapter); 15088 if (QDF_IS_STATUS_ERROR(status)) { 15089 hdd_err("Duplicate session is existing with same mac address"); 15090 return qdf_status_to_os_return(status); 15091 } 15092 15093 /* 15094 * In SSR case no need to create new sap context. 15095 * Otherwise create sap context first and then create 15096 * vdev as while creating the vdev, driver needs to 15097 * register SAP callback and that callback uses sap context 15098 */ 15099 if (WLAN_HDD_GET_SAP_CTX_PTR(link_info)) { 15100 is_ssr = true; 15101 } else if (!hdd_sap_create_ctx(adapter)) { 15102 hdd_err("sap creation failed"); 15103 return qdf_status_to_os_return(QDF_STATUS_E_FAILURE); 15104 } 15105 15106 ret = hdd_vdev_create(link_info); 15107 if (ret) { 15108 hdd_err("failed to create vdev, status:%d", ret); 15109 goto sap_destroy_ctx; 15110 } 15111 15112 sap_ctx = WLAN_HDD_GET_SAP_CTX_PTR(link_info); 15113 status = sap_acquire_vdev_ref(hdd_ctx->psoc, sap_ctx, 15114 link_info->vdev_id); 15115 if (!QDF_IS_STATUS_SUCCESS(status)) { 15116 hdd_err("Failed to get vdev ref for sap for session_id: %u", 15117 link_info->vdev_id); 15118 ret = qdf_status_to_os_return(status); 15119 goto sap_vdev_destroy; 15120 } 15121 15122 if (adapter->device_mode == QDF_SAP_MODE) { 15123 status = hdd_vdev_configure_rtt_params(sap_ctx->vdev); 15124 if (QDF_IS_STATUS_ERROR(status)) 15125 goto sap_release_ref; 15126 } 15127 15128 status = hdd_init_ap_mode(adapter, is_ssr, rtnl_held); 15129 if (QDF_STATUS_SUCCESS != status) { 15130 hdd_err("Error Initializing the AP mode: %d", status); 15131 ret = qdf_status_to_os_return(status); 15132 goto sap_release_ref; 15133 } 15134 15135 hdd_register_tx_flow_control(adapter, 15136 hdd_softap_tx_resume_timer_expired_handler, 15137 hdd_softap_tx_resume_cb, 15138 hdd_tx_flow_control_is_pause); 15139 15140 hdd_register_hl_netdev_fc_timer(adapter, 15141 hdd_tx_resume_timer_expired_handler); 15142 15143 if (cds_is_driver_recovering()) 15144 hdd_medium_assess_ssr_reinit(); 15145 15146 hdd_exit(); 15147 return 0; 15148 15149 sap_release_ref: 15150 sap_release_vdev_ref(sap_ctx); 15151 sap_vdev_destroy: 15152 hdd_vdev_destroy(link_info); 15153 sap_destroy_ctx: 15154 hdd_sap_destroy_ctx(link_info); 15155 return ret; 15156 } 15157 15158 #if defined(QCA_LL_TX_FLOW_CONTROL_V2) || defined(QCA_LL_PDEV_TX_FLOW_CONTROL) 15159 /** 15160 * hdd_txrx_populate_cds_config() - Populate txrx cds configuration 15161 * @cds_cfg: CDS Configuration 15162 * @hdd_ctx: Pointer to hdd context 15163 * 15164 * Return: none 15165 */ 15166 static inline void hdd_txrx_populate_cds_config(struct cds_config_info 15167 *cds_cfg, 15168 struct hdd_context *hdd_ctx) 15169 { 15170 cds_cfg->tx_flow_stop_queue_th = 15171 cfg_get(hdd_ctx->psoc, CFG_DP_TX_FLOW_STOP_QUEUE_TH); 15172 cds_cfg->tx_flow_start_queue_offset = 15173 cfg_get(hdd_ctx->psoc, CFG_DP_TX_FLOW_START_QUEUE_OFFSET); 15174 /* configuration for DP RX Threads */ 15175 cds_cfg->enable_dp_rx_threads = 15176 ucfg_dp_is_rx_threads_enabled(hdd_ctx->psoc); 15177 } 15178 #else 15179 static inline void hdd_txrx_populate_cds_config(struct cds_config_info 15180 *cds_cfg, 15181 struct hdd_context *hdd_ctx) 15182 { 15183 } 15184 #endif 15185 15186 /** 15187 * hdd_update_cds_config() - API to update cds configuration parameters 15188 * @hdd_ctx: HDD Context 15189 * 15190 * Return: 0 for Success, errno on failure 15191 */ 15192 static int hdd_update_cds_config(struct hdd_context *hdd_ctx) 15193 { 15194 struct cds_config_info *cds_cfg; 15195 int value; 15196 uint8_t band_capability; 15197 uint32_t band_bitmap; 15198 uint8_t ito_repeat_count; 15199 bool crash_inject; 15200 bool self_recovery; 15201 bool fw_timeout_crash; 15202 QDF_STATUS status; 15203 15204 cds_cfg = qdf_mem_malloc(sizeof(*cds_cfg)); 15205 if (!cds_cfg) 15206 return -ENOMEM; 15207 15208 cds_cfg->driver_type = QDF_DRIVER_TYPE_PRODUCTION; 15209 ucfg_mlme_get_sap_max_modulated_dtim(hdd_ctx->psoc, 15210 &cds_cfg->sta_maxlimod_dtim); 15211 15212 ucfg_mlme_get_max_modulated_dtim_ms(hdd_ctx->psoc, 15213 &cds_cfg->sta_maxlimod_dtim_ms); 15214 15215 status = ucfg_mlme_get_crash_inject(hdd_ctx->psoc, &crash_inject); 15216 if (QDF_IS_STATUS_ERROR(status)) { 15217 hdd_err("Failed to get crash inject ini config"); 15218 goto exit; 15219 } 15220 15221 status = ucfg_mlme_get_self_recovery(hdd_ctx->psoc, &self_recovery); 15222 if (QDF_IS_STATUS_ERROR(status)) { 15223 hdd_err("Failed to get self recovery ini config"); 15224 goto exit; 15225 } 15226 15227 status = ucfg_mlme_get_fw_timeout_crash(hdd_ctx->psoc, 15228 &fw_timeout_crash); 15229 if (QDF_IS_STATUS_ERROR(status)) { 15230 hdd_err("Failed to get fw timeout crash ini config"); 15231 goto exit; 15232 } 15233 15234 status = ucfg_mlme_get_ito_repeat_count(hdd_ctx->psoc, 15235 &ito_repeat_count); 15236 if (QDF_IS_STATUS_ERROR(status)) { 15237 hdd_err("Failed to get ITO repeat count ini config"); 15238 goto exit; 15239 } 15240 15241 cds_cfg->force_target_assert_enabled = crash_inject; 15242 15243 ucfg_mlme_get_sap_max_offload_peers(hdd_ctx->psoc, &value); 15244 cds_cfg->ap_maxoffload_peers = value; 15245 ucfg_mlme_get_sap_max_offload_reorder_buffs(hdd_ctx->psoc, 15246 &value); 15247 cds_cfg->ap_maxoffload_reorderbuffs = value; 15248 15249 cds_cfg->reorder_offload = DP_REORDER_OFFLOAD_SUPPORT; 15250 15251 /* IPA micro controller data path offload resource config item */ 15252 cds_cfg->uc_offload_enabled = ucfg_ipa_uc_is_enabled(); 15253 15254 cds_cfg->enable_rxthread = 15255 ucfg_dp_is_rx_common_thread_enabled(hdd_ctx->psoc); 15256 ucfg_mlme_get_sap_max_peers(hdd_ctx->psoc, &value); 15257 cds_cfg->max_station = value; 15258 cds_cfg->sub_20_channel_width = WLAN_SUB_20_CH_WIDTH_NONE; 15259 cds_cfg->max_msdus_per_rxinorderind = 15260 cfg_get(hdd_ctx->psoc, CFG_DP_MAX_MSDUS_PER_RXIND); 15261 cds_cfg->self_recovery_enabled = self_recovery; 15262 cds_cfg->fw_timeout_crash = fw_timeout_crash; 15263 15264 cds_cfg->ito_repeat_count = ito_repeat_count; 15265 15266 status = ucfg_mlme_get_band_capability(hdd_ctx->psoc, &band_bitmap); 15267 if (QDF_IS_STATUS_ERROR(status)) 15268 goto exit; 15269 15270 band_capability = wlan_reg_band_bitmap_to_band_info(band_bitmap); 15271 cds_cfg->bandcapability = band_capability; 15272 cds_cfg->num_vdevs = hdd_ctx->config->num_vdevs; 15273 cds_cfg->enable_tx_compl_tsf64 = 15274 hdd_tsf_is_tsf64_tx_set(hdd_ctx); 15275 hdd_txrx_populate_cds_config(cds_cfg, hdd_ctx); 15276 hdd_lpass_populate_cds_config(cds_cfg, hdd_ctx); 15277 cds_init_ini_config(cds_cfg); 15278 return 0; 15279 15280 exit: 15281 qdf_mem_free(cds_cfg); 15282 return -EINVAL; 15283 } 15284 15285 /** 15286 * hdd_update_user_config() - API to update user configuration 15287 * parameters to obj mgr which are used by multiple components 15288 * @hdd_ctx: HDD Context 15289 * 15290 * Return: 0 for Success, errno on failure 15291 */ 15292 static int hdd_update_user_config(struct hdd_context *hdd_ctx) 15293 { 15294 struct wlan_objmgr_psoc_user_config *user_config; 15295 uint8_t band_capability; 15296 uint32_t band_bitmap; 15297 QDF_STATUS status; 15298 bool value = false; 15299 15300 status = ucfg_mlme_get_band_capability(hdd_ctx->psoc, &band_bitmap); 15301 if (QDF_IS_STATUS_ERROR(status)) 15302 return -EIO; 15303 15304 user_config = qdf_mem_malloc(sizeof(*user_config)); 15305 if (!user_config) 15306 return -ENOMEM; 15307 15308 user_config->dot11_mode = hdd_ctx->config->dot11Mode; 15309 status = ucfg_mlme_is_11d_enabled(hdd_ctx->psoc, &value); 15310 if (!QDF_IS_STATUS_SUCCESS(status)) 15311 hdd_err("Invalid 11d_enable flag"); 15312 user_config->is_11d_support_enabled = value; 15313 15314 value = false; 15315 status = ucfg_mlme_is_11h_enabled(hdd_ctx->psoc, &value); 15316 if (!QDF_IS_STATUS_SUCCESS(status)) 15317 hdd_err("Invalid 11h_enable flag"); 15318 user_config->is_11h_support_enabled = value; 15319 band_capability = wlan_reg_band_bitmap_to_band_info(band_bitmap); 15320 user_config->band_capability = band_capability; 15321 wlan_objmgr_psoc_set_user_config(hdd_ctx->psoc, user_config); 15322 15323 qdf_mem_free(user_config); 15324 return 0; 15325 } 15326 15327 /** 15328 * hdd_init_thermal_info - Initialize thermal level 15329 * @hdd_ctx: HDD context 15330 * 15331 * Initialize thermal level at SME layer and set the thermal level callback 15332 * which would be called when a configured thermal threshold is hit. 15333 * 15334 * Return: 0 on success and errno on failure 15335 */ 15336 static int hdd_init_thermal_info(struct hdd_context *hdd_ctx) 15337 { 15338 QDF_STATUS status; 15339 mac_handle_t mac_handle = hdd_ctx->mac_handle; 15340 15341 status = sme_init_thermal_info(mac_handle); 15342 15343 if (!QDF_IS_STATUS_SUCCESS(status)) 15344 return qdf_status_to_os_return(status); 15345 15346 sme_add_set_thermal_level_callback(mac_handle, 15347 hdd_set_thermal_level_cb); 15348 15349 return 0; 15350 15351 } 15352 15353 #if defined(CONFIG_HDD_INIT_WITH_RTNL_LOCK) 15354 /** 15355 * hdd_hold_rtnl_lock - Hold RTNL lock 15356 * 15357 * Hold RTNL lock 15358 * 15359 * Return: True if held and false otherwise 15360 */ 15361 static inline bool hdd_hold_rtnl_lock(void) 15362 { 15363 rtnl_lock(); 15364 return true; 15365 } 15366 15367 /** 15368 * hdd_release_rtnl_lock - Release RTNL lock 15369 * 15370 * Release RTNL lock 15371 * 15372 * Return: None 15373 */ 15374 static inline void hdd_release_rtnl_lock(void) 15375 { 15376 rtnl_unlock(); 15377 } 15378 #else 15379 static inline bool hdd_hold_rtnl_lock(void) { return false; } 15380 static inline void hdd_release_rtnl_lock(void) { } 15381 #endif 15382 15383 #if !defined(REMOVE_PKT_LOG) 15384 15385 /* MAX iwpriv command support */ 15386 #define PKTLOG_SET_BUFF_SIZE 3 15387 #define PKTLOG_CLEAR_BUFF 4 15388 /* Set Maximum pktlog file size to 64MB */ 15389 #define MAX_PKTLOG_SIZE 64 15390 15391 /** 15392 * hdd_pktlog_set_buff_size() - set pktlog buffer size 15393 * @hdd_ctx: hdd context 15394 * @set_value2: pktlog buffer size value 15395 * 15396 * 15397 * Return: 0 for success or error. 15398 */ 15399 static int hdd_pktlog_set_buff_size(struct hdd_context *hdd_ctx, int set_value2) 15400 { 15401 struct sir_wifi_start_log start_log = { 0 }; 15402 QDF_STATUS status; 15403 15404 start_log.ring_id = RING_ID_PER_PACKET_STATS; 15405 start_log.verbose_level = WLAN_LOG_LEVEL_OFF; 15406 start_log.ini_triggered = cds_is_packet_log_enabled(); 15407 start_log.user_triggered = 1; 15408 start_log.size = set_value2; 15409 start_log.is_pktlog_buff_clear = false; 15410 15411 status = sme_wifi_start_logger(hdd_ctx->mac_handle, start_log); 15412 if (!QDF_IS_STATUS_SUCCESS(status)) { 15413 hdd_err("sme_wifi_start_logger failed(err=%d)", status); 15414 hdd_exit(); 15415 return -EINVAL; 15416 } 15417 15418 return 0; 15419 } 15420 15421 /** 15422 * hdd_pktlog_clear_buff() - clear pktlog buffer 15423 * @hdd_ctx: hdd context 15424 * 15425 * Return: 0 for success or error. 15426 */ 15427 static int hdd_pktlog_clear_buff(struct hdd_context *hdd_ctx) 15428 { 15429 struct sir_wifi_start_log start_log; 15430 QDF_STATUS status; 15431 15432 start_log.ring_id = RING_ID_PER_PACKET_STATS; 15433 start_log.verbose_level = WLAN_LOG_LEVEL_OFF; 15434 start_log.ini_triggered = cds_is_packet_log_enabled(); 15435 start_log.user_triggered = 1; 15436 start_log.size = 0; 15437 start_log.is_pktlog_buff_clear = true; 15438 15439 status = sme_wifi_start_logger(hdd_ctx->mac_handle, start_log); 15440 if (!QDF_IS_STATUS_SUCCESS(status)) { 15441 hdd_err("sme_wifi_start_logger failed(err=%d)", status); 15442 hdd_exit(); 15443 return -EINVAL; 15444 } 15445 15446 return 0; 15447 } 15448 15449 15450 /** 15451 * hdd_process_pktlog_command() - process pktlog command 15452 * @hdd_ctx: hdd context 15453 * @set_value: value set by user 15454 * @set_value2: pktlog buffer size value 15455 * 15456 * This function process pktlog command. 15457 * set_value2 only matters when set_value is 3 (set buff size) 15458 * otherwise we ignore it. 15459 * 15460 * Return: 0 for success or error. 15461 */ 15462 int hdd_process_pktlog_command(struct hdd_context *hdd_ctx, uint32_t set_value, 15463 int set_value2) 15464 { 15465 int ret; 15466 bool enable; 15467 uint8_t user_triggered = 0; 15468 15469 ret = wlan_hdd_validate_context(hdd_ctx); 15470 if (0 != ret) 15471 return ret; 15472 15473 hdd_debug("set pktlog %d, set size %d", set_value, set_value2); 15474 15475 if (set_value > PKTLOG_CLEAR_BUFF) { 15476 hdd_err("invalid pktlog value %d", set_value); 15477 return -EINVAL; 15478 } 15479 15480 if (set_value == PKTLOG_SET_BUFF_SIZE) { 15481 if (set_value2 <= 0) { 15482 hdd_err("invalid pktlog size %d", set_value2); 15483 return -EINVAL; 15484 } else if (set_value2 > MAX_PKTLOG_SIZE) { 15485 hdd_err_rl("Pktlog size is large. max value is %uMB.", 15486 MAX_PKTLOG_SIZE); 15487 return -EINVAL; 15488 } 15489 return hdd_pktlog_set_buff_size(hdd_ctx, set_value2); 15490 } else if (set_value == PKTLOG_CLEAR_BUFF) { 15491 return hdd_pktlog_clear_buff(hdd_ctx); 15492 } 15493 15494 /* 15495 * set_value = 0 then disable packetlog 15496 * set_value = 1 enable packetlog forcefully 15497 * set_value = 2 then disable packetlog if disabled through ini or 15498 * enable packetlog with AUTO type. 15499 */ 15500 enable = ((set_value > 0) && cds_is_packet_log_enabled()) ? 15501 true : false; 15502 15503 if (1 == set_value) { 15504 enable = true; 15505 user_triggered = 1; 15506 } 15507 15508 return hdd_pktlog_enable_disable(hdd_ctx, enable, user_triggered, 0); 15509 } 15510 15511 /** 15512 * hdd_pktlog_enable_disable() - Enable/Disable packet logging 15513 * @hdd_ctx: HDD context 15514 * @enable_disable_flag: Flag to enable/disable 15515 * @user_triggered: triggered through iwpriv 15516 * @size: buffer size to be used for packetlog 15517 * 15518 * Return: 0 on success; error number otherwise 15519 */ 15520 int hdd_pktlog_enable_disable(struct hdd_context *hdd_ctx, 15521 bool enable_disable_flag, 15522 uint8_t user_triggered, int size) 15523 { 15524 struct sir_wifi_start_log start_log; 15525 QDF_STATUS status; 15526 15527 if (hdd_ctx->is_pktlog_enabled && enable_disable_flag) 15528 return 0; 15529 15530 if ((!hdd_ctx->is_pktlog_enabled) && (!enable_disable_flag)) 15531 return 0; 15532 15533 start_log.ring_id = RING_ID_PER_PACKET_STATS; 15534 start_log.verbose_level = 15535 enable_disable_flag ? 15536 WLAN_LOG_LEVEL_ACTIVE : WLAN_LOG_LEVEL_OFF; 15537 start_log.ini_triggered = cds_is_packet_log_enabled(); 15538 start_log.user_triggered = user_triggered; 15539 start_log.size = size; 15540 start_log.is_pktlog_buff_clear = false; 15541 /* 15542 * Use "is_iwpriv_command" flag to distinguish iwpriv command from other 15543 * commands. Host uses this flag to decide whether to send pktlog 15544 * disable command to fw without sending pktlog enable command 15545 * previously. For eg, If vendor sends pktlog disable command without 15546 * sending pktlog enable command, then host discards the packet 15547 * but for iwpriv command, host will send it to fw. 15548 */ 15549 start_log.is_iwpriv_command = 1; 15550 15551 status = sme_wifi_start_logger(hdd_ctx->mac_handle, start_log); 15552 if (!QDF_IS_STATUS_SUCCESS(status)) { 15553 hdd_err("sme_wifi_start_logger failed(err=%d)", status); 15554 hdd_exit(); 15555 return -EINVAL; 15556 } 15557 15558 hdd_ctx->is_pktlog_enabled = enable_disable_flag; 15559 15560 return 0; 15561 } 15562 #endif /* REMOVE_PKT_LOG */ 15563 15564 void hdd_free_mac_address_lists(struct hdd_context *hdd_ctx) 15565 { 15566 hdd_debug("Resetting MAC address lists"); 15567 qdf_mem_zero(hdd_ctx->provisioned_mac_addr, 15568 sizeof(hdd_ctx->provisioned_mac_addr)); 15569 qdf_mem_zero(hdd_ctx->derived_mac_addr, 15570 sizeof(hdd_ctx->derived_mac_addr)); 15571 hdd_ctx->num_provisioned_addr = 0; 15572 hdd_ctx->num_derived_addr = 0; 15573 hdd_ctx->provisioned_intf_addr_mask = 0; 15574 hdd_ctx->derived_intf_addr_mask = 0; 15575 } 15576 15577 /** 15578 * hdd_get_platform_wlan_mac_buff() - API to query platform driver 15579 * for MAC address 15580 * @dev: Device Pointer 15581 * @num: Number of Valid Mac address 15582 * 15583 * Return: Pointer to MAC address buffer 15584 */ 15585 static uint8_t *hdd_get_platform_wlan_mac_buff(struct device *dev, 15586 uint32_t *num) 15587 { 15588 return pld_get_wlan_mac_address(dev, num); 15589 } 15590 15591 /** 15592 * hdd_get_platform_wlan_derived_mac_buff() - API to query platform driver 15593 * for derived MAC address 15594 * @dev: Device Pointer 15595 * @num: Number of Valid Mac address 15596 * 15597 * Return: Pointer to MAC address buffer 15598 */ 15599 static uint8_t *hdd_get_platform_wlan_derived_mac_buff(struct device *dev, 15600 uint32_t *num) 15601 { 15602 return pld_get_wlan_derived_mac_address(dev, num); 15603 } 15604 15605 /** 15606 * hdd_populate_random_mac_addr() - API to populate random mac addresses 15607 * @hdd_ctx: HDD Context 15608 * @num: Number of random mac addresses needed 15609 * 15610 * Generate random addresses using bit manipulation on the base mac address 15611 * 15612 * Return: None 15613 */ 15614 void hdd_populate_random_mac_addr(struct hdd_context *hdd_ctx, uint32_t num) 15615 { 15616 uint32_t idx = hdd_ctx->num_derived_addr; 15617 uint32_t iter; 15618 uint8_t *buf = NULL; 15619 uint8_t macaddr_b3, tmp_br3; 15620 /* 15621 * Consider first provisioned mac address as source address to derive 15622 * remaining addresses 15623 */ 15624 15625 uint8_t *src = hdd_ctx->provisioned_mac_addr[0].bytes; 15626 15627 for (iter = 0; iter < num; ++iter, ++idx) { 15628 buf = hdd_ctx->derived_mac_addr[idx].bytes; 15629 qdf_mem_copy(buf, src, QDF_MAC_ADDR_SIZE); 15630 macaddr_b3 = buf[3]; 15631 tmp_br3 = ((macaddr_b3 >> 4 & INTF_MACADDR_MASK) + idx) & 15632 INTF_MACADDR_MASK; 15633 macaddr_b3 += tmp_br3; 15634 macaddr_b3 ^= (1 << INTF_MACADDR_MASK); 15635 buf[0] |= 0x02; 15636 buf[3] = macaddr_b3; 15637 hdd_debug(QDF_MAC_ADDR_FMT, QDF_MAC_ADDR_REF(buf)); 15638 hdd_ctx->num_derived_addr++; 15639 } 15640 } 15641 15642 /** 15643 * hdd_platform_wlan_mac() - API to get mac addresses from platform driver 15644 * @hdd_ctx: HDD Context 15645 * 15646 * API to get mac addresses from platform driver and update the driver 15647 * structures and configure FW with the base mac address. 15648 * Return: int 15649 */ 15650 static int hdd_platform_wlan_mac(struct hdd_context *hdd_ctx) 15651 { 15652 uint32_t no_of_mac_addr, iter; 15653 uint32_t max_mac_addr = QDF_MAX_CONCURRENCY_PERSONA; 15654 uint32_t mac_addr_size = QDF_MAC_ADDR_SIZE; 15655 uint8_t *addr, *buf; 15656 struct device *dev = hdd_ctx->parent_dev; 15657 tSirMacAddr mac_addr; 15658 QDF_STATUS status; 15659 15660 addr = hdd_get_platform_wlan_mac_buff(dev, &no_of_mac_addr); 15661 15662 if (no_of_mac_addr == 0 || !addr) { 15663 hdd_debug("No mac configured from platform driver"); 15664 return -EINVAL; 15665 } 15666 15667 hdd_free_mac_address_lists(hdd_ctx); 15668 15669 if (no_of_mac_addr > max_mac_addr) 15670 no_of_mac_addr = max_mac_addr; 15671 15672 qdf_mem_copy(&mac_addr, addr, mac_addr_size); 15673 15674 for (iter = 0; iter < no_of_mac_addr; ++iter, addr += mac_addr_size) { 15675 buf = hdd_ctx->provisioned_mac_addr[iter].bytes; 15676 qdf_mem_copy(buf, addr, QDF_MAC_ADDR_SIZE); 15677 hdd_info("provisioned MAC Addr [%d] "QDF_MAC_ADDR_FMT, iter, 15678 QDF_MAC_ADDR_REF(buf)); 15679 } 15680 15681 hdd_ctx->num_provisioned_addr = no_of_mac_addr; 15682 15683 if (hdd_ctx->config->mac_provision) { 15684 addr = hdd_get_platform_wlan_derived_mac_buff(dev, 15685 &no_of_mac_addr); 15686 15687 if (no_of_mac_addr == 0 || !addr) 15688 hdd_warn("No derived address from platform driver"); 15689 else if (no_of_mac_addr > 15690 (max_mac_addr - hdd_ctx->num_provisioned_addr)) 15691 no_of_mac_addr = (max_mac_addr - 15692 hdd_ctx->num_provisioned_addr); 15693 15694 for (iter = 0; iter < no_of_mac_addr; ++iter, 15695 addr += mac_addr_size) { 15696 buf = hdd_ctx->derived_mac_addr[iter].bytes; 15697 qdf_mem_copy(buf, addr, QDF_MAC_ADDR_SIZE); 15698 hdd_debug("derived MAC Addr [%d] "QDF_MAC_ADDR_FMT, iter, 15699 QDF_MAC_ADDR_REF(buf)); 15700 } 15701 hdd_ctx->num_derived_addr = no_of_mac_addr; 15702 } 15703 15704 no_of_mac_addr = hdd_ctx->num_provisioned_addr + 15705 hdd_ctx->num_derived_addr; 15706 if (no_of_mac_addr < max_mac_addr) 15707 hdd_populate_random_mac_addr(hdd_ctx, max_mac_addr - 15708 no_of_mac_addr); 15709 15710 status = sme_set_custom_mac_addr(mac_addr); 15711 if (!QDF_IS_STATUS_SUCCESS(status)) 15712 return -EAGAIN; 15713 15714 return 0; 15715 } 15716 15717 /** 15718 * hdd_update_mac_addr_to_fw() - API to update wlan mac addresses to FW 15719 * @hdd_ctx: HDD Context 15720 * 15721 * Update MAC address to FW. If MAC address passed by FW is invalid, host 15722 * will generate its own MAC and update it to FW. 15723 * 15724 * Return: 0 for success 15725 * Non-zero error code for failure 15726 */ 15727 static int hdd_update_mac_addr_to_fw(struct hdd_context *hdd_ctx) 15728 { 15729 tSirMacAddr custom_mac_addr; 15730 QDF_STATUS status; 15731 15732 if (hdd_ctx->num_provisioned_addr) 15733 qdf_mem_copy(&custom_mac_addr, 15734 &hdd_ctx->provisioned_mac_addr[0].bytes[0], 15735 sizeof(tSirMacAddr)); 15736 else 15737 qdf_mem_copy(&custom_mac_addr, 15738 &hdd_ctx->derived_mac_addr[0].bytes[0], 15739 sizeof(tSirMacAddr)); 15740 status = sme_set_custom_mac_addr(custom_mac_addr); 15741 if (!QDF_IS_STATUS_SUCCESS(status)) 15742 return -EAGAIN; 15743 return 0; 15744 } 15745 15746 /** 15747 * hdd_initialize_mac_address() - API to get wlan mac addresses 15748 * @hdd_ctx: HDD Context 15749 * 15750 * Get MAC addresses from platform driver or wlan_mac.bin. If platform driver 15751 * is provisioned with mac addresses, driver uses it, else it will use 15752 * wlan_mac.bin to update HW MAC addresses. 15753 * 15754 * Return: None 15755 */ 15756 static int hdd_initialize_mac_address(struct hdd_context *hdd_ctx) 15757 { 15758 QDF_STATUS status; 15759 int ret; 15760 15761 ret = hdd_platform_wlan_mac(hdd_ctx); 15762 if (!ret) { 15763 hdd_info("using MAC address from platform driver"); 15764 return ret; 15765 } else if (hdd_ctx->config->mac_provision) { 15766 hdd_err("getting MAC address from platform driver failed"); 15767 return ret; 15768 } 15769 15770 status = hdd_update_mac_config(hdd_ctx); 15771 if (QDF_IS_STATUS_SUCCESS(status)) { 15772 hdd_info("using MAC address from wlan_mac.bin"); 15773 return 0; 15774 } 15775 15776 hdd_info("using default MAC address"); 15777 15778 /* Use fw provided MAC */ 15779 if (!qdf_is_macaddr_zero(&hdd_ctx->hw_macaddr)) { 15780 hdd_update_macaddr(hdd_ctx, hdd_ctx->hw_macaddr, false); 15781 return 0; 15782 } else if (hdd_generate_macaddr_auto(hdd_ctx) != 0) { 15783 struct qdf_mac_addr mac_addr; 15784 15785 hdd_err("MAC failure from device serial no."); 15786 qdf_get_random_bytes(&mac_addr, sizeof(mac_addr)); 15787 /* 15788 * Reset multicast bit (bit-0) and set 15789 * locally-administered bit 15790 */ 15791 mac_addr.bytes[0] = 0x2; 15792 hdd_update_macaddr(hdd_ctx, mac_addr, true); 15793 } 15794 15795 ret = hdd_update_mac_addr_to_fw(hdd_ctx); 15796 if (ret) 15797 hdd_err("MAC address out-of-sync, ret:%d", ret); 15798 return ret; 15799 } 15800 15801 /* params being sent: 15802 * wmi_pdev_param_tx_chain_mask_1ss 15803 * wmi_pdev_param_mgmt_retry_limit 15804 * wmi_pdev_param_default_6ghz_rate 15805 * wmi_pdev_param_pdev_stats_tx_xretry_ext 15806 * wmi_pdev_param_smart_chainmask_scheme 15807 * wmi_pdev_param_alternative_chainmask_scheme 15808 * wmi_pdev_param_ani_enable 15809 * wmi_pdev_param_pcie_config 15810 */ 15811 /** 15812 * hdd_pre_enable_configure() - Configurations prior to cds_enable 15813 * @hdd_ctx: HDD context 15814 * 15815 * Pre configurations to be done at lower layer before calling cds enable. 15816 * 15817 * Return: 0 on success and errno on failure. 15818 */ 15819 static int hdd_pre_enable_configure(struct hdd_context *hdd_ctx) 15820 { 15821 int ret; 15822 uint8_t val = 0; 15823 uint8_t max_retry = 0; 15824 bool enable_he_mcs0_for_6ghz_mgmt = false; 15825 uint32_t tx_retry_multiplier; 15826 QDF_STATUS status; 15827 void *soc = cds_get_context(QDF_MODULE_ID_SOC); 15828 struct dev_set_param setparam[MAX_PDEV_PRE_ENABLE_PARAMS] = {}; 15829 bool check_value; 15830 uint8_t index = 0; 15831 15832 cdp_register_pause_cb(soc, wlan_hdd_txrx_pause_cb); 15833 hdd_tx_latency_register_cb(soc); 15834 15835 /* Register HL netdev flow control callback */ 15836 cdp_hl_fc_register(soc, OL_TXRX_PDEV_ID, wlan_hdd_txrx_pause_cb); 15837 /* Register rx mic error indication handler */ 15838 ucfg_dp_register_rx_mic_error_ind_handler(soc); 15839 15840 /* 15841 * Note that the cds_pre_enable() sequence triggers the cfg download. 15842 * The cfg download must occur before we update the SME config 15843 * since the SME config operation must access the cfg database 15844 */ 15845 status = hdd_set_sme_config(hdd_ctx); 15846 15847 if (QDF_STATUS_SUCCESS != status) { 15848 hdd_err("Failed hdd_set_sme_config: %d", status); 15849 ret = qdf_status_to_os_return(status); 15850 goto out; 15851 } 15852 15853 status = hdd_set_policy_mgr_user_cfg(hdd_ctx); 15854 if (QDF_STATUS_SUCCESS != status) { 15855 hdd_alert("Failed hdd_set_policy_mgr_user_cfg: %d", status); 15856 ret = qdf_status_to_os_return(status); 15857 goto out; 15858 } 15859 15860 status = ucfg_mlme_get_tx_chainmask_1ss(hdd_ctx->psoc, &val); 15861 if (QDF_STATUS_SUCCESS != status) { 15862 hdd_err("Get tx_chainmask_1ss from mlme failed"); 15863 ret = qdf_status_to_os_return(status); 15864 goto out; 15865 } 15866 ret = mlme_check_index_setparam(setparam, 15867 wmi_pdev_param_tx_chain_mask_1ss, 15868 val, index++, 15869 MAX_PDEV_PRE_ENABLE_PARAMS); 15870 if (QDF_IS_STATUS_ERROR(ret)) { 15871 hdd_err("failed at wmi_pdev_param_tx_chain_mask_1ss"); 15872 goto out; 15873 15874 } 15875 15876 wlan_mlme_get_mgmt_max_retry(hdd_ctx->psoc, &max_retry); 15877 ret = mlme_check_index_setparam(setparam, 15878 wmi_pdev_param_mgmt_retry_limit, 15879 max_retry, index++, 15880 MAX_PDEV_PRE_ENABLE_PARAMS); 15881 if (QDF_IS_STATUS_ERROR(ret)) { 15882 hdd_err("failed at wmi_pdev_param_mgmt_retry_limit"); 15883 goto out; 15884 } 15885 15886 wlan_mlme_get_mgmt_6ghz_rate_support(hdd_ctx->psoc, 15887 &enable_he_mcs0_for_6ghz_mgmt); 15888 if (enable_he_mcs0_for_6ghz_mgmt) { 15889 hdd_debug("HE rates for 6GHz mgmt frames are supported"); 15890 ret = mlme_check_index_setparam( 15891 setparam, 15892 wmi_pdev_param_default_6ghz_rate, 15893 MGMT_DEFAULT_DATA_RATE_6GHZ, index++, 15894 MAX_PDEV_PRE_ENABLE_PARAMS); 15895 if (QDF_IS_STATUS_ERROR(ret)) { 15896 hdd_err("wmi_pdev_param_default_6ghz_rate failed %d", 15897 ret); 15898 goto out; 15899 } 15900 } 15901 15902 wlan_mlme_get_tx_retry_multiplier(hdd_ctx->psoc, 15903 &tx_retry_multiplier); 15904 ret = mlme_check_index_setparam(setparam, 15905 wmi_pdev_param_pdev_stats_tx_xretry_ext, 15906 tx_retry_multiplier, index++, 15907 MAX_PDEV_PRE_ENABLE_PARAMS); 15908 if (QDF_IS_STATUS_ERROR(ret)) { 15909 hdd_err("failed at wmi_pdev_param_pdev_stats_tx_xretry_ext"); 15910 goto out; 15911 } 15912 15913 ret = ucfg_get_smart_chainmask_enabled(hdd_ctx->psoc, 15914 &check_value); 15915 if (QDF_IS_STATUS_SUCCESS(ret)) { 15916 ret = mlme_check_index_setparam( 15917 setparam, 15918 wmi_pdev_param_smart_chainmask_scheme, 15919 (int)check_value, index++, 15920 MAX_PDEV_PRE_ENABLE_PARAMS); 15921 if (QDF_IS_STATUS_ERROR(ret)) { 15922 hdd_err("failed to set wmi_pdev_param_smart_chainmask_scheme"); 15923 goto out; 15924 } 15925 } 15926 15927 ret = ucfg_get_alternative_chainmask_enabled(hdd_ctx->psoc, 15928 &check_value); 15929 if (QDF_IS_STATUS_SUCCESS(ret)) { 15930 ret = mlme_check_index_setparam( 15931 setparam, 15932 wmi_pdev_param_alternative_chainmask_scheme, 15933 (int)check_value, index++, 15934 MAX_PDEV_PRE_ENABLE_PARAMS); 15935 if (QDF_IS_STATUS_ERROR(ret)) { 15936 hdd_err("failed to set wmi_pdev_param_alternative_chainmask_scheme"); 15937 goto out; 15938 } 15939 } 15940 15941 ret = ucfg_fwol_get_ani_enabled(hdd_ctx->psoc, &check_value); 15942 if (QDF_IS_STATUS_SUCCESS(ret)) { 15943 ret = mlme_check_index_setparam(setparam, 15944 wmi_pdev_param_ani_enable, 15945 (int)check_value, index++, 15946 MAX_PDEV_PRE_ENABLE_PARAMS); 15947 if (QDF_IS_STATUS_ERROR(ret)) { 15948 hdd_err("failed to set wmi_pdev_param_ani_enable"); 15949 goto out; 15950 } 15951 } 15952 15953 ret = hdd_set_pcie_params(hdd_ctx, index, setparam); 15954 if (QDF_IS_STATUS_ERROR(ret)) 15955 goto out; 15956 else 15957 index++; 15958 ret = sme_send_multi_pdev_vdev_set_params(MLME_PDEV_SETPARAM, 15959 WMI_PDEV_ID_SOC, setparam, 15960 index); 15961 if (QDF_IS_STATUS_ERROR(ret)) { 15962 hdd_err("failed to send pdev set params"); 15963 goto out; 15964 } 15965 15966 /* Configure global firmware params */ 15967 ret = ucfg_fwol_configure_global_params(hdd_ctx->psoc, hdd_ctx->pdev); 15968 if (ret) 15969 goto out; 15970 15971 status = hdd_set_sme_chan_list(hdd_ctx); 15972 if (status != QDF_STATUS_SUCCESS) { 15973 hdd_err("Failed to init channel list: %d", status); 15974 ret = qdf_status_to_os_return(status); 15975 goto out; 15976 } 15977 15978 if (!hdd_update_config_cfg(hdd_ctx)) { 15979 hdd_err("config update failed"); 15980 ret = -EINVAL; 15981 goto out; 15982 } 15983 hdd_init_channel_avoidance(hdd_ctx); 15984 15985 out: 15986 return ret; 15987 } 15988 15989 #ifdef FEATURE_P2P_LISTEN_OFFLOAD 15990 /** 15991 * wlan_hdd_p2p_lo_event_callback - P2P listen offload stop event handler 15992 * @context: context registered with sme_register_p2p_lo_event(). HDD 15993 * always registers a hdd context pointer 15994 * @evt:event structure pointer 15995 * 15996 * This is the p2p listen offload stop event handler, it sends vendor 15997 * event back to supplicant to notify the stop reason. 15998 * 15999 * Return: None 16000 */ 16001 static void wlan_hdd_p2p_lo_event_callback(void *context, 16002 struct sir_p2p_lo_event *evt) 16003 { 16004 struct hdd_context *hdd_ctx = context; 16005 struct sk_buff *vendor_event; 16006 enum qca_nl80211_vendor_subcmds_index index = 16007 QCA_NL80211_VENDOR_SUBCMD_P2P_LO_EVENT_INDEX; 16008 struct wlan_hdd_link_info *link_info; 16009 16010 hdd_enter(); 16011 16012 if (!hdd_ctx) { 16013 hdd_err("Invalid HDD context pointer"); 16014 return; 16015 } 16016 16017 link_info = hdd_get_link_info_by_vdev(hdd_ctx, evt->vdev_id); 16018 if (!link_info) { 16019 hdd_err("Cannot find adapter by vdev_id = %d", 16020 evt->vdev_id); 16021 return; 16022 } 16023 16024 vendor_event = 16025 wlan_cfg80211_vendor_event_alloc(hdd_ctx->wiphy, 16026 &link_info->adapter->wdev, 16027 sizeof(uint32_t) + 16028 NLMSG_HDRLEN, 16029 index, GFP_KERNEL); 16030 if (!vendor_event) { 16031 hdd_err("wlan_cfg80211_vendor_event_alloc failed"); 16032 return; 16033 } 16034 16035 if (nla_put_u32(vendor_event, 16036 QCA_WLAN_VENDOR_ATTR_P2P_LISTEN_OFFLOAD_STOP_REASON, 16037 evt->reason_code)) { 16038 hdd_err("nla put failed"); 16039 wlan_cfg80211_vendor_free_skb(vendor_event); 16040 return; 16041 } 16042 16043 wlan_cfg80211_vendor_event(vendor_event, GFP_KERNEL); 16044 hdd_debug("Sent P2P_LISTEN_OFFLOAD_STOP event for vdev_id = %d", 16045 evt->vdev_id); 16046 } 16047 #else 16048 static void wlan_hdd_p2p_lo_event_callback(void *context, 16049 struct sir_p2p_lo_event *evt) 16050 { 16051 } 16052 #endif 16053 16054 #ifdef FEATURE_WLAN_DYNAMIC_CVM 16055 static inline int hdd_set_vc_mode_config(struct hdd_context *hdd_ctx) 16056 { 16057 return sme_set_vc_mode_config(hdd_ctx->config->vc_mode_cfg_bitmap); 16058 } 16059 #else 16060 static inline int hdd_set_vc_mode_config(struct hdd_context *hdd_ctx) 16061 { 16062 return QDF_STATUS_SUCCESS; 16063 } 16064 #endif 16065 16066 /** 16067 * hdd_adaptive_dwelltime_init() - initialization for adaptive dwell time config 16068 * @hdd_ctx: HDD context 16069 * 16070 * This function sends the adaptive dwell time config configuration to the 16071 * firmware via WMA 16072 * 16073 * Return: 0 - success, < 0 - failure 16074 */ 16075 static int hdd_adaptive_dwelltime_init(struct hdd_context *hdd_ctx) 16076 { 16077 QDF_STATUS status; 16078 struct adaptive_dwelltime_params dwelltime_params; 16079 16080 status = ucfg_fwol_get_all_adaptive_dwelltime_params(hdd_ctx->psoc, 16081 &dwelltime_params); 16082 status = ucfg_fwol_set_adaptive_dwelltime_config(&dwelltime_params); 16083 16084 hdd_debug("Sending Adaptive Dwelltime Configuration to fw"); 16085 if (!QDF_IS_STATUS_SUCCESS(status)) { 16086 hdd_err("Failed to send Adaptive Dwelltime configuration!"); 16087 return -EAGAIN; 16088 } 16089 return 0; 16090 } 16091 16092 int hdd_dbs_scan_selection_init(struct hdd_context *hdd_ctx) 16093 { 16094 QDF_STATUS status; 16095 struct wmi_dbs_scan_sel_params dbs_scan_params; 16096 uint32_t i = 0; 16097 uint8_t count = 0, numentries = 0; 16098 uint8_t dual_mac_feature; 16099 uint8_t dbs_scan_config[CDS_DBS_SCAN_PARAM_PER_CLIENT 16100 * CDS_DBS_SCAN_CLIENTS_MAX]; 16101 16102 status = ucfg_policy_mgr_get_dual_mac_feature(hdd_ctx->psoc, 16103 &dual_mac_feature); 16104 16105 if (status != QDF_STATUS_SUCCESS) { 16106 hdd_err("can't get dual mac feature flag"); 16107 return -EINVAL; 16108 } 16109 /* check if DBS is enabled or supported */ 16110 if ((dual_mac_feature == DISABLE_DBS_CXN_AND_SCAN) || 16111 (dual_mac_feature == ENABLE_DBS_CXN_AND_DISABLE_DBS_SCAN)) 16112 return -EINVAL; 16113 16114 hdd_string_to_u8_array(hdd_ctx->config->dbs_scan_selection, 16115 dbs_scan_config, &numentries, 16116 (CDS_DBS_SCAN_PARAM_PER_CLIENT 16117 * CDS_DBS_SCAN_CLIENTS_MAX)); 16118 16119 if (!numentries) { 16120 hdd_debug("Do not send scan_selection_config"); 16121 return 0; 16122 } 16123 16124 /* hdd_set_fw_log_params */ 16125 dbs_scan_params.num_clients = 0; 16126 while (count < (numentries - 2)) { 16127 dbs_scan_params.module_id[i] = dbs_scan_config[count]; 16128 dbs_scan_params.num_dbs_scans[i] = dbs_scan_config[count + 1]; 16129 dbs_scan_params.num_non_dbs_scans[i] = 16130 dbs_scan_config[count + 2]; 16131 dbs_scan_params.num_clients++; 16132 hdd_debug("module:%d NDS:%d NNDS:%d", 16133 dbs_scan_params.module_id[i], 16134 dbs_scan_params.num_dbs_scans[i], 16135 dbs_scan_params.num_non_dbs_scans[i]); 16136 count += CDS_DBS_SCAN_PARAM_PER_CLIENT; 16137 i++; 16138 } 16139 16140 dbs_scan_params.pdev_id = 0; 16141 16142 hdd_debug("clients:%d pdev:%d", 16143 dbs_scan_params.num_clients, dbs_scan_params.pdev_id); 16144 16145 status = sme_set_dbs_scan_selection_config(hdd_ctx->mac_handle, 16146 &dbs_scan_params); 16147 hdd_debug("Sending DBS Scan Selection Configuration to fw"); 16148 if (!QDF_IS_STATUS_SUCCESS(status)) { 16149 hdd_err("Failed to send DBS Scan selection configuration!"); 16150 return -EAGAIN; 16151 } 16152 return 0; 16153 } 16154 16155 #ifdef FEATURE_WLAN_AUTO_SHUTDOWN 16156 /** 16157 * hdd_set_auto_shutdown_cb() - Set auto shutdown callback 16158 * @hdd_ctx: HDD context 16159 * 16160 * Set auto shutdown callback to get indications from firmware to indicate 16161 * userspace to shutdown WLAN after a configured amount of inactivity. 16162 * 16163 * Return: 0 on success and errno on failure. 16164 */ 16165 static int hdd_set_auto_shutdown_cb(struct hdd_context *hdd_ctx) 16166 { 16167 QDF_STATUS status; 16168 16169 if (!hdd_ctx->config->wlan_auto_shutdown) 16170 return 0; 16171 16172 status = sme_set_auto_shutdown_cb(hdd_ctx->mac_handle, 16173 wlan_hdd_auto_shutdown_cb); 16174 if (status != QDF_STATUS_SUCCESS) 16175 hdd_err("Auto shutdown feature could not be enabled: %d", 16176 status); 16177 16178 return qdf_status_to_os_return(status); 16179 } 16180 #else 16181 static int hdd_set_auto_shutdown_cb(struct hdd_context *hdd_ctx) 16182 { 16183 return 0; 16184 } 16185 #endif 16186 16187 #ifdef MWS_COEX 16188 #define MAX_PDEV_MWSCOEX_PARAMS 4 16189 /* params being sent: 16190 * wmi_pdev_param_mwscoex_4g_allow_quick_ftdm 16191 * wmi_pdev_param_mwscoex_set_5gnr_pwr_limit 16192 * wmi_pdev_param_mwscoex_pcc_chavd_delay 16193 * wmi_pdev_param_mwscoex_scc_chavd_delay 16194 */ 16195 16196 /** 16197 * hdd_init_mws_coex() - Initialize MWS coex configurations 16198 * @hdd_ctx: HDD context 16199 * 16200 * This function sends MWS-COEX 4G quick FTDM and 16201 * MWS-COEX 5G-NR power limit to FW 16202 * 16203 * Return: 0 on success and errno on failure. 16204 */ 16205 static int hdd_init_mws_coex(struct hdd_context *hdd_ctx) 16206 { 16207 int ret = 0; 16208 uint32_t mws_coex_4g_quick_tdm = 0, mws_coex_5g_nr_pwr_limit = 0; 16209 uint32_t mws_coex_pcc_channel_avoid_delay = 0; 16210 uint32_t mws_coex_scc_channel_avoid_delay = 0; 16211 struct dev_set_param setparam[MAX_PDEV_MWSCOEX_PARAMS] = {}; 16212 uint8_t index = 0; 16213 16214 ucfg_mlme_get_mws_coex_4g_quick_tdm(hdd_ctx->psoc, 16215 &mws_coex_4g_quick_tdm); 16216 ret = mlme_check_index_setparam( 16217 setparam, 16218 wmi_pdev_param_mwscoex_4g_allow_quick_ftdm, 16219 mws_coex_4g_quick_tdm, index++, 16220 MAX_PDEV_MWSCOEX_PARAMS); 16221 if (QDF_IS_STATUS_ERROR(ret)) { 16222 hdd_err("failed at wmi_pdev_param_mwscoex_4g_allow_quick_ftdm"); 16223 goto error; 16224 } 16225 16226 ucfg_mlme_get_mws_coex_5g_nr_pwr_limit(hdd_ctx->psoc, 16227 &mws_coex_5g_nr_pwr_limit); 16228 ret = mlme_check_index_setparam( 16229 setparam, 16230 wmi_pdev_param_mwscoex_set_5gnr_pwr_limit, 16231 mws_coex_5g_nr_pwr_limit, index++, 16232 MAX_PDEV_MWSCOEX_PARAMS); 16233 if (QDF_IS_STATUS_ERROR(ret)) { 16234 hdd_err("failed at wmi_pdev_param_mwscoex_set_5gnr_pwr_limit"); 16235 goto error; 16236 } 16237 16238 ucfg_mlme_get_mws_coex_pcc_channel_avoid_delay( 16239 hdd_ctx->psoc, 16240 &mws_coex_pcc_channel_avoid_delay); 16241 ret = mlme_check_index_setparam(setparam, 16242 wmi_pdev_param_mwscoex_pcc_chavd_delay, 16243 mws_coex_pcc_channel_avoid_delay, 16244 index++, MAX_PDEV_MWSCOEX_PARAMS); 16245 if (QDF_IS_STATUS_ERROR(ret)) { 16246 hdd_err("failed at wmi_pdev_param_mwscoex_pcc_chavd_delay"); 16247 goto error; 16248 } 16249 16250 ucfg_mlme_get_mws_coex_scc_channel_avoid_delay( 16251 hdd_ctx->psoc, 16252 &mws_coex_scc_channel_avoid_delay); 16253 ret = mlme_check_index_setparam(setparam, 16254 wmi_pdev_param_mwscoex_scc_chavd_delay, 16255 mws_coex_scc_channel_avoid_delay, 16256 index++, MAX_PDEV_MWSCOEX_PARAMS); 16257 if (QDF_IS_STATUS_ERROR(ret)) { 16258 hdd_err("failed at wmi_pdev_param_mwscoex_scc_chavd_delay"); 16259 goto error; 16260 } 16261 ret = sme_send_multi_pdev_vdev_set_params(MLME_PDEV_SETPARAM, 16262 WMI_PDEV_ID_SOC, setparam, 16263 index); 16264 if (QDF_IS_STATUS_ERROR(ret)) 16265 hdd_err("failed to send pdev MWSCOEX set params"); 16266 error: 16267 return ret; 16268 } 16269 #else 16270 static int hdd_init_mws_coex(struct hdd_context *hdd_ctx) 16271 { 16272 return 0; 16273 } 16274 #endif 16275 16276 #ifdef THERMAL_STATS_SUPPORT 16277 static void hdd_thermal_stats_cmd_init(struct hdd_context *hdd_ctx) 16278 { 16279 hdd_send_get_thermal_stats_cmd(hdd_ctx, thermal_stats_init, NULL, NULL); 16280 } 16281 #else 16282 static void hdd_thermal_stats_cmd_init(struct hdd_context *hdd_ctx) 16283 { 16284 } 16285 #endif 16286 16287 #ifdef WLAN_FEATURE_CAL_FAILURE_TRIGGER 16288 /** 16289 * hdd_cal_fail_send_event()- send calibration failure information 16290 * @cal_type: calibration type 16291 * @reason: reason for calibration failure 16292 * 16293 * This Function sends calibration failure diag event 16294 * 16295 * Return: void. 16296 */ 16297 static void hdd_cal_fail_send_event(uint8_t cal_type, uint8_t reason) 16298 { 16299 /* 16300 * For now we are going with the print. Once CST APK has support to 16301 * read the diag events then we will add the diag event here. 16302 */ 16303 hdd_debug("Received cal failure event with cal_type:%x reason:%x", 16304 cal_type, reason); 16305 } 16306 #else 16307 static inline void hdd_cal_fail_send_event(uint8_t cal_type, uint8_t reason) 16308 { 16309 } 16310 #endif 16311 16312 /** 16313 * hdd_features_init() - Init features 16314 * @hdd_ctx: HDD context 16315 * 16316 * Initialize features and their feature context after WLAN firmware is up. 16317 * 16318 * Return: 0 on success and errno on failure. 16319 */ 16320 static int hdd_features_init(struct hdd_context *hdd_ctx) 16321 { 16322 struct tx_power_limit hddtxlimit; 16323 QDF_STATUS status; 16324 int ret; 16325 mac_handle_t mac_handle; 16326 bool b_cts2self, is_imps_enabled; 16327 bool rf_test_mode; 16328 bool std_6ghz_conn_policy; 16329 uint32_t fw_data_stall_evt; 16330 bool disable_vlp_sta_conn_sp_ap; 16331 16332 hdd_enter(); 16333 16334 ret = hdd_init_mws_coex(hdd_ctx); 16335 if (ret) 16336 hdd_warn("Error initializing mws-coex"); 16337 16338 /* FW capabilities received, Set the Dot11 mode */ 16339 mac_handle = hdd_ctx->mac_handle; 16340 sme_setdef_dot11mode(mac_handle); 16341 16342 ucfg_mlme_is_imps_enabled(hdd_ctx->psoc, &is_imps_enabled); 16343 hdd_set_idle_ps_config(hdd_ctx, is_imps_enabled); 16344 16345 fw_data_stall_evt = ucfg_dp_fw_data_stall_evt_enabled(); 16346 16347 /* Send Enable/Disable data stall detection cmd to FW */ 16348 sme_cli_set_command(0, wmi_pdev_param_data_stall_detect_enable, 16349 fw_data_stall_evt, PDEV_CMD); 16350 16351 ucfg_mlme_get_go_cts2self_for_sta(hdd_ctx->psoc, &b_cts2self); 16352 if (b_cts2self) 16353 sme_set_cts2self_for_p2p_go(mac_handle); 16354 16355 if (hdd_set_vc_mode_config(hdd_ctx)) 16356 hdd_warn("Error in setting Voltage Corner mode config to FW"); 16357 16358 if (ucfg_dp_rx_ol_init(hdd_ctx->psoc, hdd_ctx->is_wifi3_0_target)) 16359 hdd_err("Unable to initialize Rx LRO/GRO in fw"); 16360 16361 if (hdd_adaptive_dwelltime_init(hdd_ctx)) 16362 hdd_err("Unable to send adaptive dwelltime setting to FW"); 16363 16364 if (hdd_dbs_scan_selection_init(hdd_ctx)) 16365 hdd_err("Unable to send DBS scan selection setting to FW"); 16366 16367 ret = hdd_init_thermal_info(hdd_ctx); 16368 if (ret) { 16369 hdd_err("Error while initializing thermal information"); 16370 return ret; 16371 } 16372 16373 /** 16374 * In case of SSR/PDR, if pktlog was enabled manually before 16375 * SSR/PDR, then enable it again automatically after Wlan 16376 * device up. 16377 * During SSR/PDR, pktlog will be disabled as part of 16378 * hdd_features_deinit if pktlog is enabled in ini. 16379 * Re-enable pktlog in SSR case, if pktlog is enabled in ini. 16380 */ 16381 if (hdd_get_conparam() != QDF_GLOBAL_MONITOR_MODE && 16382 (cds_is_packet_log_enabled() || 16383 (cds_is_driver_recovering() && hdd_ctx->is_pktlog_enabled))) 16384 hdd_pktlog_enable_disable(hdd_ctx, true, 0, 0); 16385 16386 hddtxlimit.txPower2g = ucfg_get_tx_power(hdd_ctx->psoc, BAND_2G); 16387 hddtxlimit.txPower5g = ucfg_get_tx_power(hdd_ctx->psoc, BAND_5G); 16388 status = sme_txpower_limit(mac_handle, &hddtxlimit); 16389 if (!QDF_IS_STATUS_SUCCESS(status)) 16390 hdd_err("Error setting txlimit in sme: %d", status); 16391 16392 wlan_hdd_tsf_init(hdd_ctx); 16393 16394 status = sme_enable_disable_chanavoidind_event(mac_handle, 0); 16395 if (QDF_IS_STATUS_ERROR(status) && (status != QDF_STATUS_E_NOSUPPORT)) { 16396 hdd_err("Failed to disable Chan Avoidance Indication"); 16397 return -EINVAL; 16398 } 16399 16400 /* register P2P Listen Offload event callback */ 16401 if (wma_is_p2p_lo_capable()) 16402 sme_register_p2p_lo_event(mac_handle, hdd_ctx, 16403 wlan_hdd_p2p_lo_event_callback); 16404 wlan_hdd_register_mcc_quota_event_callback(hdd_ctx); 16405 ret = hdd_set_auto_shutdown_cb(hdd_ctx); 16406 16407 if (ret) 16408 return -EINVAL; 16409 16410 wlan_hdd_init_chan_info(hdd_ctx); 16411 wlan_hdd_twt_init(hdd_ctx); 16412 wlan_hdd_gpio_wakeup_init(hdd_ctx); 16413 16414 status = ucfg_mlme_is_rf_test_mode_enabled(hdd_ctx->psoc, 16415 &rf_test_mode); 16416 if (!QDF_IS_STATUS_SUCCESS(status)) { 16417 hdd_err("Get rf test mode failed"); 16418 return QDF_STATUS_E_FAILURE; 16419 } 16420 16421 if (rf_test_mode) { 16422 wlan_cm_set_check_6ghz_security(hdd_ctx->psoc, false); 16423 wlan_cm_set_6ghz_key_mgmt_mask(hdd_ctx->psoc, 16424 DEFAULT_KEYMGMT_6G_MASK); 16425 } 16426 16427 status = ucfg_mlme_is_standard_6ghz_conn_policy_enabled(hdd_ctx->psoc, 16428 &std_6ghz_conn_policy); 16429 16430 if (!QDF_IS_STATUS_SUCCESS(status)) { 16431 hdd_err("Get 6ghz standard connection policy failed"); 16432 return QDF_STATUS_E_FAILURE; 16433 } 16434 if (std_6ghz_conn_policy) 16435 wlan_cm_set_standard_6ghz_conn_policy(hdd_ctx->psoc, true); 16436 16437 status = ucfg_mlme_is_disable_vlp_sta_conn_to_sp_ap_enabled( 16438 hdd_ctx->psoc, 16439 &disable_vlp_sta_conn_sp_ap); 16440 if (!QDF_IS_STATUS_SUCCESS(status)) { 16441 hdd_err("Get disable vlp sta conn to sp flag failed"); 16442 return QDF_STATUS_E_FAILURE; 16443 } 16444 16445 if (disable_vlp_sta_conn_sp_ap) 16446 wlan_cm_set_disable_vlp_sta_conn_to_sp_ap(hdd_ctx->psoc, true); 16447 16448 hdd_thermal_stats_cmd_init(hdd_ctx); 16449 sme_set_cal_failure_event_cb(hdd_ctx->mac_handle, 16450 hdd_cal_fail_send_event); 16451 16452 hdd_exit(); 16453 return 0; 16454 } 16455 16456 /** 16457 * hdd_register_bcn_cb() - register scan beacon callback 16458 * @hdd_ctx: Pointer to the HDD context 16459 * 16460 * Return: QDF_STATUS 16461 */ 16462 static inline QDF_STATUS hdd_register_bcn_cb(struct hdd_context *hdd_ctx) 16463 { 16464 QDF_STATUS status; 16465 16466 status = ucfg_scan_register_bcn_cb(hdd_ctx->psoc, 16467 wlan_cfg80211_inform_bss_frame, 16468 SCAN_CB_TYPE_INFORM_BCN); 16469 if (!QDF_IS_STATUS_SUCCESS(status)) { 16470 hdd_err("failed to register SCAN_CB_TYPE_INFORM_BCN with status code %08d [x%08x]", 16471 status, status); 16472 return status; 16473 } 16474 16475 status = ucfg_scan_register_bcn_cb(hdd_ctx->psoc, 16476 wlan_cfg80211_unlink_bss_list, 16477 SCAN_CB_TYPE_UNLINK_BSS); 16478 if (!QDF_IS_STATUS_SUCCESS(status)) { 16479 hdd_err("failed to refister SCAN_CB_TYPE_FLUSH_BSS with status code %08d [x%08x]", 16480 status, status); 16481 return status; 16482 } 16483 16484 return QDF_STATUS_SUCCESS; 16485 } 16486 16487 /** 16488 * hdd_v2_flow_pool_map() - Flow pool create callback when vdev is active 16489 * @vdev_id: vdev_id, corresponds to flow_pool 16490 * 16491 * Return: none. 16492 */ 16493 static void hdd_v2_flow_pool_map(int vdev_id) 16494 { 16495 QDF_STATUS status; 16496 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 16497 struct wlan_objmgr_vdev *vdev; 16498 16499 if (!hdd_ctx) { 16500 hdd_err("HDD context null"); 16501 return; 16502 } 16503 16504 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(hdd_ctx->psoc, vdev_id, 16505 WLAN_OSIF_ID); 16506 if (!vdev) { 16507 hdd_err("Invalid VDEV %d", vdev_id); 16508 return; 16509 } 16510 16511 if (wlan_vdev_mlme_is_mlo_link_switch_in_progress(vdev) || 16512 policy_mgr_is_set_link_in_progress(wlan_vdev_get_psoc(vdev))) { 16513 hdd_info_rl("Link switch/set_link is ongoing, do not invoke flow pool map"); 16514 goto release_ref; 16515 } 16516 16517 status = cdp_flow_pool_map(cds_get_context(QDF_MODULE_ID_SOC), 16518 OL_TXRX_PDEV_ID, vdev_id); 16519 /* 16520 * For Adrastea flow control v2 is based on FW MAP events, 16521 * so this above callback is not implemented. 16522 * Hence this is not actual failure. Dont return failure 16523 */ 16524 if ((status != QDF_STATUS_SUCCESS) && 16525 (status != QDF_STATUS_E_INVAL)) { 16526 hdd_err("vdev_id: %d, failed to create flow pool status %d", 16527 vdev_id, status); 16528 } 16529 16530 release_ref: 16531 wlan_objmgr_vdev_release_ref(vdev, WLAN_OSIF_ID); 16532 } 16533 16534 /** 16535 * hdd_v2_flow_pool_unmap() - Flow pool create callback when vdev is not active 16536 * @vdev_id: vdev_id, corresponds to flow_pool 16537 * 16538 * Return: none. 16539 */ 16540 static void hdd_v2_flow_pool_unmap(int vdev_id) 16541 { 16542 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 16543 struct wlan_objmgr_vdev *vdev; 16544 16545 if (!hdd_ctx) { 16546 hdd_err("HDD context null"); 16547 return; 16548 } 16549 16550 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(hdd_ctx->psoc, vdev_id, 16551 WLAN_OSIF_ID); 16552 if (!vdev) { 16553 hdd_err("Invalid VDEV %d", vdev_id); 16554 return; 16555 } 16556 16557 if (wlan_vdev_mlme_is_mlo_link_switch_in_progress(vdev)) { 16558 hdd_info("Link switch ongoing do not invoke flow pool unmap"); 16559 goto release_ref; 16560 } 16561 16562 cdp_flow_pool_unmap(cds_get_context(QDF_MODULE_ID_SOC), 16563 OL_TXRX_PDEV_ID, vdev_id); 16564 release_ref: 16565 wlan_objmgr_vdev_release_ref(vdev, WLAN_OSIF_ID); 16566 } 16567 16568 static void hdd_hastings_bt_war_initialize(struct hdd_context *hdd_ctx) 16569 { 16570 if (hdd_ctx->config->iface_change_wait_time) 16571 hdd_hastings_bt_war_disable_fw(hdd_ctx); 16572 else 16573 hdd_hastings_bt_war_enable_fw(hdd_ctx); 16574 } 16575 16576 #define MAX_PDEV_CFG_CDS_PARAMS 8 16577 /* params being sent: 16578 * wmi_pdev_param_set_iot_pattern 16579 * wmi_pdev_param_max_mpdus_in_ampdu 16580 * wmi_pdev_param_enable_rts_sifs_bursting 16581 * wmi_pdev_param_peer_stats_info_enable 16582 * wmi_pdev_param_abg_mode_tx_chain_num 16583 * wmi_pdev_param_gcmp_support_enable 16584 * wmi_pdev_auto_detect_power_failure 16585 * wmi_pdev_param_fast_pwr_transition 16586 */ 16587 16588 /** 16589 * hdd_configure_cds() - Configure cds modules 16590 * @hdd_ctx: HDD context 16591 * 16592 * Enable Cds modules after WLAN firmware is up. 16593 * 16594 * Return: 0 on success and errno on failure. 16595 */ 16596 int hdd_configure_cds(struct hdd_context *hdd_ctx) 16597 { 16598 int ret; 16599 QDF_STATUS status; 16600 int set_value; 16601 mac_handle_t mac_handle; 16602 bool enable_rts_sifsbursting; 16603 uint8_t enable_phy_reg_retention; 16604 uint8_t max_mpdus_inampdu, is_force_1x1 = 0; 16605 uint32_t num_abg_tx_chains = 0; 16606 uint16_t num_11b_tx_chains = 0; 16607 uint16_t num_11ag_tx_chains = 0; 16608 struct policy_mgr_dp_cbacks dp_cbs = {0}; 16609 bool value; 16610 enum pmo_auto_pwr_detect_failure_mode auto_power_fail_mode; 16611 bool bval = false; 16612 uint8_t max_index = MAX_PDEV_CFG_CDS_PARAMS; 16613 struct dev_set_param setparam[MAX_PDEV_CFG_CDS_PARAMS] = {}; 16614 uint8_t index = 0; 16615 uint8_t next_index = 0; 16616 mac_handle = hdd_ctx->mac_handle; 16617 16618 status = ucfg_policy_mgr_get_force_1x1(hdd_ctx->psoc, &is_force_1x1); 16619 if (status != QDF_STATUS_SUCCESS) { 16620 hdd_err("Failed to get force 1x1 value"); 16621 goto out; 16622 } 16623 if (is_force_1x1) { 16624 status = mlme_check_index_setparam( 16625 setparam, 16626 wmi_pdev_param_set_iot_pattern, 16627 1, index++, 16628 max_index); 16629 if (QDF_IS_STATUS_ERROR(status)) { 16630 hdd_err("failed at wmi_pdev_param_set_iot_pattern"); 16631 goto out; 16632 } 16633 } 16634 /* set chip power save failure detected callback */ 16635 sme_set_chip_pwr_save_fail_cb(mac_handle, 16636 hdd_chip_pwr_save_fail_detected_cb); 16637 16638 status = ucfg_get_max_mpdus_inampdu(hdd_ctx->psoc, 16639 &max_mpdus_inampdu); 16640 if (status) { 16641 hdd_err("Failed to get max mpdus in ampdu value"); 16642 goto out; 16643 } 16644 16645 if (max_mpdus_inampdu) { 16646 set_value = max_mpdus_inampdu; 16647 status = mlme_check_index_setparam( 16648 setparam, 16649 wmi_pdev_param_max_mpdus_in_ampdu, 16650 set_value, index++, 16651 max_index); 16652 if (QDF_IS_STATUS_ERROR(status)) { 16653 hdd_err("failed at wmi_pdev_param_max_mpdus_in_ampdu"); 16654 goto out; 16655 } 16656 } 16657 16658 status = ucfg_get_enable_rts_sifsbursting(hdd_ctx->psoc, 16659 &enable_rts_sifsbursting); 16660 if (status) { 16661 hdd_err("Failed to get rts sifs bursting value"); 16662 goto out; 16663 } 16664 16665 if (enable_rts_sifsbursting) { 16666 set_value = enable_rts_sifsbursting; 16667 status = mlme_check_index_setparam( 16668 setparam, 16669 wmi_pdev_param_enable_rts_sifs_bursting, 16670 set_value, index++, 16671 max_index); 16672 if (QDF_IS_STATUS_ERROR(status)) { 16673 hdd_err("Failed at wmi_pdev_param_enable_rts_sifs_bursting"); 16674 goto out; 16675 } 16676 } 16677 16678 ucfg_mlme_get_sap_get_peer_info(hdd_ctx->psoc, &value); 16679 if (value) { 16680 set_value = value; 16681 status = mlme_check_index_setparam( 16682 setparam, 16683 wmi_pdev_param_peer_stats_info_enable, 16684 set_value, index++, 16685 max_index); 16686 if (QDF_IS_STATUS_ERROR(status)) { 16687 hdd_err("Failed at wmi_pdev_param_peer_stats_info_enable"); 16688 goto out; 16689 } 16690 } 16691 16692 status = ucfg_mlme_get_num_11b_tx_chains(hdd_ctx->psoc, 16693 &num_11b_tx_chains); 16694 if (status != QDF_STATUS_SUCCESS) { 16695 hdd_err("Failed to get num_11b_tx_chains"); 16696 goto out; 16697 } 16698 16699 status = ucfg_mlme_get_num_11ag_tx_chains(hdd_ctx->psoc, 16700 &num_11ag_tx_chains); 16701 if (status != QDF_STATUS_SUCCESS) { 16702 hdd_err("Failed to get num_11ag_tx_chains"); 16703 goto out; 16704 } 16705 16706 status = ucfg_mlme_get_vht_enable2x2(hdd_ctx->psoc, &bval); 16707 if (!QDF_IS_STATUS_SUCCESS(status)) 16708 hdd_err("unable to get vht_enable2x2"); 16709 16710 if (!bval) { 16711 if (num_11b_tx_chains > 1) 16712 num_11b_tx_chains = 1; 16713 if (num_11ag_tx_chains > 1) 16714 num_11ag_tx_chains = 1; 16715 } 16716 WMI_PDEV_PARAM_SET_11B_TX_CHAIN_NUM(num_abg_tx_chains, 16717 num_11b_tx_chains); 16718 WMI_PDEV_PARAM_SET_11AG_TX_CHAIN_NUM(num_abg_tx_chains, 16719 num_11ag_tx_chains); 16720 status = mlme_check_index_setparam(setparam, 16721 wmi_pdev_param_abg_mode_tx_chain_num, 16722 num_abg_tx_chains, index++, 16723 max_index); 16724 if (QDF_IS_STATUS_ERROR(status)) { 16725 hdd_err("Failed at wmi_pdev_param_abg_mode_tx_chain_num"); 16726 goto out; 16727 } 16728 /* Send some pdev params to maintain legacy order of pdev set params 16729 * at hdd_pre_enable_configure 16730 */ 16731 status = sme_send_multi_pdev_vdev_set_params(MLME_PDEV_SETPARAM, 16732 WMI_PDEV_ID_SOC, setparam, 16733 index); 16734 if (QDF_IS_STATUS_ERROR(status)) { 16735 hdd_err("Failed to send 1st set of pdev params"); 16736 goto out; 16737 } 16738 if (!ucfg_reg_is_regdb_offloaded(hdd_ctx->psoc)) 16739 ucfg_reg_program_default_cc(hdd_ctx->pdev, 16740 hdd_ctx->reg.reg_domain); 16741 16742 ret = hdd_pre_enable_configure(hdd_ctx); 16743 if (ret) { 16744 hdd_err("Failed to pre-configure cds"); 16745 goto out; 16746 } 16747 16748 /* Always get latest IPA resources allocated from cds_open and configure 16749 * IPA module before configuring them to FW. Sequence required as crash 16750 * observed otherwise. 16751 */ 16752 16753 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) { 16754 ipa_disable_register_cb(); 16755 } else { 16756 status = ipa_register_is_ipa_ready(hdd_ctx->pdev); 16757 if (!QDF_IS_STATUS_SUCCESS(status)) { 16758 hdd_err("ipa_register_is_ipa_ready failed"); 16759 goto out; 16760 } 16761 } 16762 16763 /* 16764 * Start CDS which starts up the SME/MAC/HAL modules and everything 16765 * else 16766 */ 16767 status = cds_enable(hdd_ctx->psoc); 16768 16769 if (!QDF_IS_STATUS_SUCCESS(status)) { 16770 hdd_err("cds_enable failed"); 16771 goto out; 16772 } 16773 16774 status = hdd_post_cds_enable_config(hdd_ctx); 16775 if (!QDF_IS_STATUS_SUCCESS(status)) { 16776 hdd_err("hdd_post_cds_enable_config failed"); 16777 goto cds_disable; 16778 } 16779 status = hdd_register_bcn_cb(hdd_ctx); 16780 if (!QDF_IS_STATUS_SUCCESS(status)) { 16781 hdd_err("hdd_register_bcn_cb failed"); 16782 goto cds_disable; 16783 } 16784 16785 ret = hdd_features_init(hdd_ctx); 16786 if (ret) 16787 goto cds_disable; 16788 16789 /* 16790 * Donot disable rx offload on concurrency for lithium and 16791 * beryllium based targets 16792 */ 16793 if (!hdd_ctx->is_wifi3_0_target) 16794 if (ucfg_dp_is_ol_enabled(hdd_ctx->psoc)) 16795 dp_cbs.hdd_disable_rx_ol_in_concurrency = 16796 hdd_disable_rx_ol_in_concurrency; 16797 dp_cbs.hdd_set_rx_mode_rps_cb = ucfg_dp_set_rx_mode_rps; 16798 dp_cbs.hdd_ipa_set_mcc_mode_cb = hdd_ipa_set_mcc_mode; 16799 dp_cbs.hdd_v2_flow_pool_map = hdd_v2_flow_pool_map; 16800 dp_cbs.hdd_v2_flow_pool_unmap = hdd_v2_flow_pool_unmap; 16801 if (ucfg_ipa_set_perf_level_bw_enabled(hdd_ctx->pdev)) 16802 dp_cbs.hdd_ipa_set_perf_level_bw = hdd_ipa_set_perf_level_bw; 16803 status = policy_mgr_register_dp_cb(hdd_ctx->psoc, &dp_cbs); 16804 if (!QDF_IS_STATUS_SUCCESS(status)) { 16805 hdd_debug("Failed to register DP cb with Policy Manager"); 16806 goto cds_disable; 16807 } 16808 status = policy_mgr_register_mode_change_cb(hdd_ctx->psoc, 16809 wlan_hdd_send_mode_change_event); 16810 if (!QDF_IS_STATUS_SUCCESS(status)) { 16811 hdd_debug("Failed to register mode change cb with Policy Manager"); 16812 goto cds_disable; 16813 } 16814 16815 if (hdd_green_ap_enable_egap(hdd_ctx)) 16816 hdd_debug("enhance green ap is not enabled"); 16817 16818 hdd_register_green_ap_callback(hdd_ctx->pdev); 16819 16820 if (0 != wlan_hdd_set_wow_pulse(hdd_ctx, true)) 16821 hdd_debug("Failed to set wow pulse"); 16822 16823 max_index = max_index - index; 16824 status = mlme_check_index_setparam( 16825 setparam + index, 16826 wmi_pdev_param_gcmp_support_enable, 16827 ucfg_fwol_get_gcmp_enable(hdd_ctx->psoc), 16828 next_index++, max_index); 16829 if (QDF_IS_STATUS_ERROR(status)) { 16830 hdd_err("failed at wmi_pdev_param_gcmp_support_enable"); 16831 goto out; 16832 } 16833 16834 auto_power_fail_mode = 16835 ucfg_pmo_get_auto_power_fail_mode(hdd_ctx->psoc); 16836 status = mlme_check_index_setparam( 16837 setparam + index, 16838 wmi_pdev_auto_detect_power_failure, 16839 auto_power_fail_mode, 16840 next_index++, max_index); 16841 if (QDF_IS_STATUS_ERROR(status)) { 16842 hdd_err("failed at wmi_pdev_auto_detect_power_failure"); 16843 goto out; 16844 } 16845 16846 status = ucfg_get_enable_phy_reg_retention(hdd_ctx->psoc, 16847 &enable_phy_reg_retention); 16848 16849 if (QDF_IS_STATUS_ERROR(status)) 16850 return -EINVAL; 16851 16852 if (enable_phy_reg_retention) { 16853 status = mlme_check_index_setparam( 16854 setparam + index, 16855 wmi_pdev_param_fast_pwr_transition, 16856 enable_phy_reg_retention, 16857 next_index++, max_index); 16858 if (QDF_IS_STATUS_ERROR(status)) { 16859 hdd_err("failed at wmi_pdev_param_fast_pwr_transition"); 16860 goto out; 16861 } 16862 } 16863 /*Send remaining pdev setparams from array*/ 16864 status = sme_send_multi_pdev_vdev_set_params(MLME_PDEV_SETPARAM, 16865 WMI_PDEV_ID_SOC, 16866 setparam + index, 16867 next_index); 16868 if (QDF_IS_STATUS_ERROR(status)) { 16869 hdd_err("failed to send 2nd set of pdev set params"); 16870 goto out; 16871 } 16872 16873 hdd_hastings_bt_war_initialize(hdd_ctx); 16874 16875 wlan_hdd_hang_event_notifier_register(hdd_ctx); 16876 return 0; 16877 16878 cds_disable: 16879 cds_disable(hdd_ctx->psoc); 16880 16881 out: 16882 return -EINVAL; 16883 } 16884 16885 #ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH 16886 static void hdd_deregister_policy_manager_callback( 16887 struct wlan_objmgr_psoc *psoc) 16888 { 16889 if (QDF_STATUS_SUCCESS != 16890 policy_mgr_deregister_hdd_cb(psoc)) { 16891 hdd_err("HDD callback deregister with policy manager failed"); 16892 } 16893 } 16894 #else 16895 static void hdd_deregister_policy_manager_callback( 16896 struct wlan_objmgr_psoc *psoc) 16897 { 16898 } 16899 #endif 16900 16901 int hdd_wlan_stop_modules(struct hdd_context *hdd_ctx, bool ftm_mode) 16902 { 16903 void *hif_ctx; 16904 qdf_device_t qdf_ctx; 16905 QDF_STATUS qdf_status; 16906 bool is_recovery_stop = cds_is_driver_recovering(); 16907 int ret = 0; 16908 int debugfs_threads; 16909 struct target_psoc_info *tgt_hdl; 16910 struct bbm_params param = {0}; 16911 16912 hdd_enter(); 16913 qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE); 16914 if (!qdf_ctx) 16915 return -EINVAL; 16916 16917 cds_set_driver_state_module_stop(true); 16918 16919 debugfs_threads = hdd_return_debugfs_threads_count(); 16920 16921 if (debugfs_threads > 0 || hdd_ctx->is_wiphy_suspended) { 16922 hdd_warn("Debugfs threads %d, wiphy suspend %d", 16923 debugfs_threads, hdd_ctx->is_wiphy_suspended); 16924 16925 if (IS_IDLE_STOP && !ftm_mode) { 16926 hdd_psoc_idle_timer_start(hdd_ctx); 16927 cds_set_driver_state_module_stop(false); 16928 16929 ucfg_dp_bus_bw_compute_timer_stop(hdd_ctx->psoc); 16930 return -EAGAIN; 16931 } 16932 } 16933 16934 ucfg_dp_bus_bw_compute_timer_stop(hdd_ctx->psoc); 16935 hdd_deregister_policy_manager_callback(hdd_ctx->psoc); 16936 16937 /* free user wowl patterns */ 16938 hdd_free_user_wowl_ptrns(); 16939 16940 switch (hdd_ctx->driver_status) { 16941 case DRIVER_MODULES_UNINITIALIZED: 16942 hdd_debug("Modules not initialized just return"); 16943 goto done; 16944 case DRIVER_MODULES_CLOSED: 16945 hdd_debug("Modules already closed"); 16946 goto done; 16947 case DRIVER_MODULES_ENABLED: 16948 hdd_debug("Wlan transitioning (CLOSED <- ENABLED)"); 16949 16950 if (hdd_get_conparam() == QDF_GLOBAL_FTM_MODE) { 16951 hdd_disable_power_management(hdd_ctx); 16952 break; 16953 } 16954 16955 if (hdd_get_conparam() == QDF_GLOBAL_EPPING_MODE) 16956 break; 16957 16958 hdd_skip_acs_scan_timer_deinit(hdd_ctx); 16959 16960 hdd_disable_power_management(hdd_ctx); 16961 16962 if (hdd_get_conparam() == QDF_GLOBAL_MISSION_MODE) 16963 ucfg_dp_direct_link_deinit(hdd_ctx->psoc, 16964 is_recovery_stop); 16965 16966 if (hdd_deconfigure_cds(hdd_ctx)) { 16967 hdd_err("Failed to de-configure CDS"); 16968 QDF_ASSERT(0); 16969 ret = -EINVAL; 16970 } 16971 hdd_debug("successfully Disabled the CDS modules!"); 16972 16973 break; 16974 default: 16975 QDF_DEBUG_PANIC("Unknown driver state:%d", 16976 hdd_ctx->driver_status); 16977 ret = -EINVAL; 16978 goto done; 16979 } 16980 16981 hdd_destroy_sysfs_files(); 16982 hdd_debug("Closing CDS modules!"); 16983 16984 if (hdd_get_conparam() != QDF_GLOBAL_EPPING_MODE) { 16985 qdf_status = cds_post_disable(); 16986 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { 16987 hdd_err("Failed to process post CDS disable! :%d", 16988 qdf_status); 16989 ret = -EINVAL; 16990 QDF_ASSERT(0); 16991 } 16992 16993 hdd_unregister_notifiers(hdd_ctx); 16994 /* De-register the SME callbacks */ 16995 hdd_deregister_cb(hdd_ctx); 16996 16997 hdd_runtime_suspend_context_deinit(hdd_ctx); 16998 16999 qdf_status = cds_dp_close(hdd_ctx->psoc); 17000 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { 17001 hdd_warn("Failed to stop CDS DP: %d", qdf_status); 17002 ret = -EINVAL; 17003 QDF_ASSERT(0); 17004 } 17005 17006 hdd_component_pdev_close(hdd_ctx->pdev); 17007 dispatcher_pdev_close(hdd_ctx->pdev); 17008 ret = hdd_objmgr_release_and_destroy_pdev(hdd_ctx); 17009 if (ret) { 17010 hdd_err("Failed to destroy pdev; errno:%d", ret); 17011 QDF_ASSERT(0); 17012 } 17013 17014 qdf_status = cds_close(hdd_ctx->psoc); 17015 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { 17016 hdd_warn("Failed to stop CDS: %d", qdf_status); 17017 ret = -EINVAL; 17018 QDF_ASSERT(0); 17019 } 17020 17021 qdf_status = wbuff_module_deinit(); 17022 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) 17023 hdd_err("WBUFF de-init unsuccessful; status: %d", 17024 qdf_status); 17025 17026 hdd_component_psoc_close(hdd_ctx->psoc); 17027 /* pdev close and destroy use tx rx ops so call this here */ 17028 wlan_global_lmac_if_close(hdd_ctx->psoc); 17029 } 17030 17031 /* 17032 * Reset total mac phy during module stop such that during 17033 * next module start same psoc is used to populate new service 17034 * ready data 17035 */ 17036 tgt_hdl = wlan_psoc_get_tgt_if_handle(hdd_ctx->psoc); 17037 if (tgt_hdl) 17038 target_psoc_set_total_mac_phy_cnt(tgt_hdl, 0); 17039 17040 17041 hif_ctx = cds_get_context(QDF_MODULE_ID_HIF); 17042 if (!hif_ctx) 17043 ret = -EINVAL; 17044 17045 if (hdd_get_conparam() == QDF_GLOBAL_EPPING_MODE) { 17046 epping_disable(); 17047 epping_close(); 17048 } 17049 17050 wlan_connectivity_logging_stop(); 17051 17052 ucfg_ipa_component_config_free(); 17053 17054 hdd_hif_close(hdd_ctx, hif_ctx); 17055 17056 ol_cds_free(); 17057 17058 if (IS_IDLE_STOP) { 17059 ret = pld_power_off(qdf_ctx->dev); 17060 if (ret) 17061 hdd_err("Failed to power down device; errno:%d", ret); 17062 } 17063 17064 /* Free the cache channels of the command SET_DISABLE_CHANNEL_LIST */ 17065 wlan_hdd_free_cache_channels(hdd_ctx); 17066 hdd_driver_mem_cleanup(); 17067 17068 /* Free the resources allocated while storing SAR config. These needs 17069 * to be freed only in the case when it is not SSR. As in the case of 17070 * SSR, the values needs to be intact so that it can be restored during 17071 * reinit path. 17072 */ 17073 if (!is_recovery_stop) 17074 wlan_hdd_free_sar_config(hdd_ctx); 17075 17076 hdd_sap_destroy_ctx_all(hdd_ctx, is_recovery_stop); 17077 hdd_sta_destroy_ctx_all(hdd_ctx); 17078 17079 /* 17080 * Reset the driver mode specific bus bw level 17081 */ 17082 param.policy = BBM_DRIVER_MODE_POLICY; 17083 param.policy_info.driver_mode = QDF_GLOBAL_MAX_MODE; 17084 ucfg_dp_bbm_apply_independent_policy(hdd_ctx->psoc, ¶m); 17085 17086 hdd_deinit_adapter_ops_wq(hdd_ctx); 17087 hdd_deinit_qdf_ctx(hdd_debug_domain_get()); 17088 17089 hdd_check_for_leaks(hdd_ctx, is_recovery_stop); 17090 hdd_debug_domain_set(QDF_DEBUG_DOMAIN_INIT); 17091 hdd_deinit_qdf_ctx(hdd_debug_domain_get()); 17092 qdf_dma_invalid_buf_list_deinit(); 17093 17094 /* Restore PS params for monitor mode */ 17095 if (hdd_get_conparam() == QDF_GLOBAL_MONITOR_MODE) 17096 hdd_restore_all_ps(hdd_ctx); 17097 17098 /* Once the firmware sequence is completed reset this flag */ 17099 hdd_ctx->imps_enabled = false; 17100 hdd_ctx->is_dual_mac_cfg_updated = false; 17101 hdd_ctx->driver_status = DRIVER_MODULES_CLOSED; 17102 hdd_ctx->is_fw_dbg_log_levels_configured = false; 17103 hdd_debug("Wlan transitioned (now CLOSED)"); 17104 17105 done: 17106 hdd_exit(); 17107 17108 return ret; 17109 } 17110 17111 #ifdef WLAN_FEATURE_MEMDUMP_ENABLE 17112 /** 17113 * hdd_state_info_dump() - prints state information of hdd layer 17114 * @buf_ptr: buffer pointer 17115 * @size: size of buffer to be filled 17116 * 17117 * This function is used to dump state information of hdd layer 17118 * 17119 * Return: None 17120 */ 17121 static void hdd_state_info_dump(char **buf_ptr, uint16_t *size) 17122 { 17123 struct hdd_context *hdd_ctx; 17124 struct hdd_station_ctx *sta_ctx; 17125 struct hdd_adapter *adapter, *next_adapter = NULL; 17126 uint16_t len = 0; 17127 char *buf = *buf_ptr; 17128 wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_STATE_INFO_DUMP; 17129 struct wlan_hdd_link_info *link_info; 17130 17131 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 17132 if (!hdd_ctx) 17133 return; 17134 17135 hdd_debug("size of buffer: %d", *size); 17136 17137 len += scnprintf(buf + len, *size - len, "\n is_wiphy_suspended %d", 17138 hdd_ctx->is_wiphy_suspended); 17139 len += scnprintf(buf + len, *size - len, "\n is_scheduler_suspended %d", 17140 hdd_ctx->is_scheduler_suspended); 17141 17142 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 17143 dbgid) { 17144 hdd_adapter_for_each_active_link_info(adapter, link_info) { 17145 len += 17146 scnprintf(buf + len, *size - len, "\n device name: %s", 17147 adapter->dev->name); 17148 len += 17149 scnprintf(buf + len, *size - len, "\n device_mode: %d", 17150 adapter->device_mode); 17151 switch (adapter->device_mode) { 17152 case QDF_STA_MODE: 17153 case QDF_P2P_CLIENT_MODE: 17154 sta_ctx = 17155 WLAN_HDD_GET_STATION_CTX_PTR(link_info); 17156 len += scnprintf(buf + len, *size - len, 17157 "\n conn_state: %d", 17158 sta_ctx->conn_info.conn_state); 17159 break; 17160 default: 17161 break; 17162 } 17163 } 17164 hdd_adapter_dev_put_debug(adapter, dbgid); 17165 } 17166 17167 *size -= len; 17168 *buf_ptr += len; 17169 } 17170 17171 /** 17172 * hdd_register_debug_callback() - registration function for hdd layer 17173 * to print hdd state information 17174 * 17175 * Return: None 17176 */ 17177 static void hdd_register_debug_callback(void) 17178 { 17179 qdf_register_debug_callback(QDF_MODULE_ID_HDD, &hdd_state_info_dump); 17180 } 17181 #else /* WLAN_FEATURE_MEMDUMP_ENABLE */ 17182 static void hdd_register_debug_callback(void) 17183 { 17184 } 17185 #endif /* WLAN_FEATURE_MEMDUMP_ENABLE */ 17186 17187 /* 17188 * wlan_init_bug_report_lock() - Initialize bug report lock 17189 * 17190 * This function is used to create bug report lock 17191 * 17192 * Return: None 17193 */ 17194 static void wlan_init_bug_report_lock(void) 17195 { 17196 struct cds_context *p_cds_context; 17197 17198 p_cds_context = cds_get_global_context(); 17199 if (!p_cds_context) { 17200 hdd_err("cds context is NULL"); 17201 return; 17202 } 17203 17204 qdf_spinlock_create(&p_cds_context->bug_report_lock); 17205 } 17206 17207 #ifdef DISABLE_CHANNEL_LIST 17208 static QDF_STATUS wlan_hdd_cache_chann_mutex_create(struct hdd_context *hdd_ctx) 17209 { 17210 return qdf_mutex_create(&hdd_ctx->cache_channel_lock); 17211 } 17212 #else 17213 static QDF_STATUS wlan_hdd_cache_chann_mutex_create(struct hdd_context *hdd_ctx) 17214 { 17215 return QDF_STATUS_SUCCESS; 17216 } 17217 #endif 17218 17219 QDF_STATUS hdd_open_adapter_no_trans(struct hdd_context *hdd_ctx, 17220 enum QDF_OPMODE op_mode, 17221 const char *iface_name, 17222 uint8_t *mac_addr_bytes, 17223 struct hdd_adapter_create_param *params) 17224 { 17225 struct osif_vdev_sync *vdev_sync; 17226 struct hdd_adapter *adapter; 17227 QDF_STATUS status; 17228 int errno; 17229 17230 QDF_BUG(rtnl_is_locked()); 17231 17232 errno = osif_vdev_sync_create(hdd_ctx->parent_dev, &vdev_sync); 17233 if (errno) 17234 return qdf_status_from_os_return(errno); 17235 17236 adapter = hdd_open_adapter(hdd_ctx, op_mode, iface_name, 17237 mac_addr_bytes, NET_NAME_UNKNOWN, true, 17238 params); 17239 if (!adapter) { 17240 status = QDF_STATUS_E_INVAL; 17241 goto destroy_sync; 17242 } 17243 17244 osif_vdev_sync_register(adapter->dev, vdev_sync); 17245 17246 return QDF_STATUS_SUCCESS; 17247 17248 destroy_sync: 17249 osif_vdev_sync_destroy(vdev_sync); 17250 17251 return status; 17252 } 17253 17254 #ifdef WLAN_OPEN_P2P_INTERFACE 17255 /** 17256 * hdd_open_p2p_interface - Open P2P interface 17257 * @hdd_ctx: HDD context 17258 * 17259 * Return: QDF_STATUS 17260 */ 17261 static QDF_STATUS hdd_open_p2p_interface(struct hdd_context *hdd_ctx) 17262 { 17263 QDF_STATUS status; 17264 bool p2p_dev_addr_admin; 17265 bool is_p2p_locally_administered = false; 17266 struct hdd_adapter_create_param params = {0}; 17267 17268 cfg_p2p_get_device_addr_admin(hdd_ctx->psoc, &p2p_dev_addr_admin); 17269 17270 if (p2p_dev_addr_admin) { 17271 if (hdd_ctx->num_provisioned_addr && 17272 !(hdd_ctx->provisioned_mac_addr[0].bytes[0] & 0x02)) { 17273 hdd_ctx->p2p_device_address = 17274 hdd_ctx->provisioned_mac_addr[0]; 17275 17276 /* 17277 * Generate the P2P Device Address. This consists of 17278 * the device's primary MAC address with the locally 17279 * administered bit set. 17280 */ 17281 17282 hdd_ctx->p2p_device_address.bytes[0] |= 0x02; 17283 is_p2p_locally_administered = true; 17284 } else if (!(hdd_ctx->derived_mac_addr[0].bytes[0] & 0x02)) { 17285 hdd_ctx->p2p_device_address = 17286 hdd_ctx->derived_mac_addr[0]; 17287 /* 17288 * Generate the P2P Device Address. This consists of 17289 * the device's primary MAC address with the locally 17290 * administered bit set. 17291 */ 17292 hdd_ctx->p2p_device_address.bytes[0] |= 0x02; 17293 is_p2p_locally_administered = true; 17294 } 17295 } 17296 if (!is_p2p_locally_administered) { 17297 uint8_t *p2p_dev_addr; 17298 17299 p2p_dev_addr = wlan_hdd_get_intf_addr(hdd_ctx, 17300 QDF_P2P_DEVICE_MODE); 17301 if (!p2p_dev_addr) { 17302 hdd_err("Failed to get MAC address for new p2p device"); 17303 return QDF_STATUS_E_INVAL; 17304 } 17305 17306 qdf_mem_copy(hdd_ctx->p2p_device_address.bytes, 17307 p2p_dev_addr, QDF_MAC_ADDR_SIZE); 17308 } 17309 17310 status = hdd_open_adapter_no_trans(hdd_ctx, QDF_P2P_DEVICE_MODE, 17311 "p2p%d", 17312 hdd_ctx->p2p_device_address.bytes, 17313 ¶ms); 17314 if (QDF_IS_STATUS_ERROR(status)) { 17315 if (!is_p2p_locally_administered) 17316 wlan_hdd_release_intf_addr(hdd_ctx, 17317 hdd_ctx->p2p_device_address.bytes); 17318 hdd_err("Failed to open p2p interface"); 17319 return QDF_STATUS_E_INVAL; 17320 } 17321 17322 return QDF_STATUS_SUCCESS; 17323 } 17324 #else 17325 static inline QDF_STATUS hdd_open_p2p_interface(struct hdd_context *hdd_ctx) 17326 { 17327 return QDF_STATUS_SUCCESS; 17328 } 17329 #endif 17330 17331 static QDF_STATUS hdd_open_ocb_interface(struct hdd_context *hdd_ctx) 17332 { 17333 QDF_STATUS status; 17334 uint8_t *mac_addr; 17335 struct hdd_adapter_create_param params = {0}; 17336 17337 mac_addr = wlan_hdd_get_intf_addr(hdd_ctx, QDF_OCB_MODE); 17338 if (!mac_addr) 17339 return QDF_STATUS_E_INVAL; 17340 17341 status = hdd_open_adapter_no_trans(hdd_ctx, QDF_OCB_MODE, 17342 "wlanocb%d", mac_addr, 17343 ¶ms); 17344 if (QDF_IS_STATUS_ERROR(status)) { 17345 wlan_hdd_release_intf_addr(hdd_ctx, mac_addr); 17346 hdd_err("Failed to open 802.11p interface"); 17347 } 17348 17349 return status; 17350 } 17351 17352 static QDF_STATUS hdd_open_concurrent_interface(struct hdd_context *hdd_ctx) 17353 { 17354 QDF_STATUS status; 17355 const char *iface_name; 17356 uint8_t *mac_addr; 17357 struct hdd_adapter_create_param params = {0}; 17358 17359 if (qdf_str_eq(hdd_ctx->config->enable_concurrent_sta, "")) 17360 return QDF_STATUS_SUCCESS; 17361 17362 iface_name = hdd_ctx->config->enable_concurrent_sta; 17363 mac_addr = wlan_hdd_get_intf_addr(hdd_ctx, QDF_STA_MODE); 17364 if (!mac_addr) 17365 return QDF_STATUS_E_INVAL; 17366 17367 status = hdd_open_adapter_no_trans(hdd_ctx, QDF_STA_MODE, 17368 iface_name, mac_addr, 17369 ¶ms); 17370 if (QDF_IS_STATUS_ERROR(status)) { 17371 wlan_hdd_release_intf_addr(hdd_ctx, mac_addr); 17372 hdd_err("Failed to open concurrent station interface"); 17373 } 17374 17375 return status; 17376 } 17377 17378 #ifdef WLAN_HDD_MULTI_VDEV_SINGLE_NDEV 17379 static inline void 17380 hdd_adapter_open_set_max_active_links(struct hdd_adapter_create_param *params) 17381 { 17382 if (params->is_add_virtual_iface || !params->is_ml_adapter) 17383 params->num_sessions = 1; 17384 else 17385 params->num_sessions = 2; 17386 } 17387 #else 17388 static inline void 17389 hdd_adapter_open_set_max_active_links(struct hdd_adapter_create_param *params) 17390 { 17391 params->num_sessions = 1; 17392 } 17393 #endif 17394 17395 static QDF_STATUS 17396 hdd_open_adapters_for_mission_mode(struct hdd_context *hdd_ctx) 17397 { 17398 enum dot11p_mode dot11p_mode; 17399 QDF_STATUS status; 17400 uint8_t *mac_addr; 17401 struct hdd_adapter_create_param params = {0}; 17402 bool eht_capab = 0; 17403 17404 ucfg_mlme_get_dot11p_mode(hdd_ctx->psoc, &dot11p_mode); 17405 ucfg_psoc_mlme_get_11be_capab(hdd_ctx->psoc, &eht_capab); 17406 17407 /* Create only 802.11p interface? */ 17408 if (dot11p_mode == CFG_11P_STANDALONE) 17409 return hdd_open_ocb_interface(hdd_ctx); 17410 17411 mac_addr = wlan_hdd_get_intf_addr(hdd_ctx, QDF_STA_MODE); 17412 if (!mac_addr) 17413 return QDF_STATUS_E_INVAL; 17414 17415 if (eht_capab) { 17416 params.is_ml_adapter = true; 17417 hdd_adapter_open_set_max_active_links(¶ms); 17418 } 17419 17420 status = hdd_open_adapter_no_trans(hdd_ctx, QDF_STA_MODE, 17421 "wlan%d", mac_addr, 17422 ¶ms); 17423 if (QDF_IS_STATUS_ERROR(status)) { 17424 wlan_hdd_release_intf_addr(hdd_ctx, mac_addr); 17425 return status; 17426 } 17427 17428 /* opening concurrent STA is best effort, continue on error */ 17429 hdd_open_concurrent_interface(hdd_ctx); 17430 17431 status = hdd_open_p2p_interface(hdd_ctx); 17432 if (status) 17433 goto err_close_adapters; 17434 17435 /* 17436 * Create separate interface (wifi-aware0) for NAN. All NAN commands 17437 * should go on this new interface. 17438 */ 17439 if (wlan_hdd_is_vdev_creation_allowed(hdd_ctx->psoc)) { 17440 qdf_mem_zero(¶ms, sizeof(params)); 17441 mac_addr = wlan_hdd_get_intf_addr(hdd_ctx, QDF_NAN_DISC_MODE); 17442 if (!mac_addr) 17443 goto err_close_adapters; 17444 17445 status = hdd_open_adapter_no_trans(hdd_ctx, QDF_NAN_DISC_MODE, 17446 "wifi-aware%d", mac_addr, 17447 ¶ms); 17448 if (status) { 17449 wlan_hdd_release_intf_addr(hdd_ctx, mac_addr); 17450 goto err_close_adapters; 17451 } 17452 } 17453 /* Open 802.11p Interface */ 17454 if (dot11p_mode == CFG_11P_CONCURRENT) { 17455 status = hdd_open_ocb_interface(hdd_ctx); 17456 if (QDF_IS_STATUS_ERROR(status)) 17457 goto err_close_adapters; 17458 } 17459 17460 if (eht_capab) 17461 hdd_wlan_register_mlo_interfaces(hdd_ctx); 17462 17463 return QDF_STATUS_SUCCESS; 17464 17465 err_close_adapters: 17466 hdd_close_all_adapters(hdd_ctx, true); 17467 17468 return status; 17469 } 17470 17471 static QDF_STATUS hdd_open_adapters_for_ftm_mode(struct hdd_context *hdd_ctx) 17472 { 17473 QDF_STATUS status; 17474 uint8_t *mac_addr; 17475 struct hdd_adapter_create_param params = {0}; 17476 17477 mac_addr = wlan_hdd_get_intf_addr(hdd_ctx, QDF_FTM_MODE); 17478 if (!mac_addr) 17479 return QDF_STATUS_E_INVAL; 17480 17481 status = hdd_open_adapter_no_trans(hdd_ctx, QDF_FTM_MODE, 17482 "wlan%d", mac_addr, 17483 ¶ms); 17484 if (QDF_IS_STATUS_ERROR(status)) { 17485 wlan_hdd_release_intf_addr(hdd_ctx, mac_addr); 17486 return status; 17487 } 17488 17489 return QDF_STATUS_SUCCESS; 17490 } 17491 17492 static QDF_STATUS 17493 hdd_open_adapters_for_monitor_mode(struct hdd_context *hdd_ctx) 17494 { 17495 QDF_STATUS status; 17496 uint8_t *mac_addr; 17497 struct hdd_adapter_create_param params = {0}; 17498 17499 mac_addr = wlan_hdd_get_intf_addr(hdd_ctx, QDF_MONITOR_MODE); 17500 if (!mac_addr) 17501 return QDF_STATUS_E_INVAL; 17502 17503 status = hdd_open_adapter_no_trans(hdd_ctx, QDF_MONITOR_MODE, 17504 "wlan%d", mac_addr, 17505 ¶ms); 17506 if (QDF_IS_STATUS_ERROR(status)) { 17507 wlan_hdd_release_intf_addr(hdd_ctx, mac_addr); 17508 return status; 17509 } 17510 17511 return QDF_STATUS_SUCCESS; 17512 } 17513 17514 static QDF_STATUS hdd_open_adapters_for_epping_mode(struct hdd_context *hdd_ctx) 17515 { 17516 epping_enable_adapter(); 17517 return QDF_STATUS_SUCCESS; 17518 } 17519 17520 typedef QDF_STATUS (*hdd_open_mode_handler)(struct hdd_context *hdd_ctx); 17521 17522 static const hdd_open_mode_handler 17523 hdd_open_mode_handlers[QDF_GLOBAL_MAX_MODE] = { 17524 [QDF_GLOBAL_MISSION_MODE] = hdd_open_adapters_for_mission_mode, 17525 [QDF_GLOBAL_FTM_MODE] = hdd_open_adapters_for_ftm_mode, 17526 [QDF_GLOBAL_MONITOR_MODE] = hdd_open_adapters_for_monitor_mode, 17527 [QDF_GLOBAL_EPPING_MODE] = hdd_open_adapters_for_epping_mode, 17528 }; 17529 17530 static QDF_STATUS hdd_open_adapters_for_mode(struct hdd_context *hdd_ctx, 17531 enum QDF_GLOBAL_MODE driver_mode) 17532 { 17533 QDF_STATUS status; 17534 17535 if (driver_mode < 0 || 17536 driver_mode >= QDF_GLOBAL_MAX_MODE || 17537 !hdd_open_mode_handlers[driver_mode]) { 17538 hdd_err("Driver mode %d not supported", driver_mode); 17539 return -ENOTSUPP; 17540 } 17541 17542 hdd_hold_rtnl_lock(); 17543 status = hdd_open_mode_handlers[driver_mode](hdd_ctx); 17544 hdd_release_rtnl_lock(); 17545 17546 return status; 17547 } 17548 17549 int hdd_wlan_startup(struct hdd_context *hdd_ctx) 17550 { 17551 QDF_STATUS status; 17552 int errno; 17553 bool is_imps_enabled; 17554 17555 hdd_enter(); 17556 17557 qdf_nbuf_init_replenish_timer(); 17558 17559 status = wlan_hdd_cache_chann_mutex_create(hdd_ctx); 17560 if (QDF_IS_STATUS_ERROR(status)) 17561 return qdf_status_to_os_return(status); 17562 17563 #ifdef FEATURE_WLAN_CH_AVOID 17564 mutex_init(&hdd_ctx->avoid_freq_lock); 17565 #endif 17566 17567 osif_request_manager_init(); 17568 hdd_driver_memdump_init(); 17569 17570 errno = hdd_init_regulatory_update_event(hdd_ctx); 17571 if (errno) { 17572 hdd_err("Failed to initialize regulatory update event; errno:%d", 17573 errno); 17574 goto memdump_deinit; 17575 } 17576 17577 errno = hdd_wlan_start_modules(hdd_ctx, false); 17578 if (errno) { 17579 hdd_err("Failed to start modules; errno:%d", errno); 17580 goto memdump_deinit; 17581 } 17582 17583 if (hdd_get_conparam() == QDF_GLOBAL_EPPING_MODE) 17584 return 0; 17585 17586 wlan_hdd_update_wiphy(hdd_ctx); 17587 17588 hdd_ctx->mac_handle = cds_get_context(QDF_MODULE_ID_SME); 17589 if (!hdd_ctx->mac_handle) 17590 goto stop_modules; 17591 17592 errno = hdd_wiphy_init(hdd_ctx); 17593 if (errno) { 17594 hdd_err("Failed to initialize wiphy; errno:%d", errno); 17595 goto stop_modules; 17596 } 17597 17598 errno = hdd_initialize_mac_address(hdd_ctx); 17599 if (errno) { 17600 hdd_err("MAC initializtion failed: %d", errno); 17601 goto unregister_wiphy; 17602 } 17603 17604 errno = register_netdevice_notifier(&hdd_netdev_notifier); 17605 if (errno) { 17606 hdd_err("register_netdevice_notifier failed; errno:%d", errno); 17607 goto unregister_wiphy; 17608 } 17609 17610 wlan_hdd_update_11n_mode(hdd_ctx); 17611 17612 hdd_lpass_notify_wlan_version(hdd_ctx); 17613 17614 status = wlansap_global_init(); 17615 if (QDF_IS_STATUS_ERROR(status)) 17616 goto unregister_notifiers; 17617 17618 ucfg_mlme_is_imps_enabled(hdd_ctx->psoc, &is_imps_enabled); 17619 hdd_set_idle_ps_config(hdd_ctx, is_imps_enabled); 17620 hdd_debugfs_mws_coex_info_init(hdd_ctx); 17621 hdd_debugfs_ini_config_init(hdd_ctx); 17622 wlan_hdd_debugfs_unit_test_host_create(hdd_ctx); 17623 wlan_hdd_create_mib_stats_lock(); 17624 wlan_cfg80211_init_interop_issues_ap(hdd_ctx->pdev); 17625 17626 hdd_exit(); 17627 17628 return 0; 17629 17630 unregister_notifiers: 17631 unregister_netdevice_notifier(&hdd_netdev_notifier); 17632 17633 unregister_wiphy: 17634 qdf_dp_trace_deinit(); 17635 wiphy_unregister(hdd_ctx->wiphy); 17636 17637 stop_modules: 17638 hdd_wlan_stop_modules(hdd_ctx, false); 17639 17640 memdump_deinit: 17641 hdd_driver_memdump_deinit(); 17642 osif_request_manager_deinit(); 17643 qdf_nbuf_deinit_replenish_timer(); 17644 17645 if (cds_is_fw_down()) 17646 hdd_err("Not setting the complete event as fw is down"); 17647 else 17648 hdd_start_complete(errno); 17649 17650 hdd_exit(); 17651 17652 return errno; 17653 } 17654 17655 QDF_STATUS hdd_psoc_create_vdevs(struct hdd_context *hdd_ctx) 17656 { 17657 enum QDF_GLOBAL_MODE driver_mode = hdd_get_conparam(); 17658 QDF_STATUS status; 17659 17660 status = hdd_open_adapters_for_mode(hdd_ctx, driver_mode); 17661 if (QDF_IS_STATUS_ERROR(status)) { 17662 hdd_err("Failed to create vdevs; status:%d", status); 17663 return status; 17664 } 17665 17666 ucfg_dp_try_set_rps_cpu_mask(hdd_ctx->psoc); 17667 17668 if (driver_mode != QDF_GLOBAL_FTM_MODE && 17669 driver_mode != QDF_GLOBAL_EPPING_MODE) 17670 hdd_psoc_idle_timer_start(hdd_ctx); 17671 17672 return QDF_STATUS_SUCCESS; 17673 } 17674 17675 /** 17676 * hdd_wlan_update_target_info() - update target type info 17677 * @hdd_ctx: HDD context 17678 * @context: hif context 17679 * 17680 * Update target info received from firmware in hdd context 17681 * Return:None 17682 */ 17683 17684 void hdd_wlan_update_target_info(struct hdd_context *hdd_ctx, void *context) 17685 { 17686 struct hif_target_info *tgt_info = hif_get_target_info_handle(context); 17687 17688 if (!tgt_info) { 17689 hdd_err("Target info is Null"); 17690 return; 17691 } 17692 17693 hdd_ctx->target_type = tgt_info->target_type; 17694 } 17695 17696 #ifdef WLAN_FEATURE_MOTION_DETECTION 17697 /** 17698 * hdd_md_host_evt_cb - Callback for Motion Detection Event 17699 * @ctx: HDD context 17700 * @event: motion detect event 17701 * 17702 * Callback for Motion Detection Event. Re-enables Motion 17703 * Detection again upon event 17704 * 17705 * Return: QDF_STATUS QDF_STATUS_SUCCESS on Success and 17706 * QDF_STATUS_E_FAILURE on failure 17707 */ 17708 QDF_STATUS hdd_md_host_evt_cb(void *ctx, struct sir_md_evt *event) 17709 { 17710 struct hdd_adapter *adapter; 17711 struct hdd_context *hdd_ctx; 17712 struct sme_motion_det_en motion_det; 17713 struct wlan_hdd_link_info *link_info; 17714 17715 if (!ctx || !event) 17716 return QDF_STATUS_E_INVAL; 17717 17718 hdd_ctx = (struct hdd_context *)ctx; 17719 if (wlan_hdd_validate_context(hdd_ctx)) 17720 return QDF_STATUS_E_INVAL; 17721 17722 link_info = hdd_get_link_info_by_vdev(hdd_ctx, event->vdev_id); 17723 if (!link_info || 17724 WLAN_HDD_ADAPTER_MAGIC != link_info->adapter->magic) { 17725 hdd_err("Invalid adapter or adapter has invalid magic"); 17726 return QDF_STATUS_E_INVAL; 17727 } 17728 17729 adapter = link_info->adapter; 17730 /* When motion is detected, reset the motion_det_in_progress flag */ 17731 if (event->status) 17732 adapter->motion_det_in_progress = false; 17733 17734 hdd_debug("Motion Detection CB vdev_id=%u, status=%u", 17735 event->vdev_id, event->status); 17736 17737 if (adapter->motion_detection_mode) { 17738 motion_det.vdev_id = event->vdev_id; 17739 motion_det.enable = 1; 17740 hdd_debug("Motion Detect CB -> Enable Motion Detection again"); 17741 sme_motion_det_enable(hdd_ctx->mac_handle, &motion_det); 17742 } 17743 17744 return QDF_STATUS_SUCCESS; 17745 } 17746 17747 /** 17748 * hdd_md_bl_evt_cb - Callback for Motion Detection Baseline Event 17749 * @ctx: HDD context 17750 * @event: motion detect baseline event 17751 * 17752 * Callback for Motion Detection Baseline completion 17753 * 17754 * Return: QDF_STATUS QDF_STATUS_SUCCESS on Success and 17755 * QDF_STATUS_E_FAILURE on failure 17756 */ 17757 QDF_STATUS hdd_md_bl_evt_cb(void *ctx, struct sir_md_bl_evt *event) 17758 { 17759 struct hdd_context *hdd_ctx; 17760 struct wlan_hdd_link_info *link_info; 17761 17762 if (!ctx || !event) 17763 return QDF_STATUS_E_INVAL; 17764 17765 hdd_ctx = (struct hdd_context *)ctx; 17766 if (wlan_hdd_validate_context(hdd_ctx)) 17767 return QDF_STATUS_E_INVAL; 17768 17769 link_info = hdd_get_link_info_by_vdev(hdd_ctx, event->vdev_id); 17770 if (!link_info || 17771 WLAN_HDD_ADAPTER_MAGIC != link_info->adapter->magic) { 17772 hdd_err("Invalid adapter or adapter has invalid magic"); 17773 return QDF_STATUS_E_INVAL; 17774 } 17775 17776 hdd_debug("Motion Detection Baseline CB vdev id=%u, baseline val = %d", 17777 event->vdev_id, event->bl_baseline_value); 17778 17779 link_info->adapter->motion_det_baseline_value = 17780 event->bl_baseline_value; 17781 17782 return QDF_STATUS_SUCCESS; 17783 } 17784 #endif /* WLAN_FEATURE_MOTION_DETECTION */ 17785 17786 static QDF_STATUS hdd_ssr_on_pagefault_cb(struct hdd_context *hdd_ctx) 17787 { 17788 uint32_t ssr_frequency_on_pagefault; 17789 qdf_time_t curr_time, ssr_threshold; 17790 17791 hdd_enter(); 17792 17793 if (!hdd_ctx) 17794 return QDF_STATUS_E_NULL_VALUE; 17795 17796 ssr_frequency_on_pagefault = 17797 ucfg_pmo_get_ssr_frequency_on_pagefault(hdd_ctx->psoc); 17798 17799 curr_time = qdf_get_system_uptime(); 17800 ssr_threshold = qdf_system_msecs_to_ticks(ssr_frequency_on_pagefault); 17801 17802 if (!hdd_ctx->last_pagefault_ssr_time || 17803 (curr_time - hdd_ctx->last_pagefault_ssr_time) >= ssr_threshold) { 17804 hdd_info("curr_time %lu last_pagefault_ssr_time %lu ssr_frequency %d", 17805 curr_time, hdd_ctx->last_pagefault_ssr_time, 17806 ssr_threshold); 17807 hdd_ctx->last_pagefault_ssr_time = curr_time; 17808 cds_trigger_recovery(QDF_HOST_WAKEUP_REASON_PAGEFAULT); 17809 17810 return QDF_STATUS_SUCCESS; 17811 } 17812 17813 return QDF_STATUS_E_AGAIN; 17814 } 17815 17816 #define FW_PAGE_FAULT_IDX QCA_NL80211_VENDOR_SUBCMD_FW_PAGE_FAULT_REPORT_INDEX 17817 static QDF_STATUS hdd_send_pagefault_report_to_user(struct hdd_context *hdd_ctx, 17818 void *buf, uint32_t buf_len) 17819 { 17820 struct sk_buff *event_buf; 17821 int flags = cds_get_gfp_flags(); 17822 uint8_t *ev_data = buf; 17823 uint16_t event_len = NLMSG_HDRLEN + buf_len; 17824 17825 event_buf = wlan_cfg80211_vendor_event_alloc(hdd_ctx->wiphy, NULL, 17826 event_len, 17827 FW_PAGE_FAULT_IDX, flags); 17828 if (!event_buf) { 17829 hdd_err("wlan_cfg80211_vendor_event_alloc failed"); 17830 return QDF_STATUS_E_NOMEM; 17831 } 17832 17833 if (nla_put(event_buf, QCA_WLAN_VENDOR_ATTR_FW_PAGE_FAULT_REPORT_DATA, 17834 buf_len, ev_data)) { 17835 hdd_debug("Failed to fill pagefault blob data"); 17836 wlan_cfg80211_vendor_free_skb(event_buf); 17837 return QDF_STATUS_E_FAILURE; 17838 } 17839 17840 wlan_cfg80211_vendor_event(event_buf, flags); 17841 return QDF_STATUS_SUCCESS; 17842 } 17843 17844 static QDF_STATUS hdd_pagefault_action_cb(void *buf, uint32_t buf_len) 17845 { 17846 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 17847 17848 if (!hdd_ctx) 17849 return QDF_STATUS_E_NULL_VALUE; 17850 17851 if (wlan_pmo_enable_ssr_on_page_fault(hdd_ctx->psoc)) 17852 return hdd_ssr_on_pagefault_cb(hdd_ctx); 17853 17854 return hdd_send_pagefault_report_to_user(hdd_ctx, buf, buf_len); 17855 } 17856 17857 /** 17858 * hdd_register_cb - Register HDD callbacks. 17859 * @hdd_ctx: HDD context 17860 * 17861 * Register the HDD callbacks to CDS/SME. 17862 * 17863 * Return: 0 for success or Error code for failure 17864 */ 17865 int hdd_register_cb(struct hdd_context *hdd_ctx) 17866 { 17867 QDF_STATUS status; 17868 int ret = 0; 17869 mac_handle_t mac_handle; 17870 17871 hdd_enter(); 17872 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) { 17873 hdd_err("in ftm mode, no need to register callbacks"); 17874 return ret; 17875 } 17876 17877 mac_handle = hdd_ctx->mac_handle; 17878 17879 sme_register_oem_data_rsp_callback(mac_handle, 17880 hdd_send_oem_data_rsp_msg); 17881 17882 sme_register_mgmt_frame_ind_callback(mac_handle, 17883 hdd_indicate_mgmt_frame); 17884 sme_set_tsfcb(mac_handle, hdd_get_tsf_cb, hdd_ctx); 17885 sme_stats_ext_register_callback(mac_handle, 17886 wlan_hdd_cfg80211_stats_ext_callback); 17887 17888 sme_ext_scan_register_callback(mac_handle, 17889 wlan_hdd_cfg80211_extscan_callback); 17890 sme_stats_ext2_register_callback(mac_handle, 17891 wlan_hdd_cfg80211_stats_ext2_callback); 17892 17893 sme_multi_client_ll_rsp_register_callback(mac_handle, 17894 hdd_latency_level_event_handler_cb); 17895 17896 sme_set_rssi_threshold_breached_cb(mac_handle, 17897 hdd_rssi_threshold_breached); 17898 17899 sme_set_link_layer_stats_ind_cb(mac_handle, 17900 wlan_hdd_cfg80211_link_layer_stats_callback); 17901 17902 sme_rso_cmd_status_cb(mac_handle, wlan_hdd_rso_cmd_status_cb); 17903 17904 sme_set_link_layer_ext_cb(mac_handle, 17905 wlan_hdd_cfg80211_link_layer_stats_ext_callback); 17906 sme_update_hidden_ssid_status_cb(mac_handle, 17907 hdd_hidden_ssid_enable_roaming); 17908 17909 status = sme_set_lost_link_info_cb(mac_handle, 17910 hdd_lost_link_info_cb); 17911 17912 wlan_hdd_register_cp_stats_cb(hdd_ctx); 17913 hdd_dcs_register_cb(hdd_ctx); 17914 17915 hdd_thermal_register_callbacks(hdd_ctx); 17916 /* print error and not block the startup process */ 17917 if (!QDF_IS_STATUS_SUCCESS(status)) 17918 hdd_err("set lost link info callback failed"); 17919 17920 ret = hdd_register_data_stall_detect_cb(); 17921 if (ret) { 17922 hdd_err("Register data stall detect detect callback failed."); 17923 return ret; 17924 } 17925 17926 wlan_hdd_dcc_register_for_dcc_stats_event(hdd_ctx); 17927 17928 sme_register_set_connection_info_cb(mac_handle, 17929 hdd_set_connection_in_progress, 17930 hdd_is_connection_in_progress); 17931 17932 status = sme_set_bt_activity_info_cb(mac_handle, 17933 hdd_bt_activity_cb); 17934 if (!QDF_IS_STATUS_SUCCESS(status)) 17935 hdd_err("set bt activity info callback failed"); 17936 17937 status = sme_register_tx_queue_cb(mac_handle, 17938 hdd_tx_queue_cb); 17939 if (!QDF_IS_STATUS_SUCCESS(status)) 17940 hdd_err("Register tx queue callback failed"); 17941 17942 #ifdef WLAN_FEATURE_MOTION_DETECTION 17943 sme_set_md_host_evt_cb(mac_handle, hdd_md_host_evt_cb, (void *)hdd_ctx); 17944 sme_set_md_bl_evt_cb(mac_handle, hdd_md_bl_evt_cb, (void *)hdd_ctx); 17945 #endif /* WLAN_FEATURE_MOTION_DETECTION */ 17946 17947 mac_register_session_open_close_cb(hdd_ctx->mac_handle, 17948 hdd_sme_close_session_callback, 17949 hdd_common_roam_callback); 17950 17951 sme_set_roam_scan_ch_event_cb(mac_handle, hdd_get_roam_scan_ch_cb); 17952 status = sme_set_monitor_mode_cb(mac_handle, 17953 hdd_sme_monitor_mode_callback); 17954 if (QDF_IS_STATUS_ERROR(status)) 17955 hdd_err_rl("Register monitor mode callback failed"); 17956 17957 status = sme_set_beacon_latency_event_cb(mac_handle, 17958 hdd_beacon_latency_event_cb); 17959 if (QDF_IS_STATUS_ERROR(status)) 17960 hdd_err_rl("Register beacon latency event callback failed"); 17961 17962 sme_async_oem_event_init(mac_handle, 17963 hdd_oem_event_async_cb); 17964 17965 sme_register_pagefault_cb(mac_handle, hdd_pagefault_action_cb); 17966 17967 hdd_exit(); 17968 17969 return ret; 17970 } 17971 17972 /** 17973 * hdd_deregister_cb() - De-Register HDD callbacks. 17974 * @hdd_ctx: HDD context 17975 * 17976 * De-Register the HDD callbacks to CDS/SME. 17977 * 17978 * Return: void 17979 */ 17980 void hdd_deregister_cb(struct hdd_context *hdd_ctx) 17981 { 17982 QDF_STATUS status; 17983 int ret; 17984 mac_handle_t mac_handle; 17985 17986 hdd_enter(); 17987 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) { 17988 hdd_err("in ftm mode, no need to deregister callbacks"); 17989 return; 17990 } 17991 17992 mac_handle = hdd_ctx->mac_handle; 17993 17994 sme_deregister_ssr_on_pagefault_cb(mac_handle); 17995 17996 sme_async_oem_event_deinit(mac_handle); 17997 17998 sme_deregister_tx_queue_cb(mac_handle); 17999 18000 sme_reset_link_layer_stats_ind_cb(mac_handle); 18001 sme_reset_rssi_threshold_breached_cb(mac_handle); 18002 18003 sme_stats_ext_deregister_callback(mac_handle); 18004 18005 status = sme_reset_tsfcb(mac_handle); 18006 if (!QDF_IS_STATUS_SUCCESS(status)) 18007 hdd_err("Failed to de-register tsfcb the callback:%d", 18008 status); 18009 18010 ret = hdd_deregister_data_stall_detect_cb(); 18011 if (ret) 18012 hdd_err("Failed to de-register data stall detect event callback"); 18013 hdd_thermal_unregister_callbacks(hdd_ctx); 18014 sme_deregister_oem_data_rsp_callback(mac_handle); 18015 sme_multi_client_ll_rsp_deregister_callback(mac_handle); 18016 18017 hdd_exit(); 18018 } 18019 18020 /** 18021 * hdd_softap_sta_deauth() - handle deauth req from HDD 18022 * @adapter: Pointer to the HDD adapter 18023 * @param: Params to the operation 18024 * 18025 * This to take counter measure to handle deauth req from HDD 18026 * 18027 * Return: None 18028 */ 18029 QDF_STATUS hdd_softap_sta_deauth(struct hdd_adapter *adapter, 18030 struct csr_del_sta_params *param) 18031 { 18032 QDF_STATUS qdf_status = QDF_STATUS_E_FAULT; 18033 struct hdd_context *hdd_ctx; 18034 bool is_sap_bcast_deauth_enabled = false; 18035 18036 hdd_ctx = WLAN_HDD_GET_CTX(adapter); 18037 if (!hdd_ctx) { 18038 hdd_err("hdd_ctx is NULL"); 18039 return QDF_STATUS_E_INVAL; 18040 } 18041 18042 ucfg_mlme_get_sap_bcast_deauth_enabled(hdd_ctx->psoc, 18043 &is_sap_bcast_deauth_enabled); 18044 18045 hdd_enter(); 18046 18047 hdd_debug("sap_bcast_deauth_enabled %d", is_sap_bcast_deauth_enabled); 18048 /* Ignore request to deauth bcmc station */ 18049 if (!is_sap_bcast_deauth_enabled) 18050 if (param->peerMacAddr.bytes[0] & 0x1) 18051 return qdf_status; 18052 18053 qdf_status = 18054 wlansap_deauth_sta(WLAN_HDD_GET_SAP_CTX_PTR(adapter->deflink), 18055 param); 18056 18057 hdd_exit(); 18058 return qdf_status; 18059 } 18060 18061 /** 18062 * hdd_softap_sta_disassoc() - take counter measure to handle deauth req from HDD 18063 * @adapter: Pointer to the HDD 18064 * @param: pointer to station deletion parameters 18065 * 18066 * This to take counter measure to handle deauth req from HDD 18067 * 18068 * Return: None 18069 */ 18070 void hdd_softap_sta_disassoc(struct hdd_adapter *adapter, 18071 struct csr_del_sta_params *param) 18072 { 18073 hdd_enter(); 18074 18075 /* Ignore request to disassoc bcmc station */ 18076 if (param->peerMacAddr.bytes[0] & 0x1) 18077 return; 18078 18079 wlansap_disassoc_sta(WLAN_HDD_GET_SAP_CTX_PTR(adapter->deflink), 18080 param); 18081 } 18082 18083 void 18084 wlan_hdd_set_roaming_state(struct wlan_hdd_link_info *cur_link_info, 18085 enum wlan_cm_rso_control_requestor rso_op_requestor, 18086 bool enab_roam) 18087 { 18088 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(cur_link_info->adapter); 18089 struct hdd_adapter *adapter = NULL, *next_adapter = NULL; 18090 wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_DISABLE_ROAMING; 18091 uint8_t vdev_id, cur_vdev_id = cur_link_info->vdev_id; 18092 struct wlan_hdd_link_info *link_info; 18093 18094 if (!policy_mgr_is_sta_active_connection_exists(hdd_ctx->psoc)) 18095 return; 18096 18097 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 18098 dbgid) { 18099 hdd_adapter_for_each_active_link_info(adapter, link_info) { 18100 vdev_id = link_info->vdev_id; 18101 if (cur_vdev_id != link_info->vdev_id && 18102 adapter->device_mode == QDF_STA_MODE && 18103 hdd_cm_is_vdev_associated(link_info)) { 18104 if (enab_roam) { 18105 hdd_debug("%d Enable roaming", vdev_id); 18106 sme_start_roaming(hdd_ctx->mac_handle, 18107 vdev_id, 18108 REASON_DRIVER_ENABLED, 18109 rso_op_requestor); 18110 } else { 18111 hdd_debug("%d Disable roaming", 18112 vdev_id); 18113 sme_stop_roaming(hdd_ctx->mac_handle, 18114 vdev_id, 18115 REASON_DRIVER_DISABLED, 18116 rso_op_requestor); 18117 } 18118 } 18119 } 18120 hdd_adapter_dev_put_debug(adapter, dbgid); 18121 } 18122 } 18123 18124 /** 18125 * nl_srv_bcast_svc() - Wrapper function to send bcast msgs to SVC mcast group 18126 * @skb: sk buffer pointer 18127 * 18128 * Sends the bcast message to SVC multicast group with generic nl socket 18129 * if CNSS_GENL is enabled. Else, use the legacy netlink socket to send. 18130 * 18131 * Return: None 18132 */ 18133 static void nl_srv_bcast_svc(struct sk_buff *skb) 18134 { 18135 #ifdef CNSS_GENL 18136 nl_srv_bcast(skb, CLD80211_MCGRP_SVC_MSGS, WLAN_NL_MSG_SVC); 18137 #else 18138 nl_srv_bcast(skb); 18139 #endif 18140 } 18141 18142 void wlan_hdd_send_svc_nlink_msg(int radio, int type, void *data, int len) 18143 { 18144 struct sk_buff *skb; 18145 struct nlmsghdr *nlh; 18146 tAniMsgHdr *ani_hdr; 18147 void *nl_data = NULL; 18148 int flags = GFP_KERNEL; 18149 struct radio_index_tlv *radio_info; 18150 int tlv_len; 18151 18152 if (in_interrupt() || irqs_disabled() || in_atomic()) 18153 flags = GFP_ATOMIC; 18154 18155 skb = alloc_skb(NLMSG_SPACE(WLAN_NL_MAX_PAYLOAD), flags); 18156 18157 if (!skb) 18158 return; 18159 18160 nlh = (struct nlmsghdr *)skb->data; 18161 nlh->nlmsg_pid = 0; /* from kernel */ 18162 nlh->nlmsg_flags = 0; 18163 nlh->nlmsg_seq = 0; 18164 nlh->nlmsg_type = WLAN_NL_MSG_SVC; 18165 18166 ani_hdr = NLMSG_DATA(nlh); 18167 ani_hdr->type = type; 18168 18169 switch (type) { 18170 case WLAN_SVC_FW_CRASHED_IND: 18171 case WLAN_SVC_FW_SHUTDOWN_IND: 18172 case WLAN_SVC_LTE_COEX_IND: 18173 case WLAN_SVC_WLAN_AUTO_SHUTDOWN_IND: 18174 case WLAN_SVC_WLAN_AUTO_SHUTDOWN_CANCEL_IND: 18175 ani_hdr->length = 0; 18176 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr))); 18177 break; 18178 case WLAN_SVC_WLAN_STATUS_IND: 18179 case WLAN_SVC_WLAN_VERSION_IND: 18180 case WLAN_SVC_DFS_CAC_START_IND: 18181 case WLAN_SVC_DFS_CAC_END_IND: 18182 case WLAN_SVC_DFS_RADAR_DETECT_IND: 18183 case WLAN_SVC_DFS_ALL_CHANNEL_UNAVAIL_IND: 18184 case WLAN_SVC_WLAN_TP_IND: 18185 case WLAN_SVC_WLAN_TP_TX_IND: 18186 case WLAN_SVC_RPS_ENABLE_IND: 18187 case WLAN_SVC_CORE_MINFREQ: 18188 ani_hdr->length = len; 18189 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr) + len)); 18190 nl_data = (char *)ani_hdr + sizeof(tAniMsgHdr); 18191 memcpy(nl_data, data, len); 18192 break; 18193 18194 default: 18195 hdd_err("WLAN SVC: Attempt to send unknown nlink message %d", 18196 type); 18197 kfree_skb(skb); 18198 return; 18199 } 18200 18201 /* 18202 * Add radio index at the end of the svc event in TLV format 18203 * to maintain the backward compatibility with userspace 18204 * applications. 18205 */ 18206 18207 tlv_len = 0; 18208 18209 if ((sizeof(*ani_hdr) + len + sizeof(struct radio_index_tlv)) 18210 < WLAN_NL_MAX_PAYLOAD) { 18211 radio_info = (struct radio_index_tlv *)((char *) ani_hdr + 18212 sizeof(*ani_hdr) + len); 18213 radio_info->type = (unsigned short) WLAN_SVC_WLAN_RADIO_INDEX; 18214 radio_info->length = (unsigned short) sizeof(radio_info->radio); 18215 radio_info->radio = radio; 18216 tlv_len = sizeof(*radio_info); 18217 hdd_debug("Added radio index tlv - radio index %d", 18218 radio_info->radio); 18219 } 18220 18221 nlh->nlmsg_len += tlv_len; 18222 skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr) + len + tlv_len)); 18223 18224 nl_srv_bcast_svc(skb); 18225 } 18226 18227 #ifdef FEATURE_WLAN_AUTO_SHUTDOWN 18228 void wlan_hdd_auto_shutdown_cb(void) 18229 { 18230 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 18231 18232 if (!hdd_ctx) 18233 return; 18234 18235 hdd_debug("Wlan Idle. Sending Shutdown event.."); 18236 wlan_hdd_send_svc_nlink_msg(hdd_ctx->radio_index, 18237 WLAN_SVC_WLAN_AUTO_SHUTDOWN_IND, NULL, 0); 18238 } 18239 18240 void wlan_hdd_auto_shutdown_enable(struct hdd_context *hdd_ctx, bool enable) 18241 { 18242 struct hdd_adapter *adapter, *next_adapter = NULL; 18243 bool ap_connected = false, sta_connected = false; 18244 mac_handle_t mac_handle; 18245 struct wlan_hdd_link_info *link_info; 18246 struct hdd_ap_ctx *ap_ctx; 18247 wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_AUTO_SHUTDOWN_ENABLE; 18248 18249 mac_handle = hdd_ctx->mac_handle; 18250 if (!mac_handle) 18251 return; 18252 18253 if (hdd_ctx->config->wlan_auto_shutdown == 0) 18254 return; 18255 18256 if (enable == false) { 18257 if (sme_set_auto_shutdown_timer(mac_handle, 0) != 18258 QDF_STATUS_SUCCESS) { 18259 hdd_err("Failed to stop wlan auto shutdown timer"); 18260 } 18261 wlan_hdd_send_svc_nlink_msg(hdd_ctx->radio_index, 18262 WLAN_SVC_WLAN_AUTO_SHUTDOWN_CANCEL_IND, NULL, 0); 18263 return; 18264 } 18265 18266 /* To enable shutdown timer check conncurrency */ 18267 if (!policy_mgr_concurrent_open_sessions_running(hdd_ctx->psoc)) 18268 goto start_timer; 18269 18270 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, 18271 next_adapter, dbgid) { 18272 hdd_adapter_for_each_active_link_info(adapter, link_info) { 18273 if (adapter->device_mode == QDF_STA_MODE && 18274 hdd_cm_is_vdev_associated(link_info)) { 18275 sta_connected = true; 18276 hdd_adapter_dev_put_debug(adapter, dbgid); 18277 if (next_adapter) 18278 hdd_adapter_dev_put_debug(next_adapter, 18279 dbgid); 18280 break; 18281 } 18282 18283 if (adapter->device_mode == QDF_SAP_MODE) { 18284 ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(link_info); 18285 if (ap_ctx->ap_active == true) { 18286 ap_connected = true; 18287 hdd_adapter_dev_put_debug(adapter, 18288 dbgid); 18289 if (next_adapter) 18290 hdd_adapter_dev_put_debug( 18291 next_adapter, 18292 dbgid); 18293 break; 18294 } 18295 } 18296 } 18297 hdd_adapter_dev_put_debug(adapter, dbgid); 18298 } 18299 18300 start_timer: 18301 if (ap_connected == true || sta_connected == true) { 18302 hdd_debug("CC Session active. Shutdown timer not enabled"); 18303 return; 18304 } 18305 18306 if (sme_set_auto_shutdown_timer(mac_handle, 18307 hdd_ctx->config->wlan_auto_shutdown) 18308 != QDF_STATUS_SUCCESS) 18309 hdd_err("Failed to start wlan auto shutdown timer"); 18310 else 18311 hdd_info("Auto Shutdown timer for %d seconds enabled", 18312 hdd_ctx->config->wlan_auto_shutdown); 18313 } 18314 #endif 18315 18316 struct hdd_adapter * 18317 hdd_get_con_sap_adapter(struct hdd_adapter *this_sap_adapter, 18318 bool check_start_bss) 18319 { 18320 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(this_sap_adapter); 18321 struct hdd_adapter *adapter, *next_adapter = NULL; 18322 wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_GET_CON_SAP_ADAPTER; 18323 struct wlan_hdd_link_info *link_info; 18324 18325 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 18326 dbgid) { 18327 if ((adapter->device_mode == QDF_SAP_MODE || 18328 adapter->device_mode == QDF_P2P_GO_MODE) && 18329 adapter != this_sap_adapter) { 18330 hdd_adapter_for_each_active_link_info(adapter, 18331 link_info) { 18332 if (!check_start_bss) { 18333 hdd_adapter_dev_put_debug(adapter, 18334 dbgid); 18335 if (next_adapter) 18336 hdd_adapter_dev_put_debug( 18337 next_adapter, 18338 dbgid); 18339 return adapter; 18340 } 18341 if (test_bit(SOFTAP_BSS_STARTED, 18342 &link_info->link_flags)) { 18343 hdd_adapter_dev_put_debug(adapter, 18344 dbgid); 18345 if (next_adapter) 18346 hdd_adapter_dev_put_debug( 18347 next_adapter, 18348 dbgid); 18349 return adapter; 18350 } 18351 } 18352 } 18353 hdd_adapter_dev_put_debug(adapter, dbgid); 18354 } 18355 18356 return NULL; 18357 } 18358 18359 static inline bool hdd_adapter_is_sta(struct hdd_adapter *adapter) 18360 { 18361 return adapter->device_mode == QDF_STA_MODE || 18362 adapter->device_mode == QDF_P2P_CLIENT_MODE; 18363 } 18364 18365 bool hdd_is_any_adapter_connected(struct hdd_context *hdd_ctx) 18366 { 18367 struct hdd_adapter *adapter, *next_adapter = NULL; 18368 wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_IS_ANY_ADAPTER_CONNECTED; 18369 struct wlan_hdd_link_info *link_info; 18370 18371 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 18372 dbgid) { 18373 hdd_adapter_for_each_active_link_info(adapter, link_info) { 18374 if (hdd_adapter_is_sta(adapter) && 18375 hdd_cm_is_vdev_associated(link_info)) { 18376 hdd_adapter_dev_put_debug(adapter, dbgid); 18377 if (next_adapter) 18378 hdd_adapter_dev_put_debug(next_adapter, 18379 dbgid); 18380 return true; 18381 } 18382 18383 if (hdd_adapter_is_ap(adapter) && 18384 WLAN_HDD_GET_AP_CTX_PTR(link_info)->ap_active) { 18385 hdd_adapter_dev_put_debug(adapter, dbgid); 18386 if (next_adapter) 18387 hdd_adapter_dev_put_debug(next_adapter, 18388 dbgid); 18389 return true; 18390 } 18391 18392 if (adapter->device_mode == QDF_NDI_MODE && 18393 hdd_cm_is_vdev_associated(link_info)) { 18394 hdd_adapter_dev_put_debug(adapter, dbgid); 18395 if (next_adapter) 18396 hdd_adapter_dev_put_debug(next_adapter, 18397 dbgid); 18398 return true; 18399 } 18400 } 18401 hdd_adapter_dev_put_debug(adapter, dbgid); 18402 } 18403 18404 return false; 18405 } 18406 18407 #if defined MSM_PLATFORM && (LINUX_VERSION_CODE <= KERNEL_VERSION(4, 19, 0)) 18408 /** 18409 * hdd_inform_stop_sap() - call cfg80211 API to stop SAP 18410 * @adapter: pointer to adapter 18411 * 18412 * This function calls cfg80211 API to stop SAP 18413 * 18414 * Return: None 18415 */ 18416 static void hdd_inform_stop_sap(struct hdd_adapter *adapter) 18417 { 18418 hdd_debug("SAP stopped due to invalid channel vdev id %d", 18419 wlan_vdev_get_id(adapter->deflink->vdev)); 18420 cfg80211_ap_stopped(adapter->dev, GFP_KERNEL); 18421 } 18422 18423 #else 18424 static void hdd_inform_stop_sap(struct hdd_adapter *adapter) 18425 { 18426 hdd_debug("SAP stopped due to invalid channel vdev id %d", 18427 wlan_vdev_get_id(adapter->deflink->vdev)); 18428 cfg80211_stop_iface(adapter->hdd_ctx->wiphy, &adapter->wdev, 18429 GFP_KERNEL); 18430 } 18431 #endif 18432 18433 /** 18434 * wlan_hdd_stop_sap() - This function stops bss of SAP. 18435 * @ap_adapter: SAP adapter 18436 * 18437 * This function will process the stopping of sap adapter. 18438 * 18439 * Return: None 18440 */ 18441 void wlan_hdd_stop_sap(struct hdd_adapter *ap_adapter) 18442 { 18443 struct hdd_ap_ctx *hdd_ap_ctx; 18444 struct hdd_hostapd_state *hostapd_state; 18445 QDF_STATUS qdf_status; 18446 struct hdd_context *hdd_ctx; 18447 18448 if (!ap_adapter) { 18449 hdd_err("ap_adapter is NULL here"); 18450 return; 18451 } 18452 18453 hdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(ap_adapter->deflink); 18454 hdd_ctx = WLAN_HDD_GET_CTX(ap_adapter); 18455 if (wlan_hdd_validate_context(hdd_ctx)) 18456 return; 18457 18458 mutex_lock(&hdd_ctx->sap_lock); 18459 if (test_bit(SOFTAP_BSS_STARTED, &ap_adapter->deflink->link_flags)) { 18460 wlan_hdd_del_station(ap_adapter, NULL); 18461 hostapd_state = 18462 WLAN_HDD_GET_HOSTAP_STATE_PTR(ap_adapter->deflink); 18463 hdd_debug("Now doing SAP STOPBSS"); 18464 qdf_event_reset(&hostapd_state->qdf_stop_bss_event); 18465 if (QDF_STATUS_SUCCESS == wlansap_stop_bss(hdd_ap_ctx-> 18466 sap_context)) { 18467 qdf_status = qdf_wait_single_event(&hostapd_state-> 18468 qdf_stop_bss_event, 18469 SME_CMD_STOP_BSS_TIMEOUT); 18470 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { 18471 mutex_unlock(&hdd_ctx->sap_lock); 18472 hdd_err("SAP Stop Failed"); 18473 return; 18474 } 18475 } 18476 clear_bit(SOFTAP_BSS_STARTED, &ap_adapter->deflink->link_flags); 18477 policy_mgr_decr_session_set_pcl(hdd_ctx->psoc, 18478 ap_adapter->device_mode, 18479 ap_adapter->deflink->vdev_id); 18480 hdd_green_ap_start_state_mc(hdd_ctx, ap_adapter->device_mode, 18481 false); 18482 hdd_inform_stop_sap(ap_adapter); 18483 hdd_debug("SAP Stop Success"); 18484 } else { 18485 hdd_err("Can't stop ap because its not started"); 18486 } 18487 mutex_unlock(&hdd_ctx->sap_lock); 18488 } 18489 18490 #if defined(WLAN_FEATURE_11BE_MLO) && defined(CFG80211_11BE_BASIC) 18491 /** 18492 * wlan_hdd_mlo_sap_reinit() - handle mlo scenario for ssr 18493 * @link_info: Pointer of link_info in adapter 18494 * 18495 * Return: QDF_STATUS 18496 */ 18497 static QDF_STATUS wlan_hdd_mlo_sap_reinit(struct wlan_hdd_link_info *link_info) 18498 { 18499 struct hdd_context *hdd_ctx = link_info->adapter->hdd_ctx; 18500 struct sap_config *config = &link_info->session.ap.sap_config; 18501 18502 if (config->mlo_sap) { 18503 if (!mlo_ap_vdev_attach(link_info->vdev, config->link_id, 18504 config->num_link)) { 18505 hdd_err("SAP mlo mgr attach fail"); 18506 return QDF_STATUS_E_INVAL; 18507 } 18508 } 18509 18510 if (!policy_mgr_is_mlo_sap_concurrency_allowed(hdd_ctx->psoc, 18511 config->mlo_sap, 18512 wlan_vdev_get_id(link_info->vdev))) { 18513 hdd_err("MLO SAP concurrency check fails"); 18514 return QDF_STATUS_E_INVAL; 18515 } 18516 18517 return QDF_STATUS_SUCCESS; 18518 } 18519 #else 18520 static inline QDF_STATUS 18521 wlan_hdd_mlo_sap_reinit(struct wlan_hdd_link_info *link_info) 18522 { 18523 return QDF_STATUS_SUCCESS; 18524 } 18525 #endif 18526 18527 void wlan_hdd_set_sap_beacon_protection(struct hdd_context *hdd_ctx, 18528 struct wlan_hdd_link_info *link_info, 18529 struct hdd_beacon_data *beacon) 18530 { 18531 const uint8_t *ie = NULL; 18532 struct s_ext_cap *p_ext_cap; 18533 struct wlan_objmgr_vdev *vdev; 18534 bool target_bigtk_support = false; 18535 uint8_t vdev_id; 18536 uint8_t ie_len; 18537 18538 if (!beacon) { 18539 hdd_err("beacon is null"); 18540 return; 18541 } 18542 18543 ie = wlan_get_ie_ptr_from_eid(DOT11F_EID_EXTCAP, beacon->tail, 18544 beacon->tail_len); 18545 if (!ie) { 18546 hdd_err("IE is null"); 18547 return; 18548 } 18549 18550 if (ie[1] > DOT11F_IE_EXTCAP_MAX_LEN || 18551 ie[1] < DOT11F_IE_EXTCAP_MIN_LEN) { 18552 hdd_err("Invalid IEs eid: %d elem_len: %d", ie[0], ie[1]); 18553 return; 18554 } 18555 18556 p_ext_cap = qdf_mem_malloc(sizeof(*p_ext_cap)); 18557 if (!p_ext_cap) 18558 return; 18559 18560 ie_len = (ie[1] > sizeof(*p_ext_cap)) ? sizeof(*p_ext_cap) : ie[1]; 18561 18562 qdf_mem_copy(p_ext_cap, &ie[2], ie_len); 18563 18564 vdev = hdd_objmgr_get_vdev_by_user(link_info, WLAN_HDD_ID_OBJ_MGR); 18565 if (!vdev) { 18566 hdd_err("vdev is null"); 18567 goto end; 18568 } 18569 18570 vdev_id = wlan_vdev_get_id(vdev); 18571 18572 hdd_debug("vdev %d beacon protection %d", vdev_id, 18573 p_ext_cap->beacon_protection_enable); 18574 18575 ucfg_mlme_get_bigtk_support(hdd_ctx->psoc, &target_bigtk_support); 18576 18577 if (target_bigtk_support && p_ext_cap->beacon_protection_enable) 18578 mlme_set_bigtk_support(vdev, true); 18579 18580 hdd_objmgr_put_vdev_by_user(vdev, WLAN_HDD_ID_OBJ_MGR); 18581 18582 end: 18583 qdf_mem_free(p_ext_cap); 18584 } 18585 18586 void wlan_hdd_start_sap(struct wlan_hdd_link_info *link_info, bool reinit) 18587 { 18588 struct hdd_ap_ctx *ap_ctx; 18589 struct hdd_hostapd_state *hostapd_state; 18590 QDF_STATUS qdf_status; 18591 struct hdd_context *hdd_ctx; 18592 struct sap_config *sap_config; 18593 struct hdd_adapter *ap_adapter = link_info->adapter; 18594 18595 if (QDF_SAP_MODE != ap_adapter->device_mode) { 18596 hdd_err("SoftAp role has not been enabled"); 18597 return; 18598 } 18599 18600 hdd_ctx = WLAN_HDD_GET_CTX(ap_adapter); 18601 ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(link_info); 18602 hostapd_state = WLAN_HDD_GET_HOSTAP_STATE_PTR(link_info); 18603 sap_config = &ap_ctx->sap_config; 18604 18605 mutex_lock(&hdd_ctx->sap_lock); 18606 if (test_bit(SOFTAP_BSS_STARTED, &link_info->link_flags)) 18607 goto end; 18608 18609 if (wlan_hdd_cfg80211_update_apies(link_info)) { 18610 hdd_err("SAP Not able to set AP IEs"); 18611 goto end; 18612 } 18613 wlan_reg_set_channel_params_for_pwrmode(hdd_ctx->pdev, 18614 sap_config->chan_freq, 0, 18615 &sap_config->ch_params, 18616 REG_CURRENT_PWR_MODE); 18617 qdf_status = wlan_hdd_mlo_sap_reinit(link_info); 18618 if (QDF_IS_STATUS_ERROR(qdf_status)) { 18619 hdd_err("SAP Not able to do mlo attach"); 18620 goto end; 18621 } 18622 18623 qdf_event_reset(&hostapd_state->qdf_event); 18624 qdf_status = wlansap_start_bss(ap_ctx->sap_context, 18625 hdd_hostapd_sap_event_cb, sap_config, 18626 ap_adapter->dev); 18627 if (QDF_IS_STATUS_ERROR(qdf_status)) 18628 goto end; 18629 18630 wlan_hdd_set_sap_beacon_protection(hdd_ctx, link_info, ap_ctx->beacon); 18631 18632 hdd_debug("Waiting for SAP to start"); 18633 qdf_status = qdf_wait_single_event(&hostapd_state->qdf_event, 18634 SME_CMD_START_BSS_TIMEOUT); 18635 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { 18636 hdd_err("SAP Start failed"); 18637 goto end; 18638 } 18639 hdd_info("SAP Start Success"); 18640 18641 wlansap_reset_sap_config_add_ie(sap_config, eUPDATE_IE_ALL); 18642 set_bit(SOFTAP_BSS_STARTED, &link_info->link_flags); 18643 if (hostapd_state->bss_state == BSS_START) { 18644 policy_mgr_incr_active_session(hdd_ctx->psoc, 18645 ap_adapter->device_mode, 18646 link_info->vdev_id); 18647 hdd_green_ap_start_state_mc(hdd_ctx, ap_adapter->device_mode, 18648 true); 18649 } 18650 mutex_unlock(&hdd_ctx->sap_lock); 18651 18652 return; 18653 end: 18654 wlan_hdd_mlo_reset(link_info); 18655 wlansap_reset_sap_config_add_ie(sap_config, eUPDATE_IE_ALL); 18656 mutex_unlock(&hdd_ctx->sap_lock); 18657 /* SAP context and beacon cleanup will happen during driver unload 18658 * in hdd_stop_adapter 18659 */ 18660 hdd_err("SAP restart after SSR failed! Reload WLAN and try SAP again"); 18661 /* Free the beacon memory in case of failure in the sap restart */ 18662 qdf_mem_free(ap_ctx->beacon); 18663 ap_ctx->beacon = NULL; 18664 } 18665 18666 #ifdef QCA_CONFIG_SMP 18667 /** 18668 * wlan_hdd_get_cpu() - get cpu_index 18669 * 18670 * Return: cpu_index 18671 */ 18672 int wlan_hdd_get_cpu(void) 18673 { 18674 int cpu_index = get_cpu(); 18675 18676 put_cpu(); 18677 return cpu_index; 18678 } 18679 #endif 18680 18681 /** 18682 * hdd_get_fwpath() - get framework path 18683 * 18684 * This function is used to get the string written by 18685 * userspace to start the wlan driver 18686 * 18687 * Return: string 18688 */ 18689 const char *hdd_get_fwpath(void) 18690 { 18691 return fwpath.string; 18692 } 18693 18694 static inline int hdd_state_query_cb(void) 18695 { 18696 return !!wlan_hdd_validate_context(cds_get_context(QDF_MODULE_ID_HDD)); 18697 } 18698 18699 static int __hdd_op_protect_cb(void **out_sync, const char *func) 18700 { 18701 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 18702 18703 if (!hdd_ctx) 18704 return -EAGAIN; 18705 18706 return __osif_psoc_sync_op_start(hdd_ctx->parent_dev, 18707 (struct osif_psoc_sync **)out_sync, 18708 func); 18709 } 18710 18711 static void __hdd_op_unprotect_cb(void *sync, const char *func) 18712 { 18713 __osif_psoc_sync_op_stop(sync, func); 18714 } 18715 18716 #ifdef WLAN_LOGGING_SOCK_SVC_ENABLE 18717 /** 18718 * hdd_logging_sock_init_svc() - Initialize logging sock 18719 * 18720 * Return: 0 for success, errno on failure 18721 */ 18722 static int 18723 hdd_logging_sock_init_svc(void) 18724 { 18725 return wlan_logging_sock_init_svc(); 18726 } 18727 #else 18728 static inline int 18729 hdd_logging_sock_init_svc(void) 18730 { 18731 return 0; 18732 } 18733 #endif 18734 18735 /** 18736 * hdd_init() - Initialize Driver 18737 * 18738 * This function initializes CDS global context with the help of cds_init. This 18739 * has to be the first function called after probe to get a valid global 18740 * context. 18741 * 18742 * Return: 0 for success, errno on failure 18743 */ 18744 int hdd_init(void) 18745 { 18746 QDF_STATUS status; 18747 18748 status = cds_init(); 18749 if (QDF_IS_STATUS_ERROR(status)) { 18750 hdd_err("Failed to allocate CDS context"); 18751 return -ENOMEM; 18752 } 18753 18754 qdf_op_callbacks_register(__hdd_op_protect_cb, __hdd_op_unprotect_cb); 18755 18756 wlan_init_bug_report_lock(); 18757 18758 if (hdd_logging_sock_init_svc()) { 18759 hdd_err("logging sock init failed."); 18760 goto err; 18761 } 18762 18763 hdd_trace_init(); 18764 hdd_register_debug_callback(); 18765 wlan_roam_debug_init(); 18766 18767 return 0; 18768 18769 err: 18770 wlan_destroy_bug_report_lock(); 18771 qdf_op_callbacks_register(NULL, NULL); 18772 cds_deinit(); 18773 return -ENOMEM; 18774 } 18775 18776 /** 18777 * hdd_deinit() - Deinitialize Driver 18778 * 18779 * This function frees CDS global context with the help of cds_deinit. This 18780 * has to be the last function call in remove callback to free the global 18781 * context. 18782 */ 18783 void hdd_deinit(void) 18784 { 18785 wlan_roam_debug_deinit(); 18786 18787 #ifdef WLAN_LOGGING_SOCK_SVC_ENABLE 18788 wlan_logging_sock_deinit_svc(); 18789 #endif 18790 18791 wlan_destroy_bug_report_lock(); 18792 qdf_op_callbacks_register(NULL, NULL); 18793 cds_deinit(); 18794 } 18795 18796 #ifdef QCA_WIFI_EMULATION 18797 #define HDD_WLAN_START_WAIT_TIME ((CDS_WMA_TIMEOUT + 5000) * 100) 18798 #else 18799 #define HDD_WLAN_START_WAIT_TIME (CDS_WMA_TIMEOUT + 5000) 18800 #endif 18801 18802 void hdd_init_start_completion(void) 18803 { 18804 INIT_COMPLETION(wlan_start_comp); 18805 } 18806 18807 #ifdef WLAN_CTRL_NAME 18808 static unsigned int dev_num = 1; 18809 static struct cdev wlan_hdd_state_cdev; 18810 static struct class *class; 18811 static dev_t device; 18812 18813 static void hdd_set_adapter_wlm_def_level(struct hdd_context *hdd_ctx) 18814 { 18815 struct hdd_adapter *adapter, *next_adapter = NULL; 18816 wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_GET_ADAPTER; 18817 int ret; 18818 QDF_STATUS qdf_status; 18819 uint8_t latency_level; 18820 bool reset; 18821 18822 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) 18823 return; 18824 18825 ret = wlan_hdd_validate_context(hdd_ctx); 18826 if (ret != 0) 18827 return; 18828 18829 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 18830 dbgid) { 18831 qdf_status = ucfg_mlme_cfg_get_wlm_level(hdd_ctx->psoc, 18832 &latency_level); 18833 if (QDF_IS_STATUS_ERROR(qdf_status)) 18834 adapter->latency_level = 18835 QCA_WLAN_VENDOR_ATTR_CONFIG_LATENCY_LEVEL_NORMAL; 18836 else 18837 adapter->latency_level = latency_level; 18838 qdf_status = ucfg_mlme_cfg_get_wlm_reset(hdd_ctx->psoc, &reset); 18839 if (QDF_IS_STATUS_ERROR(qdf_status)) { 18840 hdd_err("could not get the wlm reset flag"); 18841 reset = false; 18842 } 18843 18844 if (hdd_get_multi_client_ll_support(adapter) && !reset) 18845 wlan_hdd_deinit_multi_client_info_table(adapter); 18846 18847 adapter->upgrade_udp_qos_threshold = QCA_WLAN_AC_BK; 18848 hdd_debug("UDP packets qos reset to: %d", 18849 adapter->upgrade_udp_qos_threshold); 18850 hdd_adapter_dev_put_debug(adapter, dbgid); 18851 } 18852 } 18853 18854 static int wlan_hdd_state_ctrl_param_open(struct inode *inode, 18855 struct file *file) 18856 { 18857 qdf_atomic_inc(&wlan_hdd_state_fops_ref); 18858 18859 return 0; 18860 } 18861 18862 static void __hdd_inform_wifi_off(void) 18863 { 18864 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 18865 int ret; 18866 18867 ret = wlan_hdd_validate_context(hdd_ctx); 18868 if (ret != 0) 18869 return; 18870 18871 ucfg_dlm_wifi_off(hdd_ctx->pdev); 18872 18873 if (rtnl_trylock()) { 18874 wlan_hdd_lpc_del_monitor_interface(hdd_ctx, false); 18875 rtnl_unlock(); 18876 } 18877 } 18878 18879 static void hdd_inform_wifi_off(void) 18880 { 18881 int ret; 18882 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 18883 struct osif_psoc_sync *psoc_sync; 18884 18885 if (!hdd_ctx) 18886 return; 18887 18888 ret = osif_psoc_sync_op_start(wiphy_dev(hdd_ctx->wiphy), &psoc_sync); 18889 if (ret) 18890 return; 18891 18892 hdd_set_adapter_wlm_def_level(hdd_ctx); 18893 __hdd_inform_wifi_off(); 18894 18895 osif_psoc_sync_op_stop(psoc_sync); 18896 } 18897 18898 #if defined CFG80211_USER_HINT_CELL_BASE_SELF_MANAGED || \ 18899 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 18, 0)) 18900 static void hdd_inform_wifi_on(void) 18901 { 18902 int ret; 18903 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 18904 struct osif_psoc_sync *psoc_sync; 18905 18906 hdd_nofl_debug("inform regdomain for wifi on"); 18907 ret = wlan_hdd_validate_context(hdd_ctx); 18908 if (ret) 18909 return; 18910 if (!wlan_hdd_validate_modules_state(hdd_ctx)) 18911 return; 18912 if (!hdd_ctx->wiphy) 18913 return; 18914 ret = osif_psoc_sync_op_start(wiphy_dev(hdd_ctx->wiphy), &psoc_sync); 18915 if (ret) 18916 return; 18917 if (hdd_ctx->wiphy->registered) 18918 hdd_send_wiphy_regd_sync_event(hdd_ctx); 18919 18920 osif_psoc_sync_op_stop(psoc_sync); 18921 } 18922 #else 18923 static void hdd_inform_wifi_on(void) 18924 { 18925 } 18926 #endif 18927 18928 static int hdd_validate_wlan_string(const char __user *user_buf) 18929 { 18930 char buf[15]; 18931 int i; 18932 static const char * const wlan_str[] = { 18933 [WLAN_OFF_STR] = "OFF", 18934 [WLAN_ON_STR] = "ON", 18935 [WLAN_ENABLE_STR] = "ENABLE", 18936 [WLAN_DISABLE_STR] = "DISABLE", 18937 [WLAN_WAIT_FOR_READY_STR] = "WAIT_FOR_READY", 18938 [WLAN_FORCE_DISABLE_STR] = "FORCE_DISABLE" 18939 }; 18940 18941 if (copy_from_user(buf, user_buf, sizeof(buf))) { 18942 pr_err("Failed to read buffer\n"); 18943 return -EINVAL; 18944 } 18945 18946 for (i = 0; i < ARRAY_SIZE(wlan_str); i++) { 18947 if (qdf_str_ncmp(buf, wlan_str[i], strlen(wlan_str[i])) == 0) 18948 return i; 18949 } 18950 18951 return -EINVAL; 18952 } 18953 18954 #ifdef FEATURE_CNSS_HW_SECURE_DISABLE 18955 #define WIFI_DISABLE_SLEEP (10) 18956 #define WIFI_DISABLE_MAX_RETRY_ATTEMPTS (10) 18957 static bool g_soft_unload; 18958 18959 bool hdd_get_wlan_driver_status(void) 18960 { 18961 return g_soft_unload; 18962 } 18963 18964 static int hdd_wlan_soft_driver_load(void) 18965 { 18966 if (!cds_is_driver_loaded()) { 18967 hdd_debug("\nEnabling CNSS WLAN HW"); 18968 pld_wlan_hw_enable(); 18969 return 0; 18970 } 18971 18972 if (!g_soft_unload) { 18973 hdd_debug_rl("Enabling WiFi\n"); 18974 return -EINVAL; 18975 } 18976 18977 hdd_driver_load(); 18978 g_soft_unload = false; 18979 return 0; 18980 } 18981 18982 static void hdd_wlan_soft_driver_unload(void) 18983 { 18984 if (g_soft_unload) { 18985 hdd_debug_rl("WiFi is already disabled"); 18986 return; 18987 } 18988 hdd_debug("Initiating soft driver unload\n"); 18989 g_soft_unload = true; 18990 hdd_driver_unload(); 18991 } 18992 18993 static int hdd_wlan_idle_shutdown(struct hdd_context *hdd_ctx) 18994 { 18995 int ret; 18996 int retries = 0; 18997 void *hif_ctx; 18998 18999 if (!hdd_ctx) { 19000 hdd_err_rl("hdd_ctx is Null"); 19001 return -EINVAL; 19002 } 19003 19004 hif_ctx = cds_get_context(QDF_MODULE_ID_HIF); 19005 19006 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_IDLE_SHUTDOWN); 19007 19008 while (retries < WIFI_DISABLE_MAX_RETRY_ATTEMPTS) { 19009 if (hif_ctx) { 19010 /* 19011 * Trigger runtime sync resume before psoc_idle_shutdown 19012 * such that resume can happen successfully 19013 */ 19014 qdf_rtpm_sync_resume(); 19015 } 19016 ret = pld_idle_shutdown(hdd_ctx->parent_dev, 19017 hdd_psoc_idle_shutdown); 19018 19019 if (-EAGAIN == ret || hdd_ctx->is_wiphy_suspended) { 19020 hdd_debug("System suspend in progress.Retries done:%d", 19021 retries); 19022 msleep(WIFI_DISABLE_SLEEP); 19023 retries++; 19024 continue; 19025 } 19026 break; 19027 } 19028 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_IDLE_SHUTDOWN); 19029 19030 if (retries > WIFI_DISABLE_MAX_RETRY_ATTEMPTS) { 19031 hdd_debug("Max retries reached"); 19032 return -EINVAL; 19033 } 19034 hdd_debug_rl("WiFi is disabled"); 19035 19036 return 0; 19037 } 19038 19039 static int hdd_disable_wifi(struct hdd_context *hdd_ctx) 19040 { 19041 int ret; 19042 19043 if (hdd_ctx->is_wlan_disabled) { 19044 hdd_err_rl("Wifi is already disabled"); 19045 return 0; 19046 } 19047 19048 hdd_debug("Initiating WLAN idle shutdown"); 19049 if (hdd_is_any_interface_open(hdd_ctx)) { 19050 hdd_err("Interfaces still open, cannot process wifi disable"); 19051 return -EAGAIN; 19052 } 19053 19054 hdd_ctx->is_wlan_disabled = true; 19055 19056 ret = hdd_wlan_idle_shutdown(hdd_ctx); 19057 if (ret) 19058 hdd_ctx->is_wlan_disabled = false; 19059 19060 return ret; 19061 } 19062 #else 19063 static int hdd_wlan_soft_driver_load(void) 19064 { 19065 return -EINVAL; 19066 } 19067 19068 static void hdd_wlan_soft_driver_unload(void) 19069 { 19070 } 19071 19072 static int hdd_disable_wifi(struct hdd_context *hdd_ctx) 19073 { 19074 return 0; 19075 } 19076 #endif /* FEATURE_CNSS_HW_SECURE_DISABLE */ 19077 19078 static ssize_t wlan_hdd_state_ctrl_param_write(struct file *filp, 19079 const char __user *user_buf, 19080 size_t count, 19081 loff_t *f_pos) 19082 { 19083 int id, ret; 19084 unsigned long rc; 19085 struct hdd_context *hdd_ctx; 19086 bool is_wait_for_ready = false; 19087 bool is_wlan_force_disabled; 19088 19089 hdd_enter(); 19090 19091 id = hdd_validate_wlan_string(user_buf); 19092 19093 switch (id) { 19094 case WLAN_OFF_STR: 19095 hdd_info("Wifi turning off from UI\n"); 19096 hdd_inform_wifi_off(); 19097 goto exit; 19098 case WLAN_ON_STR: 19099 hdd_info("Wifi Turning On from UI\n"); 19100 break; 19101 case WLAN_WAIT_FOR_READY_STR: 19102 is_wait_for_ready = true; 19103 hdd_info("Wifi wait for ready from UI\n"); 19104 break; 19105 case WLAN_ENABLE_STR: 19106 hdd_nofl_debug("Received WiFi enable from framework\n"); 19107 if (!hdd_wlan_soft_driver_load()) 19108 goto exit; 19109 pr_info("Enabling WiFi\n"); 19110 break; 19111 case WLAN_DISABLE_STR: 19112 hdd_nofl_debug("Received WiFi disable from framework\n"); 19113 if (!cds_is_driver_loaded()) 19114 goto exit; 19115 19116 is_wlan_force_disabled = hdd_get_wlan_driver_status(); 19117 if (is_wlan_force_disabled) 19118 goto exit; 19119 pr_info("Disabling WiFi\n"); 19120 break; 19121 case WLAN_FORCE_DISABLE_STR: 19122 hdd_nofl_debug("Received Force WiFi disable from framework\n"); 19123 if (!cds_is_driver_loaded()) 19124 goto exit; 19125 19126 hdd_wlan_soft_driver_unload(); 19127 goto exit; 19128 default: 19129 hdd_err_rl("Invalid value received from framework"); 19130 return -EINVAL; 19131 } 19132 19133 hdd_info("is_driver_loaded %d is_driver_recovering %d", 19134 cds_is_driver_loaded(), cds_is_driver_recovering()); 19135 19136 if (!cds_is_driver_loaded() || cds_is_driver_recovering()) { 19137 rc = wait_for_completion_timeout(&wlan_start_comp, 19138 msecs_to_jiffies(HDD_WLAN_START_WAIT_TIME)); 19139 if (!rc) { 19140 hdd_err("Driver Loading Timed-out!!"); 19141 ret = -EINVAL; 19142 return ret; 19143 } 19144 } 19145 19146 if (is_wait_for_ready) 19147 return count; 19148 /* 19149 * Flush idle shutdown work for cases to synchronize the wifi on 19150 * during the idle shutdown. 19151 */ 19152 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 19153 if (hdd_ctx) 19154 hdd_psoc_idle_timer_stop(hdd_ctx); 19155 19156 if (id == WLAN_DISABLE_STR) { 19157 if (!hdd_ctx) { 19158 hdd_err_rl("hdd_ctx is Null"); 19159 goto exit; 19160 } 19161 19162 ret = hdd_disable_wifi(hdd_ctx); 19163 if (ret) 19164 return ret; 19165 } 19166 19167 if (id == WLAN_ENABLE_STR) { 19168 if (!hdd_ctx) { 19169 hdd_err_rl("hdd_ctx is Null"); 19170 goto exit; 19171 } 19172 19173 if (!hdd_ctx->is_wlan_disabled) { 19174 hdd_err_rl("WiFi is already enabled"); 19175 goto exit; 19176 } 19177 hdd_ctx->is_wlan_disabled = false; 19178 } 19179 19180 if (id == WLAN_ON_STR) 19181 hdd_inform_wifi_on(); 19182 exit: 19183 hdd_exit(); 19184 return count; 19185 } 19186 19187 /** 19188 * wlan_hdd_state_ctrl_param_release() - Release callback for /dev/wlan. 19189 * 19190 * @inode: struct inode pointer. 19191 * @file: struct file pointer. 19192 * 19193 * Release callback that would be invoked when the file operations has 19194 * completed fully. This is implemented to provide a reference count mechanism 19195 * via which the driver can wait till all possible usage of the /dev/wlan 19196 * file is completed. 19197 * 19198 * Return: Success 19199 */ 19200 static int wlan_hdd_state_ctrl_param_release(struct inode *inode, 19201 struct file *file) 19202 { 19203 qdf_atomic_dec(&wlan_hdd_state_fops_ref); 19204 19205 return 0; 19206 } 19207 19208 const struct file_operations wlan_hdd_state_fops = { 19209 .owner = THIS_MODULE, 19210 .open = wlan_hdd_state_ctrl_param_open, 19211 .write = wlan_hdd_state_ctrl_param_write, 19212 .release = wlan_hdd_state_ctrl_param_release, 19213 }; 19214 19215 #if (LINUX_VERSION_CODE < KERNEL_VERSION(6, 2, 0)) 19216 static struct class *wlan_hdd_class_create(const char *name) 19217 { 19218 return class_create(THIS_MODULE, name); 19219 } 19220 #else 19221 static struct class *wlan_hdd_class_create(const char *name) 19222 { 19223 return class_create(name); 19224 } 19225 #endif 19226 19227 static int wlan_hdd_state_ctrl_param_create(void) 19228 { 19229 unsigned int wlan_hdd_state_major = 0; 19230 int ret; 19231 struct device *dev; 19232 19233 init_completion(&wlan_start_comp); 19234 qdf_atomic_init(&wlan_hdd_state_fops_ref); 19235 19236 device = MKDEV(wlan_hdd_state_major, 0); 19237 19238 ret = alloc_chrdev_region(&device, 0, dev_num, "qcwlanstate"); 19239 if (ret) { 19240 pr_err("Failed to register qcwlanstate"); 19241 goto dev_alloc_err; 19242 } 19243 wlan_hdd_state_major = MAJOR(device); 19244 class = wlan_hdd_class_create(WLAN_CTRL_NAME); 19245 if (IS_ERR(class)) { 19246 pr_err("wlan_hdd_state class_create error"); 19247 goto class_err; 19248 } 19249 19250 dev = device_create(class, NULL, device, NULL, WLAN_CTRL_NAME); 19251 if (IS_ERR(dev)) { 19252 pr_err("wlan_hdd_statedevice_create error"); 19253 goto err_class_destroy; 19254 } 19255 19256 cdev_init(&wlan_hdd_state_cdev, &wlan_hdd_state_fops); 19257 19258 wlan_hdd_state_cdev.owner = THIS_MODULE; 19259 19260 ret = cdev_add(&wlan_hdd_state_cdev, device, dev_num); 19261 if (ret) { 19262 pr_err("Failed to add cdev error"); 19263 goto cdev_add_err; 19264 } 19265 19266 pr_info("wlan_hdd_state %s major(%d) initialized", 19267 WLAN_CTRL_NAME, wlan_hdd_state_major); 19268 19269 return 0; 19270 19271 cdev_add_err: 19272 device_destroy(class, device); 19273 err_class_destroy: 19274 class_destroy(class); 19275 class_err: 19276 unregister_chrdev_region(device, dev_num); 19277 dev_alloc_err: 19278 return -ENODEV; 19279 } 19280 19281 /* 19282 * When multiple instances of the driver are loaded in parallel, only 19283 * one can create and own the state ctrl param. An instance of the 19284 * driver that creates the state ctrl param will wait for 19285 * HDD_WLAN_START_WAIT_TIME to be probed. If it is probed, then that 19286 * instance of the driver will stay loaded and no other instances of 19287 * the driver can load. But if it is not probed, then that instance of 19288 * the driver will destroy the state ctrl param and exit, and another 19289 * instance of the driver can then create the state ctrl param. 19290 */ 19291 19292 /* max number of instances we expect (arbitrary) */ 19293 #define WLAN_DRIVER_MAX_INSTANCES 5 19294 19295 /* max amount of time an instance has to wait for all instances */ 19296 #define CTRL_PARAM_WAIT (WLAN_DRIVER_MAX_INSTANCES * HDD_WLAN_START_WAIT_TIME) 19297 19298 /* amount of time we sleep for each retry (arbitrary) */ 19299 #define CTRL_PARAM_SLEEP 100 19300 19301 static void wlan_hdd_state_ctrl_param_destroy(void) 19302 { 19303 cdev_del(&wlan_hdd_state_cdev); 19304 device_destroy(class, device); 19305 class_destroy(class); 19306 unregister_chrdev_region(device, dev_num); 19307 19308 pr_info("Device node unregistered"); 19309 } 19310 19311 #else /* WLAN_CTRL_NAME */ 19312 19313 static int wlan_hdd_state_ctrl_param_create(void) 19314 { 19315 return 0; 19316 } 19317 19318 static void wlan_hdd_state_ctrl_param_destroy(void) 19319 { 19320 } 19321 19322 #endif /* WLAN_CTRL_NAME */ 19323 19324 /** 19325 * hdd_send_scan_done_complete_cb() - API to send scan done indication to upper 19326 * layer 19327 * @vdev_id: vdev id 19328 * 19329 * Return: none 19330 */ 19331 static void hdd_send_scan_done_complete_cb(uint8_t vdev_id) 19332 { 19333 struct hdd_context *hdd_ctx; 19334 struct wlan_hdd_link_info *link_info; 19335 struct hdd_adapter *adapter; 19336 struct sk_buff *vendor_event; 19337 uint32_t len; 19338 19339 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 19340 if (!hdd_ctx) 19341 return; 19342 19343 link_info = hdd_get_link_info_by_vdev(hdd_ctx, vdev_id); 19344 if (!link_info) { 19345 hdd_err("Invalid vdev id:%d", vdev_id); 19346 return; 19347 } 19348 19349 adapter = link_info->adapter; 19350 len = NLMSG_HDRLEN; 19351 vendor_event = 19352 wlan_cfg80211_vendor_event_alloc( 19353 hdd_ctx->wiphy, &adapter->wdev, len, 19354 QCA_NL80211_VENDOR_SUBCMD_CONNECTED_CHANNEL_STATS_INDEX, 19355 GFP_KERNEL); 19356 19357 if (!vendor_event) { 19358 hdd_err("wlan_cfg80211_vendor_event_alloc failed"); 19359 return; 19360 } 19361 19362 hdd_debug("sending scan done ind to upper layer for vdev_id:%d", 19363 vdev_id); 19364 wlan_cfg80211_vendor_event(vendor_event, GFP_KERNEL); 19365 } 19366 19367 struct osif_vdev_mgr_ops osif_vdev_mgrlegacy_ops = { 19368 #ifdef WLAN_FEATURE_DYNAMIC_MAC_ADDR_UPDATE 19369 .osif_vdev_mgr_set_mac_addr_response = hdd_set_mac_addr_event_cb, 19370 #endif 19371 .osif_vdev_mgr_send_scan_done_complete_cb = 19372 hdd_send_scan_done_complete_cb, 19373 19374 }; 19375 19376 static QDF_STATUS hdd_vdev_mgr_register_cb(void) 19377 { 19378 osif_vdev_mgr_set_legacy_cb(&osif_vdev_mgrlegacy_ops); 19379 return osif_vdev_mgr_register_cb(); 19380 } 19381 19382 static void hdd_vdev_mgr_unregister_cb(void) 19383 { 19384 osif_vdev_mgr_reset_legacy_cb(); 19385 } 19386 19387 /** 19388 * hdd_ll_sap_register_cb() - Register ll_sap osif callbacks 19389 * 19390 * Return: QDF_STATUS 19391 */ 19392 static QDF_STATUS hdd_ll_sap_register_cb(void) 19393 { 19394 return osif_ll_sap_register_cb(); 19395 } 19396 19397 /** 19398 * hdd_ll_sap_unregister_cb() - Un-register ll_sap osif callbacks 19399 * 19400 * Return: void 19401 */ 19402 static void hdd_ll_sap_unregister_cb(void) 19403 { 19404 osif_ll_sap_unregister_cb(); 19405 } 19406 19407 /** 19408 * hdd_component_cb_init() - Initialize component callbacks 19409 * 19410 * This function initializes hdd callbacks to different 19411 * components 19412 * 19413 * Context: Any context. 19414 * Return: QDF_STATUS 19415 */ 19416 static QDF_STATUS hdd_component_cb_init(void) 19417 { 19418 QDF_STATUS status; 19419 19420 status = hdd_cm_register_cb(); 19421 if (QDF_IS_STATUS_ERROR(status)) 19422 return status; 19423 19424 status = hdd_vdev_mgr_register_cb(); 19425 if (QDF_IS_STATUS_ERROR(status)) 19426 goto cm_unregister_cb; 19427 19428 status = osif_twt_register_cb(); 19429 if (QDF_IS_STATUS_ERROR(status)) 19430 goto hdd_vdev_mgr_unregister_cb; 19431 19432 status = hdd_pre_cac_register_cb(); 19433 if (QDF_IS_STATUS_ERROR(status)) 19434 goto hdd_vdev_mgr_unregister_cb; 19435 19436 status = hdd_ll_sap_register_cb(); 19437 if (QDF_IS_STATUS_ERROR(status)) 19438 goto pre_cac_unregister_cb; 19439 19440 return QDF_STATUS_SUCCESS; 19441 19442 pre_cac_unregister_cb: 19443 hdd_pre_cac_unregister_cb(); 19444 hdd_vdev_mgr_unregister_cb: 19445 hdd_vdev_mgr_unregister_cb(); 19446 cm_unregister_cb: 19447 hdd_cm_unregister_cb(); 19448 return status; 19449 } 19450 19451 /** 19452 * hdd_component_cb_deinit() - De-initialize component callbacks 19453 * 19454 * This function de-initializes hdd callbacks with different components 19455 * 19456 * Context: Any context. 19457 * Return: None` 19458 */ 19459 static void hdd_component_cb_deinit(void) 19460 { 19461 hdd_ll_sap_unregister_cb(); 19462 hdd_pre_cac_unregister_cb(); 19463 hdd_vdev_mgr_unregister_cb(); 19464 hdd_cm_unregister_cb(); 19465 } 19466 19467 /** 19468 * hdd_component_init() - Initialize all components 19469 * 19470 * Return: QDF_STATUS 19471 */ 19472 static QDF_STATUS hdd_component_init(void) 19473 { 19474 QDF_STATUS status; 19475 19476 /* initialize converged components */ 19477 19478 status = ucfg_mlme_global_init(); 19479 if (QDF_IS_STATUS_ERROR(status)) 19480 return status; 19481 19482 status = dispatcher_init(); 19483 if (QDF_IS_STATUS_ERROR(status)) 19484 goto mlme_global_deinit; 19485 19486 status = target_if_init(wma_get_psoc_from_scn_handle); 19487 if (QDF_IS_STATUS_ERROR(status)) 19488 goto dispatcher_deinit; 19489 19490 /* initialize non-converged components */ 19491 status = ucfg_mlme_init(); 19492 if (QDF_IS_STATUS_ERROR(status)) 19493 goto target_if_deinit; 19494 19495 status = ucfg_fwol_init(); 19496 if (QDF_IS_STATUS_ERROR(status)) 19497 goto mlme_deinit; 19498 19499 status = disa_init(); 19500 if (QDF_IS_STATUS_ERROR(status)) 19501 goto fwol_deinit; 19502 19503 status = pmo_init(); 19504 if (QDF_IS_STATUS_ERROR(status)) 19505 goto disa_deinit; 19506 19507 status = ucfg_ocb_init(); 19508 if (QDF_IS_STATUS_ERROR(status)) 19509 goto pmo_deinit; 19510 19511 status = ipa_init(); 19512 if (QDF_IS_STATUS_ERROR(status)) 19513 goto ocb_deinit; 19514 19515 status = ucfg_action_oui_init(); 19516 if (QDF_IS_STATUS_ERROR(status)) 19517 goto ipa_deinit; 19518 19519 status = nan_init(); 19520 if (QDF_IS_STATUS_ERROR(status)) 19521 goto action_oui_deinit; 19522 19523 status = ucfg_p2p_init(); 19524 if (QDF_IS_STATUS_ERROR(status)) 19525 goto nan_deinit; 19526 19527 status = ucfg_interop_issues_ap_init(); 19528 if (QDF_IS_STATUS_ERROR(status)) 19529 goto p2p_deinit; 19530 19531 status = policy_mgr_init(); 19532 if (QDF_IS_STATUS_ERROR(status)) 19533 goto interop_issues_ap_deinit; 19534 19535 status = ucfg_tdls_init(); 19536 if (QDF_IS_STATUS_ERROR(status)) 19537 goto policy_deinit; 19538 19539 status = ucfg_dlm_init(); 19540 if (QDF_IS_STATUS_ERROR(status)) 19541 goto tdls_deinit; 19542 19543 status = ucfg_pkt_capture_init(); 19544 if (QDF_IS_STATUS_ERROR(status)) 19545 goto dlm_deinit; 19546 19547 status = ucfg_ftm_time_sync_init(); 19548 if (QDF_IS_STATUS_ERROR(status)) 19549 goto pkt_capture_deinit; 19550 19551 status = ucfg_pre_cac_init(); 19552 if (QDF_IS_STATUS_ERROR(status)) 19553 goto pre_cac_deinit; 19554 19555 status = ucfg_dp_init(); 19556 if (QDF_IS_STATUS_ERROR(status)) 19557 goto pre_cac_deinit; 19558 19559 status = ucfg_qmi_init(); 19560 if (QDF_IS_STATUS_ERROR(status)) 19561 goto dp_deinit; 19562 19563 status = ucfg_ll_sap_init(); 19564 if (QDF_IS_STATUS_ERROR(status)) 19565 goto qmi_deinit; 19566 19567 status = ucfg_afc_init(); 19568 if (QDF_IS_STATUS_ERROR(status)) 19569 goto ll_sap_deinit; 19570 19571 status = hdd_mlo_mgr_register_osif_ops(); 19572 if (QDF_IS_STATUS_ERROR(status)) 19573 goto afc_deinit; 19574 19575 hdd_register_cstats_ops(); 19576 19577 return QDF_STATUS_SUCCESS; 19578 19579 afc_deinit: 19580 ucfg_afc_deinit(); 19581 ll_sap_deinit: 19582 ucfg_ll_sap_deinit(); 19583 qmi_deinit: 19584 ucfg_qmi_deinit(); 19585 dp_deinit: 19586 ucfg_dp_deinit(); 19587 pre_cac_deinit: 19588 ucfg_pre_cac_deinit(); 19589 pkt_capture_deinit: 19590 ucfg_pkt_capture_deinit(); 19591 dlm_deinit: 19592 ucfg_dlm_deinit(); 19593 tdls_deinit: 19594 ucfg_tdls_deinit(); 19595 policy_deinit: 19596 policy_mgr_deinit(); 19597 interop_issues_ap_deinit: 19598 ucfg_interop_issues_ap_deinit(); 19599 p2p_deinit: 19600 ucfg_p2p_deinit(); 19601 nan_deinit: 19602 nan_deinit(); 19603 action_oui_deinit: 19604 ucfg_action_oui_deinit(); 19605 ipa_deinit: 19606 ipa_deinit(); 19607 ocb_deinit: 19608 ucfg_ocb_deinit(); 19609 pmo_deinit: 19610 pmo_deinit(); 19611 disa_deinit: 19612 disa_deinit(); 19613 fwol_deinit: 19614 ucfg_fwol_deinit(); 19615 mlme_deinit: 19616 ucfg_mlme_deinit(); 19617 target_if_deinit: 19618 target_if_deinit(); 19619 dispatcher_deinit: 19620 dispatcher_deinit(); 19621 mlme_global_deinit: 19622 ucfg_mlme_global_deinit(); 19623 19624 return status; 19625 } 19626 19627 /** 19628 * hdd_component_deinit() - Deinitialize all components 19629 * 19630 * Return: None 19631 */ 19632 static void hdd_component_deinit(void) 19633 { 19634 /* deinitialize non-converged components */ 19635 hdd_mlo_mgr_unregister_osif_ops(); 19636 ucfg_afc_deinit(); 19637 ucfg_ll_sap_deinit(); 19638 ucfg_qmi_deinit(); 19639 ucfg_dp_deinit(); 19640 ucfg_pre_cac_deinit(); 19641 ucfg_ftm_time_sync_deinit(); 19642 ucfg_pkt_capture_deinit(); 19643 ucfg_dlm_deinit(); 19644 ucfg_tdls_deinit(); 19645 policy_mgr_deinit(); 19646 ucfg_interop_issues_ap_deinit(); 19647 ucfg_p2p_deinit(); 19648 nan_deinit(); 19649 ucfg_action_oui_deinit(); 19650 ipa_deinit(); 19651 ucfg_ocb_deinit(); 19652 pmo_deinit(); 19653 disa_deinit(); 19654 ucfg_fwol_deinit(); 19655 ucfg_mlme_deinit(); 19656 19657 /* deinitialize converged components */ 19658 target_if_deinit(); 19659 dispatcher_deinit(); 19660 ucfg_mlme_global_deinit(); 19661 } 19662 19663 QDF_STATUS hdd_component_psoc_open(struct wlan_objmgr_psoc *psoc) 19664 { 19665 QDF_STATUS status; 19666 19667 status = ucfg_mlme_psoc_open(psoc); 19668 if (QDF_IS_STATUS_ERROR(status)) 19669 return status; 19670 19671 status = ucfg_dlm_psoc_open(psoc); 19672 if (QDF_IS_STATUS_ERROR(status)) 19673 goto err_dlm; 19674 19675 status = ucfg_fwol_psoc_open(psoc); 19676 if (QDF_IS_STATUS_ERROR(status)) 19677 goto err_fwol; 19678 19679 status = ucfg_pmo_psoc_open(psoc); 19680 if (QDF_IS_STATUS_ERROR(status)) 19681 goto err_pmo; 19682 19683 status = ucfg_policy_mgr_psoc_open(psoc); 19684 if (QDF_IS_STATUS_ERROR(status)) 19685 goto err_plcy_mgr; 19686 19687 status = ucfg_p2p_psoc_open(psoc); 19688 if (QDF_IS_STATUS_ERROR(status)) 19689 goto err_p2p; 19690 19691 status = ucfg_tdls_psoc_open(psoc); 19692 if (QDF_IS_STATUS_ERROR(status)) 19693 goto err_tdls; 19694 19695 status = ucfg_nan_psoc_open(psoc); 19696 if (QDF_IS_STATUS_ERROR(status)) 19697 goto err_nan; 19698 19699 status = ucfg_twt_psoc_open(psoc); 19700 if (QDF_IS_STATUS_ERROR(status)) 19701 goto err_twt; 19702 19703 status = ucfg_wifi_pos_psoc_open(psoc); 19704 if (QDF_IS_STATUS_ERROR(status)) 19705 goto err_wifi_pos; 19706 19707 status = ucfg_dp_psoc_open(psoc); 19708 if (QDF_IS_STATUS_ERROR(status)) 19709 goto err_dp; 19710 19711 return status; 19712 19713 err_dp: 19714 ucfg_wifi_pos_psoc_close(psoc); 19715 err_wifi_pos: 19716 ucfg_twt_psoc_close(psoc); 19717 err_twt: 19718 ucfg_nan_psoc_close(psoc); 19719 err_nan: 19720 ucfg_tdls_psoc_close(psoc); 19721 err_tdls: 19722 ucfg_p2p_psoc_close(psoc); 19723 err_p2p: 19724 ucfg_policy_mgr_psoc_close(psoc); 19725 err_plcy_mgr: 19726 ucfg_pmo_psoc_close(psoc); 19727 err_pmo: 19728 ucfg_fwol_psoc_close(psoc); 19729 err_fwol: 19730 ucfg_dlm_psoc_close(psoc); 19731 err_dlm: 19732 ucfg_mlme_psoc_close(psoc); 19733 19734 return status; 19735 } 19736 19737 void hdd_component_psoc_close(struct wlan_objmgr_psoc *psoc) 19738 { 19739 ucfg_dp_psoc_close(psoc); 19740 ucfg_wifi_pos_psoc_close(psoc); 19741 ucfg_twt_psoc_close(psoc); 19742 ucfg_nan_psoc_close(psoc); 19743 ucfg_tdls_psoc_close(psoc); 19744 ucfg_p2p_psoc_close(psoc); 19745 ucfg_policy_mgr_psoc_close(psoc); 19746 ucfg_pmo_psoc_close(psoc); 19747 ucfg_fwol_psoc_close(psoc); 19748 ucfg_dlm_psoc_close(psoc); 19749 ucfg_mlme_psoc_close(psoc); 19750 19751 if (!cds_is_driver_recovering()) 19752 ucfg_crypto_flush_entries(psoc); 19753 } 19754 19755 void hdd_component_psoc_enable(struct wlan_objmgr_psoc *psoc) 19756 { 19757 ocb_psoc_enable(psoc); 19758 disa_psoc_enable(psoc); 19759 nan_psoc_enable(psoc); 19760 p2p_psoc_enable(psoc); 19761 ucfg_interop_issues_ap_psoc_enable(psoc); 19762 policy_mgr_psoc_enable(psoc); 19763 ucfg_tdls_psoc_enable(psoc); 19764 ucfg_fwol_psoc_enable(psoc); 19765 ucfg_action_oui_psoc_enable(psoc); 19766 ucfg_ll_sap_psoc_enable(psoc); 19767 } 19768 19769 void hdd_component_psoc_disable(struct wlan_objmgr_psoc *psoc) 19770 { 19771 ucfg_ll_sap_psoc_disable(psoc); 19772 ucfg_action_oui_psoc_disable(psoc); 19773 ucfg_fwol_psoc_disable(psoc); 19774 ucfg_tdls_psoc_disable(psoc); 19775 policy_mgr_psoc_disable(psoc); 19776 ucfg_interop_issues_ap_psoc_disable(psoc); 19777 p2p_psoc_disable(psoc); 19778 nan_psoc_disable(psoc); 19779 disa_psoc_disable(psoc); 19780 ocb_psoc_disable(psoc); 19781 } 19782 19783 QDF_STATUS hdd_component_pdev_open(struct wlan_objmgr_pdev *pdev) 19784 { 19785 return ucfg_mlme_pdev_open(pdev); 19786 } 19787 19788 void hdd_component_pdev_close(struct wlan_objmgr_pdev *pdev) 19789 { 19790 ucfg_mlme_pdev_close(pdev); 19791 } 19792 19793 static QDF_STATUS hdd_qdf_print_init(void) 19794 { 19795 QDF_STATUS status; 19796 int qdf_print_idx; 19797 19798 status = qdf_print_setup(); 19799 if (QDF_IS_STATUS_ERROR(status)) { 19800 pr_err("Failed qdf_print_setup; status:%u\n", status); 19801 return status; 19802 } 19803 19804 qdf_print_idx = qdf_print_ctrl_register(cinfo, NULL, NULL, "MCL_WLAN"); 19805 if (qdf_print_idx < 0) { 19806 pr_err("Failed to register for qdf_print_ctrl\n"); 19807 return QDF_STATUS_E_FAILURE; 19808 } 19809 19810 qdf_set_pidx(qdf_print_idx); 19811 19812 return QDF_STATUS_SUCCESS; 19813 } 19814 19815 static void hdd_qdf_print_deinit(void) 19816 { 19817 int qdf_pidx = qdf_get_pidx(); 19818 19819 qdf_set_pidx(-1); 19820 qdf_print_ctrl_cleanup(qdf_pidx); 19821 19822 /* currently, no qdf print 'un-setup'*/ 19823 } 19824 19825 static QDF_STATUS hdd_qdf_init(void) 19826 { 19827 QDF_STATUS status; 19828 19829 status = hdd_qdf_print_init(); 19830 if (QDF_IS_STATUS_ERROR(status)) 19831 goto exit; 19832 19833 status = qdf_debugfs_init(); 19834 if (QDF_IS_STATUS_ERROR(status)) { 19835 hdd_err("Failed to init debugfs; status:%u", status); 19836 goto print_deinit; 19837 } 19838 19839 qdf_lock_stats_init(); 19840 qdf_mem_init(); 19841 qdf_delayed_work_feature_init(); 19842 qdf_periodic_work_feature_init(); 19843 qdf_wake_lock_feature_init(); 19844 qdf_mc_timer_manager_init(); 19845 qdf_event_list_init(); 19846 19847 status = qdf_talloc_feature_init(); 19848 if (QDF_IS_STATUS_ERROR(status)) { 19849 hdd_err("Failed to init talloc; status:%u", status); 19850 goto event_deinit; 19851 } 19852 19853 status = qdf_cpuhp_init(); 19854 if (QDF_IS_STATUS_ERROR(status)) { 19855 hdd_err("Failed to init cpuhp; status:%u", status); 19856 goto talloc_deinit; 19857 } 19858 19859 status = qdf_trace_spin_lock_init(); 19860 if (QDF_IS_STATUS_ERROR(status)) { 19861 hdd_err("Failed to init spinlock; status:%u", status); 19862 goto cpuhp_deinit; 19863 } 19864 19865 qdf_trace_init(); 19866 qdf_minidump_init(); 19867 qdf_ssr_driver_dump_init(); 19868 qdf_register_debugcb_init(); 19869 19870 return QDF_STATUS_SUCCESS; 19871 19872 cpuhp_deinit: 19873 qdf_cpuhp_deinit(); 19874 talloc_deinit: 19875 qdf_talloc_feature_deinit(); 19876 event_deinit: 19877 qdf_event_list_destroy(); 19878 qdf_mc_timer_manager_exit(); 19879 qdf_wake_lock_feature_deinit(); 19880 qdf_periodic_work_feature_deinit(); 19881 qdf_delayed_work_feature_deinit(); 19882 qdf_mem_exit(); 19883 qdf_lock_stats_deinit(); 19884 qdf_debugfs_exit(); 19885 print_deinit: 19886 hdd_qdf_print_deinit(); 19887 19888 exit: 19889 return status; 19890 } 19891 19892 static void hdd_qdf_deinit(void) 19893 { 19894 /* currently, no debugcb deinit */ 19895 qdf_ssr_driver_dump_deinit(); 19896 qdf_minidump_deinit(); 19897 qdf_trace_deinit(); 19898 19899 /* currently, no trace spinlock deinit */ 19900 19901 qdf_cpuhp_deinit(); 19902 qdf_talloc_feature_deinit(); 19903 qdf_event_list_destroy(); 19904 qdf_mc_timer_manager_exit(); 19905 qdf_wake_lock_feature_deinit(); 19906 qdf_periodic_work_feature_deinit(); 19907 qdf_delayed_work_feature_deinit(); 19908 qdf_mem_exit(); 19909 qdf_lock_stats_deinit(); 19910 qdf_debugfs_exit(); 19911 hdd_qdf_print_deinit(); 19912 } 19913 19914 #ifdef FEATURE_MONITOR_MODE_SUPPORT 19915 static bool is_monitor_mode_supported(void) 19916 { 19917 return true; 19918 } 19919 #else 19920 static bool is_monitor_mode_supported(void) 19921 { 19922 pr_err("Monitor mode not supported!"); 19923 return false; 19924 } 19925 #endif 19926 19927 #ifdef WLAN_FEATURE_EPPING 19928 static bool is_epping_mode_supported(void) 19929 { 19930 return true; 19931 } 19932 #else 19933 static bool is_epping_mode_supported(void) 19934 { 19935 pr_err("Epping mode not supported!"); 19936 return false; 19937 } 19938 #endif 19939 19940 #ifdef QCA_WIFI_FTM 19941 static bool is_ftm_mode_supported(void) 19942 { 19943 return true; 19944 } 19945 #else 19946 static bool is_ftm_mode_supported(void) 19947 { 19948 pr_err("FTM mode not supported!"); 19949 return false; 19950 } 19951 #endif 19952 19953 /** 19954 * is_con_mode_valid() - check con mode is valid or not 19955 * @mode: global con mode 19956 * 19957 * Return: TRUE on success FALSE on failure 19958 */ 19959 static bool is_con_mode_valid(enum QDF_GLOBAL_MODE mode) 19960 { 19961 switch (mode) { 19962 case QDF_GLOBAL_MONITOR_MODE: 19963 return is_monitor_mode_supported(); 19964 case QDF_GLOBAL_EPPING_MODE: 19965 return is_epping_mode_supported(); 19966 case QDF_GLOBAL_FTM_MODE: 19967 return is_ftm_mode_supported(); 19968 case QDF_GLOBAL_MISSION_MODE: 19969 return true; 19970 default: 19971 return false; 19972 } 19973 } 19974 19975 static void hdd_stop_present_mode(struct hdd_context *hdd_ctx, 19976 enum QDF_GLOBAL_MODE curr_mode) 19977 { 19978 if (hdd_ctx->driver_status == DRIVER_MODULES_CLOSED) 19979 return; 19980 19981 switch (curr_mode) { 19982 case QDF_GLOBAL_MONITOR_MODE: 19983 hdd_info("Release wakelock for monitor mode!"); 19984 qdf_wake_lock_release(&hdd_ctx->monitor_mode_wakelock, 19985 WIFI_POWER_EVENT_WAKELOCK_MONITOR_MODE); 19986 fallthrough; 19987 case QDF_GLOBAL_MISSION_MODE: 19988 case QDF_GLOBAL_FTM_MODE: 19989 hdd_abort_mac_scan_all_adapters(hdd_ctx); 19990 wlan_cfg80211_cleanup_scan_queue(hdd_ctx->pdev, NULL); 19991 hdd_stop_all_adapters(hdd_ctx); 19992 hdd_deinit_all_adapters(hdd_ctx, false); 19993 19994 break; 19995 default: 19996 break; 19997 } 19998 } 19999 20000 static void hdd_cleanup_present_mode(struct hdd_context *hdd_ctx, 20001 enum QDF_GLOBAL_MODE curr_mode) 20002 { 20003 switch (curr_mode) { 20004 case QDF_GLOBAL_MISSION_MODE: 20005 case QDF_GLOBAL_MONITOR_MODE: 20006 case QDF_GLOBAL_FTM_MODE: 20007 hdd_close_all_adapters(hdd_ctx, false); 20008 break; 20009 case QDF_GLOBAL_EPPING_MODE: 20010 epping_disable(); 20011 epping_close(); 20012 break; 20013 default: 20014 return; 20015 } 20016 } 20017 20018 static int 20019 hdd_parse_driver_mode(const char *mode_str, enum QDF_GLOBAL_MODE *out_mode) 20020 { 20021 QDF_STATUS status; 20022 uint32_t mode; 20023 20024 *out_mode = QDF_GLOBAL_MAX_MODE; 20025 20026 status = qdf_uint32_parse(mode_str, &mode); 20027 if (QDF_IS_STATUS_ERROR(status)) 20028 return qdf_status_to_os_return(status); 20029 20030 if (mode >= QDF_GLOBAL_MAX_MODE) 20031 return -ERANGE; 20032 20033 *out_mode = (enum QDF_GLOBAL_MODE)mode; 20034 20035 return 0; 20036 } 20037 20038 static int hdd_mode_change_psoc_idle_shutdown(struct device *dev) 20039 { 20040 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 20041 20042 if (!hdd_ctx) 20043 return -EINVAL; 20044 20045 return hdd_wlan_stop_modules(hdd_ctx, true); 20046 } 20047 20048 static int hdd_mode_change_psoc_idle_restart(struct device *dev) 20049 { 20050 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 20051 int ret; 20052 20053 if (!hdd_ctx) 20054 return -EINVAL; 20055 ret = hdd_soc_idle_restart_lock(dev); 20056 if (ret) 20057 return ret; 20058 ret = hdd_wlan_start_modules(hdd_ctx, false); 20059 hdd_soc_idle_restart_unlock(); 20060 20061 return ret; 20062 } 20063 20064 /** 20065 * __hdd_driver_mode_change() - Handles a driver mode change 20066 * @hdd_ctx: Pointer to the global HDD context 20067 * @next_mode: the driver mode to transition to 20068 * 20069 * This function is invoked when user updates con_mode using sys entry, 20070 * to initialize and bring-up driver in that specific mode. 20071 * 20072 * Return: Errno 20073 */ 20074 static int __hdd_driver_mode_change(struct hdd_context *hdd_ctx, 20075 enum QDF_GLOBAL_MODE next_mode) 20076 { 20077 enum QDF_GLOBAL_MODE curr_mode; 20078 int errno; 20079 struct bbm_params param = {0}; 20080 20081 hdd_info("Driver mode changing to %d", next_mode); 20082 20083 errno = wlan_hdd_validate_context(hdd_ctx); 20084 if (errno) 20085 return errno; 20086 20087 if (!is_con_mode_valid(next_mode)) { 20088 hdd_err_rl("Requested driver mode is invalid"); 20089 return -EINVAL; 20090 } 20091 20092 curr_mode = hdd_get_conparam(); 20093 if (curr_mode == next_mode) { 20094 hdd_err_rl("Driver is already in the requested mode"); 20095 return 0; 20096 } 20097 20098 hdd_psoc_idle_timer_stop(hdd_ctx); 20099 20100 /* ensure adapters are stopped */ 20101 hdd_stop_present_mode(hdd_ctx, curr_mode); 20102 20103 if (DRIVER_MODULES_CLOSED != hdd_ctx->driver_status) { 20104 is_mode_change_psoc_idle_shutdown = true; 20105 errno = pld_idle_shutdown(hdd_ctx->parent_dev, 20106 hdd_mode_change_psoc_idle_shutdown); 20107 if (errno) { 20108 is_mode_change_psoc_idle_shutdown = false; 20109 hdd_err("Stop wlan modules failed"); 20110 return errno; 20111 } 20112 } 20113 20114 /* Cleanup present mode before switching to new mode */ 20115 hdd_cleanup_present_mode(hdd_ctx, curr_mode); 20116 20117 hdd_set_conparam(next_mode); 20118 pld_set_mode(next_mode); 20119 20120 qdf_event_reset(&hdd_ctx->regulatory_update_event); 20121 qdf_mutex_acquire(&hdd_ctx->regulatory_status_lock); 20122 hdd_ctx->is_regulatory_update_in_progress = true; 20123 qdf_mutex_release(&hdd_ctx->regulatory_status_lock); 20124 20125 errno = pld_idle_restart(hdd_ctx->parent_dev, 20126 hdd_mode_change_psoc_idle_restart); 20127 if (errno) { 20128 hdd_err("Start wlan modules failed: %d", errno); 20129 return errno; 20130 } 20131 20132 errno = hdd_open_adapters_for_mode(hdd_ctx, next_mode); 20133 if (errno) { 20134 hdd_err("Failed to open adapters"); 20135 return errno; 20136 } 20137 20138 if (next_mode == QDF_GLOBAL_MONITOR_MODE) { 20139 struct hdd_adapter *adapter = 20140 hdd_get_adapter(hdd_ctx, QDF_MONITOR_MODE); 20141 20142 QDF_BUG(adapter); 20143 if (!adapter) { 20144 hdd_err("Failed to get monitor adapter"); 20145 return -EINVAL; 20146 } 20147 20148 errno = hdd_start_adapter(adapter, false); 20149 if (errno) { 20150 hdd_err("Failed to start monitor adapter"); 20151 return errno; 20152 } 20153 20154 hdd_info("Acquire wakelock for monitor mode"); 20155 qdf_wake_lock_acquire(&hdd_ctx->monitor_mode_wakelock, 20156 WIFI_POWER_EVENT_WAKELOCK_MONITOR_MODE); 20157 } 20158 20159 /* con_mode is a global module parameter */ 20160 con_mode = next_mode; 20161 hdd_info("Driver mode successfully changed to %d", next_mode); 20162 20163 param.policy = BBM_DRIVER_MODE_POLICY; 20164 param.policy_info.driver_mode = con_mode; 20165 ucfg_dp_bbm_apply_independent_policy(hdd_ctx->psoc, ¶m); 20166 20167 return 0; 20168 } 20169 20170 static void hdd_pre_mode_change(enum QDF_GLOBAL_MODE mode) 20171 { 20172 struct osif_psoc_sync *psoc_sync; 20173 struct hdd_context *hdd_ctx; 20174 int errno; 20175 enum QDF_GLOBAL_MODE curr_mode; 20176 20177 curr_mode = hdd_get_conparam(); 20178 if (curr_mode != QDF_GLOBAL_MISSION_MODE) 20179 return; 20180 20181 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 20182 errno = wlan_hdd_validate_context(hdd_ctx); 20183 if (errno) 20184 return; 20185 20186 errno = osif_psoc_sync_op_start(hdd_ctx->parent_dev, &psoc_sync); 20187 if (errno) { 20188 hdd_err("psoc op start failed"); 20189 return; 20190 } 20191 20192 hdd_debug("cleanup scan queue"); 20193 if (hdd_ctx && hdd_ctx->pdev) 20194 wlan_cfg80211_cleanup_scan_queue(hdd_ctx->pdev, NULL); 20195 20196 osif_psoc_sync_op_stop(psoc_sync); 20197 } 20198 20199 static int hdd_driver_mode_change(enum QDF_GLOBAL_MODE mode) 20200 { 20201 struct osif_driver_sync *driver_sync; 20202 struct hdd_context *hdd_ctx; 20203 QDF_STATUS status; 20204 int errno; 20205 20206 hdd_enter(); 20207 20208 hdd_pre_mode_change(mode); 20209 20210 status = osif_driver_sync_trans_start_wait(&driver_sync); 20211 if (QDF_IS_STATUS_ERROR(status)) { 20212 hdd_err("Failed to start 'mode change'; status:%u", status); 20213 errno = qdf_status_to_os_return(status); 20214 goto exit; 20215 } 20216 20217 osif_driver_sync_wait_for_ops(driver_sync); 20218 20219 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 20220 errno = wlan_hdd_validate_context(hdd_ctx); 20221 if (errno) 20222 goto trans_stop; 20223 20224 errno = __hdd_driver_mode_change(hdd_ctx, mode); 20225 20226 trans_stop: 20227 osif_driver_sync_trans_stop(driver_sync); 20228 20229 exit: 20230 hdd_exit(); 20231 20232 return errno; 20233 } 20234 20235 static int hdd_set_con_mode(enum QDF_GLOBAL_MODE mode) 20236 { 20237 con_mode = mode; 20238 20239 return 0; 20240 } 20241 20242 static int (*hdd_set_con_mode_cb)(enum QDF_GLOBAL_MODE mode) = hdd_set_con_mode; 20243 20244 static void hdd_driver_mode_change_register(void) 20245 { 20246 hdd_set_con_mode_cb = hdd_driver_mode_change; 20247 } 20248 20249 static void hdd_driver_mode_change_unregister(void) 20250 { 20251 hdd_set_con_mode_cb = hdd_set_con_mode; 20252 } 20253 20254 static int con_mode_handler(const char *kmessage, const struct kernel_param *kp) 20255 { 20256 enum QDF_GLOBAL_MODE mode; 20257 int errno; 20258 20259 errno = hdd_parse_driver_mode(kmessage, &mode); 20260 if (errno) { 20261 hdd_err_rl("Failed to parse driver mode '%s'", kmessage); 20262 return errno; 20263 } 20264 20265 return hdd_set_con_mode_cb(mode); 20266 } 20267 20268 /* 20269 * If the wlan_hdd_register_driver will return an error 20270 * if the wlan driver tries to register with the 20271 * platform driver before cnss_probe is completed. 20272 * Depending on the error code, the wlan driver waits 20273 * and retries to register. 20274 */ 20275 20276 /* Max number of retries (arbitrary)*/ 20277 #define HDD_MAX_PLD_REGISTER_RETRY (50) 20278 20279 /* Max amount of time we sleep before each retry */ 20280 #define HDD_PLD_REGISTER_FAIL_SLEEP_DURATION (100) 20281 20282 static int hdd_register_driver_retry(void) 20283 { 20284 int count = 0; 20285 int errno; 20286 20287 while (true) { 20288 errno = wlan_hdd_register_driver(); 20289 if (errno != -EAGAIN) 20290 return errno; 20291 hdd_nofl_info("Retry Platform Driver Registration; errno:%d count:%d", 20292 errno, count); 20293 if (++count == HDD_MAX_PLD_REGISTER_RETRY) 20294 return errno; 20295 msleep(HDD_PLD_REGISTER_FAIL_SLEEP_DURATION); 20296 continue; 20297 } 20298 20299 return errno; 20300 } 20301 20302 /** 20303 * hdd_create_wifi_feature_interface() - Create wifi feature interface 20304 * 20305 * Return: none 20306 */ 20307 static void hdd_create_wifi_feature_interface(void) 20308 { 20309 hdd_sysfs_create_wifi_root_obj(); 20310 hdd_create_wifi_feature_interface_sysfs_file(); 20311 } 20312 20313 int hdd_driver_load(void) 20314 { 20315 struct osif_driver_sync *driver_sync; 20316 QDF_STATUS status; 20317 int errno; 20318 bool soft_load; 20319 20320 pr_info("%s: Loading driver v%s\n", WLAN_MODULE_NAME, 20321 g_wlan_driver_version); 20322 hdd_place_marker(NULL, "START LOADING", NULL); 20323 20324 status = hdd_qdf_init(); 20325 if (QDF_IS_STATUS_ERROR(status)) { 20326 errno = qdf_status_to_os_return(status); 20327 goto exit; 20328 } 20329 20330 osif_sync_init(); 20331 20332 status = osif_driver_sync_create_and_trans(&driver_sync); 20333 if (QDF_IS_STATUS_ERROR(status)) { 20334 hdd_err("Failed to init driver sync; status:%u", status); 20335 errno = qdf_status_to_os_return(status); 20336 goto sync_deinit; 20337 } 20338 20339 errno = hdd_init(); 20340 if (errno) { 20341 hdd_err("Failed to init HDD; errno:%d", errno); 20342 goto trans_stop; 20343 } 20344 20345 status = hdd_component_cb_init(); 20346 if (QDF_IS_STATUS_ERROR(status)) { 20347 hdd_err("Failed to init component cb; status:%u", status); 20348 errno = qdf_status_to_os_return(status); 20349 goto hdd_deinit; 20350 } 20351 20352 status = hdd_component_init(); 20353 if (QDF_IS_STATUS_ERROR(status)) { 20354 hdd_err("Failed to init components; status:%u", status); 20355 errno = qdf_status_to_os_return(status); 20356 goto comp_cb_deinit; 20357 } 20358 20359 status = qdf_wake_lock_create(&wlan_wake_lock, "wlan"); 20360 if (QDF_IS_STATUS_ERROR(status)) { 20361 hdd_err("Failed to create wake lock; status:%u", status); 20362 errno = qdf_status_to_os_return(status); 20363 goto comp_deinit; 20364 } 20365 20366 hdd_set_conparam(con_mode); 20367 20368 errno = pld_init(); 20369 if (errno) { 20370 hdd_err("Failed to init PLD; errno:%d", errno); 20371 goto wakelock_destroy; 20372 } 20373 20374 /* driver mode pass to cnss2 platform driver*/ 20375 errno = pld_set_mode(con_mode); 20376 if (errno) 20377 hdd_err("Failed to set mode in PLD; errno:%d", errno); 20378 20379 hdd_driver_mode_change_register(); 20380 20381 osif_driver_sync_register(driver_sync); 20382 osif_driver_sync_trans_stop(driver_sync); 20383 20384 /* psoc probe can happen in registration; do after 'load' transition */ 20385 errno = hdd_register_driver_retry(); 20386 if (errno) { 20387 hdd_err("Failed to register driver; errno:%d", errno); 20388 goto pld_deinit; 20389 } 20390 20391 /* If a soft unload of driver is done, we don't call 20392 * wlan_hdd_state_ctrl_param_destroy() to maintain sync 20393 * with userspace. In Symmetry, during soft load, avoid 20394 * calling wlan_hdd_state_ctrl_param_create(). 20395 */ 20396 soft_load = hdd_get_wlan_driver_status(); 20397 if (soft_load) 20398 goto out; 20399 20400 errno = wlan_hdd_state_ctrl_param_create(); 20401 if (errno) { 20402 hdd_err("Failed to create ctrl param; errno:%d", errno); 20403 goto unregister_driver; 20404 } 20405 hdd_create_wifi_feature_interface(); 20406 out: 20407 hdd_debug("%s: driver loaded", WLAN_MODULE_NAME); 20408 hdd_place_marker(NULL, "DRIVER LOADED", NULL); 20409 20410 return 0; 20411 20412 unregister_driver: 20413 wlan_hdd_unregister_driver(); 20414 pld_deinit: 20415 status = osif_driver_sync_trans_start(&driver_sync); 20416 QDF_BUG(QDF_IS_STATUS_SUCCESS(status)); 20417 20418 osif_driver_sync_unregister(); 20419 if (driver_sync) 20420 osif_driver_sync_wait_for_ops(driver_sync); 20421 20422 hdd_driver_mode_change_unregister(); 20423 pld_deinit(); 20424 20425 hdd_start_complete(errno); 20426 /* Wait for any ref taken on /dev/wlan to be released */ 20427 while (qdf_atomic_read(&wlan_hdd_state_fops_ref)) 20428 ; 20429 wakelock_destroy: 20430 qdf_wake_lock_destroy(&wlan_wake_lock); 20431 comp_deinit: 20432 hdd_component_deinit(); 20433 comp_cb_deinit: 20434 hdd_component_cb_deinit(); 20435 hdd_deinit: 20436 hdd_deinit(); 20437 trans_stop: 20438 if (driver_sync) { 20439 osif_driver_sync_trans_stop(driver_sync); 20440 osif_driver_sync_destroy(driver_sync); 20441 } 20442 sync_deinit: 20443 osif_sync_deinit(); 20444 hdd_qdf_deinit(); 20445 20446 exit: 20447 return errno; 20448 } 20449 20450 #ifdef FEATURE_WLAN_RESIDENT_DRIVER 20451 EXPORT_SYMBOL(hdd_driver_load); 20452 #endif 20453 20454 /** 20455 * hdd_distroy_wifi_feature_interface() - Distroy wifi feature interface 20456 * 20457 * Return: none 20458 */ 20459 static void hdd_distroy_wifi_feature_interface(void) 20460 { 20461 hdd_destroy_wifi_feature_interface_sysfs_file(); 20462 hdd_sysfs_destroy_wifi_root_obj(); 20463 } 20464 20465 void hdd_driver_unload(void) 20466 { 20467 struct osif_driver_sync *driver_sync; 20468 struct hdd_context *hdd_ctx; 20469 QDF_STATUS status; 20470 void *hif_ctx; 20471 bool soft_unload; 20472 20473 soft_unload = hdd_get_wlan_driver_status(); 20474 if (soft_unload) { 20475 pr_info("%s: Soft Unloading driver v%s\n", WLAN_MODULE_NAME, 20476 QWLAN_VERSIONSTR); 20477 } else { 20478 pr_info("%s: Hard Unloading driver v%s\n", WLAN_MODULE_NAME, 20479 QWLAN_VERSIONSTR); 20480 } 20481 20482 hdd_place_marker(NULL, "START UNLOADING", NULL); 20483 20484 /* 20485 * Wait for any trans to complete and then start the driver trans 20486 * for the unload. This will ensure that the driver trans proceeds only 20487 * after all trans have been completed. As a part of this trans, set 20488 * the driver load/unload flag to further ensure that any upcoming 20489 * trans are rejected via wlan_hdd_validate_context. 20490 */ 20491 status = osif_driver_sync_trans_start_wait(&driver_sync); 20492 if (QDF_IS_STATUS_ERROR(status) && status != -ETIMEDOUT) { 20493 QDF_BUG(QDF_IS_STATUS_SUCCESS(status)); 20494 hdd_err("Unable to unload wlan; status:%u", status); 20495 hdd_place_marker(NULL, "UNLOAD FAILURE", NULL); 20496 return; 20497 } 20498 20499 hif_ctx = cds_get_context(QDF_MODULE_ID_HIF); 20500 if (hif_ctx) { 20501 /* 20502 * Trigger runtime sync resume before setting unload in progress 20503 * such that resume can happen successfully 20504 */ 20505 qdf_rtpm_sync_resume(); 20506 } 20507 20508 cds_set_driver_loaded(false); 20509 cds_set_unload_in_progress(true); 20510 20511 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 20512 if (hdd_ctx) { 20513 hdd_psoc_idle_timer_stop(hdd_ctx); 20514 /* 20515 * Runtime PM sync resume may have started the bus bandwidth 20516 * periodic work hence stop it. 20517 */ 20518 ucfg_dp_bus_bw_compute_timer_stop(hdd_ctx->psoc); 20519 } 20520 20521 /* 20522 * Stop the trans before calling unregister_driver as that involves a 20523 * call to pld_remove which in itself is a psoc transaction 20524 */ 20525 if (driver_sync) 20526 osif_driver_sync_trans_stop(driver_sync); 20527 20528 hdd_distroy_wifi_feature_interface(); 20529 if (!soft_unload) 20530 wlan_hdd_state_ctrl_param_destroy(); 20531 20532 /* trigger SoC remove */ 20533 wlan_hdd_unregister_driver(); 20534 20535 status = osif_driver_sync_trans_start_wait(&driver_sync); 20536 if (QDF_IS_STATUS_ERROR(status) && status != -ETIMEDOUT) { 20537 QDF_BUG(QDF_IS_STATUS_SUCCESS(status)); 20538 hdd_err("Unable to unload wlan; status:%u", status); 20539 hdd_place_marker(NULL, "UNLOAD FAILURE", NULL); 20540 return; 20541 } 20542 20543 osif_driver_sync_unregister(); 20544 if (driver_sync) 20545 osif_driver_sync_wait_for_ops(driver_sync); 20546 20547 hdd_driver_mode_change_unregister(); 20548 pld_deinit(); 20549 hdd_set_conparam(0); 20550 qdf_wake_lock_destroy(&wlan_wake_lock); 20551 hdd_component_deinit(); 20552 hdd_component_cb_deinit(); 20553 hdd_deinit(); 20554 20555 if (driver_sync) { 20556 osif_driver_sync_trans_stop(driver_sync); 20557 osif_driver_sync_destroy(driver_sync); 20558 } 20559 osif_sync_deinit(); 20560 20561 hdd_qdf_deinit(); 20562 hdd_place_marker(NULL, "UNLOAD DONE", NULL); 20563 } 20564 20565 #ifdef FEATURE_WLAN_RESIDENT_DRIVER 20566 EXPORT_SYMBOL(hdd_driver_unload); 20567 #endif 20568 20569 #ifndef MODULE 20570 /** 20571 * wlan_boot_cb() - Wlan boot callback 20572 * @kobj: object whose directory we're creating the link in. 20573 * @attr: attribute the user is interacting with 20574 * @buf: the buffer containing the user data 20575 * @count: number of bytes in the buffer 20576 * 20577 * This callback is invoked when the fs is ready to start the 20578 * wlan driver initialization. 20579 * 20580 * Return: 'count' on success or a negative error code in case of failure 20581 */ 20582 static ssize_t wlan_boot_cb(struct kobject *kobj, 20583 struct kobj_attribute *attr, 20584 const char *buf, 20585 size_t count) 20586 { 20587 20588 if (wlan_loader->loaded_state) { 20589 hdd_err("wlan driver already initialized"); 20590 return -EALREADY; 20591 } 20592 20593 if (hdd_driver_load()) 20594 return -EIO; 20595 20596 wlan_loader->loaded_state = MODULE_INITIALIZED; 20597 20598 return count; 20599 } 20600 20601 /** 20602 * hdd_sysfs_cleanup() - cleanup sysfs 20603 * 20604 * Return: None 20605 * 20606 */ 20607 static void hdd_sysfs_cleanup(void) 20608 { 20609 /* remove from group */ 20610 if (wlan_loader->boot_wlan_obj && wlan_loader->attr_group) 20611 sysfs_remove_group(wlan_loader->boot_wlan_obj, 20612 wlan_loader->attr_group); 20613 20614 /* unlink the object from parent */ 20615 kobject_del(wlan_loader->boot_wlan_obj); 20616 20617 /* free the object */ 20618 kobject_put(wlan_loader->boot_wlan_obj); 20619 20620 kfree(wlan_loader->attr_group); 20621 kfree(wlan_loader); 20622 20623 wlan_loader = NULL; 20624 } 20625 20626 /** 20627 * wlan_init_sysfs() - Creates the sysfs to be invoked when the fs is 20628 * ready 20629 * 20630 * This is creates the syfs entry boot_wlan. Which shall be invoked 20631 * when the filesystem is ready. 20632 * 20633 * QDF API cannot be used here since this function is called even before 20634 * initializing WLAN driver. 20635 * 20636 * Return: 0 for success, errno on failure 20637 */ 20638 static int wlan_init_sysfs(void) 20639 { 20640 int ret = -ENOMEM; 20641 20642 wlan_loader = kzalloc(sizeof(*wlan_loader), GFP_KERNEL); 20643 if (!wlan_loader) 20644 return -ENOMEM; 20645 20646 wlan_loader->boot_wlan_obj = NULL; 20647 wlan_loader->attr_group = kzalloc(sizeof(*(wlan_loader->attr_group)), 20648 GFP_KERNEL); 20649 if (!wlan_loader->attr_group) 20650 goto error_return; 20651 20652 wlan_loader->loaded_state = 0; 20653 wlan_loader->attr_group->attrs = attrs; 20654 20655 wlan_loader->boot_wlan_obj = kobject_create_and_add(WLAN_LOADER_NAME, 20656 kernel_kobj); 20657 if (!wlan_loader->boot_wlan_obj) { 20658 hdd_err("sysfs create and add failed"); 20659 goto error_return; 20660 } 20661 20662 ret = sysfs_create_group(wlan_loader->boot_wlan_obj, 20663 wlan_loader->attr_group); 20664 if (ret) { 20665 hdd_err("sysfs create group failed; errno:%d", ret); 20666 goto error_return; 20667 } 20668 20669 return 0; 20670 20671 error_return: 20672 hdd_sysfs_cleanup(); 20673 20674 return ret; 20675 } 20676 20677 /** 20678 * wlan_deinit_sysfs() - Removes the sysfs created to initialize the wlan 20679 * 20680 * Return: 0 on success or errno on failure 20681 */ 20682 static int wlan_deinit_sysfs(void) 20683 { 20684 if (!wlan_loader) { 20685 hdd_err("wlan_loader is null"); 20686 return -EINVAL; 20687 } 20688 20689 hdd_sysfs_cleanup(); 20690 return 0; 20691 } 20692 20693 #endif /* MODULE */ 20694 20695 #ifdef MODULE 20696 /** 20697 * hdd_module_init() - Module init helper 20698 * 20699 * Module init helper function used by both module and static driver. 20700 * 20701 * Return: 0 for success, errno on failure 20702 */ 20703 #ifdef FEATURE_WLAN_RESIDENT_DRIVER 20704 static int hdd_module_init(void) 20705 { 20706 return 0; 20707 } 20708 #else 20709 static int hdd_module_init(void) 20710 { 20711 if (hdd_driver_load()) 20712 return -EINVAL; 20713 20714 return 0; 20715 } 20716 #endif 20717 #else 20718 static int __init hdd_module_init(void) 20719 { 20720 int ret = -EINVAL; 20721 20722 ret = wlan_init_sysfs(); 20723 if (ret) 20724 hdd_err("Failed to create sysfs entry"); 20725 20726 return ret; 20727 } 20728 #endif 20729 20730 20731 #ifdef MODULE 20732 /** 20733 * hdd_module_exit() - Exit function 20734 * 20735 * This is the driver exit point (invoked when module is unloaded using rmmod) 20736 * 20737 * Return: None 20738 */ 20739 #ifdef FEATURE_WLAN_RESIDENT_DRIVER 20740 static void __exit hdd_module_exit(void) 20741 { 20742 } 20743 #else 20744 static void __exit hdd_module_exit(void) 20745 { 20746 hdd_driver_unload(); 20747 } 20748 #endif 20749 #else 20750 static void __exit hdd_module_exit(void) 20751 { 20752 hdd_driver_unload(); 20753 wlan_deinit_sysfs(); 20754 } 20755 #endif 20756 20757 static int fwpath_changed_handler(const char *kmessage, 20758 const struct kernel_param *kp) 20759 { 20760 return param_set_copystring(kmessage, kp); 20761 } 20762 20763 static int con_mode_handler_ftm(const char *kmessage, 20764 const struct kernel_param *kp) 20765 { 20766 int ret; 20767 20768 ret = param_set_int(kmessage, kp); 20769 20770 if (cds_is_driver_loaded() || cds_is_load_or_unload_in_progress()) { 20771 pr_err("Driver already loaded or load/unload in progress"); 20772 return -ENOTSUPP; 20773 } 20774 20775 if (con_mode_ftm != QDF_GLOBAL_FTM_MODE) { 20776 pr_err("Only FTM mode supported!"); 20777 return -ENOTSUPP; 20778 } 20779 20780 hdd_set_conparam(con_mode_ftm); 20781 con_mode = con_mode_ftm; 20782 20783 return ret; 20784 } 20785 20786 #ifdef WLAN_FEATURE_EPPING 20787 static int con_mode_handler_epping(const char *kmessage, 20788 const struct kernel_param *kp) 20789 { 20790 int ret; 20791 20792 ret = param_set_int(kmessage, kp); 20793 20794 if (con_mode_epping != QDF_GLOBAL_EPPING_MODE) { 20795 pr_err("Only EPPING mode supported!"); 20796 return -ENOTSUPP; 20797 } 20798 20799 hdd_set_conparam(con_mode_epping); 20800 con_mode = con_mode_epping; 20801 20802 return ret; 20803 } 20804 #endif 20805 20806 /** 20807 * hdd_get_conparam() - driver exit point 20808 * 20809 * This is the driver exit point (invoked when module is unloaded using rmmod) 20810 * 20811 * Return: enum QDF_GLOBAL_MODE 20812 */ 20813 enum QDF_GLOBAL_MODE hdd_get_conparam(void) 20814 { 20815 return (enum QDF_GLOBAL_MODE) curr_con_mode; 20816 } 20817 20818 void hdd_set_conparam(int32_t con_param) 20819 { 20820 curr_con_mode = con_param; 20821 } 20822 20823 /** 20824 * hdd_svc_fw_crashed_ind() - API to send FW CRASHED IND to Userspace 20825 * 20826 * Return: void 20827 */ 20828 static void hdd_svc_fw_crashed_ind(void) 20829 { 20830 struct hdd_context *hdd_ctx; 20831 20832 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 20833 20834 hdd_ctx ? wlan_hdd_send_svc_nlink_msg(hdd_ctx->radio_index, 20835 WLAN_SVC_FW_CRASHED_IND, 20836 NULL, 0) : 0; 20837 } 20838 20839 /** 20840 * hdd_update_ol_config - API to update ol configuration parameters 20841 * @hdd_ctx: HDD context 20842 * 20843 * Return: void 20844 */ 20845 static void hdd_update_ol_config(struct hdd_context *hdd_ctx) 20846 { 20847 struct ol_config_info cfg = {0}; 20848 struct ol_context *ol_ctx = cds_get_context(QDF_MODULE_ID_BMI); 20849 bool self_recovery = false; 20850 QDF_STATUS status; 20851 20852 if (!ol_ctx) 20853 return; 20854 20855 status = ucfg_mlme_get_self_recovery(hdd_ctx->psoc, &self_recovery); 20856 if (QDF_IS_STATUS_ERROR(status)) 20857 hdd_err("Failed to get self recovery ini config"); 20858 20859 cfg.enable_self_recovery = self_recovery; 20860 cfg.enable_uart_print = hdd_ctx->config->enablefwprint; 20861 cfg.enable_fw_log = hdd_ctx->config->enable_fw_log; 20862 cfg.enable_ramdump_collection = hdd_ctx->config->is_ramdump_enabled; 20863 cfg.enable_lpass_support = hdd_lpass_is_supported(hdd_ctx); 20864 20865 ol_init_ini_config(ol_ctx, &cfg); 20866 ol_set_fw_crashed_cb(ol_ctx, hdd_svc_fw_crashed_ind); 20867 } 20868 20869 #ifdef FEATURE_RUNTIME_PM 20870 /** 20871 * hdd_populate_runtime_cfg() - populate runtime configuration 20872 * @hdd_ctx: hdd context 20873 * @cfg: pointer to the configuration memory being populated 20874 * 20875 * Return: void 20876 */ 20877 static void hdd_populate_runtime_cfg(struct hdd_context *hdd_ctx, 20878 struct hif_config_info *cfg) 20879 { 20880 cfg->enable_runtime_pm = hdd_ctx->config->runtime_pm; 20881 cfg->runtime_pm_delay = 20882 ucfg_pmo_get_runtime_pm_delay(hdd_ctx->psoc); 20883 } 20884 #else 20885 static void hdd_populate_runtime_cfg(struct hdd_context *hdd_ctx, 20886 struct hif_config_info *cfg) 20887 { 20888 } 20889 #endif 20890 20891 #ifdef FEATURE_ENABLE_CE_DP_IRQ_AFFINE 20892 /** 20893 * hdd_populate_ce_dp_irq_affine_cfg() - populate ce irq affine configuration 20894 * @hdd_ctx: hdd context 20895 * @cfg: pointer to the configuration memory being populated 20896 * 20897 * Return: void 20898 */ 20899 static void hdd_populate_ce_dp_irq_affine_cfg(struct hdd_context *hdd_ctx, 20900 struct hif_config_info *cfg) 20901 { 20902 cfg->enable_ce_dp_irq_affine = cfg_get(hdd_ctx->psoc, 20903 CFG_ENABLE_CE_DP_IRQ_AFFINE); 20904 } 20905 #else 20906 static void hdd_populate_ce_dp_irq_affine_cfg(struct hdd_context *hdd_ctx, 20907 struct hif_config_info *cfg) 20908 { 20909 } 20910 #endif 20911 20912 /** 20913 * hdd_update_hif_config - API to update HIF configuration parameters 20914 * @hdd_ctx: HDD Context 20915 * 20916 * Return: void 20917 */ 20918 static void hdd_update_hif_config(struct hdd_context *hdd_ctx) 20919 { 20920 struct hif_opaque_softc *scn = cds_get_context(QDF_MODULE_ID_HIF); 20921 struct hif_config_info cfg = {0}; 20922 bool prevent_link_down = false; 20923 bool self_recovery = false; 20924 QDF_STATUS status; 20925 20926 if (!scn) 20927 return; 20928 20929 status = ucfg_mlme_get_prevent_link_down(hdd_ctx->psoc, 20930 &prevent_link_down); 20931 if (QDF_IS_STATUS_ERROR(status)) 20932 hdd_err("Failed to get prevent_link_down config"); 20933 20934 status = ucfg_mlme_get_self_recovery(hdd_ctx->psoc, &self_recovery); 20935 if (QDF_IS_STATUS_ERROR(status)) 20936 hdd_err("Failed to get self recovery ini config"); 20937 20938 cfg.enable_self_recovery = self_recovery; 20939 hdd_populate_runtime_cfg(hdd_ctx, &cfg); 20940 cfg.rx_softirq_max_yield_duration_ns = 20941 ucfg_dp_get_rx_softirq_yield_duration(hdd_ctx->psoc); 20942 hdd_populate_ce_dp_irq_affine_cfg(hdd_ctx, &cfg); 20943 20944 hif_init_ini_config(scn, &cfg); 20945 hif_set_enable_rpm(scn); 20946 20947 if (prevent_link_down) 20948 hif_vote_link_up(scn); 20949 } 20950 20951 /** 20952 * hdd_update_dp_config() - Propagate config parameters to Lithium 20953 * datapath 20954 * @hdd_ctx: HDD Context 20955 * 20956 * Return: 0 for success/errno for failure 20957 */ 20958 static int hdd_update_dp_config(struct hdd_context *hdd_ctx) 20959 { 20960 struct wlan_dp_user_config dp_cfg; 20961 QDF_STATUS status; 20962 20963 dp_cfg.ipa_enable = ucfg_ipa_is_enabled(); 20964 dp_cfg.arp_connectivity_map = CONNECTIVITY_CHECK_SET_ARP; 20965 20966 status = ucfg_dp_update_config(hdd_ctx->psoc, &dp_cfg); 20967 if (status != QDF_STATUS_SUCCESS) { 20968 hdd_err("failed DP PSOC configuration update"); 20969 return -EINVAL; 20970 } 20971 20972 return 0; 20973 } 20974 20975 /** 20976 * hdd_update_config() - Initialize driver per module ini parameters 20977 * @hdd_ctx: HDD Context 20978 * 20979 * API is used to initialize all driver per module configuration parameters 20980 * Return: 0 for success, errno for failure 20981 */ 20982 int hdd_update_config(struct hdd_context *hdd_ctx) 20983 { 20984 int ret; 20985 20986 if (ucfg_pmo_is_ns_offloaded(hdd_ctx->psoc)) 20987 hdd_ctx->ns_offload_enable = true; 20988 20989 hdd_update_ol_config(hdd_ctx); 20990 hdd_update_hif_config(hdd_ctx); 20991 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) 20992 ret = hdd_update_cds_config_ftm(hdd_ctx); 20993 else 20994 ret = hdd_update_cds_config(hdd_ctx); 20995 ret = hdd_update_user_config(hdd_ctx); 20996 20997 hdd_update_regdb_offload_config(hdd_ctx); 20998 20999 return ret; 21000 } 21001 21002 /** 21003 * hdd_update_pmo_config - API to update pmo configuration parameters 21004 * @hdd_ctx: HDD context 21005 * 21006 * Return: void 21007 */ 21008 static int hdd_update_pmo_config(struct hdd_context *hdd_ctx) 21009 { 21010 struct pmo_psoc_cfg psoc_cfg = {0}; 21011 QDF_STATUS status; 21012 enum pmo_wow_enable_type wow_enable; 21013 21014 ucfg_pmo_get_psoc_config(hdd_ctx->psoc, &psoc_cfg); 21015 21016 /* 21017 * Value of hdd_ctx->wowEnable can be, 21018 * 0 - Disable both magic pattern match and pattern byte match. 21019 * 1 - Enable magic pattern match on all interfaces. 21020 * 2 - Enable pattern byte match on all interfaces. 21021 * 3 - Enable both magic pattern and pattern byte match on 21022 * all interfaces. 21023 */ 21024 wow_enable = ucfg_pmo_get_wow_enable(hdd_ctx->psoc); 21025 psoc_cfg.magic_ptrn_enable = (wow_enable & 0x01) ? true : false; 21026 psoc_cfg.ptrn_match_enable_all_vdev = 21027 (wow_enable & 0x02) ? true : false; 21028 psoc_cfg.ap_arpns_support = hdd_ctx->ap_arpns_support; 21029 psoc_cfg.d0_wow_supported = wma_d0_wow_is_supported(); 21030 ucfg_mlme_get_sap_max_modulated_dtim(hdd_ctx->psoc, 21031 &psoc_cfg.sta_max_li_mod_dtim); 21032 21033 hdd_lpass_populate_pmo_config(&psoc_cfg, hdd_ctx); 21034 21035 status = ucfg_pmo_update_psoc_config(hdd_ctx->psoc, &psoc_cfg); 21036 if (QDF_IS_STATUS_ERROR(status)) 21037 hdd_err("failed pmo psoc configuration; status:%d", status); 21038 21039 return qdf_status_to_os_return(status); 21040 } 21041 21042 void hdd_update_ie_allowlist_attr(struct probe_req_allowlist_attr *ie_allowlist, 21043 struct hdd_context *hdd_ctx) 21044 { 21045 struct wlan_fwol_ie_allowlist allowlist = {0}; 21046 struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc; 21047 QDF_STATUS status; 21048 bool is_ie_allowlist_enable = false; 21049 uint8_t i = 0; 21050 21051 status = ucfg_fwol_get_ie_allowlist(psoc, &is_ie_allowlist_enable); 21052 if (QDF_IS_STATUS_ERROR(status)) { 21053 hdd_err("Unable to get IE allowlist param"); 21054 return; 21055 } 21056 21057 ie_allowlist->allow_list = is_ie_allowlist_enable; 21058 if (!ie_allowlist->allow_list) 21059 return; 21060 21061 status = ucfg_fwol_get_all_allowlist_params(psoc, &allowlist); 21062 if (QDF_IS_STATUS_ERROR(status)) { 21063 hdd_err("Unable to get all allowlist params"); 21064 return; 21065 } 21066 21067 ie_allowlist->ie_bitmap[0] = allowlist.ie_bitmap_0; 21068 ie_allowlist->ie_bitmap[1] = allowlist.ie_bitmap_1; 21069 ie_allowlist->ie_bitmap[2] = allowlist.ie_bitmap_2; 21070 ie_allowlist->ie_bitmap[3] = allowlist.ie_bitmap_3; 21071 ie_allowlist->ie_bitmap[4] = allowlist.ie_bitmap_4; 21072 ie_allowlist->ie_bitmap[5] = allowlist.ie_bitmap_5; 21073 ie_allowlist->ie_bitmap[6] = allowlist.ie_bitmap_6; 21074 ie_allowlist->ie_bitmap[7] = allowlist.ie_bitmap_7; 21075 21076 ie_allowlist->num_vendor_oui = allowlist.no_of_probe_req_ouis; 21077 for (i = 0; i < ie_allowlist->num_vendor_oui; i++) 21078 ie_allowlist->voui[i] = allowlist.probe_req_voui[i]; 21079 } 21080 21081 QDF_STATUS hdd_update_score_config(struct hdd_context *hdd_ctx) 21082 { 21083 struct hdd_config *cfg = hdd_ctx->config; 21084 eCsrPhyMode phy_mode = hdd_cfg_xlate_to_csr_phy_mode(cfg->dot11Mode); 21085 21086 sme_update_score_config(hdd_ctx->mac_handle, phy_mode, 21087 hdd_ctx->num_rf_chains); 21088 21089 return QDF_STATUS_SUCCESS; 21090 } 21091 21092 /** 21093 * hdd_update_dfs_config() - API to update dfs configuration parameters. 21094 * @hdd_ctx: HDD context 21095 * 21096 * Return: 0 if success else err 21097 */ 21098 static int hdd_update_dfs_config(struct hdd_context *hdd_ctx) 21099 { 21100 struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc; 21101 struct dfs_user_config dfs_cfg = {0}; 21102 QDF_STATUS status; 21103 21104 ucfg_mlme_get_dfs_filter_offload(hdd_ctx->psoc, 21105 &dfs_cfg.dfs_is_phyerr_filter_offload); 21106 status = ucfg_dfs_update_config(psoc, &dfs_cfg); 21107 if (QDF_IS_STATUS_ERROR(status)) { 21108 hdd_err("failed dfs psoc configuration"); 21109 return -EINVAL; 21110 } 21111 21112 return 0; 21113 } 21114 21115 /** 21116 * hdd_update_scan_config - API to update scan configuration parameters 21117 * @hdd_ctx: HDD context 21118 * 21119 * Return: 0 if success else err 21120 */ 21121 int hdd_update_scan_config(struct hdd_context *hdd_ctx) 21122 { 21123 struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc; 21124 struct scan_user_cfg scan_cfg; 21125 QDF_STATUS status; 21126 uint32_t mcast_mcc_rest_time = 0; 21127 21128 qdf_mem_zero(&scan_cfg, sizeof(scan_cfg)); 21129 status = ucfg_mlme_get_sta_miracast_mcc_rest_time(hdd_ctx->psoc, 21130 &mcast_mcc_rest_time); 21131 if (!QDF_IS_STATUS_SUCCESS(status)) { 21132 hdd_err("ucfg_mlme_get_sta_miracast_mcc_rest_time, use def"); 21133 return -EIO; 21134 } 21135 scan_cfg.sta_miracast_mcc_rest_time = mcast_mcc_rest_time; 21136 hdd_update_ie_allowlist_attr(&scan_cfg.ie_allowlist, hdd_ctx); 21137 21138 status = ucfg_scan_update_user_config(psoc, &scan_cfg); 21139 if (status != QDF_STATUS_SUCCESS) { 21140 hdd_err("failed pmo psoc configuration"); 21141 return -EINVAL; 21142 } 21143 21144 return 0; 21145 } 21146 21147 int hdd_update_components_config(struct hdd_context *hdd_ctx) 21148 { 21149 int ret; 21150 21151 ret = hdd_update_pmo_config(hdd_ctx); 21152 if (ret) 21153 return ret; 21154 21155 ret = hdd_update_scan_config(hdd_ctx); 21156 if (ret) 21157 return ret; 21158 21159 ret = hdd_update_tdls_config(hdd_ctx); 21160 if (ret) 21161 return ret; 21162 21163 ret = hdd_update_dp_config(hdd_ctx); 21164 if (ret) 21165 return ret; 21166 21167 ret = hdd_update_dfs_config(hdd_ctx); 21168 if (ret) 21169 return ret; 21170 21171 ret = hdd_update_regulatory_config(hdd_ctx); 21172 if (ret) 21173 return ret; 21174 21175 return ret; 21176 } 21177 21178 /** 21179 * wlan_hdd_get_dfs_mode() - get ACS DFS mode 21180 * @mode : cfg80211 DFS mode 21181 * 21182 * Return: return SAP ACS DFS mode else return ACS_DFS_MODE_NONE 21183 */ 21184 enum sap_acs_dfs_mode wlan_hdd_get_dfs_mode(enum dfs_mode mode) 21185 { 21186 switch (mode) { 21187 case DFS_MODE_ENABLE: 21188 return ACS_DFS_MODE_ENABLE; 21189 case DFS_MODE_DISABLE: 21190 return ACS_DFS_MODE_DISABLE; 21191 case DFS_MODE_DEPRIORITIZE: 21192 return ACS_DFS_MODE_DEPRIORITIZE; 21193 default: 21194 hdd_debug("ACS dfs mode is NONE"); 21195 return ACS_DFS_MODE_NONE; 21196 } 21197 } 21198 21199 /** 21200 * hdd_enable_disable_ca_event() - enable/disable channel avoidance event 21201 * @hdd_ctx: pointer to hdd context 21202 * @set_value: enable/disable 21203 * 21204 * When Host sends vendor command enable, FW will send *ONE* CA ind to 21205 * Host(even though it is duplicate). When Host send vendor command 21206 * disable,FW doesn't perform any action. Whenever any change in 21207 * CA *and* WLAN is in SAP/P2P-GO mode, FW sends CA ind to host. 21208 * 21209 * return - 0 on success, appropriate error values on failure. 21210 */ 21211 int hdd_enable_disable_ca_event(struct hdd_context *hdd_ctx, uint8_t set_value) 21212 { 21213 QDF_STATUS status; 21214 21215 if (0 != wlan_hdd_validate_context(hdd_ctx)) 21216 return -EAGAIN; 21217 21218 status = sme_enable_disable_chanavoidind_event(hdd_ctx->mac_handle, 21219 set_value); 21220 if (!QDF_IS_STATUS_SUCCESS(status)) { 21221 hdd_err("Failed to send chan avoid command to SME"); 21222 return -EINVAL; 21223 } 21224 return 0; 21225 } 21226 21227 bool hdd_is_roaming_in_progress(struct hdd_context *hdd_ctx) 21228 { 21229 struct hdd_adapter *adapter = NULL, *next_adapter = NULL; 21230 uint8_t vdev_id; 21231 wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_IS_ROAMING_IN_PROGRESS; 21232 struct wlan_hdd_link_info *link_info; 21233 21234 if (!hdd_ctx) { 21235 hdd_err("HDD context is NULL"); 21236 return false; 21237 } 21238 21239 if (!policy_mgr_is_sta_active_connection_exists(hdd_ctx->psoc)) 21240 return false; 21241 21242 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 21243 dbgid) { 21244 if (adapter->device_mode != QDF_STA_MODE) 21245 goto adapter_put; 21246 21247 hdd_adapter_for_each_active_link_info(adapter, link_info) { 21248 vdev_id = link_info->vdev_id; 21249 if (test_bit(SME_SESSION_OPENED, 21250 &link_info->link_flags) && 21251 sme_roaming_in_progress(hdd_ctx->mac_handle, 21252 vdev_id)) { 21253 hdd_debug("Roaming is in progress on:vdev_id:%d", 21254 link_info->vdev_id); 21255 hdd_adapter_dev_put_debug(adapter, dbgid); 21256 if (next_adapter) 21257 hdd_adapter_dev_put_debug(next_adapter, 21258 dbgid); 21259 return true; 21260 } 21261 } 21262 adapter_put: 21263 hdd_adapter_dev_put_debug(adapter, dbgid); 21264 } 21265 21266 return false; 21267 } 21268 21269 /** 21270 * struct hdd_is_connection_in_progress_priv - adapter connection info 21271 * @out_vdev_id: id of vdev where connection is occurring 21272 * @out_reason: scan reject reason 21273 * @connection_in_progress: true if connection is in progress 21274 */ 21275 struct hdd_is_connection_in_progress_priv { 21276 uint8_t out_vdev_id; 21277 enum scan_reject_states out_reason; 21278 bool connection_in_progress; 21279 }; 21280 21281 /** 21282 * hdd_is_connection_in_progress_iterator() - Check adapter connection based 21283 * on device mode 21284 * @link_info: Link info pointer in HDD adapter 21285 * @ctx: user context supplied 21286 * 21287 * Check if connection is in progress for the current adapter according to the 21288 * device mode 21289 * 21290 * Return: 21291 * * QDF_STATUS_SUCCESS if iteration should continue 21292 * * QDF_STATUS_E_ABORTED if iteration should be aborted 21293 */ 21294 static QDF_STATUS 21295 hdd_is_connection_in_progress_iterator(struct wlan_hdd_link_info *link_info, 21296 void *ctx) 21297 { 21298 struct hdd_station_ctx *hdd_sta_ctx; 21299 uint8_t *sta_mac; 21300 struct hdd_context *hdd_ctx; 21301 mac_handle_t mac_handle; 21302 struct hdd_station_info *sta_info, *tmp = NULL; 21303 struct hdd_is_connection_in_progress_priv *context = ctx; 21304 struct hdd_adapter *adapter = link_info->adapter; 21305 21306 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 21307 if (!hdd_ctx) 21308 return QDF_STATUS_E_ABORTED; 21309 21310 mac_handle = hdd_ctx->mac_handle; 21311 21312 if (!test_bit(SME_SESSION_OPENED, &link_info->link_flags) && 21313 (adapter->device_mode == QDF_STA_MODE || 21314 adapter->device_mode == QDF_P2P_CLIENT_MODE || 21315 adapter->device_mode == QDF_P2P_DEVICE_MODE || 21316 adapter->device_mode == QDF_P2P_GO_MODE || 21317 adapter->device_mode == QDF_SAP_MODE)) 21318 return QDF_STATUS_SUCCESS; 21319 21320 if ((QDF_STA_MODE == adapter->device_mode || 21321 QDF_P2P_CLIENT_MODE == adapter->device_mode || 21322 QDF_P2P_DEVICE_MODE == adapter->device_mode) && 21323 hdd_cm_is_connecting(link_info)) { 21324 hdd_debug("%pK(%d) mode %d Connection is in progress", 21325 WLAN_HDD_GET_STATION_CTX_PTR(link_info), 21326 link_info->vdev_id, adapter->device_mode); 21327 21328 context->out_vdev_id = link_info->vdev_id; 21329 context->out_reason = CONNECTION_IN_PROGRESS; 21330 context->connection_in_progress = true; 21331 21332 return QDF_STATUS_E_ABORTED; 21333 } 21334 21335 if ((QDF_STA_MODE == adapter->device_mode) && 21336 sme_roaming_in_progress(mac_handle, link_info->vdev_id)) { 21337 hdd_debug("%pK(%d) mode %d Reassociation in progress", 21338 WLAN_HDD_GET_STATION_CTX_PTR(link_info), 21339 link_info->vdev_id, adapter->device_mode); 21340 21341 context->out_vdev_id = link_info->vdev_id; 21342 context->out_reason = REASSOC_IN_PROGRESS; 21343 context->connection_in_progress = true; 21344 return QDF_STATUS_E_ABORTED; 21345 } 21346 21347 if ((QDF_STA_MODE == adapter->device_mode) || 21348 (QDF_P2P_CLIENT_MODE == adapter->device_mode) || 21349 (QDF_P2P_DEVICE_MODE == adapter->device_mode)) { 21350 hdd_sta_ctx = 21351 WLAN_HDD_GET_STATION_CTX_PTR(link_info); 21352 if (hdd_cm_is_vdev_associated(link_info) 21353 && sme_is_sta_key_exchange_in_progress( 21354 mac_handle, link_info->vdev_id)) { 21355 sta_mac = (uint8_t *)&(adapter->mac_addr.bytes[0]); 21356 hdd_debug("client " QDF_MAC_ADDR_FMT 21357 " is in middle of WPS/EAPOL exchange.", 21358 QDF_MAC_ADDR_REF(sta_mac)); 21359 21360 context->out_vdev_id = link_info->vdev_id; 21361 context->out_reason = EAPOL_IN_PROGRESS; 21362 context->connection_in_progress = true; 21363 21364 return QDF_STATUS_E_ABORTED; 21365 } 21366 } else if ((QDF_SAP_MODE == adapter->device_mode) || 21367 (QDF_P2P_GO_MODE == adapter->device_mode)) { 21368 hdd_for_each_sta_ref_safe(adapter->sta_info_list, sta_info, tmp, 21369 STA_INFO_CONNECTION_IN_PROGRESS_ITERATOR) { 21370 if (sta_info->peer_state != 21371 OL_TXRX_PEER_STATE_CONN) { 21372 hdd_put_sta_info_ref( 21373 &adapter->sta_info_list, &sta_info, true, 21374 STA_INFO_CONNECTION_IN_PROGRESS_ITERATOR); 21375 continue; 21376 } 21377 21378 sta_mac = sta_info->sta_mac.bytes; 21379 hdd_debug("client " QDF_MAC_ADDR_FMT 21380 " of SAP/GO is in middle of WPS/EAPOL exchange", 21381 QDF_MAC_ADDR_REF(sta_mac)); 21382 21383 context->out_vdev_id = link_info->vdev_id; 21384 context->out_reason = SAP_EAPOL_IN_PROGRESS; 21385 context->connection_in_progress = true; 21386 21387 hdd_put_sta_info_ref( 21388 &adapter->sta_info_list, &sta_info, true, 21389 STA_INFO_CONNECTION_IN_PROGRESS_ITERATOR); 21390 if (tmp) 21391 hdd_put_sta_info_ref( 21392 &adapter->sta_info_list, &tmp, true, 21393 STA_INFO_CONNECTION_IN_PROGRESS_ITERATOR); 21394 21395 return QDF_STATUS_E_ABORTED; 21396 } 21397 if (hdd_ctx->connection_in_progress) { 21398 hdd_debug("AP/GO: vdev %d connection is in progress", 21399 link_info->vdev_id); 21400 context->out_reason = SAP_CONNECTION_IN_PROGRESS; 21401 context->out_vdev_id = link_info->vdev_id; 21402 context->connection_in_progress = true; 21403 21404 return QDF_STATUS_E_ABORTED; 21405 } 21406 } 21407 21408 if (ucfg_nan_is_enable_disable_in_progress(hdd_ctx->psoc)) { 21409 context->out_reason = NAN_ENABLE_DISABLE_IN_PROGRESS; 21410 context->out_vdev_id = NAN_PSEUDO_VDEV_ID; 21411 context->connection_in_progress = true; 21412 21413 return QDF_STATUS_E_ABORTED; 21414 } 21415 21416 return QDF_STATUS_SUCCESS; 21417 } 21418 21419 bool hdd_is_connection_in_progress(uint8_t *out_vdev_id, 21420 enum scan_reject_states *out_reason) 21421 { 21422 struct hdd_is_connection_in_progress_priv hdd_conn; 21423 hdd_adapter_iterate_cb cb; 21424 21425 hdd_conn.out_vdev_id = 0; 21426 hdd_conn.out_reason = SCAN_REJECT_DEFAULT; 21427 hdd_conn.connection_in_progress = false; 21428 21429 cb = hdd_is_connection_in_progress_iterator; 21430 21431 hdd_adapter_iterate(cb, &hdd_conn); 21432 21433 if (hdd_conn.connection_in_progress && out_vdev_id && out_reason) { 21434 *out_vdev_id = hdd_conn.out_vdev_id; 21435 *out_reason = hdd_conn.out_reason; 21436 } 21437 21438 return hdd_conn.connection_in_progress; 21439 } 21440 21441 void hdd_restart_sap(struct wlan_hdd_link_info *link_info) 21442 { 21443 struct hdd_hostapd_state *hapd_state; 21444 QDF_STATUS status; 21445 struct hdd_adapter *ap_adapter = link_info->adapter; 21446 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(ap_adapter); 21447 struct sap_config *sap_config; 21448 void *sap_ctx; 21449 21450 sap_config = 21451 &(WLAN_HDD_GET_AP_CTX_PTR(link_info)->sap_config); 21452 sap_ctx = WLAN_HDD_GET_SAP_CTX_PTR(link_info); 21453 21454 mutex_lock(&hdd_ctx->sap_lock); 21455 if (test_bit(SOFTAP_BSS_STARTED, &link_info->link_flags)) { 21456 wlan_hdd_del_station(ap_adapter, NULL); 21457 hapd_state = WLAN_HDD_GET_HOSTAP_STATE_PTR(link_info); 21458 qdf_event_reset(&hapd_state->qdf_stop_bss_event); 21459 if (QDF_STATUS_SUCCESS == wlansap_stop_bss(sap_ctx)) { 21460 status = qdf_wait_single_event(&hapd_state->qdf_stop_bss_event, 21461 SME_CMD_STOP_BSS_TIMEOUT); 21462 21463 if (!QDF_IS_STATUS_SUCCESS(status)) { 21464 hdd_err("SAP Stop Failed"); 21465 goto end; 21466 } 21467 } 21468 clear_bit(SOFTAP_BSS_STARTED, &link_info->link_flags); 21469 policy_mgr_decr_session_set_pcl(hdd_ctx->psoc, 21470 ap_adapter->device_mode, link_info->vdev_id); 21471 hdd_green_ap_start_state_mc(hdd_ctx, ap_adapter->device_mode, 21472 false); 21473 hdd_err("SAP Stop Success"); 21474 21475 if (0 != wlan_hdd_cfg80211_update_apies(link_info)) { 21476 hdd_err("SAP Not able to set AP IEs"); 21477 goto end; 21478 } 21479 21480 status = wlan_hdd_mlo_sap_reinit(link_info); 21481 if (QDF_IS_STATUS_ERROR(status)) { 21482 hdd_err("SAP Not able to do mlo attach"); 21483 goto deinit_mlo; 21484 } 21485 21486 qdf_event_reset(&hapd_state->qdf_event); 21487 status = wlansap_start_bss(sap_ctx, hdd_hostapd_sap_event_cb, 21488 sap_config, ap_adapter->dev); 21489 if (QDF_IS_STATUS_ERROR(status)) { 21490 hdd_err("SAP Start Bss fail"); 21491 goto deinit_mlo; 21492 } 21493 21494 hdd_info("Waiting for SAP to start"); 21495 status = qdf_wait_single_event(&hapd_state->qdf_event, 21496 SME_CMD_START_BSS_TIMEOUT); 21497 if (!QDF_IS_STATUS_SUCCESS(status)) { 21498 hdd_err("SAP Start failed"); 21499 goto deinit_mlo; 21500 } 21501 wlansap_reset_sap_config_add_ie(sap_config, eUPDATE_IE_ALL); 21502 hdd_err("SAP Start Success"); 21503 set_bit(SOFTAP_BSS_STARTED, &link_info->link_flags); 21504 if (hapd_state->bss_state == BSS_START) { 21505 policy_mgr_incr_active_session(hdd_ctx->psoc, 21506 ap_adapter->device_mode, 21507 link_info->vdev_id); 21508 hdd_green_ap_start_state_mc(hdd_ctx, 21509 ap_adapter->device_mode, 21510 true); 21511 } 21512 } 21513 mutex_unlock(&hdd_ctx->sap_lock); 21514 return; 21515 21516 deinit_mlo: 21517 wlan_hdd_mlo_reset(link_info); 21518 end: 21519 wlansap_reset_sap_config_add_ie(sap_config, eUPDATE_IE_ALL); 21520 mutex_unlock(&hdd_ctx->sap_lock); 21521 } 21522 21523 /** 21524 * hdd_set_connection_in_progress() - to set the connection in 21525 * progress flag 21526 * @value: value to set 21527 * 21528 * This function will set the passed value to connection in progress flag. 21529 * If value is previously being set to true then no need to set it again. 21530 * 21531 * Return: true if value is being set correctly and false otherwise. 21532 */ 21533 bool hdd_set_connection_in_progress(bool value) 21534 { 21535 bool status = true; 21536 struct hdd_context *hdd_ctx; 21537 21538 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 21539 if (!hdd_ctx) 21540 return false; 21541 21542 qdf_spin_lock(&hdd_ctx->connection_status_lock); 21543 /* 21544 * if the value is set to true previously and if someone is 21545 * trying to make it true again then it could be some race 21546 * condition being triggered. Avoid this situation by returning 21547 * false 21548 */ 21549 if (hdd_ctx->connection_in_progress && value) 21550 status = false; 21551 else 21552 hdd_ctx->connection_in_progress = value; 21553 qdf_spin_unlock(&hdd_ctx->connection_status_lock); 21554 return status; 21555 } 21556 21557 int wlan_hdd_send_mcc_vdev_quota(struct hdd_adapter *adapter, int set_value) 21558 { 21559 if (!adapter) { 21560 hdd_err("Invalid adapter"); 21561 return -EINVAL; 21562 } 21563 hdd_info("send mcc vdev quota to fw: %d", set_value); 21564 sme_cli_set_command(adapter->deflink->vdev_id, 21565 WMA_VDEV_MCC_SET_TIME_QUOTA, 21566 set_value, VDEV_CMD); 21567 return 0; 21568 21569 } 21570 21571 int wlan_hdd_send_mcc_latency(struct hdd_adapter *adapter, int set_value) 21572 { 21573 if (!adapter) { 21574 hdd_err("Invalid adapter"); 21575 return -EINVAL; 21576 } 21577 21578 hdd_info("Send MCC latency WMA: %d", set_value); 21579 sme_cli_set_command(adapter->deflink->vdev_id, 21580 WMA_VDEV_MCC_SET_TIME_LATENCY, 21581 set_value, VDEV_CMD); 21582 return 0; 21583 } 21584 21585 struct wlan_hdd_link_info * 21586 wlan_hdd_get_link_info_from_vdev(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id) 21587 { 21588 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 21589 struct wlan_hdd_link_info *link_info; 21590 21591 /* 21592 * Currently PSOC is not being used. But this logic will 21593 * change once we have the converged implementation of 21594 * HDD context per PSOC in place. This would break if 21595 * multiple vdev objects reuse the vdev id. 21596 */ 21597 link_info = hdd_get_link_info_by_vdev(hdd_ctx, vdev_id); 21598 if (!link_info) { 21599 hdd_err("Get adapter by vdev id failed"); 21600 return NULL; 21601 } 21602 21603 return link_info; 21604 } 21605 21606 int hdd_get_rssi_snr_by_bssid(mac_handle_t mac_handle, const uint8_t *bssid, 21607 int8_t *rssi, int8_t *snr) 21608 { 21609 QDF_STATUS status; 21610 21611 status = sme_get_rssi_snr_by_bssid(mac_handle, bssid, rssi, snr); 21612 if (QDF_IS_STATUS_ERROR(status)) { 21613 hdd_debug("sme_get_rssi_snr_by_bssid failed"); 21614 return -EINVAL; 21615 } 21616 21617 return 0; 21618 } 21619 21620 /** 21621 * hdd_reset_limit_off_chan() - reset limit off-channel command parameters 21622 * @adapter: HDD adapter 21623 * 21624 * Return: 0 on success and non zero value on failure 21625 */ 21626 int hdd_reset_limit_off_chan(struct hdd_adapter *adapter) 21627 { 21628 struct hdd_context *hdd_ctx; 21629 int ret; 21630 QDF_STATUS status; 21631 uint8_t sys_pref = 0; 21632 21633 hdd_ctx = WLAN_HDD_GET_CTX(adapter); 21634 ret = wlan_hdd_validate_context(hdd_ctx); 21635 if (ret < 0) 21636 return ret; 21637 21638 ucfg_policy_mgr_get_sys_pref(hdd_ctx->psoc, 21639 &sys_pref); 21640 /* set the system preferece to default */ 21641 policy_mgr_set_cur_conc_system_pref(hdd_ctx->psoc, sys_pref); 21642 21643 /* clear the bitmap */ 21644 adapter->active_ac = 0; 21645 21646 hdd_debug("reset ac_bitmap for session %hu active_ac %0x", 21647 adapter->deflink->vdev_id, adapter->active_ac); 21648 21649 status = sme_send_limit_off_channel_params(hdd_ctx->mac_handle, 21650 adapter->deflink->vdev_id, 21651 false, 0, 0, false); 21652 if (!QDF_IS_STATUS_SUCCESS(status)) { 21653 hdd_err("failed to reset limit off chan params"); 21654 ret = -EINVAL; 21655 } 21656 21657 return ret; 21658 } 21659 21660 void hdd_hidden_ssid_enable_roaming(hdd_handle_t hdd_handle, uint8_t vdev_id) 21661 { 21662 struct hdd_context *hdd_ctx = hdd_handle_to_context(hdd_handle); 21663 struct wlan_hdd_link_info *link_info; 21664 21665 link_info = hdd_get_link_info_by_vdev(hdd_ctx, vdev_id); 21666 if (!link_info) { 21667 hdd_err("Invalid vdev"); 21668 return; 21669 } 21670 /* enable roaming on all adapters once hdd get hidden ssid rsp */ 21671 wlan_hdd_set_roaming_state(link_info, RSO_START_BSS, true); 21672 } 21673 21674 #ifdef WLAN_FEATURE_PKT_CAPTURE 21675 bool wlan_hdd_is_mon_concurrency(void) 21676 { 21677 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 21678 21679 if (!hdd_ctx) 21680 return -EINVAL; 21681 21682 if (ucfg_pkt_capture_get_mode(hdd_ctx->psoc) != 21683 PACKET_CAPTURE_MODE_DISABLE) { 21684 if (policy_mgr_get_concurrency_mode(hdd_ctx->psoc) == 21685 (QDF_STA_MASK | QDF_MONITOR_MASK)) { 21686 hdd_err("STA + MON mode is UP"); 21687 return true; 21688 } 21689 } 21690 return false; 21691 } 21692 21693 void wlan_hdd_del_monitor(struct hdd_context *hdd_ctx, 21694 struct hdd_adapter *adapter, bool rtnl_held) 21695 { 21696 wlan_hdd_release_intf_addr(hdd_ctx, adapter->mac_addr.bytes); 21697 hdd_stop_adapter(hdd_ctx, adapter); 21698 hdd_close_adapter(hdd_ctx, adapter, true); 21699 21700 hdd_open_p2p_interface(hdd_ctx); 21701 } 21702 21703 void 21704 wlan_hdd_del_p2p_interface(struct hdd_context *hdd_ctx) 21705 { 21706 struct hdd_adapter *adapter = NULL, *next_adapter = NULL; 21707 struct osif_vdev_sync *vdev_sync; 21708 21709 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 21710 NET_DEV_HOLD_DEL_P2P_INTERFACE) { 21711 if (adapter->device_mode == QDF_P2P_CLIENT_MODE || 21712 adapter->device_mode == QDF_P2P_DEVICE_MODE || 21713 adapter->device_mode == QDF_P2P_GO_MODE) { 21714 vdev_sync = osif_vdev_sync_unregister(adapter->dev); 21715 if (vdev_sync) 21716 osif_vdev_sync_wait_for_ops(vdev_sync); 21717 21718 hdd_adapter_dev_put_debug( 21719 adapter, NET_DEV_HOLD_DEL_P2P_INTERFACE); 21720 21721 hdd_clean_up_interface(hdd_ctx, adapter); 21722 21723 if (vdev_sync) 21724 osif_vdev_sync_destroy(vdev_sync); 21725 } else 21726 hdd_adapter_dev_put_debug( 21727 adapter, NET_DEV_HOLD_DEL_P2P_INTERFACE); 21728 } 21729 } 21730 21731 #endif /* WLAN_FEATURE_PKT_CAPTURE */ 21732 21733 bool wlan_hdd_is_session_type_monitor(uint8_t session_type) 21734 { 21735 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 21736 21737 if (!hdd_ctx) { 21738 cds_err("HDD context is NULL"); 21739 return false; 21740 } 21741 21742 if (cds_get_conparam() != QDF_GLOBAL_MONITOR_MODE && 21743 session_type == QDF_MONITOR_MODE) 21744 return true; 21745 else 21746 return false; 21747 } 21748 21749 int 21750 wlan_hdd_add_monitor_check(struct hdd_context *hdd_ctx, 21751 struct hdd_adapter **adapter, 21752 const char *name, bool rtnl_held, 21753 unsigned char name_assign_type) 21754 { 21755 struct hdd_adapter *sta_adapter; 21756 struct hdd_adapter *mon_adapter; 21757 uint8_t num_open_session = 0; 21758 QDF_STATUS status; 21759 struct hdd_adapter_create_param params = {0}; 21760 21761 sta_adapter = hdd_get_adapter(hdd_ctx, QDF_STA_MODE); 21762 if (!sta_adapter) { 21763 hdd_err("No station adapter"); 21764 return -EINVAL; 21765 } 21766 21767 status = policy_mgr_check_mon_concurrency(hdd_ctx->psoc); 21768 21769 if (QDF_IS_STATUS_ERROR(status)) 21770 return -EINVAL; 21771 21772 if (hdd_is_connection_in_progress(NULL, NULL)) { 21773 hdd_err("cannot add monitor mode, Connection in progress"); 21774 return -EINVAL; 21775 } 21776 21777 if (!ucfg_dp_is_local_pkt_capture_enabled(hdd_ctx->psoc) && 21778 ucfg_mlme_is_sta_mon_conc_supported(hdd_ctx->psoc)) { 21779 num_open_session = policy_mgr_mode_specific_connection_count( 21780 hdd_ctx->psoc, 21781 PM_STA_MODE, 21782 NULL); 21783 21784 if (num_open_session) { 21785 /* Try disconnecting if already in connected state */ 21786 wlan_hdd_cm_issue_disconnect(sta_adapter->deflink, 21787 REASON_UNSPEC_FAILURE, 21788 true); 21789 } 21790 } 21791 21792 if (ucfg_pkt_capture_get_mode(hdd_ctx->psoc) != 21793 PACKET_CAPTURE_MODE_DISABLE) 21794 wlan_hdd_del_p2p_interface(hdd_ctx); 21795 21796 params.is_add_virtual_iface = 1; 21797 21798 mon_adapter = hdd_open_adapter(hdd_ctx, QDF_MONITOR_MODE, name, 21799 wlan_hdd_get_intf_addr( 21800 hdd_ctx, 21801 QDF_MONITOR_MODE), 21802 name_assign_type, rtnl_held, ¶ms); 21803 if (!mon_adapter) { 21804 hdd_err("hdd_open_adapter failed"); 21805 if (ucfg_pkt_capture_get_mode(hdd_ctx->psoc) != 21806 PACKET_CAPTURE_MODE_DISABLE) 21807 hdd_open_p2p_interface(hdd_ctx); 21808 return -EINVAL; 21809 } 21810 21811 if (mon_adapter) 21812 hdd_set_idle_ps_config(hdd_ctx, false); 21813 21814 *adapter = mon_adapter; 21815 return 0; 21816 } 21817 21818 #ifdef FEATURE_MONITOR_MODE_SUPPORT 21819 21820 void hdd_sme_monitor_mode_callback(uint8_t vdev_id) 21821 { 21822 struct hdd_context *hdd_ctx; 21823 struct hdd_adapter *adapter; 21824 struct wlan_hdd_link_info *link_info; 21825 21826 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 21827 if (!hdd_ctx) 21828 return; 21829 21830 link_info = hdd_get_link_info_by_vdev(hdd_ctx, vdev_id); 21831 if (!link_info) { 21832 hdd_err_rl("NULL adapter"); 21833 return; 21834 } 21835 21836 adapter = link_info->adapter; 21837 if (adapter->magic != WLAN_HDD_ADAPTER_MAGIC) { 21838 hdd_err_rl("Invalid magic"); 21839 return; 21840 } 21841 21842 qdf_event_set(&adapter->qdf_monitor_mode_vdev_up_event); 21843 21844 hdd_debug("monitor mode vdev up completed"); 21845 adapter->monitor_mode_vdev_up_in_progress = false; 21846 } 21847 21848 QDF_STATUS hdd_monitor_mode_qdf_create_event(struct hdd_adapter *adapter, 21849 uint8_t session_type) 21850 { 21851 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; 21852 21853 if (session_type == QDF_MONITOR_MODE) { 21854 qdf_status = qdf_event_create( 21855 &adapter->qdf_monitor_mode_vdev_up_event); 21856 } 21857 return qdf_status; 21858 } 21859 21860 QDF_STATUS hdd_monitor_mode_vdev_status(struct hdd_adapter *adapter) 21861 { 21862 QDF_STATUS status = QDF_STATUS_SUCCESS; 21863 21864 if (!adapter->monitor_mode_vdev_up_in_progress) 21865 return status; 21866 21867 /* block on a completion variable until vdev up success*/ 21868 status = qdf_wait_for_event_completion( 21869 &adapter->qdf_monitor_mode_vdev_up_event, 21870 WLAN_MONITOR_MODE_VDEV_UP_EVT); 21871 if (QDF_IS_STATUS_ERROR(status)) { 21872 hdd_err_rl("monitor mode vdev up event time out vdev id: %d", 21873 adapter->deflink->vdev_id); 21874 if (adapter->qdf_monitor_mode_vdev_up_event.force_set) 21875 /* 21876 * SSR/PDR has caused shutdown, which has 21877 * forcefully set the event. 21878 */ 21879 hdd_err_rl("monitor mode vdev up event forcefully set"); 21880 else if (status == QDF_STATUS_E_TIMEOUT) 21881 hdd_err_rl("mode vdev up event timed out"); 21882 else 21883 hdd_err_rl("Failed to wait for monitor vdev up(status-%d)", 21884 status); 21885 21886 adapter->monitor_mode_vdev_up_in_progress = false; 21887 return status; 21888 } 21889 21890 return QDF_STATUS_SUCCESS; 21891 } 21892 #endif 21893 21894 #if defined(CLD_PM_QOS) && defined(WLAN_FEATURE_LL_MODE) 21895 void hdd_beacon_latency_event_cb(uint32_t latency_level) 21896 { 21897 struct hdd_context *hdd_ctx; 21898 21899 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 21900 if (!hdd_ctx) 21901 return; 21902 21903 if (latency_level == 21904 QCA_WLAN_VENDOR_ATTR_CONFIG_LATENCY_LEVEL_ULTRALOW) 21905 wlan_hdd_set_pm_qos_request(hdd_ctx, true); 21906 else 21907 wlan_hdd_set_pm_qos_request(hdd_ctx, false); 21908 } 21909 #endif 21910 21911 #ifdef CONFIG_WLAN_DEBUG_CRASH_INJECT 21912 int hdd_crash_inject(struct hdd_adapter *adapter, uint32_t v1, uint32_t v2) 21913 { 21914 struct hdd_context *hdd_ctx; 21915 int ret; 21916 bool crash_inject; 21917 QDF_STATUS status; 21918 21919 hdd_debug("v1: %d v2: %d", v1, v2); 21920 pr_err("SSR is triggered by CRASH_INJECT: %d %d\n", 21921 v1, v2); 21922 hdd_ctx = WLAN_HDD_GET_CTX(adapter); 21923 21924 status = ucfg_mlme_get_crash_inject(hdd_ctx->psoc, &crash_inject); 21925 if (QDF_IS_STATUS_ERROR(status)) { 21926 hdd_err("Failed to get crash inject ini config"); 21927 return 0; 21928 } 21929 21930 if (!crash_inject) { 21931 hdd_err("Crash Inject ini disabled, Ignore Crash Inject"); 21932 return 0; 21933 } 21934 21935 if (v1 == 3) { 21936 cds_trigger_recovery(QDF_REASON_UNSPECIFIED); 21937 return 0; 21938 } 21939 ret = wma_cli_set2_command(adapter->deflink->vdev_id, 21940 GEN_PARAM_CRASH_INJECT, 21941 v1, v2, GEN_CMD); 21942 return ret; 21943 } 21944 #endif 21945 21946 static const struct hdd_chwidth_info chwidth_info[] = { 21947 [NL80211_CHAN_WIDTH_20_NOHT] = { 21948 .ch_bw = HW_MODE_20_MHZ, 21949 .ch_bw_str = "20MHz", 21950 .phy_chwidth = CH_WIDTH_20MHZ, 21951 }, 21952 [NL80211_CHAN_WIDTH_20] = { 21953 .sir_chwidth_valid = true, 21954 .sir_chwidth = eHT_CHANNEL_WIDTH_20MHZ, 21955 .ch_bw = HW_MODE_20_MHZ, 21956 .ch_bw_str = "20MHz", 21957 .phy_chwidth = CH_WIDTH_20MHZ, 21958 .bonding_mode = WNI_CFG_CHANNEL_BONDING_MODE_DISABLE, 21959 }, 21960 [NL80211_CHAN_WIDTH_40] = { 21961 .sir_chwidth_valid = true, 21962 .sir_chwidth = eHT_CHANNEL_WIDTH_40MHZ, 21963 .ch_bw = HW_MODE_40_MHZ, 21964 .ch_bw_str = "40MHz", 21965 .phy_chwidth = CH_WIDTH_40MHZ, 21966 .bonding_mode = WNI_CFG_CHANNEL_BONDING_MODE_ENABLE, 21967 }, 21968 [NL80211_CHAN_WIDTH_80] = { 21969 .sir_chwidth_valid = true, 21970 .sir_chwidth = eHT_CHANNEL_WIDTH_80MHZ, 21971 .ch_bw = HW_MODE_80_MHZ, 21972 .ch_bw_str = "80MHz", 21973 .phy_chwidth = CH_WIDTH_80MHZ, 21974 .bonding_mode = WNI_CFG_CHANNEL_BONDING_MODE_ENABLE, 21975 }, 21976 [NL80211_CHAN_WIDTH_80P80] = { 21977 .sir_chwidth_valid = true, 21978 .sir_chwidth = eHT_CHANNEL_WIDTH_80P80MHZ, 21979 .ch_bw = HW_MODE_80_PLUS_80_MHZ, 21980 .ch_bw_str = "(80 + 80)MHz", 21981 .phy_chwidth = CH_WIDTH_80P80MHZ, 21982 .bonding_mode = WNI_CFG_CHANNEL_BONDING_MODE_ENABLE, 21983 }, 21984 [NL80211_CHAN_WIDTH_160] = { 21985 .sir_chwidth_valid = true, 21986 .sir_chwidth = eHT_CHANNEL_WIDTH_160MHZ, 21987 .ch_bw = HW_MODE_160_MHZ, 21988 .ch_bw_str = "160MHz", 21989 .phy_chwidth = CH_WIDTH_160MHZ, 21990 .bonding_mode = WNI_CFG_CHANNEL_BONDING_MODE_ENABLE, 21991 }, 21992 [NL80211_CHAN_WIDTH_5] = { 21993 .ch_bw = HW_MODE_5_MHZ, 21994 .ch_bw_str = "5MHz", 21995 .phy_chwidth = CH_WIDTH_5MHZ, 21996 }, 21997 [NL80211_CHAN_WIDTH_10] = { 21998 .ch_bw = HW_MODE_10_MHZ, 21999 .ch_bw_str = "10MHz", 22000 .phy_chwidth = CH_WIDTH_10MHZ, 22001 }, 22002 #if defined(WLAN_FEATURE_11BE) && defined(CFG80211_11BE_BASIC) 22003 [NL80211_CHAN_WIDTH_320] = { 22004 .sir_chwidth_valid = true, 22005 .sir_chwidth = eHT_CHANNEL_WIDTH_320MHZ, 22006 .ch_bw = HW_MODE_320_MHZ, 22007 .ch_bw_str = "320MHz", 22008 .phy_chwidth = CH_WIDTH_320MHZ, 22009 .bonding_mode = WNI_CFG_CHANNEL_BONDING_MODE_ENABLE, 22010 }, 22011 #endif 22012 }; 22013 22014 enum eSirMacHTChannelWidth 22015 hdd_nl80211_chwidth_to_chwidth(uint8_t nl80211_chwidth) 22016 { 22017 if (nl80211_chwidth >= ARRAY_SIZE(chwidth_info) || 22018 !chwidth_info[nl80211_chwidth].sir_chwidth_valid) { 22019 hdd_err("Unsupported channel width %d", nl80211_chwidth); 22020 return -EINVAL; 22021 } 22022 22023 return chwidth_info[nl80211_chwidth].sir_chwidth; 22024 } 22025 22026 uint8_t hdd_chwidth_to_nl80211_chwidth(enum eSirMacHTChannelWidth chwidth) 22027 { 22028 int i; 22029 22030 for (i = 0; i < ARRAY_SIZE(chwidth_info); i++) { 22031 if (chwidth_info[i].sir_chwidth_valid && 22032 chwidth_info[i].sir_chwidth == chwidth) 22033 return i; 22034 } 22035 22036 hdd_err("Unsupported channel width %d", chwidth); 22037 return 0xFF; 22038 } 22039 22040 uint8_t hdd_phy_chwidth_to_nl80211_chwidth(enum phy_ch_width chwidth) 22041 { 22042 int i; 22043 22044 for (i = 0; i < ARRAY_SIZE(chwidth_info); i++) { 22045 if (chwidth_info[i].sir_chwidth_valid && 22046 chwidth_info[i].phy_chwidth == chwidth) 22047 return i; 22048 } 22049 22050 hdd_err("Unsupported channel width %d", chwidth); 22051 return 0xFF; 22052 } 22053 22054 enum hw_mode_bandwidth wlan_hdd_get_channel_bw(enum nl80211_chan_width width) 22055 { 22056 if (width >= ARRAY_SIZE(chwidth_info)) { 22057 hdd_err("Invalid width: %d, using default 20MHz", width); 22058 return HW_MODE_20_MHZ; 22059 } 22060 22061 return chwidth_info[width].ch_bw; 22062 } 22063 22064 uint8_t *hdd_ch_width_str(enum phy_ch_width ch_width) 22065 { 22066 int i; 22067 22068 for (i = 0; i < ARRAY_SIZE(chwidth_info); i++) { 22069 if (chwidth_info[i].phy_chwidth == ch_width) 22070 return chwidth_info[i].ch_bw_str; 22071 } 22072 22073 return "UNKNOWN"; 22074 } 22075 22076 int hdd_we_set_ch_width(struct wlan_hdd_link_info *link_info, int ch_width) 22077 { 22078 int i; 22079 uint8_t link_id = 0xFF; 22080 22081 /* updating channel bonding only on 5Ghz */ 22082 hdd_debug("wmi_vdev_param_chwidth val %d", ch_width); 22083 22084 for (i = 0; i < ARRAY_SIZE(chwidth_info); i++) { 22085 if (!chwidth_info[i].sir_chwidth_valid || 22086 chwidth_info[i].sir_chwidth != ch_width) 22087 continue; 22088 22089 return hdd_update_channel_width(link_info, ch_width, 22090 chwidth_info[i].bonding_mode, 22091 link_id, false); 22092 } 22093 22094 hdd_err("Invalid ch_width %d", ch_width); 22095 return -EINVAL; 22096 } 22097 22098 /* Register the module init/exit functions */ 22099 module_init(hdd_module_init); 22100 module_exit(hdd_module_exit); 22101 22102 MODULE_LICENSE("Dual BSD/GPL"); 22103 MODULE_AUTHOR("Qualcomm Atheros, Inc."); 22104 MODULE_DESCRIPTION("WLAN HOST DEVICE DRIVER"); 22105 22106 const struct kernel_param_ops con_mode_ops = { 22107 .set = con_mode_handler, 22108 .get = param_get_int, 22109 }; 22110 22111 #ifdef FEATURE_WLAN_RESIDENT_DRIVER 22112 EXPORT_SYMBOL(con_mode_ops); 22113 #endif 22114 22115 const struct kernel_param_ops con_mode_ftm_ops = { 22116 .set = con_mode_handler_ftm, 22117 .get = param_get_int, 22118 }; 22119 22120 #ifdef FEATURE_WLAN_RESIDENT_DRIVER 22121 EXPORT_SYMBOL(con_mode_ftm_ops); 22122 #endif 22123 22124 #ifdef WLAN_FEATURE_EPPING 22125 static const struct kernel_param_ops con_mode_epping_ops = { 22126 .set = con_mode_handler_epping, 22127 .get = param_get_int, 22128 }; 22129 #endif 22130 22131 static const struct kernel_param_ops fwpath_ops = { 22132 .set = fwpath_changed_handler, 22133 .get = param_get_string, 22134 }; 22135 22136 static int __pcie_set_gen_speed_handler(void) 22137 { 22138 int ret; 22139 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 22140 22141 ret = wlan_hdd_validate_context(hdd_ctx); 22142 if (ret) 22143 return ret; 22144 22145 hdd_info_rl("Received PCIe gen speed %d", pcie_gen_speed); 22146 if (pcie_gen_speed <= HDD_INVALID_MIN_PCIE_GEN_SPEED || 22147 pcie_gen_speed >= HDD_INVALID_MAX_PCIE_GEN_SPEED) { 22148 hdd_err_rl("invalid pcie gen speed %d", pcie_gen_speed); 22149 return -EINVAL; 22150 } 22151 22152 hdd_ctx->current_pcie_gen_speed = pcie_gen_speed; 22153 22154 return 0; 22155 } 22156 22157 static int pcie_set_gen_speed_handler(const char *kmessage, 22158 const struct kernel_param *kp) 22159 { 22160 struct osif_driver_sync *driver_sync; 22161 int ret; 22162 22163 ret = osif_driver_sync_op_start(&driver_sync); 22164 if (ret) 22165 return ret; 22166 22167 ret = param_set_int(kmessage, kp); 22168 if (ret) { 22169 hdd_err_rl("param set int failed %d", ret); 22170 goto out; 22171 } 22172 22173 ret = __pcie_set_gen_speed_handler(); 22174 22175 out: 22176 osif_driver_sync_op_stop(driver_sync); 22177 22178 return ret; 22179 } 22180 22181 static const struct kernel_param_ops pcie_gen_speed_ops = { 22182 .set = pcie_set_gen_speed_handler, 22183 .get = param_get_int, 22184 }; 22185 22186 module_param_cb(con_mode, &con_mode_ops, &con_mode, 22187 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); 22188 22189 module_param_cb(con_mode_ftm, &con_mode_ftm_ops, &con_mode_ftm, 22190 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); 22191 22192 module_param_cb(pcie_gen_speed, &pcie_gen_speed_ops, &pcie_gen_speed, 22193 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); 22194 22195 #ifdef WLAN_FEATURE_EPPING 22196 module_param_cb(con_mode_epping, &con_mode_epping_ops, 22197 &con_mode_epping, 0644); 22198 #endif 22199 22200 module_param_cb(fwpath, &fwpath_ops, &fwpath, 22201 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); 22202 22203 module_param(enable_dfs_chan_scan, int, S_IRUSR | S_IRGRP | S_IROTH); 22204 22205 module_param(enable_11d, int, S_IRUSR | S_IRGRP | S_IROTH); 22206 22207 module_param(country_code, charp, S_IRUSR | S_IRGRP | S_IROTH); 22208 22209 static int timer_multiplier_get_handler(char *buffer, 22210 const struct kernel_param *kp) 22211 { 22212 return scnprintf(buffer, PAGE_SIZE, "%u", qdf_timer_get_multiplier()); 22213 } 22214 22215 static int timer_multiplier_set_handler(const char *kmessage, 22216 const struct kernel_param *kp) 22217 { 22218 QDF_STATUS status; 22219 uint32_t scalar; 22220 22221 status = qdf_uint32_parse(kmessage, &scalar); 22222 if (QDF_IS_STATUS_ERROR(status)) 22223 return qdf_status_to_os_return(status); 22224 22225 if (!cfg_in_range(CFG_TIMER_MULTIPLIER, scalar)) 22226 return -ERANGE; 22227 22228 qdf_timer_set_multiplier(scalar); 22229 22230 return 0; 22231 } 22232 22233 static const struct kernel_param_ops timer_multiplier_ops = { 22234 .get = timer_multiplier_get_handler, 22235 .set = timer_multiplier_set_handler, 22236 }; 22237 22238 module_param_cb(timer_multiplier, &timer_multiplier_ops, NULL, 0644); 22239