From cde9070d9970eef1f7ec2360586c802a16230ad8 Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Fri, 10 May 2024 07:43:50 +0000
Subject: [PATCH] rtl88x2CE_WiFi_linux driver

---
 kernel/drivers/net/wireless/rockchip_wlan/cywdhd/bcmdhd/dhd_debug.h |  625 +++++++++++++++++++++++++++++++++++++++++++++++++++-----
 1 files changed, 567 insertions(+), 58 deletions(-)

diff --git a/kernel/drivers/net/wireless/rockchip_wlan/cywdhd/bcmdhd/dhd_debug.h b/kernel/drivers/net/wireless/rockchip_wlan/cywdhd/bcmdhd/dhd_debug.h
index 0d0e860..ec893ae 100644
--- a/kernel/drivers/net/wireless/rockchip_wlan/cywdhd/bcmdhd/dhd_debug.h
+++ b/kernel/drivers/net/wireless/rockchip_wlan/cywdhd/bcmdhd/dhd_debug.h
@@ -1,15 +1,18 @@
-/* SPDX-License-Identifier: GPL-2.0 */
 /*
  * DHD debugability header file
  *
- * Copyright (C) 1999-2019, Broadcom Corporation
- * 
+ * <<Broadcom-WL-IPTag/Open:>>
+ *
+ * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
+ *
+ * Copyright (C) 1999-2017, Broadcom Corporation
+ *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
  * under the terms of the GNU General Public License version 2 (the "GPL"),
  * available at http://www.broadcom.com/licenses/GPLv2.php, with the
  * following added to such license:
- * 
+ *
  *      As a special exception, the copyright holders of this software give you
  * permission to link this software with independent modules, and to copy and
  * distribute the resulting executable under terms of your choice, provided that
@@ -17,22 +20,24 @@
  * the license of that module.  An independent module is a module which is not
  * derived from this software.  The special exception does not apply to any
  * modifications of the software.
- * 
+ *
  *      Notwithstanding the above, under no circumstances may you combine this
  * software in any way with any other Broadcom software provided under a license
  * other than the GPL, without Broadcom's express prior written consent.
  *
- * $Id: dhd_debug.h 560028 2015-05-29 10:50:33Z $
+ * $Id: dhd_debug.h 701031 2017-05-23 11:19:09Z $
  */
 
 #ifndef _dhd_debug_h_
 #define _dhd_debug_h_
+#include <event_log.h>
+#include <bcmutils.h>
+#include <dhd_dbg_ring.h>
+
 enum {
 	DEBUG_RING_ID_INVALID	= 0,
 	FW_VERBOSE_RING_ID,
-	FW_EVENT_RING_ID,
 	DHD_EVENT_RING_ID,
-	NAN_EVENT_RING_ID,
 	/* add new id here */
 	DEBUG_RING_ID_MAX
 };
@@ -46,7 +51,9 @@
 	DBG_WAKE_LOCK_SUPPORTED = (1 << (4)), /* WAKE LOCK of Driver */
 	DBG_VERBOSE_LOG_SUPPORTED = (1 << (5)), /* verbose log of FW */
 	DBG_HEALTH_CHECK_SUPPORTED = (1 << (6)), /* monitor the health of FW */
-	DBG_NAN_EVENT_SUPPORTED = (1 << (7)), /* NAN Events */
+	DBG_DRIVER_DUMP_SUPPORTED = (1 << (7)), /* dumps driver state */
+	DBG_PACKET_FATE_SUPPORTED = (1 << (8)), /* tracks connection packets' fate */
+	DBG_NAN_EVENT_SUPPORTED = (1 << (9)), /* NAN Events */
 };
 
 enum {
@@ -56,10 +63,9 @@
 	DBG_RING_ENTRY_FLAGS_HAS_TIMESTAMP = (1 << (1))
 };
 
-#define DBGRING_NAME_MAX		32
 /* firmware verbose ring, ring id 1 */
 #define FW_VERBOSE_RING_NAME		"fw_verbose"
-#define FW_VERBOSE_RING_SIZE		(64 * 1024)
+#define FW_VERBOSE_RING_SIZE		(256 * 1024)
 /* firmware event ring, ring id 2 */
 #define FW_EVENT_RING_NAME		"fw_event"
 #define FW_EVENT_RING_SIZE		(64 * 1024)
@@ -70,10 +76,20 @@
 #define NAN_EVENT_RING_NAME		"nan_event"
 #define NAN_EVENT_RING_SIZE		(64 * 1024)
 
-#define DBG_RING_STATUS_SIZE (sizeof(dhd_dbg_ring_status_t))
+#define TLV_LOG_SIZE(tlv) ((tlv) ? (sizeof(tlv_log) + (tlv)->len) : 0)
+
+#define TLV_LOG_NEXT(tlv) \
+	((tlv) ? ((tlv_log *)((uint8 *)tlv + TLV_LOG_SIZE(tlv))) : 0)
 
 #define VALID_RING(id)	\
-	(id > DEBUG_RING_ID_INVALID && id < DEBUG_RING_ID_MAX)
+	((id > DEBUG_RING_ID_INVALID) && (id < DEBUG_RING_ID_MAX))
+
+#ifdef DEBUGABILITY
+#define DBG_RING_ACTIVE(dhdp, ring_id) \
+	((dhdp)->dbg->dbg_rings[(ring_id)].state == RING_ACTIVE)
+#else
+#define DBG_RING_ACTIVE(dhdp, ring_id) 0
+#endif /* DEBUGABILITY */
 
 enum {
 	/* driver receive association command from kernel */
@@ -113,8 +129,7 @@
 	WIFI_EVENT_FW_EAPOL_FRAME_TRANSMIT_STOP,
 	/* kernel queue EAPOL for transmission in driver with EAPOL index 1-4 */
 	WIFI_EVENT_DRIVER_EAPOL_FRAME_TRANSMIT_REQUESTED,
-	/*
-	 * with rate, regardless of the fact that EAPOL frame is accepted or
+	/* with rate, regardless of the fact that EAPOL frame is accepted or
 	 * rejected by firmware
 	 */
 	WIFI_EVENT_FW_EAPOL_FRAME_RECEIVED,
@@ -138,7 +153,43 @@
 	/* firmware sends assoc/reassoc frame in */
 	WIFI_EVENT_ROAM_ASSOC_STARTED,
 	/* firmware receive assoc/reassoc confirm from ap */
-	WIFI_EVENT_ROAM_ASSOC_COMPLETE
+	WIFI_EVENT_ROAM_ASSOC_COMPLETE,
+	/* firmware sends stop G_SCAN */
+	WIFI_EVENT_G_SCAN_STOP,
+	/* firmware indicates G_SCAN scan cycle started */
+	WIFI_EVENT_G_SCAN_CYCLE_STARTED,
+	/* firmware indicates G_SCAN scan cycle completed */
+	WIFI_EVENT_G_SCAN_CYCLE_COMPLETED,
+	/* firmware indicates G_SCAN scan start for a particular bucket */
+	WIFI_EVENT_G_SCAN_BUCKET_STARTED,
+	/* firmware indicates G_SCAN scan completed for particular bucket */
+	WIFI_EVENT_G_SCAN_BUCKET_COMPLETED,
+	/* Event received from firmware about G_SCAN scan results being available */
+	WIFI_EVENT_G_SCAN_RESULTS_AVAILABLE,
+	/* Event received from firmware with G_SCAN capabilities */
+	WIFI_EVENT_G_SCAN_CAPABILITIES,
+	/* Event received from firmware when eligible candidate is found */
+	WIFI_EVENT_ROAM_CANDIDATE_FOUND,
+	/* Event received from firmware when roam scan configuration gets enabled or disabled */
+	WIFI_EVENT_ROAM_SCAN_CONFIG,
+	/* firmware/driver timed out authentication */
+	WIFI_EVENT_AUTH_TIMEOUT,
+	/* firmware/driver timed out association */
+	WIFI_EVENT_ASSOC_TIMEOUT,
+	/* firmware/driver encountered allocation failure */
+	WIFI_EVENT_MEM_ALLOC_FAILURE,
+	/* driver added a PNO network in firmware */
+	WIFI_EVENT_DRIVER_PNO_ADD,
+	/* driver removed a PNO network in firmware */
+	WIFI_EVENT_DRIVER_PNO_REMOVE,
+	/* driver received PNO networks found indication from firmware */
+	WIFI_EVENT_DRIVER_PNO_NETWORK_FOUND,
+	/* driver triggered a scan for PNO networks */
+	WIFI_EVENT_DRIVER_PNO_SCAN_REQUESTED,
+	/* driver received scan results of PNO networks */
+	WIFI_EVENT_DRIVER_PNO_SCAN_RESULT_FOUND,
+	/* driver updated scan results from PNO candidates to cfg */
+	WIFI_EVENT_DRIVER_PNO_SCAN_COMPLETE
 };
 
 enum {
@@ -158,9 +209,23 @@
 	/* take one or more specific 802.11 IEs parameter, IEs are in turn
 	 * indicated in TLV format as per 802.11 spec
 	 */
-	WIFI_TAG_INTERFACE, /* take interface name as parameter */
-	WIFI_TAG_REASON_CODE, /* take a reason code as per 802.11 as parameter */
-	WIFI_TAG_RATE_MBPS, /* take a wifi rate in 0.5 mbps */
+	WIFI_TAG_INTERFACE,	/* take interface name as parameter */
+	WIFI_TAG_REASON_CODE,	/* take a reason code as per 802.11 as parameter */
+	WIFI_TAG_RATE_MBPS,	/* take a wifi rate in 0.5 mbps */
+	WIFI_TAG_REQUEST_ID,	/* take an integer as parameter */
+	WIFI_TAG_BUCKET_ID,	/* take an integer as parameter */
+	WIFI_TAG_GSCAN_PARAMS,	/* takes a wifi_scan_cmd_params struct as parameter */
+	WIFI_TAG_GSCAN_CAPABILITIES, /* takes a wifi_gscan_capabilities struct as parameter */
+	WIFI_TAG_SCAN_ID,	/* take an integer as parameter */
+	WIFI_TAG_RSSI,		/* takes s16 as parameter */
+	WIFI_TAG_CHANNEL,	/* takes u16 as parameter */
+	WIFI_TAG_LINK_ID,	/* take an integer as parameter */
+	WIFI_TAG_LINK_ROLE,	/* take an integer as parameter */
+	WIFI_TAG_LINK_STATE,	/* take an integer as parameter */
+	WIFI_TAG_LINK_TYPE,	/* take an integer as parameter */
+	WIFI_TAG_TSCO,		/* take an integer as parameter */
+	WIFI_TAG_RSCO,		/* take an integer as parameter */
+	WIFI_TAG_EAPOL_MESSAGE_TYPE /* take an integer as parameter */
 };
 
 /* NAN  events */
@@ -179,7 +244,7 @@
 typedef struct {
     uint16 tag;
     uint16 len; /* length of value */
-    uint8 *value;
+    uint8 value[0];
 } tlv_log;
 
 typedef struct per_packet_status_entry {
@@ -221,6 +286,8 @@
     uint8 *data;
 } per_packet_status_entry_t;
 
+#define PACKED_STRUCT __attribute__ ((packed))
+
 typedef struct log_conn_event {
     uint16 event;
     tlv_log *tlvs;
@@ -231,7 +298,7 @@
 	* as well, event_data can include a vendor proprietary part which is
 	* understood by the developer only.
 	*/
-} log_conn_event_t;
+} PACKED_STRUCT log_conn_event_t;
 
 /*
  * Ring buffer name for power events ring. note that power event are extremely frequents
@@ -267,64 +334,481 @@
 	DBG_RING_ENTRY_NAN_EVENT_TYPE
 };
 
-typedef struct dhd_dbg_ring_entry {
-	uint16 len; /* payload length excluding the header */
-	uint8 flags;
-	uint8 type; /* Per ring specific */
-	uint64 timestamp; /* present if has_timestamp bit is set. */
-} dhd_dbg_ring_entry_t;
-
-#define DBG_RING_ENTRY_SIZE (sizeof(dhd_dbg_ring_entry_t))
-#define ENTRY_LENGTH(hdr) (hdr->len + DBG_RING_ENTRY_SIZE)
-typedef struct dhd_dbg_ring_status {
-	uint8 name[DBGRING_NAME_MAX];
-	uint32 flags;
-	int ring_id; /* unique integer representing the ring */
-	/* total memory size allocated for the buffer */
-	uint32 ring_buffer_byte_size;
-	uint32 verbose_level;
-	/* number of bytes that was written to the buffer by driver */
-	uint32 written_bytes;
-	/* number of bytes that was read from the buffer by user land */
-	uint32 read_bytes;
-	/* number of records that was read from the buffer by user land */
-	uint32 written_records;
-} dhd_dbg_ring_status_t;
-
 struct log_level_table {
 	int log_level;
 	uint16 tag;
 	char *desc;
 };
 
-typedef void (*dbg_pullreq_t)(void *os_priv, const int ring_id);
-
-typedef void (*dbg_urgent_noti_t) (dhd_pub_t *dhdp, const void *data, const uint32 len);
-
-#define DBG_EVENT_LOG(dhd, connect_state) \
-{											\
+#ifdef OEM_ANDROID
+/*
+ * Assuming that the Ring lock is mutex, bailing out if the
+ * callers are from atomic context. On a long term, one has to
+ * schedule a job to execute in sleepable context so that
+ * contents are pushed to the ring.
+ */
+#define DBG_EVENT_LOG(dhdp, connect_state)					\
+{										\
 	do {									\
-		uint16 state = connect_state;			\
-		dhd_os_push_push_ring_data(dhd, DHD_EVENT_RING_ID, &state, sizeof(state)); \
-	} while (0);						\
+		uint16 state = connect_state;					\
+		if (CAN_SLEEP() && DBG_RING_ACTIVE(dhdp, DHD_EVENT_RING_ID))			\
+			dhd_os_push_push_ring_data(dhdp, DHD_EVENT_RING_ID,	\
+				&state, sizeof(state));				\
+	} while (0);								\
 }
+#else
+#define DBG_EVENT_LOG(dhd, connect_state)
+#endif /* !OEM_ANDROID */
+
+#define MD5_PREFIX_LEN				4
+#define MAX_FATE_LOG_LEN			32
+#define MAX_FRAME_LEN_ETHERNET		1518
+#define MAX_FRAME_LEN_80211_MGMT	2352 /* 802.11-2012 Fig. 8-34 */
+
+typedef enum {
+	/* Sent over air and ACKed. */
+	TX_PKT_FATE_ACKED,
+
+	/* Sent over air but not ACKed. (Normal for broadcast/multicast.) */
+	TX_PKT_FATE_SENT,
+
+	/* Queued within firmware, but not yet sent over air. */
+	TX_PKT_FATE_FW_QUEUED,
+
+	/*
+	 * Dropped by firmware as invalid. E.g. bad source address,
+	 * bad checksum, or invalid for current state.
+	 */
+	TX_PKT_FATE_FW_DROP_INVALID,
+
+	/* Dropped by firmware due to lifetime expiration. */
+	TX_PKT_FATE_FW_DROP_EXPTIME,
+
+	/*
+	 * Dropped by firmware for any other reason. Includes
+	 * frames that were sent by driver to firmware, but
+	 * unaccounted for by firmware.
+	 */
+	TX_PKT_FATE_FW_DROP_OTHER,
+
+	/* Queued within driver, not yet sent to firmware. */
+	TX_PKT_FATE_DRV_QUEUED,
+
+	/*
+	 * Dropped by driver as invalid. E.g. bad source address,
+	 * or invalid for current state.
+	 */
+	TX_PKT_FATE_DRV_DROP_INVALID,
+
+	/* Dropped by driver due to lack of buffer space. */
+	TX_PKT_FATE_DRV_DROP_NOBUFS,
+
+	/*  Dropped by driver for any other reason. */
+	TX_PKT_FATE_DRV_DROP_OTHER,
+
+	/* Packet free by firmware. */
+	TX_PKT_FATE_FW_PKT_FREE,
+
+	} wifi_tx_packet_fate;
+
+typedef enum {
+	/* Valid and delivered to network stack (e.g., netif_rx()). */
+	RX_PKT_FATE_SUCCESS,
+
+	/* Queued within firmware, but not yet sent to driver. */
+	RX_PKT_FATE_FW_QUEUED,
+
+	/* Dropped by firmware due to host-programmable filters. */
+	RX_PKT_FATE_FW_DROP_FILTER,
+
+	/*
+	 * Dropped by firmware as invalid. E.g. bad checksum,
+	 * decrypt failed, or invalid for current state.
+	 */
+	RX_PKT_FATE_FW_DROP_INVALID,
+
+	/* Dropped by firmware due to lack of buffer space. */
+	RX_PKT_FATE_FW_DROP_NOBUFS,
+
+	/* Dropped by firmware for any other reason. */
+	RX_PKT_FATE_FW_DROP_OTHER,
+
+	/* Queued within driver, not yet delivered to network stack. */
+	RX_PKT_FATE_DRV_QUEUED,
+
+	/* Dropped by driver due to filter rules. */
+	RX_PKT_FATE_DRV_DROP_FILTER,
+
+	/* Dropped by driver as invalid. E.g. not permitted in current state. */
+	RX_PKT_FATE_DRV_DROP_INVALID,
+
+	/* Dropped by driver due to lack of buffer space. */
+	RX_PKT_FATE_DRV_DROP_NOBUFS,
+
+	/* Dropped by driver for any other reason. */
+	RX_PKT_FATE_DRV_DROP_OTHER,
+
+	} wifi_rx_packet_fate;
+
+typedef enum {
+	FRAME_TYPE_UNKNOWN,
+	FRAME_TYPE_ETHERNET_II,
+	FRAME_TYPE_80211_MGMT,
+	} frame_type;
+
+typedef struct wifi_frame_info {
+	/*
+	 * The type of MAC-layer frame that this frame_info holds.
+	 * - For data frames, use FRAME_TYPE_ETHERNET_II.
+	 * - For management frames, use FRAME_TYPE_80211_MGMT.
+	 * - If the type of the frame is unknown, use FRAME_TYPE_UNKNOWN.
+	 */
+	frame_type payload_type;
+
+	/*
+	 * The number of bytes included in |frame_content|. If the frame
+	 * contents are missing (e.g. RX frame dropped in firmware),
+	 * |frame_len| should be set to 0.
+	 */
+	size_t frame_len;
+
+	/*
+	 * Host clock when this frame was received by the driver (either
+	 *	outbound from the host network stack, or inbound from the
+	 *	firmware).
+	 *	- The timestamp should be taken from a clock which includes time
+	 *	  the host spent suspended (e.g. ktime_get_boottime()).
+	 *	- If no host timestamp is available (e.g. RX frame was dropped in
+	 *	  firmware), this field should be set to 0.
+	 */
+	uint32 driver_timestamp_usec;
+
+	/*
+	 * Firmware clock when this frame was received by the firmware
+	 *	(either outbound from the host, or inbound from a remote
+	 *	station).
+	 *	- The timestamp should be taken from a clock which includes time
+	 *	  firmware spent suspended (if applicable).
+	 *	- If no firmware timestamp is available (e.g. TX frame was
+	 *	  dropped by driver), this field should be set to 0.
+	 *	- Consumers of |frame_info| should _not_ assume any
+	 *	  synchronization between driver and firmware clocks.
+	 */
+	uint32 firmware_timestamp_usec;
+
+	/*
+	 * Actual frame content.
+	 * - Should be provided for TX frames originated by the host.
+	 * - Should be provided for RX frames received by the driver.
+	 * - Optionally provided for TX frames originated by firmware. (At
+	 *   discretion of HAL implementation.)
+	 * - Optionally provided for RX frames dropped in firmware. (At
+	 *   discretion of HAL implementation.)
+	 * - If frame content is not provided, |frame_len| should be set
+	 *   to 0.
+	 */
+	union {
+		char ethernet_ii[MAX_FRAME_LEN_ETHERNET];
+		char ieee_80211_mgmt[MAX_FRAME_LEN_80211_MGMT];
+	} frame_content;
+} wifi_frame_info_t;
+
+typedef struct wifi_tx_report {
+	/*
+	 * Prefix of MD5 hash of |frame_inf.frame_content|. If frame
+	 * content is not provided, prefix of MD5 hash over the same data
+	 * that would be in frame_content, if frame content were provided.
+	 */
+	char md5_prefix[MD5_PREFIX_LEN];
+	wifi_tx_packet_fate fate;
+	wifi_frame_info_t frame_inf;
+} wifi_tx_report_t;
+
+typedef struct wifi_rx_report {
+	/*
+	 * Prefix of MD5 hash of |frame_inf.frame_content|. If frame
+	 * content is not provided, prefix of MD5 hash over the same data
+	 * that would be in frame_content, if frame content were provided.
+	 */
+	char md5_prefix[MD5_PREFIX_LEN];
+	wifi_rx_packet_fate fate;
+	wifi_frame_info_t frame_inf;
+} wifi_rx_report_t;
+
+typedef struct compat_wifi_frame_info {
+	frame_type payload_type;
+
+	uint32 frame_len;
+
+	uint32 driver_timestamp_usec;
+
+	uint32 firmware_timestamp_usec;
+
+	union {
+		char ethernet_ii[MAX_FRAME_LEN_ETHERNET];
+		char ieee_80211_mgmt[MAX_FRAME_LEN_80211_MGMT];
+	} frame_content;
+} compat_wifi_frame_info_t;
+
+typedef struct compat_wifi_tx_report {
+	char md5_prefix[MD5_PREFIX_LEN];
+	wifi_tx_packet_fate fate;
+	compat_wifi_frame_info_t frame_inf;
+} compat_wifi_tx_report_t;
+
+typedef struct compat_wifi_rx_report {
+	char md5_prefix[MD5_PREFIX_LEN];
+	wifi_rx_packet_fate fate;
+	compat_wifi_frame_info_t frame_inf;
+} compat_wifi_rx_report_t;
+
+/*
+ * Packet logging - internal data
+ */
+
+typedef enum dhd_dbg_pkt_mon_state {
+	PKT_MON_INVALID = 0,
+	PKT_MON_ATTACHED,
+	PKT_MON_STARTING,
+	PKT_MON_STARTED,
+	PKT_MON_STOPPING,
+	PKT_MON_STOPPED,
+	PKT_MON_DETACHED,
+	} dhd_dbg_pkt_mon_state_t;
+
+typedef struct dhd_dbg_pkt_info {
+	frame_type payload_type;
+	size_t pkt_len;
+	uint32 driver_ts;
+	uint32 firmware_ts;
+	uint32 pkt_hash;
+	void *pkt;
+} dhd_dbg_pkt_info_t;
+
+typedef struct compat_dhd_dbg_pkt_info {
+	frame_type payload_type;
+	uint32 pkt_len;
+	uint32 driver_ts;
+	uint32 firmware_ts;
+	uint32 pkt_hash;
+	void *pkt;
+} compat_dhd_dbg_pkt_info_t;
+
+typedef struct dhd_dbg_tx_info
+{
+	wifi_tx_packet_fate fate;
+	dhd_dbg_pkt_info_t info;
+} dhd_dbg_tx_info_t;
+
+typedef struct dhd_dbg_rx_info
+{
+	wifi_rx_packet_fate fate;
+	dhd_dbg_pkt_info_t info;
+} dhd_dbg_rx_info_t;
+
+typedef struct dhd_dbg_tx_report
+{
+	dhd_dbg_tx_info_t *tx_pkts;
+	uint16 pkt_pos;
+	uint16 status_pos;
+} dhd_dbg_tx_report_t;
+
+typedef struct dhd_dbg_rx_report
+{
+	dhd_dbg_rx_info_t *rx_pkts;
+	uint16 pkt_pos;
+} dhd_dbg_rx_report_t;
+
+typedef void (*dbg_pullreq_t)(void *os_priv, const int ring_id);
+typedef void (*dbg_urgent_noti_t) (dhd_pub_t *dhdp, const void *data, const uint32 len);
+typedef int (*dbg_mon_tx_pkts_t) (dhd_pub_t *dhdp, void *pkt, uint32 pktid);
+typedef int (*dbg_mon_tx_status_t) (dhd_pub_t *dhdp, void *pkt,
+	uint32 pktid, uint16 status);
+typedef int (*dbg_mon_rx_pkts_t) (dhd_pub_t *dhdp, void *pkt);
+
+typedef struct dhd_dbg_pkt_mon
+{
+	dhd_dbg_tx_report_t *tx_report;
+	dhd_dbg_rx_report_t *rx_report;
+	dhd_dbg_pkt_mon_state_t tx_pkt_state;
+	dhd_dbg_pkt_mon_state_t tx_status_state;
+	dhd_dbg_pkt_mon_state_t rx_pkt_state;
+
+	/* call backs */
+	dbg_mon_tx_pkts_t tx_pkt_mon;
+	dbg_mon_tx_status_t tx_status_mon;
+	dbg_mon_rx_pkts_t rx_pkt_mon;
+} dhd_dbg_pkt_mon_t;
+
+typedef struct dhd_dbg {
+	dhd_dbg_ring_t dbg_rings[DEBUG_RING_ID_MAX];
+	void *private;          /* os private_data */
+	dhd_dbg_pkt_mon_t pkt_mon;
+	void *pkt_mon_lock; /* spin lock for packet monitoring */
+	dbg_pullreq_t pullreq;
+	dbg_urgent_noti_t urgent_notifier;
+} dhd_dbg_t;
+
+#define PKT_MON_ATTACHED(state) \
+		(((state) > PKT_MON_INVALID) && ((state) < PKT_MON_DETACHED))
+#define PKT_MON_DETACHED(state) \
+		(((state) == PKT_MON_INVALID) || ((state) == PKT_MON_DETACHED))
+#define PKT_MON_STARTED(state) ((state) == PKT_MON_STARTED)
+#define PKT_MON_STOPPED(state) ((state) == PKT_MON_STOPPED)
+#define PKT_MON_NOT_OPERATIONAL(state) \
+	(((state) != PKT_MON_STARTED) && ((state) != PKT_MON_STOPPED))
+#define PKT_MON_SAFE_TO_FREE(state) \
+	(((state) == PKT_MON_STARTING) || ((state) == PKT_MON_STOPPED))
+#define PKT_MON_PKT_FULL(pkt_count) ((pkt_count) >= MAX_FATE_LOG_LEN)
+#define PKT_MON_STATUS_FULL(pkt_count, status_count) \
+		(((status_count) >= (pkt_count)) || ((status_count) >= MAX_FATE_LOG_LEN))
+
+#ifdef DBG_PKT_MON
+#define DHD_DBG_PKT_MON_TX(dhdp, pkt, pktid) \
+	do { \
+		if ((dhdp) && (dhdp)->dbg && (dhdp)->dbg->pkt_mon.tx_pkt_mon && (pkt)) { \
+			(dhdp)->dbg->pkt_mon.tx_pkt_mon((dhdp), (pkt), (pktid)); \
+		} \
+	} while (0);
+#define DHD_DBG_PKT_MON_TX_STATUS(dhdp, pkt, pktid, status) \
+	do { \
+		if ((dhdp) && (dhdp)->dbg && (dhdp)->dbg->pkt_mon.tx_status_mon && (pkt)) { \
+			(dhdp)->dbg->pkt_mon.tx_status_mon((dhdp), (pkt), (pktid), (status)); \
+		} \
+	} while (0);
+#define DHD_DBG_PKT_MON_RX(dhdp, pkt) \
+	do { \
+		if ((dhdp) && (dhdp)->dbg && (dhdp)->dbg->pkt_mon.rx_pkt_mon && (pkt)) { \
+			if (ntoh16((pkt)->protocol) != ETHER_TYPE_BRCM) { \
+				(dhdp)->dbg->pkt_mon.rx_pkt_mon((dhdp), (pkt)); \
+			} \
+		} \
+	} while (0);
+
+#define DHD_DBG_PKT_MON_START(dhdp) \
+		dhd_os_dbg_start_pkt_monitor((dhdp));
+#define DHD_DBG_PKT_MON_STOP(dhdp) \
+		dhd_os_dbg_stop_pkt_monitor((dhdp));
+#else
+#define DHD_DBG_PKT_MON_TX(dhdp, pkt, pktid)
+#define DHD_DBG_PKT_MON_TX_STATUS(dhdp, pkt, pktid, status)
+#define DHD_DBG_PKT_MON_RX(dhdp, pkt)
+#define DHD_DBG_PKT_MON_START(dhdp)
+#define DHD_DBG_PKT_MON_STOP(dhdp)
+#endif /* DBG_PKT_MON */
+
+#ifdef DUMP_IOCTL_IOV_LIST
+typedef struct dhd_iov_li {
+	dll_t list;
+	uint32 cmd; /* command number */
+	char buff[100]; /* command name */
+} dhd_iov_li_t;
+#endif /* DUMP_IOCTL_IOV_LIST */
+
+#define IOV_LIST_MAX_LEN 5
+
+#ifdef DHD_DEBUG
+typedef struct {
+	dll_t list;
+	uint32 id; /* wasted chunk id */
+	uint32 handle; /* wasted chunk handle */
+	uint32 size; /* wasted chunk size */
+} dhd_dbg_mwli_t;
+#endif /* DHD_DEBUG */
+
+#define DHD_OW_BI_RAW_EVENT_LOG_FMT 0xFFFF
+
+/* LSB 2 bits of format number to identify the type of event log */
+#define DHD_EVENT_LOG_HDR_MASK 0x3
+
+#define DHD_EVENT_LOG_FMT_NUM_OFFSET 2
+#define DHD_EVENT_LOG_FMT_NUM_MASK 0x3FFF
+/**
+ * OW:- one word
+ * TW:- two word
+ * NB:- non binary
+ * BI:- binary
+ */
+#define	DHD_OW_NB_EVENT_LOG_HDR 0
+#define DHD_TW_NB_EVENT_LOG_HDR 1
+#define DHD_BI_EVENT_LOG_HDR 3
+#define DHD_INVALID_EVENT_LOG_HDR 2
+
+#define DHD_TW_VALID_TAG_BITS_MASK 0xF
+#define DHD_OW_BI_EVENT_FMT_NUM 0x3FFF
+#define DHD_TW_BI_EVENT_FMT_NUM 0x3FFE
+
+#define DHD_TW_EVENT_LOG_TAG_OFFSET 8
+
+#define EVENT_TAG_TIMESTAMP_OFFSET 1
+#define EVENT_TAG_TIMESTAMP_EXT_OFFSET 2
+
+typedef struct prcd_event_log_hdr {
+	uint32 tag;		/* Event_log entry tag */
+	uint32 count;		/* Count of 4-byte entries */
+	uint32 fmt_num_raw;	/* Format number */
+	uint32 fmt_num;		/* Format number >> 2 */
+	uint32 armcycle;	/* global ARM CYCLE for TAG */
+	uint32 *log_ptr;	/* start of payload */
+	uint32	payload_len;
+	/* Extended event log header info
+	 * 0 - legacy, 1 - extended event log header present
+	 */
+	bool ext_event_log_hdr;
+	bool binary_payload;	/* 0 - non binary payload, 1 - binary payload */
+} prcd_event_log_hdr_t;		/* Processed event log header */
 
 /* dhd_dbg functions */
 extern void dhd_dbg_trace_evnt_handler(dhd_pub_t *dhdp, void *event_data,
 		void *raw_event_ptr, uint datalen);
+void dhd_dbg_msgtrace_log_parser(dhd_pub_t *dhdp, void *event_data,
+	void *raw_event_ptr, uint datalen, bool msgtrace_hdr_present,
+	uint32 msgtrace_seqnum);
+
 extern int dhd_dbg_attach(dhd_pub_t *dhdp, dbg_pullreq_t os_pullreq,
 	dbg_urgent_noti_t os_urgent_notifier, void *os_priv);
 extern void dhd_dbg_detach(dhd_pub_t *dhdp);
 extern int dhd_dbg_start(dhd_pub_t *dhdp, bool start);
 extern int dhd_dbg_set_configuration(dhd_pub_t *dhdp, int ring_id,
 		int log_level, int flags, uint32 threshold);
-extern int dhd_dbg_get_ring_status(dhd_pub_t *dhdp, int ring_id,
-		dhd_dbg_ring_status_t *dbg_ring_status);
-extern int dhd_dbg_ring_push(dhd_pub_t *dhdp, int ring_id, dhd_dbg_ring_entry_t *hdr, void *data);
-extern int dhd_dbg_ring_pull(dhd_pub_t *dhdp, int ring_id, void *data, uint32 buf_len);
 extern int dhd_dbg_find_ring_id(dhd_pub_t *dhdp, char *ring_name);
+extern dhd_dbg_ring_t *dhd_dbg_get_ring_from_ring_id(dhd_pub_t *dhdp, int ring_id);
 extern void *dhd_dbg_get_priv(dhd_pub_t *dhdp);
 extern int dhd_dbg_send_urgent_evt(dhd_pub_t *dhdp, const void *data, const uint32 len);
+extern void dhd_dbg_verboselog_printf(dhd_pub_t *dhdp, prcd_event_log_hdr_t *plog_hdr,
+	void *raw_event_ptr, uint32 *log_ptr, uint32 logset, uint16 block);
+int dhd_dbg_pull_from_ring(dhd_pub_t *dhdp, int ring_id, void *data, uint32 buf_len);
+int dhd_dbg_pull_single_from_ring(dhd_pub_t *dhdp, int ring_id, void *data, uint32 buf_len,
+	bool strip_header);
+int dhd_dbg_push_to_ring(dhd_pub_t *dhdp, int ring_id, dhd_dbg_ring_entry_t *hdr,
+		void *data);
+int __dhd_dbg_get_ring_status(dhd_dbg_ring_t *ring, dhd_dbg_ring_status_t *ring_status);
+int dhd_dbg_get_ring_status(dhd_pub_t *dhdp, int ring_id,
+		dhd_dbg_ring_status_t *dbg_ring_status);
+#ifdef SHOW_LOGTRACE
+void dhd_dbg_read_ring_into_trace_buf(dhd_dbg_ring_t *ring, trace_buf_info_t *trace_buf_info);
+#endif /* SHOW_LOGTRACE */
+
+#ifdef DBG_PKT_MON
+extern int dhd_dbg_attach_pkt_monitor(dhd_pub_t *dhdp,
+		dbg_mon_tx_pkts_t tx_pkt_mon,
+		dbg_mon_tx_status_t tx_status_mon,
+		dbg_mon_rx_pkts_t rx_pkt_mon);
+extern int dhd_dbg_start_pkt_monitor(dhd_pub_t *dhdp);
+extern int dhd_dbg_monitor_tx_pkts(dhd_pub_t *dhdp, void *pkt, uint32 pktid);
+extern int dhd_dbg_monitor_tx_status(dhd_pub_t *dhdp, void *pkt,
+		uint32 pktid, uint16 status);
+extern int dhd_dbg_monitor_rx_pkts(dhd_pub_t *dhdp, void *pkt);
+extern int dhd_dbg_stop_pkt_monitor(dhd_pub_t *dhdp);
+extern int dhd_dbg_monitor_get_tx_pkts(dhd_pub_t *dhdp, void __user *user_buf,
+		uint16 req_count, uint16 *resp_count);
+extern int dhd_dbg_monitor_get_rx_pkts(dhd_pub_t *dhdp, void __user *user_buf,
+		uint16 req_count, uint16 *resp_count);
+extern int dhd_dbg_detach_pkt_monitor(dhd_pub_t *dhdp);
+#endif /* DBG_PKT_MON */
+
+extern bool dhd_dbg_process_tx_status(dhd_pub_t *dhdp, void *pkt,
+		uint32 pktid, uint16 status);
 
 /* os wrapper function */
 extern int dhd_os_dbg_attach(dhd_pub_t *dhdp);
@@ -346,4 +830,29 @@
 extern int dhd_os_push_push_ring_data(dhd_pub_t *dhdp, int ring_id, void *data, int32 data_len);
 extern int dhd_os_dbg_get_feature(dhd_pub_t *dhdp, int32 *features);
 
+#ifdef DBG_PKT_MON
+extern int dhd_os_dbg_attach_pkt_monitor(dhd_pub_t *dhdp);
+extern int dhd_os_dbg_start_pkt_monitor(dhd_pub_t *dhdp);
+extern int dhd_os_dbg_monitor_tx_pkts(dhd_pub_t *dhdp, void *pkt,
+	uint32 pktid);
+extern int dhd_os_dbg_monitor_tx_status(dhd_pub_t *dhdp, void *pkt,
+	uint32 pktid, uint16 status);
+extern int dhd_os_dbg_monitor_rx_pkts(dhd_pub_t *dhdp, void *pkt);
+extern int dhd_os_dbg_stop_pkt_monitor(dhd_pub_t *dhdp);
+extern int dhd_os_dbg_monitor_get_tx_pkts(dhd_pub_t *dhdp,
+	void __user *user_buf, uint16 req_count, uint16 *resp_count);
+extern int dhd_os_dbg_monitor_get_rx_pkts(dhd_pub_t *dhdp,
+	void __user *user_buf, uint16 req_count, uint16 *resp_count);
+extern int dhd_os_dbg_detach_pkt_monitor(dhd_pub_t *dhdp);
+#endif /* DBG_PKT_MON */
+
+#ifdef DUMP_IOCTL_IOV_LIST
+extern void dhd_iov_li_append(dhd_pub_t *dhd, dll_t *list_head, dll_t *node);
+extern void dhd_iov_li_print(dll_t *list_head);
+extern void dhd_iov_li_delete(dhd_pub_t *dhd, dll_t *list_head);
+#endif /* DUMP_IOCTL_IOV_LIST */
+
+#ifdef DHD_DEBUG
+extern void dhd_mw_list_delete(dhd_pub_t *dhd, dll_t *list_head);
+#endif /* DHD_DEBUG */
 #endif /* _dhd_debug_h_ */

--
Gitblit v1.6.2