Explorar el Código

qcacld-3.0: Add CSR APIs to maintain roam state machine

Add CSR APIs to maintain the roam state machine.

Change-Id: I68728cb657c5a492f141bea90b2da0d70cb61f08
CRs-Fixed: 2520826
Yeshwanth Sriram Guntuka hace 5 años
padre
commit
1669fc0508

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

@@ -1899,7 +1899,8 @@ static QDF_STATUS hdd_dis_connect_handler(struct hdd_adapter *adapter,
 	hdd_print_bss_info(sta_ctx);
 
 	if (policy_mgr_is_sta_active_connection_exists(hdd_ctx->psoc))
-		sme_enable_roaming_on_connected_sta(mac_handle);
+		sme_enable_roaming_on_connected_sta(mac_handle,
+						    adapter->vdev_id);
 
 	return status;
 }

+ 10 - 0
core/mac/inc/sir_api.h

@@ -2150,6 +2150,16 @@ struct mawc_params {
 	uint8_t mawc_roam_rssi_low_adjust;
 };
 
+/**
+ * struct roam_init_params - Firmware roam module initialization parameters
+ * @vdev_id: vdev for which the roaming has to be enabled/disabled
+ * @enable:  flag to init/deinit roam module
+ */
+struct roam_init_params {
+	uint8_t vdev_id;
+	uint8_t enable;
+};
+
 /**
  * struct roam_sync_timeout_timer_info - Info related to roam sync timer
  * @vdev_id: Vdev id for which host waiting roam sync ind from fw

+ 3 - 1
core/mac/src/include/sir_params.h

@@ -606,8 +606,10 @@ struct sir_cfg_action_frm_tb_ppdu {
 
 #define SIR_HAL_HIDDEN_SSID_RESTART_RSP     (SIR_HAL_ITC_MSG_TYPES_BEGIN + 379)
 
+#define SIR_HAL_INIT_ROAM_OFFLOAD_PARAM     (SIR_HAL_ITC_MSG_TYPES_BEGIN + 380)
+
 /*
- * Unused SIR_HAL_ITC_MSG_TYPES_BEGIN + 380 to
+ * Unused SIR_HAL_ITC_MSG_TYPES_BEGIN + 381 to
  * SIR_HAL_ITC_MSG_TYPES_BEGIN + 386
  */
 #define SIR_HAL_GET_PEER_INFO_EXT           (SIR_HAL_ITC_MSG_TYPES_BEGIN + 387)

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

@@ -1514,4 +1514,16 @@ void csr_clear_channel_status(struct mac_context *mac);
  */
 QDF_STATUS csr_update_owe_info(struct mac_context *mac,
 			       struct assoc_ind *assoc_ind);
+
+/**
+ * csr_send_roam_offload_init_msg() - Send roam enable/disable flag to fw
+ * @mac: mac context
+ * @vdev_id: vdev id
+ * @enable: enable/disable roam flag
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS
+csr_send_roam_offload_init_msg(struct mac_context *mac, uint32_t vdev_id,
+			       bool enable);
 #endif

+ 78 - 2
core/sme/inc/csr_neighbor_roam.h

@@ -263,18 +263,94 @@ void csr_roam_reset_roam_params(struct mac_context *mac_ptr);
 #define REASON_DRIVER_ENABLED                       43
 #define REASON_ROAM_FULL_SCAN_PERIOD_CHANGED        44
 #define REASON_SCORING_CRITERIA_CHANGED             45
-#define REASON_ROAM_CONTROL_CONFIG_RESTORED         46
-#define REASON_ROAM_CONTROL_CONFIG_ENABLED          47
+#define REASON_SUPPLICANT_INIT_ROAMING              46
+#define REASON_SUPPLICANT_DE_INIT_ROAMING           47
+#define REASON_DRIVER_DISABLED                      48
+#define REASON_ROAM_CONTROL_CONFIG_RESTORED         49
+#define REASON_ROAM_CONTROL_CONFIG_ENABLED          50
 
 #if defined(WLAN_FEATURE_HOST_ROAM) || defined(WLAN_FEATURE_ROAM_OFFLOAD)
 QDF_STATUS csr_roam_offload_scan(struct mac_context *mac, uint8_t sessionId,
 		uint8_t command, uint8_t reason);
+
+/**
+ * csr_post_roam_state_change() - Post roam state change to roam state machine
+ * @mac: mac context
+ * @vdev_id: vdev id
+ * @state: roam state to be set for the requested vdev id
+ * @reason: reason for changing roam state for the requested vdev id
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS csr_post_roam_state_change(struct mac_context *mac, uint8_t vdev_id,
+				      enum roam_offload_state state,
+				      uint8_t reason);
+
+/**
+ * csr_post_rso_stop() - Post RSO stop message to WMA
+ * @mac: mac context
+ * @vdev_id: vdev id
+ * @reason: reason for requesting RSO stop
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS
+csr_post_rso_stop(struct mac_context *mac, uint8_t vdev_id, uint16_t reason);
+
+/**
+ * csr_enable_roaming_on_connected_sta() - Enable roaming on other connected
+ *  sta vdev
+ * @mac: mac context
+ * @vdev_id: vdev id on which roaming should not be enabled
+ * @reason: reason for enabling roaming on connected sta vdev
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS
+csr_enable_roaming_on_connected_sta(struct mac_context *mac, uint8_t vdev_id);
+
+/**
+ * csr_roam_update_cfg() - Process RSO update cfg request
+ * @mac: mac context
+ * @vdev_id: vdev id
+ * @reason: reason for requesting RSO update cfg
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS
+csr_roam_update_cfg(struct mac_context *mac, uint8_t vdev_id, uint8_t reason);
 #else
 static inline QDF_STATUS csr_roam_offload_scan(struct mac_context *mac,
 		uint8_t sessionId, uint8_t command, uint8_t reason)
 {
 	return QDF_STATUS_E_NOSUPPORT;
 }
+
+static inline
+QDF_STATUS csr_post_roam_state_change(struct mac_context *mac, uint8_t vdev_id,
+				      enum roam_offload_state state,
+				      uint8_t reason)
+{
+	return QDF_STATUS_E_NOSUPPORT;
+}
+
+static inline
+csr_post_rso_stop(struct mac_context *mac, uint8_t vdev_id, uint16_t reason)
+{
+	return QDF_STATUS_E_NOSUPPORT;
+}
+
+static inline QDF_STATUS
+csr_enable_roaming_on_connected_sta(struct mac_context *mac, uint8_t vdev_id)
+{
+	return QDF_STATUS_E_NOSUPPORT;
+}
+
+static inline QDF_STATUS
+csr_roam_update_cfg(struct mac_context *mac, uint8_t vdev_id, uint8_t reason)
+{
+	return QDF_STATUS_E_NOSUPPORT;
+}
 #endif
 
 /**

+ 3 - 1
core/sme/inc/sme_api.h

@@ -2799,13 +2799,15 @@ int sme_get_sec20chan_freq_mhz(struct wlan_objmgr_vdev *vdev,
 /**
  * sme_enable_roaming_on_connected_sta() - Enable roaming on an connected sta
  * @mac_handle: handle returned by mac_open
+ * @vdev_id: vdev id
  *
  * 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(mac_handle_t mac_handle);
+void sme_enable_roaming_on_connected_sta(mac_handle_t mac_handle,
+					 uint8_t vdev_id);
 
 /**
  * sme_send_mgmt_tx() - Sends mgmt frame from CSR to LIM

+ 6 - 19
core/sme/src/common/sme_api.c

@@ -15118,31 +15118,18 @@ bool sme_is_conn_state_connected(mac_handle_t mac_handle, uint8_t session_id)
 	return csr_is_conn_state_connected(mac_ctx, session_id);
 }
 
-void sme_enable_roaming_on_connected_sta(mac_handle_t mac_handle)
+void sme_enable_roaming_on_connected_sta(mac_handle_t mac_handle,
+					 uint8_t vdev_id)
 {
-	uint8_t session_id;
 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
 	QDF_STATUS status;
 
-	session_id = csr_get_roam_enabled_sta_sessionid(mac_ctx);
-	if (session_id != WLAN_UMAC_VDEV_ID_MAX)
-		return;
-
-	session_id = csr_get_connected_infra(mac_ctx);
-	if (session_id == WLAN_UMAC_VDEV_ID_MAX) {
-		sme_debug("No STA in conencted state");
+	status = sme_acquire_global_lock(&mac_ctx->sme);
+	if (QDF_IS_STATUS_ERROR(status))
 		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);
-	}
+	csr_enable_roaming_on_connected_sta(mac_ctx, vdev_id);
+	sme_release_global_lock(&mac_ctx->sme);
 }
 
 int16_t sme_get_oper_chan_freq(struct wlan_objmgr_vdev *vdev)

+ 396 - 4
core/sme/src/csr/csr_api_roam.c

@@ -19186,7 +19186,6 @@ static void csr_update_score_params(struct mac_context *mac_ctx,
 uint8_t csr_get_roam_enabled_sta_sessionid(struct mac_context *mac_ctx)
 {
 	struct csr_roam_session *session;
-	tpCsrNeighborRoamControlInfo roam_info;
 	uint8_t i;
 
 	for (i = 0; i < WLAN_MAX_VDEVS; i++) {
@@ -19196,9 +19195,9 @@ uint8_t csr_get_roam_enabled_sta_sessionid(struct mac_context *mac_ctx)
 		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);
+
+		if (MLME_IS_ROAM_INITIALIZED(mac_ctx->psoc, i)) {
+			sme_debug("ROAM: Enabled on vdev_id: %d", i);
 			return i;
 		}
 	}
@@ -19226,6 +19225,308 @@ csr_is_adaptive_11r_roam_supported(struct mac_context *mac_ctx,
 }
 #endif
 
+QDF_STATUS
+csr_post_rso_stop(struct mac_context *mac, uint8_t vdev_id, uint16_t reason)
+{
+	struct scheduler_msg sch_msg = {0};
+	QDF_STATUS status;
+	struct roam_offload_scan_req *req;
+	tpCsrNeighborRoamControlInfo roam_info;
+	struct csr_roam_session *session;
+
+	session = CSR_GET_SESSION(mac, vdev_id);
+	if (!session) {
+		sme_err("ROAM: incorrect vdev ID %d", vdev_id);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	roam_info = &mac->roam.neighborRoamInfo[vdev_id];
+
+	req = qdf_mem_malloc(sizeof(*req));
+	if (!req)
+		return QDF_STATUS_E_NOMEM;
+
+	req->sessionId = vdev_id;
+	req->Command = ROAM_SCAN_OFFLOAD_STOP;
+
+	if (reason == REASON_DRIVER_DISABLED)
+		req->reason = REASON_ROAM_STOP_ALL;
+	else
+		req->reason = REASON_SME_ISSUED;
+
+	if (csr_neighbor_middle_of_roaming(mac, vdev_id))
+		req->middle_of_roaming = 1;
+	else
+		csr_roam_reset_roam_params(mac);
+
+	/*
+	 * Disable offload_11k_params and btm_offload_config for current
+	 * vdev
+	 */
+	req->offload_11k_params.vdev_id = vdev_id;
+
+	sch_msg.type = WMA_ROAM_SCAN_OFFLOAD_REQ;
+	sch_msg.bodyptr = req;
+
+	status = scheduler_post_message(QDF_MODULE_ID_SME,
+					QDF_MODULE_ID_WMA,
+					QDF_MODULE_ID_WMA,
+					&sch_msg);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		sme_err("ROAM: Post RSO stop to WMA failed, vdev_id: %d",
+			vdev_id);
+		qdf_mem_zero(req, sizeof(*req));
+		qdf_mem_free(req);
+		return QDF_STATUS_E_FAULT;
+	}
+	roam_info->last_sent_cmd = ROAM_SCAN_OFFLOAD_STOP;
+
+	return status;
+}
+
+static QDF_STATUS
+csr_roam_switch_to_init(struct mac_context *mac, uint8_t vdev_id,
+			uint8_t reason)
+{
+	enum roam_offload_state cur_state;
+	uint8_t temp_vdev_id;
+	uint32_t roaming_bitmap;
+	QDF_STATUS status;
+
+	cur_state = mlme_get_roam_state(mac->psoc, vdev_id);
+	switch (cur_state) {
+	case ROAM_DEINIT:
+		roaming_bitmap = mlme_get_roam_trigger_bitmap(mac->psoc,
+							      vdev_id);
+		if (!roaming_bitmap) {
+			sme_info("ROAM: Cannot change to INIT state for vdev[%d]",
+				 vdev_id);
+			return QDF_STATUS_E_FAILURE;
+		}
+
+		/*
+		 * Disable roaming on the enabled sta if supplicant wants to
+		 * enable roaming on this vdev id
+		 */
+		temp_vdev_id = csr_get_roam_enabled_sta_sessionid(mac);
+		if ((temp_vdev_id != WLAN_UMAC_VDEV_ID_MAX) &&
+		    (vdev_id != temp_vdev_id)) {
+			/*
+			 * Roam init state can be requested as part of
+			 * initial connection or due to enable from
+			 * supplicant via vendor command. This check will
+			 * ensure roaming does not get enabled on this STA
+			 * vdev id if it is not an explicit enable from
+			 * supplicant.
+			 */
+			if (reason != REASON_SUPPLICANT_INIT_ROAMING) {
+				sme_info("ROAM: Roam module already initialized on vdev:[%d]",
+					 temp_vdev_id);
+				return QDF_STATUS_E_FAILURE;
+			}
+			csr_post_roam_state_change(mac, temp_vdev_id,
+						   ROAM_DEINIT, reason);
+		}
+		break;
+
+	case ROAM_INIT:
+	case ROAM_RSO_STOPPED:
+	case ROAM_RSO_STARTED:
+	/*
+	 * Already the roaming module is initialized at fw,
+	 * just return from here
+	 */
+	default:
+		return QDF_STATUS_SUCCESS;
+	}
+
+	status = csr_send_roam_offload_init_msg(mac, vdev_id, true);
+
+	if (QDF_IS_STATUS_ERROR(status))
+		return status;
+
+	mlme_set_roam_state(mac->psoc, vdev_id, ROAM_INIT);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+static QDF_STATUS
+csr_roam_switch_to_rso_start(struct mac_context *mac, uint8_t vdev_id,
+			     uint8_t reason)
+{
+	enum roam_offload_state cur_state;
+	QDF_STATUS status;
+	uint8_t control_bitmap;
+	bool sup_disabled_roaming;
+	bool rso_allowed = csr_roam_is_roam_offload_scan_enabled(mac);
+
+	cur_state = mlme_get_roam_state(mac->psoc, vdev_id);
+	switch (cur_state) {
+	case ROAM_INIT:
+	case ROAM_RSO_STOPPED:
+		break;
+
+	case ROAM_DEINIT:
+		status = csr_roam_switch_to_init(mac, vdev_id, reason);
+		if (QDF_IS_STATUS_ERROR(status))
+			return status;
+
+		break;
+	case ROAM_RSO_STARTED:
+	/*
+	 * Already the roaming module is initialized at fw,
+	 * nothing to do here
+	 */
+	default:
+		return QDF_STATUS_SUCCESS;
+	}
+
+	if (!rso_allowed) {
+		sme_debug("ROAM: RSO disabled via INI");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	control_bitmap = mlme_get_operations_bitmap(mac->psoc, vdev_id);
+	if (control_bitmap) {
+		sme_debug("ROAM: RSO Disabled internaly: vdev[%d] bitmap[0x%x]",
+			  vdev_id, control_bitmap);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	/* TODO: Check if we can map the below flag to above bitmap */
+	sup_disabled_roaming = mlme_get_supplicant_disabled_roaming(mac->psoc,
+								    vdev_id);
+	if (sup_disabled_roaming) {
+		sme_debug("ROAM: RSO Disabled by Supplicant on vdev[%d]",
+			  vdev_id);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	status = csr_roam_offload_scan(mac, vdev_id, ROAM_SCAN_OFFLOAD_START,
+				       reason);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		sme_debug("ROAM: RSO start failed");
+		return status;
+	}
+	mlme_set_roam_state(mac->psoc, vdev_id, ROAM_RSO_STARTED);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+static QDF_STATUS
+csr_roam_switch_to_rso_stop(struct mac_context *mac, uint8_t vdev_id,
+			    uint8_t reason)
+{
+	enum roam_offload_state cur_state;
+	QDF_STATUS status;
+
+	cur_state = mlme_get_roam_state(mac->psoc, vdev_id);
+	switch (cur_state) {
+	case ROAM_RSO_STARTED:
+		status = csr_post_rso_stop(mac, vdev_id, reason);
+		if (QDF_IS_STATUS_ERROR(status)) {
+			sme_err("ROAM: Unable to switch to RSO STOP State");
+			return QDF_STATUS_E_FAILURE;
+		}
+		break;
+
+	case ROAM_DEINIT:
+	case ROAM_RSO_STOPPED:
+	case ROAM_INIT:
+	/*
+	 * Already the roaming module is initialized at fw,
+	 * nothing to do here
+	 */
+	default:
+		return QDF_STATUS_SUCCESS;
+	}
+	mlme_set_roam_state(mac->psoc, vdev_id, ROAM_RSO_STOPPED);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+static QDF_STATUS
+csr_roam_switch_to_deinit(struct mac_context *mac, uint8_t vdev_id,
+			  uint8_t reason)
+{
+	QDF_STATUS status;
+	enum roam_offload_state cur_state = mlme_get_roam_state(mac->psoc,
+								vdev_id);
+	switch (cur_state) {
+	case ROAM_RSO_STARTED:
+		csr_roam_switch_to_rso_stop(mac, vdev_id, reason);
+		break;
+	case ROAM_RSO_STOPPED:
+	case ROAM_INIT:
+		break;
+
+	case ROAM_DEINIT:
+	/*
+	 * Already the roaming module is de-initialized at fw,
+	 * do nothing here
+	 */
+	default:
+		return QDF_STATUS_SUCCESS;
+	}
+
+	status = csr_send_roam_offload_init_msg(mac, vdev_id, false);
+
+	if (QDF_IS_STATUS_ERROR(status))
+		return status;
+
+	mlme_set_roam_state(mac->psoc, vdev_id, ROAM_DEINIT);
+
+	if (reason != REASON_SUPPLICANT_INIT_ROAMING)
+		csr_enable_roaming_on_connected_sta(mac, vdev_id);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+static QDF_STATUS
+csr_handle_roam_state_change(struct mac_context *mac, uint8_t vdev_id,
+			     enum roam_offload_state requested_state,
+			     uint8_t reason)
+{
+	QDF_STATUS status = QDF_STATUS_E_INVAL;
+
+	if (requested_state != ROAM_DEINIT &&
+	    !csr_is_conn_state_connected_infra(mac, vdev_id)) {
+		sme_err("ROAM: roam state change requested in disconnected state");
+		return status;
+	}
+
+	switch (requested_state) {
+	case ROAM_DEINIT:
+		status = csr_roam_switch_to_deinit(mac, vdev_id,
+						   reason);
+		break;
+	case ROAM_INIT:
+		status = csr_roam_switch_to_init(mac, vdev_id,
+						 reason);
+		break;
+	case ROAM_RSO_STARTED:
+		status = csr_roam_switch_to_rso_start(mac, vdev_id,
+						      reason);
+		break;
+	case ROAM_RSO_STOPPED:
+		status = csr_roam_switch_to_rso_stop(mac, vdev_id,
+						     reason);
+		break;
+	default:
+		sme_debug("ROAM: Invalid roam state %d", requested_state);
+		break;
+	}
+
+	return status;
+}
+
+QDF_STATUS
+csr_post_roam_state_change(struct mac_context *mac, uint8_t vdev_id,
+			   enum roam_offload_state state, uint8_t reason)
+{
+	return csr_handle_roam_state_change(mac, vdev_id, state, reason);
+}
+
 /**
  * csr_roam_offload_scan() - populates roam offload scan request and sends to
  * WMA
@@ -21683,3 +21984,94 @@ QDF_STATUS csr_update_owe_info(struct mac_context *mac,
 
 	return status;
 }
+
+QDF_STATUS
+csr_send_roam_offload_init_msg(struct mac_context *mac, uint32_t vdev_id,
+			       bool enable)
+{
+	struct scheduler_msg message = {0};
+	QDF_STATUS status;
+	struct roam_init_params *params;
+
+	/* per contract must make a copy of the params when messaging */
+	params = qdf_mem_malloc(sizeof(*params));
+	if (!params)
+		return QDF_STATUS_E_NOMEM;
+
+	params->vdev_id = vdev_id;
+	params->enable = enable;
+
+	sme_debug("Post roam init to WMA for vdev %d", vdev_id);
+	message.bodyptr = params;
+	message.type = WMA_ROAM_INIT_PARAM;
+	status = scheduler_post_message(QDF_MODULE_ID_SME,
+					QDF_MODULE_ID_WMA,
+					QDF_MODULE_ID_WMA,
+					&message);
+
+	if (QDF_IS_STATUS_ERROR(status)) {
+		sme_err("ROAM: Failed to post ROAM_TRIGGERS msg");
+		qdf_mem_free(params);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+csr_roam_update_cfg(struct mac_context *mac, uint8_t vdev_id, uint8_t reason)
+{
+	if (!MLME_IS_ROAM_INITIALIZED(mac->psoc, vdev_id) &&
+	    reason != REASON_ROAM_SET_BLACKLIST_BSSID) {
+		sme_err("Update cfg received in roam uninitialized state");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	return csr_roam_offload_scan(mac, vdev_id, ROAM_SCAN_OFFLOAD_UPDATE_CFG,
+				     reason);
+}
+
+QDF_STATUS
+csr_enable_roaming_on_connected_sta(struct mac_context *mac, uint8_t vdev_id)
+{
+	uint8_t op_ch[MAX_NUMBER_OF_CONC_CONNECTIONS];
+	uint8_t vdev_id_list[MAX_NUMBER_OF_CONC_CONNECTIONS];
+	uint32_t sta_vdev_id = WLAN_INVALID_VDEV_ID;
+	struct csr_roam_session *session;
+	uint32_t count;
+	uint32_t idx;
+
+	sta_vdev_id = csr_get_roam_enabled_sta_sessionid(mac);
+	if (sta_vdev_id != WLAN_UMAC_VDEV_ID_MAX)
+		return QDF_STATUS_E_FAILURE;
+
+	count = policy_mgr_get_mode_specific_conn_info(mac->psoc, op_ch,
+						       vdev_id_list,
+						       PM_STA_MODE);
+
+	if (!count)
+		return QDF_STATUS_E_FAILURE;
+
+	/*
+	 * Loop through all connected STA vdevs and roaming will be enabled
+	 * on the STA that has a different vdev id from the one passed as
+	 * input and has non zero roam trigger value.
+	 */
+	for (idx = 0; idx < count; idx++) {
+		session = CSR_GET_SESSION(mac, vdev_id_list[idx]);
+		if (vdev_id_list[idx] != vdev_id &&
+		    mlme_get_roam_trigger_bitmap(mac->psoc,
+						 vdev_id_list[idx])) {
+			sta_vdev_id = vdev_id_list[idx];
+			break;
+		}
+	}
+
+	if (sta_vdev_id == WLAN_INVALID_VDEV_ID)
+		return QDF_STATUS_E_FAILURE;
+
+	sme_debug("ROAM: Enabling roaming on vdev[%d]", sta_vdev_id);
+
+	return csr_post_roam_state_change(mac, sta_vdev_id, ROAM_RSO_STARTED,
+					  REASON_CTX_INIT);
+}

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

@@ -726,7 +726,6 @@ struct roam_synch_frame_ind {
  * @vdev_set_key_wakelock: wakelock to protect vdev set key op with firmware
  * @vdev_set_key_runtime_wakelock: runtime pm wakelock for set key
  * @ch_freq: channel frequency
- * @roam_offload_enabled: is roam offload enable/disable
  * @roam_scan_stats_req: cached roam scan stats request
  *
  * It stores parameters per vdev in wma.
@@ -788,7 +787,6 @@ struct wma_txrx_node {
 	qdf_runtime_lock_t vdev_set_key_runtime_wakelock;
 	struct roam_synch_frame_ind roam_synch_frame_ind;
 	bool is_waiting_for_key;
-	bool roam_offload_enabled;
 	uint32_t ch_freq;
 	struct sir_roam_scan_stats *roam_scan_stats_req;
 };

+ 9 - 0
core/wma/inc/wma_api.h

@@ -748,4 +748,13 @@ int wma_wlm_stats_req(int vdev_id, uint32_t bitmask, uint32_t max_size,
 int wma_wlm_stats_rsp(void *wma_ctx, uint8_t *event, uint32_t len);
 #endif /* FEATURE_WLM_STATS */
 
+/**
+ * wma_update_roam_offload_flag() -  update roam offload flag to fw
+ * @wma:     wma handle
+ * @params: Roaming enable/disable params
+ *
+ * Return: none
+ */
+void wma_update_roam_offload_flag(void *handle,
+				  struct roam_init_params *params);
 #endif /* WMA_API_H */

+ 2 - 0
core/wma/inc/wma_types.h

@@ -453,6 +453,8 @@
 #endif
 #define WMA_SET_ROAM_TRIGGERS                SIR_HAL_SET_ROAM_TRIGGERS
 
+#define WMA_ROAM_INIT_PARAM                  SIR_HAL_INIT_ROAM_OFFLOAD_PARAM
+
 /* Bit 6 will be used to control BD rate for Management frames */
 #define HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME 0x40
 

+ 4 - 0
core/wma/src/wma_main.c

@@ -9117,6 +9117,10 @@ static QDF_STATUS wma_mc_process_msg(struct scheduler_msg *msg)
 		wma_set_roam_triggers(wma_handle, msg->bodyptr);
 		qdf_mem_free(msg->bodyptr);
 		break;
+	case WMA_ROAM_INIT_PARAM:
+		wma_update_roam_offload_flag(wma_handle, msg->bodyptr);
+		qdf_mem_free(msg->bodyptr);
+		break;
 	default:
 		WMA_LOGD("Unhandled WMA message of type %d", msg->type);
 		if (msg->bodyptr)

+ 0 - 8
core/wma/src/wma_scan_roam.c

@@ -1727,14 +1727,6 @@ QDF_STATUS wma_process_roaming_config(tp_wma_handle wma_handle,
 		return QDF_STATUS_E_FAILURE;
 	}
 
-	if (!wma_handle->interfaces[roam_req->sessionId].roam_offload_enabled) {
-		/* roam scan offload is not enabled in firmware.
-		 * Cannot initialize it in the middle of connection.
-		 */
-		qdf_mem_zero(roam_req, sizeof(*roam_req));
-		qdf_mem_free(roam_req);
-		return QDF_STATUS_E_PERM;
-	}
 	WMA_LOGD("%s: RSO Command:%d, reason:%d session ID %d en %d", __func__,
 		 roam_req->Command, roam_req->reason, roam_req->sessionId,
 		 roam_req->RoamScanOffloadEnabled);

+ 15 - 63
core/wma/src/wma_utils.c

@@ -3618,86 +3618,40 @@ static void wma_set_roam_offload_flag(tp_wma_handle wma, uint8_t vdev_id,
 			flag |= WMI_VDEV_PARAM_SKIP_ROAM_EAPOL_4WAY_HANDSHAKE;
 	}
 
-	WMA_LOGD("%s: vdev_id:%d, is_set:%d, flag:%d, roam_offload_enabled:%d",
-		 __func__, vdev_id, is_set, flag,
-		  wma->interfaces[vdev_id].roam_offload_enabled);
+	WMA_LOGD("%s: vdev_id:%d, is_set:%d, flag:%d",
+		 __func__, vdev_id, is_set, flag);
 
 	status = wma_vdev_set_param(wma->wmi_handle, vdev_id,
 				    WMI_VDEV_PARAM_ROAM_FW_OFFLOAD, flag);
 	if (QDF_IS_STATUS_ERROR(status))
 		WMA_LOGE("Failed to set WMI_VDEV_PARAM_ROAM_FW_OFFLOAD");
-	else
-		wma->interfaces[vdev_id].roam_offload_enabled = is_set;
 }
 
-/**
- * wma_update_roam_offload_flag() -  update roam offload flag to fw
- * @wma:     wma handle
- * @vdev_id: vdev id
- * @is_connected: connected or disconnected
- *
- * Return: none
- */
-static void wma_update_roam_offload_flag(tp_wma_handle wma, uint8_t vdev_id,
-					 bool is_connected)
+void wma_update_roam_offload_flag(void *handle,
+				  struct roam_init_params *params)
 {
+	tp_wma_handle wma = handle;
 	struct wma_txrx_node *iface;
-	uint8_t id;
-	uint8_t roam_offload_vdev_id = WMA_INVALID_VDEV_ID;
-	uint32_t list[MAX_NUMBER_OF_CONC_CONNECTIONS];
-	uint8_t count;
 
 	WMA_LOGD("%s: vdev_id:%d, is_connected:%d", __func__,
-		 vdev_id, is_connected);
+		 params->vdev_id, params->enable);
 
-	iface = &wma->interfaces[vdev_id];
+	if (!wma_is_vdev_valid(params->vdev_id)) {
+		WMA_LOGE("%s: vdev_id: %d is not active", __func__,
+			 params->vdev_id);
+		return;
+	}
+
+	iface = &wma->interfaces[params->vdev_id];
 
 	if ((iface->type != WMI_VDEV_TYPE_STA) ||
 	    (iface->sub_type != 0)) {
 		WMA_LOGE("%s: this isn't a STA: %d",
-			 __func__, vdev_id);
-		return;
-	}
-
-	if (iface->roaming_in_progress || iface->roam_synch_in_progress) {
-		WMA_LOGE("%s: roaming in progress: %d",
-			 __func__, vdev_id);
+			 __func__, params->vdev_id);
 		return;
 	}
 
-	for (id = 0; id < wma->max_bssid; id++) {
-		if (wma->interfaces[id].roam_offload_enabled)
-			roam_offload_vdev_id = id;
-	}
-
-	/*
-	 * If sta connected, and no connected sta interface exist, then set
-	 * set roam offload flag to this sta interface
-	 */
-	if (is_connected && (roam_offload_vdev_id == WMA_INVALID_VDEV_ID))
-		wma_set_roam_offload_flag(wma, vdev_id, true);
-
-	if (!is_connected && roam_offload_vdev_id == vdev_id) {
-		/* If sta disconnected and roam offload enaled on this
-		 * interface, then clear roam offload flag
-		 */
-		wma_set_roam_offload_flag(wma, vdev_id, false);
-
-		count = policy_mgr_mode_specific_connection_count(
-				wma->psoc, PM_STA_MODE, list);
-		WMA_LOGD("%s: valid sta count:%d", __func__, count);
-		/*
-		 * If there is multi sta connection before this disconnection,
-		 * then set roam offload flag to other connected sta inferface.
-		 */
-		if (count > 1) {
-			for (id = 0; id < count; id++) {
-				if (list[id] != vdev_id)
-					wma_set_roam_offload_flag(wma, list[id],
-								  true);
-			}
-		}
-	}
+	wma_set_roam_offload_flag(wma, params->vdev_id, params->enable);
 }
 
 QDF_STATUS wma_send_vdev_down_to_fw(t_wma_handle *wma, uint8_t vdev_id)
@@ -3717,7 +3671,6 @@ QDF_STATUS wma_send_vdev_down_to_fw(t_wma_handle *wma, uint8_t vdev_id)
 		return status;
 	}
 
-	wma_update_roam_offload_flag(wma, vdev_id, false);
 	wma->interfaces[vdev_id].roaming_in_progress = false;
 
 	status = vdev_mgr_down_send(vdev_mlme);
@@ -3995,7 +3948,6 @@ QDF_STATUS wma_sta_vdev_up_send(struct vdev_mlme_obj *vdev_mlme,
 	iface = &wma->interfaces[vdev_id];
 	vdev_mlme->proto.sta.assoc_id = iface->aid;
 
-	wma_update_roam_offload_flag(wma, vdev_id, true);
 	status = vdev_mgr_up_send(vdev_mlme);
 
 	if (QDF_IS_STATUS_ERROR(status)) {