diff --git a/components/mlme/core/src/wlan_mlme_vdev_mgr_interface.c b/components/mlme/core/src/wlan_mlme_vdev_mgr_interface.c index 6bf45db7ba..a1641f6a73 100644 --- a/components/mlme/core/src/wlan_mlme_vdev_mgr_interface.c +++ b/components/mlme/core/src/wlan_mlme_vdev_mgr_interface.c @@ -1172,35 +1172,6 @@ vdevmgr_vdev_start_rsp_handle(struct vdev_mlme_obj *vdev_mlme, return status; } -QDF_STATUS mlme_vdev_create_send(struct wlan_objmgr_vdev *vdev) -{ - struct vdev_mlme_obj *vdev_mlme = NULL; - QDF_STATUS status; - - vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev); - if (!vdev_mlme) { - mlme_err("Failed to get vdev mlme obj for vdev id %d", - wlan_vdev_get_id(vdev)); - status = QDF_STATUS_E_INVAL; - goto return_status; - } - - status = vdev_mgr_create_send(vdev_mlme); - if (QDF_IS_STATUS_ERROR(status)) { - mlme_err("Failed to create vdev for vdev id %d", - wlan_vdev_get_id(vdev)); - goto return_status; - } - - status = wma_post_vdev_create_setup(vdev); - - if (QDF_IS_STATUS_ERROR(status)) - vdev_mgr_delete_send(vdev_mlme); - -return_status: - return status; -} - QDF_STATUS mlme_vdev_self_peer_create(struct wlan_objmgr_vdev *vdev) { struct vdev_mlme_obj *vdev_mlme; @@ -1215,6 +1186,98 @@ QDF_STATUS mlme_vdev_self_peer_create(struct wlan_objmgr_vdev *vdev) return wma_vdev_self_peer_create(vdev_mlme); } +/** + * mlme_get_vdev_types() - get vdev type and subtype from its operation mode + * @mode: operation mode of vdev + * @type: type of vdev + * @sub_type: sub_type of vdev + * + * This API is called to get vdev type and subtype from its operation mode. + * Vdev operation modes are defined in enum QDF_OPMODE. + * + * Type of vdev are WLAN_VDEV_MLME_TYPE_AP, WLAN_VDEV_MLME_TYPE_STA, + * WLAN_VDEV_MLME_TYPE_IBSS, ,WLAN_VDEV_MLME_TYPE_MONITOR, + * WLAN_VDEV_MLME_TYPE_NAN, WLAN_VDEV_MLME_TYPE_OCB, WLAN_VDEV_MLME_TYPE_NDI + * + * Sub_types of vdev are WLAN_VDEV_MLME_SUBTYPE_P2P_DEVICE, + * WLAN_VDEV_MLME_SUBTYPE_P2P_CLIENT, WLAN_VDEV_MLME_SUBTYPE_P2P_GO, + * WLAN_VDEV_MLME_SUBTYPE_PROXY_STA, WLAN_VDEV_MLME_SUBTYPE_MESH + * Return: QDF_STATUS + */ + +static QDF_STATUS mlme_get_vdev_types(enum QDF_OPMODE mode, uint8_t *type, + uint8_t *sub_type) +{ + QDF_STATUS status = QDF_STATUS_SUCCESS; + *type = 0; + *sub_type = 0; + + switch (mode) { + case QDF_STA_MODE: + *type = WLAN_VDEV_MLME_TYPE_STA; + break; + case QDF_SAP_MODE: + *type = WLAN_VDEV_MLME_TYPE_AP; + break; + case QDF_P2P_DEVICE_MODE: + *type = WLAN_VDEV_MLME_TYPE_AP; + *sub_type = WLAN_VDEV_MLME_SUBTYPE_P2P_DEVICE; + break; + case QDF_P2P_CLIENT_MODE: + *type = WLAN_VDEV_MLME_TYPE_STA; + *sub_type = WLAN_VDEV_MLME_SUBTYPE_P2P_CLIENT; + break; + case QDF_P2P_GO_MODE: + *type = WLAN_VDEV_MLME_TYPE_AP; + *sub_type = WLAN_VDEV_MLME_SUBTYPE_P2P_GO; + break; + case QDF_OCB_MODE: + *type = WLAN_VDEV_MLME_TYPE_OCB; + break; + case QDF_IBSS_MODE: + *type = WLAN_VDEV_MLME_TYPE_IBSS; + break; + case QDF_MONITOR_MODE: + *type = WMI_HOST_VDEV_TYPE_MONITOR; + break; + case QDF_NDI_MODE: + *type = WLAN_VDEV_MLME_TYPE_NDI; + break; + default: + mlme_err("Invalid device mode %d", mode); + status = QDF_STATUS_E_INVAL; + break; + } + return status; +} + +static +QDF_STATUS vdevmgr_mlme_ext_post_hdl_create(struct vdev_mlme_obj *vdev_mlme) +{ + QDF_STATUS status; + + sme_get_vdev_type_nss(wlan_vdev_mlme_get_opmode(vdev_mlme->vdev), + &vdev_mlme->proto.generic.nss_2g, + &vdev_mlme->proto.generic.nss_5g); + + status = mlme_get_vdev_types(wlan_vdev_mlme_get_opmode(vdev_mlme->vdev), + &vdev_mlme->mgmt.generic.type, + &vdev_mlme->mgmt.generic.subtype); + if (QDF_IS_STATUS_ERROR(status)) { + mlme_err("Get vdev type failed; status:%d", status); + return status; + } + + status = vdev_mgr_create_send(vdev_mlme); + if (QDF_IS_STATUS_ERROR(status)) { + mlme_err("Failed to create vdev for vdev id %d", + wlan_vdev_get_id(vdev_mlme->vdev)); + return status; + } + + return status; +} + /** * struct sta_mlme_ops - VDEV MLME operation callbacks strucutre for sta * @mlme_vdev_start_send: callback to initiate actions of VDEV @@ -1324,20 +1387,10 @@ static struct vdev_mlme_ops mon_mlme_ops = { .mlme_vdev_ext_start_rsp = vdevmgr_vdev_start_rsp_handle, }; -/** - * struct mlme_ext_ops - MLME legacy global callbacks structure - * @mlme_psoc_ext_hdl_create: callback to invoke creation of legacy - * psoc object - * @mlme_psoc_ext_hdl_destroy: callback to invoke destroy of legacy - * psoc object - * @mlme_vdev_ext_hdl_create: callback to invoke creation of legacy - * vdev object - * @mlme_vdev_ext_hdl_destroy: callback to invoke destroy of legacy - * vdev object - */ static struct mlme_ext_ops ext_ops = { .mlme_psoc_ext_hdl_create = psoc_mlme_ext_hdl_create, .mlme_psoc_ext_hdl_destroy = psoc_mlme_ext_hdl_destroy, .mlme_vdev_ext_hdl_create = vdevmgr_mlme_ext_hdl_create, .mlme_vdev_ext_hdl_destroy = vdevmgr_mlme_ext_hdl_destroy, + .mlme_vdev_ext_hdl_post_create = vdevmgr_mlme_ext_post_hdl_create, }; diff --git a/core/cds/inc/cds_api.h b/core/cds/inc/cds_api.h index cc51afa57a..f9747d0463 100644 --- a/core/cds/inc/cds_api.h +++ b/core/cds/inc/cds_api.h @@ -329,27 +329,6 @@ QDF_STATUS cds_free_context(QDF_MODULE_ID module_id, void *module_context); QDF_STATUS cds_set_context(QDF_MODULE_ID module_id, void *context); -/** - * cds_get_vdev_types() - get vdev type and subtype from it's operation mode - * @mode: operation mode of vdev - * @type: type of vdev - * @sub_type: sub_type of vdev - * - * This API is called to get vdev type and subtype from it's operation mode. - * Vdev operation modes are defined in enum QDF_OPMODE. - * - * Type of vdev are WLAN_VDEV_MLME_TYPE_AP, WLAN_VDEV_MLME_TYPE_STA, - * WLAN_VDEV_MLME_TYPE_IBSS, ,WLAN_VDEV_MLME_TYPE_MONITOR, - * WLAN_VDEV_MLME_TYPE_NAN, WLAN_VDEV_MLME_TYPE_OCB, WLAN_VDEV_MLME_TYPE_NDI - * - * Sub_types of vdev are WLAN_VDEV_MLME_SUBTYPE_P2P_DEVICE, - * WLAN_VDEV_MLME_SUBTYPE_P2P_CLIENT, WLAN_VDEV_MLME_SUBTYPE_P2P_GO, - * WLAN_VDEV_MLME_SUBTYPE_PROXY_STA, WLAN_VDEV_MLME_SUBTYPE_MESH - * Return: QDF_STATUS - */ -QDF_STATUS cds_get_vdev_types(enum QDF_OPMODE mode, uint8_t *type, - uint8_t *sub_type); - void cds_flush_work(void *work); void cds_flush_delayed_work(void *dwork); diff --git a/core/cds/src/cds_api.c b/core/cds/src/cds_api.c index a5a26d642f..7a7f44f58b 100644 --- a/core/cds/src/cds_api.c +++ b/core/cds/src/cds_api.c @@ -1640,51 +1640,6 @@ QDF_STATUS cds_free_context(QDF_MODULE_ID module_id, void *module_context) return QDF_STATUS_SUCCESS; } /* cds_free_context() */ -QDF_STATUS cds_get_vdev_types(enum QDF_OPMODE mode, uint8_t *type, - uint8_t *sub_type) -{ - QDF_STATUS status = QDF_STATUS_SUCCESS; - *type = 0; - *sub_type = 0; - - switch (mode) { - case QDF_STA_MODE: - *type = WLAN_VDEV_MLME_TYPE_STA; - break; - case QDF_SAP_MODE: - *type = WLAN_VDEV_MLME_TYPE_AP; - break; - case QDF_P2P_DEVICE_MODE: - *type = WLAN_VDEV_MLME_TYPE_AP; - *sub_type = WLAN_VDEV_MLME_SUBTYPE_P2P_DEVICE; - break; - case QDF_P2P_CLIENT_MODE: - *type = WLAN_VDEV_MLME_TYPE_STA; - *sub_type = WLAN_VDEV_MLME_SUBTYPE_P2P_CLIENT; - break; - case QDF_P2P_GO_MODE: - *type = WLAN_VDEV_MLME_TYPE_AP; - *sub_type = WLAN_VDEV_MLME_SUBTYPE_P2P_GO; - break; - case QDF_OCB_MODE: - *type = WLAN_VDEV_MLME_TYPE_OCB; - break; - case QDF_IBSS_MODE: - *type = WLAN_VDEV_MLME_TYPE_IBSS; - break; - case QDF_MONITOR_MODE: - *type = WMI_HOST_VDEV_TYPE_MONITOR; - break; - case QDF_NDI_MODE: - *type = WLAN_VDEV_MLME_TYPE_NDI; - break; - default: - cds_err("Invalid device mode %d", mode); - status = QDF_STATUS_E_INVAL; - break; - } - return status; -} /** * cds_flush_work() - flush pending works diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c index 069b960c8d..203e59c0e7 100644 --- a/core/hdd/src/wlan_hdd_main.c +++ b/core/hdd/src/wlan_hdd_main.c @@ -4399,7 +4399,7 @@ int hdd_vdev_destroy(struct hdd_adapter *adapter) /* close sme session (destroy vdev in firmware via legacy API) */ qdf_event_reset(&adapter->qdf_session_close_event); - status = sme_vdev_delete(hdd_ctx->mac_handle, adapter->vdev_id); + status = sme_vdev_delete(hdd_ctx->mac_handle, vdev); if (QDF_IS_STATUS_ERROR(status)) { hdd_err("failed to delete vdev; status:%d", status); goto release_vdev; @@ -4441,13 +4441,6 @@ release_vdev: return 0; } -static int hdd_set_sme_session_param(struct hdd_adapter *adapter, - struct sme_session_params *session_param) -{ - session_param->vdev = adapter->vdev; - return 0; -} - void hdd_store_nss_chains_cfg_in_vdev(struct hdd_adapter *adapter) { @@ -4483,14 +4476,31 @@ bool hdd_is_vdev_in_conn_state(struct hdd_adapter *adapter) return 0; } +static struct vdev_osif_priv * +hdd_init_vdev_os_priv(struct hdd_adapter *adapter) +{ + struct vdev_osif_priv *os_priv; + + os_priv = qdf_mem_malloc(sizeof(*os_priv)); + if (!os_priv) + return NULL; + + /* Initialize the vdev OS private structure*/ + os_priv->wdev = adapter->dev->ieee80211_ptr; + os_priv->legacy_osif_priv = adapter; + + return os_priv; +} + int hdd_vdev_create(struct hdd_adapter *adapter) { QDF_STATUS status; int errno; bool bval; struct hdd_context *hdd_ctx; - struct sme_session_params sme_session_params = {0}; struct wlan_objmgr_vdev *vdev; + struct vdev_osif_priv *osif_priv; + struct wlan_vdev_create_params vdev_params = {0}; hdd_info("creating new vdev"); @@ -4503,26 +4513,39 @@ int hdd_vdev_create(struct hdd_adapter *adapter) errno = qdf_status_to_os_return(status); return errno; } - errno = hdd_objmgr_create_and_store_vdev(hdd_ctx->pdev, adapter); - if (errno) { - hdd_err("failed to create objmgr vdev: %d", errno); - return errno; + + osif_priv = hdd_init_vdev_os_priv(adapter); + if (!osif_priv) { + hdd_err("Failed to allocate osif_priv"); + return -ENOMEM; } - errno = hdd_set_sme_session_param(adapter, &sme_session_params); - if (errno) { - hdd_err("failed to populating SME params"); - goto objmgr_vdev_destroy_procedure; + vdev_params.opmode = adapter->device_mode; + vdev_params.osifp = osif_priv; + qdf_mem_copy(vdev_params.macaddr, + adapter->mac_addr.bytes, + QDF_NET_MAC_ADDR_MAX_LEN); + + vdev = sme_vdev_create(hdd_ctx->mac_handle, &vdev_params); + if (!vdev) { + hdd_err("failed to create vdev"); + return -EINVAL; } - status = sme_create_vdev(hdd_ctx->mac_handle, - &sme_session_params); - if (QDF_IS_STATUS_ERROR(status)) { - hdd_err("failed to create vdev: %d", status); - errno = qdf_status_to_os_return(status); - goto objmgr_vdev_destroy_procedure; + + if (wlan_objmgr_vdev_try_get_ref(vdev, WLAN_HDD_ID_OBJ_MGR) != + QDF_STATUS_SUCCESS) { + errno = QDF_STATUS_E_INVAL; + sme_vdev_delete(hdd_ctx->mac_handle, vdev); + wlan_objmgr_vdev_obj_delete(vdev); + return -EINVAL; } set_bit(SME_SESSION_OPENED, &adapter->event_flags); + qdf_spin_lock_bh(&adapter->vdev_lock); + adapter->vdev_id = wlan_vdev_get_id(vdev); + adapter->vdev = vdev; + qdf_spin_unlock_bh(&adapter->vdev_lock); + /* firmware ready for component communication, raise vdev_ready event */ errno = hdd_vdev_ready(adapter); if (errno) { @@ -4562,16 +4585,6 @@ int hdd_vdev_create(struct hdd_adapter *adapter) return 0; - /* - * Due to legacy constraints, we need to destroy in the same order as - * create. So, split error handling into 2 cases to accommodate. - */ - -objmgr_vdev_destroy_procedure: - QDF_BUG(!hdd_objmgr_release_and_destroy_vdev(adapter)); - - return errno; - hdd_vdev_destroy_procedure: QDF_BUG(!hdd_vdev_destroy(adapter)); diff --git a/core/hdd/src/wlan_hdd_object_manager.c b/core/hdd/src/wlan_hdd_object_manager.c index 00e1d996df..62d96f9198 100644 --- a/core/hdd/src/wlan_hdd_object_manager.c +++ b/core/hdd/src/wlan_hdd_object_manager.c @@ -52,23 +52,6 @@ static void hdd_deinit_pdev_os_priv(struct wlan_objmgr_pdev *pdev) os_if_spectral_netlink_deinit(pdev); wlan_cfg80211_scan_priv_deinit(pdev); } - -static struct vdev_osif_priv * -hdd_init_vdev_os_priv(struct hdd_adapter *adapter) -{ - struct vdev_osif_priv *os_priv; - - os_priv = qdf_mem_malloc(sizeof(*os_priv)); - if (!os_priv) - return NULL; - - /* Initialize the vdev OS private structure*/ - os_priv->wdev = adapter->dev->ieee80211_ptr; - os_priv->legacy_osif_priv = adapter; - - return os_priv; -} - static void hdd_init_psoc_qdf_ctx(struct wlan_objmgr_psoc *psoc) { qdf_device_t qdf_ctx; @@ -231,63 +214,6 @@ int hdd_objmgr_release_and_destroy_pdev(struct hdd_context *hdd_ctx) return qdf_status_to_os_return(status); } -int hdd_objmgr_create_and_store_vdev(struct wlan_objmgr_pdev *pdev, - struct hdd_adapter *adapter) -{ - QDF_STATUS status; - int errno = 0; - struct wlan_objmgr_vdev *vdev; - struct vdev_osif_priv *osif_priv; - struct wlan_vdev_create_params vdev_params = {0}; - - QDF_BUG(pdev); - if (!pdev) { - hdd_err("pdev is null"); - return -EINVAL; - } - - osif_priv = hdd_init_vdev_os_priv(adapter); - if (!osif_priv) { - hdd_err("Failed to allocate osif_priv; out of memory"); - return -ENOMEM; - } - - vdev_params.opmode = adapter->device_mode; - vdev_params.osifp = osif_priv; - qdf_mem_copy(vdev_params.macaddr, - adapter->mac_addr.bytes, - QDF_NET_MAC_ADDR_MAX_LEN); - - vdev = wlan_objmgr_vdev_obj_create(pdev, &vdev_params); - if (!vdev) { - hdd_err("Failed to create vdev object"); - errno = -ENOMEM; - return errno; - } - - /* - * To enable legacy use cases, we need to delay physical vdev destroy - * until after the sme session has been closed. We accomplish this by - * getting a reference here. - */ - status = wlan_objmgr_vdev_try_get_ref(vdev, WLAN_HDD_ID_OBJ_MGR); - if (QDF_IS_STATUS_ERROR(status)) { - hdd_err("Failed to acquire vdev ref; status:%d", status); - errno = qdf_status_to_os_return(status); - goto vdev_destroy; - } - - qdf_spin_lock_bh(&adapter->vdev_lock); - adapter->vdev = vdev; - adapter->vdev_id = wlan_vdev_get_id(vdev); - qdf_spin_unlock_bh(&adapter->vdev_lock); - - return 0; - -vdev_destroy: - wlan_objmgr_vdev_obj_delete(vdev); - return errno; -} int hdd_objmgr_release_and_destroy_vdev(struct hdd_adapter *adapter) { diff --git a/core/hdd/src/wlan_hdd_object_manager.h b/core/hdd/src/wlan_hdd_object_manager.h index 580268cbf9..cf877677b7 100644 --- a/core/hdd/src/wlan_hdd_object_manager.h +++ b/core/hdd/src/wlan_hdd_object_manager.h @@ -109,19 +109,6 @@ int hdd_objmgr_create_and_store_pdev(struct hdd_context *hdd_ctx); */ int hdd_objmgr_release_and_destroy_pdev(struct hdd_context *hdd_ctx); -/** - * hdd_objmgr_create_and_store_vdev() - Create vdev and store in hdd adapter - * @pdev: pdev pointer - * @adapter: hdd adapter - * - * This API creates the vdev object and store the vdev reference to the - * given @adapter. Also, creates a self peer for the vdev. - * - * Return: 0 for success, negative error code for failure - */ -int hdd_objmgr_create_and_store_vdev(struct wlan_objmgr_pdev *pdev, - struct hdd_adapter *adapter); - /** * hdd_objmgr_release_and_destroy_vdev() - Delete vdev and remove from adapter * @adapter: hdd adapter diff --git a/core/sme/inc/sme_api.h b/core/sme/inc/sme_api.h index 3f190856b3..c9e6abb6ca 100644 --- a/core/sme/inc/sme_api.h +++ b/core/sme/inc/sme_api.h @@ -357,34 +357,43 @@ sme_nss_chains_update(mac_handle_t mac_handle, uint8_t vdev_id); /** - * sme_create_vdev() - Create vdev for given persona + * sme_vdev_create() - Create vdev for given persona * @mac_handle: The handle returned by mac_open - * @params: to initialize the session open params + * @vdev_params: params required for vdev creation * - * This is a synchronous API. For any protocol stack related activity - * requires vdev to be created. This API needs to be called to create - * vdev in SME module. + * This API will create the object manager vdev and in the same + * context vdev mlme object manager notification is invoked, which + * will send the vdev create to the firmware. * - * Return: QDF_STATUS_SUCCESS - vdev is created - * Other status means SME is failed to create vdev + * If the vdev creation is successful the following object is referenced + * by below modules: + * 1) WLAN_OBJMGR_ID + * 2) WLAN_LEGACY_SME_ID + * 3) WLAN_LEGACY_WMA_ID + * + * Return: Newly created Vdev object or NULL incase in any error */ -QDF_STATUS sme_create_vdev(mac_handle_t mac_handle, - struct sme_session_params *params); +struct wlan_objmgr_vdev *sme_vdev_create(mac_handle_t mac_handle, + struct wlan_vdev_create_params *vdev_params); + /** * sme_vdev_delete() - Delete vdev for given id + * @mac_handle: The handle returned by mac_open. + * @vdev: VDEV Object * * This is a synchronous API. This API needs to be called to delete vdev * in SME module before terminating the session completely. * - * mac_handle: The handle returned by mac_open. - * vdev_id: A previous created vdev id. + * The following modules releases their reference to the vdev object: + * 1) WLAN_LEGACY_WMA_ID + * 2) WLAN_LEGACY_SME_ID * - * Return: - * QDF_STATUS_SUCCESS - vdev is deleted. - * Other status means SME is failed to delete vdev. + * Return: QDF_STATUS_SUCCESS - vdev is deleted. + * QDF_STATUS_E_INVAL when failed to delete vdev. */ -QDF_STATUS sme_vdev_delete(mac_handle_t mac_handle, uint8_t vdev_id); +QDF_STATUS sme_vdev_delete(mac_handle_t mac_handle, + struct wlan_objmgr_vdev *vdev); /** * sme_cleanup_session() - clean up sme session info for vdev diff --git a/core/sme/src/common/sme_api.c b/core/sme/src/common/sme_api.c index 7a12549fee..13673e76ab 100644 --- a/core/sme/src/common/sme_api.c +++ b/core/sme/src/common/sme_api.c @@ -4499,38 +4499,77 @@ release_ref: return status; } -QDF_STATUS sme_create_vdev(mac_handle_t mac_handle, - struct sme_session_params *params) +struct wlan_objmgr_vdev *sme_vdev_create(mac_handle_t mac_handle, + struct wlan_vdev_create_params *vdev_params) { QDF_STATUS status = QDF_STATUS_E_INVAL; struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); uint8_t vdev_id; - u8 *mac_addr; + struct wlan_objmgr_vdev *vdev; + struct vdev_mlme_obj *vdev_mlme; - vdev_id = wlan_vdev_get_id(params->vdev); - mac_addr = wlan_vdev_mlme_get_macaddr(params->vdev); + sme_debug("addr:%pM opmode:%d", vdev_params->macaddr, + vdev_params->opmode); - sme_debug("vdev_id %d addr:%pM", vdev_id, mac_addr); + vdev = wlan_objmgr_vdev_obj_create(mac_ctx->pdev, vdev_params); + if (!vdev) { + sme_err("Failed to create vdev object"); + return NULL; + } - status = sme_acquire_global_lock(&mac_ctx->sme); - if (QDF_IS_STATUS_ERROR(status)) - return status; + if (wlan_objmgr_vdev_try_get_ref(vdev, WLAN_LEGACY_SME_ID) != + QDF_STATUS_SUCCESS) { + wlan_objmgr_vdev_obj_delete(vdev); + return NULL; + } - status = csr_create_vdev(mac_ctx, params->vdev, params); - if (QDF_IS_STATUS_SUCCESS(status)) - status = mlme_vdev_self_peer_create(params->vdev); - sme_release_global_lock(&mac_ctx->sme); + vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev); + if (!vdev_mlme) { + sme_err("Failed to get vdev mlme obj!"); + QDF_BUG(0); + goto vdev_obj_del; + } - MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_RX_HDD_OPEN_SESSION, + vdev_id = wlan_vdev_get_id(vdev); + status = wma_post_vdev_create_setup(vdev); + if (QDF_IS_STATUS_ERROR(status)) { + sme_err("Failed to setup wma for vdev: %d", vdev_id); + goto vdev_obj_del; + } + + status = csr_setup_vdev_session(vdev_mlme); + if (QDF_IS_STATUS_ERROR(status)) { + sme_err("Failed to setup CSR layer for vdev: %d", vdev_id); + goto cleanup_wma; + } + + status = mlme_vdev_self_peer_create(vdev); + if (QDF_IS_STATUS_ERROR(status)) { + sme_err("Failed to create vdev selfpeer for vdev:%d", vdev_id); + goto csr_cleanup_vdev_session; + } + MTRACE(qdf_trace(QDF_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_OPEN_SESSION, vdev_id, 0)); - return status; + return vdev; + +csr_cleanup_vdev_session: + csr_cleanup_vdev_session(mac_ctx, vdev_id); +cleanup_wma: + wma_cleanup_vdev(vdev); +vdev_obj_del: + wlan_objmgr_vdev_obj_delete(vdev); + wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID); + return NULL; } -QDF_STATUS sme_vdev_delete(mac_handle_t mac_handle, uint8_t vdev_id) +QDF_STATUS sme_vdev_delete(mac_handle_t mac_handle, + struct wlan_objmgr_vdev *vdev) { QDF_STATUS status; struct mac_context *mac = MAC_CONTEXT(mac_handle); + uint8_t vdev_id = wlan_vdev_get_id(vdev); MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_RX_HDD_CLOSE_SESSION, vdev_id, 0)); @@ -4540,6 +4579,8 @@ QDF_STATUS sme_vdev_delete(mac_handle_t mac_handle, uint8_t vdev_id) sme_release_global_lock(&mac->sme); } + /* Release the reference acquired during vdev create */ + wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID); return status; } @@ -4551,7 +4592,7 @@ void sme_cleanup_session(mac_handle_t mac_handle, uint8_t vdev_id) status = sme_acquire_global_lock(&mac->sme); if (QDF_IS_STATUS_ERROR(status)) return; - csr_cleanup_session(mac, vdev_id); + csr_cleanup_vdev_session(mac, vdev_id); sme_release_global_lock(&mac->sme); } @@ -13400,14 +13441,7 @@ QDF_STATUS sme_process_mac_pwr_dbg_cmd(mac_handle_t mac_handle, void sme_get_vdev_type_nss(enum QDF_OPMODE dev_mode, uint8_t *nss_2g, uint8_t *nss_5g) { - struct mac_context *mac_ctx = sme_get_mac_context(); - - if (!mac_ctx) { - QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, - FL("Invalid MAC context")); - return; - } - csr_get_vdev_type_nss(mac_ctx, dev_mode, nss_2g, nss_5g); + csr_get_vdev_type_nss(dev_mode, nss_2g, nss_5g); } /** diff --git a/core/sme/src/csr/csr_api_roam.c b/core/sme/src/csr/csr_api_roam.c index bca0de78a9..6b1a87d4c8 100644 --- a/core/sme/src/csr/csr_api_roam.c +++ b/core/sme/src/csr/csr_api_roam.c @@ -17199,21 +17199,16 @@ static void csr_send_set_ie(uint8_t type, uint8_t sub_type, sme_err("Failed to send set IE req for vdev_%d", vdev_id); } -/** - * csr_get_vdev_type_nss() - gets the nss value based on vdev type - * @mac_ctx: Pointer to Global MAC structure - * @dev_mode: current device operating mode. - * @nss2g: Pointer to the 2G Nss parameter. - * @nss5g: Pointer to the 5G Nss parameter. - * - * Fills the 2G and 5G Nss values based on device mode. - * - * Return: None - */ -void csr_get_vdev_type_nss(struct mac_context *mac_ctx, - enum QDF_OPMODE dev_mode, - uint8_t *nss_2g, uint8_t *nss_5g) +void csr_get_vdev_type_nss(enum QDF_OPMODE dev_mode, uint8_t *nss_2g, + uint8_t *nss_5g) { + struct mac_context *mac_ctx = sme_get_mac_context(); + + if (!mac_ctx) { + sme_err("Invalid MAC context"); + return; + } + switch (dev_mode) { case QDF_STA_MODE: *nss_2g = mac_ctx->vdev_type_nss_2g.sta; @@ -17261,19 +17256,25 @@ void csr_get_vdev_type_nss(struct mac_context *mac_ctx, dev_mode, *nss_2g, *nss_5g); } -QDF_STATUS csr_create_vdev(struct mac_context *mac_ctx, - struct wlan_objmgr_vdev *vdev, - struct sme_session_params *session_param) +QDF_STATUS csr_setup_vdev_session(struct vdev_mlme_obj *vdev_mlme) { QDF_STATUS status; uint32_t existing_session_id; struct mlme_ht_capabilities_info *ht_cap_info; struct csr_roam_session *session; struct mlme_vht_capabilities_info *vht_cap_info; - struct vdev_mlme_obj *vdev_mlme; - enum QDF_OPMODE op_mode; u8 vdev_id; struct qdf_mac_addr *mac_addr; + mac_handle_t mac_handle; + struct mac_context *mac_ctx; + struct wlan_objmgr_vdev *vdev; + + mac_handle = cds_get_context(QDF_MODULE_ID_SME); + mac_ctx = MAC_CONTEXT(mac_handle); + if (!mac_ctx) { + QDF_ASSERT(0); + return QDF_STATUS_E_INVAL; + } if (!(mac_ctx->mlme_cfg)) { sme_err("invalid mlme cfg"); @@ -17281,28 +17282,10 @@ QDF_STATUS csr_create_vdev(struct mac_context *mac_ctx, } vht_cap_info = &mac_ctx->mlme_cfg->vht_caps.vht_cap_info; - vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev); - if (!vdev_mlme) { - sme_err("Failed to get cmpt obj"); - return QDF_STATUS_E_FAILURE; - } + vdev = vdev_mlme->vdev; - vdev_id = wlan_vdev_get_id(session_param->vdev); - mac_addr = (struct qdf_mac_addr *) - wlan_vdev_mlme_get_macaddr(session_param->vdev); - - op_mode = wlan_vdev_mlme_get_opmode(vdev); - csr_get_vdev_type_nss(mac_ctx, op_mode, - &vdev_mlme->proto.generic.nss_2g, - &vdev_mlme->proto.generic.nss_5g); - - status = cds_get_vdev_types(op_mode, - &vdev_mlme->mgmt.generic.type, - &vdev_mlme->mgmt.generic.subtype); - if (QDF_IS_STATUS_ERROR(status)) { - sme_err("Get vdev type failed; status:%d", status); - return status; - } + vdev_id = wlan_vdev_get_id(vdev); + mac_addr = (struct qdf_mac_addr *)wlan_vdev_mlme_get_macaddr(vdev); /* check to see if the mac address already belongs to a session */ status = csr_roam_get_session_id_from_bssid(mac_ctx, mac_addr, @@ -17393,13 +17376,6 @@ QDF_STATUS csr_create_vdev(struct mac_context *mac_ctx, */ csr_init_session_twt_cap(session, vdev_mlme->mgmt.generic.type); - status = mlme_vdev_create_send(vdev); - - if (QDF_IS_STATUS_ERROR(status)) { - csr_cleanup_session(mac_ctx, vdev_id); - return status; - } - csr_send_set_ie(vdev_mlme->mgmt.generic.type, vdev_mlme->mgmt.generic.subtype, wlan_vdev_get_id(vdev)); @@ -17435,7 +17411,7 @@ QDF_STATUS csr_process_vdev_del_rsp(struct mac_context *mac_ctx, * for this vdev. Active cmnd is e_sme_command_del_vdev and will * be removed anyway next. */ - csr_cleanup_session(mac_ctx, vdev_id); + csr_cleanup_vdev_session(mac_ctx, vdev_id); if (rsp->sme_callback) { status = sme_release_global_lock(&mac_ctx->sme); @@ -17491,7 +17467,7 @@ csr_issue_vdev_del_req(struct mac_context *mac_ctx, uint8_t vdev_id, return status; } -void csr_cleanup_session(struct mac_context *mac, uint8_t vdev_id) +void csr_cleanup_vdev_session(struct mac_context *mac, uint8_t vdev_id) { if (CSR_IS_SESSION_VALID(mac, vdev_id)) { struct csr_roam_session *pSession = CSR_GET_SESSION(mac, @@ -17531,7 +17507,7 @@ QDF_STATUS csr_roam_vdev_delete(struct mac_context *mac_ctx, /* Vdev going down stop roaming */ session->fCancelRoaming = true; if (cleanup) { - csr_cleanup_session(mac_ctx, vdev_id); + csr_cleanup_vdev_session(mac_ctx, vdev_id); return status; } diff --git a/core/sme/src/csr/csr_inside_api.h b/core/sme/src/csr/csr_inside_api.h index 6b7260cf9e..88fdbb7f4c 100644 --- a/core/sme/src/csr/csr_inside_api.h +++ b/core/sme/src/csr/csr_inside_api.h @@ -377,7 +377,7 @@ QDF_STATUS csr_roam_vdev_delete(struct mac_context *mac_ctx, uint8_t vdev_id, bool cleanup); /* - * csr_cleanup_session() - CSR api to cleanup vdev + * csr_cleanup_vdev_session() - CSR api to cleanup vdev * @mac_ctx: pointer to mac context * @vdev_id: vdev id to be deleted. * @@ -386,7 +386,7 @@ QDF_STATUS csr_roam_vdev_delete(struct mac_context *mac_ctx, * * Return QDF_STATUS */ -void csr_cleanup_session(struct mac_context *mac, uint8_t vdev_id); +void csr_cleanup_vdev_session(struct mac_context *mac, uint8_t vdev_id); QDF_STATUS csr_roam_get_session_id_from_bssid(struct mac_context *mac, struct qdf_mac_addr *bssid, @@ -567,9 +567,18 @@ void csr_release_command_buffer(struct mac_context *mac, tSmeCmd *pCommand); bool csr_is_profile_wapi(struct csr_roam_profile *pProfile); #endif /* FEATURE_WLAN_WAPI */ -void csr_get_vdev_type_nss(struct mac_context *mac_ctx, - enum QDF_OPMODE dev_mode, - uint8_t *nss_2g, uint8_t *nss_5g); +/** + * csr_get_vdev_type_nss() - gets the nss value based on vdev type + * @dev_mode: current device operating mode. + * @nss2g: Pointer to the 2G Nss parameter. + * @nss5g: Pointer to the 5G Nss parameter. + * + * Fills the 2G and 5G Nss values based on device mode. + * + * Return: None + */ +void csr_get_vdev_type_nss(enum QDF_OPMODE dev_mode, uint8_t *nss_2g, + uint8_t *nss_5g); #ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR @@ -1120,16 +1129,15 @@ csr_scan_get_channel_for_hw_mode_change( struct mac_context *mac_ctx, uint32_t session_id, struct csr_roam_profile *profile); /** - * csr_create_vdev() - API to create vdev - * @mac_ctx: pointer to mac context - * @vdev: vdev object - * @session_param: Session params + * csr_setup_vdev_session() - API to setup vdev mac session + * @vdev_mlme: vdev mlme private object + * + * This API setsup the vdev session for the mac layer * * Returns: QDF_STATUS */ -QDF_STATUS csr_create_vdev(struct mac_context *mac, - struct wlan_objmgr_vdev *vdev, - struct sme_session_params *session_param); +QDF_STATUS csr_setup_vdev_session(struct vdev_mlme_obj *vdev_mlme); + #ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR /** diff --git a/core/wma/inc/wma_api.h b/core/wma/inc/wma_api.h index 881e1f8cb7..8751d2b5ce 100644 --- a/core/wma/inc/wma_api.h +++ b/core/wma/inc/wma_api.h @@ -773,4 +773,15 @@ void wma_update_roam_offload_flag(void *handle, * Return: QDF_STATUS */ QDF_STATUS wma_vdev_self_peer_create(struct vdev_mlme_obj *vdev_mlme); + +/** + * wma_cleanup_vdev() - cleanup wma layers vdev + * @vdev: Object manager vdev + * + * This function cleansup the wma layers vdev related data. + * + * Return: None + */ +void wma_cleanup_vdev(struct wlan_objmgr_vdev *vdev); + #endif /* WMA_API_H */ diff --git a/core/wma/src/wma_dev_if.c b/core/wma/src/wma_dev_if.c index 7ed4452a57..a7a68ddecd 100644 --- a/core/wma/src/wma_dev_if.c +++ b/core/wma/src/wma_dev_if.c @@ -2467,14 +2467,38 @@ QDF_STATUS wma_vdev_stop_resp_handler(struct vdev_mlme_obj *vdev_mlme, return status; } -static void wma_clean_up_iface(void *soc, tp_wma_handle wma_handle, - struct wlan_objmgr_vdev *vdev) +void wma_cleanup_vdev(struct wlan_objmgr_vdev *vdev) { + tp_wma_handle wma_handle; + void *soc = cds_get_context(QDF_MODULE_ID_SOC); uint8_t vdev_id = wlan_vdev_get_id(vdev); + struct vdev_mlme_obj *vdev_mlme; + + if (!soc) { + wma_err("SOC handle is NULL"); + return; + } + + wma_handle = cds_get_context(QDF_MODULE_ID_WMA); + if (!wma_handle) { + wma_err("WMA context is invalid"); + return; + } + + if (!wma_handle->interfaces[vdev_id].vdev) { + wma_err("vdev is NULL"); + return; + } + + vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev); + if (!vdev_mlme) { + wma_err("Failed to get vdev mlme obj for vdev id %d", vdev_id); + return; + } wma_cdp_vdev_detach(soc, wma_handle, vdev_id); - wma_handle->interfaces[vdev_id].vdev = NULL; wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_WMA_ID); + wma_handle->interfaces[vdev_id].vdev = NULL; wma_handle->interfaces[vdev_id].vdev_active = false; } @@ -2485,12 +2509,6 @@ QDF_STATUS wma_vdev_self_peer_create(struct vdev_mlme_obj *vdev_mlme) struct wlan_objmgr_vdev *vdev = vdev_mlme->vdev; struct cdp_pdev *txrx_pdev = cds_get_context(QDF_MODULE_ID_TXRX); tp_wma_handle wma_handle; - void *soc = cds_get_context(QDF_MODULE_ID_SOC); - - if (!soc) { - wma_err("SOC handle is NULL"); - return QDF_STATUS_E_INVAL; - } if (!txrx_pdev) { wma_err("TXRX PDEV is NULL"); @@ -2523,10 +2541,6 @@ QDF_STATUS wma_vdev_self_peer_create(struct vdev_mlme_obj *vdev_mlme) } } - /* If error cleanup the interface */ - if (QDF_IS_STATUS_ERROR(status)) - wma_clean_up_iface(soc, wma_handle, vdev); - return status; } @@ -2813,7 +2827,7 @@ QDF_STATUS wma_post_vdev_create_setup(struct wlan_objmgr_vdev *vdev) return QDF_STATUS_SUCCESS; end: - wma_clean_up_iface(soc, wma_handle, vdev); + wma_cleanup_vdev(vdev); return QDF_STATUS_E_FAILURE; }