diff --git a/core/hdd/inc/wlan_hdd_main.h b/core/hdd/inc/wlan_hdd_main.h index 4bcc53304c3e..897573fb549c 100644 --- a/core/hdd/inc/wlan_hdd_main.h +++ b/core/hdd/inc/wlan_hdd_main.h @@ -1223,6 +1223,7 @@ struct hdd_context; /** * struct hdd_adapter - hdd vdev/net_device context * @vdev: object manager vdev context + * @vdev_lock: lock to protect vdev context access * @event_flags: a bitmap of hdd_adapter_flags */ struct hdd_adapter { @@ -1238,6 +1239,7 @@ struct hdd_adapter { struct hdd_context *hdd_ctx; struct wlan_objmgr_vdev *vdev; + qdf_spinlock_t vdev_lock; void *txrx_vdev; diff --git a/core/hdd/src/wlan_hdd_cfg80211.c b/core/hdd/src/wlan_hdd_cfg80211.c index 050098b26746..2665967992aa 100644 --- a/core/hdd/src/wlan_hdd_cfg80211.c +++ b/core/hdd/src/wlan_hdd_cfg80211.c @@ -127,6 +127,7 @@ #include "wlan_nl_to_crypto_params.h" #include "wlan_crypto_global_def.h" #include "cdp_txrx_cfg.h" +#include "wlan_hdd_object_manager.h" #define g_mode_rates_size (12) #define a_mode_rates_size (8) @@ -4794,6 +4795,7 @@ void wlan_hdd_save_gtk_offload_params(struct hdd_adapter *adapter, uint8_t *buf; int i; struct pmo_gtk_req *gtk_req = NULL; + struct wlan_objmgr_vdev *vdev; QDF_STATUS status = QDF_STATUS_E_FAILURE; gtk_req = qdf_mem_malloc(sizeof(*gtk_req)); @@ -4823,10 +4825,15 @@ void wlan_hdd_save_gtk_offload_params(struct hdd_adapter *adapter, for (i = 0; i < 8; i++) buf[7 - i] = replay_ctr[i]; - status = ucfg_pmo_cache_gtk_offload_req(adapter->vdev, gtk_req); + vdev = hdd_objmgr_get_vdev(adapter); + if (!vdev) + goto end; + status = ucfg_pmo_cache_gtk_offload_req(vdev, gtk_req); + hdd_objmgr_put_vdev(adapter); if (status != QDF_STATUS_SUCCESS) hdd_err("Failed to cache GTK Offload"); +end: qdf_mem_free(gtk_req); } #else @@ -5283,29 +5290,26 @@ static int wlan_hdd_handle_restrict_offchan_config(struct hdd_adapter *adapter, { struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); enum QDF_OPMODE dev_mode = adapter->device_mode; + struct wlan_objmgr_vdev *vdev; int ret_val = 0; - QDF_STATUS status; if (!(dev_mode == QDF_SAP_MODE || dev_mode == QDF_P2P_GO_MODE)) { hdd_err("Invalid interface type:%d", dev_mode); return -EINVAL; } - status = wlan_objmgr_vdev_try_get_ref(adapter->vdev, WLAN_OSIF_ID); - if (status != QDF_STATUS_SUCCESS) { - hdd_err("Access hdd_vdev failed: %d", status); + vdev = hdd_objmgr_get_vdev(adapter); + if (!vdev) return -EINVAL; - } if (restrict_offchan == 1) { enum policy_mgr_con_mode pmode = policy_mgr_convert_device_mode_to_qdf_type(dev_mode); int chan; - u32 vdev_id = wlan_vdev_get_id(adapter->vdev); + u32 vdev_id = wlan_vdev_get_id(vdev); - wlan_vdev_obj_lock(adapter->vdev); - wlan_vdev_mlme_cap_set(adapter->vdev, - WLAN_VDEV_C_RESTRICT_OFFCHAN); - wlan_vdev_obj_unlock(adapter->vdev); + wlan_vdev_obj_lock(vdev); + wlan_vdev_mlme_cap_set(vdev, WLAN_VDEV_C_RESTRICT_OFFCHAN); + wlan_vdev_obj_unlock(vdev); chan = policy_mgr_get_channel(hdd_ctx->psoc, pmode, &vdev_id); if (!chan || @@ -5315,10 +5319,9 @@ static int wlan_hdd_handle_restrict_offchan_config(struct hdd_adapter *adapter, } hdd_info("vdev %d mode %d dnbs enabled", vdev_id, dev_mode); } else if (restrict_offchan == 0) { - wlan_vdev_obj_lock(adapter->vdev); - wlan_vdev_mlme_cap_clear(adapter->vdev, - WLAN_VDEV_C_RESTRICT_OFFCHAN); - wlan_vdev_obj_unlock(adapter->vdev); + wlan_vdev_obj_lock(vdev); + wlan_vdev_mlme_cap_clear(vdev, WLAN_VDEV_C_RESTRICT_OFFCHAN); + wlan_vdev_obj_unlock(vdev); if (wlan_hdd_send_avoid_freq_for_dnbs(hdd_ctx, 0)) { hdd_err("unable to clear avoid_freq"); ret_val = -EINVAL; @@ -5328,7 +5331,7 @@ static int wlan_hdd_handle_restrict_offchan_config(struct hdd_adapter *adapter, ret_val = -EINVAL; hdd_err("Invalid RESTRICT_OFFCHAN setting"); } - wlan_objmgr_vdev_release_ref(adapter->vdev, WLAN_OSIF_ID); + hdd_objmgr_put_vdev(adapter); return ret_val; } @@ -5560,6 +5563,7 @@ __wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy, uint16_t latency_level; mac_handle_t mac_handle; bool b_value; + struct wlan_objmgr_vdev *vdev; hdd_enter_dev(dev); qdf_mem_zero(&request, sizeof(request)); @@ -5600,8 +5604,12 @@ __wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy, modulated_dtim = nla_get_u32( tb[QCA_WLAN_VENDOR_ATTR_CONFIG_MODULATED_DTIM]); - status = ucfg_pmo_config_modulated_dtim(adapter->vdev, + vdev = hdd_objmgr_get_vdev(adapter); + if (!vdev) + return -EINVAL; + status = ucfg_pmo_config_modulated_dtim(vdev, modulated_dtim); + hdd_objmgr_put_vdev(adapter); if (QDF_STATUS_SUCCESS != status) ret_val = -EPERM; } @@ -5616,8 +5624,12 @@ __wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy, return -EINVAL; } - status = ucfg_pmo_config_listen_interval(adapter->vdev, + vdev = hdd_objmgr_get_vdev(adapter); + if (!vdev) + return -EINVAL; + status = ucfg_pmo_config_listen_interval(vdev, override_li); + hdd_objmgr_put_vdev(adapter); if (status != QDF_STATUS_SUCCESS) ret_val = -EPERM; } @@ -5652,7 +5664,6 @@ __wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy, ret_val = -EPERM; } - if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_GUARD_TIME]) { guard_time = nla_get_u32( tb[QCA_WLAN_VENDOR_ATTR_CONFIG_GUARD_TIME]); @@ -13212,8 +13223,14 @@ static int __wlan_hdd_cfg80211_change_iface(struct wiphy *wiphy, /* TDLS ignores p2p-device mode for concurrency considerations */ if (new_mode != QDF_P2P_DEVICE_MODE) { + struct wlan_objmgr_vdev *vdev; + + vdev = hdd_objmgr_get_vdev(adapter); + if (!vdev) + return -EINVAL; hdd_debug("Disable tdls; new interface is coming up"); - hdd_notify_teardown_tdls_links(adapter->vdev); + hdd_notify_teardown_tdls_links(vdev); + hdd_objmgr_put_vdev(adapter); } if (hdd_is_client_mode(adapter->device_mode)) { @@ -13431,8 +13448,13 @@ static int __wlan_hdd_change_station(struct wiphy *wiphy, (adapter->device_mode == QDF_P2P_CLIENT_MODE)) { if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) { #if defined(FEATURE_WLAN_TDLS) - ret = wlan_cfg80211_tdls_update_peer(hdd_ctx->pdev, - dev, mac, params); + struct wlan_objmgr_vdev *vdev; + + vdev = hdd_objmgr_get_vdev(adapter); + if (!vdev) + return -EINVAL; + ret = wlan_cfg80211_tdls_update_peer(vdev, mac, params); + hdd_objmgr_put_vdev(adapter); #endif } } @@ -14855,6 +14877,7 @@ static int wlan_hdd_cfg80211_connect_start(struct hdd_adapter *adapter, mac_handle_t mac_handle; uint8_t wmm_mode = 0; uint8_t value = 0; + struct wlan_objmgr_vdev *vdev; hdd_enter(); @@ -14880,7 +14903,13 @@ static int wlan_hdd_cfg80211_connect_start(struct hdd_adapter *adapter, /* Disable roaming on all other adapters before connect start */ wlan_hdd_disable_roaming(adapter); - hdd_notify_teardown_tdls_links(adapter->vdev); + vdev = hdd_objmgr_get_vdev(adapter); + if (!vdev) { + status = -EINVAL; + goto ret_status; + } + hdd_notify_teardown_tdls_links(vdev); + hdd_objmgr_put_vdev(adapter); qdf_mem_zero(&hdd_sta_ctx->conn_info.conn_flag, sizeof(hdd_sta_ctx->conn_info.conn_flag)); @@ -15024,7 +15053,13 @@ static int wlan_hdd_cfg80211_connect_start(struct hdd_adapter *adapter, } } #endif - ucfg_pmo_flush_gtk_offload_req(adapter->vdev); + vdev = hdd_objmgr_get_vdev(adapter); + if (!vdev) { + status = -EINVAL; + goto conn_failure; + } + ucfg_pmo_flush_gtk_offload_req(vdev); + hdd_objmgr_put_vdev(adapter); roam_profile->csrPersona = adapter->device_mode; if (operatingChannel) { @@ -16341,6 +16376,7 @@ static int wlan_hdd_cfg80211_set_privacy(struct hdd_adapter *adapter, int status = 0; struct hdd_station_ctx *sta_ctx; struct csr_roam_profile *roam_profile; + struct wlan_objmgr_vdev *vdev; hdd_enter(); @@ -16351,7 +16387,11 @@ static int wlan_hdd_cfg80211_set_privacy(struct hdd_adapter *adapter, roam_profile = hdd_roam_profile(adapter); /* populate auth,akm and cipher params for crypto */ - hdd_populate_crypto_params(adapter->vdev, req); + vdev = hdd_objmgr_get_vdev(adapter); + if (!vdev) + return -EINVAL; + hdd_populate_crypto_params(vdev, req); + hdd_objmgr_put_vdev(adapter); /*set authentication type */ status = wlan_hdd_cfg80211_set_auth_type(adapter, req->auth_type); @@ -17122,6 +17162,7 @@ static int __wlan_hdd_cfg80211_disconnect(struct wiphy *wiphy, struct hdd_station_ctx *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter); struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); + struct wlan_objmgr_vdev *vdev; hdd_enter(); @@ -17194,7 +17235,11 @@ static int __wlan_hdd_cfg80211_disconnect(struct wiphy *wiphy, reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED; break; } - if (ucfg_scan_get_vdev_status(adapter->vdev) != + + vdev = hdd_objmgr_get_vdev(adapter); + if (!vdev) + return -EINVAL; + if (ucfg_scan_get_vdev_status(vdev) != SCAN_NOT_IN_PROGRESS) { hdd_debug("Disconnect is in progress, Aborting Scan"); wlan_abort_scan(hdd_ctx->pdev, INVAL_PDEV_ID, @@ -17204,7 +17249,8 @@ static int __wlan_hdd_cfg80211_disconnect(struct wiphy *wiphy, wlan_hdd_cleanup_remain_on_channel_ctx(adapter); /* First clean up the tdls peers if any */ hdd_notify_sta_disconnect(adapter->session_id, - false, true, adapter->vdev); + false, true, vdev); + hdd_objmgr_put_vdev(adapter); hdd_info("Disconnect from userspace; reason:%d (%s)", reason, hdd_ieee80211_reason_code_to_str(reason)); @@ -18117,9 +18163,16 @@ static int __wlan_hdd_cfg80211_add_station(struct wiphy *wiphy, MAC_ADDR_ARRAY(mac)); if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) { - if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) - status = wlan_cfg80211_tdls_add_peer(hdd_ctx->pdev, - dev, mac); + if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) { + struct wlan_objmgr_vdev *vdev; + + vdev = hdd_objmgr_get_vdev(adapter); + if (vdev) { + status = wlan_cfg80211_tdls_add_peer(vdev, + mac); + hdd_objmgr_put_vdev(adapter); + } + } } #endif hdd_exit(); @@ -18678,6 +18731,7 @@ int __wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct pmo_gtk_req *gtk_req = NULL; struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); uint8_t *buf; + struct wlan_objmgr_vdev *vdev; QDF_STATUS status = QDF_STATUS_E_FAILURE; hdd_enter(); @@ -18718,7 +18772,13 @@ int __wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, wlan_hdd_copy_gtk_kek(gtk_req, data); qdf_mem_copy(gtk_req->kck, data->kck, NL80211_KCK_LEN); gtk_req->is_fils_connection = hdd_is_fils_connection(adapter); - status = ucfg_pmo_cache_gtk_offload_req(adapter->vdev, gtk_req); + vdev = hdd_objmgr_get_vdev(adapter); + if (!vdev) { + result = -EINVAL; + goto out; + } + status = ucfg_pmo_cache_gtk_offload_req(vdev, gtk_req); + hdd_objmgr_put_vdev(adapter); if (status != QDF_STATUS_SUCCESS) { hdd_err("Failed to cache GTK Offload"); result = qdf_status_to_os_return(status); diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c index 172ddab870e9..d63a5bc36335 100644 --- a/core/hdd/src/wlan_hdd_main.c +++ b/core/hdd/src/wlan_hdd_main.c @@ -748,6 +748,7 @@ static int __hdd_netdev_notifier_call(struct notifier_block *nb, #endif struct hdd_adapter *adapter; struct hdd_context *hdd_ctx; + struct wlan_objmgr_vdev *vdev; hdd_enter_dev(dev); @@ -811,12 +812,16 @@ static int __hdd_netdev_notifier_call(struct notifier_block *nb, break; case NETDEV_GOING_DOWN: - if (ucfg_scan_get_vdev_status(adapter->vdev) != + vdev = hdd_objmgr_get_vdev(adapter); + if (!vdev) + break; + if (ucfg_scan_get_vdev_status(vdev) != SCAN_NOT_IN_PROGRESS) { wlan_abort_scan(hdd_ctx->pdev, INVAL_PDEV_ID, adapter->session_id, INVALID_SCAN_ID, true); } + hdd_objmgr_put_vdev(adapter); cds_flush_work(&adapter->scan_block_work); /* Need to clean up blocked scan request */ wlan_hdd_cfg80211_scan_block_cb(&adapter->scan_block_work); @@ -3914,20 +3919,31 @@ QDF_STATUS hdd_sme_close_session_callback(uint8_t session_id) int hdd_vdev_ready(struct hdd_adapter *adapter) { + struct wlan_objmgr_vdev *vdev; QDF_STATUS status; - status = pmo_vdev_ready(adapter->vdev); - if (QDF_IS_STATUS_ERROR(status)) - return qdf_status_to_os_return(status); + vdev = hdd_objmgr_get_vdev(adapter); + if (!vdev) + return -EINVAL; - status = ucfg_reg_11d_vdev_created_update(adapter->vdev); - if (QDF_IS_STATUS_ERROR(status)) + status = pmo_vdev_ready(vdev); + if (QDF_IS_STATUS_ERROR(status)) { + hdd_objmgr_put_vdev(adapter); return qdf_status_to_os_return(status); + } + + status = ucfg_reg_11d_vdev_created_update(vdev); + if (QDF_IS_STATUS_ERROR(status)) { + hdd_objmgr_put_vdev(adapter); + return qdf_status_to_os_return(status); + } if (wma_capability_enhanced_mcast_filter()) - status = ucfg_pmo_enhanced_mc_filter_enable(adapter->vdev); + status = ucfg_pmo_enhanced_mc_filter_enable(vdev); else - status = ucfg_pmo_enhanced_mc_filter_disable(adapter->vdev); + status = ucfg_pmo_enhanced_mc_filter_disable(vdev); + + hdd_objmgr_put_vdev(adapter); return qdf_status_to_os_return(status); } @@ -3938,6 +3954,7 @@ int hdd_vdev_destroy(struct hdd_adapter *adapter) int errno; struct hdd_context *hdd_ctx; uint8_t vdev_id; + struct wlan_objmgr_vdev *vdev; vdev_id = adapter->session_id; hdd_info("destroying vdev %d", vdev_id); @@ -3948,8 +3965,12 @@ int hdd_vdev_destroy(struct hdd_adapter *adapter) return -EINVAL; } - status = ucfg_reg_11d_vdev_delete_update(adapter->vdev); - ucfg_scan_set_vdev_del_in_progress(adapter->vdev); + vdev = hdd_objmgr_get_vdev(adapter); + if (!vdev) + return -EINVAL; + status = ucfg_reg_11d_vdev_delete_update(vdev); + ucfg_scan_set_vdev_del_in_progress(vdev); + hdd_objmgr_put_vdev(adapter); /* close sme session (destroy vdev in firmware via legacy API) */ qdf_event_reset(&adapter->qdf_session_close_event); @@ -4029,6 +4050,7 @@ int hdd_vdev_create(struct hdd_adapter *adapter, bool bval; struct hdd_context *hdd_ctx; struct sme_session_params sme_session_params = {0}; + struct wlan_objmgr_vdev *vdev; hdd_info("creating new vdev"); @@ -4115,9 +4137,13 @@ int hdd_vdev_create(struct hdd_adapter *adapter, } if (adapter->device_mode == QDF_STA_MODE || - adapter->device_mode == QDF_P2P_CLIENT_MODE) - wlan_vdev_set_max_peer_count(adapter->vdev, - HDD_MAX_VDEV_PEER_COUNT); + adapter->device_mode == QDF_P2P_CLIENT_MODE) { + vdev = hdd_objmgr_get_vdev(adapter); + if (!vdev) + goto hdd_vdev_destroy_procedure; + wlan_vdev_set_max_peer_count(vdev, HDD_MAX_VDEV_PEER_COUNT); + hdd_objmgr_put_vdev(adapter); + } hdd_info("vdev %d created successfully", adapter->session_id); @@ -4298,7 +4324,8 @@ void hdd_deinit_adapter(struct hdd_context *hdd_ctx, hdd_exit(); } -static void hdd_cleanup_adapter(struct hdd_context *hdd_ctx, struct hdd_adapter *adapter, +static void hdd_cleanup_adapter(struct hdd_context *hdd_ctx, + struct hdd_adapter *adapter, bool rtnl_held) { struct net_device *dev = NULL; @@ -4313,6 +4340,7 @@ static void hdd_cleanup_adapter(struct hdd_context *hdd_ctx, struct hdd_adapter hdd_nud_deinit_tracking(adapter); qdf_mutex_destroy(&adapter->disconnection_status_lock); hdd_apf_context_destroy(adapter); + qdf_spinlock_destroy(&adapter->vdev_lock); wlan_hdd_debugfs_csr_deinit(adapter); @@ -5048,6 +5076,8 @@ struct hdd_adapter *hdd_open_adapter(struct hdd_context *hdd_ctx, uint8_t sessio return NULL; } + qdf_spinlock_create(&adapter->vdev_lock); + hdd_init_completion(adapter); INIT_WORK(&adapter->scan_block_work, wlan_hdd_cfg80211_scan_block_cb); qdf_list_create(&adapter->blocked_scan_request_q, WLAN_MAX_SCAN_COUNT); @@ -5215,6 +5245,7 @@ QDF_STATUS hdd_stop_adapter_ext(struct hdd_context *hdd_ctx, unsigned long rc; tsap_config_t *sap_config; mac_handle_t mac_handle; + struct wlan_objmgr_vdev *vdev; hdd_enter(); @@ -5310,9 +5341,15 @@ QDF_STATUS hdd_stop_adapter_ext(struct hdd_context *hdd_ctx, #endif #endif - if (adapter->device_mode == QDF_STA_MODE) - wlan_cfg80211_sched_scan_stop(hdd_ctx->pdev, - adapter->dev); + if (adapter->device_mode == QDF_STA_MODE) { + struct wlan_objmgr_vdev *vdev; + + vdev = hdd_objmgr_get_vdev(adapter); + if (vdev) { + wlan_cfg80211_sched_scan_stop(vdev); + hdd_objmgr_put_vdev(adapter); + } + } if (wlan_hdd_try_disconnect(adapter)) { hdd_err("Can't disconnect adapter"); @@ -5414,8 +5451,12 @@ QDF_STATUS hdd_stop_adapter_ext(struct hdd_context *hdd_ctx, /* * If Do_Not_Break_Stream was enabled clear avoid channel list. */ - if (policy_mgr_is_dnsc_set(adapter->vdev)) - wlan_hdd_send_avoid_freq_for_dnbs(hdd_ctx, 0); + vdev = hdd_objmgr_get_vdev(adapter); + if (vdev) { + if (policy_mgr_is_dnsc_set(vdev)) + wlan_hdd_send_avoid_freq_for_dnbs(hdd_ctx, 0); + hdd_objmgr_put_vdev(adapter); + } #ifdef WLAN_OPEN_SOURCE cancel_work_sync(&adapter->ipv4_notifier_work); @@ -5497,9 +5538,15 @@ static void hdd_reset_scan_operation(struct hdd_context *hdd_ctx, case QDF_NDI_MODE: wlan_hdd_scan_abort(adapter); wlan_hdd_cleanup_remain_on_channel_ctx(adapter); - if (adapter->device_mode == QDF_STA_MODE) - wlan_cfg80211_sched_scan_stop(hdd_ctx->pdev, - adapter->dev); + if (adapter->device_mode == QDF_STA_MODE) { + struct wlan_objmgr_vdev *vdev; + + vdev = hdd_objmgr_get_vdev(adapter); + if (vdev) { + wlan_cfg80211_sched_scan_stop(vdev); + hdd_objmgr_put_vdev(adapter); + } + } break; case QDF_P2P_GO_MODE: wlan_hdd_cleanup_remain_on_channel_ctx(adapter); @@ -5520,6 +5567,7 @@ QDF_STATUS hdd_reset_all_adapters(struct hdd_context *hdd_ctx) struct qdf_mac_addr peerMacAddr; int sta_id; bool value; + struct wlan_objmgr_vdev *vdev; hdd_enter(); @@ -5533,7 +5581,11 @@ QDF_STATUS hdd_reset_all_adapters(struct hdd_context *hdd_ctx) if ((adapter->device_mode == QDF_STA_MODE) || (adapter->device_mode == QDF_P2P_CLIENT_MODE)) { /* Stop tdls timers */ - hdd_notify_tdls_reset_adapter(adapter->vdev); + vdev = hdd_objmgr_get_vdev(adapter); + if (vdev) { + hdd_notify_tdls_reset_adapter(vdev); + hdd_objmgr_put_vdev(adapter); + } adapter->session.station.hdd_reassoc_scenario = false; } ucfg_mlme_get_sap_internal_restart(hdd_ctx->psoc, &value); diff --git a/core/hdd/src/wlan_hdd_object_manager.c b/core/hdd/src/wlan_hdd_object_manager.c index 6a698ebf7317..702e0e90ef71 100644 --- a/core/hdd/src/wlan_hdd_object_manager.c +++ b/core/hdd/src/wlan_hdd_object_manager.c @@ -281,8 +281,10 @@ int hdd_objmgr_create_and_store_vdev(struct wlan_objmgr_pdev *pdev, goto vdev_destroy; } + qdf_spin_lock_bh(&adapter->vdev_lock); adapter->vdev = vdev; adapter->session_id = wlan_vdev_get_id(vdev); + qdf_spin_unlock_bh(&adapter->vdev_lock); return 0; @@ -298,11 +300,14 @@ osif_priv_free: int hdd_objmgr_release_and_destroy_vdev(struct hdd_adapter *adapter) { QDF_STATUS status; - struct wlan_objmgr_vdev *vdev = adapter->vdev; + struct wlan_objmgr_vdev *vdev; struct vdev_osif_priv *osif_priv; + qdf_spin_lock_bh(&adapter->vdev_lock); + vdev = adapter->vdev; adapter->vdev = NULL; adapter->session_id = HDD_SESSION_ID_INVALID; + qdf_spin_unlock_bh(&adapter->vdev_lock); QDF_BUG(vdev); if (!vdev) @@ -320,6 +325,45 @@ int hdd_objmgr_release_and_destroy_vdev(struct hdd_adapter *adapter) return qdf_status_to_os_return(status); } +struct wlan_objmgr_vdev *__hdd_objmgr_get_vdev(struct hdd_adapter *adapter, + const char *func) +{ + struct wlan_objmgr_vdev *vdev = NULL; + QDF_STATUS status; + + if (!adapter) { + hdd_err("Adapter is NULL (via %s)", func); + return NULL; + } + + qdf_spin_lock_bh(&adapter->vdev_lock); + vdev = adapter->vdev; + if (vdev) { + status = wlan_objmgr_vdev_try_get_ref(vdev, WLAN_OSIF_ID); + if (QDF_IS_STATUS_ERROR(status)) + vdev = NULL; + } + qdf_spin_unlock_bh(&adapter->vdev_lock); + + if (!vdev) + hdd_err("VDEV is NULL (via %s)", func); + + return vdev; +} + +void __hdd_objmgr_put_vdev(struct hdd_adapter *adapter, const char *func) +{ + if (!adapter) { + hdd_err("Adapter is NULL (via %s)", func); + return; + } + + qdf_spin_lock_bh(&adapter->vdev_lock); + if (adapter->vdev) + wlan_objmgr_vdev_release_ref(adapter->vdev, WLAN_OSIF_ID); + qdf_spin_unlock_bh(&adapter->vdev_lock); +} + int hdd_objmgr_set_peer_mlme_auth_state(struct wlan_objmgr_vdev *vdev, bool is_authenticated) { diff --git a/core/hdd/src/wlan_hdd_object_manager.h b/core/hdd/src/wlan_hdd_object_manager.h index 6b2c4cff811f..5e5d8f6dc727 100644 --- a/core/hdd/src/wlan_hdd_object_manager.h +++ b/core/hdd/src/wlan_hdd_object_manager.h @@ -132,6 +132,31 @@ int hdd_objmgr_create_and_store_vdev(struct wlan_objmgr_pdev *pdev, */ int hdd_objmgr_release_and_destroy_vdev(struct hdd_adapter *adapter); +/** + * hdd_objmgr_get_vdev() - Get reference of vdev from adapter + * @adapter: hdd adapter + * + * This API gets vdev object reference from hdd adapter + * + * Return: pointer to vdev object for success, NULL for failure + */ +#define hdd_objmgr_get_vdev(adapter) \ + __hdd_objmgr_get_vdev(adapter, __func__) +struct wlan_objmgr_vdev *__hdd_objmgr_get_vdev(struct hdd_adapter *adapter, + const char *func); + +/** + * hdd_objmgr_put_vdev() - Release reference of vdev from adapter + * @adapter: hdd adapter + * + * This API releases vdev object reference from hdd adapter + * + * Return: void + */ +#define hdd_objmgr_put_vdev(adapter) \ + __hdd_objmgr_put_vdev(adapter, __func__) +void __hdd_objmgr_put_vdev(struct hdd_adapter *adapter, const char *func); + /** * hdd_objmgr_set_peer_mlme_auth_state() - set the peer mlme auth state * @vdev: vdev pointer diff --git a/core/hdd/src/wlan_hdd_scan.c b/core/hdd/src/wlan_hdd_scan.c index 74c40ae7920f..be993d94337e 100644 --- a/core/hdd/src/wlan_hdd_scan.c +++ b/core/hdd/src/wlan_hdd_scan.c @@ -46,6 +46,7 @@ #include #include #include "wlan_utility.h" +#include "wlan_hdd_object_manager.h" #define MAX_RATES 12 #define HDD_WAKE_LOCK_SCAN_DURATION (5 * 1000) /* in msec */ @@ -465,6 +466,7 @@ static int __wlan_hdd_cfg80211_scan(struct wiphy *wiphy, static uint32_t scan_ebusy_cnt; struct scan_params params = {0}; bool self_recovery; + struct wlan_objmgr_vdev *vdev; QDF_STATUS qdf_status; hdd_enter(); @@ -668,12 +670,20 @@ static int __wlan_hdd_cfg80211_scan(struct wiphy *wiphy, scan_info->scan_add_ie.length; } + vdev = hdd_objmgr_get_vdev(adapter); + if (!vdev) { + status = -EINVAL; + goto error; + } + if ((request->n_ssids == 1) && (request->ssids != NULL) && (request->ssids[0].ssid_len > 7) && !qdf_mem_cmp(&request->ssids[0], "DIRECT-", 7)) - ucfg_p2p_status_scan(adapter->vdev); + ucfg_p2p_status_scan(vdev); - status = wlan_cfg80211_scan(hdd_ctx->pdev, request, ¶ms); + status = wlan_cfg80211_scan(vdev, request, ¶ms); + hdd_objmgr_put_vdev(adapter); +error: if (params.default_ie.ptr) qdf_mem_free(params.default_ie.ptr); hdd_exit(); @@ -1269,6 +1279,7 @@ static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy, { struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev); struct hdd_context *hdd_ctx; + struct wlan_objmgr_vdev *vdev; int ret; hdd_enter(); @@ -1304,8 +1315,14 @@ static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy, return -EBUSY; } - return wlan_cfg80211_sched_scan_start(hdd_ctx->pdev, dev, request, + vdev = hdd_objmgr_get_vdev(adapter); + if (!vdev) + return -EINVAL; + ret = wlan_cfg80211_sched_scan_start(vdev, request, hdd_ctx->config->scan_backoff_multiplier); + hdd_objmgr_put_vdev(adapter); + + return ret; } /** @@ -1334,6 +1351,8 @@ int wlan_hdd_sched_scan_stop(struct net_device *dev) { struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev); struct hdd_context *hdd_ctx; + struct wlan_objmgr_vdev *vdev; + int ret; if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) { hdd_err("Command not allowed in FTM mode"); @@ -1353,7 +1372,13 @@ int wlan_hdd_sched_scan_stop(struct net_device *dev) return -EINVAL; } - return wlan_cfg80211_sched_scan_stop(hdd_ctx->pdev, dev); + vdev = hdd_objmgr_get_vdev(adapter); + if (!vdev) + return -EINVAL; + ret = wlan_cfg80211_sched_scan_stop(vdev); + hdd_objmgr_put_vdev(adapter); + + return ret; } /** diff --git a/core/hdd/src/wlan_hdd_tdls.c b/core/hdd/src/wlan_hdd_tdls.c index 45e38c95572e..9ff1129293e3 100644 --- a/core/hdd/src/wlan_hdd_tdls.c +++ b/core/hdd/src/wlan_hdd_tdls.c @@ -41,6 +41,7 @@ #include "wlan_policy_mgr_api.h" #include #include "wlan_tdls_cfg_api.h" +#include "wlan_hdd_object_manager.h" /** * enum qca_wlan_vendor_tdls_trigger_mode_hdd_map: Maps the user space TDLS @@ -75,6 +76,8 @@ int wlan_hdd_tdls_get_all_peers(struct hdd_adapter *adapter, { int len; struct hdd_context *hdd_ctx; + struct wlan_objmgr_vdev *vdev; + int ret; hdd_enter(); @@ -92,8 +95,15 @@ int wlan_hdd_tdls_get_all_peers(struct hdd_adapter *adapter, return len; } - return wlan_cfg80211_tdls_get_all_peers(adapter->vdev, - buf, buflen); + vdev = hdd_objmgr_get_vdev(adapter); + if (!vdev) { + len = scnprintf(buf, buflen, "\nVDEV is NULL\n"); + return len; + } + ret = wlan_cfg80211_tdls_get_all_peers(vdev, buf, buflen); + hdd_objmgr_put_vdev(adapter); + + return ret; } static const struct nla_policy @@ -232,8 +242,14 @@ __wlan_hdd_cfg80211_configure_tdls_mode(struct wiphy *wiphy, hdd_debug("TDLS trigger mode %d", trigger_mode); if (hdd_ctx->tdls_umac_comp_active) { - ret = wlan_cfg80211_tdls_configure_mode(adapter->vdev, + struct wlan_objmgr_vdev *vdev; + + vdev = hdd_objmgr_get_vdev(adapter); + if (!vdev) + return -EINVAL; + ret = wlan_cfg80211_tdls_configure_mode(vdev, trigger_mode); + hdd_objmgr_put_vdev(adapter); return ret; } @@ -473,12 +489,20 @@ static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, return -ENOTSUPP; } - if (hdd_ctx->tdls_umac_comp_active) - return wlan_cfg80211_tdls_mgmt(hdd_ctx->pdev, dev, - peer, - action_code, dialog_token, - status_code, peer_capability, - buf, len); + if (hdd_ctx->tdls_umac_comp_active) { + struct wlan_objmgr_vdev *vdev; + int ret; + + vdev = hdd_objmgr_get_vdev(adapter); + if (!vdev) + return -EINVAL; + ret = wlan_cfg80211_tdls_mgmt(vdev, peer, + action_code, dialog_token, + status_code, peer_capability, + buf, len); + hdd_objmgr_put_vdev(adapter); + return ret; + } return -EINVAL; } @@ -662,8 +686,13 @@ static int __wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, return status; if (hdd_ctx->tdls_umac_comp_active) { - status = wlan_cfg80211_tdls_oper(hdd_ctx->pdev, - dev, peer, oper); + struct wlan_objmgr_vdev *vdev; + + vdev = hdd_objmgr_get_vdev(adapter); + if (!vdev) + return -EINVAL; + status = wlan_cfg80211_tdls_oper(vdev, peer, oper); + hdd_objmgr_put_vdev(adapter); hdd_exit(); return status; } @@ -746,11 +775,17 @@ int hdd_set_tdls_offchannel(struct hdd_context *hdd_ctx, struct hdd_adapter *adapter, int offchannel) { + struct wlan_objmgr_vdev *vdev; QDF_STATUS status = QDF_STATUS_E_FAILURE; - if (hdd_ctx->tdls_umac_comp_active) - status = ucfg_set_tdls_offchannel(adapter->vdev, - offchannel); + if (hdd_ctx->tdls_umac_comp_active) { + vdev = hdd_objmgr_get_vdev(adapter); + if (vdev) { + status = ucfg_set_tdls_offchannel(vdev, + offchannel); + hdd_objmgr_put_vdev(adapter); + } + } return qdf_status_to_os_return(status); } @@ -758,11 +793,17 @@ int hdd_set_tdls_secoffchanneloffset(struct hdd_context *hdd_ctx, struct hdd_adapter *adapter, int offchanoffset) { + struct wlan_objmgr_vdev *vdev; QDF_STATUS status = QDF_STATUS_E_FAILURE; - if (hdd_ctx->tdls_umac_comp_active) - status = ucfg_set_tdls_secoffchanneloffset(adapter->vdev, - offchanoffset); + if (hdd_ctx->tdls_umac_comp_active) { + vdev = hdd_objmgr_get_vdev(adapter); + if (vdev) { + status = ucfg_set_tdls_secoffchanneloffset(vdev, + offchanoffset); + hdd_objmgr_put_vdev(adapter); + } + } return qdf_status_to_os_return(status); } @@ -770,11 +811,17 @@ int hdd_set_tdls_offchannelmode(struct hdd_context *hdd_ctx, struct hdd_adapter *adapter, int offchanmode) { + struct wlan_objmgr_vdev *vdev; QDF_STATUS status = QDF_STATUS_E_FAILURE; - if (hdd_ctx->tdls_umac_comp_active) - status = ucfg_set_tdls_offchan_mode(adapter->vdev, - offchanmode); + if (hdd_ctx->tdls_umac_comp_active) { + vdev = hdd_objmgr_get_vdev(adapter); + if (vdev) { + status = ucfg_set_tdls_offchan_mode(vdev, + offchanmode); + hdd_objmgr_put_vdev(adapter); + } + } return qdf_status_to_os_return(status); } @@ -818,8 +865,17 @@ int wlan_hdd_tdls_antenna_switch(struct hdd_context *hdd_ctx, struct hdd_adapter *adapter, uint32_t mode) { - if (hdd_ctx->tdls_umac_comp_active) - return wlan_tdls_antenna_switch(adapter->vdev, mode); + if (hdd_ctx->tdls_umac_comp_active) { + struct wlan_objmgr_vdev *vdev; + int ret; + + vdev = hdd_objmgr_get_vdev(adapter); + if (!vdev) + return -EINVAL; + ret = wlan_tdls_antenna_switch(vdev, mode); + hdd_objmgr_put_vdev(adapter); + return ret; + } return 0; }