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