Browse Source

qcacld-3.0: Move rso related process to connection manager [PART 1]

Add macro ROAM_OFFLOAD_V1 for new code and implement below functions
for connection manager roam part:

csr_handle_roam_state_change() roam offload state related handler.
Filling WMI_ROAM_SCAN_RSSI_THRESHOLD cmd parameters related process.

Change-Id: I0351155ca5a3d68ade6568c7527c5708582ccf1a
CRs-Fixed: 2730826
Huashan Qu 4 years ago
parent
commit
7277418aa5
23 changed files with 1646 additions and 60 deletions
  1. 6 0
      Kbuild
  2. 17 0
      components/cmn_services/policy_mgr/inc/wlan_policy_mgr_api.h
  3. 32 0
      components/cmn_services/policy_mgr/src/wlan_policy_mgr_get_set_utils.c
  4. 10 0
      components/mlme/dispatcher/inc/wlan_mlme_api.h
  5. 17 0
      components/mlme/dispatcher/src/wlan_mlme_api.c
  6. 167 1
      components/target_if/connection_mgr/src/target_if_cm_roam_offload.c
  7. 447 0
      components/umac/mlme/connection_mgr/core/src/wlan_cm_roam_offload.c
  8. 63 0
      components/umac/mlme/connection_mgr/core/src/wlan_cm_roam_offload.h
  9. 105 0
      components/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_roam_api.h
  10. 144 0
      components/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_roam_public_srtuct.h
  11. 26 0
      components/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_roam_ucfg_api.h
  12. 16 0
      components/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_tgt_if_tx_api.h
  13. 67 0
      components/umac/mlme/connection_mgr/dispatcher/src/wlan_cm_roam_api.c
  14. 24 0
      components/umac/mlme/connection_mgr/dispatcher/src/wlan_cm_roam_ucfg_api.c
  15. 32 0
      components/umac/mlme/connection_mgr/dispatcher/src/wlan_cm_tgt_if_tx_api.c
  16. 17 0
      components/wmi/inc/wmi_unified_roam_api.h
  17. 2 0
      components/wmi/inc/wmi_unified_roam_param.h
  18. 13 0
      components/wmi/src/wmi_unified_roam_api.c
  19. 137 0
      components/wmi/src/wmi_unified_roam_tlv.c
  20. 3 0
      configs/default_defconfig
  21. 0 59
      core/sme/inc/csr_neighbor_roam.h
  22. 292 0
      core/sme/src/csr/csr_api_roam.c
  23. 9 0
      core/wma/src/wma_scan_roam.c

+ 6 - 0
Kbuild

@@ -1213,8 +1213,13 @@ MLME_INC += $(CM_INC)
 
 CM_ROAM_OBJS :=    $(CM_DIR)/dispatcher/src/wlan_cm_tgt_if_tx_api.o \
 			$(CM_DIR)/dispatcher/src/wlan_cm_roam_api.o \
+			$(CM_DIR)/dispatcher/src/wlan_cm_roam_ucfg_api.o \
 			$(CM_TGT_IF_DIR)/src/target_if_cm_roam_offload.o
 
+ifeq ($(CONFIG_CM_ROAM_OFFLOAD), y)
+CM_ROAM_OBJS += $(CM_DIR)/core/src/wlan_cm_roam_offload.o
+endif
+
 MLME_OBJS += $(CM_ROAM_OBJS)
 
 ####### BLACKLIST_MGR ########
@@ -2534,6 +2539,7 @@ cppflags-$(CONFIG_FEATURE_MOTION_DETECTION) += -DWLAN_FEATURE_MOTION_DETECTION
 cppflags-$(CONFIG_WLAN_FW_OFFLOAD) += -DWLAN_FW_OFFLOAD
 cppflags-$(CONFIG_WLAN_FEATURE_ELNA) += -DWLAN_FEATURE_ELNA
 cppflags-$(CONFIG_FEATURE_COEX) += -DFEATURE_COEX
+cppflags-$(CONFIG_CM_ROAM_OFFLOAD) += -DROAM_OFFLOAD_V1
 
 cppflags-$(CONFIG_PLD_IPCI_ICNSS_FLAG) += -DCONFIG_PLD_IPCI_ICNSS
 cppflags-$(CONFIG_PLD_SDIO_CNSS_FLAG) += -DCONFIG_PLD_SDIO_CNSS

+ 17 - 0
components/cmn_services/policy_mgr/inc/wlan_policy_mgr_api.h

@@ -3516,4 +3516,21 @@ bool policy_mgr_is_restart_sap_required(struct wlan_objmgr_psoc *psoc,
 					qdf_freq_t freq,
 					tQDF_MCC_TO_SCC_SWITCH_MODE scc_mode);
 
+/**
+ * policy_mgr_get_roam_enabled_sta_session_id() - get the session id of the sta
+ * on which roaming is enabled.
+ * @psoc: pointer to psoc object
+ * @vdev_id: vdev id of the requestor
+ *
+ * The function checks if any sta(other than the provided vdev_id) 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
+ * WLAN_UMAC_VDEV_ID_MAX.
+ *
+ * Return: session id of STA on which roaming is enabled
+ */
+uint8_t policy_mgr_get_roam_enabled_sta_session_id(
+						struct wlan_objmgr_psoc *psoc,
+						uint8_t vdev_id);
+
 #endif /* __WLAN_POLICY_MGR_API_H */

+ 32 - 0
components/cmn_services/policy_mgr/src/wlan_policy_mgr_get_set_utils.c

@@ -37,6 +37,7 @@
 #include "wlan_reg_services_api.h"
 #include "wlan_cm_roam_public_srtuct.h"
 #include "csr_neighbor_roam.h"
+#include "wlan_mlme_main.h"
 
 /* invalid channel id. */
 #define INVALID_CHANNEL_ID 0
@@ -4397,3 +4398,34 @@ bool policy_mgr_is_restart_sap_required(struct wlan_objmgr_psoc *psoc,
 	return restart_required;
 }
 
+uint8_t policy_mgr_get_roam_enabled_sta_session_id(
+					struct wlan_objmgr_psoc *psoc,
+					uint8_t vdev_id)
+{
+	uint32_t list[MAX_NUMBER_OF_CONC_CONNECTIONS];
+	uint32_t index, count;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return false;
+	}
+
+	count = policy_mgr_mode_specific_connection_count(
+		psoc, PM_STA_MODE, list);
+	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
+
+	for (index = 0; index < count; index++) {
+		if (vdev_id == pm_conc_connection_list[list[index]].vdev_id)
+			continue;
+		if (MLME_IS_ROAM_INITIALIZED(
+			psoc, pm_conc_connection_list[list[index]].vdev_id)) {
+			qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+			return pm_conc_connection_list[list[index]].vdev_id;
+		}
+	}
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+
+	return WLAN_UMAC_VDEV_ID_MAX;
+}

+ 10 - 0
components/mlme/dispatcher/inc/wlan_mlme_api.h

@@ -2643,4 +2643,14 @@ mlme_store_fw_scan_channels(struct wlan_objmgr_psoc *psoc,
 QDF_STATUS mlme_get_fw_scan_channels(struct wlan_objmgr_psoc *psoc,
 				     uint32_t *freq_list,
 				     uint8_t *saved_num_chan);
+/**
+ * wlan_mlme_get_roam_scan_offload_enabled() - Roam scan offload enable or not
+ * @psoc: pointer to psoc object
+ * @val:  Pointer to the value which will be filled for the caller
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS
+wlan_mlme_get_roam_scan_offload_enabled(struct wlan_objmgr_psoc *psoc,
+					bool *val);
 #endif /* _WLAN_MLME_API_H_ */

+ 17 - 0
components/mlme/dispatcher/src/wlan_mlme_api.c

@@ -4030,3 +4030,20 @@ wlan_mlme_get_dual_sta_roaming_enabled(struct wlan_objmgr_psoc *psoc)
 	return dual_sta_roaming_enabled;
 }
 #endif
+
+QDF_STATUS
+wlan_mlme_get_roam_scan_offload_enabled(struct wlan_objmgr_psoc *psoc,
+					bool *val)
+{
+	struct wlan_mlme_psoc_ext_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_ext_obj(psoc);
+	if (!mlme_obj) {
+		*val = cfg_default(CFG_LFR_ROAM_SCAN_OFFLOAD_ENABLED);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	*val = mlme_obj->cfg.lfr.roam_scan_offload_enabled;
+
+	return QDF_STATUS_SUCCESS;
+}

+ 167 - 1
components/target_if/connection_mgr/src/target_if_cm_roam_offload.c

@@ -24,7 +24,7 @@
 #include "wmi_unified_sta_api.h"
 #include "wlan_mlme_dbg.h"
 
-#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+#if defined(WLAN_FEATURE_ROAM_OFFLOAD) || defined(ROAM_OFFLOAD_V1)
 static struct wmi_unified
 *target_if_cm_roam_get_wmi_handle_from_vdev(struct wlan_objmgr_vdev *vdev)
 {
@@ -45,7 +45,9 @@ static struct wmi_unified
 
 	return wmi_handle;
 }
+#endif
 
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
 /**
  * target_if_cm_roam_send_vdev_set_pcl_cmd  - Send set vdev pcl
  * command to wmi.
@@ -82,6 +84,169 @@ target_if_cm_roam_register_lfr3_ops(struct wlan_cm_roam_tx_ops *tx_ops)
 {}
 #endif
 
+#ifdef ROAM_OFFLOAD_V1
+/**
+ * target_if_cm_roam_scan_offload_rssi_thresh() - Send roam scan rssi threshold
+ * commands to wmi
+ * @wmi_handle: wmi handle
+ * @req: roam scan rssi threshold related parameters
+ *
+ * This function fills some parameters @req and send down roam scan rssi
+ * threshold command to wmi
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS
+target_if_cm_roam_scan_offload_rssi_thresh(
+				wmi_unified_t wmi_handle,
+				struct wlan_roam_offload_scan_rssi_params *req)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	bool db2dbm_enabled;
+
+	db2dbm_enabled = wmi_service_enabled(wmi_handle,
+					     wmi_service_hw_db2dbm_support);
+	if (!db2dbm_enabled) {
+		req->rssi_thresh -= NOISE_FLOOR_DBM_DEFAULT;
+		req->rssi_thresh &= 0x000000ff;
+		req->hi_rssi_scan_rssi_ub -= NOISE_FLOOR_DBM_DEFAULT;
+		req->bg_scan_bad_rssi_thresh -= NOISE_FLOOR_DBM_DEFAULT;
+		req->good_rssi_threshold -= NOISE_FLOOR_DBM_DEFAULT;
+		req->good_rssi_threshold &= 0x000000ff;
+	}
+
+	req->hi_rssi_scan_rssi_ub &= 0x000000ff;
+	/*
+	 * The current Noise floor in firmware is -96dBm. Penalty/Boost
+	 * threshold is applied on a weaker signal to make it even more weaker.
+	 * So, there is a chance that the user may configure a very low
+	 * Penalty/Boost threshold beyond the noise floor. If that is the case,
+	 * then suppress the penalty/boost threshold to the noise floor.
+	 */
+	if (req->raise_rssi_thresh_5g < NOISE_FLOOR_DBM_DEFAULT) {
+		if (db2dbm_enabled) {
+			req->penalty_threshold_5g = RSSI_MIN_VALUE;
+			req->boost_threshold_5g = RSSI_MAX_VALUE;
+		} else {
+			req->penalty_threshold_5g = 0;
+		}
+	} else {
+		if (db2dbm_enabled) {
+			req->boost_threshold_5g = req->raise_rssi_thresh_5g;
+		} else {
+			req->boost_threshold_5g =
+				(req->raise_rssi_thresh_5g -
+					NOISE_FLOOR_DBM_DEFAULT) & 0x000000ff;
+		}
+	}
+
+	if (req->drop_rssi_thresh_5g < NOISE_FLOOR_DBM_DEFAULT) {
+		if (db2dbm_enabled)
+			req->penalty_threshold_5g = RSSI_MIN_VALUE;
+		else
+			req->penalty_threshold_5g = 0;
+	} else {
+		if (db2dbm_enabled) {
+			req->penalty_threshold_5g = req->drop_rssi_thresh_5g;
+		} else {
+			req->penalty_threshold_5g =
+				(req->drop_rssi_thresh_5g -
+					NOISE_FLOOR_DBM_DEFAULT) & 0x000000ff;
+		}
+	}
+
+	if (req->early_stop_scan_enable) {
+		if (!db2dbm_enabled) {
+			req->roam_earlystop_thres_min -=
+						NOISE_FLOOR_DBM_DEFAULT;
+			req->roam_earlystop_thres_max -=
+						NOISE_FLOOR_DBM_DEFAULT;
+		}
+	} else {
+		if (db2dbm_enabled) {
+			req->roam_earlystop_thres_min = RSSI_MIN_VALUE;
+			req->roam_earlystop_thres_max = RSSI_MIN_VALUE;
+		} else {
+			req->roam_earlystop_thres_min = 0;
+			req->roam_earlystop_thres_max = 0;
+		}
+	}
+
+	target_if_debug("good_rssi_threshold %d, early_stop_thresholds en=%d, min=%d, max=%d roam_scan_rssi_thresh=%d, roam_rssi_thresh_diff=%d",
+			req->good_rssi_threshold, req->early_stop_scan_enable,
+			req->roam_earlystop_thres_min,
+			req->roam_earlystop_thres_max, req->rssi_thresh,
+			req->rssi_thresh_diff);
+	target_if_debug("hirssi max cnt %d, delta %d, hirssi upper bound %d dense rssi thresh offset %d, dense min aps cnt %d, traffic_threshold %d dense_status=%d",
+			req->hi_rssi_scan_max_count,
+			req->hi_rssi_scan_rssi_delta,
+			req->hi_rssi_scan_rssi_ub,
+			req->dense_rssi_thresh_offset,
+			req->dense_min_aps_cnt,
+			req->traffic_threshold,
+			req->initial_dense_status);
+	target_if_debug("BG Scan Bad RSSI:%d, bitmap:0x%x Offset for 2G to 5G Roam:%d",
+			req->bg_scan_bad_rssi_thresh,
+			req->bg_scan_client_bitmap,
+			req->roam_bad_rssi_thresh_offset_2g);
+
+	status = wmi_unified_roam_scan_offload_rssi_thresh_cmd(wmi_handle, req);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		target_if_err("roam_scan_offload_rssi_thresh_cmd failed %d",
+			      status);
+		return status;
+	}
+
+	return status;
+}
+
+/**
+ * target_if_cm_roam_send_roam_start() - Send roam start related commands
+ * to wmi
+ * @vdev: vdev object
+ * @req: roam start config parameters
+ *
+ * This function is used to Send roam start related commands to wmi
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS
+target_if_cm_roam_send_roam_start(struct wlan_objmgr_vdev *vdev,
+				  struct wlan_roam_start_config *req)
+{
+	wmi_unified_t wmi_handle;
+
+	wmi_handle = target_if_cm_roam_get_wmi_handle_from_vdev(vdev);
+	if (!wmi_handle)
+		return QDF_STATUS_E_FAILURE;
+
+	target_if_cm_roam_scan_offload_rssi_thresh(wmi_handle,
+						   &req->rssi_params);
+	/* add other wmi commands */
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * target_if_cm_roam_register_rso_req_ops() - Register rso req tx ops fucntions
+ * @tx_ops: tx ops
+ *
+ * This function is used to register rso req tx ops fucntions
+ *
+ * Return: none
+ */
+static void
+target_if_cm_roam_register_rso_req_ops(struct wlan_cm_roam_tx_ops *tx_ops)
+{
+	tx_ops->send_roam_start_req = target_if_cm_roam_send_roam_start;
+}
+#else
+static void
+target_if_cm_roam_register_rso_req_ops(struct wlan_cm_roam_tx_ops *tx_ops)
+{
+}
+#endif
+
 QDF_STATUS target_if_cm_roam_register_tx_ops(struct wlan_cm_roam_tx_ops *tx_ops)
 {
 	if (!tx_ops) {
@@ -90,6 +255,7 @@ QDF_STATUS target_if_cm_roam_register_tx_ops(struct wlan_cm_roam_tx_ops *tx_ops)
 	}
 
 	target_if_cm_roam_register_lfr3_ops(tx_ops);
+	target_if_cm_roam_register_rso_req_ops(tx_ops);
 
 	return QDF_STATUS_SUCCESS;
 }

+ 447 - 0
components/umac/mlme/connection_mgr/core/src/wlan_cm_roam_offload.c

@@ -0,0 +1,447 @@
+/*
+ * Copyright (c) 2012-2020 The Linux Foundation. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * DOC: wlan_cm_roam_offload.c
+ *
+ * Implementation for the common roaming offload api interfaces.
+ */
+
+#include "wlan_cm_roam_offload.h"
+#include "wlan_cm_tgt_if_tx_api.h"
+#include "wlan_cm_roam_api.h"
+
+/**
+ * cm_roam_init_req() - roam init request handling
+ * @psoc: psoc pointer
+ * @vdev_id: vdev id
+ * @reason: reason for changing roam state for the requested vdev id
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS cm_roam_init_req(struct wlan_objmgr_psoc *psoc,
+				   uint8_t vdev_id,
+				   bool enable)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * cm_roam_start_req() - roam start request handling
+ * @psoc: psoc pointer
+ * @vdev_id: vdev id
+ * @reason: reason for changing roam state for the requested vdev id
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS cm_roam_start_req(struct wlan_objmgr_psoc *psoc,
+				    uint8_t vdev_id,
+				    uint8_t reason)
+{
+	struct wlan_roam_start_config *start_req;
+	QDF_STATUS status;
+
+	start_req = qdf_mem_malloc(sizeof(*start_req));
+	if (!start_req)
+		return QDF_STATUS_E_NOMEM;
+
+	/* fill from legacy through this API */
+	wlan_cm_roam_fill_start_req(psoc, vdev_id, start_req, reason);
+
+	status = wlan_cm_tgt_send_roam_start_req(psoc, vdev_id, start_req);
+	if (QDF_IS_STATUS_ERROR(status))
+		mlme_debug("fail to send roam start");
+
+	qdf_mem_free(start_req);
+
+	return status;
+}
+
+/**
+ * cm_roam_update_config_req() - roam update config request handling
+ * @psoc: psoc pointer
+ * @vdev_id: vdev id
+ * @reason: reason for changing roam state for the requested vdev id
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS cm_roam_update_config_req(struct wlan_objmgr_psoc *psoc,
+					    uint8_t vdev_id,
+					    uint8_t reason)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+/*
+ * similar to csr_roam_offload_scan, will be used from many legacy
+ * process directly, generate a new function wlan_cm_roam_send_rso_cmd
+ * for external usage.
+ */
+QDF_STATUS cm_roam_send_rso_cmd(struct wlan_objmgr_psoc *psoc,
+				uint8_t vdev_id,
+				uint8_t rso_command,
+				uint8_t reason)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+
+	status = wlan_cm_roam_cmd_allowed(psoc, vdev_id, rso_command, reason);
+
+	if (status == QDF_STATUS_E_NOSUPPORT)
+		return QDF_STATUS_SUCCESS;
+	if (QDF_IS_STATUS_ERROR(status)) {
+		mlme_debug("ROAM: not allowed");
+		return status;
+	}
+	if (rso_command == ROAM_SCAN_OFFLOAD_START)
+		status = cm_roam_start_req(psoc, vdev_id, reason);
+	else if (rso_command == ROAM_SCAN_OFFLOAD_UPDATE_CFG)
+		status = cm_roam_update_config_req(psoc, vdev_id, reason);
+//	else if (rso_command == ROAM_SCAN_OFFLOAD_RESTART)
+		/* RESTART API */
+//	else
+		/* ABORT SCAN API */
+
+	return status;
+}
+
+/**
+ * cm_roam_stop_req() - roam stop request handling
+ * @psoc: psoc pointer
+ * @vdev_id: vdev id
+ * @reason: reason for changing roam state for the requested vdev id
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS cm_roam_stop_req(struct wlan_objmgr_psoc *psoc,
+				   uint8_t vdev_id,
+				   uint8_t reason)
+{
+	/* do the filling as csr_post_rso_stop */
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * cm_roam_switch_to_rso_stop() - roam state handling for rso stop
+ * @pdev: pdev pointer
+ * @vdev_id: vdev id
+ * @reason: reason for changing roam state for the requested vdev id
+ *
+ * This function is used for WLAN_ROAM_RSO_STOPPED roam state handling
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS cm_roam_switch_to_rso_stop(struct wlan_objmgr_pdev *pdev,
+					     uint8_t vdev_id,
+					     uint8_t reason)
+{
+	enum roam_offload_state cur_state;
+	QDF_STATUS status;
+	struct wlan_objmgr_psoc *psoc = wlan_pdev_get_psoc(pdev);
+
+	cur_state = mlme_get_roam_state(psoc, vdev_id);
+	switch (cur_state) {
+	case WLAN_ROAM_RSO_ENABLED:
+		status = cm_roam_stop_req(psoc, vdev_id, reason);
+		if (QDF_IS_STATUS_ERROR(status)) {
+			mlme_err("ROAM: Unable to switch to RSO STOP State");
+			return QDF_STATUS_E_FAILURE;
+		}
+		break;
+
+	case WLAN_ROAM_DEINIT:
+	case WLAN_ROAM_RSO_STOPPED:
+	case WLAN_ROAM_INIT:
+	/*
+	 * Already the roaming module is initialized at fw,
+	 * nothing to do here
+	 */
+	default:
+		return QDF_STATUS_SUCCESS;
+	}
+	mlme_set_roam_state(psoc, vdev_id, WLAN_ROAM_RSO_STOPPED);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * cm_roam_switch_to_deinit() - roam state handling for roam deinit
+ * @pdev: pdev pointer
+ * @vdev_id: vdev id
+ * @reason: reason for changing roam state for the requested vdev id
+ *
+ * This function is used for WLAN_ROAM_DEINIT roam state handling
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS cm_roam_switch_to_deinit(struct wlan_objmgr_pdev *pdev,
+					   uint8_t vdev_id,
+					   uint8_t reason)
+{
+	QDF_STATUS status;
+	struct wlan_objmgr_psoc *psoc = wlan_pdev_get_psoc(pdev);
+	enum roam_offload_state cur_state = mlme_get_roam_state(psoc, vdev_id);
+
+	switch (cur_state) {
+	case WLAN_ROAM_RSO_ENABLED:
+		cm_roam_switch_to_rso_stop(pdev, vdev_id, reason);
+		break;
+	case WLAN_ROAM_RSO_STOPPED:
+	case WLAN_ROAM_INIT:
+		break;
+
+	case WLAN_ROAM_DEINIT:
+	/*
+	 * Already the roaming module is de-initialized at fw,
+	 * do nothing here
+	 */
+	default:
+		return QDF_STATUS_SUCCESS;
+	}
+
+	status = cm_roam_init_req(psoc, vdev_id, false);
+
+	if (QDF_IS_STATUS_ERROR(status))
+		return status;
+
+	mlme_set_roam_state(psoc, vdev_id, WLAN_ROAM_DEINIT);
+
+	if (reason != REASON_SUPPLICANT_INIT_ROAMING)
+		wlan_cm_enable_roaming_on_connected_sta(pdev, vdev_id);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * cm_roam_switch_to_init() - roam state handling for roam init
+ * @pdev: pdev pointer
+ * @vdev_id: vdev id
+ * @reason: reason for changing roam state for the requested vdev id
+ *
+ * This function is used for WLAN_ROAM_INIT roam state handling
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS cm_roam_switch_to_init(struct wlan_objmgr_pdev *pdev,
+					 uint8_t vdev_id,
+					 uint8_t reason)
+{
+	enum roam_offload_state cur_state;
+	uint8_t temp_vdev_id, roam_enabled_vdev_id;
+	uint32_t roaming_bitmap;
+	bool dual_sta_roam_active;
+	QDF_STATUS status;
+	struct wlan_objmgr_psoc *psoc = wlan_pdev_get_psoc(pdev);
+
+	dual_sta_roam_active =
+		wlan_mlme_get_dual_sta_roaming_enabled(psoc);
+
+	cur_state = mlme_get_roam_state(psoc, vdev_id);
+	switch (cur_state) {
+	case WLAN_ROAM_DEINIT:
+		roaming_bitmap = mlme_get_roam_trigger_bitmap(psoc, vdev_id);
+		if (!roaming_bitmap) {
+			mlme_info("ROAM: Cannot change to INIT state for vdev[%d]",
+				  vdev_id);
+			return QDF_STATUS_E_FAILURE;
+		}
+
+		if (dual_sta_roam_active)
+			break;
+		/*
+		 * Disable roaming on the enabled sta if supplicant wants to
+		 * enable roaming on this vdev id
+		 */
+		temp_vdev_id = policy_mgr_get_roam_enabled_sta_session_id(
+								psoc, vdev_id);
+		if (temp_vdev_id != WLAN_UMAC_VDEV_ID_MAX) {
+			/*
+			 * 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) {
+				mlme_info("ROAM: Roam module already initialized on vdev:[%d]",
+					  temp_vdev_id);
+				return QDF_STATUS_E_FAILURE;
+			}
+			cm_roam_state_change(pdev, temp_vdev_id,
+					     WLAN_ROAM_DEINIT, reason);
+		}
+		break;
+
+	case WLAN_ROAM_INIT:
+	case WLAN_ROAM_RSO_STOPPED:
+	case WLAN_ROAM_RSO_ENABLED:
+	/*
+	 * Already the roaming module is initialized at fw,
+	 * just return from here
+	 */
+	default:
+		return QDF_STATUS_SUCCESS;
+	}
+
+	status = cm_roam_init_req(psoc, vdev_id, true);
+
+	if (QDF_IS_STATUS_ERROR(status))
+		return status;
+
+	mlme_set_roam_state(psoc, vdev_id, WLAN_ROAM_INIT);
+
+	roam_enabled_vdev_id =
+		policy_mgr_get_roam_enabled_sta_session_id(psoc, vdev_id);
+
+	/* Send PDEV pcl command if only one STA is in connected state
+	 * If there is another STA connection exist, then set the
+	 * PCL type to vdev level
+	 */
+	if (roam_enabled_vdev_id != WLAN_UMAC_VDEV_ID_MAX &&
+	    dual_sta_roam_active)
+		wlan_cm_roam_activate_pcl_per_vdev(psoc, vdev_id, true);
+
+	/* Set PCL before sending RSO start */
+	policy_mgr_set_pcl_for_existing_combo(psoc, PM_STA_MODE, vdev_id);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * cm_roam_switch_to_rso_start() - roam state handling for rso started
+ * @pdev: pdev pointer
+ * @vdev_id: vdev id
+ * @reason: reason for changing roam state for the requested vdev id
+ *
+ * This function is used for WLAN_ROAM_RSO_ENABLED roam state handling
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS cm_roam_switch_to_rso_start(struct wlan_objmgr_pdev *pdev,
+					      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;
+	uint8_t rso_command = ROAM_SCAN_OFFLOAD_START;
+	struct wlan_objmgr_psoc *psoc = wlan_pdev_get_psoc(pdev);
+
+	wlan_mlme_get_roam_scan_offload_enabled(psoc, &rso_allowed);
+
+	cur_state = mlme_get_roam_state(psoc, vdev_id);
+	switch (cur_state) {
+	case WLAN_ROAM_INIT:
+	case WLAN_ROAM_RSO_STOPPED:
+		break;
+
+	case WLAN_ROAM_DEINIT:
+		status = cm_roam_switch_to_init(pdev, vdev_id, reason);
+		if (QDF_IS_STATUS_ERROR(status))
+			return status;
+
+		break;
+	case WLAN_ROAM_RSO_ENABLED:
+		/*
+		 * Send RSO update config if roaming already enabled
+		 */
+		rso_command = ROAM_SCAN_OFFLOAD_UPDATE_CFG;
+		break;
+	default:
+		return QDF_STATUS_SUCCESS;
+	}
+
+	if (!rso_allowed) {
+		mlme_debug("ROAM: RSO disabled via INI");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	control_bitmap = mlme_get_operations_bitmap(psoc, vdev_id);
+	if (control_bitmap) {
+		mlme_debug("ROAM: RSO Disabled internaly: vdev[%d] bitmap[0x%x]",
+			   vdev_id, control_bitmap);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	status = cm_roam_send_rso_cmd(psoc, vdev_id, rso_command, reason);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		mlme_debug("ROAM: RSO start failed");
+		return status;
+	}
+	mlme_set_roam_state(psoc, vdev_id, WLAN_ROAM_RSO_ENABLED);
+
+	/*
+	 * If supplicant disabled roaming, driver does not send
+	 * RSO cmd to fw. This causes roam invoke to fail in FW
+	 * since RSO start never happened at least once to
+	 * configure roaming engine in FW.
+	 */
+	sup_disabled_roaming = mlme_get_supplicant_disabled_roaming(psoc,
+								    vdev_id);
+	if (!sup_disabled_roaming)
+		return QDF_STATUS_SUCCESS;
+
+	mlme_debug("ROAM: RSO disabled by Supplicant on vdev[%d]", vdev_id);
+	return cm_roam_state_change(pdev, vdev_id, WLAN_ROAM_RSO_STOPPED,
+				    REASON_SUPPLICANT_DISABLED_ROAMING);
+}
+
+QDF_STATUS cm_roam_state_change(struct wlan_objmgr_pdev *pdev,
+				uint8_t vdev_id,
+				enum roam_offload_state requested_state,
+				uint8_t reason)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	struct wlan_objmgr_vdev *vdev;
+	bool is_up;
+
+	vdev = wlan_objmgr_get_vdev_by_id_from_pdev(pdev, vdev_id,
+						    WLAN_MLME_NB_ID);
+	if (!vdev)
+		return status;
+
+	is_up = QDF_IS_STATUS_SUCCESS(wlan_vdev_is_up(vdev));
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_NB_ID);
+
+	if (requested_state != WLAN_ROAM_DEINIT && !is_up) {
+		mlme_debug("ROAM: roam state change requested in disconnected state");
+		return status;
+	}
+
+	switch (requested_state) {
+	case WLAN_ROAM_DEINIT:
+		status = cm_roam_switch_to_deinit(pdev, vdev_id, reason);
+		break;
+	case WLAN_ROAM_INIT:
+		status = cm_roam_switch_to_init(pdev, vdev_id, reason);
+		break;
+	case WLAN_ROAM_RSO_ENABLED:
+		status = cm_roam_switch_to_rso_start(pdev, vdev_id, reason);
+		break;
+	case WLAN_ROAM_RSO_STOPPED:
+		status = cm_roam_switch_to_rso_stop(pdev, vdev_id, reason);
+		break;
+	default:
+		mlme_debug("ROAM: Invalid roam state %d", requested_state);
+		break;
+	}
+
+	return status;
+}

+ 63 - 0
components/umac/mlme/connection_mgr/core/src/wlan_cm_roam_offload.h

@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2012-2020 The Linux Foundation. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * DOC: wlan_cm_roam_offload.h
+ *
+ * Implementation for the common roaming offload api interfaces.
+ */
+
+#ifndef _WLAN_CM_ROAM_OFFLOAD_H_
+#define _WLAN_CM_ROAM_OFFLOAD_H_
+
+#include "wlan_cm_roam_public_srtuct.h"
+
+#if defined(WLAN_FEATURE_HOST_ROAM) || defined(WLAN_FEATURE_ROAM_OFFLOAD)
+/**
+ * cm_roam_send_rso_cmd() - Send rso command
+ * @psoc: psoc pointer
+ * @vdev_id: vdev id
+ * @rso_command: roam scan offload command
+ * @reason: reason for changing roam state for the requested vdev id
+ *
+ * This function is used to send rso command
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS cm_roam_send_rso_cmd(struct wlan_objmgr_psoc *psoc,
+				uint8_t vdev_id,
+				uint8_t rso_command,
+				uint8_t reason);
+
+/**
+ * cm_roam_state_change() - Post roam state change to roam state machine
+ * @pdev: pdev pointer
+ * @vdev_id: vdev id
+ * @requested_state: roam state to be set
+ * @reason: reason for changing roam state for the requested vdev id
+ *
+ * This function posts roam state change to roam state machine handling
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS cm_roam_state_change(struct wlan_objmgr_pdev *pdev,
+				uint8_t vdev_id,
+				enum roam_offload_state requested_state,
+				uint8_t reason);
+#endif
+#endif

+ 105 - 0
components/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_roam_api.h

@@ -31,6 +31,111 @@
 /* Default value of reason code */
 #define DISABLE_VENDOR_BTM_CONFIG 2
 
+#ifdef ROAM_OFFLOAD_V1
+#if defined(WLAN_FEATURE_HOST_ROAM) || defined(WLAN_FEATURE_ROAM_OFFLOAD)
+/**
+ * wlan_cm_enable_roaming_on_connected_sta() - Enable roaming on other connected
+ * sta vdev
+ * @pdev: pointer to pdev object
+ * @vdev_id: vdev id on which roaming should not be enabled
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS
+wlan_cm_enable_roaming_on_connected_sta(struct wlan_objmgr_pdev *pdev,
+					uint8_t vdev_id);
+
+/**
+ * wlan_cm_start_roaming() - start roaming
+ * @pdev: pdev pointer
+ * @vdev_id: vdev id
+ * @reason: reason to roam
+ *
+ * This function gets called to start roaming
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS
+wlan_cm_start_roaming(struct wlan_objmgr_pdev *pdev,
+		      uint8_t vdev_id,
+		      uint8_t reason);
+
+/**
+ * wlan_cm_roam_cmd_allowed() - check roam cmd is allowed or not
+ * @psoc: pointer to psoc object
+ * @vdev_id: vdev id
+ * @rso_command: roam scan offload command
+ * @reason: reason to roam
+ *
+ * This function gets called to check roam cmd is allowed or not
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS
+wlan_cm_roam_cmd_allowed(struct wlan_objmgr_psoc *psoc,
+			 uint8_t vdev_id,
+			 uint8_t rso_command,
+			 uint8_t reason);
+
+/**
+ * wlan_cm_roam_fill_start_req() - fill start request structure content
+ * @psoc: pointer to psoc object
+ * @vdev_id: vdev id
+ * @req: roam start config pointer
+ * @reason: reason to roam
+ *
+ * This function gets called to fill start request structure content
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS
+wlan_cm_roam_fill_start_req(struct wlan_objmgr_psoc *psoc,
+			    uint8_t vdev_id,
+			    struct wlan_roam_start_config *req,
+			    uint8_t reason);
+
+/**
+ * wlan_cm_roam_send_rso_cmd() - Send rso command
+ * @psoc: psoc pointer
+ * @vdev_id: vdev id
+ * @rso_command: roam scan offload command
+ * @reason: reason for changing roam state for the requested vdev id
+ *
+ * This function is used to send rso command
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wlan_cm_roam_send_rso_cmd(struct wlan_objmgr_psoc *psoc,
+				     uint8_t vdev_id,
+				     uint8_t rso_command,
+				     uint8_t reason);
+#else
+static inline QDF_STATUS
+wlan_cm_enable_roaming_on_connected_sta(struct wlan_objmgr_pdev *pdev,
+					uint8_t vdev_id)
+{
+	return QDF_STATUS_E_NOSUPPORT;
+}
+
+static inline QDF_STATUS
+wlan_cm_start_roaming(struct wlan_objmgr_pdev *pdev,
+		      uint8_t vdev_id,
+		      uint8_t reason)
+{
+	return QDF_STATUS_E_NOSUPPORT;
+}
+
+static inline QDF_STATUS
+wlan_cm_roam_send_rso_cmd(struct wlan_objmgr_psoc *psoc,
+			  uint8_t vdev_id,
+			  uint8_t rso_command,
+			  uint8_t reason);
+{
+	return QDF_STATUS_E_NOSUPPORT;
+}
+#endif
+#endif
+
 #ifdef WLAN_FEATURE_ROAM_OFFLOAD
 /**
  * wlan_cm_roam_extract_btm_response() - Extract BTM rsp stats

+ 144 - 0
components/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_roam_public_srtuct.h

@@ -26,6 +26,144 @@
 #include "wmi_unified_param.h"
 #include "wmi_unified_sta_param.h"
 
+#define ROAM_SCAN_OFFLOAD_START                     1
+#define ROAM_SCAN_OFFLOAD_STOP                      2
+#define ROAM_SCAN_OFFLOAD_RESTART                   3
+#define ROAM_SCAN_OFFLOAD_UPDATE_CFG                4
+#define ROAM_SCAN_OFFLOAD_ABORT_SCAN                5
+
+#define REASON_CONNECT                              1
+#define REASON_CHANNEL_LIST_CHANGED                 2
+#define REASON_LOOKUP_THRESH_CHANGED                3
+#define REASON_DISCONNECTED                         4
+#define REASON_RSSI_DIFF_CHANGED                    5
+#define REASON_ESE_INI_CFG_CHANGED                  6
+#define REASON_NEIGHBOR_SCAN_REFRESH_PERIOD_CHANGED 7
+#define REASON_VALID_CHANNEL_LIST_CHANGED           8
+#define REASON_FLUSH_CHANNEL_LIST                   9
+#define REASON_EMPTY_SCAN_REF_PERIOD_CHANGED        10
+#define REASON_PREAUTH_FAILED_FOR_ALL               11
+#define REASON_NO_CAND_FOUND_OR_NOT_ROAMING_NOW     12
+#define REASON_NPROBES_CHANGED                      13
+#define REASON_HOME_AWAY_TIME_CHANGED               14
+#define REASON_OS_REQUESTED_ROAMING_NOW             15
+#define REASON_SCAN_CH_TIME_CHANGED                 16
+#define REASON_SCAN_HOME_TIME_CHANGED               17
+#define REASON_OPPORTUNISTIC_THRESH_DIFF_CHANGED    18
+#define REASON_ROAM_RESCAN_RSSI_DIFF_CHANGED        19
+#define REASON_ROAM_BMISS_FIRST_BCNT_CHANGED        20
+#define REASON_ROAM_BMISS_FINAL_BCNT_CHANGED        21
+#define REASON_ROAM_BEACON_RSSI_WEIGHT_CHANGED      22
+#define REASON_ROAM_DFS_SCAN_MODE_CHANGED           23
+#define REASON_ROAM_ABORT_ROAM_SCAN                 24
+#define REASON_ROAM_EXT_SCAN_PARAMS_CHANGED         25
+#define REASON_ROAM_SET_SSID_ALLOWED                26
+#define REASON_ROAM_SET_FAVORED_BSSID               27
+#define REASON_ROAM_GOOD_RSSI_CHANGED               28
+#define REASON_ROAM_SET_BLACKLIST_BSSID             29
+#define REASON_ROAM_SCAN_HI_RSSI_MAXCOUNT_CHANGED   30
+#define REASON_ROAM_SCAN_HI_RSSI_DELTA_CHANGED      31
+#define REASON_ROAM_SCAN_HI_RSSI_DELAY_CHANGED      32
+#define REASON_ROAM_SCAN_HI_RSSI_UB_CHANGED         33
+#define REASON_CONNECT_IES_CHANGED                  34
+#define REASON_ROAM_SCAN_STA_ROAM_POLICY_CHANGED    35
+#define REASON_ROAM_SYNCH_FAILED                    36
+#define REASON_ROAM_PSK_PMK_CHANGED                 37
+#define REASON_ROAM_STOP_ALL                        38
+#define REASON_SUPPLICANT_DISABLED_ROAMING          39
+#define REASON_CTX_INIT                             40
+#define REASON_FILS_PARAMS_CHANGED                  41
+#define REASON_SME_ISSUED                           42
+#define REASON_DRIVER_ENABLED                       43
+#define REASON_ROAM_FULL_SCAN_PERIOD_CHANGED        44
+#define REASON_SCORING_CRITERIA_CHANGED             45
+#define REASON_SUPPLICANT_INIT_ROAMING              46
+#define REASON_SUPPLICANT_DE_INIT_ROAMING           47
+#define REASON_DRIVER_DISABLED                      48
+#define REASON_ROAM_CONTROL_CONFIG_CHANGED          49
+#define REASON_ROAM_CONTROL_CONFIG_ENABLED          50
+#define REASON_ROAM_CANDIDATE_FOUND                 51
+#define REASON_ROAM_HANDOFF_DONE                    52
+#define REASON_ROAM_ABORT                           53
+
+#ifdef ROAM_OFFLOAD_V1
+#define NOISE_FLOOR_DBM_DEFAULT          (-96)
+#define RSSI_MIN_VALUE                   (-128)
+#define RSSI_MAX_VALUE                   (127)
+
+/**
+ * struct wlan_roam_offload_scan_rssi_params - structure containing
+ *              parameters for roam offload scan based on RSSI
+ * @rssi_thresh: rssi threshold
+ * @rssi_thresh_diff: difference in rssi threshold
+ * @hi_rssi_scan_max_count: 5G scan max count
+ * @hi_rssi_scan_rssi_delta: 5G scan rssi change threshold value
+ * @hi_rssi_scan_rssi_ub: 5G scan upper bound
+ * @raise_rssi_thresh_5g: flag to determine penalty and boost thresholds
+ * @vdev_id: vdev id
+ * @penalty_threshold_5g: RSSI threshold below which 5GHz RSSI is penalized
+ * @boost_threshold_5g: RSSI threshold above which 5GHz RSSI is favored
+ * @raise_factor_5g: factor by which 5GHz RSSI is boosted
+ * @drop_factor_5g: factor by which 5GHz RSSI is penalized
+ * @max_raise_rssi_5g: maximum boost that can be applied to a 5GHz RSSI
+ * @max_drop_rssi_5g: maximum penalty that can be applied to a 5GHz RSSI
+ * @good_rssi_threshold: RSSI below which roam is kicked in by background
+ *                       scan although rssi is still good
+ * @early_stop_scan_enable: early stop scan enable
+ * @roam_earlystop_thres_min: Minimum RSSI threshold value for early stop,
+ *                            unit is dB above NF
+ * @roam_earlystop_thres_max: Maximum RSSI threshold value for early stop,
+ *                            unit is dB above NF
+ * @dense_rssi_thresh_offset: dense roam RSSI threshold difference
+ * @dense_min_aps_cnt: dense roam minimum APs
+ * @initial_dense_status: dense status detected by host
+ * @traffic_threshold: dense roam RSSI threshold
+ * @bg_scan_bad_rssi_thresh: Bad RSSI threshold to perform bg scan
+ * @roam_bad_rssi_thresh_offset_2g: Offset from Bad RSSI threshold for 2G
+ *                                  to 5G Roam
+ * @bg_scan_client_bitmap: Bitmap used to identify the client scans to snoop
+ */
+struct wlan_roam_offload_scan_rssi_params {
+	int8_t rssi_thresh;
+	uint8_t rssi_thresh_diff;
+	uint32_t hi_rssi_scan_max_count;
+	uint32_t hi_rssi_scan_rssi_delta;
+	int32_t hi_rssi_scan_rssi_ub;
+	int raise_rssi_thresh_5g;
+	int drop_rssi_thresh_5g;
+	uint8_t vdev_id;
+	uint32_t penalty_threshold_5g;
+	uint32_t boost_threshold_5g;
+	uint8_t raise_factor_5g;
+	uint8_t drop_factor_5g;
+	int max_raise_rssi_5g;
+	int max_drop_rssi_5g;
+	uint32_t good_rssi_threshold;
+	bool early_stop_scan_enable;
+	uint32_t roam_earlystop_thres_min;
+	uint32_t roam_earlystop_thres_max;
+	int dense_rssi_thresh_offset;
+	int dense_min_aps_cnt;
+	int initial_dense_status;
+	int traffic_threshold;
+	int32_t rssi_thresh_offset_5g;
+	int8_t bg_scan_bad_rssi_thresh;
+	uint8_t roam_bad_rssi_thresh_offset_2g;
+	uint32_t bg_scan_client_bitmap;
+};
+
+/**
+ * struct wlan_roam_start_config - structure containing parameters for
+ * roam start config
+ * @rssi_params: roam scan rssi threshold parameters
+ */
+struct wlan_roam_start_config {
+	struct wlan_roam_offload_scan_rssi_params rssi_params;
+	/* other wmi cmd structures */
+};
+
+#endif
+
 #if defined(WLAN_FEATURE_HOST_ROAM) || defined(WLAN_FEATURE_ROAM_OFFLOAD)
 /**
  * enum roam_offload_state - Roaming module state for each STA vdev.
@@ -121,10 +259,16 @@ struct set_pcl_req {
  * roaming related commands
  * @send_vdev_set_pcl_cmd: TX ops function pointer to send set vdev PCL
  * command
+ * @send_roam_start_req: TX ops function pointer to send roam start related
+ * commands
  */
 struct wlan_cm_roam_tx_ops {
 	QDF_STATUS (*send_vdev_set_pcl_cmd) (struct wlan_objmgr_vdev *vdev,
 					     struct set_pcl_req *req);
+#ifdef ROAM_OFFLOAD_V1
+	QDF_STATUS (*send_roam_start_req)(struct wlan_objmgr_vdev *vdev,
+					  struct wlan_roam_start_config *req);
+#endif
 };
 
 /**

+ 26 - 0
components/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_roam_ucfg_api.h

@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2020, The Linux Foundation. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * DOC: wlan_cm_roam_ucfg_api.h
+ *
+ * Implementation for roaming public ucfg API interfaces.
+ */
+
+#ifndef _WLAN_CM_ROAM_UCFG_API_H_
+#define _WLAN_CM_ROAM_UCFG_API_H_
+
+#endif

+ 16 - 0
components/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_tgt_if_tx_api.h

@@ -47,4 +47,20 @@ wlan_cm_roam_send_set_vdev_pcl(struct wlan_objmgr_psoc *psoc,
 	return QDF_STATUS_E_FAILURE;
 }
 #endif /* WLAN_FEATURE_ROAM_OFFLOAD */
+
+#ifdef ROAM_OFFLOAD_V1
+#if defined(WLAN_FEATURE_HOST_ROAM) || defined(WLAN_FEATURE_ROAM_OFFLOAD)
+/**
+ * wlan_cm_tgt_send_roam_start_req  - Send roam start command to firmware
+ * @psoc:    psoc pointer
+ * @vdev_id: vdev id
+ * @req: roam start config parameter
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wlan_cm_tgt_send_roam_start_req(struct wlan_objmgr_psoc *psoc,
+					   uint8_t vdev_id,
+					   struct wlan_roam_start_config *req);
+#endif
+#endif
 #endif /* CM_TGT_IF_TX_API_H__ */

+ 67 - 0
components/umac/mlme/connection_mgr/dispatcher/src/wlan_cm_roam_api.c

@@ -25,6 +25,73 @@
 #include "wlan_mlme_main.h"
 #include "wlan_policy_mgr_api.h"
 #include <wmi_unified_priv.h>
+#include "../../core/src/wlan_cm_roam_offload.h"
+
+#ifdef ROAM_OFFLOAD_V1
+#if defined(WLAN_FEATURE_HOST_ROAM) || defined(WLAN_FEATURE_ROAM_OFFLOAD)
+QDF_STATUS
+wlan_cm_enable_roaming_on_connected_sta(struct wlan_objmgr_pdev *pdev,
+					uint8_t vdev_id)
+{
+	uint32_t op_ch_freq_list[MAX_NUMBER_OF_CONC_CONNECTIONS];
+	uint8_t vdev_id_list[MAX_NUMBER_OF_CONC_CONNECTIONS];
+	uint32_t sta_vdev_id = WLAN_INVALID_VDEV_ID;
+	uint32_t count;
+	uint32_t idx;
+	struct wlan_objmgr_psoc *psoc = wlan_pdev_get_psoc(pdev);
+
+	sta_vdev_id = policy_mgr_get_roam_enabled_sta_session_id(psoc, vdev_id);
+	if (sta_vdev_id != WLAN_UMAC_VDEV_ID_MAX)
+		return QDF_STATUS_E_FAILURE;
+
+	count = policy_mgr_get_mode_specific_conn_info(psoc,
+						       op_ch_freq_list,
+						       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++) {
+		if (vdev_id_list[idx] != vdev_id &&
+		    mlme_get_roam_trigger_bitmap(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;
+
+	mlme_debug("ROAM: Enabling roaming on vdev[%d]", sta_vdev_id);
+
+	return cm_roam_state_change(pdev,
+				    sta_vdev_id,
+				    WLAN_ROAM_RSO_ENABLED,
+				    REASON_CTX_INIT);
+}
+
+QDF_STATUS wlan_cm_start_roaming(struct wlan_objmgr_pdev *pdev,
+				 uint8_t vdev_id, uint8_t reason)
+{
+	return cm_roam_state_change(pdev, vdev_id,
+				    WLAN_ROAM_RSO_ENABLED, reason);
+}
+
+QDF_STATUS wlan_cm_roam_send_rso_cmd(struct wlan_objmgr_psoc *psoc,
+				     uint8_t vdev_id,
+				     uint8_t rso_command,
+				     uint8_t reason)
+{
+	return cm_roam_send_rso_cmd(psoc, vdev_id, rso_command, reason);
+}
+#endif
+#endif
 
 #ifdef WLAN_FEATURE_ROAM_OFFLOAD
 QDF_STATUS

+ 24 - 0
components/umac/mlme/connection_mgr/dispatcher/src/wlan_cm_roam_ucfg_api.c

@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2020, The Linux Foundation. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * DOC: wlan_cm_roam_ucfg_api.c
+ *
+ * Implementation for roaming ucfg public functionality.
+ */
+
+#include "wlan_cm_roam_ucfg_api.h"
+

+ 32 - 0
components/umac/mlme/connection_mgr/dispatcher/src/wlan_cm_tgt_if_tx_api.c

@@ -127,3 +127,35 @@ end:
 	return status;
 }
 #endif
+
+#ifdef ROAM_OFFLOAD_V1
+#if defined(WLAN_FEATURE_HOST_ROAM) || defined(WLAN_FEATURE_ROAM_OFFLOAD)
+QDF_STATUS wlan_cm_tgt_send_roam_start_req(struct wlan_objmgr_psoc *psoc,
+					   uint8_t vdev_id,
+					   struct wlan_roam_start_config *req)
+{
+	QDF_STATUS status;
+	struct wlan_cm_roam_tx_ops roam_tx_ops;
+	struct wlan_objmgr_vdev *vdev;
+
+	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
+						    WLAN_MLME_NB_ID);
+	if (!vdev)
+		return QDF_STATUS_E_INVAL;
+
+	roam_tx_ops = GET_CM_ROAM_TX_OPS_FROM_VDEV(vdev);
+	if (!roam_tx_ops.send_roam_start_req) {
+		mlme_err("send_roam_start_req is NULL");
+		wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_NB_ID);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	status = roam_tx_ops.send_roam_start_req(vdev, req);
+	if (QDF_IS_STATUS_ERROR(status))
+		mlme_debug("fail to send roam start");
+
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_NB_ID);
+	return status;
+}
+#endif
+#endif

+ 17 - 0
components/wmi/inc/wmi_unified_roam_api.h

@@ -58,6 +58,7 @@ wmi_unified_set_rssi_monitoring_cmd(wmi_unified_t wmi_handle,
 				    struct rssi_monitor_param *req);
 #endif
 
+#ifdef ROAM_OFFLOAD_V1
 /**
  * wmi_unified_roam_scan_offload_rssi_thresh_cmd() - set roam scan rssi
  *							parameters
@@ -69,9 +70,25 @@ wmi_unified_set_rssi_monitoring_cmd(wmi_unified_t wmi_handle,
  *
  * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure
  */
+QDF_STATUS wmi_unified_roam_scan_offload_rssi_thresh_cmd(
+		wmi_unified_t wmi_handle,
+		struct wlan_roam_offload_scan_rssi_params *roam_req);
+#else
+/**
+ * wmi_unified_roam_scan_offload_rssi_thresh_cmd() - set roam scan rssi
+ *                                                      parameters
+ * @wmi_handle: wmi handle
+ * @roam_req: roam rssi related parameters
+ *
+ * This function reads the incoming @roam_req and fill in the destination
+ * WMI structure and send down the roam scan rssi configs down to the firmware
+ *
+ * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure
+ */
 QDF_STATUS wmi_unified_roam_scan_offload_rssi_thresh_cmd(
 		wmi_unified_t wmi_handle,
 		struct roam_offload_scan_rssi_params *roam_req);
+#endif
 
 /**
  * wmi_unified_roam_mawc_params_cmd() - configure roaming MAWC parameters

+ 2 - 0
components/wmi/inc/wmi_unified_roam_param.h

@@ -64,6 +64,7 @@ struct rssi_monitor_param {
 	bool     control;
 };
 
+#ifndef ROAM_OFFLOAD_V1
 /**
  * struct roam_offload_scan_rssi_params - structure containing
  *              parameters for roam offload scan based on RSSI
@@ -126,6 +127,7 @@ struct roam_offload_scan_rssi_params {
 	uint32_t bg_scan_client_bitmap;
 	uint32_t flags;
 };
+#endif
 
 /**
  * struct roam_scan_period_params - Roam scan period parameters

+ 13 - 0
components/wmi/src/wmi_unified_roam_api.c

@@ -46,6 +46,18 @@ wmi_unified_set_rssi_monitoring_cmd(wmi_unified_t wmi_handle,
 }
 #endif /* FEATURE_RSSI_MONITOR */
 
+#ifdef ROAM_OFFLOAD_V1
+QDF_STATUS wmi_unified_roam_scan_offload_rssi_thresh_cmd(
+		wmi_unified_t wmi_handle,
+		struct wlan_roam_offload_scan_rssi_params *roam_req)
+{
+	if (wmi_handle->ops->send_roam_scan_offload_rssi_thresh_cmd)
+		return wmi_handle->ops->send_roam_scan_offload_rssi_thresh_cmd(
+				wmi_handle, roam_req);
+
+	return QDF_STATUS_E_FAILURE;
+}
+#else
 QDF_STATUS wmi_unified_roam_scan_offload_rssi_thresh_cmd(
 		wmi_unified_t wmi_handle,
 		struct roam_offload_scan_rssi_params *roam_req)
@@ -56,6 +68,7 @@ QDF_STATUS wmi_unified_roam_scan_offload_rssi_thresh_cmd(
 
 	return QDF_STATUS_E_FAILURE;
 }
+#endif
 
 QDF_STATUS wmi_unified_roam_mawc_params_cmd(
 			wmi_unified_t wmi_handle,

+ 137 - 0
components/wmi/src/wmi_unified_roam_tlv.c

@@ -155,6 +155,7 @@ void wmi_rssi_monitor_attach_tlv(struct wmi_unified *wmi_handle)
 }
 #endif /* FEATURE_RSSI_MONITOR */
 
+#ifdef ROAM_OFFLOAD_V1
 /**
  * send_roam_scan_offload_rssi_thresh_cmd_tlv() - set scan offload
  *                                                rssi threashold
@@ -165,6 +166,141 @@ void wmi_rssi_monitor_attach_tlv(struct wmi_unified *wmi_handle)
  *
  * Return: QDF status
  */
+static QDF_STATUS send_roam_scan_offload_rssi_thresh_cmd_tlv(
+			wmi_unified_t wmi_handle,
+			struct wlan_roam_offload_scan_rssi_params *roam_req)
+{
+	wmi_buf_t buf = NULL;
+	QDF_STATUS status;
+	int len;
+	uint8_t *buf_ptr;
+	wmi_roam_scan_rssi_threshold_fixed_param *rssi_threshold_fp;
+	wmi_roam_scan_extended_threshold_param *ext_thresholds = NULL;
+	wmi_roam_earlystop_rssi_thres_param *early_stop_thresholds = NULL;
+	wmi_roam_dense_thres_param *dense_thresholds = NULL;
+	wmi_roam_bg_scan_roaming_param *bg_scan_params = NULL;
+
+	len = sizeof(wmi_roam_scan_rssi_threshold_fixed_param);
+	len += WMI_TLV_HDR_SIZE; /* TLV for ext_thresholds*/
+	len += sizeof(wmi_roam_scan_extended_threshold_param);
+	len += WMI_TLV_HDR_SIZE;
+	len += sizeof(wmi_roam_earlystop_rssi_thres_param);
+	len += WMI_TLV_HDR_SIZE; /* TLV for dense thresholds*/
+	len += sizeof(wmi_roam_dense_thres_param);
+	len += WMI_TLV_HDR_SIZE; /* TLV for BG Scan*/
+	len += sizeof(wmi_roam_bg_scan_roaming_param);
+	buf = wmi_buf_alloc(wmi_handle, len);
+	if (!buf)
+		return QDF_STATUS_E_NOMEM;
+
+	buf_ptr = (uint8_t *)wmi_buf_data(buf);
+	rssi_threshold_fp =
+		(wmi_roam_scan_rssi_threshold_fixed_param *)buf_ptr;
+	WMITLV_SET_HDR(
+		&rssi_threshold_fp->tlv_header,
+		WMITLV_TAG_STRUC_wmi_roam_scan_rssi_threshold_fixed_param,
+		WMITLV_GET_STRUCT_TLVLEN
+				(wmi_roam_scan_rssi_threshold_fixed_param));
+	/* fill in threshold values */
+	rssi_threshold_fp->vdev_id = roam_req->vdev_id;
+	rssi_threshold_fp->roam_scan_rssi_thresh = roam_req->rssi_thresh;
+	rssi_threshold_fp->roam_rssi_thresh_diff = roam_req->rssi_thresh_diff;
+	rssi_threshold_fp->hirssi_scan_max_count =
+			roam_req->hi_rssi_scan_max_count;
+	rssi_threshold_fp->hirssi_scan_delta =
+			roam_req->hi_rssi_scan_rssi_delta;
+	rssi_threshold_fp->hirssi_upper_bound = roam_req->hi_rssi_scan_rssi_ub;
+	rssi_threshold_fp->rssi_thresh_offset_5g =
+		roam_req->rssi_thresh_offset_5g;
+
+	buf_ptr += sizeof(wmi_roam_scan_rssi_threshold_fixed_param);
+	WMITLV_SET_HDR(buf_ptr,
+		       WMITLV_TAG_ARRAY_STRUC,
+		       sizeof(wmi_roam_scan_extended_threshold_param));
+	buf_ptr += WMI_TLV_HDR_SIZE;
+	ext_thresholds = (wmi_roam_scan_extended_threshold_param *)buf_ptr;
+
+	ext_thresholds->penalty_threshold_5g = roam_req->penalty_threshold_5g;
+	if (roam_req->raise_rssi_thresh_5g >= WMI_NOISE_FLOOR_DBM_DEFAULT)
+		ext_thresholds->boost_threshold_5g =
+					roam_req->boost_threshold_5g;
+
+	ext_thresholds->boost_algorithm_5g =
+		WMI_ROAM_5G_BOOST_PENALIZE_ALGO_LINEAR;
+	ext_thresholds->boost_factor_5g = roam_req->raise_factor_5g;
+	ext_thresholds->penalty_algorithm_5g =
+		WMI_ROAM_5G_BOOST_PENALIZE_ALGO_LINEAR;
+	ext_thresholds->penalty_factor_5g = roam_req->drop_factor_5g;
+	ext_thresholds->max_boost_5g = roam_req->max_raise_rssi_5g;
+	ext_thresholds->max_penalty_5g = roam_req->max_drop_rssi_5g;
+	ext_thresholds->good_rssi_threshold = roam_req->good_rssi_threshold;
+
+	WMITLV_SET_HDR(&ext_thresholds->tlv_header,
+		       WMITLV_TAG_STRUC_wmi_roam_scan_extended_threshold_param,
+		       WMITLV_GET_STRUCT_TLVLEN
+				(wmi_roam_scan_extended_threshold_param));
+	buf_ptr += sizeof(wmi_roam_scan_extended_threshold_param);
+	WMITLV_SET_HDR(buf_ptr,
+		       WMITLV_TAG_ARRAY_STRUC,
+		       sizeof(wmi_roam_earlystop_rssi_thres_param));
+	buf_ptr += WMI_TLV_HDR_SIZE;
+	early_stop_thresholds = (wmi_roam_earlystop_rssi_thres_param *)buf_ptr;
+	early_stop_thresholds->roam_earlystop_thres_min =
+		roam_req->roam_earlystop_thres_min;
+	early_stop_thresholds->roam_earlystop_thres_max =
+		roam_req->roam_earlystop_thres_max;
+	WMITLV_SET_HDR(&early_stop_thresholds->tlv_header,
+		       WMITLV_TAG_STRUC_wmi_roam_earlystop_rssi_thres_param,
+		       WMITLV_GET_STRUCT_TLVLEN
+				(wmi_roam_earlystop_rssi_thres_param));
+
+	buf_ptr += sizeof(wmi_roam_earlystop_rssi_thres_param);
+	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
+		       sizeof(wmi_roam_dense_thres_param));
+	buf_ptr += WMI_TLV_HDR_SIZE;
+	dense_thresholds = (wmi_roam_dense_thres_param *)buf_ptr;
+	dense_thresholds->roam_dense_rssi_thres_offset =
+			roam_req->dense_rssi_thresh_offset;
+	dense_thresholds->roam_dense_min_aps = roam_req->dense_min_aps_cnt;
+	dense_thresholds->roam_dense_traffic_thres =
+			roam_req->traffic_threshold;
+	dense_thresholds->roam_dense_status = roam_req->initial_dense_status;
+	WMITLV_SET_HDR(&dense_thresholds->tlv_header,
+		       WMITLV_TAG_STRUC_wmi_roam_dense_thres_param,
+		       WMITLV_GET_STRUCT_TLVLEN(wmi_roam_dense_thres_param));
+
+	buf_ptr += sizeof(wmi_roam_dense_thres_param);
+	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
+		       sizeof(wmi_roam_bg_scan_roaming_param));
+	buf_ptr += WMI_TLV_HDR_SIZE;
+	bg_scan_params = (wmi_roam_bg_scan_roaming_param *)buf_ptr;
+	bg_scan_params->roam_bg_scan_bad_rssi_thresh =
+		roam_req->bg_scan_bad_rssi_thresh;
+	bg_scan_params->roam_bg_scan_client_bitmap =
+		roam_req->bg_scan_client_bitmap;
+	bg_scan_params->bad_rssi_thresh_offset_2g =
+		roam_req->roam_bad_rssi_thresh_offset_2g;
+
+	bg_scan_params->flags = 0;
+	if (roam_req->roam_bad_rssi_thresh_offset_2g)
+		bg_scan_params->flags |= WMI_ROAM_BG_SCAN_FLAGS_2G_TO_5G_ONLY;
+	WMITLV_SET_HDR(&bg_scan_params->tlv_header,
+		       WMITLV_TAG_STRUC_wmi_roam_bg_scan_roaming_param,
+		       WMITLV_GET_STRUCT_TLVLEN
+		       (wmi_roam_bg_scan_roaming_param));
+
+	wmi_mtrace(WMI_ROAM_SCAN_RSSI_THRESHOLD, NO_SESSION, 0);
+	status = wmi_unified_cmd_send(wmi_handle, buf,
+				      len, WMI_ROAM_SCAN_RSSI_THRESHOLD);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		WMI_LOGE("cmd WMI_ROAM_SCAN_RSSI_THRESHOLD returned Error %d",
+			 status);
+		wmi_buf_free(buf);
+	}
+
+	return status;
+}
+#else
 static QDF_STATUS send_roam_scan_offload_rssi_thresh_cmd_tlv(
 		wmi_unified_t wmi_handle,
 		struct roam_offload_scan_rssi_params *roam_req)
@@ -295,6 +431,7 @@ static QDF_STATUS send_roam_scan_offload_rssi_thresh_cmd_tlv(
 
 	return status;
 }
+#endif
 
 static QDF_STATUS send_roam_mawc_params_cmd_tlv(wmi_unified_t wmi_handle,
 		struct wmi_mawc_roam_params *params)

+ 3 - 0
configs/default_defconfig

@@ -1123,3 +1123,6 @@ endif
 
 #Enable connection manager
 CONFIG_CM_ENABLE := n
+
+#Flag to enable roam offload compilation of connection manager module
+CONFIG_CM_ROAM_OFFLOAD := n

+ 0 - 59
core/sme/inc/csr_neighbor_roam.h

@@ -209,65 +209,6 @@ QDF_STATUS csr_neighbor_roam_merge_channel_lists(struct mac_context *mac,
 		uint8_t outputNumOfChannels,
 		uint8_t *pMergedOutputNumOfChannels);
 void csr_roam_reset_roam_params(struct mac_context *mac_ptr);
-#define ROAM_SCAN_OFFLOAD_START                     1
-#define ROAM_SCAN_OFFLOAD_STOP                      2
-#define ROAM_SCAN_OFFLOAD_RESTART                   3
-#define ROAM_SCAN_OFFLOAD_UPDATE_CFG                4
-#define ROAM_SCAN_OFFLOAD_ABORT_SCAN                5
-
-#define REASON_CONNECT                              1
-#define REASON_CHANNEL_LIST_CHANGED                 2
-#define REASON_LOOKUP_THRESH_CHANGED                3
-#define REASON_DISCONNECTED                         4
-#define REASON_RSSI_DIFF_CHANGED                    5
-#define REASON_ESE_INI_CFG_CHANGED                  6
-#define REASON_NEIGHBOR_SCAN_REFRESH_PERIOD_CHANGED 7
-#define REASON_VALID_CHANNEL_LIST_CHANGED           8
-#define REASON_FLUSH_CHANNEL_LIST                   9
-#define REASON_EMPTY_SCAN_REF_PERIOD_CHANGED        10
-#define REASON_PREAUTH_FAILED_FOR_ALL               11
-#define REASON_NO_CAND_FOUND_OR_NOT_ROAMING_NOW     12
-#define REASON_NPROBES_CHANGED                      13
-#define REASON_HOME_AWAY_TIME_CHANGED               14
-#define REASON_OS_REQUESTED_ROAMING_NOW             15
-#define REASON_SCAN_CH_TIME_CHANGED                 16
-#define REASON_SCAN_HOME_TIME_CHANGED               17
-#define REASON_OPPORTUNISTIC_THRESH_DIFF_CHANGED    18
-#define REASON_ROAM_RESCAN_RSSI_DIFF_CHANGED        19
-#define REASON_ROAM_BMISS_FIRST_BCNT_CHANGED        20
-#define REASON_ROAM_BMISS_FINAL_BCNT_CHANGED        21
-#define REASON_ROAM_BEACON_RSSI_WEIGHT_CHANGED      22
-#define REASON_ROAM_DFS_SCAN_MODE_CHANGED           23
-#define REASON_ROAM_ABORT_ROAM_SCAN                 24
-#define REASON_ROAM_EXT_SCAN_PARAMS_CHANGED         25
-#define REASON_ROAM_SET_SSID_ALLOWED                26
-#define REASON_ROAM_SET_FAVORED_BSSID               27
-#define REASON_ROAM_GOOD_RSSI_CHANGED               28
-#define REASON_ROAM_SET_BLACKLIST_BSSID             29
-#define REASON_ROAM_SCAN_HI_RSSI_MAXCOUNT_CHANGED   30
-#define REASON_ROAM_SCAN_HI_RSSI_DELTA_CHANGED      31
-#define REASON_ROAM_SCAN_HI_RSSI_DELAY_CHANGED      32
-#define REASON_ROAM_SCAN_HI_RSSI_UB_CHANGED         33
-#define REASON_CONNECT_IES_CHANGED                  34
-#define REASON_ROAM_SCAN_STA_ROAM_POLICY_CHANGED    35
-#define REASON_ROAM_SYNCH_FAILED                    36
-#define REASON_ROAM_PSK_PMK_CHANGED                 37
-#define REASON_ROAM_STOP_ALL                        38
-#define REASON_SUPPLICANT_DISABLED_ROAMING          39
-#define REASON_CTX_INIT                             40
-#define REASON_FILS_PARAMS_CHANGED                  41
-#define REASON_SME_ISSUED                           42
-#define REASON_DRIVER_ENABLED                       43
-#define REASON_ROAM_FULL_SCAN_PERIOD_CHANGED        44
-#define REASON_SCORING_CRITERIA_CHANGED             45
-#define REASON_SUPPLICANT_INIT_ROAMING              46
-#define REASON_SUPPLICANT_DE_INIT_ROAMING           47
-#define REASON_DRIVER_DISABLED                      48
-#define REASON_ROAM_CONTROL_CONFIG_CHANGED          49
-#define REASON_ROAM_CONTROL_CONFIG_ENABLED          50
-#define REASON_ROAM_CANDIDATE_FOUND                 51
-#define REASON_ROAM_HANDOFF_DONE                    52
-#define REASON_ROAM_ABORT                           53
 
 #if defined(WLAN_FEATURE_HOST_ROAM) || defined(WLAN_FEATURE_ROAM_OFFLOAD)
 QDF_STATUS csr_roam_offload_scan(struct mac_context *mac, uint8_t sessionId,

+ 292 - 0
core/sme/src/csr/csr_api_roam.c

@@ -18557,6 +18557,7 @@ csr_post_rso_stop(struct mac_context *mac, uint8_t vdev_id, uint16_t reason)
 	return status;
 }
 
+#ifndef ROAM_OFFLOAD_V1
 static QDF_STATUS
 csr_roam_switch_to_init(struct mac_context *mac, uint8_t vdev_id,
 			uint8_t reason)
@@ -18961,6 +18962,19 @@ csr_post_roam_state_change(struct mac_context *mac, uint8_t vdev_id,
 {
 	return csr_handle_roam_state_change(mac, vdev_id, state, reason);
 }
+#else
+QDF_STATUS
+csr_post_roam_state_change(struct mac_context *mac, uint8_t vdev_id,
+			   enum roam_offload_state state, uint8_t reason)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	if (state == WLAN_ROAM_RSO_ENABLED)
+		status = wlan_cm_start_roaming(mac->pdev, vdev_id, reason);
+
+	return status;
+}
+#endif
 
 /**
  * csr_roam_offload_scan() - populates roam offload scan request and sends to
@@ -19250,6 +19264,284 @@ csr_roam_offload_scan(struct mac_context *mac_ctx, uint8_t session_id,
 	return status;
 }
 
+#ifdef ROAM_OFFLOAD_V1
+#if defined(WLAN_FEATURE_HOST_ROAM) || defined(WLAN_FEATURE_ROAM_OFFLOAD)
+QDF_STATUS wlan_cm_roam_cmd_allowed(struct wlan_objmgr_psoc *psoc,
+				    uint8_t vdev_id,
+				    uint8_t command,
+				    uint8_t reason)
+{
+	uint8_t *state = NULL;
+	struct csr_roam_session *session;
+	struct mac_context *mac_ctx;
+	tpCsrNeighborRoamControlInfo roam_info;
+	enum csr_akm_type roam_profile_akm = eCSR_AUTH_TYPE_UNKNOWN;
+	uint32_t fw_akm_bitmap;
+	bool p2p_disable_sta_roaming = 0, nan_disable_sta_roaming = 0;
+
+	mac_ctx = sme_get_mac_context();
+	if (!mac_ctx) {
+		sme_err("mac_ctx is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	sme_debug("RSO Command %d, vdev %d, Reason %d",
+		  command, vdev_id, reason);
+
+	session = CSR_GET_SESSION(mac_ctx, vdev_id);
+	if (!session) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  "session is null");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	roam_info = &mac_ctx->roam.neighborRoamInfo[vdev_id];
+
+	if (roam_info->neighborRoamState !=
+	    eCSR_NEIGHBOR_ROAM_STATE_CONNECTED &&
+	    (command == ROAM_SCAN_OFFLOAD_UPDATE_CFG ||
+	     command == ROAM_SCAN_OFFLOAD_START ||
+	     command == ROAM_SCAN_OFFLOAD_RESTART)) {
+		sme_debug("Session not in connected state, RSO not sent and state=%d ",
+			  roam_info->neighborRoamState);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (session->pCurRoamProfile)
+		roam_profile_akm =
+			session->pCurRoamProfile->AuthType.authType[0];
+	else
+		sme_info("Roam profile is NULL");
+
+	if (CSR_IS_AKM_FILS(roam_profile_akm) &&
+	    !mac_ctx->is_fils_roaming_supported) {
+		sme_info("FILS Roaming not suppprted by fw");
+		return QDF_STATUS_E_NOSUPPORT;
+	}
+
+	if (!csr_is_adaptive_11r_roam_supported(mac_ctx, session)) {
+		sme_info("Adaptive 11r Roaming not suppprted by fw");
+		return QDF_STATUS_E_NOSUPPORT;
+	}
+
+	fw_akm_bitmap = mac_ctx->mlme_cfg->lfr.fw_akm_bitmap;
+	/* Roaming is not supported currently for OWE akm */
+	if (roam_profile_akm == eCSR_AUTH_TYPE_OWE &&
+	    !CSR_IS_FW_OWE_ROAM_SUPPORTED(fw_akm_bitmap)) {
+		sme_info("OWE Roaming not suppprted by fw");
+		return QDF_STATUS_E_NOSUPPORT;
+	}
+
+	/* Roaming is not supported for SAE authentication */
+	if (CSR_IS_AUTH_TYPE_SAE(roam_profile_akm) &&
+	    !CSR_IS_FW_SAE_ROAM_SUPPORTED(fw_akm_bitmap)) {
+		sme_info("Roaming not suppprted for SAE connection");
+		return QDF_STATUS_E_NOSUPPORT;
+	}
+
+	if ((roam_profile_akm == eCSR_AUTH_TYPE_SUITEB_EAP_SHA256 ||
+	     roam_profile_akm == eCSR_AUTH_TYPE_SUITEB_EAP_SHA384) &&
+	     !CSR_IS_FW_SUITEB_ROAM_SUPPORTED(fw_akm_bitmap)) {
+		sme_info("Roaming not supported for SUITEB connection");
+		return QDF_STATUS_E_NOSUPPORT;
+	}
+
+	/*
+	 * If fw doesn't advertise FT SAE, FT-FILS or FT-Suite-B capability,
+	 * don't support roaming to that profile
+	 */
+	if (CSR_IS_AKM_FT_SAE(roam_profile_akm)) {
+		if (!CSR_IS_FW_FT_SAE_SUPPORTED(fw_akm_bitmap)) {
+			sme_info("Roaming not suppprted for FT SAE akm");
+			return QDF_STATUS_E_NOSUPPORT;
+		}
+	}
+
+	if (CSR_IS_AKM_FT_SUITEB_SHA384(roam_profile_akm)) {
+		if (!CSR_IS_FW_FT_SUITEB_SUPPORTED(fw_akm_bitmap)) {
+			sme_info("Roaming not suppprted for FT Suite-B akm");
+			return QDF_STATUS_E_NOSUPPORT;
+		}
+	}
+
+	if (CSR_IS_AKM_FT_FILS(roam_profile_akm)) {
+		if (!CSR_IS_FW_FT_FILS_SUPPORTED(fw_akm_bitmap)) {
+			sme_info("Roaming not suppprted for FT FILS akm");
+			return QDF_STATUS_E_NOSUPPORT;
+		}
+	}
+
+	p2p_disable_sta_roaming =
+		(cfg_p2p_is_roam_config_disabled(psoc) &&
+		(policy_mgr_mode_specific_connection_count(
+					psoc, PM_P2P_CLIENT_MODE, NULL) ||
+		policy_mgr_mode_specific_connection_count(
+					psoc, PM_P2P_GO_MODE, NULL)));
+	nan_disable_sta_roaming =
+	    (cfg_nan_is_roam_config_disabled(psoc) &&
+	    policy_mgr_mode_specific_connection_count(psoc, PM_NDI_MODE, NULL));
+
+	if ((command == ROAM_SCAN_OFFLOAD_START ||
+	     command == ROAM_SCAN_OFFLOAD_UPDATE_CFG) &&
+	     (p2p_disable_sta_roaming || nan_disable_sta_roaming)) {
+		sme_info("roaming not supported for active %s connection",
+			 p2p_disable_sta_roaming ? "p2p" : "ndi");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	/*
+	 * The Dynamic Config Items Update may happen even if the state is in
+	 * INIT. It is important to ensure that the command is passed down to
+	 * the FW only if the Infra Station is in a connected state. A connected
+	 * station could also be in a PREAUTH or REASSOC states.
+	 * 1) Block all CMDs that are not STOP in INIT State. For STOP always
+	 *    inform firmware irrespective of state.
+	 * 2) Block update cfg CMD if its for REASON_ROAM_SET_BLACKLIST_BSSID,
+	 *    because we need to inform firmware of blacklisted AP for PNO in
+	 *    all states.
+	 */
+	if ((roam_info->neighborRoamState == eCSR_NEIGHBOR_ROAM_STATE_INIT) &&
+	    (command != ROAM_SCAN_OFFLOAD_STOP) &&
+	    (reason != REASON_ROAM_SET_BLACKLIST_BSSID)) {
+		state = mac_trace_get_neighbour_roam_state(
+				roam_info->neighborRoamState);
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+			  FL("Scan Command not sent to FW state=%s and cmd=%d"),
+			  state,  command);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * wlan_cm_roam_scan_offload_rssi_thresh() - set roam offload scan rssi
+ * parameters
+ * @mac_ctx: global mac ctx
+ * @session: csr roam session
+ * @params:  roam offload scan rssi related parameters
+ *
+ * This function is used to set roam offload scan rssi related parameters
+ *
+ * Return: None
+ */
+static void wlan_cm_roam_scan_offload_rssi_thresh(
+			struct mac_context *mac_ctx,
+			struct csr_roam_session *session,
+			struct wlan_roam_offload_scan_rssi_params *params)
+{
+	struct roam_ext_params *roam_params;
+		tpCsrNeighborRoamControlInfo roam_info =
+		&mac_ctx->roam.neighborRoamInfo[session->vdev_id];
+
+	roam_params = &mac_ctx->roam.configParam.roam_params;
+
+	if (roam_params->alert_rssi_threshold)
+		params->rssi_thresh = roam_params->alert_rssi_threshold;
+	else
+		params->rssi_thresh =
+			(int8_t)roam_info->cfgParams.neighborLookupThreshold *
+			(-1);
+
+	params->vdev_id = session->vdev_id;
+	params->rssi_thresh_diff =
+		roam_info->cfgParams.nOpportunisticThresholdDiff & 0x000000ff;
+	params->hi_rssi_scan_max_count =
+		roam_info->cfgParams.hi_rssi_scan_max_count;
+	/*
+	 * If the current operation channel is 5G frequency band, then
+	 * there is no need to enable the HI_RSSI feature. This feature
+	 * is useful only if we are connected to a 2.4 GHz AP and we wish
+	 * to connect to a better 5GHz AP is available.
+	 */
+	if (session->disable_hi_rssi)
+		params->hi_rssi_scan_rssi_delta = 0;
+	else
+		params->hi_rssi_scan_rssi_delta =
+			roam_info->cfgParams.hi_rssi_scan_rssi_delta;
+	params->hi_rssi_scan_rssi_ub =
+		roam_info->cfgParams.hi_rssi_scan_rssi_ub;
+	params->raise_rssi_thresh_5g =
+		mac_ctx->mlme_cfg->lfr.rssi_boost_threshold_5g;
+	params->dense_rssi_thresh_offset =
+		mac_ctx->mlme_cfg->lfr.roam_dense_rssi_thre_offset;
+	params->dense_min_aps_cnt = mac_ctx->mlme_cfg->lfr.roam_dense_min_aps;
+	params->traffic_threshold =
+			mac_ctx->mlme_cfg->lfr.roam_dense_traffic_threshold;
+
+	/* Set initial dense roam status */
+	if (mac_ctx->scan.roam_candidate_count[params->vdev_id] >
+	    params->dense_min_aps_cnt)
+		params->initial_dense_status = true;
+
+	params->bg_scan_bad_rssi_thresh =
+		mac_ctx->mlme_cfg->lfr.roam_bg_scan_bad_rssi_threshold;
+
+	params->bg_scan_client_bitmap =
+		mac_ctx->mlme_cfg->lfr.roam_bg_scan_client_bitmap;
+	params->roam_bad_rssi_thresh_offset_2g =
+			mac_ctx->mlme_cfg->lfr.roam_bg_scan_bad_rssi_offset_2g;
+
+	params->drop_rssi_thresh_5g =
+		mac_ctx->mlme_cfg->lfr.rssi_penalize_threshold_5g;
+
+	params->raise_factor_5g = mac_ctx->mlme_cfg->lfr.rssi_boost_factor_5g;
+	params->drop_factor_5g = mac_ctx->mlme_cfg->lfr.rssi_penalize_factor_5g;
+	params->max_raise_rssi_5g = mac_ctx->mlme_cfg->lfr.max_rssi_boost_5g;
+	params->max_drop_rssi_5g = mac_ctx->mlme_cfg->lfr.max_rssi_penalize_5g;
+
+	if (roam_params->good_rssi_roam)
+		params->good_rssi_threshold = NOISE_FLOOR_DBM_DEFAULT;
+	else
+		params->good_rssi_threshold = 0;
+
+	params->early_stop_scan_enable =
+		mac_ctx->mlme_cfg->lfr.early_stop_scan_enable;
+	if (params->early_stop_scan_enable) {
+		params->roam_earlystop_thres_min =
+			mac_ctx->mlme_cfg->lfr.early_stop_scan_min_threshold;
+		params->roam_earlystop_thres_max =
+			mac_ctx->mlme_cfg->lfr.early_stop_scan_max_threshold;
+	}
+
+	params->rssi_thresh_offset_5g =
+		roam_info->cfgParams.rssi_thresh_offset_5g;
+}
+
+QDF_STATUS
+wlan_cm_roam_fill_start_req(struct wlan_objmgr_psoc *psoc,
+			    uint8_t vdev_id,
+			    struct wlan_roam_start_config *req,
+			    uint8_t reason)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	struct csr_roam_session *session;
+	struct mac_context *mac_ctx;
+
+	mac_ctx = sme_get_mac_context();
+	if (!mac_ctx) {
+		sme_err("mac_ctx is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	session = CSR_GET_SESSION(mac_ctx, vdev_id);
+	if (!session) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			  "session is null");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	wlan_cm_roam_scan_offload_rssi_thresh(mac_ctx,
+					      session,
+					      &req->rssi_params);
+
+	/* fill other struct similar to wlan_roam_offload_scan_rssi_params */
+
+	return status;
+}
+#endif
+#endif
+
 QDF_STATUS
 csr_roam_offload_scan_rsp_hdlr(struct mac_context *mac,
 			       struct roam_offload_scan_rsp *scanOffloadRsp)

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

@@ -518,6 +518,7 @@ QDF_STATUS wma_roam_scan_offload_mode(tp_wma_handle wma_handle,
 	return status;
 }
 
+#ifndef ROAM_OFFLOAD_V1
 QDF_STATUS
 wma_roam_scan_offload_rssi_thresh(tp_wma_handle wma_handle,
 				  struct roam_offload_scan_req *roam_req)
@@ -689,6 +690,14 @@ wma_roam_scan_offload_rssi_thresh(tp_wma_handle wma_handle,
 		  roam_params->roam_bad_rssi_thresh_offset_2g);
 	return status;
 }
+#else
+QDF_STATUS
+wma_roam_scan_offload_rssi_thresh(tp_wma_handle wma_handle,
+				  struct roam_offload_scan_req *roam_req)
+{
+	return QDF_STATUS_E_NOSUPPORT;
+}
+#endif
 
 /**
  * wma_roam_scan_offload_scan_period() - set roam offload scan period