Procházet zdrojové kódy

qcacld-3.0: Send vdev create to fw from object create notification

Send vdev create to firmware when the mlme vdev create handler
is invoked as part of the vdev object create.

Change-Id: Ibba02f6b5885d7b3a62529ef51768f520395513e
CRs-Fixed: 2555943
Arun Kumar Khandavalli před 5 roky
rodič
revize
4f6a5bd519

+ 87 - 34
components/mlme/core/src/wlan_mlme_vdev_mgr_interface.c

@@ -1172,47 +1172,110 @@ vdevmgr_vdev_start_rsp_handle(struct vdev_mlme_obj *vdev_mlme,
 	return status;
 }
 
-QDF_STATUS mlme_vdev_create_send(struct wlan_objmgr_vdev *vdev)
+QDF_STATUS mlme_vdev_self_peer_create(struct wlan_objmgr_vdev *vdev)
 {
-	struct vdev_mlme_obj *vdev_mlme = NULL;
-	QDF_STATUS status;
+	struct vdev_mlme_obj *vdev_mlme;
 
 	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;
+		return QDF_STATUS_E_INVAL;
 	}
 
-	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;
-	}
+	return wma_vdev_self_peer_create(vdev_mlme);
+}
 
-	status = wma_post_vdev_create_setup(vdev);
+/**
+ * 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
+ */
 
-	if (QDF_IS_STATUS_ERROR(status))
-		vdev_mgr_delete_send(vdev_mlme);
+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;
 
-return_status:
+	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;
 }
 
-QDF_STATUS mlme_vdev_self_peer_create(struct wlan_objmgr_vdev *vdev)
+static
+QDF_STATUS vdevmgr_mlme_ext_post_hdl_create(struct vdev_mlme_obj *vdev_mlme)
 {
-	struct vdev_mlme_obj *vdev_mlme;
+	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));
-		return QDF_STATUS_E_INVAL;
+	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;
 	}
 
-	return wma_vdev_self_peer_create(vdev_mlme);
+	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;
 }
 
 /**
@@ -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,
 };

+ 0 - 21
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);
 

+ 0 - 45
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

+ 46 - 33
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));
 

+ 0 - 74
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)
 {

+ 0 - 13
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

+ 24 - 15
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

+ 59 - 25
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;
+	}
+
+	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;
+	}
 
-	MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_RX_HDD_OPEN_SESSION,
+	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);
 }
 
 /**

+ 26 - 50
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_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);
+	vdev = vdev_mlme->vdev;
 
-	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;
 	}
 

+ 20 - 12
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
 /**

+ 11 - 0
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 */

+ 28 - 14
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;
 }