diff options
| author | CNSS_WLAN Service <cnssbldsw@qualcomm.com> | 2017-04-15 14:44:53 -0700 |
|---|---|---|
| committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2017-04-15 14:44:53 -0700 |
| commit | 5206c0fa6356f8483ea5e6cf284e4002db1a5cc2 (patch) | |
| tree | 486d4028971ae21764552435657b8fce606a5b58 | |
| parent | fb52860434a968dd0b01b01287f87637408bcaa2 (diff) | |
| parent | 92a1d1b0adea4299c7e03653abbec245ef55ae1c (diff) | |
Merge "qcacmn: Implement WMI/Credit History log print APIs" into wlan-cmn.driver.lnx.1.0-dev
| -rw-r--r-- | htc/htc_api.h | 6 | ||||
| -rw-r--r-- | htc/htc_internal.h | 21 | ||||
| -rw-r--r-- | htc/htc_send.c | 45 | ||||
| -rw-r--r-- | qdf/inc/qdf_trace.h | 2 | ||||
| -rw-r--r-- | wmi/inc/wmi_unified_api.h | 24 | ||||
| -rw-r--r-- | wmi/inc/wmi_unified_priv.h | 2 | ||||
| -rw-r--r-- | wmi/src/wmi_unified.c | 186 |
7 files changed, 283 insertions, 3 deletions
diff --git a/htc/htc_api.h b/htc/htc_api.h index 3a517e3c9325..74c5a448f1af 100644 --- a/htc/htc_api.h +++ b/htc/htc_api.h @@ -778,4 +778,10 @@ int htc_pm_runtime_put(HTC_HANDLE htc_handle); static inline int htc_pm_runtime_get(HTC_HANDLE htc_handle) { return 0; } static inline int htc_pm_runtime_put(HTC_HANDLE htc_handle) { return 0; } #endif + +#ifdef WMI_INTERFACE_EVENT_LOGGING +void htc_print_credit_history(HTC_HANDLE htc, uint32_t count, + qdf_abstract_print * print, void *print_priv); +#endif + #endif /* _HTC_API_H_ */ diff --git a/htc/htc_internal.h b/htc/htc_internal.h index 596628cead6a..6f6fa4707e17 100644 --- a/htc/htc_internal.h +++ b/htc/htc_internal.h @@ -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. * @@ -92,6 +92,25 @@ typedef enum { HTC_INITIAL_WAKE_UP, } htc_credit_exchange_type; +static inline const char* +htc_credit_exchange_type_str(htc_credit_exchange_type type) +{ + switch (type) { + case HTC_REQUEST_CREDIT: + return "HTC_REQUEST_CREDIT"; + case HTC_PROCESS_CREDIT_REPORT: + return "HTC_PROCESS_CREDIT_REPORT"; + case HTC_SUSPEND_ACK: + return "HTC_SUSPEND_ACK"; + case HTC_SUSPEND_NACK: + return "HTC_SUSPEND_NACK"; + case HTC_INITIAL_WAKE_UP: + return "HTC_INITIAL_WAKE_UP"; + default: + return "Unknown htc_credit_exchange_type"; + } +} + typedef struct { htc_credit_exchange_type type; uint64_t time; diff --git a/htc/htc_send.c b/htc/htc_send.c index 09fd9ed69a92..7b496b5197b4 100644 --- a/htc/htc_send.c +++ b/htc/htc_send.c @@ -55,6 +55,7 @@ static unsigned ep_debug_mask = /* HTC Control Path Credit History */ uint32_t g_htc_credit_history_idx = 0; +uint32_t g_htc_credit_history_length; HTC_CREDIT_HISTORY htc_credit_history_buffer[HTC_CREDIT_HISTORY_MAX]; /** @@ -85,8 +86,52 @@ void htc_credit_record(htc_credit_exchange_type type, uint32_t tx_credit, tx_credit; htc_credit_history_buffer[g_htc_credit_history_idx].htc_tx_queue_depth = htc_tx_queue_depth; + g_htc_credit_history_idx++; + g_htc_credit_history_length++; +} + +#ifdef WMI_INTERFACE_EVENT_LOGGING +void htc_print_credit_history(HTC_HANDLE htc, uint32_t count, + qdf_abstract_print *print, void *print_priv) +{ + uint32_t idx; + HTC_TARGET *target; + + target = GET_HTC_TARGET_FROM_HANDLE(htc); + LOCK_HTC_CREDIT(target); + + if (count > HTC_CREDIT_HISTORY_MAX) + count = HTC_CREDIT_HISTORY_MAX; + if (count > g_htc_credit_history_length) + count = g_htc_credit_history_length; + + /* subtract count from index, and wrap if necessary */ + idx = HTC_CREDIT_HISTORY_MAX + g_htc_credit_history_idx - count; + idx %= HTC_CREDIT_HISTORY_MAX; + + print(print_priv, + "Time (seconds) Type Credits Queue Depth"); + while (count) { + HTC_CREDIT_HISTORY *hist = &htc_credit_history_buffer[idx]; + long long us = qdf_log_timestamp_to_usecs(hist->time); + + print(print_priv, "% 8lld.%06lld %-25s %-7.d %d", + us / 1000000, + us % 1000000, + htc_credit_exchange_type_str(hist->type), + hist->tx_credit, + hist->htc_tx_queue_depth); + + --count; + ++idx; + if (idx >= HTC_CREDIT_HISTORY_MAX) + idx = 0; + } + + UNLOCK_HTC_CREDIT(target); } +#endif /* WMI_INTERFACE_EVENT_LOGGING */ void htc_dump_counter_info(HTC_HANDLE HTCHandle) { diff --git a/qdf/inc/qdf_trace.h b/qdf/inc/qdf_trace.h index 6081dfc40045..ad7723b3f786 100644 --- a/qdf/inc/qdf_trace.h +++ b/qdf/inc/qdf_trace.h @@ -45,6 +45,8 @@ #define FL(x) "%s: %d: " x, __func__, __LINE__ +typedef int (qdf_abstract_print)(void *priv, const char *fmt, ...); + /* * Log levels */ diff --git a/wmi/inc/wmi_unified_api.h b/wmi/inc/wmi_unified_api.h index 3c032c9d4d8b..65750fa42164 100644 --- a/wmi/inc/wmi_unified_api.h +++ b/wmi/inc/wmi_unified_api.h @@ -1362,4 +1362,28 @@ QDF_STATUS wmi_unified_set_arp_stats_req(void *wmi_hdl, struct set_arp_stats *req_buf); QDF_STATUS wmi_unified_get_arp_stats_req(void *wmi_hdl, struct get_arp_stats *req_buf); + +#ifdef WMI_INTERFACE_EVENT_LOGGING +void wmi_print_cmd_log(wmi_unified_t wmi, uint32_t count, + qdf_abstract_print *print, void *print_priv); + +void wmi_print_cmd_tx_cmp_log(wmi_unified_t wmi, uint32_t count, + qdf_abstract_print *print, void *print_priv); + +void wmi_print_mgmt_cmd_log(wmi_unified_t wmi, uint32_t count, + qdf_abstract_print *print, void *print_priv); + +void wmi_print_mgmt_cmd_tx_cmp_log(wmi_unified_t wmi, uint32_t count, + qdf_abstract_print *print, void *print_priv); + +void wmi_print_event_log(wmi_unified_t wmi, uint32_t count, + qdf_abstract_print *print, void *print_priv); + +void wmi_print_rx_event_log(wmi_unified_t wmi, uint32_t count, + qdf_abstract_print *print, void *print_priv); + +void wmi_print_mgmt_event_log(wmi_unified_t wmi, uint32_t count, + qdf_abstract_print *print, void *print_priv); +#endif /* WMI_INTERFACE_EVENT_LOGGING */ + #endif /* _WMI_UNIFIED_API_H_ */ diff --git a/wmi/inc/wmi_unified_priv.h b/wmi/inc/wmi_unified_priv.h index 7ded40c2c3b3..3dc67f32aac5 100644 --- a/wmi/inc/wmi_unified_priv.h +++ b/wmi/inc/wmi_unified_priv.h @@ -110,12 +110,14 @@ struct wmi_command_header { * @ buf_tail_idx - Tail index of buffer * @ p_buf_tail_idx - refernce to buffer tail index. It is added to accommodate * unified design since MCL uses global variable for buffer tail index + * @ size - the size of the buffer in number of entries */ struct wmi_log_buf_t { void *buf; uint32_t length; uint32_t buf_tail_idx; uint32_t *p_buf_tail_idx; + uint32_t size; }; /** diff --git a/wmi/src/wmi_unified.c b/wmi/src/wmi_unified.c index 9e4b2365181b..3411025c1502 100644 --- a/wmi/src/wmi_unified.c +++ b/wmi/src/wmi_unified.c @@ -314,30 +314,35 @@ static QDF_STATUS wmi_log_init(struct wmi_unified *wmi_handle) cmd_log_buf->buf_tail_idx = 0; cmd_log_buf->buf = wmi_command_log_buffer; cmd_log_buf->p_buf_tail_idx = &g_wmi_command_buf_idx; + cmd_log_buf->size = WMI_EVENT_DEBUG_MAX_ENTRY; /* WMI commands TX completed */ cmd_tx_cmpl_log_buf->length = 0; cmd_tx_cmpl_log_buf->buf_tail_idx = 0; cmd_tx_cmpl_log_buf->buf = wmi_command_tx_cmp_log_buffer; cmd_tx_cmpl_log_buf->p_buf_tail_idx = &g_wmi_command_tx_cmp_buf_idx; + cmd_tx_cmpl_log_buf->size = WMI_EVENT_DEBUG_MAX_ENTRY; /* WMI events when processed */ event_log_buf->length = 0; event_log_buf->buf_tail_idx = 0; event_log_buf->buf = wmi_event_log_buffer; event_log_buf->p_buf_tail_idx = &g_wmi_event_buf_idx; + event_log_buf->size = WMI_EVENT_DEBUG_MAX_ENTRY; /* WMI events when queued */ rx_event_log_buf->length = 0; rx_event_log_buf->buf_tail_idx = 0; rx_event_log_buf->buf = wmi_rx_event_log_buffer; rx_event_log_buf->p_buf_tail_idx = &g_wmi_rx_event_buf_idx; + rx_event_log_buf->size = WMI_EVENT_DEBUG_MAX_ENTRY; /* WMI Management commands */ mgmt_cmd_log_buf->length = 0; mgmt_cmd_log_buf->buf_tail_idx = 0; mgmt_cmd_log_buf->buf = wmi_mgmt_command_log_buffer; mgmt_cmd_log_buf->p_buf_tail_idx = &g_wmi_mgmt_command_buf_idx; + mgmt_cmd_log_buf->size = WMI_MGMT_EVENT_DEBUG_MAX_ENTRY; /* WMI Management commands Tx completed*/ mgmt_cmd_tx_cmp_log_buf->length = 0; @@ -345,12 +350,14 @@ static QDF_STATUS wmi_log_init(struct wmi_unified *wmi_handle) mgmt_cmd_tx_cmp_log_buf->buf = wmi_mgmt_command_tx_cmp_log_buffer; mgmt_cmd_tx_cmp_log_buf->p_buf_tail_idx = &g_wmi_mgmt_command_tx_cmp_buf_idx; + mgmt_cmd_tx_cmp_log_buf->size = WMI_MGMT_EVENT_DEBUG_MAX_ENTRY; /* WMI Management events when processed*/ mgmt_event_log_buf->length = 0; mgmt_event_log_buf->buf_tail_idx = 0; mgmt_event_log_buf->buf = wmi_mgmt_event_log_buffer; mgmt_event_log_buf->p_buf_tail_idx = &g_wmi_mgmt_event_buf_idx; + mgmt_event_log_buf->size = WMI_MGMT_EVENT_DEBUG_MAX_ENTRY; qdf_spinlock_create(&wmi_handle->log_info.wmi_record_lock); wmi_handle->log_info.wmi_logging_enable = 1; @@ -384,6 +391,7 @@ static QDF_STATUS wmi_log_init(struct wmi_unified *wmi_handle) cmd_log_buf->buf_tail_idx = 0; cmd_log_buf->buf = (struct wmi_command_debug *) qdf_mem_malloc( wmi_log_max_entry * sizeof(struct wmi_command_debug)); + cmd_log_buf->size = wmi_log_max_entry; if (!cmd_log_buf->buf) { qdf_print("no memory for WMI command log buffer..\n"); @@ -396,6 +404,7 @@ static QDF_STATUS wmi_log_init(struct wmi_unified *wmi_handle) cmd_tx_cmpl_log_buf->buf_tail_idx = 0; cmd_tx_cmpl_log_buf->buf = (struct wmi_command_debug *) qdf_mem_malloc( wmi_log_max_entry * sizeof(struct wmi_command_debug)); + cmd_tx_cmpl_log_buf->size = wmi_log_max_entry; if (!cmd_tx_cmpl_log_buf->buf) { qdf_print("no memory for WMI Command Tx Complete log buffer..\n"); @@ -409,6 +418,7 @@ static QDF_STATUS wmi_log_init(struct wmi_unified *wmi_handle) event_log_buf->buf_tail_idx = 0; event_log_buf->buf = (struct wmi_event_debug *) qdf_mem_malloc( wmi_log_max_entry * sizeof(struct wmi_event_debug)); + event_log_buf->size = wmi_log_max_entry; if (!event_log_buf->buf) { qdf_print("no memory for WMI Event log buffer..\n"); @@ -421,6 +431,7 @@ static QDF_STATUS wmi_log_init(struct wmi_unified *wmi_handle) rx_event_log_buf->buf_tail_idx = 0; rx_event_log_buf->buf = (struct wmi_event_debug *) qdf_mem_malloc( wmi_log_max_entry * sizeof(struct wmi_event_debug)); + rx_event_log_buf->size = wmi_log_max_entry; if (!rx_event_log_buf->buf) { qdf_print("no memory for WMI Event Rx log buffer..\n"); @@ -432,8 +443,8 @@ static QDF_STATUS wmi_log_init(struct wmi_unified *wmi_handle) mgmt_cmd_log_buf->length = 0; mgmt_cmd_log_buf->buf_tail_idx = 0; mgmt_cmd_log_buf->buf = (struct wmi_command_debug *) qdf_mem_malloc( - wmi_mgmt_log_max_entry * - sizeof(struct wmi_command_debug)); + wmi_mgmt_log_max_entry * sizeof(struct wmi_command_debug)); + mgmt_cmd_log_buf->size = wmi_mgmt_log_max_entry; if (!mgmt_cmd_log_buf->buf) { qdf_print("no memory for WMI Management Command log buffer..\n"); @@ -448,6 +459,7 @@ static QDF_STATUS wmi_log_init(struct wmi_unified *wmi_handle) qdf_mem_malloc( wmi_mgmt_log_max_entry * sizeof(struct wmi_command_debug)); + mgmt_cmd_tx_cmp_log_buf->size = wmi_mgmt_log_max_entry; if (!mgmt_cmd_tx_cmp_log_buf->buf) { qdf_print("no memory for WMI Management Command Tx complete log buffer..\n"); @@ -463,6 +475,7 @@ static QDF_STATUS wmi_log_init(struct wmi_unified *wmi_handle) mgmt_event_log_buf->buf = (struct wmi_event_debug *) qdf_mem_malloc( wmi_mgmt_log_max_entry * sizeof(struct wmi_event_debug)); + mgmt_event_log_buf->size = wmi_mgmt_log_max_entry; if (!mgmt_event_log_buf->buf) { qdf_print("no memory for WMI Management Event log buffer..\n"); @@ -517,6 +530,175 @@ static inline void wmi_log_buffer_free(struct wmi_unified *wmi_handle) } #endif +/** + * wmi_print_cmd_log_buffer() - an output agnostic wmi command log printer + * @log_buffer: the command log buffer metadata of the buffer to print + * @count: the maximum number of entries to print + * @print: an abstract print method, e.g. a qdf_print() or seq_printf() wrapper + * @print_priv: any data required by the print method, e.g. a file handle + * + * Return: None + */ +static void +wmi_print_cmd_log_buffer(struct wmi_log_buf_t *log_buffer, uint32_t count, + qdf_abstract_print *print, void *print_priv) +{ + static const int data_len = + WMI_EVENT_DEBUG_ENTRY_MAX_LENGTH / sizeof(uint32_t); + char str[128]; + uint32_t idx; + + if (count > log_buffer->size) + count = log_buffer->size; + if (count > log_buffer->length) + count = log_buffer->length; + + /* subtract count from index, and wrap if necessary */ + idx = log_buffer->size + *log_buffer->p_buf_tail_idx - count; + idx %= log_buffer->size; + + print(print_priv, "Time (seconds) Cmd Id Payload"); + while (count) { + struct wmi_command_debug *cmd_log = (struct wmi_command_debug *) + &((struct wmi_command_debug *)log_buffer->buf)[idx]; + long long us = qdf_log_timestamp_to_usecs(cmd_log->time); + int len = 0; + int i; + + len += scnprintf(str + len, sizeof(str) - len, + "% 8lld.%06lld %6u (0x%06x) ", + us / 1000000, us % 1000000, + cmd_log->command, cmd_log->command); + for (i = 0; i < data_len; ++i) { + len += scnprintf(str + len, sizeof(str) - len, + "0x%08x ", cmd_log->data[i]); + } + + print(print_priv, str); + + --count; + ++idx; + if (idx >= log_buffer->size) + idx = 0; + } +} + +/** + * wmi_print_event_log_buffer() - an output agnostic wmi event log printer + * @log_buffer: the event log buffer metadata of the buffer to print + * @count: the maximum number of entries to print + * @print: an abstract print method, e.g. a qdf_print() or seq_printf() wrapper + * @print_priv: any data required by the print method, e.g. a file handle + * + * Return: None + */ +static void +wmi_print_event_log_buffer(struct wmi_log_buf_t *log_buffer, uint32_t count, + qdf_abstract_print *print, void *print_priv) +{ + static const int data_len = + WMI_EVENT_DEBUG_ENTRY_MAX_LENGTH / sizeof(uint32_t); + char str[128]; + uint32_t idx; + + if (count > log_buffer->size) + count = log_buffer->size; + if (count > log_buffer->length) + count = log_buffer->length; + + /* subtract count from index, and wrap if necessary */ + idx = log_buffer->size + *log_buffer->p_buf_tail_idx - count; + idx %= log_buffer->size; + + print(print_priv, "Time (seconds) Event Id Payload"); + while (count) { + struct wmi_event_debug *event_log = (struct wmi_event_debug *) + &((struct wmi_event_debug *)log_buffer->buf)[idx]; + long long us = qdf_log_timestamp_to_usecs(event_log->time); + int len = 0; + int i; + + len += scnprintf(str + len, sizeof(str) - len, + "% 8lld.%06lld %6u (0x%06x) ", + us / 1000000, us % 1000000, + event_log->event, event_log->event); + for (i = 0; i < data_len; ++i) { + len += scnprintf(str + len, sizeof(str) - len, + "0x%08x ", event_log->data[i]); + } + + print(print_priv, str); + + --count; + ++idx; + if (idx >= log_buffer->size) + idx = 0; + } +} + +inline void +wmi_print_cmd_log(wmi_unified_t wmi, uint32_t count, + qdf_abstract_print *print, void *print_priv) +{ + wmi_print_cmd_log_buffer( + &wmi->log_info.wmi_command_log_buf_info, + count, print, print_priv); +} + +inline void +wmi_print_cmd_tx_cmp_log(wmi_unified_t wmi, uint32_t count, + qdf_abstract_print *print, void *print_priv) +{ + wmi_print_cmd_log_buffer( + &wmi->log_info.wmi_command_tx_cmp_log_buf_info, + count, print, print_priv); +} + +inline void +wmi_print_mgmt_cmd_log(wmi_unified_t wmi, uint32_t count, + qdf_abstract_print *print, void *print_priv) +{ + wmi_print_cmd_log_buffer( + &wmi->log_info.wmi_mgmt_command_log_buf_info, + count, print, print_priv); +} + +inline void +wmi_print_mgmt_cmd_tx_cmp_log(wmi_unified_t wmi, uint32_t count, + qdf_abstract_print *print, void *print_priv) +{ + wmi_print_cmd_log_buffer( + &wmi->log_info.wmi_mgmt_command_tx_cmp_log_buf_info, + count, print, print_priv); +} + +inline void +wmi_print_event_log(wmi_unified_t wmi, uint32_t count, + qdf_abstract_print *print, void *print_priv) +{ + wmi_print_event_log_buffer( + &wmi->log_info.wmi_event_log_buf_info, + count, print, print_priv); +} + +inline void +wmi_print_rx_event_log(wmi_unified_t wmi, uint32_t count, + qdf_abstract_print *print, void *print_priv) +{ + wmi_print_event_log_buffer( + &wmi->log_info.wmi_rx_event_log_buf_info, + count, print, print_priv); +} + +inline void +wmi_print_mgmt_event_log(wmi_unified_t wmi, uint32_t count, + qdf_abstract_print *print, void *print_priv) +{ + wmi_print_event_log_buffer( + &wmi->log_info.wmi_mgmt_event_log_buf_info, + count, print, print_priv); +} + #ifdef CONFIG_MCL const int8_t * const debugfs_dir[] = {"WMI0", "WMI1", "WMI2"}; #else |
