diff --git a/wmi/inc/wmi_unified_param.h b/wmi/inc/wmi_unified_param.h index ce3ed27d3c..ef86ae7a8f 100644 --- a/wmi/inc/wmi_unified_param.h +++ b/wmi/inc/wmi_unified_param.h @@ -4633,6 +4633,7 @@ typedef enum { wmi_twt_del_dialog_complete_event_id, wmi_twt_pause_dialog_complete_event_id, wmi_twt_resume_dialog_complete_event_id, + wmi_twt_session_stats_event_id, #endif wmi_apf_get_vdev_work_memory_resp_event_id, wmi_roam_scan_stats_event_id, diff --git a/wmi/inc/wmi_unified_priv.h b/wmi/inc/wmi_unified_priv.h index 55a09a10da..6df9e33e91 100644 --- a/wmi/inc/wmi_unified_priv.h +++ b/wmi/inc/wmi_unified_priv.h @@ -2187,6 +2187,20 @@ QDF_STATUS (*extract_twt_btwt_remove_sta_comp_event)(wmi_unified_t wmi_handle, struct wmi_twt_btwt_remove_sta_complete_event_param *params); #endif +QDF_STATUS(*extract_twt_session_stats_event) + ( + wmi_unified_t wmi_handle, + uint8_t *evt_buf, + struct wmi_twt_session_stats_event_param *params + ); +QDF_STATUS(*extract_twt_session_stats_data) + ( + wmi_unified_t wmi_handle, + uint8_t *evt_buf, + struct wmi_twt_session_stats_event_param *params, + struct wmi_host_twt_session_stats_info *session, + uint32_t idx + ); #endif #ifdef QCA_SUPPORT_CP_STATS diff --git a/wmi/inc/wmi_unified_twt_api.h b/wmi/inc/wmi_unified_twt_api.h index 8c03f8f30f..167d1597e7 100644 --- a/wmi/inc/wmi_unified_twt_api.h +++ b/wmi/inc/wmi_unified_twt_api.h @@ -246,6 +246,38 @@ QDF_STATUS wmi_extract_twt_btwt_remove_sta_comp_event( struct wmi_twt_btwt_remove_sta_complete_event_param *params); #endif +/** + * wmi_extract_twt_session_stats_event() - Extract WMI event params for TWT + * session stats event + * @wmi_handle: wmi handle + * @evt_buf: Pointer event buffer + * @params: Parameters to extract + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS wmi_extract_twt_session_stats_event( + wmi_unified_t wmi_handle, + uint8_t *evt_buf, + struct wmi_twt_session_stats_event_param *params); + +/** + * wmi_extract_twt_session_stats_data() - Extract one TWT session from TWT + * session stats event + * @wmi_handle: wmi handle + * @evt_buf: Pointer event buffer + * @params: Parameters to extract + * @session: Session struct to save one TWT session + * @idx: TWT session index + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS wmi_extract_twt_session_stats_data( + wmi_unified_t wmi_handle, + uint8_t *evt_buf, + struct wmi_twt_session_stats_event_param *params, + struct wmi_host_twt_session_stats_info *session, + uint32_t idx); + #ifdef WLAN_SUPPORT_TWT void wmi_twt_attach_tlv(struct wmi_unified *wmi_handle); #else diff --git a/wmi/inc/wmi_unified_twt_param.h b/wmi/inc/wmi_unified_twt_param.h index 4ed828092d..9bcfe95850 100644 --- a/wmi/inc/wmi_unified_twt_param.h +++ b/wmi/inc/wmi_unified_twt_param.h @@ -124,6 +124,53 @@ struct wmi_twt_disable_complete_event { uint32_t pdev_id; }; +/* TWT event types + * refer to wmi_unified.h enum wmi_twt_session_stats_type + */ +enum host_twt_session_stats_type { + HOST_TWT_SESSION_SETUP = 1, + HOST_TWT_SESSION_TEARDOWN = 2, + HOST_TWT_SESSION_UPDATE = 3, +}; + +/** + * struct wmi_host_twt_session_stats_info: + * @vdev_id: id of VDEV for twt session + * @peer_mac: MAC address of node + * @event_type: TWT event types + * @flow_id: TWT flow_id + * @bcast: broadcast TWT + * @trig: trigger + * @announ: TWT announcement + * @dialog_id: Dialog_id of current session + * @wake_dura_us: wake duration in us + * @wake_intvl_us: wake time interval in us + * @sp_offset_us: Time until initial TWT SP occurs + */ +struct wmi_host_twt_session_stats_info { + uint32_t vdev_id; + uint8_t peer_mac[QDF_MAC_ADDR_SIZE]; + uint32_t event_type; + uint32_t flow_id:16, + bcast:1, + trig:1, + announ:1; + uint32_t dialog_id; + uint32_t wake_dura_us; + uint32_t wake_intvl_us; + uint32_t sp_offset_us; +}; + +/** struct wmi_twt_session_stats_event: + * @pdev_id: pdev_id for identifying the MAC. + * @num_sessions: number of TWT sessions + * @twt_sessions: received TWT sessions + */ +struct wmi_twt_session_stats_event_param { + uint32_t pdev_id; + uint32_t num_sessions; +}; + /* from IEEE 802.11ah section 9.4.2.200 */ enum WMI_HOST_TWT_COMMAND { WMI_HOST_TWT_COMMAND_REQUEST_TWT = 0, diff --git a/wmi/src/wmi_unified_tlv.c b/wmi/src/wmi_unified_tlv.c index 295e457705..04b44b2208 100644 --- a/wmi/src/wmi_unified_tlv.c +++ b/wmi/src/wmi_unified_tlv.c @@ -14950,6 +14950,8 @@ static void populate_tlv_events_id(uint32_t *event_ids) WMI_TWT_PAUSE_DIALOG_COMPLETE_EVENTID; event_ids[wmi_twt_resume_dialog_complete_event_id] = WMI_TWT_RESUME_DIALOG_COMPLETE_EVENTID; + event_ids[wmi_twt_session_stats_event_id] = + WMI_TWT_SESSION_STATS_EVENTID; #endif event_ids[wmi_apf_get_vdev_work_memory_resp_event_id] = WMI_BPF_GET_VDEV_WORK_MEMORY_RESP_EVENTID; diff --git a/wmi/src/wmi_unified_twt_api.c b/wmi/src/wmi_unified_twt_api.c index 5016aec540..031ac02556 100644 --- a/wmi/src/wmi_unified_twt_api.c +++ b/wmi/src/wmi_unified_twt_api.c @@ -223,3 +223,29 @@ QDF_STATUS wmi_extract_twt_btwt_remove_sta_comp_event( return QDF_STATUS_E_FAILURE; } #endif + +QDF_STATUS wmi_extract_twt_session_stats_event( + wmi_unified_t wmi_handle, + uint8_t *evt_buf, + struct wmi_twt_session_stats_event_param *params) +{ + if (wmi_handle->ops->extract_twt_session_stats_event) + return wmi_handle->ops->extract_twt_session_stats_event( + wmi_handle, evt_buf, params); + + return QDF_STATUS_E_FAILURE; +} + +QDF_STATUS wmi_extract_twt_session_stats_data( + wmi_unified_t wmi_handle, + uint8_t *evt_buf, + struct wmi_twt_session_stats_event_param *params, + struct wmi_host_twt_session_stats_info *session, + uint32_t idx) +{ + if (wmi_handle->ops->extract_twt_session_stats_data) + return wmi_handle->ops->extract_twt_session_stats_data( + wmi_handle, evt_buf, params, session, idx); + + return QDF_STATUS_E_FAILURE; +} diff --git a/wmi/src/wmi_unified_twt_tlv.c b/wmi/src/wmi_unified_twt_tlv.c index 5833c674ab..c0804cfde4 100644 --- a/wmi/src/wmi_unified_twt_tlv.c +++ b/wmi/src/wmi_unified_twt_tlv.c @@ -666,6 +666,89 @@ wmi_twt_attach_bcast_twt_tlv(struct wmi_ops *ops) } #endif +static QDF_STATUS +extract_twt_session_stats_event_tlv(wmi_unified_t wmi_handle, + uint8_t *evt_buf, + struct wmi_twt_session_stats_event_param + *params) +{ + WMI_TWT_SESSION_STATS_EVENTID_param_tlvs *param_buf; + wmi_pdev_twt_session_stats_event_fixed_param *ev; + + param_buf = + (WMI_TWT_SESSION_STATS_EVENTID_param_tlvs *)evt_buf; + if (!param_buf) { + WMI_LOGE("evt_buf is NULL"); + return QDF_STATUS_E_INVAL; + } + + ev = param_buf->fixed_param; + params->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( + wmi_handle, + ev->pdev_id); + params->num_sessions = param_buf->num_twt_sessions; + + WMI_LOGD("pdev_id=%d, num of TWT sessions=%d", + params->pdev_id, params->num_sessions); + + return QDF_STATUS_SUCCESS; +} + +static QDF_STATUS +extract_twt_session_stats_event_data(wmi_unified_t wmi_handle, + uint8_t *evt_buf, + struct wmi_twt_session_stats_event_param + *params, + struct wmi_host_twt_session_stats_info + *session, + uint32_t idx) +{ + WMI_TWT_SESSION_STATS_EVENTID_param_tlvs *param_buf; + wmi_twt_session_stats_info *twt_session; + uint32_t flags; + wmi_mac_addr *m1; + uint8_t *m2; + + param_buf = + (WMI_TWT_SESSION_STATS_EVENTID_param_tlvs *)evt_buf; + if (!param_buf) { + WMI_LOGE("evt_buf is NULL"); + return QDF_STATUS_E_INVAL; + } + + if (idx >= param_buf->num_twt_sessions) { + WMI_LOGE("wrong idx, idx=%d, num_sessions=%d", + idx, param_buf->num_twt_sessions); + return QDF_STATUS_E_INVAL; + } + + twt_session = ¶m_buf->twt_sessions[idx]; + + session->vdev_id = twt_session->vdev_id; + m1 = &twt_session->peer_mac; + m2 = session->peer_mac; + WMI_MAC_ADDR_TO_CHAR_ARRAY(m1, m2); + session->event_type = twt_session->event_type; + flags = twt_session->flow_id_flags; + session->flow_id = WMI_TWT_SESSION_FLAG_FLOW_ID_GET(flags); + session->bcast = WMI_TWT_SESSION_FLAG_BCAST_TWT_GET(flags); + session->trig = WMI_TWT_SESSION_FLAG_TRIGGER_TWT_GET(flags); + session->announ = WMI_TWT_SESSION_FLAG_ANNOUN_TWT_GET(flags); + session->dialog_id = twt_session->dialog_id; + session->wake_dura_us = twt_session->wake_dura_us; + session->wake_intvl_us = twt_session->wake_intvl_us; + session->sp_offset_us = twt_session->sp_offset_us; + WMI_LOGD("type=%d,id=%d,bcast=%d,trig=%d", + session->event_type, session->flow_id, + session->bcast, session->trig); + WMI_LOGD("announ=%d,diagid=%d,wake_dur=%ul", + session->announ, session->dialog_id, session->wake_dura_us); + WMI_LOGD("wake_int=%ul,offset=%ul", + session->wake_intvl_us, session->sp_offset_us); + + return QDF_STATUS_SUCCESS; +} + void wmi_twt_attach_tlv(wmi_unified_t wmi_handle) { struct wmi_ops *ops = wmi_handle->ops; @@ -689,6 +772,10 @@ void wmi_twt_attach_tlv(wmi_unified_t wmi_handle) extract_twt_pause_dialog_comp_event_tlv; ops->extract_twt_resume_dialog_comp_event = extract_twt_resume_dialog_comp_event_tlv; + ops->extract_twt_session_stats_event = + extract_twt_session_stats_event_tlv; + ops->extract_twt_session_stats_data = + extract_twt_session_stats_event_data; wmi_twt_attach_bcast_twt_tlv(ops); }