dhd_debug.h 30 KB

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