Selaa lähdekoodia

qcacmn: Hex dump generation for WMI events and commands

This records all the WMI events and commands, for all
PDEVs. Set WMI_EXT_DBG flag to enable this feature. Refer
Original Change-Id: I18e46f683e35912cad717ca3b9cc3d1885315362

Change-Id: I4c9bdfe6fdd195656ca0c01ca400eba595be24a3
CRs-Fixed: 2762266
Jhalak Naik 4 vuotta sitten
vanhempi
sitoutus
41e8d82db9
3 muutettua tiedostoa jossa 388 lisäystä ja 382 poistoa
  1. 4 0
      qdf/linux/src/qdf_debugfs.c
  2. 0 27
      wmi/inc/wmi_unified_priv.h
  3. 384 355
      wmi/src/wmi_unified.c

+ 4 - 0
qdf/linux/src/qdf_debugfs.c

@@ -176,6 +176,7 @@ void qdf_debugfs_hexdump(qdf_debugfs_file_t file, const uint8_t *buf,
 		     false);
 }
 
+qdf_export_symbol(qdf_debugfs_hexdump);
 #else
 
 void qdf_debugfs_hexdump(qdf_debugfs_file_t file, const uint8_t *buf,
@@ -203,6 +204,7 @@ void qdf_debugfs_hexdump(qdf_debugfs_file_t file, const uint8_t *buf,
 	}
 }
 
+qdf_export_symbol(qdf_debugfs_hexdump);
 #endif
 
 bool qdf_debugfs_overflow(qdf_debugfs_file_t file)
@@ -210,6 +212,8 @@ bool qdf_debugfs_overflow(qdf_debugfs_file_t file)
 	return seq_has_overflowed(file);
 }
 
+qdf_export_symbol(qdf_debugfs_overflow);
+
 void qdf_debugfs_write(qdf_debugfs_file_t file, const uint8_t *buf,
 		       qdf_size_t len)
 {

+ 0 - 27
wmi/inc/wmi_unified_priv.h

@@ -2974,33 +2974,6 @@ static inline void wmi_ext_dbg_msg_put(struct wmi_ext_dbg_msg *msg)
 	qdf_mem_free(msg);
 }
 
-#else
-
-static inline QDF_STATUS wmi_ext_dbg_msg_cmd_record(struct wmi_unified
-						    *wmi_handle,
-						    uint8_t *buf, uint32_t len)
-{
-	return QDF_STATUS_SUCCESS;
-}
-
-static inline QDF_STATUS wmi_ext_dbg_msg_event_record(struct wmi_unified
-						      *wmi_handle,
-						      uint8_t *buf,
-						      uint32_t len)
-{
-	return QDF_STATUS_SUCCESS;
-}
-
-static inline QDF_STATUS wmi_ext_dbgfs_init(struct wmi_unified *wmi_handle)
-{
-	return QDF_STATUS_SUCCESS;
-}
-
-static inline QDF_STATUS wmi_ext_dbgfs_deinit(struct wmi_unified *wmi_handle)
-{
-	return QDF_STATUS_SUCCESS;
-}
-
 #endif /*WMI_EXT_DBG */
 
 #ifdef WLAN_CFR_ENABLE

+ 384 - 355
wmi/src/wmi_unified.c

@@ -340,271 +340,6 @@ uint32_t wmi_diag_log_max_entry = WMI_DIAG_RX_EVENT_DEBUG_MAX_ENTRY;
 uint32_t wmi_record_max_length = WMI_DEBUG_ENTRY_MAX_LENGTH;
 uint32_t wmi_display_size = 100;
 
-#ifdef WMI_EXT_DBG
-
-/**
- * wmi_ext_dbg_msg_enqueue() - enqueue wmi message
- *
- * @wmi_handle: wmi handler
- *
- * Return: size of wmi message queue after enqueue
- */
-static uint32_t wmi_ext_dbg_msg_enqueue(struct wmi_unified *wmi_handle,
-					struct wmi_ext_dbg_msg *msg)
-{
-	uint32_t list_size;
-
-	qdf_spinlock_acquire(&wmi_handle->wmi_ext_dbg_msg_queue_lock);
-	qdf_list_insert_back_size(&wmi_handle->wmi_ext_dbg_msg_queue,
-				  &msg->node, &list_size);
-	qdf_spinlock_release(&wmi_handle->wmi_ext_dbg_msg_queue_lock);
-
-	return list_size;
-}
-
-/**
- * wmi_ext_dbg_msg_dequeue() - dequeue wmi message
- *
- * @wmi_handle: wmi handler
- *
- * Return: wmi msg on success else NULL
- */
-static struct wmi_ext_dbg_msg *wmi_ext_dbg_msg_dequeue(struct wmi_unified
-						       *wmi_handle)
-{
-	qdf_list_node_t *list_node = NULL;
-
-	qdf_spinlock_acquire(&wmi_handle->wmi_ext_dbg_msg_queue_lock);
-	qdf_list_remove_front(&wmi_handle->wmi_ext_dbg_msg_queue, &list_node);
-	qdf_spinlock_release(&wmi_handle->wmi_ext_dbg_msg_queue_lock);
-
-	if (!list_node)
-		return NULL;
-
-	return qdf_container_of(list_node, struct wmi_ext_dbg_msg, node);
-}
-
-/**
- * wmi_ext_dbg_msg_record() - record wmi messages
- *
- * @wmi_handle: wmi handler
- * @buf: wmi message buffer
- * @len: wmi message length
- * @type: wmi message type
- *
- * Return: QDF_STATUS_SUCCESS on successful recording else failure.
- */
-static QDF_STATUS wmi_ext_dbg_msg_record(struct wmi_unified *wmi_handle,
-					 uint8_t *buf, uint32_t len,
-					 enum WMI_MSG_TYPE type)
-{
-	struct wmi_ext_dbg_msg *msg;
-	uint32_t list_size;
-
-	msg = wmi_ext_dbg_msg_get(len);
-	if (!msg)
-		return QDF_STATUS_E_NOMEM;
-
-	msg->len = len;
-	msg->type = type;
-	qdf_mem_copy(msg->buf, buf, len);
-	msg->ts = qdf_get_log_timestamp();
-	list_size = wmi_ext_dbg_msg_enqueue(wmi_handle, msg);
-
-	if (list_size >= wmi_handle->wmi_ext_dbg_msg_queue_size) {
-		msg = wmi_ext_dbg_msg_dequeue(wmi_handle);
-		wmi_ext_dbg_msg_put(msg);
-	}
-
-	return QDF_STATUS_SUCCESS;
-}
-
-/**
- * wmi_ext_dbg_msg_cmd_record() - record wmi command messages
- *
- * @wmi_handle: wmi handler
- * @buf: wmi command buffer
- * @len: wmi command message length
- *
- * Return: QDF_STATUS_SUCCESS on successful recording else failure.
- */
-static QDF_STATUS wmi_ext_dbg_msg_cmd_record(struct wmi_unified *wmi_handle,
-					     uint8_t *buf, uint32_t len)
-{
-	return wmi_ext_dbg_msg_record(wmi_handle, buf, len,
-				      WMI_MSG_TYPE_CMD);
-}
-
-/**
- * wmi_ext_dbg_msg_event_record() - record wmi event messages
- *
- * @wmi_handle: wmi handler
- * @buf: wmi event buffer
- * @len: wmi event message length
- *
- * Return: QDF_STATUS_SUCCESS on successful recording else failure.
- */
-static QDF_STATUS wmi_ext_dbg_msg_event_record(struct wmi_unified *wmi_handle,
-					       uint8_t *buf, uint32_t len)
-{
-	uint32_t id;
-
-	id = WMI_GET_FIELD(buf, WMI_CMD_HDR, COMMANDID);
-	if (id != wmi_handle->wmi_events[wmi_diag_event_id])
-		return wmi_ext_dbg_msg_record(wmi_handle, buf, len,
-					      WMI_MSG_TYPE_EVENT);
-
-	return QDF_STATUS_SUCCESS;
-}
-
-/**
- * wmi_ext_dbg_msg_queue_init() - create debugfs queue and associated lock
- *
- * @wmi_handle: wmi handler
- *
- * Return: none
- */
-static void wmi_ext_dbg_msg_queue_init(struct wmi_unified *wmi_handle)
-{
-	qdf_list_create(&wmi_handle->wmi_ext_dbg_msg_queue,
-			wmi_handle->wmi_ext_dbg_msg_queue_size);
-	qdf_spinlock_create(&wmi_handle->wmi_ext_dbg_msg_queue_lock);
-}
-
-/**
- * wmi_ext_dbg_msg_queue_deinit() - destroy debugfs queue and associated lock
- *
- * @wmi_handle: wmi handler
- *
- * Return: none
- */
-static void wmi_ext_dbg_msg_queue_deinit(struct wmi_unified *wmi_handle)
-{
-	qdf_list_destroy(&wmi_handle->wmi_ext_dbg_msg_queue);
-	qdf_spinlock_destroy(&wmi_handle->wmi_ext_dbg_msg_queue_lock);
-}
-
-/**
- * wmi_ext_dbg_msg_show() - debugfs function to display whole content of
- * wmi command/event messages including headers.
- *
- * @file: qdf debugfs file handler
- * @arg: pointer to wmi handler
- *
- * Return: QDF_STATUS_SUCCESS if all the messages are shown successfully,
- * else QDF_STATUS_E_AGAIN if more data to show.
- */
-static QDF_STATUS wmi_ext_dbg_msg_show(qdf_debugfs_file_t file, void *arg)
-{
-	struct wmi_unified *wmi_handle = (struct wmi_unified *)arg;
-	struct wmi_ext_dbg_msg *msg;
-	uint64_t secs, usecs;
-
-	msg = wmi_ext_dbg_msg_dequeue(wmi_handle);
-	if (!msg)
-		return QDF_STATUS_SUCCESS;
-
-	qdf_debugfs_printf(file, "%s: 0x%x\n",
-			   msg->type == WMI_MSG_TYPE_CMD ? "COMMAND" :
-			   "EVENT", WMI_GET_FIELD(msg->buf, WMI_CMD_HDR,
-						  COMMANDID));
-	qdf_log_timestamp_to_secs(msg->ts, &secs, &usecs);
-	qdf_debugfs_printf(file, "Time: %llu.%llu\n", secs, usecs);
-	qdf_debugfs_printf(file, "Length:%d\n", msg->len);
-	qdf_debugfs_hexdump(file, msg->buf, msg->len,
-			    WMI_EXT_DBG_DUMP_ROW_SIZE,
-			    WMI_EXT_DBG_DUMP_GROUP_SIZE);
-	qdf_debugfs_printf(file, "\n");
-
-	if (qdf_debugfs_overflow(file)) {
-		qdf_spinlock_acquire(&wmi_handle->wmi_ext_dbg_msg_queue_lock);
-		qdf_list_insert_front(&wmi_handle->wmi_ext_dbg_msg_queue,
-				      &msg->node);
-		qdf_spinlock_release(&wmi_handle->wmi_ext_dbg_msg_queue_lock);
-
-	} else {
-		wmi_ext_dbg_msg_put(msg);
-	}
-
-	return QDF_STATUS_E_AGAIN;
-}
-
-/**
- * wmi_ext_dbg_msg_write() - debugfs write not supported
- *
- * @priv: private data
- * @buf: received data buffer
- * @len: length of received buffer
- *
- * Return: QDF_STATUS_E_NOSUPPORT.
- */
-static QDF_STATUS wmi_ext_dbg_msg_write(void *priv, const char *buf,
-					qdf_size_t len)
-{
-	return QDF_STATUS_E_NOSUPPORT;
-}
-
-static struct qdf_debugfs_fops wmi_ext_dbgfs_ops = {
-	.show		= wmi_ext_dbg_msg_show,
-	.write		= wmi_ext_dbg_msg_write,
-	.priv		= NULL,
-};
-
-/**
- * wmi_ext_debugfs_init() - init debugfs items for extended wmi dump.
- *
- * @wmi_handle: wmi handler
- *
- * Return: QDF_STATUS_SUCCESS if debugfs is initialized else
- * QDF_STATUS_E_FAILURE
- */
-static QDF_STATUS wmi_ext_dbgfs_init(struct wmi_unified *wmi_handle)
-{
-	qdf_dentry_t dentry;
-
-	dentry  = qdf_debugfs_create_dir(WMI_EXT_DBG_DIR, NULL);
-	if (!dentry) {
-		WMI_LOGE("error while creating extended wmi debugfs dir");
-		return QDF_STATUS_E_FAILURE;
-	}
-
-	wmi_ext_dbgfs_ops.priv = wmi_handle;
-	if (!qdf_debugfs_create_file(WMI_EXT_DBG_FILE, WMI_EXT_DBG_FILE_PERM,
-				     dentry, &wmi_ext_dbgfs_ops)) {
-		qdf_debugfs_remove_dir(dentry);
-		WMI_LOGE("error while creating extended wmi debugfs file");
-		return QDF_STATUS_E_FAILURE;
-	}
-
-	wmi_handle->wmi_ext_dbg_dentry = dentry;
-	wmi_handle->wmi_ext_dbg_msg_queue_size = WMI_EXT_DBG_QUEUE_SIZE;
-	wmi_ext_dbg_msg_queue_init(wmi_handle);
-
-	return QDF_STATUS_SUCCESS;
-}
-
-/**
- * wmi_ext_debugfs_deinit() - cleanup/deinit debugfs items of extended wmi dump.
- *
- * @wmi_handle: wmi handler
- *
- * Return: QDF_STATUS_SUCCESS if cleanup is successful
- */
-static QDF_STATUS wmi_ext_dbgfs_deinit(struct wmi_unified *wmi_handle)
-{
-	struct wmi_ext_dbg_msg *msg;
-
-	while ((msg = wmi_ext_dbg_msg_dequeue(wmi_handle)))
-		wmi_ext_dbg_msg_put(msg);
-
-	wmi_ext_dbg_msg_queue_deinit(wmi_handle);
-	qdf_debugfs_remove_dir_recursive(wmi_handle->wmi_ext_dbg_dentry);
-
-	return QDF_STATUS_SUCCESS;
-}
-
-#endif /*WMI_EXT_DBG */
-
 /**
  * wmi_log_init() - Initialize WMI event logging
  * @wmi_handle: WMI handle.
@@ -1407,138 +1142,430 @@ struct wmi_debugfs_info wmi_debugfs_infos[NUM_DEBUG_INFOS] = {
 #endif
 };
 
+/**
+ * wmi_debugfs_create() - Create debug_fs entry for wmi logging.
+ *
+ * @wmi_handle: wmi handle
+ * @par_entry: debug directory entry
+ * @id: Index to debug info data array
+ *
+ * Return: none
+ */
+static void wmi_debugfs_create(wmi_unified_t wmi_handle,
+			       struct dentry *par_entry)
+{
+	int i;
+
+	if (!par_entry)
+		goto out;
+
+	for (i = 0; i < NUM_DEBUG_INFOS; ++i) {
+		wmi_handle->debugfs_de[i] = debugfs_create_file(
+				wmi_debugfs_infos[i].name, 0644, par_entry,
+				wmi_handle, wmi_debugfs_infos[i].ops);
+
+		if (!wmi_handle->debugfs_de[i]) {
+			WMI_LOGE("debug Entry creation failed!");
+			goto out;
+		}
+	}
+
+	return;
+
+out:
+	WMI_LOGE("debug Entry creation failed!");
+	wmi_log_buffer_free(wmi_handle);
+	return;
+}
+
+/**
+ * wmi_debugfs_remove() - Remove debugfs entry for wmi logging.
+ * @wmi_handle: wmi handle
+ * @dentry: debugfs directory entry
+ * @id: Index to debug info data array
+ *
+ * Return: none
+ */
+static void wmi_debugfs_remove(wmi_unified_t wmi_handle)
+{
+	int i;
+	struct dentry *dentry = wmi_handle->log_info.wmi_log_debugfs_dir;
+
+	if (dentry) {
+		for (i = 0; i < NUM_DEBUG_INFOS; ++i) {
+			if (wmi_handle->debugfs_de[i])
+				wmi_handle->debugfs_de[i] = NULL;
+		}
+	}
+
+	if (dentry)
+		debugfs_remove_recursive(dentry);
+}
+
+/**
+ * wmi_debugfs_init() - debugfs functions to create debugfs directory and to
+ * create debugfs enteries.
+ *
+ * @h: wmi handler
+ *
+ * Return: init status
+ */
+static QDF_STATUS wmi_debugfs_init(wmi_unified_t wmi_handle, uint32_t pdev_idx)
+{
+	char buf[32];
+
+	snprintf(buf, sizeof(buf), "WMI_SOC%u_PDEV%u",
+		 wmi_handle->soc->soc_idx, pdev_idx);
+
+	wmi_handle->log_info.wmi_log_debugfs_dir =
+		debugfs_create_dir(buf, NULL);
+
+	if (!wmi_handle->log_info.wmi_log_debugfs_dir) {
+		WMI_LOGE("error while creating debugfs dir for %s", buf);
+		return QDF_STATUS_E_FAILURE;
+	}
+	wmi_debugfs_create(wmi_handle,
+			   wmi_handle->log_info.wmi_log_debugfs_dir);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * wmi_mgmt_cmd_record() - Wrapper function for mgmt command logging macro
+ *
+ * @wmi_handle: wmi handle
+ * @cmd: mgmt command
+ * @header: pointer to 802.11 header
+ * @vdev_id: vdev id
+ * @chanfreq: channel frequency
+ *
+ * Return: none
+ */
+void wmi_mgmt_cmd_record(wmi_unified_t wmi_handle, uint32_t cmd,
+			void *header, uint32_t vdev_id, uint32_t chanfreq)
+{
+
+	uint32_t data[CUSTOM_MGMT_CMD_DATA_SIZE];
+
+	data[0] = ((struct wmi_command_header *)header)->type;
+	data[1] = ((struct wmi_command_header *)header)->sub_type;
+	data[2] = vdev_id;
+	data[3] = chanfreq;
+
+	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
+/**
+ * wmi_debugfs_remove() - Remove debugfs entry for wmi logging.
+ * @wmi_handle: wmi handle
+ * @dentry: debugfs directory entry
+ * @id: Index to debug info data array
+ *
+ * Return: none
+ */
+static void wmi_debugfs_remove(wmi_unified_t wmi_handle) { }
+void wmi_mgmt_cmd_record(wmi_unified_t wmi_handle, uint32_t cmd,
+			void *header, uint32_t vdev_id, uint32_t chanfreq) { }
+static inline void wmi_log_buffer_free(struct wmi_unified *wmi_handle) { }
+#endif /*WMI_INTERFACE_EVENT_LOGGING */
+qdf_export_symbol(wmi_mgmt_cmd_record);
+
+#ifdef WMI_EXT_DBG
+
+/**
+ * wmi_ext_dbg_msg_enqueue() - enqueue wmi message
+ * @wmi_handle: wmi handler
+ *
+ * Return: size of wmi message queue after enqueue
+ */
+static uint32_t wmi_ext_dbg_msg_enqueue(struct wmi_unified *wmi_handle,
+					struct wmi_ext_dbg_msg *msg)
+{
+	uint32_t list_size;
+
+	qdf_spinlock_acquire(&wmi_handle->wmi_ext_dbg_msg_queue_lock);
+	qdf_list_insert_back_size(&wmi_handle->wmi_ext_dbg_msg_queue,
+				  &msg->node, &list_size);
+	qdf_spinlock_release(&wmi_handle->wmi_ext_dbg_msg_queue_lock);
+
+	return list_size;
+}
+
+/**
+ * wmi_ext_dbg_msg_dequeue() - dequeue wmi message
+ * @wmi_handle: wmi handler
+ *
+ * Return: wmi msg on success else NULL
+ */
+static struct wmi_ext_dbg_msg *wmi_ext_dbg_msg_dequeue(struct wmi_unified
+						       *wmi_handle)
+{
+	qdf_list_node_t *list_node = NULL;
+
+	qdf_spinlock_acquire(&wmi_handle->wmi_ext_dbg_msg_queue_lock);
+	qdf_list_remove_front(&wmi_handle->wmi_ext_dbg_msg_queue, &list_node);
+	qdf_spinlock_release(&wmi_handle->wmi_ext_dbg_msg_queue_lock);
+
+	if (!list_node)
+		return NULL;
+
+	return qdf_container_of(list_node, struct wmi_ext_dbg_msg, node);
+}
+
+/**
+ * wmi_ext_dbg_msg_record() - record wmi messages
+ * @wmi_handle: wmi handler
+ * @buf: wmi message buffer
+ * @len: wmi message length
+ * @type: wmi message type
+ *
+ * Return: QDF_STATUS_SUCCESS on successful recording else failure.
+ */
+static QDF_STATUS wmi_ext_dbg_msg_record(struct wmi_unified *wmi_handle,
+					 uint8_t *buf, uint32_t len,
+					 enum WMI_MSG_TYPE type)
+{
+	struct wmi_ext_dbg_msg *msg;
+	uint32_t list_size;
+
+	msg = wmi_ext_dbg_msg_get(len);
+	if (!msg)
+		return QDF_STATUS_E_NOMEM;
+
+	msg->len = len;
+	msg->type = type;
+	qdf_mem_copy(msg->buf, buf, len);
+	msg->ts = qdf_get_log_timestamp();
+	list_size = wmi_ext_dbg_msg_enqueue(wmi_handle, msg);
+
+	if (list_size >= wmi_handle->wmi_ext_dbg_msg_queue_size) {
+		msg = wmi_ext_dbg_msg_dequeue(wmi_handle);
+		wmi_ext_dbg_msg_put(msg);
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
 
 /**
- * wmi_debugfs_create() - Create debug_fs entry for wmi logging.
- *
- * @wmi_handle: wmi handle
- * @par_entry: debug directory entry
- * @id: Index to debug info data array
+ * wmi_ext_dbg_msg_cmd_record() - record wmi command messages
+ * @wmi_handle: wmi handler
+ * @buf: wmi command buffer
+ * @len: wmi command message length
  *
- * Return: none
+ * Return: QDF_STATUS_SUCCESS on successful recording else failure.
  */
-static void wmi_debugfs_create(wmi_unified_t wmi_handle,
-			       struct dentry *par_entry)
+static QDF_STATUS wmi_ext_dbg_msg_cmd_record(struct wmi_unified *wmi_handle,
+					     uint8_t *buf, uint32_t len)
 {
-	int i;
-
-	if (!par_entry)
-		goto out;
+	return wmi_ext_dbg_msg_record(wmi_handle, buf, len,
+				      WMI_MSG_TYPE_CMD);
+}
 
-	for (i = 0; i < NUM_DEBUG_INFOS; ++i) {
-		wmi_handle->debugfs_de[i] = debugfs_create_file(
-				wmi_debugfs_infos[i].name, 0644, par_entry,
-				wmi_handle, wmi_debugfs_infos[i].ops);
+/**
+ * wmi_ext_dbg_msg_event_record() - record wmi event messages
+ * @wmi_handle: wmi handler
+ * @buf: wmi event buffer
+ * @len: wmi event message length
+ *
+ * Return: QDF_STATUS_SUCCESS on successful recording else failure.
+ */
+static QDF_STATUS wmi_ext_dbg_msg_event_record(struct wmi_unified *wmi_handle,
+					       uint8_t *buf, uint32_t len)
+{
+	uint32_t id;
 
-		if (!wmi_handle->debugfs_de[i]) {
-			WMI_LOGE("debug Entry creation failed!");
-			goto out;
-		}
-	}
+	id = WMI_GET_FIELD(buf, WMI_CMD_HDR, COMMANDID);
+	if (id != wmi_handle->wmi_events[wmi_diag_event_id])
+		return wmi_ext_dbg_msg_record(wmi_handle, buf, len,
+					      WMI_MSG_TYPE_EVENT);
 
-	return;
+	return QDF_STATUS_SUCCESS;
+}
 
-out:
-	WMI_LOGE("debug Entry creation failed!");
-	wmi_log_buffer_free(wmi_handle);
-	return;
+/**
+ * wmi_ext_dbg_msg_queue_init() - create debugfs queue and associated lock
+ * @wmi_handle: wmi handler
+ *
+ * Return: none
+ */
+static void wmi_ext_dbg_msg_queue_init(struct wmi_unified *wmi_handle)
+{
+	qdf_list_create(&wmi_handle->wmi_ext_dbg_msg_queue,
+			wmi_handle->wmi_ext_dbg_msg_queue_size);
+	qdf_spinlock_create(&wmi_handle->wmi_ext_dbg_msg_queue_lock);
 }
 
 /**
- * wmi_debugfs_remove() - Remove debugfs entry for wmi logging.
- * @wmi_handle: wmi handle
- * @dentry: debugfs directory entry
- * @id: Index to debug info data array
+ * wmi_ext_dbg_msg_queue_deinit() - destroy debugfs queue and associated lock
+ * @wmi_handle: wmi handler
  *
  * Return: none
  */
-static void wmi_debugfs_remove(wmi_unified_t wmi_handle)
+static void wmi_ext_dbg_msg_queue_deinit(struct wmi_unified *wmi_handle)
 {
-	int i;
-	struct dentry *dentry = wmi_handle->log_info.wmi_log_debugfs_dir;
+	qdf_list_destroy(&wmi_handle->wmi_ext_dbg_msg_queue);
+	qdf_spinlock_destroy(&wmi_handle->wmi_ext_dbg_msg_queue_lock);
+}
 
-	if (dentry) {
-		for (i = 0; i < NUM_DEBUG_INFOS; ++i) {
-			if (wmi_handle->debugfs_de[i])
-				wmi_handle->debugfs_de[i] = NULL;
-		}
+/**
+ * wmi_ext_dbg_msg_show() - debugfs function to display whole content of
+ * wmi command/event messages including headers.
+ * @file: qdf debugfs file handler
+ * @arg: pointer to wmi handler
+ *
+ * Return: QDF_STATUS_SUCCESS if all the messages are shown successfully,
+ * else QDF_STATUS_E_AGAIN if more data to show.
+ */
+static QDF_STATUS wmi_ext_dbg_msg_show(qdf_debugfs_file_t file, void *arg)
+{
+	struct wmi_unified *wmi_handle = (struct wmi_unified *)arg;
+	struct wmi_ext_dbg_msg *msg;
+	uint64_t secs, usecs;
+
+	msg = wmi_ext_dbg_msg_dequeue(wmi_handle);
+	if (!msg)
+		return QDF_STATUS_SUCCESS;
+
+	qdf_debugfs_printf(file, "%s: 0x%x\n",
+			   msg->type == WMI_MSG_TYPE_CMD ? "COMMAND" :
+			   "EVENT", WMI_GET_FIELD(msg->buf, WMI_CMD_HDR,
+						  COMMANDID));
+	qdf_log_timestamp_to_secs(msg->ts, &secs, &usecs);
+	qdf_debugfs_printf(file, "Time: %llu.%llu\n", secs, usecs);
+	qdf_debugfs_printf(file, "Length:%d\n", msg->len);
+	qdf_debugfs_hexdump(file, msg->buf, msg->len,
+			    WMI_EXT_DBG_DUMP_ROW_SIZE,
+			    WMI_EXT_DBG_DUMP_GROUP_SIZE);
+	qdf_debugfs_printf(file, "\n");
+
+	if (qdf_debugfs_overflow(file)) {
+		qdf_spinlock_acquire(&wmi_handle->wmi_ext_dbg_msg_queue_lock);
+		qdf_list_insert_front(&wmi_handle->wmi_ext_dbg_msg_queue,
+				      &msg->node);
+		qdf_spinlock_release(&wmi_handle->wmi_ext_dbg_msg_queue_lock);
+
+	} else {
+		wmi_ext_dbg_msg_put(msg);
 	}
 
-	if (dentry)
-		debugfs_remove_recursive(dentry);
+	return QDF_STATUS_E_AGAIN;
 }
 
 /**
- * wmi_debugfs_init() - debugfs functions to create debugfs directory and to
- * create debugfs enteries.
+ * wmi_ext_dbg_msg_write() - debugfs write not supported
+ * @priv: private data
+ * @buf: received data buffer
+ * @len: length of received buffer
  *
- * @h: wmi handler
+ * Return: QDF_STATUS_E_NOSUPPORT.
+ */
+static QDF_STATUS wmi_ext_dbg_msg_write(void *priv, const char *buf,
+					qdf_size_t len)
+{
+	return QDF_STATUS_E_NOSUPPORT;
+}
+
+static struct qdf_debugfs_fops wmi_ext_dbgfs_ops[WMI_MAX_RADIOS];
+
+/**
+ * wmi_ext_debugfs_init() - init debugfs items for extended wmi dump.
+ * @wmi_handle: wmi handler
+ * @pdev_idx: pdev index
  *
- * Return: init status
+ * Return: QDF_STATUS_SUCCESS if debugfs is initialized else
+ * QDF_STATUS_E_FAILURE
  */
-static QDF_STATUS wmi_debugfs_init(wmi_unified_t wmi_handle, uint32_t pdev_idx)
+static QDF_STATUS wmi_ext_dbgfs_init(struct wmi_unified *wmi_handle,
+				     uint32_t pdev_idx)
 {
+	qdf_dentry_t dentry;
 	char buf[32];
 
-	snprintf(buf, sizeof(buf), "WMI_SOC%u_PDEV%u",
-		 wmi_handle->soc->soc_idx, pdev_idx);
+	/* To maintain backward compatibility, naming convention for PDEV 0
+	 * dentry is kept same as before. For more than 1 PDEV, dentry
+	 * names will be appended with PDEVx.
+	*/
+	if (wmi_handle->soc->soc_idx == 0 && pdev_idx == 0) {
+		dentry  = qdf_debugfs_create_dir(WMI_EXT_DBG_DIR, NULL);
+	} else {
+		snprintf(buf, sizeof(buf), "WMI_EXT_DBG_SOC%u_PDEV%u",
+			 wmi_handle->soc->soc_idx, pdev_idx);
+		dentry  = qdf_debugfs_create_dir(buf, NULL);
+	}
 
-	wmi_handle->log_info.wmi_log_debugfs_dir =
-		debugfs_create_dir(buf, NULL);
+	if (!dentry) {
+		WMI_LOGE("error while creating extended wmi debugfs dir");
+		return QDF_STATUS_E_FAILURE;
+	}
 
-	if (!wmi_handle->log_info.wmi_log_debugfs_dir) {
-		WMI_LOGE("error while creating debugfs dir for %s", buf);
+	wmi_ext_dbgfs_ops[pdev_idx].show = wmi_ext_dbg_msg_show;
+	wmi_ext_dbgfs_ops[pdev_idx].write = wmi_ext_dbg_msg_write;
+	wmi_ext_dbgfs_ops[pdev_idx].priv = wmi_handle;
+	if (!qdf_debugfs_create_file(WMI_EXT_DBG_FILE, WMI_EXT_DBG_FILE_PERM,
+				     dentry, &wmi_ext_dbgfs_ops[pdev_idx])) {
+		qdf_debugfs_remove_dir(dentry);
+		WMI_LOGE("error while creating extended wmi debugfs file");
 		return QDF_STATUS_E_FAILURE;
 	}
-	wmi_debugfs_create(wmi_handle,
-			   wmi_handle->log_info.wmi_log_debugfs_dir);
+
+	wmi_handle->wmi_ext_dbg_dentry = dentry;
+	wmi_handle->wmi_ext_dbg_msg_queue_size = WMI_EXT_DBG_QUEUE_SIZE;
+	wmi_ext_dbg_msg_queue_init(wmi_handle);
 
 	return QDF_STATUS_SUCCESS;
 }
 
 /**
- * wmi_mgmt_cmd_record() - Wrapper function for mgmt command logging macro
- *
- * @wmi_handle: wmi handle
- * @cmd: mgmt command
- * @header: pointer to 802.11 header
- * @vdev_id: vdev id
- * @chanfreq: channel frequency
+ * wmi_ext_debugfs_deinit() - cleanup/deinit debugfs items of extended wmi dump.
+ * @wmi_handle: wmi handler
  *
- * Return: none
+ * Return: QDF_STATUS_SUCCESS if cleanup is successful
  */
-void wmi_mgmt_cmd_record(wmi_unified_t wmi_handle, uint32_t cmd,
-			void *header, uint32_t vdev_id, uint32_t chanfreq)
+static QDF_STATUS wmi_ext_dbgfs_deinit(struct wmi_unified *wmi_handle)
 {
+	struct wmi_ext_dbg_msg *msg;
 
-	uint32_t data[CUSTOM_MGMT_CMD_DATA_SIZE];
-
-	data[0] = ((struct wmi_command_header *)header)->type;
-	data[1] = ((struct wmi_command_header *)header)->sub_type;
-	data[2] = vdev_id;
-	data[3] = chanfreq;
+	while ((msg = wmi_ext_dbg_msg_dequeue(wmi_handle)))
+		wmi_ext_dbg_msg_put(msg);
 
-	qdf_spin_lock_bh(&wmi_handle->log_info.wmi_record_lock);
+	wmi_ext_dbg_msg_queue_deinit(wmi_handle);
+	qdf_debugfs_remove_dir_recursive(wmi_handle->wmi_ext_dbg_dentry);
 
-	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);
+	return QDF_STATUS_SUCCESS;
 }
+
 #else
-/**
- * wmi_debugfs_remove() - Remove debugfs entry for wmi logging.
- * @wmi_handle: wmi handle
- * @dentry: debugfs directory entry
- * @id: Index to debug info data array
- *
- * Return: none
- */
-static void wmi_debugfs_remove(wmi_unified_t wmi_handle) { }
-void wmi_mgmt_cmd_record(wmi_unified_t wmi_handle, uint32_t cmd,
-			void *header, uint32_t vdev_id, uint32_t chanfreq) { }
-static inline void wmi_log_buffer_free(struct wmi_unified *wmi_handle) { }
-#endif /*WMI_INTERFACE_EVENT_LOGGING */
-qdf_export_symbol(wmi_mgmt_cmd_record);
+
+static inline QDF_STATUS wmi_ext_dbg_msg_cmd_record(struct wmi_unified
+						    *wmi_handle,
+						    uint8_t *buf, uint32_t len)
+{
+		return QDF_STATUS_SUCCESS;
+}
+
+static inline QDF_STATUS wmi_ext_dbg_msg_event_record(struct wmi_unified
+						      *wmi_handle,
+						      uint8_t *buf, uint32_t len)
+{
+		return QDF_STATUS_SUCCESS;
+}
+
+static inline QDF_STATUS wmi_ext_dbgfs_init(struct wmi_unified *wmi_handle,
+					    uint32_t pdev_idx)
+{
+		return QDF_STATUS_SUCCESS;
+}
+
+static inline QDF_STATUS wmi_ext_dbgfs_deinit(struct wmi_unified *wmi_handle)
+{
+		return QDF_STATUS_SUCCESS;
+}
+
+#endif /*WMI_EXT_DBG */
 
 int wmi_get_host_credits(wmi_unified_t wmi_handle);
 /* WMI buffer APIs */
@@ -2754,6 +2781,9 @@ void *wmi_unified_get_pdev_handle(struct wmi_soc *soc, uint32_t pdev_idx)
 		wmi_handle->wmi_max_cmds = soc->wmi_max_cmds;
 
 		wmi_interface_sequence_init(wmi_handle);
+		if (wmi_ext_dbgfs_init(wmi_handle, pdev_idx) !=
+		    QDF_STATUS_SUCCESS)
+			WMI_LOGE("failed to initialize wmi extended debugfs");
 
 		soc->wmi_pdev[pdev_idx] = wmi_handle;
 	} else
@@ -2902,7 +2932,7 @@ void *wmi_unified_attach(void *scn_handle,
 	qdf_spinlock_create(&soc->ctx_lock);
 	soc->ops = wmi_handle->ops;
 	soc->wmi_pdev[0] = wmi_handle;
-	if (wmi_ext_dbgfs_init(wmi_handle) != QDF_STATUS_SUCCESS)
+	if (wmi_ext_dbgfs_init(wmi_handle, 0) != QDF_STATUS_SUCCESS)
 		WMI_LOGE("failed to initialize wmi extended debugfs");
 
 	wmi_wbuff_register(wmi_handle);
@@ -2935,8 +2965,6 @@ void wmi_unified_detach(struct wmi_unified *wmi_handle)
 
 	wmi_wbuff_deregister(wmi_handle);
 
-	wmi_ext_dbgfs_deinit(wmi_handle);
-
 	soc = wmi_handle->soc;
 	for (i = 0; i < WMI_MAX_RADIOS; i++) {
 		if (soc->wmi_pdev[i]) {
@@ -2963,6 +2991,7 @@ void wmi_unified_detach(struct wmi_unified *wmi_handle)
 			qdf_spinlock_destroy(&soc->wmi_pdev[i]->eventq_lock);
 
 			wmi_interface_sequence_deinit(soc->wmi_pdev[i]);
+			wmi_ext_dbgfs_deinit(soc->wmi_pdev[i]);
 
 			qdf_mem_free(soc->wmi_pdev[i]);
 		}