diff --git a/components/mlme/core/src/wlan_mlme_main.c b/components/mlme/core/src/wlan_mlme_main.c index 56bbc7cabd44..264740508c0b 100644 --- a/components/mlme/core/src/wlan_mlme_main.c +++ b/components/mlme/core/src/wlan_mlme_main.c @@ -1606,6 +1606,7 @@ static void mlme_init_roam_offload_cfg(struct wlan_objmgr_psoc *psoc, lfr->idle_roam_band = cfg_get(psoc, CFG_LFR_IDLE_ROAM_BAND); lfr->sta_roam_disable = cfg_get(psoc, CFG_STA_DISABLE_ROAM); mlme_init_sae_single_pmk_cfg(psoc, lfr); + qdf_mem_zero(&lfr->roam_rt_stats, sizeof(lfr->roam_rt_stats)); } #else diff --git a/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h b/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h index f96673fd7b42..0deef4f6c5ae 100644 --- a/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h +++ b/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h @@ -1586,6 +1586,7 @@ struct fw_scan_channels { * @mawc_roam_enabled: Enable/Disable MAWC during roaming * @enable_fast_roam_in_concurrency:Enable LFR roaming on STA during concurrency * @vendor_btm_param: Vendor WTC roam trigger parameters + * @roam_rt_stats: Roam event stats vendor command parameters * @lfr3_roaming_offload: Enable/disable roam offload feature * @lfr3_dual_sta_roaming_enabled: Enable/Disable dual sta roaming offload * feature @@ -1704,6 +1705,7 @@ struct wlan_mlme_lfr_cfg { bool enable_fast_roam_in_concurrency; #ifdef WLAN_FEATURE_ROAM_OFFLOAD struct wlan_cm_roam_vendor_btm_params vendor_btm_param; + struct wlan_cm_roam_rt_stats roam_rt_stats; bool lfr3_roaming_offload; bool lfr3_dual_sta_roaming_enabled; bool enable_self_bss_roam; 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 c8c885f24a2f..bea08a478e7b 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 @@ -26,6 +26,7 @@ #include "wlan_mlme_api.h" #include "wlan_crypto_global_api.h" #include "wlan_mlme_main.h" +#include "wlan_cm_roam_api.h" static struct wmi_unified *target_if_cm_roam_get_wmi_handle_from_vdev(struct wlan_objmgr_vdev *vdev) @@ -74,15 +75,78 @@ target_if_cm_roam_send_vdev_set_pcl_cmd(struct wlan_objmgr_vdev *vdev, return wmi_unified_vdev_set_pcl_cmd(wmi_handle, ¶ms); } +/** + * target_if_roam_set_param() - set roam params in fw + * @wmi_handle: wmi handle + * @vdev_id: vdev id + * @param_id: parameter id + * @param_value: parameter value + * + * Return: QDF_STATUS_SUCCESS for success or error code + */ +static QDF_STATUS +target_if_roam_set_param(wmi_unified_t wmi_handle, uint8_t vdev_id, + uint32_t param_id, uint32_t param_value) +{ + struct vdev_set_params roam_param = {0}; + + roam_param.vdev_id = vdev_id; + roam_param.param_id = param_id; + roam_param.param_value = param_value; + + return wmi_unified_roam_set_param_send(wmi_handle, &roam_param); +} + +/** + * target_if_cm_roam_rt_stats_config() - Send enable/disable roam event stats + * commands to wmi + * @vdev: vdev object + * @vdev_id: vdev id + * @rstats_config: roam event stats config parameters + * + * Return: QDF_STATUS + */ +static QDF_STATUS +target_if_cm_roam_rt_stats_config(struct wlan_objmgr_vdev *vdev, + uint8_t vdev_id, uint8_t rstats_config) +{ + 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_EVENTS_CONFIG, + rstats_config); + + if (QDF_IS_STATUS_ERROR(status)) + target_if_err("Failed to set " + "WMI_ROAM_PARAM_ROAM_EVENTS_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; } #else static inline void target_if_cm_roam_register_lfr3_ops(struct wlan_cm_roam_tx_ops *tx_ops) {} + +static QDF_STATUS +target_if_cm_roam_rt_stats_config(struct wlan_objmgr_vdev *vdev, + uint8_t vdev_id, uint8_t rstats_config) +{ + return QDF_STATUS_E_NOSUPPORT; +} #endif /** @@ -842,6 +906,7 @@ target_if_cm_roam_send_start(struct wlan_objmgr_vdev *vdev, QDF_STATUS status = QDF_STATUS_SUCCESS; wmi_unified_t wmi_handle; struct wlan_objmgr_psoc *psoc; + uint8_t vdev_id; bool bss_load_enabled; wmi_handle = target_if_cm_roam_get_wmi_handle_from_vdev(vdev); @@ -962,6 +1027,11 @@ target_if_cm_roam_send_start(struct wlan_objmgr_vdev *vdev, target_if_cm_roam_idle_params(wmi_handle, ROAM_SCAN_OFFLOAD_START, &req->idle_params); + + vdev_id = wlan_vdev_get_id(vdev); + if (req->wlan_roam_rt_stats_config) + target_if_cm_roam_rt_stats_config(vdev, vdev_id, + req->wlan_roam_rt_stats_config); /* add other wmi commands */ end: return status; @@ -1179,6 +1249,11 @@ target_if_cm_roam_send_update_config(struct wlan_objmgr_vdev *vdev, wmi_handle, ROAM_SCAN_OFFLOAD_UPDATE_CFG, &req->idle_params); target_if_cm_roam_triggers(vdev, &req->roam_triggers); + + if (req->wlan_roam_rt_stats_config) + target_if_cm_roam_rt_stats_config( + vdev, vdev_id, + req->wlan_roam_rt_stats_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 056a5fdbe460..9dacc36f316d 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 @@ -237,6 +237,39 @@ cm_roam_idle_params(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, wlan_mlme_get_idle_roam_min_rssi(psoc, ¶ms->conn_ap_min_rssi); wlan_mlme_get_idle_roam_band(psoc, ¶ms->band); } + +/** + * cm_roam_send_rt_stats_config() - set roam stats parameters + * @psoc: psoc pointer + * @vdev_id: vdev id + * @param_value: roam stats param value + * + * This function is used to set roam event stats parameters + * + * Return: QDF_STATUS + */ +QDF_STATUS +cm_roam_send_rt_stats_config(struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id, uint8_t param_value) +{ + 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 = param_value; + + status = wlan_cm_tgt_send_roam_rt_stats_config(psoc, req); + if (QDF_IS_STATUS_ERROR(status)) + mlme_debug("fail to send roam rt stats config"); + + qdf_mem_free(req); + + return status; +} #else static inline void cm_roam_reason_vsie(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, @@ -488,6 +521,9 @@ cm_roam_start_req(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, /* fill from legacy through this API */ wlan_cm_roam_fill_start_req(psoc, vdev_id, start_req, reason); + start_req->wlan_roam_rt_stats_config = + wlan_cm_get_roam_rt_stats(psoc, ROAM_RT_STATS_ENABLE); + 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"); @@ -534,6 +570,9 @@ cm_roam_update_config_req(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, /* fill from legacy through this API */ wlan_cm_roam_fill_update_config_req(psoc, vdev_id, update_req, reason); + update_req->wlan_roam_rt_stats_config = + wlan_cm_get_roam_rt_stats(psoc, ROAM_RT_STATS_ENABLE); + 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 9175fef7e423..e05eb0b8d1de 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 @@ -102,6 +102,27 @@ cm_roam_fill_rssi_change_params(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, struct wlan_roam_rssi_change_params *params); #endif +#ifdef WLAN_FEATURE_ROAM_OFFLOAD +/** + * cm_roam_send_rt_stats_config() - Send roam event stats cfg value to FW + * @psoc: PSOC pointer + * @vdev_id: vdev id + * @param_value: roam stats enable/disable cfg + * + * Return: QDF_STATUS + */ +QDF_STATUS +cm_roam_send_rt_stats_config(struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id, uint8_t param_value); +#else +static inline QDF_STATUS +cm_roam_send_rt_stats_config(struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id, uint8_t param_value) +{ + return QDF_STATUS_E_NOSUPPORT; +} +#endif + /** * cm_roam_send_disable_config() - Send roam module enable/disable cfg to fw * @psoc: PSOC pointer 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 591208a4dbc6..478d6a477160 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 @@ -599,6 +599,28 @@ uint32_t wlan_cm_get_roam_states(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, enum roam_fail_params states); +/** + * wlan_cm_update_roam_rt_stats() - Store roam event stats command params + * @psoc: PSOC pointer + * @value: Value to update + * @stats: type of value to update + * + * Return: QDF_STATUS + */ +QDF_STATUS +wlan_cm_update_roam_rt_stats(struct wlan_objmgr_psoc *psoc, + uint8_t value, enum roam_rt_stats_params stats); + +/** + * wlan_cm_get_roam_rt_stats() - Get roam event stats value + * @psoc: PSOC pointer + * @stats: Get roam event command param for specific attribute + * + * Return: Roam events stats param value + */ +uint8_t +wlan_cm_get_roam_rt_stats(struct wlan_objmgr_psoc *psoc, + enum roam_rt_stats_params stats); #else static inline void wlan_cm_roam_activate_pcl_per_vdev(struct wlan_objmgr_psoc *psoc, @@ -702,5 +724,18 @@ wlan_cm_get_roam_states(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, return 0; } +static inline QDF_STATUS +wlan_cm_update_roam_rt_stats(struct wlan_objmgr_psoc *psoc, + uint8_t value, enum roam_rt_stats_params stats) +{ + return QDF_STATUS_SUCCESS; +} + +static inline uint8_t +wlan_cm_get_roam_rt_stats(struct wlan_objmgr_psoc *psoc, + enum roam_rt_stats_params stats) +{ + 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 d7d166f6e6b2..f306a9bc328d 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 @@ -1095,6 +1095,27 @@ struct wlan_roam_rssi_change_params { int32_t rssi_change_thresh; }; +/** + * struct wlan_cm_roam_rt_stats - Roam events stats update + * @roam_stats_enabled: set 1 if roam stats feature is enabled from userspace + * @roam_stats_wow_sent: set 1 if roam stats wow event is sent to FW + */ +struct wlan_cm_roam_rt_stats { + uint8_t roam_stats_enabled; + uint8_t roam_stats_wow_sent; +}; + +/** + * enum roam_rt_stats_params: different types of params to set or get roam + * events stats for the vdev + * @ROAM_RT_STATS_ENABLE: Roam stats feature if enable/not + * @ROAM_RT_STATS_SUSPEND_MODE_ENABLE: Roam stats wow event if sent to FW/not + */ +enum roam_rt_stats_params { + ROAM_RT_STATS_ENABLE, + ROAM_RT_STATS_SUSPEND_MODE_ENABLE, +}; + /** * struct wlan_roam_start_config - structure containing parameters for * roam start config @@ -1113,6 +1134,7 @@ struct wlan_roam_rssi_change_params { * @bss_load_config: bss load config * @disconnect_params: disconnect params * @idle_params: idle params + * @wlan_roam_rt_stats_config: roam events stats config */ struct wlan_roam_start_config { struct wlan_roam_offload_scan_rssi_params rssi_params; @@ -1131,6 +1153,7 @@ struct wlan_roam_start_config { struct wlan_roam_bss_load_config bss_load_config; struct wlan_roam_disconnect_params disconnect_params; struct wlan_roam_idle_params idle_params; + uint8_t wlan_roam_rt_stats_config; /* other wmi cmd structures */ }; @@ -1175,6 +1198,7 @@ struct wlan_roam_stop_config { * @disconnect_params: disconnect params * @idle_params: idle params * @roam_triggers: roam triggers parameters + * @wlan_roam_rt_stats_config: roam events stats config */ struct wlan_roam_update_config { struct wlan_roam_beacon_miss_cnt beacon_miss_cnt; @@ -1188,6 +1212,7 @@ struct wlan_roam_update_config { struct wlan_roam_disconnect_params disconnect_params; struct wlan_roam_idle_params idle_params; struct wlan_roam_triggers roam_triggers; + uint8_t wlan_roam_rt_stats_config; }; #if defined(WLAN_FEATURE_HOST_ROAM) || defined(WLAN_FEATURE_ROAM_OFFLOAD) @@ -1312,6 +1337,7 @@ struct set_pcl_req { * commands * @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 */ struct wlan_cm_roam_tx_ops { QDF_STATUS (*send_vdev_set_pcl_cmd)(struct wlan_objmgr_vdev *vdev, @@ -1336,6 +1362,10 @@ struct wlan_cm_roam_tx_ops { struct wlan_roam_triggers *req); QDF_STATUS (*send_roam_disable_config)(struct wlan_objmgr_vdev *vdev, struct roam_disable_cfg *req); +#ifdef WLAN_FEATURE_ROAM_OFFLOAD + QDF_STATUS (*send_roam_rt_stats_config)(struct wlan_objmgr_vdev *vdev, + uint8_t vdev_id, uint8_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 aed82c91b478..6272fb622c2f 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 @@ -155,6 +155,35 @@ ucfg_cm_update_roam_scan_scheme_bitmap(struct wlan_objmgr_psoc *psoc, return wlan_cm_update_roam_scan_scheme_bitmap(psoc, vdev_id, roam_scan_scheme_bitmap); } + +static inline QDF_STATUS +ucfg_cm_update_roam_rt_stats(struct wlan_objmgr_psoc *psoc, + uint8_t value, enum roam_rt_stats_params stats) +{ + return wlan_cm_update_roam_rt_stats(psoc, value, stats); +} + +static inline uint8_t +ucfg_cm_get_roam_rt_stats(struct wlan_objmgr_psoc *psoc, + enum roam_rt_stats_params stats) +{ + return wlan_cm_get_roam_rt_stats(psoc, stats); +} + +/** + * ucfg_cm_roam_send_rt_stats_config() - Enable/Disable Roam event stats from FW + * @pdev: Pointer to pdev + * @vdev_id: vdev id + * @param_value: Value set based on the userspace attributes. + * param_value - 0: if configure attribute is 0 + * 1: if configure is 1 and suspend_state is not set + * 3: if configure is 1 and suspend_state is set + * + * Return: QDF_STATUS + */ +QDF_STATUS +ucfg_cm_roam_send_rt_stats_config(struct wlan_objmgr_pdev *pdev, + uint8_t vdev_id, uint8_t param_value); #else static inline QDF_STATUS ucfg_cm_update_roam_scan_scheme_bitmap(struct wlan_objmgr_psoc *psoc, @@ -163,4 +192,25 @@ ucfg_cm_update_roam_scan_scheme_bitmap(struct wlan_objmgr_psoc *psoc, { return QDF_STATUS_SUCCESS; } + +static inline QDF_STATUS +ucfg_cm_update_roam_rt_stats(struct wlan_objmgr_psoc *psoc, + uint8_t value, enum roam_rt_stats_params stats) +{ + return QDF_STATUS_SUCCESS; +} + +static inline uint8_t +ucfg_cm_get_roam_rt_stats(struct wlan_objmgr_psoc *psoc, + enum roam_rt_stats_params stats) +{ + return 0; +} + +static inline QDF_STATUS +ucfg_cm_roam_send_rt_stats_config(struct wlan_objmgr_pdev *pdev, + uint8_t vdev_id, uint8_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 43c867d7f5f6..f814c4f6b626 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 @@ -36,6 +36,17 @@ QDF_STATUS wlan_cm_roam_send_set_vdev_pcl(struct wlan_objmgr_psoc *psoc, struct set_pcl_req *pcl_req); + +/** + * wlan_cm_tgt_send_roam_rt_stats_config() - Send roam event stats config + * command to FW + * @psoc: psoc pointer + * @req: roam stats config parameter + * + * Return: QDF_STATUS + */ +QDF_STATUS wlan_cm_tgt_send_roam_rt_stats_config(struct wlan_objmgr_psoc *psoc, + struct roam_disable_cfg *req); #else static inline QDF_STATUS wlan_cm_roam_send_set_vdev_pcl(struct wlan_objmgr_psoc *psoc, @@ -43,6 +54,13 @@ wlan_cm_roam_send_set_vdev_pcl(struct wlan_objmgr_psoc *psoc, { return QDF_STATUS_E_FAILURE; } + +static inline QDF_STATUS +wlan_cm_tgt_send_roam_rt_stats_config(struct wlan_objmgr_psoc *psoc, + struct roam_disable_cfg *req) +{ + 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 e298d4e6c350..1d7f07c9ce73 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 @@ -818,4 +818,55 @@ uint32_t wlan_cm_get_roam_states(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, return roam_states; } + +QDF_STATUS +wlan_cm_update_roam_rt_stats(struct wlan_objmgr_psoc *psoc, + uint8_t value, enum roam_rt_stats_params stats) +{ + struct wlan_mlme_psoc_ext_obj *mlme_obj; + struct wlan_cm_roam_rt_stats *roam_rt_stats; + + mlme_obj = mlme_get_psoc_ext_obj(psoc); + if (!mlme_obj) { + mlme_legacy_err("Failed to get MLME Obj"); + return QDF_STATUS_E_FAILURE; + } + + roam_rt_stats = &mlme_obj->cfg.lfr.roam_rt_stats; + + switch (stats) { + case ROAM_RT_STATS_ENABLE: + roam_rt_stats->roam_stats_enabled = value; + break; + default: + break; + } + + return QDF_STATUS_SUCCESS; +} + +uint8_t wlan_cm_get_roam_rt_stats(struct wlan_objmgr_psoc *psoc, + enum roam_rt_stats_params stats) +{ + struct wlan_mlme_psoc_ext_obj *mlme_obj; + struct wlan_cm_roam_rt_stats *roam_rt_stats; + uint8_t rstats_value = 0; + + mlme_obj = mlme_get_psoc_ext_obj(psoc); + if (!mlme_obj) { + mlme_legacy_err("Failed to get MLME Obj"); + return QDF_STATUS_E_FAILURE; + } + + roam_rt_stats = &mlme_obj->cfg.lfr.roam_rt_stats; + switch (stats) { + case ROAM_RT_STATS_ENABLE: + rstats_value = roam_rt_stats->roam_stats_enabled; + break; + default: + break; + } + + return rstats_value; +} #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 e765a6c0615d..630deff30cf4 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 @@ -127,3 +127,14 @@ QDF_STATUS ucfg_cm_abort_roam_scan(struct wlan_objmgr_pdev *pdev, return status; } + +#ifdef WLAN_FEATURE_ROAM_OFFLOAD +QDF_STATUS +ucfg_cm_roam_send_rt_stats_config(struct wlan_objmgr_pdev *pdev, + uint8_t vdev_id, uint8_t param_value) +{ + struct wlan_objmgr_psoc *psoc = wlan_pdev_get_psoc(pdev); + + return cm_roam_send_rt_stats_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 8b7c322cb5b1..76ecef7a8baf 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 @@ -154,6 +154,37 @@ end: return status; } + +QDF_STATUS wlan_cm_tgt_send_roam_rt_stats_config(struct wlan_objmgr_psoc *psoc, + 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, req->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_rt_stats_config) { + mlme_err("vdev %d send_roam_rt_stats_config is NULL", + req->vdev_id); + wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_NB_ID); + return QDF_STATUS_E_INVAL; + } + + status = roam_tx_ops->send_roam_rt_stats_config(vdev, + req->vdev_id, req->cfg); + if (QDF_IS_STATUS_ERROR(status)) + mlme_debug("vdev %d fail to send roam rt stats config", + req->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 be03aa5671d3..f064a28e9504 100644 --- a/core/hdd/src/wlan_hdd_cfg80211.c +++ b/core/hdd/src/wlan_hdd_cfg80211.c @@ -1703,6 +1703,12 @@ static const struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] = FEATURE_TWT_VENDOR_EVENTS #endif FEATURE_CFR_DATA_VENDOR_EVENTS +#ifdef WLAN_FEATURE_ROAM_OFFLOAD + [QCA_NL80211_VENDOR_SUBCMD_ROAM_EVENTS_INDEX] = { + .vendor_id = QCA_NL80211_VENDOR_ID, + .subcmd = QCA_NL80211_VENDOR_SUBCMD_ROAM_EVENTS, + }, +#endif }; /** @@ -15306,6 +15312,133 @@ err: } #endif +#ifdef WLAN_FEATURE_ROAM_OFFLOAD +/** + * enum roam_stats_set_params - Different types of params to set the roam stats + * @ROAM_RT_STATS_DISABLED: Roam stats feature disabled + * @ROAM_RT_STATS_ENABLED: Roam stats feature enabled + * @ROAM_RT_STATS_ENABLED_IN_SUSPEND_MODE: Roam stats enabled in suspend mode + */ +enum roam_stats_set_params { + ROAM_RT_STATS_DISABLED = 0, + ROAM_RT_STATS_ENABLED = 1, + ROAM_RT_STATS_ENABLED_IN_SUSPEND_MODE = 2, +}; + +#define EVENTS_CONFIGURE QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CONFIGURE +#define SUSPEND_STATE QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_SUSPEND_STATE + +static const struct nla_policy +set_roam_events_policy[QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_MAX + 1] = { + [QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CONFIGURE] = {.type = NLA_U8}, + [QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_SUSPEND_STATE] = {.type = NLA_FLAG}, +}; + +/** + * __wlan_hdd_cfg80211_set_roam_events() - set roam stats + * @wiphy: wiphy pointer + * @wdev: pointer to struct wireless_dev + * @data: pointer to incoming NL vendor data + * @data_len: length of @data + * + * Return: 0 on success; error number otherwise. + */ +static int __wlan_hdd_cfg80211_set_roam_events(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, + int data_len) +{ + struct hdd_context *hdd_ctx = wiphy_priv(wiphy); + struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(wdev->netdev); + struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_MAX + 1]; + QDF_STATUS status; + int ret; + uint8_t config, state, param = 0; + + ret = wlan_hdd_validate_context(hdd_ctx); + if (ret != 0) { + hdd_err("Invalid hdd_ctx"); + return ret; + } + + ret = hdd_validate_adapter(adapter); + if (ret != 0) { + hdd_err("Invalid adapter"); + return ret; + } + + if (adapter->device_mode != QDF_STA_MODE) { + hdd_err("STATS supported in only STA mode!"); + return -EINVAL; + } + + if (wlan_cfg80211_nla_parse(tb, QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_MAX, + data, data_len, set_roam_events_policy)) { + hdd_err("Invalid ATTR"); + return -EINVAL; + } + + if (!tb[EVENTS_CONFIGURE]) { + hdd_err("roam events configure not present"); + return -EINVAL; + } + + config = nla_get_u8(tb[EVENTS_CONFIGURE]); + hdd_debug("roam stats configured: %d", config); + + if (!tb[SUSPEND_STATE]) { + hdd_debug("suspend state not present"); + param = config ? ROAM_RT_STATS_ENABLED : ROAM_RT_STATS_DISABLED; + } else if (config == ROAM_RT_STATS_ENABLED) { + state = nla_get_flag(tb[SUSPEND_STATE]); + hdd_debug("Suspend state configured: %d", state); + param = ROAM_RT_STATS_ENABLED | + ROAM_RT_STATS_ENABLED_IN_SUSPEND_MODE; + } + + hdd_debug("roam events param: %d", param); + ucfg_cm_update_roam_rt_stats(hdd_ctx->psoc, + param, ROAM_RT_STATS_ENABLE); + + status = ucfg_cm_roam_send_rt_stats_config(hdd_ctx->pdev, + adapter->vdev_id, param); + + return qdf_status_to_os_return(status); +} + +#undef EVENTS_CONFIGURE +#undef SUSPEND_STATE + +/** + * wlan_hdd_cfg80211_set_roam_events() - set roam stats + * @wiphy: wiphy pointer + * @wdev: pointer to struct wireless_dev + * @data: pointer to incoming NL vendor data + * @data_len: length of @data + * + * Return: 0 on success; error number otherwise. + */ +static int wlan_hdd_cfg80211_set_roam_events(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, + int data_len) +{ + int errno; + struct osif_vdev_sync *vdev_sync; + + errno = osif_vdev_sync_op_start(wdev->netdev, &vdev_sync); + if (errno) + return errno; + + errno = __wlan_hdd_cfg80211_set_roam_events(wiphy, wdev, + data, data_len); + + osif_vdev_sync_op_stop(vdev_sync); + + return errno; +} +#endif + /** * __wlan_hdd_cfg80211_get_chain_rssi() - get chain rssi * @wiphy: wiphy pointer @@ -16398,6 +16531,19 @@ const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] = { #ifdef WLAN_FEATURE_PKT_CAPTURE FEATURE_MONITOR_MODE_VENDOR_COMMANDS #endif + +#ifdef WLAN_FEATURE_ROAM_OFFLOAD + { + .info.vendor_id = QCA_NL80211_VENDOR_ID, + .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_ROAM_EVENTS, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | + WIPHY_VENDOR_CMD_NEED_NETDEV | + WIPHY_VENDOR_CMD_NEED_RUNNING, + .doit = wlan_hdd_cfg80211_set_roam_events, + vendor_command_policy(set_roam_events_policy, + QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_MAX) + }, +#endif }; struct hdd_context *hdd_cfg80211_wiphy_alloc(void)