Quellcode durchsuchen

qcacld-3.0: (Part-3) Refactor open and close session logic in HDD module

Current open and close session APIs mainly defined in HDD, SME, and SAP
modules are not proper. They require some design changes to maintain the
consistency.

In order to achieve the goal of making symmetrical design for open
and close session logic, refactor existing API in HDD module.

CRs-Fixed: 2147971
Change-Id: Icdf8b0f99bc9fb828f7c68a32e5d25652baa8a17
Krunal Soni vor 7 Jahren
Ursprung
Commit
b51eec7368

+ 4 - 2
core/hdd/inc/wlan_hdd_main.h

@@ -1844,7 +1844,8 @@ struct hdd_adapter *hdd_get_adapter_by_vdev(struct hdd_context *hdd_ctx,
 struct hdd_adapter *hdd_get_adapter_by_macaddr(struct hdd_context *hdd_ctx,
 					  tSirMacAddr macAddr);
 
-int hdd_vdev_create(struct hdd_adapter *adapter);
+int hdd_vdev_create(struct hdd_adapter *adapter,
+		    csr_roam_completeCallback callback, void *ctx);
 int hdd_vdev_destroy(struct hdd_adapter *adapter);
 int hdd_vdev_ready(struct hdd_adapter *adapter);
 
@@ -2376,7 +2377,8 @@ static inline int wlan_hdd_nl_init(struct hdd_context *hdd_ctx)
 	return nl_srv_init(hdd_ctx->wiphy);
 }
 #endif
-QDF_STATUS hdd_sme_close_session_callback(void *pContext);
+QDF_STATUS hdd_sme_open_session_callback(uint8_t session_id);
+QDF_STATUS hdd_sme_close_session_callback(uint8_t session_id);
 
 int hdd_reassoc(struct hdd_adapter *adapter, const uint8_t *bssid,
 		uint8_t channel, const handoff_src src);

+ 0 - 6
core/hdd/src/wlan_hdd_assoc.c

@@ -4423,12 +4423,6 @@ hdd_sme_roam_callback(void *pContext, struct csr_roam_info *roam_info,
 				 adapter->session_id, roamStatus));
 
 	switch (roamStatus) {
-	case eCSR_ROAM_SESSION_OPENED:
-		set_bit(SME_SESSION_OPENED, &adapter->event_flags);
-		complete(&adapter->session_open_comp_var);
-		hdd_debug("session %d opened", adapter->session_id);
-		break;
-
 	/*
 	 * We did pre-auth,then we attempted a 11r or ese reassoc.
 	 * reassoc failed due to failure, timeout, reject from ap

+ 1 - 1
core/hdd/src/wlan_hdd_cfg80211.c

@@ -13839,7 +13839,7 @@ static int wlan_hdd_change_client_iface_to_new_mode(struct net_device *ndev,
 	wext->roamProfile.nAddIEScanLength =
 		adapter->scan_info.scan_add_ie.length;
 	if (type == NL80211_IFTYPE_ADHOC) {
-		status = hdd_init_station_mode(adapter);
+		status = hdd_start_station_adapter(adapter);
 		wext->roamProfile.BSSType = eCSR_BSS_TYPE_START_IBSS;
 		wext->roamProfile.phyMode =
 			hdd_cfg_xlate_to_csr_phy_mode(config->dot11Mode);

+ 40 - 93
core/hdd/src/wlan_hdd_hostapd.c

@@ -219,53 +219,40 @@ int hdd_sap_context_init(struct hdd_context *hdd_ctx)
 	return 0;
 }
 
-struct sap_context *
-hdd_hostapd_init_sap_session(struct hdd_adapter *adapter,
-			     bool reinit)
+/**
+ * hdd_hostapd_init_sap_session() - To init the sap session completely
+ * @adapter: SAP/GO adapter
+ *
+ * This API will do
+ * 1) sap_init_ctx()
+ *
+ * Return: 0 if success else non-zero value.
+ */
+static struct sap_context *
+hdd_hostapd_init_sap_session(struct hdd_adapter *adapter)
 {
 	struct sap_context *sap_ctx;
-	struct hdd_context *hdd_ctx;
 	QDF_STATUS status;
 
 	if (!adapter) {
 		hdd_err("invalid adapter");
 		return NULL;
 	}
-	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
 
-	if (reinit)
-		sap_ctx = adapter->session.ap.sap_context;
-	else
-		sap_ctx = sap_create_ctx();
+	sap_ctx = adapter->session.ap.sap_context;
 
 	if (!sap_ctx) {
 		hdd_err("can't allocate the sap_ctx");
 		return NULL;
 	}
-
-	/*
-	 * This is a special case of hdd_vdev_create(). In phase 4 convergence,
-	 * this special case will be properly addressed.
-	 */
-	if (hdd_objmgr_create_and_store_vdev(hdd_ctx->hdd_pdev, adapter)) {
-		hdd_err("failed to create objmgr vdev");
-		goto error;
-	}
 	status = sap_init_ctx(sap_ctx, adapter->device_mode,
 			       adapter->mac_addr.bytes,
 			       adapter->session_id);
 	if (QDF_IS_STATUS_ERROR(status)) {
 		hdd_err("wlansap_start failed!! status: %d", status);
 		adapter->session.ap.sap_context = NULL;
-
-		/*
-		 * In this case, we need to cleanup in the same order as create.
-		 * See hdd_vdev_create() for more details.
-		 */
-		QDF_BUG(!hdd_objmgr_release_and_destroy_vdev(adapter));
 		goto error;
 	}
-
 	return sap_ctx;
 error:
 	wlansap_context_put(sap_ctx);
@@ -275,7 +262,17 @@ error:
 	return NULL;
 }
 
-int hdd_hostapd_deinit_sap_session(struct hdd_adapter *adapter)
+/**
+ * hdd_hostapd_deinit_sap_session() - To de-init the sap session completely
+ * @adapter: SAP/GO adapter
+ *
+ * This API will do
+ * 1) sap_init_ctx()
+ * 2) sap_destroy_ctx()
+ *
+ * Return: 0 if success else non-zero value.
+ */
+static int hdd_hostapd_deinit_sap_session(struct hdd_adapter *adapter)
 {
 	struct sap_context *sap_ctx;
 	int status = 0;
@@ -295,23 +292,13 @@ int hdd_hostapd_deinit_sap_session(struct hdd_adapter *adapter)
 		hdd_err("Error stopping the sap session");
 		status = -EINVAL;
 	}
-	if (hdd_objmgr_destroy_vdev(adapter)) {
-		hdd_err("objmgr vdev destroy failed");
-		status = -EINVAL;
-	}
+
 	if (!QDF_IS_STATUS_SUCCESS(sap_destroy_ctx(sap_ctx))) {
 		hdd_err("Error closing the sap session");
 		status = -EINVAL;
 	}
 	adapter->session.ap.sap_context = NULL;
 
-	if (!wlan_hdd_validate_session_id(adapter->session_id)) {
-		if (hdd_objmgr_release_vdev(adapter)) {
-			hdd_err("objmgr vdev release failed");
-			status = -EINVAL;
-		}
-	}
-
 	if (!QDF_IS_STATUS_SUCCESS(status))
 		hdd_debug("sap has issue closing the session");
 	else
@@ -6164,24 +6151,13 @@ QDF_STATUS hdd_init_ap_mode(struct hdd_adapter *adapter, bool reinit)
 
 	hdd_info("SSR in progress: %d", reinit);
 
-	/*
-	 * check if adapter is already open then most likely
-	 * SAP session is already initialized, no need to do anything
-	 * further
-	 */
-	if (test_bit(SME_SESSION_OPENED, &adapter->event_flags)) {
-		hdd_debug("sap context is not NULL, %pK",
-			  adapter->session.ap.sap_context);
-		return QDF_STATUS_SUCCESS;
-	}
-
-	sapContext = hdd_hostapd_init_sap_session(adapter, reinit);
+	sapContext = hdd_hostapd_init_sap_session(adapter);
 	if (!sapContext) {
 		hdd_err("Invalid sap_ctx");
-		return QDF_STATUS_E_FAULT;
+		goto error_release_vdev;
 	}
+
 	if (!reinit) {
-		adapter->session.ap.sap_context = sapContext;
 		adapter->session.ap.sap_config.channel =
 			hdd_ctx->acs_policy.acs_channel;
 		acs_dfs_mode = hdd_ctx->acs_policy.acs_dfs_mode;
@@ -6189,15 +6165,6 @@ QDF_STATUS hdd_init_ap_mode(struct hdd_adapter *adapter, bool reinit)
 			wlan_hdd_get_dfs_mode(acs_dfs_mode);
 	}
 
-	/* set SME_SESSION_OPENED since sap session started */
-	set_bit(SME_SESSION_OPENED, &adapter->event_flags);
-
-	ret = hdd_vdev_ready(adapter);
-	if (ret) {
-		hdd_err("failed to raise vdev ready event: %d", ret);
-		goto error_init_ap_mode;
-	}
-
 	/* Allocate the Wireless Extensions state structure */
 	phostapdBuf = WLAN_HDD_GET_HOSTAP_STATE_PTR(adapter);
 
@@ -6209,37 +6176,37 @@ QDF_STATUS hdd_init_ap_mode(struct hdd_adapter *adapter, bool reinit)
 	status = qdf_event_create(&phostapdBuf->qdf_event);
 	if (!QDF_IS_STATUS_SUCCESS(status)) {
 		hdd_err("Hostapd HDD qdf event init failed!!");
-		goto error_init_ap_mode;
+		goto error_release_sap_session;
 	}
 
 	status = qdf_event_create(&phostapdBuf->qdf_stop_bss_event);
 	if (!QDF_IS_STATUS_SUCCESS(status)) {
 		hdd_err("Hostapd HDD stop bss event init failed!!");
-		goto error_init_ap_mode;
+		goto error_release_sap_session;
 	}
 
 	status = qdf_event_create(&phostapdBuf->qdf_sta_disassoc_event);
 	if (!QDF_IS_STATUS_SUCCESS(status)) {
 		hdd_err("Hostapd HDD sta disassoc event init failed!!");
-		goto error_init_ap_mode;
+		goto error_release_sap_session;
 	}
 
-	init_completion(&adapter->session_close_comp_var);
-	init_completion(&adapter->session_open_comp_var);
 
 	/* Register as a wireless device */
 	dev->wireless_handlers = (struct iw_handler_def *)&hostapd_handler_def;
 
 	/* Initialize the data path module */
 	status = hdd_softap_init_tx_rx(adapter);
-	if (!QDF_IS_STATUS_SUCCESS(status))
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
 		hdd_err("hdd_softap_init_tx_rx failed");
+		goto error_release_sap_session;
+	}
 
 	status = hdd_wmm_adapter_init(adapter);
 	if (!QDF_IS_STATUS_SUCCESS(status)) {
 		hdd_err("hdd_wmm_adapter_init() failed code: %08d [x%08x]",
 		       status, status);
-		goto error_wmm_init;
+		goto error_release_wmm;
 	}
 
 	set_bit(WMM_INIT_DONE, &adapter->event_flags);
@@ -6266,12 +6233,12 @@ QDF_STATUS hdd_init_ap_mode(struct hdd_adapter *adapter, bool reinit)
 
 	return status;
 
-error_wmm_init:
+error_release_wmm:
 	hdd_softap_deinit_tx_rx(adapter);
-
-error_init_ap_mode:
+error_release_sap_session:
 	hdd_hostapd_deinit_sap_session(adapter);
-	QDF_BUG(!hdd_objmgr_release_vdev(adapter));
+error_release_vdev:
+	QDF_BUG(!hdd_vdev_destroy(adapter));
 
 	EXIT();
 	return status;
@@ -6306,7 +6273,6 @@ void hdd_deinit_ap_mode(struct hdd_context *hdd_ctx,
 	}
 	if (hdd_hostapd_deinit_sap_session(adapter))
 		hdd_err("Failed:hdd_hostapd_deinit_sap_session");
-	clear_bit(SME_SESSION_OPENED, &adapter->event_flags);
 
 	EXIT();
 }
@@ -6384,6 +6350,8 @@ struct hdd_adapter *hdd_wlan_create_ap_dev(struct hdd_context *hdd_ctx,
 	adapter->wdev.wiphy = hdd_ctx->wiphy;
 	adapter->wdev.netdev = dev;
 	hdd_set_tso_flags(hdd_ctx, dev);
+	init_completion(&adapter->session_close_comp_var);
+	init_completion(&adapter->session_open_comp_var);
 	init_completion(&adapter->tx_action_cnf_event);
 	init_completion(&adapter->cancel_rem_on_chan_var);
 	init_completion(&adapter->rem_on_chan_ready_event);
@@ -8876,27 +8844,6 @@ void hdd_sap_indicate_disconnect_for_sta(struct hdd_adapter *adapter)
 	EXIT();
 }
 
-/**
- * hdd_sap_destroy_events() - Destroy sap evets
- * @adapter: sap adapter context
- *
- * Return:   nothing
- */
-void hdd_sap_destroy_events(struct hdd_adapter *adapter)
-{
-	struct sap_context *sap_ctx;
-
-	ENTER();
-	sap_ctx = WLAN_HDD_GET_SAP_CTX_PTR(adapter);
-	if (!sap_ctx) {
-		hdd_err("invalid sap context");
-		return;
-	}
-
-	qdf_event_destroy(&sap_ctx->sap_session_opened_evt);
-	EXIT();
-}
-
 bool hdd_is_peer_associated(struct hdd_adapter *adapter,
 			    struct qdf_mac_addr *mac_addr)
 {

+ 1 - 27
core/hdd/src/wlan_hdd_hostapd.h

@@ -122,30 +122,6 @@ int hdd_softap_unpack_ie(tHalHandle halHandle,
 			 bool *pMFPCapable,
 			 bool *pMFPRequired,
 			 uint16_t gen_ie_len, uint8_t *gen_ie);
-/**
- * hdd_hostapd_deinit_sap_session() - To de-init the sap session completely
- * @adapter: SAP/GO adapter
- *
- * This API will do
- * 1) wlansap_stop(), wlansap_close()
- * 2) destroys and releases the vdev objects
- *
- * Return: 0 if success else non-zero value.
- */
-int hdd_hostapd_deinit_sap_session(struct hdd_adapter *adapter);
-
-/**
- * hdd_hostapd_init_sap_session() - To init the sap session completely
- * @adapter: SAP/GO adapter
- *
- * This API will do
- * 1) sap_create_ctx(), wlansap_start()
- * 2) creates and stores the vdev objects
- *
- * Return: 0 if success else non-zero value.
- */
-struct sap_context *
-hdd_hostapd_init_sap_session(struct hdd_adapter *adapter, bool reinit);
 
 QDF_STATUS hdd_hostapd_sap_event_cb(tpSap_Event pSapEvent,
 				    void *usrDataForCallback);
@@ -170,8 +146,7 @@ QDF_STATUS hdd_init_ap_mode(struct hdd_adapter *adapter, bool reinit);
  * SAP adapter related params.
  */
 void hdd_deinit_ap_mode(struct hdd_context *hdd_ctx,
-		struct hdd_adapter *adapter,
-		bool rtnl_held);
+			struct hdd_adapter *adapter, bool rtnl_held);
 void hdd_set_ap_ops(struct net_device *dev);
 /**
  * hdd_sap_create_ctx() - Wrapper API to create SAP context
@@ -231,5 +206,4 @@ QDF_STATUS wlan_hdd_config_acs(struct hdd_context *hdd_ctx,
 			       struct hdd_adapter *adapter);
 
 void hdd_sap_indicate_disconnect_for_sta(struct hdd_adapter *adapter);
-void hdd_sap_destroy_events(struct hdd_adapter *adapter);
 #endif /* end #if !defined(WLAN_HDD_HOSTAPD_H) */

+ 131 - 41
core/hdd/src/wlan_hdd_main.c

@@ -3257,10 +3257,41 @@ static QDF_STATUS hdd_register_interface(struct hdd_adapter *adapter, bool rtnl_
 	return QDF_STATUS_SUCCESS;
 }
 
-QDF_STATUS hdd_sme_close_session_callback(void *pContext)
+QDF_STATUS hdd_sme_open_session_callback(uint8_t session_id)
 {
-	struct hdd_adapter *adapter = pContext;
+	struct hdd_adapter *adapter;
+	struct hdd_context *hdd_ctx;
+
+	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
+	if (!hdd_ctx) {
+		hdd_err("Invalid HDD_CTX");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	adapter = hdd_get_adapter_by_sme_session_id(hdd_ctx, session_id);
+	if (NULL == adapter) {
+		hdd_err("NULL adapter");
+		return QDF_STATUS_E_INVAL;
+	}
+	set_bit(SME_SESSION_OPENED, &adapter->event_flags);
+	complete(&adapter->session_open_comp_var);
+	hdd_debug("session %d opened", adapter->session_id);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS hdd_sme_close_session_callback(uint8_t session_id)
+{
+	struct hdd_adapter *adapter;
+	struct hdd_context *hdd_ctx;
+
+	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
+	if (!hdd_ctx) {
+		hdd_err("Invalid HDD_CTX");
+		return QDF_STATUS_E_FAILURE;
+	}
 
+	adapter = hdd_get_adapter_by_sme_session_id(hdd_ctx, session_id);
 	if (NULL == adapter) {
 		hdd_err("NULL adapter");
 		return QDF_STATUS_E_INVAL;
@@ -3332,14 +3363,17 @@ int hdd_vdev_destroy(struct hdd_adapter *adapter)
 	 * In SSR case, there is no need to destroy vdev in firmware since
 	 * it has already asserted. vdev can be released directly.
 	 */
-	if (cds_is_driver_recovering())
+	if (cds_is_driver_recovering()) {
+		hdd_debug("SSR: silently release the vdev for session-id: %d",
+			  adapter->session_id);
+		clear_bit(SME_SESSION_OPENED, &adapter->event_flags);
 		goto release_vdev;
+	}
 
 	/* close sme session (destroy vdev in firmware via legacy API) */
 	INIT_COMPLETION(adapter->session_close_comp_var);
 	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
-	status = sme_close_session(hdd_ctx->hHal, adapter->session_id,
-				   hdd_sme_close_session_callback, adapter);
+	status = sme_close_session(hdd_ctx->hHal, adapter->session_id);
 	if (QDF_IS_STATUS_ERROR(status)) {
 		hdd_err("failed to close sme session: %d", status);
 		return qdf_status_to_os_return(status);
@@ -3375,16 +3409,14 @@ release_vdev:
 	return 0;
 }
 
-int hdd_vdev_create(struct hdd_adapter *adapter)
+static int hdd_set_sme_session_param(struct hdd_adapter *adapter,
+			struct sme_session_params *session_param,
+			csr_roam_completeCallback callback,
+			void *callback_ctx)
 {
-	QDF_STATUS status;
-	int errno;
-	struct hdd_context *hdd_ctx;
 	uint32_t type;
 	uint32_t sub_type;
-	unsigned long rc;
-
-	hdd_info("creating new vdev");
+	QDF_STATUS status;
 
 	/* determine vdev (sub)type */
 	status = cds_get_vdev_types(adapter->device_mode, &type, &sub_type);
@@ -3392,6 +3424,28 @@ int hdd_vdev_create(struct hdd_adapter *adapter)
 		hdd_err("failed to get vdev type: %d", status);
 		return qdf_status_to_os_return(status);
 	}
+	session_param->sme_session_id = adapter->session_id;
+	session_param->self_mac_addr = (uint8_t *)&adapter->mac_addr;
+	session_param->type_of_persona = type;
+	session_param->subtype_of_persona = sub_type;
+	session_param->session_open_cb = hdd_sme_open_session_callback;
+	session_param->session_close_cb = hdd_sme_close_session_callback;
+	session_param->callback = callback;
+	session_param->callback_ctx = callback_ctx;
+
+	return 0;
+}
+
+int hdd_vdev_create(struct hdd_adapter *adapter,
+		    csr_roam_completeCallback callback, void *ctx)
+{
+	QDF_STATUS status;
+	int errno;
+	struct hdd_context *hdd_ctx;
+	struct sme_session_params sme_session_params = {0};
+	unsigned long rc;
+
+	hdd_info("creating new vdev");
 
 	/* do vdev create via objmgr */
 	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
@@ -3403,9 +3457,14 @@ int hdd_vdev_create(struct hdd_adapter *adapter)
 
 	/* Open a SME session (prepare vdev in firmware via legacy API) */
 	INIT_COMPLETION(adapter->session_open_comp_var);
-	status = sme_open_session(hdd_ctx->hHal, hdd_sme_roam_callback, adapter,
-				  (uint8_t *)&adapter->mac_addr,
-				  adapter->session_id, type, sub_type);
+	errno = hdd_set_sme_session_param(adapter, &sme_session_params,
+					  callback, ctx);
+	if (errno) {
+		hdd_err("failed to populating SME params");
+		goto objmgr_vdev_destroy_procedure;
+	}
+
+	status = sme_open_session(hdd_ctx->hHal, &sme_session_params);
 	if (QDF_IS_STATUS_ERROR(status)) {
 		hdd_err("failed to open sme session: %d", status);
 		errno = qdf_status_to_os_return(status);
@@ -3457,12 +3516,6 @@ QDF_STATUS hdd_init_station_mode(struct hdd_adapter *adapter)
 	QDF_STATUS status;
 	int ret_val;
 
-	ret_val = hdd_vdev_create(adapter);
-	if (ret_val) {
-		hdd_err("failed to create vdev: %d", ret_val);
-		return QDF_STATUS_E_FAILURE;
-	}
-
 	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
 	sme_set_curr_device_mode(hdd_ctx->hHal, adapter->device_mode);
 	sme_set_pdev_ht_vht_ies(hdd_ctx->hHal, hdd_ctx->config->enable2x2);
@@ -3575,10 +3628,12 @@ static void hdd_deinit_station_mode(struct hdd_context *hdd_ctx,
 		clear_bit(WMM_INIT_DONE, &adapter->event_flags);
 	}
 
+
 	EXIT();
 }
 
-void hdd_deinit_adapter(struct hdd_context *hdd_ctx, struct hdd_adapter *adapter,
+void hdd_deinit_adapter(struct hdd_context *hdd_ctx,
+			struct hdd_adapter *adapter,
 			bool rtnl_held)
 {
 	ENTER();
@@ -3587,6 +3642,8 @@ void hdd_deinit_adapter(struct hdd_context *hdd_ctx, struct hdd_adapter *adapter
 	case QDF_STA_MODE:
 	case QDF_P2P_CLIENT_MODE:
 	case QDF_P2P_DEVICE_MODE:
+	case QDF_IBSS_MODE:
+	case QDF_NDI_MODE:
 	{
 		hdd_deinit_station_mode(hdd_ctx, adapter, rtnl_held);
 		break;
@@ -4008,10 +4065,8 @@ struct hdd_adapter *hdd_open_adapter(struct hdd_context *hdd_ctx, uint8_t sessio
 			  hdd_ipv6_notifier_work_queue);
 #endif
 		status = hdd_register_interface(adapter, rtnl_held);
-		if (QDF_STATUS_SUCCESS != status) {
-			hdd_deinit_adapter(hdd_ctx, adapter, rtnl_held);
+		if (QDF_STATUS_SUCCESS != status)
 			goto err_deinit_adapter_runtime_pm;
-		}
 
 		/* Stop the Interface TX queue. */
 		hdd_debug("Disabling queues");
@@ -4046,10 +4101,9 @@ struct hdd_adapter *hdd_open_adapter(struct hdd_context *hdd_ctx, uint8_t sessio
 		adapter->device_mode = session_type;
 
 		status = hdd_register_interface(adapter, rtnl_held);
-		if (QDF_STATUS_SUCCESS != status) {
-			hdd_deinit_adapter(hdd_ctx, adapter, rtnl_held);
+		if (QDF_STATUS_SUCCESS != status)
 			goto err_free_netdev;
-		}
+
 		hdd_debug("Disabling queues");
 		wlan_hdd_netif_queue_control(adapter,
 					WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER,
@@ -4082,10 +4136,9 @@ struct hdd_adapter *hdd_open_adapter(struct hdd_context *hdd_ctx, uint8_t sessio
 		adapter->wdev.iftype = NL80211_IFTYPE_STATION;
 		adapter->device_mode = session_type;
 		status = hdd_register_interface(adapter, rtnl_held);
-		if (QDF_STATUS_SUCCESS != status) {
-			hdd_deinit_adapter(hdd_ctx, adapter, rtnl_held);
+		if (QDF_STATUS_SUCCESS != status)
 			goto err_deinit_adapter_runtime_pm;
-		}
+
 		/* Stop the Interface TX queue. */
 		hdd_debug("Disabling queues");
 		wlan_hdd_netif_queue_control(adapter,
@@ -4396,6 +4449,8 @@ QDF_STATUS hdd_stop_adapter(struct hdd_context *hdd_ctx, struct hdd_adapter *ada
 				hdd_err("Error: Can't disconnect adapter");
 				return QDF_STATUS_E_FAILURE;
 			}
+			hdd_debug("Destroying adapter: %d",
+				  adapter->session_id);
 			hdd_vdev_destroy(adapter);
 		}
 		break;
@@ -4484,10 +4539,6 @@ QDF_STATUS hdd_stop_adapter(struct hdd_context *hdd_ctx, struct hdd_adapter *ada
 		if (policy_mgr_is_dnsc_set(adapter->hdd_vdev))
 			wlan_hdd_send_avoid_freq_for_dnbs(hdd_ctx, 0);
 
-		if (true == bCloseSession)
-			hdd_vdev_destroy(adapter);
-		mutex_unlock(&hdd_ctx->sap_lock);
-
 #ifdef WLAN_OPEN_SOURCE
 		cancel_work_sync(&adapter->ipv4_notifier_work);
 #endif
@@ -4497,6 +4548,12 @@ QDF_STATUS hdd_stop_adapter(struct hdd_context *hdd_ctx, struct hdd_adapter *ada
 		cancel_work_sync(&adapter->ipv6_notifier_work);
 #endif
 #endif
+		if (true == bCloseSession) {
+			hdd_debug("Destroying adapter: %d",
+				  adapter->session_id);
+			hdd_vdev_destroy(adapter);
+		}
+		mutex_unlock(&hdd_ctx->sap_lock);
 		break;
 	case QDF_OCB_MODE:
 		cdp_clear_peer(cds_get_context(QDF_MODULE_ID_SOC),
@@ -4618,10 +4675,8 @@ QDF_STATUS hdd_reset_all_adapters(struct hdd_context *hdd_ctx)
 						     WLAN_STOP_ALL_NETIF_QUEUE,
 						     WLAN_CONTROL_PATH);
 			if (test_bit(SOFTAP_BSS_STARTED,
-						&adapter->event_flags)) {
+						&adapter->event_flags))
 				hdd_sap_indicate_disconnect_for_sta(adapter);
-				hdd_sap_destroy_events(adapter);
-			}
 			clear_bit(SOFTAP_BSS_STARTED, &adapter->event_flags);
 		} else {
 			wlan_hdd_netif_queue_control(adapter,
@@ -5234,7 +5289,7 @@ QDF_STATUS hdd_start_all_adapters(struct hdd_context *hdd_ctx)
 			connState = (WLAN_HDD_GET_STATION_CTX_PTR(adapter))
 					->conn_info.connState;
 
-			hdd_init_station_mode(adapter);
+			hdd_start_station_adapter(adapter);
 			/* Open the gates for HDD to receive Wext commands */
 			adapter->is_link_up_service_needed = false;
 
@@ -5280,7 +5335,7 @@ QDF_STATUS hdd_start_all_adapters(struct hdd_context *hdd_ctx)
 
 		case QDF_SAP_MODE:
 			if (hdd_ctx->config->sap_internal_restart)
-				hdd_init_ap_mode(adapter, true);
+				hdd_start_ap_adapter(adapter);
 
 			break;
 
@@ -5297,7 +5352,7 @@ QDF_STATUS hdd_start_all_adapters(struct hdd_context *hdd_ctx)
 #endif
 			break;
 		case QDF_MONITOR_MODE:
-			hdd_init_station_mode(adapter);
+			hdd_start_station_adapter(adapter);
 			hdd_set_mon_rx_cb(adapter->dev);
 			wlan_hdd_set_mon_chan(adapter, adapter->mon_chan,
 					      adapter->mon_bandwidth);
@@ -8029,9 +8084,20 @@ static int hdd_open_ocb_interface(struct hdd_context *hdd_ctx, bool rtnl_held)
 int hdd_start_station_adapter(struct hdd_adapter *adapter)
 {
 	QDF_STATUS status;
+	int ret;
 
 	ENTER_DEV(adapter->dev);
+	if (test_bit(SME_SESSION_OPENED, &adapter->event_flags)) {
+		hdd_err("session is already opened, %d",
+			adapter->session_id);
+		return qdf_status_to_os_return(QDF_STATUS_SUCCESS);
+	}
 
+	ret = hdd_vdev_create(adapter, hdd_sme_roam_callback, adapter);
+	if (ret) {
+		hdd_err("failed to create vdev: %d", ret);
+		return ret;
+	}
 	status = hdd_init_station_mode(adapter);
 
 	if (QDF_STATUS_SUCCESS != status) {
@@ -8059,9 +8125,33 @@ int hdd_start_station_adapter(struct hdd_adapter *adapter)
 int hdd_start_ap_adapter(struct hdd_adapter *adapter)
 {
 	QDF_STATUS status;
+	int ret;
 
 	ENTER();
 
+	if (test_bit(SME_SESSION_OPENED, &adapter->event_flags)) {
+		hdd_err("session is already opened, %d",
+			adapter->session_id);
+		return qdf_status_to_os_return(QDF_STATUS_SUCCESS);
+	}
+	/*
+	 * create sap context first and then create vdev as
+	 * while creating the vdev, driver needs to register
+	 * SAP callback and that callback uses sap context
+	 */
+	if (!adapter->session.ap.sap_context &&
+	    !hdd_sap_create_ctx(adapter)) {
+		hdd_err("sap creation failed");
+		return qdf_status_to_os_return(QDF_STATUS_E_FAILURE);
+	}
+
+	ret = hdd_vdev_create(adapter, wlansap_roam_callback,
+			      adapter->session.ap.sap_context);
+	if (ret) {
+		hdd_err("failed to create vdev, status:%d", ret);
+		hdd_sap_destroy_ctx(adapter);
+		return ret;
+	}
 	status = hdd_init_ap_mode(adapter, false);
 
 	if (QDF_STATUS_SUCCESS != status) {

+ 1 - 1
core/hdd/src/wlan_hdd_nan_datapath.c

@@ -2114,7 +2114,7 @@ int hdd_init_nan_data_mode(struct hdd_adapter *adapter)
 	QDF_STATUS status;
 	int32_t ret_val = 0;
 
-	ret_val = hdd_vdev_create(adapter);
+	ret_val = hdd_vdev_create(adapter, hdd_sme_roam_callback, adapter);
 	if (ret_val) {
 		hdd_err("failed to create vdev: %d", ret_val);
 		return ret_val;