From dce2e3a8a182580af1660451fbecdb86e7d56073 Mon Sep 17 00:00:00 2001 From: Srikanth Marepalli Date: Tue, 22 Nov 2022 17:35:02 +0530 Subject: [PATCH] qcacld-3.0: Add vendor command attribute for roam hand-off delay User can configure roam hand-off delay value using the new vendor attribute introduced as part roam vendor command. This change gets the configured value and sends it to firmware. And firmware delays the roam Hand-off (in msec) by the specified duration to receive pending RX frames from the current BSS. Change-Id: Ic328c077cba06532ee8ffed12cde072c816b92e0 CRs-Fixed: 3329964 --- .../dispatcher/inc/wlan_mlme_public_struct.h | 2 + .../src/target_if_cm_roam_offload.c | 50 +++++++++++++++++++ .../core/src/wlan_cm_roam_offload.c | 21 ++++++++ .../core/src/wlan_cm_roam_offload.h | 22 ++++++++ .../dispatcher/inc/wlan_cm_roam_api.h | 27 ++++++++++ .../inc/wlan_cm_roam_public_struct.h | 8 +++ .../dispatcher/inc/wlan_cm_roam_ucfg_api.h | 20 ++++++++ .../dispatcher/inc/wlan_cm_tgt_if_tx_api.h | 21 ++++++++ .../dispatcher/src/wlan_cm_roam_api.c | 27 ++++++++++ .../dispatcher/src/wlan_cm_roam_ucfg_api.c | 10 ++++ .../dispatcher/src/wlan_cm_tgt_if_tx_api.c | 31 ++++++++++++ core/hdd/src/wlan_hdd_cfg80211.c | 21 ++++++++ 12 files changed, 260 insertions(+) diff --git a/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h b/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h index 328d3edf40f4..d919392c992d 100644 --- a/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h +++ b/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h @@ -1722,6 +1722,7 @@ struct fw_scan_channels { * @sae_single_pmk_feature_enabled: Contains value of ini * sae_single_pmk_feature_enabled * @enable_ft_over_ds: Flag to enable/disable FT-over-DS + * @roam_ho_delay_config: Roam HO delay value */ struct wlan_mlme_lfr_cfg { bool mawc_roam_enabled; @@ -1840,6 +1841,7 @@ struct wlan_mlme_lfr_cfg { bool sae_single_pmk_feature_enabled; #endif bool enable_ft_over_ds; + uint16_t roam_ho_delay_config; }; /** 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 f2f046b22c48..8ca5ec7aae17 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 @@ -1,5 +1,6 @@ /* * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. 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 @@ -130,11 +131,44 @@ target_if_cm_roam_rt_stats_config(struct wlan_objmgr_vdev *vdev, return status; } +/** + * target_if_cm_roam_ho_delay_config() - Send roam HO delay value to wmi + * @vdev: vdev object + * @vdev_id: vdev id + * @roam_ho_delay: roam hand-off delay value + * + * Return: QDF_STATUS + */ +static QDF_STATUS +target_if_cm_roam_ho_delay_config(struct wlan_objmgr_vdev *vdev, + uint8_t vdev_id, uint16_t roam_ho_delay) +{ + QDF_STATUS status = QDF_STATUS_E_FAILURE; + wmi_unified_t wmi_handle; + + wmi_handle = target_if_cm_roam_get_wmi_handle_from_vdev(vdev); + if (!wmi_handle) + return status; + + status = target_if_roam_set_param( + wmi_handle, + vdev_id, + WMI_ROAM_PARAM_ROAM_HO_DELAY_RUNTIME_CONFIG, + roam_ho_delay); + + if (QDF_IS_STATUS_ERROR(status)) + target_if_err("Failed to set " + "WMI_ROAM_PARAM_ROAM_HO_DELAY_RUNTIME_CONFIG"); + + return status; +} + static void target_if_cm_roam_register_lfr3_ops(struct wlan_cm_roam_tx_ops *tx_ops) { tx_ops->send_vdev_set_pcl_cmd = target_if_cm_roam_send_vdev_set_pcl_cmd; tx_ops->send_roam_rt_stats_config = target_if_cm_roam_rt_stats_config; + tx_ops->send_roam_ho_delay_config = target_if_cm_roam_ho_delay_config; } #else static inline void @@ -147,6 +181,13 @@ target_if_cm_roam_rt_stats_config(struct wlan_objmgr_vdev *vdev, { return QDF_STATUS_E_NOSUPPORT; } + +static QDF_STATUS +target_if_cm_roam_ho_delay_config(struct wlan_objmgr_vdev *vdev, + uint8_t vdev_id, uint16_t roam_ho_delay) +{ + return QDF_STATUS_E_NOSUPPORT; +} #endif /** @@ -1032,6 +1073,10 @@ target_if_cm_roam_send_start(struct wlan_objmgr_vdev *vdev, if (req->wlan_roam_rt_stats_config) target_if_cm_roam_rt_stats_config(vdev, vdev_id, req->wlan_roam_rt_stats_config); + + if (req->wlan_roam_ho_delay_config) + target_if_cm_roam_ho_delay_config( + vdev, vdev_id, req->wlan_roam_ho_delay_config); /* add other wmi commands */ end: return status; @@ -1254,6 +1299,11 @@ target_if_cm_roam_send_update_config(struct wlan_objmgr_vdev *vdev, target_if_cm_roam_rt_stats_config( vdev, vdev_id, req->wlan_roam_rt_stats_config); + + if (req->wlan_roam_ho_delay_config) + target_if_cm_roam_ho_delay_config( + vdev, vdev_id, + req->wlan_roam_ho_delay_config); } end: return status; 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 d1618afbcce8..2fa20d946d65 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 @@ -272,6 +272,21 @@ cm_roam_send_rt_stats_config(struct wlan_objmgr_psoc *psoc, return status; } + +QDF_STATUS +cm_roam_send_ho_delay_config(struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id, uint16_t param_value) +{ + QDF_STATUS status; + + wlan_cm_roam_set_ho_delay_config(psoc, param_value); + status = wlan_cm_tgt_send_roam_ho_delay_config(psoc, + vdev_id, param_value); + if (QDF_IS_STATUS_ERROR(status)) + mlme_debug("fail to send roam HO delay config"); + + return status; +} #else static inline void cm_roam_reason_vsie(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, @@ -526,6 +541,9 @@ cm_roam_start_req(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, start_req->wlan_roam_rt_stats_config = wlan_cm_get_roam_rt_stats(psoc, ROAM_RT_STATS_ENABLE); + start_req->wlan_roam_ho_delay_config = + wlan_cm_roam_get_ho_delay_config(psoc); + 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"); @@ -575,6 +593,9 @@ cm_roam_update_config_req(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, update_req->wlan_roam_rt_stats_config = wlan_cm_get_roam_rt_stats(psoc, ROAM_RT_STATS_ENABLE); + update_req->wlan_roam_ho_delay_config = + wlan_cm_roam_get_ho_delay_config(psoc); + status = wlan_cm_tgt_send_roam_update_req(psoc, vdev_id, update_req); if (QDF_IS_STATUS_ERROR(status)) mlme_debug("fail to send update config"); 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 e05eb0b8d1de..6fd45b0e987d 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 @@ -1,5 +1,6 @@ /* * Copyright (c) 2012-2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. 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 @@ -114,6 +115,20 @@ cm_roam_fill_rssi_change_params(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, QDF_STATUS cm_roam_send_rt_stats_config(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, uint8_t param_value); + +/** + * cm_roam_send_ho_delay_config() - Send HO delay value to FW to delay + * hand-off (in msec) by the specified duration to receive pending rx frames + * from current BSS. + * @psoc: PSOC pointer + * @vdev_id: vdev id + * @param_value: HO delay value + * + * Return: QDF_STATUS + */ +QDF_STATUS +cm_roam_send_ho_delay_config(struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id, uint16_t param_value); #else static inline QDF_STATUS cm_roam_send_rt_stats_config(struct wlan_objmgr_psoc *psoc, @@ -121,6 +136,13 @@ cm_roam_send_rt_stats_config(struct wlan_objmgr_psoc *psoc, { return QDF_STATUS_E_NOSUPPORT; } + +static inline QDF_STATUS +cm_roam_send_ho_delay_config(struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id, uint16_t param_value) +{ + return QDF_STATUS_E_NOSUPPORT; +} #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 478d6a477160..6551c3b40193 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 @@ -1,5 +1,6 @@ /* * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. 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 @@ -621,6 +622,26 @@ wlan_cm_update_roam_rt_stats(struct wlan_objmgr_psoc *psoc, uint8_t wlan_cm_get_roam_rt_stats(struct wlan_objmgr_psoc *psoc, enum roam_rt_stats_params stats); + +/** + * wlan_cm_roam_set_ho_delay_config() - Set roam hand-off delay + * @psoc: PSOC pointer + * @roam_ho_delay: vendor configured roam HO delay value + * + * Return: none + */ +void +wlan_cm_roam_set_ho_delay_config(struct wlan_objmgr_psoc *psoc, + uint16_t roam_ho_delay); + +/** + * wlan_cm_roam_get_ho_delay_config() - Get roam hand-off delay + * @psoc: PSOC pointer + * + * Return: Roam HO delay value + */ +uint16_t +wlan_cm_roam_get_ho_delay_config(struct wlan_objmgr_psoc *psoc); #else static inline void wlan_cm_roam_activate_pcl_per_vdev(struct wlan_objmgr_psoc *psoc, @@ -737,5 +758,11 @@ wlan_cm_get_roam_rt_stats(struct wlan_objmgr_psoc *psoc, { return 0; } + +static inline uint16_t +wlan_cm_roam_get_ho_delay_config(struct wlan_objmgr_psoc *psoc) +{ + return 0; +} #endif /* FEATURE_ROAM_OFFLOAD */ #endif /* WLAN_CM_ROAM_API_H__ */ 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 058b92f4f5db..f0d99dbb487e 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 @@ -1168,6 +1168,7 @@ enum roam_rt_stats_params { * @disconnect_params: disconnect params * @idle_params: idle params * @wlan_roam_rt_stats_config: roam events stats config + * @wlan_roam_ho_delay_config: roam HO delay value */ struct wlan_roam_start_config { struct wlan_roam_offload_scan_rssi_params rssi_params; @@ -1187,6 +1188,7 @@ struct wlan_roam_start_config { struct wlan_roam_disconnect_params disconnect_params; struct wlan_roam_idle_params idle_params; uint8_t wlan_roam_rt_stats_config; + uint16_t wlan_roam_ho_delay_config; /* other wmi cmd structures */ }; @@ -1232,6 +1234,7 @@ struct wlan_roam_stop_config { * @idle_params: idle params * @roam_triggers: roam triggers parameters * @wlan_roam_rt_stats_config: roam events stats config + * @wlan_roam_ho_delay_config: roam HO delay value */ struct wlan_roam_update_config { struct wlan_roam_beacon_miss_cnt beacon_miss_cnt; @@ -1246,6 +1249,7 @@ struct wlan_roam_update_config { struct wlan_roam_idle_params idle_params; struct wlan_roam_triggers roam_triggers; uint8_t wlan_roam_rt_stats_config; + uint16_t wlan_roam_ho_delay_config; }; #if defined(WLAN_FEATURE_HOST_ROAM) || defined(WLAN_FEATURE_ROAM_OFFLOAD) @@ -1371,6 +1375,7 @@ struct set_pcl_req { * @send_roam_abort: send roam abort * @send_roam_disable_config: send roam disable config * @send_roam_rt_stats_config: Send roam events vendor command param value to FW + * @send_roam_ho_delay_config: Send roam Hand-off delay value to FW */ struct wlan_cm_roam_tx_ops { QDF_STATUS (*send_vdev_set_pcl_cmd)(struct wlan_objmgr_vdev *vdev, @@ -1398,6 +1403,9 @@ struct wlan_cm_roam_tx_ops { #ifdef WLAN_FEATURE_ROAM_OFFLOAD QDF_STATUS (*send_roam_rt_stats_config)(struct wlan_objmgr_vdev *vdev, uint8_t vdev_id, uint8_t value); + QDF_STATUS (*send_roam_ho_delay_config)(struct wlan_objmgr_vdev *vdev, + uint8_t vdev_id, + uint16_t value); #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 index 6272fb622c2f..7bc847bd699f 100644 --- 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 @@ -1,5 +1,6 @@ /* * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. 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 @@ -184,6 +185,18 @@ ucfg_cm_get_roam_rt_stats(struct wlan_objmgr_psoc *psoc, QDF_STATUS ucfg_cm_roam_send_rt_stats_config(struct wlan_objmgr_pdev *pdev, uint8_t vdev_id, uint8_t param_value); + +/** + * ucfg_cm_roam_send_ho_delay_config() - Send the HO delay value to Firmware + * @pdev: Pointer to pdev + * @vdev_id: vdev id + * @param_value: Value will be from range 20 to 1000 in msec. + * + * Return: QDF_STATUS + */ +QDF_STATUS +ucfg_cm_roam_send_ho_delay_config(struct wlan_objmgr_pdev *pdev, + uint8_t vdev_id, uint16_t param_value); #else static inline QDF_STATUS ucfg_cm_update_roam_scan_scheme_bitmap(struct wlan_objmgr_psoc *psoc, @@ -213,4 +226,11 @@ ucfg_cm_roam_send_rt_stats_config(struct wlan_objmgr_pdev *pdev, { return QDF_STATUS_SUCCESS; } + +static inline QDF_STATUS +ucfg_cm_roam_send_ho_delay_config(struct wlan_objmgr_pdev *pdev, + uint8_t vdev_id, uint16_t param_value) +{ + return QDF_STATUS_SUCCESS; +} #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 f814c4f6b626..781b1f8a604c 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 @@ -1,5 +1,6 @@ /* * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. 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 @@ -47,6 +48,19 @@ wlan_cm_roam_send_set_vdev_pcl(struct wlan_objmgr_psoc *psoc, */ QDF_STATUS wlan_cm_tgt_send_roam_rt_stats_config(struct wlan_objmgr_psoc *psoc, struct roam_disable_cfg *req); + +/** + * wlan_cm_tgt_send_roam_ho_delay_config() - Send roam HO delay config command + * to FW + * @psoc: psoc pointer + * @vdev_id: vdev id + * @roam_ho_delay: roam hand-off delay value + * + * Return: QDF_STATUS + */ +QDF_STATUS wlan_cm_tgt_send_roam_ho_delay_config(struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id, + uint16_t roam_ho_delay); #else static inline QDF_STATUS wlan_cm_roam_send_set_vdev_pcl(struct wlan_objmgr_psoc *psoc, @@ -61,6 +75,13 @@ wlan_cm_tgt_send_roam_rt_stats_config(struct wlan_objmgr_psoc *psoc, { return QDF_STATUS_E_FAILURE; } + +static inline QDF_STATUS +wlan_cm_tgt_send_roam_ho_delay_config(struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id, uint16_t roam_ho_delay) +{ + return QDF_STATUS_E_FAILURE; +} #endif /* WLAN_FEATURE_ROAM_OFFLOAD */ #if defined(WLAN_FEATURE_HOST_ROAM) || defined(WLAN_FEATURE_ROAM_OFFLOAD) 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 b542d4d2b24f..84f8eba88ffc 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 @@ -889,4 +889,31 @@ uint8_t wlan_cm_get_roam_rt_stats(struct wlan_objmgr_psoc *psoc, return rstats_value; } + +void +wlan_cm_roam_set_ho_delay_config(struct wlan_objmgr_psoc *psoc, + uint16_t roam_ho_delay) +{ + struct wlan_mlme_psoc_ext_obj *mlme_obj; + + mlme_obj = mlme_get_psoc_ext_obj(psoc); + if (!mlme_obj) + return; + + mlme_obj->cfg.lfr.roam_ho_delay_config = roam_ho_delay; +} + +uint16_t +wlan_cm_roam_get_ho_delay_config(struct wlan_objmgr_psoc *psoc) +{ + struct wlan_mlme_psoc_ext_obj *mlme_obj; + + mlme_obj = mlme_get_psoc_ext_obj(psoc); + if (!mlme_obj) { + mlme_legacy_err("Failed to get MLME Obj"); + return 0; + } + + return mlme_obj->cfg.lfr.roam_ho_delay_config; +} #endif 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 630deff30cf4..d2709aa2c136 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 @@ -1,5 +1,6 @@ /* * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. 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 @@ -137,4 +138,13 @@ ucfg_cm_roam_send_rt_stats_config(struct wlan_objmgr_pdev *pdev, return cm_roam_send_rt_stats_config(psoc, vdev_id, param_value); } + +QDF_STATUS +ucfg_cm_roam_send_ho_delay_config(struct wlan_objmgr_pdev *pdev, + uint8_t vdev_id, uint16_t param_value) +{ + struct wlan_objmgr_psoc *psoc = wlan_pdev_get_psoc(pdev); + + return cm_roam_send_ho_delay_config(psoc, vdev_id, param_value); +} #endif /* WLAN_FEATURE_ROAM_OFFLOAD */ 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 7b556f9b0d9c..fe50d993fa2a 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 @@ -202,6 +202,37 @@ QDF_STATUS wlan_cm_tgt_send_roam_rt_stats_config(struct wlan_objmgr_psoc *psoc, return status; } + +QDF_STATUS wlan_cm_tgt_send_roam_ho_delay_config(struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id, + uint16_t roam_ho_delay) +{ + 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 = wlan_cm_roam_get_tx_ops_from_vdev(vdev); + if (!roam_tx_ops || !roam_tx_ops->send_roam_ho_delay_config) { + mlme_err("vdev %d send_roam_ho_delay_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_ho_delay_config(vdev, vdev_id, + roam_ho_delay); + if (QDF_IS_STATUS_ERROR(status)) + mlme_debug("vdev %d fail to send roam HO delay config", + vdev_id); + + wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_NB_ID); + + return status; +} #endif #if defined(WLAN_FEATURE_HOST_ROAM) || defined(WLAN_FEATURE_ROAM_OFFLOAD) diff --git a/core/hdd/src/wlan_hdd_cfg80211.c b/core/hdd/src/wlan_hdd_cfg80211.c index 08b6ed22fc77..486cd4f52528 100644 --- a/core/hdd/src/wlan_hdd_cfg80211.c +++ b/core/hdd/src/wlan_hdd_cfg80211.c @@ -4645,6 +4645,7 @@ roam_control_policy[QCA_ATTR_ROAM_CONTROL_MAX + 1] = { .type = NLA_U32}, [QCA_ATTR_ROAM_CONTROL_USER_REASON] = {.type = NLA_U32}, [QCA_ATTR_ROAM_CONTROL_SCAN_SCHEME_TRIGGERS] = {.type = NLA_U32}, + [QCA_ATTR_ROAM_CONTROL_HO_DELAY_FOR_RX] = {.type = NLA_U16}, }; /** @@ -5036,6 +5037,10 @@ hdd_send_roam_scan_period_to_sme(struct hdd_context *hdd_ctx, return status; } +/* Roam Hand-off delay range is 20 to 1000 msec */ +#define MIN_ROAM_HO_DELAY 20 +#define MAX_ROAM_HO_DELAY 1000 + /** * hdd_set_roam_with_control_config() - Set roam control configuration * @hdd_ctx: HDD context @@ -5229,6 +5234,22 @@ hdd_set_roam_with_control_config(struct hdd_context *hdd_ctx, sme_send_vendor_btm_params(hdd_ctx->mac_handle, vdev_id); } + attr = tb2[QCA_ATTR_ROAM_CONTROL_HO_DELAY_FOR_RX]; + if (attr) { + value = nla_get_u16(attr); + if (value < MIN_ROAM_HO_DELAY || value > MAX_ROAM_HO_DELAY) { + hdd_err("Invalid roam HO delay value: %d", value); + return -EINVAL; + } + + hdd_debug("Received roam HO delay value: %d", value); + + status = ucfg_cm_roam_send_ho_delay_config(hdd_ctx->pdev, + vdev_id, value); + if (QDF_IS_STATUS_ERROR(status)) + hdd_err("failed to set hand-off delay"); + } + return qdf_status_to_os_return(status); }