diff --git a/components/mlme/core/inc/wlan_mlme_twt_api.h b/components/mlme/core/inc/wlan_mlme_twt_api.h index f0b5faacee83..63a110b5caf6 100644 --- a/components/mlme/core/inc/wlan_mlme_twt_api.h +++ b/components/mlme/core/inc/wlan_mlme_twt_api.h @@ -85,23 +85,28 @@ bool mlme_is_twt_setup_done(struct wlan_objmgr_psoc *psoc, * mlme_set_twt_session_state() - Set the TWT session state for the given dialog * id in TWT context * @peer: Pointer to peer object + * @peer_mac: Pointer to peer mac address * @dialog_id: Dialog id * @state: TWT session state * * Return: None */ -void mlme_set_twt_session_state(struct wlan_objmgr_peer *peer, +void mlme_set_twt_session_state(struct wlan_objmgr_psoc *psoc, + struct qdf_mac_addr *peer_mac, uint8_t dialog_id, enum wlan_twt_session_state state); + /** * mlme_get_twt_session_state() - Get TWT session state for given dialog id - * @peer: Pointer to peer object + * @psoc: Pointer to psoc object + * @peer_mac: Pointer to peer mac address * @dialog_id: Dialog id * * Return: TWT session state. */ enum wlan_twt_session_state -mlme_get_twt_session_state(struct wlan_objmgr_peer *peer, uint8_t dialog_id); +mlme_get_twt_session_state(struct wlan_objmgr_psoc *psoc, + struct qdf_mac_addr *peer_mac, uint8_t dialog_id); /** * mlme_get_twt_peer_capabilities - Get TWT peer capabilities diff --git a/components/mlme/core/src/wlan_mlme_twt_api.c b/components/mlme/core/src/wlan_mlme_twt_api.c index a184dded570c..4c5facb2071a 100644 --- a/components/mlme/core/src/wlan_mlme_twt_api.c +++ b/components/mlme/core/src/wlan_mlme_twt_api.c @@ -269,16 +269,26 @@ bool mlme_twt_is_notify_done(struct wlan_objmgr_psoc *psoc, return notify_done; } -void mlme_set_twt_session_state(struct wlan_objmgr_peer *peer, +void mlme_set_twt_session_state(struct wlan_objmgr_psoc *psoc, + struct qdf_mac_addr *peer_mac, uint8_t dialog_id, enum wlan_twt_session_state state) { + struct wlan_objmgr_peer *peer; struct peer_mlme_priv_obj *peer_priv; uint8_t i; + peer = wlan_objmgr_get_peer_by_mac(psoc, peer_mac->bytes, + WLAN_MLME_NB_ID); + if (!peer) { + mlme_legacy_err("Peer object not found"); + return; + } + peer_priv = wlan_objmgr_peer_get_comp_private_obj(peer, WLAN_UMAC_COMP_MLME); if (!peer_priv) { + wlan_objmgr_peer_release_ref(peer, WLAN_MLME_NB_ID); mlme_err(" peer mlme component object is NULL"); return; } @@ -290,27 +300,43 @@ void mlme_set_twt_session_state(struct wlan_objmgr_peer *peer, break; } } + + wlan_objmgr_peer_release_ref(peer, WLAN_MLME_NB_ID); } enum wlan_twt_session_state -mlme_get_twt_session_state(struct wlan_objmgr_peer *peer, - uint8_t dialog_id) +mlme_get_twt_session_state(struct wlan_objmgr_psoc *psoc, + struct qdf_mac_addr *peer_mac, uint8_t dialog_id) { + struct wlan_objmgr_peer *peer; struct peer_mlme_priv_obj *peer_priv; uint8_t i; + peer = wlan_objmgr_get_peer_by_mac(psoc, peer_mac->bytes, + WLAN_MLME_NB_ID); + if (!peer) { + mlme_legacy_err("Peer object not found"); + return WLAN_TWT_SETUP_STATE_NOT_ESTABLISHED; + } + peer_priv = wlan_objmgr_peer_get_comp_private_obj(peer, WLAN_UMAC_COMP_MLME); if (!peer_priv) { + wlan_objmgr_peer_release_ref(peer, WLAN_MLME_NB_ID); mlme_legacy_err(" peer mlme object is NULL"); return WLAN_TWT_SETUP_STATE_NOT_ESTABLISHED; } for (i = 0; i < peer_priv->twt_ctx.num_twt_sessions; i++) { - if (peer_priv->twt_ctx.session_info[i].dialog_id == dialog_id) + if (peer_priv->twt_ctx.session_info[i].dialog_id == dialog_id && + dialog_id != WLAN_ALL_SESSIONS_DIALOG_ID) { + wlan_objmgr_peer_release_ref(peer, WLAN_MLME_NB_ID); return peer_priv->twt_ctx.session_info[i].state; + } } + wlan_objmgr_peer_release_ref(peer, WLAN_MLME_NB_ID); + return WLAN_TWT_SETUP_STATE_NOT_ESTABLISHED; } diff --git a/components/mlme/dispatcher/inc/wlan_mlme_twt_ucfg_api.h b/components/mlme/dispatcher/inc/wlan_mlme_twt_ucfg_api.h index 1bc7283a7f7c..5f50cb2ca9cb 100644 --- a/components/mlme/dispatcher/inc/wlan_mlme_twt_ucfg_api.h +++ b/components/mlme/dispatcher/inc/wlan_mlme_twt_ucfg_api.h @@ -376,6 +376,40 @@ ucfg_mlme_set_twt_statistics_tgt_cap(struct wlan_objmgr_psoc *psoc, bool val); */ QDF_STATUS ucfg_mlme_get_twt_statistics_tgt_cap(struct wlan_objmgr_psoc *psoc, bool *val); + +/** + * ucfg_mlme_set_twt_session_state() - Set TWT session state + * @psoc: Pointer to global psoc object + * @peer_mac: Pointer to peer mac address + * @dialog_id: TWT session dialog id + * @state: TWT state + * + * Return: None + */ +static inline +void ucfg_mlme_set_twt_session_state(struct wlan_objmgr_psoc *psoc, + struct qdf_mac_addr *peer_mac, + uint8_t dialog_id, + enum wlan_twt_session_state state) +{ + mlme_set_twt_session_state(psoc, peer_mac, dialog_id, state); +} + +/** + * ucfg_mlme_get_twt_session_state() - Get TWT session state + * @psoc: Pointer to global psoc object + * @peer_mac: Pointer to peer mac address + * @dialog_id: TWT session dialog id + * + * Return: enum wlan_twt_session_state + */ +static inline enum wlan_twt_session_state +ucfg_mlme_get_twt_session_state(struct wlan_objmgr_psoc *psoc, + struct qdf_mac_addr *peer_mac, + uint8_t dialog_id) +{ + return mlme_get_twt_session_state(psoc, peer_mac, dialog_id); +} #else static inline QDF_STATUS ucfg_mlme_get_twt_requestor(struct wlan_objmgr_psoc *psoc, @@ -580,5 +614,20 @@ ucfg_mlme_set_twt_statistics_tgt_cap(struct wlan_objmgr_psoc *psoc, bool val) { return QDF_STATUS_E_NOSUPPORT; } + +static inline +void ucfg_mlme_set_twt_session_state(struct wlan_objmgr_psoc *psoc, + struct qdf_mac_addr *peer_mac, + uint8_t dialog_id, + enum wlan_twt_session_state state) +{} + +static inline enum wlan_twt_session_state +ucfg_mlme_get_twt_session_state(struct wlan_objmgr_psoc *psoc, + struct qdf_mac_addr *peer_mac, + uint8_t dialog_id) +{ + return WLAN_TWT_SETUP_STATE_NOT_ESTABLISHED; +} #endif /* defined(WLAN_SUPPORT_TWT) && defined(WLAN_FEATURE_11AX) */ #endif /* _WLAN_MLME_TWT_UCFG_API_H_ */ diff --git a/core/hdd/src/wlan_hdd_twt.c b/core/hdd/src/wlan_hdd_twt.c index 6c161e3ec18c..049d10766c5a 100644 --- a/core/hdd/src/wlan_hdd_twt.c +++ b/core/hdd/src/wlan_hdd_twt.c @@ -463,21 +463,50 @@ static uint32_t hdd_twt_get_params_resp_len(void) /* QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_TIME_TSF */ len += nla_total_size(sizeof(u64)); + /* QCA_WLAN_VENDOR_ATTR_TWT_SETUP_STATE */ + len += nla_total_size(sizeof(u32)); + return len; } +/** + * hdd_get_converted_twt_state() - Convert the internal twt state + * to qca_wlan_twt_setup_state type. + * @state: Internal TWT state to be converted. + * + * Return: qca_wlan_twt_setup_state type state + */ +static enum qca_wlan_twt_setup_state +hdd_get_converted_twt_state(enum wlan_twt_session_state state) +{ + switch (state) { + case WLAN_TWT_SETUP_STATE_NOT_ESTABLISHED: + return QCA_WLAN_TWT_SETUP_STATE_NOT_ESTABLISHED; + case WLAN_TWT_SETUP_STATE_ACTIVE: + return QCA_WLAN_TWT_SETUP_STATE_ACTIVE; + case WLAN_TWT_SETUP_STATE_SUSPEND: + return QCA_WLAN_TWT_SETUP_STATE_SUSPEND; + default: + return QCA_WLAN_TWT_SETUP_STATE_NOT_ESTABLISHED; + } +} + /** * hdd_twt_pack_get_params_resp_nlmsg()- Packs and sends twt get_params response + * @psoc: Pointer to Global psoc * @reply_skb: pointer to response skb buffer * @params: Ponter to twt peer session parameters * * Return: QDF_STATUS_SUCCESS on success, else other qdf error values */ static QDF_STATUS -hdd_twt_pack_get_params_resp_nlmsg(struct sk_buff *reply_skb, +hdd_twt_pack_get_params_resp_nlmsg(struct wlan_objmgr_psoc *psoc, + struct sk_buff *reply_skb, struct wmi_host_twt_session_stats_info *params) { struct nlattr *config_attr, *nla_params; + enum wlan_twt_session_state state; + enum qca_wlan_twt_setup_state converted_state; uint64_t tsf_val; int i, attr; @@ -584,6 +613,16 @@ hdd_twt_pack_get_params_resp_nlmsg(struct sk_buff *reply_skb, return QDF_STATUS_E_INVAL; } + attr = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_STATE; + state = ucfg_mlme_get_twt_session_state( + psoc, (struct qdf_mac_addr *)params[i].peer_mac, + params[i].dialog_id); + converted_state = hdd_get_converted_twt_state(state); + if (nla_put_u32(reply_skb, attr, converted_state)) { + hdd_err("TWT: get_params failed to put TWT state"); + return QDF_STATUS_E_INVAL; + } + nla_nest_end(reply_skb, nla_params); } nla_nest_end(reply_skb, config_attr); @@ -624,7 +663,8 @@ hdd_twt_pack_get_params_resp(struct hdd_context *hdd_ctx, return QDF_STATUS_E_NOMEM; } - qdf_status = hdd_twt_pack_get_params_resp_nlmsg(reply_skb, params); + qdf_status = hdd_twt_pack_get_params_resp_nlmsg(hdd_ctx->psoc, + reply_skb, params); if (QDF_IS_STATUS_ERROR(qdf_status)) goto fail; @@ -637,6 +677,25 @@ fail: return qdf_status; } +/** + * hdd_send_inactive_session_reply - Send session state as inactive for + * dialog ID for which setup is not done. + * @params: TWT session parameters + * + * Return: QDF_STATUS + */ +static QDF_STATUS +hdd_send_inactive_session_reply(struct hdd_adapter *adapter, + struct wmi_host_twt_session_stats_info *params) +{ + QDF_STATUS qdf_status; + + params[0].event_type = HOST_TWT_SESSION_UPDATE; + qdf_status = hdd_twt_pack_get_params_resp(adapter->hdd_ctx, params); + + return qdf_status; +} + /** * hdd_twt_get_peer_session_params() - Obtains twt session parameters of a peer * and sends response to the user space @@ -701,16 +760,6 @@ static int hdd_twt_get_session_params(struct hdd_adapter *adapter, else params[0].dialog_id = 0; - if (!ucfg_mlme_is_twt_setup_done(adapter->hdd_ctx->psoc, - &hdd_sta_ctx->conn_info.bssid, - params[0].dialog_id)) { - hdd_debug("vdev%d: TWT session %d setup incomplete", - adapter->vdev_id, params[0].dialog_id); - return -EINVAL; - } - - hdd_debug("TWT: get_params dialog_id %d", params[0].dialog_id); - if (params[0].dialog_id <= TWT_MAX_DIALOG_ID) { qdf_mem_copy(params[0].peer_mac, hdd_sta_ctx->conn_info.bssid.bytes, @@ -719,6 +768,18 @@ static int hdd_twt_get_session_params(struct hdd_adapter *adapter, QDF_MAC_ADDR_REF(params[0].peer_mac)); } + if (!ucfg_mlme_is_twt_setup_done(adapter->hdd_ctx->psoc, + &hdd_sta_ctx->conn_info.bssid, + params[0].dialog_id)) { + hdd_debug("vdev%d: TWT session %d setup incomplete", + adapter->vdev_id, params[0].dialog_id); + qdf_status = hdd_send_inactive_session_reply(adapter, params); + + return qdf_status_to_os_return(qdf_status); + } + + hdd_debug("TWT: get_params dialog_id %d", params[0].dialog_id); + qdf_status = hdd_twt_get_peer_session_params(adapter->hdd_ctx, ¶ms[0]); @@ -1001,6 +1062,7 @@ hdd_twt_setup_pack_resp_nlmsg(struct sk_buff *reply_skb, uint64_t sp_offset_tsf; enum qca_wlan_vendor_twt_status vendor_status; int response_type; + uint32_t wake_duration; hdd_enter(); @@ -1054,8 +1116,10 @@ hdd_twt_setup_pack_resp_nlmsg(struct sk_buff *reply_skb, return QDF_STATUS_E_FAILURE; } + wake_duration = (event->additional_params.wake_dur_us / + TWT_WAKE_DURATION_MULTIPLICATION_FACTOR); if (nla_put_u32(reply_skb, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_DURATION, - event->additional_params.wake_dur_us)) { + wake_duration)) { hdd_err("TWT: Failed to put wake duration"); return QDF_STATUS_E_FAILURE; } @@ -1470,7 +1534,6 @@ hdd_twt_del_dialog_comp_cb(struct wlan_objmgr_psoc *psoc, mlme_init_twt_context(hdd_ctx->psoc, (struct qdf_mac_addr *)params->peer_macaddr, params->dialog_id); - hdd_exit(); return; diff --git a/core/mac/src/pe/lim/lim_process_assoc_rsp_frame.c b/core/mac/src/pe/lim/lim_process_assoc_rsp_frame.c index 464df02bb235..694da41fe1a9 100644 --- a/core/mac/src/pe/lim/lim_process_assoc_rsp_frame.c +++ b/core/mac/src/pe/lim/lim_process_assoc_rsp_frame.c @@ -1094,7 +1094,6 @@ lim_process_assoc_rsp_frame(struct mac_context *mac_ctx, uint8_t *rx_pkt_info, session_entry->ap_mu_edca_params[QCA_WLAN_AC_VO] = assoc_rsp->mu_edca.acvo; } - } if (beacon->VHTCaps.present) diff --git a/core/sme/src/common/sme_api.c b/core/sme/src/common/sme_api.c index c48ec789b122..699dbd96972a 100644 --- a/core/sme/src/common/sme_api.c +++ b/core/sme/src/common/sme_api.c @@ -69,6 +69,7 @@ #include "wlan_cm_tgt_if_tx_api.h" #include "wlan_mlme_twt_public_struct.h" #include "wlan_mlme_twt_api.h" +#include "wlan_mlme_twt_ucfg_api.h" #include "parser_api.h" #include @@ -2072,13 +2073,21 @@ sme_process_twt_add_dialog_event(struct mac_context *mac, mac->psoc, (struct qdf_mac_addr *)add_dialog_event->params.peer_macaddr, add_dialog_event->params.dialog_id, WLAN_TWT_SETUP); - if (!is_evt_allowed) + if (!is_evt_allowed) { + sme_debug("add dialog event dropped"); return; + } callback = mac->sme.twt_add_dialog_cb; if (callback) callback(mac->psoc, add_dialog_event); + ucfg_mlme_set_twt_session_state( + mac->psoc, + (struct qdf_mac_addr *)add_dialog_event->params.peer_macaddr, + add_dialog_event->params.dialog_id, + WLAN_TWT_SETUP_STATE_ACTIVE); + /* Reset the active TWT command to none */ mlme_set_twt_command_in_progress( mac->psoc, @@ -2105,9 +2114,12 @@ sme_process_twt_del_dialog_event(struct mac_context *mac, mac->psoc, (struct qdf_mac_addr *)param->peer_macaddr, param->dialog_id, WLAN_TWT_TERMINATE); if (!is_evt_allowed && + param->dialog_id != WLAN_ALL_SESSIONS_DIALOG_ID && (param->status != WMI_HOST_DEL_TWT_STATUS_ROAMING || - param->status != WMI_HOST_DEL_TWT_STATUS_PEER_INIT_TEARDOWN)) + param->status != WMI_HOST_DEL_TWT_STATUS_PEER_INIT_TEARDOWN)) { + sme_debug("add dialog event dropped"); return; + } callback = mac->sme.twt_del_dialog_cb; if (callback) @@ -2119,6 +2131,10 @@ sme_process_twt_del_dialog_event(struct mac_context *mac, mac->psoc, (struct qdf_mac_addr *)param->peer_macaddr, true); + ucfg_mlme_set_twt_session_state( + mac->psoc, (struct qdf_mac_addr *)param->peer_macaddr, + param->dialog_id, WLAN_TWT_SETUP_STATE_NOT_ESTABLISHED); + /* Reset the active TWT command to none */ mlme_set_twt_command_in_progress( mac->psoc, (struct qdf_mac_addr *)param->peer_macaddr, @@ -2138,18 +2154,15 @@ sme_process_twt_pause_dialog_event(struct mac_context *mac, struct wmi_twt_pause_dialog_complete_event_param *param) { twt_pause_dialog_cb callback; - bool is_evt_allowed; - - is_evt_allowed = mlme_twt_is_command_in_progress( - mac->psoc, (struct qdf_mac_addr *)param->peer_macaddr, - param->dialog_id, WLAN_TWT_SUSPEND); - if (!is_evt_allowed) - return; callback = mac->sme.twt_pause_dialog_cb; if (callback) callback(mac->psoc, param); + ucfg_mlme_set_twt_session_state( + mac->psoc, (struct qdf_mac_addr *)param->peer_macaddr, + param->dialog_id, WLAN_TWT_SETUP_STATE_SUSPEND); + /* Reset the active TWT command to none */ mlme_set_twt_command_in_progress( mac->psoc, (struct qdf_mac_addr *)param->peer_macaddr, @@ -2175,8 +2188,11 @@ sme_process_twt_nudge_dialog_event(struct mac_context *mac, is_evt_allowed = mlme_twt_is_command_in_progress( mac->psoc, (struct qdf_mac_addr *)param->peer_macaddr, param->dialog_id, WLAN_TWT_NUDGE); - if (!is_evt_allowed) + if (!is_evt_allowed && + param->dialog_id != WLAN_ALL_SESSIONS_DIALOG_ID) { + sme_debug("Nudge event dropped"); return; + } callback = mac->sme.twt_nudge_dialog_cb; context = mac->sme.twt_nudge_dialog_context; @@ -2203,18 +2219,15 @@ sme_process_twt_resume_dialog_event(struct mac_context *mac, struct wmi_twt_resume_dialog_complete_event_param *param) { twt_resume_dialog_cb callback; - bool is_evt_allowed; - - is_evt_allowed = mlme_twt_is_command_in_progress( - mac->psoc, (struct qdf_mac_addr *)param->peer_macaddr, - param->dialog_id, WLAN_TWT_RESUME); - if (!is_evt_allowed) - return; callback = mac->sme.twt_resume_dialog_cb; if (callback) callback(mac->psoc, param); + ucfg_mlme_set_twt_session_state( + mac->psoc, (struct qdf_mac_addr *)param->peer_macaddr, + param->dialog_id, WLAN_TWT_SETUP_STATE_ACTIVE); + /* Reset the active TWT command to none */ mlme_set_twt_command_in_progress( mac->psoc, (struct qdf_mac_addr *)param->peer_macaddr,