Prechádzať zdrojové kódy

qcacld-3.0: Handle request to delete NAN Data Interface (NDI)

qcacld-2.0 to qcacld-3.0 propagation

Add changes to handle request to delete NAN datapath interface.

Change-Id: I3efef6adf6c7a974d3e344a7609f8517cd1aa752
CRs-Fixed: 962367
Deepak Dhamdhere 9 rokov pred
rodič
commit
13983f2571

+ 0 - 3
core/hdd/inc/wlan_hdd_main.h

@@ -68,10 +68,7 @@
 #include <wlan_hdd_lro.h>
 #include "cdp_txrx_flow_ctrl_legacy.h"
 #include <cdp_txrx_peer_ops.h>
-
-#ifdef WLAN_FEATURE_NAN_DATAPATH
 #include "wlan_hdd_nan_datapath.h"
-#endif
 
 /*---------------------------------------------------------------------------
    Preprocessor definitions and constants

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

@@ -60,7 +60,6 @@
 #include "ol_rx_fwd.h"
 #include "cdp_txrx_flow_ctrl_legacy.h"
 #include "cdp_txrx_peer_ops.h"
-#include "wlan_hdd_nan_datapath.h"
 
 /* These are needed to recognize WPA and RSN suite types */
 #define HDD_WPA_OUI_SIZE 4

+ 0 - 1
core/hdd/src/wlan_hdd_cfg.c

@@ -45,7 +45,6 @@
 #include <wlan_hdd_misc.h>
 #include <wlan_hdd_napi.h>
 #include <cds_concurrency.h>
-#include "wlan_hdd_nan_datapath.h"
 
 static void
 cb_notify_set_roam_prefer5_g_hz(hdd_context_t *pHddCtx, unsigned long notifyId)

+ 29 - 13
core/hdd/src/wlan_hdd_main.c

@@ -89,7 +89,6 @@
 #include "pld_common.h"
 #include "wlan_hdd_ocb.h"
 #include "wlan_hdd_nan.h"
-#include "wlan_hdd_nan_datapath.h"
 #include "wlan_hdd_debugfs.h"
 #include "wlan_hdd_driver_ops.h"
 #include "epping_main.h"
@@ -105,7 +104,6 @@
 #include <wlan_hdd_regulatory.h>
 #include "ol_rx_fwd.h"
 #include "wlan_hdd_lpass.h"
-#include "wlan_hdd_nan_datapath.h"
 
 #ifdef MODULE
 #define WLAN_MODULE_NAME  module_name(THIS_MODULE)
@@ -2170,6 +2168,12 @@ QDF_STATUS hdd_sme_close_session_callback(void *pContext)
 		return QDF_STATUS_NOT_INITIALIZED;
 	}
 
+	/*
+	 * For NAN Data interface, the close session results in the final
+	 * indication to the userspace
+	 */
+	hdd_ndp_session_end_handler(adapter);
+
 	clear_bit(SME_SESSION_OPENED, &adapter->event_flags);
 
 	/*
@@ -3056,21 +3060,33 @@ QDF_STATUS hdd_stop_adapter(hdd_context_t *hdd_ctx, hdd_adapter_t *adapter,
 	case QDF_P2P_CLIENT_MODE:
 	case QDF_IBSS_MODE:
 	case QDF_P2P_DEVICE_MODE:
-		if (hdd_conn_is_connected(
+	case QDF_NDI_MODE:
+		if ((QDF_NDI_MODE == adapter->device_mode) ||
+			hdd_conn_is_connected(
 				WLAN_HDD_GET_STATION_CTX_PTR(adapter)) ||
 			hdd_is_connecting(
 				WLAN_HDD_GET_STATION_CTX_PTR(adapter))) {
-			if (pWextState->roamProfile.BSSType ==
-			    eCSR_BSS_TYPE_START_IBSS)
-				qdf_ret_status =
-					sme_roam_disconnect(hdd_ctx->hHal,
-							    adapter->sessionId,
-							    eCSR_DISCONNECT_REASON_IBSS_LEAVE);
+			INIT_COMPLETION(adapter->disconnect_comp_var);
+			/*
+			 * For NDI do not use pWextState from sta_ctx, if needed
+			 * extract from ndi_ctx.
+			 */
+			if (QDF_NDI_MODE == adapter->device_mode)
+				qdf_ret_status = sme_roam_disconnect(
+					hdd_ctx->hHal,
+					adapter->sessionId,
+					eCSR_DISCONNECT_REASON_NDI_DELETE);
+			else if (pWextState->roamProfile.BSSType ==
+						eCSR_BSS_TYPE_START_IBSS)
+				qdf_ret_status = sme_roam_disconnect(
+					hdd_ctx->hHal,
+					adapter->sessionId,
+					eCSR_DISCONNECT_REASON_IBSS_LEAVE);
 			else
-				qdf_ret_status =
-					sme_roam_disconnect(hdd_ctx->hHal,
-							    adapter->sessionId,
-							    eCSR_DISCONNECT_REASON_UNSPECIFIED);
+				qdf_ret_status = sme_roam_disconnect(
+					hdd_ctx->hHal,
+					adapter->sessionId,
+					eCSR_DISCONNECT_REASON_UNSPECIFIED);
 			/* success implies disconnect command got queued up successfully */
 			if (qdf_ret_status == QDF_STATUS_SUCCESS) {
 				rc = wait_for_completion_timeout(

+ 234 - 38
core/hdd/src/wlan_hdd_nan_datapath.c

@@ -23,12 +23,12 @@
  *
  * WLAN Host Device Driver nan datapath API implementation
  */
+#include <wlan_hdd_includes.h>
 #include <linux/if.h>
 #include <linux/netdevice.h>
 #include <linux/skbuff.h>
 #include <linux/etherdevice.h>
 #include "wlan_hdd_includes.h"
-#include "wlan_hdd_nan_datapath.h"
 #include "wlan_hdd_p2p.h"
 #include "wma_api.h"
 
@@ -78,8 +78,8 @@ void hdd_ndp_print_ini_config(hdd_context_t *hdd_ctx)
  * @hdd_ctx: Pointer to HDD context
  * @cfg: Pointer to target device capability information
  *
- * NAN datapath functinality is enabled if it is enabled in
- * .ini file and also supported in firmware.
+ * NAN datapath functionality is enabled if it is enabled in
+ * .ini file and also supported on target device.
  *
  * Return: None
  */
@@ -110,7 +110,7 @@ static int hdd_ndi_start_bss(hdd_adapter_t *adapter,
 	ENTER();
 
 	if (!roam_profile) {
-		hddLog(LOGE, FL("No valid roam profile"));
+		hdd_err(FL("No valid roam profile"));
 		return -EINVAL;
 	}
 
@@ -153,7 +153,7 @@ static int hdd_ndi_start_bss(hdd_adapter_t *adapter,
 	ret = sme_roam_connect(WLAN_HDD_GET_HAL_CTX(adapter),
 		adapter->sessionId, roam_profile, &roam_id);
 	if (QDF_STATUS_SUCCESS != ret) {
-		hddLog(LOGE,
+		hdd_err(
 			FL("NDI sme_RoamConnect session %d failed with status %d -> NotConnected"),
 			  adapter->sessionId, ret);
 		/* change back to NotConnected */
@@ -193,13 +193,13 @@ static int hdd_ndi_create_req_handler(hdd_context_t *hdd_ctx,
 	ENTER();
 
 	if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]) {
-		hddLog(LOGE, FL("Interface name string is unavailable"));
+		hdd_err(FL("Interface name string is unavailable"));
 		return -EINVAL;
 	}
 	iface_name = nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]);
 
 	if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]) {
-		hddLog(LOGE, FL("transaction id is unavailable"));
+		hdd_err(FL("transaction id is unavailable"));
 		return -EINVAL;
 	}
 	transaction_id =
@@ -208,7 +208,7 @@ static int hdd_ndi_create_req_handler(hdd_context_t *hdd_ctx,
 	/* Check for an existing interface of NDI type */
 	adapter = hdd_get_adapter(hdd_ctx, QDF_NDI_MODE);
 	if (adapter) {
-		hddLog(LOGE, FL("Cannot support more than one NDI"));
+		hdd_err(FL("Cannot support more than one NDI"));
 		return -EEXIST;
 	}
 
@@ -216,7 +216,7 @@ static int hdd_ndi_create_req_handler(hdd_context_t *hdd_ctx,
 			wlan_hdd_get_intf_addr(hdd_ctx), NET_NAME_UNKNOWN,
 			true);
 	if (!adapter) {
-		hddLog(LOGE, FL("hdd_open_adapter failed"));
+		hdd_err(FL("hdd_open_adapter failed"));
 		return -ENOMEM;
 	}
 
@@ -226,6 +226,7 @@ static int hdd_ndi_create_req_handler(hdd_context_t *hdd_ctx,
 	 */
 	ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter);
 	ndp_ctx->ndp_create_transaction_id = transaction_id;
+	ndp_ctx->state = NAN_DATA_NDI_CREATING_STATE;
 
 	/*
 	 * The NAN data interface has been created at this point.
@@ -242,7 +243,7 @@ static int hdd_ndi_create_req_handler(hdd_context_t *hdd_ctx,
 	}
 	ret = hdd_ndi_start_bss(adapter, op_channel);
 	if (0 > ret)
-		hddLog(LOGE, FL("NDI start bss failed"));
+		hdd_err(FL("NDI start bss failed"));
 
 	EXIT();
 	return ret;
@@ -258,7 +259,68 @@ static int hdd_ndi_create_req_handler(hdd_context_t *hdd_ctx,
 static int hdd_ndi_delete_req_handler(hdd_context_t *hdd_ctx,
 						struct nlattr **tb)
 {
-	return 0;
+	hdd_adapter_t *adapter;
+	char *iface_name;
+	uint16_t transaction_id;
+	struct nan_datapath_ctx *ndp_ctx;
+	int ret;
+
+	ENTER();
+
+	if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]) {
+		hdd_err(FL("Interface name string is unavailable"));
+		return -EINVAL;
+	}
+
+	iface_name = nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]);
+
+	if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]) {
+		hdd_err(FL("Transaction id is unavailable"));
+		return -EINVAL;
+	}
+
+	transaction_id =
+		nla_get_u16(tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]);
+
+	/* Check if there is already an existing inteface with the same name */
+	adapter = hdd_get_adapter(hdd_ctx, QDF_NDI_MODE);
+	if (!adapter) {
+		hdd_err(FL("NAN data interface %s is not available"),
+			iface_name);
+		return -EINVAL;
+	}
+
+	/* check if adapter is in NDI mode */
+	if (QDF_NDI_MODE != adapter->device_mode) {
+		hdd_err(FL("Interface %s is not in NDI mode"),
+			iface_name);
+		return -EINVAL;
+	}
+
+	ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter);
+	if (!ndp_ctx) {
+		hdd_err(FL("ndp_ctx is NULL"));
+		return -EINVAL;
+	}
+
+	/* check if there are active NDP sessions on the adapter */
+	if (ndp_ctx->active_ndp_sessions > 0) {
+		hdd_err(FL("NDP sessions active %d, cannot delete NDI"),
+			ndp_ctx->active_ndp_sessions);
+		return -EINVAL;
+	}
+
+	ndp_ctx->ndp_delete_transaction_id = transaction_id;
+	ndp_ctx->state = NAN_DATA_NDI_DELETING_STATE;
+
+	/* Delete the interface */
+	ret = __wlan_hdd_del_virtual_intf(hdd_ctx->wiphy, &adapter->wdev);
+	if (ret < 0)
+		hdd_err(FL("NDI delete request failed"));
+	else
+		hdd_err(FL("NDI delete request successfully issued"));
+
+	return ret;
 }
 
 
@@ -348,7 +410,12 @@ static void hdd_ndp_iface_create_rsp_handler(hdd_adapter_t *adapter,
 		return;
 
 	if (!ndi_rsp) {
-		hddLog(LOGE, FL("Invalid ndi create response"));
+		hdd_err(FL("Invalid ndi create response"));
+		return;
+	}
+
+	if (!ndp_ctx) {
+		hdd_err(FL("ndp_ctx is NULL"));
 		return;
 	}
 
@@ -360,35 +427,35 @@ static void hdd_ndp_iface_create_rsp_handler(hdd_adapter_t *adapter,
 				cds_get_gfp_flags());
 
 	if (!vendor_event) {
-		hddLog(LOGE, FL("cfg80211_vendor_event_alloc failed"));
+		hdd_err(FL("cfg80211_vendor_event_alloc failed"));
 		return;
 	}
 
 	/* Sub vendor command */
 	if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
 		QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_CREATE)) {
-		hddLog(LOGE, FL("QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD put fail"));
+		hdd_err(FL("QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD put fail"));
 		goto nla_put_failure;
 	}
 
 	/* Transaction id */
 	if (nla_put_u16(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID,
 		ndp_ctx->ndp_create_transaction_id)) {
-		hddLog(LOGE, FL("VENDOR_ATTR_NDP_TRANSACTION_ID put fail"));
+		hdd_err(FL("VENDOR_ATTR_NDP_TRANSACTION_ID put fail"));
 		goto nla_put_failure;
 	}
 
 	/* Status code */
 	if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_TYPE,
 		ndi_rsp->status)) {
-		hddLog(LOGE, FL("VENDOR_ATTR_NDP_DRV_RETURN_TYPE put fail"));
+		hdd_err(FL("VENDOR_ATTR_NDP_DRV_RETURN_TYPE put fail"));
 		goto nla_put_failure;
 	}
 
 	/* Status return value */
 	if (nla_put_u32(vendor_event,
 			QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE, 0xA5)) {
-		hddLog(LOGE, FL("VENDOR_ATTR_NDP_DRV_RETURN_VALUE put fail"));
+		hdd_err(FL("VENDOR_ATTR_NDP_DRV_RETURN_VALUE put fail"));
 		goto nla_put_failure;
 	}
 
@@ -408,10 +475,9 @@ static void hdd_ndp_iface_create_rsp_handler(hdd_adapter_t *adapter,
 	ndp_ctx->ndp_create_transaction_id = 0;
 
 	if (ndi_rsp->status == QDF_STATUS_SUCCESS) {
-		hddLog(LOGE, FL("NDI interface successfully created"));
+		hdd_err(FL("NDI interface successfully created"));
 	} else {
-		hddLog(LOGE,
-			FL("NDI interface creation failed with reason %d"),
+		hdd_err(FL("NDI interface creation failed with reason %d"),
 			ndi_rsp->reason);
 	}
 	EXIT();
@@ -432,9 +498,141 @@ nla_put_failure:
 static void hdd_ndp_iface_delete_rsp_handler(hdd_adapter_t *adapter,
 							void *rsp_params)
 {
+	hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	struct ndi_delete_rsp *ndi_rsp = rsp_params;
+
+	if (wlan_hdd_validate_context(hdd_ctx))
+		return;
+
+	if (!ndi_rsp) {
+		hdd_err(FL("Invalid ndi delete response"));
+		return;
+	}
+
+	if (ndi_rsp->status == QDF_STATUS_SUCCESS)
+		hdd_err(FL("NDI BSS successfully stopped"));
+	else
+		hdd_err(FL("NDI BSS stop failed with reason %d"),
+			ndi_rsp->reason);
+
+	complete(&adapter->disconnect_comp_var);
+	return;
+}
+
+/**
+ * hdd_ndp_session_end_handler() - NDI session termination handler
+ * @adapter: pointer to adapter context
+ *
+ * Following vendor event is sent to cfg80211:
+ * QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD =
+ *     QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_DELETE (4 bytes)
+ * QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID (2 bytes)
+ * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_TYPE (4 bytes)
+ * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE (4 bytes)
+ *
+ * Return: none
+ */
+void hdd_ndp_session_end_handler(hdd_adapter_t *adapter)
+{
+	hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	struct sk_buff *vendor_event;
+	struct nan_datapath_ctx *ndp_ctx;
+	uint32_t data_len = sizeof(uint32_t) * (3 + sizeof(uint16_t)) +
+				(NLA_HDRLEN * 4) + NLMSG_HDRLEN;
+
+	ENTER();
+
+	if (wlan_hdd_validate_context(hdd_ctx))
+		return;
+
+	/* Handle only if adapter is in NDI mode */
+	if (QDF_NDI_MODE != adapter->device_mode) {
+		hdd_err(FL("Adapter is not in NDI mode"));
+		return;
+	}
+
+	ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter);
+	if (!ndp_ctx) {
+		hdd_err(FL("ndp context is NULL"));
+		return;
+	}
+
+	/*
+	 * The virtual adapters are stopped and closed even during
+	 * driver unload or stop, the service layer is not required
+	 * to be informed in that case (response is not expected)
+	 */
+	if (NAN_DATA_NDI_DELETING_STATE != ndp_ctx->state) {
+		hdd_err(FL("NDI interface %s deleted"),
+			adapter->dev->name);
+		return;
+	}
+
+	/* notify response to the upper layer */
+	vendor_event = cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
+			NULL,
+			data_len,
+			QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX,
+			GFP_KERNEL);
+
+	if (!vendor_event) {
+		hdd_err(FL("cfg80211_vendor_event_alloc failed"));
+		return;
+	}
+
+	/* Sub vendor command goes first */
+	if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
+			QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_DELETE)) {
+		hdd_err(FL("VENDOR_ATTR_NDP_SUBCMD put fail"));
+		goto failure;
+	}
+
+	/* Transaction id */
+	if (nla_put_u16(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID,
+			ndp_ctx->ndp_delete_transaction_id)) {
+		hdd_err(FL("VENDOR_ATTR_NDP_TRANSACTION_ID put fail"));
+		goto failure;
+	}
+
+	/* Status code */
+	if (nla_put_u32(vendor_event,
+			QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_TYPE, 0x0)) {
+		hdd_err(FL("VENDOR_ATTR_NDP_DRV_RETURN_TYPE put fail"));
+		goto failure;
+	}
+
+	/* Status return value */
+	if (nla_put_u32(vendor_event,
+			QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE, 0x0)) {
+		hdd_err(FL("VENDOR_ATTR_NDP_DRV_RETURN_VALUE put fail"));
+		goto failure;
+	}
+
+	hddLog(LOG2, FL("sub command: %d, value: %d"),
+		QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
+		QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_DELETE);
+	hddLog(LOG2, FL("delete transaction id: %d, value: %d"),
+		QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID,
+		ndp_ctx->ndp_delete_transaction_id);
+	hddLog(LOG2, FL("status code: %d, value: %d"),
+		QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_TYPE,
+		true);
+	hddLog(LOG2, FL("Return value: %d, value: %d"),
+		QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE, 0x5A);
+
+	ndp_ctx->ndp_delete_transaction_id = 0;
+	ndp_ctx->state = NAN_DATA_NDI_DELETED_STATE;
+
+	cfg80211_vendor_event(vendor_event, GFP_KERNEL);
+
+	EXIT();
 	return;
+
+failure:
+	kfree_skb(vendor_event);
 }
 
+
 /**
  * hdd_ndp_initiator_rsp_handler() - NDP initiator response handler
  * @adapter: pointer to adapter context
@@ -613,8 +811,7 @@ void hdd_ndp_event_handler(hdd_adapter_t *adapter,
 				&roam_info->ndp.ndp_end_ind_params);
 			break;
 		default:
-			hddLog(LOGE,
-				FL("Unknown NDP response event from SME %d"),
+			hdd_err(FL("Unknown NDP response event from SME %d"),
 				roam_result);
 			break;
 		}
@@ -649,36 +846,36 @@ static int __wlan_hdd_cfg80211_process_ndp_cmd(struct wiphy *wiphy,
 		return ret_val;
 
 	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
-		hddLog(LOGE, FL("Command not allowed in FTM mode"));
+		hdd_err(FL("Command not allowed in FTM mode"));
 		return -EPERM;
 	}
 	if (!hdd_ctx->config->enable_nan_datapath) {
-		hddLog(LOGE, FL("NAN datapath is not suported"));
+		hdd_err(FL("NAN datapath is not suported"));
 		return -EPERM;
 	}
 	if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_NDP_PARAMS_MAX,
 			data, data_len,
 			qca_wlan_vendor_ndp_policy)) {
-		hddLog(LOGE, FL("Invalid NDP vendor command attributes"));
+		hdd_err(FL("Invalid NDP vendor command attributes"));
 		return -EINVAL;
 	}
 
 	/* Parse and fetch NDP Command Type*/
 	if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD]) {
-		hddLog(LOGE, FL("NAN datapath cmd type failed"));
+		hdd_err(FL("NAN datapath cmd type failed"));
 		return -EINVAL;
 	}
 	ndp_cmd_type = nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD]);
 
 	if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]) {
-		hddLog(LOGE, FL("attr transaction id failed"));
+		hdd_err(FL("attr transaction id failed"));
 		return -EINVAL;
 	}
 	transaction_id = nla_get_u16(
 			tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]);
 
 	if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]) {
-		hddLog(LOGE, FL("Interface name string is unavailable"));
+		hdd_err(FL("Interface name string is unavailable"));
 		return -EINVAL;
 	}
 	iface_name = nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]);
@@ -706,7 +903,7 @@ static int __wlan_hdd_cfg80211_process_ndp_cmd(struct wiphy *wiphy,
 		ret_val = hdd_ndp_schedule_req_handler(hdd_ctx, tb);
 		break;
 	default:
-		hddLog(LOGE, FL("Unrecognized NDP vendor cmd %d"),
+		hdd_err(FL("Unrecognized NDP vendor cmd %d"),
 			ndp_cmd_type);
 		ret_val = -EINVAL;
 		break;
@@ -760,7 +957,7 @@ int hdd_init_nan_data_mode(struct hdd_adapter_s *adapter)
 	sme_set_curr_device_mode(hdd_ctx->hHal, adapter->device_mode);
 	status = cds_get_vdev_types(adapter->device_mode, &type, &sub_type);
 	if (QDF_STATUS_SUCCESS != status) {
-		hddLog(LOGE, "failed to get vdev type");
+		hdd_err("failed to get vdev type");
 		goto error_sme_open;
 	}
 
@@ -769,7 +966,7 @@ int hdd_init_nan_data_mode(struct hdd_adapter_s *adapter)
 			adapter, (uint8_t *)&adapter->macAddressCurrent,
 			&adapter->sessionId, type, sub_type);
 	if (QDF_STATUS_SUCCESS == status) {
-		hddLog(LOGE, "sme_open_session() failed with status code %d",
+		hdd_err("sme_open_session() failed with status code %d",
 				status);
 		ret_val = -EAGAIN;
 		goto error_sme_open;
@@ -780,7 +977,7 @@ int hdd_init_nan_data_mode(struct hdd_adapter_s *adapter)
 			&adapter->session_open_comp_var,
 			msecs_to_jiffies(timeout));
 	if (!rc) {
-		hddLog(LOGE,
+		hdd_err(
 			FL("Failed to open session, timeout code: %ld"), rc);
 		ret_val = -ETIMEDOUT;
 		goto error_sme_open;
@@ -789,7 +986,7 @@ int hdd_init_nan_data_mode(struct hdd_adapter_s *adapter)
 	/* Register wireless extensions */
 	ret_val = hdd_register_wext(wlan_dev);
 	if (0 > ret_val) {
-		hddLog(LOGE, FL("Wext registration failed with status code %d"),
+		hdd_err(FL("Wext registration failed with status code %d"),
 				ret_val);
 		ret_val = -EAGAIN;
 		goto error_register_wext;
@@ -797,7 +994,7 @@ int hdd_init_nan_data_mode(struct hdd_adapter_s *adapter)
 
 	status = hdd_init_tx_rx(adapter);
 	if (QDF_STATUS_SUCCESS != status) {
-		hddLog(LOGE, FL("hdd_init_tx_rx() init failed, status %d"),
+		hdd_err(FL("hdd_init_tx_rx() init failed, status %d"),
 				status);
 		ret_val = -EAGAIN;
 		goto error_init_txrx;
@@ -807,7 +1004,7 @@ int hdd_init_nan_data_mode(struct hdd_adapter_s *adapter)
 
 	status = hdd_wmm_adapter_init(adapter);
 	if (QDF_STATUS_SUCCESS != status) {
-		hddLog(LOGE, FL("hdd_wmm_adapter_init() failed, status %d"),
+		hdd_err(FL("hdd_wmm_adapter_init() failed, status %d"),
 				status);
 		ret_val = -EAGAIN;
 		goto error_wmm_init;
@@ -820,7 +1017,7 @@ int hdd_init_nan_data_mode(struct hdd_adapter_s *adapter)
 			(int)hdd_ctx->config->enableSifsBurst,
 			PDEV_CMD);
 	if (0 != ret_val) {
-		hddLog(LOGE, FL("WMI_PDEV_PARAM_BURST_ENABLE set failed %d"),
+		hdd_err(FL("WMI_PDEV_PARAM_BURST_ENABLE set failed %d"),
 				ret_val);
 	}
 
@@ -846,8 +1043,7 @@ error_register_wext:
 					&adapter->session_close_comp_var,
 					msecs_to_jiffies(timeout));
 			if (rc <= 0) {
-				hddLog(LOGE,
-					FL("Session close failed status %ld"),
+				hdd_err(FL("Session close failed status %ld"),
 					rc);
 				ret_val = -ETIMEDOUT;
 			}

+ 4 - 0
core/hdd/src/wlan_hdd_nan_datapath.h

@@ -215,6 +215,7 @@ void hdd_ndp_event_handler(struct hdd_adapter_s *adapter,
 int wlan_hdd_cfg80211_process_ndp_cmd(struct wiphy *wiphy,
 	struct wireless_dev *wdev, const void *data, int data_len);
 int hdd_init_nan_data_mode(struct hdd_adapter_s *adapter);
+void hdd_ndp_session_end_handler(hdd_adapter_t *adapter);
 #else
 static inline void hdd_ndp_print_ini_config(struct hdd_context_s *hdd_ctx)
 {
@@ -237,6 +238,9 @@ static inline int hdd_init_nan_data_mode(struct hdd_adapter_s *adapter)
 {
 	return 0;
 }
+static inline void hdd_ndp_session_end_handler(hdd_adapter_t *adapter)
+{
+}
 #endif /* WLAN_FEATURE_NAN_DATAPATH */
 
 #endif /* __WLAN_HDD_NAN_DATAPATH_H */

+ 22 - 17
core/mac/src/pe/lim/lim_process_sme_req_messages.c

@@ -3435,34 +3435,39 @@ __lim_handle_sme_stop_bss_request(tpAniSirGlobal pMac, uint32_t *pMsgBuf)
 	psessionEntry->smeSessionId = smesessionId;
 	psessionEntry->transactionId = smetransactionId;
 
-	/* BTAMP_STA and STA_IN_IBSS should NOT send Disassoc frame */
-	if (!LIM_IS_IBSS_ROLE(psessionEntry)) {
+	/* STA_IN_IBSS and NDI should NOT send Disassoc frame */
+	if (!LIM_IS_IBSS_ROLE(psessionEntry) &&
+	    !LIM_IS_NDI_ROLE(psessionEntry)) {
 		tSirMacAddr bcAddr = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
 		if (stopBssReq.reasonCode == eSIR_SME_MIC_COUNTER_MEASURES)
 			/* Send disassoc all stations associated thru TKIP */
 			__lim_counter_measures(pMac, psessionEntry);
 		else
 			lim_send_disassoc_mgmt_frame(pMac,
-						     eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
-						     bcAddr, psessionEntry, false);
+				eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
+				bcAddr, psessionEntry, false);
 	}
 
-	/* Free the buffer allocated in START_BSS_REQ */
-	qdf_mem_free(psessionEntry->addIeParams.probeRespData_buff);
-	psessionEntry->addIeParams.probeRespDataLen = 0;
-	psessionEntry->addIeParams.probeRespData_buff = NULL;
+	if (!LIM_IS_NDI_ROLE(psessionEntry)) {
+		/* Free the buffer allocated in START_BSS_REQ */
+		qdf_mem_free(psessionEntry->addIeParams.probeRespData_buff);
+		psessionEntry->addIeParams.probeRespDataLen = 0;
+		psessionEntry->addIeParams.probeRespData_buff = NULL;
 
-	qdf_mem_free(psessionEntry->addIeParams.assocRespData_buff);
-	psessionEntry->addIeParams.assocRespDataLen = 0;
-	psessionEntry->addIeParams.assocRespData_buff = NULL;
+		qdf_mem_free(psessionEntry->addIeParams.assocRespData_buff);
+		psessionEntry->addIeParams.assocRespDataLen = 0;
+		psessionEntry->addIeParams.assocRespData_buff = NULL;
 
-	qdf_mem_free(psessionEntry->addIeParams.probeRespBCNData_buff);
-	psessionEntry->addIeParams.probeRespBCNDataLen = 0;
-	psessionEntry->addIeParams.probeRespBCNData_buff = NULL;
-
-	/* lim_del_bss is also called as part of coalescing, when we send DEL BSS followed by Add Bss msg. */
-	pMac->lim.gLimIbssCoalescingHappened = false;
+		qdf_mem_free(psessionEntry->addIeParams.probeRespBCNData_buff);
+		psessionEntry->addIeParams.probeRespBCNDataLen = 0;
+		psessionEntry->addIeParams.probeRespBCNData_buff = NULL;
 
+		/*
+		 * lim_del_bss is also called as part of coalescing,
+		 * when we send DEL BSS followed by Add Bss msg.
+		 */
+		pMac->lim.gLimIbssCoalescingHappened = false;
+	}
 	for (i = 1; i < pMac->lim.gLimAssocStaLimit; i++) {
 		pStaDs =
 			dph_get_hash_entry(pMac, i, &psessionEntry->dph.dphHashTable);

+ 5 - 4
core/mac/src/pe/lim/lim_send_sme_rsp_messages.c

@@ -57,6 +57,7 @@
 #include "sir_api.h"
 #include "cds_regdomain.h"
 #include "lim_send_messages.h"
+#include "nan_datapath.h"
 
 static void lim_handle_join_rsp_status(tpAniSirGlobal mac_ctx,
 	tpPESession session_entry, tSirResultCodes result_code,
@@ -2249,12 +2250,12 @@ void lim_handle_delete_bss_rsp(tpAniSirGlobal pMac, tpSirMsgQ MsgQ)
 			pDelBss->sessionId);
 		return;
 	}
-	if (LIM_IS_IBSS_ROLE(psessionEntry)) {
+	if (LIM_IS_IBSS_ROLE(psessionEntry))
 		lim_ibss_del_bss_rsp(pMac, MsgQ->bodyptr, psessionEntry);
-	} else if (LIM_IS_UNKNOWN_ROLE(psessionEntry)) {
+	else if (LIM_IS_UNKNOWN_ROLE(psessionEntry))
 		lim_process_sme_del_bss_rsp(pMac, MsgQ->bodyval, psessionEntry);
-	}
-
+	else if (LIM_IS_NDI_ROLE(psessionEntry))
+		lim_ndi_del_bss_rsp(pMac, MsgQ->bodyptr, psessionEntry);
 	else
 		lim_process_mlm_del_bss_rsp(pMac, MsgQ, psessionEntry);
 

+ 63 - 0
core/mac/src/pe/nan/nan_datapath.c

@@ -27,6 +27,8 @@
 #include "lim_utils.h"
 #include "lim_api.h"
 #include "nan_datapath.h"
+#include "lim_types.h"
+#include "lim_send_messages.h"
 
 /**
  * handle_ndp_request_message() - Function to handle NDP requests from SME
@@ -97,3 +99,64 @@ end:
 	qdf_mem_free(lim_msgq->bodyptr);
 	lim_msgq->bodyptr = NULL;
 }
+
+/**
+ * lim_ndi_del_bss_rsp() - Handler for DEL BSS resp for NDI interface
+ * @mac_ctx: handle to mac structure
+ * @msg: pointer to message
+ * @session_entry: session entry
+ *
+ * Return: None
+ */
+void lim_ndi_del_bss_rsp(tpAniSirGlobal  mac_ctx,
+			void *msg, tpPESession session_entry)
+{
+	tSirResultCodes rc = eSIR_SME_SUCCESS;
+	tpDeleteBssParams del_bss = (tpDeleteBssParams) msg;
+
+	SET_LIM_PROCESS_DEFD_MESGS(mac_ctx, true);
+	if (del_bss == NULL) {
+		lim_log(mac_ctx, LOGE,
+			FL("NDI: DEL_BSS_RSP with no body!"));
+		rc = eSIR_SME_STOP_BSS_FAILURE;
+		goto end;
+	}
+	session_entry =
+		pe_find_session_by_session_id(mac_ctx, del_bss->sessionId);
+	if (!session_entry) {
+		lim_log(mac_ctx, LOGE,
+			FL("Session Does not exist for given sessionID"));
+		goto end;
+	}
+
+	if (del_bss->status != QDF_STATUS_SUCCESS) {
+		lim_log(mac_ctx, LOGE,
+			FL("NDI: DEL_BSS_RSP error (%x) Bss %d "),
+			del_bss->status, del_bss->bssIdx);
+		rc = eSIR_SME_STOP_BSS_FAILURE;
+		goto end;
+	}
+
+	if (lim_set_link_state(mac_ctx, eSIR_LINK_IDLE_STATE,
+			session_entry->selfMacAddr,
+			session_entry->selfMacAddr, NULL, NULL)
+			!= eSIR_SUCCESS) {
+		lim_log(mac_ctx, LOGE,
+			FL("NDI: DEL_BSS_RSP setLinkState failed"));
+		goto end;
+	}
+
+	session_entry->limMlmState = eLIM_MLM_IDLE_STATE;
+
+end:
+	if (del_bss)
+		qdf_mem_free(del_bss);
+	/* Delete PE session once BSS is deleted */
+	if (NULL != session_entry) {
+		lim_send_sme_rsp(mac_ctx, eWNI_SME_STOP_BSS_RSP,
+			rc, session_entry->smeSessionId,
+			session_entry->transactionId);
+		pe_delete_session(mac_ctx, session_entry);
+		session_entry = NULL;
+	}
+}

+ 7 - 0
core/mac/src/pe/nan/nan_datapath.h

@@ -109,6 +109,9 @@ QDF_STATUS lim_handle_ndp_event_message(tpAniSirGlobal mac_ctx,
 void lim_process_ndi_mlm_add_bss_rsp(tpAniSirGlobal mac_ctx,
 				     tpSirMsgQ lim_msg_q,
 				     tpPESession session_entry);
+/* Handler for DEL BSS resp for NDI interface */
+void lim_ndi_del_bss_rsp(tpAniSirGlobal  mac_ctx,
+			void *msg, tpPESession session_entry);
 #else
 /* Function to process NDP requests */
 static inline QDF_STATUS lim_handle_ndp_request_message(tpAniSirGlobal mac_ctx,
@@ -129,6 +132,10 @@ static inline void lim_process_ndi_mlm_add_bss_rsp(tpAniSirGlobal mac_ctx,
 						   tpPESession session_entry)
 {
 }
+static inline void lim_ndi_del_bss_rsp(tpAniSirGlobal mac_ctx,
+					void *msg, tpPESession session_entry)
+{
+}
 
 #endif /* WLAN_FEATURE_NAN_DATAPATH */
 

+ 1 - 0
core/sme/inc/csr_api.h

@@ -646,6 +646,7 @@ typedef enum {
 	eCSR_DISCONNECT_REASON_IBSS_JOIN_FAILURE,
 	eCSR_DISCONNECT_REASON_IBSS_LEAVE,
 	eCSR_DISCONNECT_REASON_STA_HAS_LEFT,
+	eCSR_DISCONNECT_REASON_NDI_DELETE,
 } eCsrRoamDisconnectReason;
 
 typedef enum {

+ 6 - 4
core/sme/inc/sme_nan_datapath.h

@@ -71,7 +71,8 @@ void csr_roam_save_ndi_connected_info(tpAniSirGlobal mac_ctx,
 void csr_roam_update_ndp_return_params(tpAniSirGlobal mac_ctx,
 					uint32_t result,
 					uint32_t *roam_status,
-					uint32_t *roam_result);
+					uint32_t *roam_result,
+					struct tagCsrRoamInfo *roam_info);
 #else
 
 /* Start NDI BSS */
@@ -100,9 +101,10 @@ static inline void csr_roam_save_ndi_connected_info(tpAniSirGlobal mac_ctx,
 }
 
 static inline void csr_roam_update_ndp_return_params(tpAniSirGlobal mac_ctx,
-						uint32_t result,
-						uint32_t *roam_status,
-						uint32_t *roam_result)
+					uint32_t result,
+					uint32_t *roam_status,
+					uint32_t *roam_result,
+					struct tagCsrRoamInfo *roam_info)
 {
 }
 #endif /* WLAN_FEATURE_NAN_DATAPATH */

+ 44 - 11
core/sme/src/csr/csr_api_roam.c

@@ -6398,12 +6398,15 @@ static void csr_roam_process_start_bss_success(tpAniSirGlobal mac_ctx,
 		}
 		if (CSR_IS_NDI(profile)) {
 			csr_roam_update_ndp_return_params(mac_ctx,
-					eCsrStartBssSuccess,
-					&roam_status, &roam_result);
-			csr_roam_fill_roaminfo_ndp(mac_ctx, &roam_info,
-					roam_result,
-					start_bss_rsp->statusCode,
-					0, 0);
+							eCsrStartBssSuccess,
+							&roam_status,
+							&roam_result,
+							&roam_info);
+			csr_roam_fill_roaminfo_ndp(mac_ctx,
+						&roam_info,
+						roam_result,
+						start_bss_rsp->statusCode,
+						0, 0);
 		}
 		/*
 		 * Only tell upper layer is we start the BSS because Vista
@@ -6880,7 +6883,7 @@ static bool csr_roam_process_results(tpAniSirGlobal mac_ctx, tSmeCmd *cmd,
 		if (CSR_IS_NDI(profile)) {
 			csr_roam_update_ndp_return_params(mac_ctx,
 				eCsrStartBssFailure,
-				&roam_status, &roam_result);
+				&roam_status, &roam_result, &roam_info);
 			csr_roam_fill_roaminfo_ndp(mac_ctx, &roam_info,
 				roam_result,
 				(start_bss_rsp) ? start_bss_rsp->statusCode :
@@ -6972,6 +6975,24 @@ static bool csr_roam_process_results(tpAniSirGlobal mac_ctx, tSmeCmd *cmd,
 				SME_QOS_CSR_REASSOC_FAILURE, NULL);
 #endif
 		break;
+	case eCsrStopBssSuccess:
+		if (CSR_IS_NDI(profile)) {
+			csr_roam_update_ndp_return_params(mac_ctx, res,
+				&roam_status, &roam_result, &roam_info);
+			csr_roam_call_callback(mac_ctx, session_id, &roam_info,
+				cmd->u.roamCmd.roamId,
+				roam_status, roam_result);
+		}
+		break;
+	case eCsrStopBssFailure:
+		if (CSR_IS_NDI(profile)) {
+			csr_roam_update_ndp_return_params(mac_ctx, res,
+				&roam_status, &roam_result, &roam_info);
+			csr_roam_call_callback(mac_ctx, session_id, &roam_info,
+				cmd->u.roamCmd.roamId,
+				roam_status, roam_result);
+		}
+		break;
 	case eCsrJoinFailure:
 	case eCsrNothingToJoin:
 	case eCsrJoinFailureDueToConcurrency:
@@ -7984,9 +8005,12 @@ QDF_STATUS csr_roam_issue_disassociate_cmd(tpAniSirGlobal pMac, uint32_t session
 			pCommand->u.roamCmd.reason =
 				eSIR_MAC_DISASSOC_LEAVING_BSS_REASON;
 			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO,
-				  FL
-					  ("SME convert to internal reason code eCsrStaHasLeft"));
+				  FL("SME convert to internal reason code eCsrStaHasLeft"));
 			break;
+		case eCSR_DISCONNECT_REASON_NDI_DELETE:
+			pCommand->u.roamCmd.roamReason = eCsrStopBss;
+			pCommand->u.roamCmd.roamProfile.BSSType =
+				eCSR_BSS_TYPE_NDI;
 		default:
 			break;
 		}
@@ -8048,7 +8072,8 @@ QDF_STATUS csr_roam_disconnect_internal(tpAniSirGlobal pMac, uint32_t sessionId,
 	/* Only issue disconnect when necessary */
 	if (csr_is_conn_state_connected(pMac, sessionId)
 	    || csr_is_bss_type_ibss(pSession->connectedProfile.BSSType)
-	    || csr_is_roam_command_waiting_for_session(pMac, sessionId)) {
+	    || csr_is_roam_command_waiting_for_session(pMac, sessionId)
+	    || CSR_IS_CONN_NDI(&pSession->connectedProfile)) {
 		sms_log(pMac, LOG2, FL("called"));
 		status = csr_roam_issue_disassociate_cmd(pMac, sessionId,
 							 reason);
@@ -8845,6 +8870,8 @@ static void csr_roam_roaming_state_reassoc_rsp_processor(tpAniSirGlobal pMac,
 static void csr_roam_roaming_state_stop_bss_rsp_processor(tpAniSirGlobal pMac,
 							  tSirSmeRsp *pSmeRsp)
 {
+	eCsrRoamCompleteResult result_code = eCsrNothingToJoin;
+
 #ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
 	{
 		host_log_ibss_pkt_type *pIbssLog;
@@ -8862,7 +8889,13 @@ static void csr_roam_roaming_state_stop_bss_rsp_processor(tpAniSirGlobal pMac,
 	pMac->roam.roamSession[pSmeRsp->sessionId].connectState =
 		eCSR_ASSOC_STATE_TYPE_NOT_CONNECTED;
 	if (CSR_IS_ROAM_SUBSTATE_STOP_BSS_REQ(pMac, pSmeRsp->sessionId)) {
-		csr_roam_complete(pMac, eCsrNothingToJoin, NULL);
+		if (CSR_IS_CONN_NDI(pMac->roam.roamSession[pSmeRsp->sessionId].
+							pCurRoamProfile)) {
+			result_code = eCsrStopBssSuccess;
+			if (pSmeRsp->statusCode != eSIR_SME_SUCCESS)
+				result_code = eCsrStopBssFailure;
+		}
+		csr_roam_complete(pMac, result_code, NULL);
 	} else
 	if (CSR_IS_ROAM_SUBSTATE_DISCONNECT_CONTINUE
 		    (pMac, pSmeRsp->sessionId)) {

+ 2 - 1
core/sme/src/csr/csr_inside_api.h

@@ -140,7 +140,8 @@ typedef enum {
 	eCsrSilentlyStopRoaming,
 	eCsrSilentlyStopRoamingSaveState,
 	eCsrJoinFailureDueToConcurrency,
-
+	eCsrStopBssSuccess,
+	eCsrStopBssFailure,
 } eCsrRoamCompleteResult;
 
 typedef struct tagScanReqParam {

+ 14 - 1
core/sme/src/nan/nan_datapath_api.c

@@ -212,20 +212,33 @@ void csr_roam_save_ndi_connected_info(tpAniSirGlobal mac_ctx,
  * @result: result of the roaming command
  * @roam_status: roam status returned to the roam command initiator
  * @roam_result: roam result returned to the roam command initiator
+ * @roam_info: Roam info data structure to be updated
  *
  * Results: None
  */
 void csr_roam_update_ndp_return_params(tpAniSirGlobal mac_ctx,
 					uint32_t result,
 					uint32_t *roam_status,
-					uint32_t *roam_result)
+					uint32_t *roam_result,
+					tCsrRoamInfo *roam_info)
 {
+
 	switch (result) {
 	case eCsrStartBssSuccess:
 	case eCsrStartBssFailure:
 		*roam_status = eCSR_ROAM_NDP_STATUS_UPDATE;
 		*roam_result = eCSR_ROAM_RESULT_NDP_CREATE_RSP;
 		break;
+	case eCsrStopBssSuccess:
+		*roam_status = eCSR_ROAM_NDP_STATUS_UPDATE;
+		*roam_result = eCSR_ROAM_RESULT_NDP_DELETE_RSP;
+		roam_info->ndp.ndi_delete_params.status = QDF_STATUS_SUCCESS;
+		break;
+	case eCsrStopBssFailure:
+		*roam_status = eCSR_ROAM_NDP_STATUS_UPDATE;
+		*roam_result = eCSR_ROAM_RESULT_NDP_DELETE_RSP;
+		roam_info->ndp.ndi_delete_params.status = QDF_STATUS_E_FAILURE;
+		break;
 	default:
 		sms_log(mac_ctx, LOGE,
 			FL("Invalid CSR Roam result code: %d"), result);

+ 3 - 0
core/wma/inc/wma.h

@@ -2122,6 +2122,9 @@ void wma_process_set_pdev_ht_ie_req(tp_wma_handle wma,
 		struct set_ie_param *ie_params);
 void wma_process_set_pdev_vht_ie_req(tp_wma_handle wma,
 		struct set_ie_param *ie_params);
+void wma_remove_peer(tp_wma_handle wma, u_int8_t *bssid,
+			u_int8_t vdev_id, ol_txrx_peer_handle peer,
+			bool roam_synch_in_progress);
 #endif
 struct wma_ini_config *wma_get_ini_handle(tp_wma_handle wma_handle);
 WLAN_PHY_MODE wma_chan_phy_mode(u8 chan, enum phy_ch_width chan_width,

+ 11 - 1
core/wma/src/wma_dev_if.c

@@ -1378,7 +1378,11 @@ int wma_vdev_stop_resp_handler(void *handle, uint8_t *cmd_param_info,
 		}
 		if (wma_is_vdev_in_ibss_mode(wma, resp_event->vdev_id))
 			wma_delete_all_ibss_peers(wma, resp_event->vdev_id);
-		else {
+		else if (WMA_IS_VDEV_IN_NDI_MODE(wma->interfaces,
+			resp_event->vdev_id)) {
+			wma_delete_all_nan_remote_peers(wma,
+				resp_event->vdev_id);
+		} else {
 			if (wma_is_vdev_in_ap_mode(wma, resp_event->vdev_id)) {
 				wma_delete_all_ap_remote_peers(wma,
 						resp_event->vdev_id);
@@ -4169,6 +4173,12 @@ void wma_delete_bss(tp_wma_handle wma, tpDeleteBssParams params)
 		peer = ol_txrx_find_peer_by_addr(pdev,
 			wma->interfaces[params->smesessionId].addr,
 			&peer_id);
+	else if (WMA_IS_VDEV_IN_NDI_MODE(wma->interfaces,
+			params->smesessionId))
+		/* In ndi case, self mac is used to create the self peer */
+		peer = ol_txrx_find_peer_by_addr(pdev,
+				wma->interfaces[params->smesessionId].addr,
+				&peer_id);
 	else
 		peer = ol_txrx_find_peer_by_addr(pdev, params->bssid, &peer_id);
 

+ 52 - 0
core/wma/src/wma_nan_datapath.c

@@ -253,3 +253,55 @@ send_fail_resp:
 	wma_send_msg(wma, WMA_ADD_BSS_RSP, (void *)add_bss, 0);
 }
 
+/**
+ * wma_delete_all_nan_remote_peers() - Delete all nan peers
+ * @wma:  wma handle
+ * @vdev_id: vdev id
+ *
+ * Return: None
+ */
+void wma_delete_all_nan_remote_peers(tp_wma_handle wma, uint32_t vdev_id)
+{
+	ol_txrx_vdev_handle vdev;
+	ol_txrx_peer_handle peer, temp;
+
+	if (vdev_id > wma->max_bssid) {
+		WMA_LOGE("%s: invalid vdev_id = %d", __func__, vdev_id);
+		return;
+	}
+
+	vdev = wma->interfaces[vdev_id].handle;
+	if (!vdev) {
+		WMA_LOGE("%s: vdev is NULL for vdev_id = %d",
+			 __func__, vdev_id);
+		return;
+	}
+
+	/* remove all remote peers of ndi */
+	qdf_spin_lock_bh(&vdev->pdev->peer_ref_mutex);
+
+	temp = NULL;
+	TAILQ_FOREACH_REVERSE(peer, &vdev->peer_list,
+		peer_list_t, peer_list_elem) {
+		if (temp) {
+			qdf_spin_unlock_bh(&vdev->pdev->peer_ref_mutex);
+			if (qdf_atomic_read(
+				&temp->delete_in_progress) == 0)
+				wma_remove_peer(wma, temp->mac_addr.raw,
+					vdev_id, temp, false);
+			qdf_spin_lock_bh(&vdev->pdev->peer_ref_mutex);
+		}
+		/* self peer is deleted last */
+		if (peer == TAILQ_FIRST(&vdev->peer_list)) {
+			WMA_LOGE("%s: self peer removed", __func__);
+			break;
+		} else
+			temp = peer;
+	}
+	qdf_spin_unlock_bh(&vdev->pdev->peer_ref_mutex);
+
+	/* remove ndi self peer last */
+	peer = TAILQ_FIRST(&vdev->peer_list);
+	wma_remove_peer(wma, peer->mac_addr.raw, vdev_id, peer,
+			false);
+}

+ 10 - 2
core/wma/src/wma_nan_datapath.h

@@ -31,6 +31,8 @@
 #include "sir_api.h"
 
 #ifdef WLAN_FEATURE_NAN_DATAPATH
+#define WMA_IS_VDEV_IN_NDI_MODE(intf, vdev_id) \
+				(WMI_VDEV_TYPE_NDI == intf[vdev_id].type)
 
 void wma_add_bss_ndi_mode(tp_wma_handle wma, tpAddBssParams add_bss);
 
@@ -46,8 +48,10 @@ static inline void wma_update_hdd_cfg_ndp(tp_wma_handle wma_handle,
 {
 	tgt_cfg->nan_datapath_enabled = wma_handle->nan_datapath_enabled;
 }
-
+void wma_delete_all_nan_remote_peers(tp_wma_handle wma,
+					uint32_t vdev_id);
 #else
+#define WMA_IS_VDEV_IN_NDI_MODE(intf, vdev_id) (false)
 static inline void wma_update_hdd_cfg_ndp(tp_wma_handle wma_handle,
 					struct wma_tgt_cfg *tgt_cfg)
 {
@@ -59,6 +63,10 @@ static inline void wma_add_bss_ndi_mode(tp_wma_handle wma,
 	return;
 }
 
-#endif /* WLAN_FEATURE_NAN_DATAPATH */
+static inline void wma_delete_all_nan_remote_peers(tp_wma_handle wma,
+							uint32_t vdev_id)
+{
+}
 
+#endif /* WLAN_FEATURE_NAN_DATAPATH */
 #endif /* __WMA_NAN_DATAPATH_H */