qcacmn: DebugFS Improvements for WMI logs
1)Configurable number of bytes to log 2)Add support to record only specific WMI command/events Separate buffers are added to save user specified WMI commands and events 1.To record specific wmi cmd, e.g. WMI_VDEV_START_REQUEST_CMDID echo 0x5003 > /sys/kernel/debug/WMI_SOC0_PDEV0/filtered_wmi_cmds 2.To record specific wmi evt, e.g. WMI_MGMT_RX_EVENTID echo 0x7001 > /sys/kernel/debug/WMI_SOC0_PDEV0/filtered_wmi_evts Results of recorded specific WMI command/events: 1. WMI commands, e.g.: cat /sys/kernel/debug/WMI_SOC0_PDEV0/wmi_filtered_command_log 2. WMI events, e.g.: cat /sys/kernel/debug/WMI_SOC0_PDEV0/wmi_filtered_event_log CRs-Fixed: 2597854 Change-Id: I1e90a13ac0717f1f37ba998fb1d06a990d3f4fa2
This commit is contained in:
199
wmi/inc/wmi_filtered_logging.h
Normal file
199
wmi/inc/wmi_filtered_logging.h
Normal file
@@ -0,0 +1,199 @@
|
||||
/*
|
||||
* Copyright (c) 2015-2020 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for
|
||||
* any purpose with or without fee is hereby granted, provided that the
|
||||
* above copyright notice and this permission notice appear in all
|
||||
* copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
|
||||
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
|
||||
* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
|
||||
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
|
||||
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef WMI_FILTERED_LOGGING_H
|
||||
#define WMI_FILTERED_LOGGING_H
|
||||
|
||||
#include <qdf_debugfs.h>
|
||||
#include "wmi_unified_priv.h"
|
||||
|
||||
#ifdef WMI_INTERFACE_FILTERED_EVENT_LOGGING
|
||||
/**
|
||||
* wmi_specific_cmd_record() - Record user specified command
|
||||
* @wmi_handle: handle to WMI
|
||||
* @id: cmd id
|
||||
* @buf: buf containing cmd details
|
||||
*
|
||||
* Check if the command id is in target list,
|
||||
* if found, record it.
|
||||
*
|
||||
* Context: the function will not sleep, caller is expected to hold
|
||||
* proper locking.
|
||||
*
|
||||
* Return: none
|
||||
*/
|
||||
void wmi_specific_cmd_record(wmi_unified_t wmi_handle,
|
||||
uint32_t id, uint8_t *buf);
|
||||
|
||||
/**
|
||||
* wmi_specific_evt_record() - Record user specified event
|
||||
* @wmi_handle: handle to WMI
|
||||
* @id: cmd id
|
||||
* @buf: buf containing event details
|
||||
*
|
||||
* Check if the event id is in target list,
|
||||
* if found, record it.
|
||||
*
|
||||
* Context: the function will not sleep, caller is expected to hold
|
||||
* proper locking.
|
||||
*
|
||||
* Return: none
|
||||
*/
|
||||
void wmi_specific_evt_record(wmi_unified_t wmi_handle,
|
||||
uint32_t id, uint8_t *buf);
|
||||
|
||||
/**
|
||||
* wmi_filtered_logging_init() - initialize filtered logging
|
||||
* @wmi_handle: handle to WMI
|
||||
*
|
||||
* Context: the function will not sleep, no lock needed
|
||||
*
|
||||
* Return: none
|
||||
*/
|
||||
void wmi_filtered_logging_init(wmi_unified_t wmi_handle);
|
||||
|
||||
/**
|
||||
* wmi_filtered_logging_free() - free the buffers for filtered logging
|
||||
* @wmi_handle: handle to WMI
|
||||
*
|
||||
* Context: the function will not sleep, no lock needed
|
||||
*
|
||||
* Return: none
|
||||
*/
|
||||
void wmi_filtered_logging_free(wmi_unified_t wmi_handle);
|
||||
|
||||
/*
|
||||
* Debugfs read/write functions
|
||||
*/
|
||||
/**
|
||||
* debug_filtered_wmi_cmds_show() - debugfs read function for filtered_wmi_cmds
|
||||
* @m: seq_file handle
|
||||
* @v: not used, offset of read
|
||||
* Return: number of bytes read
|
||||
*/
|
||||
int debug_filtered_wmi_cmds_show(qdf_debugfs_file_t m, void *v);
|
||||
|
||||
/**
|
||||
* debug_filtered_wmi_evts_show() - debugfs read function for filtered_wmi_evts
|
||||
* @m: seq_file handle
|
||||
* @v: not used, offset of read
|
||||
* Return: number of bytes read
|
||||
*/
|
||||
int debug_filtered_wmi_evts_show(qdf_debugfs_file_t m, void *v);
|
||||
|
||||
/**
|
||||
* debug_wmi_filtered_command_log_show() - debugfs read function for
|
||||
* wmi_filtered_command_log
|
||||
* @m: seq_file handle
|
||||
* @v: not used, offset of read
|
||||
* Return: number of bytes read
|
||||
*/
|
||||
int debug_wmi_filtered_command_log_show(qdf_debugfs_file_t m, void *v);
|
||||
|
||||
/**
|
||||
* debug_wmi_filtered_event_log_show() - debugfs read function for
|
||||
* wmi_filtered_event_log
|
||||
* @m: seq_file handle
|
||||
* @v: not used, offset of read
|
||||
* Return: number of bytes read
|
||||
*/
|
||||
int debug_wmi_filtered_event_log_show(qdf_debugfs_file_t m, void *v);
|
||||
|
||||
/**
|
||||
* debug_wmi_filtered_wmi_cmds_write() - debugfs write for filtered_wmi_cmds
|
||||
*
|
||||
* @file: file handler to access wmi_handle
|
||||
* @buf: received data buffer
|
||||
* @count: length of received buffer
|
||||
* @ppos: Not used
|
||||
*
|
||||
* Return: count
|
||||
*/
|
||||
ssize_t debug_filtered_wmi_cmds_write(struct file *file,
|
||||
const char __user *buf,
|
||||
size_t count, loff_t *ppos);
|
||||
|
||||
/**
|
||||
* debug_wmi_filtered_wmi_evts_write() - debugfs write for filtered_wmi_evts
|
||||
*
|
||||
* @file: file handler to access wmi_handle
|
||||
* @buf: received data buffer
|
||||
* @count: length of received buffer
|
||||
* @ppos: Not used
|
||||
*
|
||||
* Return: count
|
||||
*/
|
||||
ssize_t debug_filtered_wmi_evts_write(struct file *file,
|
||||
const char __user *buf,
|
||||
size_t count, loff_t *ppos);
|
||||
|
||||
/**
|
||||
* debug_wmi_filtered_command_log_write() - debugfs write for
|
||||
* filtered_command_log
|
||||
*
|
||||
* @file: file handler to access wmi_handle
|
||||
* @buf: received data buffer
|
||||
* @count: length of received buffer
|
||||
* @ppos: Not used
|
||||
*
|
||||
* Return: count
|
||||
*/
|
||||
ssize_t debug_wmi_filtered_command_log_write(struct file *file,
|
||||
const char __user *buf,
|
||||
size_t count, loff_t *ppos);
|
||||
|
||||
/**
|
||||
* debug_wmi_filtered_event_log_write() - debugfs write for filtered_event_log
|
||||
*
|
||||
* @file: file handler to access wmi_handle
|
||||
* @buf: received data buffer
|
||||
* @count: length of received buffer
|
||||
* @ppos: Not used
|
||||
*
|
||||
* Return: count
|
||||
*/
|
||||
ssize_t debug_wmi_filtered_event_log_write(struct file *file,
|
||||
const char __user *buf,
|
||||
size_t count, loff_t *ppos);
|
||||
|
||||
#else /* WMI_INTERFACE_FILTERED_EVENT_LOGGING */
|
||||
|
||||
static inline void wmi_specific_cmd_record(wmi_unified_t wmi_handle,
|
||||
uint32_t id, uint8_t *buf)
|
||||
{
|
||||
/* do nothing */
|
||||
}
|
||||
|
||||
static inline void wmi_specific_evt_record(wmi_unified_t wmi_handle,
|
||||
uint32_t id, uint8_t *buf)
|
||||
{
|
||||
/* do nothing */
|
||||
}
|
||||
|
||||
static inline void wmi_filtered_logging_init(wmi_unified_t wmi_handle)
|
||||
{
|
||||
/* do nothing */
|
||||
}
|
||||
|
||||
static inline void wmi_filtered_logging_free(wmi_unified_t wmi_handle)
|
||||
{
|
||||
/* do nothing */
|
||||
}
|
||||
#endif /* end of WMI_INTERFACE_FILTERED_EVENT_LOGGING */
|
||||
|
||||
#endif /*WMI_FILTERED_LOGGING_H*/
|
@@ -116,7 +116,9 @@ struct wmi_ext_dbg_msg {
|
||||
#define WMI_EVENT_DEBUG_MAX_ENTRY (1024)
|
||||
#endif
|
||||
|
||||
#ifndef WMI_EVENT_DEBUG_ENTRY_MAX_LENGTH
|
||||
#define WMI_EVENT_DEBUG_ENTRY_MAX_LENGTH (16)
|
||||
#endif
|
||||
|
||||
/* wmi_mgmt commands */
|
||||
#ifndef WMI_MGMT_EVENT_DEBUG_MAX_ENTRY
|
||||
@@ -127,6 +129,16 @@ struct wmi_ext_dbg_msg {
|
||||
#define WMI_DIAG_RX_EVENT_DEBUG_MAX_ENTRY (256)
|
||||
#endif
|
||||
|
||||
#ifdef WMI_INTERFACE_FILTERED_EVENT_LOGGING
|
||||
#ifndef WMI_FILTERED_CMD_EVT_SUPPORTED
|
||||
#define WMI_FILTERED_CMD_EVT_SUPPORTED (10)
|
||||
#endif
|
||||
|
||||
#ifndef WMI_FILTERED_CMD_EVT_MAX_NUM_ENTRY
|
||||
#define WMI_FILTERED_CMD_EVT_MAX_NUM_ENTRY (1024)
|
||||
#endif
|
||||
#endif /* WMI_INTERFACE_FILTERED_EVENT_LOGGING */
|
||||
|
||||
#define wmi_alert(params...) QDF_TRACE_FATAL(QDF_MODULE_ID_WMI, ## params)
|
||||
#define wmi_err(params...) QDF_TRACE_ERROR(QDF_MODULE_ID_WMI, ## params)
|
||||
#define wmi_warn(params...) QDF_TRACE_WARN(QDF_MODULE_ID_WMI, ## params)
|
||||
@@ -234,6 +246,14 @@ struct wmi_log_buf_t {
|
||||
* @wmi_id_to_name - Function refernce to API to convert Command id to
|
||||
* string name
|
||||
* @wmi_log_debugfs_dir - refernce to debugfs directory
|
||||
* @filtered_wmi_cmds - Buffer to save inputs from user on
|
||||
* which WMI commands to record
|
||||
* @filtered_wmi_cmds_idx - target cmd index
|
||||
* @filtered_wmi_evts - Buffer to save inputs from user on
|
||||
* which WMI event to record
|
||||
* @filtered_wmi_evts_idx - target evt index
|
||||
* @wmi_filtered_command_log - buffer to record user specified WMI commands
|
||||
* @wmi_filtered_event_log - buffer to record user specified WMI events
|
||||
*/
|
||||
struct wmi_debug_log_info {
|
||||
struct wmi_log_buf_t wmi_command_log_buf_info;
|
||||
@@ -250,6 +270,25 @@ struct wmi_debug_log_info {
|
||||
qdf_spinlock_t wmi_record_lock;
|
||||
bool wmi_logging_enable;
|
||||
struct dentry *wmi_log_debugfs_dir;
|
||||
|
||||
#ifdef WMI_INTERFACE_FILTERED_EVENT_LOGGING
|
||||
uint32_t *filtered_wmi_cmds;
|
||||
uint32_t filtered_wmi_cmds_idx;
|
||||
uint32_t *filtered_wmi_evts;
|
||||
uint32_t filtered_wmi_evts_idx;
|
||||
struct wmi_log_buf_t *wmi_filtered_command_log;
|
||||
struct wmi_log_buf_t *wmi_filtered_event_log;
|
||||
#endif
|
||||
};
|
||||
|
||||
/**
|
||||
* enum WMI_RECORD_TYPE - User specified WMI logging types
|
||||
* @ WMI_CMD - wmi command id
|
||||
* @ WMI_EVT - wmi event id
|
||||
*/
|
||||
enum WMI_RECORD_TYPE {
|
||||
WMI_CMD = 1,
|
||||
WMI_EVT = 2,
|
||||
};
|
||||
|
||||
#endif /*WMI_INTERFACE_EVENT_LOGGING */
|
||||
@@ -2210,7 +2249,14 @@ struct wmi_host_abi_version {
|
||||
uint32_t abi_version_ns_3;
|
||||
};
|
||||
|
||||
/* number of debugfs entries used */
|
||||
#ifdef WMI_INTERFACE_FILTERED_EVENT_LOGGING
|
||||
/* filtered logging added 4 more entries */
|
||||
#define NUM_DEBUG_INFOS 13
|
||||
#else
|
||||
#define NUM_DEBUG_INFOS 9
|
||||
#endif
|
||||
|
||||
struct wmi_unified {
|
||||
void *scn_handle; /* handle to device */
|
||||
osdev_t osdev; /* handle to use OS-independent services */
|
||||
|
513
wmi/src/wmi_filtered_logging.c
Normal file
513
wmi/src/wmi_filtered_logging.c
Normal file
@@ -0,0 +1,513 @@
|
||||
/*
|
||||
* Copyright (c) 2015-2020 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for
|
||||
* any purpose with or without fee is hereby granted, provided that the
|
||||
* above copyright notice and this permission notice appear in all
|
||||
* copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
|
||||
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
|
||||
* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
|
||||
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
|
||||
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "wmi_filtered_logging.h"
|
||||
|
||||
static struct wmi_log_buf_t *wmi_log_buf_allocate(void)
|
||||
{
|
||||
struct wmi_log_buf_t *cmd_log_buf;
|
||||
int buf_size = WMI_FILTERED_CMD_EVT_MAX_NUM_ENTRY *
|
||||
sizeof(struct wmi_command_debug);
|
||||
|
||||
cmd_log_buf = qdf_mem_malloc(sizeof(struct wmi_log_buf_t));
|
||||
if (!cmd_log_buf)
|
||||
return NULL;
|
||||
|
||||
cmd_log_buf->buf = qdf_mem_malloc(buf_size);
|
||||
if (!cmd_log_buf->buf) {
|
||||
qdf_mem_free(cmd_log_buf);
|
||||
return NULL;
|
||||
}
|
||||
cmd_log_buf->length = 0;
|
||||
cmd_log_buf->buf_tail_idx = 0;
|
||||
cmd_log_buf->size = WMI_FILTERED_CMD_EVT_MAX_NUM_ENTRY;
|
||||
cmd_log_buf->p_buf_tail_idx = &cmd_log_buf->buf_tail_idx;
|
||||
|
||||
return cmd_log_buf;
|
||||
}
|
||||
|
||||
void wmi_filtered_logging_init(wmi_unified_t wmi_handle)
|
||||
{
|
||||
int buf_size = WMI_FILTERED_CMD_EVT_SUPPORTED * sizeof(int);
|
||||
|
||||
/* alloc buffer to save user inputs, for WMI_CMD */
|
||||
wmi_handle->log_info.filtered_wmi_cmds =
|
||||
qdf_mem_malloc(buf_size);
|
||||
if (!wmi_handle->log_info.filtered_wmi_cmds)
|
||||
return;
|
||||
|
||||
wmi_handle->log_info.filtered_wmi_cmds_idx = 0;
|
||||
|
||||
/* alloc buffer to save user interested WMI commands */
|
||||
wmi_handle->log_info.wmi_filtered_command_log = wmi_log_buf_allocate();
|
||||
if (!wmi_handle->log_info.wmi_filtered_command_log)
|
||||
goto fail1;
|
||||
|
||||
/* alloc buffer to save user inputs, for WMI_EVT */
|
||||
wmi_handle->log_info.filtered_wmi_evts =
|
||||
qdf_mem_malloc(buf_size);
|
||||
if (!wmi_handle->log_info.filtered_wmi_evts)
|
||||
goto fail2;
|
||||
|
||||
wmi_handle->log_info.filtered_wmi_evts_idx = 0;
|
||||
|
||||
/* alloc buffer to save user interested WMI events */
|
||||
wmi_handle->log_info.wmi_filtered_event_log = wmi_log_buf_allocate();
|
||||
if (!wmi_handle->log_info.wmi_filtered_event_log)
|
||||
goto fail3;
|
||||
|
||||
return;
|
||||
|
||||
fail3:
|
||||
qdf_mem_free(wmi_handle->log_info.filtered_wmi_evts);
|
||||
wmi_handle->log_info.filtered_wmi_evts = NULL;
|
||||
fail2:
|
||||
qdf_mem_free(wmi_handle->log_info.wmi_filtered_command_log);
|
||||
wmi_handle->log_info.wmi_filtered_command_log = NULL;
|
||||
fail1:
|
||||
qdf_mem_free(wmi_handle->log_info.filtered_wmi_cmds);
|
||||
wmi_handle->log_info.filtered_wmi_cmds = NULL;
|
||||
}
|
||||
|
||||
void wmi_filtered_logging_free(wmi_unified_t wmi_handle)
|
||||
{
|
||||
if (!wmi_handle)
|
||||
return;
|
||||
|
||||
qdf_mem_free(wmi_handle->log_info.filtered_wmi_cmds);
|
||||
wmi_handle->log_info.filtered_wmi_cmds = NULL;
|
||||
qdf_mem_free(wmi_handle->log_info.filtered_wmi_evts);
|
||||
wmi_handle->log_info.filtered_wmi_evts = NULL;
|
||||
|
||||
if (wmi_handle->log_info.wmi_filtered_command_log) {
|
||||
qdf_mem_free(wmi_handle->log_info.
|
||||
wmi_filtered_command_log->buf);
|
||||
wmi_handle->log_info.wmi_filtered_command_log->buf = NULL;
|
||||
qdf_mem_free(wmi_handle->log_info.wmi_filtered_command_log);
|
||||
wmi_handle->log_info.wmi_filtered_command_log = NULL;
|
||||
}
|
||||
if (wmi_handle->log_info.wmi_filtered_event_log) {
|
||||
qdf_mem_free(wmi_handle->log_info.
|
||||
wmi_filtered_event_log->buf);
|
||||
wmi_handle->log_info.wmi_filtered_event_log->buf = NULL;
|
||||
qdf_mem_free(wmi_handle->log_info.wmi_filtered_event_log);
|
||||
wmi_handle->log_info.wmi_filtered_event_log = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Reset the buffer which saves user interested cmds/evts
|
||||
*/
|
||||
static int wmi_reset_filtered_buffers(wmi_unified_t wmi_handle,
|
||||
struct wmi_log_buf_t *cmd_log_buf)
|
||||
{
|
||||
int buf_size = WMI_FILTERED_CMD_EVT_MAX_NUM_ENTRY *
|
||||
sizeof(struct wmi_command_debug);
|
||||
|
||||
if (!cmd_log_buf)
|
||||
return 0;
|
||||
|
||||
cmd_log_buf->length = 0;
|
||||
cmd_log_buf->buf_tail_idx = 0;
|
||||
cmd_log_buf->size = WMI_FILTERED_CMD_EVT_MAX_NUM_ENTRY;
|
||||
cmd_log_buf->p_buf_tail_idx = &cmd_log_buf->buf_tail_idx;
|
||||
qdf_mem_zero(cmd_log_buf->buf, buf_size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if id is in id list,
|
||||
* return true if found.
|
||||
*/
|
||||
static bool wmi_id_in_list(uint32_t *id_list, uint32_t id)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!id_list)
|
||||
return false;
|
||||
|
||||
for (i = 0; i < WMI_FILTERED_CMD_EVT_SUPPORTED; i++) {
|
||||
if (id == id_list[i]) {
|
||||
/* id already in target list */
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Add command or event ids to list to be recorded
|
||||
*/
|
||||
static int wmi_add_to_record_list(wmi_unified_t wmi_handle,
|
||||
uint32_t id,
|
||||
enum WMI_RECORD_TYPE record_type)
|
||||
{
|
||||
uint32_t *target_list;
|
||||
|
||||
if (record_type == WMI_CMD) {
|
||||
target_list = wmi_handle->log_info.filtered_wmi_cmds;
|
||||
/* check if id already in target list */
|
||||
if (wmi_id_in_list(target_list, id))
|
||||
return 0;
|
||||
if (wmi_handle->log_info.filtered_wmi_cmds_idx >=
|
||||
WMI_FILTERED_CMD_EVT_SUPPORTED) {
|
||||
wmi_handle->log_info.filtered_wmi_cmds_idx = 0;
|
||||
}
|
||||
target_list[wmi_handle->log_info.filtered_wmi_cmds_idx] = id;
|
||||
wmi_handle->log_info.filtered_wmi_cmds_idx++;
|
||||
} else if (record_type == WMI_EVT) {
|
||||
target_list = wmi_handle->log_info.filtered_wmi_evts;
|
||||
/* check if id already in target list */
|
||||
if (wmi_id_in_list(target_list, id))
|
||||
return 0;
|
||||
if (wmi_handle->log_info.filtered_wmi_evts_idx >=
|
||||
WMI_FILTERED_CMD_EVT_SUPPORTED) {
|
||||
wmi_handle->log_info.filtered_wmi_evts_idx = 0;
|
||||
}
|
||||
target_list[wmi_handle->log_info.filtered_wmi_evts_idx] = id;
|
||||
wmi_handle->log_info.filtered_wmi_evts_idx++;
|
||||
} else {
|
||||
return -EINVAL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void wmi_specific_cmd_evt_record(uint32_t id, uint8_t *buf,
|
||||
struct wmi_log_buf_t *log_buffer)
|
||||
{
|
||||
int idx;
|
||||
struct wmi_command_debug *tmpbuf =
|
||||
(struct wmi_command_debug *)log_buffer->buf;
|
||||
|
||||
if (*log_buffer->p_buf_tail_idx >= WMI_FILTERED_CMD_EVT_MAX_NUM_ENTRY)
|
||||
*log_buffer->p_buf_tail_idx = 0;
|
||||
|
||||
idx = *log_buffer->p_buf_tail_idx;
|
||||
tmpbuf[idx].command = id;
|
||||
qdf_mem_copy(tmpbuf[idx].data, buf,
|
||||
WMI_EVENT_DEBUG_ENTRY_MAX_LENGTH);
|
||||
tmpbuf[idx].time = qdf_get_log_timestamp();
|
||||
(*log_buffer->p_buf_tail_idx)++;
|
||||
log_buffer->length++;
|
||||
}
|
||||
|
||||
void wmi_specific_cmd_record(wmi_unified_t wmi_handle,
|
||||
uint32_t id, uint8_t *buf)
|
||||
{
|
||||
uint32_t *target_list;
|
||||
struct wmi_log_buf_t *log_buffer;
|
||||
|
||||
target_list = wmi_handle->log_info.filtered_wmi_cmds;
|
||||
if (!target_list)
|
||||
return;
|
||||
|
||||
log_buffer = wmi_handle->log_info.wmi_filtered_command_log;
|
||||
if (!log_buffer)
|
||||
return;
|
||||
|
||||
if (wmi_id_in_list(target_list, id)) {
|
||||
/* id in target list, need to be recorded */
|
||||
wmi_specific_cmd_evt_record(id, buf, log_buffer);
|
||||
}
|
||||
}
|
||||
|
||||
void wmi_specific_evt_record(wmi_unified_t wmi_handle,
|
||||
uint32_t id, uint8_t *buf)
|
||||
{
|
||||
uint32_t *target_list;
|
||||
struct wmi_log_buf_t *log_buffer;
|
||||
|
||||
target_list = wmi_handle->log_info.filtered_wmi_evts;
|
||||
if (!target_list)
|
||||
return;
|
||||
|
||||
log_buffer = wmi_handle->log_info.wmi_filtered_event_log;
|
||||
if (!log_buffer)
|
||||
return;
|
||||
|
||||
if (wmi_id_in_list(target_list, id)) {
|
||||
/* id in target list, need to be recorded */
|
||||
wmi_specific_cmd_evt_record(id, buf, log_buffer);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Debugfs read/write functions
|
||||
*/
|
||||
static int wmi_filtered_seq_printf(qdf_debugfs_file_t m, const char *f, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
va_start(args, f);
|
||||
seq_vprintf(m, f, args);
|
||||
va_end(args);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* debugfs show/read for filtered_wmi_cmds
|
||||
*/
|
||||
int debug_filtered_wmi_cmds_show(qdf_debugfs_file_t m, void *v)
|
||||
{
|
||||
wmi_unified_t wmi_handle = (wmi_unified_t)m->private;
|
||||
int i;
|
||||
int *target_list;
|
||||
|
||||
target_list = wmi_handle->log_info.filtered_wmi_cmds;
|
||||
if (!target_list)
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < WMI_FILTERED_CMD_EVT_SUPPORTED; i++) {
|
||||
if (target_list[i] != 0) {
|
||||
wmi_filtered_seq_printf(m, "0x%x ",
|
||||
target_list[i]);
|
||||
}
|
||||
}
|
||||
wmi_filtered_seq_printf(m, "\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int debug_filtered_wmi_evts_show(qdf_debugfs_file_t m, void *v)
|
||||
{
|
||||
wmi_unified_t wmi_handle = (wmi_unified_t)m->private;
|
||||
int i;
|
||||
int *target_list;
|
||||
|
||||
target_list = wmi_handle->log_info.filtered_wmi_evts;
|
||||
if (!target_list)
|
||||
return 0;
|
||||
for (i = 0; i < WMI_FILTERED_CMD_EVT_SUPPORTED; i++) {
|
||||
if (target_list[i] != 0) {
|
||||
wmi_filtered_seq_printf(m, "0x%x ",
|
||||
target_list[i]);
|
||||
}
|
||||
}
|
||||
wmi_filtered_seq_printf(m, "\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int wmi_log_show(wmi_unified_t wmi_handle, void *buf,
|
||||
qdf_debugfs_file_t m)
|
||||
{
|
||||
struct wmi_log_buf_t *wmi_log = (struct wmi_log_buf_t *)buf;
|
||||
int pos, nread, outlen;
|
||||
int i;
|
||||
uint64_t secs, usecs;
|
||||
int wmi_ring_size = 100;
|
||||
|
||||
qdf_spin_lock_bh(&wmi_handle->log_info.wmi_record_lock);
|
||||
if (!wmi_log->length) {
|
||||
qdf_spin_unlock_bh(&wmi_handle->log_info.wmi_record_lock);
|
||||
return wmi_filtered_seq_printf(m,
|
||||
"Nothing to read!\n");
|
||||
}
|
||||
if (wmi_log->length <= wmi_ring_size)
|
||||
nread = wmi_log->length;
|
||||
else
|
||||
nread = wmi_ring_size;
|
||||
|
||||
if (*wmi_log->p_buf_tail_idx == 0)
|
||||
/* tail can be 0 after wrap-around */
|
||||
pos = wmi_ring_size - 1;
|
||||
else
|
||||
pos = *wmi_log->p_buf_tail_idx - 1;
|
||||
|
||||
outlen = wmi_filtered_seq_printf(m, "Length = %d\n", wmi_log->length);
|
||||
qdf_spin_unlock_bh(&wmi_handle->log_info.wmi_record_lock);
|
||||
while (nread--) {
|
||||
struct wmi_event_debug *wmi_record;
|
||||
|
||||
wmi_record = &(((struct wmi_event_debug *)wmi_log->buf)[pos]);
|
||||
qdf_log_timestamp_to_secs(wmi_record->time, &secs,
|
||||
&usecs);
|
||||
outlen += wmi_filtered_seq_printf(m, "Event ID = %x\n",
|
||||
(wmi_record->event));
|
||||
outlen +=
|
||||
wmi_filtered_seq_printf(m,
|
||||
"Event TIME = [%llu.%06llu]\n",
|
||||
secs, usecs);
|
||||
outlen += wmi_filtered_seq_printf(m, "CMD = ");
|
||||
for (i = 0; i < (WMI_EVENT_DEBUG_ENTRY_MAX_LENGTH /
|
||||
sizeof(uint32_t)); i++)
|
||||
outlen += wmi_filtered_seq_printf(m, "%x ",
|
||||
wmi_record->data[i]);
|
||||
outlen += wmi_filtered_seq_printf(m, "\n");
|
||||
if (pos == 0)
|
||||
pos = wmi_ring_size - 1;
|
||||
else
|
||||
pos--;
|
||||
}
|
||||
return outlen;
|
||||
}
|
||||
|
||||
int debug_wmi_filtered_command_log_show(qdf_debugfs_file_t m, void *v)
|
||||
{
|
||||
wmi_unified_t wmi_handle = (wmi_unified_t)m->private;
|
||||
struct wmi_log_buf_t *wmi_log =
|
||||
wmi_handle->log_info.wmi_filtered_command_log;
|
||||
|
||||
if (!wmi_log)
|
||||
return 0;
|
||||
return wmi_log_show(wmi_handle, wmi_log, m);
|
||||
}
|
||||
|
||||
int debug_wmi_filtered_event_log_show(qdf_debugfs_file_t m, void *v)
|
||||
{
|
||||
wmi_unified_t wmi_handle = (wmi_unified_t)m->private;
|
||||
struct wmi_log_buf_t *wmi_log =
|
||||
wmi_handle->log_info.wmi_filtered_event_log;
|
||||
|
||||
if (!wmi_log)
|
||||
return 0;
|
||||
return wmi_log_show(wmi_handle, wmi_log, m);
|
||||
}
|
||||
|
||||
ssize_t debug_filtered_wmi_cmds_write(struct file *file,
|
||||
const char __user *buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
wmi_unified_t wmi_handle =
|
||||
((struct seq_file *)file->private_data)->private;
|
||||
int k, ret;
|
||||
char locbuf[12] = {0};
|
||||
int buf_size = WMI_FILTERED_CMD_EVT_SUPPORTED * sizeof(int);
|
||||
|
||||
if ((!buf) || (count > 8 || count <= 0))
|
||||
return -EFAULT;
|
||||
|
||||
if (!wmi_handle->log_info.filtered_wmi_cmds)
|
||||
return -EFAULT;
|
||||
|
||||
if (copy_from_user(locbuf, buf, count))
|
||||
return -EFAULT;
|
||||
|
||||
ret = qdf_kstrtoint(locbuf, 16, &k);
|
||||
if (ret)
|
||||
return -EINVAL;
|
||||
|
||||
if (k == 0xffff) {
|
||||
qdf_mem_zero(wmi_handle->log_info.filtered_wmi_cmds, buf_size);
|
||||
wmi_handle->log_info.filtered_wmi_cmds_idx = 0;
|
||||
return count;
|
||||
}
|
||||
|
||||
if (wmi_add_to_record_list(wmi_handle, k, WMI_CMD)) {
|
||||
WMI_LOGE("Add cmd %d to WMI_CMD list failed");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
ssize_t debug_filtered_wmi_evts_write(struct file *file,
|
||||
const char __user *buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
wmi_unified_t wmi_handle =
|
||||
((struct seq_file *)file->private_data)->private;
|
||||
int k, ret;
|
||||
char locbuf[12] = {0};
|
||||
int buf_size = WMI_FILTERED_CMD_EVT_SUPPORTED * sizeof(int);
|
||||
|
||||
if ((!buf) || (count > 8 || count <= 0))
|
||||
return -EFAULT;
|
||||
|
||||
if (!wmi_handle->log_info.filtered_wmi_evts)
|
||||
return -EFAULT;
|
||||
|
||||
if (copy_from_user(locbuf, buf, count))
|
||||
return -EFAULT;
|
||||
|
||||
ret = qdf_kstrtoint(locbuf, 16, &k);
|
||||
if (ret)
|
||||
return -EINVAL;
|
||||
|
||||
if (k == 0xffff) {
|
||||
qdf_mem_zero(wmi_handle->log_info.filtered_wmi_evts, buf_size);
|
||||
wmi_handle->log_info.filtered_wmi_evts_idx = 0;
|
||||
return count;
|
||||
}
|
||||
|
||||
if (wmi_add_to_record_list(wmi_handle, k, WMI_EVT)) {
|
||||
WMI_LOGE("Add cmd %d to WMI_EVT list failed");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
ssize_t debug_wmi_filtered_command_log_write(struct file *file,
|
||||
const char __user *buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
wmi_unified_t wmi_handle =
|
||||
((struct seq_file *)file->private_data)->private;
|
||||
int k, ret;
|
||||
char locbuf[12] = {0};
|
||||
struct wmi_log_buf_t *cmd_log_buf;
|
||||
|
||||
if ((!buf) || (count > 8 || count <= 0))
|
||||
return -EFAULT;
|
||||
|
||||
if (copy_from_user(locbuf, buf, count))
|
||||
return -EFAULT;
|
||||
|
||||
ret = qdf_kstrtoint(locbuf, 16, &k);
|
||||
if (ret)
|
||||
return -EINVAL;
|
||||
|
||||
if (k != 0xffff)
|
||||
return -EINVAL;
|
||||
|
||||
cmd_log_buf = wmi_handle->log_info.wmi_filtered_command_log;
|
||||
if (wmi_reset_filtered_buffers(wmi_handle, cmd_log_buf))
|
||||
WMI_LOGE("reset WMI CMD filtered_buffers failed");
|
||||
return count;
|
||||
}
|
||||
|
||||
ssize_t debug_wmi_filtered_event_log_write(struct file *file,
|
||||
const char __user *buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
wmi_unified_t wmi_handle =
|
||||
((struct seq_file *)file->private_data)->private;
|
||||
int k, ret;
|
||||
char locbuf[12] = {0};
|
||||
struct wmi_log_buf_t *cmd_log_buf;
|
||||
|
||||
if ((!buf) || (count > 8 || count <= 0))
|
||||
return -EFAULT;
|
||||
|
||||
if (copy_from_user(locbuf, buf, count))
|
||||
return -EFAULT;
|
||||
|
||||
ret = qdf_kstrtoint(locbuf, 16, &k);
|
||||
if (ret)
|
||||
return -EINVAL;
|
||||
|
||||
if (k != 0xffff)
|
||||
return -EINVAL;
|
||||
|
||||
cmd_log_buf = wmi_handle->log_info.wmi_filtered_event_log;
|
||||
if (wmi_reset_filtered_buffers(wmi_handle, cmd_log_buf))
|
||||
WMI_LOGE("reset WMI EVT filtered_buffers failed");
|
||||
return count;
|
||||
}
|
@@ -36,6 +36,8 @@
|
||||
|
||||
#include <linux/debugfs.h>
|
||||
#include <target_if.h>
|
||||
#include <qdf_debugfs.h>
|
||||
#include "wmi_filtered_logging.h"
|
||||
|
||||
/* This check for CONFIG_WIN temporary added due to redeclaration compilation
|
||||
error in MCL. Error is caused due to inclusion of wmi.h in wmi_unified_api.h
|
||||
@@ -101,7 +103,7 @@ typedef PREPACK struct {
|
||||
#ifdef WMI_INTERFACE_EVENT_LOGGING
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 3, 0))
|
||||
/* TODO Cleanup this backported function */
|
||||
static int wmi_bp_seq_printf(struct seq_file *m, const char *f, ...)
|
||||
static int wmi_bp_seq_printf(qdf_debugfs_file_t m, const char *f, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
@@ -813,6 +815,8 @@ static QDF_STATUS wmi_log_init(struct wmi_unified *wmi_handle)
|
||||
qdf_spinlock_create(&wmi_handle->log_info.wmi_record_lock);
|
||||
wmi_handle->log_info.wmi_logging_enable = 1;
|
||||
|
||||
wmi_filtered_logging_init(wmi_handle);
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
@@ -827,6 +831,8 @@ static QDF_STATUS wmi_log_init(struct wmi_unified *wmi_handle)
|
||||
#ifdef WMI_INTERFACE_EVENT_LOGGING_DYNAMIC_ALLOC
|
||||
static inline void wmi_log_buffer_free(struct wmi_unified *wmi_handle)
|
||||
{
|
||||
wmi_filtered_logging_free(wmi_handle);
|
||||
|
||||
if (wmi_handle->log_info.wmi_command_log_buf_info.buf)
|
||||
qdf_mem_free(wmi_handle->log_info.wmi_command_log_buf_info.buf);
|
||||
if (wmi_handle->log_info.wmi_command_tx_cmp_log_buf_info.buf)
|
||||
@@ -850,6 +856,7 @@ static inline void wmi_log_buffer_free(struct wmi_unified *wmi_handle)
|
||||
qdf_mem_free(
|
||||
wmi_handle->log_info.wmi_diag_event_log_buf_info.buf);
|
||||
wmi_handle->log_info.wmi_logging_enable = 0;
|
||||
|
||||
qdf_spinlock_destroy(&wmi_handle->log_info.wmi_record_lock);
|
||||
}
|
||||
#else
|
||||
@@ -1357,6 +1364,12 @@ GENERATE_DEBUG_STRUCTS(wmi_mgmt_command_tx_cmp_log);
|
||||
GENERATE_DEBUG_STRUCTS(wmi_mgmt_event_log);
|
||||
GENERATE_DEBUG_STRUCTS(wmi_enable);
|
||||
GENERATE_DEBUG_STRUCTS(wmi_log_size);
|
||||
#ifdef WMI_INTERFACE_FILTERED_EVENT_LOGGING
|
||||
GENERATE_DEBUG_STRUCTS(filtered_wmi_cmds);
|
||||
GENERATE_DEBUG_STRUCTS(filtered_wmi_evts);
|
||||
GENERATE_DEBUG_STRUCTS(wmi_filtered_command_log);
|
||||
GENERATE_DEBUG_STRUCTS(wmi_filtered_event_log);
|
||||
#endif
|
||||
|
||||
struct wmi_debugfs_info wmi_debugfs_infos[NUM_DEBUG_INFOS] = {
|
||||
DEBUG_FOO(wmi_command_log),
|
||||
@@ -1368,6 +1381,12 @@ struct wmi_debugfs_info wmi_debugfs_infos[NUM_DEBUG_INFOS] = {
|
||||
DEBUG_FOO(wmi_mgmt_event_log),
|
||||
DEBUG_FOO(wmi_enable),
|
||||
DEBUG_FOO(wmi_log_size),
|
||||
#ifdef WMI_INTERFACE_FILTERED_EVENT_LOGGING
|
||||
DEBUG_FOO(filtered_wmi_cmds),
|
||||
DEBUG_FOO(filtered_wmi_evts),
|
||||
DEBUG_FOO(wmi_filtered_command_log),
|
||||
DEBUG_FOO(wmi_filtered_event_log),
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
@@ -1484,7 +1503,7 @@ void wmi_mgmt_cmd_record(wmi_unified_t wmi_handle, uint32_t cmd,
|
||||
qdf_spin_lock_bh(&wmi_handle->log_info.wmi_record_lock);
|
||||
|
||||
WMI_MGMT_COMMAND_RECORD(wmi_handle, cmd, (uint8_t *)data);
|
||||
|
||||
wmi_specific_cmd_record(wmi_handle, cmd, (uint8_t *)data);
|
||||
qdf_spin_unlock_bh(&wmi_handle->log_info.wmi_record_lock);
|
||||
}
|
||||
#else
|
||||
@@ -1839,9 +1858,11 @@ QDF_STATUS wmi_unified_cmd_send_fl(wmi_unified_t wmi_handle, wmi_buf_t buf,
|
||||
* WMI mgmt command already recorded in wmi_mgmt_cmd_record
|
||||
*/
|
||||
if (wmi_handle->ops->is_management_record(cmd_id) == false) {
|
||||
WMI_COMMAND_RECORD(wmi_handle, cmd_id,
|
||||
qdf_nbuf_data(buf) +
|
||||
wmi_handle->soc->buf_offset_command);
|
||||
uint8_t *tmpbuf = (uint8_t *)qdf_nbuf_data(buf) +
|
||||
wmi_handle->soc->buf_offset_command;
|
||||
|
||||
WMI_COMMAND_RECORD(wmi_handle, cmd_id, tmpbuf);
|
||||
wmi_specific_cmd_record(wmi_handle, cmd_id, tmpbuf);
|
||||
}
|
||||
qdf_spin_unlock_bh(&wmi_handle->log_info.wmi_record_lock);
|
||||
}
|
||||
@@ -2430,8 +2451,11 @@ void __wmi_control_rx(struct wmi_unified *wmi_handle, wmi_buf_t evt_buf)
|
||||
* as its already logged in WMI RX event buffer
|
||||
*/
|
||||
} else {
|
||||
WMI_EVENT_RECORD(wmi_handle, id, ((uint8_t *) data +
|
||||
wmi_handle->soc->buf_offset_event));
|
||||
uint8_t *tmpbuf = (uint8_t *)data +
|
||||
wmi_handle->soc->buf_offset_event;
|
||||
|
||||
WMI_EVENT_RECORD(wmi_handle, id, tmpbuf);
|
||||
wmi_specific_evt_record(wmi_handle, id, tmpbuf);
|
||||
}
|
||||
qdf_spin_unlock_bh(&wmi_handle->log_info.wmi_record_lock);
|
||||
}
|
||||
|
Reference in New Issue
Block a user