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