|
@@ -1,5 +1,5 @@
|
|
|
/*
|
|
|
- * Copyright (c) 2013-2016 The Linux Foundation. All rights reserved.
|
|
|
+ * Copyright (c) 2013-2017 The Linux Foundation. All rights reserved.
|
|
|
*
|
|
|
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
|
|
|
*
|
|
@@ -37,6 +37,7 @@
|
|
|
#ifdef WLAN_OPEN_SOURCE
|
|
|
#include <wlan_hdd_includes.h>
|
|
|
#include <wlan_hdd_debugfs.h>
|
|
|
+#include <wlan_hdd_request_manager.h>
|
|
|
#include <wlan_hdd_wowl.h>
|
|
|
#include <cds_sched.h>
|
|
|
|
|
@@ -508,72 +509,54 @@ static ssize_t wcnss_patterngen_write(struct file *file,
|
|
|
}
|
|
|
|
|
|
#ifdef WLAN_POWER_DEBUGFS
|
|
|
-/**
|
|
|
- * hdd_power_debugstats_cb() - callback routine for Power stats debugs
|
|
|
- * @response: Pointer to Power stats response
|
|
|
- * @context: Pointer to statsContext
|
|
|
- *
|
|
|
- * Return: None
|
|
|
- */
|
|
|
+struct power_stats_priv {
|
|
|
+ struct power_stats_response power_stats;
|
|
|
+};
|
|
|
+
|
|
|
+static void hdd_power_debugstats_dealloc(void *priv)
|
|
|
+{
|
|
|
+ struct power_stats_priv *stats = priv;
|
|
|
+ qdf_mem_free(stats->power_stats.debug_registers);
|
|
|
+}
|
|
|
+
|
|
|
static void hdd_power_debugstats_cb(struct power_stats_response *response,
|
|
|
- void *context)
|
|
|
+ void *context)
|
|
|
{
|
|
|
- struct statsContext *stats_context;
|
|
|
- struct power_stats_response *power_stats;
|
|
|
- hdd_adapter_t *adapter;
|
|
|
- uint32_t power_stats_len;
|
|
|
- uint32_t stats_registers_len;
|
|
|
+ struct hdd_request *request;
|
|
|
+ struct power_stats_priv *priv;
|
|
|
+ uint32_t *debug_registers;
|
|
|
+ uint32_t debug_registers_len;
|
|
|
|
|
|
ENTER();
|
|
|
- if (!context) {
|
|
|
- hdd_err("context is NULL");
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- stats_context = (struct statsContext *)context;
|
|
|
|
|
|
- spin_lock(&hdd_context_lock);
|
|
|
- adapter = stats_context->pAdapter;
|
|
|
- if ((POWER_STATS_MAGIC != stats_context->magic) ||
|
|
|
- (!adapter) || (WLAN_HDD_ADAPTER_MAGIC != adapter->magic)) {
|
|
|
- spin_unlock(&hdd_context_lock);
|
|
|
- hdd_err("Invalid context, adapter [%p] magic [%08x]",
|
|
|
- adapter, stats_context->magic);
|
|
|
+ request = hdd_request_get(context);
|
|
|
+ if (!request) {
|
|
|
+ hdd_err("Obsolete request");
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- stats_context->magic = 0;
|
|
|
- stats_registers_len = (sizeof(response->debug_registers[0]) *
|
|
|
- response->num_debug_register);
|
|
|
- power_stats_len = stats_registers_len + sizeof(*power_stats);
|
|
|
- adapter->chip_power_stats = qdf_mem_malloc(power_stats_len);
|
|
|
- if (!adapter->chip_power_stats) {
|
|
|
- hdd_err("Power stats memory alloc fails!");
|
|
|
- goto exit_stats_cb;
|
|
|
+ priv = hdd_request_priv(request);
|
|
|
+
|
|
|
+ /* copy fixed-sized data */
|
|
|
+ priv->power_stats = *response;
|
|
|
+
|
|
|
+ /* copy variable-size data */
|
|
|
+ if (response->num_debug_register) {
|
|
|
+ debug_registers_len = (sizeof(response->debug_registers[0]) *
|
|
|
+ response->num_debug_register);
|
|
|
+ debug_registers = qdf_mem_malloc(debug_registers_len);
|
|
|
+ priv->power_stats.debug_registers = debug_registers;
|
|
|
+ if (debug_registers) {
|
|
|
+ qdf_mem_copy(debug_registers,
|
|
|
+ response->debug_registers,
|
|
|
+ debug_registers_len);
|
|
|
+ } else {
|
|
|
+ hdd_err("Power stats memory alloc fails!");
|
|
|
+ priv->power_stats.num_debug_register = 0;
|
|
|
+ }
|
|
|
}
|
|
|
-
|
|
|
- power_stats = adapter->chip_power_stats;
|
|
|
- power_stats->cumulative_sleep_time_ms
|
|
|
- = response->cumulative_sleep_time_ms;
|
|
|
- power_stats->cumulative_total_on_time_ms
|
|
|
- = response->cumulative_total_on_time_ms;
|
|
|
- power_stats->deep_sleep_enter_counter
|
|
|
- = response->deep_sleep_enter_counter;
|
|
|
- power_stats->last_deep_sleep_enter_tstamp_ms
|
|
|
- = response->last_deep_sleep_enter_tstamp_ms;
|
|
|
- power_stats->debug_register_fmt
|
|
|
- = response->debug_register_fmt;
|
|
|
- power_stats->num_debug_register
|
|
|
- = response->num_debug_register;
|
|
|
-
|
|
|
- power_stats->debug_registers = (uint32_t *)(power_stats + 1);
|
|
|
-
|
|
|
- qdf_mem_copy(power_stats->debug_registers,
|
|
|
- response->debug_registers, stats_registers_len);
|
|
|
-
|
|
|
-exit_stats_cb:
|
|
|
- complete(&stats_context->completion);
|
|
|
- spin_unlock(&hdd_context_lock);
|
|
|
+ hdd_request_complete(request);
|
|
|
+ hdd_request_put(request);
|
|
|
EXIT();
|
|
|
}
|
|
|
|
|
@@ -592,12 +575,20 @@ static ssize_t __wlan_hdd_read_power_debugfs(struct file *file,
|
|
|
{
|
|
|
hdd_adapter_t *adapter;
|
|
|
hdd_context_t *hdd_ctx;
|
|
|
- static struct statsContext context;
|
|
|
+ QDF_STATUS status;
|
|
|
struct power_stats_response *chip_power_stats;
|
|
|
ssize_t ret_cnt = 0;
|
|
|
- int rc = 0, j;
|
|
|
+ int j;
|
|
|
unsigned int len = 0;
|
|
|
- char *power_debugfs_buf;
|
|
|
+ char *power_debugfs_buf = NULL;
|
|
|
+ void *cookie;
|
|
|
+ struct hdd_request *request;
|
|
|
+ struct power_stats_priv *priv;
|
|
|
+ static const struct hdd_request_params params = {
|
|
|
+ .priv_size = sizeof(*priv),
|
|
|
+ .timeout_ms = WLAN_WAIT_TIME_STATS,
|
|
|
+ .dealloc = hdd_power_debugstats_dealloc,
|
|
|
+ };
|
|
|
|
|
|
ENTER();
|
|
|
adapter = (hdd_adapter_t *)file->private_data;
|
|
@@ -611,46 +602,37 @@ static ssize_t __wlan_hdd_read_power_debugfs(struct file *file,
|
|
|
if (0 != ret_cnt)
|
|
|
return ret_cnt;
|
|
|
|
|
|
- if (adapter->chip_power_stats)
|
|
|
- qdf_mem_free(adapter->chip_power_stats);
|
|
|
-
|
|
|
- adapter->chip_power_stats = NULL;
|
|
|
- context.pAdapter = adapter;
|
|
|
- context.magic = POWER_STATS_MAGIC;
|
|
|
-
|
|
|
- init_completion(&context.completion);
|
|
|
+ request = hdd_request_alloc(¶ms);
|
|
|
+ if (!request) {
|
|
|
+ hdd_err("Request allocation failure");
|
|
|
+ return -ENOMEM;
|
|
|
+ }
|
|
|
+ cookie = hdd_request_cookie(request);
|
|
|
|
|
|
- if (QDF_STATUS_SUCCESS !=
|
|
|
- sme_power_debug_stats_req(hdd_ctx->hHal,
|
|
|
- hdd_power_debugstats_cb,
|
|
|
- &context)) {
|
|
|
+ status = sme_power_debug_stats_req(hdd_ctx->hHal,
|
|
|
+ hdd_power_debugstats_cb,
|
|
|
+ cookie);
|
|
|
+ if (QDF_IS_STATUS_ERROR(status)) {
|
|
|
hdd_err("chip power stats request failed");
|
|
|
- return -EINVAL;
|
|
|
+ ret_cnt = -EINVAL;
|
|
|
+ goto cleanup;
|
|
|
}
|
|
|
|
|
|
- rc = wait_for_completion_timeout(&context.completion,
|
|
|
- msecs_to_jiffies(WLAN_WAIT_TIME_POWER_STATS));
|
|
|
- if (!rc) {
|
|
|
+ ret_cnt = hdd_request_wait_for_response(request);
|
|
|
+ if (ret_cnt) {
|
|
|
hdd_err("Target response timed out Power stats");
|
|
|
- /* Invalidate the Stats context magic */
|
|
|
- spin_lock(&hdd_context_lock);
|
|
|
- context.magic = 0;
|
|
|
- spin_unlock(&hdd_context_lock);
|
|
|
- return -ETIMEDOUT;
|
|
|
+ ret_cnt = -ETIMEDOUT;
|
|
|
+ goto cleanup;
|
|
|
}
|
|
|
|
|
|
- chip_power_stats = adapter->chip_power_stats;
|
|
|
- if (!chip_power_stats) {
|
|
|
- hdd_err("Power stats retrieval fails!");
|
|
|
- return -EINVAL;
|
|
|
- }
|
|
|
+ priv = hdd_request_priv(request);
|
|
|
+ chip_power_stats = &priv->power_stats;
|
|
|
|
|
|
power_debugfs_buf = qdf_mem_malloc(POWER_DEBUGFS_BUFFER_MAX_LEN);
|
|
|
if (!power_debugfs_buf) {
|
|
|
hdd_err("Power stats buffer alloc fails!");
|
|
|
- qdf_mem_free(chip_power_stats);
|
|
|
- adapter->chip_power_stats = NULL;
|
|
|
- return -EINVAL;
|
|
|
+ ret_cnt = -EINVAL;
|
|
|
+ goto cleanup;
|
|
|
}
|
|
|
|
|
|
len += scnprintf(power_debugfs_buf, POWER_DEBUGFS_BUFFER_MAX_LEN,
|
|
@@ -678,12 +660,13 @@ static ssize_t __wlan_hdd_read_power_debugfs(struct file *file,
|
|
|
j = chip_power_stats->num_debug_register;
|
|
|
}
|
|
|
|
|
|
- qdf_mem_free(chip_power_stats);
|
|
|
- adapter->chip_power_stats = NULL;
|
|
|
-
|
|
|
ret_cnt = simple_read_from_buffer(buf, count, pos,
|
|
|
- power_debugfs_buf, len);
|
|
|
+ power_debugfs_buf, len);
|
|
|
+
|
|
|
+ cleanup:
|
|
|
qdf_mem_free(power_debugfs_buf);
|
|
|
+ hdd_request_put(request);
|
|
|
+
|
|
|
return ret_cnt;
|
|
|
}
|
|
|
|