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