--- a/drivers/net/wireless/ath/ath11k/debug_htt_stats.c +++ b/drivers/net/wireless/ath/ath11k/debug_htt_stats.c @@ -4330,9 +4330,11 @@ void ath11k_dbg_htt_ext_stats_handler(st return; spin_lock_bh(&ar->debug.htt_stats.lock); - if (!stats_req->done) + + stats_req->done = FIELD_GET(HTT_T2H_EXT_STATS_INFO1_DONE, msg->info1); + if (stats_req->done) send_completion = true; - stats_req->done = true; + spin_unlock_bh(&ar->debug.htt_stats.lock); len = FIELD_GET(HTT_T2H_EXT_STATS_INFO1_LENGTH, msg->info1); @@ -4496,28 +4498,54 @@ static int ath11k_open_htt_stats(struct if (type == ATH11K_DBG_HTT_EXT_STATS_RESET) return -EPERM; + mutex_lock(&ar->conf_mutex); + + if (ar->state != ATH11K_STATE_ON) { + ret = -ENETDOWN; + goto err_unlock; + } + + if (ar->debug.htt_stats.stats_req) { + ret = -EAGAIN; + goto err_unlock; + } + stats_req = vzalloc(sizeof(*stats_req) + ATH11K_HTT_STATS_BUF_SIZE); - if (!stats_req) - return -ENOMEM; + if (!stats_req) { + ret = -ENOMEM; + goto err_unlock; + } - mutex_lock(&ar->conf_mutex); ar->debug.htt_stats.stats_req = stats_req; stats_req->type = type; + ret = ath11k_dbg_htt_stats_req(ar); - mutex_unlock(&ar->conf_mutex); if (ret < 0) goto out; file->private_data = stats_req; + + mutex_unlock(&ar->conf_mutex); + return 0; out: vfree(stats_req); + ar->debug.htt_stats.stats_req = NULL; +err_unlock: + mutex_unlock(&ar->conf_mutex); + return ret; } static int ath11k_release_htt_stats(struct inode *inode, struct file *file) { + struct ath11k *ar = inode->i_private; + + mutex_lock(&ar->conf_mutex); vfree(file->private_data); + ar->debug.htt_stats.stats_req = NULL; + mutex_unlock(&ar->conf_mutex); + return 0; } @@ -4581,7 +4609,6 @@ static ssize_t ath11k_write_htt_stats_re 0ULL); if (ret) { ath11k_warn(ar->ab, "failed to send htt stats request: %d\n", ret); - mutex_unlock(&ar->conf_mutex); return ret; } --- a/drivers/net/wireless/ath/ath11k/dp.h +++ b/drivers/net/wireless/ath/ath11k/dp.h @@ -1627,6 +1627,7 @@ struct htt_ext_stats_cfg_params { * 4 bytes. */ +#define HTT_T2H_EXT_STATS_INFO1_DONE BIT(11) #define HTT_T2H_EXT_STATS_INFO1_LENGTH GENMASK(31, 16) struct ath11k_htt_extd_stats_msg {