From b729f073fc508c51f4b3396d225610971c584172 Mon Sep 17 00:00:00 2001 From: Deeksha Gupta Date: Wed, 17 Feb 2021 16:09:43 +0530 Subject: [PATCH] qcacld-3.0: Allow only one twt statistics and clear statistics command Don't allow twt statistics or clear statistics command if twt statistics or clear statistics is in_progress. As a Fix, reject the new twt statistic or clear statistic command till existing twt statistic or clear statistic command completion. Change-Id: I710a81ae3409f181689b2e4c9e9d4e583d4aadab CRs-Fixed: 2870592 --- .../inc/wlan_mlme_twt_public_struct.h | 18 +++++--- .../dispatcher/inc/wlan_mlme_twt_ucfg_api.h | 46 +++++++++++++++++++ core/hdd/src/wlan_hdd_twt.c | 33 +++++++++++++ .../cp_stats/src/wlan_cfg80211_mc_cp_stats.c | 18 +++++++- 4 files changed, 106 insertions(+), 9 deletions(-) diff --git a/components/mlme/dispatcher/inc/wlan_mlme_twt_public_struct.h b/components/mlme/dispatcher/inc/wlan_mlme_twt_public_struct.h index bd3b048447929..35d126ef17013 100644 --- a/components/mlme/dispatcher/inc/wlan_mlme_twt_public_struct.h +++ b/components/mlme/dispatcher/inc/wlan_mlme_twt_public_struct.h @@ -29,16 +29,20 @@ * @WLAN_TWT_SUSPEND: TWT suspend * @WLAN_TWT_RESUME: TWT resume * @WLAN_TWT_NUDGE: TWT nudge + * @WLAN_TWT_STATISTICS: TWT statistics + * @WLAN_TWT_CLEAR_STATISTICS: TWT clear statistics * @WLAN_TWT_ANY: Indicates one of the commands is in progress. */ enum wlan_twt_commands { - WLAN_TWT_NONE = 0, - WLAN_TWT_SETUP = BIT(0), - WLAN_TWT_TERMINATE = BIT(1), - WLAN_TWT_SUSPEND = BIT(2), - WLAN_TWT_RESUME = BIT(3), - WLAN_TWT_NUDGE = BIT(4), - WLAN_TWT_ANY = 0xFF, + WLAN_TWT_NONE = 0, + WLAN_TWT_SETUP = BIT(0), + WLAN_TWT_TERMINATE = BIT(1), + WLAN_TWT_SUSPEND = BIT(2), + WLAN_TWT_RESUME = BIT(3), + WLAN_TWT_NUDGE = BIT(4), + WLAN_TWT_STATISTICS = BIT(5), + WLAN_TWT_CLEAR_STATISTICS = BIT(6), + WLAN_TWT_ANY = 0xFF, }; /** 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 bbcb2d0b2b949..d96c46334cf97 100644 --- a/components/mlme/dispatcher/inc/wlan_mlme_twt_ucfg_api.h +++ b/components/mlme/dispatcher/inc/wlan_mlme_twt_ucfg_api.h @@ -216,6 +216,34 @@ ucfg_mlme_is_twt_setup_in_progress(struct wlan_objmgr_psoc *psoc, return mlme_is_twt_setup_in_progress(psoc, peer_mac, dialog_id); } +/** + * ucfg_mlme_twt_is_command_in_progress() - Get TWT command in progress + * @psoc: Pointer to global PSOC object + * @peer_mac: Global peer mac address + * @dialog_id: TWT session dialog id + * @cmd: TWT command + * + * Return: True if given command is in progress + */ + +static inline bool +ucfg_mlme_twt_is_command_in_progress(struct wlan_objmgr_psoc *psoc, + struct qdf_mac_addr *peer_mac, + uint8_t dialog_id, + enum wlan_twt_commands cmd) +{ + return mlme_twt_is_command_in_progress(psoc, peer_mac, dialog_id, cmd); +} + +static inline QDF_STATUS +ucfg_mlme_set_twt_command_in_progress(struct wlan_objmgr_psoc *psoc, + struct qdf_mac_addr *peer_mac, + uint8_t dialog_id, + enum wlan_twt_commands cmd) +{ + return mlme_set_twt_command_in_progress(psoc, peer_mac, dialog_id, cmd); +} + /** * ucfg_mlme_set_twt_setup_done() - Set TWT setup done flag * @psoc: Pointer to global PSOC object @@ -479,6 +507,24 @@ ucfg_mlme_is_twt_setup_in_progress(struct wlan_objmgr_psoc *psoc, return false; } +static inline QDF_STATUS +ucfg_mlme_set_twt_command_in_progress(struct wlan_objmgr_psoc *psoc, + struct qdf_mac_addr *peer_mac, + uint8_t dialog_id, + enum wlan_twt_commands cmd) +{ + return QDF_STATUS_E_FAILURE; +} + +static inline bool +ucfg_mlme_twt_is_command_in_progress(struct wlan_objmgr_psoc *psoc, + struct qdf_mac_addr *peer_mac, + uint8_t dialog_id, + enum wlan_twt_commands cmd) +{ + return false; +} + static inline QDF_STATUS ucfg_mlme_get_twt_bcast_requestor(struct wlan_objmgr_psoc *psoc, bool *val) diff --git a/core/hdd/src/wlan_hdd_twt.c b/core/hdd/src/wlan_hdd_twt.c index dc30dd1d24efc..4ba20c57420a3 100644 --- a/core/hdd/src/wlan_hdd_twt.c +++ b/core/hdd/src/wlan_hdd_twt.c @@ -2719,12 +2719,25 @@ static int hdd_twt_clear_session_traffic_stats(struct hdd_adapter *adapter, return -EOPNOTSUPP; } + if (ucfg_mlme_twt_is_command_in_progress(adapter->hdd_ctx->psoc, + &hdd_sta_ctx->conn_info.bssid, + WLAN_ALL_SESSIONS_DIALOG_ID, + WLAN_TWT_STATISTICS) || + ucfg_mlme_twt_is_command_in_progress(adapter->hdd_ctx->psoc, + &hdd_sta_ctx->conn_info.bssid, + WLAN_ALL_SESSIONS_DIALOG_ID, + WLAN_TWT_CLEAR_STATISTICS)) { + hdd_warn("Already TWT statistics or clear statistics exists"); + return -EALREADY; + } + if (!ucfg_mlme_is_twt_setup_done(adapter->hdd_ctx->psoc, &hdd_sta_ctx->conn_info.bssid, dialog_id)) { hdd_debug("TWT session %d setup incomplete", dialog_id); return -EINVAL; } + ret = wlan_cfg80211_mc_twt_clear_infra_cp_stats(adapter->vdev, dialog_id, peer_mac); @@ -2821,6 +2834,18 @@ static int hdd_twt_get_session_traffic_stats(struct hdd_adapter *adapter, return -EOPNOTSUPP; } + if (ucfg_mlme_twt_is_command_in_progress(adapter->hdd_ctx->psoc, + &hdd_sta_ctx->conn_info.bssid, + WLAN_ALL_SESSIONS_DIALOG_ID, + WLAN_TWT_STATISTICS) || + ucfg_mlme_twt_is_command_in_progress(adapter->hdd_ctx->psoc, + &hdd_sta_ctx->conn_info.bssid, + WLAN_ALL_SESSIONS_DIALOG_ID, + WLAN_TWT_CLEAR_STATISTICS)) { + hdd_warn("Already TWT statistics or clear statistics exists"); + return -EALREADY; + } + id = QCA_WLAN_VENDOR_ATTR_TWT_STATS_FLOW_ID; if (tb[id]) dialog_id = (uint32_t)nla_get_u8(tb[id]); @@ -2842,8 +2867,16 @@ static int hdd_twt_get_session_traffic_stats(struct hdd_adapter *adapter, return -EINVAL; } + ucfg_mlme_set_twt_command_in_progress(adapter->hdd_ctx->psoc, + &hdd_sta_ctx->conn_info.bssid, + dialog_id, + WLAN_TWT_STATISTICS); qdf_status = hdd_twt_request_session_traffic_stats(adapter, dialog_id, peer_mac); + ucfg_mlme_set_twt_command_in_progress(adapter->hdd_ctx->psoc, + &hdd_sta_ctx->conn_info.bssid, + dialog_id, + WLAN_TWT_NONE); return qdf_status_to_os_return(qdf_status); } diff --git a/os_if/cp_stats/src/wlan_cfg80211_mc_cp_stats.c b/os_if/cp_stats/src/wlan_cfg80211_mc_cp_stats.c index cae113c97905d..2c995419f292c 100644 --- a/os_if/cp_stats/src/wlan_cfg80211_mc_cp_stats.c +++ b/os_if/cp_stats/src/wlan_cfg80211_mc_cp_stats.c @@ -32,6 +32,7 @@ #include "cds_utils.h" #include "wlan_hdd_main.h" #include "wlan_hdd_stats.h" +#include "wlan_mlme_twt_ucfg_api.h" /* max time in ms, caller may wait for stats request get serviced */ #define CP_STATS_WAIT_TIME_STAT 800 @@ -852,6 +853,7 @@ wlan_cfg80211_mc_twt_clear_infra_cp_stats( void *cookie; QDF_STATUS status; struct infra_cp_stats_event *priv; + struct wlan_objmgr_psoc *psoc; struct wlan_objmgr_peer *peer; struct osif_request *request; struct infra_cp_stats_cmd_info info = {0}; @@ -863,10 +865,19 @@ wlan_cfg80211_mc_twt_clear_infra_cp_stats( osif_debug("Enter"); + psoc = wlan_vdev_get_psoc(vdev); + if (!psoc) + return -EINVAL; + request = osif_request_alloc(¶ms); if (!request) return -ENOMEM; + ucfg_mlme_set_twt_command_in_progress(psoc, + (struct qdf_mac_addr *)twt_peer_mac, + dialog_id, + WLAN_TWT_CLEAR_STATISTICS); + cookie = osif_request_cookie(request); priv = osif_request_priv(request); @@ -899,8 +910,7 @@ wlan_cfg80211_mc_twt_clear_infra_cp_stats( } wlan_objmgr_peer_release_ref(peer, WLAN_CP_STATS_ID); - status = ucfg_infra_cp_stats_register_resp_cb(wlan_vdev_get_psoc(vdev), - &info); + status = ucfg_infra_cp_stats_register_resp_cb(psoc, &info); if (QDF_IS_STATUS_ERROR(status)) { osif_err("Failed to register resp callback: %d", status); ret = qdf_status_to_os_return(status); @@ -920,6 +930,10 @@ wlan_cfg80211_mc_twt_clear_infra_cp_stats( osif_err("wait failed or timed out ret: %d", ret); clear_twt_stats_fail: + ucfg_mlme_set_twt_command_in_progress(psoc, + (struct qdf_mac_addr *)twt_peer_mac, + dialog_id, + WLAN_TWT_NONE); osif_request_put(request); osif_debug("Exit");