diff --git a/components/mlme/dispatcher/inc/wlan_mlme_api.h b/components/mlme/dispatcher/inc/wlan_mlme_api.h index ff3064e239..d9cec575f7 100644 --- a/components/mlme/dispatcher/inc/wlan_mlme_api.h +++ b/components/mlme/dispatcher/inc/wlan_mlme_api.h @@ -2930,4 +2930,24 @@ bool wlan_mlme_check_chan_param_has_dfs(struct wlan_objmgr_pdev *pdev, struct ch_params *ch_params, uint32_t chan_freq); + +/** + * wlan_mlme_set_usr_disabled_roaming() - Set user config for roaming disable + * @psoc: pointer to psoc object + * @val: user config for roaming disable + * + * Return: QDF_STATUS + */ +QDF_STATUS +wlan_mlme_set_usr_disabled_roaming(struct wlan_objmgr_psoc *psoc, bool val); + +/** + * wlan_mlme_get_usr_disabled_roaming() - Get user config for roaming disable + * @psoc: pointer to psoc object + * @val: user config for roaming disable + * + * Return: QDF_STATUS + */ +QDF_STATUS +wlan_mlme_get_usr_disabled_roaming(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 c49b871b34..20631027f2 100644 --- a/components/mlme/dispatcher/src/wlan_mlme_api.c +++ b/components/mlme/dispatcher/src/wlan_mlme_api.c @@ -4476,3 +4476,31 @@ wlan_mlme_check_chan_param_has_dfs(struct wlan_objmgr_pdev *pdev, return is_dfs; } + +QDF_STATUS +wlan_mlme_set_usr_disabled_roaming(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) + return QDF_STATUS_E_FAILURE; + + mlme_obj->cfg.sta.usr_disabled_roaming = val; + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS +wlan_mlme_get_usr_disabled_roaming(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) + return QDF_STATUS_E_INVAL; + + *val = mlme_obj->cfg.sta.usr_disabled_roaming; + + 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 5a9663eb5a..c6ee7bb950 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 @@ -1198,6 +1198,51 @@ target_if_cm_roam_per_config(struct wlan_objmgr_vdev *vdev, return wmi_unified_set_per_roam_config(wmi_handle, req); } +/** + * target_if_cm_roam_send_disable_config() - Send roam disable config related + * commands to wmi + * @vdev: vdev object + * @req: roam disable config parameters + * + * Return: QDF_STATUS + */ +static QDF_STATUS +target_if_cm_roam_send_disable_config(struct wlan_objmgr_vdev *vdev, + struct roam_disable_cfg *req) +{ + QDF_STATUS status = QDF_STATUS_E_FAILURE; + wmi_unified_t wmi_handle; + struct vdev_mlme_obj *vdev_mlme; + + vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev); + if (!vdev_mlme) { + target_if_err("Failed to get vdev mlme obj!"); + goto end; + } + + if (vdev_mlme->mgmt.generic.type != WMI_VDEV_TYPE_STA || + vdev_mlme->mgmt.generic.subtype != 0) { + target_if_err("This isn't a STA: %d", req->vdev_id); + goto end; + } + + wmi_handle = target_if_cm_roam_get_wmi_handle_from_vdev(vdev); + if (!wmi_handle) + goto end; + + status = target_if_vdev_set_param( + wmi_handle, + req->vdev_id, + WMI_VDEV_PARAM_ROAM_11KV_CTRL, + req->cfg); + + if (QDF_IS_STATUS_ERROR(status)) + target_if_err("Failed to set WMI_VDEV_PARAM_ROAM_11KV_CTRL"); + +end: + return status; +} + /** * target_if_cm_roam_register_rso_req_ops() - Register rso req tx ops fucntions * @tx_ops: tx ops @@ -1216,6 +1261,8 @@ target_if_cm_roam_register_rso_req_ops(struct wlan_cm_roam_tx_ops *tx_ops) tx_ops->send_roam_abort = target_if_cm_roam_abort; tx_ops->send_roam_per_config = target_if_cm_roam_per_config; tx_ops->send_roam_triggers = target_if_cm_roam_triggers; + tx_ops->send_roam_disable_config = + target_if_cm_roam_send_disable_config; } #else static void 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 index fefcb19996..3751da8e7b 100644 --- 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 @@ -245,6 +245,29 @@ cm_roam_mawc_params(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, psoc, ¶ms->rssi_stationary_low_adjust); } +QDF_STATUS +cm_roam_send_disable_config(struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id, uint8_t cfg) +{ + struct roam_disable_cfg *req; + QDF_STATUS status; + + req = qdf_mem_malloc(sizeof(*req)); + if (!req) + return QDF_STATUS_E_NOMEM; + + req->vdev_id = vdev_id; + req->cfg = cfg; + + status = wlan_cm_tgt_send_roam_disable_config(psoc, vdev_id, req); + if (QDF_IS_STATUS_ERROR(status)) + mlme_debug("fail to send roam disable config"); + + qdf_mem_free(req); + + return status; +} + /** * cm_roam_init_req() - roam init request handling * @psoc: psoc pointer @@ -568,7 +591,7 @@ cm_roam_fill_per_roam_request(struct wlan_objmgr_psoc *psoc, static QDF_STATUS cm_roam_offload_per_config(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id) { - struct wlan_per_roam_config_req *req = NULL; + struct wlan_per_roam_config_req *req; QDF_STATUS status; req = qdf_mem_malloc(sizeof(*req)); @@ -672,6 +695,9 @@ cm_roam_switch_to_rso_stop(struct wlan_objmgr_pdev *pdev, * nothing to do here */ default: + /* For LFR2 BTM request, need handoff even roam disabled */ + if (reason == REASON_OS_REQUESTED_ROAMING_NOW) + wlan_cm_roam_neighbor_proceed_with_handoff_req(vdev_id); return QDF_STATUS_SUCCESS; } mlme_set_roam_state(psoc, vdev_id, WLAN_ROAM_RSO_STOPPED); @@ -768,7 +794,7 @@ cm_roam_switch_to_init(struct wlan_objmgr_pdev *pdev, enum roam_offload_state cur_state; uint8_t temp_vdev_id, roam_enabled_vdev_id; uint32_t roaming_bitmap; - bool dual_sta_roam_active; + bool dual_sta_roam_active, usr_disabled_roaming; QDF_STATUS status; struct wlan_objmgr_psoc *psoc = wlan_pdev_get_psoc(pdev); @@ -851,6 +877,18 @@ cm_roam_switch_to_init(struct wlan_objmgr_pdev *pdev, /* Set PCL before sending RSO start */ policy_mgr_set_pcl_for_existing_combo(psoc, PM_STA_MODE, vdev_id); + wlan_mlme_get_usr_disabled_roaming(psoc, &usr_disabled_roaming); + if (usr_disabled_roaming) { + status = + cm_roam_send_disable_config( + psoc, vdev_id, + WMI_VDEV_ROAM_11KV_CTRL_DISABLE_FW_TRIGGER_ROAMING); + + if (!QDF_IS_STATUS_SUCCESS(status)) + mlme_err("ROAM: fast roaming disable failed. status %d", + status); + } + return QDF_STATUS_SUCCESS; } 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 index e4230ba5bb..3e00822018 100644 --- 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 @@ -89,7 +89,7 @@ cm_roam_stop_req(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, uint8_t reason); /** - * wlan_cm_rso_fill_rssi_change_params - Fill roam scan rssi change parameters + * cm_roam_fill_rssi_change_params() - Fill roam scan rssi change parameters * @psoc: PSOC pointer * @vdev_id: vdev_id * @params: RSSI change parameters @@ -100,4 +100,16 @@ QDF_STATUS cm_roam_fill_rssi_change_params(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, struct wlan_roam_rssi_change_params *params); #endif + +/** + * cm_roam_send_disable_config() - Send roam module enable/disable cfg to fw + * @psoc: PSOC pointer + * @vdev_id: vdev id + * @cfg: roaming enable/disable cfg + * + * Return: QDF_STATUS + */ +QDF_STATUS +cm_roam_send_disable_config(struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id, uint8_t cfg); #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 1186d0d2f0..f104ad0d26 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 @@ -129,6 +129,17 @@ wlan_cm_roam_scan_offload_rsp(uint8_t vdev_id, uint8_t reason); */ void wlan_cm_send_beacon_miss(uint8_t vdev_id, int32_t rssi); +/** + * wlan_cm_roam_neighbor_proceed_with_handoff_req() - invoke host handover to + * new AP + * @vdev_id: vdev id + * + * This function gets called to invoke host handover to new AP + * + * Return: QDF_STATUS + */ +QDF_STATUS +wlan_cm_roam_neighbor_proceed_with_handoff_req(uint8_t vdev_id); #else static inline QDF_STATUS wlan_cm_enable_roaming_on_connected_sta(struct wlan_objmgr_pdev *pdev, diff --git a/components/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_roam_public_struct.h b/components/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_roam_public_struct.h index 16d4d0238d..3026d39c67 100644 --- a/components/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_roam_public_struct.h +++ b/components/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_roam_public_struct.h @@ -1207,6 +1207,7 @@ struct set_pcl_req { * @send_roam_start_req: TX ops function pointer to send roam start related * commands * @send_roam_abort: send roam abort + * @send_roam_disable_config: send roam disable config */ struct wlan_cm_roam_tx_ops { QDF_STATUS (*send_vdev_set_pcl_cmd)(struct wlan_objmgr_vdev *vdev, @@ -1230,6 +1231,8 @@ struct wlan_cm_roam_tx_ops { struct wlan_per_roam_config_req *req); QDF_STATUS (*send_roam_triggers)(struct wlan_objmgr_vdev *vdev, struct wlan_roam_triggers *req); + QDF_STATUS (*send_roam_disable_config)(struct wlan_objmgr_vdev *vdev, + struct roam_disable_cfg *req); #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 147d24b9ec..5f1db8cdfe 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 @@ -112,6 +112,7 @@ QDF_STATUS wlan_cm_tgt_send_roam_abort_req(struct wlan_objmgr_psoc *psoc, * wlan_cm_tgt_send_roam_per_config() - Send roam per config command to FW * @psoc: psoc pointer * @vdev_id: vdev id + * @req: per roam config parameter * * Return: QDF_STATUS */ @@ -131,5 +132,18 @@ QDF_STATUS wlan_cm_tgt_send_roam_triggers(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, struct wlan_roam_triggers *req); #endif + +/** + * wlan_cm_tgt_send_roam_disable_config() - Send roam disable config command + * to FW + * @psoc: psoc pointer + * @vdev_id: vdev id + * @req: roam disable config parameter + * + * Return: QDF_STATUS + */ +QDF_STATUS wlan_cm_tgt_send_roam_disable_config(struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id, + struct roam_disable_cfg *req); #endif #endif /* CM_TGT_IF_TX_API_H__ */ 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 index 1ee686465a..332438d409 100644 --- 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 @@ -35,6 +35,8 @@ ucfg_user_space_enable_disable_rso(struct wlan_objmgr_pdev *pdev, QDF_STATUS status; bool lfr_enabled; enum roam_offload_state state; + uint32_t set_val = 0; + enum roam_offload_state cur_state; /* * If the ini "FastRoamEnabled" is disabled, don't allow the @@ -50,6 +52,19 @@ ucfg_user_space_enable_disable_rso(struct wlan_objmgr_pdev *pdev, return QDF_STATUS_E_FAILURE; } + cur_state = mlme_get_roam_state(psoc, vdev_id); + if (cur_state == WLAN_ROAM_INIT) { + if (!is_fast_roam_enabled) + set_val = + WMI_VDEV_ROAM_11KV_CTRL_DISABLE_FW_TRIGGER_ROAMING; + + status = cm_roam_send_disable_config(psoc, vdev_id, set_val); + if (!QDF_IS_STATUS_SUCCESS(status)) + mlme_err("ROAM: update fast roaming failed, status: %d", + status); + } + wlan_mlme_set_usr_disabled_roaming(psoc, !is_fast_roam_enabled); + /* * Supplicant_disabled_roaming flag is the global flag to control * roam offload from supplicant. Driver cannot enable roaming if 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 4cf2f7450d..773b3e5fa2 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 @@ -358,6 +358,36 @@ QDF_STATUS wlan_cm_tgt_send_roam_triggers(struct wlan_objmgr_psoc *psoc, return status; } +#endif -#endif +QDF_STATUS wlan_cm_tgt_send_roam_disable_config(struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id, + struct roam_disable_cfg *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_disable_config) { + mlme_err("CM_RSO: vdev %d send_roam_disable_config is NULL", + vdev_id); + wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_NB_ID); + return QDF_STATUS_E_INVAL; + } + + status = roam_tx_ops.send_roam_disable_config(vdev, req); + if (QDF_IS_STATUS_ERROR(status)) + mlme_debug("CM_RSO: vdev %d fail to send roam disable config", + vdev_id); + + wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_NB_ID); + + return status; +} #endif diff --git a/core/sme/src/csr/csr_api_roam.c b/core/sme/src/csr/csr_api_roam.c index dab8415857..ffbc8bff74 100644 --- a/core/sme/src/csr/csr_api_roam.c +++ b/core/sme/src/csr/csr_api_roam.c @@ -20044,6 +20044,20 @@ wlan_cm_roam_scan_offload_rsp(uint8_t vdev_id, uint8_t reason) return status; } + +QDF_STATUS +wlan_cm_roam_neighbor_proceed_with_handoff_req(uint8_t vdev_id) +{ + 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; + } + + return csr_neighbor_roam_proceed_with_handoff_req(mac_ctx, vdev_id); +} #endif QDF_STATUS