qcacld-3.0: Enable roaming only on wlan0

Current implementation of host driver will support fast roaming only
on a single device even in DBS mode. It is allowed on the first
STA, i.e. wlan device created in driver initialization. Dynamic roaming
disable/enable is allowed only on that device. Roaming is marked as not
allowed on other devices.

Change-Id: I3e3a72eb4d8fe81f6d3b784ab70023d2e3ac5618
CRs-Fixed: 1092386
diff --git a/core/hdd/src/wlan_hdd_assoc.c b/core/hdd/src/wlan_hdd_assoc.c
index de08e4f..f0b8a5c 100644
--- a/core/hdd/src/wlan_hdd_assoc.c
+++ b/core/hdd/src/wlan_hdd_assoc.c
@@ -1322,7 +1322,6 @@
 		memset(wrqu.ap_addr.sa_data, '\0', ETH_ALEN);
 		cds_decr_session_set_pcl(pAdapter->device_mode,
 					pAdapter->sessionId);
-		wlan_hdd_enable_roaming(pAdapter);
 
 #ifdef FEATURE_WLAN_AUTO_SHUTDOWN
 		wlan_hdd_auto_shutdown_enable(pHddCtx, true);
diff --git a/core/hdd/src/wlan_hdd_cfg80211.c b/core/hdd/src/wlan_hdd_cfg80211.c
index caeb2e9..1f0f003 100644
--- a/core/hdd/src/wlan_hdd_cfg80211.c
+++ b/core/hdd/src/wlan_hdd_cfg80211.c
@@ -8049,11 +8049,18 @@
 
 	is_fast_roam_enabled = nla_get_u32(
 				tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]);
-	hdd_notice("isFastRoamEnabled %d", is_fast_roam_enabled);
+	hdd_notice("isFastRoamEnabled %d fast_roaming_allowed %d",
+		   is_fast_roam_enabled, adapter->fast_roaming_allowed);
 
+	if (!adapter->fast_roaming_allowed) {
+		hdd_err("fast roaming not allowed on %s interface",
+			adapter->dev->name);
+		return -EINVAL;
+	}
 	/* Update roaming */
 	ret = sme_config_fast_roaming(hdd_ctx->hHal, adapter->sessionId,
-					is_fast_roam_enabled);
+				      (is_fast_roam_enabled &&
+				       adapter->fast_roaming_allowed));
 	if (ret)
 		hdd_err("sme_config_fast_roaming failed");
 	EXIT();
@@ -11551,7 +11558,7 @@
 		qdf_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
 			     ssid, ssid_len);
 
-		pRoamProfile->do_not_roam = false;
+		pRoamProfile->do_not_roam = !pAdapter->fast_roaming_allowed;
 		if (bssid) {
 			pRoamProfile->BSSIDs.numOfBSSIDs = 1;
 			pRoamProfile->do_not_roam = true;
@@ -12676,8 +12683,6 @@
 	if (true == wlan_hdd_reassoc_bssid_hint(pAdapter, req, &status))
 		return status;
 
-	wlan_hdd_disable_roaming(pAdapter);
-
 	/* Try disconnecting if already in connected state */
 	status = wlan_hdd_try_disconnect(pAdapter);
 	if (0 > status) {
diff --git a/core/hdd/src/wlan_hdd_ioctl.c b/core/hdd/src/wlan_hdd_ioctl.c
index ba48e4c..33f3bbb 100644
--- a/core/hdd/src/wlan_hdd_ioctl.c
+++ b/core/hdd/src/wlan_hdd_ioctl.c
@@ -3281,6 +3281,11 @@
 	uint8_t *value = command;
 	uint8_t roamMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
 
+	if (!adapter->fast_roaming_allowed) {
+		hdd_err("Roaming is always disabled on this interface");
+		goto exit;
+	}
+
 	/* Move pointer to ahead of SETROAMMODE<delimiter> */
 	value = value + SIZE_OF_SETROAMMODE + 1;
 
@@ -4315,6 +4320,11 @@
 	uint8_t *value = command;
 	uint8_t lfrMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
 
+	if (!adapter->fast_roaming_allowed) {
+		hdd_err("Roaming is always disabled on this interface");
+		goto exit;
+	}
+
 	/* Move pointer to ahead of SETFASTROAM<delimiter> */
 	value = value + command_len + 1;
 
@@ -5644,6 +5654,12 @@
 		goto exit;
 	}
 
+	if (!adapter->fast_roaming_allowed) {
+		hdd_warn("Fast roaming is not allowed on this device hence this operation is not permitted!");
+		ret = -EPERM;
+		goto exit;
+	}
+
 	/* Move pointer to ahead of SETCCXMODE<delimiter> */
 	value = value + command_len + 1;
 
diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c
index db281de..a3b7649 100644
--- a/core/hdd/src/wlan_hdd_main.c
+++ b/core/hdd/src/wlan_hdd_main.c
@@ -2701,6 +2701,9 @@
 	hdd_notice("Set HDD connState to eConnectionState_NotConnected");
 	pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
 
+	/* set fast roaming capability in sme session */
+	status = sme_config_fast_roaming(hdd_ctx->hHal, adapter->sessionId,
+					 adapter->fast_roaming_allowed);
 	/* Set the default operation channel */
 	pHddStaCtx->conn_info.operationChannel =
 		hdd_ctx->config->OperatingChannel;
@@ -6859,6 +6862,9 @@
 
 	if (adapter == NULL)
 		return ERR_PTR(-ENOSPC);
+	/* fast roaming is allowed only on first STA, i.e. wlan adapter */
+	adapter->fast_roaming_allowed = true;
+
 	ret = hdd_open_p2p_interface(hdd_ctx, rtnl_held);
 	if (ret)
 		goto err_close_adapter;