From fc3c62d771e81b866c9dcd40a244d145de4b6bf8 Mon Sep 17 00:00:00 2001 From: Jyoti Kumari Date: Mon, 21 Jun 2021 21:25:47 +0530 Subject: [PATCH] qcacmn: Add support for TWT ack event In case if TWT command (i.e setup, terminate, pause, resume, nudge) comes from userspace and if the firmware is in below mode 1. scan in progress 2. roam in progress 3. CSA is in progress or 4. Any other error then the command needs to be rejected in userspace context. Synchronize the TWT command so that whenever command goes from driver to firmware, then driver will receive ack event first followed by respective event (i.e add dialog, delete dialog, pause, resume, nudge) with below condition 1. If driver receives the ack event as successful then driver waits for this ack event, respective event with status of the TWT action frame over the air is expected. 2. If driver receives the ack event as failure then it will rejects the TWT command in userspace context. Change-Id: Ie885d98ecf2dad98d34676d889fd70e4c84f0a05 CRs-Fixed: 2987904 --- wmi/inc/wmi_unified_param.h | 1 + wmi/inc/wmi_unified_priv.h | 3 ++ wmi/inc/wmi_unified_twt_api.h | 14 +++++++ wmi/inc/wmi_unified_twt_param.h | 33 +++++++++++++++ wmi/src/wmi_unified_tlv.c | 2 + wmi/src/wmi_unified_twt_api.c | 12 ++++++ wmi/src/wmi_unified_twt_tlv.c | 71 ++++++++++++++++++++++++++++++++- 7 files changed, 135 insertions(+), 1 deletion(-) diff --git a/wmi/inc/wmi_unified_param.h b/wmi/inc/wmi_unified_param.h index cde23a3155..e23d8ef09e 100644 --- a/wmi/inc/wmi_unified_param.h +++ b/wmi/inc/wmi_unified_param.h @@ -4627,6 +4627,7 @@ typedef enum { wmi_twt_nudge_dialog_complete_event_id, wmi_twt_session_stats_event_id, wmi_twt_notify_event_id, + wmi_twt_ack_complete_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 ed54bb230d..8b5e1c50ec 100644 --- a/wmi/inc/wmi_unified_priv.h +++ b/wmi/inc/wmi_unified_priv.h @@ -2318,6 +2318,9 @@ QDF_STATUS (*extract_twt_resume_dialog_comp_event)(wmi_unified_t wmi_handle, QDF_STATUS (*extract_twt_notify_event)(wmi_unified_t wmi_handle, uint8_t *evt_buf, struct wmi_twt_notify_event_param *params); +QDF_STATUS (*extract_twt_ack_comp_event)(wmi_unified_t wmi_handle, + uint8_t *evt_buf, + struct wmi_twt_ack_complete_event_param *params); #ifdef WLAN_SUPPORT_BCAST_TWT QDF_STATUS (*extract_twt_btwt_invite_sta_comp_event)(wmi_unified_t wmi_handle, uint8_t *evt_buf, diff --git a/wmi/inc/wmi_unified_twt_api.h b/wmi/inc/wmi_unified_twt_api.h index f443718b0d..9233f885a5 100644 --- a/wmi/inc/wmi_unified_twt_api.h +++ b/wmi/inc/wmi_unified_twt_api.h @@ -341,4 +341,18 @@ QDF_STATUS wmi_extract_twt_cap_service_ready_ext2( uint8_t *evt_buf, struct wmi_twt_cap_bitmap_params *params); +/** + * wmi_extract_twt_ack_comp_event() - Extract WMI event params for TWT ack 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_ack_comp_event( + wmi_unified_t wmi_handle, + uint8_t *evt_buf, + struct wmi_twt_ack_complete_event_param *param); + #endif /* _WMI_UNIFIED_TWT_API_H_ */ diff --git a/wmi/inc/wmi_unified_twt_param.h b/wmi/inc/wmi_unified_twt_param.h index f3ded0c4df..7f522a5129 100644 --- a/wmi/inc/wmi_unified_twt_param.h +++ b/wmi/inc/wmi_unified_twt_param.h @@ -161,6 +161,22 @@ struct wmi_twt_disable_complete_event { uint32_t pdev_id; }; +/** + * wmi_twt_ack_complete_event_param: + * @vdev_id: vdev id + * @peer_macaddr: peer mac address + * @dialog_id: dialog id + * @twt_cmd_ack: ack event to the corresponding twt command + * @status: twt command status + */ +struct wmi_twt_ack_complete_event_param { + uint32_t vdev_id; + struct qdf_mac_addr peer_macaddr; + uint32_t dialog_id; + uint32_t twt_cmd_ack; + uint32_t status; +}; + /* TWT event types * refer to wmi_unified.h enum wmi_twt_session_stats_type */ @@ -762,4 +778,21 @@ struct wmi_twt_btwt_remove_sta_complete_event_param { }; #endif +/** + * enum WMI_HOST_TWT_CMD_FOR_ACK_EVENT - Ack event for different TWT command + * WMI_HOST_TWT_ADD_DIALOG_CMDID: Ack event for add dialog command + * WMI_HOST_TWT_DEL_DIALOG_CMDID: Ack event for delete dialog command + * WMI_HOST_TWT_PAUSE_DIALOG_CMDID: Ack event for pause command + * WMI_HOST_TWT_RESUME_DIALOG_CMDID: Ack event for resume command + * WMI_HOST_TWT_NUDGE_DIALOG_CMDID: Ack event for nudge command + * WMI_HOST_TWT_UNKNOWN_CMDID: Ack event for unknown TWT command + */ +enum WMI_HOST_TWT_CMD_FOR_ACK_EVENT { + WMI_HOST_TWT_ADD_DIALOG_CMDID = 0, + WMI_HOST_TWT_DEL_DIALOG_CMDID, + WMI_HOST_TWT_PAUSE_DIALOG_CMDID, + WMI_HOST_TWT_RESUME_DIALOG_CMDID, + WMI_HOST_TWT_NUDGE_DIALOG_CMDID, + WMI_HOST_TWT_UNKNOWN_CMDID, +}; #endif /* _WMI_UNIFIED_TWT_PARAM_H_ */ diff --git a/wmi/src/wmi_unified_tlv.c b/wmi/src/wmi_unified_tlv.c index 747d00c61d..a994057c92 100644 --- a/wmi/src/wmi_unified_tlv.c +++ b/wmi/src/wmi_unified_tlv.c @@ -15946,6 +15946,8 @@ static void populate_tlv_events_id(uint32_t *event_ids) WMI_TWT_SESSION_STATS_EVENTID; event_ids[wmi_twt_notify_event_id] = WMI_TWT_NOTIFY_EVENTID; + event_ids[wmi_twt_ack_complete_event_id] = + WMI_TWT_ACK_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 40370ceb93..7b98165f0f 100644 --- a/wmi/src/wmi_unified_twt_api.c +++ b/wmi/src/wmi_unified_twt_api.c @@ -298,3 +298,15 @@ QDF_STATUS wmi_extract_twt_cap_service_ready_ext2( return QDF_STATUS_E_FAILURE; } + +QDF_STATUS wmi_extract_twt_ack_comp_event( + wmi_unified_t wmi_handle, + uint8_t *evt_buf, + struct wmi_twt_ack_complete_event_param *params) +{ + if (wmi_handle->ops->extract_twt_ack_comp_event) + return wmi_handle->ops->extract_twt_ack_comp_event( + wmi_handle, evt_buf, params); + + return QDF_STATUS_E_FAILURE; +} diff --git a/wmi/src/wmi_unified_twt_tlv.c b/wmi/src/wmi_unified_twt_tlv.c index ec27e8eb8e..656eb9f498 100644 --- a/wmi/src/wmi_unified_twt_tlv.c +++ b/wmi/src/wmi_unified_twt_tlv.c @@ -1049,6 +1049,75 @@ static QDF_STATUS extract_twt_cap_service_ready_ext2_tlv( return QDF_STATUS_SUCCESS; } +static enum WMI_HOST_TWT_CMD_FOR_ACK_EVENT +wmi_get_converted_twt_command_for_ack_event(WMI_CMD_ID tgt_cmd) +{ + switch (tgt_cmd) { + case WMI_TWT_ADD_DIALOG_CMDID: + return WMI_HOST_TWT_ADD_DIALOG_CMDID; + case WMI_TWT_DEL_DIALOG_CMDID: + return WMI_HOST_TWT_DEL_DIALOG_CMDID; + case WMI_TWT_PAUSE_DIALOG_CMDID: + return WMI_HOST_TWT_PAUSE_DIALOG_CMDID; + case WMI_TWT_RESUME_DIALOG_CMDID: + return WMI_HOST_TWT_RESUME_DIALOG_CMDID; + case WMI_TWT_NUDGE_DIALOG_CMDID: + return WMI_HOST_TWT_NUDGE_DIALOG_CMDID; + default: + return WMI_HOST_TWT_UNKNOWN_CMDID; + } +} + +static QDF_STATUS +extract_twt_ack_comp_event_tlv(wmi_unified_t wmi_handle, + uint8_t *evt_buf, + struct wmi_twt_ack_complete_event_param *var) +{ + WMI_TWT_ACK_EVENTID_param_tlvs *param_buf; + wmi_twt_ack_event_fixed_param *ack_event; + + param_buf = (WMI_TWT_ACK_EVENTID_param_tlvs *)evt_buf; + if (!param_buf) { + wmi_err("evt_buf is NULL"); + return QDF_STATUS_E_INVAL; + } + + ack_event = param_buf->fixed_param; + + var->vdev_id = ack_event->vdev_id; + WMI_MAC_ADDR_TO_CHAR_ARRAY(&ack_event->peer_macaddr, + var->peer_macaddr.bytes); + var->dialog_id = ack_event->dialog_id; + var->twt_cmd_ack = wmi_get_converted_twt_command_for_ack_event( + ack_event->twt_cmd); + + switch (ack_event->twt_cmd) { + case WMI_TWT_ADD_DIALOG_CMDID: + var->status = wmi_get_converted_twt_add_dialog_status( + ack_event->status); + break; + case WMI_TWT_DEL_DIALOG_CMDID: + var->status = wmi_get_converted_twt_del_dialog_status( + ack_event->status); + break; + case WMI_TWT_PAUSE_DIALOG_CMDID: + var->status = wmi_twt_pause_status_to_host_twt_status( + ack_event->status); + break; + case WMI_TWT_RESUME_DIALOG_CMDID: + var->status = wmi_get_converted_twt_resume_dialog_status( + ack_event->status); + break; + case WMI_TWT_NUDGE_DIALOG_CMDID: + var->status = wmi_twt_nudge_status_to_host_twt_status( + ack_event->status); + break; + default: + break; + } + return QDF_STATUS_SUCCESS; +} + void wmi_twt_attach_tlv(wmi_unified_t wmi_handle) { struct wmi_ops *ops = wmi_handle->ops; @@ -1083,6 +1152,6 @@ void wmi_twt_attach_tlv(wmi_unified_t wmi_handle) extract_twt_notify_event_tlv; ops->extract_twt_cap_service_ready_ext2 = extract_twt_cap_service_ready_ext2_tlv, - + ops->extract_twt_ack_comp_event = extract_twt_ack_comp_event_tlv; wmi_twt_attach_bcast_twt_tlv(ops); }