1 /* 2 * Copyright (c) 2012-2021 The Linux Foundation. All rights reserved. 3 * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved. 4 * 5 * Permission to use, copy, modify, and/or distribute this software for 6 * any purpose with or without fee is hereby granted, provided that the 7 * above copyright notice and this permission notice appear in all 8 * copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 11 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 12 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 13 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 14 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 15 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 16 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 17 * PERFORMANCE OF THIS SOFTWARE. 18 */ 19 20 /** 21 * DOC: wlan_hdd_main.c 22 * 23 * WLAN Host Device Driver implementation 24 * 25 */ 26 27 /* Include Files */ 28 #include <wbuff.h> 29 #include "cfg_ucfg_api.h" 30 #include <wlan_hdd_includes.h> 31 #include <cds_api.h> 32 #include <cds_sched.h> 33 #include <linux/cpu.h> 34 #include <linux/etherdevice.h> 35 #include <linux/firmware.h> 36 #include <linux/kernel.h> 37 #include <wlan_hdd_tx_rx.h> 38 #include <wni_api.h> 39 #include <wlan_hdd_cfg.h> 40 #include <wlan_ptt_sock_svc.h> 41 #include <dbglog_host.h> 42 #include <wlan_logging_sock_svc.h> 43 #include <wlan_roam_debug.h> 44 #include <wlan_hdd_connectivity_logging.h> 45 #include "osif_sync.h" 46 #include <wlan_hdd_wowl.h> 47 #include <wlan_hdd_misc.h> 48 #include <wlan_hdd_wext.h> 49 #include "wlan_hdd_trace.h" 50 #include "wlan_hdd_ioctl.h" 51 #include "wlan_hdd_ftm.h" 52 #include "wlan_hdd_power.h" 53 #include "wlan_hdd_stats.h" 54 #include "wlan_hdd_scan.h" 55 #include "wlan_policy_mgr_ucfg.h" 56 #include "wlan_osif_priv.h" 57 #include <wlan_osif_request_manager.h> 58 #ifdef CONFIG_LEAK_DETECTION 59 #include "qdf_debug_domain.h" 60 #endif 61 #include "qdf_delayed_work.h" 62 #include "qdf_periodic_work.h" 63 #include "qdf_str.h" 64 #include "qdf_talloc.h" 65 #include "qdf_trace.h" 66 #include "qdf_types.h" 67 #include "qdf_net_if.h" 68 #include <cdp_txrx_peer_ops.h> 69 #include <cdp_txrx_misc.h> 70 #include <cdp_txrx_stats.h> 71 #include "cdp_txrx_flow_ctrl_legacy.h" 72 #include "qdf_ssr_driver_dump.h" 73 74 #include <net/addrconf.h> 75 #include <linux/wireless.h> 76 #include <net/cfg80211.h> 77 #include <linux/inetdevice.h> 78 #include <net/addrconf.h> 79 #include "wlan_hdd_cfg80211.h" 80 #include "wlan_hdd_ext_scan.h" 81 #include "wlan_hdd_p2p.h" 82 #include <linux/rtnetlink.h> 83 #include "sap_api.h" 84 #include <sap_internal.h> 85 #include <linux/semaphore.h> 86 #include <linux/ctype.h> 87 #include <linux/compat.h> 88 #include <linux/ethtool.h> 89 #include <linux/suspend.h> 90 91 #ifdef WLAN_FEATURE_DP_BUS_BANDWIDTH 92 #include "qdf_periodic_work.h" 93 #endif 94 95 #include <wlan_hdd_hostapd.h> 96 #include <wlan_hdd_softap_tx_rx.h> 97 #include <wlan_hdd_green_ap.h> 98 #include "qwlan_version.h" 99 #include "wma_types.h" 100 #include "wlan_hdd_tdls.h" 101 #ifdef FEATURE_WLAN_CH_AVOID 102 #include "cds_regdomain.h" 103 #endif /* FEATURE_WLAN_CH_AVOID */ 104 #include "cdp_txrx_flow_ctrl_v2.h" 105 #include "pld_common.h" 106 #include "wlan_hdd_ocb.h" 107 #include "wlan_hdd_nan.h" 108 #include "wlan_hdd_debugfs.h" 109 #include "wlan_hdd_debugfs_csr.h" 110 #include "wlan_hdd_driver_ops.h" 111 #include "epping_main.h" 112 #include "wlan_hdd_data_stall_detection.h" 113 #include "wlan_hdd_mpta_helper.h" 114 115 #include <wlan_hdd_ipa.h> 116 #include "hif.h" 117 #include "wma.h" 118 #include "wlan_policy_mgr_api.h" 119 #include "wlan_hdd_tsf.h" 120 #include "bmi.h" 121 #include <wlan_hdd_regulatory.h> 122 #include "wlan_hdd_lpass.h" 123 #include "wlan_nan_api.h" 124 #include <wlan_hdd_napi.h> 125 #include "wlan_hdd_disa.h" 126 #include <dispatcher_init_deinit.h> 127 #include "wlan_hdd_object_manager.h" 128 #include "cds_utils.h" 129 #include <cdp_txrx_handle.h> 130 #include <qca_vendor.h> 131 #include "wlan_pmo_ucfg_api.h" 132 #include "sir_api.h" 133 #include "os_if_wifi_pos.h" 134 #include "wifi_pos_api.h" 135 #include "wlan_hdd_oemdata.h" 136 #include "wlan_hdd_he.h" 137 #include "os_if_nan.h" 138 #include "nan_public_structs.h" 139 #include "nan_ucfg_api.h" 140 #include "wlan_reg_ucfg_api.h" 141 #include "wlan_hdd_afc.h" 142 #include "wlan_afc_ucfg_api.h" 143 #include "wlan_dfs_ucfg_api.h" 144 #include "wlan_hdd_rx_monitor.h" 145 #include "sme_power_save_api.h" 146 #include "enet.h" 147 #include <cdp_txrx_cmn_struct.h> 148 #include "wlan_hdd_sysfs.h" 149 #include "wlan_disa_ucfg_api.h" 150 #include "wlan_disa_obj_mgmt_api.h" 151 #include "wlan_action_oui_ucfg_api.h" 152 #include "wlan_ipa_ucfg_api.h" 153 #include <target_if.h> 154 #include "wlan_hdd_nud_tracking.h" 155 #include "wlan_hdd_apf.h" 156 #include "wlan_hdd_twt.h" 157 #include "qc_sap_ioctl.h" 158 #include "wlan_mlme_main.h" 159 #include "wlan_p2p_cfg_api.h" 160 #include "wlan_cfg80211_p2p.h" 161 #include "wlan_cfg80211_interop_issues_ap.h" 162 #include "wlan_tdls_cfg_api.h" 163 #include <wlan_hdd_rssi_monitor.h> 164 #include "wlan_mlme_ucfg_api.h" 165 #include "wlan_mlme_twt_ucfg_api.h" 166 #include "wlan_fwol_ucfg_api.h" 167 #include "wlan_policy_mgr_ucfg.h" 168 #include "qdf_func_tracker.h" 169 #include "pld_common.h" 170 #include "wlan_hdd_pre_cac.h" 171 172 #include "sme_api.h" 173 174 #ifdef CNSS_GENL 175 #ifdef CONFIG_CNSS_OUT_OF_TREE 176 #include "cnss_nl.h" 177 #else 178 #include <net/cnss_nl.h> 179 #endif 180 #endif 181 #include "wlan_reg_ucfg_api.h" 182 #include "wlan_ocb_ucfg_api.h" 183 #include <wlan_hdd_spectralscan.h> 184 #include "wlan_green_ap_ucfg_api.h" 185 #include <wlan_p2p_ucfg_api.h> 186 #include <wlan_interop_issues_ap_ucfg_api.h> 187 #include <target_type.h> 188 #include <wlan_hdd_debugfs_coex.h> 189 #include <wlan_hdd_debugfs_config.h> 190 #include "wlan_dlm_ucfg_api.h" 191 #include "ftm_time_sync_ucfg_api.h" 192 #include "wlan_pre_cac_ucfg_api.h" 193 #include "ol_txrx.h" 194 #include "wlan_hdd_sta_info.h" 195 #include "mac_init_api.h" 196 #include "wlan_pkt_capture_ucfg_api.h" 197 #include <wlan_hdd_sar_limits.h> 198 #include "cfg_nan_api.h" 199 #include "wlan_hdd_btc_chain_mode.h" 200 #include <wlan_hdd_dcs.h> 201 #include "wlan_hdd_debugfs_unit_test.h" 202 #include "wlan_hdd_debugfs_mibstat.h" 203 #include <wlan_hdd_hang_event.h> 204 #include "wlan_global_lmac_if_api.h" 205 #include "wlan_coex_ucfg_api.h" 206 #include "wlan_cm_roam_api.h" 207 #include "wlan_cm_roam_ucfg_api.h" 208 #include <cdp_txrx_ctrl.h> 209 #include "qdf_lock.h" 210 #include "wlan_hdd_thermal.h" 211 #include "osif_cm_util.h" 212 #include "wlan_hdd_gpio_wakeup.h" 213 #include "wlan_hdd_bootup_marker.h" 214 #include "wlan_dp_ucfg_api.h" 215 #include "wlan_hdd_medium_assess.h" 216 #include "wlan_hdd_eht.h" 217 #include <linux/bitfield.h> 218 #include "wlan_hdd_mlo.h" 219 #include <wlan_hdd_son.h> 220 #ifdef WLAN_FEATURE_11BE_MLO 221 #include <wlan_mlo_mgr_ap.h> 222 #endif 223 #include "wlan_osif_features.h" 224 #include "wlan_vdev_mgr_ucfg_api.h" 225 #include <wlan_objmgr_psoc_obj_i.h> 226 #include <wlan_objmgr_vdev_obj_i.h> 227 #include "wifi_pos_ucfg_api.h" 228 #include "osif_vdev_mgr_util.h" 229 #include <son_ucfg_api.h> 230 #include "osif_twt_util.h" 231 #include "wlan_twt_ucfg_ext_api.h" 232 #include "wlan_hdd_mcc_quota.h" 233 #include "osif_pre_cac.h" 234 #include "wlan_hdd_pre_cac.h" 235 #include "wlan_osif_features.h" 236 #ifdef WLAN_FEATURE_DYNAMIC_RX_AGGREGATION 237 #include <net/pkt_cls.h> 238 #endif 239 #include "wlan_dp_public_struct.h" 240 #include "os_if_dp.h" 241 #include <wlan_dp_ucfg_api.h> 242 #include "wlan_psoc_mlme_ucfg_api.h" 243 #include "os_if_qmi.h" 244 #include "wlan_qmi_ucfg_api.h" 245 #include "wlan_psoc_mlme_ucfg_api.h" 246 #include "wlan_ll_sap_ucfg_api.h" 247 248 #include "os_if_dp_local_pkt_capture.h" 249 #include <wlan_mlo_mgr_link_switch.h> 250 #include "cdp_txrx_mon.h" 251 252 #ifdef MULTI_CLIENT_LL_SUPPORT 253 #define WLAM_WLM_HOST_DRIVER_PORT_ID 0xFFFFFF 254 #endif 255 256 #ifdef MODULE 257 #ifdef WLAN_WEAR_CHIPSET 258 #define WLAN_MODULE_NAME "wlan" 259 #else 260 #define WLAN_MODULE_NAME module_name(THIS_MODULE) 261 #endif 262 #else 263 #define WLAN_MODULE_NAME "wlan" 264 #endif 265 266 #ifdef TIMER_MANAGER 267 #define TIMER_MANAGER_STR " +TIMER_MANAGER" 268 #else 269 #define TIMER_MANAGER_STR "" 270 #endif 271 272 #ifdef MEMORY_DEBUG 273 #define MEMORY_DEBUG_STR " +MEMORY_DEBUG" 274 #else 275 #define MEMORY_DEBUG_STR "" 276 #endif 277 278 #ifdef PANIC_ON_BUG 279 #define PANIC_ON_BUG_STR " +PANIC_ON_BUG" 280 #else 281 #define PANIC_ON_BUG_STR "" 282 #endif 283 284 /* PCIe gen speed change idle shutdown timer 100 milliseconds */ 285 #define HDD_PCIE_GEN_SPEED_CHANGE_TIMEOUT_MS (100) 286 287 #define MAX_NET_DEV_REF_LEAK_ITERATIONS 10 288 #define NET_DEV_REF_LEAK_ITERATION_SLEEP_TIME_MS 10 289 290 #ifdef FEATURE_TSO 291 #define TSO_FEATURE_FLAGS (NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_SG) 292 #else 293 #define TSO_FEATURE_FLAGS 0 294 #endif 295 296 int wlan_start_ret_val; 297 static DECLARE_COMPLETION(wlan_start_comp); 298 static qdf_atomic_t wlan_hdd_state_fops_ref; 299 #ifndef MODULE 300 static struct gwlan_loader *wlan_loader; 301 static ssize_t wlan_boot_cb(struct kobject *kobj, 302 struct kobj_attribute *attr, 303 const char *buf, size_t count); 304 struct gwlan_loader { 305 bool loaded_state; 306 struct kobject *boot_wlan_obj; 307 struct attribute_group *attr_group; 308 }; 309 310 static struct kobj_attribute wlan_boot_attribute = 311 __ATTR(boot_wlan, 0220, NULL, wlan_boot_cb); 312 313 static struct attribute *attrs[] = { 314 &wlan_boot_attribute.attr, 315 NULL, 316 }; 317 #define MODULE_INITIALIZED 1 318 319 #ifdef MULTI_IF_NAME 320 #define WLAN_LOADER_NAME "boot_" MULTI_IF_NAME 321 #else 322 #define WLAN_LOADER_NAME "boot_wlan" 323 #endif 324 #endif 325 326 /* the Android framework expects this param even though we don't use it */ 327 #define BUF_LEN 20 328 static char fwpath_buffer[BUF_LEN]; 329 static struct kparam_string fwpath = { 330 .string = fwpath_buffer, 331 .maxlen = BUF_LEN, 332 }; 333 334 char *country_code; 335 #ifdef FEATURE_WLAN_RESIDENT_DRIVER 336 EXPORT_SYMBOL(country_code); 337 #endif 338 static int enable_11d = -1; 339 static int enable_dfs_chan_scan = -1; 340 static bool is_mode_change_psoc_idle_shutdown; 341 342 #define WLAN_NLINK_CESIUM 30 343 344 static qdf_wake_lock_t wlan_wake_lock; 345 346 /* The valid PCIe gen speeds are 1, 2, 3 */ 347 #define HDD_INVALID_MIN_PCIE_GEN_SPEED (0) 348 #define HDD_INVALID_MAX_PCIE_GEN_SPEED (4) 349 350 #define MAX_PDEV_PRE_ENABLE_PARAMS 8 351 #define FTM_MAX_PDEV_PARAMS 1 352 353 #define WOW_MAX_FILTER_LISTS 1 354 #define WOW_MAX_FILTERS_PER_LIST 4 355 #define WOW_MIN_PATTERN_SIZE 6 356 #define WOW_MAX_PATTERN_SIZE 64 357 #define MGMT_DEFAULT_DATA_RATE_6GHZ 0x400 /* This maps to 8.6Mbps data rate */ 358 359 #define IS_IDLE_STOP (!cds_is_driver_unloading() && \ 360 !cds_is_driver_recovering() && !cds_is_driver_loading()) 361 362 #define HDD_FW_VER_MAJOR_SPID(tgt_fw_ver) ((tgt_fw_ver & 0xf0000000) >> 28) 363 #define HDD_FW_VER_MINOR_SPID(tgt_fw_ver) ((tgt_fw_ver & 0xf000000) >> 24) 364 #define HDD_FW_VER_SIID(tgt_fw_ver) ((tgt_fw_ver & 0xf00000) >> 20) 365 #define HDD_FW_VER_CRM_ID(tgt_fw_ver) (tgt_fw_ver & 0x7fff) 366 #define HDD_FW_VER_SUB_ID(tgt_fw_ver_ext) \ 367 (((tgt_fw_ver_ext & 0x1c00) >> 6) | ((tgt_fw_ver_ext & 0xf0000000) >> 28)) 368 #define HDD_FW_VER_REL_ID(tgt_fw_ver_ext) \ 369 ((tgt_fw_ver_ext & 0xf800000) >> 23) 370 371 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0)) 372 static const struct wiphy_wowlan_support wowlan_support_reg_init = { 373 .flags = WIPHY_WOWLAN_ANY | 374 WIPHY_WOWLAN_MAGIC_PKT | 375 WIPHY_WOWLAN_DISCONNECT | 376 WIPHY_WOWLAN_SUPPORTS_GTK_REKEY | 377 WIPHY_WOWLAN_GTK_REKEY_FAILURE | 378 WIPHY_WOWLAN_EAP_IDENTITY_REQ | 379 WIPHY_WOWLAN_4WAY_HANDSHAKE | 380 WIPHY_WOWLAN_RFKILL_RELEASE, 381 .n_patterns = WOW_MAX_FILTER_LISTS * WOW_MAX_FILTERS_PER_LIST, 382 .pattern_min_len = WOW_MIN_PATTERN_SIZE, 383 .pattern_max_len = WOW_MAX_PATTERN_SIZE, 384 }; 385 #endif 386 387 static const struct category_info cinfo[MAX_SUPPORTED_CATEGORY] = { 388 [QDF_MODULE_ID_TLSHIM] = {QDF_TRACE_LEVEL_ALL}, 389 [QDF_MODULE_ID_WMI] = {QDF_TRACE_LEVEL_ALL}, 390 [QDF_MODULE_ID_HTT] = {QDF_TRACE_LEVEL_ALL}, 391 [QDF_MODULE_ID_HDD] = {QDF_TRACE_LEVEL_ALL}, 392 [QDF_MODULE_ID_SME] = {QDF_TRACE_LEVEL_ALL}, 393 [QDF_MODULE_ID_PE] = {QDF_TRACE_LEVEL_ALL}, 394 [QDF_MODULE_ID_WMA] = {QDF_TRACE_LEVEL_ALL}, 395 [QDF_MODULE_ID_SYS] = {QDF_TRACE_LEVEL_ALL}, 396 [QDF_MODULE_ID_QDF] = {QDF_TRACE_LEVEL_ALL}, 397 [QDF_MODULE_ID_SAP] = {QDF_TRACE_LEVEL_ALL}, 398 [QDF_MODULE_ID_HDD_SOFTAP] = {QDF_TRACE_LEVEL_ALL}, 399 [QDF_MODULE_ID_HDD_DATA] = {QDF_DATA_PATH_TRACE_LEVEL}, 400 [QDF_MODULE_ID_HDD_SAP_DATA] = {QDF_DATA_PATH_TRACE_LEVEL}, 401 [QDF_MODULE_ID_HIF] = {QDF_DATA_PATH_TRACE_LEVEL}, 402 [QDF_MODULE_ID_HTC] = {QDF_DATA_PATH_TRACE_LEVEL}, 403 [QDF_MODULE_ID_TXRX] = {QDF_DATA_PATH_TRACE_LEVEL}, 404 [QDF_MODULE_ID_HAL] = {QDF_DATA_PATH_TRACE_LEVEL}, 405 [QDF_MODULE_ID_QDF_DEVICE] = {QDF_TRACE_LEVEL_ALL}, 406 [QDF_MODULE_ID_CFG] = {QDF_TRACE_LEVEL_ALL}, 407 [QDF_MODULE_ID_BMI] = {QDF_TRACE_LEVEL_ALL}, 408 [QDF_MODULE_ID_EPPING] = {QDF_TRACE_LEVEL_ALL}, 409 [QDF_MODULE_ID_QVIT] = {QDF_TRACE_LEVEL_ALL}, 410 [QDF_MODULE_ID_DP] = {QDF_DATA_PATH_TRACE_LEVEL}, 411 [QDF_MODULE_ID_DP_TX_CAPTURE] = {QDF_DATA_PATH_TRACE_LEVEL}, 412 [QDF_MODULE_ID_DP_INIT] = {QDF_DATA_PATH_TRACE_LEVEL}, 413 [QDF_MODULE_ID_DP_STATS] = {QDF_DATA_PATH_TRACE_LEVEL}, 414 [QDF_MODULE_ID_DP_HTT] = {QDF_DATA_PATH_TRACE_LEVEL}, 415 [QDF_MODULE_ID_DP_PEER] = {QDF_DATA_PATH_TRACE_LEVEL}, 416 [QDF_MODULE_ID_DP_HTT_TX_STATS] = {QDF_DATA_PATH_TRACE_LEVEL}, 417 [QDF_MODULE_ID_DP_REO] = {QDF_DATA_PATH_TRACE_LEVEL}, 418 [QDF_MODULE_ID_DP_VDEV] = {QDF_DATA_PATH_TRACE_LEVEL}, 419 [QDF_MODULE_ID_DP_CDP] = {QDF_DATA_PATH_TRACE_LEVEL}, 420 [QDF_MODULE_ID_DP_UMAC_RESET] = {QDF_DATA_PATH_TRACE_LEVEL}, 421 [QDF_MODULE_ID_DP_SAWF] = {QDF_DATA_PATH_TRACE_LEVEL}, 422 [QDF_MODULE_ID_SOC] = {QDF_TRACE_LEVEL_ALL}, 423 [QDF_MODULE_ID_OS_IF] = {QDF_TRACE_LEVEL_ALL}, 424 [QDF_MODULE_ID_TARGET_IF] = {QDF_TRACE_LEVEL_ALL}, 425 [QDF_MODULE_ID_SCHEDULER] = {QDF_TRACE_LEVEL_ALL}, 426 [QDF_MODULE_ID_MGMT_TXRX] = {QDF_TRACE_LEVEL_ALL}, 427 [QDF_MODULE_ID_PMO] = {QDF_TRACE_LEVEL_ALL}, 428 [QDF_MODULE_ID_SCAN] = {QDF_TRACE_LEVEL_ALL}, 429 [QDF_MODULE_ID_POLICY_MGR] = {QDF_TRACE_LEVEL_ALL}, 430 [QDF_MODULE_ID_P2P] = {QDF_TRACE_LEVEL_ALL}, 431 [QDF_MODULE_ID_TDLS] = {QDF_TRACE_LEVEL_ALL}, 432 [QDF_MODULE_ID_REGULATORY] = {QDF_TRACE_LEVEL_ALL}, 433 [QDF_MODULE_ID_SERIALIZATION] = {QDF_TRACE_LEVEL_ALL}, 434 [QDF_MODULE_ID_DFS] = {QDF_TRACE_LEVEL_ALL}, 435 [QDF_MODULE_ID_OBJ_MGR] = {QDF_TRACE_LEVEL_ALL}, 436 [QDF_MODULE_ID_ROAM_DEBUG] = {QDF_TRACE_LEVEL_ALL}, 437 [QDF_MODULE_ID_GREEN_AP] = {QDF_TRACE_LEVEL_ALL}, 438 [QDF_MODULE_ID_OCB] = {QDF_TRACE_LEVEL_ALL}, 439 [QDF_MODULE_ID_IPA] = {QDF_TRACE_LEVEL_ALL}, 440 [QDF_MODULE_ID_ACTION_OUI] = {QDF_TRACE_LEVEL_ALL}, 441 [QDF_MODULE_ID_CONFIG] = {QDF_TRACE_LEVEL_ALL}, 442 [QDF_MODULE_ID_MLME] = {QDF_TRACE_LEVEL_ALL}, 443 [QDF_MODULE_ID_TARGET] = {QDF_TRACE_LEVEL_ALL}, 444 [QDF_MODULE_ID_CRYPTO] = {QDF_TRACE_LEVEL_ALL}, 445 [QDF_MODULE_ID_FWOL] = {QDF_TRACE_LEVEL_ALL}, 446 [QDF_MODULE_ID_SM_ENGINE] = {QDF_TRACE_LEVEL_ALL}, 447 [QDF_MODULE_ID_CMN_MLME] = {QDF_TRACE_LEVEL_ALL}, 448 [QDF_MODULE_ID_NAN] = {QDF_TRACE_LEVEL_ALL}, 449 [QDF_MODULE_ID_CP_STATS] = {QDF_TRACE_LEVEL_ALL}, 450 [QDF_MODULE_ID_DCS] = {QDF_TRACE_LEVEL_ALL}, 451 [QDF_MODULE_ID_INTEROP_ISSUES_AP] = {QDF_TRACE_LEVEL_ALL}, 452 [QDF_MODULE_ID_DENYLIST_MGR] = {QDF_TRACE_LEVEL_ALL}, 453 [QDF_MODULE_ID_DIRECT_BUF_RX] = {QDF_TRACE_LEVEL_ALL}, 454 [QDF_MODULE_ID_SPECTRAL] = {QDF_TRACE_LEVEL_ALL}, 455 [QDF_MODULE_ID_WIFIPOS] = {QDF_TRACE_LEVEL_ALL}, 456 [QDF_MODULE_ID_PKT_CAPTURE] = {QDF_TRACE_LEVEL_ALL}, 457 [QDF_MODULE_ID_FTM_TIME_SYNC] = {QDF_TRACE_LEVEL_ALL}, 458 [QDF_MODULE_ID_CFR] = {QDF_TRACE_LEVEL_ALL}, 459 [QDF_MODULE_ID_IFMGR] = {QDF_TRACE_LEVEL_ALL}, 460 [QDF_MODULE_ID_GPIO] = {QDF_TRACE_LEVEL_ALL}, 461 [QDF_MODULE_ID_T2LM] = {QDF_TRACE_LEVEL_ALL}, 462 [QDF_MODULE_ID_MLO] = {QDF_TRACE_LEVEL_ALL}, 463 [QDF_MODULE_ID_SON] = {QDF_TRACE_LEVEL_ALL}, 464 [QDF_MODULE_ID_TWT] = {QDF_TRACE_LEVEL_ALL}, 465 [QDF_MODULE_ID_WLAN_PRE_CAC] = {QDF_TRACE_LEVEL_ALL}, 466 [QDF_MODULE_ID_COAP] = {QDF_TRACE_LEVEL_ALL}, 467 [QDF_MODULE_ID_MON_FILTER] = {QDF_DATA_PATH_TRACE_LEVEL}, 468 [QDF_MODULE_ID_LL_SAP] = {QDF_TRACE_LEVEL_ALL}, 469 }; 470 471 struct notifier_block hdd_netdev_notifier; 472 473 struct sock *cesium_nl_srv_sock; 474 #ifdef FEATURE_WLAN_AUTO_SHUTDOWN 475 static void wlan_hdd_auto_shutdown_cb(void); 476 #endif 477 478 static void hdd_dp_register_callbacks(struct hdd_context *hdd_ctx); 479 480 bool hdd_adapter_is_ap(struct hdd_adapter *adapter) 481 { 482 if (!adapter) { 483 hdd_err("null adapter"); 484 return false; 485 } 486 487 return adapter->device_mode == QDF_SAP_MODE || 488 adapter->device_mode == QDF_P2P_GO_MODE; 489 } 490 491 QDF_STATUS hdd_common_roam_callback(struct wlan_objmgr_psoc *psoc, 492 uint8_t session_id, 493 struct csr_roam_info *roam_info, 494 eRoamCmdStatus roam_status, 495 eCsrRoamResult roam_result) 496 { 497 struct hdd_context *hdd_ctx; 498 struct hdd_adapter *adapter; 499 struct wlan_hdd_link_info *link_info; 500 QDF_STATUS status = QDF_STATUS_SUCCESS; 501 502 link_info = wlan_hdd_get_link_info_from_vdev(psoc, session_id); 503 if (!link_info) 504 return QDF_STATUS_E_INVAL; 505 506 adapter = link_info->adapter; 507 hdd_ctx = WLAN_HDD_GET_CTX(adapter); 508 if (!hdd_ctx) 509 return QDF_STATUS_E_INVAL; 510 511 switch (adapter->device_mode) { 512 case QDF_STA_MODE: 513 case QDF_NDI_MODE: 514 case QDF_P2P_CLIENT_MODE: 515 case QDF_P2P_DEVICE_MODE: 516 status = hdd_sme_roam_callback(link_info, roam_info, 517 roam_status, roam_result); 518 break; 519 case QDF_SAP_MODE: 520 case QDF_P2P_GO_MODE: 521 status = 522 wlansap_roam_callback(link_info->session.ap.sap_context, 523 roam_info, roam_status, 524 roam_result); 525 break; 526 default: 527 hdd_err("Wrong device mode"); 528 break; 529 } 530 531 return status; 532 } 533 534 void hdd_start_complete(int ret) 535 { 536 wlan_start_ret_val = ret; 537 complete_all(&wlan_start_comp); 538 } 539 540 #ifdef WLAN_FEATURE_LOCAL_PKT_CAPTURE 541 /** 542 * wlan_hdd_lpc_del_monitor_interface() - Delete monitor interface 543 * @hdd_ctx: hdd_ctx 544 * 545 * This function takes care of deleting monitor interface 546 * 547 * Return: none 548 */ 549 static void 550 wlan_hdd_lpc_del_monitor_interface(struct hdd_context *hdd_ctx) 551 { 552 struct hdd_adapter *adapter; 553 void *soc; 554 bool running; 555 556 if (!hdd_ctx) 557 return; 558 559 if (!ucfg_dp_is_local_pkt_capture_enabled(hdd_ctx->psoc)) 560 return; 561 562 soc = cds_get_context(QDF_MODULE_ID_SOC); 563 if (!soc) 564 return; 565 566 running = cdp_is_local_pkt_capture_running(soc, OL_TXRX_PDEV_ID); 567 if (!running) 568 return; 569 570 adapter = hdd_get_adapter(hdd_ctx, QDF_MONITOR_MODE); 571 if (!adapter) { 572 hdd_debug("There is no monitor adapter"); 573 return; 574 } 575 576 hdd_debug("lpc: Delete monitor interface"); 577 wlan_hdd_release_intf_addr(hdd_ctx, adapter->mac_addr.bytes); 578 hdd_stop_adapter(hdd_ctx, adapter); 579 hdd_close_adapter(hdd_ctx, adapter, true); 580 } 581 #else 582 static inline 583 void wlan_hdd_lpc_del_monitor_interface(struct hdd_context *hdd_ctx) 584 { 585 } 586 #endif 587 588 #ifdef QCA_HL_NETDEV_FLOW_CONTROL 589 void wlan_hdd_mod_fc_timer(struct hdd_adapter *adapter, 590 enum netif_action_type action) 591 { 592 struct hdd_stats *hdd_stats; 593 594 if (!adapter->tx_flow_timer_initialized) 595 return; 596 597 hdd_stats = &adapter->deflink->hdd_stats; 598 if (action == WLAN_WAKE_NON_PRIORITY_QUEUE) { 599 qdf_mc_timer_stop(&adapter->tx_flow_control_timer); 600 hdd_stats->tx_rx_stats.is_txflow_paused = false; 601 hdd_stats->tx_rx_stats.txflow_unpause_cnt++; 602 } else if (action == WLAN_STOP_NON_PRIORITY_QUEUE) { 603 QDF_STATUS status = 604 qdf_mc_timer_start(&adapter->tx_flow_control_timer, 605 WLAN_HDD_TX_FLOW_CONTROL_OS_Q_BLOCK_TIME); 606 607 if (!QDF_IS_STATUS_SUCCESS(status)) 608 hdd_err("Failed to start tx_flow_control_timer"); 609 else 610 hdd_stats->tx_rx_stats.txflow_timer_cnt++; 611 612 hdd_stats->tx_rx_stats.txflow_pause_cnt++; 613 hdd_stats->tx_rx_stats.is_txflow_paused = true; 614 } 615 } 616 #endif /* QCA_HL_NETDEV_FLOW_CONTROL */ 617 618 /** 619 * wlan_hdd_txrx_pause_cb() - pause callback from txrx layer 620 * @vdev_id: vdev_id 621 * @action: action type 622 * @reason: reason type 623 * 624 * Return: none 625 */ 626 void wlan_hdd_txrx_pause_cb(uint8_t vdev_id, 627 enum netif_action_type action, enum netif_reason_type reason) 628 { 629 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 630 struct hdd_adapter *adapter; 631 struct wlan_hdd_link_info *link_info; 632 633 if (!hdd_ctx) 634 return; 635 636 link_info = hdd_get_link_info_by_vdev(hdd_ctx, vdev_id); 637 if (!link_info) 638 return; 639 640 adapter = link_info->adapter; 641 wlan_hdd_mod_fc_timer(adapter, action); 642 wlan_hdd_netif_queue_control(adapter, action, reason); 643 } 644 645 /* 646 * Store WLAN driver version and timestamp info in global variables such that 647 * crash debugger can extract them from driver debug symbol and crashdump for 648 * post processing 649 */ 650 #ifdef BUILD_TAG 651 uint8_t g_wlan_driver_version[] = QWLAN_VERSIONSTR TIMER_MANAGER_STR MEMORY_DEBUG_STR PANIC_ON_BUG_STR "; " BUILD_TAG; 652 #else 653 uint8_t g_wlan_driver_version[] = QWLAN_VERSIONSTR TIMER_MANAGER_STR MEMORY_DEBUG_STR PANIC_ON_BUG_STR; 654 #endif 655 656 int hdd_validate_channel_and_bandwidth(struct hdd_adapter *adapter, 657 qdf_freq_t chan_freq, 658 enum phy_ch_width chan_bw) 659 { 660 struct ch_params ch_params = {0}; 661 struct hdd_context *hdd_ctx; 662 663 hdd_ctx = WLAN_HDD_GET_CTX(adapter); 664 if (!hdd_ctx) { 665 hdd_err("hdd context is NULL"); 666 return -EINVAL; 667 } 668 669 if (reg_is_chan_enum_invalid( 670 wlan_reg_get_chan_enum_for_freq(chan_freq))) { 671 hdd_err("Channel freq %d not in driver's valid channel list", chan_freq); 672 return -EOPNOTSUPP; 673 } 674 675 if ((!WLAN_REG_IS_24GHZ_CH_FREQ(chan_freq)) && 676 (!WLAN_REG_IS_5GHZ_CH_FREQ(chan_freq)) && 677 (!WLAN_REG_IS_6GHZ_CHAN_FREQ(chan_freq))) { 678 hdd_err("CH %d is not in 2.4GHz or 5GHz or 6GHz", chan_freq); 679 return -EINVAL; 680 } 681 ch_params.ch_width = CH_WIDTH_MAX; 682 wlan_reg_set_channel_params_for_pwrmode(hdd_ctx->pdev, chan_freq, 683 0, &ch_params, 684 REG_CURRENT_PWR_MODE); 685 if (ch_params.ch_width == CH_WIDTH_MAX) { 686 hdd_err("failed to get max bandwdith for %d", chan_freq); 687 return -EINVAL; 688 } 689 if (WLAN_REG_IS_24GHZ_CH_FREQ(chan_freq)) { 690 if (chan_bw == CH_WIDTH_80MHZ) { 691 hdd_err("BW80 not possible in 2.4GHz band"); 692 return -EINVAL; 693 } 694 if ((chan_bw != CH_WIDTH_20MHZ) && 695 (chan_freq == wlan_reg_ch_to_freq(CHAN_ENUM_2484)) && 696 (chan_bw != CH_WIDTH_MAX) && 697 (ch_params.ch_width == CH_WIDTH_20MHZ)) { 698 hdd_err("Only BW20 possible on channel freq 2484"); 699 return -EINVAL; 700 } 701 } 702 703 if (WLAN_REG_IS_5GHZ_CH_FREQ(chan_freq)) { 704 if ((chan_bw != CH_WIDTH_20MHZ) && 705 (chan_freq == wlan_reg_ch_to_freq(CHAN_ENUM_5825)) && 706 (chan_bw != CH_WIDTH_MAX) && 707 (ch_params.ch_width == CH_WIDTH_20MHZ)) { 708 hdd_err("Only BW20 possible on channel freq 5825"); 709 return -EINVAL; 710 } 711 } 712 713 return 0; 714 } 715 716 uint32_t hdd_get_link_info_home_channel(struct wlan_hdd_link_info *link_info) 717 { 718 uint32_t home_chan_freq = 0; 719 enum QDF_OPMODE opmode = link_info->adapter->device_mode; 720 721 switch (opmode) { 722 case QDF_SAP_MODE: 723 case QDF_P2P_GO_MODE: 724 if (test_bit(SOFTAP_BSS_STARTED, &link_info->link_flags)) { 725 home_chan_freq = 726 link_info->session.ap.operating_chan_freq; 727 } 728 break; 729 case QDF_STA_MODE: 730 case QDF_P2P_CLIENT_MODE: 731 if (hdd_cm_is_vdev_associated(link_info)) { 732 home_chan_freq = 733 link_info->session.station.conn_info.chan_freq; 734 } 735 break; 736 default: 737 break; 738 } 739 740 return home_chan_freq; 741 } 742 743 enum phy_ch_width hdd_get_link_info_width(struct wlan_hdd_link_info *link_info) 744 { 745 enum phy_ch_width width = CH_WIDTH_20MHZ; 746 enum QDF_OPMODE opmode = link_info->adapter->device_mode; 747 748 switch (opmode) { 749 case QDF_SAP_MODE: 750 case QDF_P2P_GO_MODE: 751 if (test_bit(SOFTAP_BSS_STARTED, &link_info->link_flags)) { 752 struct hdd_ap_ctx *ap_ctx = 753 WLAN_HDD_GET_AP_CTX_PTR(link_info); 754 755 width = ap_ctx->sap_config.ch_params.ch_width; 756 } 757 break; 758 case QDF_STA_MODE: 759 case QDF_P2P_CLIENT_MODE: 760 if (hdd_cm_is_vdev_associated(link_info)) 761 width = link_info->session.station.conn_info.ch_width; 762 break; 763 default: 764 break; 765 } 766 767 return width; 768 } 769 770 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0)) 771 static inline struct net_device *hdd_net_dev_from_notifier(void *context) 772 { 773 struct netdev_notifier_info *info = context; 774 775 return info->dev; 776 } 777 #else 778 static inline struct net_device *hdd_net_dev_from_notifier(void *context) 779 { 780 return context; 781 } 782 #endif 783 784 static int __hdd_netdev_notifier_call(struct net_device *net_dev, 785 unsigned long state) 786 { 787 struct hdd_adapter *adapter; 788 struct hdd_context *hdd_ctx; 789 struct wlan_objmgr_vdev *vdev; 790 791 hdd_enter_dev(net_dev); 792 793 if (!net_dev->ieee80211_ptr) { 794 hdd_debug("ieee80211_ptr is null"); 795 return NOTIFY_DONE; 796 } 797 798 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 799 if (!hdd_ctx) 800 return NOTIFY_DONE; 801 802 if (hdd_ctx->driver_status == DRIVER_MODULES_CLOSED) { 803 hdd_debug("Driver module is closed"); 804 return NOTIFY_DONE; 805 } 806 807 /* Make sure that this callback corresponds to our device. */ 808 adapter = hdd_get_adapter_by_iface_name(hdd_ctx, net_dev->name); 809 if (!adapter) { 810 hdd_debug("failed to look up adapter for '%s'", net_dev->name); 811 return NOTIFY_DONE; 812 } 813 814 if (adapter != WLAN_HDD_GET_PRIV_PTR(net_dev)) { 815 hdd_err("HDD adapter mismatch!"); 816 return NOTIFY_DONE; 817 } 818 819 if (cds_is_driver_recovering()) { 820 hdd_debug("Driver is recovering"); 821 return NOTIFY_DONE; 822 } 823 824 if (cds_is_driver_in_bad_state()) { 825 hdd_debug("Driver is in failed recovery state"); 826 return NOTIFY_DONE; 827 } 828 829 hdd_debug("%s New Net Device State = %lu, flags 0x%x", 830 net_dev->name, state, net_dev->flags); 831 832 switch (state) { 833 case NETDEV_REGISTER: 834 break; 835 836 case NETDEV_UNREGISTER: 837 break; 838 839 case NETDEV_UP: 840 sme_ch_avoid_update_req(hdd_ctx->mac_handle); 841 break; 842 843 case NETDEV_DOWN: 844 break; 845 846 case NETDEV_CHANGE: 847 if (adapter->is_link_up_service_needed) 848 complete(&adapter->linkup_event_var); 849 break; 850 851 case NETDEV_GOING_DOWN: 852 vdev = hdd_objmgr_get_vdev_by_user(adapter->deflink, 853 WLAN_OSIF_SCAN_ID); 854 if (!vdev) 855 break; 856 if (ucfg_scan_get_vdev_status(vdev) != 857 SCAN_NOT_IN_PROGRESS) { 858 wlan_abort_scan(hdd_ctx->pdev, INVAL_PDEV_ID, 859 adapter->deflink->vdev_id, 860 INVALID_SCAN_ID, true); 861 } 862 hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_SCAN_ID); 863 cds_flush_work(&adapter->scan_block_work); 864 /* Need to clean up blocked scan request */ 865 wlan_hdd_cfg80211_scan_block(adapter); 866 hdd_debug("Scan is not Pending from user"); 867 /* 868 * After NETDEV_GOING_DOWN, kernel calls hdd_stop.Irrespective 869 * of return status of hdd_stop call, kernel resets the IFF_UP 870 * flag after which driver does not send the cfg80211_scan_done. 871 * Ensure to cleanup the scan queue in NETDEV_GOING_DOWN 872 */ 873 wlan_cfg80211_cleanup_scan_queue(hdd_ctx->pdev, net_dev); 874 break; 875 case NETDEV_FEAT_CHANGE: 876 hdd_debug("vdev %d netdev Feature 0x%llx\n", 877 adapter->deflink->vdev_id, net_dev->features); 878 break; 879 default: 880 break; 881 } 882 883 return NOTIFY_DONE; 884 } 885 886 static int hdd_netdev_notifier_bridge_intf(struct net_device *net_dev, 887 unsigned long state) 888 { 889 struct hdd_adapter *adapter, *next_adapter = NULL; 890 wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_GET_ADAPTER; 891 struct hdd_context *hdd_ctx; 892 QDF_STATUS status; 893 894 hdd_enter_dev(net_dev); 895 896 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 897 if (wlan_hdd_validate_context(hdd_ctx)) 898 return NOTIFY_DONE; 899 900 hdd_debug("%s New Net Device State = %lu, flags 0x%x bridge mac address: "QDF_MAC_ADDR_FMT, 901 net_dev->name, state, net_dev->flags, QDF_MAC_ADDR_REF(net_dev->dev_addr)); 902 903 if (!qdf_mem_cmp(hdd_ctx->bridgeaddr, net_dev->dev_addr, 904 QDF_MAC_ADDR_SIZE)) 905 return NOTIFY_DONE; 906 907 switch (state) { 908 case NETDEV_REGISTER: 909 case NETDEV_CHANGEADDR: 910 /* Update FW WoW pattern with new MAC address */ 911 qdf_mem_copy(hdd_ctx->bridgeaddr, net_dev->dev_addr, 912 QDF_MAC_ADDR_SIZE); 913 914 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 915 dbgid) { 916 if (adapter->device_mode != QDF_SAP_MODE) 917 goto loop_next; 918 919 if (wlan_hdd_validate_vdev_id(adapter->deflink->vdev_id)) 920 goto loop_next; 921 922 status = wlan_objmgr_vdev_try_get_ref(adapter->deflink->vdev, 923 WLAN_HDD_ID_OBJ_MGR); 924 if (QDF_IS_STATUS_ERROR(status)) 925 goto loop_next; 926 927 ucfg_pmo_set_vdev_bridge_addr(adapter->deflink->vdev, 928 (struct qdf_mac_addr *)hdd_ctx->bridgeaddr); 929 ucfg_pmo_del_wow_pattern(adapter->deflink->vdev); 930 ucfg_pmo_register_wow_default_patterns(adapter->deflink->vdev); 931 932 wlan_objmgr_vdev_release_ref(adapter->deflink->vdev, 933 WLAN_HDD_ID_OBJ_MGR); 934 935 loop_next: 936 hdd_adapter_dev_put_debug(adapter, dbgid); 937 } 938 939 break; 940 case NETDEV_UNREGISTER: 941 qdf_zero_macaddr((struct qdf_mac_addr *)hdd_ctx->bridgeaddr); 942 break; 943 default: 944 break; 945 } 946 947 return NOTIFY_DONE; 948 } 949 950 /** 951 * hdd_netdev_notifier_call() - netdev notifier callback function 952 * @nb: pointer to notifier block 953 * @state: state 954 * @context: notifier callback context pointer 955 * 956 * Return: 0 on success, error number otherwise. 957 */ 958 static int hdd_netdev_notifier_call(struct notifier_block *nb, 959 unsigned long state, 960 void *context) 961 { 962 struct net_device *net_dev = hdd_net_dev_from_notifier(context); 963 struct osif_vdev_sync *vdev_sync; 964 int errno; 965 966 if (net_dev->priv_flags & IFF_EBRIDGE) { 967 errno = hdd_netdev_notifier_bridge_intf(net_dev, state); 968 if (errno) 969 return NOTIFY_DONE; 970 } 971 972 errno = osif_vdev_sync_op_start(net_dev, &vdev_sync); 973 if (errno) 974 return NOTIFY_DONE; 975 976 errno = __hdd_netdev_notifier_call(net_dev, state); 977 978 osif_vdev_sync_op_stop(vdev_sync); 979 980 return NOTIFY_DONE; 981 } 982 983 struct notifier_block hdd_netdev_notifier = { 984 .notifier_call = hdd_netdev_notifier_call, 985 }; 986 987 /* variable to hold the insmod parameters */ 988 int con_mode; 989 #ifdef FEATURE_WLAN_RESIDENT_DRIVER 990 EXPORT_SYMBOL(con_mode); 991 #endif 992 993 int con_mode_ftm; 994 #ifdef FEATURE_WLAN_RESIDENT_DRIVER 995 EXPORT_SYMBOL(con_mode_ftm); 996 #endif 997 int con_mode_epping; 998 999 static int pcie_gen_speed; 1000 1001 /* Variable to hold connection mode including module parameter con_mode */ 1002 static int curr_con_mode; 1003 1004 #if defined(WLAN_FEATURE_11BE) && defined(CFG80211_11BE_BASIC) 1005 static enum phy_ch_width hdd_get_eht_phy_ch_width_from_target(void) 1006 { 1007 uint32_t max_fw_bw = sme_get_eht_ch_width(); 1008 1009 if (max_fw_bw == WNI_CFG_EHT_CHANNEL_WIDTH_320MHZ) 1010 return CH_WIDTH_320MHZ; 1011 else if (max_fw_bw == WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ) 1012 return CH_WIDTH_160MHZ; 1013 else 1014 return CH_WIDTH_80MHZ; 1015 } 1016 1017 static bool hdd_is_target_eht_phy_ch_width_supported(enum phy_ch_width width) 1018 { 1019 enum phy_ch_width max_fw_bw = hdd_get_eht_phy_ch_width_from_target(); 1020 1021 if (width <= max_fw_bw) 1022 return true; 1023 1024 hdd_err("FW does not support this BW %d max BW supported %d", 1025 width, max_fw_bw); 1026 return false; 1027 } 1028 1029 static bool hdd_is_target_eht_160mhz_capable(void) 1030 { 1031 return hdd_is_target_eht_phy_ch_width_supported(CH_WIDTH_160MHZ); 1032 } 1033 1034 static enum phy_ch_width 1035 wlan_hdd_map_nl_chan_width(enum nl80211_chan_width width) 1036 { 1037 if (width == NL80211_CHAN_WIDTH_320) { 1038 return hdd_get_eht_phy_ch_width_from_target(); 1039 } else { 1040 hdd_err("Invalid channel width %d, setting to default", width); 1041 return CH_WIDTH_INVALID; 1042 } 1043 } 1044 1045 #else /* !WLAN_FEATURE_11BE */ 1046 static inline bool 1047 hdd_is_target_eht_phy_ch_width_supported(enum phy_ch_width width) 1048 { 1049 return true; 1050 } 1051 1052 static inline bool hdd_is_target_eht_160mhz_capable(void) 1053 { 1054 return false; 1055 } 1056 1057 static enum phy_ch_width 1058 wlan_hdd_map_nl_chan_width(enum nl80211_chan_width width) 1059 { 1060 hdd_err("Invalid channel width %d, setting to default", width); 1061 return CH_WIDTH_INVALID; 1062 } 1063 #endif /* WLAN_FEATURE_11BE */ 1064 1065 /** 1066 * hdd_map_nl_chan_width() - Map NL channel width to internal representation 1067 * @ch_width: NL channel width 1068 * 1069 * Converts the NL channel width to the driver's internal representation 1070 * 1071 * Return: Converted channel width. In case of non matching NL channel width, 1072 * CH_WIDTH_MAX will be returned. 1073 */ 1074 enum phy_ch_width hdd_map_nl_chan_width(enum nl80211_chan_width ch_width) 1075 { 1076 uint8_t fw_ch_bw; 1077 1078 fw_ch_bw = wma_get_vht_ch_width(); 1079 switch (ch_width) { 1080 case NL80211_CHAN_WIDTH_20_NOHT: 1081 case NL80211_CHAN_WIDTH_20: 1082 return CH_WIDTH_20MHZ; 1083 case NL80211_CHAN_WIDTH_40: 1084 return CH_WIDTH_40MHZ; 1085 case NL80211_CHAN_WIDTH_80: 1086 return CH_WIDTH_80MHZ; 1087 case NL80211_CHAN_WIDTH_80P80: 1088 if (fw_ch_bw == WNI_CFG_VHT_CHANNEL_WIDTH_80_PLUS_80MHZ) 1089 return CH_WIDTH_80P80MHZ; 1090 else if (fw_ch_bw == WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ) 1091 return CH_WIDTH_160MHZ; 1092 else 1093 return CH_WIDTH_80MHZ; 1094 case NL80211_CHAN_WIDTH_160: 1095 if (hdd_is_target_eht_160mhz_capable()) 1096 return CH_WIDTH_160MHZ; 1097 1098 if (fw_ch_bw >= WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ) 1099 return CH_WIDTH_160MHZ; 1100 else 1101 return CH_WIDTH_80MHZ; 1102 case NL80211_CHAN_WIDTH_5: 1103 return CH_WIDTH_5MHZ; 1104 case NL80211_CHAN_WIDTH_10: 1105 return CH_WIDTH_10MHZ; 1106 default: 1107 return wlan_hdd_map_nl_chan_width(ch_width); 1108 } 1109 } 1110 1111 #if defined(WLAN_FEATURE_NAN) && \ 1112 (KERNEL_VERSION(4, 9, 0) <= LINUX_VERSION_CODE) 1113 /** 1114 * wlan_hdd_convert_nan_type() - Convert nl type to qdf type 1115 * @nl_type: NL80211 interface type 1116 * @out_qdf_type: QDF type for the given nl_type 1117 * 1118 * Convert nl type to QDF type 1119 * 1120 * Return: QDF_STATUS_SUCCESS if converted, failure otherwise. 1121 */ 1122 static QDF_STATUS wlan_hdd_convert_nan_type(enum nl80211_iftype nl_type, 1123 enum QDF_OPMODE *out_qdf_type) 1124 { 1125 if (nl_type == NL80211_IFTYPE_NAN) { 1126 *out_qdf_type = QDF_NAN_DISC_MODE; 1127 return QDF_STATUS_SUCCESS; 1128 } 1129 return QDF_STATUS_E_INVAL; 1130 } 1131 1132 /** 1133 * wlan_hdd_set_nan_if_type() - Set the NAN iftype 1134 * @adapter: pointer to HDD adapter 1135 * 1136 * Set the NL80211_IFTYPE_NAN to wdev iftype. 1137 * 1138 * Return: None 1139 */ 1140 static void wlan_hdd_set_nan_if_type(struct hdd_adapter *adapter) 1141 { 1142 adapter->wdev.iftype = NL80211_IFTYPE_NAN; 1143 } 1144 1145 static bool wlan_hdd_is_vdev_creation_allowed(struct wlan_objmgr_psoc *psoc) 1146 { 1147 return ucfg_nan_is_vdev_creation_allowed(psoc); 1148 } 1149 #else 1150 static QDF_STATUS wlan_hdd_convert_nan_type(enum nl80211_iftype nl_type, 1151 enum QDF_OPMODE *out_qdf_type) 1152 { 1153 return QDF_STATUS_E_INVAL; 1154 } 1155 1156 static void wlan_hdd_set_nan_if_type(struct hdd_adapter *adapter) 1157 { 1158 } 1159 1160 static bool wlan_hdd_is_vdev_creation_allowed(struct wlan_objmgr_psoc *psoc) 1161 { 1162 return false; 1163 } 1164 #endif 1165 1166 QDF_STATUS hdd_nl_to_qdf_iface_type(enum nl80211_iftype nl_type, 1167 enum QDF_OPMODE *out_qdf_type) 1168 { 1169 QDF_STATUS status = QDF_STATUS_SUCCESS; 1170 1171 switch (nl_type) { 1172 case NL80211_IFTYPE_AP: 1173 *out_qdf_type = QDF_SAP_MODE; 1174 break; 1175 case NL80211_IFTYPE_MONITOR: 1176 *out_qdf_type = QDF_MONITOR_MODE; 1177 break; 1178 case NL80211_IFTYPE_OCB: 1179 *out_qdf_type = QDF_OCB_MODE; 1180 break; 1181 case NL80211_IFTYPE_P2P_CLIENT: 1182 *out_qdf_type = QDF_P2P_CLIENT_MODE; 1183 break; 1184 case NL80211_IFTYPE_P2P_DEVICE: 1185 *out_qdf_type = QDF_P2P_DEVICE_MODE; 1186 break; 1187 case NL80211_IFTYPE_P2P_GO: 1188 *out_qdf_type = QDF_P2P_GO_MODE; 1189 break; 1190 case NL80211_IFTYPE_STATION: 1191 *out_qdf_type = QDF_STA_MODE; 1192 break; 1193 case NL80211_IFTYPE_WDS: 1194 *out_qdf_type = QDF_WDS_MODE; 1195 break; 1196 default: 1197 status = wlan_hdd_convert_nan_type(nl_type, out_qdf_type); 1198 if (QDF_IS_STATUS_SUCCESS(status)) 1199 break; 1200 hdd_err("Invalid nl80211 interface type %d", nl_type); 1201 return QDF_STATUS_E_INVAL; 1202 } 1203 1204 return QDF_STATUS_SUCCESS; 1205 } 1206 1207 uint8_t wlan_hdd_find_opclass(mac_handle_t mac_handle, uint8_t channel, 1208 uint8_t bw_offset) 1209 { 1210 uint8_t opclass = 0; 1211 1212 sme_get_opclass(mac_handle, channel, bw_offset, &opclass); 1213 return opclass; 1214 } 1215 1216 /** 1217 * hdd_qdf_trace_enable() - configure initial QDF Trace enable 1218 * @module_id: Module whose trace level is being configured 1219 * @bitmask: Bitmask of log levels to be enabled 1220 * 1221 * Called immediately after the cfg.ini is read in order to configure 1222 * the desired trace levels. 1223 * 1224 * Return: None 1225 */ 1226 int hdd_qdf_trace_enable(QDF_MODULE_ID module_id, uint32_t bitmask) 1227 { 1228 QDF_TRACE_LEVEL level; 1229 int qdf_print_idx = -1; 1230 int status = -1; 1231 /* 1232 * if the bitmask is the default value, then a bitmask was not 1233 * specified in cfg.ini, so leave the logging level alone (it 1234 * will remain at the "compiled in" default value) 1235 */ 1236 if (CFG_QDF_TRACE_ENABLE_DEFAULT == bitmask) 1237 return 0; 1238 1239 qdf_print_idx = qdf_get_pidx(); 1240 1241 /* a mask was specified. start by disabling all logging */ 1242 status = qdf_print_set_category_verbose(qdf_print_idx, module_id, 1243 QDF_TRACE_LEVEL_NONE, 0); 1244 1245 if (QDF_STATUS_SUCCESS != status) 1246 return -EINVAL; 1247 /* now cycle through the bitmask until all "set" bits are serviced */ 1248 level = QDF_TRACE_LEVEL_NONE; 1249 while (0 != bitmask) { 1250 if (bitmask & 1) { 1251 status = qdf_print_set_category_verbose(qdf_print_idx, 1252 module_id, level, 1); 1253 if (QDF_STATUS_SUCCESS != status) 1254 return -EINVAL; 1255 } 1256 1257 level++; 1258 bitmask >>= 1; 1259 } 1260 return 0; 1261 } 1262 1263 int __wlan_hdd_validate_context(struct hdd_context *hdd_ctx, const char *func) 1264 { 1265 if (!hdd_ctx) { 1266 hdd_err("HDD context is null (via %s)", func); 1267 return -ENODEV; 1268 } 1269 1270 if (!hdd_ctx->config) { 1271 hdd_err("HDD config is null (via %s)", func); 1272 return -ENODEV; 1273 } 1274 1275 if (cds_is_driver_recovering()) { 1276 hdd_debug("Recovery in progress (via %s); state:0x%x", 1277 func, cds_get_driver_state()); 1278 return -EAGAIN; 1279 } 1280 1281 if (cds_is_load_or_unload_in_progress()) { 1282 hdd_debug("Load/unload in progress (via %s); state:0x%x", 1283 func, cds_get_driver_state()); 1284 return -EAGAIN; 1285 } 1286 1287 if (cds_is_driver_in_bad_state()) { 1288 hdd_debug("Driver in bad state (via %s); state:0x%x", 1289 func, cds_get_driver_state()); 1290 return -EAGAIN; 1291 } 1292 1293 if (cds_is_fw_down()) { 1294 hdd_debug("FW is down (via %s); state:0x%x", 1295 func, cds_get_driver_state()); 1296 return -EAGAIN; 1297 } 1298 1299 if (hdd_ctx->is_wlan_disabled) { 1300 hdd_debug("WLAN is disabled by user space"); 1301 return -EAGAIN; 1302 } 1303 1304 return 0; 1305 } 1306 1307 int __hdd_validate_adapter(struct hdd_adapter *adapter, const char *func) 1308 { 1309 if (!adapter) { 1310 hdd_err("adapter is null (via %s)", func); 1311 return -EINVAL; 1312 } 1313 1314 if (adapter->magic != WLAN_HDD_ADAPTER_MAGIC) { 1315 hdd_err("bad adapter magic (via %s)", func); 1316 return -EINVAL; 1317 } 1318 1319 if (!adapter->dev) { 1320 hdd_err("adapter net_device is null (via %s)", func); 1321 return -EINVAL; 1322 } 1323 1324 if (!(adapter->dev->flags & IFF_UP)) { 1325 hdd_debug_rl("adapter '%s' is not up (via %s)", 1326 adapter->dev->name, func); 1327 return -EAGAIN; 1328 } 1329 1330 return __wlan_hdd_validate_vdev_id(adapter->deflink->vdev_id, func); 1331 } 1332 1333 int __wlan_hdd_validate_vdev_id(uint8_t vdev_id, const char *func) 1334 { 1335 if (vdev_id == WLAN_UMAC_VDEV_ID_MAX) { 1336 hdd_debug_rl("adapter is not up (via %s)", func); 1337 return -EINVAL; 1338 } 1339 1340 if (vdev_id >= WLAN_MAX_VDEVS) { 1341 hdd_err("bad vdev Id:%u (via %s)", vdev_id, func); 1342 return -EINVAL; 1343 } 1344 1345 return 0; 1346 } 1347 1348 QDF_STATUS __wlan_hdd_validate_mac_address(struct qdf_mac_addr *mac_addr, 1349 const char *func) 1350 { 1351 if (!mac_addr) { 1352 hdd_err("Received NULL mac address (via %s)", func); 1353 return QDF_STATUS_E_INVAL; 1354 } 1355 1356 if (qdf_is_macaddr_zero(mac_addr)) { 1357 hdd_err("MAC is all zero (via %s)", func); 1358 return QDF_STATUS_E_INVAL; 1359 } 1360 1361 if (qdf_is_macaddr_broadcast(mac_addr)) { 1362 hdd_err("MAC is Broadcast (via %s)", func); 1363 return QDF_STATUS_E_INVAL; 1364 } 1365 1366 if (QDF_NET_IS_MAC_MULTICAST(mac_addr->bytes)) { 1367 hdd_err("MAC is Multicast (via %s)", func); 1368 return QDF_STATUS_E_INVAL; 1369 } 1370 1371 return QDF_STATUS_SUCCESS; 1372 } 1373 1374 /** 1375 * wlan_hdd_validate_modules_state() - Check modules status 1376 * @hdd_ctx: HDD context pointer 1377 * 1378 * Check's the driver module's state and returns true if the 1379 * modules are enabled returns false if modules are closed. 1380 * 1381 * Return: True if modules are enabled or false. 1382 */ 1383 bool wlan_hdd_validate_modules_state(struct hdd_context *hdd_ctx) 1384 { 1385 if (hdd_ctx->driver_status != DRIVER_MODULES_ENABLED) { 1386 hdd_info("Modules not enabled, Present status: %d", 1387 hdd_ctx->driver_status); 1388 return false; 1389 } 1390 1391 return true; 1392 } 1393 1394 #ifdef FEATURE_RUNTIME_PM 1395 /** 1396 * hdd_runtime_suspend_context_init() - API to initialize HDD Runtime Contexts 1397 * @hdd_ctx: HDD context 1398 * 1399 * Return: None 1400 */ 1401 static void hdd_runtime_suspend_context_init(struct hdd_context *hdd_ctx) 1402 { 1403 struct hdd_runtime_pm_context *ctx = &hdd_ctx->runtime_context; 1404 1405 qdf_runtime_lock_init(&ctx->dfs); 1406 qdf_runtime_lock_init(&ctx->connect); 1407 qdf_runtime_lock_init(&ctx->user); 1408 qdf_runtime_lock_init(&ctx->monitor_mode); 1409 qdf_runtime_lock_init(&ctx->wow_unit_test); 1410 qdf_runtime_lock_init(&ctx->system_suspend); 1411 qdf_runtime_lock_init(&ctx->dyn_mac_addr_update); 1412 qdf_runtime_lock_init(&ctx->vdev_destroy); 1413 qdf_runtime_lock_init(&ctx->oem_data_cmd); 1414 1415 qdf_rtpm_register(QDF_RTPM_ID_WIPHY_SUSPEND, NULL); 1416 qdf_rtpm_register(QDF_RTPM_ID_PM_QOS_NOTIFY, NULL); 1417 1418 ctx->is_user_wakelock_acquired = false; 1419 1420 wlan_scan_runtime_pm_init(hdd_ctx->pdev); 1421 } 1422 1423 /** 1424 * hdd_runtime_suspend_context_deinit() - API to deinit HDD runtime context 1425 * @hdd_ctx: HDD Context 1426 * 1427 * Return: None 1428 */ 1429 static void hdd_runtime_suspend_context_deinit(struct hdd_context *hdd_ctx) 1430 { 1431 struct hdd_runtime_pm_context *ctx = &hdd_ctx->runtime_context; 1432 1433 if (ctx->is_user_wakelock_acquired) 1434 qdf_runtime_pm_allow_suspend(&ctx->user); 1435 1436 qdf_runtime_lock_deinit(&ctx->oem_data_cmd); 1437 qdf_runtime_lock_deinit(&ctx->dyn_mac_addr_update); 1438 qdf_runtime_lock_deinit(&ctx->wow_unit_test); 1439 qdf_runtime_lock_deinit(&ctx->monitor_mode); 1440 qdf_runtime_lock_deinit(&ctx->user); 1441 qdf_runtime_lock_deinit(&ctx->connect); 1442 qdf_runtime_lock_deinit(&ctx->dfs); 1443 qdf_runtime_lock_deinit(&ctx->system_suspend); 1444 qdf_runtime_lock_deinit(&ctx->vdev_destroy); 1445 1446 qdf_rtpm_deregister(QDF_RTPM_ID_WIPHY_SUSPEND); 1447 qdf_rtpm_deregister(QDF_RTPM_ID_PM_QOS_NOTIFY); 1448 1449 wlan_scan_runtime_pm_deinit(hdd_ctx->pdev); 1450 } 1451 1452 #else /* FEATURE_RUNTIME_PM */ 1453 static void hdd_runtime_suspend_context_init(struct hdd_context *hdd_ctx) {} 1454 static void hdd_runtime_suspend_context_deinit(struct hdd_context *hdd_ctx) {} 1455 #endif /* FEATURE_RUNTIME_PM */ 1456 1457 void hdd_update_macaddr(struct hdd_context *hdd_ctx, 1458 struct qdf_mac_addr hw_macaddr, bool generate_mac_auto) 1459 { 1460 int8_t i; 1461 uint8_t macaddr_b3, tmp_br3; 1462 1463 /* 1464 * If "generate_mac_auto" is true, it indicates that all the 1465 * addresses are derived addresses, else the first addresses 1466 * is not derived address (It is provided by fw). 1467 */ 1468 if (!generate_mac_auto) { 1469 qdf_mem_copy(hdd_ctx->provisioned_mac_addr[0].bytes, 1470 hw_macaddr.bytes, QDF_MAC_ADDR_SIZE); 1471 hdd_ctx->num_provisioned_addr++; 1472 hdd_debug("hdd_ctx->provisioned_mac_addr[0]: " 1473 QDF_MAC_ADDR_FMT, 1474 QDF_MAC_ADDR_REF(hdd_ctx-> 1475 provisioned_mac_addr[0].bytes)); 1476 } else { 1477 qdf_mem_copy(hdd_ctx->derived_mac_addr[0].bytes, 1478 hw_macaddr.bytes, 1479 QDF_MAC_ADDR_SIZE); 1480 hdd_ctx->num_derived_addr++; 1481 hdd_debug("hdd_ctx->derived_mac_addr[0]: " 1482 QDF_MAC_ADDR_FMT, 1483 QDF_MAC_ADDR_REF(hdd_ctx->derived_mac_addr[0].bytes)); 1484 } 1485 for (i = hdd_ctx->num_derived_addr; i < (QDF_MAX_CONCURRENCY_PERSONA - 1486 hdd_ctx->num_provisioned_addr); 1487 i++) { 1488 qdf_mem_copy(hdd_ctx->derived_mac_addr[i].bytes, 1489 hw_macaddr.bytes, 1490 QDF_MAC_ADDR_SIZE); 1491 macaddr_b3 = hdd_ctx->derived_mac_addr[i].bytes[3]; 1492 tmp_br3 = ((macaddr_b3 >> 4 & INTF_MACADDR_MASK) + i) & 1493 INTF_MACADDR_MASK; 1494 macaddr_b3 += tmp_br3; 1495 1496 /* XOR-ing bit-24 of the mac address. This will give enough 1497 * mac address range before collision 1498 */ 1499 macaddr_b3 ^= (1 << 7); 1500 1501 /* Set locally administered bit */ 1502 hdd_ctx->derived_mac_addr[i].bytes[0] |= 0x02; 1503 hdd_ctx->derived_mac_addr[i].bytes[3] = macaddr_b3; 1504 hdd_debug("hdd_ctx->derived_mac_addr[%d]: " 1505 QDF_MAC_ADDR_FMT, i, 1506 QDF_MAC_ADDR_REF(hdd_ctx->derived_mac_addr[i].bytes)); 1507 hdd_ctx->num_derived_addr++; 1508 } 1509 } 1510 1511 #ifdef FEATURE_WLAN_TDLS 1512 static int hdd_update_tdls_config(struct hdd_context *hdd_ctx) 1513 { 1514 struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc; 1515 struct tdls_start_params tdls_cfg; 1516 QDF_STATUS status; 1517 struct wlan_mlme_nss_chains vdev_ini_cfg; 1518 1519 /* Populate the nss chain params from ini for this vdev type */ 1520 sme_populate_nss_chain_params(hdd_ctx->mac_handle, &vdev_ini_cfg, 1521 QDF_TDLS_MODE, 1522 hdd_ctx->num_rf_chains); 1523 1524 cfg_tdls_set_vdev_nss_2g(hdd_ctx->psoc, 1525 vdev_ini_cfg.rx_nss[NSS_CHAINS_BAND_2GHZ]); 1526 cfg_tdls_set_vdev_nss_5g(hdd_ctx->psoc, 1527 vdev_ini_cfg.rx_nss[NSS_CHAINS_BAND_5GHZ]); 1528 hdd_init_tdls_config(&tdls_cfg); 1529 tdls_cfg.tdls_del_all_peers = eWNI_SME_DEL_ALL_TDLS_PEERS; 1530 tdls_cfg.tdls_update_dp_vdev_flags = CDP_UPDATE_TDLS_FLAGS; 1531 tdls_cfg.tdls_event_cb = wlan_cfg80211_tdls_event_callback; 1532 tdls_cfg.tdls_evt_cb_data = psoc; 1533 tdls_cfg.tdls_peer_context = hdd_ctx; 1534 tdls_cfg.tdls_reg_peer = hdd_tdls_register_peer; 1535 tdls_cfg.tdls_wmm_cb = hdd_wmm_is_acm_allowed; 1536 tdls_cfg.tdls_wmm_cb_data = psoc; 1537 tdls_cfg.tdls_rx_cb = wlan_cfg80211_tdls_rx_callback; 1538 tdls_cfg.tdls_rx_cb_data = psoc; 1539 tdls_cfg.tdls_dp_vdev_update = hdd_update_dp_vdev_flags; 1540 tdls_cfg.tdls_osif_init_cb = wlan_cfg80211_tdls_osif_priv_init; 1541 tdls_cfg.tdls_osif_deinit_cb = wlan_cfg80211_tdls_osif_priv_deinit; 1542 tdls_cfg.tdls_osif_update_cb.tdls_osif_conn_update = 1543 hdd_check_and_set_tdls_conn_params; 1544 tdls_cfg.tdls_osif_update_cb.tdls_osif_disconn_update = 1545 hdd_check_and_set_tdls_disconn_params; 1546 1547 status = ucfg_tdls_update_config(psoc, &tdls_cfg); 1548 if (status != QDF_STATUS_SUCCESS) { 1549 hdd_err("failed pmo psoc configuration"); 1550 return -EINVAL; 1551 } 1552 1553 hdd_ctx->tdls_umac_comp_active = true; 1554 /* enable napier specific tdls data path */ 1555 hdd_ctx->tdls_nap_active = true; 1556 1557 return 0; 1558 } 1559 #else 1560 static int hdd_update_tdls_config(struct hdd_context *hdd_ctx) 1561 { 1562 return 0; 1563 } 1564 #endif 1565 1566 void hdd_indicate_active_ndp_cnt(struct wlan_objmgr_psoc *psoc, 1567 uint8_t vdev_id, uint8_t cnt) 1568 { 1569 struct wlan_hdd_link_info *link_info; 1570 1571 link_info = wlan_hdd_get_link_info_from_vdev(psoc, vdev_id); 1572 if (!link_info || !cfg_nan_is_roam_config_disabled(psoc)) 1573 return; 1574 1575 hdd_debug("vdev_id:%d%s active ndp sessions present", vdev_id, 1576 cnt ? "" : " no more"); 1577 if (!cnt) 1578 wlan_hdd_set_roaming_state(link_info, RSO_NDP_CON_ON_NDI, true); 1579 else 1580 wlan_hdd_set_roaming_state(link_info, RSO_NDP_CON_ON_NDI, 1581 false); 1582 } 1583 1584 #ifdef WLAN_FEATURE_ROAM_OFFLOAD 1585 static void hdd_update_roam_offload(struct hdd_context *hdd_ctx, 1586 struct wma_tgt_services *cfg) 1587 { 1588 bool roam_offload_enable; 1589 1590 ucfg_mlme_get_roaming_offload(hdd_ctx->psoc, &roam_offload_enable); 1591 ucfg_mlme_set_roaming_offload(hdd_ctx->psoc, 1592 roam_offload_enable & 1593 cfg->en_roam_offload); 1594 } 1595 #else 1596 static inline void hdd_update_roam_offload(struct hdd_context *hdd_ctx, 1597 struct wma_tgt_services *cfg) 1598 { 1599 } 1600 #endif 1601 1602 #ifdef FEATURE_CLUB_LL_STATS_AND_GET_STATION 1603 static void 1604 hdd_club_ll_stats_in_get_sta_cfg_update(struct hdd_config *config, 1605 struct wlan_objmgr_psoc *psoc) 1606 { 1607 config->sta_stats_cache_expiry_time = 1608 cfg_get(psoc, CFG_STA_STATS_CACHE_EXPIRY); 1609 } 1610 1611 static void 1612 hdd_update_feature_cfg_club_get_sta_in_ll_stats_req( 1613 struct hdd_context *hdd_ctx, 1614 struct wma_tgt_services *cfg) 1615 { 1616 hdd_ctx->is_get_station_clubbed_in_ll_stats_req = 1617 cfg->is_get_station_clubbed_in_ll_stats_req && 1618 cfg_get(hdd_ctx->psoc, 1619 CFG_CLUB_LL_STA_AND_GET_STATION); 1620 } 1621 1622 static void 1623 hdd_init_get_sta_in_ll_stats_config(struct hdd_adapter *adapter) 1624 { 1625 adapter->sta_stats_cached_timestamp = 0; 1626 } 1627 #else 1628 static void 1629 hdd_club_ll_stats_in_get_sta_cfg_update(struct hdd_config *config, 1630 struct wlan_objmgr_psoc *psoc) 1631 { 1632 } 1633 1634 static void 1635 hdd_update_feature_cfg_club_get_sta_in_ll_stats_req( 1636 struct hdd_context *hdd_ctx, 1637 struct wma_tgt_services *cfg) 1638 { 1639 } 1640 1641 static void 1642 hdd_init_get_sta_in_ll_stats_config(struct hdd_adapter *adapter) 1643 { 1644 } 1645 #endif /* FEATURE_CLUB_LL_STATS_AND_GET_STATION */ 1646 1647 #ifdef WLAN_FEATURE_IGMP_OFFLOAD 1648 static void 1649 hdd_intersect_igmp_offload_setting(struct wlan_objmgr_psoc *psoc, 1650 struct wma_tgt_services *cfg) 1651 { 1652 bool igmp_offload_enable; 1653 1654 igmp_offload_enable = 1655 ucfg_pmo_is_igmp_offload_enabled(psoc); 1656 ucfg_pmo_set_igmp_offload_enabled(psoc, 1657 igmp_offload_enable & 1658 cfg->igmp_offload_enable); 1659 hdd_info("fw cap to handle igmp %d igmp_offload_enable ini %d", 1660 cfg->igmp_offload_enable, igmp_offload_enable); 1661 } 1662 #else 1663 static inline void 1664 hdd_intersect_igmp_offload_setting(struct wlan_objmgr_psoc *psoc, 1665 struct wma_tgt_services *cfg) 1666 {} 1667 #endif 1668 1669 #ifdef FEATURE_WLAN_TDLS 1670 static void hdd_update_fw_tdls_wideband_capability(struct hdd_context *hdd_ctx, 1671 struct wma_tgt_services *cfg) 1672 { 1673 ucfg_tdls_update_fw_wideband_capability(hdd_ctx->psoc, 1674 cfg->en_tdls_wideband_support); 1675 } 1676 1677 #ifdef WLAN_FEATURE_11BE 1678 static void hdd_update_fw_tdls_mlo_capability(struct hdd_context *hdd_ctx, 1679 struct wma_tgt_services *cfg) 1680 { 1681 ucfg_tdls_update_fw_mlo_capability(hdd_ctx->psoc, 1682 cfg->en_tdls_mlo_support); 1683 } 1684 #else 1685 static inline 1686 void hdd_update_fw_tdls_mlo_capability(struct hdd_context *hdd_ctx, 1687 struct wma_tgt_services *cfg) 1688 {} 1689 #endif 1690 1691 #ifdef WLAN_FEATURE_11AX 1692 static void hdd_update_fw_tdls_11ax_capability(struct hdd_context *hdd_ctx, 1693 struct wma_tgt_services *cfg) 1694 { 1695 ucfg_tdls_update_fw_11ax_capability(hdd_ctx->psoc, 1696 cfg->en_tdls_11ax_support); 1697 } 1698 1699 static void hdd_update_fw_tdls_6g_capability(struct hdd_context *hdd_ctx, 1700 struct wma_tgt_services *cfg) 1701 { 1702 ucfg_update_fw_tdls_6g_capability(hdd_ctx->psoc, 1703 cfg->en_tdls_6g_support); 1704 } 1705 1706 #else 1707 static inline 1708 void hdd_update_fw_tdls_11ax_capability(struct hdd_context *hdd_ctx, 1709 struct wma_tgt_services *cfg) 1710 {} 1711 static inline 1712 void hdd_update_fw_tdls_6g_capability(struct hdd_context *hdd_ctx, 1713 struct wma_tgt_services *cfg) 1714 {} 1715 #endif 1716 #else 1717 static inline 1718 void hdd_update_fw_tdls_mlo_capability(struct hdd_context *hdd_ctx, 1719 struct wma_tgt_services *cfg) 1720 {} 1721 1722 static inline 1723 void hdd_update_fw_tdls_11ax_capability(struct hdd_context *hdd_ctx, 1724 struct wma_tgt_services *cfg) 1725 {} 1726 1727 static inline 1728 void hdd_update_fw_tdls_6g_capability(struct hdd_context *hdd_ctx, 1729 struct wma_tgt_services *cfg) 1730 {} 1731 1732 static inline 1733 void hdd_update_fw_tdls_wideband_capability(struct hdd_context *hdd_ctx, 1734 struct wma_tgt_services *cfg) 1735 {} 1736 #endif 1737 1738 #ifdef WLAN_FEATURE_DYNAMIC_MAC_ADDR_UPDATE 1739 static inline void 1740 hdd_set_dynamic_macaddr_update_capability(struct hdd_context *hdd_ctx, 1741 struct wma_tgt_services *cfg) 1742 { 1743 hdd_ctx->is_vdev_macaddr_dynamic_update_supported = 1744 cfg->dynamic_vdev_macaddr_support && 1745 cfg_get(hdd_ctx->psoc, 1746 CFG_DYNAMIC_MAC_ADDR_UPDATE_SUPPORTED); 1747 } 1748 #else 1749 static inline void 1750 hdd_set_dynamic_macaddr_update_capability(struct hdd_context *hdd_ctx, 1751 struct wma_tgt_services *cfg) 1752 { 1753 } 1754 #endif 1755 1756 #ifdef WLAN_FEATURE_11BE 1757 static bool hdd_dot11Mode_support_11be(enum hdd_dot11_mode dot11Mode) 1758 { 1759 if (dot11Mode != eHDD_DOT11_MODE_AUTO && 1760 dot11Mode < eHDD_DOT11_MODE_11be) 1761 return false; 1762 1763 return true; 1764 } 1765 #else 1766 static bool hdd_dot11Mode_support_11be(enum hdd_dot11_mode dot11Mode) 1767 { 1768 return false; 1769 } 1770 #endif 1771 1772 #ifdef WLAN_FEATURE_11BE_MLO 1773 static void 1774 hdd_update_mlo_per_link_stats_capability(struct hdd_context *hdd_ctx, 1775 struct wma_tgt_services *cfg) 1776 { 1777 hdd_ctx->is_mlo_per_link_stats_supported = 1778 cfg->is_mlo_per_link_stats_supported; 1779 } 1780 #else 1781 static void 1782 hdd_update_mlo_per_link_stats_capability(struct hdd_context *hdd_ctx, 1783 struct wma_tgt_services *cfg) 1784 { 1785 } 1786 #endif 1787 1788 static void hdd_update_tgt_services(struct hdd_context *hdd_ctx, 1789 struct wma_tgt_services *cfg) 1790 { 1791 struct hdd_config *config = hdd_ctx->config; 1792 bool arp_offload_enable; 1793 bool mawc_enabled; 1794 #ifdef FEATURE_WLAN_TDLS 1795 bool tdls_support; 1796 bool tdls_off_channel; 1797 bool tdls_buffer_sta; 1798 uint32_t tdls_uapsd_mask; 1799 #endif 1800 bool get_peer_info_enable; 1801 1802 /* Set up UAPSD */ 1803 ucfg_mlme_set_sap_uapsd_flag(hdd_ctx->psoc, cfg->uapsd); 1804 1805 /* 11AX mode support */ 1806 if ((config->dot11Mode == eHDD_DOT11_MODE_11ax || 1807 config->dot11Mode == eHDD_DOT11_MODE_11ax_ONLY) && !cfg->en_11ax) 1808 config->dot11Mode = eHDD_DOT11_MODE_11ac; 1809 1810 /* 11AC mode support */ 1811 if ((config->dot11Mode == eHDD_DOT11_MODE_11ac || 1812 config->dot11Mode == eHDD_DOT11_MODE_11ac_ONLY) && !cfg->en_11ac) 1813 config->dot11Mode = eHDD_DOT11_MODE_AUTO; 1814 /* 11BE mode support */ 1815 if (!hdd_dot11Mode_support_11be(config->dot11Mode) && 1816 cfg->en_11be) { 1817 hdd_debug("dot11Mode %d override target en_11be to false", 1818 config->dot11Mode); 1819 cfg->en_11be = false; 1820 } 1821 1822 /* ARP offload: override user setting if invalid */ 1823 arp_offload_enable = 1824 ucfg_pmo_is_arp_offload_enabled(hdd_ctx->psoc); 1825 ucfg_pmo_set_arp_offload_enabled(hdd_ctx->psoc, 1826 arp_offload_enable & cfg->arp_offload); 1827 1828 /* Intersect igmp offload ini configuration and fw cap*/ 1829 hdd_intersect_igmp_offload_setting(hdd_ctx->psoc, cfg); 1830 1831 #ifdef FEATURE_WLAN_SCAN_PNO 1832 /* PNO offload */ 1833 hdd_debug("PNO Capability in f/w = %d", cfg->pno_offload); 1834 if (cfg->pno_offload) 1835 ucfg_scan_set_pno_offload(hdd_ctx->psoc, true); 1836 #endif 1837 #ifdef FEATURE_WLAN_TDLS 1838 cfg_tdls_get_support_enable(hdd_ctx->psoc, &tdls_support); 1839 cfg_tdls_set_support_enable(hdd_ctx->psoc, 1840 tdls_support & cfg->en_tdls); 1841 1842 cfg_tdls_get_off_channel_enable(hdd_ctx->psoc, &tdls_off_channel); 1843 cfg_tdls_set_off_channel_enable(hdd_ctx->psoc, 1844 tdls_off_channel && 1845 cfg->en_tdls_offchan); 1846 1847 cfg_tdls_get_buffer_sta_enable(hdd_ctx->psoc, &tdls_buffer_sta); 1848 cfg_tdls_set_buffer_sta_enable(hdd_ctx->psoc, 1849 tdls_buffer_sta && 1850 cfg->en_tdls_uapsd_buf_sta); 1851 1852 cfg_tdls_get_uapsd_mask(hdd_ctx->psoc, &tdls_uapsd_mask); 1853 if (tdls_uapsd_mask && cfg->en_tdls_uapsd_sleep_sta) 1854 cfg_tdls_set_sleep_sta_enable(hdd_ctx->psoc, true); 1855 else 1856 cfg_tdls_set_sleep_sta_enable(hdd_ctx->psoc, false); 1857 #endif 1858 hdd_update_roam_offload(hdd_ctx, cfg); 1859 1860 if (ucfg_mlme_get_sap_get_peer_info( 1861 hdd_ctx->psoc, &get_peer_info_enable) == QDF_STATUS_SUCCESS) { 1862 get_peer_info_enable &= cfg->get_peer_info_enabled; 1863 ucfg_mlme_set_sap_get_peer_info(hdd_ctx->psoc, 1864 get_peer_info_enable); 1865 } 1866 1867 ucfg_mlme_is_mawc_enabled(hdd_ctx->psoc, &mawc_enabled); 1868 ucfg_mlme_set_mawc_enabled(hdd_ctx->psoc, 1869 mawc_enabled & cfg->is_fw_mawc_capable); 1870 hdd_update_tdls_config(hdd_ctx); 1871 sme_update_tgt_services(hdd_ctx->mac_handle, cfg); 1872 hdd_ctx->roam_ch_from_fw_supported = cfg->is_roam_scan_ch_to_host; 1873 hdd_ctx->ll_stats_per_chan_rx_tx_time = 1874 cfg->ll_stats_per_chan_rx_tx_time; 1875 1876 hdd_update_feature_cfg_club_get_sta_in_ll_stats_req(hdd_ctx, cfg); 1877 hdd_ctx->is_therm_cmd_supp = 1878 cfg->is_fw_therm_throt_supp && 1879 cfg_get(hdd_ctx->psoc, 1880 CFG_THERMAL_MITIGATION_ENABLE); 1881 hdd_update_fw_tdls_11ax_capability(hdd_ctx, cfg); 1882 hdd_update_fw_tdls_mlo_capability(hdd_ctx, cfg); 1883 hdd_set_dynamic_macaddr_update_capability(hdd_ctx, cfg); 1884 hdd_update_fw_tdls_6g_capability(hdd_ctx, cfg); 1885 hdd_update_fw_tdls_wideband_capability(hdd_ctx, cfg); 1886 ucfg_psoc_mlme_set_11be_capab(hdd_ctx->psoc, cfg->en_11be); 1887 hdd_update_mlo_per_link_stats_capability(hdd_ctx, cfg); 1888 } 1889 1890 /** 1891 * hdd_update_vdev_nss() - sets the vdev nss 1892 * @hdd_ctx: HDD context 1893 * 1894 * Sets the Nss per vdev type based on INI 1895 * 1896 * Return: None 1897 */ 1898 static void hdd_update_vdev_nss(struct hdd_context *hdd_ctx) 1899 { 1900 uint8_t max_supp_nss = 1; 1901 mac_handle_t mac_handle; 1902 QDF_STATUS status; 1903 bool bval; 1904 1905 status = ucfg_mlme_get_vht_enable2x2(hdd_ctx->psoc, &bval); 1906 if (!QDF_IS_STATUS_SUCCESS(status)) 1907 hdd_err("unable to get vht_enable2x2"); 1908 1909 if (bval && !cds_is_sub_20_mhz_enabled()) 1910 max_supp_nss = 2; 1911 1912 hdd_debug("max nss %d", max_supp_nss); 1913 1914 mac_handle = hdd_ctx->mac_handle; 1915 sme_update_vdev_type_nss(mac_handle, max_supp_nss, 1916 NSS_CHAINS_BAND_2GHZ); 1917 1918 sme_update_vdev_type_nss(mac_handle, max_supp_nss, 1919 NSS_CHAINS_BAND_5GHZ); 1920 } 1921 1922 /** 1923 * hdd_update_2g_wiphy_vhtcap() - Updates 2G wiphy vhtcap fields 1924 * @hdd_ctx: HDD context 1925 * 1926 * Updates 2G wiphy vhtcap fields 1927 * 1928 * Return: None 1929 */ 1930 static void hdd_update_2g_wiphy_vhtcap(struct hdd_context *hdd_ctx) 1931 { 1932 struct ieee80211_supported_band *band_2g = 1933 hdd_ctx->wiphy->bands[NL80211_BAND_2GHZ]; 1934 uint32_t value; 1935 bool is_vht_24ghz; 1936 1937 if (!band_2g) { 1938 hdd_debug("2GHz band disabled, skipping capability population"); 1939 return; 1940 } 1941 1942 ucfg_mlme_get_vht_for_24ghz(hdd_ctx->psoc, &is_vht_24ghz); 1943 1944 if (is_vht_24ghz) { 1945 ucfg_mlme_cfg_get_vht_tx_mcs_map(hdd_ctx->psoc, &value); 1946 band_2g->vht_cap.vht_mcs.tx_mcs_map = value; 1947 } 1948 } 1949 1950 /** 1951 * hdd_update_5g_wiphy_vhtcap() - Updates 5G wiphy vhtcap fields 1952 * @hdd_ctx: HDD context 1953 * 1954 * Updates 5G wiphy vhtcap fields 1955 * 1956 * Return: None 1957 */ 1958 static void hdd_update_5g_wiphy_vhtcap(struct hdd_context *hdd_ctx) 1959 { 1960 struct ieee80211_supported_band *band_5g = 1961 hdd_ctx->wiphy->bands[NL80211_BAND_5GHZ]; 1962 QDF_STATUS status; 1963 uint8_t value = 0, value1 = 0; 1964 uint32_t value2; 1965 1966 if (!band_5g) { 1967 hdd_debug("5GHz band disabled, skipping capability population"); 1968 return; 1969 } 1970 1971 status = ucfg_mlme_cfg_get_vht_tx_bfee_ant_supp(hdd_ctx->psoc, 1972 &value); 1973 if (!QDF_IS_STATUS_SUCCESS(status)) 1974 hdd_err("unable to get tx_bfee_ant_supp"); 1975 1976 band_5g->vht_cap.cap |= 1977 (value << IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT); 1978 1979 value1 = NUM_OF_SOUNDING_DIMENSIONS; 1980 band_5g->vht_cap.cap |= 1981 (value1 << IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_SHIFT); 1982 1983 hdd_debug("Updated wiphy vhtcap:0x%x, CSNAntSupp:%d, NumSoundDim:%d", 1984 band_5g->vht_cap.cap, value, value1); 1985 1986 ucfg_mlme_cfg_get_vht_rx_mcs_map(hdd_ctx->psoc, &value2); 1987 band_5g->vht_cap.vht_mcs.rx_mcs_map = value2; 1988 1989 ucfg_mlme_cfg_get_vht_tx_mcs_map(hdd_ctx->psoc, &value2); 1990 band_5g->vht_cap.vht_mcs.tx_mcs_map = value2; 1991 } 1992 1993 /** 1994 * hdd_update_wiphy_vhtcap() - Updates wiphy vhtcap fields 1995 * @hdd_ctx: HDD context 1996 * 1997 * Updates wiphy vhtcap fields 1998 * 1999 * Return: None 2000 */ 2001 static void hdd_update_wiphy_vhtcap(struct hdd_context *hdd_ctx) 2002 { 2003 hdd_update_2g_wiphy_vhtcap(hdd_ctx); 2004 hdd_update_5g_wiphy_vhtcap(hdd_ctx); 2005 } 2006 2007 static void hdd_update_tgt_ht_cap(struct hdd_context *hdd_ctx, 2008 struct wma_tgt_ht_cap *cfg) 2009 { 2010 QDF_STATUS status; 2011 qdf_size_t value_len; 2012 uint32_t value; 2013 uint8_t mpdu_density; 2014 struct mlme_ht_capabilities_info ht_cap_info; 2015 uint8_t mcs_set[SIZE_OF_SUPPORTED_MCS_SET]; 2016 bool b_enable1x1; 2017 2018 /* get the MPDU density */ 2019 status = ucfg_mlme_get_ht_mpdu_density(hdd_ctx->psoc, &mpdu_density); 2020 if (QDF_IS_STATUS_ERROR(status)) { 2021 hdd_err("could not get HT MPDU Density"); 2022 return; 2023 } 2024 2025 /* 2026 * MPDU density: 2027 * override user's setting if value is larger 2028 * than the one supported by target, 2029 * if target value is 0, then follow user's setting. 2030 */ 2031 if (cfg->mpdu_density && mpdu_density > cfg->mpdu_density) { 2032 status = ucfg_mlme_set_ht_mpdu_density(hdd_ctx->psoc, 2033 cfg->mpdu_density); 2034 if (QDF_IS_STATUS_ERROR(status)) 2035 hdd_err("could not set HT capability to CCM"); 2036 } 2037 2038 /* get the HT capability info */ 2039 status = ucfg_mlme_get_ht_cap_info(hdd_ctx->psoc, &ht_cap_info); 2040 if (QDF_STATUS_SUCCESS != status) { 2041 hdd_err("could not get HT capability info"); 2042 return; 2043 } 2044 2045 /* check and update RX STBC */ 2046 if (ht_cap_info.rx_stbc && !cfg->ht_rx_stbc) 2047 ht_cap_info.rx_stbc = cfg->ht_rx_stbc; 2048 2049 /* Set the LDPC capability */ 2050 if (ht_cap_info.adv_coding_cap && !cfg->ht_rx_ldpc) 2051 ht_cap_info.adv_coding_cap = cfg->ht_rx_ldpc; 2052 2053 if (ht_cap_info.short_gi_20_mhz && !cfg->ht_sgi_20) 2054 ht_cap_info.short_gi_20_mhz = cfg->ht_sgi_20; 2055 2056 if (ht_cap_info.short_gi_40_mhz && !cfg->ht_sgi_40) 2057 ht_cap_info.short_gi_40_mhz = cfg->ht_sgi_40; 2058 2059 hdd_ctx->num_rf_chains = cfg->num_rf_chains; 2060 hdd_ctx->ht_tx_stbc_supported = cfg->ht_tx_stbc; 2061 2062 status = ucfg_mlme_get_vht_enable2x2(hdd_ctx->psoc, &b_enable1x1); 2063 if (!QDF_IS_STATUS_SUCCESS(status)) 2064 hdd_err("unable to get vht_enable2x2"); 2065 2066 b_enable1x1 = b_enable1x1 && (cfg->num_rf_chains == 2); 2067 2068 status = ucfg_mlme_set_vht_enable2x2(hdd_ctx->psoc, b_enable1x1); 2069 if (!QDF_IS_STATUS_SUCCESS(status)) 2070 hdd_err("unable to set vht_enable2x2"); 2071 2072 if (!b_enable1x1) 2073 ht_cap_info.tx_stbc = 0; 2074 2075 if (!(cfg->ht_tx_stbc && b_enable1x1)) 2076 ht_cap_info.tx_stbc = 0; 2077 2078 status = ucfg_mlme_set_ht_cap_info(hdd_ctx->psoc, ht_cap_info); 2079 if (status != QDF_STATUS_SUCCESS) 2080 hdd_err("could not set HT capability to CCM"); 2081 #define WLAN_HDD_RX_MCS_ALL_NSTREAM_RATES 0xff 2082 value_len = SIZE_OF_SUPPORTED_MCS_SET; 2083 if (ucfg_mlme_get_supported_mcs_set( 2084 hdd_ctx->psoc, mcs_set, 2085 &value_len) == QDF_STATUS_SUCCESS) { 2086 hdd_debug("Read MCS rate set"); 2087 if (cfg->num_rf_chains > SIZE_OF_SUPPORTED_MCS_SET) 2088 cfg->num_rf_chains = SIZE_OF_SUPPORTED_MCS_SET; 2089 2090 if (b_enable1x1) { 2091 for (value = 0; value < cfg->num_rf_chains; value++) 2092 mcs_set[value] = 2093 WLAN_HDD_RX_MCS_ALL_NSTREAM_RATES; 2094 2095 status = ucfg_mlme_set_supported_mcs_set( 2096 hdd_ctx->psoc, 2097 mcs_set, 2098 (qdf_size_t)SIZE_OF_SUPPORTED_MCS_SET); 2099 if (QDF_IS_STATUS_ERROR(status)) 2100 hdd_err("could not set MCS SET to CCM"); 2101 } 2102 } 2103 #undef WLAN_HDD_RX_MCS_ALL_NSTREAM_RATES 2104 } 2105 2106 static void hdd_update_tgt_vht_cap(struct hdd_context *hdd_ctx, 2107 struct wma_tgt_vht_cap *cfg) 2108 { 2109 QDF_STATUS status; 2110 struct wiphy *wiphy = hdd_ctx->wiphy; 2111 struct ieee80211_supported_band *band_5g = 2112 wiphy->bands[HDD_NL80211_BAND_5GHZ]; 2113 uint32_t ch_width; 2114 struct wma_caps_per_phy caps_per_phy = {0}; 2115 bool vht_enable_2x2; 2116 uint32_t tx_highest_data_rate; 2117 uint32_t rx_highest_data_rate; 2118 2119 if (!band_5g) { 2120 hdd_debug("5GHz band disabled, skipping capability population"); 2121 return; 2122 } 2123 2124 status = ucfg_mlme_update_vht_cap(hdd_ctx->psoc, cfg); 2125 if (QDF_IS_STATUS_ERROR(status)) 2126 hdd_err("could not update vht capabilities"); 2127 2128 status = ucfg_mlme_get_vht_enable2x2(hdd_ctx->psoc, &vht_enable_2x2); 2129 if (!QDF_IS_STATUS_SUCCESS(status)) 2130 hdd_err("unable to get vht_enable2x2"); 2131 2132 if (vht_enable_2x2) { 2133 tx_highest_data_rate = 2134 VHT_TX_HIGHEST_SUPPORTED_DATA_RATE_2_2; 2135 rx_highest_data_rate = 2136 VHT_RX_HIGHEST_SUPPORTED_DATA_RATE_2_2; 2137 } else { 2138 tx_highest_data_rate = 2139 VHT_TX_HIGHEST_SUPPORTED_DATA_RATE_1_1; 2140 rx_highest_data_rate = 2141 VHT_RX_HIGHEST_SUPPORTED_DATA_RATE_1_1; 2142 } 2143 2144 status = ucfg_mlme_cfg_set_vht_rx_supp_data_rate(hdd_ctx->psoc, 2145 rx_highest_data_rate); 2146 if (!QDF_IS_STATUS_SUCCESS(status)) 2147 hdd_err("Failed to set rx_supp_data_rate"); 2148 2149 status = ucfg_mlme_cfg_set_vht_tx_supp_data_rate(hdd_ctx->psoc, 2150 tx_highest_data_rate); 2151 if (!QDF_IS_STATUS_SUCCESS(status)) 2152 hdd_err("Failed to set tx_supp_data_rate"); 2153 2154 /* Update the real highest data rate to wiphy */ 2155 if (cfg->vht_short_gi_80 & WMI_VHT_CAP_SGI_80MHZ) { 2156 if (vht_enable_2x2) { 2157 tx_highest_data_rate = 2158 VHT_TX_HIGHEST_SUPPORTED_DATA_RATE_2_2_SGI80; 2159 rx_highest_data_rate = 2160 VHT_RX_HIGHEST_SUPPORTED_DATA_RATE_2_2_SGI80; 2161 } else { 2162 tx_highest_data_rate = 2163 VHT_TX_HIGHEST_SUPPORTED_DATA_RATE_1_1_SGI80; 2164 rx_highest_data_rate = 2165 VHT_RX_HIGHEST_SUPPORTED_DATA_RATE_1_1_SGI80; 2166 } 2167 } 2168 2169 if (WMI_VHT_CAP_MAX_MPDU_LEN_11454 == cfg->vht_max_mpdu) 2170 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454; 2171 else if (WMI_VHT_CAP_MAX_MPDU_LEN_7935 == cfg->vht_max_mpdu) 2172 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_7991; 2173 else 2174 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_3895; 2175 2176 2177 if (cfg->supp_chan_width & (1 << eHT_CHANNEL_WIDTH_80P80MHZ)) { 2178 band_5g->vht_cap.cap |= 2179 IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ; 2180 ch_width = VHT_CAP_160_AND_80P80_SUPP; 2181 } else if (cfg->supp_chan_width & (1 << eHT_CHANNEL_WIDTH_160MHZ)) { 2182 band_5g->vht_cap.cap |= 2183 IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ; 2184 ch_width = VHT_CAP_160_SUPP; 2185 } else { 2186 ch_width = VHT_CAP_NO_160M_SUPP; 2187 } 2188 2189 status = ucfg_mlme_set_vht_ch_width(hdd_ctx->psoc, ch_width); 2190 if (QDF_IS_STATUS_ERROR(status)) 2191 hdd_err("could not set the channel width"); 2192 else 2193 hdd_debug("supported channel width %d", ch_width); 2194 2195 if (cfg->vht_rx_ldpc & WMI_VHT_CAP_RX_LDPC) { 2196 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_RXLDPC; 2197 hdd_debug("VHT RxLDPC capability is set"); 2198 } else { 2199 /* 2200 * Get the RX LDPC capability for the NON DBS 2201 * hardware mode for 5G band 2202 */ 2203 status = wma_get_caps_for_phyidx_hwmode(&caps_per_phy, 2204 HW_MODE_DBS_NONE, CDS_BAND_5GHZ); 2205 if ((QDF_IS_STATUS_SUCCESS(status)) && 2206 (caps_per_phy.vht_5g & WMI_VHT_CAP_RX_LDPC)) { 2207 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_RXLDPC; 2208 hdd_debug("VHT RX LDPC capability is set"); 2209 } 2210 } 2211 2212 if (cfg->vht_short_gi_80 & WMI_VHT_CAP_SGI_80MHZ) 2213 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_SHORT_GI_80; 2214 if (cfg->vht_short_gi_160 & WMI_VHT_CAP_SGI_160MHZ) 2215 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_SHORT_GI_160; 2216 2217 if (vht_enable_2x2 && (cfg->vht_tx_stbc & WMI_VHT_CAP_TX_STBC)) 2218 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_TXSTBC; 2219 2220 if (cfg->vht_rx_stbc & WMI_VHT_CAP_RX_STBC_1SS) 2221 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_RXSTBC_1; 2222 if (vht_enable_2x2 && (cfg->vht_rx_stbc & WMI_VHT_CAP_RX_STBC_2SS)) 2223 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_RXSTBC_2; 2224 if (cfg->vht_rx_stbc & WMI_VHT_CAP_RX_STBC_3SS) 2225 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_RXSTBC_3; 2226 2227 band_5g->vht_cap.cap |= 2228 (cfg->vht_max_ampdu_len_exp << 2229 IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT); 2230 2231 if (cfg->vht_su_bformer & WMI_VHT_CAP_SU_BFORMER) 2232 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE; 2233 if (cfg->vht_su_bformee & WMI_VHT_CAP_SU_BFORMEE) 2234 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE; 2235 if (cfg->vht_mu_bformer & WMI_VHT_CAP_MU_BFORMER) 2236 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE; 2237 if (cfg->vht_mu_bformee & WMI_VHT_CAP_MU_BFORMEE) 2238 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE; 2239 2240 if (cfg->vht_txop_ps & WMI_VHT_CAP_TXOP_PS) 2241 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_VHT_TXOP_PS; 2242 2243 band_5g->vht_cap.vht_mcs.rx_highest = cpu_to_le16(rx_highest_data_rate); 2244 band_5g->vht_cap.vht_mcs.tx_highest = cpu_to_le16(tx_highest_data_rate); 2245 } 2246 2247 /** 2248 * hdd_generate_macaddr_auto() - Auto-generate mac address 2249 * @hdd_ctx: Pointer to the HDD context 2250 * 2251 * Auto-generate mac address using device serial number. 2252 * Keep the first 3 bytes of OUI as before and replace 2253 * the last 3 bytes with the lower 3 bytes of serial number. 2254 * 2255 * Return: 0 for success 2256 * Non zero failure code for errors 2257 */ 2258 static int hdd_generate_macaddr_auto(struct hdd_context *hdd_ctx) 2259 { 2260 unsigned int serialno = 0; 2261 struct qdf_mac_addr mac_addr = { 2262 {0x00, 0x0A, 0xF5, 0x00, 0x00, 0x00} 2263 }; 2264 2265 serialno = pld_socinfo_get_serial_number(hdd_ctx->parent_dev); 2266 if (serialno == 0) 2267 return -EINVAL; 2268 2269 serialno &= 0x00ffffff; 2270 2271 mac_addr.bytes[3] = (serialno >> 16) & 0xff; 2272 mac_addr.bytes[4] = (serialno >> 8) & 0xff; 2273 mac_addr.bytes[5] = serialno & 0xff; 2274 2275 hdd_update_macaddr(hdd_ctx, mac_addr, true); 2276 return 0; 2277 } 2278 2279 static void hdd_sar_target_config(struct hdd_context *hdd_ctx, 2280 struct wma_tgt_cfg *cfg) 2281 { 2282 hdd_ctx->sar_version = cfg->sar_version; 2283 } 2284 2285 static void hdd_update_vhtcap_2g(struct hdd_context *hdd_ctx) 2286 { 2287 uint64_t chip_mode = 0; 2288 QDF_STATUS status; 2289 bool b2g_vht_cfg = false; 2290 bool b2g_vht_target = false; 2291 struct wma_caps_per_phy caps_per_phy = {0}; 2292 struct wmi_unified *wmi_handle; 2293 2294 wmi_handle = get_wmi_unified_hdl_from_psoc(hdd_ctx->psoc); 2295 if (!wmi_handle) { 2296 hdd_err("wmi handle is NULL"); 2297 return; 2298 } 2299 2300 status = ucfg_mlme_get_vht_for_24ghz(hdd_ctx->psoc, &b2g_vht_cfg); 2301 if (QDF_IS_STATUS_ERROR(status)) { 2302 hdd_err("Failed to get 2g vht mode"); 2303 return; 2304 } 2305 if (wmi_service_enabled(wmi_handle, wmi_service_ext_msg)) { 2306 status = wma_get_caps_for_phyidx_hwmode(&caps_per_phy, 2307 HW_MODE_DBS_NONE, 2308 CDS_BAND_2GHZ); 2309 if (QDF_IS_STATUS_ERROR(status)) { 2310 hdd_err("Failed to get phy caps"); 2311 return; 2312 } 2313 if (caps_per_phy.vht_2g) 2314 b2g_vht_target = true; 2315 } else { 2316 status = wlan_reg_get_chip_mode(hdd_ctx->pdev, &chip_mode); 2317 if (QDF_IS_STATUS_ERROR(status)) { 2318 hdd_err("Failed to get chip mode"); 2319 return; 2320 } 2321 b2g_vht_target = 2322 (chip_mode & HOST_REGDMN_MODE_11AC_VHT20_2G) ? 2323 true : false; 2324 } 2325 2326 b2g_vht_cfg = b2g_vht_cfg && b2g_vht_target; 2327 hdd_debug("vht 2g target: %d, cfg: %d", b2g_vht_target, b2g_vht_cfg); 2328 status = ucfg_mlme_set_vht_for_24ghz(hdd_ctx->psoc, b2g_vht_cfg); 2329 if (QDF_IS_STATUS_ERROR(status)) { 2330 hdd_err("Failed to update 2g vht mode"); 2331 return; 2332 } 2333 } 2334 2335 static void hdd_extract_fw_version_info(struct hdd_context *hdd_ctx) 2336 { 2337 hdd_ctx->fw_version_info.major_spid = 2338 HDD_FW_VER_MAJOR_SPID(hdd_ctx->target_fw_version); 2339 hdd_ctx->fw_version_info.minor_spid = 2340 HDD_FW_VER_MINOR_SPID(hdd_ctx->target_fw_version); 2341 hdd_ctx->fw_version_info.siid = 2342 HDD_FW_VER_SIID(hdd_ctx->target_fw_version); 2343 hdd_ctx->fw_version_info.crmid = 2344 HDD_FW_VER_CRM_ID(hdd_ctx->target_fw_version); 2345 hdd_ctx->fw_version_info.sub_id = 2346 HDD_FW_VER_SUB_ID(hdd_ctx->target_fw_vers_ext); 2347 hdd_ctx->fw_version_info.rel_id = 2348 HDD_FW_VER_REL_ID(hdd_ctx->target_fw_vers_ext); 2349 } 2350 2351 #if defined(WLAN_FEATURE_11AX) && \ 2352 (defined(CFG80211_SBAND_IFTYPE_DATA_BACKPORT) || \ 2353 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0))) 2354 2355 static void 2356 hdd_update_wiphy_he_mcs(struct ieee80211_sband_iftype_data *iftype_data, 2357 tDot11fIEhe_cap *he_cap_cfg) 2358 { 2359 if (!iftype_data || !he_cap_cfg) { 2360 hdd_err("Unable to update wiphy he_mcs"); 2361 return; 2362 } 2363 2364 iftype_data->he_cap.he_mcs_nss_supp.tx_mcs_80 = 2365 he_cap_cfg->tx_he_mcs_map_lt_80; 2366 iftype_data->he_cap.he_mcs_nss_supp.tx_mcs_160 = 2367 *((uint16_t *)he_cap_cfg->tx_he_mcs_map_160); 2368 iftype_data->he_cap.he_mcs_nss_supp.tx_mcs_80p80 = 2369 *((uint16_t *)he_cap_cfg->tx_he_mcs_map_80_80); 2370 } 2371 2372 #if defined(CONFIG_BAND_6GHZ) && (defined(IEEE80211_HE_6GHZ_CAP_MIN_MPDU_START)) 2373 static void hdd_update_wiphy_he_6ghz_capa(struct hdd_context *hdd_ctx) 2374 { 2375 uint16_t he_6ghz_capa = 0; 2376 uint8_t min_mpdu_start_spacing; 2377 uint8_t max_ampdu_len_exp; 2378 uint8_t max_mpdu_len; 2379 uint8_t sm_pow_save; 2380 2381 ucfg_mlme_get_ht_mpdu_density(hdd_ctx->psoc, &min_mpdu_start_spacing); 2382 he_6ghz_capa |= FIELD_PREP(IEEE80211_HE_6GHZ_CAP_MIN_MPDU_START, 2383 min_mpdu_start_spacing); 2384 2385 ucfg_mlme_cfg_get_vht_ampdu_len_exp(hdd_ctx->psoc, &max_ampdu_len_exp); 2386 he_6ghz_capa |= FIELD_PREP(IEEE80211_HE_6GHZ_CAP_MAX_AMPDU_LEN_EXP, 2387 max_ampdu_len_exp); 2388 2389 ucfg_mlme_cfg_get_vht_max_mpdu_len(hdd_ctx->psoc, &max_mpdu_len); 2390 he_6ghz_capa |= FIELD_PREP(IEEE80211_HE_6GHZ_CAP_MAX_MPDU_LEN, 2391 max_mpdu_len); 2392 2393 ucfg_mlme_cfg_get_ht_smps(hdd_ctx->psoc, &sm_pow_save); 2394 he_6ghz_capa |= FIELD_PREP(IEEE80211_HE_6GHZ_CAP_SM_PS, sm_pow_save); 2395 2396 he_6ghz_capa |= IEEE80211_HE_6GHZ_CAP_RX_ANTPAT_CONS; 2397 he_6ghz_capa |= IEEE80211_HE_6GHZ_CAP_TX_ANTPAT_CONS; 2398 2399 hdd_ctx->iftype_data_6g->he_6ghz_capa.capa = he_6ghz_capa; 2400 } 2401 #else 2402 static inline void hdd_update_wiphy_he_6ghz_capa(struct hdd_context *hdd_ctx) 2403 { 2404 } 2405 #endif 2406 2407 #if defined(CONFIG_BAND_6GHZ) && (defined(CFG80211_6GHZ_BAND_SUPPORTED) || \ 2408 (KERNEL_VERSION(5, 4, 0) <= LINUX_VERSION_CODE)) 2409 static void 2410 hdd_update_wiphy_he_caps_6ghz(struct hdd_context *hdd_ctx, 2411 tDot11fIEhe_cap *he_cap_cfg) 2412 { 2413 struct ieee80211_supported_band *band_6g = 2414 hdd_ctx->wiphy->bands[HDD_NL80211_BAND_6GHZ]; 2415 uint8_t *phy_info = 2416 hdd_ctx->iftype_data_6g->he_cap.he_cap_elem.phy_cap_info; 2417 uint8_t *mac_info_6g = 2418 hdd_ctx->iftype_data_6g->he_cap.he_cap_elem.mac_cap_info; 2419 uint8_t max_fw_bw = sme_get_vht_ch_width(); 2420 2421 if (!band_6g || !phy_info) { 2422 hdd_debug("6ghz not supported in wiphy"); 2423 return; 2424 } 2425 2426 hdd_ctx->iftype_data_6g->types_mask = 2427 (BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP)); 2428 hdd_ctx->iftype_data_6g->he_cap.has_he = true; 2429 band_6g->n_iftype_data = 1; 2430 2431 if (max_fw_bw >= WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ) 2432 phy_info[0] |= 2433 IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_80MHZ_IN_5G; 2434 if (max_fw_bw >= WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ) 2435 phy_info[0] |= 2436 IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_160MHZ_IN_5G; 2437 if (max_fw_bw >= WNI_CFG_VHT_CHANNEL_WIDTH_80_PLUS_80MHZ) 2438 phy_info[0] |= 2439 IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G; 2440 2441 if (he_cap_cfg->twt_request) 2442 mac_info_6g[0] |= IEEE80211_HE_MAC_CAP0_TWT_REQ; 2443 2444 if (he_cap_cfg->twt_responder) 2445 mac_info_6g[0] |= IEEE80211_HE_MAC_CAP0_TWT_RES; 2446 2447 hdd_update_wiphy_he_6ghz_capa(hdd_ctx); 2448 2449 hdd_update_wiphy_he_mcs(hdd_ctx->iftype_data_6g, he_cap_cfg); 2450 2451 band_6g->iftype_data = hdd_ctx->iftype_data_6g; 2452 } 2453 #else 2454 static inline void 2455 hdd_update_wiphy_he_caps_6ghz(struct hdd_context *hdd_ctx, 2456 tDot11fIEhe_cap *he_cap_cfg) 2457 { 2458 } 2459 #endif 2460 2461 static void hdd_update_wiphy_he_cap(struct hdd_context *hdd_ctx) 2462 { 2463 tDot11fIEhe_cap he_cap_cfg; 2464 struct ieee80211_supported_band *band_2g = 2465 hdd_ctx->wiphy->bands[HDD_NL80211_BAND_2GHZ]; 2466 struct ieee80211_supported_band *band_5g = 2467 hdd_ctx->wiphy->bands[HDD_NL80211_BAND_5GHZ]; 2468 QDF_STATUS status; 2469 uint8_t *phy_info_5g = 2470 hdd_ctx->iftype_data_5g->he_cap.he_cap_elem.phy_cap_info; 2471 uint8_t max_fw_bw = sme_get_vht_ch_width(); 2472 uint32_t channel_bonding_mode_2g; 2473 uint8_t *phy_info_2g = 2474 hdd_ctx->iftype_data_2g->he_cap.he_cap_elem.phy_cap_info; 2475 uint8_t *mac_info_2g = 2476 hdd_ctx->iftype_data_2g->he_cap.he_cap_elem.mac_cap_info; 2477 uint8_t *mac_info_5g = 2478 hdd_ctx->iftype_data_5g->he_cap.he_cap_elem.mac_cap_info; 2479 2480 status = ucfg_mlme_cfg_get_he_caps(hdd_ctx->psoc, &he_cap_cfg); 2481 2482 if (QDF_IS_STATUS_ERROR(status)) 2483 return; 2484 2485 if (band_2g) { 2486 hdd_ctx->iftype_data_2g->types_mask = 2487 (BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP)); 2488 hdd_ctx->iftype_data_2g->he_cap.has_he = he_cap_cfg.present; 2489 band_2g->n_iftype_data = 1; 2490 hdd_update_wiphy_he_mcs(hdd_ctx->iftype_data_2g, &he_cap_cfg); 2491 band_2g->iftype_data = hdd_ctx->iftype_data_2g; 2492 2493 ucfg_mlme_get_channel_bonding_24ghz(hdd_ctx->psoc, 2494 &channel_bonding_mode_2g); 2495 if (channel_bonding_mode_2g) 2496 phy_info_2g[0] |= 2497 IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_IN_2G; 2498 2499 if (he_cap_cfg.twt_request) 2500 mac_info_2g[0] |= IEEE80211_HE_MAC_CAP0_TWT_REQ; 2501 2502 if (he_cap_cfg.twt_responder) 2503 mac_info_2g[0] |= IEEE80211_HE_MAC_CAP0_TWT_RES; 2504 } 2505 if (band_5g) { 2506 hdd_ctx->iftype_data_5g->types_mask = 2507 (BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP)); 2508 hdd_ctx->iftype_data_5g->he_cap.has_he = he_cap_cfg.present; 2509 band_5g->n_iftype_data = 1; 2510 hdd_update_wiphy_he_mcs(hdd_ctx->iftype_data_5g, &he_cap_cfg); 2511 band_5g->iftype_data = hdd_ctx->iftype_data_5g; 2512 2513 if (max_fw_bw >= WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ) 2514 phy_info_5g[0] |= 2515 IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_80MHZ_IN_5G; 2516 if (max_fw_bw >= WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ) 2517 phy_info_5g[0] |= 2518 IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_160MHZ_IN_5G; 2519 if (max_fw_bw >= WNI_CFG_VHT_CHANNEL_WIDTH_80_PLUS_80MHZ) 2520 phy_info_5g[0] |= 2521 IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G; 2522 2523 if (he_cap_cfg.twt_request) 2524 mac_info_5g[0] |= IEEE80211_HE_MAC_CAP0_TWT_REQ; 2525 2526 if (he_cap_cfg.twt_responder) 2527 mac_info_5g[0] |= IEEE80211_HE_MAC_CAP0_TWT_RES; 2528 } 2529 2530 hdd_update_wiphy_he_caps_6ghz(hdd_ctx, &he_cap_cfg); 2531 } 2532 #else 2533 static void hdd_update_wiphy_he_cap(struct hdd_context *hdd_ctx) 2534 { 2535 } 2536 #endif 2537 2538 static void hdd_component_cfg_chan_to_freq(struct wlan_objmgr_pdev *pdev) 2539 { 2540 ucfg_mlme_cfg_chan_to_freq(pdev); 2541 } 2542 2543 static uint32_t hdd_update_band_cap_from_dot11mode( 2544 struct hdd_context *hdd_ctx, uint32_t band_capability) 2545 { 2546 if (hdd_ctx->config->dot11Mode == eHDD_DOT11_MODE_AUTO) 2547 return band_capability; 2548 2549 if (hdd_ctx->config->dot11Mode == eHDD_DOT11_MODE_11b || 2550 hdd_ctx->config->dot11Mode == eHDD_DOT11_MODE_11g || 2551 hdd_ctx->config->dot11Mode == eHDD_DOT11_MODE_11g_ONLY || 2552 hdd_ctx->config->dot11Mode == eHDD_DOT11_MODE_11b_ONLY) 2553 band_capability = (band_capability & (~BIT(REG_BAND_5G))); 2554 2555 if (hdd_ctx->config->dot11Mode == eHDD_DOT11_MODE_11a) 2556 band_capability = (band_capability & (~BIT(REG_BAND_2G))); 2557 2558 if (hdd_ctx->config->dot11Mode != eHDD_DOT11_MODE_11ax_ONLY && 2559 hdd_ctx->config->dot11Mode != eHDD_DOT11_MODE_11ax) 2560 band_capability = (band_capability & (~BIT(REG_BAND_6G))); 2561 2562 qdf_debug("Update band capability %x", band_capability); 2563 return band_capability; 2564 } 2565 2566 #ifdef FEATURE_WPSS_THERMAL_MITIGATION 2567 static inline 2568 void hdd_update_multi_client_thermal_support(struct hdd_context *hdd_ctx) 2569 { 2570 struct wmi_unified *wmi_handle; 2571 2572 wmi_handle = get_wmi_unified_hdl_from_psoc(hdd_ctx->psoc); 2573 if (!wmi_handle) 2574 return; 2575 2576 hdd_ctx->multi_client_thermal_mitigation = 2577 wmi_service_enabled(wmi_handle, 2578 wmi_service_thermal_multi_client_support); 2579 } 2580 #else 2581 static inline 2582 void hdd_update_multi_client_thermal_support(struct hdd_context *hdd_ctx) 2583 { 2584 } 2585 #endif 2586 2587 #ifdef WLAN_FEATURE_LOCAL_PKT_CAPTURE 2588 static void hdd_lpc_enable_powersave(struct hdd_context *hdd_ctx) 2589 { 2590 struct hdd_adapter *sta_adapter; 2591 2592 if (!ucfg_dp_is_local_pkt_capture_enabled(hdd_ctx->psoc)) 2593 return; 2594 2595 ucfg_fwol_configure_global_params(hdd_ctx->psoc, hdd_ctx->pdev); 2596 2597 sta_adapter = hdd_get_adapter(hdd_ctx, QDF_STA_MODE); 2598 if (!sta_adapter) { 2599 hdd_debug("STA adapter does not exist"); 2600 return; 2601 } 2602 2603 wlan_hdd_set_powersave(sta_adapter->deflink, true, 0); 2604 } 2605 2606 static void hdd_lpc_disable_powersave(struct hdd_context *hdd_ctx) 2607 { 2608 struct hdd_adapter *sta_adapter; 2609 2610 if (!ucfg_dp_is_local_pkt_capture_enabled(hdd_ctx->psoc)) 2611 return; 2612 2613 ucfg_fwol_set_ilp_config(hdd_ctx->psoc, hdd_ctx->pdev, 0); 2614 2615 sta_adapter = hdd_get_adapter(hdd_ctx, QDF_STA_MODE); 2616 if (!sta_adapter) { 2617 hdd_err("STA adapter does not exist"); 2618 return; 2619 } 2620 wlan_hdd_set_powersave(sta_adapter->deflink, false, 0); 2621 } 2622 #else 2623 static inline void hdd_lpc_enable_powersave(struct hdd_context *hdd_ctx) 2624 { 2625 } 2626 2627 static inline void hdd_lpc_disable_powersave(struct hdd_context *hdd_ctx) 2628 { 2629 } 2630 #endif 2631 2632 int hdd_update_tgt_cfg(hdd_handle_t hdd_handle, struct wma_tgt_cfg *cfg) 2633 { 2634 int ret; 2635 struct hdd_context *hdd_ctx = hdd_handle_to_context(hdd_handle); 2636 uint32_t temp_band_cap, band_capability; 2637 struct cds_config_info *cds_cfg = cds_get_ini_config(); 2638 uint8_t antenna_mode; 2639 uint8_t sub_20_chan_width; 2640 QDF_STATUS status; 2641 mac_handle_t mac_handle; 2642 bool bval = false; 2643 uint8_t value = 0; 2644 uint32_t fine_time_meas_cap = 0; 2645 enum nss_chains_band_info band; 2646 bool enable_dynamic_cfg; 2647 2648 if (!hdd_ctx) { 2649 hdd_err("HDD context is NULL"); 2650 return -EINVAL; 2651 } 2652 ret = hdd_objmgr_create_and_store_pdev(hdd_ctx); 2653 if (ret) { 2654 QDF_DEBUG_PANIC("Failed to create pdev; errno:%d", ret); 2655 return -EINVAL; 2656 } 2657 2658 hdd_debug("New pdev has been created with pdev_id = %u", 2659 hdd_ctx->pdev->pdev_objmgr.wlan_pdev_id); 2660 2661 status = dispatcher_pdev_open(hdd_ctx->pdev); 2662 if (QDF_IS_STATUS_ERROR(status)) { 2663 QDF_DEBUG_PANIC("dispatcher pdev open failed; status:%d", 2664 status); 2665 ret = qdf_status_to_os_return(status); 2666 goto exit; 2667 } 2668 2669 status = hdd_component_pdev_open(hdd_ctx->pdev); 2670 if (QDF_IS_STATUS_ERROR(status)) { 2671 QDF_DEBUG_PANIC("hdd component pdev open failed; status:%d", 2672 status); 2673 ret = qdf_status_to_os_return(status); 2674 goto dispatcher_close; 2675 } 2676 /* 2677 * For 6GHz support this api is added to convert mlme cfgs 2678 * channel numbers to frequency 2679 */ 2680 hdd_component_cfg_chan_to_freq(hdd_ctx->pdev); 2681 2682 hdd_objmgr_update_tgt_max_vdev_psoc(hdd_ctx, cfg->max_intf_count); 2683 2684 ucfg_ipa_set_dp_handle(hdd_ctx->psoc, 2685 cds_get_context(QDF_MODULE_ID_SOC)); 2686 ucfg_ipa_set_pdev_id(hdd_ctx->psoc, OL_TXRX_PDEV_ID); 2687 2688 status = ucfg_mlme_get_sub_20_chan_width(hdd_ctx->psoc, 2689 &sub_20_chan_width); 2690 if (QDF_IS_STATUS_ERROR(status)) { 2691 hdd_err("Failed to get sub_20_chan_width config"); 2692 ret = qdf_status_to_os_return(status); 2693 goto pdev_close; 2694 } 2695 2696 if (cds_cfg) { 2697 if (sub_20_chan_width != 2698 WLAN_SUB_20_CH_WIDTH_NONE && !cfg->sub_20_support) { 2699 hdd_err("User requested sub 20 MHz channel width but unsupported by FW."); 2700 cds_cfg->sub_20_channel_width = 2701 WLAN_SUB_20_CH_WIDTH_NONE; 2702 } else { 2703 cds_cfg->sub_20_channel_width = sub_20_chan_width; 2704 } 2705 } 2706 2707 status = ucfg_mlme_get_band_capability(hdd_ctx->psoc, &band_capability); 2708 if (QDF_IS_STATUS_ERROR(status)) { 2709 hdd_err("Failed to get MLME band capability"); 2710 ret = qdf_status_to_os_return(status); 2711 goto pdev_close; 2712 } 2713 2714 band_capability = 2715 hdd_update_band_cap_from_dot11mode(hdd_ctx, band_capability); 2716 2717 /* first store the INI band capability */ 2718 temp_band_cap = band_capability; 2719 2720 band_capability = cfg->band_cap; 2721 hdd_ctx->is_fils_roaming_supported = 2722 cfg->services.is_fils_roaming_supported; 2723 2724 hdd_ctx->config->is_11k_offload_supported = 2725 cfg->services.is_11k_offload_supported; 2726 2727 /* 2728 * merge the target band capability with INI setting if the merge has 2729 * at least 1 band enabled 2730 */ 2731 temp_band_cap &= band_capability; 2732 if (!temp_band_cap) 2733 hdd_warn("ini BandCapability not supported by the target"); 2734 else 2735 band_capability = temp_band_cap; 2736 2737 status = ucfg_mlme_set_band_capability(hdd_ctx->psoc, band_capability); 2738 if (QDF_IS_STATUS_ERROR(status)) { 2739 hdd_err("Failed to set MLME Band Capability"); 2740 ret = qdf_status_to_os_return(status); 2741 goto pdev_close; 2742 } 2743 2744 hdd_ctx->curr_band = band_capability; 2745 hdd_ctx->psoc->soc_nif.user_config.band_capability = hdd_ctx->curr_band; 2746 2747 status = wlan_hdd_update_wiphy_supported_band(hdd_ctx); 2748 if (QDF_IS_STATUS_ERROR(status)) { 2749 hdd_err("Failed to update wiphy band info"); 2750 goto pdev_close; 2751 } 2752 2753 status = ucfg_reg_set_band(hdd_ctx->pdev, band_capability); 2754 if (QDF_IS_STATUS_ERROR(status)) 2755 /* 2756 * Continue, Do not close the pdev from here as if host fails 2757 * to update band information if cc_list event is not received 2758 * by this time, then also driver load should happen. 2759 */ 2760 hdd_err("Failed to update regulatory band info"); 2761 2762 if (!cds_is_driver_recovering() || cds_is_driver_in_bad_state()) { 2763 hdd_ctx->reg.reg_domain = cfg->reg_domain; 2764 hdd_ctx->reg.eeprom_rd_ext = cfg->eeprom_rd_ext; 2765 } 2766 2767 /* This can be extended to other configurations like ht, vht cap... */ 2768 status = wlan_hdd_validate_mac_address(&cfg->hw_macaddr); 2769 if (QDF_IS_STATUS_SUCCESS(status)) 2770 qdf_mem_copy(&hdd_ctx->hw_macaddr, &cfg->hw_macaddr, 2771 QDF_MAC_ADDR_SIZE); 2772 2773 hdd_ctx->target_fw_version = cfg->target_fw_version; 2774 hdd_ctx->target_fw_vers_ext = cfg->target_fw_vers_ext; 2775 hdd_extract_fw_version_info(hdd_ctx); 2776 2777 hdd_ctx->hw_bd_id = cfg->hw_bd_id; 2778 qdf_mem_copy(&hdd_ctx->hw_bd_info, &cfg->hw_bd_info, 2779 sizeof(cfg->hw_bd_info)); 2780 2781 if (cfg->max_intf_count > WLAN_MAX_VDEVS) { 2782 hdd_err("fw max vdevs (%u) > host max vdevs (%u); using %u", 2783 cfg->max_intf_count, WLAN_MAX_VDEVS, WLAN_MAX_VDEVS); 2784 hdd_ctx->max_intf_count = WLAN_MAX_VDEVS; 2785 } else { 2786 hdd_ctx->max_intf_count = cfg->max_intf_count; 2787 } 2788 2789 hdd_sar_target_config(hdd_ctx, cfg); 2790 hdd_lpass_target_config(hdd_ctx, cfg); 2791 2792 hdd_ctx->ap_arpns_support = cfg->ap_arpns_support; 2793 2794 hdd_update_tgt_services(hdd_ctx, &cfg->services); 2795 2796 hdd_update_tgt_ht_cap(hdd_ctx, &cfg->ht_cap); 2797 2798 sme_update_bfer_caps_as_per_nss_chains(hdd_ctx->mac_handle, cfg); 2799 2800 hdd_update_tgt_vht_cap(hdd_ctx, &cfg->vht_cap); 2801 if (cfg->services.en_11ax && 2802 (hdd_ctx->config->dot11Mode == eHDD_DOT11_MODE_AUTO || 2803 hdd_ctx->config->dot11Mode == eHDD_DOT11_MODE_11ax || 2804 hdd_ctx->config->dot11Mode == eHDD_DOT11_MODE_11ax_ONLY)) { 2805 hdd_debug("11AX: 11ax is enabled - update HDD config"); 2806 hdd_update_tgt_he_cap(hdd_ctx, cfg); 2807 hdd_update_wiphy_he_cap(hdd_ctx); 2808 } 2809 hdd_update_tgt_twt_cap(hdd_ctx, cfg); 2810 hdd_update_tgt_eht_cap(hdd_ctx, cfg); 2811 hdd_update_wiphy_eht_cap(hdd_ctx); 2812 ucfg_mlme_update_tgt_mlo_cap(hdd_ctx->psoc); 2813 2814 for (band = NSS_CHAINS_BAND_2GHZ; band < NSS_CHAINS_BAND_MAX; band++) { 2815 sme_modify_nss_chains_tgt_cfg(hdd_ctx->mac_handle, 2816 QDF_STA_MODE, band); 2817 sme_modify_nss_chains_tgt_cfg(hdd_ctx->mac_handle, 2818 QDF_SAP_MODE, band); 2819 sme_modify_nss_chains_tgt_cfg(hdd_ctx->mac_handle, 2820 QDF_TDLS_MODE, band); 2821 sme_modify_nss_chains_tgt_cfg(hdd_ctx->mac_handle, 2822 QDF_P2P_DEVICE_MODE, 2823 band); 2824 sme_modify_nss_chains_tgt_cfg(hdd_ctx->mac_handle, 2825 QDF_OCB_MODE, band); 2826 sme_modify_nss_chains_tgt_cfg(hdd_ctx->mac_handle, 2827 QDF_TDLS_MODE, band); 2828 } 2829 2830 hdd_update_vdev_nss(hdd_ctx); 2831 2832 status = 2833 ucfg_mlme_get_enable_dynamic_nss_chains_cfg(hdd_ctx->psoc, 2834 &enable_dynamic_cfg); 2835 if (QDF_IS_STATUS_ERROR(status)) { 2836 hdd_err("unable to get enable dynamic config"); 2837 hdd_ctx->dynamic_nss_chains_support = false; 2838 } else { 2839 hdd_ctx->dynamic_nss_chains_support = 2840 cfg->dynamic_nss_chains_support & 2841 enable_dynamic_cfg; 2842 hdd_debug("Dynamic nss chain support FW %d driver %d", 2843 cfg->dynamic_nss_chains_support, enable_dynamic_cfg); 2844 } 2845 2846 status = ucfg_mlme_update_dynamic_nss_chains_support 2847 (hdd_ctx->psoc, hdd_ctx->dynamic_nss_chains_support); 2848 if (QDF_IS_STATUS_ERROR(status)) 2849 hdd_err("unable to set dynamic_nss_chains_support"); 2850 2851 ucfg_mlme_get_fine_time_meas_cap(hdd_ctx->psoc, &fine_time_meas_cap); 2852 fine_time_meas_cap &= cfg->fine_time_measurement_cap; 2853 status = ucfg_mlme_set_fine_time_meas_cap(hdd_ctx->psoc, 2854 fine_time_meas_cap); 2855 if (QDF_IS_STATUS_ERROR(status)) { 2856 hdd_err("failed to set fine_time_meas_cap, 0x%x, ox%x", 2857 fine_time_meas_cap, cfg->fine_time_measurement_cap); 2858 ucfg_mlme_get_fine_time_meas_cap(hdd_ctx->psoc, 2859 &fine_time_meas_cap); 2860 } 2861 2862 hdd_ctx->fine_time_meas_cap_target = cfg->fine_time_measurement_cap; 2863 hdd_debug("fine_time_meas_cap: 0x%x", fine_time_meas_cap); 2864 2865 status = ucfg_mlme_get_vht_enable2x2(hdd_ctx->psoc, &bval); 2866 if (!QDF_IS_STATUS_SUCCESS(status)) 2867 hdd_err("unable to get vht_enable2x2"); 2868 2869 antenna_mode = (bval == 0x01) ? 2870 HDD_ANTENNA_MODE_2X2 : HDD_ANTENNA_MODE_1X1; 2871 hdd_update_smps_antenna_mode(hdd_ctx, antenna_mode); 2872 hdd_debug("Init current antenna mode: %d", 2873 hdd_ctx->current_antenna_mode); 2874 2875 hdd_ctx->rcpi_enabled = cfg->rcpi_enabled; 2876 2877 status = ucfg_mlme_cfg_get_vht_tx_bfee_ant_supp(hdd_ctx->psoc, 2878 &value); 2879 if (QDF_IS_STATUS_ERROR(status)) { 2880 status = false; 2881 hdd_err("set tx_bfee_ant_supp failed"); 2882 } 2883 2884 status = ucfg_mlme_set_restricted_80p80_bw_supp(hdd_ctx->psoc, 2885 cfg->restricted_80p80_bw_supp); 2886 if (QDF_IS_STATUS_ERROR(status)) 2887 hdd_err("Failed to set MLME restircted 80p80 BW support"); 2888 2889 if ((value > MLME_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED_FW_DEF) && 2890 !cfg->tx_bfee_8ss_enabled) { 2891 status = ucfg_mlme_cfg_set_vht_tx_bfee_ant_supp(hdd_ctx->psoc, 2892 MLME_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED_FW_DEF); 2893 if (QDF_IS_STATUS_ERROR(status)) { 2894 status = false; 2895 hdd_err("set tx_bfee_ant_supp failed"); 2896 } 2897 } 2898 2899 mac_handle = hdd_ctx->mac_handle; 2900 2901 hdd_debug("txBFCsnValue %d", value); 2902 2903 /* 2904 * Update txBFCsnValue and NumSoundingDim values to vhtcap in wiphy 2905 */ 2906 hdd_update_wiphy_vhtcap(hdd_ctx); 2907 2908 hdd_update_vhtcap_2g(hdd_ctx); 2909 2910 hdd_ctx->wmi_max_len = cfg->wmi_max_len; 2911 2912 wlan_config_sched_scan_plans_to_wiphy(hdd_ctx->wiphy, hdd_ctx->psoc); 2913 /* 2914 * This needs to be done after HDD pdev is created and stored since 2915 * it will access the HDD pdev object lock. 2916 */ 2917 hdd_runtime_suspend_context_init(hdd_ctx); 2918 2919 /* Configure NAN datapath features */ 2920 hdd_nan_datapath_target_config(hdd_ctx, cfg); 2921 ucfg_nan_set_tgt_caps(hdd_ctx->psoc, &cfg->nan_caps); 2922 hdd_ctx->dfs_cac_offload = cfg->dfs_cac_offload; 2923 hdd_ctx->lte_coex_ant_share = cfg->services.lte_coex_ant_share; 2924 hdd_ctx->obss_scan_offload = cfg->services.obss_scan_offload; 2925 ucfg_scan_set_obss_scan_offload(hdd_ctx->psoc, 2926 hdd_ctx->obss_scan_offload); 2927 status = ucfg_mlme_set_obss_detection_offload_enabled( 2928 hdd_ctx->psoc, cfg->obss_detection_offloaded); 2929 if (QDF_IS_STATUS_ERROR(status)) 2930 hdd_err("Couldn't pass WNI_CFG_OBSS_DETECTION_OFFLOAD to CFG"); 2931 2932 status = ucfg_mlme_set_obss_color_collision_offload_enabled( 2933 hdd_ctx->psoc, cfg->obss_color_collision_offloaded); 2934 if (QDF_IS_STATUS_ERROR(status)) 2935 hdd_err("Failed to set WNI_CFG_OBSS_COLOR_COLLISION_OFFLOAD"); 2936 2937 ucfg_mlme_set_bss_color_collision_det_support( 2938 hdd_ctx->psoc, 2939 cfg->obss_color_collision_offloaded); 2940 if (!cfg->obss_color_collision_offloaded) { 2941 status = ucfg_mlme_set_bss_color_collision_det_sta( 2942 hdd_ctx->psoc, 2943 cfg->obss_color_collision_offloaded); 2944 if (QDF_IS_STATUS_ERROR(status)) 2945 hdd_err("Failed to set CFG_BSS_CLR_COLLISION_DET_STA"); 2946 } 2947 2948 hdd_update_score_config(hdd_ctx); 2949 hdd_update_multi_client_thermal_support(hdd_ctx); 2950 2951 ucfg_psoc_mlme_set_11be_capab(hdd_ctx->psoc, cfg->services.en_11be); 2952 return 0; 2953 2954 dispatcher_close: 2955 dispatcher_pdev_close(hdd_ctx->pdev); 2956 pdev_close: 2957 hdd_component_pdev_close(hdd_ctx->pdev); 2958 exit: 2959 hdd_objmgr_release_and_destroy_pdev(hdd_ctx); 2960 2961 return ret; 2962 } 2963 2964 bool hdd_dfs_indicate_radar(struct hdd_context *hdd_ctx) 2965 { 2966 struct hdd_adapter *adapter, *next_adapter = NULL; 2967 struct hdd_ap_ctx *ap_ctx; 2968 uint32_t ap_chan; 2969 bool dfs_disable_channel_switch = false; 2970 struct wlan_hdd_link_info *link_info; 2971 2972 if (!hdd_ctx) { 2973 hdd_info("Couldn't get hdd_ctx"); 2974 return true; 2975 } 2976 2977 ucfg_mlme_get_dfs_disable_channel_switch(hdd_ctx->psoc, 2978 &dfs_disable_channel_switch); 2979 if (dfs_disable_channel_switch) { 2980 hdd_info("skip tx block hdd_ctx=%pK, disableDFSChSwitch=%d", 2981 hdd_ctx, dfs_disable_channel_switch); 2982 return true; 2983 } 2984 2985 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 2986 NET_DEV_HOLD_DFS_INDICATE_RADAR) { 2987 2988 if (adapter->device_mode != QDF_SAP_MODE && 2989 adapter->device_mode != QDF_P2P_GO_MODE) 2990 goto next_adapter; 2991 2992 hdd_adapter_for_each_active_link_info(adapter, link_info) { 2993 ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(link_info); 2994 ap_chan = ap_ctx->operating_chan_freq; 2995 if (!wlan_reg_is_passive_or_disable_for_pwrmode(hdd_ctx->pdev, 2996 ap_chan, REG_CURRENT_PWR_MODE)) 2997 continue; 2998 2999 ap_ctx->dfs_cac_block_tx = true; 3000 hdd_info("tx blocked for vdev: %d", link_info->vdev_id); 3001 if (link_info->vdev_id != WLAN_UMAC_VDEV_ID_MAX) 3002 cdp_fc_vdev_flush( 3003 cds_get_context(QDF_MODULE_ID_SOC), 3004 link_info->vdev_id); 3005 } 3006 next_adapter: 3007 hdd_adapter_dev_put_debug(adapter, 3008 NET_DEV_HOLD_DFS_INDICATE_RADAR); 3009 } 3010 3011 return true; 3012 } 3013 3014 bool hdd_is_valid_mac_address(const uint8_t *mac_addr) 3015 { 3016 int xdigit = 0; 3017 int separator = 0; 3018 3019 while (*mac_addr) { 3020 if (isxdigit(*mac_addr)) { 3021 xdigit++; 3022 } else if (':' == *mac_addr) { 3023 if (0 == xdigit || ((xdigit / 2) - 1) != separator) 3024 break; 3025 3026 ++separator; 3027 } else { 3028 /* Invalid MAC found */ 3029 return false; 3030 } 3031 ++mac_addr; 3032 } 3033 return xdigit == 12 && (separator == 5 || separator == 0); 3034 } 3035 3036 /** 3037 * hdd_mon_mode_ether_setup() - Update monitor mode struct net_device. 3038 * @dev: Handle to struct net_device to be updated. 3039 * 3040 * Return: None 3041 */ 3042 static void hdd_mon_mode_ether_setup(struct net_device *dev) 3043 { 3044 dev->header_ops = NULL; 3045 dev->type = ARPHRD_IEEE80211_RADIOTAP; 3046 dev->hard_header_len = ETH_HLEN; 3047 dev->mtu = ETH_DATA_LEN; 3048 dev->addr_len = ETH_ALEN; 3049 dev->tx_queue_len = 1000; /* Ethernet wants good queues */ 3050 dev->flags = IFF_BROADCAST|IFF_MULTICAST; 3051 dev->priv_flags |= IFF_TX_SKB_SHARING; 3052 3053 memset(dev->broadcast, 0xFF, ETH_ALEN); 3054 } 3055 3056 #ifdef FEATURE_MONITOR_MODE_SUPPORT 3057 /** 3058 * hdd_mon_turn_off_ps_and_wow() - Update monitor mode struct net_device. 3059 * @hdd_ctx: Pointer to HDD context. 3060 * 3061 * Return: None 3062 */ 3063 static void hdd_mon_turn_off_ps_and_wow(struct hdd_context *hdd_ctx) 3064 { 3065 ucfg_pmo_set_power_save_mode(hdd_ctx->psoc, 3066 PMO_PS_ADVANCED_POWER_SAVE_DISABLE); 3067 ucfg_pmo_set_wow_enable(hdd_ctx->psoc, PMO_WOW_DISABLE_BOTH); 3068 } 3069 3070 /** 3071 * __hdd_mon_open() - HDD Open function 3072 * @dev: Pointer to net_device structure 3073 * 3074 * This is called in response to ifconfig up 3075 * 3076 * Return: 0 for success; non-zero for failure 3077 */ 3078 static int __hdd_mon_open(struct net_device *dev) 3079 { 3080 int ret; 3081 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev); 3082 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); 3083 struct bbm_params param = {0}; 3084 3085 hdd_enter_dev(dev); 3086 3087 if (test_bit(DEVICE_IFACE_OPENED, &adapter->event_flags)) { 3088 hdd_debug_rl("Monitor interface is already up"); 3089 return 0; 3090 } 3091 3092 ret = wlan_hdd_validate_context(hdd_ctx); 3093 if (ret) 3094 return ret; 3095 3096 hdd_mon_mode_ether_setup(dev); 3097 3098 if (con_mode == QDF_GLOBAL_MONITOR_MODE || 3099 ucfg_mlme_is_sta_mon_conc_supported(hdd_ctx->psoc) || 3100 ucfg_dp_is_local_pkt_capture_enabled(hdd_ctx->psoc)) { 3101 ret = hdd_trigger_psoc_idle_restart(hdd_ctx); 3102 if (ret) { 3103 hdd_err("Failed to start WLAN modules return"); 3104 return ret; 3105 } 3106 hdd_err("hdd_wlan_start_modules() successful !"); 3107 3108 if ((!test_bit(SME_SESSION_OPENED, 3109 &adapter->deflink->link_flags)) || 3110 (policy_mgr_is_sta_mon_concurrency(hdd_ctx->psoc))) { 3111 ret = hdd_start_adapter(adapter, true); 3112 if (ret) { 3113 hdd_err("Failed to start adapter :%d", 3114 adapter->device_mode); 3115 return ret; 3116 } 3117 hdd_err("hdd_start_adapters() successful !"); 3118 } 3119 hdd_mon_turn_off_ps_and_wow(hdd_ctx); 3120 set_bit(DEVICE_IFACE_OPENED, &adapter->event_flags); 3121 } 3122 3123 if (con_mode != QDF_GLOBAL_MONITOR_MODE && 3124 (ucfg_mlme_is_sta_mon_conc_supported(hdd_ctx->psoc) || 3125 ucfg_dp_is_local_pkt_capture_enabled(hdd_ctx->psoc))) { 3126 hdd_info("Acquire wakelock for STA + monitor mode"); 3127 3128 qdf_wake_lock_acquire(&hdd_ctx->monitor_mode_wakelock, 3129 WIFI_POWER_EVENT_WAKELOCK_MONITOR_MODE); 3130 hdd_lpc_disable_powersave(hdd_ctx); 3131 qdf_runtime_pm_prevent_suspend( 3132 &hdd_ctx->runtime_context.monitor_mode); 3133 } 3134 3135 ret = hdd_set_mon_rx_cb(dev); 3136 3137 if (!ret) 3138 ret = hdd_enable_monitor_mode(dev); 3139 3140 if (!ret) { 3141 param.policy = BBM_DRIVER_MODE_POLICY; 3142 param.policy_info.driver_mode = QDF_GLOBAL_MONITOR_MODE; 3143 ucfg_dp_bbm_apply_independent_policy(hdd_ctx->psoc, ¶m); 3144 ucfg_dp_set_current_throughput_level(hdd_ctx->psoc, 3145 PLD_BUS_WIDTH_VERY_HIGH); 3146 } 3147 3148 return ret; 3149 } 3150 3151 /** 3152 * hdd_mon_open() - Wrapper function for __hdd_mon_open to protect it from SSR 3153 * @net_dev: Pointer to net_device structure 3154 * 3155 * This is called in response to ifconfig up 3156 * 3157 * Return: 0 for success; non-zero for failure 3158 */ 3159 static int hdd_mon_open(struct net_device *net_dev) 3160 { 3161 int errno; 3162 struct osif_vdev_sync *vdev_sync; 3163 3164 errno = osif_vdev_sync_trans_start(net_dev, &vdev_sync); 3165 if (errno) 3166 return errno; 3167 3168 errno = __hdd_mon_open(net_dev); 3169 3170 osif_vdev_sync_trans_stop(vdev_sync); 3171 3172 return errno; 3173 } 3174 #endif 3175 3176 #ifdef WLAN_FEATURE_PKT_CAPTURE 3177 /** 3178 * __hdd_pktcapture_open() - HDD Open function 3179 * @dev: Pointer to net_device structure 3180 * 3181 * This is called in response to ifconfig up 3182 * 3183 * Return: 0 for success; non-zero for failure 3184 */ 3185 static int __hdd_pktcapture_open(struct net_device *dev) 3186 { 3187 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev); 3188 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); 3189 struct hdd_adapter *sta_adapter; 3190 QDF_STATUS status; 3191 struct wlan_objmgr_vdev *vdev; 3192 int ret; 3193 3194 hdd_enter_dev(dev); 3195 3196 ret = wlan_hdd_validate_context(hdd_ctx); 3197 if (ret) 3198 return ret; 3199 3200 sta_adapter = hdd_get_adapter(hdd_ctx, QDF_STA_MODE); 3201 if (!sta_adapter) { 3202 hdd_err("No station interface found"); 3203 return -EINVAL; 3204 } 3205 3206 vdev = hdd_objmgr_get_vdev_by_user(sta_adapter->deflink, WLAN_OSIF_ID); 3207 if (!vdev) 3208 return -EINVAL; 3209 3210 hdd_mon_mode_ether_setup(dev); 3211 3212 status = ucfg_dp_register_pkt_capture_callbacks(vdev); 3213 ret = qdf_status_to_os_return(status); 3214 if (ret) { 3215 hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_ID); 3216 return ret; 3217 } 3218 3219 adapter->deflink->vdev = vdev; 3220 set_bit(DEVICE_IFACE_OPENED, &adapter->event_flags); 3221 sta_adapter->mon_adapter = adapter; 3222 3223 return ret; 3224 } 3225 3226 /** 3227 * hdd_pktcapture_open() - Wrapper function for hdd_pktcapture_open to 3228 * protect it from SSR 3229 * @net_dev: Pointer to net_device structure 3230 * 3231 * This is called in response to ifconfig up 3232 * 3233 * Return: 0 for success; non-zero for failure 3234 */ 3235 static int hdd_pktcapture_open(struct net_device *net_dev) 3236 { 3237 int errno; 3238 struct osif_vdev_sync *vdev_sync; 3239 3240 errno = osif_vdev_sync_trans_start(net_dev, &vdev_sync); 3241 if (errno) 3242 return errno; 3243 3244 errno = __hdd_pktcapture_open(net_dev); 3245 3246 osif_vdev_sync_trans_stop(vdev_sync); 3247 3248 return errno; 3249 } 3250 3251 /** 3252 * hdd_unmap_monitor_interface_vdev() - unmap monitor interface vdev and 3253 * deregister packet capture callbacks 3254 * @sta_adapter: station adapter 3255 * 3256 * Return: void 3257 */ 3258 static void 3259 hdd_unmap_monitor_interface_vdev(struct hdd_adapter *sta_adapter) 3260 { 3261 struct hdd_adapter *mon_adapter = sta_adapter->mon_adapter; 3262 3263 if (mon_adapter && hdd_is_interface_up(mon_adapter)) { 3264 ucfg_pkt_capture_deregister_callbacks( 3265 mon_adapter->deflink->vdev); 3266 hdd_objmgr_put_vdev_by_user(mon_adapter->deflink->vdev, 3267 WLAN_OSIF_ID); 3268 mon_adapter->deflink->vdev = NULL; 3269 hdd_reset_monitor_interface(sta_adapter); 3270 } 3271 } 3272 3273 /** 3274 * hdd_map_monitor_interface_vdev() - Map monitor interface vdev and 3275 * register packet capture callbacks 3276 * @sta_adapter: Station adapter 3277 * 3278 * Return: None 3279 */ 3280 static void hdd_map_monitor_interface_vdev(struct hdd_adapter *sta_adapter) 3281 { 3282 struct hdd_adapter *mon_adapter; 3283 QDF_STATUS status; 3284 struct wlan_objmgr_vdev *vdev; 3285 int ret; 3286 3287 mon_adapter = hdd_get_adapter(sta_adapter->hdd_ctx, QDF_MONITOR_MODE); 3288 if (!mon_adapter) { 3289 hdd_debug("No monitor interface found"); 3290 return; 3291 } 3292 3293 if (!mon_adapter || !hdd_is_interface_up(mon_adapter)) { 3294 hdd_debug("Monitor interface is not up\n"); 3295 return; 3296 } 3297 3298 if (!wlan_hdd_is_session_type_monitor(mon_adapter->device_mode)) 3299 return; 3300 3301 vdev = hdd_objmgr_get_vdev_by_user(sta_adapter->deflink, WLAN_OSIF_ID); 3302 if (!vdev) 3303 return; 3304 3305 status = ucfg_dp_register_pkt_capture_callbacks(vdev); 3306 ret = qdf_status_to_os_return(status); 3307 if (ret) { 3308 hdd_err("Failed registering packet capture callbacks"); 3309 hdd_objmgr_put_vdev_by_user(vdev, 3310 WLAN_OSIF_ID); 3311 return; 3312 } 3313 3314 mon_adapter->deflink->vdev = vdev; 3315 sta_adapter->mon_adapter = mon_adapter; 3316 } 3317 3318 void hdd_reset_monitor_interface(struct hdd_adapter *sta_adapter) 3319 { 3320 sta_adapter->mon_adapter = NULL; 3321 } 3322 3323 struct hdd_adapter * 3324 hdd_is_pkt_capture_mon_enable(struct hdd_adapter *sta_adapter) 3325 { 3326 return sta_adapter->mon_adapter; 3327 } 3328 #else 3329 static inline void 3330 hdd_unmap_monitor_interface_vdev(struct hdd_adapter *sta_adapter) 3331 { 3332 } 3333 3334 static inline void 3335 hdd_map_monitor_interface_vdev(struct hdd_adapter *sta_adapter) 3336 { 3337 } 3338 #endif 3339 3340 static QDF_STATUS 3341 wlan_hdd_update_dbs_scan_and_fw_mode_config(void) 3342 { 3343 struct policy_mgr_dual_mac_config cfg = {0}; 3344 QDF_STATUS status; 3345 uint32_t chnl_sel_logic_conc = 0; 3346 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 3347 uint8_t dual_mac_feature = DISABLE_DBS_CXN_AND_SCAN; 3348 3349 if (!hdd_ctx) 3350 return QDF_STATUS_E_FAILURE; 3351 3352 /* 3353 * ROME platform doesn't support any DBS related commands in FW, 3354 * so if driver sends wmi command with dual_mac_config with all set to 3355 * 0 then FW wouldn't respond back and driver would timeout on waiting 3356 * for response. Check if FW supports DBS to eliminate ROME vs 3357 * NON-ROME platform. 3358 */ 3359 if (!policy_mgr_find_if_fw_supports_dbs(hdd_ctx->psoc)) 3360 return QDF_STATUS_SUCCESS; 3361 3362 if (hdd_ctx->is_dual_mac_cfg_updated) { 3363 hdd_debug("dual mac config has already been updated, skip"); 3364 return QDF_STATUS_SUCCESS; 3365 } 3366 3367 cfg.scan_config = 0; 3368 cfg.fw_mode_config = 0; 3369 cfg.set_dual_mac_cb = policy_mgr_soc_set_dual_mac_cfg_cb; 3370 if (policy_mgr_is_hw_dbs_capable(hdd_ctx->psoc)) { 3371 status = 3372 ucfg_policy_mgr_get_chnl_select_plcy(hdd_ctx->psoc, 3373 &chnl_sel_logic_conc); 3374 if (status != QDF_STATUS_SUCCESS) { 3375 hdd_err("can't get chnl sel policy, use def"); 3376 return status; 3377 } 3378 } 3379 status = 3380 ucfg_policy_mgr_get_dual_mac_feature(hdd_ctx->psoc, 3381 &dual_mac_feature); 3382 if (status != QDF_STATUS_SUCCESS) { 3383 hdd_err("ucfg_policy_mgr_get_dual_mac_feature failed, use def"); 3384 return status; 3385 } 3386 3387 if (dual_mac_feature != DISABLE_DBS_CXN_AND_SCAN) { 3388 status = policy_mgr_get_updated_scan_and_fw_mode_config( 3389 hdd_ctx->psoc, &cfg.scan_config, 3390 &cfg.fw_mode_config, 3391 dual_mac_feature, 3392 chnl_sel_logic_conc); 3393 3394 if (status != QDF_STATUS_SUCCESS) { 3395 hdd_err("wma_get_updated_scan_and_fw_mode_config failed %d", 3396 status); 3397 return status; 3398 } 3399 } 3400 3401 hdd_debug("send scan_cfg: 0x%x fw_mode_cfg: 0x%x to fw", 3402 cfg.scan_config, cfg.fw_mode_config); 3403 3404 status = sme_soc_set_dual_mac_config(cfg); 3405 if (QDF_IS_STATUS_ERROR(status)) { 3406 hdd_err("sme_soc_set_dual_mac_config failed %d", status); 3407 return status; 3408 } 3409 hdd_ctx->is_dual_mac_cfg_updated = true; 3410 3411 return QDF_STATUS_SUCCESS; 3412 } 3413 3414 /** 3415 * hdd_max_sta_interface_up_count_reached() - check sta/p2p_cli vdev count 3416 * @adapter: HDD adapter 3417 * 3418 * Return: true if vdev limit reached 3419 */ 3420 static bool hdd_max_sta_interface_up_count_reached(struct hdd_adapter *adapter) 3421 { 3422 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); 3423 struct hdd_adapter *temp_adapter = NULL, *next_adapter = NULL; 3424 uint8_t intf_count = 0; 3425 wlan_net_dev_ref_dbgid dbgid = 3426 NET_DEV_HOLD_MAX_STA_INTERFACE_UP_COUNT_REACHED; 3427 3428 if (0 == CFG_TGT_DEFAULT_MAX_STA_VDEVS) 3429 return false; 3430 3431 /* 3432 * Check for max no of supported STA/P2PCLI VDEVs before 3433 * creating another one. 3434 */ 3435 hdd_for_each_adapter_dev_held_safe(hdd_ctx, temp_adapter, 3436 next_adapter, dbgid) { 3437 if ((temp_adapter != adapter) && 3438 (temp_adapter->dev->flags & IFF_UP) && 3439 ((temp_adapter->device_mode == QDF_STA_MODE) || 3440 (temp_adapter->device_mode == QDF_P2P_CLIENT_MODE))) 3441 intf_count++; 3442 3443 hdd_adapter_dev_put_debug(temp_adapter, dbgid); 3444 } 3445 3446 if (intf_count >= CFG_TGT_DEFAULT_MAX_STA_VDEVS) { 3447 hdd_err("Max limit reached sta vdev-current %d max %d", 3448 intf_count, CFG_TGT_DEFAULT_MAX_STA_VDEVS); 3449 return true; 3450 } 3451 return false; 3452 } 3453 3454 #if (defined(WLAN_FEATURE_11BE_MLO) && defined(CFG80211_11BE_BASIC)) && \ 3455 (defined(CFG80211_IFTYPE_MLO_LINK_SUPPORT) || \ 3456 defined(CFG80211_SINGLE_NETDEV_MULTI_LINK_SUPPORT)) && \ 3457 !defined(WLAN_HDD_MULTI_VDEV_SINGLE_NDEV) 3458 static int hdd_start_link_adapter(struct hdd_adapter *sta_adapter) 3459 { 3460 int i, ret = 0; 3461 struct hdd_mlo_adapter_info *mlo_adapter_info; 3462 struct hdd_adapter *link_adapter; 3463 3464 hdd_enter_dev(sta_adapter->dev); 3465 mlo_adapter_info = &sta_adapter->mlo_adapter_info; 3466 3467 for (i = 0; i < WLAN_MAX_MLD; i++) { 3468 link_adapter = mlo_adapter_info->link_adapter[i]; 3469 if (!link_adapter) 3470 continue; 3471 if (link_adapter->mlo_adapter_info.associate_with_ml_adapter) { 3472 /* TODO have proper references here */ 3473 qdf_spin_lock_bh(&link_adapter->deflink->vdev_lock); 3474 link_adapter->deflink->vdev = 3475 sta_adapter->deflink->vdev; 3476 link_adapter->deflink->vdev_id = 3477 sta_adapter->deflink->vdev_id; 3478 qdf_spin_unlock_bh(&link_adapter->deflink->vdev_lock); 3479 3480 sta_adapter->link_info[i].vdev_id = 3481 sta_adapter->deflink->vdev_id; 3482 continue; 3483 } 3484 ret = hdd_start_station_adapter(link_adapter); 3485 if (!ret) { 3486 sta_adapter->link_info[i].vdev_id = 3487 link_adapter->deflink->vdev_id; 3488 } 3489 } 3490 3491 hdd_adapter_update_mlo_mgr_mac_addr(sta_adapter); 3492 3493 hdd_exit(); 3494 return ret; 3495 } 3496 3497 static int hdd_stop_link_adapter(struct hdd_context *hdd_ctx, 3498 struct hdd_adapter *sta_adapter) 3499 { 3500 int i, ret = 0; 3501 struct hdd_mlo_adapter_info *mlo_adapter_info; 3502 struct hdd_adapter *link_adapter; 3503 3504 hdd_enter_dev(sta_adapter->dev); 3505 hdd_debug("Stop adapter for link mode : %s(%d)", 3506 qdf_opmode_str(sta_adapter->device_mode), 3507 sta_adapter->deflink->vdev_id); 3508 3509 mlo_adapter_info = &sta_adapter->mlo_adapter_info; 3510 for (i = 0; i < WLAN_MAX_MLD; i++) { 3511 link_adapter = mlo_adapter_info->link_adapter[i]; 3512 if (!link_adapter) 3513 continue; 3514 3515 if (link_adapter->mlo_adapter_info.associate_with_ml_adapter) { 3516 /* TODO have proper references here */ 3517 qdf_spin_lock_bh(&link_adapter->deflink->vdev_lock); 3518 link_adapter->deflink->vdev = NULL; 3519 link_adapter->deflink->vdev_id = 0xff; 3520 qdf_spin_unlock_bh(&link_adapter->deflink->vdev_lock); 3521 continue; 3522 } 3523 ret = hdd_stop_adapter_ext(hdd_ctx, link_adapter); 3524 } 3525 3526 hdd_exit(); 3527 return ret; 3528 } 3529 #else 3530 static int hdd_start_link_adapter(struct hdd_adapter *link_adapter) 3531 { 3532 return 0; 3533 } 3534 3535 static int hdd_stop_link_adapter(struct hdd_context *hdd_ctx, 3536 struct hdd_adapter *link_adapter) 3537 { 3538 return 0; 3539 } 3540 #endif 3541 3542 /** 3543 * hdd_start_adapter() - Wrapper function for device specific adapter 3544 * @adapter: pointer to HDD adapter 3545 * @rtnl_held: true if rtnl lock is taken, otherwise false 3546 * 3547 * This function is called to start the device specific adapter for 3548 * the mode passed in the adapter's device_mode. 3549 * 3550 * Return: 0 for success; non-zero for failure 3551 */ 3552 int hdd_start_adapter(struct hdd_adapter *adapter, bool rtnl_held) 3553 { 3554 3555 int ret; 3556 enum QDF_OPMODE device_mode = adapter->device_mode; 3557 3558 hdd_enter_dev(adapter->dev); 3559 3560 switch (device_mode) { 3561 case QDF_STA_MODE: 3562 case QDF_P2P_CLIENT_MODE: 3563 if (hdd_max_sta_interface_up_count_reached(adapter)) 3564 goto err_start_adapter; 3565 3566 fallthrough; 3567 case QDF_P2P_DEVICE_MODE: 3568 case QDF_OCB_MODE: 3569 case QDF_MONITOR_MODE: 3570 case QDF_NAN_DISC_MODE: 3571 ret = hdd_start_station_adapter(adapter); 3572 if (ret) 3573 goto err_start_adapter; 3574 3575 if (device_mode == QDF_STA_MODE) { 3576 ret = hdd_start_link_adapter(adapter); 3577 if (ret) 3578 hdd_err("Failed to start link adapter:%d", ret); 3579 } 3580 break; 3581 case QDF_P2P_GO_MODE: 3582 case QDF_SAP_MODE: 3583 ret = hdd_start_ap_adapter(adapter, rtnl_held); 3584 if (ret) 3585 goto err_start_adapter; 3586 break; 3587 case QDF_FTM_MODE: 3588 /* vdevs are dynamically managed by firmware in FTM */ 3589 hdd_register_wext(adapter->dev); 3590 goto exit_with_success; 3591 default: 3592 hdd_err("Invalid session type %d", device_mode); 3593 QDF_ASSERT(0); 3594 goto err_start_adapter; 3595 } 3596 3597 if (hdd_set_fw_params(adapter)) 3598 hdd_err("Failed to set the FW params for the adapter!"); 3599 3600 if (adapter->deflink->vdev_id != WLAN_UMAC_VDEV_ID_MAX) { 3601 ret = wlan_hdd_cfg80211_register_frames(adapter); 3602 if (ret < 0) { 3603 hdd_err("Failed to register frames - ret %d", ret); 3604 goto err_start_adapter; 3605 } 3606 } 3607 3608 wlan_hdd_update_dbs_scan_and_fw_mode_config(); 3609 3610 exit_with_success: 3611 hdd_create_adapter_sysfs_files(adapter); 3612 3613 hdd_exit(); 3614 3615 return 0; 3616 3617 err_start_adapter: 3618 return -EINVAL; 3619 } 3620 3621 void hdd_update_hw_sw_info(struct hdd_context *hdd_ctx) 3622 { 3623 void *hif_sc; 3624 size_t target_hw_name_len; 3625 const char *target_hw_name; 3626 uint8_t *buf; 3627 uint32_t buf_len; 3628 3629 hif_sc = cds_get_context(QDF_MODULE_ID_HIF); 3630 if (!hif_sc) 3631 return; 3632 3633 hif_get_hw_info(hif_sc, &hdd_ctx->target_hw_version, 3634 &hdd_ctx->target_hw_revision, 3635 &target_hw_name); 3636 3637 qdf_mem_zero(hdd_ctx->target_hw_name, MAX_TGT_HW_NAME_LEN); 3638 3639 target_hw_name_len = strlen(target_hw_name) + 1; 3640 3641 if (target_hw_name_len <= MAX_TGT_HW_NAME_LEN) { 3642 qdf_mem_copy(hdd_ctx->target_hw_name, target_hw_name, 3643 target_hw_name_len); 3644 } else { 3645 hdd_err("target_hw_name_len is greater than MAX_TGT_HW_NAME_LEN"); 3646 return; 3647 } 3648 3649 hdd_debug("target_hw_name = %s", hdd_ctx->target_hw_name); 3650 3651 buf = qdf_mem_malloc(WE_MAX_STR_LEN); 3652 if (buf) { 3653 buf_len = hdd_wlan_get_version(hdd_ctx, WE_MAX_STR_LEN, buf); 3654 hdd_nofl_debug("%s", buf); 3655 qdf_mem_free(buf); 3656 } 3657 } 3658 3659 /** 3660 * hdd_update_cds_ac_specs_params() - update cds ac_specs params 3661 * @hdd_ctx: Pointer to hdd context 3662 * 3663 * Return: none 3664 */ 3665 static void 3666 hdd_update_cds_ac_specs_params(struct hdd_context *hdd_ctx) 3667 { 3668 uint8_t tx_sched_wrr_param[TX_SCHED_WRR_PARAMS_NUM] = {0}; 3669 qdf_size_t out_size = 0; 3670 int i; 3671 struct cds_context *cds_ctx; 3672 3673 if (!hdd_ctx) 3674 return; 3675 3676 if (!hdd_ctx->config) { 3677 /* Do nothing if hdd_ctx is invalid */ 3678 hdd_err("Warning: hdd_ctx->cfg_ini is NULL"); 3679 return; 3680 } 3681 3682 cds_ctx = cds_get_context(QDF_MODULE_ID_QDF); 3683 if (!cds_ctx) 3684 return; 3685 3686 for (i = 0; i < QCA_WLAN_AC_ALL; i++) { 3687 switch (i) { 3688 case QCA_WLAN_AC_BE: 3689 qdf_uint8_array_parse( 3690 cfg_get(hdd_ctx->psoc, 3691 CFG_DP_ENABLE_TX_SCHED_WRR_BE), 3692 tx_sched_wrr_param, 3693 sizeof(tx_sched_wrr_param), 3694 &out_size); 3695 break; 3696 case QCA_WLAN_AC_BK: 3697 qdf_uint8_array_parse( 3698 cfg_get(hdd_ctx->psoc, 3699 CFG_DP_ENABLE_TX_SCHED_WRR_BK), 3700 tx_sched_wrr_param, 3701 sizeof(tx_sched_wrr_param), 3702 &out_size); 3703 break; 3704 case QCA_WLAN_AC_VI: 3705 qdf_uint8_array_parse( 3706 cfg_get(hdd_ctx->psoc, 3707 CFG_DP_ENABLE_TX_SCHED_WRR_VI), 3708 tx_sched_wrr_param, 3709 sizeof(tx_sched_wrr_param), 3710 &out_size); 3711 break; 3712 case QCA_WLAN_AC_VO: 3713 qdf_uint8_array_parse( 3714 cfg_get(hdd_ctx->psoc, 3715 CFG_DP_ENABLE_TX_SCHED_WRR_VO), 3716 tx_sched_wrr_param, 3717 sizeof(tx_sched_wrr_param), 3718 &out_size); 3719 break; 3720 default: 3721 break; 3722 } 3723 3724 if (out_size == TX_SCHED_WRR_PARAMS_NUM) { 3725 cds_ctx->ac_specs[i].wrr_skip_weight = 3726 tx_sched_wrr_param[0]; 3727 cds_ctx->ac_specs[i].credit_threshold = 3728 tx_sched_wrr_param[1]; 3729 cds_ctx->ac_specs[i].send_limit = 3730 tx_sched_wrr_param[2]; 3731 cds_ctx->ac_specs[i].credit_reserve = 3732 tx_sched_wrr_param[3]; 3733 cds_ctx->ac_specs[i].discard_weight = 3734 tx_sched_wrr_param[4]; 3735 } 3736 3737 out_size = 0; 3738 } 3739 } 3740 3741 uint32_t hdd_wlan_get_version(struct hdd_context *hdd_ctx, 3742 const size_t version_len, uint8_t *version) 3743 { 3744 uint32_t size; 3745 uint8_t reg_major = 0, reg_minor = 0, bdf_major = 0, bdf_minor = 0; 3746 struct target_psoc_info *tgt_hdl; 3747 3748 if (!hdd_ctx) { 3749 hdd_err("Invalid context, HDD context is null"); 3750 return 0; 3751 } 3752 3753 if (!version || version_len == 0) { 3754 hdd_err("Invalid buffer pointr or buffer len\n"); 3755 return 0; 3756 } 3757 tgt_hdl = wlan_psoc_get_tgt_if_handle(hdd_ctx->psoc); 3758 if (tgt_hdl) 3759 target_psoc_get_version_info(tgt_hdl, ®_major, ®_minor, 3760 &bdf_major, &bdf_minor); 3761 3762 size = scnprintf(version, version_len, 3763 "Host SW:%s, FW:%d.%d.%d.%d.%d.%d, HW:%s, Board ver: %x Ref design id: %x, Customer id: %x, Project id: %x, Board Data Rev: %x, REG DB: %u:%u, BDF REG DB: %u:%u", 3764 QWLAN_VERSIONSTR, 3765 hdd_ctx->fw_version_info.major_spid, 3766 hdd_ctx->fw_version_info.minor_spid, 3767 hdd_ctx->fw_version_info.siid, 3768 hdd_ctx->fw_version_info.rel_id, 3769 hdd_ctx->fw_version_info.crmid, 3770 hdd_ctx->fw_version_info.sub_id, 3771 hdd_ctx->target_hw_name, 3772 hdd_ctx->hw_bd_info.bdf_version, 3773 hdd_ctx->hw_bd_info.ref_design_id, 3774 hdd_ctx->hw_bd_info.customer_id, 3775 hdd_ctx->hw_bd_info.project_id, 3776 hdd_ctx->hw_bd_info.board_data_rev, 3777 reg_major, reg_minor, bdf_major, bdf_minor); 3778 3779 return size; 3780 } 3781 3782 int hdd_set_11ax_rate(struct hdd_adapter *adapter, int set_value, 3783 struct sap_config *sap_config) 3784 { 3785 uint8_t preamble = 0, nss = 0, rix = 0; 3786 int ret; 3787 mac_handle_t mac_handle = adapter->hdd_ctx->mac_handle; 3788 3789 if (!sap_config) { 3790 if (!sme_is_feature_supported_by_fw(DOT11AX)) { 3791 hdd_err("Target does not support 11ax"); 3792 return -EIO; 3793 } 3794 } else if (sap_config->SapHw_mode != eCSR_DOT11_MODE_11ax && 3795 sap_config->SapHw_mode != eCSR_DOT11_MODE_11ax_ONLY) { 3796 hdd_err("Invalid hw mode, SAP hw_mode= 0x%x, ch_freq = %d", 3797 sap_config->SapHw_mode, sap_config->chan_freq); 3798 return -EIO; 3799 } 3800 3801 if (set_value != 0xffff) { 3802 rix = RC_2_RATE_IDX_11AX(set_value); 3803 preamble = WMI_RATE_PREAMBLE_HE; 3804 nss = HT_RC_2_STREAMS_11AX(set_value); 3805 3806 set_value = hdd_assemble_rate_code(preamble, nss, rix); 3807 } else { 3808 ret = sme_set_auto_rate_he_ltf(mac_handle, 3809 adapter->deflink->vdev_id, 3810 QCA_WLAN_HE_LTF_AUTO); 3811 } 3812 3813 hdd_info("SET_11AX_RATE val %d rix %d preamble %x nss %d", 3814 set_value, rix, preamble, nss); 3815 3816 ret = wma_cli_set_command(adapter->deflink->vdev_id, 3817 wmi_vdev_param_fixed_rate, 3818 set_value, VDEV_CMD); 3819 3820 return ret; 3821 } 3822 3823 int hdd_assemble_rate_code(uint8_t preamble, uint8_t nss, uint8_t rate) 3824 { 3825 int set_value; 3826 3827 if (sme_is_feature_supported_by_fw(DOT11AX)) 3828 set_value = WMI_ASSEMBLE_RATECODE_V1(rate, nss, preamble); 3829 else 3830 set_value = (preamble << 6) | (nss << 4) | rate; 3831 3832 return set_value; 3833 } 3834 3835 #ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH 3836 static enum policy_mgr_con_mode wlan_hdd_get_mode_for_non_connected_vdev( 3837 struct wlan_objmgr_psoc *psoc, uint8_t vdev_id) 3838 { 3839 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 3840 struct hdd_adapter *adapter; 3841 enum policy_mgr_con_mode mode; 3842 struct wlan_hdd_link_info *link_info; 3843 3844 link_info = hdd_get_link_info_by_vdev(hdd_ctx, vdev_id); 3845 if (!link_info) { 3846 hdd_err("Invalid vdev"); 3847 return PM_MAX_NUM_OF_MODE; 3848 } 3849 3850 adapter = link_info->adapter; 3851 mode = policy_mgr_qdf_opmode_to_pm_con_mode(psoc, 3852 adapter->device_mode, 3853 vdev_id); 3854 return mode; 3855 } 3856 3857 /** 3858 * hdd_is_chan_switch_in_progress() - Check if any adapter has channel switch in 3859 * progress 3860 * 3861 * Return: true, if any adapter has channel switch in 3862 * progress else false 3863 */ 3864 static bool hdd_is_chan_switch_in_progress(void) 3865 { 3866 struct hdd_adapter *adapter = NULL, *next_adapter = NULL; 3867 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 3868 wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_IS_CHAN_SWITCH_IN_PROGRESS; 3869 struct hdd_ap_ctx *ap_ctx; 3870 struct wlan_hdd_link_info *link_info; 3871 3872 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 3873 dbgid) { 3874 if (adapter->device_mode != QDF_SAP_MODE && 3875 adapter->device_mode != QDF_P2P_GO_MODE) 3876 goto next_adapter; 3877 3878 hdd_adapter_for_each_active_link_info(adapter, link_info) { 3879 ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(link_info); 3880 if (qdf_atomic_read(&ap_ctx->ch_switch_in_progress)) { 3881 hdd_debug("channel switch progress for vdev_id %d", 3882 link_info->vdev_id); 3883 hdd_adapter_dev_put_debug(adapter, dbgid); 3884 if (next_adapter) 3885 hdd_adapter_dev_put_debug(next_adapter, 3886 dbgid); 3887 return true; 3888 } 3889 } 3890 next_adapter: 3891 hdd_adapter_dev_put_debug(adapter, dbgid); 3892 } 3893 3894 return false; 3895 } 3896 3897 /** 3898 * hdd_is_cac_in_progress() - Check if any SAP connection is performing 3899 * CAC on DFS channel 3900 * 3901 * Return: true, if any of existing SAP is performing CAC 3902 * or else false 3903 */ 3904 static bool hdd_is_cac_in_progress(void) 3905 { 3906 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 3907 3908 if (!hdd_ctx) 3909 return false; 3910 3911 return (hdd_ctx->dev_dfs_cac_status == DFS_CAC_IN_PROGRESS); 3912 } 3913 3914 static void hdd_register_policy_manager_callback( 3915 struct wlan_objmgr_psoc *psoc) 3916 { 3917 struct policy_mgr_hdd_cbacks hdd_cbacks; 3918 3919 qdf_mem_zero(&hdd_cbacks, sizeof(hdd_cbacks)); 3920 hdd_cbacks.sap_restart_chan_switch_cb = 3921 hdd_sap_restart_chan_switch_cb; 3922 hdd_cbacks.wlan_hdd_get_channel_for_sap_restart = 3923 wlan_hdd_get_channel_for_sap_restart; 3924 hdd_cbacks.get_mode_for_non_connected_vdev = 3925 wlan_hdd_get_mode_for_non_connected_vdev; 3926 hdd_cbacks.hdd_get_device_mode = hdd_get_device_mode; 3927 hdd_cbacks.hdd_is_chan_switch_in_progress = 3928 hdd_is_chan_switch_in_progress; 3929 hdd_cbacks.hdd_is_cac_in_progress = 3930 hdd_is_cac_in_progress; 3931 hdd_cbacks.wlan_hdd_set_sap_csa_reason = 3932 wlan_hdd_set_sap_csa_reason; 3933 hdd_cbacks.hdd_get_ap_6ghz_capable = hdd_get_ap_6ghz_capable; 3934 hdd_cbacks.wlan_hdd_indicate_active_ndp_cnt = 3935 hdd_indicate_active_ndp_cnt; 3936 hdd_cbacks.wlan_get_ap_prefer_conc_ch_params = 3937 wlan_get_ap_prefer_conc_ch_params; 3938 hdd_cbacks.wlan_get_sap_acs_band = 3939 wlan_get_sap_acs_band; 3940 hdd_cbacks.wlan_check_cc_intf_cb = wlan_hdd_check_cc_intf_cb; 3941 3942 if (QDF_STATUS_SUCCESS != 3943 policy_mgr_register_hdd_cb(psoc, &hdd_cbacks)) { 3944 hdd_err("HDD callback registration with policy manager failed"); 3945 } 3946 } 3947 #else 3948 static void hdd_register_policy_manager_callback( 3949 struct wlan_objmgr_psoc *psoc) 3950 { 3951 } 3952 #endif 3953 3954 #ifdef WLAN_SUPPORT_GAP_LL_PS_MODE 3955 static void hdd_register_green_ap_callback(struct wlan_objmgr_pdev *pdev) 3956 { 3957 struct green_ap_hdd_callback hdd_cback; 3958 qdf_mem_zero(&hdd_cback, sizeof(hdd_cback)); 3959 3960 hdd_cback.send_event = wlan_hdd_send_green_ap_ll_ps_event; 3961 3962 if (QDF_STATUS_SUCCESS != 3963 green_ap_register_hdd_callback(pdev, &hdd_cback)) { 3964 hdd_err("HDD callback registration for Green AP failed"); 3965 } 3966 } 3967 #else 3968 static inline void hdd_register_green_ap_callback(struct wlan_objmgr_pdev *pdev) 3969 { 3970 } 3971 #endif 3972 3973 #ifdef WLAN_FEATURE_NAN 3974 #ifdef WLAN_FEATURE_SR 3975 static void hdd_register_sr_concurrency_cb(struct nan_callbacks *cb_obj) 3976 { 3977 cb_obj->nan_sr_concurrency_update = hdd_nan_sr_concurrency_update; 3978 } 3979 #else 3980 static void hdd_register_sr_concurrency_cb(struct nan_callbacks *cb_obj) 3981 {} 3982 #endif 3983 static void hdd_nan_register_callbacks(struct hdd_context *hdd_ctx) 3984 { 3985 struct nan_callbacks cb_obj = {0}; 3986 3987 cb_obj.ndi_open = hdd_ndi_open; 3988 cb_obj.ndi_close = hdd_ndi_close; 3989 cb_obj.ndi_set_mode = hdd_ndi_set_mode; 3990 cb_obj.ndi_start = hdd_ndi_start; 3991 cb_obj.ndi_delete = hdd_ndi_delete; 3992 cb_obj.drv_ndi_create_rsp_handler = hdd_ndi_drv_ndi_create_rsp_handler; 3993 cb_obj.drv_ndi_delete_rsp_handler = hdd_ndi_drv_ndi_delete_rsp_handler; 3994 3995 cb_obj.new_peer_ind = hdd_ndp_new_peer_handler; 3996 cb_obj.peer_departed_ind = hdd_ndp_peer_departed_handler; 3997 3998 cb_obj.nan_concurrency_update = hdd_nan_concurrency_update; 3999 cb_obj.set_mc_list = hdd_update_multicast_list; 4000 4001 hdd_register_sr_concurrency_cb(&cb_obj); 4002 4003 os_if_nan_register_hdd_callbacks(hdd_ctx->psoc, &cb_obj); 4004 } 4005 #else 4006 static inline void hdd_nan_register_callbacks(struct hdd_context *hdd_ctx) 4007 { 4008 } 4009 #endif 4010 4011 #ifdef CONFIG_LEAK_DETECTION 4012 /** 4013 * hdd_check_for_leaks() - Perform runtime memory leak checks 4014 * @hdd_ctx: the global HDD context 4015 * @is_ssr: true if SSR is in progress 4016 * 4017 * This API triggers runtime memory leak detection. This feature enforces the 4018 * policy that any memory allocated at runtime must also be released at runtime. 4019 * 4020 * Allocating memory at runtime and releasing it at unload is effectively a 4021 * memory leak for configurations which never unload (e.g. LONU, statically 4022 * compiled driver). Such memory leaks are NOT false positives, and must be 4023 * fixed. 4024 * 4025 * Return: None 4026 */ 4027 static void hdd_check_for_leaks(struct hdd_context *hdd_ctx, bool is_ssr) 4028 { 4029 /* DO NOT REMOVE these checks; for false positives, read above first */ 4030 4031 wlan_objmgr_psoc_check_for_leaks(hdd_ctx->psoc); 4032 4033 /* many adapter resources are not freed by design during SSR */ 4034 if (is_ssr) 4035 return; 4036 4037 qdf_wake_lock_check_for_leaks(); 4038 qdf_delayed_work_check_for_leaks(); 4039 qdf_mc_timer_check_for_leaks(); 4040 qdf_nbuf_map_check_for_leaks(); 4041 qdf_periodic_work_check_for_leaks(); 4042 qdf_mem_check_for_leaks(); 4043 } 4044 4045 /** 4046 * hdd_debug_domain_set() - Set qdf debug domain 4047 * @domain: debug domain to be set 4048 * 4049 * In the scenario of system reboot, it may have thread accessing debug domain 4050 * for memory allocation/free, other than the one trying to change it. 4051 * If debug domain is changed after a memory allocation but before the free, 4052 * it will hit debug domain mismatch assertion in memory free. 4053 * To avoid such assertion, skip debug domain transition if system reboot is 4054 * in progress. 4055 * 4056 * Return: 0 if the specified debug domain has been set, -EBUSY otherwise 4057 */ 4058 static int hdd_debug_domain_set(enum qdf_debug_domain domain) 4059 { 4060 int ret = 0; 4061 4062 if (cds_sys_reboot_protect()) { 4063 hdd_info("System is rebooting, skip debug domain transition"); 4064 ret = -EBUSY; 4065 } else { 4066 qdf_debug_domain_set(domain); 4067 } 4068 4069 cds_sys_reboot_unprotect(); 4070 4071 return ret; 4072 } 4073 4074 #define hdd_debug_domain_get() qdf_debug_domain_get() 4075 #else 4076 static void hdd_check_for_objmgr_peer_leaks(struct wlan_objmgr_psoc *psoc) 4077 { 4078 uint32_t vdev_id; 4079 struct wlan_objmgr_vdev *vdev; 4080 struct wlan_objmgr_peer *peer; 4081 4082 /* get module id which cause the leak and release ref */ 4083 wlan_objmgr_for_each_psoc_vdev(psoc, vdev_id, vdev) { 4084 wlan_vdev_obj_lock(vdev); 4085 wlan_objmgr_for_each_vdev_peer(vdev, peer) { 4086 qdf_atomic_t *ref_id_dbg; 4087 int ref_id; 4088 int32_t refs; 4089 4090 ref_id_dbg = vdev->vdev_objmgr.ref_id_dbg; 4091 wlan_objmgr_for_each_refs(ref_id_dbg, ref_id, refs) 4092 wlan_objmgr_peer_release_ref(peer, ref_id); 4093 } 4094 wlan_vdev_obj_unlock(vdev); 4095 } 4096 } 4097 4098 static void hdd_check_for_objmgr_leaks(struct hdd_context *hdd_ctx) 4099 { 4100 uint32_t vdev_id, pdev_id; 4101 struct wlan_objmgr_psoc *psoc; 4102 struct wlan_objmgr_vdev *vdev; 4103 struct wlan_objmgr_pdev *pdev; 4104 /* 4105 * leak detection is disabled, force release the references for the wlan 4106 * to recover cleanly. 4107 */ 4108 psoc = hdd_ctx->psoc; 4109 if (!psoc) 4110 return; 4111 4112 4113 hdd_check_for_objmgr_peer_leaks(psoc); 4114 4115 wlan_objmgr_for_each_psoc_vdev(psoc, vdev_id, vdev) { 4116 qdf_atomic_t *ref_id_dbg; 4117 int ref_id; 4118 int32_t refs; 4119 4120 ref_id_dbg = vdev->vdev_objmgr.ref_id_dbg; 4121 wlan_objmgr_for_each_refs(ref_id_dbg, ref_id, refs) { 4122 wlan_objmgr_vdev_release_ref(vdev, ref_id); 4123 } 4124 } 4125 4126 wlan_objmgr_for_each_psoc_pdev(psoc, pdev_id, pdev) { 4127 qdf_atomic_t *ref_id_dbg; 4128 int ref_id; 4129 int32_t refs; 4130 4131 ref_id_dbg = pdev->pdev_objmgr.ref_id_dbg; 4132 wlan_objmgr_for_each_refs(ref_id_dbg, ref_id, refs) 4133 wlan_objmgr_pdev_release_ref(pdev, ref_id); 4134 } 4135 } 4136 4137 static void hdd_check_for_leaks(struct hdd_context *hdd_ctx, bool is_ssr) 4138 { 4139 hdd_check_for_objmgr_leaks(hdd_ctx); 4140 } 4141 4142 #define hdd_debug_domain_set(domain) 0 4143 #define hdd_debug_domain_get() DEFAULT_DEBUG_DOMAIN_INIT 4144 #endif /* CONFIG_LEAK_DETECTION */ 4145 4146 #ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE 4147 /** 4148 * hdd_skip_acs_scan_timer_handler() - skip ACS scan timer timeout handler 4149 * @data: pointer to struct hdd_context 4150 * 4151 * This function will reset acs_scan_status to eSAP_DO_NEW_ACS_SCAN. 4152 * Then new ACS request will do a fresh scan without reusing the cached 4153 * scan information. 4154 * 4155 * Return: void 4156 */ 4157 static void hdd_skip_acs_scan_timer_handler(void *data) 4158 { 4159 struct hdd_context *hdd_ctx = data; 4160 mac_handle_t mac_handle; 4161 4162 hdd_debug("ACS Scan result expired. Reset ACS scan skip"); 4163 hdd_ctx->skip_acs_scan_status = eSAP_DO_NEW_ACS_SCAN; 4164 qdf_spin_lock(&hdd_ctx->acs_skip_lock); 4165 qdf_mem_free(hdd_ctx->last_acs_freq_list); 4166 hdd_ctx->last_acs_freq_list = NULL; 4167 hdd_ctx->num_of_channels = 0; 4168 qdf_spin_unlock(&hdd_ctx->acs_skip_lock); 4169 4170 mac_handle = hdd_ctx->mac_handle; 4171 if (!mac_handle) 4172 return; 4173 } 4174 4175 static void hdd_skip_acs_scan_timer_init(struct hdd_context *hdd_ctx) 4176 { 4177 QDF_STATUS status; 4178 4179 status = qdf_mc_timer_init(&hdd_ctx->skip_acs_scan_timer, 4180 QDF_TIMER_TYPE_SW, 4181 hdd_skip_acs_scan_timer_handler, 4182 hdd_ctx); 4183 if (QDF_IS_STATUS_ERROR(status)) 4184 hdd_err("Failed to init ACS Skip timer"); 4185 qdf_spinlock_create(&hdd_ctx->acs_skip_lock); 4186 } 4187 4188 static void hdd_skip_acs_scan_timer_deinit(struct hdd_context *hdd_ctx) 4189 { 4190 if (QDF_TIMER_STATE_RUNNING == 4191 qdf_mc_timer_get_current_state(&hdd_ctx->skip_acs_scan_timer)) { 4192 qdf_mc_timer_stop(&hdd_ctx->skip_acs_scan_timer); 4193 } 4194 4195 if (!QDF_IS_STATUS_SUCCESS 4196 (qdf_mc_timer_destroy(&hdd_ctx->skip_acs_scan_timer))) { 4197 hdd_err("Cannot deallocate ACS Skip timer"); 4198 } 4199 qdf_spin_lock(&hdd_ctx->acs_skip_lock); 4200 qdf_mem_free(hdd_ctx->last_acs_freq_list); 4201 hdd_ctx->last_acs_freq_list = NULL; 4202 hdd_ctx->num_of_channels = 0; 4203 qdf_spin_unlock(&hdd_ctx->acs_skip_lock); 4204 } 4205 #else 4206 static void hdd_skip_acs_scan_timer_init(struct hdd_context *hdd_ctx) {} 4207 static void hdd_skip_acs_scan_timer_deinit(struct hdd_context *hdd_ctx) {} 4208 #endif 4209 4210 /** 4211 * hdd_update_country_code - Update country code 4212 * @hdd_ctx: HDD context 4213 * 4214 * Update country code based on module parameter country_code 4215 * 4216 * Return: 0 on success and errno on failure 4217 */ 4218 int hdd_update_country_code(struct hdd_context *hdd_ctx) 4219 { 4220 if (!country_code || 4221 !ucfg_reg_is_user_country_set_allowed(hdd_ctx->psoc)) 4222 return 0; 4223 4224 return hdd_reg_set_country(hdd_ctx, country_code); 4225 } 4226 4227 #ifdef WLAN_NS_OFFLOAD 4228 /** 4229 * hdd_wlan_unregister_ip6_notifier() - unregister IPv6 change notifier 4230 * @hdd_ctx: Pointer to hdd context 4231 * 4232 * Unregister for IPv6 address change notifications. 4233 * 4234 * Return: None 4235 */ 4236 static void hdd_wlan_unregister_ip6_notifier(struct hdd_context *hdd_ctx) 4237 { 4238 unregister_inet6addr_notifier(&hdd_ctx->ipv6_notifier); 4239 } 4240 4241 /** 4242 * hdd_wlan_register_ip6_notifier() - register IPv6 change notifier 4243 * @hdd_ctx: Pointer to hdd context 4244 * 4245 * Register for IPv6 address change notifications. 4246 * 4247 * Return: 0 on success and errno on failure. 4248 */ 4249 static int hdd_wlan_register_ip6_notifier(struct hdd_context *hdd_ctx) 4250 { 4251 int ret; 4252 4253 hdd_ctx->ipv6_notifier.notifier_call = wlan_hdd_ipv6_changed; 4254 ret = register_inet6addr_notifier(&hdd_ctx->ipv6_notifier); 4255 if (ret) { 4256 hdd_err("Failed to register IPv6 notifier: %d", ret); 4257 goto out; 4258 } 4259 4260 hdd_debug("Registered IPv6 notifier"); 4261 out: 4262 return ret; 4263 } 4264 #else 4265 /** 4266 * hdd_wlan_unregister_ip6_notifier() - unregister IPv6 change notifier 4267 * @hdd_ctx: Pointer to hdd context 4268 * 4269 * Unregister for IPv6 address change notifications. 4270 * 4271 * Return: None 4272 */ 4273 static void hdd_wlan_unregister_ip6_notifier(struct hdd_context *hdd_ctx) 4274 { 4275 } 4276 4277 /** 4278 * hdd_wlan_register_ip6_notifier() - register IPv6 change notifier 4279 * @hdd_ctx: Pointer to hdd context 4280 * 4281 * Register for IPv6 address change notifications. 4282 * 4283 * Return: None 4284 */ 4285 static int hdd_wlan_register_ip6_notifier(struct hdd_context *hdd_ctx) 4286 { 4287 return 0; 4288 } 4289 #endif 4290 4291 #ifdef FEATURE_RUNTIME_PM 4292 #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 7, 0) 4293 static int hdd_pm_qos_add_notifier(struct hdd_context *hdd_ctx) 4294 { 4295 return dev_pm_qos_add_notifier(hdd_ctx->parent_dev, 4296 &hdd_ctx->pm_qos_notifier, 4297 DEV_PM_QOS_RESUME_LATENCY); 4298 } 4299 4300 static int hdd_pm_qos_remove_notifier(struct hdd_context *hdd_ctx) 4301 { 4302 return dev_pm_qos_remove_notifier(hdd_ctx->parent_dev, 4303 &hdd_ctx->pm_qos_notifier, 4304 DEV_PM_QOS_RESUME_LATENCY); 4305 } 4306 #else 4307 static int hdd_pm_qos_add_notifier(struct hdd_context *hdd_ctx) 4308 { 4309 return pm_qos_add_notifier(PM_QOS_CPU_DMA_LATENCY, 4310 &hdd_ctx->pm_qos_notifier); 4311 } 4312 4313 static int hdd_pm_qos_remove_notifier(struct hdd_context *hdd_ctx) 4314 { 4315 return pm_qos_remove_notifier(PM_QOS_CPU_DMA_LATENCY, 4316 &hdd_ctx->pm_qos_notifier); 4317 } 4318 #endif 4319 4320 /** 4321 * hdd_wlan_register_pm_qos_notifier() - register PM QOS notifier 4322 * @hdd_ctx: Pointer to hdd context 4323 * 4324 * Register for PM QOS change notifications. 4325 * 4326 * Return: None 4327 */ 4328 static int hdd_wlan_register_pm_qos_notifier(struct hdd_context *hdd_ctx) 4329 { 4330 int ret; 4331 4332 qdf_spinlock_create(&hdd_ctx->pm_qos_lock); 4333 4334 /* if gRuntimePM is 1 then feature is enabled without CXPC */ 4335 if (hdd_ctx->config->runtime_pm != hdd_runtime_pm_dynamic) { 4336 hdd_debug("Dynamic Runtime PM disabled"); 4337 return 0; 4338 } 4339 4340 hdd_ctx->pm_qos_notifier.notifier_call = wlan_hdd_pm_qos_notify; 4341 ret = hdd_pm_qos_add_notifier(hdd_ctx); 4342 if (ret) 4343 hdd_err("Failed to register PM_QOS notifier: %d", ret); 4344 else 4345 hdd_debug("PM QOS Notifier registered"); 4346 4347 return ret; 4348 } 4349 4350 /** 4351 * hdd_wlan_unregister_pm_qos_notifier() - unregister PM QOS notifier 4352 * @hdd_ctx: Pointer to hdd context 4353 * 4354 * Unregister for PM QOS change notifications. 4355 * 4356 * Return: None 4357 */ 4358 static void hdd_wlan_unregister_pm_qos_notifier(struct hdd_context *hdd_ctx) 4359 { 4360 int ret; 4361 4362 if (hdd_ctx->config->runtime_pm != hdd_runtime_pm_dynamic) { 4363 hdd_debug("Dynamic Runtime PM disabled"); 4364 qdf_spinlock_destroy(&hdd_ctx->pm_qos_lock); 4365 return; 4366 } 4367 4368 ret = hdd_pm_qos_remove_notifier(hdd_ctx); 4369 if (ret) 4370 hdd_warn("Failed to remove qos notifier, err = %d\n", ret); 4371 4372 qdf_spin_lock_irqsave(&hdd_ctx->pm_qos_lock); 4373 4374 if (hdd_ctx->runtime_pm_prevented) { 4375 hif_rtpm_put(HIF_RTPM_PUT_NOIDLE, HIF_RTPM_ID_PM_QOS_NOTIFY); 4376 hdd_ctx->runtime_pm_prevented = false; 4377 } 4378 4379 qdf_spin_unlock_irqrestore(&hdd_ctx->pm_qos_lock); 4380 4381 qdf_spinlock_destroy(&hdd_ctx->pm_qos_lock); 4382 } 4383 #else 4384 static int hdd_wlan_register_pm_qos_notifier(struct hdd_context *hdd_ctx) 4385 { 4386 return 0; 4387 } 4388 4389 static void hdd_wlan_unregister_pm_qos_notifier(struct hdd_context *hdd_ctx) 4390 { 4391 } 4392 #endif 4393 4394 /** 4395 * hdd_enable_power_management() - API to Enable Power Management 4396 * @hdd_ctx: HDD context 4397 * 4398 * API invokes Bus Interface Layer power management functionality 4399 * 4400 * Return: None 4401 */ 4402 static void hdd_enable_power_management(struct hdd_context *hdd_ctx) 4403 { 4404 void *hif_ctx = cds_get_context(QDF_MODULE_ID_HIF); 4405 4406 if (!hif_ctx) 4407 return; 4408 4409 hif_enable_power_management(hif_ctx, cds_is_packet_log_enabled()); 4410 hdd_wlan_register_pm_qos_notifier(hdd_ctx); 4411 } 4412 4413 /** 4414 * hdd_disable_power_management() - API to disable Power Management 4415 * @hdd_ctx: HDD context 4416 * 4417 * API disable Bus Interface Layer Power management functionality 4418 * 4419 * Return: None 4420 */ 4421 static void hdd_disable_power_management(struct hdd_context *hdd_ctx) 4422 { 4423 void *hif_ctx = cds_get_context(QDF_MODULE_ID_HIF); 4424 4425 if (!hif_ctx) 4426 return; 4427 4428 hdd_wlan_unregister_pm_qos_notifier(hdd_ctx); 4429 hif_disable_power_management(hif_ctx); 4430 } 4431 4432 /** 4433 * hdd_register_notifiers - Register netdev notifiers. 4434 * @hdd_ctx: HDD context 4435 * 4436 * Register netdev notifiers like IPv4 and IPv6. 4437 * 4438 * Return: 0 on success and errno on failure 4439 */ 4440 static int hdd_register_notifiers(struct hdd_context *hdd_ctx) 4441 { 4442 int ret; 4443 4444 ret = hdd_wlan_register_ip6_notifier(hdd_ctx); 4445 if (ret) 4446 goto out; 4447 4448 hdd_ctx->ipv4_notifier.notifier_call = wlan_hdd_ipv4_changed; 4449 ret = register_inetaddr_notifier(&hdd_ctx->ipv4_notifier); 4450 if (ret) { 4451 hdd_err("Failed to register IPv4 notifier: %d", ret); 4452 goto unregister_ip6_notifier; 4453 } 4454 4455 ret = osif_dp_nud_register_netevent_notifier(hdd_ctx->psoc); 4456 if (ret) { 4457 hdd_err("Failed to register netevent notifier: %d", 4458 ret); 4459 goto unregister_inetaddr_notifier; 4460 } 4461 4462 return 0; 4463 4464 unregister_inetaddr_notifier: 4465 unregister_inetaddr_notifier(&hdd_ctx->ipv4_notifier); 4466 unregister_ip6_notifier: 4467 hdd_wlan_unregister_ip6_notifier(hdd_ctx); 4468 out: 4469 return ret; 4470 } 4471 4472 #ifdef WLAN_FEATURE_WMI_SEND_RECV_QMI 4473 static inline 4474 void hdd_set_qmi_stats_enabled(struct hdd_context *hdd_ctx) 4475 { 4476 wmi_unified_t wmi_handle = get_wmi_unified_hdl_from_psoc(hdd_ctx->psoc); 4477 4478 if (!wmi_handle) { 4479 hdd_err("could not get wmi handle"); 4480 return; 4481 } 4482 4483 wmi_set_qmi_stats(wmi_handle, hdd_ctx->config->is_qmi_stats_enabled); 4484 } 4485 #else 4486 static inline 4487 void hdd_set_qmi_stats_enabled(struct hdd_context *hdd_ctx) 4488 { 4489 } 4490 #endif 4491 4492 #ifdef CONFIG_FW_LOGS_BASED_ON_INI 4493 /** 4494 * hdd_set_fw_log_params() - Set log parameters to FW 4495 * @hdd_ctx: HDD Context 4496 * @vdev_id: vdev_id 4497 * 4498 * This function set the FW Debug log level based on the INI. 4499 * 4500 * Return: None 4501 */ 4502 static void hdd_set_fw_log_params(struct hdd_context *hdd_ctx, 4503 uint8_t vdev_id) 4504 { 4505 QDF_STATUS status; 4506 uint16_t enable_fw_log_level, enable_fw_log_type; 4507 int ret; 4508 4509 if (!hdd_ctx->config->enable_fw_log) { 4510 hdd_debug("enable_fw_log not enabled in INI"); 4511 return; 4512 } 4513 4514 /* Enable FW logs based on INI configuration */ 4515 status = ucfg_fwol_get_enable_fw_log_type(hdd_ctx->psoc, 4516 &enable_fw_log_type); 4517 if (QDF_IS_STATUS_ERROR(status)) 4518 return; 4519 ret = sme_cli_set_command(vdev_id, WMI_DBGLOG_TYPE, 4520 enable_fw_log_type, DBG_CMD); 4521 if (ret != 0) 4522 hdd_err("Failed to enable FW log type ret %d", ret); 4523 4524 status = ucfg_fwol_get_enable_fw_log_level(hdd_ctx->psoc, 4525 &enable_fw_log_level); 4526 if (QDF_IS_STATUS_ERROR(status)) 4527 return; 4528 ret = sme_cli_set_command(vdev_id, WMI_DBGLOG_LOG_LEVEL, 4529 enable_fw_log_level, DBG_CMD); 4530 if (ret != 0) 4531 hdd_err("Failed to enable FW log level ret %d", ret); 4532 4533 sme_enable_fw_module_log_level(hdd_ctx->mac_handle, vdev_id); 4534 } 4535 #else 4536 static void hdd_set_fw_log_params(struct hdd_context *hdd_ctx, uint8_t vdev_id) 4537 { 4538 } 4539 4540 #endif 4541 4542 /** 4543 * hdd_features_deinit() - Deinit features 4544 * @hdd_ctx: HDD context 4545 * 4546 * De-Initialize features and their feature context. 4547 * 4548 * Return: none. 4549 */ 4550 static void hdd_features_deinit(struct hdd_context *hdd_ctx) 4551 { 4552 wlan_hdd_gpio_wakeup_deinit(hdd_ctx); 4553 wlan_hdd_twt_deinit(hdd_ctx); 4554 wlan_hdd_deinit_chan_info(hdd_ctx); 4555 wlan_hdd_tsf_deinit(hdd_ctx); 4556 if (cds_is_packet_log_enabled()) 4557 hdd_pktlog_enable_disable(hdd_ctx, false, 0, 0); 4558 } 4559 4560 /** 4561 * hdd_deconfigure_cds() -De-Configure cds 4562 * @hdd_ctx: HDD context 4563 * 4564 * Deconfigure Cds modules before WLAN firmware is down. 4565 * 4566 * Return: 0 on success and errno on failure. 4567 */ 4568 static int hdd_deconfigure_cds(struct hdd_context *hdd_ctx) 4569 { 4570 QDF_STATUS qdf_status; 4571 int ret = 0; 4572 4573 hdd_enter(); 4574 4575 wlan_hdd_hang_event_notifier_unregister(); 4576 /* De-init features */ 4577 hdd_features_deinit(hdd_ctx); 4578 4579 qdf_status = policy_mgr_deregister_mode_change_cb(hdd_ctx->psoc); 4580 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) 4581 hdd_debug("Failed to deregister mode change cb with Policy Manager"); 4582 4583 qdf_status = cds_disable(hdd_ctx->psoc); 4584 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { 4585 hdd_err("Failed to Disable the CDS Modules! :%d", 4586 qdf_status); 4587 ret = -EINVAL; 4588 } 4589 4590 if (ucfg_ipa_uc_ol_deinit(hdd_ctx->pdev) != QDF_STATUS_SUCCESS) { 4591 hdd_err("Failed to disconnect pipes"); 4592 ret = -EINVAL; 4593 } 4594 4595 hdd_exit(); 4596 return ret; 4597 } 4598 4599 /** 4600 * hdd_qmi_register_callbacks() - Register QMI callbacks 4601 * @hdd_ctx: HDD context 4602 * 4603 * Return: None 4604 */ 4605 static inline void hdd_qmi_register_callbacks(struct hdd_context *hdd_ctx) 4606 { 4607 struct wlan_qmi_psoc_callbacks cb_obj; 4608 4609 os_if_qmi_register_callbacks(hdd_ctx->psoc, &cb_obj); 4610 } 4611 4612 /** 4613 * hdd_set_pcie_params() - Set pcie params 4614 * @hdd_ctx: HDD context 4615 * @index: index value 4616 * @param: pointer to vdev/pdev set param info 4617 * 4618 * Checks for pcie_config value and sets 4619 * corresponding params 4620 * 4621 * Return: 0 on success and errno on failure. 4622 */ 4623 static int hdd_set_pcie_params(struct hdd_context *hdd_ctx, 4624 uint8_t index, struct dev_set_param *param) 4625 { 4626 int ret = 0; 4627 uint8_t check_value = 0; 4628 4629 ret = ucfg_fwol_get_pcie_config(hdd_ctx->psoc, &check_value); 4630 if (QDF_IS_STATUS_SUCCESS(ret)) { 4631 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) { 4632 ret = mlme_check_index_setparam(param, 4633 wmi_pdev_param_pcie_config, 4634 (int)check_value, index++, 4635 FTM_MAX_PDEV_PARAMS); 4636 } else { 4637 ret = mlme_check_index_setparam(param, 4638 wmi_pdev_param_pcie_config, 4639 (int)check_value, index++, 4640 MAX_PDEV_PRE_ENABLE_PARAMS); 4641 } 4642 if (QDF_IS_STATUS_ERROR(ret)) { 4643 hdd_err("failed to set wmi_pdev_param_pcie_config"); 4644 return ret; 4645 } 4646 } 4647 return ret; 4648 } 4649 4650 #ifdef FEATURE_SET 4651 #ifdef WLAN_FEATURE_11BE 4652 /** 4653 * hdd_is_cfg_dot11_mode_11be() - Check if dot11 mode is 11 be 4654 * @dot11_mode: Input dot11_mode which needs to be checked 4655 * 4656 * Return: True, ifinput dot11_mode is 11be dot11 mode else return false 4657 */ 4658 static bool hdd_is_cfg_dot11_mode_11be(enum hdd_dot11_mode dot11_mode) 4659 { 4660 return (dot11_mode == eHDD_DOT11_MODE_11be || 4661 dot11_mode == eHDD_DOT11_MODE_11be_ONLY); 4662 } 4663 4664 /** 4665 * hdd_is_11be_supported() - Check if 11be is supported or not 4666 * @hdd_ctx: Pointer to hdd context 4667 * 4668 * Return: True, if 11be is supported else return false 4669 */ 4670 static bool hdd_is_11be_supported(struct hdd_context *hdd_ctx) 4671 { 4672 bool mlo_capab; 4673 4674 ucfg_psoc_mlme_get_11be_capab(hdd_ctx->psoc, &mlo_capab); 4675 if (!mlo_capab) 4676 return false; 4677 4678 return true; 4679 } 4680 #else 4681 4682 static bool hdd_is_cfg_dot11_mode_11be(enum hdd_dot11_mode dot11_mode) 4683 { 4684 return false; 4685 } 4686 4687 static bool hdd_is_11be_supported(struct hdd_context *hdd_ctx) 4688 { 4689 return false; 4690 } 4691 #endif 4692 4693 WMI_HOST_WIFI_STANDARD 4694 hdd_get_wifi_standard(struct hdd_context *hdd_ctx, 4695 enum hdd_dot11_mode dot11_mode, uint32_t band_capability) 4696 { 4697 WMI_HOST_WIFI_STANDARD wifi_standard = WMI_HOST_WIFI_STANDARD_4; 4698 4699 if (dot11_mode == eHDD_DOT11_MODE_AUTO) { 4700 if (hdd_is_11be_supported(hdd_ctx)) 4701 wifi_standard = WMI_HOST_WIFI_STANDARD_7; 4702 else if (band_capability & BIT(REG_BAND_6G)) 4703 wifi_standard = WMI_HOST_WIFI_STANDARD_6E; 4704 else 4705 wifi_standard = WMI_HOST_WIFI_STANDARD_6; 4706 } else if (hdd_is_cfg_dot11_mode_11be(dot11_mode)) { 4707 wifi_standard = WMI_HOST_WIFI_STANDARD_7; 4708 } else if (dot11_mode == eHDD_DOT11_MODE_11ax || 4709 (dot11_mode == eHDD_DOT11_MODE_11ax_ONLY)) { 4710 if (band_capability & BIT(REG_BAND_6G)) 4711 wifi_standard = WMI_HOST_WIFI_STANDARD_6E; 4712 else 4713 wifi_standard = WMI_HOST_WIFI_STANDARD_6; 4714 } else if ((dot11_mode == eHDD_DOT11_MODE_11ac) || 4715 (dot11_mode == eHDD_DOT11_MODE_11ac_ONLY)) { 4716 wifi_standard = WMI_HOST_WIFI_STANDARD_5; 4717 } 4718 4719 return wifi_standard; 4720 } 4721 4722 /** 4723 * hdd_populate_feature_set_cds_config() - Populate cds feature set config 4724 * @hdd_ctx: hdd context pointer 4725 * 4726 * Return: None 4727 */ 4728 static void hdd_populate_feature_set_cds_config(struct hdd_context *hdd_ctx) 4729 { 4730 struct wlan_objmgr_psoc *psoc; 4731 uint32_t band_capability; 4732 QDF_STATUS status; 4733 struct cds_config_info *cds_cfg; 4734 4735 if (!hdd_ctx) 4736 return; 4737 4738 cds_cfg = cds_get_ini_config(); 4739 if (!cds_cfg) { 4740 hdd_err("CDS config is null."); 4741 return; 4742 } 4743 4744 psoc = hdd_ctx->psoc; 4745 4746 cds_cfg->get_wifi_features = hdd_ctx->config->get_wifi_features; 4747 4748 status = ucfg_mlme_get_band_capability(hdd_ctx->psoc, &band_capability); 4749 if (QDF_IS_STATUS_ERROR(status)) 4750 hdd_err("Failed to get MLME band capability"); 4751 4752 band_capability = 4753 hdd_update_band_cap_from_dot11mode(hdd_ctx, band_capability); 4754 4755 cds_cfg->cds_feature_set.wifi_standard = 4756 hdd_get_wifi_standard(hdd_ctx, 4757 hdd_ctx->config->dot11Mode, 4758 band_capability); 4759 4760 cds_cfg->cds_feature_set.sap_5g_supported = 4761 band_capability & BIT(REG_BAND_5G); 4762 4763 cds_cfg->cds_feature_set.sap_6g_supported = 4764 band_capability & BIT(REG_BAND_6G); 4765 cds_cfg->cds_feature_set.band_capability = band_capability; 4766 } 4767 #else 4768 WMI_HOST_WIFI_STANDARD 4769 hdd_get_wifi_standard(struct hdd_context *hdd_ctx, 4770 enum hdd_dot11_mode dot11_mode, uint32_t band_capability) 4771 { 4772 return WMI_HOST_WIFI_STANDARD_5; 4773 } 4774 4775 static inline void 4776 hdd_populate_feature_set_cds_config(struct hdd_context *hdd_ctx) 4777 { 4778 } 4779 #endif 4780 4781 int hdd_wlan_start_modules(struct hdd_context *hdd_ctx, bool reinit) 4782 { 4783 int ret = 0; 4784 qdf_device_t qdf_dev; 4785 QDF_STATUS status; 4786 bool unint = false; 4787 void *hif_ctx; 4788 struct target_psoc_info *tgt_hdl; 4789 unsigned long thermal_state = 0; 4790 uint8_t index = 0; 4791 struct dev_set_param setparam[MAX_PDEV_PRE_ENABLE_PARAMS] = {}; 4792 4793 hdd_enter(); 4794 qdf_dev = cds_get_context(QDF_MODULE_ID_QDF_DEVICE); 4795 if (!qdf_dev) { 4796 hdd_exit(); 4797 return -EINVAL; 4798 } 4799 4800 hdd_psoc_idle_timer_stop(hdd_ctx); 4801 4802 if (hdd_ctx->driver_status == DRIVER_MODULES_ENABLED) { 4803 hdd_debug("Driver modules already Enabled"); 4804 hdd_exit(); 4805 return 0; 4806 } 4807 4808 cds_set_driver_state_module_stop(false); 4809 4810 switch (hdd_ctx->driver_status) { 4811 case DRIVER_MODULES_UNINITIALIZED: 4812 hdd_nofl_debug("Wlan transitioning (UNINITIALIZED -> CLOSED)"); 4813 unint = true; 4814 fallthrough; 4815 case DRIVER_MODULES_CLOSED: 4816 hdd_nofl_debug("Wlan transitioning (CLOSED -> ENABLED)"); 4817 ret = hdd_debug_domain_set(QDF_DEBUG_DOMAIN_ACTIVE); 4818 if (ret) 4819 goto abort; 4820 4821 if (!reinit && !unint) { 4822 ret = pld_power_on(qdf_dev->dev); 4823 if (ret) { 4824 hdd_err("Failed to power up device; errno:%d", 4825 ret); 4826 goto release_lock; 4827 } 4828 } 4829 4830 hdd_init_adapter_ops_wq(hdd_ctx); 4831 pld_set_fw_log_mode(hdd_ctx->parent_dev, 4832 hdd_ctx->config->enable_fw_log); 4833 ret = hdd_hif_open(qdf_dev->dev, qdf_dev->drv_hdl, qdf_dev->bid, 4834 qdf_dev->bus_type, 4835 (reinit == true) ? HIF_ENABLE_TYPE_REINIT : 4836 HIF_ENABLE_TYPE_PROBE); 4837 if (ret) { 4838 hdd_err("Failed to open hif; errno: %d", ret); 4839 goto power_down; 4840 } 4841 4842 hif_ctx = cds_get_context(QDF_MODULE_ID_HIF); 4843 if (!hif_ctx) { 4844 ret = -EINVAL; 4845 goto power_down; 4846 } 4847 4848 status = ol_cds_init(qdf_dev, hif_ctx); 4849 if (status != QDF_STATUS_SUCCESS) { 4850 hdd_err("No Memory to Create BMI Context; status: %d", 4851 status); 4852 ret = qdf_status_to_os_return(status); 4853 goto hif_close; 4854 } 4855 4856 if (hdd_get_conparam() == QDF_GLOBAL_EPPING_MODE) { 4857 status = epping_open(); 4858 if (status) { 4859 hdd_err("Failed to open in epping mode: %d", 4860 status); 4861 ret = -EINVAL; 4862 goto cds_free; 4863 } 4864 4865 status = epping_enable(qdf_dev->dev, false); 4866 if (status) { 4867 hdd_err("Failed to enable in epping mode : %d", 4868 status); 4869 epping_close(); 4870 goto cds_free; 4871 } 4872 4873 hdd_info("epping mode enabled"); 4874 break; 4875 } 4876 4877 if (pld_is_ipa_offload_disabled(qdf_dev->dev)) 4878 ucfg_ipa_set_pld_enable(false); 4879 4880 ucfg_ipa_component_config_update(hdd_ctx->psoc); 4881 4882 hdd_update_cds_ac_specs_params(hdd_ctx); 4883 4884 hdd_dp_register_callbacks(hdd_ctx); 4885 4886 hdd_qmi_register_callbacks(hdd_ctx); 4887 4888 status = hdd_component_psoc_open(hdd_ctx->psoc); 4889 if (QDF_IS_STATUS_ERROR(status)) { 4890 hdd_err("Failed to Open legacy components; status: %d", 4891 status); 4892 ret = qdf_status_to_os_return(status); 4893 goto ipa_component_free; 4894 } 4895 4896 ret = hdd_update_config(hdd_ctx); 4897 if (ret) { 4898 hdd_err("Failed to update configuration; errno: %d", 4899 ret); 4900 goto ipa_component_free; 4901 } 4902 4903 status = wbuff_module_init(); 4904 if (QDF_IS_STATUS_ERROR(status)) 4905 hdd_err("WBUFF init unsuccessful; status: %d", status); 4906 4907 status = cds_open(hdd_ctx->psoc); 4908 if (QDF_IS_STATUS_ERROR(status)) { 4909 hdd_err("Failed to Open CDS; status: %d", status); 4910 ret = qdf_status_to_os_return(status); 4911 goto psoc_close; 4912 } 4913 4914 hdd_populate_feature_set_cds_config(hdd_ctx); 4915 4916 hdd_set_qmi_stats_enabled(hdd_ctx); 4917 4918 hdd_ctx->mac_handle = cds_get_context(QDF_MODULE_ID_SME); 4919 4920 ucfg_dp_set_rx_thread_affinity(hdd_ctx->psoc); 4921 4922 /* initialize components configurations after psoc open */ 4923 ret = hdd_update_components_config(hdd_ctx); 4924 if (ret) { 4925 hdd_err("Failed to update component configs; errno: %d", 4926 ret); 4927 goto close; 4928 } 4929 4930 /* Override PS params for monitor mode */ 4931 if (hdd_get_conparam() == QDF_GLOBAL_MONITOR_MODE) 4932 hdd_override_all_ps(hdd_ctx); 4933 4934 status = cds_dp_open(hdd_ctx->psoc); 4935 if (!QDF_IS_STATUS_SUCCESS(status)) { 4936 hdd_err("Failed to Open cds post open; status: %d", 4937 status); 4938 ret = qdf_status_to_os_return(status); 4939 goto close; 4940 } 4941 /* Set IRQ affinity for WLAN DP and CE IRQS */ 4942 hif_config_irq_set_perf_affinity_hint(hif_ctx); 4943 4944 ret = hdd_register_cb(hdd_ctx); 4945 if (ret) { 4946 hdd_err("Failed to register HDD callbacks!"); 4947 goto cds_txrx_free; 4948 } 4949 4950 ret = hdd_register_notifiers(hdd_ctx); 4951 if (ret) 4952 goto deregister_cb; 4953 4954 /* 4955 * NAN component requires certain operations like, open adapter, 4956 * close adapter, etc. to be initiated by HDD, for those 4957 * register HDD callbacks with UMAC's NAN component. 4958 */ 4959 hdd_nan_register_callbacks(hdd_ctx); 4960 4961 hdd_son_register_callbacks(hdd_ctx); 4962 4963 hdd_sr_register_callbacks(hdd_ctx); 4964 4965 wlan_hdd_register_btc_chain_mode_handler(hdd_ctx->psoc); 4966 4967 wlan_hdd_register_afc_pld_cb(hdd_ctx->psoc); 4968 4969 status = cds_pre_enable(); 4970 if (!QDF_IS_STATUS_SUCCESS(status)) { 4971 hdd_err("Failed to pre-enable CDS; status: %d", status); 4972 ret = qdf_status_to_os_return(status); 4973 goto unregister_notifiers; 4974 } 4975 4976 hdd_register_policy_manager_callback( 4977 hdd_ctx->psoc); 4978 4979 /* 4980 * Call this function before hdd_enable_power_management. Since 4981 * it is required to trigger WMI_PDEV_DMA_RING_CFG_REQ_CMDID 4982 * to FW when power save isn't enable. 4983 */ 4984 hdd_spectral_register_to_dbr(hdd_ctx); 4985 4986 hdd_create_sysfs_files(hdd_ctx); 4987 hdd_update_hw_sw_info(hdd_ctx); 4988 4989 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) { 4990 hdd_enable_power_management(hdd_ctx); 4991 hdd_err("in ftm mode, no need to configure cds modules"); 4992 hdd_info("Enable FW log in ftm mode"); 4993 /* 4994 * Since vdev is not created for FTM mode, 4995 * in FW use vdev_id = 0. 4996 */ 4997 hdd_set_fw_log_params(hdd_ctx, 0); 4998 ret = hdd_set_pcie_params(hdd_ctx, index, setparam); 4999 if (QDF_IS_STATUS_ERROR(ret)) 5000 break; 5001 index++; 5002 ret = sme_send_multi_pdev_vdev_set_params( 5003 MLME_PDEV_SETPARAM, 5004 WMI_PDEV_ID_SOC, setparam, index); 5005 if (QDF_IS_STATUS_ERROR(ret)) { 5006 hdd_err("failed to send pdev set params"); 5007 return ret; 5008 } 5009 5010 ret = -EINVAL; 5011 break; 5012 } 5013 5014 ret = hdd_configure_cds(hdd_ctx); 5015 if (ret) { 5016 hdd_err("Failed to Enable cds modules; errno: %d", ret); 5017 goto sched_disable; 5018 } 5019 5020 if (hdd_get_conparam() == QDF_GLOBAL_MISSION_MODE) { 5021 status = ucfg_dp_direct_link_init(hdd_ctx->psoc); 5022 if (QDF_IS_STATUS_ERROR(status)) { 5023 cds_err("Failed to initialize Direct Link datapath"); 5024 ret = -EINVAL; 5025 goto deconfigure_cds; 5026 } 5027 } 5028 5029 hdd_enable_power_management(hdd_ctx); 5030 5031 hdd_skip_acs_scan_timer_init(hdd_ctx); 5032 5033 hdd_set_hif_init_phase(hif_ctx, false); 5034 hdd_hif_set_enable_detection(hif_ctx, true); 5035 5036 wlan_hdd_start_connectivity_logging(hdd_ctx); 5037 5038 break; 5039 5040 default: 5041 QDF_DEBUG_PANIC("Unknown driver state:%d", 5042 hdd_ctx->driver_status); 5043 ret = -EINVAL; 5044 goto release_lock; 5045 } 5046 5047 hdd_ctx->driver_status = DRIVER_MODULES_ENABLED; 5048 hdd_nofl_debug("Wlan transitioned (now ENABLED)"); 5049 5050 ucfg_ipa_reg_is_driver_unloading_cb(hdd_ctx->pdev, 5051 cds_is_driver_unloading); 5052 ucfg_ipa_reg_sap_xmit_cb(hdd_ctx->pdev, 5053 hdd_softap_ipa_start_xmit); 5054 ucfg_ipa_reg_send_to_nw_cb(hdd_ctx->pdev, 5055 hdd_ipa_send_nbuf_to_network); 5056 ucfg_dp_reg_ipa_rsp_ind(hdd_ctx->pdev); 5057 5058 if (!pld_get_thermal_state(hdd_ctx->parent_dev, &thermal_state, 5059 THERMAL_MONITOR_APPS)) { 5060 if (thermal_state > QCA_WLAN_VENDOR_THERMAL_LEVEL_NONE) 5061 hdd_send_thermal_mitigation_val(hdd_ctx, 5062 thermal_state, 5063 THERMAL_MONITOR_APPS); 5064 } 5065 5066 if (!pld_get_thermal_state(hdd_ctx->parent_dev, &thermal_state, 5067 THERMAL_MONITOR_WPSS)) { 5068 if (thermal_state > QCA_WLAN_VENDOR_THERMAL_LEVEL_NONE) 5069 hdd_send_thermal_mitigation_val(hdd_ctx, thermal_state, 5070 THERMAL_MONITOR_WPSS); 5071 } 5072 5073 hdd_exit(); 5074 5075 return 0; 5076 5077 deconfigure_cds: 5078 hdd_deconfigure_cds(hdd_ctx); 5079 sched_disable: 5080 /* 5081 * Disable scheduler 1st so that scheduler thread doesn't send messages 5082 * to fw in parallel to the cleanup 5083 */ 5084 dispatcher_disable(); 5085 hdd_destroy_sysfs_files(); 5086 cds_post_disable(); 5087 unregister_notifiers: 5088 hdd_unregister_notifiers(hdd_ctx); 5089 5090 deregister_cb: 5091 hdd_deregister_cb(hdd_ctx); 5092 5093 cds_txrx_free: 5094 5095 tgt_hdl = wlan_psoc_get_tgt_if_handle(hdd_ctx->psoc); 5096 5097 if (tgt_hdl && target_psoc_get_wmi_ready(tgt_hdl)) 5098 hdd_runtime_suspend_context_deinit(hdd_ctx); 5099 5100 if (hdd_ctx->pdev) { 5101 dispatcher_pdev_close(hdd_ctx->pdev); 5102 hdd_objmgr_release_and_destroy_pdev(hdd_ctx); 5103 } 5104 5105 cds_dp_close(hdd_ctx->psoc); 5106 5107 close: 5108 dispatcher_disable(); 5109 hdd_ctx->driver_status = DRIVER_MODULES_CLOSED; 5110 hdd_info("Wlan transition aborted (now CLOSED)"); 5111 5112 cds_close(hdd_ctx->psoc); 5113 5114 psoc_close: 5115 hdd_component_psoc_close(hdd_ctx->psoc); 5116 wlan_global_lmac_if_close(hdd_ctx->psoc); 5117 cds_deinit_ini_config(); 5118 5119 ipa_component_free: 5120 ucfg_ipa_component_config_free(); 5121 5122 cds_free: 5123 ol_cds_free(); 5124 5125 hif_close: 5126 hif_ctx = cds_get_context(QDF_MODULE_ID_HIF); 5127 hdd_hif_close(hdd_ctx, hif_ctx); 5128 power_down: 5129 hdd_deinit_adapter_ops_wq(hdd_ctx); 5130 if (!reinit && !unint) 5131 pld_power_off(qdf_dev->dev); 5132 release_lock: 5133 cds_shutdown_notifier_purge(); 5134 hdd_check_for_leaks(hdd_ctx, reinit); 5135 hdd_debug_domain_set(QDF_DEBUG_DOMAIN_INIT); 5136 5137 abort: 5138 cds_set_driver_state_module_stop(true); 5139 5140 hdd_exit(); 5141 5142 return ret; 5143 } 5144 5145 #ifdef WIFI_POS_CONVERGED 5146 static int hdd_activate_wifi_pos(struct hdd_context *hdd_ctx) 5147 { 5148 int ret = os_if_wifi_pos_register_nl(); 5149 5150 if (ret) 5151 hdd_err("os_if_wifi_pos_register_nl failed"); 5152 5153 return ret; 5154 } 5155 5156 static int hdd_deactivate_wifi_pos(void) 5157 { 5158 int ret = os_if_wifi_pos_deregister_nl(); 5159 5160 if (ret) 5161 hdd_err("os_if_wifi_pos_deregister_nl failed"); 5162 5163 return ret; 5164 } 5165 5166 /** 5167 * hdd_populate_wifi_pos_cfg - populates wifi_pos parameters 5168 * @hdd_ctx: hdd context 5169 * 5170 * Return: status of operation 5171 */ 5172 static void hdd_populate_wifi_pos_cfg(struct hdd_context *hdd_ctx) 5173 { 5174 struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc; 5175 uint16_t neighbor_scan_max_chan_time; 5176 uint16_t neighbor_scan_min_chan_time; 5177 5178 wifi_pos_set_oem_target_type(psoc, hdd_ctx->target_type); 5179 wifi_pos_set_oem_fw_version(psoc, hdd_ctx->target_fw_version); 5180 wifi_pos_set_drv_ver_major(psoc, QWLAN_VERSION_MAJOR); 5181 wifi_pos_set_drv_ver_minor(psoc, QWLAN_VERSION_MINOR); 5182 wifi_pos_set_drv_ver_patch(psoc, QWLAN_VERSION_PATCH); 5183 wifi_pos_set_drv_ver_build(psoc, QWLAN_VERSION_BUILD); 5184 ucfg_mlme_get_neighbor_scan_max_chan_time(psoc, 5185 &neighbor_scan_max_chan_time); 5186 ucfg_mlme_get_neighbor_scan_min_chan_time(psoc, 5187 &neighbor_scan_min_chan_time); 5188 wifi_pos_set_dwell_time_min(psoc, neighbor_scan_min_chan_time); 5189 wifi_pos_set_dwell_time_max(psoc, neighbor_scan_max_chan_time); 5190 } 5191 #else 5192 static int hdd_activate_wifi_pos(struct hdd_context *hdd_ctx) 5193 { 5194 return oem_activate_service(hdd_ctx); 5195 } 5196 5197 static int hdd_deactivate_wifi_pos(void) 5198 { 5199 return oem_deactivate_service(); 5200 } 5201 5202 static void hdd_populate_wifi_pos_cfg(struct hdd_context *hdd_ctx) 5203 { 5204 } 5205 #endif 5206 5207 /** 5208 * __hdd_open() - HDD Open function 5209 * @dev: Pointer to net_device structure 5210 * 5211 * This is called in response to ifconfig up 5212 * 5213 * Return: 0 for success; non-zero for failure 5214 */ 5215 static int __hdd_open(struct net_device *dev) 5216 { 5217 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev); 5218 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); 5219 int ret; 5220 struct wlan_hdd_link_info *link_info = adapter->deflink; 5221 5222 hdd_enter_dev(dev); 5223 5224 qdf_mtrace(QDF_MODULE_ID_HDD, QDF_MODULE_ID_HDD, 5225 TRACE_CODE_HDD_OPEN_REQUEST, 5226 link_info->vdev_id, adapter->device_mode); 5227 5228 /* Nothing to be done if device is unloading */ 5229 if (cds_is_driver_unloading()) { 5230 hdd_err("Driver is unloading can not open the hdd"); 5231 return -EBUSY; 5232 } 5233 5234 if (cds_is_driver_recovering()) { 5235 hdd_err("WLAN is currently recovering; Please try again."); 5236 return -EBUSY; 5237 } 5238 5239 /* 5240 * This scenario can be hit in cases where in the wlan driver after 5241 * registering the netdevices and there is a failure in driver 5242 * initialization. So return error gracefully because the netdevices 5243 * will be de-registered as part of the load failure. 5244 */ 5245 5246 if (!cds_is_driver_loaded()) { 5247 hdd_err("Failed to start the wlan driver!!"); 5248 return -EIO; 5249 } 5250 5251 ret = wlan_hdd_validate_context(hdd_ctx); 5252 if (ret) { 5253 hdd_err("Can't start WLAN module, WiFi Disabled"); 5254 return ret; 5255 } 5256 5257 ret = hdd_trigger_psoc_idle_restart(hdd_ctx); 5258 if (ret) { 5259 hdd_err("Failed to start WLAN modules return"); 5260 return ret; 5261 } 5262 5263 if (!test_bit(SME_SESSION_OPENED, &link_info->link_flags)) { 5264 ret = hdd_start_adapter(adapter, true); 5265 if (ret) { 5266 hdd_err("Failed to start adapter :%d", 5267 adapter->device_mode); 5268 return ret; 5269 } 5270 } 5271 5272 set_bit(DEVICE_IFACE_OPENED, &adapter->event_flags); 5273 if (hdd_cm_is_vdev_associated(link_info)) { 5274 hdd_debug("Enabling Tx Queues"); 5275 /* Enable TX queues only when we are connected */ 5276 wlan_hdd_netif_queue_control(adapter, 5277 WLAN_START_ALL_NETIF_QUEUE, 5278 WLAN_CONTROL_PATH); 5279 } 5280 5281 /* Enable carrier and transmit queues for NDI */ 5282 if (WLAN_HDD_IS_NDI(adapter)) { 5283 hdd_debug("Enabling Tx Queues"); 5284 wlan_hdd_netif_queue_control(adapter, 5285 WLAN_START_ALL_NETIF_QUEUE_N_CARRIER, 5286 WLAN_CONTROL_PATH); 5287 } 5288 5289 hdd_populate_wifi_pos_cfg(hdd_ctx); 5290 hdd_lpass_notify_start(link_info); 5291 5292 if (ucfg_pkt_capture_get_mode(hdd_ctx->psoc) != 5293 PACKET_CAPTURE_MODE_DISABLE) 5294 hdd_map_monitor_interface_vdev(adapter); 5295 5296 return 0; 5297 } 5298 5299 /** 5300 * hdd_open() - Wrapper function for __hdd_open to protect it from SSR 5301 * @net_dev: Pointer to net_device structure 5302 * 5303 * This is called in response to ifconfig up 5304 * 5305 * Return: 0 for success; non-zero for failure 5306 */ 5307 static int hdd_open(struct net_device *net_dev) 5308 { 5309 int errno; 5310 struct osif_vdev_sync *vdev_sync; 5311 5312 errno = osif_vdev_sync_trans_start(net_dev, &vdev_sync); 5313 if (errno) 5314 return errno; 5315 5316 errno = __hdd_open(net_dev); 5317 if (!errno) 5318 osif_vdev_cache_command(vdev_sync, NO_COMMAND); 5319 5320 osif_vdev_sync_trans_stop(vdev_sync); 5321 5322 return errno; 5323 } 5324 5325 int hdd_stop_no_trans(struct net_device *dev) 5326 { 5327 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev); 5328 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); 5329 int ret; 5330 mac_handle_t mac_handle; 5331 5332 hdd_enter_dev(dev); 5333 5334 qdf_mtrace(QDF_MODULE_ID_HDD, QDF_MODULE_ID_HDD, 5335 TRACE_CODE_HDD_STOP_REQUEST, 5336 adapter->deflink->vdev_id, adapter->device_mode); 5337 5338 ret = wlan_hdd_validate_context(hdd_ctx); 5339 if (ret) 5340 return ret; 5341 5342 /* Nothing to be done if the interface is not opened */ 5343 if (false == test_bit(DEVICE_IFACE_OPENED, &adapter->event_flags)) { 5344 hdd_err("NETDEV Interface is not OPENED"); 5345 return -ENODEV; 5346 } 5347 5348 mac_handle = hdd_ctx->mac_handle; 5349 5350 if (!wlan_hdd_is_session_type_monitor(adapter->device_mode) && 5351 adapter->device_mode != QDF_FTM_MODE) { 5352 hdd_debug("Disabling Auto Power save timer"); 5353 sme_ps_disable_auto_ps_timer( 5354 mac_handle, 5355 adapter->deflink->vdev_id); 5356 } 5357 5358 /* 5359 * Disable TX on the interface, after this hard_start_xmit() will not 5360 * be called on that interface 5361 */ 5362 hdd_debug("Disabling queues, adapter device mode: %s(%d)", 5363 qdf_opmode_str(adapter->device_mode), adapter->device_mode); 5364 5365 wlan_hdd_netif_queue_control(adapter, 5366 WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER, 5367 WLAN_CONTROL_PATH); 5368 5369 if (adapter->device_mode == QDF_STA_MODE) 5370 hdd_lpass_notify_stop(hdd_ctx); 5371 5372 /* 5373 * NAN data interface is different in some sense. The traffic on NDI is 5374 * bursty in nature and depends on the need to transfer. The service 5375 * layer may down the interface after the usage and up again when 5376 * required. In some sense, the NDI is expected to be available 5377 * (like SAP) iface until NDI delete request is issued by the service 5378 * layer. Skip BSS termination and adapter deletion for NAN Data 5379 * interface (NDI). 5380 */ 5381 if (WLAN_HDD_IS_NDI(adapter)) 5382 goto reset_iface_opened; 5383 5384 /* 5385 * The interface is marked as down for outside world (aka kernel) 5386 * But the driver is pretty much alive inside. The driver needs to 5387 * tear down the existing connection on the netdev (session) 5388 * cleanup the data pipes and wait until the control plane is stabilized 5389 * for this interface. The call also needs to wait until the above 5390 * mentioned actions are completed before returning to the caller. 5391 * Notice that hdd_stop_adapter is requested not to close the session 5392 * That is intentional to be able to scan if it is a STA/P2P interface 5393 */ 5394 hdd_stop_adapter(hdd_ctx, adapter); 5395 5396 /* DeInit the adapter. This ensures datapath cleanup as well */ 5397 hdd_deinit_adapter(hdd_ctx, adapter, true); 5398 5399 reset_iface_opened: 5400 /* Make sure the interface is marked as closed */ 5401 clear_bit(DEVICE_IFACE_OPENED, &adapter->event_flags); 5402 if (!hdd_is_any_interface_open(hdd_ctx)) 5403 hdd_psoc_idle_timer_start(hdd_ctx); 5404 hdd_exit(); 5405 5406 return 0; 5407 } 5408 5409 /** 5410 * hdd_stop() - Wrapper function for __hdd_stop to protect it from SSR 5411 * @net_dev: pointer to net_device structure 5412 * 5413 * This is called in response to ifconfig down 5414 * 5415 * Return: 0 for success and error number for failure 5416 */ 5417 static int hdd_stop(struct net_device *net_dev) 5418 { 5419 int errno; 5420 struct osif_vdev_sync *vdev_sync; 5421 5422 errno = osif_vdev_sync_trans_start(net_dev, &vdev_sync); 5423 if (errno) { 5424 if (vdev_sync) 5425 osif_vdev_cache_command(vdev_sync, INTERFACE_DOWN); 5426 return errno; 5427 } 5428 5429 errno = hdd_stop_no_trans(net_dev); 5430 5431 osif_vdev_sync_trans_stop(vdev_sync); 5432 5433 return errno; 5434 } 5435 5436 /** 5437 * hdd_uninit() - HDD uninit function 5438 * @dev: Pointer to net_device structure 5439 * 5440 * This is called during the netdev unregister to uninitialize all data 5441 * associated with the device 5442 * 5443 * This function must be protected by a transition 5444 * 5445 * Return: None 5446 */ 5447 static void hdd_uninit(struct net_device *dev) 5448 { 5449 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev); 5450 struct hdd_context *hdd_ctx; 5451 5452 hdd_enter_dev(dev); 5453 5454 if (adapter->magic != WLAN_HDD_ADAPTER_MAGIC) { 5455 hdd_err("Invalid magic"); 5456 goto exit; 5457 } 5458 5459 hdd_ctx = WLAN_HDD_GET_CTX(adapter); 5460 if (!hdd_ctx) { 5461 hdd_err("NULL hdd_ctx"); 5462 goto exit; 5463 } 5464 5465 if (dev != adapter->dev) 5466 hdd_err("Invalid device reference"); 5467 5468 hdd_deinit_adapter(hdd_ctx, adapter, true); 5469 5470 /* after uninit our adapter structure will no longer be valid */ 5471 adapter->magic = 0; 5472 5473 exit: 5474 hdd_exit(); 5475 } 5476 5477 static int hdd_open_cesium_nl_sock(void) 5478 { 5479 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0)) 5480 struct netlink_kernel_cfg cfg = { 5481 .groups = WLAN_NLINK_MCAST_GRP_ID, 5482 .input = NULL 5483 }; 5484 #endif 5485 int ret = 0; 5486 5487 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0)) 5488 cesium_nl_srv_sock = netlink_kernel_create(&init_net, WLAN_NLINK_CESIUM, 5489 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 7, 0)) 5490 THIS_MODULE, 5491 #endif 5492 &cfg); 5493 #else 5494 cesium_nl_srv_sock = netlink_kernel_create(&init_net, WLAN_NLINK_CESIUM, 5495 WLAN_NLINK_MCAST_GRP_ID, 5496 NULL, NULL, THIS_MODULE); 5497 #endif 5498 5499 if (!cesium_nl_srv_sock) { 5500 hdd_err("NLINK: cesium netlink_kernel_create failed"); 5501 ret = -ECONNREFUSED; 5502 } 5503 5504 return ret; 5505 } 5506 5507 static void hdd_close_cesium_nl_sock(void) 5508 { 5509 if (cesium_nl_srv_sock) { 5510 netlink_kernel_release(cesium_nl_srv_sock); 5511 cesium_nl_srv_sock = NULL; 5512 } 5513 } 5514 5515 void hdd_update_dynamic_mac(struct hdd_context *hdd_ctx, 5516 struct qdf_mac_addr *curr_mac_addr, 5517 struct qdf_mac_addr *new_mac_addr) 5518 { 5519 uint8_t i; 5520 5521 hdd_enter(); 5522 5523 for (i = 0; i < QDF_MAX_CONCURRENCY_PERSONA; i++) { 5524 if (!qdf_mem_cmp( 5525 curr_mac_addr->bytes, 5526 &hdd_ctx->dynamic_mac_list[i].dynamic_mac.bytes[0], 5527 sizeof(struct qdf_mac_addr))) { 5528 qdf_mem_copy(&hdd_ctx->dynamic_mac_list[i].dynamic_mac, 5529 new_mac_addr->bytes, 5530 sizeof(struct qdf_mac_addr)); 5531 break; 5532 } 5533 } 5534 5535 hdd_exit(); 5536 } 5537 5538 #if defined(WLAN_FEATURE_11BE_MLO) && defined(CFG80211_11BE_BASIC) && \ 5539 !defined(WLAN_HDD_MULTI_VDEV_SINGLE_NDEV) 5540 void hdd_set_mld_address(struct hdd_adapter *adapter, 5541 const struct qdf_mac_addr *mac_addr) 5542 { 5543 int i; 5544 bool eht_capab; 5545 struct hdd_adapter *link_adapter; 5546 struct hdd_mlo_adapter_info *mlo_adapter_info; 5547 5548 ucfg_psoc_mlme_get_11be_capab(adapter->hdd_ctx->psoc, &eht_capab); 5549 if (adapter->mlo_adapter_info.is_ml_adapter && eht_capab) { 5550 mlo_adapter_info = &adapter->mlo_adapter_info; 5551 for (i = 0; i < WLAN_MAX_MLD; i++) { 5552 link_adapter = mlo_adapter_info->link_adapter[i]; 5553 if (link_adapter) 5554 qdf_copy_macaddr(&link_adapter->mld_addr, 5555 mac_addr); 5556 } 5557 qdf_copy_macaddr(&adapter->mld_addr, mac_addr); 5558 } 5559 } 5560 5561 /** 5562 * hdd_get_netdev_by_vdev_mac() - Get Netdev based on MAC 5563 * @mac_addr: Vdev MAC address 5564 * 5565 * Get netdev from adapter based upon Vdev MAC address. 5566 * 5567 * Return: netdev pointer. 5568 */ 5569 static qdf_netdev_t 5570 hdd_get_netdev_by_vdev_mac(struct qdf_mac_addr *mac_addr) 5571 { 5572 struct hdd_context *hdd_ctx; 5573 struct hdd_adapter *adapter; 5574 struct hdd_adapter *ml_adapter; 5575 5576 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 5577 if (!hdd_ctx) { 5578 hdd_err("Invalid HDD context"); 5579 return NULL; 5580 } 5581 5582 adapter = hdd_get_adapter_by_macaddr(hdd_ctx, mac_addr->bytes); 5583 if (!adapter) { 5584 hdd_err("Adapter not foud for MAC " QDF_MAC_ADDR_FMT "", 5585 QDF_MAC_ADDR_REF(mac_addr->bytes)); 5586 return NULL; 5587 } 5588 5589 if (adapter->mlo_adapter_info.is_link_adapter && 5590 adapter->mlo_adapter_info.associate_with_ml_adapter) { 5591 ml_adapter = adapter->mlo_adapter_info.ml_adapter; 5592 adapter = ml_adapter; 5593 } 5594 5595 return adapter->dev; 5596 } 5597 #else 5598 static qdf_netdev_t 5599 hdd_get_netdev_by_vdev_mac(struct qdf_mac_addr *mac_addr) 5600 { 5601 struct hdd_context *hdd_ctx; 5602 struct hdd_adapter *adapter; 5603 5604 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 5605 if (!hdd_ctx) { 5606 hdd_err("Invalid HDD context"); 5607 return NULL; 5608 } 5609 5610 adapter = hdd_get_adapter_by_macaddr(hdd_ctx, mac_addr->bytes); 5611 if (!adapter) { 5612 hdd_err("Adapter not foud for MAC " QDF_MAC_ADDR_FMT "", 5613 QDF_MAC_ADDR_REF(mac_addr->bytes)); 5614 return NULL; 5615 } 5616 5617 return adapter->dev; 5618 } 5619 #endif 5620 5621 #ifdef WLAN_FEATURE_DYNAMIC_MAC_ADDR_UPDATE 5622 #if defined(WLAN_FEATURE_11BE_MLO) && defined(CFG80211_11BE_BASIC) && \ 5623 !defined(WLAN_HDD_MULTI_VDEV_SINGLE_NDEV) 5624 static void hdd_update_set_mac_addr_req_ctx(struct hdd_adapter *adapter, 5625 void *req_ctx) 5626 { 5627 adapter->set_mac_addr_req_ctx = req_ctx; 5628 if (adapter->mlo_adapter_info.associate_with_ml_adapter) 5629 adapter->mlo_adapter_info.ml_adapter->set_mac_addr_req_ctx = 5630 req_ctx; 5631 } 5632 #else 5633 static void hdd_update_set_mac_addr_req_ctx(struct hdd_adapter *adapter, 5634 void *req_ctx) 5635 { 5636 adapter->set_mac_addr_req_ctx = req_ctx; 5637 } 5638 #endif 5639 5640 /** 5641 * hdd_is_dynamic_set_mac_addr_supported() - API to check dynamic MAC address 5642 * update is supported or not 5643 * @hdd_ctx: Pointer to the HDD context 5644 * 5645 * Return: true or false 5646 */ 5647 static inline bool 5648 hdd_is_dynamic_set_mac_addr_supported(struct hdd_context *hdd_ctx) 5649 { 5650 return hdd_ctx->is_vdev_macaddr_dynamic_update_supported; 5651 } 5652 5653 bool hdd_is_dynamic_set_mac_addr_allowed(struct hdd_adapter *adapter) 5654 { 5655 if (!adapter->deflink->vdev) { 5656 hdd_err("VDEV is NULL"); 5657 return false; 5658 } 5659 5660 if (!hdd_is_dynamic_set_mac_addr_supported(adapter->hdd_ctx)) { 5661 hdd_info_rl("On iface up, set mac address change isn't supported"); 5662 return false; 5663 } 5664 5665 switch (adapter->device_mode) { 5666 case QDF_STA_MODE: 5667 if (!cm_is_vdev_disconnected(adapter->deflink->vdev)) { 5668 hdd_info_rl("VDEV is not in disconnected state, set mac address isn't supported"); 5669 return false; 5670 } 5671 return true; 5672 case QDF_SAP_MODE: 5673 if (test_bit(SOFTAP_BSS_STARTED, 5674 &adapter->deflink->link_flags)) { 5675 hdd_info_rl("SAP is in up state, set mac address isn't supported"); 5676 return false; 5677 } else { 5678 return true; 5679 } 5680 default: 5681 hdd_info_rl("Dynamic set mac address isn't supported for opmode:%d", 5682 adapter->device_mode); 5683 return false; 5684 } 5685 } 5686 5687 int hdd_dynamic_mac_address_set(struct wlan_hdd_link_info *link_info, 5688 struct qdf_mac_addr mac_addr, 5689 struct qdf_mac_addr mld_addr, 5690 bool update_self_peer) 5691 { 5692 int ret; 5693 void *cookie; 5694 bool update_mld_addr; 5695 uint32_t *fw_resp_status; 5696 QDF_STATUS status; 5697 struct osif_request *request; 5698 struct wlan_objmgr_vdev *vdev; 5699 struct hdd_adapter *adapter = link_info->adapter; 5700 struct hdd_context *hdd_ctx = adapter->hdd_ctx; 5701 static const struct osif_request_params params = { 5702 .priv_size = sizeof(*fw_resp_status), 5703 .timeout_ms = WLAN_SET_MAC_ADDR_TIMEOUT 5704 }; 5705 5706 vdev = hdd_objmgr_get_vdev_by_user(link_info, WLAN_OSIF_ID); 5707 if (!vdev) 5708 return -EINVAL; 5709 5710 status = ucfg_vdev_mgr_cdp_vdev_detach(vdev); 5711 if (QDF_IS_STATUS_ERROR(status)) { 5712 hdd_err("Failed to detach CDP vdev. Status:%d", status); 5713 ret = qdf_status_to_os_return(status); 5714 goto vdev_ref; 5715 } 5716 5717 request = osif_request_alloc(¶ms); 5718 if (!request) { 5719 ret = -ENOMEM; 5720 goto status_ret; 5721 } 5722 5723 /* Host should hold a wake lock until the FW event response is received 5724 * the WMI event would not be a wake up event. 5725 */ 5726 qdf_runtime_pm_prevent_suspend( 5727 &hdd_ctx->runtime_context.dyn_mac_addr_update); 5728 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_DYN_MAC_ADDR_UPDATE); 5729 5730 cookie = osif_request_cookie(request); 5731 hdd_update_set_mac_addr_req_ctx(adapter, cookie); 5732 5733 status = sme_send_set_mac_addr(mac_addr, mld_addr, vdev); 5734 ret = qdf_status_to_os_return(status); 5735 if (QDF_IS_STATUS_ERROR(status)) { 5736 hdd_nofl_err("Failed to send set MAC address command. Status:%d", 5737 status); 5738 osif_request_put(request); 5739 goto status_ret; 5740 } else { 5741 ret = osif_request_wait_for_response(request); 5742 if (ret) { 5743 hdd_err("Set MAC address response timed out"); 5744 } else { 5745 fw_resp_status = (uint32_t *)osif_request_priv(request); 5746 if (*fw_resp_status) { 5747 hdd_err("Set MAC address failed in FW. Status: %d", 5748 *fw_resp_status); 5749 ret = -EAGAIN; 5750 } 5751 } 5752 } 5753 5754 osif_request_put(request); 5755 5756 if (qdf_is_macaddr_zero(&mld_addr)) 5757 update_mld_addr = false; 5758 else 5759 update_mld_addr = true; 5760 5761 status = sme_update_vdev_mac_addr(vdev, mac_addr, mld_addr, 5762 update_self_peer, update_mld_addr, 5763 ret); 5764 5765 if (QDF_IS_STATUS_ERROR(status)) 5766 ret = qdf_status_to_os_return(status); 5767 5768 status_ret: 5769 status = ucfg_vdev_mgr_cdp_vdev_attach(vdev); 5770 if (QDF_IS_STATUS_ERROR(status)) { 5771 hdd_err("Failed to attach CDP vdev. status:%d", status); 5772 ret = qdf_status_to_os_return(status); 5773 goto allow_suspend; 5774 } else if (!ret) { 5775 status = ucfg_dp_update_link_mac_addr(vdev, &mac_addr, false); 5776 if (QDF_IS_STATUS_ERROR(status)) { 5777 ret = qdf_status_to_os_return(status); 5778 hdd_err("DP link MAC update failed"); 5779 goto allow_suspend; 5780 } 5781 } 5782 sme_vdev_set_data_tx_callback(vdev); 5783 5784 /* Update FW WoW pattern with new MAC address */ 5785 ucfg_pmo_del_wow_pattern(vdev); 5786 ucfg_pmo_register_wow_default_patterns(vdev); 5787 5788 allow_suspend: 5789 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DYN_MAC_ADDR_UPDATE); 5790 qdf_runtime_pm_allow_suspend( 5791 &hdd_ctx->runtime_context.dyn_mac_addr_update); 5792 5793 vdev_ref: 5794 hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_ID); 5795 5796 return ret; 5797 } 5798 5799 static void hdd_set_mac_addr_event_cb(uint8_t vdev_id, uint8_t status) 5800 { 5801 struct hdd_context *hdd_ctx; 5802 struct wlan_hdd_link_info *link_info; 5803 struct osif_request *req; 5804 uint32_t *fw_response_status; 5805 5806 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 5807 if (!hdd_ctx) { 5808 hdd_err("Invalid HDD context"); 5809 return; 5810 } 5811 5812 link_info = hdd_get_link_info_by_vdev(hdd_ctx, vdev_id); 5813 if (!link_info) { 5814 hdd_err("No adapter found for VDEV ID:%d", vdev_id); 5815 return; 5816 } 5817 5818 req = osif_request_get(link_info->adapter->set_mac_addr_req_ctx); 5819 if (!req) { 5820 osif_err("Obsolete request for VDEV ID:%d", vdev_id); 5821 return; 5822 } 5823 5824 fw_response_status = (uint32_t *)osif_request_priv(req); 5825 *fw_response_status = status; 5826 5827 osif_request_complete(req); 5828 osif_request_put(req); 5829 } 5830 #else 5831 static inline bool 5832 hdd_is_dynamic_set_mac_addr_supported(struct hdd_context *hdd_ctx) 5833 { 5834 return false; 5835 } 5836 #endif 5837 5838 #if defined(WLAN_FEATURE_11BE_MLO) && defined(WLAN_HDD_MULTI_VDEV_SINGLE_NDEV) 5839 static QDF_STATUS 5840 hdd_adapter_update_links_on_link_switch(struct wlan_hdd_link_info *cur_link_info, 5841 struct wlan_hdd_link_info *new_link_info) 5842 { 5843 unsigned long link_flags; 5844 struct wlan_objmgr_vdev *vdev; 5845 int cur_link_idx, new_link_idx; 5846 uint8_t cur_old_pos, cur_new_pos; 5847 struct vdev_osif_priv *vdev_priv; 5848 struct hdd_adapter *adapter = cur_link_info->adapter; 5849 5850 /* Update the new position of current and new link info 5851 * in the link info array. 5852 */ 5853 cur_link_idx = hdd_adapter_get_index_of_link_info(cur_link_info); 5854 new_link_idx = hdd_adapter_get_index_of_link_info(new_link_info); 5855 5856 cur_old_pos = adapter->curr_link_info_map[cur_link_idx]; 5857 cur_new_pos = adapter->curr_link_info_map[new_link_idx]; 5858 5859 adapter->curr_link_info_map[new_link_idx] = cur_old_pos; 5860 adapter->curr_link_info_map[cur_link_idx] = cur_new_pos; 5861 5862 /* Move VDEV from current link info to new link info */ 5863 qdf_atomic_clear_bit(cur_link_idx, &adapter->active_links); 5864 qdf_spin_lock_bh(&cur_link_info->vdev_lock); 5865 vdev = cur_link_info->vdev; 5866 cur_link_info->vdev = NULL; 5867 cur_link_info->vdev_id = WLAN_INVALID_VDEV_ID; 5868 qdf_spin_unlock_bh(&cur_link_info->vdev_lock); 5869 5870 qdf_spin_lock_bh(&new_link_info->vdev_lock); 5871 new_link_info->vdev = vdev; 5872 new_link_info->vdev_id = wlan_vdev_get_id(vdev); 5873 qdf_spin_unlock_bh(&new_link_info->vdev_lock); 5874 qdf_atomic_set_bit(new_link_idx, &adapter->active_links); 5875 5876 /* Move the link flags between current and new link info */ 5877 link_flags = new_link_info->link_flags; 5878 new_link_info->link_flags = cur_link_info->link_flags; 5879 cur_link_info->link_flags = link_flags; 5880 5881 /* Update VDEV-OSIF priv pointer to new link info */ 5882 vdev_priv = wlan_vdev_get_ospriv(new_link_info->vdev); 5883 vdev_priv->legacy_osif_priv = new_link_info; 5884 5885 return QDF_STATUS_SUCCESS; 5886 } 5887 5888 struct wlan_hdd_link_info * 5889 hdd_get_link_info_by_ieee_link_id(struct hdd_adapter *adapter, int32_t link_id) 5890 { 5891 struct wlan_hdd_link_info *link_info; 5892 struct hdd_station_ctx *sta_ctx; 5893 5894 if (!adapter || link_id == WLAN_INVALID_LINK_ID) { 5895 hdd_err("NULL adapter or invalid link ID"); 5896 return NULL; 5897 } 5898 5899 hdd_adapter_for_each_link_info(adapter, link_info) { 5900 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(link_info); 5901 if (sta_ctx->conn_info.ieee_link_id == link_id) 5902 return link_info; 5903 } 5904 5905 return NULL; 5906 } 5907 5908 QDF_STATUS 5909 hdd_link_switch_vdev_mac_addr_update(int32_t ieee_old_link_id, 5910 int32_t ieee_new_link_id, uint8_t vdev_id) 5911 { 5912 QDF_STATUS status = QDF_STATUS_E_INVAL; 5913 struct hdd_context *hdd_ctx; 5914 struct hdd_adapter *adapter; 5915 struct wlan_objmgr_vdev *vdev; 5916 struct wlan_hdd_link_info *cur_link_info, *new_link_info; 5917 struct hdd_station_ctx *sta_ctx; 5918 5919 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 5920 if (!hdd_ctx) { 5921 hdd_err("HDD ctx NULL"); 5922 return QDF_STATUS_E_INVAL; 5923 } 5924 5925 cur_link_info = hdd_get_link_info_by_vdev(hdd_ctx, vdev_id); 5926 if (!cur_link_info) { 5927 hdd_err("VDEV %d not found", vdev_id); 5928 return status; 5929 } 5930 5931 vdev = hdd_objmgr_get_vdev_by_user(cur_link_info, WLAN_OSIF_ID); 5932 if (!vdev) { 5933 hdd_err("Invalid VDEV %d", vdev_id); 5934 return status; 5935 } 5936 5937 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(cur_link_info); 5938 if (sta_ctx->conn_info.ieee_link_id != ieee_old_link_id) { 5939 hdd_err("Link id %d mismatch", sta_ctx->conn_info.ieee_link_id); 5940 goto release_ref; 5941 } 5942 5943 adapter = cur_link_info->adapter; 5944 new_link_info = hdd_get_link_info_by_ieee_link_id(adapter, 5945 ieee_new_link_id); 5946 if (!new_link_info) { 5947 hdd_err("Link id %d not found", ieee_new_link_id); 5948 goto release_ref; 5949 } 5950 5951 status = ucfg_dp_update_link_mac_addr(vdev, &new_link_info->link_addr, 5952 true); 5953 if (QDF_IS_STATUS_ERROR(status)) { 5954 hdd_err("DP link MAC update failed"); 5955 goto release_ref; 5956 } 5957 5958 status = hdd_adapter_update_links_on_link_switch(cur_link_info, 5959 new_link_info); 5960 if (QDF_IS_STATUS_ERROR(status)) { 5961 hdd_err("Failed to update adapter link info"); 5962 goto release_ref; 5963 } 5964 5965 hdd_adapter_update_mlo_mgr_mac_addr(adapter); 5966 sme_vdev_set_data_tx_callback(vdev); 5967 ucfg_pmo_del_wow_pattern(vdev); 5968 ucfg_pmo_register_wow_default_patterns(vdev); 5969 5970 release_ref: 5971 hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_ID); 5972 return status; 5973 } 5974 #endif 5975 5976 /** 5977 * __hdd_set_mac_address() - set the user specified mac address 5978 * @dev: Pointer to the net device. 5979 * @addr: Pointer to the sockaddr. 5980 * 5981 * This function sets the user specified mac address using 5982 * the command ifconfig wlanX hw ether <mac address>. 5983 * 5984 * Return: 0 for success, non zero for failure 5985 */ 5986 static int __hdd_set_mac_address(struct net_device *dev, void *addr) 5987 { 5988 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev); 5989 struct hdd_adapter *adapter_temp; 5990 struct hdd_context *hdd_ctx; 5991 struct sockaddr *psta_mac_addr = addr; 5992 QDF_STATUS qdf_ret_status = QDF_STATUS_SUCCESS; 5993 int ret; 5994 struct qdf_mac_addr mac_addr; 5995 bool net_if_running = netif_running(dev); 5996 5997 hdd_enter_dev(dev); 5998 5999 hdd_ctx = WLAN_HDD_GET_CTX(adapter); 6000 ret = wlan_hdd_validate_context(hdd_ctx); 6001 if (0 != ret) 6002 return ret; 6003 6004 if (net_if_running) { 6005 if (!hdd_is_dynamic_set_mac_addr_allowed(adapter)) 6006 return -ENOTSUPP; 6007 } 6008 6009 qdf_mem_copy(&mac_addr, psta_mac_addr->sa_data, sizeof(mac_addr)); 6010 adapter_temp = hdd_get_adapter_by_macaddr(hdd_ctx, mac_addr.bytes); 6011 if (adapter_temp) { 6012 if (!qdf_str_cmp(adapter_temp->dev->name, dev->name)) 6013 return 0; 6014 hdd_err("%s adapter exist with same address " QDF_MAC_ADDR_FMT, 6015 adapter_temp->dev->name, 6016 QDF_MAC_ADDR_REF(mac_addr.bytes)); 6017 return -EINVAL; 6018 } 6019 qdf_ret_status = wlan_hdd_validate_mac_address(&mac_addr); 6020 if (QDF_IS_STATUS_ERROR(qdf_ret_status)) 6021 return -EINVAL; 6022 6023 hdd_nofl_debug("Changing MAC to " 6024 QDF_MAC_ADDR_FMT " of the interface %s ", 6025 QDF_MAC_ADDR_REF(mac_addr.bytes), dev->name); 6026 6027 if (net_if_running && adapter->deflink->vdev) { 6028 ret = hdd_update_vdev_mac_address(adapter, mac_addr); 6029 if (ret) 6030 return ret; 6031 } 6032 6033 hdd_set_mld_address(adapter, &mac_addr); 6034 6035 hdd_update_dynamic_mac(hdd_ctx, &adapter->mac_addr, &mac_addr); 6036 ucfg_dp_update_intf_mac(hdd_ctx->psoc, &adapter->mac_addr, &mac_addr, 6037 adapter->deflink->vdev); 6038 memcpy(&adapter->mac_addr, psta_mac_addr->sa_data, ETH_ALEN); 6039 qdf_net_update_net_device_dev_addr(dev, psta_mac_addr->sa_data, 6040 ETH_ALEN); 6041 6042 hdd_exit(); 6043 return ret; 6044 } 6045 6046 /** 6047 * hdd_set_mac_address() - Wrapper function to protect __hdd_set_mac_address() 6048 * function from SSR 6049 * @net_dev: pointer to net_device structure 6050 * @addr: Pointer to the sockaddr 6051 * 6052 * This function sets the user specified mac address using 6053 * the command ifconfig wlanX hw ether <mac address>. 6054 * 6055 * Return: 0 for success. 6056 */ 6057 static int hdd_set_mac_address(struct net_device *net_dev, void *addr) 6058 { 6059 struct osif_vdev_sync *vdev_sync; 6060 int errno; 6061 6062 errno = osif_vdev_sync_op_start(net_dev, &vdev_sync); 6063 if (errno) 6064 return errno; 6065 6066 errno = __hdd_set_mac_address(net_dev, addr); 6067 6068 osif_vdev_sync_op_stop(vdev_sync); 6069 6070 return errno; 6071 } 6072 6073 static uint8_t *wlan_hdd_get_derived_intf_addr(struct hdd_context *hdd_ctx) 6074 { 6075 int i, j; 6076 6077 i = qdf_ffz(hdd_ctx->derived_intf_addr_mask); 6078 if (i < 0 || i >= hdd_ctx->num_derived_addr) 6079 return NULL; 6080 qdf_atomic_set_bit(i, &hdd_ctx->derived_intf_addr_mask); 6081 hdd_nofl_debug("Assigning MAC from derived list "QDF_MAC_ADDR_FMT, 6082 QDF_MAC_ADDR_REF(hdd_ctx->derived_mac_addr[i].bytes)); 6083 6084 /* Copy the mac in dynamic mac list at first free position */ 6085 for (j = 0; j < QDF_MAX_CONCURRENCY_PERSONA; j++) { 6086 if (qdf_is_macaddr_zero(&hdd_ctx-> 6087 dynamic_mac_list[j].dynamic_mac)) 6088 break; 6089 } 6090 if (j == QDF_MAX_CONCURRENCY_PERSONA) { 6091 hdd_err("Max interfaces are up"); 6092 return NULL; 6093 } 6094 6095 qdf_mem_copy(&hdd_ctx->dynamic_mac_list[j].dynamic_mac.bytes, 6096 &hdd_ctx->derived_mac_addr[i].bytes, 6097 sizeof(struct qdf_mac_addr)); 6098 hdd_ctx->dynamic_mac_list[j].is_provisioned_mac = false; 6099 hdd_ctx->dynamic_mac_list[j].bit_position = i; 6100 6101 return hdd_ctx->derived_mac_addr[i].bytes; 6102 } 6103 6104 static uint8_t *wlan_hdd_get_provisioned_intf_addr(struct hdd_context *hdd_ctx) 6105 { 6106 int i, j; 6107 6108 i = qdf_ffz(hdd_ctx->provisioned_intf_addr_mask); 6109 if (i < 0 || i >= hdd_ctx->num_provisioned_addr) 6110 return NULL; 6111 qdf_atomic_set_bit(i, &hdd_ctx->provisioned_intf_addr_mask); 6112 hdd_debug("Assigning MAC from provisioned list "QDF_MAC_ADDR_FMT, 6113 QDF_MAC_ADDR_REF(hdd_ctx->provisioned_mac_addr[i].bytes)); 6114 6115 /* Copy the mac in dynamic mac list at first free position */ 6116 for (j = 0; j < QDF_MAX_CONCURRENCY_PERSONA; j++) { 6117 if (qdf_is_macaddr_zero(&hdd_ctx-> 6118 dynamic_mac_list[j].dynamic_mac)) 6119 break; 6120 } 6121 if (j == QDF_MAX_CONCURRENCY_PERSONA) { 6122 hdd_err("Max interfaces are up"); 6123 return NULL; 6124 } 6125 6126 qdf_mem_copy(&hdd_ctx->dynamic_mac_list[j].dynamic_mac.bytes, 6127 &hdd_ctx->provisioned_mac_addr[i].bytes, 6128 sizeof(struct qdf_mac_addr)); 6129 hdd_ctx->dynamic_mac_list[j].is_provisioned_mac = true; 6130 hdd_ctx->dynamic_mac_list[j].bit_position = i; 6131 return hdd_ctx->provisioned_mac_addr[i].bytes; 6132 } 6133 6134 uint8_t *wlan_hdd_get_intf_addr(struct hdd_context *hdd_ctx, 6135 enum QDF_OPMODE interface_type) 6136 { 6137 uint8_t *mac_addr = NULL; 6138 6139 if (qdf_atomic_test_bit(interface_type, 6140 (unsigned long *) 6141 (&hdd_ctx->config->provisioned_intf_pool))) 6142 mac_addr = wlan_hdd_get_provisioned_intf_addr(hdd_ctx); 6143 6144 if ((!mac_addr) && 6145 (qdf_atomic_test_bit(interface_type, 6146 (unsigned long *) 6147 (&hdd_ctx->config->derived_intf_pool)))) 6148 mac_addr = wlan_hdd_get_derived_intf_addr(hdd_ctx); 6149 6150 if (!mac_addr) 6151 hdd_err("MAC is not available in both the lists"); 6152 return mac_addr; 6153 } 6154 6155 void wlan_hdd_release_intf_addr(struct hdd_context *hdd_ctx, 6156 uint8_t *releaseAddr) 6157 { 6158 int i; 6159 int mac_pos_in_mask; 6160 6161 for (i = 0; i < QDF_MAX_CONCURRENCY_PERSONA; i++) { 6162 if (!memcmp(releaseAddr, 6163 hdd_ctx->dynamic_mac_list[i].dynamic_mac.bytes, 6164 QDF_MAC_ADDR_SIZE)) { 6165 mac_pos_in_mask = 6166 hdd_ctx->dynamic_mac_list[i].bit_position; 6167 if (hdd_ctx->dynamic_mac_list[i].is_provisioned_mac) { 6168 qdf_atomic_clear_bit( 6169 mac_pos_in_mask, 6170 &hdd_ctx-> 6171 provisioned_intf_addr_mask); 6172 hdd_debug("Releasing MAC from provisioned list"); 6173 hdd_debug( 6174 QDF_MAC_ADDR_FMT, 6175 QDF_MAC_ADDR_REF(releaseAddr)); 6176 } else { 6177 qdf_atomic_clear_bit( 6178 mac_pos_in_mask, &hdd_ctx-> 6179 derived_intf_addr_mask); 6180 hdd_debug("Releasing MAC from derived list"); 6181 hdd_debug(QDF_MAC_ADDR_FMT, 6182 QDF_MAC_ADDR_REF(releaseAddr)); 6183 } 6184 qdf_zero_macaddr(&hdd_ctx-> 6185 dynamic_mac_list[i].dynamic_mac); 6186 hdd_ctx->dynamic_mac_list[i].is_provisioned_mac = 6187 false; 6188 hdd_ctx->dynamic_mac_list[i].bit_position = 0; 6189 break; 6190 } 6191 6192 } 6193 if (i == QDF_MAX_CONCURRENCY_PERSONA) 6194 hdd_debug("Releasing non existing MAC " QDF_MAC_ADDR_FMT, 6195 QDF_MAC_ADDR_REF(releaseAddr)); 6196 } 6197 6198 /** 6199 * hdd_set_derived_multicast_list(): Add derived peer multicast address list in 6200 * multicast list request to the FW 6201 * @psoc: Pointer to psoc 6202 * @adapter: Pointer to hdd adapter 6203 * @mc_list_request: Multicast list request to the FW 6204 * @mc_count: number of multicast addresses received from the kernel 6205 * 6206 * Return: None 6207 */ 6208 static void 6209 hdd_set_derived_multicast_list(struct wlan_objmgr_psoc *psoc, 6210 struct hdd_adapter *adapter, 6211 struct pmo_mc_addr_list_params *mc_list_request, 6212 int *mc_count) 6213 { 6214 int i = 0, j = 0, list_count = *mc_count; 6215 struct qdf_mac_addr *peer_mc_addr_list = NULL; 6216 uint8_t driver_mc_cnt = 0; 6217 uint32_t max_ndp_sessions = 0; 6218 6219 cfg_nan_get_ndp_max_sessions(psoc, &max_ndp_sessions); 6220 6221 ucfg_nan_get_peer_mc_list(adapter->deflink->vdev, &peer_mc_addr_list); 6222 6223 for (j = 0; j < max_ndp_sessions; j++) { 6224 for (i = 0; i < list_count; i++) { 6225 if (qdf_is_macaddr_zero(&peer_mc_addr_list[j]) || 6226 qdf_is_macaddr_equal(&mc_list_request->mc_addr[i], 6227 &peer_mc_addr_list[j])) 6228 break; 6229 } 6230 if (i == list_count) { 6231 qdf_mem_copy( 6232 &(mc_list_request->mc_addr[list_count + 6233 driver_mc_cnt].bytes), 6234 peer_mc_addr_list[j].bytes, ETH_ALEN); 6235 hdd_debug("mlist[%d] = " QDF_MAC_ADDR_FMT, 6236 list_count + driver_mc_cnt, 6237 QDF_MAC_ADDR_REF( 6238 mc_list_request->mc_addr[list_count + 6239 driver_mc_cnt].bytes)); 6240 driver_mc_cnt++; 6241 } 6242 } 6243 *mc_count += driver_mc_cnt; 6244 } 6245 6246 /** 6247 * __hdd_set_multicast_list() - set the multicast address list 6248 * @dev: Pointer to the WLAN device. 6249 * 6250 * This function sets the multicast address list. 6251 * 6252 * Return: None 6253 */ 6254 static void __hdd_set_multicast_list(struct net_device *dev) 6255 { 6256 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev); 6257 int i = 0, errno; 6258 struct netdev_hw_addr *ha; 6259 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); 6260 struct pmo_mc_addr_list_params *mc_list_request = NULL; 6261 struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc; 6262 int mc_count = 0; 6263 6264 if (hdd_ctx->hdd_wlan_suspended) { 6265 hdd_err_rl("Device is system suspended"); 6266 return; 6267 } 6268 6269 hdd_enter_dev(dev); 6270 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) 6271 return; 6272 6273 errno = wlan_hdd_validate_context(hdd_ctx); 6274 if (errno) 6275 return; 6276 6277 errno = hdd_validate_adapter(adapter); 6278 if (errno) 6279 return; 6280 6281 if (hdd_ctx->driver_status == DRIVER_MODULES_CLOSED) { 6282 hdd_debug("Driver module is closed"); 6283 return; 6284 } 6285 6286 mc_list_request = qdf_mem_malloc(sizeof(*mc_list_request)); 6287 if (!mc_list_request) 6288 return; 6289 6290 qdf_spin_lock_bh(&adapter->mc_list_lock); 6291 /* Delete already configured multicast address list */ 6292 if (adapter->mc_addr_list.mc_cnt > 0) 6293 hdd_disable_and_flush_mc_addr_list(adapter, 6294 pmo_mc_list_change_notify); 6295 6296 if (dev->flags & IFF_ALLMULTI) { 6297 hdd_debug("allow all multicast frames"); 6298 hdd_disable_and_flush_mc_addr_list(adapter, 6299 pmo_mc_list_change_notify); 6300 } else { 6301 mc_count = netdev_mc_count(dev); 6302 if (mc_count > ucfg_pmo_max_mc_addr_supported(psoc)) { 6303 hdd_debug("Exceeded max MC filter addresses (%d). Allowing all MC frames by disabling MC address filtering", 6304 ucfg_pmo_max_mc_addr_supported(psoc)); 6305 hdd_disable_and_flush_mc_addr_list(adapter, 6306 pmo_mc_list_change_notify); 6307 adapter->mc_addr_list.mc_cnt = 0; 6308 goto free_req; 6309 } 6310 netdev_for_each_mc_addr(ha, dev) { 6311 if (i == mc_count) 6312 break; 6313 memset(&(mc_list_request->mc_addr[i].bytes), 6314 0, ETH_ALEN); 6315 memcpy(&(mc_list_request->mc_addr[i].bytes), 6316 ha->addr, ETH_ALEN); 6317 hdd_debug("mlist[%d] = "QDF_MAC_ADDR_FMT, i, 6318 QDF_MAC_ADDR_REF(mc_list_request->mc_addr[i].bytes)); 6319 i++; 6320 } 6321 6322 if (adapter->device_mode == QDF_NDI_MODE) 6323 hdd_set_derived_multicast_list(psoc, adapter, 6324 mc_list_request, 6325 &mc_count); 6326 } 6327 6328 adapter->mc_addr_list.mc_cnt = mc_count; 6329 mc_list_request->psoc = psoc; 6330 mc_list_request->vdev_id = adapter->deflink->vdev_id; 6331 mc_list_request->count = mc_count; 6332 6333 errno = hdd_cache_mc_addr_list(mc_list_request); 6334 if (errno) { 6335 hdd_debug("Failed to cache MC address list for vdev %u; errno:%d", 6336 adapter->deflink->vdev_id, errno); 6337 goto free_req; 6338 } 6339 6340 hdd_enable_mc_addr_filtering(adapter, pmo_mc_list_change_notify); 6341 6342 free_req: 6343 qdf_spin_unlock_bh(&adapter->mc_list_lock); 6344 qdf_mem_free(mc_list_request); 6345 } 6346 6347 /** 6348 * hdd_set_multicast_list() - SSR wrapper function for __hdd_set_multicast_list 6349 * @net_dev: pointer to net_device 6350 * 6351 * Return: none 6352 */ 6353 static void hdd_set_multicast_list(struct net_device *net_dev) 6354 { 6355 struct osif_vdev_sync *vdev_sync; 6356 6357 if (osif_vdev_sync_op_start(net_dev, &vdev_sync)) 6358 return; 6359 6360 __hdd_set_multicast_list(net_dev); 6361 6362 osif_vdev_sync_op_stop(vdev_sync); 6363 } 6364 6365 void hdd_update_multicast_list(struct wlan_objmgr_vdev *vdev) 6366 { 6367 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 6368 struct wlan_hdd_link_info *link_info; 6369 struct hdd_adapter *adapter; 6370 uint8_t vdev_id = wlan_vdev_get_id(vdev); 6371 struct net_device *net_dev; 6372 6373 if (!hdd_ctx) { 6374 hdd_err("hdd_ctx is null"); 6375 return; 6376 } 6377 6378 link_info = hdd_get_link_info_by_vdev(hdd_ctx, vdev_id); 6379 if (!link_info) { 6380 hdd_err("adapter is null for vdev_id %d", vdev_id); 6381 return; 6382 } 6383 6384 adapter = link_info->adapter; 6385 if (!adapter) { 6386 hdd_err("adapter is null for vdev_id %d", vdev_id); 6387 return; 6388 } 6389 6390 net_dev = adapter->dev; 6391 if (!net_dev) { 6392 hdd_err("netdev is null"); 6393 return; 6394 } 6395 6396 __hdd_set_multicast_list(net_dev); 6397 } 6398 6399 #ifdef WLAN_FEATURE_TSF_PTP 6400 static const struct ethtool_ops wlan_ethtool_ops = { 6401 .get_ts_info = wlan_get_ts_info, 6402 }; 6403 #endif 6404 6405 /** 6406 * __hdd_fix_features - Adjust the feature flags needed to be updated 6407 * @net_dev: Handle to net_device 6408 * @features: Currently enabled feature flags 6409 * 6410 * Return: Adjusted feature flags on success, old feature on failure 6411 */ 6412 static netdev_features_t __hdd_fix_features(struct net_device *net_dev, 6413 netdev_features_t features) 6414 { 6415 netdev_features_t feature_change_req = features; 6416 netdev_features_t feature_tso_csum; 6417 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(net_dev); 6418 6419 if (!adapter->handle_feature_update) { 6420 hdd_debug("Not triggered by hdd_netdev_update_features"); 6421 return features; 6422 } 6423 6424 feature_tso_csum = hdd_get_tso_csum_feature_flags(); 6425 if (hdd_is_legacy_connection(adapter->deflink)) { 6426 /* Disable checksum and TSO */ 6427 feature_change_req &= ~feature_tso_csum; 6428 adapter->tso_csum_feature_enabled = 0; 6429 } else { 6430 /* Enable checksum and TSO */ 6431 feature_change_req |= feature_tso_csum; 6432 adapter->tso_csum_feature_enabled = 1; 6433 } 6434 hdd_debug("vdev mode %d current features 0x%llx, requesting feature change 0x%llx", 6435 adapter->device_mode, net_dev->features, 6436 feature_change_req); 6437 6438 return feature_change_req; 6439 } 6440 6441 /** 6442 * hdd_fix_features() - Wrapper for __hdd_fix_features to protect it from SSR 6443 * @net_dev: Pointer to net_device structure 6444 * @features: Updated features set 6445 * 6446 * Adjusts the feature request, do not update the device yet. 6447 * 6448 * Return: updated feature for success, incoming feature as is on failure 6449 */ 6450 static netdev_features_t hdd_fix_features(struct net_device *net_dev, 6451 netdev_features_t features) 6452 { 6453 int errno; 6454 int changed_features = features; 6455 struct osif_vdev_sync *vdev_sync; 6456 6457 errno = osif_vdev_sync_op_start(net_dev, &vdev_sync); 6458 if (errno) 6459 return features; 6460 6461 changed_features = __hdd_fix_features(net_dev, features); 6462 6463 osif_vdev_sync_op_stop(vdev_sync); 6464 6465 return changed_features; 6466 } 6467 /** 6468 * __hdd_set_features - Notify device about change in features 6469 * @net_dev: Handle to net_device 6470 * @features: Existing + requested feature after resolving the dependency 6471 * 6472 * Return: 0 on success, non zero error on failure 6473 */ 6474 static int __hdd_set_features(struct net_device *net_dev, 6475 netdev_features_t features) 6476 { 6477 struct hdd_adapter *adapter = netdev_priv(net_dev); 6478 ol_txrx_soc_handle soc = cds_get_context(QDF_MODULE_ID_SOC); 6479 6480 if (!adapter->handle_feature_update) { 6481 hdd_debug("Not triggered by hdd_netdev_update_features"); 6482 return 0; 6483 } 6484 6485 if (!soc) 6486 return 0; 6487 6488 hdd_debug("vdev mode %d vdev_id %d current features 0x%llx, changed features 0x%llx", 6489 adapter->device_mode, adapter->deflink->vdev_id, 6490 net_dev->features, features); 6491 6492 return 0; 6493 } 6494 6495 /** 6496 * hdd_set_features() - Wrapper for __hdd_set_features to protect it from SSR 6497 * @net_dev: Pointer to net_device structure 6498 * @features: Updated features set 6499 * 6500 * Is called to update device configurations for changed features. 6501 * 6502 * Return: 0 for success, non-zero for failure 6503 */ 6504 static int hdd_set_features(struct net_device *net_dev, 6505 netdev_features_t features) 6506 { 6507 int errno; 6508 struct osif_vdev_sync *vdev_sync; 6509 6510 errno = osif_vdev_sync_op_start(net_dev, &vdev_sync); 6511 if (errno) { 6512 /* 6513 * Only invoke from netdev_feature_update_work expected, 6514 * which is from CLD inside. 6515 * Ignore others from upper stack during loading phase, 6516 * and return success to avoid failure print from kernel. 6517 */ 6518 hdd_debug("VDEV in transition, ignore set_features"); 6519 return 0; 6520 } 6521 6522 errno = __hdd_set_features(net_dev, features); 6523 6524 osif_vdev_sync_op_stop(vdev_sync); 6525 6526 return errno; 6527 } 6528 6529 #define HDD_NETDEV_FEATURES_UPDATE_MAX_WAIT_COUNT 10 6530 #define HDD_NETDEV_FEATURES_UPDATE_WAIT_INTERVAL_MS 20 6531 6532 void hdd_netdev_update_features(struct hdd_adapter *adapter) 6533 { 6534 struct net_device *net_dev = adapter->dev; 6535 ol_txrx_soc_handle soc = cds_get_context(QDF_MODULE_ID_SOC); 6536 bool request_feature_update = false; 6537 int wait_count = HDD_NETDEV_FEATURES_UPDATE_MAX_WAIT_COUNT; 6538 6539 if (!soc) 6540 return; 6541 6542 if (!cdp_cfg_get(soc, cfg_dp_disable_legacy_mode_csum_offload)) 6543 return; 6544 6545 switch (adapter->device_mode) { 6546 case QDF_STA_MODE: 6547 if (cdp_cfg_get(soc, cfg_dp_enable_ip_tcp_udp_checksum_offload)) 6548 request_feature_update = true; 6549 break; 6550 default: 6551 break; 6552 } 6553 6554 if (request_feature_update) { 6555 hdd_debug("Update net_dev features for device mode %d", 6556 adapter->device_mode); 6557 while (!adapter->delete_in_progress) { 6558 if (rtnl_trylock()) { 6559 adapter->handle_feature_update = true; 6560 netdev_update_features(net_dev); 6561 adapter->handle_feature_update = false; 6562 rtnl_unlock(); 6563 break; 6564 } 6565 6566 if (wait_count--) { 6567 qdf_sleep( 6568 HDD_NETDEV_FEATURES_UPDATE_WAIT_INTERVAL_MS); 6569 } else { 6570 /* 6571 * We have failed to updated the netdev 6572 * features for very long, so enable the queues 6573 * now. The impact of not being able to update 6574 * the netdev feature is lower TPUT when 6575 * switching from legacy to non-legacy mode. 6576 */ 6577 hdd_err("Failed to update netdev features for device mode %d", 6578 adapter->device_mode); 6579 break; 6580 } 6581 } 6582 } 6583 } 6584 6585 static const struct net_device_ops wlan_drv_ops = { 6586 .ndo_open = hdd_open, 6587 .ndo_stop = hdd_stop, 6588 .ndo_uninit = hdd_uninit, 6589 .ndo_start_xmit = hdd_hard_start_xmit, 6590 .ndo_fix_features = hdd_fix_features, 6591 .ndo_set_features = hdd_set_features, 6592 .ndo_tx_timeout = hdd_tx_timeout, 6593 .ndo_get_stats = hdd_get_stats, 6594 #if LINUX_VERSION_CODE < KERNEL_VERSION(5, 15, 0) 6595 .ndo_do_ioctl = hdd_ioctl, 6596 #endif 6597 .ndo_set_mac_address = hdd_set_mac_address, 6598 .ndo_select_queue = hdd_select_queue, 6599 .ndo_set_rx_mode = hdd_set_multicast_list, 6600 #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0) 6601 .ndo_siocdevprivate = hdd_dev_private_ioctl, 6602 #endif 6603 }; 6604 6605 #ifdef FEATURE_MONITOR_MODE_SUPPORT 6606 /* Monitor mode net_device_ops, does not Tx and most of operations. */ 6607 static const struct net_device_ops wlan_mon_drv_ops = { 6608 .ndo_open = hdd_mon_open, 6609 .ndo_stop = hdd_stop, 6610 .ndo_get_stats = hdd_get_stats, 6611 }; 6612 6613 /** 6614 * hdd_set_mon_ops() - update net_device ops for monitor mode 6615 * @dev: Handle to struct net_device to be updated. 6616 * Return: None 6617 */ 6618 static void hdd_set_mon_ops(struct net_device *dev) 6619 { 6620 dev->netdev_ops = &wlan_mon_drv_ops; 6621 } 6622 6623 #ifdef WLAN_FEATURE_TSF_PTP 6624 void hdd_set_station_ops(struct net_device *dev) 6625 { 6626 if (cds_get_conparam() == QDF_GLOBAL_MONITOR_MODE) { 6627 hdd_set_mon_ops(dev); 6628 } else { 6629 dev->netdev_ops = &wlan_drv_ops; 6630 dev->ethtool_ops = &wlan_ethtool_ops; 6631 } 6632 } 6633 #else 6634 void hdd_set_station_ops(struct net_device *dev) 6635 { 6636 if (cds_get_conparam() == QDF_GLOBAL_MONITOR_MODE) 6637 hdd_set_mon_ops(dev); 6638 else 6639 dev->netdev_ops = &wlan_drv_ops; 6640 } 6641 6642 #endif 6643 #else 6644 #ifdef WLAN_FEATURE_TSF_PTP 6645 void hdd_set_station_ops(struct net_device *dev) 6646 { 6647 dev->netdev_ops = &wlan_drv_ops; 6648 dev->ethtool_ops = &wlan_ethtool_ops; 6649 } 6650 #else 6651 void hdd_set_station_ops(struct net_device *dev) 6652 { 6653 dev->netdev_ops = &wlan_drv_ops; 6654 } 6655 #endif 6656 static void hdd_set_mon_ops(struct net_device *dev) 6657 { 6658 } 6659 #endif 6660 6661 #ifdef WLAN_FEATURE_PKT_CAPTURE 6662 /* Packet Capture mode net_device_ops, does not Tx and most of operations. */ 6663 static const struct net_device_ops wlan_pktcapture_drv_ops = { 6664 .ndo_open = hdd_pktcapture_open, 6665 .ndo_stop = hdd_stop, 6666 .ndo_get_stats = hdd_get_stats, 6667 }; 6668 6669 static void hdd_set_pktcapture_ops(struct net_device *dev) 6670 { 6671 dev->netdev_ops = &wlan_pktcapture_drv_ops; 6672 } 6673 #else 6674 static void hdd_set_pktcapture_ops(struct net_device *dev) 6675 { 6676 } 6677 #endif 6678 6679 #ifdef MULTI_CLIENT_LL_SUPPORT 6680 /** 6681 * hdd_set_multi_client_ll_support() - set multi client ll support flag in 6682 * allocated station hdd adapter 6683 * @adapter: pointer to hdd adapter 6684 * 6685 * Return: none 6686 */ 6687 static void hdd_set_multi_client_ll_support(struct hdd_adapter *adapter) 6688 { 6689 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); 6690 bool multi_client_ll_ini_support, multi_client_ll_caps; 6691 6692 ucfg_mlme_cfg_get_multi_client_ll_ini_support(hdd_ctx->psoc, 6693 &multi_client_ll_ini_support); 6694 multi_client_ll_caps = 6695 ucfg_mlme_get_wlm_multi_client_ll_caps(hdd_ctx->psoc); 6696 6697 hdd_debug("fw caps: %d, ini: %d", multi_client_ll_caps, 6698 multi_client_ll_ini_support); 6699 if (multi_client_ll_caps && multi_client_ll_ini_support) 6700 adapter->multi_client_ll_support = true; 6701 } 6702 #else 6703 static inline void 6704 hdd_set_multi_client_ll_support(struct hdd_adapter *adapter) 6705 { 6706 } 6707 #endif 6708 6709 /** 6710 * hdd_alloc_station_adapter() - allocate the station hdd adapter 6711 * @hdd_ctx: global hdd context 6712 * @mac_addr: mac address to assign to the interface 6713 * @name_assign_type: name assignment type 6714 * @name: User-visible name of the interface 6715 * @session_type: interface type to be created 6716 * 6717 * hdd adapter pointer would point to the netdev->priv space, this function 6718 * would retrieve the pointer, and setup the hdd adapter configuration. 6719 * 6720 * Return: the pointer to hdd adapter, otherwise NULL 6721 */ 6722 static struct hdd_adapter * 6723 hdd_alloc_station_adapter(struct hdd_context *hdd_ctx, tSirMacAddr mac_addr, 6724 unsigned char name_assign_type, const char *name, 6725 uint8_t session_type) 6726 { 6727 struct net_device *dev; 6728 struct hdd_adapter *adapter; 6729 QDF_STATUS qdf_status; 6730 uint8_t latency_level; 6731 6732 /* cfg80211 initialization and registration */ 6733 dev = alloc_netdev_mqs(sizeof(*adapter), name, 6734 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS) 6735 name_assign_type, 6736 #endif 6737 ((cds_get_conparam() == QDF_GLOBAL_MONITOR_MODE || 6738 wlan_hdd_is_session_type_monitor(session_type)) ? 6739 hdd_mon_mode_ether_setup : ether_setup), 6740 NUM_TX_QUEUES, NUM_RX_QUEUES); 6741 6742 if (!dev) { 6743 hdd_err("Failed to allocate new net_device '%s'", name); 6744 return NULL; 6745 } 6746 6747 adapter = netdev_priv(dev); 6748 6749 qdf_mem_zero(adapter, sizeof(*adapter)); 6750 adapter->dev = dev; 6751 adapter->deflink = &adapter->link_info[WLAN_HDD_DEFLINK_IDX]; 6752 adapter->hdd_ctx = hdd_ctx; 6753 adapter->magic = WLAN_HDD_ADAPTER_MAGIC; 6754 qdf_atomic_set_bit(WLAN_HDD_DEFLINK_IDX, &adapter->active_links); 6755 6756 qdf_status = hdd_monitor_mode_qdf_create_event(adapter, session_type); 6757 if (QDF_IS_STATUS_ERROR(qdf_status)) { 6758 hdd_err_rl("create monitor mode vdve up event failed"); 6759 goto free_net_dev; 6760 } 6761 6762 hdd_update_dynamic_tsf_sync(adapter); 6763 adapter->is_link_up_service_needed = false; 6764 adapter->send_mode_change = true; 6765 6766 /* Cache station count initialize to zero */ 6767 qdf_atomic_init(&adapter->cache_sta_count); 6768 6769 /* Init the net_device structure */ 6770 strlcpy(dev->name, name, IFNAMSIZ); 6771 6772 qdf_net_update_net_device_dev_addr(dev, mac_addr, sizeof(tSirMacAddr)); 6773 qdf_mem_copy(adapter->mac_addr.bytes, mac_addr, sizeof(tSirMacAddr)); 6774 dev->watchdog_timeo = HDD_TX_TIMEOUT; 6775 6776 if (wlan_hdd_is_session_type_monitor(session_type)) { 6777 if (ucfg_pkt_capture_get_mode(hdd_ctx->psoc) != 6778 PACKET_CAPTURE_MODE_DISABLE) 6779 hdd_set_pktcapture_ops(adapter->dev); 6780 if (ucfg_mlme_is_sta_mon_conc_supported(hdd_ctx->psoc) || 6781 ucfg_dp_is_local_pkt_capture_enabled(hdd_ctx->psoc)) 6782 hdd_set_mon_ops(adapter->dev); 6783 } else { 6784 hdd_set_station_ops(adapter->dev); 6785 } 6786 6787 hdd_dev_setup_destructor(dev); 6788 dev->ieee80211_ptr = &adapter->wdev; 6789 dev->tx_queue_len = HDD_NETDEV_TX_QUEUE_LEN; 6790 adapter->wdev.wiphy = hdd_ctx->wiphy; 6791 adapter->wdev.netdev = dev; 6792 qdf_status = ucfg_mlme_cfg_get_wlm_level(hdd_ctx->psoc, &latency_level); 6793 if (QDF_IS_STATUS_ERROR(qdf_status)) { 6794 hdd_debug("Can't get latency level"); 6795 latency_level = 6796 QCA_WLAN_VENDOR_ATTR_CONFIG_LATENCY_LEVEL_NORMAL; 6797 } 6798 adapter->latency_level = latency_level; 6799 hdd_set_multi_client_ll_support(adapter); 6800 6801 /* set dev's parent to underlying device */ 6802 SET_NETDEV_DEV(dev, hdd_ctx->parent_dev); 6803 spin_lock_init(&adapter->pause_map_lock); 6804 adapter->start_time = qdf_system_ticks(); 6805 adapter->last_time = adapter->start_time; 6806 6807 qdf_atomic_init(&adapter->is_ll_stats_req_pending); 6808 hdd_init_get_sta_in_ll_stats_config(adapter); 6809 6810 return adapter; 6811 6812 free_net_dev: 6813 free_netdev(adapter->dev); 6814 6815 return NULL; 6816 } 6817 6818 #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 12, 0) 6819 static int 6820 hdd_register_netdevice(struct hdd_adapter *adapter, struct net_device *dev, 6821 struct hdd_adapter_create_param *params) 6822 { 6823 int ret; 6824 6825 if (params->is_add_virtual_iface) 6826 ret = wlan_cfg80211_register_netdevice(dev); 6827 else 6828 ret = register_netdevice(dev); 6829 6830 return ret; 6831 } 6832 #else 6833 static int 6834 hdd_register_netdevice(struct hdd_adapter *adapter, struct net_device *dev, 6835 struct hdd_adapter_create_param *params) 6836 { 6837 return register_netdevice(dev); 6838 } 6839 #endif 6840 6841 static QDF_STATUS 6842 hdd_register_interface(struct hdd_adapter *adapter, bool rtnl_held, 6843 struct hdd_adapter_create_param *params) 6844 { 6845 struct net_device *dev = adapter->dev; 6846 int ret; 6847 6848 hdd_enter(); 6849 6850 if (rtnl_held) { 6851 if (strnchr(dev->name, IFNAMSIZ - 1, '%')) { 6852 6853 ret = dev_alloc_name(dev, dev->name); 6854 if (ret < 0) { 6855 hdd_err( 6856 "unable to get dev name: %s, err = 0x%x", 6857 dev->name, ret); 6858 return QDF_STATUS_E_FAILURE; 6859 } 6860 } 6861 hdd_debug("hdd_register_netdevice(%s) type:%d", dev->name, 6862 adapter->device_mode); 6863 ret = hdd_register_netdevice(adapter, dev, params); 6864 if (ret) { 6865 hdd_err("register_netdevice(%s) failed, err = 0x%x", 6866 dev->name, ret); 6867 return QDF_STATUS_E_FAILURE; 6868 } 6869 } else { 6870 hdd_debug("register_netdev(%s) type:%d", dev->name, 6871 adapter->device_mode); 6872 ret = register_netdev(dev); 6873 if (ret) { 6874 hdd_err("register_netdev(%s) failed, err = 0x%x", 6875 dev->name, ret); 6876 return QDF_STATUS_E_FAILURE; 6877 } 6878 } 6879 set_bit(NET_DEVICE_REGISTERED, &adapter->event_flags); 6880 6881 hdd_exit(); 6882 6883 return QDF_STATUS_SUCCESS; 6884 } 6885 6886 QDF_STATUS hdd_sme_close_session_callback(uint8_t vdev_id) 6887 { 6888 struct hdd_adapter *adapter; 6889 struct hdd_context *hdd_ctx; 6890 struct wlan_hdd_link_info *link_info; 6891 6892 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 6893 if (!hdd_ctx) 6894 return QDF_STATUS_E_FAILURE; 6895 6896 link_info = hdd_get_link_info_by_vdev(hdd_ctx, vdev_id); 6897 if (!link_info) { 6898 hdd_err("Invalid vdev %d", vdev_id); 6899 return QDF_STATUS_E_INVAL; 6900 } 6901 6902 adapter = link_info->adapter; 6903 if (WLAN_HDD_ADAPTER_MAGIC != adapter->magic) { 6904 hdd_err("Invalid magic"); 6905 return QDF_STATUS_NOT_INITIALIZED; 6906 } 6907 6908 clear_bit(SME_SESSION_OPENED, &link_info->link_flags); 6909 qdf_spin_lock_bh(&link_info->vdev_lock); 6910 link_info->vdev_id = WLAN_UMAC_VDEV_ID_MAX; 6911 qdf_spin_unlock_bh(&link_info->vdev_lock); 6912 6913 /* 6914 * We can be blocked while waiting for scheduled work to be 6915 * flushed, and the adapter structure can potentially be freed, in 6916 * which case the magic will have been reset. So make sure the 6917 * magic is still good, and hence the adapter structure is still 6918 * valid, before signaling completion 6919 */ 6920 if (WLAN_HDD_ADAPTER_MAGIC == adapter->magic) 6921 complete(&link_info->vdev_destroy_event); 6922 6923 return QDF_STATUS_SUCCESS; 6924 } 6925 6926 int hdd_vdev_ready(struct wlan_objmgr_vdev *vdev, 6927 struct qdf_mac_addr *bridgeaddr) 6928 { 6929 QDF_STATUS status; 6930 6931 status = pmo_vdev_ready(vdev, bridgeaddr); 6932 if (QDF_IS_STATUS_ERROR(status)) 6933 return qdf_status_to_os_return(status); 6934 6935 status = ucfg_reg_11d_vdev_created_update(vdev); 6936 if (QDF_IS_STATUS_ERROR(status)) 6937 return qdf_status_to_os_return(status); 6938 6939 if (wma_capability_enhanced_mcast_filter()) 6940 status = ucfg_pmo_enhanced_mc_filter_enable(vdev); 6941 else 6942 status = ucfg_pmo_enhanced_mc_filter_disable(vdev); 6943 6944 return qdf_status_to_os_return(status); 6945 } 6946 6947 /** 6948 * hdd_check_wait_for_hw_mode_completion - Check hw mode in progress 6949 * @hdd_ctx: hdd context 6950 * 6951 * Check and wait for hw mode response if any hw mode change is 6952 * in progress. Vdev delete will purge the serialization queue 6953 * for the vdev. It will cause issues when the fw event coming 6954 * up later and no active hw mode change req ser command in queue. 6955 * 6956 * Return void 6957 */ 6958 static void hdd_check_wait_for_hw_mode_completion(struct hdd_context *hdd_ctx) 6959 { 6960 QDF_STATUS status; 6961 6962 if (!wlan_hdd_validate_context(hdd_ctx) && 6963 policy_mgr_is_hw_mode_change_in_progress( 6964 hdd_ctx->psoc)) { 6965 status = policy_mgr_wait_for_connection_update( 6966 hdd_ctx->psoc); 6967 if (!QDF_IS_STATUS_SUCCESS(status)) { 6968 hdd_nofl_debug("qdf wait for hw mode event failed!!"); 6969 } 6970 } 6971 } 6972 6973 static void hdd_stop_last_active_connection(struct hdd_context *hdd_ctx, 6974 struct wlan_objmgr_vdev *vdev) 6975 { 6976 enum policy_mgr_con_mode mode; 6977 struct wlan_objmgr_psoc *psoc; 6978 enum QDF_OPMODE op_mode; 6979 6980 /* If this is the last active connection check 6981 * and stop the opportunistic timer. 6982 */ 6983 psoc = wlan_vdev_get_psoc(vdev); 6984 op_mode = wlan_vdev_mlme_get_opmode(vdev); 6985 mode = policy_mgr_qdf_opmode_to_pm_con_mode(psoc, op_mode, 6986 wlan_vdev_get_id(vdev)); 6987 if ((policy_mgr_get_connection_count(psoc) == 1 && 6988 policy_mgr_mode_specific_connection_count(psoc, 6989 mode, NULL) == 1) || 6990 (!policy_mgr_get_connection_count(psoc) && 6991 !hdd_is_any_sta_connecting(hdd_ctx))) { 6992 policy_mgr_check_and_stop_opportunistic_timer( 6993 psoc, 6994 wlan_vdev_get_id(vdev)); 6995 } 6996 } 6997 6998 static int hdd_vdev_destroy_event_wait(struct hdd_context *hdd_ctx, 6999 struct wlan_objmgr_vdev *vdev) 7000 { 7001 long rc; 7002 QDF_STATUS status; 7003 uint8_t vdev_id; 7004 struct wlan_hdd_link_info *link_info; 7005 7006 vdev_id = wlan_vdev_get_id(vdev); 7007 link_info = hdd_get_link_info_by_vdev(hdd_ctx, vdev_id); 7008 if (!link_info) { 7009 hdd_err("Invalid vdev"); 7010 return -EINVAL; 7011 } 7012 7013 /* close sme session (destroy vdev in firmware via legacy API) */ 7014 INIT_COMPLETION(link_info->vdev_destroy_event); 7015 status = sme_vdev_delete(hdd_ctx->mac_handle, vdev); 7016 if (QDF_IS_STATUS_ERROR(status)) { 7017 hdd_err("vdev %d: failed to delete with status:%d", 7018 vdev_id, status); 7019 return -EAGAIN; 7020 } 7021 7022 /* block on a completion variable until sme session is closed */ 7023 rc = wait_for_completion_timeout( 7024 &link_info->vdev_destroy_event, 7025 msecs_to_jiffies(SME_CMD_VDEV_CREATE_DELETE_TIMEOUT)); 7026 if (!rc) { 7027 hdd_err("vdev %d: timed out waiting for delete", vdev_id); 7028 clear_bit(SME_SESSION_OPENED, &link_info->link_flags); 7029 sme_cleanup_session(hdd_ctx->mac_handle, vdev_id); 7030 cds_flush_logs(WLAN_LOG_TYPE_FATAL, 7031 WLAN_LOG_INDICATOR_HOST_DRIVER, 7032 WLAN_LOG_REASON_VDEV_DELETE_RSP_TIMED_OUT, 7033 true, true); 7034 return -EINVAL; 7035 } 7036 7037 hdd_nofl_info("vdev %d destroyed successfully", vdev_id); 7038 return 0; 7039 } 7040 7041 static inline 7042 void hdd_vdev_deinit_components(struct wlan_objmgr_vdev *vdev) 7043 { 7044 ucfg_pmo_del_wow_pattern(vdev); 7045 ucfg_son_disable_cbs(vdev); 7046 } 7047 7048 static inline 7049 void hdd_reset_vdev_info(struct wlan_hdd_link_info *link_info) 7050 { 7051 qdf_spin_lock_bh(&link_info->vdev_lock); 7052 link_info->vdev = NULL; 7053 qdf_spin_unlock_bh(&link_info->vdev_lock); 7054 } 7055 7056 int hdd_vdev_destroy(struct wlan_hdd_link_info *link_info) 7057 { 7058 int ret; 7059 uint8_t vdev_id; 7060 struct hdd_context *hdd_ctx; 7061 struct wlan_objmgr_vdev *vdev; 7062 struct wlan_objmgr_psoc *psoc; 7063 enum QDF_OPMODE op_mode; 7064 7065 vdev_id = link_info->vdev_id; 7066 hdd_nofl_debug("destroying vdev %d", vdev_id); 7067 /* vdev created sanity check */ 7068 if (!test_bit(SME_SESSION_OPENED, &link_info->link_flags)) { 7069 hdd_nofl_debug("vdev %u does not exist", vdev_id); 7070 return -EINVAL; 7071 } 7072 7073 hdd_ctx = WLAN_HDD_GET_CTX(link_info->adapter); 7074 7075 vdev = hdd_objmgr_get_vdev_by_user(link_info, WLAN_OSIF_ID); 7076 if (!vdev) 7077 return -EINVAL; 7078 7079 psoc = wlan_vdev_get_psoc(vdev); 7080 if (!psoc) { 7081 hdd_err("invalid psoc"); 7082 return -EINVAL; 7083 } 7084 op_mode = wlan_vdev_mlme_get_opmode(vdev); 7085 7086 hdd_stop_last_active_connection(hdd_ctx, vdev); 7087 hdd_check_wait_for_hw_mode_completion(hdd_ctx); 7088 ucfg_scan_vdev_set_disable(vdev, REASON_VDEV_DOWN); 7089 wlan_hdd_scan_abort(link_info); 7090 hdd_vdev_deinit_components(vdev); 7091 hdd_mlo_t2lm_unregister_callback(vdev); 7092 hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_ID); 7093 7094 hdd_reset_vdev_info(link_info); 7095 osif_cm_osif_priv_deinit(vdev); 7096 7097 /* Release the hdd reference */ 7098 wlan_objmgr_vdev_release_ref(vdev, WLAN_HDD_ID_OBJ_MGR); 7099 7100 /* Get runtime lock to prevent runtime suspend */ 7101 qdf_runtime_pm_prevent_suspend(&hdd_ctx->runtime_context.vdev_destroy); 7102 7103 ret = hdd_vdev_destroy_event_wait(hdd_ctx, vdev); 7104 7105 ucfg_reg_11d_vdev_delete_update(psoc, op_mode, vdev_id); 7106 7107 qdf_runtime_pm_allow_suspend(&hdd_ctx->runtime_context.vdev_destroy); 7108 return ret; 7109 } 7110 7111 void 7112 hdd_store_nss_chains_cfg_in_vdev(struct hdd_context *hdd_ctx, 7113 struct wlan_objmgr_vdev *vdev) 7114 { 7115 struct wlan_mlme_nss_chains vdev_ini_cfg; 7116 7117 /* Populate the nss chain params from ini for this vdev type */ 7118 sme_populate_nss_chain_params(hdd_ctx->mac_handle, &vdev_ini_cfg, 7119 wlan_vdev_mlme_get_opmode(vdev), 7120 hdd_ctx->num_rf_chains); 7121 7122 /* Store the nss chain config into the vdev */ 7123 sme_store_nss_chains_cfg_in_vdev(vdev, &vdev_ini_cfg); 7124 } 7125 7126 bool hdd_is_vdev_in_conn_state(struct wlan_hdd_link_info *link_info) 7127 { 7128 switch (link_info->adapter->device_mode) { 7129 case QDF_STA_MODE: 7130 case QDF_P2P_CLIENT_MODE: 7131 case QDF_P2P_DEVICE_MODE: 7132 return hdd_cm_is_vdev_associated(link_info); 7133 case QDF_SAP_MODE: 7134 case QDF_P2P_GO_MODE: 7135 return (test_bit(SOFTAP_BSS_STARTED, 7136 &link_info->link_flags)); 7137 default: 7138 hdd_err("Device mode %d invalid", 7139 link_info->adapter->device_mode); 7140 return 0; 7141 } 7142 } 7143 7144 #define MAX_VDEV_RTT_PARAMS 2 7145 /* params being sent: 7146 * wmi_vdev_param_enable_disable_rtt_responder_role 7147 * wmi_vdev_param_enable_disable_rtt_initiator_role 7148 */ 7149 static QDF_STATUS 7150 hdd_vdev_configure_rtt_params(struct wlan_objmgr_vdev *vdev) 7151 { 7152 QDF_STATUS status; 7153 struct wlan_objmgr_psoc *psoc; 7154 uint32_t fine_time_meas_cap = 0; 7155 uint8_t vdev_id = wlan_vdev_get_id(vdev); 7156 struct dev_set_param vdevsetparam[MAX_VDEV_RTT_PARAMS] = {}; 7157 uint8_t index = 0; 7158 WMI_FW_SUB_FEAT_CAPS wmi_fw_rtt_respr, wmi_fw_rtt_initr; 7159 7160 switch (wlan_vdev_mlme_get_opmode(vdev)) { 7161 case QDF_STA_MODE: 7162 wmi_fw_rtt_respr = WMI_FW_STA_RTT_RESPR; 7163 wmi_fw_rtt_initr = WMI_FW_STA_RTT_INITR; 7164 break; 7165 case QDF_SAP_MODE: 7166 wmi_fw_rtt_respr = WMI_FW_AP_RTT_RESPR; 7167 wmi_fw_rtt_initr = WMI_FW_AP_RTT_INITR; 7168 break; 7169 default: 7170 return QDF_STATUS_SUCCESS; 7171 } 7172 7173 psoc = wlan_vdev_get_psoc(vdev); 7174 7175 ucfg_mlme_get_fine_time_meas_cap(psoc, &fine_time_meas_cap); 7176 status = mlme_check_index_setparam( 7177 vdevsetparam, 7178 wmi_vdev_param_enable_disable_rtt_responder_role, 7179 (fine_time_meas_cap & wmi_fw_rtt_respr), index++, 7180 MAX_VDEV_RTT_PARAMS); 7181 if (QDF_IS_STATUS_ERROR(status)) 7182 return status; 7183 7184 status = mlme_check_index_setparam( 7185 vdevsetparam, 7186 wmi_vdev_param_enable_disable_rtt_initiator_role, 7187 (fine_time_meas_cap & wmi_fw_rtt_initr), index++, 7188 MAX_VDEV_RTT_PARAMS); 7189 if (QDF_IS_STATUS_ERROR(status)) 7190 return status; 7191 7192 status = sme_send_multi_pdev_vdev_set_params(MLME_VDEV_SETPARAM, 7193 vdev_id, vdevsetparam, 7194 index); 7195 if (QDF_IS_STATUS_ERROR(status)) 7196 hdd_err("failed to set RTT_RESPONDER,INITIATOR params:%d", 7197 status); 7198 7199 return status; 7200 } 7201 7202 static void hdd_store_vdev_info(struct wlan_hdd_link_info *link_info, 7203 struct wlan_objmgr_vdev *vdev) 7204 { 7205 struct vdev_osif_priv *osif_priv; 7206 7207 osif_priv = wlan_vdev_get_ospriv(vdev); 7208 if (osif_priv) { 7209 osif_priv->wdev = link_info->adapter->dev->ieee80211_ptr; 7210 osif_priv->legacy_osif_priv = link_info; 7211 } 7212 7213 qdf_spin_lock_bh(&link_info->vdev_lock); 7214 link_info->vdev_id = wlan_vdev_get_id(vdev); 7215 link_info->vdev = vdev; 7216 qdf_spin_unlock_bh(&link_info->vdev_lock); 7217 } 7218 7219 static void 7220 hdd_init_station_context(struct wlan_hdd_link_info *link_info) 7221 { 7222 struct hdd_station_ctx *sta_ctx; 7223 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(link_info->adapter); 7224 7225 /* Set the default operation channel freq and auth type to open */ 7226 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(link_info); 7227 sta_ctx->conn_info.chan_freq = hdd_ctx->config->operating_chan_freq; 7228 sta_ctx->conn_info.auth_type = eCSR_AUTH_TYPE_OPEN_SYSTEM; 7229 hdd_roam_profile_init(link_info); 7230 } 7231 7232 static void hdd_vdev_set_ht_vht_ies(mac_handle_t mac_handle, 7233 struct wlan_objmgr_vdev *vdev) 7234 { 7235 QDF_STATUS status; 7236 struct wlan_objmgr_psoc *psoc; 7237 bool bval = false; 7238 7239 psoc = wlan_vdev_get_psoc(vdev); 7240 status = ucfg_mlme_get_vht_enable2x2(psoc, &bval); 7241 if (QDF_IS_STATUS_ERROR(status)) 7242 hdd_err("unable to get vht_enable2x2"); 7243 7244 sme_set_pdev_ht_vht_ies(mac_handle, bval); 7245 sme_set_vdev_ies_per_band(mac_handle, wlan_vdev_get_id(vdev), 7246 wlan_vdev_mlme_get_opmode(vdev)); 7247 } 7248 7249 static void 7250 hdd_vdev_configure_rtt_mac_randomization(struct wlan_objmgr_psoc *psoc, 7251 struct wlan_objmgr_vdev *vdev) 7252 { 7253 int errno; 7254 QDF_STATUS status; 7255 bool bval = false; 7256 7257 status = ucfg_mlme_get_rtt_mac_randomization(psoc, &bval); 7258 if (QDF_IS_STATUS_ERROR(status)) 7259 hdd_err("unable to get RTT MAC randomization value"); 7260 7261 hdd_debug("setting RTT mac randomization param: %d", bval); 7262 errno = sme_cli_set_command( 7263 wlan_vdev_get_id(vdev), 7264 wmi_vdev_param_enable_disable_rtt_initiator_random_mac, 7265 bval, VDEV_CMD); 7266 7267 if (errno) 7268 hdd_err("RTT mac randomization param set failed %d", errno); 7269 } 7270 7271 static void 7272 hdd_vdev_configure_max_tdls_params(struct wlan_objmgr_psoc *psoc, 7273 struct wlan_objmgr_vdev *vdev) 7274 { 7275 uint16_t max_peer_count; 7276 bool target_bigtk_support = false; 7277 7278 /* Max peer can be tdls peers + self peer + bss peer */ 7279 max_peer_count = cfg_tdls_get_max_peer_count(psoc); 7280 max_peer_count += 2; 7281 wlan_vdev_set_max_peer_count(vdev, max_peer_count); 7282 7283 ucfg_mlme_get_bigtk_support(psoc, &target_bigtk_support); 7284 if (target_bigtk_support) 7285 mlme_set_bigtk_support(vdev, true); 7286 } 7287 7288 static inline void 7289 hdd_vdev_configure_nan_params(struct wlan_objmgr_psoc *psoc, 7290 struct wlan_objmgr_vdev *vdev) 7291 { 7292 sme_cli_set_command( 7293 wlan_vdev_get_id(vdev), 7294 wmi_vdev_param_allow_nan_initial_discovery_of_mp0_cluster, 7295 cfg_nan_get_support_mp0_discovery(psoc), VDEV_CMD); 7296 } 7297 7298 #if defined(WLAN_FEATURE_11BE_MLO) && defined(WLAN_EXTERNAL_AUTH_MLO_SUPPORT) 7299 static void 7300 hdd_set_vdev_mlo_external_sae_auth_conversion(struct wlan_objmgr_vdev *vdev, 7301 enum QDF_OPMODE mode) 7302 { 7303 if (mode == QDF_STA_MODE || mode == QDF_SAP_MODE) 7304 wlan_vdev_set_mlo_external_sae_auth_conversion(vdev, true); 7305 } 7306 #else 7307 static inline void 7308 hdd_set_vdev_mlo_external_sae_auth_conversion(struct wlan_objmgr_vdev *vdev, 7309 enum QDF_OPMODE mode) 7310 { 7311 } 7312 #endif 7313 7314 static void 7315 hdd_vdev_configure_opmode_params(struct hdd_context *hdd_ctx, 7316 struct wlan_objmgr_vdev *vdev) 7317 { 7318 struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc; 7319 enum QDF_OPMODE opmode = wlan_vdev_mlme_get_opmode(vdev); 7320 7321 switch (opmode) { 7322 case QDF_STA_MODE: 7323 hdd_vdev_configure_rtt_mac_randomization(psoc, vdev); 7324 hdd_vdev_configure_max_tdls_params(psoc, vdev); 7325 break; 7326 case QDF_P2P_CLIENT_MODE: 7327 hdd_vdev_configure_max_tdls_params(psoc, vdev); 7328 break; 7329 case QDF_NAN_DISC_MODE: 7330 hdd_vdev_configure_nan_params(psoc, vdev); 7331 break; 7332 default: 7333 break; 7334 } 7335 7336 ucfg_fwol_configure_vdev_params(psoc, vdev); 7337 hdd_set_vdev_mlo_external_sae_auth_conversion(vdev, opmode); 7338 hdd_store_nss_chains_cfg_in_vdev(hdd_ctx, vdev); 7339 } 7340 7341 #if defined(WLAN_FEATURE_11BE_MLO) && defined(CFG80211_11BE_BASIC) && \ 7342 defined(WLAN_HDD_MULTI_VDEV_SINGLE_NDEV) 7343 static int 7344 hdd_populate_vdev_create_params(struct wlan_hdd_link_info *link_info, 7345 struct wlan_vdev_create_params *vdev_params) 7346 { 7347 struct hdd_adapter *adapter = link_info->adapter; 7348 7349 vdev_params->opmode = adapter->device_mode; 7350 vdev_params->size_vdev_priv = sizeof(struct vdev_osif_priv); 7351 7352 if (hdd_adapter_is_ml_adapter(adapter)) { 7353 qdf_ether_addr_copy(vdev_params->mldaddr, 7354 adapter->mac_addr.bytes); 7355 qdf_ether_addr_copy(vdev_params->macaddr, 7356 link_info->link_addr.bytes); 7357 } else { 7358 qdf_ether_addr_copy(vdev_params->macaddr, 7359 adapter->mac_addr.bytes); 7360 } 7361 return 0; 7362 } 7363 #elif defined(WLAN_FEATURE_11BE_MLO) && defined(CFG80211_11BE_BASIC) 7364 static int 7365 hdd_populate_vdev_create_params(struct wlan_hdd_link_info *link_info, 7366 struct wlan_vdev_create_params *vdev_params) 7367 { 7368 struct hdd_adapter *adapter = link_info->adapter; 7369 struct hdd_mlo_adapter_info *mlo_adapter_info; 7370 struct hdd_adapter *link_adapter; 7371 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); 7372 bool eht_capab; 7373 7374 hdd_enter_dev(adapter->dev); 7375 mlo_adapter_info = &adapter->mlo_adapter_info; 7376 7377 ucfg_psoc_mlme_get_11be_capab(hdd_ctx->psoc, &eht_capab); 7378 if (mlo_adapter_info->is_ml_adapter && eht_capab && 7379 adapter->device_mode == QDF_STA_MODE) { 7380 link_adapter = hdd_get_assoc_link_adapter(adapter); 7381 if (link_adapter) { 7382 qdf_ether_addr_copy(vdev_params->macaddr, 7383 link_adapter->mac_addr.bytes); 7384 } else { 7385 return -EINVAL; 7386 } 7387 } else { 7388 qdf_ether_addr_copy(vdev_params->macaddr, 7389 adapter->mac_addr.bytes); 7390 } 7391 7392 vdev_params->opmode = adapter->device_mode; 7393 7394 if (eht_capab) { 7395 qdf_ether_addr_copy(vdev_params->mldaddr, 7396 adapter->mld_addr.bytes); 7397 } 7398 7399 vdev_params->size_vdev_priv = sizeof(struct vdev_osif_priv); 7400 hdd_exit(); 7401 7402 return 0; 7403 } 7404 #else 7405 static int 7406 hdd_populate_vdev_create_params(struct wlan_hdd_link_info *link_info, 7407 struct wlan_vdev_create_params *vdev_params) 7408 { 7409 struct hdd_adapter *adapter = link_info->adapter; 7410 7411 vdev_params->opmode = adapter->device_mode; 7412 qdf_ether_addr_copy(vdev_params->macaddr, adapter->mac_addr.bytes); 7413 vdev_params->size_vdev_priv = sizeof(struct vdev_osif_priv); 7414 return 0; 7415 } 7416 #endif 7417 7418 int hdd_vdev_create(struct wlan_hdd_link_info *link_info) 7419 { 7420 QDF_STATUS status; 7421 int errno = 0; 7422 struct hdd_adapter *adapter = link_info->adapter; 7423 struct hdd_context *hdd_ctx; 7424 struct wlan_objmgr_vdev *vdev; 7425 struct wlan_vdev_create_params vdev_params = {0}; 7426 7427 hdd_nofl_debug("creating new vdev"); 7428 7429 /* do vdev create via objmgr */ 7430 hdd_ctx = WLAN_HDD_GET_CTX(adapter); 7431 7432 errno = hdd_populate_vdev_create_params(link_info, &vdev_params); 7433 if (errno) 7434 return errno; 7435 7436 vdev = sme_vdev_create(hdd_ctx->mac_handle, &vdev_params); 7437 if (!vdev) { 7438 hdd_err("failed to create vdev"); 7439 return -EINVAL; 7440 } 7441 7442 if (wlan_objmgr_vdev_try_get_ref(vdev, WLAN_HDD_ID_OBJ_MGR) != 7443 QDF_STATUS_SUCCESS) { 7444 errno = QDF_STATUS_E_INVAL; 7445 sme_vdev_delete(hdd_ctx->mac_handle, vdev); 7446 return -EINVAL; 7447 } 7448 7449 hdd_store_vdev_info(link_info, vdev); 7450 osif_cm_osif_priv_init(vdev); 7451 7452 if (hdd_adapter_is_ml_adapter(adapter)) 7453 hdd_mlo_t2lm_register_callback(vdev); 7454 7455 set_bit(SME_SESSION_OPENED, &link_info->link_flags); 7456 status = sme_vdev_post_vdev_create_setup(hdd_ctx->mac_handle, vdev); 7457 if (QDF_IS_STATUS_ERROR(status)) { 7458 hdd_err("Failed to setup the vdev"); 7459 errno = qdf_status_to_os_return(status); 7460 goto hdd_vdev_destroy_procedure; 7461 } 7462 7463 /* firmware ready for component communication, raise vdev_ready event */ 7464 errno = hdd_vdev_ready(vdev, 7465 (struct qdf_mac_addr *)hdd_ctx->bridgeaddr); 7466 if (errno) { 7467 hdd_err("failed to dispatch vdev ready event: %d", errno); 7468 goto hdd_vdev_destroy_procedure; 7469 } 7470 7471 hdd_vdev_configure_opmode_params(hdd_ctx, vdev); 7472 7473 hdd_nofl_debug("vdev %d created successfully", link_info->vdev_id); 7474 7475 return errno; 7476 7477 hdd_vdev_destroy_procedure: 7478 QDF_BUG(!hdd_vdev_destroy(link_info)); 7479 7480 return errno; 7481 } 7482 7483 QDF_STATUS hdd_init_station_mode(struct wlan_hdd_link_info *link_info) 7484 { 7485 struct hdd_adapter *adapter = link_info->adapter; 7486 struct hdd_context *hdd_ctx; 7487 QDF_STATUS status; 7488 mac_handle_t mac_handle; 7489 uint32_t roam_triggers; 7490 struct wlan_objmgr_vdev *vdev; 7491 7492 hdd_ctx = WLAN_HDD_GET_CTX(adapter); 7493 mac_handle = hdd_ctx->mac_handle; 7494 7495 vdev = hdd_objmgr_get_vdev_by_user(link_info, WLAN_INIT_DEINIT_ID); 7496 if (!vdev) { 7497 status = QDF_STATUS_E_NULL_VALUE; 7498 goto vdev_destroy; 7499 } 7500 7501 hdd_vdev_set_ht_vht_ies(mac_handle, vdev); 7502 hdd_init_station_context(link_info); 7503 7504 status = hdd_wmm_adapter_init(adapter); 7505 if (QDF_STATUS_SUCCESS != status) { 7506 hdd_err("hdd_wmm_adapter_init() failed, status code %08d [x%08x]", 7507 status, status); 7508 goto error_wmm_init; 7509 } 7510 set_bit(WMM_INIT_DONE, &adapter->event_flags); 7511 7512 /* rcpi info initialization */ 7513 qdf_mem_zero(&adapter->rcpi, sizeof(adapter->rcpi)); 7514 7515 if (adapter->device_mode == QDF_STA_MODE) { 7516 roam_triggers = ucfg_mlme_get_roaming_triggers(hdd_ctx->psoc); 7517 mlme_set_roam_trigger_bitmap(hdd_ctx->psoc, 7518 link_info->vdev_id, 7519 roam_triggers); 7520 7521 status = hdd_vdev_configure_rtt_params(vdev); 7522 if (QDF_IS_STATUS_ERROR(status)) 7523 goto error_wmm_init; 7524 } 7525 7526 hdd_objmgr_put_vdev_by_user(vdev, WLAN_INIT_DEINIT_ID); 7527 return QDF_STATUS_SUCCESS; 7528 7529 error_wmm_init: 7530 hdd_objmgr_put_vdev_by_user(vdev, WLAN_INIT_DEINIT_ID); 7531 7532 vdev_destroy: 7533 QDF_BUG(!hdd_vdev_destroy(link_info)); 7534 7535 return status; 7536 } 7537 7538 static char *net_dev_ref_debug_string_from_id(wlan_net_dev_ref_dbgid dbgid) 7539 { 7540 static const char *strings[] = { 7541 "NET_DEV_HOLD_ID_RESERVED", 7542 "NET_DEV_HOLD_GET_STA_CONNECTION_IN_PROGRESS", 7543 "NET_DEV_HOLD_CHECK_DFS_CHANNEL_FOR_ADAPTER", 7544 "NET_DEV_HOLD_GET_SAP_OPERATING_BAND", 7545 "NET_DEV_HOLD_RECOVERY_NOTIFIER_CALL", 7546 "NET_DEV_HOLD_IS_ANY_STA_CONNECTING", 7547 "NET_DEV_HOLD_SAP_DESTROY_CTX_ALL", 7548 "NET_DEV_HOLD_DRV_CMD_MAX_TX_POWER", 7549 "NET_DEV_HOLD_IPA_SET_TX_FLOW_INFO", 7550 "NET_DEV_HOLD_SET_RPS_CPU_MASK", 7551 "NET_DEV_HOLD_DFS_INDICATE_RADAR", 7552 "NET_DEV_HOLD_MAX_STA_INTERFACE_UP_COUNT_REACHED", 7553 "NET_DEV_HOLD_IS_CHAN_SWITCH_IN_PROGRESS", 7554 "NET_DEV_HOLD_STA_DESTROY_CTX_ALL", 7555 "NET_DEV_HOLD_CHECK_FOR_EXISTING_MACADDR", 7556 "NET_DEV_HOLD_DEINIT_ALL_ADAPTERS", 7557 "NET_DEV_HOLD_STOP_ALL_ADAPTERS", 7558 "NET_DEV_HOLD_RESET_ALL_ADAPTERS", 7559 "NET_DEV_HOLD_IS_ANY_INTERFACE_OPEN", 7560 "NET_DEV_HOLD_START_ALL_ADAPTERS", 7561 "NET_DEV_HOLD_GET_ADAPTER_BY_RAND_MACADDR", 7562 "NET_DEV_HOLD_GET_ADAPTER_BY_MACADDR", 7563 "NET_DEV_HOLD_GET_ADAPTER_BY_VDEV", 7564 "NET_DEV_HOLD_ADAPTER_GET_BY_REFERENCE", 7565 "NET_DEV_HOLD_GET_ADAPTER_BY_IFACE_NAME", 7566 "NET_DEV_HOLD_GET_ADAPTER", 7567 "NET_DEV_HOLD_GET_OPERATING_CHAN_FREQ", 7568 "NET_DEV_HOLD_UNREGISTER_WEXT_ALL_ADAPTERS", 7569 "NET_DEV_HOLD_ABORT_MAC_SCAN_ALL_ADAPTERS", 7570 "NET_DEV_HOLD_ABORT_SCHED_SCAN_ALL_ADAPTERS", 7571 "NET_DEV_HOLD_GET_FIRST_VALID_ADAPTER", 7572 "NET_DEV_HOLD_CLEAR_RPS_CPU_MASK", 7573 "NET_DEV_HOLD_BUS_BW_WORK_HANDLER", 7574 "NET_DEV_HOLD_DISPLAY_NETIF_QUEUE_HISTORY_COMPACT", 7575 "NET_DEV_HOLD_DISPLAY_NETIF_QUEUE_HISTORY", 7576 "NET_DEV_HOLD_CLEAR_NETIF_QUEUE_HISTORY", 7577 "NET_DEV_HOLD_UNSAFE_CHANNEL_RESTART_SAP", 7578 "NET_DEV_HOLD_INDICATE_MGMT_FRAME", 7579 "NET_DEV_HOLD_STATE_INFO_DUMP", 7580 "NET_DEV_HOLD_DISABLE_ROAMING", 7581 "NET_DEV_HOLD_ENABLE_ROAMING", 7582 "NET_DEV_HOLD_AUTO_SHUTDOWN_ENABLE", 7583 "NET_DEV_HOLD_GET_CON_SAP_ADAPTER", 7584 "NET_DEV_HOLD_IS_ANY_ADAPTER_CONNECTED", 7585 "NET_DEV_HOLD_IS_ROAMING_IN_PROGRESS", 7586 "NET_DEV_HOLD_DEL_P2P_INTERFACE", 7587 "NET_DEV_HOLD_IS_NDP_ALLOWED", 7588 "NET_DEV_HOLD_NDI_OPEN", 7589 "NET_DEV_HOLD_SEND_OEM_REG_RSP_NLINK_MSG", 7590 "NET_DEV_HOLD_PERIODIC_STA_STATS_DISPLAY", 7591 "NET_DEV_HOLD_SUSPEND_WLAN", 7592 "NET_DEV_HOLD_RESUME_WLAN", 7593 "NET_DEV_HOLD_SSR_RESTART_SAP", 7594 "NET_DEV_HOLD_SEND_DEFAULT_SCAN_IES", 7595 "NET_DEV_HOLD_CFG80211_SUSPEND_WLAN", 7596 "NET_DEV_HOLD_COUNTRY_CHANGE_UPDATE_STA", 7597 "NET_DEV_HOLD_COUNTRY_CHANGE_UPDATE_SAP", 7598 "NET_DEV_HOLD_CACHE_STATION_STATS_CB", 7599 "NET_DEV_HOLD_DISPLAY_TXRX_STATS", 7600 "NET_DEV_HOLD_START_PRE_CAC_TRANS", 7601 "NET_DEV_HOLD_IS_ANY_STA_CONNECTED", 7602 "NET_DEV_HOLD_GET_ADAPTER_BY_BSSID", 7603 "NET_DEV_HOLD_ID_MAX"}; 7604 int32_t num_dbg_strings = QDF_ARRAY_SIZE(strings); 7605 7606 if (dbgid >= num_dbg_strings) { 7607 char *ret = ""; 7608 7609 hdd_err("Debug string not found for debug id %d", dbgid); 7610 return ret; 7611 } 7612 7613 return (char *)strings[dbgid]; 7614 } 7615 7616 void hdd_check_for_net_dev_ref_leak(struct hdd_adapter *adapter) 7617 { 7618 int i, id; 7619 7620 for (id = 0; id < NET_DEV_HOLD_ID_MAX; id++) { 7621 for (i = 0; i < MAX_NET_DEV_REF_LEAK_ITERATIONS; i++) { 7622 if (!qdf_atomic_read( 7623 &adapter->net_dev_hold_ref_count[id])) 7624 break; 7625 hdd_info("net_dev held for debug id %s", 7626 net_dev_ref_debug_string_from_id(id)); 7627 qdf_sleep(NET_DEV_REF_LEAK_ITERATION_SLEEP_TIME_MS); 7628 } 7629 if (i == MAX_NET_DEV_REF_LEAK_ITERATIONS) { 7630 hdd_err("net_dev hold reference leak detected for debug id: %s", 7631 net_dev_ref_debug_string_from_id(id)); 7632 QDF_BUG(0); 7633 } 7634 } 7635 } 7636 7637 /** 7638 * hdd_deinit_station_mode() - De-initialize the station adapter 7639 * @adapter: HDD adapter pointer 7640 * 7641 * This function De-initializes the STA/P2P/OCB adapter. 7642 * 7643 * Return: None. 7644 */ 7645 static void hdd_deinit_station_mode(struct hdd_adapter *adapter) 7646 { 7647 if (test_bit(WMM_INIT_DONE, &adapter->event_flags)) { 7648 hdd_wmm_adapter_close(adapter); 7649 clear_bit(WMM_INIT_DONE, &adapter->event_flags); 7650 } 7651 } 7652 7653 void hdd_deinit_session(struct hdd_adapter *adapter) 7654 { 7655 struct wlan_hdd_link_info *link_info; 7656 7657 hdd_enter(); 7658 7659 switch (adapter->device_mode) { 7660 case QDF_STA_MODE: 7661 case QDF_P2P_CLIENT_MODE: 7662 case QDF_MONITOR_MODE: 7663 case QDF_P2P_DEVICE_MODE: 7664 case QDF_NDI_MODE: 7665 case QDF_NAN_DISC_MODE: 7666 { 7667 hdd_deinit_station_mode(adapter); 7668 break; 7669 } 7670 7671 case QDF_SAP_MODE: 7672 case QDF_P2P_GO_MODE: 7673 { 7674 hdd_adapter_for_each_active_link_info(adapter, link_info) 7675 hdd_deinit_ap_mode(link_info); 7676 break; 7677 } 7678 7679 default: 7680 break; 7681 } 7682 7683 if (adapter->scan_info.default_scan_ies) { 7684 qdf_mem_free(adapter->scan_info.default_scan_ies); 7685 adapter->scan_info.default_scan_ies = NULL; 7686 adapter->scan_info.default_scan_ies_len = 0; 7687 } 7688 7689 hdd_exit(); 7690 } 7691 7692 void hdd_deinit_adapter(struct hdd_context *hdd_ctx, 7693 struct hdd_adapter *adapter, 7694 bool rtnl_held) 7695 { 7696 hdd_enter_dev(adapter->dev); 7697 7698 hdd_wext_unregister(adapter->dev, rtnl_held); 7699 hdd_deinit_session(adapter); 7700 hdd_exit(); 7701 } 7702 7703 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0)) && \ 7704 defined(WLAN_FEATURE_11AX) 7705 /** 7706 * hdd_cleanup_he_operation_info() - cleanup he operation info 7707 * @link_info: pointer to link_info struct in adapter 7708 * 7709 * This function destroys he operation information 7710 * 7711 * Return: none 7712 */ 7713 static void hdd_cleanup_he_operation_info(struct wlan_hdd_link_info *link_info) 7714 { 7715 struct hdd_station_ctx *hdd_sta_ctx; 7716 7717 hdd_debug("cleanup he operation info"); 7718 7719 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(link_info); 7720 7721 if (hdd_sta_ctx->cache_conn_info.he_operation) { 7722 qdf_mem_free(hdd_sta_ctx->cache_conn_info.he_operation); 7723 hdd_sta_ctx->cache_conn_info.he_operation = NULL; 7724 } 7725 } 7726 #else 7727 static inline void 7728 hdd_cleanup_he_operation_info(struct wlan_hdd_link_info *link_info) 7729 { 7730 } 7731 #endif 7732 7733 /** 7734 * hdd_cleanup_prev_ap_bcn_ie() - cleanup previous ap beacon ie 7735 * @link_info: pointer to link_info struct in adapter 7736 * 7737 * This function destroys previous ap beacon information 7738 * 7739 * Return: none 7740 */ 7741 static void hdd_cleanup_prev_ap_bcn_ie(struct wlan_hdd_link_info *link_info) 7742 { 7743 struct hdd_station_ctx *hdd_sta_ctx; 7744 struct element_info *bcn_ie; 7745 7746 hdd_debug("cleanup previous ap bcn ie"); 7747 7748 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(link_info); 7749 bcn_ie = &hdd_sta_ctx->conn_info.prev_ap_bcn_ie; 7750 7751 if (bcn_ie->ptr) { 7752 qdf_mem_free(bcn_ie->ptr); 7753 bcn_ie->ptr = NULL; 7754 bcn_ie->len = 0; 7755 } 7756 } 7757 7758 void hdd_cleanup_conn_info(struct wlan_hdd_link_info *link_info) 7759 { 7760 hdd_cleanup_he_operation_info(link_info); 7761 hdd_cleanup_prev_ap_bcn_ie(link_info); 7762 } 7763 7764 /** 7765 * hdd_sta_destroy_ctx_all() - cleanup all station contexts 7766 * @hdd_ctx: Global HDD context 7767 * 7768 * This function destroys all the station contexts 7769 * 7770 * Return: none 7771 */ 7772 static void hdd_sta_destroy_ctx_all(struct hdd_context *hdd_ctx) 7773 { 7774 struct hdd_adapter *adapter, *next_adapter = NULL; 7775 struct wlan_hdd_link_info *link_info; 7776 7777 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 7778 NET_DEV_HOLD_STA_DESTROY_CTX_ALL) { 7779 if (adapter->device_mode == QDF_STA_MODE) { 7780 hdd_adapter_for_each_link_info(adapter, link_info) { 7781 hdd_cleanup_conn_info(link_info); 7782 } 7783 } 7784 hdd_adapter_dev_put_debug(adapter, 7785 NET_DEV_HOLD_STA_DESTROY_CTX_ALL); 7786 } 7787 } 7788 7789 #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 12, 0) 7790 static void 7791 hdd_unregister_netdevice(struct hdd_adapter *adapter, struct net_device *dev) 7792 { 7793 if (adapter->is_virtual_iface) { 7794 wlan_cfg80211_unregister_netdevice(dev); 7795 adapter->is_virtual_iface = false; 7796 } else { 7797 unregister_netdevice(dev); 7798 } 7799 } 7800 #else 7801 static void 7802 hdd_unregister_netdevice(struct hdd_adapter *adapter, struct net_device *dev) 7803 { 7804 unregister_netdevice(dev); 7805 } 7806 #endif 7807 7808 static inline void hdd_adapter_destroy_vdev_info(struct hdd_adapter *adapter) 7809 { 7810 struct wlan_hdd_link_info *link_info; 7811 7812 hdd_adapter_for_each_link_info(adapter, link_info) { 7813 qdf_event_destroy(&link_info->acs_complete_event); 7814 qdf_spinlock_destroy(&link_info->vdev_lock); 7815 } 7816 } 7817 7818 static void hdd_cleanup_adapter(struct hdd_context *hdd_ctx, 7819 struct hdd_adapter *adapter, 7820 bool rtnl_held) 7821 { 7822 struct net_device *dev = NULL; 7823 7824 if (adapter) 7825 dev = adapter->dev; 7826 else { 7827 hdd_err("adapter is Null"); 7828 return; 7829 } 7830 7831 hdd_apf_context_destroy(adapter); 7832 qdf_spinlock_destroy(&adapter->mc_list_lock); 7833 hdd_adapter_destroy_vdev_info(adapter); 7834 hdd_sta_info_deinit(&adapter->sta_info_list); 7835 hdd_sta_info_deinit(&adapter->cache_sta_info_list); 7836 7837 wlan_hdd_debugfs_csr_deinit(adapter); 7838 7839 hdd_debugfs_exit(adapter); 7840 7841 /* 7842 * The adapter is marked as closed. When hdd_wlan_exit() call returns, 7843 * the driver is almost closed and cannot handle either control 7844 * messages or data. However, unregister_netdevice() call above will 7845 * eventually invoke hdd_stop(ndo_close) driver callback, which attempts 7846 * to close the active connections(basically excites control path) which 7847 * is not right. Setting this flag helps hdd_stop() to recognize that 7848 * the interface is closed and restricts any operations on that 7849 */ 7850 clear_bit(DEVICE_IFACE_OPENED, &adapter->event_flags); 7851 7852 if (test_bit(NET_DEVICE_REGISTERED, &adapter->event_flags)) { 7853 if (rtnl_held) { 7854 hdd_debug("hdd_unregister_netdevice(%s) type:%d", 7855 dev->name, adapter->device_mode); 7856 hdd_unregister_netdevice(adapter, dev); 7857 } else { 7858 hdd_debug("unregister_netdev(%s) type:%d", dev->name, 7859 adapter->device_mode); 7860 unregister_netdev(dev); 7861 } 7862 /* 7863 * Note that the adapter is no longer valid at this point 7864 * since the memory has been reclaimed 7865 */ 7866 } 7867 } 7868 7869 static QDF_STATUS hdd_check_for_existing_macaddr(struct hdd_context *hdd_ctx, 7870 tSirMacAddr mac_addr) 7871 { 7872 struct hdd_adapter *adapter, *next_adapter = NULL; 7873 wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_CHECK_FOR_EXISTING_MACADDR; 7874 7875 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 7876 dbgid) { 7877 if (!qdf_mem_cmp(adapter->mac_addr.bytes, 7878 mac_addr, sizeof(tSirMacAddr))) { 7879 hdd_adapter_dev_put_debug(adapter, dbgid); 7880 if (next_adapter) 7881 hdd_adapter_dev_put_debug(next_adapter, 7882 dbgid); 7883 return QDF_STATUS_E_FAILURE; 7884 } 7885 hdd_adapter_dev_put_debug(adapter, dbgid); 7886 } 7887 7888 return QDF_STATUS_SUCCESS; 7889 } 7890 7891 /** 7892 * hdd_configure_chain_mask() - programs chain mask to firmware 7893 * @adapter: HDD adapter 7894 * 7895 * Return: 0 on success or errno on failure 7896 */ 7897 static int hdd_configure_chain_mask(struct hdd_adapter *adapter) 7898 { 7899 QDF_STATUS status; 7900 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); 7901 7902 status = ucfg_mlme_configure_chain_mask(hdd_ctx->psoc, 7903 adapter->deflink->vdev_id); 7904 if (QDF_IS_STATUS_ERROR(status)) 7905 goto error; 7906 7907 return 0; 7908 7909 error: 7910 hdd_debug("WMI PDEV set param failed"); 7911 return -EINVAL; 7912 } 7913 7914 void hdd_adapter_update_mlo_mgr_mac_addr(struct hdd_adapter *adapter) 7915 { 7916 int i = 0; 7917 struct wlan_hdd_link_info *link_info; 7918 struct wlan_mlo_link_mac_update link_mac = {0}; 7919 7920 if (!hdd_adapter_is_ml_adapter(adapter)) 7921 return; 7922 7923 hdd_adapter_for_each_link_info(adapter, link_info) { 7924 link_mac.link_mac_info[i].vdev_id = link_info->vdev_id; 7925 qdf_copy_macaddr(&link_mac.link_mac_info[i++].link_mac_addr, 7926 &link_info->link_addr); 7927 } 7928 7929 link_mac.num_mac_update = i; 7930 mlo_mgr_update_link_info_mac_addr(adapter->deflink->vdev, &link_mac); 7931 } 7932 7933 /** 7934 * hdd_send_coex_config_params() - Send coex config params to FW 7935 * @hdd_ctx: HDD context 7936 * @adapter: Primary adapter context 7937 * 7938 * This function is used to send all coex config related params to FW 7939 * 7940 * Return: 0 on success and -EINVAL on failure 7941 */ 7942 static int hdd_send_coex_config_params(struct hdd_context *hdd_ctx, 7943 struct hdd_adapter *adapter) 7944 { 7945 struct coex_config_params coex_cfg_params = {0}; 7946 struct wlan_fwol_coex_config config = {0}; 7947 struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc; 7948 enum coex_btc_chain_mode btc_chain_mode; 7949 QDF_STATUS status; 7950 7951 if (!adapter) { 7952 hdd_err("adapter is invalid"); 7953 goto err; 7954 } 7955 7956 if (!psoc) { 7957 hdd_err("HDD psoc is invalid"); 7958 goto err; 7959 } 7960 7961 status = ucfg_fwol_get_coex_config_params(psoc, &config); 7962 if (QDF_IS_STATUS_ERROR(status)) { 7963 hdd_err("Unable to get coex config params"); 7964 goto err; 7965 } 7966 7967 coex_cfg_params.vdev_id = adapter->deflink->vdev_id; 7968 coex_cfg_params.config_type = WMI_COEX_CONFIG_TX_POWER; 7969 coex_cfg_params.config_arg1 = config.max_tx_power_for_btc; 7970 7971 wma_nofl_debug("TXP[W][send_coex_cfg]: %d", 7972 config.max_tx_power_for_btc); 7973 7974 status = sme_send_coex_config_cmd(&coex_cfg_params); 7975 if (QDF_IS_STATUS_ERROR(status)) { 7976 hdd_err("Failed to send coex Tx power"); 7977 goto err; 7978 } 7979 7980 coex_cfg_params.config_type = WMI_COEX_CONFIG_HANDOVER_RSSI; 7981 coex_cfg_params.config_arg1 = config.wlan_low_rssi_threshold; 7982 7983 status = sme_send_coex_config_cmd(&coex_cfg_params); 7984 if (QDF_IS_STATUS_ERROR(status)) { 7985 hdd_err("Failed to send coex handover RSSI"); 7986 goto err; 7987 } 7988 7989 coex_cfg_params.config_type = WMI_COEX_CONFIG_BTC_MODE; 7990 7991 /* Modify BTC_MODE according to BTC_CHAIN_MODE */ 7992 status = ucfg_coex_psoc_get_btc_chain_mode(psoc, &btc_chain_mode); 7993 if (QDF_IS_STATUS_ERROR(status)) { 7994 hdd_err("Failed to get btc chain mode"); 7995 btc_chain_mode = WLAN_COEX_BTC_CHAIN_MODE_UNSETTLED; 7996 } 7997 7998 if (btc_chain_mode <= WLAN_COEX_BTC_CHAIN_MODE_HYBRID) 7999 coex_cfg_params.config_arg1 = btc_chain_mode; 8000 else 8001 coex_cfg_params.config_arg1 = config.btc_mode; 8002 8003 hdd_debug("Configured BTC mode is %d, BTC chain mode is 0x%x, set BTC mode to %d", 8004 config.btc_mode, btc_chain_mode, 8005 coex_cfg_params.config_arg1); 8006 status = sme_send_coex_config_cmd(&coex_cfg_params); 8007 if (QDF_IS_STATUS_ERROR(status)) { 8008 hdd_err("Failed to send coex BTC mode"); 8009 goto err; 8010 } 8011 8012 coex_cfg_params.config_type = WMI_COEX_CONFIG_ANTENNA_ISOLATION; 8013 coex_cfg_params.config_arg1 = config.antenna_isolation; 8014 8015 status = sme_send_coex_config_cmd(&coex_cfg_params); 8016 if (QDF_IS_STATUS_ERROR(status)) { 8017 hdd_err("Failed to send coex antenna isolation"); 8018 goto err; 8019 } 8020 8021 coex_cfg_params.config_type = WMI_COEX_CONFIG_BT_LOW_RSSI_THRESHOLD; 8022 coex_cfg_params.config_arg1 = config.bt_low_rssi_threshold; 8023 8024 status = sme_send_coex_config_cmd(&coex_cfg_params); 8025 if (QDF_IS_STATUS_ERROR(status)) { 8026 hdd_err("Failed to send coex BT low RSSI threshold"); 8027 goto err; 8028 } 8029 8030 coex_cfg_params.config_type = WMI_COEX_CONFIG_BT_INTERFERENCE_LEVEL; 8031 coex_cfg_params.config_arg1 = config.bt_interference_low_ll; 8032 coex_cfg_params.config_arg2 = config.bt_interference_low_ul; 8033 coex_cfg_params.config_arg3 = config.bt_interference_medium_ll; 8034 coex_cfg_params.config_arg4 = config.bt_interference_medium_ul; 8035 coex_cfg_params.config_arg5 = config.bt_interference_high_ll; 8036 coex_cfg_params.config_arg6 = config.bt_interference_high_ul; 8037 8038 status = sme_send_coex_config_cmd(&coex_cfg_params); 8039 if (QDF_IS_STATUS_ERROR(status)) { 8040 hdd_err("Failed to send coex BT interference level"); 8041 goto err; 8042 } 8043 8044 if (wlan_hdd_mpta_helper_enable(&coex_cfg_params, &config)) 8045 goto err; 8046 8047 coex_cfg_params.config_type = 8048 WMI_COEX_CONFIG_BT_SCO_ALLOW_WLAN_2G_SCAN; 8049 coex_cfg_params.config_arg1 = config.bt_sco_allow_wlan_2g_scan; 8050 8051 status = sme_send_coex_config_cmd(&coex_cfg_params); 8052 if (QDF_IS_STATUS_ERROR(status)) { 8053 hdd_err("Failed to send coex BT sco allow wlan 2g scan"); 8054 goto err; 8055 } 8056 8057 coex_cfg_params.config_type = 8058 WMI_COEX_CONFIG_LE_SCAN_POLICY; 8059 coex_cfg_params.config_arg1 = config.ble_scan_coex_policy; 8060 8061 status = sme_send_coex_config_cmd(&coex_cfg_params); 8062 if (QDF_IS_STATUS_ERROR(status)) { 8063 hdd_err("Failed to send coex BLE scan policy"); 8064 goto err; 8065 } 8066 8067 #ifdef FEATURE_COEX_TPUT_SHAPING_CONFIG 8068 coex_cfg_params.config_type = 8069 WMI_COEX_CONFIG_ENABLE_TPUT_SHAPING; 8070 coex_cfg_params.config_arg1 = config.coex_tput_shaping_enable; 8071 8072 status = sme_send_coex_config_cmd(&coex_cfg_params); 8073 if (QDF_IS_STATUS_ERROR(status)) { 8074 hdd_err("Failed to send coex traffic shaping value %d", 8075 coex_cfg_params.config_arg1); 8076 goto err; 8077 } 8078 #endif 8079 return 0; 8080 err: 8081 return -EINVAL; 8082 } 8083 8084 #define MAX_PDEV_SET_FW_PARAMS 7 8085 /* params being sent: 8086 * 1.wmi_pdev_param_dtim_synth 8087 * 2.wmi_pdev_param_1ch_dtim_optimized_chain_selection 8088 * 3.wmi_pdev_param_tx_sch_delay 8089 * 4.wmi_pdev_param_en_update_scram_seed 8090 * 5.wmi_pdev_param_secondary_retry_enable 8091 * 6.wmi_pdev_param_set_sap_xlna_bypass 8092 * 7.wmi_pdev_param_set_dfs_chan_ageout_time 8093 */ 8094 8095 /** 8096 * hdd_set_fw_params() - Set parameters to firmware 8097 * @adapter: HDD adapter 8098 * 8099 * This function Sets various parameters to fw once the 8100 * adapter is started. 8101 * 8102 * Return: 0 on success or errno on failure 8103 */ 8104 int hdd_set_fw_params(struct hdd_adapter *adapter) 8105 { 8106 int ret; 8107 uint16_t upper_brssi_thresh, lower_brssi_thresh, rts_profile; 8108 bool enable_dtim_1chrx; 8109 QDF_STATUS status; 8110 struct hdd_context *hdd_ctx; 8111 bool is_lprx_enabled; 8112 bool bval = false; 8113 uint8_t enable_tx_sch_delay, dfs_chan_ageout_time; 8114 uint32_t dtim_sel_diversity, enable_secondary_rate; 8115 bool sap_xlna_bypass; 8116 bool enable_ofdm_scrambler_seed = false; 8117 struct dev_set_param setparam[MAX_PDEV_SET_FW_PARAMS] = { }; 8118 uint8_t index = 0; 8119 8120 hdd_enter_dev(adapter->dev); 8121 8122 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 8123 if (!hdd_ctx) 8124 return -EINVAL; 8125 8126 if (cds_get_conparam() == QDF_GLOBAL_FTM_MODE) { 8127 hdd_debug("FTM Mode is active; nothing to do"); 8128 return 0; 8129 } 8130 8131 /* The ini gEnableLPRx is deprecated. By default, the ini 8132 * is enabled. So, making the variable is_lprx_enabled true. 8133 */ 8134 is_lprx_enabled = true; 8135 8136 ret = mlme_check_index_setparam(setparam, wmi_pdev_param_dtim_synth, 8137 is_lprx_enabled, index++, 8138 MAX_PDEV_SET_FW_PARAMS); 8139 if (QDF_IS_STATUS_ERROR(ret)) 8140 goto error; 8141 8142 ucfg_mlme_get_dtim_selection_diversity(hdd_ctx->psoc, 8143 &dtim_sel_diversity); 8144 ret = mlme_check_index_setparam( 8145 setparam, 8146 wmi_pdev_param_1ch_dtim_optimized_chain_selection, 8147 dtim_sel_diversity, index++, MAX_PDEV_SET_FW_PARAMS); 8148 if (QDF_IS_STATUS_ERROR(ret)) 8149 goto error; 8150 8151 if (QDF_IS_STATUS_SUCCESS(ucfg_fwol_get_enable_tx_sch_delay( 8152 hdd_ctx->psoc, &enable_tx_sch_delay))) { 8153 ret = mlme_check_index_setparam( 8154 setparam, 8155 wmi_pdev_param_tx_sch_delay, 8156 enable_tx_sch_delay, index++, 8157 MAX_PDEV_SET_FW_PARAMS); 8158 if (QDF_IS_STATUS_ERROR(ret)) 8159 goto error; 8160 } 8161 8162 if (QDF_IS_STATUS_SUCCESS(ucfg_fwol_get_ofdm_scrambler_seed( 8163 hdd_ctx->psoc, &enable_ofdm_scrambler_seed))) { 8164 ret = mlme_check_index_setparam( 8165 setparam, 8166 wmi_pdev_param_en_update_scram_seed, 8167 enable_ofdm_scrambler_seed, index++, 8168 MAX_PDEV_SET_FW_PARAMS); 8169 if (QDF_IS_STATUS_ERROR(ret)) 8170 goto error; 8171 } 8172 8173 if (QDF_IS_STATUS_SUCCESS(ucfg_fwol_get_enable_secondary_rate( 8174 hdd_ctx->psoc, &enable_secondary_rate))) { 8175 ret = mlme_check_index_setparam( 8176 setparam, 8177 wmi_pdev_param_secondary_retry_enable, 8178 enable_secondary_rate, index++, 8179 MAX_PDEV_SET_FW_PARAMS); 8180 if (QDF_IS_STATUS_ERROR(ret)) 8181 goto error; 8182 } 8183 if (QDF_IS_STATUS_SUCCESS(ucfg_fwol_get_sap_xlna_bypass( 8184 hdd_ctx->psoc, &sap_xlna_bypass))) { 8185 ret = mlme_check_index_setparam( 8186 setparam, 8187 wmi_pdev_param_set_sap_xlna_bypass, 8188 sap_xlna_bypass, index++, 8189 MAX_PDEV_SET_FW_PARAMS); 8190 if (QDF_IS_STATUS_ERROR(ret)) 8191 goto error; 8192 } 8193 wlan_mlme_get_dfs_chan_ageout_time(hdd_ctx->psoc, 8194 &dfs_chan_ageout_time); 8195 ret = mlme_check_index_setparam( 8196 setparam, 8197 wmi_pdev_param_set_dfs_chan_ageout_time, 8198 dfs_chan_ageout_time, index++, 8199 MAX_PDEV_SET_FW_PARAMS); 8200 if (QDF_IS_STATUS_ERROR(ret)) 8201 goto error; 8202 8203 ret = sme_send_multi_pdev_vdev_set_params(MLME_PDEV_SETPARAM, 8204 WMI_PDEV_ID_SOC, setparam, 8205 index); 8206 if (QDF_IS_STATUS_ERROR(ret)) { 8207 goto error; 8208 } 8209 if (adapter->device_mode == QDF_STA_MODE) { 8210 status = ucfg_get_upper_brssi_thresh(hdd_ctx->psoc, 8211 &upper_brssi_thresh); 8212 if (QDF_IS_STATUS_ERROR(status)) 8213 return -EINVAL; 8214 8215 sme_set_smps_cfg(adapter->deflink->vdev_id, 8216 HDD_STA_SMPS_PARAM_UPPER_BRSSI_THRESH, 8217 upper_brssi_thresh); 8218 8219 status = ucfg_get_lower_brssi_thresh(hdd_ctx->psoc, 8220 &lower_brssi_thresh); 8221 if (QDF_IS_STATUS_ERROR(status)) 8222 return -EINVAL; 8223 8224 sme_set_smps_cfg(adapter->deflink->vdev_id, 8225 HDD_STA_SMPS_PARAM_LOWER_BRSSI_THRESH, 8226 lower_brssi_thresh); 8227 8228 status = ucfg_get_enable_dtim_1chrx(hdd_ctx->psoc, 8229 &enable_dtim_1chrx); 8230 if (QDF_IS_STATUS_ERROR(status)) 8231 return -EINVAL; 8232 8233 sme_set_smps_cfg(adapter->deflink->vdev_id, 8234 HDD_STA_SMPS_PARAM_DTIM_1CHRX_ENABLE, 8235 enable_dtim_1chrx); 8236 } 8237 8238 status = ucfg_mlme_get_vht_enable2x2(hdd_ctx->psoc, &bval); 8239 if (!QDF_IS_STATUS_SUCCESS(status)) 8240 hdd_err("unable to get vht_enable2x2"); 8241 8242 if (bval) { 8243 hdd_debug("configuring 2x2 mode fw params"); 8244 8245 ret = sme_set_cck_tx_fir_override(hdd_ctx->mac_handle, 8246 adapter->deflink->vdev_id); 8247 if (ret) { 8248 hdd_err("wmi_pdev_param_enable_cck_tfir_override set failed %d", 8249 ret); 8250 goto error; 8251 } 8252 8253 hdd_configure_chain_mask(adapter); 8254 } else { 8255 #define HDD_DTIM_1CHAIN_RX_ID 0x5 8256 #define HDD_SMPS_PARAM_VALUE_S 29 8257 hdd_debug("configuring 1x1 mode fw params"); 8258 8259 /* 8260 * Disable DTIM 1 chain Rx when in 1x1, 8261 * we are passing two value 8262 * as param_id << 29 | param_value. 8263 * Below param_value = 0(disable) 8264 */ 8265 ret = sme_cli_set_command(adapter->deflink->vdev_id, 8266 WMI_STA_SMPS_PARAM_CMDID, 8267 HDD_DTIM_1CHAIN_RX_ID << 8268 HDD_SMPS_PARAM_VALUE_S, 8269 VDEV_CMD); 8270 if (ret) { 8271 hdd_err("DTIM 1 chain set failed %d", ret); 8272 goto error; 8273 } 8274 8275 #undef HDD_DTIM_1CHAIN_RX_ID 8276 #undef HDD_SMPS_PARAM_VALUE_S 8277 8278 hdd_configure_chain_mask(adapter); 8279 } 8280 8281 ret = sme_set_enable_mem_deep_sleep(hdd_ctx->mac_handle, 8282 adapter->deflink->vdev_id); 8283 if (ret) { 8284 hdd_err("wmi_pdev_param_hyst_en set failed %d", ret); 8285 goto error; 8286 } 8287 8288 status = ucfg_fwol_get_rts_profile(hdd_ctx->psoc, &rts_profile); 8289 if (QDF_IS_STATUS_ERROR(status)) 8290 return -EINVAL; 8291 8292 ret = sme_cli_set_command(adapter->deflink->vdev_id, 8293 wmi_vdev_param_enable_rtscts, 8294 rts_profile, 8295 VDEV_CMD); 8296 if (ret) { 8297 hdd_err("FAILED TO SET RTSCTS Profile ret:%d", ret); 8298 goto error; 8299 } 8300 8301 if (!hdd_ctx->is_fw_dbg_log_levels_configured) { 8302 hdd_set_fw_log_params(hdd_ctx, adapter->deflink->vdev_id); 8303 hdd_ctx->is_fw_dbg_log_levels_configured = true; 8304 } 8305 8306 ret = hdd_send_coex_config_params(hdd_ctx, adapter); 8307 if (ret) { 8308 hdd_warn("Error initializing coex config params"); 8309 goto error; 8310 } 8311 8312 hdd_exit(); 8313 8314 return 0; 8315 8316 error: 8317 return -EINVAL; 8318 } 8319 8320 /** 8321 * hdd_init_completion() - Initialize Completion Variables 8322 * @adapter: HDD adapter 8323 * 8324 * This function Initialize the completion variables for 8325 * a particular adapter 8326 * 8327 * Return: None 8328 */ 8329 static void hdd_init_completion(struct hdd_adapter *adapter) 8330 { 8331 init_completion(&adapter->disconnect_comp_var); 8332 init_completion(&adapter->linkup_event_var); 8333 init_completion(&adapter->lfr_fw_status.disable_lfr_event); 8334 } 8335 8336 static void hdd_reset_locally_admin_bit(struct hdd_context *hdd_ctx, 8337 tSirMacAddr mac_addr) 8338 { 8339 int i; 8340 /* 8341 * Reset locally administered bit for dynamic_mac_list 8342 * also as while releasing the MAC address for any 8343 * interface mac will be compared with dynamic mac list 8344 */ 8345 for (i = 0; i < QDF_MAX_CONCURRENCY_PERSONA; i++) { 8346 if (!qdf_mem_cmp( 8347 mac_addr, 8348 &hdd_ctx-> 8349 dynamic_mac_list[i].dynamic_mac.bytes[0], 8350 sizeof(struct qdf_mac_addr))) { 8351 WLAN_HDD_RESET_LOCALLY_ADMINISTERED_BIT( 8352 hdd_ctx-> 8353 dynamic_mac_list[i].dynamic_mac.bytes); 8354 break; 8355 } 8356 } 8357 /* 8358 * Reset locally administered bit if the device mode is 8359 * STA 8360 */ 8361 WLAN_HDD_RESET_LOCALLY_ADMINISTERED_BIT(mac_addr); 8362 hdd_debug("locally administered bit reset in sta mode: " 8363 QDF_MAC_ADDR_FMT, QDF_MAC_ADDR_REF(mac_addr)); 8364 } 8365 8366 static void wlan_hdd_cfg80211_scan_block_cb(struct work_struct *work) 8367 { 8368 struct hdd_adapter *adapter = 8369 container_of(work, struct hdd_adapter, scan_block_work); 8370 struct osif_vdev_sync *vdev_sync; 8371 8372 if (osif_vdev_sync_op_start(adapter->dev, &vdev_sync)) 8373 return; 8374 8375 wlan_hdd_cfg80211_scan_block(adapter); 8376 8377 osif_vdev_sync_op_stop(vdev_sync); 8378 } 8379 8380 #if defined(WLAN_FEATURE_11BE_MLO) && \ 8381 defined(WLAN_HDD_MULTI_VDEV_SINGLE_NDEV) 8382 static inline void 8383 wlan_hdd_set_ml_cap_for_sap_intf(struct hdd_adapter_create_param *create_params, 8384 enum QDF_OPMODE mode) 8385 { 8386 if (mode != QDF_SAP_MODE) 8387 return; 8388 8389 create_params->is_ml_adapter = true; 8390 } 8391 #elif defined(WLAN_FEATURE_11BE_MLO) 8392 static inline void 8393 wlan_hdd_set_ml_cap_for_sap_intf(struct hdd_adapter_create_param *create_params, 8394 enum QDF_OPMODE mode) 8395 { 8396 if (mode != QDF_SAP_MODE) 8397 return; 8398 8399 create_params->is_ml_adapter = true; 8400 create_params->is_single_link = true; 8401 } 8402 #else 8403 static inline void 8404 wlan_hdd_set_ml_cap_for_sap_intf(struct hdd_adapter_create_param *create_params, 8405 enum QDF_OPMODE mode) 8406 { 8407 create_params->is_ml_adapter = false; 8408 } 8409 #endif /* WLAN_FEATURE_11BE_MLO */ 8410 8411 #if defined(WLAN_FEATURE_11BE_MLO) && defined(CFG80211_11BE_BASIC) && \ 8412 defined(WLAN_HDD_MULTI_VDEV_SINGLE_NDEV) 8413 void hdd_adapter_disable_all_links(struct hdd_adapter *adapter) 8414 { 8415 uint8_t idx_pos; 8416 struct wlan_hdd_link_info *link_info; 8417 8418 hdd_adapter_for_each_link_info(adapter, link_info) { 8419 qdf_zero_macaddr(&link_info->link_addr); 8420 idx_pos = hdd_adapter_get_index_of_link_info(link_info); 8421 adapter->curr_link_info_map[idx_pos] = idx_pos; 8422 } 8423 adapter->deflink = &adapter->link_info[WLAN_HDD_DEFLINK_IDX]; 8424 if (adapter->device_mode == QDF_STA_MODE) 8425 adapter->active_links = (1 << adapter->num_links_on_create) - 1; 8426 else 8427 adapter->active_links = 0x1; 8428 } 8429 #endif 8430 8431 static void hdd_adapter_enable_links(struct hdd_adapter *adapter, 8432 struct hdd_adapter_create_param *params) 8433 { 8434 uint8_t num, link_idx; 8435 8436 /* Default link is already set on adapter allocation, only 8437 * enable other links if requested links is greater than 1 8438 */ 8439 if (params->num_sessions <= 1) { 8440 adapter->num_links_on_create = 1; 8441 return; 8442 } 8443 8444 num = QDF_MIN(params->num_sessions, WLAN_MAX_MLD); 8445 for (link_idx = WLAN_HDD_DEFLINK_IDX; link_idx < num; link_idx++) 8446 qdf_atomic_set_bit(link_idx, &adapter->active_links); 8447 8448 adapter->num_links_on_create = num; 8449 } 8450 8451 static void hdd_adapter_init_link_info(struct hdd_adapter *adapter) 8452 { 8453 uint8_t idx_pos; 8454 struct wlan_hdd_link_info *link_info; 8455 8456 /* Initialize each member in link info array to default values */ 8457 hdd_adapter_for_each_link_info(adapter, link_info) { 8458 link_info->adapter = adapter; 8459 link_info->vdev_id = WLAN_UMAC_VDEV_ID_MAX; 8460 qdf_spinlock_create(&link_info->vdev_lock); 8461 init_completion(&link_info->vdev_destroy_event); 8462 qdf_event_create(&link_info->acs_complete_event); 8463 8464 idx_pos = hdd_adapter_get_index_of_link_info(link_info); 8465 adapter->curr_link_info_map[idx_pos] = idx_pos; 8466 } 8467 } 8468 8469 /** 8470 * hdd_open_adapter() - open and setup the hdd adapter 8471 * @hdd_ctx: global hdd context 8472 * @session_type: type of the interface to be created 8473 * @iface_name: User-visible name of the interface 8474 * @mac_addr: MAC address to assign to the interface 8475 * @name_assign_type: the name of assign type of the netdev 8476 * @rtnl_held: the rtnl lock hold flag 8477 * @params: adapter create params 8478 * 8479 * This function open and setup the hdd adapter according to the device 8480 * type request, assign the name, the mac address assigned, and then prepared 8481 * the hdd related parameters, queue, lock and ready to start. 8482 * 8483 * Return: the pointer of hdd adapter, otherwise NULL. 8484 */ 8485 struct hdd_adapter *hdd_open_adapter(struct hdd_context *hdd_ctx, 8486 uint8_t session_type, 8487 const char *iface_name, 8488 tSirMacAddr mac_addr, 8489 unsigned char name_assign_type, 8490 bool rtnl_held, 8491 struct hdd_adapter_create_param *params) 8492 { 8493 struct net_device *ndev = NULL; 8494 struct hdd_adapter *adapter = NULL, *sta_adapter = NULL; 8495 QDF_STATUS status = QDF_STATUS_E_FAILURE; 8496 uint32_t i; 8497 bool eht_capab = 0; 8498 8499 status = wlan_hdd_validate_mac_address((struct qdf_mac_addr *)mac_addr); 8500 if (QDF_IS_STATUS_ERROR(status)) { 8501 /* Not received valid mac_addr */ 8502 hdd_err("Unable to add virtual intf: Not able to get valid mac address"); 8503 return NULL; 8504 } 8505 8506 status = hdd_check_for_existing_macaddr(hdd_ctx, mac_addr); 8507 if (QDF_STATUS_E_FAILURE == status) { 8508 hdd_err("Duplicate MAC addr: " QDF_MAC_ADDR_FMT 8509 " already exists", 8510 QDF_MAC_ADDR_REF(mac_addr)); 8511 return NULL; 8512 } 8513 8514 if (params->only_wdev_register) { 8515 sta_adapter = hdd_get_ml_adapter(hdd_ctx); 8516 if (!sta_adapter) { 8517 hdd_err("not able to find the sta adapter"); 8518 return NULL; 8519 } 8520 } 8521 8522 switch (session_type) { 8523 case QDF_STA_MODE: 8524 if (!(hdd_ctx->config->mac_provision || 8525 params->only_wdev_register)) { 8526 hdd_reset_locally_admin_bit(hdd_ctx, mac_addr); 8527 /* 8528 * After resetting locally administered bit 8529 * again check if the new mac address is already 8530 * exists. 8531 */ 8532 status = hdd_check_for_existing_macaddr(hdd_ctx, 8533 mac_addr); 8534 if (QDF_STATUS_E_FAILURE == status) { 8535 hdd_err("Duplicate MAC addr: " QDF_MAC_ADDR_FMT 8536 " already exists", 8537 QDF_MAC_ADDR_REF(mac_addr)); 8538 return NULL; 8539 } 8540 } 8541 8542 fallthrough; 8543 case QDF_P2P_CLIENT_MODE: 8544 case QDF_P2P_DEVICE_MODE: 8545 case QDF_OCB_MODE: 8546 case QDF_NDI_MODE: 8547 case QDF_MONITOR_MODE: 8548 case QDF_NAN_DISC_MODE: 8549 adapter = hdd_alloc_station_adapter(hdd_ctx, mac_addr, 8550 name_assign_type, 8551 iface_name, session_type); 8552 8553 if (!adapter) { 8554 hdd_err("failed to allocate adapter for session %d", 8555 session_type); 8556 return NULL; 8557 } 8558 8559 ndev = adapter->dev; 8560 8561 status = ucfg_dp_create_intf(hdd_ctx->psoc, &adapter->mac_addr, 8562 (qdf_netdev_t)adapter->dev); 8563 if (QDF_IS_STATUS_ERROR(status)) 8564 goto err_free_netdev; 8565 8566 if (QDF_P2P_CLIENT_MODE == session_type) 8567 adapter->wdev.iftype = NL80211_IFTYPE_P2P_CLIENT; 8568 else if (QDF_P2P_DEVICE_MODE == session_type) 8569 adapter->wdev.iftype = NL80211_IFTYPE_P2P_DEVICE; 8570 else if (QDF_MONITOR_MODE == session_type) 8571 adapter->wdev.iftype = NL80211_IFTYPE_MONITOR; 8572 else if (QDF_NAN_DISC_MODE == session_type) 8573 wlan_hdd_set_nan_if_type(adapter); 8574 else 8575 adapter->wdev.iftype = NL80211_IFTYPE_STATION; 8576 8577 adapter->device_mode = session_type; 8578 8579 8580 /* 8581 * Workqueue which gets scheduled in IPv4 notification 8582 * callback 8583 */ 8584 INIT_WORK(&adapter->ipv4_notifier_work, 8585 hdd_ipv4_notifier_work_queue); 8586 8587 #ifdef WLAN_NS_OFFLOAD 8588 /* 8589 * Workqueue which gets scheduled in IPv6 8590 * notification callback. 8591 */ 8592 INIT_WORK(&adapter->ipv6_notifier_work, 8593 hdd_ipv6_notifier_work_queue); 8594 #endif 8595 if (params->only_wdev_register) { 8596 hdd_register_wdev(sta_adapter, adapter, params); 8597 } else { 8598 status = hdd_register_interface(adapter, rtnl_held, 8599 params); 8600 if (QDF_STATUS_SUCCESS != status) 8601 goto err_destroy_dp_intf; 8602 /* Stop the Interface TX queue. */ 8603 hdd_debug("Disabling queues"); 8604 wlan_hdd_netif_queue_control(adapter, 8605 WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER, 8606 WLAN_CONTROL_PATH); 8607 } 8608 break; 8609 case QDF_P2P_GO_MODE: 8610 case QDF_SAP_MODE: 8611 adapter = hdd_wlan_create_ap_dev(hdd_ctx, mac_addr, 8612 name_assign_type, 8613 (uint8_t *) iface_name); 8614 if (!adapter) { 8615 hdd_err("failed to allocate adapter for session %d", 8616 session_type); 8617 return NULL; 8618 } 8619 8620 ndev = adapter->dev; 8621 8622 status = ucfg_dp_create_intf(hdd_ctx->psoc, &adapter->mac_addr, 8623 (qdf_netdev_t)adapter->dev); 8624 if (QDF_IS_STATUS_ERROR(status)) 8625 goto err_free_netdev; 8626 8627 adapter->wdev.iftype = 8628 (session_type == 8629 QDF_SAP_MODE) ? NL80211_IFTYPE_AP : 8630 NL80211_IFTYPE_P2P_GO; 8631 adapter->device_mode = session_type; 8632 8633 status = hdd_register_interface(adapter, rtnl_held, params); 8634 if (QDF_STATUS_SUCCESS != status) 8635 goto err_destroy_dp_intf; 8636 8637 hdd_debug("Disabling queues"); 8638 wlan_hdd_netif_queue_control(adapter, 8639 WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER, 8640 WLAN_CONTROL_PATH); 8641 8642 /* 8643 * Workqueue which gets scheduled in IPv4 notification 8644 * callback 8645 */ 8646 INIT_WORK(&adapter->ipv4_notifier_work, 8647 hdd_ipv4_notifier_work_queue); 8648 8649 #ifdef WLAN_NS_OFFLOAD 8650 /* 8651 * Workqueue which gets scheduled in IPv6 8652 * notification callback. 8653 */ 8654 INIT_WORK(&adapter->ipv6_notifier_work, 8655 hdd_ipv6_notifier_work_queue); 8656 #endif 8657 wlan_hdd_set_ml_cap_for_sap_intf(params, session_type); 8658 break; 8659 case QDF_FTM_MODE: 8660 adapter = hdd_alloc_station_adapter(hdd_ctx, mac_addr, 8661 name_assign_type, 8662 iface_name, session_type); 8663 if (!adapter) { 8664 hdd_err("Failed to allocate adapter for FTM mode"); 8665 return NULL; 8666 } 8667 8668 ndev = adapter->dev; 8669 8670 status = ucfg_dp_create_intf(hdd_ctx->psoc, &adapter->mac_addr, 8671 (qdf_netdev_t)adapter->dev); 8672 if (QDF_IS_STATUS_ERROR(status)) 8673 goto err_free_netdev; 8674 8675 adapter->wdev.iftype = NL80211_IFTYPE_STATION; 8676 adapter->device_mode = session_type; 8677 status = hdd_register_interface(adapter, rtnl_held, params); 8678 if (QDF_STATUS_SUCCESS != status) 8679 goto err_destroy_dp_intf; 8680 8681 /* Stop the Interface TX queue. */ 8682 hdd_debug("Disabling queues"); 8683 wlan_hdd_netif_queue_control(adapter, 8684 WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER, 8685 WLAN_CONTROL_PATH); 8686 8687 break; 8688 default: 8689 hdd_err("Invalid session type %d", session_type); 8690 QDF_ASSERT(0); 8691 return NULL; 8692 } 8693 8694 hdd_adapter_init_link_info(adapter); 8695 hdd_adapter_enable_links(adapter, params); 8696 8697 ucfg_psoc_mlme_get_11be_capab(hdd_ctx->psoc, &eht_capab); 8698 if (params->is_ml_adapter && eht_capab) { 8699 hdd_adapter_set_ml_adapter(adapter); 8700 if (params->is_single_link) 8701 hdd_adapter_set_sl_ml_adapter(adapter); 8702 } 8703 8704 status = hdd_adapter_feature_update_work_init(adapter); 8705 if (QDF_IS_STATUS_ERROR(status)) 8706 goto err_cleanup_adapter; 8707 8708 adapter->upgrade_udp_qos_threshold = QCA_WLAN_AC_BK; 8709 8710 hdd_init_completion(adapter); 8711 INIT_WORK(&adapter->scan_block_work, wlan_hdd_cfg80211_scan_block_cb); 8712 INIT_WORK(&adapter->sap_stop_bss_work, 8713 hdd_stop_sap_due_to_invalid_channel); 8714 qdf_list_create(&adapter->blocked_scan_request_q, WLAN_MAX_SCAN_COUNT); 8715 qdf_mutex_create(&adapter->blocked_scan_request_q_lock); 8716 qdf_spinlock_create(&adapter->mc_list_lock); 8717 qdf_event_create(&adapter->peer_cleanup_done); 8718 hdd_sta_info_init(&adapter->sta_info_list); 8719 hdd_sta_info_init(&adapter->cache_sta_info_list); 8720 8721 for (i = 0; i < NET_DEV_HOLD_ID_MAX; i++) 8722 qdf_atomic_init( 8723 &adapter->net_dev_hold_ref_count[NET_DEV_HOLD_ID_MAX]); 8724 8725 /* Add it to the hdd's session list. */ 8726 status = hdd_add_adapter_back(hdd_ctx, adapter); 8727 if (QDF_STATUS_SUCCESS != status) 8728 goto err_destroy_adapter_features_update_work; 8729 8730 hdd_apf_context_init(adapter); 8731 8732 policy_mgr_set_concurrency_mode(hdd_ctx->psoc, session_type); 8733 8734 if (QDF_STATUS_SUCCESS != hdd_debugfs_init(adapter)) 8735 hdd_err("debugfs: Interface %s init failed", 8736 netdev_name(adapter->dev)); 8737 8738 hdd_debug("%s interface created. iftype: %d", netdev_name(adapter->dev), 8739 session_type); 8740 8741 if (adapter->device_mode == QDF_STA_MODE) 8742 wlan_hdd_debugfs_csr_init(adapter); 8743 8744 return adapter; 8745 8746 err_destroy_adapter_features_update_work: 8747 hdd_adapter_feature_update_work_deinit(adapter); 8748 8749 err_cleanup_adapter: 8750 if (adapter) { 8751 hdd_cleanup_adapter(hdd_ctx, adapter, rtnl_held); 8752 adapter = NULL; 8753 } 8754 8755 err_destroy_dp_intf: 8756 ucfg_dp_destroy_intf(hdd_ctx->psoc, &adapter->mac_addr); 8757 8758 err_free_netdev: 8759 if (ndev) 8760 free_netdev(ndev); 8761 8762 return NULL; 8763 } 8764 8765 static void __hdd_close_adapter(struct hdd_context *hdd_ctx, 8766 struct hdd_adapter *adapter, 8767 bool rtnl_held) 8768 { 8769 struct qdf_mac_addr adapter_mac; 8770 struct wlan_hdd_link_info *link_info; 8771 8772 8773 qdf_copy_macaddr(&adapter_mac, &adapter->mac_addr); 8774 if (adapter->device_mode == QDF_STA_MODE) { 8775 hdd_adapter_for_each_link_info(adapter, link_info) 8776 hdd_cleanup_conn_info(link_info); 8777 } 8778 qdf_list_destroy(&adapter->blocked_scan_request_q); 8779 qdf_mutex_destroy(&adapter->blocked_scan_request_q_lock); 8780 policy_mgr_clear_concurrency_mode(hdd_ctx->psoc, adapter->device_mode); 8781 qdf_event_destroy(&adapter->peer_cleanup_done); 8782 hdd_adapter_feature_update_work_deinit(adapter); 8783 hdd_cleanup_adapter(hdd_ctx, adapter, rtnl_held); 8784 ucfg_dp_destroy_intf(hdd_ctx->psoc, &adapter_mac); 8785 } 8786 8787 void hdd_close_adapter(struct hdd_context *hdd_ctx, 8788 struct hdd_adapter *adapter, 8789 bool rtnl_held) 8790 { 8791 /* 8792 * Stop the global bus bandwidth timer while touching the adapter list 8793 * to avoid bad memory access by the timer handler. 8794 */ 8795 ucfg_dp_bus_bw_compute_timer_stop(hdd_ctx->psoc); 8796 8797 hdd_check_for_net_dev_ref_leak(adapter); 8798 hdd_remove_adapter(hdd_ctx, adapter); 8799 __hdd_close_adapter(hdd_ctx, adapter, rtnl_held); 8800 8801 /* conditionally restart the bw timer */ 8802 ucfg_dp_bus_bw_compute_timer_try_start(hdd_ctx->psoc); 8803 } 8804 8805 void hdd_close_all_adapters(struct hdd_context *hdd_ctx, bool rtnl_held) 8806 { 8807 struct hdd_adapter *adapter; 8808 struct osif_vdev_sync *vdev_sync; 8809 QDF_STATUS qdf_status; 8810 8811 hdd_enter(); 8812 8813 while (QDF_IS_STATUS_SUCCESS(hdd_get_front_adapter( 8814 hdd_ctx, &adapter))) { 8815 /* If MLO is enabled unregister the link wdev's */ 8816 if (adapter->device_mode == QDF_STA_MODE || 8817 adapter->device_mode == QDF_SAP_MODE) { 8818 qdf_status = hdd_wlan_unregister_mlo_interfaces(adapter, 8819 rtnl_held); 8820 if (QDF_IS_STATUS_ERROR(qdf_status)) 8821 continue; 8822 } 8823 8824 hdd_check_for_net_dev_ref_leak(adapter); 8825 hdd_remove_front_adapter(hdd_ctx, &adapter); 8826 vdev_sync = osif_vdev_sync_unregister(adapter->dev); 8827 if (vdev_sync) 8828 osif_vdev_sync_wait_for_ops(vdev_sync); 8829 8830 wlan_hdd_release_intf_addr(hdd_ctx, adapter->mac_addr.bytes); 8831 __hdd_close_adapter(hdd_ctx, adapter, rtnl_held); 8832 8833 if (vdev_sync) 8834 osif_vdev_sync_destroy(vdev_sync); 8835 } 8836 8837 hdd_exit(); 8838 } 8839 8840 void wlan_hdd_reset_prob_rspies(struct wlan_hdd_link_info *link_info) 8841 { 8842 struct qdf_mac_addr *bssid = NULL; 8843 tSirUpdateIE update_ie; 8844 mac_handle_t mac_handle; 8845 struct hdd_adapter *adapter = link_info->adapter; 8846 8847 switch (adapter->device_mode) { 8848 case QDF_STA_MODE: 8849 case QDF_P2P_CLIENT_MODE: 8850 { 8851 struct hdd_station_ctx *sta_ctx = 8852 WLAN_HDD_GET_STATION_CTX_PTR(link_info); 8853 bssid = &sta_ctx->conn_info.bssid; 8854 break; 8855 } 8856 case QDF_SAP_MODE: 8857 case QDF_P2P_GO_MODE: 8858 { 8859 bssid = &adapter->mac_addr; 8860 break; 8861 } 8862 case QDF_FTM_MODE: 8863 case QDF_P2P_DEVICE_MODE: 8864 default: 8865 /* 8866 * wlan_hdd_reset_prob_rspies should not have been called 8867 * for these kind of devices 8868 */ 8869 hdd_err("Unexpected request for the current device type %d", 8870 adapter->device_mode); 8871 return; 8872 } 8873 8874 qdf_copy_macaddr(&update_ie.bssid, bssid); 8875 update_ie.vdev_id = link_info->vdev_id; 8876 update_ie.ieBufferlength = 0; 8877 update_ie.pAdditionIEBuffer = NULL; 8878 update_ie.append = true; 8879 update_ie.notify = false; 8880 mac_handle = hdd_adapter_get_mac_handle(adapter); 8881 if (sme_update_add_ie(mac_handle, 8882 &update_ie, 8883 eUPDATE_IE_PROBE_RESP) == QDF_STATUS_E_FAILURE) { 8884 hdd_err("Could not pass on PROBE_RSP_BCN data to PE"); 8885 } 8886 } 8887 8888 /** 8889 * hdd_ipa_ap_disconnect_evt() - Indicate wlan ipa ap disconnect event 8890 * @hdd_ctx: hdd context 8891 * @adapter: hdd adapter 8892 * 8893 * Return: None 8894 */ 8895 static inline 8896 void hdd_ipa_ap_disconnect_evt(struct hdd_context *hdd_ctx, 8897 struct hdd_adapter *adapter) 8898 { 8899 if (ucfg_ipa_is_enabled()) { 8900 ucfg_ipa_uc_disconnect_ap(hdd_ctx->pdev, 8901 adapter->dev); 8902 ucfg_ipa_cleanup_dev_iface(hdd_ctx->pdev, 8903 adapter->dev); 8904 } 8905 } 8906 8907 #ifdef WLAN_FEATURE_NAN 8908 /** 8909 * hdd_ndp_state_cleanup() - API to set NDP state to Disconnected 8910 * @psoc: pointer to psoc object 8911 * @ndi_vdev_id: vdev_id of the NDI 8912 * 8913 * Return: None 8914 */ 8915 static void 8916 hdd_ndp_state_cleanup(struct wlan_objmgr_psoc *psoc, uint8_t ndi_vdev_id) 8917 { 8918 struct wlan_objmgr_vdev *ndi_vdev; 8919 8920 ndi_vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, ndi_vdev_id, 8921 WLAN_NAN_ID); 8922 if (!ndi_vdev) { 8923 hdd_err("Cannot obtain NDI vdev object!"); 8924 return; 8925 } 8926 8927 ucfg_nan_set_ndi_state(ndi_vdev, NAN_DATA_DISCONNECTED_STATE); 8928 8929 wlan_objmgr_vdev_release_ref(ndi_vdev, WLAN_NAN_ID); 8930 } 8931 8932 /** 8933 * hdd_peer_cleanup() - This API will delete NDP peer if exist and modifies 8934 * the NDP state. 8935 * @link_info: Link info pointer in HDD adapter 8936 * 8937 * Return: None 8938 */ 8939 static void hdd_peer_cleanup(struct wlan_hdd_link_info *link_info) 8940 { 8941 QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE; 8942 struct hdd_adapter *adapter = link_info->adapter; 8943 struct hdd_context *hdd_ctx = adapter->hdd_ctx; 8944 8945 /* Check if there is any peer present on the adapter */ 8946 if (!hdd_any_valid_peer_present(link_info)) { 8947 /* 8948 * No peers are connected to the NDI. So, set the NDI state to 8949 * DISCONNECTED. If there are any peers, ucfg_nan_disable_ndi() 8950 * would take care of cleanup all the peers and setting the 8951 * state to DISCONNECTED. 8952 */ 8953 hdd_ndp_state_cleanup(hdd_ctx->psoc, link_info->vdev_id); 8954 return; 8955 } 8956 8957 if (adapter->device_mode == QDF_NDI_MODE) 8958 qdf_status = ucfg_nan_disable_ndi(hdd_ctx->psoc, 8959 link_info->vdev_id); 8960 8961 if (QDF_IS_STATUS_ERROR(qdf_status)) 8962 return; 8963 8964 qdf_status = qdf_wait_for_event_completion(&adapter->peer_cleanup_done, 8965 WLAN_WAIT_PEER_CLEANUP); 8966 if (QDF_IS_STATUS_ERROR(qdf_status)) 8967 hdd_debug("peer_cleanup_done wait fail"); 8968 } 8969 #else 8970 static inline void 8971 hdd_ndp_state_cleanup(struct wlan_objmgr_psoc *psoc, uint8_t ndi_vdev_id) 8972 { 8973 } 8974 8975 static inline void 8976 hdd_ndp_peer_cleanup(struct hdd_context *hdd_ctx, struct hdd_adapter *adapter) 8977 { 8978 } 8979 8980 static inline void hdd_peer_cleanup(struct wlan_hdd_link_info *link_info) 8981 { 8982 } 8983 #endif /* WLAN_FEATURE_NAN */ 8984 8985 #ifdef FUNC_CALL_MAP 8986 8987 /** 8988 * hdd_dump_func_call_map() - Dump the function call map 8989 * 8990 * Return: None 8991 */ 8992 8993 static void hdd_dump_func_call_map(void) 8994 { 8995 char *cc_buf; 8996 8997 cc_buf = qdf_mem_malloc(QDF_FUNCTION_CALL_MAP_BUF_LEN); 8998 /* 8999 * These logs are required as these indicates the start and end of the 9000 * dump for the auto script to parse 9001 */ 9002 hdd_info("Function call map dump start"); 9003 qdf_get_func_call_map(cc_buf); 9004 qdf_trace_hex_dump(QDF_MODULE_ID_HDD, 9005 QDF_TRACE_LEVEL_DEBUG, cc_buf, QDF_FUNCTION_CALL_MAP_BUF_LEN); 9006 hdd_info("Function call map dump end"); 9007 qdf_mem_free(cc_buf); 9008 } 9009 #else 9010 static inline void hdd_dump_func_call_map(void) 9011 { 9012 } 9013 #endif 9014 9015 static void hdd_reset_scan_operation(struct wlan_hdd_link_info *link_info) 9016 { 9017 switch (link_info->adapter->device_mode) { 9018 case QDF_STA_MODE: 9019 case QDF_P2P_CLIENT_MODE: 9020 case QDF_P2P_DEVICE_MODE: 9021 case QDF_NDI_MODE: 9022 wlan_hdd_scan_abort(link_info); 9023 wlan_hdd_cleanup_remain_on_channel_ctx(link_info); 9024 if (link_info->adapter->device_mode == QDF_STA_MODE) { 9025 struct wlan_objmgr_vdev *vdev; 9026 9027 vdev = hdd_objmgr_get_vdev_by_user(link_info, 9028 WLAN_OSIF_SCAN_ID); 9029 if (!vdev) 9030 break; 9031 9032 wlan_cfg80211_sched_scan_stop(vdev); 9033 hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_SCAN_ID); 9034 } 9035 break; 9036 case QDF_P2P_GO_MODE: 9037 wlan_hdd_cleanup_remain_on_channel_ctx(link_info); 9038 break; 9039 case QDF_SAP_MODE: 9040 qdf_atomic_set(&link_info->session.ap.acs_in_progress, 0); 9041 break; 9042 default: 9043 break; 9044 } 9045 } 9046 9047 #ifdef WLAN_OPEN_SOURCE 9048 void hdd_cancel_ip_notifier_work(struct hdd_adapter *adapter) 9049 { 9050 cancel_work_sync(&adapter->ipv4_notifier_work); 9051 #ifdef WLAN_NS_OFFLOAD 9052 cancel_work_sync(&adapter->ipv6_notifier_work); 9053 #endif 9054 } 9055 #endif 9056 9057 void hdd_adapter_deregister_fc(struct hdd_adapter *adapter) 9058 { 9059 hdd_deregister_hl_netdev_fc_timer(adapter); 9060 hdd_deregister_tx_flow_control(adapter); 9061 } 9062 9063 static void hdd_stop_and_cleanup_ndi(struct wlan_hdd_link_info *link_info) 9064 { 9065 QDF_STATUS status; 9066 unsigned long rc; 9067 struct hdd_adapter *adapter = link_info->adapter; 9068 struct hdd_context *hdd_ctx = adapter->hdd_ctx; 9069 9070 /* For NDI do not use roam_profile */ 9071 INIT_COMPLETION(adapter->disconnect_comp_var); 9072 hdd_peer_cleanup(link_info); 9073 status = sme_roam_ndi_stop(hdd_ctx->mac_handle, link_info->vdev_id); 9074 if (QDF_IS_STATUS_SUCCESS(status)) { 9075 rc = wait_for_completion_timeout( 9076 &adapter->disconnect_comp_var, 9077 msecs_to_jiffies(SME_CMD_STOP_BSS_TIMEOUT)); 9078 if (!rc) 9079 hdd_warn("disconn_comp_var wait fail"); 9080 hdd_cleanup_ndi(link_info); 9081 } 9082 } 9083 9084 static void 9085 hdd_sta_disconnect_and_cleanup(struct wlan_hdd_link_info *link_info) 9086 { 9087 QDF_STATUS status; 9088 enum wlan_reason_code reason; 9089 struct hdd_adapter *adapter = link_info->adapter; 9090 9091 /* 9092 * On vdev delete wait for disconnect to 9093 * complete. i.e use sync API, so that the 9094 * vdev ref of MLME are cleaned and disconnect 9095 * complete before vdev is moved to logically 9096 * deleted. 9097 */ 9098 if (cds_is_driver_recovering()) 9099 reason = REASON_DEVICE_RECOVERY; 9100 else 9101 reason = REASON_IFACE_DOWN; 9102 9103 status = wlan_hdd_cm_issue_disconnect(link_info, reason, true); 9104 if (QDF_IS_STATUS_ERROR(status) && ucfg_ipa_is_enabled()) { 9105 hdd_err("STA disconnect failed"); 9106 ucfg_ipa_uc_cleanup_sta(adapter->hdd_ctx->pdev, adapter->dev); 9107 } 9108 } 9109 9110 static void 9111 hdd_disable_nan_active_disc(struct hdd_adapter *adapter) 9112 { 9113 struct hdd_context *hdd_ctx = adapter->hdd_ctx; 9114 enum QDF_OPMODE device_mode = adapter->device_mode; 9115 9116 if ((device_mode == QDF_NAN_DISC_MODE || 9117 (device_mode == QDF_STA_MODE && 9118 !ucfg_nan_is_vdev_creation_allowed(hdd_ctx->psoc))) && 9119 ucfg_is_nan_conc_control_supported(hdd_ctx->psoc) && 9120 ucfg_is_nan_disc_active(hdd_ctx->psoc)) 9121 ucfg_disable_nan_discovery(hdd_ctx->psoc, NULL, 0); 9122 } 9123 9124 static void 9125 hdd_monitor_mode_release_wakelock(struct wlan_hdd_link_info *link_info) 9126 { 9127 struct hdd_adapter *adapter = link_info->adapter; 9128 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); 9129 9130 if (wlan_hdd_is_session_type_monitor(adapter->device_mode) && 9131 (ucfg_mlme_is_sta_mon_conc_supported(hdd_ctx->psoc) || 9132 ucfg_dp_is_local_pkt_capture_enabled(hdd_ctx->psoc))) { 9133 hdd_info("Release wakelock for STA + monitor mode!"); 9134 os_if_dp_local_pkt_capture_stop(link_info->vdev); 9135 qdf_runtime_pm_allow_suspend( 9136 &hdd_ctx->runtime_context.monitor_mode); 9137 hdd_lpc_enable_powersave(hdd_ctx); 9138 qdf_wake_lock_release(&hdd_ctx->monitor_mode_wakelock, 9139 WIFI_POWER_EVENT_WAKELOCK_MONITOR_MODE); 9140 } 9141 } 9142 9143 static void 9144 hdd_monitor_mode_disable_and_delete(struct wlan_hdd_link_info *link_info) 9145 { 9146 QDF_STATUS status; 9147 struct hdd_adapter *adapter = link_info->adapter; 9148 struct hdd_context *hdd_ctx = adapter->hdd_ctx; 9149 9150 status = hdd_disable_monitor_mode(); 9151 if (QDF_IS_STATUS_ERROR(status)) 9152 hdd_err_rl("datapath reset failed for montior mode"); 9153 hdd_set_idle_ps_config(hdd_ctx, true); 9154 status = hdd_monitor_mode_vdev_status(adapter); 9155 if (QDF_IS_STATUS_ERROR(status)) 9156 hdd_err_rl("stop failed montior mode"); 9157 sme_delete_mon_session(hdd_ctx->mac_handle, link_info->vdev_id); 9158 } 9159 9160 static void 9161 hdd_stop_and_close_pre_cac_adapter(struct hdd_context *hdd_ctx, 9162 struct wlan_objmgr_vdev *vdev) 9163 { 9164 if (!vdev) 9165 return; 9166 9167 if (!ucfg_pre_cac_adapter_is_active(vdev)) { 9168 ucfg_pre_cac_stop(hdd_ctx->psoc); 9169 hdd_close_pre_cac_adapter(hdd_ctx); 9170 } else { 9171 if (ucfg_pre_cac_set_status(vdev, false)) 9172 hdd_err("Failed to set is_pre_cac_on to false"); 9173 } 9174 } 9175 9176 static void hdd_reset_ies_on_sap_stop(struct wlan_hdd_link_info *link_info) 9177 { 9178 mac_handle_t mac_handle; 9179 tSirUpdateIE update_ie; 9180 QDF_STATUS status; 9181 struct hdd_adapter *adapter = link_info->adapter; 9182 9183 mac_handle = hdd_adapter_get_mac_handle(adapter); 9184 update_ie.vdev_id = link_info->vdev_id; 9185 update_ie.ieBufferlength = 0; 9186 update_ie.pAdditionIEBuffer = NULL; 9187 update_ie.append = false; 9188 update_ie.notify = false; 9189 9190 /* Probe bcn reset */ 9191 status = sme_update_add_ie(mac_handle, &update_ie, 9192 eUPDATE_IE_PROBE_BCN); 9193 if (status == QDF_STATUS_E_FAILURE) 9194 hdd_err("Could not pass PROBE_RSP_BCN to PE"); 9195 9196 /* Assoc resp reset */ 9197 status = sme_update_add_ie(mac_handle, &update_ie, 9198 eUPDATE_IE_ASSOC_RESP); 9199 if (status == QDF_STATUS_E_FAILURE) 9200 hdd_err("Could not pass ASSOC_RSP to PE"); 9201 9202 /* Reset WNI_CFG_PROBE_RSP Flags */ 9203 wlan_hdd_reset_prob_rspies(link_info); 9204 } 9205 9206 static void hdd_stop_station_adapter(struct hdd_adapter *adapter) 9207 { 9208 struct wlan_objmgr_vdev *vdev; 9209 enum QDF_OPMODE mode; 9210 struct wlan_hdd_link_info *link_info; 9211 9212 mode = adapter->device_mode; 9213 hdd_adapter_for_each_active_link_info(adapter, link_info) { 9214 vdev = hdd_objmgr_get_vdev_by_user(link_info, 9215 WLAN_INIT_DEINIT_ID); 9216 if (!vdev) 9217 continue; 9218 9219 if (mode == QDF_NDI_MODE) 9220 hdd_stop_and_cleanup_ndi(link_info); 9221 else if (!hdd_cm_is_disconnected(link_info)) 9222 hdd_sta_disconnect_and_cleanup(link_info); 9223 9224 hdd_reset_scan_operation(link_info); 9225 wlan_hdd_cleanup_actionframe(link_info); 9226 wlan_hdd_flush_pmksa_cache(link_info); 9227 9228 if (mode == QDF_STA_MODE) 9229 ucfg_ipa_flush_pending_vdev_events( 9230 wlan_vdev_get_pdev(vdev), 9231 link_info->vdev_id); 9232 hdd_objmgr_put_vdev_by_user(vdev, WLAN_INIT_DEINIT_ID); 9233 hdd_vdev_destroy(link_info); 9234 } 9235 9236 hdd_disable_nan_active_disc(adapter); 9237 hdd_adapter_deregister_fc(adapter); 9238 hdd_cancel_ip_notifier_work(adapter); 9239 } 9240 9241 static int hdd_stop_mon_adapter(struct hdd_adapter *adapter) 9242 { 9243 struct wlan_objmgr_vdev *vdev; 9244 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); 9245 struct wlan_hdd_link_info *link_info = adapter->deflink; 9246 9247 vdev = hdd_objmgr_get_vdev_by_user(link_info, 9248 WLAN_INIT_DEINIT_ID); 9249 if (wlan_hdd_is_session_type_monitor(adapter->device_mode) && 9250 vdev && 9251 ucfg_pkt_capture_get_mode(hdd_ctx->psoc) != 9252 PACKET_CAPTURE_MODE_DISABLE) { 9253 struct hdd_adapter *sta_adapter; 9254 9255 ucfg_pkt_capture_deregister_callbacks(vdev); 9256 hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_ID); 9257 link_info->vdev = NULL; 9258 9259 sta_adapter = hdd_get_adapter(hdd_ctx, QDF_STA_MODE); 9260 if (!sta_adapter) { 9261 hdd_objmgr_put_vdev_by_user(vdev, WLAN_INIT_DEINIT_ID); 9262 hdd_err("No station interface found"); 9263 return -EINVAL; 9264 } 9265 hdd_reset_monitor_interface(sta_adapter); 9266 } 9267 9268 hdd_monitor_mode_release_wakelock(link_info); 9269 wlan_hdd_scan_abort(link_info); 9270 hdd_adapter_deregister_fc(adapter); 9271 hdd_monitor_mode_disable_and_delete(link_info); 9272 if (vdev) 9273 hdd_objmgr_put_vdev_by_user(vdev, WLAN_INIT_DEINIT_ID); 9274 9275 hdd_vdev_destroy(link_info); 9276 9277 return 0; 9278 } 9279 9280 static void hdd_stop_sap_go_adapter(struct hdd_adapter *adapter) 9281 { 9282 enum QDF_OPMODE mode; 9283 struct hdd_ap_ctx *ap_ctx; 9284 struct sap_context *sap_ctx; 9285 struct sap_config *sap_config; 9286 struct hdd_hostapd_state *hostapd_state; 9287 struct wlan_objmgr_vdev *vdev; 9288 struct wlan_hdd_link_info *link_info = adapter->deflink; 9289 QDF_STATUS status = QDF_STATUS_SUCCESS; 9290 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); 9291 9292 mode = adapter->device_mode; 9293 ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(link_info); 9294 sap_ctx = WLAN_HDD_GET_SAP_CTX_PTR(link_info); 9295 vdev = hdd_objmgr_get_vdev_by_user(link_info, WLAN_INIT_DEINIT_ID); 9296 9297 if (mode == QDF_SAP_MODE) { 9298 wlan_hdd_scan_abort(link_info); 9299 hdd_abort_ongoing_sta_connection(hdd_ctx); 9300 /* Diassociate with all the peers before stop ap post */ 9301 if (test_bit(SOFTAP_BSS_STARTED, &link_info->link_flags)) { 9302 if (wlan_hdd_del_station(adapter, NULL)) 9303 hdd_sap_indicate_disconnect_for_sta(adapter); 9304 } 9305 wlan_hdd_flush_pmksa_cache(link_info); 9306 sap_config = &ap_ctx->sap_config; 9307 wlansap_reset_sap_config_add_ie(sap_config, eUPDATE_IE_ALL); 9308 hdd_stop_and_close_pre_cac_adapter(hdd_ctx, vdev); 9309 } 9310 wlansap_cleanup_cac_timer(sap_ctx); 9311 cds_flush_work(&adapter->sap_stop_bss_work); 9312 9313 if (qdf_atomic_read(&ap_ctx->acs_in_progress)) { 9314 hdd_info("ACS in progress, wait for complete"); 9315 qdf_wait_for_event_completion(&link_info->acs_complete_event, 9316 ACS_COMPLETE_TIMEOUT); 9317 } 9318 9319 if (mode == QDF_P2P_GO_MODE) { 9320 wlan_hdd_cleanup_remain_on_channel_ctx(link_info); 9321 hdd_abort_ongoing_sta_connection(hdd_ctx); 9322 } 9323 9324 hdd_adapter_deregister_fc(adapter); 9325 hdd_destroy_acs_timer(adapter); 9326 9327 mutex_lock(&hdd_ctx->sap_lock); 9328 if (test_bit(SOFTAP_BSS_STARTED, &link_info->link_flags)) { 9329 hostapd_state = WLAN_HDD_GET_HOSTAP_STATE_PTR(link_info); 9330 qdf_event_reset(&hostapd_state->qdf_stop_bss_event); 9331 status = wlansap_stop_bss(ap_ctx->sap_context); 9332 if (QDF_IS_STATUS_SUCCESS(status)) { 9333 status = qdf_wait_single_event(&hostapd_state->qdf_stop_bss_event, 9334 SME_CMD_STOP_BSS_TIMEOUT); 9335 if (QDF_IS_STATUS_ERROR(status)) { 9336 hdd_err("failure waiting for wlansap_stop_bss %d", 9337 status); 9338 hdd_ipa_ap_disconnect_evt(hdd_ctx, adapter); 9339 } 9340 } else { 9341 hdd_err("failure in wlansap_stop_bss"); 9342 } 9343 9344 clear_bit(SOFTAP_BSS_STARTED, &link_info->link_flags); 9345 policy_mgr_decr_session_set_pcl(hdd_ctx->psoc, 9346 adapter->device_mode, 9347 link_info->vdev_id); 9348 hdd_green_ap_start_state_mc(hdd_ctx, adapter->device_mode, 9349 false); 9350 9351 hdd_reset_ies_on_sap_stop(link_info); 9352 } 9353 9354 /* 9355 * Note to restart sap after SSR driver needs below information 9356 * and is not cleared/freed on purpose in case of SAP SSR 9357 */ 9358 if (!cds_is_driver_recovering()) { 9359 clear_bit(SOFTAP_INIT_DONE, &link_info->link_flags); 9360 qdf_mem_free(ap_ctx->beacon); 9361 ap_ctx->beacon = NULL; 9362 } 9363 /* Clear all the cached sta info */ 9364 hdd_clear_cached_sta_info(adapter); 9365 9366 if (vdev && policy_mgr_is_dnsc_set(vdev)) 9367 wlan_hdd_send_avoid_freq_for_dnbs(hdd_ctx, 0); 9368 9369 hdd_cancel_ip_notifier_work(adapter); 9370 sap_release_vdev_ref(sap_ctx); 9371 9372 if (mode == QDF_SAP_MODE) 9373 ucfg_ipa_flush_pending_vdev_events(hdd_ctx->pdev, 9374 link_info->vdev_id); 9375 if (vdev) 9376 hdd_objmgr_put_vdev_by_user(vdev, WLAN_INIT_DEINIT_ID); 9377 hdd_vdev_destroy(link_info); 9378 mutex_unlock(&hdd_ctx->sap_lock); 9379 ucfg_ipa_flush(hdd_ctx->pdev); 9380 } 9381 9382 static void hdd_stop_ocb_adapter(struct hdd_adapter *adapter) 9383 { 9384 struct hdd_station_ctx *sta_ctx; 9385 struct wlan_objmgr_vdev *vdev; 9386 struct wlan_hdd_link_info *link_info = adapter->deflink; 9387 9388 vdev = hdd_objmgr_get_vdev_by_user(link_info, WLAN_INIT_DEINIT_ID); 9389 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(link_info); 9390 cdp_clear_peer(cds_get_context(QDF_MODULE_ID_SOC), OL_TXRX_PDEV_ID, 9391 sta_ctx->conn_info.peer_macaddr[0]); 9392 hdd_adapter_deregister_fc(adapter); 9393 if (vdev) 9394 hdd_objmgr_put_vdev_by_user(vdev, WLAN_INIT_DEINIT_ID); 9395 hdd_vdev_destroy(link_info); 9396 } 9397 9398 QDF_STATUS hdd_stop_adapter_ext(struct hdd_context *hdd_ctx, 9399 struct hdd_adapter *adapter) 9400 { 9401 QDF_STATUS status; 9402 struct wlan_hdd_link_info *link_info = adapter->deflink; 9403 9404 hdd_enter(); 9405 hdd_destroy_adapter_sysfs_files(adapter); 9406 9407 if (adapter->device_mode == QDF_STA_MODE && 9408 hdd_is_pkt_capture_mon_enable(adapter) && 9409 ucfg_pkt_capture_get_mode(hdd_ctx->psoc) != 9410 PACKET_CAPTURE_MODE_DISABLE) { 9411 hdd_unmap_monitor_interface_vdev(adapter); 9412 } 9413 9414 if (link_info->vdev_id != WLAN_UMAC_VDEV_ID_MAX) 9415 wlan_hdd_cfg80211_deregister_frames(adapter); 9416 9417 hdd_stop_tsf_sync(adapter); 9418 cds_flush_work(&adapter->scan_block_work); 9419 wlan_hdd_cfg80211_scan_block(adapter); 9420 hdd_debug("Disabling queues"); 9421 wlan_hdd_netif_queue_control(adapter, 9422 WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER, 9423 WLAN_CONTROL_PATH); 9424 9425 switch (adapter->device_mode) { 9426 case QDF_STA_MODE: 9427 case QDF_P2P_CLIENT_MODE: 9428 case QDF_NDI_MODE: 9429 case QDF_P2P_DEVICE_MODE: 9430 case QDF_NAN_DISC_MODE: 9431 hdd_stop_station_adapter(adapter); 9432 break; 9433 case QDF_MONITOR_MODE: 9434 status = hdd_stop_mon_adapter(adapter); 9435 if (QDF_IS_STATUS_ERROR(status)) 9436 return status; 9437 9438 break; 9439 case QDF_SAP_MODE: 9440 case QDF_P2P_GO_MODE: 9441 hdd_stop_sap_go_adapter(adapter); 9442 break; 9443 case QDF_OCB_MODE: 9444 hdd_stop_ocb_adapter(adapter); 9445 break; 9446 default: 9447 break; 9448 } 9449 9450 /* Moved from vdev destroy as it is per adapter */ 9451 wlan_cfg80211_cleanup_scan_queue(hdd_ctx->pdev, adapter->dev); 9452 9453 /* Disable all links (expect default index) in adapter. 9454 * Set link address to NULL 9455 */ 9456 hdd_adapter_disable_all_links(adapter); 9457 9458 /* This function should be invoked at the end of this api*/ 9459 hdd_dump_func_call_map(); 9460 hdd_exit(); 9461 9462 return QDF_STATUS_SUCCESS; 9463 } 9464 9465 QDF_STATUS hdd_stop_adapter(struct hdd_context *hdd_ctx, 9466 struct hdd_adapter *adapter) 9467 { 9468 QDF_STATUS status; 9469 9470 if (adapter->device_mode == QDF_STA_MODE) 9471 status = hdd_stop_link_adapter(hdd_ctx, adapter); 9472 9473 status = hdd_stop_adapter_ext(hdd_ctx, adapter); 9474 9475 return status; 9476 } 9477 9478 /** 9479 * hdd_deinit_all_adapters - deinit all adapters 9480 * @hdd_ctx: HDD context 9481 * @rtnl_held: True if RTNL lock held 9482 * 9483 */ 9484 void hdd_deinit_all_adapters(struct hdd_context *hdd_ctx, bool rtnl_held) 9485 { 9486 struct hdd_adapter *adapter, *next_adapter = NULL; 9487 9488 hdd_enter(); 9489 9490 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 9491 NET_DEV_HOLD_DEINIT_ALL_ADAPTERS) { 9492 hdd_deinit_adapter(hdd_ctx, adapter, rtnl_held); 9493 hdd_adapter_dev_put_debug(adapter, 9494 NET_DEV_HOLD_DEINIT_ALL_ADAPTERS); 9495 } 9496 9497 hdd_exit(); 9498 } 9499 9500 QDF_STATUS hdd_stop_all_adapters(struct hdd_context *hdd_ctx) 9501 { 9502 struct hdd_adapter *adapter, *next_adapter = NULL; 9503 9504 hdd_enter(); 9505 9506 ucfg_pre_cac_stop(hdd_ctx->psoc); 9507 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 9508 NET_DEV_HOLD_STOP_ALL_ADAPTERS) { 9509 hdd_stop_adapter(hdd_ctx, adapter); 9510 hdd_adapter_dev_put_debug(adapter, 9511 NET_DEV_HOLD_STOP_ALL_ADAPTERS); 9512 } 9513 9514 hdd_exit(); 9515 9516 return QDF_STATUS_SUCCESS; 9517 } 9518 9519 void hdd_set_netdev_flags(struct hdd_adapter *adapter) 9520 { 9521 bool enable_csum = false; 9522 bool enable_lro; 9523 enum QDF_OPMODE device_mode; 9524 struct hdd_context *hdd_ctx; 9525 ol_txrx_soc_handle soc; 9526 uint64_t temp; 9527 9528 if (!adapter || !adapter->dev) { 9529 hdd_err("invalid input!"); 9530 return; 9531 } 9532 device_mode = adapter->device_mode; 9533 9534 hdd_ctx = adapter->hdd_ctx; 9535 soc = cds_get_context(QDF_MODULE_ID_SOC); 9536 9537 if (!soc || !hdd_ctx) { 9538 hdd_err("invalid SOC or HDD context!"); 9539 return; 9540 } 9541 9542 /* Determine device_mode specific configuration */ 9543 9544 enable_lro = !!cdp_cfg_get(soc, cfg_dp_lro_enable); 9545 enable_csum = !!cdp_cfg_get(soc, 9546 cfg_dp_enable_ip_tcp_udp_checksum_offload); 9547 switch (device_mode) { 9548 case QDF_P2P_DEVICE_MODE: 9549 case QDF_P2P_CLIENT_MODE: 9550 enable_csum = !!cdp_cfg_get(soc, 9551 cfg_dp_enable_p2p_ip_tcp_udp_checksum_offload); 9552 break; 9553 case QDF_P2P_GO_MODE: 9554 enable_csum = !!cdp_cfg_get(soc, 9555 cfg_dp_enable_p2p_ip_tcp_udp_checksum_offload); 9556 enable_lro = false; 9557 break; 9558 case QDF_SAP_MODE: 9559 enable_lro = false; 9560 break; 9561 case QDF_NDI_MODE: 9562 case QDF_NAN_DISC_MODE: 9563 enable_csum = !!cdp_cfg_get(soc, 9564 cfg_dp_enable_nan_ip_tcp_udp_checksum_offload); 9565 break; 9566 default: 9567 break; 9568 } 9569 9570 /* Set netdev flags */ 9571 9572 /* 9573 * In case of USB tethering, LRO is disabled. If SSR happened 9574 * during that time, then as part of SSR init, do not enable 9575 * the LRO again. Keep the LRO state same as before SSR. 9576 */ 9577 if (enable_lro && !(qdf_atomic_read(&hdd_ctx->vendor_disable_lro_flag))) 9578 adapter->dev->features |= NETIF_F_LRO; 9579 9580 if (enable_csum) 9581 adapter->dev->features |= 9582 (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM); 9583 9584 if (cdp_cfg_get(soc, cfg_dp_tso_enable) && enable_csum) { 9585 adapter->dev->features |= TSO_FEATURE_FLAGS; 9586 adapter->tso_csum_feature_enabled = 1; 9587 } 9588 9589 if (cdp_cfg_get(soc, cfg_dp_sg_enable)) 9590 adapter->dev->features |= NETIF_F_SG; 9591 9592 adapter->dev->features |= NETIF_F_RXCSUM; 9593 temp = (uint64_t)adapter->dev->features; 9594 9595 hdd_debug("adapter mode %u dev feature 0x%llx", device_mode, temp); 9596 } 9597 9598 #ifdef QCA_LL_LEGACY_TX_FLOW_CONTROL 9599 /** 9600 * hdd_adapter_abort_tx_flow() - Abort the tx flow control 9601 * @adapter: pointer to hdd adapter 9602 * 9603 * Resume tx and stop the tx flow control timer if the tx is paused 9604 * and the flow control timer is running. This function is called by 9605 * SSR to avoid the inconsistency of tx status before and after SSR. 9606 * 9607 * Return: void 9608 */ 9609 static void hdd_adapter_abort_tx_flow(struct hdd_adapter *adapter) 9610 { 9611 if (adapter->deflink->hdd_stats.tx_rx_stats.is_txflow_paused && 9612 QDF_TIMER_STATE_RUNNING == 9613 qdf_mc_timer_get_current_state( 9614 &adapter->tx_flow_control_timer)) { 9615 hdd_tx_resume_timer_expired_handler(adapter); 9616 qdf_mc_timer_stop(&adapter->tx_flow_control_timer); 9617 } 9618 } 9619 #else 9620 static void hdd_adapter_abort_tx_flow(struct hdd_adapter *adapter) 9621 { 9622 } 9623 #endif 9624 9625 QDF_STATUS hdd_reset_all_adapters(struct hdd_context *hdd_ctx) 9626 { 9627 struct hdd_adapter *adapter, *next_adapter = NULL; 9628 bool value; 9629 struct wlan_objmgr_vdev *vdev; 9630 struct wlan_hdd_link_info *link_info; 9631 9632 hdd_enter(); 9633 9634 ucfg_mlme_get_sap_internal_restart(hdd_ctx->psoc, &value); 9635 9636 9637 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 9638 NET_DEV_HOLD_RESET_ALL_ADAPTERS) { 9639 hdd_info("[SSR] reset adapter with device mode %s(%d)", 9640 qdf_opmode_str(adapter->device_mode), 9641 adapter->device_mode); 9642 9643 hdd_adapter_for_each_active_link_info(adapter, link_info) { 9644 hdd_adapter_abort_tx_flow(adapter); 9645 9646 if ((adapter->device_mode == QDF_STA_MODE) || 9647 (adapter->device_mode == QDF_P2P_CLIENT_MODE)) { 9648 hdd_send_twt_del_all_sessions_to_userspace(link_info); 9649 9650 /* Stop tdls timers */ 9651 vdev = hdd_objmgr_get_vdev_by_user(link_info, 9652 WLAN_OSIF_TDLS_ID); 9653 if (vdev) { 9654 hdd_notify_tdls_reset_adapter(vdev); 9655 hdd_objmgr_put_vdev_by_user(vdev, 9656 WLAN_OSIF_TDLS_ID); 9657 } 9658 } 9659 9660 if (value && 9661 adapter->device_mode == QDF_SAP_MODE) { 9662 hdd_medium_assess_ssr_enable_flag(); 9663 wlan_hdd_netif_queue_control(adapter, 9664 WLAN_STOP_ALL_NETIF_QUEUE, 9665 WLAN_CONTROL_PATH); 9666 } else { 9667 wlan_hdd_netif_queue_control(adapter, 9668 WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER, 9669 WLAN_CONTROL_PATH); 9670 } 9671 9672 /* 9673 * Clear fc flag if it was set before SSR to avoid 9674 * TX queues permanently stopped after SSR. 9675 * Here WLAN_START_ALL_NETIF_QUEUE will actually 9676 * not start any queue since it's blocked by reason 9677 * WLAN_CONTROL_PATH. 9678 */ 9679 if (adapter->pause_map & (1 << WLAN_DATA_FLOW_CONTROL)) 9680 wlan_hdd_netif_queue_control(adapter, 9681 WLAN_START_ALL_NETIF_QUEUE, 9682 WLAN_DATA_FLOW_CONTROL); 9683 9684 hdd_reset_scan_operation(link_info); 9685 9686 if (test_bit(WMM_INIT_DONE, &adapter->event_flags)) { 9687 hdd_wmm_adapter_close(adapter); 9688 clear_bit(WMM_INIT_DONE, &adapter->event_flags); 9689 } 9690 9691 hdd_debug("Flush any mgmt references held by peer"); 9692 hdd_stop_adapter(hdd_ctx, adapter); 9693 } 9694 hdd_adapter_dev_put_debug(adapter, 9695 NET_DEV_HOLD_RESET_ALL_ADAPTERS); 9696 } 9697 9698 hdd_exit(); 9699 9700 return QDF_STATUS_SUCCESS; 9701 } 9702 9703 static bool hdd_is_any_link_opened(struct hdd_adapter *adapter) 9704 { 9705 struct wlan_hdd_link_info *link_info; 9706 9707 hdd_adapter_for_each_active_link_info(adapter, link_info) { 9708 if (test_bit(SME_SESSION_OPENED, &link_info->link_flags)) 9709 return true; 9710 } 9711 return false; 9712 } 9713 9714 bool hdd_is_any_interface_open(struct hdd_context *hdd_ctx) 9715 { 9716 struct hdd_adapter *adapter, *next_adapter = NULL; 9717 wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_IS_ANY_INTERFACE_OPEN; 9718 9719 if (hdd_get_conparam() == QDF_GLOBAL_FTM_MODE) { 9720 hdd_info("FTM mode, don't close the module"); 9721 return true; 9722 } 9723 9724 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 9725 dbgid) { 9726 if (test_bit(DEVICE_IFACE_OPENED, &adapter->event_flags) || 9727 hdd_is_any_link_opened(adapter)) { 9728 hdd_adapter_dev_put_debug(adapter, dbgid); 9729 if (next_adapter) 9730 hdd_adapter_dev_put_debug(next_adapter, dbgid); 9731 return true; 9732 } 9733 hdd_adapter_dev_put_debug(adapter, dbgid); 9734 } 9735 9736 return false; 9737 } 9738 9739 bool hdd_is_interface_up(struct hdd_adapter *adapter) 9740 { 9741 if (test_bit(DEVICE_IFACE_OPENED, &adapter->event_flags)) 9742 return true; 9743 else 9744 return false; 9745 } 9746 9747 #ifdef FEATURE_MONITOR_MODE_SUPPORT 9748 #ifdef WLAN_FEATURE_11BE 9749 static inline bool wlan_hdd_is_mon_channel_bw_valid(enum phy_ch_width ch_width) 9750 { 9751 if (ch_width > CH_WIDTH_320MHZ || 9752 (!cds_is_sub_20_mhz_enabled() && (ch_width == CH_WIDTH_5MHZ || 9753 ch_width == CH_WIDTH_10MHZ))) 9754 return false; 9755 9756 return true; 9757 } 9758 #else 9759 static inline bool wlan_hdd_is_mon_channel_bw_valid(enum phy_ch_width ch_width) 9760 { 9761 if (ch_width > CH_WIDTH_10MHZ || 9762 (!cds_is_sub_20_mhz_enabled() && (ch_width == CH_WIDTH_5MHZ || 9763 ch_width == CH_WIDTH_10MHZ))) 9764 return false; 9765 9766 return true; 9767 } 9768 #endif 9769 9770 int wlan_hdd_set_mon_chan(struct hdd_adapter *adapter, qdf_freq_t freq, 9771 uint32_t bandwidth) 9772 { 9773 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); 9774 struct hdd_station_ctx *sta_ctx; 9775 struct hdd_mon_set_ch_info *ch_info; 9776 QDF_STATUS status; 9777 struct qdf_mac_addr bssid; 9778 struct channel_change_req *req; 9779 struct ch_params ch_params; 9780 enum phy_ch_width max_fw_bw; 9781 enum phy_ch_width ch_width; 9782 int ret; 9783 9784 if ((hdd_get_conparam() != QDF_GLOBAL_MONITOR_MODE) && 9785 (!policy_mgr_is_sta_mon_concurrency(hdd_ctx->psoc))) { 9786 hdd_err("Not supported, device is not in monitor mode"); 9787 return -EINVAL; 9788 } 9789 9790 if (adapter->device_mode != QDF_MONITOR_MODE) { 9791 hdd_err_rl("Not supported, adapter is not in monitor mode"); 9792 return -EINVAL; 9793 } 9794 9795 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter->deflink); 9796 ch_info = &sta_ctx->ch_info; 9797 9798 /* Verify the BW before accepting this request */ 9799 ch_width = bandwidth; 9800 9801 if (!wlan_hdd_is_mon_channel_bw_valid(ch_width)) { 9802 hdd_err("invalid BW received %d", ch_width); 9803 return -EINVAL; 9804 } 9805 9806 max_fw_bw = sme_get_vht_ch_width(); 9807 9808 hdd_debug("max fw BW %d ch width %d", max_fw_bw, ch_width); 9809 if ((ch_width == CH_WIDTH_160MHZ && 9810 max_fw_bw <= WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ) || 9811 (ch_width == CH_WIDTH_80P80MHZ && 9812 max_fw_bw <= WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ)) { 9813 hdd_err("FW does not support this BW %d max BW supported %d", 9814 ch_width, max_fw_bw); 9815 return -EINVAL; 9816 } 9817 9818 if (!hdd_is_target_eht_phy_ch_width_supported(ch_width)) 9819 return -EINVAL; 9820 9821 ret = hdd_validate_channel_and_bandwidth(adapter, freq, bandwidth); 9822 if (ret) { 9823 hdd_err("Invalid CH and BW combo"); 9824 return ret; 9825 } 9826 9827 hdd_debug("Set monitor mode frequency %d", freq); 9828 qdf_mem_copy(bssid.bytes, adapter->mac_addr.bytes, 9829 QDF_MAC_ADDR_SIZE); 9830 9831 ch_params.ch_width = bandwidth; 9832 wlan_reg_set_channel_params_for_pwrmode(hdd_ctx->pdev, freq, 0, 9833 &ch_params, 9834 REG_CURRENT_PWR_MODE); 9835 9836 if (ch_params.ch_width == CH_WIDTH_INVALID) { 9837 hdd_err("Invalid capture channel or bandwidth for a country"); 9838 return -EINVAL; 9839 } 9840 if (wlan_hdd_change_hw_mode_for_given_chnl(adapter, freq, 9841 POLICY_MGR_UPDATE_REASON_SET_OPER_CHAN)) { 9842 hdd_err("Failed to change hw mode"); 9843 return -EINVAL; 9844 } 9845 9846 if (adapter->monitor_mode_vdev_up_in_progress) { 9847 hdd_err_rl("monitor mode vdev up in progress"); 9848 return -EBUSY; 9849 } 9850 9851 status = qdf_event_reset(&adapter->qdf_monitor_mode_vdev_up_event); 9852 if (QDF_IS_STATUS_ERROR(status)) { 9853 hdd_err_rl("failed to reinit monitor mode vdev up event"); 9854 return qdf_status_to_os_return(status); 9855 } 9856 adapter->monitor_mode_vdev_up_in_progress = true; 9857 9858 qdf_mem_zero(&ch_params, sizeof(struct ch_params)); 9859 9860 req = qdf_mem_malloc(sizeof(struct channel_change_req)); 9861 if (!req) 9862 return -ENOMEM; 9863 req->vdev_id = adapter->deflink->vdev_id; 9864 req->target_chan_freq = freq; 9865 req->ch_width = ch_width; 9866 9867 ch_params.ch_width = ch_width; 9868 hdd_select_cbmode(adapter, freq, 0, &ch_params); 9869 9870 req->sec_ch_offset = ch_params.sec_ch_offset; 9871 req->center_freq_seg0 = ch_params.center_freq_seg0; 9872 req->center_freq_seg1 = ch_params.center_freq_seg1; 9873 9874 sme_fill_channel_change_request(hdd_ctx->mac_handle, req, 9875 ch_info->phy_mode); 9876 status = sme_send_channel_change_req(hdd_ctx->mac_handle, req); 9877 qdf_mem_free(req); 9878 if (status) { 9879 hdd_err("Status: %d Failed to set sme_roam Channel for monitor mode", 9880 status); 9881 adapter->monitor_mode_vdev_up_in_progress = false; 9882 return qdf_status_to_os_return(status); 9883 } 9884 9885 adapter->mon_chan_freq = freq; 9886 adapter->mon_bandwidth = bandwidth; 9887 9888 /* block on a completion variable until vdev up success*/ 9889 status = qdf_wait_for_event_completion( 9890 &adapter->qdf_monitor_mode_vdev_up_event, 9891 WLAN_MONITOR_MODE_VDEV_UP_EVT); 9892 if (QDF_IS_STATUS_ERROR(status)) { 9893 hdd_err_rl("monitor vdev up event time out vdev id: %d", 9894 adapter->deflink->vdev_id); 9895 if (adapter->qdf_monitor_mode_vdev_up_event.force_set) 9896 /* 9897 * SSR/PDR has caused shutdown, which has 9898 * forcefully set the event. 9899 */ 9900 hdd_err_rl("monitor mode vdev up event forcefully set"); 9901 else if (status == QDF_STATUS_E_TIMEOUT) 9902 hdd_err("monitor mode vdev up timed out"); 9903 else 9904 hdd_err_rl("Failed monitor mode vdev up(status-%d)", 9905 status); 9906 9907 adapter->monitor_mode_vdev_up_in_progress = false; 9908 } 9909 9910 return qdf_status_to_os_return(status); 9911 } 9912 #endif 9913 9914 #if defined MSM_PLATFORM && (LINUX_VERSION_CODE <= KERNEL_VERSION(4, 19, 0)) 9915 /** 9916 * hdd_stop_p2p_go() - call cfg80211 API to stop P2P GO 9917 * @adapter: pointer to adapter 9918 * 9919 * This function calls cfg80211 API to stop P2P GO 9920 * 9921 * Return: None 9922 */ 9923 static void hdd_stop_p2p_go(struct hdd_adapter *adapter) 9924 { 9925 hdd_debug("[SSR] send stop ap to supplicant"); 9926 cfg80211_ap_stopped(adapter->dev, GFP_KERNEL); 9927 } 9928 9929 static inline void hdd_delete_sta(struct hdd_adapter *adapter) 9930 { 9931 } 9932 9933 #else 9934 static void hdd_stop_p2p_go(struct hdd_adapter *adapter) 9935 { 9936 hdd_debug("[SSR] send stop iface ap to supplicant"); 9937 cfg80211_stop_iface(adapter->hdd_ctx->wiphy, &adapter->wdev, 9938 GFP_KERNEL); 9939 } 9940 9941 /** 9942 * hdd_delete_sta() - call cfg80211 API to delete STA 9943 * @adapter: pointer to adapter 9944 * 9945 * This function calls cfg80211 API to delete STA 9946 * 9947 * Return: None 9948 */ 9949 static void hdd_delete_sta(struct hdd_adapter *adapter) 9950 { 9951 struct qdf_mac_addr bcast_mac = QDF_MAC_ADDR_BCAST_INIT; 9952 9953 hdd_debug("[SSR] send restart supplicant"); 9954 /* event supplicant to restart */ 9955 cfg80211_del_sta(adapter->dev, 9956 (const u8 *)&bcast_mac.bytes[0], 9957 GFP_KERNEL); 9958 } 9959 #endif 9960 9961 QDF_STATUS hdd_start_all_adapters(struct hdd_context *hdd_ctx, bool rtnl_held) 9962 { 9963 struct hdd_adapter *adapter, *next_adapter = NULL; 9964 bool value; 9965 wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_START_ALL_ADAPTERS; 9966 int ret; 9967 9968 hdd_enter(); 9969 9970 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 9971 dbgid) { 9972 if (!hdd_is_interface_up(adapter) && 9973 adapter->device_mode != QDF_NDI_MODE) { 9974 hdd_adapter_dev_put_debug(adapter, dbgid); 9975 continue; 9976 } 9977 9978 hdd_debug("[SSR] start adapter with device mode %s(%d)", 9979 qdf_opmode_str(adapter->device_mode), 9980 adapter->device_mode); 9981 9982 hdd_wmm_dscp_initial_state(adapter); 9983 9984 switch (adapter->device_mode) { 9985 case QDF_STA_MODE: 9986 case QDF_P2P_CLIENT_MODE: 9987 case QDF_P2P_DEVICE_MODE: 9988 case QDF_NAN_DISC_MODE: 9989 9990 ret = hdd_start_station_adapter(adapter); 9991 if (ret) { 9992 hdd_err("[SSR] Failed to start station adapter: %d", 9993 ret); 9994 hdd_adapter_dev_put_debug(adapter, dbgid); 9995 continue; 9996 } 9997 if (adapter->device_mode == QDF_STA_MODE) { 9998 ret = hdd_start_link_adapter(adapter); 9999 if (ret) { 10000 hdd_err("[SSR] Failed to start link adapter: %d", 10001 ret); 10002 hdd_stop_adapter(hdd_ctx, adapter); 10003 hdd_adapter_dev_put_debug(adapter, 10004 dbgid); 10005 continue; 10006 } 10007 } 10008 10009 /* Open the gates for HDD to receive Wext commands */ 10010 adapter->is_link_up_service_needed = false; 10011 10012 if ((adapter->device_mode == QDF_NAN_DISC_MODE || 10013 (adapter->device_mode == QDF_STA_MODE && 10014 !ucfg_nan_is_vdev_creation_allowed( 10015 hdd_ctx->psoc))) && 10016 cds_is_driver_recovering()) 10017 ucfg_nan_disable_ind_to_userspace( 10018 hdd_ctx->psoc); 10019 10020 hdd_register_tx_flow_control(adapter, 10021 hdd_tx_resume_timer_expired_handler, 10022 hdd_tx_resume_cb, 10023 hdd_tx_flow_control_is_pause); 10024 10025 hdd_register_hl_netdev_fc_timer( 10026 adapter, 10027 hdd_tx_resume_timer_expired_handler); 10028 10029 hdd_lpass_notify_start(adapter->deflink); 10030 break; 10031 10032 case QDF_SAP_MODE: 10033 ucfg_mlme_get_sap_internal_restart(hdd_ctx->psoc, 10034 &value); 10035 if (value) 10036 hdd_start_ap_adapter(adapter, rtnl_held); 10037 10038 break; 10039 10040 case QDF_P2P_GO_MODE: 10041 hdd_delete_sta(adapter); 10042 break; 10043 case QDF_MONITOR_MODE: 10044 if (wlan_hdd_is_session_type_monitor( 10045 adapter->device_mode) && 10046 ucfg_pkt_capture_get_mode(hdd_ctx->psoc) != 10047 PACKET_CAPTURE_MODE_DISABLE) { 10048 struct hdd_adapter *sta_adapter; 10049 10050 sta_adapter = hdd_get_adapter(hdd_ctx, 10051 QDF_STA_MODE); 10052 if (!sta_adapter) { 10053 hdd_err("No station interface found"); 10054 return -EINVAL; 10055 } 10056 10057 hdd_map_monitor_interface_vdev(sta_adapter); 10058 break; 10059 } 10060 hdd_start_station_adapter(adapter); 10061 hdd_set_mon_rx_cb(adapter->dev); 10062 10063 wlan_hdd_set_mon_chan( 10064 adapter, adapter->mon_chan_freq, 10065 adapter->mon_bandwidth); 10066 break; 10067 case QDF_NDI_MODE: 10068 hdd_ndi_start(adapter->dev->name, 0); 10069 break; 10070 default: 10071 break; 10072 } 10073 /* 10074 * Action frame registered in one adapter which will 10075 * applicable to all interfaces 10076 */ 10077 if (hdd_set_fw_params(adapter)) 10078 hdd_err("Failed to set adapter FW params after SSR!"); 10079 10080 wlan_hdd_cfg80211_register_frames(adapter); 10081 hdd_create_adapter_sysfs_files(adapter); 10082 hdd_adapter_dev_put_debug(adapter, dbgid); 10083 } 10084 10085 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 10086 dbgid) { 10087 if (!hdd_is_interface_up(adapter)) { 10088 hdd_adapter_dev_put_debug(adapter, dbgid); 10089 continue; 10090 } 10091 10092 if (adapter->device_mode == QDF_P2P_GO_MODE) 10093 hdd_stop_p2p_go(adapter); 10094 10095 hdd_adapter_dev_put_debug(adapter, dbgid); 10096 } 10097 10098 hdd_exit(); 10099 10100 return QDF_STATUS_SUCCESS; 10101 } 10102 10103 void hdd_adapter_dev_hold_debug(struct hdd_adapter *adapter, 10104 wlan_net_dev_ref_dbgid dbgid) 10105 { 10106 if (dbgid >= NET_DEV_HOLD_ID_MAX) { 10107 hdd_err("Invalid debug id: %d", dbgid); 10108 QDF_BUG(0); 10109 } 10110 dev_hold(adapter->dev); 10111 qdf_atomic_inc(&adapter->net_dev_hold_ref_count[dbgid]); 10112 } 10113 10114 void hdd_adapter_dev_put_debug(struct hdd_adapter *adapter, 10115 wlan_net_dev_ref_dbgid dbgid) 10116 { 10117 if (dbgid >= NET_DEV_HOLD_ID_MAX) { 10118 hdd_err("Invalid debug id: %d", dbgid); 10119 QDF_BUG(0); 10120 } 10121 10122 if (qdf_atomic_dec_return( 10123 &adapter->net_dev_hold_ref_count[dbgid]) < 0) { 10124 hdd_err("dev_put detected without dev_hold for debug id: %s", 10125 net_dev_ref_debug_string_from_id(dbgid)); 10126 QDF_BUG(0); 10127 } 10128 10129 if (adapter->dev) { 10130 dev_put(adapter->dev); 10131 } else { 10132 hdd_err("adapter->dev is NULL"); 10133 QDF_BUG(0); 10134 } 10135 } 10136 10137 QDF_STATUS hdd_get_front_adapter(struct hdd_context *hdd_ctx, 10138 struct hdd_adapter **out_adapter) 10139 { 10140 QDF_STATUS status; 10141 qdf_list_node_t *node; 10142 10143 *out_adapter = NULL; 10144 10145 qdf_spin_lock_bh(&hdd_ctx->hdd_adapter_lock); 10146 status = qdf_list_peek_front(&hdd_ctx->hdd_adapters, &node); 10147 qdf_spin_unlock_bh(&hdd_ctx->hdd_adapter_lock); 10148 10149 if (QDF_IS_STATUS_ERROR(status)) 10150 return status; 10151 10152 *out_adapter = qdf_container_of(node, struct hdd_adapter, node); 10153 10154 return QDF_STATUS_SUCCESS; 10155 } 10156 10157 QDF_STATUS hdd_get_next_adapter(struct hdd_context *hdd_ctx, 10158 struct hdd_adapter *current_adapter, 10159 struct hdd_adapter **out_adapter) 10160 { 10161 QDF_STATUS status; 10162 qdf_list_node_t *node; 10163 10164 *out_adapter = NULL; 10165 10166 qdf_spin_lock_bh(&hdd_ctx->hdd_adapter_lock); 10167 status = qdf_list_peek_next(&hdd_ctx->hdd_adapters, 10168 ¤t_adapter->node, 10169 &node); 10170 qdf_spin_unlock_bh(&hdd_ctx->hdd_adapter_lock); 10171 10172 if (QDF_IS_STATUS_ERROR(status)) 10173 return status; 10174 10175 *out_adapter = qdf_container_of(node, struct hdd_adapter, node); 10176 10177 return status; 10178 } 10179 10180 QDF_STATUS hdd_get_front_adapter_no_lock(struct hdd_context *hdd_ctx, 10181 struct hdd_adapter **out_adapter) 10182 { 10183 QDF_STATUS status; 10184 qdf_list_node_t *node; 10185 10186 *out_adapter = NULL; 10187 10188 status = qdf_list_peek_front(&hdd_ctx->hdd_adapters, &node); 10189 10190 if (QDF_IS_STATUS_ERROR(status)) 10191 return status; 10192 10193 *out_adapter = qdf_container_of(node, struct hdd_adapter, node); 10194 10195 return QDF_STATUS_SUCCESS; 10196 } 10197 10198 QDF_STATUS hdd_get_next_adapter_no_lock(struct hdd_context *hdd_ctx, 10199 struct hdd_adapter *current_adapter, 10200 struct hdd_adapter **out_adapter) 10201 { 10202 QDF_STATUS status; 10203 qdf_list_node_t *node; 10204 10205 if (!current_adapter) 10206 return QDF_STATUS_E_INVAL; 10207 10208 *out_adapter = NULL; 10209 10210 status = qdf_list_peek_next(&hdd_ctx->hdd_adapters, 10211 ¤t_adapter->node, 10212 &node); 10213 10214 if (QDF_IS_STATUS_ERROR(status)) 10215 return status; 10216 10217 *out_adapter = qdf_container_of(node, struct hdd_adapter, node); 10218 10219 return status; 10220 } 10221 10222 QDF_STATUS hdd_remove_adapter(struct hdd_context *hdd_ctx, 10223 struct hdd_adapter *adapter) 10224 { 10225 QDF_STATUS status; 10226 10227 qdf_spin_lock_bh(&hdd_ctx->hdd_adapter_lock); 10228 status = qdf_list_remove_node(&hdd_ctx->hdd_adapters, &adapter->node); 10229 qdf_spin_unlock_bh(&hdd_ctx->hdd_adapter_lock); 10230 10231 return status; 10232 } 10233 10234 QDF_STATUS hdd_remove_front_adapter(struct hdd_context *hdd_ctx, 10235 struct hdd_adapter **out_adapter) 10236 { 10237 QDF_STATUS status; 10238 qdf_list_node_t *node; 10239 10240 *out_adapter = NULL; 10241 10242 qdf_spin_lock_bh(&hdd_ctx->hdd_adapter_lock); 10243 status = qdf_list_remove_front(&hdd_ctx->hdd_adapters, &node); 10244 qdf_spin_unlock_bh(&hdd_ctx->hdd_adapter_lock); 10245 10246 if (QDF_IS_STATUS_ERROR(status)) 10247 return status; 10248 10249 *out_adapter = qdf_container_of(node, struct hdd_adapter, node); 10250 10251 return status; 10252 } 10253 10254 QDF_STATUS hdd_add_adapter_back(struct hdd_context *hdd_ctx, 10255 struct hdd_adapter *adapter) 10256 { 10257 QDF_STATUS status; 10258 10259 qdf_spin_lock_bh(&hdd_ctx->hdd_adapter_lock); 10260 status = qdf_list_insert_back(&hdd_ctx->hdd_adapters, &adapter->node); 10261 qdf_spin_unlock_bh(&hdd_ctx->hdd_adapter_lock); 10262 10263 return status; 10264 } 10265 10266 QDF_STATUS hdd_add_adapter_front(struct hdd_context *hdd_ctx, 10267 struct hdd_adapter *adapter) 10268 { 10269 QDF_STATUS status; 10270 10271 qdf_spin_lock_bh(&hdd_ctx->hdd_adapter_lock); 10272 status = qdf_list_insert_front(&hdd_ctx->hdd_adapters, &adapter->node); 10273 qdf_spin_unlock_bh(&hdd_ctx->hdd_adapter_lock); 10274 10275 return status; 10276 } 10277 10278 void hdd_validate_next_adapter(struct hdd_adapter **curr, 10279 struct hdd_adapter **next, 10280 wlan_net_dev_ref_dbgid dbg_id) 10281 { 10282 if (!*curr || !*next || *curr != *next) 10283 return; 10284 10285 hdd_err("Validation failed"); 10286 hdd_adapter_dev_put_debug(*curr, dbg_id); 10287 *curr = NULL; 10288 *next = NULL; 10289 } 10290 10291 QDF_STATUS hdd_adapter_iterate(hdd_adapter_iterate_cb cb, void *context) 10292 { 10293 struct hdd_context *hdd_ctx; 10294 struct hdd_adapter *cache[HDD_MAX_ADAPTERS]; 10295 struct hdd_adapter *adapter; 10296 uint32_t n_cache = 0; 10297 QDF_STATUS ret = QDF_STATUS_SUCCESS; 10298 QDF_STATUS status; 10299 int i; 10300 struct wlan_hdd_link_info *link_info; 10301 10302 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 10303 if (unlikely(!hdd_ctx)) 10304 return QDF_STATUS_E_FAILURE; 10305 10306 qdf_spin_lock_bh(&hdd_ctx->hdd_adapter_lock); 10307 for (hdd_get_front_adapter_no_lock(hdd_ctx, &adapter); adapter; 10308 hdd_get_next_adapter_no_lock(hdd_ctx, adapter, &adapter)) { 10309 cache[n_cache++] = adapter; 10310 } 10311 qdf_spin_unlock_bh(&hdd_ctx->hdd_adapter_lock); 10312 10313 for (i = 0; i < n_cache; i++) { 10314 adapter = hdd_adapter_get_by_reference(hdd_ctx, cache[i]); 10315 if (!adapter) { 10316 /* 10317 * detected remove while iterating 10318 * concurrency failure 10319 */ 10320 ret = QDF_STATUS_E_FAILURE; 10321 continue; 10322 } 10323 hdd_adapter_for_each_active_link_info(adapter, link_info) { 10324 status = cb(link_info, context); 10325 if (status != QDF_STATUS_SUCCESS) { 10326 hdd_adapter_put(adapter); 10327 return status; 10328 } 10329 } 10330 hdd_adapter_put(adapter); 10331 } 10332 10333 return ret; 10334 } 10335 10336 struct hdd_adapter *hdd_get_adapter_by_rand_macaddr( 10337 struct hdd_context *hdd_ctx, tSirMacAddr mac_addr) 10338 { 10339 struct hdd_adapter *adapter, *next_adapter = NULL; 10340 wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_GET_ADAPTER_BY_RAND_MACADDR; 10341 struct wlan_hdd_link_info *link_info; 10342 10343 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 10344 dbgid) { 10345 if (adapter->device_mode != QDF_STA_MODE && 10346 adapter->device_mode != QDF_P2P_CLIENT_MODE && 10347 adapter->device_mode != QDF_P2P_DEVICE_MODE) { 10348 hdd_adapter_dev_put_debug(adapter, dbgid); 10349 continue; 10350 } 10351 10352 hdd_adapter_for_each_active_link_info(adapter, link_info) { 10353 if (ucfg_p2p_check_random_mac(hdd_ctx->psoc, 10354 link_info->vdev_id, 10355 mac_addr)) { 10356 hdd_adapter_dev_put_debug(adapter, dbgid); 10357 if (next_adapter) 10358 hdd_adapter_dev_put_debug(next_adapter, 10359 dbgid); 10360 return adapter; 10361 } 10362 } 10363 hdd_adapter_dev_put_debug(adapter, dbgid); 10364 } 10365 10366 return NULL; 10367 } 10368 10369 #ifdef WLAN_HDD_MULTI_VDEV_SINGLE_NDEV 10370 struct hdd_adapter *hdd_get_adapter_by_macaddr(struct hdd_context *hdd_ctx, 10371 tSirMacAddr mac_addr) 10372 { 10373 struct hdd_adapter *adapter, *next_adapter = NULL; 10374 wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_GET_ADAPTER_BY_MACADDR; 10375 struct qdf_mac_addr zero_mac_addr = QDF_MAC_ADDR_ZERO_INIT; 10376 struct wlan_hdd_link_info *link_info; 10377 10378 if (!qdf_mem_cmp(mac_addr, zero_mac_addr.bytes, sizeof(tSirMacAddr))) 10379 return NULL; 10380 10381 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 10382 dbgid) { 10383 if (!qdf_mem_cmp(adapter->mac_addr.bytes, 10384 mac_addr, sizeof(tSirMacAddr))) { 10385 hdd_adapter_dev_put_debug(adapter, dbgid); 10386 if (next_adapter) 10387 hdd_adapter_dev_put_debug(next_adapter, 10388 dbgid); 10389 return adapter; 10390 } 10391 hdd_adapter_for_each_active_link_info(adapter, link_info) { 10392 if (!qdf_mem_cmp(link_info->link_addr.bytes, 10393 mac_addr, sizeof(tSirMacAddr))) { 10394 hdd_adapter_dev_put_debug(adapter, dbgid); 10395 if (next_adapter) 10396 hdd_adapter_dev_put_debug(next_adapter, 10397 dbgid); 10398 return adapter; 10399 } 10400 } 10401 hdd_adapter_dev_put_debug(adapter, dbgid); 10402 } 10403 10404 return NULL; 10405 } 10406 10407 struct wlan_hdd_link_info * 10408 hdd_get_link_info_by_link_addr(struct hdd_context *hdd_ctx, 10409 struct qdf_mac_addr *link_addr) 10410 { 10411 struct wlan_hdd_link_info *link_info; 10412 struct hdd_adapter *adapter, *next_adapter = NULL; 10413 wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_GET_ADAPTER_BY_MACADDR; 10414 10415 if (!link_addr || qdf_is_macaddr_zero(link_addr)) 10416 return NULL; 10417 10418 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 10419 dbgid) { 10420 hdd_adapter_for_each_link_info(adapter, link_info) { 10421 if (qdf_is_macaddr_equal(link_addr, 10422 &link_info->link_addr)) { 10423 hdd_adapter_dev_put_debug(adapter, dbgid); 10424 if (next_adapter) 10425 hdd_adapter_dev_put_debug(next_adapter, 10426 dbgid); 10427 return link_info; 10428 } 10429 } 10430 hdd_adapter_dev_put_debug(adapter, dbgid); 10431 } 10432 10433 return NULL; 10434 } 10435 #else 10436 struct hdd_adapter *hdd_get_adapter_by_macaddr(struct hdd_context *hdd_ctx, 10437 tSirMacAddr mac_addr) 10438 { 10439 struct hdd_adapter *adapter, *next_adapter = NULL; 10440 wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_GET_ADAPTER_BY_MACADDR; 10441 10442 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 10443 dbgid) { 10444 if (!qdf_mem_cmp(adapter->mac_addr.bytes, 10445 mac_addr, sizeof(tSirMacAddr))) { 10446 hdd_adapter_dev_put_debug(adapter, dbgid); 10447 if (next_adapter) 10448 hdd_adapter_dev_put_debug(next_adapter, 10449 dbgid); 10450 return adapter; 10451 } 10452 10453 if (hdd_adapter_is_sl_ml_adapter(adapter) && 10454 !qdf_mem_cmp(adapter->mld_addr.bytes, 10455 mac_addr, sizeof(tSirMacAddr))) { 10456 hdd_adapter_dev_put_debug(adapter, dbgid); 10457 if (next_adapter) 10458 hdd_adapter_dev_put_debug(next_adapter, dbgid); 10459 return adapter; 10460 } 10461 hdd_adapter_dev_put_debug(adapter, dbgid); 10462 } 10463 10464 return NULL; 10465 } 10466 10467 struct wlan_hdd_link_info * 10468 hdd_get_link_info_by_link_addr(struct hdd_context *hdd_ctx, 10469 struct qdf_mac_addr *link_addr) 10470 { 10471 return NULL; 10472 } 10473 #endif 10474 10475 struct wlan_hdd_link_info * 10476 hdd_get_link_info_by_vdev(struct hdd_context *hdd_ctx, uint32_t vdev_id) 10477 { 10478 struct hdd_adapter *adapter, *next_adapter = NULL; 10479 wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_GET_ADAPTER_BY_VDEV; 10480 struct wlan_hdd_link_info *link_info; 10481 10482 if (vdev_id == WLAN_INVALID_VDEV_ID) 10483 return NULL; 10484 10485 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 10486 dbgid) { 10487 hdd_adapter_for_each_active_link_info(adapter, link_info) { 10488 if (link_info->vdev_id == vdev_id) { 10489 hdd_adapter_dev_put_debug(adapter, dbgid); 10490 if (next_adapter) 10491 hdd_adapter_dev_put_debug(next_adapter, 10492 dbgid); 10493 return link_info; 10494 } 10495 } 10496 hdd_adapter_dev_put_debug(adapter, dbgid); 10497 } 10498 10499 return NULL; 10500 } 10501 10502 struct hdd_adapter *hdd_adapter_get_by_reference(struct hdd_context *hdd_ctx, 10503 struct hdd_adapter *reference) 10504 { 10505 struct hdd_adapter *adapter, *next_adapter = NULL; 10506 wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_ADAPTER_GET_BY_REFERENCE; 10507 10508 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 10509 dbgid) { 10510 if (adapter == reference) { 10511 dev_hold(adapter->dev); 10512 hdd_adapter_dev_put_debug(adapter, dbgid); 10513 if (next_adapter) 10514 hdd_adapter_dev_put_debug(next_adapter, 10515 dbgid); 10516 break; 10517 } 10518 hdd_adapter_dev_put_debug(adapter, dbgid); 10519 } 10520 10521 return adapter; 10522 } 10523 10524 void hdd_adapter_put(struct hdd_adapter *adapter) 10525 { 10526 dev_put(adapter->dev); 10527 } 10528 10529 struct hdd_adapter *hdd_get_adapter_by_iface_name(struct hdd_context *hdd_ctx, 10530 const char *iface_name) 10531 { 10532 struct hdd_adapter *adapter, *next_adapter = NULL; 10533 wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_GET_ADAPTER_BY_IFACE_NAME; 10534 10535 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 10536 dbgid) { 10537 if (!qdf_str_cmp(adapter->dev->name, iface_name)) { 10538 hdd_adapter_dev_put_debug(adapter, dbgid); 10539 if (next_adapter) 10540 hdd_adapter_dev_put_debug(next_adapter, 10541 dbgid); 10542 return adapter; 10543 } 10544 hdd_adapter_dev_put_debug(adapter, dbgid); 10545 } 10546 10547 return NULL; 10548 } 10549 10550 struct hdd_adapter *hdd_get_adapter_by_ifindex(struct hdd_context *hdd_ctx, 10551 uint32_t if_index) 10552 { 10553 struct hdd_adapter *adapter, *next_adapter = NULL; 10554 wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_GET_ADAPTER; 10555 10556 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 10557 dbgid) { 10558 if (adapter->dev->ifindex == if_index) { 10559 hdd_adapter_dev_put_debug(adapter, dbgid); 10560 if (next_adapter) 10561 hdd_adapter_dev_put_debug(next_adapter, 10562 dbgid); 10563 return adapter; 10564 } 10565 hdd_adapter_dev_put_debug(adapter, dbgid); 10566 } 10567 10568 return NULL; 10569 } 10570 10571 /** 10572 * hdd_get_adapter() - to get adapter matching the mode 10573 * @hdd_ctx: hdd context 10574 * @mode: adapter mode 10575 * 10576 * This routine will return the pointer to adapter matching 10577 * with the passed mode. 10578 * 10579 * Return: pointer to adapter or null 10580 */ 10581 struct hdd_adapter *hdd_get_adapter(struct hdd_context *hdd_ctx, 10582 enum QDF_OPMODE mode) 10583 { 10584 struct hdd_adapter *adapter, *next_adapter = NULL; 10585 wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_GET_ADAPTER; 10586 10587 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 10588 dbgid) { 10589 if (adapter->device_mode == mode) { 10590 hdd_adapter_dev_put_debug(adapter, dbgid); 10591 if (next_adapter) 10592 hdd_adapter_dev_put_debug(next_adapter, 10593 dbgid); 10594 return adapter; 10595 } 10596 hdd_adapter_dev_put_debug(adapter, dbgid); 10597 } 10598 10599 return NULL; 10600 } 10601 10602 enum QDF_OPMODE hdd_get_device_mode(uint32_t vdev_id) 10603 { 10604 struct hdd_context *hdd_ctx; 10605 struct wlan_hdd_link_info *link_info; 10606 10607 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 10608 if (!hdd_ctx) 10609 return QDF_MAX_NO_OF_MODE; 10610 10611 link_info = hdd_get_link_info_by_vdev(hdd_ctx, vdev_id); 10612 if (!link_info) { 10613 hdd_err("Invalid vdev"); 10614 return QDF_MAX_NO_OF_MODE; 10615 } 10616 10617 return link_info->adapter->device_mode; 10618 } 10619 10620 uint32_t hdd_get_operating_chan_freq(struct hdd_context *hdd_ctx, 10621 enum QDF_OPMODE mode) 10622 { 10623 struct hdd_adapter *adapter, *next_adapter = NULL; 10624 uint32_t oper_chan_freq = 0; 10625 wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_GET_OPERATING_CHAN_FREQ; 10626 10627 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 10628 dbgid) { 10629 if (mode == adapter->device_mode) { 10630 oper_chan_freq = 10631 hdd_get_link_info_home_channel(adapter->deflink); 10632 hdd_adapter_dev_put_debug(adapter, dbgid); 10633 if (next_adapter) 10634 hdd_adapter_dev_put_debug(next_adapter, 10635 dbgid); 10636 break; 10637 } 10638 hdd_adapter_dev_put_debug(adapter, dbgid); 10639 } 10640 10641 return oper_chan_freq; 10642 } 10643 10644 static inline QDF_STATUS hdd_unregister_wext_all_adapters( 10645 struct hdd_context *hdd_ctx, 10646 bool rtnl_held) 10647 { 10648 struct hdd_adapter *adapter, *next_adapter = NULL; 10649 wlan_net_dev_ref_dbgid dbgid = 10650 NET_DEV_HOLD_UNREGISTER_WEXT_ALL_ADAPTERS; 10651 10652 hdd_enter(); 10653 10654 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 10655 dbgid) { 10656 if (adapter->device_mode == QDF_STA_MODE || 10657 adapter->device_mode == QDF_P2P_CLIENT_MODE || 10658 adapter->device_mode == QDF_P2P_DEVICE_MODE || 10659 adapter->device_mode == QDF_SAP_MODE || 10660 adapter->device_mode == QDF_P2P_GO_MODE) { 10661 hdd_wext_unregister(adapter->dev, rtnl_held); 10662 } 10663 hdd_adapter_dev_put_debug(adapter, dbgid); 10664 } 10665 10666 hdd_exit(); 10667 10668 return QDF_STATUS_SUCCESS; 10669 } 10670 10671 QDF_STATUS hdd_abort_mac_scan_all_adapters(struct hdd_context *hdd_ctx) 10672 { 10673 struct hdd_adapter *adapter, *next_adapter = NULL; 10674 wlan_net_dev_ref_dbgid dbgid = 10675 NET_DEV_HOLD_ABORT_MAC_SCAN_ALL_ADAPTERS; 10676 struct wlan_hdd_link_info *link_info; 10677 10678 hdd_enter(); 10679 10680 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 10681 dbgid) { 10682 if (adapter->device_mode == QDF_STA_MODE || 10683 adapter->device_mode == QDF_P2P_CLIENT_MODE || 10684 adapter->device_mode == QDF_P2P_DEVICE_MODE || 10685 adapter->device_mode == QDF_SAP_MODE || 10686 adapter->device_mode == QDF_P2P_GO_MODE) { 10687 hdd_adapter_for_each_active_link_info(adapter, 10688 link_info) { 10689 wlan_abort_scan(hdd_ctx->pdev, INVAL_PDEV_ID, 10690 link_info->vdev_id, 10691 INVALID_SCAN_ID, true); 10692 } 10693 } 10694 hdd_adapter_dev_put_debug(adapter, dbgid); 10695 } 10696 10697 hdd_exit(); 10698 10699 return QDF_STATUS_SUCCESS; 10700 } 10701 10702 /** 10703 * hdd_abort_sched_scan_all_adapters() - stops scheduled (PNO) scans for all 10704 * adapters 10705 * @hdd_ctx: The HDD context containing the adapters to operate on 10706 * 10707 * return: QDF_STATUS_SUCCESS 10708 */ 10709 static QDF_STATUS hdd_abort_sched_scan_all_adapters(struct hdd_context *hdd_ctx) 10710 { 10711 struct hdd_adapter *adapter, *next_adapter = NULL; 10712 int err; 10713 wlan_net_dev_ref_dbgid dbgid = 10714 NET_DEV_HOLD_ABORT_SCHED_SCAN_ALL_ADAPTERS; 10715 10716 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 10717 dbgid) { 10718 if (adapter->device_mode == QDF_STA_MODE || 10719 adapter->device_mode == QDF_P2P_CLIENT_MODE || 10720 adapter->device_mode == QDF_P2P_DEVICE_MODE || 10721 adapter->device_mode == QDF_SAP_MODE || 10722 adapter->device_mode == QDF_P2P_GO_MODE) { 10723 err = wlan_hdd_sched_scan_stop(adapter->dev); 10724 if (err) 10725 hdd_err("Unable to stop scheduled scan"); 10726 } 10727 hdd_adapter_dev_put_debug(adapter, dbgid); 10728 } 10729 10730 return QDF_STATUS_SUCCESS; 10731 } 10732 10733 /** 10734 * hdd_unregister_notifiers - Unregister netdev notifiers. 10735 * @hdd_ctx: HDD context 10736 * 10737 * Unregister netdev notifiers like IPv4 and IPv6. 10738 * 10739 * Return: None. 10740 */ 10741 void hdd_unregister_notifiers(struct hdd_context *hdd_ctx) 10742 { 10743 osif_dp_nud_unregister_netevent_notifier(hdd_ctx->psoc); 10744 hdd_wlan_unregister_ip6_notifier(hdd_ctx); 10745 10746 unregister_inetaddr_notifier(&hdd_ctx->ipv4_notifier); 10747 } 10748 10749 /** 10750 * hdd_exit_netlink_services - Exit netlink services 10751 * @hdd_ctx: HDD context 10752 * 10753 * Exit netlink services like cnss_diag, cesium netlink socket, ptt socket and 10754 * nl service. 10755 * 10756 * Return: None. 10757 */ 10758 static void hdd_exit_netlink_services(struct hdd_context *hdd_ctx) 10759 { 10760 spectral_scan_deactivate_service(); 10761 cnss_diag_deactivate_service(); 10762 hdd_close_cesium_nl_sock(); 10763 ptt_sock_deactivate_svc(); 10764 hdd_deactivate_wifi_pos(); 10765 10766 nl_srv_exit(); 10767 } 10768 10769 /** 10770 * hdd_init_netlink_services- Init netlink services 10771 * @hdd_ctx: HDD context 10772 * 10773 * Init netlink services like cnss_diag, cesium netlink socket, ptt socket and 10774 * nl service. 10775 * 10776 * Return: 0 on success and errno on failure. 10777 */ 10778 static int hdd_init_netlink_services(struct hdd_context *hdd_ctx) 10779 { 10780 int ret; 10781 10782 ret = wlan_hdd_nl_init(hdd_ctx); 10783 if (ret) { 10784 hdd_err("nl_srv_init failed: %d", ret); 10785 goto out; 10786 } 10787 cds_set_radio_index(hdd_ctx->radio_index); 10788 10789 ret = hdd_activate_wifi_pos(hdd_ctx); 10790 if (ret) { 10791 hdd_err("hdd_activate_wifi_pos failed: %d", ret); 10792 goto err_nl_srv; 10793 } 10794 10795 ptt_sock_activate_svc(); 10796 10797 ret = hdd_open_cesium_nl_sock(); 10798 if (ret) 10799 hdd_err("hdd_open_cesium_nl_sock failed ret: %d", ret); 10800 10801 ret = cnss_diag_activate_service(); 10802 if (ret) { 10803 hdd_err("cnss_diag_activate_service failed: %d", ret); 10804 goto err_close_cesium; 10805 } 10806 10807 spectral_scan_activate_service(hdd_ctx); 10808 10809 return 0; 10810 10811 err_close_cesium: 10812 hdd_close_cesium_nl_sock(); 10813 ptt_sock_deactivate_svc(); 10814 hdd_deactivate_wifi_pos(); 10815 err_nl_srv: 10816 nl_srv_exit(); 10817 out: 10818 return ret; 10819 } 10820 10821 #ifdef SHUTDOWN_WLAN_IN_SYSTEM_SUSPEND 10822 static QDF_STATUS 10823 hdd_shutdown_wlan_in_suspend_prepare(struct hdd_context *hdd_ctx) 10824 { 10825 #define SHUTDOWN_IN_SUSPEND_RETRY 10 10826 10827 int count = 0; 10828 10829 if (ucfg_pmo_get_suspend_mode(hdd_ctx->psoc) != PMO_SUSPEND_SHUTDOWN) { 10830 hdd_debug("shutdown in suspend not supported"); 10831 return 0; 10832 } 10833 10834 while (hdd_is_any_interface_open(hdd_ctx) && 10835 count < SHUTDOWN_IN_SUSPEND_RETRY) { 10836 count++; 10837 hdd_debug_rl("sleep 50ms to wait adapters stopped, #%d", count); 10838 msleep(50); 10839 } 10840 if (count >= SHUTDOWN_IN_SUSPEND_RETRY) { 10841 hdd_err("some adapters not stopped"); 10842 return -EBUSY; 10843 } 10844 10845 hdd_debug("call pld idle shutdown directly"); 10846 return pld_idle_shutdown(hdd_ctx->parent_dev, hdd_psoc_idle_shutdown); 10847 } 10848 10849 static int hdd_pm_notify(struct notifier_block *b, 10850 unsigned long event, void *p) 10851 { 10852 struct hdd_context *hdd_ctx = container_of(b, struct hdd_context, 10853 pm_notifier); 10854 10855 if (wlan_hdd_validate_context(hdd_ctx) != 0) 10856 return NOTIFY_STOP; 10857 10858 hdd_debug("got PM event: %lu", event); 10859 10860 switch (event) { 10861 case PM_SUSPEND_PREPARE: 10862 case PM_HIBERNATION_PREPARE: 10863 if (0 != hdd_shutdown_wlan_in_suspend_prepare(hdd_ctx)) 10864 return NOTIFY_STOP; 10865 break; 10866 case PM_POST_SUSPEND: 10867 case PM_POST_HIBERNATION: 10868 break; 10869 } 10870 10871 return NOTIFY_DONE; 10872 } 10873 10874 static void hdd_pm_notifier_init(struct hdd_context *hdd_ctx) 10875 { 10876 hdd_ctx->pm_notifier.notifier_call = hdd_pm_notify; 10877 register_pm_notifier(&hdd_ctx->pm_notifier); 10878 } 10879 10880 static void hdd_pm_notifier_deinit(struct hdd_context *hdd_ctx) 10881 { 10882 unregister_pm_notifier(&hdd_ctx->pm_notifier); 10883 } 10884 #else 10885 static inline void hdd_pm_notifier_init(struct hdd_context *hdd_ctx) 10886 { 10887 } 10888 10889 static inline void hdd_pm_notifier_deinit(struct hdd_context *hdd_ctx) 10890 { 10891 } 10892 #endif 10893 10894 /** 10895 * hdd_context_deinit() - Deinitialize HDD context 10896 * @hdd_ctx: HDD context. 10897 * 10898 * Deinitialize HDD context along with all the feature specific contexts but 10899 * do not free hdd context itself. Caller of this API is supposed to free 10900 * HDD context. 10901 * 10902 * return: 0 on success and errno on failure. 10903 */ 10904 static int hdd_context_deinit(struct hdd_context *hdd_ctx) 10905 { 10906 qdf_wake_lock_destroy(&hdd_ctx->monitor_mode_wakelock); 10907 10908 wlan_hdd_cfg80211_deinit(hdd_ctx->wiphy); 10909 10910 ucfg_dp_bbm_context_deinit(hdd_ctx->psoc); 10911 10912 hdd_sap_context_destroy(hdd_ctx); 10913 10914 hdd_scan_context_destroy(hdd_ctx); 10915 10916 qdf_list_destroy(&hdd_ctx->hdd_adapters); 10917 10918 return 0; 10919 } 10920 10921 void hdd_context_destroy(struct hdd_context *hdd_ctx) 10922 { 10923 wlan_hdd_sar_timers_deinit(hdd_ctx); 10924 10925 cds_set_context(QDF_MODULE_ID_HDD, NULL); 10926 10927 hdd_exit_netlink_services(hdd_ctx); 10928 10929 hdd_context_deinit(hdd_ctx); 10930 10931 hdd_objmgr_release_and_destroy_psoc(hdd_ctx); 10932 10933 qdf_mem_free(hdd_ctx->config); 10934 hdd_ctx->config = NULL; 10935 cfg_release(); 10936 10937 hdd_pm_notifier_deinit(hdd_ctx); 10938 qdf_delayed_work_destroy(&hdd_ctx->psoc_idle_timeout_work); 10939 wiphy_free(hdd_ctx->wiphy); 10940 } 10941 10942 /** 10943 * wlan_destroy_bug_report_lock() - Destroy bug report lock 10944 * 10945 * This function is used to destroy bug report lock 10946 * 10947 * Return: None 10948 */ 10949 static void wlan_destroy_bug_report_lock(void) 10950 { 10951 struct cds_context *p_cds_context; 10952 10953 p_cds_context = cds_get_global_context(); 10954 if (!p_cds_context) { 10955 hdd_err("cds context is NULL"); 10956 return; 10957 } 10958 10959 qdf_spinlock_destroy(&p_cds_context->bug_report_lock); 10960 } 10961 10962 #ifdef DISABLE_CHANNEL_LIST 10963 static void wlan_hdd_cache_chann_mutex_destroy(struct hdd_context *hdd_ctx) 10964 { 10965 qdf_mutex_destroy(&hdd_ctx->cache_channel_lock); 10966 } 10967 #else 10968 static void wlan_hdd_cache_chann_mutex_destroy(struct hdd_context *hdd_ctx) 10969 { 10970 } 10971 #endif 10972 10973 void hdd_wlan_exit(struct hdd_context *hdd_ctx) 10974 { 10975 struct wiphy *wiphy = hdd_ctx->wiphy; 10976 10977 hdd_enter(); 10978 10979 ucfg_dp_wait_complete_tasks(); 10980 wlan_hdd_destroy_mib_stats_lock(); 10981 hdd_debugfs_ini_config_deinit(hdd_ctx); 10982 hdd_debugfs_mws_coex_info_deinit(hdd_ctx); 10983 hdd_psoc_idle_timer_stop(hdd_ctx); 10984 hdd_regulatory_deinit(hdd_ctx); 10985 10986 /* 10987 * Powersave Offload Case 10988 * Disable Idle Power Save Mode 10989 */ 10990 hdd_set_idle_ps_config(hdd_ctx, false); 10991 /* clear the scan queue in all the scenarios */ 10992 wlan_cfg80211_cleanup_scan_queue(hdd_ctx->pdev, NULL); 10993 10994 if (hdd_ctx->driver_status != DRIVER_MODULES_CLOSED) { 10995 hdd_unregister_wext_all_adapters(hdd_ctx, false); 10996 /* 10997 * Cancel any outstanding scan requests. We are about to close 10998 * all of our adapters, but an adapter structure is what SME 10999 * passes back to our callback function. Hence if there 11000 * are any outstanding scan requests then there is a 11001 * race condition between when the adapter is closed and 11002 * when the callback is invoked. We try to resolve that 11003 * race condition here by canceling any outstanding scans 11004 * before we close the adapters. 11005 * Note that the scans may be cancelled in an asynchronous 11006 * manner, so ideally there needs to be some kind of 11007 * synchronization. Rather than introduce a new 11008 * synchronization here, we will utilize the fact that we are 11009 * about to Request Full Power, and since that is synchronized, 11010 * the expectation is that by the time Request Full Power has 11011 * completed, all scans will be cancelled 11012 */ 11013 hdd_abort_mac_scan_all_adapters(hdd_ctx); 11014 hdd_abort_sched_scan_all_adapters(hdd_ctx); 11015 11016 hdd_stop_all_adapters(hdd_ctx); 11017 hdd_deinit_all_adapters(hdd_ctx, false); 11018 } 11019 11020 unregister_netdevice_notifier(&hdd_netdev_notifier); 11021 11022 qdf_dp_trace_deinit(); 11023 11024 hdd_wlan_stop_modules(hdd_ctx, false); 11025 11026 hdd_driver_memdump_deinit(); 11027 11028 qdf_nbuf_deinit_replenish_timer(); 11029 11030 if (QDF_GLOBAL_MONITOR_MODE == hdd_get_conparam()) { 11031 hdd_info("Release wakelock for monitor mode!"); 11032 qdf_wake_lock_release(&hdd_ctx->monitor_mode_wakelock, 11033 WIFI_POWER_EVENT_WAKELOCK_MONITOR_MODE); 11034 } 11035 11036 qdf_spinlock_destroy(&hdd_ctx->hdd_adapter_lock); 11037 qdf_spinlock_destroy(&hdd_ctx->connection_status_lock); 11038 wlan_hdd_cache_chann_mutex_destroy(hdd_ctx); 11039 11040 osif_request_manager_deinit(); 11041 11042 hdd_close_all_adapters(hdd_ctx, false); 11043 11044 wlansap_global_deinit(); 11045 /* 11046 * If there is re_init failure wiphy would have already de-registered 11047 * check the wiphy status before un-registering again 11048 */ 11049 if (wiphy && wiphy->registered) { 11050 wiphy_unregister(wiphy); 11051 wlan_hdd_cfg80211_deinit(wiphy); 11052 hdd_lpass_notify_stop(hdd_ctx); 11053 } 11054 11055 hdd_deinit_regulatory_update_event(hdd_ctx); 11056 hdd_exit_netlink_services(hdd_ctx); 11057 #ifdef FEATURE_WLAN_CH_AVOID 11058 mutex_destroy(&hdd_ctx->avoid_freq_lock); 11059 #endif 11060 11061 /* This function should be invoked at the end of this api*/ 11062 hdd_dump_func_call_map(); 11063 } 11064 11065 /** 11066 * hdd_wlan_notify_modem_power_state() - notify FW with modem power status 11067 * @state: state 11068 * 11069 * This function notifies FW with modem power status 11070 * 11071 * Return: 0 if successful, error number otherwise 11072 */ 11073 int hdd_wlan_notify_modem_power_state(int state) 11074 { 11075 int status; 11076 QDF_STATUS qdf_status; 11077 struct hdd_context *hdd_ctx; 11078 mac_handle_t mac_handle; 11079 11080 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 11081 status = wlan_hdd_validate_context(hdd_ctx); 11082 if (status) 11083 return status; 11084 11085 mac_handle = hdd_ctx->mac_handle; 11086 if (!mac_handle) 11087 return -EINVAL; 11088 11089 qdf_status = sme_notify_modem_power_state(mac_handle, state); 11090 if (QDF_STATUS_SUCCESS != qdf_status) { 11091 hdd_err("Fail to send notification with modem power state %d", 11092 state); 11093 return -EINVAL; 11094 } 11095 return 0; 11096 } 11097 11098 /** 11099 * hdd_post_cds_enable_config() - HDD post cds start config helper 11100 * @hdd_ctx: Pointer to the HDD 11101 * 11102 * Return: None 11103 */ 11104 QDF_STATUS hdd_post_cds_enable_config(struct hdd_context *hdd_ctx) 11105 { 11106 QDF_STATUS qdf_ret_status; 11107 11108 /* 11109 * Send ready indication to the HDD. This will kick off the MAC 11110 * into a 'running' state and should kick off an initial scan. 11111 */ 11112 qdf_ret_status = sme_hdd_ready_ind(hdd_ctx->mac_handle); 11113 if (!QDF_IS_STATUS_SUCCESS(qdf_ret_status)) { 11114 hdd_err("sme_hdd_ready_ind() failed with status code %08d [x%08x]", 11115 qdf_ret_status, qdf_ret_status); 11116 return QDF_STATUS_E_FAILURE; 11117 } 11118 11119 return QDF_STATUS_SUCCESS; 11120 } 11121 11122 struct hdd_adapter *hdd_get_first_valid_adapter(struct hdd_context *hdd_ctx) 11123 { 11124 struct hdd_adapter *adapter, *next_adapter = NULL; 11125 wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_GET_FIRST_VALID_ADAPTER; 11126 11127 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 11128 dbgid) { 11129 if (adapter && adapter->magic == WLAN_HDD_ADAPTER_MAGIC) { 11130 hdd_adapter_dev_put_debug(adapter, dbgid); 11131 if (next_adapter) 11132 hdd_adapter_dev_put_debug(next_adapter, 11133 dbgid); 11134 return adapter; 11135 } 11136 hdd_adapter_dev_put_debug(adapter, dbgid); 11137 } 11138 11139 return NULL; 11140 } 11141 11142 /* wake lock APIs for HDD */ 11143 void hdd_prevent_suspend(uint32_t reason) 11144 { 11145 qdf_wake_lock_acquire(&wlan_wake_lock, reason); 11146 } 11147 11148 void hdd_allow_suspend(uint32_t reason) 11149 { 11150 qdf_wake_lock_release(&wlan_wake_lock, reason); 11151 } 11152 11153 void hdd_prevent_suspend_timeout(uint32_t timeout, uint32_t reason) 11154 { 11155 cds_host_diag_log_work(&wlan_wake_lock, timeout, reason); 11156 qdf_wake_lock_timeout_acquire(&wlan_wake_lock, timeout); 11157 } 11158 11159 /* Initialize channel list in sme based on the country code */ 11160 QDF_STATUS hdd_set_sme_chan_list(struct hdd_context *hdd_ctx) 11161 { 11162 return sme_init_chan_list(hdd_ctx->mac_handle, 11163 hdd_ctx->reg.cc_src); 11164 } 11165 11166 /** 11167 * hdd_is_5g_supported() - check if hardware supports 5GHz 11168 * @hdd_ctx: Pointer to the hdd context 11169 * 11170 * HDD function to know if hardware supports 5GHz 11171 * 11172 * Return: true if hardware supports 5GHz 11173 */ 11174 bool hdd_is_5g_supported(struct hdd_context *hdd_ctx) 11175 { 11176 if (!hdd_ctx) 11177 return true; 11178 11179 if (hdd_ctx->curr_band != BAND_2G) 11180 return true; 11181 else 11182 return false; 11183 } 11184 11185 bool hdd_is_2g_supported(struct hdd_context *hdd_ctx) 11186 { 11187 if (!hdd_ctx) 11188 return false; 11189 11190 if (hdd_ctx->curr_band != BAND_5G) 11191 return true; 11192 else 11193 return false; 11194 } 11195 11196 static int hdd_wiphy_init(struct hdd_context *hdd_ctx) 11197 { 11198 struct wiphy *wiphy; 11199 int ret_val; 11200 uint32_t channel_bonding_mode; 11201 11202 wiphy = hdd_ctx->wiphy; 11203 11204 /* 11205 * The channel information in 11206 * wiphy needs to be initialized before wiphy registration 11207 */ 11208 ret_val = hdd_regulatory_init(hdd_ctx, wiphy); 11209 if (ret_val) { 11210 hdd_err("regulatory init failed"); 11211 return ret_val; 11212 } 11213 11214 if (ucfg_pmo_get_suspend_mode(hdd_ctx->psoc) == PMO_SUSPEND_WOW) { 11215 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0)) 11216 wiphy->wowlan = &wowlan_support_reg_init; 11217 #else 11218 wiphy->wowlan.flags = WIPHY_WOWLAN_ANY | 11219 WIPHY_WOWLAN_MAGIC_PKT | 11220 WIPHY_WOWLAN_DISCONNECT | 11221 WIPHY_WOWLAN_SUPPORTS_GTK_REKEY | 11222 WIPHY_WOWLAN_GTK_REKEY_FAILURE | 11223 WIPHY_WOWLAN_EAP_IDENTITY_REQ | 11224 WIPHY_WOWLAN_4WAY_HANDSHAKE | 11225 WIPHY_WOWLAN_RFKILL_RELEASE; 11226 11227 wiphy->wowlan.n_patterns = (WOW_MAX_FILTER_LISTS * 11228 WOW_MAX_FILTERS_PER_LIST); 11229 wiphy->wowlan.pattern_min_len = WOW_MIN_PATTERN_SIZE; 11230 wiphy->wowlan.pattern_max_len = WOW_MAX_PATTERN_SIZE; 11231 #endif 11232 } 11233 11234 ucfg_mlme_get_channel_bonding_24ghz(hdd_ctx->psoc, 11235 &channel_bonding_mode); 11236 if (hdd_ctx->obss_scan_offload) { 11237 hdd_debug("wmi_service_obss_scan supported"); 11238 } else if (channel_bonding_mode) { 11239 hdd_debug("enable wpa_supp obss_scan"); 11240 wiphy->features |= NL80211_FEATURE_NEED_OBSS_SCAN; 11241 } 11242 11243 if (hdd_ctx->num_rf_chains == HDD_ANTENNA_MODE_2X2 && 11244 ucfg_mlme_is_chain_mask_supported(hdd_ctx->psoc)) { 11245 wiphy->available_antennas_tx = HDD_CHAIN_MODE_2X2; 11246 wiphy->available_antennas_rx = HDD_CHAIN_MODE_2X2; 11247 } 11248 /* registration of wiphy dev with cfg80211 */ 11249 ret_val = wlan_hdd_cfg80211_register(wiphy); 11250 if (0 > ret_val) { 11251 hdd_err("wiphy registration failed"); 11252 return ret_val; 11253 } 11254 11255 /* Check the kernel version for upstream commit aced43ce780dc5 that 11256 * has support for processing user cell_base hints when wiphy is 11257 * self managed or check the backport flag for the same. 11258 */ 11259 #if defined CFG80211_USER_HINT_CELL_BASE_SELF_MANAGED || \ 11260 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 18, 0)) 11261 hdd_send_wiphy_regd_sync_event(hdd_ctx); 11262 #endif 11263 11264 pld_increment_driver_load_cnt(hdd_ctx->parent_dev); 11265 11266 return ret_val; 11267 } 11268 11269 #ifdef WLAN_FEATURE_DP_BUS_BANDWIDTH 11270 #ifdef CLD_PM_QOS 11271 #define PLD_REMOVE_PM_QOS(x) 11272 #define PLD_REQUEST_PM_QOS(x, y) 11273 #define HDD_PM_QOS_HIGH_TPUT_LATENCY_US 1 11274 11275 /** 11276 * hdd_pm_qos_update_cpu_mask() - Prepare CPU mask for PM_qos voting 11277 * @mask: return variable of cpumask for the TPUT 11278 * @enable_perf_cluster: Enable PERF cluster or not 11279 * 11280 * By default, the function sets CPU mask for silver cluster unless 11281 * enable_perf_cluster is set as true. 11282 * 11283 * Return: none 11284 */ 11285 static inline void hdd_pm_qos_update_cpu_mask(cpumask_t *mask, 11286 bool enable_perf_cluster) 11287 { 11288 cpumask_set_cpu(0, mask); 11289 cpumask_set_cpu(1, mask); 11290 cpumask_set_cpu(2, mask); 11291 cpumask_set_cpu(3, mask); 11292 11293 if (enable_perf_cluster) { 11294 cpumask_set_cpu(4, mask); 11295 cpumask_set_cpu(5, mask); 11296 cpumask_set_cpu(6, mask); 11297 } 11298 } 11299 11300 #ifdef MSM_PLATFORM 11301 #define COPY_CPU_MASK(a, b) cpumask_copy(a, b) 11302 #define DUMP_CPU_AFFINE() hdd_info("Set cpu_mask %*pb for affine_cores", \ 11303 cpumask_pr_args(&hdd_ctx->pm_qos_req.cpus_affine)) 11304 #else 11305 #define COPY_CPU_MASK(a, b) /* no-op*/ 11306 #define DUMP_CPU_AFFINE() /* no-op*/ 11307 #endif 11308 11309 #ifdef CLD_DEV_PM_QOS 11310 11311 static inline void _hdd_pm_qos_update_request(struct hdd_context *hdd_ctx, 11312 cpumask_t *pm_qos_cpu_mask, 11313 unsigned int latency) 11314 { 11315 int cpu; 11316 uint32_t default_latency; 11317 11318 default_latency = wlan_hdd_get_default_pm_qos_cpu_latency(); 11319 qdf_cpumask_copy(&hdd_ctx->qos_cpu_mask, pm_qos_cpu_mask); 11320 11321 if (qdf_cpumask_empty(pm_qos_cpu_mask)) { 11322 for_each_present_cpu(cpu) { 11323 dev_pm_qos_update_request( 11324 &hdd_ctx->pm_qos_req[cpu], 11325 default_latency); 11326 } 11327 hdd_debug("Empty mask %*pb: Set latency %u", 11328 qdf_cpumask_pr_args(&hdd_ctx->qos_cpu_mask), 11329 default_latency); 11330 } else { /* Set latency to default for CPUs not included in mask */ 11331 qdf_for_each_cpu_not(cpu, &hdd_ctx->qos_cpu_mask) { 11332 dev_pm_qos_update_request( 11333 &hdd_ctx->pm_qos_req[cpu], 11334 default_latency); 11335 } 11336 /* Set latency for CPUs included in mask */ 11337 qdf_for_each_cpu(cpu, &hdd_ctx->qos_cpu_mask) { 11338 dev_pm_qos_update_request( 11339 &hdd_ctx->pm_qos_req[cpu], 11340 latency); 11341 } 11342 hdd_debug("For qos_cpu_mask %*pb set latency %u", 11343 qdf_cpumask_pr_args(&hdd_ctx->qos_cpu_mask), 11344 latency); 11345 } 11346 } 11347 11348 /** 11349 * hdd_pm_qos_update_request() - API to request for pm_qos 11350 * @hdd_ctx: handle to hdd context 11351 * @pm_qos_cpu_mask: cpu_mask to apply 11352 * 11353 * Return: none 11354 */ 11355 static void hdd_pm_qos_update_request(struct hdd_context *hdd_ctx, 11356 cpumask_t *pm_qos_cpu_mask) 11357 { 11358 unsigned int latency; 11359 11360 if (qdf_cpumask_empty(pm_qos_cpu_mask)) 11361 latency = wlan_hdd_get_default_pm_qos_cpu_latency(); 11362 else 11363 latency = HDD_PM_QOS_HIGH_TPUT_LATENCY_US; 11364 11365 _hdd_pm_qos_update_request(hdd_ctx, pm_qos_cpu_mask, latency); 11366 } 11367 11368 static inline void hdd_pm_qos_add_request(struct hdd_context *hdd_ctx) 11369 { 11370 struct device *cpu_dev; 11371 int cpu; 11372 uint32_t default_latency = wlan_hdd_get_default_pm_qos_cpu_latency(); 11373 11374 11375 qdf_cpumask_clear(&hdd_ctx->qos_cpu_mask); 11376 hdd_pm_qos_update_cpu_mask(&hdd_ctx->qos_cpu_mask, false); 11377 11378 for_each_present_cpu(cpu) { 11379 cpu_dev = get_cpu_device(cpu); 11380 dev_pm_qos_add_request(cpu_dev, &hdd_ctx->pm_qos_req[cpu], 11381 DEV_PM_QOS_RESUME_LATENCY, 11382 default_latency); 11383 hdd_debug("Set qos_cpu_mask %*pb for affine_cores", 11384 cpumask_pr_args(&hdd_ctx->qos_cpu_mask)); 11385 } 11386 } 11387 11388 static inline void hdd_pm_qos_remove_request(struct hdd_context *hdd_ctx) 11389 { 11390 int cpu; 11391 11392 for_each_present_cpu(cpu) { 11393 dev_pm_qos_remove_request(&hdd_ctx->pm_qos_req[cpu]); 11394 hdd_debug("Remove dev_pm_qos_request for all cpus: %d", cpu); 11395 } 11396 qdf_cpumask_clear(&hdd_ctx->qos_cpu_mask); 11397 } 11398 11399 #else /* CLD_DEV_PM_QOS */ 11400 11401 #if defined(CONFIG_SMP) && defined(MSM_PLATFORM) 11402 /** 11403 * hdd_set_default_pm_qos_mask() - Update PM_qos request for AFFINE_CORES 11404 * @hdd_ctx: handle to hdd context 11405 * 11406 * Return: none 11407 */ 11408 static inline void hdd_set_default_pm_qos_mask(struct hdd_context *hdd_ctx) 11409 { 11410 hdd_ctx->pm_qos_req.type = PM_QOS_REQ_AFFINE_CORES; 11411 qdf_cpumask_clear(&hdd_ctx->pm_qos_req.cpus_affine); 11412 hdd_pm_qos_update_cpu_mask(&hdd_ctx->pm_qos_req.cpus_affine, false); 11413 } 11414 #else 11415 static inline void hdd_set_default_pm_qos_mask(struct hdd_context *hdd_ctx) 11416 { 11417 } 11418 #endif 11419 11420 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 7, 0)) 11421 /** 11422 * hdd_pm_qos_update_request() - API to request for pm_qos 11423 * @hdd_ctx: handle to hdd context 11424 * @pm_qos_cpu_mask: cpu_mask to apply 11425 * 11426 * Return: none 11427 */ 11428 static inline void hdd_pm_qos_update_request(struct hdd_context *hdd_ctx, 11429 cpumask_t *pm_qos_cpu_mask) 11430 { 11431 COPY_CPU_MASK(&hdd_ctx->pm_qos_req.cpus_affine, pm_qos_cpu_mask); 11432 11433 if (cpumask_empty(pm_qos_cpu_mask)) 11434 cpu_latency_qos_update_request(&hdd_ctx->pm_qos_req, 11435 PM_QOS_DEFAULT_VALUE); 11436 else 11437 cpu_latency_qos_update_request(&hdd_ctx->pm_qos_req, 1); 11438 } 11439 11440 static inline void hdd_pm_qos_add_request(struct hdd_context *hdd_ctx) 11441 { 11442 hdd_set_default_pm_qos_mask(hdd_ctx); 11443 cpu_latency_qos_add_request(&hdd_ctx->pm_qos_req, PM_QOS_DEFAULT_VALUE); 11444 DUMP_CPU_AFFINE(); 11445 } 11446 11447 static inline void hdd_pm_qos_remove_request(struct hdd_context *hdd_ctx) 11448 { 11449 cpu_latency_qos_remove_request(&hdd_ctx->pm_qos_req); 11450 } 11451 #else 11452 static inline void hdd_pm_qos_update_request(struct hdd_context *hdd_ctx, 11453 cpumask_t *pm_qos_cpu_mask) 11454 { 11455 COPY_CPU_MASK(&hdd_ctx->pm_qos_req.cpus_affine, pm_qos_cpu_mask); 11456 11457 if (cpumask_empty(pm_qos_cpu_mask)) 11458 pm_qos_update_request(&hdd_ctx->pm_qos_req, 11459 PM_QOS_DEFAULT_VALUE); 11460 else 11461 pm_qos_update_request(&hdd_ctx->pm_qos_req, 1); 11462 } 11463 11464 static inline void hdd_pm_qos_add_request(struct hdd_context *hdd_ctx) 11465 { 11466 hdd_set_default_pm_qos_mask(hdd_ctx); 11467 pm_qos_add_request(&hdd_ctx->pm_qos_req, PM_QOS_CPU_DMA_LATENCY, 11468 PM_QOS_DEFAULT_VALUE); 11469 DUMP_CPU_AFFINE(); 11470 } 11471 11472 static inline void hdd_pm_qos_remove_request(struct hdd_context *hdd_ctx) 11473 { 11474 pm_qos_remove_request(&hdd_ctx->pm_qos_req); 11475 } 11476 #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(5, 7, 0) */ 11477 #endif /* CLD_DEV_PM_QOS */ 11478 11479 #else /* CLD_PM_QOS */ 11480 #define PLD_REMOVE_PM_QOS(x) pld_remove_pm_qos(x) 11481 #define PLD_REQUEST_PM_QOS(x, y) pld_request_pm_qos(x, y) 11482 11483 static inline void hdd_pm_qos_add_request(struct hdd_context *hdd_ctx) 11484 { 11485 } 11486 11487 static inline void hdd_pm_qos_remove_request(struct hdd_context *hdd_ctx) 11488 { 11489 } 11490 11491 static inline void hdd_pm_qos_update_cpu_mask(cpumask_t *mask, 11492 bool high_throughput) 11493 { 11494 } 11495 11496 static inline void hdd_pm_qos_update_request(struct hdd_context *hdd_ctx, 11497 cpumask_t *pm_qos_cpu_mask) 11498 { 11499 } 11500 #endif /* CLD_PM_QOS */ 11501 11502 #if defined(CLD_PM_QOS) 11503 #if defined(CLD_DEV_PM_QOS) 11504 void wlan_hdd_set_pm_qos_request(struct hdd_context *hdd_ctx, 11505 bool pm_qos_request) 11506 { 11507 cpumask_t pm_qos_cpu_mask; 11508 11509 cpumask_clear(&pm_qos_cpu_mask); 11510 if (pm_qos_request) { 11511 hdd_ctx->pm_qos_request = true; 11512 if (!hdd_ctx->hbw_requested) { 11513 hdd_pm_qos_update_cpu_mask(&pm_qos_cpu_mask, true); 11514 hdd_pm_qos_update_request(hdd_ctx, &pm_qos_cpu_mask); 11515 hdd_ctx->hbw_requested = true; 11516 } 11517 } else { 11518 if (hdd_ctx->hbw_requested) { 11519 hdd_pm_qos_update_cpu_mask(&pm_qos_cpu_mask, false); 11520 hdd_pm_qos_update_request(hdd_ctx, &pm_qos_cpu_mask); 11521 hdd_ctx->hbw_requested = false; 11522 } 11523 hdd_ctx->pm_qos_request = false; 11524 } 11525 } 11526 #else /* CLD_DEV_PM_QOS */ 11527 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 7, 0)) 11528 void wlan_hdd_set_pm_qos_request(struct hdd_context *hdd_ctx, 11529 bool pm_qos_request) 11530 { 11531 if (pm_qos_request) { 11532 hdd_ctx->pm_qos_request = true; 11533 if (!hdd_ctx->hbw_requested) { 11534 cpumask_setall(&hdd_ctx->pm_qos_req.cpus_affine); 11535 cpu_latency_qos_update_request( 11536 &hdd_ctx->pm_qos_req, 11537 DISABLE_KRAIT_IDLE_PS_VAL); 11538 hdd_ctx->hbw_requested = true; 11539 } 11540 } else { 11541 if (hdd_ctx->hbw_requested) { 11542 cpumask_clear(&hdd_ctx->pm_qos_req.cpus_affine); 11543 cpu_latency_qos_update_request(&hdd_ctx->pm_qos_req, 11544 PM_QOS_DEFAULT_VALUE); 11545 hdd_ctx->hbw_requested = false; 11546 } 11547 hdd_ctx->pm_qos_request = false; 11548 } 11549 } 11550 #else /* (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 7, 0)) */ 11551 void wlan_hdd_set_pm_qos_request(struct hdd_context *hdd_ctx, 11552 bool pm_qos_request) 11553 { 11554 if (pm_qos_request) { 11555 hdd_ctx->pm_qos_request = true; 11556 if (!hdd_ctx->hbw_requested) { 11557 cpumask_setall(&hdd_ctx->pm_qos_req.cpus_affine); 11558 pm_qos_update_request(&hdd_ctx->pm_qos_req, 11559 DISABLE_KRAIT_IDLE_PS_VAL); 11560 hdd_ctx->hbw_requested = true; 11561 } 11562 } else { 11563 if (hdd_ctx->hbw_requested) { 11564 cpumask_clear(&hdd_ctx->pm_qos_req.cpus_affine); 11565 pm_qos_update_request(&hdd_ctx->pm_qos_req, 11566 PM_QOS_DEFAULT_VALUE); 11567 hdd_ctx->hbw_requested = false; 11568 } 11569 hdd_ctx->pm_qos_request = false; 11570 } 11571 } 11572 #endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 7, 0)) */ 11573 #endif /* CLD_DEV_PM_QOS*/ 11574 #endif /* CLD_PM_QOS */ 11575 11576 #define HDD_BW_GET_DIFF(_x, _y) (unsigned long)((ULONG_MAX - (_y)) + (_x) + 1) 11577 11578 #ifdef WLAN_FEATURE_MSCS 11579 11580 static 11581 void hdd_send_mscs_action_frame(struct wlan_hdd_link_info *link_info) 11582 { 11583 struct hdd_context *hdd_ctx = link_info->adapter->hdd_ctx; 11584 uint64_t mscs_vo_pkt_delta; 11585 unsigned long tx_vo_pkts = 0; 11586 unsigned int cpu; 11587 struct hdd_tx_rx_stats *stats = &link_info->hdd_stats.tx_rx_stats; 11588 uint32_t bus_bw_compute_interval; 11589 11590 /* 11591 * To disable MSCS feature in driver set mscs_pkt_threshold = 0 11592 * in ini file. 11593 */ 11594 if (!hdd_ctx->config->mscs_pkt_threshold) 11595 return; 11596 11597 for (cpu = 0; cpu < NUM_CPUS; cpu++) 11598 tx_vo_pkts += stats->per_cpu[cpu].tx_classified_ac[SME_AC_VO]; 11599 11600 if (!link_info->mscs_counter) 11601 link_info->mscs_prev_tx_vo_pkts = tx_vo_pkts; 11602 11603 link_info->mscs_counter++; 11604 bus_bw_compute_interval = 11605 ucfg_dp_get_bus_bw_compute_interval(hdd_ctx->psoc); 11606 if (link_info->mscs_counter * bus_bw_compute_interval >= 11607 hdd_ctx->config->mscs_voice_interval * 1000) { 11608 link_info->mscs_counter = 0; 11609 mscs_vo_pkt_delta = 11610 HDD_BW_GET_DIFF(tx_vo_pkts, 11611 link_info->mscs_prev_tx_vo_pkts); 11612 if (mscs_vo_pkt_delta > hdd_ctx->config->mscs_pkt_threshold && 11613 !mlme_get_is_mscs_req_sent(link_info->vdev)) 11614 sme_send_mscs_action_frame(link_info->vdev_id); 11615 } 11616 } 11617 #else 11618 static inline 11619 void hdd_send_mscs_action_frame(struct wlan_hdd_link_info *link_info) 11620 { 11621 } 11622 #endif 11623 #endif /*WLAN_FEATURE_DP_BUS_BANDWIDTH*/ 11624 11625 /** 11626 * wlan_hdd_sta_get_dot11mode() - GET AP client count 11627 * @context: HDD context 11628 * @netdev: netdev 11629 * @dot11_mode: variable in which mode need to update. 11630 * 11631 * Return: true on success else false 11632 */ 11633 static inline 11634 bool wlan_hdd_sta_get_dot11mode(hdd_cb_handle context, qdf_netdev_t netdev, 11635 enum qca_wlan_802_11_mode *dot11_mode) 11636 { 11637 struct hdd_context *hdd_ctx; 11638 struct wlan_hdd_link_info *link_info; 11639 struct hdd_station_ctx *sta_ctx; 11640 struct hdd_adapter *adapter; 11641 enum csr_cfgdot11mode mode; 11642 11643 hdd_ctx = hdd_cb_handle_to_context(context); 11644 if (!hdd_ctx) 11645 return false; 11646 11647 adapter = WLAN_HDD_GET_PRIV_PTR(netdev); 11648 if (!adapter) 11649 return false; 11650 11651 link_info = adapter->deflink; 11652 11653 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(link_info); 11654 mode = sta_ctx->conn_info.dot11mode; 11655 *dot11_mode = hdd_convert_cfgdot11mode_to_80211mode(mode); 11656 return true; 11657 } 11658 11659 /** 11660 * wlan_hdd_get_ap_client_count() - GET AP client count 11661 * @context: HDD context 11662 * @netdev: netdev 11663 * @client_count: variable in which number of client need to update. 11664 * 11665 * Return: true on success else false 11666 */ 11667 static inline 11668 bool wlan_hdd_get_ap_client_count(hdd_cb_handle context, qdf_netdev_t netdev, 11669 uint16_t *client_count) 11670 { 11671 struct hdd_context *hdd_ctx; 11672 struct wlan_hdd_link_info *link_info; 11673 struct hdd_adapter *adapter; 11674 struct hdd_ap_ctx *ap_ctx; 11675 enum qca_wlan_802_11_mode i; 11676 11677 hdd_ctx = hdd_cb_handle_to_context(context); 11678 if (!hdd_ctx) { 11679 hdd_err("hdd ctx is null"); 11680 return false; 11681 } 11682 11683 adapter = WLAN_HDD_GET_PRIV_PTR(netdev); 11684 if (!adapter) { 11685 hdd_err("adapter is null"); 11686 return false; 11687 } 11688 11689 link_info = adapter->deflink; 11690 ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(link_info); 11691 if (!ap_ctx->ap_active) 11692 return false; 11693 11694 for (i = QCA_WLAN_802_11_MODE_11B; i < QCA_WLAN_802_11_MODE_INVALID; 11695 i++) 11696 client_count[i] = ap_ctx->client_count[i]; 11697 11698 return true; 11699 } 11700 11701 /** 11702 * wlan_hdd_sta_ndi_connected() - Check if NDI connected 11703 * @context: HDD context 11704 * @netdev: netdev 11705 * 11706 * Return: true if NDI connected else false 11707 */ 11708 static inline 11709 bool wlan_hdd_sta_ndi_connected(hdd_cb_handle context, qdf_netdev_t netdev) 11710 { 11711 struct hdd_adapter *adapter; 11712 struct hdd_context *hdd_ctx; 11713 struct wlan_hdd_link_info *link_info; 11714 struct hdd_station_ctx *sta_ctx; 11715 11716 hdd_ctx = hdd_cb_handle_to_context(context); 11717 if (!hdd_ctx) { 11718 hdd_err("hdd_ctx is null"); 11719 return false; 11720 } 11721 11722 adapter = WLAN_HDD_GET_PRIV_PTR(netdev); 11723 if (!adapter) { 11724 hdd_err("adapter is null"); 11725 return false; 11726 } 11727 11728 link_info = adapter->deflink; 11729 11730 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(link_info); 11731 if (sta_ctx->conn_info.conn_state != eConnectionState_NdiConnected) 11732 return false; 11733 11734 return true; 11735 } 11736 11737 /** 11738 * wlan_hdd_pktlog_enable_disable() - Enable/Disable packet logging 11739 * @context: HDD context 11740 * @enable_disable_flag: Flag to enable/disable 11741 * @user_triggered: triggered through iwpriv 11742 * @size: buffer size to be used for packetlog 11743 * 11744 * Return: 0 on success; error number otherwise 11745 */ 11746 static inline 11747 int wlan_hdd_pktlog_enable_disable(hdd_cb_handle context, 11748 bool enable_disable_flag, 11749 uint8_t user_triggered, int size) 11750 { 11751 struct hdd_context *hdd_ctx = hdd_cb_handle_to_context(context); 11752 11753 if (!hdd_ctx) { 11754 hdd_err("hdd_ctx is null"); 11755 return -EINVAL; 11756 } 11757 return hdd_pktlog_enable_disable(hdd_ctx, enable_disable_flag, 11758 user_triggered, size); 11759 } 11760 11761 /** 11762 * wlan_hdd_is_roaming_in_progress() - Check if roaming is in progress 11763 * @context: HDD context 11764 * 11765 * Return: true if roaming is in progress else false 11766 */ 11767 static inline bool wlan_hdd_is_roaming_in_progress(hdd_cb_handle context) 11768 { 11769 struct hdd_context *hdd_ctx = hdd_cb_handle_to_context(context); 11770 11771 if (!hdd_ctx) { 11772 hdd_err("hdd_ctx is null"); 11773 return false; 11774 } 11775 return hdd_is_roaming_in_progress(hdd_ctx); 11776 } 11777 11778 /** 11779 * hdd_is_ap_active() - Check if AP is active 11780 * @context: HDD context 11781 * @netdev: netdev 11782 * 11783 * Return: true if AP active else false 11784 */ 11785 static inline bool hdd_is_ap_active(hdd_cb_handle context, qdf_netdev_t netdev) 11786 { 11787 struct hdd_adapter *adapter; 11788 struct hdd_context *hdd_ctx; 11789 struct wlan_hdd_link_info *link_info; 11790 11791 hdd_ctx = hdd_cb_handle_to_context(context); 11792 if (!hdd_ctx) { 11793 hdd_err("hdd_ctx is null"); 11794 return false; 11795 } 11796 11797 adapter = WLAN_HDD_GET_PRIV_PTR(netdev); 11798 if (!adapter) { 11799 hdd_err("adapter is null"); 11800 return false; 11801 } 11802 11803 link_info = adapter->deflink; 11804 return WLAN_HDD_GET_AP_CTX_PTR(link_info)->ap_active; 11805 } 11806 11807 /** 11808 * wlan_hdd_napi_apply_throughput_policy() - Apply NAPI policy 11809 * @context: HDD context 11810 * @tx_packets: tx_packets 11811 * @rx_packets: rx_packets 11812 * 11813 * Return: 0 on success else error code 11814 */ 11815 static inline 11816 int wlan_hdd_napi_apply_throughput_policy(hdd_cb_handle context, 11817 uint64_t tx_packets, 11818 uint64_t rx_packets) 11819 { 11820 struct hdd_context *hdd_ctx = hdd_cb_handle_to_context(context); 11821 int rc = 0; 11822 11823 if (!hdd_ctx) { 11824 hdd_err("hdd_ctx is null"); 11825 return 0; 11826 } 11827 if (hdd_ctx->config->napi_cpu_affinity_mask) 11828 rc = hdd_napi_apply_throughput_policy(hdd_ctx, tx_packets, 11829 rx_packets); 11830 return rc; 11831 } 11832 11833 /** 11834 * hdd_is_link_adapter() - Check if adapter is link adapter 11835 * @context: HDD context 11836 * @vdev_id: Vdev ID 11837 * 11838 * Return: true if link adapter else false 11839 */ 11840 static inline bool hdd_is_link_adapter(hdd_cb_handle context, uint8_t vdev_id) 11841 { 11842 struct hdd_context *hdd_ctx; 11843 struct wlan_hdd_link_info *link_info; 11844 11845 hdd_ctx = hdd_cb_handle_to_context(context); 11846 if (!hdd_ctx) { 11847 hdd_err("hdd_ctx is null"); 11848 return false; 11849 } 11850 11851 link_info = hdd_get_link_info_by_vdev(hdd_ctx, vdev_id); 11852 if (!link_info) { 11853 hdd_err("Invalid vdev"); 11854 return false; 11855 } 11856 return hdd_adapter_is_link_adapter(link_info->adapter); 11857 } 11858 11859 /** 11860 * hdd_get_pause_map() - Get pause map value 11861 * @context: HDD context 11862 * @netdev: netdev 11863 * 11864 * Return: pause map value 11865 */ 11866 static inline 11867 uint32_t hdd_get_pause_map(hdd_cb_handle context, qdf_netdev_t netdev) 11868 { 11869 struct hdd_adapter *adapter; 11870 11871 adapter = WLAN_HDD_GET_PRIV_PTR(netdev); 11872 if (!adapter) { 11873 hdd_err("adapter is null"); 11874 return 0; 11875 } 11876 11877 return adapter->pause_map; 11878 } 11879 11880 /** 11881 * hdd_any_adapter_connected() - Check if any adapter connected. 11882 * @context: HDD context 11883 * 11884 * Return: True if connected else false. 11885 */ 11886 static inline bool hdd_any_adapter_connected(hdd_cb_handle context) 11887 { 11888 struct hdd_context *hdd_ctx = hdd_cb_handle_to_context(context); 11889 11890 if (!hdd_ctx) { 11891 hdd_err("hdd_ctx is null"); 11892 return false; 11893 } 11894 11895 return hdd_is_any_adapter_connected(hdd_ctx); 11896 } 11897 11898 #ifdef WLAN_FEATURE_DP_BUS_BANDWIDTH 11899 /** 11900 * hdd_pld_request_pm_qos() - Request PLD PM QoS request 11901 * @context: HDD context 11902 * 11903 * Return: None 11904 */ 11905 static inline void hdd_pld_request_pm_qos(hdd_cb_handle context) 11906 { 11907 struct hdd_context *hdd_ctx = hdd_cb_handle_to_context(context); 11908 11909 if (!hdd_ctx) { 11910 hdd_err("hdd_ctx is null"); 11911 return; 11912 } 11913 11914 if (!hdd_ctx->hbw_requested) { 11915 PLD_REQUEST_PM_QOS(hdd_ctx->parent_dev, 1); 11916 hdd_ctx->hbw_requested = true; 11917 } 11918 } 11919 11920 /** 11921 * hdd_pld_remove_pm_qos() - Remove PLD PM QoS request 11922 * @context: HDD context 11923 * 11924 * Return: None 11925 */ 11926 static inline void hdd_pld_remove_pm_qos(hdd_cb_handle context) 11927 { 11928 struct hdd_context *hdd_ctx = hdd_cb_handle_to_context(context); 11929 11930 if (!hdd_ctx) { 11931 hdd_err("hdd_ctx is null"); 11932 return; 11933 } 11934 11935 if (hdd_ctx->hbw_requested && 11936 !hdd_ctx->pm_qos_request) { 11937 PLD_REMOVE_PM_QOS(hdd_ctx->parent_dev); 11938 hdd_ctx->hbw_requested = false; 11939 } 11940 } 11941 11942 /** 11943 * wlan_hdd_pm_qos_update_request() - Update PM QoS request 11944 * @context: HDD context 11945 * @pm_qos_cpu_mask: CPU mask 11946 * 11947 * Return: None 11948 */ 11949 static inline void 11950 wlan_hdd_pm_qos_update_request(hdd_cb_handle context, 11951 cpumask_t *pm_qos_cpu_mask) 11952 { 11953 struct hdd_context *hdd_ctx = hdd_cb_handle_to_context(context); 11954 11955 if (!hdd_ctx) { 11956 hdd_err("hdd_ctx is null"); 11957 return; 11958 } 11959 11960 if (!hdd_ctx->pm_qos_request) 11961 hdd_pm_qos_update_request(hdd_ctx, pm_qos_cpu_mask); 11962 } 11963 11964 /** 11965 * wlan_hdd_pm_qos_add_request() - Add PM QoS request 11966 * @context: HDD context 11967 * 11968 * Return: None 11969 */ 11970 static inline void wlan_hdd_pm_qos_add_request(hdd_cb_handle context) 11971 { 11972 struct hdd_context *hdd_ctx = hdd_cb_handle_to_context(context); 11973 11974 if (!hdd_ctx) { 11975 hdd_err("hdd_ctx is null"); 11976 return; 11977 } 11978 11979 hdd_pm_qos_add_request(hdd_ctx); 11980 } 11981 11982 /** 11983 * wlan_hdd_pm_qos_remove_request() - remove PM QoS request 11984 * @context: HDD context 11985 * 11986 * Return: None 11987 */ 11988 static inline void wlan_hdd_pm_qos_remove_request(hdd_cb_handle context) 11989 { 11990 struct hdd_context *hdd_ctx = hdd_cb_handle_to_context(context); 11991 11992 if (!hdd_ctx) { 11993 hdd_err("hdd_ctx is null"); 11994 return; 11995 } 11996 11997 hdd_pm_qos_remove_request(hdd_ctx); 11998 } 11999 12000 /** 12001 * wlan_hdd_send_mscs_action_frame() - Send MSCS action frame 12002 * @context: HDD context 12003 * @netdev: netdev 12004 * 12005 * Return: None 12006 */ 12007 static inline void wlan_hdd_send_mscs_action_frame(hdd_cb_handle context, 12008 qdf_netdev_t netdev) 12009 { 12010 struct hdd_adapter *adapter; 12011 struct wlan_hdd_link_info *link_info; 12012 12013 adapter = WLAN_HDD_GET_PRIV_PTR(netdev); 12014 if (!adapter) { 12015 hdd_err("adapter is null"); 12016 return; 12017 } 12018 12019 link_info = adapter->deflink; 12020 hdd_send_mscs_action_frame(link_info); 12021 } 12022 12023 #else 12024 static inline void hdd_pld_remove_pm_qos(hdd_cb_handle context) 12025 { 12026 } 12027 12028 static inline void hdd_pld_request_pm_qos(hdd_cb_handle context) 12029 { 12030 } 12031 12032 static inline void 12033 wlan_hdd_pm_qos_update_request(hdd_cb_handle context, 12034 cpumask_t *pm_qos_cpu_mask) 12035 { 12036 } 12037 12038 static inline void wlan_hdd_pm_qos_add_request(hdd_cb_handle context) 12039 { 12040 } 12041 12042 static inline void wlan_hdd_pm_qos_remove_request(hdd_cb_handle context) 12043 { 12044 } 12045 12046 static inline void wlan_hdd_send_mscs_action_frame(hdd_cb_handle context, 12047 qdf_netdev_t netdev) 12048 { 12049 } 12050 #endif 12051 12052 #if defined(WLAN_FEATURE_ROAM_OFFLOAD) && \ 12053 defined(FEATURE_RX_LINKSPEED_ROAM_TRIGGER) 12054 void wlan_hdd_link_speed_update(struct wlan_objmgr_psoc *psoc, 12055 uint8_t vdev_id, 12056 bool is_link_speed_good) 12057 { 12058 ucfg_cm_roam_link_speed_update(psoc, vdev_id, is_link_speed_good); 12059 } 12060 #endif 12061 12062 /** 12063 * hdd_dp_register_callbacks() - Register DP callbacks with HDD 12064 * @hdd_ctx: HDD context 12065 * 12066 * Return: None 12067 */ 12068 static void hdd_dp_register_callbacks(struct hdd_context *hdd_ctx) 12069 { 12070 struct wlan_dp_psoc_callbacks cb_obj = {0}; 12071 12072 cb_obj.callback_ctx = (hdd_cb_handle)hdd_ctx; 12073 cb_obj.wlan_dp_sta_get_dot11mode = wlan_hdd_sta_get_dot11mode; 12074 cb_obj.wlan_dp_get_ap_client_count = wlan_hdd_get_ap_client_count; 12075 cb_obj.wlan_dp_sta_ndi_connected = wlan_hdd_sta_ndi_connected; 12076 cb_obj.dp_any_adapter_connected = hdd_any_adapter_connected; 12077 cb_obj.dp_send_svc_nlink_msg = wlan_hdd_send_svc_nlink_msg; 12078 cb_obj.dp_pld_remove_pm_qos = hdd_pld_remove_pm_qos; 12079 cb_obj.dp_pld_request_pm_qos = hdd_pld_request_pm_qos; 12080 cb_obj.dp_pktlog_enable_disable = wlan_hdd_pktlog_enable_disable; 12081 cb_obj.dp_pm_qos_update_request = wlan_hdd_pm_qos_update_request; 12082 cb_obj.dp_pm_qos_add_request = wlan_hdd_pm_qos_add_request; 12083 cb_obj.dp_pm_qos_remove_request = wlan_hdd_pm_qos_remove_request; 12084 cb_obj.dp_send_mscs_action_frame = wlan_hdd_send_mscs_action_frame; 12085 cb_obj.dp_is_roaming_in_progress = wlan_hdd_is_roaming_in_progress; 12086 cb_obj.wlan_dp_display_tx_multiq_stats = 12087 wlan_hdd_display_tx_multiq_stats; 12088 cb_obj.wlan_dp_display_netif_queue_history = 12089 wlan_hdd_display_netif_queue_history; 12090 cb_obj.dp_is_ap_active = hdd_is_ap_active; 12091 cb_obj.dp_napi_apply_throughput_policy = 12092 wlan_hdd_napi_apply_throughput_policy; 12093 cb_obj.dp_is_link_adapter = hdd_is_link_adapter; 12094 cb_obj.dp_nud_failure_work = hdd_nud_failure_work; 12095 cb_obj.dp_get_pause_map = hdd_get_pause_map; 12096 12097 cb_obj.dp_get_netdev_by_vdev_mac = 12098 hdd_get_netdev_by_vdev_mac; 12099 cb_obj.dp_get_tx_resource = hdd_get_tx_resource; 12100 cb_obj.dp_get_tx_flow_low_watermark = hdd_get_tx_flow_low_watermark; 12101 cb_obj.dp_get_tsf_time = hdd_get_tsf_time_cb; 12102 cb_obj.dp_tsf_timestamp_rx = hdd_tsf_timestamp_rx; 12103 cb_obj.dp_gro_rx_legacy_get_napi = hdd_legacy_gro_get_napi; 12104 cb_obj.link_monitoring_cb = wlan_hdd_link_speed_update; 12105 12106 os_if_dp_register_hdd_callbacks(hdd_ctx->psoc, &cb_obj); 12107 } 12108 12109 /** 12110 * __hdd_adapter_param_update_work() - Gist of the work to process 12111 * netdev feature update. 12112 * @adapter: pointer to adapter structure 12113 * 12114 * This function assumes that the adapter pointer is always valid. 12115 * So the caller should always validate adapter pointer before calling 12116 * this function 12117 * 12118 * Returns: None 12119 */ 12120 static inline void 12121 __hdd_adapter_param_update_work(struct hdd_adapter *adapter) 12122 { 12123 /** 12124 * This check is needed in case the work got scheduled after the 12125 * interface got disconnected. 12126 * Netdev features update is to be done only after the connection, 12127 * since the connection mode plays an important role in identifying 12128 * the features that are to be updated. 12129 * So in case of interface disconnect skip feature update. 12130 */ 12131 if (!hdd_cm_is_vdev_associated(adapter->deflink)) 12132 return; 12133 12134 hdd_netdev_update_features(adapter); 12135 } 12136 12137 /** 12138 * hdd_adapter_param_update_work() - work to process the netdev features 12139 * update. 12140 * @arg: private data passed to work 12141 * 12142 * Returns: None 12143 */ 12144 static void hdd_adapter_param_update_work(void *arg) 12145 { 12146 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 12147 struct hdd_adapter *adapter = arg; 12148 struct osif_vdev_sync *vdev_sync; 12149 int errno; 12150 12151 if (!hdd_ctx) 12152 return; 12153 12154 hdd_adapter_ops_record_event(hdd_ctx, 12155 WLAN_HDD_ADAPTER_OPS_WORK_SCHED, 12156 WLAN_INVALID_VDEV_ID); 12157 12158 if (hdd_validate_adapter(adapter)) 12159 return; 12160 12161 errno = osif_vdev_sync_op_start(adapter->dev, &vdev_sync); 12162 if (errno) 12163 return; 12164 12165 __hdd_adapter_param_update_work(adapter); 12166 12167 osif_vdev_sync_op_stop(vdev_sync); 12168 } 12169 12170 QDF_STATUS hdd_init_adapter_ops_wq(struct hdd_context *hdd_ctx) 12171 { 12172 hdd_enter(); 12173 12174 hdd_ctx->adapter_ops_wq = 12175 qdf_alloc_high_prior_ordered_workqueue("hdd_adapter_ops_wq"); 12176 if (!hdd_ctx->adapter_ops_wq) 12177 return QDF_STATUS_E_NOMEM; 12178 12179 hdd_exit(); 12180 12181 return QDF_STATUS_SUCCESS; 12182 } 12183 12184 void hdd_deinit_adapter_ops_wq(struct hdd_context *hdd_ctx) 12185 { 12186 hdd_enter(); 12187 12188 qdf_flush_workqueue(0, hdd_ctx->adapter_ops_wq); 12189 qdf_destroy_workqueue(0, hdd_ctx->adapter_ops_wq); 12190 12191 hdd_exit(); 12192 } 12193 12194 QDF_STATUS hdd_adapter_feature_update_work_init(struct hdd_adapter *adapter) 12195 { 12196 QDF_STATUS status; 12197 12198 hdd_enter(); 12199 12200 status = qdf_create_work(0, &adapter->netdev_features_update_work, 12201 hdd_adapter_param_update_work, adapter); 12202 adapter->netdev_features_update_work_status = HDD_WORK_INITIALIZED; 12203 12204 hdd_exit(); 12205 12206 return status; 12207 } 12208 12209 void hdd_adapter_feature_update_work_deinit(struct hdd_adapter *adapter) 12210 { 12211 hdd_enter(); 12212 12213 if (adapter->netdev_features_update_work_status != 12214 HDD_WORK_INITIALIZED) { 12215 hdd_debug("work not yet init"); 12216 return; 12217 } 12218 qdf_cancel_work(&adapter->netdev_features_update_work); 12219 qdf_flush_work(&adapter->netdev_features_update_work); 12220 adapter->netdev_features_update_work_status = HDD_WORK_UNINITIALIZED; 12221 12222 hdd_exit(); 12223 } 12224 12225 #define HDD_DUMP_STAT_HELP(STAT_ID) \ 12226 hdd_nofl_debug("%u -- %s", STAT_ID, (# STAT_ID)) 12227 /** 12228 * hdd_display_stats_help() - print statistics help 12229 * 12230 * Return: none 12231 */ 12232 static void hdd_display_stats_help(void) 12233 { 12234 hdd_nofl_debug("iwpriv wlan0 dumpStats [option] - dump statistics"); 12235 hdd_nofl_debug("iwpriv wlan0 clearStats [option] - clear statistics"); 12236 hdd_nofl_debug("options:"); 12237 HDD_DUMP_STAT_HELP(CDP_TXRX_PATH_STATS); 12238 HDD_DUMP_STAT_HELP(CDP_TXRX_HIST_STATS); 12239 HDD_DUMP_STAT_HELP(CDP_TXRX_TSO_STATS); 12240 HDD_DUMP_STAT_HELP(CDP_HDD_NETIF_OPER_HISTORY); 12241 HDD_DUMP_STAT_HELP(CDP_DUMP_TX_FLOW_POOL_INFO); 12242 HDD_DUMP_STAT_HELP(CDP_TXRX_DESC_STATS); 12243 HDD_DUMP_STAT_HELP(CDP_HIF_STATS); 12244 HDD_DUMP_STAT_HELP(CDP_NAPI_STATS); 12245 HDD_DUMP_STAT_HELP(CDP_DP_NAPI_STATS); 12246 HDD_DUMP_STAT_HELP(CDP_DP_RX_THREAD_STATS); 12247 } 12248 12249 int hdd_wlan_dump_stats(struct hdd_adapter *adapter, int stats_id) 12250 { 12251 int ret = 0; 12252 QDF_STATUS status; 12253 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); 12254 12255 hdd_debug("stats_id %d", stats_id); 12256 12257 switch (stats_id) { 12258 case CDP_TXRX_HIST_STATS: 12259 ucfg_wlan_dp_display_tx_rx_histogram(hdd_ctx->psoc); 12260 break; 12261 case CDP_HDD_NETIF_OPER_HISTORY: 12262 wlan_hdd_display_adapter_netif_queue_history(adapter); 12263 break; 12264 case CDP_HIF_STATS: 12265 hdd_display_hif_stats(); 12266 break; 12267 case CDP_NAPI_STATS: 12268 if (hdd_display_napi_stats()) { 12269 hdd_err("error displaying napi stats"); 12270 ret = -EFAULT; 12271 } 12272 break; 12273 case CDP_DP_RX_THREAD_STATS: 12274 ucfg_dp_txrx_ext_dump_stats(cds_get_context(QDF_MODULE_ID_SOC), 12275 CDP_DP_RX_THREAD_STATS); 12276 break; 12277 case CDP_DISCONNECT_STATS: 12278 sme_display_disconnect_stats(hdd_ctx->mac_handle, 12279 adapter->deflink->vdev_id); 12280 break; 12281 default: 12282 status = cdp_display_stats(cds_get_context(QDF_MODULE_ID_SOC), 12283 stats_id, 12284 QDF_STATS_VERBOSITY_LEVEL_HIGH); 12285 if (status == QDF_STATUS_E_INVAL) { 12286 hdd_display_stats_help(); 12287 ret = -EINVAL; 12288 } 12289 break; 12290 } 12291 return ret; 12292 } 12293 12294 int hdd_wlan_clear_stats(struct hdd_adapter *adapter, int stats_id) 12295 { 12296 QDF_STATUS status = QDF_STATUS_SUCCESS; 12297 12298 hdd_debug("stats_id %d", stats_id); 12299 12300 switch (stats_id) { 12301 case CDP_HDD_STATS: 12302 ucfg_dp_clear_net_dev_stats(adapter->dev); 12303 memset(&adapter->deflink->hdd_stats, 0, 12304 sizeof(adapter->deflink->hdd_stats)); 12305 break; 12306 case CDP_TXRX_HIST_STATS: 12307 ucfg_wlan_dp_clear_tx_rx_histogram(adapter->hdd_ctx->psoc); 12308 break; 12309 case CDP_HDD_NETIF_OPER_HISTORY: 12310 wlan_hdd_clear_netif_queue_history(adapter->hdd_ctx); 12311 break; 12312 case CDP_HIF_STATS: 12313 hdd_clear_hif_stats(); 12314 break; 12315 case CDP_NAPI_STATS: 12316 hdd_clear_napi_stats(); 12317 break; 12318 default: 12319 status = cdp_clear_stats(cds_get_context(QDF_MODULE_ID_SOC), 12320 OL_TXRX_PDEV_ID, 12321 stats_id); 12322 if (status != QDF_STATUS_SUCCESS) 12323 hdd_debug("Failed to dump stats for stats_id: %d", 12324 stats_id); 12325 break; 12326 } 12327 12328 return qdf_status_to_os_return(status); 12329 } 12330 12331 /* length of the netif queue log needed per adapter */ 12332 #define ADAP_NETIFQ_LOG_LEN ((20 * WLAN_REASON_TYPE_MAX) + 50) 12333 12334 /** 12335 * hdd_display_netif_queue_history_compact() - display compact netifq history 12336 * @hdd_ctx: hdd context 12337 * 12338 * Return: none 12339 */ 12340 static void 12341 hdd_display_netif_queue_history_compact(struct hdd_context *hdd_ctx) 12342 { 12343 int adapter_num = 0; 12344 int i; 12345 int bytes_written; 12346 u32 tbytes; 12347 qdf_time_t total, pause, unpause, curr_time, delta; 12348 char temp_str[20 * WLAN_REASON_TYPE_MAX]; 12349 char *comb_log_str; 12350 uint32_t comb_log_str_size; 12351 struct hdd_adapter *adapter = NULL, *next_adapter = NULL; 12352 wlan_net_dev_ref_dbgid dbgid = 12353 NET_DEV_HOLD_DISPLAY_NETIF_QUEUE_HISTORY_COMPACT; 12354 12355 comb_log_str_size = (ADAP_NETIFQ_LOG_LEN * WLAN_MAX_VDEVS) + 1; 12356 comb_log_str = qdf_mem_malloc(comb_log_str_size); 12357 if (!comb_log_str) 12358 return; 12359 12360 bytes_written = 0; 12361 12362 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 12363 dbgid) { 12364 curr_time = qdf_system_ticks(); 12365 total = curr_time - adapter->start_time; 12366 delta = curr_time - adapter->last_time; 12367 12368 if (adapter->pause_map) { 12369 pause = adapter->total_pause_time + delta; 12370 unpause = adapter->total_unpause_time; 12371 } else { 12372 unpause = adapter->total_unpause_time + delta; 12373 pause = adapter->total_pause_time; 12374 } 12375 12376 tbytes = 0; 12377 qdf_mem_zero(temp_str, sizeof(temp_str)); 12378 for (i = WLAN_CONTROL_PATH; i < WLAN_REASON_TYPE_MAX; i++) { 12379 if (adapter->queue_oper_stats[i].pause_count == 0) 12380 continue; 12381 tbytes += 12382 snprintf( 12383 &temp_str[tbytes], 12384 (tbytes >= sizeof(temp_str) ? 12385 0 : sizeof(temp_str) - tbytes), 12386 "%d(%d,%d) ", 12387 i, 12388 adapter->queue_oper_stats[i]. 12389 pause_count, 12390 adapter->queue_oper_stats[i]. 12391 unpause_count); 12392 } 12393 if (tbytes >= sizeof(temp_str)) 12394 hdd_warn("log truncated"); 12395 12396 bytes_written += snprintf(&comb_log_str[bytes_written], 12397 bytes_written >= comb_log_str_size ? 0 : 12398 comb_log_str_size - bytes_written, 12399 "[%d %d] (%d) %u/%ums %s|", 12400 adapter->deflink->vdev_id, adapter->device_mode, 12401 adapter->pause_map, 12402 qdf_system_ticks_to_msecs(pause), 12403 qdf_system_ticks_to_msecs(total), 12404 temp_str); 12405 12406 adapter_num++; 12407 /* dev_put has to be done here */ 12408 hdd_adapter_dev_put_debug(adapter, dbgid); 12409 } 12410 12411 /* using QDF_TRACE to avoid printing function name */ 12412 QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_INFO_LOW, 12413 "STATS |%s", comb_log_str); 12414 12415 if (bytes_written >= comb_log_str_size) 12416 hdd_warn("log string truncated"); 12417 12418 qdf_mem_free(comb_log_str); 12419 } 12420 12421 /* Max size of a single netdev tx queue state string. e.g. "1: 0x1" */ 12422 #define HDD_NETDEV_TX_Q_STATE_STRLEN 15 12423 /** 12424 * wlan_hdd_display_adapter_netif_queue_stats() - display adapter based 12425 * netif queue stats 12426 * @adapter: hdd adapter 12427 * 12428 * Return: none 12429 */ 12430 static void 12431 wlan_hdd_display_adapter_netif_queue_stats(struct hdd_adapter *adapter) 12432 { 12433 int i; 12434 qdf_time_t total, pause, unpause, curr_time, delta; 12435 struct hdd_netif_queue_history *q_hist_ptr; 12436 char q_status_buf[NUM_TX_QUEUES * HDD_NETDEV_TX_Q_STATE_STRLEN] = {0}; 12437 12438 hdd_nofl_debug("Netif queue operation statistics:"); 12439 hdd_nofl_debug("vdev_id %d device mode %d", 12440 adapter->deflink->vdev_id, adapter->device_mode); 12441 hdd_nofl_debug("Current pause_map %x", adapter->pause_map); 12442 curr_time = qdf_system_ticks(); 12443 total = curr_time - adapter->start_time; 12444 delta = curr_time - adapter->last_time; 12445 if (adapter->pause_map) { 12446 pause = adapter->total_pause_time + delta; 12447 unpause = adapter->total_unpause_time; 12448 } else { 12449 unpause = adapter->total_unpause_time + delta; 12450 pause = adapter->total_pause_time; 12451 } 12452 hdd_nofl_debug("Total: %ums Pause: %ums Unpause: %ums", 12453 qdf_system_ticks_to_msecs(total), 12454 qdf_system_ticks_to_msecs(pause), 12455 qdf_system_ticks_to_msecs(unpause)); 12456 hdd_nofl_debug("reason_type: pause_cnt: unpause_cnt: pause_time"); 12457 12458 for (i = WLAN_CONTROL_PATH; i < WLAN_REASON_TYPE_MAX; i++) { 12459 qdf_time_t pause_delta = 0; 12460 12461 if (adapter->pause_map & (1 << i)) 12462 pause_delta = delta; 12463 12464 /* using hdd_log to avoid printing function name */ 12465 hdd_nofl_debug("%s: %d: %d: %ums", 12466 hdd_reason_type_to_string(i), 12467 adapter->queue_oper_stats[i].pause_count, 12468 adapter->queue_oper_stats[i]. 12469 unpause_count, 12470 qdf_system_ticks_to_msecs( 12471 adapter->queue_oper_stats[i]. 12472 total_pause_time + pause_delta)); 12473 } 12474 12475 hdd_nofl_debug("Netif queue operation history: Total entries: %d current index %d(-1) time %u", 12476 WLAN_HDD_MAX_HISTORY_ENTRY, 12477 adapter->history_index, 12478 qdf_system_ticks_to_msecs(qdf_system_ticks())); 12479 12480 hdd_nofl_debug("%2s%20s%50s%30s%10s %s", 12481 "#", "time(ms)", "action_type", "reason_type", 12482 "pause_map", "netdev-queue-status"); 12483 12484 for (i = 0; i < WLAN_HDD_MAX_HISTORY_ENTRY; i++) { 12485 /* using hdd_log to avoid printing function name */ 12486 if (adapter->queue_oper_history[i].time == 0) 12487 continue; 12488 q_hist_ptr = &adapter->queue_oper_history[i]; 12489 wlan_hdd_dump_queue_history_state(q_hist_ptr, 12490 q_status_buf, 12491 sizeof(q_status_buf)); 12492 hdd_nofl_debug("%2d%20u%50s%30s%10x %s", 12493 i, qdf_system_ticks_to_msecs( 12494 adapter->queue_oper_history[i].time), 12495 hdd_action_type_to_string( 12496 adapter->queue_oper_history[i]. 12497 netif_action), 12498 hdd_reason_type_to_string( 12499 adapter->queue_oper_history[i]. 12500 netif_reason), 12501 adapter->queue_oper_history[i].pause_map, 12502 q_status_buf); 12503 } 12504 } 12505 12506 void 12507 wlan_hdd_display_adapter_netif_queue_history(struct hdd_adapter *adapter) 12508 { 12509 wlan_hdd_display_adapter_netif_queue_stats(adapter); 12510 } 12511 12512 /** 12513 * wlan_hdd_display_netif_queue_history() - display netif queue history 12514 * @context: hdd context 12515 * @verb_lvl: verbosity level 12516 * 12517 * Return: none 12518 */ 12519 void 12520 wlan_hdd_display_netif_queue_history(hdd_cb_handle context, 12521 enum qdf_stats_verbosity_level verb_lvl) 12522 { 12523 struct hdd_adapter *adapter = NULL, *next_adapter = NULL; 12524 struct hdd_context *hdd_ctx = hdd_cb_handle_to_context(context); 12525 wlan_net_dev_ref_dbgid dbgid = 12526 NET_DEV_HOLD_DISPLAY_NETIF_QUEUE_HISTORY; 12527 12528 if (!hdd_ctx) { 12529 hdd_err("hdd_ctx is null"); 12530 return; 12531 } 12532 12533 if (verb_lvl == QDF_STATS_VERBOSITY_LEVEL_LOW) { 12534 hdd_display_netif_queue_history_compact(hdd_ctx); 12535 return; 12536 } 12537 12538 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 12539 dbgid) { 12540 if (adapter->deflink->vdev_id == CDP_INVALID_VDEV_ID) { 12541 hdd_adapter_dev_put_debug(adapter, dbgid); 12542 continue; 12543 } 12544 wlan_hdd_display_adapter_netif_queue_stats(adapter); 12545 /* dev_put has to be done here */ 12546 hdd_adapter_dev_put_debug(adapter, dbgid); 12547 } 12548 } 12549 12550 /** 12551 * wlan_hdd_clear_netif_queue_history() - clear netif queue operation history 12552 * @hdd_ctx: hdd context 12553 * 12554 * Return: none 12555 */ 12556 void wlan_hdd_clear_netif_queue_history(struct hdd_context *hdd_ctx) 12557 { 12558 struct hdd_adapter *adapter = NULL, *next_adapter = NULL; 12559 wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_CLEAR_NETIF_QUEUE_HISTORY; 12560 12561 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 12562 dbgid) { 12563 qdf_mem_zero(adapter->queue_oper_stats, 12564 sizeof(adapter->queue_oper_stats)); 12565 qdf_mem_zero(adapter->queue_oper_history, 12566 sizeof(adapter->queue_oper_history)); 12567 adapter->history_index = 0; 12568 adapter->start_time = adapter->last_time = qdf_system_ticks(); 12569 adapter->total_pause_time = 0; 12570 adapter->total_unpause_time = 0; 12571 hdd_adapter_dev_put_debug(adapter, dbgid); 12572 } 12573 } 12574 12575 #ifdef WLAN_FEATURE_OFFLOAD_PACKETS 12576 /** 12577 * hdd_init_offloaded_packets_ctx() - Initialize offload packets context 12578 * @hdd_ctx: hdd global context 12579 * 12580 * Return: none 12581 */ 12582 static void hdd_init_offloaded_packets_ctx(struct hdd_context *hdd_ctx) 12583 { 12584 uint8_t i; 12585 12586 mutex_init(&hdd_ctx->op_ctx.op_lock); 12587 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++) { 12588 hdd_ctx->op_ctx.op_table[i].request_id = MAX_REQUEST_ID; 12589 hdd_ctx->op_ctx.op_table[i].pattern_id = i; 12590 } 12591 } 12592 #else 12593 static void hdd_init_offloaded_packets_ctx(struct hdd_context *hdd_ctx) 12594 { 12595 } 12596 #endif 12597 12598 #ifdef WLAN_FEATURE_WOW_PULSE 12599 /** 12600 * wlan_hdd_set_wow_pulse() - call SME to send wmi cmd of wow pulse 12601 * @hdd_ctx: struct hdd_context structure pointer 12602 * @enable: enable or disable this behaviour 12603 * 12604 * Return: int 12605 */ 12606 static int wlan_hdd_set_wow_pulse(struct hdd_context *hdd_ctx, bool enable) 12607 { 12608 struct wow_pulse_mode wow_pulse_set_info; 12609 QDF_STATUS status; 12610 12611 hdd_debug("wow pulse enable flag is %d", enable); 12612 12613 if (!ucfg_pmo_is_wow_pulse_enabled(hdd_ctx->psoc)) 12614 return 0; 12615 12616 /* prepare the request to send to SME */ 12617 if (enable == true) { 12618 wow_pulse_set_info.wow_pulse_enable = true; 12619 wow_pulse_set_info.wow_pulse_pin = 12620 ucfg_pmo_get_wow_pulse_pin(hdd_ctx->psoc); 12621 12622 wow_pulse_set_info.wow_pulse_interval_high = 12623 ucfg_pmo_get_wow_pulse_interval_high(hdd_ctx->psoc); 12624 12625 wow_pulse_set_info.wow_pulse_interval_low = 12626 ucfg_pmo_get_wow_pulse_interval_low(hdd_ctx->psoc); 12627 12628 wow_pulse_set_info.wow_pulse_repeat_count = 12629 ucfg_pmo_get_wow_pulse_repeat_count(hdd_ctx->psoc); 12630 12631 wow_pulse_set_info.wow_pulse_init_state = 12632 ucfg_pmo_get_wow_pulse_init_state(hdd_ctx->psoc); 12633 } else { 12634 wow_pulse_set_info.wow_pulse_enable = false; 12635 wow_pulse_set_info.wow_pulse_pin = 0; 12636 wow_pulse_set_info.wow_pulse_interval_low = 0; 12637 wow_pulse_set_info.wow_pulse_interval_high = 0; 12638 wow_pulse_set_info.wow_pulse_repeat_count = 0; 12639 wow_pulse_set_info.wow_pulse_init_state = 0; 12640 } 12641 hdd_debug("enable %d pin %d low %d high %d count %d init %d", 12642 wow_pulse_set_info.wow_pulse_enable, 12643 wow_pulse_set_info.wow_pulse_pin, 12644 wow_pulse_set_info.wow_pulse_interval_low, 12645 wow_pulse_set_info.wow_pulse_interval_high, 12646 wow_pulse_set_info.wow_pulse_repeat_count, 12647 wow_pulse_set_info.wow_pulse_init_state); 12648 12649 status = sme_set_wow_pulse(&wow_pulse_set_info); 12650 if (QDF_STATUS_E_FAILURE == status) { 12651 hdd_debug("sme_set_wow_pulse failure!"); 12652 return -EIO; 12653 } 12654 hdd_debug("sme_set_wow_pulse success!"); 12655 return 0; 12656 } 12657 #else 12658 static inline int wlan_hdd_set_wow_pulse(struct hdd_context *hdd_ctx, bool enable) 12659 { 12660 return 0; 12661 } 12662 #endif 12663 12664 #ifdef WLAN_FEATURE_FASTPATH 12665 12666 /** 12667 * hdd_enable_fastpath() - Enable fastpath if enabled in config INI 12668 * @hdd_ctx: hdd context 12669 * @context: lower layer context 12670 * 12671 * Return: none 12672 */ 12673 void hdd_enable_fastpath(struct hdd_context *hdd_ctx, 12674 void *context) 12675 { 12676 if (cfg_get(hdd_ctx->psoc, CFG_DP_ENABLE_FASTPATH)) 12677 hif_enable_fastpath(context); 12678 } 12679 #endif 12680 12681 #if defined(FEATURE_WLAN_CH_AVOID) 12682 /** 12683 * hdd_set_thermal_level_cb() - set thermal level callback function 12684 * @hdd_handle: opaque handle for the hdd context 12685 * @level: thermal level 12686 * 12687 * Change IPA data path to SW path when the thermal throttle level greater 12688 * than 0, and restore the original data path when throttle level is 0 12689 * 12690 * Return: none 12691 */ 12692 static void hdd_set_thermal_level_cb(hdd_handle_t hdd_handle, u_int8_t level) 12693 { 12694 struct hdd_context *hdd_ctx = hdd_handle_to_context(hdd_handle); 12695 12696 /* Change IPA to SW path when throttle level greater than 0 */ 12697 if (level > THROTTLE_LEVEL_0) 12698 ucfg_ipa_send_mcc_scc_msg(hdd_ctx->pdev, true); 12699 else 12700 /* restore original concurrency mode */ 12701 ucfg_ipa_send_mcc_scc_msg(hdd_ctx->pdev, hdd_ctx->mcc_mode); 12702 } 12703 #else 12704 /** 12705 * hdd_set_thermal_level_cb() - set thermal level callback function 12706 * @hdd_handle: opaque handle for the hdd context 12707 * @level: thermal level 12708 * 12709 * Change IPA data path to SW path when the thermal throttle level greater 12710 * than 0, and restore the original data path when throttle level is 0 12711 * 12712 * Return: none 12713 */ 12714 static void hdd_set_thermal_level_cb(hdd_handle_t hdd_handle, u_int8_t level) 12715 { 12716 } 12717 #endif 12718 12719 QDF_STATUS hdd_switch_sap_channel(struct wlan_hdd_link_info *link_info, 12720 uint8_t channel, bool forced) 12721 { 12722 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(link_info->adapter); 12723 mac_handle_t mac_handle; 12724 struct sap_config *sap_cfg; 12725 qdf_freq_t freq; 12726 12727 mac_handle = hdd_adapter_get_mac_handle(link_info->adapter); 12728 if (!mac_handle) { 12729 hdd_err("invalid MAC handle"); 12730 return QDF_STATUS_E_INVAL; 12731 } 12732 12733 freq = wlan_reg_legacy_chan_to_freq(hdd_ctx->pdev, channel); 12734 sap_cfg = &(WLAN_HDD_GET_AP_CTX_PTR(link_info)->sap_config); 12735 hdd_debug("chan:%d width:%d", channel, sap_cfg->ch_width_orig); 12736 12737 return policy_mgr_change_sap_channel_with_csa(hdd_ctx->psoc, 12738 link_info->vdev_id, freq, 12739 sap_cfg->ch_width_orig, 12740 forced); 12741 } 12742 12743 QDF_STATUS hdd_switch_sap_chan_freq(struct hdd_adapter *adapter, 12744 qdf_freq_t chan_freq, 12745 enum phy_ch_width ch_width, 12746 bool forced) 12747 { 12748 struct hdd_ap_ctx *hdd_ap_ctx; 12749 struct hdd_context *hdd_ctx; 12750 12751 if (hdd_validate_adapter(adapter)) 12752 return QDF_STATUS_E_INVAL; 12753 12754 hdd_ctx = WLAN_HDD_GET_CTX(adapter); 12755 12756 if(wlan_hdd_validate_context(hdd_ctx)) 12757 return QDF_STATUS_E_INVAL; 12758 12759 hdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(adapter->deflink); 12760 12761 hdd_debug("chan freq:%d width:%d org bw %d", 12762 chan_freq, ch_width, hdd_ap_ctx->sap_config.ch_width_orig); 12763 12764 return policy_mgr_change_sap_channel_with_csa(hdd_ctx->psoc, 12765 adapter->deflink->vdev_id, 12766 chan_freq, 12767 ch_width, 12768 forced); 12769 } 12770 12771 int hdd_update_acs_timer_reason(struct hdd_adapter *adapter, uint8_t reason) 12772 { 12773 struct hdd_external_acs_timer_context *timer_context; 12774 int status; 12775 QDF_STATUS qdf_status; 12776 qdf_mc_timer_t *vendor_acs_timer; 12777 12778 set_bit(VENDOR_ACS_RESPONSE_PENDING, &adapter->deflink->link_flags); 12779 12780 vendor_acs_timer = &adapter->deflink->session.ap.vendor_acs_timer; 12781 if (QDF_TIMER_STATE_RUNNING == 12782 qdf_mc_timer_get_current_state(vendor_acs_timer)) { 12783 qdf_mc_timer_stop(vendor_acs_timer); 12784 } 12785 timer_context = 12786 (struct hdd_external_acs_timer_context *)vendor_acs_timer->user_data; 12787 timer_context->reason = reason; 12788 qdf_status = 12789 qdf_mc_timer_start(vendor_acs_timer, WLAN_VENDOR_ACS_WAIT_TIME); 12790 if (qdf_status != QDF_STATUS_SUCCESS) { 12791 hdd_err("failed to start external acs timer"); 12792 return -ENOSPC; 12793 } 12794 /* Update config to application */ 12795 status = hdd_cfg80211_update_acs_config(adapter, reason); 12796 hdd_info("Updated ACS config to nl with reason %d", reason); 12797 12798 return status; 12799 } 12800 12801 #ifdef FEATURE_WLAN_CH_AVOID_EXT 12802 uint32_t wlan_hdd_get_restriction_mask(struct hdd_context *hdd_ctx) 12803 { 12804 return hdd_ctx->restriction_mask; 12805 } 12806 12807 void wlan_hdd_set_restriction_mask(struct hdd_context *hdd_ctx) 12808 { 12809 hdd_ctx->restriction_mask = 12810 hdd_ctx->coex_avoid_freq_list.restriction_mask; 12811 } 12812 #else 12813 uint32_t wlan_hdd_get_restriction_mask(struct hdd_context *hdd_ctx) 12814 { 12815 return -EINVAL; 12816 } 12817 12818 void wlan_hdd_set_restriction_mask(struct hdd_context *hdd_ctx) 12819 { 12820 } 12821 #endif 12822 12823 #if defined(FEATURE_WLAN_CH_AVOID) 12824 /** 12825 * hdd_store_sap_restart_channel() - store sap restart channel 12826 * @restart_chan: restart channel 12827 * @restart_chan_store: pointer to restart channel store 12828 * 12829 * The function will store new sap restart channel. 12830 * 12831 * Return - none 12832 */ 12833 static void 12834 hdd_store_sap_restart_channel(qdf_freq_t restart_chan, qdf_freq_t *restart_chan_store) 12835 { 12836 uint8_t i; 12837 12838 for (i = 0; i < SAP_MAX_NUM_SESSION; i++) { 12839 if (*(restart_chan_store + i) == restart_chan) 12840 return; 12841 12842 if (*(restart_chan_store + i)) 12843 continue; 12844 12845 *(restart_chan_store + i) = restart_chan; 12846 return; 12847 } 12848 } 12849 12850 /** 12851 * hdd_check_chn_bw_boundary_unsafe() - check channel range unsafe 12852 * @hdd_ctxt: hdd context pointer 12853 * @adapter: hdd adapter pointer 12854 * 12855 * hdd_check_chn_bw_boundary_unsafe check SAP channel range with certain 12856 * bandwidth whether cover all unsafe channel list. 12857 * 12858 * Return - bool 12859 */ 12860 static bool 12861 hdd_check_chn_bw_boundary_unsafe(struct hdd_context *hdd_ctxt, 12862 struct hdd_adapter *adapter) 12863 { 12864 uint32_t freq; 12865 uint32_t start_freq = 0; 12866 uint32_t end_freq = 0; 12867 uint32_t i; 12868 uint8_t ch_width; 12869 const struct bonded_channel_freq *bonded_chan_ptr_ptr = NULL; 12870 12871 freq = adapter->deflink->session.ap.operating_chan_freq; 12872 ch_width = adapter->deflink->session.ap.sap_config.acs_cfg.ch_width; 12873 12874 if (ch_width > CH_WIDTH_20MHZ) 12875 bonded_chan_ptr_ptr = 12876 wlan_reg_get_bonded_chan_entry(freq, ch_width, 0); 12877 12878 if (bonded_chan_ptr_ptr) { 12879 start_freq = bonded_chan_ptr_ptr->start_freq; 12880 end_freq = bonded_chan_ptr_ptr->end_freq; 12881 } 12882 12883 for (i = 0; i < hdd_ctxt->unsafe_channel_count; i++) { 12884 if ((freq == hdd_ctxt->unsafe_channel_list[i]) || 12885 (start_freq <= hdd_ctxt->unsafe_channel_list[i] && 12886 hdd_ctxt->unsafe_channel_list[i] <= end_freq)) { 12887 hdd_debug("op chn freq:%u is unsafe for chn list:%u", 12888 freq, hdd_ctxt->unsafe_channel_list[i]); 12889 return true; 12890 } 12891 } 12892 12893 return false; 12894 } 12895 12896 /** 12897 * hdd_unsafe_channel_restart_sap() - restart sap if sap is on unsafe channel 12898 * @hdd_ctx: hdd context pointer 12899 * 12900 * hdd_unsafe_channel_restart_sap check all unsafe channel list 12901 * and if ACS is enabled, driver will ask userspace to restart the 12902 * sap. User space on LTE coex indication restart driver. 12903 * 12904 * Return - none 12905 */ 12906 QDF_STATUS hdd_unsafe_channel_restart_sap(struct hdd_context *hdd_ctx) 12907 { 12908 struct hdd_adapter *adapter, *next_adapter = NULL; 12909 struct hdd_ap_ctx *ap_ctx; 12910 uint32_t i; 12911 bool found = false; 12912 qdf_freq_t restart_chan_store[SAP_MAX_NUM_SESSION] = {0}; 12913 uint8_t scc_on_lte_coex = 0; 12914 uint32_t restart_freq, ap_chan_freq; 12915 bool value; 12916 QDF_STATUS status; 12917 bool is_acs_support_for_dfs_ltecoex = cfg_default(CFG_USER_ACS_DFS_LTE); 12918 bool is_vendor_acs_support = 12919 cfg_default(CFG_USER_AUTO_CHANNEL_SELECTION); 12920 wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_UNSAFE_CHANNEL_RESTART_SAP; 12921 enum phy_ch_width ch_width; 12922 struct wlan_hdd_link_info *link_info; 12923 12924 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 12925 dbgid) { 12926 if (adapter->device_mode != QDF_SAP_MODE) { 12927 hdd_debug_rl("skip device mode:%d", 12928 adapter->device_mode); 12929 hdd_adapter_dev_put_debug(adapter, dbgid); 12930 continue; 12931 } 12932 12933 hdd_adapter_for_each_active_link_info(adapter, link_info) { 12934 ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(link_info); 12935 if (!ap_ctx->sap_config.acs_cfg.acs_mode) { 12936 hdd_debug_rl("skip acs:%d", 12937 ap_ctx->sap_config.acs_cfg.acs_mode); 12938 continue; 12939 } 12940 12941 ap_chan_freq = ap_ctx->operating_chan_freq; 12942 ch_width = ap_ctx->sap_config.ch_width_orig; 12943 found = false; 12944 status = 12945 ucfg_policy_mgr_get_sta_sap_scc_lte_coex_chnl(hdd_ctx->psoc, 12946 &scc_on_lte_coex); 12947 if (!QDF_IS_STATUS_SUCCESS(status)) 12948 hdd_err("can't get scc on lte coex chnl, use def"); 12949 /* 12950 * If STA+SAP is doing SCC & 12951 * g_sta_sap_scc_on_lte_coex_chan is set, 12952 * no need to move SAP. 12953 */ 12954 if ((policy_mgr_is_sta_sap_scc(hdd_ctx->psoc, 12955 ap_chan_freq) && 12956 scc_on_lte_coex) || 12957 policy_mgr_nan_sap_scc_on_unsafe_ch_chk(hdd_ctx->psoc, 12958 ap_chan_freq)) 12959 hdd_debug("SAP allowed in unsafe SCC channel"); 12960 else 12961 found = hdd_check_chn_bw_boundary_unsafe(hdd_ctx, 12962 adapter); 12963 if (!found) { 12964 hdd_store_sap_restart_channel(ap_chan_freq, 12965 restart_chan_store); 12966 hdd_debug("ch freq:%d is safe. no need to change channel", 12967 ap_chan_freq); 12968 continue; 12969 } 12970 12971 status = ucfg_mlme_get_acs_support_for_dfs_ltecoex( 12972 hdd_ctx->psoc, 12973 &is_acs_support_for_dfs_ltecoex); 12974 if (!QDF_IS_STATUS_SUCCESS(status)) 12975 hdd_err("get_acs_support_for_dfs_ltecoex failed,set def"); 12976 12977 status = ucfg_mlme_get_vendor_acs_support( 12978 hdd_ctx->psoc, 12979 &is_vendor_acs_support); 12980 if (!QDF_IS_STATUS_SUCCESS(status)) 12981 hdd_err("get_vendor_acs_support failed, set default"); 12982 12983 if (is_vendor_acs_support && 12984 is_acs_support_for_dfs_ltecoex) { 12985 hdd_update_acs_timer_reason(adapter, 12986 QCA_WLAN_VENDOR_ACS_SELECT_REASON_LTE_COEX); 12987 continue; 12988 } 12989 12990 restart_freq = 0; 12991 for (i = 0; i < SAP_MAX_NUM_SESSION; i++) { 12992 if (!restart_chan_store[i]) 12993 continue; 12994 12995 if (policy_mgr_is_force_scc(hdd_ctx->psoc) && 12996 WLAN_REG_IS_SAME_BAND_FREQS( 12997 restart_chan_store[i], 12998 ap_chan_freq)) { 12999 restart_freq = restart_chan_store[i]; 13000 break; 13001 } 13002 } 13003 if (!restart_freq) { 13004 restart_freq = 13005 wlansap_get_safe_channel_from_pcl_and_acs_range( 13006 WLAN_HDD_GET_SAP_CTX_PTR(link_info), 13007 &ch_width); 13008 } 13009 if (!restart_freq) { 13010 wlan_hdd_set_sap_csa_reason(hdd_ctx->psoc, 13011 link_info->vdev_id, 13012 CSA_REASON_UNSAFE_CHANNEL); 13013 hdd_err("Unable to find safe chan, Stop the SAP if restriction mask is set else set txpower"); 13014 hdd_stop_sap_set_tx_power(hdd_ctx->psoc, adapter); 13015 continue; 13016 } 13017 /* 13018 * SAP restart due to unsafe channel. While 13019 * restarting the SAP, make sure to clear 13020 * acs_channel, channel to reset to 13021 * 0. Otherwise these settings will override 13022 * the ACS while restart. 13023 */ 13024 hdd_ctx->acs_policy.acs_chan_freq = 13025 AUTO_CHANNEL_SELECT; 13026 ucfg_mlme_get_sap_internal_restart(hdd_ctx->psoc, 13027 &value); 13028 if (value) { 13029 wlan_hdd_set_sap_csa_reason(hdd_ctx->psoc, 13030 link_info->vdev_id, 13031 CSA_REASON_UNSAFE_CHANNEL); 13032 status = hdd_switch_sap_chan_freq(adapter, 13033 restart_freq, 13034 ch_width, 13035 true); 13036 if (QDF_IS_STATUS_SUCCESS(status)) { 13037 hdd_adapter_dev_put_debug(adapter, 13038 dbgid); 13039 if (next_adapter) 13040 hdd_adapter_dev_put_debug( 13041 next_adapter, 13042 dbgid); 13043 return QDF_STATUS_E_PENDING; 13044 } else { 13045 hdd_debug("CSA failed, check next SAP"); 13046 } 13047 } else { 13048 hdd_debug("sending coex indication"); 13049 wlan_hdd_send_svc_nlink_msg( 13050 hdd_ctx->radio_index, 13051 WLAN_SVC_LTE_COEX_IND, NULL, 0); 13052 hdd_adapter_dev_put_debug(adapter, dbgid); 13053 if (next_adapter) 13054 hdd_adapter_dev_put_debug(next_adapter, 13055 dbgid); 13056 return QDF_STATUS_SUCCESS; 13057 } 13058 } 13059 /* dev_put has to be done here */ 13060 hdd_adapter_dev_put_debug(adapter, dbgid); 13061 } 13062 13063 return QDF_STATUS_SUCCESS; 13064 } 13065 13066 /** 13067 * hdd_init_channel_avoidance() - Initialize channel avoidance 13068 * @hdd_ctx: HDD global context 13069 * 13070 * Initialize the channel avoidance logic by retrieving the unsafe 13071 * channel list from the platform driver and plumbing the data 13072 * down to the lower layers. Then subscribe to subsequent channel 13073 * avoidance events. 13074 * 13075 * Return: None 13076 */ 13077 static void hdd_init_channel_avoidance(struct hdd_context *hdd_ctx) 13078 { 13079 uint16_t unsafe_channel_count; 13080 int index; 13081 qdf_freq_t *unsafe_freq_list; 13082 13083 pld_get_wlan_unsafe_channel(hdd_ctx->parent_dev, 13084 hdd_ctx->unsafe_channel_list, 13085 &(hdd_ctx->unsafe_channel_count), 13086 sizeof(uint16_t) * NUM_CHANNELS); 13087 13088 hdd_debug("num of unsafe channels is %d", 13089 hdd_ctx->unsafe_channel_count); 13090 13091 unsafe_channel_count = QDF_MIN((uint16_t)hdd_ctx->unsafe_channel_count, 13092 (uint16_t)NUM_CHANNELS); 13093 13094 if (!unsafe_channel_count) 13095 return; 13096 13097 unsafe_freq_list = qdf_mem_malloc( 13098 unsafe_channel_count * sizeof(*unsafe_freq_list)); 13099 13100 if (!unsafe_freq_list) 13101 return; 13102 13103 for (index = 0; index < unsafe_channel_count; index++) { 13104 hdd_debug("channel frequency %d is not safe", 13105 hdd_ctx->unsafe_channel_list[index]); 13106 unsafe_freq_list[index] = 13107 (qdf_freq_t)hdd_ctx->unsafe_channel_list[index]; 13108 } 13109 13110 ucfg_policy_mgr_init_chan_avoidance( 13111 hdd_ctx->psoc, 13112 unsafe_freq_list, 13113 unsafe_channel_count); 13114 13115 qdf_mem_free(unsafe_freq_list); 13116 } 13117 13118 static void hdd_lte_coex_restart_sap(struct hdd_adapter *adapter, 13119 struct hdd_context *hdd_ctx) 13120 { 13121 uint8_t restart_chan; 13122 uint32_t restart_freq; 13123 13124 restart_freq = wlansap_get_safe_channel_from_pcl_and_acs_range( 13125 WLAN_HDD_GET_SAP_CTX_PTR(adapter->deflink), 13126 NULL); 13127 13128 restart_chan = wlan_reg_freq_to_chan(hdd_ctx->pdev, 13129 restart_freq); 13130 13131 if (!restart_chan) { 13132 hdd_alert("fail to restart SAP"); 13133 return; 13134 } 13135 13136 /* SAP restart due to unsafe channel. While restarting 13137 * the SAP, make sure to clear acs_channel, channel to 13138 * reset to 0. Otherwise these settings will override 13139 * the ACS while restart. 13140 */ 13141 hdd_ctx->acs_policy.acs_chan_freq = AUTO_CHANNEL_SELECT; 13142 13143 hdd_debug("sending coex indication"); 13144 13145 wlan_hdd_send_svc_nlink_msg(hdd_ctx->radio_index, 13146 WLAN_SVC_LTE_COEX_IND, NULL, 0); 13147 wlan_hdd_set_sap_csa_reason(hdd_ctx->psoc, adapter->deflink->vdev_id, 13148 CSA_REASON_LTE_COEX); 13149 hdd_switch_sap_channel(adapter->deflink, restart_chan, true); 13150 } 13151 13152 int hdd_clone_local_unsafe_chan(struct hdd_context *hdd_ctx, 13153 uint16_t **local_unsafe_list, uint16_t *local_unsafe_list_count) 13154 { 13155 uint32_t size; 13156 uint16_t *unsafe_list; 13157 uint16_t chan_count; 13158 13159 if (!hdd_ctx || !local_unsafe_list_count || !local_unsafe_list_count) 13160 return -EINVAL; 13161 13162 chan_count = QDF_MIN(hdd_ctx->unsafe_channel_count, 13163 NUM_CHANNELS); 13164 if (chan_count) { 13165 size = chan_count * sizeof(hdd_ctx->unsafe_channel_list[0]); 13166 unsafe_list = qdf_mem_malloc(size); 13167 if (!unsafe_list) 13168 return -ENOMEM; 13169 qdf_mem_copy(unsafe_list, hdd_ctx->unsafe_channel_list, size); 13170 } else { 13171 unsafe_list = NULL; 13172 } 13173 13174 *local_unsafe_list = unsafe_list; 13175 *local_unsafe_list_count = chan_count; 13176 13177 return 0; 13178 } 13179 13180 bool hdd_local_unsafe_channel_updated( 13181 struct hdd_context *hdd_ctx, uint16_t *local_unsafe_list, 13182 uint16_t local_unsafe_list_count, uint32_t restriction_mask) 13183 { 13184 int i, j; 13185 13186 if (local_unsafe_list_count != hdd_ctx->unsafe_channel_count) 13187 return true; 13188 if (local_unsafe_list_count == 0) 13189 return false; 13190 for (i = 0; i < local_unsafe_list_count; i++) { 13191 for (j = 0; j < local_unsafe_list_count; j++) 13192 if (local_unsafe_list[i] == 13193 hdd_ctx->unsafe_channel_list[j]) 13194 break; 13195 if (j >= local_unsafe_list_count) 13196 break; 13197 } 13198 13199 if (ucfg_mlme_get_coex_unsafe_chan_nb_user_prefer(hdd_ctx->psoc)) { 13200 /* Return false if current channel list is same as previous 13201 * and restriction mask is not altered 13202 */ 13203 if (i >= local_unsafe_list_count && 13204 (restriction_mask == 13205 wlan_hdd_get_restriction_mask(hdd_ctx))) { 13206 hdd_info("unsafe chan list same"); 13207 return false; 13208 } 13209 } else if (i >= local_unsafe_list_count) { 13210 hdd_info("unsafe chan list same"); 13211 return false; 13212 } 13213 13214 return true; 13215 } 13216 #else 13217 static void hdd_init_channel_avoidance(struct hdd_context *hdd_ctx) 13218 { 13219 } 13220 13221 static inline void hdd_lte_coex_restart_sap(struct hdd_adapter *adapter, 13222 struct hdd_context *hdd_ctx) 13223 { 13224 hdd_debug("Channel avoidance is not enabled; Abort SAP restart"); 13225 } 13226 #endif /* defined(FEATURE_WLAN_CH_AVOID) */ 13227 13228 struct wlan_hdd_link_info * 13229 wlan_hdd_get_link_info_from_objmgr(struct wlan_objmgr_vdev *vdev) 13230 { 13231 if (!vdev) { 13232 hdd_err("null vdev object"); 13233 return NULL; 13234 } 13235 13236 if (vdev->vdev_nif.osdev) 13237 return vdev->vdev_nif.osdev->legacy_osif_priv; 13238 13239 return NULL; 13240 } 13241 13242 /** 13243 * hdd_indicate_mgmt_frame() - Wrapper to indicate management frame to 13244 * user space 13245 * @frame_ind: Management frame data to be informed. 13246 * 13247 * This function is used to indicate management frame to 13248 * user space 13249 * 13250 * Return: None 13251 * 13252 */ 13253 void hdd_indicate_mgmt_frame(tSirSmeMgmtFrameInd *frame_ind) 13254 { 13255 struct hdd_context *hdd_ctx = NULL; 13256 struct hdd_adapter *adapter = NULL, *next_adapter = NULL; 13257 int i, num_adapters; 13258 uint8_t vdev_id[WLAN_MAX_VDEVS + WLAN_MAX_ML_VDEVS]; 13259 struct ieee80211_mgmt *mgmt = 13260 (struct ieee80211_mgmt *)frame_ind->frameBuf; 13261 struct wlan_objmgr_vdev *vdev; 13262 wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_INDICATE_MGMT_FRAME; 13263 struct wlan_hdd_link_info *link_info; 13264 13265 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 13266 if (wlan_hdd_validate_context(hdd_ctx)) 13267 return; 13268 13269 if (frame_ind->frame_len < ieee80211_hdrlen(mgmt->frame_control)) { 13270 hdd_err(" Invalid frame length"); 13271 return; 13272 } 13273 13274 if (SME_SESSION_ID_ANY == frame_ind->sessionId) { 13275 for (i = 0; i < WLAN_MAX_VDEVS; i++) { 13276 link_info = hdd_get_link_info_by_vdev(hdd_ctx, i); 13277 if (link_info) { 13278 adapter = link_info->adapter; 13279 break; 13280 } 13281 } 13282 } else if (SME_SESSION_ID_BROADCAST == frame_ind->sessionId) { 13283 num_adapters = 0; 13284 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, 13285 next_adapter, dbgid) { 13286 hdd_adapter_for_each_active_link_info(adapter, 13287 link_info) { 13288 vdev_id[num_adapters] = link_info->vdev_id; 13289 num_adapters++; 13290 } 13291 /* dev_put has to be done here */ 13292 hdd_adapter_dev_put_debug(adapter, dbgid); 13293 } 13294 13295 adapter = NULL; 13296 13297 for (i = 0; i < num_adapters; i++) { 13298 vdev = wlan_objmgr_get_vdev_by_id_from_psoc( 13299 hdd_ctx->psoc, 13300 vdev_id[i], 13301 WLAN_OSIF_ID); 13302 13303 if (!vdev) 13304 continue; 13305 13306 link_info = wlan_hdd_get_link_info_from_objmgr(vdev); 13307 if (!link_info) { 13308 wlan_objmgr_vdev_release_ref(vdev, 13309 WLAN_OSIF_ID); 13310 continue; 13311 } 13312 13313 hdd_indicate_mgmt_frame_to_user(link_info->adapter, 13314 frame_ind->frame_len, 13315 frame_ind->frameBuf, 13316 frame_ind->frameType, 13317 frame_ind->rx_freq, 13318 frame_ind->rxRssi, 13319 frame_ind->rx_flags); 13320 wlan_objmgr_vdev_release_ref(vdev, WLAN_OSIF_ID); 13321 } 13322 13323 adapter = NULL; 13324 } else { 13325 link_info = hdd_get_link_info_by_vdev(hdd_ctx, 13326 frame_ind->sessionId); 13327 13328 if (!link_info) { 13329 hdd_err("Invalid vdev"); 13330 return; 13331 } 13332 13333 adapter = link_info->adapter; 13334 } 13335 13336 if ((adapter) && 13337 (WLAN_HDD_ADAPTER_MAGIC == adapter->magic)) 13338 hdd_indicate_mgmt_frame_to_user(adapter, 13339 frame_ind->frame_len, 13340 frame_ind->frameBuf, 13341 frame_ind->frameType, 13342 frame_ind->rx_freq, 13343 frame_ind->rxRssi, 13344 frame_ind->rx_flags); 13345 } 13346 13347 void hdd_acs_response_timeout_handler(void *context) 13348 { 13349 struct hdd_external_acs_timer_context *timer_context = 13350 (struct hdd_external_acs_timer_context *)context; 13351 struct hdd_adapter *adapter; 13352 struct hdd_context *hdd_ctx; 13353 uint8_t reason; 13354 struct sap_context *sap_context; 13355 struct wlan_hdd_link_info *link_info; 13356 13357 hdd_enter(); 13358 if (!timer_context) { 13359 hdd_err("invalid timer context"); 13360 return; 13361 } 13362 adapter = timer_context->adapter; 13363 reason = timer_context->reason; 13364 13365 if (!adapter || adapter->magic != WLAN_HDD_ADAPTER_MAGIC) { 13366 hdd_err("invalid adapter or adapter has invalid magic"); 13367 return; 13368 } 13369 13370 hdd_ctx = WLAN_HDD_GET_CTX(adapter); 13371 if (wlan_hdd_validate_context(hdd_ctx)) 13372 return; 13373 13374 link_info = adapter->deflink; 13375 if (!test_bit(VENDOR_ACS_RESPONSE_PENDING, &link_info->link_flags)) 13376 return; 13377 13378 clear_bit(VENDOR_ACS_RESPONSE_PENDING, &link_info->link_flags); 13379 13380 hdd_err("ACS timeout happened for %s reason %d", 13381 adapter->dev->name, reason); 13382 13383 sap_context = WLAN_HDD_GET_SAP_CTX_PTR(link_info); 13384 switch (reason) { 13385 /* SAP init case */ 13386 case QCA_WLAN_VENDOR_ACS_SELECT_REASON_INIT: 13387 wlan_sap_set_vendor_acs(sap_context, false); 13388 wlan_hdd_cfg80211_start_acs(link_info); 13389 break; 13390 /* DFS detected on current channel */ 13391 case QCA_WLAN_VENDOR_ACS_SELECT_REASON_DFS: 13392 wlan_sap_update_next_channel(sap_context, 0, 0); 13393 sme_update_new_channel_event(hdd_ctx->mac_handle, 13394 link_info->vdev_id); 13395 break; 13396 /* LTE coex event on current channel */ 13397 case QCA_WLAN_VENDOR_ACS_SELECT_REASON_LTE_COEX: 13398 hdd_lte_coex_restart_sap(adapter, hdd_ctx); 13399 break; 13400 default: 13401 hdd_info("invalid reason for timer invoke"); 13402 } 13403 } 13404 13405 /** 13406 * hdd_override_ini_config - Override INI config 13407 * @hdd_ctx: HDD context 13408 * 13409 * Override INI config based on module parameter. 13410 * 13411 * Return: None 13412 */ 13413 static void hdd_override_ini_config(struct hdd_context *hdd_ctx) 13414 { 13415 QDF_STATUS status; 13416 13417 if (0 == enable_dfs_chan_scan || 1 == enable_dfs_chan_scan) { 13418 ucfg_scan_cfg_set_dfs_chan_scan_allowed(hdd_ctx->psoc, 13419 enable_dfs_chan_scan); 13420 hdd_debug("Module enable_dfs_chan_scan set to %d", 13421 enable_dfs_chan_scan); 13422 } 13423 if (0 == enable_11d || 1 == enable_11d) { 13424 status = ucfg_mlme_set_11d_enabled(hdd_ctx->psoc, enable_11d); 13425 if (!QDF_IS_STATUS_SUCCESS(status)) 13426 hdd_err("Failed to set 11d_enable flag"); 13427 } 13428 } 13429 13430 #ifdef ENABLE_MTRACE_LOG 13431 static void hdd_set_mtrace_for_each(struct hdd_context *hdd_ctx) 13432 { 13433 uint8_t module_id = 0; 13434 int qdf_print_idx = -1; 13435 13436 qdf_print_idx = qdf_get_pidx(); 13437 for (module_id = 0; module_id < QDF_MODULE_ID_MAX; module_id++) 13438 qdf_print_set_category_verbose( 13439 qdf_print_idx, 13440 module_id, QDF_TRACE_LEVEL_TRACE, 13441 hdd_ctx->config->enable_mtrace); 13442 } 13443 #else 13444 static void hdd_set_mtrace_for_each(struct hdd_context *hdd_ctx) 13445 { 13446 } 13447 13448 #endif 13449 13450 /** 13451 * hdd_log_level_to_bitmask() - user space log level to host log bitmask 13452 * @user_log_level: user space log level 13453 * 13454 * Convert log level from user space to host log level bitmask. 13455 * 13456 * Return: Bitmask of log levels to be enabled 13457 */ 13458 static uint32_t hdd_log_level_to_bitmask(enum host_log_level user_log_level) 13459 { 13460 QDF_TRACE_LEVEL host_trace_level; 13461 uint32_t bitmask; 13462 13463 switch (user_log_level) { 13464 case HOST_LOG_LEVEL_NONE: 13465 host_trace_level = QDF_TRACE_LEVEL_NONE; 13466 break; 13467 case HOST_LOG_LEVEL_FATAL: 13468 host_trace_level = QDF_TRACE_LEVEL_FATAL; 13469 break; 13470 case HOST_LOG_LEVEL_ERROR: 13471 host_trace_level = QDF_TRACE_LEVEL_ERROR; 13472 break; 13473 case HOST_LOG_LEVEL_WARN: 13474 host_trace_level = QDF_TRACE_LEVEL_WARN; 13475 break; 13476 case HOST_LOG_LEVEL_INFO: 13477 host_trace_level = QDF_TRACE_LEVEL_INFO_LOW; 13478 break; 13479 case HOST_LOG_LEVEL_DEBUG: 13480 host_trace_level = QDF_TRACE_LEVEL_DEBUG; 13481 break; 13482 case HOST_LOG_LEVEL_TRACE: 13483 host_trace_level = QDF_TRACE_LEVEL_TRACE; 13484 break; 13485 default: 13486 host_trace_level = QDF_TRACE_LEVEL_TRACE; 13487 break; 13488 } 13489 13490 bitmask = (1 << (host_trace_level + 1)) - 1; 13491 13492 return bitmask; 13493 } 13494 13495 /** 13496 * hdd_set_trace_level_for_each - Set trace level for each INI config 13497 * @hdd_ctx: HDD context 13498 * 13499 * Set trace level for each module based on INI config. 13500 * 13501 * Return: None 13502 */ 13503 static void hdd_set_trace_level_for_each(struct hdd_context *hdd_ctx) 13504 { 13505 uint8_t host_module_log[QDF_MODULE_ID_MAX * 2]; 13506 qdf_size_t host_module_log_num = 0; 13507 QDF_MODULE_ID module_id; 13508 uint32_t bitmask; 13509 uint32_t i; 13510 13511 qdf_uint8_array_parse(cfg_get(hdd_ctx->psoc, 13512 CFG_ENABLE_HOST_MODULE_LOG_LEVEL), 13513 host_module_log, 13514 QDF_MODULE_ID_MAX * 2, 13515 &host_module_log_num); 13516 13517 for (i = 0; i + 1 < host_module_log_num; i += 2) { 13518 module_id = host_module_log[i]; 13519 bitmask = hdd_log_level_to_bitmask(host_module_log[i + 1]); 13520 if (module_id < QDF_MODULE_ID_MAX && 13521 module_id >= QDF_MODULE_ID_MIN) 13522 hdd_qdf_trace_enable(module_id, bitmask); 13523 } 13524 13525 hdd_set_mtrace_for_each(hdd_ctx); 13526 } 13527 13528 /** 13529 * hdd_context_init() - Initialize HDD context 13530 * @hdd_ctx: HDD context. 13531 * 13532 * Initialize HDD context along with all the feature specific contexts. 13533 * 13534 * return: 0 on success and errno on failure. 13535 */ 13536 static int hdd_context_init(struct hdd_context *hdd_ctx) 13537 { 13538 int ret; 13539 13540 hdd_ctx->ioctl_scan_mode = eSIR_ACTIVE_SCAN; 13541 hdd_ctx->max_intf_count = WLAN_MAX_VDEVS; 13542 13543 init_completion(&hdd_ctx->mc_sus_event_var); 13544 init_completion(&hdd_ctx->ready_to_suspend); 13545 13546 qdf_spinlock_create(&hdd_ctx->connection_status_lock); 13547 qdf_spinlock_create(&hdd_ctx->hdd_adapter_lock); 13548 13549 qdf_list_create(&hdd_ctx->hdd_adapters, 0); 13550 13551 ret = hdd_scan_context_init(hdd_ctx); 13552 if (ret) 13553 goto list_destroy; 13554 13555 ret = hdd_sap_context_init(hdd_ctx); 13556 if (ret) 13557 goto scan_destroy; 13558 13559 ret = ucfg_dp_bbm_context_init(hdd_ctx->psoc); 13560 if (ret) 13561 goto sap_destroy; 13562 13563 wlan_hdd_cfg80211_extscan_init(hdd_ctx); 13564 13565 hdd_init_offloaded_packets_ctx(hdd_ctx); 13566 13567 ret = wlan_hdd_cfg80211_init(hdd_ctx->parent_dev, hdd_ctx->wiphy, 13568 hdd_ctx->config); 13569 if (ret) 13570 goto bbm_destroy; 13571 13572 qdf_wake_lock_create(&hdd_ctx->monitor_mode_wakelock, 13573 "monitor_mode_wakelock"); 13574 13575 return 0; 13576 13577 bbm_destroy: 13578 ucfg_dp_bbm_context_deinit(hdd_ctx->psoc); 13579 13580 sap_destroy: 13581 hdd_sap_context_destroy(hdd_ctx); 13582 13583 scan_destroy: 13584 hdd_scan_context_destroy(hdd_ctx); 13585 list_destroy: 13586 qdf_list_destroy(&hdd_ctx->hdd_adapters); 13587 13588 return ret; 13589 } 13590 13591 void hdd_psoc_idle_timer_start(struct hdd_context *hdd_ctx) 13592 { 13593 uint32_t timeout_ms = hdd_ctx->config->iface_change_wait_time; 13594 uint32_t suspend_timeout_ms; 13595 enum wake_lock_reason reason = 13596 WIFI_POWER_EVENT_WAKELOCK_IFACE_CHANGE_TIMER; 13597 13598 if (!timeout_ms) { 13599 hdd_info("psoc idle timer is disabled"); 13600 return; 13601 } 13602 13603 hdd_debug("Starting psoc idle timer"); 13604 13605 /* If PCIe gen speed change is requested, reduce idle shutdown 13606 * timeout to 100 ms 13607 */ 13608 if (hdd_ctx->current_pcie_gen_speed) { 13609 timeout_ms = HDD_PCIE_GEN_SPEED_CHANGE_TIMEOUT_MS; 13610 hdd_info("pcie gen speed change requested"); 13611 } 13612 13613 qdf_delayed_work_start(&hdd_ctx->psoc_idle_timeout_work, timeout_ms); 13614 suspend_timeout_ms = timeout_ms + HDD_PSOC_IDLE_SHUTDOWN_SUSPEND_DELAY; 13615 hdd_prevent_suspend_timeout(suspend_timeout_ms, reason); 13616 } 13617 13618 void hdd_psoc_idle_timer_stop(struct hdd_context *hdd_ctx) 13619 { 13620 qdf_delayed_work_stop_sync(&hdd_ctx->psoc_idle_timeout_work); 13621 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_IFACE_CHANGE_TIMER); 13622 hdd_debug("Stopped psoc idle timer"); 13623 } 13624 13625 13626 /** 13627 * __hdd_psoc_idle_shutdown() - perform an idle shutdown on the given psoc 13628 * @hdd_ctx: the hdd context which should be shutdown 13629 * 13630 * When no interfaces are "up" on a psoc, an idle shutdown timer is started. 13631 * If no interfaces are brought up before the timer expires, we do an 13632 * "idle shutdown," cutting power to the physical SoC to save power. This is 13633 * done completely transparently from the perspective of userspace. 13634 * 13635 * Return: None 13636 */ 13637 static int __hdd_psoc_idle_shutdown(struct hdd_context *hdd_ctx) 13638 { 13639 struct osif_psoc_sync *psoc_sync; 13640 int errno; 13641 13642 hdd_enter(); 13643 13644 hdd_reg_wait_for_country_change(hdd_ctx); 13645 13646 errno = osif_psoc_sync_trans_start(hdd_ctx->parent_dev, &psoc_sync); 13647 if (errno) { 13648 hdd_info("psoc busy, abort idle shutdown; errno:%d", errno); 13649 errno = -EAGAIN; 13650 goto exit; 13651 } 13652 13653 osif_psoc_sync_wait_for_ops(psoc_sync); 13654 /* 13655 * This is to handle scenario in which platform driver triggers 13656 * idle_shutdown if Deep Sleep/Hibernate entry notification is 13657 * received from modem subsystem in wearable devices 13658 */ 13659 if (hdd_is_any_interface_open(hdd_ctx)) { 13660 hdd_err_rl("all interfaces are not down, ignore idle shutdown"); 13661 errno = -EAGAIN; 13662 } else { 13663 errno = hdd_wlan_stop_modules(hdd_ctx, false); 13664 } 13665 13666 osif_psoc_sync_trans_stop(psoc_sync); 13667 13668 exit: 13669 hdd_exit(); 13670 return errno; 13671 } 13672 13673 static int __hdd_mode_change_psoc_idle_shutdown(struct hdd_context *hdd_ctx) 13674 { 13675 is_mode_change_psoc_idle_shutdown = false; 13676 return hdd_wlan_stop_modules(hdd_ctx, true); 13677 } 13678 13679 int hdd_psoc_idle_shutdown(struct device *dev) 13680 { 13681 int ret; 13682 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 13683 13684 if (!hdd_ctx) 13685 return -EINVAL; 13686 13687 if (is_mode_change_psoc_idle_shutdown) 13688 ret = __hdd_mode_change_psoc_idle_shutdown(hdd_ctx); 13689 else { 13690 ret = __hdd_psoc_idle_shutdown(hdd_ctx); 13691 } 13692 13693 return ret; 13694 } 13695 13696 static int __hdd_psoc_idle_restart(struct hdd_context *hdd_ctx) 13697 { 13698 int ret; 13699 13700 ret = hdd_soc_idle_restart_lock(hdd_ctx->parent_dev); 13701 if (ret) 13702 return ret; 13703 13704 ret = hdd_wlan_start_modules(hdd_ctx, false); 13705 13706 hdd_soc_idle_restart_unlock(); 13707 13708 return ret; 13709 } 13710 13711 int hdd_psoc_idle_restart(struct device *dev) 13712 { 13713 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 13714 13715 if (!hdd_ctx) 13716 return -EINVAL; 13717 13718 return __hdd_psoc_idle_restart(hdd_ctx); 13719 } 13720 13721 int hdd_trigger_psoc_idle_restart(struct hdd_context *hdd_ctx) 13722 { 13723 int ret; 13724 13725 QDF_BUG(rtnl_is_locked()); 13726 13727 hdd_psoc_idle_timer_stop(hdd_ctx); 13728 if (hdd_ctx->driver_status == DRIVER_MODULES_ENABLED) { 13729 hdd_nofl_debug("Driver modules already Enabled"); 13730 return 0; 13731 } 13732 13733 ret = hdd_soc_idle_restart_lock(hdd_ctx->parent_dev); 13734 if (ret) 13735 return ret; 13736 13737 if (hdd_ctx->current_pcie_gen_speed) { 13738 hdd_info("request pcie gen speed change to %d", 13739 hdd_ctx->current_pcie_gen_speed); 13740 13741 /* call pld api for pcie gen speed change */ 13742 ret = pld_set_pcie_gen_speed(hdd_ctx->parent_dev, 13743 hdd_ctx->current_pcie_gen_speed); 13744 if (ret) 13745 hdd_err_rl("failed to set pcie gen speed"); 13746 13747 hdd_ctx->current_pcie_gen_speed = 0; 13748 } 13749 13750 qdf_event_reset(&hdd_ctx->regulatory_update_event); 13751 qdf_mutex_acquire(&hdd_ctx->regulatory_status_lock); 13752 hdd_ctx->is_regulatory_update_in_progress = true; 13753 qdf_mutex_release(&hdd_ctx->regulatory_status_lock); 13754 13755 ret = pld_idle_restart(hdd_ctx->parent_dev, hdd_psoc_idle_restart); 13756 hdd_soc_idle_restart_unlock(); 13757 13758 return ret; 13759 } 13760 13761 /** 13762 * hdd_psoc_idle_timeout_callback() - Handler for psoc idle timeout 13763 * @priv: pointer to hdd context 13764 * 13765 * Return: None 13766 */ 13767 static void hdd_psoc_idle_timeout_callback(void *priv) 13768 { 13769 int ret; 13770 struct hdd_context *hdd_ctx = priv; 13771 void *hif_ctx; 13772 13773 if (wlan_hdd_validate_context(hdd_ctx)) 13774 return; 13775 13776 hif_ctx = cds_get_context(QDF_MODULE_ID_HIF); 13777 if (hif_ctx) { 13778 /* 13779 * Trigger runtime sync resume before psoc_idle_shutdown 13780 * such that resume can happen successfully 13781 */ 13782 qdf_rtpm_sync_resume(); 13783 } 13784 13785 hdd_info("Psoc idle timeout elapsed; starting psoc shutdown"); 13786 13787 ret = pld_idle_shutdown(hdd_ctx->parent_dev, hdd_psoc_idle_shutdown); 13788 if (-EAGAIN == ret || hdd_ctx->is_wiphy_suspended) { 13789 hdd_debug("System suspend in progress. Restart idle shutdown timer"); 13790 hdd_psoc_idle_timer_start(hdd_ctx); 13791 } 13792 13793 /* Clear the recovery flag for PCIe discrete soc after idle shutdown*/ 13794 if (PLD_BUS_TYPE_PCIE == pld_get_bus_type(hdd_ctx->parent_dev) && 13795 -EBUSY != ret) 13796 cds_set_recovery_in_progress(false); 13797 } 13798 13799 #ifdef WLAN_LOGGING_SOCK_SVC_ENABLE 13800 static void hdd_set_wlan_logging(struct hdd_context *hdd_ctx) 13801 { 13802 wlan_set_console_log_levels(hdd_ctx->config->wlan_console_log_levels); 13803 wlan_logging_set_active(hdd_ctx->config->wlan_logging_enable); 13804 } 13805 #else 13806 static void hdd_set_wlan_logging(struct hdd_context *hdd_ctx) 13807 { } 13808 #endif 13809 13810 #ifdef WLAN_LOGGING_SOCK_SVC_ENABLE 13811 static void hdd_init_wlan_logging_params(struct hdd_config *config, 13812 struct wlan_objmgr_psoc *psoc) 13813 { 13814 config->wlan_logging_enable = cfg_get(psoc, CFG_WLAN_LOGGING_SUPPORT); 13815 13816 config->wlan_console_log_levels = 13817 cfg_get(psoc, CFG_WLAN_LOGGING_CONSOLE_SUPPORT); 13818 config->host_log_custom_nl_proto = 13819 cfg_get(psoc, CFG_HOST_LOG_CUSTOM_NETLINK_PROTO); 13820 } 13821 #else 13822 static void hdd_init_wlan_logging_params(struct hdd_config *config, 13823 struct wlan_objmgr_psoc *psoc) 13824 { 13825 } 13826 #endif 13827 13828 #ifdef FEATURE_WLAN_AUTO_SHUTDOWN 13829 static void hdd_init_wlan_auto_shutdown(struct hdd_config *config, 13830 struct wlan_objmgr_psoc *psoc) 13831 { 13832 config->wlan_auto_shutdown = cfg_get(psoc, CFG_WLAN_AUTO_SHUTDOWN); 13833 } 13834 #else 13835 static void hdd_init_wlan_auto_shutdown(struct hdd_config *config, 13836 struct wlan_objmgr_psoc *psoc) 13837 { 13838 } 13839 #endif 13840 13841 #ifndef REMOVE_PKT_LOG 13842 static void hdd_init_packet_log(struct hdd_config *config, 13843 struct wlan_objmgr_psoc *psoc) 13844 { 13845 config->enable_packet_log = cfg_get(psoc, CFG_ENABLE_PACKET_LOG); 13846 } 13847 #else 13848 static void hdd_init_packet_log(struct hdd_config *config, 13849 struct wlan_objmgr_psoc *psoc) 13850 { 13851 } 13852 #endif 13853 13854 #ifdef ENABLE_MTRACE_LOG 13855 static void hdd_init_mtrace_log(struct hdd_config *config, 13856 struct wlan_objmgr_psoc *psoc) 13857 { 13858 config->enable_mtrace = cfg_get(psoc, CFG_ENABLE_MTRACE); 13859 } 13860 #else 13861 static void hdd_init_mtrace_log(struct hdd_config *config, 13862 struct wlan_objmgr_psoc *psoc) 13863 { 13864 } 13865 #endif 13866 13867 #ifdef FEATURE_RUNTIME_PM 13868 static void hdd_init_runtime_pm(struct hdd_config *config, 13869 struct wlan_objmgr_psoc *psoc) 13870 { 13871 config->runtime_pm = cfg_get(psoc, CFG_ENABLE_RUNTIME_PM); 13872 } 13873 13874 bool hdd_is_runtime_pm_enabled(struct hdd_context *hdd_ctx) 13875 { 13876 return hdd_ctx->config->runtime_pm != hdd_runtime_pm_disabled; 13877 } 13878 #else 13879 static void hdd_init_runtime_pm(struct hdd_config *config, 13880 struct wlan_objmgr_psoc *psoc) 13881 13882 { 13883 } 13884 13885 bool hdd_is_runtime_pm_enabled(struct hdd_context *hdd_ctx) 13886 { 13887 return false; 13888 } 13889 #endif 13890 13891 #ifdef WLAN_FEATURE_WMI_SEND_RECV_QMI 13892 static void hdd_init_qmi_stats(struct hdd_config *config, 13893 struct wlan_objmgr_psoc *psoc) 13894 { 13895 config->is_qmi_stats_enabled = cfg_get(psoc, CFG_ENABLE_QMI_STATS); 13896 } 13897 #else 13898 static void hdd_init_qmi_stats(struct hdd_config *config, 13899 struct wlan_objmgr_psoc *psoc) 13900 13901 { 13902 } 13903 #endif 13904 13905 #ifdef FEATURE_WLAN_DYNAMIC_CVM 13906 static void hdd_init_vc_mode_cfg_bitmap(struct hdd_config *config, 13907 struct wlan_objmgr_psoc *psoc) 13908 { 13909 config->vc_mode_cfg_bitmap = cfg_get(psoc, CFG_VC_MODE_BITMAP); 13910 } 13911 #else 13912 static void hdd_init_vc_mode_cfg_bitmap(struct hdd_config *config, 13913 struct wlan_objmgr_psoc *psoc) 13914 { 13915 } 13916 #endif 13917 13918 #ifdef DHCP_SERVER_OFFLOAD 13919 static void 13920 hdd_init_dhcp_server_ip(struct hdd_context *hdd_ctx) 13921 { 13922 uint8_t num_entries; 13923 13924 hdd_ctx->config->dhcp_server_ip.is_dhcp_server_ip_valid = true; 13925 hdd_string_to_u8_array(cfg_get(hdd_ctx->psoc, CFG_DHCP_SERVER_IP_NAME), 13926 hdd_ctx->config->dhcp_server_ip.dhcp_server_ip, 13927 &num_entries, IPADDR_NUM_ENTRIES); 13928 13929 if (num_entries != IPADDR_NUM_ENTRIES) { 13930 hdd_err("Incorrect IP address (%s) assigned for DHCP server!", 13931 cfg_get(hdd_ctx->psoc, CFG_DHCP_SERVER_IP_NAME)); 13932 hdd_config->dhcp_server_ip.is_dhcp_server_ip_valid = false; 13933 } 13934 } 13935 #else 13936 static void 13937 hdd_init_dhcp_server_ip(struct hdd_context *hdd_ctx) 13938 { 13939 } 13940 #endif 13941 13942 #ifdef SAR_SAFETY_FEATURE 13943 static void hdd_sar_cfg_update(struct hdd_config *config, 13944 struct wlan_objmgr_psoc *psoc) 13945 { 13946 config->sar_safety_timeout = cfg_get(psoc, CFG_SAR_SAFETY_TIMEOUT); 13947 config->sar_safety_unsolicited_timeout = 13948 cfg_get(psoc, CFG_SAR_SAFETY_UNSOLICITED_TIMEOUT); 13949 config->sar_safety_req_resp_timeout = 13950 cfg_get(psoc, CFG_SAR_SAFETY_REQ_RESP_TIMEOUT); 13951 config->sar_safety_req_resp_retry = 13952 cfg_get(psoc, CFG_SAR_SAFETY_REQ_RESP_RETRIES); 13953 config->sar_safety_index = cfg_get(psoc, CFG_SAR_SAFETY_INDEX); 13954 config->sar_safety_sleep_index = 13955 cfg_get(psoc, CFG_SAR_SAFETY_SLEEP_INDEX); 13956 config->enable_sar_safety = 13957 cfg_get(psoc, CFG_ENABLE_SAR_SAFETY_FEATURE); 13958 config->config_sar_safety_sleep_index = 13959 cfg_get(psoc, CFG_CONFIG_SAR_SAFETY_SLEEP_MODE_INDEX); 13960 } 13961 #else 13962 static void hdd_sar_cfg_update(struct hdd_config *config, 13963 struct wlan_objmgr_psoc *psoc) 13964 { 13965 } 13966 #endif 13967 13968 #ifdef FEATURE_SET 13969 /** 13970 * hdd_get_wifi_features_cfg_update() - Initialize get wifi features cfg 13971 * @config: Pointer to HDD config 13972 * @psoc: psoc pointer 13973 * 13974 * Return: None 13975 */ 13976 static void hdd_get_wifi_features_cfg_update(struct hdd_config *config, 13977 struct wlan_objmgr_psoc *psoc) 13978 { 13979 config->get_wifi_features = cfg_get(psoc, CFG_GET_WIFI_FEATURES); 13980 } 13981 #else 13982 static void hdd_get_wifi_features_cfg_update(struct hdd_config *config, 13983 struct wlan_objmgr_psoc *psoc) 13984 { 13985 } 13986 #endif 13987 13988 #ifdef FEATURE_RUNTIME_PM 13989 /** 13990 * hdd_init_cpu_cxpc_threshold_cfg() - Initialize cpu cxpc threshold cfg 13991 * @config: Pointer to HDD config 13992 * @psoc: psoc pointer 13993 * 13994 * Return: None 13995 */ 13996 static void hdd_init_cpu_cxpc_threshold_cfg(struct hdd_config *config, 13997 struct wlan_objmgr_psoc *psoc) 13998 { 13999 config->cpu_cxpc_threshold = cfg_get(psoc, CFG_CPU_CXPC_THRESHOLD); 14000 } 14001 #else 14002 static void hdd_init_cpu_cxpc_threshold_cfg(struct hdd_config *config, 14003 struct wlan_objmgr_psoc *psoc) 14004 { 14005 } 14006 #endif 14007 14008 /** 14009 * hdd_cfg_params_init() - Initialize hdd params in hdd_config structure 14010 * @hdd_ctx: Pointer to HDD context 14011 * 14012 * Return: None 14013 */ 14014 static void hdd_cfg_params_init(struct hdd_context *hdd_ctx) 14015 { 14016 struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc; 14017 struct hdd_config *config = hdd_ctx->config; 14018 if (!psoc) { 14019 hdd_err("Invalid psoc"); 14020 return; 14021 } 14022 14023 if (!config) { 14024 hdd_err("Invalid hdd config"); 14025 return; 14026 } 14027 14028 config->dot11Mode = cfg_get(psoc, CFG_HDD_DOT11_MODE); 14029 config->bug_on_reinit_failure = cfg_get(psoc, 14030 CFG_BUG_ON_REINIT_FAILURE); 14031 14032 config->is_ramdump_enabled = cfg_get(psoc, 14033 CFG_ENABLE_RAMDUMP_COLLECTION); 14034 14035 config->iface_change_wait_time = cfg_get(psoc, 14036 CFG_INTERFACE_CHANGE_WAIT); 14037 14038 config->multicast_host_fw_msgs = cfg_get(psoc, 14039 CFG_MULTICAST_HOST_FW_MSGS); 14040 14041 config->private_wext_control = cfg_get(psoc, CFG_PRIVATE_WEXT_CONTROL); 14042 config->enablefwprint = cfg_get(psoc, CFG_ENABLE_FW_UART_PRINT); 14043 config->enable_fw_log = cfg_get(psoc, CFG_ENABLE_FW_LOG); 14044 config->operating_chan_freq = cfg_get(psoc, CFG_OPERATING_FREQUENCY); 14045 config->num_vdevs = cfg_get(psoc, CFG_NUM_VDEV_ENABLE); 14046 qdf_str_lcopy(config->enable_concurrent_sta, 14047 cfg_get(psoc, CFG_ENABLE_CONCURRENT_STA), 14048 CFG_CONCURRENT_IFACE_MAX_LEN); 14049 qdf_str_lcopy(config->dbs_scan_selection, 14050 cfg_get(psoc, CFG_DBS_SCAN_SELECTION), 14051 CFG_DBS_SCAN_PARAM_LENGTH); 14052 config->inform_bss_rssi_raw = cfg_get(psoc, CFG_INFORM_BSS_RSSI_RAW); 14053 config->mac_provision = cfg_get(psoc, CFG_ENABLE_MAC_PROVISION); 14054 config->provisioned_intf_pool = 14055 cfg_get(psoc, CFG_PROVISION_INTERFACE_POOL); 14056 config->derived_intf_pool = cfg_get(psoc, CFG_DERIVED_INTERFACE_POOL); 14057 config->advertise_concurrent_operation = 14058 cfg_get(psoc, 14059 CFG_ADVERTISE_CONCURRENT_OPERATION); 14060 config->is_unit_test_framework_enabled = 14061 cfg_get(psoc, CFG_ENABLE_UNIT_TEST_FRAMEWORK); 14062 config->disable_channel = cfg_get(psoc, CFG_ENABLE_DISABLE_CHANNEL); 14063 config->enable_sar_conversion = cfg_get(psoc, CFG_SAR_CONVERSION); 14064 config->nb_commands_interval = 14065 cfg_get(psoc, CFG_NB_COMMANDS_RATE_LIMIT); 14066 14067 hdd_init_vc_mode_cfg_bitmap(config, psoc); 14068 hdd_init_runtime_pm(config, psoc); 14069 hdd_init_wlan_auto_shutdown(config, psoc); 14070 hdd_init_wlan_logging_params(config, psoc); 14071 hdd_init_packet_log(config, psoc); 14072 hdd_init_mtrace_log(config, psoc); 14073 hdd_init_dhcp_server_ip(hdd_ctx); 14074 hdd_dp_cfg_update(psoc, hdd_ctx); 14075 hdd_sar_cfg_update(config, psoc); 14076 hdd_init_qmi_stats(config, psoc); 14077 hdd_club_ll_stats_in_get_sta_cfg_update(config, psoc); 14078 config->read_mac_addr_from_mac_file = 14079 cfg_get(psoc, CFG_READ_MAC_ADDR_FROM_MAC_FILE); 14080 14081 hdd_get_wifi_features_cfg_update(config, psoc); 14082 hdd_init_cpu_cxpc_threshold_cfg(config, psoc); 14083 } 14084 14085 #ifdef CONNECTION_ROAMING_CFG 14086 static QDF_STATUS hdd_cfg_parse_connection_roaming_cfg(void) 14087 { 14088 QDF_STATUS status = QDF_STATUS_E_INVAL; 14089 bool is_valid; 14090 14091 is_valid = cfg_valid_ini_check(WLAN_CONNECTION_ROAMING_INI_FILE); 14092 14093 if (is_valid) 14094 status = cfg_parse(WLAN_CONNECTION_ROAMING_INI_FILE); 14095 if (QDF_IS_STATUS_ERROR(status)) { 14096 is_valid = cfg_valid_ini_check(WLAN_CONNECTION_ROAMING_BACKUP_INI_FILE); 14097 if (is_valid) 14098 status = cfg_parse(WLAN_CONNECTION_ROAMING_BACKUP_INI_FILE); 14099 } 14100 return status; 14101 } 14102 #else 14103 static inline QDF_STATUS hdd_cfg_parse_connection_roaming_cfg(void) 14104 { 14105 return QDF_STATUS_E_NOSUPPORT; 14106 } 14107 #endif 14108 14109 struct hdd_context *hdd_context_create(struct device *dev) 14110 { 14111 QDF_STATUS status; 14112 int ret = 0; 14113 struct hdd_context *hdd_ctx; 14114 14115 hdd_enter(); 14116 14117 hdd_ctx = hdd_cfg80211_wiphy_alloc(); 14118 if (!hdd_ctx) { 14119 ret = -ENOMEM; 14120 goto err_out; 14121 } 14122 14123 status = qdf_delayed_work_create(&hdd_ctx->psoc_idle_timeout_work, 14124 hdd_psoc_idle_timeout_callback, 14125 hdd_ctx); 14126 if (QDF_IS_STATUS_ERROR(status)) { 14127 ret = qdf_status_to_os_return(status); 14128 goto wiphy_dealloc; 14129 } 14130 14131 hdd_pm_notifier_init(hdd_ctx); 14132 14133 hdd_ctx->parent_dev = dev; 14134 hdd_ctx->last_scan_reject_vdev_id = WLAN_UMAC_VDEV_ID_MAX; 14135 14136 hdd_ctx->config = qdf_mem_malloc(sizeof(struct hdd_config)); 14137 if (!hdd_ctx->config) { 14138 ret = -ENOMEM; 14139 goto err_free_hdd_context; 14140 } 14141 14142 status = cfg_parse(WLAN_INI_FILE); 14143 if (QDF_IS_STATUS_ERROR(status)) { 14144 hdd_err("Failed to parse cfg %s; status:%d\n", 14145 WLAN_INI_FILE, status); 14146 /* Assert if failed to parse at least one INI parameter */ 14147 QDF_BUG(status != QDF_STATUS_E_INVAL); 14148 ret = qdf_status_to_os_return(status); 14149 goto err_free_config; 14150 } 14151 14152 status = hdd_cfg_parse_connection_roaming_cfg(); 14153 14154 ret = hdd_objmgr_create_and_store_psoc(hdd_ctx, DEFAULT_PSOC_ID); 14155 if (ret) { 14156 QDF_DEBUG_PANIC("Psoc creation fails!"); 14157 goto err_release_store; 14158 } 14159 14160 if (QDF_IS_STATUS_SUCCESS(status)) 14161 ucfg_mlme_set_connection_roaming_ini_present(hdd_ctx->psoc, 14162 true); 14163 14164 hdd_cfg_params_init(hdd_ctx); 14165 14166 /* apply multiplier config, if not already set via module parameter */ 14167 if (qdf_timer_get_multiplier() == 1) 14168 qdf_timer_set_multiplier(cfg_get(hdd_ctx->psoc, 14169 CFG_TIMER_MULTIPLIER)); 14170 hdd_debug("set timer multiplier: %u", qdf_timer_get_multiplier()); 14171 14172 cds_set_fatal_event(cfg_get(hdd_ctx->psoc, 14173 CFG_ENABLE_FATAL_EVENT_TRIGGER)); 14174 14175 hdd_override_ini_config(hdd_ctx); 14176 14177 ret = hdd_context_init(hdd_ctx); 14178 14179 if (ret) 14180 goto err_hdd_objmgr_destroy; 14181 14182 if (hdd_get_conparam() == QDF_GLOBAL_EPPING_MODE) 14183 goto skip_multicast_logging; 14184 14185 cds_set_multicast_logging(hdd_ctx->config->multicast_host_fw_msgs); 14186 ret = hdd_init_netlink_services(hdd_ctx); 14187 if (ret) 14188 goto err_deinit_hdd_context; 14189 14190 hdd_set_wlan_logging(hdd_ctx); 14191 qdf_atomic_init(&hdd_ctx->adapter_ops_history.index); 14192 14193 skip_multicast_logging: 14194 hdd_set_trace_level_for_each(hdd_ctx); 14195 14196 cds_set_context(QDF_MODULE_ID_HDD, hdd_ctx); 14197 14198 wlan_hdd_sar_timers_init(hdd_ctx); 14199 14200 hdd_exit(); 14201 14202 return hdd_ctx; 14203 14204 err_deinit_hdd_context: 14205 hdd_context_deinit(hdd_ctx); 14206 14207 err_hdd_objmgr_destroy: 14208 hdd_objmgr_release_and_destroy_psoc(hdd_ctx); 14209 14210 err_release_store: 14211 cfg_release(); 14212 14213 err_free_config: 14214 qdf_mem_free(hdd_ctx->config); 14215 14216 err_free_hdd_context: 14217 qdf_delayed_work_destroy(&hdd_ctx->psoc_idle_timeout_work); 14218 14219 wiphy_dealloc: 14220 wiphy_free(hdd_ctx->wiphy); 14221 14222 err_out: 14223 return ERR_PTR(ret); 14224 } 14225 14226 #ifdef MULTI_CLIENT_LL_SUPPORT 14227 /** 14228 * wlan_hdd_init_multi_client_info_table()- Initialize the multi client info 14229 * table 14230 * @adapter: hdd adapter 14231 * 14232 * Return: none 14233 */ 14234 static void 14235 wlan_hdd_init_multi_client_info_table(struct hdd_adapter *adapter) 14236 { 14237 uint8_t i; 14238 14239 for (i = 0; i < WLM_MAX_HOST_CLIENT; i++) { 14240 adapter->client_info[i].client_id = i; 14241 adapter->client_info[i].port_id = 0; 14242 adapter->client_info[i].in_use = false; 14243 } 14244 } 14245 14246 void wlan_hdd_deinit_multi_client_info_table(struct hdd_adapter *adapter) 14247 { 14248 uint8_t i; 14249 14250 hdd_debug("deinitializing the client info table"); 14251 /* de-initialize the table for host driver client */ 14252 for (i = 0; i < WLM_MAX_HOST_CLIENT; i++) { 14253 if (adapter->client_info[i].in_use) { 14254 adapter->client_info[i].port_id = 0; 14255 adapter->client_info[i].client_id = i; 14256 adapter->client_info[i].in_use = false; 14257 } 14258 } 14259 } 14260 14261 /** 14262 * wlan_hdd_get_host_driver_port_id()- get host driver port id 14263 * @port_id: argument to be filled 14264 * 14265 * Return: none 14266 */ 14267 static void wlan_hdd_get_host_driver_port_id(uint32_t *port_id) 14268 { 14269 *port_id = WLAM_WLM_HOST_DRIVER_PORT_ID; 14270 } 14271 14272 #else 14273 static inline void 14274 wlan_hdd_init_multi_client_info_table(struct hdd_adapter *adapter) 14275 { 14276 } 14277 14278 static inline void wlan_hdd_get_host_driver_port_id(uint32_t *port_id) 14279 { 14280 } 14281 #endif 14282 14283 static void 14284 hdd_adapter_set_wlm_client_latency_level(struct hdd_adapter *adapter) 14285 { 14286 QDF_STATUS status; 14287 bool reset; 14288 uint32_t port_id; 14289 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); 14290 14291 if (!hdd_ctx) 14292 return; 14293 14294 status = ucfg_mlme_cfg_get_wlm_reset(hdd_ctx->psoc, &reset); 14295 if (QDF_IS_STATUS_ERROR(status)) { 14296 hdd_err("could not get the wlm reset flag"); 14297 reset = false; 14298 } 14299 14300 if (reset) 14301 goto out; 14302 14303 if (hdd_get_multi_client_ll_support(adapter)) { 14304 wlan_hdd_get_host_driver_port_id(&port_id); 14305 status = wlan_hdd_set_wlm_client_latency_level( 14306 adapter, port_id, 14307 adapter->latency_level); 14308 if (QDF_IS_STATUS_ERROR(status)) 14309 hdd_warn("Fail to set latency level:%u", status); 14310 } else { 14311 status = sme_set_wlm_latency_level(hdd_ctx->mac_handle, 14312 adapter->deflink->vdev_id, 14313 adapter->latency_level, 14314 0, false); 14315 if (QDF_IS_STATUS_ERROR(status)) 14316 hdd_warn("set wlm mode failed, %u", status); 14317 } 14318 out: 14319 hdd_debug("wlm initial mode %u", adapter->latency_level); 14320 } 14321 14322 #ifdef WLAN_HDD_MULTI_VDEV_SINGLE_NDEV 14323 struct qdf_mac_addr * 14324 hdd_adapter_get_link_mac_addr(struct wlan_hdd_link_info *link_info) 14325 { 14326 struct hdd_adapter *adapter; 14327 14328 if (!link_info) 14329 return NULL; 14330 14331 adapter = link_info->adapter; 14332 if (!hdd_adapter_is_ml_adapter(adapter) || 14333 qdf_is_macaddr_zero(&link_info->link_addr)) 14334 return &adapter->mac_addr; 14335 14336 return &link_info->link_addr; 14337 } 14338 #else 14339 struct qdf_mac_addr * 14340 hdd_adapter_get_link_mac_addr(struct wlan_hdd_link_info *link_info) 14341 { 14342 if (!link_info) 14343 return NULL; 14344 14345 return &link_info->adapter->mac_addr; 14346 } 14347 #endif 14348 14349 #if defined(WLAN_FEATURE_11BE_MLO) && defined(CFG80211_11BE_BASIC) && \ 14350 defined(WLAN_HDD_MULTI_VDEV_SINGLE_NDEV) 14351 QDF_STATUS hdd_adapter_check_duplicate_session(struct hdd_adapter *adapter) 14352 { 14353 int i = 0; 14354 QDF_STATUS status; 14355 uint8_t *addr_list[WLAN_MAX_MLD + 2] = {0}; 14356 struct wlan_hdd_link_info *link_info; 14357 14358 if (!hdd_adapter_is_ml_adapter(adapter) || 14359 adapter->device_mode == QDF_SAP_MODE) 14360 goto netdev_addr; 14361 14362 hdd_adapter_for_each_active_link_info(adapter, link_info) 14363 addr_list[i++] = &link_info->link_addr.bytes[0]; 14364 14365 netdev_addr: 14366 addr_list[i] = &adapter->mac_addr.bytes[0]; 14367 status = sme_check_for_duplicate_session(adapter->hdd_ctx->mac_handle, 14368 &addr_list[0]); 14369 return status; 14370 } 14371 14372 QDF_STATUS hdd_adapter_fill_link_address(struct hdd_adapter *adapter) 14373 { 14374 int i = 0; 14375 QDF_STATUS status; 14376 enum QDF_OPMODE opmode = adapter->device_mode; 14377 struct qdf_mac_addr link_addrs[WLAN_MAX_ML_BSS_LINKS] = {0}; 14378 struct wlan_hdd_link_info *link_info; 14379 14380 if (opmode != QDF_STA_MODE && opmode != QDF_SAP_MODE) 14381 return QDF_STATUS_SUCCESS; 14382 14383 if (opmode == QDF_SAP_MODE) { 14384 link_info = adapter->deflink; 14385 qdf_copy_macaddr(&link_info->link_addr, &adapter->mac_addr); 14386 return QDF_STATUS_SUCCESS; 14387 } 14388 14389 if (!hdd_adapter_is_ml_adapter(adapter)) 14390 return QDF_STATUS_SUCCESS; 14391 14392 status = hdd_derive_link_address_from_mld(&adapter->mac_addr, 14393 &link_addrs[0], 14394 WLAN_MAX_ML_BSS_LINKS); 14395 if (QDF_IS_STATUS_ERROR(status)) 14396 return status; 14397 14398 hdd_adapter_for_each_link_info(adapter, link_info) 14399 qdf_copy_macaddr(&link_info->link_addr, &link_addrs[i++]); 14400 14401 return status; 14402 } 14403 #elif defined(WLAN_FEATURE_11BE_MLO) && defined(CFG80211_11BE_BASIC) 14404 QDF_STATUS hdd_adapter_check_duplicate_session(struct hdd_adapter *adapter) 14405 { 14406 int i; 14407 QDF_STATUS status; 14408 uint8_t *addr_list[WLAN_MAX_MLD + 1] = {0}; 14409 struct hdd_adapter *link_adapter; 14410 struct hdd_mlo_adapter_info *mlo_adapter_info; 14411 mac_handle_t mac_handle = hdd_adapter_get_mac_handle(adapter); 14412 14413 if (hdd_adapter_is_ml_adapter(adapter) && 14414 adapter->device_mode == QDF_STA_MODE) { 14415 addr_list[0] = &adapter->mld_addr.bytes[0]; 14416 mlo_adapter_info = &adapter->mlo_adapter_info; 14417 for (i = 0; i < WLAN_MAX_MLD; i++) { 14418 link_adapter = mlo_adapter_info->link_adapter[i]; 14419 if (!link_adapter) 14420 continue; 14421 if (hdd_adapter_is_associated_with_ml_adapter( 14422 link_adapter)) { 14423 addr_list[1] = &link_adapter->mac_addr.bytes[0]; 14424 } 14425 } 14426 } else { 14427 addr_list[0] = &adapter->mac_addr.bytes[0]; 14428 } 14429 14430 status = sme_check_for_duplicate_session(mac_handle, &addr_list[0]); 14431 return status; 14432 } 14433 #else 14434 QDF_STATUS hdd_adapter_check_duplicate_session(struct hdd_adapter *adapter) 14435 { 14436 QDF_STATUS status; 14437 uint8_t *addr_list[2] = {0}; 14438 mac_handle_t mac_handle = hdd_adapter_get_mac_handle(adapter); 14439 14440 addr_list[0] = &adapter->mac_addr.bytes[0]; 14441 status = sme_check_for_duplicate_session(mac_handle, &addr_list[0]); 14442 14443 return status; 14444 } 14445 #endif 14446 14447 static void hdd_restore_info_for_ssr(struct hdd_adapter *adapter) 14448 { 14449 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); 14450 14451 if (cds_is_driver_recovering()) { 14452 /* ssr happens, recover the info */ 14453 hdd_set_vdev_phy_mode(adapter, adapter->user_phy_mode); 14454 wlan_mlme_restore_user_set_link_num(hdd_ctx->psoc); 14455 } else { 14456 /* intf down/up happens, reset default info */ 14457 hdd_set_vdev_phy_mode(adapter, QCA_WLAN_VENDOR_PHY_MODE_AUTO); 14458 wlan_mlme_clear_user_set_link_num(hdd_ctx->psoc); 14459 } 14460 } 14461 14462 void hdd_adapter_reset_station_ctx(struct hdd_adapter *adapter) 14463 { 14464 struct wlan_hdd_link_info *link_info; 14465 14466 hdd_adapter_for_each_link_info(adapter, link_info) 14467 hdd_cm_clear_ieee_link_id(link_info); 14468 } 14469 14470 int hdd_start_station_adapter(struct hdd_adapter *adapter) 14471 { 14472 QDF_STATUS status; 14473 int ret; 14474 struct wlan_hdd_link_info *link_info; 14475 14476 hdd_enter_dev(adapter->dev); 14477 if (test_bit(SME_SESSION_OPENED, &adapter->deflink->link_flags)) { 14478 hdd_err("session is already opened, %d", 14479 adapter->deflink->vdev_id); 14480 return qdf_status_to_os_return(QDF_STATUS_SUCCESS); 14481 } 14482 14483 if ((adapter->device_mode == QDF_P2P_DEVICE_MODE) || 14484 (adapter->device_mode == QDF_NAN_DISC_MODE)) 14485 wlan_hdd_lpc_del_monitor_interface(adapter->hdd_ctx); 14486 14487 status = hdd_adapter_fill_link_address(adapter); 14488 if (QDF_IS_STATUS_ERROR(status)) { 14489 hdd_debug("Link address derive failed"); 14490 return qdf_status_to_os_return(status); 14491 } 14492 14493 status = hdd_adapter_check_duplicate_session(adapter); 14494 if (QDF_IS_STATUS_ERROR(status)) { 14495 hdd_err("Duplicate session is existing with same mac address"); 14496 return qdf_status_to_os_return(status); 14497 } 14498 14499 hdd_adapter_for_each_active_link_info(adapter, link_info) { 14500 ret = hdd_vdev_create(link_info); 14501 if (ret) { 14502 hdd_err("failed to create vdev: %d", ret); 14503 goto fail; 14504 } 14505 14506 status = hdd_init_station_mode(link_info); 14507 if (QDF_STATUS_SUCCESS != status) { 14508 hdd_err("Error Initializing station mode: %d", status); 14509 ret = qdf_status_to_os_return(status); 14510 goto fail; 14511 } 14512 } 14513 14514 hdd_adapter_reset_station_ctx(adapter); 14515 14516 hdd_register_wext(adapter->dev); 14517 hdd_set_netdev_flags(adapter); 14518 14519 hdd_register_tx_flow_control(adapter, 14520 hdd_tx_resume_timer_expired_handler, 14521 hdd_tx_resume_cb, 14522 hdd_tx_flow_control_is_pause); 14523 14524 hdd_register_hl_netdev_fc_timer(adapter, 14525 hdd_tx_resume_timer_expired_handler); 14526 14527 if (hdd_get_multi_client_ll_support(adapter)) 14528 wlan_hdd_init_multi_client_info_table(adapter); 14529 14530 hdd_adapter_set_wlm_client_latency_level(adapter); 14531 hdd_adapter_update_mlo_mgr_mac_addr(adapter); 14532 hdd_restore_info_for_ssr(adapter); 14533 14534 hdd_exit(); 14535 return 0; 14536 14537 fail: 14538 hdd_adapter_for_each_active_link_info(adapter, link_info) 14539 hdd_vdev_destroy(link_info); 14540 14541 return ret; 14542 } 14543 14544 int hdd_start_ap_adapter(struct hdd_adapter *adapter, bool rtnl_held) 14545 { 14546 QDF_STATUS status; 14547 bool is_ssr = false; 14548 int ret; 14549 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); 14550 struct sap_context *sap_ctx; 14551 struct wlan_hdd_link_info *link_info = adapter->deflink; 14552 14553 hdd_enter(); 14554 14555 if (test_bit(SME_SESSION_OPENED, &link_info->link_flags)) { 14556 hdd_err("session is already opened, %d", 14557 link_info->vdev_id); 14558 return qdf_status_to_os_return(QDF_STATUS_SUCCESS); 14559 } 14560 14561 wlan_hdd_lpc_del_monitor_interface(hdd_ctx); 14562 14563 status = hdd_adapter_fill_link_address(adapter); 14564 if (QDF_IS_STATUS_ERROR(status)) { 14565 hdd_debug("Link address derive failed"); 14566 return qdf_status_to_os_return(status); 14567 } 14568 14569 status = hdd_adapter_check_duplicate_session(adapter); 14570 if (QDF_IS_STATUS_ERROR(status)) { 14571 hdd_err("Duplicate session is existing with same mac address"); 14572 return qdf_status_to_os_return(status); 14573 } 14574 14575 /* 14576 * In SSR case no need to create new sap context. 14577 * Otherwise create sap context first and then create 14578 * vdev as while creating the vdev, driver needs to 14579 * register SAP callback and that callback uses sap context 14580 */ 14581 if (WLAN_HDD_GET_SAP_CTX_PTR(link_info)) { 14582 is_ssr = true; 14583 } else if (!hdd_sap_create_ctx(adapter)) { 14584 hdd_err("sap creation failed"); 14585 return qdf_status_to_os_return(QDF_STATUS_E_FAILURE); 14586 } 14587 14588 ret = hdd_vdev_create(link_info); 14589 if (ret) { 14590 hdd_err("failed to create vdev, status:%d", ret); 14591 goto sap_destroy_ctx; 14592 } 14593 14594 sap_ctx = WLAN_HDD_GET_SAP_CTX_PTR(link_info); 14595 status = sap_acquire_vdev_ref(hdd_ctx->psoc, sap_ctx, 14596 link_info->vdev_id); 14597 if (!QDF_IS_STATUS_SUCCESS(status)) { 14598 hdd_err("Failed to get vdev ref for sap for session_id: %u", 14599 link_info->vdev_id); 14600 ret = qdf_status_to_os_return(status); 14601 goto sap_vdev_destroy; 14602 } 14603 14604 if (adapter->device_mode == QDF_SAP_MODE) { 14605 status = hdd_vdev_configure_rtt_params(sap_ctx->vdev); 14606 if (QDF_IS_STATUS_ERROR(status)) 14607 goto sap_release_ref; 14608 } 14609 14610 status = hdd_init_ap_mode(adapter, is_ssr, rtnl_held); 14611 if (QDF_STATUS_SUCCESS != status) { 14612 hdd_err("Error Initializing the AP mode: %d", status); 14613 ret = qdf_status_to_os_return(status); 14614 goto sap_release_ref; 14615 } 14616 14617 hdd_register_tx_flow_control(adapter, 14618 hdd_softap_tx_resume_timer_expired_handler, 14619 hdd_softap_tx_resume_cb, 14620 hdd_tx_flow_control_is_pause); 14621 14622 hdd_register_hl_netdev_fc_timer(adapter, 14623 hdd_tx_resume_timer_expired_handler); 14624 14625 hdd_exit(); 14626 return 0; 14627 14628 sap_release_ref: 14629 sap_release_vdev_ref(sap_ctx); 14630 sap_vdev_destroy: 14631 hdd_vdev_destroy(link_info); 14632 sap_destroy_ctx: 14633 hdd_sap_destroy_ctx(link_info); 14634 return ret; 14635 } 14636 14637 #if defined(QCA_LL_TX_FLOW_CONTROL_V2) || defined(QCA_LL_PDEV_TX_FLOW_CONTROL) 14638 /** 14639 * hdd_txrx_populate_cds_config() - Populate txrx cds configuration 14640 * @cds_cfg: CDS Configuration 14641 * @hdd_ctx: Pointer to hdd context 14642 * 14643 * Return: none 14644 */ 14645 static inline void hdd_txrx_populate_cds_config(struct cds_config_info 14646 *cds_cfg, 14647 struct hdd_context *hdd_ctx) 14648 { 14649 cds_cfg->tx_flow_stop_queue_th = 14650 cfg_get(hdd_ctx->psoc, CFG_DP_TX_FLOW_STOP_QUEUE_TH); 14651 cds_cfg->tx_flow_start_queue_offset = 14652 cfg_get(hdd_ctx->psoc, CFG_DP_TX_FLOW_START_QUEUE_OFFSET); 14653 /* configuration for DP RX Threads */ 14654 cds_cfg->enable_dp_rx_threads = 14655 ucfg_dp_is_rx_threads_enabled(hdd_ctx->psoc); 14656 } 14657 #else 14658 static inline void hdd_txrx_populate_cds_config(struct cds_config_info 14659 *cds_cfg, 14660 struct hdd_context *hdd_ctx) 14661 { 14662 } 14663 #endif 14664 14665 /** 14666 * hdd_update_cds_config() - API to update cds configuration parameters 14667 * @hdd_ctx: HDD Context 14668 * 14669 * Return: 0 for Success, errno on failure 14670 */ 14671 static int hdd_update_cds_config(struct hdd_context *hdd_ctx) 14672 { 14673 struct cds_config_info *cds_cfg; 14674 int value; 14675 uint8_t band_capability; 14676 uint32_t band_bitmap; 14677 uint8_t ito_repeat_count; 14678 bool crash_inject; 14679 bool self_recovery; 14680 bool fw_timeout_crash; 14681 QDF_STATUS status; 14682 14683 cds_cfg = qdf_mem_malloc(sizeof(*cds_cfg)); 14684 if (!cds_cfg) 14685 return -ENOMEM; 14686 14687 cds_cfg->driver_type = QDF_DRIVER_TYPE_PRODUCTION; 14688 ucfg_mlme_get_sap_max_modulated_dtim(hdd_ctx->psoc, 14689 &cds_cfg->sta_maxlimod_dtim); 14690 14691 ucfg_mlme_get_max_modulated_dtim_ms(hdd_ctx->psoc, 14692 &cds_cfg->sta_maxlimod_dtim_ms); 14693 14694 status = ucfg_mlme_get_crash_inject(hdd_ctx->psoc, &crash_inject); 14695 if (QDF_IS_STATUS_ERROR(status)) { 14696 hdd_err("Failed to get crash inject ini config"); 14697 goto exit; 14698 } 14699 14700 status = ucfg_mlme_get_self_recovery(hdd_ctx->psoc, &self_recovery); 14701 if (QDF_IS_STATUS_ERROR(status)) { 14702 hdd_err("Failed to get self recovery ini config"); 14703 goto exit; 14704 } 14705 14706 status = ucfg_mlme_get_fw_timeout_crash(hdd_ctx->psoc, 14707 &fw_timeout_crash); 14708 if (QDF_IS_STATUS_ERROR(status)) { 14709 hdd_err("Failed to get fw timeout crash ini config"); 14710 goto exit; 14711 } 14712 14713 status = ucfg_mlme_get_ito_repeat_count(hdd_ctx->psoc, 14714 &ito_repeat_count); 14715 if (QDF_IS_STATUS_ERROR(status)) { 14716 hdd_err("Failed to get ITO repeat count ini config"); 14717 goto exit; 14718 } 14719 14720 cds_cfg->force_target_assert_enabled = crash_inject; 14721 14722 ucfg_mlme_get_sap_max_offload_peers(hdd_ctx->psoc, &value); 14723 cds_cfg->ap_maxoffload_peers = value; 14724 ucfg_mlme_get_sap_max_offload_reorder_buffs(hdd_ctx->psoc, 14725 &value); 14726 cds_cfg->ap_maxoffload_reorderbuffs = value; 14727 14728 cds_cfg->reorder_offload = DP_REORDER_OFFLOAD_SUPPORT; 14729 14730 /* IPA micro controller data path offload resource config item */ 14731 cds_cfg->uc_offload_enabled = ucfg_ipa_uc_is_enabled(); 14732 14733 cds_cfg->enable_rxthread = 14734 ucfg_dp_is_rx_common_thread_enabled(hdd_ctx->psoc); 14735 ucfg_mlme_get_sap_max_peers(hdd_ctx->psoc, &value); 14736 cds_cfg->max_station = value; 14737 cds_cfg->sub_20_channel_width = WLAN_SUB_20_CH_WIDTH_NONE; 14738 cds_cfg->max_msdus_per_rxinorderind = 14739 cfg_get(hdd_ctx->psoc, CFG_DP_MAX_MSDUS_PER_RXIND); 14740 cds_cfg->self_recovery_enabled = self_recovery; 14741 cds_cfg->fw_timeout_crash = fw_timeout_crash; 14742 14743 cds_cfg->ito_repeat_count = ito_repeat_count; 14744 14745 status = ucfg_mlme_get_band_capability(hdd_ctx->psoc, &band_bitmap); 14746 if (QDF_IS_STATUS_ERROR(status)) 14747 goto exit; 14748 14749 band_capability = wlan_reg_band_bitmap_to_band_info(band_bitmap); 14750 cds_cfg->bandcapability = band_capability; 14751 cds_cfg->num_vdevs = hdd_ctx->config->num_vdevs; 14752 cds_cfg->enable_tx_compl_tsf64 = 14753 hdd_tsf_is_tsf64_tx_set(hdd_ctx); 14754 hdd_txrx_populate_cds_config(cds_cfg, hdd_ctx); 14755 hdd_lpass_populate_cds_config(cds_cfg, hdd_ctx); 14756 cds_init_ini_config(cds_cfg); 14757 return 0; 14758 14759 exit: 14760 qdf_mem_free(cds_cfg); 14761 return -EINVAL; 14762 } 14763 14764 /** 14765 * hdd_update_user_config() - API to update user configuration 14766 * parameters to obj mgr which are used by multiple components 14767 * @hdd_ctx: HDD Context 14768 * 14769 * Return: 0 for Success, errno on failure 14770 */ 14771 static int hdd_update_user_config(struct hdd_context *hdd_ctx) 14772 { 14773 struct wlan_objmgr_psoc_user_config *user_config; 14774 uint8_t band_capability; 14775 uint32_t band_bitmap; 14776 QDF_STATUS status; 14777 bool value = false; 14778 14779 status = ucfg_mlme_get_band_capability(hdd_ctx->psoc, &band_bitmap); 14780 if (QDF_IS_STATUS_ERROR(status)) 14781 return -EIO; 14782 14783 user_config = qdf_mem_malloc(sizeof(*user_config)); 14784 if (!user_config) 14785 return -ENOMEM; 14786 14787 user_config->dot11_mode = hdd_ctx->config->dot11Mode; 14788 status = ucfg_mlme_is_11d_enabled(hdd_ctx->psoc, &value); 14789 if (!QDF_IS_STATUS_SUCCESS(status)) 14790 hdd_err("Invalid 11d_enable flag"); 14791 user_config->is_11d_support_enabled = value; 14792 14793 value = false; 14794 status = ucfg_mlme_is_11h_enabled(hdd_ctx->psoc, &value); 14795 if (!QDF_IS_STATUS_SUCCESS(status)) 14796 hdd_err("Invalid 11h_enable flag"); 14797 user_config->is_11h_support_enabled = value; 14798 band_capability = wlan_reg_band_bitmap_to_band_info(band_bitmap); 14799 user_config->band_capability = band_capability; 14800 wlan_objmgr_psoc_set_user_config(hdd_ctx->psoc, user_config); 14801 14802 qdf_mem_free(user_config); 14803 return 0; 14804 } 14805 14806 /** 14807 * hdd_init_thermal_info - Initialize thermal level 14808 * @hdd_ctx: HDD context 14809 * 14810 * Initialize thermal level at SME layer and set the thermal level callback 14811 * which would be called when a configured thermal threshold is hit. 14812 * 14813 * Return: 0 on success and errno on failure 14814 */ 14815 static int hdd_init_thermal_info(struct hdd_context *hdd_ctx) 14816 { 14817 QDF_STATUS status; 14818 mac_handle_t mac_handle = hdd_ctx->mac_handle; 14819 14820 status = sme_init_thermal_info(mac_handle); 14821 14822 if (!QDF_IS_STATUS_SUCCESS(status)) 14823 return qdf_status_to_os_return(status); 14824 14825 sme_add_set_thermal_level_callback(mac_handle, 14826 hdd_set_thermal_level_cb); 14827 14828 return 0; 14829 14830 } 14831 14832 #if defined(CONFIG_HDD_INIT_WITH_RTNL_LOCK) 14833 /** 14834 * hdd_hold_rtnl_lock - Hold RTNL lock 14835 * 14836 * Hold RTNL lock 14837 * 14838 * Return: True if held and false otherwise 14839 */ 14840 static inline bool hdd_hold_rtnl_lock(void) 14841 { 14842 rtnl_lock(); 14843 return true; 14844 } 14845 14846 /** 14847 * hdd_release_rtnl_lock - Release RTNL lock 14848 * 14849 * Release RTNL lock 14850 * 14851 * Return: None 14852 */ 14853 static inline void hdd_release_rtnl_lock(void) 14854 { 14855 rtnl_unlock(); 14856 } 14857 #else 14858 static inline bool hdd_hold_rtnl_lock(void) { return false; } 14859 static inline void hdd_release_rtnl_lock(void) { } 14860 #endif 14861 14862 #if !defined(REMOVE_PKT_LOG) 14863 14864 /* MAX iwpriv command support */ 14865 #define PKTLOG_SET_BUFF_SIZE 3 14866 #define PKTLOG_CLEAR_BUFF 4 14867 /* Set Maximum pktlog file size to 64MB */ 14868 #define MAX_PKTLOG_SIZE 64 14869 14870 /** 14871 * hdd_pktlog_set_buff_size() - set pktlog buffer size 14872 * @hdd_ctx: hdd context 14873 * @set_value2: pktlog buffer size value 14874 * 14875 * 14876 * Return: 0 for success or error. 14877 */ 14878 static int hdd_pktlog_set_buff_size(struct hdd_context *hdd_ctx, int set_value2) 14879 { 14880 struct sir_wifi_start_log start_log = { 0 }; 14881 QDF_STATUS status; 14882 14883 start_log.ring_id = RING_ID_PER_PACKET_STATS; 14884 start_log.verbose_level = WLAN_LOG_LEVEL_OFF; 14885 start_log.ini_triggered = cds_is_packet_log_enabled(); 14886 start_log.user_triggered = 1; 14887 start_log.size = set_value2; 14888 start_log.is_pktlog_buff_clear = false; 14889 14890 status = sme_wifi_start_logger(hdd_ctx->mac_handle, start_log); 14891 if (!QDF_IS_STATUS_SUCCESS(status)) { 14892 hdd_err("sme_wifi_start_logger failed(err=%d)", status); 14893 hdd_exit(); 14894 return -EINVAL; 14895 } 14896 14897 return 0; 14898 } 14899 14900 /** 14901 * hdd_pktlog_clear_buff() - clear pktlog buffer 14902 * @hdd_ctx: hdd context 14903 * 14904 * Return: 0 for success or error. 14905 */ 14906 static int hdd_pktlog_clear_buff(struct hdd_context *hdd_ctx) 14907 { 14908 struct sir_wifi_start_log start_log; 14909 QDF_STATUS status; 14910 14911 start_log.ring_id = RING_ID_PER_PACKET_STATS; 14912 start_log.verbose_level = WLAN_LOG_LEVEL_OFF; 14913 start_log.ini_triggered = cds_is_packet_log_enabled(); 14914 start_log.user_triggered = 1; 14915 start_log.size = 0; 14916 start_log.is_pktlog_buff_clear = true; 14917 14918 status = sme_wifi_start_logger(hdd_ctx->mac_handle, start_log); 14919 if (!QDF_IS_STATUS_SUCCESS(status)) { 14920 hdd_err("sme_wifi_start_logger failed(err=%d)", status); 14921 hdd_exit(); 14922 return -EINVAL; 14923 } 14924 14925 return 0; 14926 } 14927 14928 14929 /** 14930 * hdd_process_pktlog_command() - process pktlog command 14931 * @hdd_ctx: hdd context 14932 * @set_value: value set by user 14933 * @set_value2: pktlog buffer size value 14934 * 14935 * This function process pktlog command. 14936 * set_value2 only matters when set_value is 3 (set buff size) 14937 * otherwise we ignore it. 14938 * 14939 * Return: 0 for success or error. 14940 */ 14941 int hdd_process_pktlog_command(struct hdd_context *hdd_ctx, uint32_t set_value, 14942 int set_value2) 14943 { 14944 int ret; 14945 bool enable; 14946 uint8_t user_triggered = 0; 14947 14948 ret = wlan_hdd_validate_context(hdd_ctx); 14949 if (0 != ret) 14950 return ret; 14951 14952 hdd_debug("set pktlog %d, set size %d", set_value, set_value2); 14953 14954 if (set_value > PKTLOG_CLEAR_BUFF) { 14955 hdd_err("invalid pktlog value %d", set_value); 14956 return -EINVAL; 14957 } 14958 14959 if (set_value == PKTLOG_SET_BUFF_SIZE) { 14960 if (set_value2 <= 0) { 14961 hdd_err("invalid pktlog size %d", set_value2); 14962 return -EINVAL; 14963 } else if (set_value2 > MAX_PKTLOG_SIZE) { 14964 hdd_err_rl("Pktlog size is large. max value is %uMB.", 14965 MAX_PKTLOG_SIZE); 14966 return -EINVAL; 14967 } 14968 return hdd_pktlog_set_buff_size(hdd_ctx, set_value2); 14969 } else if (set_value == PKTLOG_CLEAR_BUFF) { 14970 return hdd_pktlog_clear_buff(hdd_ctx); 14971 } 14972 14973 /* 14974 * set_value = 0 then disable packetlog 14975 * set_value = 1 enable packetlog forcefully 14976 * set_value = 2 then disable packetlog if disabled through ini or 14977 * enable packetlog with AUTO type. 14978 */ 14979 enable = ((set_value > 0) && cds_is_packet_log_enabled()) ? 14980 true : false; 14981 14982 if (1 == set_value) { 14983 enable = true; 14984 user_triggered = 1; 14985 } 14986 14987 return hdd_pktlog_enable_disable(hdd_ctx, enable, user_triggered, 0); 14988 } 14989 14990 /** 14991 * hdd_pktlog_enable_disable() - Enable/Disable packet logging 14992 * @hdd_ctx: HDD context 14993 * @enable_disable_flag: Flag to enable/disable 14994 * @user_triggered: triggered through iwpriv 14995 * @size: buffer size to be used for packetlog 14996 * 14997 * Return: 0 on success; error number otherwise 14998 */ 14999 int hdd_pktlog_enable_disable(struct hdd_context *hdd_ctx, 15000 bool enable_disable_flag, 15001 uint8_t user_triggered, int size) 15002 { 15003 struct sir_wifi_start_log start_log; 15004 QDF_STATUS status; 15005 15006 if (hdd_ctx->is_pktlog_enabled && enable_disable_flag) 15007 return 0; 15008 15009 if ((!hdd_ctx->is_pktlog_enabled) && (!enable_disable_flag)) 15010 return 0; 15011 15012 start_log.ring_id = RING_ID_PER_PACKET_STATS; 15013 start_log.verbose_level = 15014 enable_disable_flag ? 15015 WLAN_LOG_LEVEL_ACTIVE : WLAN_LOG_LEVEL_OFF; 15016 start_log.ini_triggered = cds_is_packet_log_enabled(); 15017 start_log.user_triggered = user_triggered; 15018 start_log.size = size; 15019 start_log.is_pktlog_buff_clear = false; 15020 /* 15021 * Use "is_iwpriv_command" flag to distinguish iwpriv command from other 15022 * commands. Host uses this flag to decide whether to send pktlog 15023 * disable command to fw without sending pktlog enable command 15024 * previously. For eg, If vendor sends pktlog disable command without 15025 * sending pktlog enable command, then host discards the packet 15026 * but for iwpriv command, host will send it to fw. 15027 */ 15028 start_log.is_iwpriv_command = 1; 15029 15030 status = sme_wifi_start_logger(hdd_ctx->mac_handle, start_log); 15031 if (!QDF_IS_STATUS_SUCCESS(status)) { 15032 hdd_err("sme_wifi_start_logger failed(err=%d)", status); 15033 hdd_exit(); 15034 return -EINVAL; 15035 } 15036 15037 hdd_ctx->is_pktlog_enabled = enable_disable_flag; 15038 15039 return 0; 15040 } 15041 #endif /* REMOVE_PKT_LOG */ 15042 15043 void hdd_free_mac_address_lists(struct hdd_context *hdd_ctx) 15044 { 15045 hdd_debug("Resetting MAC address lists"); 15046 qdf_mem_zero(hdd_ctx->provisioned_mac_addr, 15047 sizeof(hdd_ctx->provisioned_mac_addr)); 15048 qdf_mem_zero(hdd_ctx->derived_mac_addr, 15049 sizeof(hdd_ctx->derived_mac_addr)); 15050 hdd_ctx->num_provisioned_addr = 0; 15051 hdd_ctx->num_derived_addr = 0; 15052 hdd_ctx->provisioned_intf_addr_mask = 0; 15053 hdd_ctx->derived_intf_addr_mask = 0; 15054 } 15055 15056 /** 15057 * hdd_get_platform_wlan_mac_buff() - API to query platform driver 15058 * for MAC address 15059 * @dev: Device Pointer 15060 * @num: Number of Valid Mac address 15061 * 15062 * Return: Pointer to MAC address buffer 15063 */ 15064 static uint8_t *hdd_get_platform_wlan_mac_buff(struct device *dev, 15065 uint32_t *num) 15066 { 15067 return pld_get_wlan_mac_address(dev, num); 15068 } 15069 15070 /** 15071 * hdd_get_platform_wlan_derived_mac_buff() - API to query platform driver 15072 * for derived MAC address 15073 * @dev: Device Pointer 15074 * @num: Number of Valid Mac address 15075 * 15076 * Return: Pointer to MAC address buffer 15077 */ 15078 static uint8_t *hdd_get_platform_wlan_derived_mac_buff(struct device *dev, 15079 uint32_t *num) 15080 { 15081 return pld_get_wlan_derived_mac_address(dev, num); 15082 } 15083 15084 /** 15085 * hdd_populate_random_mac_addr() - API to populate random mac addresses 15086 * @hdd_ctx: HDD Context 15087 * @num: Number of random mac addresses needed 15088 * 15089 * Generate random addresses using bit manipulation on the base mac address 15090 * 15091 * Return: None 15092 */ 15093 void hdd_populate_random_mac_addr(struct hdd_context *hdd_ctx, uint32_t num) 15094 { 15095 uint32_t idx = hdd_ctx->num_derived_addr; 15096 uint32_t iter; 15097 uint8_t *buf = NULL; 15098 uint8_t macaddr_b3, tmp_br3; 15099 /* 15100 * Consider first provisioned mac address as source address to derive 15101 * remaining addresses 15102 */ 15103 15104 uint8_t *src = hdd_ctx->provisioned_mac_addr[0].bytes; 15105 15106 for (iter = 0; iter < num; ++iter, ++idx) { 15107 buf = hdd_ctx->derived_mac_addr[idx].bytes; 15108 qdf_mem_copy(buf, src, QDF_MAC_ADDR_SIZE); 15109 macaddr_b3 = buf[3]; 15110 tmp_br3 = ((macaddr_b3 >> 4 & INTF_MACADDR_MASK) + idx) & 15111 INTF_MACADDR_MASK; 15112 macaddr_b3 += tmp_br3; 15113 macaddr_b3 ^= (1 << INTF_MACADDR_MASK); 15114 buf[0] |= 0x02; 15115 buf[3] = macaddr_b3; 15116 hdd_debug(QDF_MAC_ADDR_FMT, QDF_MAC_ADDR_REF(buf)); 15117 hdd_ctx->num_derived_addr++; 15118 } 15119 } 15120 15121 /** 15122 * hdd_platform_wlan_mac() - API to get mac addresses from platform driver 15123 * @hdd_ctx: HDD Context 15124 * 15125 * API to get mac addresses from platform driver and update the driver 15126 * structures and configure FW with the base mac address. 15127 * Return: int 15128 */ 15129 static int hdd_platform_wlan_mac(struct hdd_context *hdd_ctx) 15130 { 15131 uint32_t no_of_mac_addr, iter; 15132 uint32_t max_mac_addr = QDF_MAX_CONCURRENCY_PERSONA; 15133 uint32_t mac_addr_size = QDF_MAC_ADDR_SIZE; 15134 uint8_t *addr, *buf; 15135 struct device *dev = hdd_ctx->parent_dev; 15136 tSirMacAddr mac_addr; 15137 QDF_STATUS status; 15138 15139 addr = hdd_get_platform_wlan_mac_buff(dev, &no_of_mac_addr); 15140 15141 if (no_of_mac_addr == 0 || !addr) { 15142 hdd_debug("No mac configured from platform driver"); 15143 return -EINVAL; 15144 } 15145 15146 hdd_free_mac_address_lists(hdd_ctx); 15147 15148 if (no_of_mac_addr > max_mac_addr) 15149 no_of_mac_addr = max_mac_addr; 15150 15151 qdf_mem_copy(&mac_addr, addr, mac_addr_size); 15152 15153 for (iter = 0; iter < no_of_mac_addr; ++iter, addr += mac_addr_size) { 15154 buf = hdd_ctx->provisioned_mac_addr[iter].bytes; 15155 qdf_mem_copy(buf, addr, QDF_MAC_ADDR_SIZE); 15156 hdd_info("provisioned MAC Addr [%d] "QDF_MAC_ADDR_FMT, iter, 15157 QDF_MAC_ADDR_REF(buf)); 15158 } 15159 15160 hdd_ctx->num_provisioned_addr = no_of_mac_addr; 15161 15162 if (hdd_ctx->config->mac_provision) { 15163 addr = hdd_get_platform_wlan_derived_mac_buff(dev, 15164 &no_of_mac_addr); 15165 15166 if (no_of_mac_addr == 0 || !addr) 15167 hdd_warn("No derived address from platform driver"); 15168 else if (no_of_mac_addr > 15169 (max_mac_addr - hdd_ctx->num_provisioned_addr)) 15170 no_of_mac_addr = (max_mac_addr - 15171 hdd_ctx->num_provisioned_addr); 15172 15173 for (iter = 0; iter < no_of_mac_addr; ++iter, 15174 addr += mac_addr_size) { 15175 buf = hdd_ctx->derived_mac_addr[iter].bytes; 15176 qdf_mem_copy(buf, addr, QDF_MAC_ADDR_SIZE); 15177 hdd_debug("derived MAC Addr [%d] "QDF_MAC_ADDR_FMT, iter, 15178 QDF_MAC_ADDR_REF(buf)); 15179 } 15180 hdd_ctx->num_derived_addr = no_of_mac_addr; 15181 } 15182 15183 no_of_mac_addr = hdd_ctx->num_provisioned_addr + 15184 hdd_ctx->num_derived_addr; 15185 if (no_of_mac_addr < max_mac_addr) 15186 hdd_populate_random_mac_addr(hdd_ctx, max_mac_addr - 15187 no_of_mac_addr); 15188 15189 status = sme_set_custom_mac_addr(mac_addr); 15190 if (!QDF_IS_STATUS_SUCCESS(status)) 15191 return -EAGAIN; 15192 15193 return 0; 15194 } 15195 15196 /** 15197 * hdd_update_mac_addr_to_fw() - API to update wlan mac addresses to FW 15198 * @hdd_ctx: HDD Context 15199 * 15200 * Update MAC address to FW. If MAC address passed by FW is invalid, host 15201 * will generate its own MAC and update it to FW. 15202 * 15203 * Return: 0 for success 15204 * Non-zero error code for failure 15205 */ 15206 static int hdd_update_mac_addr_to_fw(struct hdd_context *hdd_ctx) 15207 { 15208 tSirMacAddr custom_mac_addr; 15209 QDF_STATUS status; 15210 15211 if (hdd_ctx->num_provisioned_addr) 15212 qdf_mem_copy(&custom_mac_addr, 15213 &hdd_ctx->provisioned_mac_addr[0].bytes[0], 15214 sizeof(tSirMacAddr)); 15215 else 15216 qdf_mem_copy(&custom_mac_addr, 15217 &hdd_ctx->derived_mac_addr[0].bytes[0], 15218 sizeof(tSirMacAddr)); 15219 status = sme_set_custom_mac_addr(custom_mac_addr); 15220 if (!QDF_IS_STATUS_SUCCESS(status)) 15221 return -EAGAIN; 15222 return 0; 15223 } 15224 15225 /** 15226 * hdd_initialize_mac_address() - API to get wlan mac addresses 15227 * @hdd_ctx: HDD Context 15228 * 15229 * Get MAC addresses from platform driver or wlan_mac.bin. If platform driver 15230 * is provisioned with mac addresses, driver uses it, else it will use 15231 * wlan_mac.bin to update HW MAC addresses. 15232 * 15233 * Return: None 15234 */ 15235 static int hdd_initialize_mac_address(struct hdd_context *hdd_ctx) 15236 { 15237 QDF_STATUS status; 15238 int ret; 15239 15240 ret = hdd_platform_wlan_mac(hdd_ctx); 15241 if (!ret) { 15242 hdd_info("using MAC address from platform driver"); 15243 return ret; 15244 } else if (hdd_ctx->config->mac_provision) { 15245 hdd_err("getting MAC address from platform driver failed"); 15246 return ret; 15247 } 15248 15249 status = hdd_update_mac_config(hdd_ctx); 15250 if (QDF_IS_STATUS_SUCCESS(status)) { 15251 hdd_info("using MAC address from wlan_mac.bin"); 15252 return 0; 15253 } 15254 15255 hdd_info("using default MAC address"); 15256 15257 /* Use fw provided MAC */ 15258 if (!qdf_is_macaddr_zero(&hdd_ctx->hw_macaddr)) { 15259 hdd_update_macaddr(hdd_ctx, hdd_ctx->hw_macaddr, false); 15260 return 0; 15261 } else if (hdd_generate_macaddr_auto(hdd_ctx) != 0) { 15262 struct qdf_mac_addr mac_addr; 15263 15264 hdd_err("MAC failure from device serial no."); 15265 qdf_get_random_bytes(&mac_addr, sizeof(mac_addr)); 15266 /* 15267 * Reset multicast bit (bit-0) and set 15268 * locally-administered bit 15269 */ 15270 mac_addr.bytes[0] = 0x2; 15271 hdd_update_macaddr(hdd_ctx, mac_addr, true); 15272 } 15273 15274 ret = hdd_update_mac_addr_to_fw(hdd_ctx); 15275 if (ret) 15276 hdd_err("MAC address out-of-sync, ret:%d", ret); 15277 return ret; 15278 } 15279 15280 /* params being sent: 15281 * wmi_pdev_param_tx_chain_mask_1ss 15282 * wmi_pdev_param_mgmt_retry_limit 15283 * wmi_pdev_param_default_6ghz_rate 15284 * wmi_pdev_param_pdev_stats_tx_xretry_ext 15285 * wmi_pdev_param_smart_chainmask_scheme 15286 * wmi_pdev_param_alternative_chainmask_scheme 15287 * wmi_pdev_param_ani_enable 15288 * wmi_pdev_param_pcie_config 15289 */ 15290 /** 15291 * hdd_pre_enable_configure() - Configurations prior to cds_enable 15292 * @hdd_ctx: HDD context 15293 * 15294 * Pre configurations to be done at lower layer before calling cds enable. 15295 * 15296 * Return: 0 on success and errno on failure. 15297 */ 15298 static int hdd_pre_enable_configure(struct hdd_context *hdd_ctx) 15299 { 15300 int ret; 15301 uint8_t val = 0; 15302 uint8_t max_retry = 0; 15303 bool enable_he_mcs0_for_6ghz_mgmt = false; 15304 uint32_t tx_retry_multiplier; 15305 QDF_STATUS status; 15306 void *soc = cds_get_context(QDF_MODULE_ID_SOC); 15307 struct dev_set_param setparam[MAX_PDEV_PRE_ENABLE_PARAMS] = {}; 15308 bool check_value; 15309 uint8_t index = 0; 15310 15311 cdp_register_pause_cb(soc, wlan_hdd_txrx_pause_cb); 15312 /* Register HL netdev flow control callback */ 15313 cdp_hl_fc_register(soc, OL_TXRX_PDEV_ID, wlan_hdd_txrx_pause_cb); 15314 /* Register rx mic error indication handler */ 15315 ucfg_dp_register_rx_mic_error_ind_handler(soc); 15316 15317 /* 15318 * Note that the cds_pre_enable() sequence triggers the cfg download. 15319 * The cfg download must occur before we update the SME config 15320 * since the SME config operation must access the cfg database 15321 */ 15322 status = hdd_set_sme_config(hdd_ctx); 15323 15324 if (QDF_STATUS_SUCCESS != status) { 15325 hdd_err("Failed hdd_set_sme_config: %d", status); 15326 ret = qdf_status_to_os_return(status); 15327 goto out; 15328 } 15329 15330 status = hdd_set_policy_mgr_user_cfg(hdd_ctx); 15331 if (QDF_STATUS_SUCCESS != status) { 15332 hdd_alert("Failed hdd_set_policy_mgr_user_cfg: %d", status); 15333 ret = qdf_status_to_os_return(status); 15334 goto out; 15335 } 15336 15337 status = ucfg_mlme_get_tx_chainmask_1ss(hdd_ctx->psoc, &val); 15338 if (QDF_STATUS_SUCCESS != status) { 15339 hdd_err("Get tx_chainmask_1ss from mlme failed"); 15340 ret = qdf_status_to_os_return(status); 15341 goto out; 15342 } 15343 ret = mlme_check_index_setparam(setparam, 15344 wmi_pdev_param_tx_chain_mask_1ss, 15345 val, index++, 15346 MAX_PDEV_PRE_ENABLE_PARAMS); 15347 if (QDF_IS_STATUS_ERROR(ret)) { 15348 hdd_err("failed at wmi_pdev_param_tx_chain_mask_1ss"); 15349 goto out; 15350 15351 } 15352 15353 wlan_mlme_get_mgmt_max_retry(hdd_ctx->psoc, &max_retry); 15354 ret = mlme_check_index_setparam(setparam, 15355 wmi_pdev_param_mgmt_retry_limit, 15356 max_retry, index++, 15357 MAX_PDEV_PRE_ENABLE_PARAMS); 15358 if (QDF_IS_STATUS_ERROR(ret)) { 15359 hdd_err("failed at wmi_pdev_param_mgmt_retry_limit"); 15360 goto out; 15361 } 15362 15363 wlan_mlme_get_mgmt_6ghz_rate_support(hdd_ctx->psoc, 15364 &enable_he_mcs0_for_6ghz_mgmt); 15365 if (enable_he_mcs0_for_6ghz_mgmt) { 15366 hdd_debug("HE rates for 6GHz mgmt frames are supported"); 15367 ret = mlme_check_index_setparam( 15368 setparam, 15369 wmi_pdev_param_default_6ghz_rate, 15370 MGMT_DEFAULT_DATA_RATE_6GHZ, index++, 15371 MAX_PDEV_PRE_ENABLE_PARAMS); 15372 if (QDF_IS_STATUS_ERROR(ret)) { 15373 hdd_err("wmi_pdev_param_default_6ghz_rate failed %d", 15374 ret); 15375 goto out; 15376 } 15377 } 15378 15379 wlan_mlme_get_tx_retry_multiplier(hdd_ctx->psoc, 15380 &tx_retry_multiplier); 15381 ret = mlme_check_index_setparam(setparam, 15382 wmi_pdev_param_pdev_stats_tx_xretry_ext, 15383 tx_retry_multiplier, index++, 15384 MAX_PDEV_PRE_ENABLE_PARAMS); 15385 if (QDF_IS_STATUS_ERROR(ret)) { 15386 hdd_err("failed at wmi_pdev_param_pdev_stats_tx_xretry_ext"); 15387 goto out; 15388 } 15389 15390 ret = ucfg_get_smart_chainmask_enabled(hdd_ctx->psoc, 15391 &check_value); 15392 if (QDF_IS_STATUS_SUCCESS(ret)) { 15393 ret = mlme_check_index_setparam( 15394 setparam, 15395 wmi_pdev_param_smart_chainmask_scheme, 15396 (int)check_value, index++, 15397 MAX_PDEV_PRE_ENABLE_PARAMS); 15398 if (QDF_IS_STATUS_ERROR(ret)) { 15399 hdd_err("failed to set wmi_pdev_param_smart_chainmask_scheme"); 15400 goto out; 15401 } 15402 } 15403 15404 ret = ucfg_get_alternative_chainmask_enabled(hdd_ctx->psoc, 15405 &check_value); 15406 if (QDF_IS_STATUS_SUCCESS(ret)) { 15407 ret = mlme_check_index_setparam( 15408 setparam, 15409 wmi_pdev_param_alternative_chainmask_scheme, 15410 (int)check_value, index++, 15411 MAX_PDEV_PRE_ENABLE_PARAMS); 15412 if (QDF_IS_STATUS_ERROR(ret)) { 15413 hdd_err("failed to set wmi_pdev_param_alternative_chainmask_scheme"); 15414 goto out; 15415 } 15416 } 15417 15418 ret = ucfg_fwol_get_ani_enabled(hdd_ctx->psoc, &check_value); 15419 if (QDF_IS_STATUS_SUCCESS(ret)) { 15420 ret = mlme_check_index_setparam(setparam, 15421 wmi_pdev_param_ani_enable, 15422 (int)check_value, index++, 15423 MAX_PDEV_PRE_ENABLE_PARAMS); 15424 if (QDF_IS_STATUS_ERROR(ret)) { 15425 hdd_err("failed to set wmi_pdev_param_ani_enable"); 15426 goto out; 15427 } 15428 } 15429 15430 ret = hdd_set_pcie_params(hdd_ctx, index, setparam); 15431 if (QDF_IS_STATUS_ERROR(ret)) 15432 goto out; 15433 else 15434 index++; 15435 ret = sme_send_multi_pdev_vdev_set_params(MLME_PDEV_SETPARAM, 15436 WMI_PDEV_ID_SOC, setparam, 15437 index); 15438 if (QDF_IS_STATUS_ERROR(ret)) { 15439 hdd_err("failed to send pdev set params"); 15440 goto out; 15441 } 15442 15443 /* Configure global firmware params */ 15444 ret = ucfg_fwol_configure_global_params(hdd_ctx->psoc, hdd_ctx->pdev); 15445 if (ret) 15446 goto out; 15447 15448 status = hdd_set_sme_chan_list(hdd_ctx); 15449 if (status != QDF_STATUS_SUCCESS) { 15450 hdd_err("Failed to init channel list: %d", status); 15451 ret = qdf_status_to_os_return(status); 15452 goto out; 15453 } 15454 15455 if (!hdd_update_config_cfg(hdd_ctx)) { 15456 hdd_err("config update failed"); 15457 ret = -EINVAL; 15458 goto out; 15459 } 15460 hdd_init_channel_avoidance(hdd_ctx); 15461 15462 out: 15463 return ret; 15464 } 15465 15466 #ifdef FEATURE_P2P_LISTEN_OFFLOAD 15467 /** 15468 * wlan_hdd_p2p_lo_event_callback - P2P listen offload stop event handler 15469 * @context: context registered with sme_register_p2p_lo_event(). HDD 15470 * always registers a hdd context pointer 15471 * @evt:event structure pointer 15472 * 15473 * This is the p2p listen offload stop event handler, it sends vendor 15474 * event back to supplicant to notify the stop reason. 15475 * 15476 * Return: None 15477 */ 15478 static void wlan_hdd_p2p_lo_event_callback(void *context, 15479 struct sir_p2p_lo_event *evt) 15480 { 15481 struct hdd_context *hdd_ctx = context; 15482 struct sk_buff *vendor_event; 15483 enum qca_nl80211_vendor_subcmds_index index = 15484 QCA_NL80211_VENDOR_SUBCMD_P2P_LO_EVENT_INDEX; 15485 struct wlan_hdd_link_info *link_info; 15486 15487 hdd_enter(); 15488 15489 if (!hdd_ctx) { 15490 hdd_err("Invalid HDD context pointer"); 15491 return; 15492 } 15493 15494 link_info = hdd_get_link_info_by_vdev(hdd_ctx, evt->vdev_id); 15495 if (!link_info) { 15496 hdd_err("Cannot find adapter by vdev_id = %d", 15497 evt->vdev_id); 15498 return; 15499 } 15500 15501 vendor_event = 15502 wlan_cfg80211_vendor_event_alloc(hdd_ctx->wiphy, 15503 &link_info->adapter->wdev, 15504 sizeof(uint32_t) + 15505 NLMSG_HDRLEN, 15506 index, GFP_KERNEL); 15507 if (!vendor_event) { 15508 hdd_err("wlan_cfg80211_vendor_event_alloc failed"); 15509 return; 15510 } 15511 15512 if (nla_put_u32(vendor_event, 15513 QCA_WLAN_VENDOR_ATTR_P2P_LISTEN_OFFLOAD_STOP_REASON, 15514 evt->reason_code)) { 15515 hdd_err("nla put failed"); 15516 wlan_cfg80211_vendor_free_skb(vendor_event); 15517 return; 15518 } 15519 15520 wlan_cfg80211_vendor_event(vendor_event, GFP_KERNEL); 15521 hdd_debug("Sent P2P_LISTEN_OFFLOAD_STOP event for vdev_id = %d", 15522 evt->vdev_id); 15523 } 15524 #else 15525 static void wlan_hdd_p2p_lo_event_callback(void *context, 15526 struct sir_p2p_lo_event *evt) 15527 { 15528 } 15529 #endif 15530 15531 #ifdef FEATURE_WLAN_DYNAMIC_CVM 15532 static inline int hdd_set_vc_mode_config(struct hdd_context *hdd_ctx) 15533 { 15534 return sme_set_vc_mode_config(hdd_ctx->config->vc_mode_cfg_bitmap); 15535 } 15536 #else 15537 static inline int hdd_set_vc_mode_config(struct hdd_context *hdd_ctx) 15538 { 15539 return QDF_STATUS_SUCCESS; 15540 } 15541 #endif 15542 15543 /** 15544 * hdd_adaptive_dwelltime_init() - initialization for adaptive dwell time config 15545 * @hdd_ctx: HDD context 15546 * 15547 * This function sends the adaptive dwell time config configuration to the 15548 * firmware via WMA 15549 * 15550 * Return: 0 - success, < 0 - failure 15551 */ 15552 static int hdd_adaptive_dwelltime_init(struct hdd_context *hdd_ctx) 15553 { 15554 QDF_STATUS status; 15555 struct adaptive_dwelltime_params dwelltime_params; 15556 15557 status = ucfg_fwol_get_all_adaptive_dwelltime_params(hdd_ctx->psoc, 15558 &dwelltime_params); 15559 status = ucfg_fwol_set_adaptive_dwelltime_config(&dwelltime_params); 15560 15561 hdd_debug("Sending Adaptive Dwelltime Configuration to fw"); 15562 if (!QDF_IS_STATUS_SUCCESS(status)) { 15563 hdd_err("Failed to send Adaptive Dwelltime configuration!"); 15564 return -EAGAIN; 15565 } 15566 return 0; 15567 } 15568 15569 int hdd_dbs_scan_selection_init(struct hdd_context *hdd_ctx) 15570 { 15571 QDF_STATUS status; 15572 struct wmi_dbs_scan_sel_params dbs_scan_params; 15573 uint32_t i = 0; 15574 uint8_t count = 0, numentries = 0; 15575 uint8_t dual_mac_feature; 15576 uint8_t dbs_scan_config[CDS_DBS_SCAN_PARAM_PER_CLIENT 15577 * CDS_DBS_SCAN_CLIENTS_MAX]; 15578 15579 status = ucfg_policy_mgr_get_dual_mac_feature(hdd_ctx->psoc, 15580 &dual_mac_feature); 15581 15582 if (status != QDF_STATUS_SUCCESS) { 15583 hdd_err("can't get dual mac feature flag"); 15584 return -EINVAL; 15585 } 15586 /* check if DBS is enabled or supported */ 15587 if ((dual_mac_feature == DISABLE_DBS_CXN_AND_SCAN) || 15588 (dual_mac_feature == ENABLE_DBS_CXN_AND_DISABLE_DBS_SCAN)) 15589 return -EINVAL; 15590 15591 hdd_string_to_u8_array(hdd_ctx->config->dbs_scan_selection, 15592 dbs_scan_config, &numentries, 15593 (CDS_DBS_SCAN_PARAM_PER_CLIENT 15594 * CDS_DBS_SCAN_CLIENTS_MAX)); 15595 15596 if (!numentries) { 15597 hdd_debug("Do not send scan_selection_config"); 15598 return 0; 15599 } 15600 15601 /* hdd_set_fw_log_params */ 15602 dbs_scan_params.num_clients = 0; 15603 while (count < (numentries - 2)) { 15604 dbs_scan_params.module_id[i] = dbs_scan_config[count]; 15605 dbs_scan_params.num_dbs_scans[i] = dbs_scan_config[count + 1]; 15606 dbs_scan_params.num_non_dbs_scans[i] = 15607 dbs_scan_config[count + 2]; 15608 dbs_scan_params.num_clients++; 15609 hdd_debug("module:%d NDS:%d NNDS:%d", 15610 dbs_scan_params.module_id[i], 15611 dbs_scan_params.num_dbs_scans[i], 15612 dbs_scan_params.num_non_dbs_scans[i]); 15613 count += CDS_DBS_SCAN_PARAM_PER_CLIENT; 15614 i++; 15615 } 15616 15617 dbs_scan_params.pdev_id = 0; 15618 15619 hdd_debug("clients:%d pdev:%d", 15620 dbs_scan_params.num_clients, dbs_scan_params.pdev_id); 15621 15622 status = sme_set_dbs_scan_selection_config(hdd_ctx->mac_handle, 15623 &dbs_scan_params); 15624 hdd_debug("Sending DBS Scan Selection Configuration to fw"); 15625 if (!QDF_IS_STATUS_SUCCESS(status)) { 15626 hdd_err("Failed to send DBS Scan selection configuration!"); 15627 return -EAGAIN; 15628 } 15629 return 0; 15630 } 15631 15632 #ifdef FEATURE_WLAN_AUTO_SHUTDOWN 15633 /** 15634 * hdd_set_auto_shutdown_cb() - Set auto shutdown callback 15635 * @hdd_ctx: HDD context 15636 * 15637 * Set auto shutdown callback to get indications from firmware to indicate 15638 * userspace to shutdown WLAN after a configured amount of inactivity. 15639 * 15640 * Return: 0 on success and errno on failure. 15641 */ 15642 static int hdd_set_auto_shutdown_cb(struct hdd_context *hdd_ctx) 15643 { 15644 QDF_STATUS status; 15645 15646 if (!hdd_ctx->config->wlan_auto_shutdown) 15647 return 0; 15648 15649 status = sme_set_auto_shutdown_cb(hdd_ctx->mac_handle, 15650 wlan_hdd_auto_shutdown_cb); 15651 if (status != QDF_STATUS_SUCCESS) 15652 hdd_err("Auto shutdown feature could not be enabled: %d", 15653 status); 15654 15655 return qdf_status_to_os_return(status); 15656 } 15657 #else 15658 static int hdd_set_auto_shutdown_cb(struct hdd_context *hdd_ctx) 15659 { 15660 return 0; 15661 } 15662 #endif 15663 15664 #ifdef MWS_COEX 15665 #define MAX_PDEV_MWSCOEX_PARAMS 4 15666 /* params being sent: 15667 * wmi_pdev_param_mwscoex_4g_allow_quick_ftdm 15668 * wmi_pdev_param_mwscoex_set_5gnr_pwr_limit 15669 * wmi_pdev_param_mwscoex_pcc_chavd_delay 15670 * wmi_pdev_param_mwscoex_scc_chavd_delay 15671 */ 15672 15673 /** 15674 * hdd_init_mws_coex() - Initialize MWS coex configurations 15675 * @hdd_ctx: HDD context 15676 * 15677 * This function sends MWS-COEX 4G quick FTDM and 15678 * MWS-COEX 5G-NR power limit to FW 15679 * 15680 * Return: 0 on success and errno on failure. 15681 */ 15682 static int hdd_init_mws_coex(struct hdd_context *hdd_ctx) 15683 { 15684 int ret = 0; 15685 uint32_t mws_coex_4g_quick_tdm = 0, mws_coex_5g_nr_pwr_limit = 0; 15686 uint32_t mws_coex_pcc_channel_avoid_delay = 0; 15687 uint32_t mws_coex_scc_channel_avoid_delay = 0; 15688 struct dev_set_param setparam[MAX_PDEV_MWSCOEX_PARAMS] = {}; 15689 uint8_t index = 0; 15690 15691 ucfg_mlme_get_mws_coex_4g_quick_tdm(hdd_ctx->psoc, 15692 &mws_coex_4g_quick_tdm); 15693 ret = mlme_check_index_setparam( 15694 setparam, 15695 wmi_pdev_param_mwscoex_4g_allow_quick_ftdm, 15696 mws_coex_4g_quick_tdm, index++, 15697 MAX_PDEV_MWSCOEX_PARAMS); 15698 if (QDF_IS_STATUS_ERROR(ret)) { 15699 hdd_err("failed at wmi_pdev_param_mwscoex_4g_allow_quick_ftdm"); 15700 goto error; 15701 } 15702 15703 ucfg_mlme_get_mws_coex_5g_nr_pwr_limit(hdd_ctx->psoc, 15704 &mws_coex_5g_nr_pwr_limit); 15705 ret = mlme_check_index_setparam( 15706 setparam, 15707 wmi_pdev_param_mwscoex_set_5gnr_pwr_limit, 15708 mws_coex_5g_nr_pwr_limit, index++, 15709 MAX_PDEV_MWSCOEX_PARAMS); 15710 if (QDF_IS_STATUS_ERROR(ret)) { 15711 hdd_err("failed at wmi_pdev_param_mwscoex_set_5gnr_pwr_limit"); 15712 goto error; 15713 } 15714 15715 ucfg_mlme_get_mws_coex_pcc_channel_avoid_delay( 15716 hdd_ctx->psoc, 15717 &mws_coex_pcc_channel_avoid_delay); 15718 ret = mlme_check_index_setparam(setparam, 15719 wmi_pdev_param_mwscoex_pcc_chavd_delay, 15720 mws_coex_pcc_channel_avoid_delay, 15721 index++, MAX_PDEV_MWSCOEX_PARAMS); 15722 if (QDF_IS_STATUS_ERROR(ret)) { 15723 hdd_err("failed at wmi_pdev_param_mwscoex_pcc_chavd_delay"); 15724 goto error; 15725 } 15726 15727 ucfg_mlme_get_mws_coex_scc_channel_avoid_delay( 15728 hdd_ctx->psoc, 15729 &mws_coex_scc_channel_avoid_delay); 15730 ret = mlme_check_index_setparam(setparam, 15731 wmi_pdev_param_mwscoex_scc_chavd_delay, 15732 mws_coex_scc_channel_avoid_delay, 15733 index++, MAX_PDEV_MWSCOEX_PARAMS); 15734 if (QDF_IS_STATUS_ERROR(ret)) { 15735 hdd_err("failed at wmi_pdev_param_mwscoex_scc_chavd_delay"); 15736 goto error; 15737 } 15738 ret = sme_send_multi_pdev_vdev_set_params(MLME_PDEV_SETPARAM, 15739 WMI_PDEV_ID_SOC, setparam, 15740 index); 15741 if (QDF_IS_STATUS_ERROR(ret)) 15742 hdd_err("failed to send pdev MWSCOEX set params"); 15743 error: 15744 return ret; 15745 } 15746 #else 15747 static int hdd_init_mws_coex(struct hdd_context *hdd_ctx) 15748 { 15749 return 0; 15750 } 15751 #endif 15752 15753 #ifdef THERMAL_STATS_SUPPORT 15754 static void hdd_thermal_stats_cmd_init(struct hdd_context *hdd_ctx) 15755 { 15756 hdd_send_get_thermal_stats_cmd(hdd_ctx, thermal_stats_init, NULL, NULL); 15757 } 15758 #else 15759 static void hdd_thermal_stats_cmd_init(struct hdd_context *hdd_ctx) 15760 { 15761 } 15762 #endif 15763 15764 #ifdef WLAN_FEATURE_CAL_FAILURE_TRIGGER 15765 /** 15766 * hdd_cal_fail_send_event()- send calibration failure information 15767 * @cal_type: calibration type 15768 * @reason: reason for calibration failure 15769 * 15770 * This Function sends calibration failure diag event 15771 * 15772 * Return: void. 15773 */ 15774 static void hdd_cal_fail_send_event(uint8_t cal_type, uint8_t reason) 15775 { 15776 /* 15777 * For now we are going with the print. Once CST APK has support to 15778 * read the diag events then we will add the diag event here. 15779 */ 15780 hdd_debug("Received cal failure event with cal_type:%x reason:%x", 15781 cal_type, reason); 15782 } 15783 #else 15784 static inline void hdd_cal_fail_send_event(uint8_t cal_type, uint8_t reason) 15785 { 15786 } 15787 #endif 15788 15789 /** 15790 * hdd_features_init() - Init features 15791 * @hdd_ctx: HDD context 15792 * 15793 * Initialize features and their feature context after WLAN firmware is up. 15794 * 15795 * Return: 0 on success and errno on failure. 15796 */ 15797 static int hdd_features_init(struct hdd_context *hdd_ctx) 15798 { 15799 struct tx_power_limit hddtxlimit; 15800 QDF_STATUS status; 15801 int ret; 15802 mac_handle_t mac_handle; 15803 bool b_cts2self, is_imps_enabled; 15804 bool rf_test_mode; 15805 bool std_6ghz_conn_policy; 15806 uint32_t fw_data_stall_evt; 15807 bool disable_vlp_sta_conn_sp_ap; 15808 15809 hdd_enter(); 15810 15811 ret = hdd_init_mws_coex(hdd_ctx); 15812 if (ret) 15813 hdd_warn("Error initializing mws-coex"); 15814 15815 /* FW capabilities received, Set the Dot11 mode */ 15816 mac_handle = hdd_ctx->mac_handle; 15817 sme_setdef_dot11mode(mac_handle); 15818 15819 ucfg_mlme_is_imps_enabled(hdd_ctx->psoc, &is_imps_enabled); 15820 hdd_set_idle_ps_config(hdd_ctx, is_imps_enabled); 15821 15822 fw_data_stall_evt = ucfg_dp_fw_data_stall_evt_enabled(); 15823 15824 /* Send Enable/Disable data stall detection cmd to FW */ 15825 sme_cli_set_command(0, wmi_pdev_param_data_stall_detect_enable, 15826 fw_data_stall_evt, PDEV_CMD); 15827 15828 ucfg_mlme_get_go_cts2self_for_sta(hdd_ctx->psoc, &b_cts2self); 15829 if (b_cts2self) 15830 sme_set_cts2self_for_p2p_go(mac_handle); 15831 15832 if (hdd_set_vc_mode_config(hdd_ctx)) 15833 hdd_warn("Error in setting Voltage Corner mode config to FW"); 15834 15835 if (ucfg_dp_rx_ol_init(hdd_ctx->psoc, hdd_ctx->is_wifi3_0_target)) 15836 hdd_err("Unable to initialize Rx LRO/GRO in fw"); 15837 15838 if (hdd_adaptive_dwelltime_init(hdd_ctx)) 15839 hdd_err("Unable to send adaptive dwelltime setting to FW"); 15840 15841 if (hdd_dbs_scan_selection_init(hdd_ctx)) 15842 hdd_err("Unable to send DBS scan selection setting to FW"); 15843 15844 ret = hdd_init_thermal_info(hdd_ctx); 15845 if (ret) { 15846 hdd_err("Error while initializing thermal information"); 15847 return ret; 15848 } 15849 15850 /** 15851 * In case of SSR/PDR, if pktlog was enabled manually before 15852 * SSR/PDR, then enable it again automatically after Wlan 15853 * device up. 15854 * During SSR/PDR, pktlog will be disabled as part of 15855 * hdd_features_deinit if pktlog is enabled in ini. 15856 * Re-enable pktlog in SSR case, if pktlog is enabled in ini. 15857 */ 15858 if (hdd_get_conparam() != QDF_GLOBAL_MONITOR_MODE && 15859 (cds_is_packet_log_enabled() || 15860 (cds_is_driver_recovering() && hdd_ctx->is_pktlog_enabled))) 15861 hdd_pktlog_enable_disable(hdd_ctx, true, 0, 0); 15862 15863 hddtxlimit.txPower2g = ucfg_get_tx_power(hdd_ctx->psoc, BAND_2G); 15864 hddtxlimit.txPower5g = ucfg_get_tx_power(hdd_ctx->psoc, BAND_5G); 15865 status = sme_txpower_limit(mac_handle, &hddtxlimit); 15866 if (!QDF_IS_STATUS_SUCCESS(status)) 15867 hdd_err("Error setting txlimit in sme: %d", status); 15868 15869 wlan_hdd_tsf_init(hdd_ctx); 15870 15871 status = sme_enable_disable_chanavoidind_event(mac_handle, 0); 15872 if (QDF_IS_STATUS_ERROR(status) && (status != QDF_STATUS_E_NOSUPPORT)) { 15873 hdd_err("Failed to disable Chan Avoidance Indication"); 15874 return -EINVAL; 15875 } 15876 15877 /* register P2P Listen Offload event callback */ 15878 if (wma_is_p2p_lo_capable()) 15879 sme_register_p2p_lo_event(mac_handle, hdd_ctx, 15880 wlan_hdd_p2p_lo_event_callback); 15881 wlan_hdd_register_mcc_quota_event_callback(hdd_ctx); 15882 ret = hdd_set_auto_shutdown_cb(hdd_ctx); 15883 15884 if (ret) 15885 return -EINVAL; 15886 15887 wlan_hdd_init_chan_info(hdd_ctx); 15888 wlan_hdd_twt_init(hdd_ctx); 15889 wlan_hdd_gpio_wakeup_init(hdd_ctx); 15890 15891 status = ucfg_mlme_is_rf_test_mode_enabled(hdd_ctx->psoc, 15892 &rf_test_mode); 15893 if (!QDF_IS_STATUS_SUCCESS(status)) { 15894 hdd_err("Get rf test mode failed"); 15895 return QDF_STATUS_E_FAILURE; 15896 } 15897 15898 if (rf_test_mode) { 15899 wlan_cm_set_check_6ghz_security(hdd_ctx->psoc, false); 15900 wlan_cm_set_6ghz_key_mgmt_mask(hdd_ctx->psoc, 15901 DEFAULT_KEYMGMT_6G_MASK); 15902 } 15903 15904 status = ucfg_mlme_is_standard_6ghz_conn_policy_enabled(hdd_ctx->psoc, 15905 &std_6ghz_conn_policy); 15906 15907 if (!QDF_IS_STATUS_SUCCESS(status)) { 15908 hdd_err("Get 6ghz standard connection policy failed"); 15909 return QDF_STATUS_E_FAILURE; 15910 } 15911 if (std_6ghz_conn_policy) 15912 wlan_cm_set_standard_6ghz_conn_policy(hdd_ctx->psoc, true); 15913 15914 status = ucfg_mlme_is_disable_vlp_sta_conn_to_sp_ap_enabled( 15915 hdd_ctx->psoc, 15916 &disable_vlp_sta_conn_sp_ap); 15917 if (!QDF_IS_STATUS_SUCCESS(status)) { 15918 hdd_err("Get disable vlp sta conn to sp flag failed"); 15919 return QDF_STATUS_E_FAILURE; 15920 } 15921 15922 if (disable_vlp_sta_conn_sp_ap) 15923 wlan_cm_set_disable_vlp_sta_conn_to_sp_ap(hdd_ctx->psoc, true); 15924 15925 hdd_thermal_stats_cmd_init(hdd_ctx); 15926 sme_set_cal_failure_event_cb(hdd_ctx->mac_handle, 15927 hdd_cal_fail_send_event); 15928 15929 hdd_exit(); 15930 return 0; 15931 } 15932 15933 /** 15934 * hdd_register_bcn_cb() - register scan beacon callback 15935 * @hdd_ctx: Pointer to the HDD context 15936 * 15937 * Return: QDF_STATUS 15938 */ 15939 static inline QDF_STATUS hdd_register_bcn_cb(struct hdd_context *hdd_ctx) 15940 { 15941 QDF_STATUS status; 15942 15943 status = ucfg_scan_register_bcn_cb(hdd_ctx->psoc, 15944 wlan_cfg80211_inform_bss_frame, 15945 SCAN_CB_TYPE_INFORM_BCN); 15946 if (!QDF_IS_STATUS_SUCCESS(status)) { 15947 hdd_err("failed to register SCAN_CB_TYPE_INFORM_BCN with status code %08d [x%08x]", 15948 status, status); 15949 return status; 15950 } 15951 15952 status = ucfg_scan_register_bcn_cb(hdd_ctx->psoc, 15953 wlan_cfg80211_unlink_bss_list, 15954 SCAN_CB_TYPE_UNLINK_BSS); 15955 if (!QDF_IS_STATUS_SUCCESS(status)) { 15956 hdd_err("failed to refister SCAN_CB_TYPE_FLUSH_BSS with status code %08d [x%08x]", 15957 status, status); 15958 return status; 15959 } 15960 15961 return QDF_STATUS_SUCCESS; 15962 } 15963 15964 /** 15965 * hdd_v2_flow_pool_map() - Flow pool create callback when vdev is active 15966 * @vdev_id: vdev_id, corresponds to flow_pool 15967 * 15968 * Return: none. 15969 */ 15970 static void hdd_v2_flow_pool_map(int vdev_id) 15971 { 15972 QDF_STATUS status; 15973 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 15974 struct wlan_objmgr_vdev *vdev; 15975 15976 if (!hdd_ctx) { 15977 hdd_err("HDD context null"); 15978 return; 15979 } 15980 15981 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(hdd_ctx->psoc, vdev_id, 15982 WLAN_OSIF_ID); 15983 if (!vdev) { 15984 hdd_err("Invalid VDEV %d", vdev_id); 15985 return; 15986 } 15987 15988 if (wlan_vdev_mlme_is_mlo_link_switch_in_progress(vdev)) { 15989 hdd_info("Link switch ongoing, do not invoke flow pool map"); 15990 goto release_ref; 15991 } 15992 15993 status = cdp_flow_pool_map(cds_get_context(QDF_MODULE_ID_SOC), 15994 OL_TXRX_PDEV_ID, vdev_id); 15995 /* 15996 * For Adrastea flow control v2 is based on FW MAP events, 15997 * so this above callback is not implemented. 15998 * Hence this is not actual failure. Dont return failure 15999 */ 16000 if ((status != QDF_STATUS_SUCCESS) && 16001 (status != QDF_STATUS_E_INVAL)) { 16002 hdd_err("vdev_id: %d, failed to create flow pool status %d", 16003 vdev_id, status); 16004 } 16005 16006 release_ref: 16007 wlan_objmgr_vdev_release_ref(vdev, WLAN_OSIF_ID); 16008 } 16009 16010 /** 16011 * hdd_v2_flow_pool_unmap() - Flow pool create callback when vdev is not active 16012 * @vdev_id: vdev_id, corresponds to flow_pool 16013 * 16014 * Return: none. 16015 */ 16016 static void hdd_v2_flow_pool_unmap(int vdev_id) 16017 { 16018 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 16019 struct wlan_objmgr_vdev *vdev; 16020 16021 if (!hdd_ctx) { 16022 hdd_err("HDD context null"); 16023 return; 16024 } 16025 16026 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(hdd_ctx->psoc, vdev_id, 16027 WLAN_OSIF_ID); 16028 if (!vdev) { 16029 hdd_err("Invalid VDEV %d", vdev_id); 16030 return; 16031 } 16032 16033 if (wlan_vdev_mlme_is_mlo_link_switch_in_progress(vdev)) { 16034 hdd_info("Link switch ongoing do not invoke flow pool unmap"); 16035 goto release_ref; 16036 } 16037 16038 cdp_flow_pool_unmap(cds_get_context(QDF_MODULE_ID_SOC), 16039 OL_TXRX_PDEV_ID, vdev_id); 16040 release_ref: 16041 wlan_objmgr_vdev_release_ref(vdev, WLAN_OSIF_ID); 16042 } 16043 16044 static void hdd_hastings_bt_war_initialize(struct hdd_context *hdd_ctx) 16045 { 16046 if (hdd_ctx->config->iface_change_wait_time) 16047 hdd_hastings_bt_war_disable_fw(hdd_ctx); 16048 else 16049 hdd_hastings_bt_war_enable_fw(hdd_ctx); 16050 } 16051 16052 #define MAX_PDEV_CFG_CDS_PARAMS 8 16053 /* params being sent: 16054 * wmi_pdev_param_set_iot_pattern 16055 * wmi_pdev_param_max_mpdus_in_ampdu 16056 * wmi_pdev_param_enable_rts_sifs_bursting 16057 * wmi_pdev_param_peer_stats_info_enable 16058 * wmi_pdev_param_abg_mode_tx_chain_num 16059 * wmi_pdev_param_gcmp_support_enable 16060 * wmi_pdev_auto_detect_power_failure 16061 * wmi_pdev_param_fast_pwr_transition 16062 */ 16063 16064 /** 16065 * hdd_configure_cds() - Configure cds modules 16066 * @hdd_ctx: HDD context 16067 * 16068 * Enable Cds modules after WLAN firmware is up. 16069 * 16070 * Return: 0 on success and errno on failure. 16071 */ 16072 int hdd_configure_cds(struct hdd_context *hdd_ctx) 16073 { 16074 int ret; 16075 QDF_STATUS status; 16076 int set_value; 16077 mac_handle_t mac_handle; 16078 bool enable_rts_sifsbursting; 16079 uint8_t enable_phy_reg_retention; 16080 uint8_t max_mpdus_inampdu, is_force_1x1 = 0; 16081 uint32_t num_abg_tx_chains = 0; 16082 uint16_t num_11b_tx_chains = 0; 16083 uint16_t num_11ag_tx_chains = 0; 16084 struct policy_mgr_dp_cbacks dp_cbs = {0}; 16085 bool value; 16086 enum pmo_auto_pwr_detect_failure_mode auto_power_fail_mode; 16087 bool bval = false; 16088 uint8_t max_index = MAX_PDEV_CFG_CDS_PARAMS; 16089 struct dev_set_param setparam[MAX_PDEV_CFG_CDS_PARAMS] = {}; 16090 uint8_t index = 0; 16091 uint8_t next_index = 0; 16092 mac_handle = hdd_ctx->mac_handle; 16093 16094 status = ucfg_policy_mgr_get_force_1x1(hdd_ctx->psoc, &is_force_1x1); 16095 if (status != QDF_STATUS_SUCCESS) { 16096 hdd_err("Failed to get force 1x1 value"); 16097 goto out; 16098 } 16099 if (is_force_1x1) { 16100 status = mlme_check_index_setparam( 16101 setparam, 16102 wmi_pdev_param_set_iot_pattern, 16103 1, index++, 16104 max_index); 16105 if (QDF_IS_STATUS_ERROR(status)) { 16106 hdd_err("failed at wmi_pdev_param_set_iot_pattern"); 16107 goto out; 16108 } 16109 } 16110 /* set chip power save failure detected callback */ 16111 sme_set_chip_pwr_save_fail_cb(mac_handle, 16112 hdd_chip_pwr_save_fail_detected_cb); 16113 16114 status = ucfg_get_max_mpdus_inampdu(hdd_ctx->psoc, 16115 &max_mpdus_inampdu); 16116 if (status) { 16117 hdd_err("Failed to get max mpdus in ampdu value"); 16118 goto out; 16119 } 16120 16121 if (max_mpdus_inampdu) { 16122 set_value = max_mpdus_inampdu; 16123 status = mlme_check_index_setparam( 16124 setparam, 16125 wmi_pdev_param_max_mpdus_in_ampdu, 16126 set_value, index++, 16127 max_index); 16128 if (QDF_IS_STATUS_ERROR(status)) { 16129 hdd_err("failed at wmi_pdev_param_max_mpdus_in_ampdu"); 16130 goto out; 16131 } 16132 } 16133 16134 status = ucfg_get_enable_rts_sifsbursting(hdd_ctx->psoc, 16135 &enable_rts_sifsbursting); 16136 if (status) { 16137 hdd_err("Failed to get rts sifs bursting value"); 16138 goto out; 16139 } 16140 16141 if (enable_rts_sifsbursting) { 16142 set_value = enable_rts_sifsbursting; 16143 status = mlme_check_index_setparam( 16144 setparam, 16145 wmi_pdev_param_enable_rts_sifs_bursting, 16146 set_value, index++, 16147 max_index); 16148 if (QDF_IS_STATUS_ERROR(status)) { 16149 hdd_err("Failed at wmi_pdev_param_enable_rts_sifs_bursting"); 16150 goto out; 16151 } 16152 } 16153 16154 ucfg_mlme_get_sap_get_peer_info(hdd_ctx->psoc, &value); 16155 if (value) { 16156 set_value = value; 16157 status = mlme_check_index_setparam( 16158 setparam, 16159 wmi_pdev_param_peer_stats_info_enable, 16160 set_value, index++, 16161 max_index); 16162 if (QDF_IS_STATUS_ERROR(status)) { 16163 hdd_err("Failed at wmi_pdev_param_peer_stats_info_enable"); 16164 goto out; 16165 } 16166 } 16167 16168 status = ucfg_mlme_get_num_11b_tx_chains(hdd_ctx->psoc, 16169 &num_11b_tx_chains); 16170 if (status != QDF_STATUS_SUCCESS) { 16171 hdd_err("Failed to get num_11b_tx_chains"); 16172 goto out; 16173 } 16174 16175 status = ucfg_mlme_get_num_11ag_tx_chains(hdd_ctx->psoc, 16176 &num_11ag_tx_chains); 16177 if (status != QDF_STATUS_SUCCESS) { 16178 hdd_err("Failed to get num_11ag_tx_chains"); 16179 goto out; 16180 } 16181 16182 status = ucfg_mlme_get_vht_enable2x2(hdd_ctx->psoc, &bval); 16183 if (!QDF_IS_STATUS_SUCCESS(status)) 16184 hdd_err("unable to get vht_enable2x2"); 16185 16186 if (!bval) { 16187 if (num_11b_tx_chains > 1) 16188 num_11b_tx_chains = 1; 16189 if (num_11ag_tx_chains > 1) 16190 num_11ag_tx_chains = 1; 16191 } 16192 WMI_PDEV_PARAM_SET_11B_TX_CHAIN_NUM(num_abg_tx_chains, 16193 num_11b_tx_chains); 16194 WMI_PDEV_PARAM_SET_11AG_TX_CHAIN_NUM(num_abg_tx_chains, 16195 num_11ag_tx_chains); 16196 status = mlme_check_index_setparam(setparam, 16197 wmi_pdev_param_abg_mode_tx_chain_num, 16198 num_abg_tx_chains, index++, 16199 max_index); 16200 if (QDF_IS_STATUS_ERROR(status)) { 16201 hdd_err("Failed at wmi_pdev_param_abg_mode_tx_chain_num"); 16202 goto out; 16203 } 16204 /* Send some pdev params to maintain legacy order of pdev set params 16205 * at hdd_pre_enable_configure 16206 */ 16207 status = sme_send_multi_pdev_vdev_set_params(MLME_PDEV_SETPARAM, 16208 WMI_PDEV_ID_SOC, setparam, 16209 index); 16210 if (QDF_IS_STATUS_ERROR(status)) { 16211 hdd_err("Failed to send 1st set of pdev params"); 16212 goto out; 16213 } 16214 if (!ucfg_reg_is_regdb_offloaded(hdd_ctx->psoc)) 16215 ucfg_reg_program_default_cc(hdd_ctx->pdev, 16216 hdd_ctx->reg.reg_domain); 16217 16218 ret = hdd_pre_enable_configure(hdd_ctx); 16219 if (ret) { 16220 hdd_err("Failed to pre-configure cds"); 16221 goto out; 16222 } 16223 16224 /* Always get latest IPA resources allocated from cds_open and configure 16225 * IPA module before configuring them to FW. Sequence required as crash 16226 * observed otherwise. 16227 */ 16228 16229 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) { 16230 ipa_disable_register_cb(); 16231 } else { 16232 status = ipa_register_is_ipa_ready(hdd_ctx->pdev); 16233 if (!QDF_IS_STATUS_SUCCESS(status)) { 16234 hdd_err("ipa_register_is_ipa_ready failed"); 16235 goto out; 16236 } 16237 } 16238 16239 /* 16240 * Start CDS which starts up the SME/MAC/HAL modules and everything 16241 * else 16242 */ 16243 status = cds_enable(hdd_ctx->psoc); 16244 16245 if (!QDF_IS_STATUS_SUCCESS(status)) { 16246 hdd_err("cds_enable failed"); 16247 goto out; 16248 } 16249 16250 status = hdd_post_cds_enable_config(hdd_ctx); 16251 if (!QDF_IS_STATUS_SUCCESS(status)) { 16252 hdd_err("hdd_post_cds_enable_config failed"); 16253 goto cds_disable; 16254 } 16255 status = hdd_register_bcn_cb(hdd_ctx); 16256 if (!QDF_IS_STATUS_SUCCESS(status)) { 16257 hdd_err("hdd_register_bcn_cb failed"); 16258 goto cds_disable; 16259 } 16260 16261 ret = hdd_features_init(hdd_ctx); 16262 if (ret) 16263 goto cds_disable; 16264 16265 /* 16266 * Donot disable rx offload on concurrency for lithium and 16267 * beryllium based targets 16268 */ 16269 if (!hdd_ctx->is_wifi3_0_target) 16270 if (ucfg_dp_is_ol_enabled(hdd_ctx->psoc)) 16271 dp_cbs.hdd_disable_rx_ol_in_concurrency = 16272 hdd_disable_rx_ol_in_concurrency; 16273 dp_cbs.hdd_set_rx_mode_rps_cb = ucfg_dp_set_rx_mode_rps; 16274 dp_cbs.hdd_ipa_set_mcc_mode_cb = hdd_ipa_set_mcc_mode; 16275 dp_cbs.hdd_v2_flow_pool_map = hdd_v2_flow_pool_map; 16276 dp_cbs.hdd_v2_flow_pool_unmap = hdd_v2_flow_pool_unmap; 16277 status = policy_mgr_register_dp_cb(hdd_ctx->psoc, &dp_cbs); 16278 if (!QDF_IS_STATUS_SUCCESS(status)) { 16279 hdd_debug("Failed to register DP cb with Policy Manager"); 16280 goto cds_disable; 16281 } 16282 status = policy_mgr_register_mode_change_cb(hdd_ctx->psoc, 16283 wlan_hdd_send_mode_change_event); 16284 if (!QDF_IS_STATUS_SUCCESS(status)) { 16285 hdd_debug("Failed to register mode change cb with Policy Manager"); 16286 goto cds_disable; 16287 } 16288 16289 if (hdd_green_ap_enable_egap(hdd_ctx)) 16290 hdd_debug("enhance green ap is not enabled"); 16291 16292 hdd_register_green_ap_callback(hdd_ctx->pdev); 16293 16294 if (0 != wlan_hdd_set_wow_pulse(hdd_ctx, true)) 16295 hdd_debug("Failed to set wow pulse"); 16296 16297 max_index = max_index - index; 16298 status = mlme_check_index_setparam( 16299 setparam + index, 16300 wmi_pdev_param_gcmp_support_enable, 16301 ucfg_fwol_get_gcmp_enable(hdd_ctx->psoc), 16302 next_index++, max_index); 16303 if (QDF_IS_STATUS_ERROR(status)) { 16304 hdd_err("failed at wmi_pdev_param_gcmp_support_enable"); 16305 goto out; 16306 } 16307 16308 auto_power_fail_mode = 16309 ucfg_pmo_get_auto_power_fail_mode(hdd_ctx->psoc); 16310 status = mlme_check_index_setparam( 16311 setparam + index, 16312 wmi_pdev_auto_detect_power_failure, 16313 auto_power_fail_mode, 16314 next_index++, max_index); 16315 if (QDF_IS_STATUS_ERROR(status)) { 16316 hdd_err("failed at wmi_pdev_auto_detect_power_failure"); 16317 goto out; 16318 } 16319 16320 status = ucfg_get_enable_phy_reg_retention(hdd_ctx->psoc, 16321 &enable_phy_reg_retention); 16322 16323 if (QDF_IS_STATUS_ERROR(status)) 16324 return -EINVAL; 16325 16326 if (enable_phy_reg_retention) { 16327 status = mlme_check_index_setparam( 16328 setparam + index, 16329 wmi_pdev_param_fast_pwr_transition, 16330 enable_phy_reg_retention, 16331 next_index++, max_index); 16332 if (QDF_IS_STATUS_ERROR(status)) { 16333 hdd_err("failed at wmi_pdev_param_fast_pwr_transition"); 16334 goto out; 16335 } 16336 } 16337 /*Send remaining pdev setparams from array*/ 16338 status = sme_send_multi_pdev_vdev_set_params(MLME_PDEV_SETPARAM, 16339 WMI_PDEV_ID_SOC, 16340 setparam + index, 16341 next_index); 16342 if (QDF_IS_STATUS_ERROR(status)) { 16343 hdd_err("failed to send 2nd set of pdev set params"); 16344 goto out; 16345 } 16346 16347 hdd_hastings_bt_war_initialize(hdd_ctx); 16348 16349 wlan_hdd_hang_event_notifier_register(hdd_ctx); 16350 return 0; 16351 16352 cds_disable: 16353 cds_disable(hdd_ctx->psoc); 16354 16355 out: 16356 return -EINVAL; 16357 } 16358 16359 #ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH 16360 static void hdd_deregister_policy_manager_callback( 16361 struct wlan_objmgr_psoc *psoc) 16362 { 16363 if (QDF_STATUS_SUCCESS != 16364 policy_mgr_deregister_hdd_cb(psoc)) { 16365 hdd_err("HDD callback deregister with policy manager failed"); 16366 } 16367 } 16368 #else 16369 static void hdd_deregister_policy_manager_callback( 16370 struct wlan_objmgr_psoc *psoc) 16371 { 16372 } 16373 #endif 16374 16375 int hdd_wlan_stop_modules(struct hdd_context *hdd_ctx, bool ftm_mode) 16376 { 16377 void *hif_ctx; 16378 qdf_device_t qdf_ctx; 16379 QDF_STATUS qdf_status; 16380 bool is_recovery_stop = cds_is_driver_recovering(); 16381 int ret = 0; 16382 int debugfs_threads; 16383 struct target_psoc_info *tgt_hdl; 16384 struct bbm_params param = {0}; 16385 16386 hdd_enter(); 16387 qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE); 16388 if (!qdf_ctx) 16389 return -EINVAL; 16390 16391 cds_set_driver_state_module_stop(true); 16392 16393 debugfs_threads = hdd_return_debugfs_threads_count(); 16394 16395 if (debugfs_threads > 0 || hdd_ctx->is_wiphy_suspended) { 16396 hdd_warn("Debugfs threads %d, wiphy suspend %d", 16397 debugfs_threads, hdd_ctx->is_wiphy_suspended); 16398 16399 if (IS_IDLE_STOP && !ftm_mode) { 16400 hdd_psoc_idle_timer_start(hdd_ctx); 16401 cds_set_driver_state_module_stop(false); 16402 16403 ucfg_dp_bus_bw_compute_timer_stop(hdd_ctx->psoc); 16404 return -EAGAIN; 16405 } 16406 } 16407 16408 ucfg_dp_bus_bw_compute_timer_stop(hdd_ctx->psoc); 16409 hdd_deregister_policy_manager_callback(hdd_ctx->psoc); 16410 16411 /* free user wowl patterns */ 16412 hdd_free_user_wowl_ptrns(); 16413 16414 switch (hdd_ctx->driver_status) { 16415 case DRIVER_MODULES_UNINITIALIZED: 16416 hdd_debug("Modules not initialized just return"); 16417 goto done; 16418 case DRIVER_MODULES_CLOSED: 16419 hdd_debug("Modules already closed"); 16420 goto done; 16421 case DRIVER_MODULES_ENABLED: 16422 hdd_debug("Wlan transitioning (CLOSED <- ENABLED)"); 16423 16424 if (hdd_get_conparam() == QDF_GLOBAL_FTM_MODE) { 16425 hdd_disable_power_management(hdd_ctx); 16426 break; 16427 } 16428 16429 if (hdd_get_conparam() == QDF_GLOBAL_EPPING_MODE) 16430 break; 16431 16432 hdd_skip_acs_scan_timer_deinit(hdd_ctx); 16433 16434 hdd_disable_power_management(hdd_ctx); 16435 16436 if (hdd_get_conparam() == QDF_GLOBAL_MISSION_MODE) 16437 ucfg_dp_direct_link_deinit(hdd_ctx->psoc, 16438 is_recovery_stop); 16439 16440 if (hdd_deconfigure_cds(hdd_ctx)) { 16441 hdd_err("Failed to de-configure CDS"); 16442 QDF_ASSERT(0); 16443 ret = -EINVAL; 16444 } 16445 hdd_debug("successfully Disabled the CDS modules!"); 16446 16447 break; 16448 default: 16449 QDF_DEBUG_PANIC("Unknown driver state:%d", 16450 hdd_ctx->driver_status); 16451 ret = -EINVAL; 16452 goto done; 16453 } 16454 16455 hdd_destroy_sysfs_files(); 16456 hdd_debug("Closing CDS modules!"); 16457 16458 if (hdd_get_conparam() != QDF_GLOBAL_EPPING_MODE) { 16459 qdf_status = cds_post_disable(); 16460 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { 16461 hdd_err("Failed to process post CDS disable! :%d", 16462 qdf_status); 16463 ret = -EINVAL; 16464 QDF_ASSERT(0); 16465 } 16466 16467 hdd_unregister_notifiers(hdd_ctx); 16468 /* De-register the SME callbacks */ 16469 hdd_deregister_cb(hdd_ctx); 16470 16471 hdd_runtime_suspend_context_deinit(hdd_ctx); 16472 16473 qdf_status = cds_dp_close(hdd_ctx->psoc); 16474 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { 16475 hdd_warn("Failed to stop CDS DP: %d", qdf_status); 16476 ret = -EINVAL; 16477 QDF_ASSERT(0); 16478 } 16479 16480 hdd_component_pdev_close(hdd_ctx->pdev); 16481 dispatcher_pdev_close(hdd_ctx->pdev); 16482 ret = hdd_objmgr_release_and_destroy_pdev(hdd_ctx); 16483 if (ret) { 16484 hdd_err("Failed to destroy pdev; errno:%d", ret); 16485 QDF_ASSERT(0); 16486 } 16487 16488 qdf_status = cds_close(hdd_ctx->psoc); 16489 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { 16490 hdd_warn("Failed to stop CDS: %d", qdf_status); 16491 ret = -EINVAL; 16492 QDF_ASSERT(0); 16493 } 16494 16495 qdf_status = wbuff_module_deinit(); 16496 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) 16497 hdd_err("WBUFF de-init unsuccessful; status: %d", 16498 qdf_status); 16499 16500 hdd_component_psoc_close(hdd_ctx->psoc); 16501 /* pdev close and destroy use tx rx ops so call this here */ 16502 wlan_global_lmac_if_close(hdd_ctx->psoc); 16503 } 16504 16505 /* 16506 * Reset total mac phy during module stop such that during 16507 * next module start same psoc is used to populate new service 16508 * ready data 16509 */ 16510 tgt_hdl = wlan_psoc_get_tgt_if_handle(hdd_ctx->psoc); 16511 if (tgt_hdl) 16512 target_psoc_set_total_mac_phy_cnt(tgt_hdl, 0); 16513 16514 16515 hif_ctx = cds_get_context(QDF_MODULE_ID_HIF); 16516 if (!hif_ctx) 16517 ret = -EINVAL; 16518 16519 if (hdd_get_conparam() == QDF_GLOBAL_EPPING_MODE) { 16520 epping_disable(); 16521 epping_close(); 16522 } 16523 16524 wlan_connectivity_logging_stop(); 16525 16526 ucfg_ipa_component_config_free(); 16527 16528 hdd_hif_close(hdd_ctx, hif_ctx); 16529 16530 ol_cds_free(); 16531 16532 if (IS_IDLE_STOP) { 16533 ret = pld_power_off(qdf_ctx->dev); 16534 if (ret) 16535 hdd_err("Failed to power down device; errno:%d", ret); 16536 } 16537 16538 /* Free the cache channels of the command SET_DISABLE_CHANNEL_LIST */ 16539 wlan_hdd_free_cache_channels(hdd_ctx); 16540 hdd_driver_mem_cleanup(); 16541 16542 /* Free the resources allocated while storing SAR config. These needs 16543 * to be freed only in the case when it is not SSR. As in the case of 16544 * SSR, the values needs to be intact so that it can be restored during 16545 * reinit path. 16546 */ 16547 if (!is_recovery_stop) 16548 wlan_hdd_free_sar_config(hdd_ctx); 16549 16550 hdd_sap_destroy_ctx_all(hdd_ctx, is_recovery_stop); 16551 hdd_sta_destroy_ctx_all(hdd_ctx); 16552 16553 /* 16554 * Reset the driver mode specific bus bw level 16555 */ 16556 param.policy = BBM_DRIVER_MODE_POLICY; 16557 param.policy_info.driver_mode = QDF_GLOBAL_MAX_MODE; 16558 ucfg_dp_bbm_apply_independent_policy(hdd_ctx->psoc, ¶m); 16559 16560 hdd_deinit_adapter_ops_wq(hdd_ctx); 16561 hdd_deinit_qdf_ctx(hdd_debug_domain_get()); 16562 16563 hdd_check_for_leaks(hdd_ctx, is_recovery_stop); 16564 hdd_debug_domain_set(QDF_DEBUG_DOMAIN_INIT); 16565 hdd_deinit_qdf_ctx(hdd_debug_domain_get()); 16566 qdf_dma_invalid_buf_list_deinit(); 16567 16568 /* Restore PS params for monitor mode */ 16569 if (hdd_get_conparam() == QDF_GLOBAL_MONITOR_MODE) 16570 hdd_restore_all_ps(hdd_ctx); 16571 16572 /* Once the firmware sequence is completed reset this flag */ 16573 hdd_ctx->imps_enabled = false; 16574 hdd_ctx->is_dual_mac_cfg_updated = false; 16575 hdd_ctx->driver_status = DRIVER_MODULES_CLOSED; 16576 hdd_ctx->is_fw_dbg_log_levels_configured = false; 16577 hdd_debug("Wlan transitioned (now CLOSED)"); 16578 16579 done: 16580 hdd_exit(); 16581 16582 return ret; 16583 } 16584 16585 #ifdef WLAN_FEATURE_MEMDUMP_ENABLE 16586 /** 16587 * hdd_state_info_dump() - prints state information of hdd layer 16588 * @buf_ptr: buffer pointer 16589 * @size: size of buffer to be filled 16590 * 16591 * This function is used to dump state information of hdd layer 16592 * 16593 * Return: None 16594 */ 16595 static void hdd_state_info_dump(char **buf_ptr, uint16_t *size) 16596 { 16597 struct hdd_context *hdd_ctx; 16598 struct hdd_station_ctx *sta_ctx; 16599 struct hdd_adapter *adapter, *next_adapter = NULL; 16600 uint16_t len = 0; 16601 char *buf = *buf_ptr; 16602 wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_STATE_INFO_DUMP; 16603 struct wlan_hdd_link_info *link_info; 16604 16605 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 16606 if (!hdd_ctx) 16607 return; 16608 16609 hdd_debug("size of buffer: %d", *size); 16610 16611 len += scnprintf(buf + len, *size - len, "\n is_wiphy_suspended %d", 16612 hdd_ctx->is_wiphy_suspended); 16613 len += scnprintf(buf + len, *size - len, "\n is_scheduler_suspended %d", 16614 hdd_ctx->is_scheduler_suspended); 16615 16616 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 16617 dbgid) { 16618 hdd_adapter_for_each_active_link_info(adapter, link_info) { 16619 len += 16620 scnprintf(buf + len, *size - len, "\n device name: %s", 16621 adapter->dev->name); 16622 len += 16623 scnprintf(buf + len, *size - len, "\n device_mode: %d", 16624 adapter->device_mode); 16625 switch (adapter->device_mode) { 16626 case QDF_STA_MODE: 16627 case QDF_P2P_CLIENT_MODE: 16628 sta_ctx = 16629 WLAN_HDD_GET_STATION_CTX_PTR(link_info); 16630 len += scnprintf(buf + len, *size - len, 16631 "\n conn_state: %d", 16632 sta_ctx->conn_info.conn_state); 16633 break; 16634 default: 16635 break; 16636 } 16637 } 16638 hdd_adapter_dev_put_debug(adapter, dbgid); 16639 } 16640 16641 *size -= len; 16642 *buf_ptr += len; 16643 } 16644 16645 /** 16646 * hdd_register_debug_callback() - registration function for hdd layer 16647 * to print hdd state information 16648 * 16649 * Return: None 16650 */ 16651 static void hdd_register_debug_callback(void) 16652 { 16653 qdf_register_debug_callback(QDF_MODULE_ID_HDD, &hdd_state_info_dump); 16654 } 16655 #else /* WLAN_FEATURE_MEMDUMP_ENABLE */ 16656 static void hdd_register_debug_callback(void) 16657 { 16658 } 16659 #endif /* WLAN_FEATURE_MEMDUMP_ENABLE */ 16660 16661 /* 16662 * wlan_init_bug_report_lock() - Initialize bug report lock 16663 * 16664 * This function is used to create bug report lock 16665 * 16666 * Return: None 16667 */ 16668 static void wlan_init_bug_report_lock(void) 16669 { 16670 struct cds_context *p_cds_context; 16671 16672 p_cds_context = cds_get_global_context(); 16673 if (!p_cds_context) { 16674 hdd_err("cds context is NULL"); 16675 return; 16676 } 16677 16678 qdf_spinlock_create(&p_cds_context->bug_report_lock); 16679 } 16680 16681 #ifdef DISABLE_CHANNEL_LIST 16682 static QDF_STATUS wlan_hdd_cache_chann_mutex_create(struct hdd_context *hdd_ctx) 16683 { 16684 return qdf_mutex_create(&hdd_ctx->cache_channel_lock); 16685 } 16686 #else 16687 static QDF_STATUS wlan_hdd_cache_chann_mutex_create(struct hdd_context *hdd_ctx) 16688 { 16689 return QDF_STATUS_SUCCESS; 16690 } 16691 #endif 16692 16693 QDF_STATUS hdd_open_adapter_no_trans(struct hdd_context *hdd_ctx, 16694 enum QDF_OPMODE op_mode, 16695 const char *iface_name, 16696 uint8_t *mac_addr_bytes, 16697 struct hdd_adapter_create_param *params) 16698 { 16699 struct osif_vdev_sync *vdev_sync; 16700 struct hdd_adapter *adapter; 16701 QDF_STATUS status; 16702 int errno; 16703 16704 QDF_BUG(rtnl_is_locked()); 16705 16706 errno = osif_vdev_sync_create(hdd_ctx->parent_dev, &vdev_sync); 16707 if (errno) 16708 return qdf_status_from_os_return(errno); 16709 16710 adapter = hdd_open_adapter(hdd_ctx, op_mode, iface_name, 16711 mac_addr_bytes, NET_NAME_UNKNOWN, true, 16712 params); 16713 if (!adapter) { 16714 status = QDF_STATUS_E_INVAL; 16715 goto destroy_sync; 16716 } 16717 16718 osif_vdev_sync_register(adapter->dev, vdev_sync); 16719 16720 return QDF_STATUS_SUCCESS; 16721 16722 destroy_sync: 16723 osif_vdev_sync_destroy(vdev_sync); 16724 16725 return status; 16726 } 16727 16728 #ifdef WLAN_OPEN_P2P_INTERFACE 16729 /** 16730 * hdd_open_p2p_interface - Open P2P interface 16731 * @hdd_ctx: HDD context 16732 * 16733 * Return: QDF_STATUS 16734 */ 16735 static QDF_STATUS hdd_open_p2p_interface(struct hdd_context *hdd_ctx) 16736 { 16737 QDF_STATUS status; 16738 bool p2p_dev_addr_admin; 16739 bool is_p2p_locally_administered = false; 16740 struct hdd_adapter_create_param params = {0}; 16741 16742 cfg_p2p_get_device_addr_admin(hdd_ctx->psoc, &p2p_dev_addr_admin); 16743 16744 if (p2p_dev_addr_admin) { 16745 if (hdd_ctx->num_provisioned_addr && 16746 !(hdd_ctx->provisioned_mac_addr[0].bytes[0] & 0x02)) { 16747 hdd_ctx->p2p_device_address = 16748 hdd_ctx->provisioned_mac_addr[0]; 16749 16750 /* 16751 * Generate the P2P Device Address. This consists of 16752 * the device's primary MAC address with the locally 16753 * administered bit set. 16754 */ 16755 16756 hdd_ctx->p2p_device_address.bytes[0] |= 0x02; 16757 is_p2p_locally_administered = true; 16758 } else if (!(hdd_ctx->derived_mac_addr[0].bytes[0] & 0x02)) { 16759 hdd_ctx->p2p_device_address = 16760 hdd_ctx->derived_mac_addr[0]; 16761 /* 16762 * Generate the P2P Device Address. This consists of 16763 * the device's primary MAC address with the locally 16764 * administered bit set. 16765 */ 16766 hdd_ctx->p2p_device_address.bytes[0] |= 0x02; 16767 is_p2p_locally_administered = true; 16768 } 16769 } 16770 if (!is_p2p_locally_administered) { 16771 uint8_t *p2p_dev_addr; 16772 16773 p2p_dev_addr = wlan_hdd_get_intf_addr(hdd_ctx, 16774 QDF_P2P_DEVICE_MODE); 16775 if (!p2p_dev_addr) { 16776 hdd_err("Failed to get MAC address for new p2p device"); 16777 return QDF_STATUS_E_INVAL; 16778 } 16779 16780 qdf_mem_copy(hdd_ctx->p2p_device_address.bytes, 16781 p2p_dev_addr, QDF_MAC_ADDR_SIZE); 16782 } 16783 16784 status = hdd_open_adapter_no_trans(hdd_ctx, QDF_P2P_DEVICE_MODE, 16785 "p2p%d", 16786 hdd_ctx->p2p_device_address.bytes, 16787 ¶ms); 16788 if (QDF_IS_STATUS_ERROR(status)) { 16789 if (!is_p2p_locally_administered) 16790 wlan_hdd_release_intf_addr(hdd_ctx, 16791 hdd_ctx->p2p_device_address.bytes); 16792 hdd_err("Failed to open p2p interface"); 16793 return QDF_STATUS_E_INVAL; 16794 } 16795 16796 return QDF_STATUS_SUCCESS; 16797 } 16798 #else 16799 static inline QDF_STATUS hdd_open_p2p_interface(struct hdd_context *hdd_ctx) 16800 { 16801 return QDF_STATUS_SUCCESS; 16802 } 16803 #endif 16804 16805 static QDF_STATUS hdd_open_ocb_interface(struct hdd_context *hdd_ctx) 16806 { 16807 QDF_STATUS status; 16808 uint8_t *mac_addr; 16809 struct hdd_adapter_create_param params = {0}; 16810 16811 mac_addr = wlan_hdd_get_intf_addr(hdd_ctx, QDF_OCB_MODE); 16812 if (!mac_addr) 16813 return QDF_STATUS_E_INVAL; 16814 16815 status = hdd_open_adapter_no_trans(hdd_ctx, QDF_OCB_MODE, 16816 "wlanocb%d", mac_addr, 16817 ¶ms); 16818 if (QDF_IS_STATUS_ERROR(status)) { 16819 wlan_hdd_release_intf_addr(hdd_ctx, mac_addr); 16820 hdd_err("Failed to open 802.11p interface"); 16821 } 16822 16823 return status; 16824 } 16825 16826 static QDF_STATUS hdd_open_concurrent_interface(struct hdd_context *hdd_ctx) 16827 { 16828 QDF_STATUS status; 16829 const char *iface_name; 16830 uint8_t *mac_addr; 16831 struct hdd_adapter_create_param params = {0}; 16832 16833 if (qdf_str_eq(hdd_ctx->config->enable_concurrent_sta, "")) 16834 return QDF_STATUS_SUCCESS; 16835 16836 iface_name = hdd_ctx->config->enable_concurrent_sta; 16837 mac_addr = wlan_hdd_get_intf_addr(hdd_ctx, QDF_STA_MODE); 16838 if (!mac_addr) 16839 return QDF_STATUS_E_INVAL; 16840 16841 status = hdd_open_adapter_no_trans(hdd_ctx, QDF_STA_MODE, 16842 iface_name, mac_addr, 16843 ¶ms); 16844 if (QDF_IS_STATUS_ERROR(status)) { 16845 wlan_hdd_release_intf_addr(hdd_ctx, mac_addr); 16846 hdd_err("Failed to open concurrent station interface"); 16847 } 16848 16849 return status; 16850 } 16851 16852 #ifdef WLAN_HDD_MULTI_VDEV_SINGLE_NDEV 16853 static inline void 16854 hdd_adapter_open_set_max_active_links(struct hdd_adapter_create_param *params) 16855 { 16856 if (params->is_add_virtual_iface || !params->is_ml_adapter) 16857 params->num_sessions = 1; 16858 else 16859 params->num_sessions = 2; 16860 } 16861 #else 16862 static inline void 16863 hdd_adapter_open_set_max_active_links(struct hdd_adapter_create_param *params) 16864 { 16865 params->num_sessions = 1; 16866 } 16867 #endif 16868 16869 static QDF_STATUS 16870 hdd_open_adapters_for_mission_mode(struct hdd_context *hdd_ctx) 16871 { 16872 enum dot11p_mode dot11p_mode; 16873 QDF_STATUS status; 16874 uint8_t *mac_addr; 16875 struct hdd_adapter_create_param params = {0}; 16876 bool eht_capab = 0; 16877 16878 ucfg_mlme_get_dot11p_mode(hdd_ctx->psoc, &dot11p_mode); 16879 ucfg_psoc_mlme_get_11be_capab(hdd_ctx->psoc, &eht_capab); 16880 16881 /* Create only 802.11p interface? */ 16882 if (dot11p_mode == CFG_11P_STANDALONE) 16883 return hdd_open_ocb_interface(hdd_ctx); 16884 16885 mac_addr = wlan_hdd_get_intf_addr(hdd_ctx, QDF_STA_MODE); 16886 if (!mac_addr) 16887 return QDF_STATUS_E_INVAL; 16888 16889 if (eht_capab) { 16890 params.is_ml_adapter = true; 16891 hdd_adapter_open_set_max_active_links(¶ms); 16892 } 16893 16894 status = hdd_open_adapter_no_trans(hdd_ctx, QDF_STA_MODE, 16895 "wlan%d", mac_addr, 16896 ¶ms); 16897 if (QDF_IS_STATUS_ERROR(status)) { 16898 wlan_hdd_release_intf_addr(hdd_ctx, mac_addr); 16899 return status; 16900 } 16901 16902 /* opening concurrent STA is best effort, continue on error */ 16903 hdd_open_concurrent_interface(hdd_ctx); 16904 16905 status = hdd_open_p2p_interface(hdd_ctx); 16906 if (status) 16907 goto err_close_adapters; 16908 16909 /* 16910 * Create separate interface (wifi-aware0) for NAN. All NAN commands 16911 * should go on this new interface. 16912 */ 16913 if (wlan_hdd_is_vdev_creation_allowed(hdd_ctx->psoc)) { 16914 qdf_mem_zero(¶ms, sizeof(params)); 16915 mac_addr = wlan_hdd_get_intf_addr(hdd_ctx, QDF_NAN_DISC_MODE); 16916 if (!mac_addr) 16917 goto err_close_adapters; 16918 16919 status = hdd_open_adapter_no_trans(hdd_ctx, QDF_NAN_DISC_MODE, 16920 "wifi-aware%d", mac_addr, 16921 ¶ms); 16922 if (status) { 16923 wlan_hdd_release_intf_addr(hdd_ctx, mac_addr); 16924 goto err_close_adapters; 16925 } 16926 } 16927 /* Open 802.11p Interface */ 16928 if (dot11p_mode == CFG_11P_CONCURRENT) { 16929 status = hdd_open_ocb_interface(hdd_ctx); 16930 if (QDF_IS_STATUS_ERROR(status)) 16931 goto err_close_adapters; 16932 } 16933 16934 if (eht_capab) 16935 hdd_wlan_register_mlo_interfaces(hdd_ctx); 16936 16937 return QDF_STATUS_SUCCESS; 16938 16939 err_close_adapters: 16940 hdd_close_all_adapters(hdd_ctx, true); 16941 16942 return status; 16943 } 16944 16945 static QDF_STATUS hdd_open_adapters_for_ftm_mode(struct hdd_context *hdd_ctx) 16946 { 16947 QDF_STATUS status; 16948 uint8_t *mac_addr; 16949 struct hdd_adapter_create_param params = {0}; 16950 16951 mac_addr = wlan_hdd_get_intf_addr(hdd_ctx, QDF_FTM_MODE); 16952 if (!mac_addr) 16953 return QDF_STATUS_E_INVAL; 16954 16955 status = hdd_open_adapter_no_trans(hdd_ctx, QDF_FTM_MODE, 16956 "wlan%d", mac_addr, 16957 ¶ms); 16958 if (QDF_IS_STATUS_ERROR(status)) { 16959 wlan_hdd_release_intf_addr(hdd_ctx, mac_addr); 16960 return status; 16961 } 16962 16963 return QDF_STATUS_SUCCESS; 16964 } 16965 16966 static QDF_STATUS 16967 hdd_open_adapters_for_monitor_mode(struct hdd_context *hdd_ctx) 16968 { 16969 QDF_STATUS status; 16970 uint8_t *mac_addr; 16971 struct hdd_adapter_create_param params = {0}; 16972 16973 mac_addr = wlan_hdd_get_intf_addr(hdd_ctx, QDF_MONITOR_MODE); 16974 if (!mac_addr) 16975 return QDF_STATUS_E_INVAL; 16976 16977 status = hdd_open_adapter_no_trans(hdd_ctx, QDF_MONITOR_MODE, 16978 "wlan%d", mac_addr, 16979 ¶ms); 16980 if (QDF_IS_STATUS_ERROR(status)) { 16981 wlan_hdd_release_intf_addr(hdd_ctx, mac_addr); 16982 return status; 16983 } 16984 16985 return QDF_STATUS_SUCCESS; 16986 } 16987 16988 static QDF_STATUS hdd_open_adapters_for_epping_mode(struct hdd_context *hdd_ctx) 16989 { 16990 epping_enable_adapter(); 16991 return QDF_STATUS_SUCCESS; 16992 } 16993 16994 typedef QDF_STATUS (*hdd_open_mode_handler)(struct hdd_context *hdd_ctx); 16995 16996 static const hdd_open_mode_handler 16997 hdd_open_mode_handlers[QDF_GLOBAL_MAX_MODE] = { 16998 [QDF_GLOBAL_MISSION_MODE] = hdd_open_adapters_for_mission_mode, 16999 [QDF_GLOBAL_FTM_MODE] = hdd_open_adapters_for_ftm_mode, 17000 [QDF_GLOBAL_MONITOR_MODE] = hdd_open_adapters_for_monitor_mode, 17001 [QDF_GLOBAL_EPPING_MODE] = hdd_open_adapters_for_epping_mode, 17002 }; 17003 17004 static QDF_STATUS hdd_open_adapters_for_mode(struct hdd_context *hdd_ctx, 17005 enum QDF_GLOBAL_MODE driver_mode) 17006 { 17007 QDF_STATUS status; 17008 17009 if (driver_mode < 0 || 17010 driver_mode >= QDF_GLOBAL_MAX_MODE || 17011 !hdd_open_mode_handlers[driver_mode]) { 17012 hdd_err("Driver mode %d not supported", driver_mode); 17013 return -ENOTSUPP; 17014 } 17015 17016 hdd_hold_rtnl_lock(); 17017 status = hdd_open_mode_handlers[driver_mode](hdd_ctx); 17018 hdd_release_rtnl_lock(); 17019 17020 return status; 17021 } 17022 17023 int hdd_wlan_startup(struct hdd_context *hdd_ctx) 17024 { 17025 QDF_STATUS status; 17026 int errno; 17027 bool is_imps_enabled; 17028 17029 hdd_enter(); 17030 17031 qdf_nbuf_init_replenish_timer(); 17032 17033 status = wlan_hdd_cache_chann_mutex_create(hdd_ctx); 17034 if (QDF_IS_STATUS_ERROR(status)) 17035 return qdf_status_to_os_return(status); 17036 17037 #ifdef FEATURE_WLAN_CH_AVOID 17038 mutex_init(&hdd_ctx->avoid_freq_lock); 17039 #endif 17040 17041 osif_request_manager_init(); 17042 hdd_driver_memdump_init(); 17043 17044 errno = hdd_init_regulatory_update_event(hdd_ctx); 17045 if (errno) { 17046 hdd_err("Failed to initialize regulatory update event; errno:%d", 17047 errno); 17048 goto memdump_deinit; 17049 } 17050 17051 errno = hdd_wlan_start_modules(hdd_ctx, false); 17052 if (errno) { 17053 hdd_err("Failed to start modules; errno:%d", errno); 17054 goto memdump_deinit; 17055 } 17056 17057 if (hdd_get_conparam() == QDF_GLOBAL_EPPING_MODE) 17058 return 0; 17059 17060 wlan_hdd_update_wiphy(hdd_ctx); 17061 17062 hdd_ctx->mac_handle = cds_get_context(QDF_MODULE_ID_SME); 17063 if (!hdd_ctx->mac_handle) 17064 goto stop_modules; 17065 17066 errno = hdd_wiphy_init(hdd_ctx); 17067 if (errno) { 17068 hdd_err("Failed to initialize wiphy; errno:%d", errno); 17069 goto stop_modules; 17070 } 17071 17072 errno = hdd_initialize_mac_address(hdd_ctx); 17073 if (errno) { 17074 hdd_err("MAC initializtion failed: %d", errno); 17075 goto unregister_wiphy; 17076 } 17077 17078 errno = register_netdevice_notifier(&hdd_netdev_notifier); 17079 if (errno) { 17080 hdd_err("register_netdevice_notifier failed; errno:%d", errno); 17081 goto unregister_wiphy; 17082 } 17083 17084 wlan_hdd_update_11n_mode(hdd_ctx); 17085 17086 hdd_lpass_notify_wlan_version(hdd_ctx); 17087 17088 status = wlansap_global_init(); 17089 if (QDF_IS_STATUS_ERROR(status)) 17090 goto unregister_notifiers; 17091 17092 ucfg_mlme_is_imps_enabled(hdd_ctx->psoc, &is_imps_enabled); 17093 hdd_set_idle_ps_config(hdd_ctx, is_imps_enabled); 17094 hdd_debugfs_mws_coex_info_init(hdd_ctx); 17095 hdd_debugfs_ini_config_init(hdd_ctx); 17096 wlan_hdd_debugfs_unit_test_host_create(hdd_ctx); 17097 wlan_hdd_create_mib_stats_lock(); 17098 wlan_cfg80211_init_interop_issues_ap(hdd_ctx->pdev); 17099 17100 hdd_exit(); 17101 17102 return 0; 17103 17104 unregister_notifiers: 17105 unregister_netdevice_notifier(&hdd_netdev_notifier); 17106 17107 unregister_wiphy: 17108 qdf_dp_trace_deinit(); 17109 wiphy_unregister(hdd_ctx->wiphy); 17110 17111 stop_modules: 17112 hdd_wlan_stop_modules(hdd_ctx, false); 17113 17114 memdump_deinit: 17115 hdd_driver_memdump_deinit(); 17116 osif_request_manager_deinit(); 17117 qdf_nbuf_deinit_replenish_timer(); 17118 17119 if (cds_is_fw_down()) 17120 hdd_err("Not setting the complete event as fw is down"); 17121 else 17122 hdd_start_complete(errno); 17123 17124 hdd_exit(); 17125 17126 return errno; 17127 } 17128 17129 QDF_STATUS hdd_psoc_create_vdevs(struct hdd_context *hdd_ctx) 17130 { 17131 enum QDF_GLOBAL_MODE driver_mode = hdd_get_conparam(); 17132 QDF_STATUS status; 17133 17134 status = hdd_open_adapters_for_mode(hdd_ctx, driver_mode); 17135 if (QDF_IS_STATUS_ERROR(status)) { 17136 hdd_err("Failed to create vdevs; status:%d", status); 17137 return status; 17138 } 17139 17140 ucfg_dp_try_set_rps_cpu_mask(hdd_ctx->psoc); 17141 17142 if (driver_mode != QDF_GLOBAL_FTM_MODE && 17143 driver_mode != QDF_GLOBAL_EPPING_MODE) 17144 hdd_psoc_idle_timer_start(hdd_ctx); 17145 17146 return QDF_STATUS_SUCCESS; 17147 } 17148 17149 /** 17150 * hdd_wlan_update_target_info() - update target type info 17151 * @hdd_ctx: HDD context 17152 * @context: hif context 17153 * 17154 * Update target info received from firmware in hdd context 17155 * Return:None 17156 */ 17157 17158 void hdd_wlan_update_target_info(struct hdd_context *hdd_ctx, void *context) 17159 { 17160 struct hif_target_info *tgt_info = hif_get_target_info_handle(context); 17161 17162 if (!tgt_info) { 17163 hdd_err("Target info is Null"); 17164 return; 17165 } 17166 17167 hdd_ctx->target_type = tgt_info->target_type; 17168 } 17169 17170 #ifdef WLAN_FEATURE_MOTION_DETECTION 17171 /** 17172 * hdd_md_host_evt_cb - Callback for Motion Detection Event 17173 * @ctx: HDD context 17174 * @event: motion detect event 17175 * 17176 * Callback for Motion Detection Event. Re-enables Motion 17177 * Detection again upon event 17178 * 17179 * Return: QDF_STATUS QDF_STATUS_SUCCESS on Success and 17180 * QDF_STATUS_E_FAILURE on failure 17181 */ 17182 QDF_STATUS hdd_md_host_evt_cb(void *ctx, struct sir_md_evt *event) 17183 { 17184 struct hdd_adapter *adapter; 17185 struct hdd_context *hdd_ctx; 17186 struct sme_motion_det_en motion_det; 17187 struct wlan_hdd_link_info *link_info; 17188 17189 if (!ctx || !event) 17190 return QDF_STATUS_E_INVAL; 17191 17192 hdd_ctx = (struct hdd_context *)ctx; 17193 if (wlan_hdd_validate_context(hdd_ctx)) 17194 return QDF_STATUS_E_INVAL; 17195 17196 link_info = hdd_get_link_info_by_vdev(hdd_ctx, event->vdev_id); 17197 if (!link_info || 17198 WLAN_HDD_ADAPTER_MAGIC != link_info->adapter->magic) { 17199 hdd_err("Invalid adapter or adapter has invalid magic"); 17200 return QDF_STATUS_E_INVAL; 17201 } 17202 17203 adapter = link_info->adapter; 17204 /* When motion is detected, reset the motion_det_in_progress flag */ 17205 if (event->status) 17206 adapter->motion_det_in_progress = false; 17207 17208 hdd_debug("Motion Detection CB vdev_id=%u, status=%u", 17209 event->vdev_id, event->status); 17210 17211 if (adapter->motion_detection_mode) { 17212 motion_det.vdev_id = event->vdev_id; 17213 motion_det.enable = 1; 17214 hdd_debug("Motion Detect CB -> Enable Motion Detection again"); 17215 sme_motion_det_enable(hdd_ctx->mac_handle, &motion_det); 17216 } 17217 17218 return QDF_STATUS_SUCCESS; 17219 } 17220 17221 /** 17222 * hdd_md_bl_evt_cb - Callback for Motion Detection Baseline Event 17223 * @ctx: HDD context 17224 * @event: motion detect baseline event 17225 * 17226 * Callback for Motion Detection Baseline completion 17227 * 17228 * Return: QDF_STATUS QDF_STATUS_SUCCESS on Success and 17229 * QDF_STATUS_E_FAILURE on failure 17230 */ 17231 QDF_STATUS hdd_md_bl_evt_cb(void *ctx, struct sir_md_bl_evt *event) 17232 { 17233 struct hdd_context *hdd_ctx; 17234 struct wlan_hdd_link_info *link_info; 17235 17236 if (!ctx || !event) 17237 return QDF_STATUS_E_INVAL; 17238 17239 hdd_ctx = (struct hdd_context *)ctx; 17240 if (wlan_hdd_validate_context(hdd_ctx)) 17241 return QDF_STATUS_E_INVAL; 17242 17243 link_info = hdd_get_link_info_by_vdev(hdd_ctx, event->vdev_id); 17244 if (!link_info || 17245 WLAN_HDD_ADAPTER_MAGIC != link_info->adapter->magic) { 17246 hdd_err("Invalid adapter or adapter has invalid magic"); 17247 return QDF_STATUS_E_INVAL; 17248 } 17249 17250 hdd_debug("Motion Detection Baseline CB vdev id=%u, baseline val = %d", 17251 event->vdev_id, event->bl_baseline_value); 17252 17253 link_info->adapter->motion_det_baseline_value = 17254 event->bl_baseline_value; 17255 17256 return QDF_STATUS_SUCCESS; 17257 } 17258 #endif /* WLAN_FEATURE_MOTION_DETECTION */ 17259 17260 /** 17261 * hdd_ssr_on_pagefault_cb - Callback to trigger SSR because 17262 * of host wake up by firmware with reason pagefault 17263 * 17264 * Return: None 17265 */ 17266 static void hdd_ssr_on_pagefault_cb(void) 17267 { 17268 uint32_t ssr_frequency_on_pagefault; 17269 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 17270 qdf_time_t curr_time; 17271 17272 hdd_enter(); 17273 17274 if (!hdd_ctx) 17275 return; 17276 17277 ssr_frequency_on_pagefault = 17278 ucfg_pmo_get_ssr_frequency_on_pagefault(hdd_ctx->psoc); 17279 17280 curr_time = qdf_get_time_of_the_day_ms(); 17281 17282 if (!hdd_ctx->last_pagefault_ssr_time || 17283 (curr_time - hdd_ctx->last_pagefault_ssr_time) >= 17284 ssr_frequency_on_pagefault) { 17285 hdd_info("curr_time %lu last_pagefault_ssr_time %lu ssr_frequency %d", 17286 curr_time, hdd_ctx->last_pagefault_ssr_time, 17287 ssr_frequency_on_pagefault); 17288 hdd_ctx->last_pagefault_ssr_time = curr_time; 17289 cds_trigger_recovery(QDF_HOST_WAKEUP_REASON_PAGEFAULT); 17290 } 17291 } 17292 17293 /** 17294 * hdd_register_cb - Register HDD callbacks. 17295 * @hdd_ctx: HDD context 17296 * 17297 * Register the HDD callbacks to CDS/SME. 17298 * 17299 * Return: 0 for success or Error code for failure 17300 */ 17301 int hdd_register_cb(struct hdd_context *hdd_ctx) 17302 { 17303 QDF_STATUS status; 17304 int ret = 0; 17305 mac_handle_t mac_handle; 17306 17307 hdd_enter(); 17308 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) { 17309 hdd_err("in ftm mode, no need to register callbacks"); 17310 return ret; 17311 } 17312 17313 mac_handle = hdd_ctx->mac_handle; 17314 17315 sme_register_oem_data_rsp_callback(mac_handle, 17316 hdd_send_oem_data_rsp_msg); 17317 17318 sme_register_mgmt_frame_ind_callback(mac_handle, 17319 hdd_indicate_mgmt_frame); 17320 sme_set_tsfcb(mac_handle, hdd_get_tsf_cb, hdd_ctx); 17321 sme_stats_ext_register_callback(mac_handle, 17322 wlan_hdd_cfg80211_stats_ext_callback); 17323 17324 sme_ext_scan_register_callback(mac_handle, 17325 wlan_hdd_cfg80211_extscan_callback); 17326 sme_stats_ext2_register_callback(mac_handle, 17327 wlan_hdd_cfg80211_stats_ext2_callback); 17328 17329 sme_multi_client_ll_rsp_register_callback(mac_handle, 17330 hdd_latency_level_event_handler_cb); 17331 17332 sme_set_rssi_threshold_breached_cb(mac_handle, 17333 hdd_rssi_threshold_breached); 17334 17335 sme_set_link_layer_stats_ind_cb(mac_handle, 17336 wlan_hdd_cfg80211_link_layer_stats_callback); 17337 17338 sme_rso_cmd_status_cb(mac_handle, wlan_hdd_rso_cmd_status_cb); 17339 17340 sme_set_link_layer_ext_cb(mac_handle, 17341 wlan_hdd_cfg80211_link_layer_stats_ext_callback); 17342 sme_update_hidden_ssid_status_cb(mac_handle, 17343 hdd_hidden_ssid_enable_roaming); 17344 17345 status = sme_set_lost_link_info_cb(mac_handle, 17346 hdd_lost_link_info_cb); 17347 17348 wlan_hdd_register_cp_stats_cb(hdd_ctx); 17349 hdd_dcs_register_cb(hdd_ctx); 17350 17351 hdd_thermal_register_callbacks(hdd_ctx); 17352 /* print error and not block the startup process */ 17353 if (!QDF_IS_STATUS_SUCCESS(status)) 17354 hdd_err("set lost link info callback failed"); 17355 17356 ret = hdd_register_data_stall_detect_cb(); 17357 if (ret) { 17358 hdd_err("Register data stall detect detect callback failed."); 17359 return ret; 17360 } 17361 17362 wlan_hdd_dcc_register_for_dcc_stats_event(hdd_ctx); 17363 17364 sme_register_set_connection_info_cb(mac_handle, 17365 hdd_set_connection_in_progress, 17366 hdd_is_connection_in_progress); 17367 17368 status = sme_set_bt_activity_info_cb(mac_handle, 17369 hdd_bt_activity_cb); 17370 if (!QDF_IS_STATUS_SUCCESS(status)) 17371 hdd_err("set bt activity info callback failed"); 17372 17373 status = sme_register_tx_queue_cb(mac_handle, 17374 hdd_tx_queue_cb); 17375 if (!QDF_IS_STATUS_SUCCESS(status)) 17376 hdd_err("Register tx queue callback failed"); 17377 17378 #ifdef WLAN_FEATURE_MOTION_DETECTION 17379 sme_set_md_host_evt_cb(mac_handle, hdd_md_host_evt_cb, (void *)hdd_ctx); 17380 sme_set_md_bl_evt_cb(mac_handle, hdd_md_bl_evt_cb, (void *)hdd_ctx); 17381 #endif /* WLAN_FEATURE_MOTION_DETECTION */ 17382 17383 mac_register_session_open_close_cb(hdd_ctx->mac_handle, 17384 hdd_sme_close_session_callback, 17385 hdd_common_roam_callback); 17386 17387 sme_set_roam_scan_ch_event_cb(mac_handle, hdd_get_roam_scan_ch_cb); 17388 status = sme_set_monitor_mode_cb(mac_handle, 17389 hdd_sme_monitor_mode_callback); 17390 if (QDF_IS_STATUS_ERROR(status)) 17391 hdd_err_rl("Register monitor mode callback failed"); 17392 17393 status = sme_set_beacon_latency_event_cb(mac_handle, 17394 hdd_beacon_latency_event_cb); 17395 if (QDF_IS_STATUS_ERROR(status)) 17396 hdd_err_rl("Register beacon latency event callback failed"); 17397 17398 sme_async_oem_event_init(mac_handle, 17399 hdd_oem_event_async_cb); 17400 17401 sme_register_ssr_on_pagefault_cb(mac_handle, hdd_ssr_on_pagefault_cb); 17402 17403 hdd_exit(); 17404 17405 return ret; 17406 } 17407 17408 /** 17409 * hdd_deregister_cb() - De-Register HDD callbacks. 17410 * @hdd_ctx: HDD context 17411 * 17412 * De-Register the HDD callbacks to CDS/SME. 17413 * 17414 * Return: void 17415 */ 17416 void hdd_deregister_cb(struct hdd_context *hdd_ctx) 17417 { 17418 QDF_STATUS status; 17419 int ret; 17420 mac_handle_t mac_handle; 17421 17422 hdd_enter(); 17423 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) { 17424 hdd_err("in ftm mode, no need to deregister callbacks"); 17425 return; 17426 } 17427 17428 mac_handle = hdd_ctx->mac_handle; 17429 17430 sme_deregister_ssr_on_pagefault_cb(mac_handle); 17431 17432 sme_async_oem_event_deinit(mac_handle); 17433 17434 sme_deregister_tx_queue_cb(mac_handle); 17435 17436 sme_reset_link_layer_stats_ind_cb(mac_handle); 17437 sme_reset_rssi_threshold_breached_cb(mac_handle); 17438 17439 sme_stats_ext_deregister_callback(mac_handle); 17440 17441 status = sme_reset_tsfcb(mac_handle); 17442 if (!QDF_IS_STATUS_SUCCESS(status)) 17443 hdd_err("Failed to de-register tsfcb the callback:%d", 17444 status); 17445 17446 ret = hdd_deregister_data_stall_detect_cb(); 17447 if (ret) 17448 hdd_err("Failed to de-register data stall detect event callback"); 17449 hdd_thermal_unregister_callbacks(hdd_ctx); 17450 sme_deregister_oem_data_rsp_callback(mac_handle); 17451 sme_multi_client_ll_rsp_deregister_callback(mac_handle); 17452 17453 hdd_exit(); 17454 } 17455 17456 /** 17457 * hdd_softap_sta_deauth() - handle deauth req from HDD 17458 * @adapter: Pointer to the HDD adapter 17459 * @param: Params to the operation 17460 * 17461 * This to take counter measure to handle deauth req from HDD 17462 * 17463 * Return: None 17464 */ 17465 QDF_STATUS hdd_softap_sta_deauth(struct hdd_adapter *adapter, 17466 struct csr_del_sta_params *param) 17467 { 17468 QDF_STATUS qdf_status = QDF_STATUS_E_FAULT; 17469 struct hdd_context *hdd_ctx; 17470 bool is_sap_bcast_deauth_enabled = false; 17471 17472 hdd_ctx = WLAN_HDD_GET_CTX(adapter); 17473 if (!hdd_ctx) { 17474 hdd_err("hdd_ctx is NULL"); 17475 return QDF_STATUS_E_INVAL; 17476 } 17477 17478 ucfg_mlme_get_sap_bcast_deauth_enabled(hdd_ctx->psoc, 17479 &is_sap_bcast_deauth_enabled); 17480 17481 hdd_enter(); 17482 17483 hdd_debug("sap_bcast_deauth_enabled %d", is_sap_bcast_deauth_enabled); 17484 /* Ignore request to deauth bcmc station */ 17485 if (!is_sap_bcast_deauth_enabled) 17486 if (param->peerMacAddr.bytes[0] & 0x1) 17487 return qdf_status; 17488 17489 qdf_status = 17490 wlansap_deauth_sta(WLAN_HDD_GET_SAP_CTX_PTR(adapter->deflink), 17491 param); 17492 17493 hdd_exit(); 17494 return qdf_status; 17495 } 17496 17497 /** 17498 * hdd_softap_sta_disassoc() - take counter measure to handle deauth req from HDD 17499 * @adapter: Pointer to the HDD 17500 * @param: pointer to station deletion parameters 17501 * 17502 * This to take counter measure to handle deauth req from HDD 17503 * 17504 * Return: None 17505 */ 17506 void hdd_softap_sta_disassoc(struct hdd_adapter *adapter, 17507 struct csr_del_sta_params *param) 17508 { 17509 hdd_enter(); 17510 17511 /* Ignore request to disassoc bcmc station */ 17512 if (param->peerMacAddr.bytes[0] & 0x1) 17513 return; 17514 17515 wlansap_disassoc_sta(WLAN_HDD_GET_SAP_CTX_PTR(adapter->deflink), 17516 param); 17517 } 17518 17519 void 17520 wlan_hdd_set_roaming_state(struct wlan_hdd_link_info *cur_link_info, 17521 enum wlan_cm_rso_control_requestor rso_op_requestor, 17522 bool enab_roam) 17523 { 17524 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(cur_link_info->adapter); 17525 struct hdd_adapter *adapter = NULL, *next_adapter = NULL; 17526 wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_DISABLE_ROAMING; 17527 uint8_t vdev_id, cur_vdev_id = cur_link_info->vdev_id; 17528 struct wlan_hdd_link_info *link_info; 17529 17530 if (!policy_mgr_is_sta_active_connection_exists(hdd_ctx->psoc)) 17531 return; 17532 17533 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 17534 dbgid) { 17535 hdd_adapter_for_each_active_link_info(adapter, link_info) { 17536 vdev_id = link_info->vdev_id; 17537 if (cur_vdev_id != link_info->vdev_id && 17538 adapter->device_mode == QDF_STA_MODE && 17539 hdd_cm_is_vdev_associated(link_info)) { 17540 if (enab_roam) { 17541 hdd_debug("%d Enable roaming", vdev_id); 17542 sme_start_roaming(hdd_ctx->mac_handle, 17543 vdev_id, 17544 REASON_DRIVER_ENABLED, 17545 rso_op_requestor); 17546 } else { 17547 hdd_debug("%d Disable roaming", 17548 vdev_id); 17549 sme_stop_roaming(hdd_ctx->mac_handle, 17550 vdev_id, 17551 REASON_DRIVER_DISABLED, 17552 rso_op_requestor); 17553 } 17554 } 17555 } 17556 hdd_adapter_dev_put_debug(adapter, dbgid); 17557 } 17558 } 17559 17560 /** 17561 * nl_srv_bcast_svc() - Wrapper function to send bcast msgs to SVC mcast group 17562 * @skb: sk buffer pointer 17563 * 17564 * Sends the bcast message to SVC multicast group with generic nl socket 17565 * if CNSS_GENL is enabled. Else, use the legacy netlink socket to send. 17566 * 17567 * Return: None 17568 */ 17569 static void nl_srv_bcast_svc(struct sk_buff *skb) 17570 { 17571 #ifdef CNSS_GENL 17572 nl_srv_bcast(skb, CLD80211_MCGRP_SVC_MSGS, WLAN_NL_MSG_SVC); 17573 #else 17574 nl_srv_bcast(skb); 17575 #endif 17576 } 17577 17578 void wlan_hdd_send_svc_nlink_msg(int radio, int type, void *data, int len) 17579 { 17580 struct sk_buff *skb; 17581 struct nlmsghdr *nlh; 17582 tAniMsgHdr *ani_hdr; 17583 void *nl_data = NULL; 17584 int flags = GFP_KERNEL; 17585 struct radio_index_tlv *radio_info; 17586 int tlv_len; 17587 17588 if (in_interrupt() || irqs_disabled() || in_atomic()) 17589 flags = GFP_ATOMIC; 17590 17591 skb = alloc_skb(NLMSG_SPACE(WLAN_NL_MAX_PAYLOAD), flags); 17592 17593 if (!skb) 17594 return; 17595 17596 nlh = (struct nlmsghdr *)skb->data; 17597 nlh->nlmsg_pid = 0; /* from kernel */ 17598 nlh->nlmsg_flags = 0; 17599 nlh->nlmsg_seq = 0; 17600 nlh->nlmsg_type = WLAN_NL_MSG_SVC; 17601 17602 ani_hdr = NLMSG_DATA(nlh); 17603 ani_hdr->type = type; 17604 17605 switch (type) { 17606 case WLAN_SVC_FW_CRASHED_IND: 17607 case WLAN_SVC_FW_SHUTDOWN_IND: 17608 case WLAN_SVC_LTE_COEX_IND: 17609 case WLAN_SVC_WLAN_AUTO_SHUTDOWN_IND: 17610 case WLAN_SVC_WLAN_AUTO_SHUTDOWN_CANCEL_IND: 17611 ani_hdr->length = 0; 17612 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr))); 17613 break; 17614 case WLAN_SVC_WLAN_STATUS_IND: 17615 case WLAN_SVC_WLAN_VERSION_IND: 17616 case WLAN_SVC_DFS_CAC_START_IND: 17617 case WLAN_SVC_DFS_CAC_END_IND: 17618 case WLAN_SVC_DFS_RADAR_DETECT_IND: 17619 case WLAN_SVC_DFS_ALL_CHANNEL_UNAVAIL_IND: 17620 case WLAN_SVC_WLAN_TP_IND: 17621 case WLAN_SVC_WLAN_TP_TX_IND: 17622 case WLAN_SVC_RPS_ENABLE_IND: 17623 case WLAN_SVC_CORE_MINFREQ: 17624 ani_hdr->length = len; 17625 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr) + len)); 17626 nl_data = (char *)ani_hdr + sizeof(tAniMsgHdr); 17627 memcpy(nl_data, data, len); 17628 break; 17629 17630 default: 17631 hdd_err("WLAN SVC: Attempt to send unknown nlink message %d", 17632 type); 17633 kfree_skb(skb); 17634 return; 17635 } 17636 17637 /* 17638 * Add radio index at the end of the svc event in TLV format 17639 * to maintain the backward compatibility with userspace 17640 * applications. 17641 */ 17642 17643 tlv_len = 0; 17644 17645 if ((sizeof(*ani_hdr) + len + sizeof(struct radio_index_tlv)) 17646 < WLAN_NL_MAX_PAYLOAD) { 17647 radio_info = (struct radio_index_tlv *)((char *) ani_hdr + 17648 sizeof(*ani_hdr) + len); 17649 radio_info->type = (unsigned short) WLAN_SVC_WLAN_RADIO_INDEX; 17650 radio_info->length = (unsigned short) sizeof(radio_info->radio); 17651 radio_info->radio = radio; 17652 tlv_len = sizeof(*radio_info); 17653 hdd_debug("Added radio index tlv - radio index %d", 17654 radio_info->radio); 17655 } 17656 17657 nlh->nlmsg_len += tlv_len; 17658 skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr) + len + tlv_len)); 17659 17660 nl_srv_bcast_svc(skb); 17661 } 17662 17663 #ifdef FEATURE_WLAN_AUTO_SHUTDOWN 17664 void wlan_hdd_auto_shutdown_cb(void) 17665 { 17666 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 17667 17668 if (!hdd_ctx) 17669 return; 17670 17671 hdd_debug("Wlan Idle. Sending Shutdown event.."); 17672 wlan_hdd_send_svc_nlink_msg(hdd_ctx->radio_index, 17673 WLAN_SVC_WLAN_AUTO_SHUTDOWN_IND, NULL, 0); 17674 } 17675 17676 void wlan_hdd_auto_shutdown_enable(struct hdd_context *hdd_ctx, bool enable) 17677 { 17678 struct hdd_adapter *adapter, *next_adapter = NULL; 17679 bool ap_connected = false, sta_connected = false; 17680 mac_handle_t mac_handle; 17681 struct wlan_hdd_link_info *link_info; 17682 struct hdd_ap_ctx *ap_ctx; 17683 wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_AUTO_SHUTDOWN_ENABLE; 17684 17685 mac_handle = hdd_ctx->mac_handle; 17686 if (!mac_handle) 17687 return; 17688 17689 if (hdd_ctx->config->wlan_auto_shutdown == 0) 17690 return; 17691 17692 if (enable == false) { 17693 if (sme_set_auto_shutdown_timer(mac_handle, 0) != 17694 QDF_STATUS_SUCCESS) { 17695 hdd_err("Failed to stop wlan auto shutdown timer"); 17696 } 17697 wlan_hdd_send_svc_nlink_msg(hdd_ctx->radio_index, 17698 WLAN_SVC_WLAN_AUTO_SHUTDOWN_CANCEL_IND, NULL, 0); 17699 return; 17700 } 17701 17702 /* To enable shutdown timer check conncurrency */ 17703 if (!policy_mgr_concurrent_open_sessions_running(hdd_ctx->psoc)) 17704 goto start_timer; 17705 17706 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, 17707 next_adapter, dbgid) { 17708 hdd_adapter_for_each_active_link_info(adapter, link_info) { 17709 if (adapter->device_mode == QDF_STA_MODE && 17710 hdd_cm_is_vdev_associated(link_info)) { 17711 sta_connected = true; 17712 hdd_adapter_dev_put_debug(adapter, dbgid); 17713 if (next_adapter) 17714 hdd_adapter_dev_put_debug(next_adapter, 17715 dbgid); 17716 break; 17717 } 17718 17719 if (adapter->device_mode == QDF_SAP_MODE) { 17720 ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(link_info); 17721 if (ap_ctx->ap_active == true) { 17722 ap_connected = true; 17723 hdd_adapter_dev_put_debug(adapter, 17724 dbgid); 17725 if (next_adapter) 17726 hdd_adapter_dev_put_debug( 17727 next_adapter, 17728 dbgid); 17729 break; 17730 } 17731 } 17732 } 17733 hdd_adapter_dev_put_debug(adapter, dbgid); 17734 } 17735 17736 start_timer: 17737 if (ap_connected == true || sta_connected == true) { 17738 hdd_debug("CC Session active. Shutdown timer not enabled"); 17739 return; 17740 } 17741 17742 if (sme_set_auto_shutdown_timer(mac_handle, 17743 hdd_ctx->config->wlan_auto_shutdown) 17744 != QDF_STATUS_SUCCESS) 17745 hdd_err("Failed to start wlan auto shutdown timer"); 17746 else 17747 hdd_info("Auto Shutdown timer for %d seconds enabled", 17748 hdd_ctx->config->wlan_auto_shutdown); 17749 } 17750 #endif 17751 17752 struct hdd_adapter * 17753 hdd_get_con_sap_adapter(struct hdd_adapter *this_sap_adapter, 17754 bool check_start_bss) 17755 { 17756 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(this_sap_adapter); 17757 struct hdd_adapter *adapter, *next_adapter = NULL; 17758 wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_GET_CON_SAP_ADAPTER; 17759 struct wlan_hdd_link_info *link_info; 17760 17761 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 17762 dbgid) { 17763 if ((adapter->device_mode == QDF_SAP_MODE || 17764 adapter->device_mode == QDF_P2P_GO_MODE) && 17765 adapter != this_sap_adapter) { 17766 hdd_adapter_for_each_active_link_info(adapter, 17767 link_info) { 17768 if (!check_start_bss) { 17769 hdd_adapter_dev_put_debug(adapter, 17770 dbgid); 17771 if (next_adapter) 17772 hdd_adapter_dev_put_debug( 17773 next_adapter, 17774 dbgid); 17775 return adapter; 17776 } 17777 if (test_bit(SOFTAP_BSS_STARTED, 17778 &link_info->link_flags)) { 17779 hdd_adapter_dev_put_debug(adapter, 17780 dbgid); 17781 if (next_adapter) 17782 hdd_adapter_dev_put_debug( 17783 next_adapter, 17784 dbgid); 17785 return adapter; 17786 } 17787 } 17788 } 17789 hdd_adapter_dev_put_debug(adapter, dbgid); 17790 } 17791 17792 return NULL; 17793 } 17794 17795 static inline bool hdd_adapter_is_sta(struct hdd_adapter *adapter) 17796 { 17797 return adapter->device_mode == QDF_STA_MODE || 17798 adapter->device_mode == QDF_P2P_CLIENT_MODE; 17799 } 17800 17801 bool hdd_is_any_adapter_connected(struct hdd_context *hdd_ctx) 17802 { 17803 struct hdd_adapter *adapter, *next_adapter = NULL; 17804 wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_IS_ANY_ADAPTER_CONNECTED; 17805 struct wlan_hdd_link_info *link_info; 17806 17807 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 17808 dbgid) { 17809 hdd_adapter_for_each_active_link_info(adapter, link_info) { 17810 if (hdd_adapter_is_sta(adapter) && 17811 hdd_cm_is_vdev_associated(link_info)) { 17812 hdd_adapter_dev_put_debug(adapter, dbgid); 17813 if (next_adapter) 17814 hdd_adapter_dev_put_debug(next_adapter, 17815 dbgid); 17816 return true; 17817 } 17818 17819 if (hdd_adapter_is_ap(adapter) && 17820 WLAN_HDD_GET_AP_CTX_PTR(link_info)->ap_active) { 17821 hdd_adapter_dev_put_debug(adapter, dbgid); 17822 if (next_adapter) 17823 hdd_adapter_dev_put_debug(next_adapter, 17824 dbgid); 17825 return true; 17826 } 17827 17828 if (adapter->device_mode == QDF_NDI_MODE && 17829 hdd_cm_is_vdev_associated(link_info)) { 17830 hdd_adapter_dev_put_debug(adapter, dbgid); 17831 if (next_adapter) 17832 hdd_adapter_dev_put_debug(next_adapter, 17833 dbgid); 17834 return true; 17835 } 17836 } 17837 hdd_adapter_dev_put_debug(adapter, dbgid); 17838 } 17839 17840 return false; 17841 } 17842 17843 #if defined MSM_PLATFORM && (LINUX_VERSION_CODE <= KERNEL_VERSION(4, 19, 0)) 17844 /** 17845 * hdd_inform_stop_sap() - call cfg80211 API to stop SAP 17846 * @adapter: pointer to adapter 17847 * 17848 * This function calls cfg80211 API to stop SAP 17849 * 17850 * Return: None 17851 */ 17852 static void hdd_inform_stop_sap(struct hdd_adapter *adapter) 17853 { 17854 hdd_debug("SAP stopped due to invalid channel vdev id %d", 17855 wlan_vdev_get_id(adapter->deflink->vdev)); 17856 cfg80211_ap_stopped(adapter->dev, GFP_KERNEL); 17857 } 17858 17859 #else 17860 static void hdd_inform_stop_sap(struct hdd_adapter *adapter) 17861 { 17862 hdd_debug("SAP stopped due to invalid channel vdev id %d", 17863 wlan_vdev_get_id(adapter->deflink->vdev)); 17864 cfg80211_stop_iface(adapter->hdd_ctx->wiphy, &adapter->wdev, 17865 GFP_KERNEL); 17866 } 17867 #endif 17868 17869 /** 17870 * wlan_hdd_stop_sap() - This function stops bss of SAP. 17871 * @ap_adapter: SAP adapter 17872 * 17873 * This function will process the stopping of sap adapter. 17874 * 17875 * Return: None 17876 */ 17877 void wlan_hdd_stop_sap(struct hdd_adapter *ap_adapter) 17878 { 17879 struct hdd_ap_ctx *hdd_ap_ctx; 17880 struct hdd_hostapd_state *hostapd_state; 17881 QDF_STATUS qdf_status; 17882 struct hdd_context *hdd_ctx; 17883 17884 if (!ap_adapter) { 17885 hdd_err("ap_adapter is NULL here"); 17886 return; 17887 } 17888 17889 hdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(ap_adapter->deflink); 17890 hdd_ctx = WLAN_HDD_GET_CTX(ap_adapter); 17891 if (wlan_hdd_validate_context(hdd_ctx)) 17892 return; 17893 17894 mutex_lock(&hdd_ctx->sap_lock); 17895 if (test_bit(SOFTAP_BSS_STARTED, &ap_adapter->deflink->link_flags)) { 17896 wlan_hdd_del_station(ap_adapter, NULL); 17897 hostapd_state = 17898 WLAN_HDD_GET_HOSTAP_STATE_PTR(ap_adapter->deflink); 17899 hdd_debug("Now doing SAP STOPBSS"); 17900 qdf_event_reset(&hostapd_state->qdf_stop_bss_event); 17901 if (QDF_STATUS_SUCCESS == wlansap_stop_bss(hdd_ap_ctx-> 17902 sap_context)) { 17903 qdf_status = qdf_wait_single_event(&hostapd_state-> 17904 qdf_stop_bss_event, 17905 SME_CMD_STOP_BSS_TIMEOUT); 17906 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { 17907 mutex_unlock(&hdd_ctx->sap_lock); 17908 hdd_err("SAP Stop Failed"); 17909 return; 17910 } 17911 } 17912 clear_bit(SOFTAP_BSS_STARTED, &ap_adapter->deflink->link_flags); 17913 policy_mgr_decr_session_set_pcl(hdd_ctx->psoc, 17914 ap_adapter->device_mode, 17915 ap_adapter->deflink->vdev_id); 17916 hdd_green_ap_start_state_mc(hdd_ctx, ap_adapter->device_mode, 17917 false); 17918 hdd_inform_stop_sap(ap_adapter); 17919 hdd_debug("SAP Stop Success"); 17920 } else { 17921 hdd_err("Can't stop ap because its not started"); 17922 } 17923 mutex_unlock(&hdd_ctx->sap_lock); 17924 } 17925 17926 #if defined(WLAN_FEATURE_11BE_MLO) && defined(CFG80211_11BE_BASIC) 17927 /** 17928 * wlan_hdd_mlo_sap_reinit() - handle mlo scenario for ssr 17929 * @link_info: Pointer of link_info in adapter 17930 * 17931 * Return: QDF_STATUS 17932 */ 17933 static QDF_STATUS wlan_hdd_mlo_sap_reinit(struct wlan_hdd_link_info *link_info) 17934 { 17935 struct hdd_context *hdd_ctx = link_info->adapter->hdd_ctx; 17936 struct sap_config *config = &link_info->session.ap.sap_config; 17937 17938 if (config->mlo_sap) { 17939 if (!mlo_ap_vdev_attach(link_info->vdev, config->link_id, 17940 config->num_link)) { 17941 hdd_err("SAP mlo mgr attach fail"); 17942 return QDF_STATUS_E_INVAL; 17943 } 17944 } 17945 17946 if (!policy_mgr_is_mlo_sap_concurrency_allowed(hdd_ctx->psoc, 17947 config->mlo_sap, 17948 wlan_vdev_get_id(link_info->vdev))) { 17949 hdd_err("MLO SAP concurrency check fails"); 17950 return QDF_STATUS_E_INVAL; 17951 } 17952 17953 return QDF_STATUS_SUCCESS; 17954 } 17955 #else 17956 static inline QDF_STATUS 17957 wlan_hdd_mlo_sap_reinit(struct wlan_hdd_link_info *link_info) 17958 { 17959 return QDF_STATUS_SUCCESS; 17960 } 17961 #endif 17962 17963 void wlan_hdd_start_sap(struct wlan_hdd_link_info *link_info, bool reinit) 17964 { 17965 struct hdd_ap_ctx *ap_ctx; 17966 struct hdd_hostapd_state *hostapd_state; 17967 QDF_STATUS qdf_status; 17968 struct hdd_context *hdd_ctx; 17969 struct sap_config *sap_config; 17970 struct hdd_adapter *ap_adapter = link_info->adapter; 17971 17972 if (QDF_SAP_MODE != ap_adapter->device_mode) { 17973 hdd_err("SoftAp role has not been enabled"); 17974 return; 17975 } 17976 17977 hdd_ctx = WLAN_HDD_GET_CTX(ap_adapter); 17978 ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(link_info); 17979 hostapd_state = WLAN_HDD_GET_HOSTAP_STATE_PTR(link_info); 17980 sap_config = &ap_ctx->sap_config; 17981 17982 mutex_lock(&hdd_ctx->sap_lock); 17983 if (test_bit(SOFTAP_BSS_STARTED, &link_info->link_flags)) 17984 goto end; 17985 17986 if (wlan_hdd_cfg80211_update_apies(link_info)) { 17987 hdd_err("SAP Not able to set AP IEs"); 17988 goto end; 17989 } 17990 wlan_reg_set_channel_params_for_pwrmode(hdd_ctx->pdev, 17991 sap_config->chan_freq, 0, 17992 &sap_config->ch_params, 17993 REG_CURRENT_PWR_MODE); 17994 qdf_status = wlan_hdd_mlo_sap_reinit(link_info); 17995 if (QDF_IS_STATUS_ERROR(qdf_status)) { 17996 hdd_err("SAP Not able to do mlo attach"); 17997 goto end; 17998 } 17999 18000 qdf_event_reset(&hostapd_state->qdf_event); 18001 qdf_status = wlansap_start_bss(ap_ctx->sap_context, 18002 hdd_hostapd_sap_event_cb, sap_config, 18003 ap_adapter->dev); 18004 if (QDF_IS_STATUS_ERROR(qdf_status)) 18005 goto end; 18006 18007 hdd_debug("Waiting for SAP to start"); 18008 qdf_status = qdf_wait_single_event(&hostapd_state->qdf_event, 18009 SME_CMD_START_BSS_TIMEOUT); 18010 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { 18011 hdd_err("SAP Start failed"); 18012 goto end; 18013 } 18014 hdd_info("SAP Start Success"); 18015 18016 if (reinit) 18017 hdd_medium_assess_init(); 18018 wlansap_reset_sap_config_add_ie(sap_config, eUPDATE_IE_ALL); 18019 set_bit(SOFTAP_BSS_STARTED, &link_info->link_flags); 18020 if (hostapd_state->bss_state == BSS_START) { 18021 policy_mgr_incr_active_session(hdd_ctx->psoc, 18022 ap_adapter->device_mode, 18023 link_info->vdev_id); 18024 hdd_green_ap_start_state_mc(hdd_ctx, ap_adapter->device_mode, 18025 true); 18026 } 18027 mutex_unlock(&hdd_ctx->sap_lock); 18028 18029 return; 18030 end: 18031 wlan_hdd_mlo_reset(link_info); 18032 wlansap_reset_sap_config_add_ie(sap_config, eUPDATE_IE_ALL); 18033 mutex_unlock(&hdd_ctx->sap_lock); 18034 /* SAP context and beacon cleanup will happen during driver unload 18035 * in hdd_stop_adapter 18036 */ 18037 hdd_err("SAP restart after SSR failed! Reload WLAN and try SAP again"); 18038 /* Free the beacon memory in case of failure in the sap restart */ 18039 qdf_mem_free(ap_ctx->beacon); 18040 ap_ctx->beacon = NULL; 18041 } 18042 18043 #ifdef QCA_CONFIG_SMP 18044 /** 18045 * wlan_hdd_get_cpu() - get cpu_index 18046 * 18047 * Return: cpu_index 18048 */ 18049 int wlan_hdd_get_cpu(void) 18050 { 18051 int cpu_index = get_cpu(); 18052 18053 put_cpu(); 18054 return cpu_index; 18055 } 18056 #endif 18057 18058 /** 18059 * hdd_get_fwpath() - get framework path 18060 * 18061 * This function is used to get the string written by 18062 * userspace to start the wlan driver 18063 * 18064 * Return: string 18065 */ 18066 const char *hdd_get_fwpath(void) 18067 { 18068 return fwpath.string; 18069 } 18070 18071 static inline int hdd_state_query_cb(void) 18072 { 18073 return !!wlan_hdd_validate_context(cds_get_context(QDF_MODULE_ID_HDD)); 18074 } 18075 18076 static int __hdd_op_protect_cb(void **out_sync, const char *func) 18077 { 18078 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 18079 18080 if (!hdd_ctx) 18081 return -EAGAIN; 18082 18083 return __osif_psoc_sync_op_start(hdd_ctx->parent_dev, 18084 (struct osif_psoc_sync **)out_sync, 18085 func); 18086 } 18087 18088 static void __hdd_op_unprotect_cb(void *sync, const char *func) 18089 { 18090 __osif_psoc_sync_op_stop(sync, func); 18091 } 18092 18093 #ifdef WLAN_LOGGING_SOCK_SVC_ENABLE 18094 /** 18095 * hdd_logging_sock_init_svc() - Initialize logging sock 18096 * 18097 * Return: 0 for success, errno on failure 18098 */ 18099 static int 18100 hdd_logging_sock_init_svc(void) 18101 { 18102 return wlan_logging_sock_init_svc(); 18103 } 18104 #else 18105 static inline int 18106 hdd_logging_sock_init_svc(void) 18107 { 18108 return 0; 18109 } 18110 #endif 18111 18112 /** 18113 * hdd_init() - Initialize Driver 18114 * 18115 * This function initializes CDS global context with the help of cds_init. This 18116 * has to be the first function called after probe to get a valid global 18117 * context. 18118 * 18119 * Return: 0 for success, errno on failure 18120 */ 18121 int hdd_init(void) 18122 { 18123 QDF_STATUS status; 18124 18125 status = cds_init(); 18126 if (QDF_IS_STATUS_ERROR(status)) { 18127 hdd_err("Failed to allocate CDS context"); 18128 return -ENOMEM; 18129 } 18130 18131 qdf_op_callbacks_register(__hdd_op_protect_cb, __hdd_op_unprotect_cb); 18132 18133 wlan_init_bug_report_lock(); 18134 18135 if (hdd_logging_sock_init_svc()) { 18136 hdd_err("logging sock init failed."); 18137 goto err; 18138 } 18139 18140 hdd_trace_init(); 18141 hdd_register_debug_callback(); 18142 wlan_roam_debug_init(); 18143 18144 return 0; 18145 18146 err: 18147 wlan_destroy_bug_report_lock(); 18148 qdf_op_callbacks_register(NULL, NULL); 18149 cds_deinit(); 18150 return -ENOMEM; 18151 } 18152 18153 /** 18154 * hdd_deinit() - Deinitialize Driver 18155 * 18156 * This function frees CDS global context with the help of cds_deinit. This 18157 * has to be the last function call in remove callback to free the global 18158 * context. 18159 */ 18160 void hdd_deinit(void) 18161 { 18162 wlan_roam_debug_deinit(); 18163 18164 #ifdef WLAN_LOGGING_SOCK_SVC_ENABLE 18165 wlan_logging_sock_deinit_svc(); 18166 #endif 18167 18168 wlan_destroy_bug_report_lock(); 18169 qdf_op_callbacks_register(NULL, NULL); 18170 cds_deinit(); 18171 } 18172 18173 #ifdef QCA_WIFI_EMULATION 18174 #define HDD_WLAN_START_WAIT_TIME ((CDS_WMA_TIMEOUT + 5000) * 100) 18175 #else 18176 #define HDD_WLAN_START_WAIT_TIME (CDS_WMA_TIMEOUT + 5000) 18177 #endif 18178 18179 void hdd_init_start_completion(void) 18180 { 18181 INIT_COMPLETION(wlan_start_comp); 18182 } 18183 18184 #ifdef WLAN_CTRL_NAME 18185 static unsigned int dev_num = 1; 18186 static struct cdev wlan_hdd_state_cdev; 18187 static struct class *class; 18188 static dev_t device; 18189 18190 static void hdd_set_adapter_wlm_def_level(struct hdd_context *hdd_ctx) 18191 { 18192 struct hdd_adapter *adapter, *next_adapter = NULL; 18193 wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_GET_ADAPTER; 18194 int ret; 18195 QDF_STATUS qdf_status; 18196 uint8_t latency_level; 18197 bool reset; 18198 18199 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) 18200 return; 18201 18202 ret = wlan_hdd_validate_context(hdd_ctx); 18203 if (ret != 0) 18204 return; 18205 18206 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 18207 dbgid) { 18208 qdf_status = ucfg_mlme_cfg_get_wlm_level(hdd_ctx->psoc, 18209 &latency_level); 18210 if (QDF_IS_STATUS_ERROR(qdf_status)) 18211 adapter->latency_level = 18212 QCA_WLAN_VENDOR_ATTR_CONFIG_LATENCY_LEVEL_NORMAL; 18213 else 18214 adapter->latency_level = latency_level; 18215 qdf_status = ucfg_mlme_cfg_get_wlm_reset(hdd_ctx->psoc, &reset); 18216 if (QDF_IS_STATUS_ERROR(qdf_status)) { 18217 hdd_err("could not get the wlm reset flag"); 18218 reset = false; 18219 } 18220 18221 if (hdd_get_multi_client_ll_support(adapter) && !reset) 18222 wlan_hdd_deinit_multi_client_info_table(adapter); 18223 18224 adapter->upgrade_udp_qos_threshold = QCA_WLAN_AC_BK; 18225 hdd_debug("UDP packets qos reset to: %d", 18226 adapter->upgrade_udp_qos_threshold); 18227 hdd_adapter_dev_put_debug(adapter, dbgid); 18228 } 18229 } 18230 18231 static int wlan_hdd_state_ctrl_param_open(struct inode *inode, 18232 struct file *file) 18233 { 18234 qdf_atomic_inc(&wlan_hdd_state_fops_ref); 18235 18236 return 0; 18237 } 18238 18239 static void __hdd_inform_wifi_off(void) 18240 { 18241 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 18242 int ret; 18243 18244 ret = wlan_hdd_validate_context(hdd_ctx); 18245 if (ret != 0) 18246 return; 18247 18248 ucfg_dlm_wifi_off(hdd_ctx->pdev); 18249 } 18250 18251 static void hdd_inform_wifi_off(void) 18252 { 18253 int ret; 18254 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 18255 struct osif_psoc_sync *psoc_sync; 18256 18257 if (!hdd_ctx) 18258 return; 18259 18260 ret = osif_psoc_sync_op_start(wiphy_dev(hdd_ctx->wiphy), &psoc_sync); 18261 if (ret) 18262 return; 18263 18264 hdd_set_adapter_wlm_def_level(hdd_ctx); 18265 __hdd_inform_wifi_off(); 18266 18267 osif_psoc_sync_op_stop(psoc_sync); 18268 } 18269 18270 #if defined CFG80211_USER_HINT_CELL_BASE_SELF_MANAGED || \ 18271 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 18, 0)) 18272 static void hdd_inform_wifi_on(void) 18273 { 18274 int ret; 18275 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 18276 struct osif_psoc_sync *psoc_sync; 18277 18278 hdd_nofl_debug("inform regdomain for wifi on"); 18279 ret = wlan_hdd_validate_context(hdd_ctx); 18280 if (ret) 18281 return; 18282 if (!wlan_hdd_validate_modules_state(hdd_ctx)) 18283 return; 18284 if (!hdd_ctx->wiphy) 18285 return; 18286 ret = osif_psoc_sync_op_start(wiphy_dev(hdd_ctx->wiphy), &psoc_sync); 18287 if (ret) 18288 return; 18289 if (hdd_ctx->wiphy->registered) 18290 hdd_send_wiphy_regd_sync_event(hdd_ctx); 18291 18292 osif_psoc_sync_op_stop(psoc_sync); 18293 } 18294 #else 18295 static void hdd_inform_wifi_on(void) 18296 { 18297 } 18298 #endif 18299 18300 static int hdd_validate_wlan_string(const char __user *user_buf) 18301 { 18302 char buf[15]; 18303 int i; 18304 static const char * const wlan_str[] = { 18305 [WLAN_OFF_STR] = "OFF", 18306 [WLAN_ON_STR] = "ON", 18307 [WLAN_ENABLE_STR] = "ENABLE", 18308 [WLAN_DISABLE_STR] = "DISABLE", 18309 [WLAN_WAIT_FOR_READY_STR] = "WAIT_FOR_READY", 18310 [WLAN_FORCE_DISABLE_STR] = "FORCE_DISABLE" 18311 }; 18312 18313 if (copy_from_user(buf, user_buf, sizeof(buf))) { 18314 pr_err("Failed to read buffer\n"); 18315 return -EINVAL; 18316 } 18317 18318 for (i = 0; i < ARRAY_SIZE(wlan_str); i++) { 18319 if (qdf_str_ncmp(buf, wlan_str[i], strlen(wlan_str[i])) == 0) 18320 return i; 18321 } 18322 18323 return -EINVAL; 18324 } 18325 18326 #ifdef FEATURE_CNSS_HW_SECURE_DISABLE 18327 #define WIFI_DISABLE_SLEEP (10) 18328 #define WIFI_DISABLE_MAX_RETRY_ATTEMPTS (10) 18329 static bool g_soft_unload; 18330 18331 bool hdd_get_wlan_driver_status(void) 18332 { 18333 return g_soft_unload; 18334 } 18335 18336 static int hdd_wlan_soft_driver_load(void) 18337 { 18338 if (!cds_is_driver_loaded()) { 18339 hdd_debug("\nEnabling CNSS WLAN HW"); 18340 pld_wlan_hw_enable(); 18341 return 0; 18342 } 18343 18344 if (!g_soft_unload) { 18345 hdd_debug_rl("Enabling WiFi\n"); 18346 return -EINVAL; 18347 } 18348 18349 hdd_driver_load(); 18350 g_soft_unload = false; 18351 return 0; 18352 } 18353 18354 static void hdd_wlan_soft_driver_unload(void) 18355 { 18356 if (g_soft_unload) { 18357 hdd_debug_rl("WiFi is already disabled"); 18358 return; 18359 } 18360 hdd_debug("Initiating soft driver unload\n"); 18361 g_soft_unload = true; 18362 hdd_driver_unload(); 18363 } 18364 18365 static int hdd_wlan_idle_shutdown(struct hdd_context *hdd_ctx) 18366 { 18367 int ret; 18368 int retries = 0; 18369 void *hif_ctx; 18370 18371 if (!hdd_ctx) { 18372 hdd_err_rl("hdd_ctx is Null"); 18373 return -EINVAL; 18374 } 18375 18376 hif_ctx = cds_get_context(QDF_MODULE_ID_HIF); 18377 18378 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_IDLE_SHUTDOWN); 18379 18380 while (retries < WIFI_DISABLE_MAX_RETRY_ATTEMPTS) { 18381 if (hif_ctx) { 18382 /* 18383 * Trigger runtime sync resume before psoc_idle_shutdown 18384 * such that resume can happen successfully 18385 */ 18386 qdf_rtpm_sync_resume(); 18387 } 18388 ret = pld_idle_shutdown(hdd_ctx->parent_dev, 18389 hdd_psoc_idle_shutdown); 18390 18391 if (-EAGAIN == ret || hdd_ctx->is_wiphy_suspended) { 18392 hdd_debug("System suspend in progress.Retries done:%d", 18393 retries); 18394 msleep(WIFI_DISABLE_SLEEP); 18395 retries++; 18396 continue; 18397 } 18398 break; 18399 } 18400 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_IDLE_SHUTDOWN); 18401 18402 if (retries > WIFI_DISABLE_MAX_RETRY_ATTEMPTS) { 18403 hdd_debug("Max retries reached"); 18404 return -EINVAL; 18405 } 18406 hdd_debug_rl("WiFi is disabled"); 18407 18408 return 0; 18409 } 18410 18411 static int hdd_disable_wifi(struct hdd_context *hdd_ctx) 18412 { 18413 int ret; 18414 18415 if (hdd_ctx->is_wlan_disabled) { 18416 hdd_err_rl("Wifi is already disabled"); 18417 return 0; 18418 } 18419 18420 hdd_debug("Initiating WLAN idle shutdown"); 18421 if (hdd_is_any_interface_open(hdd_ctx)) { 18422 hdd_err("Interfaces still open, cannot process wifi disable"); 18423 return -EAGAIN; 18424 } 18425 18426 hdd_ctx->is_wlan_disabled = true; 18427 18428 ret = hdd_wlan_idle_shutdown(hdd_ctx); 18429 if (ret) 18430 hdd_ctx->is_wlan_disabled = false; 18431 18432 return ret; 18433 } 18434 #else 18435 static int hdd_wlan_soft_driver_load(void) 18436 { 18437 return -EINVAL; 18438 } 18439 18440 static void hdd_wlan_soft_driver_unload(void) 18441 { 18442 } 18443 18444 static int hdd_disable_wifi(struct hdd_context *hdd_ctx) 18445 { 18446 return 0; 18447 } 18448 #endif /* FEATURE_CNSS_HW_SECURE_DISABLE */ 18449 18450 static ssize_t wlan_hdd_state_ctrl_param_write(struct file *filp, 18451 const char __user *user_buf, 18452 size_t count, 18453 loff_t *f_pos) 18454 { 18455 int id, ret; 18456 unsigned long rc; 18457 struct hdd_context *hdd_ctx; 18458 bool is_wait_for_ready = false; 18459 bool is_wlan_force_disabled; 18460 18461 hdd_enter(); 18462 18463 id = hdd_validate_wlan_string(user_buf); 18464 18465 switch (id) { 18466 case WLAN_OFF_STR: 18467 hdd_info("Wifi turning off from UI\n"); 18468 hdd_inform_wifi_off(); 18469 goto exit; 18470 case WLAN_ON_STR: 18471 hdd_info("Wifi Turning On from UI\n"); 18472 break; 18473 case WLAN_WAIT_FOR_READY_STR: 18474 is_wait_for_ready = true; 18475 hdd_info("Wifi wait for ready from UI\n"); 18476 break; 18477 case WLAN_ENABLE_STR: 18478 hdd_nofl_debug("Received WiFi enable from framework\n"); 18479 if (!hdd_wlan_soft_driver_load()) 18480 goto exit; 18481 pr_info("Enabling WiFi\n"); 18482 break; 18483 case WLAN_DISABLE_STR: 18484 hdd_nofl_debug("Received WiFi disable from framework\n"); 18485 if (!cds_is_driver_loaded()) 18486 goto exit; 18487 18488 is_wlan_force_disabled = hdd_get_wlan_driver_status(); 18489 if (is_wlan_force_disabled) 18490 goto exit; 18491 pr_info("Disabling WiFi\n"); 18492 break; 18493 case WLAN_FORCE_DISABLE_STR: 18494 hdd_nofl_debug("Received Force WiFi disable from framework\n"); 18495 if (!cds_is_driver_loaded()) 18496 goto exit; 18497 18498 hdd_wlan_soft_driver_unload(); 18499 goto exit; 18500 default: 18501 hdd_err_rl("Invalid value received from framework"); 18502 return -EINVAL; 18503 } 18504 18505 hdd_info("is_driver_loaded %d is_driver_recovering %d", 18506 cds_is_driver_loaded(), cds_is_driver_recovering()); 18507 18508 if (!cds_is_driver_loaded() || cds_is_driver_recovering()) { 18509 rc = wait_for_completion_timeout(&wlan_start_comp, 18510 msecs_to_jiffies(HDD_WLAN_START_WAIT_TIME)); 18511 if (!rc) { 18512 hdd_err("Driver Loading Timed-out!!"); 18513 ret = -EINVAL; 18514 return ret; 18515 } 18516 } 18517 18518 if (is_wait_for_ready) 18519 return count; 18520 /* 18521 * Flush idle shutdown work for cases to synchronize the wifi on 18522 * during the idle shutdown. 18523 */ 18524 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 18525 if (hdd_ctx) 18526 hdd_psoc_idle_timer_stop(hdd_ctx); 18527 18528 if (id == WLAN_DISABLE_STR) { 18529 if (!hdd_ctx) { 18530 hdd_err_rl("hdd_ctx is Null"); 18531 goto exit; 18532 } 18533 18534 ret = hdd_disable_wifi(hdd_ctx); 18535 if (ret) 18536 return ret; 18537 } 18538 18539 if (id == WLAN_ENABLE_STR) { 18540 if (!hdd_ctx) { 18541 hdd_err_rl("hdd_ctx is Null"); 18542 goto exit; 18543 } 18544 18545 if (!hdd_ctx->is_wlan_disabled) { 18546 hdd_err_rl("WiFi is already enabled"); 18547 goto exit; 18548 } 18549 hdd_ctx->is_wlan_disabled = false; 18550 } 18551 18552 if (id == WLAN_ON_STR) 18553 hdd_inform_wifi_on(); 18554 exit: 18555 hdd_exit(); 18556 return count; 18557 } 18558 18559 /** 18560 * wlan_hdd_state_ctrl_param_release() - Release callback for /dev/wlan. 18561 * 18562 * @inode: struct inode pointer. 18563 * @file: struct file pointer. 18564 * 18565 * Release callback that would be invoked when the file operations has 18566 * completed fully. This is implemented to provide a reference count mechanism 18567 * via which the driver can wait till all possible usage of the /dev/wlan 18568 * file is completed. 18569 * 18570 * Return: Success 18571 */ 18572 static int wlan_hdd_state_ctrl_param_release(struct inode *inode, 18573 struct file *file) 18574 { 18575 qdf_atomic_dec(&wlan_hdd_state_fops_ref); 18576 18577 return 0; 18578 } 18579 18580 const struct file_operations wlan_hdd_state_fops = { 18581 .owner = THIS_MODULE, 18582 .open = wlan_hdd_state_ctrl_param_open, 18583 .write = wlan_hdd_state_ctrl_param_write, 18584 .release = wlan_hdd_state_ctrl_param_release, 18585 }; 18586 18587 static int wlan_hdd_state_ctrl_param_create(void) 18588 { 18589 unsigned int wlan_hdd_state_major = 0; 18590 int ret; 18591 struct device *dev; 18592 18593 init_completion(&wlan_start_comp); 18594 qdf_atomic_init(&wlan_hdd_state_fops_ref); 18595 18596 device = MKDEV(wlan_hdd_state_major, 0); 18597 18598 ret = alloc_chrdev_region(&device, 0, dev_num, "qcwlanstate"); 18599 if (ret) { 18600 pr_err("Failed to register qcwlanstate"); 18601 goto dev_alloc_err; 18602 } 18603 wlan_hdd_state_major = MAJOR(device); 18604 18605 class = class_create(THIS_MODULE, WLAN_CTRL_NAME); 18606 if (IS_ERR(class)) { 18607 pr_err("wlan_hdd_state class_create error"); 18608 goto class_err; 18609 } 18610 18611 dev = device_create(class, NULL, device, NULL, WLAN_CTRL_NAME); 18612 if (IS_ERR(dev)) { 18613 pr_err("wlan_hdd_statedevice_create error"); 18614 goto err_class_destroy; 18615 } 18616 18617 cdev_init(&wlan_hdd_state_cdev, &wlan_hdd_state_fops); 18618 18619 wlan_hdd_state_cdev.owner = THIS_MODULE; 18620 18621 ret = cdev_add(&wlan_hdd_state_cdev, device, dev_num); 18622 if (ret) { 18623 pr_err("Failed to add cdev error"); 18624 goto cdev_add_err; 18625 } 18626 18627 pr_info("wlan_hdd_state %s major(%d) initialized", 18628 WLAN_CTRL_NAME, wlan_hdd_state_major); 18629 18630 return 0; 18631 18632 cdev_add_err: 18633 device_destroy(class, device); 18634 err_class_destroy: 18635 class_destroy(class); 18636 class_err: 18637 unregister_chrdev_region(device, dev_num); 18638 dev_alloc_err: 18639 return -ENODEV; 18640 } 18641 18642 /* 18643 * When multiple instances of the driver are loaded in parallel, only 18644 * one can create and own the state ctrl param. An instance of the 18645 * driver that creates the state ctrl param will wait for 18646 * HDD_WLAN_START_WAIT_TIME to be probed. If it is probed, then that 18647 * instance of the driver will stay loaded and no other instances of 18648 * the driver can load. But if it is not probed, then that instance of 18649 * the driver will destroy the state ctrl param and exit, and another 18650 * instance of the driver can then create the state ctrl param. 18651 */ 18652 18653 /* max number of instances we expect (arbitrary) */ 18654 #define WLAN_DRIVER_MAX_INSTANCES 5 18655 18656 /* max amount of time an instance has to wait for all instances */ 18657 #define CTRL_PARAM_WAIT (WLAN_DRIVER_MAX_INSTANCES * HDD_WLAN_START_WAIT_TIME) 18658 18659 /* amount of time we sleep for each retry (arbitrary) */ 18660 #define CTRL_PARAM_SLEEP 100 18661 18662 static void wlan_hdd_state_ctrl_param_destroy(void) 18663 { 18664 cdev_del(&wlan_hdd_state_cdev); 18665 device_destroy(class, device); 18666 class_destroy(class); 18667 unregister_chrdev_region(device, dev_num); 18668 18669 pr_info("Device node unregistered"); 18670 } 18671 18672 #else /* WLAN_CTRL_NAME */ 18673 18674 static int wlan_hdd_state_ctrl_param_create(void) 18675 { 18676 return 0; 18677 } 18678 18679 static void wlan_hdd_state_ctrl_param_destroy(void) 18680 { 18681 } 18682 18683 #endif /* WLAN_CTRL_NAME */ 18684 18685 /** 18686 * hdd_send_scan_done_complete_cb() - API to send scan done indication to upper 18687 * layer 18688 * @vdev_id: vdev id 18689 * 18690 * Return: none 18691 */ 18692 static void hdd_send_scan_done_complete_cb(uint8_t vdev_id) 18693 { 18694 struct hdd_context *hdd_ctx; 18695 struct wlan_hdd_link_info *link_info; 18696 struct hdd_adapter *adapter; 18697 struct sk_buff *vendor_event; 18698 uint32_t len; 18699 18700 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 18701 if (!hdd_ctx) 18702 return; 18703 18704 link_info = hdd_get_link_info_by_vdev(hdd_ctx, vdev_id); 18705 if (!link_info) { 18706 hdd_err("Invalid vdev id:%d", vdev_id); 18707 return; 18708 } 18709 18710 adapter = link_info->adapter; 18711 len = NLMSG_HDRLEN; 18712 vendor_event = 18713 wlan_cfg80211_vendor_event_alloc( 18714 hdd_ctx->wiphy, &adapter->wdev, len, 18715 QCA_NL80211_VENDOR_SUBCMD_CONNECTED_CHANNEL_STATS_INDEX, 18716 GFP_KERNEL); 18717 18718 if (!vendor_event) { 18719 hdd_err("wlan_cfg80211_vendor_event_alloc failed"); 18720 return; 18721 } 18722 18723 hdd_debug("sending scan done ind to upper layer for vdev_id:%d", 18724 vdev_id); 18725 wlan_cfg80211_vendor_event(vendor_event, GFP_KERNEL); 18726 } 18727 18728 struct osif_vdev_mgr_ops osif_vdev_mgrlegacy_ops = { 18729 #ifdef WLAN_FEATURE_DYNAMIC_MAC_ADDR_UPDATE 18730 .osif_vdev_mgr_set_mac_addr_response = hdd_set_mac_addr_event_cb, 18731 #endif 18732 .osif_vdev_mgr_send_scan_done_complete_cb = 18733 hdd_send_scan_done_complete_cb, 18734 18735 }; 18736 18737 static QDF_STATUS hdd_vdev_mgr_register_cb(void) 18738 { 18739 osif_vdev_mgr_set_legacy_cb(&osif_vdev_mgrlegacy_ops); 18740 return osif_vdev_mgr_register_cb(); 18741 } 18742 18743 static void hdd_vdev_mgr_unregister_cb(void) 18744 { 18745 osif_vdev_mgr_reset_legacy_cb(); 18746 } 18747 18748 /** 18749 * hdd_component_cb_init() - Initialize component callbacks 18750 * 18751 * This function initializes hdd callbacks to different 18752 * components 18753 * 18754 * Context: Any context. 18755 * Return: QDF_STATUS 18756 */ 18757 static QDF_STATUS hdd_component_cb_init(void) 18758 { 18759 QDF_STATUS status; 18760 18761 status = hdd_cm_register_cb(); 18762 if (QDF_IS_STATUS_ERROR(status)) 18763 return status; 18764 18765 status = hdd_vdev_mgr_register_cb(); 18766 if (QDF_IS_STATUS_ERROR(status)) 18767 goto cm_unregister_cb; 18768 18769 status = osif_twt_register_cb(); 18770 if (QDF_IS_STATUS_ERROR(status)) 18771 goto hdd_vdev_mgr_unregister_cb; 18772 18773 status = hdd_pre_cac_register_cb(); 18774 if (QDF_IS_STATUS_ERROR(status)) 18775 goto hdd_vdev_mgr_unregister_cb; 18776 18777 return QDF_STATUS_SUCCESS; 18778 18779 hdd_vdev_mgr_unregister_cb: 18780 hdd_vdev_mgr_unregister_cb(); 18781 cm_unregister_cb: 18782 hdd_cm_unregister_cb(); 18783 return status; 18784 } 18785 18786 /** 18787 * hdd_component_cb_deinit() - De-initialize component callbacks 18788 * 18789 * This function de-initializes hdd callbacks with different components 18790 * 18791 * Context: Any context. 18792 * Return: None` 18793 */ 18794 static void hdd_component_cb_deinit(void) 18795 { 18796 hdd_pre_cac_unregister_cb(); 18797 hdd_vdev_mgr_unregister_cb(); 18798 hdd_cm_unregister_cb(); 18799 } 18800 18801 /** 18802 * hdd_component_init() - Initialize all components 18803 * 18804 * Return: QDF_STATUS 18805 */ 18806 static QDF_STATUS hdd_component_init(void) 18807 { 18808 QDF_STATUS status; 18809 18810 /* initialize converged components */ 18811 18812 status = ucfg_mlme_global_init(); 18813 if (QDF_IS_STATUS_ERROR(status)) 18814 return status; 18815 18816 status = dispatcher_init(); 18817 if (QDF_IS_STATUS_ERROR(status)) 18818 goto mlme_global_deinit; 18819 18820 status = target_if_init(wma_get_psoc_from_scn_handle); 18821 if (QDF_IS_STATUS_ERROR(status)) 18822 goto dispatcher_deinit; 18823 18824 /* initialize non-converged components */ 18825 status = ucfg_mlme_init(); 18826 if (QDF_IS_STATUS_ERROR(status)) 18827 goto target_if_deinit; 18828 18829 status = ucfg_fwol_init(); 18830 if (QDF_IS_STATUS_ERROR(status)) 18831 goto mlme_deinit; 18832 18833 status = disa_init(); 18834 if (QDF_IS_STATUS_ERROR(status)) 18835 goto fwol_deinit; 18836 18837 status = pmo_init(); 18838 if (QDF_IS_STATUS_ERROR(status)) 18839 goto disa_deinit; 18840 18841 status = ucfg_ocb_init(); 18842 if (QDF_IS_STATUS_ERROR(status)) 18843 goto pmo_deinit; 18844 18845 status = ipa_init(); 18846 if (QDF_IS_STATUS_ERROR(status)) 18847 goto ocb_deinit; 18848 18849 status = ucfg_action_oui_init(); 18850 if (QDF_IS_STATUS_ERROR(status)) 18851 goto ipa_deinit; 18852 18853 status = nan_init(); 18854 if (QDF_IS_STATUS_ERROR(status)) 18855 goto action_oui_deinit; 18856 18857 status = ucfg_p2p_init(); 18858 if (QDF_IS_STATUS_ERROR(status)) 18859 goto nan_deinit; 18860 18861 status = ucfg_interop_issues_ap_init(); 18862 if (QDF_IS_STATUS_ERROR(status)) 18863 goto p2p_deinit; 18864 18865 status = policy_mgr_init(); 18866 if (QDF_IS_STATUS_ERROR(status)) 18867 goto interop_issues_ap_deinit; 18868 18869 status = ucfg_tdls_init(); 18870 if (QDF_IS_STATUS_ERROR(status)) 18871 goto policy_deinit; 18872 18873 status = ucfg_dlm_init(); 18874 if (QDF_IS_STATUS_ERROR(status)) 18875 goto tdls_deinit; 18876 18877 status = ucfg_pkt_capture_init(); 18878 if (QDF_IS_STATUS_ERROR(status)) 18879 goto dlm_deinit; 18880 18881 status = ucfg_ftm_time_sync_init(); 18882 if (QDF_IS_STATUS_ERROR(status)) 18883 goto pkt_capture_deinit; 18884 18885 status = ucfg_pre_cac_init(); 18886 if (QDF_IS_STATUS_ERROR(status)) 18887 goto pre_cac_deinit; 18888 18889 status = ucfg_dp_init(); 18890 if (QDF_IS_STATUS_ERROR(status)) 18891 goto pre_cac_deinit; 18892 18893 status = ucfg_qmi_init(); 18894 if (QDF_IS_STATUS_ERROR(status)) 18895 goto dp_deinit; 18896 18897 status = ucfg_ll_sap_init(); 18898 if (QDF_IS_STATUS_ERROR(status)) 18899 goto qmi_deinit; 18900 18901 status = ucfg_afc_init(); 18902 if (QDF_IS_STATUS_ERROR(status)) 18903 goto ll_sap_deinit; 18904 18905 status = hdd_mlo_mgr_register_osif_ops(); 18906 if (QDF_IS_STATUS_ERROR(status)) 18907 goto afc_deinit; 18908 18909 return QDF_STATUS_SUCCESS; 18910 18911 afc_deinit: 18912 ucfg_afc_deinit(); 18913 ll_sap_deinit: 18914 ucfg_ll_sap_deinit(); 18915 qmi_deinit: 18916 ucfg_qmi_deinit(); 18917 dp_deinit: 18918 ucfg_dp_deinit(); 18919 pre_cac_deinit: 18920 ucfg_pre_cac_deinit(); 18921 pkt_capture_deinit: 18922 ucfg_pkt_capture_deinit(); 18923 dlm_deinit: 18924 ucfg_dlm_deinit(); 18925 tdls_deinit: 18926 ucfg_tdls_deinit(); 18927 policy_deinit: 18928 policy_mgr_deinit(); 18929 interop_issues_ap_deinit: 18930 ucfg_interop_issues_ap_deinit(); 18931 p2p_deinit: 18932 ucfg_p2p_deinit(); 18933 nan_deinit: 18934 nan_deinit(); 18935 action_oui_deinit: 18936 ucfg_action_oui_deinit(); 18937 ipa_deinit: 18938 ipa_deinit(); 18939 ocb_deinit: 18940 ucfg_ocb_deinit(); 18941 pmo_deinit: 18942 pmo_deinit(); 18943 disa_deinit: 18944 disa_deinit(); 18945 fwol_deinit: 18946 ucfg_fwol_deinit(); 18947 mlme_deinit: 18948 ucfg_mlme_deinit(); 18949 target_if_deinit: 18950 target_if_deinit(); 18951 dispatcher_deinit: 18952 dispatcher_deinit(); 18953 mlme_global_deinit: 18954 ucfg_mlme_global_deinit(); 18955 18956 return status; 18957 } 18958 18959 /** 18960 * hdd_component_deinit() - Deinitialize all components 18961 * 18962 * Return: None 18963 */ 18964 static void hdd_component_deinit(void) 18965 { 18966 /* deinitialize non-converged components */ 18967 hdd_mlo_mgr_unregister_osif_ops(); 18968 ucfg_afc_deinit(); 18969 ucfg_ll_sap_deinit(); 18970 ucfg_qmi_deinit(); 18971 ucfg_dp_deinit(); 18972 ucfg_pre_cac_deinit(); 18973 ucfg_ftm_time_sync_deinit(); 18974 ucfg_pkt_capture_deinit(); 18975 ucfg_dlm_deinit(); 18976 ucfg_tdls_deinit(); 18977 policy_mgr_deinit(); 18978 ucfg_interop_issues_ap_deinit(); 18979 ucfg_p2p_deinit(); 18980 nan_deinit(); 18981 ucfg_action_oui_deinit(); 18982 ipa_deinit(); 18983 ucfg_ocb_deinit(); 18984 pmo_deinit(); 18985 disa_deinit(); 18986 ucfg_fwol_deinit(); 18987 ucfg_mlme_deinit(); 18988 18989 /* deinitialize converged components */ 18990 target_if_deinit(); 18991 dispatcher_deinit(); 18992 ucfg_mlme_global_deinit(); 18993 } 18994 18995 QDF_STATUS hdd_component_psoc_open(struct wlan_objmgr_psoc *psoc) 18996 { 18997 QDF_STATUS status; 18998 18999 status = ucfg_mlme_psoc_open(psoc); 19000 if (QDF_IS_STATUS_ERROR(status)) 19001 return status; 19002 19003 status = ucfg_dlm_psoc_open(psoc); 19004 if (QDF_IS_STATUS_ERROR(status)) 19005 goto err_dlm; 19006 19007 status = ucfg_fwol_psoc_open(psoc); 19008 if (QDF_IS_STATUS_ERROR(status)) 19009 goto err_fwol; 19010 19011 status = ucfg_pmo_psoc_open(psoc); 19012 if (QDF_IS_STATUS_ERROR(status)) 19013 goto err_pmo; 19014 19015 status = ucfg_policy_mgr_psoc_open(psoc); 19016 if (QDF_IS_STATUS_ERROR(status)) 19017 goto err_plcy_mgr; 19018 19019 status = ucfg_p2p_psoc_open(psoc); 19020 if (QDF_IS_STATUS_ERROR(status)) 19021 goto err_p2p; 19022 19023 status = ucfg_tdls_psoc_open(psoc); 19024 if (QDF_IS_STATUS_ERROR(status)) 19025 goto err_tdls; 19026 19027 status = ucfg_nan_psoc_open(psoc); 19028 if (QDF_IS_STATUS_ERROR(status)) 19029 goto err_nan; 19030 19031 status = ucfg_twt_psoc_open(psoc); 19032 if (QDF_IS_STATUS_ERROR(status)) 19033 goto err_twt; 19034 19035 status = ucfg_wifi_pos_psoc_open(psoc); 19036 if (QDF_IS_STATUS_ERROR(status)) 19037 goto err_wifi_pos; 19038 19039 status = ucfg_dp_psoc_open(psoc); 19040 if (QDF_IS_STATUS_ERROR(status)) 19041 goto err_dp; 19042 19043 return status; 19044 19045 err_dp: 19046 ucfg_wifi_pos_psoc_close(psoc); 19047 err_wifi_pos: 19048 ucfg_twt_psoc_close(psoc); 19049 err_twt: 19050 ucfg_nan_psoc_close(psoc); 19051 err_nan: 19052 ucfg_tdls_psoc_close(psoc); 19053 err_tdls: 19054 ucfg_p2p_psoc_close(psoc); 19055 err_p2p: 19056 ucfg_policy_mgr_psoc_close(psoc); 19057 err_plcy_mgr: 19058 ucfg_pmo_psoc_close(psoc); 19059 err_pmo: 19060 ucfg_fwol_psoc_close(psoc); 19061 err_fwol: 19062 ucfg_dlm_psoc_close(psoc); 19063 err_dlm: 19064 ucfg_mlme_psoc_close(psoc); 19065 19066 return status; 19067 } 19068 19069 void hdd_component_psoc_close(struct wlan_objmgr_psoc *psoc) 19070 { 19071 ucfg_dp_psoc_close(psoc); 19072 ucfg_wifi_pos_psoc_close(psoc); 19073 ucfg_twt_psoc_close(psoc); 19074 ucfg_nan_psoc_close(psoc); 19075 ucfg_tdls_psoc_close(psoc); 19076 ucfg_p2p_psoc_close(psoc); 19077 ucfg_policy_mgr_psoc_close(psoc); 19078 ucfg_pmo_psoc_close(psoc); 19079 ucfg_fwol_psoc_close(psoc); 19080 ucfg_dlm_psoc_close(psoc); 19081 ucfg_mlme_psoc_close(psoc); 19082 } 19083 19084 void hdd_component_psoc_enable(struct wlan_objmgr_psoc *psoc) 19085 { 19086 ocb_psoc_enable(psoc); 19087 disa_psoc_enable(psoc); 19088 nan_psoc_enable(psoc); 19089 p2p_psoc_enable(psoc); 19090 ucfg_interop_issues_ap_psoc_enable(psoc); 19091 policy_mgr_psoc_enable(psoc); 19092 ucfg_tdls_psoc_enable(psoc); 19093 ucfg_fwol_psoc_enable(psoc); 19094 ucfg_action_oui_psoc_enable(psoc); 19095 } 19096 19097 void hdd_component_psoc_disable(struct wlan_objmgr_psoc *psoc) 19098 { 19099 ucfg_action_oui_psoc_disable(psoc); 19100 ucfg_fwol_psoc_disable(psoc); 19101 ucfg_tdls_psoc_disable(psoc); 19102 policy_mgr_psoc_disable(psoc); 19103 ucfg_interop_issues_ap_psoc_disable(psoc); 19104 p2p_psoc_disable(psoc); 19105 nan_psoc_disable(psoc); 19106 disa_psoc_disable(psoc); 19107 ocb_psoc_disable(psoc); 19108 } 19109 19110 QDF_STATUS hdd_component_pdev_open(struct wlan_objmgr_pdev *pdev) 19111 { 19112 return ucfg_mlme_pdev_open(pdev); 19113 } 19114 19115 void hdd_component_pdev_close(struct wlan_objmgr_pdev *pdev) 19116 { 19117 ucfg_mlme_pdev_close(pdev); 19118 } 19119 19120 static QDF_STATUS hdd_qdf_print_init(void) 19121 { 19122 QDF_STATUS status; 19123 int qdf_print_idx; 19124 19125 status = qdf_print_setup(); 19126 if (QDF_IS_STATUS_ERROR(status)) { 19127 pr_err("Failed qdf_print_setup; status:%u\n", status); 19128 return status; 19129 } 19130 19131 qdf_print_idx = qdf_print_ctrl_register(cinfo, NULL, NULL, "MCL_WLAN"); 19132 if (qdf_print_idx < 0) { 19133 pr_err("Failed to register for qdf_print_ctrl\n"); 19134 return QDF_STATUS_E_FAILURE; 19135 } 19136 19137 qdf_set_pidx(qdf_print_idx); 19138 19139 return QDF_STATUS_SUCCESS; 19140 } 19141 19142 static void hdd_qdf_print_deinit(void) 19143 { 19144 int qdf_pidx = qdf_get_pidx(); 19145 19146 qdf_set_pidx(-1); 19147 qdf_print_ctrl_cleanup(qdf_pidx); 19148 19149 /* currently, no qdf print 'un-setup'*/ 19150 } 19151 19152 static QDF_STATUS hdd_qdf_init(void) 19153 { 19154 QDF_STATUS status; 19155 19156 status = hdd_qdf_print_init(); 19157 if (QDF_IS_STATUS_ERROR(status)) 19158 goto exit; 19159 19160 status = qdf_debugfs_init(); 19161 if (QDF_IS_STATUS_ERROR(status)) { 19162 hdd_err("Failed to init debugfs; status:%u", status); 19163 goto print_deinit; 19164 } 19165 19166 qdf_lock_stats_init(); 19167 qdf_mem_init(); 19168 qdf_delayed_work_feature_init(); 19169 qdf_periodic_work_feature_init(); 19170 qdf_wake_lock_feature_init(); 19171 qdf_mc_timer_manager_init(); 19172 qdf_event_list_init(); 19173 19174 status = qdf_talloc_feature_init(); 19175 if (QDF_IS_STATUS_ERROR(status)) { 19176 hdd_err("Failed to init talloc; status:%u", status); 19177 goto event_deinit; 19178 } 19179 19180 status = qdf_cpuhp_init(); 19181 if (QDF_IS_STATUS_ERROR(status)) { 19182 hdd_err("Failed to init cpuhp; status:%u", status); 19183 goto talloc_deinit; 19184 } 19185 19186 status = qdf_trace_spin_lock_init(); 19187 if (QDF_IS_STATUS_ERROR(status)) { 19188 hdd_err("Failed to init spinlock; status:%u", status); 19189 goto cpuhp_deinit; 19190 } 19191 19192 qdf_trace_init(); 19193 qdf_minidump_init(); 19194 qdf_ssr_driver_dump_init(); 19195 qdf_register_debugcb_init(); 19196 19197 return QDF_STATUS_SUCCESS; 19198 19199 cpuhp_deinit: 19200 qdf_cpuhp_deinit(); 19201 talloc_deinit: 19202 qdf_talloc_feature_deinit(); 19203 event_deinit: 19204 qdf_event_list_destroy(); 19205 qdf_mc_timer_manager_exit(); 19206 qdf_wake_lock_feature_deinit(); 19207 qdf_periodic_work_feature_deinit(); 19208 qdf_delayed_work_feature_deinit(); 19209 qdf_mem_exit(); 19210 qdf_lock_stats_deinit(); 19211 qdf_debugfs_exit(); 19212 print_deinit: 19213 hdd_qdf_print_deinit(); 19214 19215 exit: 19216 return status; 19217 } 19218 19219 static void hdd_qdf_deinit(void) 19220 { 19221 /* currently, no debugcb deinit */ 19222 qdf_ssr_driver_dump_deinit(); 19223 qdf_minidump_deinit(); 19224 qdf_trace_deinit(); 19225 19226 /* currently, no trace spinlock deinit */ 19227 19228 qdf_cpuhp_deinit(); 19229 qdf_talloc_feature_deinit(); 19230 qdf_event_list_destroy(); 19231 qdf_mc_timer_manager_exit(); 19232 qdf_wake_lock_feature_deinit(); 19233 qdf_periodic_work_feature_deinit(); 19234 qdf_delayed_work_feature_deinit(); 19235 qdf_mem_exit(); 19236 qdf_lock_stats_deinit(); 19237 qdf_debugfs_exit(); 19238 hdd_qdf_print_deinit(); 19239 } 19240 19241 #ifdef FEATURE_MONITOR_MODE_SUPPORT 19242 static bool is_monitor_mode_supported(void) 19243 { 19244 return true; 19245 } 19246 #else 19247 static bool is_monitor_mode_supported(void) 19248 { 19249 pr_err("Monitor mode not supported!"); 19250 return false; 19251 } 19252 #endif 19253 19254 #ifdef WLAN_FEATURE_EPPING 19255 static bool is_epping_mode_supported(void) 19256 { 19257 return true; 19258 } 19259 #else 19260 static bool is_epping_mode_supported(void) 19261 { 19262 pr_err("Epping mode not supported!"); 19263 return false; 19264 } 19265 #endif 19266 19267 #ifdef QCA_WIFI_FTM 19268 static bool is_ftm_mode_supported(void) 19269 { 19270 return true; 19271 } 19272 #else 19273 static bool is_ftm_mode_supported(void) 19274 { 19275 pr_err("FTM mode not supported!"); 19276 return false; 19277 } 19278 #endif 19279 19280 /** 19281 * is_con_mode_valid() - check con mode is valid or not 19282 * @mode: global con mode 19283 * 19284 * Return: TRUE on success FALSE on failure 19285 */ 19286 static bool is_con_mode_valid(enum QDF_GLOBAL_MODE mode) 19287 { 19288 switch (mode) { 19289 case QDF_GLOBAL_MONITOR_MODE: 19290 return is_monitor_mode_supported(); 19291 case QDF_GLOBAL_EPPING_MODE: 19292 return is_epping_mode_supported(); 19293 case QDF_GLOBAL_FTM_MODE: 19294 return is_ftm_mode_supported(); 19295 case QDF_GLOBAL_MISSION_MODE: 19296 return true; 19297 default: 19298 return false; 19299 } 19300 } 19301 19302 static void hdd_stop_present_mode(struct hdd_context *hdd_ctx, 19303 enum QDF_GLOBAL_MODE curr_mode) 19304 { 19305 if (hdd_ctx->driver_status == DRIVER_MODULES_CLOSED) 19306 return; 19307 19308 switch (curr_mode) { 19309 case QDF_GLOBAL_MONITOR_MODE: 19310 hdd_info("Release wakelock for monitor mode!"); 19311 qdf_wake_lock_release(&hdd_ctx->monitor_mode_wakelock, 19312 WIFI_POWER_EVENT_WAKELOCK_MONITOR_MODE); 19313 fallthrough; 19314 case QDF_GLOBAL_MISSION_MODE: 19315 case QDF_GLOBAL_FTM_MODE: 19316 hdd_abort_mac_scan_all_adapters(hdd_ctx); 19317 wlan_cfg80211_cleanup_scan_queue(hdd_ctx->pdev, NULL); 19318 hdd_stop_all_adapters(hdd_ctx); 19319 hdd_deinit_all_adapters(hdd_ctx, false); 19320 19321 break; 19322 default: 19323 break; 19324 } 19325 } 19326 19327 static void hdd_cleanup_present_mode(struct hdd_context *hdd_ctx, 19328 enum QDF_GLOBAL_MODE curr_mode) 19329 { 19330 switch (curr_mode) { 19331 case QDF_GLOBAL_MISSION_MODE: 19332 case QDF_GLOBAL_MONITOR_MODE: 19333 case QDF_GLOBAL_FTM_MODE: 19334 hdd_close_all_adapters(hdd_ctx, false); 19335 break; 19336 case QDF_GLOBAL_EPPING_MODE: 19337 epping_disable(); 19338 epping_close(); 19339 break; 19340 default: 19341 return; 19342 } 19343 } 19344 19345 static int 19346 hdd_parse_driver_mode(const char *mode_str, enum QDF_GLOBAL_MODE *out_mode) 19347 { 19348 QDF_STATUS status; 19349 uint32_t mode; 19350 19351 *out_mode = QDF_GLOBAL_MAX_MODE; 19352 19353 status = qdf_uint32_parse(mode_str, &mode); 19354 if (QDF_IS_STATUS_ERROR(status)) 19355 return qdf_status_to_os_return(status); 19356 19357 if (mode >= QDF_GLOBAL_MAX_MODE) 19358 return -ERANGE; 19359 19360 *out_mode = (enum QDF_GLOBAL_MODE)mode; 19361 19362 return 0; 19363 } 19364 19365 static int hdd_mode_change_psoc_idle_shutdown(struct device *dev) 19366 { 19367 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 19368 19369 if (!hdd_ctx) 19370 return -EINVAL; 19371 19372 return hdd_wlan_stop_modules(hdd_ctx, true); 19373 } 19374 19375 static int hdd_mode_change_psoc_idle_restart(struct device *dev) 19376 { 19377 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 19378 int ret; 19379 19380 if (!hdd_ctx) 19381 return -EINVAL; 19382 ret = hdd_soc_idle_restart_lock(dev); 19383 if (ret) 19384 return ret; 19385 ret = hdd_wlan_start_modules(hdd_ctx, false); 19386 hdd_soc_idle_restart_unlock(); 19387 19388 return ret; 19389 } 19390 19391 /** 19392 * __hdd_driver_mode_change() - Handles a driver mode change 19393 * @hdd_ctx: Pointer to the global HDD context 19394 * @next_mode: the driver mode to transition to 19395 * 19396 * This function is invoked when user updates con_mode using sys entry, 19397 * to initialize and bring-up driver in that specific mode. 19398 * 19399 * Return: Errno 19400 */ 19401 static int __hdd_driver_mode_change(struct hdd_context *hdd_ctx, 19402 enum QDF_GLOBAL_MODE next_mode) 19403 { 19404 enum QDF_GLOBAL_MODE curr_mode; 19405 int errno; 19406 struct bbm_params param = {0}; 19407 19408 hdd_info("Driver mode changing to %d", next_mode); 19409 19410 errno = wlan_hdd_validate_context(hdd_ctx); 19411 if (errno) 19412 return errno; 19413 19414 if (!is_con_mode_valid(next_mode)) { 19415 hdd_err_rl("Requested driver mode is invalid"); 19416 return -EINVAL; 19417 } 19418 19419 curr_mode = hdd_get_conparam(); 19420 if (curr_mode == next_mode) { 19421 hdd_err_rl("Driver is already in the requested mode"); 19422 return 0; 19423 } 19424 19425 hdd_psoc_idle_timer_stop(hdd_ctx); 19426 19427 /* ensure adapters are stopped */ 19428 hdd_stop_present_mode(hdd_ctx, curr_mode); 19429 19430 if (DRIVER_MODULES_CLOSED != hdd_ctx->driver_status) { 19431 is_mode_change_psoc_idle_shutdown = true; 19432 errno = pld_idle_shutdown(hdd_ctx->parent_dev, 19433 hdd_mode_change_psoc_idle_shutdown); 19434 if (errno) { 19435 is_mode_change_psoc_idle_shutdown = false; 19436 hdd_err("Stop wlan modules failed"); 19437 return errno; 19438 } 19439 } 19440 19441 /* Cleanup present mode before switching to new mode */ 19442 hdd_cleanup_present_mode(hdd_ctx, curr_mode); 19443 19444 hdd_set_conparam(next_mode); 19445 pld_set_mode(next_mode); 19446 19447 qdf_event_reset(&hdd_ctx->regulatory_update_event); 19448 qdf_mutex_acquire(&hdd_ctx->regulatory_status_lock); 19449 hdd_ctx->is_regulatory_update_in_progress = true; 19450 qdf_mutex_release(&hdd_ctx->regulatory_status_lock); 19451 19452 errno = pld_idle_restart(hdd_ctx->parent_dev, 19453 hdd_mode_change_psoc_idle_restart); 19454 if (errno) { 19455 hdd_err("Start wlan modules failed: %d", errno); 19456 return errno; 19457 } 19458 19459 errno = hdd_open_adapters_for_mode(hdd_ctx, next_mode); 19460 if (errno) { 19461 hdd_err("Failed to open adapters"); 19462 return errno; 19463 } 19464 19465 if (next_mode == QDF_GLOBAL_MONITOR_MODE) { 19466 struct hdd_adapter *adapter = 19467 hdd_get_adapter(hdd_ctx, QDF_MONITOR_MODE); 19468 19469 QDF_BUG(adapter); 19470 if (!adapter) { 19471 hdd_err("Failed to get monitor adapter"); 19472 return -EINVAL; 19473 } 19474 19475 errno = hdd_start_adapter(adapter, false); 19476 if (errno) { 19477 hdd_err("Failed to start monitor adapter"); 19478 return errno; 19479 } 19480 19481 hdd_info("Acquire wakelock for monitor mode"); 19482 qdf_wake_lock_acquire(&hdd_ctx->monitor_mode_wakelock, 19483 WIFI_POWER_EVENT_WAKELOCK_MONITOR_MODE); 19484 } 19485 19486 /* con_mode is a global module parameter */ 19487 con_mode = next_mode; 19488 hdd_info("Driver mode successfully changed to %d", next_mode); 19489 19490 param.policy = BBM_DRIVER_MODE_POLICY; 19491 param.policy_info.driver_mode = con_mode; 19492 ucfg_dp_bbm_apply_independent_policy(hdd_ctx->psoc, ¶m); 19493 19494 return 0; 19495 } 19496 19497 static int hdd_driver_mode_change(enum QDF_GLOBAL_MODE mode) 19498 { 19499 struct osif_driver_sync *driver_sync; 19500 struct hdd_context *hdd_ctx; 19501 QDF_STATUS status; 19502 int errno; 19503 19504 hdd_enter(); 19505 19506 status = osif_driver_sync_trans_start_wait(&driver_sync); 19507 if (QDF_IS_STATUS_ERROR(status)) { 19508 hdd_err("Failed to start 'mode change'; status:%u", status); 19509 errno = qdf_status_to_os_return(status); 19510 goto exit; 19511 } 19512 19513 osif_driver_sync_wait_for_ops(driver_sync); 19514 19515 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 19516 errno = wlan_hdd_validate_context(hdd_ctx); 19517 if (errno) 19518 goto trans_stop; 19519 19520 errno = __hdd_driver_mode_change(hdd_ctx, mode); 19521 19522 trans_stop: 19523 osif_driver_sync_trans_stop(driver_sync); 19524 19525 exit: 19526 hdd_exit(); 19527 19528 return errno; 19529 } 19530 19531 static int hdd_set_con_mode(enum QDF_GLOBAL_MODE mode) 19532 { 19533 con_mode = mode; 19534 19535 return 0; 19536 } 19537 19538 static int (*hdd_set_con_mode_cb)(enum QDF_GLOBAL_MODE mode) = hdd_set_con_mode; 19539 19540 static void hdd_driver_mode_change_register(void) 19541 { 19542 hdd_set_con_mode_cb = hdd_driver_mode_change; 19543 } 19544 19545 static void hdd_driver_mode_change_unregister(void) 19546 { 19547 hdd_set_con_mode_cb = hdd_set_con_mode; 19548 } 19549 19550 static int con_mode_handler(const char *kmessage, const struct kernel_param *kp) 19551 { 19552 enum QDF_GLOBAL_MODE mode; 19553 int errno; 19554 19555 errno = hdd_parse_driver_mode(kmessage, &mode); 19556 if (errno) { 19557 hdd_err_rl("Failed to parse driver mode '%s'", kmessage); 19558 return errno; 19559 } 19560 19561 return hdd_set_con_mode_cb(mode); 19562 } 19563 19564 /* 19565 * If the wlan_hdd_register_driver will return an error 19566 * if the wlan driver tries to register with the 19567 * platform driver before cnss_probe is completed. 19568 * Depending on the error code, the wlan driver waits 19569 * and retries to register. 19570 */ 19571 19572 /* Max number of retries (arbitrary)*/ 19573 #define HDD_MAX_PLD_REGISTER_RETRY (50) 19574 19575 /* Max amount of time we sleep before each retry */ 19576 #define HDD_PLD_REGISTER_FAIL_SLEEP_DURATION (100) 19577 19578 static int hdd_register_driver_retry(void) 19579 { 19580 int count = 0; 19581 int errno; 19582 19583 while (true) { 19584 errno = wlan_hdd_register_driver(); 19585 if (errno != -EAGAIN) 19586 return errno; 19587 hdd_nofl_info("Retry Platform Driver Registration; errno:%d count:%d", 19588 errno, count); 19589 if (++count == HDD_MAX_PLD_REGISTER_RETRY) 19590 return errno; 19591 msleep(HDD_PLD_REGISTER_FAIL_SLEEP_DURATION); 19592 continue; 19593 } 19594 19595 return errno; 19596 } 19597 19598 /** 19599 * hdd_create_wifi_feature_interface() - Create wifi feature interface 19600 * 19601 * Return: none 19602 */ 19603 static void hdd_create_wifi_feature_interface(void) 19604 { 19605 hdd_sysfs_create_wifi_root_obj(); 19606 hdd_create_wifi_feature_interface_sysfs_file(); 19607 } 19608 19609 int hdd_driver_load(void) 19610 { 19611 struct osif_driver_sync *driver_sync; 19612 QDF_STATUS status; 19613 int errno; 19614 bool soft_load; 19615 19616 pr_info("%s: Loading driver v%s\n", WLAN_MODULE_NAME, 19617 g_wlan_driver_version); 19618 hdd_place_marker(NULL, "START LOADING", NULL); 19619 19620 status = hdd_qdf_init(); 19621 if (QDF_IS_STATUS_ERROR(status)) { 19622 errno = qdf_status_to_os_return(status); 19623 goto exit; 19624 } 19625 19626 osif_sync_init(); 19627 19628 status = osif_driver_sync_create_and_trans(&driver_sync); 19629 if (QDF_IS_STATUS_ERROR(status)) { 19630 hdd_err("Failed to init driver sync; status:%u", status); 19631 errno = qdf_status_to_os_return(status); 19632 goto sync_deinit; 19633 } 19634 19635 errno = hdd_init(); 19636 if (errno) { 19637 hdd_err("Failed to init HDD; errno:%d", errno); 19638 goto trans_stop; 19639 } 19640 19641 status = hdd_component_cb_init(); 19642 if (QDF_IS_STATUS_ERROR(status)) { 19643 hdd_err("Failed to init component cb; status:%u", status); 19644 errno = qdf_status_to_os_return(status); 19645 goto hdd_deinit; 19646 } 19647 19648 status = hdd_component_init(); 19649 if (QDF_IS_STATUS_ERROR(status)) { 19650 hdd_err("Failed to init components; status:%u", status); 19651 errno = qdf_status_to_os_return(status); 19652 goto comp_cb_deinit; 19653 } 19654 19655 status = qdf_wake_lock_create(&wlan_wake_lock, "wlan"); 19656 if (QDF_IS_STATUS_ERROR(status)) { 19657 hdd_err("Failed to create wake lock; status:%u", status); 19658 errno = qdf_status_to_os_return(status); 19659 goto comp_deinit; 19660 } 19661 19662 hdd_set_conparam(con_mode); 19663 19664 errno = pld_init(); 19665 if (errno) { 19666 hdd_err("Failed to init PLD; errno:%d", errno); 19667 goto wakelock_destroy; 19668 } 19669 19670 /* driver mode pass to cnss2 platform driver*/ 19671 errno = pld_set_mode(con_mode); 19672 if (errno) 19673 hdd_err("Failed to set mode in PLD; errno:%d", errno); 19674 19675 hdd_driver_mode_change_register(); 19676 19677 osif_driver_sync_register(driver_sync); 19678 osif_driver_sync_trans_stop(driver_sync); 19679 19680 /* psoc probe can happen in registration; do after 'load' transition */ 19681 errno = hdd_register_driver_retry(); 19682 if (errno) { 19683 hdd_err("Failed to register driver; errno:%d", errno); 19684 goto pld_deinit; 19685 } 19686 19687 /* If a soft unload of driver is done, we don't call 19688 * wlan_hdd_state_ctrl_param_destroy() to maintain sync 19689 * with userspace. In Symmetry, during soft load, avoid 19690 * calling wlan_hdd_state_ctrl_param_create(). 19691 */ 19692 soft_load = hdd_get_wlan_driver_status(); 19693 if (soft_load) 19694 goto out; 19695 19696 errno = wlan_hdd_state_ctrl_param_create(); 19697 if (errno) { 19698 hdd_err("Failed to create ctrl param; errno:%d", errno); 19699 goto unregister_driver; 19700 } 19701 hdd_create_wifi_feature_interface(); 19702 out: 19703 hdd_debug("%s: driver loaded", WLAN_MODULE_NAME); 19704 hdd_place_marker(NULL, "DRIVER LOADED", NULL); 19705 19706 return 0; 19707 19708 unregister_driver: 19709 wlan_hdd_unregister_driver(); 19710 pld_deinit: 19711 status = osif_driver_sync_trans_start(&driver_sync); 19712 QDF_BUG(QDF_IS_STATUS_SUCCESS(status)); 19713 19714 osif_driver_sync_unregister(); 19715 if (driver_sync) 19716 osif_driver_sync_wait_for_ops(driver_sync); 19717 19718 hdd_driver_mode_change_unregister(); 19719 pld_deinit(); 19720 19721 hdd_start_complete(errno); 19722 /* Wait for any ref taken on /dev/wlan to be released */ 19723 while (qdf_atomic_read(&wlan_hdd_state_fops_ref)) 19724 ; 19725 wakelock_destroy: 19726 qdf_wake_lock_destroy(&wlan_wake_lock); 19727 comp_deinit: 19728 hdd_component_deinit(); 19729 comp_cb_deinit: 19730 hdd_component_cb_deinit(); 19731 hdd_deinit: 19732 hdd_deinit(); 19733 trans_stop: 19734 if (driver_sync) { 19735 osif_driver_sync_trans_stop(driver_sync); 19736 osif_driver_sync_destroy(driver_sync); 19737 } 19738 sync_deinit: 19739 osif_sync_deinit(); 19740 hdd_qdf_deinit(); 19741 19742 exit: 19743 return errno; 19744 } 19745 19746 #ifdef FEATURE_WLAN_RESIDENT_DRIVER 19747 EXPORT_SYMBOL(hdd_driver_load); 19748 #endif 19749 19750 /** 19751 * hdd_distroy_wifi_feature_interface() - Distroy wifi feature interface 19752 * 19753 * Return: none 19754 */ 19755 static void hdd_distroy_wifi_feature_interface(void) 19756 { 19757 hdd_destroy_wifi_feature_interface_sysfs_file(); 19758 hdd_sysfs_destroy_wifi_root_obj(); 19759 } 19760 19761 void hdd_driver_unload(void) 19762 { 19763 struct osif_driver_sync *driver_sync; 19764 struct hdd_context *hdd_ctx; 19765 QDF_STATUS status; 19766 void *hif_ctx; 19767 bool soft_unload; 19768 19769 soft_unload = hdd_get_wlan_driver_status(); 19770 if (soft_unload) { 19771 pr_info("%s: Soft Unloading driver v%s\n", WLAN_MODULE_NAME, 19772 QWLAN_VERSIONSTR); 19773 } else { 19774 pr_info("%s: Hard Unloading driver v%s\n", WLAN_MODULE_NAME, 19775 QWLAN_VERSIONSTR); 19776 } 19777 19778 hdd_place_marker(NULL, "START UNLOADING", NULL); 19779 19780 /* 19781 * Wait for any trans to complete and then start the driver trans 19782 * for the unload. This will ensure that the driver trans proceeds only 19783 * after all trans have been completed. As a part of this trans, set 19784 * the driver load/unload flag to further ensure that any upcoming 19785 * trans are rejected via wlan_hdd_validate_context. 19786 */ 19787 status = osif_driver_sync_trans_start_wait(&driver_sync); 19788 QDF_BUG(QDF_IS_STATUS_SUCCESS(status)); 19789 if (QDF_IS_STATUS_ERROR(status)) { 19790 hdd_err("Unable to unload wlan; status:%u", status); 19791 hdd_place_marker(NULL, "UNLOAD FAILURE", NULL); 19792 return; 19793 } 19794 19795 hif_ctx = cds_get_context(QDF_MODULE_ID_HIF); 19796 if (hif_ctx) { 19797 /* 19798 * Trigger runtime sync resume before setting unload in progress 19799 * such that resume can happen successfully 19800 */ 19801 qdf_rtpm_sync_resume(); 19802 } 19803 19804 cds_set_driver_loaded(false); 19805 cds_set_unload_in_progress(true); 19806 19807 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 19808 if (hdd_ctx) { 19809 hdd_psoc_idle_timer_stop(hdd_ctx); 19810 /* 19811 * Runtime PM sync resume may have started the bus bandwidth 19812 * periodic work hence stop it. 19813 */ 19814 ucfg_dp_bus_bw_compute_timer_stop(hdd_ctx->psoc); 19815 } 19816 19817 /* 19818 * Stop the trans before calling unregister_driver as that involves a 19819 * call to pld_remove which in itself is a psoc transaction 19820 */ 19821 osif_driver_sync_trans_stop(driver_sync); 19822 19823 hdd_distroy_wifi_feature_interface(); 19824 if (!soft_unload) 19825 wlan_hdd_state_ctrl_param_destroy(); 19826 19827 /* trigger SoC remove */ 19828 wlan_hdd_unregister_driver(); 19829 19830 status = osif_driver_sync_trans_start_wait(&driver_sync); 19831 QDF_BUG(QDF_IS_STATUS_SUCCESS(status)); 19832 if (QDF_IS_STATUS_ERROR(status)) { 19833 hdd_err("Unable to unload wlan; status:%u", status); 19834 hdd_place_marker(NULL, "UNLOAD FAILURE", NULL); 19835 return; 19836 } 19837 19838 osif_driver_sync_unregister(); 19839 osif_driver_sync_wait_for_ops(driver_sync); 19840 19841 hdd_driver_mode_change_unregister(); 19842 pld_deinit(); 19843 hdd_set_conparam(0); 19844 qdf_wake_lock_destroy(&wlan_wake_lock); 19845 hdd_component_deinit(); 19846 hdd_component_cb_deinit(); 19847 hdd_deinit(); 19848 19849 osif_driver_sync_trans_stop(driver_sync); 19850 osif_driver_sync_destroy(driver_sync); 19851 19852 osif_sync_deinit(); 19853 19854 hdd_qdf_deinit(); 19855 hdd_place_marker(NULL, "UNLOAD DONE", NULL); 19856 } 19857 19858 #ifdef FEATURE_WLAN_RESIDENT_DRIVER 19859 EXPORT_SYMBOL(hdd_driver_unload); 19860 #endif 19861 19862 #ifndef MODULE 19863 /** 19864 * wlan_boot_cb() - Wlan boot callback 19865 * @kobj: object whose directory we're creating the link in. 19866 * @attr: attribute the user is interacting with 19867 * @buf: the buffer containing the user data 19868 * @count: number of bytes in the buffer 19869 * 19870 * This callback is invoked when the fs is ready to start the 19871 * wlan driver initialization. 19872 * 19873 * Return: 'count' on success or a negative error code in case of failure 19874 */ 19875 static ssize_t wlan_boot_cb(struct kobject *kobj, 19876 struct kobj_attribute *attr, 19877 const char *buf, 19878 size_t count) 19879 { 19880 19881 if (wlan_loader->loaded_state) { 19882 hdd_err("wlan driver already initialized"); 19883 return -EALREADY; 19884 } 19885 19886 if (hdd_driver_load()) 19887 return -EIO; 19888 19889 wlan_loader->loaded_state = MODULE_INITIALIZED; 19890 19891 return count; 19892 } 19893 19894 /** 19895 * hdd_sysfs_cleanup() - cleanup sysfs 19896 * 19897 * Return: None 19898 * 19899 */ 19900 static void hdd_sysfs_cleanup(void) 19901 { 19902 /* remove from group */ 19903 if (wlan_loader->boot_wlan_obj && wlan_loader->attr_group) 19904 sysfs_remove_group(wlan_loader->boot_wlan_obj, 19905 wlan_loader->attr_group); 19906 19907 /* unlink the object from parent */ 19908 kobject_del(wlan_loader->boot_wlan_obj); 19909 19910 /* free the object */ 19911 kobject_put(wlan_loader->boot_wlan_obj); 19912 19913 kfree(wlan_loader->attr_group); 19914 kfree(wlan_loader); 19915 19916 wlan_loader = NULL; 19917 } 19918 19919 /** 19920 * wlan_init_sysfs() - Creates the sysfs to be invoked when the fs is 19921 * ready 19922 * 19923 * This is creates the syfs entry boot_wlan. Which shall be invoked 19924 * when the filesystem is ready. 19925 * 19926 * QDF API cannot be used here since this function is called even before 19927 * initializing WLAN driver. 19928 * 19929 * Return: 0 for success, errno on failure 19930 */ 19931 static int wlan_init_sysfs(void) 19932 { 19933 int ret = -ENOMEM; 19934 19935 wlan_loader = kzalloc(sizeof(*wlan_loader), GFP_KERNEL); 19936 if (!wlan_loader) 19937 return -ENOMEM; 19938 19939 wlan_loader->boot_wlan_obj = NULL; 19940 wlan_loader->attr_group = kzalloc(sizeof(*(wlan_loader->attr_group)), 19941 GFP_KERNEL); 19942 if (!wlan_loader->attr_group) 19943 goto error_return; 19944 19945 wlan_loader->loaded_state = 0; 19946 wlan_loader->attr_group->attrs = attrs; 19947 19948 wlan_loader->boot_wlan_obj = kobject_create_and_add(WLAN_LOADER_NAME, 19949 kernel_kobj); 19950 if (!wlan_loader->boot_wlan_obj) { 19951 hdd_err("sysfs create and add failed"); 19952 goto error_return; 19953 } 19954 19955 ret = sysfs_create_group(wlan_loader->boot_wlan_obj, 19956 wlan_loader->attr_group); 19957 if (ret) { 19958 hdd_err("sysfs create group failed; errno:%d", ret); 19959 goto error_return; 19960 } 19961 19962 return 0; 19963 19964 error_return: 19965 hdd_sysfs_cleanup(); 19966 19967 return ret; 19968 } 19969 19970 /** 19971 * wlan_deinit_sysfs() - Removes the sysfs created to initialize the wlan 19972 * 19973 * Return: 0 on success or errno on failure 19974 */ 19975 static int wlan_deinit_sysfs(void) 19976 { 19977 if (!wlan_loader) { 19978 hdd_err("wlan_loader is null"); 19979 return -EINVAL; 19980 } 19981 19982 hdd_sysfs_cleanup(); 19983 return 0; 19984 } 19985 19986 #endif /* MODULE */ 19987 19988 #ifdef MODULE 19989 /** 19990 * hdd_module_init() - Module init helper 19991 * 19992 * Module init helper function used by both module and static driver. 19993 * 19994 * Return: 0 for success, errno on failure 19995 */ 19996 #ifdef FEATURE_WLAN_RESIDENT_DRIVER 19997 static int hdd_module_init(void) 19998 { 19999 return 0; 20000 } 20001 #else 20002 static int hdd_module_init(void) 20003 { 20004 if (hdd_driver_load()) 20005 return -EINVAL; 20006 20007 return 0; 20008 } 20009 #endif 20010 #else 20011 static int __init hdd_module_init(void) 20012 { 20013 int ret = -EINVAL; 20014 20015 ret = wlan_init_sysfs(); 20016 if (ret) 20017 hdd_err("Failed to create sysfs entry"); 20018 20019 return ret; 20020 } 20021 #endif 20022 20023 20024 #ifdef MODULE 20025 /** 20026 * hdd_module_exit() - Exit function 20027 * 20028 * This is the driver exit point (invoked when module is unloaded using rmmod) 20029 * 20030 * Return: None 20031 */ 20032 #ifdef FEATURE_WLAN_RESIDENT_DRIVER 20033 static void __exit hdd_module_exit(void) 20034 { 20035 } 20036 #else 20037 static void __exit hdd_module_exit(void) 20038 { 20039 hdd_driver_unload(); 20040 } 20041 #endif 20042 #else 20043 static void __exit hdd_module_exit(void) 20044 { 20045 hdd_driver_unload(); 20046 wlan_deinit_sysfs(); 20047 } 20048 #endif 20049 20050 static int fwpath_changed_handler(const char *kmessage, 20051 const struct kernel_param *kp) 20052 { 20053 return param_set_copystring(kmessage, kp); 20054 } 20055 20056 static int con_mode_handler_ftm(const char *kmessage, 20057 const struct kernel_param *kp) 20058 { 20059 int ret; 20060 20061 ret = param_set_int(kmessage, kp); 20062 20063 if (cds_is_driver_loaded() || cds_is_load_or_unload_in_progress()) { 20064 pr_err("Driver already loaded or load/unload in progress"); 20065 return -ENOTSUPP; 20066 } 20067 20068 if (con_mode_ftm != QDF_GLOBAL_FTM_MODE) { 20069 pr_err("Only FTM mode supported!"); 20070 return -ENOTSUPP; 20071 } 20072 20073 hdd_set_conparam(con_mode_ftm); 20074 con_mode = con_mode_ftm; 20075 20076 return ret; 20077 } 20078 20079 #ifdef WLAN_FEATURE_EPPING 20080 static int con_mode_handler_epping(const char *kmessage, 20081 const struct kernel_param *kp) 20082 { 20083 int ret; 20084 20085 ret = param_set_int(kmessage, kp); 20086 20087 if (con_mode_epping != QDF_GLOBAL_EPPING_MODE) { 20088 pr_err("Only EPPING mode supported!"); 20089 return -ENOTSUPP; 20090 } 20091 20092 hdd_set_conparam(con_mode_epping); 20093 con_mode = con_mode_epping; 20094 20095 return ret; 20096 } 20097 #endif 20098 20099 /** 20100 * hdd_get_conparam() - driver exit point 20101 * 20102 * This is the driver exit point (invoked when module is unloaded using rmmod) 20103 * 20104 * Return: enum QDF_GLOBAL_MODE 20105 */ 20106 enum QDF_GLOBAL_MODE hdd_get_conparam(void) 20107 { 20108 return (enum QDF_GLOBAL_MODE) curr_con_mode; 20109 } 20110 20111 void hdd_set_conparam(int32_t con_param) 20112 { 20113 curr_con_mode = con_param; 20114 } 20115 20116 /** 20117 * hdd_svc_fw_crashed_ind() - API to send FW CRASHED IND to Userspace 20118 * 20119 * Return: void 20120 */ 20121 static void hdd_svc_fw_crashed_ind(void) 20122 { 20123 struct hdd_context *hdd_ctx; 20124 20125 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 20126 20127 hdd_ctx ? wlan_hdd_send_svc_nlink_msg(hdd_ctx->radio_index, 20128 WLAN_SVC_FW_CRASHED_IND, 20129 NULL, 0) : 0; 20130 } 20131 20132 /** 20133 * hdd_update_ol_config - API to update ol configuration parameters 20134 * @hdd_ctx: HDD context 20135 * 20136 * Return: void 20137 */ 20138 static void hdd_update_ol_config(struct hdd_context *hdd_ctx) 20139 { 20140 struct ol_config_info cfg = {0}; 20141 struct ol_context *ol_ctx = cds_get_context(QDF_MODULE_ID_BMI); 20142 bool self_recovery = false; 20143 QDF_STATUS status; 20144 20145 if (!ol_ctx) 20146 return; 20147 20148 status = ucfg_mlme_get_self_recovery(hdd_ctx->psoc, &self_recovery); 20149 if (QDF_IS_STATUS_ERROR(status)) 20150 hdd_err("Failed to get self recovery ini config"); 20151 20152 cfg.enable_self_recovery = self_recovery; 20153 cfg.enable_uart_print = hdd_ctx->config->enablefwprint; 20154 cfg.enable_fw_log = hdd_ctx->config->enable_fw_log; 20155 cfg.enable_ramdump_collection = hdd_ctx->config->is_ramdump_enabled; 20156 cfg.enable_lpass_support = hdd_lpass_is_supported(hdd_ctx); 20157 20158 ol_init_ini_config(ol_ctx, &cfg); 20159 ol_set_fw_crashed_cb(ol_ctx, hdd_svc_fw_crashed_ind); 20160 } 20161 20162 #ifdef FEATURE_RUNTIME_PM 20163 /** 20164 * hdd_populate_runtime_cfg() - populate runtime configuration 20165 * @hdd_ctx: hdd context 20166 * @cfg: pointer to the configuration memory being populated 20167 * 20168 * Return: void 20169 */ 20170 static void hdd_populate_runtime_cfg(struct hdd_context *hdd_ctx, 20171 struct hif_config_info *cfg) 20172 { 20173 cfg->enable_runtime_pm = hdd_ctx->config->runtime_pm; 20174 cfg->runtime_pm_delay = 20175 ucfg_pmo_get_runtime_pm_delay(hdd_ctx->psoc); 20176 } 20177 #else 20178 static void hdd_populate_runtime_cfg(struct hdd_context *hdd_ctx, 20179 struct hif_config_info *cfg) 20180 { 20181 } 20182 #endif 20183 20184 /** 20185 * hdd_update_hif_config - API to update HIF configuration parameters 20186 * @hdd_ctx: HDD Context 20187 * 20188 * Return: void 20189 */ 20190 static void hdd_update_hif_config(struct hdd_context *hdd_ctx) 20191 { 20192 struct hif_opaque_softc *scn = cds_get_context(QDF_MODULE_ID_HIF); 20193 struct hif_config_info cfg = {0}; 20194 bool prevent_link_down = false; 20195 bool self_recovery = false; 20196 QDF_STATUS status; 20197 20198 if (!scn) 20199 return; 20200 20201 status = ucfg_mlme_get_prevent_link_down(hdd_ctx->psoc, 20202 &prevent_link_down); 20203 if (QDF_IS_STATUS_ERROR(status)) 20204 hdd_err("Failed to get prevent_link_down config"); 20205 20206 status = ucfg_mlme_get_self_recovery(hdd_ctx->psoc, &self_recovery); 20207 if (QDF_IS_STATUS_ERROR(status)) 20208 hdd_err("Failed to get self recovery ini config"); 20209 20210 cfg.enable_self_recovery = self_recovery; 20211 hdd_populate_runtime_cfg(hdd_ctx, &cfg); 20212 cfg.rx_softirq_max_yield_duration_ns = 20213 ucfg_dp_get_rx_softirq_yield_duration(hdd_ctx->psoc); 20214 20215 hif_init_ini_config(scn, &cfg); 20216 20217 if (prevent_link_down) 20218 hif_vote_link_up(scn); 20219 } 20220 20221 /** 20222 * hdd_update_dp_config() - Propagate config parameters to Lithium 20223 * datapath 20224 * @hdd_ctx: HDD Context 20225 * 20226 * Return: 0 for success/errno for failure 20227 */ 20228 static int hdd_update_dp_config(struct hdd_context *hdd_ctx) 20229 { 20230 struct wlan_dp_user_config dp_cfg; 20231 QDF_STATUS status; 20232 20233 dp_cfg.ipa_enable = ucfg_ipa_is_enabled(); 20234 dp_cfg.arp_connectivity_map = CONNECTIVITY_CHECK_SET_ARP; 20235 20236 status = ucfg_dp_update_config(hdd_ctx->psoc, &dp_cfg); 20237 if (status != QDF_STATUS_SUCCESS) { 20238 hdd_err("failed DP PSOC configuration update"); 20239 return -EINVAL; 20240 } 20241 20242 return 0; 20243 } 20244 20245 /** 20246 * hdd_update_config() - Initialize driver per module ini parameters 20247 * @hdd_ctx: HDD Context 20248 * 20249 * API is used to initialize all driver per module configuration parameters 20250 * Return: 0 for success, errno for failure 20251 */ 20252 int hdd_update_config(struct hdd_context *hdd_ctx) 20253 { 20254 int ret; 20255 20256 if (ucfg_pmo_is_ns_offloaded(hdd_ctx->psoc)) 20257 hdd_ctx->ns_offload_enable = true; 20258 20259 hdd_update_ol_config(hdd_ctx); 20260 hdd_update_hif_config(hdd_ctx); 20261 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) 20262 ret = hdd_update_cds_config_ftm(hdd_ctx); 20263 else 20264 ret = hdd_update_cds_config(hdd_ctx); 20265 ret = hdd_update_user_config(hdd_ctx); 20266 20267 hdd_update_regdb_offload_config(hdd_ctx); 20268 20269 return ret; 20270 } 20271 20272 /** 20273 * hdd_update_pmo_config - API to update pmo configuration parameters 20274 * @hdd_ctx: HDD context 20275 * 20276 * Return: void 20277 */ 20278 static int hdd_update_pmo_config(struct hdd_context *hdd_ctx) 20279 { 20280 struct pmo_psoc_cfg psoc_cfg = {0}; 20281 QDF_STATUS status; 20282 enum pmo_wow_enable_type wow_enable; 20283 20284 ucfg_pmo_get_psoc_config(hdd_ctx->psoc, &psoc_cfg); 20285 20286 /* 20287 * Value of hdd_ctx->wowEnable can be, 20288 * 0 - Disable both magic pattern match and pattern byte match. 20289 * 1 - Enable magic pattern match on all interfaces. 20290 * 2 - Enable pattern byte match on all interfaces. 20291 * 3 - Enable both magic pattern and pattern byte match on 20292 * all interfaces. 20293 */ 20294 wow_enable = ucfg_pmo_get_wow_enable(hdd_ctx->psoc); 20295 psoc_cfg.magic_ptrn_enable = (wow_enable & 0x01) ? true : false; 20296 psoc_cfg.ptrn_match_enable_all_vdev = 20297 (wow_enable & 0x02) ? true : false; 20298 psoc_cfg.ap_arpns_support = hdd_ctx->ap_arpns_support; 20299 psoc_cfg.d0_wow_supported = wma_d0_wow_is_supported(); 20300 ucfg_mlme_get_sap_max_modulated_dtim(hdd_ctx->psoc, 20301 &psoc_cfg.sta_max_li_mod_dtim); 20302 20303 hdd_lpass_populate_pmo_config(&psoc_cfg, hdd_ctx); 20304 20305 status = ucfg_pmo_update_psoc_config(hdd_ctx->psoc, &psoc_cfg); 20306 if (QDF_IS_STATUS_ERROR(status)) 20307 hdd_err("failed pmo psoc configuration; status:%d", status); 20308 20309 return qdf_status_to_os_return(status); 20310 } 20311 20312 void hdd_update_ie_allowlist_attr(struct probe_req_allowlist_attr *ie_allowlist, 20313 struct hdd_context *hdd_ctx) 20314 { 20315 struct wlan_fwol_ie_allowlist allowlist = {0}; 20316 struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc; 20317 QDF_STATUS status; 20318 bool is_ie_allowlist_enable = false; 20319 uint8_t i = 0; 20320 20321 status = ucfg_fwol_get_ie_allowlist(psoc, &is_ie_allowlist_enable); 20322 if (QDF_IS_STATUS_ERROR(status)) { 20323 hdd_err("Unable to get IE allowlist param"); 20324 return; 20325 } 20326 20327 ie_allowlist->allow_list = is_ie_allowlist_enable; 20328 if (!ie_allowlist->allow_list) 20329 return; 20330 20331 status = ucfg_fwol_get_all_allowlist_params(psoc, &allowlist); 20332 if (QDF_IS_STATUS_ERROR(status)) { 20333 hdd_err("Unable to get all allowlist params"); 20334 return; 20335 } 20336 20337 ie_allowlist->ie_bitmap[0] = allowlist.ie_bitmap_0; 20338 ie_allowlist->ie_bitmap[1] = allowlist.ie_bitmap_1; 20339 ie_allowlist->ie_bitmap[2] = allowlist.ie_bitmap_2; 20340 ie_allowlist->ie_bitmap[3] = allowlist.ie_bitmap_3; 20341 ie_allowlist->ie_bitmap[4] = allowlist.ie_bitmap_4; 20342 ie_allowlist->ie_bitmap[5] = allowlist.ie_bitmap_5; 20343 ie_allowlist->ie_bitmap[6] = allowlist.ie_bitmap_6; 20344 ie_allowlist->ie_bitmap[7] = allowlist.ie_bitmap_7; 20345 20346 ie_allowlist->num_vendor_oui = allowlist.no_of_probe_req_ouis; 20347 for (i = 0; i < ie_allowlist->num_vendor_oui; i++) 20348 ie_allowlist->voui[i] = allowlist.probe_req_voui[i]; 20349 } 20350 20351 QDF_STATUS hdd_update_score_config(struct hdd_context *hdd_ctx) 20352 { 20353 struct hdd_config *cfg = hdd_ctx->config; 20354 eCsrPhyMode phy_mode = hdd_cfg_xlate_to_csr_phy_mode(cfg->dot11Mode); 20355 20356 sme_update_score_config(hdd_ctx->mac_handle, phy_mode, 20357 hdd_ctx->num_rf_chains); 20358 20359 return QDF_STATUS_SUCCESS; 20360 } 20361 20362 /** 20363 * hdd_update_dfs_config() - API to update dfs configuration parameters. 20364 * @hdd_ctx: HDD context 20365 * 20366 * Return: 0 if success else err 20367 */ 20368 static int hdd_update_dfs_config(struct hdd_context *hdd_ctx) 20369 { 20370 struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc; 20371 struct dfs_user_config dfs_cfg = {0}; 20372 QDF_STATUS status; 20373 20374 ucfg_mlme_get_dfs_filter_offload(hdd_ctx->psoc, 20375 &dfs_cfg.dfs_is_phyerr_filter_offload); 20376 status = ucfg_dfs_update_config(psoc, &dfs_cfg); 20377 if (QDF_IS_STATUS_ERROR(status)) { 20378 hdd_err("failed dfs psoc configuration"); 20379 return -EINVAL; 20380 } 20381 20382 return 0; 20383 } 20384 20385 /** 20386 * hdd_update_scan_config - API to update scan configuration parameters 20387 * @hdd_ctx: HDD context 20388 * 20389 * Return: 0 if success else err 20390 */ 20391 int hdd_update_scan_config(struct hdd_context *hdd_ctx) 20392 { 20393 struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc; 20394 struct scan_user_cfg scan_cfg; 20395 QDF_STATUS status; 20396 uint32_t mcast_mcc_rest_time = 0; 20397 20398 qdf_mem_zero(&scan_cfg, sizeof(scan_cfg)); 20399 status = ucfg_mlme_get_sta_miracast_mcc_rest_time(hdd_ctx->psoc, 20400 &mcast_mcc_rest_time); 20401 if (!QDF_IS_STATUS_SUCCESS(status)) { 20402 hdd_err("ucfg_mlme_get_sta_miracast_mcc_rest_time, use def"); 20403 return -EIO; 20404 } 20405 scan_cfg.sta_miracast_mcc_rest_time = mcast_mcc_rest_time; 20406 hdd_update_ie_allowlist_attr(&scan_cfg.ie_allowlist, hdd_ctx); 20407 20408 status = ucfg_scan_update_user_config(psoc, &scan_cfg); 20409 if (status != QDF_STATUS_SUCCESS) { 20410 hdd_err("failed pmo psoc configuration"); 20411 return -EINVAL; 20412 } 20413 20414 return 0; 20415 } 20416 20417 int hdd_update_components_config(struct hdd_context *hdd_ctx) 20418 { 20419 int ret; 20420 20421 ret = hdd_update_pmo_config(hdd_ctx); 20422 if (ret) 20423 return ret; 20424 20425 ret = hdd_update_scan_config(hdd_ctx); 20426 if (ret) 20427 return ret; 20428 20429 ret = hdd_update_tdls_config(hdd_ctx); 20430 if (ret) 20431 return ret; 20432 20433 ret = hdd_update_dp_config(hdd_ctx); 20434 if (ret) 20435 return ret; 20436 20437 ret = hdd_update_dfs_config(hdd_ctx); 20438 if (ret) 20439 return ret; 20440 20441 ret = hdd_update_regulatory_config(hdd_ctx); 20442 if (ret) 20443 return ret; 20444 20445 return ret; 20446 } 20447 20448 /** 20449 * wlan_hdd_get_dfs_mode() - get ACS DFS mode 20450 * @mode : cfg80211 DFS mode 20451 * 20452 * Return: return SAP ACS DFS mode else return ACS_DFS_MODE_NONE 20453 */ 20454 enum sap_acs_dfs_mode wlan_hdd_get_dfs_mode(enum dfs_mode mode) 20455 { 20456 switch (mode) { 20457 case DFS_MODE_ENABLE: 20458 return ACS_DFS_MODE_ENABLE; 20459 case DFS_MODE_DISABLE: 20460 return ACS_DFS_MODE_DISABLE; 20461 case DFS_MODE_DEPRIORITIZE: 20462 return ACS_DFS_MODE_DEPRIORITIZE; 20463 default: 20464 hdd_debug("ACS dfs mode is NONE"); 20465 return ACS_DFS_MODE_NONE; 20466 } 20467 } 20468 20469 /** 20470 * hdd_enable_disable_ca_event() - enable/disable channel avoidance event 20471 * @hdd_ctx: pointer to hdd context 20472 * @set_value: enable/disable 20473 * 20474 * When Host sends vendor command enable, FW will send *ONE* CA ind to 20475 * Host(even though it is duplicate). When Host send vendor command 20476 * disable,FW doesn't perform any action. Whenever any change in 20477 * CA *and* WLAN is in SAP/P2P-GO mode, FW sends CA ind to host. 20478 * 20479 * return - 0 on success, appropriate error values on failure. 20480 */ 20481 int hdd_enable_disable_ca_event(struct hdd_context *hdd_ctx, uint8_t set_value) 20482 { 20483 QDF_STATUS status; 20484 20485 if (0 != wlan_hdd_validate_context(hdd_ctx)) 20486 return -EAGAIN; 20487 20488 status = sme_enable_disable_chanavoidind_event(hdd_ctx->mac_handle, 20489 set_value); 20490 if (!QDF_IS_STATUS_SUCCESS(status)) { 20491 hdd_err("Failed to send chan avoid command to SME"); 20492 return -EINVAL; 20493 } 20494 return 0; 20495 } 20496 20497 bool hdd_is_roaming_in_progress(struct hdd_context *hdd_ctx) 20498 { 20499 struct hdd_adapter *adapter = NULL, *next_adapter = NULL; 20500 uint8_t vdev_id; 20501 wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_IS_ROAMING_IN_PROGRESS; 20502 struct wlan_hdd_link_info *link_info; 20503 20504 if (!hdd_ctx) { 20505 hdd_err("HDD context is NULL"); 20506 return false; 20507 } 20508 20509 if (!policy_mgr_is_sta_active_connection_exists(hdd_ctx->psoc)) 20510 return false; 20511 20512 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 20513 dbgid) { 20514 if (adapter->device_mode != QDF_STA_MODE) 20515 goto adapter_put; 20516 20517 hdd_adapter_for_each_active_link_info(adapter, link_info) { 20518 vdev_id = link_info->vdev_id; 20519 if (test_bit(SME_SESSION_OPENED, 20520 &link_info->link_flags) && 20521 sme_roaming_in_progress(hdd_ctx->mac_handle, 20522 vdev_id)) { 20523 hdd_debug("Roaming is in progress on:vdev_id:%d", 20524 link_info->vdev_id); 20525 hdd_adapter_dev_put_debug(adapter, dbgid); 20526 if (next_adapter) 20527 hdd_adapter_dev_put_debug(next_adapter, 20528 dbgid); 20529 return true; 20530 } 20531 } 20532 adapter_put: 20533 hdd_adapter_dev_put_debug(adapter, dbgid); 20534 } 20535 20536 return false; 20537 } 20538 20539 /** 20540 * struct hdd_is_connection_in_progress_priv - adapter connection info 20541 * @out_vdev_id: id of vdev where connection is occurring 20542 * @out_reason: scan reject reason 20543 * @connection_in_progress: true if connection is in progress 20544 */ 20545 struct hdd_is_connection_in_progress_priv { 20546 uint8_t out_vdev_id; 20547 enum scan_reject_states out_reason; 20548 bool connection_in_progress; 20549 }; 20550 20551 /** 20552 * hdd_is_connection_in_progress_iterator() - Check adapter connection based 20553 * on device mode 20554 * @link_info: Link info pointer in HDD adapter 20555 * @ctx: user context supplied 20556 * 20557 * Check if connection is in progress for the current adapter according to the 20558 * device mode 20559 * 20560 * Return: 20561 * * QDF_STATUS_SUCCESS if iteration should continue 20562 * * QDF_STATUS_E_ABORTED if iteration should be aborted 20563 */ 20564 static QDF_STATUS 20565 hdd_is_connection_in_progress_iterator(struct wlan_hdd_link_info *link_info, 20566 void *ctx) 20567 { 20568 struct hdd_station_ctx *hdd_sta_ctx; 20569 uint8_t *sta_mac; 20570 struct hdd_context *hdd_ctx; 20571 mac_handle_t mac_handle; 20572 struct hdd_station_info *sta_info, *tmp = NULL; 20573 struct hdd_is_connection_in_progress_priv *context = ctx; 20574 struct hdd_adapter *adapter = link_info->adapter; 20575 20576 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 20577 if (!hdd_ctx) 20578 return QDF_STATUS_E_ABORTED; 20579 20580 mac_handle = hdd_ctx->mac_handle; 20581 20582 if (!test_bit(SME_SESSION_OPENED, &link_info->link_flags) && 20583 (adapter->device_mode == QDF_STA_MODE || 20584 adapter->device_mode == QDF_P2P_CLIENT_MODE || 20585 adapter->device_mode == QDF_P2P_DEVICE_MODE || 20586 adapter->device_mode == QDF_P2P_GO_MODE || 20587 adapter->device_mode == QDF_SAP_MODE)) 20588 return QDF_STATUS_SUCCESS; 20589 20590 if ((QDF_STA_MODE == adapter->device_mode || 20591 QDF_P2P_CLIENT_MODE == adapter->device_mode || 20592 QDF_P2P_DEVICE_MODE == adapter->device_mode) && 20593 hdd_cm_is_connecting(link_info)) { 20594 hdd_debug("%pK(%d) mode %d Connection is in progress", 20595 WLAN_HDD_GET_STATION_CTX_PTR(link_info), 20596 link_info->vdev_id, adapter->device_mode); 20597 20598 context->out_vdev_id = link_info->vdev_id; 20599 context->out_reason = CONNECTION_IN_PROGRESS; 20600 context->connection_in_progress = true; 20601 20602 return QDF_STATUS_E_ABORTED; 20603 } 20604 20605 if ((QDF_STA_MODE == adapter->device_mode) && 20606 sme_roaming_in_progress(mac_handle, link_info->vdev_id)) { 20607 hdd_debug("%pK(%d) mode %d Reassociation in progress", 20608 WLAN_HDD_GET_STATION_CTX_PTR(link_info), 20609 link_info->vdev_id, adapter->device_mode); 20610 20611 context->out_vdev_id = link_info->vdev_id; 20612 context->out_reason = REASSOC_IN_PROGRESS; 20613 context->connection_in_progress = true; 20614 return QDF_STATUS_E_ABORTED; 20615 } 20616 20617 if ((QDF_STA_MODE == adapter->device_mode) || 20618 (QDF_P2P_CLIENT_MODE == adapter->device_mode) || 20619 (QDF_P2P_DEVICE_MODE == adapter->device_mode)) { 20620 hdd_sta_ctx = 20621 WLAN_HDD_GET_STATION_CTX_PTR(link_info); 20622 if (hdd_cm_is_vdev_associated(link_info) 20623 && sme_is_sta_key_exchange_in_progress( 20624 mac_handle, link_info->vdev_id)) { 20625 sta_mac = (uint8_t *)&(adapter->mac_addr.bytes[0]); 20626 hdd_debug("client " QDF_MAC_ADDR_FMT 20627 " is in middle of WPS/EAPOL exchange.", 20628 QDF_MAC_ADDR_REF(sta_mac)); 20629 20630 context->out_vdev_id = link_info->vdev_id; 20631 context->out_reason = EAPOL_IN_PROGRESS; 20632 context->connection_in_progress = true; 20633 20634 return QDF_STATUS_E_ABORTED; 20635 } 20636 } else if ((QDF_SAP_MODE == adapter->device_mode) || 20637 (QDF_P2P_GO_MODE == adapter->device_mode)) { 20638 hdd_for_each_sta_ref_safe(adapter->sta_info_list, sta_info, tmp, 20639 STA_INFO_CONNECTION_IN_PROGRESS_ITERATOR) { 20640 if (sta_info->peer_state != 20641 OL_TXRX_PEER_STATE_CONN) { 20642 hdd_put_sta_info_ref( 20643 &adapter->sta_info_list, &sta_info, true, 20644 STA_INFO_CONNECTION_IN_PROGRESS_ITERATOR); 20645 continue; 20646 } 20647 20648 sta_mac = sta_info->sta_mac.bytes; 20649 hdd_debug("client " QDF_MAC_ADDR_FMT 20650 " of SAP/GO is in middle of WPS/EAPOL exchange", 20651 QDF_MAC_ADDR_REF(sta_mac)); 20652 20653 context->out_vdev_id = link_info->vdev_id; 20654 context->out_reason = SAP_EAPOL_IN_PROGRESS; 20655 context->connection_in_progress = true; 20656 20657 hdd_put_sta_info_ref( 20658 &adapter->sta_info_list, &sta_info, true, 20659 STA_INFO_CONNECTION_IN_PROGRESS_ITERATOR); 20660 if (tmp) 20661 hdd_put_sta_info_ref( 20662 &adapter->sta_info_list, &tmp, true, 20663 STA_INFO_CONNECTION_IN_PROGRESS_ITERATOR); 20664 20665 return QDF_STATUS_E_ABORTED; 20666 } 20667 if (hdd_ctx->connection_in_progress) { 20668 hdd_debug("AP/GO: vdev %d connection is in progress", 20669 link_info->vdev_id); 20670 context->out_reason = SAP_CONNECTION_IN_PROGRESS; 20671 context->out_vdev_id = link_info->vdev_id; 20672 context->connection_in_progress = true; 20673 20674 return QDF_STATUS_E_ABORTED; 20675 } 20676 } 20677 20678 if (ucfg_nan_is_enable_disable_in_progress(hdd_ctx->psoc)) { 20679 context->out_reason = NAN_ENABLE_DISABLE_IN_PROGRESS; 20680 context->out_vdev_id = NAN_PSEUDO_VDEV_ID; 20681 context->connection_in_progress = true; 20682 20683 return QDF_STATUS_E_ABORTED; 20684 } 20685 20686 return QDF_STATUS_SUCCESS; 20687 } 20688 20689 bool hdd_is_connection_in_progress(uint8_t *out_vdev_id, 20690 enum scan_reject_states *out_reason) 20691 { 20692 struct hdd_is_connection_in_progress_priv hdd_conn; 20693 hdd_adapter_iterate_cb cb; 20694 20695 hdd_conn.out_vdev_id = 0; 20696 hdd_conn.out_reason = SCAN_REJECT_DEFAULT; 20697 hdd_conn.connection_in_progress = false; 20698 20699 cb = hdd_is_connection_in_progress_iterator; 20700 20701 hdd_adapter_iterate(cb, &hdd_conn); 20702 20703 if (hdd_conn.connection_in_progress && out_vdev_id && out_reason) { 20704 *out_vdev_id = hdd_conn.out_vdev_id; 20705 *out_reason = hdd_conn.out_reason; 20706 } 20707 20708 return hdd_conn.connection_in_progress; 20709 } 20710 20711 void hdd_restart_sap(struct wlan_hdd_link_info *link_info) 20712 { 20713 struct hdd_hostapd_state *hapd_state; 20714 QDF_STATUS status; 20715 struct hdd_adapter *ap_adapter = link_info->adapter; 20716 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(ap_adapter); 20717 struct sap_config *sap_config; 20718 void *sap_ctx; 20719 20720 sap_config = 20721 &(WLAN_HDD_GET_AP_CTX_PTR(link_info)->sap_config); 20722 sap_ctx = WLAN_HDD_GET_SAP_CTX_PTR(link_info); 20723 20724 mutex_lock(&hdd_ctx->sap_lock); 20725 if (test_bit(SOFTAP_BSS_STARTED, &link_info->link_flags)) { 20726 wlan_hdd_del_station(ap_adapter, NULL); 20727 hapd_state = WLAN_HDD_GET_HOSTAP_STATE_PTR(link_info); 20728 qdf_event_reset(&hapd_state->qdf_stop_bss_event); 20729 if (QDF_STATUS_SUCCESS == wlansap_stop_bss(sap_ctx)) { 20730 status = qdf_wait_single_event(&hapd_state->qdf_stop_bss_event, 20731 SME_CMD_STOP_BSS_TIMEOUT); 20732 20733 if (!QDF_IS_STATUS_SUCCESS(status)) { 20734 hdd_err("SAP Stop Failed"); 20735 goto end; 20736 } 20737 } 20738 clear_bit(SOFTAP_BSS_STARTED, &link_info->link_flags); 20739 policy_mgr_decr_session_set_pcl(hdd_ctx->psoc, 20740 ap_adapter->device_mode, link_info->vdev_id); 20741 hdd_green_ap_start_state_mc(hdd_ctx, ap_adapter->device_mode, 20742 false); 20743 hdd_err("SAP Stop Success"); 20744 20745 if (0 != wlan_hdd_cfg80211_update_apies(link_info)) { 20746 hdd_err("SAP Not able to set AP IEs"); 20747 goto end; 20748 } 20749 20750 status = wlan_hdd_mlo_sap_reinit(link_info); 20751 if (QDF_IS_STATUS_ERROR(status)) { 20752 hdd_err("SAP Not able to do mlo attach"); 20753 goto deinit_mlo; 20754 } 20755 20756 qdf_event_reset(&hapd_state->qdf_event); 20757 status = wlansap_start_bss(sap_ctx, hdd_hostapd_sap_event_cb, 20758 sap_config, ap_adapter->dev); 20759 if (QDF_IS_STATUS_ERROR(status)) { 20760 hdd_err("SAP Start Bss fail"); 20761 goto deinit_mlo; 20762 } 20763 20764 hdd_info("Waiting for SAP to start"); 20765 status = qdf_wait_single_event(&hapd_state->qdf_event, 20766 SME_CMD_START_BSS_TIMEOUT); 20767 if (!QDF_IS_STATUS_SUCCESS(status)) { 20768 hdd_err("SAP Start failed"); 20769 goto deinit_mlo; 20770 } 20771 wlansap_reset_sap_config_add_ie(sap_config, eUPDATE_IE_ALL); 20772 hdd_err("SAP Start Success"); 20773 hdd_medium_assess_init(); 20774 set_bit(SOFTAP_BSS_STARTED, &link_info->link_flags); 20775 if (hapd_state->bss_state == BSS_START) { 20776 policy_mgr_incr_active_session(hdd_ctx->psoc, 20777 ap_adapter->device_mode, 20778 link_info->vdev_id); 20779 hdd_green_ap_start_state_mc(hdd_ctx, 20780 ap_adapter->device_mode, 20781 true); 20782 } 20783 } 20784 mutex_unlock(&hdd_ctx->sap_lock); 20785 return; 20786 20787 deinit_mlo: 20788 wlan_hdd_mlo_reset(link_info); 20789 end: 20790 wlansap_reset_sap_config_add_ie(sap_config, eUPDATE_IE_ALL); 20791 mutex_unlock(&hdd_ctx->sap_lock); 20792 } 20793 20794 /** 20795 * hdd_set_connection_in_progress() - to set the connection in 20796 * progress flag 20797 * @value: value to set 20798 * 20799 * This function will set the passed value to connection in progress flag. 20800 * If value is previously being set to true then no need to set it again. 20801 * 20802 * Return: true if value is being set correctly and false otherwise. 20803 */ 20804 bool hdd_set_connection_in_progress(bool value) 20805 { 20806 bool status = true; 20807 struct hdd_context *hdd_ctx; 20808 20809 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 20810 if (!hdd_ctx) 20811 return false; 20812 20813 qdf_spin_lock(&hdd_ctx->connection_status_lock); 20814 /* 20815 * if the value is set to true previously and if someone is 20816 * trying to make it true again then it could be some race 20817 * condition being triggered. Avoid this situation by returning 20818 * false 20819 */ 20820 if (hdd_ctx->connection_in_progress && value) 20821 status = false; 20822 else 20823 hdd_ctx->connection_in_progress = value; 20824 qdf_spin_unlock(&hdd_ctx->connection_status_lock); 20825 return status; 20826 } 20827 20828 int wlan_hdd_send_mcc_vdev_quota(struct hdd_adapter *adapter, int set_value) 20829 { 20830 if (!adapter) { 20831 hdd_err("Invalid adapter"); 20832 return -EINVAL; 20833 } 20834 hdd_info("send mcc vdev quota to fw: %d", set_value); 20835 sme_cli_set_command(adapter->deflink->vdev_id, 20836 WMA_VDEV_MCC_SET_TIME_QUOTA, 20837 set_value, VDEV_CMD); 20838 return 0; 20839 20840 } 20841 20842 int wlan_hdd_send_mcc_latency(struct hdd_adapter *adapter, int set_value) 20843 { 20844 if (!adapter) { 20845 hdd_err("Invalid adapter"); 20846 return -EINVAL; 20847 } 20848 20849 hdd_info("Send MCC latency WMA: %d", set_value); 20850 sme_cli_set_command(adapter->deflink->vdev_id, 20851 WMA_VDEV_MCC_SET_TIME_LATENCY, 20852 set_value, VDEV_CMD); 20853 return 0; 20854 } 20855 20856 struct wlan_hdd_link_info * 20857 wlan_hdd_get_link_info_from_vdev(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id) 20858 { 20859 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 20860 struct wlan_hdd_link_info *link_info; 20861 20862 /* 20863 * Currently PSOC is not being used. But this logic will 20864 * change once we have the converged implementation of 20865 * HDD context per PSOC in place. This would break if 20866 * multiple vdev objects reuse the vdev id. 20867 */ 20868 link_info = hdd_get_link_info_by_vdev(hdd_ctx, vdev_id); 20869 if (!link_info) { 20870 hdd_err("Get adapter by vdev id failed"); 20871 return NULL; 20872 } 20873 20874 return link_info; 20875 } 20876 20877 int hdd_get_rssi_snr_by_bssid(mac_handle_t mac_handle, const uint8_t *bssid, 20878 int8_t *rssi, int8_t *snr) 20879 { 20880 QDF_STATUS status; 20881 20882 status = sme_get_rssi_snr_by_bssid(mac_handle, bssid, rssi, snr); 20883 if (QDF_IS_STATUS_ERROR(status)) { 20884 hdd_debug("sme_get_rssi_snr_by_bssid failed"); 20885 return -EINVAL; 20886 } 20887 20888 return 0; 20889 } 20890 20891 /** 20892 * hdd_reset_limit_off_chan() - reset limit off-channel command parameters 20893 * @adapter: HDD adapter 20894 * 20895 * Return: 0 on success and non zero value on failure 20896 */ 20897 int hdd_reset_limit_off_chan(struct hdd_adapter *adapter) 20898 { 20899 struct hdd_context *hdd_ctx; 20900 int ret; 20901 QDF_STATUS status; 20902 uint8_t sys_pref = 0; 20903 20904 hdd_ctx = WLAN_HDD_GET_CTX(adapter); 20905 ret = wlan_hdd_validate_context(hdd_ctx); 20906 if (ret < 0) 20907 return ret; 20908 20909 ucfg_policy_mgr_get_sys_pref(hdd_ctx->psoc, 20910 &sys_pref); 20911 /* set the system preferece to default */ 20912 policy_mgr_set_cur_conc_system_pref(hdd_ctx->psoc, sys_pref); 20913 20914 /* clear the bitmap */ 20915 adapter->active_ac = 0; 20916 20917 hdd_debug("reset ac_bitmap for session %hu active_ac %0x", 20918 adapter->deflink->vdev_id, adapter->active_ac); 20919 20920 status = sme_send_limit_off_channel_params(hdd_ctx->mac_handle, 20921 adapter->deflink->vdev_id, 20922 false, 0, 0, false); 20923 if (!QDF_IS_STATUS_SUCCESS(status)) { 20924 hdd_err("failed to reset limit off chan params"); 20925 ret = -EINVAL; 20926 } 20927 20928 return ret; 20929 } 20930 20931 void hdd_hidden_ssid_enable_roaming(hdd_handle_t hdd_handle, uint8_t vdev_id) 20932 { 20933 struct hdd_context *hdd_ctx = hdd_handle_to_context(hdd_handle); 20934 struct wlan_hdd_link_info *link_info; 20935 20936 link_info = hdd_get_link_info_by_vdev(hdd_ctx, vdev_id); 20937 if (!link_info) { 20938 hdd_err("Invalid vdev"); 20939 return; 20940 } 20941 /* enable roaming on all adapters once hdd get hidden ssid rsp */ 20942 wlan_hdd_set_roaming_state(link_info, RSO_START_BSS, true); 20943 } 20944 20945 #ifdef WLAN_FEATURE_PKT_CAPTURE 20946 bool wlan_hdd_is_mon_concurrency(void) 20947 { 20948 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 20949 20950 if (!hdd_ctx) 20951 return -EINVAL; 20952 20953 if (ucfg_pkt_capture_get_mode(hdd_ctx->psoc) != 20954 PACKET_CAPTURE_MODE_DISABLE) { 20955 if (policy_mgr_get_concurrency_mode(hdd_ctx->psoc) == 20956 (QDF_STA_MASK | QDF_MONITOR_MASK)) { 20957 hdd_err("STA + MON mode is UP"); 20958 return true; 20959 } 20960 } 20961 return false; 20962 } 20963 20964 void wlan_hdd_del_monitor(struct hdd_context *hdd_ctx, 20965 struct hdd_adapter *adapter, bool rtnl_held) 20966 { 20967 wlan_hdd_release_intf_addr(hdd_ctx, adapter->mac_addr.bytes); 20968 hdd_stop_adapter(hdd_ctx, adapter); 20969 hdd_close_adapter(hdd_ctx, adapter, true); 20970 20971 hdd_open_p2p_interface(hdd_ctx); 20972 } 20973 20974 void 20975 wlan_hdd_del_p2p_interface(struct hdd_context *hdd_ctx) 20976 { 20977 struct hdd_adapter *adapter = NULL, *next_adapter = NULL; 20978 struct osif_vdev_sync *vdev_sync; 20979 20980 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter, 20981 NET_DEV_HOLD_DEL_P2P_INTERFACE) { 20982 if (adapter->device_mode == QDF_P2P_CLIENT_MODE || 20983 adapter->device_mode == QDF_P2P_DEVICE_MODE || 20984 adapter->device_mode == QDF_P2P_GO_MODE) { 20985 vdev_sync = osif_vdev_sync_unregister(adapter->dev); 20986 if (vdev_sync) 20987 osif_vdev_sync_wait_for_ops(vdev_sync); 20988 20989 hdd_adapter_dev_put_debug( 20990 adapter, NET_DEV_HOLD_DEL_P2P_INTERFACE); 20991 20992 hdd_clean_up_interface(hdd_ctx, adapter); 20993 20994 if (vdev_sync) 20995 osif_vdev_sync_destroy(vdev_sync); 20996 } else 20997 hdd_adapter_dev_put_debug( 20998 adapter, NET_DEV_HOLD_DEL_P2P_INTERFACE); 20999 } 21000 } 21001 21002 #endif /* WLAN_FEATURE_PKT_CAPTURE */ 21003 21004 bool wlan_hdd_is_session_type_monitor(uint8_t session_type) 21005 { 21006 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 21007 21008 if (!hdd_ctx) { 21009 cds_err("HDD context is NULL"); 21010 return false; 21011 } 21012 21013 if (cds_get_conparam() != QDF_GLOBAL_MONITOR_MODE && 21014 session_type == QDF_MONITOR_MODE) 21015 return true; 21016 else 21017 return false; 21018 } 21019 21020 int 21021 wlan_hdd_add_monitor_check(struct hdd_context *hdd_ctx, 21022 struct hdd_adapter **adapter, 21023 const char *name, bool rtnl_held, 21024 unsigned char name_assign_type) 21025 { 21026 struct hdd_adapter *sta_adapter; 21027 struct hdd_adapter *mon_adapter; 21028 uint8_t num_open_session = 0; 21029 QDF_STATUS status; 21030 struct hdd_adapter_create_param params = {0}; 21031 21032 sta_adapter = hdd_get_adapter(hdd_ctx, QDF_STA_MODE); 21033 if (!sta_adapter) { 21034 hdd_err("No station adapter"); 21035 return -EINVAL; 21036 } 21037 21038 status = policy_mgr_check_mon_concurrency(hdd_ctx->psoc); 21039 21040 if (QDF_IS_STATUS_ERROR(status)) 21041 return -EINVAL; 21042 21043 if (hdd_is_connection_in_progress(NULL, NULL)) { 21044 hdd_err("cannot add monitor mode, Connection in progress"); 21045 return -EINVAL; 21046 } 21047 21048 if (!ucfg_dp_is_local_pkt_capture_enabled(hdd_ctx->psoc) && 21049 ucfg_mlme_is_sta_mon_conc_supported(hdd_ctx->psoc)) { 21050 num_open_session = policy_mgr_mode_specific_connection_count( 21051 hdd_ctx->psoc, 21052 PM_STA_MODE, 21053 NULL); 21054 21055 if (num_open_session) { 21056 /* Try disconnecting if already in connected state */ 21057 wlan_hdd_cm_issue_disconnect(sta_adapter->deflink, 21058 REASON_UNSPEC_FAILURE, 21059 true); 21060 } 21061 } 21062 21063 if (ucfg_pkt_capture_get_mode(hdd_ctx->psoc) != 21064 PACKET_CAPTURE_MODE_DISABLE) 21065 wlan_hdd_del_p2p_interface(hdd_ctx); 21066 21067 params.is_add_virtual_iface = 1; 21068 21069 mon_adapter = hdd_open_adapter(hdd_ctx, QDF_MONITOR_MODE, name, 21070 wlan_hdd_get_intf_addr( 21071 hdd_ctx, 21072 QDF_MONITOR_MODE), 21073 name_assign_type, rtnl_held, ¶ms); 21074 if (!mon_adapter) { 21075 hdd_err("hdd_open_adapter failed"); 21076 if (ucfg_pkt_capture_get_mode(hdd_ctx->psoc) != 21077 PACKET_CAPTURE_MODE_DISABLE) 21078 hdd_open_p2p_interface(hdd_ctx); 21079 return -EINVAL; 21080 } 21081 21082 if (mon_adapter) 21083 hdd_set_idle_ps_config(hdd_ctx, false); 21084 21085 *adapter = mon_adapter; 21086 return 0; 21087 } 21088 21089 #ifdef FEATURE_MONITOR_MODE_SUPPORT 21090 21091 void hdd_sme_monitor_mode_callback(uint8_t vdev_id) 21092 { 21093 struct hdd_context *hdd_ctx; 21094 struct hdd_adapter *adapter; 21095 struct wlan_hdd_link_info *link_info; 21096 21097 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 21098 if (!hdd_ctx) 21099 return; 21100 21101 link_info = hdd_get_link_info_by_vdev(hdd_ctx, vdev_id); 21102 if (!link_info) { 21103 hdd_err_rl("NULL adapter"); 21104 return; 21105 } 21106 21107 adapter = link_info->adapter; 21108 if (adapter->magic != WLAN_HDD_ADAPTER_MAGIC) { 21109 hdd_err_rl("Invalid magic"); 21110 return; 21111 } 21112 21113 qdf_event_set(&adapter->qdf_monitor_mode_vdev_up_event); 21114 21115 hdd_debug("monitor mode vdev up completed"); 21116 adapter->monitor_mode_vdev_up_in_progress = false; 21117 } 21118 21119 QDF_STATUS hdd_monitor_mode_qdf_create_event(struct hdd_adapter *adapter, 21120 uint8_t session_type) 21121 { 21122 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; 21123 21124 if (session_type == QDF_MONITOR_MODE) { 21125 qdf_status = qdf_event_create( 21126 &adapter->qdf_monitor_mode_vdev_up_event); 21127 } 21128 return qdf_status; 21129 } 21130 21131 QDF_STATUS hdd_monitor_mode_vdev_status(struct hdd_adapter *adapter) 21132 { 21133 QDF_STATUS status = QDF_STATUS_SUCCESS; 21134 21135 if (!adapter->monitor_mode_vdev_up_in_progress) 21136 return status; 21137 21138 /* block on a completion variable until vdev up success*/ 21139 status = qdf_wait_for_event_completion( 21140 &adapter->qdf_monitor_mode_vdev_up_event, 21141 WLAN_MONITOR_MODE_VDEV_UP_EVT); 21142 if (QDF_IS_STATUS_ERROR(status)) { 21143 hdd_err_rl("monitor mode vdev up event time out vdev id: %d", 21144 adapter->deflink->vdev_id); 21145 if (adapter->qdf_monitor_mode_vdev_up_event.force_set) 21146 /* 21147 * SSR/PDR has caused shutdown, which has 21148 * forcefully set the event. 21149 */ 21150 hdd_err_rl("monitor mode vdev up event forcefully set"); 21151 else if (status == QDF_STATUS_E_TIMEOUT) 21152 hdd_err_rl("mode vdev up event timed out"); 21153 else 21154 hdd_err_rl("Failed to wait for monitor vdev up(status-%d)", 21155 status); 21156 21157 adapter->monitor_mode_vdev_up_in_progress = false; 21158 return status; 21159 } 21160 21161 return QDF_STATUS_SUCCESS; 21162 } 21163 #endif 21164 21165 #if defined(CLD_PM_QOS) && defined(WLAN_FEATURE_LL_MODE) 21166 void hdd_beacon_latency_event_cb(uint32_t latency_level) 21167 { 21168 struct hdd_context *hdd_ctx; 21169 21170 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 21171 if (!hdd_ctx) 21172 return; 21173 21174 if (latency_level == 21175 QCA_WLAN_VENDOR_ATTR_CONFIG_LATENCY_LEVEL_ULTRALOW) 21176 wlan_hdd_set_pm_qos_request(hdd_ctx, true); 21177 else 21178 wlan_hdd_set_pm_qos_request(hdd_ctx, false); 21179 } 21180 #endif 21181 21182 #ifdef CONFIG_WLAN_DEBUG_CRASH_INJECT 21183 int hdd_crash_inject(struct hdd_adapter *adapter, uint32_t v1, uint32_t v2) 21184 { 21185 struct hdd_context *hdd_ctx; 21186 int ret; 21187 bool crash_inject; 21188 QDF_STATUS status; 21189 21190 hdd_debug("v1: %d v2: %d", v1, v2); 21191 pr_err("SSR is triggered by CRASH_INJECT: %d %d\n", 21192 v1, v2); 21193 hdd_ctx = WLAN_HDD_GET_CTX(adapter); 21194 21195 status = ucfg_mlme_get_crash_inject(hdd_ctx->psoc, &crash_inject); 21196 if (QDF_IS_STATUS_ERROR(status)) { 21197 hdd_err("Failed to get crash inject ini config"); 21198 return 0; 21199 } 21200 21201 if (!crash_inject) { 21202 hdd_err("Crash Inject ini disabled, Ignore Crash Inject"); 21203 return 0; 21204 } 21205 21206 if (v1 == 3) { 21207 cds_trigger_recovery(QDF_REASON_UNSPECIFIED); 21208 return 0; 21209 } 21210 ret = wma_cli_set2_command(adapter->deflink->vdev_id, 21211 GEN_PARAM_CRASH_INJECT, 21212 v1, v2, GEN_CMD); 21213 return ret; 21214 } 21215 #endif 21216 21217 static const struct hdd_chwidth_info chwidth_info[] = { 21218 [NL80211_CHAN_WIDTH_20_NOHT] = { 21219 .ch_bw = HW_MODE_20_MHZ, 21220 .ch_bw_str = "20MHz", 21221 .phy_chwidth = CH_WIDTH_20MHZ, 21222 }, 21223 [NL80211_CHAN_WIDTH_20] = { 21224 .sir_chwidth_valid = true, 21225 .sir_chwidth = eHT_CHANNEL_WIDTH_20MHZ, 21226 .ch_bw = HW_MODE_20_MHZ, 21227 .ch_bw_str = "20MHz", 21228 .phy_chwidth = CH_WIDTH_20MHZ, 21229 .bonding_mode = WNI_CFG_CHANNEL_BONDING_MODE_DISABLE, 21230 }, 21231 [NL80211_CHAN_WIDTH_40] = { 21232 .sir_chwidth_valid = true, 21233 .sir_chwidth = eHT_CHANNEL_WIDTH_40MHZ, 21234 .ch_bw = HW_MODE_40_MHZ, 21235 .ch_bw_str = "40MHz", 21236 .phy_chwidth = CH_WIDTH_40MHZ, 21237 .bonding_mode = WNI_CFG_CHANNEL_BONDING_MODE_ENABLE, 21238 }, 21239 [NL80211_CHAN_WIDTH_80] = { 21240 .sir_chwidth_valid = true, 21241 .sir_chwidth = eHT_CHANNEL_WIDTH_80MHZ, 21242 .ch_bw = HW_MODE_80_MHZ, 21243 .ch_bw_str = "80MHz", 21244 .phy_chwidth = CH_WIDTH_80MHZ, 21245 .bonding_mode = WNI_CFG_CHANNEL_BONDING_MODE_ENABLE, 21246 }, 21247 [NL80211_CHAN_WIDTH_80P80] = { 21248 .sir_chwidth_valid = true, 21249 .sir_chwidth = eHT_CHANNEL_WIDTH_80P80MHZ, 21250 .ch_bw = HW_MODE_80_PLUS_80_MHZ, 21251 .ch_bw_str = "(80 + 80)MHz", 21252 .phy_chwidth = CH_WIDTH_80P80MHZ, 21253 .bonding_mode = WNI_CFG_CHANNEL_BONDING_MODE_ENABLE, 21254 }, 21255 [NL80211_CHAN_WIDTH_160] = { 21256 .sir_chwidth_valid = true, 21257 .sir_chwidth = eHT_CHANNEL_WIDTH_160MHZ, 21258 .ch_bw = HW_MODE_160_MHZ, 21259 .ch_bw_str = "160MHz", 21260 .phy_chwidth = CH_WIDTH_160MHZ, 21261 .bonding_mode = WNI_CFG_CHANNEL_BONDING_MODE_ENABLE, 21262 }, 21263 [NL80211_CHAN_WIDTH_5] = { 21264 .ch_bw = HW_MODE_5_MHZ, 21265 .ch_bw_str = "5MHz", 21266 .phy_chwidth = CH_WIDTH_5MHZ, 21267 }, 21268 [NL80211_CHAN_WIDTH_10] = { 21269 .ch_bw = HW_MODE_10_MHZ, 21270 .ch_bw_str = "10MHz", 21271 .phy_chwidth = CH_WIDTH_10MHZ, 21272 }, 21273 #if defined(WLAN_FEATURE_11BE) && defined(CFG80211_11BE_BASIC) 21274 [NL80211_CHAN_WIDTH_320] = { 21275 .sir_chwidth_valid = true, 21276 .sir_chwidth = eHT_CHANNEL_WIDTH_320MHZ, 21277 .ch_bw = HW_MODE_320_MHZ, 21278 .ch_bw_str = "320MHz", 21279 .phy_chwidth = CH_WIDTH_320MHZ, 21280 .bonding_mode = WNI_CFG_CHANNEL_BONDING_MODE_ENABLE, 21281 }, 21282 #endif 21283 }; 21284 21285 enum eSirMacHTChannelWidth 21286 hdd_nl80211_chwidth_to_chwidth(uint8_t nl80211_chwidth) 21287 { 21288 if (nl80211_chwidth >= ARRAY_SIZE(chwidth_info) || 21289 !chwidth_info[nl80211_chwidth].sir_chwidth_valid) { 21290 hdd_err("Unsupported channel width %d", nl80211_chwidth); 21291 return -EINVAL; 21292 } 21293 21294 return chwidth_info[nl80211_chwidth].sir_chwidth; 21295 } 21296 21297 uint8_t hdd_chwidth_to_nl80211_chwidth(enum eSirMacHTChannelWidth chwidth) 21298 { 21299 int i; 21300 21301 for (i = 0; i < ARRAY_SIZE(chwidth_info); i++) { 21302 if (chwidth_info[i].sir_chwidth_valid && 21303 chwidth_info[i].sir_chwidth == chwidth) 21304 return i; 21305 } 21306 21307 hdd_err("Unsupported channel width %d", chwidth); 21308 return 0xFF; 21309 } 21310 21311 enum hw_mode_bandwidth wlan_hdd_get_channel_bw(enum nl80211_chan_width width) 21312 { 21313 if (width >= ARRAY_SIZE(chwidth_info)) { 21314 hdd_err("Invalid width: %d, using default 20MHz", width); 21315 return HW_MODE_20_MHZ; 21316 } 21317 21318 return chwidth_info[width].ch_bw; 21319 } 21320 21321 uint8_t *hdd_ch_width_str(enum phy_ch_width ch_width) 21322 { 21323 int i; 21324 21325 for (i = 0; i < ARRAY_SIZE(chwidth_info); i++) { 21326 if (chwidth_info[i].phy_chwidth == ch_width) 21327 return chwidth_info[i].ch_bw_str; 21328 } 21329 21330 return "UNKNOWN"; 21331 } 21332 21333 int hdd_we_set_ch_width(struct wlan_hdd_link_info *link_info, int ch_width) 21334 { 21335 int i; 21336 21337 /* updating channel bonding only on 5Ghz */ 21338 hdd_debug("wmi_vdev_param_chwidth val %d", ch_width); 21339 21340 for (i = 0; i < ARRAY_SIZE(chwidth_info); i++) { 21341 if (!chwidth_info[i].sir_chwidth_valid || 21342 chwidth_info[i].sir_chwidth != ch_width) 21343 continue; 21344 21345 return hdd_update_channel_width(link_info->adapter, ch_width, 21346 chwidth_info[i].bonding_mode); 21347 } 21348 21349 hdd_err("Invalid ch_width %d", ch_width); 21350 return -EINVAL; 21351 } 21352 21353 /* Register the module init/exit functions */ 21354 module_init(hdd_module_init); 21355 module_exit(hdd_module_exit); 21356 21357 MODULE_LICENSE("Dual BSD/GPL"); 21358 MODULE_AUTHOR("Qualcomm Atheros, Inc."); 21359 MODULE_DESCRIPTION("WLAN HOST DEVICE DRIVER"); 21360 21361 const struct kernel_param_ops con_mode_ops = { 21362 .set = con_mode_handler, 21363 .get = param_get_int, 21364 }; 21365 21366 #ifdef FEATURE_WLAN_RESIDENT_DRIVER 21367 EXPORT_SYMBOL(con_mode_ops); 21368 #endif 21369 21370 const struct kernel_param_ops con_mode_ftm_ops = { 21371 .set = con_mode_handler_ftm, 21372 .get = param_get_int, 21373 }; 21374 21375 #ifdef FEATURE_WLAN_RESIDENT_DRIVER 21376 EXPORT_SYMBOL(con_mode_ftm_ops); 21377 #endif 21378 21379 #ifdef WLAN_FEATURE_EPPING 21380 static const struct kernel_param_ops con_mode_epping_ops = { 21381 .set = con_mode_handler_epping, 21382 .get = param_get_int, 21383 }; 21384 #endif 21385 21386 static const struct kernel_param_ops fwpath_ops = { 21387 .set = fwpath_changed_handler, 21388 .get = param_get_string, 21389 }; 21390 21391 static int __pcie_set_gen_speed_handler(void) 21392 { 21393 int ret; 21394 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 21395 21396 ret = wlan_hdd_validate_context(hdd_ctx); 21397 if (ret) 21398 return ret; 21399 21400 hdd_info_rl("Received PCIe gen speed %d", pcie_gen_speed); 21401 if (pcie_gen_speed <= HDD_INVALID_MIN_PCIE_GEN_SPEED || 21402 pcie_gen_speed >= HDD_INVALID_MAX_PCIE_GEN_SPEED) { 21403 hdd_err_rl("invalid pcie gen speed %d", pcie_gen_speed); 21404 return -EINVAL; 21405 } 21406 21407 hdd_ctx->current_pcie_gen_speed = pcie_gen_speed; 21408 21409 return 0; 21410 } 21411 21412 static int pcie_set_gen_speed_handler(const char *kmessage, 21413 const struct kernel_param *kp) 21414 { 21415 struct osif_driver_sync *driver_sync; 21416 int ret; 21417 21418 ret = osif_driver_sync_op_start(&driver_sync); 21419 if (ret) 21420 return ret; 21421 21422 ret = param_set_int(kmessage, kp); 21423 if (ret) { 21424 hdd_err_rl("param set int failed %d", ret); 21425 goto out; 21426 } 21427 21428 ret = __pcie_set_gen_speed_handler(); 21429 21430 out: 21431 osif_driver_sync_op_stop(driver_sync); 21432 21433 return ret; 21434 } 21435 21436 static const struct kernel_param_ops pcie_gen_speed_ops = { 21437 .set = pcie_set_gen_speed_handler, 21438 .get = param_get_int, 21439 }; 21440 21441 module_param_cb(con_mode, &con_mode_ops, &con_mode, 21442 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); 21443 21444 module_param_cb(con_mode_ftm, &con_mode_ftm_ops, &con_mode_ftm, 21445 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); 21446 21447 module_param_cb(pcie_gen_speed, &pcie_gen_speed_ops, &pcie_gen_speed, 21448 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); 21449 21450 #ifdef WLAN_FEATURE_EPPING 21451 module_param_cb(con_mode_epping, &con_mode_epping_ops, 21452 &con_mode_epping, 0644); 21453 #endif 21454 21455 module_param_cb(fwpath, &fwpath_ops, &fwpath, 21456 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); 21457 21458 module_param(enable_dfs_chan_scan, int, S_IRUSR | S_IRGRP | S_IROTH); 21459 21460 module_param(enable_11d, int, S_IRUSR | S_IRGRP | S_IROTH); 21461 21462 module_param(country_code, charp, S_IRUSR | S_IRGRP | S_IROTH); 21463 21464 static int timer_multiplier_get_handler(char *buffer, 21465 const struct kernel_param *kp) 21466 { 21467 return scnprintf(buffer, PAGE_SIZE, "%u", qdf_timer_get_multiplier()); 21468 } 21469 21470 static int timer_multiplier_set_handler(const char *kmessage, 21471 const struct kernel_param *kp) 21472 { 21473 QDF_STATUS status; 21474 uint32_t scalar; 21475 21476 status = qdf_uint32_parse(kmessage, &scalar); 21477 if (QDF_IS_STATUS_ERROR(status)) 21478 return qdf_status_to_os_return(status); 21479 21480 if (!cfg_in_range(CFG_TIMER_MULTIPLIER, scalar)) 21481 return -ERANGE; 21482 21483 qdf_timer_set_multiplier(scalar); 21484 21485 return 0; 21486 } 21487 21488 static const struct kernel_param_ops timer_multiplier_ops = { 21489 .get = timer_multiplier_get_handler, 21490 .set = timer_multiplier_set_handler, 21491 }; 21492 21493 module_param_cb(timer_multiplier, &timer_multiplier_ops, NULL, 0644); 21494