Ver Fonte

qcacld-3.0: Add support for roaming on all STA interfaces

Roaming is allowed only on wlan0 interface and is not allowed by
default on any other STA interface.

With this change, roaming will be allowed on all the STA interface
with below conditions:
 - At a time only one STA interface will have roaming enabled.
 - STA which connects first will enable the roaming.
 - Whenever a STA connects and if roaming is not enabled on
   any STA interface, roaming will be enabled on the connected STA.
 - Whenever a STA on which roaming was enabled disconnects, if any
   other STA interface is present and is in connected state, the
   roaming will get enabled on the other STA interface.

Change-Id: I4c7654480ad893eb1635138447e1a0b37abf1ac4
CRs-Fixed: 2166972
Abhishek Singh há 7 anos atrás
pai
commit
1f217ecc2d

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

@@ -1214,7 +1214,6 @@ struct hdd_adapter {
 	uint8_t pre_cac_chan;
 	struct hdd_connect_pm_context connect_rpm_ctx;
 
-	bool fast_roaming_allowed;
 	/*
 	 * Indicate if HO fails during disconnect so that
 	 * disconnect is not initiated by HDD as its already

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

@@ -1741,6 +1741,10 @@ static QDF_STATUS hdd_dis_connect_handler(struct hdd_adapter *adapter,
 	hdd_reset_limit_off_chan(adapter);
 
 	hdd_print_bss_info(sta_ctx);
+
+	if (policy_mgr_is_sta_active_connection_exists(hdd_ctx->hdd_psoc))
+		sme_enable_roaming_on_connected_sta(hdd_ctx->hHal);
+
 	return status;
 }
 

+ 7 - 19
core/hdd/src/wlan_hdd_cfg80211.c

@@ -11744,7 +11744,7 @@ static int __wlan_hdd_cfg80211_set_fast_roaming(struct wiphy *wiphy,
 	struct net_device *dev = wdev->netdev;
 	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
 	struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
-	uint32_t is_fast_roam_enabled, enable_lfr_fw;
+	uint32_t is_fast_roam_enabled;
 	int ret;
 	QDF_STATUS qdf_status;
 	unsigned long rc;
@@ -11777,25 +11777,18 @@ static int __wlan_hdd_cfg80211_set_fast_roaming(struct wiphy *wiphy,
 
 	is_fast_roam_enabled = nla_get_u32(
 				tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]);
-	hdd_debug("isFastRoamEnabled %d fast_roaming_allowed %d",
-		   is_fast_roam_enabled, adapter->fast_roaming_allowed);
+	hdd_debug("isFastRoamEnabled %d", is_fast_roam_enabled);
 
-	if (!adapter->fast_roaming_allowed) {
-		hdd_err("fast roaming not allowed on %s interface",
-			adapter->dev->name);
-		return -EINVAL;
-	}
 	/* Update roaming */
-	enable_lfr_fw = (is_fast_roam_enabled && adapter->fast_roaming_allowed);
 	qdf_status = sme_config_fast_roaming(hdd_ctx->hHal, adapter->session_id,
-					     enable_lfr_fw);
+					     is_fast_roam_enabled);
 	if (qdf_status != QDF_STATUS_SUCCESS)
 		hdd_err("sme_config_fast_roaming failed with status=%d",
 				qdf_status);
 	ret = qdf_status_to_os_return(qdf_status);
 
 	if (eConnectionState_Associated == hdd_sta_ctx->conn_info.connState &&
-		QDF_IS_STATUS_SUCCESS(qdf_status) && !enable_lfr_fw) {
+		QDF_IS_STATUS_SUCCESS(qdf_status) && !is_fast_roam_enabled) {
 
 		INIT_COMPLETION(adapter->lfr_fw_status.disable_lfr_event);
 		/*
@@ -16540,10 +16533,7 @@ static int wlan_hdd_cfg80211_connect_start(struct hdd_adapter *adapter,
 		qdf_mem_copy((void *)(roam_profile->SSIDs.SSIDList->SSID.ssId),
 			     ssid, ssid_len);
 
-		roam_profile->supplicant_disabled_roaming =
-			!adapter->fast_roaming_allowed;
-		roam_profile->roaming_allowed_on_iface =
-			adapter->fast_roaming_allowed;
+		roam_profile->supplicant_disabled_roaming = false;
 
 		/* cleanup bssid hint */
 		qdf_mem_zero(roam_profile->bssid_hint.bytes,
@@ -20967,10 +20957,8 @@ static int __wlan_hdd_cfg80211_update_connect_params(
 		  changed, roam_profile->fils_con_info->is_fils_connection,
 		  roam_profile->fils_con_info->key_nai_length);
 
-	if (!adapter->fast_roaming_allowed ||
-	    !hdd_ctx->is_fils_roaming_supported) {
-		hdd_debug("LFR3: %d, FILS support %d",
-			  adapter->fast_roaming_allowed,
+	if (!hdd_ctx->is_fils_roaming_supported) {
+		hdd_debug("FILS roaming support %d",
 			  hdd_ctx->is_fils_roaming_supported);
 		return 0;
 	}

+ 1 - 17
core/hdd/src/wlan_hdd_ioctl.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -3215,11 +3215,6 @@ static int drv_cmd_set_roam_mode(struct hdd_adapter *adapter,
 	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;
 
@@ -4256,11 +4251,6 @@ static int drv_cmd_set_fast_roam(struct hdd_adapter *adapter,
 	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;
 
@@ -5596,12 +5586,6 @@ static int drv_cmd_set_ccx_mode(struct hdd_adapter *adapter,
 		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;
 

+ 1 - 4
core/hdd/src/wlan_hdd_main.c

@@ -3750,7 +3750,7 @@ QDF_STATUS hdd_init_station_mode(struct hdd_adapter *adapter)
 
 	/* set fast roaming capability in sme session */
 	status = sme_config_fast_roaming(hdd_ctx->hHal, adapter->session_id,
-					 adapter->fast_roaming_allowed);
+					 true);
 	/* Set the default operation channel */
 	sta_ctx->conn_info.operationChannel =
 		hdd_ctx->config->OperatingChannel;
@@ -8534,9 +8534,6 @@ static int hdd_open_interfaces(struct hdd_context *hdd_ctx, bool rtnl_held)
 	if (adapter == NULL)
 		return -ENOSPC;
 
-	/* fast roaming is allowed only on first STA, i.e. wlan adapter */
-	adapter->fast_roaming_allowed = true;
-
 	if (strlen(hdd_ctx->config->enableConcurrentSTA) != 0) {
 		ret = hdd_open_concurrent_interface(hdd_ctx, rtnl_held);
 		if (ret)

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

@@ -996,7 +996,6 @@ typedef struct csr_roam_profile {
 	uint32_t cac_duration_ms;
 	uint32_t dfs_regdomain;
 	bool supplicant_disabled_roaming;
-	bool roaming_allowed_on_iface;
 #ifdef WLAN_FEATURE_FILS_SK
 	bool fils_connection;
 	uint8_t *hlp_ie;

+ 13 - 1
core/sme/inc/csr_internal.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2018 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -1246,6 +1246,18 @@ bool csr_is_sta_session_connected(tpAniSirGlobal pMac);
 bool csr_is_p2p_session_connected(tpAniSirGlobal pMac);
 bool csr_is_any_session_connected(tpAniSirGlobal pMac);
 bool csr_is_infra_connected(tpAniSirGlobal pMac);
+
+/**
+ * csr_get_connected_infra() - get the session id of the connected infra
+ * @mac_ctx:  pointer to global mac structure
+ *
+ * The function check if any infra is present in connected state and if present
+ * return the session id of the connected infra else if no infra is in connected
+ * state return CSR_SESSION_ID_INVALID
+ *
+ * Return: session id of the connected infra
+ */
+uint8_t csr_get_connected_infra(tpAniSirGlobal mac_ctx);
 bool csr_is_concurrent_infra_connected(tpAniSirGlobal pMac);
 bool csr_is_concurrent_session_running(tpAniSirGlobal pMac);
 bool csr_is_infra_ap_started(tpAniSirGlobal pMac);

+ 15 - 1
core/sme/inc/csr_neighbor_roam.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2018 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -344,6 +344,20 @@ static inline QDF_STATUS csr_roam_offload_scan(tpAniSirGlobal pMac,
 }
 #endif
 
+/**
+ * csr_get_roam_enabled_sta_sessionid() - get the session id of the sta on which
+ * roaming is enabled.
+ * @mac_ctx:  pointer to global mac structure
+ *
+ * The function check if any sta is present and has roaming enabled and return
+ * the session id of the sta with roaming enabled else if roaming is not enabled
+ * on any STA return CSR_SESSION_ID_INVALID
+ *
+ * Return: session id of STA on which roaming is enabled
+ */
+uint8_t csr_get_roam_enabled_sta_sessionid(
+	tpAniSirGlobal mac_ctx);
+
 #if defined(WLAN_FEATURE_FILS_SK)
 /**
  * csr_update_fils_config - Update FILS config to CSR roam session

+ 11 - 0
core/sme/inc/sme_api.h

@@ -1994,4 +1994,15 @@ uint32_t sme_unpack_rsn_ie(tHalHandle hal, uint8_t *buf,
 				  uint8_t buf_len, tDot11fIERSN *rsn_ie,
 				  bool append_ie);
 
+/**
+ * sme_enable_roaming_on_connected_sta() - Enable roaming on an connected sta
+ * @hal: handle returned by mac_open
+ *
+ * The function check if any connected STA is present on which roaming is not
+ * enabled and if present enabled roaming on that STA.
+ *
+ * Return: none
+ */
+void sme_enable_roaming_on_connected_sta(tHalHandle hal);
+
 #endif /* #if !defined( __SME_API_H ) */

+ 32 - 5
core/sme/src/common/sme_api.c

@@ -7278,13 +7278,12 @@ QDF_STATUS sme_stop_roaming(tHalHandle hal, uint8_t session_id, uint8_t reason)
 	}
 
 	session = CSR_GET_SESSION(mac_ctx, session_id);
-	if (session->pCurRoamProfile &&
-		!session->pCurRoamProfile->roaming_allowed_on_iface) {
-		sme_debug("Roaming was never started on session %d",
-				session_id);
+
+	roam_info = &mac_ctx->roam.neighborRoamInfo[session_id];
+	if (!roam_info->b_roam_scan_offload_started) {
+		sme_debug("Roaming already disabled for session %d", session_id);
 		return QDF_STATUS_SUCCESS;
 	}
-	roam_info = &mac_ctx->roam.neighborRoamInfo[session_id];
 	req = qdf_mem_malloc(sizeof(*req));
 	if (!req) {
 		sme_err("failed to allocated memory");
@@ -15844,3 +15843,31 @@ free:
 	return status;
 }
 
+void sme_enable_roaming_on_connected_sta(tHalHandle hal)
+{
+	uint8_t session_id;
+	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
+	QDF_STATUS status;
+
+	session_id = csr_get_roam_enabled_sta_sessionid(mac_ctx);
+	if (session_id != CSR_SESSION_ID_INVALID)
+		return;
+
+	session_id = csr_get_connected_infra(mac_ctx);
+	if (session_id == CSR_SESSION_ID_INVALID) {
+		sme_debug("No STA in conencted state");
+		return;
+	}
+
+	sme_debug("Roaming not enabled on any STA, enable roaming on session %d",
+		  session_id);
+	status = sme_acquire_global_lock(&mac_ctx->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		csr_roam_offload_scan(mac_ctx, session_id,
+				      ROAM_SCAN_OFFLOAD_START,
+				      REASON_CTX_INIT);
+		sme_release_global_lock(&mac_ctx->sme);
+	}
+
+}
+

+ 31 - 9
core/sme/src/csr/csr_api_roam.c

@@ -8016,8 +8016,6 @@ QDF_STATUS csr_roam_copy_profile(tpAniSirGlobal pMac,
 	pDstProfile->sap_dot11mc = pSrcProfile->sap_dot11mc;
 	pDstProfile->supplicant_disabled_roaming =
 		pSrcProfile->supplicant_disabled_roaming;
-	pDstProfile->roaming_allowed_on_iface =
-		pSrcProfile->roaming_allowed_on_iface;
 	qdf_mem_copy(&pDstProfile->Keys, &pSrcProfile->Keys,
 		sizeof(pDstProfile->Keys));
 #ifdef WLAN_FEATURE_11W
@@ -18750,6 +18748,29 @@ static void csr_update_score_params(tpAniSirGlobal mac_ctx,
 		bss_score_params->oce_wan_scoring.score_pcnt15_to_12;
 }
 
+uint8_t csr_get_roam_enabled_sta_sessionid(tpAniSirGlobal mac_ctx)
+{
+	struct csr_roam_session *session;
+	tpCsrNeighborRoamControlInfo roam_info;
+	uint8_t i;
+
+	for (i = 0; i < CSR_ROAM_SESSION_MAX; i++) {
+		session = CSR_GET_SESSION(mac_ctx, i);
+		if (!session || !CSR_IS_SESSION_VALID(mac_ctx, i))
+			continue;
+		if (!session->pCurRoamProfile ||
+		    session->pCurRoamProfile->csrPersona != QDF_STA_MODE)
+			continue;
+		roam_info = &mac_ctx->roam.neighborRoamInfo[i];
+		if (roam_info->b_roam_scan_offload_started) {
+			sme_debug("Roaming enabled on iface, session: %d", i);
+			return i;
+		}
+	}
+
+	return CSR_SESSION_ID_INVALID;
+}
+
 /**
  * csr_roam_offload_scan() - populates roam offload scan request and sends to
  * WMA
@@ -18774,21 +18795,22 @@ csr_roam_offload_scan(tpAniSirGlobal mac_ctx, uint8_t session_id,
 		&mac_ctx->roam.neighborRoamInfo[session_id];
 	struct roam_ext_params *roam_params_dst;
 	struct roam_ext_params *roam_params_src;
-	uint8_t i;
+	uint8_t i, temp_session_id;
 	uint8_t op_channel;
 
-	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
-			"RSO Command %d, Session id %d, Reason %d",
-			command, session_id, reason);
+	sme_debug("RSO Command %d, Session id %d, Reason %d", command,
+		   session_id, reason);
 	if (NULL == session) {
 		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
 			 "session is null");
 		return QDF_STATUS_E_FAILURE;
 	}
 
-	if ((session->pCurRoamProfile &&
-		session->pCurRoamProfile->roaming_allowed_on_iface == false)) {
-		sme_debug("Roaming disabled on iface, session: %d", session_id);
+	temp_session_id = csr_get_roam_enabled_sta_sessionid(mac_ctx);
+	if ((temp_session_id != CSR_SESSION_ID_INVALID) &&
+	    (session_id != temp_session_id)) {
+		sme_debug("Roam cmd not for session %d on which roaming is enabled",
+			   temp_session_id);
 		return QDF_STATUS_E_FAILURE;
 	}
 

+ 17 - 0
core/sme/src/csr/csr_util.c

@@ -1434,6 +1434,23 @@ bool csr_is_infra_connected(tpAniSirGlobal pMac)
 	return fRc;
 }
 
+uint8_t csr_get_connected_infra(tpAniSirGlobal mac_ctx)
+{
+	uint32_t i;
+	uint8_t connected_session = CSR_SESSION_ID_INVALID;
+
+	for (i = 0; i < CSR_ROAM_SESSION_MAX; i++) {
+		if (CSR_IS_SESSION_VALID(mac_ctx, i)
+		    && csr_is_conn_state_connected_infra(mac_ctx, i)) {
+			connected_session = i;
+			break;
+		}
+	}
+
+	return connected_session;
+}
+
+
 bool csr_is_concurrent_infra_connected(tpAniSirGlobal pMac)
 {
 	uint32_t i, noOfConnectedInfra = 0;

+ 2 - 2
core/wma/src/wma_scan_roam.c

@@ -1882,8 +1882,8 @@ QDF_STATUS wma_process_roaming_config(tp_wma_handle wma_handle,
 		qdf_mem_free(roam_req);
 		return QDF_STATUS_E_PERM;
 	}
-	WMA_LOGD("%s: RSO Command:%d, reason:%d",
-			__func__, roam_req->Command, roam_req->reason);
+	WMA_LOGD("%s: RSO Command:%d, reason:%d session ID %d", __func__,
+		 roam_req->Command, roam_req->reason, roam_req->sessionId);
 	wma_handle->interfaces[roam_req->sessionId].roaming_in_progress = false;
 	switch (roam_req->Command) {
 	case ROAM_SCAN_OFFLOAD_START: