Browse Source

qcacld-3.0: Expose WMI/Credit History debugging APIs via ioctl

Add an ioctl that allows a user to dump a specified number of records to
dmesg for WMI and Credit History.

Change-Id: I644dcf5edcb2f875af1e99e7b4677cde37081674
CRs-Fixed: 2028760
Dustin Brown 8 years ago
parent
commit
8d2d0f57a5
4 changed files with 211 additions and 0 deletions
  1. 6 0
      core/cds/inc/cds_api.h
  2. 10 0
      core/cds/src/cds_api.c
  3. 118 0
      core/hdd/src/wlan_hdd_wext.c
  4. 77 0
      core/wma/inc/wma.h

+ 6 - 0
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 */

+ 10 - 0
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

+ 118 - 0
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
 
+/*
+ * <ioctl>
+ * 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
+ *
+ * </ioctl>
+ */
+#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,

+ 77 - 0
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