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