xref: /OK3568_Linux_fs/external/rkwifibt/drivers/infineon/dhd_debug.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun  * DHD debugability header file
3*4882a593Smuzhiyun  *
4*4882a593Smuzhiyun  * <<Broadcom-WL-IPTag/Open:>>
5*4882a593Smuzhiyun  *
6*4882a593Smuzhiyun  * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
7*4882a593Smuzhiyun  *
8*4882a593Smuzhiyun  * Copyright (C) 1999-2017, Broadcom Corporation
9*4882a593Smuzhiyun  *
10*4882a593Smuzhiyun  *      Unless you and Broadcom execute a separate written software license
11*4882a593Smuzhiyun  * agreement governing use of this software, this software is licensed to you
12*4882a593Smuzhiyun  * under the terms of the GNU General Public License version 2 (the "GPL"),
13*4882a593Smuzhiyun  * available at http://www.broadcom.com/licenses/GPLv2.php, with the
14*4882a593Smuzhiyun  * following added to such license:
15*4882a593Smuzhiyun  *
16*4882a593Smuzhiyun  *      As a special exception, the copyright holders of this software give you
17*4882a593Smuzhiyun  * permission to link this software with independent modules, and to copy and
18*4882a593Smuzhiyun  * distribute the resulting executable under terms of your choice, provided that
19*4882a593Smuzhiyun  * you also meet, for each linked independent module, the terms and conditions of
20*4882a593Smuzhiyun  * the license of that module.  An independent module is a module which is not
21*4882a593Smuzhiyun  * derived from this software.  The special exception does not apply to any
22*4882a593Smuzhiyun  * modifications of the software.
23*4882a593Smuzhiyun  *
24*4882a593Smuzhiyun  *      Notwithstanding the above, under no circumstances may you combine this
25*4882a593Smuzhiyun  * software in any way with any other Broadcom software provided under a license
26*4882a593Smuzhiyun  * other than the GPL, without Broadcom's express prior written consent.
27*4882a593Smuzhiyun  *
28*4882a593Smuzhiyun  * $Id: dhd_debug.h 701031 2017-05-23 11:19:09Z $
29*4882a593Smuzhiyun  */
30*4882a593Smuzhiyun 
31*4882a593Smuzhiyun #ifndef _dhd_debug_h_
32*4882a593Smuzhiyun #define _dhd_debug_h_
33*4882a593Smuzhiyun #include <event_log.h>
34*4882a593Smuzhiyun #include <bcmutils.h>
35*4882a593Smuzhiyun #include <dhd_dbg_ring.h>
36*4882a593Smuzhiyun 
37*4882a593Smuzhiyun enum {
38*4882a593Smuzhiyun 	DEBUG_RING_ID_INVALID	= 0,
39*4882a593Smuzhiyun 	FW_VERBOSE_RING_ID,
40*4882a593Smuzhiyun 	DHD_EVENT_RING_ID,
41*4882a593Smuzhiyun 	/* add new id here */
42*4882a593Smuzhiyun 	DEBUG_RING_ID_MAX
43*4882a593Smuzhiyun };
44*4882a593Smuzhiyun 
45*4882a593Smuzhiyun enum {
46*4882a593Smuzhiyun 	/* Feature set */
47*4882a593Smuzhiyun 	DBG_MEMORY_DUMP_SUPPORTED = (1 << (0)), /* Memory dump of FW */
48*4882a593Smuzhiyun 	DBG_PER_PACKET_TX_RX_STATUS_SUPPORTED = (1 << (1)), /* PKT Status */
49*4882a593Smuzhiyun 	DBG_CONNECT_EVENT_SUPPORTED = (1 << (2)), /* Connectivity Event */
50*4882a593Smuzhiyun 	DBG_POWER_EVENT_SUPOORTED = (1 << (3)), /* POWER of Driver */
51*4882a593Smuzhiyun 	DBG_WAKE_LOCK_SUPPORTED = (1 << (4)), /* WAKE LOCK of Driver */
52*4882a593Smuzhiyun 	DBG_VERBOSE_LOG_SUPPORTED = (1 << (5)), /* verbose log of FW */
53*4882a593Smuzhiyun 	DBG_HEALTH_CHECK_SUPPORTED = (1 << (6)), /* monitor the health of FW */
54*4882a593Smuzhiyun 	DBG_DRIVER_DUMP_SUPPORTED = (1 << (7)), /* dumps driver state */
55*4882a593Smuzhiyun 	DBG_PACKET_FATE_SUPPORTED = (1 << (8)), /* tracks connection packets' fate */
56*4882a593Smuzhiyun 	DBG_NAN_EVENT_SUPPORTED = (1 << (9)), /* NAN Events */
57*4882a593Smuzhiyun };
58*4882a593Smuzhiyun 
59*4882a593Smuzhiyun enum {
60*4882a593Smuzhiyun 	/* set for binary entries */
61*4882a593Smuzhiyun 	DBG_RING_ENTRY_FLAGS_HAS_BINARY = (1 << (0)),
62*4882a593Smuzhiyun 	/* set if 64 bits timestamp is present */
63*4882a593Smuzhiyun 	DBG_RING_ENTRY_FLAGS_HAS_TIMESTAMP = (1 << (1))
64*4882a593Smuzhiyun };
65*4882a593Smuzhiyun 
66*4882a593Smuzhiyun /* firmware verbose ring, ring id 1 */
67*4882a593Smuzhiyun #define FW_VERBOSE_RING_NAME		"fw_verbose"
68*4882a593Smuzhiyun #define FW_VERBOSE_RING_SIZE		(256 * 1024)
69*4882a593Smuzhiyun /* firmware event ring, ring id 2 */
70*4882a593Smuzhiyun #define FW_EVENT_RING_NAME		"fw_event"
71*4882a593Smuzhiyun #define FW_EVENT_RING_SIZE		(64 * 1024)
72*4882a593Smuzhiyun /* DHD connection event ring, ring id 3 */
73*4882a593Smuzhiyun #define DHD_EVENT_RING_NAME		"dhd_event"
74*4882a593Smuzhiyun #define DHD_EVENT_RING_SIZE		(64 * 1024)
75*4882a593Smuzhiyun /* NAN event ring, ring id 4 */
76*4882a593Smuzhiyun #define NAN_EVENT_RING_NAME		"nan_event"
77*4882a593Smuzhiyun #define NAN_EVENT_RING_SIZE		(64 * 1024)
78*4882a593Smuzhiyun 
79*4882a593Smuzhiyun #define TLV_LOG_SIZE(tlv) ((tlv) ? (sizeof(tlv_log) + (tlv)->len) : 0)
80*4882a593Smuzhiyun 
81*4882a593Smuzhiyun #define TLV_LOG_NEXT(tlv) \
82*4882a593Smuzhiyun 	((tlv) ? ((tlv_log *)((uint8 *)tlv + TLV_LOG_SIZE(tlv))) : 0)
83*4882a593Smuzhiyun 
84*4882a593Smuzhiyun #define VALID_RING(id)	\
85*4882a593Smuzhiyun 	((id > DEBUG_RING_ID_INVALID) && (id < DEBUG_RING_ID_MAX))
86*4882a593Smuzhiyun 
87*4882a593Smuzhiyun #ifdef DEBUGABILITY
88*4882a593Smuzhiyun #define DBG_RING_ACTIVE(dhdp, ring_id) \
89*4882a593Smuzhiyun 	((dhdp)->dbg->dbg_rings[(ring_id)].state == RING_ACTIVE)
90*4882a593Smuzhiyun #else
91*4882a593Smuzhiyun #define DBG_RING_ACTIVE(dhdp, ring_id) 0
92*4882a593Smuzhiyun #endif /* DEBUGABILITY */
93*4882a593Smuzhiyun 
94*4882a593Smuzhiyun enum {
95*4882a593Smuzhiyun 	/* driver receive association command from kernel */
96*4882a593Smuzhiyun 	WIFI_EVENT_ASSOCIATION_REQUESTED	= 0,
97*4882a593Smuzhiyun 	WIFI_EVENT_AUTH_COMPLETE,
98*4882a593Smuzhiyun 	WIFI_EVENT_ASSOC_COMPLETE,
99*4882a593Smuzhiyun 	/* received firmware event indicating auth frames are sent */
100*4882a593Smuzhiyun 	WIFI_EVENT_FW_AUTH_STARTED,
101*4882a593Smuzhiyun 	/* received firmware event indicating assoc frames are sent */
102*4882a593Smuzhiyun 	WIFI_EVENT_FW_ASSOC_STARTED,
103*4882a593Smuzhiyun 	/* received firmware event indicating reassoc frames are sent */
104*4882a593Smuzhiyun 	WIFI_EVENT_FW_RE_ASSOC_STARTED,
105*4882a593Smuzhiyun 	WIFI_EVENT_DRIVER_SCAN_REQUESTED,
106*4882a593Smuzhiyun 	WIFI_EVENT_DRIVER_SCAN_RESULT_FOUND,
107*4882a593Smuzhiyun 	WIFI_EVENT_DRIVER_SCAN_COMPLETE,
108*4882a593Smuzhiyun 	WIFI_EVENT_G_SCAN_STARTED,
109*4882a593Smuzhiyun 	WIFI_EVENT_G_SCAN_COMPLETE,
110*4882a593Smuzhiyun 	WIFI_EVENT_DISASSOCIATION_REQUESTED,
111*4882a593Smuzhiyun 	WIFI_EVENT_RE_ASSOCIATION_REQUESTED,
112*4882a593Smuzhiyun 	WIFI_EVENT_ROAM_REQUESTED,
113*4882a593Smuzhiyun 	/* received beacon from AP (event enabled only in verbose mode) */
114*4882a593Smuzhiyun 	WIFI_EVENT_BEACON_RECEIVED,
115*4882a593Smuzhiyun 	/* firmware has triggered a roam scan (not g-scan) */
116*4882a593Smuzhiyun 	WIFI_EVENT_ROAM_SCAN_STARTED,
117*4882a593Smuzhiyun 	/* firmware has completed a roam scan (not g-scan) */
118*4882a593Smuzhiyun 	WIFI_EVENT_ROAM_SCAN_COMPLETE,
119*4882a593Smuzhiyun 	/* firmware has started searching for roam candidates (with reason =xx) */
120*4882a593Smuzhiyun 	WIFI_EVENT_ROAM_SEARCH_STARTED,
121*4882a593Smuzhiyun 	/* firmware has stopped searching for roam candidates (with reason =xx) */
122*4882a593Smuzhiyun 	WIFI_EVENT_ROAM_SEARCH_STOPPED,
123*4882a593Smuzhiyun 	WIFI_EVENT_UNUSED_0,
124*4882a593Smuzhiyun 	/* received channel switch anouncement from AP */
125*4882a593Smuzhiyun 	WIFI_EVENT_CHANNEL_SWITCH_ANOUNCEMENT,
126*4882a593Smuzhiyun 	/* fw start transmit eapol frame, with EAPOL index 1-4 */
127*4882a593Smuzhiyun 	WIFI_EVENT_FW_EAPOL_FRAME_TRANSMIT_START,
128*4882a593Smuzhiyun 	/* fw gives up eapol frame, with rate, success/failure and number retries */
129*4882a593Smuzhiyun 	WIFI_EVENT_FW_EAPOL_FRAME_TRANSMIT_STOP,
130*4882a593Smuzhiyun 	/* kernel queue EAPOL for transmission in driver with EAPOL index 1-4 */
131*4882a593Smuzhiyun 	WIFI_EVENT_DRIVER_EAPOL_FRAME_TRANSMIT_REQUESTED,
132*4882a593Smuzhiyun 	/* with rate, regardless of the fact that EAPOL frame is accepted or
133*4882a593Smuzhiyun 	 * rejected by firmware
134*4882a593Smuzhiyun 	 */
135*4882a593Smuzhiyun 	WIFI_EVENT_FW_EAPOL_FRAME_RECEIVED,
136*4882a593Smuzhiyun 	WIFI_EVENT_UNUSED_1,
137*4882a593Smuzhiyun 	/* with rate, and eapol index, driver has received */
138*4882a593Smuzhiyun 	/* EAPOL frame and will queue it up to wpa_supplicant */
139*4882a593Smuzhiyun 	WIFI_EVENT_DRIVER_EAPOL_FRAME_RECEIVED,
140*4882a593Smuzhiyun 	/* with success/failure, parameters */
141*4882a593Smuzhiyun 	WIFI_EVENT_BLOCK_ACK_NEGOTIATION_COMPLETE,
142*4882a593Smuzhiyun 	WIFI_EVENT_BT_COEX_BT_SCO_START,
143*4882a593Smuzhiyun 	WIFI_EVENT_BT_COEX_BT_SCO_STOP,
144*4882a593Smuzhiyun 	/* for paging/scan etc..., when BT starts transmiting twice per BT slot */
145*4882a593Smuzhiyun 	WIFI_EVENT_BT_COEX_BT_SCAN_START,
146*4882a593Smuzhiyun 	WIFI_EVENT_BT_COEX_BT_SCAN_STOP,
147*4882a593Smuzhiyun 	WIFI_EVENT_BT_COEX_BT_HID_START,
148*4882a593Smuzhiyun 	WIFI_EVENT_BT_COEX_BT_HID_STOP,
149*4882a593Smuzhiyun 	/* firmware sends auth frame in roaming to next candidate */
150*4882a593Smuzhiyun 	WIFI_EVENT_ROAM_AUTH_STARTED,
151*4882a593Smuzhiyun 	/* firmware receive auth confirm from ap */
152*4882a593Smuzhiyun 	WIFI_EVENT_ROAM_AUTH_COMPLETE,
153*4882a593Smuzhiyun 	/* firmware sends assoc/reassoc frame in */
154*4882a593Smuzhiyun 	WIFI_EVENT_ROAM_ASSOC_STARTED,
155*4882a593Smuzhiyun 	/* firmware receive assoc/reassoc confirm from ap */
156*4882a593Smuzhiyun 	WIFI_EVENT_ROAM_ASSOC_COMPLETE,
157*4882a593Smuzhiyun 	/* firmware sends stop G_SCAN */
158*4882a593Smuzhiyun 	WIFI_EVENT_G_SCAN_STOP,
159*4882a593Smuzhiyun 	/* firmware indicates G_SCAN scan cycle started */
160*4882a593Smuzhiyun 	WIFI_EVENT_G_SCAN_CYCLE_STARTED,
161*4882a593Smuzhiyun 	/* firmware indicates G_SCAN scan cycle completed */
162*4882a593Smuzhiyun 	WIFI_EVENT_G_SCAN_CYCLE_COMPLETED,
163*4882a593Smuzhiyun 	/* firmware indicates G_SCAN scan start for a particular bucket */
164*4882a593Smuzhiyun 	WIFI_EVENT_G_SCAN_BUCKET_STARTED,
165*4882a593Smuzhiyun 	/* firmware indicates G_SCAN scan completed for particular bucket */
166*4882a593Smuzhiyun 	WIFI_EVENT_G_SCAN_BUCKET_COMPLETED,
167*4882a593Smuzhiyun 	/* Event received from firmware about G_SCAN scan results being available */
168*4882a593Smuzhiyun 	WIFI_EVENT_G_SCAN_RESULTS_AVAILABLE,
169*4882a593Smuzhiyun 	/* Event received from firmware with G_SCAN capabilities */
170*4882a593Smuzhiyun 	WIFI_EVENT_G_SCAN_CAPABILITIES,
171*4882a593Smuzhiyun 	/* Event received from firmware when eligible candidate is found */
172*4882a593Smuzhiyun 	WIFI_EVENT_ROAM_CANDIDATE_FOUND,
173*4882a593Smuzhiyun 	/* Event received from firmware when roam scan configuration gets enabled or disabled */
174*4882a593Smuzhiyun 	WIFI_EVENT_ROAM_SCAN_CONFIG,
175*4882a593Smuzhiyun 	/* firmware/driver timed out authentication */
176*4882a593Smuzhiyun 	WIFI_EVENT_AUTH_TIMEOUT,
177*4882a593Smuzhiyun 	/* firmware/driver timed out association */
178*4882a593Smuzhiyun 	WIFI_EVENT_ASSOC_TIMEOUT,
179*4882a593Smuzhiyun 	/* firmware/driver encountered allocation failure */
180*4882a593Smuzhiyun 	WIFI_EVENT_MEM_ALLOC_FAILURE,
181*4882a593Smuzhiyun 	/* driver added a PNO network in firmware */
182*4882a593Smuzhiyun 	WIFI_EVENT_DRIVER_PNO_ADD,
183*4882a593Smuzhiyun 	/* driver removed a PNO network in firmware */
184*4882a593Smuzhiyun 	WIFI_EVENT_DRIVER_PNO_REMOVE,
185*4882a593Smuzhiyun 	/* driver received PNO networks found indication from firmware */
186*4882a593Smuzhiyun 	WIFI_EVENT_DRIVER_PNO_NETWORK_FOUND,
187*4882a593Smuzhiyun 	/* driver triggered a scan for PNO networks */
188*4882a593Smuzhiyun 	WIFI_EVENT_DRIVER_PNO_SCAN_REQUESTED,
189*4882a593Smuzhiyun 	/* driver received scan results of PNO networks */
190*4882a593Smuzhiyun 	WIFI_EVENT_DRIVER_PNO_SCAN_RESULT_FOUND,
191*4882a593Smuzhiyun 	/* driver updated scan results from PNO candidates to cfg */
192*4882a593Smuzhiyun 	WIFI_EVENT_DRIVER_PNO_SCAN_COMPLETE
193*4882a593Smuzhiyun };
194*4882a593Smuzhiyun 
195*4882a593Smuzhiyun enum {
196*4882a593Smuzhiyun 	WIFI_TAG_VENDOR_SPECIFIC = 0, /* take a byte stream as parameter */
197*4882a593Smuzhiyun 	WIFI_TAG_BSSID, /* takes a 6 bytes MAC address as parameter */
198*4882a593Smuzhiyun 	WIFI_TAG_ADDR, /* takes a 6 bytes MAC address as parameter */
199*4882a593Smuzhiyun 	WIFI_TAG_SSID, /* takes a 32 bytes SSID address as parameter */
200*4882a593Smuzhiyun 	WIFI_TAG_STATUS, /* takes an integer as parameter */
201*4882a593Smuzhiyun 	WIFI_TAG_CHANNEL_SPEC, /* takes one or more wifi_channel_spec as parameter */
202*4882a593Smuzhiyun 	WIFI_TAG_WAKE_LOCK_EVENT, /* takes a wake_lock_event struct as parameter */
203*4882a593Smuzhiyun 	WIFI_TAG_ADDR1, /* takes a 6 bytes MAC address as parameter */
204*4882a593Smuzhiyun 	WIFI_TAG_ADDR2, /* takes a 6 bytes MAC address as parameter */
205*4882a593Smuzhiyun 	WIFI_TAG_ADDR3, /* takes a 6 bytes MAC address as parameter */
206*4882a593Smuzhiyun 	WIFI_TAG_ADDR4, /* takes a 6 bytes MAC address as parameter */
207*4882a593Smuzhiyun 	WIFI_TAG_TSF, /* take a 64 bits TSF value as parameter */
208*4882a593Smuzhiyun 	WIFI_TAG_IE,
209*4882a593Smuzhiyun 	/* take one or more specific 802.11 IEs parameter, IEs are in turn
210*4882a593Smuzhiyun 	 * indicated in TLV format as per 802.11 spec
211*4882a593Smuzhiyun 	 */
212*4882a593Smuzhiyun 	WIFI_TAG_INTERFACE,	/* take interface name as parameter */
213*4882a593Smuzhiyun 	WIFI_TAG_REASON_CODE,	/* take a reason code as per 802.11 as parameter */
214*4882a593Smuzhiyun 	WIFI_TAG_RATE_MBPS,	/* take a wifi rate in 0.5 mbps */
215*4882a593Smuzhiyun 	WIFI_TAG_REQUEST_ID,	/* take an integer as parameter */
216*4882a593Smuzhiyun 	WIFI_TAG_BUCKET_ID,	/* take an integer as parameter */
217*4882a593Smuzhiyun 	WIFI_TAG_GSCAN_PARAMS,	/* takes a wifi_scan_cmd_params struct as parameter */
218*4882a593Smuzhiyun 	WIFI_TAG_GSCAN_CAPABILITIES, /* takes a wifi_gscan_capabilities struct as parameter */
219*4882a593Smuzhiyun 	WIFI_TAG_SCAN_ID,	/* take an integer as parameter */
220*4882a593Smuzhiyun 	WIFI_TAG_RSSI,		/* takes s16 as parameter */
221*4882a593Smuzhiyun 	WIFI_TAG_CHANNEL,	/* takes u16 as parameter */
222*4882a593Smuzhiyun 	WIFI_TAG_LINK_ID,	/* take an integer as parameter */
223*4882a593Smuzhiyun 	WIFI_TAG_LINK_ROLE,	/* take an integer as parameter */
224*4882a593Smuzhiyun 	WIFI_TAG_LINK_STATE,	/* take an integer as parameter */
225*4882a593Smuzhiyun 	WIFI_TAG_LINK_TYPE,	/* take an integer as parameter */
226*4882a593Smuzhiyun 	WIFI_TAG_TSCO,		/* take an integer as parameter */
227*4882a593Smuzhiyun 	WIFI_TAG_RSCO,		/* take an integer as parameter */
228*4882a593Smuzhiyun 	WIFI_TAG_EAPOL_MESSAGE_TYPE /* take an integer as parameter */
229*4882a593Smuzhiyun };
230*4882a593Smuzhiyun 
231*4882a593Smuzhiyun /* NAN  events */
232*4882a593Smuzhiyun typedef enum {
233*4882a593Smuzhiyun 	NAN_EVENT_INVALID = 0,
234*4882a593Smuzhiyun 	NAN_EVENT_CLUSTER_STARTED = 1,
235*4882a593Smuzhiyun 	NAN_EVENT_CLUSTER_JOINED = 2,
236*4882a593Smuzhiyun 	NAN_EVENT_CLUSTER_MERGED = 3,
237*4882a593Smuzhiyun 	NAN_EVENT_ROLE_CHANGED = 4,
238*4882a593Smuzhiyun 	NAN_EVENT_SCAN_COMPLETE = 5,
239*4882a593Smuzhiyun 	NAN_EVENT_STATUS_CHNG  = 6,
240*4882a593Smuzhiyun 	/* ADD new events before this line */
241*4882a593Smuzhiyun 	NAN_EVENT_MAX
242*4882a593Smuzhiyun } nan_event_id_t;
243*4882a593Smuzhiyun 
244*4882a593Smuzhiyun typedef struct {
245*4882a593Smuzhiyun     uint16 tag;
246*4882a593Smuzhiyun     uint16 len; /* length of value */
247*4882a593Smuzhiyun     uint8 value[0];
248*4882a593Smuzhiyun } tlv_log;
249*4882a593Smuzhiyun 
250*4882a593Smuzhiyun typedef struct per_packet_status_entry {
251*4882a593Smuzhiyun     uint8 flags;
252*4882a593Smuzhiyun     uint8 tid; /* transmit or received tid */
253*4882a593Smuzhiyun     uint16 MCS; /* modulation and bandwidth */
254*4882a593Smuzhiyun 	/*
255*4882a593Smuzhiyun 	* TX: RSSI of ACK for that packet
256*4882a593Smuzhiyun 	* RX: RSSI of packet
257*4882a593Smuzhiyun 	*/
258*4882a593Smuzhiyun     uint8 rssi;
259*4882a593Smuzhiyun     uint8 num_retries; /* number of attempted retries */
260*4882a593Smuzhiyun     uint16 last_transmit_rate; /* last transmit rate in .5 mbps */
261*4882a593Smuzhiyun 	 /* transmit/reeive sequence for that MPDU packet */
262*4882a593Smuzhiyun     uint16 link_layer_transmit_sequence;
263*4882a593Smuzhiyun 	/*
264*4882a593Smuzhiyun 	* TX: firmware timestamp (us) when packet is queued within firmware buffer
265*4882a593Smuzhiyun 	* for SDIO/HSIC or into PCIe buffer
266*4882a593Smuzhiyun 	* RX : firmware receive timestamp
267*4882a593Smuzhiyun 	*/
268*4882a593Smuzhiyun     uint64 firmware_entry_timestamp;
269*4882a593Smuzhiyun 	/*
270*4882a593Smuzhiyun 	* firmware timestamp (us) when packet start contending for the
271*4882a593Smuzhiyun 	* medium for the first time, at head of its AC queue,
272*4882a593Smuzhiyun 	* or as part of an MPDU or A-MPDU. This timestamp is not updated
273*4882a593Smuzhiyun 	* for each retry, only the first transmit attempt.
274*4882a593Smuzhiyun 	*/
275*4882a593Smuzhiyun     uint64 start_contention_timestamp;
276*4882a593Smuzhiyun 	/*
277*4882a593Smuzhiyun 	* fimrware timestamp (us) when packet is successfully transmitted
278*4882a593Smuzhiyun 	* or aborted because it has exhausted its maximum number of retries
279*4882a593Smuzhiyun 	*/
280*4882a593Smuzhiyun 	uint64 transmit_success_timestamp;
281*4882a593Smuzhiyun 	/*
282*4882a593Smuzhiyun 	* packet data. The length of packet data is determined by the entry_size field of
283*4882a593Smuzhiyun 	* the wifi_ring_buffer_entry structure. It is expected that first bytes of the
284*4882a593Smuzhiyun 	* packet, or packet headers only (up to TCP or RTP/UDP headers) will be copied into the ring
285*4882a593Smuzhiyun 	*/
286*4882a593Smuzhiyun     uint8 *data;
287*4882a593Smuzhiyun } per_packet_status_entry_t;
288*4882a593Smuzhiyun 
289*4882a593Smuzhiyun #define PACKED_STRUCT __attribute__ ((packed))
290*4882a593Smuzhiyun 
291*4882a593Smuzhiyun typedef struct log_conn_event {
292*4882a593Smuzhiyun     uint16 event;
293*4882a593Smuzhiyun     tlv_log *tlvs;
294*4882a593Smuzhiyun 	/*
295*4882a593Smuzhiyun 	* separate parameter structure per event to be provided and optional data
296*4882a593Smuzhiyun 	* the event_data is expected to include an official android part, with some
297*4882a593Smuzhiyun 	* parameter as transmit rate, num retries, num scan result found etc...
298*4882a593Smuzhiyun 	* as well, event_data can include a vendor proprietary part which is
299*4882a593Smuzhiyun 	* understood by the developer only.
300*4882a593Smuzhiyun 	*/
301*4882a593Smuzhiyun } PACKED_STRUCT log_conn_event_t;
302*4882a593Smuzhiyun 
303*4882a593Smuzhiyun /*
304*4882a593Smuzhiyun  * Ring buffer name for power events ring. note that power event are extremely frequents
305*4882a593Smuzhiyun  * and thus should be stored in their own ring/file so as not to clobber connectivity events
306*4882a593Smuzhiyun  */
307*4882a593Smuzhiyun 
308*4882a593Smuzhiyun typedef struct wake_lock_event {
309*4882a593Smuzhiyun     uint32 status; /* 0 taken, 1 released */
310*4882a593Smuzhiyun     uint32 reason; /* reason why this wake lock is taken */
311*4882a593Smuzhiyun     char *name; /* null terminated */
312*4882a593Smuzhiyun } wake_lock_event_t;
313*4882a593Smuzhiyun 
314*4882a593Smuzhiyun typedef struct wifi_power_event {
315*4882a593Smuzhiyun     uint16 event;
316*4882a593Smuzhiyun     tlv_log *tlvs;
317*4882a593Smuzhiyun } wifi_power_event_t;
318*4882a593Smuzhiyun 
319*4882a593Smuzhiyun #define NAN_EVENT_VERSION 1
320*4882a593Smuzhiyun typedef struct log_nan_event {
321*4882a593Smuzhiyun     uint8 version;
322*4882a593Smuzhiyun     uint8 pad;
323*4882a593Smuzhiyun     uint16 event;
324*4882a593Smuzhiyun     tlv_log *tlvs;
325*4882a593Smuzhiyun } log_nan_event_t;
326*4882a593Smuzhiyun 
327*4882a593Smuzhiyun /* entry type */
328*4882a593Smuzhiyun enum {
329*4882a593Smuzhiyun 	DBG_RING_ENTRY_EVENT_TYPE = 1,
330*4882a593Smuzhiyun 	DBG_RING_ENTRY_PKT_TYPE,
331*4882a593Smuzhiyun 	DBG_RING_ENTRY_WAKE_LOCK_EVENT_TYPE,
332*4882a593Smuzhiyun 	DBG_RING_ENTRY_POWER_EVENT_TYPE,
333*4882a593Smuzhiyun 	DBG_RING_ENTRY_DATA_TYPE,
334*4882a593Smuzhiyun 	DBG_RING_ENTRY_NAN_EVENT_TYPE
335*4882a593Smuzhiyun };
336*4882a593Smuzhiyun 
337*4882a593Smuzhiyun struct log_level_table {
338*4882a593Smuzhiyun 	int log_level;
339*4882a593Smuzhiyun 	uint16 tag;
340*4882a593Smuzhiyun 	char *desc;
341*4882a593Smuzhiyun };
342*4882a593Smuzhiyun 
343*4882a593Smuzhiyun #ifdef OEM_ANDROID
344*4882a593Smuzhiyun /*
345*4882a593Smuzhiyun  * Assuming that the Ring lock is mutex, bailing out if the
346*4882a593Smuzhiyun  * callers are from atomic context. On a long term, one has to
347*4882a593Smuzhiyun  * schedule a job to execute in sleepable context so that
348*4882a593Smuzhiyun  * contents are pushed to the ring.
349*4882a593Smuzhiyun  */
350*4882a593Smuzhiyun #define DBG_EVENT_LOG(dhdp, connect_state)					\
351*4882a593Smuzhiyun {										\
352*4882a593Smuzhiyun 	do {									\
353*4882a593Smuzhiyun 		uint16 state = connect_state;					\
354*4882a593Smuzhiyun 		if (CAN_SLEEP() && DBG_RING_ACTIVE(dhdp, DHD_EVENT_RING_ID))			\
355*4882a593Smuzhiyun 			dhd_os_push_push_ring_data(dhdp, DHD_EVENT_RING_ID,	\
356*4882a593Smuzhiyun 				&state, sizeof(state));				\
357*4882a593Smuzhiyun 	} while (0);								\
358*4882a593Smuzhiyun }
359*4882a593Smuzhiyun #else
360*4882a593Smuzhiyun #define DBG_EVENT_LOG(dhd, connect_state)
361*4882a593Smuzhiyun #endif /* !OEM_ANDROID */
362*4882a593Smuzhiyun 
363*4882a593Smuzhiyun #define MD5_PREFIX_LEN				4
364*4882a593Smuzhiyun #define MAX_FATE_LOG_LEN			32
365*4882a593Smuzhiyun #define MAX_FRAME_LEN_ETHERNET		1518
366*4882a593Smuzhiyun #define MAX_FRAME_LEN_80211_MGMT	2352 /* 802.11-2012 Fig. 8-34 */
367*4882a593Smuzhiyun 
368*4882a593Smuzhiyun typedef enum {
369*4882a593Smuzhiyun 	/* Sent over air and ACKed. */
370*4882a593Smuzhiyun 	TX_PKT_FATE_ACKED,
371*4882a593Smuzhiyun 
372*4882a593Smuzhiyun 	/* Sent over air but not ACKed. (Normal for broadcast/multicast.) */
373*4882a593Smuzhiyun 	TX_PKT_FATE_SENT,
374*4882a593Smuzhiyun 
375*4882a593Smuzhiyun 	/* Queued within firmware, but not yet sent over air. */
376*4882a593Smuzhiyun 	TX_PKT_FATE_FW_QUEUED,
377*4882a593Smuzhiyun 
378*4882a593Smuzhiyun 	/*
379*4882a593Smuzhiyun 	 * Dropped by firmware as invalid. E.g. bad source address,
380*4882a593Smuzhiyun 	 * bad checksum, or invalid for current state.
381*4882a593Smuzhiyun 	 */
382*4882a593Smuzhiyun 	TX_PKT_FATE_FW_DROP_INVALID,
383*4882a593Smuzhiyun 
384*4882a593Smuzhiyun 	/* Dropped by firmware due to lifetime expiration. */
385*4882a593Smuzhiyun 	TX_PKT_FATE_FW_DROP_EXPTIME,
386*4882a593Smuzhiyun 
387*4882a593Smuzhiyun 	/*
388*4882a593Smuzhiyun 	 * Dropped by firmware for any other reason. Includes
389*4882a593Smuzhiyun 	 * frames that were sent by driver to firmware, but
390*4882a593Smuzhiyun 	 * unaccounted for by firmware.
391*4882a593Smuzhiyun 	 */
392*4882a593Smuzhiyun 	TX_PKT_FATE_FW_DROP_OTHER,
393*4882a593Smuzhiyun 
394*4882a593Smuzhiyun 	/* Queued within driver, not yet sent to firmware. */
395*4882a593Smuzhiyun 	TX_PKT_FATE_DRV_QUEUED,
396*4882a593Smuzhiyun 
397*4882a593Smuzhiyun 	/*
398*4882a593Smuzhiyun 	 * Dropped by driver as invalid. E.g. bad source address,
399*4882a593Smuzhiyun 	 * or invalid for current state.
400*4882a593Smuzhiyun 	 */
401*4882a593Smuzhiyun 	TX_PKT_FATE_DRV_DROP_INVALID,
402*4882a593Smuzhiyun 
403*4882a593Smuzhiyun 	/* Dropped by driver due to lack of buffer space. */
404*4882a593Smuzhiyun 	TX_PKT_FATE_DRV_DROP_NOBUFS,
405*4882a593Smuzhiyun 
406*4882a593Smuzhiyun 	/*  Dropped by driver for any other reason. */
407*4882a593Smuzhiyun 	TX_PKT_FATE_DRV_DROP_OTHER,
408*4882a593Smuzhiyun 
409*4882a593Smuzhiyun 	/* Packet free by firmware. */
410*4882a593Smuzhiyun 	TX_PKT_FATE_FW_PKT_FREE,
411*4882a593Smuzhiyun 
412*4882a593Smuzhiyun 	} wifi_tx_packet_fate;
413*4882a593Smuzhiyun 
414*4882a593Smuzhiyun typedef enum {
415*4882a593Smuzhiyun 	/* Valid and delivered to network stack (e.g., netif_rx()). */
416*4882a593Smuzhiyun 	RX_PKT_FATE_SUCCESS,
417*4882a593Smuzhiyun 
418*4882a593Smuzhiyun 	/* Queued within firmware, but not yet sent to driver. */
419*4882a593Smuzhiyun 	RX_PKT_FATE_FW_QUEUED,
420*4882a593Smuzhiyun 
421*4882a593Smuzhiyun 	/* Dropped by firmware due to host-programmable filters. */
422*4882a593Smuzhiyun 	RX_PKT_FATE_FW_DROP_FILTER,
423*4882a593Smuzhiyun 
424*4882a593Smuzhiyun 	/*
425*4882a593Smuzhiyun 	 * Dropped by firmware as invalid. E.g. bad checksum,
426*4882a593Smuzhiyun 	 * decrypt failed, or invalid for current state.
427*4882a593Smuzhiyun 	 */
428*4882a593Smuzhiyun 	RX_PKT_FATE_FW_DROP_INVALID,
429*4882a593Smuzhiyun 
430*4882a593Smuzhiyun 	/* Dropped by firmware due to lack of buffer space. */
431*4882a593Smuzhiyun 	RX_PKT_FATE_FW_DROP_NOBUFS,
432*4882a593Smuzhiyun 
433*4882a593Smuzhiyun 	/* Dropped by firmware for any other reason. */
434*4882a593Smuzhiyun 	RX_PKT_FATE_FW_DROP_OTHER,
435*4882a593Smuzhiyun 
436*4882a593Smuzhiyun 	/* Queued within driver, not yet delivered to network stack. */
437*4882a593Smuzhiyun 	RX_PKT_FATE_DRV_QUEUED,
438*4882a593Smuzhiyun 
439*4882a593Smuzhiyun 	/* Dropped by driver due to filter rules. */
440*4882a593Smuzhiyun 	RX_PKT_FATE_DRV_DROP_FILTER,
441*4882a593Smuzhiyun 
442*4882a593Smuzhiyun 	/* Dropped by driver as invalid. E.g. not permitted in current state. */
443*4882a593Smuzhiyun 	RX_PKT_FATE_DRV_DROP_INVALID,
444*4882a593Smuzhiyun 
445*4882a593Smuzhiyun 	/* Dropped by driver due to lack of buffer space. */
446*4882a593Smuzhiyun 	RX_PKT_FATE_DRV_DROP_NOBUFS,
447*4882a593Smuzhiyun 
448*4882a593Smuzhiyun 	/* Dropped by driver for any other reason. */
449*4882a593Smuzhiyun 	RX_PKT_FATE_DRV_DROP_OTHER,
450*4882a593Smuzhiyun 
451*4882a593Smuzhiyun 	} wifi_rx_packet_fate;
452*4882a593Smuzhiyun 
453*4882a593Smuzhiyun typedef enum {
454*4882a593Smuzhiyun 	FRAME_TYPE_UNKNOWN,
455*4882a593Smuzhiyun 	FRAME_TYPE_ETHERNET_II,
456*4882a593Smuzhiyun 	FRAME_TYPE_80211_MGMT,
457*4882a593Smuzhiyun 	} frame_type;
458*4882a593Smuzhiyun 
459*4882a593Smuzhiyun typedef struct wifi_frame_info {
460*4882a593Smuzhiyun 	/*
461*4882a593Smuzhiyun 	 * The type of MAC-layer frame that this frame_info holds.
462*4882a593Smuzhiyun 	 * - For data frames, use FRAME_TYPE_ETHERNET_II.
463*4882a593Smuzhiyun 	 * - For management frames, use FRAME_TYPE_80211_MGMT.
464*4882a593Smuzhiyun 	 * - If the type of the frame is unknown, use FRAME_TYPE_UNKNOWN.
465*4882a593Smuzhiyun 	 */
466*4882a593Smuzhiyun 	frame_type payload_type;
467*4882a593Smuzhiyun 
468*4882a593Smuzhiyun 	/*
469*4882a593Smuzhiyun 	 * The number of bytes included in |frame_content|. If the frame
470*4882a593Smuzhiyun 	 * contents are missing (e.g. RX frame dropped in firmware),
471*4882a593Smuzhiyun 	 * |frame_len| should be set to 0.
472*4882a593Smuzhiyun 	 */
473*4882a593Smuzhiyun 	size_t frame_len;
474*4882a593Smuzhiyun 
475*4882a593Smuzhiyun 	/*
476*4882a593Smuzhiyun 	 * Host clock when this frame was received by the driver (either
477*4882a593Smuzhiyun 	 *	outbound from the host network stack, or inbound from the
478*4882a593Smuzhiyun 	 *	firmware).
479*4882a593Smuzhiyun 	 *	- The timestamp should be taken from a clock which includes time
480*4882a593Smuzhiyun 	 *	  the host spent suspended (e.g. ktime_get_boottime()).
481*4882a593Smuzhiyun 	 *	- If no host timestamp is available (e.g. RX frame was dropped in
482*4882a593Smuzhiyun 	 *	  firmware), this field should be set to 0.
483*4882a593Smuzhiyun 	 */
484*4882a593Smuzhiyun 	uint32 driver_timestamp_usec;
485*4882a593Smuzhiyun 
486*4882a593Smuzhiyun 	/*
487*4882a593Smuzhiyun 	 * Firmware clock when this frame was received by the firmware
488*4882a593Smuzhiyun 	 *	(either outbound from the host, or inbound from a remote
489*4882a593Smuzhiyun 	 *	station).
490*4882a593Smuzhiyun 	 *	- The timestamp should be taken from a clock which includes time
491*4882a593Smuzhiyun 	 *	  firmware spent suspended (if applicable).
492*4882a593Smuzhiyun 	 *	- If no firmware timestamp is available (e.g. TX frame was
493*4882a593Smuzhiyun 	 *	  dropped by driver), this field should be set to 0.
494*4882a593Smuzhiyun 	 *	- Consumers of |frame_info| should _not_ assume any
495*4882a593Smuzhiyun 	 *	  synchronization between driver and firmware clocks.
496*4882a593Smuzhiyun 	 */
497*4882a593Smuzhiyun 	uint32 firmware_timestamp_usec;
498*4882a593Smuzhiyun 
499*4882a593Smuzhiyun 	/*
500*4882a593Smuzhiyun 	 * Actual frame content.
501*4882a593Smuzhiyun 	 * - Should be provided for TX frames originated by the host.
502*4882a593Smuzhiyun 	 * - Should be provided for RX frames received by the driver.
503*4882a593Smuzhiyun 	 * - Optionally provided for TX frames originated by firmware. (At
504*4882a593Smuzhiyun 	 *   discretion of HAL implementation.)
505*4882a593Smuzhiyun 	 * - Optionally provided for RX frames dropped in firmware. (At
506*4882a593Smuzhiyun 	 *   discretion of HAL implementation.)
507*4882a593Smuzhiyun 	 * - If frame content is not provided, |frame_len| should be set
508*4882a593Smuzhiyun 	 *   to 0.
509*4882a593Smuzhiyun 	 */
510*4882a593Smuzhiyun 	union {
511*4882a593Smuzhiyun 		char ethernet_ii[MAX_FRAME_LEN_ETHERNET];
512*4882a593Smuzhiyun 		char ieee_80211_mgmt[MAX_FRAME_LEN_80211_MGMT];
513*4882a593Smuzhiyun 	} frame_content;
514*4882a593Smuzhiyun } wifi_frame_info_t;
515*4882a593Smuzhiyun 
516*4882a593Smuzhiyun typedef struct wifi_tx_report {
517*4882a593Smuzhiyun 	/*
518*4882a593Smuzhiyun 	 * Prefix of MD5 hash of |frame_inf.frame_content|. If frame
519*4882a593Smuzhiyun 	 * content is not provided, prefix of MD5 hash over the same data
520*4882a593Smuzhiyun 	 * that would be in frame_content, if frame content were provided.
521*4882a593Smuzhiyun 	 */
522*4882a593Smuzhiyun 	char md5_prefix[MD5_PREFIX_LEN];
523*4882a593Smuzhiyun 	wifi_tx_packet_fate fate;
524*4882a593Smuzhiyun 	wifi_frame_info_t frame_inf;
525*4882a593Smuzhiyun } wifi_tx_report_t;
526*4882a593Smuzhiyun 
527*4882a593Smuzhiyun typedef struct wifi_rx_report {
528*4882a593Smuzhiyun 	/*
529*4882a593Smuzhiyun 	 * Prefix of MD5 hash of |frame_inf.frame_content|. If frame
530*4882a593Smuzhiyun 	 * content is not provided, prefix of MD5 hash over the same data
531*4882a593Smuzhiyun 	 * that would be in frame_content, if frame content were provided.
532*4882a593Smuzhiyun 	 */
533*4882a593Smuzhiyun 	char md5_prefix[MD5_PREFIX_LEN];
534*4882a593Smuzhiyun 	wifi_rx_packet_fate fate;
535*4882a593Smuzhiyun 	wifi_frame_info_t frame_inf;
536*4882a593Smuzhiyun } wifi_rx_report_t;
537*4882a593Smuzhiyun 
538*4882a593Smuzhiyun typedef struct compat_wifi_frame_info {
539*4882a593Smuzhiyun 	frame_type payload_type;
540*4882a593Smuzhiyun 
541*4882a593Smuzhiyun 	uint32 frame_len;
542*4882a593Smuzhiyun 
543*4882a593Smuzhiyun 	uint32 driver_timestamp_usec;
544*4882a593Smuzhiyun 
545*4882a593Smuzhiyun 	uint32 firmware_timestamp_usec;
546*4882a593Smuzhiyun 
547*4882a593Smuzhiyun 	union {
548*4882a593Smuzhiyun 		char ethernet_ii[MAX_FRAME_LEN_ETHERNET];
549*4882a593Smuzhiyun 		char ieee_80211_mgmt[MAX_FRAME_LEN_80211_MGMT];
550*4882a593Smuzhiyun 	} frame_content;
551*4882a593Smuzhiyun } compat_wifi_frame_info_t;
552*4882a593Smuzhiyun 
553*4882a593Smuzhiyun typedef struct compat_wifi_tx_report {
554*4882a593Smuzhiyun 	char md5_prefix[MD5_PREFIX_LEN];
555*4882a593Smuzhiyun 	wifi_tx_packet_fate fate;
556*4882a593Smuzhiyun 	compat_wifi_frame_info_t frame_inf;
557*4882a593Smuzhiyun } compat_wifi_tx_report_t;
558*4882a593Smuzhiyun 
559*4882a593Smuzhiyun typedef struct compat_wifi_rx_report {
560*4882a593Smuzhiyun 	char md5_prefix[MD5_PREFIX_LEN];
561*4882a593Smuzhiyun 	wifi_rx_packet_fate fate;
562*4882a593Smuzhiyun 	compat_wifi_frame_info_t frame_inf;
563*4882a593Smuzhiyun } compat_wifi_rx_report_t;
564*4882a593Smuzhiyun 
565*4882a593Smuzhiyun /*
566*4882a593Smuzhiyun  * Packet logging - internal data
567*4882a593Smuzhiyun  */
568*4882a593Smuzhiyun 
569*4882a593Smuzhiyun typedef enum dhd_dbg_pkt_mon_state {
570*4882a593Smuzhiyun 	PKT_MON_INVALID = 0,
571*4882a593Smuzhiyun 	PKT_MON_ATTACHED,
572*4882a593Smuzhiyun 	PKT_MON_STARTING,
573*4882a593Smuzhiyun 	PKT_MON_STARTED,
574*4882a593Smuzhiyun 	PKT_MON_STOPPING,
575*4882a593Smuzhiyun 	PKT_MON_STOPPED,
576*4882a593Smuzhiyun 	PKT_MON_DETACHED,
577*4882a593Smuzhiyun 	} dhd_dbg_pkt_mon_state_t;
578*4882a593Smuzhiyun 
579*4882a593Smuzhiyun typedef struct dhd_dbg_pkt_info {
580*4882a593Smuzhiyun 	frame_type payload_type;
581*4882a593Smuzhiyun 	size_t pkt_len;
582*4882a593Smuzhiyun 	uint32 driver_ts;
583*4882a593Smuzhiyun 	uint32 firmware_ts;
584*4882a593Smuzhiyun 	uint32 pkt_hash;
585*4882a593Smuzhiyun 	void *pkt;
586*4882a593Smuzhiyun } dhd_dbg_pkt_info_t;
587*4882a593Smuzhiyun 
588*4882a593Smuzhiyun typedef struct compat_dhd_dbg_pkt_info {
589*4882a593Smuzhiyun 	frame_type payload_type;
590*4882a593Smuzhiyun 	uint32 pkt_len;
591*4882a593Smuzhiyun 	uint32 driver_ts;
592*4882a593Smuzhiyun 	uint32 firmware_ts;
593*4882a593Smuzhiyun 	uint32 pkt_hash;
594*4882a593Smuzhiyun 	void *pkt;
595*4882a593Smuzhiyun } compat_dhd_dbg_pkt_info_t;
596*4882a593Smuzhiyun 
597*4882a593Smuzhiyun typedef struct dhd_dbg_tx_info
598*4882a593Smuzhiyun {
599*4882a593Smuzhiyun 	wifi_tx_packet_fate fate;
600*4882a593Smuzhiyun 	dhd_dbg_pkt_info_t info;
601*4882a593Smuzhiyun } dhd_dbg_tx_info_t;
602*4882a593Smuzhiyun 
603*4882a593Smuzhiyun typedef struct dhd_dbg_rx_info
604*4882a593Smuzhiyun {
605*4882a593Smuzhiyun 	wifi_rx_packet_fate fate;
606*4882a593Smuzhiyun 	dhd_dbg_pkt_info_t info;
607*4882a593Smuzhiyun } dhd_dbg_rx_info_t;
608*4882a593Smuzhiyun 
609*4882a593Smuzhiyun typedef struct dhd_dbg_tx_report
610*4882a593Smuzhiyun {
611*4882a593Smuzhiyun 	dhd_dbg_tx_info_t *tx_pkts;
612*4882a593Smuzhiyun 	uint16 pkt_pos;
613*4882a593Smuzhiyun 	uint16 status_pos;
614*4882a593Smuzhiyun } dhd_dbg_tx_report_t;
615*4882a593Smuzhiyun 
616*4882a593Smuzhiyun typedef struct dhd_dbg_rx_report
617*4882a593Smuzhiyun {
618*4882a593Smuzhiyun 	dhd_dbg_rx_info_t *rx_pkts;
619*4882a593Smuzhiyun 	uint16 pkt_pos;
620*4882a593Smuzhiyun } dhd_dbg_rx_report_t;
621*4882a593Smuzhiyun 
622*4882a593Smuzhiyun typedef void (*dbg_pullreq_t)(void *os_priv, const int ring_id);
623*4882a593Smuzhiyun typedef void (*dbg_urgent_noti_t) (dhd_pub_t *dhdp, const void *data, const uint32 len);
624*4882a593Smuzhiyun typedef int (*dbg_mon_tx_pkts_t) (dhd_pub_t *dhdp, void *pkt, uint32 pktid);
625*4882a593Smuzhiyun typedef int (*dbg_mon_tx_status_t) (dhd_pub_t *dhdp, void *pkt,
626*4882a593Smuzhiyun 	uint32 pktid, uint16 status);
627*4882a593Smuzhiyun typedef int (*dbg_mon_rx_pkts_t) (dhd_pub_t *dhdp, void *pkt);
628*4882a593Smuzhiyun 
629*4882a593Smuzhiyun typedef struct dhd_dbg_pkt_mon
630*4882a593Smuzhiyun {
631*4882a593Smuzhiyun 	dhd_dbg_tx_report_t *tx_report;
632*4882a593Smuzhiyun 	dhd_dbg_rx_report_t *rx_report;
633*4882a593Smuzhiyun 	dhd_dbg_pkt_mon_state_t tx_pkt_state;
634*4882a593Smuzhiyun 	dhd_dbg_pkt_mon_state_t tx_status_state;
635*4882a593Smuzhiyun 	dhd_dbg_pkt_mon_state_t rx_pkt_state;
636*4882a593Smuzhiyun 
637*4882a593Smuzhiyun 	/* call backs */
638*4882a593Smuzhiyun 	dbg_mon_tx_pkts_t tx_pkt_mon;
639*4882a593Smuzhiyun 	dbg_mon_tx_status_t tx_status_mon;
640*4882a593Smuzhiyun 	dbg_mon_rx_pkts_t rx_pkt_mon;
641*4882a593Smuzhiyun } dhd_dbg_pkt_mon_t;
642*4882a593Smuzhiyun 
643*4882a593Smuzhiyun typedef struct dhd_dbg {
644*4882a593Smuzhiyun 	dhd_dbg_ring_t dbg_rings[DEBUG_RING_ID_MAX];
645*4882a593Smuzhiyun 	void *private;          /* os private_data */
646*4882a593Smuzhiyun 	dhd_dbg_pkt_mon_t pkt_mon;
647*4882a593Smuzhiyun 	void *pkt_mon_lock; /* spin lock for packet monitoring */
648*4882a593Smuzhiyun 	dbg_pullreq_t pullreq;
649*4882a593Smuzhiyun 	dbg_urgent_noti_t urgent_notifier;
650*4882a593Smuzhiyun } dhd_dbg_t;
651*4882a593Smuzhiyun 
652*4882a593Smuzhiyun #define PKT_MON_ATTACHED(state) \
653*4882a593Smuzhiyun 		(((state) > PKT_MON_INVALID) && ((state) < PKT_MON_DETACHED))
654*4882a593Smuzhiyun #define PKT_MON_DETACHED(state) \
655*4882a593Smuzhiyun 		(((state) == PKT_MON_INVALID) || ((state) == PKT_MON_DETACHED))
656*4882a593Smuzhiyun #define PKT_MON_STARTED(state) ((state) == PKT_MON_STARTED)
657*4882a593Smuzhiyun #define PKT_MON_STOPPED(state) ((state) == PKT_MON_STOPPED)
658*4882a593Smuzhiyun #define PKT_MON_NOT_OPERATIONAL(state) \
659*4882a593Smuzhiyun 	(((state) != PKT_MON_STARTED) && ((state) != PKT_MON_STOPPED))
660*4882a593Smuzhiyun #define PKT_MON_SAFE_TO_FREE(state) \
661*4882a593Smuzhiyun 	(((state) == PKT_MON_STARTING) || ((state) == PKT_MON_STOPPED))
662*4882a593Smuzhiyun #define PKT_MON_PKT_FULL(pkt_count) ((pkt_count) >= MAX_FATE_LOG_LEN)
663*4882a593Smuzhiyun #define PKT_MON_STATUS_FULL(pkt_count, status_count) \
664*4882a593Smuzhiyun 		(((status_count) >= (pkt_count)) || ((status_count) >= MAX_FATE_LOG_LEN))
665*4882a593Smuzhiyun 
666*4882a593Smuzhiyun #ifdef DBG_PKT_MON
667*4882a593Smuzhiyun #define DHD_DBG_PKT_MON_TX(dhdp, pkt, pktid) \
668*4882a593Smuzhiyun 	do { \
669*4882a593Smuzhiyun 		if ((dhdp) && (dhdp)->dbg && (dhdp)->dbg->pkt_mon.tx_pkt_mon && (pkt)) { \
670*4882a593Smuzhiyun 			(dhdp)->dbg->pkt_mon.tx_pkt_mon((dhdp), (pkt), (pktid)); \
671*4882a593Smuzhiyun 		} \
672*4882a593Smuzhiyun 	} while (0);
673*4882a593Smuzhiyun #define DHD_DBG_PKT_MON_TX_STATUS(dhdp, pkt, pktid, status) \
674*4882a593Smuzhiyun 	do { \
675*4882a593Smuzhiyun 		if ((dhdp) && (dhdp)->dbg && (dhdp)->dbg->pkt_mon.tx_status_mon && (pkt)) { \
676*4882a593Smuzhiyun 			(dhdp)->dbg->pkt_mon.tx_status_mon((dhdp), (pkt), (pktid), (status)); \
677*4882a593Smuzhiyun 		} \
678*4882a593Smuzhiyun 	} while (0);
679*4882a593Smuzhiyun #define DHD_DBG_PKT_MON_RX(dhdp, pkt) \
680*4882a593Smuzhiyun 	do { \
681*4882a593Smuzhiyun 		if ((dhdp) && (dhdp)->dbg && (dhdp)->dbg->pkt_mon.rx_pkt_mon && (pkt)) { \
682*4882a593Smuzhiyun 			if (ntoh16((pkt)->protocol) != ETHER_TYPE_BRCM) { \
683*4882a593Smuzhiyun 				(dhdp)->dbg->pkt_mon.rx_pkt_mon((dhdp), (pkt)); \
684*4882a593Smuzhiyun 			} \
685*4882a593Smuzhiyun 		} \
686*4882a593Smuzhiyun 	} while (0);
687*4882a593Smuzhiyun 
688*4882a593Smuzhiyun #define DHD_DBG_PKT_MON_START(dhdp) \
689*4882a593Smuzhiyun 		dhd_os_dbg_start_pkt_monitor((dhdp));
690*4882a593Smuzhiyun #define DHD_DBG_PKT_MON_STOP(dhdp) \
691*4882a593Smuzhiyun 		dhd_os_dbg_stop_pkt_monitor((dhdp));
692*4882a593Smuzhiyun #else
693*4882a593Smuzhiyun #define DHD_DBG_PKT_MON_TX(dhdp, pkt, pktid)
694*4882a593Smuzhiyun #define DHD_DBG_PKT_MON_TX_STATUS(dhdp, pkt, pktid, status)
695*4882a593Smuzhiyun #define DHD_DBG_PKT_MON_RX(dhdp, pkt)
696*4882a593Smuzhiyun #define DHD_DBG_PKT_MON_START(dhdp)
697*4882a593Smuzhiyun #define DHD_DBG_PKT_MON_STOP(dhdp)
698*4882a593Smuzhiyun #endif /* DBG_PKT_MON */
699*4882a593Smuzhiyun 
700*4882a593Smuzhiyun #ifdef DUMP_IOCTL_IOV_LIST
701*4882a593Smuzhiyun typedef struct dhd_iov_li {
702*4882a593Smuzhiyun 	dll_t list;
703*4882a593Smuzhiyun 	uint32 cmd; /* command number */
704*4882a593Smuzhiyun 	char buff[100]; /* command name */
705*4882a593Smuzhiyun } dhd_iov_li_t;
706*4882a593Smuzhiyun #endif /* DUMP_IOCTL_IOV_LIST */
707*4882a593Smuzhiyun 
708*4882a593Smuzhiyun #define IOV_LIST_MAX_LEN 5
709*4882a593Smuzhiyun 
710*4882a593Smuzhiyun #ifdef DHD_DEBUG
711*4882a593Smuzhiyun typedef struct {
712*4882a593Smuzhiyun 	dll_t list;
713*4882a593Smuzhiyun 	uint32 id; /* wasted chunk id */
714*4882a593Smuzhiyun 	uint32 handle; /* wasted chunk handle */
715*4882a593Smuzhiyun 	uint32 size; /* wasted chunk size */
716*4882a593Smuzhiyun } dhd_dbg_mwli_t;
717*4882a593Smuzhiyun #endif /* DHD_DEBUG */
718*4882a593Smuzhiyun 
719*4882a593Smuzhiyun #define DHD_OW_BI_RAW_EVENT_LOG_FMT 0xFFFF
720*4882a593Smuzhiyun 
721*4882a593Smuzhiyun /* LSB 2 bits of format number to identify the type of event log */
722*4882a593Smuzhiyun #define DHD_EVENT_LOG_HDR_MASK 0x3
723*4882a593Smuzhiyun 
724*4882a593Smuzhiyun #define DHD_EVENT_LOG_FMT_NUM_OFFSET 2
725*4882a593Smuzhiyun #define DHD_EVENT_LOG_FMT_NUM_MASK 0x3FFF
726*4882a593Smuzhiyun /**
727*4882a593Smuzhiyun  * OW:- one word
728*4882a593Smuzhiyun  * TW:- two word
729*4882a593Smuzhiyun  * NB:- non binary
730*4882a593Smuzhiyun  * BI:- binary
731*4882a593Smuzhiyun  */
732*4882a593Smuzhiyun #define	DHD_OW_NB_EVENT_LOG_HDR 0
733*4882a593Smuzhiyun #define DHD_TW_NB_EVENT_LOG_HDR 1
734*4882a593Smuzhiyun #define DHD_BI_EVENT_LOG_HDR 3
735*4882a593Smuzhiyun #define DHD_INVALID_EVENT_LOG_HDR 2
736*4882a593Smuzhiyun 
737*4882a593Smuzhiyun #define DHD_TW_VALID_TAG_BITS_MASK 0xF
738*4882a593Smuzhiyun #define DHD_OW_BI_EVENT_FMT_NUM 0x3FFF
739*4882a593Smuzhiyun #define DHD_TW_BI_EVENT_FMT_NUM 0x3FFE
740*4882a593Smuzhiyun 
741*4882a593Smuzhiyun #define DHD_TW_EVENT_LOG_TAG_OFFSET 8
742*4882a593Smuzhiyun 
743*4882a593Smuzhiyun #define EVENT_TAG_TIMESTAMP_OFFSET 1
744*4882a593Smuzhiyun #define EVENT_TAG_TIMESTAMP_EXT_OFFSET 2
745*4882a593Smuzhiyun 
746*4882a593Smuzhiyun typedef struct prcd_event_log_hdr {
747*4882a593Smuzhiyun 	uint32 tag;		/* Event_log entry tag */
748*4882a593Smuzhiyun 	uint32 count;		/* Count of 4-byte entries */
749*4882a593Smuzhiyun 	uint32 fmt_num_raw;	/* Format number */
750*4882a593Smuzhiyun 	uint32 fmt_num;		/* Format number >> 2 */
751*4882a593Smuzhiyun 	uint32 armcycle;	/* global ARM CYCLE for TAG */
752*4882a593Smuzhiyun 	uint32 *log_ptr;	/* start of payload */
753*4882a593Smuzhiyun 	uint32	payload_len;
754*4882a593Smuzhiyun 	/* Extended event log header info
755*4882a593Smuzhiyun 	 * 0 - legacy, 1 - extended event log header present
756*4882a593Smuzhiyun 	 */
757*4882a593Smuzhiyun 	bool ext_event_log_hdr;
758*4882a593Smuzhiyun 	bool binary_payload;	/* 0 - non binary payload, 1 - binary payload */
759*4882a593Smuzhiyun } prcd_event_log_hdr_t;		/* Processed event log header */
760*4882a593Smuzhiyun 
761*4882a593Smuzhiyun /* dhd_dbg functions */
762*4882a593Smuzhiyun extern void dhd_dbg_trace_evnt_handler(dhd_pub_t *dhdp, void *event_data,
763*4882a593Smuzhiyun 		void *raw_event_ptr, uint datalen);
764*4882a593Smuzhiyun void dhd_dbg_msgtrace_log_parser(dhd_pub_t *dhdp, void *event_data,
765*4882a593Smuzhiyun 	void *raw_event_ptr, uint datalen, bool msgtrace_hdr_present,
766*4882a593Smuzhiyun 	uint32 msgtrace_seqnum);
767*4882a593Smuzhiyun 
768*4882a593Smuzhiyun extern int dhd_dbg_attach(dhd_pub_t *dhdp, dbg_pullreq_t os_pullreq,
769*4882a593Smuzhiyun 	dbg_urgent_noti_t os_urgent_notifier, void *os_priv);
770*4882a593Smuzhiyun extern void dhd_dbg_detach(dhd_pub_t *dhdp);
771*4882a593Smuzhiyun extern int dhd_dbg_start(dhd_pub_t *dhdp, bool start);
772*4882a593Smuzhiyun extern int dhd_dbg_set_configuration(dhd_pub_t *dhdp, int ring_id,
773*4882a593Smuzhiyun 		int log_level, int flags, uint32 threshold);
774*4882a593Smuzhiyun extern int dhd_dbg_find_ring_id(dhd_pub_t *dhdp, char *ring_name);
775*4882a593Smuzhiyun extern dhd_dbg_ring_t *dhd_dbg_get_ring_from_ring_id(dhd_pub_t *dhdp, int ring_id);
776*4882a593Smuzhiyun extern void *dhd_dbg_get_priv(dhd_pub_t *dhdp);
777*4882a593Smuzhiyun extern int dhd_dbg_send_urgent_evt(dhd_pub_t *dhdp, const void *data, const uint32 len);
778*4882a593Smuzhiyun extern void dhd_dbg_verboselog_printf(dhd_pub_t *dhdp, prcd_event_log_hdr_t *plog_hdr,
779*4882a593Smuzhiyun 	void *raw_event_ptr, uint32 *log_ptr, uint32 logset, uint16 block);
780*4882a593Smuzhiyun int dhd_dbg_pull_from_ring(dhd_pub_t *dhdp, int ring_id, void *data, uint32 buf_len);
781*4882a593Smuzhiyun int dhd_dbg_pull_single_from_ring(dhd_pub_t *dhdp, int ring_id, void *data, uint32 buf_len,
782*4882a593Smuzhiyun 	bool strip_header);
783*4882a593Smuzhiyun int dhd_dbg_push_to_ring(dhd_pub_t *dhdp, int ring_id, dhd_dbg_ring_entry_t *hdr,
784*4882a593Smuzhiyun 		void *data);
785*4882a593Smuzhiyun int __dhd_dbg_get_ring_status(dhd_dbg_ring_t *ring, dhd_dbg_ring_status_t *ring_status);
786*4882a593Smuzhiyun int dhd_dbg_get_ring_status(dhd_pub_t *dhdp, int ring_id,
787*4882a593Smuzhiyun 		dhd_dbg_ring_status_t *dbg_ring_status);
788*4882a593Smuzhiyun #ifdef SHOW_LOGTRACE
789*4882a593Smuzhiyun void dhd_dbg_read_ring_into_trace_buf(dhd_dbg_ring_t *ring, trace_buf_info_t *trace_buf_info);
790*4882a593Smuzhiyun #endif /* SHOW_LOGTRACE */
791*4882a593Smuzhiyun 
792*4882a593Smuzhiyun #ifdef DBG_PKT_MON
793*4882a593Smuzhiyun extern int dhd_dbg_attach_pkt_monitor(dhd_pub_t *dhdp,
794*4882a593Smuzhiyun 		dbg_mon_tx_pkts_t tx_pkt_mon,
795*4882a593Smuzhiyun 		dbg_mon_tx_status_t tx_status_mon,
796*4882a593Smuzhiyun 		dbg_mon_rx_pkts_t rx_pkt_mon);
797*4882a593Smuzhiyun extern int dhd_dbg_start_pkt_monitor(dhd_pub_t *dhdp);
798*4882a593Smuzhiyun extern int dhd_dbg_monitor_tx_pkts(dhd_pub_t *dhdp, void *pkt, uint32 pktid);
799*4882a593Smuzhiyun extern int dhd_dbg_monitor_tx_status(dhd_pub_t *dhdp, void *pkt,
800*4882a593Smuzhiyun 		uint32 pktid, uint16 status);
801*4882a593Smuzhiyun extern int dhd_dbg_monitor_rx_pkts(dhd_pub_t *dhdp, void *pkt);
802*4882a593Smuzhiyun extern int dhd_dbg_stop_pkt_monitor(dhd_pub_t *dhdp);
803*4882a593Smuzhiyun extern int dhd_dbg_monitor_get_tx_pkts(dhd_pub_t *dhdp, void __user *user_buf,
804*4882a593Smuzhiyun 		uint16 req_count, uint16 *resp_count);
805*4882a593Smuzhiyun extern int dhd_dbg_monitor_get_rx_pkts(dhd_pub_t *dhdp, void __user *user_buf,
806*4882a593Smuzhiyun 		uint16 req_count, uint16 *resp_count);
807*4882a593Smuzhiyun extern int dhd_dbg_detach_pkt_monitor(dhd_pub_t *dhdp);
808*4882a593Smuzhiyun #endif /* DBG_PKT_MON */
809*4882a593Smuzhiyun 
810*4882a593Smuzhiyun extern bool dhd_dbg_process_tx_status(dhd_pub_t *dhdp, void *pkt,
811*4882a593Smuzhiyun 		uint32 pktid, uint16 status);
812*4882a593Smuzhiyun 
813*4882a593Smuzhiyun /* os wrapper function */
814*4882a593Smuzhiyun extern int dhd_os_dbg_attach(dhd_pub_t *dhdp);
815*4882a593Smuzhiyun extern void dhd_os_dbg_detach(dhd_pub_t *dhdp);
816*4882a593Smuzhiyun extern int dhd_os_dbg_register_callback(int ring_id,
817*4882a593Smuzhiyun 	void (*dbg_ring_sub_cb)(void *ctx, const int ring_id, const void *data,
818*4882a593Smuzhiyun 		const uint32 len, const dhd_dbg_ring_status_t dbg_ring_status));
819*4882a593Smuzhiyun extern int dhd_os_dbg_register_urgent_notifier(dhd_pub_t *dhdp,
820*4882a593Smuzhiyun 	void (*urgent_noti)(void *ctx, const void *data, const uint32 len, const uint32 fw_len));
821*4882a593Smuzhiyun 
822*4882a593Smuzhiyun extern int dhd_os_start_logging(dhd_pub_t *dhdp, char *ring_name, int log_level,
823*4882a593Smuzhiyun 		int flags, int time_intval, int threshold);
824*4882a593Smuzhiyun extern int dhd_os_reset_logging(dhd_pub_t *dhdp);
825*4882a593Smuzhiyun extern int dhd_os_suppress_logging(dhd_pub_t *dhdp, bool suppress);
826*4882a593Smuzhiyun 
827*4882a593Smuzhiyun extern int dhd_os_get_ring_status(dhd_pub_t *dhdp, int ring_id,
828*4882a593Smuzhiyun 		dhd_dbg_ring_status_t *dbg_ring_status);
829*4882a593Smuzhiyun extern int dhd_os_trigger_get_ring_data(dhd_pub_t *dhdp, char *ring_name);
830*4882a593Smuzhiyun extern int dhd_os_push_push_ring_data(dhd_pub_t *dhdp, int ring_id, void *data, int32 data_len);
831*4882a593Smuzhiyun extern int dhd_os_dbg_get_feature(dhd_pub_t *dhdp, int32 *features);
832*4882a593Smuzhiyun 
833*4882a593Smuzhiyun #ifdef DBG_PKT_MON
834*4882a593Smuzhiyun extern int dhd_os_dbg_attach_pkt_monitor(dhd_pub_t *dhdp);
835*4882a593Smuzhiyun extern int dhd_os_dbg_start_pkt_monitor(dhd_pub_t *dhdp);
836*4882a593Smuzhiyun extern int dhd_os_dbg_monitor_tx_pkts(dhd_pub_t *dhdp, void *pkt,
837*4882a593Smuzhiyun 	uint32 pktid);
838*4882a593Smuzhiyun extern int dhd_os_dbg_monitor_tx_status(dhd_pub_t *dhdp, void *pkt,
839*4882a593Smuzhiyun 	uint32 pktid, uint16 status);
840*4882a593Smuzhiyun extern int dhd_os_dbg_monitor_rx_pkts(dhd_pub_t *dhdp, void *pkt);
841*4882a593Smuzhiyun extern int dhd_os_dbg_stop_pkt_monitor(dhd_pub_t *dhdp);
842*4882a593Smuzhiyun extern int dhd_os_dbg_monitor_get_tx_pkts(dhd_pub_t *dhdp,
843*4882a593Smuzhiyun 	void __user *user_buf, uint16 req_count, uint16 *resp_count);
844*4882a593Smuzhiyun extern int dhd_os_dbg_monitor_get_rx_pkts(dhd_pub_t *dhdp,
845*4882a593Smuzhiyun 	void __user *user_buf, uint16 req_count, uint16 *resp_count);
846*4882a593Smuzhiyun extern int dhd_os_dbg_detach_pkt_monitor(dhd_pub_t *dhdp);
847*4882a593Smuzhiyun #endif /* DBG_PKT_MON */
848*4882a593Smuzhiyun 
849*4882a593Smuzhiyun #ifdef DUMP_IOCTL_IOV_LIST
850*4882a593Smuzhiyun extern void dhd_iov_li_append(dhd_pub_t *dhd, dll_t *list_head, dll_t *node);
851*4882a593Smuzhiyun extern void dhd_iov_li_print(dll_t *list_head);
852*4882a593Smuzhiyun extern void dhd_iov_li_delete(dhd_pub_t *dhd, dll_t *list_head);
853*4882a593Smuzhiyun #endif /* DUMP_IOCTL_IOV_LIST */
854*4882a593Smuzhiyun 
855*4882a593Smuzhiyun #ifdef DHD_DEBUG
856*4882a593Smuzhiyun extern void dhd_mw_list_delete(dhd_pub_t *dhd, dll_t *list_head);
857*4882a593Smuzhiyun #endif /* DHD_DEBUG */
858*4882a593Smuzhiyun #endif /* _dhd_debug_h_ */
859