diff --git a/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h b/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h index cfd547a5ee..110b18136e 100644 --- a/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h +++ b/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h @@ -2289,12 +2289,16 @@ struct wlan_mlme_sae_single_pmk { * @scan: Roam scan related data structure. * @result: Roam result parameters. * @data_11kv: Neighbor report/BTM parameters. + * @btm_rsp: BTM response information + * @roam_init_info: Roam initial info */ struct mlme_roam_debug_info { struct wmi_roam_trigger_info trigger; struct wmi_roam_scan_data scan; struct wmi_roam_result result; struct wmi_neighbor_report_data data_11kv; + struct roam_btm_response_data btm_rsp; + struct roam_initial_data roam_init_info; }; /** diff --git a/components/mlme/dispatcher/src/wlan_mlme_api.c b/components/mlme/dispatcher/src/wlan_mlme_api.c index 40fcbf25a3..507171ec43 100644 --- a/components/mlme/dispatcher/src/wlan_mlme_api.c +++ b/components/mlme/dispatcher/src/wlan_mlme_api.c @@ -3599,6 +3599,8 @@ char *mlme_get_roam_trigger_str(uint32_t roam_scan_trigger) return "STA KICKOUT"; case WMI_ROAM_TRIGGER_REASON_ESS_RSSI: return "ESS RSSI"; + case WMI_ROAM_TRIGGER_REASON_WTC_BTM: + return "WTC BTM"; case WMI_ROAM_TRIGGER_REASON_NONE: return "NONE"; default: @@ -3815,6 +3817,8 @@ char *mlme_get_sub_reason_str(uint32_t sub_reason) return "LOW RSSI PERIODIC SCAN"; case WMI_ROAM_TRIGGER_SUB_REASON_CU_PERIODIC: return "CU PERIODIC SCAN"; + case WMI_ROAM_TRIGGER_SUB_REASCON_PERIODIC_TIMER_AFTER_INACTIVITY: + return "PERIODIC TIMER AFTER INACTIVITY"; default: return "NONE"; } 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 61e4d0b6a7..cbd6b1f86d 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 @@ -29,6 +29,34 @@ #include "wlan_mlme_api.h" #ifdef WLAN_FEATURE_ROAM_OFFLOAD +/** + * wlan_cm_roam_extract_btm_response() - Extract BTM rsp stats + * @wmi: wmi handle + * @evt_buf: Pointer to the event buffer + * @dst: Pointer to destination structure to fill data + * @idx: TLV id + * + * Return: QDF_STATUS + */ +QDF_STATUS +wlan_cm_roam_extract_btm_response(wmi_unified_t wmi, void *evt_buf, + struct roam_btm_response_data *dst, + uint8_t idx); + +/** + * wlan_cm_roam_extract_roam_initial_info() - Extract Roam Initial stats + * @wmi: wmi handle + * @evt_buf: Pointer to the event buffer + * @dst: Pointer to destination structure to fill data + * @idx: TLV id + * + * Return: QDF_STATUS + */ +QDF_STATUS +wlan_cm_roam_extract_roam_initial_info(wmi_unified_t wmi, void *evt_buf, + struct roam_initial_data *dst, + uint8_t idx); + /** * wlan_cm_roam_activate_pcl_per_vdev - Set the PCL command to be sent per * vdev instead of pdev. @@ -114,5 +142,22 @@ static inline void wlan_cm_dual_sta_roam_update_connect_channels(struct wlan_objmgr_psoc *psoc, struct scan_filter *filter) {} + +static inline QDF_STATUS +wlan_cm_roam_extract_btm_response(wmi_unified_t wmi, void *evt_buf, + struct roam_btm_response_data *dst, + uint8_t idx) +{ + return true; +} + +static inline QDF_STATUS +wlan_cm_roam_extract_roam_initial_info(wmi_unified_t wmi, void *evt_buf, + struct roam_initial_data *dst, + uint8_t idx) +{ + return true; +} + #endif /* FEATURE_ROAM_OFFLOAD */ #endif /* WLAN_CM_ROAM_API_H__ */ 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 a2d3877d6d..1f83ad9e2c 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 @@ -21,9 +21,10 @@ #ifndef CM_ROAM_PUBLIC_STRUCT_H__ #define CM_ROAM_PUBLIC_STRUCT_H__ -#include "wlan_policy_mgr_public_struct.h" #include "wlan_objmgr_cmn.h" #include "reg_services_public_struct.h" +#include "wmi_unified_param.h" +#include "wmi_unified_sta_param.h" #if defined(WLAN_FEATURE_HOST_ROAM) || defined(WLAN_FEATURE_ROAM_OFFLOAD) /** @@ -49,6 +50,36 @@ enum roam_offload_state { WLAN_ROAM_SYNCH_IN_PROG, }; +/** + * struct roam_btm_response_data - BTM response related data + * @present: Flag to check if the roam btm_rsp tlv is present + * @btm_status: Btm request status + * @target_bssid: AP MAC address + * @vsie_reason: Vsie_reason value + */ +struct roam_btm_response_data { + bool present; + uint32_t btm_status; + struct qdf_mac_addr target_bssid; + uint32_t vsie_reason; +}; + +/** + * struct roam_initial_data - Roam initial related data + * @present: Flag to check if the roam btm_rsp tlv is present + * @roam_full_scan_count: Roam full scan count + * @rssi_th: RSSI threhold + * @cu_th: Channel utilization threhold + * @fw_cancel_timer_bitmap: FW timers, which are getting cancelled + */ +struct roam_initial_data { + bool present; + uint32_t roam_full_scan_count; + uint32_t rssi_th; + uint32_t cu_th; + uint32_t fw_cancel_timer_bitmap; +}; + /** * enum wlan_cm_rso_control_requestor - Driver disabled roaming requestor that * will request the roam module to disable roaming based on the mlme operation 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 1f93cbb35d..2a74fba2fd 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 @@ -24,8 +24,33 @@ #include "wlan_vdev_mlme_api.h" #include "wlan_mlme_main.h" #include "wlan_policy_mgr_api.h" +#include #ifdef WLAN_FEATURE_ROAM_OFFLOAD +QDF_STATUS +wlan_cm_roam_extract_btm_response(wmi_unified_t wmi, void *evt_buf, + struct roam_btm_response_data *dst, + uint8_t idx) +{ + if (wmi->ops->extract_roam_btm_response_stats) + return wmi->ops->extract_roam_btm_response_stats(wmi, evt_buf, + dst, idx); + + return QDF_STATUS_E_FAILURE; +} + +QDF_STATUS +wlan_cm_roam_extract_roam_initial_info(wmi_unified_t wmi, void *evt_buf, + struct roam_initial_data *dst, + uint8_t idx) +{ + if (wmi->ops->extract_roam_initial_info) + return wmi->ops->extract_roam_initial_info(wmi, evt_buf, + dst, idx); + + return QDF_STATUS_E_FAILURE; +} + void wlan_cm_roam_activate_pcl_per_vdev(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, bool pcl_per_vdev) { diff --git a/components/wmi/inc/wmi_unified_roam_api.h b/components/wmi/inc/wmi_unified_roam_api.h index 6e03c361d8..8a5046ba64 100644 --- a/components/wmi/inc/wmi_unified_roam_api.h +++ b/components/wmi/inc/wmi_unified_roam_api.h @@ -22,6 +22,7 @@ #define _WMI_UNIFIED_ROAM_API_H_ #include +#include #ifdef FEATURE_LFR_SUBNET_DETECTION /** diff --git a/components/wmi/src/wmi_unified_roam_tlv.c b/components/wmi/src/wmi_unified_roam_tlv.c index 7e60b52e70..3a4c88b28e 100644 --- a/components/wmi/src/wmi_unified_roam_tlv.c +++ b/components/wmi/src/wmi_unified_roam_tlv.c @@ -988,16 +988,107 @@ send_vdev_set_pcl_cmd_tlv(wmi_unified_t wmi_handle, return QDF_STATUS_SUCCESS; } +/** + * extract_roam_btm_response_stats_tlv() - Extract the btm rsp stats + * from the WMI_ROAM_STATS_EVENTID + * @wmi_handle: wmi handle + * @evt_buf: Pointer to the event buffer + * @dst: Pointer to destination structure to fill data + * @idx: TLV id + */ +static QDF_STATUS +extract_roam_btm_response_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, + struct roam_btm_response_data *dst, + uint8_t idx) +{ + WMI_ROAM_STATS_EVENTID_param_tlvs *param_buf; + wmi_roam_btm_response_info *src_data = NULL; + + param_buf = (WMI_ROAM_STATS_EVENTID_param_tlvs *)evt_buf; + + if (!param_buf || !param_buf->roam_btm_response_info || + !param_buf->num_roam_btm_response_info || + idx >= param_buf->num_roam_btm_response_info) { + WMI_LOGD("%s: Empty btm response param buf", __func__); + return QDF_STATUS_SUCCESS; + } + + src_data = ¶m_buf->roam_btm_response_info[idx]; + + dst->present = true; + dst->btm_status = src_data->btm_status; + WMI_MAC_ADDR_TO_CHAR_ARRAY(&src_data->target_bssid, + dst->target_bssid.bytes); + dst->vsie_reason = src_data->vsie_reason; + + return QDF_STATUS_SUCCESS; +} + +/** + * extract_roam_initial_info_tlv() - Extract the roam initial info + * from the WMI_ROAM_STATS_EVENTID + * @wmi_handle: wmi handle + * @evt_buf: Pointer to the event buffer + * @dst: Pointer to destination structure to fill data + * @idx: TLV id + */ +static QDF_STATUS +extract_roam_initial_info_tlv(wmi_unified_t wmi_handle, void *evt_buf, + struct roam_initial_data *dst, uint8_t idx) +{ + WMI_ROAM_STATS_EVENTID_param_tlvs *param_buf; + wmi_roam_initial_info *src_data = NULL; + + param_buf = (WMI_ROAM_STATS_EVENTID_param_tlvs *)evt_buf; + + if (!param_buf || !param_buf->roam_initial_info || + !param_buf->num_roam_initial_info || + idx >= param_buf->num_roam_initial_info) { + WMI_LOGD("%s: Empty roam_initial_info param buf", __func__); + return QDF_STATUS_SUCCESS; + } + + src_data = ¶m_buf->roam_initial_info[idx]; + + dst->present = true; + dst->roam_full_scan_count = src_data->roam_full_scan_count; + dst->rssi_th = src_data->rssi_th; + dst->cu_th = src_data->cu_th; + dst->fw_cancel_timer_bitmap = src_data->timer_canceled; + + return QDF_STATUS_SUCCESS; +} + void wmi_roam_offload_attach_tlv(wmi_unified_t wmi_handle) { struct wmi_ops *ops = wmi_handle->ops; + ops->extract_roam_btm_response_stats = + extract_roam_btm_response_stats_tlv; + ops->extract_roam_initial_info = extract_roam_initial_info_tlv; + ops->send_set_ric_req_cmd = send_set_ric_req_cmd_tlv; ops->send_process_roam_synch_complete_cmd = send_process_roam_synch_complete_cmd_tlv; ops->send_roam_invoke_cmd = send_roam_invoke_cmd_tlv; ops->send_vdev_set_pcl_cmd = send_vdev_set_pcl_cmd_tlv; } +#else +static inline QDF_STATUS +extract_roam_btm_response_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, + struct roam_btm_response_data *dst, + uint8_t idx) +{ + return QDF_STATUS_E_NOSUPPORT; +} + +static inline QDF_STATUS +extract_roam_initial_info_tlv(wmi_unified_t wmi_handle, void *evt_buf, + struct roam_initial_data *dst, uint8_t idx) +{ + return QDF_STATUS_E_NOSUPPORT; +} + #endif /* WLAN_FEATURE_ROAM_OFFLOAD */ #if defined(WLAN_FEATURE_FILS_SK) && defined(WLAN_FEATURE_ROAM_OFFLOAD) diff --git a/core/wma/src/wma_scan_roam.c b/core/wma/src/wma_scan_roam.c index 1555969d5c..bb5d4cfbc5 100644 --- a/core/wma/src/wma_scan_roam.c +++ b/core/wma/src/wma_scan_roam.c @@ -81,7 +81,7 @@ #include #include #include "wlan_blm_api.h" - +#include "wlan_cm_roam_api.h" #ifdef FEATURE_WLAN_DIAG_SUPPORT /* FEATURE_WLAN_DIAG_SUPPORT */ #include "host_diag_core_log.h" #endif /* FEATURE_WLAN_DIAG_SUPPORT */ @@ -3487,6 +3487,43 @@ wma_rso_print_trigger_info(struct wmi_roam_trigger_info *data, uint8_t vdev_id) qdf_mem_free(buf); } +/** + * wma_rso_print_btm_rsp_info - BTM RSP related details + * @data: Pointer to the btm rsp data + * @vdev_id: vdev id + * + * Prints the vdev, btm status, target_bssid and vsie reason + * + * Return: None + */ +static void +wma_rso_print_btm_rsp_info(struct roam_btm_response_data *data, + uint8_t vdev_id) +{ + wma_info("[BTM RSP]: VDEV[%d], Status: %d, VSIE reason: %d, BSSID: %pM", + vdev_id, data->btm_status, data->vsie_reason, + data->target_bssid.bytes); +} + +/** + * wma_rso_print_roam_initial_info - Roaming related initial details + * @data: Pointer to the btm rsp data + * @vdev_id: vdev id + * + * Prints the vdev, roam_full_scan_count, channel and rssi + * utilization threhold and timer + * + * Return: None + */ +static void +wma_rso_print_roam_initial_info(struct roam_initial_data *data, + uint8_t vdev_id) +{ + wma_info("[ROAM INIT INFO]: VDEV[%d], roam_full_scan_count: %d, rssi_th: %d, cu_th: %d, fw_cancel_timer_bitmap: %d", + vdev_id, data->roam_full_scan_count, data->rssi_th, + data->cu_th, data->fw_cancel_timer_bitmap); +} + /** * wma_log_roam_scan_candidates - Print roam scan candidate AP info * @ap: Pointer to the candidate AP list @@ -3770,6 +3807,22 @@ int wma_roam_stats_event_handler(WMA_HANDLE handle, uint8_t *event, goto err; } + rem_len -= param_buf->num_roam_neighbor_report_chan_info * + sizeof(wmi_roam_neighbor_report_channel_info); + if (rem_len < param_buf->num_roam_btm_response_info * + sizeof(wmi_roam_btm_response_info)) { + wma_err_rl("Invalid btm rsp data"); + goto err; + } + + rem_len -= param_buf->num_roam_btm_response_info * + sizeof(wmi_roam_btm_response_info); + if (rem_len < param_buf->num_roam_initial_info * + sizeof(wmi_roam_initial_info)) { + wma_err_rl("Invalid Initial roam info"); + goto err; + } + if (!num_tlv) { roam_info = qdf_mem_malloc(sizeof(*roam_info)); if (!roam_info) @@ -3836,6 +3889,29 @@ int wma_roam_stats_event_handler(WMA_HANDLE handle, uint8_t *event, return -EINVAL; } + /* BTM resp info */ + status = wlan_cm_roam_extract_btm_response(wma->wmi_handle, + event, + &roam_info->btm_rsp, + i); + if (QDF_IS_STATUS_ERROR(status)) { + wma_err("%s:Roam btm rsp stats extract fail vdev %d", + __func__, vdev_id); + qdf_mem_free(roam_info); + return -EINVAL; + } + + /* Initial Roam info */ + status = wlan_cm_roam_extract_roam_initial_info( + wma->wmi_handle, event, + &roam_info->roam_init_info, i); + if (QDF_IS_STATUS_ERROR(status)) { + wma_err("%s:Initial roam stats extract fail vdev %d", + __func__, vdev_id); + qdf_mem_free(roam_info); + return -EINVAL; + } + /* BTM req/resp or Neighbor report/response info */ status = wmi_unified_extract_roam_11kv_stats( wma->wmi_handle, event, @@ -3864,6 +3940,14 @@ int wma_roam_stats_event_handler(WMA_HANDLE handle, uint8_t *event, if (roam_info->data_11kv.present) wma_rso_print_11kv_info(&roam_info->data_11kv, vdev_id); + if (roam_info->btm_rsp.present) + wma_rso_print_btm_rsp_info(&roam_info->btm_rsp, + vdev_id); + + if (roam_info->roam_init_info.present) + wma_rso_print_roam_initial_info( + &roam_info->roam_init_info, vdev_id); + qdf_mem_free(roam_info); }