From 7277418aa5cb3ddcbe477f9f755aa796d852112e Mon Sep 17 00:00:00 2001 From: Huashan Qu Date: Fri, 17 Jul 2020 09:32:56 +0530 Subject: [PATCH] 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 --- Kbuild | 6 + .../policy_mgr/inc/wlan_policy_mgr_api.h | 17 + .../src/wlan_policy_mgr_get_set_utils.c | 32 ++ .../mlme/dispatcher/inc/wlan_mlme_api.h | 10 + .../mlme/dispatcher/src/wlan_mlme_api.c | 17 + .../src/target_if_cm_roam_offload.c | 168 ++++++- .../core/src/wlan_cm_roam_offload.c | 447 ++++++++++++++++++ .../core/src/wlan_cm_roam_offload.h | 63 +++ .../dispatcher/inc/wlan_cm_roam_api.h | 105 ++++ .../inc/wlan_cm_roam_public_srtuct.h | 144 ++++++ .../dispatcher/inc/wlan_cm_roam_ucfg_api.h | 26 + .../dispatcher/inc/wlan_cm_tgt_if_tx_api.h | 16 + .../dispatcher/src/wlan_cm_roam_api.c | 67 +++ .../dispatcher/src/wlan_cm_roam_ucfg_api.c | 24 + .../dispatcher/src/wlan_cm_tgt_if_tx_api.c | 32 ++ components/wmi/inc/wmi_unified_roam_api.h | 17 + components/wmi/inc/wmi_unified_roam_param.h | 2 + components/wmi/src/wmi_unified_roam_api.c | 13 + components/wmi/src/wmi_unified_roam_tlv.c | 137 ++++++ configs/default_defconfig | 3 + core/sme/inc/csr_neighbor_roam.h | 59 --- core/sme/src/csr/csr_api_roam.c | 292 ++++++++++++ core/wma/src/wma_scan_roam.c | 9 + 23 files changed, 1646 insertions(+), 60 deletions(-) create mode 100644 components/umac/mlme/connection_mgr/core/src/wlan_cm_roam_offload.c create mode 100644 components/umac/mlme/connection_mgr/core/src/wlan_cm_roam_offload.h create mode 100644 components/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_roam_ucfg_api.h create mode 100644 components/umac/mlme/connection_mgr/dispatcher/src/wlan_cm_roam_ucfg_api.c diff --git a/Kbuild b/Kbuild index 95b241e248..b8e69690c2 100644 --- a/Kbuild +++ b/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 diff --git a/components/cmn_services/policy_mgr/inc/wlan_policy_mgr_api.h b/components/cmn_services/policy_mgr/inc/wlan_policy_mgr_api.h index 32028a700b..9c3ada4be1 100644 --- a/components/cmn_services/policy_mgr/inc/wlan_policy_mgr_api.h +++ b/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 */ diff --git a/components/cmn_services/policy_mgr/src/wlan_policy_mgr_get_set_utils.c b/components/cmn_services/policy_mgr/src/wlan_policy_mgr_get_set_utils.c index 3414332bbf..bd6cf8b714 100644 --- a/components/cmn_services/policy_mgr/src/wlan_policy_mgr_get_set_utils.c +++ b/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; +} diff --git a/components/mlme/dispatcher/inc/wlan_mlme_api.h b/components/mlme/dispatcher/inc/wlan_mlme_api.h index cdd3c830bd..b24ef8c90f 100644 --- a/components/mlme/dispatcher/inc/wlan_mlme_api.h +++ b/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_ */ diff --git a/components/mlme/dispatcher/src/wlan_mlme_api.c b/components/mlme/dispatcher/src/wlan_mlme_api.c index 507171ec43..9dc710ba51 100644 --- a/components/mlme/dispatcher/src/wlan_mlme_api.c +++ b/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; +} diff --git a/components/target_if/connection_mgr/src/target_if_cm_roam_offload.c b/components/target_if/connection_mgr/src/target_if_cm_roam_offload.c index 85c41a71b1..19afccfeaa 100644 --- a/components/target_if/connection_mgr/src/target_if_cm_roam_offload.c +++ b/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; } diff --git a/components/umac/mlme/connection_mgr/core/src/wlan_cm_roam_offload.c b/components/umac/mlme/connection_mgr/core/src/wlan_cm_roam_offload.c new file mode 100644 index 0000000000..9fe6be0e6d --- /dev/null +++ b/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; +} diff --git a/components/umac/mlme/connection_mgr/core/src/wlan_cm_roam_offload.h b/components/umac/mlme/connection_mgr/core/src/wlan_cm_roam_offload.h new file mode 100644 index 0000000000..ca4d643fa0 --- /dev/null +++ b/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 diff --git a/components/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_roam_api.h b/components/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_roam_api.h index 679dd2cefb..6cdf4c9eca 100644 --- a/components/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_roam_api.h +++ b/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 diff --git a/components/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_roam_public_srtuct.h b/components/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_roam_public_srtuct.h index 5d0399e833..e2f24b949d 100644 --- a/components/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_roam_public_srtuct.h +++ b/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 }; /** diff --git a/components/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_roam_ucfg_api.h b/components/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_roam_ucfg_api.h new file mode 100644 index 0000000000..0c11761374 --- /dev/null +++ b/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 diff --git a/components/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_tgt_if_tx_api.h b/components/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_tgt_if_tx_api.h index 33cc2da30c..52455e34a6 100644 --- a/components/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_tgt_if_tx_api.h +++ b/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__ */ diff --git a/components/umac/mlme/connection_mgr/dispatcher/src/wlan_cm_roam_api.c b/components/umac/mlme/connection_mgr/dispatcher/src/wlan_cm_roam_api.c index cfd608a72b..1732a0ccdc 100644 --- a/components/umac/mlme/connection_mgr/dispatcher/src/wlan_cm_roam_api.c +++ b/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 +#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 diff --git a/components/umac/mlme/connection_mgr/dispatcher/src/wlan_cm_roam_ucfg_api.c b/components/umac/mlme/connection_mgr/dispatcher/src/wlan_cm_roam_ucfg_api.c new file mode 100644 index 0000000000..9777b3ea9e --- /dev/null +++ b/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" + diff --git a/components/umac/mlme/connection_mgr/dispatcher/src/wlan_cm_tgt_if_tx_api.c b/components/umac/mlme/connection_mgr/dispatcher/src/wlan_cm_tgt_if_tx_api.c index 6ffa50664c..99405f7883 100644 --- a/components/umac/mlme/connection_mgr/dispatcher/src/wlan_cm_tgt_if_tx_api.c +++ b/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 diff --git a/components/wmi/inc/wmi_unified_roam_api.h b/components/wmi/inc/wmi_unified_roam_api.h index 0867c92bc0..1ebba1c6f0 100644 --- a/components/wmi/inc/wmi_unified_roam_api.h +++ b/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 diff --git a/components/wmi/inc/wmi_unified_roam_param.h b/components/wmi/inc/wmi_unified_roam_param.h index 5a7fd64b2a..09611d3719 100644 --- a/components/wmi/inc/wmi_unified_roam_param.h +++ b/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 diff --git a/components/wmi/src/wmi_unified_roam_api.c b/components/wmi/src/wmi_unified_roam_api.c index b92156f91b..3d5129a8c1 100644 --- a/components/wmi/src/wmi_unified_roam_api.c +++ b/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, diff --git a/components/wmi/src/wmi_unified_roam_tlv.c b/components/wmi/src/wmi_unified_roam_tlv.c index 4ed459b16c..00bde111b7 100644 --- a/components/wmi/src/wmi_unified_roam_tlv.c +++ b/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) diff --git a/configs/default_defconfig b/configs/default_defconfig index 83d9ccfb40..e07a0298f5 100644 --- a/configs/default_defconfig +++ b/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 diff --git a/core/sme/inc/csr_neighbor_roam.h b/core/sme/inc/csr_neighbor_roam.h index f8a040d117..a9bd1db03c 100644 --- a/core/sme/inc/csr_neighbor_roam.h +++ b/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, diff --git a/core/sme/src/csr/csr_api_roam.c b/core/sme/src/csr/csr_api_roam.c index 48899cfaa5..1596a3f02e 100644 --- a/core/sme/src/csr/csr_api_roam.c +++ b/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) diff --git a/core/wma/src/wma_scan_roam.c b/core/wma/src/wma_scan_roam.c index f8750e2ebb..88dd7df30d 100644 --- a/core/wma/src/wma_scan_roam.c +++ b/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