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
This commit is contained in:
Deeksha Gupta 2021-02-17 16:09:43 +05:30 committed by snandini
parent f87d3036a7
commit b729f073fc
4 changed files with 106 additions and 9 deletions

View File

@ -29,6 +29,8 @@
* @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 {
@ -38,6 +40,8 @@ enum wlan_twt_commands {
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,
};

View File

@ -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)

View File

@ -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);
}

View File

@ -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(&params);
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");