qcacmn: Separate WMI diag rx event logging

FW generates too many diag events and these diag events
also come on CE-2 together with other critical control
path WMI events and easily over-run useful control path
WMI RX even log buffer. Separate WMI diag rx event loggig
in a separate log buffer such that useful control path WMI
log event buffer is not over-run.

Change-Id: I89b5d88036bc9d7e57e8e16858bc556be4e2ed41
CRs-Fixed: 2318083
Bug: 119838321
diff --git a/wmi/inc/wmi_unified_priv.h b/wmi/inc/wmi_unified_priv.h
index 32229e8..c7116dc 100644
--- a/wmi/inc/wmi_unified_priv.h
+++ b/wmi/inc/wmi_unified_priv.h
@@ -49,6 +49,8 @@
 #define WMI_EVENT_DEBUG_ENTRY_MAX_LENGTH (16)
 /* wmi_mgmt commands */
 #define WMI_MGMT_EVENT_DEBUG_MAX_ENTRY (256)
+/* wmi diag rx events max buffer */
+#define WMI_DIAG_RX_EVENT_DEBUG_MAX_ENTRY (256)
 
 /**
  * struct wmi_command_debug - WMI command log buffer data type
@@ -127,12 +129,14 @@
  * @wmi_mgmt_command_tx_cmp_log_buf_info - Buffer info for WMI Management
  * Command Tx completion log
  * @wmi_mgmt_event_log_buf_info - Buffer info for WMI Management event log
+ * @wmi_diag_event_log_buf_info - Buffer info for WMI diag event log
  * @wmi_record_lock - Lock WMI recording
  * @wmi_logging_enable - Enable/Disable state for WMI logging
  * @buf_offset_command - Offset from where WMI command data should be logged
  * @buf_offset_event - Offset from where WMI event data should be logged
  * @is_management_record - Function refernce to check if command/event is
  *  management record
+ * @is_diag_event - Function refernce to check if event is diag event
  * @wmi_id_to_name - Function refernce to API to convert Command id to
  * string name
  * @wmi_log_debugfs_dir - refernce to debugfs directory
@@ -147,12 +151,14 @@
 	struct wmi_log_buf_t wmi_mgmt_command_log_buf_info;
 	struct wmi_log_buf_t wmi_mgmt_command_tx_cmp_log_buf_info;
 	struct wmi_log_buf_t wmi_mgmt_event_log_buf_info;
+	struct wmi_log_buf_t wmi_diag_event_log_buf_info;
 
 	qdf_spinlock_t wmi_record_lock;
 	bool wmi_logging_enable;
 	uint32_t buf_offset_command;
 	uint32_t buf_offset_event;
 	bool (*is_management_record)(uint32_t cmd_id);
+	bool (*is_diag_event)(uint32_t event_id);
 	uint8_t *(*wmi_id_to_name)(uint32_t cmd_id);
 	struct dentry *wmi_log_debugfs_dir;
 	uint8_t wmi_instance_id;
diff --git a/wmi/src/wmi_unified.c b/wmi/src/wmi_unified.c
index 2359a9d..b423832 100644
--- a/wmi/src/wmi_unified.c
+++ b/wmi/src/wmi_unified.c
@@ -215,10 +215,15 @@
 struct wmi_command_debug
 wmi_mgmt_command_tx_cmp_log_buffer[WMI_MGMT_EVENT_DEBUG_MAX_ENTRY];
 
-/* wmi_mgmt events when processed */
-uint32_t g_wmi_mgmt_event_buf_idx = 0;
+/* wmi_mgmt events are received */
+uint32_t g_wmi_mgmt_rx_event_buf_idx = 0;
 struct wmi_event_debug
-wmi_mgmt_event_log_buffer[WMI_MGMT_EVENT_DEBUG_MAX_ENTRY];
+wmi_mgmt_rx_event_log_buffer[WMI_MGMT_EVENT_DEBUG_MAX_ENTRY];
+
+/* wmi_diag events are received */
+uint32_t g_wmi_diag_rx_event_buf_idx = 0;
+struct wmi_event_debug
+wmi_diag_rx_event_log_buffer[WMI_DIAG_RX_EVENT_DEBUG_MAX_ENTRY];
 
 #define WMI_MGMT_COMMAND_RECORD(a, b, c, d, e) {			     \
 	if (WMI_MGMT_EVENT_DEBUG_MAX_ENTRY <=				     \
@@ -259,7 +264,7 @@
 	h->log_info.wmi_mgmt_command_tx_cmp_log_buf_info.length++;	\
 }
 
-#define WMI_MGMT_EVENT_RECORD(h, a, b) {				\
+#define WMI_MGMT_RX_EVENT_RECORD(h, a, b) {				\
 	if (wmi_mgmt_log_max_entry <=					\
 		*(h->log_info.wmi_mgmt_event_log_buf_info.p_buf_tail_idx))\
 		*(h->log_info.wmi_mgmt_event_log_buf_info.p_buf_tail_idx) = 0;\
@@ -277,9 +282,29 @@
 	h->log_info.wmi_mgmt_event_log_buf_info.length++;		\
 }
 
+#define WMI_DIAG_RX_EVENT_RECORD(h, a, b) {				\
+	if (wmi_mgmt_log_max_entry <=					\
+		*(h->log_info.wmi_diag_event_log_buf_info.p_buf_tail_idx))\
+		*(h->log_info.wmi_diag_event_log_buf_info.p_buf_tail_idx) = 0;\
+	((struct wmi_event_debug *)h->log_info.wmi_diag_event_log_buf_info.buf)\
+		[*(h->log_info.wmi_diag_event_log_buf_info.p_buf_tail_idx)]\
+					.event = a;			\
+	qdf_mem_copy(((struct wmi_event_debug *)h->log_info.		\
+				wmi_diag_event_log_buf_info.buf)	\
+		[*(h->log_info.wmi_diag_event_log_buf_info.p_buf_tail_idx)].\
+			data, b, wmi_record_max_length);		\
+	((struct wmi_event_debug *)h->log_info.wmi_diag_event_log_buf_info.buf)\
+		[*(h->log_info.wmi_diag_event_log_buf_info.p_buf_tail_idx)].\
+			time = qdf_get_log_timestamp();			\
+	(*(h->log_info.wmi_diag_event_log_buf_info.p_buf_tail_idx))++;	\
+	h->log_info.wmi_diag_event_log_buf_info.length++;		\
+}
+
+
 /* These are defined to made it as module param, which can be configured */
 uint32_t wmi_log_max_entry = WMI_EVENT_DEBUG_MAX_ENTRY;
 uint32_t wmi_mgmt_log_max_entry = WMI_MGMT_EVENT_DEBUG_MAX_ENTRY;
+uint32_t wmi_diag_log_max_entry = WMI_DIAG_RX_EVENT_DEBUG_MAX_ENTRY;
 uint32_t wmi_record_max_length = WMI_EVENT_DEBUG_ENTRY_MAX_LENGTH;
 uint32_t wmi_display_size = 100;
 
@@ -308,6 +333,8 @@
 		&wmi_handle->log_info.wmi_mgmt_command_tx_cmp_log_buf_info;
 	struct wmi_log_buf_t *mgmt_event_log_buf =
 			&wmi_handle->log_info.wmi_mgmt_event_log_buf_info;
+	struct wmi_log_buf_t *diag_event_log_buf =
+			&wmi_handle->log_info.wmi_diag_event_log_buf_info;
 
 	/* WMI commands */
 	cmd_log_buf->length = 0;
@@ -352,13 +379,20 @@
 		&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*/
+	/* WMI Management events when received*/
 	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->buf = wmi_mgmt_rx_event_log_buffer;
+	mgmt_event_log_buf->p_buf_tail_idx = &g_wmi_mgmt_rx_event_buf_idx;
 	mgmt_event_log_buf->size = WMI_MGMT_EVENT_DEBUG_MAX_ENTRY;
 
+	/* WMI diag events when received */
+	diag_event_log_buf->length = 0;
+	diag_event_log_buf->buf_tail_idx = 0;
+	diag_event_log_buf->buf = wmi_diag_rx_event_log_buffer;
+	diag_event_log_buf->p_buf_tail_idx = &g_wmi_diag_rx_event_buf_idx;
+	diag_event_log_buf->size = WMI_DIAG_RX_EVENT_DEBUG_MAX_ENTRY;
+
 	qdf_spinlock_create(&wmi_handle->log_info.wmi_record_lock);
 	wmi_handle->log_info.wmi_logging_enable = 1;
 
@@ -383,6 +417,8 @@
 		&wmi_handle->log_info.wmi_mgmt_command_tx_cmp_log_buf_info;
 	struct wmi_log_buf_t *mgmt_event_log_buf =
 			&wmi_handle->log_info.wmi_mgmt_event_log_buf_info;
+	struct wmi_log_buf_t *diag_event_log_buf =
+			&wmi_handle->log_info.wmi_diag_event_log_buf_info;
 
 	wmi_handle->log_info.wmi_logging_enable = 0;
 
@@ -468,7 +504,7 @@
 	mgmt_cmd_tx_cmp_log_buf->p_buf_tail_idx =
 		&mgmt_cmd_tx_cmp_log_buf->buf_tail_idx;
 
-	/* WMI Management events when processed*/
+	/* WMI Management events when received */
 	mgmt_event_log_buf->length = 0;
 	mgmt_event_log_buf->buf_tail_idx = 0;
 
@@ -483,6 +519,21 @@
 	}
 	mgmt_event_log_buf->p_buf_tail_idx = &mgmt_event_log_buf->buf_tail_idx;
 
+	/* WMI diag events when received */
+	diag_event_log_buf->length = 0;
+	diag_event_log_buf->buf_tail_idx = 0;
+
+	diag_event_log_buf->buf = (struct wmi_event_debug *) qdf_mem_malloc(
+		wmi_diag_log_max_entry *
+		sizeof(struct wmi_event_debug));
+	diag_event_log_buf->size = wmi_diag_log_max_entry;
+
+	if (!diag_event_log_buf->buf) {
+		qdf_print("no memory for WMI diag event log buffer..\n");
+		return QDF_STATUS_E_NOMEM;
+	}
+	diag_event_log_buf->p_buf_tail_idx = &diag_event_log_buf->buf_tail_idx;
+
 	qdf_spinlock_create(&wmi_handle->log_info.wmi_record_lock);
 	wmi_handle->log_info.wmi_logging_enable = 1;
 
@@ -519,6 +570,9 @@
 	if (wmi_handle->log_info.wmi_mgmt_event_log_buf_info.buf)
 		qdf_mem_free(
 			wmi_handle->log_info.wmi_mgmt_event_log_buf_info.buf);
+	if (wmi_handle->log_info.wmi_diag_event_log_buf_info.buf)
+		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);
 }
@@ -1597,8 +1651,18 @@
 
 		qdf_spin_lock_bh(&wmi_handle->log_info.wmi_record_lock);
 		/* Exclude 4 bytes of TLV header */
-		WMI_RX_EVENT_RECORD(wmi_handle, id, ((uint8_t *) data +
+		if (wmi_handle->log_info.is_diag_event(id)) {
+			WMI_DIAG_RX_EVENT_RECORD(wmi_handle, id,
+				((uint8_t *) data +
 				wmi_handle->log_info.buf_offset_event));
+		} else if (wmi_handle->log_info.is_management_record(id)) {
+			WMI_MGMT_RX_EVENT_RECORD(wmi_handle, id,
+				((uint8_t *) data +
+				wmi_handle->log_info.buf_offset_event));
+		} else {
+			WMI_RX_EVENT_RECORD(wmi_handle, id, ((uint8_t *) data +
+				wmi_handle->log_info.buf_offset_event));
+		}
 		qdf_spin_unlock_bh(&wmi_handle->log_info.wmi_record_lock);
 	}
 #endif
@@ -1683,9 +1747,16 @@
 	if (wmi_handle->log_info.wmi_logging_enable) {
 		qdf_spin_lock_bh(&wmi_handle->log_info.wmi_record_lock);
 		/* Exclude 4 bytes of TLV header */
-		if (wmi_handle->log_info.is_management_record(id)) {
-			WMI_MGMT_EVENT_RECORD(wmi_handle, id, ((uint8_t *) data
-				+ wmi_handle->log_info.buf_offset_event));
+		if (wmi_handle->log_info.is_diag_event(id)) {
+			/*
+			 * skip diag event logging in WMI event buffer
+			 * as its already logged in WMI RX event buffer
+			 */
+		} else if (wmi_handle->log_info.is_management_record(id)) {
+			/*
+			 * skip wmi mgmt event logging in WMI event buffer
+			 * as its already logged in WMI RX event buffer
+			 */
 		} else {
 			WMI_EVENT_RECORD(wmi_handle, id, ((uint8_t *) data +
 					wmi_handle->log_info.buf_offset_event));
diff --git a/wmi/src/wmi_unified_non_tlv.c b/wmi/src/wmi_unified_non_tlv.c
index b44b3c4..ac19623 100644
--- a/wmi/src/wmi_unified_non_tlv.c
+++ b/wmi/src/wmi_unified_non_tlv.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016-2018 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -7227,6 +7227,14 @@
 
 	return false;
 }
+
+static bool is_diag_event_non_tlv(uint32_t event_id)
+{
+	if (WMI_DIAG_EVENTID == event_id)
+		return true;
+
+	return false;
+}
 #endif
 
 /**
@@ -8026,6 +8034,8 @@
 	wmi_handle->log_info.buf_offset_event = 0;
 	wmi_handle->log_info.is_management_record =
 		is_management_record_non_tlv;
+	wmi_handle->log_info.is_diag_event =
+		is_diag_event_non_tlv;
 	/*(uint8 *)(*wmi_id_to_name)(uint32_t cmd_id);*/
 #endif
 #else
diff --git a/wmi/src/wmi_unified_tlv.c b/wmi/src/wmi_unified_tlv.c
index 78aad63..06801e7 100644
--- a/wmi/src/wmi_unified_tlv.c
+++ b/wmi/src/wmi_unified_tlv.c
@@ -13791,6 +13791,14 @@
 
 	return false;
 }
+
+static bool is_diag_event_tlv(uint32_t event_id)
+{
+	if (WMI_DIAG_EVENTID == event_id)
+		return true;
+
+	return false;
+}
 #endif
 
 static uint16_t wmi_tag_vdev_set_cmd(wmi_unified_t wmi_hdl, wmi_buf_t buf)
@@ -15864,6 +15872,8 @@
 	wmi_handle->log_info.buf_offset_event = 4;
 	wmi_handle->log_info.is_management_record =
 		is_management_record_tlv;
+	wmi_handle->log_info.is_diag_event =
+		is_diag_event_tlv;
 #endif
 	populate_tlv_service(wmi_handle->services);
 	populate_tlv_events_id(wmi_handle->wmi_events);
@@ -15879,6 +15889,8 @@
 	wmi_handle->log_info.buf_offset_event = 4;
 	wmi_handle->log_info.is_management_record =
 		is_management_record_tlv;
+	wmi_handle->log_info.is_diag_event =
+		is_diag_event_tlv;
 #endif
 }
 #endif