1 /* 2 * Copyright (c) 2012-2021 The Linux Foundation. All rights reserved. 3 * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved. 4 * 5 * Permission to use, copy, modify, and/or distribute this software for 6 * any purpose with or without fee is hereby granted, provided that the 7 * above copyright notice and this permission notice appear in all 8 * copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 11 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 12 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 13 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 14 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 15 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 16 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 17 * PERFORMANCE OF THIS SOFTWARE. 18 */ 19 20 /** 21 * DOC: wlan_hdd_main.c 22 * 23 * WLAN Host Device Driver implementation 24 * 25 */ 26 27 /* Include Files */ 28 #include <wbuff.h> 29 #include "cfg_ucfg_api.h" 30 #include <wlan_hdd_includes.h> 31 #include <cds_api.h> 32 #include <cds_sched.h> 33 #include <linux/cpu.h> 34 #include <linux/etherdevice.h> 35 #include <linux/firmware.h> 36 #include <linux/kernel.h> 37 #include <wlan_hdd_tx_rx.h> 38 #include <wni_api.h> 39 #include <wlan_hdd_cfg.h> 40 #include <wlan_ptt_sock_svc.h> 41 #include <dbglog_host.h> 42 #include <wlan_logging_sock_svc.h> 43 #include <wlan_roam_debug.h> 44 #include <wlan_hdd_connectivity_logging.h> 45 #include "osif_sync.h" 46 #include <wlan_hdd_wowl.h> 47 #include <wlan_hdd_misc.h> 48 #include <wlan_hdd_wext.h> 49 #include "wlan_hdd_trace.h" 50 #include "wlan_hdd_ioctl.h" 51 #include "wlan_hdd_ftm.h" 52 #include "wlan_hdd_power.h" 53 #include "wlan_hdd_stats.h" 54 #include "wlan_hdd_scan.h" 55 #include "wlan_policy_mgr_ucfg.h" 56 #include "wlan_osif_priv.h" 57 #include <wlan_osif_request_manager.h> 58 #ifdef CONFIG_LEAK_DETECTION 59 #include "qdf_debug_domain.h" 60 #endif 61 #include "qdf_delayed_work.h" 62 #include "qdf_periodic_work.h" 63 #include "qdf_str.h" 64 #include "qdf_talloc.h" 65 #include "qdf_trace.h" 66 #include "qdf_types.h" 67 #include "qdf_net_if.h" 68 #include <cdp_txrx_peer_ops.h> 69 #include <cdp_txrx_misc.h> 70 #include <cdp_txrx_stats.h> 71 #include "cdp_txrx_flow_ctrl_legacy.h" 72 #include "qdf_ssr_driver_dump.h" 73 74 #include <net/addrconf.h> 75 #include <linux/wireless.h> 76 #include <net/cfg80211.h> 77 #include <linux/inetdevice.h> 78 #include <net/addrconf.h> 79 #include "wlan_hdd_cfg80211.h" 80 #include "wlan_hdd_ext_scan.h" 81 #include "wlan_hdd_p2p.h" 82 #include <linux/rtnetlink.h> 83 #include "sap_api.h" 84 #include <sap_internal.h> 85 #include <linux/semaphore.h> 86 #include <linux/ctype.h> 87 #include <linux/compat.h> 88 #include <linux/ethtool.h> 89 #include <linux/suspend.h> 90 91 #ifdef WLAN_FEATURE_DP_BUS_BANDWIDTH 92 #include "qdf_periodic_work.h" 93 #endif 94 95 #include <wlan_hdd_hostapd.h> 96 #include <wlan_hdd_softap_tx_rx.h> 97 #include <wlan_hdd_green_ap.h> 98 #include "qwlan_version.h" 99 #include "wma_types.h" 100 #include "wlan_hdd_tdls.h" 101 #ifdef FEATURE_WLAN_CH_AVOID 102 #include "cds_regdomain.h" 103 #endif /* FEATURE_WLAN_CH_AVOID */ 104 #include "cdp_txrx_flow_ctrl_v2.h" 105 #include "pld_common.h" 106 #include "wlan_hdd_ocb.h" 107 #include "wlan_hdd_nan.h" 108 #include "wlan_hdd_debugfs.h" 109 #include "wlan_hdd_debugfs_csr.h" 110 #include "wlan_hdd_driver_ops.h" 111 #include "epping_main.h" 112 #include "wlan_hdd_data_stall_detection.h" 113 #include "wlan_hdd_mpta_helper.h" 114 115 #include <wlan_hdd_ipa.h> 116 #include "hif.h" 117 #include "wma.h" 118 #include "wlan_policy_mgr_api.h" 119 #include "wlan_hdd_tsf.h" 120 #include "bmi.h" 121 #include <wlan_hdd_regulatory.h> 122 #include "wlan_hdd_lpass.h" 123 #include "wlan_nan_api.h" 124 #include <wlan_hdd_napi.h> 125 #include "wlan_hdd_disa.h" 126 #include <dispatcher_init_deinit.h> 127 #include "wlan_hdd_object_manager.h" 128 #include "cds_utils.h" 129 #include <cdp_txrx_handle.h> 130 #include <qca_vendor.h> 131 #include "wlan_pmo_ucfg_api.h" 132 #include "sir_api.h" 133 #include "os_if_wifi_pos.h" 134 #include "wifi_pos_api.h" 135 #include "wlan_hdd_oemdata.h" 136 #include "wlan_hdd_he.h" 137 #include "os_if_nan.h" 138 #include "nan_public_structs.h" 139 #include "nan_ucfg_api.h" 140 #include "wlan_reg_ucfg_api.h" 141 #include "wlan_hdd_afc.h" 142 #include "wlan_afc_ucfg_api.h" 143 #include "wlan_dfs_ucfg_api.h" 144 #include "wlan_hdd_rx_monitor.h" 145 #include "sme_power_save_api.h" 146 #include "enet.h" 147 #include <cdp_txrx_cmn_struct.h> 148 #include "wlan_hdd_sysfs.h" 149 #include "wlan_disa_ucfg_api.h" 150 #include "wlan_disa_obj_mgmt_api.h" 151 #include "wlan_action_oui_ucfg_api.h" 152 #include "wlan_ipa_ucfg_api.h" 153 #include <target_if.h> 154 #include "wlan_hdd_nud_tracking.h" 155 #include "wlan_hdd_apf.h" 156 #include "wlan_hdd_twt.h" 157 #include "qc_sap_ioctl.h" 158 #include "wlan_mlme_main.h" 159 #include "wlan_p2p_cfg_api.h" 160 #include "wlan_cfg80211_p2p.h" 161 #include "wlan_cfg80211_interop_issues_ap.h" 162 #include "wlan_tdls_cfg_api.h" 163 #include <wlan_hdd_rssi_monitor.h> 164 #include "wlan_mlme_ucfg_api.h" 165 #include "wlan_mlme_twt_ucfg_api.h" 166 #include "wlan_fwol_ucfg_api.h" 167 #include "wlan_policy_mgr_ucfg.h" 168 #include "qdf_func_tracker.h" 169 #include "pld_common.h" 170 #include "wlan_hdd_pre_cac.h" 171 172 #include "sme_api.h" 173 174 #ifdef CNSS_GENL 175 #ifdef CONFIG_CNSS_OUT_OF_TREE 176 #include "cnss_nl.h" 177 #else 178 #include <net/cnss_nl.h> 179 #endif 180 #endif 181 #include "wlan_reg_ucfg_api.h" 182 #include "wlan_ocb_ucfg_api.h" 183 #include <wlan_hdd_spectralscan.h> 184 #include "wlan_green_ap_ucfg_api.h" 185 #include <wlan_p2p_ucfg_api.h> 186 #include <wlan_interop_issues_ap_ucfg_api.h> 187 #include <target_type.h> 188 #include <wlan_hdd_debugfs_coex.h> 189 #include <wlan_hdd_debugfs_config.h> 190 #include "wlan_dlm_ucfg_api.h" 191 #include "ftm_time_sync_ucfg_api.h" 192 #include "wlan_pre_cac_ucfg_api.h" 193 #include "ol_txrx.h" 194 #include "wlan_hdd_sta_info.h" 195 #include "mac_init_api.h" 196 #include "wlan_pkt_capture_ucfg_api.h" 197 #include <wlan_hdd_sar_limits.h> 198 #include "cfg_nan_api.h" 199 #include "wlan_hdd_btc_chain_mode.h" 200 #include <wlan_hdd_dcs.h> 201 #include "wlan_hdd_debugfs_unit_test.h" 202 #include "wlan_hdd_debugfs_mibstat.h" 203 #include <wlan_hdd_hang_event.h> 204 #include "wlan_global_lmac_if_api.h" 205 #include "wlan_coex_ucfg_api.h" 206 #include "wlan_cm_roam_api.h" 207 #include "wlan_cm_roam_ucfg_api.h" 208 #include <cdp_txrx_ctrl.h> 209 #include "qdf_lock.h" 210 #include "wlan_hdd_thermal.h" 211 #include "osif_cm_util.h" 212 #include "wlan_hdd_gpio_wakeup.h" 213 #include "wlan_hdd_bootup_marker.h" 214 #include "wlan_dp_ucfg_api.h" 215 #include "wlan_hdd_medium_assess.h" 216 #include "wlan_hdd_eht.h" 217 #include <linux/bitfield.h> 218 #include "wlan_hdd_mlo.h" 219 #include <wlan_hdd_son.h> 220 #ifdef WLAN_FEATURE_11BE_MLO 221 #include <wlan_mlo_mgr_ap.h> 222 #endif 223 #include "wlan_osif_features.h" 224 #include "wlan_vdev_mgr_ucfg_api.h" 225 #include <wlan_objmgr_psoc_obj_i.h> 226 #include <wlan_objmgr_vdev_obj_i.h> 227 #include "wifi_pos_ucfg_api.h" 228 #include "osif_vdev_mgr_util.h" 229 #include <son_ucfg_api.h> 230 #include "osif_twt_util.h" 231 #include "wlan_twt_ucfg_ext_api.h" 232 #include "wlan_hdd_mcc_quota.h" 233 #include "osif_pre_cac.h" 234 #include "wlan_hdd_pre_cac.h" 235 #include "wlan_osif_features.h" 236 #ifdef WLAN_FEATURE_DYNAMIC_RX_AGGREGATION 237 #include <net/pkt_cls.h> 238 #endif 239 #include "wlan_dp_public_struct.h" 240 #include "os_if_dp.h" 241 #include <wlan_dp_ucfg_api.h> 242 #include "wlan_psoc_mlme_ucfg_api.h" 243 #include "os_if_qmi.h" 244 #include "wlan_qmi_ucfg_api.h" 245 #include "wlan_psoc_mlme_ucfg_api.h" 246 #include "wlan_ll_sap_ucfg_api.h" 247 248 #include "os_if_dp_local_pkt_capture.h" 249 #include <wlan_mlo_mgr_link_switch.h> 250 #include "cdp_txrx_mon.h" 251 #include "os_if_ll_sap.h" 252 #include "wlan_p2p_ucfg_api.h" 253 #include "wlan_crypto_obj_mgr_i.h" 254 255 #ifdef MULTI_CLIENT_LL_SUPPORT 256 #define WLAM_WLM_HOST_DRIVER_PORT_ID 0xFFFFFF 257 #endif 258 259 #ifdef MODULE 260 #ifdef WLAN_WEAR_CHIPSET 261 #define WLAN_MODULE_NAME "wlan" 262 #else 263 #define WLAN_MODULE_NAME module_name(THIS_MODULE) 264 #endif 265 #else 266 #define WLAN_MODULE_NAME "wlan" 267 #endif 268 269 #ifdef TIMER_MANAGER 270 #define TIMER_MANAGER_STR " +TIMER_MANAGER" 271 #else 272 #define TIMER_MANAGER_STR "" 273 #endif 274 275 #ifdef MEMORY_DEBUG 276 #define MEMORY_DEBUG_STR " +MEMORY_DEBUG" 277 #else 278 #define MEMORY_DEBUG_STR "" 279 #endif 280 281 #ifdef PANIC_ON_BUG 282 #define PANIC_ON_BUG_STR " +PANIC_ON_BUG" 283 #else 284 #define PANIC_ON_BUG_STR "" 285 #endif 286 287 /* PCIe gen speed change idle shutdown timer 100 milliseconds */ 288 #define HDD_PCIE_GEN_SPEED_CHANGE_TIMEOUT_MS (100) 289 290 #define MAX_NET_DEV_REF_LEAK_ITERATIONS 10 291 #define NET_DEV_REF_LEAK_ITERATION_SLEEP_TIME_MS 10 292 293 #ifdef FEATURE_TSO 294 #define TSO_FEATURE_FLAGS (NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_SG) 295 #else 296 #define TSO_FEATURE_FLAGS 0 297 #endif 298 299 int wlan_start_ret_val; 300 static DECLARE_COMPLETION(wlan_start_comp); 301 static qdf_atomic_t wlan_hdd_state_fops_ref; 302 #ifndef MODULE 303 static struct gwlan_loader *wlan_loader; 304 static ssize_t wlan_boot_cb(struct kobject *kobj, 305 struct kobj_attribute *attr, 306 const char *buf, size_t count); 307 struct gwlan_loader { 308 bool loaded_state; 309 struct kobject *boot_wlan_obj; 310 struct attribute_group *attr_group; 311 }; 312 313 static struct kobj_attribute wlan_boot_attribute = 314 __ATTR(boot_wlan, 0220, NULL, wlan_boot_cb); 315 316 static struct attribute *attrs[] = { 317 &wlan_boot_attribute.attr, 318 NULL, 319 }; 320 #define MODULE_INITIALIZED 1 321 322 #ifdef MULTI_IF_NAME 323 #define WLAN_LOADER_NAME "boot_" MULTI_IF_NAME 324 #else 325 #define WLAN_LOADER_NAME "boot_wlan" 326 #endif 327 #endif 328 329 /* the Android framework expects this param even though we don't use it */ 330 #define BUF_LEN 20 331 static char fwpath_buffer[BUF_LEN]; 332 static struct kparam_string fwpath = { 333 .string = fwpath_buffer, 334 .maxlen = BUF_LEN, 335 }; 336 337 char *country_code; 338 #ifdef FEATURE_WLAN_RESIDENT_DRIVER 339 EXPORT_SYMBOL(country_code); 340 #endif 341 static int enable_11d = -1; 342 static int enable_dfs_chan_scan = -1; 343 static bool is_mode_change_psoc_idle_shutdown; 344 345 #define WLAN_NLINK_CESIUM 30 346 347 static qdf_wake_lock_t wlan_wake_lock; 348 349 /* The valid PCIe gen speeds are 1, 2, 3 */ 350 #define HDD_INVALID_MIN_PCIE_GEN_SPEED (0) 351 #define HDD_INVALID_MAX_PCIE_GEN_SPEED (4) 352 353 #define MAX_PDEV_PRE_ENABLE_PARAMS 8 354 #define FTM_MAX_PDEV_PARAMS 1 355 356 #define WOW_MAX_FILTER_LISTS 1 357 #define WOW_MAX_FILTERS_PER_LIST 4 358 #define WOW_MIN_PATTERN_SIZE 6 359 #define WOW_MAX_PATTERN_SIZE 64 360 #define MGMT_DEFAULT_DATA_RATE_6GHZ 0x400 /* This maps to 8.6Mbps data rate */ 361 362 #define IS_IDLE_STOP (!cds_is_driver_unloading() && \ 363 !cds_is_driver_recovering() && !cds_is_driver_loading()) 364 365 #define HDD_FW_VER_MAJOR_SPID(tgt_fw_ver) ((tgt_fw_ver & 0xf0000000) >> 28) 366 #define HDD_FW_VER_MINOR_SPID(tgt_fw_ver) ((tgt_fw_ver & 0xf000000) >> 24) 367 #define HDD_FW_VER_SIID(tgt_fw_ver) ((tgt_fw_ver & 0xf00000) >> 20) 368 #define HDD_FW_VER_CRM_ID(tgt_fw_ver) (tgt_fw_ver & 0x7fff) 369 #define HDD_FW_VER_SUB_ID(tgt_fw_ver_ext) \ 370 (((tgt_fw_ver_ext & 0x1c00) >> 6) | ((tgt_fw_ver_ext & 0xf0000000) >> 28)) 371 #define HDD_FW_VER_REL_ID(tgt_fw_ver_ext) \ 372 ((tgt_fw_ver_ext & 0xf800000) >> 23) 373 374 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0)) 375 static const struct wiphy_wowlan_support wowlan_support_reg_init = { 376 .flags = WIPHY_WOWLAN_ANY | 377 WIPHY_WOWLAN_MAGIC_PKT | 378 WIPHY_WOWLAN_DISCONNECT | 379 WIPHY_WOWLAN_SUPPORTS_GTK_REKEY | 380 WIPHY_WOWLAN_GTK_REKEY_FAILURE | 381 WIPHY_WOWLAN_EAP_IDENTITY_REQ | 382 WIPHY_WOWLAN_4WAY_HANDSHAKE | 383 WIPHY_WOWLAN_RFKILL_RELEASE, 384 .n_patterns = WOW_MAX_FILTER_LISTS * WOW_MAX_FILTERS_PER_LIST, 385 .pattern_min_len = WOW_MIN_PATTERN_SIZE, 386 .pattern_max_len = WOW_MAX_PATTERN_SIZE, 387 }; 388 #endif 389 390 static const struct category_info cinfo[MAX_SUPPORTED_CATEGORY] = { 391 [QDF_MODULE_ID_TLSHIM] = {QDF_TRACE_LEVEL_ALL}, 392 [QDF_MODULE_ID_WMI] = {QDF_TRACE_LEVEL_ALL}, 393 [QDF_MODULE_ID_HTT] = {QDF_TRACE_LEVEL_ALL}, 394 [QDF_MODULE_ID_HDD] = {QDF_TRACE_LEVEL_ALL}, 395 [QDF_MODULE_ID_SME] = {QDF_TRACE_LEVEL_ALL}, 396 [QDF_MODULE_ID_PE] = {QDF_TRACE_LEVEL_ALL}, 397 [QDF_MODULE_ID_WMA] = {QDF_TRACE_LEVEL_ALL}, 398 [QDF_MODULE_ID_SYS] = {QDF_TRACE_LEVEL_ALL}, 399 [QDF_MODULE_ID_QDF] = {QDF_TRACE_LEVEL_ALL}, 400 [QDF_MODULE_ID_SAP] = {QDF_TRACE_LEVEL_ALL}, 401 [QDF_MODULE_ID_HDD_SOFTAP] = {QDF_TRACE_LEVEL_ALL}, 402 [QDF_MODULE_ID_HDD_DATA] = {QDF_DATA_PATH_TRACE_LEVEL}, 403 [QDF_MODULE_ID_HDD_SAP_DATA] = {QDF_DATA_PATH_TRACE_LEVEL}, 404 [QDF_MODULE_ID_HIF] = {QDF_DATA_PATH_TRACE_LEVEL}, 405 [QDF_MODULE_ID_HTC] = {QDF_DATA_PATH_TRACE_LEVEL}, 406 [QDF_MODULE_ID_TXRX] = {QDF_DATA_PATH_TRACE_LEVEL}, 407 [QDF_MODULE_ID_HAL] = {QDF_DATA_PATH_TRACE_LEVEL}, 408 [QDF_MODULE_ID_QDF_DEVICE] = {QDF_TRACE_LEVEL_ALL}, 409 [QDF_MODULE_ID_CFG] = {QDF_TRACE_LEVEL_ALL}, 410 [QDF_MODULE_ID_BMI] = {QDF_TRACE_LEVEL_ALL}, 411 [QDF_MODULE_ID_EPPING] = {QDF_TRACE_LEVEL_ALL}, 412 [QDF_MODULE_ID_QVIT] = {QDF_TRACE_LEVEL_ALL}, 413 [QDF_MODULE_ID_DP] = {QDF_DATA_PATH_TRACE_LEVEL}, 414 [QDF_MODULE_ID_DP_TX_CAPTURE] = {QDF_DATA_PATH_TRACE_LEVEL}, 415 [QDF_MODULE_ID_DP_INIT] = {QDF_DATA_PATH_TRACE_LEVEL}, 416 [QDF_MODULE_ID_DP_STATS] = {QDF_DATA_PATH_TRACE_LEVEL}, 417 [QDF_MODULE_ID_DP_HTT] = {QDF_DATA_PATH_TRACE_LEVEL}, 418 [QDF_MODULE_ID_DP_PEER] = {QDF_DATA_PATH_TRACE_LEVEL}, 419 [QDF_MODULE_ID_DP_HTT_TX_STATS] = {QDF_DATA_PATH_TRACE_LEVEL}, 420 [QDF_MODULE_ID_DP_REO] = {QDF_DATA_PATH_TRACE_LEVEL}, 421 [QDF_MODULE_ID_DP_VDEV] = {QDF_DATA_PATH_TRACE_LEVEL}, 422 [QDF_MODULE_ID_DP_CDP] = {QDF_DATA_PATH_TRACE_LEVEL}, 423 [QDF_MODULE_ID_DP_UMAC_RESET] = {QDF_DATA_PATH_TRACE_LEVEL}, 424 [QDF_MODULE_ID_DP_SAWF] = {QDF_DATA_PATH_TRACE_LEVEL}, 425 [QDF_MODULE_ID_SOC] = {QDF_TRACE_LEVEL_ALL}, 426 [QDF_MODULE_ID_OS_IF] = {QDF_TRACE_LEVEL_ALL}, 427 [QDF_MODULE_ID_TARGET_IF] = {QDF_TRACE_LEVEL_ALL}, 428 [QDF_MODULE_ID_SCHEDULER] = {QDF_TRACE_LEVEL_ALL}, 429 [QDF_MODULE_ID_MGMT_TXRX] = {QDF_TRACE_LEVEL_ALL}, 430 [QDF_MODULE_ID_PMO] = {QDF_TRACE_LEVEL_ALL}, 431 [QDF_MODULE_ID_SCAN] = {QDF_TRACE_LEVEL_ALL}, 432 [QDF_MODULE_ID_POLICY_MGR] = {QDF_TRACE_LEVEL_ALL}, 433 [QDF_MODULE_ID_P2P] = {QDF_TRACE_LEVEL_ALL}, 434 [QDF_MODULE_ID_TDLS] = {QDF_TRACE_LEVEL_ALL}, 435 [QDF_MODULE_ID_REGULATORY] = {QDF_TRACE_LEVEL_ALL}, 436 [QDF_MODULE_ID_SERIALIZATION] = {QDF_TRACE_LEVEL_ALL}, 437 [QDF_MODULE_ID_DFS] = {QDF_TRACE_LEVEL_ALL}, 438 [QDF_MODULE_ID_OBJ_MGR] = {QDF_TRACE_LEVEL_ALL}, 439 [QDF_MODULE_ID_ROAM_DEBUG] = {QDF_TRACE_LEVEL_ALL}, 440 [QDF_MODULE_ID_GREEN_AP] = {QDF_TRACE_LEVEL_ALL}, 441 [QDF_MODULE_ID_OCB] = {QDF_TRACE_LEVEL_ALL}, 442 [QDF_MODULE_ID_IPA] = {QDF_TRACE_LEVEL_ALL}, 443 [QDF_MODULE_ID_ACTION_OUI] = {QDF_TRACE_LEVEL_ALL}, 444 [QDF_MODULE_ID_CONFIG] = {QDF_TRACE_LEVEL_ALL}, 445 [QDF_MODULE_ID_MLME] = {QDF_TRACE_LEVEL_ALL}, 446 [QDF_MODULE_ID_TARGET] = {QDF_TRACE_LEVEL_ALL}, 447 [QDF_MODULE_ID_CRYPTO] = {QDF_TRACE_LEVEL_ALL}, 448 [QDF_MODULE_ID_FWOL] = {QDF_TRACE_LEVEL_ALL}, 449 [QDF_MODULE_ID_SM_ENGINE] = {QDF_TRACE_LEVEL_ALL}, 450 [QDF_MODULE_ID_CMN_MLME] = {QDF_TRACE_LEVEL_ALL}, 451 [QDF_MODULE_ID_NAN] = {QDF_TRACE_LEVEL_ALL}, 452 [QDF_MODULE_ID_CP_STATS] = {QDF_TRACE_LEVEL_ALL}, 453 [QDF_MODULE_ID_DCS] = {QDF_TRACE_LEVEL_ALL}, 454 [QDF_MODULE_ID_INTEROP_ISSUES_AP] = {QDF_TRACE_LEVEL_ALL}, 455 [QDF_MODULE_ID_DENYLIST_MGR] = {QDF_TRACE_LEVEL_ALL}, 456 [QDF_MODULE_ID_DIRECT_BUF_RX] = {QDF_TRACE_LEVEL_ALL}, 457 [QDF_MODULE_ID_SPECTRAL] = {QDF_TRACE_LEVEL_ALL}, 458 [QDF_MODULE_ID_WIFIPOS] = {QDF_TRACE_LEVEL_ALL}, 459 [QDF_MODULE_ID_PKT_CAPTURE] = {QDF_TRACE_LEVEL_ALL}, 460 [QDF_MODULE_ID_FTM_TIME_SYNC] = {QDF_TRACE_LEVEL_ALL}, 461 [QDF_MODULE_ID_CFR] = {QDF_TRACE_LEVEL_ALL}, 462 [QDF_MODULE_ID_IFMGR] = {QDF_TRACE_LEVEL_ALL}, 463 [QDF_MODULE_ID_GPIO] = {QDF_TRACE_LEVEL_ALL}, 464 [QDF_MODULE_ID_T2LM] = {QDF_TRACE_LEVEL_ALL}, 465 [QDF_MODULE_ID_MLO] = {QDF_TRACE_LEVEL_ALL}, 466 [QDF_MODULE_ID_SON] = {QDF_TRACE_LEVEL_ALL}, 467 [QDF_MODULE_ID_TWT] = {QDF_TRACE_LEVEL_ALL}, 468 [QDF_MODULE_ID_WLAN_PRE_CAC] = {QDF_TRACE_LEVEL_ALL}, 469 [QDF_MODULE_ID_COAP] = {QDF_TRACE_LEVEL_ALL}, 470 [QDF_MODULE_ID_MON_FILTER] = {QDF_DATA_PATH_TRACE_LEVEL}, 471 [QDF_MODULE_ID_LL_SAP] = {QDF_TRACE_LEVEL_ALL}, 472 }; 473 474 struct notifier_block hdd_netdev_notifier; 475 476 struct sock *cesium_nl_srv_sock; 477 #ifdef FEATURE_WLAN_AUTO_SHUTDOWN 478 static void wlan_hdd_auto_shutdown_cb(void); 479 #endif 480 481 static void hdd_dp_register_callbacks(struct hdd_context *hdd_ctx); 482 hdd_adapter_is_ap(struct hdd_adapter * adapter)483 bool hdd_adapter_is_ap(struct hdd_adapter *adapter) 484 { 485 if (!adapter) { 486 hdd_err("null adapter"); 487 return false; 488 } 489 490 return adapter->device_mode == QDF_SAP_MODE || 491 adapter->device_mode == QDF_P2P_GO_MODE; 492 } 493 hdd_common_roam_callback(struct wlan_objmgr_psoc * psoc,uint8_t session_id,struct csr_roam_info * roam_info,eRoamCmdStatus roam_status,eCsrRoamResult roam_result)494 QDF_STATUS hdd_common_roam_callback(struct wlan_objmgr_psoc *psoc, 495 uint8_t session_id, 496 struct csr_roam_info *roam_info, 497 eRoamCmdStatus roam_status, 498 eCsrRoamResult roam_result) 499 { 500 struct hdd_context *hdd_ctx; 501 struct hdd_adapter *adapter; 502 struct wlan_hdd_link_info *link_info; 503 QDF_STATUS status = QDF_STATUS_SUCCESS; 504 505 link_info = wlan_hdd_get_link_info_from_vdev(psoc, session_id); 506 if (!link_info) 507 return QDF_STATUS_E_INVAL; 508 509 adapter = link_info->adapter; 510 hdd_ctx = WLAN_HDD_GET_CTX(adapter); 511 if (!hdd_ctx) 512 return QDF_STATUS_E_INVAL; 513 514 switch (adapter->device_mode) { 515 case QDF_STA_MODE: 516 case QDF_NDI_MODE: 517 case QDF_P2P_CLIENT_MODE: 518 case QDF_P2P_DEVICE_MODE: 519 status = hdd_sme_roam_callback(link_info, roam_info, 520 roam_status, roam_result); 521 break; 522 case QDF_SAP_MODE: 523 case QDF_P2P_GO_MODE: 524 status = 525 wlansap_roam_callback(link_info->session.ap.sap_context, 526 roam_info, roam_status, 527 roam_result); 528 break; 529 default: 530 hdd_err("Wrong device mode"); 531 break; 532 } 533 534 return status; 535 } 536 hdd_start_complete(int ret)537 void hdd_start_complete(int ret) 538 { 539 wlan_start_ret_val = ret; 540 complete_all(&wlan_start_comp); 541 } 542 543 #ifdef WLAN_FEATURE_LOCAL_PKT_CAPTURE 544 /** 545 * wlan_hdd_lpc_del_monitor_interface() - Delete monitor interface 546 * @hdd_ctx: hdd_ctx 547 * @is_virtual_iface: Is virtual interface 548 * 549 * This function takes care of deleting monitor interface 550 * 551 * Return: none 552 */ 553 static void wlan_hdd_lpc_del_monitor_interface(struct hdd_context * hdd_ctx,bool is_virtual_iface)554 wlan_hdd_lpc_del_monitor_interface(struct hdd_context *hdd_ctx, 555 bool is_virtual_iface) 556 { 557 struct hdd_adapter *adapter; 558 void *soc; 559 bool running; 560 561 if (!hdd_ctx) 562 return; 563 564 if (!ucfg_dp_is_local_pkt_capture_enabled(hdd_ctx->psoc)) 565 return; 566 567 soc = cds_get_context(QDF_MODULE_ID_SOC); 568 if (!soc) 569 return; 570 571 running = cdp_is_local_pkt_capture_running(soc, OL_TXRX_PDEV_ID); 572 if (!running) 573 return; 574 575 adapter = hdd_get_adapter(hdd_ctx, QDF_MONITOR_MODE); 576 if (!adapter) { 577 hdd_debug("There is no monitor adapter"); 578 return; 579 } 580 581 hdd_debug("lpc: Delete monitor interface"); 582 583 wlan_hdd_release_intf_addr(hdd_ctx, adapter->mac_addr.bytes); 584 qdf_zero_macaddr(&adapter->mac_addr); 585 hdd_stop_adapter(hdd_ctx, adapter); 586 hdd_deinit_adapter(hdd_ctx, adapter, true); 587 adapter->is_virtual_iface = is_virtual_iface; 588 hdd_ctx->lpc_info.mon_adapter = adapter; 589 590 hdd_ctx->lpc_info.lpc_wk_scheduled = true; 591 qdf_sched_work(0, &hdd_ctx->lpc_info.lpc_wk); 592 } 593 wlan_hdd_lpc_handle_concurrency(struct hdd_context * hdd_ctx,bool is_virtual_iface)594 void wlan_hdd_lpc_handle_concurrency(struct hdd_context *hdd_ctx, 595 bool is_virtual_iface) 596 { 597 wlan_hdd_lpc_del_monitor_interface(hdd_ctx, is_virtual_iface); 598 } 599 hdd_lpc_is_work_scheduled(struct hdd_context * hdd_ctx)600 bool hdd_lpc_is_work_scheduled(struct hdd_context *hdd_ctx) 601 { 602 return hdd_ctx->lpc_info.lpc_wk_scheduled; 603 } 604 hdd_lpc_work_handler(void * arg)605 static void hdd_lpc_work_handler(void *arg) 606 { 607 struct hdd_context *hdd_ctx = (struct hdd_context *)arg; 608 struct hdd_adapter *adapter; 609 struct osif_vdev_sync *vdev_sync; 610 int errno; 611 612 if (!hdd_ctx) 613 return; 614 615 adapter = hdd_ctx->lpc_info.mon_adapter; 616 if (!adapter) { 617 hdd_err("There is no monitor adapter"); 618 return; 619 } 620 621 errno = osif_vdev_sync_trans_start_wait(adapter->dev, &vdev_sync); 622 if (errno) 623 return; 624 625 osif_vdev_sync_unregister(adapter->dev); 626 osif_vdev_sync_wait_for_ops(vdev_sync); 627 628 hdd_close_adapter(hdd_ctx, adapter, true); 629 hdd_ctx->lpc_info.lpc_wk_scheduled = false; 630 631 osif_vdev_sync_trans_stop(vdev_sync); 632 osif_vdev_sync_destroy(vdev_sync); 633 } 634 635 static inline hdd_lp_create_work(struct hdd_context * hdd_ctx)636 void hdd_lp_create_work(struct hdd_context *hdd_ctx) 637 { 638 hdd_ctx->lpc_info.lpc_wk_scheduled = false; 639 qdf_create_work(0, &hdd_ctx->lpc_info.lpc_wk, hdd_lpc_work_handler, 640 hdd_ctx); 641 } 642 643 static inline hdd_lpc_delete_work(struct hdd_context * hdd_ctx)644 void hdd_lpc_delete_work(struct hdd_context *hdd_ctx) 645 { 646 qdf_flush_work(&hdd_ctx->lpc_info.lpc_wk); 647 hdd_ctx->lpc_info.lpc_wk_scheduled = false; 648 qdf_destroy_work(NULL, &hdd_ctx->lpc_info.lpc_wk); 649 } 650 651 #else 652 static inline hdd_lp_create_work(struct hdd_context * hdd_ctx)653 void hdd_lp_create_work(struct hdd_context *hdd_ctx) 654 { 655 } 656 657 static inline hdd_lpc_delete_work(struct hdd_context * hdd_ctx)658 void hdd_lpc_delete_work(struct hdd_context *hdd_ctx) 659 { 660 } 661 662 static inline wlan_hdd_lpc_del_monitor_interface(struct hdd_context * hdd_ctx,bool is_virtual_iface)663 void wlan_hdd_lpc_del_monitor_interface(struct hdd_context *hdd_ctx, 664 bool is_virtual_iface) 665 { 666 } 667 #endif 668 669 #ifdef QCA_HL_NETDEV_FLOW_CONTROL wlan_hdd_mod_fc_timer(struct hdd_adapter * adapter,enum netif_action_type action)670 void wlan_hdd_mod_fc_timer(struct hdd_adapter *adapter, 671 enum netif_action_type action) 672 { 673 struct hdd_stats *hdd_stats; 674 675 if (!adapter->tx_flow_timer_initialized) 676 return; 677 678 hdd_stats = &adapter->deflink->hdd_stats; 679 if (action == WLAN_WAKE_NON_PRIORITY_QUEUE) { 680 qdf_mc_timer_stop(&adapter->tx_flow_control_timer); 681 hdd_stats->tx_rx_stats.is_txflow_paused = false; 682 hdd_stats->tx_rx_stats.txflow_unpause_cnt++; 683 } else if (action == WLAN_STOP_NON_PRIORITY_QUEUE) { 684 QDF_STATUS status = 685 qdf_mc_timer_start(&adapter->tx_flow_control_timer, 686 WLAN_HDD_TX_FLOW_CONTROL_OS_Q_BLOCK_TIME); 687 688 if (!QDF_IS_STATUS_SUCCESS(status)) 689 hdd_err("Failed to start tx_flow_control_timer"); 690 else 691 hdd_stats->tx_rx_stats.txflow_timer_cnt++; 692 693 hdd_stats->tx_rx_stats.txflow_pause_cnt++; 694 hdd_stats->tx_rx_stats.is_txflow_paused = true; 695 } 696 } 697 #endif /* QCA_HL_NETDEV_FLOW_CONTROL */ 698 699 /** 700 * wlan_hdd_txrx_pause_cb() - pause callback from txrx layer 701 * @vdev_id: vdev_id 702 * @action: action type 703 * @reason: reason type 704 * 705 * Return: none 706 */ wlan_hdd_txrx_pause_cb(uint8_t vdev_id,enum netif_action_type action,enum netif_reason_type reason)707 void wlan_hdd_txrx_pause_cb(uint8_t vdev_id, 708 enum netif_action_type action, enum netif_reason_type reason) 709 { 710 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 711 struct hdd_adapter *adapter; 712 struct wlan_hdd_link_info *link_info; 713 714 if (!hdd_ctx) 715 return; 716 717 link_info = hdd_get_link_info_by_vdev(hdd_ctx, vdev_id); 718 if (!link_info) 719 return; 720 721 adapter = link_info->adapter; 722 wlan_hdd_mod_fc_timer(adapter, action); 723 wlan_hdd_netif_queue_control(adapter, action, reason); 724 } 725 726 /* 727 * Store WLAN driver version and timestamp info in global variables such that 728 * crash debugger can extract them from driver debug symbol and crashdump for 729 * post processing 730 */ 731 #ifdef BUILD_TAG 732 uint8_t g_wlan_driver_version[] = QWLAN_VERSIONSTR TIMER_MANAGER_STR MEMORY_DEBUG_STR PANIC_ON_BUG_STR "; " BUILD_TAG; 733 #else 734 uint8_t g_wlan_driver_version[] = QWLAN_VERSIONSTR TIMER_MANAGER_STR MEMORY_DEBUG_STR PANIC_ON_BUG_STR; 735 #endif 736 hdd_validate_channel_and_bandwidth(struct hdd_adapter * adapter,qdf_freq_t chan_freq,enum phy_ch_width chan_bw)737 int hdd_validate_channel_and_bandwidth(struct hdd_adapter *adapter, 738 qdf_freq_t chan_freq, 739 enum phy_ch_width chan_bw) 740 { 741 struct ch_params ch_params = {0}; 742 struct hdd_context *hdd_ctx; 743 744 hdd_ctx = WLAN_HDD_GET_CTX(adapter); 745 if (!hdd_ctx) { 746 hdd_err("hdd context is NULL"); 747 return -EINVAL; 748 } 749 750 if (reg_is_chan_enum_invalid( 751 wlan_reg_get_chan_enum_for_freq(chan_freq))) { 752 hdd_err("Channel freq %d not in driver's valid channel list", chan_freq); 753 return -EOPNOTSUPP; 754 } 755 756 if ((!WLAN_REG_IS_24GHZ_CH_FREQ(chan_freq)) && 757 (!WLAN_REG_IS_5GHZ_CH_FREQ(chan_freq)) && 758 (!WLAN_REG_IS_6GHZ_CHAN_FREQ(chan_freq))) { 759 hdd_err("CH %d is not in 2.4GHz or 5GHz or 6GHz", chan_freq); 760 return -EINVAL; 761 } 762 ch_params.ch_width = CH_WIDTH_MAX; 763 wlan_reg_set_channel_params_for_pwrmode(hdd_ctx->pdev, chan_freq, 764 0, &ch_params, 765 REG_CURRENT_PWR_MODE); 766 if (ch_params.ch_width == CH_WIDTH_MAX) { 767 hdd_err("failed to get max bandwdith for %d", chan_freq); 768 return -EINVAL; 769 } 770 if (WLAN_REG_IS_24GHZ_CH_FREQ(chan_freq)) { 771 if (chan_bw == CH_WIDTH_80MHZ) { 772 hdd_err("BW80 not possible in 2.4GHz band"); 773 return -EINVAL; 774 } 775 if ((chan_bw != CH_WIDTH_20MHZ) && 776 (chan_freq == wlan_reg_ch_to_freq(CHAN_ENUM_2484)) && 777 (chan_bw != CH_WIDTH_MAX) && 778 (ch_params.ch_width == CH_WIDTH_20MHZ)) { 779 hdd_err("Only BW20 possible on channel freq 2484"); 780 return -EINVAL; 781 } 782 } 783 784 if (WLAN_REG_IS_5GHZ_CH_FREQ(chan_freq)) { 785 if ((chan_bw != CH_WIDTH_20MHZ) && 786 (chan_freq == wlan_reg_ch_to_freq(CHAN_ENUM_5825)) && 787 (chan_bw != CH_WIDTH_MAX) && 788 (ch_params.ch_width == CH_WIDTH_20MHZ)) { 789 hdd_err("Only BW20 possible on channel freq 5825"); 790 return -EINVAL; 791 } 792 } 793 794 return 0; 795 } 796 hdd_get_link_info_home_channel(struct wlan_hdd_link_info * link_info)797 uint32_t hdd_get_link_info_home_channel(struct wlan_hdd_link_info *link_info) 798 { 799 uint32_t home_chan_freq = 0; 800 enum QDF_OPMODE opmode = link_info->adapter->device_mode; 801 802 switch (opmode) { 803 case QDF_SAP_MODE: 804 case QDF_P2P_GO_MODE: 805 if (test_bit(SOFTAP_BSS_STARTED, &link_info->link_flags)) { 806 home_chan_freq = 807 link_info->session.ap.operating_chan_freq; 808 } 809 break; 810 case QDF_STA_MODE: 811 case QDF_P2P_CLIENT_MODE: 812 if (hdd_cm_is_vdev_associated(link_info)) { 813 home_chan_freq = 814 link_info->session.station.conn_info.chan_freq; 815 } 816 break; 817 default: 818 break; 819 } 820 821 return home_chan_freq; 822 } 823 hdd_get_link_info_width(struct wlan_hdd_link_info * link_info)824 enum phy_ch_width hdd_get_link_info_width(struct wlan_hdd_link_info *link_info) 825 { 826 enum phy_ch_width width = CH_WIDTH_20MHZ; 827 enum QDF_OPMODE opmode = link_info->adapter->device_mode; 828 829 switch (opmode) { 830 case QDF_SAP_MODE: 831 case QDF_P2P_GO_MODE: 832 if (test_bit(SOFTAP_BSS_STARTED, &link_info->link_flags)) { 833 struct hdd_ap_ctx *ap_ctx = 834 WLAN_HDD_GET_AP_CTX_PTR(link_info); 835 836 width = ap_ctx->sap_config.ch_params.ch_width; 837 } 838 break; 839 case QDF_STA_MODE: 840 case QDF_P2P_CLIENT_MODE: 841 if (hdd_cm_is_vdev_associated(link_info)) 842 width = link_info->session.station.conn_info.ch_width; 843 break; 844 default: 845 break; 846 } 847 848 return width; 849 } 850 851 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0)) hdd_net_dev_from_notifier(void * context)852 static inline struct net_device *hdd_net_dev_from_notifier(void *context) 853 { 854 struct netdev_notifier_info *info = context; 855 856 return info->dev; 857 } 858 #else hdd_net_dev_from_notifier(void * context)859 static inline struct net_device *hdd_net_dev_from_notifier(void *context) 860 { 861 return context; 862 } 863 #endif 864 __hdd_netdev_notifier_call(struct net_device * net_dev,unsigned long state)865 static int __hdd_netdev_notifier_call(struct net_device *net_dev, 866 unsigned long state) 867 { 868 struct hdd_adapter *adapter; 869 struct hdd_context *hdd_ctx; 870 struct wlan_objmgr_vdev *vdev; 871 872 hdd_enter_dev(net_dev); 873 874 if (!net_dev->ieee80211_ptr) { 875 hdd_debug("ieee80211_ptr is null"); 876 return NOTIFY_DONE; 877 } 878 879 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 880 if (!hdd_ctx) 881 return NOTIFY_DONE; 882 883 if (hdd_ctx->driver_status == DRIVER_MODULES_CLOSED) { 884 hdd_debug("Driver module is closed"); 885 return NOTIFY_DONE; 886 } 887 888 /* Make sure that this callback corresponds to our device. */ 889 adapter = hdd_get_adapter_by_iface_name(hdd_ctx, net_dev->name); 890 if (!adapter) { 891 hdd_debug("failed to look up adapter for '%s'", net_dev->name); 892 return NOTIFY_DONE; 893 } 894 895 if (adapter != WLAN_HDD_GET_PRIV_PTR(net_dev)) { 896 hdd_err("HDD adapter mismatch!"); 897 return NOTIFY_DONE; 898 } 899 900 if (cds_is_driver_recovering()) { 901 hdd_debug("Driver is recovering"); 902 return NOTIFY_DONE; 903 } 904 905 if (cds_is_driver_in_bad_state()) { 906 hdd_debug("Driver is in failed recovery state"); 907 return NOTIFY_DONE; 908 } 909 910 hdd_debug("%s New Net Device State = %lu, flags 0x%x", 911 net_dev->name, state, net_dev->flags); 912 913 switch (state) { 914 case NETDEV_REGISTER: 915 break; 916 917 case NETDEV_UNREGISTER: 918 break; 919 920 case NETDEV_UP: 921 sme_ch_avoid_update_req(hdd_ctx->mac_handle); 922 break; 923 924 case NETDEV_DOWN: 925 break; 926 927 case NETDEV_CHANGE: 928 if (adapter->is_link_up_service_needed) 929 complete(&adapter->linkup_event_var); 930 break; 931 932 case NETDEV_GOING_DOWN: 933 vdev = hdd_objmgr_get_vdev_by_user(adapter->deflink, 934 WLAN_OSIF_SCAN_ID); 935 if (!vdev) 936 break; 937 if (ucfg_scan_get_vdev_status(vdev) != 938 SCAN_NOT_IN_PROGRESS) { 939 wlan_abort_scan(hdd_ctx->pdev, INVAL_PDEV_ID, 940 adapter->deflink->vdev_id, 941 INVALID_SCAN_ID, true); 942 } 943 hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_SCAN_ID); 944 cds_flush_work(&adapter->scan_block_work); 945 /* Need to clean up blocked scan request */ 946 wlan_hdd_cfg80211_scan_block(adapter); 947 hdd_debug("Scan is not Pending from user"); 948 /* 949 * After NETDEV_GOING_DOWN, kernel calls hdd_stop.Irrespective 950 * of return status of hdd_stop call, kernel resets the IFF_UP 951 * flag after which driver does not send the cfg80211_scan_done. 952 * Ensure to cleanup the scan queue in NETDEV_GOING_DOWN 953 */ 954 wlan_cfg80211_cleanup_scan_queue(hdd_ctx->pdev, net_dev); 955 break; 956 case NETDEV_FEAT_CHANGE: 957 hdd_debug("vdev %d netdev Feature 0x%llx\n", 958 adapter->deflink->vdev_id, net_dev->features); 959 break; 960 default: 961 break; 962 } 963 964 return NOTIFY_DONE; 965 } 966 hdd_netdev_notifier_bridge_intf(struct net_device * net_dev,unsigned long state)967 static int hdd_netdev_notifier_bridge_intf(struct net_device *net_dev, 968 unsigned long state) 969 { 970 struct hdd_adapter *adapter, *next_adapter = NULL; 971 wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_GET_ADAPTER; 972 struct hdd_context *hdd_ctx; 973 QDF_STATUS status; 974 975 hdd_enter_dev(net_dev); 976 977 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 978 if (wlan_hdd_validate_context(hdd_ctx)) 979 return NOTIFY_DONE; 980 981 hdd_debug("%s New Net Device State = %lu, flags 0x%x bridge mac address: "QDF_MAC_ADDR_FMT, 982 net_dev->name, state, net_dev->flags, QDF_MAC_ADDR_REF(net_dev->dev_addr)); 983 984 if (!qdf_mem_cmp(hdd_ctx->bridgeaddr, net_dev->dev_addr, 985 QDF_MAC_ADDR_SIZE)) 986 return NOTIFY_DONE; 987 988 switch (state) { 989 case NETDEV_REGISTER: 990 case NETDEV_CHANGEADDR: 991 /* Update FW WoW pattern with new MAC address */ 992 qdf_mem_copy(hdd_ctx->bridgeaddr, net_dev->dev_addr, 993 QDF_MAC_ADDR_SIZE); 994 995 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 996 dbgid) { 997 if (adapter->device_mode != QDF_SAP_MODE) 998 goto loop_next; 999 1000 if (wlan_hdd_validate_vdev_id(adapter->deflink->vdev_id)) 1001 goto loop_next; 1002 1003 status = wlan_objmgr_vdev_try_get_ref(adapter->deflink->vdev, 1004 WLAN_HDD_ID_OBJ_MGR); 1005 if (QDF_IS_STATUS_ERROR(status)) 1006 goto loop_next; 1007 1008 ucfg_pmo_set_vdev_bridge_addr(adapter->deflink->vdev, 1009 (struct qdf_mac_addr *)hdd_ctx->bridgeaddr); 1010 ucfg_pmo_del_wow_pattern(adapter->deflink->vdev); 1011 ucfg_pmo_register_wow_default_patterns(adapter->deflink->vdev); 1012 1013 wlan_objmgr_vdev_release_ref(adapter->deflink->vdev, 1014 WLAN_HDD_ID_OBJ_MGR); 1015 1016 loop_next: 1017 hdd_adapter_dev_put_debug(adapter, dbgid); 1018 } 1019 1020 break; 1021 case NETDEV_UNREGISTER: 1022 qdf_zero_macaddr((struct qdf_mac_addr *)hdd_ctx->bridgeaddr); 1023 break; 1024 default: 1025 break; 1026 } 1027 1028 return NOTIFY_DONE; 1029 } 1030 1031 /** 1032 * hdd_netdev_notifier_call() - netdev notifier callback function 1033 * @nb: pointer to notifier block 1034 * @state: state 1035 * @context: notifier callback context pointer 1036 * 1037 * Return: 0 on success, error number otherwise. 1038 */ hdd_netdev_notifier_call(struct notifier_block * nb,unsigned long state,void * context)1039 static int hdd_netdev_notifier_call(struct notifier_block *nb, 1040 unsigned long state, 1041 void *context) 1042 { 1043 struct net_device *net_dev = hdd_net_dev_from_notifier(context); 1044 struct osif_vdev_sync *vdev_sync; 1045 int errno; 1046 1047 if (net_dev->priv_flags & IFF_EBRIDGE) { 1048 errno = hdd_netdev_notifier_bridge_intf(net_dev, state); 1049 if (errno) 1050 return NOTIFY_DONE; 1051 } 1052 1053 errno = osif_vdev_sync_op_start(net_dev, &vdev_sync); 1054 if (errno) { 1055 hdd_debug("%s New Net Device State = %lu, flags 0x%x NOTIFY_DONE", 1056 net_dev->name, state, net_dev->flags); 1057 return NOTIFY_DONE; 1058 } 1059 1060 errno = __hdd_netdev_notifier_call(net_dev, state); 1061 1062 osif_vdev_sync_op_stop(vdev_sync); 1063 1064 return NOTIFY_DONE; 1065 } 1066 1067 struct notifier_block hdd_netdev_notifier = { 1068 .notifier_call = hdd_netdev_notifier_call, 1069 }; 1070 1071 /* variable to hold the insmod parameters */ 1072 int con_mode; 1073 #ifdef FEATURE_WLAN_RESIDENT_DRIVER 1074 EXPORT_SYMBOL(con_mode); 1075 #endif 1076 1077 int con_mode_ftm; 1078 #ifdef FEATURE_WLAN_RESIDENT_DRIVER 1079 EXPORT_SYMBOL(con_mode_ftm); 1080 #endif 1081 int con_mode_epping; 1082 1083 static int pcie_gen_speed; 1084 1085 /* Variable to hold connection mode including module parameter con_mode */ 1086 static int curr_con_mode; 1087 1088 #if defined(WLAN_FEATURE_11BE) && defined(CFG80211_11BE_BASIC) hdd_get_eht_phy_ch_width_from_target(void)1089 static enum phy_ch_width hdd_get_eht_phy_ch_width_from_target(void) 1090 { 1091 uint32_t max_fw_bw = sme_get_eht_ch_width(); 1092 1093 if (max_fw_bw == WNI_CFG_EHT_CHANNEL_WIDTH_320MHZ) 1094 return CH_WIDTH_320MHZ; 1095 else if (max_fw_bw == WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ) 1096 return CH_WIDTH_160MHZ; 1097 else 1098 return CH_WIDTH_80MHZ; 1099 } 1100 hdd_is_target_eht_phy_ch_width_supported(enum phy_ch_width width)1101 static bool hdd_is_target_eht_phy_ch_width_supported(enum phy_ch_width width) 1102 { 1103 enum phy_ch_width max_fw_bw = hdd_get_eht_phy_ch_width_from_target(); 1104 1105 if (width <= max_fw_bw) 1106 return true; 1107 1108 hdd_err("FW does not support this BW %d max BW supported %d", 1109 width, max_fw_bw); 1110 return false; 1111 } 1112 hdd_is_target_eht_160mhz_capable(void)1113 static bool hdd_is_target_eht_160mhz_capable(void) 1114 { 1115 return hdd_is_target_eht_phy_ch_width_supported(CH_WIDTH_160MHZ); 1116 } 1117 1118 static enum phy_ch_width wlan_hdd_map_nl_chan_width(enum nl80211_chan_width width)1119 wlan_hdd_map_nl_chan_width(enum nl80211_chan_width width) 1120 { 1121 if (width == NL80211_CHAN_WIDTH_320) { 1122 return hdd_get_eht_phy_ch_width_from_target(); 1123 } else { 1124 hdd_err("Invalid channel width %d, setting to default", width); 1125 return CH_WIDTH_INVALID; 1126 } 1127 } 1128 1129 #else /* !WLAN_FEATURE_11BE */ 1130 static inline bool hdd_is_target_eht_phy_ch_width_supported(enum phy_ch_width width)1131 hdd_is_target_eht_phy_ch_width_supported(enum phy_ch_width width) 1132 { 1133 return true; 1134 } 1135 hdd_is_target_eht_160mhz_capable(void)1136 static inline bool hdd_is_target_eht_160mhz_capable(void) 1137 { 1138 return false; 1139 } 1140 1141 static enum phy_ch_width wlan_hdd_map_nl_chan_width(enum nl80211_chan_width width)1142 wlan_hdd_map_nl_chan_width(enum nl80211_chan_width width) 1143 { 1144 hdd_err("Invalid channel width %d, setting to default", width); 1145 return CH_WIDTH_INVALID; 1146 } 1147 #endif /* WLAN_FEATURE_11BE */ 1148 1149 /** 1150 * hdd_map_nl_chan_width() - Map NL channel width to internal representation 1151 * @ch_width: NL channel width 1152 * 1153 * Converts the NL channel width to the driver's internal representation 1154 * 1155 * Return: Converted channel width. In case of non matching NL channel width, 1156 * CH_WIDTH_MAX will be returned. 1157 */ hdd_map_nl_chan_width(enum nl80211_chan_width ch_width)1158 enum phy_ch_width hdd_map_nl_chan_width(enum nl80211_chan_width ch_width) 1159 { 1160 uint8_t fw_ch_bw; 1161 1162 fw_ch_bw = wma_get_vht_ch_width(); 1163 switch (ch_width) { 1164 case NL80211_CHAN_WIDTH_20_NOHT: 1165 case NL80211_CHAN_WIDTH_20: 1166 return CH_WIDTH_20MHZ; 1167 case NL80211_CHAN_WIDTH_40: 1168 return CH_WIDTH_40MHZ; 1169 case NL80211_CHAN_WIDTH_80: 1170 return CH_WIDTH_80MHZ; 1171 case NL80211_CHAN_WIDTH_80P80: 1172 if (fw_ch_bw == WNI_CFG_VHT_CHANNEL_WIDTH_80_PLUS_80MHZ) 1173 return CH_WIDTH_80P80MHZ; 1174 else if (fw_ch_bw == WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ) 1175 return CH_WIDTH_160MHZ; 1176 else 1177 return CH_WIDTH_80MHZ; 1178 case NL80211_CHAN_WIDTH_160: 1179 if (hdd_is_target_eht_160mhz_capable()) 1180 return CH_WIDTH_160MHZ; 1181 1182 if (fw_ch_bw >= WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ) 1183 return CH_WIDTH_160MHZ; 1184 else 1185 return CH_WIDTH_80MHZ; 1186 case NL80211_CHAN_WIDTH_5: 1187 return CH_WIDTH_5MHZ; 1188 case NL80211_CHAN_WIDTH_10: 1189 return CH_WIDTH_10MHZ; 1190 default: 1191 return wlan_hdd_map_nl_chan_width(ch_width); 1192 } 1193 } 1194 1195 #if defined(WLAN_FEATURE_NAN) && \ 1196 (KERNEL_VERSION(4, 9, 0) <= LINUX_VERSION_CODE) 1197 /** 1198 * wlan_hdd_convert_nan_type() - Convert nl type to qdf type 1199 * @nl_type: NL80211 interface type 1200 * @out_qdf_type: QDF type for the given nl_type 1201 * 1202 * Convert nl type to QDF type 1203 * 1204 * Return: QDF_STATUS_SUCCESS if converted, failure otherwise. 1205 */ wlan_hdd_convert_nan_type(enum nl80211_iftype nl_type,enum QDF_OPMODE * out_qdf_type)1206 static QDF_STATUS wlan_hdd_convert_nan_type(enum nl80211_iftype nl_type, 1207 enum QDF_OPMODE *out_qdf_type) 1208 { 1209 if (nl_type == NL80211_IFTYPE_NAN) { 1210 *out_qdf_type = QDF_NAN_DISC_MODE; 1211 return QDF_STATUS_SUCCESS; 1212 } 1213 return QDF_STATUS_E_INVAL; 1214 } 1215 1216 /** 1217 * wlan_hdd_set_nan_if_type() - Set the NAN iftype 1218 * @adapter: pointer to HDD adapter 1219 * 1220 * Set the NL80211_IFTYPE_NAN to wdev iftype. 1221 * 1222 * Return: None 1223 */ wlan_hdd_set_nan_if_type(struct hdd_adapter * adapter)1224 static void wlan_hdd_set_nan_if_type(struct hdd_adapter *adapter) 1225 { 1226 adapter->wdev.iftype = NL80211_IFTYPE_NAN; 1227 } 1228 wlan_hdd_is_vdev_creation_allowed(struct wlan_objmgr_psoc * psoc)1229 static bool wlan_hdd_is_vdev_creation_allowed(struct wlan_objmgr_psoc *psoc) 1230 { 1231 return ucfg_nan_is_vdev_creation_allowed(psoc); 1232 } 1233 #else wlan_hdd_convert_nan_type(enum nl80211_iftype nl_type,enum QDF_OPMODE * out_qdf_type)1234 static QDF_STATUS wlan_hdd_convert_nan_type(enum nl80211_iftype nl_type, 1235 enum QDF_OPMODE *out_qdf_type) 1236 { 1237 return QDF_STATUS_E_INVAL; 1238 } 1239 wlan_hdd_set_nan_if_type(struct hdd_adapter * adapter)1240 static void wlan_hdd_set_nan_if_type(struct hdd_adapter *adapter) 1241 { 1242 } 1243 wlan_hdd_is_vdev_creation_allowed(struct wlan_objmgr_psoc * psoc)1244 static bool wlan_hdd_is_vdev_creation_allowed(struct wlan_objmgr_psoc *psoc) 1245 { 1246 return false; 1247 } 1248 #endif 1249 hdd_nl_to_qdf_iface_type(enum nl80211_iftype nl_type,enum QDF_OPMODE * out_qdf_type)1250 QDF_STATUS hdd_nl_to_qdf_iface_type(enum nl80211_iftype nl_type, 1251 enum QDF_OPMODE *out_qdf_type) 1252 { 1253 QDF_STATUS status = QDF_STATUS_SUCCESS; 1254 1255 switch (nl_type) { 1256 case NL80211_IFTYPE_AP: 1257 *out_qdf_type = QDF_SAP_MODE; 1258 break; 1259 case NL80211_IFTYPE_MONITOR: 1260 *out_qdf_type = QDF_MONITOR_MODE; 1261 break; 1262 case NL80211_IFTYPE_OCB: 1263 *out_qdf_type = QDF_OCB_MODE; 1264 break; 1265 case NL80211_IFTYPE_P2P_CLIENT: 1266 *out_qdf_type = QDF_P2P_CLIENT_MODE; 1267 break; 1268 case NL80211_IFTYPE_P2P_DEVICE: 1269 *out_qdf_type = QDF_P2P_DEVICE_MODE; 1270 break; 1271 case NL80211_IFTYPE_P2P_GO: 1272 *out_qdf_type = QDF_P2P_GO_MODE; 1273 break; 1274 case NL80211_IFTYPE_STATION: 1275 *out_qdf_type = QDF_STA_MODE; 1276 break; 1277 case NL80211_IFTYPE_WDS: 1278 *out_qdf_type = QDF_WDS_MODE; 1279 break; 1280 default: 1281 status = wlan_hdd_convert_nan_type(nl_type, out_qdf_type); 1282 if (QDF_IS_STATUS_SUCCESS(status)) 1283 break; 1284 hdd_err("Invalid nl80211 interface type %d", nl_type); 1285 return QDF_STATUS_E_INVAL; 1286 } 1287 1288 return QDF_STATUS_SUCCESS; 1289 } 1290 wlan_hdd_find_opclass(mac_handle_t mac_handle,uint8_t channel,uint8_t bw_offset)1291 uint8_t wlan_hdd_find_opclass(mac_handle_t mac_handle, uint8_t channel, 1292 uint8_t bw_offset) 1293 { 1294 uint8_t opclass = 0; 1295 1296 sme_get_opclass(mac_handle, channel, bw_offset, &opclass); 1297 return opclass; 1298 } 1299 1300 /** 1301 * hdd_qdf_trace_enable() - configure initial QDF Trace enable 1302 * @module_id: Module whose trace level is being configured 1303 * @bitmask: Bitmask of log levels to be enabled 1304 * 1305 * Called immediately after the cfg.ini is read in order to configure 1306 * the desired trace levels. 1307 * 1308 * Return: None 1309 */ hdd_qdf_trace_enable(QDF_MODULE_ID module_id,uint32_t bitmask)1310 int hdd_qdf_trace_enable(QDF_MODULE_ID module_id, uint32_t bitmask) 1311 { 1312 QDF_TRACE_LEVEL level; 1313 int qdf_print_idx = -1; 1314 int status = -1; 1315 /* 1316 * if the bitmask is the default value, then a bitmask was not 1317 * specified in cfg.ini, so leave the logging level alone (it 1318 * will remain at the "compiled in" default value) 1319 */ 1320 if (CFG_QDF_TRACE_ENABLE_DEFAULT == bitmask) 1321 return 0; 1322 1323 qdf_print_idx = qdf_get_pidx(); 1324 1325 /* a mask was specified. start by disabling all logging */ 1326 status = qdf_print_set_category_verbose(qdf_print_idx, module_id, 1327 QDF_TRACE_LEVEL_NONE, 0); 1328 1329 if (QDF_STATUS_SUCCESS != status) 1330 return -EINVAL; 1331 /* now cycle through the bitmask until all "set" bits are serviced */ 1332 level = QDF_TRACE_LEVEL_NONE; 1333 while (0 != bitmask) { 1334 if (bitmask & 1) { 1335 status = qdf_print_set_category_verbose(qdf_print_idx, 1336 module_id, level, 1); 1337 if (QDF_STATUS_SUCCESS != status) 1338 return -EINVAL; 1339 } 1340 1341 level++; 1342 bitmask >>= 1; 1343 } 1344 return 0; 1345 } 1346 __wlan_hdd_validate_context(struct hdd_context * hdd_ctx,const char * func)1347 int __wlan_hdd_validate_context(struct hdd_context *hdd_ctx, const char *func) 1348 { 1349 if (!hdd_ctx) { 1350 hdd_err("HDD context is null (via %s)", func); 1351 return -ENODEV; 1352 } 1353 1354 if (!hdd_ctx->config) { 1355 hdd_err("HDD config is null (via %s)", func); 1356 return -ENODEV; 1357 } 1358 1359 if (cds_is_driver_recovering()) { 1360 hdd_debug("Recovery in progress (via %s); state:0x%x", 1361 func, cds_get_driver_state()); 1362 return -EAGAIN; 1363 } 1364 1365 if (cds_is_load_or_unload_in_progress()) { 1366 hdd_debug("Load/unload in progress (via %s); state:0x%x", 1367 func, cds_get_driver_state()); 1368 return -EAGAIN; 1369 } 1370 1371 if (cds_is_driver_in_bad_state()) { 1372 hdd_debug("Driver in bad state (via %s); state:0x%x", 1373 func, cds_get_driver_state()); 1374 return -EAGAIN; 1375 } 1376 1377 if (cds_is_fw_down()) { 1378 hdd_debug("FW is down (via %s); state:0x%x", 1379 func, cds_get_driver_state()); 1380 return -EAGAIN; 1381 } 1382 1383 if (hdd_ctx->is_wlan_disabled) { 1384 hdd_debug("WLAN is disabled by user space"); 1385 return -EAGAIN; 1386 } 1387 1388 return 0; 1389 } 1390 __hdd_validate_adapter(struct hdd_adapter * adapter,const char * func)1391 int __hdd_validate_adapter(struct hdd_adapter *adapter, const char *func) 1392 { 1393 if (!adapter) { 1394 hdd_err("adapter is null (via %s)", func); 1395 return -EINVAL; 1396 } 1397 1398 if (adapter->magic != WLAN_HDD_ADAPTER_MAGIC) { 1399 hdd_err("bad adapter magic (via %s)", func); 1400 return -EINVAL; 1401 } 1402 1403 if (!adapter->dev) { 1404 hdd_err("adapter net_device is null (via %s)", func); 1405 return -EINVAL; 1406 } 1407 1408 if (!(adapter->dev->flags & IFF_UP)) { 1409 hdd_debug_rl("adapter '%s' is not up (via %s)", 1410 adapter->dev->name, func); 1411 return -EAGAIN; 1412 } 1413 1414 return __wlan_hdd_validate_vdev_id(adapter->deflink->vdev_id, func); 1415 } 1416 __wlan_hdd_validate_vdev_id(uint8_t vdev_id,const char * func)1417 int __wlan_hdd_validate_vdev_id(uint8_t vdev_id, const char *func) 1418 { 1419 if (vdev_id == WLAN_UMAC_VDEV_ID_MAX) { 1420 hdd_debug_rl("adapter is not up (via %s)", func); 1421 return -EINVAL; 1422 } 1423 1424 if (vdev_id >= WLAN_MAX_VDEVS) { 1425 hdd_err("bad vdev Id:%u (via %s)", vdev_id, func); 1426 return -EINVAL; 1427 } 1428 1429 return 0; 1430 } 1431 __wlan_hdd_validate_mac_address(struct qdf_mac_addr * mac_addr,const char * func)1432 QDF_STATUS __wlan_hdd_validate_mac_address(struct qdf_mac_addr *mac_addr, 1433 const char *func) 1434 { 1435 if (!mac_addr) { 1436 hdd_err("Received NULL mac address (via %s)", func); 1437 return QDF_STATUS_E_INVAL; 1438 } 1439 1440 if (qdf_is_macaddr_zero(mac_addr)) { 1441 hdd_err("MAC is all zero (via %s)", func); 1442 return QDF_STATUS_E_INVAL; 1443 } 1444 1445 if (qdf_is_macaddr_broadcast(mac_addr)) { 1446 hdd_err("MAC is Broadcast (via %s)", func); 1447 return QDF_STATUS_E_INVAL; 1448 } 1449 1450 if (QDF_NET_IS_MAC_MULTICAST(mac_addr->bytes)) { 1451 hdd_err("MAC is Multicast (via %s)", func); 1452 return QDF_STATUS_E_INVAL; 1453 } 1454 1455 return QDF_STATUS_SUCCESS; 1456 } 1457 1458 /** 1459 * wlan_hdd_validate_modules_state() - Check modules status 1460 * @hdd_ctx: HDD context pointer 1461 * 1462 * Check's the driver module's state and returns true if the 1463 * modules are enabled returns false if modules are closed. 1464 * 1465 * Return: True if modules are enabled or false. 1466 */ wlan_hdd_validate_modules_state(struct hdd_context * hdd_ctx)1467 bool wlan_hdd_validate_modules_state(struct hdd_context *hdd_ctx) 1468 { 1469 if (hdd_ctx->driver_status != DRIVER_MODULES_ENABLED) { 1470 hdd_info("Modules not enabled, Present status: %d", 1471 hdd_ctx->driver_status); 1472 return false; 1473 } 1474 1475 return true; 1476 } 1477 1478 #ifdef FEATURE_RUNTIME_PM 1479 /** 1480 * hdd_runtime_suspend_context_init() - API to initialize HDD Runtime Contexts 1481 * @hdd_ctx: HDD context 1482 * 1483 * Return: None 1484 */ hdd_runtime_suspend_context_init(struct hdd_context * hdd_ctx)1485 static void hdd_runtime_suspend_context_init(struct hdd_context *hdd_ctx) 1486 { 1487 struct hdd_runtime_pm_context *ctx = &hdd_ctx->runtime_context; 1488 1489 qdf_runtime_lock_init(&ctx->dfs); 1490 qdf_runtime_lock_init(&ctx->connect); 1491 qdf_runtime_lock_init(&ctx->user); 1492 qdf_runtime_lock_init(&ctx->monitor_mode); 1493 qdf_runtime_lock_init(&ctx->wow_unit_test); 1494 qdf_runtime_lock_init(&ctx->system_suspend); 1495 qdf_runtime_lock_init(&ctx->dyn_mac_addr_update); 1496 qdf_runtime_lock_init(&ctx->vdev_destroy); 1497 qdf_runtime_lock_init(&ctx->oem_data_cmd); 1498 1499 qdf_rtpm_register(QDF_RTPM_ID_WIPHY_SUSPEND, NULL); 1500 qdf_rtpm_register(QDF_RTPM_ID_PM_QOS_NOTIFY, NULL); 1501 1502 ctx->is_user_wakelock_acquired = false; 1503 1504 wlan_scan_runtime_pm_init(hdd_ctx->pdev); 1505 } 1506 1507 /** 1508 * hdd_runtime_suspend_context_deinit() - API to deinit HDD runtime context 1509 * @hdd_ctx: HDD Context 1510 * 1511 * Return: None 1512 */ hdd_runtime_suspend_context_deinit(struct hdd_context * hdd_ctx)1513 static void hdd_runtime_suspend_context_deinit(struct hdd_context *hdd_ctx) 1514 { 1515 struct hdd_runtime_pm_context *ctx = &hdd_ctx->runtime_context; 1516 1517 if (ctx->is_user_wakelock_acquired) 1518 qdf_runtime_pm_allow_suspend(&ctx->user); 1519 1520 qdf_runtime_lock_deinit(&ctx->oem_data_cmd); 1521 qdf_runtime_lock_deinit(&ctx->dyn_mac_addr_update); 1522 qdf_runtime_lock_deinit(&ctx->wow_unit_test); 1523 qdf_runtime_lock_deinit(&ctx->monitor_mode); 1524 qdf_runtime_lock_deinit(&ctx->user); 1525 qdf_runtime_lock_deinit(&ctx->connect); 1526 qdf_runtime_lock_deinit(&ctx->dfs); 1527 qdf_runtime_lock_deinit(&ctx->system_suspend); 1528 qdf_runtime_lock_deinit(&ctx->vdev_destroy); 1529 1530 qdf_rtpm_deregister(QDF_RTPM_ID_WIPHY_SUSPEND); 1531 qdf_rtpm_deregister(QDF_RTPM_ID_PM_QOS_NOTIFY); 1532 1533 wlan_scan_runtime_pm_deinit(hdd_ctx->pdev); 1534 } 1535 1536 #else /* FEATURE_RUNTIME_PM */ hdd_runtime_suspend_context_init(struct hdd_context * hdd_ctx)1537 static void hdd_runtime_suspend_context_init(struct hdd_context *hdd_ctx) {} hdd_runtime_suspend_context_deinit(struct hdd_context * hdd_ctx)1538 static void hdd_runtime_suspend_context_deinit(struct hdd_context *hdd_ctx) {} 1539 #endif /* FEATURE_RUNTIME_PM */ 1540 hdd_update_macaddr(struct hdd_context * hdd_ctx,struct qdf_mac_addr hw_macaddr,bool generate_mac_auto)1541 void hdd_update_macaddr(struct hdd_context *hdd_ctx, 1542 struct qdf_mac_addr hw_macaddr, bool generate_mac_auto) 1543 { 1544 int8_t i; 1545 uint8_t macaddr_b3, tmp_br3; 1546 1547 /* 1548 * If "generate_mac_auto" is true, it indicates that all the 1549 * addresses are derived addresses, else the first addresses 1550 * is not derived address (It is provided by fw). 1551 */ 1552 if (!generate_mac_auto) { 1553 qdf_mem_copy(hdd_ctx->provisioned_mac_addr[0].bytes, 1554 hw_macaddr.bytes, QDF_MAC_ADDR_SIZE); 1555 hdd_ctx->num_provisioned_addr++; 1556 hdd_debug("hdd_ctx->provisioned_mac_addr[0]: " 1557 QDF_MAC_ADDR_FMT, 1558 QDF_MAC_ADDR_REF(hdd_ctx-> 1559 provisioned_mac_addr[0].bytes)); 1560 } else { 1561 qdf_mem_copy(hdd_ctx->derived_mac_addr[0].bytes, 1562 hw_macaddr.bytes, 1563 QDF_MAC_ADDR_SIZE); 1564 hdd_ctx->num_derived_addr++; 1565 hdd_debug("hdd_ctx->derived_mac_addr[0]: " 1566 QDF_MAC_ADDR_FMT, 1567 QDF_MAC_ADDR_REF(hdd_ctx->derived_mac_addr[0].bytes)); 1568 } 1569 for (i = hdd_ctx->num_derived_addr; i < (QDF_MAX_CONCURRENCY_PERSONA - 1570 hdd_ctx->num_provisioned_addr); 1571 i++) { 1572 qdf_mem_copy(hdd_ctx->derived_mac_addr[i].bytes, 1573 hw_macaddr.bytes, 1574 QDF_MAC_ADDR_SIZE); 1575 macaddr_b3 = hdd_ctx->derived_mac_addr[i].bytes[3]; 1576 tmp_br3 = ((macaddr_b3 >> 4 & INTF_MACADDR_MASK) + i) & 1577 INTF_MACADDR_MASK; 1578 macaddr_b3 += tmp_br3; 1579 1580 /* XOR-ing bit-24 of the mac address. This will give enough 1581 * mac address range before collision 1582 */ 1583 macaddr_b3 ^= (1 << 7); 1584 1585 /* Set locally administered bit */ 1586 hdd_ctx->derived_mac_addr[i].bytes[0] |= 0x02; 1587 hdd_ctx->derived_mac_addr[i].bytes[3] = macaddr_b3; 1588 hdd_debug("hdd_ctx->derived_mac_addr[%d]: " 1589 QDF_MAC_ADDR_FMT, i, 1590 QDF_MAC_ADDR_REF(hdd_ctx->derived_mac_addr[i].bytes)); 1591 hdd_ctx->num_derived_addr++; 1592 } 1593 } 1594 1595 #ifdef FEATURE_WLAN_TDLS hdd_update_tdls_config(struct hdd_context * hdd_ctx)1596 static int hdd_update_tdls_config(struct hdd_context *hdd_ctx) 1597 { 1598 struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc; 1599 struct tdls_start_params tdls_cfg; 1600 QDF_STATUS status; 1601 struct wlan_mlme_nss_chains vdev_ini_cfg; 1602 1603 /* Populate the nss chain params from ini for this vdev type */ 1604 sme_populate_nss_chain_params(hdd_ctx->mac_handle, &vdev_ini_cfg, 1605 QDF_TDLS_MODE, 1606 hdd_ctx->num_rf_chains); 1607 1608 cfg_tdls_set_vdev_nss_2g(hdd_ctx->psoc, 1609 vdev_ini_cfg.rx_nss[NSS_CHAINS_BAND_2GHZ]); 1610 cfg_tdls_set_vdev_nss_5g(hdd_ctx->psoc, 1611 vdev_ini_cfg.rx_nss[NSS_CHAINS_BAND_5GHZ]); 1612 hdd_init_tdls_config(&tdls_cfg); 1613 tdls_cfg.tdls_del_all_peers = eWNI_SME_DEL_ALL_TDLS_PEERS; 1614 tdls_cfg.tdls_update_dp_vdev_flags = CDP_UPDATE_TDLS_FLAGS; 1615 tdls_cfg.tdls_event_cb = wlan_cfg80211_tdls_event_callback; 1616 tdls_cfg.tdls_evt_cb_data = psoc; 1617 tdls_cfg.tdls_peer_context = hdd_ctx; 1618 tdls_cfg.tdls_reg_peer = hdd_tdls_register_peer; 1619 tdls_cfg.tdls_wmm_cb = hdd_wmm_is_acm_allowed; 1620 tdls_cfg.tdls_wmm_cb_data = psoc; 1621 tdls_cfg.tdls_rx_cb = wlan_cfg80211_tdls_rx_callback; 1622 tdls_cfg.tdls_rx_cb_data = psoc; 1623 tdls_cfg.tdls_dp_vdev_update = hdd_update_dp_vdev_flags; 1624 tdls_cfg.tdls_osif_init_cb = wlan_cfg80211_tdls_osif_priv_init; 1625 tdls_cfg.tdls_osif_deinit_cb = wlan_cfg80211_tdls_osif_priv_deinit; 1626 tdls_cfg.tdls_osif_update_cb.tdls_osif_conn_update = 1627 hdd_check_and_set_tdls_conn_params; 1628 tdls_cfg.tdls_osif_update_cb.tdls_osif_disconn_update = 1629 hdd_check_and_set_tdls_disconn_params; 1630 1631 status = ucfg_tdls_update_config(psoc, &tdls_cfg); 1632 if (status != QDF_STATUS_SUCCESS) { 1633 hdd_err("failed pmo psoc configuration"); 1634 return -EINVAL; 1635 } 1636 1637 hdd_ctx->tdls_umac_comp_active = true; 1638 /* enable napier specific tdls data path */ 1639 hdd_ctx->tdls_nap_active = true; 1640 1641 return 0; 1642 } 1643 #else hdd_update_tdls_config(struct hdd_context * hdd_ctx)1644 static int hdd_update_tdls_config(struct hdd_context *hdd_ctx) 1645 { 1646 return 0; 1647 } 1648 #endif 1649 hdd_indicate_active_ndp_cnt(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id,uint8_t cnt)1650 void hdd_indicate_active_ndp_cnt(struct wlan_objmgr_psoc *psoc, 1651 uint8_t vdev_id, uint8_t cnt) 1652 { 1653 struct wlan_hdd_link_info *link_info; 1654 1655 link_info = wlan_hdd_get_link_info_from_vdev(psoc, vdev_id); 1656 if (!link_info || !cfg_nan_is_roam_config_disabled(psoc)) 1657 return; 1658 1659 hdd_debug("vdev_id:%d%s active ndp sessions present", vdev_id, 1660 cnt ? "" : " no more"); 1661 if (!cnt) 1662 wlan_hdd_set_roaming_state(link_info, RSO_NDP_CON_ON_NDI, true); 1663 else 1664 wlan_hdd_set_roaming_state(link_info, RSO_NDP_CON_ON_NDI, 1665 false); 1666 } 1667 1668 #ifdef WLAN_FEATURE_ROAM_OFFLOAD hdd_update_roam_offload(struct hdd_context * hdd_ctx,struct wma_tgt_services * cfg)1669 static void hdd_update_roam_offload(struct hdd_context *hdd_ctx, 1670 struct wma_tgt_services *cfg) 1671 { 1672 bool roam_offload_enable; 1673 1674 ucfg_mlme_get_roaming_offload(hdd_ctx->psoc, &roam_offload_enable); 1675 ucfg_mlme_set_roaming_offload(hdd_ctx->psoc, 1676 roam_offload_enable & 1677 cfg->en_roam_offload); 1678 } 1679 #else hdd_update_roam_offload(struct hdd_context * hdd_ctx,struct wma_tgt_services * cfg)1680 static inline void hdd_update_roam_offload(struct hdd_context *hdd_ctx, 1681 struct wma_tgt_services *cfg) 1682 { 1683 } 1684 #endif 1685 1686 #ifdef FEATURE_CLUB_LL_STATS_AND_GET_STATION 1687 static void hdd_club_ll_stats_in_get_sta_cfg_update(struct hdd_config * config,struct wlan_objmgr_psoc * psoc)1688 hdd_club_ll_stats_in_get_sta_cfg_update(struct hdd_config *config, 1689 struct wlan_objmgr_psoc *psoc) 1690 { 1691 config->sta_stats_cache_expiry_time = 1692 cfg_get(psoc, CFG_STA_STATS_CACHE_EXPIRY); 1693 } 1694 1695 static void hdd_update_feature_cfg_club_get_sta_in_ll_stats_req(struct hdd_context * hdd_ctx,struct wma_tgt_services * cfg)1696 hdd_update_feature_cfg_club_get_sta_in_ll_stats_req( 1697 struct hdd_context *hdd_ctx, 1698 struct wma_tgt_services *cfg) 1699 { 1700 hdd_ctx->is_get_station_clubbed_in_ll_stats_req = 1701 cfg->is_get_station_clubbed_in_ll_stats_req && 1702 cfg_get(hdd_ctx->psoc, 1703 CFG_CLUB_LL_STA_AND_GET_STATION); 1704 } 1705 1706 static void hdd_init_get_sta_in_ll_stats_config(struct hdd_adapter * adapter)1707 hdd_init_get_sta_in_ll_stats_config(struct hdd_adapter *adapter) 1708 { 1709 adapter->sta_stats_cached_timestamp = 0; 1710 } 1711 #else 1712 static void hdd_club_ll_stats_in_get_sta_cfg_update(struct hdd_config * config,struct wlan_objmgr_psoc * psoc)1713 hdd_club_ll_stats_in_get_sta_cfg_update(struct hdd_config *config, 1714 struct wlan_objmgr_psoc *psoc) 1715 { 1716 } 1717 1718 static void hdd_update_feature_cfg_club_get_sta_in_ll_stats_req(struct hdd_context * hdd_ctx,struct wma_tgt_services * cfg)1719 hdd_update_feature_cfg_club_get_sta_in_ll_stats_req( 1720 struct hdd_context *hdd_ctx, 1721 struct wma_tgt_services *cfg) 1722 { 1723 } 1724 1725 static void hdd_init_get_sta_in_ll_stats_config(struct hdd_adapter * adapter)1726 hdd_init_get_sta_in_ll_stats_config(struct hdd_adapter *adapter) 1727 { 1728 } 1729 #endif /* FEATURE_CLUB_LL_STATS_AND_GET_STATION */ 1730 1731 #ifdef WLAN_FEATURE_11BE_MLO 1732 1733 static void hdd_init_link_state_cfg(struct hdd_config * config,struct wlan_objmgr_psoc * psoc)1734 hdd_init_link_state_cfg(struct hdd_config *config, 1735 struct wlan_objmgr_psoc *psoc) 1736 { 1737 config->link_state_cache_expiry_time = 1738 cfg_get(psoc, CFG_LINK_STATE_CACHE_EXPIRY); 1739 } 1740 1741 static void hdd_init_link_state_config(struct hdd_adapter * adapter)1742 hdd_init_link_state_config(struct hdd_adapter *adapter) 1743 { 1744 adapter->link_state_cached_timestamp = 0; 1745 } 1746 1747 #else 1748 static void hdd_init_link_state_cfg(struct hdd_config * config,struct wlan_objmgr_psoc * psoc)1749 hdd_init_link_state_cfg(struct hdd_config *config, 1750 struct wlan_objmgr_psoc *psoc) 1751 { 1752 } 1753 1754 static void hdd_init_link_state_config(struct hdd_adapter * adapter)1755 hdd_init_link_state_config(struct hdd_adapter *adapter) 1756 { 1757 } 1758 #endif /* WLAN_FEATURE_11BE_MLO */ 1759 1760 #ifdef WLAN_FEATURE_IGMP_OFFLOAD 1761 static void hdd_intersect_igmp_offload_setting(struct wlan_objmgr_psoc * psoc,struct wma_tgt_services * cfg)1762 hdd_intersect_igmp_offload_setting(struct wlan_objmgr_psoc *psoc, 1763 struct wma_tgt_services *cfg) 1764 { 1765 bool igmp_offload_enable; 1766 1767 igmp_offload_enable = 1768 ucfg_pmo_is_igmp_offload_enabled(psoc); 1769 ucfg_pmo_set_igmp_offload_enabled(psoc, 1770 igmp_offload_enable & 1771 cfg->igmp_offload_enable); 1772 hdd_info("fw cap to handle igmp %d igmp_offload_enable ini %d", 1773 cfg->igmp_offload_enable, igmp_offload_enable); 1774 } 1775 #else 1776 static inline void hdd_intersect_igmp_offload_setting(struct wlan_objmgr_psoc * psoc,struct wma_tgt_services * cfg)1777 hdd_intersect_igmp_offload_setting(struct wlan_objmgr_psoc *psoc, 1778 struct wma_tgt_services *cfg) 1779 {} 1780 #endif 1781 1782 #ifdef FEATURE_WLAN_TDLS hdd_update_fw_tdls_wideband_capability(struct hdd_context * hdd_ctx,struct wma_tgt_services * cfg)1783 static void hdd_update_fw_tdls_wideband_capability(struct hdd_context *hdd_ctx, 1784 struct wma_tgt_services *cfg) 1785 { 1786 ucfg_tdls_update_fw_wideband_capability(hdd_ctx->psoc, 1787 cfg->en_tdls_wideband_support); 1788 } 1789 1790 #ifdef WLAN_FEATURE_11BE hdd_update_fw_tdls_mlo_capability(struct hdd_context * hdd_ctx,struct wma_tgt_services * cfg)1791 static void hdd_update_fw_tdls_mlo_capability(struct hdd_context *hdd_ctx, 1792 struct wma_tgt_services *cfg) 1793 { 1794 ucfg_tdls_update_fw_mlo_capability(hdd_ctx->psoc, 1795 cfg->en_tdls_mlo_support); 1796 } 1797 #else 1798 static inline hdd_update_fw_tdls_mlo_capability(struct hdd_context * hdd_ctx,struct wma_tgt_services * cfg)1799 void hdd_update_fw_tdls_mlo_capability(struct hdd_context *hdd_ctx, 1800 struct wma_tgt_services *cfg) 1801 {} 1802 #endif 1803 1804 #ifdef WLAN_FEATURE_11AX hdd_update_fw_tdls_11ax_capability(struct hdd_context * hdd_ctx,struct wma_tgt_services * cfg)1805 static void hdd_update_fw_tdls_11ax_capability(struct hdd_context *hdd_ctx, 1806 struct wma_tgt_services *cfg) 1807 { 1808 ucfg_tdls_update_fw_11ax_capability(hdd_ctx->psoc, 1809 cfg->en_tdls_11ax_support); 1810 } 1811 hdd_update_fw_tdls_6g_capability(struct hdd_context * hdd_ctx,struct wma_tgt_services * cfg)1812 static void hdd_update_fw_tdls_6g_capability(struct hdd_context *hdd_ctx, 1813 struct wma_tgt_services *cfg) 1814 { 1815 ucfg_update_fw_tdls_6g_capability(hdd_ctx->psoc, 1816 cfg->en_tdls_6g_support); 1817 } 1818 1819 #else 1820 static inline hdd_update_fw_tdls_11ax_capability(struct hdd_context * hdd_ctx,struct wma_tgt_services * cfg)1821 void hdd_update_fw_tdls_11ax_capability(struct hdd_context *hdd_ctx, 1822 struct wma_tgt_services *cfg) 1823 {} 1824 static inline hdd_update_fw_tdls_6g_capability(struct hdd_context * hdd_ctx,struct wma_tgt_services * cfg)1825 void hdd_update_fw_tdls_6g_capability(struct hdd_context *hdd_ctx, 1826 struct wma_tgt_services *cfg) 1827 {} 1828 #endif 1829 #else 1830 static inline hdd_update_fw_tdls_mlo_capability(struct hdd_context * hdd_ctx,struct wma_tgt_services * cfg)1831 void hdd_update_fw_tdls_mlo_capability(struct hdd_context *hdd_ctx, 1832 struct wma_tgt_services *cfg) 1833 {} 1834 1835 static inline hdd_update_fw_tdls_11ax_capability(struct hdd_context * hdd_ctx,struct wma_tgt_services * cfg)1836 void hdd_update_fw_tdls_11ax_capability(struct hdd_context *hdd_ctx, 1837 struct wma_tgt_services *cfg) 1838 {} 1839 1840 static inline hdd_update_fw_tdls_6g_capability(struct hdd_context * hdd_ctx,struct wma_tgt_services * cfg)1841 void hdd_update_fw_tdls_6g_capability(struct hdd_context *hdd_ctx, 1842 struct wma_tgt_services *cfg) 1843 {} 1844 1845 static inline hdd_update_fw_tdls_wideband_capability(struct hdd_context * hdd_ctx,struct wma_tgt_services * cfg)1846 void hdd_update_fw_tdls_wideband_capability(struct hdd_context *hdd_ctx, 1847 struct wma_tgt_services *cfg) 1848 {} 1849 #endif 1850 1851 #ifdef WLAN_FEATURE_DYNAMIC_MAC_ADDR_UPDATE 1852 static inline void hdd_set_dynamic_macaddr_update_capability(struct hdd_context * hdd_ctx,struct wma_tgt_services * cfg)1853 hdd_set_dynamic_macaddr_update_capability(struct hdd_context *hdd_ctx, 1854 struct wma_tgt_services *cfg) 1855 { 1856 hdd_ctx->is_vdev_macaddr_dynamic_update_supported = 1857 cfg->dynamic_vdev_macaddr_support && 1858 cfg_get(hdd_ctx->psoc, 1859 CFG_DYNAMIC_MAC_ADDR_UPDATE_SUPPORTED); 1860 } 1861 #else 1862 static inline void hdd_set_dynamic_macaddr_update_capability(struct hdd_context * hdd_ctx,struct wma_tgt_services * cfg)1863 hdd_set_dynamic_macaddr_update_capability(struct hdd_context *hdd_ctx, 1864 struct wma_tgt_services *cfg) 1865 { 1866 } 1867 #endif 1868 1869 #ifdef WLAN_FEATURE_11BE hdd_dot11Mode_support_11be(enum hdd_dot11_mode dot11Mode)1870 static bool hdd_dot11Mode_support_11be(enum hdd_dot11_mode dot11Mode) 1871 { 1872 if (dot11Mode != eHDD_DOT11_MODE_AUTO && 1873 dot11Mode < eHDD_DOT11_MODE_11be) 1874 return false; 1875 1876 return true; 1877 } 1878 1879 static void hdd_update_tid_to_link_supported(struct hdd_context * hdd_ctx,struct wma_tgt_services * cfg)1880 hdd_update_tid_to_link_supported(struct hdd_context *hdd_ctx, 1881 struct wma_tgt_services *cfg) 1882 { 1883 if (!cfg->en_mlo_tid_to_link_support) 1884 ucfg_mlme_set_t2lm_negotiation_supported(hdd_ctx->psoc, 1885 T2LM_NEGOTIATION_DISABLED); 1886 } 1887 1888 #else hdd_dot11Mode_support_11be(enum hdd_dot11_mode dot11Mode)1889 static bool hdd_dot11Mode_support_11be(enum hdd_dot11_mode dot11Mode) 1890 { 1891 return false; 1892 } 1893 1894 static inline void hdd_update_tid_to_link_supported(struct hdd_context * hdd_ctx,struct wma_tgt_services * cfg)1895 hdd_update_tid_to_link_supported(struct hdd_context *hdd_ctx, 1896 struct wma_tgt_services *cfg) 1897 { 1898 } 1899 #endif 1900 1901 #ifdef WLAN_FEATURE_11BE_MLO 1902 static void hdd_update_mlo_per_link_stats_capability(struct hdd_context * hdd_ctx,struct wma_tgt_services * cfg)1903 hdd_update_mlo_per_link_stats_capability(struct hdd_context *hdd_ctx, 1904 struct wma_tgt_services *cfg) 1905 { 1906 hdd_ctx->is_mlo_per_link_stats_supported = 1907 cfg->is_mlo_per_link_stats_supported; 1908 } 1909 #else 1910 static void hdd_update_mlo_per_link_stats_capability(struct hdd_context * hdd_ctx,struct wma_tgt_services * cfg)1911 hdd_update_mlo_per_link_stats_capability(struct hdd_context *hdd_ctx, 1912 struct wma_tgt_services *cfg) 1913 { 1914 } 1915 #endif 1916 hdd_update_tgt_services(struct hdd_context * hdd_ctx,struct wma_tgt_services * cfg)1917 static void hdd_update_tgt_services(struct hdd_context *hdd_ctx, 1918 struct wma_tgt_services *cfg) 1919 { 1920 struct hdd_config *config = hdd_ctx->config; 1921 bool arp_offload_enable; 1922 bool mawc_enabled; 1923 #ifdef FEATURE_WLAN_TDLS 1924 bool tdls_support; 1925 bool tdls_off_channel; 1926 bool tdls_buffer_sta; 1927 uint32_t tdls_uapsd_mask; 1928 #endif 1929 bool get_peer_info_enable; 1930 1931 /* Set up UAPSD */ 1932 ucfg_mlme_set_sap_uapsd_flag(hdd_ctx->psoc, cfg->uapsd); 1933 1934 /* 11AX mode support */ 1935 if ((config->dot11Mode == eHDD_DOT11_MODE_11ax || 1936 config->dot11Mode == eHDD_DOT11_MODE_11ax_ONLY) && !cfg->en_11ax) 1937 config->dot11Mode = eHDD_DOT11_MODE_11ac; 1938 1939 /* 11AC mode support */ 1940 if ((config->dot11Mode == eHDD_DOT11_MODE_11ac || 1941 config->dot11Mode == eHDD_DOT11_MODE_11ac_ONLY) && !cfg->en_11ac) 1942 config->dot11Mode = eHDD_DOT11_MODE_AUTO; 1943 1944 /* 11BE mode support */ 1945 if (cfg->en_11be && 1946 (!hdd_dot11Mode_support_11be(config->dot11Mode) || 1947 !wlan_reg_phybitmap_support_11be(hdd_ctx->pdev))) { 1948 hdd_debug("dot11Mode %d override target en_11be to false", 1949 config->dot11Mode); 1950 cfg->en_11be = false; 1951 } 1952 1953 /* ARP offload: override user setting if invalid */ 1954 arp_offload_enable = 1955 ucfg_pmo_is_arp_offload_enabled(hdd_ctx->psoc); 1956 ucfg_pmo_set_arp_offload_enabled(hdd_ctx->psoc, 1957 arp_offload_enable & cfg->arp_offload); 1958 1959 /* Intersect igmp offload ini configuration and fw cap*/ 1960 hdd_intersect_igmp_offload_setting(hdd_ctx->psoc, cfg); 1961 1962 #ifdef FEATURE_WLAN_SCAN_PNO 1963 /* PNO offload */ 1964 hdd_debug("PNO Capability in f/w = %d", cfg->pno_offload); 1965 if (cfg->pno_offload) 1966 ucfg_scan_set_pno_offload(hdd_ctx->psoc, true); 1967 #endif 1968 #ifdef FEATURE_WLAN_TDLS 1969 cfg_tdls_get_support_enable(hdd_ctx->psoc, &tdls_support); 1970 cfg_tdls_set_support_enable(hdd_ctx->psoc, 1971 tdls_support & cfg->en_tdls); 1972 1973 cfg_tdls_get_off_channel_enable(hdd_ctx->psoc, &tdls_off_channel); 1974 cfg_tdls_set_off_channel_enable(hdd_ctx->psoc, 1975 tdls_off_channel && 1976 cfg->en_tdls_offchan); 1977 1978 cfg_tdls_get_buffer_sta_enable(hdd_ctx->psoc, &tdls_buffer_sta); 1979 cfg_tdls_set_buffer_sta_enable(hdd_ctx->psoc, 1980 tdls_buffer_sta && 1981 cfg->en_tdls_uapsd_buf_sta); 1982 1983 cfg_tdls_get_uapsd_mask(hdd_ctx->psoc, &tdls_uapsd_mask); 1984 if (tdls_uapsd_mask && cfg->en_tdls_uapsd_sleep_sta) 1985 cfg_tdls_set_sleep_sta_enable(hdd_ctx->psoc, true); 1986 else 1987 cfg_tdls_set_sleep_sta_enable(hdd_ctx->psoc, false); 1988 #endif 1989 hdd_update_roam_offload(hdd_ctx, cfg); 1990 1991 if (ucfg_mlme_get_sap_get_peer_info( 1992 hdd_ctx->psoc, &get_peer_info_enable) == QDF_STATUS_SUCCESS) { 1993 get_peer_info_enable &= cfg->get_peer_info_enabled; 1994 ucfg_mlme_set_sap_get_peer_info(hdd_ctx->psoc, 1995 get_peer_info_enable); 1996 } 1997 1998 ucfg_mlme_is_mawc_enabled(hdd_ctx->psoc, &mawc_enabled); 1999 ucfg_mlme_set_mawc_enabled(hdd_ctx->psoc, 2000 mawc_enabled & cfg->is_fw_mawc_capable); 2001 hdd_update_tdls_config(hdd_ctx); 2002 sme_update_tgt_services(hdd_ctx->mac_handle, cfg); 2003 hdd_ctx->roam_ch_from_fw_supported = cfg->is_roam_scan_ch_to_host; 2004 hdd_ctx->ll_stats_per_chan_rx_tx_time = 2005 cfg->ll_stats_per_chan_rx_tx_time; 2006 2007 hdd_update_feature_cfg_club_get_sta_in_ll_stats_req(hdd_ctx, cfg); 2008 hdd_ctx->is_therm_cmd_supp = 2009 cfg->is_fw_therm_throt_supp && 2010 cfg_get(hdd_ctx->psoc, 2011 CFG_THERMAL_MITIGATION_ENABLE); 2012 hdd_update_fw_tdls_11ax_capability(hdd_ctx, cfg); 2013 hdd_update_fw_tdls_mlo_capability(hdd_ctx, cfg); 2014 hdd_set_dynamic_macaddr_update_capability(hdd_ctx, cfg); 2015 hdd_update_fw_tdls_6g_capability(hdd_ctx, cfg); 2016 hdd_update_fw_tdls_wideband_capability(hdd_ctx, cfg); 2017 ucfg_psoc_mlme_set_11be_capab(hdd_ctx->psoc, cfg->en_11be); 2018 hdd_update_mlo_per_link_stats_capability(hdd_ctx, cfg); 2019 } 2020 2021 /** 2022 * hdd_update_vdev_nss() - sets the vdev nss 2023 * @hdd_ctx: HDD context 2024 * 2025 * Sets the Nss per vdev type based on INI 2026 * 2027 * Return: None 2028 */ hdd_update_vdev_nss(struct hdd_context * hdd_ctx)2029 static void hdd_update_vdev_nss(struct hdd_context *hdd_ctx) 2030 { 2031 uint8_t max_supp_nss = 1; 2032 mac_handle_t mac_handle; 2033 QDF_STATUS status; 2034 bool bval; 2035 2036 status = ucfg_mlme_get_vht_enable2x2(hdd_ctx->psoc, &bval); 2037 if (!QDF_IS_STATUS_SUCCESS(status)) 2038 hdd_err("unable to get vht_enable2x2"); 2039 2040 if (bval && !cds_is_sub_20_mhz_enabled()) 2041 max_supp_nss = 2; 2042 2043 hdd_debug("max nss %d", max_supp_nss); 2044 2045 mac_handle = hdd_ctx->mac_handle; 2046 sme_update_vdev_type_nss(mac_handle, max_supp_nss, 2047 NSS_CHAINS_BAND_2GHZ); 2048 2049 sme_update_vdev_type_nss(mac_handle, max_supp_nss, 2050 NSS_CHAINS_BAND_5GHZ); 2051 } 2052 2053 /** 2054 * hdd_update_2g_wiphy_vhtcap() - Updates 2G wiphy vhtcap fields 2055 * @hdd_ctx: HDD context 2056 * 2057 * Updates 2G wiphy vhtcap fields 2058 * 2059 * Return: None 2060 */ hdd_update_2g_wiphy_vhtcap(struct hdd_context * hdd_ctx)2061 static void hdd_update_2g_wiphy_vhtcap(struct hdd_context *hdd_ctx) 2062 { 2063 struct ieee80211_supported_band *band_2g = 2064 hdd_ctx->wiphy->bands[NL80211_BAND_2GHZ]; 2065 uint32_t value; 2066 bool is_vht_24ghz; 2067 2068 if (!band_2g) { 2069 hdd_debug("2GHz band disabled, skipping capability population"); 2070 return; 2071 } 2072 2073 ucfg_mlme_get_vht_for_24ghz(hdd_ctx->psoc, &is_vht_24ghz); 2074 2075 if (is_vht_24ghz) { 2076 ucfg_mlme_cfg_get_vht_tx_mcs_map(hdd_ctx->psoc, &value); 2077 band_2g->vht_cap.vht_mcs.tx_mcs_map = value; 2078 } 2079 } 2080 2081 /** 2082 * hdd_update_5g_wiphy_vhtcap() - Updates 5G wiphy vhtcap fields 2083 * @hdd_ctx: HDD context 2084 * 2085 * Updates 5G wiphy vhtcap fields 2086 * 2087 * Return: None 2088 */ hdd_update_5g_wiphy_vhtcap(struct hdd_context * hdd_ctx)2089 static void hdd_update_5g_wiphy_vhtcap(struct hdd_context *hdd_ctx) 2090 { 2091 struct ieee80211_supported_band *band_5g = 2092 hdd_ctx->wiphy->bands[NL80211_BAND_5GHZ]; 2093 QDF_STATUS status; 2094 uint8_t value = 0, value1 = 0; 2095 uint32_t value2; 2096 2097 if (!band_5g) { 2098 hdd_debug("5GHz band disabled, skipping capability population"); 2099 return; 2100 } 2101 2102 status = ucfg_mlme_cfg_get_vht_tx_bfee_ant_supp(hdd_ctx->psoc, 2103 &value); 2104 if (!QDF_IS_STATUS_SUCCESS(status)) 2105 hdd_err("unable to get tx_bfee_ant_supp"); 2106 2107 band_5g->vht_cap.cap |= 2108 (value << IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT); 2109 2110 value1 = NUM_OF_SOUNDING_DIMENSIONS; 2111 band_5g->vht_cap.cap |= 2112 (value1 << IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_SHIFT); 2113 2114 hdd_debug("Updated wiphy vhtcap:0x%x, CSNAntSupp:%d, NumSoundDim:%d", 2115 band_5g->vht_cap.cap, value, value1); 2116 2117 ucfg_mlme_cfg_get_vht_rx_mcs_map(hdd_ctx->psoc, &value2); 2118 band_5g->vht_cap.vht_mcs.rx_mcs_map = value2; 2119 2120 ucfg_mlme_cfg_get_vht_tx_mcs_map(hdd_ctx->psoc, &value2); 2121 band_5g->vht_cap.vht_mcs.tx_mcs_map = value2; 2122 } 2123 2124 /** 2125 * hdd_update_wiphy_vhtcap() - Updates wiphy vhtcap fields 2126 * @hdd_ctx: HDD context 2127 * 2128 * Updates wiphy vhtcap fields 2129 * 2130 * Return: None 2131 */ hdd_update_wiphy_vhtcap(struct hdd_context * hdd_ctx)2132 static void hdd_update_wiphy_vhtcap(struct hdd_context *hdd_ctx) 2133 { 2134 hdd_update_2g_wiphy_vhtcap(hdd_ctx); 2135 hdd_update_5g_wiphy_vhtcap(hdd_ctx); 2136 } 2137 hdd_update_tgt_ht_cap(struct hdd_context * hdd_ctx,struct wma_tgt_ht_cap * cfg)2138 static void hdd_update_tgt_ht_cap(struct hdd_context *hdd_ctx, 2139 struct wma_tgt_ht_cap *cfg) 2140 { 2141 QDF_STATUS status; 2142 qdf_size_t value_len; 2143 uint32_t value; 2144 uint8_t mpdu_density; 2145 struct mlme_ht_capabilities_info ht_cap_info; 2146 uint8_t mcs_set[SIZE_OF_SUPPORTED_MCS_SET]; 2147 bool b_enable1x1; 2148 2149 /* get the MPDU density */ 2150 status = ucfg_mlme_get_ht_mpdu_density(hdd_ctx->psoc, &mpdu_density); 2151 if (QDF_IS_STATUS_ERROR(status)) { 2152 hdd_err("could not get HT MPDU Density"); 2153 return; 2154 } 2155 2156 /* 2157 * MPDU density: 2158 * override user's setting if value is larger 2159 * than the one supported by target, 2160 * if target value is 0, then follow user's setting. 2161 */ 2162 if (cfg->mpdu_density && mpdu_density > cfg->mpdu_density) { 2163 status = ucfg_mlme_set_ht_mpdu_density(hdd_ctx->psoc, 2164 cfg->mpdu_density); 2165 if (QDF_IS_STATUS_ERROR(status)) 2166 hdd_err("could not set HT capability to CCM"); 2167 } 2168 2169 /* get the HT capability info */ 2170 status = ucfg_mlme_get_ht_cap_info(hdd_ctx->psoc, &ht_cap_info); 2171 if (QDF_STATUS_SUCCESS != status) { 2172 hdd_err("could not get HT capability info"); 2173 return; 2174 } 2175 2176 /* check and update RX STBC */ 2177 if (ht_cap_info.rx_stbc && !cfg->ht_rx_stbc) 2178 ht_cap_info.rx_stbc = cfg->ht_rx_stbc; 2179 2180 /* Set the LDPC capability */ 2181 if (ht_cap_info.adv_coding_cap && !cfg->ht_rx_ldpc) 2182 ht_cap_info.adv_coding_cap = cfg->ht_rx_ldpc; 2183 2184 if (ht_cap_info.short_gi_20_mhz && !cfg->ht_sgi_20) 2185 ht_cap_info.short_gi_20_mhz = cfg->ht_sgi_20; 2186 2187 if (ht_cap_info.short_gi_40_mhz && !cfg->ht_sgi_40) 2188 ht_cap_info.short_gi_40_mhz = cfg->ht_sgi_40; 2189 2190 hdd_debug("gHtSMPS ini: %d, dynamic_smps fw cap: %d", 2191 ht_cap_info.mimo_power_save, cfg->dynamic_smps); 2192 if (ht_cap_info.mimo_power_save == HDD_SMPS_MODE_DYNAMIC) { 2193 if (cfg->dynamic_smps) 2194 ht_cap_info.mimo_power_save = HDD_SMPS_MODE_DYNAMIC; 2195 else 2196 ht_cap_info.mimo_power_save = HDD_SMPS_MODE_DISABLED; 2197 } 2198 2199 hdd_ctx->num_rf_chains = cfg->num_rf_chains; 2200 hdd_ctx->ht_tx_stbc_supported = cfg->ht_tx_stbc; 2201 2202 status = ucfg_mlme_get_vht_enable2x2(hdd_ctx->psoc, &b_enable1x1); 2203 if (!QDF_IS_STATUS_SUCCESS(status)) 2204 hdd_err("unable to get vht_enable2x2"); 2205 2206 b_enable1x1 = b_enable1x1 && (cfg->num_rf_chains == 2); 2207 2208 status = ucfg_mlme_set_vht_enable2x2(hdd_ctx->psoc, b_enable1x1); 2209 if (!QDF_IS_STATUS_SUCCESS(status)) 2210 hdd_err("unable to set vht_enable2x2"); 2211 2212 if (!b_enable1x1) 2213 ht_cap_info.tx_stbc = 0; 2214 2215 if (!(cfg->ht_tx_stbc && b_enable1x1)) 2216 ht_cap_info.tx_stbc = 0; 2217 2218 status = ucfg_mlme_set_ht_cap_info(hdd_ctx->psoc, ht_cap_info); 2219 if (status != QDF_STATUS_SUCCESS) 2220 hdd_err("could not set HT capability to CCM"); 2221 #define WLAN_HDD_RX_MCS_ALL_NSTREAM_RATES 0xff 2222 value_len = SIZE_OF_SUPPORTED_MCS_SET; 2223 if (ucfg_mlme_get_supported_mcs_set( 2224 hdd_ctx->psoc, mcs_set, 2225 &value_len) == QDF_STATUS_SUCCESS) { 2226 hdd_debug("Read MCS rate set"); 2227 if (cfg->num_rf_chains > SIZE_OF_SUPPORTED_MCS_SET) 2228 cfg->num_rf_chains = SIZE_OF_SUPPORTED_MCS_SET; 2229 2230 if (b_enable1x1) { 2231 for (value = 0; value < cfg->num_rf_chains; value++) 2232 mcs_set[value] = 2233 WLAN_HDD_RX_MCS_ALL_NSTREAM_RATES; 2234 2235 status = ucfg_mlme_set_supported_mcs_set( 2236 hdd_ctx->psoc, 2237 mcs_set, 2238 (qdf_size_t)SIZE_OF_SUPPORTED_MCS_SET); 2239 if (QDF_IS_STATUS_ERROR(status)) 2240 hdd_err("could not set MCS SET to CCM"); 2241 } 2242 } 2243 #undef WLAN_HDD_RX_MCS_ALL_NSTREAM_RATES 2244 } 2245 hdd_update_tgt_vht_cap(struct hdd_context * hdd_ctx,struct wma_tgt_vht_cap * cfg)2246 static void hdd_update_tgt_vht_cap(struct hdd_context *hdd_ctx, 2247 struct wma_tgt_vht_cap *cfg) 2248 { 2249 QDF_STATUS status; 2250 struct wiphy *wiphy = hdd_ctx->wiphy; 2251 struct ieee80211_supported_band *band_5g = 2252 wiphy->bands[HDD_NL80211_BAND_5GHZ]; 2253 uint32_t ch_width; 2254 struct wma_caps_per_phy caps_per_phy = {0}; 2255 bool vht_enable_2x2; 2256 uint32_t tx_highest_data_rate; 2257 uint32_t rx_highest_data_rate; 2258 2259 if (!band_5g) { 2260 hdd_debug("5GHz band disabled, skipping capability population"); 2261 return; 2262 } 2263 2264 status = ucfg_mlme_update_vht_cap(hdd_ctx->psoc, cfg); 2265 if (QDF_IS_STATUS_ERROR(status)) 2266 hdd_err("could not update vht capabilities"); 2267 2268 status = ucfg_mlme_get_vht_enable2x2(hdd_ctx->psoc, &vht_enable_2x2); 2269 if (!QDF_IS_STATUS_SUCCESS(status)) 2270 hdd_err("unable to get vht_enable2x2"); 2271 2272 if (vht_enable_2x2) { 2273 tx_highest_data_rate = 2274 VHT_TX_HIGHEST_SUPPORTED_DATA_RATE_2_2; 2275 rx_highest_data_rate = 2276 VHT_RX_HIGHEST_SUPPORTED_DATA_RATE_2_2; 2277 } else { 2278 tx_highest_data_rate = 2279 VHT_TX_HIGHEST_SUPPORTED_DATA_RATE_1_1; 2280 rx_highest_data_rate = 2281 VHT_RX_HIGHEST_SUPPORTED_DATA_RATE_1_1; 2282 } 2283 2284 status = ucfg_mlme_cfg_set_vht_rx_supp_data_rate(hdd_ctx->psoc, 2285 rx_highest_data_rate); 2286 if (!QDF_IS_STATUS_SUCCESS(status)) 2287 hdd_err("Failed to set rx_supp_data_rate"); 2288 2289 status = ucfg_mlme_cfg_set_vht_tx_supp_data_rate(hdd_ctx->psoc, 2290 tx_highest_data_rate); 2291 if (!QDF_IS_STATUS_SUCCESS(status)) 2292 hdd_err("Failed to set tx_supp_data_rate"); 2293 2294 /* Update the real highest data rate to wiphy */ 2295 if (cfg->vht_short_gi_80 & WMI_VHT_CAP_SGI_80MHZ) { 2296 if (vht_enable_2x2) { 2297 tx_highest_data_rate = 2298 VHT_TX_HIGHEST_SUPPORTED_DATA_RATE_2_2_SGI80; 2299 rx_highest_data_rate = 2300 VHT_RX_HIGHEST_SUPPORTED_DATA_RATE_2_2_SGI80; 2301 } else { 2302 tx_highest_data_rate = 2303 VHT_TX_HIGHEST_SUPPORTED_DATA_RATE_1_1_SGI80; 2304 rx_highest_data_rate = 2305 VHT_RX_HIGHEST_SUPPORTED_DATA_RATE_1_1_SGI80; 2306 } 2307 } 2308 2309 if (WMI_VHT_CAP_MAX_MPDU_LEN_11454 == cfg->vht_max_mpdu) 2310 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454; 2311 else if (WMI_VHT_CAP_MAX_MPDU_LEN_7935 == cfg->vht_max_mpdu) 2312 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_7991; 2313 else 2314 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_3895; 2315 2316 2317 if (cfg->supp_chan_width & (1 << eHT_CHANNEL_WIDTH_80P80MHZ)) { 2318 band_5g->vht_cap.cap |= 2319 IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ; 2320 ch_width = VHT_CAP_160_AND_80P80_SUPP; 2321 } else if (cfg->supp_chan_width & (1 << eHT_CHANNEL_WIDTH_160MHZ)) { 2322 band_5g->vht_cap.cap |= 2323 IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ; 2324 ch_width = VHT_CAP_160_SUPP; 2325 } else { 2326 ch_width = VHT_CAP_NO_160M_SUPP; 2327 } 2328 2329 status = ucfg_mlme_set_vht_ch_width(hdd_ctx->psoc, ch_width); 2330 if (QDF_IS_STATUS_ERROR(status)) 2331 hdd_err("could not set the channel width"); 2332 else 2333 hdd_debug("supported channel width %d", ch_width); 2334 2335 if (cfg->vht_rx_ldpc & WMI_VHT_CAP_RX_LDPC) { 2336 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_RXLDPC; 2337 hdd_debug("VHT RxLDPC capability is set"); 2338 } else { 2339 /* 2340 * Get the RX LDPC capability for the NON DBS 2341 * hardware mode for 5G band 2342 */ 2343 status = wma_get_caps_for_phyidx_hwmode(&caps_per_phy, 2344 HW_MODE_DBS_NONE, CDS_BAND_5GHZ); 2345 if ((QDF_IS_STATUS_SUCCESS(status)) && 2346 (caps_per_phy.vht_5g & WMI_VHT_CAP_RX_LDPC)) { 2347 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_RXLDPC; 2348 hdd_debug("VHT RX LDPC capability is set"); 2349 } 2350 } 2351 2352 if (cfg->vht_short_gi_80 & WMI_VHT_CAP_SGI_80MHZ) 2353 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_SHORT_GI_80; 2354 if (cfg->vht_short_gi_160 & WMI_VHT_CAP_SGI_160MHZ) 2355 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_SHORT_GI_160; 2356 2357 if (vht_enable_2x2 && (cfg->vht_tx_stbc & WMI_VHT_CAP_TX_STBC)) 2358 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_TXSTBC; 2359 2360 if (cfg->vht_rx_stbc & WMI_VHT_CAP_RX_STBC_1SS) 2361 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_RXSTBC_1; 2362 if (vht_enable_2x2 && (cfg->vht_rx_stbc & WMI_VHT_CAP_RX_STBC_2SS)) 2363 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_RXSTBC_2; 2364 if (cfg->vht_rx_stbc & WMI_VHT_CAP_RX_STBC_3SS) 2365 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_RXSTBC_3; 2366 2367 band_5g->vht_cap.cap |= 2368 (cfg->vht_max_ampdu_len_exp << 2369 IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT); 2370 2371 if (cfg->vht_su_bformer & WMI_VHT_CAP_SU_BFORMER) 2372 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE; 2373 if (cfg->vht_su_bformee & WMI_VHT_CAP_SU_BFORMEE) 2374 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE; 2375 if (cfg->vht_mu_bformer & WMI_VHT_CAP_MU_BFORMER) 2376 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE; 2377 if (cfg->vht_mu_bformee & WMI_VHT_CAP_MU_BFORMEE) 2378 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE; 2379 2380 if (cfg->vht_txop_ps & WMI_VHT_CAP_TXOP_PS) 2381 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_VHT_TXOP_PS; 2382 2383 band_5g->vht_cap.vht_mcs.rx_highest = cpu_to_le16(rx_highest_data_rate); 2384 band_5g->vht_cap.vht_mcs.tx_highest = cpu_to_le16(tx_highest_data_rate); 2385 } 2386 2387 /** 2388 * hdd_generate_macaddr_auto() - Auto-generate mac address 2389 * @hdd_ctx: Pointer to the HDD context 2390 * 2391 * Auto-generate mac address using device serial number. 2392 * Keep the first 3 bytes of OUI as before and replace 2393 * the last 3 bytes with the lower 3 bytes of serial number. 2394 * 2395 * Return: 0 for success 2396 * Non zero failure code for errors 2397 */ hdd_generate_macaddr_auto(struct hdd_context * hdd_ctx)2398 static int hdd_generate_macaddr_auto(struct hdd_context *hdd_ctx) 2399 { 2400 unsigned int serialno = 0; 2401 struct qdf_mac_addr mac_addr = { 2402 {0x00, 0x0A, 0xF5, 0x00, 0x00, 0x00} 2403 }; 2404 2405 serialno = pld_socinfo_get_serial_number(hdd_ctx->parent_dev); 2406 if (serialno == 0) 2407 return -EINVAL; 2408 2409 serialno &= 0x00ffffff; 2410 2411 mac_addr.bytes[3] = (serialno >> 16) & 0xff; 2412 mac_addr.bytes[4] = (serialno >> 8) & 0xff; 2413 mac_addr.bytes[5] = serialno & 0xff; 2414 2415 hdd_update_macaddr(hdd_ctx, mac_addr, true); 2416 return 0; 2417 } 2418 hdd_sar_target_config(struct hdd_context * hdd_ctx,struct wma_tgt_cfg * cfg)2419 static void hdd_sar_target_config(struct hdd_context *hdd_ctx, 2420 struct wma_tgt_cfg *cfg) 2421 { 2422 hdd_ctx->sar_version = cfg->sar_version; 2423 } 2424 hdd_update_vhtcap_2g(struct hdd_context * hdd_ctx)2425 static void hdd_update_vhtcap_2g(struct hdd_context *hdd_ctx) 2426 { 2427 uint64_t chip_mode = 0; 2428 QDF_STATUS status; 2429 bool b2g_vht_cfg = false; 2430 bool b2g_vht_target = false; 2431 struct wma_caps_per_phy caps_per_phy = {0}; 2432 struct wmi_unified *wmi_handle; 2433 2434 wmi_handle = get_wmi_unified_hdl_from_psoc(hdd_ctx->psoc); 2435 if (!wmi_handle) { 2436 hdd_err("wmi handle is NULL"); 2437 return; 2438 } 2439 2440 status = ucfg_mlme_get_vht_for_24ghz(hdd_ctx->psoc, &b2g_vht_cfg); 2441 if (QDF_IS_STATUS_ERROR(status)) { 2442 hdd_err("Failed to get 2g vht mode"); 2443 return; 2444 } 2445 if (wmi_service_enabled(wmi_handle, wmi_service_ext_msg)) { 2446 status = wma_get_caps_for_phyidx_hwmode(&caps_per_phy, 2447 HW_MODE_DBS_NONE, 2448 CDS_BAND_2GHZ); 2449 if (QDF_IS_STATUS_ERROR(status)) { 2450 hdd_err("Failed to get phy caps"); 2451 return; 2452 } 2453 if (caps_per_phy.vht_2g) 2454 b2g_vht_target = true; 2455 } else { 2456 status = wlan_reg_get_chip_mode(hdd_ctx->pdev, &chip_mode); 2457 if (QDF_IS_STATUS_ERROR(status)) { 2458 hdd_err("Failed to get chip mode"); 2459 return; 2460 } 2461 b2g_vht_target = 2462 (chip_mode & HOST_REGDMN_MODE_11AC_VHT20_2G) ? 2463 true : false; 2464 } 2465 2466 b2g_vht_cfg = b2g_vht_cfg && b2g_vht_target; 2467 hdd_debug("vht 2g target: %d, cfg: %d", b2g_vht_target, b2g_vht_cfg); 2468 status = ucfg_mlme_set_vht_for_24ghz(hdd_ctx->psoc, b2g_vht_cfg); 2469 if (QDF_IS_STATUS_ERROR(status)) { 2470 hdd_err("Failed to update 2g vht mode"); 2471 return; 2472 } 2473 } 2474 hdd_extract_fw_version_info(struct hdd_context * hdd_ctx)2475 static void hdd_extract_fw_version_info(struct hdd_context *hdd_ctx) 2476 { 2477 hdd_ctx->fw_version_info.major_spid = 2478 HDD_FW_VER_MAJOR_SPID(hdd_ctx->target_fw_version); 2479 hdd_ctx->fw_version_info.minor_spid = 2480 HDD_FW_VER_MINOR_SPID(hdd_ctx->target_fw_version); 2481 hdd_ctx->fw_version_info.siid = 2482 HDD_FW_VER_SIID(hdd_ctx->target_fw_version); 2483 hdd_ctx->fw_version_info.crmid = 2484 HDD_FW_VER_CRM_ID(hdd_ctx->target_fw_version); 2485 hdd_ctx->fw_version_info.sub_id = 2486 HDD_FW_VER_SUB_ID(hdd_ctx->target_fw_vers_ext); 2487 hdd_ctx->fw_version_info.rel_id = 2488 HDD_FW_VER_REL_ID(hdd_ctx->target_fw_vers_ext); 2489 } 2490 2491 #if defined(WLAN_FEATURE_11AX) && \ 2492 (defined(CFG80211_SBAND_IFTYPE_DATA_BACKPORT) || \ 2493 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0))) 2494 2495 static void hdd_update_wiphy_he_mcs(struct ieee80211_sband_iftype_data * iftype_data,tDot11fIEhe_cap * he_cap_cfg)2496 hdd_update_wiphy_he_mcs(struct ieee80211_sband_iftype_data *iftype_data, 2497 tDot11fIEhe_cap *he_cap_cfg) 2498 { 2499 if (!iftype_data || !he_cap_cfg) { 2500 hdd_err("Unable to update wiphy he_mcs"); 2501 return; 2502 } 2503 2504 iftype_data->he_cap.he_mcs_nss_supp.tx_mcs_80 = 2505 he_cap_cfg->tx_he_mcs_map_lt_80; 2506 iftype_data->he_cap.he_mcs_nss_supp.tx_mcs_160 = 2507 *((uint16_t *)he_cap_cfg->tx_he_mcs_map_160); 2508 iftype_data->he_cap.he_mcs_nss_supp.tx_mcs_80p80 = 2509 *((uint16_t *)he_cap_cfg->tx_he_mcs_map_80_80); 2510 } 2511 2512 #if defined(CONFIG_BAND_6GHZ) && (defined(IEEE80211_HE_6GHZ_CAP_MIN_MPDU_START)) hdd_update_wiphy_he_6ghz_capa(struct hdd_context * hdd_ctx)2513 static void hdd_update_wiphy_he_6ghz_capa(struct hdd_context *hdd_ctx) 2514 { 2515 uint16_t he_6ghz_capa = 0; 2516 uint8_t min_mpdu_start_spacing; 2517 uint8_t max_ampdu_len_exp; 2518 uint8_t max_mpdu_len; 2519 uint8_t sm_pow_save; 2520 2521 ucfg_mlme_get_ht_mpdu_density(hdd_ctx->psoc, &min_mpdu_start_spacing); 2522 he_6ghz_capa |= FIELD_PREP(IEEE80211_HE_6GHZ_CAP_MIN_MPDU_START, 2523 min_mpdu_start_spacing); 2524 2525 ucfg_mlme_cfg_get_vht_ampdu_len_exp(hdd_ctx->psoc, &max_ampdu_len_exp); 2526 he_6ghz_capa |= FIELD_PREP(IEEE80211_HE_6GHZ_CAP_MAX_AMPDU_LEN_EXP, 2527 max_ampdu_len_exp); 2528 2529 ucfg_mlme_cfg_get_vht_max_mpdu_len(hdd_ctx->psoc, &max_mpdu_len); 2530 he_6ghz_capa |= FIELD_PREP(IEEE80211_HE_6GHZ_CAP_MAX_MPDU_LEN, 2531 max_mpdu_len); 2532 2533 ucfg_mlme_cfg_get_ht_smps(hdd_ctx->psoc, &sm_pow_save); 2534 he_6ghz_capa |= FIELD_PREP(IEEE80211_HE_6GHZ_CAP_SM_PS, sm_pow_save); 2535 2536 he_6ghz_capa |= IEEE80211_HE_6GHZ_CAP_RX_ANTPAT_CONS; 2537 he_6ghz_capa |= IEEE80211_HE_6GHZ_CAP_TX_ANTPAT_CONS; 2538 2539 hdd_ctx->iftype_data_6g->he_6ghz_capa.capa = he_6ghz_capa; 2540 } 2541 #else hdd_update_wiphy_he_6ghz_capa(struct hdd_context * hdd_ctx)2542 static inline void hdd_update_wiphy_he_6ghz_capa(struct hdd_context *hdd_ctx) 2543 { 2544 } 2545 #endif 2546 2547 #if defined(CONFIG_BAND_6GHZ) && (defined(CFG80211_6GHZ_BAND_SUPPORTED) || \ 2548 (KERNEL_VERSION(5, 4, 0) <= LINUX_VERSION_CODE)) 2549 static void hdd_update_wiphy_he_caps_6ghz(struct hdd_context * hdd_ctx,tDot11fIEhe_cap * he_cap_cfg)2550 hdd_update_wiphy_he_caps_6ghz(struct hdd_context *hdd_ctx, 2551 tDot11fIEhe_cap *he_cap_cfg) 2552 { 2553 struct ieee80211_supported_band *band_6g = 2554 hdd_ctx->wiphy->bands[HDD_NL80211_BAND_6GHZ]; 2555 uint8_t *phy_info = 2556 hdd_ctx->iftype_data_6g->he_cap.he_cap_elem.phy_cap_info; 2557 uint8_t *mac_info_6g = 2558 hdd_ctx->iftype_data_6g->he_cap.he_cap_elem.mac_cap_info; 2559 uint8_t max_fw_bw = sme_get_vht_ch_width(); 2560 2561 if (!band_6g || !phy_info) { 2562 hdd_debug("6ghz not supported in wiphy"); 2563 return; 2564 } 2565 2566 hdd_ctx->iftype_data_6g->types_mask = 2567 (BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP)); 2568 hdd_ctx->iftype_data_6g->he_cap.has_he = true; 2569 band_6g->n_iftype_data = 1; 2570 2571 if (max_fw_bw >= WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ) 2572 phy_info[0] |= 2573 IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_80MHZ_IN_5G; 2574 if (max_fw_bw >= WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ) 2575 phy_info[0] |= 2576 IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_160MHZ_IN_5G; 2577 if (max_fw_bw >= WNI_CFG_VHT_CHANNEL_WIDTH_80_PLUS_80MHZ) 2578 phy_info[0] |= 2579 IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G; 2580 2581 if (he_cap_cfg->twt_request) 2582 mac_info_6g[0] |= IEEE80211_HE_MAC_CAP0_TWT_REQ; 2583 2584 if (he_cap_cfg->twt_responder) 2585 mac_info_6g[0] |= IEEE80211_HE_MAC_CAP0_TWT_RES; 2586 2587 hdd_update_wiphy_he_6ghz_capa(hdd_ctx); 2588 2589 hdd_update_wiphy_he_mcs(hdd_ctx->iftype_data_6g, he_cap_cfg); 2590 2591 band_6g->iftype_data = hdd_ctx->iftype_data_6g; 2592 } 2593 #else 2594 static inline void hdd_update_wiphy_he_caps_6ghz(struct hdd_context * hdd_ctx,tDot11fIEhe_cap * he_cap_cfg)2595 hdd_update_wiphy_he_caps_6ghz(struct hdd_context *hdd_ctx, 2596 tDot11fIEhe_cap *he_cap_cfg) 2597 { 2598 } 2599 #endif 2600 hdd_update_wiphy_he_cap(struct hdd_context * hdd_ctx)2601 static void hdd_update_wiphy_he_cap(struct hdd_context *hdd_ctx) 2602 { 2603 tDot11fIEhe_cap he_cap_cfg; 2604 struct ieee80211_supported_band *band_2g = 2605 hdd_ctx->wiphy->bands[HDD_NL80211_BAND_2GHZ]; 2606 struct ieee80211_supported_band *band_5g = 2607 hdd_ctx->wiphy->bands[HDD_NL80211_BAND_5GHZ]; 2608 QDF_STATUS status; 2609 uint8_t *phy_info_5g = 2610 hdd_ctx->iftype_data_5g->he_cap.he_cap_elem.phy_cap_info; 2611 uint8_t max_fw_bw = sme_get_vht_ch_width(); 2612 uint32_t channel_bonding_mode_2g; 2613 uint8_t *phy_info_2g = 2614 hdd_ctx->iftype_data_2g->he_cap.he_cap_elem.phy_cap_info; 2615 uint8_t *mac_info_2g = 2616 hdd_ctx->iftype_data_2g->he_cap.he_cap_elem.mac_cap_info; 2617 uint8_t *mac_info_5g = 2618 hdd_ctx->iftype_data_5g->he_cap.he_cap_elem.mac_cap_info; 2619 2620 status = ucfg_mlme_cfg_get_he_caps(hdd_ctx->psoc, &he_cap_cfg); 2621 2622 if (QDF_IS_STATUS_ERROR(status)) 2623 return; 2624 2625 if (band_2g) { 2626 hdd_ctx->iftype_data_2g->types_mask = 2627 (BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP)); 2628 hdd_ctx->iftype_data_2g->he_cap.has_he = he_cap_cfg.present; 2629 band_2g->n_iftype_data = 1; 2630 hdd_update_wiphy_he_mcs(hdd_ctx->iftype_data_2g, &he_cap_cfg); 2631 band_2g->iftype_data = hdd_ctx->iftype_data_2g; 2632 2633 ucfg_mlme_get_channel_bonding_24ghz(hdd_ctx->psoc, 2634 &channel_bonding_mode_2g); 2635 if (channel_bonding_mode_2g) 2636 phy_info_2g[0] |= 2637 IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_IN_2G; 2638 2639 if (he_cap_cfg.twt_request) 2640 mac_info_2g[0] |= IEEE80211_HE_MAC_CAP0_TWT_REQ; 2641 2642 if (he_cap_cfg.twt_responder) 2643 mac_info_2g[0] |= IEEE80211_HE_MAC_CAP0_TWT_RES; 2644 } 2645 if (band_5g) { 2646 hdd_ctx->iftype_data_5g->types_mask = 2647 (BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP)); 2648 hdd_ctx->iftype_data_5g->he_cap.has_he = he_cap_cfg.present; 2649 band_5g->n_iftype_data = 1; 2650 hdd_update_wiphy_he_mcs(hdd_ctx->iftype_data_5g, &he_cap_cfg); 2651 band_5g->iftype_data = hdd_ctx->iftype_data_5g; 2652 2653 if (max_fw_bw >= WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ) 2654 phy_info_5g[0] |= 2655 IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_80MHZ_IN_5G; 2656 if (max_fw_bw >= WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ) 2657 phy_info_5g[0] |= 2658 IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_160MHZ_IN_5G; 2659 if (max_fw_bw >= WNI_CFG_VHT_CHANNEL_WIDTH_80_PLUS_80MHZ) 2660 phy_info_5g[0] |= 2661 IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G; 2662 2663 if (he_cap_cfg.twt_request) 2664 mac_info_5g[0] |= IEEE80211_HE_MAC_CAP0_TWT_REQ; 2665 2666 if (he_cap_cfg.twt_responder) 2667 mac_info_5g[0] |= IEEE80211_HE_MAC_CAP0_TWT_RES; 2668 } 2669 2670 hdd_update_wiphy_he_caps_6ghz(hdd_ctx, &he_cap_cfg); 2671 } 2672 #else hdd_update_wiphy_he_cap(struct hdd_context * hdd_ctx)2673 static void hdd_update_wiphy_he_cap(struct hdd_context *hdd_ctx) 2674 { 2675 } 2676 #endif 2677 hdd_component_cfg_chan_to_freq(struct wlan_objmgr_pdev * pdev)2678 static void hdd_component_cfg_chan_to_freq(struct wlan_objmgr_pdev *pdev) 2679 { 2680 ucfg_mlme_cfg_chan_to_freq(pdev); 2681 } 2682 hdd_update_band_cap_from_dot11mode(struct hdd_context * hdd_ctx,uint32_t band_capability)2683 static uint32_t hdd_update_band_cap_from_dot11mode( 2684 struct hdd_context *hdd_ctx, uint32_t band_capability) 2685 { 2686 if (hdd_ctx->config->dot11Mode == eHDD_DOT11_MODE_AUTO) 2687 return band_capability; 2688 2689 if (hdd_ctx->config->dot11Mode == eHDD_DOT11_MODE_11b || 2690 hdd_ctx->config->dot11Mode == eHDD_DOT11_MODE_11g || 2691 hdd_ctx->config->dot11Mode == eHDD_DOT11_MODE_11g_ONLY || 2692 hdd_ctx->config->dot11Mode == eHDD_DOT11_MODE_11b_ONLY) 2693 band_capability = (band_capability & (~BIT(REG_BAND_5G))); 2694 2695 if (hdd_ctx->config->dot11Mode == eHDD_DOT11_MODE_11a) 2696 band_capability = (band_capability & (~BIT(REG_BAND_2G))); 2697 2698 if (hdd_ctx->config->dot11Mode != eHDD_DOT11_MODE_11ax_ONLY && 2699 hdd_ctx->config->dot11Mode != eHDD_DOT11_MODE_11ax) 2700 band_capability = (band_capability & (~BIT(REG_BAND_6G))); 2701 2702 qdf_debug("Update band capability %x", band_capability); 2703 return band_capability; 2704 } 2705 2706 #ifdef FEATURE_WPSS_THERMAL_MITIGATION 2707 static inline hdd_update_multi_client_thermal_support(struct hdd_context * hdd_ctx)2708 void hdd_update_multi_client_thermal_support(struct hdd_context *hdd_ctx) 2709 { 2710 struct wmi_unified *wmi_handle; 2711 2712 wmi_handle = get_wmi_unified_hdl_from_psoc(hdd_ctx->psoc); 2713 if (!wmi_handle) 2714 return; 2715 2716 hdd_ctx->multi_client_thermal_mitigation = 2717 wmi_service_enabled(wmi_handle, 2718 wmi_service_thermal_multi_client_support); 2719 } 2720 #else 2721 static inline hdd_update_multi_client_thermal_support(struct hdd_context * hdd_ctx)2722 void hdd_update_multi_client_thermal_support(struct hdd_context *hdd_ctx) 2723 { 2724 } 2725 #endif 2726 2727 #ifdef WLAN_FEATURE_LOCAL_PKT_CAPTURE hdd_lpc_enable_powersave(struct hdd_context * hdd_ctx)2728 static void hdd_lpc_enable_powersave(struct hdd_context *hdd_ctx) 2729 { 2730 struct hdd_adapter *sta_adapter; 2731 2732 if (!ucfg_dp_is_local_pkt_capture_enabled(hdd_ctx->psoc)) 2733 return; 2734 2735 ucfg_fwol_configure_global_params(hdd_ctx->psoc, hdd_ctx->pdev); 2736 2737 if (wma_enable_disable_imps(hdd_ctx->pdev->pdev_objmgr.wlan_pdev_id, 1)) 2738 hdd_err("IMPS feature enable failed"); 2739 2740 sta_adapter = hdd_get_adapter(hdd_ctx, QDF_STA_MODE); 2741 if (!sta_adapter) { 2742 hdd_debug("STA adapter does not exist"); 2743 return; 2744 } 2745 2746 wlan_hdd_set_powersave(sta_adapter->deflink, true, 0); 2747 } 2748 hdd_lpc_disable_powersave(struct hdd_context * hdd_ctx)2749 static void hdd_lpc_disable_powersave(struct hdd_context *hdd_ctx) 2750 { 2751 struct hdd_adapter *sta_adapter; 2752 2753 if (!ucfg_dp_is_local_pkt_capture_enabled(hdd_ctx->psoc)) 2754 return; 2755 2756 ucfg_fwol_set_ilp_config(hdd_ctx->psoc, hdd_ctx->pdev, 0); 2757 2758 if (wma_enable_disable_imps(hdd_ctx->pdev->pdev_objmgr.wlan_pdev_id, 0)) 2759 hdd_err("IMPS feature disable failed"); 2760 2761 sta_adapter = hdd_get_adapter(hdd_ctx, QDF_STA_MODE); 2762 if (!sta_adapter) { 2763 hdd_err("STA adapter does not exist"); 2764 return; 2765 } 2766 wlan_hdd_set_powersave(sta_adapter->deflink, false, 0); 2767 } 2768 #else hdd_lpc_enable_powersave(struct hdd_context * hdd_ctx)2769 static inline void hdd_lpc_enable_powersave(struct hdd_context *hdd_ctx) 2770 { 2771 } 2772 hdd_lpc_disable_powersave(struct hdd_context * hdd_ctx)2773 static inline void hdd_lpc_disable_powersave(struct hdd_context *hdd_ctx) 2774 { 2775 } 2776 #endif 2777 hdd_update_tgt_cfg(hdd_handle_t hdd_handle,struct wma_tgt_cfg * cfg)2778 int hdd_update_tgt_cfg(hdd_handle_t hdd_handle, struct wma_tgt_cfg *cfg) 2779 { 2780 int ret; 2781 struct hdd_context *hdd_ctx = hdd_handle_to_context(hdd_handle); 2782 uint32_t temp_band_cap, band_capability; 2783 struct cds_config_info *cds_cfg = cds_get_ini_config(); 2784 uint8_t antenna_mode; 2785 uint8_t sub_20_chan_width; 2786 QDF_STATUS status; 2787 mac_handle_t mac_handle; 2788 bool bval = false; 2789 uint8_t value = 0; 2790 uint32_t fine_time_meas_cap = 0; 2791 enum nss_chains_band_info band; 2792 bool enable_dynamic_cfg; 2793 2794 if (!hdd_ctx) { 2795 hdd_err("HDD context is NULL"); 2796 return -EINVAL; 2797 } 2798 ret = hdd_objmgr_create_and_store_pdev(hdd_ctx); 2799 if (ret) { 2800 QDF_DEBUG_PANIC("Failed to create pdev; errno:%d", ret); 2801 return -EINVAL; 2802 } 2803 2804 hdd_debug("New pdev has been created with pdev_id = %u", 2805 hdd_ctx->pdev->pdev_objmgr.wlan_pdev_id); 2806 2807 status = dispatcher_pdev_open(hdd_ctx->pdev); 2808 if (QDF_IS_STATUS_ERROR(status)) { 2809 QDF_DEBUG_PANIC("dispatcher pdev open failed; status:%d", 2810 status); 2811 ret = qdf_status_to_os_return(status); 2812 goto exit; 2813 } 2814 2815 status = hdd_component_pdev_open(hdd_ctx->pdev); 2816 if (QDF_IS_STATUS_ERROR(status)) { 2817 QDF_DEBUG_PANIC("hdd component pdev open failed; status:%d", 2818 status); 2819 ret = qdf_status_to_os_return(status); 2820 goto dispatcher_close; 2821 } 2822 /* 2823 * For 6GHz support this api is added to convert mlme cfgs 2824 * channel numbers to frequency 2825 */ 2826 hdd_component_cfg_chan_to_freq(hdd_ctx->pdev); 2827 2828 hdd_objmgr_update_tgt_max_vdev_psoc(hdd_ctx, cfg->max_intf_count); 2829 2830 ucfg_ipa_set_dp_handle(hdd_ctx->psoc, 2831 cds_get_context(QDF_MODULE_ID_SOC)); 2832 ucfg_ipa_set_pdev_id(hdd_ctx->psoc, OL_TXRX_PDEV_ID); 2833 2834 status = ucfg_mlme_get_sub_20_chan_width(hdd_ctx->psoc, 2835 &sub_20_chan_width); 2836 if (QDF_IS_STATUS_ERROR(status)) { 2837 hdd_err("Failed to get sub_20_chan_width config"); 2838 ret = qdf_status_to_os_return(status); 2839 goto pdev_close; 2840 } 2841 2842 if (cds_cfg) { 2843 if (sub_20_chan_width != 2844 WLAN_SUB_20_CH_WIDTH_NONE && !cfg->sub_20_support) { 2845 hdd_err("User requested sub 20 MHz channel width but unsupported by FW."); 2846 cds_cfg->sub_20_channel_width = 2847 WLAN_SUB_20_CH_WIDTH_NONE; 2848 } else { 2849 cds_cfg->sub_20_channel_width = sub_20_chan_width; 2850 } 2851 } 2852 2853 status = ucfg_mlme_get_band_capability(hdd_ctx->psoc, &band_capability); 2854 if (QDF_IS_STATUS_ERROR(status)) { 2855 hdd_err("Failed to get MLME band capability"); 2856 ret = qdf_status_to_os_return(status); 2857 goto pdev_close; 2858 } 2859 2860 band_capability = 2861 hdd_update_band_cap_from_dot11mode(hdd_ctx, band_capability); 2862 2863 /* first store the INI band capability */ 2864 temp_band_cap = band_capability; 2865 2866 band_capability = cfg->band_cap; 2867 hdd_ctx->is_fils_roaming_supported = 2868 cfg->services.is_fils_roaming_supported; 2869 2870 hdd_ctx->config->is_11k_offload_supported = 2871 cfg->services.is_11k_offload_supported; 2872 2873 /* 2874 * merge the target band capability with INI setting if the merge has 2875 * at least 1 band enabled 2876 */ 2877 temp_band_cap &= band_capability; 2878 if (!temp_band_cap) 2879 hdd_warn("ini BandCapability not supported by the target"); 2880 else 2881 band_capability = temp_band_cap; 2882 2883 status = ucfg_mlme_set_band_capability(hdd_ctx->psoc, band_capability); 2884 if (QDF_IS_STATUS_ERROR(status)) { 2885 hdd_err("Failed to set MLME Band Capability"); 2886 ret = qdf_status_to_os_return(status); 2887 goto pdev_close; 2888 } 2889 2890 hdd_ctx->curr_band = band_capability; 2891 hdd_ctx->psoc->soc_nif.user_config.band_capability = hdd_ctx->curr_band; 2892 2893 status = wlan_hdd_update_wiphy_supported_band(hdd_ctx); 2894 if (QDF_IS_STATUS_ERROR(status)) { 2895 hdd_err("Failed to update wiphy band info"); 2896 goto pdev_close; 2897 } 2898 2899 status = ucfg_reg_set_band(hdd_ctx->pdev, band_capability); 2900 if (QDF_IS_STATUS_ERROR(status)) 2901 /* 2902 * Continue, Do not close the pdev from here as if host fails 2903 * to update band information if cc_list event is not received 2904 * by this time, then also driver load should happen. 2905 */ 2906 hdd_err("Failed to update regulatory band info"); 2907 2908 if (!cds_is_driver_recovering() || cds_is_driver_in_bad_state()) { 2909 hdd_ctx->reg.reg_domain = cfg->reg_domain; 2910 hdd_ctx->reg.eeprom_rd_ext = cfg->eeprom_rd_ext; 2911 } 2912 2913 /* This can be extended to other configurations like ht, vht cap... */ 2914 status = wlan_hdd_validate_mac_address(&cfg->hw_macaddr); 2915 if (QDF_IS_STATUS_SUCCESS(status)) 2916 qdf_mem_copy(&hdd_ctx->hw_macaddr, &cfg->hw_macaddr, 2917 QDF_MAC_ADDR_SIZE); 2918 2919 hdd_ctx->target_fw_version = cfg->target_fw_version; 2920 hdd_ctx->target_fw_vers_ext = cfg->target_fw_vers_ext; 2921 hdd_extract_fw_version_info(hdd_ctx); 2922 2923 hdd_ctx->hw_bd_id = cfg->hw_bd_id; 2924 qdf_mem_copy(&hdd_ctx->hw_bd_info, &cfg->hw_bd_info, 2925 sizeof(cfg->hw_bd_info)); 2926 2927 if (cfg->max_intf_count > WLAN_MAX_VDEVS) { 2928 hdd_err("fw max vdevs (%u) > host max vdevs (%u); using %u", 2929 cfg->max_intf_count, WLAN_MAX_VDEVS, WLAN_MAX_VDEVS); 2930 hdd_ctx->max_intf_count = WLAN_MAX_VDEVS; 2931 } else { 2932 hdd_ctx->max_intf_count = cfg->max_intf_count; 2933 } 2934 2935 hdd_sar_target_config(hdd_ctx, cfg); 2936 hdd_lpass_target_config(hdd_ctx, cfg); 2937 2938 hdd_ctx->ap_arpns_support = cfg->ap_arpns_support; 2939 2940 hdd_update_tgt_services(hdd_ctx, &cfg->services); 2941 2942 hdd_update_tgt_ht_cap(hdd_ctx, &cfg->ht_cap); 2943 2944 sme_update_bfer_caps_as_per_nss_chains(hdd_ctx->mac_handle, cfg); 2945 2946 hdd_update_tgt_vht_cap(hdd_ctx, &cfg->vht_cap); 2947 if (cfg->services.en_11ax && 2948 (hdd_ctx->config->dot11Mode == eHDD_DOT11_MODE_AUTO || 2949 hdd_ctx->config->dot11Mode == eHDD_DOT11_MODE_11ax || 2950 hdd_ctx->config->dot11Mode == eHDD_DOT11_MODE_11ax_ONLY)) { 2951 hdd_debug("11AX: 11ax is enabled - update HDD config"); 2952 hdd_update_tgt_he_cap(hdd_ctx, cfg); 2953 hdd_update_wiphy_he_cap(hdd_ctx); 2954 } 2955 hdd_update_tgt_twt_cap(hdd_ctx, cfg); 2956 hdd_update_tgt_eht_cap(hdd_ctx, cfg); 2957 hdd_update_wiphy_eht_cap(hdd_ctx); 2958 ucfg_mlme_update_tgt_mlo_cap(hdd_ctx->psoc); 2959 2960 for (band = NSS_CHAINS_BAND_2GHZ; band < NSS_CHAINS_BAND_MAX; band++) { 2961 sme_modify_nss_chains_tgt_cfg(hdd_ctx->mac_handle, 2962 QDF_STA_MODE, band); 2963 sme_modify_nss_chains_tgt_cfg(hdd_ctx->mac_handle, 2964 QDF_SAP_MODE, band); 2965 sme_modify_nss_chains_tgt_cfg(hdd_ctx->mac_handle, 2966 QDF_TDLS_MODE, band); 2967 sme_modify_nss_chains_tgt_cfg(hdd_ctx->mac_handle, 2968 QDF_P2P_DEVICE_MODE, 2969 band); 2970 sme_modify_nss_chains_tgt_cfg(hdd_ctx->mac_handle, 2971 QDF_OCB_MODE, band); 2972 sme_modify_nss_chains_tgt_cfg(hdd_ctx->mac_handle, 2973 QDF_TDLS_MODE, band); 2974 } 2975 2976 hdd_update_vdev_nss(hdd_ctx); 2977 2978 status = 2979 ucfg_mlme_get_enable_dynamic_nss_chains_cfg(hdd_ctx->psoc, 2980 &enable_dynamic_cfg); 2981 if (QDF_IS_STATUS_ERROR(status)) { 2982 hdd_err("unable to get enable dynamic config"); 2983 hdd_ctx->dynamic_nss_chains_support = false; 2984 } else { 2985 hdd_ctx->dynamic_nss_chains_support = 2986 cfg->dynamic_nss_chains_support & 2987 enable_dynamic_cfg; 2988 hdd_debug("Dynamic nss chain support FW %d driver %d", 2989 cfg->dynamic_nss_chains_support, enable_dynamic_cfg); 2990 } 2991 2992 status = ucfg_mlme_update_dynamic_nss_chains_support 2993 (hdd_ctx->psoc, hdd_ctx->dynamic_nss_chains_support); 2994 if (QDF_IS_STATUS_ERROR(status)) 2995 hdd_err("unable to set dynamic_nss_chains_support"); 2996 2997 ucfg_mlme_get_fine_time_meas_cap(hdd_ctx->psoc, &fine_time_meas_cap); 2998 fine_time_meas_cap &= cfg->fine_time_measurement_cap; 2999 status = ucfg_mlme_set_fine_time_meas_cap(hdd_ctx->psoc, 3000 fine_time_meas_cap); 3001 if (QDF_IS_STATUS_ERROR(status)) { 3002 hdd_err("failed to set fine_time_meas_cap, 0x%x, ox%x", 3003 fine_time_meas_cap, cfg->fine_time_measurement_cap); 3004 ucfg_mlme_get_fine_time_meas_cap(hdd_ctx->psoc, 3005 &fine_time_meas_cap); 3006 } 3007 3008 hdd_ctx->fine_time_meas_cap_target = cfg->fine_time_measurement_cap; 3009 hdd_debug("fine_time_meas_cap: 0x%x", fine_time_meas_cap); 3010 3011 status = ucfg_mlme_get_vht_enable2x2(hdd_ctx->psoc, &bval); 3012 if (!QDF_IS_STATUS_SUCCESS(status)) 3013 hdd_err("unable to get vht_enable2x2"); 3014 3015 antenna_mode = (bval == 0x01) ? 3016 HDD_ANTENNA_MODE_2X2 : HDD_ANTENNA_MODE_1X1; 3017 hdd_update_smps_antenna_mode(hdd_ctx, antenna_mode); 3018 hdd_debug("Init current antenna mode: %d", 3019 hdd_ctx->current_antenna_mode); 3020 3021 hdd_ctx->rcpi_enabled = cfg->rcpi_enabled; 3022 3023 status = ucfg_mlme_cfg_get_vht_tx_bfee_ant_supp(hdd_ctx->psoc, 3024 &value); 3025 if (QDF_IS_STATUS_ERROR(status)) { 3026 status = false; 3027 hdd_err("set tx_bfee_ant_supp failed"); 3028 } 3029 3030 status = ucfg_mlme_set_restricted_80p80_bw_supp(hdd_ctx->psoc, 3031 cfg->restricted_80p80_bw_supp); 3032 if (QDF_IS_STATUS_ERROR(status)) 3033 hdd_err("Failed to set MLME restircted 80p80 BW support"); 3034 3035 if ((value > MLME_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED_FW_DEF) && 3036 !cfg->tx_bfee_8ss_enabled) { 3037 status = ucfg_mlme_cfg_set_vht_tx_bfee_ant_supp(hdd_ctx->psoc, 3038 MLME_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED_FW_DEF); 3039 if (QDF_IS_STATUS_ERROR(status)) { 3040 status = false; 3041 hdd_err("set tx_bfee_ant_supp failed"); 3042 } 3043 } 3044 3045 hdd_update_tid_to_link_supported(hdd_ctx, &cfg->services); 3046 mac_handle = hdd_ctx->mac_handle; 3047 3048 hdd_debug("txBFCsnValue %d", value); 3049 3050 /* 3051 * Update txBFCsnValue and NumSoundingDim values to vhtcap in wiphy 3052 */ 3053 hdd_update_wiphy_vhtcap(hdd_ctx); 3054 3055 hdd_update_vhtcap_2g(hdd_ctx); 3056 3057 hdd_ctx->wmi_max_len = cfg->wmi_max_len; 3058 3059 wlan_config_sched_scan_plans_to_wiphy(hdd_ctx->wiphy, hdd_ctx->psoc); 3060 /* 3061 * This needs to be done after HDD pdev is created and stored since 3062 * it will access the HDD pdev object lock. 3063 */ 3064 hdd_runtime_suspend_context_init(hdd_ctx); 3065 3066 /* Configure NAN datapath features */ 3067 hdd_nan_datapath_target_config(hdd_ctx, cfg); 3068 ucfg_nan_set_tgt_caps(hdd_ctx->psoc, &cfg->nan_caps); 3069 hdd_ctx->dfs_cac_offload = cfg->dfs_cac_offload; 3070 hdd_ctx->lte_coex_ant_share = cfg->services.lte_coex_ant_share; 3071 hdd_ctx->obss_scan_offload = cfg->services.obss_scan_offload; 3072 ucfg_scan_set_obss_scan_offload(hdd_ctx->psoc, 3073 hdd_ctx->obss_scan_offload); 3074 status = ucfg_mlme_set_obss_detection_offload_enabled( 3075 hdd_ctx->psoc, cfg->obss_detection_offloaded); 3076 if (QDF_IS_STATUS_ERROR(status)) 3077 hdd_err("Couldn't pass WNI_CFG_OBSS_DETECTION_OFFLOAD to CFG"); 3078 3079 status = ucfg_mlme_set_obss_color_collision_offload_enabled( 3080 hdd_ctx->psoc, cfg->obss_color_collision_offloaded); 3081 if (QDF_IS_STATUS_ERROR(status)) 3082 hdd_err("Failed to set WNI_CFG_OBSS_COLOR_COLLISION_OFFLOAD"); 3083 3084 ucfg_mlme_set_bss_color_collision_det_support( 3085 hdd_ctx->psoc, 3086 cfg->obss_color_collision_offloaded); 3087 if (!cfg->obss_color_collision_offloaded) { 3088 status = ucfg_mlme_set_bss_color_collision_det_sta( 3089 hdd_ctx->psoc, 3090 cfg->obss_color_collision_offloaded); 3091 if (QDF_IS_STATUS_ERROR(status)) 3092 hdd_err("Failed to set CFG_BSS_CLR_COLLISION_DET_STA"); 3093 } 3094 3095 hdd_update_score_config(hdd_ctx); 3096 hdd_update_multi_client_thermal_support(hdd_ctx); 3097 3098 ucfg_psoc_mlme_set_11be_capab(hdd_ctx->psoc, cfg->services.en_11be); 3099 return 0; 3100 3101 dispatcher_close: 3102 dispatcher_pdev_close(hdd_ctx->pdev); 3103 pdev_close: 3104 hdd_component_pdev_close(hdd_ctx->pdev); 3105 exit: 3106 hdd_objmgr_release_and_destroy_pdev(hdd_ctx); 3107 3108 return ret; 3109 } 3110 hdd_dfs_indicate_radar(struct hdd_context * hdd_ctx)3111 bool hdd_dfs_indicate_radar(struct hdd_context *hdd_ctx) 3112 { 3113 struct hdd_adapter *adapter, *next_adapter = NULL; 3114 struct hdd_ap_ctx *ap_ctx; 3115 uint32_t ap_chan; 3116 bool dfs_disable_channel_switch = false; 3117 struct wlan_hdd_link_info *link_info; 3118 3119 if (!hdd_ctx) { 3120 hdd_info("Couldn't get hdd_ctx"); 3121 return true; 3122 } 3123 3124 ucfg_mlme_get_dfs_disable_channel_switch(hdd_ctx->psoc, 3125 &dfs_disable_channel_switch); 3126 if (dfs_disable_channel_switch) { 3127 hdd_info("skip tx block hdd_ctx=%pK, disableDFSChSwitch=%d", 3128 hdd_ctx, dfs_disable_channel_switch); 3129 return true; 3130 } 3131 3132 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 3133 NET_DEV_HOLD_DFS_INDICATE_RADAR) { 3134 3135 if (adapter->device_mode != QDF_SAP_MODE && 3136 adapter->device_mode != QDF_P2P_GO_MODE) 3137 goto next_adapter; 3138 3139 hdd_adapter_for_each_active_link_info(adapter, link_info) { 3140 ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(link_info); 3141 ap_chan = ap_ctx->operating_chan_freq; 3142 if (!wlan_reg_is_passive_or_disable_for_pwrmode(hdd_ctx->pdev, 3143 ap_chan, REG_CURRENT_PWR_MODE)) 3144 continue; 3145 3146 ap_ctx->dfs_cac_block_tx = true; 3147 hdd_info("tx blocked for vdev: %d", link_info->vdev_id); 3148 if (link_info->vdev_id != WLAN_UMAC_VDEV_ID_MAX) 3149 cdp_fc_vdev_flush( 3150 cds_get_context(QDF_MODULE_ID_SOC), 3151 link_info->vdev_id); 3152 } 3153 next_adapter: 3154 hdd_adapter_dev_put_debug(adapter, 3155 NET_DEV_HOLD_DFS_INDICATE_RADAR); 3156 } 3157 3158 return true; 3159 } 3160 hdd_is_valid_mac_address(const uint8_t * mac_addr)3161 bool hdd_is_valid_mac_address(const uint8_t *mac_addr) 3162 { 3163 int xdigit = 0; 3164 int separator = 0; 3165 3166 while (*mac_addr) { 3167 if (isxdigit(*mac_addr)) { 3168 xdigit++; 3169 } else if (':' == *mac_addr) { 3170 if (0 == xdigit || ((xdigit / 2) - 1) != separator) 3171 break; 3172 3173 ++separator; 3174 } else { 3175 /* Invalid MAC found */ 3176 return false; 3177 } 3178 ++mac_addr; 3179 } 3180 return xdigit == 12 && (separator == 5 || separator == 0); 3181 } 3182 3183 /** 3184 * hdd_mon_mode_ether_setup() - Update monitor mode struct net_device. 3185 * @dev: Handle to struct net_device to be updated. 3186 * 3187 * Return: None 3188 */ hdd_mon_mode_ether_setup(struct net_device * dev)3189 static void hdd_mon_mode_ether_setup(struct net_device *dev) 3190 { 3191 dev->header_ops = NULL; 3192 dev->type = ARPHRD_IEEE80211_RADIOTAP; 3193 dev->hard_header_len = ETH_HLEN; 3194 dev->mtu = ETH_DATA_LEN; 3195 dev->addr_len = ETH_ALEN; 3196 dev->tx_queue_len = 1000; /* Ethernet wants good queues */ 3197 dev->flags = IFF_BROADCAST|IFF_MULTICAST; 3198 dev->priv_flags |= IFF_TX_SKB_SHARING; 3199 3200 memset(dev->broadcast, 0xFF, ETH_ALEN); 3201 } 3202 3203 #ifdef FEATURE_MONITOR_MODE_SUPPORT 3204 /** 3205 * hdd_mon_turn_off_ps_and_wow() - Update monitor mode struct net_device. 3206 * @hdd_ctx: Pointer to HDD context. 3207 * 3208 * Return: None 3209 */ hdd_mon_turn_off_ps_and_wow(struct hdd_context * hdd_ctx)3210 static void hdd_mon_turn_off_ps_and_wow(struct hdd_context *hdd_ctx) 3211 { 3212 ucfg_pmo_set_power_save_mode(hdd_ctx->psoc, 3213 PMO_PS_ADVANCED_POWER_SAVE_DISABLE); 3214 ucfg_pmo_set_wow_enable(hdd_ctx->psoc, PMO_WOW_DISABLE_BOTH); 3215 } 3216 3217 /** 3218 * __hdd_mon_open() - HDD Open function 3219 * @dev: Pointer to net_device structure 3220 * 3221 * This is called in response to ifconfig up 3222 * 3223 * Return: 0 for success; non-zero for failure 3224 */ __hdd_mon_open(struct net_device * dev)3225 static int __hdd_mon_open(struct net_device *dev) 3226 { 3227 int ret; 3228 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev); 3229 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); 3230 struct bbm_params param = {0}; 3231 3232 hdd_enter_dev(dev); 3233 3234 if (test_bit(DEVICE_IFACE_OPENED, &adapter->event_flags)) { 3235 hdd_debug_rl("Monitor interface is already up"); 3236 return 0; 3237 } 3238 3239 ret = wlan_hdd_validate_context(hdd_ctx); 3240 if (ret) 3241 return ret; 3242 3243 hdd_mon_mode_ether_setup(dev); 3244 3245 if (con_mode == QDF_GLOBAL_MONITOR_MODE || 3246 ucfg_mlme_is_sta_mon_conc_supported(hdd_ctx->psoc) || 3247 ucfg_dp_is_local_pkt_capture_enabled(hdd_ctx->psoc)) { 3248 ret = hdd_trigger_psoc_idle_restart(hdd_ctx); 3249 if (ret) { 3250 hdd_err("Failed to start WLAN modules return"); 3251 return ret; 3252 } 3253 hdd_err("hdd_wlan_start_modules() successful !"); 3254 3255 if ((!test_bit(SME_SESSION_OPENED, 3256 &adapter->deflink->link_flags)) || 3257 (policy_mgr_is_sta_mon_concurrency(hdd_ctx->psoc))) { 3258 ret = hdd_start_adapter(adapter, true); 3259 if (ret) { 3260 hdd_err("Failed to start adapter :%d", 3261 adapter->device_mode); 3262 return ret; 3263 } 3264 hdd_err("hdd_start_adapters() successful !"); 3265 } 3266 hdd_mon_turn_off_ps_and_wow(hdd_ctx); 3267 set_bit(DEVICE_IFACE_OPENED, &adapter->event_flags); 3268 } 3269 3270 if (con_mode != QDF_GLOBAL_MONITOR_MODE && 3271 (ucfg_mlme_is_sta_mon_conc_supported(hdd_ctx->psoc) || 3272 ucfg_dp_is_local_pkt_capture_enabled(hdd_ctx->psoc))) { 3273 hdd_info("Acquire wakelock for STA + monitor mode"); 3274 3275 qdf_wake_lock_acquire(&hdd_ctx->monitor_mode_wakelock, 3276 WIFI_POWER_EVENT_WAKELOCK_MONITOR_MODE); 3277 hdd_lpc_disable_powersave(hdd_ctx); 3278 qdf_runtime_pm_prevent_suspend( 3279 &hdd_ctx->runtime_context.monitor_mode); 3280 } 3281 3282 ret = hdd_set_mon_rx_cb(dev); 3283 3284 if (!ret) 3285 ret = hdd_enable_monitor_mode(dev); 3286 3287 if (!ret) { 3288 param.policy = BBM_DRIVER_MODE_POLICY; 3289 param.policy_info.driver_mode = QDF_GLOBAL_MONITOR_MODE; 3290 ucfg_dp_bbm_apply_independent_policy(hdd_ctx->psoc, ¶m); 3291 ucfg_dp_set_current_throughput_level(hdd_ctx->psoc, 3292 PLD_BUS_WIDTH_VERY_HIGH); 3293 } 3294 3295 return ret; 3296 } 3297 3298 /** 3299 * hdd_mon_open() - Wrapper function for __hdd_mon_open to protect it from SSR 3300 * @net_dev: Pointer to net_device structure 3301 * 3302 * This is called in response to ifconfig up 3303 * 3304 * Return: 0 for success; non-zero for failure 3305 */ hdd_mon_open(struct net_device * net_dev)3306 static int hdd_mon_open(struct net_device *net_dev) 3307 { 3308 int errno; 3309 struct osif_vdev_sync *vdev_sync; 3310 3311 errno = osif_vdev_sync_trans_start(net_dev, &vdev_sync); 3312 if (errno) 3313 return errno; 3314 3315 errno = __hdd_mon_open(net_dev); 3316 3317 osif_vdev_sync_trans_stop(vdev_sync); 3318 3319 return errno; 3320 } 3321 #endif 3322 3323 #ifdef WLAN_FEATURE_PKT_CAPTURE 3324 /** 3325 * __hdd_pktcapture_open() - HDD Open function 3326 * @dev: Pointer to net_device structure 3327 * 3328 * This is called in response to ifconfig up 3329 * 3330 * Return: 0 for success; non-zero for failure 3331 */ __hdd_pktcapture_open(struct net_device * dev)3332 static int __hdd_pktcapture_open(struct net_device *dev) 3333 { 3334 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev); 3335 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); 3336 struct hdd_adapter *sta_adapter; 3337 QDF_STATUS status; 3338 struct wlan_objmgr_vdev *vdev; 3339 int ret; 3340 3341 hdd_enter_dev(dev); 3342 3343 ret = wlan_hdd_validate_context(hdd_ctx); 3344 if (ret) 3345 return ret; 3346 3347 sta_adapter = hdd_get_adapter(hdd_ctx, QDF_STA_MODE); 3348 if (!sta_adapter) { 3349 hdd_err("No station interface found"); 3350 return -EINVAL; 3351 } 3352 3353 vdev = hdd_objmgr_get_vdev_by_user(sta_adapter->deflink, WLAN_OSIF_ID); 3354 if (!vdev) 3355 return -EINVAL; 3356 3357 hdd_mon_mode_ether_setup(dev); 3358 3359 status = ucfg_dp_register_pkt_capture_callbacks(vdev); 3360 ret = qdf_status_to_os_return(status); 3361 if (ret) { 3362 hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_ID); 3363 return ret; 3364 } 3365 3366 adapter->deflink->vdev = vdev; 3367 set_bit(DEVICE_IFACE_OPENED, &adapter->event_flags); 3368 sta_adapter->mon_adapter = adapter; 3369 3370 return ret; 3371 } 3372 3373 /** 3374 * hdd_pktcapture_open() - Wrapper function for hdd_pktcapture_open to 3375 * protect it from SSR 3376 * @net_dev: Pointer to net_device structure 3377 * 3378 * This is called in response to ifconfig up 3379 * 3380 * Return: 0 for success; non-zero for failure 3381 */ hdd_pktcapture_open(struct net_device * net_dev)3382 static int hdd_pktcapture_open(struct net_device *net_dev) 3383 { 3384 int errno; 3385 struct osif_vdev_sync *vdev_sync; 3386 3387 errno = osif_vdev_sync_trans_start(net_dev, &vdev_sync); 3388 if (errno) 3389 return errno; 3390 3391 errno = __hdd_pktcapture_open(net_dev); 3392 3393 osif_vdev_sync_trans_stop(vdev_sync); 3394 3395 return errno; 3396 } 3397 3398 /** 3399 * hdd_unmap_monitor_interface_vdev() - unmap monitor interface vdev and 3400 * deregister packet capture callbacks 3401 * @sta_adapter: station adapter 3402 * 3403 * Return: void 3404 */ 3405 static void hdd_unmap_monitor_interface_vdev(struct hdd_adapter * sta_adapter)3406 hdd_unmap_monitor_interface_vdev(struct hdd_adapter *sta_adapter) 3407 { 3408 struct hdd_adapter *mon_adapter = sta_adapter->mon_adapter; 3409 3410 if (mon_adapter && hdd_is_interface_up(mon_adapter)) { 3411 ucfg_pkt_capture_deregister_callbacks( 3412 mon_adapter->deflink->vdev); 3413 hdd_objmgr_put_vdev_by_user(mon_adapter->deflink->vdev, 3414 WLAN_OSIF_ID); 3415 mon_adapter->deflink->vdev = NULL; 3416 hdd_reset_monitor_interface(sta_adapter); 3417 } 3418 } 3419 3420 /** 3421 * hdd_map_monitor_interface_vdev() - Map monitor interface vdev and 3422 * register packet capture callbacks 3423 * @sta_adapter: Station adapter 3424 * 3425 * Return: None 3426 */ hdd_map_monitor_interface_vdev(struct hdd_adapter * sta_adapter)3427 static void hdd_map_monitor_interface_vdev(struct hdd_adapter *sta_adapter) 3428 { 3429 struct hdd_adapter *mon_adapter; 3430 QDF_STATUS status; 3431 struct wlan_objmgr_vdev *vdev; 3432 int ret; 3433 3434 mon_adapter = hdd_get_adapter(sta_adapter->hdd_ctx, QDF_MONITOR_MODE); 3435 if (!mon_adapter) { 3436 hdd_debug("No monitor interface found"); 3437 return; 3438 } 3439 3440 if (!mon_adapter || !hdd_is_interface_up(mon_adapter)) { 3441 hdd_debug("Monitor interface is not up\n"); 3442 return; 3443 } 3444 3445 if (!wlan_hdd_is_session_type_monitor(mon_adapter->device_mode)) 3446 return; 3447 3448 vdev = hdd_objmgr_get_vdev_by_user(sta_adapter->deflink, WLAN_OSIF_ID); 3449 if (!vdev) 3450 return; 3451 3452 status = ucfg_dp_register_pkt_capture_callbacks(vdev); 3453 ret = qdf_status_to_os_return(status); 3454 if (ret) { 3455 hdd_err("Failed registering packet capture callbacks"); 3456 hdd_objmgr_put_vdev_by_user(vdev, 3457 WLAN_OSIF_ID); 3458 return; 3459 } 3460 3461 mon_adapter->deflink->vdev = vdev; 3462 sta_adapter->mon_adapter = mon_adapter; 3463 } 3464 hdd_reset_monitor_interface(struct hdd_adapter * sta_adapter)3465 void hdd_reset_monitor_interface(struct hdd_adapter *sta_adapter) 3466 { 3467 sta_adapter->mon_adapter = NULL; 3468 } 3469 3470 struct hdd_adapter * hdd_is_pkt_capture_mon_enable(struct hdd_adapter * sta_adapter)3471 hdd_is_pkt_capture_mon_enable(struct hdd_adapter *sta_adapter) 3472 { 3473 return sta_adapter->mon_adapter; 3474 } 3475 #else 3476 static inline void hdd_unmap_monitor_interface_vdev(struct hdd_adapter * sta_adapter)3477 hdd_unmap_monitor_interface_vdev(struct hdd_adapter *sta_adapter) 3478 { 3479 } 3480 3481 static inline void hdd_map_monitor_interface_vdev(struct hdd_adapter * sta_adapter)3482 hdd_map_monitor_interface_vdev(struct hdd_adapter *sta_adapter) 3483 { 3484 } 3485 #endif 3486 3487 static QDF_STATUS wlan_hdd_update_dbs_scan_and_fw_mode_config(void)3488 wlan_hdd_update_dbs_scan_and_fw_mode_config(void) 3489 { 3490 struct policy_mgr_dual_mac_config cfg = {0}; 3491 QDF_STATUS status; 3492 uint32_t chnl_sel_logic_conc = 0; 3493 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 3494 uint8_t dual_mac_feature = DISABLE_DBS_CXN_AND_SCAN; 3495 3496 if (!hdd_ctx) 3497 return QDF_STATUS_E_FAILURE; 3498 3499 /* 3500 * ROME platform doesn't support any DBS related commands in FW, 3501 * so if driver sends wmi command with dual_mac_config with all set to 3502 * 0 then FW wouldn't respond back and driver would timeout on waiting 3503 * for response. Check if FW supports DBS to eliminate ROME vs 3504 * NON-ROME platform. 3505 */ 3506 if (!policy_mgr_find_if_fw_supports_dbs(hdd_ctx->psoc)) 3507 return QDF_STATUS_SUCCESS; 3508 3509 if (hdd_ctx->is_dual_mac_cfg_updated) { 3510 hdd_debug("dual mac config has already been updated, skip"); 3511 return QDF_STATUS_SUCCESS; 3512 } 3513 3514 cfg.scan_config = 0; 3515 cfg.fw_mode_config = 0; 3516 cfg.set_dual_mac_cb = policy_mgr_soc_set_dual_mac_cfg_cb; 3517 if (policy_mgr_is_hw_dbs_capable(hdd_ctx->psoc)) { 3518 status = 3519 ucfg_policy_mgr_get_chnl_select_plcy(hdd_ctx->psoc, 3520 &chnl_sel_logic_conc); 3521 if (status != QDF_STATUS_SUCCESS) { 3522 hdd_err("can't get chnl sel policy, use def"); 3523 return status; 3524 } 3525 } 3526 status = 3527 ucfg_policy_mgr_get_dual_mac_feature(hdd_ctx->psoc, 3528 &dual_mac_feature); 3529 if (status != QDF_STATUS_SUCCESS) { 3530 hdd_err("ucfg_policy_mgr_get_dual_mac_feature failed, use def"); 3531 return status; 3532 } 3533 3534 if (dual_mac_feature != DISABLE_DBS_CXN_AND_SCAN) { 3535 status = policy_mgr_get_updated_scan_and_fw_mode_config( 3536 hdd_ctx->psoc, &cfg.scan_config, 3537 &cfg.fw_mode_config, 3538 dual_mac_feature, 3539 chnl_sel_logic_conc); 3540 3541 if (status != QDF_STATUS_SUCCESS) { 3542 hdd_err("wma_get_updated_scan_and_fw_mode_config failed %d", 3543 status); 3544 return status; 3545 } 3546 } 3547 3548 hdd_debug("send scan_cfg: 0x%x fw_mode_cfg: 0x%x to fw", 3549 cfg.scan_config, cfg.fw_mode_config); 3550 3551 status = sme_soc_set_dual_mac_config(cfg); 3552 if (QDF_IS_STATUS_ERROR(status)) { 3553 hdd_err("sme_soc_set_dual_mac_config failed %d", status); 3554 return status; 3555 } 3556 hdd_ctx->is_dual_mac_cfg_updated = true; 3557 3558 return QDF_STATUS_SUCCESS; 3559 } 3560 3561 /** 3562 * hdd_max_sta_interface_up_count_reached() - check sta/p2p_cli vdev count 3563 * @adapter: HDD adapter 3564 * 3565 * Return: true if vdev limit reached 3566 */ hdd_max_sta_interface_up_count_reached(struct hdd_adapter * adapter)3567 static bool hdd_max_sta_interface_up_count_reached(struct hdd_adapter *adapter) 3568 { 3569 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); 3570 struct hdd_adapter *temp_adapter = NULL, *next_adapter = NULL; 3571 uint8_t intf_count = 0; 3572 wlan_net_dev_ref_dbgid dbgid = 3573 NET_DEV_HOLD_MAX_STA_INTERFACE_UP_COUNT_REACHED; 3574 3575 if (0 == CFG_TGT_DEFAULT_MAX_STA_VDEVS) 3576 return false; 3577 3578 /* 3579 * Check for max no of supported STA/P2PCLI VDEVs before 3580 * creating another one. 3581 */ 3582 hdd_for_each_adapter_dev_held_safe(hdd_ctx, temp_adapter, 3583 next_adapter, dbgid) { 3584 if ((temp_adapter != adapter) && 3585 (temp_adapter->dev->flags & IFF_UP) && 3586 ((temp_adapter->device_mode == QDF_STA_MODE) || 3587 (temp_adapter->device_mode == QDF_P2P_CLIENT_MODE))) 3588 intf_count++; 3589 3590 hdd_adapter_dev_put_debug(temp_adapter, dbgid); 3591 } 3592 3593 if (intf_count >= CFG_TGT_DEFAULT_MAX_STA_VDEVS) { 3594 hdd_err("Max limit reached sta vdev-current %d max %d", 3595 intf_count, CFG_TGT_DEFAULT_MAX_STA_VDEVS); 3596 return true; 3597 } 3598 return false; 3599 } 3600 3601 #if (defined(WLAN_FEATURE_11BE_MLO) && defined(CFG80211_11BE_BASIC)) && \ 3602 (defined(CFG80211_IFTYPE_MLO_LINK_SUPPORT) || \ 3603 defined(CFG80211_SINGLE_NETDEV_MULTI_LINK_SUPPORT)) && \ 3604 !defined(WLAN_HDD_MULTI_VDEV_SINGLE_NDEV) hdd_start_link_adapter(struct hdd_adapter * sta_adapter)3605 static int hdd_start_link_adapter(struct hdd_adapter *sta_adapter) 3606 { 3607 int i, ret = 0; 3608 struct hdd_mlo_adapter_info *mlo_adapter_info; 3609 struct hdd_adapter *link_adapter; 3610 3611 hdd_enter_dev(sta_adapter->dev); 3612 mlo_adapter_info = &sta_adapter->mlo_adapter_info; 3613 3614 for (i = 0; i < WLAN_MAX_MLD; i++) { 3615 link_adapter = mlo_adapter_info->link_adapter[i]; 3616 if (!link_adapter) 3617 continue; 3618 if (link_adapter->mlo_adapter_info.associate_with_ml_adapter) { 3619 /* TODO have proper references here */ 3620 qdf_spin_lock_bh(&link_adapter->deflink->vdev_lock); 3621 link_adapter->deflink->vdev = 3622 sta_adapter->deflink->vdev; 3623 link_adapter->deflink->vdev_id = 3624 sta_adapter->deflink->vdev_id; 3625 qdf_spin_unlock_bh(&link_adapter->deflink->vdev_lock); 3626 3627 sta_adapter->link_info[i].vdev_id = 3628 sta_adapter->deflink->vdev_id; 3629 continue; 3630 } 3631 ret = hdd_start_station_adapter(link_adapter); 3632 if (!ret) { 3633 sta_adapter->link_info[i].vdev_id = 3634 link_adapter->deflink->vdev_id; 3635 } 3636 } 3637 3638 hdd_adapter_update_mlo_mgr_mac_addr(sta_adapter); 3639 3640 hdd_exit(); 3641 return ret; 3642 } 3643 hdd_stop_link_adapter(struct hdd_context * hdd_ctx,struct hdd_adapter * sta_adapter)3644 static int hdd_stop_link_adapter(struct hdd_context *hdd_ctx, 3645 struct hdd_adapter *sta_adapter) 3646 { 3647 int i, ret = 0; 3648 struct hdd_mlo_adapter_info *mlo_adapter_info; 3649 struct hdd_adapter *link_adapter; 3650 3651 hdd_enter_dev(sta_adapter->dev); 3652 hdd_debug("Stop adapter for link mode : %s(%d)", 3653 qdf_opmode_str(sta_adapter->device_mode), 3654 sta_adapter->deflink->vdev_id); 3655 3656 mlo_adapter_info = &sta_adapter->mlo_adapter_info; 3657 for (i = 0; i < WLAN_MAX_MLD; i++) { 3658 link_adapter = mlo_adapter_info->link_adapter[i]; 3659 if (!link_adapter) 3660 continue; 3661 3662 if (link_adapter->mlo_adapter_info.associate_with_ml_adapter) { 3663 /* TODO have proper references here */ 3664 qdf_spin_lock_bh(&link_adapter->deflink->vdev_lock); 3665 link_adapter->deflink->vdev = NULL; 3666 link_adapter->deflink->vdev_id = 0xff; 3667 qdf_spin_unlock_bh(&link_adapter->deflink->vdev_lock); 3668 continue; 3669 } 3670 ret = hdd_stop_adapter_ext(hdd_ctx, link_adapter); 3671 } 3672 3673 hdd_exit(); 3674 return ret; 3675 } 3676 #else hdd_start_link_adapter(struct hdd_adapter * link_adapter)3677 static int hdd_start_link_adapter(struct hdd_adapter *link_adapter) 3678 { 3679 return 0; 3680 } 3681 hdd_stop_link_adapter(struct hdd_context * hdd_ctx,struct hdd_adapter * link_adapter)3682 static int hdd_stop_link_adapter(struct hdd_context *hdd_ctx, 3683 struct hdd_adapter *link_adapter) 3684 { 3685 return 0; 3686 } 3687 #endif 3688 3689 /** 3690 * hdd_start_adapter() - Wrapper function for device specific adapter 3691 * @adapter: pointer to HDD adapter 3692 * @rtnl_held: true if rtnl lock is taken, otherwise false 3693 * 3694 * This function is called to start the device specific adapter for 3695 * the mode passed in the adapter's device_mode. 3696 * 3697 * Return: 0 for success; non-zero for failure 3698 */ hdd_start_adapter(struct hdd_adapter * adapter,bool rtnl_held)3699 int hdd_start_adapter(struct hdd_adapter *adapter, bool rtnl_held) 3700 { 3701 3702 int ret; 3703 enum QDF_OPMODE device_mode = adapter->device_mode; 3704 3705 hdd_enter_dev(adapter->dev); 3706 3707 switch (device_mode) { 3708 case QDF_MONITOR_MODE: 3709 ret = hdd_start_station_adapter(adapter); 3710 if (ret) 3711 goto err_start_adapter; 3712 hdd_set_idle_ps_config(adapter->hdd_ctx, false); 3713 break; 3714 case QDF_STA_MODE: 3715 case QDF_P2P_CLIENT_MODE: 3716 if (hdd_max_sta_interface_up_count_reached(adapter)) 3717 goto err_start_adapter; 3718 fallthrough; 3719 case QDF_P2P_DEVICE_MODE: 3720 case QDF_OCB_MODE: 3721 case QDF_NAN_DISC_MODE: 3722 ret = hdd_start_station_adapter(adapter); 3723 if (ret) 3724 goto err_start_adapter; 3725 3726 if (device_mode == QDF_STA_MODE) { 3727 ret = hdd_start_link_adapter(adapter); 3728 if (ret) 3729 hdd_err("Failed to start link adapter:%d", ret); 3730 } 3731 break; 3732 case QDF_P2P_GO_MODE: 3733 case QDF_SAP_MODE: 3734 ret = hdd_start_ap_adapter(adapter, rtnl_held); 3735 if (ret) 3736 goto err_start_adapter; 3737 break; 3738 case QDF_FTM_MODE: 3739 /* vdevs are dynamically managed by firmware in FTM */ 3740 hdd_register_wext(adapter->dev); 3741 goto exit_with_success; 3742 default: 3743 hdd_err("Invalid session type %d", device_mode); 3744 QDF_ASSERT(0); 3745 goto err_start_adapter; 3746 } 3747 3748 if (hdd_set_fw_params(adapter)) 3749 hdd_err("Failed to set the FW params for the adapter!"); 3750 3751 if (adapter->deflink->vdev_id != WLAN_UMAC_VDEV_ID_MAX) { 3752 ret = wlan_hdd_cfg80211_register_frames(adapter); 3753 if (ret < 0) { 3754 hdd_err("Failed to register frames - ret %d", ret); 3755 goto err_start_adapter; 3756 } 3757 } 3758 3759 wlan_hdd_update_dbs_scan_and_fw_mode_config(); 3760 3761 exit_with_success: 3762 hdd_create_adapter_sysfs_files(adapter); 3763 3764 hdd_exit(); 3765 3766 return 0; 3767 3768 err_start_adapter: 3769 return -EINVAL; 3770 } 3771 hdd_update_hw_sw_info(struct hdd_context * hdd_ctx)3772 void hdd_update_hw_sw_info(struct hdd_context *hdd_ctx) 3773 { 3774 void *hif_sc; 3775 size_t target_hw_name_len; 3776 const char *target_hw_name; 3777 uint8_t *buf; 3778 uint32_t buf_len; 3779 3780 hif_sc = cds_get_context(QDF_MODULE_ID_HIF); 3781 if (!hif_sc) 3782 return; 3783 3784 hif_get_hw_info(hif_sc, &hdd_ctx->target_hw_version, 3785 &hdd_ctx->target_hw_revision, 3786 &target_hw_name); 3787 3788 qdf_mem_zero(hdd_ctx->target_hw_name, MAX_TGT_HW_NAME_LEN); 3789 3790 target_hw_name_len = strlen(target_hw_name) + 1; 3791 3792 if (target_hw_name_len <= MAX_TGT_HW_NAME_LEN) { 3793 qdf_mem_copy(hdd_ctx->target_hw_name, target_hw_name, 3794 target_hw_name_len); 3795 } else { 3796 hdd_err("target_hw_name_len is greater than MAX_TGT_HW_NAME_LEN"); 3797 return; 3798 } 3799 3800 hdd_debug("target_hw_name = %s", hdd_ctx->target_hw_name); 3801 3802 buf = qdf_mem_malloc(WE_MAX_STR_LEN); 3803 if (buf) { 3804 buf_len = hdd_wlan_get_version(hdd_ctx, WE_MAX_STR_LEN, buf); 3805 hdd_nofl_debug("%s", buf); 3806 qdf_mem_free(buf); 3807 } 3808 } 3809 3810 /** 3811 * hdd_update_cds_ac_specs_params() - update cds ac_specs params 3812 * @hdd_ctx: Pointer to hdd context 3813 * 3814 * Return: none 3815 */ 3816 static void hdd_update_cds_ac_specs_params(struct hdd_context * hdd_ctx)3817 hdd_update_cds_ac_specs_params(struct hdd_context *hdd_ctx) 3818 { 3819 uint8_t tx_sched_wrr_param[TX_SCHED_WRR_PARAMS_NUM] = {0}; 3820 qdf_size_t out_size = 0; 3821 int i; 3822 struct cds_context *cds_ctx; 3823 3824 if (!hdd_ctx) 3825 return; 3826 3827 if (!hdd_ctx->config) { 3828 /* Do nothing if hdd_ctx is invalid */ 3829 hdd_err("Warning: hdd_ctx->cfg_ini is NULL"); 3830 return; 3831 } 3832 3833 cds_ctx = cds_get_context(QDF_MODULE_ID_QDF); 3834 if (!cds_ctx) 3835 return; 3836 3837 for (i = 0; i < QCA_WLAN_AC_ALL; i++) { 3838 switch (i) { 3839 case QCA_WLAN_AC_BE: 3840 qdf_uint8_array_parse( 3841 cfg_get(hdd_ctx->psoc, 3842 CFG_DP_ENABLE_TX_SCHED_WRR_BE), 3843 tx_sched_wrr_param, 3844 sizeof(tx_sched_wrr_param), 3845 &out_size); 3846 break; 3847 case QCA_WLAN_AC_BK: 3848 qdf_uint8_array_parse( 3849 cfg_get(hdd_ctx->psoc, 3850 CFG_DP_ENABLE_TX_SCHED_WRR_BK), 3851 tx_sched_wrr_param, 3852 sizeof(tx_sched_wrr_param), 3853 &out_size); 3854 break; 3855 case QCA_WLAN_AC_VI: 3856 qdf_uint8_array_parse( 3857 cfg_get(hdd_ctx->psoc, 3858 CFG_DP_ENABLE_TX_SCHED_WRR_VI), 3859 tx_sched_wrr_param, 3860 sizeof(tx_sched_wrr_param), 3861 &out_size); 3862 break; 3863 case QCA_WLAN_AC_VO: 3864 qdf_uint8_array_parse( 3865 cfg_get(hdd_ctx->psoc, 3866 CFG_DP_ENABLE_TX_SCHED_WRR_VO), 3867 tx_sched_wrr_param, 3868 sizeof(tx_sched_wrr_param), 3869 &out_size); 3870 break; 3871 default: 3872 break; 3873 } 3874 3875 if (out_size == TX_SCHED_WRR_PARAMS_NUM) { 3876 cds_ctx->ac_specs[i].wrr_skip_weight = 3877 tx_sched_wrr_param[0]; 3878 cds_ctx->ac_specs[i].credit_threshold = 3879 tx_sched_wrr_param[1]; 3880 cds_ctx->ac_specs[i].send_limit = 3881 tx_sched_wrr_param[2]; 3882 cds_ctx->ac_specs[i].credit_reserve = 3883 tx_sched_wrr_param[3]; 3884 cds_ctx->ac_specs[i].discard_weight = 3885 tx_sched_wrr_param[4]; 3886 } 3887 3888 out_size = 0; 3889 } 3890 } 3891 hdd_wlan_get_version(struct hdd_context * hdd_ctx,const size_t version_len,uint8_t * version)3892 uint32_t hdd_wlan_get_version(struct hdd_context *hdd_ctx, 3893 const size_t version_len, uint8_t *version) 3894 { 3895 uint32_t size; 3896 uint8_t reg_major = 0, reg_minor = 0, bdf_major = 0, bdf_minor = 0; 3897 struct target_psoc_info *tgt_hdl; 3898 3899 if (!hdd_ctx) { 3900 hdd_err("Invalid context, HDD context is null"); 3901 return 0; 3902 } 3903 3904 if (!version || version_len == 0) { 3905 hdd_err("Invalid buffer pointr or buffer len\n"); 3906 return 0; 3907 } 3908 tgt_hdl = wlan_psoc_get_tgt_if_handle(hdd_ctx->psoc); 3909 if (tgt_hdl) 3910 target_psoc_get_version_info(tgt_hdl, ®_major, ®_minor, 3911 &bdf_major, &bdf_minor); 3912 3913 size = scnprintf(version, version_len, 3914 "Host SW:%s, FW:%d.%d.%d.%d.%d.%d, HW:%s, Board ver: %x Ref design id: %x, Customer id: %x, Project id: %x, Board Data Rev: %x, REG DB: %u:%u, BDF REG DB: %u:%u", 3915 QWLAN_VERSIONSTR, 3916 hdd_ctx->fw_version_info.major_spid, 3917 hdd_ctx->fw_version_info.minor_spid, 3918 hdd_ctx->fw_version_info.siid, 3919 hdd_ctx->fw_version_info.rel_id, 3920 hdd_ctx->fw_version_info.crmid, 3921 hdd_ctx->fw_version_info.sub_id, 3922 hdd_ctx->target_hw_name, 3923 hdd_ctx->hw_bd_info.bdf_version, 3924 hdd_ctx->hw_bd_info.ref_design_id, 3925 hdd_ctx->hw_bd_info.customer_id, 3926 hdd_ctx->hw_bd_info.project_id, 3927 hdd_ctx->hw_bd_info.board_data_rev, 3928 reg_major, reg_minor, bdf_major, bdf_minor); 3929 3930 return size; 3931 } 3932 hdd_set_11ax_rate(struct hdd_adapter * adapter,int set_value,struct sap_config * sap_config)3933 int hdd_set_11ax_rate(struct hdd_adapter *adapter, int set_value, 3934 struct sap_config *sap_config) 3935 { 3936 uint8_t preamble = 0, nss = 0, rix = 0; 3937 int ret; 3938 mac_handle_t mac_handle = adapter->hdd_ctx->mac_handle; 3939 3940 if (!sap_config) { 3941 if (!sme_is_feature_supported_by_fw(DOT11AX)) { 3942 hdd_err("Target does not support 11ax"); 3943 return -EIO; 3944 } 3945 } else if (sap_config->SapHw_mode != eCSR_DOT11_MODE_11ax && 3946 sap_config->SapHw_mode != eCSR_DOT11_MODE_11ax_ONLY) { 3947 hdd_err("Invalid hw mode, SAP hw_mode= 0x%x, ch_freq = %d", 3948 sap_config->SapHw_mode, sap_config->chan_freq); 3949 return -EIO; 3950 } 3951 3952 if (set_value != 0xffff) { 3953 rix = RC_2_RATE_IDX_11AX(set_value); 3954 preamble = WMI_RATE_PREAMBLE_HE; 3955 nss = HT_RC_2_STREAMS_11AX(set_value); 3956 3957 set_value = hdd_assemble_rate_code(preamble, nss, rix); 3958 } else { 3959 ret = sme_set_auto_rate_he_ltf(mac_handle, 3960 adapter->deflink->vdev_id, 3961 QCA_WLAN_HE_LTF_AUTO); 3962 } 3963 3964 hdd_info("SET_11AX_RATE val %d rix %d preamble %x nss %d", 3965 set_value, rix, preamble, nss); 3966 3967 ret = wma_cli_set_command(adapter->deflink->vdev_id, 3968 wmi_vdev_param_fixed_rate, 3969 set_value, VDEV_CMD); 3970 3971 return ret; 3972 } 3973 hdd_assemble_rate_code(uint8_t preamble,uint8_t nss,uint8_t rate)3974 int hdd_assemble_rate_code(uint8_t preamble, uint8_t nss, uint8_t rate) 3975 { 3976 return ucfg_mlme_assemble_rate_code(preamble, nss, rate); 3977 } 3978 3979 #ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH wlan_hdd_get_mode_for_non_connected_vdev(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id)3980 static enum policy_mgr_con_mode wlan_hdd_get_mode_for_non_connected_vdev( 3981 struct wlan_objmgr_psoc *psoc, uint8_t vdev_id) 3982 { 3983 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 3984 struct hdd_adapter *adapter; 3985 enum policy_mgr_con_mode mode; 3986 struct wlan_hdd_link_info *link_info; 3987 3988 link_info = hdd_get_link_info_by_vdev(hdd_ctx, vdev_id); 3989 if (!link_info) { 3990 hdd_err("Invalid vdev"); 3991 return PM_MAX_NUM_OF_MODE; 3992 } 3993 3994 adapter = link_info->adapter; 3995 mode = policy_mgr_qdf_opmode_to_pm_con_mode(psoc, 3996 adapter->device_mode, 3997 vdev_id); 3998 return mode; 3999 } 4000 4001 /** 4002 * hdd_is_chan_switch_in_progress() - Check if any adapter has channel switch in 4003 * progress 4004 * 4005 * Return: true, if any adapter has channel switch in 4006 * progress else false 4007 */ hdd_is_chan_switch_in_progress(void)4008 static bool hdd_is_chan_switch_in_progress(void) 4009 { 4010 struct hdd_adapter *adapter = NULL, *next_adapter = NULL; 4011 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 4012 wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_IS_CHAN_SWITCH_IN_PROGRESS; 4013 struct hdd_ap_ctx *ap_ctx; 4014 struct wlan_hdd_link_info *link_info; 4015 bool is_restart; 4016 struct wlan_objmgr_vdev *vdev; 4017 4018 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 4019 dbgid) { 4020 if (adapter->device_mode != QDF_SAP_MODE && 4021 adapter->device_mode != QDF_P2P_GO_MODE) 4022 goto next_adapter; 4023 4024 hdd_adapter_for_each_active_link_info(adapter, link_info) { 4025 ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(link_info); 4026 vdev = hdd_objmgr_get_vdev_by_user(link_info, 4027 WLAN_OSIF_ID); 4028 if (!vdev) 4029 continue; 4030 is_restart = false; 4031 if (wlan_vdev_is_restart_progress(vdev) == 4032 QDF_STATUS_SUCCESS) { 4033 hdd_debug("vdev: %d restart in progress", 4034 wlan_vdev_get_id(vdev)); 4035 is_restart = true; 4036 } 4037 hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_ID); 4038 4039 if (is_restart || 4040 qdf_atomic_read(&ap_ctx->ch_switch_in_progress)) { 4041 hdd_debug("channel switch progress for vdev_id %d", 4042 link_info->vdev_id); 4043 hdd_adapter_dev_put_debug(adapter, dbgid); 4044 if (next_adapter) 4045 hdd_adapter_dev_put_debug(next_adapter, 4046 dbgid); 4047 return true; 4048 } 4049 } 4050 next_adapter: 4051 hdd_adapter_dev_put_debug(adapter, dbgid); 4052 } 4053 4054 return false; 4055 } 4056 4057 /** 4058 * hdd_is_cac_in_progress() - Check if any SAP connection is performing 4059 * CAC on DFS channel 4060 * 4061 * Return: true, if any of existing SAP is performing CAC 4062 * or else false 4063 */ hdd_is_cac_in_progress(void)4064 static bool hdd_is_cac_in_progress(void) 4065 { 4066 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 4067 4068 if (!hdd_ctx) 4069 return false; 4070 4071 return (hdd_ctx->dev_dfs_cac_status == DFS_CAC_IN_PROGRESS); 4072 } 4073 4074 static QDF_STATUS wlan_hdd_set_tx_rx_nss_cb(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id,uint8_t tx_nss,uint8_t rx_nss)4075 wlan_hdd_set_tx_rx_nss_cb(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, 4076 uint8_t tx_nss, uint8_t rx_nss) 4077 { 4078 struct wlan_hdd_link_info *link_info; 4079 4080 link_info = wlan_hdd_get_link_info_from_vdev(psoc, vdev_id); 4081 if (!link_info) { 4082 hdd_err("Invalid vdev %d", vdev_id); 4083 return QDF_STATUS_E_FAILURE; 4084 } 4085 4086 return hdd_update_nss(link_info, tx_nss, rx_nss); 4087 } 4088 hdd_register_policy_manager_callback(struct wlan_objmgr_psoc * psoc)4089 static void hdd_register_policy_manager_callback( 4090 struct wlan_objmgr_psoc *psoc) 4091 { 4092 struct policy_mgr_hdd_cbacks hdd_cbacks; 4093 4094 qdf_mem_zero(&hdd_cbacks, sizeof(hdd_cbacks)); 4095 hdd_cbacks.sap_restart_chan_switch_cb = 4096 hdd_sap_restart_chan_switch_cb; 4097 hdd_cbacks.wlan_hdd_get_channel_for_sap_restart = 4098 wlan_hdd_get_channel_for_sap_restart; 4099 hdd_cbacks.get_mode_for_non_connected_vdev = 4100 wlan_hdd_get_mode_for_non_connected_vdev; 4101 hdd_cbacks.hdd_get_device_mode = hdd_get_device_mode; 4102 hdd_cbacks.hdd_is_chan_switch_in_progress = 4103 hdd_is_chan_switch_in_progress; 4104 hdd_cbacks.hdd_is_cac_in_progress = 4105 hdd_is_cac_in_progress; 4106 hdd_cbacks.wlan_hdd_set_sap_csa_reason = 4107 wlan_hdd_set_sap_csa_reason; 4108 hdd_cbacks.hdd_get_ap_6ghz_capable = hdd_get_ap_6ghz_capable; 4109 hdd_cbacks.wlan_hdd_indicate_active_ndp_cnt = 4110 hdd_indicate_active_ndp_cnt; 4111 hdd_cbacks.wlan_get_ap_prefer_conc_ch_params = 4112 wlan_get_ap_prefer_conc_ch_params; 4113 hdd_cbacks.wlan_get_sap_acs_band = 4114 wlan_get_sap_acs_band; 4115 hdd_cbacks.wlan_check_cc_intf_cb = wlan_hdd_check_cc_intf_cb; 4116 hdd_cbacks.wlan_set_tx_rx_nss_cb = wlan_hdd_set_tx_rx_nss_cb; 4117 4118 if (QDF_STATUS_SUCCESS != 4119 policy_mgr_register_hdd_cb(psoc, &hdd_cbacks)) { 4120 hdd_err("HDD callback registration with policy manager failed"); 4121 } 4122 } 4123 #else hdd_register_policy_manager_callback(struct wlan_objmgr_psoc * psoc)4124 static void hdd_register_policy_manager_callback( 4125 struct wlan_objmgr_psoc *psoc) 4126 { 4127 } 4128 #endif 4129 4130 #ifdef WLAN_SUPPORT_GAP_LL_PS_MODE hdd_register_green_ap_callback(struct wlan_objmgr_pdev * pdev)4131 static void hdd_register_green_ap_callback(struct wlan_objmgr_pdev *pdev) 4132 { 4133 struct green_ap_hdd_callback hdd_cback; 4134 qdf_mem_zero(&hdd_cback, sizeof(hdd_cback)); 4135 4136 hdd_cback.send_event = wlan_hdd_send_green_ap_ll_ps_event; 4137 4138 if (QDF_STATUS_SUCCESS != 4139 green_ap_register_hdd_callback(pdev, &hdd_cback)) { 4140 hdd_err("HDD callback registration for Green AP failed"); 4141 } 4142 } 4143 #else hdd_register_green_ap_callback(struct wlan_objmgr_pdev * pdev)4144 static inline void hdd_register_green_ap_callback(struct wlan_objmgr_pdev *pdev) 4145 { 4146 } 4147 #endif 4148 4149 #ifdef WLAN_FEATURE_NAN 4150 #ifdef WLAN_FEATURE_SR hdd_register_sr_concurrency_cb(struct nan_callbacks * cb_obj)4151 static void hdd_register_sr_concurrency_cb(struct nan_callbacks *cb_obj) 4152 { 4153 cb_obj->nan_sr_concurrency_update = hdd_nan_sr_concurrency_update; 4154 } 4155 #else hdd_register_sr_concurrency_cb(struct nan_callbacks * cb_obj)4156 static void hdd_register_sr_concurrency_cb(struct nan_callbacks *cb_obj) 4157 {} 4158 #endif hdd_nan_register_callbacks(struct hdd_context * hdd_ctx)4159 static void hdd_nan_register_callbacks(struct hdd_context *hdd_ctx) 4160 { 4161 struct nan_callbacks cb_obj = {0}; 4162 4163 cb_obj.ndi_open = hdd_ndi_open; 4164 cb_obj.ndi_close = hdd_ndi_close; 4165 cb_obj.ndi_set_mode = hdd_ndi_set_mode; 4166 cb_obj.ndi_start = hdd_ndi_start; 4167 cb_obj.ndi_delete = hdd_ndi_delete; 4168 cb_obj.drv_ndi_create_rsp_handler = hdd_ndi_drv_ndi_create_rsp_handler; 4169 cb_obj.drv_ndi_delete_rsp_handler = hdd_ndi_drv_ndi_delete_rsp_handler; 4170 4171 cb_obj.new_peer_ind = hdd_ndp_new_peer_handler; 4172 cb_obj.peer_departed_ind = hdd_ndp_peer_departed_handler; 4173 4174 cb_obj.nan_concurrency_update = hdd_nan_concurrency_update; 4175 cb_obj.set_mc_list = hdd_update_multicast_list; 4176 4177 hdd_register_sr_concurrency_cb(&cb_obj); 4178 4179 os_if_nan_register_hdd_callbacks(hdd_ctx->psoc, &cb_obj); 4180 } 4181 #else hdd_nan_register_callbacks(struct hdd_context * hdd_ctx)4182 static inline void hdd_nan_register_callbacks(struct hdd_context *hdd_ctx) 4183 { 4184 } 4185 #endif 4186 4187 #ifdef CONFIG_LEAK_DETECTION 4188 /** 4189 * hdd_check_for_leaks() - Perform runtime memory leak checks 4190 * @hdd_ctx: the global HDD context 4191 * @is_ssr: true if SSR is in progress 4192 * 4193 * This API triggers runtime memory leak detection. This feature enforces the 4194 * policy that any memory allocated at runtime must also be released at runtime. 4195 * 4196 * Allocating memory at runtime and releasing it at unload is effectively a 4197 * memory leak for configurations which never unload (e.g. LONU, statically 4198 * compiled driver). Such memory leaks are NOT false positives, and must be 4199 * fixed. 4200 * 4201 * Return: None 4202 */ hdd_check_for_leaks(struct hdd_context * hdd_ctx,bool is_ssr)4203 static void hdd_check_for_leaks(struct hdd_context *hdd_ctx, bool is_ssr) 4204 { 4205 /* DO NOT REMOVE these checks; for false positives, read above first */ 4206 4207 wlan_objmgr_psoc_check_for_leaks(hdd_ctx->psoc); 4208 4209 /* many adapter resources are not freed by design during SSR */ 4210 if (is_ssr) 4211 return; 4212 4213 qdf_wake_lock_check_for_leaks(); 4214 qdf_delayed_work_check_for_leaks(); 4215 qdf_mc_timer_check_for_leaks(); 4216 qdf_nbuf_map_check_for_leaks(); 4217 qdf_periodic_work_check_for_leaks(); 4218 qdf_mem_check_for_leaks(); 4219 } 4220 4221 /** 4222 * hdd_debug_domain_set() - Set qdf debug domain 4223 * @domain: debug domain to be set 4224 * 4225 * In the scenario of system reboot, it may have thread accessing debug domain 4226 * for memory allocation/free, other than the one trying to change it. 4227 * If debug domain is changed after a memory allocation but before the free, 4228 * it will hit debug domain mismatch assertion in memory free. 4229 * To avoid such assertion, skip debug domain transition if system reboot is 4230 * in progress. 4231 * 4232 * Return: 0 if the specified debug domain has been set, -EBUSY otherwise 4233 */ hdd_debug_domain_set(enum qdf_debug_domain domain)4234 static int hdd_debug_domain_set(enum qdf_debug_domain domain) 4235 { 4236 int ret = 0; 4237 4238 if (cds_sys_reboot_protect()) { 4239 hdd_info("System is rebooting, skip debug domain transition"); 4240 ret = -EBUSY; 4241 } else { 4242 qdf_debug_domain_set(domain); 4243 } 4244 4245 cds_sys_reboot_unprotect(); 4246 4247 return ret; 4248 } 4249 4250 #define hdd_debug_domain_get() qdf_debug_domain_get() 4251 #else hdd_check_for_objmgr_peer_leaks(struct wlan_objmgr_psoc * psoc)4252 static void hdd_check_for_objmgr_peer_leaks(struct wlan_objmgr_psoc *psoc) 4253 { 4254 uint32_t vdev_id; 4255 struct wlan_objmgr_vdev *vdev; 4256 struct wlan_objmgr_peer *peer; 4257 4258 /* get module id which cause the leak and release ref */ 4259 wlan_objmgr_for_each_psoc_vdev(psoc, vdev_id, vdev) { 4260 wlan_objmgr_for_each_vdev_peer(vdev, peer) { 4261 qdf_atomic_t *ref_id_dbg; 4262 int ref_id; 4263 int32_t refs; 4264 4265 ref_id_dbg = vdev->vdev_objmgr.ref_id_dbg; 4266 wlan_objmgr_for_each_refs(ref_id_dbg, ref_id, refs) 4267 wlan_objmgr_peer_release_ref(peer, ref_id); 4268 } 4269 } 4270 } 4271 hdd_check_for_objmgr_leaks(struct hdd_context * hdd_ctx)4272 static void hdd_check_for_objmgr_leaks(struct hdd_context *hdd_ctx) 4273 { 4274 uint32_t vdev_id, pdev_id; 4275 struct wlan_objmgr_psoc *psoc; 4276 struct wlan_objmgr_vdev *vdev; 4277 struct wlan_objmgr_pdev *pdev; 4278 /* 4279 * leak detection is disabled, force release the references for the wlan 4280 * to recover cleanly. 4281 */ 4282 psoc = hdd_ctx->psoc; 4283 if (!psoc) 4284 return; 4285 4286 4287 hdd_check_for_objmgr_peer_leaks(psoc); 4288 4289 wlan_objmgr_for_each_psoc_vdev(psoc, vdev_id, vdev) { 4290 qdf_atomic_t *ref_id_dbg; 4291 int ref_id; 4292 int32_t refs; 4293 4294 ref_id_dbg = vdev->vdev_objmgr.ref_id_dbg; 4295 wlan_objmgr_for_each_refs(ref_id_dbg, ref_id, refs) { 4296 wlan_objmgr_vdev_release_ref(vdev, ref_id); 4297 } 4298 } 4299 4300 wlan_objmgr_for_each_psoc_pdev(psoc, pdev_id, pdev) { 4301 qdf_atomic_t *ref_id_dbg; 4302 int ref_id; 4303 int32_t refs; 4304 4305 ref_id_dbg = pdev->pdev_objmgr.ref_id_dbg; 4306 wlan_objmgr_for_each_refs(ref_id_dbg, ref_id, refs) 4307 wlan_objmgr_pdev_release_ref(pdev, ref_id); 4308 } 4309 } 4310 hdd_check_for_leaks(struct hdd_context * hdd_ctx,bool is_ssr)4311 static void hdd_check_for_leaks(struct hdd_context *hdd_ctx, bool is_ssr) 4312 { 4313 hdd_check_for_objmgr_leaks(hdd_ctx); 4314 } 4315 4316 #define hdd_debug_domain_set(domain) 0 4317 #define hdd_debug_domain_get() DEFAULT_DEBUG_DOMAIN_INIT 4318 #endif /* CONFIG_LEAK_DETECTION */ 4319 4320 #ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE 4321 /** 4322 * hdd_skip_acs_scan_timer_handler() - skip ACS scan timer timeout handler 4323 * @data: pointer to struct hdd_context 4324 * 4325 * This function will reset acs_scan_status to eSAP_DO_NEW_ACS_SCAN. 4326 * Then new ACS request will do a fresh scan without reusing the cached 4327 * scan information. 4328 * 4329 * Return: void 4330 */ hdd_skip_acs_scan_timer_handler(void * data)4331 static void hdd_skip_acs_scan_timer_handler(void *data) 4332 { 4333 struct hdd_context *hdd_ctx = data; 4334 mac_handle_t mac_handle; 4335 4336 hdd_debug("ACS Scan result expired. Reset ACS scan skip"); 4337 hdd_ctx->skip_acs_scan_status = eSAP_DO_NEW_ACS_SCAN; 4338 qdf_spin_lock(&hdd_ctx->acs_skip_lock); 4339 qdf_mem_free(hdd_ctx->last_acs_freq_list); 4340 hdd_ctx->last_acs_freq_list = NULL; 4341 hdd_ctx->num_of_channels = 0; 4342 qdf_spin_unlock(&hdd_ctx->acs_skip_lock); 4343 4344 mac_handle = hdd_ctx->mac_handle; 4345 if (!mac_handle) 4346 return; 4347 } 4348 hdd_skip_acs_scan_timer_init(struct hdd_context * hdd_ctx)4349 static void hdd_skip_acs_scan_timer_init(struct hdd_context *hdd_ctx) 4350 { 4351 QDF_STATUS status; 4352 4353 status = qdf_mc_timer_init(&hdd_ctx->skip_acs_scan_timer, 4354 QDF_TIMER_TYPE_SW, 4355 hdd_skip_acs_scan_timer_handler, 4356 hdd_ctx); 4357 if (QDF_IS_STATUS_ERROR(status)) 4358 hdd_err("Failed to init ACS Skip timer"); 4359 qdf_spinlock_create(&hdd_ctx->acs_skip_lock); 4360 } 4361 hdd_skip_acs_scan_timer_deinit(struct hdd_context * hdd_ctx)4362 static void hdd_skip_acs_scan_timer_deinit(struct hdd_context *hdd_ctx) 4363 { 4364 if (QDF_TIMER_STATE_RUNNING == 4365 qdf_mc_timer_get_current_state(&hdd_ctx->skip_acs_scan_timer)) { 4366 qdf_mc_timer_stop(&hdd_ctx->skip_acs_scan_timer); 4367 } 4368 4369 if (!QDF_IS_STATUS_SUCCESS 4370 (qdf_mc_timer_destroy(&hdd_ctx->skip_acs_scan_timer))) { 4371 hdd_err("Cannot deallocate ACS Skip timer"); 4372 } 4373 qdf_spin_lock(&hdd_ctx->acs_skip_lock); 4374 qdf_mem_free(hdd_ctx->last_acs_freq_list); 4375 hdd_ctx->last_acs_freq_list = NULL; 4376 hdd_ctx->num_of_channels = 0; 4377 qdf_spin_unlock(&hdd_ctx->acs_skip_lock); 4378 } 4379 #else hdd_skip_acs_scan_timer_init(struct hdd_context * hdd_ctx)4380 static void hdd_skip_acs_scan_timer_init(struct hdd_context *hdd_ctx) {} hdd_skip_acs_scan_timer_deinit(struct hdd_context * hdd_ctx)4381 static void hdd_skip_acs_scan_timer_deinit(struct hdd_context *hdd_ctx) {} 4382 #endif 4383 4384 /** 4385 * hdd_update_country_code - Update country code 4386 * @hdd_ctx: HDD context 4387 * 4388 * Update country code based on module parameter country_code 4389 * 4390 * Return: 0 on success and errno on failure 4391 */ hdd_update_country_code(struct hdd_context * hdd_ctx)4392 int hdd_update_country_code(struct hdd_context *hdd_ctx) 4393 { 4394 if (!country_code || 4395 !ucfg_reg_is_user_country_set_allowed(hdd_ctx->psoc)) 4396 return 0; 4397 4398 return hdd_reg_set_country(hdd_ctx, country_code); 4399 } 4400 4401 #ifdef WLAN_NS_OFFLOAD 4402 /** 4403 * hdd_wlan_unregister_ip6_notifier() - unregister IPv6 change notifier 4404 * @hdd_ctx: Pointer to hdd context 4405 * 4406 * Unregister for IPv6 address change notifications. 4407 * 4408 * Return: None 4409 */ hdd_wlan_unregister_ip6_notifier(struct hdd_context * hdd_ctx)4410 static void hdd_wlan_unregister_ip6_notifier(struct hdd_context *hdd_ctx) 4411 { 4412 unregister_inet6addr_notifier(&hdd_ctx->ipv6_notifier); 4413 } 4414 4415 /** 4416 * hdd_wlan_register_ip6_notifier() - register IPv6 change notifier 4417 * @hdd_ctx: Pointer to hdd context 4418 * 4419 * Register for IPv6 address change notifications. 4420 * 4421 * Return: 0 on success and errno on failure. 4422 */ hdd_wlan_register_ip6_notifier(struct hdd_context * hdd_ctx)4423 static int hdd_wlan_register_ip6_notifier(struct hdd_context *hdd_ctx) 4424 { 4425 int ret; 4426 4427 hdd_ctx->ipv6_notifier.notifier_call = wlan_hdd_ipv6_changed; 4428 ret = register_inet6addr_notifier(&hdd_ctx->ipv6_notifier); 4429 if (ret) { 4430 hdd_err("Failed to register IPv6 notifier: %d", ret); 4431 goto out; 4432 } 4433 4434 hdd_debug("Registered IPv6 notifier"); 4435 out: 4436 return ret; 4437 } 4438 #else 4439 /** 4440 * hdd_wlan_unregister_ip6_notifier() - unregister IPv6 change notifier 4441 * @hdd_ctx: Pointer to hdd context 4442 * 4443 * Unregister for IPv6 address change notifications. 4444 * 4445 * Return: None 4446 */ hdd_wlan_unregister_ip6_notifier(struct hdd_context * hdd_ctx)4447 static void hdd_wlan_unregister_ip6_notifier(struct hdd_context *hdd_ctx) 4448 { 4449 } 4450 4451 /** 4452 * hdd_wlan_register_ip6_notifier() - register IPv6 change notifier 4453 * @hdd_ctx: Pointer to hdd context 4454 * 4455 * Register for IPv6 address change notifications. 4456 * 4457 * Return: None 4458 */ hdd_wlan_register_ip6_notifier(struct hdd_context * hdd_ctx)4459 static int hdd_wlan_register_ip6_notifier(struct hdd_context *hdd_ctx) 4460 { 4461 return 0; 4462 } 4463 #endif 4464 4465 #ifdef FEATURE_RUNTIME_PM 4466 #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 7, 0) hdd_pm_qos_add_notifier(struct hdd_context * hdd_ctx)4467 static int hdd_pm_qos_add_notifier(struct hdd_context *hdd_ctx) 4468 { 4469 return dev_pm_qos_add_notifier(hdd_ctx->parent_dev, 4470 &hdd_ctx->pm_qos_notifier, 4471 DEV_PM_QOS_RESUME_LATENCY); 4472 } 4473 hdd_pm_qos_remove_notifier(struct hdd_context * hdd_ctx)4474 static int hdd_pm_qos_remove_notifier(struct hdd_context *hdd_ctx) 4475 { 4476 return dev_pm_qos_remove_notifier(hdd_ctx->parent_dev, 4477 &hdd_ctx->pm_qos_notifier, 4478 DEV_PM_QOS_RESUME_LATENCY); 4479 } 4480 #else hdd_pm_qos_add_notifier(struct hdd_context * hdd_ctx)4481 static int hdd_pm_qos_add_notifier(struct hdd_context *hdd_ctx) 4482 { 4483 return pm_qos_add_notifier(PM_QOS_CPU_DMA_LATENCY, 4484 &hdd_ctx->pm_qos_notifier); 4485 } 4486 hdd_pm_qos_remove_notifier(struct hdd_context * hdd_ctx)4487 static int hdd_pm_qos_remove_notifier(struct hdd_context *hdd_ctx) 4488 { 4489 return pm_qos_remove_notifier(PM_QOS_CPU_DMA_LATENCY, 4490 &hdd_ctx->pm_qos_notifier); 4491 } 4492 #endif 4493 4494 /** 4495 * hdd_wlan_register_pm_qos_notifier() - register PM QOS notifier 4496 * @hdd_ctx: Pointer to hdd context 4497 * 4498 * Register for PM QOS change notifications. 4499 * 4500 * Return: None 4501 */ hdd_wlan_register_pm_qos_notifier(struct hdd_context * hdd_ctx)4502 static int hdd_wlan_register_pm_qos_notifier(struct hdd_context *hdd_ctx) 4503 { 4504 int ret; 4505 4506 qdf_spinlock_create(&hdd_ctx->pm_qos_lock); 4507 4508 /* if gRuntimePM is 1 then feature is enabled without CXPC */ 4509 if (hdd_ctx->config->runtime_pm != hdd_runtime_pm_dynamic) { 4510 hdd_debug("Dynamic Runtime PM disabled"); 4511 return 0; 4512 } 4513 4514 hdd_ctx->pm_qos_notifier.notifier_call = wlan_hdd_pm_qos_notify; 4515 ret = hdd_pm_qos_add_notifier(hdd_ctx); 4516 if (ret) 4517 hdd_err("Failed to register PM_QOS notifier: %d", ret); 4518 else 4519 hdd_debug("PM QOS Notifier registered"); 4520 4521 return ret; 4522 } 4523 4524 /** 4525 * hdd_wlan_unregister_pm_qos_notifier() - unregister PM QOS notifier 4526 * @hdd_ctx: Pointer to hdd context 4527 * 4528 * Unregister for PM QOS change notifications. 4529 * 4530 * Return: None 4531 */ hdd_wlan_unregister_pm_qos_notifier(struct hdd_context * hdd_ctx)4532 static void hdd_wlan_unregister_pm_qos_notifier(struct hdd_context *hdd_ctx) 4533 { 4534 int ret; 4535 4536 if (hdd_ctx->config->runtime_pm != hdd_runtime_pm_dynamic) { 4537 hdd_debug("Dynamic Runtime PM disabled"); 4538 qdf_spinlock_destroy(&hdd_ctx->pm_qos_lock); 4539 return; 4540 } 4541 4542 ret = hdd_pm_qos_remove_notifier(hdd_ctx); 4543 if (ret) 4544 hdd_warn("Failed to remove qos notifier, err = %d\n", ret); 4545 4546 qdf_spin_lock_irqsave(&hdd_ctx->pm_qos_lock); 4547 4548 if (hdd_ctx->runtime_pm_prevented) { 4549 hif_rtpm_put(HIF_RTPM_PUT_NOIDLE, HIF_RTPM_ID_PM_QOS_NOTIFY); 4550 hdd_ctx->runtime_pm_prevented = false; 4551 } 4552 4553 qdf_spin_unlock_irqrestore(&hdd_ctx->pm_qos_lock); 4554 4555 qdf_spinlock_destroy(&hdd_ctx->pm_qos_lock); 4556 } 4557 #else hdd_wlan_register_pm_qos_notifier(struct hdd_context * hdd_ctx)4558 static int hdd_wlan_register_pm_qos_notifier(struct hdd_context *hdd_ctx) 4559 { 4560 return 0; 4561 } 4562 hdd_wlan_unregister_pm_qos_notifier(struct hdd_context * hdd_ctx)4563 static void hdd_wlan_unregister_pm_qos_notifier(struct hdd_context *hdd_ctx) 4564 { 4565 } 4566 #endif 4567 4568 /** 4569 * hdd_enable_power_management() - API to Enable Power Management 4570 * @hdd_ctx: HDD context 4571 * 4572 * API invokes Bus Interface Layer power management functionality 4573 * 4574 * Return: None 4575 */ hdd_enable_power_management(struct hdd_context * hdd_ctx)4576 static void hdd_enable_power_management(struct hdd_context *hdd_ctx) 4577 { 4578 void *hif_ctx = cds_get_context(QDF_MODULE_ID_HIF); 4579 4580 if (!hif_ctx) 4581 return; 4582 4583 hif_enable_power_management(hif_ctx, cds_is_packet_log_enabled()); 4584 hdd_wlan_register_pm_qos_notifier(hdd_ctx); 4585 } 4586 4587 /** 4588 * hdd_disable_power_management() - API to disable Power Management 4589 * @hdd_ctx: HDD context 4590 * 4591 * API disable Bus Interface Layer Power management functionality 4592 * 4593 * Return: None 4594 */ hdd_disable_power_management(struct hdd_context * hdd_ctx)4595 static void hdd_disable_power_management(struct hdd_context *hdd_ctx) 4596 { 4597 void *hif_ctx = cds_get_context(QDF_MODULE_ID_HIF); 4598 4599 if (!hif_ctx) 4600 return; 4601 4602 hdd_wlan_unregister_pm_qos_notifier(hdd_ctx); 4603 hif_disable_power_management(hif_ctx); 4604 } 4605 4606 /** 4607 * hdd_register_notifiers - Register netdev notifiers. 4608 * @hdd_ctx: HDD context 4609 * 4610 * Register netdev notifiers like IPv4 and IPv6. 4611 * 4612 * Return: 0 on success and errno on failure 4613 */ hdd_register_notifiers(struct hdd_context * hdd_ctx)4614 static int hdd_register_notifiers(struct hdd_context *hdd_ctx) 4615 { 4616 int ret; 4617 4618 ret = hdd_wlan_register_ip6_notifier(hdd_ctx); 4619 if (ret) 4620 goto out; 4621 4622 hdd_ctx->ipv4_notifier.notifier_call = wlan_hdd_ipv4_changed; 4623 ret = register_inetaddr_notifier(&hdd_ctx->ipv4_notifier); 4624 if (ret) { 4625 hdd_err("Failed to register IPv4 notifier: %d", ret); 4626 goto unregister_ip6_notifier; 4627 } 4628 4629 ret = osif_dp_nud_register_netevent_notifier(hdd_ctx->psoc); 4630 if (ret) { 4631 hdd_err("Failed to register netevent notifier: %d", 4632 ret); 4633 goto unregister_inetaddr_notifier; 4634 } 4635 4636 return 0; 4637 4638 unregister_inetaddr_notifier: 4639 unregister_inetaddr_notifier(&hdd_ctx->ipv4_notifier); 4640 unregister_ip6_notifier: 4641 hdd_wlan_unregister_ip6_notifier(hdd_ctx); 4642 out: 4643 return ret; 4644 } 4645 4646 #ifdef WLAN_FEATURE_WMI_SEND_RECV_QMI 4647 static inline hdd_set_qmi_stats_enabled(struct hdd_context * hdd_ctx)4648 void hdd_set_qmi_stats_enabled(struct hdd_context *hdd_ctx) 4649 { 4650 wmi_unified_t wmi_handle = get_wmi_unified_hdl_from_psoc(hdd_ctx->psoc); 4651 4652 if (!wmi_handle) { 4653 hdd_err("could not get wmi handle"); 4654 return; 4655 } 4656 4657 wmi_set_qmi_stats(wmi_handle, hdd_ctx->config->is_qmi_stats_enabled); 4658 } 4659 #else 4660 static inline hdd_set_qmi_stats_enabled(struct hdd_context * hdd_ctx)4661 void hdd_set_qmi_stats_enabled(struct hdd_context *hdd_ctx) 4662 { 4663 } 4664 #endif 4665 4666 #ifdef CONFIG_FW_LOGS_BASED_ON_INI 4667 /** 4668 * hdd_set_fw_log_params() - Set log parameters to FW 4669 * @hdd_ctx: HDD Context 4670 * @vdev_id: vdev_id 4671 * 4672 * This function set the FW Debug log level based on the INI. 4673 * 4674 * Return: None 4675 */ hdd_set_fw_log_params(struct hdd_context * hdd_ctx,uint8_t vdev_id)4676 static void hdd_set_fw_log_params(struct hdd_context *hdd_ctx, 4677 uint8_t vdev_id) 4678 { 4679 QDF_STATUS status; 4680 uint16_t enable_fw_log_level, enable_fw_log_type; 4681 int ret; 4682 4683 if (!hdd_ctx->config->enable_fw_log) { 4684 hdd_debug("enable_fw_log not enabled in INI"); 4685 return; 4686 } 4687 4688 /* Enable FW logs based on INI configuration */ 4689 status = ucfg_fwol_get_enable_fw_log_type(hdd_ctx->psoc, 4690 &enable_fw_log_type); 4691 if (QDF_IS_STATUS_ERROR(status)) 4692 return; 4693 ret = sme_cli_set_command(vdev_id, WMI_DBGLOG_TYPE, 4694 enable_fw_log_type, DBG_CMD); 4695 if (ret != 0) 4696 hdd_err("Failed to enable FW log type ret %d", ret); 4697 4698 status = ucfg_fwol_get_enable_fw_log_level(hdd_ctx->psoc, 4699 &enable_fw_log_level); 4700 if (QDF_IS_STATUS_ERROR(status)) 4701 return; 4702 ret = sme_cli_set_command(vdev_id, WMI_DBGLOG_LOG_LEVEL, 4703 enable_fw_log_level, DBG_CMD); 4704 if (ret != 0) 4705 hdd_err("Failed to enable FW log level ret %d", ret); 4706 4707 sme_enable_fw_module_log_level(hdd_ctx->mac_handle, vdev_id); 4708 } 4709 #else hdd_set_fw_log_params(struct hdd_context * hdd_ctx,uint8_t vdev_id)4710 static void hdd_set_fw_log_params(struct hdd_context *hdd_ctx, uint8_t vdev_id) 4711 { 4712 } 4713 4714 #endif 4715 4716 /** 4717 * hdd_features_deinit() - Deinit features 4718 * @hdd_ctx: HDD context 4719 * 4720 * De-Initialize features and their feature context. 4721 * 4722 * Return: none. 4723 */ hdd_features_deinit(struct hdd_context * hdd_ctx)4724 static void hdd_features_deinit(struct hdd_context *hdd_ctx) 4725 { 4726 wlan_hdd_gpio_wakeup_deinit(hdd_ctx); 4727 wlan_hdd_twt_deinit(hdd_ctx); 4728 wlan_hdd_deinit_chan_info(hdd_ctx); 4729 wlan_hdd_tsf_deinit(hdd_ctx); 4730 if (cds_is_packet_log_enabled()) 4731 hdd_pktlog_enable_disable(hdd_ctx, false, 0, 0); 4732 } 4733 4734 /** 4735 * hdd_deconfigure_cds() -De-Configure cds 4736 * @hdd_ctx: HDD context 4737 * 4738 * Deconfigure Cds modules before WLAN firmware is down. 4739 * 4740 * Return: 0 on success and errno on failure. 4741 */ hdd_deconfigure_cds(struct hdd_context * hdd_ctx)4742 static int hdd_deconfigure_cds(struct hdd_context *hdd_ctx) 4743 { 4744 QDF_STATUS qdf_status; 4745 int ret = 0; 4746 4747 hdd_enter(); 4748 4749 wlan_hdd_hang_event_notifier_unregister(); 4750 /* De-init features */ 4751 hdd_features_deinit(hdd_ctx); 4752 4753 qdf_status = policy_mgr_deregister_mode_change_cb(hdd_ctx->psoc); 4754 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) 4755 hdd_debug("Failed to deregister mode change cb with Policy Manager"); 4756 4757 qdf_status = cds_disable(hdd_ctx->psoc); 4758 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { 4759 hdd_err("Failed to Disable the CDS Modules! :%d", 4760 qdf_status); 4761 ret = -EINVAL; 4762 } 4763 4764 if (ucfg_ipa_uc_ol_deinit(hdd_ctx->pdev) != QDF_STATUS_SUCCESS) { 4765 hdd_err("Failed to disconnect pipes"); 4766 ret = -EINVAL; 4767 } 4768 4769 hdd_exit(); 4770 return ret; 4771 } 4772 4773 /** 4774 * hdd_qmi_register_callbacks() - Register QMI callbacks 4775 * @hdd_ctx: HDD context 4776 * 4777 * Return: None 4778 */ hdd_qmi_register_callbacks(struct hdd_context * hdd_ctx)4779 static inline void hdd_qmi_register_callbacks(struct hdd_context *hdd_ctx) 4780 { 4781 struct wlan_qmi_psoc_callbacks cb_obj; 4782 4783 os_if_qmi_register_callbacks(hdd_ctx->psoc, &cb_obj); 4784 } 4785 4786 /** 4787 * hdd_set_pcie_params() - Set pcie params 4788 * @hdd_ctx: HDD context 4789 * @index: index value 4790 * @param: pointer to vdev/pdev set param info 4791 * 4792 * Checks for pcie_config value and sets 4793 * corresponding params 4794 * 4795 * Return: 0 on success and errno on failure. 4796 */ hdd_set_pcie_params(struct hdd_context * hdd_ctx,uint8_t index,struct dev_set_param * param)4797 static int hdd_set_pcie_params(struct hdd_context *hdd_ctx, 4798 uint8_t index, struct dev_set_param *param) 4799 { 4800 int ret = 0; 4801 uint8_t check_value = 0; 4802 4803 ret = ucfg_fwol_get_pcie_config(hdd_ctx->psoc, &check_value); 4804 if (QDF_IS_STATUS_SUCCESS(ret)) { 4805 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) { 4806 ret = mlme_check_index_setparam(param, 4807 wmi_pdev_param_pcie_config, 4808 (int)check_value, index++, 4809 FTM_MAX_PDEV_PARAMS); 4810 } else { 4811 ret = mlme_check_index_setparam(param, 4812 wmi_pdev_param_pcie_config, 4813 (int)check_value, index++, 4814 MAX_PDEV_PRE_ENABLE_PARAMS); 4815 } 4816 if (QDF_IS_STATUS_ERROR(ret)) { 4817 hdd_err("failed to set wmi_pdev_param_pcie_config"); 4818 return ret; 4819 } 4820 } 4821 return ret; 4822 } 4823 4824 #ifdef FEATURE_SET 4825 #ifdef WLAN_FEATURE_11BE 4826 /** 4827 * hdd_is_cfg_dot11_mode_11be() - Check if dot11 mode is 11 be 4828 * @dot11_mode: Input dot11_mode which needs to be checked 4829 * 4830 * Return: True, ifinput dot11_mode is 11be dot11 mode else return false 4831 */ hdd_is_cfg_dot11_mode_11be(enum hdd_dot11_mode dot11_mode)4832 static bool hdd_is_cfg_dot11_mode_11be(enum hdd_dot11_mode dot11_mode) 4833 { 4834 return (dot11_mode == eHDD_DOT11_MODE_11be || 4835 dot11_mode == eHDD_DOT11_MODE_11be_ONLY); 4836 } 4837 4838 /** 4839 * hdd_is_11be_supported() - Check if 11be is supported or not 4840 * @hdd_ctx: Pointer to hdd context 4841 * 4842 * Return: True, if 11be is supported else return false 4843 */ hdd_is_11be_supported(struct hdd_context * hdd_ctx)4844 static bool hdd_is_11be_supported(struct hdd_context *hdd_ctx) 4845 { 4846 bool mlo_capab; 4847 4848 ucfg_psoc_mlme_get_11be_capab(hdd_ctx->psoc, &mlo_capab); 4849 if (!mlo_capab) 4850 return false; 4851 4852 return true; 4853 } 4854 #else 4855 hdd_is_cfg_dot11_mode_11be(enum hdd_dot11_mode dot11_mode)4856 static bool hdd_is_cfg_dot11_mode_11be(enum hdd_dot11_mode dot11_mode) 4857 { 4858 return false; 4859 } 4860 hdd_is_11be_supported(struct hdd_context * hdd_ctx)4861 static bool hdd_is_11be_supported(struct hdd_context *hdd_ctx) 4862 { 4863 return false; 4864 } 4865 #endif 4866 4867 WMI_HOST_WIFI_STANDARD hdd_get_wifi_standard(struct hdd_context * hdd_ctx,enum hdd_dot11_mode dot11_mode,uint32_t band_capability)4868 hdd_get_wifi_standard(struct hdd_context *hdd_ctx, 4869 enum hdd_dot11_mode dot11_mode, uint32_t band_capability) 4870 { 4871 WMI_HOST_WIFI_STANDARD wifi_standard = WMI_HOST_WIFI_STANDARD_4; 4872 4873 if (dot11_mode == eHDD_DOT11_MODE_AUTO) { 4874 if (hdd_is_11be_supported(hdd_ctx)) 4875 wifi_standard = WMI_HOST_WIFI_STANDARD_7; 4876 else if (band_capability & BIT(REG_BAND_6G)) 4877 wifi_standard = WMI_HOST_WIFI_STANDARD_6E; 4878 else 4879 wifi_standard = WMI_HOST_WIFI_STANDARD_6; 4880 } else if (hdd_is_cfg_dot11_mode_11be(dot11_mode)) { 4881 wifi_standard = WMI_HOST_WIFI_STANDARD_7; 4882 } else if (dot11_mode == eHDD_DOT11_MODE_11ax || 4883 (dot11_mode == eHDD_DOT11_MODE_11ax_ONLY)) { 4884 if (band_capability & BIT(REG_BAND_6G)) 4885 wifi_standard = WMI_HOST_WIFI_STANDARD_6E; 4886 else 4887 wifi_standard = WMI_HOST_WIFI_STANDARD_6; 4888 } else if ((dot11_mode == eHDD_DOT11_MODE_11ac) || 4889 (dot11_mode == eHDD_DOT11_MODE_11ac_ONLY)) { 4890 wifi_standard = WMI_HOST_WIFI_STANDARD_5; 4891 } 4892 4893 return wifi_standard; 4894 } 4895 4896 /** 4897 * hdd_populate_feature_set_cds_config() - Populate cds feature set config 4898 * @hdd_ctx: hdd context pointer 4899 * 4900 * Return: None 4901 */ hdd_populate_feature_set_cds_config(struct hdd_context * hdd_ctx)4902 static void hdd_populate_feature_set_cds_config(struct hdd_context *hdd_ctx) 4903 { 4904 struct wlan_objmgr_psoc *psoc; 4905 uint32_t band_capability; 4906 QDF_STATUS status; 4907 struct cds_config_info *cds_cfg; 4908 4909 if (!hdd_ctx) 4910 return; 4911 4912 cds_cfg = cds_get_ini_config(); 4913 if (!cds_cfg) { 4914 hdd_err("CDS config is null."); 4915 return; 4916 } 4917 4918 psoc = hdd_ctx->psoc; 4919 4920 cds_cfg->get_wifi_features = hdd_ctx->config->get_wifi_features; 4921 4922 status = ucfg_mlme_get_band_capability(hdd_ctx->psoc, &band_capability); 4923 if (QDF_IS_STATUS_ERROR(status)) 4924 hdd_err("Failed to get MLME band capability"); 4925 4926 band_capability = 4927 hdd_update_band_cap_from_dot11mode(hdd_ctx, band_capability); 4928 4929 cds_cfg->cds_feature_set.wifi_standard = 4930 hdd_get_wifi_standard(hdd_ctx, 4931 hdd_ctx->config->dot11Mode, 4932 band_capability); 4933 4934 cds_cfg->cds_feature_set.sap_5g_supported = 4935 band_capability & BIT(REG_BAND_5G); 4936 4937 cds_cfg->cds_feature_set.sap_6g_supported = 4938 band_capability & BIT(REG_BAND_6G); 4939 cds_cfg->cds_feature_set.band_capability = band_capability; 4940 } 4941 #else 4942 WMI_HOST_WIFI_STANDARD hdd_get_wifi_standard(struct hdd_context * hdd_ctx,enum hdd_dot11_mode dot11_mode,uint32_t band_capability)4943 hdd_get_wifi_standard(struct hdd_context *hdd_ctx, 4944 enum hdd_dot11_mode dot11_mode, uint32_t band_capability) 4945 { 4946 return WMI_HOST_WIFI_STANDARD_5; 4947 } 4948 4949 static inline void hdd_populate_feature_set_cds_config(struct hdd_context * hdd_ctx)4950 hdd_populate_feature_set_cds_config(struct hdd_context *hdd_ctx) 4951 { 4952 } 4953 #endif 4954 hdd_wlan_start_modules(struct hdd_context * hdd_ctx,bool reinit)4955 int hdd_wlan_start_modules(struct hdd_context *hdd_ctx, bool reinit) 4956 { 4957 int ret = 0; 4958 qdf_device_t qdf_dev; 4959 QDF_STATUS status; 4960 bool unint = false; 4961 void *hif_ctx; 4962 struct target_psoc_info *tgt_hdl; 4963 unsigned long thermal_state = 0; 4964 uint8_t index = 0; 4965 struct dev_set_param setparam[MAX_PDEV_PRE_ENABLE_PARAMS] = {}; 4966 4967 hdd_enter(); 4968 qdf_dev = cds_get_context(QDF_MODULE_ID_QDF_DEVICE); 4969 if (!qdf_dev) { 4970 hdd_exit(); 4971 return -EINVAL; 4972 } 4973 4974 hdd_psoc_idle_timer_stop(hdd_ctx); 4975 4976 if (hdd_ctx->driver_status == DRIVER_MODULES_ENABLED) { 4977 hdd_debug("Driver modules already Enabled"); 4978 hdd_exit(); 4979 return 0; 4980 } 4981 4982 cds_set_driver_state_module_stop(false); 4983 4984 switch (hdd_ctx->driver_status) { 4985 case DRIVER_MODULES_UNINITIALIZED: 4986 hdd_nofl_debug("Wlan transitioning (UNINITIALIZED -> CLOSED)"); 4987 unint = true; 4988 fallthrough; 4989 case DRIVER_MODULES_CLOSED: 4990 hdd_nofl_debug("Wlan transitioning (CLOSED -> ENABLED)"); 4991 ret = hdd_debug_domain_set(QDF_DEBUG_DOMAIN_ACTIVE); 4992 if (ret) 4993 goto abort; 4994 4995 if (!reinit && !unint) { 4996 ret = pld_power_on(qdf_dev->dev); 4997 if (ret) { 4998 hdd_err("Failed to power up device; errno:%d", 4999 ret); 5000 goto release_lock; 5001 } 5002 } 5003 5004 hdd_init_adapter_ops_wq(hdd_ctx); 5005 pld_set_fw_log_mode(hdd_ctx->parent_dev, 5006 hdd_ctx->config->enable_fw_log); 5007 ret = hdd_hif_open(qdf_dev->dev, qdf_dev->drv_hdl, qdf_dev->bid, 5008 qdf_dev->bus_type, 5009 (reinit == true) ? HIF_ENABLE_TYPE_REINIT : 5010 HIF_ENABLE_TYPE_PROBE); 5011 if (ret) { 5012 hdd_err("Failed to open hif; errno: %d", ret); 5013 goto power_down; 5014 } 5015 5016 hif_ctx = cds_get_context(QDF_MODULE_ID_HIF); 5017 if (!hif_ctx) { 5018 ret = -EINVAL; 5019 goto power_down; 5020 } 5021 5022 status = ol_cds_init(qdf_dev, hif_ctx); 5023 if (status != QDF_STATUS_SUCCESS) { 5024 hdd_err("No Memory to Create BMI Context; status: %d", 5025 status); 5026 ret = qdf_status_to_os_return(status); 5027 goto hif_close; 5028 } 5029 5030 if (hdd_get_conparam() == QDF_GLOBAL_EPPING_MODE) { 5031 status = epping_open(); 5032 if (status) { 5033 hdd_err("Failed to open in epping mode: %d", 5034 status); 5035 ret = -EINVAL; 5036 goto cds_free; 5037 } 5038 5039 status = epping_enable(qdf_dev->dev, false); 5040 if (status) { 5041 hdd_err("Failed to enable in epping mode : %d", 5042 status); 5043 epping_close(); 5044 goto cds_free; 5045 } 5046 5047 hdd_info("epping mode enabled"); 5048 break; 5049 } 5050 5051 if (pld_is_ipa_offload_disabled(qdf_dev->dev)) 5052 ucfg_ipa_set_pld_enable(false); 5053 5054 ucfg_ipa_component_config_update(hdd_ctx->psoc); 5055 5056 hdd_update_cds_ac_specs_params(hdd_ctx); 5057 5058 hdd_dp_register_callbacks(hdd_ctx); 5059 5060 hdd_qmi_register_callbacks(hdd_ctx); 5061 5062 status = hdd_component_psoc_open(hdd_ctx->psoc); 5063 if (QDF_IS_STATUS_ERROR(status)) { 5064 hdd_err("Failed to Open legacy components; status: %d", 5065 status); 5066 ret = qdf_status_to_os_return(status); 5067 goto ipa_component_free; 5068 } 5069 5070 ret = hdd_update_config(hdd_ctx); 5071 if (ret) { 5072 hdd_err("Failed to update configuration; errno: %d", 5073 ret); 5074 goto ipa_component_free; 5075 } 5076 5077 status = wbuff_module_init(); 5078 if (QDF_IS_STATUS_ERROR(status)) 5079 hdd_err("WBUFF init unsuccessful; status: %d", status); 5080 5081 status = cds_open(hdd_ctx->psoc); 5082 if (QDF_IS_STATUS_ERROR(status)) { 5083 hdd_err("Failed to Open CDS; status: %d", status); 5084 ret = qdf_status_to_os_return(status); 5085 goto psoc_close; 5086 } 5087 5088 hdd_populate_feature_set_cds_config(hdd_ctx); 5089 5090 hdd_set_qmi_stats_enabled(hdd_ctx); 5091 5092 hdd_ctx->mac_handle = cds_get_context(QDF_MODULE_ID_SME); 5093 5094 ucfg_dp_set_rx_thread_affinity(hdd_ctx->psoc); 5095 5096 /* initialize components configurations after psoc open */ 5097 ret = hdd_update_components_config(hdd_ctx); 5098 if (ret) { 5099 hdd_err("Failed to update component configs; errno: %d", 5100 ret); 5101 goto close; 5102 } 5103 5104 /* Override PS params for monitor mode */ 5105 if (hdd_get_conparam() == QDF_GLOBAL_MONITOR_MODE) 5106 hdd_override_all_ps(hdd_ctx); 5107 5108 status = cds_dp_open(hdd_ctx->psoc); 5109 if (!QDF_IS_STATUS_SUCCESS(status)) { 5110 hdd_err("Failed to Open cds post open; status: %d", 5111 status); 5112 ret = qdf_status_to_os_return(status); 5113 goto close; 5114 } 5115 /* Set IRQ affinity for WLAN DP and CE IRQS */ 5116 hif_config_irq_set_perf_affinity_hint(hif_ctx); 5117 5118 ret = hdd_register_cb(hdd_ctx); 5119 if (ret) { 5120 hdd_err("Failed to register HDD callbacks!"); 5121 goto cds_txrx_free; 5122 } 5123 5124 ret = hdd_register_notifiers(hdd_ctx); 5125 if (ret) 5126 goto deregister_cb; 5127 5128 /* 5129 * NAN component requires certain operations like, open adapter, 5130 * close adapter, etc. to be initiated by HDD, for those 5131 * register HDD callbacks with UMAC's NAN component. 5132 */ 5133 hdd_nan_register_callbacks(hdd_ctx); 5134 5135 hdd_son_register_callbacks(hdd_ctx); 5136 5137 hdd_sr_register_callbacks(hdd_ctx); 5138 5139 wlan_hdd_register_btc_chain_mode_handler(hdd_ctx->psoc); 5140 5141 wlan_hdd_register_afc_pld_cb(hdd_ctx->psoc); 5142 5143 status = cds_pre_enable(); 5144 if (!QDF_IS_STATUS_SUCCESS(status)) { 5145 hdd_err("Failed to pre-enable CDS; status: %d", status); 5146 ret = qdf_status_to_os_return(status); 5147 goto unregister_notifiers; 5148 } 5149 5150 hdd_register_policy_manager_callback( 5151 hdd_ctx->psoc); 5152 5153 /* 5154 * Call this function before hdd_enable_power_management. Since 5155 * it is required to trigger WMI_PDEV_DMA_RING_CFG_REQ_CMDID 5156 * to FW when power save isn't enable. 5157 */ 5158 hdd_spectral_register_to_dbr(hdd_ctx); 5159 5160 hdd_create_sysfs_files(hdd_ctx); 5161 hdd_update_hw_sw_info(hdd_ctx); 5162 5163 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) { 5164 hdd_enable_power_management(hdd_ctx); 5165 hdd_err("in ftm mode, no need to configure cds modules"); 5166 hdd_info("Enable FW log in ftm mode"); 5167 /* 5168 * Since vdev is not created for FTM mode, 5169 * in FW use vdev_id = 0. 5170 */ 5171 hdd_set_fw_log_params(hdd_ctx, 0); 5172 ret = hdd_set_pcie_params(hdd_ctx, index, setparam); 5173 if (QDF_IS_STATUS_ERROR(ret)) 5174 break; 5175 index++; 5176 ret = sme_send_multi_pdev_vdev_set_params( 5177 MLME_PDEV_SETPARAM, 5178 WMI_PDEV_ID_SOC, setparam, index); 5179 if (QDF_IS_STATUS_ERROR(ret)) { 5180 hdd_err("failed to send pdev set params"); 5181 return ret; 5182 } 5183 5184 ret = -EINVAL; 5185 break; 5186 } 5187 5188 ret = hdd_configure_cds(hdd_ctx); 5189 if (ret) { 5190 hdd_err("Failed to Enable cds modules; errno: %d", ret); 5191 goto sched_disable; 5192 } 5193 5194 if (hdd_get_conparam() == QDF_GLOBAL_MISSION_MODE) { 5195 status = ucfg_dp_direct_link_init(hdd_ctx->psoc); 5196 if (QDF_IS_STATUS_ERROR(status)) { 5197 cds_err("Failed to initialize Direct Link datapath"); 5198 ret = -EINVAL; 5199 goto deconfigure_cds; 5200 } 5201 } 5202 5203 hdd_enable_power_management(hdd_ctx); 5204 5205 hdd_skip_acs_scan_timer_init(hdd_ctx); 5206 5207 hdd_set_hif_init_phase(hif_ctx, false); 5208 hdd_hif_set_enable_detection(hif_ctx, true); 5209 5210 wlan_hdd_start_connectivity_logging(hdd_ctx); 5211 5212 break; 5213 5214 default: 5215 QDF_DEBUG_PANIC("Unknown driver state:%d", 5216 hdd_ctx->driver_status); 5217 ret = -EINVAL; 5218 goto release_lock; 5219 } 5220 5221 hdd_ctx->driver_status = DRIVER_MODULES_ENABLED; 5222 hdd_nofl_debug("Wlan transitioned (now ENABLED)"); 5223 5224 ucfg_ipa_reg_is_driver_unloading_cb(hdd_ctx->pdev, 5225 cds_is_driver_unloading); 5226 ucfg_ipa_reg_sap_xmit_cb(hdd_ctx->pdev, 5227 hdd_softap_ipa_start_xmit); 5228 ucfg_ipa_reg_send_to_nw_cb(hdd_ctx->pdev, 5229 hdd_ipa_send_nbuf_to_network); 5230 ucfg_dp_reg_ipa_rsp_ind(hdd_ctx->pdev); 5231 5232 if (!pld_get_thermal_state(hdd_ctx->parent_dev, &thermal_state, 5233 THERMAL_MONITOR_APPS)) { 5234 if (thermal_state > QCA_WLAN_VENDOR_THERMAL_LEVEL_NONE) 5235 hdd_send_thermal_mitigation_val(hdd_ctx, 5236 thermal_state, 5237 THERMAL_MONITOR_APPS); 5238 } 5239 5240 if (!pld_get_thermal_state(hdd_ctx->parent_dev, &thermal_state, 5241 THERMAL_MONITOR_WPSS)) { 5242 if (thermal_state > QCA_WLAN_VENDOR_THERMAL_LEVEL_NONE) 5243 hdd_send_thermal_mitigation_val(hdd_ctx, thermal_state, 5244 THERMAL_MONITOR_WPSS); 5245 } 5246 5247 hdd_exit(); 5248 5249 return 0; 5250 5251 deconfigure_cds: 5252 hdd_deconfigure_cds(hdd_ctx); 5253 sched_disable: 5254 /* 5255 * Disable scheduler 1st so that scheduler thread doesn't send messages 5256 * to fw in parallel to the cleanup 5257 */ 5258 dispatcher_disable(); 5259 hdd_destroy_sysfs_files(); 5260 cds_post_disable(); 5261 unregister_notifiers: 5262 hdd_unregister_notifiers(hdd_ctx); 5263 5264 deregister_cb: 5265 hdd_deregister_cb(hdd_ctx); 5266 5267 cds_txrx_free: 5268 5269 tgt_hdl = wlan_psoc_get_tgt_if_handle(hdd_ctx->psoc); 5270 5271 if (tgt_hdl && target_psoc_get_wmi_ready(tgt_hdl)) 5272 hdd_runtime_suspend_context_deinit(hdd_ctx); 5273 5274 if (hdd_ctx->pdev) { 5275 dispatcher_pdev_close(hdd_ctx->pdev); 5276 hdd_objmgr_release_and_destroy_pdev(hdd_ctx); 5277 } 5278 5279 cds_dp_close(hdd_ctx->psoc); 5280 5281 close: 5282 dispatcher_disable(); 5283 hdd_ctx->driver_status = DRIVER_MODULES_CLOSED; 5284 hdd_info("Wlan transition aborted (now CLOSED)"); 5285 5286 cds_close(hdd_ctx->psoc); 5287 5288 psoc_close: 5289 hdd_component_psoc_close(hdd_ctx->psoc); 5290 wlan_global_lmac_if_close(hdd_ctx->psoc); 5291 cds_deinit_ini_config(); 5292 5293 ipa_component_free: 5294 ucfg_ipa_component_config_free(); 5295 5296 cds_free: 5297 ol_cds_free(); 5298 5299 hif_close: 5300 hif_ctx = cds_get_context(QDF_MODULE_ID_HIF); 5301 hdd_hif_close(hdd_ctx, hif_ctx); 5302 power_down: 5303 hdd_deinit_adapter_ops_wq(hdd_ctx); 5304 if (!reinit && !unint) 5305 pld_power_off(qdf_dev->dev); 5306 release_lock: 5307 cds_shutdown_notifier_purge(); 5308 hdd_check_for_leaks(hdd_ctx, reinit); 5309 hdd_debug_domain_set(QDF_DEBUG_DOMAIN_INIT); 5310 5311 abort: 5312 cds_set_driver_state_module_stop(true); 5313 5314 hdd_exit(); 5315 5316 return ret; 5317 } 5318 5319 #ifdef WIFI_POS_CONVERGED hdd_activate_wifi_pos(struct hdd_context * hdd_ctx)5320 static int hdd_activate_wifi_pos(struct hdd_context *hdd_ctx) 5321 { 5322 int ret = os_if_wifi_pos_register_nl(); 5323 5324 if (ret) 5325 hdd_err("os_if_wifi_pos_register_nl failed"); 5326 5327 return ret; 5328 } 5329 hdd_deactivate_wifi_pos(void)5330 static int hdd_deactivate_wifi_pos(void) 5331 { 5332 int ret = os_if_wifi_pos_deregister_nl(); 5333 5334 if (ret) 5335 hdd_err("os_if_wifi_pos_deregister_nl failed"); 5336 5337 return ret; 5338 } 5339 5340 /** 5341 * hdd_populate_wifi_pos_cfg - populates wifi_pos parameters 5342 * @hdd_ctx: hdd context 5343 * 5344 * Return: status of operation 5345 */ hdd_populate_wifi_pos_cfg(struct hdd_context * hdd_ctx)5346 static void hdd_populate_wifi_pos_cfg(struct hdd_context *hdd_ctx) 5347 { 5348 struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc; 5349 uint16_t neighbor_scan_max_chan_time; 5350 uint16_t neighbor_scan_min_chan_time; 5351 5352 wifi_pos_set_oem_target_type(psoc, hdd_ctx->target_type); 5353 wifi_pos_set_oem_fw_version(psoc, hdd_ctx->target_fw_version); 5354 wifi_pos_set_drv_ver_major(psoc, QWLAN_VERSION_MAJOR); 5355 wifi_pos_set_drv_ver_minor(psoc, QWLAN_VERSION_MINOR); 5356 wifi_pos_set_drv_ver_patch(psoc, QWLAN_VERSION_PATCH); 5357 wifi_pos_set_drv_ver_build(psoc, QWLAN_VERSION_BUILD); 5358 ucfg_mlme_get_neighbor_scan_max_chan_time(psoc, 5359 &neighbor_scan_max_chan_time); 5360 ucfg_mlme_get_neighbor_scan_min_chan_time(psoc, 5361 &neighbor_scan_min_chan_time); 5362 wifi_pos_set_dwell_time_min(psoc, neighbor_scan_min_chan_time); 5363 wifi_pos_set_dwell_time_max(psoc, neighbor_scan_max_chan_time); 5364 } 5365 #else hdd_activate_wifi_pos(struct hdd_context * hdd_ctx)5366 static int hdd_activate_wifi_pos(struct hdd_context *hdd_ctx) 5367 { 5368 return oem_activate_service(hdd_ctx); 5369 } 5370 hdd_deactivate_wifi_pos(void)5371 static int hdd_deactivate_wifi_pos(void) 5372 { 5373 return oem_deactivate_service(); 5374 } 5375 hdd_populate_wifi_pos_cfg(struct hdd_context * hdd_ctx)5376 static void hdd_populate_wifi_pos_cfg(struct hdd_context *hdd_ctx) 5377 { 5378 } 5379 #endif 5380 5381 /** 5382 * __hdd_open() - HDD Open function 5383 * @dev: Pointer to net_device structure 5384 * 5385 * This is called in response to ifconfig up 5386 * 5387 * Return: 0 for success; non-zero for failure 5388 */ __hdd_open(struct net_device * dev)5389 static int __hdd_open(struct net_device *dev) 5390 { 5391 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev); 5392 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); 5393 int ret; 5394 struct wlan_hdd_link_info *link_info = adapter->deflink; 5395 5396 hdd_enter_dev(dev); 5397 5398 qdf_mtrace(QDF_MODULE_ID_HDD, QDF_MODULE_ID_HDD, 5399 TRACE_CODE_HDD_OPEN_REQUEST, 5400 link_info->vdev_id, adapter->device_mode); 5401 5402 /* Nothing to be done if device is unloading */ 5403 if (cds_is_driver_unloading()) { 5404 hdd_err("Driver is unloading can not open the hdd"); 5405 return -EBUSY; 5406 } 5407 5408 if (cds_is_driver_recovering()) { 5409 hdd_err("WLAN is currently recovering; Please try again."); 5410 return -EBUSY; 5411 } 5412 5413 /* 5414 * This scenario can be hit in cases where in the wlan driver after 5415 * registering the netdevices and there is a failure in driver 5416 * initialization. So return error gracefully because the netdevices 5417 * will be de-registered as part of the load failure. 5418 */ 5419 5420 if (!cds_is_driver_loaded()) { 5421 hdd_err("Failed to start the wlan driver!!"); 5422 return -EIO; 5423 } 5424 5425 ret = wlan_hdd_validate_context(hdd_ctx); 5426 if (ret) { 5427 hdd_err("Can't start WLAN module, WiFi Disabled"); 5428 return ret; 5429 } 5430 5431 ret = hdd_trigger_psoc_idle_restart(hdd_ctx); 5432 if (ret) { 5433 hdd_err("Failed to start WLAN modules return"); 5434 return ret; 5435 } 5436 5437 if (!test_bit(SME_SESSION_OPENED, &link_info->link_flags)) { 5438 ret = hdd_start_adapter(adapter, true); 5439 if (ret) { 5440 hdd_err("Failed to start adapter :%d", 5441 adapter->device_mode); 5442 return ret; 5443 } 5444 } 5445 5446 set_bit(DEVICE_IFACE_OPENED, &adapter->event_flags); 5447 if (hdd_cm_is_vdev_associated(link_info)) { 5448 hdd_debug("Enabling Tx Queues"); 5449 /* Enable TX queues only when we are connected */ 5450 wlan_hdd_netif_queue_control(adapter, 5451 WLAN_START_ALL_NETIF_QUEUE, 5452 WLAN_CONTROL_PATH); 5453 } 5454 5455 /* Enable carrier and transmit queues for NDI */ 5456 if (WLAN_HDD_IS_NDI(adapter)) { 5457 hdd_debug("Enabling Tx Queues"); 5458 wlan_hdd_netif_queue_control(adapter, 5459 WLAN_START_ALL_NETIF_QUEUE_N_CARRIER, 5460 WLAN_CONTROL_PATH); 5461 } 5462 5463 hdd_populate_wifi_pos_cfg(hdd_ctx); 5464 hdd_lpass_notify_start(link_info); 5465 5466 if (ucfg_pkt_capture_get_mode(hdd_ctx->psoc) != 5467 PACKET_CAPTURE_MODE_DISABLE) 5468 hdd_map_monitor_interface_vdev(adapter); 5469 5470 return 0; 5471 } 5472 5473 /** 5474 * hdd_open() - Wrapper function for __hdd_open to protect it from SSR 5475 * @net_dev: Pointer to net_device structure 5476 * 5477 * This is called in response to ifconfig up 5478 * 5479 * Return: 0 for success; non-zero for failure 5480 */ hdd_open(struct net_device * net_dev)5481 static int hdd_open(struct net_device *net_dev) 5482 { 5483 int errno; 5484 struct osif_vdev_sync *vdev_sync; 5485 5486 errno = osif_vdev_sync_trans_start(net_dev, &vdev_sync); 5487 if (errno) 5488 return errno; 5489 5490 errno = __hdd_open(net_dev); 5491 if (!errno) 5492 osif_vdev_cache_command(vdev_sync, NO_COMMAND); 5493 5494 osif_vdev_sync_trans_stop(vdev_sync); 5495 5496 return errno; 5497 } 5498 hdd_stop_no_trans(struct net_device * dev)5499 int hdd_stop_no_trans(struct net_device *dev) 5500 { 5501 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev); 5502 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); 5503 int ret; 5504 mac_handle_t mac_handle; 5505 5506 hdd_enter_dev(dev); 5507 5508 qdf_mtrace(QDF_MODULE_ID_HDD, QDF_MODULE_ID_HDD, 5509 TRACE_CODE_HDD_STOP_REQUEST, 5510 adapter->deflink->vdev_id, adapter->device_mode); 5511 5512 ret = wlan_hdd_validate_context(hdd_ctx); 5513 if (ret) 5514 return ret; 5515 5516 /* Nothing to be done if the interface is not opened */ 5517 if (false == test_bit(DEVICE_IFACE_OPENED, &adapter->event_flags)) { 5518 hdd_err("NETDEV Interface is not OPENED"); 5519 return -ENODEV; 5520 } 5521 5522 mac_handle = hdd_ctx->mac_handle; 5523 5524 if (!wlan_hdd_is_session_type_monitor(adapter->device_mode) && 5525 adapter->device_mode != QDF_FTM_MODE) { 5526 hdd_debug("Disabling Auto Power save timer"); 5527 sme_ps_disable_auto_ps_timer( 5528 mac_handle, 5529 adapter->deflink->vdev_id); 5530 } 5531 5532 /* 5533 * Disable TX on the interface, after this hard_start_xmit() will not 5534 * be called on that interface 5535 */ 5536 hdd_debug("Disabling queues, adapter device mode: %s(%d)", 5537 qdf_opmode_str(adapter->device_mode), adapter->device_mode); 5538 5539 wlan_hdd_netif_queue_control(adapter, 5540 WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER, 5541 WLAN_CONTROL_PATH); 5542 5543 if (adapter->device_mode == QDF_STA_MODE) 5544 hdd_lpass_notify_stop(hdd_ctx); 5545 5546 /* 5547 * NAN data interface is different in some sense. The traffic on NDI is 5548 * bursty in nature and depends on the need to transfer. The service 5549 * layer may down the interface after the usage and up again when 5550 * required. In some sense, the NDI is expected to be available 5551 * (like SAP) iface until NDI delete request is issued by the service 5552 * layer. Skip BSS termination and adapter deletion for NAN Data 5553 * interface (NDI). 5554 */ 5555 if (WLAN_HDD_IS_NDI(adapter)) 5556 goto reset_iface_opened; 5557 5558 /* 5559 * The interface is marked as down for outside world (aka kernel) 5560 * But the driver is pretty much alive inside. The driver needs to 5561 * tear down the existing connection on the netdev (session) 5562 * cleanup the data pipes and wait until the control plane is stabilized 5563 * for this interface. The call also needs to wait until the above 5564 * mentioned actions are completed before returning to the caller. 5565 * Notice that hdd_stop_adapter is requested not to close the session 5566 * That is intentional to be able to scan if it is a STA/P2P interface 5567 */ 5568 hdd_stop_adapter(hdd_ctx, adapter); 5569 5570 /* DeInit the adapter. This ensures datapath cleanup as well */ 5571 hdd_deinit_adapter(hdd_ctx, adapter, true); 5572 5573 reset_iface_opened: 5574 /* Make sure the interface is marked as closed */ 5575 clear_bit(DEVICE_IFACE_OPENED, &adapter->event_flags); 5576 if (!hdd_is_any_interface_open(hdd_ctx)) 5577 hdd_psoc_idle_timer_start(hdd_ctx); 5578 hdd_exit(); 5579 5580 return 0; 5581 } 5582 5583 /** 5584 * hdd_stop() - Wrapper function for __hdd_stop to protect it from SSR 5585 * @net_dev: pointer to net_device structure 5586 * 5587 * This is called in response to ifconfig down 5588 * 5589 * Return: 0 for success and error number for failure 5590 */ hdd_stop(struct net_device * net_dev)5591 static int hdd_stop(struct net_device *net_dev) 5592 { 5593 int errno; 5594 struct osif_vdev_sync *vdev_sync; 5595 5596 errno = osif_vdev_sync_trans_start(net_dev, &vdev_sync); 5597 if (errno) { 5598 if (vdev_sync) 5599 osif_vdev_cache_command(vdev_sync, INTERFACE_DOWN); 5600 return errno; 5601 } 5602 5603 errno = hdd_stop_no_trans(net_dev); 5604 5605 osif_vdev_sync_trans_stop(vdev_sync); 5606 5607 return errno; 5608 } 5609 5610 /** 5611 * hdd_uninit() - HDD uninit function 5612 * @dev: Pointer to net_device structure 5613 * 5614 * This is called during the netdev unregister to uninitialize all data 5615 * associated with the device 5616 * 5617 * This function must be protected by a transition 5618 * 5619 * Return: None 5620 */ hdd_uninit(struct net_device * dev)5621 static void hdd_uninit(struct net_device *dev) 5622 { 5623 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev); 5624 struct hdd_context *hdd_ctx; 5625 5626 hdd_enter_dev(dev); 5627 5628 if (adapter->magic != WLAN_HDD_ADAPTER_MAGIC) { 5629 hdd_err("Invalid magic"); 5630 goto exit; 5631 } 5632 5633 hdd_ctx = WLAN_HDD_GET_CTX(adapter); 5634 if (!hdd_ctx) { 5635 hdd_err("NULL hdd_ctx"); 5636 goto exit; 5637 } 5638 5639 if (dev != adapter->dev) 5640 hdd_err("Invalid device reference"); 5641 5642 hdd_deinit_adapter(hdd_ctx, adapter, true); 5643 5644 /* after uninit our adapter structure will no longer be valid */ 5645 adapter->magic = 0; 5646 5647 exit: 5648 hdd_exit(); 5649 } 5650 hdd_open_cesium_nl_sock(void)5651 static int hdd_open_cesium_nl_sock(void) 5652 { 5653 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0)) 5654 struct netlink_kernel_cfg cfg = { 5655 .groups = WLAN_NLINK_MCAST_GRP_ID, 5656 .input = NULL 5657 }; 5658 #endif 5659 int ret = 0; 5660 5661 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0)) 5662 cesium_nl_srv_sock = netlink_kernel_create(&init_net, WLAN_NLINK_CESIUM, 5663 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 7, 0)) 5664 THIS_MODULE, 5665 #endif 5666 &cfg); 5667 #else 5668 cesium_nl_srv_sock = netlink_kernel_create(&init_net, WLAN_NLINK_CESIUM, 5669 WLAN_NLINK_MCAST_GRP_ID, 5670 NULL, NULL, THIS_MODULE); 5671 #endif 5672 5673 if (!cesium_nl_srv_sock) { 5674 hdd_err("NLINK: cesium netlink_kernel_create failed"); 5675 ret = -ECONNREFUSED; 5676 } 5677 5678 return ret; 5679 } 5680 hdd_close_cesium_nl_sock(void)5681 static void hdd_close_cesium_nl_sock(void) 5682 { 5683 if (cesium_nl_srv_sock) { 5684 netlink_kernel_release(cesium_nl_srv_sock); 5685 cesium_nl_srv_sock = NULL; 5686 } 5687 } 5688 hdd_update_dynamic_mac(struct hdd_context * hdd_ctx,struct qdf_mac_addr * curr_mac_addr,struct qdf_mac_addr * new_mac_addr)5689 void hdd_update_dynamic_mac(struct hdd_context *hdd_ctx, 5690 struct qdf_mac_addr *curr_mac_addr, 5691 struct qdf_mac_addr *new_mac_addr) 5692 { 5693 uint8_t i; 5694 5695 hdd_enter(); 5696 5697 for (i = 0; i < QDF_MAX_CONCURRENCY_PERSONA; i++) { 5698 if (!qdf_mem_cmp( 5699 curr_mac_addr->bytes, 5700 &hdd_ctx->dynamic_mac_list[i].dynamic_mac.bytes[0], 5701 sizeof(struct qdf_mac_addr))) { 5702 qdf_mem_copy(&hdd_ctx->dynamic_mac_list[i].dynamic_mac, 5703 new_mac_addr->bytes, 5704 sizeof(struct qdf_mac_addr)); 5705 break; 5706 } 5707 } 5708 5709 hdd_exit(); 5710 } 5711 5712 #if defined(WLAN_FEATURE_11BE_MLO) && defined(CFG80211_11BE_BASIC) && \ 5713 !defined(WLAN_HDD_MULTI_VDEV_SINGLE_NDEV) hdd_set_mld_address(struct hdd_adapter * adapter,const struct qdf_mac_addr * mac_addr)5714 void hdd_set_mld_address(struct hdd_adapter *adapter, 5715 const struct qdf_mac_addr *mac_addr) 5716 { 5717 int i; 5718 bool eht_capab; 5719 struct hdd_adapter *link_adapter; 5720 struct hdd_mlo_adapter_info *mlo_adapter_info; 5721 5722 ucfg_psoc_mlme_get_11be_capab(adapter->hdd_ctx->psoc, &eht_capab); 5723 if (adapter->mlo_adapter_info.is_ml_adapter && eht_capab) { 5724 mlo_adapter_info = &adapter->mlo_adapter_info; 5725 for (i = 0; i < WLAN_MAX_MLD; i++) { 5726 link_adapter = mlo_adapter_info->link_adapter[i]; 5727 if (link_adapter) 5728 qdf_copy_macaddr(&link_adapter->mld_addr, 5729 mac_addr); 5730 } 5731 qdf_copy_macaddr(&adapter->mld_addr, mac_addr); 5732 } 5733 } 5734 5735 /** 5736 * hdd_get_netdev_by_vdev_mac() - Get Netdev based on MAC 5737 * @mac_addr: Vdev MAC address 5738 * 5739 * Get netdev from adapter based upon Vdev MAC address. 5740 * 5741 * Return: netdev pointer. 5742 */ 5743 static qdf_netdev_t hdd_get_netdev_by_vdev_mac(struct qdf_mac_addr * mac_addr)5744 hdd_get_netdev_by_vdev_mac(struct qdf_mac_addr *mac_addr) 5745 { 5746 struct hdd_context *hdd_ctx; 5747 struct hdd_adapter *adapter; 5748 struct hdd_adapter *ml_adapter; 5749 5750 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 5751 if (!hdd_ctx) { 5752 hdd_err("Invalid HDD context"); 5753 return NULL; 5754 } 5755 5756 adapter = hdd_get_adapter_by_macaddr(hdd_ctx, mac_addr->bytes); 5757 if (!adapter) { 5758 hdd_err("Adapter not foud for MAC " QDF_MAC_ADDR_FMT "", 5759 QDF_MAC_ADDR_REF(mac_addr->bytes)); 5760 return NULL; 5761 } 5762 5763 if (adapter->mlo_adapter_info.is_link_adapter && 5764 adapter->mlo_adapter_info.associate_with_ml_adapter) { 5765 ml_adapter = adapter->mlo_adapter_info.ml_adapter; 5766 adapter = ml_adapter; 5767 } 5768 5769 return adapter->dev; 5770 } 5771 #else 5772 static qdf_netdev_t hdd_get_netdev_by_vdev_mac(struct qdf_mac_addr * mac_addr)5773 hdd_get_netdev_by_vdev_mac(struct qdf_mac_addr *mac_addr) 5774 { 5775 struct hdd_context *hdd_ctx; 5776 struct hdd_adapter *adapter; 5777 5778 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 5779 if (!hdd_ctx) { 5780 hdd_err("Invalid HDD context"); 5781 return NULL; 5782 } 5783 5784 adapter = hdd_get_adapter_by_macaddr(hdd_ctx, mac_addr->bytes); 5785 if (!adapter) { 5786 hdd_err("Adapter not foud for MAC " QDF_MAC_ADDR_FMT "", 5787 QDF_MAC_ADDR_REF(mac_addr->bytes)); 5788 return NULL; 5789 } 5790 5791 return adapter->dev; 5792 } 5793 #endif 5794 5795 #ifdef WLAN_FEATURE_DYNAMIC_MAC_ADDR_UPDATE 5796 #if defined(WLAN_FEATURE_11BE_MLO) && defined(CFG80211_11BE_BASIC) && \ 5797 !defined(WLAN_HDD_MULTI_VDEV_SINGLE_NDEV) hdd_update_set_mac_addr_req_ctx(struct hdd_adapter * adapter,void * req_ctx)5798 static void hdd_update_set_mac_addr_req_ctx(struct hdd_adapter *adapter, 5799 void *req_ctx) 5800 { 5801 adapter->set_mac_addr_req_ctx = req_ctx; 5802 if (adapter->mlo_adapter_info.associate_with_ml_adapter) 5803 adapter->mlo_adapter_info.ml_adapter->set_mac_addr_req_ctx = 5804 req_ctx; 5805 } 5806 #else hdd_update_set_mac_addr_req_ctx(struct hdd_adapter * adapter,void * req_ctx)5807 static void hdd_update_set_mac_addr_req_ctx(struct hdd_adapter *adapter, 5808 void *req_ctx) 5809 { 5810 adapter->set_mac_addr_req_ctx = req_ctx; 5811 } 5812 #endif 5813 5814 /** 5815 * hdd_is_dynamic_set_mac_addr_supported() - API to check dynamic MAC address 5816 * update is supported or not 5817 * @hdd_ctx: Pointer to the HDD context 5818 * 5819 * Return: true or false 5820 */ 5821 static inline bool hdd_is_dynamic_set_mac_addr_supported(struct hdd_context * hdd_ctx)5822 hdd_is_dynamic_set_mac_addr_supported(struct hdd_context *hdd_ctx) 5823 { 5824 return hdd_ctx->is_vdev_macaddr_dynamic_update_supported; 5825 } 5826 hdd_is_dynamic_set_mac_addr_allowed(struct hdd_adapter * adapter)5827 bool hdd_is_dynamic_set_mac_addr_allowed(struct hdd_adapter *adapter) 5828 { 5829 if (!adapter->deflink->vdev) { 5830 hdd_err("VDEV is NULL"); 5831 return false; 5832 } 5833 5834 if (!hdd_is_dynamic_set_mac_addr_supported(adapter->hdd_ctx)) { 5835 hdd_info_rl("On iface up, set mac address change isn't supported"); 5836 return false; 5837 } 5838 5839 switch (adapter->device_mode) { 5840 case QDF_STA_MODE: 5841 if (!cm_is_vdev_disconnected(adapter->deflink->vdev)) { 5842 hdd_info_rl("VDEV is not in disconnected state, set mac address isn't supported"); 5843 return false; 5844 } 5845 return true; 5846 case QDF_P2P_DEVICE_MODE: 5847 return ucfg_is_p2p_device_dynamic_set_mac_addr_supported(adapter->hdd_ctx->psoc); 5848 case QDF_SAP_MODE: 5849 if (test_bit(SOFTAP_BSS_STARTED, 5850 &adapter->deflink->link_flags)) { 5851 hdd_info_rl("SAP is in up state, set mac address isn't supported"); 5852 return false; 5853 } else { 5854 return true; 5855 } 5856 default: 5857 hdd_info_rl("Dynamic set mac address isn't supported for opmode:%d", 5858 adapter->device_mode); 5859 return false; 5860 } 5861 } 5862 hdd_dynamic_mac_address_set(struct wlan_hdd_link_info * link_info,struct qdf_mac_addr mac_addr,struct qdf_mac_addr mld_addr,bool update_self_peer)5863 int hdd_dynamic_mac_address_set(struct wlan_hdd_link_info *link_info, 5864 struct qdf_mac_addr mac_addr, 5865 struct qdf_mac_addr mld_addr, 5866 bool update_self_peer) 5867 { 5868 int ret; 5869 void *cookie; 5870 bool update_mld_addr; 5871 uint32_t fw_resp_status; 5872 QDF_STATUS status = QDF_STATUS_SUCCESS; 5873 struct osif_request *request; 5874 struct wlan_objmgr_vdev *vdev; 5875 struct hdd_adapter *adapter = link_info->adapter; 5876 struct hdd_context *hdd_ctx = adapter->hdd_ctx; 5877 struct mac_addr_set_priv *priv; 5878 static const struct osif_request_params params = { 5879 .priv_size = sizeof(*priv), 5880 .timeout_ms = WLAN_SET_MAC_ADDR_TIMEOUT 5881 }; 5882 5883 vdev = hdd_objmgr_get_vdev_by_user(link_info, WLAN_OSIF_ID); 5884 if (!vdev) 5885 return -EINVAL; 5886 5887 if (wlan_vdev_mlme_get_opmode(vdev) != QDF_P2P_DEVICE_MODE) { 5888 status = ucfg_vdev_mgr_cdp_vdev_detach(vdev); 5889 if (QDF_IS_STATUS_ERROR(status)) { 5890 hdd_err("Failed to detach CDP vdev. Status:%d", status); 5891 ret = qdf_status_to_os_return(status); 5892 goto vdev_ref; 5893 } 5894 } 5895 request = osif_request_alloc(¶ms); 5896 if (!request) { 5897 hdd_err("request alloc fail"); 5898 status = QDF_STATUS_E_NOMEM; 5899 ret = -ENOMEM; 5900 goto status_ret; 5901 } 5902 5903 /* Host should hold a wake lock until the FW event response is received 5904 * the WMI event would not be a wake up event. 5905 */ 5906 qdf_runtime_pm_prevent_suspend( 5907 &hdd_ctx->runtime_context.dyn_mac_addr_update); 5908 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_DYN_MAC_ADDR_UPDATE); 5909 5910 cookie = osif_request_cookie(request); 5911 hdd_update_set_mac_addr_req_ctx(adapter, cookie); 5912 5913 priv = (struct mac_addr_set_priv *)osif_request_priv(request); 5914 5915 /* For p2p device mode, need send delete self peer cmd to F/W, 5916 * To avoid p2p new DP vdev is created before old DP vdev deleted, 5917 * don't create new DP vdev until both self peer delete rsp and set 5918 * mac addr rsp received, so initialize pending_rsp_cnt as 2. 5919 * 5920 * For other mode like STA/SAP, don't need send delete self peer cmd 5921 * to F/W, only need wait set mad addr rsp, so initialize 5922 * pending_rsp_cnt as 1. 5923 */ 5924 if (wlan_vdev_mlme_get_opmode(vdev) == QDF_P2P_DEVICE_MODE) 5925 qdf_atomic_set(&priv->pending_rsp_cnt, 2); 5926 else 5927 qdf_atomic_set(&priv->pending_rsp_cnt, 1); 5928 5929 status = sme_send_set_mac_addr(mac_addr, mld_addr, vdev); 5930 ret = qdf_status_to_os_return(status); 5931 if (QDF_IS_STATUS_ERROR(status)) { 5932 hdd_nofl_err("Failed to send set MAC address command. Status:%d", 5933 status); 5934 osif_request_put(request); 5935 goto status_ret; 5936 } else { 5937 ret = osif_request_wait_for_response(request); 5938 if (ret) { 5939 hdd_err("Set MAC address response timed out"); 5940 } else { 5941 fw_resp_status = priv->fw_resp_status; 5942 if (fw_resp_status) { 5943 hdd_err("Set MAC address failed in FW. Status: %d", 5944 fw_resp_status); 5945 ret = -EAGAIN; 5946 } 5947 } 5948 } 5949 5950 osif_request_put(request); 5951 5952 if (qdf_is_macaddr_zero(&mld_addr)) 5953 update_mld_addr = false; 5954 else 5955 update_mld_addr = true; 5956 5957 status = sme_update_vdev_mac_addr(vdev, mac_addr, mld_addr, 5958 update_self_peer, update_mld_addr, 5959 ret); 5960 5961 status_ret: 5962 if (QDF_IS_STATUS_ERROR(status)) { 5963 ret = qdf_status_to_os_return(status); 5964 goto allow_suspend; 5965 } else if (!ret) { 5966 status = ucfg_dp_update_link_mac_addr(vdev, &mac_addr, false); 5967 if (QDF_IS_STATUS_ERROR(status)) { 5968 ret = qdf_status_to_os_return(status); 5969 hdd_err("DP link MAC update failed"); 5970 goto allow_suspend; 5971 } 5972 } 5973 sme_vdev_set_data_tx_callback(vdev); 5974 5975 /* Update FW WoW pattern with new MAC address */ 5976 ucfg_pmo_del_wow_pattern(vdev); 5977 ucfg_pmo_register_wow_default_patterns(vdev); 5978 hdd_tx_latency_restore_config(link_info); 5979 5980 allow_suspend: 5981 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DYN_MAC_ADDR_UPDATE); 5982 qdf_runtime_pm_allow_suspend( 5983 &hdd_ctx->runtime_context.dyn_mac_addr_update); 5984 5985 vdev_ref: 5986 hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_ID); 5987 5988 return ret; 5989 } 5990 hdd_set_mac_addr_event_cb(uint8_t vdev_id,uint8_t status)5991 static void hdd_set_mac_addr_event_cb(uint8_t vdev_id, uint8_t status) 5992 { 5993 struct hdd_context *hdd_ctx; 5994 struct wlan_hdd_link_info *link_info; 5995 struct osif_request *req; 5996 struct mac_addr_set_priv *priv; 5997 5998 osif_debug("enter"); 5999 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 6000 if (!hdd_ctx) { 6001 hdd_err("Invalid HDD context"); 6002 return; 6003 } 6004 6005 link_info = hdd_get_link_info_by_vdev(hdd_ctx, vdev_id); 6006 if (!link_info) { 6007 hdd_err("No adapter found for VDEV ID:%d", vdev_id); 6008 return; 6009 } 6010 6011 req = osif_request_get(link_info->adapter->set_mac_addr_req_ctx); 6012 if (!req) { 6013 osif_err("Obsolete request for VDEV ID:%d", vdev_id); 6014 return; 6015 } 6016 6017 priv = (struct mac_addr_set_priv *)osif_request_priv(req); 6018 6019 if (qdf_atomic_dec_and_test(&priv->pending_rsp_cnt)) { 6020 priv->fw_resp_status = status; 6021 osif_request_complete(req); 6022 } 6023 6024 osif_request_put(req); 6025 } 6026 #else 6027 static inline bool hdd_is_dynamic_set_mac_addr_supported(struct hdd_context * hdd_ctx)6028 hdd_is_dynamic_set_mac_addr_supported(struct hdd_context *hdd_ctx) 6029 { 6030 return false; 6031 } 6032 #endif 6033 6034 #if defined(WLAN_FEATURE_11BE_MLO) && defined(WLAN_HDD_MULTI_VDEV_SINGLE_NDEV) 6035 static QDF_STATUS hdd_adapter_update_links_on_link_switch(struct wlan_hdd_link_info * cur_link_info,struct wlan_hdd_link_info * new_link_info)6036 hdd_adapter_update_links_on_link_switch(struct wlan_hdd_link_info *cur_link_info, 6037 struct wlan_hdd_link_info *new_link_info) 6038 { 6039 unsigned long link_flags; 6040 struct wlan_objmgr_vdev *vdev; 6041 int cur_link_idx, new_link_idx; 6042 uint8_t cur_old_pos, cur_new_pos; 6043 struct vdev_osif_priv *vdev_priv; 6044 struct hdd_adapter *adapter = cur_link_info->adapter; 6045 6046 /* Update the new position of current and new link info 6047 * in the link info array. 6048 */ 6049 cur_link_idx = hdd_adapter_get_index_of_link_info(cur_link_info); 6050 new_link_idx = hdd_adapter_get_index_of_link_info(new_link_info); 6051 6052 cur_old_pos = adapter->curr_link_info_map[cur_link_idx]; 6053 cur_new_pos = adapter->curr_link_info_map[new_link_idx]; 6054 6055 adapter->curr_link_info_map[new_link_idx] = cur_old_pos; 6056 adapter->curr_link_info_map[cur_link_idx] = cur_new_pos; 6057 6058 /* Move VDEV from current link info to new link info */ 6059 qdf_atomic_clear_bit(cur_link_idx, &adapter->active_links); 6060 qdf_spin_lock_bh(&cur_link_info->vdev_lock); 6061 vdev = cur_link_info->vdev; 6062 cur_link_info->vdev = NULL; 6063 cur_link_info->vdev_id = WLAN_INVALID_VDEV_ID; 6064 qdf_spin_unlock_bh(&cur_link_info->vdev_lock); 6065 6066 qdf_spin_lock_bh(&new_link_info->vdev_lock); 6067 new_link_info->vdev = vdev; 6068 new_link_info->vdev_id = wlan_vdev_get_id(vdev); 6069 qdf_spin_unlock_bh(&new_link_info->vdev_lock); 6070 qdf_atomic_set_bit(new_link_idx, &adapter->active_links); 6071 6072 /* Move the link flags between current and new link info */ 6073 link_flags = new_link_info->link_flags; 6074 new_link_info->link_flags = cur_link_info->link_flags; 6075 cur_link_info->link_flags = link_flags; 6076 6077 /* Update VDEV-OSIF priv pointer to new link info */ 6078 vdev_priv = wlan_vdev_get_ospriv(new_link_info->vdev); 6079 vdev_priv->legacy_osif_priv = new_link_info; 6080 6081 return QDF_STATUS_SUCCESS; 6082 } 6083 6084 struct wlan_hdd_link_info * hdd_get_link_info_by_ieee_link_id(struct hdd_adapter * adapter,int32_t link_id)6085 hdd_get_link_info_by_ieee_link_id(struct hdd_adapter *adapter, int32_t link_id) 6086 { 6087 struct wlan_hdd_link_info *link_info; 6088 struct hdd_station_ctx *sta_ctx; 6089 6090 if (!adapter || link_id == WLAN_INVALID_LINK_ID) { 6091 hdd_err("NULL adapter or invalid link ID"); 6092 return NULL; 6093 } 6094 6095 hdd_adapter_for_each_link_info(adapter, link_info) { 6096 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(link_info); 6097 if (sta_ctx->conn_info.ieee_link_id == link_id) 6098 return link_info; 6099 } 6100 6101 return NULL; 6102 } 6103 6104 QDF_STATUS hdd_link_switch_vdev_mac_addr_update(int32_t ieee_old_link_id,int32_t ieee_new_link_id,uint8_t vdev_id)6105 hdd_link_switch_vdev_mac_addr_update(int32_t ieee_old_link_id, 6106 int32_t ieee_new_link_id, uint8_t vdev_id) 6107 { 6108 QDF_STATUS status = QDF_STATUS_E_INVAL; 6109 struct hdd_context *hdd_ctx; 6110 struct hdd_adapter *adapter; 6111 struct wlan_objmgr_vdev *vdev; 6112 struct wlan_hdd_link_info *cur_link_info, *new_link_info; 6113 struct hdd_station_ctx *sta_ctx; 6114 6115 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 6116 if (!hdd_ctx) { 6117 hdd_err("HDD ctx NULL"); 6118 return QDF_STATUS_E_INVAL; 6119 } 6120 6121 cur_link_info = hdd_get_link_info_by_vdev(hdd_ctx, vdev_id); 6122 if (!cur_link_info) { 6123 hdd_err("VDEV %d not found", vdev_id); 6124 return status; 6125 } 6126 6127 vdev = hdd_objmgr_get_vdev_by_user(cur_link_info, WLAN_OSIF_ID); 6128 if (!vdev) { 6129 hdd_err("Invalid VDEV %d", vdev_id); 6130 return status; 6131 } 6132 6133 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(cur_link_info); 6134 if (sta_ctx->conn_info.ieee_link_id != ieee_old_link_id) { 6135 hdd_err("Link id %d mismatch", sta_ctx->conn_info.ieee_link_id); 6136 goto release_ref; 6137 } 6138 6139 adapter = cur_link_info->adapter; 6140 new_link_info = hdd_get_link_info_by_ieee_link_id(adapter, 6141 ieee_new_link_id); 6142 if (!new_link_info) { 6143 hdd_err("Link id %d not found", ieee_new_link_id); 6144 goto release_ref; 6145 } 6146 6147 status = ucfg_dp_update_link_mac_addr(vdev, &new_link_info->link_addr, 6148 true); 6149 if (QDF_IS_STATUS_ERROR(status)) { 6150 hdd_err("DP link MAC update failed"); 6151 goto release_ref; 6152 } 6153 6154 status = hdd_adapter_update_links_on_link_switch(cur_link_info, 6155 new_link_info); 6156 if (QDF_IS_STATUS_ERROR(status)) { 6157 hdd_err("Failed to update adapter link info"); 6158 goto release_ref; 6159 } 6160 6161 hdd_adapter_update_mlo_mgr_mac_addr(adapter); 6162 sme_vdev_set_data_tx_callback(vdev); 6163 ucfg_pmo_del_wow_pattern(vdev); 6164 ucfg_pmo_register_wow_default_patterns(vdev); 6165 6166 release_ref: 6167 hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_ID); 6168 return status; 6169 } 6170 #endif 6171 6172 /** 6173 * __hdd_set_mac_address() - set the user specified mac address 6174 * @dev: Pointer to the net device. 6175 * @addr: Pointer to the sockaddr. 6176 * 6177 * This function sets the user specified mac address using 6178 * the command ifconfig wlanX hw ether <mac address>. 6179 * 6180 * Return: 0 for success, non zero for failure 6181 */ __hdd_set_mac_address(struct net_device * dev,void * addr)6182 static int __hdd_set_mac_address(struct net_device *dev, void *addr) 6183 { 6184 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev); 6185 struct hdd_adapter *adapter_temp; 6186 struct hdd_context *hdd_ctx; 6187 struct sockaddr *psta_mac_addr = addr; 6188 QDF_STATUS qdf_ret_status = QDF_STATUS_SUCCESS; 6189 int ret; 6190 struct qdf_mac_addr mac_addr; 6191 bool net_if_running = netif_running(dev); 6192 6193 hdd_enter_dev(dev); 6194 6195 hdd_ctx = WLAN_HDD_GET_CTX(adapter); 6196 ret = wlan_hdd_validate_context(hdd_ctx); 6197 if (0 != ret) 6198 return ret; 6199 6200 if (net_if_running) { 6201 if (!hdd_is_dynamic_set_mac_addr_allowed(adapter)) 6202 return -ENOTSUPP; 6203 } 6204 6205 qdf_mem_copy(&mac_addr, psta_mac_addr->sa_data, sizeof(mac_addr)); 6206 adapter_temp = hdd_get_adapter_by_macaddr(hdd_ctx, mac_addr.bytes); 6207 if (adapter_temp) { 6208 if (!qdf_str_cmp(adapter_temp->dev->name, dev->name)) 6209 return 0; 6210 hdd_err("%s adapter exist with same address " QDF_MAC_ADDR_FMT, 6211 adapter_temp->dev->name, 6212 QDF_MAC_ADDR_REF(mac_addr.bytes)); 6213 return -EINVAL; 6214 } 6215 qdf_ret_status = wlan_hdd_validate_mac_address(&mac_addr); 6216 if (QDF_IS_STATUS_ERROR(qdf_ret_status)) 6217 return -EINVAL; 6218 6219 hdd_nofl_debug("Changing MAC to " 6220 QDF_MAC_ADDR_FMT " of the interface %s ", 6221 QDF_MAC_ADDR_REF(mac_addr.bytes), dev->name); 6222 6223 if (net_if_running && adapter->deflink->vdev) { 6224 ret = hdd_update_vdev_mac_address(adapter, mac_addr); 6225 if (ret) 6226 return ret; 6227 } 6228 6229 hdd_set_mld_address(adapter, &mac_addr); 6230 6231 hdd_update_dynamic_mac(hdd_ctx, &adapter->mac_addr, &mac_addr); 6232 ucfg_dp_update_intf_mac(hdd_ctx->psoc, &adapter->mac_addr, &mac_addr, 6233 adapter->deflink->vdev); 6234 memcpy(&adapter->mac_addr, psta_mac_addr->sa_data, ETH_ALEN); 6235 qdf_net_update_net_device_dev_addr(dev, psta_mac_addr->sa_data, 6236 ETH_ALEN); 6237 6238 hdd_exit(); 6239 return ret; 6240 } 6241 6242 /** 6243 * hdd_set_mac_address() - Wrapper function to protect __hdd_set_mac_address() 6244 * function from SSR 6245 * @net_dev: pointer to net_device structure 6246 * @addr: Pointer to the sockaddr 6247 * 6248 * This function sets the user specified mac address using 6249 * the command ifconfig wlanX hw ether <mac address>. 6250 * 6251 * Return: 0 for success. 6252 */ hdd_set_mac_address(struct net_device * net_dev,void * addr)6253 static int hdd_set_mac_address(struct net_device *net_dev, void *addr) 6254 { 6255 struct osif_vdev_sync *vdev_sync; 6256 int errno; 6257 6258 errno = osif_vdev_sync_op_start(net_dev, &vdev_sync); 6259 if (errno) 6260 return errno; 6261 6262 errno = __hdd_set_mac_address(net_dev, addr); 6263 6264 osif_vdev_sync_op_stop(vdev_sync); 6265 6266 return errno; 6267 } 6268 wlan_hdd_get_derived_intf_addr(struct hdd_context * hdd_ctx)6269 static uint8_t *wlan_hdd_get_derived_intf_addr(struct hdd_context *hdd_ctx) 6270 { 6271 int i, j; 6272 6273 i = qdf_ffz(hdd_ctx->derived_intf_addr_mask); 6274 if (i < 0 || i >= hdd_ctx->num_derived_addr) 6275 return NULL; 6276 qdf_atomic_set_bit(i, &hdd_ctx->derived_intf_addr_mask); 6277 hdd_nofl_debug("Assigning MAC from derived list "QDF_MAC_ADDR_FMT, 6278 QDF_MAC_ADDR_REF(hdd_ctx->derived_mac_addr[i].bytes)); 6279 6280 /* Copy the mac in dynamic mac list at first free position */ 6281 for (j = 0; j < QDF_MAX_CONCURRENCY_PERSONA; j++) { 6282 if (qdf_is_macaddr_zero(&hdd_ctx-> 6283 dynamic_mac_list[j].dynamic_mac)) 6284 break; 6285 } 6286 if (j == QDF_MAX_CONCURRENCY_PERSONA) { 6287 hdd_err("Max interfaces are up"); 6288 return NULL; 6289 } 6290 6291 qdf_mem_copy(&hdd_ctx->dynamic_mac_list[j].dynamic_mac.bytes, 6292 &hdd_ctx->derived_mac_addr[i].bytes, 6293 sizeof(struct qdf_mac_addr)); 6294 hdd_ctx->dynamic_mac_list[j].is_provisioned_mac = false; 6295 hdd_ctx->dynamic_mac_list[j].bit_position = i; 6296 6297 return hdd_ctx->derived_mac_addr[i].bytes; 6298 } 6299 wlan_hdd_get_provisioned_intf_addr(struct hdd_context * hdd_ctx)6300 static uint8_t *wlan_hdd_get_provisioned_intf_addr(struct hdd_context *hdd_ctx) 6301 { 6302 int i, j; 6303 6304 i = qdf_ffz(hdd_ctx->provisioned_intf_addr_mask); 6305 if (i < 0 || i >= hdd_ctx->num_provisioned_addr) 6306 return NULL; 6307 qdf_atomic_set_bit(i, &hdd_ctx->provisioned_intf_addr_mask); 6308 hdd_debug("Assigning MAC from provisioned list "QDF_MAC_ADDR_FMT, 6309 QDF_MAC_ADDR_REF(hdd_ctx->provisioned_mac_addr[i].bytes)); 6310 6311 /* Copy the mac in dynamic mac list at first free position */ 6312 for (j = 0; j < QDF_MAX_CONCURRENCY_PERSONA; j++) { 6313 if (qdf_is_macaddr_zero(&hdd_ctx-> 6314 dynamic_mac_list[j].dynamic_mac)) 6315 break; 6316 } 6317 if (j == QDF_MAX_CONCURRENCY_PERSONA) { 6318 hdd_err("Max interfaces are up"); 6319 return NULL; 6320 } 6321 6322 qdf_mem_copy(&hdd_ctx->dynamic_mac_list[j].dynamic_mac.bytes, 6323 &hdd_ctx->provisioned_mac_addr[i].bytes, 6324 sizeof(struct qdf_mac_addr)); 6325 hdd_ctx->dynamic_mac_list[j].is_provisioned_mac = true; 6326 hdd_ctx->dynamic_mac_list[j].bit_position = i; 6327 return hdd_ctx->provisioned_mac_addr[i].bytes; 6328 } 6329 wlan_hdd_get_intf_addr(struct hdd_context * hdd_ctx,enum QDF_OPMODE interface_type)6330 uint8_t *wlan_hdd_get_intf_addr(struct hdd_context *hdd_ctx, 6331 enum QDF_OPMODE interface_type) 6332 { 6333 uint8_t *mac_addr = NULL; 6334 6335 if (qdf_atomic_test_bit(interface_type, 6336 (unsigned long *) 6337 (&hdd_ctx->config->provisioned_intf_pool))) 6338 mac_addr = wlan_hdd_get_provisioned_intf_addr(hdd_ctx); 6339 6340 if ((!mac_addr) && 6341 (qdf_atomic_test_bit(interface_type, 6342 (unsigned long *) 6343 (&hdd_ctx->config->derived_intf_pool)))) 6344 mac_addr = wlan_hdd_get_derived_intf_addr(hdd_ctx); 6345 6346 if (!mac_addr) 6347 hdd_err("MAC is not available in both the lists"); 6348 return mac_addr; 6349 } 6350 wlan_hdd_release_intf_addr(struct hdd_context * hdd_ctx,uint8_t * releaseAddr)6351 void wlan_hdd_release_intf_addr(struct hdd_context *hdd_ctx, 6352 uint8_t *releaseAddr) 6353 { 6354 int i; 6355 int mac_pos_in_mask; 6356 6357 for (i = 0; i < QDF_MAX_CONCURRENCY_PERSONA; i++) { 6358 if (!memcmp(releaseAddr, 6359 hdd_ctx->dynamic_mac_list[i].dynamic_mac.bytes, 6360 QDF_MAC_ADDR_SIZE)) { 6361 mac_pos_in_mask = 6362 hdd_ctx->dynamic_mac_list[i].bit_position; 6363 if (hdd_ctx->dynamic_mac_list[i].is_provisioned_mac) { 6364 qdf_atomic_clear_bit( 6365 mac_pos_in_mask, 6366 &hdd_ctx-> 6367 provisioned_intf_addr_mask); 6368 hdd_debug("Releasing MAC from provisioned list"); 6369 hdd_debug( 6370 QDF_MAC_ADDR_FMT, 6371 QDF_MAC_ADDR_REF(releaseAddr)); 6372 } else { 6373 qdf_atomic_clear_bit( 6374 mac_pos_in_mask, &hdd_ctx-> 6375 derived_intf_addr_mask); 6376 hdd_debug("Releasing MAC from derived list"); 6377 hdd_debug(QDF_MAC_ADDR_FMT, 6378 QDF_MAC_ADDR_REF(releaseAddr)); 6379 } 6380 qdf_zero_macaddr(&hdd_ctx-> 6381 dynamic_mac_list[i].dynamic_mac); 6382 hdd_ctx->dynamic_mac_list[i].is_provisioned_mac = 6383 false; 6384 hdd_ctx->dynamic_mac_list[i].bit_position = 0; 6385 break; 6386 } 6387 6388 } 6389 if (i == QDF_MAX_CONCURRENCY_PERSONA) 6390 hdd_debug("Releasing non existing MAC " QDF_MAC_ADDR_FMT, 6391 QDF_MAC_ADDR_REF(releaseAddr)); 6392 } 6393 6394 /** 6395 * hdd_set_derived_multicast_list(): Add derived peer multicast address list in 6396 * multicast list request to the FW 6397 * @psoc: Pointer to psoc 6398 * @adapter: Pointer to hdd adapter 6399 * @mc_list_request: Multicast list request to the FW 6400 * @mc_count: number of multicast addresses received from the kernel 6401 * 6402 * Return: None 6403 */ 6404 static void hdd_set_derived_multicast_list(struct wlan_objmgr_psoc * psoc,struct hdd_adapter * adapter,struct pmo_mc_addr_list_params * mc_list_request,int * mc_count)6405 hdd_set_derived_multicast_list(struct wlan_objmgr_psoc *psoc, 6406 struct hdd_adapter *adapter, 6407 struct pmo_mc_addr_list_params *mc_list_request, 6408 int *mc_count) 6409 { 6410 int i = 0, j = 0, list_count = *mc_count; 6411 struct qdf_mac_addr *peer_mc_addr_list = NULL; 6412 uint8_t driver_mc_cnt = 0; 6413 uint32_t max_ndp_sessions = 0; 6414 6415 cfg_nan_get_ndp_max_sessions(psoc, &max_ndp_sessions); 6416 6417 ucfg_nan_get_peer_mc_list(adapter->deflink->vdev, &peer_mc_addr_list); 6418 6419 for (j = 0; j < max_ndp_sessions; j++) { 6420 for (i = 0; i < list_count; i++) { 6421 if (qdf_is_macaddr_zero(&peer_mc_addr_list[j]) || 6422 qdf_is_macaddr_equal(&mc_list_request->mc_addr[i], 6423 &peer_mc_addr_list[j])) 6424 break; 6425 } 6426 if (i == list_count) { 6427 qdf_mem_copy( 6428 &(mc_list_request->mc_addr[list_count + 6429 driver_mc_cnt].bytes), 6430 peer_mc_addr_list[j].bytes, ETH_ALEN); 6431 hdd_debug("mlist[%d] = " QDF_MAC_ADDR_FMT, 6432 list_count + driver_mc_cnt, 6433 QDF_MAC_ADDR_REF( 6434 mc_list_request->mc_addr[list_count + 6435 driver_mc_cnt].bytes)); 6436 driver_mc_cnt++; 6437 } 6438 } 6439 *mc_count += driver_mc_cnt; 6440 } 6441 6442 /** 6443 * __hdd_set_multicast_list() - set the multicast address list 6444 * @dev: Pointer to the WLAN device. 6445 * 6446 * This function sets the multicast address list. 6447 * 6448 * Return: None 6449 */ __hdd_set_multicast_list(struct net_device * dev)6450 static void __hdd_set_multicast_list(struct net_device *dev) 6451 { 6452 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev); 6453 int i = 0, errno; 6454 struct netdev_hw_addr *ha; 6455 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); 6456 struct pmo_mc_addr_list_params *mc_list_request = NULL; 6457 struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc; 6458 int mc_count = 0; 6459 6460 if (hdd_ctx->hdd_wlan_suspended) { 6461 hdd_err_rl("Device is system suspended"); 6462 return; 6463 } 6464 6465 hdd_enter_dev(dev); 6466 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) 6467 return; 6468 6469 errno = wlan_hdd_validate_context(hdd_ctx); 6470 if (errno) 6471 return; 6472 6473 errno = hdd_validate_adapter(adapter); 6474 if (errno) 6475 return; 6476 6477 if (hdd_ctx->driver_status == DRIVER_MODULES_CLOSED) { 6478 hdd_debug("Driver module is closed"); 6479 return; 6480 } 6481 6482 mc_list_request = qdf_mem_malloc(sizeof(*mc_list_request)); 6483 if (!mc_list_request) 6484 return; 6485 6486 qdf_spin_lock_bh(&adapter->mc_list_lock); 6487 /* Delete already configured multicast address list */ 6488 if (adapter->mc_addr_list.mc_cnt > 0) 6489 hdd_disable_and_flush_mc_addr_list(adapter, 6490 pmo_mc_list_change_notify); 6491 6492 if (dev->flags & IFF_ALLMULTI) { 6493 hdd_debug("allow all multicast frames"); 6494 hdd_disable_and_flush_mc_addr_list(adapter, 6495 pmo_mc_list_change_notify); 6496 } else { 6497 mc_count = netdev_mc_count(dev); 6498 if (mc_count > ucfg_pmo_max_mc_addr_supported(psoc)) { 6499 hdd_debug("Exceeded max MC filter addresses (%d). Allowing all MC frames by disabling MC address filtering", 6500 ucfg_pmo_max_mc_addr_supported(psoc)); 6501 hdd_disable_and_flush_mc_addr_list(adapter, 6502 pmo_mc_list_change_notify); 6503 adapter->mc_addr_list.mc_cnt = 0; 6504 goto free_req; 6505 } 6506 netdev_for_each_mc_addr(ha, dev) { 6507 if (i == mc_count) 6508 break; 6509 memset(&(mc_list_request->mc_addr[i].bytes), 6510 0, ETH_ALEN); 6511 memcpy(&(mc_list_request->mc_addr[i].bytes), 6512 ha->addr, ETH_ALEN); 6513 hdd_debug("mlist[%d] = "QDF_MAC_ADDR_FMT, i, 6514 QDF_MAC_ADDR_REF(mc_list_request->mc_addr[i].bytes)); 6515 i++; 6516 } 6517 6518 if (adapter->device_mode == QDF_NDI_MODE) 6519 hdd_set_derived_multicast_list(psoc, adapter, 6520 mc_list_request, 6521 &mc_count); 6522 } 6523 6524 adapter->mc_addr_list.mc_cnt = mc_count; 6525 mc_list_request->psoc = psoc; 6526 mc_list_request->vdev_id = adapter->deflink->vdev_id; 6527 mc_list_request->count = mc_count; 6528 6529 errno = hdd_cache_mc_addr_list(mc_list_request); 6530 if (errno) { 6531 hdd_debug("Failed to cache MC address list for vdev %u; errno:%d", 6532 adapter->deflink->vdev_id, errno); 6533 goto free_req; 6534 } 6535 6536 hdd_enable_mc_addr_filtering(adapter, pmo_mc_list_change_notify); 6537 6538 free_req: 6539 qdf_spin_unlock_bh(&adapter->mc_list_lock); 6540 qdf_mem_free(mc_list_request); 6541 } 6542 6543 /** 6544 * hdd_set_multicast_list() - SSR wrapper function for __hdd_set_multicast_list 6545 * @net_dev: pointer to net_device 6546 * 6547 * Return: none 6548 */ hdd_set_multicast_list(struct net_device * net_dev)6549 static void hdd_set_multicast_list(struct net_device *net_dev) 6550 { 6551 struct osif_vdev_sync *vdev_sync; 6552 6553 if (osif_vdev_sync_op_start(net_dev, &vdev_sync)) 6554 return; 6555 6556 __hdd_set_multicast_list(net_dev); 6557 6558 osif_vdev_sync_op_stop(vdev_sync); 6559 } 6560 hdd_update_multicast_list(struct wlan_objmgr_vdev * vdev)6561 void hdd_update_multicast_list(struct wlan_objmgr_vdev *vdev) 6562 { 6563 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 6564 struct wlan_hdd_link_info *link_info; 6565 struct hdd_adapter *adapter; 6566 uint8_t vdev_id = wlan_vdev_get_id(vdev); 6567 struct net_device *net_dev; 6568 6569 if (!hdd_ctx) { 6570 hdd_err("hdd_ctx is null"); 6571 return; 6572 } 6573 6574 link_info = hdd_get_link_info_by_vdev(hdd_ctx, vdev_id); 6575 if (!link_info) { 6576 hdd_err("adapter is null for vdev_id %d", vdev_id); 6577 return; 6578 } 6579 6580 adapter = link_info->adapter; 6581 if (!adapter) { 6582 hdd_err("adapter is null for vdev_id %d", vdev_id); 6583 return; 6584 } 6585 6586 net_dev = adapter->dev; 6587 if (!net_dev) { 6588 hdd_err("netdev is null"); 6589 return; 6590 } 6591 6592 __hdd_set_multicast_list(net_dev); 6593 } 6594 6595 #ifdef WLAN_FEATURE_TSF_PTP 6596 static const struct ethtool_ops wlan_ethtool_ops = { 6597 .get_ts_info = wlan_get_ts_info, 6598 }; 6599 #endif 6600 6601 /** 6602 * __hdd_fix_features - Adjust the feature flags needed to be updated 6603 * @net_dev: Handle to net_device 6604 * @features: Currently enabled feature flags 6605 * 6606 * Return: Adjusted feature flags on success, old feature on failure 6607 */ __hdd_fix_features(struct net_device * net_dev,netdev_features_t features)6608 static netdev_features_t __hdd_fix_features(struct net_device *net_dev, 6609 netdev_features_t features) 6610 { 6611 netdev_features_t feature_change_req = features; 6612 netdev_features_t feature_tso_csum; 6613 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(net_dev); 6614 6615 if (!adapter->handle_feature_update) { 6616 hdd_debug("Not triggered by hdd_netdev_update_features"); 6617 return features; 6618 } 6619 6620 feature_tso_csum = hdd_get_tso_csum_feature_flags(); 6621 if (hdd_is_legacy_connection(adapter->deflink)) { 6622 /* Disable checksum and TSO */ 6623 feature_change_req &= ~feature_tso_csum; 6624 adapter->tso_csum_feature_enabled = 0; 6625 } else { 6626 /* Enable checksum and TSO */ 6627 feature_change_req |= feature_tso_csum; 6628 adapter->tso_csum_feature_enabled = 1; 6629 } 6630 hdd_debug("vdev mode %d current features 0x%llx, requesting feature change 0x%llx", 6631 adapter->device_mode, net_dev->features, 6632 feature_change_req); 6633 6634 return feature_change_req; 6635 } 6636 6637 /** 6638 * hdd_fix_features() - Wrapper for __hdd_fix_features to protect it from SSR 6639 * @net_dev: Pointer to net_device structure 6640 * @features: Updated features set 6641 * 6642 * Adjusts the feature request, do not update the device yet. 6643 * 6644 * Return: updated feature for success, incoming feature as is on failure 6645 */ hdd_fix_features(struct net_device * net_dev,netdev_features_t features)6646 static netdev_features_t hdd_fix_features(struct net_device *net_dev, 6647 netdev_features_t features) 6648 { 6649 int errno; 6650 int changed_features = features; 6651 struct osif_vdev_sync *vdev_sync; 6652 6653 errno = osif_vdev_sync_op_start(net_dev, &vdev_sync); 6654 if (errno) 6655 return features; 6656 6657 changed_features = __hdd_fix_features(net_dev, features); 6658 6659 osif_vdev_sync_op_stop(vdev_sync); 6660 6661 return changed_features; 6662 } 6663 /** 6664 * __hdd_set_features - Notify device about change in features 6665 * @net_dev: Handle to net_device 6666 * @features: Existing + requested feature after resolving the dependency 6667 * 6668 * Return: 0 on success, non zero error on failure 6669 */ __hdd_set_features(struct net_device * net_dev,netdev_features_t features)6670 static int __hdd_set_features(struct net_device *net_dev, 6671 netdev_features_t features) 6672 { 6673 struct hdd_adapter *adapter = netdev_priv(net_dev); 6674 ol_txrx_soc_handle soc = cds_get_context(QDF_MODULE_ID_SOC); 6675 6676 if (!adapter->handle_feature_update) { 6677 hdd_debug("Not triggered by hdd_netdev_update_features"); 6678 return 0; 6679 } 6680 6681 if (!soc) 6682 return 0; 6683 6684 hdd_debug("vdev mode %d vdev_id %d current features 0x%llx, changed features 0x%llx", 6685 adapter->device_mode, adapter->deflink->vdev_id, 6686 net_dev->features, features); 6687 6688 return 0; 6689 } 6690 6691 /** 6692 * hdd_set_features() - Wrapper for __hdd_set_features to protect it from SSR 6693 * @net_dev: Pointer to net_device structure 6694 * @features: Updated features set 6695 * 6696 * Is called to update device configurations for changed features. 6697 * 6698 * Return: 0 for success, non-zero for failure 6699 */ hdd_set_features(struct net_device * net_dev,netdev_features_t features)6700 static int hdd_set_features(struct net_device *net_dev, 6701 netdev_features_t features) 6702 { 6703 int errno; 6704 struct osif_vdev_sync *vdev_sync; 6705 6706 errno = osif_vdev_sync_op_start(net_dev, &vdev_sync); 6707 if (errno) { 6708 /* 6709 * Only invoke from netdev_feature_update_work expected, 6710 * which is from CLD inside. 6711 * Ignore others from upper stack during loading phase, 6712 * and return success to avoid failure print from kernel. 6713 */ 6714 hdd_debug("VDEV in transition, ignore set_features"); 6715 return 0; 6716 } 6717 6718 errno = __hdd_set_features(net_dev, features); 6719 6720 osif_vdev_sync_op_stop(vdev_sync); 6721 6722 return errno; 6723 } 6724 6725 #define HDD_NETDEV_FEATURES_UPDATE_MAX_WAIT_COUNT 10 6726 #define HDD_NETDEV_FEATURES_UPDATE_WAIT_INTERVAL_MS 20 6727 hdd_netdev_update_features(struct hdd_adapter * adapter)6728 void hdd_netdev_update_features(struct hdd_adapter *adapter) 6729 { 6730 struct net_device *net_dev = adapter->dev; 6731 ol_txrx_soc_handle soc = cds_get_context(QDF_MODULE_ID_SOC); 6732 bool request_feature_update = false; 6733 int wait_count = HDD_NETDEV_FEATURES_UPDATE_MAX_WAIT_COUNT; 6734 6735 if (!soc) 6736 return; 6737 6738 if (!cdp_cfg_get(soc, cfg_dp_disable_legacy_mode_csum_offload)) 6739 return; 6740 6741 switch (adapter->device_mode) { 6742 case QDF_STA_MODE: 6743 if (cdp_cfg_get(soc, cfg_dp_enable_ip_tcp_udp_checksum_offload)) 6744 request_feature_update = true; 6745 break; 6746 default: 6747 break; 6748 } 6749 6750 if (request_feature_update) { 6751 hdd_debug("Update net_dev features for device mode %d", 6752 adapter->device_mode); 6753 while (!adapter->delete_in_progress) { 6754 if (rtnl_trylock()) { 6755 adapter->handle_feature_update = true; 6756 netdev_update_features(net_dev); 6757 adapter->handle_feature_update = false; 6758 rtnl_unlock(); 6759 break; 6760 } 6761 6762 if (wait_count--) { 6763 qdf_sleep( 6764 HDD_NETDEV_FEATURES_UPDATE_WAIT_INTERVAL_MS); 6765 } else { 6766 /* 6767 * We have failed to updated the netdev 6768 * features for very long, so enable the queues 6769 * now. The impact of not being able to update 6770 * the netdev feature is lower TPUT when 6771 * switching from legacy to non-legacy mode. 6772 */ 6773 hdd_err("Failed to update netdev features for device mode %d", 6774 adapter->device_mode); 6775 break; 6776 } 6777 } 6778 } 6779 } 6780 6781 static const struct net_device_ops wlan_drv_ops = { 6782 .ndo_open = hdd_open, 6783 .ndo_stop = hdd_stop, 6784 .ndo_uninit = hdd_uninit, 6785 .ndo_start_xmit = hdd_hard_start_xmit, 6786 .ndo_fix_features = hdd_fix_features, 6787 .ndo_set_features = hdd_set_features, 6788 .ndo_tx_timeout = hdd_tx_timeout, 6789 .ndo_get_stats = hdd_get_stats, 6790 #if LINUX_VERSION_CODE < KERNEL_VERSION(5, 15, 0) 6791 .ndo_do_ioctl = hdd_ioctl, 6792 #endif 6793 .ndo_set_mac_address = hdd_set_mac_address, 6794 .ndo_select_queue = hdd_select_queue, 6795 .ndo_set_rx_mode = hdd_set_multicast_list, 6796 #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0) 6797 .ndo_siocdevprivate = hdd_dev_private_ioctl, 6798 #endif 6799 }; 6800 6801 #ifdef FEATURE_MONITOR_MODE_SUPPORT 6802 /* Monitor mode net_device_ops, does not Tx and most of operations. */ 6803 static const struct net_device_ops wlan_mon_drv_ops = { 6804 .ndo_open = hdd_mon_open, 6805 .ndo_stop = hdd_stop, 6806 .ndo_get_stats = hdd_get_stats, 6807 }; 6808 6809 /** 6810 * hdd_set_mon_ops() - update net_device ops for monitor mode 6811 * @dev: Handle to struct net_device to be updated. 6812 * Return: None 6813 */ hdd_set_mon_ops(struct net_device * dev)6814 static void hdd_set_mon_ops(struct net_device *dev) 6815 { 6816 dev->netdev_ops = &wlan_mon_drv_ops; 6817 } 6818 6819 #ifdef WLAN_FEATURE_TSF_PTP hdd_set_station_ops(struct net_device * dev)6820 void hdd_set_station_ops(struct net_device *dev) 6821 { 6822 if (cds_get_conparam() == QDF_GLOBAL_MONITOR_MODE) { 6823 hdd_set_mon_ops(dev); 6824 } else { 6825 dev->netdev_ops = &wlan_drv_ops; 6826 dev->ethtool_ops = &wlan_ethtool_ops; 6827 } 6828 } 6829 #else hdd_set_station_ops(struct net_device * dev)6830 void hdd_set_station_ops(struct net_device *dev) 6831 { 6832 if (cds_get_conparam() == QDF_GLOBAL_MONITOR_MODE) 6833 hdd_set_mon_ops(dev); 6834 else 6835 dev->netdev_ops = &wlan_drv_ops; 6836 } 6837 6838 #endif 6839 #else 6840 #ifdef WLAN_FEATURE_TSF_PTP hdd_set_station_ops(struct net_device * dev)6841 void hdd_set_station_ops(struct net_device *dev) 6842 { 6843 dev->netdev_ops = &wlan_drv_ops; 6844 dev->ethtool_ops = &wlan_ethtool_ops; 6845 } 6846 #else hdd_set_station_ops(struct net_device * dev)6847 void hdd_set_station_ops(struct net_device *dev) 6848 { 6849 dev->netdev_ops = &wlan_drv_ops; 6850 } 6851 #endif hdd_set_mon_ops(struct net_device * dev)6852 static void hdd_set_mon_ops(struct net_device *dev) 6853 { 6854 } 6855 #endif 6856 6857 #ifdef WLAN_FEATURE_PKT_CAPTURE 6858 /* Packet Capture mode net_device_ops, does not Tx and most of operations. */ 6859 static const struct net_device_ops wlan_pktcapture_drv_ops = { 6860 .ndo_open = hdd_pktcapture_open, 6861 .ndo_stop = hdd_stop, 6862 .ndo_get_stats = hdd_get_stats, 6863 }; 6864 hdd_set_pktcapture_ops(struct net_device * dev)6865 static void hdd_set_pktcapture_ops(struct net_device *dev) 6866 { 6867 dev->netdev_ops = &wlan_pktcapture_drv_ops; 6868 } 6869 #else hdd_set_pktcapture_ops(struct net_device * dev)6870 static void hdd_set_pktcapture_ops(struct net_device *dev) 6871 { 6872 } 6873 #endif 6874 6875 #ifdef MULTI_CLIENT_LL_SUPPORT 6876 /** 6877 * hdd_set_multi_client_ll_support() - set multi client ll support flag in 6878 * allocated station hdd adapter 6879 * @adapter: pointer to hdd adapter 6880 * 6881 * Return: none 6882 */ hdd_set_multi_client_ll_support(struct hdd_adapter * adapter)6883 static void hdd_set_multi_client_ll_support(struct hdd_adapter *adapter) 6884 { 6885 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); 6886 bool multi_client_ll_ini_support, multi_client_ll_caps; 6887 6888 ucfg_mlme_cfg_get_multi_client_ll_ini_support(hdd_ctx->psoc, 6889 &multi_client_ll_ini_support); 6890 multi_client_ll_caps = 6891 ucfg_mlme_get_wlm_multi_client_ll_caps(hdd_ctx->psoc); 6892 6893 hdd_debug("fw caps: %d, ini: %d", multi_client_ll_caps, 6894 multi_client_ll_ini_support); 6895 if (multi_client_ll_caps && multi_client_ll_ini_support) 6896 adapter->multi_client_ll_support = true; 6897 } 6898 #else 6899 static inline void hdd_set_multi_client_ll_support(struct hdd_adapter * adapter)6900 hdd_set_multi_client_ll_support(struct hdd_adapter *adapter) 6901 { 6902 } 6903 #endif 6904 6905 /** 6906 * hdd_alloc_station_adapter() - allocate the station hdd adapter 6907 * @hdd_ctx: global hdd context 6908 * @mac_addr: mac address to assign to the interface 6909 * @name_assign_type: name assignment type 6910 * @name: User-visible name of the interface 6911 * @session_type: interface type to be created 6912 * 6913 * hdd adapter pointer would point to the netdev->priv space, this function 6914 * would retrieve the pointer, and setup the hdd adapter configuration. 6915 * 6916 * Return: the pointer to hdd adapter, otherwise NULL 6917 */ 6918 static struct hdd_adapter * hdd_alloc_station_adapter(struct hdd_context * hdd_ctx,tSirMacAddr mac_addr,unsigned char name_assign_type,const char * name,uint8_t session_type)6919 hdd_alloc_station_adapter(struct hdd_context *hdd_ctx, tSirMacAddr mac_addr, 6920 unsigned char name_assign_type, const char *name, 6921 uint8_t session_type) 6922 { 6923 struct net_device *dev; 6924 struct hdd_adapter *adapter; 6925 QDF_STATUS qdf_status; 6926 uint8_t latency_level; 6927 6928 /* cfg80211 initialization and registration */ 6929 dev = alloc_netdev_mqs(sizeof(*adapter), name, 6930 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS) 6931 name_assign_type, 6932 #endif 6933 ((cds_get_conparam() == QDF_GLOBAL_MONITOR_MODE || 6934 wlan_hdd_is_session_type_monitor(session_type)) ? 6935 hdd_mon_mode_ether_setup : ether_setup), 6936 NUM_TX_QUEUES, NUM_RX_QUEUES); 6937 6938 if (!dev) { 6939 hdd_err("Failed to allocate new net_device '%s'", name); 6940 return NULL; 6941 } 6942 6943 adapter = netdev_priv(dev); 6944 6945 qdf_mem_zero(adapter, sizeof(*adapter)); 6946 adapter->dev = dev; 6947 adapter->deflink = &adapter->link_info[WLAN_HDD_DEFLINK_IDX]; 6948 adapter->hdd_ctx = hdd_ctx; 6949 adapter->magic = WLAN_HDD_ADAPTER_MAGIC; 6950 qdf_atomic_set_bit(WLAN_HDD_DEFLINK_IDX, &adapter->active_links); 6951 6952 qdf_status = hdd_monitor_mode_qdf_create_event(adapter, session_type); 6953 if (QDF_IS_STATUS_ERROR(qdf_status)) { 6954 hdd_err_rl("create monitor mode vdve up event failed"); 6955 goto free_net_dev; 6956 } 6957 6958 hdd_update_dynamic_tsf_sync(adapter); 6959 adapter->is_link_up_service_needed = false; 6960 adapter->send_mode_change = true; 6961 6962 /* Cache station count initialize to zero */ 6963 qdf_atomic_init(&adapter->cache_sta_count); 6964 6965 /* Init the net_device structure */ 6966 strlcpy(dev->name, name, IFNAMSIZ); 6967 6968 qdf_net_update_net_device_dev_addr(dev, mac_addr, sizeof(tSirMacAddr)); 6969 qdf_mem_copy(adapter->mac_addr.bytes, mac_addr, sizeof(tSirMacAddr)); 6970 dev->watchdog_timeo = HDD_TX_TIMEOUT; 6971 6972 if (wlan_hdd_is_session_type_monitor(session_type)) { 6973 if (ucfg_pkt_capture_get_mode(hdd_ctx->psoc) != 6974 PACKET_CAPTURE_MODE_DISABLE) 6975 hdd_set_pktcapture_ops(adapter->dev); 6976 if (ucfg_mlme_is_sta_mon_conc_supported(hdd_ctx->psoc) || 6977 ucfg_dp_is_local_pkt_capture_enabled(hdd_ctx->psoc)) 6978 hdd_set_mon_ops(adapter->dev); 6979 } else { 6980 hdd_set_station_ops(adapter->dev); 6981 } 6982 6983 hdd_dev_setup_destructor(dev); 6984 dev->ieee80211_ptr = &adapter->wdev; 6985 dev->tx_queue_len = HDD_NETDEV_TX_QUEUE_LEN; 6986 adapter->wdev.wiphy = hdd_ctx->wiphy; 6987 adapter->wdev.netdev = dev; 6988 qdf_status = ucfg_mlme_cfg_get_wlm_level(hdd_ctx->psoc, &latency_level); 6989 if (QDF_IS_STATUS_ERROR(qdf_status)) { 6990 hdd_debug("Can't get latency level"); 6991 latency_level = 6992 QCA_WLAN_VENDOR_ATTR_CONFIG_LATENCY_LEVEL_NORMAL; 6993 } 6994 adapter->latency_level = latency_level; 6995 hdd_set_multi_client_ll_support(adapter); 6996 6997 /* set dev's parent to underlying device */ 6998 SET_NETDEV_DEV(dev, hdd_ctx->parent_dev); 6999 spin_lock_init(&adapter->pause_map_lock); 7000 adapter->start_time = qdf_system_ticks(); 7001 adapter->last_time = adapter->start_time; 7002 7003 qdf_atomic_init(&adapter->is_ll_stats_req_pending); 7004 hdd_init_get_sta_in_ll_stats_config(adapter); 7005 hdd_init_link_state_config(adapter); 7006 7007 return adapter; 7008 7009 free_net_dev: 7010 free_netdev(adapter->dev); 7011 7012 return NULL; 7013 } 7014 7015 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 12, 0) || \ 7016 (defined CFG80211_CHANGE_NETDEV_REGISTRATION_SEMANTICS)) 7017 static int hdd_register_netdevice(struct hdd_adapter * adapter,struct net_device * dev,struct hdd_adapter_create_param * params)7018 hdd_register_netdevice(struct hdd_adapter *adapter, struct net_device *dev, 7019 struct hdd_adapter_create_param *params) 7020 { 7021 int ret; 7022 7023 if (params->is_add_virtual_iface) 7024 ret = wlan_cfg80211_register_netdevice(dev); 7025 else 7026 ret = register_netdevice(dev); 7027 7028 return ret; 7029 } 7030 #else 7031 static int hdd_register_netdevice(struct hdd_adapter * adapter,struct net_device * dev,struct hdd_adapter_create_param * params)7032 hdd_register_netdevice(struct hdd_adapter *adapter, struct net_device *dev, 7033 struct hdd_adapter_create_param *params) 7034 { 7035 return register_netdevice(dev); 7036 } 7037 #endif 7038 7039 static QDF_STATUS hdd_register_interface(struct hdd_adapter * adapter,bool rtnl_held,struct hdd_adapter_create_param * params)7040 hdd_register_interface(struct hdd_adapter *adapter, bool rtnl_held, 7041 struct hdd_adapter_create_param *params) 7042 { 7043 struct net_device *dev = adapter->dev; 7044 int ret; 7045 7046 hdd_enter(); 7047 7048 if (rtnl_held) { 7049 if (strnchr(dev->name, IFNAMSIZ - 1, '%')) { 7050 7051 ret = dev_alloc_name(dev, dev->name); 7052 if (ret < 0) { 7053 hdd_err( 7054 "unable to get dev name: %s, err = 0x%x", 7055 dev->name, ret); 7056 return QDF_STATUS_E_FAILURE; 7057 } 7058 } 7059 hdd_debug("hdd_register_netdevice(%s) type:%d", dev->name, 7060 adapter->device_mode); 7061 ret = hdd_register_netdevice(adapter, dev, params); 7062 if (ret) { 7063 hdd_err("register_netdevice(%s) failed, err = 0x%x", 7064 dev->name, ret); 7065 return QDF_STATUS_E_FAILURE; 7066 } 7067 } else { 7068 hdd_debug("register_netdev(%s) type:%d", dev->name, 7069 adapter->device_mode); 7070 ret = register_netdev(dev); 7071 if (ret) { 7072 hdd_err("register_netdev(%s) failed, err = 0x%x", 7073 dev->name, ret); 7074 return QDF_STATUS_E_FAILURE; 7075 } 7076 } 7077 set_bit(NET_DEVICE_REGISTERED, &adapter->event_flags); 7078 7079 hdd_exit(); 7080 7081 return QDF_STATUS_SUCCESS; 7082 } 7083 hdd_sme_close_session_callback(uint8_t vdev_id)7084 QDF_STATUS hdd_sme_close_session_callback(uint8_t vdev_id) 7085 { 7086 struct hdd_adapter *adapter; 7087 struct hdd_context *hdd_ctx; 7088 struct wlan_hdd_link_info *link_info; 7089 7090 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 7091 if (!hdd_ctx) 7092 return QDF_STATUS_E_FAILURE; 7093 7094 link_info = hdd_get_link_info_by_vdev(hdd_ctx, vdev_id); 7095 if (!link_info) { 7096 hdd_err("Invalid vdev %d", vdev_id); 7097 return QDF_STATUS_E_INVAL; 7098 } 7099 7100 adapter = link_info->adapter; 7101 if (WLAN_HDD_ADAPTER_MAGIC != adapter->magic) { 7102 hdd_err("Invalid magic"); 7103 return QDF_STATUS_NOT_INITIALIZED; 7104 } 7105 7106 clear_bit(SME_SESSION_OPENED, &link_info->link_flags); 7107 qdf_spin_lock_bh(&link_info->vdev_lock); 7108 link_info->vdev_id = WLAN_UMAC_VDEV_ID_MAX; 7109 qdf_spin_unlock_bh(&link_info->vdev_lock); 7110 7111 /* 7112 * We can be blocked while waiting for scheduled work to be 7113 * flushed, and the adapter structure can potentially be freed, in 7114 * which case the magic will have been reset. So make sure the 7115 * magic is still good, and hence the adapter structure is still 7116 * valid, before signaling completion 7117 */ 7118 if (WLAN_HDD_ADAPTER_MAGIC == adapter->magic) 7119 complete(&link_info->vdev_destroy_event); 7120 7121 return QDF_STATUS_SUCCESS; 7122 } 7123 hdd_vdev_ready(struct wlan_objmgr_vdev * vdev,struct qdf_mac_addr * bridgeaddr)7124 int hdd_vdev_ready(struct wlan_objmgr_vdev *vdev, 7125 struct qdf_mac_addr *bridgeaddr) 7126 { 7127 QDF_STATUS status; 7128 7129 status = pmo_vdev_ready(vdev, bridgeaddr); 7130 if (QDF_IS_STATUS_ERROR(status)) 7131 return qdf_status_to_os_return(status); 7132 7133 status = ucfg_reg_11d_vdev_created_update(vdev); 7134 if (QDF_IS_STATUS_ERROR(status)) 7135 return qdf_status_to_os_return(status); 7136 7137 if (wma_capability_enhanced_mcast_filter()) 7138 status = ucfg_pmo_enhanced_mc_filter_enable(vdev); 7139 else 7140 status = ucfg_pmo_enhanced_mc_filter_disable(vdev); 7141 7142 return qdf_status_to_os_return(status); 7143 } 7144 7145 /** 7146 * hdd_check_wait_for_hw_mode_completion - Check hw mode in progress 7147 * @hdd_ctx: hdd context 7148 * 7149 * Check and wait for hw mode response if any hw mode change is 7150 * in progress. Vdev delete will purge the serialization queue 7151 * for the vdev. It will cause issues when the fw event coming 7152 * up later and no active hw mode change req ser command in queue. 7153 * 7154 * Return void 7155 */ hdd_check_wait_for_hw_mode_completion(struct hdd_context * hdd_ctx)7156 static void hdd_check_wait_for_hw_mode_completion(struct hdd_context *hdd_ctx) 7157 { 7158 QDF_STATUS status; 7159 7160 if (!wlan_hdd_validate_context(hdd_ctx) && 7161 policy_mgr_is_hw_mode_change_in_progress( 7162 hdd_ctx->psoc)) { 7163 status = policy_mgr_wait_for_connection_update( 7164 hdd_ctx->psoc); 7165 if (!QDF_IS_STATUS_SUCCESS(status)) { 7166 hdd_nofl_debug("qdf wait for hw mode event failed!!"); 7167 } 7168 } 7169 } 7170 hdd_stop_last_active_connection(struct hdd_context * hdd_ctx,struct wlan_objmgr_vdev * vdev)7171 static void hdd_stop_last_active_connection(struct hdd_context *hdd_ctx, 7172 struct wlan_objmgr_vdev *vdev) 7173 { 7174 enum policy_mgr_con_mode mode; 7175 struct wlan_objmgr_psoc *psoc; 7176 enum QDF_OPMODE op_mode; 7177 7178 /* If this is the last active connection check 7179 * and stop the opportunistic timer. 7180 */ 7181 psoc = wlan_vdev_get_psoc(vdev); 7182 op_mode = wlan_vdev_mlme_get_opmode(vdev); 7183 mode = policy_mgr_qdf_opmode_to_pm_con_mode(psoc, op_mode, 7184 wlan_vdev_get_id(vdev)); 7185 if ((policy_mgr_get_connection_count(psoc) == 1 && 7186 policy_mgr_mode_specific_connection_count(psoc, 7187 mode, NULL) == 1) || 7188 (!policy_mgr_get_connection_count(psoc) && 7189 !hdd_is_any_sta_connecting(hdd_ctx))) { 7190 policy_mgr_check_and_stop_opportunistic_timer( 7191 psoc, 7192 wlan_vdev_get_id(vdev)); 7193 } 7194 } 7195 hdd_vdev_destroy_event_wait(struct hdd_context * hdd_ctx,struct wlan_objmgr_vdev * vdev)7196 static int hdd_vdev_destroy_event_wait(struct hdd_context *hdd_ctx, 7197 struct wlan_objmgr_vdev *vdev) 7198 { 7199 long rc; 7200 QDF_STATUS status; 7201 uint8_t vdev_id; 7202 struct wlan_hdd_link_info *link_info; 7203 struct qdf_mac_addr *mld_addr; 7204 struct wlan_objmgr_psoc *psoc = NULL; 7205 7206 vdev_id = wlan_vdev_get_id(vdev); 7207 link_info = hdd_get_link_info_by_vdev(hdd_ctx, vdev_id); 7208 if (!link_info) { 7209 hdd_err("Invalid vdev"); 7210 return -EINVAL; 7211 } 7212 7213 psoc = wlan_vdev_get_psoc(vdev); 7214 if (!psoc) { 7215 obj_mgr_err("Failed to get psoc"); 7216 return QDF_STATUS_E_FAILURE; 7217 } 7218 7219 /* Detach DP vdev from DP MLO Device Context */ 7220 mld_addr = (struct qdf_mac_addr *)wlan_vdev_mlme_get_mldaddr(vdev); 7221 7222 if (!qdf_is_macaddr_zero(mld_addr)) { 7223 /* only for MLO vdev's */ 7224 7225 if (cdp_mlo_dev_ctxt_detach(wlan_psoc_get_dp_handle(psoc), 7226 wlan_vdev_get_id(vdev), 7227 (uint8_t *)mld_addr) 7228 != QDF_STATUS_SUCCESS) { 7229 obj_mgr_err("Failed to detach DP vdev from DP MLO Dev ctxt"); 7230 QDF_BUG(0); 7231 return QDF_STATUS_E_FAILURE; 7232 } 7233 } 7234 7235 /* close sme session (destroy vdev in firmware via legacy API) */ 7236 INIT_COMPLETION(link_info->vdev_destroy_event); 7237 status = sme_vdev_delete(hdd_ctx->mac_handle, vdev); 7238 if (QDF_IS_STATUS_ERROR(status)) { 7239 hdd_err("vdev %d: failed to delete with status:%d", 7240 vdev_id, status); 7241 return -EAGAIN; 7242 } 7243 7244 /* block on a completion variable until sme session is closed */ 7245 rc = wait_for_completion_timeout( 7246 &link_info->vdev_destroy_event, 7247 msecs_to_jiffies(SME_CMD_VDEV_CREATE_DELETE_TIMEOUT)); 7248 if (!rc) { 7249 hdd_err("vdev %d: timed out waiting for delete", vdev_id); 7250 clear_bit(SME_SESSION_OPENED, &link_info->link_flags); 7251 sme_cleanup_session(hdd_ctx->mac_handle, vdev_id); 7252 cds_flush_logs(WLAN_LOG_TYPE_FATAL, 7253 WLAN_LOG_INDICATOR_HOST_DRIVER, 7254 WLAN_LOG_REASON_VDEV_DELETE_RSP_TIMED_OUT, 7255 true, true); 7256 return -EINVAL; 7257 } 7258 7259 hdd_nofl_info("vdev %d destroyed successfully", vdev_id); 7260 return 0; 7261 } 7262 7263 static inline hdd_vdev_deinit_components(struct wlan_objmgr_vdev * vdev)7264 void hdd_vdev_deinit_components(struct wlan_objmgr_vdev *vdev) 7265 { 7266 ucfg_pmo_del_wow_pattern(vdev); 7267 ucfg_son_disable_cbs(vdev); 7268 } 7269 7270 static inline hdd_reset_vdev_info(struct wlan_hdd_link_info * link_info)7271 void hdd_reset_vdev_info(struct wlan_hdd_link_info *link_info) 7272 { 7273 qdf_spin_lock_bh(&link_info->vdev_lock); 7274 link_info->vdev = NULL; 7275 qdf_spin_unlock_bh(&link_info->vdev_lock); 7276 } 7277 hdd_vdev_destroy(struct wlan_hdd_link_info * link_info)7278 int hdd_vdev_destroy(struct wlan_hdd_link_info *link_info) 7279 { 7280 int ret; 7281 uint8_t vdev_id; 7282 struct hdd_context *hdd_ctx; 7283 struct wlan_objmgr_vdev *vdev; 7284 struct wlan_objmgr_psoc *psoc; 7285 enum QDF_OPMODE op_mode; 7286 7287 vdev_id = link_info->vdev_id; 7288 hdd_nofl_debug("destroying vdev %d", vdev_id); 7289 /* vdev created sanity check */ 7290 if (!test_bit(SME_SESSION_OPENED, &link_info->link_flags)) { 7291 hdd_nofl_debug("vdev %u does not exist", vdev_id); 7292 return -EINVAL; 7293 } 7294 7295 hdd_ctx = WLAN_HDD_GET_CTX(link_info->adapter); 7296 7297 vdev = hdd_objmgr_get_vdev_by_user(link_info, WLAN_OSIF_ID); 7298 if (!vdev) 7299 return -EINVAL; 7300 7301 psoc = wlan_vdev_get_psoc(vdev); 7302 if (!psoc) { 7303 hdd_err("invalid psoc"); 7304 return -EINVAL; 7305 } 7306 op_mode = wlan_vdev_mlme_get_opmode(vdev); 7307 7308 hdd_stop_last_active_connection(hdd_ctx, vdev); 7309 hdd_check_wait_for_hw_mode_completion(hdd_ctx); 7310 ucfg_scan_vdev_set_disable(vdev, REASON_VDEV_DOWN); 7311 wlan_hdd_scan_abort(link_info); 7312 hdd_vdev_deinit_components(vdev); 7313 hdd_mlo_t2lm_unregister_callback(vdev); 7314 hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_ID); 7315 7316 hdd_reset_vdev_info(link_info); 7317 osif_cm_osif_priv_deinit(vdev); 7318 7319 /* Release the hdd reference */ 7320 wlan_objmgr_vdev_release_ref(vdev, WLAN_HDD_ID_OBJ_MGR); 7321 7322 /* Get runtime lock to prevent runtime suspend */ 7323 qdf_runtime_pm_prevent_suspend(&hdd_ctx->runtime_context.vdev_destroy); 7324 7325 ret = hdd_vdev_destroy_event_wait(hdd_ctx, vdev); 7326 7327 ucfg_reg_11d_vdev_delete_update(psoc, op_mode, vdev_id); 7328 7329 qdf_runtime_pm_allow_suspend(&hdd_ctx->runtime_context.vdev_destroy); 7330 return ret; 7331 } 7332 7333 void hdd_store_nss_chains_cfg_in_vdev(struct hdd_context * hdd_ctx,struct wlan_objmgr_vdev * vdev)7334 hdd_store_nss_chains_cfg_in_vdev(struct hdd_context *hdd_ctx, 7335 struct wlan_objmgr_vdev *vdev) 7336 { 7337 struct wlan_mlme_nss_chains vdev_ini_cfg; 7338 7339 /* Populate the nss chain params from ini for this vdev type */ 7340 sme_populate_nss_chain_params(hdd_ctx->mac_handle, &vdev_ini_cfg, 7341 wlan_vdev_mlme_get_opmode(vdev), 7342 hdd_ctx->num_rf_chains); 7343 7344 /* Store the nss chain config into the vdev */ 7345 sme_store_nss_chains_cfg_in_vdev(vdev, &vdev_ini_cfg); 7346 } 7347 hdd_is_vdev_in_conn_state(struct wlan_hdd_link_info * link_info)7348 bool hdd_is_vdev_in_conn_state(struct wlan_hdd_link_info *link_info) 7349 { 7350 switch (link_info->adapter->device_mode) { 7351 case QDF_STA_MODE: 7352 case QDF_P2P_CLIENT_MODE: 7353 case QDF_P2P_DEVICE_MODE: 7354 return hdd_cm_is_vdev_associated(link_info); 7355 case QDF_SAP_MODE: 7356 case QDF_P2P_GO_MODE: 7357 return (test_bit(SOFTAP_BSS_STARTED, 7358 &link_info->link_flags)); 7359 default: 7360 hdd_err("Device mode %d invalid", 7361 link_info->adapter->device_mode); 7362 return 0; 7363 } 7364 } 7365 7366 #define MAX_VDEV_RTT_PARAMS 2 7367 /* params being sent: 7368 * wmi_vdev_param_enable_disable_rtt_responder_role 7369 * wmi_vdev_param_enable_disable_rtt_initiator_role 7370 */ 7371 static QDF_STATUS hdd_vdev_configure_rtt_params(struct wlan_objmgr_vdev * vdev)7372 hdd_vdev_configure_rtt_params(struct wlan_objmgr_vdev *vdev) 7373 { 7374 QDF_STATUS status; 7375 struct wlan_objmgr_psoc *psoc; 7376 uint32_t fine_time_meas_cap = 0; 7377 uint8_t vdev_id = wlan_vdev_get_id(vdev); 7378 struct dev_set_param vdevsetparam[MAX_VDEV_RTT_PARAMS] = {}; 7379 uint8_t index = 0; 7380 WMI_FW_SUB_FEAT_CAPS wmi_fw_rtt_respr, wmi_fw_rtt_initr; 7381 7382 switch (wlan_vdev_mlme_get_opmode(vdev)) { 7383 case QDF_STA_MODE: 7384 wmi_fw_rtt_respr = WMI_FW_STA_RTT_RESPR; 7385 wmi_fw_rtt_initr = WMI_FW_STA_RTT_INITR; 7386 break; 7387 case QDF_SAP_MODE: 7388 wmi_fw_rtt_respr = WMI_FW_AP_RTT_RESPR; 7389 wmi_fw_rtt_initr = WMI_FW_AP_RTT_INITR; 7390 break; 7391 default: 7392 return QDF_STATUS_SUCCESS; 7393 } 7394 7395 psoc = wlan_vdev_get_psoc(vdev); 7396 7397 ucfg_mlme_get_fine_time_meas_cap(psoc, &fine_time_meas_cap); 7398 status = mlme_check_index_setparam( 7399 vdevsetparam, 7400 wmi_vdev_param_enable_disable_rtt_responder_role, 7401 (fine_time_meas_cap & wmi_fw_rtt_respr), index++, 7402 MAX_VDEV_RTT_PARAMS); 7403 if (QDF_IS_STATUS_ERROR(status)) 7404 return status; 7405 7406 status = mlme_check_index_setparam( 7407 vdevsetparam, 7408 wmi_vdev_param_enable_disable_rtt_initiator_role, 7409 (fine_time_meas_cap & wmi_fw_rtt_initr), index++, 7410 MAX_VDEV_RTT_PARAMS); 7411 if (QDF_IS_STATUS_ERROR(status)) 7412 return status; 7413 7414 status = sme_send_multi_pdev_vdev_set_params(MLME_VDEV_SETPARAM, 7415 vdev_id, vdevsetparam, 7416 index); 7417 if (QDF_IS_STATUS_ERROR(status)) 7418 hdd_err("failed to set RTT_RESPONDER,INITIATOR params:%d", 7419 status); 7420 7421 return status; 7422 } 7423 hdd_store_vdev_info(struct wlan_hdd_link_info * link_info,struct wlan_objmgr_vdev * vdev)7424 static void hdd_store_vdev_info(struct wlan_hdd_link_info *link_info, 7425 struct wlan_objmgr_vdev *vdev) 7426 { 7427 struct vdev_osif_priv *osif_priv; 7428 7429 osif_priv = wlan_vdev_get_ospriv(vdev); 7430 if (osif_priv) { 7431 osif_priv->wdev = link_info->adapter->dev->ieee80211_ptr; 7432 osif_priv->legacy_osif_priv = link_info; 7433 } 7434 7435 qdf_spin_lock_bh(&link_info->vdev_lock); 7436 link_info->vdev_id = wlan_vdev_get_id(vdev); 7437 link_info->vdev = vdev; 7438 qdf_spin_unlock_bh(&link_info->vdev_lock); 7439 } 7440 7441 static void hdd_init_station_context(struct wlan_hdd_link_info * link_info)7442 hdd_init_station_context(struct wlan_hdd_link_info *link_info) 7443 { 7444 struct hdd_station_ctx *sta_ctx; 7445 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(link_info->adapter); 7446 7447 /* Set the default operation channel freq and auth type to open */ 7448 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(link_info); 7449 sta_ctx->conn_info.chan_freq = hdd_ctx->config->operating_chan_freq; 7450 sta_ctx->conn_info.auth_type = eCSR_AUTH_TYPE_OPEN_SYSTEM; 7451 hdd_roam_profile_init(link_info); 7452 } 7453 hdd_vdev_set_ht_vht_ies(mac_handle_t mac_handle,struct wlan_objmgr_vdev * vdev)7454 static void hdd_vdev_set_ht_vht_ies(mac_handle_t mac_handle, 7455 struct wlan_objmgr_vdev *vdev) 7456 { 7457 QDF_STATUS status; 7458 struct wlan_objmgr_psoc *psoc; 7459 bool bval = false; 7460 7461 psoc = wlan_vdev_get_psoc(vdev); 7462 status = ucfg_mlme_get_vht_enable2x2(psoc, &bval); 7463 if (QDF_IS_STATUS_ERROR(status)) 7464 hdd_err("unable to get vht_enable2x2"); 7465 7466 sme_set_pdev_ht_vht_ies(mac_handle, bval); 7467 sme_set_vdev_ies_per_band(mac_handle, wlan_vdev_get_id(vdev), 7468 wlan_vdev_mlme_get_opmode(vdev)); 7469 } 7470 7471 static void hdd_vdev_configure_rtt_mac_randomization(struct wlan_objmgr_psoc * psoc,struct wlan_objmgr_vdev * vdev)7472 hdd_vdev_configure_rtt_mac_randomization(struct wlan_objmgr_psoc *psoc, 7473 struct wlan_objmgr_vdev *vdev) 7474 { 7475 int errno; 7476 QDF_STATUS status; 7477 bool bval = false; 7478 7479 status = ucfg_mlme_get_rtt_mac_randomization(psoc, &bval); 7480 if (QDF_IS_STATUS_ERROR(status)) 7481 hdd_err("unable to get RTT MAC randomization value"); 7482 7483 hdd_debug("setting RTT mac randomization param: %d", bval); 7484 errno = sme_cli_set_command( 7485 wlan_vdev_get_id(vdev), 7486 wmi_vdev_param_enable_disable_rtt_initiator_random_mac, 7487 bval, VDEV_CMD); 7488 7489 if (errno) 7490 hdd_err("RTT mac randomization param set failed %d", errno); 7491 } 7492 7493 static void hdd_vdev_configure_max_tdls_params(struct wlan_objmgr_psoc * psoc,struct wlan_objmgr_vdev * vdev)7494 hdd_vdev_configure_max_tdls_params(struct wlan_objmgr_psoc *psoc, 7495 struct wlan_objmgr_vdev *vdev) 7496 { 7497 uint16_t max_peer_count; 7498 bool target_bigtk_support = false; 7499 7500 /* 7501 * Max peer can be tdls peers + self peer + bss peer + 7502 * temp bss peer for roaming create/delete peer at same time 7503 */ 7504 max_peer_count = cfg_tdls_get_max_peer_count(psoc); 7505 max_peer_count += 3; 7506 wlan_vdev_set_max_peer_count(vdev, max_peer_count); 7507 7508 ucfg_mlme_get_bigtk_support(psoc, &target_bigtk_support); 7509 if (target_bigtk_support) 7510 mlme_set_bigtk_support(vdev, true); 7511 } 7512 7513 static inline void hdd_vdev_configure_nan_params(struct wlan_objmgr_psoc * psoc,struct wlan_objmgr_vdev * vdev)7514 hdd_vdev_configure_nan_params(struct wlan_objmgr_psoc *psoc, 7515 struct wlan_objmgr_vdev *vdev) 7516 { 7517 sme_cli_set_command( 7518 wlan_vdev_get_id(vdev), 7519 wmi_vdev_param_allow_nan_initial_discovery_of_mp0_cluster, 7520 cfg_nan_get_support_mp0_discovery(psoc), VDEV_CMD); 7521 } 7522 7523 #if defined(WLAN_FEATURE_11BE_MLO) && defined(WLAN_EXTERNAL_AUTH_MLO_SUPPORT) 7524 static void hdd_set_vdev_mlo_external_sae_auth_conversion(struct wlan_objmgr_vdev * vdev,enum QDF_OPMODE mode)7525 hdd_set_vdev_mlo_external_sae_auth_conversion(struct wlan_objmgr_vdev *vdev, 7526 enum QDF_OPMODE mode) 7527 { 7528 if (mode == QDF_STA_MODE || mode == QDF_SAP_MODE) 7529 wlan_vdev_set_mlo_external_sae_auth_conversion(vdev, true); 7530 } 7531 #else 7532 static inline void hdd_set_vdev_mlo_external_sae_auth_conversion(struct wlan_objmgr_vdev * vdev,enum QDF_OPMODE mode)7533 hdd_set_vdev_mlo_external_sae_auth_conversion(struct wlan_objmgr_vdev *vdev, 7534 enum QDF_OPMODE mode) 7535 { 7536 } 7537 #endif 7538 7539 static void hdd_vdev_configure_rtscts_enable(struct hdd_context * hdd_ctx,struct wlan_objmgr_vdev * vdev)7540 hdd_vdev_configure_rtscts_enable(struct hdd_context *hdd_ctx, 7541 struct wlan_objmgr_vdev *vdev) 7542 { 7543 int ret; 7544 QDF_STATUS status; 7545 uint16_t rts_profile = 0; 7546 7547 if (cds_get_conparam() == QDF_GLOBAL_FTM_MODE) 7548 return; 7549 7550 status = ucfg_fwol_get_rts_profile(hdd_ctx->psoc, &rts_profile); 7551 if (QDF_IS_STATUS_ERROR(status)) { 7552 hdd_err("FAILED TO GET RTSCTS Profile status:%d", status); 7553 return; 7554 } 7555 7556 ret = sme_cli_set_command(wlan_vdev_get_id(vdev), 7557 wmi_vdev_param_enable_rtscts, 7558 rts_profile, 7559 VDEV_CMD); 7560 if (ret) 7561 hdd_err("FAILED TO SET RTSCTS Profile ret:%d", ret); 7562 } 7563 7564 static void hdd_vdev_configure_usr_ps_params(struct wlan_objmgr_psoc * psoc,struct wlan_objmgr_vdev * vdev,struct wlan_hdd_link_info * link_info)7565 hdd_vdev_configure_usr_ps_params(struct wlan_objmgr_psoc *psoc, 7566 struct wlan_objmgr_vdev *vdev, 7567 struct wlan_hdd_link_info *link_info) 7568 { 7569 struct hdd_adapter *adapter = link_info->adapter; 7570 7571 if (cds_get_conparam() == QDF_GLOBAL_FTM_MODE || !adapter) 7572 return; 7573 7574 ucfg_mlme_set_user_ps(psoc, wlan_vdev_get_id(vdev), 7575 adapter->allow_power_save); 7576 } 7577 7578 static void hdd_vdev_configure_opmode_params(struct hdd_context * hdd_ctx,struct wlan_objmgr_vdev * vdev,struct wlan_hdd_link_info * link_info)7579 hdd_vdev_configure_opmode_params(struct hdd_context *hdd_ctx, 7580 struct wlan_objmgr_vdev *vdev, 7581 struct wlan_hdd_link_info *link_info) 7582 { 7583 struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc; 7584 enum QDF_OPMODE opmode = wlan_vdev_mlme_get_opmode(vdev); 7585 7586 switch (opmode) { 7587 case QDF_STA_MODE: 7588 hdd_vdev_configure_rtt_mac_randomization(psoc, vdev); 7589 hdd_vdev_configure_max_tdls_params(psoc, vdev); 7590 hdd_vdev_configure_usr_ps_params(psoc, vdev, link_info); 7591 break; 7592 case QDF_P2P_CLIENT_MODE: 7593 hdd_vdev_configure_max_tdls_params(psoc, vdev); 7594 hdd_vdev_configure_usr_ps_params(psoc, vdev, link_info); 7595 break; 7596 case QDF_NAN_DISC_MODE: 7597 hdd_vdev_configure_nan_params(psoc, vdev); 7598 break; 7599 default: 7600 break; 7601 } 7602 7603 ucfg_fwol_configure_vdev_params(psoc, vdev); 7604 hdd_set_vdev_mlo_external_sae_auth_conversion(vdev, opmode); 7605 hdd_store_nss_chains_cfg_in_vdev(hdd_ctx, vdev); 7606 hdd_vdev_configure_rtscts_enable(hdd_ctx, vdev); 7607 } 7608 7609 #if defined(WLAN_FEATURE_11BE_MLO) && defined(CFG80211_11BE_BASIC) && \ 7610 defined(WLAN_HDD_MULTI_VDEV_SINGLE_NDEV) 7611 static int hdd_populate_vdev_create_params(struct wlan_hdd_link_info * link_info,struct wlan_vdev_create_params * vdev_params)7612 hdd_populate_vdev_create_params(struct wlan_hdd_link_info *link_info, 7613 struct wlan_vdev_create_params *vdev_params) 7614 { 7615 struct hdd_adapter *adapter = link_info->adapter; 7616 7617 vdev_params->opmode = adapter->device_mode; 7618 vdev_params->size_vdev_priv = sizeof(struct vdev_osif_priv); 7619 7620 if (hdd_adapter_is_ml_adapter(adapter)) { 7621 qdf_ether_addr_copy(vdev_params->mldaddr, 7622 adapter->mac_addr.bytes); 7623 qdf_ether_addr_copy(vdev_params->macaddr, 7624 link_info->link_addr.bytes); 7625 } else { 7626 qdf_ether_addr_copy(vdev_params->macaddr, 7627 adapter->mac_addr.bytes); 7628 } 7629 return 0; 7630 } 7631 #elif defined(WLAN_FEATURE_11BE_MLO) && defined(CFG80211_11BE_BASIC) 7632 static int hdd_populate_vdev_create_params(struct wlan_hdd_link_info * link_info,struct wlan_vdev_create_params * vdev_params)7633 hdd_populate_vdev_create_params(struct wlan_hdd_link_info *link_info, 7634 struct wlan_vdev_create_params *vdev_params) 7635 { 7636 struct hdd_adapter *adapter = link_info->adapter; 7637 struct hdd_mlo_adapter_info *mlo_adapter_info; 7638 struct hdd_adapter *link_adapter; 7639 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); 7640 bool eht_capab; 7641 7642 hdd_enter_dev(adapter->dev); 7643 mlo_adapter_info = &adapter->mlo_adapter_info; 7644 7645 ucfg_psoc_mlme_get_11be_capab(hdd_ctx->psoc, &eht_capab); 7646 if (mlo_adapter_info->is_ml_adapter && eht_capab && 7647 adapter->device_mode == QDF_STA_MODE) { 7648 link_adapter = hdd_get_assoc_link_adapter(adapter); 7649 if (link_adapter) { 7650 qdf_ether_addr_copy(vdev_params->macaddr, 7651 link_adapter->mac_addr.bytes); 7652 } else { 7653 return -EINVAL; 7654 } 7655 } else { 7656 qdf_ether_addr_copy(vdev_params->macaddr, 7657 adapter->mac_addr.bytes); 7658 } 7659 7660 vdev_params->opmode = adapter->device_mode; 7661 7662 if (eht_capab) { 7663 qdf_ether_addr_copy(vdev_params->mldaddr, 7664 adapter->mld_addr.bytes); 7665 } 7666 7667 vdev_params->size_vdev_priv = sizeof(struct vdev_osif_priv); 7668 hdd_exit(); 7669 7670 return 0; 7671 } 7672 #else 7673 static int hdd_populate_vdev_create_params(struct wlan_hdd_link_info * link_info,struct wlan_vdev_create_params * vdev_params)7674 hdd_populate_vdev_create_params(struct wlan_hdd_link_info *link_info, 7675 struct wlan_vdev_create_params *vdev_params) 7676 { 7677 struct hdd_adapter *adapter = link_info->adapter; 7678 7679 vdev_params->opmode = adapter->device_mode; 7680 qdf_ether_addr_copy(vdev_params->macaddr, adapter->mac_addr.bytes); 7681 vdev_params->size_vdev_priv = sizeof(struct vdev_osif_priv); 7682 return 0; 7683 } 7684 #endif 7685 hdd_vdev_create(struct wlan_hdd_link_info * link_info)7686 int hdd_vdev_create(struct wlan_hdd_link_info *link_info) 7687 { 7688 QDF_STATUS status; 7689 int errno = 0; 7690 struct hdd_adapter *adapter = link_info->adapter; 7691 struct hdd_context *hdd_ctx; 7692 struct wlan_objmgr_vdev *vdev; 7693 struct wlan_vdev_create_params vdev_params = {0}; 7694 7695 hdd_nofl_debug("creating new vdev"); 7696 7697 /* do vdev create via objmgr */ 7698 hdd_ctx = WLAN_HDD_GET_CTX(adapter); 7699 7700 errno = hdd_populate_vdev_create_params(link_info, &vdev_params); 7701 if (errno) 7702 return errno; 7703 7704 vdev = sme_vdev_create(hdd_ctx->mac_handle, &vdev_params); 7705 if (!vdev) { 7706 hdd_err("failed to create vdev"); 7707 return -EINVAL; 7708 } 7709 7710 if (wlan_objmgr_vdev_try_get_ref(vdev, WLAN_HDD_ID_OBJ_MGR) != 7711 QDF_STATUS_SUCCESS) { 7712 errno = QDF_STATUS_E_INVAL; 7713 sme_vdev_delete(hdd_ctx->mac_handle, vdev); 7714 return -EINVAL; 7715 } 7716 7717 hdd_store_vdev_info(link_info, vdev); 7718 osif_cm_osif_priv_init(vdev); 7719 7720 if (hdd_adapter_is_ml_adapter(adapter)) 7721 hdd_mlo_t2lm_register_callback(vdev); 7722 7723 set_bit(SME_SESSION_OPENED, &link_info->link_flags); 7724 status = sme_vdev_post_vdev_create_setup(hdd_ctx->mac_handle, vdev); 7725 if (QDF_IS_STATUS_ERROR(status)) { 7726 hdd_err("Failed to setup the vdev"); 7727 errno = qdf_status_to_os_return(status); 7728 goto hdd_vdev_destroy_procedure; 7729 } 7730 7731 /* firmware ready for component communication, raise vdev_ready event */ 7732 errno = hdd_vdev_ready(vdev, 7733 (struct qdf_mac_addr *)hdd_ctx->bridgeaddr); 7734 if (errno) { 7735 hdd_err("failed to dispatch vdev ready event: %d", errno); 7736 goto hdd_vdev_destroy_procedure; 7737 } 7738 7739 hdd_vdev_configure_opmode_params(hdd_ctx, vdev, link_info); 7740 7741 hdd_nofl_debug("vdev %d created successfully", link_info->vdev_id); 7742 7743 return errno; 7744 7745 hdd_vdev_destroy_procedure: 7746 QDF_BUG(!hdd_vdev_destroy(link_info)); 7747 7748 return errno; 7749 } 7750 hdd_init_station_mode(struct wlan_hdd_link_info * link_info)7751 QDF_STATUS hdd_init_station_mode(struct wlan_hdd_link_info *link_info) 7752 { 7753 struct hdd_adapter *adapter = link_info->adapter; 7754 struct hdd_context *hdd_ctx; 7755 QDF_STATUS status; 7756 mac_handle_t mac_handle; 7757 uint32_t roam_triggers; 7758 struct wlan_objmgr_vdev *vdev; 7759 7760 hdd_ctx = WLAN_HDD_GET_CTX(adapter); 7761 mac_handle = hdd_ctx->mac_handle; 7762 7763 vdev = hdd_objmgr_get_vdev_by_user(link_info, WLAN_INIT_DEINIT_ID); 7764 if (!vdev) { 7765 status = QDF_STATUS_E_NULL_VALUE; 7766 goto vdev_destroy; 7767 } 7768 7769 hdd_vdev_set_ht_vht_ies(mac_handle, vdev); 7770 hdd_init_station_context(link_info); 7771 7772 status = hdd_wmm_adapter_init(adapter); 7773 if (QDF_STATUS_SUCCESS != status) { 7774 hdd_err("hdd_wmm_adapter_init() failed, status code %08d [x%08x]", 7775 status, status); 7776 goto error_wmm_init; 7777 } 7778 set_bit(WMM_INIT_DONE, &adapter->event_flags); 7779 7780 /* rcpi info initialization */ 7781 qdf_mem_zero(&adapter->rcpi, sizeof(adapter->rcpi)); 7782 7783 if (adapter->device_mode == QDF_STA_MODE) { 7784 roam_triggers = ucfg_mlme_get_roaming_triggers(hdd_ctx->psoc); 7785 mlme_set_roam_trigger_bitmap(hdd_ctx->psoc, 7786 link_info->vdev_id, 7787 roam_triggers); 7788 7789 status = hdd_vdev_configure_rtt_params(vdev); 7790 if (QDF_IS_STATUS_ERROR(status)) 7791 goto error_wmm_init; 7792 } 7793 7794 hdd_tsf_auto_report_init(adapter); 7795 hdd_objmgr_put_vdev_by_user(vdev, WLAN_INIT_DEINIT_ID); 7796 7797 return QDF_STATUS_SUCCESS; 7798 7799 error_wmm_init: 7800 hdd_objmgr_put_vdev_by_user(vdev, WLAN_INIT_DEINIT_ID); 7801 7802 vdev_destroy: 7803 QDF_BUG(!hdd_vdev_destroy(link_info)); 7804 7805 return status; 7806 } 7807 net_dev_ref_debug_string_from_id(wlan_net_dev_ref_dbgid dbgid)7808 static char *net_dev_ref_debug_string_from_id(wlan_net_dev_ref_dbgid dbgid) 7809 { 7810 static const char *strings[] = { 7811 "NET_DEV_HOLD_ID_RESERVED", 7812 "NET_DEV_HOLD_GET_STA_CONNECTION_IN_PROGRESS", 7813 "NET_DEV_HOLD_CHECK_DFS_CHANNEL_FOR_ADAPTER", 7814 "NET_DEV_HOLD_GET_SAP_OPERATING_BAND", 7815 "NET_DEV_HOLD_RECOVERY_NOTIFIER_CALL", 7816 "NET_DEV_HOLD_IS_ANY_STA_CONNECTING", 7817 "NET_DEV_HOLD_SAP_DESTROY_CTX_ALL", 7818 "NET_DEV_HOLD_DRV_CMD_MAX_TX_POWER", 7819 "NET_DEV_HOLD_IPA_SET_TX_FLOW_INFO", 7820 "NET_DEV_HOLD_SET_RPS_CPU_MASK", 7821 "NET_DEV_HOLD_DFS_INDICATE_RADAR", 7822 "NET_DEV_HOLD_MAX_STA_INTERFACE_UP_COUNT_REACHED", 7823 "NET_DEV_HOLD_IS_CHAN_SWITCH_IN_PROGRESS", 7824 "NET_DEV_HOLD_STA_DESTROY_CTX_ALL", 7825 "NET_DEV_HOLD_CHECK_FOR_EXISTING_MACADDR", 7826 "NET_DEV_HOLD_DEINIT_ALL_ADAPTERS", 7827 "NET_DEV_HOLD_STOP_ALL_ADAPTERS", 7828 "NET_DEV_HOLD_RESET_ALL_ADAPTERS", 7829 "NET_DEV_HOLD_IS_ANY_INTERFACE_OPEN", 7830 "NET_DEV_HOLD_START_ALL_ADAPTERS", 7831 "NET_DEV_HOLD_GET_ADAPTER_BY_RAND_MACADDR", 7832 "NET_DEV_HOLD_GET_ADAPTER_BY_MACADDR", 7833 "NET_DEV_HOLD_GET_ADAPTER_BY_VDEV", 7834 "NET_DEV_HOLD_ADAPTER_GET_BY_REFERENCE", 7835 "NET_DEV_HOLD_GET_ADAPTER_BY_IFACE_NAME", 7836 "NET_DEV_HOLD_GET_ADAPTER", 7837 "NET_DEV_HOLD_GET_OPERATING_CHAN_FREQ", 7838 "NET_DEV_HOLD_UNREGISTER_WEXT_ALL_ADAPTERS", 7839 "NET_DEV_HOLD_ABORT_MAC_SCAN_ALL_ADAPTERS", 7840 "NET_DEV_HOLD_ABORT_SCHED_SCAN_ALL_ADAPTERS", 7841 "NET_DEV_HOLD_GET_FIRST_VALID_ADAPTER", 7842 "NET_DEV_HOLD_CLEAR_RPS_CPU_MASK", 7843 "NET_DEV_HOLD_BUS_BW_WORK_HANDLER", 7844 "NET_DEV_HOLD_DISPLAY_NETIF_QUEUE_HISTORY_COMPACT", 7845 "NET_DEV_HOLD_DISPLAY_NETIF_QUEUE_HISTORY", 7846 "NET_DEV_HOLD_CLEAR_NETIF_QUEUE_HISTORY", 7847 "NET_DEV_HOLD_UNSAFE_CHANNEL_RESTART_SAP", 7848 "NET_DEV_HOLD_INDICATE_MGMT_FRAME", 7849 "NET_DEV_HOLD_STATE_INFO_DUMP", 7850 "NET_DEV_HOLD_DISABLE_ROAMING", 7851 "NET_DEV_HOLD_ENABLE_ROAMING", 7852 "NET_DEV_HOLD_AUTO_SHUTDOWN_ENABLE", 7853 "NET_DEV_HOLD_GET_CON_SAP_ADAPTER", 7854 "NET_DEV_HOLD_IS_ANY_ADAPTER_CONNECTED", 7855 "NET_DEV_HOLD_IS_ROAMING_IN_PROGRESS", 7856 "NET_DEV_HOLD_DEL_P2P_INTERFACE", 7857 "NET_DEV_HOLD_IS_NDP_ALLOWED", 7858 "NET_DEV_HOLD_NDI_OPEN", 7859 "NET_DEV_HOLD_SEND_OEM_REG_RSP_NLINK_MSG", 7860 "NET_DEV_HOLD_PERIODIC_STA_STATS_DISPLAY", 7861 "NET_DEV_HOLD_SUSPEND_WLAN", 7862 "NET_DEV_HOLD_RESUME_WLAN", 7863 "NET_DEV_HOLD_SSR_RESTART_SAP", 7864 "NET_DEV_HOLD_SEND_DEFAULT_SCAN_IES", 7865 "NET_DEV_HOLD_CFG80211_SUSPEND_WLAN", 7866 "NET_DEV_HOLD_COUNTRY_CHANGE_UPDATE_STA", 7867 "NET_DEV_HOLD_COUNTRY_CHANGE_UPDATE_SAP", 7868 "NET_DEV_HOLD_CACHE_STATION_STATS_CB", 7869 "NET_DEV_HOLD_DISPLAY_TXRX_STATS", 7870 "NET_DEV_HOLD_START_PRE_CAC_TRANS", 7871 "NET_DEV_HOLD_IS_ANY_STA_CONNECTED", 7872 "NET_DEV_HOLD_GET_ADAPTER_BY_BSSID", 7873 "NET_DEV_HOLD_ALLOW_NEW_INTF", 7874 "NET_DEV_HOLD_ID_MAX"}; 7875 int32_t num_dbg_strings = QDF_ARRAY_SIZE(strings); 7876 7877 if (dbgid >= num_dbg_strings) { 7878 char *ret = ""; 7879 7880 hdd_err("Debug string not found for debug id %d", dbgid); 7881 return ret; 7882 } 7883 7884 return (char *)strings[dbgid]; 7885 } 7886 hdd_check_for_net_dev_ref_leak(struct hdd_adapter * adapter)7887 void hdd_check_for_net_dev_ref_leak(struct hdd_adapter *adapter) 7888 { 7889 int i, id; 7890 7891 for (id = 0; id < NET_DEV_HOLD_ID_MAX; id++) { 7892 for (i = 0; i < MAX_NET_DEV_REF_LEAK_ITERATIONS; i++) { 7893 if (!qdf_atomic_read( 7894 &adapter->net_dev_hold_ref_count[id])) 7895 break; 7896 hdd_info("net_dev held for debug id %s", 7897 net_dev_ref_debug_string_from_id(id)); 7898 qdf_sleep(NET_DEV_REF_LEAK_ITERATION_SLEEP_TIME_MS); 7899 } 7900 if (i == MAX_NET_DEV_REF_LEAK_ITERATIONS) { 7901 hdd_err("net_dev hold reference leak detected for debug id: %s", 7902 net_dev_ref_debug_string_from_id(id)); 7903 QDF_BUG(0); 7904 } 7905 } 7906 } 7907 7908 /** 7909 * hdd_deinit_station_mode() - De-initialize the station adapter 7910 * @adapter: HDD adapter pointer 7911 * 7912 * This function De-initializes the STA/P2P/OCB adapter. 7913 * 7914 * Return: None. 7915 */ hdd_deinit_station_mode(struct hdd_adapter * adapter)7916 static void hdd_deinit_station_mode(struct hdd_adapter *adapter) 7917 { 7918 if (test_bit(WMM_INIT_DONE, &adapter->event_flags)) { 7919 hdd_wmm_adapter_close(adapter); 7920 clear_bit(WMM_INIT_DONE, &adapter->event_flags); 7921 } 7922 } 7923 hdd_deinit_session(struct hdd_adapter * adapter)7924 void hdd_deinit_session(struct hdd_adapter *adapter) 7925 { 7926 struct wlan_hdd_link_info *link_info; 7927 7928 hdd_enter(); 7929 7930 switch (adapter->device_mode) { 7931 case QDF_STA_MODE: 7932 case QDF_P2P_CLIENT_MODE: 7933 case QDF_MONITOR_MODE: 7934 case QDF_P2P_DEVICE_MODE: 7935 case QDF_NDI_MODE: 7936 case QDF_NAN_DISC_MODE: 7937 { 7938 hdd_deinit_station_mode(adapter); 7939 break; 7940 } 7941 7942 case QDF_SAP_MODE: 7943 case QDF_P2P_GO_MODE: 7944 { 7945 hdd_adapter_for_each_active_link_info(adapter, link_info) 7946 hdd_deinit_ap_mode(link_info); 7947 break; 7948 } 7949 7950 default: 7951 break; 7952 } 7953 7954 if (adapter->scan_info.default_scan_ies) { 7955 qdf_mem_free(adapter->scan_info.default_scan_ies); 7956 adapter->scan_info.default_scan_ies = NULL; 7957 adapter->scan_info.default_scan_ies_len = 0; 7958 } 7959 7960 hdd_exit(); 7961 } 7962 hdd_deinit_adapter(struct hdd_context * hdd_ctx,struct hdd_adapter * adapter,bool rtnl_held)7963 void hdd_deinit_adapter(struct hdd_context *hdd_ctx, 7964 struct hdd_adapter *adapter, 7965 bool rtnl_held) 7966 { 7967 hdd_enter_dev(adapter->dev); 7968 7969 hdd_wext_unregister(adapter->dev, rtnl_held); 7970 hdd_deinit_session(adapter); 7971 hdd_exit(); 7972 } 7973 7974 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0)) && \ 7975 defined(WLAN_FEATURE_11AX) 7976 /** 7977 * hdd_cleanup_he_operation_info() - cleanup he operation info 7978 * @link_info: pointer to link_info struct in adapter 7979 * 7980 * This function destroys he operation information 7981 * 7982 * Return: none 7983 */ hdd_cleanup_he_operation_info(struct wlan_hdd_link_info * link_info)7984 static void hdd_cleanup_he_operation_info(struct wlan_hdd_link_info *link_info) 7985 { 7986 struct hdd_station_ctx *hdd_sta_ctx; 7987 7988 hdd_debug("cleanup he operation info"); 7989 7990 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(link_info); 7991 7992 if (hdd_sta_ctx->cache_conn_info.he_operation) { 7993 qdf_mem_free(hdd_sta_ctx->cache_conn_info.he_operation); 7994 hdd_sta_ctx->cache_conn_info.he_operation = NULL; 7995 } 7996 } 7997 #else 7998 static inline void hdd_cleanup_he_operation_info(struct wlan_hdd_link_info * link_info)7999 hdd_cleanup_he_operation_info(struct wlan_hdd_link_info *link_info) 8000 { 8001 } 8002 #endif 8003 8004 /** 8005 * hdd_cleanup_prev_ap_bcn_ie() - cleanup previous ap beacon ie 8006 * @link_info: pointer to link_info struct in adapter 8007 * 8008 * This function destroys previous ap beacon information 8009 * 8010 * Return: none 8011 */ hdd_cleanup_prev_ap_bcn_ie(struct wlan_hdd_link_info * link_info)8012 static void hdd_cleanup_prev_ap_bcn_ie(struct wlan_hdd_link_info *link_info) 8013 { 8014 struct hdd_station_ctx *hdd_sta_ctx; 8015 struct element_info *bcn_ie; 8016 8017 hdd_debug("cleanup previous ap bcn ie"); 8018 8019 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(link_info); 8020 bcn_ie = &hdd_sta_ctx->conn_info.prev_ap_bcn_ie; 8021 8022 if (bcn_ie->ptr) { 8023 qdf_mem_free(bcn_ie->ptr); 8024 bcn_ie->ptr = NULL; 8025 bcn_ie->len = 0; 8026 } 8027 } 8028 hdd_cleanup_conn_info(struct wlan_hdd_link_info * link_info)8029 void hdd_cleanup_conn_info(struct wlan_hdd_link_info *link_info) 8030 { 8031 hdd_cleanup_he_operation_info(link_info); 8032 hdd_cleanup_prev_ap_bcn_ie(link_info); 8033 } 8034 8035 /** 8036 * hdd_sta_destroy_ctx_all() - cleanup all station contexts 8037 * @hdd_ctx: Global HDD context 8038 * 8039 * This function destroys all the station contexts 8040 * 8041 * Return: none 8042 */ hdd_sta_destroy_ctx_all(struct hdd_context * hdd_ctx)8043 static void hdd_sta_destroy_ctx_all(struct hdd_context *hdd_ctx) 8044 { 8045 struct hdd_adapter *adapter, *next_adapter = NULL; 8046 struct wlan_hdd_link_info *link_info; 8047 8048 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 8049 NET_DEV_HOLD_STA_DESTROY_CTX_ALL) { 8050 if (adapter->device_mode == QDF_STA_MODE) { 8051 hdd_adapter_for_each_link_info(adapter, link_info) { 8052 hdd_cleanup_conn_info(link_info); 8053 } 8054 } 8055 hdd_adapter_dev_put_debug(adapter, 8056 NET_DEV_HOLD_STA_DESTROY_CTX_ALL); 8057 } 8058 } 8059 8060 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 12, 0) || \ 8061 (defined CFG80211_CHANGE_NETDEV_REGISTRATION_SEMANTICS)) 8062 static void hdd_unregister_netdevice(struct hdd_adapter * adapter,struct net_device * dev)8063 hdd_unregister_netdevice(struct hdd_adapter *adapter, struct net_device *dev) 8064 { 8065 if (adapter->is_virtual_iface) { 8066 wlan_cfg80211_unregister_netdevice(dev); 8067 adapter->is_virtual_iface = false; 8068 } else { 8069 unregister_netdevice(dev); 8070 } 8071 } 8072 #else 8073 static void hdd_unregister_netdevice(struct hdd_adapter * adapter,struct net_device * dev)8074 hdd_unregister_netdevice(struct hdd_adapter *adapter, struct net_device *dev) 8075 { 8076 unregister_netdevice(dev); 8077 } 8078 #endif 8079 hdd_adapter_destroy_vdev_info(struct hdd_adapter * adapter)8080 static inline void hdd_adapter_destroy_vdev_info(struct hdd_adapter *adapter) 8081 { 8082 struct wlan_hdd_link_info *link_info; 8083 8084 hdd_adapter_for_each_link_info(adapter, link_info) { 8085 qdf_event_destroy(&link_info->acs_complete_event); 8086 qdf_spinlock_destroy(&link_info->vdev_lock); 8087 } 8088 } 8089 hdd_cleanup_adapter(struct hdd_context * hdd_ctx,struct hdd_adapter * adapter,bool rtnl_held)8090 static void hdd_cleanup_adapter(struct hdd_context *hdd_ctx, 8091 struct hdd_adapter *adapter, 8092 bool rtnl_held) 8093 { 8094 struct net_device *dev = NULL; 8095 8096 if (adapter) 8097 dev = adapter->dev; 8098 else { 8099 hdd_err("adapter is Null"); 8100 return; 8101 } 8102 8103 hdd_apf_context_destroy(adapter); 8104 qdf_spinlock_destroy(&adapter->mc_list_lock); 8105 hdd_adapter_destroy_vdev_info(adapter); 8106 hdd_sta_info_deinit(&adapter->sta_info_list); 8107 hdd_sta_info_deinit(&adapter->cache_sta_info_list); 8108 8109 wlan_hdd_debugfs_csr_deinit(adapter); 8110 8111 hdd_debugfs_exit(adapter); 8112 8113 /* 8114 * The adapter is marked as closed. When hdd_wlan_exit() call returns, 8115 * the driver is almost closed and cannot handle either control 8116 * messages or data. However, unregister_netdevice() call above will 8117 * eventually invoke hdd_stop(ndo_close) driver callback, which attempts 8118 * to close the active connections(basically excites control path) which 8119 * is not right. Setting this flag helps hdd_stop() to recognize that 8120 * the interface is closed and restricts any operations on that 8121 */ 8122 clear_bit(DEVICE_IFACE_OPENED, &adapter->event_flags); 8123 8124 if (test_bit(NET_DEVICE_REGISTERED, &adapter->event_flags)) { 8125 if (rtnl_held) { 8126 hdd_debug("hdd_unregister_netdevice(%s) type:%d", 8127 dev->name, adapter->device_mode); 8128 hdd_unregister_netdevice(adapter, dev); 8129 } else { 8130 hdd_debug("unregister_netdev(%s) type:%d", dev->name, 8131 adapter->device_mode); 8132 unregister_netdev(dev); 8133 } 8134 /* 8135 * Note that the adapter is no longer valid at this point 8136 * since the memory has been reclaimed 8137 */ 8138 } 8139 } 8140 hdd_check_for_existing_macaddr(struct hdd_context * hdd_ctx,tSirMacAddr mac_addr)8141 static QDF_STATUS hdd_check_for_existing_macaddr(struct hdd_context *hdd_ctx, 8142 tSirMacAddr mac_addr) 8143 { 8144 struct hdd_adapter *adapter, *next_adapter = NULL; 8145 wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_CHECK_FOR_EXISTING_MACADDR; 8146 8147 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 8148 dbgid) { 8149 if (!qdf_mem_cmp(adapter->mac_addr.bytes, 8150 mac_addr, sizeof(tSirMacAddr))) { 8151 hdd_adapter_dev_put_debug(adapter, dbgid); 8152 if (next_adapter) 8153 hdd_adapter_dev_put_debug(next_adapter, 8154 dbgid); 8155 return QDF_STATUS_E_FAILURE; 8156 } 8157 hdd_adapter_dev_put_debug(adapter, dbgid); 8158 } 8159 8160 return QDF_STATUS_SUCCESS; 8161 } 8162 8163 /** 8164 * hdd_configure_chain_mask() - programs chain mask to firmware 8165 * @adapter: HDD adapter 8166 * 8167 * Return: 0 on success or errno on failure 8168 */ hdd_configure_chain_mask(struct hdd_adapter * adapter)8169 static int hdd_configure_chain_mask(struct hdd_adapter *adapter) 8170 { 8171 QDF_STATUS status; 8172 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); 8173 8174 status = ucfg_mlme_configure_chain_mask(hdd_ctx->psoc, 8175 adapter->deflink->vdev_id); 8176 if (QDF_IS_STATUS_ERROR(status)) 8177 goto error; 8178 8179 return 0; 8180 8181 error: 8182 hdd_debug("WMI PDEV set param failed"); 8183 return -EINVAL; 8184 } 8185 hdd_adapter_update_mlo_mgr_mac_addr(struct hdd_adapter * adapter)8186 void hdd_adapter_update_mlo_mgr_mac_addr(struct hdd_adapter *adapter) 8187 { 8188 int i = 0; 8189 struct wlan_hdd_link_info *link_info; 8190 struct wlan_mlo_link_mac_update link_mac = {0}; 8191 8192 if (!hdd_adapter_is_ml_adapter(adapter)) 8193 return; 8194 8195 hdd_adapter_for_each_link_info(adapter, link_info) { 8196 link_mac.link_mac_info[i].vdev_id = link_info->vdev_id; 8197 qdf_copy_macaddr(&link_mac.link_mac_info[i++].link_mac_addr, 8198 &link_info->link_addr); 8199 } 8200 8201 link_mac.num_mac_update = i; 8202 mlo_mgr_update_link_info_mac_addr(adapter->deflink->vdev, &link_mac); 8203 } 8204 8205 #ifdef FEATURE_COEX 8206 /** 8207 * hdd_send_coex_config_params() - Send coex config params to FW 8208 * @hdd_ctx: HDD context 8209 * @adapter: Primary adapter context 8210 * 8211 * This function is used to send all coex config related params to FW 8212 * 8213 * Return: 0 on success and -EINVAL on failure 8214 */ hdd_send_coex_config_params(struct hdd_context * hdd_ctx,struct hdd_adapter * adapter)8215 static int hdd_send_coex_config_params(struct hdd_context *hdd_ctx, 8216 struct hdd_adapter *adapter) 8217 { 8218 struct wlan_objmgr_vdev *vdev; 8219 struct coex_config_params coex_cfg_params = {0}; 8220 struct coex_multi_config *coex_multi_cfg = NULL; 8221 struct wlan_fwol_coex_config config = {0}; 8222 struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc; 8223 enum coex_btc_chain_mode btc_chain_mode; 8224 QDF_STATUS status; 8225 uint32_t i = 0; 8226 8227 if (!adapter) { 8228 hdd_err("adapter is invalid"); 8229 goto err; 8230 } 8231 8232 if (!psoc) { 8233 hdd_err("HDD psoc is invalid"); 8234 goto err; 8235 } 8236 8237 status = ucfg_fwol_get_coex_config_params(psoc, &config); 8238 if (QDF_IS_STATUS_ERROR(status)) { 8239 hdd_err("Unable to get coex config params"); 8240 goto err; 8241 } 8242 8243 coex_multi_cfg = qdf_mem_malloc(sizeof(*coex_multi_cfg)); 8244 if (!coex_multi_cfg) 8245 goto err; 8246 8247 coex_multi_cfg->vdev_id = adapter->deflink->vdev_id; 8248 8249 coex_multi_cfg->cfg_items[i].config_type = WMI_COEX_CONFIG_TX_POWER; 8250 coex_multi_cfg->cfg_items[i].config_arg1 = config.max_tx_power_for_btc; 8251 8252 wma_nofl_debug("TXP[W][send_coex_cfg]: %d", 8253 config.max_tx_power_for_btc); 8254 8255 if (++i > COEX_MULTI_CONFIG_MAX_CNT) 8256 goto err; 8257 8258 coex_multi_cfg->cfg_items[i].config_type = 8259 WMI_COEX_CONFIG_HANDOVER_RSSI; 8260 coex_multi_cfg->cfg_items[i].config_arg1 = 8261 config.wlan_low_rssi_threshold; 8262 8263 if (++i > COEX_MULTI_CONFIG_MAX_CNT) 8264 goto err; 8265 8266 coex_multi_cfg->cfg_items[i].config_type = WMI_COEX_CONFIG_BTC_MODE; 8267 8268 /* Modify BTC_MODE according to BTC_CHAIN_MODE */ 8269 status = ucfg_coex_psoc_get_btc_chain_mode(psoc, &btc_chain_mode); 8270 if (QDF_IS_STATUS_ERROR(status)) { 8271 hdd_err("Failed to get btc chain mode"); 8272 btc_chain_mode = WLAN_COEX_BTC_CHAIN_MODE_UNSETTLED; 8273 } 8274 8275 if (btc_chain_mode <= WLAN_COEX_BTC_CHAIN_MODE_HYBRID) 8276 coex_multi_cfg->cfg_items[i].config_arg1 = btc_chain_mode; 8277 else 8278 coex_multi_cfg->cfg_items[i].config_arg1 = config.btc_mode; 8279 8280 hdd_debug("Configured BTC mode is %d, BTC chain mode is 0x%x, set BTC mode to %d", 8281 config.btc_mode, btc_chain_mode, 8282 coex_multi_cfg->cfg_items[i].config_arg1); 8283 8284 if (++i > COEX_MULTI_CONFIG_MAX_CNT) 8285 goto err; 8286 8287 coex_multi_cfg->cfg_items[i].config_type = 8288 WMI_COEX_CONFIG_ANTENNA_ISOLATION; 8289 coex_multi_cfg->cfg_items[i].config_arg1 = config.antenna_isolation; 8290 if (++i > COEX_MULTI_CONFIG_MAX_CNT) 8291 goto err; 8292 8293 coex_multi_cfg->cfg_items[i].config_type = 8294 WMI_COEX_CONFIG_BT_LOW_RSSI_THRESHOLD; 8295 coex_multi_cfg->cfg_items[i].config_arg1 = config.bt_low_rssi_threshold; 8296 8297 if (++i > COEX_MULTI_CONFIG_MAX_CNT) 8298 goto err; 8299 8300 coex_multi_cfg->cfg_items[i].config_type = 8301 WMI_COEX_CONFIG_BT_INTERFERENCE_LEVEL; 8302 coex_multi_cfg->cfg_items[i].config_arg1 = 8303 config.bt_interference_low_ll; 8304 coex_multi_cfg->cfg_items[i].config_arg2 = 8305 config.bt_interference_low_ul; 8306 coex_multi_cfg->cfg_items[i].config_arg3 = 8307 config.bt_interference_medium_ll; 8308 coex_multi_cfg->cfg_items[i].config_arg4 = 8309 config.bt_interference_medium_ul; 8310 coex_multi_cfg->cfg_items[i].config_arg5 = 8311 config.bt_interference_high_ll; 8312 coex_multi_cfg->cfg_items[i].config_arg6 = 8313 config.bt_interference_high_ul; 8314 8315 if (++i > COEX_MULTI_CONFIG_MAX_CNT) 8316 goto err; 8317 8318 if (wlan_hdd_mpta_helper_enable(&coex_cfg_params, &config)) 8319 goto err; 8320 8321 coex_multi_cfg->cfg_items[i].config_type = 8322 WMI_COEX_CONFIG_BT_SCO_ALLOW_WLAN_2G_SCAN; 8323 coex_multi_cfg->cfg_items[i].config_arg1 = 8324 config.bt_sco_allow_wlan_2g_scan; 8325 8326 if (++i > COEX_MULTI_CONFIG_MAX_CNT) 8327 goto err; 8328 8329 coex_multi_cfg->cfg_items[i].config_type = 8330 WMI_COEX_CONFIG_LE_SCAN_POLICY; 8331 coex_multi_cfg->cfg_items[i].config_arg1 = config.ble_scan_coex_policy; 8332 8333 if (++i > COEX_MULTI_CONFIG_MAX_CNT) 8334 goto err; 8335 8336 #ifdef FEATURE_COEX_TPUT_SHAPING_CONFIG 8337 coex_multi_cfg->cfg_items[i].config_type = 8338 WMI_COEX_CONFIG_ENABLE_TPUT_SHAPING; 8339 coex_multi_cfg->cfg_items[i].config_arg1 = 8340 config.coex_tput_shaping_enable; 8341 8342 if (++i > COEX_MULTI_CONFIG_MAX_CNT) 8343 goto err; 8344 #endif 8345 8346 coex_multi_cfg->num_configs = i; 8347 8348 vdev = hdd_objmgr_get_vdev_by_user(adapter->deflink, WLAN_COEX_ID); 8349 if (!vdev) { 8350 hdd_err("vdev is null"); 8351 goto err; 8352 } 8353 8354 ucfg_coex_send_multi_config(vdev, coex_multi_cfg); 8355 8356 hdd_objmgr_put_vdev_by_user(vdev, WLAN_COEX_ID); 8357 qdf_mem_free(coex_multi_cfg); 8358 8359 return 0; 8360 err: 8361 qdf_mem_free(coex_multi_cfg); 8362 return -EINVAL; 8363 } 8364 #else 8365 /** 8366 * hdd_send_coex_config_params() - Send coex config params to FW 8367 * @hdd_ctx: HDD context 8368 * @adapter: Primary adapter context 8369 * 8370 * This function is used to send all coex config related params to FW 8371 * 8372 * Return: 0 on success and -EINVAL on failure 8373 */ hdd_send_coex_config_params(struct hdd_context * hdd_ctx,struct hdd_adapter * adapter)8374 static int hdd_send_coex_config_params(struct hdd_context *hdd_ctx, 8375 struct hdd_adapter *adapter) 8376 { 8377 struct coex_config_params coex_cfg_params = {0}; 8378 struct wlan_fwol_coex_config config = {0}; 8379 struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc; 8380 enum coex_btc_chain_mode btc_chain_mode; 8381 QDF_STATUS status; 8382 8383 if (!adapter) { 8384 hdd_err("adapter is invalid"); 8385 goto err; 8386 } 8387 8388 if (!psoc) { 8389 hdd_err("HDD psoc is invalid"); 8390 goto err; 8391 } 8392 8393 status = ucfg_fwol_get_coex_config_params(psoc, &config); 8394 if (QDF_IS_STATUS_ERROR(status)) { 8395 hdd_err("Unable to get coex config params"); 8396 goto err; 8397 } 8398 8399 coex_cfg_params.vdev_id = adapter->deflink->vdev_id; 8400 coex_cfg_params.config_type = WMI_COEX_CONFIG_TX_POWER; 8401 coex_cfg_params.config_arg1 = config.max_tx_power_for_btc; 8402 8403 wma_nofl_debug("TXP[W][send_coex_cfg]: %d", 8404 config.max_tx_power_for_btc); 8405 8406 status = sme_send_coex_config_cmd(&coex_cfg_params); 8407 if (QDF_IS_STATUS_ERROR(status)) { 8408 hdd_err("Failed to send coex Tx power"); 8409 goto err; 8410 } 8411 8412 coex_cfg_params.config_type = WMI_COEX_CONFIG_HANDOVER_RSSI; 8413 coex_cfg_params.config_arg1 = config.wlan_low_rssi_threshold; 8414 8415 status = sme_send_coex_config_cmd(&coex_cfg_params); 8416 if (QDF_IS_STATUS_ERROR(status)) { 8417 hdd_err("Failed to send coex handover RSSI"); 8418 goto err; 8419 } 8420 8421 coex_cfg_params.config_type = WMI_COEX_CONFIG_BTC_MODE; 8422 8423 /* Modify BTC_MODE according to BTC_CHAIN_MODE */ 8424 status = ucfg_coex_psoc_get_btc_chain_mode(psoc, &btc_chain_mode); 8425 if (QDF_IS_STATUS_ERROR(status)) { 8426 hdd_err("Failed to get btc chain mode"); 8427 btc_chain_mode = WLAN_COEX_BTC_CHAIN_MODE_UNSETTLED; 8428 } 8429 8430 if (btc_chain_mode <= WLAN_COEX_BTC_CHAIN_MODE_HYBRID) 8431 coex_cfg_params.config_arg1 = btc_chain_mode; 8432 else 8433 coex_cfg_params.config_arg1 = config.btc_mode; 8434 8435 hdd_debug("Configured BTC mode is %d, BTC chain mode is 0x%x, set BTC mode to %d", 8436 config.btc_mode, btc_chain_mode, 8437 coex_cfg_params.config_arg1); 8438 status = sme_send_coex_config_cmd(&coex_cfg_params); 8439 if (QDF_IS_STATUS_ERROR(status)) { 8440 hdd_err("Failed to send coex BTC mode"); 8441 goto err; 8442 } 8443 8444 coex_cfg_params.config_type = WMI_COEX_CONFIG_ANTENNA_ISOLATION; 8445 coex_cfg_params.config_arg1 = config.antenna_isolation; 8446 8447 status = sme_send_coex_config_cmd(&coex_cfg_params); 8448 if (QDF_IS_STATUS_ERROR(status)) { 8449 hdd_err("Failed to send coex antenna isolation"); 8450 goto err; 8451 } 8452 8453 coex_cfg_params.config_type = WMI_COEX_CONFIG_BT_LOW_RSSI_THRESHOLD; 8454 coex_cfg_params.config_arg1 = config.bt_low_rssi_threshold; 8455 8456 status = sme_send_coex_config_cmd(&coex_cfg_params); 8457 if (QDF_IS_STATUS_ERROR(status)) { 8458 hdd_err("Failed to send coex BT low RSSI threshold"); 8459 goto err; 8460 } 8461 8462 coex_cfg_params.config_type = WMI_COEX_CONFIG_BT_INTERFERENCE_LEVEL; 8463 coex_cfg_params.config_arg1 = config.bt_interference_low_ll; 8464 coex_cfg_params.config_arg2 = config.bt_interference_low_ul; 8465 coex_cfg_params.config_arg3 = config.bt_interference_medium_ll; 8466 coex_cfg_params.config_arg4 = config.bt_interference_medium_ul; 8467 coex_cfg_params.config_arg5 = config.bt_interference_high_ll; 8468 coex_cfg_params.config_arg6 = config.bt_interference_high_ul; 8469 8470 status = sme_send_coex_config_cmd(&coex_cfg_params); 8471 if (QDF_IS_STATUS_ERROR(status)) { 8472 hdd_err("Failed to send coex BT interference level"); 8473 goto err; 8474 } 8475 8476 if (wlan_hdd_mpta_helper_enable(&coex_cfg_params, &config)) 8477 goto err; 8478 8479 coex_cfg_params.config_type = 8480 WMI_COEX_CONFIG_BT_SCO_ALLOW_WLAN_2G_SCAN; 8481 coex_cfg_params.config_arg1 = config.bt_sco_allow_wlan_2g_scan; 8482 8483 status = sme_send_coex_config_cmd(&coex_cfg_params); 8484 if (QDF_IS_STATUS_ERROR(status)) { 8485 hdd_err("Failed to send coex BT sco allow wlan 2g scan"); 8486 goto err; 8487 } 8488 8489 coex_cfg_params.config_type = 8490 WMI_COEX_CONFIG_LE_SCAN_POLICY; 8491 coex_cfg_params.config_arg1 = config.ble_scan_coex_policy; 8492 8493 status = sme_send_coex_config_cmd(&coex_cfg_params); 8494 if (QDF_IS_STATUS_ERROR(status)) { 8495 hdd_err("Failed to send coex BLE scan policy"); 8496 goto err; 8497 } 8498 8499 #ifdef FEATURE_COEX_TPUT_SHAPING_CONFIG 8500 coex_cfg_params.config_type = 8501 WMI_COEX_CONFIG_ENABLE_TPUT_SHAPING; 8502 coex_cfg_params.config_arg1 = config.coex_tput_shaping_enable; 8503 8504 status = sme_send_coex_config_cmd(&coex_cfg_params); 8505 if (QDF_IS_STATUS_ERROR(status)) { 8506 hdd_err("Failed to send coex traffic shaping value %d", 8507 coex_cfg_params.config_arg1); 8508 goto err; 8509 } 8510 #endif 8511 return 0; 8512 err: 8513 return -EINVAL; 8514 } 8515 #endif 8516 8517 /** 8518 * hdd_send_coex_traffic_shaping_mode() - Send coex traffic shaping mode 8519 * to FW 8520 * @vdev_id: vdev ID 8521 * @mode: traffic shaping mode 8522 * 8523 * This function is used to send coex traffic shaping mode to FW 8524 * 8525 * Return: 0 on success and -EINVAL on failure 8526 */ hdd_send_coex_traffic_shaping_mode(uint8_t vdev_id,uint8_t mode)8527 int hdd_send_coex_traffic_shaping_mode(uint8_t vdev_id, uint8_t mode) 8528 { 8529 struct coex_config_params coex_cfg_params = {0}; 8530 8531 coex_cfg_params.config_type = WMI_COEX_SET_TRAFFIC_SHAPING_MODE; 8532 coex_cfg_params.config_arg1 = mode; 8533 coex_cfg_params.vdev_id = vdev_id; 8534 8535 if (QDF_IS_STATUS_ERROR(sme_send_coex_config_cmd(&coex_cfg_params))) { 8536 hdd_err_rl("Failed to send coex traffic shaping mode"); 8537 return -EINVAL; 8538 } 8539 return 0; 8540 } 8541 8542 #define MAX_PDEV_SET_FW_PARAMS 7 8543 /* params being sent: 8544 * 1.wmi_pdev_param_dtim_synth 8545 * 2.wmi_pdev_param_1ch_dtim_optimized_chain_selection 8546 * 3.wmi_pdev_param_tx_sch_delay 8547 * 4.wmi_pdev_param_en_update_scram_seed 8548 * 5.wmi_pdev_param_secondary_retry_enable 8549 * 6.wmi_pdev_param_set_sap_xlna_bypass 8550 * 7.wmi_pdev_param_set_dfs_chan_ageout_time 8551 */ 8552 8553 /** 8554 * hdd_set_fw_params() - Set parameters to firmware 8555 * @adapter: HDD adapter 8556 * 8557 * This function Sets various parameters to fw once the 8558 * adapter is started. 8559 * 8560 * Return: 0 on success or errno on failure 8561 */ hdd_set_fw_params(struct hdd_adapter * adapter)8562 int hdd_set_fw_params(struct hdd_adapter *adapter) 8563 { 8564 int ret; 8565 uint16_t upper_brssi_thresh, lower_brssi_thresh; 8566 bool enable_dtim_1chrx; 8567 QDF_STATUS status; 8568 struct hdd_context *hdd_ctx; 8569 bool is_lprx_enabled; 8570 bool bval = false; 8571 uint8_t enable_tx_sch_delay, dfs_chan_ageout_time; 8572 uint32_t dtim_sel_diversity, enable_secondary_rate; 8573 bool sap_xlna_bypass; 8574 bool enable_ofdm_scrambler_seed = false; 8575 struct dev_set_param setparam[MAX_PDEV_SET_FW_PARAMS] = { }; 8576 uint8_t index = 0; 8577 8578 hdd_enter_dev(adapter->dev); 8579 8580 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 8581 if (!hdd_ctx) 8582 return -EINVAL; 8583 8584 if (cds_get_conparam() == QDF_GLOBAL_FTM_MODE) { 8585 hdd_debug("FTM Mode is active; nothing to do"); 8586 return 0; 8587 } 8588 8589 /* The ini gEnableLPRx is deprecated. By default, the ini 8590 * is enabled. So, making the variable is_lprx_enabled true. 8591 */ 8592 is_lprx_enabled = true; 8593 8594 ret = mlme_check_index_setparam(setparam, wmi_pdev_param_dtim_synth, 8595 is_lprx_enabled, index++, 8596 MAX_PDEV_SET_FW_PARAMS); 8597 if (QDF_IS_STATUS_ERROR(ret)) 8598 goto error; 8599 8600 ucfg_mlme_get_dtim_selection_diversity(hdd_ctx->psoc, 8601 &dtim_sel_diversity); 8602 ret = mlme_check_index_setparam( 8603 setparam, 8604 wmi_pdev_param_1ch_dtim_optimized_chain_selection, 8605 dtim_sel_diversity, index++, MAX_PDEV_SET_FW_PARAMS); 8606 if (QDF_IS_STATUS_ERROR(ret)) 8607 goto error; 8608 8609 if (QDF_IS_STATUS_SUCCESS(ucfg_fwol_get_enable_tx_sch_delay( 8610 hdd_ctx->psoc, &enable_tx_sch_delay))) { 8611 ret = mlme_check_index_setparam( 8612 setparam, 8613 wmi_pdev_param_tx_sch_delay, 8614 enable_tx_sch_delay, index++, 8615 MAX_PDEV_SET_FW_PARAMS); 8616 if (QDF_IS_STATUS_ERROR(ret)) 8617 goto error; 8618 } 8619 8620 if (QDF_IS_STATUS_SUCCESS(ucfg_fwol_get_ofdm_scrambler_seed( 8621 hdd_ctx->psoc, &enable_ofdm_scrambler_seed))) { 8622 ret = mlme_check_index_setparam( 8623 setparam, 8624 wmi_pdev_param_en_update_scram_seed, 8625 enable_ofdm_scrambler_seed, index++, 8626 MAX_PDEV_SET_FW_PARAMS); 8627 if (QDF_IS_STATUS_ERROR(ret)) 8628 goto error; 8629 } 8630 8631 if (QDF_IS_STATUS_SUCCESS(ucfg_fwol_get_enable_secondary_rate( 8632 hdd_ctx->psoc, &enable_secondary_rate))) { 8633 ret = mlme_check_index_setparam( 8634 setparam, 8635 wmi_pdev_param_secondary_retry_enable, 8636 enable_secondary_rate, index++, 8637 MAX_PDEV_SET_FW_PARAMS); 8638 if (QDF_IS_STATUS_ERROR(ret)) 8639 goto error; 8640 } 8641 if (QDF_IS_STATUS_SUCCESS(ucfg_fwol_get_sap_xlna_bypass( 8642 hdd_ctx->psoc, &sap_xlna_bypass))) { 8643 ret = mlme_check_index_setparam( 8644 setparam, 8645 wmi_pdev_param_set_sap_xlna_bypass, 8646 sap_xlna_bypass, index++, 8647 MAX_PDEV_SET_FW_PARAMS); 8648 if (QDF_IS_STATUS_ERROR(ret)) 8649 goto error; 8650 } 8651 wlan_mlme_get_dfs_chan_ageout_time(hdd_ctx->psoc, 8652 &dfs_chan_ageout_time); 8653 ret = mlme_check_index_setparam( 8654 setparam, 8655 wmi_pdev_param_set_dfs_chan_ageout_time, 8656 dfs_chan_ageout_time, index++, 8657 MAX_PDEV_SET_FW_PARAMS); 8658 if (QDF_IS_STATUS_ERROR(ret)) 8659 goto error; 8660 8661 ret = sme_send_multi_pdev_vdev_set_params(MLME_PDEV_SETPARAM, 8662 WMI_PDEV_ID_SOC, setparam, 8663 index); 8664 if (QDF_IS_STATUS_ERROR(ret)) { 8665 goto error; 8666 } 8667 if (adapter->device_mode == QDF_STA_MODE) { 8668 status = ucfg_get_upper_brssi_thresh(hdd_ctx->psoc, 8669 &upper_brssi_thresh); 8670 if (QDF_IS_STATUS_ERROR(status)) 8671 return -EINVAL; 8672 8673 sme_set_smps_cfg(adapter->deflink->vdev_id, 8674 HDD_STA_SMPS_PARAM_UPPER_BRSSI_THRESH, 8675 upper_brssi_thresh); 8676 8677 status = ucfg_get_lower_brssi_thresh(hdd_ctx->psoc, 8678 &lower_brssi_thresh); 8679 if (QDF_IS_STATUS_ERROR(status)) 8680 return -EINVAL; 8681 8682 sme_set_smps_cfg(adapter->deflink->vdev_id, 8683 HDD_STA_SMPS_PARAM_LOWER_BRSSI_THRESH, 8684 lower_brssi_thresh); 8685 8686 status = ucfg_get_enable_dtim_1chrx(hdd_ctx->psoc, 8687 &enable_dtim_1chrx); 8688 if (QDF_IS_STATUS_ERROR(status)) 8689 return -EINVAL; 8690 8691 sme_set_smps_cfg(adapter->deflink->vdev_id, 8692 HDD_STA_SMPS_PARAM_DTIM_1CHRX_ENABLE, 8693 enable_dtim_1chrx); 8694 } 8695 8696 status = ucfg_mlme_get_vht_enable2x2(hdd_ctx->psoc, &bval); 8697 if (!QDF_IS_STATUS_SUCCESS(status)) 8698 hdd_err("unable to get vht_enable2x2"); 8699 8700 if (bval) { 8701 hdd_debug("configuring 2x2 mode fw params"); 8702 8703 ret = sme_set_cck_tx_fir_override(hdd_ctx->mac_handle, 8704 adapter->deflink->vdev_id); 8705 if (ret) { 8706 hdd_err("wmi_pdev_param_enable_cck_tfir_override set failed %d", 8707 ret); 8708 goto error; 8709 } 8710 8711 hdd_configure_chain_mask(adapter); 8712 } else { 8713 #define HDD_DTIM_1CHAIN_RX_ID 0x5 8714 #define HDD_SMPS_PARAM_VALUE_S 29 8715 hdd_debug("configuring 1x1 mode fw params"); 8716 8717 /* 8718 * Disable DTIM 1 chain Rx when in 1x1, 8719 * we are passing two value 8720 * as param_id << 29 | param_value. 8721 * Below param_value = 0(disable) 8722 */ 8723 ret = sme_cli_set_command(adapter->deflink->vdev_id, 8724 WMI_STA_SMPS_PARAM_CMDID, 8725 HDD_DTIM_1CHAIN_RX_ID << 8726 HDD_SMPS_PARAM_VALUE_S, 8727 VDEV_CMD); 8728 if (ret) { 8729 hdd_err("DTIM 1 chain set failed %d", ret); 8730 goto error; 8731 } 8732 8733 #undef HDD_DTIM_1CHAIN_RX_ID 8734 #undef HDD_SMPS_PARAM_VALUE_S 8735 8736 hdd_configure_chain_mask(adapter); 8737 } 8738 8739 ret = sme_set_enable_mem_deep_sleep(hdd_ctx->mac_handle, 8740 adapter->deflink->vdev_id); 8741 if (ret) { 8742 hdd_err("wmi_pdev_param_hyst_en set failed %d", ret); 8743 goto error; 8744 } 8745 8746 if (!hdd_ctx->is_fw_dbg_log_levels_configured) { 8747 hdd_set_fw_log_params(hdd_ctx, adapter->deflink->vdev_id); 8748 hdd_ctx->is_fw_dbg_log_levels_configured = true; 8749 } 8750 8751 ret = hdd_send_coex_config_params(hdd_ctx, adapter); 8752 if (ret) { 8753 hdd_warn("Error initializing coex config params"); 8754 goto error; 8755 } 8756 8757 hdd_exit(); 8758 8759 return 0; 8760 8761 error: 8762 return -EINVAL; 8763 } 8764 8765 /** 8766 * hdd_init_completion() - Initialize Completion Variables 8767 * @adapter: HDD adapter 8768 * 8769 * This function Initialize the completion variables for 8770 * a particular adapter 8771 * 8772 * Return: None 8773 */ hdd_init_completion(struct hdd_adapter * adapter)8774 static void hdd_init_completion(struct hdd_adapter *adapter) 8775 { 8776 init_completion(&adapter->disconnect_comp_var); 8777 init_completion(&adapter->linkup_event_var); 8778 init_completion(&adapter->lfr_fw_status.disable_lfr_event); 8779 } 8780 hdd_reset_locally_admin_bit(struct hdd_context * hdd_ctx,tSirMacAddr mac_addr)8781 static void hdd_reset_locally_admin_bit(struct hdd_context *hdd_ctx, 8782 tSirMacAddr mac_addr) 8783 { 8784 int i; 8785 /* 8786 * Reset locally administered bit for dynamic_mac_list 8787 * also as while releasing the MAC address for any 8788 * interface mac will be compared with dynamic mac list 8789 */ 8790 for (i = 0; i < QDF_MAX_CONCURRENCY_PERSONA; i++) { 8791 if (!qdf_mem_cmp( 8792 mac_addr, 8793 &hdd_ctx-> 8794 dynamic_mac_list[i].dynamic_mac.bytes[0], 8795 sizeof(struct qdf_mac_addr))) { 8796 WLAN_HDD_RESET_LOCALLY_ADMINISTERED_BIT( 8797 hdd_ctx-> 8798 dynamic_mac_list[i].dynamic_mac.bytes); 8799 break; 8800 } 8801 } 8802 /* 8803 * Reset locally administered bit if the device mode is 8804 * STA 8805 */ 8806 WLAN_HDD_RESET_LOCALLY_ADMINISTERED_BIT(mac_addr); 8807 hdd_debug("locally administered bit reset in sta mode: " 8808 QDF_MAC_ADDR_FMT, QDF_MAC_ADDR_REF(mac_addr)); 8809 } 8810 wlan_hdd_cfg80211_scan_block_cb(struct work_struct * work)8811 static void wlan_hdd_cfg80211_scan_block_cb(struct work_struct *work) 8812 { 8813 struct hdd_adapter *adapter = 8814 container_of(work, struct hdd_adapter, scan_block_work); 8815 struct osif_vdev_sync *vdev_sync; 8816 8817 if (osif_vdev_sync_op_start(adapter->dev, &vdev_sync)) 8818 return; 8819 8820 wlan_hdd_cfg80211_scan_block(adapter); 8821 8822 osif_vdev_sync_op_stop(vdev_sync); 8823 } 8824 8825 #if defined(WLAN_FEATURE_11BE_MLO) && \ 8826 defined(WLAN_HDD_MULTI_VDEV_SINGLE_NDEV) 8827 static inline void wlan_hdd_set_ml_cap_for_sap_intf(struct hdd_adapter_create_param * create_params,enum QDF_OPMODE mode)8828 wlan_hdd_set_ml_cap_for_sap_intf(struct hdd_adapter_create_param *create_params, 8829 enum QDF_OPMODE mode) 8830 { 8831 if (mode != QDF_SAP_MODE) 8832 return; 8833 8834 create_params->is_ml_adapter = true; 8835 } 8836 #elif defined(WLAN_FEATURE_11BE_MLO) 8837 static inline void wlan_hdd_set_ml_cap_for_sap_intf(struct hdd_adapter_create_param * create_params,enum QDF_OPMODE mode)8838 wlan_hdd_set_ml_cap_for_sap_intf(struct hdd_adapter_create_param *create_params, 8839 enum QDF_OPMODE mode) 8840 { 8841 if (mode != QDF_SAP_MODE) 8842 return; 8843 8844 create_params->is_ml_adapter = true; 8845 create_params->is_single_link = true; 8846 } 8847 #else 8848 static inline void wlan_hdd_set_ml_cap_for_sap_intf(struct hdd_adapter_create_param * create_params,enum QDF_OPMODE mode)8849 wlan_hdd_set_ml_cap_for_sap_intf(struct hdd_adapter_create_param *create_params, 8850 enum QDF_OPMODE mode) 8851 { 8852 create_params->is_ml_adapter = false; 8853 } 8854 #endif /* WLAN_FEATURE_11BE_MLO */ 8855 8856 #if defined(WLAN_FEATURE_11BE_MLO) && defined(CFG80211_11BE_BASIC) && \ 8857 defined(WLAN_HDD_MULTI_VDEV_SINGLE_NDEV) 8858 void hdd_adapter_disable_all_links(struct hdd_adapter * adapter,bool clear_macaddr)8859 hdd_adapter_disable_all_links(struct hdd_adapter *adapter, bool clear_macaddr) 8860 { 8861 uint8_t idx_pos; 8862 struct wlan_hdd_link_info *link_info; 8863 8864 hdd_adapter_for_each_link_info(adapter, link_info) { 8865 if (clear_macaddr) 8866 qdf_zero_macaddr(&link_info->link_addr); 8867 idx_pos = hdd_adapter_get_index_of_link_info(link_info); 8868 adapter->curr_link_info_map[idx_pos] = idx_pos; 8869 } 8870 8871 adapter->deflink = &adapter->link_info[WLAN_HDD_DEFLINK_IDX]; 8872 adapter->active_links = (1 << adapter->num_links_on_create) - 1; 8873 } 8874 #endif 8875 hdd_adapter_enable_links(struct hdd_adapter * adapter,struct hdd_adapter_create_param * params)8876 static void hdd_adapter_enable_links(struct hdd_adapter *adapter, 8877 struct hdd_adapter_create_param *params) 8878 { 8879 uint8_t num, link_idx; 8880 8881 /* Default link is already set on adapter allocation, only 8882 * enable other links if requested links is greater than 1 8883 */ 8884 if (params->num_sessions <= 1) { 8885 adapter->num_links_on_create = 1; 8886 return; 8887 } 8888 8889 num = QDF_MIN(params->num_sessions, WLAN_MAX_MLD); 8890 for (link_idx = WLAN_HDD_DEFLINK_IDX; link_idx < num; link_idx++) 8891 qdf_atomic_set_bit(link_idx, &adapter->active_links); 8892 8893 adapter->num_links_on_create = num; 8894 } 8895 hdd_adapter_init_link_info(struct hdd_adapter * adapter)8896 static void hdd_adapter_init_link_info(struct hdd_adapter *adapter) 8897 { 8898 uint8_t idx_pos; 8899 struct wlan_hdd_link_info *link_info; 8900 8901 /* Initialize each member in link info array to default values */ 8902 hdd_adapter_for_each_link_info(adapter, link_info) { 8903 link_info->adapter = adapter; 8904 link_info->vdev_id = WLAN_UMAC_VDEV_ID_MAX; 8905 qdf_spinlock_create(&link_info->vdev_lock); 8906 init_completion(&link_info->vdev_destroy_event); 8907 qdf_event_create(&link_info->acs_complete_event); 8908 8909 idx_pos = hdd_adapter_get_index_of_link_info(link_info); 8910 adapter->curr_link_info_map[idx_pos] = idx_pos; 8911 qdf_create_work(0, &link_info->chan_change_notify_work, 8912 hdd_chan_change_notify_work_handler, 8913 link_info); 8914 } 8915 } 8916 8917 /** 8918 * hdd_open_adapter() - open and setup the hdd adapter 8919 * @hdd_ctx: global hdd context 8920 * @session_type: type of the interface to be created 8921 * @iface_name: User-visible name of the interface 8922 * @mac_addr: MAC address to assign to the interface 8923 * @name_assign_type: the name of assign type of the netdev 8924 * @rtnl_held: the rtnl lock hold flag 8925 * @params: adapter create params 8926 * 8927 * This function open and setup the hdd adapter according to the device 8928 * type request, assign the name, the mac address assigned, and then prepared 8929 * the hdd related parameters, queue, lock and ready to start. 8930 * 8931 * Return: the pointer of hdd adapter, otherwise NULL. 8932 */ hdd_open_adapter(struct hdd_context * hdd_ctx,uint8_t session_type,const char * iface_name,tSirMacAddr mac_addr,unsigned char name_assign_type,bool rtnl_held,struct hdd_adapter_create_param * params)8933 struct hdd_adapter *hdd_open_adapter(struct hdd_context *hdd_ctx, 8934 uint8_t session_type, 8935 const char *iface_name, 8936 tSirMacAddr mac_addr, 8937 unsigned char name_assign_type, 8938 bool rtnl_held, 8939 struct hdd_adapter_create_param *params) 8940 { 8941 struct net_device *ndev = NULL; 8942 struct hdd_adapter *adapter = NULL, *sta_adapter = NULL; 8943 QDF_STATUS status = QDF_STATUS_E_FAILURE; 8944 uint32_t i; 8945 bool eht_capab = 0; 8946 8947 status = wlan_hdd_validate_mac_address((struct qdf_mac_addr *)mac_addr); 8948 if (QDF_IS_STATUS_ERROR(status)) { 8949 /* Not received valid mac_addr */ 8950 hdd_err("Unable to add virtual intf: Not able to get valid mac address"); 8951 return NULL; 8952 } 8953 8954 status = hdd_check_for_existing_macaddr(hdd_ctx, mac_addr); 8955 if (QDF_STATUS_E_FAILURE == status) { 8956 hdd_err("Duplicate MAC addr: " QDF_MAC_ADDR_FMT 8957 " already exists", 8958 QDF_MAC_ADDR_REF(mac_addr)); 8959 return NULL; 8960 } 8961 8962 if (params->only_wdev_register) { 8963 sta_adapter = hdd_get_ml_adapter(hdd_ctx); 8964 if (!sta_adapter) { 8965 hdd_err("not able to find the sta adapter"); 8966 return NULL; 8967 } 8968 } 8969 8970 switch (session_type) { 8971 case QDF_STA_MODE: 8972 if (!(hdd_ctx->config->mac_provision || 8973 params->only_wdev_register)) { 8974 hdd_reset_locally_admin_bit(hdd_ctx, mac_addr); 8975 /* 8976 * After resetting locally administered bit 8977 * again check if the new mac address is already 8978 * exists. 8979 */ 8980 status = hdd_check_for_existing_macaddr(hdd_ctx, 8981 mac_addr); 8982 if (QDF_STATUS_E_FAILURE == status) { 8983 hdd_err("Duplicate MAC addr: " QDF_MAC_ADDR_FMT 8984 " already exists", 8985 QDF_MAC_ADDR_REF(mac_addr)); 8986 return NULL; 8987 } 8988 } 8989 8990 fallthrough; 8991 case QDF_P2P_CLIENT_MODE: 8992 case QDF_P2P_DEVICE_MODE: 8993 case QDF_OCB_MODE: 8994 case QDF_NDI_MODE: 8995 case QDF_MONITOR_MODE: 8996 case QDF_NAN_DISC_MODE: 8997 adapter = hdd_alloc_station_adapter(hdd_ctx, mac_addr, 8998 name_assign_type, 8999 iface_name, session_type); 9000 9001 if (!adapter) { 9002 hdd_err("failed to allocate adapter for session %d", 9003 session_type); 9004 return NULL; 9005 } 9006 9007 ndev = adapter->dev; 9008 9009 status = ucfg_dp_create_intf(hdd_ctx->psoc, &adapter->mac_addr, 9010 (qdf_netdev_t)adapter->dev); 9011 if (QDF_IS_STATUS_ERROR(status)) 9012 goto err_free_netdev; 9013 9014 if (QDF_P2P_CLIENT_MODE == session_type) 9015 adapter->wdev.iftype = NL80211_IFTYPE_P2P_CLIENT; 9016 else if (QDF_P2P_DEVICE_MODE == session_type) 9017 adapter->wdev.iftype = NL80211_IFTYPE_P2P_DEVICE; 9018 else if (QDF_MONITOR_MODE == session_type) 9019 adapter->wdev.iftype = NL80211_IFTYPE_MONITOR; 9020 else if (QDF_NAN_DISC_MODE == session_type) 9021 wlan_hdd_set_nan_if_type(adapter); 9022 else 9023 adapter->wdev.iftype = NL80211_IFTYPE_STATION; 9024 9025 adapter->device_mode = session_type; 9026 9027 9028 /* 9029 * Workqueue which gets scheduled in IPv4 notification 9030 * callback 9031 */ 9032 INIT_WORK(&adapter->ipv4_notifier_work, 9033 hdd_ipv4_notifier_work_queue); 9034 9035 #ifdef WLAN_NS_OFFLOAD 9036 /* 9037 * Workqueue which gets scheduled in IPv6 9038 * notification callback. 9039 */ 9040 INIT_WORK(&adapter->ipv6_notifier_work, 9041 hdd_ipv6_notifier_work_queue); 9042 #endif 9043 if (params->only_wdev_register) { 9044 hdd_register_wdev(sta_adapter, adapter, params); 9045 } else { 9046 status = hdd_register_interface(adapter, rtnl_held, 9047 params); 9048 if (QDF_STATUS_SUCCESS != status) 9049 goto err_destroy_dp_intf; 9050 /* Stop the Interface TX queue. */ 9051 hdd_debug("Disabling queues"); 9052 wlan_hdd_netif_queue_control(adapter, 9053 WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER, 9054 WLAN_CONTROL_PATH); 9055 } 9056 break; 9057 case QDF_P2P_GO_MODE: 9058 case QDF_SAP_MODE: 9059 adapter = hdd_wlan_create_ap_dev(hdd_ctx, mac_addr, 9060 name_assign_type, 9061 (uint8_t *) iface_name); 9062 if (!adapter) { 9063 hdd_err("failed to allocate adapter for session %d", 9064 session_type); 9065 return NULL; 9066 } 9067 9068 ndev = adapter->dev; 9069 9070 status = ucfg_dp_create_intf(hdd_ctx->psoc, &adapter->mac_addr, 9071 (qdf_netdev_t)adapter->dev); 9072 if (QDF_IS_STATUS_ERROR(status)) 9073 goto err_free_netdev; 9074 9075 adapter->wdev.iftype = 9076 (session_type == 9077 QDF_SAP_MODE) ? NL80211_IFTYPE_AP : 9078 NL80211_IFTYPE_P2P_GO; 9079 adapter->device_mode = session_type; 9080 9081 status = hdd_register_interface(adapter, rtnl_held, params); 9082 if (QDF_STATUS_SUCCESS != status) 9083 goto err_destroy_dp_intf; 9084 9085 hdd_debug("Disabling queues"); 9086 wlan_hdd_netif_queue_control(adapter, 9087 WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER, 9088 WLAN_CONTROL_PATH); 9089 9090 /* 9091 * Workqueue which gets scheduled in IPv4 notification 9092 * callback 9093 */ 9094 INIT_WORK(&adapter->ipv4_notifier_work, 9095 hdd_ipv4_notifier_work_queue); 9096 9097 #ifdef WLAN_NS_OFFLOAD 9098 /* 9099 * Workqueue which gets scheduled in IPv6 9100 * notification callback. 9101 */ 9102 INIT_WORK(&adapter->ipv6_notifier_work, 9103 hdd_ipv6_notifier_work_queue); 9104 #endif 9105 if (!params->is_pre_cac_adapter) 9106 wlan_hdd_set_ml_cap_for_sap_intf(params, session_type); 9107 break; 9108 case QDF_FTM_MODE: 9109 adapter = hdd_alloc_station_adapter(hdd_ctx, mac_addr, 9110 name_assign_type, 9111 iface_name, session_type); 9112 if (!adapter) { 9113 hdd_err("Failed to allocate adapter for FTM mode"); 9114 return NULL; 9115 } 9116 9117 ndev = adapter->dev; 9118 9119 status = ucfg_dp_create_intf(hdd_ctx->psoc, &adapter->mac_addr, 9120 (qdf_netdev_t)adapter->dev); 9121 if (QDF_IS_STATUS_ERROR(status)) 9122 goto err_free_netdev; 9123 9124 adapter->wdev.iftype = NL80211_IFTYPE_STATION; 9125 adapter->device_mode = session_type; 9126 status = hdd_register_interface(adapter, rtnl_held, params); 9127 if (QDF_STATUS_SUCCESS != status) 9128 goto err_destroy_dp_intf; 9129 9130 /* Stop the Interface TX queue. */ 9131 hdd_debug("Disabling queues"); 9132 wlan_hdd_netif_queue_control(adapter, 9133 WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER, 9134 WLAN_CONTROL_PATH); 9135 9136 break; 9137 default: 9138 hdd_err("Invalid session type %d", session_type); 9139 QDF_ASSERT(0); 9140 return NULL; 9141 } 9142 9143 hdd_adapter_init_link_info(adapter); 9144 hdd_adapter_enable_links(adapter, params); 9145 9146 ucfg_psoc_mlme_get_11be_capab(hdd_ctx->psoc, &eht_capab); 9147 if (params->is_ml_adapter && eht_capab) { 9148 hdd_adapter_set_ml_adapter(adapter); 9149 if (params->is_single_link) 9150 hdd_adapter_set_sl_ml_adapter(adapter); 9151 } 9152 9153 status = hdd_adapter_feature_update_work_init(adapter); 9154 if (QDF_IS_STATUS_ERROR(status)) 9155 goto err_cleanup_adapter; 9156 9157 adapter->upgrade_udp_qos_threshold = QCA_WLAN_AC_BK; 9158 9159 hdd_init_completion(adapter); 9160 INIT_WORK(&adapter->scan_block_work, wlan_hdd_cfg80211_scan_block_cb); 9161 INIT_WORK(&adapter->sap_stop_bss_work, 9162 hdd_stop_sap_due_to_invalid_channel); 9163 qdf_list_create(&adapter->blocked_scan_request_q, WLAN_MAX_SCAN_COUNT); 9164 qdf_mutex_create(&adapter->blocked_scan_request_q_lock); 9165 qdf_spinlock_create(&adapter->mc_list_lock); 9166 qdf_event_create(&adapter->peer_cleanup_done); 9167 hdd_sta_info_init(&adapter->sta_info_list); 9168 hdd_sta_info_init(&adapter->cache_sta_info_list); 9169 9170 for (i = 0; i < NET_DEV_HOLD_ID_MAX; i++) 9171 qdf_atomic_init( 9172 &adapter->net_dev_hold_ref_count[NET_DEV_HOLD_ID_MAX]); 9173 9174 /* Add it to the hdd's session list. */ 9175 status = hdd_add_adapter_back(hdd_ctx, adapter); 9176 if (QDF_STATUS_SUCCESS != status) 9177 goto err_destroy_adapter_features_update_work; 9178 9179 hdd_apf_context_init(adapter); 9180 9181 policy_mgr_set_concurrency_mode(hdd_ctx->psoc, session_type); 9182 9183 if (QDF_STATUS_SUCCESS != hdd_debugfs_init(adapter)) 9184 hdd_err("debugfs: Interface %s init failed", 9185 netdev_name(adapter->dev)); 9186 9187 hdd_debug("%s interface created. iftype: %d", netdev_name(adapter->dev), 9188 session_type); 9189 9190 if (adapter->device_mode == QDF_STA_MODE) 9191 wlan_hdd_debugfs_csr_init(adapter); 9192 9193 return adapter; 9194 9195 err_destroy_adapter_features_update_work: 9196 hdd_adapter_feature_update_work_deinit(adapter); 9197 9198 err_cleanup_adapter: 9199 if (adapter) { 9200 hdd_cleanup_adapter(hdd_ctx, adapter, rtnl_held); 9201 adapter = NULL; 9202 } 9203 9204 err_destroy_dp_intf: 9205 ucfg_dp_destroy_intf(hdd_ctx->psoc, &adapter->mac_addr); 9206 9207 err_free_netdev: 9208 if (ndev) 9209 free_netdev(ndev); 9210 9211 return NULL; 9212 } 9213 __hdd_close_adapter(struct hdd_context * hdd_ctx,struct hdd_adapter * adapter,bool rtnl_held)9214 static void __hdd_close_adapter(struct hdd_context *hdd_ctx, 9215 struct hdd_adapter *adapter, 9216 bool rtnl_held) 9217 { 9218 struct qdf_mac_addr adapter_mac; 9219 struct wlan_hdd_link_info *link_info; 9220 9221 qdf_copy_macaddr(&adapter_mac, &adapter->mac_addr); 9222 if (adapter->device_mode == QDF_STA_MODE) { 9223 hdd_adapter_for_each_link_info(adapter, link_info) 9224 hdd_cleanup_conn_info(link_info); 9225 } 9226 9227 hdd_adapter_for_each_link_info(adapter, link_info) 9228 qdf_flush_work(&link_info->chan_change_notify_work); 9229 9230 qdf_list_destroy(&adapter->blocked_scan_request_q); 9231 qdf_mutex_destroy(&adapter->blocked_scan_request_q_lock); 9232 policy_mgr_clear_concurrency_mode(hdd_ctx->psoc, adapter->device_mode); 9233 qdf_event_destroy(&adapter->peer_cleanup_done); 9234 hdd_adapter_feature_update_work_deinit(adapter); 9235 hdd_cleanup_adapter(hdd_ctx, adapter, rtnl_held); 9236 ucfg_dp_destroy_intf(hdd_ctx->psoc, &adapter_mac); 9237 } 9238 hdd_close_adapter(struct hdd_context * hdd_ctx,struct hdd_adapter * adapter,bool rtnl_held)9239 void hdd_close_adapter(struct hdd_context *hdd_ctx, 9240 struct hdd_adapter *adapter, 9241 bool rtnl_held) 9242 { 9243 /* 9244 * Stop the global bus bandwidth timer while touching the adapter list 9245 * to avoid bad memory access by the timer handler. 9246 */ 9247 ucfg_dp_bus_bw_compute_timer_stop(hdd_ctx->psoc); 9248 9249 hdd_check_for_net_dev_ref_leak(adapter); 9250 hdd_remove_adapter(hdd_ctx, adapter); 9251 __hdd_close_adapter(hdd_ctx, adapter, rtnl_held); 9252 9253 /* conditionally restart the bw timer */ 9254 ucfg_dp_bus_bw_compute_timer_try_start(hdd_ctx->psoc); 9255 } 9256 hdd_close_all_adapters(struct hdd_context * hdd_ctx,bool rtnl_held)9257 void hdd_close_all_adapters(struct hdd_context *hdd_ctx, bool rtnl_held) 9258 { 9259 struct hdd_adapter *adapter; 9260 struct osif_vdev_sync *vdev_sync; 9261 QDF_STATUS qdf_status; 9262 9263 hdd_enter(); 9264 9265 while (QDF_IS_STATUS_SUCCESS(hdd_get_front_adapter( 9266 hdd_ctx, &adapter))) { 9267 /* If MLO is enabled unregister the link wdev's */ 9268 if (adapter->device_mode == QDF_STA_MODE || 9269 adapter->device_mode == QDF_SAP_MODE) { 9270 qdf_status = hdd_wlan_unregister_mlo_interfaces(adapter, 9271 rtnl_held); 9272 if (QDF_IS_STATUS_ERROR(qdf_status)) 9273 continue; 9274 } 9275 9276 hdd_check_for_net_dev_ref_leak(adapter); 9277 hdd_remove_front_adapter(hdd_ctx, &adapter); 9278 vdev_sync = osif_vdev_sync_unregister(adapter->dev); 9279 if (vdev_sync) 9280 osif_vdev_sync_wait_for_ops(vdev_sync); 9281 9282 wlan_hdd_release_intf_addr(hdd_ctx, adapter->mac_addr.bytes); 9283 __hdd_close_adapter(hdd_ctx, adapter, rtnl_held); 9284 9285 if (vdev_sync) 9286 osif_vdev_sync_destroy(vdev_sync); 9287 } 9288 9289 hdd_exit(); 9290 } 9291 wlan_hdd_reset_prob_rspies(struct wlan_hdd_link_info * link_info)9292 void wlan_hdd_reset_prob_rspies(struct wlan_hdd_link_info *link_info) 9293 { 9294 struct qdf_mac_addr *bssid = NULL; 9295 tSirUpdateIE update_ie; 9296 mac_handle_t mac_handle; 9297 struct hdd_adapter *adapter = link_info->adapter; 9298 9299 switch (adapter->device_mode) { 9300 case QDF_STA_MODE: 9301 case QDF_P2P_CLIENT_MODE: 9302 { 9303 struct hdd_station_ctx *sta_ctx = 9304 WLAN_HDD_GET_STATION_CTX_PTR(link_info); 9305 bssid = &sta_ctx->conn_info.bssid; 9306 break; 9307 } 9308 case QDF_SAP_MODE: 9309 case QDF_P2P_GO_MODE: 9310 { 9311 bssid = &adapter->mac_addr; 9312 break; 9313 } 9314 case QDF_FTM_MODE: 9315 case QDF_P2P_DEVICE_MODE: 9316 default: 9317 /* 9318 * wlan_hdd_reset_prob_rspies should not have been called 9319 * for these kind of devices 9320 */ 9321 hdd_err("Unexpected request for the current device type %d", 9322 adapter->device_mode); 9323 return; 9324 } 9325 9326 qdf_copy_macaddr(&update_ie.bssid, bssid); 9327 update_ie.vdev_id = link_info->vdev_id; 9328 update_ie.ieBufferlength = 0; 9329 update_ie.pAdditionIEBuffer = NULL; 9330 update_ie.append = true; 9331 update_ie.notify = false; 9332 mac_handle = hdd_adapter_get_mac_handle(adapter); 9333 if (sme_update_add_ie(mac_handle, 9334 &update_ie, 9335 eUPDATE_IE_PROBE_RESP) == QDF_STATUS_E_FAILURE) { 9336 hdd_err("Could not pass on PROBE_RSP_BCN data to PE"); 9337 } 9338 } 9339 9340 /** 9341 * hdd_ipa_ap_disconnect_evt() - Indicate wlan ipa ap disconnect event 9342 * @hdd_ctx: hdd context 9343 * @adapter: hdd adapter 9344 * 9345 * Return: None 9346 */ 9347 static inline hdd_ipa_ap_disconnect_evt(struct hdd_context * hdd_ctx,struct hdd_adapter * adapter)9348 void hdd_ipa_ap_disconnect_evt(struct hdd_context *hdd_ctx, 9349 struct hdd_adapter *adapter) 9350 { 9351 struct wlan_hdd_link_info *link_info; 9352 9353 link_info = adapter->deflink; 9354 if (ucfg_ipa_is_enabled()) { 9355 ucfg_ipa_uc_disconnect_ap(hdd_ctx->pdev, 9356 adapter->dev); 9357 ucfg_ipa_cleanup_dev_iface(hdd_ctx->pdev, 9358 adapter->dev, 9359 link_info->vdev_id); 9360 } 9361 } 9362 9363 #ifdef WLAN_FEATURE_NAN 9364 /** 9365 * hdd_ndp_state_cleanup() - API to set NDP state to Disconnected 9366 * @psoc: pointer to psoc object 9367 * @ndi_vdev_id: vdev_id of the NDI 9368 * 9369 * Return: None 9370 */ 9371 static void hdd_ndp_state_cleanup(struct wlan_objmgr_psoc * psoc,uint8_t ndi_vdev_id)9372 hdd_ndp_state_cleanup(struct wlan_objmgr_psoc *psoc, uint8_t ndi_vdev_id) 9373 { 9374 struct wlan_objmgr_vdev *ndi_vdev; 9375 9376 ndi_vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, ndi_vdev_id, 9377 WLAN_NAN_ID); 9378 if (!ndi_vdev) { 9379 hdd_err("Cannot obtain NDI vdev object!"); 9380 return; 9381 } 9382 9383 ucfg_nan_set_ndi_state(ndi_vdev, NAN_DATA_DISCONNECTED_STATE); 9384 9385 wlan_objmgr_vdev_release_ref(ndi_vdev, WLAN_NAN_ID); 9386 } 9387 9388 /** 9389 * hdd_peer_cleanup() - This API will delete NDP peer if exist and modifies 9390 * the NDP state. 9391 * @link_info: Link info pointer in HDD adapter 9392 * 9393 * Return: None 9394 */ hdd_peer_cleanup(struct wlan_hdd_link_info * link_info)9395 static void hdd_peer_cleanup(struct wlan_hdd_link_info *link_info) 9396 { 9397 QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE; 9398 struct hdd_adapter *adapter = link_info->adapter; 9399 struct hdd_context *hdd_ctx = adapter->hdd_ctx; 9400 9401 /* Check if there is any peer present on the adapter */ 9402 if (!hdd_any_valid_peer_present(link_info)) { 9403 /* 9404 * No peers are connected to the NDI. So, set the NDI state to 9405 * DISCONNECTED. If there are any peers, ucfg_nan_disable_ndi() 9406 * would take care of cleanup all the peers and setting the 9407 * state to DISCONNECTED. 9408 */ 9409 hdd_ndp_state_cleanup(hdd_ctx->psoc, link_info->vdev_id); 9410 return; 9411 } 9412 9413 if (adapter->device_mode == QDF_NDI_MODE) 9414 qdf_status = ucfg_nan_disable_ndi(hdd_ctx->psoc, 9415 link_info->vdev_id); 9416 9417 if (QDF_IS_STATUS_ERROR(qdf_status)) 9418 return; 9419 9420 qdf_status = qdf_wait_for_event_completion(&adapter->peer_cleanup_done, 9421 WLAN_WAIT_PEER_CLEANUP); 9422 if (QDF_IS_STATUS_ERROR(qdf_status)) 9423 hdd_debug("peer_cleanup_done wait fail"); 9424 } 9425 #else 9426 static inline void hdd_ndp_state_cleanup(struct wlan_objmgr_psoc * psoc,uint8_t ndi_vdev_id)9427 hdd_ndp_state_cleanup(struct wlan_objmgr_psoc *psoc, uint8_t ndi_vdev_id) 9428 { 9429 } 9430 9431 static inline void hdd_ndp_peer_cleanup(struct hdd_context * hdd_ctx,struct hdd_adapter * adapter)9432 hdd_ndp_peer_cleanup(struct hdd_context *hdd_ctx, struct hdd_adapter *adapter) 9433 { 9434 } 9435 hdd_peer_cleanup(struct wlan_hdd_link_info * link_info)9436 static inline void hdd_peer_cleanup(struct wlan_hdd_link_info *link_info) 9437 { 9438 } 9439 #endif /* WLAN_FEATURE_NAN */ 9440 9441 #ifdef FUNC_CALL_MAP 9442 9443 /** 9444 * hdd_dump_func_call_map() - Dump the function call map 9445 * 9446 * Return: None 9447 */ 9448 hdd_dump_func_call_map(void)9449 static void hdd_dump_func_call_map(void) 9450 { 9451 char *cc_buf; 9452 9453 cc_buf = qdf_mem_malloc(QDF_FUNCTION_CALL_MAP_BUF_LEN); 9454 /* 9455 * These logs are required as these indicates the start and end of the 9456 * dump for the auto script to parse 9457 */ 9458 hdd_info("Function call map dump start"); 9459 qdf_get_func_call_map(cc_buf); 9460 qdf_trace_hex_dump(QDF_MODULE_ID_HDD, 9461 QDF_TRACE_LEVEL_DEBUG, cc_buf, QDF_FUNCTION_CALL_MAP_BUF_LEN); 9462 hdd_info("Function call map dump end"); 9463 qdf_mem_free(cc_buf); 9464 } 9465 #else hdd_dump_func_call_map(void)9466 static inline void hdd_dump_func_call_map(void) 9467 { 9468 } 9469 #endif 9470 hdd_reset_scan_operation(struct wlan_hdd_link_info * link_info)9471 static void hdd_reset_scan_operation(struct wlan_hdd_link_info *link_info) 9472 { 9473 switch (link_info->adapter->device_mode) { 9474 case QDF_STA_MODE: 9475 case QDF_P2P_CLIENT_MODE: 9476 case QDF_P2P_DEVICE_MODE: 9477 case QDF_NDI_MODE: 9478 wlan_hdd_scan_abort(link_info); 9479 wlan_hdd_cleanup_remain_on_channel_ctx(link_info); 9480 if (link_info->adapter->device_mode == QDF_STA_MODE) { 9481 struct wlan_objmgr_vdev *vdev; 9482 9483 vdev = hdd_objmgr_get_vdev_by_user(link_info, 9484 WLAN_OSIF_SCAN_ID); 9485 if (!vdev) 9486 break; 9487 9488 wlan_cfg80211_sched_scan_stop(vdev); 9489 hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_SCAN_ID); 9490 } 9491 break; 9492 case QDF_P2P_GO_MODE: 9493 wlan_hdd_cleanup_remain_on_channel_ctx(link_info); 9494 break; 9495 case QDF_SAP_MODE: 9496 qdf_atomic_set(&link_info->session.ap.acs_in_progress, 0); 9497 break; 9498 default: 9499 break; 9500 } 9501 } 9502 9503 #ifdef WLAN_OPEN_SOURCE hdd_cancel_ip_notifier_work(struct hdd_adapter * adapter)9504 void hdd_cancel_ip_notifier_work(struct hdd_adapter *adapter) 9505 { 9506 cancel_work_sync(&adapter->ipv4_notifier_work); 9507 #ifdef WLAN_NS_OFFLOAD 9508 cancel_work_sync(&adapter->ipv6_notifier_work); 9509 #endif 9510 } 9511 #endif 9512 hdd_adapter_deregister_fc(struct hdd_adapter * adapter)9513 void hdd_adapter_deregister_fc(struct hdd_adapter *adapter) 9514 { 9515 hdd_deregister_hl_netdev_fc_timer(adapter); 9516 hdd_deregister_tx_flow_control(adapter); 9517 } 9518 hdd_stop_and_cleanup_ndi(struct wlan_hdd_link_info * link_info)9519 static void hdd_stop_and_cleanup_ndi(struct wlan_hdd_link_info *link_info) 9520 { 9521 QDF_STATUS status; 9522 unsigned long rc; 9523 struct hdd_adapter *adapter = link_info->adapter; 9524 struct hdd_context *hdd_ctx = adapter->hdd_ctx; 9525 9526 hdd_destroy_adapter_sysfs_files(adapter); 9527 /* For NDI do not use roam_profile */ 9528 INIT_COMPLETION(adapter->disconnect_comp_var); 9529 hdd_peer_cleanup(link_info); 9530 status = sme_roam_ndi_stop(hdd_ctx->mac_handle, link_info->vdev_id); 9531 if (QDF_IS_STATUS_SUCCESS(status)) { 9532 rc = wait_for_completion_timeout( 9533 &adapter->disconnect_comp_var, 9534 msecs_to_jiffies(SME_CMD_STOP_BSS_TIMEOUT)); 9535 if (!rc) 9536 hdd_warn("disconn_comp_var wait fail"); 9537 hdd_cleanup_ndi(link_info); 9538 } 9539 } 9540 9541 static void hdd_sta_disconnect_and_cleanup(struct wlan_hdd_link_info * link_info)9542 hdd_sta_disconnect_and_cleanup(struct wlan_hdd_link_info *link_info) 9543 { 9544 QDF_STATUS status; 9545 enum wlan_reason_code reason; 9546 struct hdd_adapter *adapter = link_info->adapter; 9547 9548 /* 9549 * On vdev delete wait for disconnect to 9550 * complete. i.e use sync API, so that the 9551 * vdev ref of MLME are cleaned and disconnect 9552 * complete before vdev is moved to logically 9553 * deleted. 9554 */ 9555 if (cds_is_driver_recovering()) 9556 reason = REASON_DEVICE_RECOVERY; 9557 else 9558 reason = REASON_IFACE_DOWN; 9559 9560 status = wlan_hdd_cm_issue_disconnect(link_info, reason, true); 9561 if (QDF_IS_STATUS_ERROR(status) && ucfg_ipa_is_enabled()) { 9562 hdd_err("STA disconnect failed"); 9563 ucfg_ipa_uc_cleanup_sta(adapter->hdd_ctx->pdev, adapter->dev, 9564 link_info->vdev_id); 9565 } 9566 } 9567 9568 static void hdd_disable_nan_active_disc(struct hdd_adapter * adapter)9569 hdd_disable_nan_active_disc(struct hdd_adapter *adapter) 9570 { 9571 struct hdd_context *hdd_ctx = adapter->hdd_ctx; 9572 enum QDF_OPMODE device_mode = adapter->device_mode; 9573 9574 if ((device_mode == QDF_NAN_DISC_MODE || 9575 (device_mode == QDF_STA_MODE && 9576 !ucfg_nan_is_vdev_creation_allowed(hdd_ctx->psoc))) && 9577 ucfg_is_nan_conc_control_supported(hdd_ctx->psoc) && 9578 ucfg_is_nan_disc_active(hdd_ctx->psoc)) 9579 ucfg_disable_nan_discovery(hdd_ctx->psoc, NULL, 0); 9580 } 9581 9582 static void hdd_monitor_mode_release_wakelock(struct wlan_hdd_link_info * link_info)9583 hdd_monitor_mode_release_wakelock(struct wlan_hdd_link_info *link_info) 9584 { 9585 struct hdd_adapter *adapter = link_info->adapter; 9586 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); 9587 9588 if (wlan_hdd_is_session_type_monitor(adapter->device_mode) && 9589 (ucfg_mlme_is_sta_mon_conc_supported(hdd_ctx->psoc) || 9590 ucfg_dp_is_local_pkt_capture_enabled(hdd_ctx->psoc))) { 9591 hdd_info("Release wakelock for STA + monitor mode!"); 9592 os_if_dp_local_pkt_capture_stop(link_info->vdev); 9593 qdf_runtime_pm_allow_suspend( 9594 &hdd_ctx->runtime_context.monitor_mode); 9595 hdd_lpc_enable_powersave(hdd_ctx); 9596 qdf_wake_lock_release(&hdd_ctx->monitor_mode_wakelock, 9597 WIFI_POWER_EVENT_WAKELOCK_MONITOR_MODE); 9598 } 9599 } 9600 9601 static void hdd_monitor_mode_disable_and_delete(struct wlan_hdd_link_info * link_info)9602 hdd_monitor_mode_disable_and_delete(struct wlan_hdd_link_info *link_info) 9603 { 9604 QDF_STATUS status; 9605 struct hdd_adapter *adapter = link_info->adapter; 9606 struct hdd_context *hdd_ctx = adapter->hdd_ctx; 9607 9608 status = hdd_disable_monitor_mode(); 9609 if (QDF_IS_STATUS_ERROR(status)) 9610 hdd_err_rl("datapath reset failed for montior mode"); 9611 hdd_set_idle_ps_config(hdd_ctx, true); 9612 status = hdd_monitor_mode_vdev_status(adapter); 9613 if (QDF_IS_STATUS_ERROR(status)) 9614 hdd_err_rl("stop failed montior mode"); 9615 sme_delete_mon_session(hdd_ctx->mac_handle, link_info->vdev_id); 9616 } 9617 9618 static void hdd_stop_and_close_pre_cac_adapter(struct hdd_context * hdd_ctx,struct wlan_objmgr_vdev * vdev)9619 hdd_stop_and_close_pre_cac_adapter(struct hdd_context *hdd_ctx, 9620 struct wlan_objmgr_vdev *vdev) 9621 { 9622 if (!vdev) 9623 return; 9624 9625 if (!ucfg_pre_cac_adapter_is_active(vdev)) { 9626 ucfg_pre_cac_stop(hdd_ctx->psoc); 9627 hdd_close_pre_cac_adapter(hdd_ctx); 9628 } else { 9629 if (ucfg_pre_cac_set_status(vdev, false)) 9630 hdd_err("Failed to set is_pre_cac_on to false"); 9631 } 9632 } 9633 hdd_reset_ies_on_sap_stop(struct wlan_hdd_link_info * link_info)9634 static void hdd_reset_ies_on_sap_stop(struct wlan_hdd_link_info *link_info) 9635 { 9636 mac_handle_t mac_handle; 9637 tSirUpdateIE update_ie; 9638 QDF_STATUS status; 9639 struct hdd_adapter *adapter = link_info->adapter; 9640 9641 mac_handle = hdd_adapter_get_mac_handle(adapter); 9642 update_ie.vdev_id = link_info->vdev_id; 9643 update_ie.ieBufferlength = 0; 9644 update_ie.pAdditionIEBuffer = NULL; 9645 update_ie.append = false; 9646 update_ie.notify = false; 9647 9648 /* Probe bcn reset */ 9649 status = sme_update_add_ie(mac_handle, &update_ie, 9650 eUPDATE_IE_PROBE_BCN); 9651 if (status == QDF_STATUS_E_FAILURE) 9652 hdd_err("Could not pass PROBE_RSP_BCN to PE"); 9653 9654 /* Assoc resp reset */ 9655 status = sme_update_add_ie(mac_handle, &update_ie, 9656 eUPDATE_IE_ASSOC_RESP); 9657 if (status == QDF_STATUS_E_FAILURE) 9658 hdd_err("Could not pass ASSOC_RSP to PE"); 9659 9660 /* Reset WNI_CFG_PROBE_RSP Flags */ 9661 wlan_hdd_reset_prob_rspies(link_info); 9662 } 9663 hdd_stop_station_adapter(struct hdd_adapter * adapter)9664 static void hdd_stop_station_adapter(struct hdd_adapter *adapter) 9665 { 9666 struct wlan_objmgr_vdev *vdev; 9667 enum QDF_OPMODE mode; 9668 struct wlan_hdd_link_info *link_info; 9669 9670 mode = adapter->device_mode; 9671 hdd_adapter_for_each_active_link_info(adapter, link_info) { 9672 vdev = hdd_objmgr_get_vdev_by_user(link_info, 9673 WLAN_INIT_DEINIT_ID); 9674 if (!vdev) 9675 continue; 9676 9677 if (mode == QDF_NDI_MODE) 9678 hdd_stop_and_cleanup_ndi(link_info); 9679 else if (!hdd_cm_is_disconnected(link_info)) 9680 hdd_sta_disconnect_and_cleanup(link_info); 9681 9682 hdd_reset_scan_operation(link_info); 9683 wlan_hdd_cleanup_actionframe(link_info); 9684 wlan_hdd_flush_pmksa_cache(link_info); 9685 9686 if (mode == QDF_STA_MODE) 9687 ucfg_ipa_flush_pending_vdev_events( 9688 wlan_vdev_get_pdev(vdev), 9689 link_info->vdev_id); 9690 hdd_objmgr_put_vdev_by_user(vdev, WLAN_INIT_DEINIT_ID); 9691 hdd_vdev_destroy(link_info); 9692 } 9693 9694 hdd_disable_nan_active_disc(adapter); 9695 hdd_adapter_deregister_fc(adapter); 9696 hdd_cancel_ip_notifier_work(adapter); 9697 } 9698 hdd_stop_mon_adapter(struct hdd_adapter * adapter)9699 static int hdd_stop_mon_adapter(struct hdd_adapter *adapter) 9700 { 9701 struct wlan_objmgr_vdev *vdev; 9702 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); 9703 struct wlan_hdd_link_info *link_info = adapter->deflink; 9704 9705 vdev = hdd_objmgr_get_vdev_by_user(link_info, 9706 WLAN_INIT_DEINIT_ID); 9707 if (wlan_hdd_is_session_type_monitor(adapter->device_mode) && 9708 vdev && 9709 ucfg_pkt_capture_get_mode(hdd_ctx->psoc) != 9710 PACKET_CAPTURE_MODE_DISABLE) { 9711 struct hdd_adapter *sta_adapter; 9712 9713 ucfg_pkt_capture_deregister_callbacks(vdev); 9714 hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_ID); 9715 link_info->vdev = NULL; 9716 9717 sta_adapter = hdd_get_adapter(hdd_ctx, QDF_STA_MODE); 9718 if (!sta_adapter) { 9719 hdd_objmgr_put_vdev_by_user(vdev, WLAN_INIT_DEINIT_ID); 9720 hdd_err("No station interface found"); 9721 return -EINVAL; 9722 } 9723 hdd_reset_monitor_interface(sta_adapter); 9724 } 9725 9726 hdd_monitor_mode_release_wakelock(link_info); 9727 wlan_hdd_scan_abort(link_info); 9728 hdd_adapter_deregister_fc(adapter); 9729 hdd_monitor_mode_disable_and_delete(link_info); 9730 if (vdev) 9731 hdd_objmgr_put_vdev_by_user(vdev, WLAN_INIT_DEINIT_ID); 9732 9733 hdd_vdev_destroy(link_info); 9734 9735 return 0; 9736 } 9737 hdd_stop_sap_go_adapter(struct hdd_adapter * adapter)9738 static void hdd_stop_sap_go_adapter(struct hdd_adapter *adapter) 9739 { 9740 enum QDF_OPMODE mode; 9741 struct hdd_ap_ctx *ap_ctx; 9742 struct sap_context *sap_ctx; 9743 struct sap_config *sap_config; 9744 struct hdd_hostapd_state *hostapd_state; 9745 struct wlan_objmgr_vdev *vdev; 9746 struct wlan_hdd_link_info *link_info = adapter->deflink; 9747 QDF_STATUS status = QDF_STATUS_SUCCESS; 9748 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); 9749 uint8_t link_id; 9750 9751 mode = adapter->device_mode; 9752 ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(link_info); 9753 sap_ctx = WLAN_HDD_GET_SAP_CTX_PTR(link_info); 9754 vdev = hdd_objmgr_get_vdev_by_user(link_info, WLAN_INIT_DEINIT_ID); 9755 9756 if (mode == QDF_SAP_MODE) { 9757 wlan_hdd_scan_abort(link_info); 9758 hdd_abort_ongoing_sta_connection(hdd_ctx); 9759 /* Diassociate with all the peers before stop ap post */ 9760 if (test_bit(SOFTAP_BSS_STARTED, &link_info->link_flags)) { 9761 if (wlan_hdd_del_station(adapter, NULL)) 9762 hdd_sap_indicate_disconnect_for_sta(adapter); 9763 } 9764 wlan_hdd_flush_pmksa_cache(link_info); 9765 sap_config = &ap_ctx->sap_config; 9766 wlansap_reset_sap_config_add_ie(sap_config, eUPDATE_IE_ALL); 9767 hdd_stop_and_close_pre_cac_adapter(hdd_ctx, vdev); 9768 } 9769 wlansap_cleanup_cac_timer(sap_ctx); 9770 cds_flush_work(&adapter->sap_stop_bss_work); 9771 9772 if (qdf_atomic_read(&ap_ctx->acs_in_progress)) { 9773 hdd_info("ACS in progress, wait for complete"); 9774 qdf_wait_for_event_completion(&link_info->acs_complete_event, 9775 ACS_COMPLETE_TIMEOUT); 9776 } 9777 9778 if (mode == QDF_P2P_GO_MODE) { 9779 wlan_hdd_cleanup_remain_on_channel_ctx(link_info); 9780 hdd_abort_ongoing_sta_connection(hdd_ctx); 9781 } 9782 9783 hdd_adapter_deregister_fc(adapter); 9784 hdd_destroy_acs_timer(adapter); 9785 9786 mutex_lock(&hdd_ctx->sap_lock); 9787 if (test_bit(SOFTAP_BSS_STARTED, &link_info->link_flags)) { 9788 hostapd_state = WLAN_HDD_GET_HOSTAP_STATE_PTR(link_info); 9789 qdf_event_reset(&hostapd_state->qdf_stop_bss_event); 9790 status = wlansap_stop_bss(ap_ctx->sap_context); 9791 if (QDF_IS_STATUS_SUCCESS(status)) { 9792 status = qdf_wait_single_event(&hostapd_state->qdf_stop_bss_event, 9793 SME_CMD_STOP_BSS_TIMEOUT); 9794 if (QDF_IS_STATUS_ERROR(status)) { 9795 hdd_err("failure waiting for wlansap_stop_bss %d", 9796 status); 9797 hdd_ipa_ap_disconnect_evt(hdd_ctx, adapter); 9798 } 9799 } else { 9800 hdd_err("failure in wlansap_stop_bss"); 9801 } 9802 9803 clear_bit(SOFTAP_BSS_STARTED, &link_info->link_flags); 9804 policy_mgr_decr_session_set_pcl(hdd_ctx->psoc, 9805 adapter->device_mode, 9806 link_info->vdev_id); 9807 hdd_green_ap_start_state_mc(hdd_ctx, adapter->device_mode, 9808 false); 9809 9810 hdd_reset_ies_on_sap_stop(link_info); 9811 } 9812 9813 /* 9814 * Note to restart sap after SSR driver needs below information 9815 * and is not cleared/freed on purpose in case of SAP SSR 9816 */ 9817 if (!cds_is_driver_recovering()) { 9818 clear_bit(SOFTAP_INIT_DONE, &link_info->link_flags); 9819 qdf_mem_free(ap_ctx->beacon); 9820 ap_ctx->beacon = NULL; 9821 9822 if (vdev) { 9823 link_id = wlan_vdev_get_link_id(vdev); 9824 ucfg_crypto_free_key_by_link_id(hdd_ctx->psoc, 9825 &link_info->link_addr, 9826 link_id); 9827 } 9828 } 9829 /* Clear all the cached sta info */ 9830 hdd_clear_cached_sta_info(adapter); 9831 9832 if (vdev && policy_mgr_is_dnsc_set(vdev)) 9833 wlan_hdd_send_avoid_freq_for_dnbs(hdd_ctx, 0); 9834 9835 hdd_cancel_ip_notifier_work(adapter); 9836 sap_release_vdev_ref(sap_ctx); 9837 9838 if (mode == QDF_SAP_MODE) 9839 ucfg_ipa_flush_pending_vdev_events(hdd_ctx->pdev, 9840 link_info->vdev_id); 9841 if (vdev) 9842 hdd_objmgr_put_vdev_by_user(vdev, WLAN_INIT_DEINIT_ID); 9843 hdd_vdev_destroy(link_info); 9844 mutex_unlock(&hdd_ctx->sap_lock); 9845 ucfg_ipa_flush(hdd_ctx->pdev); 9846 } 9847 hdd_stop_ocb_adapter(struct hdd_adapter * adapter)9848 static void hdd_stop_ocb_adapter(struct hdd_adapter *adapter) 9849 { 9850 struct hdd_station_ctx *sta_ctx; 9851 struct wlan_objmgr_vdev *vdev; 9852 struct wlan_hdd_link_info *link_info = adapter->deflink; 9853 9854 vdev = hdd_objmgr_get_vdev_by_user(link_info, WLAN_INIT_DEINIT_ID); 9855 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(link_info); 9856 cdp_clear_peer(cds_get_context(QDF_MODULE_ID_SOC), OL_TXRX_PDEV_ID, 9857 sta_ctx->conn_info.peer_macaddr[0]); 9858 hdd_adapter_deregister_fc(adapter); 9859 if (vdev) 9860 hdd_objmgr_put_vdev_by_user(vdev, WLAN_INIT_DEINIT_ID); 9861 hdd_vdev_destroy(link_info); 9862 } 9863 hdd_stop_adapter_ext(struct hdd_context * hdd_ctx,struct hdd_adapter * adapter)9864 QDF_STATUS hdd_stop_adapter_ext(struct hdd_context *hdd_ctx, 9865 struct hdd_adapter *adapter) 9866 { 9867 QDF_STATUS status; 9868 struct wlan_hdd_link_info *link_info = adapter->deflink; 9869 9870 hdd_enter(); 9871 hdd_destroy_adapter_sysfs_files(adapter); 9872 9873 if (adapter->device_mode == QDF_STA_MODE && 9874 hdd_is_pkt_capture_mon_enable(adapter) && 9875 ucfg_pkt_capture_get_mode(hdd_ctx->psoc) != 9876 PACKET_CAPTURE_MODE_DISABLE) { 9877 hdd_unmap_monitor_interface_vdev(adapter); 9878 } 9879 9880 if (link_info->vdev_id != WLAN_UMAC_VDEV_ID_MAX) 9881 wlan_hdd_cfg80211_deregister_frames(adapter); 9882 9883 hdd_stop_tsf_sync(adapter); 9884 cds_flush_work(&adapter->scan_block_work); 9885 wlan_hdd_cfg80211_scan_block(adapter); 9886 hdd_debug("Disabling queues"); 9887 wlan_hdd_netif_queue_control(adapter, 9888 WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER, 9889 WLAN_CONTROL_PATH); 9890 9891 switch (adapter->device_mode) { 9892 case QDF_STA_MODE: 9893 case QDF_P2P_CLIENT_MODE: 9894 case QDF_NDI_MODE: 9895 case QDF_P2P_DEVICE_MODE: 9896 case QDF_NAN_DISC_MODE: 9897 hdd_stop_station_adapter(adapter); 9898 break; 9899 case QDF_MONITOR_MODE: 9900 status = hdd_stop_mon_adapter(adapter); 9901 if (QDF_IS_STATUS_ERROR(status)) 9902 return status; 9903 9904 break; 9905 case QDF_SAP_MODE: 9906 case QDF_P2P_GO_MODE: 9907 hdd_stop_sap_go_adapter(adapter); 9908 break; 9909 case QDF_OCB_MODE: 9910 hdd_stop_ocb_adapter(adapter); 9911 break; 9912 default: 9913 break; 9914 } 9915 9916 /* Moved from vdev destroy as it is per adapter */ 9917 wlan_cfg80211_cleanup_scan_queue(hdd_ctx->pdev, adapter->dev); 9918 9919 /* Disable all links (expect default index) in adapter. 9920 * Set link address to NULL 9921 */ 9922 hdd_adapter_disable_all_links(adapter, true); 9923 9924 /* This function should be invoked at the end of this api*/ 9925 hdd_dump_func_call_map(); 9926 hdd_exit(); 9927 9928 return QDF_STATUS_SUCCESS; 9929 } 9930 hdd_stop_adapter(struct hdd_context * hdd_ctx,struct hdd_adapter * adapter)9931 QDF_STATUS hdd_stop_adapter(struct hdd_context *hdd_ctx, 9932 struct hdd_adapter *adapter) 9933 { 9934 QDF_STATUS status; 9935 9936 if (adapter->device_mode == QDF_STA_MODE) 9937 status = hdd_stop_link_adapter(hdd_ctx, adapter); 9938 9939 status = hdd_stop_adapter_ext(hdd_ctx, adapter); 9940 9941 return status; 9942 } 9943 9944 /** 9945 * hdd_deinit_all_adapters - deinit all adapters 9946 * @hdd_ctx: HDD context 9947 * @rtnl_held: True if RTNL lock held 9948 * 9949 */ hdd_deinit_all_adapters(struct hdd_context * hdd_ctx,bool rtnl_held)9950 void hdd_deinit_all_adapters(struct hdd_context *hdd_ctx, bool rtnl_held) 9951 { 9952 struct hdd_adapter *adapter, *next_adapter = NULL; 9953 9954 hdd_enter(); 9955 9956 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 9957 NET_DEV_HOLD_DEINIT_ALL_ADAPTERS) { 9958 hdd_deinit_adapter(hdd_ctx, adapter, rtnl_held); 9959 hdd_adapter_dev_put_debug(adapter, 9960 NET_DEV_HOLD_DEINIT_ALL_ADAPTERS); 9961 } 9962 9963 hdd_exit(); 9964 } 9965 hdd_stop_all_adapters(struct hdd_context * hdd_ctx)9966 QDF_STATUS hdd_stop_all_adapters(struct hdd_context *hdd_ctx) 9967 { 9968 struct hdd_adapter *adapter, *next_adapter = NULL; 9969 9970 hdd_enter(); 9971 9972 ucfg_pre_cac_stop(hdd_ctx->psoc); 9973 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 9974 NET_DEV_HOLD_STOP_ALL_ADAPTERS) { 9975 hdd_stop_adapter(hdd_ctx, adapter); 9976 hdd_adapter_dev_put_debug(adapter, 9977 NET_DEV_HOLD_STOP_ALL_ADAPTERS); 9978 } 9979 9980 hdd_exit(); 9981 9982 return QDF_STATUS_SUCCESS; 9983 } 9984 hdd_set_netdev_flags(struct hdd_adapter * adapter)9985 void hdd_set_netdev_flags(struct hdd_adapter *adapter) 9986 { 9987 bool enable_csum = false; 9988 bool enable_lro; 9989 enum QDF_OPMODE device_mode; 9990 struct hdd_context *hdd_ctx; 9991 ol_txrx_soc_handle soc; 9992 uint64_t temp; 9993 9994 if (!adapter || !adapter->dev) { 9995 hdd_err("invalid input!"); 9996 return; 9997 } 9998 device_mode = adapter->device_mode; 9999 10000 hdd_ctx = adapter->hdd_ctx; 10001 soc = cds_get_context(QDF_MODULE_ID_SOC); 10002 10003 if (!soc || !hdd_ctx) { 10004 hdd_err("invalid SOC or HDD context!"); 10005 return; 10006 } 10007 10008 /* Determine device_mode specific configuration */ 10009 10010 enable_lro = !!cdp_cfg_get(soc, cfg_dp_lro_enable); 10011 enable_csum = !!cdp_cfg_get(soc, 10012 cfg_dp_enable_ip_tcp_udp_checksum_offload); 10013 switch (device_mode) { 10014 case QDF_P2P_DEVICE_MODE: 10015 case QDF_P2P_CLIENT_MODE: 10016 enable_csum = !!cdp_cfg_get(soc, 10017 cfg_dp_enable_p2p_ip_tcp_udp_checksum_offload); 10018 break; 10019 case QDF_P2P_GO_MODE: 10020 enable_csum = !!cdp_cfg_get(soc, 10021 cfg_dp_enable_p2p_ip_tcp_udp_checksum_offload); 10022 enable_lro = false; 10023 break; 10024 case QDF_SAP_MODE: 10025 enable_lro = false; 10026 break; 10027 case QDF_NDI_MODE: 10028 case QDF_NAN_DISC_MODE: 10029 enable_csum = !!cdp_cfg_get(soc, 10030 cfg_dp_enable_nan_ip_tcp_udp_checksum_offload); 10031 break; 10032 default: 10033 break; 10034 } 10035 10036 /* Set netdev flags */ 10037 10038 /* 10039 * In case of USB tethering, LRO is disabled. If SSR happened 10040 * during that time, then as part of SSR init, do not enable 10041 * the LRO again. Keep the LRO state same as before SSR. 10042 */ 10043 if (enable_lro && !(qdf_atomic_read(&hdd_ctx->vendor_disable_lro_flag))) 10044 adapter->dev->features |= NETIF_F_LRO; 10045 10046 if (enable_csum) 10047 adapter->dev->features |= 10048 (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM); 10049 10050 if (cdp_cfg_get(soc, cfg_dp_tso_enable) && enable_csum) { 10051 adapter->dev->features |= TSO_FEATURE_FLAGS; 10052 adapter->tso_csum_feature_enabled = 1; 10053 } 10054 10055 if (cdp_cfg_get(soc, cfg_dp_sg_enable)) 10056 adapter->dev->features |= NETIF_F_SG; 10057 10058 adapter->dev->features |= NETIF_F_RXCSUM; 10059 temp = (uint64_t)adapter->dev->features; 10060 10061 hdd_debug("adapter mode %u dev feature 0x%llx", device_mode, temp); 10062 } 10063 10064 #ifdef QCA_LL_LEGACY_TX_FLOW_CONTROL 10065 /** 10066 * hdd_adapter_abort_tx_flow() - Abort the tx flow control 10067 * @adapter: pointer to hdd adapter 10068 * 10069 * Resume tx and stop the tx flow control timer if the tx is paused 10070 * and the flow control timer is running. This function is called by 10071 * SSR to avoid the inconsistency of tx status before and after SSR. 10072 * 10073 * Return: void 10074 */ hdd_adapter_abort_tx_flow(struct hdd_adapter * adapter)10075 static void hdd_adapter_abort_tx_flow(struct hdd_adapter *adapter) 10076 { 10077 if (adapter->deflink->hdd_stats.tx_rx_stats.is_txflow_paused && 10078 QDF_TIMER_STATE_RUNNING == 10079 qdf_mc_timer_get_current_state( 10080 &adapter->tx_flow_control_timer)) { 10081 hdd_tx_resume_timer_expired_handler(adapter); 10082 qdf_mc_timer_stop(&adapter->tx_flow_control_timer); 10083 } 10084 } 10085 #else hdd_adapter_abort_tx_flow(struct hdd_adapter * adapter)10086 static void hdd_adapter_abort_tx_flow(struct hdd_adapter *adapter) 10087 { 10088 } 10089 #endif 10090 hdd_reset_all_adapters(struct hdd_context * hdd_ctx)10091 QDF_STATUS hdd_reset_all_adapters(struct hdd_context *hdd_ctx) 10092 { 10093 struct hdd_adapter *adapter, *next_adapter = NULL; 10094 bool value; 10095 struct wlan_objmgr_vdev *vdev; 10096 struct wlan_hdd_link_info *link_info; 10097 10098 hdd_enter(); 10099 10100 ucfg_mlme_get_sap_internal_restart(hdd_ctx->psoc, &value); 10101 10102 10103 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 10104 NET_DEV_HOLD_RESET_ALL_ADAPTERS) { 10105 hdd_info("[SSR] reset adapter with device mode %s(%d)", 10106 qdf_opmode_str(adapter->device_mode), 10107 adapter->device_mode); 10108 10109 hdd_adapter_for_each_active_link_info(adapter, link_info) { 10110 hdd_adapter_abort_tx_flow(adapter); 10111 10112 if ((adapter->device_mode == QDF_STA_MODE) || 10113 (adapter->device_mode == QDF_P2P_CLIENT_MODE)) { 10114 hdd_send_twt_del_all_sessions_to_userspace(link_info); 10115 10116 /* Stop tdls timers */ 10117 vdev = hdd_objmgr_get_vdev_by_user(link_info, 10118 WLAN_OSIF_TDLS_ID); 10119 if (vdev) { 10120 hdd_notify_tdls_reset_adapter(vdev); 10121 hdd_objmgr_put_vdev_by_user(vdev, 10122 WLAN_OSIF_TDLS_ID); 10123 } 10124 } 10125 10126 if (value && 10127 adapter->device_mode == QDF_SAP_MODE) { 10128 hdd_medium_assess_ssr_enable_flag(); 10129 wlan_hdd_netif_queue_control(adapter, 10130 WLAN_STOP_ALL_NETIF_QUEUE, 10131 WLAN_CONTROL_PATH); 10132 } else { 10133 wlan_hdd_netif_queue_control(adapter, 10134 WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER, 10135 WLAN_CONTROL_PATH); 10136 } 10137 10138 /* 10139 * Clear fc flag if it was set before SSR to avoid 10140 * TX queues permanently stopped after SSR. 10141 * Here WLAN_START_ALL_NETIF_QUEUE will actually 10142 * not start any queue since it's blocked by reason 10143 * WLAN_CONTROL_PATH. 10144 */ 10145 if (adapter->pause_map & (1 << WLAN_DATA_FLOW_CONTROL)) 10146 wlan_hdd_netif_queue_control(adapter, 10147 WLAN_START_ALL_NETIF_QUEUE, 10148 WLAN_DATA_FLOW_CONTROL); 10149 10150 hdd_reset_scan_operation(link_info); 10151 if (test_bit(WMM_INIT_DONE, &adapter->event_flags)) { 10152 hdd_wmm_adapter_close(adapter); 10153 clear_bit(WMM_INIT_DONE, &adapter->event_flags); 10154 } 10155 10156 hdd_debug("Flush any mgmt references held by peer"); 10157 hdd_stop_adapter(hdd_ctx, adapter); 10158 } 10159 hdd_adapter_dev_put_debug(adapter, 10160 NET_DEV_HOLD_RESET_ALL_ADAPTERS); 10161 } 10162 10163 hdd_exit(); 10164 10165 return QDF_STATUS_SUCCESS; 10166 } 10167 hdd_is_any_link_opened(struct hdd_adapter * adapter)10168 static bool hdd_is_any_link_opened(struct hdd_adapter *adapter) 10169 { 10170 struct wlan_hdd_link_info *link_info; 10171 10172 hdd_adapter_for_each_active_link_info(adapter, link_info) { 10173 if (test_bit(SME_SESSION_OPENED, &link_info->link_flags)) 10174 return true; 10175 } 10176 return false; 10177 } 10178 hdd_is_any_interface_open(struct hdd_context * hdd_ctx)10179 bool hdd_is_any_interface_open(struct hdd_context *hdd_ctx) 10180 { 10181 struct hdd_adapter *adapter, *next_adapter = NULL; 10182 wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_IS_ANY_INTERFACE_OPEN; 10183 10184 if (hdd_get_conparam() == QDF_GLOBAL_FTM_MODE) { 10185 hdd_info("FTM mode, don't close the module"); 10186 return true; 10187 } 10188 10189 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 10190 dbgid) { 10191 if (test_bit(DEVICE_IFACE_OPENED, &adapter->event_flags) || 10192 hdd_is_any_link_opened(adapter)) { 10193 hdd_adapter_dev_put_debug(adapter, dbgid); 10194 if (next_adapter) 10195 hdd_adapter_dev_put_debug(next_adapter, dbgid); 10196 return true; 10197 } 10198 hdd_adapter_dev_put_debug(adapter, dbgid); 10199 } 10200 10201 return false; 10202 } 10203 hdd_is_interface_up(struct hdd_adapter * adapter)10204 bool hdd_is_interface_up(struct hdd_adapter *adapter) 10205 { 10206 if (test_bit(DEVICE_IFACE_OPENED, &adapter->event_flags)) 10207 return true; 10208 else 10209 return false; 10210 } 10211 10212 #ifdef FEATURE_MONITOR_MODE_SUPPORT 10213 #ifdef WLAN_FEATURE_11BE wlan_hdd_is_mon_channel_bw_valid(enum phy_ch_width ch_width)10214 static inline bool wlan_hdd_is_mon_channel_bw_valid(enum phy_ch_width ch_width) 10215 { 10216 if (ch_width > CH_WIDTH_320MHZ || 10217 (!cds_is_sub_20_mhz_enabled() && (ch_width == CH_WIDTH_5MHZ || 10218 ch_width == CH_WIDTH_10MHZ))) 10219 return false; 10220 10221 return true; 10222 } 10223 #else wlan_hdd_is_mon_channel_bw_valid(enum phy_ch_width ch_width)10224 static inline bool wlan_hdd_is_mon_channel_bw_valid(enum phy_ch_width ch_width) 10225 { 10226 if (ch_width > CH_WIDTH_10MHZ || 10227 (!cds_is_sub_20_mhz_enabled() && (ch_width == CH_WIDTH_5MHZ || 10228 ch_width == CH_WIDTH_10MHZ))) 10229 return false; 10230 10231 return true; 10232 } 10233 #endif 10234 wlan_hdd_set_mon_chan(struct hdd_adapter * adapter,qdf_freq_t freq,uint32_t bandwidth)10235 int wlan_hdd_set_mon_chan(struct hdd_adapter *adapter, qdf_freq_t freq, 10236 uint32_t bandwidth) 10237 { 10238 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); 10239 struct hdd_station_ctx *sta_ctx; 10240 struct hdd_mon_set_ch_info *ch_info; 10241 QDF_STATUS status; 10242 struct qdf_mac_addr bssid; 10243 struct channel_change_req *req; 10244 struct ch_params ch_params; 10245 enum phy_ch_width max_fw_bw; 10246 enum phy_ch_width ch_width; 10247 int ret; 10248 10249 if ((hdd_get_conparam() != QDF_GLOBAL_MONITOR_MODE) && 10250 (!policy_mgr_is_sta_mon_concurrency(hdd_ctx->psoc))) { 10251 hdd_err("Not supported, device is not in monitor mode"); 10252 return -EINVAL; 10253 } 10254 10255 if (adapter->device_mode != QDF_MONITOR_MODE) { 10256 hdd_err_rl("Not supported, adapter is not in monitor mode"); 10257 return -EINVAL; 10258 } 10259 10260 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter->deflink); 10261 ch_info = &sta_ctx->ch_info; 10262 10263 /* Verify the BW before accepting this request */ 10264 ch_width = bandwidth; 10265 10266 if (!wlan_hdd_is_mon_channel_bw_valid(ch_width)) { 10267 hdd_err("invalid BW received %d", ch_width); 10268 return -EINVAL; 10269 } 10270 10271 max_fw_bw = sme_get_vht_ch_width(); 10272 10273 hdd_debug("max fw BW %d ch width %d", max_fw_bw, ch_width); 10274 if ((ch_width == CH_WIDTH_160MHZ && 10275 max_fw_bw <= WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ) || 10276 (ch_width == CH_WIDTH_80P80MHZ && 10277 max_fw_bw <= WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ)) { 10278 hdd_err("FW does not support this BW %d max BW supported %d", 10279 ch_width, max_fw_bw); 10280 return -EINVAL; 10281 } 10282 10283 if (!hdd_is_target_eht_phy_ch_width_supported(ch_width)) 10284 return -EINVAL; 10285 10286 ret = hdd_validate_channel_and_bandwidth(adapter, freq, bandwidth); 10287 if (ret) { 10288 hdd_err("Invalid CH and BW combo"); 10289 return ret; 10290 } 10291 10292 hdd_debug("Set monitor mode frequency %d", freq); 10293 qdf_mem_copy(bssid.bytes, adapter->mac_addr.bytes, 10294 QDF_MAC_ADDR_SIZE); 10295 10296 ch_params.ch_width = bandwidth; 10297 wlan_reg_set_channel_params_for_pwrmode(hdd_ctx->pdev, freq, 0, 10298 &ch_params, 10299 REG_CURRENT_PWR_MODE); 10300 10301 if (ch_params.ch_width == CH_WIDTH_INVALID) { 10302 hdd_err("Invalid capture channel or bandwidth for a country"); 10303 return -EINVAL; 10304 } 10305 if (wlan_hdd_change_hw_mode_for_given_chnl(adapter, freq, 10306 POLICY_MGR_UPDATE_REASON_SET_OPER_CHAN)) { 10307 hdd_err("Failed to change hw mode"); 10308 return -EINVAL; 10309 } 10310 10311 if (adapter->monitor_mode_vdev_up_in_progress) { 10312 hdd_err_rl("monitor mode vdev up in progress"); 10313 return -EBUSY; 10314 } 10315 10316 status = qdf_event_reset(&adapter->qdf_monitor_mode_vdev_up_event); 10317 if (QDF_IS_STATUS_ERROR(status)) { 10318 hdd_err_rl("failed to reinit monitor mode vdev up event"); 10319 return qdf_status_to_os_return(status); 10320 } 10321 adapter->monitor_mode_vdev_up_in_progress = true; 10322 10323 qdf_mem_zero(&ch_params, sizeof(struct ch_params)); 10324 10325 req = qdf_mem_malloc(sizeof(struct channel_change_req)); 10326 if (!req) 10327 return -ENOMEM; 10328 req->vdev_id = adapter->deflink->vdev_id; 10329 req->target_chan_freq = freq; 10330 req->ch_width = ch_width; 10331 10332 ch_params.ch_width = ch_width; 10333 hdd_select_cbmode(adapter, freq, 0, &ch_params); 10334 10335 req->sec_ch_offset = ch_params.sec_ch_offset; 10336 req->center_freq_seg0 = ch_params.center_freq_seg0; 10337 req->center_freq_seg1 = ch_params.center_freq_seg1; 10338 10339 sme_fill_channel_change_request(hdd_ctx->mac_handle, req, 10340 ch_info->phy_mode); 10341 status = sme_send_channel_change_req(hdd_ctx->mac_handle, req); 10342 qdf_mem_free(req); 10343 if (status) { 10344 hdd_err("Status: %d Failed to set sme_roam Channel for monitor mode", 10345 status); 10346 adapter->monitor_mode_vdev_up_in_progress = false; 10347 return qdf_status_to_os_return(status); 10348 } 10349 10350 adapter->mon_chan_freq = freq; 10351 adapter->mon_bandwidth = bandwidth; 10352 10353 /* block on a completion variable until vdev up success*/ 10354 status = qdf_wait_for_event_completion( 10355 &adapter->qdf_monitor_mode_vdev_up_event, 10356 WLAN_MONITOR_MODE_VDEV_UP_EVT); 10357 if (QDF_IS_STATUS_ERROR(status)) { 10358 hdd_err_rl("monitor vdev up event time out vdev id: %d", 10359 adapter->deflink->vdev_id); 10360 if (adapter->qdf_monitor_mode_vdev_up_event.force_set) 10361 /* 10362 * SSR/PDR has caused shutdown, which has 10363 * forcefully set the event. 10364 */ 10365 hdd_err_rl("monitor mode vdev up event forcefully set"); 10366 else if (status == QDF_STATUS_E_TIMEOUT) 10367 hdd_err("monitor mode vdev up timed out"); 10368 else 10369 hdd_err_rl("Failed monitor mode vdev up(status-%d)", 10370 status); 10371 10372 adapter->monitor_mode_vdev_up_in_progress = false; 10373 } 10374 10375 return qdf_status_to_os_return(status); 10376 } 10377 #endif 10378 10379 #if defined MSM_PLATFORM && (LINUX_VERSION_CODE <= KERNEL_VERSION(4, 19, 0)) 10380 /** 10381 * hdd_stop_p2p_go() - call cfg80211 API to stop P2P GO 10382 * @adapter: pointer to adapter 10383 * 10384 * This function calls cfg80211 API to stop P2P GO 10385 * 10386 * Return: None 10387 */ hdd_stop_p2p_go(struct hdd_adapter * adapter)10388 static void hdd_stop_p2p_go(struct hdd_adapter *adapter) 10389 { 10390 hdd_debug("[SSR] send stop ap to supplicant"); 10391 cfg80211_ap_stopped(adapter->dev, GFP_KERNEL); 10392 } 10393 hdd_delete_sta(struct hdd_adapter * adapter)10394 static inline void hdd_delete_sta(struct hdd_adapter *adapter) 10395 { 10396 } 10397 10398 #else hdd_stop_p2p_go(struct hdd_adapter * adapter)10399 static void hdd_stop_p2p_go(struct hdd_adapter *adapter) 10400 { 10401 hdd_debug("[SSR] send stop iface ap to supplicant"); 10402 cfg80211_stop_iface(adapter->hdd_ctx->wiphy, &adapter->wdev, 10403 GFP_KERNEL); 10404 } 10405 10406 /** 10407 * hdd_delete_sta() - call cfg80211 API to delete STA 10408 * @adapter: pointer to adapter 10409 * 10410 * This function calls cfg80211 API to delete STA 10411 * 10412 * Return: None 10413 */ hdd_delete_sta(struct hdd_adapter * adapter)10414 static void hdd_delete_sta(struct hdd_adapter *adapter) 10415 { 10416 struct qdf_mac_addr bcast_mac = QDF_MAC_ADDR_BCAST_INIT; 10417 10418 hdd_debug("[SSR] send restart supplicant"); 10419 /* event supplicant to restart */ 10420 cfg80211_del_sta(adapter->dev, 10421 (const u8 *)&bcast_mac.bytes[0], 10422 GFP_KERNEL); 10423 } 10424 #endif 10425 hdd_start_all_adapters(struct hdd_context * hdd_ctx,bool rtnl_held)10426 QDF_STATUS hdd_start_all_adapters(struct hdd_context *hdd_ctx, bool rtnl_held) 10427 { 10428 struct hdd_adapter *adapter, *next_adapter = NULL; 10429 bool value; 10430 wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_START_ALL_ADAPTERS; 10431 int ret; 10432 10433 hdd_enter(); 10434 10435 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 10436 dbgid) { 10437 if (!hdd_is_interface_up(adapter) && 10438 adapter->device_mode != QDF_NDI_MODE) { 10439 hdd_adapter_dev_put_debug(adapter, dbgid); 10440 continue; 10441 } 10442 10443 hdd_debug("[SSR] start adapter with device mode %s(%d)", 10444 qdf_opmode_str(adapter->device_mode), 10445 adapter->device_mode); 10446 10447 hdd_wmm_dscp_initial_state(adapter); 10448 10449 switch (adapter->device_mode) { 10450 case QDF_STA_MODE: 10451 case QDF_P2P_CLIENT_MODE: 10452 case QDF_P2P_DEVICE_MODE: 10453 case QDF_NAN_DISC_MODE: 10454 10455 ret = hdd_start_station_adapter(adapter); 10456 if (ret) { 10457 hdd_err("[SSR] Failed to start station adapter: %d", 10458 ret); 10459 hdd_adapter_dev_put_debug(adapter, dbgid); 10460 continue; 10461 } 10462 if (adapter->device_mode == QDF_STA_MODE) { 10463 ret = hdd_start_link_adapter(adapter); 10464 if (ret) { 10465 hdd_err("[SSR] Failed to start link adapter: %d", 10466 ret); 10467 hdd_stop_adapter(hdd_ctx, adapter); 10468 hdd_adapter_dev_put_debug(adapter, 10469 dbgid); 10470 continue; 10471 } 10472 } 10473 10474 /* Open the gates for HDD to receive Wext commands */ 10475 adapter->is_link_up_service_needed = false; 10476 10477 if ((adapter->device_mode == QDF_NAN_DISC_MODE || 10478 (adapter->device_mode == QDF_STA_MODE && 10479 !ucfg_nan_is_vdev_creation_allowed( 10480 hdd_ctx->psoc))) && 10481 cds_is_driver_recovering()) 10482 ucfg_nan_disable_ind_to_userspace( 10483 hdd_ctx->psoc); 10484 10485 hdd_register_tx_flow_control(adapter, 10486 hdd_tx_resume_timer_expired_handler, 10487 hdd_tx_resume_cb, 10488 hdd_tx_flow_control_is_pause); 10489 10490 hdd_register_hl_netdev_fc_timer( 10491 adapter, 10492 hdd_tx_resume_timer_expired_handler); 10493 10494 hdd_lpass_notify_start(adapter->deflink); 10495 break; 10496 10497 case QDF_SAP_MODE: 10498 ucfg_mlme_get_sap_internal_restart(hdd_ctx->psoc, 10499 &value); 10500 if (value) 10501 hdd_start_ap_adapter(adapter, rtnl_held); 10502 10503 break; 10504 10505 case QDF_P2P_GO_MODE: 10506 hdd_delete_sta(adapter); 10507 break; 10508 case QDF_MONITOR_MODE: 10509 if (wlan_hdd_is_session_type_monitor( 10510 adapter->device_mode) && 10511 ucfg_pkt_capture_get_mode(hdd_ctx->psoc) != 10512 PACKET_CAPTURE_MODE_DISABLE) { 10513 struct hdd_adapter *sta_adapter; 10514 10515 sta_adapter = hdd_get_adapter(hdd_ctx, 10516 QDF_STA_MODE); 10517 if (!sta_adapter) { 10518 hdd_err("No station interface found"); 10519 return -EINVAL; 10520 } 10521 10522 hdd_map_monitor_interface_vdev(sta_adapter); 10523 break; 10524 } 10525 hdd_start_station_adapter(adapter); 10526 hdd_set_mon_rx_cb(adapter->dev); 10527 10528 wlan_hdd_set_mon_chan( 10529 adapter, adapter->mon_chan_freq, 10530 adapter->mon_bandwidth); 10531 break; 10532 case QDF_NDI_MODE: 10533 hdd_ndi_start(adapter->dev->name, 0); 10534 break; 10535 default: 10536 break; 10537 } 10538 /* 10539 * Action frame registered in one adapter which will 10540 * applicable to all interfaces 10541 */ 10542 if (hdd_set_fw_params(adapter)) 10543 hdd_err("Failed to set adapter FW params after SSR!"); 10544 10545 wlan_hdd_cfg80211_register_frames(adapter); 10546 hdd_create_adapter_sysfs_files(adapter); 10547 hdd_adapter_dev_put_debug(adapter, dbgid); 10548 } 10549 10550 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 10551 dbgid) { 10552 if (!hdd_is_interface_up(adapter)) { 10553 hdd_adapter_dev_put_debug(adapter, dbgid); 10554 continue; 10555 } 10556 10557 if (adapter->device_mode == QDF_P2P_GO_MODE) 10558 hdd_stop_p2p_go(adapter); 10559 10560 hdd_adapter_dev_put_debug(adapter, dbgid); 10561 } 10562 10563 hdd_exit(); 10564 10565 return QDF_STATUS_SUCCESS; 10566 } 10567 hdd_adapter_dev_hold_debug(struct hdd_adapter * adapter,wlan_net_dev_ref_dbgid dbgid)10568 void hdd_adapter_dev_hold_debug(struct hdd_adapter *adapter, 10569 wlan_net_dev_ref_dbgid dbgid) 10570 { 10571 if (dbgid >= NET_DEV_HOLD_ID_MAX) { 10572 hdd_err("Invalid debug id: %d", dbgid); 10573 QDF_BUG(0); 10574 } 10575 dev_hold(adapter->dev); 10576 qdf_atomic_inc(&adapter->net_dev_hold_ref_count[dbgid]); 10577 } 10578 hdd_adapter_dev_put_debug(struct hdd_adapter * adapter,wlan_net_dev_ref_dbgid dbgid)10579 void hdd_adapter_dev_put_debug(struct hdd_adapter *adapter, 10580 wlan_net_dev_ref_dbgid dbgid) 10581 { 10582 if (dbgid >= NET_DEV_HOLD_ID_MAX) { 10583 hdd_err("Invalid debug id: %d", dbgid); 10584 QDF_BUG(0); 10585 } 10586 10587 if (qdf_atomic_dec_return( 10588 &adapter->net_dev_hold_ref_count[dbgid]) < 0) { 10589 hdd_err("dev_put detected without dev_hold for debug id: %s", 10590 net_dev_ref_debug_string_from_id(dbgid)); 10591 QDF_BUG(0); 10592 } 10593 10594 if (adapter->dev) { 10595 dev_put(adapter->dev); 10596 } else { 10597 hdd_err("adapter->dev is NULL"); 10598 QDF_BUG(0); 10599 } 10600 } 10601 hdd_get_front_adapter(struct hdd_context * hdd_ctx,struct hdd_adapter ** out_adapter)10602 QDF_STATUS hdd_get_front_adapter(struct hdd_context *hdd_ctx, 10603 struct hdd_adapter **out_adapter) 10604 { 10605 QDF_STATUS status; 10606 qdf_list_node_t *node; 10607 10608 *out_adapter = NULL; 10609 10610 qdf_spin_lock_bh(&hdd_ctx->hdd_adapter_lock); 10611 status = qdf_list_peek_front(&hdd_ctx->hdd_adapters, &node); 10612 qdf_spin_unlock_bh(&hdd_ctx->hdd_adapter_lock); 10613 10614 if (QDF_IS_STATUS_ERROR(status)) 10615 return status; 10616 10617 *out_adapter = qdf_container_of(node, struct hdd_adapter, node); 10618 10619 return QDF_STATUS_SUCCESS; 10620 } 10621 hdd_get_next_adapter(struct hdd_context * hdd_ctx,struct hdd_adapter * current_adapter,struct hdd_adapter ** out_adapter)10622 QDF_STATUS hdd_get_next_adapter(struct hdd_context *hdd_ctx, 10623 struct hdd_adapter *current_adapter, 10624 struct hdd_adapter **out_adapter) 10625 { 10626 QDF_STATUS status; 10627 qdf_list_node_t *node; 10628 10629 *out_adapter = NULL; 10630 10631 qdf_spin_lock_bh(&hdd_ctx->hdd_adapter_lock); 10632 status = qdf_list_peek_next(&hdd_ctx->hdd_adapters, 10633 ¤t_adapter->node, 10634 &node); 10635 qdf_spin_unlock_bh(&hdd_ctx->hdd_adapter_lock); 10636 10637 if (QDF_IS_STATUS_ERROR(status)) 10638 return status; 10639 10640 *out_adapter = qdf_container_of(node, struct hdd_adapter, node); 10641 10642 return status; 10643 } 10644 hdd_get_front_adapter_no_lock(struct hdd_context * hdd_ctx,struct hdd_adapter ** out_adapter)10645 QDF_STATUS hdd_get_front_adapter_no_lock(struct hdd_context *hdd_ctx, 10646 struct hdd_adapter **out_adapter) 10647 { 10648 QDF_STATUS status; 10649 qdf_list_node_t *node; 10650 10651 *out_adapter = NULL; 10652 10653 status = qdf_list_peek_front(&hdd_ctx->hdd_adapters, &node); 10654 10655 if (QDF_IS_STATUS_ERROR(status)) 10656 return status; 10657 10658 *out_adapter = qdf_container_of(node, struct hdd_adapter, node); 10659 10660 return QDF_STATUS_SUCCESS; 10661 } 10662 hdd_get_next_adapter_no_lock(struct hdd_context * hdd_ctx,struct hdd_adapter * current_adapter,struct hdd_adapter ** out_adapter)10663 QDF_STATUS hdd_get_next_adapter_no_lock(struct hdd_context *hdd_ctx, 10664 struct hdd_adapter *current_adapter, 10665 struct hdd_adapter **out_adapter) 10666 { 10667 QDF_STATUS status; 10668 qdf_list_node_t *node; 10669 10670 if (!current_adapter) 10671 return QDF_STATUS_E_INVAL; 10672 10673 *out_adapter = NULL; 10674 10675 status = qdf_list_peek_next(&hdd_ctx->hdd_adapters, 10676 ¤t_adapter->node, 10677 &node); 10678 10679 if (QDF_IS_STATUS_ERROR(status)) 10680 return status; 10681 10682 *out_adapter = qdf_container_of(node, struct hdd_adapter, node); 10683 10684 return status; 10685 } 10686 hdd_remove_adapter(struct hdd_context * hdd_ctx,struct hdd_adapter * adapter)10687 QDF_STATUS hdd_remove_adapter(struct hdd_context *hdd_ctx, 10688 struct hdd_adapter *adapter) 10689 { 10690 QDF_STATUS status; 10691 10692 qdf_spin_lock_bh(&hdd_ctx->hdd_adapter_lock); 10693 status = qdf_list_remove_node(&hdd_ctx->hdd_adapters, &adapter->node); 10694 qdf_spin_unlock_bh(&hdd_ctx->hdd_adapter_lock); 10695 10696 return status; 10697 } 10698 hdd_remove_front_adapter(struct hdd_context * hdd_ctx,struct hdd_adapter ** out_adapter)10699 QDF_STATUS hdd_remove_front_adapter(struct hdd_context *hdd_ctx, 10700 struct hdd_adapter **out_adapter) 10701 { 10702 QDF_STATUS status; 10703 qdf_list_node_t *node; 10704 10705 *out_adapter = NULL; 10706 10707 qdf_spin_lock_bh(&hdd_ctx->hdd_adapter_lock); 10708 status = qdf_list_remove_front(&hdd_ctx->hdd_adapters, &node); 10709 qdf_spin_unlock_bh(&hdd_ctx->hdd_adapter_lock); 10710 10711 if (QDF_IS_STATUS_ERROR(status)) 10712 return status; 10713 10714 *out_adapter = qdf_container_of(node, struct hdd_adapter, node); 10715 10716 return status; 10717 } 10718 hdd_add_adapter_back(struct hdd_context * hdd_ctx,struct hdd_adapter * adapter)10719 QDF_STATUS hdd_add_adapter_back(struct hdd_context *hdd_ctx, 10720 struct hdd_adapter *adapter) 10721 { 10722 QDF_STATUS status; 10723 10724 qdf_spin_lock_bh(&hdd_ctx->hdd_adapter_lock); 10725 status = qdf_list_insert_back(&hdd_ctx->hdd_adapters, &adapter->node); 10726 qdf_spin_unlock_bh(&hdd_ctx->hdd_adapter_lock); 10727 10728 return status; 10729 } 10730 hdd_add_adapter_front(struct hdd_context * hdd_ctx,struct hdd_adapter * adapter)10731 QDF_STATUS hdd_add_adapter_front(struct hdd_context *hdd_ctx, 10732 struct hdd_adapter *adapter) 10733 { 10734 QDF_STATUS status; 10735 10736 qdf_spin_lock_bh(&hdd_ctx->hdd_adapter_lock); 10737 status = qdf_list_insert_front(&hdd_ctx->hdd_adapters, &adapter->node); 10738 qdf_spin_unlock_bh(&hdd_ctx->hdd_adapter_lock); 10739 10740 return status; 10741 } 10742 hdd_validate_next_adapter(struct hdd_adapter ** curr,struct hdd_adapter ** next,wlan_net_dev_ref_dbgid dbg_id)10743 void hdd_validate_next_adapter(struct hdd_adapter **curr, 10744 struct hdd_adapter **next, 10745 wlan_net_dev_ref_dbgid dbg_id) 10746 { 10747 if (!*curr || !*next || *curr != *next) 10748 return; 10749 10750 hdd_err("Validation failed"); 10751 hdd_adapter_dev_put_debug(*curr, dbg_id); 10752 *curr = NULL; 10753 *next = NULL; 10754 } 10755 hdd_adapter_iterate(hdd_adapter_iterate_cb cb,void * context)10756 QDF_STATUS hdd_adapter_iterate(hdd_adapter_iterate_cb cb, void *context) 10757 { 10758 struct hdd_context *hdd_ctx; 10759 struct hdd_adapter *cache[HDD_MAX_ADAPTERS]; 10760 struct hdd_adapter *adapter; 10761 uint32_t n_cache = 0; 10762 QDF_STATUS ret = QDF_STATUS_SUCCESS; 10763 QDF_STATUS status; 10764 int i; 10765 struct wlan_hdd_link_info *link_info; 10766 10767 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 10768 if (unlikely(!hdd_ctx)) 10769 return QDF_STATUS_E_FAILURE; 10770 10771 qdf_spin_lock_bh(&hdd_ctx->hdd_adapter_lock); 10772 for (hdd_get_front_adapter_no_lock(hdd_ctx, &adapter); adapter; 10773 hdd_get_next_adapter_no_lock(hdd_ctx, adapter, &adapter)) { 10774 cache[n_cache++] = adapter; 10775 } 10776 qdf_spin_unlock_bh(&hdd_ctx->hdd_adapter_lock); 10777 10778 for (i = 0; i < n_cache; i++) { 10779 adapter = hdd_adapter_get_by_reference(hdd_ctx, cache[i]); 10780 if (!adapter) { 10781 /* 10782 * detected remove while iterating 10783 * concurrency failure 10784 */ 10785 ret = QDF_STATUS_E_FAILURE; 10786 continue; 10787 } 10788 hdd_adapter_for_each_active_link_info(adapter, link_info) { 10789 status = cb(link_info, context); 10790 if (status != QDF_STATUS_SUCCESS) { 10791 hdd_adapter_put(adapter); 10792 return status; 10793 } 10794 } 10795 hdd_adapter_put(adapter); 10796 } 10797 10798 return ret; 10799 } 10800 hdd_get_adapter_by_rand_macaddr(struct hdd_context * hdd_ctx,tSirMacAddr mac_addr)10801 struct hdd_adapter *hdd_get_adapter_by_rand_macaddr( 10802 struct hdd_context *hdd_ctx, tSirMacAddr mac_addr) 10803 { 10804 struct hdd_adapter *adapter, *next_adapter = NULL; 10805 wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_GET_ADAPTER_BY_RAND_MACADDR; 10806 struct wlan_hdd_link_info *link_info; 10807 10808 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 10809 dbgid) { 10810 if (adapter->device_mode != QDF_STA_MODE && 10811 adapter->device_mode != QDF_P2P_CLIENT_MODE && 10812 adapter->device_mode != QDF_P2P_DEVICE_MODE) { 10813 hdd_adapter_dev_put_debug(adapter, dbgid); 10814 continue; 10815 } 10816 10817 hdd_adapter_for_each_active_link_info(adapter, link_info) { 10818 if (ucfg_p2p_check_random_mac(hdd_ctx->psoc, 10819 link_info->vdev_id, 10820 mac_addr)) { 10821 hdd_adapter_dev_put_debug(adapter, dbgid); 10822 if (next_adapter) 10823 hdd_adapter_dev_put_debug(next_adapter, 10824 dbgid); 10825 return adapter; 10826 } 10827 } 10828 hdd_adapter_dev_put_debug(adapter, dbgid); 10829 } 10830 10831 return NULL; 10832 } 10833 10834 #ifdef WLAN_HDD_MULTI_VDEV_SINGLE_NDEV hdd_get_adapter_by_macaddr(struct hdd_context * hdd_ctx,tSirMacAddr mac_addr)10835 struct hdd_adapter *hdd_get_adapter_by_macaddr(struct hdd_context *hdd_ctx, 10836 tSirMacAddr mac_addr) 10837 { 10838 struct hdd_adapter *adapter, *next_adapter = NULL; 10839 wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_GET_ADAPTER_BY_MACADDR; 10840 struct qdf_mac_addr zero_mac_addr = QDF_MAC_ADDR_ZERO_INIT; 10841 struct wlan_hdd_link_info *link_info; 10842 10843 if (!qdf_mem_cmp(mac_addr, zero_mac_addr.bytes, sizeof(tSirMacAddr))) 10844 return NULL; 10845 10846 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 10847 dbgid) { 10848 if (!qdf_mem_cmp(adapter->mac_addr.bytes, 10849 mac_addr, sizeof(tSirMacAddr))) { 10850 hdd_adapter_dev_put_debug(adapter, dbgid); 10851 if (next_adapter) 10852 hdd_adapter_dev_put_debug(next_adapter, 10853 dbgid); 10854 return adapter; 10855 } 10856 hdd_adapter_for_each_active_link_info(adapter, link_info) { 10857 if (!qdf_mem_cmp(link_info->link_addr.bytes, 10858 mac_addr, sizeof(tSirMacAddr))) { 10859 hdd_adapter_dev_put_debug(adapter, dbgid); 10860 if (next_adapter) 10861 hdd_adapter_dev_put_debug(next_adapter, 10862 dbgid); 10863 return adapter; 10864 } 10865 } 10866 hdd_adapter_dev_put_debug(adapter, dbgid); 10867 } 10868 10869 return NULL; 10870 } 10871 10872 struct wlan_hdd_link_info * hdd_get_link_info_by_link_addr(struct hdd_context * hdd_ctx,struct qdf_mac_addr * link_addr)10873 hdd_get_link_info_by_link_addr(struct hdd_context *hdd_ctx, 10874 struct qdf_mac_addr *link_addr) 10875 { 10876 struct wlan_hdd_link_info *link_info; 10877 struct hdd_adapter *adapter, *next_adapter = NULL; 10878 wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_GET_ADAPTER_BY_MACADDR; 10879 10880 if (!link_addr || qdf_is_macaddr_zero(link_addr)) 10881 return NULL; 10882 10883 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 10884 dbgid) { 10885 hdd_adapter_for_each_link_info(adapter, link_info) { 10886 if (qdf_is_macaddr_equal(link_addr, 10887 &link_info->link_addr)) { 10888 hdd_adapter_dev_put_debug(adapter, dbgid); 10889 if (next_adapter) 10890 hdd_adapter_dev_put_debug(next_adapter, 10891 dbgid); 10892 return link_info; 10893 } 10894 } 10895 hdd_adapter_dev_put_debug(adapter, dbgid); 10896 } 10897 10898 return NULL; 10899 } 10900 #else hdd_get_adapter_by_macaddr(struct hdd_context * hdd_ctx,tSirMacAddr mac_addr)10901 struct hdd_adapter *hdd_get_adapter_by_macaddr(struct hdd_context *hdd_ctx, 10902 tSirMacAddr mac_addr) 10903 { 10904 struct hdd_adapter *adapter, *next_adapter = NULL; 10905 wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_GET_ADAPTER_BY_MACADDR; 10906 10907 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 10908 dbgid) { 10909 if (!qdf_mem_cmp(adapter->mac_addr.bytes, 10910 mac_addr, sizeof(tSirMacAddr))) { 10911 hdd_adapter_dev_put_debug(adapter, dbgid); 10912 if (next_adapter) 10913 hdd_adapter_dev_put_debug(next_adapter, 10914 dbgid); 10915 return adapter; 10916 } 10917 10918 if (hdd_adapter_is_sl_ml_adapter(adapter) && 10919 !qdf_mem_cmp(adapter->mld_addr.bytes, 10920 mac_addr, sizeof(tSirMacAddr))) { 10921 hdd_adapter_dev_put_debug(adapter, dbgid); 10922 if (next_adapter) 10923 hdd_adapter_dev_put_debug(next_adapter, dbgid); 10924 return adapter; 10925 } 10926 hdd_adapter_dev_put_debug(adapter, dbgid); 10927 } 10928 10929 return NULL; 10930 } 10931 10932 struct wlan_hdd_link_info * hdd_get_link_info_by_link_addr(struct hdd_context * hdd_ctx,struct qdf_mac_addr * link_addr)10933 hdd_get_link_info_by_link_addr(struct hdd_context *hdd_ctx, 10934 struct qdf_mac_addr *link_addr) 10935 { 10936 return NULL; 10937 } 10938 #endif 10939 10940 struct wlan_hdd_link_info * hdd_get_link_info_by_vdev(struct hdd_context * hdd_ctx,uint32_t vdev_id)10941 hdd_get_link_info_by_vdev(struct hdd_context *hdd_ctx, uint32_t vdev_id) 10942 { 10943 struct hdd_adapter *adapter, *next_adapter = NULL; 10944 wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_GET_ADAPTER_BY_VDEV; 10945 struct wlan_hdd_link_info *link_info; 10946 10947 if (vdev_id == WLAN_INVALID_VDEV_ID) 10948 return NULL; 10949 10950 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 10951 dbgid) { 10952 hdd_adapter_for_each_active_link_info(adapter, link_info) { 10953 if (link_info->vdev_id == vdev_id) { 10954 hdd_adapter_dev_put_debug(adapter, dbgid); 10955 if (next_adapter) 10956 hdd_adapter_dev_put_debug(next_adapter, 10957 dbgid); 10958 return link_info; 10959 } 10960 } 10961 hdd_adapter_dev_put_debug(adapter, dbgid); 10962 } 10963 10964 return NULL; 10965 } 10966 hdd_adapter_get_by_reference(struct hdd_context * hdd_ctx,struct hdd_adapter * reference)10967 struct hdd_adapter *hdd_adapter_get_by_reference(struct hdd_context *hdd_ctx, 10968 struct hdd_adapter *reference) 10969 { 10970 struct hdd_adapter *adapter, *next_adapter = NULL; 10971 wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_ADAPTER_GET_BY_REFERENCE; 10972 10973 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 10974 dbgid) { 10975 if (adapter == reference) { 10976 dev_hold(adapter->dev); 10977 hdd_adapter_dev_put_debug(adapter, dbgid); 10978 if (next_adapter) 10979 hdd_adapter_dev_put_debug(next_adapter, 10980 dbgid); 10981 break; 10982 } 10983 hdd_adapter_dev_put_debug(adapter, dbgid); 10984 } 10985 10986 return adapter; 10987 } 10988 hdd_adapter_put(struct hdd_adapter * adapter)10989 void hdd_adapter_put(struct hdd_adapter *adapter) 10990 { 10991 dev_put(adapter->dev); 10992 } 10993 hdd_get_adapter_by_iface_name(struct hdd_context * hdd_ctx,const char * iface_name)10994 struct hdd_adapter *hdd_get_adapter_by_iface_name(struct hdd_context *hdd_ctx, 10995 const char *iface_name) 10996 { 10997 struct hdd_adapter *adapter, *next_adapter = NULL; 10998 wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_GET_ADAPTER_BY_IFACE_NAME; 10999 11000 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 11001 dbgid) { 11002 if (!qdf_str_cmp(adapter->dev->name, iface_name)) { 11003 hdd_adapter_dev_put_debug(adapter, dbgid); 11004 if (next_adapter) 11005 hdd_adapter_dev_put_debug(next_adapter, 11006 dbgid); 11007 return adapter; 11008 } 11009 hdd_adapter_dev_put_debug(adapter, dbgid); 11010 } 11011 11012 return NULL; 11013 } 11014 hdd_get_adapter_by_ifindex(struct hdd_context * hdd_ctx,uint32_t if_index)11015 struct hdd_adapter *hdd_get_adapter_by_ifindex(struct hdd_context *hdd_ctx, 11016 uint32_t if_index) 11017 { 11018 struct hdd_adapter *adapter, *next_adapter = NULL; 11019 wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_GET_ADAPTER; 11020 11021 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 11022 dbgid) { 11023 if (adapter->dev->ifindex == if_index) { 11024 hdd_adapter_dev_put_debug(adapter, dbgid); 11025 if (next_adapter) 11026 hdd_adapter_dev_put_debug(next_adapter, 11027 dbgid); 11028 return adapter; 11029 } 11030 hdd_adapter_dev_put_debug(adapter, dbgid); 11031 } 11032 11033 return NULL; 11034 } 11035 11036 /** 11037 * hdd_get_adapter() - to get adapter matching the mode 11038 * @hdd_ctx: hdd context 11039 * @mode: adapter mode 11040 * 11041 * This routine will return the pointer to adapter matching 11042 * with the passed mode. 11043 * 11044 * Return: pointer to adapter or null 11045 */ hdd_get_adapter(struct hdd_context * hdd_ctx,enum QDF_OPMODE mode)11046 struct hdd_adapter *hdd_get_adapter(struct hdd_context *hdd_ctx, 11047 enum QDF_OPMODE mode) 11048 { 11049 struct hdd_adapter *adapter, *next_adapter = NULL; 11050 wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_GET_ADAPTER; 11051 11052 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 11053 dbgid) { 11054 if (adapter->device_mode == mode) { 11055 hdd_adapter_dev_put_debug(adapter, dbgid); 11056 if (next_adapter) 11057 hdd_adapter_dev_put_debug(next_adapter, 11058 dbgid); 11059 return adapter; 11060 } 11061 hdd_adapter_dev_put_debug(adapter, dbgid); 11062 } 11063 11064 return NULL; 11065 } 11066 hdd_get_device_mode(uint32_t vdev_id)11067 enum QDF_OPMODE hdd_get_device_mode(uint32_t vdev_id) 11068 { 11069 struct hdd_context *hdd_ctx; 11070 struct wlan_hdd_link_info *link_info; 11071 11072 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 11073 if (!hdd_ctx) 11074 return QDF_MAX_NO_OF_MODE; 11075 11076 link_info = hdd_get_link_info_by_vdev(hdd_ctx, vdev_id); 11077 if (!link_info) { 11078 hdd_err("Invalid vdev"); 11079 return QDF_MAX_NO_OF_MODE; 11080 } 11081 11082 return link_info->adapter->device_mode; 11083 } 11084 hdd_get_operating_chan_freq(struct hdd_context * hdd_ctx,enum QDF_OPMODE mode)11085 uint32_t hdd_get_operating_chan_freq(struct hdd_context *hdd_ctx, 11086 enum QDF_OPMODE mode) 11087 { 11088 struct hdd_adapter *adapter, *next_adapter = NULL; 11089 uint32_t oper_chan_freq = 0; 11090 wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_GET_OPERATING_CHAN_FREQ; 11091 11092 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 11093 dbgid) { 11094 if (mode == adapter->device_mode) { 11095 oper_chan_freq = 11096 hdd_get_link_info_home_channel(adapter->deflink); 11097 hdd_adapter_dev_put_debug(adapter, dbgid); 11098 if (next_adapter) 11099 hdd_adapter_dev_put_debug(next_adapter, 11100 dbgid); 11101 break; 11102 } 11103 hdd_adapter_dev_put_debug(adapter, dbgid); 11104 } 11105 11106 return oper_chan_freq; 11107 } 11108 hdd_unregister_wext_all_adapters(struct hdd_context * hdd_ctx,bool rtnl_held)11109 static inline QDF_STATUS hdd_unregister_wext_all_adapters( 11110 struct hdd_context *hdd_ctx, 11111 bool rtnl_held) 11112 { 11113 struct hdd_adapter *adapter, *next_adapter = NULL; 11114 wlan_net_dev_ref_dbgid dbgid = 11115 NET_DEV_HOLD_UNREGISTER_WEXT_ALL_ADAPTERS; 11116 11117 hdd_enter(); 11118 11119 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 11120 dbgid) { 11121 if (adapter->device_mode == QDF_STA_MODE || 11122 adapter->device_mode == QDF_P2P_CLIENT_MODE || 11123 adapter->device_mode == QDF_P2P_DEVICE_MODE || 11124 adapter->device_mode == QDF_SAP_MODE || 11125 adapter->device_mode == QDF_P2P_GO_MODE) { 11126 hdd_wext_unregister(adapter->dev, rtnl_held); 11127 } 11128 hdd_adapter_dev_put_debug(adapter, dbgid); 11129 } 11130 11131 hdd_exit(); 11132 11133 return QDF_STATUS_SUCCESS; 11134 } 11135 hdd_abort_mac_scan_all_adapters(struct hdd_context * hdd_ctx)11136 QDF_STATUS hdd_abort_mac_scan_all_adapters(struct hdd_context *hdd_ctx) 11137 { 11138 struct hdd_adapter *adapter, *next_adapter = NULL; 11139 wlan_net_dev_ref_dbgid dbgid = 11140 NET_DEV_HOLD_ABORT_MAC_SCAN_ALL_ADAPTERS; 11141 struct wlan_hdd_link_info *link_info; 11142 11143 hdd_enter(); 11144 11145 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 11146 dbgid) { 11147 if (adapter->device_mode == QDF_STA_MODE || 11148 adapter->device_mode == QDF_P2P_CLIENT_MODE || 11149 adapter->device_mode == QDF_P2P_DEVICE_MODE || 11150 adapter->device_mode == QDF_SAP_MODE || 11151 adapter->device_mode == QDF_P2P_GO_MODE) { 11152 hdd_adapter_for_each_active_link_info(adapter, 11153 link_info) { 11154 wlan_abort_scan(hdd_ctx->pdev, INVAL_PDEV_ID, 11155 link_info->vdev_id, 11156 INVALID_SCAN_ID, true); 11157 } 11158 } 11159 hdd_adapter_dev_put_debug(adapter, dbgid); 11160 } 11161 11162 hdd_exit(); 11163 11164 return QDF_STATUS_SUCCESS; 11165 } 11166 11167 /** 11168 * hdd_abort_sched_scan_all_adapters() - stops scheduled (PNO) scans for all 11169 * adapters 11170 * @hdd_ctx: The HDD context containing the adapters to operate on 11171 * 11172 * return: QDF_STATUS_SUCCESS 11173 */ hdd_abort_sched_scan_all_adapters(struct hdd_context * hdd_ctx)11174 static QDF_STATUS hdd_abort_sched_scan_all_adapters(struct hdd_context *hdd_ctx) 11175 { 11176 struct hdd_adapter *adapter, *next_adapter = NULL; 11177 int err; 11178 wlan_net_dev_ref_dbgid dbgid = 11179 NET_DEV_HOLD_ABORT_SCHED_SCAN_ALL_ADAPTERS; 11180 11181 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 11182 dbgid) { 11183 if (adapter->device_mode == QDF_STA_MODE || 11184 adapter->device_mode == QDF_P2P_CLIENT_MODE || 11185 adapter->device_mode == QDF_P2P_DEVICE_MODE || 11186 adapter->device_mode == QDF_SAP_MODE || 11187 adapter->device_mode == QDF_P2P_GO_MODE) { 11188 err = wlan_hdd_sched_scan_stop(adapter->dev); 11189 if (err) 11190 hdd_err("Unable to stop scheduled scan"); 11191 } 11192 hdd_adapter_dev_put_debug(adapter, dbgid); 11193 } 11194 11195 return QDF_STATUS_SUCCESS; 11196 } 11197 11198 /** 11199 * hdd_unregister_notifiers - Unregister netdev notifiers. 11200 * @hdd_ctx: HDD context 11201 * 11202 * Unregister netdev notifiers like IPv4 and IPv6. 11203 * 11204 * Return: None. 11205 */ hdd_unregister_notifiers(struct hdd_context * hdd_ctx)11206 void hdd_unregister_notifiers(struct hdd_context *hdd_ctx) 11207 { 11208 osif_dp_nud_unregister_netevent_notifier(hdd_ctx->psoc); 11209 hdd_wlan_unregister_ip6_notifier(hdd_ctx); 11210 11211 unregister_inetaddr_notifier(&hdd_ctx->ipv4_notifier); 11212 } 11213 11214 /** 11215 * hdd_exit_netlink_services - Exit netlink services 11216 * @hdd_ctx: HDD context 11217 * 11218 * Exit netlink services like cnss_diag, cesium netlink socket, ptt socket and 11219 * nl service. 11220 * 11221 * Return: None. 11222 */ hdd_exit_netlink_services(struct hdd_context * hdd_ctx)11223 static void hdd_exit_netlink_services(struct hdd_context *hdd_ctx) 11224 { 11225 spectral_scan_deactivate_service(); 11226 cnss_diag_deactivate_service(); 11227 hdd_close_cesium_nl_sock(); 11228 ptt_sock_deactivate_svc(); 11229 hdd_deactivate_wifi_pos(); 11230 11231 nl_srv_exit(); 11232 } 11233 11234 /** 11235 * hdd_init_netlink_services- Init netlink services 11236 * @hdd_ctx: HDD context 11237 * 11238 * Init netlink services like cnss_diag, cesium netlink socket, ptt socket and 11239 * nl service. 11240 * 11241 * Return: 0 on success and errno on failure. 11242 */ hdd_init_netlink_services(struct hdd_context * hdd_ctx)11243 static int hdd_init_netlink_services(struct hdd_context *hdd_ctx) 11244 { 11245 int ret; 11246 11247 ret = wlan_hdd_nl_init(hdd_ctx); 11248 if (ret) { 11249 hdd_err("nl_srv_init failed: %d", ret); 11250 goto out; 11251 } 11252 cds_set_radio_index(hdd_ctx->radio_index); 11253 11254 ret = hdd_activate_wifi_pos(hdd_ctx); 11255 if (ret) { 11256 hdd_err("hdd_activate_wifi_pos failed: %d", ret); 11257 goto err_nl_srv; 11258 } 11259 11260 ptt_sock_activate_svc(); 11261 11262 ret = hdd_open_cesium_nl_sock(); 11263 if (ret) 11264 hdd_err("hdd_open_cesium_nl_sock failed ret: %d", ret); 11265 11266 ret = cnss_diag_activate_service(); 11267 if (ret) { 11268 hdd_err("cnss_diag_activate_service failed: %d", ret); 11269 goto err_close_cesium; 11270 } 11271 11272 spectral_scan_activate_service(hdd_ctx); 11273 11274 return 0; 11275 11276 err_close_cesium: 11277 hdd_close_cesium_nl_sock(); 11278 ptt_sock_deactivate_svc(); 11279 hdd_deactivate_wifi_pos(); 11280 err_nl_srv: 11281 nl_srv_exit(); 11282 out: 11283 return ret; 11284 } 11285 11286 #ifdef SHUTDOWN_WLAN_IN_SYSTEM_SUSPEND 11287 static QDF_STATUS hdd_shutdown_wlan_in_suspend_prepare(struct hdd_context * hdd_ctx)11288 hdd_shutdown_wlan_in_suspend_prepare(struct hdd_context *hdd_ctx) 11289 { 11290 #define SHUTDOWN_IN_SUSPEND_RETRY 30 11291 11292 int count = 0; 11293 enum pmo_suspend_mode mode; 11294 11295 if (hdd_ctx->driver_status != DRIVER_MODULES_ENABLED) { 11296 hdd_debug("Driver Modules not Enabled "); 11297 return 0; 11298 } 11299 11300 mode = ucfg_pmo_get_suspend_mode(hdd_ctx->psoc); 11301 hdd_debug("suspend mode is %d", mode); 11302 11303 if (mode == PMO_SUSPEND_NONE || mode == PMO_SUSPEND_LEGENCY) { 11304 hdd_debug("needn't shutdown in suspend"); 11305 return 0; 11306 } 11307 11308 if (!hdd_is_any_interface_open(hdd_ctx)) { 11309 return pld_idle_shutdown(hdd_ctx->parent_dev, 11310 hdd_psoc_idle_shutdown); 11311 } else { 11312 if (mode == PMO_SUSPEND_WOW) 11313 return 0; 11314 } 11315 11316 /*try to wait interface down for PMO_SUSPEND_SHUTDOWN mode*/ 11317 while (hdd_is_any_interface_open(hdd_ctx) && 11318 count < SHUTDOWN_IN_SUSPEND_RETRY) { 11319 count++; 11320 hdd_debug_rl("sleep 50ms to wait adapters stopped, #%d", count); 11321 msleep(50); 11322 } 11323 if (count >= SHUTDOWN_IN_SUSPEND_RETRY) { 11324 hdd_err("some adapters not stopped"); 11325 return -EBUSY; 11326 } 11327 return pld_idle_shutdown(hdd_ctx->parent_dev, hdd_psoc_idle_shutdown); 11328 } 11329 hdd_pm_notify(struct notifier_block * b,unsigned long event,void * p)11330 static int hdd_pm_notify(struct notifier_block *b, 11331 unsigned long event, void *p) 11332 { 11333 struct hdd_context *hdd_ctx = container_of(b, struct hdd_context, 11334 pm_notifier); 11335 11336 if (wlan_hdd_validate_context(hdd_ctx) != 0) 11337 return NOTIFY_STOP; 11338 11339 hdd_debug("got PM event: %lu", event); 11340 11341 switch (event) { 11342 case PM_SUSPEND_PREPARE: 11343 case PM_HIBERNATION_PREPARE: 11344 if (0 != hdd_shutdown_wlan_in_suspend_prepare(hdd_ctx)) 11345 return NOTIFY_STOP; 11346 break; 11347 case PM_POST_SUSPEND: 11348 case PM_POST_HIBERNATION: 11349 break; 11350 } 11351 11352 return NOTIFY_DONE; 11353 } 11354 hdd_pm_notifier_init(struct hdd_context * hdd_ctx)11355 static void hdd_pm_notifier_init(struct hdd_context *hdd_ctx) 11356 { 11357 hdd_ctx->pm_notifier.notifier_call = hdd_pm_notify; 11358 register_pm_notifier(&hdd_ctx->pm_notifier); 11359 } 11360 hdd_pm_notifier_deinit(struct hdd_context * hdd_ctx)11361 static void hdd_pm_notifier_deinit(struct hdd_context *hdd_ctx) 11362 { 11363 unregister_pm_notifier(&hdd_ctx->pm_notifier); 11364 } 11365 #else hdd_pm_notifier_init(struct hdd_context * hdd_ctx)11366 static inline void hdd_pm_notifier_init(struct hdd_context *hdd_ctx) 11367 { 11368 } 11369 hdd_pm_notifier_deinit(struct hdd_context * hdd_ctx)11370 static inline void hdd_pm_notifier_deinit(struct hdd_context *hdd_ctx) 11371 { 11372 } 11373 #endif 11374 11375 /** 11376 * hdd_context_deinit() - Deinitialize HDD context 11377 * @hdd_ctx: HDD context. 11378 * 11379 * Deinitialize HDD context along with all the feature specific contexts but 11380 * do not free hdd context itself. Caller of this API is supposed to free 11381 * HDD context. 11382 * 11383 * return: 0 on success and errno on failure. 11384 */ hdd_context_deinit(struct hdd_context * hdd_ctx)11385 static int hdd_context_deinit(struct hdd_context *hdd_ctx) 11386 { 11387 hdd_lpc_delete_work(hdd_ctx); 11388 11389 qdf_wake_lock_destroy(&hdd_ctx->monitor_mode_wakelock); 11390 11391 wlan_hdd_cfg80211_deinit(hdd_ctx->wiphy); 11392 11393 ucfg_dp_bbm_context_deinit(hdd_ctx->psoc); 11394 11395 hdd_sap_context_destroy(hdd_ctx); 11396 11397 hdd_scan_context_destroy(hdd_ctx); 11398 11399 qdf_list_destroy(&hdd_ctx->hdd_adapters); 11400 11401 return 0; 11402 } 11403 hdd_context_destroy(struct hdd_context * hdd_ctx)11404 void hdd_context_destroy(struct hdd_context *hdd_ctx) 11405 { 11406 wlan_hdd_sar_timers_deinit(hdd_ctx); 11407 11408 cds_set_context(QDF_MODULE_ID_HDD, NULL); 11409 11410 hdd_exit_netlink_services(hdd_ctx); 11411 11412 hdd_context_deinit(hdd_ctx); 11413 11414 hdd_objmgr_release_and_destroy_psoc(hdd_ctx); 11415 11416 qdf_mem_free(hdd_ctx->config); 11417 hdd_ctx->config = NULL; 11418 cfg_release(); 11419 11420 hdd_pm_notifier_deinit(hdd_ctx); 11421 qdf_delayed_work_destroy(&hdd_ctx->psoc_idle_timeout_work); 11422 wiphy_free(hdd_ctx->wiphy); 11423 } 11424 11425 /** 11426 * wlan_destroy_bug_report_lock() - Destroy bug report lock 11427 * 11428 * This function is used to destroy bug report lock 11429 * 11430 * Return: None 11431 */ wlan_destroy_bug_report_lock(void)11432 static void wlan_destroy_bug_report_lock(void) 11433 { 11434 struct cds_context *p_cds_context; 11435 11436 p_cds_context = cds_get_global_context(); 11437 if (!p_cds_context) { 11438 hdd_err("cds context is NULL"); 11439 return; 11440 } 11441 11442 qdf_spinlock_destroy(&p_cds_context->bug_report_lock); 11443 } 11444 11445 #ifdef DISABLE_CHANNEL_LIST wlan_hdd_cache_chann_mutex_destroy(struct hdd_context * hdd_ctx)11446 static void wlan_hdd_cache_chann_mutex_destroy(struct hdd_context *hdd_ctx) 11447 { 11448 qdf_mutex_destroy(&hdd_ctx->cache_channel_lock); 11449 } 11450 #else wlan_hdd_cache_chann_mutex_destroy(struct hdd_context * hdd_ctx)11451 static void wlan_hdd_cache_chann_mutex_destroy(struct hdd_context *hdd_ctx) 11452 { 11453 } 11454 #endif 11455 hdd_wlan_exit(struct hdd_context * hdd_ctx)11456 void hdd_wlan_exit(struct hdd_context *hdd_ctx) 11457 { 11458 struct wiphy *wiphy = hdd_ctx->wiphy; 11459 11460 hdd_enter(); 11461 11462 ucfg_dp_wait_complete_tasks(); 11463 wlan_hdd_destroy_mib_stats_lock(); 11464 hdd_debugfs_ini_config_deinit(hdd_ctx); 11465 hdd_debugfs_mws_coex_info_deinit(hdd_ctx); 11466 hdd_psoc_idle_timer_stop(hdd_ctx); 11467 hdd_regulatory_deinit(hdd_ctx); 11468 11469 /* 11470 * Powersave Offload Case 11471 * Disable Idle Power Save Mode 11472 */ 11473 hdd_set_idle_ps_config(hdd_ctx, false); 11474 /* clear the scan queue in all the scenarios */ 11475 wlan_cfg80211_cleanup_scan_queue(hdd_ctx->pdev, NULL); 11476 11477 if (hdd_ctx->driver_status != DRIVER_MODULES_CLOSED) { 11478 hdd_unregister_wext_all_adapters(hdd_ctx, false); 11479 /* 11480 * Cancel any outstanding scan requests. We are about to close 11481 * all of our adapters, but an adapter structure is what SME 11482 * passes back to our callback function. Hence if there 11483 * are any outstanding scan requests then there is a 11484 * race condition between when the adapter is closed and 11485 * when the callback is invoked. We try to resolve that 11486 * race condition here by canceling any outstanding scans 11487 * before we close the adapters. 11488 * Note that the scans may be cancelled in an asynchronous 11489 * manner, so ideally there needs to be some kind of 11490 * synchronization. Rather than introduce a new 11491 * synchronization here, we will utilize the fact that we are 11492 * about to Request Full Power, and since that is synchronized, 11493 * the expectation is that by the time Request Full Power has 11494 * completed, all scans will be cancelled 11495 */ 11496 hdd_abort_mac_scan_all_adapters(hdd_ctx); 11497 hdd_abort_sched_scan_all_adapters(hdd_ctx); 11498 11499 hdd_stop_all_adapters(hdd_ctx); 11500 hdd_deinit_all_adapters(hdd_ctx, false); 11501 } 11502 11503 unregister_netdevice_notifier(&hdd_netdev_notifier); 11504 11505 qdf_dp_trace_deinit(); 11506 11507 hdd_wlan_stop_modules(hdd_ctx, false); 11508 11509 hdd_driver_memdump_deinit(); 11510 11511 qdf_nbuf_deinit_replenish_timer(); 11512 11513 if (QDF_GLOBAL_MONITOR_MODE == hdd_get_conparam()) { 11514 hdd_info("Release wakelock for monitor mode!"); 11515 qdf_wake_lock_release(&hdd_ctx->monitor_mode_wakelock, 11516 WIFI_POWER_EVENT_WAKELOCK_MONITOR_MODE); 11517 } 11518 11519 qdf_spinlock_destroy(&hdd_ctx->hdd_adapter_lock); 11520 qdf_spinlock_destroy(&hdd_ctx->connection_status_lock); 11521 wlan_hdd_cache_chann_mutex_destroy(hdd_ctx); 11522 11523 osif_request_manager_deinit(); 11524 11525 hdd_close_all_adapters(hdd_ctx, false); 11526 11527 wlansap_global_deinit(); 11528 /* 11529 * If there is re_init failure wiphy would have already de-registered 11530 * check the wiphy status before un-registering again 11531 */ 11532 if (wiphy && wiphy->registered) { 11533 wiphy_unregister(wiphy); 11534 wlan_hdd_cfg80211_deinit(wiphy); 11535 hdd_lpass_notify_stop(hdd_ctx); 11536 } 11537 11538 hdd_deinit_regulatory_update_event(hdd_ctx); 11539 hdd_exit_netlink_services(hdd_ctx); 11540 #ifdef FEATURE_WLAN_CH_AVOID 11541 mutex_destroy(&hdd_ctx->avoid_freq_lock); 11542 #endif 11543 11544 /* This function should be invoked at the end of this api*/ 11545 hdd_dump_func_call_map(); 11546 } 11547 11548 /** 11549 * hdd_wlan_notify_modem_power_state() - notify FW with modem power status 11550 * @state: state 11551 * 11552 * This function notifies FW with modem power status 11553 * 11554 * Return: 0 if successful, error number otherwise 11555 */ hdd_wlan_notify_modem_power_state(int state)11556 int hdd_wlan_notify_modem_power_state(int state) 11557 { 11558 int status; 11559 QDF_STATUS qdf_status; 11560 struct hdd_context *hdd_ctx; 11561 mac_handle_t mac_handle; 11562 11563 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 11564 status = wlan_hdd_validate_context(hdd_ctx); 11565 if (status) 11566 return status; 11567 11568 mac_handle = hdd_ctx->mac_handle; 11569 if (!mac_handle) 11570 return -EINVAL; 11571 11572 qdf_status = sme_notify_modem_power_state(mac_handle, state); 11573 if (QDF_STATUS_SUCCESS != qdf_status) { 11574 hdd_err("Fail to send notification with modem power state %d", 11575 state); 11576 return -EINVAL; 11577 } 11578 return 0; 11579 } 11580 11581 /** 11582 * hdd_post_cds_enable_config() - HDD post cds start config helper 11583 * @hdd_ctx: Pointer to the HDD 11584 * 11585 * Return: None 11586 */ hdd_post_cds_enable_config(struct hdd_context * hdd_ctx)11587 QDF_STATUS hdd_post_cds_enable_config(struct hdd_context *hdd_ctx) 11588 { 11589 QDF_STATUS qdf_ret_status; 11590 11591 /* 11592 * Send ready indication to the HDD. This will kick off the MAC 11593 * into a 'running' state and should kick off an initial scan. 11594 */ 11595 qdf_ret_status = sme_hdd_ready_ind(hdd_ctx->mac_handle); 11596 if (!QDF_IS_STATUS_SUCCESS(qdf_ret_status)) { 11597 hdd_err("sme_hdd_ready_ind() failed with status code %08d [x%08x]", 11598 qdf_ret_status, qdf_ret_status); 11599 return QDF_STATUS_E_FAILURE; 11600 } 11601 11602 return QDF_STATUS_SUCCESS; 11603 } 11604 hdd_get_first_valid_adapter(struct hdd_context * hdd_ctx)11605 struct hdd_adapter *hdd_get_first_valid_adapter(struct hdd_context *hdd_ctx) 11606 { 11607 struct hdd_adapter *adapter, *next_adapter = NULL; 11608 wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_GET_FIRST_VALID_ADAPTER; 11609 11610 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 11611 dbgid) { 11612 if (adapter && adapter->magic == WLAN_HDD_ADAPTER_MAGIC) { 11613 hdd_adapter_dev_put_debug(adapter, dbgid); 11614 if (next_adapter) 11615 hdd_adapter_dev_put_debug(next_adapter, 11616 dbgid); 11617 return adapter; 11618 } 11619 hdd_adapter_dev_put_debug(adapter, dbgid); 11620 } 11621 11622 return NULL; 11623 } 11624 11625 /* wake lock APIs for HDD */ hdd_prevent_suspend(uint32_t reason)11626 void hdd_prevent_suspend(uint32_t reason) 11627 { 11628 qdf_wake_lock_acquire(&wlan_wake_lock, reason); 11629 } 11630 hdd_allow_suspend(uint32_t reason)11631 void hdd_allow_suspend(uint32_t reason) 11632 { 11633 qdf_wake_lock_release(&wlan_wake_lock, reason); 11634 } 11635 hdd_prevent_suspend_timeout(uint32_t timeout,uint32_t reason)11636 void hdd_prevent_suspend_timeout(uint32_t timeout, uint32_t reason) 11637 { 11638 cds_host_diag_log_work(&wlan_wake_lock, timeout, reason); 11639 qdf_wake_lock_timeout_acquire(&wlan_wake_lock, timeout); 11640 } 11641 11642 /* Initialize channel list in sme based on the country code */ hdd_set_sme_chan_list(struct hdd_context * hdd_ctx)11643 QDF_STATUS hdd_set_sme_chan_list(struct hdd_context *hdd_ctx) 11644 { 11645 return sme_init_chan_list(hdd_ctx->mac_handle, 11646 hdd_ctx->reg.cc_src); 11647 } 11648 11649 /** 11650 * hdd_is_5g_supported() - check if hardware supports 5GHz 11651 * @hdd_ctx: Pointer to the hdd context 11652 * 11653 * HDD function to know if hardware supports 5GHz 11654 * 11655 * Return: true if hardware supports 5GHz 11656 */ hdd_is_5g_supported(struct hdd_context * hdd_ctx)11657 bool hdd_is_5g_supported(struct hdd_context *hdd_ctx) 11658 { 11659 if (!hdd_ctx) 11660 return true; 11661 11662 if (hdd_ctx->curr_band != BAND_2G) 11663 return true; 11664 else 11665 return false; 11666 } 11667 hdd_is_2g_supported(struct hdd_context * hdd_ctx)11668 bool hdd_is_2g_supported(struct hdd_context *hdd_ctx) 11669 { 11670 if (!hdd_ctx) 11671 return false; 11672 11673 if (hdd_ctx->curr_band != BAND_5G) 11674 return true; 11675 else 11676 return false; 11677 } 11678 hdd_wiphy_init(struct hdd_context * hdd_ctx)11679 static int hdd_wiphy_init(struct hdd_context *hdd_ctx) 11680 { 11681 struct wiphy *wiphy; 11682 int ret_val; 11683 uint32_t channel_bonding_mode; 11684 11685 wiphy = hdd_ctx->wiphy; 11686 11687 /* 11688 * The channel information in 11689 * wiphy needs to be initialized before wiphy registration 11690 */ 11691 ret_val = hdd_regulatory_init(hdd_ctx, wiphy); 11692 if (ret_val) { 11693 hdd_err("regulatory init failed"); 11694 return ret_val; 11695 } 11696 11697 if (ucfg_pmo_get_suspend_mode(hdd_ctx->psoc) == PMO_SUSPEND_WOW) { 11698 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0)) 11699 wiphy->wowlan = &wowlan_support_reg_init; 11700 #else 11701 wiphy->wowlan.flags = WIPHY_WOWLAN_ANY | 11702 WIPHY_WOWLAN_MAGIC_PKT | 11703 WIPHY_WOWLAN_DISCONNECT | 11704 WIPHY_WOWLAN_SUPPORTS_GTK_REKEY | 11705 WIPHY_WOWLAN_GTK_REKEY_FAILURE | 11706 WIPHY_WOWLAN_EAP_IDENTITY_REQ | 11707 WIPHY_WOWLAN_4WAY_HANDSHAKE | 11708 WIPHY_WOWLAN_RFKILL_RELEASE; 11709 11710 wiphy->wowlan.n_patterns = (WOW_MAX_FILTER_LISTS * 11711 WOW_MAX_FILTERS_PER_LIST); 11712 wiphy->wowlan.pattern_min_len = WOW_MIN_PATTERN_SIZE; 11713 wiphy->wowlan.pattern_max_len = WOW_MAX_PATTERN_SIZE; 11714 #endif 11715 } 11716 11717 ucfg_mlme_get_channel_bonding_24ghz(hdd_ctx->psoc, 11718 &channel_bonding_mode); 11719 if (hdd_ctx->obss_scan_offload) { 11720 hdd_debug("wmi_service_obss_scan supported"); 11721 } else if (channel_bonding_mode) { 11722 hdd_debug("enable wpa_supp obss_scan"); 11723 wiphy->features |= NL80211_FEATURE_NEED_OBSS_SCAN; 11724 } 11725 11726 if (hdd_ctx->num_rf_chains == HDD_ANTENNA_MODE_2X2 && 11727 ucfg_mlme_is_chain_mask_supported(hdd_ctx->psoc)) { 11728 wiphy->available_antennas_tx = HDD_CHAIN_MODE_2X2; 11729 wiphy->available_antennas_rx = HDD_CHAIN_MODE_2X2; 11730 } 11731 /* registration of wiphy dev with cfg80211 */ 11732 ret_val = wlan_hdd_cfg80211_register(wiphy); 11733 if (0 > ret_val) { 11734 hdd_err("wiphy registration failed"); 11735 return ret_val; 11736 } 11737 11738 /* Check the kernel version for upstream commit aced43ce780dc5 that 11739 * has support for processing user cell_base hints when wiphy is 11740 * self managed or check the backport flag for the same. 11741 */ 11742 #if defined CFG80211_USER_HINT_CELL_BASE_SELF_MANAGED || \ 11743 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 18, 0)) 11744 hdd_send_wiphy_regd_sync_event(hdd_ctx); 11745 #endif 11746 11747 pld_increment_driver_load_cnt(hdd_ctx->parent_dev); 11748 11749 return ret_val; 11750 } 11751 11752 #ifdef WLAN_FEATURE_DP_BUS_BANDWIDTH 11753 #ifdef CLD_PM_QOS 11754 #define PLD_REMOVE_PM_QOS(x) 11755 #define PLD_REQUEST_PM_QOS(x, y) 11756 #define HDD_PM_QOS_HIGH_TPUT_LATENCY_US 1 11757 11758 /** 11759 * hdd_pm_qos_update_cpu_mask() - Prepare CPU mask for PM_qos voting 11760 * @mask: return variable of cpumask for the TPUT 11761 * @enable_perf_cluster: Enable PERF cluster or not 11762 * 11763 * By default, the function sets CPU mask for silver cluster unless 11764 * enable_perf_cluster is set as true. 11765 * 11766 * Return: none 11767 */ hdd_pm_qos_update_cpu_mask(cpumask_t * mask,bool enable_perf_cluster)11768 static inline void hdd_pm_qos_update_cpu_mask(cpumask_t *mask, 11769 bool enable_perf_cluster) 11770 { 11771 cpumask_set_cpu(0, mask); 11772 cpumask_set_cpu(1, mask); 11773 cpumask_set_cpu(2, mask); 11774 cpumask_set_cpu(3, mask); 11775 11776 if (enable_perf_cluster) { 11777 cpumask_set_cpu(4, mask); 11778 cpumask_set_cpu(5, mask); 11779 cpumask_set_cpu(6, mask); 11780 } 11781 } 11782 11783 #ifdef MSM_PLATFORM 11784 #define COPY_CPU_MASK(a, b) cpumask_copy(a, b) 11785 #define DUMP_CPU_AFFINE() hdd_info("Set cpu_mask %*pb for affine_cores", \ 11786 cpumask_pr_args(&hdd_ctx->pm_qos_req.cpus_affine)) 11787 #else 11788 #define COPY_CPU_MASK(a, b) /* no-op*/ 11789 #define DUMP_CPU_AFFINE() /* no-op*/ 11790 #endif 11791 11792 #ifdef CLD_DEV_PM_QOS 11793 _hdd_pm_qos_update_request(struct hdd_context * hdd_ctx,cpumask_t * pm_qos_cpu_mask,unsigned int latency)11794 static inline void _hdd_pm_qos_update_request(struct hdd_context *hdd_ctx, 11795 cpumask_t *pm_qos_cpu_mask, 11796 unsigned int latency) 11797 { 11798 int cpu; 11799 uint32_t default_latency; 11800 11801 default_latency = wlan_hdd_get_default_pm_qos_cpu_latency(); 11802 qdf_cpumask_copy(&hdd_ctx->qos_cpu_mask, pm_qos_cpu_mask); 11803 11804 if (qdf_cpumask_empty(pm_qos_cpu_mask)) { 11805 for_each_present_cpu(cpu) { 11806 dev_pm_qos_update_request( 11807 &hdd_ctx->pm_qos_req[cpu], 11808 default_latency); 11809 } 11810 hdd_debug("Empty mask %*pb: Set latency %u", 11811 qdf_cpumask_pr_args(&hdd_ctx->qos_cpu_mask), 11812 default_latency); 11813 } else { /* Set latency to default for CPUs not included in mask */ 11814 qdf_for_each_cpu_not(cpu, &hdd_ctx->qos_cpu_mask) { 11815 dev_pm_qos_update_request( 11816 &hdd_ctx->pm_qos_req[cpu], 11817 default_latency); 11818 } 11819 /* Set latency for CPUs included in mask */ 11820 qdf_for_each_cpu(cpu, &hdd_ctx->qos_cpu_mask) { 11821 dev_pm_qos_update_request( 11822 &hdd_ctx->pm_qos_req[cpu], 11823 latency); 11824 } 11825 hdd_debug("For qos_cpu_mask %*pb set latency %u", 11826 qdf_cpumask_pr_args(&hdd_ctx->qos_cpu_mask), 11827 latency); 11828 } 11829 } 11830 11831 /** 11832 * hdd_pm_qos_update_request() - API to request for pm_qos 11833 * @hdd_ctx: handle to hdd context 11834 * @pm_qos_cpu_mask: cpu_mask to apply 11835 * 11836 * Return: none 11837 */ hdd_pm_qos_update_request(struct hdd_context * hdd_ctx,cpumask_t * pm_qos_cpu_mask)11838 static void hdd_pm_qos_update_request(struct hdd_context *hdd_ctx, 11839 cpumask_t *pm_qos_cpu_mask) 11840 { 11841 unsigned int latency; 11842 11843 if (qdf_cpumask_empty(pm_qos_cpu_mask)) 11844 latency = wlan_hdd_get_default_pm_qos_cpu_latency(); 11845 else 11846 latency = HDD_PM_QOS_HIGH_TPUT_LATENCY_US; 11847 11848 _hdd_pm_qos_update_request(hdd_ctx, pm_qos_cpu_mask, latency); 11849 } 11850 hdd_pm_qos_add_request(struct hdd_context * hdd_ctx)11851 static inline void hdd_pm_qos_add_request(struct hdd_context *hdd_ctx) 11852 { 11853 struct device *cpu_dev; 11854 int cpu; 11855 uint32_t default_latency = wlan_hdd_get_default_pm_qos_cpu_latency(); 11856 11857 11858 qdf_cpumask_clear(&hdd_ctx->qos_cpu_mask); 11859 hdd_pm_qos_update_cpu_mask(&hdd_ctx->qos_cpu_mask, false); 11860 11861 for_each_present_cpu(cpu) { 11862 cpu_dev = get_cpu_device(cpu); 11863 dev_pm_qos_add_request(cpu_dev, &hdd_ctx->pm_qos_req[cpu], 11864 DEV_PM_QOS_RESUME_LATENCY, 11865 default_latency); 11866 hdd_debug("Set qos_cpu_mask %*pb for affine_cores", 11867 cpumask_pr_args(&hdd_ctx->qos_cpu_mask)); 11868 } 11869 } 11870 hdd_pm_qos_remove_request(struct hdd_context * hdd_ctx)11871 static inline void hdd_pm_qos_remove_request(struct hdd_context *hdd_ctx) 11872 { 11873 int cpu; 11874 11875 for_each_present_cpu(cpu) { 11876 dev_pm_qos_remove_request(&hdd_ctx->pm_qos_req[cpu]); 11877 hdd_debug("Remove dev_pm_qos_request for all cpus: %d", cpu); 11878 } 11879 qdf_cpumask_clear(&hdd_ctx->qos_cpu_mask); 11880 } 11881 11882 #else /* CLD_DEV_PM_QOS */ 11883 11884 #if defined(CONFIG_SMP) && defined(MSM_PLATFORM) 11885 /** 11886 * hdd_set_default_pm_qos_mask() - Update PM_qos request for AFFINE_CORES 11887 * @hdd_ctx: handle to hdd context 11888 * 11889 * Return: none 11890 */ hdd_set_default_pm_qos_mask(struct hdd_context * hdd_ctx)11891 static inline void hdd_set_default_pm_qos_mask(struct hdd_context *hdd_ctx) 11892 { 11893 hdd_ctx->pm_qos_req.type = PM_QOS_REQ_AFFINE_CORES; 11894 qdf_cpumask_clear(&hdd_ctx->pm_qos_req.cpus_affine); 11895 hdd_pm_qos_update_cpu_mask(&hdd_ctx->pm_qos_req.cpus_affine, false); 11896 } 11897 #else hdd_set_default_pm_qos_mask(struct hdd_context * hdd_ctx)11898 static inline void hdd_set_default_pm_qos_mask(struct hdd_context *hdd_ctx) 11899 { 11900 } 11901 #endif 11902 11903 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 7, 0)) 11904 /** 11905 * hdd_pm_qos_update_request() - API to request for pm_qos 11906 * @hdd_ctx: handle to hdd context 11907 * @pm_qos_cpu_mask: cpu_mask to apply 11908 * 11909 * Return: none 11910 */ hdd_pm_qos_update_request(struct hdd_context * hdd_ctx,cpumask_t * pm_qos_cpu_mask)11911 static inline void hdd_pm_qos_update_request(struct hdd_context *hdd_ctx, 11912 cpumask_t *pm_qos_cpu_mask) 11913 { 11914 COPY_CPU_MASK(&hdd_ctx->pm_qos_req.cpus_affine, pm_qos_cpu_mask); 11915 11916 if (cpumask_empty(pm_qos_cpu_mask)) 11917 cpu_latency_qos_update_request(&hdd_ctx->pm_qos_req, 11918 PM_QOS_DEFAULT_VALUE); 11919 else 11920 cpu_latency_qos_update_request(&hdd_ctx->pm_qos_req, 1); 11921 } 11922 hdd_pm_qos_add_request(struct hdd_context * hdd_ctx)11923 static inline void hdd_pm_qos_add_request(struct hdd_context *hdd_ctx) 11924 { 11925 hdd_set_default_pm_qos_mask(hdd_ctx); 11926 cpu_latency_qos_add_request(&hdd_ctx->pm_qos_req, PM_QOS_DEFAULT_VALUE); 11927 DUMP_CPU_AFFINE(); 11928 } 11929 hdd_pm_qos_remove_request(struct hdd_context * hdd_ctx)11930 static inline void hdd_pm_qos_remove_request(struct hdd_context *hdd_ctx) 11931 { 11932 cpu_latency_qos_remove_request(&hdd_ctx->pm_qos_req); 11933 } 11934 #else hdd_pm_qos_update_request(struct hdd_context * hdd_ctx,cpumask_t * pm_qos_cpu_mask)11935 static inline void hdd_pm_qos_update_request(struct hdd_context *hdd_ctx, 11936 cpumask_t *pm_qos_cpu_mask) 11937 { 11938 COPY_CPU_MASK(&hdd_ctx->pm_qos_req.cpus_affine, pm_qos_cpu_mask); 11939 11940 if (cpumask_empty(pm_qos_cpu_mask)) 11941 pm_qos_update_request(&hdd_ctx->pm_qos_req, 11942 PM_QOS_DEFAULT_VALUE); 11943 else 11944 pm_qos_update_request(&hdd_ctx->pm_qos_req, 1); 11945 } 11946 hdd_pm_qos_add_request(struct hdd_context * hdd_ctx)11947 static inline void hdd_pm_qos_add_request(struct hdd_context *hdd_ctx) 11948 { 11949 hdd_set_default_pm_qos_mask(hdd_ctx); 11950 pm_qos_add_request(&hdd_ctx->pm_qos_req, PM_QOS_CPU_DMA_LATENCY, 11951 PM_QOS_DEFAULT_VALUE); 11952 DUMP_CPU_AFFINE(); 11953 } 11954 hdd_pm_qos_remove_request(struct hdd_context * hdd_ctx)11955 static inline void hdd_pm_qos_remove_request(struct hdd_context *hdd_ctx) 11956 { 11957 pm_qos_remove_request(&hdd_ctx->pm_qos_req); 11958 } 11959 #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(5, 7, 0) */ 11960 #endif /* CLD_DEV_PM_QOS */ 11961 11962 #else /* CLD_PM_QOS */ 11963 #define PLD_REMOVE_PM_QOS(x) pld_remove_pm_qos(x) 11964 #define PLD_REQUEST_PM_QOS(x, y) pld_request_pm_qos(x, y) 11965 hdd_pm_qos_add_request(struct hdd_context * hdd_ctx)11966 static inline void hdd_pm_qos_add_request(struct hdd_context *hdd_ctx) 11967 { 11968 } 11969 hdd_pm_qos_remove_request(struct hdd_context * hdd_ctx)11970 static inline void hdd_pm_qos_remove_request(struct hdd_context *hdd_ctx) 11971 { 11972 } 11973 hdd_pm_qos_update_cpu_mask(cpumask_t * mask,bool high_throughput)11974 static inline void hdd_pm_qos_update_cpu_mask(cpumask_t *mask, 11975 bool high_throughput) 11976 { 11977 } 11978 hdd_pm_qos_update_request(struct hdd_context * hdd_ctx,cpumask_t * pm_qos_cpu_mask)11979 static inline void hdd_pm_qos_update_request(struct hdd_context *hdd_ctx, 11980 cpumask_t *pm_qos_cpu_mask) 11981 { 11982 } 11983 #endif /* CLD_PM_QOS */ 11984 11985 #if defined(CLD_PM_QOS) 11986 #if defined(CLD_DEV_PM_QOS) wlan_hdd_set_pm_qos_request(struct hdd_context * hdd_ctx,bool pm_qos_request)11987 void wlan_hdd_set_pm_qos_request(struct hdd_context *hdd_ctx, 11988 bool pm_qos_request) 11989 { 11990 cpumask_t pm_qos_cpu_mask; 11991 11992 cpumask_clear(&pm_qos_cpu_mask); 11993 if (pm_qos_request) { 11994 hdd_ctx->pm_qos_request = true; 11995 if (!hdd_ctx->hbw_requested) { 11996 hdd_pm_qos_update_cpu_mask(&pm_qos_cpu_mask, true); 11997 hdd_pm_qos_update_request(hdd_ctx, &pm_qos_cpu_mask); 11998 hdd_ctx->hbw_requested = true; 11999 } 12000 } else { 12001 if (hdd_ctx->hbw_requested) { 12002 hdd_pm_qos_update_cpu_mask(&pm_qos_cpu_mask, false); 12003 hdd_pm_qos_update_request(hdd_ctx, &pm_qos_cpu_mask); 12004 hdd_ctx->hbw_requested = false; 12005 } 12006 hdd_ctx->pm_qos_request = false; 12007 } 12008 } 12009 #else /* CLD_DEV_PM_QOS */ 12010 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 7, 0)) wlan_hdd_set_pm_qos_request(struct hdd_context * hdd_ctx,bool pm_qos_request)12011 void wlan_hdd_set_pm_qos_request(struct hdd_context *hdd_ctx, 12012 bool pm_qos_request) 12013 { 12014 if (pm_qos_request) { 12015 hdd_ctx->pm_qos_request = true; 12016 if (!hdd_ctx->hbw_requested) { 12017 cpumask_setall(&hdd_ctx->pm_qos_req.cpus_affine); 12018 cpu_latency_qos_update_request( 12019 &hdd_ctx->pm_qos_req, 12020 DISABLE_KRAIT_IDLE_PS_VAL); 12021 hdd_ctx->hbw_requested = true; 12022 } 12023 } else { 12024 if (hdd_ctx->hbw_requested) { 12025 cpumask_clear(&hdd_ctx->pm_qos_req.cpus_affine); 12026 cpu_latency_qos_update_request(&hdd_ctx->pm_qos_req, 12027 PM_QOS_DEFAULT_VALUE); 12028 hdd_ctx->hbw_requested = false; 12029 } 12030 hdd_ctx->pm_qos_request = false; 12031 } 12032 } 12033 #else /* (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 7, 0)) */ wlan_hdd_set_pm_qos_request(struct hdd_context * hdd_ctx,bool pm_qos_request)12034 void wlan_hdd_set_pm_qos_request(struct hdd_context *hdd_ctx, 12035 bool pm_qos_request) 12036 { 12037 if (pm_qos_request) { 12038 hdd_ctx->pm_qos_request = true; 12039 if (!hdd_ctx->hbw_requested) { 12040 cpumask_setall(&hdd_ctx->pm_qos_req.cpus_affine); 12041 pm_qos_update_request(&hdd_ctx->pm_qos_req, 12042 DISABLE_KRAIT_IDLE_PS_VAL); 12043 hdd_ctx->hbw_requested = true; 12044 } 12045 } else { 12046 if (hdd_ctx->hbw_requested) { 12047 cpumask_clear(&hdd_ctx->pm_qos_req.cpus_affine); 12048 pm_qos_update_request(&hdd_ctx->pm_qos_req, 12049 PM_QOS_DEFAULT_VALUE); 12050 hdd_ctx->hbw_requested = false; 12051 } 12052 hdd_ctx->pm_qos_request = false; 12053 } 12054 } 12055 #endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 7, 0)) */ 12056 #endif /* CLD_DEV_PM_QOS*/ 12057 #endif /* CLD_PM_QOS */ 12058 12059 #define HDD_BW_GET_DIFF(_x, _y) (unsigned long)((ULONG_MAX - (_y)) + (_x) + 1) 12060 12061 #ifdef WLAN_FEATURE_MSCS 12062 12063 static hdd_send_mscs_action_frame(struct wlan_hdd_link_info * link_info)12064 void hdd_send_mscs_action_frame(struct wlan_hdd_link_info *link_info) 12065 { 12066 struct hdd_context *hdd_ctx = link_info->adapter->hdd_ctx; 12067 uint64_t mscs_vo_pkt_delta; 12068 unsigned long tx_vo_pkts = 0; 12069 unsigned int cpu; 12070 struct hdd_tx_rx_stats *stats = &link_info->hdd_stats.tx_rx_stats; 12071 uint32_t bus_bw_compute_interval; 12072 12073 /* 12074 * To disable MSCS feature in driver set mscs_pkt_threshold = 0 12075 * in ini file. 12076 */ 12077 if (!hdd_ctx->config->mscs_pkt_threshold) 12078 return; 12079 12080 for (cpu = 0; cpu < NUM_CPUS; cpu++) 12081 tx_vo_pkts += stats->per_cpu[cpu].tx_classified_ac[SME_AC_VO]; 12082 12083 if (!link_info->mscs_counter) 12084 link_info->mscs_prev_tx_vo_pkts = tx_vo_pkts; 12085 12086 link_info->mscs_counter++; 12087 bus_bw_compute_interval = 12088 ucfg_dp_get_bus_bw_compute_interval(hdd_ctx->psoc); 12089 if (link_info->mscs_counter * bus_bw_compute_interval >= 12090 hdd_ctx->config->mscs_voice_interval * 1000) { 12091 link_info->mscs_counter = 0; 12092 mscs_vo_pkt_delta = 12093 HDD_BW_GET_DIFF(tx_vo_pkts, 12094 link_info->mscs_prev_tx_vo_pkts); 12095 if (mscs_vo_pkt_delta > hdd_ctx->config->mscs_pkt_threshold && 12096 !mlme_get_is_mscs_req_sent(link_info->vdev)) 12097 sme_send_mscs_action_frame(link_info->vdev_id); 12098 } 12099 } 12100 #else 12101 static inline hdd_send_mscs_action_frame(struct wlan_hdd_link_info * link_info)12102 void hdd_send_mscs_action_frame(struct wlan_hdd_link_info *link_info) 12103 { 12104 } 12105 #endif 12106 #endif /*WLAN_FEATURE_DP_BUS_BANDWIDTH*/ 12107 12108 /** 12109 * wlan_hdd_sta_get_dot11mode() - GET AP client count 12110 * @context: HDD context 12111 * @netdev: netdev 12112 * @dot11_mode: variable in which mode need to update. 12113 * 12114 * Return: true on success else false 12115 */ 12116 static inline wlan_hdd_sta_get_dot11mode(hdd_cb_handle context,qdf_netdev_t netdev,enum qca_wlan_802_11_mode * dot11_mode)12117 bool wlan_hdd_sta_get_dot11mode(hdd_cb_handle context, qdf_netdev_t netdev, 12118 enum qca_wlan_802_11_mode *dot11_mode) 12119 { 12120 struct hdd_context *hdd_ctx; 12121 struct wlan_hdd_link_info *link_info; 12122 struct hdd_station_ctx *sta_ctx; 12123 struct hdd_adapter *adapter; 12124 enum csr_cfgdot11mode mode; 12125 12126 hdd_ctx = hdd_cb_handle_to_context(context); 12127 if (!hdd_ctx) 12128 return false; 12129 12130 adapter = WLAN_HDD_GET_PRIV_PTR(netdev); 12131 if (!adapter) 12132 return false; 12133 12134 link_info = adapter->deflink; 12135 12136 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(link_info); 12137 mode = sta_ctx->conn_info.dot11mode; 12138 *dot11_mode = hdd_convert_cfgdot11mode_to_80211mode(mode); 12139 return true; 12140 } 12141 12142 /** 12143 * wlan_hdd_get_ap_client_count() - GET AP client count 12144 * @context: HDD context 12145 * @netdev: netdev 12146 * @client_count: variable in which number of client need to update. 12147 * 12148 * Return: true on success else false 12149 */ 12150 static inline wlan_hdd_get_ap_client_count(hdd_cb_handle context,qdf_netdev_t netdev,uint16_t * client_count)12151 bool wlan_hdd_get_ap_client_count(hdd_cb_handle context, qdf_netdev_t netdev, 12152 uint16_t *client_count) 12153 { 12154 struct hdd_context *hdd_ctx; 12155 struct wlan_hdd_link_info *link_info; 12156 struct hdd_adapter *adapter; 12157 struct hdd_ap_ctx *ap_ctx; 12158 enum qca_wlan_802_11_mode i; 12159 12160 hdd_ctx = hdd_cb_handle_to_context(context); 12161 if (!hdd_ctx) { 12162 hdd_err("hdd ctx is null"); 12163 return false; 12164 } 12165 12166 adapter = WLAN_HDD_GET_PRIV_PTR(netdev); 12167 if (!adapter) { 12168 hdd_err("adapter is null"); 12169 return false; 12170 } 12171 12172 link_info = adapter->deflink; 12173 ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(link_info); 12174 if (!ap_ctx->ap_active) 12175 return false; 12176 12177 for (i = QCA_WLAN_802_11_MODE_11B; i < QCA_WLAN_802_11_MODE_INVALID; 12178 i++) 12179 client_count[i] = ap_ctx->client_count[i]; 12180 12181 return true; 12182 } 12183 12184 /** 12185 * wlan_hdd_sta_ndi_connected() - Check if NDI connected 12186 * @context: HDD context 12187 * @netdev: netdev 12188 * 12189 * Return: true if NDI connected else false 12190 */ 12191 static inline wlan_hdd_sta_ndi_connected(hdd_cb_handle context,qdf_netdev_t netdev)12192 bool wlan_hdd_sta_ndi_connected(hdd_cb_handle context, qdf_netdev_t netdev) 12193 { 12194 struct hdd_adapter *adapter; 12195 struct hdd_context *hdd_ctx; 12196 struct wlan_hdd_link_info *link_info; 12197 struct hdd_station_ctx *sta_ctx; 12198 12199 hdd_ctx = hdd_cb_handle_to_context(context); 12200 if (!hdd_ctx) { 12201 hdd_err("hdd_ctx is null"); 12202 return false; 12203 } 12204 12205 adapter = WLAN_HDD_GET_PRIV_PTR(netdev); 12206 if (!adapter) { 12207 hdd_err("adapter is null"); 12208 return false; 12209 } 12210 12211 link_info = adapter->deflink; 12212 12213 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(link_info); 12214 if (sta_ctx->conn_info.conn_state != eConnectionState_NdiConnected) 12215 return false; 12216 12217 return true; 12218 } 12219 12220 /** 12221 * wlan_hdd_pktlog_enable_disable() - Enable/Disable packet logging 12222 * @context: HDD context 12223 * @enable_disable_flag: Flag to enable/disable 12224 * @user_triggered: triggered through iwpriv 12225 * @size: buffer size to be used for packetlog 12226 * 12227 * Return: 0 on success; error number otherwise 12228 */ 12229 static inline wlan_hdd_pktlog_enable_disable(hdd_cb_handle context,bool enable_disable_flag,uint8_t user_triggered,int size)12230 int wlan_hdd_pktlog_enable_disable(hdd_cb_handle context, 12231 bool enable_disable_flag, 12232 uint8_t user_triggered, int size) 12233 { 12234 struct hdd_context *hdd_ctx = hdd_cb_handle_to_context(context); 12235 12236 if (!hdd_ctx) { 12237 hdd_err("hdd_ctx is null"); 12238 return -EINVAL; 12239 } 12240 return hdd_pktlog_enable_disable(hdd_ctx, enable_disable_flag, 12241 user_triggered, size); 12242 } 12243 12244 /** 12245 * wlan_hdd_is_roaming_in_progress() - Check if roaming is in progress 12246 * @context: HDD context 12247 * 12248 * Return: true if roaming is in progress else false 12249 */ wlan_hdd_is_roaming_in_progress(hdd_cb_handle context)12250 static inline bool wlan_hdd_is_roaming_in_progress(hdd_cb_handle context) 12251 { 12252 struct hdd_context *hdd_ctx = hdd_cb_handle_to_context(context); 12253 12254 if (!hdd_ctx) { 12255 hdd_err("hdd_ctx is null"); 12256 return false; 12257 } 12258 return hdd_is_roaming_in_progress(hdd_ctx); 12259 } 12260 12261 /** 12262 * hdd_is_ap_active() - Check if AP is active 12263 * @context: HDD context 12264 * @netdev: netdev 12265 * 12266 * Return: true if AP active else false 12267 */ hdd_is_ap_active(hdd_cb_handle context,qdf_netdev_t netdev)12268 static inline bool hdd_is_ap_active(hdd_cb_handle context, qdf_netdev_t netdev) 12269 { 12270 struct hdd_adapter *adapter; 12271 struct hdd_context *hdd_ctx; 12272 struct wlan_hdd_link_info *link_info; 12273 12274 hdd_ctx = hdd_cb_handle_to_context(context); 12275 if (!hdd_ctx) { 12276 hdd_err("hdd_ctx is null"); 12277 return false; 12278 } 12279 12280 adapter = WLAN_HDD_GET_PRIV_PTR(netdev); 12281 if (!adapter) { 12282 hdd_err("adapter is null"); 12283 return false; 12284 } 12285 12286 link_info = adapter->deflink; 12287 return WLAN_HDD_GET_AP_CTX_PTR(link_info)->ap_active; 12288 } 12289 12290 /** 12291 * wlan_hdd_napi_apply_throughput_policy() - Apply NAPI policy 12292 * @context: HDD context 12293 * @tx_packets: tx_packets 12294 * @rx_packets: rx_packets 12295 * 12296 * Return: 0 on success else error code 12297 */ 12298 static inline wlan_hdd_napi_apply_throughput_policy(hdd_cb_handle context,uint64_t tx_packets,uint64_t rx_packets)12299 int wlan_hdd_napi_apply_throughput_policy(hdd_cb_handle context, 12300 uint64_t tx_packets, 12301 uint64_t rx_packets) 12302 { 12303 struct hdd_context *hdd_ctx = hdd_cb_handle_to_context(context); 12304 int rc = 0; 12305 12306 if (!hdd_ctx) { 12307 hdd_err("hdd_ctx is null"); 12308 return 0; 12309 } 12310 if (hdd_ctx->config->napi_cpu_affinity_mask) 12311 rc = hdd_napi_apply_throughput_policy(hdd_ctx, tx_packets, 12312 rx_packets); 12313 return rc; 12314 } 12315 12316 /** 12317 * hdd_is_link_adapter() - Check if adapter is link adapter 12318 * @context: HDD context 12319 * @vdev_id: Vdev ID 12320 * 12321 * Return: true if link adapter else false 12322 */ hdd_is_link_adapter(hdd_cb_handle context,uint8_t vdev_id)12323 static inline bool hdd_is_link_adapter(hdd_cb_handle context, uint8_t vdev_id) 12324 { 12325 struct hdd_context *hdd_ctx; 12326 struct wlan_hdd_link_info *link_info; 12327 12328 hdd_ctx = hdd_cb_handle_to_context(context); 12329 if (!hdd_ctx) { 12330 hdd_err("hdd_ctx is null"); 12331 return false; 12332 } 12333 12334 link_info = hdd_get_link_info_by_vdev(hdd_ctx, vdev_id); 12335 if (!link_info) { 12336 hdd_err("Invalid vdev"); 12337 return false; 12338 } 12339 return hdd_adapter_is_link_adapter(link_info->adapter); 12340 } 12341 12342 /** 12343 * hdd_get_pause_map() - Get pause map value 12344 * @context: HDD context 12345 * @netdev: netdev 12346 * 12347 * Return: pause map value 12348 */ 12349 static inline hdd_get_pause_map(hdd_cb_handle context,qdf_netdev_t netdev)12350 uint32_t hdd_get_pause_map(hdd_cb_handle context, qdf_netdev_t netdev) 12351 { 12352 struct hdd_adapter *adapter; 12353 12354 adapter = WLAN_HDD_GET_PRIV_PTR(netdev); 12355 if (!adapter) { 12356 hdd_err("adapter is null"); 12357 return 0; 12358 } 12359 12360 return adapter->pause_map; 12361 } 12362 12363 /** 12364 * hdd_any_adapter_connected() - Check if any adapter connected. 12365 * @context: HDD context 12366 * 12367 * Return: True if connected else false. 12368 */ hdd_any_adapter_connected(hdd_cb_handle context)12369 static inline bool hdd_any_adapter_connected(hdd_cb_handle context) 12370 { 12371 struct hdd_context *hdd_ctx = hdd_cb_handle_to_context(context); 12372 12373 if (!hdd_ctx) { 12374 hdd_err("hdd_ctx is null"); 12375 return false; 12376 } 12377 12378 return hdd_is_any_adapter_connected(hdd_ctx); 12379 } 12380 12381 #ifdef WLAN_FEATURE_DP_BUS_BANDWIDTH 12382 /** 12383 * hdd_pld_request_pm_qos() - Request PLD PM QoS request 12384 * @context: HDD context 12385 * 12386 * Return: None 12387 */ hdd_pld_request_pm_qos(hdd_cb_handle context)12388 static inline void hdd_pld_request_pm_qos(hdd_cb_handle context) 12389 { 12390 struct hdd_context *hdd_ctx = hdd_cb_handle_to_context(context); 12391 12392 if (!hdd_ctx) { 12393 hdd_err("hdd_ctx is null"); 12394 return; 12395 } 12396 12397 if (!hdd_ctx->hbw_requested) { 12398 PLD_REQUEST_PM_QOS(hdd_ctx->parent_dev, 1); 12399 hdd_ctx->hbw_requested = true; 12400 } 12401 } 12402 12403 /** 12404 * hdd_pld_remove_pm_qos() - Remove PLD PM QoS request 12405 * @context: HDD context 12406 * 12407 * Return: None 12408 */ hdd_pld_remove_pm_qos(hdd_cb_handle context)12409 static inline void hdd_pld_remove_pm_qos(hdd_cb_handle context) 12410 { 12411 struct hdd_context *hdd_ctx = hdd_cb_handle_to_context(context); 12412 12413 if (!hdd_ctx) { 12414 hdd_err("hdd_ctx is null"); 12415 return; 12416 } 12417 12418 if (hdd_ctx->hbw_requested && 12419 !hdd_ctx->pm_qos_request) { 12420 PLD_REMOVE_PM_QOS(hdd_ctx->parent_dev); 12421 hdd_ctx->hbw_requested = false; 12422 } 12423 } 12424 12425 /** 12426 * wlan_hdd_pm_qos_update_request() - Update PM QoS request 12427 * @context: HDD context 12428 * @pm_qos_cpu_mask: CPU mask 12429 * 12430 * Return: None 12431 */ 12432 static inline void wlan_hdd_pm_qos_update_request(hdd_cb_handle context,cpumask_t * pm_qos_cpu_mask)12433 wlan_hdd_pm_qos_update_request(hdd_cb_handle context, 12434 cpumask_t *pm_qos_cpu_mask) 12435 { 12436 struct hdd_context *hdd_ctx = hdd_cb_handle_to_context(context); 12437 12438 if (!hdd_ctx) { 12439 hdd_err("hdd_ctx is null"); 12440 return; 12441 } 12442 12443 if (!hdd_ctx->pm_qos_request) 12444 hdd_pm_qos_update_request(hdd_ctx, pm_qos_cpu_mask); 12445 } 12446 12447 /** 12448 * wlan_hdd_pm_qos_add_request() - Add PM QoS request 12449 * @context: HDD context 12450 * 12451 * Return: None 12452 */ wlan_hdd_pm_qos_add_request(hdd_cb_handle context)12453 static inline void wlan_hdd_pm_qos_add_request(hdd_cb_handle context) 12454 { 12455 struct hdd_context *hdd_ctx = hdd_cb_handle_to_context(context); 12456 12457 if (!hdd_ctx) { 12458 hdd_err("hdd_ctx is null"); 12459 return; 12460 } 12461 12462 hdd_pm_qos_add_request(hdd_ctx); 12463 } 12464 12465 /** 12466 * wlan_hdd_pm_qos_remove_request() - remove PM QoS request 12467 * @context: HDD context 12468 * 12469 * Return: None 12470 */ wlan_hdd_pm_qos_remove_request(hdd_cb_handle context)12471 static inline void wlan_hdd_pm_qos_remove_request(hdd_cb_handle context) 12472 { 12473 struct hdd_context *hdd_ctx = hdd_cb_handle_to_context(context); 12474 12475 if (!hdd_ctx) { 12476 hdd_err("hdd_ctx is null"); 12477 return; 12478 } 12479 12480 hdd_pm_qos_remove_request(hdd_ctx); 12481 } 12482 12483 /** 12484 * wlan_hdd_send_mscs_action_frame() - Send MSCS action frame 12485 * @context: HDD context 12486 * @netdev: netdev 12487 * 12488 * Return: None 12489 */ wlan_hdd_send_mscs_action_frame(hdd_cb_handle context,qdf_netdev_t netdev)12490 static inline void wlan_hdd_send_mscs_action_frame(hdd_cb_handle context, 12491 qdf_netdev_t netdev) 12492 { 12493 struct hdd_adapter *adapter; 12494 struct wlan_hdd_link_info *link_info; 12495 12496 adapter = WLAN_HDD_GET_PRIV_PTR(netdev); 12497 if (!adapter) { 12498 hdd_err("adapter is null"); 12499 return; 12500 } 12501 12502 link_info = adapter->deflink; 12503 hdd_send_mscs_action_frame(link_info); 12504 } 12505 12506 #else hdd_pld_remove_pm_qos(hdd_cb_handle context)12507 static inline void hdd_pld_remove_pm_qos(hdd_cb_handle context) 12508 { 12509 } 12510 hdd_pld_request_pm_qos(hdd_cb_handle context)12511 static inline void hdd_pld_request_pm_qos(hdd_cb_handle context) 12512 { 12513 } 12514 12515 static inline void wlan_hdd_pm_qos_update_request(hdd_cb_handle context,cpumask_t * pm_qos_cpu_mask)12516 wlan_hdd_pm_qos_update_request(hdd_cb_handle context, 12517 cpumask_t *pm_qos_cpu_mask) 12518 { 12519 } 12520 wlan_hdd_pm_qos_add_request(hdd_cb_handle context)12521 static inline void wlan_hdd_pm_qos_add_request(hdd_cb_handle context) 12522 { 12523 } 12524 wlan_hdd_pm_qos_remove_request(hdd_cb_handle context)12525 static inline void wlan_hdd_pm_qos_remove_request(hdd_cb_handle context) 12526 { 12527 } 12528 wlan_hdd_send_mscs_action_frame(hdd_cb_handle context,qdf_netdev_t netdev)12529 static inline void wlan_hdd_send_mscs_action_frame(hdd_cb_handle context, 12530 qdf_netdev_t netdev) 12531 { 12532 } 12533 #endif 12534 12535 #if defined(WLAN_FEATURE_ROAM_OFFLOAD) && \ 12536 defined(FEATURE_RX_LINKSPEED_ROAM_TRIGGER) wlan_hdd_link_speed_update(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id,bool is_link_speed_good)12537 void wlan_hdd_link_speed_update(struct wlan_objmgr_psoc *psoc, 12538 uint8_t vdev_id, 12539 bool is_link_speed_good) 12540 { 12541 ucfg_cm_roam_link_speed_update(psoc, vdev_id, is_link_speed_good); 12542 } 12543 #endif 12544 12545 /** 12546 * hdd_dp_register_callbacks() - Register DP callbacks with HDD 12547 * @hdd_ctx: HDD context 12548 * 12549 * Return: None 12550 */ hdd_dp_register_callbacks(struct hdd_context * hdd_ctx)12551 static void hdd_dp_register_callbacks(struct hdd_context *hdd_ctx) 12552 { 12553 struct wlan_dp_psoc_callbacks cb_obj = {0}; 12554 12555 cb_obj.callback_ctx = (hdd_cb_handle)hdd_ctx; 12556 cb_obj.wlan_dp_sta_get_dot11mode = wlan_hdd_sta_get_dot11mode; 12557 cb_obj.wlan_dp_get_ap_client_count = wlan_hdd_get_ap_client_count; 12558 cb_obj.wlan_dp_sta_ndi_connected = wlan_hdd_sta_ndi_connected; 12559 cb_obj.dp_any_adapter_connected = hdd_any_adapter_connected; 12560 cb_obj.dp_send_svc_nlink_msg = wlan_hdd_send_svc_nlink_msg; 12561 cb_obj.dp_pld_remove_pm_qos = hdd_pld_remove_pm_qos; 12562 cb_obj.dp_pld_request_pm_qos = hdd_pld_request_pm_qos; 12563 cb_obj.dp_pktlog_enable_disable = wlan_hdd_pktlog_enable_disable; 12564 cb_obj.dp_pm_qos_update_request = wlan_hdd_pm_qos_update_request; 12565 cb_obj.dp_pm_qos_add_request = wlan_hdd_pm_qos_add_request; 12566 cb_obj.dp_pm_qos_remove_request = wlan_hdd_pm_qos_remove_request; 12567 cb_obj.dp_send_mscs_action_frame = wlan_hdd_send_mscs_action_frame; 12568 cb_obj.dp_is_roaming_in_progress = wlan_hdd_is_roaming_in_progress; 12569 cb_obj.wlan_dp_display_tx_multiq_stats = 12570 wlan_hdd_display_tx_multiq_stats; 12571 cb_obj.wlan_dp_display_netif_queue_history = 12572 wlan_hdd_display_netif_queue_history; 12573 cb_obj.dp_is_ap_active = hdd_is_ap_active; 12574 cb_obj.dp_napi_apply_throughput_policy = 12575 wlan_hdd_napi_apply_throughput_policy; 12576 cb_obj.dp_is_link_adapter = hdd_is_link_adapter; 12577 cb_obj.dp_nud_failure_work = hdd_nud_failure_work; 12578 cb_obj.dp_get_pause_map = hdd_get_pause_map; 12579 12580 cb_obj.dp_get_netdev_by_vdev_mac = 12581 hdd_get_netdev_by_vdev_mac; 12582 cb_obj.dp_get_tx_resource = hdd_get_tx_resource; 12583 cb_obj.dp_get_tx_flow_low_watermark = hdd_get_tx_flow_low_watermark; 12584 cb_obj.dp_get_tsf_time = hdd_get_tsf_time_cb; 12585 cb_obj.dp_tsf_timestamp_rx = hdd_tsf_timestamp_rx; 12586 cb_obj.dp_gro_rx_legacy_get_napi = hdd_legacy_gro_get_napi; 12587 cb_obj.link_monitoring_cb = wlan_hdd_link_speed_update; 12588 12589 os_if_dp_register_hdd_callbacks(hdd_ctx->psoc, &cb_obj); 12590 } 12591 12592 /** 12593 * __hdd_adapter_param_update_work() - Gist of the work to process 12594 * netdev feature update. 12595 * @adapter: pointer to adapter structure 12596 * 12597 * This function assumes that the adapter pointer is always valid. 12598 * So the caller should always validate adapter pointer before calling 12599 * this function 12600 * 12601 * Returns: None 12602 */ 12603 static inline void __hdd_adapter_param_update_work(struct hdd_adapter * adapter)12604 __hdd_adapter_param_update_work(struct hdd_adapter *adapter) 12605 { 12606 /** 12607 * This check is needed in case the work got scheduled after the 12608 * interface got disconnected. 12609 * Netdev features update is to be done only after the connection, 12610 * since the connection mode plays an important role in identifying 12611 * the features that are to be updated. 12612 * So in case of interface disconnect skip feature update. 12613 */ 12614 if (!hdd_cm_is_vdev_associated(adapter->deflink)) 12615 return; 12616 12617 hdd_netdev_update_features(adapter); 12618 } 12619 12620 /** 12621 * hdd_adapter_param_update_work() - work to process the netdev features 12622 * update. 12623 * @arg: private data passed to work 12624 * 12625 * Returns: None 12626 */ hdd_adapter_param_update_work(void * arg)12627 static void hdd_adapter_param_update_work(void *arg) 12628 { 12629 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 12630 struct hdd_adapter *adapter = arg; 12631 struct osif_vdev_sync *vdev_sync; 12632 int errno; 12633 12634 if (!hdd_ctx) 12635 return; 12636 12637 hdd_adapter_ops_record_event(hdd_ctx, 12638 WLAN_HDD_ADAPTER_OPS_WORK_SCHED, 12639 WLAN_INVALID_VDEV_ID); 12640 12641 if (hdd_validate_adapter(adapter)) 12642 return; 12643 12644 errno = osif_vdev_sync_op_start(adapter->dev, &vdev_sync); 12645 if (errno) 12646 return; 12647 12648 __hdd_adapter_param_update_work(adapter); 12649 12650 osif_vdev_sync_op_stop(vdev_sync); 12651 } 12652 hdd_init_adapter_ops_wq(struct hdd_context * hdd_ctx)12653 QDF_STATUS hdd_init_adapter_ops_wq(struct hdd_context *hdd_ctx) 12654 { 12655 hdd_enter(); 12656 12657 hdd_ctx->adapter_ops_wq = 12658 qdf_alloc_high_prior_ordered_workqueue("hdd_adapter_ops_wq"); 12659 if (!hdd_ctx->adapter_ops_wq) 12660 return QDF_STATUS_E_NOMEM; 12661 12662 hdd_exit(); 12663 12664 return QDF_STATUS_SUCCESS; 12665 } 12666 hdd_deinit_adapter_ops_wq(struct hdd_context * hdd_ctx)12667 void hdd_deinit_adapter_ops_wq(struct hdd_context *hdd_ctx) 12668 { 12669 hdd_enter(); 12670 12671 qdf_flush_workqueue(0, hdd_ctx->adapter_ops_wq); 12672 qdf_destroy_workqueue(0, hdd_ctx->adapter_ops_wq); 12673 12674 hdd_exit(); 12675 } 12676 hdd_adapter_feature_update_work_init(struct hdd_adapter * adapter)12677 QDF_STATUS hdd_adapter_feature_update_work_init(struct hdd_adapter *adapter) 12678 { 12679 QDF_STATUS status; 12680 12681 hdd_enter(); 12682 12683 status = qdf_create_work(0, &adapter->netdev_features_update_work, 12684 hdd_adapter_param_update_work, adapter); 12685 adapter->netdev_features_update_work_status = HDD_WORK_INITIALIZED; 12686 12687 hdd_exit(); 12688 12689 return status; 12690 } 12691 hdd_adapter_feature_update_work_deinit(struct hdd_adapter * adapter)12692 void hdd_adapter_feature_update_work_deinit(struct hdd_adapter *adapter) 12693 { 12694 hdd_enter(); 12695 12696 if (adapter->netdev_features_update_work_status != 12697 HDD_WORK_INITIALIZED) { 12698 hdd_debug("work not yet init"); 12699 return; 12700 } 12701 qdf_cancel_work(&adapter->netdev_features_update_work); 12702 qdf_flush_work(&adapter->netdev_features_update_work); 12703 adapter->netdev_features_update_work_status = HDD_WORK_UNINITIALIZED; 12704 12705 hdd_exit(); 12706 } 12707 12708 #define HDD_DUMP_STAT_HELP(STAT_ID) \ 12709 hdd_nofl_debug("%u -- %s", STAT_ID, (# STAT_ID)) 12710 /** 12711 * hdd_display_stats_help() - print statistics help 12712 * 12713 * Return: none 12714 */ hdd_display_stats_help(void)12715 static void hdd_display_stats_help(void) 12716 { 12717 hdd_nofl_debug("iwpriv wlan0 dumpStats [option] - dump statistics"); 12718 hdd_nofl_debug("iwpriv wlan0 clearStats [option] - clear statistics"); 12719 hdd_nofl_debug("options:"); 12720 HDD_DUMP_STAT_HELP(CDP_TXRX_PATH_STATS); 12721 HDD_DUMP_STAT_HELP(CDP_TXRX_HIST_STATS); 12722 HDD_DUMP_STAT_HELP(CDP_TXRX_TSO_STATS); 12723 HDD_DUMP_STAT_HELP(CDP_HDD_NETIF_OPER_HISTORY); 12724 HDD_DUMP_STAT_HELP(CDP_DUMP_TX_FLOW_POOL_INFO); 12725 HDD_DUMP_STAT_HELP(CDP_TXRX_DESC_STATS); 12726 HDD_DUMP_STAT_HELP(CDP_HIF_STATS); 12727 HDD_DUMP_STAT_HELP(CDP_NAPI_STATS); 12728 HDD_DUMP_STAT_HELP(CDP_DP_NAPI_STATS); 12729 HDD_DUMP_STAT_HELP(CDP_DP_RX_THREAD_STATS); 12730 } 12731 hdd_wlan_dump_stats(struct hdd_adapter * adapter,int stats_id)12732 int hdd_wlan_dump_stats(struct hdd_adapter *adapter, int stats_id) 12733 { 12734 int ret = 0; 12735 QDF_STATUS status; 12736 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); 12737 12738 hdd_debug("stats_id %d", stats_id); 12739 12740 switch (stats_id) { 12741 case CDP_TXRX_HIST_STATS: 12742 ucfg_wlan_dp_display_tx_rx_histogram(hdd_ctx->psoc); 12743 break; 12744 case CDP_HDD_NETIF_OPER_HISTORY: 12745 wlan_hdd_display_adapter_netif_queue_history(adapter); 12746 break; 12747 case CDP_HIF_STATS: 12748 hdd_display_hif_stats(); 12749 break; 12750 case CDP_NAPI_STATS: 12751 if (hdd_display_napi_stats()) { 12752 hdd_err("error displaying napi stats"); 12753 ret = -EFAULT; 12754 } 12755 break; 12756 case CDP_DP_RX_THREAD_STATS: 12757 ucfg_dp_txrx_ext_dump_stats(cds_get_context(QDF_MODULE_ID_SOC), 12758 CDP_DP_RX_THREAD_STATS); 12759 break; 12760 case CDP_DISCONNECT_STATS: 12761 sme_display_disconnect_stats(hdd_ctx->mac_handle, 12762 adapter->deflink->vdev_id); 12763 break; 12764 default: 12765 status = cdp_display_stats(cds_get_context(QDF_MODULE_ID_SOC), 12766 stats_id, 12767 QDF_STATS_VERBOSITY_LEVEL_HIGH); 12768 if (status == QDF_STATUS_E_INVAL) { 12769 hdd_display_stats_help(); 12770 ret = -EINVAL; 12771 } 12772 break; 12773 } 12774 return ret; 12775 } 12776 hdd_wlan_clear_stats(struct hdd_adapter * adapter,int stats_id)12777 int hdd_wlan_clear_stats(struct hdd_adapter *adapter, int stats_id) 12778 { 12779 QDF_STATUS status = QDF_STATUS_SUCCESS; 12780 12781 hdd_debug("stats_id %d", stats_id); 12782 12783 switch (stats_id) { 12784 case CDP_HDD_STATS: 12785 ucfg_dp_clear_net_dev_stats(adapter->dev); 12786 memset(&adapter->deflink->hdd_stats, 0, 12787 sizeof(adapter->deflink->hdd_stats)); 12788 break; 12789 case CDP_TXRX_HIST_STATS: 12790 ucfg_wlan_dp_clear_tx_rx_histogram(adapter->hdd_ctx->psoc); 12791 break; 12792 case CDP_HDD_NETIF_OPER_HISTORY: 12793 wlan_hdd_clear_netif_queue_history(adapter->hdd_ctx); 12794 break; 12795 case CDP_HIF_STATS: 12796 hdd_clear_hif_stats(); 12797 break; 12798 case CDP_NAPI_STATS: 12799 hdd_clear_napi_stats(); 12800 break; 12801 default: 12802 status = cdp_clear_stats(cds_get_context(QDF_MODULE_ID_SOC), 12803 OL_TXRX_PDEV_ID, 12804 stats_id); 12805 if (status != QDF_STATUS_SUCCESS) 12806 hdd_debug("Failed to dump stats for stats_id: %d", 12807 stats_id); 12808 break; 12809 } 12810 12811 return qdf_status_to_os_return(status); 12812 } 12813 12814 /* length of the netif queue log needed per adapter */ 12815 #define ADAP_NETIFQ_LOG_LEN ((20 * WLAN_REASON_TYPE_MAX) + 50) 12816 12817 /** 12818 * hdd_display_netif_queue_history_compact() - display compact netifq history 12819 * @hdd_ctx: hdd context 12820 * 12821 * Return: none 12822 */ 12823 static void hdd_display_netif_queue_history_compact(struct hdd_context * hdd_ctx)12824 hdd_display_netif_queue_history_compact(struct hdd_context *hdd_ctx) 12825 { 12826 int adapter_num = 0; 12827 int i; 12828 int bytes_written; 12829 u32 tbytes; 12830 qdf_time_t total, pause, unpause, curr_time, delta; 12831 char temp_str[20 * WLAN_REASON_TYPE_MAX]; 12832 char *comb_log_str; 12833 uint32_t comb_log_str_size; 12834 struct hdd_adapter *adapter = NULL, *next_adapter = NULL; 12835 wlan_net_dev_ref_dbgid dbgid = 12836 NET_DEV_HOLD_DISPLAY_NETIF_QUEUE_HISTORY_COMPACT; 12837 12838 comb_log_str_size = (ADAP_NETIFQ_LOG_LEN * WLAN_MAX_VDEVS) + 1; 12839 comb_log_str = qdf_mem_malloc(comb_log_str_size); 12840 if (!comb_log_str) 12841 return; 12842 12843 bytes_written = 0; 12844 12845 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 12846 dbgid) { 12847 curr_time = qdf_system_ticks(); 12848 total = curr_time - adapter->start_time; 12849 delta = curr_time - adapter->last_time; 12850 12851 if (adapter->pause_map) { 12852 pause = adapter->total_pause_time + delta; 12853 unpause = adapter->total_unpause_time; 12854 } else { 12855 unpause = adapter->total_unpause_time + delta; 12856 pause = adapter->total_pause_time; 12857 } 12858 12859 tbytes = 0; 12860 qdf_mem_zero(temp_str, sizeof(temp_str)); 12861 for (i = WLAN_CONTROL_PATH; i < WLAN_REASON_TYPE_MAX; i++) { 12862 if (adapter->queue_oper_stats[i].pause_count == 0) 12863 continue; 12864 tbytes += 12865 snprintf( 12866 &temp_str[tbytes], 12867 (tbytes >= sizeof(temp_str) ? 12868 0 : sizeof(temp_str) - tbytes), 12869 "%d(%d,%d) ", 12870 i, 12871 adapter->queue_oper_stats[i]. 12872 pause_count, 12873 adapter->queue_oper_stats[i]. 12874 unpause_count); 12875 } 12876 if (tbytes >= sizeof(temp_str)) 12877 hdd_warn("log truncated"); 12878 12879 bytes_written += snprintf(&comb_log_str[bytes_written], 12880 bytes_written >= comb_log_str_size ? 0 : 12881 comb_log_str_size - bytes_written, 12882 "[%d %d] (%d) %u/%ums %s|", 12883 adapter->deflink->vdev_id, adapter->device_mode, 12884 adapter->pause_map, 12885 qdf_system_ticks_to_msecs(pause), 12886 qdf_system_ticks_to_msecs(total), 12887 temp_str); 12888 12889 adapter_num++; 12890 /* dev_put has to be done here */ 12891 hdd_adapter_dev_put_debug(adapter, dbgid); 12892 } 12893 12894 /* using QDF_TRACE to avoid printing function name */ 12895 QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_INFO_LOW, 12896 "STATS |%s", comb_log_str); 12897 12898 if (bytes_written >= comb_log_str_size) 12899 hdd_warn("log string truncated"); 12900 12901 qdf_mem_free(comb_log_str); 12902 } 12903 12904 /* Max size of a single netdev tx queue state string. e.g. "1: 0x1" */ 12905 #define HDD_NETDEV_TX_Q_STATE_STRLEN 15 12906 /** 12907 * wlan_hdd_display_adapter_netif_queue_stats() - display adapter based 12908 * netif queue stats 12909 * @adapter: hdd adapter 12910 * 12911 * Return: none 12912 */ 12913 static void wlan_hdd_display_adapter_netif_queue_stats(struct hdd_adapter * adapter)12914 wlan_hdd_display_adapter_netif_queue_stats(struct hdd_adapter *adapter) 12915 { 12916 int i; 12917 qdf_time_t total, pause, unpause, curr_time, delta; 12918 struct hdd_netif_queue_history *q_hist_ptr; 12919 char q_status_buf[NUM_TX_QUEUES * HDD_NETDEV_TX_Q_STATE_STRLEN] = {0}; 12920 12921 hdd_nofl_debug("Netif queue operation statistics:"); 12922 hdd_nofl_debug("vdev_id %d device mode %d", 12923 adapter->deflink->vdev_id, adapter->device_mode); 12924 hdd_nofl_debug("Current pause_map %x", adapter->pause_map); 12925 curr_time = qdf_system_ticks(); 12926 total = curr_time - adapter->start_time; 12927 delta = curr_time - adapter->last_time; 12928 if (adapter->pause_map) { 12929 pause = adapter->total_pause_time + delta; 12930 unpause = adapter->total_unpause_time; 12931 } else { 12932 unpause = adapter->total_unpause_time + delta; 12933 pause = adapter->total_pause_time; 12934 } 12935 hdd_nofl_debug("Total: %ums Pause: %ums Unpause: %ums", 12936 qdf_system_ticks_to_msecs(total), 12937 qdf_system_ticks_to_msecs(pause), 12938 qdf_system_ticks_to_msecs(unpause)); 12939 hdd_nofl_debug("reason_type: pause_cnt: unpause_cnt: pause_time"); 12940 12941 for (i = WLAN_CONTROL_PATH; i < WLAN_REASON_TYPE_MAX; i++) { 12942 qdf_time_t pause_delta = 0; 12943 12944 if (adapter->pause_map & (1 << i)) 12945 pause_delta = delta; 12946 12947 /* using hdd_log to avoid printing function name */ 12948 hdd_nofl_debug("%s: %d: %d: %ums", 12949 hdd_reason_type_to_string(i), 12950 adapter->queue_oper_stats[i].pause_count, 12951 adapter->queue_oper_stats[i]. 12952 unpause_count, 12953 qdf_system_ticks_to_msecs( 12954 adapter->queue_oper_stats[i]. 12955 total_pause_time + pause_delta)); 12956 } 12957 12958 hdd_nofl_debug("Netif queue operation history: Total entries: %d current index %d(-1) time %u", 12959 WLAN_HDD_MAX_HISTORY_ENTRY, 12960 adapter->history_index, 12961 qdf_system_ticks_to_msecs(qdf_system_ticks())); 12962 12963 hdd_nofl_debug("%2s%20s%50s%30s%10s %s", 12964 "#", "time(ms)", "action_type", "reason_type", 12965 "pause_map", "netdev-queue-status"); 12966 12967 for (i = 0; i < WLAN_HDD_MAX_HISTORY_ENTRY; i++) { 12968 /* using hdd_log to avoid printing function name */ 12969 if (adapter->queue_oper_history[i].time == 0) 12970 continue; 12971 q_hist_ptr = &adapter->queue_oper_history[i]; 12972 wlan_hdd_dump_queue_history_state(q_hist_ptr, 12973 q_status_buf, 12974 sizeof(q_status_buf)); 12975 hdd_nofl_debug("%2d%20u%50s%30s%10x %s", 12976 i, qdf_system_ticks_to_msecs( 12977 adapter->queue_oper_history[i].time), 12978 hdd_action_type_to_string( 12979 adapter->queue_oper_history[i]. 12980 netif_action), 12981 hdd_reason_type_to_string( 12982 adapter->queue_oper_history[i]. 12983 netif_reason), 12984 adapter->queue_oper_history[i].pause_map, 12985 q_status_buf); 12986 } 12987 } 12988 12989 void wlan_hdd_display_adapter_netif_queue_history(struct hdd_adapter * adapter)12990 wlan_hdd_display_adapter_netif_queue_history(struct hdd_adapter *adapter) 12991 { 12992 wlan_hdd_display_adapter_netif_queue_stats(adapter); 12993 } 12994 12995 /** 12996 * wlan_hdd_display_netif_queue_history() - display netif queue history 12997 * @context: hdd context 12998 * @verb_lvl: verbosity level 12999 * 13000 * Return: none 13001 */ 13002 void wlan_hdd_display_netif_queue_history(hdd_cb_handle context,enum qdf_stats_verbosity_level verb_lvl)13003 wlan_hdd_display_netif_queue_history(hdd_cb_handle context, 13004 enum qdf_stats_verbosity_level verb_lvl) 13005 { 13006 struct hdd_adapter *adapter = NULL, *next_adapter = NULL; 13007 struct hdd_context *hdd_ctx = hdd_cb_handle_to_context(context); 13008 wlan_net_dev_ref_dbgid dbgid = 13009 NET_DEV_HOLD_DISPLAY_NETIF_QUEUE_HISTORY; 13010 13011 if (!hdd_ctx) { 13012 hdd_err("hdd_ctx is null"); 13013 return; 13014 } 13015 13016 if (verb_lvl == QDF_STATS_VERBOSITY_LEVEL_LOW) { 13017 hdd_display_netif_queue_history_compact(hdd_ctx); 13018 return; 13019 } 13020 13021 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 13022 dbgid) { 13023 if (adapter->deflink->vdev_id == CDP_INVALID_VDEV_ID) { 13024 hdd_adapter_dev_put_debug(adapter, dbgid); 13025 continue; 13026 } 13027 wlan_hdd_display_adapter_netif_queue_stats(adapter); 13028 /* dev_put has to be done here */ 13029 hdd_adapter_dev_put_debug(adapter, dbgid); 13030 } 13031 } 13032 13033 /** 13034 * wlan_hdd_clear_netif_queue_history() - clear netif queue operation history 13035 * @hdd_ctx: hdd context 13036 * 13037 * Return: none 13038 */ wlan_hdd_clear_netif_queue_history(struct hdd_context * hdd_ctx)13039 void wlan_hdd_clear_netif_queue_history(struct hdd_context *hdd_ctx) 13040 { 13041 struct hdd_adapter *adapter = NULL, *next_adapter = NULL; 13042 wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_CLEAR_NETIF_QUEUE_HISTORY; 13043 13044 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 13045 dbgid) { 13046 qdf_mem_zero(adapter->queue_oper_stats, 13047 sizeof(adapter->queue_oper_stats)); 13048 qdf_mem_zero(adapter->queue_oper_history, 13049 sizeof(adapter->queue_oper_history)); 13050 adapter->history_index = 0; 13051 adapter->start_time = adapter->last_time = qdf_system_ticks(); 13052 adapter->total_pause_time = 0; 13053 adapter->total_unpause_time = 0; 13054 hdd_adapter_dev_put_debug(adapter, dbgid); 13055 } 13056 } 13057 13058 #ifdef WLAN_FEATURE_OFFLOAD_PACKETS 13059 /** 13060 * hdd_init_offloaded_packets_ctx() - Initialize offload packets context 13061 * @hdd_ctx: hdd global context 13062 * 13063 * Return: none 13064 */ hdd_init_offloaded_packets_ctx(struct hdd_context * hdd_ctx)13065 static void hdd_init_offloaded_packets_ctx(struct hdd_context *hdd_ctx) 13066 { 13067 uint8_t i; 13068 13069 mutex_init(&hdd_ctx->op_ctx.op_lock); 13070 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++) { 13071 hdd_ctx->op_ctx.op_table[i].request_id = MAX_REQUEST_ID; 13072 hdd_ctx->op_ctx.op_table[i].pattern_id = i; 13073 } 13074 } 13075 #else hdd_init_offloaded_packets_ctx(struct hdd_context * hdd_ctx)13076 static void hdd_init_offloaded_packets_ctx(struct hdd_context *hdd_ctx) 13077 { 13078 } 13079 #endif 13080 13081 #ifdef WLAN_FEATURE_WOW_PULSE 13082 /** 13083 * wlan_hdd_set_wow_pulse() - call SME to send wmi cmd of wow pulse 13084 * @hdd_ctx: struct hdd_context structure pointer 13085 * @enable: enable or disable this behaviour 13086 * 13087 * Return: int 13088 */ wlan_hdd_set_wow_pulse(struct hdd_context * hdd_ctx,bool enable)13089 static int wlan_hdd_set_wow_pulse(struct hdd_context *hdd_ctx, bool enable) 13090 { 13091 struct wow_pulse_mode wow_pulse_set_info; 13092 QDF_STATUS status; 13093 13094 hdd_debug("wow pulse enable flag is %d", enable); 13095 13096 if (!ucfg_pmo_is_wow_pulse_enabled(hdd_ctx->psoc)) 13097 return 0; 13098 13099 /* prepare the request to send to SME */ 13100 if (enable == true) { 13101 wow_pulse_set_info.wow_pulse_enable = true; 13102 wow_pulse_set_info.wow_pulse_pin = 13103 ucfg_pmo_get_wow_pulse_pin(hdd_ctx->psoc); 13104 13105 wow_pulse_set_info.wow_pulse_interval_high = 13106 ucfg_pmo_get_wow_pulse_interval_high(hdd_ctx->psoc); 13107 13108 wow_pulse_set_info.wow_pulse_interval_low = 13109 ucfg_pmo_get_wow_pulse_interval_low(hdd_ctx->psoc); 13110 13111 wow_pulse_set_info.wow_pulse_repeat_count = 13112 ucfg_pmo_get_wow_pulse_repeat_count(hdd_ctx->psoc); 13113 13114 wow_pulse_set_info.wow_pulse_init_state = 13115 ucfg_pmo_get_wow_pulse_init_state(hdd_ctx->psoc); 13116 } else { 13117 wow_pulse_set_info.wow_pulse_enable = false; 13118 wow_pulse_set_info.wow_pulse_pin = 0; 13119 wow_pulse_set_info.wow_pulse_interval_low = 0; 13120 wow_pulse_set_info.wow_pulse_interval_high = 0; 13121 wow_pulse_set_info.wow_pulse_repeat_count = 0; 13122 wow_pulse_set_info.wow_pulse_init_state = 0; 13123 } 13124 hdd_debug("enable %d pin %d low %d high %d count %d init %d", 13125 wow_pulse_set_info.wow_pulse_enable, 13126 wow_pulse_set_info.wow_pulse_pin, 13127 wow_pulse_set_info.wow_pulse_interval_low, 13128 wow_pulse_set_info.wow_pulse_interval_high, 13129 wow_pulse_set_info.wow_pulse_repeat_count, 13130 wow_pulse_set_info.wow_pulse_init_state); 13131 13132 status = sme_set_wow_pulse(&wow_pulse_set_info); 13133 if (QDF_STATUS_E_FAILURE == status) { 13134 hdd_debug("sme_set_wow_pulse failure!"); 13135 return -EIO; 13136 } 13137 hdd_debug("sme_set_wow_pulse success!"); 13138 return 0; 13139 } 13140 #else wlan_hdd_set_wow_pulse(struct hdd_context * hdd_ctx,bool enable)13141 static inline int wlan_hdd_set_wow_pulse(struct hdd_context *hdd_ctx, bool enable) 13142 { 13143 return 0; 13144 } 13145 #endif 13146 13147 #ifdef WLAN_FEATURE_FASTPATH 13148 13149 /** 13150 * hdd_enable_fastpath() - Enable fastpath if enabled in config INI 13151 * @hdd_ctx: hdd context 13152 * @context: lower layer context 13153 * 13154 * Return: none 13155 */ hdd_enable_fastpath(struct hdd_context * hdd_ctx,void * context)13156 void hdd_enable_fastpath(struct hdd_context *hdd_ctx, 13157 void *context) 13158 { 13159 if (cfg_get(hdd_ctx->psoc, CFG_DP_ENABLE_FASTPATH)) 13160 hif_enable_fastpath(context); 13161 } 13162 #endif 13163 13164 #if defined(FEATURE_WLAN_CH_AVOID) 13165 /** 13166 * hdd_set_thermal_level_cb() - set thermal level callback function 13167 * @hdd_handle: opaque handle for the hdd context 13168 * @level: thermal level 13169 * 13170 * Change IPA data path to SW path when the thermal throttle level greater 13171 * than 0, and restore the original data path when throttle level is 0 13172 * 13173 * Return: none 13174 */ hdd_set_thermal_level_cb(hdd_handle_t hdd_handle,u_int8_t level)13175 static void hdd_set_thermal_level_cb(hdd_handle_t hdd_handle, u_int8_t level) 13176 { 13177 struct hdd_context *hdd_ctx = hdd_handle_to_context(hdd_handle); 13178 13179 /* Change IPA to SW path when throttle level greater than 0 */ 13180 if (level > THROTTLE_LEVEL_0) 13181 ucfg_ipa_send_mcc_scc_msg(hdd_ctx->pdev, true); 13182 else 13183 /* restore original concurrency mode */ 13184 ucfg_ipa_send_mcc_scc_msg(hdd_ctx->pdev, hdd_ctx->mcc_mode); 13185 } 13186 #else 13187 /** 13188 * hdd_set_thermal_level_cb() - set thermal level callback function 13189 * @hdd_handle: opaque handle for the hdd context 13190 * @level: thermal level 13191 * 13192 * Change IPA data path to SW path when the thermal throttle level greater 13193 * than 0, and restore the original data path when throttle level is 0 13194 * 13195 * Return: none 13196 */ hdd_set_thermal_level_cb(hdd_handle_t hdd_handle,u_int8_t level)13197 static void hdd_set_thermal_level_cb(hdd_handle_t hdd_handle, u_int8_t level) 13198 { 13199 } 13200 #endif 13201 hdd_switch_sap_channel(struct wlan_hdd_link_info * link_info,uint8_t channel,bool forced)13202 QDF_STATUS hdd_switch_sap_channel(struct wlan_hdd_link_info *link_info, 13203 uint8_t channel, bool forced) 13204 { 13205 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(link_info->adapter); 13206 mac_handle_t mac_handle; 13207 struct sap_config *sap_cfg; 13208 qdf_freq_t freq; 13209 13210 mac_handle = hdd_adapter_get_mac_handle(link_info->adapter); 13211 if (!mac_handle) { 13212 hdd_err("invalid MAC handle"); 13213 return QDF_STATUS_E_INVAL; 13214 } 13215 13216 freq = wlan_reg_legacy_chan_to_freq(hdd_ctx->pdev, channel); 13217 sap_cfg = &(WLAN_HDD_GET_AP_CTX_PTR(link_info)->sap_config); 13218 hdd_debug("chan:%d width:%d", channel, sap_cfg->ch_width_orig); 13219 13220 return policy_mgr_change_sap_channel_with_csa(hdd_ctx->psoc, 13221 link_info->vdev_id, freq, 13222 sap_cfg->ch_width_orig, 13223 forced); 13224 } 13225 hdd_switch_sap_chan_freq(struct hdd_adapter * adapter,qdf_freq_t chan_freq,enum phy_ch_width ch_width,bool forced)13226 QDF_STATUS hdd_switch_sap_chan_freq(struct hdd_adapter *adapter, 13227 qdf_freq_t chan_freq, 13228 enum phy_ch_width ch_width, 13229 bool forced) 13230 { 13231 struct hdd_ap_ctx *hdd_ap_ctx; 13232 struct hdd_context *hdd_ctx; 13233 13234 if (hdd_validate_adapter(adapter)) 13235 return QDF_STATUS_E_INVAL; 13236 13237 hdd_ctx = WLAN_HDD_GET_CTX(adapter); 13238 13239 if(wlan_hdd_validate_context(hdd_ctx)) 13240 return QDF_STATUS_E_INVAL; 13241 13242 hdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(adapter->deflink); 13243 13244 hdd_debug("chan freq:%d width:%d org bw %d", 13245 chan_freq, ch_width, hdd_ap_ctx->sap_config.ch_width_orig); 13246 13247 return policy_mgr_change_sap_channel_with_csa(hdd_ctx->psoc, 13248 adapter->deflink->vdev_id, 13249 chan_freq, 13250 ch_width, 13251 forced); 13252 } 13253 hdd_update_acs_timer_reason(struct hdd_adapter * adapter,uint8_t reason)13254 int hdd_update_acs_timer_reason(struct hdd_adapter *adapter, uint8_t reason) 13255 { 13256 struct hdd_external_acs_timer_context *timer_context; 13257 int status; 13258 QDF_STATUS qdf_status; 13259 qdf_mc_timer_t *vendor_acs_timer; 13260 13261 set_bit(VENDOR_ACS_RESPONSE_PENDING, &adapter->deflink->link_flags); 13262 13263 vendor_acs_timer = &adapter->deflink->session.ap.vendor_acs_timer; 13264 if (QDF_TIMER_STATE_RUNNING == 13265 qdf_mc_timer_get_current_state(vendor_acs_timer)) { 13266 qdf_mc_timer_stop(vendor_acs_timer); 13267 } 13268 timer_context = 13269 (struct hdd_external_acs_timer_context *)vendor_acs_timer->user_data; 13270 timer_context->reason = reason; 13271 qdf_status = 13272 qdf_mc_timer_start(vendor_acs_timer, WLAN_VENDOR_ACS_WAIT_TIME); 13273 if (qdf_status != QDF_STATUS_SUCCESS) { 13274 hdd_err("failed to start external acs timer"); 13275 return -ENOSPC; 13276 } 13277 /* Update config to application */ 13278 status = hdd_cfg80211_update_acs_config(adapter, reason); 13279 hdd_info("Updated ACS config to nl with reason %d", reason); 13280 13281 return status; 13282 } 13283 13284 #ifdef FEATURE_WLAN_CH_AVOID_EXT wlan_hdd_get_restriction_mask(struct hdd_context * hdd_ctx)13285 uint32_t wlan_hdd_get_restriction_mask(struct hdd_context *hdd_ctx) 13286 { 13287 return hdd_ctx->restriction_mask; 13288 } 13289 wlan_hdd_set_restriction_mask(struct hdd_context * hdd_ctx)13290 void wlan_hdd_set_restriction_mask(struct hdd_context *hdd_ctx) 13291 { 13292 hdd_ctx->restriction_mask = 13293 hdd_ctx->coex_avoid_freq_list.restriction_mask; 13294 } 13295 #else wlan_hdd_get_restriction_mask(struct hdd_context * hdd_ctx)13296 uint32_t wlan_hdd_get_restriction_mask(struct hdd_context *hdd_ctx) 13297 { 13298 return -EINVAL; 13299 } 13300 wlan_hdd_set_restriction_mask(struct hdd_context * hdd_ctx)13301 void wlan_hdd_set_restriction_mask(struct hdd_context *hdd_ctx) 13302 { 13303 } 13304 #endif 13305 13306 #if defined(FEATURE_WLAN_CH_AVOID) 13307 /** 13308 * hdd_store_sap_restart_channel() - store sap restart channel 13309 * @restart_chan: restart channel 13310 * @restart_chan_store: pointer to restart channel store 13311 * 13312 * The function will store new sap restart channel. 13313 * 13314 * Return - none 13315 */ 13316 static void hdd_store_sap_restart_channel(qdf_freq_t restart_chan,qdf_freq_t * restart_chan_store)13317 hdd_store_sap_restart_channel(qdf_freq_t restart_chan, qdf_freq_t *restart_chan_store) 13318 { 13319 uint8_t i; 13320 13321 for (i = 0; i < SAP_MAX_NUM_SESSION; i++) { 13322 if (*(restart_chan_store + i) == restart_chan) 13323 return; 13324 13325 if (*(restart_chan_store + i)) 13326 continue; 13327 13328 *(restart_chan_store + i) = restart_chan; 13329 return; 13330 } 13331 } 13332 13333 /** 13334 * hdd_check_chn_bw_boundary_unsafe() - check channel range unsafe 13335 * @hdd_ctxt: hdd context pointer 13336 * @adapter: hdd adapter pointer 13337 * 13338 * hdd_check_chn_bw_boundary_unsafe check SAP channel range with certain 13339 * bandwidth whether cover all unsafe channel list. 13340 * 13341 * Return - bool 13342 */ 13343 static bool hdd_check_chn_bw_boundary_unsafe(struct hdd_context * hdd_ctxt,struct hdd_adapter * adapter)13344 hdd_check_chn_bw_boundary_unsafe(struct hdd_context *hdd_ctxt, 13345 struct hdd_adapter *adapter) 13346 { 13347 uint32_t freq; 13348 uint32_t start_freq = 0; 13349 uint32_t end_freq = 0; 13350 uint32_t i; 13351 uint8_t ch_width; 13352 const struct bonded_channel_freq *bonded_chan_ptr_ptr = NULL; 13353 13354 freq = adapter->deflink->session.ap.operating_chan_freq; 13355 ch_width = adapter->deflink->session.ap.sap_config.acs_cfg.ch_width; 13356 13357 if (ch_width > CH_WIDTH_20MHZ) 13358 bonded_chan_ptr_ptr = 13359 wlan_reg_get_bonded_chan_entry(freq, ch_width, 0); 13360 13361 if (bonded_chan_ptr_ptr) { 13362 start_freq = bonded_chan_ptr_ptr->start_freq; 13363 end_freq = bonded_chan_ptr_ptr->end_freq; 13364 } 13365 13366 for (i = 0; i < hdd_ctxt->unsafe_channel_count; i++) { 13367 if ((freq == hdd_ctxt->unsafe_channel_list[i]) || 13368 (start_freq <= hdd_ctxt->unsafe_channel_list[i] && 13369 hdd_ctxt->unsafe_channel_list[i] <= end_freq)) { 13370 hdd_debug("op chn freq:%u is unsafe for chn list:%u", 13371 freq, hdd_ctxt->unsafe_channel_list[i]); 13372 return true; 13373 } 13374 } 13375 13376 return false; 13377 } 13378 13379 /** 13380 * hdd_unsafe_channel_restart_sap() - restart sap if sap is on unsafe channel 13381 * @hdd_ctx: hdd context pointer 13382 * 13383 * hdd_unsafe_channel_restart_sap check all unsafe channel list 13384 * and if ACS is enabled, driver will ask userspace to restart the 13385 * sap. User space on LTE coex indication restart driver. 13386 * 13387 * Return - none 13388 */ hdd_unsafe_channel_restart_sap(struct hdd_context * hdd_ctx)13389 QDF_STATUS hdd_unsafe_channel_restart_sap(struct hdd_context *hdd_ctx) 13390 { 13391 struct hdd_adapter *adapter, *next_adapter = NULL; 13392 struct hdd_ap_ctx *ap_ctx; 13393 uint32_t i; 13394 bool found = false; 13395 qdf_freq_t restart_chan_store[SAP_MAX_NUM_SESSION] = {0}; 13396 uint8_t scc_on_lte_coex = 0; 13397 uint32_t restart_freq, ap_chan_freq; 13398 bool value; 13399 QDF_STATUS status; 13400 bool is_acs_support_for_dfs_ltecoex = cfg_default(CFG_USER_ACS_DFS_LTE); 13401 bool is_vendor_acs_support = 13402 cfg_default(CFG_USER_AUTO_CHANNEL_SELECTION); 13403 wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_UNSAFE_CHANNEL_RESTART_SAP; 13404 enum phy_ch_width ch_width; 13405 struct wlan_hdd_link_info *link_info; 13406 13407 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 13408 dbgid) { 13409 if (adapter->device_mode != QDF_SAP_MODE) { 13410 hdd_debug_rl("skip device mode:%d", 13411 adapter->device_mode); 13412 hdd_adapter_dev_put_debug(adapter, dbgid); 13413 continue; 13414 } 13415 13416 hdd_adapter_for_each_active_link_info(adapter, link_info) { 13417 ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(link_info); 13418 if (!ap_ctx->sap_config.acs_cfg.acs_mode) { 13419 hdd_debug_rl("skip acs:%d", 13420 ap_ctx->sap_config.acs_cfg.acs_mode); 13421 continue; 13422 } 13423 13424 ap_chan_freq = ap_ctx->operating_chan_freq; 13425 ch_width = ap_ctx->sap_config.ch_width_orig; 13426 found = false; 13427 status = 13428 ucfg_policy_mgr_get_sta_sap_scc_lte_coex_chnl(hdd_ctx->psoc, 13429 &scc_on_lte_coex); 13430 if (!QDF_IS_STATUS_SUCCESS(status)) 13431 hdd_err("can't get scc on lte coex chnl, use def"); 13432 /* 13433 * If STA+SAP is doing SCC & 13434 * g_sta_sap_scc_on_lte_coex_chan is set, 13435 * no need to move SAP. 13436 */ 13437 if ((policy_mgr_is_sta_sap_scc(hdd_ctx->psoc, 13438 ap_chan_freq) && 13439 scc_on_lte_coex) || 13440 policy_mgr_nan_sap_scc_on_unsafe_ch_chk(hdd_ctx->psoc, 13441 ap_chan_freq)) 13442 hdd_debug("SAP allowed in unsafe SCC channel"); 13443 else 13444 found = hdd_check_chn_bw_boundary_unsafe(hdd_ctx, 13445 adapter); 13446 if (!found) { 13447 hdd_store_sap_restart_channel(ap_chan_freq, 13448 restart_chan_store); 13449 hdd_debug("ch freq:%d is safe. no need to change channel", 13450 ap_chan_freq); 13451 continue; 13452 } 13453 13454 status = ucfg_mlme_get_acs_support_for_dfs_ltecoex( 13455 hdd_ctx->psoc, 13456 &is_acs_support_for_dfs_ltecoex); 13457 if (!QDF_IS_STATUS_SUCCESS(status)) 13458 hdd_err("get_acs_support_for_dfs_ltecoex failed,set def"); 13459 13460 status = ucfg_mlme_get_vendor_acs_support( 13461 hdd_ctx->psoc, 13462 &is_vendor_acs_support); 13463 if (!QDF_IS_STATUS_SUCCESS(status)) 13464 hdd_err("get_vendor_acs_support failed, set default"); 13465 13466 if (is_vendor_acs_support && 13467 is_acs_support_for_dfs_ltecoex) { 13468 hdd_update_acs_timer_reason(adapter, 13469 QCA_WLAN_VENDOR_ACS_SELECT_REASON_LTE_COEX); 13470 continue; 13471 } 13472 13473 restart_freq = 0; 13474 for (i = 0; i < SAP_MAX_NUM_SESSION; i++) { 13475 if (!restart_chan_store[i]) 13476 continue; 13477 13478 if (policy_mgr_is_force_scc(hdd_ctx->psoc) && 13479 WLAN_REG_IS_SAME_BAND_FREQS( 13480 restart_chan_store[i], 13481 ap_chan_freq)) { 13482 restart_freq = restart_chan_store[i]; 13483 break; 13484 } 13485 } 13486 if (!restart_freq) { 13487 restart_freq = 13488 wlansap_get_safe_channel_from_pcl_and_acs_range( 13489 WLAN_HDD_GET_SAP_CTX_PTR(link_info), 13490 &ch_width); 13491 } 13492 if (!restart_freq) { 13493 wlan_hdd_set_sap_csa_reason(hdd_ctx->psoc, 13494 link_info->vdev_id, 13495 CSA_REASON_UNSAFE_CHANNEL); 13496 hdd_err("Unable to find safe chan, Stop the SAP if restriction mask is set else set txpower"); 13497 hdd_stop_sap_set_tx_power(hdd_ctx->psoc, adapter); 13498 continue; 13499 } 13500 /* 13501 * SAP restart due to unsafe channel. While 13502 * restarting the SAP, make sure to clear 13503 * acs_channel, channel to reset to 13504 * 0. Otherwise these settings will override 13505 * the ACS while restart. 13506 */ 13507 hdd_ctx->acs_policy.acs_chan_freq = 13508 AUTO_CHANNEL_SELECT; 13509 ucfg_mlme_get_sap_internal_restart(hdd_ctx->psoc, 13510 &value); 13511 if (value) { 13512 wlan_hdd_set_sap_csa_reason(hdd_ctx->psoc, 13513 link_info->vdev_id, 13514 CSA_REASON_UNSAFE_CHANNEL); 13515 status = hdd_switch_sap_chan_freq(adapter, 13516 restart_freq, 13517 ch_width, 13518 true); 13519 if (QDF_IS_STATUS_SUCCESS(status)) { 13520 hdd_adapter_dev_put_debug(adapter, 13521 dbgid); 13522 if (next_adapter) 13523 hdd_adapter_dev_put_debug( 13524 next_adapter, 13525 dbgid); 13526 return QDF_STATUS_E_PENDING; 13527 } else { 13528 hdd_debug("CSA failed, check next SAP"); 13529 } 13530 } else { 13531 hdd_debug("sending coex indication"); 13532 wlan_hdd_send_svc_nlink_msg( 13533 hdd_ctx->radio_index, 13534 WLAN_SVC_LTE_COEX_IND, NULL, 0); 13535 hdd_adapter_dev_put_debug(adapter, dbgid); 13536 if (next_adapter) 13537 hdd_adapter_dev_put_debug(next_adapter, 13538 dbgid); 13539 return QDF_STATUS_SUCCESS; 13540 } 13541 } 13542 /* dev_put has to be done here */ 13543 hdd_adapter_dev_put_debug(adapter, dbgid); 13544 } 13545 13546 return QDF_STATUS_SUCCESS; 13547 } 13548 13549 /** 13550 * hdd_init_channel_avoidance() - Initialize channel avoidance 13551 * @hdd_ctx: HDD global context 13552 * 13553 * Initialize the channel avoidance logic by retrieving the unsafe 13554 * channel list from the platform driver and plumbing the data 13555 * down to the lower layers. Then subscribe to subsequent channel 13556 * avoidance events. 13557 * 13558 * Return: None 13559 */ hdd_init_channel_avoidance(struct hdd_context * hdd_ctx)13560 static void hdd_init_channel_avoidance(struct hdd_context *hdd_ctx) 13561 { 13562 uint16_t unsafe_channel_count; 13563 int index; 13564 qdf_freq_t *unsafe_freq_list; 13565 13566 pld_get_wlan_unsafe_channel(hdd_ctx->parent_dev, 13567 hdd_ctx->unsafe_channel_list, 13568 &(hdd_ctx->unsafe_channel_count), 13569 sizeof(uint16_t) * NUM_CHANNELS); 13570 13571 hdd_debug("num of unsafe channels is %d", 13572 hdd_ctx->unsafe_channel_count); 13573 13574 unsafe_channel_count = QDF_MIN((uint16_t)hdd_ctx->unsafe_channel_count, 13575 (uint16_t)NUM_CHANNELS); 13576 13577 if (!unsafe_channel_count) 13578 return; 13579 13580 unsafe_freq_list = qdf_mem_malloc( 13581 unsafe_channel_count * sizeof(*unsafe_freq_list)); 13582 13583 if (!unsafe_freq_list) 13584 return; 13585 13586 for (index = 0; index < unsafe_channel_count; index++) { 13587 hdd_debug("channel frequency %d is not safe", 13588 hdd_ctx->unsafe_channel_list[index]); 13589 unsafe_freq_list[index] = 13590 (qdf_freq_t)hdd_ctx->unsafe_channel_list[index]; 13591 } 13592 13593 ucfg_policy_mgr_init_chan_avoidance( 13594 hdd_ctx->psoc, 13595 unsafe_freq_list, 13596 unsafe_channel_count); 13597 13598 qdf_mem_free(unsafe_freq_list); 13599 } 13600 hdd_lte_coex_restart_sap(struct hdd_adapter * adapter,struct hdd_context * hdd_ctx)13601 static void hdd_lte_coex_restart_sap(struct hdd_adapter *adapter, 13602 struct hdd_context *hdd_ctx) 13603 { 13604 uint8_t restart_chan; 13605 uint32_t restart_freq; 13606 13607 restart_freq = wlansap_get_safe_channel_from_pcl_and_acs_range( 13608 WLAN_HDD_GET_SAP_CTX_PTR(adapter->deflink), 13609 NULL); 13610 13611 restart_chan = wlan_reg_freq_to_chan(hdd_ctx->pdev, 13612 restart_freq); 13613 13614 if (!restart_chan) { 13615 hdd_alert("fail to restart SAP"); 13616 return; 13617 } 13618 13619 /* SAP restart due to unsafe channel. While restarting 13620 * the SAP, make sure to clear acs_channel, channel to 13621 * reset to 0. Otherwise these settings will override 13622 * the ACS while restart. 13623 */ 13624 hdd_ctx->acs_policy.acs_chan_freq = AUTO_CHANNEL_SELECT; 13625 13626 hdd_debug("sending coex indication"); 13627 13628 wlan_hdd_send_svc_nlink_msg(hdd_ctx->radio_index, 13629 WLAN_SVC_LTE_COEX_IND, NULL, 0); 13630 wlan_hdd_set_sap_csa_reason(hdd_ctx->psoc, adapter->deflink->vdev_id, 13631 CSA_REASON_LTE_COEX); 13632 hdd_switch_sap_channel(adapter->deflink, restart_chan, true); 13633 } 13634 hdd_clone_local_unsafe_chan(struct hdd_context * hdd_ctx,uint16_t ** local_unsafe_list,uint16_t * local_unsafe_list_count)13635 int hdd_clone_local_unsafe_chan(struct hdd_context *hdd_ctx, 13636 uint16_t **local_unsafe_list, uint16_t *local_unsafe_list_count) 13637 { 13638 uint32_t size; 13639 uint16_t *unsafe_list; 13640 uint16_t chan_count; 13641 13642 if (!hdd_ctx || !local_unsafe_list_count || !local_unsafe_list_count) 13643 return -EINVAL; 13644 13645 chan_count = QDF_MIN(hdd_ctx->unsafe_channel_count, 13646 NUM_CHANNELS); 13647 if (chan_count) { 13648 size = chan_count * sizeof(hdd_ctx->unsafe_channel_list[0]); 13649 unsafe_list = qdf_mem_malloc(size); 13650 if (!unsafe_list) 13651 return -ENOMEM; 13652 qdf_mem_copy(unsafe_list, hdd_ctx->unsafe_channel_list, size); 13653 } else { 13654 unsafe_list = NULL; 13655 } 13656 13657 *local_unsafe_list = unsafe_list; 13658 *local_unsafe_list_count = chan_count; 13659 13660 return 0; 13661 } 13662 hdd_local_unsafe_channel_updated(struct hdd_context * hdd_ctx,uint16_t * local_unsafe_list,uint16_t local_unsafe_list_count,uint32_t restriction_mask)13663 bool hdd_local_unsafe_channel_updated( 13664 struct hdd_context *hdd_ctx, uint16_t *local_unsafe_list, 13665 uint16_t local_unsafe_list_count, uint32_t restriction_mask) 13666 { 13667 int i, j; 13668 13669 if (local_unsafe_list_count != hdd_ctx->unsafe_channel_count) 13670 return true; 13671 if (local_unsafe_list_count == 0) 13672 return false; 13673 for (i = 0; i < local_unsafe_list_count; i++) { 13674 for (j = 0; j < local_unsafe_list_count; j++) 13675 if (local_unsafe_list[i] == 13676 hdd_ctx->unsafe_channel_list[j]) 13677 break; 13678 if (j >= local_unsafe_list_count) 13679 break; 13680 } 13681 13682 if (ucfg_mlme_get_coex_unsafe_chan_nb_user_prefer(hdd_ctx->psoc)) { 13683 /* Return false if current channel list is same as previous 13684 * and restriction mask is not altered 13685 */ 13686 if (i >= local_unsafe_list_count && 13687 (restriction_mask == 13688 wlan_hdd_get_restriction_mask(hdd_ctx))) { 13689 hdd_info("unsafe chan list same"); 13690 return false; 13691 } 13692 } else if (i >= local_unsafe_list_count) { 13693 hdd_info("unsafe chan list same"); 13694 return false; 13695 } 13696 13697 return true; 13698 } 13699 #else hdd_init_channel_avoidance(struct hdd_context * hdd_ctx)13700 static void hdd_init_channel_avoidance(struct hdd_context *hdd_ctx) 13701 { 13702 } 13703 hdd_lte_coex_restart_sap(struct hdd_adapter * adapter,struct hdd_context * hdd_ctx)13704 static inline void hdd_lte_coex_restart_sap(struct hdd_adapter *adapter, 13705 struct hdd_context *hdd_ctx) 13706 { 13707 hdd_debug("Channel avoidance is not enabled; Abort SAP restart"); 13708 } 13709 #endif /* defined(FEATURE_WLAN_CH_AVOID) */ 13710 13711 struct wlan_hdd_link_info * wlan_hdd_get_link_info_from_objmgr(struct wlan_objmgr_vdev * vdev)13712 wlan_hdd_get_link_info_from_objmgr(struct wlan_objmgr_vdev *vdev) 13713 { 13714 if (!vdev) { 13715 hdd_err("null vdev object"); 13716 return NULL; 13717 } 13718 13719 if (vdev->vdev_nif.osdev) 13720 return vdev->vdev_nif.osdev->legacy_osif_priv; 13721 13722 return NULL; 13723 } 13724 13725 /** 13726 * hdd_indicate_mgmt_frame() - Wrapper to indicate management frame to 13727 * user space 13728 * @frame_ind: Management frame data to be informed. 13729 * 13730 * This function is used to indicate management frame to 13731 * user space 13732 * 13733 * Return: None 13734 * 13735 */ hdd_indicate_mgmt_frame(tSirSmeMgmtFrameInd * frame_ind)13736 void hdd_indicate_mgmt_frame(tSirSmeMgmtFrameInd *frame_ind) 13737 { 13738 struct hdd_context *hdd_ctx = NULL; 13739 struct hdd_adapter *adapter = NULL, *next_adapter = NULL; 13740 int i, num_adapters; 13741 uint8_t vdev_id[WLAN_MAX_VDEVS + WLAN_MAX_ML_VDEVS]; 13742 struct ieee80211_mgmt *mgmt = 13743 (struct ieee80211_mgmt *)frame_ind->frameBuf; 13744 struct wlan_objmgr_vdev *vdev; 13745 wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_INDICATE_MGMT_FRAME; 13746 struct wlan_hdd_link_info *link_info; 13747 13748 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 13749 if (wlan_hdd_validate_context(hdd_ctx)) 13750 return; 13751 13752 if (frame_ind->frame_len < ieee80211_hdrlen(mgmt->frame_control)) { 13753 hdd_err(" Invalid frame length"); 13754 return; 13755 } 13756 13757 if (SME_SESSION_ID_ANY == frame_ind->sessionId) { 13758 for (i = 0; i < WLAN_MAX_VDEVS; i++) { 13759 link_info = hdd_get_link_info_by_vdev(hdd_ctx, i); 13760 if (link_info) { 13761 adapter = link_info->adapter; 13762 break; 13763 } 13764 } 13765 } else if (SME_SESSION_ID_BROADCAST == frame_ind->sessionId) { 13766 num_adapters = 0; 13767 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, 13768 next_adapter, dbgid) { 13769 hdd_adapter_for_each_active_link_info(adapter, 13770 link_info) { 13771 vdev_id[num_adapters] = link_info->vdev_id; 13772 num_adapters++; 13773 } 13774 /* dev_put has to be done here */ 13775 hdd_adapter_dev_put_debug(adapter, dbgid); 13776 } 13777 13778 adapter = NULL; 13779 13780 for (i = 0; i < num_adapters; i++) { 13781 vdev = wlan_objmgr_get_vdev_by_id_from_psoc( 13782 hdd_ctx->psoc, 13783 vdev_id[i], 13784 WLAN_OSIF_ID); 13785 13786 if (!vdev) 13787 continue; 13788 13789 link_info = wlan_hdd_get_link_info_from_objmgr(vdev); 13790 if (!link_info) { 13791 wlan_objmgr_vdev_release_ref(vdev, 13792 WLAN_OSIF_ID); 13793 continue; 13794 } 13795 13796 hdd_indicate_mgmt_frame_to_user(link_info->adapter, 13797 frame_ind->frame_len, 13798 frame_ind->frameBuf, 13799 frame_ind->frameType, 13800 frame_ind->rx_freq, 13801 frame_ind->rxRssi, 13802 frame_ind->rx_flags); 13803 wlan_objmgr_vdev_release_ref(vdev, WLAN_OSIF_ID); 13804 } 13805 13806 adapter = NULL; 13807 } else { 13808 link_info = hdd_get_link_info_by_vdev(hdd_ctx, 13809 frame_ind->sessionId); 13810 13811 if (!link_info) { 13812 hdd_err("Invalid vdev"); 13813 return; 13814 } 13815 13816 adapter = link_info->adapter; 13817 } 13818 13819 if ((adapter) && 13820 (WLAN_HDD_ADAPTER_MAGIC == adapter->magic)) 13821 hdd_indicate_mgmt_frame_to_user(adapter, 13822 frame_ind->frame_len, 13823 frame_ind->frameBuf, 13824 frame_ind->frameType, 13825 frame_ind->rx_freq, 13826 frame_ind->rxRssi, 13827 frame_ind->rx_flags); 13828 } 13829 hdd_acs_response_timeout_handler(void * context)13830 void hdd_acs_response_timeout_handler(void *context) 13831 { 13832 struct hdd_external_acs_timer_context *timer_context = 13833 (struct hdd_external_acs_timer_context *)context; 13834 struct hdd_adapter *adapter; 13835 struct hdd_context *hdd_ctx; 13836 uint8_t reason; 13837 struct sap_context *sap_context; 13838 struct wlan_hdd_link_info *link_info; 13839 13840 hdd_enter(); 13841 if (!timer_context) { 13842 hdd_err("invalid timer context"); 13843 return; 13844 } 13845 adapter = timer_context->adapter; 13846 reason = timer_context->reason; 13847 13848 if (!adapter || adapter->magic != WLAN_HDD_ADAPTER_MAGIC) { 13849 hdd_err("invalid adapter or adapter has invalid magic"); 13850 return; 13851 } 13852 13853 hdd_ctx = WLAN_HDD_GET_CTX(adapter); 13854 if (wlan_hdd_validate_context(hdd_ctx)) 13855 return; 13856 13857 link_info = adapter->deflink; 13858 if (!test_bit(VENDOR_ACS_RESPONSE_PENDING, &link_info->link_flags)) 13859 return; 13860 13861 clear_bit(VENDOR_ACS_RESPONSE_PENDING, &link_info->link_flags); 13862 13863 hdd_err("ACS timeout happened for %s reason %d", 13864 adapter->dev->name, reason); 13865 13866 sap_context = WLAN_HDD_GET_SAP_CTX_PTR(link_info); 13867 switch (reason) { 13868 /* SAP init case */ 13869 case QCA_WLAN_VENDOR_ACS_SELECT_REASON_INIT: 13870 wlan_sap_set_vendor_acs(sap_context, false); 13871 wlan_hdd_cfg80211_start_acs(link_info); 13872 break; 13873 /* DFS detected on current channel */ 13874 case QCA_WLAN_VENDOR_ACS_SELECT_REASON_DFS: 13875 wlan_sap_update_next_channel(sap_context, 0, 0); 13876 sme_update_new_channel_event(hdd_ctx->mac_handle, 13877 link_info->vdev_id); 13878 break; 13879 /* LTE coex event on current channel */ 13880 case QCA_WLAN_VENDOR_ACS_SELECT_REASON_LTE_COEX: 13881 hdd_lte_coex_restart_sap(adapter, hdd_ctx); 13882 break; 13883 default: 13884 hdd_info("invalid reason for timer invoke"); 13885 } 13886 } 13887 13888 /** 13889 * hdd_override_ini_config - Override INI config 13890 * @hdd_ctx: HDD context 13891 * 13892 * Override INI config based on module parameter. 13893 * 13894 * Return: None 13895 */ hdd_override_ini_config(struct hdd_context * hdd_ctx)13896 static void hdd_override_ini_config(struct hdd_context *hdd_ctx) 13897 { 13898 QDF_STATUS status; 13899 13900 if (0 == enable_dfs_chan_scan || 1 == enable_dfs_chan_scan) { 13901 ucfg_scan_cfg_set_dfs_chan_scan_allowed(hdd_ctx->psoc, 13902 enable_dfs_chan_scan); 13903 hdd_debug("Module enable_dfs_chan_scan set to %d", 13904 enable_dfs_chan_scan); 13905 } 13906 if (0 == enable_11d || 1 == enable_11d) { 13907 status = ucfg_mlme_set_11d_enabled(hdd_ctx->psoc, enable_11d); 13908 if (!QDF_IS_STATUS_SUCCESS(status)) 13909 hdd_err("Failed to set 11d_enable flag"); 13910 } 13911 } 13912 13913 #ifdef ENABLE_MTRACE_LOG hdd_set_mtrace_for_each(struct hdd_context * hdd_ctx)13914 static void hdd_set_mtrace_for_each(struct hdd_context *hdd_ctx) 13915 { 13916 uint8_t module_id = 0; 13917 int qdf_print_idx = -1; 13918 13919 qdf_print_idx = qdf_get_pidx(); 13920 for (module_id = 0; module_id < QDF_MODULE_ID_MAX; module_id++) 13921 qdf_print_set_category_verbose( 13922 qdf_print_idx, 13923 module_id, QDF_TRACE_LEVEL_TRACE, 13924 hdd_ctx->config->enable_mtrace); 13925 } 13926 #else hdd_set_mtrace_for_each(struct hdd_context * hdd_ctx)13927 static void hdd_set_mtrace_for_each(struct hdd_context *hdd_ctx) 13928 { 13929 } 13930 13931 #endif 13932 13933 /** 13934 * hdd_log_level_to_bitmask() - user space log level to host log bitmask 13935 * @user_log_level: user space log level 13936 * 13937 * Convert log level from user space to host log level bitmask. 13938 * 13939 * Return: Bitmask of log levels to be enabled 13940 */ hdd_log_level_to_bitmask(enum host_log_level user_log_level)13941 static uint32_t hdd_log_level_to_bitmask(enum host_log_level user_log_level) 13942 { 13943 QDF_TRACE_LEVEL host_trace_level; 13944 uint32_t bitmask; 13945 13946 switch (user_log_level) { 13947 case HOST_LOG_LEVEL_NONE: 13948 host_trace_level = QDF_TRACE_LEVEL_NONE; 13949 break; 13950 case HOST_LOG_LEVEL_FATAL: 13951 host_trace_level = QDF_TRACE_LEVEL_FATAL; 13952 break; 13953 case HOST_LOG_LEVEL_ERROR: 13954 host_trace_level = QDF_TRACE_LEVEL_ERROR; 13955 break; 13956 case HOST_LOG_LEVEL_WARN: 13957 host_trace_level = QDF_TRACE_LEVEL_WARN; 13958 break; 13959 case HOST_LOG_LEVEL_INFO: 13960 host_trace_level = QDF_TRACE_LEVEL_INFO_LOW; 13961 break; 13962 case HOST_LOG_LEVEL_DEBUG: 13963 host_trace_level = QDF_TRACE_LEVEL_DEBUG; 13964 break; 13965 case HOST_LOG_LEVEL_TRACE: 13966 host_trace_level = QDF_TRACE_LEVEL_TRACE; 13967 break; 13968 default: 13969 host_trace_level = QDF_TRACE_LEVEL_TRACE; 13970 break; 13971 } 13972 13973 bitmask = (1 << (host_trace_level + 1)) - 1; 13974 13975 return bitmask; 13976 } 13977 13978 /** 13979 * hdd_set_trace_level_for_each - Set trace level for each INI config 13980 * @hdd_ctx: HDD context 13981 * 13982 * Set trace level for each module based on INI config. 13983 * 13984 * Return: None 13985 */ hdd_set_trace_level_for_each(struct hdd_context * hdd_ctx)13986 static void hdd_set_trace_level_for_each(struct hdd_context *hdd_ctx) 13987 { 13988 uint8_t host_module_log[QDF_MODULE_ID_MAX * 2]; 13989 qdf_size_t host_module_log_num = 0; 13990 QDF_MODULE_ID module_id; 13991 uint32_t bitmask; 13992 uint32_t i; 13993 13994 qdf_uint8_array_parse(cfg_get(hdd_ctx->psoc, 13995 CFG_ENABLE_HOST_MODULE_LOG_LEVEL), 13996 host_module_log, 13997 QDF_MODULE_ID_MAX * 2, 13998 &host_module_log_num); 13999 14000 for (i = 0; i + 1 < host_module_log_num; i += 2) { 14001 module_id = host_module_log[i]; 14002 bitmask = hdd_log_level_to_bitmask(host_module_log[i + 1]); 14003 if (module_id < QDF_MODULE_ID_MAX && 14004 module_id >= QDF_MODULE_ID_MIN) 14005 hdd_qdf_trace_enable(module_id, bitmask); 14006 } 14007 14008 hdd_set_mtrace_for_each(hdd_ctx); 14009 } 14010 14011 /** 14012 * hdd_context_init() - Initialize HDD context 14013 * @hdd_ctx: HDD context. 14014 * 14015 * Initialize HDD context along with all the feature specific contexts. 14016 * 14017 * return: 0 on success and errno on failure. 14018 */ hdd_context_init(struct hdd_context * hdd_ctx)14019 static int hdd_context_init(struct hdd_context *hdd_ctx) 14020 { 14021 int ret; 14022 14023 hdd_ctx->ioctl_scan_mode = eSIR_ACTIVE_SCAN; 14024 hdd_ctx->max_intf_count = WLAN_MAX_VDEVS; 14025 14026 init_completion(&hdd_ctx->mc_sus_event_var); 14027 init_completion(&hdd_ctx->ready_to_suspend); 14028 14029 qdf_spinlock_create(&hdd_ctx->connection_status_lock); 14030 qdf_spinlock_create(&hdd_ctx->hdd_adapter_lock); 14031 14032 qdf_list_create(&hdd_ctx->hdd_adapters, 0); 14033 14034 ret = hdd_scan_context_init(hdd_ctx); 14035 if (ret) 14036 goto list_destroy; 14037 14038 ret = hdd_sap_context_init(hdd_ctx); 14039 if (ret) 14040 goto scan_destroy; 14041 14042 ret = ucfg_dp_bbm_context_init(hdd_ctx->psoc); 14043 if (ret) 14044 goto sap_destroy; 14045 14046 wlan_hdd_cfg80211_extscan_init(hdd_ctx); 14047 14048 hdd_init_offloaded_packets_ctx(hdd_ctx); 14049 14050 ret = wlan_hdd_cfg80211_init(hdd_ctx->parent_dev, hdd_ctx->wiphy, 14051 hdd_ctx->config); 14052 if (ret) 14053 goto bbm_destroy; 14054 14055 qdf_wake_lock_create(&hdd_ctx->monitor_mode_wakelock, 14056 "monitor_mode_wakelock"); 14057 hdd_lp_create_work(hdd_ctx); 14058 14059 return 0; 14060 14061 bbm_destroy: 14062 ucfg_dp_bbm_context_deinit(hdd_ctx->psoc); 14063 14064 sap_destroy: 14065 hdd_sap_context_destroy(hdd_ctx); 14066 14067 scan_destroy: 14068 hdd_scan_context_destroy(hdd_ctx); 14069 list_destroy: 14070 qdf_list_destroy(&hdd_ctx->hdd_adapters); 14071 14072 return ret; 14073 } 14074 14075 #ifdef SHUTDOWN_WLAN_IN_SYSTEM_SUSPEND hdd_idle_timer_in_active(uint32_t timeout_ms)14076 static void hdd_idle_timer_in_active(uint32_t timeout_ms) 14077 { 14078 /* do nothing because idle shutdown will be called in system 14079 * suspend prepare 14080 */ 14081 } 14082 #else 14083 /* ensure idle shutdown can be called/finished once timer started */ hdd_idle_timer_in_active(uint32_t timeout_ms)14084 static void hdd_idle_timer_in_active(uint32_t timeout_ms) 14085 { 14086 uint32_t suspend_timeout_ms; 14087 enum wake_lock_reason reason = 14088 WIFI_POWER_EVENT_WAKELOCK_IFACE_CHANGE_TIMER; 14089 14090 suspend_timeout_ms = timeout_ms + HDD_PSOC_IDLE_SHUTDOWN_SUSPEND_DELAY; 14091 hdd_prevent_suspend_timeout(suspend_timeout_ms, reason); 14092 } 14093 #endif 14094 hdd_psoc_idle_timer_start(struct hdd_context * hdd_ctx)14095 void hdd_psoc_idle_timer_start(struct hdd_context *hdd_ctx) 14096 { 14097 uint32_t timeout_ms = hdd_ctx->config->iface_change_wait_time; 14098 14099 if (!timeout_ms) { 14100 hdd_info("psoc idle timer is disabled"); 14101 return; 14102 } 14103 14104 hdd_debug("Starting psoc idle timer"); 14105 14106 /* If PCIe gen speed change is requested, reduce idle shutdown 14107 * timeout to 100 ms 14108 */ 14109 if (hdd_ctx->current_pcie_gen_speed) { 14110 timeout_ms = HDD_PCIE_GEN_SPEED_CHANGE_TIMEOUT_MS; 14111 hdd_info("pcie gen speed change requested"); 14112 } 14113 14114 qdf_delayed_work_start(&hdd_ctx->psoc_idle_timeout_work, timeout_ms); 14115 hdd_idle_timer_in_active(timeout_ms); 14116 } 14117 hdd_psoc_idle_timer_stop(struct hdd_context * hdd_ctx)14118 void hdd_psoc_idle_timer_stop(struct hdd_context *hdd_ctx) 14119 { 14120 qdf_delayed_work_stop_sync(&hdd_ctx->psoc_idle_timeout_work); 14121 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_IFACE_CHANGE_TIMER); 14122 hdd_debug("Stopped psoc idle timer"); 14123 } 14124 14125 14126 /** 14127 * __hdd_psoc_idle_shutdown() - perform an idle shutdown on the given psoc 14128 * @hdd_ctx: the hdd context which should be shutdown 14129 * 14130 * When no interfaces are "up" on a psoc, an idle shutdown timer is started. 14131 * If no interfaces are brought up before the timer expires, we do an 14132 * "idle shutdown," cutting power to the physical SoC to save power. This is 14133 * done completely transparently from the perspective of userspace. 14134 * 14135 * Return: None 14136 */ __hdd_psoc_idle_shutdown(struct hdd_context * hdd_ctx)14137 static int __hdd_psoc_idle_shutdown(struct hdd_context *hdd_ctx) 14138 { 14139 struct osif_psoc_sync *psoc_sync; 14140 int errno; 14141 14142 hdd_enter(); 14143 14144 hdd_reg_wait_for_country_change(hdd_ctx); 14145 14146 errno = osif_psoc_sync_trans_start(hdd_ctx->parent_dev, &psoc_sync); 14147 if (errno) { 14148 hdd_info("psoc busy, abort idle shutdown; errno:%d", errno); 14149 errno = -EAGAIN; 14150 goto exit; 14151 } 14152 14153 osif_psoc_sync_wait_for_ops(psoc_sync); 14154 /* 14155 * This is to handle scenario in which platform driver triggers 14156 * idle_shutdown if Deep Sleep/Hibernate entry notification is 14157 * received from modem subsystem in wearable devices 14158 */ 14159 if (hdd_is_any_interface_open(hdd_ctx)) { 14160 hdd_err_rl("all interfaces are not down, ignore idle shutdown"); 14161 errno = -EAGAIN; 14162 } else { 14163 errno = hdd_wlan_stop_modules(hdd_ctx, false); 14164 } 14165 14166 osif_psoc_sync_trans_stop(psoc_sync); 14167 14168 exit: 14169 hdd_exit(); 14170 return errno; 14171 } 14172 __hdd_mode_change_psoc_idle_shutdown(struct hdd_context * hdd_ctx)14173 static int __hdd_mode_change_psoc_idle_shutdown(struct hdd_context *hdd_ctx) 14174 { 14175 is_mode_change_psoc_idle_shutdown = false; 14176 return hdd_wlan_stop_modules(hdd_ctx, true); 14177 } 14178 hdd_psoc_idle_shutdown(struct device * dev)14179 int hdd_psoc_idle_shutdown(struct device *dev) 14180 { 14181 int ret; 14182 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 14183 14184 if (!hdd_ctx) 14185 return -EINVAL; 14186 14187 if (is_mode_change_psoc_idle_shutdown) 14188 ret = __hdd_mode_change_psoc_idle_shutdown(hdd_ctx); 14189 else { 14190 ret = __hdd_psoc_idle_shutdown(hdd_ctx); 14191 } 14192 14193 return ret; 14194 } 14195 __hdd_psoc_idle_restart(struct hdd_context * hdd_ctx)14196 static int __hdd_psoc_idle_restart(struct hdd_context *hdd_ctx) 14197 { 14198 int ret; 14199 14200 ret = hdd_soc_idle_restart_lock(hdd_ctx->parent_dev); 14201 if (ret) 14202 return ret; 14203 14204 ret = hdd_wlan_start_modules(hdd_ctx, false); 14205 14206 if (!qdf_is_fw_down()) 14207 cds_set_recovery_in_progress(false); 14208 14209 hdd_soc_idle_restart_unlock(); 14210 14211 return ret; 14212 } 14213 hdd_psoc_idle_restart(struct device * dev)14214 int hdd_psoc_idle_restart(struct device *dev) 14215 { 14216 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 14217 14218 if (!hdd_ctx) 14219 return -EINVAL; 14220 14221 return __hdd_psoc_idle_restart(hdd_ctx); 14222 } 14223 hdd_trigger_psoc_idle_restart(struct hdd_context * hdd_ctx)14224 int hdd_trigger_psoc_idle_restart(struct hdd_context *hdd_ctx) 14225 { 14226 int ret; 14227 14228 QDF_BUG(rtnl_is_locked()); 14229 14230 hdd_psoc_idle_timer_stop(hdd_ctx); 14231 if (hdd_ctx->driver_status == DRIVER_MODULES_ENABLED) { 14232 hdd_nofl_debug("Driver modules already Enabled"); 14233 return 0; 14234 } 14235 14236 ret = hdd_soc_idle_restart_lock(hdd_ctx->parent_dev); 14237 if (ret) 14238 return ret; 14239 14240 if (hdd_ctx->current_pcie_gen_speed) { 14241 hdd_info("request pcie gen speed change to %d", 14242 hdd_ctx->current_pcie_gen_speed); 14243 14244 /* call pld api for pcie gen speed change */ 14245 ret = pld_set_pcie_gen_speed(hdd_ctx->parent_dev, 14246 hdd_ctx->current_pcie_gen_speed); 14247 if (ret) 14248 hdd_err_rl("failed to set pcie gen speed"); 14249 14250 hdd_ctx->current_pcie_gen_speed = 0; 14251 } 14252 14253 qdf_event_reset(&hdd_ctx->regulatory_update_event); 14254 qdf_mutex_acquire(&hdd_ctx->regulatory_status_lock); 14255 hdd_ctx->is_regulatory_update_in_progress = true; 14256 qdf_mutex_release(&hdd_ctx->regulatory_status_lock); 14257 14258 ret = pld_idle_restart(hdd_ctx->parent_dev, hdd_psoc_idle_restart); 14259 hdd_soc_idle_restart_unlock(); 14260 14261 return ret; 14262 } 14263 14264 /** 14265 * hdd_psoc_idle_timeout_callback() - Handler for psoc idle timeout 14266 * @priv: pointer to hdd context 14267 * 14268 * Return: None 14269 */ hdd_psoc_idle_timeout_callback(void * priv)14270 static void hdd_psoc_idle_timeout_callback(void *priv) 14271 { 14272 int ret; 14273 struct hdd_context *hdd_ctx = priv; 14274 void *hif_ctx; 14275 14276 if (wlan_hdd_validate_context(hdd_ctx)) 14277 return; 14278 14279 hif_ctx = cds_get_context(QDF_MODULE_ID_HIF); 14280 if (hif_ctx) { 14281 /* 14282 * Trigger runtime sync resume before psoc_idle_shutdown 14283 * such that resume can happen successfully 14284 */ 14285 qdf_rtpm_sync_resume(); 14286 } 14287 14288 hdd_info("Psoc idle timeout elapsed; starting psoc shutdown"); 14289 14290 ret = pld_idle_shutdown(hdd_ctx->parent_dev, hdd_psoc_idle_shutdown); 14291 if (-EAGAIN == ret || hdd_ctx->is_wiphy_suspended) { 14292 hdd_debug("System suspend in progress. Restart idle shutdown timer"); 14293 hdd_psoc_idle_timer_start(hdd_ctx); 14294 } 14295 14296 /* Clear the recovery flag for PCIe discrete soc after idle shutdown*/ 14297 if (PLD_BUS_TYPE_PCIE == pld_get_bus_type(hdd_ctx->parent_dev) && 14298 -EBUSY != ret) 14299 cds_set_recovery_in_progress(false); 14300 } 14301 14302 #ifdef WLAN_LOGGING_SOCK_SVC_ENABLE hdd_set_wlan_logging(struct hdd_context * hdd_ctx)14303 static void hdd_set_wlan_logging(struct hdd_context *hdd_ctx) 14304 { 14305 wlan_set_console_log_levels(hdd_ctx->config->wlan_console_log_levels); 14306 wlan_logging_set_active(hdd_ctx->config->wlan_logging_enable); 14307 } 14308 #else hdd_set_wlan_logging(struct hdd_context * hdd_ctx)14309 static void hdd_set_wlan_logging(struct hdd_context *hdd_ctx) 14310 { } 14311 #endif 14312 14313 #ifdef WLAN_LOGGING_SOCK_SVC_ENABLE hdd_init_wlan_logging_params(struct hdd_config * config,struct wlan_objmgr_psoc * psoc)14314 static void hdd_init_wlan_logging_params(struct hdd_config *config, 14315 struct wlan_objmgr_psoc *psoc) 14316 { 14317 config->wlan_logging_enable = cfg_get(psoc, CFG_WLAN_LOGGING_SUPPORT); 14318 14319 config->wlan_console_log_levels = 14320 cfg_get(psoc, CFG_WLAN_LOGGING_CONSOLE_SUPPORT); 14321 config->host_log_custom_nl_proto = 14322 cfg_get(psoc, CFG_HOST_LOG_CUSTOM_NETLINK_PROTO); 14323 } 14324 #else hdd_init_wlan_logging_params(struct hdd_config * config,struct wlan_objmgr_psoc * psoc)14325 static void hdd_init_wlan_logging_params(struct hdd_config *config, 14326 struct wlan_objmgr_psoc *psoc) 14327 { 14328 } 14329 #endif 14330 14331 #ifdef FEATURE_WLAN_AUTO_SHUTDOWN hdd_init_wlan_auto_shutdown(struct hdd_config * config,struct wlan_objmgr_psoc * psoc)14332 static void hdd_init_wlan_auto_shutdown(struct hdd_config *config, 14333 struct wlan_objmgr_psoc *psoc) 14334 { 14335 config->wlan_auto_shutdown = cfg_get(psoc, CFG_WLAN_AUTO_SHUTDOWN); 14336 } 14337 #else hdd_init_wlan_auto_shutdown(struct hdd_config * config,struct wlan_objmgr_psoc * psoc)14338 static void hdd_init_wlan_auto_shutdown(struct hdd_config *config, 14339 struct wlan_objmgr_psoc *psoc) 14340 { 14341 } 14342 #endif 14343 14344 #ifndef REMOVE_PKT_LOG hdd_init_packet_log(struct hdd_config * config,struct wlan_objmgr_psoc * psoc)14345 static void hdd_init_packet_log(struct hdd_config *config, 14346 struct wlan_objmgr_psoc *psoc) 14347 { 14348 config->enable_packet_log = cfg_get(psoc, CFG_ENABLE_PACKET_LOG); 14349 } 14350 #else hdd_init_packet_log(struct hdd_config * config,struct wlan_objmgr_psoc * psoc)14351 static void hdd_init_packet_log(struct hdd_config *config, 14352 struct wlan_objmgr_psoc *psoc) 14353 { 14354 } 14355 #endif 14356 14357 #ifdef ENABLE_MTRACE_LOG hdd_init_mtrace_log(struct hdd_config * config,struct wlan_objmgr_psoc * psoc)14358 static void hdd_init_mtrace_log(struct hdd_config *config, 14359 struct wlan_objmgr_psoc *psoc) 14360 { 14361 config->enable_mtrace = cfg_get(psoc, CFG_ENABLE_MTRACE); 14362 } 14363 #else hdd_init_mtrace_log(struct hdd_config * config,struct wlan_objmgr_psoc * psoc)14364 static void hdd_init_mtrace_log(struct hdd_config *config, 14365 struct wlan_objmgr_psoc *psoc) 14366 { 14367 } 14368 #endif 14369 14370 #ifdef FEATURE_RUNTIME_PM hdd_init_runtime_pm(struct hdd_config * config,struct wlan_objmgr_psoc * psoc)14371 static void hdd_init_runtime_pm(struct hdd_config *config, 14372 struct wlan_objmgr_psoc *psoc) 14373 { 14374 config->runtime_pm = cfg_get(psoc, CFG_ENABLE_RUNTIME_PM); 14375 } 14376 hdd_is_runtime_pm_enabled(struct hdd_context * hdd_ctx)14377 bool hdd_is_runtime_pm_enabled(struct hdd_context *hdd_ctx) 14378 { 14379 return hdd_ctx->config->runtime_pm != hdd_runtime_pm_disabled; 14380 } 14381 #else hdd_init_runtime_pm(struct hdd_config * config,struct wlan_objmgr_psoc * psoc)14382 static void hdd_init_runtime_pm(struct hdd_config *config, 14383 struct wlan_objmgr_psoc *psoc) 14384 14385 { 14386 } 14387 hdd_is_runtime_pm_enabled(struct hdd_context * hdd_ctx)14388 bool hdd_is_runtime_pm_enabled(struct hdd_context *hdd_ctx) 14389 { 14390 return false; 14391 } 14392 #endif 14393 14394 #ifdef WLAN_FEATURE_WMI_SEND_RECV_QMI hdd_init_qmi_stats(struct hdd_config * config,struct wlan_objmgr_psoc * psoc)14395 static void hdd_init_qmi_stats(struct hdd_config *config, 14396 struct wlan_objmgr_psoc *psoc) 14397 { 14398 config->is_qmi_stats_enabled = cfg_get(psoc, CFG_ENABLE_QMI_STATS); 14399 } 14400 #else hdd_init_qmi_stats(struct hdd_config * config,struct wlan_objmgr_psoc * psoc)14401 static void hdd_init_qmi_stats(struct hdd_config *config, 14402 struct wlan_objmgr_psoc *psoc) 14403 14404 { 14405 } 14406 #endif 14407 14408 #ifdef FEATURE_WLAN_DYNAMIC_CVM hdd_init_vc_mode_cfg_bitmap(struct hdd_config * config,struct wlan_objmgr_psoc * psoc)14409 static void hdd_init_vc_mode_cfg_bitmap(struct hdd_config *config, 14410 struct wlan_objmgr_psoc *psoc) 14411 { 14412 config->vc_mode_cfg_bitmap = cfg_get(psoc, CFG_VC_MODE_BITMAP); 14413 } 14414 #else hdd_init_vc_mode_cfg_bitmap(struct hdd_config * config,struct wlan_objmgr_psoc * psoc)14415 static void hdd_init_vc_mode_cfg_bitmap(struct hdd_config *config, 14416 struct wlan_objmgr_psoc *psoc) 14417 { 14418 } 14419 #endif 14420 14421 #ifdef DHCP_SERVER_OFFLOAD 14422 static void hdd_init_dhcp_server_ip(struct hdd_context * hdd_ctx)14423 hdd_init_dhcp_server_ip(struct hdd_context *hdd_ctx) 14424 { 14425 uint8_t num_entries; 14426 14427 hdd_ctx->config->dhcp_server_ip.is_dhcp_server_ip_valid = true; 14428 hdd_string_to_u8_array(cfg_get(hdd_ctx->psoc, CFG_DHCP_SERVER_IP_NAME), 14429 hdd_ctx->config->dhcp_server_ip.dhcp_server_ip, 14430 &num_entries, IPADDR_NUM_ENTRIES); 14431 14432 if (num_entries != IPADDR_NUM_ENTRIES) { 14433 hdd_err("Incorrect IP address (%s) assigned for DHCP server!", 14434 cfg_get(hdd_ctx->psoc, CFG_DHCP_SERVER_IP_NAME)); 14435 hdd_config->dhcp_server_ip.is_dhcp_server_ip_valid = false; 14436 } 14437 } 14438 #else 14439 static void hdd_init_dhcp_server_ip(struct hdd_context * hdd_ctx)14440 hdd_init_dhcp_server_ip(struct hdd_context *hdd_ctx) 14441 { 14442 } 14443 #endif 14444 14445 #ifdef SAR_SAFETY_FEATURE hdd_sar_cfg_update(struct hdd_config * config,struct wlan_objmgr_psoc * psoc)14446 static void hdd_sar_cfg_update(struct hdd_config *config, 14447 struct wlan_objmgr_psoc *psoc) 14448 { 14449 config->sar_safety_timeout = cfg_get(psoc, CFG_SAR_SAFETY_TIMEOUT); 14450 config->sar_safety_unsolicited_timeout = 14451 cfg_get(psoc, CFG_SAR_SAFETY_UNSOLICITED_TIMEOUT); 14452 config->sar_safety_req_resp_timeout = 14453 cfg_get(psoc, CFG_SAR_SAFETY_REQ_RESP_TIMEOUT); 14454 config->sar_safety_req_resp_retry = 14455 cfg_get(psoc, CFG_SAR_SAFETY_REQ_RESP_RETRIES); 14456 config->sar_safety_index = cfg_get(psoc, CFG_SAR_SAFETY_INDEX); 14457 config->sar_safety_sleep_index = 14458 cfg_get(psoc, CFG_SAR_SAFETY_SLEEP_INDEX); 14459 config->enable_sar_safety = 14460 cfg_get(psoc, CFG_ENABLE_SAR_SAFETY_FEATURE); 14461 config->config_sar_safety_sleep_index = 14462 cfg_get(psoc, CFG_CONFIG_SAR_SAFETY_SLEEP_MODE_INDEX); 14463 } 14464 hdd_set_sar_init_index(struct hdd_context * hdd_ctx)14465 void hdd_set_sar_init_index(struct hdd_context *hdd_ctx) 14466 { 14467 uint32_t index, enable = 0; 14468 14469 if (!hdd_ctx) { 14470 hdd_err("hdd_ctx NULL"); 14471 return; 14472 } 14473 if (hdd_ctx->sar_version == SAR_VERSION_1) { 14474 hdd_nofl_debug("FW SAR version: %d", hdd_ctx->sar_version); 14475 return; 14476 } 14477 14478 enable = hdd_ctx->config->enable_sar_safety; 14479 index = hdd_ctx->config->sar_safety_index; 14480 if (enable & SAR_SAFETY_ENABLED_INIT) 14481 hdd_configure_sar_index(hdd_ctx, index); 14482 } 14483 #else hdd_sar_cfg_update(struct hdd_config * config,struct wlan_objmgr_psoc * psoc)14484 static void hdd_sar_cfg_update(struct hdd_config *config, 14485 struct wlan_objmgr_psoc *psoc) 14486 { 14487 } 14488 #endif 14489 14490 #ifdef FEATURE_SET 14491 /** 14492 * hdd_get_wifi_features_cfg_update() - Initialize get wifi features cfg 14493 * @config: Pointer to HDD config 14494 * @psoc: psoc pointer 14495 * 14496 * Return: None 14497 */ hdd_get_wifi_features_cfg_update(struct hdd_config * config,struct wlan_objmgr_psoc * psoc)14498 static void hdd_get_wifi_features_cfg_update(struct hdd_config *config, 14499 struct wlan_objmgr_psoc *psoc) 14500 { 14501 config->get_wifi_features = cfg_get(psoc, CFG_GET_WIFI_FEATURES); 14502 } 14503 #else hdd_get_wifi_features_cfg_update(struct hdd_config * config,struct wlan_objmgr_psoc * psoc)14504 static void hdd_get_wifi_features_cfg_update(struct hdd_config *config, 14505 struct wlan_objmgr_psoc *psoc) 14506 { 14507 } 14508 #endif 14509 14510 #ifdef FEATURE_RUNTIME_PM 14511 /** 14512 * hdd_init_cpu_cxpc_threshold_cfg() - Initialize cpu cxpc threshold cfg 14513 * @config: Pointer to HDD config 14514 * @psoc: psoc pointer 14515 * 14516 * Return: None 14517 */ hdd_init_cpu_cxpc_threshold_cfg(struct hdd_config * config,struct wlan_objmgr_psoc * psoc)14518 static void hdd_init_cpu_cxpc_threshold_cfg(struct hdd_config *config, 14519 struct wlan_objmgr_psoc *psoc) 14520 { 14521 config->cpu_cxpc_threshold = cfg_get(psoc, CFG_CPU_CXPC_THRESHOLD); 14522 } 14523 #else hdd_init_cpu_cxpc_threshold_cfg(struct hdd_config * config,struct wlan_objmgr_psoc * psoc)14524 static void hdd_init_cpu_cxpc_threshold_cfg(struct hdd_config *config, 14525 struct wlan_objmgr_psoc *psoc) 14526 { 14527 } 14528 #endif 14529 14530 /** 14531 * hdd_cfg_params_init() - Initialize hdd params in hdd_config structure 14532 * @hdd_ctx: Pointer to HDD context 14533 * 14534 * Return: None 14535 */ hdd_cfg_params_init(struct hdd_context * hdd_ctx)14536 static void hdd_cfg_params_init(struct hdd_context *hdd_ctx) 14537 { 14538 struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc; 14539 struct hdd_config *config = hdd_ctx->config; 14540 if (!psoc) { 14541 hdd_err("Invalid psoc"); 14542 return; 14543 } 14544 14545 if (!config) { 14546 hdd_err("Invalid hdd config"); 14547 return; 14548 } 14549 14550 config->dot11Mode = cfg_get(psoc, CFG_HDD_DOT11_MODE); 14551 config->bug_on_reinit_failure = cfg_get(psoc, 14552 CFG_BUG_ON_REINIT_FAILURE); 14553 14554 config->is_ramdump_enabled = cfg_get(psoc, 14555 CFG_ENABLE_RAMDUMP_COLLECTION); 14556 14557 config->iface_change_wait_time = cfg_get(psoc, 14558 CFG_INTERFACE_CHANGE_WAIT); 14559 14560 config->multicast_host_fw_msgs = cfg_get(psoc, 14561 CFG_MULTICAST_HOST_FW_MSGS); 14562 14563 config->private_wext_control = cfg_get(psoc, CFG_PRIVATE_WEXT_CONTROL); 14564 config->enablefwprint = cfg_get(psoc, CFG_ENABLE_FW_UART_PRINT); 14565 config->enable_fw_log = cfg_get(psoc, CFG_ENABLE_FW_LOG); 14566 config->operating_chan_freq = cfg_get(psoc, CFG_OPERATING_FREQUENCY); 14567 config->num_vdevs = cfg_get(psoc, CFG_NUM_VDEV_ENABLE); 14568 qdf_str_lcopy(config->enable_concurrent_sta, 14569 cfg_get(psoc, CFG_ENABLE_CONCURRENT_STA), 14570 CFG_CONCURRENT_IFACE_MAX_LEN); 14571 qdf_str_lcopy(config->dbs_scan_selection, 14572 cfg_get(psoc, CFG_DBS_SCAN_SELECTION), 14573 CFG_DBS_SCAN_PARAM_LENGTH); 14574 config->inform_bss_rssi_raw = cfg_get(psoc, CFG_INFORM_BSS_RSSI_RAW); 14575 config->mac_provision = cfg_get(psoc, CFG_ENABLE_MAC_PROVISION); 14576 config->provisioned_intf_pool = 14577 cfg_get(psoc, CFG_PROVISION_INTERFACE_POOL); 14578 config->derived_intf_pool = cfg_get(psoc, CFG_DERIVED_INTERFACE_POOL); 14579 config->advertise_concurrent_operation = 14580 cfg_get(psoc, 14581 CFG_ADVERTISE_CONCURRENT_OPERATION); 14582 config->is_unit_test_framework_enabled = 14583 cfg_get(psoc, CFG_ENABLE_UNIT_TEST_FRAMEWORK); 14584 config->disable_channel = cfg_get(psoc, CFG_ENABLE_DISABLE_CHANNEL); 14585 config->enable_sar_conversion = cfg_get(psoc, CFG_SAR_CONVERSION); 14586 config->nb_commands_interval = 14587 cfg_get(psoc, CFG_NB_COMMANDS_RATE_LIMIT); 14588 14589 hdd_init_vc_mode_cfg_bitmap(config, psoc); 14590 hdd_init_runtime_pm(config, psoc); 14591 hdd_init_wlan_auto_shutdown(config, psoc); 14592 hdd_init_wlan_logging_params(config, psoc); 14593 hdd_init_packet_log(config, psoc); 14594 hdd_init_mtrace_log(config, psoc); 14595 hdd_init_dhcp_server_ip(hdd_ctx); 14596 hdd_dp_cfg_update(psoc, hdd_ctx); 14597 hdd_sar_cfg_update(config, psoc); 14598 hdd_init_qmi_stats(config, psoc); 14599 hdd_club_ll_stats_in_get_sta_cfg_update(config, psoc); 14600 config->read_mac_addr_from_mac_file = 14601 cfg_get(psoc, CFG_READ_MAC_ADDR_FROM_MAC_FILE); 14602 14603 hdd_get_wifi_features_cfg_update(config, psoc); 14604 hdd_init_cpu_cxpc_threshold_cfg(config, psoc); 14605 14606 config->exclude_selftx_from_cca_busy = 14607 cfg_get(psoc, CFG_EXCLUDE_SELFTX_FROM_CCA_BUSY_TIME); 14608 hdd_init_link_state_cfg(config, psoc); 14609 } 14610 14611 #ifdef CONNECTION_ROAMING_CFG hdd_cfg_parse_connection_roaming_cfg(void)14612 static QDF_STATUS hdd_cfg_parse_connection_roaming_cfg(void) 14613 { 14614 QDF_STATUS status = QDF_STATUS_E_INVAL; 14615 bool is_valid; 14616 14617 is_valid = cfg_valid_ini_check(WLAN_CONNECTION_ROAMING_INI_FILE); 14618 14619 if (is_valid) 14620 status = cfg_parse(WLAN_CONNECTION_ROAMING_INI_FILE); 14621 if (QDF_IS_STATUS_ERROR(status)) { 14622 is_valid = cfg_valid_ini_check(WLAN_CONNECTION_ROAMING_BACKUP_INI_FILE); 14623 if (is_valid) 14624 status = cfg_parse(WLAN_CONNECTION_ROAMING_BACKUP_INI_FILE); 14625 } 14626 return status; 14627 } 14628 #else hdd_cfg_parse_connection_roaming_cfg(void)14629 static inline QDF_STATUS hdd_cfg_parse_connection_roaming_cfg(void) 14630 { 14631 return QDF_STATUS_E_NOSUPPORT; 14632 } 14633 #endif 14634 hdd_context_create(struct device * dev)14635 struct hdd_context *hdd_context_create(struct device *dev) 14636 { 14637 QDF_STATUS status; 14638 int ret = 0; 14639 struct hdd_context *hdd_ctx; 14640 14641 hdd_enter(); 14642 14643 hdd_ctx = hdd_cfg80211_wiphy_alloc(); 14644 if (!hdd_ctx) { 14645 ret = -ENOMEM; 14646 goto err_out; 14647 } 14648 14649 status = qdf_delayed_work_create(&hdd_ctx->psoc_idle_timeout_work, 14650 hdd_psoc_idle_timeout_callback, 14651 hdd_ctx); 14652 if (QDF_IS_STATUS_ERROR(status)) { 14653 ret = qdf_status_to_os_return(status); 14654 goto wiphy_dealloc; 14655 } 14656 14657 hdd_pm_notifier_init(hdd_ctx); 14658 14659 hdd_ctx->parent_dev = dev; 14660 hdd_ctx->last_scan_reject_vdev_id = WLAN_UMAC_VDEV_ID_MAX; 14661 14662 hdd_ctx->config = qdf_mem_malloc(sizeof(struct hdd_config)); 14663 if (!hdd_ctx->config) { 14664 ret = -ENOMEM; 14665 goto err_free_hdd_context; 14666 } 14667 14668 status = cfg_parse(WLAN_INI_FILE); 14669 if (QDF_IS_STATUS_ERROR(status)) { 14670 hdd_err("Failed to parse cfg %s; status:%d\n", 14671 WLAN_INI_FILE, status); 14672 /* Assert if failed to parse at least one INI parameter */ 14673 QDF_BUG(status != QDF_STATUS_E_INVAL); 14674 ret = qdf_status_to_os_return(status); 14675 goto err_free_config; 14676 } 14677 14678 status = hdd_cfg_parse_connection_roaming_cfg(); 14679 14680 ret = hdd_objmgr_create_and_store_psoc(hdd_ctx, DEFAULT_PSOC_ID); 14681 if (ret) { 14682 QDF_DEBUG_PANIC("Psoc creation fails!"); 14683 goto err_release_store; 14684 } 14685 14686 if (QDF_IS_STATUS_SUCCESS(status)) 14687 ucfg_mlme_set_connection_roaming_ini_present(hdd_ctx->psoc, 14688 true); 14689 14690 hdd_cfg_params_init(hdd_ctx); 14691 14692 /* apply multiplier config, if not already set via module parameter */ 14693 if (qdf_timer_get_multiplier() == 1) 14694 qdf_timer_set_multiplier(cfg_get(hdd_ctx->psoc, 14695 CFG_TIMER_MULTIPLIER)); 14696 hdd_debug("set timer multiplier: %u", qdf_timer_get_multiplier()); 14697 14698 cds_set_fatal_event(cfg_get(hdd_ctx->psoc, 14699 CFG_ENABLE_FATAL_EVENT_TRIGGER)); 14700 14701 hdd_override_ini_config(hdd_ctx); 14702 14703 ret = hdd_context_init(hdd_ctx); 14704 14705 if (ret) 14706 goto err_hdd_objmgr_destroy; 14707 14708 if (hdd_get_conparam() == QDF_GLOBAL_EPPING_MODE) 14709 goto skip_multicast_logging; 14710 14711 cds_set_multicast_logging(hdd_ctx->config->multicast_host_fw_msgs); 14712 ret = hdd_init_netlink_services(hdd_ctx); 14713 if (ret) 14714 goto err_deinit_hdd_context; 14715 14716 hdd_set_wlan_logging(hdd_ctx); 14717 qdf_atomic_init(&hdd_ctx->adapter_ops_history.index); 14718 14719 skip_multicast_logging: 14720 hdd_set_trace_level_for_each(hdd_ctx); 14721 14722 cds_set_context(QDF_MODULE_ID_HDD, hdd_ctx); 14723 14724 wlan_hdd_sar_timers_init(hdd_ctx); 14725 14726 hdd_exit(); 14727 14728 return hdd_ctx; 14729 14730 err_deinit_hdd_context: 14731 hdd_context_deinit(hdd_ctx); 14732 14733 err_hdd_objmgr_destroy: 14734 hdd_objmgr_release_and_destroy_psoc(hdd_ctx); 14735 14736 err_release_store: 14737 cfg_release(); 14738 14739 err_free_config: 14740 qdf_mem_free(hdd_ctx->config); 14741 14742 err_free_hdd_context: 14743 qdf_delayed_work_destroy(&hdd_ctx->psoc_idle_timeout_work); 14744 14745 wiphy_dealloc: 14746 wiphy_free(hdd_ctx->wiphy); 14747 14748 err_out: 14749 return ERR_PTR(ret); 14750 } 14751 14752 #ifdef MULTI_CLIENT_LL_SUPPORT 14753 /** 14754 * wlan_hdd_init_multi_client_info_table()- Initialize the multi client info 14755 * table 14756 * @adapter: hdd adapter 14757 * 14758 * Return: none 14759 */ 14760 static void wlan_hdd_init_multi_client_info_table(struct hdd_adapter * adapter)14761 wlan_hdd_init_multi_client_info_table(struct hdd_adapter *adapter) 14762 { 14763 uint8_t i; 14764 14765 for (i = 0; i < WLM_MAX_HOST_CLIENT; i++) { 14766 adapter->client_info[i].client_id = i; 14767 adapter->client_info[i].port_id = 0; 14768 adapter->client_info[i].in_use = false; 14769 } 14770 } 14771 wlan_hdd_deinit_multi_client_info_table(struct hdd_adapter * adapter)14772 void wlan_hdd_deinit_multi_client_info_table(struct hdd_adapter *adapter) 14773 { 14774 uint8_t i; 14775 14776 hdd_debug("deinitializing the client info table"); 14777 /* de-initialize the table for host driver client */ 14778 for (i = 0; i < WLM_MAX_HOST_CLIENT; i++) { 14779 if (adapter->client_info[i].in_use) { 14780 adapter->client_info[i].port_id = 0; 14781 adapter->client_info[i].client_id = i; 14782 adapter->client_info[i].in_use = false; 14783 } 14784 } 14785 } 14786 14787 /** 14788 * wlan_hdd_get_host_driver_port_id()- get host driver port id 14789 * @port_id: argument to be filled 14790 * 14791 * Return: none 14792 */ wlan_hdd_get_host_driver_port_id(uint32_t * port_id)14793 static void wlan_hdd_get_host_driver_port_id(uint32_t *port_id) 14794 { 14795 *port_id = WLAM_WLM_HOST_DRIVER_PORT_ID; 14796 } 14797 14798 #else 14799 static inline void wlan_hdd_init_multi_client_info_table(struct hdd_adapter * adapter)14800 wlan_hdd_init_multi_client_info_table(struct hdd_adapter *adapter) 14801 { 14802 } 14803 wlan_hdd_get_host_driver_port_id(uint32_t * port_id)14804 static inline void wlan_hdd_get_host_driver_port_id(uint32_t *port_id) 14805 { 14806 } 14807 #endif 14808 14809 static void hdd_adapter_set_wlm_client_latency_level(struct hdd_adapter * adapter)14810 hdd_adapter_set_wlm_client_latency_level(struct hdd_adapter *adapter) 14811 { 14812 QDF_STATUS status; 14813 bool reset; 14814 uint32_t port_id; 14815 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); 14816 14817 if (!hdd_ctx) 14818 return; 14819 14820 status = ucfg_mlme_cfg_get_wlm_reset(hdd_ctx->psoc, &reset); 14821 if (QDF_IS_STATUS_ERROR(status)) { 14822 hdd_err("could not get the wlm reset flag"); 14823 reset = false; 14824 } 14825 14826 if (reset) 14827 goto out; 14828 14829 if (hdd_get_multi_client_ll_support(adapter)) { 14830 wlan_hdd_get_host_driver_port_id(&port_id); 14831 status = wlan_hdd_set_wlm_client_latency_level( 14832 adapter, port_id, 14833 adapter->latency_level); 14834 if (QDF_IS_STATUS_ERROR(status)) 14835 hdd_warn("Fail to set latency level:%u", status); 14836 } else { 14837 status = sme_set_wlm_latency_level(hdd_ctx->mac_handle, 14838 adapter->deflink->vdev_id, 14839 adapter->latency_level, 14840 0, false); 14841 if (QDF_IS_STATUS_ERROR(status)) 14842 hdd_warn("set wlm mode failed, %u", status); 14843 } 14844 out: 14845 hdd_debug("wlm initial mode %u", adapter->latency_level); 14846 } 14847 14848 #ifdef WLAN_HDD_MULTI_VDEV_SINGLE_NDEV 14849 struct qdf_mac_addr * hdd_adapter_get_link_mac_addr(struct wlan_hdd_link_info * link_info)14850 hdd_adapter_get_link_mac_addr(struct wlan_hdd_link_info *link_info) 14851 { 14852 struct hdd_adapter *adapter; 14853 14854 if (!link_info) 14855 return NULL; 14856 14857 adapter = link_info->adapter; 14858 if (!hdd_adapter_is_ml_adapter(adapter) || 14859 qdf_is_macaddr_zero(&link_info->link_addr) || 14860 !wlan_vdev_mlme_is_mlo_vdev(link_info->vdev)) 14861 return &adapter->mac_addr; 14862 14863 return &link_info->link_addr; 14864 } 14865 #else 14866 struct qdf_mac_addr * hdd_adapter_get_link_mac_addr(struct wlan_hdd_link_info * link_info)14867 hdd_adapter_get_link_mac_addr(struct wlan_hdd_link_info *link_info) 14868 { 14869 if (!link_info) 14870 return NULL; 14871 14872 return &link_info->adapter->mac_addr; 14873 } 14874 #endif 14875 14876 #if defined(WLAN_FEATURE_11BE_MLO) && defined(CFG80211_11BE_BASIC) && \ 14877 defined(WLAN_HDD_MULTI_VDEV_SINGLE_NDEV) hdd_adapter_check_duplicate_session(struct hdd_adapter * adapter)14878 QDF_STATUS hdd_adapter_check_duplicate_session(struct hdd_adapter *adapter) 14879 { 14880 int i = 0; 14881 QDF_STATUS status; 14882 uint8_t *addr_list[WLAN_MAX_MLD + 2] = {0}; 14883 struct wlan_hdd_link_info *link_info; 14884 14885 if (!hdd_adapter_is_ml_adapter(adapter) || 14886 adapter->device_mode == QDF_SAP_MODE) 14887 goto netdev_addr; 14888 14889 hdd_adapter_for_each_active_link_info(adapter, link_info) 14890 addr_list[i++] = &link_info->link_addr.bytes[0]; 14891 14892 netdev_addr: 14893 addr_list[i] = &adapter->mac_addr.bytes[0]; 14894 status = sme_check_for_duplicate_session(adapter->hdd_ctx->mac_handle, 14895 &addr_list[0]); 14896 return status; 14897 } 14898 hdd_adapter_fill_link_address(struct hdd_adapter * adapter)14899 QDF_STATUS hdd_adapter_fill_link_address(struct hdd_adapter *adapter) 14900 { 14901 int i = 0; 14902 QDF_STATUS status; 14903 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); 14904 enum QDF_OPMODE opmode = adapter->device_mode; 14905 struct qdf_mac_addr link_addrs[WLAN_MAX_ML_BSS_LINKS] = {0}; 14906 struct wlan_hdd_link_info *link_info; 14907 14908 if (opmode != QDF_STA_MODE && opmode != QDF_SAP_MODE) 14909 return QDF_STATUS_SUCCESS; 14910 14911 if (opmode == QDF_SAP_MODE) { 14912 link_info = adapter->deflink; 14913 qdf_copy_macaddr(&link_info->link_addr, &adapter->mac_addr); 14914 return QDF_STATUS_SUCCESS; 14915 } 14916 14917 if (!hdd_adapter_is_ml_adapter(adapter)) 14918 return QDF_STATUS_SUCCESS; 14919 14920 status = hdd_derive_link_address_from_mld(hdd_ctx->psoc, 14921 &adapter->mac_addr, 14922 &link_addrs[0], 14923 WLAN_MAX_ML_BSS_LINKS); 14924 if (QDF_IS_STATUS_ERROR(status)) 14925 return status; 14926 14927 hdd_adapter_for_each_link_info(adapter, link_info) 14928 qdf_copy_macaddr(&link_info->link_addr, &link_addrs[i++]); 14929 14930 return status; 14931 } 14932 #elif defined(WLAN_FEATURE_11BE_MLO) && defined(CFG80211_11BE_BASIC) hdd_adapter_check_duplicate_session(struct hdd_adapter * adapter)14933 QDF_STATUS hdd_adapter_check_duplicate_session(struct hdd_adapter *adapter) 14934 { 14935 int i; 14936 QDF_STATUS status; 14937 uint8_t *addr_list[WLAN_MAX_MLD + 1] = {0}; 14938 struct hdd_adapter *link_adapter; 14939 struct hdd_mlo_adapter_info *mlo_adapter_info; 14940 mac_handle_t mac_handle = hdd_adapter_get_mac_handle(adapter); 14941 14942 if (hdd_adapter_is_ml_adapter(adapter) && 14943 adapter->device_mode == QDF_STA_MODE) { 14944 addr_list[0] = &adapter->mld_addr.bytes[0]; 14945 mlo_adapter_info = &adapter->mlo_adapter_info; 14946 for (i = 0; i < WLAN_MAX_MLD; i++) { 14947 link_adapter = mlo_adapter_info->link_adapter[i]; 14948 if (!link_adapter) 14949 continue; 14950 if (hdd_adapter_is_associated_with_ml_adapter( 14951 link_adapter)) { 14952 addr_list[1] = &link_adapter->mac_addr.bytes[0]; 14953 } 14954 } 14955 } else { 14956 addr_list[0] = &adapter->mac_addr.bytes[0]; 14957 } 14958 14959 status = sme_check_for_duplicate_session(mac_handle, &addr_list[0]); 14960 return status; 14961 } 14962 #else hdd_adapter_check_duplicate_session(struct hdd_adapter * adapter)14963 QDF_STATUS hdd_adapter_check_duplicate_session(struct hdd_adapter *adapter) 14964 { 14965 QDF_STATUS status; 14966 uint8_t *addr_list[2] = {0}; 14967 mac_handle_t mac_handle = hdd_adapter_get_mac_handle(adapter); 14968 14969 addr_list[0] = &adapter->mac_addr.bytes[0]; 14970 status = sme_check_for_duplicate_session(mac_handle, &addr_list[0]); 14971 14972 return status; 14973 } 14974 #endif 14975 hdd_restore_info_for_ssr(struct hdd_adapter * adapter)14976 static void hdd_restore_info_for_ssr(struct hdd_adapter *adapter) 14977 { 14978 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); 14979 14980 if (cds_is_driver_recovering()) { 14981 /* ssr happens, recover the info */ 14982 hdd_set_vdev_phy_mode(adapter, adapter->user_phy_mode); 14983 wlan_mlme_restore_user_set_link_num(hdd_ctx->psoc); 14984 } else { 14985 /* intf down/up happens, reset default info */ 14986 hdd_set_vdev_phy_mode(adapter, QCA_WLAN_VENDOR_PHY_MODE_AUTO); 14987 wlan_mlme_clear_user_set_link_num(hdd_ctx->psoc); 14988 } 14989 } 14990 hdd_adapter_reset_station_ctx(struct hdd_adapter * adapter)14991 void hdd_adapter_reset_station_ctx(struct hdd_adapter *adapter) 14992 { 14993 struct wlan_hdd_link_info *link_info; 14994 struct hdd_station_ctx *sta_ctx; 14995 14996 hdd_adapter_for_each_link_info(adapter, link_info) { 14997 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(link_info); 14998 qdf_mem_zero(&sta_ctx->conn_info.bssid, QDF_MAC_ADDR_SIZE); 14999 15000 hdd_cm_clear_ieee_link_id(link_info); 15001 sta_ctx->user_cfg_chn_width = CH_WIDTH_INVALID; 15002 } 15003 } 15004 hdd_start_station_adapter(struct hdd_adapter * adapter)15005 int hdd_start_station_adapter(struct hdd_adapter *adapter) 15006 { 15007 QDF_STATUS status; 15008 int ret; 15009 struct wlan_hdd_link_info *link_info; 15010 15011 hdd_enter_dev(adapter->dev); 15012 if (test_bit(SME_SESSION_OPENED, &adapter->deflink->link_flags)) { 15013 hdd_err("session is already opened, %d", 15014 adapter->deflink->vdev_id); 15015 return qdf_status_to_os_return(QDF_STATUS_SUCCESS); 15016 } 15017 15018 if ((adapter->device_mode == QDF_P2P_DEVICE_MODE) || 15019 (adapter->device_mode == QDF_NAN_DISC_MODE)) 15020 wlan_hdd_lpc_del_monitor_interface(adapter->hdd_ctx, false); 15021 15022 status = hdd_adapter_fill_link_address(adapter); 15023 if (QDF_IS_STATUS_ERROR(status)) { 15024 hdd_debug("Link address derive failed"); 15025 return qdf_status_to_os_return(status); 15026 } 15027 15028 status = hdd_adapter_check_duplicate_session(adapter); 15029 if (QDF_IS_STATUS_ERROR(status)) { 15030 hdd_err("Duplicate session is existing with same mac address"); 15031 return qdf_status_to_os_return(status); 15032 } 15033 15034 hdd_adapter_for_each_active_link_info(adapter, link_info) { 15035 ret = hdd_vdev_create(link_info); 15036 if (ret) { 15037 hdd_err("failed to create vdev: %d", ret); 15038 goto fail; 15039 } 15040 15041 status = hdd_init_station_mode(link_info); 15042 if (QDF_STATUS_SUCCESS != status) { 15043 hdd_err("Error Initializing station mode: %d", status); 15044 ret = qdf_status_to_os_return(status); 15045 goto fail; 15046 } 15047 } 15048 15049 hdd_adapter_reset_station_ctx(adapter); 15050 15051 hdd_register_wext(adapter->dev); 15052 hdd_set_netdev_flags(adapter); 15053 15054 hdd_register_tx_flow_control(adapter, 15055 hdd_tx_resume_timer_expired_handler, 15056 hdd_tx_resume_cb, 15057 hdd_tx_flow_control_is_pause); 15058 15059 hdd_register_hl_netdev_fc_timer(adapter, 15060 hdd_tx_resume_timer_expired_handler); 15061 15062 if (hdd_get_multi_client_ll_support(adapter)) 15063 wlan_hdd_init_multi_client_info_table(adapter); 15064 15065 hdd_adapter_set_wlm_client_latency_level(adapter); 15066 hdd_adapter_update_mlo_mgr_mac_addr(adapter); 15067 hdd_restore_info_for_ssr(adapter); 15068 15069 hdd_exit(); 15070 return 0; 15071 15072 fail: 15073 hdd_adapter_for_each_active_link_info(adapter, link_info) 15074 hdd_vdev_destroy(link_info); 15075 15076 return ret; 15077 } 15078 hdd_start_ap_adapter(struct hdd_adapter * adapter,bool rtnl_held)15079 int hdd_start_ap_adapter(struct hdd_adapter *adapter, bool rtnl_held) 15080 { 15081 QDF_STATUS status; 15082 bool is_ssr = false; 15083 int ret; 15084 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); 15085 struct sap_context *sap_ctx; 15086 struct wlan_hdd_link_info *link_info = adapter->deflink; 15087 15088 hdd_enter(); 15089 15090 if (test_bit(SME_SESSION_OPENED, &link_info->link_flags)) { 15091 hdd_err("session is already opened, %d", 15092 link_info->vdev_id); 15093 return qdf_status_to_os_return(QDF_STATUS_SUCCESS); 15094 } 15095 15096 status = hdd_adapter_fill_link_address(adapter); 15097 if (QDF_IS_STATUS_ERROR(status)) { 15098 hdd_debug("Link address derive failed"); 15099 return qdf_status_to_os_return(status); 15100 } 15101 15102 status = hdd_adapter_check_duplicate_session(adapter); 15103 if (QDF_IS_STATUS_ERROR(status)) { 15104 hdd_err("Duplicate session is existing with same mac address"); 15105 return qdf_status_to_os_return(status); 15106 } 15107 15108 /* 15109 * In SSR case no need to create new sap context. 15110 * Otherwise create sap context first and then create 15111 * vdev as while creating the vdev, driver needs to 15112 * register SAP callback and that callback uses sap context 15113 */ 15114 if (WLAN_HDD_GET_SAP_CTX_PTR(link_info)) { 15115 is_ssr = true; 15116 } else if (!hdd_sap_create_ctx(adapter)) { 15117 hdd_err("sap creation failed"); 15118 return qdf_status_to_os_return(QDF_STATUS_E_FAILURE); 15119 } 15120 15121 ret = hdd_vdev_create(link_info); 15122 if (ret) { 15123 hdd_err("failed to create vdev, status:%d", ret); 15124 goto sap_destroy_ctx; 15125 } 15126 15127 sap_ctx = WLAN_HDD_GET_SAP_CTX_PTR(link_info); 15128 status = sap_acquire_vdev_ref(hdd_ctx->psoc, sap_ctx, 15129 link_info->vdev_id); 15130 if (!QDF_IS_STATUS_SUCCESS(status)) { 15131 hdd_err("Failed to get vdev ref for sap for session_id: %u", 15132 link_info->vdev_id); 15133 ret = qdf_status_to_os_return(status); 15134 goto sap_vdev_destroy; 15135 } 15136 15137 if (adapter->device_mode == QDF_SAP_MODE) { 15138 status = hdd_vdev_configure_rtt_params(sap_ctx->vdev); 15139 if (QDF_IS_STATUS_ERROR(status)) 15140 goto sap_release_ref; 15141 } 15142 15143 status = hdd_init_ap_mode(adapter, is_ssr, rtnl_held); 15144 if (QDF_STATUS_SUCCESS != status) { 15145 hdd_err("Error Initializing the AP mode: %d", status); 15146 ret = qdf_status_to_os_return(status); 15147 goto sap_release_ref; 15148 } 15149 15150 hdd_register_tx_flow_control(adapter, 15151 hdd_softap_tx_resume_timer_expired_handler, 15152 hdd_softap_tx_resume_cb, 15153 hdd_tx_flow_control_is_pause); 15154 15155 hdd_register_hl_netdev_fc_timer(adapter, 15156 hdd_tx_resume_timer_expired_handler); 15157 15158 if (cds_is_driver_recovering()) 15159 hdd_medium_assess_ssr_reinit(); 15160 15161 hdd_exit(); 15162 return 0; 15163 15164 sap_release_ref: 15165 sap_release_vdev_ref(sap_ctx); 15166 sap_vdev_destroy: 15167 hdd_vdev_destroy(link_info); 15168 sap_destroy_ctx: 15169 hdd_sap_destroy_ctx(link_info); 15170 return ret; 15171 } 15172 15173 #if defined(QCA_LL_TX_FLOW_CONTROL_V2) || defined(QCA_LL_PDEV_TX_FLOW_CONTROL) 15174 /** 15175 * hdd_txrx_populate_cds_config() - Populate txrx cds configuration 15176 * @cds_cfg: CDS Configuration 15177 * @hdd_ctx: Pointer to hdd context 15178 * 15179 * Return: none 15180 */ hdd_txrx_populate_cds_config(struct cds_config_info * cds_cfg,struct hdd_context * hdd_ctx)15181 static inline void hdd_txrx_populate_cds_config(struct cds_config_info 15182 *cds_cfg, 15183 struct hdd_context *hdd_ctx) 15184 { 15185 cds_cfg->tx_flow_stop_queue_th = 15186 cfg_get(hdd_ctx->psoc, CFG_DP_TX_FLOW_STOP_QUEUE_TH); 15187 cds_cfg->tx_flow_start_queue_offset = 15188 cfg_get(hdd_ctx->psoc, CFG_DP_TX_FLOW_START_QUEUE_OFFSET); 15189 /* configuration for DP RX Threads */ 15190 cds_cfg->enable_dp_rx_threads = 15191 ucfg_dp_is_rx_threads_enabled(hdd_ctx->psoc); 15192 } 15193 #else hdd_txrx_populate_cds_config(struct cds_config_info * cds_cfg,struct hdd_context * hdd_ctx)15194 static inline void hdd_txrx_populate_cds_config(struct cds_config_info 15195 *cds_cfg, 15196 struct hdd_context *hdd_ctx) 15197 { 15198 } 15199 #endif 15200 15201 /** 15202 * hdd_update_cds_config() - API to update cds configuration parameters 15203 * @hdd_ctx: HDD Context 15204 * 15205 * Return: 0 for Success, errno on failure 15206 */ hdd_update_cds_config(struct hdd_context * hdd_ctx)15207 static int hdd_update_cds_config(struct hdd_context *hdd_ctx) 15208 { 15209 struct cds_config_info *cds_cfg; 15210 int value; 15211 uint8_t band_capability; 15212 uint32_t band_bitmap; 15213 uint8_t ito_repeat_count; 15214 bool crash_inject; 15215 bool self_recovery; 15216 bool fw_timeout_crash; 15217 QDF_STATUS status; 15218 15219 cds_cfg = qdf_mem_malloc(sizeof(*cds_cfg)); 15220 if (!cds_cfg) 15221 return -ENOMEM; 15222 15223 cds_cfg->driver_type = QDF_DRIVER_TYPE_PRODUCTION; 15224 ucfg_mlme_get_sap_max_modulated_dtim(hdd_ctx->psoc, 15225 &cds_cfg->sta_maxlimod_dtim); 15226 15227 ucfg_mlme_get_max_modulated_dtim_ms(hdd_ctx->psoc, 15228 &cds_cfg->sta_maxlimod_dtim_ms); 15229 15230 status = ucfg_mlme_get_crash_inject(hdd_ctx->psoc, &crash_inject); 15231 if (QDF_IS_STATUS_ERROR(status)) { 15232 hdd_err("Failed to get crash inject ini config"); 15233 goto exit; 15234 } 15235 15236 status = ucfg_mlme_get_self_recovery(hdd_ctx->psoc, &self_recovery); 15237 if (QDF_IS_STATUS_ERROR(status)) { 15238 hdd_err("Failed to get self recovery ini config"); 15239 goto exit; 15240 } 15241 15242 status = ucfg_mlme_get_fw_timeout_crash(hdd_ctx->psoc, 15243 &fw_timeout_crash); 15244 if (QDF_IS_STATUS_ERROR(status)) { 15245 hdd_err("Failed to get fw timeout crash ini config"); 15246 goto exit; 15247 } 15248 15249 status = ucfg_mlme_get_ito_repeat_count(hdd_ctx->psoc, 15250 &ito_repeat_count); 15251 if (QDF_IS_STATUS_ERROR(status)) { 15252 hdd_err("Failed to get ITO repeat count ini config"); 15253 goto exit; 15254 } 15255 15256 cds_cfg->force_target_assert_enabled = crash_inject; 15257 15258 ucfg_mlme_get_sap_max_offload_peers(hdd_ctx->psoc, &value); 15259 cds_cfg->ap_maxoffload_peers = value; 15260 ucfg_mlme_get_sap_max_offload_reorder_buffs(hdd_ctx->psoc, 15261 &value); 15262 cds_cfg->ap_maxoffload_reorderbuffs = value; 15263 15264 cds_cfg->reorder_offload = DP_REORDER_OFFLOAD_SUPPORT; 15265 15266 /* IPA micro controller data path offload resource config item */ 15267 cds_cfg->uc_offload_enabled = ucfg_ipa_uc_is_enabled(); 15268 15269 cds_cfg->enable_rxthread = 15270 ucfg_dp_is_rx_common_thread_enabled(hdd_ctx->psoc); 15271 ucfg_mlme_get_sap_max_peers(hdd_ctx->psoc, &value); 15272 cds_cfg->max_station = value; 15273 cds_cfg->sub_20_channel_width = WLAN_SUB_20_CH_WIDTH_NONE; 15274 cds_cfg->max_msdus_per_rxinorderind = 15275 cfg_get(hdd_ctx->psoc, CFG_DP_MAX_MSDUS_PER_RXIND); 15276 cds_cfg->self_recovery_enabled = self_recovery; 15277 cds_cfg->fw_timeout_crash = fw_timeout_crash; 15278 15279 cds_cfg->ito_repeat_count = ito_repeat_count; 15280 15281 status = ucfg_mlme_get_band_capability(hdd_ctx->psoc, &band_bitmap); 15282 if (QDF_IS_STATUS_ERROR(status)) 15283 goto exit; 15284 15285 band_capability = wlan_reg_band_bitmap_to_band_info(band_bitmap); 15286 cds_cfg->bandcapability = band_capability; 15287 cds_cfg->num_vdevs = hdd_ctx->config->num_vdevs; 15288 cds_cfg->enable_tx_compl_tsf64 = 15289 hdd_tsf_is_tsf64_tx_set(hdd_ctx); 15290 hdd_txrx_populate_cds_config(cds_cfg, hdd_ctx); 15291 hdd_lpass_populate_cds_config(cds_cfg, hdd_ctx); 15292 cds_init_ini_config(cds_cfg); 15293 return 0; 15294 15295 exit: 15296 qdf_mem_free(cds_cfg); 15297 return -EINVAL; 15298 } 15299 15300 /** 15301 * hdd_update_user_config() - API to update user configuration 15302 * parameters to obj mgr which are used by multiple components 15303 * @hdd_ctx: HDD Context 15304 * 15305 * Return: 0 for Success, errno on failure 15306 */ hdd_update_user_config(struct hdd_context * hdd_ctx)15307 static int hdd_update_user_config(struct hdd_context *hdd_ctx) 15308 { 15309 struct wlan_objmgr_psoc_user_config *user_config; 15310 uint8_t band_capability; 15311 uint32_t band_bitmap; 15312 QDF_STATUS status; 15313 bool value = false; 15314 15315 status = ucfg_mlme_get_band_capability(hdd_ctx->psoc, &band_bitmap); 15316 if (QDF_IS_STATUS_ERROR(status)) 15317 return -EIO; 15318 15319 user_config = qdf_mem_malloc(sizeof(*user_config)); 15320 if (!user_config) 15321 return -ENOMEM; 15322 15323 user_config->dot11_mode = hdd_ctx->config->dot11Mode; 15324 status = ucfg_mlme_is_11d_enabled(hdd_ctx->psoc, &value); 15325 if (!QDF_IS_STATUS_SUCCESS(status)) 15326 hdd_err("Invalid 11d_enable flag"); 15327 user_config->is_11d_support_enabled = value; 15328 15329 value = false; 15330 status = ucfg_mlme_is_11h_enabled(hdd_ctx->psoc, &value); 15331 if (!QDF_IS_STATUS_SUCCESS(status)) 15332 hdd_err("Invalid 11h_enable flag"); 15333 user_config->is_11h_support_enabled = value; 15334 band_capability = wlan_reg_band_bitmap_to_band_info(band_bitmap); 15335 user_config->band_capability = band_capability; 15336 wlan_objmgr_psoc_set_user_config(hdd_ctx->psoc, user_config); 15337 15338 qdf_mem_free(user_config); 15339 return 0; 15340 } 15341 15342 /** 15343 * hdd_init_thermal_info - Initialize thermal level 15344 * @hdd_ctx: HDD context 15345 * 15346 * Initialize thermal level at SME layer and set the thermal level callback 15347 * which would be called when a configured thermal threshold is hit. 15348 * 15349 * Return: 0 on success and errno on failure 15350 */ hdd_init_thermal_info(struct hdd_context * hdd_ctx)15351 static int hdd_init_thermal_info(struct hdd_context *hdd_ctx) 15352 { 15353 QDF_STATUS status; 15354 mac_handle_t mac_handle = hdd_ctx->mac_handle; 15355 15356 status = sme_init_thermal_info(mac_handle); 15357 15358 if (!QDF_IS_STATUS_SUCCESS(status)) 15359 return qdf_status_to_os_return(status); 15360 15361 sme_add_set_thermal_level_callback(mac_handle, 15362 hdd_set_thermal_level_cb); 15363 15364 return 0; 15365 15366 } 15367 15368 #if defined(CONFIG_HDD_INIT_WITH_RTNL_LOCK) 15369 /** 15370 * hdd_hold_rtnl_lock - Hold RTNL lock 15371 * 15372 * Hold RTNL lock 15373 * 15374 * Return: True if held and false otherwise 15375 */ hdd_hold_rtnl_lock(void)15376 static inline bool hdd_hold_rtnl_lock(void) 15377 { 15378 rtnl_lock(); 15379 return true; 15380 } 15381 15382 /** 15383 * hdd_release_rtnl_lock - Release RTNL lock 15384 * 15385 * Release RTNL lock 15386 * 15387 * Return: None 15388 */ hdd_release_rtnl_lock(void)15389 static inline void hdd_release_rtnl_lock(void) 15390 { 15391 rtnl_unlock(); 15392 } 15393 #else hdd_hold_rtnl_lock(void)15394 static inline bool hdd_hold_rtnl_lock(void) { return false; } hdd_release_rtnl_lock(void)15395 static inline void hdd_release_rtnl_lock(void) { } 15396 #endif 15397 15398 #if !defined(REMOVE_PKT_LOG) 15399 15400 /* MAX iwpriv command support */ 15401 #define PKTLOG_SET_BUFF_SIZE 3 15402 #define PKTLOG_CLEAR_BUFF 4 15403 /* Set Maximum pktlog file size to 64MB */ 15404 #define MAX_PKTLOG_SIZE 64 15405 15406 /** 15407 * hdd_pktlog_set_buff_size() - set pktlog buffer size 15408 * @hdd_ctx: hdd context 15409 * @set_value2: pktlog buffer size value 15410 * 15411 * 15412 * Return: 0 for success or error. 15413 */ hdd_pktlog_set_buff_size(struct hdd_context * hdd_ctx,int set_value2)15414 static int hdd_pktlog_set_buff_size(struct hdd_context *hdd_ctx, int set_value2) 15415 { 15416 struct sir_wifi_start_log start_log = { 0 }; 15417 QDF_STATUS status; 15418 15419 start_log.ring_id = RING_ID_PER_PACKET_STATS; 15420 start_log.verbose_level = WLAN_LOG_LEVEL_OFF; 15421 start_log.ini_triggered = cds_is_packet_log_enabled(); 15422 start_log.user_triggered = 1; 15423 start_log.size = set_value2; 15424 start_log.is_pktlog_buff_clear = false; 15425 15426 status = sme_wifi_start_logger(hdd_ctx->mac_handle, start_log); 15427 if (!QDF_IS_STATUS_SUCCESS(status)) { 15428 hdd_err("sme_wifi_start_logger failed(err=%d)", status); 15429 hdd_exit(); 15430 return -EINVAL; 15431 } 15432 15433 return 0; 15434 } 15435 15436 /** 15437 * hdd_pktlog_clear_buff() - clear pktlog buffer 15438 * @hdd_ctx: hdd context 15439 * 15440 * Return: 0 for success or error. 15441 */ hdd_pktlog_clear_buff(struct hdd_context * hdd_ctx)15442 static int hdd_pktlog_clear_buff(struct hdd_context *hdd_ctx) 15443 { 15444 struct sir_wifi_start_log start_log; 15445 QDF_STATUS status; 15446 15447 start_log.ring_id = RING_ID_PER_PACKET_STATS; 15448 start_log.verbose_level = WLAN_LOG_LEVEL_OFF; 15449 start_log.ini_triggered = cds_is_packet_log_enabled(); 15450 start_log.user_triggered = 1; 15451 start_log.size = 0; 15452 start_log.is_pktlog_buff_clear = true; 15453 15454 status = sme_wifi_start_logger(hdd_ctx->mac_handle, start_log); 15455 if (!QDF_IS_STATUS_SUCCESS(status)) { 15456 hdd_err("sme_wifi_start_logger failed(err=%d)", status); 15457 hdd_exit(); 15458 return -EINVAL; 15459 } 15460 15461 return 0; 15462 } 15463 15464 15465 /** 15466 * hdd_process_pktlog_command() - process pktlog command 15467 * @hdd_ctx: hdd context 15468 * @set_value: value set by user 15469 * @set_value2: pktlog buffer size value 15470 * 15471 * This function process pktlog command. 15472 * set_value2 only matters when set_value is 3 (set buff size) 15473 * otherwise we ignore it. 15474 * 15475 * Return: 0 for success or error. 15476 */ hdd_process_pktlog_command(struct hdd_context * hdd_ctx,uint32_t set_value,int set_value2)15477 int hdd_process_pktlog_command(struct hdd_context *hdd_ctx, uint32_t set_value, 15478 int set_value2) 15479 { 15480 int ret; 15481 bool enable; 15482 uint8_t user_triggered = 0; 15483 15484 ret = wlan_hdd_validate_context(hdd_ctx); 15485 if (0 != ret) 15486 return ret; 15487 15488 hdd_debug("set pktlog %d, set size %d", set_value, set_value2); 15489 15490 if (set_value > PKTLOG_CLEAR_BUFF) { 15491 hdd_err("invalid pktlog value %d", set_value); 15492 return -EINVAL; 15493 } 15494 15495 if (set_value == PKTLOG_SET_BUFF_SIZE) { 15496 if (set_value2 <= 0) { 15497 hdd_err("invalid pktlog size %d", set_value2); 15498 return -EINVAL; 15499 } else if (set_value2 > MAX_PKTLOG_SIZE) { 15500 hdd_err_rl("Pktlog size is large. max value is %uMB.", 15501 MAX_PKTLOG_SIZE); 15502 return -EINVAL; 15503 } 15504 return hdd_pktlog_set_buff_size(hdd_ctx, set_value2); 15505 } else if (set_value == PKTLOG_CLEAR_BUFF) { 15506 return hdd_pktlog_clear_buff(hdd_ctx); 15507 } 15508 15509 /* 15510 * set_value = 0 then disable packetlog 15511 * set_value = 1 enable packetlog forcefully 15512 * set_value = 2 then disable packetlog if disabled through ini or 15513 * enable packetlog with AUTO type. 15514 */ 15515 enable = ((set_value > 0) && cds_is_packet_log_enabled()) ? 15516 true : false; 15517 15518 if (1 == set_value) { 15519 enable = true; 15520 user_triggered = 1; 15521 } 15522 15523 return hdd_pktlog_enable_disable(hdd_ctx, enable, user_triggered, 0); 15524 } 15525 15526 /** 15527 * hdd_pktlog_enable_disable() - Enable/Disable packet logging 15528 * @hdd_ctx: HDD context 15529 * @enable_disable_flag: Flag to enable/disable 15530 * @user_triggered: triggered through iwpriv 15531 * @size: buffer size to be used for packetlog 15532 * 15533 * Return: 0 on success; error number otherwise 15534 */ hdd_pktlog_enable_disable(struct hdd_context * hdd_ctx,bool enable_disable_flag,uint8_t user_triggered,int size)15535 int hdd_pktlog_enable_disable(struct hdd_context *hdd_ctx, 15536 bool enable_disable_flag, 15537 uint8_t user_triggered, int size) 15538 { 15539 struct sir_wifi_start_log start_log; 15540 QDF_STATUS status; 15541 15542 if (hdd_ctx->is_pktlog_enabled && enable_disable_flag) 15543 return 0; 15544 15545 if ((!hdd_ctx->is_pktlog_enabled) && (!enable_disable_flag)) 15546 return 0; 15547 15548 start_log.ring_id = RING_ID_PER_PACKET_STATS; 15549 start_log.verbose_level = 15550 enable_disable_flag ? 15551 WLAN_LOG_LEVEL_ACTIVE : WLAN_LOG_LEVEL_OFF; 15552 start_log.ini_triggered = cds_is_packet_log_enabled(); 15553 start_log.user_triggered = user_triggered; 15554 start_log.size = size; 15555 start_log.is_pktlog_buff_clear = false; 15556 /* 15557 * Use "is_iwpriv_command" flag to distinguish iwpriv command from other 15558 * commands. Host uses this flag to decide whether to send pktlog 15559 * disable command to fw without sending pktlog enable command 15560 * previously. For eg, If vendor sends pktlog disable command without 15561 * sending pktlog enable command, then host discards the packet 15562 * but for iwpriv command, host will send it to fw. 15563 */ 15564 start_log.is_iwpriv_command = 1; 15565 15566 status = sme_wifi_start_logger(hdd_ctx->mac_handle, start_log); 15567 if (!QDF_IS_STATUS_SUCCESS(status)) { 15568 hdd_err("sme_wifi_start_logger failed(err=%d)", status); 15569 hdd_exit(); 15570 return -EINVAL; 15571 } 15572 15573 hdd_ctx->is_pktlog_enabled = enable_disable_flag; 15574 15575 return 0; 15576 } 15577 #endif /* REMOVE_PKT_LOG */ 15578 hdd_free_mac_address_lists(struct hdd_context * hdd_ctx)15579 void hdd_free_mac_address_lists(struct hdd_context *hdd_ctx) 15580 { 15581 hdd_debug("Resetting MAC address lists"); 15582 qdf_mem_zero(hdd_ctx->provisioned_mac_addr, 15583 sizeof(hdd_ctx->provisioned_mac_addr)); 15584 qdf_mem_zero(hdd_ctx->derived_mac_addr, 15585 sizeof(hdd_ctx->derived_mac_addr)); 15586 hdd_ctx->num_provisioned_addr = 0; 15587 hdd_ctx->num_derived_addr = 0; 15588 hdd_ctx->provisioned_intf_addr_mask = 0; 15589 hdd_ctx->derived_intf_addr_mask = 0; 15590 } 15591 15592 /** 15593 * hdd_get_platform_wlan_mac_buff() - API to query platform driver 15594 * for MAC address 15595 * @dev: Device Pointer 15596 * @num: Number of Valid Mac address 15597 * 15598 * Return: Pointer to MAC address buffer 15599 */ hdd_get_platform_wlan_mac_buff(struct device * dev,uint32_t * num)15600 static uint8_t *hdd_get_platform_wlan_mac_buff(struct device *dev, 15601 uint32_t *num) 15602 { 15603 return pld_get_wlan_mac_address(dev, num); 15604 } 15605 15606 /** 15607 * hdd_get_platform_wlan_derived_mac_buff() - API to query platform driver 15608 * for derived MAC address 15609 * @dev: Device Pointer 15610 * @num: Number of Valid Mac address 15611 * 15612 * Return: Pointer to MAC address buffer 15613 */ hdd_get_platform_wlan_derived_mac_buff(struct device * dev,uint32_t * num)15614 static uint8_t *hdd_get_platform_wlan_derived_mac_buff(struct device *dev, 15615 uint32_t *num) 15616 { 15617 return pld_get_wlan_derived_mac_address(dev, num); 15618 } 15619 15620 /** 15621 * hdd_populate_random_mac_addr() - API to populate random mac addresses 15622 * @hdd_ctx: HDD Context 15623 * @num: Number of random mac addresses needed 15624 * 15625 * Generate random addresses using bit manipulation on the base mac address 15626 * 15627 * Return: None 15628 */ hdd_populate_random_mac_addr(struct hdd_context * hdd_ctx,uint32_t num)15629 void hdd_populate_random_mac_addr(struct hdd_context *hdd_ctx, uint32_t num) 15630 { 15631 uint32_t idx = hdd_ctx->num_derived_addr; 15632 uint32_t iter; 15633 uint8_t *buf = NULL; 15634 uint8_t macaddr_b3, tmp_br3; 15635 /* 15636 * Consider first provisioned mac address as source address to derive 15637 * remaining addresses 15638 */ 15639 15640 uint8_t *src = hdd_ctx->provisioned_mac_addr[0].bytes; 15641 15642 for (iter = 0; iter < num; ++iter, ++idx) { 15643 buf = hdd_ctx->derived_mac_addr[idx].bytes; 15644 qdf_mem_copy(buf, src, QDF_MAC_ADDR_SIZE); 15645 macaddr_b3 = buf[3]; 15646 tmp_br3 = ((macaddr_b3 >> 4 & INTF_MACADDR_MASK) + idx) & 15647 INTF_MACADDR_MASK; 15648 macaddr_b3 += tmp_br3; 15649 macaddr_b3 ^= (1 << INTF_MACADDR_MASK); 15650 buf[0] |= 0x02; 15651 buf[3] = macaddr_b3; 15652 hdd_debug(QDF_MAC_ADDR_FMT, QDF_MAC_ADDR_REF(buf)); 15653 hdd_ctx->num_derived_addr++; 15654 } 15655 } 15656 15657 /** 15658 * hdd_platform_wlan_mac() - API to get mac addresses from platform driver 15659 * @hdd_ctx: HDD Context 15660 * 15661 * API to get mac addresses from platform driver and update the driver 15662 * structures and configure FW with the base mac address. 15663 * Return: int 15664 */ hdd_platform_wlan_mac(struct hdd_context * hdd_ctx)15665 static int hdd_platform_wlan_mac(struct hdd_context *hdd_ctx) 15666 { 15667 uint32_t no_of_mac_addr, iter; 15668 uint32_t max_mac_addr = QDF_MAX_CONCURRENCY_PERSONA; 15669 uint32_t mac_addr_size = QDF_MAC_ADDR_SIZE; 15670 uint8_t *addr, *buf; 15671 struct device *dev = hdd_ctx->parent_dev; 15672 tSirMacAddr mac_addr; 15673 QDF_STATUS status; 15674 15675 addr = hdd_get_platform_wlan_mac_buff(dev, &no_of_mac_addr); 15676 15677 if (no_of_mac_addr == 0 || !addr) { 15678 hdd_debug("No mac configured from platform driver"); 15679 return -EINVAL; 15680 } 15681 15682 hdd_free_mac_address_lists(hdd_ctx); 15683 15684 if (no_of_mac_addr > max_mac_addr) 15685 no_of_mac_addr = max_mac_addr; 15686 15687 qdf_mem_copy(&mac_addr, addr, mac_addr_size); 15688 15689 for (iter = 0; iter < no_of_mac_addr; ++iter, addr += mac_addr_size) { 15690 buf = hdd_ctx->provisioned_mac_addr[iter].bytes; 15691 qdf_mem_copy(buf, addr, QDF_MAC_ADDR_SIZE); 15692 hdd_info("provisioned MAC Addr [%d] "QDF_MAC_ADDR_FMT, iter, 15693 QDF_MAC_ADDR_REF(buf)); 15694 } 15695 15696 hdd_ctx->num_provisioned_addr = no_of_mac_addr; 15697 15698 if (hdd_ctx->config->mac_provision) { 15699 addr = hdd_get_platform_wlan_derived_mac_buff(dev, 15700 &no_of_mac_addr); 15701 15702 if (no_of_mac_addr == 0 || !addr) 15703 hdd_warn("No derived address from platform driver"); 15704 else if (no_of_mac_addr > 15705 (max_mac_addr - hdd_ctx->num_provisioned_addr)) 15706 no_of_mac_addr = (max_mac_addr - 15707 hdd_ctx->num_provisioned_addr); 15708 15709 for (iter = 0; iter < no_of_mac_addr; ++iter, 15710 addr += mac_addr_size) { 15711 buf = hdd_ctx->derived_mac_addr[iter].bytes; 15712 qdf_mem_copy(buf, addr, QDF_MAC_ADDR_SIZE); 15713 hdd_debug("derived MAC Addr [%d] "QDF_MAC_ADDR_FMT, iter, 15714 QDF_MAC_ADDR_REF(buf)); 15715 } 15716 hdd_ctx->num_derived_addr = no_of_mac_addr; 15717 } 15718 15719 no_of_mac_addr = hdd_ctx->num_provisioned_addr + 15720 hdd_ctx->num_derived_addr; 15721 if (no_of_mac_addr < max_mac_addr) 15722 hdd_populate_random_mac_addr(hdd_ctx, max_mac_addr - 15723 no_of_mac_addr); 15724 15725 status = sme_set_custom_mac_addr(mac_addr); 15726 if (!QDF_IS_STATUS_SUCCESS(status)) 15727 return -EAGAIN; 15728 15729 return 0; 15730 } 15731 15732 /** 15733 * hdd_update_mac_addr_to_fw() - API to update wlan mac addresses to FW 15734 * @hdd_ctx: HDD Context 15735 * 15736 * Update MAC address to FW. If MAC address passed by FW is invalid, host 15737 * will generate its own MAC and update it to FW. 15738 * 15739 * Return: 0 for success 15740 * Non-zero error code for failure 15741 */ hdd_update_mac_addr_to_fw(struct hdd_context * hdd_ctx)15742 static int hdd_update_mac_addr_to_fw(struct hdd_context *hdd_ctx) 15743 { 15744 tSirMacAddr custom_mac_addr; 15745 QDF_STATUS status; 15746 15747 if (hdd_ctx->num_provisioned_addr) 15748 qdf_mem_copy(&custom_mac_addr, 15749 &hdd_ctx->provisioned_mac_addr[0].bytes[0], 15750 sizeof(tSirMacAddr)); 15751 else 15752 qdf_mem_copy(&custom_mac_addr, 15753 &hdd_ctx->derived_mac_addr[0].bytes[0], 15754 sizeof(tSirMacAddr)); 15755 status = sme_set_custom_mac_addr(custom_mac_addr); 15756 if (!QDF_IS_STATUS_SUCCESS(status)) 15757 return -EAGAIN; 15758 return 0; 15759 } 15760 15761 /** 15762 * hdd_initialize_mac_address() - API to get wlan mac addresses 15763 * @hdd_ctx: HDD Context 15764 * 15765 * Get MAC addresses from platform driver or wlan_mac.bin. If platform driver 15766 * is provisioned with mac addresses, driver uses it, else it will use 15767 * wlan_mac.bin to update HW MAC addresses. 15768 * 15769 * Return: None 15770 */ hdd_initialize_mac_address(struct hdd_context * hdd_ctx)15771 static int hdd_initialize_mac_address(struct hdd_context *hdd_ctx) 15772 { 15773 QDF_STATUS status; 15774 int ret; 15775 15776 ret = hdd_platform_wlan_mac(hdd_ctx); 15777 if (!ret) { 15778 hdd_info("using MAC address from platform driver"); 15779 return ret; 15780 } else if (hdd_ctx->config->mac_provision) { 15781 hdd_err("getting MAC address from platform driver failed"); 15782 return ret; 15783 } 15784 15785 status = hdd_update_mac_config(hdd_ctx); 15786 if (QDF_IS_STATUS_SUCCESS(status)) { 15787 hdd_info("using MAC address from wlan_mac.bin"); 15788 return 0; 15789 } 15790 15791 hdd_info("using default MAC address"); 15792 15793 /* Use fw provided MAC */ 15794 if (!qdf_is_macaddr_zero(&hdd_ctx->hw_macaddr)) { 15795 hdd_update_macaddr(hdd_ctx, hdd_ctx->hw_macaddr, false); 15796 return 0; 15797 } else if (hdd_generate_macaddr_auto(hdd_ctx) != 0) { 15798 struct qdf_mac_addr mac_addr; 15799 15800 hdd_err("MAC failure from device serial no."); 15801 qdf_get_random_bytes(&mac_addr, sizeof(mac_addr)); 15802 /* 15803 * Reset multicast bit (bit-0) and set 15804 * locally-administered bit 15805 */ 15806 mac_addr.bytes[0] = 0x2; 15807 hdd_update_macaddr(hdd_ctx, mac_addr, true); 15808 } 15809 15810 ret = hdd_update_mac_addr_to_fw(hdd_ctx); 15811 if (ret) 15812 hdd_err("MAC address out-of-sync, ret:%d", ret); 15813 return ret; 15814 } 15815 15816 /* params being sent: 15817 * wmi_pdev_param_tx_chain_mask_1ss 15818 * wmi_pdev_param_mgmt_retry_limit 15819 * wmi_pdev_param_default_6ghz_rate 15820 * wmi_pdev_param_pdev_stats_tx_xretry_ext 15821 * wmi_pdev_param_smart_chainmask_scheme 15822 * wmi_pdev_param_alternative_chainmask_scheme 15823 * wmi_pdev_param_ani_enable 15824 * wmi_pdev_param_pcie_config 15825 */ 15826 /** 15827 * hdd_pre_enable_configure() - Configurations prior to cds_enable 15828 * @hdd_ctx: HDD context 15829 * 15830 * Pre configurations to be done at lower layer before calling cds enable. 15831 * 15832 * Return: 0 on success and errno on failure. 15833 */ hdd_pre_enable_configure(struct hdd_context * hdd_ctx)15834 static int hdd_pre_enable_configure(struct hdd_context *hdd_ctx) 15835 { 15836 int ret; 15837 uint8_t val = 0; 15838 uint8_t max_retry = 0; 15839 bool enable_he_mcs0_for_6ghz_mgmt = false; 15840 uint32_t tx_retry_multiplier; 15841 QDF_STATUS status; 15842 void *soc = cds_get_context(QDF_MODULE_ID_SOC); 15843 struct dev_set_param setparam[MAX_PDEV_PRE_ENABLE_PARAMS] = {}; 15844 bool check_value; 15845 uint8_t index = 0; 15846 15847 cdp_register_pause_cb(soc, wlan_hdd_txrx_pause_cb); 15848 hdd_tx_latency_register_cb(soc); 15849 15850 /* Register HL netdev flow control callback */ 15851 cdp_hl_fc_register(soc, OL_TXRX_PDEV_ID, wlan_hdd_txrx_pause_cb); 15852 /* Register rx mic error indication handler */ 15853 ucfg_dp_register_rx_mic_error_ind_handler(soc); 15854 15855 /* 15856 * Note that the cds_pre_enable() sequence triggers the cfg download. 15857 * The cfg download must occur before we update the SME config 15858 * since the SME config operation must access the cfg database 15859 */ 15860 status = hdd_set_sme_config(hdd_ctx); 15861 15862 if (QDF_STATUS_SUCCESS != status) { 15863 hdd_err("Failed hdd_set_sme_config: %d", status); 15864 ret = qdf_status_to_os_return(status); 15865 goto out; 15866 } 15867 15868 status = hdd_set_policy_mgr_user_cfg(hdd_ctx); 15869 if (QDF_STATUS_SUCCESS != status) { 15870 hdd_alert("Failed hdd_set_policy_mgr_user_cfg: %d", status); 15871 ret = qdf_status_to_os_return(status); 15872 goto out; 15873 } 15874 15875 status = ucfg_mlme_get_tx_chainmask_1ss(hdd_ctx->psoc, &val); 15876 if (QDF_STATUS_SUCCESS != status) { 15877 hdd_err("Get tx_chainmask_1ss from mlme failed"); 15878 ret = qdf_status_to_os_return(status); 15879 goto out; 15880 } 15881 ret = mlme_check_index_setparam(setparam, 15882 wmi_pdev_param_tx_chain_mask_1ss, 15883 val, index++, 15884 MAX_PDEV_PRE_ENABLE_PARAMS); 15885 if (QDF_IS_STATUS_ERROR(ret)) { 15886 hdd_err("failed at wmi_pdev_param_tx_chain_mask_1ss"); 15887 goto out; 15888 15889 } 15890 15891 wlan_mlme_get_mgmt_max_retry(hdd_ctx->psoc, &max_retry); 15892 ret = mlme_check_index_setparam(setparam, 15893 wmi_pdev_param_mgmt_retry_limit, 15894 max_retry, index++, 15895 MAX_PDEV_PRE_ENABLE_PARAMS); 15896 if (QDF_IS_STATUS_ERROR(ret)) { 15897 hdd_err("failed at wmi_pdev_param_mgmt_retry_limit"); 15898 goto out; 15899 } 15900 15901 wlan_mlme_get_mgmt_6ghz_rate_support(hdd_ctx->psoc, 15902 &enable_he_mcs0_for_6ghz_mgmt); 15903 if (enable_he_mcs0_for_6ghz_mgmt) { 15904 hdd_debug("HE rates for 6GHz mgmt frames are supported"); 15905 ret = mlme_check_index_setparam( 15906 setparam, 15907 wmi_pdev_param_default_6ghz_rate, 15908 MGMT_DEFAULT_DATA_RATE_6GHZ, index++, 15909 MAX_PDEV_PRE_ENABLE_PARAMS); 15910 if (QDF_IS_STATUS_ERROR(ret)) { 15911 hdd_err("wmi_pdev_param_default_6ghz_rate failed %d", 15912 ret); 15913 goto out; 15914 } 15915 } 15916 15917 wlan_mlme_get_tx_retry_multiplier(hdd_ctx->psoc, 15918 &tx_retry_multiplier); 15919 ret = mlme_check_index_setparam(setparam, 15920 wmi_pdev_param_pdev_stats_tx_xretry_ext, 15921 tx_retry_multiplier, index++, 15922 MAX_PDEV_PRE_ENABLE_PARAMS); 15923 if (QDF_IS_STATUS_ERROR(ret)) { 15924 hdd_err("failed at wmi_pdev_param_pdev_stats_tx_xretry_ext"); 15925 goto out; 15926 } 15927 15928 ret = ucfg_get_smart_chainmask_enabled(hdd_ctx->psoc, 15929 &check_value); 15930 if (QDF_IS_STATUS_SUCCESS(ret)) { 15931 ret = mlme_check_index_setparam( 15932 setparam, 15933 wmi_pdev_param_smart_chainmask_scheme, 15934 (int)check_value, index++, 15935 MAX_PDEV_PRE_ENABLE_PARAMS); 15936 if (QDF_IS_STATUS_ERROR(ret)) { 15937 hdd_err("failed to set wmi_pdev_param_smart_chainmask_scheme"); 15938 goto out; 15939 } 15940 } 15941 15942 ret = ucfg_get_alternative_chainmask_enabled(hdd_ctx->psoc, 15943 &check_value); 15944 if (QDF_IS_STATUS_SUCCESS(ret)) { 15945 ret = mlme_check_index_setparam( 15946 setparam, 15947 wmi_pdev_param_alternative_chainmask_scheme, 15948 (int)check_value, index++, 15949 MAX_PDEV_PRE_ENABLE_PARAMS); 15950 if (QDF_IS_STATUS_ERROR(ret)) { 15951 hdd_err("failed to set wmi_pdev_param_alternative_chainmask_scheme"); 15952 goto out; 15953 } 15954 } 15955 15956 ret = ucfg_fwol_get_ani_enabled(hdd_ctx->psoc, &check_value); 15957 if (QDF_IS_STATUS_SUCCESS(ret)) { 15958 ret = mlme_check_index_setparam(setparam, 15959 wmi_pdev_param_ani_enable, 15960 (int)check_value, index++, 15961 MAX_PDEV_PRE_ENABLE_PARAMS); 15962 if (QDF_IS_STATUS_ERROR(ret)) { 15963 hdd_err("failed to set wmi_pdev_param_ani_enable"); 15964 goto out; 15965 } 15966 } 15967 15968 ret = hdd_set_pcie_params(hdd_ctx, index, setparam); 15969 if (QDF_IS_STATUS_ERROR(ret)) 15970 goto out; 15971 else 15972 index++; 15973 ret = sme_send_multi_pdev_vdev_set_params(MLME_PDEV_SETPARAM, 15974 WMI_PDEV_ID_SOC, setparam, 15975 index); 15976 if (QDF_IS_STATUS_ERROR(ret)) { 15977 hdd_err("failed to send pdev set params"); 15978 goto out; 15979 } 15980 15981 /* Configure global firmware params */ 15982 ret = ucfg_fwol_configure_global_params(hdd_ctx->psoc, hdd_ctx->pdev); 15983 if (ret) 15984 goto out; 15985 15986 status = hdd_set_sme_chan_list(hdd_ctx); 15987 if (status != QDF_STATUS_SUCCESS) { 15988 hdd_err("Failed to init channel list: %d", status); 15989 ret = qdf_status_to_os_return(status); 15990 goto out; 15991 } 15992 15993 if (!hdd_update_config_cfg(hdd_ctx)) { 15994 hdd_err("config update failed"); 15995 ret = -EINVAL; 15996 goto out; 15997 } 15998 hdd_init_channel_avoidance(hdd_ctx); 15999 16000 out: 16001 return ret; 16002 } 16003 16004 #ifdef FEATURE_P2P_LISTEN_OFFLOAD 16005 /** 16006 * wlan_hdd_p2p_lo_event_callback - P2P listen offload stop event handler 16007 * @context: context registered with sme_register_p2p_lo_event(). HDD 16008 * always registers a hdd context pointer 16009 * @evt:event structure pointer 16010 * 16011 * This is the p2p listen offload stop event handler, it sends vendor 16012 * event back to supplicant to notify the stop reason. 16013 * 16014 * Return: None 16015 */ wlan_hdd_p2p_lo_event_callback(void * context,struct sir_p2p_lo_event * evt)16016 static void wlan_hdd_p2p_lo_event_callback(void *context, 16017 struct sir_p2p_lo_event *evt) 16018 { 16019 struct hdd_context *hdd_ctx = context; 16020 struct sk_buff *vendor_event; 16021 enum qca_nl80211_vendor_subcmds_index index = 16022 QCA_NL80211_VENDOR_SUBCMD_P2P_LO_EVENT_INDEX; 16023 struct wlan_hdd_link_info *link_info; 16024 16025 hdd_enter(); 16026 16027 if (!hdd_ctx) { 16028 hdd_err("Invalid HDD context pointer"); 16029 return; 16030 } 16031 16032 link_info = hdd_get_link_info_by_vdev(hdd_ctx, evt->vdev_id); 16033 if (!link_info) { 16034 hdd_err("Cannot find adapter by vdev_id = %d", 16035 evt->vdev_id); 16036 return; 16037 } 16038 16039 vendor_event = 16040 wlan_cfg80211_vendor_event_alloc(hdd_ctx->wiphy, 16041 &link_info->adapter->wdev, 16042 sizeof(uint32_t) + 16043 NLMSG_HDRLEN, 16044 index, GFP_KERNEL); 16045 if (!vendor_event) { 16046 hdd_err("wlan_cfg80211_vendor_event_alloc failed"); 16047 return; 16048 } 16049 16050 if (nla_put_u32(vendor_event, 16051 QCA_WLAN_VENDOR_ATTR_P2P_LISTEN_OFFLOAD_STOP_REASON, 16052 evt->reason_code)) { 16053 hdd_err("nla put failed"); 16054 wlan_cfg80211_vendor_free_skb(vendor_event); 16055 return; 16056 } 16057 16058 wlan_cfg80211_vendor_event(vendor_event, GFP_KERNEL); 16059 hdd_debug("Sent P2P_LISTEN_OFFLOAD_STOP event for vdev_id = %d", 16060 evt->vdev_id); 16061 } 16062 #else wlan_hdd_p2p_lo_event_callback(void * context,struct sir_p2p_lo_event * evt)16063 static void wlan_hdd_p2p_lo_event_callback(void *context, 16064 struct sir_p2p_lo_event *evt) 16065 { 16066 } 16067 #endif 16068 16069 #ifdef FEATURE_WLAN_DYNAMIC_CVM hdd_set_vc_mode_config(struct hdd_context * hdd_ctx)16070 static inline int hdd_set_vc_mode_config(struct hdd_context *hdd_ctx) 16071 { 16072 return sme_set_vc_mode_config(hdd_ctx->config->vc_mode_cfg_bitmap); 16073 } 16074 #else hdd_set_vc_mode_config(struct hdd_context * hdd_ctx)16075 static inline int hdd_set_vc_mode_config(struct hdd_context *hdd_ctx) 16076 { 16077 return QDF_STATUS_SUCCESS; 16078 } 16079 #endif 16080 16081 /** 16082 * hdd_adaptive_dwelltime_init() - initialization for adaptive dwell time config 16083 * @hdd_ctx: HDD context 16084 * 16085 * This function sends the adaptive dwell time config configuration to the 16086 * firmware via WMA 16087 * 16088 * Return: 0 - success, < 0 - failure 16089 */ hdd_adaptive_dwelltime_init(struct hdd_context * hdd_ctx)16090 static int hdd_adaptive_dwelltime_init(struct hdd_context *hdd_ctx) 16091 { 16092 QDF_STATUS status; 16093 struct adaptive_dwelltime_params dwelltime_params; 16094 16095 status = ucfg_fwol_get_all_adaptive_dwelltime_params(hdd_ctx->psoc, 16096 &dwelltime_params); 16097 status = ucfg_fwol_set_adaptive_dwelltime_config(&dwelltime_params); 16098 16099 hdd_debug("Sending Adaptive Dwelltime Configuration to fw"); 16100 if (!QDF_IS_STATUS_SUCCESS(status)) { 16101 hdd_err("Failed to send Adaptive Dwelltime configuration!"); 16102 return -EAGAIN; 16103 } 16104 return 0; 16105 } 16106 hdd_dbs_scan_selection_init(struct hdd_context * hdd_ctx)16107 int hdd_dbs_scan_selection_init(struct hdd_context *hdd_ctx) 16108 { 16109 QDF_STATUS status; 16110 struct wmi_dbs_scan_sel_params dbs_scan_params; 16111 uint32_t i = 0; 16112 uint8_t count = 0, numentries = 0; 16113 uint8_t dual_mac_feature; 16114 uint8_t dbs_scan_config[CDS_DBS_SCAN_PARAM_PER_CLIENT 16115 * CDS_DBS_SCAN_CLIENTS_MAX]; 16116 16117 status = ucfg_policy_mgr_get_dual_mac_feature(hdd_ctx->psoc, 16118 &dual_mac_feature); 16119 16120 if (status != QDF_STATUS_SUCCESS) { 16121 hdd_err("can't get dual mac feature flag"); 16122 return -EINVAL; 16123 } 16124 /* check if DBS is enabled or supported */ 16125 if ((dual_mac_feature == DISABLE_DBS_CXN_AND_SCAN) || 16126 (dual_mac_feature == ENABLE_DBS_CXN_AND_DISABLE_DBS_SCAN)) 16127 return -EINVAL; 16128 16129 hdd_string_to_u8_array(hdd_ctx->config->dbs_scan_selection, 16130 dbs_scan_config, &numentries, 16131 (CDS_DBS_SCAN_PARAM_PER_CLIENT 16132 * CDS_DBS_SCAN_CLIENTS_MAX)); 16133 16134 if (!numentries) { 16135 hdd_debug("Do not send scan_selection_config"); 16136 return 0; 16137 } 16138 16139 /* hdd_set_fw_log_params */ 16140 dbs_scan_params.num_clients = 0; 16141 while (count < (numentries - 2)) { 16142 dbs_scan_params.module_id[i] = dbs_scan_config[count]; 16143 dbs_scan_params.num_dbs_scans[i] = dbs_scan_config[count + 1]; 16144 dbs_scan_params.num_non_dbs_scans[i] = 16145 dbs_scan_config[count + 2]; 16146 dbs_scan_params.num_clients++; 16147 hdd_debug("module:%d NDS:%d NNDS:%d", 16148 dbs_scan_params.module_id[i], 16149 dbs_scan_params.num_dbs_scans[i], 16150 dbs_scan_params.num_non_dbs_scans[i]); 16151 count += CDS_DBS_SCAN_PARAM_PER_CLIENT; 16152 i++; 16153 } 16154 16155 dbs_scan_params.pdev_id = 0; 16156 16157 hdd_debug("clients:%d pdev:%d", 16158 dbs_scan_params.num_clients, dbs_scan_params.pdev_id); 16159 16160 status = sme_set_dbs_scan_selection_config(hdd_ctx->mac_handle, 16161 &dbs_scan_params); 16162 hdd_debug("Sending DBS Scan Selection Configuration to fw"); 16163 if (!QDF_IS_STATUS_SUCCESS(status)) { 16164 hdd_err("Failed to send DBS Scan selection configuration!"); 16165 return -EAGAIN; 16166 } 16167 return 0; 16168 } 16169 16170 #ifdef FEATURE_WLAN_AUTO_SHUTDOWN 16171 /** 16172 * hdd_set_auto_shutdown_cb() - Set auto shutdown callback 16173 * @hdd_ctx: HDD context 16174 * 16175 * Set auto shutdown callback to get indications from firmware to indicate 16176 * userspace to shutdown WLAN after a configured amount of inactivity. 16177 * 16178 * Return: 0 on success and errno on failure. 16179 */ hdd_set_auto_shutdown_cb(struct hdd_context * hdd_ctx)16180 static int hdd_set_auto_shutdown_cb(struct hdd_context *hdd_ctx) 16181 { 16182 QDF_STATUS status; 16183 16184 if (!hdd_ctx->config->wlan_auto_shutdown) 16185 return 0; 16186 16187 status = sme_set_auto_shutdown_cb(hdd_ctx->mac_handle, 16188 wlan_hdd_auto_shutdown_cb); 16189 if (status != QDF_STATUS_SUCCESS) 16190 hdd_err("Auto shutdown feature could not be enabled: %d", 16191 status); 16192 16193 return qdf_status_to_os_return(status); 16194 } 16195 #else hdd_set_auto_shutdown_cb(struct hdd_context * hdd_ctx)16196 static int hdd_set_auto_shutdown_cb(struct hdd_context *hdd_ctx) 16197 { 16198 return 0; 16199 } 16200 #endif 16201 16202 #ifdef MWS_COEX 16203 #define MAX_PDEV_MWSCOEX_PARAMS 4 16204 /* params being sent: 16205 * wmi_pdev_param_mwscoex_4g_allow_quick_ftdm 16206 * wmi_pdev_param_mwscoex_set_5gnr_pwr_limit 16207 * wmi_pdev_param_mwscoex_pcc_chavd_delay 16208 * wmi_pdev_param_mwscoex_scc_chavd_delay 16209 */ 16210 16211 /** 16212 * hdd_init_mws_coex() - Initialize MWS coex configurations 16213 * @hdd_ctx: HDD context 16214 * 16215 * This function sends MWS-COEX 4G quick FTDM and 16216 * MWS-COEX 5G-NR power limit to FW 16217 * 16218 * Return: 0 on success and errno on failure. 16219 */ hdd_init_mws_coex(struct hdd_context * hdd_ctx)16220 static int hdd_init_mws_coex(struct hdd_context *hdd_ctx) 16221 { 16222 int ret = 0; 16223 uint32_t mws_coex_4g_quick_tdm = 0, mws_coex_5g_nr_pwr_limit = 0; 16224 uint32_t mws_coex_pcc_channel_avoid_delay = 0; 16225 uint32_t mws_coex_scc_channel_avoid_delay = 0; 16226 struct dev_set_param setparam[MAX_PDEV_MWSCOEX_PARAMS] = {}; 16227 uint8_t index = 0; 16228 16229 ucfg_mlme_get_mws_coex_4g_quick_tdm(hdd_ctx->psoc, 16230 &mws_coex_4g_quick_tdm); 16231 ret = mlme_check_index_setparam( 16232 setparam, 16233 wmi_pdev_param_mwscoex_4g_allow_quick_ftdm, 16234 mws_coex_4g_quick_tdm, index++, 16235 MAX_PDEV_MWSCOEX_PARAMS); 16236 if (QDF_IS_STATUS_ERROR(ret)) { 16237 hdd_err("failed at wmi_pdev_param_mwscoex_4g_allow_quick_ftdm"); 16238 goto error; 16239 } 16240 16241 ucfg_mlme_get_mws_coex_5g_nr_pwr_limit(hdd_ctx->psoc, 16242 &mws_coex_5g_nr_pwr_limit); 16243 ret = mlme_check_index_setparam( 16244 setparam, 16245 wmi_pdev_param_mwscoex_set_5gnr_pwr_limit, 16246 mws_coex_5g_nr_pwr_limit, index++, 16247 MAX_PDEV_MWSCOEX_PARAMS); 16248 if (QDF_IS_STATUS_ERROR(ret)) { 16249 hdd_err("failed at wmi_pdev_param_mwscoex_set_5gnr_pwr_limit"); 16250 goto error; 16251 } 16252 16253 ucfg_mlme_get_mws_coex_pcc_channel_avoid_delay( 16254 hdd_ctx->psoc, 16255 &mws_coex_pcc_channel_avoid_delay); 16256 ret = mlme_check_index_setparam(setparam, 16257 wmi_pdev_param_mwscoex_pcc_chavd_delay, 16258 mws_coex_pcc_channel_avoid_delay, 16259 index++, MAX_PDEV_MWSCOEX_PARAMS); 16260 if (QDF_IS_STATUS_ERROR(ret)) { 16261 hdd_err("failed at wmi_pdev_param_mwscoex_pcc_chavd_delay"); 16262 goto error; 16263 } 16264 16265 ucfg_mlme_get_mws_coex_scc_channel_avoid_delay( 16266 hdd_ctx->psoc, 16267 &mws_coex_scc_channel_avoid_delay); 16268 ret = mlme_check_index_setparam(setparam, 16269 wmi_pdev_param_mwscoex_scc_chavd_delay, 16270 mws_coex_scc_channel_avoid_delay, 16271 index++, MAX_PDEV_MWSCOEX_PARAMS); 16272 if (QDF_IS_STATUS_ERROR(ret)) { 16273 hdd_err("failed at wmi_pdev_param_mwscoex_scc_chavd_delay"); 16274 goto error; 16275 } 16276 ret = sme_send_multi_pdev_vdev_set_params(MLME_PDEV_SETPARAM, 16277 WMI_PDEV_ID_SOC, setparam, 16278 index); 16279 if (QDF_IS_STATUS_ERROR(ret)) 16280 hdd_err("failed to send pdev MWSCOEX set params"); 16281 error: 16282 return ret; 16283 } 16284 #else hdd_init_mws_coex(struct hdd_context * hdd_ctx)16285 static int hdd_init_mws_coex(struct hdd_context *hdd_ctx) 16286 { 16287 return 0; 16288 } 16289 #endif 16290 16291 #ifdef THERMAL_STATS_SUPPORT hdd_thermal_stats_cmd_init(struct hdd_context * hdd_ctx)16292 static void hdd_thermal_stats_cmd_init(struct hdd_context *hdd_ctx) 16293 { 16294 hdd_send_get_thermal_stats_cmd(hdd_ctx, thermal_stats_init, NULL, NULL); 16295 } 16296 #else hdd_thermal_stats_cmd_init(struct hdd_context * hdd_ctx)16297 static void hdd_thermal_stats_cmd_init(struct hdd_context *hdd_ctx) 16298 { 16299 } 16300 #endif 16301 16302 #ifdef WLAN_FEATURE_CAL_FAILURE_TRIGGER 16303 /** 16304 * hdd_cal_fail_send_event()- send calibration failure information 16305 * @cal_type: calibration type 16306 * @reason: reason for calibration failure 16307 * 16308 * This Function sends calibration failure diag event 16309 * 16310 * Return: void. 16311 */ hdd_cal_fail_send_event(uint8_t cal_type,uint8_t reason)16312 static void hdd_cal_fail_send_event(uint8_t cal_type, uint8_t reason) 16313 { 16314 /* 16315 * For now we are going with the print. Once CST APK has support to 16316 * read the diag events then we will add the diag event here. 16317 */ 16318 hdd_debug("Received cal failure event with cal_type:%x reason:%x", 16319 cal_type, reason); 16320 } 16321 #else hdd_cal_fail_send_event(uint8_t cal_type,uint8_t reason)16322 static inline void hdd_cal_fail_send_event(uint8_t cal_type, uint8_t reason) 16323 { 16324 } 16325 #endif 16326 16327 /** 16328 * hdd_features_init() - Init features 16329 * @hdd_ctx: HDD context 16330 * 16331 * Initialize features and their feature context after WLAN firmware is up. 16332 * 16333 * Return: 0 on success and errno on failure. 16334 */ hdd_features_init(struct hdd_context * hdd_ctx)16335 static int hdd_features_init(struct hdd_context *hdd_ctx) 16336 { 16337 struct tx_power_limit hddtxlimit; 16338 QDF_STATUS status; 16339 int ret; 16340 mac_handle_t mac_handle; 16341 bool b_cts2self, is_imps_enabled; 16342 bool rf_test_mode; 16343 bool std_6ghz_conn_policy; 16344 uint32_t fw_data_stall_evt; 16345 bool disable_vlp_sta_conn_sp_ap; 16346 16347 hdd_enter(); 16348 16349 ret = hdd_init_mws_coex(hdd_ctx); 16350 if (ret) 16351 hdd_warn("Error initializing mws-coex"); 16352 16353 /* FW capabilities received, Set the Dot11 mode */ 16354 mac_handle = hdd_ctx->mac_handle; 16355 sme_setdef_dot11mode(mac_handle); 16356 16357 ucfg_mlme_is_imps_enabled(hdd_ctx->psoc, &is_imps_enabled); 16358 hdd_set_idle_ps_config(hdd_ctx, is_imps_enabled); 16359 16360 fw_data_stall_evt = ucfg_dp_fw_data_stall_evt_enabled(); 16361 16362 /* Send Enable/Disable data stall detection cmd to FW */ 16363 sme_cli_set_command(0, wmi_pdev_param_data_stall_detect_enable, 16364 fw_data_stall_evt, PDEV_CMD); 16365 16366 ucfg_mlme_get_go_cts2self_for_sta(hdd_ctx->psoc, &b_cts2self); 16367 if (b_cts2self) 16368 sme_set_cts2self_for_p2p_go(mac_handle); 16369 16370 if (hdd_set_vc_mode_config(hdd_ctx)) 16371 hdd_warn("Error in setting Voltage Corner mode config to FW"); 16372 16373 if (ucfg_dp_rx_ol_init(hdd_ctx->psoc, hdd_ctx->is_wifi3_0_target)) 16374 hdd_err("Unable to initialize Rx LRO/GRO in fw"); 16375 16376 if (hdd_adaptive_dwelltime_init(hdd_ctx)) 16377 hdd_err("Unable to send adaptive dwelltime setting to FW"); 16378 16379 if (hdd_dbs_scan_selection_init(hdd_ctx)) 16380 hdd_err("Unable to send DBS scan selection setting to FW"); 16381 16382 ret = hdd_init_thermal_info(hdd_ctx); 16383 if (ret) { 16384 hdd_err("Error while initializing thermal information"); 16385 return ret; 16386 } 16387 16388 /** 16389 * In case of SSR/PDR, if pktlog was enabled manually before 16390 * SSR/PDR, then enable it again automatically after Wlan 16391 * device up. 16392 * During SSR/PDR, pktlog will be disabled as part of 16393 * hdd_features_deinit if pktlog is enabled in ini. 16394 * Re-enable pktlog in SSR case, if pktlog is enabled in ini. 16395 */ 16396 if (hdd_get_conparam() != QDF_GLOBAL_MONITOR_MODE && 16397 (cds_is_packet_log_enabled() || 16398 (cds_is_driver_recovering() && hdd_ctx->is_pktlog_enabled))) 16399 hdd_pktlog_enable_disable(hdd_ctx, true, 0, 0); 16400 16401 hddtxlimit.txPower2g = ucfg_get_tx_power(hdd_ctx->psoc, BAND_2G); 16402 hddtxlimit.txPower5g = ucfg_get_tx_power(hdd_ctx->psoc, BAND_5G); 16403 status = sme_txpower_limit(mac_handle, &hddtxlimit); 16404 if (!QDF_IS_STATUS_SUCCESS(status)) 16405 hdd_err("Error setting txlimit in sme: %d", status); 16406 16407 wlan_hdd_tsf_init(hdd_ctx); 16408 16409 status = sme_enable_disable_chanavoidind_event(mac_handle, 0); 16410 if (QDF_IS_STATUS_ERROR(status) && (status != QDF_STATUS_E_NOSUPPORT)) { 16411 hdd_err("Failed to disable Chan Avoidance Indication"); 16412 return -EINVAL; 16413 } 16414 16415 /* register P2P Listen Offload event callback */ 16416 if (wma_is_p2p_lo_capable()) 16417 sme_register_p2p_lo_event(mac_handle, hdd_ctx, 16418 wlan_hdd_p2p_lo_event_callback); 16419 wlan_hdd_register_mcc_quota_event_callback(hdd_ctx); 16420 ret = hdd_set_auto_shutdown_cb(hdd_ctx); 16421 16422 if (ret) 16423 return -EINVAL; 16424 16425 wlan_hdd_init_chan_info(hdd_ctx); 16426 wlan_hdd_twt_init(hdd_ctx); 16427 wlan_hdd_gpio_wakeup_init(hdd_ctx); 16428 16429 status = ucfg_mlme_is_rf_test_mode_enabled(hdd_ctx->psoc, 16430 &rf_test_mode); 16431 if (!QDF_IS_STATUS_SUCCESS(status)) { 16432 hdd_err("Get rf test mode failed"); 16433 return QDF_STATUS_E_FAILURE; 16434 } 16435 16436 if (rf_test_mode) { 16437 wlan_cm_set_check_6ghz_security(hdd_ctx->psoc, false); 16438 wlan_cm_set_6ghz_key_mgmt_mask(hdd_ctx->psoc, 16439 DEFAULT_KEYMGMT_6G_MASK); 16440 } 16441 16442 status = ucfg_mlme_is_standard_6ghz_conn_policy_enabled(hdd_ctx->psoc, 16443 &std_6ghz_conn_policy); 16444 16445 if (!QDF_IS_STATUS_SUCCESS(status)) { 16446 hdd_err("Get 6ghz standard connection policy failed"); 16447 return QDF_STATUS_E_FAILURE; 16448 } 16449 if (std_6ghz_conn_policy) 16450 wlan_cm_set_standard_6ghz_conn_policy(hdd_ctx->psoc, true); 16451 16452 status = ucfg_mlme_is_disable_vlp_sta_conn_to_sp_ap_enabled( 16453 hdd_ctx->psoc, 16454 &disable_vlp_sta_conn_sp_ap); 16455 if (!QDF_IS_STATUS_SUCCESS(status)) { 16456 hdd_err("Get disable vlp sta conn to sp flag failed"); 16457 return QDF_STATUS_E_FAILURE; 16458 } 16459 16460 if (disable_vlp_sta_conn_sp_ap) 16461 wlan_cm_set_disable_vlp_sta_conn_to_sp_ap(hdd_ctx->psoc, true); 16462 16463 hdd_thermal_stats_cmd_init(hdd_ctx); 16464 sme_set_cal_failure_event_cb(hdd_ctx->mac_handle, 16465 hdd_cal_fail_send_event); 16466 16467 hdd_exit(); 16468 return 0; 16469 } 16470 16471 /** 16472 * hdd_register_bcn_cb() - register scan beacon callback 16473 * @hdd_ctx: Pointer to the HDD context 16474 * 16475 * Return: QDF_STATUS 16476 */ hdd_register_bcn_cb(struct hdd_context * hdd_ctx)16477 static inline QDF_STATUS hdd_register_bcn_cb(struct hdd_context *hdd_ctx) 16478 { 16479 QDF_STATUS status; 16480 16481 status = ucfg_scan_register_bcn_cb(hdd_ctx->psoc, 16482 wlan_cfg80211_inform_bss_frame, 16483 SCAN_CB_TYPE_INFORM_BCN); 16484 if (!QDF_IS_STATUS_SUCCESS(status)) { 16485 hdd_err("failed to register SCAN_CB_TYPE_INFORM_BCN with status code %08d [x%08x]", 16486 status, status); 16487 return status; 16488 } 16489 16490 status = ucfg_scan_register_bcn_cb(hdd_ctx->psoc, 16491 wlan_cfg80211_unlink_bss_list, 16492 SCAN_CB_TYPE_UNLINK_BSS); 16493 if (!QDF_IS_STATUS_SUCCESS(status)) { 16494 hdd_err("failed to refister SCAN_CB_TYPE_FLUSH_BSS with status code %08d [x%08x]", 16495 status, status); 16496 return status; 16497 } 16498 16499 return QDF_STATUS_SUCCESS; 16500 } 16501 16502 /** 16503 * hdd_v2_flow_pool_map() - Flow pool create callback when vdev is active 16504 * @vdev_id: vdev_id, corresponds to flow_pool 16505 * 16506 * Return: none. 16507 */ hdd_v2_flow_pool_map(int vdev_id)16508 static void hdd_v2_flow_pool_map(int vdev_id) 16509 { 16510 QDF_STATUS status; 16511 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 16512 struct wlan_objmgr_vdev *vdev; 16513 16514 if (!hdd_ctx) { 16515 hdd_err("HDD context null"); 16516 return; 16517 } 16518 16519 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(hdd_ctx->psoc, vdev_id, 16520 WLAN_OSIF_ID); 16521 if (!vdev) { 16522 hdd_err("Invalid VDEV %d", vdev_id); 16523 return; 16524 } 16525 16526 if (wlan_vdev_mlme_is_mlo_link_switch_in_progress(vdev) || 16527 policy_mgr_is_set_link_in_progress(wlan_vdev_get_psoc(vdev))) { 16528 hdd_info_rl("Link switch/set_link is ongoing, do not invoke flow pool map"); 16529 goto release_ref; 16530 } 16531 16532 status = cdp_flow_pool_map(cds_get_context(QDF_MODULE_ID_SOC), 16533 OL_TXRX_PDEV_ID, vdev_id); 16534 /* 16535 * For Adrastea flow control v2 is based on FW MAP events, 16536 * so this above callback is not implemented. 16537 * Hence this is not actual failure. Dont return failure 16538 */ 16539 if ((status != QDF_STATUS_SUCCESS) && 16540 (status != QDF_STATUS_E_INVAL)) { 16541 hdd_err("vdev_id: %d, failed to create flow pool status %d", 16542 vdev_id, status); 16543 } 16544 16545 release_ref: 16546 wlan_objmgr_vdev_release_ref(vdev, WLAN_OSIF_ID); 16547 } 16548 16549 /** 16550 * hdd_v2_flow_pool_unmap() - Flow pool create callback when vdev is not active 16551 * @vdev_id: vdev_id, corresponds to flow_pool 16552 * 16553 * Return: none. 16554 */ hdd_v2_flow_pool_unmap(int vdev_id)16555 static void hdd_v2_flow_pool_unmap(int vdev_id) 16556 { 16557 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 16558 struct wlan_objmgr_vdev *vdev; 16559 16560 if (!hdd_ctx) { 16561 hdd_err("HDD context null"); 16562 return; 16563 } 16564 16565 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(hdd_ctx->psoc, vdev_id, 16566 WLAN_OSIF_ID); 16567 if (!vdev) { 16568 hdd_err("Invalid VDEV %d", vdev_id); 16569 return; 16570 } 16571 16572 if (wlan_vdev_mlme_is_mlo_link_switch_in_progress(vdev)) { 16573 hdd_info("Link switch ongoing do not invoke flow pool unmap"); 16574 goto release_ref; 16575 } 16576 16577 cdp_flow_pool_unmap(cds_get_context(QDF_MODULE_ID_SOC), 16578 OL_TXRX_PDEV_ID, vdev_id); 16579 release_ref: 16580 wlan_objmgr_vdev_release_ref(vdev, WLAN_OSIF_ID); 16581 } 16582 hdd_hastings_bt_war_initialize(struct hdd_context * hdd_ctx)16583 static void hdd_hastings_bt_war_initialize(struct hdd_context *hdd_ctx) 16584 { 16585 if (hdd_ctx->config->iface_change_wait_time) 16586 hdd_hastings_bt_war_disable_fw(hdd_ctx); 16587 else 16588 hdd_hastings_bt_war_enable_fw(hdd_ctx); 16589 } 16590 16591 #define MAX_PDEV_CFG_CDS_PARAMS 8 16592 /* params being sent: 16593 * wmi_pdev_param_set_iot_pattern 16594 * wmi_pdev_param_max_mpdus_in_ampdu 16595 * wmi_pdev_param_enable_rts_sifs_bursting 16596 * wmi_pdev_param_peer_stats_info_enable 16597 * wmi_pdev_param_abg_mode_tx_chain_num 16598 * wmi_pdev_param_gcmp_support_enable 16599 * wmi_pdev_auto_detect_power_failure 16600 * wmi_pdev_param_fast_pwr_transition 16601 */ 16602 16603 /** 16604 * hdd_configure_cds() - Configure cds modules 16605 * @hdd_ctx: HDD context 16606 * 16607 * Enable Cds modules after WLAN firmware is up. 16608 * 16609 * Return: 0 on success and errno on failure. 16610 */ hdd_configure_cds(struct hdd_context * hdd_ctx)16611 int hdd_configure_cds(struct hdd_context *hdd_ctx) 16612 { 16613 int ret; 16614 QDF_STATUS status; 16615 int set_value; 16616 mac_handle_t mac_handle; 16617 bool enable_rts_sifsbursting; 16618 uint8_t enable_phy_reg_retention; 16619 uint8_t max_mpdus_inampdu, is_force_1x1 = 0; 16620 uint32_t num_abg_tx_chains = 0; 16621 uint16_t num_11b_tx_chains = 0; 16622 uint16_t num_11ag_tx_chains = 0; 16623 struct policy_mgr_dp_cbacks dp_cbs = {0}; 16624 bool value; 16625 enum pmo_auto_pwr_detect_failure_mode auto_power_fail_mode; 16626 bool bval = false; 16627 uint8_t max_index = MAX_PDEV_CFG_CDS_PARAMS; 16628 struct dev_set_param setparam[MAX_PDEV_CFG_CDS_PARAMS] = {}; 16629 uint8_t index = 0; 16630 uint8_t next_index = 0; 16631 mac_handle = hdd_ctx->mac_handle; 16632 16633 status = ucfg_policy_mgr_get_force_1x1(hdd_ctx->psoc, &is_force_1x1); 16634 if (status != QDF_STATUS_SUCCESS) { 16635 hdd_err("Failed to get force 1x1 value"); 16636 goto out; 16637 } 16638 if (is_force_1x1) { 16639 status = mlme_check_index_setparam( 16640 setparam, 16641 wmi_pdev_param_set_iot_pattern, 16642 1, index++, 16643 max_index); 16644 if (QDF_IS_STATUS_ERROR(status)) { 16645 hdd_err("failed at wmi_pdev_param_set_iot_pattern"); 16646 goto out; 16647 } 16648 } 16649 /* set chip power save failure detected callback */ 16650 sme_set_chip_pwr_save_fail_cb(mac_handle, 16651 hdd_chip_pwr_save_fail_detected_cb); 16652 16653 status = ucfg_get_max_mpdus_inampdu(hdd_ctx->psoc, 16654 &max_mpdus_inampdu); 16655 if (status) { 16656 hdd_err("Failed to get max mpdus in ampdu value"); 16657 goto out; 16658 } 16659 16660 if (max_mpdus_inampdu) { 16661 set_value = max_mpdus_inampdu; 16662 status = mlme_check_index_setparam( 16663 setparam, 16664 wmi_pdev_param_max_mpdus_in_ampdu, 16665 set_value, index++, 16666 max_index); 16667 if (QDF_IS_STATUS_ERROR(status)) { 16668 hdd_err("failed at wmi_pdev_param_max_mpdus_in_ampdu"); 16669 goto out; 16670 } 16671 } 16672 16673 status = ucfg_get_enable_rts_sifsbursting(hdd_ctx->psoc, 16674 &enable_rts_sifsbursting); 16675 if (status) { 16676 hdd_err("Failed to get rts sifs bursting value"); 16677 goto out; 16678 } 16679 16680 if (enable_rts_sifsbursting) { 16681 set_value = enable_rts_sifsbursting; 16682 status = mlme_check_index_setparam( 16683 setparam, 16684 wmi_pdev_param_enable_rts_sifs_bursting, 16685 set_value, index++, 16686 max_index); 16687 if (QDF_IS_STATUS_ERROR(status)) { 16688 hdd_err("Failed at wmi_pdev_param_enable_rts_sifs_bursting"); 16689 goto out; 16690 } 16691 } 16692 16693 ucfg_mlme_get_sap_get_peer_info(hdd_ctx->psoc, &value); 16694 if (value) { 16695 set_value = value; 16696 status = mlme_check_index_setparam( 16697 setparam, 16698 wmi_pdev_param_peer_stats_info_enable, 16699 set_value, index++, 16700 max_index); 16701 if (QDF_IS_STATUS_ERROR(status)) { 16702 hdd_err("Failed at wmi_pdev_param_peer_stats_info_enable"); 16703 goto out; 16704 } 16705 } 16706 16707 status = ucfg_mlme_get_num_11b_tx_chains(hdd_ctx->psoc, 16708 &num_11b_tx_chains); 16709 if (status != QDF_STATUS_SUCCESS) { 16710 hdd_err("Failed to get num_11b_tx_chains"); 16711 goto out; 16712 } 16713 16714 status = ucfg_mlme_get_num_11ag_tx_chains(hdd_ctx->psoc, 16715 &num_11ag_tx_chains); 16716 if (status != QDF_STATUS_SUCCESS) { 16717 hdd_err("Failed to get num_11ag_tx_chains"); 16718 goto out; 16719 } 16720 16721 status = ucfg_mlme_get_vht_enable2x2(hdd_ctx->psoc, &bval); 16722 if (!QDF_IS_STATUS_SUCCESS(status)) 16723 hdd_err("unable to get vht_enable2x2"); 16724 16725 if (!bval) { 16726 if (num_11b_tx_chains > 1) 16727 num_11b_tx_chains = 1; 16728 if (num_11ag_tx_chains > 1) 16729 num_11ag_tx_chains = 1; 16730 } 16731 WMI_PDEV_PARAM_SET_11B_TX_CHAIN_NUM(num_abg_tx_chains, 16732 num_11b_tx_chains); 16733 WMI_PDEV_PARAM_SET_11AG_TX_CHAIN_NUM(num_abg_tx_chains, 16734 num_11ag_tx_chains); 16735 status = mlme_check_index_setparam(setparam, 16736 wmi_pdev_param_abg_mode_tx_chain_num, 16737 num_abg_tx_chains, index++, 16738 max_index); 16739 if (QDF_IS_STATUS_ERROR(status)) { 16740 hdd_err("Failed at wmi_pdev_param_abg_mode_tx_chain_num"); 16741 goto out; 16742 } 16743 /* Send some pdev params to maintain legacy order of pdev set params 16744 * at hdd_pre_enable_configure 16745 */ 16746 status = sme_send_multi_pdev_vdev_set_params(MLME_PDEV_SETPARAM, 16747 WMI_PDEV_ID_SOC, setparam, 16748 index); 16749 if (QDF_IS_STATUS_ERROR(status)) { 16750 hdd_err("Failed to send 1st set of pdev params"); 16751 goto out; 16752 } 16753 if (!ucfg_reg_is_regdb_offloaded(hdd_ctx->psoc)) 16754 ucfg_reg_program_default_cc(hdd_ctx->pdev, 16755 hdd_ctx->reg.reg_domain); 16756 16757 ret = hdd_pre_enable_configure(hdd_ctx); 16758 if (ret) { 16759 hdd_err("Failed to pre-configure cds"); 16760 goto out; 16761 } 16762 16763 /* Always get latest IPA resources allocated from cds_open and configure 16764 * IPA module before configuring them to FW. Sequence required as crash 16765 * observed otherwise. 16766 */ 16767 16768 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) { 16769 ipa_disable_register_cb(); 16770 } else { 16771 status = ipa_register_is_ipa_ready(hdd_ctx->pdev); 16772 if (!QDF_IS_STATUS_SUCCESS(status)) { 16773 hdd_err("ipa_register_is_ipa_ready failed"); 16774 goto out; 16775 } 16776 } 16777 16778 /* 16779 * Start CDS which starts up the SME/MAC/HAL modules and everything 16780 * else 16781 */ 16782 status = cds_enable(hdd_ctx->psoc); 16783 16784 if (!QDF_IS_STATUS_SUCCESS(status)) { 16785 hdd_err("cds_enable failed"); 16786 goto out; 16787 } 16788 16789 status = hdd_post_cds_enable_config(hdd_ctx); 16790 if (!QDF_IS_STATUS_SUCCESS(status)) { 16791 hdd_err("hdd_post_cds_enable_config failed"); 16792 goto cds_disable; 16793 } 16794 status = hdd_register_bcn_cb(hdd_ctx); 16795 if (!QDF_IS_STATUS_SUCCESS(status)) { 16796 hdd_err("hdd_register_bcn_cb failed"); 16797 goto cds_disable; 16798 } 16799 16800 ret = hdd_features_init(hdd_ctx); 16801 if (ret) 16802 goto cds_disable; 16803 16804 /* 16805 * Donot disable rx offload on concurrency for lithium and 16806 * beryllium based targets 16807 */ 16808 if (!hdd_ctx->is_wifi3_0_target) 16809 if (ucfg_dp_is_ol_enabled(hdd_ctx->psoc)) 16810 dp_cbs.hdd_disable_rx_ol_in_concurrency = 16811 hdd_disable_rx_ol_in_concurrency; 16812 dp_cbs.hdd_set_rx_mode_rps_cb = ucfg_dp_set_rx_mode_rps; 16813 dp_cbs.hdd_ipa_set_mcc_mode_cb = hdd_ipa_set_mcc_mode; 16814 dp_cbs.hdd_v2_flow_pool_map = hdd_v2_flow_pool_map; 16815 dp_cbs.hdd_v2_flow_pool_unmap = hdd_v2_flow_pool_unmap; 16816 if (ucfg_ipa_set_perf_level_bw_enabled(hdd_ctx->pdev)) 16817 dp_cbs.hdd_ipa_set_perf_level_bw = hdd_ipa_set_perf_level_bw; 16818 status = policy_mgr_register_dp_cb(hdd_ctx->psoc, &dp_cbs); 16819 if (!QDF_IS_STATUS_SUCCESS(status)) { 16820 hdd_debug("Failed to register DP cb with Policy Manager"); 16821 goto cds_disable; 16822 } 16823 status = policy_mgr_register_mode_change_cb(hdd_ctx->psoc, 16824 wlan_hdd_send_mode_change_event); 16825 if (!QDF_IS_STATUS_SUCCESS(status)) { 16826 hdd_debug("Failed to register mode change cb with Policy Manager"); 16827 goto cds_disable; 16828 } 16829 16830 if (hdd_green_ap_enable_egap(hdd_ctx)) 16831 hdd_debug("enhance green ap is not enabled"); 16832 16833 hdd_register_green_ap_callback(hdd_ctx->pdev); 16834 16835 if (0 != wlan_hdd_set_wow_pulse(hdd_ctx, true)) 16836 hdd_debug("Failed to set wow pulse"); 16837 16838 max_index = max_index - index; 16839 status = mlme_check_index_setparam( 16840 setparam + index, 16841 wmi_pdev_param_gcmp_support_enable, 16842 ucfg_fwol_get_gcmp_enable(hdd_ctx->psoc), 16843 next_index++, max_index); 16844 if (QDF_IS_STATUS_ERROR(status)) { 16845 hdd_err("failed at wmi_pdev_param_gcmp_support_enable"); 16846 goto out; 16847 } 16848 16849 auto_power_fail_mode = 16850 ucfg_pmo_get_auto_power_fail_mode(hdd_ctx->psoc); 16851 status = mlme_check_index_setparam( 16852 setparam + index, 16853 wmi_pdev_auto_detect_power_failure, 16854 auto_power_fail_mode, 16855 next_index++, max_index); 16856 if (QDF_IS_STATUS_ERROR(status)) { 16857 hdd_err("failed at wmi_pdev_auto_detect_power_failure"); 16858 goto out; 16859 } 16860 16861 status = ucfg_get_enable_phy_reg_retention(hdd_ctx->psoc, 16862 &enable_phy_reg_retention); 16863 16864 if (QDF_IS_STATUS_ERROR(status)) 16865 return -EINVAL; 16866 16867 if (enable_phy_reg_retention) { 16868 status = mlme_check_index_setparam( 16869 setparam + index, 16870 wmi_pdev_param_fast_pwr_transition, 16871 enable_phy_reg_retention, 16872 next_index++, max_index); 16873 if (QDF_IS_STATUS_ERROR(status)) { 16874 hdd_err("failed at wmi_pdev_param_fast_pwr_transition"); 16875 goto out; 16876 } 16877 } 16878 /*Send remaining pdev setparams from array*/ 16879 status = sme_send_multi_pdev_vdev_set_params(MLME_PDEV_SETPARAM, 16880 WMI_PDEV_ID_SOC, 16881 setparam + index, 16882 next_index); 16883 if (QDF_IS_STATUS_ERROR(status)) { 16884 hdd_err("failed to send 2nd set of pdev set params"); 16885 goto out; 16886 } 16887 16888 hdd_hastings_bt_war_initialize(hdd_ctx); 16889 16890 wlan_hdd_hang_event_notifier_register(hdd_ctx); 16891 return 0; 16892 16893 cds_disable: 16894 cds_disable(hdd_ctx->psoc); 16895 16896 out: 16897 return -EINVAL; 16898 } 16899 16900 #ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH hdd_deregister_policy_manager_callback(struct wlan_objmgr_psoc * psoc)16901 static void hdd_deregister_policy_manager_callback( 16902 struct wlan_objmgr_psoc *psoc) 16903 { 16904 if (QDF_STATUS_SUCCESS != 16905 policy_mgr_deregister_hdd_cb(psoc)) { 16906 hdd_err("HDD callback deregister with policy manager failed"); 16907 } 16908 } 16909 #else hdd_deregister_policy_manager_callback(struct wlan_objmgr_psoc * psoc)16910 static void hdd_deregister_policy_manager_callback( 16911 struct wlan_objmgr_psoc *psoc) 16912 { 16913 } 16914 #endif 16915 hdd_wlan_stop_modules(struct hdd_context * hdd_ctx,bool ftm_mode)16916 int hdd_wlan_stop_modules(struct hdd_context *hdd_ctx, bool ftm_mode) 16917 { 16918 void *hif_ctx; 16919 qdf_device_t qdf_ctx; 16920 QDF_STATUS qdf_status; 16921 bool is_recovery_stop = cds_is_driver_recovering(); 16922 int ret = 0; 16923 int debugfs_threads; 16924 struct target_psoc_info *tgt_hdl; 16925 struct bbm_params param = {0}; 16926 16927 hdd_enter(); 16928 qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE); 16929 if (!qdf_ctx) 16930 return -EINVAL; 16931 16932 cds_set_driver_state_module_stop(true); 16933 16934 debugfs_threads = hdd_return_debugfs_threads_count(); 16935 16936 if (debugfs_threads > 0 || hdd_ctx->is_wiphy_suspended) { 16937 hdd_warn("Debugfs threads %d, wiphy suspend %d", 16938 debugfs_threads, hdd_ctx->is_wiphy_suspended); 16939 16940 if (IS_IDLE_STOP && !ftm_mode) { 16941 hdd_psoc_idle_timer_start(hdd_ctx); 16942 cds_set_driver_state_module_stop(false); 16943 16944 ucfg_dp_bus_bw_compute_timer_stop(hdd_ctx->psoc); 16945 return -EAGAIN; 16946 } 16947 } 16948 16949 ucfg_dp_bus_bw_compute_timer_stop(hdd_ctx->psoc); 16950 hdd_deregister_policy_manager_callback(hdd_ctx->psoc); 16951 16952 /* free user wowl patterns */ 16953 hdd_free_user_wowl_ptrns(); 16954 16955 switch (hdd_ctx->driver_status) { 16956 case DRIVER_MODULES_UNINITIALIZED: 16957 hdd_debug("Modules not initialized just return"); 16958 goto done; 16959 case DRIVER_MODULES_CLOSED: 16960 hdd_debug("Modules already closed"); 16961 goto done; 16962 case DRIVER_MODULES_ENABLED: 16963 hdd_debug("Wlan transitioning (CLOSED <- ENABLED)"); 16964 16965 if (hdd_get_conparam() == QDF_GLOBAL_FTM_MODE) { 16966 hdd_disable_power_management(hdd_ctx); 16967 break; 16968 } 16969 16970 if (hdd_get_conparam() == QDF_GLOBAL_EPPING_MODE) 16971 break; 16972 16973 hdd_skip_acs_scan_timer_deinit(hdd_ctx); 16974 16975 hdd_disable_power_management(hdd_ctx); 16976 16977 if (hdd_get_conparam() == QDF_GLOBAL_MISSION_MODE) 16978 ucfg_dp_direct_link_deinit(hdd_ctx->psoc, 16979 is_recovery_stop); 16980 16981 if (hdd_deconfigure_cds(hdd_ctx)) { 16982 hdd_err("Failed to de-configure CDS"); 16983 QDF_ASSERT(0); 16984 ret = -EINVAL; 16985 } 16986 hdd_debug("successfully Disabled the CDS modules!"); 16987 16988 break; 16989 default: 16990 QDF_DEBUG_PANIC("Unknown driver state:%d", 16991 hdd_ctx->driver_status); 16992 ret = -EINVAL; 16993 goto done; 16994 } 16995 16996 hdd_destroy_sysfs_files(); 16997 hdd_debug("Closing CDS modules!"); 16998 16999 if (hdd_get_conparam() != QDF_GLOBAL_EPPING_MODE) { 17000 qdf_status = cds_post_disable(); 17001 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { 17002 hdd_err("Failed to process post CDS disable! :%d", 17003 qdf_status); 17004 ret = -EINVAL; 17005 QDF_ASSERT(0); 17006 } 17007 17008 hdd_unregister_notifiers(hdd_ctx); 17009 /* De-register the SME callbacks */ 17010 hdd_deregister_cb(hdd_ctx); 17011 17012 hdd_runtime_suspend_context_deinit(hdd_ctx); 17013 17014 qdf_status = cds_dp_close(hdd_ctx->psoc); 17015 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { 17016 hdd_warn("Failed to stop CDS DP: %d", qdf_status); 17017 ret = -EINVAL; 17018 QDF_ASSERT(0); 17019 } 17020 17021 hdd_component_pdev_close(hdd_ctx->pdev); 17022 dispatcher_pdev_close(hdd_ctx->pdev); 17023 ret = hdd_objmgr_release_and_destroy_pdev(hdd_ctx); 17024 if (ret) { 17025 hdd_err("Failed to destroy pdev; errno:%d", ret); 17026 QDF_ASSERT(0); 17027 } 17028 17029 qdf_status = cds_close(hdd_ctx->psoc); 17030 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { 17031 hdd_warn("Failed to stop CDS: %d", qdf_status); 17032 ret = -EINVAL; 17033 QDF_ASSERT(0); 17034 } 17035 17036 qdf_status = wbuff_module_deinit(); 17037 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) 17038 hdd_err("WBUFF de-init unsuccessful; status: %d", 17039 qdf_status); 17040 17041 hdd_component_psoc_close(hdd_ctx->psoc); 17042 /* pdev close and destroy use tx rx ops so call this here */ 17043 wlan_global_lmac_if_close(hdd_ctx->psoc); 17044 } 17045 17046 /* 17047 * Reset total mac phy during module stop such that during 17048 * next module start same psoc is used to populate new service 17049 * ready data 17050 */ 17051 tgt_hdl = wlan_psoc_get_tgt_if_handle(hdd_ctx->psoc); 17052 if (tgt_hdl) 17053 target_psoc_set_total_mac_phy_cnt(tgt_hdl, 0); 17054 17055 17056 hif_ctx = cds_get_context(QDF_MODULE_ID_HIF); 17057 if (!hif_ctx) 17058 ret = -EINVAL; 17059 17060 if (hdd_get_conparam() == QDF_GLOBAL_EPPING_MODE) { 17061 epping_disable(); 17062 epping_close(); 17063 } 17064 17065 wlan_connectivity_logging_stop(); 17066 17067 ucfg_ipa_component_config_free(); 17068 17069 hdd_hif_close(hdd_ctx, hif_ctx); 17070 17071 ol_cds_free(); 17072 17073 if (IS_IDLE_STOP) { 17074 ret = pld_power_off(qdf_ctx->dev); 17075 if (ret) 17076 hdd_err("Failed to power down device; errno:%d", ret); 17077 } 17078 17079 /* Free the cache channels of the command SET_DISABLE_CHANNEL_LIST */ 17080 wlan_hdd_free_cache_channels(hdd_ctx); 17081 hdd_driver_mem_cleanup(); 17082 17083 /* Free the resources allocated while storing SAR config. These needs 17084 * to be freed only in the case when it is not SSR. As in the case of 17085 * SSR, the values needs to be intact so that it can be restored during 17086 * reinit path. 17087 */ 17088 if (!is_recovery_stop) 17089 wlan_hdd_free_sar_config(hdd_ctx); 17090 17091 hdd_sap_destroy_ctx_all(hdd_ctx, is_recovery_stop); 17092 hdd_sta_destroy_ctx_all(hdd_ctx); 17093 17094 /* 17095 * Reset the driver mode specific bus bw level 17096 */ 17097 param.policy = BBM_DRIVER_MODE_POLICY; 17098 param.policy_info.driver_mode = QDF_GLOBAL_MAX_MODE; 17099 ucfg_dp_bbm_apply_independent_policy(hdd_ctx->psoc, ¶m); 17100 17101 hdd_deinit_adapter_ops_wq(hdd_ctx); 17102 hdd_deinit_qdf_ctx(hdd_debug_domain_get()); 17103 17104 hdd_check_for_leaks(hdd_ctx, is_recovery_stop); 17105 hdd_debug_domain_set(QDF_DEBUG_DOMAIN_INIT); 17106 hdd_deinit_qdf_ctx(hdd_debug_domain_get()); 17107 qdf_dma_invalid_buf_list_deinit(); 17108 17109 /* Restore PS params for monitor mode */ 17110 if (hdd_get_conparam() == QDF_GLOBAL_MONITOR_MODE) 17111 hdd_restore_all_ps(hdd_ctx); 17112 17113 /* Once the firmware sequence is completed reset this flag */ 17114 hdd_ctx->imps_enabled = false; 17115 hdd_ctx->is_dual_mac_cfg_updated = false; 17116 hdd_ctx->driver_status = DRIVER_MODULES_CLOSED; 17117 hdd_ctx->is_fw_dbg_log_levels_configured = false; 17118 hdd_debug("Wlan transitioned (now CLOSED)"); 17119 17120 done: 17121 hdd_exit(); 17122 17123 return ret; 17124 } 17125 17126 #ifdef WLAN_FEATURE_MEMDUMP_ENABLE 17127 /** 17128 * hdd_state_info_dump() - prints state information of hdd layer 17129 * @buf_ptr: buffer pointer 17130 * @size: size of buffer to be filled 17131 * 17132 * This function is used to dump state information of hdd layer 17133 * 17134 * Return: None 17135 */ hdd_state_info_dump(char ** buf_ptr,uint16_t * size)17136 static void hdd_state_info_dump(char **buf_ptr, uint16_t *size) 17137 { 17138 struct hdd_context *hdd_ctx; 17139 struct hdd_station_ctx *sta_ctx; 17140 struct hdd_adapter *adapter, *next_adapter = NULL; 17141 uint16_t len = 0; 17142 char *buf = *buf_ptr; 17143 wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_STATE_INFO_DUMP; 17144 struct wlan_hdd_link_info *link_info; 17145 17146 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 17147 if (!hdd_ctx) 17148 return; 17149 17150 hdd_debug("size of buffer: %d", *size); 17151 17152 len += scnprintf(buf + len, *size - len, "\n is_wiphy_suspended %d", 17153 hdd_ctx->is_wiphy_suspended); 17154 len += scnprintf(buf + len, *size - len, "\n is_scheduler_suspended %d", 17155 hdd_ctx->is_scheduler_suspended); 17156 17157 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 17158 dbgid) { 17159 hdd_adapter_for_each_active_link_info(adapter, link_info) { 17160 len += 17161 scnprintf(buf + len, *size - len, "\n device name: %s", 17162 adapter->dev->name); 17163 len += 17164 scnprintf(buf + len, *size - len, "\n device_mode: %d", 17165 adapter->device_mode); 17166 switch (adapter->device_mode) { 17167 case QDF_STA_MODE: 17168 case QDF_P2P_CLIENT_MODE: 17169 sta_ctx = 17170 WLAN_HDD_GET_STATION_CTX_PTR(link_info); 17171 len += scnprintf(buf + len, *size - len, 17172 "\n conn_state: %d", 17173 sta_ctx->conn_info.conn_state); 17174 break; 17175 default: 17176 break; 17177 } 17178 } 17179 hdd_adapter_dev_put_debug(adapter, dbgid); 17180 } 17181 17182 *size -= len; 17183 *buf_ptr += len; 17184 } 17185 17186 /** 17187 * hdd_register_debug_callback() - registration function for hdd layer 17188 * to print hdd state information 17189 * 17190 * Return: None 17191 */ hdd_register_debug_callback(void)17192 static void hdd_register_debug_callback(void) 17193 { 17194 qdf_register_debug_callback(QDF_MODULE_ID_HDD, &hdd_state_info_dump); 17195 } 17196 #else /* WLAN_FEATURE_MEMDUMP_ENABLE */ hdd_register_debug_callback(void)17197 static void hdd_register_debug_callback(void) 17198 { 17199 } 17200 #endif /* WLAN_FEATURE_MEMDUMP_ENABLE */ 17201 17202 /* 17203 * wlan_init_bug_report_lock() - Initialize bug report lock 17204 * 17205 * This function is used to create bug report lock 17206 * 17207 * Return: None 17208 */ wlan_init_bug_report_lock(void)17209 static void wlan_init_bug_report_lock(void) 17210 { 17211 struct cds_context *p_cds_context; 17212 17213 p_cds_context = cds_get_global_context(); 17214 if (!p_cds_context) { 17215 hdd_err("cds context is NULL"); 17216 return; 17217 } 17218 17219 qdf_spinlock_create(&p_cds_context->bug_report_lock); 17220 } 17221 17222 #ifdef DISABLE_CHANNEL_LIST wlan_hdd_cache_chann_mutex_create(struct hdd_context * hdd_ctx)17223 static QDF_STATUS wlan_hdd_cache_chann_mutex_create(struct hdd_context *hdd_ctx) 17224 { 17225 return qdf_mutex_create(&hdd_ctx->cache_channel_lock); 17226 } 17227 #else wlan_hdd_cache_chann_mutex_create(struct hdd_context * hdd_ctx)17228 static QDF_STATUS wlan_hdd_cache_chann_mutex_create(struct hdd_context *hdd_ctx) 17229 { 17230 return QDF_STATUS_SUCCESS; 17231 } 17232 #endif 17233 hdd_open_adapter_no_trans(struct hdd_context * hdd_ctx,enum QDF_OPMODE op_mode,const char * iface_name,uint8_t * mac_addr_bytes,struct hdd_adapter_create_param * params)17234 QDF_STATUS hdd_open_adapter_no_trans(struct hdd_context *hdd_ctx, 17235 enum QDF_OPMODE op_mode, 17236 const char *iface_name, 17237 uint8_t *mac_addr_bytes, 17238 struct hdd_adapter_create_param *params) 17239 { 17240 struct osif_vdev_sync *vdev_sync; 17241 struct hdd_adapter *adapter; 17242 QDF_STATUS status; 17243 int errno; 17244 17245 QDF_BUG(rtnl_is_locked()); 17246 17247 errno = osif_vdev_sync_create(hdd_ctx->parent_dev, &vdev_sync); 17248 if (errno) 17249 return qdf_status_from_os_return(errno); 17250 17251 adapter = hdd_open_adapter(hdd_ctx, op_mode, iface_name, 17252 mac_addr_bytes, NET_NAME_UNKNOWN, true, 17253 params); 17254 if (!adapter) { 17255 status = QDF_STATUS_E_INVAL; 17256 goto destroy_sync; 17257 } 17258 17259 osif_vdev_sync_register(adapter->dev, vdev_sync); 17260 17261 return QDF_STATUS_SUCCESS; 17262 17263 destroy_sync: 17264 osif_vdev_sync_destroy(vdev_sync); 17265 17266 return status; 17267 } 17268 17269 #ifdef WLAN_OPEN_P2P_INTERFACE 17270 /** 17271 * hdd_open_p2p_interface - Open P2P interface 17272 * @hdd_ctx: HDD context 17273 * 17274 * Return: QDF_STATUS 17275 */ hdd_open_p2p_interface(struct hdd_context * hdd_ctx)17276 static QDF_STATUS hdd_open_p2p_interface(struct hdd_context *hdd_ctx) 17277 { 17278 QDF_STATUS status; 17279 bool p2p_dev_addr_admin; 17280 bool is_p2p_locally_administered = false; 17281 struct hdd_adapter_create_param params = {0}; 17282 17283 cfg_p2p_get_device_addr_admin(hdd_ctx->psoc, &p2p_dev_addr_admin); 17284 17285 if (p2p_dev_addr_admin) { 17286 if (hdd_ctx->num_provisioned_addr && 17287 !(hdd_ctx->provisioned_mac_addr[0].bytes[0] & 0x02)) { 17288 hdd_ctx->p2p_device_address = 17289 hdd_ctx->provisioned_mac_addr[0]; 17290 17291 /* 17292 * Generate the P2P Device Address. This consists of 17293 * the device's primary MAC address with the locally 17294 * administered bit set. 17295 */ 17296 17297 hdd_ctx->p2p_device_address.bytes[0] |= 0x02; 17298 is_p2p_locally_administered = true; 17299 } else if (!(hdd_ctx->derived_mac_addr[0].bytes[0] & 0x02)) { 17300 hdd_ctx->p2p_device_address = 17301 hdd_ctx->derived_mac_addr[0]; 17302 /* 17303 * Generate the P2P Device Address. This consists of 17304 * the device's primary MAC address with the locally 17305 * administered bit set. 17306 */ 17307 hdd_ctx->p2p_device_address.bytes[0] |= 0x02; 17308 is_p2p_locally_administered = true; 17309 } 17310 } 17311 if (!is_p2p_locally_administered) { 17312 uint8_t *p2p_dev_addr; 17313 17314 p2p_dev_addr = wlan_hdd_get_intf_addr(hdd_ctx, 17315 QDF_P2P_DEVICE_MODE); 17316 if (!p2p_dev_addr) { 17317 hdd_err("Failed to get MAC address for new p2p device"); 17318 return QDF_STATUS_E_INVAL; 17319 } 17320 17321 qdf_mem_copy(hdd_ctx->p2p_device_address.bytes, 17322 p2p_dev_addr, QDF_MAC_ADDR_SIZE); 17323 } 17324 17325 status = hdd_open_adapter_no_trans(hdd_ctx, QDF_P2P_DEVICE_MODE, 17326 "p2p%d", 17327 hdd_ctx->p2p_device_address.bytes, 17328 ¶ms); 17329 if (QDF_IS_STATUS_ERROR(status)) { 17330 if (!is_p2p_locally_administered) 17331 wlan_hdd_release_intf_addr(hdd_ctx, 17332 hdd_ctx->p2p_device_address.bytes); 17333 hdd_err("Failed to open p2p interface"); 17334 return QDF_STATUS_E_INVAL; 17335 } 17336 17337 return QDF_STATUS_SUCCESS; 17338 } 17339 #else hdd_open_p2p_interface(struct hdd_context * hdd_ctx)17340 static inline QDF_STATUS hdd_open_p2p_interface(struct hdd_context *hdd_ctx) 17341 { 17342 return QDF_STATUS_SUCCESS; 17343 } 17344 #endif 17345 hdd_open_ocb_interface(struct hdd_context * hdd_ctx)17346 static QDF_STATUS hdd_open_ocb_interface(struct hdd_context *hdd_ctx) 17347 { 17348 QDF_STATUS status; 17349 uint8_t *mac_addr; 17350 struct hdd_adapter_create_param params = {0}; 17351 17352 mac_addr = wlan_hdd_get_intf_addr(hdd_ctx, QDF_OCB_MODE); 17353 if (!mac_addr) 17354 return QDF_STATUS_E_INVAL; 17355 17356 status = hdd_open_adapter_no_trans(hdd_ctx, QDF_OCB_MODE, 17357 "wlanocb%d", mac_addr, 17358 ¶ms); 17359 if (QDF_IS_STATUS_ERROR(status)) { 17360 wlan_hdd_release_intf_addr(hdd_ctx, mac_addr); 17361 hdd_err("Failed to open 802.11p interface"); 17362 } 17363 17364 return status; 17365 } 17366 hdd_open_concurrent_interface(struct hdd_context * hdd_ctx)17367 static QDF_STATUS hdd_open_concurrent_interface(struct hdd_context *hdd_ctx) 17368 { 17369 QDF_STATUS status; 17370 const char *iface_name; 17371 uint8_t *mac_addr; 17372 struct hdd_adapter_create_param params = {0}; 17373 17374 if (qdf_str_eq(hdd_ctx->config->enable_concurrent_sta, "")) 17375 return QDF_STATUS_SUCCESS; 17376 17377 iface_name = hdd_ctx->config->enable_concurrent_sta; 17378 mac_addr = wlan_hdd_get_intf_addr(hdd_ctx, QDF_STA_MODE); 17379 if (!mac_addr) 17380 return QDF_STATUS_E_INVAL; 17381 17382 status = hdd_open_adapter_no_trans(hdd_ctx, QDF_STA_MODE, 17383 iface_name, mac_addr, 17384 ¶ms); 17385 if (QDF_IS_STATUS_ERROR(status)) { 17386 wlan_hdd_release_intf_addr(hdd_ctx, mac_addr); 17387 hdd_err("Failed to open concurrent station interface"); 17388 } 17389 17390 return status; 17391 } 17392 17393 #ifdef WLAN_HDD_MULTI_VDEV_SINGLE_NDEV 17394 static inline void hdd_adapter_open_set_max_active_links(struct hdd_adapter_create_param * params)17395 hdd_adapter_open_set_max_active_links(struct hdd_adapter_create_param *params) 17396 { 17397 if (params->is_add_virtual_iface || !params->is_ml_adapter) 17398 params->num_sessions = 1; 17399 else 17400 params->num_sessions = 2; 17401 } 17402 #else 17403 static inline void hdd_adapter_open_set_max_active_links(struct hdd_adapter_create_param * params)17404 hdd_adapter_open_set_max_active_links(struct hdd_adapter_create_param *params) 17405 { 17406 params->num_sessions = 1; 17407 } 17408 #endif 17409 17410 static QDF_STATUS hdd_open_adapters_for_mission_mode(struct hdd_context * hdd_ctx)17411 hdd_open_adapters_for_mission_mode(struct hdd_context *hdd_ctx) 17412 { 17413 enum dot11p_mode dot11p_mode; 17414 QDF_STATUS status; 17415 uint8_t *mac_addr; 17416 struct hdd_adapter_create_param params = {0}; 17417 bool eht_capab = 0; 17418 17419 ucfg_mlme_get_dot11p_mode(hdd_ctx->psoc, &dot11p_mode); 17420 ucfg_psoc_mlme_get_11be_capab(hdd_ctx->psoc, &eht_capab); 17421 17422 /* Create only 802.11p interface? */ 17423 if (dot11p_mode == CFG_11P_STANDALONE) 17424 return hdd_open_ocb_interface(hdd_ctx); 17425 17426 mac_addr = wlan_hdd_get_intf_addr(hdd_ctx, QDF_STA_MODE); 17427 if (!mac_addr) 17428 return QDF_STATUS_E_INVAL; 17429 17430 if (eht_capab) { 17431 params.is_ml_adapter = true; 17432 hdd_adapter_open_set_max_active_links(¶ms); 17433 } 17434 17435 status = hdd_open_adapter_no_trans(hdd_ctx, QDF_STA_MODE, 17436 "wlan%d", mac_addr, 17437 ¶ms); 17438 if (QDF_IS_STATUS_ERROR(status)) { 17439 wlan_hdd_release_intf_addr(hdd_ctx, mac_addr); 17440 return status; 17441 } 17442 17443 /* opening concurrent STA is best effort, continue on error */ 17444 hdd_open_concurrent_interface(hdd_ctx); 17445 17446 status = hdd_open_p2p_interface(hdd_ctx); 17447 if (status) 17448 goto err_close_adapters; 17449 17450 /* 17451 * Create separate interface (wifi-aware0) for NAN. All NAN commands 17452 * should go on this new interface. 17453 */ 17454 if (wlan_hdd_is_vdev_creation_allowed(hdd_ctx->psoc)) { 17455 qdf_mem_zero(¶ms, sizeof(params)); 17456 mac_addr = wlan_hdd_get_intf_addr(hdd_ctx, QDF_NAN_DISC_MODE); 17457 if (!mac_addr) 17458 goto err_close_adapters; 17459 17460 status = hdd_open_adapter_no_trans(hdd_ctx, QDF_NAN_DISC_MODE, 17461 "wifi-aware%d", mac_addr, 17462 ¶ms); 17463 if (status) { 17464 wlan_hdd_release_intf_addr(hdd_ctx, mac_addr); 17465 goto err_close_adapters; 17466 } 17467 } 17468 /* Open 802.11p Interface */ 17469 if (dot11p_mode == CFG_11P_CONCURRENT) { 17470 status = hdd_open_ocb_interface(hdd_ctx); 17471 if (QDF_IS_STATUS_ERROR(status)) 17472 goto err_close_adapters; 17473 } 17474 17475 if (eht_capab) 17476 hdd_wlan_register_mlo_interfaces(hdd_ctx); 17477 17478 return QDF_STATUS_SUCCESS; 17479 17480 err_close_adapters: 17481 hdd_close_all_adapters(hdd_ctx, true); 17482 17483 return status; 17484 } 17485 hdd_open_adapters_for_ftm_mode(struct hdd_context * hdd_ctx)17486 static QDF_STATUS hdd_open_adapters_for_ftm_mode(struct hdd_context *hdd_ctx) 17487 { 17488 QDF_STATUS status; 17489 uint8_t *mac_addr; 17490 struct hdd_adapter_create_param params = {0}; 17491 17492 mac_addr = wlan_hdd_get_intf_addr(hdd_ctx, QDF_FTM_MODE); 17493 if (!mac_addr) 17494 return QDF_STATUS_E_INVAL; 17495 17496 status = hdd_open_adapter_no_trans(hdd_ctx, QDF_FTM_MODE, 17497 "wlan%d", mac_addr, 17498 ¶ms); 17499 if (QDF_IS_STATUS_ERROR(status)) { 17500 wlan_hdd_release_intf_addr(hdd_ctx, mac_addr); 17501 return status; 17502 } 17503 17504 return QDF_STATUS_SUCCESS; 17505 } 17506 17507 static QDF_STATUS hdd_open_adapters_for_monitor_mode(struct hdd_context * hdd_ctx)17508 hdd_open_adapters_for_monitor_mode(struct hdd_context *hdd_ctx) 17509 { 17510 QDF_STATUS status; 17511 uint8_t *mac_addr; 17512 struct hdd_adapter_create_param params = {0}; 17513 17514 mac_addr = wlan_hdd_get_intf_addr(hdd_ctx, QDF_MONITOR_MODE); 17515 if (!mac_addr) 17516 return QDF_STATUS_E_INVAL; 17517 17518 status = hdd_open_adapter_no_trans(hdd_ctx, QDF_MONITOR_MODE, 17519 "wlan%d", mac_addr, 17520 ¶ms); 17521 if (QDF_IS_STATUS_ERROR(status)) { 17522 wlan_hdd_release_intf_addr(hdd_ctx, mac_addr); 17523 return status; 17524 } 17525 17526 return QDF_STATUS_SUCCESS; 17527 } 17528 hdd_open_adapters_for_epping_mode(struct hdd_context * hdd_ctx)17529 static QDF_STATUS hdd_open_adapters_for_epping_mode(struct hdd_context *hdd_ctx) 17530 { 17531 epping_enable_adapter(); 17532 return QDF_STATUS_SUCCESS; 17533 } 17534 17535 typedef QDF_STATUS (*hdd_open_mode_handler)(struct hdd_context *hdd_ctx); 17536 17537 static const hdd_open_mode_handler 17538 hdd_open_mode_handlers[QDF_GLOBAL_MAX_MODE] = { 17539 [QDF_GLOBAL_MISSION_MODE] = hdd_open_adapters_for_mission_mode, 17540 [QDF_GLOBAL_FTM_MODE] = hdd_open_adapters_for_ftm_mode, 17541 [QDF_GLOBAL_MONITOR_MODE] = hdd_open_adapters_for_monitor_mode, 17542 [QDF_GLOBAL_EPPING_MODE] = hdd_open_adapters_for_epping_mode, 17543 }; 17544 hdd_open_adapters_for_mode(struct hdd_context * hdd_ctx,enum QDF_GLOBAL_MODE driver_mode)17545 static QDF_STATUS hdd_open_adapters_for_mode(struct hdd_context *hdd_ctx, 17546 enum QDF_GLOBAL_MODE driver_mode) 17547 { 17548 QDF_STATUS status; 17549 17550 if (driver_mode < 0 || 17551 driver_mode >= QDF_GLOBAL_MAX_MODE || 17552 !hdd_open_mode_handlers[driver_mode]) { 17553 hdd_err("Driver mode %d not supported", driver_mode); 17554 return -ENOTSUPP; 17555 } 17556 17557 hdd_hold_rtnl_lock(); 17558 status = hdd_open_mode_handlers[driver_mode](hdd_ctx); 17559 hdd_release_rtnl_lock(); 17560 17561 return status; 17562 } 17563 hdd_wlan_startup(struct hdd_context * hdd_ctx)17564 int hdd_wlan_startup(struct hdd_context *hdd_ctx) 17565 { 17566 QDF_STATUS status; 17567 int errno; 17568 bool is_imps_enabled; 17569 17570 hdd_enter(); 17571 17572 qdf_nbuf_init_replenish_timer(); 17573 17574 status = wlan_hdd_cache_chann_mutex_create(hdd_ctx); 17575 if (QDF_IS_STATUS_ERROR(status)) 17576 return qdf_status_to_os_return(status); 17577 17578 #ifdef FEATURE_WLAN_CH_AVOID 17579 mutex_init(&hdd_ctx->avoid_freq_lock); 17580 #endif 17581 17582 osif_request_manager_init(); 17583 hdd_driver_memdump_init(); 17584 17585 errno = hdd_init_regulatory_update_event(hdd_ctx); 17586 if (errno) { 17587 hdd_err("Failed to initialize regulatory update event; errno:%d", 17588 errno); 17589 goto memdump_deinit; 17590 } 17591 17592 errno = hdd_wlan_start_modules(hdd_ctx, false); 17593 if (errno) { 17594 hdd_err("Failed to start modules; errno:%d", errno); 17595 goto memdump_deinit; 17596 } 17597 17598 if (hdd_get_conparam() == QDF_GLOBAL_EPPING_MODE) 17599 return 0; 17600 17601 wlan_hdd_update_wiphy(hdd_ctx); 17602 17603 hdd_ctx->mac_handle = cds_get_context(QDF_MODULE_ID_SME); 17604 if (!hdd_ctx->mac_handle) 17605 goto stop_modules; 17606 17607 errno = hdd_wiphy_init(hdd_ctx); 17608 if (errno) { 17609 hdd_err("Failed to initialize wiphy; errno:%d", errno); 17610 goto stop_modules; 17611 } 17612 17613 errno = hdd_initialize_mac_address(hdd_ctx); 17614 if (errno) { 17615 hdd_err("MAC initializtion failed: %d", errno); 17616 goto unregister_wiphy; 17617 } 17618 17619 errno = register_netdevice_notifier(&hdd_netdev_notifier); 17620 if (errno) { 17621 hdd_err("register_netdevice_notifier failed; errno:%d", errno); 17622 goto unregister_wiphy; 17623 } 17624 17625 wlan_hdd_update_11n_mode(hdd_ctx); 17626 17627 hdd_lpass_notify_wlan_version(hdd_ctx); 17628 17629 status = wlansap_global_init(); 17630 if (QDF_IS_STATUS_ERROR(status)) 17631 goto unregister_notifiers; 17632 17633 ucfg_mlme_is_imps_enabled(hdd_ctx->psoc, &is_imps_enabled); 17634 hdd_set_idle_ps_config(hdd_ctx, is_imps_enabled); 17635 hdd_debugfs_mws_coex_info_init(hdd_ctx); 17636 hdd_debugfs_ini_config_init(hdd_ctx); 17637 wlan_hdd_debugfs_unit_test_host_create(hdd_ctx); 17638 wlan_hdd_create_mib_stats_lock(); 17639 wlan_cfg80211_init_interop_issues_ap(hdd_ctx->pdev); 17640 17641 hdd_exit(); 17642 17643 return 0; 17644 17645 unregister_notifiers: 17646 unregister_netdevice_notifier(&hdd_netdev_notifier); 17647 17648 unregister_wiphy: 17649 qdf_dp_trace_deinit(); 17650 wiphy_unregister(hdd_ctx->wiphy); 17651 17652 stop_modules: 17653 hdd_wlan_stop_modules(hdd_ctx, false); 17654 17655 memdump_deinit: 17656 hdd_driver_memdump_deinit(); 17657 osif_request_manager_deinit(); 17658 qdf_nbuf_deinit_replenish_timer(); 17659 17660 if (cds_is_fw_down()) 17661 hdd_err("Not setting the complete event as fw is down"); 17662 else 17663 hdd_start_complete(errno); 17664 17665 hdd_exit(); 17666 17667 return errno; 17668 } 17669 hdd_psoc_create_vdevs(struct hdd_context * hdd_ctx)17670 QDF_STATUS hdd_psoc_create_vdevs(struct hdd_context *hdd_ctx) 17671 { 17672 enum QDF_GLOBAL_MODE driver_mode = hdd_get_conparam(); 17673 QDF_STATUS status; 17674 17675 status = hdd_open_adapters_for_mode(hdd_ctx, driver_mode); 17676 if (QDF_IS_STATUS_ERROR(status)) { 17677 hdd_err("Failed to create vdevs; status:%d", status); 17678 return status; 17679 } 17680 17681 ucfg_dp_try_set_rps_cpu_mask(hdd_ctx->psoc); 17682 17683 if (driver_mode != QDF_GLOBAL_FTM_MODE && 17684 driver_mode != QDF_GLOBAL_EPPING_MODE) 17685 hdd_psoc_idle_timer_start(hdd_ctx); 17686 17687 return QDF_STATUS_SUCCESS; 17688 } 17689 17690 /** 17691 * hdd_wlan_update_target_info() - update target type info 17692 * @hdd_ctx: HDD context 17693 * @context: hif context 17694 * 17695 * Update target info received from firmware in hdd context 17696 * Return:None 17697 */ 17698 hdd_wlan_update_target_info(struct hdd_context * hdd_ctx,void * context)17699 void hdd_wlan_update_target_info(struct hdd_context *hdd_ctx, void *context) 17700 { 17701 struct hif_target_info *tgt_info = hif_get_target_info_handle(context); 17702 17703 if (!tgt_info) { 17704 hdd_err("Target info is Null"); 17705 return; 17706 } 17707 17708 hdd_ctx->target_type = tgt_info->target_type; 17709 } 17710 17711 #ifdef WLAN_FEATURE_MOTION_DETECTION 17712 /** 17713 * hdd_md_host_evt_cb - Callback for Motion Detection Event 17714 * @ctx: HDD context 17715 * @event: motion detect event 17716 * 17717 * Callback for Motion Detection Event. Re-enables Motion 17718 * Detection again upon event 17719 * 17720 * Return: QDF_STATUS QDF_STATUS_SUCCESS on Success and 17721 * QDF_STATUS_E_FAILURE on failure 17722 */ hdd_md_host_evt_cb(void * ctx,struct sir_md_evt * event)17723 QDF_STATUS hdd_md_host_evt_cb(void *ctx, struct sir_md_evt *event) 17724 { 17725 struct hdd_adapter *adapter; 17726 struct hdd_context *hdd_ctx; 17727 struct sme_motion_det_en motion_det; 17728 struct wlan_hdd_link_info *link_info; 17729 17730 if (!ctx || !event) 17731 return QDF_STATUS_E_INVAL; 17732 17733 hdd_ctx = (struct hdd_context *)ctx; 17734 if (wlan_hdd_validate_context(hdd_ctx)) 17735 return QDF_STATUS_E_INVAL; 17736 17737 link_info = hdd_get_link_info_by_vdev(hdd_ctx, event->vdev_id); 17738 if (!link_info || 17739 WLAN_HDD_ADAPTER_MAGIC != link_info->adapter->magic) { 17740 hdd_err("Invalid adapter or adapter has invalid magic"); 17741 return QDF_STATUS_E_INVAL; 17742 } 17743 17744 adapter = link_info->adapter; 17745 /* When motion is detected, reset the motion_det_in_progress flag */ 17746 if (event->status) 17747 adapter->motion_det_in_progress = false; 17748 17749 hdd_debug("Motion Detection CB vdev_id=%u, status=%u", 17750 event->vdev_id, event->status); 17751 17752 if (adapter->motion_detection_mode) { 17753 motion_det.vdev_id = event->vdev_id; 17754 motion_det.enable = 1; 17755 hdd_debug("Motion Detect CB -> Enable Motion Detection again"); 17756 sme_motion_det_enable(hdd_ctx->mac_handle, &motion_det); 17757 } 17758 17759 return QDF_STATUS_SUCCESS; 17760 } 17761 17762 /** 17763 * hdd_md_bl_evt_cb - Callback for Motion Detection Baseline Event 17764 * @ctx: HDD context 17765 * @event: motion detect baseline event 17766 * 17767 * Callback for Motion Detection Baseline completion 17768 * 17769 * Return: QDF_STATUS QDF_STATUS_SUCCESS on Success and 17770 * QDF_STATUS_E_FAILURE on failure 17771 */ hdd_md_bl_evt_cb(void * ctx,struct sir_md_bl_evt * event)17772 QDF_STATUS hdd_md_bl_evt_cb(void *ctx, struct sir_md_bl_evt *event) 17773 { 17774 struct hdd_context *hdd_ctx; 17775 struct wlan_hdd_link_info *link_info; 17776 17777 if (!ctx || !event) 17778 return QDF_STATUS_E_INVAL; 17779 17780 hdd_ctx = (struct hdd_context *)ctx; 17781 if (wlan_hdd_validate_context(hdd_ctx)) 17782 return QDF_STATUS_E_INVAL; 17783 17784 link_info = hdd_get_link_info_by_vdev(hdd_ctx, event->vdev_id); 17785 if (!link_info || 17786 WLAN_HDD_ADAPTER_MAGIC != link_info->adapter->magic) { 17787 hdd_err("Invalid adapter or adapter has invalid magic"); 17788 return QDF_STATUS_E_INVAL; 17789 } 17790 17791 hdd_debug("Motion Detection Baseline CB vdev id=%u, baseline val = %d", 17792 event->vdev_id, event->bl_baseline_value); 17793 17794 link_info->adapter->motion_det_baseline_value = 17795 event->bl_baseline_value; 17796 17797 return QDF_STATUS_SUCCESS; 17798 } 17799 #endif /* WLAN_FEATURE_MOTION_DETECTION */ 17800 hdd_ssr_on_pagefault_cb(struct hdd_context * hdd_ctx)17801 static QDF_STATUS hdd_ssr_on_pagefault_cb(struct hdd_context *hdd_ctx) 17802 { 17803 uint32_t ssr_frequency_on_pagefault; 17804 qdf_time_t curr_time, ssr_threshold; 17805 17806 hdd_enter(); 17807 17808 if (!hdd_ctx) 17809 return QDF_STATUS_E_NULL_VALUE; 17810 17811 ssr_frequency_on_pagefault = 17812 ucfg_pmo_get_ssr_frequency_on_pagefault(hdd_ctx->psoc); 17813 17814 curr_time = qdf_get_system_uptime(); 17815 ssr_threshold = qdf_system_msecs_to_ticks(ssr_frequency_on_pagefault); 17816 17817 if (!hdd_ctx->last_pagefault_ssr_time || 17818 (curr_time - hdd_ctx->last_pagefault_ssr_time) >= ssr_threshold) { 17819 hdd_info("curr_time %lu last_pagefault_ssr_time %lu ssr_frequency %lu", 17820 curr_time, hdd_ctx->last_pagefault_ssr_time, 17821 ssr_threshold); 17822 hdd_ctx->last_pagefault_ssr_time = curr_time; 17823 cds_trigger_recovery(QDF_HOST_WAKEUP_REASON_PAGEFAULT); 17824 17825 return QDF_STATUS_SUCCESS; 17826 } 17827 17828 return QDF_STATUS_E_AGAIN; 17829 } 17830 17831 #define FW_PAGE_FAULT_IDX QCA_NL80211_VENDOR_SUBCMD_FW_PAGE_FAULT_REPORT_INDEX hdd_send_pagefault_report_to_user(struct hdd_context * hdd_ctx,void * buf,uint32_t buf_len)17832 static QDF_STATUS hdd_send_pagefault_report_to_user(struct hdd_context *hdd_ctx, 17833 void *buf, uint32_t buf_len) 17834 { 17835 struct sk_buff *event_buf; 17836 int flags = cds_get_gfp_flags(); 17837 uint8_t *ev_data = buf; 17838 uint16_t event_len = NLMSG_HDRLEN + buf_len; 17839 17840 event_buf = wlan_cfg80211_vendor_event_alloc(hdd_ctx->wiphy, NULL, 17841 event_len, 17842 FW_PAGE_FAULT_IDX, flags); 17843 if (!event_buf) { 17844 hdd_err("wlan_cfg80211_vendor_event_alloc failed"); 17845 return QDF_STATUS_E_NOMEM; 17846 } 17847 17848 if (nla_put(event_buf, QCA_WLAN_VENDOR_ATTR_FW_PAGE_FAULT_REPORT_DATA, 17849 buf_len, ev_data)) { 17850 hdd_debug("Failed to fill pagefault blob data"); 17851 wlan_cfg80211_vendor_free_skb(event_buf); 17852 return QDF_STATUS_E_FAILURE; 17853 } 17854 17855 wlan_cfg80211_vendor_event(event_buf, flags); 17856 return QDF_STATUS_SUCCESS; 17857 } 17858 hdd_pagefault_action_cb(void * buf,uint32_t buf_len)17859 static QDF_STATUS hdd_pagefault_action_cb(void *buf, uint32_t buf_len) 17860 { 17861 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 17862 17863 if (!hdd_ctx) 17864 return QDF_STATUS_E_NULL_VALUE; 17865 17866 if (wlan_pmo_enable_ssr_on_page_fault(hdd_ctx->psoc)) 17867 return hdd_ssr_on_pagefault_cb(hdd_ctx); 17868 17869 return hdd_send_pagefault_report_to_user(hdd_ctx, buf, buf_len); 17870 } 17871 17872 /** 17873 * hdd_register_cb - Register HDD callbacks. 17874 * @hdd_ctx: HDD context 17875 * 17876 * Register the HDD callbacks to CDS/SME. 17877 * 17878 * Return: 0 for success or Error code for failure 17879 */ hdd_register_cb(struct hdd_context * hdd_ctx)17880 int hdd_register_cb(struct hdd_context *hdd_ctx) 17881 { 17882 QDF_STATUS status; 17883 int ret = 0; 17884 mac_handle_t mac_handle; 17885 17886 hdd_enter(); 17887 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) { 17888 hdd_err("in ftm mode, no need to register callbacks"); 17889 return ret; 17890 } 17891 17892 mac_handle = hdd_ctx->mac_handle; 17893 17894 sme_register_oem_data_rsp_callback(mac_handle, 17895 hdd_send_oem_data_rsp_msg); 17896 17897 sme_register_mgmt_frame_ind_callback(mac_handle, 17898 hdd_indicate_mgmt_frame); 17899 sme_set_tsfcb(mac_handle, hdd_get_tsf_cb, hdd_ctx); 17900 sme_stats_ext_register_callback(mac_handle, 17901 wlan_hdd_cfg80211_stats_ext_callback); 17902 17903 sme_ext_scan_register_callback(mac_handle, 17904 wlan_hdd_cfg80211_extscan_callback); 17905 sme_stats_ext2_register_callback(mac_handle, 17906 wlan_hdd_cfg80211_stats_ext2_callback); 17907 17908 sme_multi_client_ll_rsp_register_callback(mac_handle, 17909 hdd_latency_level_event_handler_cb); 17910 17911 sme_set_rssi_threshold_breached_cb(mac_handle, 17912 hdd_rssi_threshold_breached); 17913 17914 sme_set_link_layer_stats_ind_cb(mac_handle, 17915 wlan_hdd_cfg80211_link_layer_stats_callback); 17916 17917 sme_rso_cmd_status_cb(mac_handle, wlan_hdd_rso_cmd_status_cb); 17918 17919 sme_set_link_layer_ext_cb(mac_handle, 17920 wlan_hdd_cfg80211_link_layer_stats_ext_callback); 17921 sme_update_hidden_ssid_status_cb(mac_handle, 17922 hdd_hidden_ssid_enable_roaming); 17923 17924 status = sme_set_lost_link_info_cb(mac_handle, 17925 hdd_lost_link_info_cb); 17926 17927 wlan_hdd_register_cp_stats_cb(hdd_ctx); 17928 hdd_dcs_register_cb(hdd_ctx); 17929 17930 hdd_thermal_register_callbacks(hdd_ctx); 17931 /* print error and not block the startup process */ 17932 if (!QDF_IS_STATUS_SUCCESS(status)) 17933 hdd_err("set lost link info callback failed"); 17934 17935 ret = hdd_register_data_stall_detect_cb(); 17936 if (ret) { 17937 hdd_err("Register data stall detect detect callback failed."); 17938 return ret; 17939 } 17940 17941 wlan_hdd_dcc_register_for_dcc_stats_event(hdd_ctx); 17942 17943 sme_register_set_connection_info_cb(mac_handle, 17944 hdd_set_connection_in_progress, 17945 hdd_is_connection_in_progress); 17946 17947 status = sme_set_bt_activity_info_cb(mac_handle, 17948 hdd_bt_activity_cb); 17949 if (!QDF_IS_STATUS_SUCCESS(status)) 17950 hdd_err("set bt activity info callback failed"); 17951 17952 status = sme_register_tx_queue_cb(mac_handle, 17953 hdd_tx_queue_cb); 17954 if (!QDF_IS_STATUS_SUCCESS(status)) 17955 hdd_err("Register tx queue callback failed"); 17956 17957 #ifdef WLAN_FEATURE_MOTION_DETECTION 17958 sme_set_md_host_evt_cb(mac_handle, hdd_md_host_evt_cb, (void *)hdd_ctx); 17959 sme_set_md_bl_evt_cb(mac_handle, hdd_md_bl_evt_cb, (void *)hdd_ctx); 17960 #endif /* WLAN_FEATURE_MOTION_DETECTION */ 17961 17962 mac_register_session_open_close_cb(hdd_ctx->mac_handle, 17963 hdd_sme_close_session_callback, 17964 hdd_common_roam_callback); 17965 17966 sme_set_roam_scan_ch_event_cb(mac_handle, hdd_get_roam_scan_ch_cb); 17967 status = sme_set_monitor_mode_cb(mac_handle, 17968 hdd_sme_monitor_mode_callback); 17969 if (QDF_IS_STATUS_ERROR(status)) 17970 hdd_err_rl("Register monitor mode callback failed"); 17971 17972 status = sme_set_beacon_latency_event_cb(mac_handle, 17973 hdd_beacon_latency_event_cb); 17974 if (QDF_IS_STATUS_ERROR(status)) 17975 hdd_err_rl("Register beacon latency event callback failed"); 17976 17977 sme_async_oem_event_init(mac_handle, 17978 hdd_oem_event_async_cb); 17979 17980 sme_register_pagefault_cb(mac_handle, hdd_pagefault_action_cb); 17981 17982 hdd_exit(); 17983 17984 return ret; 17985 } 17986 17987 /** 17988 * hdd_deregister_cb() - De-Register HDD callbacks. 17989 * @hdd_ctx: HDD context 17990 * 17991 * De-Register the HDD callbacks to CDS/SME. 17992 * 17993 * Return: void 17994 */ hdd_deregister_cb(struct hdd_context * hdd_ctx)17995 void hdd_deregister_cb(struct hdd_context *hdd_ctx) 17996 { 17997 QDF_STATUS status; 17998 int ret; 17999 mac_handle_t mac_handle; 18000 18001 hdd_enter(); 18002 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) { 18003 hdd_err("in ftm mode, no need to deregister callbacks"); 18004 return; 18005 } 18006 18007 mac_handle = hdd_ctx->mac_handle; 18008 18009 sme_deregister_ssr_on_pagefault_cb(mac_handle); 18010 18011 sme_async_oem_event_deinit(mac_handle); 18012 18013 sme_deregister_tx_queue_cb(mac_handle); 18014 18015 sme_reset_link_layer_stats_ind_cb(mac_handle); 18016 sme_reset_rssi_threshold_breached_cb(mac_handle); 18017 18018 sme_stats_ext_deregister_callback(mac_handle); 18019 18020 status = sme_reset_tsfcb(mac_handle); 18021 if (!QDF_IS_STATUS_SUCCESS(status)) 18022 hdd_err("Failed to de-register tsfcb the callback:%d", 18023 status); 18024 18025 ret = hdd_deregister_data_stall_detect_cb(); 18026 if (ret) 18027 hdd_err("Failed to de-register data stall detect event callback"); 18028 hdd_thermal_unregister_callbacks(hdd_ctx); 18029 sme_deregister_oem_data_rsp_callback(mac_handle); 18030 sme_multi_client_ll_rsp_deregister_callback(mac_handle); 18031 18032 hdd_exit(); 18033 } 18034 18035 /** 18036 * hdd_softap_sta_deauth() - handle deauth req from HDD 18037 * @adapter: Pointer to the HDD adapter 18038 * @param: Params to the operation 18039 * 18040 * This to take counter measure to handle deauth req from HDD 18041 * 18042 * Return: None 18043 */ hdd_softap_sta_deauth(struct hdd_adapter * adapter,struct csr_del_sta_params * param)18044 QDF_STATUS hdd_softap_sta_deauth(struct hdd_adapter *adapter, 18045 struct csr_del_sta_params *param) 18046 { 18047 QDF_STATUS qdf_status = QDF_STATUS_E_FAULT; 18048 struct hdd_context *hdd_ctx; 18049 bool is_sap_bcast_deauth_enabled = false; 18050 18051 hdd_ctx = WLAN_HDD_GET_CTX(adapter); 18052 if (!hdd_ctx) { 18053 hdd_err("hdd_ctx is NULL"); 18054 return QDF_STATUS_E_INVAL; 18055 } 18056 18057 ucfg_mlme_get_sap_bcast_deauth_enabled(hdd_ctx->psoc, 18058 &is_sap_bcast_deauth_enabled); 18059 18060 hdd_enter(); 18061 18062 hdd_debug("sap_bcast_deauth_enabled %d", is_sap_bcast_deauth_enabled); 18063 /* Ignore request to deauth bcmc station */ 18064 if (!is_sap_bcast_deauth_enabled) 18065 if (param->peerMacAddr.bytes[0] & 0x1) 18066 return qdf_status; 18067 18068 qdf_status = 18069 wlansap_deauth_sta(WLAN_HDD_GET_SAP_CTX_PTR(adapter->deflink), 18070 param); 18071 18072 hdd_exit(); 18073 return qdf_status; 18074 } 18075 18076 /** 18077 * hdd_softap_sta_disassoc() - take counter measure to handle deauth req from HDD 18078 * @adapter: Pointer to the HDD 18079 * @param: pointer to station deletion parameters 18080 * 18081 * This to take counter measure to handle deauth req from HDD 18082 * 18083 * Return: None 18084 */ hdd_softap_sta_disassoc(struct hdd_adapter * adapter,struct csr_del_sta_params * param)18085 void hdd_softap_sta_disassoc(struct hdd_adapter *adapter, 18086 struct csr_del_sta_params *param) 18087 { 18088 hdd_enter(); 18089 18090 /* Ignore request to disassoc bcmc station */ 18091 if (param->peerMacAddr.bytes[0] & 0x1) 18092 return; 18093 18094 wlansap_disassoc_sta(WLAN_HDD_GET_SAP_CTX_PTR(adapter->deflink), 18095 param); 18096 } 18097 18098 void wlan_hdd_set_roaming_state(struct wlan_hdd_link_info * cur_link_info,enum wlan_cm_rso_control_requestor rso_op_requestor,bool enab_roam)18099 wlan_hdd_set_roaming_state(struct wlan_hdd_link_info *cur_link_info, 18100 enum wlan_cm_rso_control_requestor rso_op_requestor, 18101 bool enab_roam) 18102 { 18103 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(cur_link_info->adapter); 18104 struct hdd_adapter *adapter = NULL, *next_adapter = NULL; 18105 wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_DISABLE_ROAMING; 18106 uint8_t vdev_id, cur_vdev_id = cur_link_info->vdev_id; 18107 struct wlan_hdd_link_info *link_info; 18108 18109 if (!policy_mgr_is_sta_active_connection_exists(hdd_ctx->psoc)) 18110 return; 18111 18112 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 18113 dbgid) { 18114 hdd_adapter_for_each_active_link_info(adapter, link_info) { 18115 vdev_id = link_info->vdev_id; 18116 if (cur_vdev_id != link_info->vdev_id && 18117 adapter->device_mode == QDF_STA_MODE && 18118 hdd_cm_is_vdev_associated(link_info)) { 18119 if (enab_roam) { 18120 hdd_debug("%d Enable roaming", vdev_id); 18121 sme_start_roaming(hdd_ctx->mac_handle, 18122 vdev_id, 18123 REASON_DRIVER_ENABLED, 18124 rso_op_requestor); 18125 } else { 18126 hdd_debug("%d Disable roaming", 18127 vdev_id); 18128 sme_stop_roaming(hdd_ctx->mac_handle, 18129 vdev_id, 18130 REASON_DRIVER_DISABLED, 18131 rso_op_requestor); 18132 } 18133 } 18134 } 18135 hdd_adapter_dev_put_debug(adapter, dbgid); 18136 } 18137 } 18138 18139 /** 18140 * nl_srv_bcast_svc() - Wrapper function to send bcast msgs to SVC mcast group 18141 * @skb: sk buffer pointer 18142 * 18143 * Sends the bcast message to SVC multicast group with generic nl socket 18144 * if CNSS_GENL is enabled. Else, use the legacy netlink socket to send. 18145 * 18146 * Return: None 18147 */ nl_srv_bcast_svc(struct sk_buff * skb)18148 static void nl_srv_bcast_svc(struct sk_buff *skb) 18149 { 18150 #ifdef CNSS_GENL 18151 nl_srv_bcast(skb, CLD80211_MCGRP_SVC_MSGS, WLAN_NL_MSG_SVC); 18152 #else 18153 nl_srv_bcast(skb); 18154 #endif 18155 } 18156 wlan_hdd_send_svc_nlink_msg(int radio,int type,void * data,int len)18157 void wlan_hdd_send_svc_nlink_msg(int radio, int type, void *data, int len) 18158 { 18159 struct sk_buff *skb; 18160 struct nlmsghdr *nlh; 18161 tAniMsgHdr *ani_hdr; 18162 void *nl_data = NULL; 18163 int flags = GFP_KERNEL; 18164 struct radio_index_tlv *radio_info; 18165 int tlv_len; 18166 18167 if (in_interrupt() || irqs_disabled() || in_atomic()) 18168 flags = GFP_ATOMIC; 18169 18170 skb = alloc_skb(NLMSG_SPACE(WLAN_NL_MAX_PAYLOAD), flags); 18171 18172 if (!skb) 18173 return; 18174 18175 nlh = (struct nlmsghdr *)skb->data; 18176 nlh->nlmsg_pid = 0; /* from kernel */ 18177 nlh->nlmsg_flags = 0; 18178 nlh->nlmsg_seq = 0; 18179 nlh->nlmsg_type = WLAN_NL_MSG_SVC; 18180 18181 ani_hdr = NLMSG_DATA(nlh); 18182 ani_hdr->type = type; 18183 18184 switch (type) { 18185 case WLAN_SVC_FW_CRASHED_IND: 18186 case WLAN_SVC_FW_SHUTDOWN_IND: 18187 case WLAN_SVC_LTE_COEX_IND: 18188 case WLAN_SVC_WLAN_AUTO_SHUTDOWN_IND: 18189 case WLAN_SVC_WLAN_AUTO_SHUTDOWN_CANCEL_IND: 18190 ani_hdr->length = 0; 18191 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr))); 18192 break; 18193 case WLAN_SVC_WLAN_STATUS_IND: 18194 case WLAN_SVC_WLAN_VERSION_IND: 18195 case WLAN_SVC_DFS_CAC_START_IND: 18196 case WLAN_SVC_DFS_CAC_END_IND: 18197 case WLAN_SVC_DFS_RADAR_DETECT_IND: 18198 case WLAN_SVC_DFS_ALL_CHANNEL_UNAVAIL_IND: 18199 case WLAN_SVC_WLAN_TP_IND: 18200 case WLAN_SVC_WLAN_TP_TX_IND: 18201 case WLAN_SVC_RPS_ENABLE_IND: 18202 case WLAN_SVC_CORE_MINFREQ: 18203 ani_hdr->length = len; 18204 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr) + len)); 18205 nl_data = (char *)ani_hdr + sizeof(tAniMsgHdr); 18206 memcpy(nl_data, data, len); 18207 break; 18208 18209 default: 18210 hdd_err("WLAN SVC: Attempt to send unknown nlink message %d", 18211 type); 18212 kfree_skb(skb); 18213 return; 18214 } 18215 18216 /* 18217 * Add radio index at the end of the svc event in TLV format 18218 * to maintain the backward compatibility with userspace 18219 * applications. 18220 */ 18221 18222 tlv_len = 0; 18223 18224 if ((sizeof(*ani_hdr) + len + sizeof(struct radio_index_tlv)) 18225 < WLAN_NL_MAX_PAYLOAD) { 18226 radio_info = (struct radio_index_tlv *)((char *) ani_hdr + 18227 sizeof(*ani_hdr) + len); 18228 radio_info->type = (unsigned short) WLAN_SVC_WLAN_RADIO_INDEX; 18229 radio_info->length = (unsigned short) sizeof(radio_info->radio); 18230 radio_info->radio = radio; 18231 tlv_len = sizeof(*radio_info); 18232 hdd_debug("Added radio index tlv - radio index %d", 18233 radio_info->radio); 18234 } 18235 18236 nlh->nlmsg_len += tlv_len; 18237 skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr) + len + tlv_len)); 18238 18239 nl_srv_bcast_svc(skb); 18240 } 18241 18242 #ifdef FEATURE_WLAN_AUTO_SHUTDOWN wlan_hdd_auto_shutdown_cb(void)18243 void wlan_hdd_auto_shutdown_cb(void) 18244 { 18245 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 18246 18247 if (!hdd_ctx) 18248 return; 18249 18250 hdd_debug("Wlan Idle. Sending Shutdown event.."); 18251 wlan_hdd_send_svc_nlink_msg(hdd_ctx->radio_index, 18252 WLAN_SVC_WLAN_AUTO_SHUTDOWN_IND, NULL, 0); 18253 } 18254 wlan_hdd_auto_shutdown_enable(struct hdd_context * hdd_ctx,bool enable)18255 void wlan_hdd_auto_shutdown_enable(struct hdd_context *hdd_ctx, bool enable) 18256 { 18257 struct hdd_adapter *adapter, *next_adapter = NULL; 18258 bool ap_connected = false, sta_connected = false; 18259 mac_handle_t mac_handle; 18260 struct wlan_hdd_link_info *link_info; 18261 struct hdd_ap_ctx *ap_ctx; 18262 wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_AUTO_SHUTDOWN_ENABLE; 18263 18264 mac_handle = hdd_ctx->mac_handle; 18265 if (!mac_handle) 18266 return; 18267 18268 if (hdd_ctx->config->wlan_auto_shutdown == 0) 18269 return; 18270 18271 if (enable == false) { 18272 if (sme_set_auto_shutdown_timer(mac_handle, 0) != 18273 QDF_STATUS_SUCCESS) { 18274 hdd_err("Failed to stop wlan auto shutdown timer"); 18275 } 18276 wlan_hdd_send_svc_nlink_msg(hdd_ctx->radio_index, 18277 WLAN_SVC_WLAN_AUTO_SHUTDOWN_CANCEL_IND, NULL, 0); 18278 return; 18279 } 18280 18281 /* To enable shutdown timer check conncurrency */ 18282 if (!policy_mgr_concurrent_open_sessions_running(hdd_ctx->psoc)) 18283 goto start_timer; 18284 18285 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, 18286 next_adapter, dbgid) { 18287 hdd_adapter_for_each_active_link_info(adapter, link_info) { 18288 if (adapter->device_mode == QDF_STA_MODE && 18289 hdd_cm_is_vdev_associated(link_info)) { 18290 sta_connected = true; 18291 hdd_adapter_dev_put_debug(adapter, dbgid); 18292 if (next_adapter) 18293 hdd_adapter_dev_put_debug(next_adapter, 18294 dbgid); 18295 break; 18296 } 18297 18298 if (adapter->device_mode == QDF_SAP_MODE) { 18299 ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(link_info); 18300 if (ap_ctx->ap_active == true) { 18301 ap_connected = true; 18302 hdd_adapter_dev_put_debug(adapter, 18303 dbgid); 18304 if (next_adapter) 18305 hdd_adapter_dev_put_debug( 18306 next_adapter, 18307 dbgid); 18308 break; 18309 } 18310 } 18311 } 18312 hdd_adapter_dev_put_debug(adapter, dbgid); 18313 } 18314 18315 start_timer: 18316 if (ap_connected == true || sta_connected == true) { 18317 hdd_debug("CC Session active. Shutdown timer not enabled"); 18318 return; 18319 } 18320 18321 if (sme_set_auto_shutdown_timer(mac_handle, 18322 hdd_ctx->config->wlan_auto_shutdown) 18323 != QDF_STATUS_SUCCESS) 18324 hdd_err("Failed to start wlan auto shutdown timer"); 18325 else 18326 hdd_info("Auto Shutdown timer for %d seconds enabled", 18327 hdd_ctx->config->wlan_auto_shutdown); 18328 } 18329 #endif 18330 18331 struct hdd_adapter * hdd_get_con_sap_adapter(struct hdd_adapter * this_sap_adapter,bool check_start_bss)18332 hdd_get_con_sap_adapter(struct hdd_adapter *this_sap_adapter, 18333 bool check_start_bss) 18334 { 18335 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(this_sap_adapter); 18336 struct hdd_adapter *adapter, *next_adapter = NULL; 18337 wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_GET_CON_SAP_ADAPTER; 18338 struct wlan_hdd_link_info *link_info; 18339 18340 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 18341 dbgid) { 18342 if ((adapter->device_mode == QDF_SAP_MODE || 18343 adapter->device_mode == QDF_P2P_GO_MODE) && 18344 adapter != this_sap_adapter) { 18345 hdd_adapter_for_each_active_link_info(adapter, 18346 link_info) { 18347 if (!check_start_bss) { 18348 hdd_adapter_dev_put_debug(adapter, 18349 dbgid); 18350 if (next_adapter) 18351 hdd_adapter_dev_put_debug( 18352 next_adapter, 18353 dbgid); 18354 return adapter; 18355 } 18356 if (test_bit(SOFTAP_BSS_STARTED, 18357 &link_info->link_flags)) { 18358 hdd_adapter_dev_put_debug(adapter, 18359 dbgid); 18360 if (next_adapter) 18361 hdd_adapter_dev_put_debug( 18362 next_adapter, 18363 dbgid); 18364 return adapter; 18365 } 18366 } 18367 } 18368 hdd_adapter_dev_put_debug(adapter, dbgid); 18369 } 18370 18371 return NULL; 18372 } 18373 hdd_adapter_is_sta(struct hdd_adapter * adapter)18374 static inline bool hdd_adapter_is_sta(struct hdd_adapter *adapter) 18375 { 18376 return adapter->device_mode == QDF_STA_MODE || 18377 adapter->device_mode == QDF_P2P_CLIENT_MODE; 18378 } 18379 hdd_is_any_adapter_connected(struct hdd_context * hdd_ctx)18380 bool hdd_is_any_adapter_connected(struct hdd_context *hdd_ctx) 18381 { 18382 struct hdd_adapter *adapter, *next_adapter = NULL; 18383 wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_IS_ANY_ADAPTER_CONNECTED; 18384 struct wlan_hdd_link_info *link_info; 18385 18386 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 18387 dbgid) { 18388 hdd_adapter_for_each_active_link_info(adapter, link_info) { 18389 if (hdd_adapter_is_sta(adapter) && 18390 hdd_cm_is_vdev_associated(link_info)) { 18391 hdd_adapter_dev_put_debug(adapter, dbgid); 18392 if (next_adapter) 18393 hdd_adapter_dev_put_debug(next_adapter, 18394 dbgid); 18395 return true; 18396 } 18397 18398 if (hdd_adapter_is_ap(adapter) && 18399 WLAN_HDD_GET_AP_CTX_PTR(link_info)->ap_active) { 18400 hdd_adapter_dev_put_debug(adapter, dbgid); 18401 if (next_adapter) 18402 hdd_adapter_dev_put_debug(next_adapter, 18403 dbgid); 18404 return true; 18405 } 18406 18407 if (adapter->device_mode == QDF_NDI_MODE && 18408 hdd_cm_is_vdev_associated(link_info)) { 18409 hdd_adapter_dev_put_debug(adapter, dbgid); 18410 if (next_adapter) 18411 hdd_adapter_dev_put_debug(next_adapter, 18412 dbgid); 18413 return true; 18414 } 18415 } 18416 hdd_adapter_dev_put_debug(adapter, dbgid); 18417 } 18418 18419 return false; 18420 } 18421 18422 #if defined MSM_PLATFORM && (LINUX_VERSION_CODE <= KERNEL_VERSION(4, 19, 0)) 18423 /** 18424 * hdd_inform_stop_sap() - call cfg80211 API to stop SAP 18425 * @adapter: pointer to adapter 18426 * 18427 * This function calls cfg80211 API to stop SAP 18428 * 18429 * Return: None 18430 */ hdd_inform_stop_sap(struct hdd_adapter * adapter)18431 static void hdd_inform_stop_sap(struct hdd_adapter *adapter) 18432 { 18433 hdd_debug("SAP stopped due to invalid channel vdev id %d", 18434 wlan_vdev_get_id(adapter->deflink->vdev)); 18435 cfg80211_ap_stopped(adapter->dev, GFP_KERNEL); 18436 } 18437 18438 #else hdd_inform_stop_sap(struct hdd_adapter * adapter)18439 static void hdd_inform_stop_sap(struct hdd_adapter *adapter) 18440 { 18441 hdd_debug("SAP stopped due to invalid channel vdev id %d", 18442 wlan_vdev_get_id(adapter->deflink->vdev)); 18443 cfg80211_stop_iface(adapter->hdd_ctx->wiphy, &adapter->wdev, 18444 GFP_KERNEL); 18445 } 18446 #endif 18447 18448 /** 18449 * wlan_hdd_stop_sap() - This function stops bss of SAP. 18450 * @ap_adapter: SAP adapter 18451 * 18452 * This function will process the stopping of sap adapter. 18453 * 18454 * Return: None 18455 */ wlan_hdd_stop_sap(struct hdd_adapter * ap_adapter)18456 void wlan_hdd_stop_sap(struct hdd_adapter *ap_adapter) 18457 { 18458 struct hdd_ap_ctx *hdd_ap_ctx; 18459 struct hdd_hostapd_state *hostapd_state; 18460 QDF_STATUS qdf_status; 18461 struct hdd_context *hdd_ctx; 18462 18463 if (!ap_adapter) { 18464 hdd_err("ap_adapter is NULL here"); 18465 return; 18466 } 18467 18468 hdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(ap_adapter->deflink); 18469 hdd_ctx = WLAN_HDD_GET_CTX(ap_adapter); 18470 if (wlan_hdd_validate_context(hdd_ctx)) 18471 return; 18472 18473 mutex_lock(&hdd_ctx->sap_lock); 18474 if (test_bit(SOFTAP_BSS_STARTED, &ap_adapter->deflink->link_flags)) { 18475 wlan_hdd_del_station(ap_adapter, NULL); 18476 hostapd_state = 18477 WLAN_HDD_GET_HOSTAP_STATE_PTR(ap_adapter->deflink); 18478 hdd_debug("Now doing SAP STOPBSS"); 18479 qdf_event_reset(&hostapd_state->qdf_stop_bss_event); 18480 if (QDF_STATUS_SUCCESS == wlansap_stop_bss(hdd_ap_ctx-> 18481 sap_context)) { 18482 qdf_status = qdf_wait_single_event(&hostapd_state-> 18483 qdf_stop_bss_event, 18484 SME_CMD_STOP_BSS_TIMEOUT); 18485 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { 18486 mutex_unlock(&hdd_ctx->sap_lock); 18487 hdd_err("SAP Stop Failed"); 18488 return; 18489 } 18490 } 18491 clear_bit(SOFTAP_BSS_STARTED, &ap_adapter->deflink->link_flags); 18492 policy_mgr_decr_session_set_pcl(hdd_ctx->psoc, 18493 ap_adapter->device_mode, 18494 ap_adapter->deflink->vdev_id); 18495 hdd_green_ap_start_state_mc(hdd_ctx, ap_adapter->device_mode, 18496 false); 18497 hdd_inform_stop_sap(ap_adapter); 18498 hdd_debug("SAP Stop Success"); 18499 } else { 18500 hdd_err("Can't stop ap because its not started"); 18501 } 18502 mutex_unlock(&hdd_ctx->sap_lock); 18503 } 18504 18505 #if defined(WLAN_FEATURE_11BE_MLO) && defined(CFG80211_11BE_BASIC) 18506 /** 18507 * wlan_hdd_mlo_sap_reinit() - handle mlo scenario for ssr 18508 * @link_info: Pointer of link_info in adapter 18509 * 18510 * Return: QDF_STATUS 18511 */ wlan_hdd_mlo_sap_reinit(struct wlan_hdd_link_info * link_info)18512 static QDF_STATUS wlan_hdd_mlo_sap_reinit(struct wlan_hdd_link_info *link_info) 18513 { 18514 struct hdd_context *hdd_ctx = link_info->adapter->hdd_ctx; 18515 struct sap_config *config = &link_info->session.ap.sap_config; 18516 18517 if (config->mlo_sap) { 18518 if (!mlo_ap_vdev_attach(link_info->vdev, config->link_id, 18519 config->num_link)) { 18520 hdd_err("SAP mlo mgr attach fail"); 18521 return QDF_STATUS_E_INVAL; 18522 } 18523 } 18524 18525 if (!policy_mgr_is_mlo_sap_concurrency_allowed(hdd_ctx->psoc, 18526 config->mlo_sap, 18527 wlan_vdev_get_id(link_info->vdev))) { 18528 hdd_err("MLO SAP concurrency check fails"); 18529 return QDF_STATUS_E_INVAL; 18530 } 18531 18532 return QDF_STATUS_SUCCESS; 18533 } 18534 #else 18535 static inline QDF_STATUS wlan_hdd_mlo_sap_reinit(struct wlan_hdd_link_info * link_info)18536 wlan_hdd_mlo_sap_reinit(struct wlan_hdd_link_info *link_info) 18537 { 18538 return QDF_STATUS_SUCCESS; 18539 } 18540 #endif 18541 wlan_hdd_set_sap_beacon_protection(struct hdd_context * hdd_ctx,struct wlan_hdd_link_info * link_info,struct hdd_beacon_data * beacon)18542 void wlan_hdd_set_sap_beacon_protection(struct hdd_context *hdd_ctx, 18543 struct wlan_hdd_link_info *link_info, 18544 struct hdd_beacon_data *beacon) 18545 { 18546 const uint8_t *ie = NULL; 18547 struct s_ext_cap *p_ext_cap; 18548 struct wlan_objmgr_vdev *vdev; 18549 bool target_bigtk_support = false; 18550 uint8_t vdev_id; 18551 uint8_t ie_len; 18552 18553 if (!beacon) { 18554 hdd_err("beacon is null"); 18555 return; 18556 } 18557 18558 ie = wlan_get_ie_ptr_from_eid(DOT11F_EID_EXTCAP, beacon->tail, 18559 beacon->tail_len); 18560 if (!ie) { 18561 hdd_err("IE is null"); 18562 return; 18563 } 18564 18565 if (ie[1] > DOT11F_IE_EXTCAP_MAX_LEN || 18566 ie[1] < DOT11F_IE_EXTCAP_MIN_LEN) { 18567 hdd_err("Invalid IEs eid: %d elem_len: %d", ie[0], ie[1]); 18568 return; 18569 } 18570 18571 p_ext_cap = qdf_mem_malloc(sizeof(*p_ext_cap)); 18572 if (!p_ext_cap) 18573 return; 18574 18575 ie_len = (ie[1] > sizeof(*p_ext_cap)) ? sizeof(*p_ext_cap) : ie[1]; 18576 18577 qdf_mem_copy(p_ext_cap, &ie[2], ie_len); 18578 18579 vdev = hdd_objmgr_get_vdev_by_user(link_info, WLAN_HDD_ID_OBJ_MGR); 18580 if (!vdev) { 18581 hdd_err("vdev is null"); 18582 goto end; 18583 } 18584 18585 vdev_id = wlan_vdev_get_id(vdev); 18586 18587 hdd_debug("vdev %d beacon protection %d", vdev_id, 18588 p_ext_cap->beacon_protection_enable); 18589 18590 ucfg_mlme_get_bigtk_support(hdd_ctx->psoc, &target_bigtk_support); 18591 18592 if (target_bigtk_support && p_ext_cap->beacon_protection_enable) 18593 mlme_set_bigtk_support(vdev, true); 18594 18595 hdd_objmgr_put_vdev_by_user(vdev, WLAN_HDD_ID_OBJ_MGR); 18596 18597 end: 18598 qdf_mem_free(p_ext_cap); 18599 } 18600 wlan_hdd_start_sap(struct wlan_hdd_link_info * link_info,bool reinit)18601 void wlan_hdd_start_sap(struct wlan_hdd_link_info *link_info, bool reinit) 18602 { 18603 struct hdd_ap_ctx *ap_ctx; 18604 struct hdd_hostapd_state *hostapd_state; 18605 QDF_STATUS qdf_status; 18606 struct hdd_context *hdd_ctx; 18607 struct sap_config *sap_config; 18608 struct hdd_adapter *ap_adapter = link_info->adapter; 18609 18610 if (QDF_SAP_MODE != ap_adapter->device_mode) { 18611 hdd_err("SoftAp role has not been enabled"); 18612 return; 18613 } 18614 18615 hdd_ctx = WLAN_HDD_GET_CTX(ap_adapter); 18616 ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(link_info); 18617 hostapd_state = WLAN_HDD_GET_HOSTAP_STATE_PTR(link_info); 18618 sap_config = &ap_ctx->sap_config; 18619 18620 mutex_lock(&hdd_ctx->sap_lock); 18621 if (test_bit(SOFTAP_BSS_STARTED, &link_info->link_flags)) 18622 goto end; 18623 18624 if (wlan_hdd_cfg80211_update_apies(link_info)) { 18625 hdd_err("SAP Not able to set AP IEs"); 18626 goto end; 18627 } 18628 wlan_reg_set_channel_params_for_pwrmode(hdd_ctx->pdev, 18629 sap_config->chan_freq, 0, 18630 &sap_config->ch_params, 18631 REG_CURRENT_PWR_MODE); 18632 qdf_status = wlan_hdd_mlo_sap_reinit(link_info); 18633 if (QDF_IS_STATUS_ERROR(qdf_status)) { 18634 hdd_err("SAP Not able to do mlo attach"); 18635 goto end; 18636 } 18637 18638 qdf_event_reset(&hostapd_state->qdf_event); 18639 qdf_status = wlansap_start_bss(ap_ctx->sap_context, 18640 hdd_hostapd_sap_event_cb, sap_config, 18641 ap_adapter->dev); 18642 if (QDF_IS_STATUS_ERROR(qdf_status)) 18643 goto end; 18644 18645 wlan_hdd_set_sap_beacon_protection(hdd_ctx, link_info, ap_ctx->beacon); 18646 18647 hdd_debug("Waiting for SAP to start"); 18648 qdf_status = qdf_wait_single_event(&hostapd_state->qdf_event, 18649 SME_CMD_START_BSS_TIMEOUT); 18650 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { 18651 hdd_err("SAP Start failed"); 18652 goto end; 18653 } 18654 hdd_info("SAP Start Success"); 18655 18656 wlansap_reset_sap_config_add_ie(sap_config, eUPDATE_IE_ALL); 18657 set_bit(SOFTAP_BSS_STARTED, &link_info->link_flags); 18658 if (hostapd_state->bss_state == BSS_START) { 18659 policy_mgr_incr_active_session(hdd_ctx->psoc, 18660 ap_adapter->device_mode, 18661 link_info->vdev_id); 18662 hdd_green_ap_start_state_mc(hdd_ctx, ap_adapter->device_mode, 18663 true); 18664 } 18665 mutex_unlock(&hdd_ctx->sap_lock); 18666 18667 return; 18668 end: 18669 wlan_hdd_mlo_reset(link_info); 18670 wlansap_reset_sap_config_add_ie(sap_config, eUPDATE_IE_ALL); 18671 mutex_unlock(&hdd_ctx->sap_lock); 18672 /* SAP context and beacon cleanup will happen during driver unload 18673 * in hdd_stop_adapter 18674 */ 18675 hdd_err("SAP restart after SSR failed! Reload WLAN and try SAP again"); 18676 /* Free the beacon memory in case of failure in the sap restart */ 18677 qdf_mem_free(ap_ctx->beacon); 18678 ap_ctx->beacon = NULL; 18679 } 18680 18681 #ifdef QCA_CONFIG_SMP 18682 /** 18683 * wlan_hdd_get_cpu() - get cpu_index 18684 * 18685 * Return: cpu_index 18686 */ wlan_hdd_get_cpu(void)18687 int wlan_hdd_get_cpu(void) 18688 { 18689 int cpu_index = get_cpu(); 18690 18691 put_cpu(); 18692 return cpu_index; 18693 } 18694 #endif 18695 18696 /** 18697 * hdd_get_fwpath() - get framework path 18698 * 18699 * This function is used to get the string written by 18700 * userspace to start the wlan driver 18701 * 18702 * Return: string 18703 */ hdd_get_fwpath(void)18704 const char *hdd_get_fwpath(void) 18705 { 18706 return fwpath.string; 18707 } 18708 hdd_state_query_cb(void)18709 static inline int hdd_state_query_cb(void) 18710 { 18711 return !!wlan_hdd_validate_context(cds_get_context(QDF_MODULE_ID_HDD)); 18712 } 18713 __hdd_op_protect_cb(void ** out_sync,const char * func)18714 static int __hdd_op_protect_cb(void **out_sync, const char *func) 18715 { 18716 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 18717 18718 if (!hdd_ctx) 18719 return -EAGAIN; 18720 18721 return __osif_psoc_sync_op_start(hdd_ctx->parent_dev, 18722 (struct osif_psoc_sync **)out_sync, 18723 func); 18724 } 18725 __hdd_op_unprotect_cb(void * sync,const char * func)18726 static void __hdd_op_unprotect_cb(void *sync, const char *func) 18727 { 18728 __osif_psoc_sync_op_stop(sync, func); 18729 } 18730 18731 #ifdef WLAN_LOGGING_SOCK_SVC_ENABLE 18732 /** 18733 * hdd_logging_sock_init_svc() - Initialize logging sock 18734 * 18735 * Return: 0 for success, errno on failure 18736 */ 18737 static int hdd_logging_sock_init_svc(void)18738 hdd_logging_sock_init_svc(void) 18739 { 18740 return wlan_logging_sock_init_svc(); 18741 } 18742 #else 18743 static inline int hdd_logging_sock_init_svc(void)18744 hdd_logging_sock_init_svc(void) 18745 { 18746 return 0; 18747 } 18748 #endif 18749 18750 /** 18751 * hdd_init() - Initialize Driver 18752 * 18753 * This function initializes CDS global context with the help of cds_init. This 18754 * has to be the first function called after probe to get a valid global 18755 * context. 18756 * 18757 * Return: 0 for success, errno on failure 18758 */ hdd_init(void)18759 int hdd_init(void) 18760 { 18761 QDF_STATUS status; 18762 18763 status = cds_init(); 18764 if (QDF_IS_STATUS_ERROR(status)) { 18765 hdd_err("Failed to allocate CDS context"); 18766 return -ENOMEM; 18767 } 18768 18769 qdf_op_callbacks_register(__hdd_op_protect_cb, __hdd_op_unprotect_cb); 18770 18771 wlan_init_bug_report_lock(); 18772 18773 if (hdd_logging_sock_init_svc()) { 18774 hdd_err("logging sock init failed."); 18775 goto err; 18776 } 18777 18778 hdd_trace_init(); 18779 hdd_register_debug_callback(); 18780 wlan_roam_debug_init(); 18781 18782 return 0; 18783 18784 err: 18785 wlan_destroy_bug_report_lock(); 18786 qdf_op_callbacks_register(NULL, NULL); 18787 cds_deinit(); 18788 return -ENOMEM; 18789 } 18790 18791 /** 18792 * hdd_deinit() - Deinitialize Driver 18793 * 18794 * This function frees CDS global context with the help of cds_deinit. This 18795 * has to be the last function call in remove callback to free the global 18796 * context. 18797 */ hdd_deinit(void)18798 void hdd_deinit(void) 18799 { 18800 wlan_roam_debug_deinit(); 18801 18802 #ifdef WLAN_LOGGING_SOCK_SVC_ENABLE 18803 wlan_logging_sock_deinit_svc(); 18804 #endif 18805 18806 wlan_destroy_bug_report_lock(); 18807 qdf_op_callbacks_register(NULL, NULL); 18808 cds_deinit(); 18809 } 18810 18811 #ifdef QCA_WIFI_EMULATION 18812 #define HDD_WLAN_START_WAIT_TIME ((CDS_WMA_TIMEOUT + 5000) * 100) 18813 #else 18814 #define HDD_WLAN_START_WAIT_TIME (CDS_WMA_TIMEOUT + 5000) 18815 #endif 18816 hdd_init_start_completion(void)18817 void hdd_init_start_completion(void) 18818 { 18819 INIT_COMPLETION(wlan_start_comp); 18820 } 18821 18822 #ifdef WLAN_CTRL_NAME 18823 static unsigned int dev_num = 1; 18824 static struct cdev wlan_hdd_state_cdev; 18825 static struct class *class; 18826 static dev_t device; 18827 hdd_set_adapter_wlm_def_level(struct hdd_context * hdd_ctx)18828 static void hdd_set_adapter_wlm_def_level(struct hdd_context *hdd_ctx) 18829 { 18830 struct hdd_adapter *adapter, *next_adapter = NULL; 18831 wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_GET_ADAPTER; 18832 int ret; 18833 QDF_STATUS qdf_status; 18834 uint8_t latency_level; 18835 bool reset; 18836 18837 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) 18838 return; 18839 18840 ret = wlan_hdd_validate_context(hdd_ctx); 18841 if (ret != 0) 18842 return; 18843 18844 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 18845 dbgid) { 18846 qdf_status = ucfg_mlme_cfg_get_wlm_level(hdd_ctx->psoc, 18847 &latency_level); 18848 if (QDF_IS_STATUS_ERROR(qdf_status)) 18849 adapter->latency_level = 18850 QCA_WLAN_VENDOR_ATTR_CONFIG_LATENCY_LEVEL_NORMAL; 18851 else 18852 adapter->latency_level = latency_level; 18853 qdf_status = ucfg_mlme_cfg_get_wlm_reset(hdd_ctx->psoc, &reset); 18854 if (QDF_IS_STATUS_ERROR(qdf_status)) { 18855 hdd_err("could not get the wlm reset flag"); 18856 reset = false; 18857 } 18858 18859 if (hdd_get_multi_client_ll_support(adapter) && !reset) 18860 wlan_hdd_deinit_multi_client_info_table(adapter); 18861 18862 adapter->upgrade_udp_qos_threshold = QCA_WLAN_AC_BK; 18863 hdd_debug("UDP packets qos reset to: %d", 18864 adapter->upgrade_udp_qos_threshold); 18865 hdd_adapter_dev_put_debug(adapter, dbgid); 18866 } 18867 } 18868 wlan_hdd_state_ctrl_param_open(struct inode * inode,struct file * file)18869 static int wlan_hdd_state_ctrl_param_open(struct inode *inode, 18870 struct file *file) 18871 { 18872 qdf_atomic_inc(&wlan_hdd_state_fops_ref); 18873 18874 return 0; 18875 } 18876 __hdd_inform_wifi_off(void)18877 static void __hdd_inform_wifi_off(void) 18878 { 18879 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 18880 int ret; 18881 18882 ret = wlan_hdd_validate_context(hdd_ctx); 18883 if (ret != 0) 18884 return; 18885 18886 ucfg_dlm_wifi_off(hdd_ctx->pdev); 18887 18888 if (rtnl_trylock()) { 18889 wlan_hdd_lpc_del_monitor_interface(hdd_ctx, false); 18890 rtnl_unlock(); 18891 } 18892 } 18893 hdd_inform_wifi_off(void)18894 static void hdd_inform_wifi_off(void) 18895 { 18896 int ret; 18897 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 18898 struct osif_psoc_sync *psoc_sync; 18899 18900 if (!hdd_ctx) 18901 return; 18902 18903 ret = osif_psoc_sync_op_start(wiphy_dev(hdd_ctx->wiphy), &psoc_sync); 18904 if (ret) 18905 return; 18906 18907 hdd_set_adapter_wlm_def_level(hdd_ctx); 18908 __hdd_inform_wifi_off(); 18909 18910 osif_psoc_sync_op_stop(psoc_sync); 18911 } 18912 18913 #if defined CFG80211_USER_HINT_CELL_BASE_SELF_MANAGED || \ 18914 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 18, 0)) hdd_inform_wifi_on(void)18915 static void hdd_inform_wifi_on(void) 18916 { 18917 int ret; 18918 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 18919 struct osif_psoc_sync *psoc_sync; 18920 18921 hdd_nofl_debug("inform regdomain for wifi on"); 18922 ret = wlan_hdd_validate_context(hdd_ctx); 18923 if (ret) 18924 return; 18925 if (!wlan_hdd_validate_modules_state(hdd_ctx)) 18926 return; 18927 if (!hdd_ctx->wiphy) 18928 return; 18929 ret = osif_psoc_sync_op_start(wiphy_dev(hdd_ctx->wiphy), &psoc_sync); 18930 if (ret) 18931 return; 18932 if (hdd_ctx->wiphy->registered) 18933 hdd_send_wiphy_regd_sync_event(hdd_ctx); 18934 18935 osif_psoc_sync_op_stop(psoc_sync); 18936 } 18937 #else hdd_inform_wifi_on(void)18938 static void hdd_inform_wifi_on(void) 18939 { 18940 } 18941 #endif 18942 hdd_validate_wlan_string(const char __user * user_buf)18943 static int hdd_validate_wlan_string(const char __user *user_buf) 18944 { 18945 char buf[15]; 18946 int i; 18947 static const char * const wlan_str[] = { 18948 [WLAN_OFF_STR] = "OFF", 18949 [WLAN_ON_STR] = "ON", 18950 [WLAN_ENABLE_STR] = "ENABLE", 18951 [WLAN_DISABLE_STR] = "DISABLE", 18952 [WLAN_WAIT_FOR_READY_STR] = "WAIT_FOR_READY", 18953 [WLAN_FORCE_DISABLE_STR] = "FORCE_DISABLE" 18954 }; 18955 18956 if (copy_from_user(buf, user_buf, sizeof(buf))) { 18957 pr_err("Failed to read buffer\n"); 18958 return -EINVAL; 18959 } 18960 18961 for (i = 0; i < ARRAY_SIZE(wlan_str); i++) { 18962 if (qdf_str_ncmp(buf, wlan_str[i], strlen(wlan_str[i])) == 0) 18963 return i; 18964 } 18965 18966 return -EINVAL; 18967 } 18968 18969 #ifdef FEATURE_CNSS_HW_SECURE_DISABLE 18970 #define WIFI_DISABLE_SLEEP (10) 18971 #define WIFI_DISABLE_MAX_RETRY_ATTEMPTS (10) 18972 static bool g_soft_unload; 18973 hdd_get_wlan_driver_status(void)18974 bool hdd_get_wlan_driver_status(void) 18975 { 18976 return g_soft_unload; 18977 } 18978 hdd_wlan_soft_driver_load(void)18979 static int hdd_wlan_soft_driver_load(void) 18980 { 18981 if (!cds_is_driver_loaded()) { 18982 hdd_debug("\nEnabling CNSS WLAN HW"); 18983 pld_wlan_hw_enable(); 18984 return 0; 18985 } 18986 18987 if (!g_soft_unload) { 18988 hdd_debug_rl("Enabling WiFi\n"); 18989 return -EINVAL; 18990 } 18991 18992 hdd_driver_load(); 18993 g_soft_unload = false; 18994 return 0; 18995 } 18996 hdd_wlan_soft_driver_unload(void)18997 static void hdd_wlan_soft_driver_unload(void) 18998 { 18999 if (g_soft_unload) { 19000 hdd_debug_rl("WiFi is already disabled"); 19001 return; 19002 } 19003 hdd_debug("Initiating soft driver unload\n"); 19004 g_soft_unload = true; 19005 hdd_driver_unload(); 19006 } 19007 hdd_wlan_idle_shutdown(struct hdd_context * hdd_ctx)19008 static int hdd_wlan_idle_shutdown(struct hdd_context *hdd_ctx) 19009 { 19010 int ret; 19011 int retries = 0; 19012 void *hif_ctx; 19013 19014 if (!hdd_ctx) { 19015 hdd_err_rl("hdd_ctx is Null"); 19016 return -EINVAL; 19017 } 19018 19019 hif_ctx = cds_get_context(QDF_MODULE_ID_HIF); 19020 19021 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_IDLE_SHUTDOWN); 19022 19023 while (retries < WIFI_DISABLE_MAX_RETRY_ATTEMPTS) { 19024 if (hif_ctx) { 19025 /* 19026 * Trigger runtime sync resume before psoc_idle_shutdown 19027 * such that resume can happen successfully 19028 */ 19029 qdf_rtpm_sync_resume(); 19030 } 19031 ret = pld_idle_shutdown(hdd_ctx->parent_dev, 19032 hdd_psoc_idle_shutdown); 19033 19034 if (-EAGAIN == ret || hdd_ctx->is_wiphy_suspended) { 19035 hdd_debug("System suspend in progress.Retries done:%d", 19036 retries); 19037 msleep(WIFI_DISABLE_SLEEP); 19038 retries++; 19039 continue; 19040 } 19041 break; 19042 } 19043 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_IDLE_SHUTDOWN); 19044 19045 if (retries > WIFI_DISABLE_MAX_RETRY_ATTEMPTS) { 19046 hdd_debug("Max retries reached"); 19047 return -EINVAL; 19048 } 19049 hdd_debug_rl("WiFi is disabled"); 19050 19051 return 0; 19052 } 19053 hdd_disable_wifi(struct hdd_context * hdd_ctx)19054 static int hdd_disable_wifi(struct hdd_context *hdd_ctx) 19055 { 19056 int ret; 19057 19058 if (hdd_ctx->is_wlan_disabled) { 19059 hdd_err_rl("Wifi is already disabled"); 19060 return 0; 19061 } 19062 19063 hdd_debug("Initiating WLAN idle shutdown"); 19064 if (hdd_is_any_interface_open(hdd_ctx)) { 19065 hdd_err("Interfaces still open, cannot process wifi disable"); 19066 return -EAGAIN; 19067 } 19068 19069 hdd_ctx->is_wlan_disabled = true; 19070 19071 ret = hdd_wlan_idle_shutdown(hdd_ctx); 19072 if (ret) 19073 hdd_ctx->is_wlan_disabled = false; 19074 19075 return ret; 19076 } 19077 #else hdd_wlan_soft_driver_load(void)19078 static int hdd_wlan_soft_driver_load(void) 19079 { 19080 return -EINVAL; 19081 } 19082 hdd_wlan_soft_driver_unload(void)19083 static void hdd_wlan_soft_driver_unload(void) 19084 { 19085 } 19086 hdd_disable_wifi(struct hdd_context * hdd_ctx)19087 static int hdd_disable_wifi(struct hdd_context *hdd_ctx) 19088 { 19089 return 0; 19090 } 19091 #endif /* FEATURE_CNSS_HW_SECURE_DISABLE */ 19092 wlan_hdd_state_ctrl_param_write(struct file * filp,const char __user * user_buf,size_t count,loff_t * f_pos)19093 static ssize_t wlan_hdd_state_ctrl_param_write(struct file *filp, 19094 const char __user *user_buf, 19095 size_t count, 19096 loff_t *f_pos) 19097 { 19098 int id, ret; 19099 unsigned long rc; 19100 struct hdd_context *hdd_ctx; 19101 bool is_wait_for_ready = false; 19102 bool is_wlan_force_disabled; 19103 19104 hdd_enter(); 19105 19106 id = hdd_validate_wlan_string(user_buf); 19107 19108 switch (id) { 19109 case WLAN_OFF_STR: 19110 hdd_info("Wifi turning off from UI\n"); 19111 hdd_inform_wifi_off(); 19112 goto exit; 19113 case WLAN_ON_STR: 19114 hdd_info("Wifi Turning On from UI\n"); 19115 break; 19116 case WLAN_WAIT_FOR_READY_STR: 19117 is_wait_for_ready = true; 19118 hdd_info("Wifi wait for ready from UI\n"); 19119 break; 19120 case WLAN_ENABLE_STR: 19121 hdd_nofl_debug("Received WiFi enable from framework\n"); 19122 if (!hdd_wlan_soft_driver_load()) 19123 goto exit; 19124 pr_info("Enabling WiFi\n"); 19125 break; 19126 case WLAN_DISABLE_STR: 19127 hdd_nofl_debug("Received WiFi disable from framework\n"); 19128 if (!cds_is_driver_loaded()) 19129 goto exit; 19130 19131 is_wlan_force_disabled = hdd_get_wlan_driver_status(); 19132 if (is_wlan_force_disabled) 19133 goto exit; 19134 pr_info("Disabling WiFi\n"); 19135 break; 19136 case WLAN_FORCE_DISABLE_STR: 19137 hdd_nofl_debug("Received Force WiFi disable from framework\n"); 19138 if (!cds_is_driver_loaded()) 19139 goto exit; 19140 19141 hdd_wlan_soft_driver_unload(); 19142 goto exit; 19143 default: 19144 hdd_err_rl("Invalid value received from framework"); 19145 return -EINVAL; 19146 } 19147 19148 hdd_info("is_driver_loaded %d is_driver_recovering %d", 19149 cds_is_driver_loaded(), cds_is_driver_recovering()); 19150 19151 if (!cds_is_driver_loaded() || cds_is_driver_recovering()) { 19152 rc = wait_for_completion_timeout(&wlan_start_comp, 19153 msecs_to_jiffies(HDD_WLAN_START_WAIT_TIME)); 19154 if (!rc) { 19155 hdd_err("Driver Loading Timed-out!!"); 19156 ret = -EINVAL; 19157 return ret; 19158 } 19159 } 19160 19161 if (is_wait_for_ready) 19162 return count; 19163 /* 19164 * Flush idle shutdown work for cases to synchronize the wifi on 19165 * during the idle shutdown. 19166 */ 19167 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 19168 if (hdd_ctx) 19169 hdd_psoc_idle_timer_stop(hdd_ctx); 19170 19171 if (id == WLAN_DISABLE_STR) { 19172 if (!hdd_ctx) { 19173 hdd_err_rl("hdd_ctx is Null"); 19174 goto exit; 19175 } 19176 19177 ret = hdd_disable_wifi(hdd_ctx); 19178 if (ret) 19179 return ret; 19180 } 19181 19182 if (id == WLAN_ENABLE_STR) { 19183 if (!hdd_ctx) { 19184 hdd_err_rl("hdd_ctx is Null"); 19185 goto exit; 19186 } 19187 19188 if (!hdd_ctx->is_wlan_disabled) { 19189 hdd_err_rl("WiFi is already enabled"); 19190 goto exit; 19191 } 19192 hdd_ctx->is_wlan_disabled = false; 19193 } 19194 19195 if (id == WLAN_ON_STR) 19196 hdd_inform_wifi_on(); 19197 exit: 19198 hdd_exit(); 19199 return count; 19200 } 19201 19202 /** 19203 * wlan_hdd_state_ctrl_param_release() - Release callback for /dev/wlan. 19204 * 19205 * @inode: struct inode pointer. 19206 * @file: struct file pointer. 19207 * 19208 * Release callback that would be invoked when the file operations has 19209 * completed fully. This is implemented to provide a reference count mechanism 19210 * via which the driver can wait till all possible usage of the /dev/wlan 19211 * file is completed. 19212 * 19213 * Return: Success 19214 */ wlan_hdd_state_ctrl_param_release(struct inode * inode,struct file * file)19215 static int wlan_hdd_state_ctrl_param_release(struct inode *inode, 19216 struct file *file) 19217 { 19218 qdf_atomic_dec(&wlan_hdd_state_fops_ref); 19219 19220 return 0; 19221 } 19222 19223 const struct file_operations wlan_hdd_state_fops = { 19224 .owner = THIS_MODULE, 19225 .open = wlan_hdd_state_ctrl_param_open, 19226 .write = wlan_hdd_state_ctrl_param_write, 19227 .release = wlan_hdd_state_ctrl_param_release, 19228 }; 19229 19230 #if (LINUX_VERSION_CODE < KERNEL_VERSION(6, 2, 0)) wlan_hdd_class_create(const char * name)19231 static struct class *wlan_hdd_class_create(const char *name) 19232 { 19233 return class_create(THIS_MODULE, name); 19234 } 19235 #else wlan_hdd_class_create(const char * name)19236 static struct class *wlan_hdd_class_create(const char *name) 19237 { 19238 return class_create(name); 19239 } 19240 #endif 19241 wlan_hdd_state_ctrl_param_create(void)19242 static int wlan_hdd_state_ctrl_param_create(void) 19243 { 19244 unsigned int wlan_hdd_state_major = 0; 19245 int ret; 19246 struct device *dev; 19247 19248 init_completion(&wlan_start_comp); 19249 qdf_atomic_init(&wlan_hdd_state_fops_ref); 19250 19251 device = MKDEV(wlan_hdd_state_major, 0); 19252 19253 ret = alloc_chrdev_region(&device, 0, dev_num, "qcwlanstate"); 19254 if (ret) { 19255 pr_err("Failed to register qcwlanstate"); 19256 goto dev_alloc_err; 19257 } 19258 wlan_hdd_state_major = MAJOR(device); 19259 class = wlan_hdd_class_create(WLAN_CTRL_NAME); 19260 if (IS_ERR(class)) { 19261 pr_err("wlan_hdd_state class_create error"); 19262 goto class_err; 19263 } 19264 19265 dev = device_create(class, NULL, device, NULL, WLAN_CTRL_NAME); 19266 if (IS_ERR(dev)) { 19267 pr_err("wlan_hdd_statedevice_create error"); 19268 goto err_class_destroy; 19269 } 19270 19271 cdev_init(&wlan_hdd_state_cdev, &wlan_hdd_state_fops); 19272 19273 wlan_hdd_state_cdev.owner = THIS_MODULE; 19274 19275 ret = cdev_add(&wlan_hdd_state_cdev, device, dev_num); 19276 if (ret) { 19277 pr_err("Failed to add cdev error"); 19278 goto cdev_add_err; 19279 } 19280 19281 pr_info("wlan_hdd_state %s major(%d) initialized", 19282 WLAN_CTRL_NAME, wlan_hdd_state_major); 19283 19284 return 0; 19285 19286 cdev_add_err: 19287 device_destroy(class, device); 19288 err_class_destroy: 19289 class_destroy(class); 19290 class_err: 19291 unregister_chrdev_region(device, dev_num); 19292 dev_alloc_err: 19293 return -ENODEV; 19294 } 19295 19296 /* 19297 * When multiple instances of the driver are loaded in parallel, only 19298 * one can create and own the state ctrl param. An instance of the 19299 * driver that creates the state ctrl param will wait for 19300 * HDD_WLAN_START_WAIT_TIME to be probed. If it is probed, then that 19301 * instance of the driver will stay loaded and no other instances of 19302 * the driver can load. But if it is not probed, then that instance of 19303 * the driver will destroy the state ctrl param and exit, and another 19304 * instance of the driver can then create the state ctrl param. 19305 */ 19306 19307 /* max number of instances we expect (arbitrary) */ 19308 #define WLAN_DRIVER_MAX_INSTANCES 5 19309 19310 /* max amount of time an instance has to wait for all instances */ 19311 #define CTRL_PARAM_WAIT (WLAN_DRIVER_MAX_INSTANCES * HDD_WLAN_START_WAIT_TIME) 19312 19313 /* amount of time we sleep for each retry (arbitrary) */ 19314 #define CTRL_PARAM_SLEEP 100 19315 wlan_hdd_state_ctrl_param_destroy(void)19316 static void wlan_hdd_state_ctrl_param_destroy(void) 19317 { 19318 cdev_del(&wlan_hdd_state_cdev); 19319 device_destroy(class, device); 19320 class_destroy(class); 19321 unregister_chrdev_region(device, dev_num); 19322 19323 pr_info("Device node unregistered"); 19324 } 19325 19326 #else /* WLAN_CTRL_NAME */ 19327 wlan_hdd_state_ctrl_param_create(void)19328 static int wlan_hdd_state_ctrl_param_create(void) 19329 { 19330 return 0; 19331 } 19332 wlan_hdd_state_ctrl_param_destroy(void)19333 static void wlan_hdd_state_ctrl_param_destroy(void) 19334 { 19335 } 19336 19337 #endif /* WLAN_CTRL_NAME */ 19338 19339 /** 19340 * hdd_send_scan_done_complete_cb() - API to send scan done indication to upper 19341 * layer 19342 * @vdev_id: vdev id 19343 * 19344 * Return: none 19345 */ hdd_send_scan_done_complete_cb(uint8_t vdev_id)19346 static void hdd_send_scan_done_complete_cb(uint8_t vdev_id) 19347 { 19348 struct hdd_context *hdd_ctx; 19349 struct wlan_hdd_link_info *link_info; 19350 struct hdd_adapter *adapter; 19351 struct sk_buff *vendor_event; 19352 uint32_t len; 19353 19354 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 19355 if (!hdd_ctx) 19356 return; 19357 19358 link_info = hdd_get_link_info_by_vdev(hdd_ctx, vdev_id); 19359 if (!link_info) { 19360 hdd_err("Invalid vdev id:%d", vdev_id); 19361 return; 19362 } 19363 19364 adapter = link_info->adapter; 19365 len = NLMSG_HDRLEN; 19366 vendor_event = 19367 wlan_cfg80211_vendor_event_alloc( 19368 hdd_ctx->wiphy, &adapter->wdev, len, 19369 QCA_NL80211_VENDOR_SUBCMD_CONNECTED_CHANNEL_STATS_INDEX, 19370 GFP_KERNEL); 19371 19372 if (!vendor_event) { 19373 hdd_err("wlan_cfg80211_vendor_event_alloc failed"); 19374 return; 19375 } 19376 19377 hdd_debug("sending scan done ind to upper layer for vdev_id:%d", 19378 vdev_id); 19379 wlan_cfg80211_vendor_event(vendor_event, GFP_KERNEL); 19380 } 19381 19382 struct osif_vdev_mgr_ops osif_vdev_mgrlegacy_ops = { 19383 #ifdef WLAN_FEATURE_DYNAMIC_MAC_ADDR_UPDATE 19384 .osif_vdev_mgr_set_mac_addr_response = hdd_set_mac_addr_event_cb, 19385 #endif 19386 .osif_vdev_mgr_send_scan_done_complete_cb = 19387 hdd_send_scan_done_complete_cb, 19388 19389 }; 19390 hdd_vdev_mgr_register_cb(void)19391 static QDF_STATUS hdd_vdev_mgr_register_cb(void) 19392 { 19393 osif_vdev_mgr_set_legacy_cb(&osif_vdev_mgrlegacy_ops); 19394 return osif_vdev_mgr_register_cb(); 19395 } 19396 hdd_vdev_mgr_unregister_cb(void)19397 static void hdd_vdev_mgr_unregister_cb(void) 19398 { 19399 osif_vdev_mgr_reset_legacy_cb(); 19400 } 19401 19402 /** 19403 * hdd_ll_sap_register_cb() - Register ll_sap osif callbacks 19404 * 19405 * Return: QDF_STATUS 19406 */ hdd_ll_sap_register_cb(void)19407 static QDF_STATUS hdd_ll_sap_register_cb(void) 19408 { 19409 return osif_ll_sap_register_cb(); 19410 } 19411 19412 /** 19413 * hdd_ll_sap_unregister_cb() - Un-register ll_sap osif callbacks 19414 * 19415 * Return: void 19416 */ hdd_ll_sap_unregister_cb(void)19417 static void hdd_ll_sap_unregister_cb(void) 19418 { 19419 osif_ll_sap_unregister_cb(); 19420 } 19421 19422 /** 19423 * hdd_component_cb_init() - Initialize component callbacks 19424 * 19425 * This function initializes hdd callbacks to different 19426 * components 19427 * 19428 * Context: Any context. 19429 * Return: QDF_STATUS 19430 */ hdd_component_cb_init(void)19431 static QDF_STATUS hdd_component_cb_init(void) 19432 { 19433 QDF_STATUS status; 19434 19435 status = hdd_cm_register_cb(); 19436 if (QDF_IS_STATUS_ERROR(status)) 19437 return status; 19438 19439 status = hdd_vdev_mgr_register_cb(); 19440 if (QDF_IS_STATUS_ERROR(status)) 19441 goto cm_unregister_cb; 19442 19443 status = osif_twt_register_cb(); 19444 if (QDF_IS_STATUS_ERROR(status)) 19445 goto hdd_vdev_mgr_unregister_cb; 19446 19447 status = hdd_pre_cac_register_cb(); 19448 if (QDF_IS_STATUS_ERROR(status)) 19449 goto hdd_vdev_mgr_unregister_cb; 19450 19451 status = hdd_ll_sap_register_cb(); 19452 if (QDF_IS_STATUS_ERROR(status)) 19453 goto pre_cac_unregister_cb; 19454 19455 return QDF_STATUS_SUCCESS; 19456 19457 pre_cac_unregister_cb: 19458 hdd_pre_cac_unregister_cb(); 19459 hdd_vdev_mgr_unregister_cb: 19460 hdd_vdev_mgr_unregister_cb(); 19461 cm_unregister_cb: 19462 hdd_cm_unregister_cb(); 19463 return status; 19464 } 19465 19466 /** 19467 * hdd_component_cb_deinit() - De-initialize component callbacks 19468 * 19469 * This function de-initializes hdd callbacks with different components 19470 * 19471 * Context: Any context. 19472 * Return: None` 19473 */ hdd_component_cb_deinit(void)19474 static void hdd_component_cb_deinit(void) 19475 { 19476 hdd_ll_sap_unregister_cb(); 19477 hdd_pre_cac_unregister_cb(); 19478 hdd_vdev_mgr_unregister_cb(); 19479 hdd_cm_unregister_cb(); 19480 } 19481 19482 /** 19483 * hdd_component_init() - Initialize all components 19484 * 19485 * Return: QDF_STATUS 19486 */ hdd_component_init(void)19487 static QDF_STATUS hdd_component_init(void) 19488 { 19489 QDF_STATUS status; 19490 19491 /* initialize converged components */ 19492 19493 status = ucfg_mlme_global_init(); 19494 if (QDF_IS_STATUS_ERROR(status)) 19495 return status; 19496 19497 status = dispatcher_init(); 19498 if (QDF_IS_STATUS_ERROR(status)) 19499 goto mlme_global_deinit; 19500 19501 status = target_if_init(wma_get_psoc_from_scn_handle); 19502 if (QDF_IS_STATUS_ERROR(status)) 19503 goto dispatcher_deinit; 19504 19505 /* initialize non-converged components */ 19506 status = ucfg_mlme_init(); 19507 if (QDF_IS_STATUS_ERROR(status)) 19508 goto target_if_deinit; 19509 19510 status = ucfg_fwol_init(); 19511 if (QDF_IS_STATUS_ERROR(status)) 19512 goto mlme_deinit; 19513 19514 status = disa_init(); 19515 if (QDF_IS_STATUS_ERROR(status)) 19516 goto fwol_deinit; 19517 19518 status = pmo_init(); 19519 if (QDF_IS_STATUS_ERROR(status)) 19520 goto disa_deinit; 19521 19522 status = ucfg_ocb_init(); 19523 if (QDF_IS_STATUS_ERROR(status)) 19524 goto pmo_deinit; 19525 19526 status = ipa_init(); 19527 if (QDF_IS_STATUS_ERROR(status)) 19528 goto ocb_deinit; 19529 19530 status = ucfg_action_oui_init(); 19531 if (QDF_IS_STATUS_ERROR(status)) 19532 goto ipa_deinit; 19533 19534 status = nan_init(); 19535 if (QDF_IS_STATUS_ERROR(status)) 19536 goto action_oui_deinit; 19537 19538 status = ucfg_p2p_init(); 19539 if (QDF_IS_STATUS_ERROR(status)) 19540 goto nan_deinit; 19541 19542 status = ucfg_interop_issues_ap_init(); 19543 if (QDF_IS_STATUS_ERROR(status)) 19544 goto p2p_deinit; 19545 19546 status = policy_mgr_init(); 19547 if (QDF_IS_STATUS_ERROR(status)) 19548 goto interop_issues_ap_deinit; 19549 19550 status = ucfg_tdls_init(); 19551 if (QDF_IS_STATUS_ERROR(status)) 19552 goto policy_deinit; 19553 19554 status = ucfg_dlm_init(); 19555 if (QDF_IS_STATUS_ERROR(status)) 19556 goto tdls_deinit; 19557 19558 status = ucfg_pkt_capture_init(); 19559 if (QDF_IS_STATUS_ERROR(status)) 19560 goto dlm_deinit; 19561 19562 status = ucfg_ftm_time_sync_init(); 19563 if (QDF_IS_STATUS_ERROR(status)) 19564 goto pkt_capture_deinit; 19565 19566 status = ucfg_pre_cac_init(); 19567 if (QDF_IS_STATUS_ERROR(status)) 19568 goto pre_cac_deinit; 19569 19570 status = ucfg_dp_init(); 19571 if (QDF_IS_STATUS_ERROR(status)) 19572 goto pre_cac_deinit; 19573 19574 status = ucfg_qmi_init(); 19575 if (QDF_IS_STATUS_ERROR(status)) 19576 goto dp_deinit; 19577 19578 status = ucfg_ll_sap_init(); 19579 if (QDF_IS_STATUS_ERROR(status)) 19580 goto qmi_deinit; 19581 19582 status = ucfg_afc_init(); 19583 if (QDF_IS_STATUS_ERROR(status)) 19584 goto ll_sap_deinit; 19585 19586 status = hdd_mlo_mgr_register_osif_ops(); 19587 if (QDF_IS_STATUS_ERROR(status)) 19588 goto afc_deinit; 19589 19590 hdd_register_cstats_ops(); 19591 19592 return QDF_STATUS_SUCCESS; 19593 19594 afc_deinit: 19595 ucfg_afc_deinit(); 19596 ll_sap_deinit: 19597 ucfg_ll_sap_deinit(); 19598 qmi_deinit: 19599 ucfg_qmi_deinit(); 19600 dp_deinit: 19601 ucfg_dp_deinit(); 19602 pre_cac_deinit: 19603 ucfg_pre_cac_deinit(); 19604 pkt_capture_deinit: 19605 ucfg_pkt_capture_deinit(); 19606 dlm_deinit: 19607 ucfg_dlm_deinit(); 19608 tdls_deinit: 19609 ucfg_tdls_deinit(); 19610 policy_deinit: 19611 policy_mgr_deinit(); 19612 interop_issues_ap_deinit: 19613 ucfg_interop_issues_ap_deinit(); 19614 p2p_deinit: 19615 ucfg_p2p_deinit(); 19616 nan_deinit: 19617 nan_deinit(); 19618 action_oui_deinit: 19619 ucfg_action_oui_deinit(); 19620 ipa_deinit: 19621 ipa_deinit(); 19622 ocb_deinit: 19623 ucfg_ocb_deinit(); 19624 pmo_deinit: 19625 pmo_deinit(); 19626 disa_deinit: 19627 disa_deinit(); 19628 fwol_deinit: 19629 ucfg_fwol_deinit(); 19630 mlme_deinit: 19631 ucfg_mlme_deinit(); 19632 target_if_deinit: 19633 target_if_deinit(); 19634 dispatcher_deinit: 19635 dispatcher_deinit(); 19636 mlme_global_deinit: 19637 ucfg_mlme_global_deinit(); 19638 19639 return status; 19640 } 19641 19642 /** 19643 * hdd_component_deinit() - Deinitialize all components 19644 * 19645 * Return: None 19646 */ hdd_component_deinit(void)19647 static void hdd_component_deinit(void) 19648 { 19649 /* deinitialize non-converged components */ 19650 hdd_mlo_mgr_unregister_osif_ops(); 19651 ucfg_afc_deinit(); 19652 ucfg_ll_sap_deinit(); 19653 ucfg_qmi_deinit(); 19654 ucfg_dp_deinit(); 19655 ucfg_pre_cac_deinit(); 19656 ucfg_ftm_time_sync_deinit(); 19657 ucfg_pkt_capture_deinit(); 19658 ucfg_dlm_deinit(); 19659 ucfg_tdls_deinit(); 19660 policy_mgr_deinit(); 19661 ucfg_interop_issues_ap_deinit(); 19662 ucfg_p2p_deinit(); 19663 nan_deinit(); 19664 ucfg_action_oui_deinit(); 19665 ipa_deinit(); 19666 ucfg_ocb_deinit(); 19667 pmo_deinit(); 19668 disa_deinit(); 19669 ucfg_fwol_deinit(); 19670 ucfg_mlme_deinit(); 19671 19672 /* deinitialize converged components */ 19673 target_if_deinit(); 19674 dispatcher_deinit(); 19675 ucfg_mlme_global_deinit(); 19676 } 19677 hdd_component_psoc_open(struct wlan_objmgr_psoc * psoc)19678 QDF_STATUS hdd_component_psoc_open(struct wlan_objmgr_psoc *psoc) 19679 { 19680 QDF_STATUS status; 19681 19682 status = ucfg_mlme_psoc_open(psoc); 19683 if (QDF_IS_STATUS_ERROR(status)) 19684 return status; 19685 19686 status = ucfg_dlm_psoc_open(psoc); 19687 if (QDF_IS_STATUS_ERROR(status)) 19688 goto err_dlm; 19689 19690 status = ucfg_fwol_psoc_open(psoc); 19691 if (QDF_IS_STATUS_ERROR(status)) 19692 goto err_fwol; 19693 19694 status = ucfg_pmo_psoc_open(psoc); 19695 if (QDF_IS_STATUS_ERROR(status)) 19696 goto err_pmo; 19697 19698 status = ucfg_policy_mgr_psoc_open(psoc); 19699 if (QDF_IS_STATUS_ERROR(status)) 19700 goto err_plcy_mgr; 19701 19702 status = ucfg_p2p_psoc_open(psoc); 19703 if (QDF_IS_STATUS_ERROR(status)) 19704 goto err_p2p; 19705 19706 status = ucfg_tdls_psoc_open(psoc); 19707 if (QDF_IS_STATUS_ERROR(status)) 19708 goto err_tdls; 19709 19710 status = ucfg_nan_psoc_open(psoc); 19711 if (QDF_IS_STATUS_ERROR(status)) 19712 goto err_nan; 19713 19714 status = ucfg_twt_psoc_open(psoc); 19715 if (QDF_IS_STATUS_ERROR(status)) 19716 goto err_twt; 19717 19718 status = ucfg_wifi_pos_psoc_open(psoc); 19719 if (QDF_IS_STATUS_ERROR(status)) 19720 goto err_wifi_pos; 19721 19722 status = ucfg_dp_psoc_open(psoc); 19723 if (QDF_IS_STATUS_ERROR(status)) 19724 goto err_dp; 19725 19726 return status; 19727 19728 err_dp: 19729 ucfg_wifi_pos_psoc_close(psoc); 19730 err_wifi_pos: 19731 ucfg_twt_psoc_close(psoc); 19732 err_twt: 19733 ucfg_nan_psoc_close(psoc); 19734 err_nan: 19735 ucfg_tdls_psoc_close(psoc); 19736 err_tdls: 19737 ucfg_p2p_psoc_close(psoc); 19738 err_p2p: 19739 ucfg_policy_mgr_psoc_close(psoc); 19740 err_plcy_mgr: 19741 ucfg_pmo_psoc_close(psoc); 19742 err_pmo: 19743 ucfg_fwol_psoc_close(psoc); 19744 err_fwol: 19745 ucfg_dlm_psoc_close(psoc); 19746 err_dlm: 19747 ucfg_mlme_psoc_close(psoc); 19748 19749 return status; 19750 } 19751 hdd_component_psoc_close(struct wlan_objmgr_psoc * psoc)19752 void hdd_component_psoc_close(struct wlan_objmgr_psoc *psoc) 19753 { 19754 ucfg_dp_psoc_close(psoc); 19755 ucfg_wifi_pos_psoc_close(psoc); 19756 ucfg_twt_psoc_close(psoc); 19757 ucfg_nan_psoc_close(psoc); 19758 ucfg_tdls_psoc_close(psoc); 19759 ucfg_p2p_psoc_close(psoc); 19760 ucfg_policy_mgr_psoc_close(psoc); 19761 ucfg_pmo_psoc_close(psoc); 19762 ucfg_fwol_psoc_close(psoc); 19763 ucfg_dlm_psoc_close(psoc); 19764 ucfg_mlme_psoc_close(psoc); 19765 19766 if (!cds_is_driver_recovering()) 19767 ucfg_crypto_flush_entries(psoc); 19768 } 19769 hdd_component_psoc_enable(struct wlan_objmgr_psoc * psoc)19770 void hdd_component_psoc_enable(struct wlan_objmgr_psoc *psoc) 19771 { 19772 ocb_psoc_enable(psoc); 19773 disa_psoc_enable(psoc); 19774 nan_psoc_enable(psoc); 19775 p2p_psoc_enable(psoc); 19776 ucfg_interop_issues_ap_psoc_enable(psoc); 19777 policy_mgr_psoc_enable(psoc); 19778 ucfg_tdls_psoc_enable(psoc); 19779 ucfg_fwol_psoc_enable(psoc); 19780 ucfg_action_oui_psoc_enable(psoc); 19781 ucfg_ll_sap_psoc_enable(psoc); 19782 } 19783 hdd_component_psoc_disable(struct wlan_objmgr_psoc * psoc)19784 void hdd_component_psoc_disable(struct wlan_objmgr_psoc *psoc) 19785 { 19786 ucfg_ll_sap_psoc_disable(psoc); 19787 ucfg_action_oui_psoc_disable(psoc); 19788 ucfg_fwol_psoc_disable(psoc); 19789 ucfg_tdls_psoc_disable(psoc); 19790 policy_mgr_psoc_disable(psoc); 19791 ucfg_interop_issues_ap_psoc_disable(psoc); 19792 p2p_psoc_disable(psoc); 19793 nan_psoc_disable(psoc); 19794 disa_psoc_disable(psoc); 19795 ocb_psoc_disable(psoc); 19796 } 19797 hdd_component_pdev_open(struct wlan_objmgr_pdev * pdev)19798 QDF_STATUS hdd_component_pdev_open(struct wlan_objmgr_pdev *pdev) 19799 { 19800 return ucfg_mlme_pdev_open(pdev); 19801 } 19802 hdd_component_pdev_close(struct wlan_objmgr_pdev * pdev)19803 void hdd_component_pdev_close(struct wlan_objmgr_pdev *pdev) 19804 { 19805 ucfg_mlme_pdev_close(pdev); 19806 } 19807 hdd_qdf_print_init(void)19808 static QDF_STATUS hdd_qdf_print_init(void) 19809 { 19810 QDF_STATUS status; 19811 int qdf_print_idx; 19812 19813 status = qdf_print_setup(); 19814 if (QDF_IS_STATUS_ERROR(status)) { 19815 pr_err("Failed qdf_print_setup; status:%u\n", status); 19816 return status; 19817 } 19818 19819 qdf_print_idx = qdf_print_ctrl_register(cinfo, NULL, NULL, "MCL_WLAN"); 19820 if (qdf_print_idx < 0) { 19821 pr_err("Failed to register for qdf_print_ctrl\n"); 19822 return QDF_STATUS_E_FAILURE; 19823 } 19824 19825 qdf_set_pidx(qdf_print_idx); 19826 19827 return QDF_STATUS_SUCCESS; 19828 } 19829 hdd_qdf_print_deinit(void)19830 static void hdd_qdf_print_deinit(void) 19831 { 19832 int qdf_pidx = qdf_get_pidx(); 19833 19834 qdf_set_pidx(-1); 19835 qdf_print_ctrl_cleanup(qdf_pidx); 19836 19837 /* currently, no qdf print 'un-setup'*/ 19838 } 19839 hdd_qdf_init(void)19840 static QDF_STATUS hdd_qdf_init(void) 19841 { 19842 QDF_STATUS status; 19843 19844 status = hdd_qdf_print_init(); 19845 if (QDF_IS_STATUS_ERROR(status)) 19846 goto exit; 19847 19848 status = qdf_debugfs_init(); 19849 if (QDF_IS_STATUS_ERROR(status)) { 19850 hdd_err("Failed to init debugfs; status:%u", status); 19851 goto print_deinit; 19852 } 19853 19854 qdf_lock_stats_init(); 19855 qdf_mem_init(); 19856 qdf_delayed_work_feature_init(); 19857 qdf_periodic_work_feature_init(); 19858 qdf_wake_lock_feature_init(); 19859 qdf_mc_timer_manager_init(); 19860 qdf_event_list_init(); 19861 19862 status = qdf_talloc_feature_init(); 19863 if (QDF_IS_STATUS_ERROR(status)) { 19864 hdd_err("Failed to init talloc; status:%u", status); 19865 goto event_deinit; 19866 } 19867 19868 status = qdf_cpuhp_init(); 19869 if (QDF_IS_STATUS_ERROR(status)) { 19870 hdd_err("Failed to init cpuhp; status:%u", status); 19871 goto talloc_deinit; 19872 } 19873 19874 status = qdf_trace_spin_lock_init(); 19875 if (QDF_IS_STATUS_ERROR(status)) { 19876 hdd_err("Failed to init spinlock; status:%u", status); 19877 goto cpuhp_deinit; 19878 } 19879 19880 qdf_trace_init(); 19881 qdf_minidump_init(); 19882 qdf_ssr_driver_dump_init(); 19883 qdf_register_debugcb_init(); 19884 19885 return QDF_STATUS_SUCCESS; 19886 19887 cpuhp_deinit: 19888 qdf_cpuhp_deinit(); 19889 talloc_deinit: 19890 qdf_talloc_feature_deinit(); 19891 event_deinit: 19892 qdf_event_list_destroy(); 19893 qdf_mc_timer_manager_exit(); 19894 qdf_wake_lock_feature_deinit(); 19895 qdf_periodic_work_feature_deinit(); 19896 qdf_delayed_work_feature_deinit(); 19897 qdf_mem_exit(); 19898 qdf_lock_stats_deinit(); 19899 qdf_debugfs_exit(); 19900 print_deinit: 19901 hdd_qdf_print_deinit(); 19902 19903 exit: 19904 return status; 19905 } 19906 hdd_qdf_deinit(void)19907 static void hdd_qdf_deinit(void) 19908 { 19909 /* currently, no debugcb deinit */ 19910 qdf_ssr_driver_dump_deinit(); 19911 qdf_minidump_deinit(); 19912 qdf_trace_deinit(); 19913 19914 /* currently, no trace spinlock deinit */ 19915 19916 qdf_cpuhp_deinit(); 19917 qdf_talloc_feature_deinit(); 19918 qdf_event_list_destroy(); 19919 qdf_mc_timer_manager_exit(); 19920 qdf_wake_lock_feature_deinit(); 19921 qdf_periodic_work_feature_deinit(); 19922 qdf_delayed_work_feature_deinit(); 19923 qdf_mem_exit(); 19924 qdf_lock_stats_deinit(); 19925 qdf_debugfs_exit(); 19926 hdd_qdf_print_deinit(); 19927 } 19928 19929 #ifdef FEATURE_MONITOR_MODE_SUPPORT is_monitor_mode_supported(void)19930 static bool is_monitor_mode_supported(void) 19931 { 19932 return true; 19933 } 19934 #else is_monitor_mode_supported(void)19935 static bool is_monitor_mode_supported(void) 19936 { 19937 pr_err("Monitor mode not supported!"); 19938 return false; 19939 } 19940 #endif 19941 19942 #ifdef WLAN_FEATURE_EPPING is_epping_mode_supported(void)19943 static bool is_epping_mode_supported(void) 19944 { 19945 return true; 19946 } 19947 #else is_epping_mode_supported(void)19948 static bool is_epping_mode_supported(void) 19949 { 19950 pr_err("Epping mode not supported!"); 19951 return false; 19952 } 19953 #endif 19954 19955 #ifdef QCA_WIFI_FTM is_ftm_mode_supported(void)19956 static bool is_ftm_mode_supported(void) 19957 { 19958 return true; 19959 } 19960 #else is_ftm_mode_supported(void)19961 static bool is_ftm_mode_supported(void) 19962 { 19963 pr_err("FTM mode not supported!"); 19964 return false; 19965 } 19966 #endif 19967 19968 /** 19969 * is_con_mode_valid() - check con mode is valid or not 19970 * @mode: global con mode 19971 * 19972 * Return: TRUE on success FALSE on failure 19973 */ is_con_mode_valid(enum QDF_GLOBAL_MODE mode)19974 static bool is_con_mode_valid(enum QDF_GLOBAL_MODE mode) 19975 { 19976 switch (mode) { 19977 case QDF_GLOBAL_MONITOR_MODE: 19978 return is_monitor_mode_supported(); 19979 case QDF_GLOBAL_EPPING_MODE: 19980 return is_epping_mode_supported(); 19981 case QDF_GLOBAL_FTM_MODE: 19982 return is_ftm_mode_supported(); 19983 case QDF_GLOBAL_MISSION_MODE: 19984 return true; 19985 default: 19986 return false; 19987 } 19988 } 19989 hdd_stop_present_mode(struct hdd_context * hdd_ctx,enum QDF_GLOBAL_MODE curr_mode)19990 static void hdd_stop_present_mode(struct hdd_context *hdd_ctx, 19991 enum QDF_GLOBAL_MODE curr_mode) 19992 { 19993 if (hdd_ctx->driver_status == DRIVER_MODULES_CLOSED) 19994 return; 19995 19996 switch (curr_mode) { 19997 case QDF_GLOBAL_MONITOR_MODE: 19998 hdd_info("Release wakelock for monitor mode!"); 19999 qdf_wake_lock_release(&hdd_ctx->monitor_mode_wakelock, 20000 WIFI_POWER_EVENT_WAKELOCK_MONITOR_MODE); 20001 fallthrough; 20002 case QDF_GLOBAL_MISSION_MODE: 20003 case QDF_GLOBAL_FTM_MODE: 20004 hdd_abort_mac_scan_all_adapters(hdd_ctx); 20005 wlan_cfg80211_cleanup_scan_queue(hdd_ctx->pdev, NULL); 20006 hdd_stop_all_adapters(hdd_ctx); 20007 hdd_deinit_all_adapters(hdd_ctx, false); 20008 20009 break; 20010 default: 20011 break; 20012 } 20013 } 20014 hdd_cleanup_present_mode(struct hdd_context * hdd_ctx,enum QDF_GLOBAL_MODE curr_mode)20015 static void hdd_cleanup_present_mode(struct hdd_context *hdd_ctx, 20016 enum QDF_GLOBAL_MODE curr_mode) 20017 { 20018 switch (curr_mode) { 20019 case QDF_GLOBAL_MISSION_MODE: 20020 case QDF_GLOBAL_MONITOR_MODE: 20021 case QDF_GLOBAL_FTM_MODE: 20022 hdd_close_all_adapters(hdd_ctx, false); 20023 break; 20024 case QDF_GLOBAL_EPPING_MODE: 20025 epping_disable(); 20026 epping_close(); 20027 break; 20028 default: 20029 return; 20030 } 20031 } 20032 20033 static int hdd_parse_driver_mode(const char * mode_str,enum QDF_GLOBAL_MODE * out_mode)20034 hdd_parse_driver_mode(const char *mode_str, enum QDF_GLOBAL_MODE *out_mode) 20035 { 20036 QDF_STATUS status; 20037 uint32_t mode; 20038 20039 *out_mode = QDF_GLOBAL_MAX_MODE; 20040 20041 status = qdf_uint32_parse(mode_str, &mode); 20042 if (QDF_IS_STATUS_ERROR(status)) 20043 return qdf_status_to_os_return(status); 20044 20045 if (mode >= QDF_GLOBAL_MAX_MODE) 20046 return -ERANGE; 20047 20048 *out_mode = (enum QDF_GLOBAL_MODE)mode; 20049 20050 return 0; 20051 } 20052 hdd_mode_change_psoc_idle_shutdown(struct device * dev)20053 static int hdd_mode_change_psoc_idle_shutdown(struct device *dev) 20054 { 20055 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 20056 20057 if (!hdd_ctx) 20058 return -EINVAL; 20059 20060 return hdd_wlan_stop_modules(hdd_ctx, true); 20061 } 20062 hdd_mode_change_psoc_idle_restart(struct device * dev)20063 static int hdd_mode_change_psoc_idle_restart(struct device *dev) 20064 { 20065 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 20066 int ret; 20067 20068 if (!hdd_ctx) 20069 return -EINVAL; 20070 ret = hdd_soc_idle_restart_lock(dev); 20071 if (ret) 20072 return ret; 20073 ret = hdd_wlan_start_modules(hdd_ctx, false); 20074 hdd_soc_idle_restart_unlock(); 20075 20076 return ret; 20077 } 20078 20079 /** 20080 * __hdd_driver_mode_change() - Handles a driver mode change 20081 * @hdd_ctx: Pointer to the global HDD context 20082 * @next_mode: the driver mode to transition to 20083 * 20084 * This function is invoked when user updates con_mode using sys entry, 20085 * to initialize and bring-up driver in that specific mode. 20086 * 20087 * Return: Errno 20088 */ __hdd_driver_mode_change(struct hdd_context * hdd_ctx,enum QDF_GLOBAL_MODE next_mode)20089 static int __hdd_driver_mode_change(struct hdd_context *hdd_ctx, 20090 enum QDF_GLOBAL_MODE next_mode) 20091 { 20092 enum QDF_GLOBAL_MODE curr_mode; 20093 int errno; 20094 struct bbm_params param = {0}; 20095 20096 hdd_info("Driver mode changing to %d", next_mode); 20097 20098 errno = wlan_hdd_validate_context(hdd_ctx); 20099 if (errno) 20100 return errno; 20101 20102 if (!is_con_mode_valid(next_mode)) { 20103 hdd_err_rl("Requested driver mode is invalid"); 20104 return -EINVAL; 20105 } 20106 20107 curr_mode = hdd_get_conparam(); 20108 if (curr_mode == next_mode) { 20109 hdd_err_rl("Driver is already in the requested mode"); 20110 return 0; 20111 } 20112 20113 hdd_psoc_idle_timer_stop(hdd_ctx); 20114 20115 /* ensure adapters are stopped */ 20116 hdd_stop_present_mode(hdd_ctx, curr_mode); 20117 20118 if (DRIVER_MODULES_CLOSED != hdd_ctx->driver_status) { 20119 is_mode_change_psoc_idle_shutdown = true; 20120 errno = pld_idle_shutdown(hdd_ctx->parent_dev, 20121 hdd_mode_change_psoc_idle_shutdown); 20122 if (errno) { 20123 is_mode_change_psoc_idle_shutdown = false; 20124 hdd_err("Stop wlan modules failed"); 20125 return errno; 20126 } 20127 } 20128 20129 /* Cleanup present mode before switching to new mode */ 20130 hdd_cleanup_present_mode(hdd_ctx, curr_mode); 20131 20132 hdd_set_conparam(next_mode); 20133 pld_set_mode(next_mode); 20134 20135 qdf_event_reset(&hdd_ctx->regulatory_update_event); 20136 qdf_mutex_acquire(&hdd_ctx->regulatory_status_lock); 20137 hdd_ctx->is_regulatory_update_in_progress = true; 20138 qdf_mutex_release(&hdd_ctx->regulatory_status_lock); 20139 20140 errno = pld_idle_restart(hdd_ctx->parent_dev, 20141 hdd_mode_change_psoc_idle_restart); 20142 if (errno) { 20143 hdd_err("Start wlan modules failed: %d", errno); 20144 return errno; 20145 } 20146 20147 errno = hdd_open_adapters_for_mode(hdd_ctx, next_mode); 20148 if (errno) { 20149 hdd_err("Failed to open adapters"); 20150 return errno; 20151 } 20152 20153 if (next_mode == QDF_GLOBAL_MONITOR_MODE) { 20154 struct hdd_adapter *adapter = 20155 hdd_get_adapter(hdd_ctx, QDF_MONITOR_MODE); 20156 20157 QDF_BUG(adapter); 20158 if (!adapter) { 20159 hdd_err("Failed to get monitor adapter"); 20160 return -EINVAL; 20161 } 20162 20163 errno = hdd_start_adapter(adapter, false); 20164 if (errno) { 20165 hdd_err("Failed to start monitor adapter"); 20166 return errno; 20167 } 20168 20169 hdd_info("Acquire wakelock for monitor mode"); 20170 qdf_wake_lock_acquire(&hdd_ctx->monitor_mode_wakelock, 20171 WIFI_POWER_EVENT_WAKELOCK_MONITOR_MODE); 20172 } 20173 20174 /* con_mode is a global module parameter */ 20175 con_mode = next_mode; 20176 hdd_info("Driver mode successfully changed to %d", next_mode); 20177 20178 param.policy = BBM_DRIVER_MODE_POLICY; 20179 param.policy_info.driver_mode = con_mode; 20180 ucfg_dp_bbm_apply_independent_policy(hdd_ctx->psoc, ¶m); 20181 20182 return 0; 20183 } 20184 hdd_pre_mode_change(enum QDF_GLOBAL_MODE mode)20185 static void hdd_pre_mode_change(enum QDF_GLOBAL_MODE mode) 20186 { 20187 struct osif_psoc_sync *psoc_sync; 20188 struct hdd_context *hdd_ctx; 20189 int errno; 20190 enum QDF_GLOBAL_MODE curr_mode; 20191 20192 curr_mode = hdd_get_conparam(); 20193 if (curr_mode != QDF_GLOBAL_MISSION_MODE) 20194 return; 20195 20196 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 20197 errno = wlan_hdd_validate_context(hdd_ctx); 20198 if (errno) 20199 return; 20200 20201 errno = osif_psoc_sync_op_start(hdd_ctx->parent_dev, &psoc_sync); 20202 if (errno) { 20203 hdd_err("psoc op start failed"); 20204 return; 20205 } 20206 20207 hdd_debug("cleanup scan queue"); 20208 if (hdd_ctx && hdd_ctx->pdev) 20209 wlan_cfg80211_cleanup_scan_queue(hdd_ctx->pdev, NULL); 20210 20211 osif_psoc_sync_op_stop(psoc_sync); 20212 } 20213 hdd_driver_mode_change(enum QDF_GLOBAL_MODE mode)20214 static int hdd_driver_mode_change(enum QDF_GLOBAL_MODE mode) 20215 { 20216 struct osif_driver_sync *driver_sync; 20217 struct hdd_context *hdd_ctx; 20218 QDF_STATUS status; 20219 int errno; 20220 20221 hdd_enter(); 20222 20223 hdd_pre_mode_change(mode); 20224 20225 status = osif_driver_sync_trans_start_wait(&driver_sync); 20226 if (QDF_IS_STATUS_ERROR(status)) { 20227 hdd_err("Failed to start 'mode change'; status:%u", status); 20228 errno = qdf_status_to_os_return(status); 20229 goto exit; 20230 } 20231 20232 osif_driver_sync_wait_for_ops(driver_sync); 20233 20234 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 20235 errno = wlan_hdd_validate_context(hdd_ctx); 20236 if (errno) 20237 goto trans_stop; 20238 20239 errno = __hdd_driver_mode_change(hdd_ctx, mode); 20240 20241 trans_stop: 20242 osif_driver_sync_trans_stop(driver_sync); 20243 20244 exit: 20245 hdd_exit(); 20246 20247 return errno; 20248 } 20249 hdd_set_con_mode(enum QDF_GLOBAL_MODE mode)20250 static int hdd_set_con_mode(enum QDF_GLOBAL_MODE mode) 20251 { 20252 con_mode = mode; 20253 20254 return 0; 20255 } 20256 20257 static int (*hdd_set_con_mode_cb)(enum QDF_GLOBAL_MODE mode) = hdd_set_con_mode; 20258 hdd_driver_mode_change_register(void)20259 static void hdd_driver_mode_change_register(void) 20260 { 20261 hdd_set_con_mode_cb = hdd_driver_mode_change; 20262 } 20263 hdd_driver_mode_change_unregister(void)20264 static void hdd_driver_mode_change_unregister(void) 20265 { 20266 hdd_set_con_mode_cb = hdd_set_con_mode; 20267 } 20268 con_mode_handler(const char * kmessage,const struct kernel_param * kp)20269 static int con_mode_handler(const char *kmessage, const struct kernel_param *kp) 20270 { 20271 enum QDF_GLOBAL_MODE mode; 20272 int errno; 20273 20274 errno = hdd_parse_driver_mode(kmessage, &mode); 20275 if (errno) { 20276 hdd_err_rl("Failed to parse driver mode '%s'", kmessage); 20277 return errno; 20278 } 20279 20280 return hdd_set_con_mode_cb(mode); 20281 } 20282 20283 /* 20284 * If the wlan_hdd_register_driver will return an error 20285 * if the wlan driver tries to register with the 20286 * platform driver before cnss_probe is completed. 20287 * Depending on the error code, the wlan driver waits 20288 * and retries to register. 20289 */ 20290 20291 /* Max number of retries (arbitrary)*/ 20292 #define HDD_MAX_PLD_REGISTER_RETRY (50) 20293 20294 /* Max amount of time we sleep before each retry */ 20295 #define HDD_PLD_REGISTER_FAIL_SLEEP_DURATION (100) 20296 hdd_register_driver_retry(void)20297 static int hdd_register_driver_retry(void) 20298 { 20299 int count = 0; 20300 int errno; 20301 20302 while (true) { 20303 errno = wlan_hdd_register_driver(); 20304 if (errno != -EAGAIN) 20305 return errno; 20306 hdd_nofl_info("Retry Platform Driver Registration; errno:%d count:%d", 20307 errno, count); 20308 if (++count == HDD_MAX_PLD_REGISTER_RETRY) 20309 return errno; 20310 msleep(HDD_PLD_REGISTER_FAIL_SLEEP_DURATION); 20311 continue; 20312 } 20313 20314 return errno; 20315 } 20316 20317 /** 20318 * hdd_create_wifi_feature_interface() - Create wifi feature interface 20319 * 20320 * Return: none 20321 */ hdd_create_wifi_feature_interface(void)20322 static void hdd_create_wifi_feature_interface(void) 20323 { 20324 hdd_sysfs_create_wifi_root_obj(); 20325 hdd_create_wifi_feature_interface_sysfs_file(); 20326 } 20327 hdd_driver_load(void)20328 int hdd_driver_load(void) 20329 { 20330 struct osif_driver_sync *driver_sync; 20331 QDF_STATUS status; 20332 int errno; 20333 bool soft_load; 20334 20335 pr_info("%s: Loading driver v%s\n", WLAN_MODULE_NAME, 20336 g_wlan_driver_version); 20337 hdd_place_marker(NULL, "START LOADING", NULL); 20338 20339 status = hdd_qdf_init(); 20340 if (QDF_IS_STATUS_ERROR(status)) { 20341 errno = qdf_status_to_os_return(status); 20342 goto exit; 20343 } 20344 20345 osif_sync_init(); 20346 20347 status = osif_driver_sync_create_and_trans(&driver_sync); 20348 if (QDF_IS_STATUS_ERROR(status)) { 20349 hdd_err("Failed to init driver sync; status:%u", status); 20350 errno = qdf_status_to_os_return(status); 20351 goto sync_deinit; 20352 } 20353 20354 errno = hdd_init(); 20355 if (errno) { 20356 hdd_err("Failed to init HDD; errno:%d", errno); 20357 goto trans_stop; 20358 } 20359 20360 status = hdd_component_cb_init(); 20361 if (QDF_IS_STATUS_ERROR(status)) { 20362 hdd_err("Failed to init component cb; status:%u", status); 20363 errno = qdf_status_to_os_return(status); 20364 goto hdd_deinit; 20365 } 20366 20367 status = hdd_component_init(); 20368 if (QDF_IS_STATUS_ERROR(status)) { 20369 hdd_err("Failed to init components; status:%u", status); 20370 errno = qdf_status_to_os_return(status); 20371 goto comp_cb_deinit; 20372 } 20373 20374 status = qdf_wake_lock_create(&wlan_wake_lock, "wlan"); 20375 if (QDF_IS_STATUS_ERROR(status)) { 20376 hdd_err("Failed to create wake lock; status:%u", status); 20377 errno = qdf_status_to_os_return(status); 20378 goto comp_deinit; 20379 } 20380 20381 hdd_set_conparam(con_mode); 20382 20383 errno = pld_init(); 20384 if (errno) { 20385 hdd_err("Failed to init PLD; errno:%d", errno); 20386 goto wakelock_destroy; 20387 } 20388 20389 /* driver mode pass to cnss2 platform driver*/ 20390 errno = pld_set_mode(con_mode); 20391 if (errno) 20392 hdd_err("Failed to set mode in PLD; errno:%d", errno); 20393 20394 hdd_driver_mode_change_register(); 20395 20396 osif_driver_sync_register(driver_sync); 20397 osif_driver_sync_trans_stop(driver_sync); 20398 20399 /* psoc probe can happen in registration; do after 'load' transition */ 20400 errno = hdd_register_driver_retry(); 20401 if (errno) { 20402 hdd_err("Failed to register driver; errno:%d", errno); 20403 goto pld_deinit; 20404 } 20405 20406 /* If a soft unload of driver is done, we don't call 20407 * wlan_hdd_state_ctrl_param_destroy() to maintain sync 20408 * with userspace. In Symmetry, during soft load, avoid 20409 * calling wlan_hdd_state_ctrl_param_create(). 20410 */ 20411 soft_load = hdd_get_wlan_driver_status(); 20412 if (soft_load) 20413 goto out; 20414 20415 errno = wlan_hdd_state_ctrl_param_create(); 20416 if (errno) { 20417 hdd_err("Failed to create ctrl param; errno:%d", errno); 20418 goto unregister_driver; 20419 } 20420 hdd_create_wifi_feature_interface(); 20421 out: 20422 hdd_debug("%s: driver loaded", WLAN_MODULE_NAME); 20423 hdd_place_marker(NULL, "DRIVER LOADED", NULL); 20424 20425 return 0; 20426 20427 unregister_driver: 20428 wlan_hdd_unregister_driver(); 20429 pld_deinit: 20430 status = osif_driver_sync_trans_start(&driver_sync); 20431 QDF_BUG(QDF_IS_STATUS_SUCCESS(status)); 20432 20433 osif_driver_sync_unregister(); 20434 if (driver_sync) 20435 osif_driver_sync_wait_for_ops(driver_sync); 20436 20437 hdd_driver_mode_change_unregister(); 20438 pld_deinit(); 20439 20440 hdd_start_complete(errno); 20441 /* Wait for any ref taken on /dev/wlan to be released */ 20442 while (qdf_atomic_read(&wlan_hdd_state_fops_ref)) 20443 ; 20444 wakelock_destroy: 20445 qdf_wake_lock_destroy(&wlan_wake_lock); 20446 comp_deinit: 20447 hdd_component_deinit(); 20448 comp_cb_deinit: 20449 hdd_component_cb_deinit(); 20450 hdd_deinit: 20451 hdd_deinit(); 20452 trans_stop: 20453 if (driver_sync) { 20454 osif_driver_sync_trans_stop(driver_sync); 20455 osif_driver_sync_destroy(driver_sync); 20456 } 20457 sync_deinit: 20458 osif_sync_deinit(); 20459 hdd_qdf_deinit(); 20460 20461 exit: 20462 return errno; 20463 } 20464 20465 #ifdef FEATURE_WLAN_RESIDENT_DRIVER 20466 EXPORT_SYMBOL(hdd_driver_load); 20467 #endif 20468 20469 /** 20470 * hdd_distroy_wifi_feature_interface() - Distroy wifi feature interface 20471 * 20472 * Return: none 20473 */ hdd_distroy_wifi_feature_interface(void)20474 static void hdd_distroy_wifi_feature_interface(void) 20475 { 20476 hdd_destroy_wifi_feature_interface_sysfs_file(); 20477 hdd_sysfs_destroy_wifi_root_obj(); 20478 } 20479 hdd_driver_unload(void)20480 void hdd_driver_unload(void) 20481 { 20482 struct osif_driver_sync *driver_sync; 20483 struct hdd_context *hdd_ctx; 20484 QDF_STATUS status; 20485 void *hif_ctx; 20486 bool soft_unload; 20487 20488 soft_unload = hdd_get_wlan_driver_status(); 20489 if (soft_unload) { 20490 pr_info("%s: Soft Unloading driver v%s\n", WLAN_MODULE_NAME, 20491 QWLAN_VERSIONSTR); 20492 } else { 20493 pr_info("%s: Hard Unloading driver v%s\n", WLAN_MODULE_NAME, 20494 QWLAN_VERSIONSTR); 20495 } 20496 20497 hdd_place_marker(NULL, "START UNLOADING", NULL); 20498 20499 /* 20500 * Wait for any trans to complete and then start the driver trans 20501 * for the unload. This will ensure that the driver trans proceeds only 20502 * after all trans have been completed. As a part of this trans, set 20503 * the driver load/unload flag to further ensure that any upcoming 20504 * trans are rejected via wlan_hdd_validate_context. 20505 */ 20506 status = osif_driver_sync_trans_start_wait(&driver_sync); 20507 if (QDF_IS_STATUS_ERROR(status) && status != -ETIMEDOUT) { 20508 QDF_BUG(QDF_IS_STATUS_SUCCESS(status)); 20509 hdd_err("Unable to unload wlan; status:%u", status); 20510 hdd_place_marker(NULL, "UNLOAD FAILURE", NULL); 20511 return; 20512 } 20513 20514 hif_ctx = cds_get_context(QDF_MODULE_ID_HIF); 20515 if (hif_ctx) { 20516 /* 20517 * Trigger runtime sync resume before setting unload in progress 20518 * such that resume can happen successfully 20519 */ 20520 qdf_rtpm_sync_resume(); 20521 } 20522 20523 cds_set_driver_loaded(false); 20524 cds_set_unload_in_progress(true); 20525 20526 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 20527 if (hdd_ctx) { 20528 hdd_psoc_idle_timer_stop(hdd_ctx); 20529 /* 20530 * Runtime PM sync resume may have started the bus bandwidth 20531 * periodic work hence stop it. 20532 */ 20533 ucfg_dp_bus_bw_compute_timer_stop(hdd_ctx->psoc); 20534 } 20535 20536 /* 20537 * Stop the trans before calling unregister_driver as that involves a 20538 * call to pld_remove which in itself is a psoc transaction 20539 */ 20540 if (driver_sync) 20541 osif_driver_sync_trans_stop(driver_sync); 20542 20543 hdd_distroy_wifi_feature_interface(); 20544 if (!soft_unload) 20545 wlan_hdd_state_ctrl_param_destroy(); 20546 20547 /* trigger SoC remove */ 20548 wlan_hdd_unregister_driver(); 20549 20550 status = osif_driver_sync_trans_start_wait(&driver_sync); 20551 if (QDF_IS_STATUS_ERROR(status) && status != -ETIMEDOUT) { 20552 QDF_BUG(QDF_IS_STATUS_SUCCESS(status)); 20553 hdd_err("Unable to unload wlan; status:%u", status); 20554 hdd_place_marker(NULL, "UNLOAD FAILURE", NULL); 20555 return; 20556 } 20557 20558 osif_driver_sync_unregister(); 20559 if (driver_sync) 20560 osif_driver_sync_wait_for_ops(driver_sync); 20561 20562 hdd_driver_mode_change_unregister(); 20563 pld_deinit(); 20564 hdd_set_conparam(0); 20565 qdf_wake_lock_destroy(&wlan_wake_lock); 20566 hdd_component_deinit(); 20567 hdd_component_cb_deinit(); 20568 hdd_deinit(); 20569 20570 if (driver_sync) { 20571 osif_driver_sync_trans_stop(driver_sync); 20572 osif_driver_sync_destroy(driver_sync); 20573 } 20574 osif_sync_deinit(); 20575 20576 hdd_qdf_deinit(); 20577 hdd_place_marker(NULL, "UNLOAD DONE", NULL); 20578 } 20579 20580 #ifdef FEATURE_WLAN_RESIDENT_DRIVER 20581 EXPORT_SYMBOL(hdd_driver_unload); 20582 #endif 20583 20584 #ifndef MODULE 20585 /** 20586 * wlan_boot_cb() - Wlan boot callback 20587 * @kobj: object whose directory we're creating the link in. 20588 * @attr: attribute the user is interacting with 20589 * @buf: the buffer containing the user data 20590 * @count: number of bytes in the buffer 20591 * 20592 * This callback is invoked when the fs is ready to start the 20593 * wlan driver initialization. 20594 * 20595 * Return: 'count' on success or a negative error code in case of failure 20596 */ wlan_boot_cb(struct kobject * kobj,struct kobj_attribute * attr,const char * buf,size_t count)20597 static ssize_t wlan_boot_cb(struct kobject *kobj, 20598 struct kobj_attribute *attr, 20599 const char *buf, 20600 size_t count) 20601 { 20602 20603 if (wlan_loader->loaded_state) { 20604 hdd_err("wlan driver already initialized"); 20605 return -EALREADY; 20606 } 20607 20608 if (hdd_driver_load()) 20609 return -EIO; 20610 20611 wlan_loader->loaded_state = MODULE_INITIALIZED; 20612 20613 return count; 20614 } 20615 20616 /** 20617 * hdd_sysfs_cleanup() - cleanup sysfs 20618 * 20619 * Return: None 20620 * 20621 */ hdd_sysfs_cleanup(void)20622 static void hdd_sysfs_cleanup(void) 20623 { 20624 /* remove from group */ 20625 if (wlan_loader->boot_wlan_obj && wlan_loader->attr_group) 20626 sysfs_remove_group(wlan_loader->boot_wlan_obj, 20627 wlan_loader->attr_group); 20628 20629 /* unlink the object from parent */ 20630 kobject_del(wlan_loader->boot_wlan_obj); 20631 20632 /* free the object */ 20633 kobject_put(wlan_loader->boot_wlan_obj); 20634 20635 kfree(wlan_loader->attr_group); 20636 kfree(wlan_loader); 20637 20638 wlan_loader = NULL; 20639 } 20640 20641 /** 20642 * wlan_init_sysfs() - Creates the sysfs to be invoked when the fs is 20643 * ready 20644 * 20645 * This is creates the syfs entry boot_wlan. Which shall be invoked 20646 * when the filesystem is ready. 20647 * 20648 * QDF API cannot be used here since this function is called even before 20649 * initializing WLAN driver. 20650 * 20651 * Return: 0 for success, errno on failure 20652 */ wlan_init_sysfs(void)20653 static int wlan_init_sysfs(void) 20654 { 20655 int ret = -ENOMEM; 20656 20657 wlan_loader = kzalloc(sizeof(*wlan_loader), GFP_KERNEL); 20658 if (!wlan_loader) 20659 return -ENOMEM; 20660 20661 wlan_loader->boot_wlan_obj = NULL; 20662 wlan_loader->attr_group = kzalloc(sizeof(*(wlan_loader->attr_group)), 20663 GFP_KERNEL); 20664 if (!wlan_loader->attr_group) 20665 goto error_return; 20666 20667 wlan_loader->loaded_state = 0; 20668 wlan_loader->attr_group->attrs = attrs; 20669 20670 wlan_loader->boot_wlan_obj = kobject_create_and_add(WLAN_LOADER_NAME, 20671 kernel_kobj); 20672 if (!wlan_loader->boot_wlan_obj) { 20673 hdd_err("sysfs create and add failed"); 20674 goto error_return; 20675 } 20676 20677 ret = sysfs_create_group(wlan_loader->boot_wlan_obj, 20678 wlan_loader->attr_group); 20679 if (ret) { 20680 hdd_err("sysfs create group failed; errno:%d", ret); 20681 goto error_return; 20682 } 20683 20684 return 0; 20685 20686 error_return: 20687 hdd_sysfs_cleanup(); 20688 20689 return ret; 20690 } 20691 20692 /** 20693 * wlan_deinit_sysfs() - Removes the sysfs created to initialize the wlan 20694 * 20695 * Return: 0 on success or errno on failure 20696 */ wlan_deinit_sysfs(void)20697 static int wlan_deinit_sysfs(void) 20698 { 20699 if (!wlan_loader) { 20700 hdd_err("wlan_loader is null"); 20701 return -EINVAL; 20702 } 20703 20704 hdd_sysfs_cleanup(); 20705 return 0; 20706 } 20707 20708 #endif /* MODULE */ 20709 20710 #ifdef MODULE 20711 /** 20712 * hdd_module_init() - Module init helper 20713 * 20714 * Module init helper function used by both module and static driver. 20715 * 20716 * Return: 0 for success, errno on failure 20717 */ 20718 #ifdef FEATURE_WLAN_RESIDENT_DRIVER hdd_module_init(void)20719 static int hdd_module_init(void) 20720 { 20721 return 0; 20722 } 20723 #else hdd_module_init(void)20724 static int hdd_module_init(void) 20725 { 20726 if (hdd_driver_load()) 20727 return -EINVAL; 20728 20729 return 0; 20730 } 20731 #endif 20732 #else hdd_module_init(void)20733 static int __init hdd_module_init(void) 20734 { 20735 int ret = -EINVAL; 20736 20737 ret = wlan_init_sysfs(); 20738 if (ret) 20739 hdd_err("Failed to create sysfs entry"); 20740 20741 return ret; 20742 } 20743 #endif 20744 20745 20746 #ifdef MODULE 20747 /** 20748 * hdd_module_exit() - Exit function 20749 * 20750 * This is the driver exit point (invoked when module is unloaded using rmmod) 20751 * 20752 * Return: None 20753 */ 20754 #ifdef FEATURE_WLAN_RESIDENT_DRIVER hdd_module_exit(void)20755 static void __exit hdd_module_exit(void) 20756 { 20757 } 20758 #else hdd_module_exit(void)20759 static void __exit hdd_module_exit(void) 20760 { 20761 hdd_driver_unload(); 20762 } 20763 #endif 20764 #else hdd_module_exit(void)20765 static void __exit hdd_module_exit(void) 20766 { 20767 hdd_driver_unload(); 20768 wlan_deinit_sysfs(); 20769 } 20770 #endif 20771 fwpath_changed_handler(const char * kmessage,const struct kernel_param * kp)20772 static int fwpath_changed_handler(const char *kmessage, 20773 const struct kernel_param *kp) 20774 { 20775 return param_set_copystring(kmessage, kp); 20776 } 20777 con_mode_handler_ftm(const char * kmessage,const struct kernel_param * kp)20778 static int con_mode_handler_ftm(const char *kmessage, 20779 const struct kernel_param *kp) 20780 { 20781 int ret; 20782 20783 ret = param_set_int(kmessage, kp); 20784 20785 if (cds_is_driver_loaded() || cds_is_load_or_unload_in_progress()) { 20786 pr_err("Driver already loaded or load/unload in progress"); 20787 return -ENOTSUPP; 20788 } 20789 20790 if (con_mode_ftm != QDF_GLOBAL_FTM_MODE) { 20791 pr_err("Only FTM mode supported!"); 20792 return -ENOTSUPP; 20793 } 20794 20795 hdd_set_conparam(con_mode_ftm); 20796 con_mode = con_mode_ftm; 20797 20798 return ret; 20799 } 20800 20801 #ifdef WLAN_FEATURE_EPPING con_mode_handler_epping(const char * kmessage,const struct kernel_param * kp)20802 static int con_mode_handler_epping(const char *kmessage, 20803 const struct kernel_param *kp) 20804 { 20805 int ret; 20806 20807 ret = param_set_int(kmessage, kp); 20808 20809 if (con_mode_epping != QDF_GLOBAL_EPPING_MODE) { 20810 pr_err("Only EPPING mode supported!"); 20811 return -ENOTSUPP; 20812 } 20813 20814 hdd_set_conparam(con_mode_epping); 20815 con_mode = con_mode_epping; 20816 20817 return ret; 20818 } 20819 #endif 20820 20821 /** 20822 * hdd_get_conparam() - driver exit point 20823 * 20824 * This is the driver exit point (invoked when module is unloaded using rmmod) 20825 * 20826 * Return: enum QDF_GLOBAL_MODE 20827 */ hdd_get_conparam(void)20828 enum QDF_GLOBAL_MODE hdd_get_conparam(void) 20829 { 20830 return (enum QDF_GLOBAL_MODE) curr_con_mode; 20831 } 20832 hdd_set_conparam(int32_t con_param)20833 void hdd_set_conparam(int32_t con_param) 20834 { 20835 curr_con_mode = con_param; 20836 } 20837 20838 /** 20839 * hdd_svc_fw_crashed_ind() - API to send FW CRASHED IND to Userspace 20840 * 20841 * Return: void 20842 */ hdd_svc_fw_crashed_ind(void)20843 static void hdd_svc_fw_crashed_ind(void) 20844 { 20845 struct hdd_context *hdd_ctx; 20846 20847 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 20848 20849 hdd_ctx ? wlan_hdd_send_svc_nlink_msg(hdd_ctx->radio_index, 20850 WLAN_SVC_FW_CRASHED_IND, 20851 NULL, 0) : 0; 20852 } 20853 20854 /** 20855 * hdd_update_ol_config - API to update ol configuration parameters 20856 * @hdd_ctx: HDD context 20857 * 20858 * Return: void 20859 */ hdd_update_ol_config(struct hdd_context * hdd_ctx)20860 static void hdd_update_ol_config(struct hdd_context *hdd_ctx) 20861 { 20862 struct ol_config_info cfg = {0}; 20863 struct ol_context *ol_ctx = cds_get_context(QDF_MODULE_ID_BMI); 20864 bool self_recovery = false; 20865 QDF_STATUS status; 20866 20867 if (!ol_ctx) 20868 return; 20869 20870 status = ucfg_mlme_get_self_recovery(hdd_ctx->psoc, &self_recovery); 20871 if (QDF_IS_STATUS_ERROR(status)) 20872 hdd_err("Failed to get self recovery ini config"); 20873 20874 cfg.enable_self_recovery = self_recovery; 20875 cfg.enable_uart_print = hdd_ctx->config->enablefwprint; 20876 cfg.enable_fw_log = hdd_ctx->config->enable_fw_log; 20877 cfg.enable_ramdump_collection = hdd_ctx->config->is_ramdump_enabled; 20878 cfg.enable_lpass_support = hdd_lpass_is_supported(hdd_ctx); 20879 20880 ol_init_ini_config(ol_ctx, &cfg); 20881 ol_set_fw_crashed_cb(ol_ctx, hdd_svc_fw_crashed_ind); 20882 } 20883 20884 #ifdef FEATURE_RUNTIME_PM 20885 /** 20886 * hdd_populate_runtime_cfg() - populate runtime configuration 20887 * @hdd_ctx: hdd context 20888 * @cfg: pointer to the configuration memory being populated 20889 * 20890 * Return: void 20891 */ hdd_populate_runtime_cfg(struct hdd_context * hdd_ctx,struct hif_config_info * cfg)20892 static void hdd_populate_runtime_cfg(struct hdd_context *hdd_ctx, 20893 struct hif_config_info *cfg) 20894 { 20895 cfg->enable_runtime_pm = hdd_ctx->config->runtime_pm; 20896 cfg->runtime_pm_delay = 20897 ucfg_pmo_get_runtime_pm_delay(hdd_ctx->psoc); 20898 } 20899 #else hdd_populate_runtime_cfg(struct hdd_context * hdd_ctx,struct hif_config_info * cfg)20900 static void hdd_populate_runtime_cfg(struct hdd_context *hdd_ctx, 20901 struct hif_config_info *cfg) 20902 { 20903 } 20904 #endif 20905 20906 #ifdef FEATURE_ENABLE_CE_DP_IRQ_AFFINE 20907 /** 20908 * hdd_populate_ce_dp_irq_affine_cfg() - populate ce irq affine configuration 20909 * @hdd_ctx: hdd context 20910 * @cfg: pointer to the configuration memory being populated 20911 * 20912 * Return: void 20913 */ hdd_populate_ce_dp_irq_affine_cfg(struct hdd_context * hdd_ctx,struct hif_config_info * cfg)20914 static void hdd_populate_ce_dp_irq_affine_cfg(struct hdd_context *hdd_ctx, 20915 struct hif_config_info *cfg) 20916 { 20917 cfg->enable_ce_dp_irq_affine = cfg_get(hdd_ctx->psoc, 20918 CFG_ENABLE_CE_DP_IRQ_AFFINE); 20919 } 20920 #else hdd_populate_ce_dp_irq_affine_cfg(struct hdd_context * hdd_ctx,struct hif_config_info * cfg)20921 static void hdd_populate_ce_dp_irq_affine_cfg(struct hdd_context *hdd_ctx, 20922 struct hif_config_info *cfg) 20923 { 20924 } 20925 #endif 20926 20927 /** 20928 * hdd_update_hif_config - API to update HIF configuration parameters 20929 * @hdd_ctx: HDD Context 20930 * 20931 * Return: void 20932 */ hdd_update_hif_config(struct hdd_context * hdd_ctx)20933 static void hdd_update_hif_config(struct hdd_context *hdd_ctx) 20934 { 20935 struct hif_opaque_softc *scn = cds_get_context(QDF_MODULE_ID_HIF); 20936 struct hif_config_info cfg = {0}; 20937 bool prevent_link_down = false; 20938 bool self_recovery = false; 20939 QDF_STATUS status; 20940 20941 if (!scn) 20942 return; 20943 20944 status = ucfg_mlme_get_prevent_link_down(hdd_ctx->psoc, 20945 &prevent_link_down); 20946 if (QDF_IS_STATUS_ERROR(status)) 20947 hdd_err("Failed to get prevent_link_down config"); 20948 20949 status = ucfg_mlme_get_self_recovery(hdd_ctx->psoc, &self_recovery); 20950 if (QDF_IS_STATUS_ERROR(status)) 20951 hdd_err("Failed to get self recovery ini config"); 20952 20953 cfg.enable_self_recovery = self_recovery; 20954 hdd_populate_runtime_cfg(hdd_ctx, &cfg); 20955 cfg.rx_softirq_max_yield_duration_ns = 20956 ucfg_dp_get_rx_softirq_yield_duration(hdd_ctx->psoc); 20957 hdd_populate_ce_dp_irq_affine_cfg(hdd_ctx, &cfg); 20958 20959 hif_init_ini_config(scn, &cfg); 20960 hif_set_enable_rpm(scn); 20961 20962 if (prevent_link_down) 20963 hif_vote_link_up(scn); 20964 } 20965 20966 /** 20967 * hdd_update_dp_config() - Propagate config parameters to Lithium 20968 * datapath 20969 * @hdd_ctx: HDD Context 20970 * 20971 * Return: 0 for success/errno for failure 20972 */ hdd_update_dp_config(struct hdd_context * hdd_ctx)20973 static int hdd_update_dp_config(struct hdd_context *hdd_ctx) 20974 { 20975 struct wlan_dp_user_config dp_cfg; 20976 QDF_STATUS status; 20977 20978 dp_cfg.ipa_enable = ucfg_ipa_is_enabled(); 20979 dp_cfg.arp_connectivity_map = CONNECTIVITY_CHECK_SET_ARP; 20980 20981 status = ucfg_dp_update_config(hdd_ctx->psoc, &dp_cfg); 20982 if (status != QDF_STATUS_SUCCESS) { 20983 hdd_err("failed DP PSOC configuration update"); 20984 return -EINVAL; 20985 } 20986 20987 return 0; 20988 } 20989 20990 /** 20991 * hdd_update_config() - Initialize driver per module ini parameters 20992 * @hdd_ctx: HDD Context 20993 * 20994 * API is used to initialize all driver per module configuration parameters 20995 * Return: 0 for success, errno for failure 20996 */ hdd_update_config(struct hdd_context * hdd_ctx)20997 int hdd_update_config(struct hdd_context *hdd_ctx) 20998 { 20999 int ret; 21000 21001 if (ucfg_pmo_is_ns_offloaded(hdd_ctx->psoc)) 21002 hdd_ctx->ns_offload_enable = true; 21003 21004 hdd_update_ol_config(hdd_ctx); 21005 hdd_update_hif_config(hdd_ctx); 21006 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) 21007 ret = hdd_update_cds_config_ftm(hdd_ctx); 21008 else 21009 ret = hdd_update_cds_config(hdd_ctx); 21010 ret = hdd_update_user_config(hdd_ctx); 21011 21012 hdd_update_regdb_offload_config(hdd_ctx); 21013 21014 return ret; 21015 } 21016 21017 /** 21018 * hdd_update_pmo_config - API to update pmo configuration parameters 21019 * @hdd_ctx: HDD context 21020 * 21021 * Return: void 21022 */ hdd_update_pmo_config(struct hdd_context * hdd_ctx)21023 static int hdd_update_pmo_config(struct hdd_context *hdd_ctx) 21024 { 21025 struct pmo_psoc_cfg psoc_cfg = {0}; 21026 QDF_STATUS status; 21027 enum pmo_wow_enable_type wow_enable; 21028 21029 ucfg_pmo_get_psoc_config(hdd_ctx->psoc, &psoc_cfg); 21030 21031 /* 21032 * Value of hdd_ctx->wowEnable can be, 21033 * 0 - Disable both magic pattern match and pattern byte match. 21034 * 1 - Enable magic pattern match on all interfaces. 21035 * 2 - Enable pattern byte match on all interfaces. 21036 * 3 - Enable both magic pattern and pattern byte match on 21037 * all interfaces. 21038 */ 21039 wow_enable = ucfg_pmo_get_wow_enable(hdd_ctx->psoc); 21040 psoc_cfg.magic_ptrn_enable = (wow_enable & 0x01) ? true : false; 21041 psoc_cfg.ptrn_match_enable_all_vdev = 21042 (wow_enable & 0x02) ? true : false; 21043 psoc_cfg.ap_arpns_support = hdd_ctx->ap_arpns_support; 21044 psoc_cfg.d0_wow_supported = wma_d0_wow_is_supported(); 21045 ucfg_mlme_get_sap_max_modulated_dtim(hdd_ctx->psoc, 21046 &psoc_cfg.sta_max_li_mod_dtim); 21047 21048 hdd_lpass_populate_pmo_config(&psoc_cfg, hdd_ctx); 21049 21050 status = ucfg_pmo_update_psoc_config(hdd_ctx->psoc, &psoc_cfg); 21051 if (QDF_IS_STATUS_ERROR(status)) 21052 hdd_err("failed pmo psoc configuration; status:%d", status); 21053 21054 return qdf_status_to_os_return(status); 21055 } 21056 hdd_update_ie_allowlist_attr(struct probe_req_allowlist_attr * ie_allowlist,struct hdd_context * hdd_ctx)21057 void hdd_update_ie_allowlist_attr(struct probe_req_allowlist_attr *ie_allowlist, 21058 struct hdd_context *hdd_ctx) 21059 { 21060 struct wlan_fwol_ie_allowlist allowlist = {0}; 21061 struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc; 21062 QDF_STATUS status; 21063 bool is_ie_allowlist_enable = false; 21064 uint8_t i = 0; 21065 21066 status = ucfg_fwol_get_ie_allowlist(psoc, &is_ie_allowlist_enable); 21067 if (QDF_IS_STATUS_ERROR(status)) { 21068 hdd_err("Unable to get IE allowlist param"); 21069 return; 21070 } 21071 21072 ie_allowlist->allow_list = is_ie_allowlist_enable; 21073 if (!ie_allowlist->allow_list) 21074 return; 21075 21076 status = ucfg_fwol_get_all_allowlist_params(psoc, &allowlist); 21077 if (QDF_IS_STATUS_ERROR(status)) { 21078 hdd_err("Unable to get all allowlist params"); 21079 return; 21080 } 21081 21082 ie_allowlist->ie_bitmap[0] = allowlist.ie_bitmap_0; 21083 ie_allowlist->ie_bitmap[1] = allowlist.ie_bitmap_1; 21084 ie_allowlist->ie_bitmap[2] = allowlist.ie_bitmap_2; 21085 ie_allowlist->ie_bitmap[3] = allowlist.ie_bitmap_3; 21086 ie_allowlist->ie_bitmap[4] = allowlist.ie_bitmap_4; 21087 ie_allowlist->ie_bitmap[5] = allowlist.ie_bitmap_5; 21088 ie_allowlist->ie_bitmap[6] = allowlist.ie_bitmap_6; 21089 ie_allowlist->ie_bitmap[7] = allowlist.ie_bitmap_7; 21090 21091 ie_allowlist->num_vendor_oui = allowlist.no_of_probe_req_ouis; 21092 for (i = 0; i < ie_allowlist->num_vendor_oui; i++) 21093 ie_allowlist->voui[i] = allowlist.probe_req_voui[i]; 21094 } 21095 hdd_update_score_config(struct hdd_context * hdd_ctx)21096 QDF_STATUS hdd_update_score_config(struct hdd_context *hdd_ctx) 21097 { 21098 struct hdd_config *cfg = hdd_ctx->config; 21099 eCsrPhyMode phy_mode = hdd_cfg_xlate_to_csr_phy_mode(cfg->dot11Mode); 21100 21101 sme_update_score_config(hdd_ctx->mac_handle, phy_mode, 21102 hdd_ctx->num_rf_chains); 21103 21104 return QDF_STATUS_SUCCESS; 21105 } 21106 21107 /** 21108 * hdd_update_dfs_config() - API to update dfs configuration parameters. 21109 * @hdd_ctx: HDD context 21110 * 21111 * Return: 0 if success else err 21112 */ hdd_update_dfs_config(struct hdd_context * hdd_ctx)21113 static int hdd_update_dfs_config(struct hdd_context *hdd_ctx) 21114 { 21115 struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc; 21116 struct dfs_user_config dfs_cfg = {0}; 21117 QDF_STATUS status; 21118 21119 ucfg_mlme_get_dfs_filter_offload(hdd_ctx->psoc, 21120 &dfs_cfg.dfs_is_phyerr_filter_offload); 21121 status = ucfg_dfs_update_config(psoc, &dfs_cfg); 21122 if (QDF_IS_STATUS_ERROR(status)) { 21123 hdd_err("failed dfs psoc configuration"); 21124 return -EINVAL; 21125 } 21126 21127 return 0; 21128 } 21129 21130 /** 21131 * hdd_update_scan_config - API to update scan configuration parameters 21132 * @hdd_ctx: HDD context 21133 * 21134 * Return: 0 if success else err 21135 */ hdd_update_scan_config(struct hdd_context * hdd_ctx)21136 int hdd_update_scan_config(struct hdd_context *hdd_ctx) 21137 { 21138 struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc; 21139 struct scan_user_cfg scan_cfg; 21140 QDF_STATUS status; 21141 uint32_t mcast_mcc_rest_time = 0; 21142 21143 qdf_mem_zero(&scan_cfg, sizeof(scan_cfg)); 21144 status = ucfg_mlme_get_sta_miracast_mcc_rest_time(hdd_ctx->psoc, 21145 &mcast_mcc_rest_time); 21146 if (!QDF_IS_STATUS_SUCCESS(status)) { 21147 hdd_err("ucfg_mlme_get_sta_miracast_mcc_rest_time, use def"); 21148 return -EIO; 21149 } 21150 scan_cfg.sta_miracast_mcc_rest_time = mcast_mcc_rest_time; 21151 hdd_update_ie_allowlist_attr(&scan_cfg.ie_allowlist, hdd_ctx); 21152 21153 status = ucfg_scan_update_user_config(psoc, &scan_cfg); 21154 if (status != QDF_STATUS_SUCCESS) { 21155 hdd_err("failed pmo psoc configuration"); 21156 return -EINVAL; 21157 } 21158 21159 return 0; 21160 } 21161 hdd_update_components_config(struct hdd_context * hdd_ctx)21162 int hdd_update_components_config(struct hdd_context *hdd_ctx) 21163 { 21164 int ret; 21165 21166 ret = hdd_update_pmo_config(hdd_ctx); 21167 if (ret) 21168 return ret; 21169 21170 ret = hdd_update_scan_config(hdd_ctx); 21171 if (ret) 21172 return ret; 21173 21174 ret = hdd_update_tdls_config(hdd_ctx); 21175 if (ret) 21176 return ret; 21177 21178 ret = hdd_update_dp_config(hdd_ctx); 21179 if (ret) 21180 return ret; 21181 21182 ret = hdd_update_dfs_config(hdd_ctx); 21183 if (ret) 21184 return ret; 21185 21186 ret = hdd_update_regulatory_config(hdd_ctx); 21187 if (ret) 21188 return ret; 21189 21190 return ret; 21191 } 21192 21193 /** 21194 * wlan_hdd_get_dfs_mode() - get ACS DFS mode 21195 * @mode : cfg80211 DFS mode 21196 * 21197 * Return: return SAP ACS DFS mode else return ACS_DFS_MODE_NONE 21198 */ wlan_hdd_get_dfs_mode(enum dfs_mode mode)21199 enum sap_acs_dfs_mode wlan_hdd_get_dfs_mode(enum dfs_mode mode) 21200 { 21201 switch (mode) { 21202 case DFS_MODE_ENABLE: 21203 return ACS_DFS_MODE_ENABLE; 21204 case DFS_MODE_DISABLE: 21205 return ACS_DFS_MODE_DISABLE; 21206 case DFS_MODE_DEPRIORITIZE: 21207 return ACS_DFS_MODE_DEPRIORITIZE; 21208 default: 21209 hdd_debug("ACS dfs mode is NONE"); 21210 return ACS_DFS_MODE_NONE; 21211 } 21212 } 21213 21214 /** 21215 * hdd_enable_disable_ca_event() - enable/disable channel avoidance event 21216 * @hdd_ctx: pointer to hdd context 21217 * @set_value: enable/disable 21218 * 21219 * When Host sends vendor command enable, FW will send *ONE* CA ind to 21220 * Host(even though it is duplicate). When Host send vendor command 21221 * disable,FW doesn't perform any action. Whenever any change in 21222 * CA *and* WLAN is in SAP/P2P-GO mode, FW sends CA ind to host. 21223 * 21224 * return - 0 on success, appropriate error values on failure. 21225 */ hdd_enable_disable_ca_event(struct hdd_context * hdd_ctx,uint8_t set_value)21226 int hdd_enable_disable_ca_event(struct hdd_context *hdd_ctx, uint8_t set_value) 21227 { 21228 QDF_STATUS status; 21229 21230 if (0 != wlan_hdd_validate_context(hdd_ctx)) 21231 return -EAGAIN; 21232 21233 status = sme_enable_disable_chanavoidind_event(hdd_ctx->mac_handle, 21234 set_value); 21235 if (!QDF_IS_STATUS_SUCCESS(status)) { 21236 hdd_err("Failed to send chan avoid command to SME"); 21237 return -EINVAL; 21238 } 21239 return 0; 21240 } 21241 hdd_is_roaming_in_progress(struct hdd_context * hdd_ctx)21242 bool hdd_is_roaming_in_progress(struct hdd_context *hdd_ctx) 21243 { 21244 struct hdd_adapter *adapter = NULL, *next_adapter = NULL; 21245 uint8_t vdev_id; 21246 wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_IS_ROAMING_IN_PROGRESS; 21247 struct wlan_hdd_link_info *link_info; 21248 21249 if (!hdd_ctx) { 21250 hdd_err("HDD context is NULL"); 21251 return false; 21252 } 21253 21254 if (!policy_mgr_is_sta_active_connection_exists(hdd_ctx->psoc)) 21255 return false; 21256 21257 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 21258 dbgid) { 21259 if (adapter->device_mode != QDF_STA_MODE) 21260 goto adapter_put; 21261 21262 hdd_adapter_for_each_active_link_info(adapter, link_info) { 21263 vdev_id = link_info->vdev_id; 21264 if (test_bit(SME_SESSION_OPENED, 21265 &link_info->link_flags) && 21266 sme_roaming_in_progress(hdd_ctx->mac_handle, 21267 vdev_id)) { 21268 hdd_debug("Roaming is in progress on:vdev_id:%d", 21269 link_info->vdev_id); 21270 hdd_adapter_dev_put_debug(adapter, dbgid); 21271 if (next_adapter) 21272 hdd_adapter_dev_put_debug(next_adapter, 21273 dbgid); 21274 return true; 21275 } 21276 } 21277 adapter_put: 21278 hdd_adapter_dev_put_debug(adapter, dbgid); 21279 } 21280 21281 return false; 21282 } 21283 21284 /** 21285 * struct hdd_is_connection_in_progress_priv - adapter connection info 21286 * @out_vdev_id: id of vdev where connection is occurring 21287 * @out_reason: scan reject reason 21288 * @connection_in_progress: true if connection is in progress 21289 */ 21290 struct hdd_is_connection_in_progress_priv { 21291 uint8_t out_vdev_id; 21292 enum scan_reject_states out_reason; 21293 bool connection_in_progress; 21294 }; 21295 21296 /** 21297 * hdd_is_connection_in_progress_iterator() - Check adapter connection based 21298 * on device mode 21299 * @link_info: Link info pointer in HDD adapter 21300 * @ctx: user context supplied 21301 * 21302 * Check if connection is in progress for the current adapter according to the 21303 * device mode 21304 * 21305 * Return: 21306 * * QDF_STATUS_SUCCESS if iteration should continue 21307 * * QDF_STATUS_E_ABORTED if iteration should be aborted 21308 */ 21309 static QDF_STATUS hdd_is_connection_in_progress_iterator(struct wlan_hdd_link_info * link_info,void * ctx)21310 hdd_is_connection_in_progress_iterator(struct wlan_hdd_link_info *link_info, 21311 void *ctx) 21312 { 21313 struct hdd_station_ctx *hdd_sta_ctx; 21314 uint8_t *sta_mac; 21315 struct hdd_context *hdd_ctx; 21316 mac_handle_t mac_handle; 21317 struct hdd_station_info *sta_info, *tmp = NULL; 21318 struct hdd_is_connection_in_progress_priv *context = ctx; 21319 struct hdd_adapter *adapter = link_info->adapter; 21320 21321 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 21322 if (!hdd_ctx) 21323 return QDF_STATUS_E_ABORTED; 21324 21325 mac_handle = hdd_ctx->mac_handle; 21326 21327 if (!test_bit(SME_SESSION_OPENED, &link_info->link_flags) && 21328 (adapter->device_mode == QDF_STA_MODE || 21329 adapter->device_mode == QDF_P2P_CLIENT_MODE || 21330 adapter->device_mode == QDF_P2P_DEVICE_MODE || 21331 adapter->device_mode == QDF_P2P_GO_MODE || 21332 adapter->device_mode == QDF_SAP_MODE)) 21333 return QDF_STATUS_SUCCESS; 21334 21335 if ((QDF_STA_MODE == adapter->device_mode || 21336 QDF_P2P_CLIENT_MODE == adapter->device_mode || 21337 QDF_P2P_DEVICE_MODE == adapter->device_mode) && 21338 hdd_cm_is_connecting(link_info)) { 21339 hdd_debug("%pK(%d) mode %d Connection is in progress", 21340 WLAN_HDD_GET_STATION_CTX_PTR(link_info), 21341 link_info->vdev_id, adapter->device_mode); 21342 21343 context->out_vdev_id = link_info->vdev_id; 21344 context->out_reason = CONNECTION_IN_PROGRESS; 21345 context->connection_in_progress = true; 21346 21347 return QDF_STATUS_E_ABORTED; 21348 } 21349 21350 if ((QDF_STA_MODE == adapter->device_mode) && 21351 sme_roaming_in_progress(mac_handle, link_info->vdev_id)) { 21352 hdd_debug("%pK(%d) mode %d Reassociation in progress", 21353 WLAN_HDD_GET_STATION_CTX_PTR(link_info), 21354 link_info->vdev_id, adapter->device_mode); 21355 21356 context->out_vdev_id = link_info->vdev_id; 21357 context->out_reason = REASSOC_IN_PROGRESS; 21358 context->connection_in_progress = true; 21359 return QDF_STATUS_E_ABORTED; 21360 } 21361 21362 if ((QDF_STA_MODE == adapter->device_mode) || 21363 (QDF_P2P_CLIENT_MODE == adapter->device_mode) || 21364 (QDF_P2P_DEVICE_MODE == adapter->device_mode)) { 21365 hdd_sta_ctx = 21366 WLAN_HDD_GET_STATION_CTX_PTR(link_info); 21367 if (hdd_cm_is_vdev_associated(link_info) 21368 && sme_is_sta_key_exchange_in_progress( 21369 mac_handle, link_info->vdev_id)) { 21370 sta_mac = (uint8_t *)&(adapter->mac_addr.bytes[0]); 21371 hdd_debug("client " QDF_MAC_ADDR_FMT 21372 " is in middle of WPS/EAPOL exchange.", 21373 QDF_MAC_ADDR_REF(sta_mac)); 21374 21375 context->out_vdev_id = link_info->vdev_id; 21376 context->out_reason = EAPOL_IN_PROGRESS; 21377 context->connection_in_progress = true; 21378 21379 return QDF_STATUS_E_ABORTED; 21380 } 21381 } else if ((QDF_SAP_MODE == adapter->device_mode) || 21382 (QDF_P2P_GO_MODE == adapter->device_mode)) { 21383 hdd_for_each_sta_ref_safe(adapter->sta_info_list, sta_info, tmp, 21384 STA_INFO_CONNECTION_IN_PROGRESS_ITERATOR) { 21385 if (sta_info->peer_state != 21386 OL_TXRX_PEER_STATE_CONN) { 21387 hdd_put_sta_info_ref( 21388 &adapter->sta_info_list, &sta_info, true, 21389 STA_INFO_CONNECTION_IN_PROGRESS_ITERATOR); 21390 continue; 21391 } 21392 21393 sta_mac = sta_info->sta_mac.bytes; 21394 hdd_debug("client " QDF_MAC_ADDR_FMT 21395 " of SAP/GO is in middle of WPS/EAPOL exchange", 21396 QDF_MAC_ADDR_REF(sta_mac)); 21397 21398 context->out_vdev_id = link_info->vdev_id; 21399 context->out_reason = SAP_EAPOL_IN_PROGRESS; 21400 context->connection_in_progress = true; 21401 21402 hdd_put_sta_info_ref( 21403 &adapter->sta_info_list, &sta_info, true, 21404 STA_INFO_CONNECTION_IN_PROGRESS_ITERATOR); 21405 if (tmp) 21406 hdd_put_sta_info_ref( 21407 &adapter->sta_info_list, &tmp, true, 21408 STA_INFO_CONNECTION_IN_PROGRESS_ITERATOR); 21409 21410 return QDF_STATUS_E_ABORTED; 21411 } 21412 if (hdd_ctx->connection_in_progress) { 21413 hdd_debug("AP/GO: vdev %d connection is in progress", 21414 link_info->vdev_id); 21415 context->out_reason = SAP_CONNECTION_IN_PROGRESS; 21416 context->out_vdev_id = link_info->vdev_id; 21417 context->connection_in_progress = true; 21418 21419 return QDF_STATUS_E_ABORTED; 21420 } 21421 } 21422 21423 if (ucfg_nan_is_enable_disable_in_progress(hdd_ctx->psoc)) { 21424 context->out_reason = NAN_ENABLE_DISABLE_IN_PROGRESS; 21425 context->out_vdev_id = NAN_PSEUDO_VDEV_ID; 21426 context->connection_in_progress = true; 21427 21428 return QDF_STATUS_E_ABORTED; 21429 } 21430 21431 return QDF_STATUS_SUCCESS; 21432 } 21433 hdd_is_connection_in_progress(uint8_t * out_vdev_id,enum scan_reject_states * out_reason)21434 bool hdd_is_connection_in_progress(uint8_t *out_vdev_id, 21435 enum scan_reject_states *out_reason) 21436 { 21437 struct hdd_is_connection_in_progress_priv hdd_conn; 21438 hdd_adapter_iterate_cb cb; 21439 21440 hdd_conn.out_vdev_id = 0; 21441 hdd_conn.out_reason = SCAN_REJECT_DEFAULT; 21442 hdd_conn.connection_in_progress = false; 21443 21444 cb = hdd_is_connection_in_progress_iterator; 21445 21446 hdd_adapter_iterate(cb, &hdd_conn); 21447 21448 if (hdd_conn.connection_in_progress && out_vdev_id && out_reason) { 21449 *out_vdev_id = hdd_conn.out_vdev_id; 21450 *out_reason = hdd_conn.out_reason; 21451 } 21452 21453 return hdd_conn.connection_in_progress; 21454 } 21455 hdd_restart_sap(struct wlan_hdd_link_info * link_info)21456 void hdd_restart_sap(struct wlan_hdd_link_info *link_info) 21457 { 21458 struct hdd_hostapd_state *hapd_state; 21459 QDF_STATUS status; 21460 struct hdd_adapter *ap_adapter = link_info->adapter; 21461 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(ap_adapter); 21462 struct sap_config *sap_config; 21463 void *sap_ctx; 21464 21465 sap_config = 21466 &(WLAN_HDD_GET_AP_CTX_PTR(link_info)->sap_config); 21467 sap_ctx = WLAN_HDD_GET_SAP_CTX_PTR(link_info); 21468 21469 mutex_lock(&hdd_ctx->sap_lock); 21470 if (test_bit(SOFTAP_BSS_STARTED, &link_info->link_flags)) { 21471 wlan_hdd_del_station(ap_adapter, NULL); 21472 hapd_state = WLAN_HDD_GET_HOSTAP_STATE_PTR(link_info); 21473 qdf_event_reset(&hapd_state->qdf_stop_bss_event); 21474 if (QDF_STATUS_SUCCESS == wlansap_stop_bss(sap_ctx)) { 21475 status = qdf_wait_single_event(&hapd_state->qdf_stop_bss_event, 21476 SME_CMD_STOP_BSS_TIMEOUT); 21477 21478 if (!QDF_IS_STATUS_SUCCESS(status)) { 21479 hdd_err("SAP Stop Failed"); 21480 goto end; 21481 } 21482 } 21483 clear_bit(SOFTAP_BSS_STARTED, &link_info->link_flags); 21484 policy_mgr_decr_session_set_pcl(hdd_ctx->psoc, 21485 ap_adapter->device_mode, link_info->vdev_id); 21486 hdd_green_ap_start_state_mc(hdd_ctx, ap_adapter->device_mode, 21487 false); 21488 hdd_err("SAP Stop Success"); 21489 21490 if (0 != wlan_hdd_cfg80211_update_apies(link_info)) { 21491 hdd_err("SAP Not able to set AP IEs"); 21492 goto end; 21493 } 21494 21495 status = wlan_hdd_mlo_sap_reinit(link_info); 21496 if (QDF_IS_STATUS_ERROR(status)) { 21497 hdd_err("SAP Not able to do mlo attach"); 21498 goto deinit_mlo; 21499 } 21500 21501 qdf_event_reset(&hapd_state->qdf_event); 21502 status = wlansap_start_bss(sap_ctx, hdd_hostapd_sap_event_cb, 21503 sap_config, ap_adapter->dev); 21504 if (QDF_IS_STATUS_ERROR(status)) { 21505 hdd_err("SAP Start Bss fail"); 21506 goto deinit_mlo; 21507 } 21508 21509 hdd_info("Waiting for SAP to start"); 21510 status = qdf_wait_single_event(&hapd_state->qdf_event, 21511 SME_CMD_START_BSS_TIMEOUT); 21512 if (!QDF_IS_STATUS_SUCCESS(status)) { 21513 hdd_err("SAP Start failed"); 21514 goto deinit_mlo; 21515 } 21516 wlansap_reset_sap_config_add_ie(sap_config, eUPDATE_IE_ALL); 21517 hdd_err("SAP Start Success"); 21518 set_bit(SOFTAP_BSS_STARTED, &link_info->link_flags); 21519 if (hapd_state->bss_state == BSS_START) { 21520 policy_mgr_incr_active_session(hdd_ctx->psoc, 21521 ap_adapter->device_mode, 21522 link_info->vdev_id); 21523 hdd_green_ap_start_state_mc(hdd_ctx, 21524 ap_adapter->device_mode, 21525 true); 21526 } 21527 } 21528 mutex_unlock(&hdd_ctx->sap_lock); 21529 return; 21530 21531 deinit_mlo: 21532 wlan_hdd_mlo_reset(link_info); 21533 end: 21534 wlansap_reset_sap_config_add_ie(sap_config, eUPDATE_IE_ALL); 21535 mutex_unlock(&hdd_ctx->sap_lock); 21536 } 21537 21538 /** 21539 * hdd_set_connection_in_progress() - to set the connection in 21540 * progress flag 21541 * @value: value to set 21542 * 21543 * This function will set the passed value to connection in progress flag. 21544 * If value is previously being set to true then no need to set it again. 21545 * 21546 * Return: true if value is being set correctly and false otherwise. 21547 */ hdd_set_connection_in_progress(bool value)21548 bool hdd_set_connection_in_progress(bool value) 21549 { 21550 bool status = true; 21551 struct hdd_context *hdd_ctx; 21552 21553 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 21554 if (!hdd_ctx) 21555 return false; 21556 21557 qdf_spin_lock(&hdd_ctx->connection_status_lock); 21558 /* 21559 * if the value is set to true previously and if someone is 21560 * trying to make it true again then it could be some race 21561 * condition being triggered. Avoid this situation by returning 21562 * false 21563 */ 21564 if (hdd_ctx->connection_in_progress && value) 21565 status = false; 21566 else 21567 hdd_ctx->connection_in_progress = value; 21568 qdf_spin_unlock(&hdd_ctx->connection_status_lock); 21569 return status; 21570 } 21571 wlan_hdd_send_mcc_vdev_quota(struct hdd_adapter * adapter,int set_value)21572 int wlan_hdd_send_mcc_vdev_quota(struct hdd_adapter *adapter, int set_value) 21573 { 21574 if (!adapter) { 21575 hdd_err("Invalid adapter"); 21576 return -EINVAL; 21577 } 21578 hdd_info("send mcc vdev quota to fw: %d", set_value); 21579 sme_cli_set_command(adapter->deflink->vdev_id, 21580 WMA_VDEV_MCC_SET_TIME_QUOTA, 21581 set_value, VDEV_CMD); 21582 return 0; 21583 21584 } 21585 wlan_hdd_send_mcc_latency(struct hdd_adapter * adapter,int set_value)21586 int wlan_hdd_send_mcc_latency(struct hdd_adapter *adapter, int set_value) 21587 { 21588 if (!adapter) { 21589 hdd_err("Invalid adapter"); 21590 return -EINVAL; 21591 } 21592 21593 hdd_info("Send MCC latency WMA: %d", set_value); 21594 sme_cli_set_command(adapter->deflink->vdev_id, 21595 WMA_VDEV_MCC_SET_TIME_LATENCY, 21596 set_value, VDEV_CMD); 21597 return 0; 21598 } 21599 21600 struct wlan_hdd_link_info * wlan_hdd_get_link_info_from_vdev(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id)21601 wlan_hdd_get_link_info_from_vdev(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id) 21602 { 21603 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 21604 struct wlan_hdd_link_info *link_info; 21605 21606 /* 21607 * Currently PSOC is not being used. But this logic will 21608 * change once we have the converged implementation of 21609 * HDD context per PSOC in place. This would break if 21610 * multiple vdev objects reuse the vdev id. 21611 */ 21612 link_info = hdd_get_link_info_by_vdev(hdd_ctx, vdev_id); 21613 if (!link_info) { 21614 hdd_err("Get adapter by vdev id failed"); 21615 return NULL; 21616 } 21617 21618 return link_info; 21619 } 21620 hdd_get_rssi_snr_by_bssid(mac_handle_t mac_handle,const uint8_t * bssid,int8_t * rssi,int8_t * snr)21621 int hdd_get_rssi_snr_by_bssid(mac_handle_t mac_handle, const uint8_t *bssid, 21622 int8_t *rssi, int8_t *snr) 21623 { 21624 QDF_STATUS status; 21625 21626 status = sme_get_rssi_snr_by_bssid(mac_handle, bssid, rssi, snr); 21627 if (QDF_IS_STATUS_ERROR(status)) { 21628 hdd_debug("sme_get_rssi_snr_by_bssid failed"); 21629 return -EINVAL; 21630 } 21631 21632 return 0; 21633 } 21634 21635 /** 21636 * hdd_reset_limit_off_chan() - reset limit off-channel command parameters 21637 * @adapter: HDD adapter 21638 * 21639 * Return: 0 on success and non zero value on failure 21640 */ hdd_reset_limit_off_chan(struct hdd_adapter * adapter)21641 int hdd_reset_limit_off_chan(struct hdd_adapter *adapter) 21642 { 21643 struct hdd_context *hdd_ctx; 21644 int ret; 21645 QDF_STATUS status; 21646 uint8_t sys_pref = 0; 21647 21648 hdd_ctx = WLAN_HDD_GET_CTX(adapter); 21649 ret = wlan_hdd_validate_context(hdd_ctx); 21650 if (ret < 0) 21651 return ret; 21652 21653 ucfg_policy_mgr_get_sys_pref(hdd_ctx->psoc, 21654 &sys_pref); 21655 /* set the system preferece to default */ 21656 policy_mgr_set_cur_conc_system_pref(hdd_ctx->psoc, sys_pref); 21657 21658 /* clear the bitmap */ 21659 adapter->active_ac = 0; 21660 21661 hdd_debug("reset ac_bitmap for session %hu active_ac %0x", 21662 adapter->deflink->vdev_id, adapter->active_ac); 21663 21664 status = sme_send_limit_off_channel_params(hdd_ctx->mac_handle, 21665 adapter->deflink->vdev_id, 21666 false, 0, 0, false); 21667 if (!QDF_IS_STATUS_SUCCESS(status)) { 21668 hdd_err("failed to reset limit off chan params"); 21669 ret = -EINVAL; 21670 } 21671 21672 return ret; 21673 } 21674 hdd_hidden_ssid_enable_roaming(hdd_handle_t hdd_handle,uint8_t vdev_id)21675 void hdd_hidden_ssid_enable_roaming(hdd_handle_t hdd_handle, uint8_t vdev_id) 21676 { 21677 struct hdd_context *hdd_ctx = hdd_handle_to_context(hdd_handle); 21678 struct wlan_hdd_link_info *link_info; 21679 21680 link_info = hdd_get_link_info_by_vdev(hdd_ctx, vdev_id); 21681 if (!link_info) { 21682 hdd_err("Invalid vdev"); 21683 return; 21684 } 21685 /* enable roaming on all adapters once hdd get hidden ssid rsp */ 21686 wlan_hdd_set_roaming_state(link_info, RSO_START_BSS, true); 21687 } 21688 21689 #ifdef WLAN_FEATURE_PKT_CAPTURE wlan_hdd_is_mon_concurrency(void)21690 bool wlan_hdd_is_mon_concurrency(void) 21691 { 21692 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 21693 21694 if (!hdd_ctx) 21695 return -EINVAL; 21696 21697 if (ucfg_pkt_capture_get_mode(hdd_ctx->psoc) != 21698 PACKET_CAPTURE_MODE_DISABLE) { 21699 if (policy_mgr_get_concurrency_mode(hdd_ctx->psoc) == 21700 (QDF_STA_MASK | QDF_MONITOR_MASK)) { 21701 hdd_err("STA + MON mode is UP"); 21702 return true; 21703 } 21704 } 21705 return false; 21706 } 21707 wlan_hdd_del_monitor(struct hdd_context * hdd_ctx,struct hdd_adapter * adapter,bool rtnl_held)21708 void wlan_hdd_del_monitor(struct hdd_context *hdd_ctx, 21709 struct hdd_adapter *adapter, bool rtnl_held) 21710 { 21711 wlan_hdd_release_intf_addr(hdd_ctx, adapter->mac_addr.bytes); 21712 hdd_stop_adapter(hdd_ctx, adapter); 21713 hdd_close_adapter(hdd_ctx, adapter, true); 21714 21715 hdd_open_p2p_interface(hdd_ctx); 21716 } 21717 21718 void wlan_hdd_del_p2p_interface(struct hdd_context * hdd_ctx)21719 wlan_hdd_del_p2p_interface(struct hdd_context *hdd_ctx) 21720 { 21721 struct hdd_adapter *adapter = NULL, *next_adapter = NULL; 21722 struct osif_vdev_sync *vdev_sync; 21723 21724 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 21725 NET_DEV_HOLD_DEL_P2P_INTERFACE) { 21726 if (adapter->device_mode == QDF_P2P_CLIENT_MODE || 21727 adapter->device_mode == QDF_P2P_DEVICE_MODE || 21728 adapter->device_mode == QDF_P2P_GO_MODE) { 21729 vdev_sync = osif_vdev_sync_unregister(adapter->dev); 21730 if (vdev_sync) 21731 osif_vdev_sync_wait_for_ops(vdev_sync); 21732 21733 hdd_adapter_dev_put_debug( 21734 adapter, NET_DEV_HOLD_DEL_P2P_INTERFACE); 21735 21736 hdd_clean_up_interface(hdd_ctx, adapter); 21737 21738 if (vdev_sync) 21739 osif_vdev_sync_destroy(vdev_sync); 21740 } else 21741 hdd_adapter_dev_put_debug( 21742 adapter, NET_DEV_HOLD_DEL_P2P_INTERFACE); 21743 } 21744 } 21745 21746 #endif /* WLAN_FEATURE_PKT_CAPTURE */ 21747 wlan_hdd_is_session_type_monitor(uint8_t session_type)21748 bool wlan_hdd_is_session_type_monitor(uint8_t session_type) 21749 { 21750 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 21751 21752 if (!hdd_ctx) { 21753 cds_err("HDD context is NULL"); 21754 return false; 21755 } 21756 21757 if (cds_get_conparam() != QDF_GLOBAL_MONITOR_MODE && 21758 session_type == QDF_MONITOR_MODE) 21759 return true; 21760 else 21761 return false; 21762 } 21763 21764 int wlan_hdd_add_monitor_check(struct hdd_context * hdd_ctx,struct hdd_adapter ** adapter,const char * name,bool rtnl_held,unsigned char name_assign_type,bool is_rx_mon)21765 wlan_hdd_add_monitor_check(struct hdd_context *hdd_ctx, 21766 struct hdd_adapter **adapter, 21767 const char *name, bool rtnl_held, 21768 unsigned char name_assign_type, bool is_rx_mon) 21769 { 21770 struct hdd_adapter *sta_adapter; 21771 struct hdd_adapter *mon_adapter; 21772 uint8_t num_open_session = 0; 21773 QDF_STATUS status; 21774 struct hdd_adapter_create_param params = {0}; 21775 21776 sta_adapter = hdd_get_adapter(hdd_ctx, QDF_STA_MODE); 21777 if (!sta_adapter) { 21778 hdd_err("No station adapter"); 21779 return -EINVAL; 21780 } 21781 21782 status = policy_mgr_check_mon_concurrency(hdd_ctx->psoc); 21783 21784 if (QDF_IS_STATUS_ERROR(status)) 21785 return -EINVAL; 21786 21787 if (hdd_is_connection_in_progress(NULL, NULL)) { 21788 hdd_err("cannot add monitor mode, Connection in progress"); 21789 return -EINVAL; 21790 } 21791 21792 if (is_rx_mon) { 21793 num_open_session = policy_mgr_mode_specific_connection_count( 21794 hdd_ctx->psoc, 21795 PM_STA_MODE, 21796 NULL); 21797 21798 if (num_open_session) { 21799 /* Try disconnecting if already in connected state */ 21800 wlan_hdd_cm_issue_disconnect(sta_adapter->deflink, 21801 REASON_UNSPEC_FAILURE, 21802 true); 21803 } 21804 } 21805 21806 if (ucfg_pkt_capture_get_mode(hdd_ctx->psoc) != 21807 PACKET_CAPTURE_MODE_DISABLE) 21808 wlan_hdd_del_p2p_interface(hdd_ctx); 21809 21810 params.is_add_virtual_iface = 1; 21811 21812 mon_adapter = hdd_open_adapter(hdd_ctx, QDF_MONITOR_MODE, name, 21813 wlan_hdd_get_intf_addr( 21814 hdd_ctx, 21815 QDF_MONITOR_MODE), 21816 name_assign_type, rtnl_held, ¶ms); 21817 if (!mon_adapter) { 21818 hdd_err("hdd_open_adapter failed"); 21819 if (ucfg_pkt_capture_get_mode(hdd_ctx->psoc) != 21820 PACKET_CAPTURE_MODE_DISABLE) 21821 hdd_open_p2p_interface(hdd_ctx); 21822 return -EINVAL; 21823 } 21824 21825 if (mon_adapter) 21826 hdd_set_idle_ps_config(hdd_ctx, false); 21827 21828 *adapter = mon_adapter; 21829 return 0; 21830 } 21831 21832 #ifdef FEATURE_MONITOR_MODE_SUPPORT 21833 hdd_sme_monitor_mode_callback(uint8_t vdev_id)21834 void hdd_sme_monitor_mode_callback(uint8_t vdev_id) 21835 { 21836 struct hdd_context *hdd_ctx; 21837 struct hdd_adapter *adapter; 21838 struct wlan_hdd_link_info *link_info; 21839 21840 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 21841 if (!hdd_ctx) 21842 return; 21843 21844 link_info = hdd_get_link_info_by_vdev(hdd_ctx, vdev_id); 21845 if (!link_info) { 21846 hdd_err_rl("NULL adapter"); 21847 return; 21848 } 21849 21850 adapter = link_info->adapter; 21851 if (adapter->magic != WLAN_HDD_ADAPTER_MAGIC) { 21852 hdd_err_rl("Invalid magic"); 21853 return; 21854 } 21855 21856 qdf_event_set(&adapter->qdf_monitor_mode_vdev_up_event); 21857 21858 hdd_debug("monitor mode vdev up completed"); 21859 adapter->monitor_mode_vdev_up_in_progress = false; 21860 } 21861 hdd_monitor_mode_qdf_create_event(struct hdd_adapter * adapter,uint8_t session_type)21862 QDF_STATUS hdd_monitor_mode_qdf_create_event(struct hdd_adapter *adapter, 21863 uint8_t session_type) 21864 { 21865 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; 21866 21867 if (session_type == QDF_MONITOR_MODE) { 21868 qdf_status = qdf_event_create( 21869 &adapter->qdf_monitor_mode_vdev_up_event); 21870 } 21871 return qdf_status; 21872 } 21873 hdd_monitor_mode_vdev_status(struct hdd_adapter * adapter)21874 QDF_STATUS hdd_monitor_mode_vdev_status(struct hdd_adapter *adapter) 21875 { 21876 QDF_STATUS status = QDF_STATUS_SUCCESS; 21877 21878 if (!adapter->monitor_mode_vdev_up_in_progress) 21879 return status; 21880 21881 /* block on a completion variable until vdev up success*/ 21882 status = qdf_wait_for_event_completion( 21883 &adapter->qdf_monitor_mode_vdev_up_event, 21884 WLAN_MONITOR_MODE_VDEV_UP_EVT); 21885 if (QDF_IS_STATUS_ERROR(status)) { 21886 hdd_err_rl("monitor mode vdev up event time out vdev id: %d", 21887 adapter->deflink->vdev_id); 21888 if (adapter->qdf_monitor_mode_vdev_up_event.force_set) 21889 /* 21890 * SSR/PDR has caused shutdown, which has 21891 * forcefully set the event. 21892 */ 21893 hdd_err_rl("monitor mode vdev up event forcefully set"); 21894 else if (status == QDF_STATUS_E_TIMEOUT) 21895 hdd_err_rl("mode vdev up event timed out"); 21896 else 21897 hdd_err_rl("Failed to wait for monitor vdev up(status-%d)", 21898 status); 21899 21900 adapter->monitor_mode_vdev_up_in_progress = false; 21901 return status; 21902 } 21903 21904 return QDF_STATUS_SUCCESS; 21905 } 21906 #endif 21907 21908 #if defined(CLD_PM_QOS) && defined(WLAN_FEATURE_LL_MODE) hdd_beacon_latency_event_cb(uint32_t latency_level)21909 void hdd_beacon_latency_event_cb(uint32_t latency_level) 21910 { 21911 struct hdd_context *hdd_ctx; 21912 21913 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 21914 if (!hdd_ctx) 21915 return; 21916 21917 if (latency_level == 21918 QCA_WLAN_VENDOR_ATTR_CONFIG_LATENCY_LEVEL_ULTRALOW) 21919 wlan_hdd_set_pm_qos_request(hdd_ctx, true); 21920 else 21921 wlan_hdd_set_pm_qos_request(hdd_ctx, false); 21922 } 21923 #endif 21924 21925 #ifdef CONFIG_WLAN_DEBUG_CRASH_INJECT hdd_crash_inject(struct hdd_adapter * adapter,uint32_t v1,uint32_t v2)21926 int hdd_crash_inject(struct hdd_adapter *adapter, uint32_t v1, uint32_t v2) 21927 { 21928 struct hdd_context *hdd_ctx; 21929 int ret; 21930 bool crash_inject; 21931 QDF_STATUS status; 21932 21933 hdd_debug("v1: %d v2: %d", v1, v2); 21934 pr_err("SSR is triggered by CRASH_INJECT: %d %d\n", 21935 v1, v2); 21936 hdd_ctx = WLAN_HDD_GET_CTX(adapter); 21937 21938 status = ucfg_mlme_get_crash_inject(hdd_ctx->psoc, &crash_inject); 21939 if (QDF_IS_STATUS_ERROR(status)) { 21940 hdd_err("Failed to get crash inject ini config"); 21941 return 0; 21942 } 21943 21944 if (!crash_inject) { 21945 hdd_err("Crash Inject ini disabled, Ignore Crash Inject"); 21946 return 0; 21947 } 21948 21949 if (v1 == 3) { 21950 cds_trigger_recovery(QDF_REASON_UNSPECIFIED); 21951 return 0; 21952 } 21953 ret = wma_cli_set2_command(adapter->deflink->vdev_id, 21954 GEN_PARAM_CRASH_INJECT, 21955 v1, v2, GEN_CMD); 21956 return ret; 21957 } 21958 #endif 21959 21960 static const struct hdd_chwidth_info chwidth_info[] = { 21961 [NL80211_CHAN_WIDTH_20_NOHT] = { 21962 .ch_bw = HW_MODE_20_MHZ, 21963 .ch_bw_str = "20MHz", 21964 .phy_chwidth = CH_WIDTH_20MHZ, 21965 }, 21966 [NL80211_CHAN_WIDTH_20] = { 21967 .sir_chwidth_valid = true, 21968 .sir_chwidth = eHT_CHANNEL_WIDTH_20MHZ, 21969 .ch_bw = HW_MODE_20_MHZ, 21970 .ch_bw_str = "20MHz", 21971 .phy_chwidth = CH_WIDTH_20MHZ, 21972 .bonding_mode = WNI_CFG_CHANNEL_BONDING_MODE_DISABLE, 21973 }, 21974 [NL80211_CHAN_WIDTH_40] = { 21975 .sir_chwidth_valid = true, 21976 .sir_chwidth = eHT_CHANNEL_WIDTH_40MHZ, 21977 .ch_bw = HW_MODE_40_MHZ, 21978 .ch_bw_str = "40MHz", 21979 .phy_chwidth = CH_WIDTH_40MHZ, 21980 .bonding_mode = WNI_CFG_CHANNEL_BONDING_MODE_ENABLE, 21981 }, 21982 [NL80211_CHAN_WIDTH_80] = { 21983 .sir_chwidth_valid = true, 21984 .sir_chwidth = eHT_CHANNEL_WIDTH_80MHZ, 21985 .ch_bw = HW_MODE_80_MHZ, 21986 .ch_bw_str = "80MHz", 21987 .phy_chwidth = CH_WIDTH_80MHZ, 21988 .bonding_mode = WNI_CFG_CHANNEL_BONDING_MODE_ENABLE, 21989 }, 21990 [NL80211_CHAN_WIDTH_80P80] = { 21991 .sir_chwidth_valid = true, 21992 .sir_chwidth = eHT_CHANNEL_WIDTH_80P80MHZ, 21993 .ch_bw = HW_MODE_80_PLUS_80_MHZ, 21994 .ch_bw_str = "(80 + 80)MHz", 21995 .phy_chwidth = CH_WIDTH_80P80MHZ, 21996 .bonding_mode = WNI_CFG_CHANNEL_BONDING_MODE_ENABLE, 21997 }, 21998 [NL80211_CHAN_WIDTH_160] = { 21999 .sir_chwidth_valid = true, 22000 .sir_chwidth = eHT_CHANNEL_WIDTH_160MHZ, 22001 .ch_bw = HW_MODE_160_MHZ, 22002 .ch_bw_str = "160MHz", 22003 .phy_chwidth = CH_WIDTH_160MHZ, 22004 .bonding_mode = WNI_CFG_CHANNEL_BONDING_MODE_ENABLE, 22005 }, 22006 [NL80211_CHAN_WIDTH_5] = { 22007 .ch_bw = HW_MODE_5_MHZ, 22008 .ch_bw_str = "5MHz", 22009 .phy_chwidth = CH_WIDTH_5MHZ, 22010 }, 22011 [NL80211_CHAN_WIDTH_10] = { 22012 .ch_bw = HW_MODE_10_MHZ, 22013 .ch_bw_str = "10MHz", 22014 .phy_chwidth = CH_WIDTH_10MHZ, 22015 }, 22016 #if defined(WLAN_FEATURE_11BE) && defined(CFG80211_11BE_BASIC) 22017 [NL80211_CHAN_WIDTH_320] = { 22018 .sir_chwidth_valid = true, 22019 .sir_chwidth = eHT_CHANNEL_WIDTH_320MHZ, 22020 .ch_bw = HW_MODE_320_MHZ, 22021 .ch_bw_str = "320MHz", 22022 .phy_chwidth = CH_WIDTH_320MHZ, 22023 .bonding_mode = WNI_CFG_CHANNEL_BONDING_MODE_ENABLE, 22024 }, 22025 #endif 22026 }; 22027 22028 enum eSirMacHTChannelWidth hdd_nl80211_chwidth_to_chwidth(uint8_t nl80211_chwidth)22029 hdd_nl80211_chwidth_to_chwidth(uint8_t nl80211_chwidth) 22030 { 22031 if (nl80211_chwidth >= ARRAY_SIZE(chwidth_info) || 22032 !chwidth_info[nl80211_chwidth].sir_chwidth_valid) { 22033 hdd_err("Unsupported channel width %d", nl80211_chwidth); 22034 return -EINVAL; 22035 } 22036 22037 return chwidth_info[nl80211_chwidth].sir_chwidth; 22038 } 22039 hdd_chwidth_to_nl80211_chwidth(enum eSirMacHTChannelWidth chwidth)22040 uint8_t hdd_chwidth_to_nl80211_chwidth(enum eSirMacHTChannelWidth chwidth) 22041 { 22042 int i; 22043 22044 for (i = 0; i < ARRAY_SIZE(chwidth_info); i++) { 22045 if (chwidth_info[i].sir_chwidth_valid && 22046 chwidth_info[i].sir_chwidth == chwidth) 22047 return i; 22048 } 22049 22050 hdd_err("Unsupported channel width %d", chwidth); 22051 return 0xFF; 22052 } 22053 hdd_phy_chwidth_to_nl80211_chwidth(enum phy_ch_width chwidth)22054 uint8_t hdd_phy_chwidth_to_nl80211_chwidth(enum phy_ch_width chwidth) 22055 { 22056 int i; 22057 22058 for (i = 0; i < ARRAY_SIZE(chwidth_info); i++) { 22059 if (chwidth_info[i].sir_chwidth_valid && 22060 chwidth_info[i].phy_chwidth == chwidth) 22061 return i; 22062 } 22063 22064 hdd_err("Unsupported channel width %d", chwidth); 22065 return 0xFF; 22066 } 22067 wlan_hdd_get_channel_bw(enum nl80211_chan_width width)22068 enum hw_mode_bandwidth wlan_hdd_get_channel_bw(enum nl80211_chan_width width) 22069 { 22070 if (width >= ARRAY_SIZE(chwidth_info)) { 22071 hdd_err("Invalid width: %d, using default 20MHz", width); 22072 return HW_MODE_20_MHZ; 22073 } 22074 22075 return chwidth_info[width].ch_bw; 22076 } 22077 hdd_ch_width_str(enum phy_ch_width ch_width)22078 uint8_t *hdd_ch_width_str(enum phy_ch_width ch_width) 22079 { 22080 int i; 22081 22082 for (i = 0; i < ARRAY_SIZE(chwidth_info); i++) { 22083 if (chwidth_info[i].phy_chwidth == ch_width) 22084 return chwidth_info[i].ch_bw_str; 22085 } 22086 22087 return "UNKNOWN"; 22088 } 22089 hdd_we_set_ch_width(struct wlan_hdd_link_info * link_info,int ch_width)22090 int hdd_we_set_ch_width(struct wlan_hdd_link_info *link_info, int ch_width) 22091 { 22092 int i; 22093 uint8_t link_id = 0xFF; 22094 22095 /* updating channel bonding only on 5Ghz */ 22096 hdd_debug("wmi_vdev_param_chwidth val %d", ch_width); 22097 22098 for (i = 0; i < ARRAY_SIZE(chwidth_info); i++) { 22099 if (!chwidth_info[i].sir_chwidth_valid || 22100 chwidth_info[i].sir_chwidth != ch_width) 22101 continue; 22102 22103 return hdd_update_channel_width(link_info, ch_width, 22104 chwidth_info[i].bonding_mode, 22105 link_id, false); 22106 } 22107 22108 hdd_err("Invalid ch_width %d", ch_width); 22109 return -EINVAL; 22110 } 22111 22112 /* Register the module init/exit functions */ 22113 module_init(hdd_module_init); 22114 module_exit(hdd_module_exit); 22115 22116 MODULE_LICENSE("Dual BSD/GPL"); 22117 MODULE_AUTHOR("Qualcomm Atheros, Inc."); 22118 MODULE_DESCRIPTION("WLAN HOST DEVICE DRIVER"); 22119 22120 const struct kernel_param_ops con_mode_ops = { 22121 .set = con_mode_handler, 22122 .get = param_get_int, 22123 }; 22124 22125 #ifdef FEATURE_WLAN_RESIDENT_DRIVER 22126 EXPORT_SYMBOL(con_mode_ops); 22127 #endif 22128 22129 const struct kernel_param_ops con_mode_ftm_ops = { 22130 .set = con_mode_handler_ftm, 22131 .get = param_get_int, 22132 }; 22133 22134 #ifdef FEATURE_WLAN_RESIDENT_DRIVER 22135 EXPORT_SYMBOL(con_mode_ftm_ops); 22136 #endif 22137 22138 #ifdef WLAN_FEATURE_EPPING 22139 static const struct kernel_param_ops con_mode_epping_ops = { 22140 .set = con_mode_handler_epping, 22141 .get = param_get_int, 22142 }; 22143 #endif 22144 22145 static const struct kernel_param_ops fwpath_ops = { 22146 .set = fwpath_changed_handler, 22147 .get = param_get_string, 22148 }; 22149 __pcie_set_gen_speed_handler(void)22150 static int __pcie_set_gen_speed_handler(void) 22151 { 22152 int ret; 22153 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 22154 22155 ret = wlan_hdd_validate_context(hdd_ctx); 22156 if (ret) 22157 return ret; 22158 22159 hdd_info_rl("Received PCIe gen speed %d", pcie_gen_speed); 22160 if (pcie_gen_speed <= HDD_INVALID_MIN_PCIE_GEN_SPEED || 22161 pcie_gen_speed >= HDD_INVALID_MAX_PCIE_GEN_SPEED) { 22162 hdd_err_rl("invalid pcie gen speed %d", pcie_gen_speed); 22163 return -EINVAL; 22164 } 22165 22166 hdd_ctx->current_pcie_gen_speed = pcie_gen_speed; 22167 22168 return 0; 22169 } 22170 pcie_set_gen_speed_handler(const char * kmessage,const struct kernel_param * kp)22171 static int pcie_set_gen_speed_handler(const char *kmessage, 22172 const struct kernel_param *kp) 22173 { 22174 struct osif_driver_sync *driver_sync; 22175 int ret; 22176 22177 ret = osif_driver_sync_op_start(&driver_sync); 22178 if (ret) 22179 return ret; 22180 22181 ret = param_set_int(kmessage, kp); 22182 if (ret) { 22183 hdd_err_rl("param set int failed %d", ret); 22184 goto out; 22185 } 22186 22187 ret = __pcie_set_gen_speed_handler(); 22188 22189 out: 22190 osif_driver_sync_op_stop(driver_sync); 22191 22192 return ret; 22193 } 22194 22195 static const struct kernel_param_ops pcie_gen_speed_ops = { 22196 .set = pcie_set_gen_speed_handler, 22197 .get = param_get_int, 22198 }; 22199 22200 module_param_cb(con_mode, &con_mode_ops, &con_mode, 22201 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); 22202 22203 module_param_cb(con_mode_ftm, &con_mode_ftm_ops, &con_mode_ftm, 22204 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); 22205 22206 module_param_cb(pcie_gen_speed, &pcie_gen_speed_ops, &pcie_gen_speed, 22207 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); 22208 22209 #ifdef WLAN_FEATURE_EPPING 22210 module_param_cb(con_mode_epping, &con_mode_epping_ops, 22211 &con_mode_epping, 0644); 22212 #endif 22213 22214 module_param_cb(fwpath, &fwpath_ops, &fwpath, 22215 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); 22216 22217 module_param(enable_dfs_chan_scan, int, S_IRUSR | S_IRGRP | S_IROTH); 22218 22219 module_param(enable_11d, int, S_IRUSR | S_IRGRP | S_IROTH); 22220 22221 module_param(country_code, charp, S_IRUSR | S_IRGRP | S_IROTH); 22222 timer_multiplier_get_handler(char * buffer,const struct kernel_param * kp)22223 static int timer_multiplier_get_handler(char *buffer, 22224 const struct kernel_param *kp) 22225 { 22226 return scnprintf(buffer, PAGE_SIZE, "%u", qdf_timer_get_multiplier()); 22227 } 22228 timer_multiplier_set_handler(const char * kmessage,const struct kernel_param * kp)22229 static int timer_multiplier_set_handler(const char *kmessage, 22230 const struct kernel_param *kp) 22231 { 22232 QDF_STATUS status; 22233 uint32_t scalar; 22234 22235 status = qdf_uint32_parse(kmessage, &scalar); 22236 if (QDF_IS_STATUS_ERROR(status)) 22237 return qdf_status_to_os_return(status); 22238 22239 if (!cfg_in_range(CFG_TIMER_MULTIPLIER, scalar)) 22240 return -ERANGE; 22241 22242 qdf_timer_set_multiplier(scalar); 22243 22244 return 0; 22245 } 22246 22247 static const struct kernel_param_ops timer_multiplier_ops = { 22248 .get = timer_multiplier_get_handler, 22249 .set = timer_multiplier_set_handler, 22250 }; 22251 22252 module_param_cb(timer_multiplier, &timer_multiplier_ops, NULL, 0644); 22253