qcacld-3.0: Add Host Driver support for Chip Power stats debugfs
Implementation of Host driver support to collect chip power stats from firmware and display the stats in "adb shell cat /sys/kernel/debug/wlan0/power_stats". Change-Id: I19595ebf5a6870a0ee4d3cc2ff47d18eb24d213c CRs-Fixed: 1045057
This commit is contained in:
parent
2560111dd2
commit
dc400d2572
9
Kbuild
9
Kbuild
@ -88,6 +88,11 @@ ifeq ($(KERNEL_BUILD), 0)
|
||||
#Flag to enable Legacy Fast Roaming3(LFR3)
|
||||
CONFIG_QCACLD_WLAN_LFR3 := y
|
||||
|
||||
#Enable Power debugfs feature only if debug_fs is enabled
|
||||
ifeq ($(CONFIG_DEBUG_FS), y)
|
||||
CONFIG_WLAN_POWER_DEBUGFS := y
|
||||
endif
|
||||
|
||||
# JB kernel has CPU enablement patches, so enable
|
||||
ifeq ($(CONFIG_ROME_IF),pci)
|
||||
CONFIG_PRIMA_WLAN_11AC_HIGH_TP := y
|
||||
@ -1325,6 +1330,10 @@ ifeq ($(CONFIG_QCACLD_WLAN_LFR2),y)
|
||||
CDEFINES += -DWLAN_FEATURE_HOST_ROAM
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_WLAN_POWER_DEBUGFS), y)
|
||||
CDEFINES += -DWLAN_POWER_DEBUGFS
|
||||
endif
|
||||
|
||||
ifeq ($(BUILD_DIAG_VERSION),1)
|
||||
CDEFINES += -DFEATURE_WLAN_DIAG_SUPPORT
|
||||
CDEFINES += -DFEATURE_WLAN_DIAG_SUPPORT_CSR
|
||||
|
@ -122,6 +122,7 @@
|
||||
#define WLAN_WAIT_TIME_POWER 800
|
||||
#define WLAN_WAIT_TIME_COUNTRY 1000
|
||||
#define WLAN_WAIT_TIME_LINK_STATUS 800
|
||||
#define WLAN_WAIT_TIME_POWER_STATS 800
|
||||
/* Amount of time to wait for sme close session callback.
|
||||
This value should be larger than the timeout used by WDI to wait for
|
||||
a response from WCNSS */
|
||||
@ -330,6 +331,7 @@ extern spinlock_t hdd_context_lock;
|
||||
#define LINK_STATUS_MAGIC 0x4C4B5354 /* LINKSTATUS(LNST) */
|
||||
#define TEMP_CONTEXT_MAGIC 0x74656d70 /* TEMP (temperature) */
|
||||
#define BPF_CONTEXT_MAGIC 0x4575354 /* BPF */
|
||||
#define POWER_STATS_MAGIC 0x14111990
|
||||
|
||||
/* MAX OS Q block time value in msec
|
||||
* Prevent from permanent stall, resume OS Q if timer expired */
|
||||
@ -1138,6 +1140,7 @@ struct hdd_adapter_s {
|
||||
*/
|
||||
uint8_t pre_cac_chan;
|
||||
struct hdd_connect_pm_context connect_rpm_ctx;
|
||||
struct power_stats_response *chip_power_stats;
|
||||
};
|
||||
|
||||
#define WLAN_HDD_GET_STATION_CTX_PTR(pAdapter) (&(pAdapter)->sessionCtx.station)
|
||||
|
@ -47,6 +47,10 @@
|
||||
#define MAX_USER_COMMAND_SIZE_WOWL_PATTERN 512
|
||||
#define MAX_USER_COMMAND_SIZE_FRAME 4096
|
||||
|
||||
#ifdef WLAN_POWER_DEBUGFS
|
||||
#define POWER_DEBUGFS_BUFFER_MAX_LEN 4096
|
||||
#endif
|
||||
|
||||
/**
|
||||
* __wcnss_wowenable_write() - wow_enable debugfs handler
|
||||
* @file: debugfs file handle
|
||||
@ -506,6 +510,241 @@ static ssize_t wcnss_patterngen_write(struct file *file,
|
||||
return ret;
|
||||
}
|
||||
|
||||
#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
|
||||
*/
|
||||
static void hdd_power_debugstats_cb(struct power_stats_response *response,
|
||||
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;
|
||||
|
||||
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);
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
EXIT();
|
||||
}
|
||||
|
||||
/**
|
||||
* __wlan_hdd_read_power_debugfs() - API to collect Chip power stats from FW
|
||||
* @file: file pointer
|
||||
* @buf: buffer
|
||||
* @count: count
|
||||
* @pos: position pointer
|
||||
*
|
||||
* Return: Number of bytes read on success, error number otherwise
|
||||
*/
|
||||
static ssize_t __wlan_hdd_read_power_debugfs(struct file *file,
|
||||
char __user *buf,
|
||||
size_t count, loff_t *pos)
|
||||
{
|
||||
hdd_adapter_t *adapter;
|
||||
hdd_context_t *hdd_ctx;
|
||||
static struct statsContext context;
|
||||
struct power_stats_response *chip_power_stats;
|
||||
ssize_t ret_cnt = 0;
|
||||
int rc = 0, j;
|
||||
unsigned int len = 0;
|
||||
char *power_debugfs_buf;
|
||||
|
||||
ENTER();
|
||||
adapter = (hdd_adapter_t *)file->private_data;
|
||||
if ((!adapter) || (WLAN_HDD_ADAPTER_MAGIC != adapter->magic)) {
|
||||
hdd_err("Invalid adapter or adapter has invalid magic");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
hdd_ctx = WLAN_HDD_GET_CTX(adapter);
|
||||
ret_cnt = wlan_hdd_validate_context(hdd_ctx);
|
||||
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);
|
||||
|
||||
if (QDF_STATUS_SUCCESS !=
|
||||
sme_power_debug_stats_req(hdd_ctx->hHal,
|
||||
hdd_power_debugstats_cb,
|
||||
&context)) {
|
||||
hdd_err("chip power stats request failed");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
rc = wait_for_completion_timeout(&context.completion,
|
||||
msecs_to_jiffies(WLAN_WAIT_TIME_POWER_STATS));
|
||||
if (!rc) {
|
||||
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;
|
||||
}
|
||||
|
||||
chip_power_stats = adapter->chip_power_stats;
|
||||
if (!chip_power_stats) {
|
||||
hdd_err("Power stats retrieval fails!");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
len += scnprintf(power_debugfs_buf, POWER_DEBUGFS_BUFFER_MAX_LEN,
|
||||
"POWER DEBUG STATS\n=================\n"
|
||||
"cumulative_sleep_time_ms: %d\n"
|
||||
"cumulative_total_on_time_ms: %d\n"
|
||||
"deep_sleep_enter_counter: %d\n"
|
||||
"last_deep_sleep_enter_tstamp_ms: %d\n"
|
||||
"debug_register_fmt: %d\n"
|
||||
"num_debug_register: %d\n",
|
||||
chip_power_stats->cumulative_sleep_time_ms,
|
||||
chip_power_stats->cumulative_total_on_time_ms,
|
||||
chip_power_stats->deep_sleep_enter_counter,
|
||||
chip_power_stats->last_deep_sleep_enter_tstamp_ms,
|
||||
chip_power_stats->debug_register_fmt,
|
||||
chip_power_stats->num_debug_register);
|
||||
|
||||
for (j = 0; j < chip_power_stats->num_debug_register; j++) {
|
||||
if ((POWER_DEBUGFS_BUFFER_MAX_LEN - len) > 0)
|
||||
len += scnprintf(power_debugfs_buf + len,
|
||||
POWER_DEBUGFS_BUFFER_MAX_LEN - len,
|
||||
"debug_registers[%d]: 0x%x\n", j,
|
||||
chip_power_stats->debug_registers[j]);
|
||||
else
|
||||
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);
|
||||
qdf_mem_free(power_debugfs_buf);
|
||||
return ret_cnt;
|
||||
}
|
||||
|
||||
/**
|
||||
* wlan_hdd_read_power_debugfs() - SSR wrapper function to read power debugfs
|
||||
* @file: file pointer
|
||||
* @buf: buffer
|
||||
* @count: count
|
||||
* @pos: position pointer
|
||||
*
|
||||
* Return: Number of bytes read on success, error number otherwise
|
||||
*/
|
||||
static ssize_t wlan_hdd_read_power_debugfs(struct file *file,
|
||||
char __user *buf,
|
||||
size_t count, loff_t *pos)
|
||||
{
|
||||
int ret;
|
||||
|
||||
cds_ssr_protect(__func__);
|
||||
ret = __wlan_hdd_read_power_debugfs(file, buf, count, pos);
|
||||
cds_ssr_unprotect(__func__);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* __wlan_hdd_open_power_debugfs() - Function to save private on open
|
||||
* @inode: Pointer to inode structure
|
||||
* @file: file pointer
|
||||
*
|
||||
* Return: zero
|
||||
*/
|
||||
static int __wlan_hdd_open_power_debugfs(struct inode *inode, struct file *file)
|
||||
{
|
||||
file->private_data = inode->i_private;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* wlan_hdd_open_power_debugfs() - SSR wrapper function to save private on open
|
||||
* @inode: Pointer to inode structure
|
||||
* @file: file pointer
|
||||
*
|
||||
* Return: zero
|
||||
*/
|
||||
static int wlan_hdd_open_power_debugfs(struct inode *inode, struct file *file)
|
||||
{
|
||||
int ret;
|
||||
|
||||
cds_ssr_protect(__func__);
|
||||
ret = __wlan_hdd_open_power_debugfs(inode, file);
|
||||
cds_ssr_unprotect(__func__);
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* __wcnss_debugfs_open() - Generic debugfs open() handler
|
||||
* @inode: inode of the debugfs file
|
||||
@ -577,6 +816,37 @@ static const struct file_operations fops_patterngen = {
|
||||
.llseek = default_llseek,
|
||||
};
|
||||
|
||||
#ifdef WLAN_POWER_DEBUGFS
|
||||
static const struct file_operations fops_powerdebugs = {
|
||||
.read = wlan_hdd_read_power_debugfs,
|
||||
.open = wlan_hdd_open_power_debugfs,
|
||||
.owner = THIS_MODULE,
|
||||
.llseek = default_llseek,
|
||||
};
|
||||
|
||||
/**
|
||||
* wlan_hdd_create_power_stats_file() - API to create power stats file
|
||||
* @adapter: interface adapter pointer
|
||||
*
|
||||
* Return: QDF_STATUS
|
||||
*/
|
||||
static QDF_STATUS wlan_hdd_create_power_stats_file(hdd_adapter_t *adapter)
|
||||
{
|
||||
if (!debugfs_create_file("power_stats", S_IRUSR | S_IRGRP | S_IROTH,
|
||||
adapter->debugfs_phy, adapter,
|
||||
&fops_powerdebugs))
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
#else
|
||||
static QDF_STATUS wlan_hdd_create_power_stats_file(hdd_adapter_t *adapter)
|
||||
{
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* hdd_debugfs_init() - Initialize debugfs interface
|
||||
* @adapter: interface adapter pointer
|
||||
@ -612,6 +882,9 @@ QDF_STATUS hdd_debugfs_init(hdd_adapter_t *adapter)
|
||||
&fops_patterngen))
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
|
||||
if (QDF_STATUS_SUCCESS != wlan_hdd_create_power_stats_file(adapter))
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -4901,6 +4901,28 @@ typedef struct {
|
||||
uint8_t stopReq;
|
||||
} tSirLLStatsClearReq, *tpSirLLStatsClearReq;
|
||||
|
||||
#ifdef WLAN_POWER_DEBUGFS
|
||||
/**
|
||||
* struct power_stats_response - Power stats response
|
||||
* @cumulative_sleep_time_ms: cumulative sleep time in ms
|
||||
* @cumulative_total_on_time_ms: total awake time in ms
|
||||
* @deep_sleep_enter_counter: deep sleep enter counter
|
||||
* @last_deep_sleep_enter_tstamp_ms: last deep sleep enter timestamp
|
||||
* @debug_register_fmt: debug registers format
|
||||
* @num_debug_register: number of debug registers
|
||||
* @debug_registers: Pointer to the debug registers buffer
|
||||
*/
|
||||
struct power_stats_response {
|
||||
uint32_t cumulative_sleep_time_ms;
|
||||
uint32_t cumulative_total_on_time_ms;
|
||||
uint32_t deep_sleep_enter_counter;
|
||||
uint32_t last_deep_sleep_enter_tstamp_ms;
|
||||
uint32_t debug_register_fmt;
|
||||
uint32_t num_debug_register;
|
||||
uint32_t *debug_registers;
|
||||
};
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
uint8_t oui[WIFI_SCANNING_MAC_OUI_LENGTH];
|
||||
} tSirScanMacOui, *tpSirScanMacOui;
|
||||
|
@ -640,6 +640,8 @@ typedef struct sSirMbMsgP2p {
|
||||
#define SIR_HAL_SHORT_RETRY_LIMIT_CNT (SIR_HAL_ITC_MSG_TYPES_BEGIN + 365)
|
||||
#define SIR_HAL_LONG_RETRY_LIMIT_CNT (SIR_HAL_ITC_MSG_TYPES_BEGIN + 366)
|
||||
#define SIR_HAL_UPDATE_TX_FAIL_CNT_TH (SIR_HAL_ITC_MSG_TYPES_BEGIN + 367)
|
||||
#define SIR_HAL_POWER_DEBUG_STATS_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 368)
|
||||
|
||||
#define SIR_HAL_MSG_TYPES_END (SIR_HAL_MSG_TYPES_BEGIN + 0x1FF)
|
||||
|
||||
/* CFG message types */
|
||||
|
@ -1358,4 +1358,9 @@ QDF_STATUS sme_update_sta_inactivity_timeout(tHalHandle hal_handle,
|
||||
*/
|
||||
QDF_STATUS sme_set_lost_link_info_cb(tHalHandle hal,
|
||||
void (*cb)(void *, struct sir_lost_link_info *));
|
||||
#ifdef WLAN_POWER_DEBUGFS
|
||||
QDF_STATUS sme_power_debug_stats_req(tHalHandle hal, void (*callback_fn)
|
||||
(struct power_stats_response *response,
|
||||
void *context), void *power_stats_context);
|
||||
#endif
|
||||
#endif /* #if !defined( __SME_API_H ) */
|
||||
|
@ -183,6 +183,12 @@ typedef struct tagSmeStruct {
|
||||
void (*pLinkLayerStatsIndCallback)(void *callbackContext,
|
||||
int indType, void *pRsp);
|
||||
#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
|
||||
|
||||
#ifdef WLAN_POWER_DEBUGFS
|
||||
void *power_debug_stats_context;
|
||||
void (*power_stats_resp_callback)(struct power_stats_response *rsp,
|
||||
void *callback_context);
|
||||
#endif
|
||||
#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
|
||||
void (*pAutoShutdownNotificationCb)(void);
|
||||
#endif
|
||||
|
@ -14362,6 +14362,46 @@ QDF_STATUS sme_reset_link_layer_stats_ind_cb(tHalHandle h_hal)
|
||||
|
||||
#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
|
||||
|
||||
#ifdef WLAN_POWER_DEBUGFS
|
||||
/**
|
||||
* sme_power_debug_stats_req() - SME API to collect Power debug stats
|
||||
* @callback_fn: Pointer to the callback function for Power stats event
|
||||
* @power_stats_context: Pointer to context
|
||||
*
|
||||
* Return: QDF_STATUS
|
||||
*/
|
||||
QDF_STATUS sme_power_debug_stats_req(tHalHandle hal, void (*callback_fn)
|
||||
(struct power_stats_response *response,
|
||||
void *context), void *power_stats_context)
|
||||
{
|
||||
QDF_STATUS status = QDF_STATUS_SUCCESS;
|
||||
tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
|
||||
cds_msg_t msg;
|
||||
|
||||
status = sme_acquire_global_lock(&mac_ctx->sme);
|
||||
if (QDF_IS_STATUS_SUCCESS(status)) {
|
||||
if (!callback_fn) {
|
||||
sms_log(mac_ctx, LOGE,
|
||||
FL("Indication callback did not registered"));
|
||||
sme_release_global_lock(&mac_ctx->sme);
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
|
||||
mac_ctx->sme.power_debug_stats_context = power_stats_context;
|
||||
mac_ctx->sme.power_stats_resp_callback = callback_fn;
|
||||
msg.bodyptr = NULL;
|
||||
msg.type = WMA_POWER_DEBUG_STATS_REQ;
|
||||
status = cds_mq_post_message(QDF_MODULE_ID_WMA, &msg);
|
||||
if (!QDF_IS_STATUS_SUCCESS(status)) {
|
||||
sms_log(mac_ctx, LOGE,
|
||||
FL("not able to post WDA_POWER_DEBUG_STATS_REQ"));
|
||||
}
|
||||
sme_release_global_lock(&mac_ctx->sme);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* sme_fw_mem_dump_register_cb() - Register fw memory dump callback
|
||||
*
|
||||
|
@ -1231,4 +1231,6 @@ static inline int wma_encrypt_decrypt_msg_handler(void *handle, uint8_t *data,
|
||||
*/
|
||||
void wma_lost_link_info_handler(tp_wma_handle wma, uint32_t vdev_id,
|
||||
int32_t rssi);
|
||||
int wma_unified_power_debug_stats_event_handler(void *handle,
|
||||
uint8_t *cmd_param_info, uint32_t len);
|
||||
#endif
|
||||
|
@ -477,6 +477,8 @@
|
||||
#define WMA_UPDATE_WEP_DEFAULT_KEY SIR_HAL_UPDATE_WEP_DEFAULT_KEY
|
||||
#define WMA_SEND_FREQ_RANGE_CONTROL_IND SIR_HAL_SEND_FREQ_RANGE_CONTROL_IND
|
||||
#define WMA_ENCRYPT_DECRYPT_MSG SIR_HAL_ENCRYPT_DECRYPT_MSG
|
||||
#define WMA_POWER_DEBUG_STATS_REQ SIR_HAL_POWER_DEBUG_STATS_REQ
|
||||
|
||||
/* Bit 6 will be used to control BD rate for Management frames */
|
||||
#define HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME 0x40
|
||||
|
||||
|
@ -8516,3 +8516,87 @@ int wma_encrypt_decrypt_msg_handler(void *handle, uint8_t *data,
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* wma_unified_power_debug_stats_event_handler() - WMA handler function to
|
||||
* handle Power stats event from firmware
|
||||
* @handle: Pointer to wma handle
|
||||
* @cmd_param_info: Pointer to Power stats event TLV
|
||||
* @len: Length of the cmd_param_info
|
||||
*
|
||||
* Return: 0 on success, error number otherwise
|
||||
*/
|
||||
#ifdef WLAN_POWER_DEBUGFS
|
||||
int wma_unified_power_debug_stats_event_handler(void *handle,
|
||||
uint8_t *cmd_param_info, uint32_t len)
|
||||
{
|
||||
WMI_PDEV_CHIP_POWER_STATS_EVENTID_param_tlvs *param_tlvs;
|
||||
struct power_stats_response *power_stats_results;
|
||||
wmi_pdev_chip_power_stats_event_fixed_param *param_buf;
|
||||
uint32_t power_stats_len, stats_registers_len, *debug_registers;
|
||||
|
||||
tpAniSirGlobal mac = (tpAniSirGlobal)cds_get_context(QDF_MODULE_ID_PE);
|
||||
param_tlvs =
|
||||
(WMI_PDEV_CHIP_POWER_STATS_EVENTID_param_tlvs *) cmd_param_info;
|
||||
|
||||
param_buf = (wmi_pdev_chip_power_stats_event_fixed_param *)
|
||||
param_tlvs->fixed_param;
|
||||
if (!mac || !mac->sme.power_stats_resp_callback) {
|
||||
WMA_LOGD("%s: NULL mac ptr or HDD callback is null", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!param_buf) {
|
||||
WMA_LOGD("%s: NULL power stats event fixed param", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
debug_registers = param_tlvs->debug_registers;
|
||||
stats_registers_len =
|
||||
(sizeof(uint32_t) * param_buf->num_debug_register);
|
||||
power_stats_len = stats_registers_len + sizeof(*power_stats_results);
|
||||
power_stats_results = qdf_mem_malloc(power_stats_len);
|
||||
if (!power_stats_results) {
|
||||
WMA_LOGD("%s: could not allocate mem for power stats results",
|
||||
__func__);
|
||||
return -ENOMEM;
|
||||
}
|
||||
WMA_LOGD("Cumulative sleep time %d cumulative total on time %d deep sleep enter counter %d last deep sleep enter tstamp ts %d debug registers fmt %d num debug register %d",
|
||||
param_buf->cumulative_sleep_time_ms,
|
||||
param_buf->cumulative_total_on_time_ms,
|
||||
param_buf->deep_sleep_enter_counter,
|
||||
param_buf->last_deep_sleep_enter_tstamp_ms,
|
||||
param_buf->debug_register_fmt,
|
||||
param_buf->num_debug_register);
|
||||
|
||||
power_stats_results->cumulative_sleep_time_ms
|
||||
= param_buf->cumulative_sleep_time_ms;
|
||||
power_stats_results->cumulative_total_on_time_ms
|
||||
= param_buf->cumulative_total_on_time_ms;
|
||||
power_stats_results->deep_sleep_enter_counter
|
||||
= param_buf->deep_sleep_enter_counter;
|
||||
power_stats_results->last_deep_sleep_enter_tstamp_ms
|
||||
= param_buf->last_deep_sleep_enter_tstamp_ms;
|
||||
power_stats_results->debug_register_fmt
|
||||
= param_buf->debug_register_fmt;
|
||||
power_stats_results->num_debug_register
|
||||
= param_buf->num_debug_register;
|
||||
|
||||
power_stats_results->debug_registers
|
||||
= (uint32_t *)(power_stats_results + 1);
|
||||
|
||||
qdf_mem_copy(power_stats_results->debug_registers,
|
||||
debug_registers, stats_registers_len);
|
||||
|
||||
mac->sme.power_stats_resp_callback(power_stats_results,
|
||||
mac->sme.power_debug_stats_context);
|
||||
qdf_mem_free(power_stats_results);
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
int wma_unified_power_debug_stats_event_handler(void *handle,
|
||||
uint8_t *cmd_param_info, uint32_t len)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
@ -2164,6 +2164,15 @@ QDF_STATUS wma_open(struct wlan_objmgr_psoc *psoc, void *cds_context,
|
||||
WMI_UPDATE_STATS_EVENTID,
|
||||
wma_stats_event_handler,
|
||||
WMA_RX_SERIALIZER_CTX);
|
||||
|
||||
#ifdef WLAN_POWER_DEBUGFS
|
||||
/* register for Chip Power stats event */
|
||||
wmi_unified_register_event_handler(wma_handle->wmi_handle,
|
||||
WMI_PDEV_CHIP_POWER_STATS_EVENTID,
|
||||
wma_unified_power_debug_stats_event_handler,
|
||||
WMA_RX_SERIALIZER_CTX);
|
||||
#endif
|
||||
|
||||
/* register for linkspeed response event */
|
||||
wmi_unified_register_event_handler(wma_handle->wmi_handle,
|
||||
WMI_PEER_ESTIMATED_LINKSPEED_EVENTID,
|
||||
@ -6081,6 +6090,62 @@ void wma_update_sta_inactivity_timeout(tp_wma_handle wma,
|
||||
max_unresponsive_time);
|
||||
}
|
||||
|
||||
/**
|
||||
* wma_process_power_debug_stats_req() - Process the Chip Power stats collect
|
||||
* request and pass the Power stats request to Fw
|
||||
* @wma_handle: WMA handle
|
||||
*
|
||||
* Return: QDF_STATUS
|
||||
*/
|
||||
#ifdef WLAN_POWER_DEBUGFS
|
||||
static QDF_STATUS wma_process_power_debug_stats_req(tp_wma_handle wma_handle)
|
||||
{
|
||||
wmi_pdev_get_chip_power_stats_cmd_fixed_param *cmd;
|
||||
int32_t len;
|
||||
wmi_buf_t buf;
|
||||
uint8_t *buf_ptr;
|
||||
int ret;
|
||||
|
||||
if (!wma_handle) {
|
||||
WMA_LOGE("%s: input pointer is NULL", __func__);
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
|
||||
len = sizeof(*cmd);
|
||||
buf = wmi_buf_alloc(wma_handle->wmi_handle, len);
|
||||
if (!buf) {
|
||||
WMA_LOGE("%s: Failed allocate wmi buffer", __func__);
|
||||
return QDF_STATUS_E_NOMEM;
|
||||
}
|
||||
|
||||
buf_ptr = (u_int8_t *) wmi_buf_data(buf);
|
||||
cmd = (wmi_pdev_get_chip_power_stats_cmd_fixed_param *) buf_ptr;
|
||||
|
||||
WMITLV_SET_HDR(&cmd->tlv_header,
|
||||
WMITLV_TAG_STRUC_wmi_get_chip_power_stats_cmd_fixed_param,
|
||||
WMITLV_GET_STRUCT_TLVLEN(
|
||||
wmi_pdev_get_chip_power_stats_cmd_fixed_param));
|
||||
cmd->pdev_id = 0;
|
||||
|
||||
WMA_LOGD("POWER_DEBUG_STATS - Get Request Params; Pdev id - %d",
|
||||
cmd->pdev_id);
|
||||
ret = wmi_unified_cmd_send(wma_handle->wmi_handle, buf, len,
|
||||
WMI_PDEV_GET_CHIP_POWER_STATS_CMDID);
|
||||
if (ret) {
|
||||
WMA_LOGE("%s: Failed to send power debug stats request",
|
||||
__func__);
|
||||
wmi_buf_free(buf);
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
#else
|
||||
static QDF_STATUS wma_process_power_debug_stats_req(tp_wma_handle wma_handle)
|
||||
{
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* wma_mc_process_msg() - process wma messages and call appropriate function.
|
||||
* @cds_context: cds context
|
||||
@ -6915,8 +6980,11 @@ QDF_STATUS wma_mc_process_msg(void *cds_context, cds_msg_t *msg)
|
||||
wma_update_short_retry_limit(wma_handle, msg->bodyptr);
|
||||
qdf_mem_free(msg->bodyptr);
|
||||
break;
|
||||
case SIR_HAL_POWER_DEBUG_STATS_REQ:
|
||||
wma_process_power_debug_stats_req(wma_handle);
|
||||
break;
|
||||
default:
|
||||
WMA_LOGD("unknow msg type %x", msg->type);
|
||||
WMA_LOGD("unknown msg type %x", msg->type);
|
||||
/* Do Nothing? MSG Body should be freed at here */
|
||||
if (NULL != msg->bodyptr) {
|
||||
qdf_mem_free(msg->bodyptr);
|
||||
|
Loading…
Reference in New Issue
Block a user