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