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