diff --git a/core/cds/inc/cds_api.h b/core/cds/inc/cds_api.h index 9ce6bb7030..7ee074f4f9 100644 --- a/core/cds/inc/cds_api.h +++ b/core/cds/inc/cds_api.h @@ -289,4 +289,10 @@ bool cds_is_sub_20_mhz_enabled(void); bool cds_is_self_recovery_enabled(void); void cds_pkt_stats_to_logger_thread(void *pl_hdr, void *pkt_dump, void *data); enum tQDF_GLOBAL_CON_MODE cds_get_conparam(void); + +#ifdef WMI_INTERFACE_EVENT_LOGGING +void cds_print_htc_credit_history(uint32_t count, qdf_abstract_print * print, + void *print_priv); +#endif + #endif /* if !defined __CDS_API_H */ diff --git a/core/cds/src/cds_api.c b/core/cds/src/cds_api.c index 2aa2266d48..dc73d40244 100644 --- a/core/cds/src/cds_api.c +++ b/core/cds/src/cds_api.c @@ -2459,3 +2459,13 @@ enum tQDF_GLOBAL_CON_MODE cds_get_conparam(void) return con_mode; } + +#ifdef WMI_INTERFACE_EVENT_LOGGING +inline void +cds_print_htc_credit_history(uint32_t count, qdf_abstract_print *print, + void *print_priv) +{ + htc_print_credit_history(gp_cds_context->htc_ctx, count, + print, print_priv); +} +#endif diff --git a/core/hdd/src/wlan_hdd_wext.c b/core/hdd/src/wlan_hdd_wext.c index 9776f53cd9..44a5071ef9 100644 --- a/core/hdd/src/wlan_hdd_wext.c +++ b/core/hdd/src/wlan_hdd_wext.c @@ -2673,6 +2673,49 @@ static const hdd_freq_chan_map_t freq_chan_map[] = { #define WE_SET_WLAN_SUSPEND 6 #define WE_SET_WLAN_RESUME 7 +/* + * + * log_buffer - prints host/target related communication logs via dmesg + * + * @INPUT: Log Id, Count + * + * Log Id: + * 0) HTC_CREDIT_HISTORY_LOG + * 1) COMMAND_LOG, + * 2) COMMAND_TX_CMP_LOG, + * 3) MGMT_COMMAND_LOG, + * 4) MGMT_COMMAND_TX_CMP_LOG, + * 5) EVENT_LOG, + * 6) RX_EVENT_LOG, + * 7) MGMT_EVENT_LOG + * + * @OUTPUT: None + * + * @E.g: + * # print up to 10 of the most recent records from HTC Credit History + * iwpriv wlan0 log_buffer 0 10 + * # print up to 3 of the most recent records from Event Log + * iwpriv wlan0 log_buffer 5 3 + * + * Supported Feature: WLAN Trace + * + * Usage: Internal/External + * + * + */ +#define WE_LOG_BUFFER 8 + +enum host_target_comm_log { + HTC_CREDIT_HISTORY_LOG = 0, + COMMAND_LOG, + COMMAND_TX_CMP_LOG, + MGMT_COMMAND_LOG, + MGMT_COMMAND_TX_CMP_LOG, + EVENT_LOG, + RX_EVENT_LOG, + MGMT_EVENT_LOG +}; + /* (SIOCIWFIRSTPRIV + 29) is currently unused */ /* 802.11p IOCTL */ @@ -12375,6 +12418,69 @@ static int wlan_hdd_set_mon_chan(hdd_adapter_t *adapter, uint32_t chan, return qdf_status_to_os_return(status); } +static int printk_adapter(void *priv, const char *fmt, ...) +{ + int ret; + va_list args; + + va_start(args, fmt); + ret = vprintk(fmt, args); + ret += printk("\n"); + va_end(args); + + return ret; +} + +#ifdef WMI_INTERFACE_EVENT_LOGGING +static void hdd_ioctl_log_buffer(int log_id, uint32_t count) +{ + qdf_abstract_print *print = &printk_adapter; + + switch (log_id) { + case HTC_CREDIT_HISTORY_LOG: + print(NULL, "HTC Credit History (count %u)", count); + cds_print_htc_credit_history(count, print, NULL); + break; + case COMMAND_LOG: + print(NULL, "Command Log (count %u)", count); + wma_print_wmi_cmd_log(count, print, NULL); + break; + case COMMAND_TX_CMP_LOG: + print(NULL, "Command Tx Complete Log (count %u)", count); + wma_print_wmi_cmd_tx_cmp_log(count, print, NULL); + break; + case MGMT_COMMAND_LOG: + print(NULL, "Management Command Log (count %u)", count); + wma_print_wmi_mgmt_cmd_log(count, print, NULL); + break; + case MGMT_COMMAND_TX_CMP_LOG: + print(NULL, "Management Command Tx Complete Log (count %u)", + count); + wma_print_wmi_mgmt_cmd_tx_cmp_log(count, print, NULL); + break; + case EVENT_LOG: + print(NULL, "Event Log (count %u)", count); + wma_print_wmi_event_log(count, print, NULL); + break; + case RX_EVENT_LOG: + print(NULL, "Rx Event Log (count %u)", count); + wma_print_wmi_rx_event_log(count, print, NULL); + break; + case MGMT_EVENT_LOG: + print(NULL, "Management Event Log (count %u)", count); + wma_print_wmi_mgmt_event_log(count, print, NULL); + break; + default: + print(NULL, "Invalid Log Id %d", log_id); + break; + } +} +#else +static inline void hdd_ioctl_log_buffer(int log_id, uint32_t count) +{ +} +#endif /* WMI_INTERFACE_EVENT_LOGGING */ + static int __iw_set_two_ints_getnone(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra) @@ -12461,6 +12567,14 @@ static int __iw_set_two_ints_getnone(struct net_device *dev, case WE_SET_WLAN_RESUME: ret = hdd_wlan_fake_apps_resume(hdd_ctx->wiphy, dev); break; + case WE_LOG_BUFFER: { + int log_id = value[1]; + uint32_t count = value[2] < 0 ? 0 : value[2]; + + hdd_ioctl_log_buffer(log_id, count); + + break; + } default: hdd_err("Invalid IOCTL command %d", sub_cmd); break; @@ -13682,6 +13796,10 @@ static const struct iw_priv_args we_private_args[] = { IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "crash_inject"} , + {WE_LOG_BUFFER, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, + 0, "log_buffer"} + , #endif #ifdef WLAN_SUSPEND_RESUME_TEST {WE_SET_WLAN_SUSPEND, diff --git a/core/wma/inc/wma.h b/core/wma/inc/wma.h index 32593b99e2..eae4d42fe0 100644 --- a/core/wma/inc/wma.h +++ b/core/wma/inc/wma.h @@ -2455,4 +2455,81 @@ void wma_vdev_clear_pause_bit(uint8_t vdev_id, wmi_tx_pause_type bit_pos) iface->pause_bitmap &= ~(1 << bit_pos); } +#ifdef WMI_INTERFACE_EVENT_LOGGING +static inline void wma_print_wmi_cmd_log(uint32_t count, + qdf_abstract_print *print, + void *print_priv) +{ + t_wma_handle *wma = cds_get_context(QDF_MODULE_ID_WMA); + + if (wma) + wmi_print_cmd_log(wma->wmi_handle, count, print, print_priv); +} + +static inline void wma_print_wmi_cmd_tx_cmp_log(uint32_t count, + qdf_abstract_print *print, + void *print_priv) +{ + t_wma_handle *wma = cds_get_context(QDF_MODULE_ID_WMA); + + if (wma) + wmi_print_cmd_tx_cmp_log(wma->wmi_handle, count, print, + print_priv); +} + +static inline void wma_print_wmi_mgmt_cmd_log(uint32_t count, + qdf_abstract_print *print, + void *print_priv) +{ + t_wma_handle *wma = cds_get_context(QDF_MODULE_ID_WMA); + + if (wma) + wmi_print_mgmt_cmd_log(wma->wmi_handle, count, print, + print_priv); +} + +static inline void wma_print_wmi_mgmt_cmd_tx_cmp_log(uint32_t count, + qdf_abstract_print *print, + void *print_priv) +{ + t_wma_handle *wma = cds_get_context(QDF_MODULE_ID_WMA); + + if (wma) + wmi_print_mgmt_cmd_tx_cmp_log(wma->wmi_handle, count, print, + print_priv); +} + +static inline void wma_print_wmi_event_log(uint32_t count, + qdf_abstract_print *print, + void *print_priv) +{ + t_wma_handle *wma = cds_get_context(QDF_MODULE_ID_WMA); + + if (wma) + wmi_print_event_log(wma->wmi_handle, count, print, print_priv); +} + +static inline void wma_print_wmi_rx_event_log(uint32_t count, + qdf_abstract_print *print, + void *print_priv) +{ + t_wma_handle *wma = cds_get_context(QDF_MODULE_ID_WMA); + + if (wma) + wmi_print_rx_event_log(wma->wmi_handle, count, print, + print_priv); +} + +static inline void wma_print_wmi_mgmt_event_log(uint32_t count, + qdf_abstract_print *print, + void *print_priv) +{ + t_wma_handle *wma = cds_get_context(QDF_MODULE_ID_WMA); + + if (wma) + wmi_print_mgmt_event_log(wma->wmi_handle, count, print, + print_priv); +} +#endif /* WMI_INTERFACE_EVENT_LOGGING */ + #endif