2 * DHD debugability support
4 * Copyright (C) 2020, Broadcom.
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:
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.
21 * <<Broadcom-WL-IPTag/Open:>>
29 #include <bcmendian.h>
30 #include <dngl_stats.h>
33 #include <dhd_dbg_ring.h>
34 #include <dhd_debug.h>
35 #include <dhd_mschdbg.h>
38 #include <event_log.h>
39 #include <event_trace.h>
42 #if defined(DHD_EVENT_LOG_FILTER)
43 #include <dhd_event_log_filter.h>
44 #endif /* DHD_EVENT_LOG_FILTER */
46 uint8 control_logtrace
= CUSTOM_CONTROL_LOGTRACE
;
54 struct map_table event_map
[] = {
55 {WLC_E_AUTH
, WIFI_EVENT_AUTH_COMPLETE
, "AUTH_COMPLETE"},
56 {WLC_E_ASSOC
, WIFI_EVENT_ASSOC_COMPLETE
, "ASSOC_COMPLETE"},
57 {TRACE_FW_AUTH_STARTED
, WIFI_EVENT_FW_AUTH_STARTED
, "AUTH STARTED"},
58 {TRACE_FW_ASSOC_STARTED
, WIFI_EVENT_FW_ASSOC_STARTED
, "ASSOC STARTED"},
59 {TRACE_FW_RE_ASSOC_STARTED
, WIFI_EVENT_FW_RE_ASSOC_STARTED
, "REASSOC STARTED"},
60 {TRACE_G_SCAN_STARTED
, WIFI_EVENT_G_SCAN_STARTED
, "GSCAN STARTED"},
61 {WLC_E_PFN_SCAN_COMPLETE
, WIFI_EVENT_G_SCAN_COMPLETE
, "GSCAN COMPLETE"},
62 {WLC_E_DISASSOC
, WIFI_EVENT_DISASSOCIATION_REQUESTED
, "DIASSOC REQUESTED"},
63 {WLC_E_REASSOC
, WIFI_EVENT_RE_ASSOCIATION_REQUESTED
, "REASSOC REQUESTED"},
64 {TRACE_ROAM_SCAN_STARTED
, WIFI_EVENT_ROAM_REQUESTED
, "ROAM REQUESTED"},
65 {WLC_E_BEACON_FRAME_RX
, WIFI_EVENT_BEACON_RECEIVED
, "BEACON Received"},
66 {TRACE_ROAM_SCAN_STARTED
, WIFI_EVENT_ROAM_SCAN_STARTED
, "ROAM SCAN STARTED"},
67 {TRACE_ROAM_SCAN_COMPLETE
, WIFI_EVENT_ROAM_SCAN_COMPLETE
, "ROAM SCAN COMPLETED"},
68 {TRACE_ROAM_AUTH_STARTED
, WIFI_EVENT_ROAM_AUTH_STARTED
, "ROAM AUTH STARTED"},
69 {WLC_E_AUTH
, WIFI_EVENT_ROAM_AUTH_COMPLETE
, "ROAM AUTH COMPLETED"},
70 {TRACE_FW_RE_ASSOC_STARTED
, WIFI_EVENT_ROAM_ASSOC_STARTED
, "ROAM ASSOC STARTED"},
71 {WLC_E_ASSOC
, WIFI_EVENT_ROAM_ASSOC_COMPLETE
, "ROAM ASSOC COMPLETED"},
72 {TRACE_ROAM_SCAN_COMPLETE
, WIFI_EVENT_ROAM_SCAN_COMPLETE
, "ROAM SCAN COMPLETED"},
73 {TRACE_BT_COEX_BT_SCO_START
, WIFI_EVENT_BT_COEX_BT_SCO_START
, "BT SCO START"},
74 {TRACE_BT_COEX_BT_SCO_STOP
, WIFI_EVENT_BT_COEX_BT_SCO_STOP
, "BT SCO STOP"},
75 {TRACE_BT_COEX_BT_SCAN_START
, WIFI_EVENT_BT_COEX_BT_SCAN_START
, "BT COEX SCAN START"},
76 {TRACE_BT_COEX_BT_SCAN_STOP
, WIFI_EVENT_BT_COEX_BT_SCAN_STOP
, "BT COEX SCAN STOP"},
77 {TRACE_BT_COEX_BT_HID_START
, WIFI_EVENT_BT_COEX_BT_HID_START
, "BT HID START"},
78 {TRACE_BT_COEX_BT_HID_STOP
, WIFI_EVENT_BT_COEX_BT_HID_STOP
, "BT HID STOP"},
79 {WLC_E_EAPOL_MSG
, WIFI_EVENT_FW_EAPOL_FRAME_RECEIVED
, "FW EAPOL PKT RECEIVED"},
80 {TRACE_FW_EAPOL_FRAME_TRANSMIT_START
, WIFI_EVENT_FW_EAPOL_FRAME_TRANSMIT_START
,
81 "FW EAPOL PKT TRANSMITED"},
82 {TRACE_FW_EAPOL_FRAME_TRANSMIT_STOP
, WIFI_EVENT_FW_EAPOL_FRAME_TRANSMIT_STOP
,
83 "FW EAPOL PKT TX STOPPED"},
84 {TRACE_BLOCK_ACK_NEGOTIATION_COMPLETE
, WIFI_EVENT_BLOCK_ACK_NEGOTIATION_COMPLETE
,
85 "BLOCK ACK NEGO COMPLETED"},
88 struct map_table event_tag_map
[] = {
89 {TRACE_TAG_VENDOR_SPECIFIC
, WIFI_TAG_VENDOR_SPECIFIC
, "VENDOR SPECIFIC DATA"},
90 {TRACE_TAG_BSSID
, WIFI_TAG_BSSID
, "BSSID"},
91 {TRACE_TAG_ADDR
, WIFI_TAG_ADDR
, "ADDR_0"},
92 {TRACE_TAG_SSID
, WIFI_TAG_SSID
, "SSID"},
93 {TRACE_TAG_STATUS
, WIFI_TAG_STATUS
, "STATUS"},
94 {TRACE_TAG_CHANNEL_SPEC
, WIFI_TAG_CHANNEL_SPEC
, "CHANSPEC"},
95 {TRACE_TAG_WAKE_LOCK_EVENT
, WIFI_TAG_WAKE_LOCK_EVENT
, "WAKELOCK EVENT"},
96 {TRACE_TAG_ADDR1
, WIFI_TAG_ADDR1
, "ADDR_1"},
97 {TRACE_TAG_ADDR2
, WIFI_TAG_ADDR2
, "ADDR_2"},
98 {TRACE_TAG_ADDR3
, WIFI_TAG_ADDR3
, "ADDR_3"},
99 {TRACE_TAG_ADDR4
, WIFI_TAG_ADDR4
, "ADDR_4"},
100 {TRACE_TAG_TSF
, WIFI_TAG_TSF
, "TSF"},
101 {TRACE_TAG_IE
, WIFI_TAG_IE
, "802.11 IE"},
102 {TRACE_TAG_INTERFACE
, WIFI_TAG_INTERFACE
, "INTERFACE"},
103 {TRACE_TAG_REASON_CODE
, WIFI_TAG_REASON_CODE
, "REASON CODE"},
104 {TRACE_TAG_RATE_MBPS
, WIFI_TAG_RATE_MBPS
, "RATE"},
107 /* define log level per ring type */
108 struct log_level_table fw_verbose_level_map
[] = {
109 {1, EVENT_LOG_TAG_PCI_ERROR
, "PCI_ERROR"},
110 {1, EVENT_LOG_TAG_PCI_WARN
, "PCI_WARN"},
111 {2, EVENT_LOG_TAG_PCI_INFO
, "PCI_INFO"},
112 {3, EVENT_LOG_TAG_PCI_DBG
, "PCI_DEBUG"},
113 {3, EVENT_LOG_TAG_BEACON_LOG
, "BEACON_LOG"},
114 {2, EVENT_LOG_TAG_WL_ASSOC_LOG
, "ASSOC_LOG"},
115 {2, EVENT_LOG_TAG_WL_ROAM_LOG
, "ROAM_LOG"},
116 {1, EVENT_LOG_TAG_TRACE_WL_INFO
, "WL INFO"},
117 {1, EVENT_LOG_TAG_TRACE_BTCOEX_INFO
, "BTCOEX INFO"},
118 #ifdef CUSTOMER_HW4_DEBUG
119 {3, EVENT_LOG_TAG_SCAN_WARN
, "SCAN_WARN"},
121 {1, EVENT_LOG_TAG_SCAN_WARN
, "SCAN_WARN"},
122 #endif /* CUSTOMER_HW4_DEBUG */
123 {1, EVENT_LOG_TAG_SCAN_ERROR
, "SCAN_ERROR"},
124 {2, EVENT_LOG_TAG_SCAN_TRACE_LOW
, "SCAN_TRACE_LOW"},
125 {2, EVENT_LOG_TAG_SCAN_TRACE_HIGH
, "SCAN_TRACE_HIGH"}
128 /* reference tab table */
129 uint ref_tag_tbl
[EVENT_LOG_TAG_MAX
+ 1] = {0};
131 typedef struct dhddbg_loglist_item
{
133 prcd_event_log_hdr_t prcd_log_hdr
;
136 typedef struct dhbdbg_pending_item
{
138 dhd_dbg_ring_status_t ring_status
;
139 dhd_dbg_ring_entry_t
*ring_entry
;
142 /* trace log entry header user space processing */
143 struct tracelog_header
{
148 #define TRACE_LOG_MAGIC_NUMBER 0xEAE47C06
151 dhd_dbg_push_to_ring(dhd_pub_t
*dhdp
, int ring_id
, dhd_dbg_ring_entry_t
*hdr
, void *data
)
153 dhd_dbg_ring_t
*ring
;
155 uint32 pending_len
= 0;
157 if (!dhdp
|| !dhdp
->dbg
) {
161 if (!VALID_RING(ring_id
)) {
162 DHD_ERROR(("%s : invalid ring_id : %d\n", __FUNCTION__
, ring_id
));
166 ring
= &dhdp
->dbg
->dbg_rings
[ring_id
];
168 ret
= dhd_dbg_ring_push(ring
, hdr
, data
);
172 pending_len
= dhd_dbg_ring_get_pending_len(ring
);
173 dhd_dbg_ring_sched_pull(ring
, pending_len
, dhdp
->dbg
->pullreq
,
174 dhdp
->dbg
->private, ring
->id
);
180 dhd_dbg_get_ring_from_ring_id(dhd_pub_t
*dhdp
, int ring_id
)
182 if (!dhdp
|| !dhdp
->dbg
) {
186 if (!VALID_RING(ring_id
)) {
187 DHD_ERROR(("%s : invalid ring_id : %d\n", __FUNCTION__
, ring_id
));
191 return &dhdp
->dbg
->dbg_rings
[ring_id
];
195 dhd_dbg_pull_single_from_ring(dhd_pub_t
*dhdp
, int ring_id
, void *data
, uint32 buf_len
,
198 dhd_dbg_ring_t
*ring
;
200 if (!dhdp
|| !dhdp
->dbg
) {
204 if (!VALID_RING(ring_id
)) {
205 DHD_ERROR(("%s : invalid ring_id : %d\n", __FUNCTION__
, ring_id
));
209 ring
= &dhdp
->dbg
->dbg_rings
[ring_id
];
211 return dhd_dbg_ring_pull_single(ring
, data
, buf_len
, strip_header
);
215 dhd_dbg_pull_from_ring(dhd_pub_t
*dhdp
, int ring_id
, void *data
, uint32 buf_len
)
217 dhd_dbg_ring_t
*ring
;
219 if (!dhdp
|| !dhdp
->dbg
)
221 if (!VALID_RING(ring_id
)) {
222 DHD_ERROR(("%s : invalid ring_id : %d\n", __FUNCTION__
, ring_id
));
225 ring
= &dhdp
->dbg
->dbg_rings
[ring_id
];
226 return dhd_dbg_ring_pull(ring
, data
, buf_len
, FALSE
);
230 dhd_dbg_msgtrace_seqchk(uint32
*prev
, uint32 cur
)
232 /* normal case including wrap around */
233 if ((cur
== 0 && *prev
== 0xFFFFFFFF) || ((cur
- *prev
) == 1)) {
235 } else if (cur
== *prev
) {
236 DHD_EVENT(("%s duplicate trace\n", __FUNCTION__
));
238 } else if (cur
> *prev
) {
239 DHD_EVENT(("%s lost %d packets\n", __FUNCTION__
, cur
- *prev
));
241 DHD_EVENT(("%s seq out of order, dhd %d, dongle %d\n",
242 __FUNCTION__
, *prev
, cur
));
250 dhd_dbg_msgtrace_msg_parser(void *event_data
)
254 static uint32 seqnum_prev
= 0;
257 DHD_ERROR(("%s: event_data is NULL\n", __FUNCTION__
));
261 hdr
= (msgtrace_hdr_t
*)event_data
;
262 data
= (char *)event_data
+ MSGTRACE_HDRLEN
;
264 /* There are 2 bytes available at the end of data */
265 data
[ntoh16(hdr
->len
)] = '\0';
267 if (ntoh32(hdr
->discarded_bytes
) || ntoh32(hdr
->discarded_printf
)) {
268 DHD_DBGIF(("WLC_E_TRACE: [Discarded traces in dongle -->"
269 "discarded_bytes %d discarded_printf %d]\n",
270 ntoh32(hdr
->discarded_bytes
),
271 ntoh32(hdr
->discarded_printf
)));
274 if (dhd_dbg_msgtrace_seqchk(&seqnum_prev
, ntoh32(hdr
->seqnum
)))
277 /* Display the trace buffer. Advance from
278 * \n to \n to avoid display big
279 * printf (issue with Linux printk )
281 while (*data
!= '\0' && (s
= strstr(data
, "\n")) != NULL
) {
283 DHD_FWLOG(("[FWLOG] %s\n", data
));
287 DHD_FWLOG(("[FWLOG] %s", data
));
290 #define DATA_UNIT_FOR_LOG_CNT 4
292 #if defined(STRICT_GCC_WARNINGS) && defined(__GNUC__)
293 #pragma GCC diagnostic pop
297 replace_percent_p_to_x(char *fmt
)
299 int p_to_x_done
= FALSE
;
303 /* Skip characters will we see a % */
310 * Skip any flags, field width and precision:
311 *Flags: Followed by %
317 if (*fmt
== '0' || *fmt
== '-' || *fmt
== '+')
322 * An optional decimal digit string (with non-zero first digit)
323 * specifying a minimum field width
325 while (*fmt
&& bcm_isdigit(*fmt
))
330 * An optional precision, in the form of a period ('.') followed by an
331 * optional decimal digit string.
336 while (*fmt
&& bcm_isdigit(*fmt
)) fmt
++;
339 /* If %p is seen, change it to %x */
352 /* To identify format of types %Ns where N >= 0 is a number */
354 check_valid_string_format(char *curr_ptr
)
357 if ((next_ptr
= bcmstrstr(curr_ptr
, "s")) != NULL
) {
358 /* Default %s format */
359 if (curr_ptr
== next_ptr
) {
363 /* Verify each charater between '%' and 's' is a valid number */
364 while (curr_ptr
< next_ptr
) {
365 if (bcm_isdigit(*curr_ptr
) == FALSE
) {
377 /* To identify format of non string format types */
379 check_valid_non_string_format(char *curr_ptr
)
382 char *next_fmt_stptr
;
383 char valid_fmt_types
[17] = {'d', 'i', 'x', 'X', 'c', 'p', 'u',
384 'f', 'F', 'e', 'E', 'g', 'G', 'o',
389 /* Check for next % in the fmt str */
390 next_fmt_stptr
= bcmstrstr(curr_ptr
, "%");
392 for (next_ptr
= curr_ptr
; *next_ptr
!= '\0'; next_ptr
++) {
393 for (i
= 0; i
< (int)((sizeof(valid_fmt_types
))/sizeof(valid_fmt_types
[0])); i
++) {
394 if (*next_ptr
== valid_fmt_types
[i
]) {
395 /* Check whether format type found corresponds to current %
396 * and not the next one, if exists.
398 if ((next_fmt_stptr
== NULL
) ||
399 (next_fmt_stptr
&& (next_ptr
< next_fmt_stptr
))) {
400 /* Not validating for length/width fields in
414 #define MAX_NO_OF_ARG 16
415 #define FMTSTR_SIZE 200
416 #define ROMSTR_SIZE 268
417 #define SIZE_LOC_STR 50
418 #define LOG_PRINT_CNT_MAX 16u
419 #define EL_MSEC_PER_SEC 1000
420 #ifdef DHD_LOG_PRINT_RATE_LIMIT
421 #define MAX_LOG_PRINT_COUNT 100u
422 #define LOG_PRINT_THRESH (1u * USEC_PER_SEC)
424 #define EL_PARSE_VER "V02"
425 static uint64 verboselog_ts_saved
= 0;
428 dhd_dbg_process_event_log_hdr(event_log_hdr_t
*log_hdr
, prcd_event_log_hdr_t
*prcd_log_hdr
)
430 event_log_extended_hdr_t
*ext_log_hdr
;
431 uint16 event_log_fmt_num
;
432 uint8 event_log_hdr_type
;
434 /* Identify the type of event tag, payload type etc.. */
435 event_log_hdr_type
= log_hdr
->fmt_num
& DHD_EVENT_LOG_HDR_MASK
;
436 event_log_fmt_num
= (log_hdr
->fmt_num
>> DHD_EVENT_LOG_FMT_NUM_OFFSET
) &
437 DHD_EVENT_LOG_FMT_NUM_MASK
;
439 switch (event_log_hdr_type
) {
440 case DHD_OW_NB_EVENT_LOG_HDR
:
441 prcd_log_hdr
->ext_event_log_hdr
= FALSE
;
442 prcd_log_hdr
->binary_payload
= FALSE
;
444 case DHD_TW_NB_EVENT_LOG_HDR
:
445 prcd_log_hdr
->ext_event_log_hdr
= TRUE
;
446 prcd_log_hdr
->binary_payload
= FALSE
;
448 case DHD_BI_EVENT_LOG_HDR
:
449 if (event_log_fmt_num
== DHD_OW_BI_EVENT_FMT_NUM
) {
450 prcd_log_hdr
->ext_event_log_hdr
= FALSE
;
451 prcd_log_hdr
->binary_payload
= TRUE
;
452 } else if (event_log_fmt_num
== DHD_TW_BI_EVENT_FMT_NUM
) {
453 prcd_log_hdr
->ext_event_log_hdr
= TRUE
;
454 prcd_log_hdr
->binary_payload
= TRUE
;
456 DHD_ERROR(("%s: invalid format number 0x%X\n",
457 __FUNCTION__
, event_log_fmt_num
));
461 case DHD_INVALID_EVENT_LOG_HDR
:
463 DHD_ERROR(("%s: invalid event log header type 0x%X\n",
464 __FUNCTION__
, event_log_hdr_type
));
468 /* Parse extended and legacy event log headers and populate prcd_event_log_hdr_t */
469 if (prcd_log_hdr
->ext_event_log_hdr
) {
470 ext_log_hdr
= (event_log_extended_hdr_t
*)
471 ((uint8
*)log_hdr
- sizeof(event_log_hdr_t
));
472 prcd_log_hdr
->tag
= ((ext_log_hdr
->extended_tag
&
473 DHD_TW_VALID_TAG_BITS_MASK
) << DHD_TW_EVENT_LOG_TAG_OFFSET
) | log_hdr
->tag
;
475 prcd_log_hdr
->tag
= log_hdr
->tag
;
477 prcd_log_hdr
->count
= log_hdr
->count
;
478 prcd_log_hdr
->fmt_num_raw
= log_hdr
->fmt_num
;
479 prcd_log_hdr
->fmt_num
= event_log_fmt_num
;
481 /* update arm cycle */
483 * For loegacy event tag :-
484 * |payload........|Timestamp| Tag
486 * For extended event tag:-
487 * |payload........|Timestamp|extended Tag| Tag.
490 prcd_log_hdr
->armcycle
= prcd_log_hdr
->ext_event_log_hdr
?
491 *(uint32
*)(log_hdr
- EVENT_TAG_TIMESTAMP_EXT_OFFSET
) :
492 *(uint32
*)(log_hdr
- EVENT_TAG_TIMESTAMP_OFFSET
);
494 /* update event log data pointer address */
495 prcd_log_hdr
->log_ptr
=
496 (uint32
*)log_hdr
- log_hdr
->count
- prcd_log_hdr
->ext_event_log_hdr
;
498 /* handle error cases above this */
503 dhd_dbg_verboselog_handler(dhd_pub_t
*dhdp
, prcd_event_log_hdr_t
*plog_hdr
,
504 void *raw_event_ptr
, uint32 logset
, uint16 block
, uint32
* data
)
506 event_log_hdr_t
*ts_hdr
;
507 uint32
*log_ptr
= plog_hdr
->log_ptr
;
508 char fmtstr_loc_buf
[ROMSTR_SIZE
] = { 0 };
509 uint32 rom_str_len
= 0;
512 if (!raw_event_ptr
) {
516 if (log_ptr
< data
) {
517 DHD_ERROR(("Invalid log pointer, logptr : %p data : %p \n", log_ptr
, data
));
521 if (log_ptr
> data
) {
522 /* Get time stamp if it's updated */
523 ts_hdr
= (event_log_hdr_t
*)((char *)log_ptr
- sizeof(event_log_hdr_t
));
524 if (ts_hdr
->tag
== EVENT_LOG_TAG_TS
) {
525 ts_data
= (uint32
*)ts_hdr
- ts_hdr
->count
;
526 if (ts_data
>= data
) {
527 verboselog_ts_saved
= (uint64
)ts_data
[0];
528 DHD_MSGTRACE_LOG(("EVENT_LOG_TS[0x%08x]: SYS:%08x CPU:%08x\n",
529 ts_data
[ts_hdr
->count
- 1], ts_data
[0], ts_data
[1]));
531 } else if (ts_hdr
->tag
== EVENT_LOG_TAG_ENHANCED_TS
) {
533 ets
= (ets_msg_v1_t
*)ts_hdr
- ts_hdr
->count
;
534 if ((uint32
*)ets
>= data
&&
535 ts_hdr
->count
>= (sizeof(ets_msg_v1_t
) / sizeof(uint32
)) &&
536 ets
->version
== ENHANCED_TS_MSG_VERSION_1
) {
537 DHD_MSGTRACE_LOG(("EVENT_LOG_ENHANCED_TS_V1: "
538 "SYS:%08x CPU:%08x CPUFREQ:%u\n",
539 ets
->timestamp
, ets
->cyclecount
, ets
->cpu_freq
));
544 if (plog_hdr
->tag
== EVENT_LOG_TAG_ROM_PRINTF
) {
545 rom_str_len
= (plog_hdr
->count
- 1) * sizeof(uint32
);
546 if (rom_str_len
>= (ROMSTR_SIZE
-1))
547 rom_str_len
= ROMSTR_SIZE
- 1;
549 /* copy all ascii data for ROM printf to local string */
550 memcpy(fmtstr_loc_buf
, log_ptr
, rom_str_len
);
551 /* add end of line at last */
552 fmtstr_loc_buf
[rom_str_len
] = '\0';
554 DHD_MSGTRACE_LOG(("EVENT_LOG_ROM[0x%08x]: %s",
555 log_ptr
[plog_hdr
->count
- 1], fmtstr_loc_buf
));
557 /* Add newline if missing */
558 if (fmtstr_loc_buf
[strlen(fmtstr_loc_buf
) - 1] != '\n')
559 DHD_MSGTRACE_LOG(("\n"));
564 if (plog_hdr
->tag
== EVENT_LOG_TAG_MSCHPROFILE
||
565 plog_hdr
->tag
== EVENT_LOG_TAG_MSCHPROFILE_TLV
) {
566 wl_mschdbg_verboselog_handler(dhdp
, raw_event_ptr
, plog_hdr
, log_ptr
);
570 /* print the message out in a logprint */
571 dhd_dbg_verboselog_printf(dhdp
, plog_hdr
, raw_event_ptr
, log_ptr
, logset
, block
);
575 dhd_dbg_verboselog_printf(dhd_pub_t
*dhdp
, prcd_event_log_hdr_t
*plog_hdr
,
576 void *raw_event_ptr
, uint32
*log_ptr
, uint32 logset
, uint16 block
)
578 dhd_event_log_t
*raw_event
= (dhd_event_log_t
*)raw_event_ptr
;
581 char fmtstr_loc_buf
[ROMSTR_SIZE
] = { 0 };
582 char (*str_buf
)[SIZE_LOC_STR
] = NULL
;
583 char *str_tmpptr
= NULL
;
589 u_arg arg
[MAX_NO_OF_ARG
] = {{0}};
592 #ifdef DHD_LOG_PRINT_RATE_LIMIT
593 static int log_print_count
= 0;
594 static uint64 ts0
= 0;
596 #endif /* DHD_LOG_PRINT_RATE_LIMIT */
600 #ifdef DHD_LOG_PRINT_RATE_LIMIT
602 ts0
= OSL_SYSUPTIME_US();
604 ts1
= OSL_SYSUPTIME_US();
606 if (((ts1
- ts0
) <= LOG_PRINT_THRESH
) && (log_print_count
>= MAX_LOG_PRINT_COUNT
)) {
607 log_print_threshold
= 1;
610 DHD_ERROR(("%s: Log print water mark is reached,"
611 " console logs are dumped only to debug_dump file\n", __FUNCTION__
));
612 } else if ((ts1
- ts0
) > LOG_PRINT_THRESH
) {
613 log_print_threshold
= 0;
618 #endif /* DHD_LOG_PRINT_RATE_LIMIT */
619 /* print the message out in a logprint */
620 if ((control_logtrace
== LOGTRACE_RAW_FMT
) || !(raw_event
->fmts
)) {
622 log_level
= dhdp
->dbg
->dbg_rings
[FW_VERBOSE_RING_ID
].log_level
;
623 for (id
= 0; id
< ARRAYSIZE(fw_verbose_level_map
); id
++) {
624 if ((fw_verbose_level_map
[id
].tag
== plog_hdr
->tag
) &&
625 (fw_verbose_level_map
[id
].log_level
> log_level
))
629 if (plog_hdr
->binary_payload
) {
630 DHD_ECNTR_LOG(("%d.%d EL:tag=%d len=%d fmt=0x%x",
631 (uint32
)(log_ptr
[plog_hdr
->count
- 1] / EL_MSEC_PER_SEC
),
632 (uint32
)(log_ptr
[plog_hdr
->count
- 1] % EL_MSEC_PER_SEC
),
635 plog_hdr
->fmt_num_raw
));
637 for (count
= 0; count
< (plog_hdr
->count
- 1); count
++) {
638 /* XXX: skip first line feed in case count 0 */
639 if (count
&& (count
% LOG_PRINT_CNT_MAX
== 0)) {
640 DHD_ECNTR_LOG(("\n\t%08x", log_ptr
[count
]));
642 DHD_ECNTR_LOG((" %08x", log_ptr
[count
]));
645 DHD_ECNTR_LOG(("\n"));
648 bcm_binit(&b
, fmtstr_loc_buf
, FMTSTR_SIZE
);
649 /* XXX: The 'hdr->count - 1' is dongle time */
650 bcm_bprintf(&b
, "%06d.%03d EL:%s:%u:%u %d %d 0x%x",
651 (uint32
)(log_ptr
[plog_hdr
->count
- 1] / EL_MSEC_PER_SEC
),
652 (uint32
)(log_ptr
[plog_hdr
->count
- 1] % EL_MSEC_PER_SEC
),
653 EL_PARSE_VER
, logset
, block
,
656 plog_hdr
->fmt_num_raw
);
657 for (count
= 0; count
< (plog_hdr
->count
- 1); count
++) {
658 bcm_bprintf(&b
, " %x", log_ptr
[count
]);
661 /* ensure preserve fw logs go to debug_dump only in case of customer4 */
662 if (logset
< dhdp
->event_log_max_sets
&&
663 ((0x01u
<< logset
) & dhdp
->logset_prsrv_mask
)) {
664 DHD_PRSRV_MEM(("%s\n", b
.origbuf
));
666 DHD_FWLOG(("%s\n", b
.origbuf
));
667 #ifdef DHD_LOG_PRINT_RATE_LIMIT
669 #endif /* DHD_LOG_PRINT_RATE_LIMIT */
675 str_buf
= MALLOCZ(dhdp
->osh
, (MAX_NO_OF_ARG
* SIZE_LOC_STR
));
677 DHD_ERROR(("%s: malloc failed str_buf\n", __FUNCTION__
));
681 if ((plog_hdr
->fmt_num
) < raw_event
->num_fmts
) {
682 if (plog_hdr
->tag
== EVENT_LOG_TAG_MSCHPROFILE
) {
683 snprintf(fmtstr_loc_buf
, FMTSTR_SIZE
, "%s",
684 raw_event
->fmts
[plog_hdr
->fmt_num
]);
687 snprintf(fmtstr_loc_buf
, FMTSTR_SIZE
, "CONSOLE_E:%u:%u %06d.%03d %s",
689 (uint32
)(log_ptr
[plog_hdr
->count
- 1] / EL_MSEC_PER_SEC
),
690 (uint32
)(log_ptr
[plog_hdr
->count
- 1] % EL_MSEC_PER_SEC
),
691 raw_event
->fmts
[plog_hdr
->fmt_num
]);
693 c_ptr
= fmtstr_loc_buf
;
695 /* for ecounters, don't print the error as it will flood */
696 if ((plog_hdr
->fmt_num
!= DHD_OW_BI_EVENT_FMT_NUM
) &&
697 (plog_hdr
->fmt_num
!= DHD_TW_BI_EVENT_FMT_NUM
)) {
698 DHD_ERROR(("%s: fmt number: 0x%x out of range\n",
699 __FUNCTION__
, plog_hdr
->fmt_num
));
701 DHD_INFO(("%s: fmt number: 0x%x out of range\n",
702 __FUNCTION__
, plog_hdr
->fmt_num
));
708 if (plog_hdr
->count
> MAX_NO_OF_ARG
) {
709 DHD_ERROR(("%s: plog_hdr->count(%d) out of range\n",
710 __FUNCTION__
, plog_hdr
->count
));
714 /* print the format string which will be needed for debugging incorrect formats */
715 DHD_INFO(("%s: fmtstr_loc_buf = %s\n", __FUNCTION__
, fmtstr_loc_buf
));
717 /* Replace all %p to %x to handle 32 bit %p */
718 replace_percent_p_to_x(fmtstr_loc_buf
);
720 for (count
= 0; count
< (plog_hdr
->count
- 1); count
++) {
722 if ((c_ptr
= bcmstrstr(c_ptr
, "%")) != NULL
)
726 if (check_valid_string_format(c_ptr
)) {
727 if ((raw_event
->raw_sstr
) &&
728 ((log_ptr
[count
] > raw_event
->rodata_start
) &&
729 (log_ptr
[count
] < raw_event
->rodata_end
))) {
730 /* ram static string */
731 addr
= log_ptr
[count
] - raw_event
->rodata_start
;
732 str_tmpptr
= raw_event
->raw_sstr
+ addr
;
733 memcpy(str_buf
[count
], str_tmpptr
,
735 str_buf
[count
][SIZE_LOC_STR
-1] = '\0';
736 arg
[count
].addr
= str_buf
[count
];
737 } else if ((raw_event
->rom_raw_sstr
) &&
739 raw_event
->rom_rodata_start
) &&
741 raw_event
->rom_rodata_end
))) {
742 /* rom static string */
743 addr
= log_ptr
[count
] - raw_event
->rom_rodata_start
;
744 str_tmpptr
= raw_event
->rom_raw_sstr
+ addr
;
745 memcpy(str_buf
[count
], str_tmpptr
,
747 str_buf
[count
][SIZE_LOC_STR
-1] = '\0';
748 arg
[count
].addr
= str_buf
[count
];
752 * No data for static string.
753 * So store all string's address as string.
755 snprintf(str_buf
[count
], SIZE_LOC_STR
,
756 "(s)0x%x", log_ptr
[count
]);
757 arg
[count
].addr
= str_buf
[count
];
759 } else if (check_valid_non_string_format(c_ptr
)) {
760 /* Other than string format */
761 arg
[count
].val
= log_ptr
[count
];
763 /* There is nothing copied after % or improper format specifier
764 * after current %, because of not enough buffer size for complete
765 * copy of original fmt string.
766 * This is causing error mentioned below.
767 * Error: "Please remove unsupported %\x00 in format string"
768 * error(lib/vsprintf.c:1900 format_decode+0x3bc/0x470).
769 * Refer to JIRA: SWWLAN-200629 for detailed info.
771 * Terminate the string at current .
779 /* ensure preserve fw logs go to debug_dump only in case of customer4 */
780 if (logset
< dhdp
->event_log_max_sets
&&
781 ((0x01u
<< logset
) & dhdp
->logset_prsrv_mask
)) {
782 DHD_PRSRV_MEM((fmtstr_loc_buf
, arg
[0], arg
[1], arg
[2], arg
[3],
783 arg
[4], arg
[5], arg
[6], arg
[7], arg
[8], arg
[9], arg
[10],
784 arg
[11], arg
[12], arg
[13], arg
[14], arg
[15]));
786 DHD_FWLOG((fmtstr_loc_buf
, arg
[0], arg
[1], arg
[2], arg
[3],
787 arg
[4], arg
[5], arg
[6], arg
[7], arg
[8], arg
[9], arg
[10],
788 arg
[11], arg
[12], arg
[13], arg
[14], arg
[15]));
789 #ifdef DHD_LOG_PRINT_RATE_LIMIT
791 #endif /* DHD_LOG_PRINT_RATE_LIMIT */
795 MFREE(dhdp
->osh
, str_buf
, (MAX_NO_OF_ARG
* SIZE_LOC_STR
));
799 dhd_dbg_msgtrace_log_parser(dhd_pub_t
*dhdp
, void *event_data
,
800 void *raw_event_ptr
, uint datalen
, bool msgtrace_hdr_present
,
801 uint32 msgtrace_seqnum
)
804 char *data
, *tmpdata
;
805 const uint32 log_hdr_len
= sizeof(event_log_hdr_t
);
807 static uint32 seqnum_prev
= 0;
808 event_log_hdr_t
*log_hdr
;
809 bool msg_processed
= FALSE
;
810 prcd_event_log_hdr_t prcd_log_hdr
;
811 prcd_event_log_hdr_t
*plog_hdr
;
812 dll_t list_head
, *cur
;
813 loglist_item_t
*log_item
;
814 dhd_dbg_ring_entry_t msg_hdr
;
816 struct tracelog_header
*logentry_header
;
817 uint ring_data_len
= 0;
818 bool ecntr_pushed
= FALSE
;
819 bool rtt_pushed
= FALSE
;
820 bool dll_inited
= FALSE
;
823 bool event_log_max_sets_queried
;
824 uint32 event_log_max_sets
;
825 uint min_expected_len
= 0;
828 BCM_REFERENCE(ecntr_pushed
);
829 BCM_REFERENCE(rtt_pushed
);
830 BCM_REFERENCE(len_chk
);
832 /* store event_logset_queried and event_log_max_sets in local variables
833 * to avoid race conditions as they were set from different contexts(preinit)
835 event_log_max_sets_queried
= dhdp
->event_log_max_sets_queried
;
836 /* Make sure queried is read first with wmb and then max_sets,
837 * as it is done in reverse order during preinit ioctls.
840 event_log_max_sets
= dhdp
->event_log_max_sets
;
842 if (msgtrace_hdr_present
)
843 min_expected_len
= (MSGTRACE_HDRLEN
+ EVENT_LOG_BLOCK_LEN
);
845 min_expected_len
= EVENT_LOG_BLOCK_LEN
;
847 /* log trace event consists of:
849 * event log block header
852 if (!event_data
|| (datalen
<= min_expected_len
)) {
853 DHD_ERROR(("%s: Not processing due to invalid event_data : %p or length : %d\n",
854 __FUNCTION__
, event_data
, datalen
));
855 if (event_data
&& msgtrace_hdr_present
) {
856 prhex("event_data dump", event_data
, datalen
);
857 tmpdata
= (char *)event_data
+ MSGTRACE_HDRLEN
;
859 DHD_ERROR(("EVENT_LOG_HDR[0x%x]: Set: 0x%08x length = %d\n",
860 ltoh16(*((uint16
*)(tmpdata
+2))),
861 ltoh32(*((uint32
*)(tmpdata
+ 4))),
862 ltoh16(*((uint16
*)(tmpdata
)))));
864 } else if (!event_data
) {
865 DHD_ERROR(("%s: event_data is NULL, cannot dump prhex\n", __FUNCTION__
));
871 if (msgtrace_hdr_present
) {
872 hdr
= (msgtrace_hdr_t
*)event_data
;
873 data
= (char *)event_data
+ MSGTRACE_HDRLEN
;
874 datalen
-= MSGTRACE_HDRLEN
;
875 msgtrace_seqnum
= ntoh32(hdr
->seqnum
);
877 data
= (char *)event_data
;
880 if (dhd_dbg_msgtrace_seqchk(&seqnum_prev
, msgtrace_seqnum
))
883 /* Save the whole message to event log ring */
884 memset(&msg_hdr
, 0, sizeof(dhd_dbg_ring_entry_t
));
885 logbuf
= VMALLOC(dhdp
->osh
, sizeof(*logentry_header
) + datalen
);
888 logentry_header
= (struct tracelog_header
*)logbuf
;
889 logentry_header
->magic_num
= TRACE_LOG_MAGIC_NUMBER
;
890 logentry_header
->buf_size
= datalen
;
891 logentry_header
->seq_num
= msgtrace_seqnum
;
892 msg_hdr
.type
= DBG_RING_ENTRY_DATA_TYPE
;
894 ring_data_len
= datalen
+ sizeof(*logentry_header
);
896 if ((sizeof(*logentry_header
) + datalen
) > PAYLOAD_MAX_LEN
) {
897 DHD_ERROR(("%s:Payload len=%u exceeds max len\n", __FUNCTION__
,
898 ((uint
)sizeof(*logentry_header
) + datalen
)));
902 msg_hdr
.len
= sizeof(*logentry_header
) + datalen
;
903 memcpy(logbuf
+ sizeof(*logentry_header
), data
, datalen
);
904 DHD_DBGIF(("%s: datalen %d %d\n", __FUNCTION__
, msg_hdr
.len
, datalen
));
905 dhd_dbg_push_to_ring(dhdp
, FW_VERBOSE_RING_ID
, &msg_hdr
, logbuf
);
907 /* Print sequence number, originating set and length of received
908 * event log buffer. Refer to event log buffer structure in
911 DHD_MSGTRACE_LOG(("EVENT_LOG_HDR[0x%x]: Set: 0x%08x length = %d\n",
912 ltoh16(*((uint16
*)(data
+2))), ltoh32(*((uint32
*)(data
+ 4))),
913 ltoh16(*((uint16
*)(data
)))));
915 logset
= ltoh32(*((uint32
*)(data
+ 4)));
917 if (logset
>= event_log_max_sets
) {
918 DHD_ERROR(("%s logset: %d max: %d out of range queried: %d\n",
919 __FUNCTION__
, logset
, event_log_max_sets
, event_log_max_sets_queried
));
920 #ifdef DHD_FW_COREDUMP
921 if (event_log_max_sets_queried
) {
922 DHD_ERROR(("%s: collect socram for DUMP_TYPE_LOGSET_BEYOND_RANGE\n",
924 dhdp
->memdump_type
= DUMP_TYPE_LOGSET_BEYOND_RANGE
;
925 dhd_bus_mem_dump(dhdp
);
927 #endif /* DHD_FW_COREDUMP */
930 block
= ltoh16(*((uint16
*)(data
+ 2)));
932 data
+= EVENT_LOG_BLOCK_HDRLEN
;
933 datalen
-= EVENT_LOG_BLOCK_HDRLEN
;
935 /* start parsing from the tail of packet
936 * Sameple format of a meessage
937 * 001d3c54 00000064 00000064 001d3c54 001dba08 035d6ce1 0c540639
938 * 001d3c54 00000064 00000064 035d6d89 0c580439
939 * 0x0c580439 -- 39 is tag, 04 is count, 580c is format number
940 * all these uint32 values comes in reverse order as group as EL data
941 * while decoding we can only parse from last to first
943 * |----(payload and maybe more logs)----|event_log_hdr_t|
946 dll_init(&list_head
);
949 while (datalen
> log_hdr_len
) {
950 log_hdr
= (event_log_hdr_t
*)(data
+ datalen
- log_hdr_len
);
951 memset(&prcd_log_hdr
, 0, sizeof(prcd_log_hdr
));
952 if (!dhd_dbg_process_event_log_hdr(log_hdr
, &prcd_log_hdr
)) {
953 DHD_ERROR(("%s: Error while parsing event log header\n",
957 /* skip zero padding at end of frame */
958 if (prcd_log_hdr
.tag
== EVENT_LOG_TAG_NULL
) {
959 datalen
-= log_hdr_len
;
962 /* Check argument count (for non-ecounter events only),
963 * any event log should contain at least
964 * one argument (4 bytes) for arm cycle count and up to 16
965 * arguments except EVENT_LOG_TAG_STATS which could use the
966 * whole payload of 256 words
968 if (prcd_log_hdr
.count
== 0) {
971 /* Both tag_stats and proxd are binary payloads so skip
972 * argument count check for these.
974 if ((prcd_log_hdr
.tag
!= EVENT_LOG_TAG_STATS
) &&
975 (prcd_log_hdr
.tag
!= EVENT_LOG_TAG_PROXD_SAMPLE_COLLECT
) &&
976 (prcd_log_hdr
.tag
!= EVENT_LOG_TAG_ROAM_ENHANCED_LOG
) &&
977 (prcd_log_hdr
.count
> MAX_NO_OF_ARG
)) {
981 log_pyld_len
= (prcd_log_hdr
.count
+ prcd_log_hdr
.ext_event_log_hdr
) *
982 DATA_UNIT_FOR_LOG_CNT
;
983 /* log data should not cross the event data boundary */
984 if ((uint32
)((char *)log_hdr
- data
) < log_pyld_len
) {
987 /* skip 4 bytes time stamp packet */
988 if (prcd_log_hdr
.tag
== EVENT_LOG_TAG_TS
||
989 prcd_log_hdr
.tag
== EVENT_LOG_TAG_ENHANCED_TS
) {
990 datalen
-= (log_pyld_len
+ log_hdr_len
);
993 if (!(log_item
= MALLOC(dhdp
->osh
, sizeof(*log_item
)))) {
994 DHD_ERROR(("%s allocating log list item failed\n",
999 log_item
->prcd_log_hdr
.tag
= prcd_log_hdr
.tag
;
1000 log_item
->prcd_log_hdr
.count
= prcd_log_hdr
.count
;
1001 log_item
->prcd_log_hdr
.fmt_num
= prcd_log_hdr
.fmt_num
;
1002 log_item
->prcd_log_hdr
.fmt_num_raw
= prcd_log_hdr
.fmt_num_raw
;
1003 log_item
->prcd_log_hdr
.armcycle
= prcd_log_hdr
.armcycle
;
1004 log_item
->prcd_log_hdr
.log_ptr
= prcd_log_hdr
.log_ptr
;
1005 log_item
->prcd_log_hdr
.payload_len
= prcd_log_hdr
.payload_len
;
1006 log_item
->prcd_log_hdr
.ext_event_log_hdr
= prcd_log_hdr
.ext_event_log_hdr
;
1007 log_item
->prcd_log_hdr
.binary_payload
= prcd_log_hdr
.binary_payload
;
1009 dll_insert(&log_item
->list
, &list_head
);
1010 datalen
-= (log_pyld_len
+ log_hdr_len
);
1013 while (!dll_empty(&list_head
)) {
1014 msg_processed
= FALSE
;
1015 cur
= dll_head_p(&list_head
);
1017 GCC_DIAGNOSTIC_PUSH_SUPPRESS_CAST();
1018 log_item
= (loglist_item_t
*)container_of(cur
, loglist_item_t
, list
);
1019 GCC_DIAGNOSTIC_POP();
1021 plog_hdr
= &log_item
->prcd_log_hdr
;
1022 #if defined(EWP_ECNTRS_LOGGING) && defined(DHD_LOG_DUMP)
1023 /* Ecounter tag can be time_data or log_stats+binary paloaod */
1024 if ((plog_hdr
->tag
== EVENT_LOG_TAG_ECOUNTERS_TIME_DATA
) ||
1025 ((plog_hdr
->tag
== EVENT_LOG_TAG_STATS
) &&
1026 (plog_hdr
->binary_payload
))) {
1027 if (!ecntr_pushed
&& dhd_log_dump_ecntr_enabled()) {
1029 * check msg hdr len before pushing.
1030 * FW msg_hdr.len includes length of event log hdr,
1031 * logentry header and payload.
1033 len_chk
= (sizeof(*logentry_header
) + sizeof(*log_hdr
) +
1034 PAYLOAD_ECNTR_MAX_LEN
);
1035 /* account extended event log header(extended_event_log_hdr) */
1036 if (plog_hdr
->ext_event_log_hdr
) {
1037 len_chk
+= sizeof(*log_hdr
);
1039 if (msg_hdr
.len
> len_chk
) {
1040 DHD_ERROR(("%s: EVENT_LOG_VALIDATION_FAILS: "
1041 "msg_hdr.len=%u, max allowed for ecntrs=%u\n",
1042 __FUNCTION__
, msg_hdr
.len
, len_chk
));
1045 dhd_dbg_ring_push(dhdp
->ecntr_dbg_ring
, &msg_hdr
, logbuf
);
1046 ecntr_pushed
= TRUE
;
1049 #endif /* EWP_ECNTRS_LOGGING && DHD_LOG_DUMP */
1051 if (plog_hdr
->tag
== EVENT_LOG_TAG_ROAM_ENHANCED_LOG
) {
1052 print_roam_enhanced_log(plog_hdr
);
1053 msg_processed
= TRUE
;
1055 #if defined(EWP_RTT_LOGGING) && defined(DHD_LOG_DUMP)
1056 if ((plog_hdr
->tag
== EVENT_LOG_TAG_PROXD_SAMPLE_COLLECT
) &&
1057 plog_hdr
->binary_payload
) {
1058 if (!rtt_pushed
&& dhd_log_dump_rtt_enabled()) {
1060 * check msg hdr len before pushing.
1061 * FW msg_hdr.len includes length of event log hdr,
1062 * logentry header and payload.
1064 len_chk
= (sizeof(*logentry_header
) + sizeof(*log_hdr
) +
1065 PAYLOAD_RTT_MAX_LEN
);
1066 /* account extended event log header(extended_event_log_hdr) */
1067 if (plog_hdr
->ext_event_log_hdr
) {
1068 len_chk
+= sizeof(*log_hdr
);
1070 if (msg_hdr
.len
> len_chk
) {
1071 DHD_ERROR(("%s: EVENT_LOG_VALIDATION_FAILS: "
1072 "msg_hdr.len=%u, max allowed for ecntrs=%u\n",
1073 __FUNCTION__
, msg_hdr
.len
, len_chk
));
1076 dhd_dbg_ring_push(dhdp
->rtt_dbg_ring
, &msg_hdr
, logbuf
);
1080 #endif /* EWP_RTT_LOGGING && DHD_LOG_DUMP */
1082 #if defined(DHD_EVENT_LOG_FILTER)
1083 if (plog_hdr
->tag
== EVENT_LOG_TAG_STATS
) {
1084 dhd_event_log_filter_event_handler(dhdp
, plog_hdr
, plog_hdr
->log_ptr
);
1086 #endif /* DHD_EVENT_LOG_FILTER */
1087 if (!msg_processed
) {
1088 dhd_dbg_verboselog_handler(dhdp
, plog_hdr
, raw_event_ptr
,
1089 logset
, block
, (uint32
*)data
);
1092 MFREE(dhdp
->osh
, log_item
, sizeof(*log_item
));
1095 BCM_REFERENCE(log_hdr
);
1097 while (dll_inited
&& (!dll_empty(&list_head
))) {
1098 cur
= dll_head_p(&list_head
);
1100 GCC_DIAGNOSTIC_PUSH_SUPPRESS_CAST();
1101 log_item
= (loglist_item_t
*)container_of(cur
, loglist_item_t
, list
);
1102 GCC_DIAGNOSTIC_POP();
1105 MFREE(dhdp
->osh
, log_item
, sizeof(*log_item
));
1108 VMFREE(dhdp
->osh
, logbuf
, ring_data_len
);
1110 #else /* !SHOW_LOGTRACE */
1111 static INLINE
void dhd_dbg_verboselog_handler(dhd_pub_t
*dhdp
,
1112 prcd_event_log_hdr_t
*plog_hdr
, void *raw_event_ptr
, uint32 logset
, uint16 block
,
1114 INLINE
void dhd_dbg_msgtrace_log_parser(dhd_pub_t
*dhdp
,
1115 void *event_data
, void *raw_event_ptr
, uint datalen
,
1116 bool msgtrace_hdr_present
, uint32 msgtrace_seqnum
) {};
1117 #endif /* SHOW_LOGTRACE */
1119 dhd_dbg_trace_evnt_handler(dhd_pub_t
*dhdp
, void *event_data
,
1120 void *raw_event_ptr
, uint datalen
)
1122 msgtrace_hdr_t
*hdr
;
1124 hdr
= (msgtrace_hdr_t
*)event_data
;
1126 if (hdr
->version
!= MSGTRACE_VERSION
) {
1127 DHD_DBGIF(("%s unsupported MSGTRACE version, dhd %d, dongle %d\n",
1128 __FUNCTION__
, MSGTRACE_VERSION
, hdr
->version
));
1132 if (hdr
->trace_type
== MSGTRACE_HDR_TYPE_MSG
)
1133 dhd_dbg_msgtrace_msg_parser(event_data
);
1134 else if (hdr
->trace_type
== MSGTRACE_HDR_TYPE_LOG
)
1135 dhd_dbg_msgtrace_log_parser(dhdp
, event_data
, raw_event_ptr
, datalen
, TRUE
, 0);
1139 * dhd_dbg_set_event_log_tag : modify the state of an event log tag
1142 dhd_dbg_set_event_log_tag(dhd_pub_t
*dhdp
, uint16 tag
, uint8 set
)
1144 wl_el_tag_params_t pars
;
1145 char *cmd
= "event_log_tag_control";
1146 char iovbuf
[WLC_IOCTL_SMLEN
] = { 0 };
1149 memset(&pars
, 0, sizeof(pars
));
1152 pars
.flags
= EVENT_LOG_TAG_FLAG_LOG
;
1154 if (!bcm_mkiovar(cmd
, (char *)&pars
, sizeof(pars
), iovbuf
, sizeof(iovbuf
))) {
1155 DHD_ERROR(("%s mkiovar failed\n", __FUNCTION__
));
1159 ret
= dhd_wl_ioctl_cmd(dhdp
, WLC_SET_VAR
, iovbuf
, sizeof(iovbuf
), TRUE
, 0);
1161 DHD_ERROR(("%s set log tag iovar failed %d\n", __FUNCTION__
, ret
));
1166 dhd_dbg_set_configuration(dhd_pub_t
*dhdp
, int ring_id
, int log_level
, int flags
, uint32 threshold
)
1168 dhd_dbg_ring_t
*ring
;
1170 int i
, array_len
= 0;
1171 struct log_level_table
*log_level_tbl
= NULL
;
1172 if (!dhdp
|| !dhdp
->dbg
)
1173 return BCME_BADADDR
;
1175 if (!VALID_RING(ring_id
)) {
1176 DHD_ERROR(("%s : invalid ring_id : %d\n", __FUNCTION__
, ring_id
));
1180 ring
= &dhdp
->dbg
->dbg_rings
[ring_id
];
1181 dhd_dbg_ring_config(ring
, log_level
, threshold
);
1186 if (ring
->id
== FW_VERBOSE_RING_ID
) {
1187 log_level_tbl
= fw_verbose_level_map
;
1188 array_len
= ARRAYSIZE(fw_verbose_level_map
);
1191 for (i
= 0; i
< array_len
; i
++) {
1192 if (log_level
== 0 || (log_level_tbl
[i
].log_level
> log_level
)) {
1193 /* clear the reference per ring */
1194 ref_tag_tbl
[log_level_tbl
[i
].tag
] &= ~(1 << ring_id
);
1196 /* set the reference per ring */
1197 ref_tag_tbl
[log_level_tbl
[i
].tag
] |= (1 << ring_id
);
1199 set
= (ref_tag_tbl
[log_level_tbl
[i
].tag
])? 1 : 0;
1200 DHD_DBGIF(("%s TAG(%s) is %s for the ring(%s)\n", __FUNCTION__
,
1201 log_level_tbl
[i
].desc
, (set
)? "SET" : "CLEAR", ring
->name
));
1202 dhd_dbg_set_event_log_tag(dhdp
, log_level_tbl
[i
].tag
, set
);
1208 __dhd_dbg_get_ring_status(dhd_dbg_ring_t
*ring
, dhd_dbg_ring_status_t
*get_ring_status
)
1210 dhd_dbg_ring_status_t ring_status
;
1214 return BCME_BADADDR
;
1217 bzero(&ring_status
, sizeof(dhd_dbg_ring_status_t
));
1218 RING_STAT_TO_STATUS(ring
, ring_status
);
1219 *get_ring_status
= ring_status
;
1225 * dhd_dbg_get_ring_status : get the ring status from the coresponding ring buffer
1226 * Return: An error code or 0 on success.
1230 dhd_dbg_get_ring_status(dhd_pub_t
*dhdp
, int ring_id
, dhd_dbg_ring_status_t
*dbg_ring_status
)
1235 dhd_dbg_ring_t
*dbg_ring
;
1236 if (!dhdp
|| !dhdp
->dbg
)
1237 return BCME_BADADDR
;
1240 for (id
= DEBUG_RING_ID_INVALID
+ 1; id
< DEBUG_RING_ID_MAX
; id
++) {
1241 dbg_ring
= &dbg
->dbg_rings
[id
];
1242 if (VALID_RING(dbg_ring
->id
) && (dbg_ring
->id
== ring_id
)) {
1243 __dhd_dbg_get_ring_status(dbg_ring
, dbg_ring_status
);
1247 if (!VALID_RING(id
)) {
1248 DHD_ERROR(("%s : cannot find the ring_id : %d\n", __FUNCTION__
, ring_id
));
1249 ret
= BCME_NOTFOUND
;
1254 #ifdef SHOW_LOGTRACE
1256 dhd_dbg_read_ring_into_trace_buf(dhd_dbg_ring_t
*ring
, trace_buf_info_t
*trace_buf_info
)
1258 dhd_dbg_ring_status_t ring_status
;
1261 rlen
= dhd_dbg_ring_pull_single(ring
, trace_buf_info
->buf
, TRACE_LOG_BUF_MAX_SIZE
, TRUE
);
1263 trace_buf_info
->size
= rlen
;
1264 trace_buf_info
->availability
= NEXT_BUF_NOT_AVAIL
;
1266 trace_buf_info
->availability
= BUF_NOT_AVAILABLE
;
1270 __dhd_dbg_get_ring_status(ring
, &ring_status
);
1272 if (ring_status
.written_bytes
!= ring_status
.read_bytes
) {
1273 trace_buf_info
->availability
= NEXT_BUF_AVAIL
;
1276 #endif /* SHOW_LOGTRACE */
1279 * dhd_dbg_find_ring_id : return ring_id based on ring_name
1280 * Return: An invalid ring id for failure or valid ring id on success.
1284 dhd_dbg_find_ring_id(dhd_pub_t
*dhdp
, char *ring_name
)
1288 dhd_dbg_ring_t
*ring
;
1290 if (!dhdp
|| !dhdp
->dbg
)
1291 return BCME_BADADDR
;
1294 for (id
= DEBUG_RING_ID_INVALID
+ 1; id
< DEBUG_RING_ID_MAX
; id
++) {
1295 ring
= &dbg
->dbg_rings
[id
];
1296 if (!strncmp((char *)ring
->name
, ring_name
, sizeof(ring
->name
) - 1))
1303 * dhd_dbg_get_priv : get the private data of dhd dbugability module
1304 * Return : An NULL on failure or valid data address
1307 dhd_dbg_get_priv(dhd_pub_t
*dhdp
)
1309 if (!dhdp
|| !dhdp
->dbg
)
1311 return dhdp
->dbg
->private;
1315 * dhd_dbg_start : start and stop All of Ring buffers
1316 * Return: An error code or 0 on success.
1319 dhd_dbg_start(dhd_pub_t
*dhdp
, bool start
)
1324 dhd_dbg_ring_t
*dbg_ring
;
1329 for (ring_id
= DEBUG_RING_ID_INVALID
+ 1; ring_id
< DEBUG_RING_ID_MAX
; ring_id
++) {
1330 dbg_ring
= &dbg
->dbg_rings
[ring_id
];
1332 if (VALID_RING(dbg_ring
->id
)) {
1333 dhd_dbg_ring_start(dbg_ring
);
1341 * dhd_dbg_send_urgent_evt: send the health check evt to Upper layer
1343 * Return: An error code or 0 on success.
1347 dhd_dbg_send_urgent_evt(dhd_pub_t
*dhdp
, const void *data
, const uint32 len
)
1351 if (!dhdp
|| !dhdp
->dbg
)
1352 return BCME_BADADDR
;
1355 if (dbg
->urgent_notifier
) {
1356 dbg
->urgent_notifier(dhdp
, data
, len
);
1361 #if defined(DBG_PKT_MON) || defined(DHD_PKT_LOGGING)
1363 __dhd_dbg_pkt_hash(uintptr_t pkt
, uint32 pktid
)
1368 __pkt
= ((int)pkt
) >= 0 ? (2 * pkt
) : (-2 * pkt
- 1);
1369 __pktid
= ((int)pktid
) >= 0 ? (2 * pktid
) : (-2 * pktid
- 1);
1371 return (__pkt
>= __pktid
? (__pkt
* __pkt
+ __pkt
+ __pktid
) :
1372 (__pkt
+ __pktid
* __pktid
));
1375 #define __TIMESPEC_TO_US(ts) \
1376 (((uint32)(ts).tv_sec * USEC_PER_SEC) + ((ts).tv_nsec / NSEC_PER_USEC))
1379 __dhd_dbg_driver_ts_usec(void)
1381 struct osl_timespec ts
;
1383 osl_get_monotonic_boottime(&ts
);
1384 return ((uint32
)(__TIMESPEC_TO_US(ts
)));
1388 __dhd_dbg_map_tx_status_to_pkt_fate(uint16 status
)
1390 wifi_tx_packet_fate pkt_fate
;
1393 case WLFC_CTL_PKTFLAG_DISCARD
:
1394 pkt_fate
= TX_PKT_FATE_ACKED
;
1396 case WLFC_CTL_PKTFLAG_D11SUPPRESS
:
1397 /* intensional fall through */
1398 case WLFC_CTL_PKTFLAG_WLSUPPRESS
:
1399 pkt_fate
= TX_PKT_FATE_FW_QUEUED
;
1401 case WLFC_CTL_PKTFLAG_TOSSED_BYWLC
:
1402 pkt_fate
= TX_PKT_FATE_FW_DROP_INVALID
;
1404 case WLFC_CTL_PKTFLAG_DISCARD_NOACK
:
1405 pkt_fate
= TX_PKT_FATE_SENT
;
1407 case WLFC_CTL_PKTFLAG_EXPIRED
:
1408 pkt_fate
= TX_PKT_FATE_FW_DROP_EXPTIME
;
1410 case WLFC_CTL_PKTFLAG_MKTFREE
:
1411 pkt_fate
= TX_PKT_FATE_FW_PKT_FREE
;
1414 pkt_fate
= TX_PKT_FATE_FW_DROP_OTHER
;
1420 #endif /* DBG_PKT_MON || DHD_PKT_LOGGING */
1424 __dhd_dbg_free_tx_pkts(dhd_pub_t
*dhdp
, dhd_dbg_tx_info_t
*tx_pkts
,
1430 while ((count
< pkt_count
) && tx_pkts
) {
1431 if (tx_pkts
->info
.pkt
) {
1432 PKTFREE(dhdp
->osh
, tx_pkts
->info
.pkt
, TRUE
);
1442 __dhd_dbg_free_rx_pkts(dhd_pub_t
*dhdp
, dhd_dbg_rx_info_t
*rx_pkts
,
1448 while ((count
< pkt_count
) && rx_pkts
) {
1449 if (rx_pkts
->info
.pkt
) {
1450 PKTFREE(dhdp
->osh
, rx_pkts
->info
.pkt
, TRUE
);
1460 __dhd_dbg_dump_pkt_info(dhd_pub_t
*dhdp
, dhd_dbg_pkt_info_t
*info
)
1462 if (DHD_PKT_MON_DUMP_ON()) {
1463 DHD_PKT_MON(("payload type = %d\n", info
->payload_type
));
1464 DHD_PKT_MON(("driver ts = %u\n", info
->driver_ts
));
1465 DHD_PKT_MON(("firmware ts = %u\n", info
->firmware_ts
));
1466 DHD_PKT_MON(("packet hash = %u\n", info
->pkt_hash
));
1467 DHD_PKT_MON(("packet length = %zu\n", info
->pkt_len
));
1468 DHD_PKT_MON(("packet address = %p\n", info
->pkt
));
1469 DHD_PKT_MON(("packet data = \n"));
1470 if (DHD_PKT_MON_ON()) {
1471 prhex(NULL
, PKTDATA(dhdp
->osh
, info
->pkt
), info
->pkt_len
);
1477 __dhd_dbg_dump_tx_pkt_info(dhd_pub_t
*dhdp
, dhd_dbg_tx_info_t
*tx_pkt
,
1480 if (DHD_PKT_MON_DUMP_ON()) {
1481 DHD_PKT_MON(("\nTX (count: %d)\n", ++count
));
1482 DHD_PKT_MON(("packet fate = %d\n", tx_pkt
->fate
));
1483 __dhd_dbg_dump_pkt_info(dhdp
, &tx_pkt
->info
);
1488 __dhd_dbg_dump_rx_pkt_info(dhd_pub_t
*dhdp
, dhd_dbg_rx_info_t
*rx_pkt
,
1491 if (DHD_PKT_MON_DUMP_ON()) {
1492 DHD_PKT_MON(("\nRX (count: %d)\n", ++count
));
1493 DHD_PKT_MON(("packet fate = %d\n", rx_pkt
->fate
));
1494 __dhd_dbg_dump_pkt_info(dhdp
, &rx_pkt
->info
);
1499 dhd_dbg_attach_pkt_monitor(dhd_pub_t
*dhdp
,
1500 dbg_mon_tx_pkts_t tx_pkt_mon
,
1501 dbg_mon_tx_status_t tx_status_mon
,
1502 dbg_mon_rx_pkts_t rx_pkt_mon
)
1505 dhd_dbg_tx_report_t
*tx_report
= NULL
;
1506 dhd_dbg_rx_report_t
*rx_report
= NULL
;
1507 dhd_dbg_tx_info_t
*tx_pkts
= NULL
;
1508 dhd_dbg_rx_info_t
*rx_pkts
= NULL
;
1509 dhd_dbg_pkt_mon_state_t tx_pkt_state
;
1510 dhd_dbg_pkt_mon_state_t tx_status_state
;
1511 dhd_dbg_pkt_mon_state_t rx_pkt_state
;
1514 unsigned long flags
;
1516 if (!dhdp
|| !dhdp
->dbg
) {
1517 DHD_PKT_MON(("%s(): dhdp=%p, dhdp->dbg=%p\n", __FUNCTION__
,
1518 dhdp
, (dhdp
? dhdp
->dbg
: NULL
)));
1522 DHD_PKT_MON_LOCK(dhdp
->dbg
->pkt_mon_lock
, flags
);
1523 tx_pkt_state
= dhdp
->dbg
->pkt_mon
.tx_pkt_state
;
1524 tx_status_state
= dhdp
->dbg
->pkt_mon
.tx_pkt_state
;
1525 rx_pkt_state
= dhdp
->dbg
->pkt_mon
.rx_pkt_state
;
1527 if (PKT_MON_ATTACHED(tx_pkt_state
) || PKT_MON_ATTACHED(tx_status_state
) ||
1528 PKT_MON_ATTACHED(rx_pkt_state
)) {
1529 DHD_PKT_MON(("%s(): packet monitor is already attached, "
1530 "tx_pkt_state=%d, tx_status_state=%d, rx_pkt_state=%d\n",
1531 __FUNCTION__
, tx_pkt_state
, tx_status_state
, rx_pkt_state
));
1532 DHD_PKT_MON_UNLOCK(dhdp
->dbg
->pkt_mon_lock
, flags
);
1533 /* return success as the intention was to initialize packet monitor */
1537 /* allocate and initialize tx packet monitoring */
1538 alloc_len
= sizeof(*tx_report
);
1539 tx_report
= (dhd_dbg_tx_report_t
*)MALLOCZ(dhdp
->osh
, alloc_len
);
1540 if (unlikely(!tx_report
)) {
1541 DHD_ERROR(("%s(): could not allocate memory for - "
1542 "dhd_dbg_tx_report_t\n", __FUNCTION__
));
1547 alloc_len
= (sizeof(*tx_pkts
) * MAX_FATE_LOG_LEN
);
1548 tx_pkts
= (dhd_dbg_tx_info_t
*)MALLOCZ(dhdp
->osh
, alloc_len
);
1549 if (unlikely(!tx_pkts
)) {
1550 DHD_ERROR(("%s(): could not allocate memory for - "
1551 "dhd_dbg_tx_info_t\n", __FUNCTION__
));
1555 dhdp
->dbg
->pkt_mon
.tx_report
= tx_report
;
1556 dhdp
->dbg
->pkt_mon
.tx_report
->tx_pkts
= tx_pkts
;
1557 dhdp
->dbg
->pkt_mon
.tx_pkt_mon
= tx_pkt_mon
;
1558 dhdp
->dbg
->pkt_mon
.tx_status_mon
= tx_status_mon
;
1559 dhdp
->dbg
->pkt_mon
.tx_pkt_state
= PKT_MON_ATTACHED
;
1560 dhdp
->dbg
->pkt_mon
.tx_status_state
= PKT_MON_ATTACHED
;
1562 /* allocate and initialze rx packet monitoring */
1563 alloc_len
= sizeof(*rx_report
);
1564 rx_report
= (dhd_dbg_rx_report_t
*)MALLOCZ(dhdp
->osh
, alloc_len
);
1565 if (unlikely(!rx_report
)) {
1566 DHD_ERROR(("%s(): could not allocate memory for - "
1567 "dhd_dbg_rx_report_t\n", __FUNCTION__
));
1572 alloc_len
= (sizeof(*rx_pkts
) * MAX_FATE_LOG_LEN
);
1573 rx_pkts
= (dhd_dbg_rx_info_t
*)MALLOCZ(dhdp
->osh
, alloc_len
);
1574 if (unlikely(!rx_pkts
)) {
1575 DHD_ERROR(("%s(): could not allocate memory for - "
1576 "dhd_dbg_rx_info_t\n", __FUNCTION__
));
1580 dhdp
->dbg
->pkt_mon
.rx_report
= rx_report
;
1581 dhdp
->dbg
->pkt_mon
.rx_report
->rx_pkts
= rx_pkts
;
1582 dhdp
->dbg
->pkt_mon
.rx_pkt_mon
= rx_pkt_mon
;
1583 dhdp
->dbg
->pkt_mon
.rx_pkt_state
= PKT_MON_ATTACHED
;
1585 DHD_PKT_MON_UNLOCK(dhdp
->dbg
->pkt_mon_lock
, flags
);
1586 DHD_PKT_MON(("%s(): packet monitor attach succeeded\n", __FUNCTION__
));
1590 /* tx packet monitoring */
1592 alloc_len
= (sizeof(*tx_pkts
) * MAX_FATE_LOG_LEN
);
1593 MFREE(dhdp
->osh
, tx_pkts
, alloc_len
);
1596 alloc_len
= sizeof(*tx_report
);
1597 MFREE(dhdp
->osh
, tx_report
, alloc_len
);
1599 dhdp
->dbg
->pkt_mon
.tx_report
= NULL
;
1600 dhdp
->dbg
->pkt_mon
.tx_report
->tx_pkts
= NULL
;
1601 dhdp
->dbg
->pkt_mon
.tx_pkt_mon
= NULL
;
1602 dhdp
->dbg
->pkt_mon
.tx_status_mon
= NULL
;
1603 dhdp
->dbg
->pkt_mon
.tx_pkt_state
= PKT_MON_DETACHED
;
1604 dhdp
->dbg
->pkt_mon
.tx_status_state
= PKT_MON_DETACHED
;
1606 /* rx packet monitoring */
1608 alloc_len
= (sizeof(*rx_pkts
) * MAX_FATE_LOG_LEN
);
1609 MFREE(dhdp
->osh
, rx_pkts
, alloc_len
);
1612 alloc_len
= sizeof(*rx_report
);
1613 MFREE(dhdp
->osh
, rx_report
, alloc_len
);
1615 dhdp
->dbg
->pkt_mon
.rx_report
= NULL
;
1616 dhdp
->dbg
->pkt_mon
.rx_report
->rx_pkts
= NULL
;
1617 dhdp
->dbg
->pkt_mon
.rx_pkt_mon
= NULL
;
1618 dhdp
->dbg
->pkt_mon
.rx_pkt_state
= PKT_MON_DETACHED
;
1620 DHD_PKT_MON_UNLOCK(dhdp
->dbg
->pkt_mon_lock
, flags
);
1621 DHD_ERROR(("%s(): packet monitor attach failed\n", __FUNCTION__
));
1626 dhd_dbg_start_pkt_monitor(dhd_pub_t
*dhdp
)
1628 dhd_dbg_tx_report_t
*tx_report
;
1629 dhd_dbg_rx_report_t
*rx_report
;
1630 dhd_dbg_pkt_mon_state_t tx_pkt_state
;
1631 dhd_dbg_pkt_mon_state_t tx_status_state
;
1632 dhd_dbg_pkt_mon_state_t rx_pkt_state
;
1633 unsigned long flags
;
1635 if (!dhdp
|| !dhdp
->dbg
) {
1636 DHD_PKT_MON(("%s(): dhdp=%p, dhdp->dbg=%p\n", __FUNCTION__
,
1637 dhdp
, (dhdp
? dhdp
->dbg
: NULL
)));
1641 DHD_PKT_MON_LOCK(dhdp
->dbg
->pkt_mon_lock
, flags
);
1642 tx_pkt_state
= dhdp
->dbg
->pkt_mon
.tx_pkt_state
;
1643 tx_status_state
= dhdp
->dbg
->pkt_mon
.tx_status_state
;
1644 rx_pkt_state
= dhdp
->dbg
->pkt_mon
.rx_pkt_state
;
1646 if (PKT_MON_DETACHED(tx_pkt_state
) || PKT_MON_DETACHED(tx_status_state
) ||
1647 PKT_MON_DETACHED(rx_pkt_state
)) {
1648 DHD_PKT_MON(("%s(): packet monitor is not yet enabled, "
1649 "tx_pkt_state=%d, tx_status_state=%d, rx_pkt_state=%d\n",
1650 __FUNCTION__
, tx_pkt_state
, tx_status_state
, rx_pkt_state
));
1651 DHD_PKT_MON_UNLOCK(dhdp
->dbg
->pkt_mon_lock
, flags
);
1655 dhdp
->dbg
->pkt_mon
.tx_pkt_state
= PKT_MON_STARTING
;
1656 dhdp
->dbg
->pkt_mon
.tx_status_state
= PKT_MON_STARTING
;
1657 dhdp
->dbg
->pkt_mon
.rx_pkt_state
= PKT_MON_STARTING
;
1659 tx_report
= dhdp
->dbg
->pkt_mon
.tx_report
;
1660 rx_report
= dhdp
->dbg
->pkt_mon
.rx_report
;
1661 if (!tx_report
|| !rx_report
) {
1662 DHD_PKT_MON(("%s(): tx_report=%p, rx_report=%p\n",
1663 __FUNCTION__
, tx_report
, rx_report
));
1664 DHD_PKT_MON_UNLOCK(dhdp
->dbg
->pkt_mon_lock
, flags
);
1668 tx_pkt_state
= dhdp
->dbg
->pkt_mon
.tx_pkt_state
;
1669 tx_status_state
= dhdp
->dbg
->pkt_mon
.tx_status_state
;
1670 rx_pkt_state
= dhdp
->dbg
->pkt_mon
.rx_pkt_state
;
1672 /* Safe to free packets as state pkt_state is STARTING */
1673 __dhd_dbg_free_tx_pkts(dhdp
, tx_report
->tx_pkts
, tx_report
->pkt_pos
);
1675 __dhd_dbg_free_rx_pkts(dhdp
, rx_report
->rx_pkts
, rx_report
->pkt_pos
);
1677 /* reset array postion */
1678 tx_report
->pkt_pos
= 0;
1679 tx_report
->status_pos
= 0;
1680 dhdp
->dbg
->pkt_mon
.tx_pkt_state
= PKT_MON_STARTED
;
1681 dhdp
->dbg
->pkt_mon
.tx_status_state
= PKT_MON_STARTED
;
1683 rx_report
->pkt_pos
= 0;
1684 dhdp
->dbg
->pkt_mon
.rx_pkt_state
= PKT_MON_STARTED
;
1685 DHD_PKT_MON_UNLOCK(dhdp
->dbg
->pkt_mon_lock
, flags
);
1687 DHD_PKT_MON(("%s(): packet monitor started\n", __FUNCTION__
));
1692 dhd_dbg_monitor_tx_pkts(dhd_pub_t
*dhdp
, void *pkt
, uint32 pktid
)
1694 dhd_dbg_tx_report_t
*tx_report
;
1695 dhd_dbg_tx_info_t
*tx_pkts
;
1696 dhd_dbg_pkt_mon_state_t tx_pkt_state
;
1697 uint32 pkt_hash
, driver_ts
;
1699 unsigned long flags
;
1701 if (!dhdp
|| !dhdp
->dbg
) {
1702 DHD_PKT_MON(("%s(): dhdp=%p, dhdp->dbg=%p\n", __FUNCTION__
,
1703 dhdp
, (dhdp
? dhdp
->dbg
: NULL
)));
1707 DHD_PKT_MON_LOCK(dhdp
->dbg
->pkt_mon_lock
, flags
);
1708 tx_pkt_state
= dhdp
->dbg
->pkt_mon
.tx_pkt_state
;
1709 if (PKT_MON_STARTED(tx_pkt_state
)) {
1710 tx_report
= dhdp
->dbg
->pkt_mon
.tx_report
;
1711 pkt_pos
= tx_report
->pkt_pos
;
1713 if (!PKT_MON_PKT_FULL(pkt_pos
)) {
1714 tx_pkts
= tx_report
->tx_pkts
;
1715 pkt_hash
= __dhd_dbg_pkt_hash((uintptr_t)pkt
, pktid
);
1716 driver_ts
= __dhd_dbg_driver_ts_usec();
1718 tx_pkts
[pkt_pos
].info
.pkt
= PKTDUP(dhdp
->osh
, pkt
);
1719 tx_pkts
[pkt_pos
].info
.pkt_len
= PKTLEN(dhdp
->osh
, pkt
);
1720 tx_pkts
[pkt_pos
].info
.pkt_hash
= pkt_hash
;
1721 tx_pkts
[pkt_pos
].info
.driver_ts
= driver_ts
;
1722 tx_pkts
[pkt_pos
].info
.firmware_ts
= 0U;
1723 tx_pkts
[pkt_pos
].info
.payload_type
= FRAME_TYPE_ETHERNET_II
;
1724 tx_pkts
[pkt_pos
].fate
= TX_PKT_FATE_DRV_QUEUED
;
1726 tx_report
->pkt_pos
++;
1728 dhdp
->dbg
->pkt_mon
.tx_pkt_state
= PKT_MON_STOPPED
;
1729 DHD_PKT_MON(("%s(): tx pkt logging stopped, reached "
1730 "max limit\n", __FUNCTION__
));
1734 DHD_PKT_MON_UNLOCK(dhdp
->dbg
->pkt_mon_lock
, flags
);
1739 dhd_dbg_monitor_tx_status(dhd_pub_t
*dhdp
, void *pkt
, uint32 pktid
,
1742 dhd_dbg_tx_report_t
*tx_report
;
1743 dhd_dbg_tx_info_t
*tx_pkt
;
1744 dhd_dbg_pkt_mon_state_t tx_status_state
;
1745 wifi_tx_packet_fate pkt_fate
;
1746 uint32 pkt_hash
, temp_hash
;
1747 uint16 pkt_pos
, status_pos
;
1750 unsigned long flags
;
1752 if (!dhdp
|| !dhdp
->dbg
) {
1753 DHD_PKT_MON(("%s(): dhdp=%p, dhdp->dbg=%p\n", __FUNCTION__
,
1754 dhdp
, (dhdp
? dhdp
->dbg
: NULL
)));
1758 DHD_PKT_MON_LOCK(dhdp
->dbg
->pkt_mon_lock
, flags
);
1759 tx_status_state
= dhdp
->dbg
->pkt_mon
.tx_status_state
;
1760 if (PKT_MON_STARTED(tx_status_state
)) {
1761 tx_report
= dhdp
->dbg
->pkt_mon
.tx_report
;
1762 pkt_pos
= tx_report
->pkt_pos
;
1763 status_pos
= tx_report
->status_pos
;
1765 if (!PKT_MON_STATUS_FULL(pkt_pos
, status_pos
)) {
1766 pkt_hash
= __dhd_dbg_pkt_hash((uintptr_t)pkt
, pktid
);
1767 pkt_fate
= __dhd_dbg_map_tx_status_to_pkt_fate(status
);
1769 /* best bet (in-order tx completion) */
1771 tx_pkt
= (((dhd_dbg_tx_info_t
*)tx_report
->tx_pkts
) + status_pos
);
1772 while ((count
< pkt_pos
) && tx_pkt
) {
1773 temp_hash
= tx_pkt
->info
.pkt_hash
;
1774 if (temp_hash
== pkt_hash
) {
1775 tx_pkt
->fate
= pkt_fate
;
1776 tx_report
->status_pos
++;
1784 /* search until beginning (handles out-of-order completion) */
1786 count
= status_pos
- 1;
1787 tx_pkt
= (((dhd_dbg_tx_info_t
*)tx_report
->tx_pkts
) + count
);
1788 while ((count
>= 0) && tx_pkt
) {
1789 temp_hash
= tx_pkt
->info
.pkt_hash
;
1790 if (temp_hash
== pkt_hash
) {
1791 tx_pkt
->fate
= pkt_fate
;
1792 tx_report
->status_pos
++;
1801 /* still couldn't match tx_status */
1802 DHD_INFO(("%s(): couldn't match tx_status, pkt_pos=%u, "
1803 "status_pos=%u, pkt_fate=%u\n", __FUNCTION__
,
1804 pkt_pos
, status_pos
, pkt_fate
));
1808 dhdp
->dbg
->pkt_mon
.tx_status_state
= PKT_MON_STOPPED
;
1809 DHD_PKT_MON(("%s(): tx_status logging stopped, reached "
1810 "max limit\n", __FUNCTION__
));
1814 DHD_PKT_MON_UNLOCK(dhdp
->dbg
->pkt_mon_lock
, flags
);
1819 dhd_dbg_monitor_rx_pkts(dhd_pub_t
*dhdp
, void *pkt
)
1821 dhd_dbg_rx_report_t
*rx_report
;
1822 dhd_dbg_rx_info_t
*rx_pkts
;
1823 dhd_dbg_pkt_mon_state_t rx_pkt_state
;
1826 unsigned long flags
;
1828 if (!dhdp
|| !dhdp
->dbg
) {
1829 DHD_PKT_MON(("%s(): dhdp=%p, dhdp->dbg=%p\n", __FUNCTION__
,
1830 dhdp
, (dhdp
? dhdp
->dbg
: NULL
)));
1834 DHD_PKT_MON_LOCK(dhdp
->dbg
->pkt_mon_lock
, flags
);
1835 rx_pkt_state
= dhdp
->dbg
->pkt_mon
.rx_pkt_state
;
1836 if (PKT_MON_STARTED(rx_pkt_state
)) {
1837 rx_report
= dhdp
->dbg
->pkt_mon
.rx_report
;
1838 pkt_pos
= rx_report
->pkt_pos
;
1840 if (!PKT_MON_PKT_FULL(pkt_pos
)) {
1841 rx_pkts
= rx_report
->rx_pkts
;
1842 driver_ts
= __dhd_dbg_driver_ts_usec();
1844 rx_pkts
[pkt_pos
].info
.pkt
= PKTDUP(dhdp
->osh
, pkt
);
1845 rx_pkts
[pkt_pos
].info
.pkt_len
= PKTLEN(dhdp
->osh
, pkt
);
1846 rx_pkts
[pkt_pos
].info
.pkt_hash
= 0U;
1847 rx_pkts
[pkt_pos
].info
.driver_ts
= driver_ts
;
1848 rx_pkts
[pkt_pos
].info
.firmware_ts
= 0U;
1849 rx_pkts
[pkt_pos
].info
.payload_type
= FRAME_TYPE_ETHERNET_II
;
1850 rx_pkts
[pkt_pos
].fate
= RX_PKT_FATE_SUCCESS
;
1852 rx_report
->pkt_pos
++;
1854 dhdp
->dbg
->pkt_mon
.rx_pkt_state
= PKT_MON_STOPPED
;
1855 DHD_PKT_MON(("%s(): rx pkt logging stopped, reached "
1856 "max limit\n", __FUNCTION__
));
1860 DHD_PKT_MON_UNLOCK(dhdp
->dbg
->pkt_mon_lock
, flags
);
1865 dhd_dbg_stop_pkt_monitor(dhd_pub_t
*dhdp
)
1867 dhd_dbg_pkt_mon_state_t tx_pkt_state
;
1868 dhd_dbg_pkt_mon_state_t tx_status_state
;
1869 dhd_dbg_pkt_mon_state_t rx_pkt_state
;
1870 unsigned long flags
;
1872 if (!dhdp
|| !dhdp
->dbg
) {
1873 DHD_PKT_MON(("%s(): dhdp=%p, dhdp->dbg=%p\n", __FUNCTION__
,
1874 dhdp
, (dhdp
? dhdp
->dbg
: NULL
)));
1878 DHD_PKT_MON_LOCK(dhdp
->dbg
->pkt_mon_lock
, flags
);
1879 tx_pkt_state
= dhdp
->dbg
->pkt_mon
.tx_pkt_state
;
1880 tx_status_state
= dhdp
->dbg
->pkt_mon
.tx_status_state
;
1881 rx_pkt_state
= dhdp
->dbg
->pkt_mon
.rx_pkt_state
;
1883 if (PKT_MON_DETACHED(tx_pkt_state
) || PKT_MON_DETACHED(tx_status_state
) ||
1884 PKT_MON_DETACHED(rx_pkt_state
)) {
1885 DHD_PKT_MON(("%s(): packet monitor is not yet enabled, "
1886 "tx_pkt_state=%d, tx_status_state=%d, rx_pkt_state=%d\n",
1887 __FUNCTION__
, tx_pkt_state
, tx_status_state
, rx_pkt_state
));
1888 DHD_PKT_MON_UNLOCK(dhdp
->dbg
->pkt_mon_lock
, flags
);
1891 dhdp
->dbg
->pkt_mon
.tx_pkt_state
= PKT_MON_STOPPED
;
1892 dhdp
->dbg
->pkt_mon
.tx_status_state
= PKT_MON_STOPPED
;
1893 dhdp
->dbg
->pkt_mon
.rx_pkt_state
= PKT_MON_STOPPED
;
1894 DHD_PKT_MON_UNLOCK(dhdp
->dbg
->pkt_mon_lock
, flags
);
1896 DHD_PKT_MON(("%s(): packet monitor stopped\n", __FUNCTION__
));
1900 #define __COPY_TO_USER(to, from, n) \
1903 __ret = copy_to_user((void __user *)(to), (void *)(from), \
1904 (unsigned long)(n)); \
1905 if (unlikely(__ret)) { \
1906 DHD_ERROR(("%s():%d: copy_to_user failed, ret=%d\n", \
1907 __FUNCTION__, __LINE__, __ret)); \
1913 dhd_dbg_monitor_get_tx_pkts(dhd_pub_t
*dhdp
, void __user
*user_buf
,
1914 uint16 req_count
, uint16
*resp_count
)
1916 dhd_dbg_tx_report_t
*tx_report
;
1917 dhd_dbg_tx_info_t
*tx_pkt
;
1918 wifi_tx_report_t
*ptr
;
1919 compat_wifi_tx_report_t
*cptr
;
1920 dhd_dbg_pkt_mon_state_t tx_pkt_state
;
1921 dhd_dbg_pkt_mon_state_t tx_status_state
;
1922 uint16 pkt_count
, count
;
1923 unsigned long flags
;
1926 BCM_REFERENCE(cptr
);
1928 if (!dhdp
|| !dhdp
->dbg
) {
1929 DHD_PKT_MON(("%s(): dhdp=%p, dhdp->dbg=%p\n", __FUNCTION__
,
1930 dhdp
, (dhdp
? dhdp
->dbg
: NULL
)));
1934 DHD_PKT_MON_LOCK(dhdp
->dbg
->pkt_mon_lock
, flags
);
1935 tx_pkt_state
= dhdp
->dbg
->pkt_mon
.tx_pkt_state
;
1936 tx_status_state
= dhdp
->dbg
->pkt_mon
.tx_status_state
;
1937 if (PKT_MON_DETACHED(tx_pkt_state
) || PKT_MON_DETACHED(tx_status_state
)) {
1938 DHD_PKT_MON(("%s(): packet monitor is not yet enabled, "
1939 "tx_pkt_state=%d, tx_status_state=%d\n", __FUNCTION__
,
1940 tx_pkt_state
, tx_status_state
));
1941 DHD_PKT_MON_UNLOCK(dhdp
->dbg
->pkt_mon_lock
, flags
);
1946 tx_report
= dhdp
->dbg
->pkt_mon
.tx_report
;
1947 tx_pkt
= tx_report
->tx_pkts
;
1948 pkt_count
= MIN(req_count
, tx_report
->status_pos
);
1950 #ifdef CONFIG_COMPAT
1951 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 6, 0))
1952 if (in_compat_syscall())
1954 if (is_compat_task())
1957 cptr
= (compat_wifi_tx_report_t
*)user_buf
;
1958 while ((count
< pkt_count
) && tx_pkt
&& cptr
) {
1959 compat_wifi_tx_report_t
*comp_ptr
= compat_ptr((uintptr_t) cptr
);
1960 compat_dhd_dbg_pkt_info_t compat_tx_pkt
;
1961 __dhd_dbg_dump_tx_pkt_info(dhdp
, tx_pkt
, count
);
1962 __COPY_TO_USER(&comp_ptr
->fate
, &tx_pkt
->fate
, sizeof(tx_pkt
->fate
));
1964 compat_tx_pkt
.payload_type
= tx_pkt
->info
.payload_type
;
1965 compat_tx_pkt
.pkt_len
= tx_pkt
->info
.pkt_len
;
1966 compat_tx_pkt
.driver_ts
= tx_pkt
->info
.driver_ts
;
1967 compat_tx_pkt
.firmware_ts
= tx_pkt
->info
.firmware_ts
;
1968 compat_tx_pkt
.pkt_hash
= tx_pkt
->info
.pkt_hash
;
1969 __COPY_TO_USER(&comp_ptr
->frame_inf
.payload_type
,
1970 &compat_tx_pkt
.payload_type
,
1971 OFFSETOF(compat_dhd_dbg_pkt_info_t
, pkt_hash
));
1972 __COPY_TO_USER(comp_ptr
->frame_inf
.frame_content
.ethernet_ii
,
1973 PKTDATA(dhdp
->osh
, tx_pkt
->info
.pkt
), tx_pkt
->info
.pkt_len
);
1980 #endif /* CONFIG_COMPAT */
1982 ptr
= (wifi_tx_report_t
*)user_buf
;
1983 while ((count
< pkt_count
) && tx_pkt
&& ptr
) {
1984 __dhd_dbg_dump_tx_pkt_info(dhdp
, tx_pkt
, count
);
1985 __COPY_TO_USER(&ptr
->fate
, &tx_pkt
->fate
, sizeof(tx_pkt
->fate
));
1986 __COPY_TO_USER(&ptr
->frame_inf
.payload_type
,
1987 &tx_pkt
->info
.payload_type
,
1988 OFFSETOF(dhd_dbg_pkt_info_t
, pkt_hash
));
1989 __COPY_TO_USER(ptr
->frame_inf
.frame_content
.ethernet_ii
,
1990 PKTDATA(dhdp
->osh
, tx_pkt
->info
.pkt
), tx_pkt
->info
.pkt_len
);
1997 *resp_count
= pkt_count
;
1999 DHD_PKT_MON_UNLOCK(dhdp
->dbg
->pkt_mon_lock
, flags
);
2001 DHD_ERROR(("%s(): no tx_status in tx completion messages, "
2002 "make sure that 'd11status' is enabled in firmware, "
2003 "status_pos=%u\n", __FUNCTION__
, pkt_count
));
2010 dhd_dbg_monitor_get_rx_pkts(dhd_pub_t
*dhdp
, void __user
*user_buf
,
2011 uint16 req_count
, uint16
*resp_count
)
2013 dhd_dbg_rx_report_t
*rx_report
;
2014 dhd_dbg_rx_info_t
*rx_pkt
;
2015 wifi_rx_report_t
*ptr
;
2016 compat_wifi_rx_report_t
*cptr
;
2017 dhd_dbg_pkt_mon_state_t rx_pkt_state
;
2018 uint16 pkt_count
, count
;
2019 unsigned long flags
;
2022 BCM_REFERENCE(cptr
);
2024 if (!dhdp
|| !dhdp
->dbg
) {
2025 DHD_PKT_MON(("%s(): dhdp=%p, dhdp->dbg=%p\n", __FUNCTION__
,
2026 dhdp
, (dhdp
? dhdp
->dbg
: NULL
)));
2030 DHD_PKT_MON_LOCK(dhdp
->dbg
->pkt_mon_lock
, flags
);
2031 rx_pkt_state
= dhdp
->dbg
->pkt_mon
.rx_pkt_state
;
2032 if (PKT_MON_DETACHED(rx_pkt_state
)) {
2033 DHD_PKT_MON(("%s(): packet fetch is not allowed , "
2034 "rx_pkt_state=%d\n", __FUNCTION__
, rx_pkt_state
));
2035 DHD_PKT_MON_UNLOCK(dhdp
->dbg
->pkt_mon_lock
, flags
);
2040 rx_report
= dhdp
->dbg
->pkt_mon
.rx_report
;
2041 rx_pkt
= rx_report
->rx_pkts
;
2042 pkt_count
= MIN(req_count
, rx_report
->pkt_pos
);
2044 #ifdef CONFIG_COMPAT
2045 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 6, 0))
2046 if (in_compat_syscall())
2048 if (is_compat_task())
2051 cptr
= (compat_wifi_rx_report_t
*)user_buf
;
2052 while ((count
< pkt_count
) && rx_pkt
&& cptr
) {
2053 compat_wifi_rx_report_t
*comp_ptr
= compat_ptr((uintptr_t) cptr
);
2054 compat_dhd_dbg_pkt_info_t compat_rx_pkt
;
2055 __dhd_dbg_dump_rx_pkt_info(dhdp
, rx_pkt
, count
);
2056 __COPY_TO_USER(&comp_ptr
->fate
, &rx_pkt
->fate
, sizeof(rx_pkt
->fate
));
2058 compat_rx_pkt
.payload_type
= rx_pkt
->info
.payload_type
;
2059 compat_rx_pkt
.pkt_len
= rx_pkt
->info
.pkt_len
;
2060 compat_rx_pkt
.driver_ts
= rx_pkt
->info
.driver_ts
;
2061 compat_rx_pkt
.firmware_ts
= rx_pkt
->info
.firmware_ts
;
2062 compat_rx_pkt
.pkt_hash
= rx_pkt
->info
.pkt_hash
;
2063 __COPY_TO_USER(&comp_ptr
->frame_inf
.payload_type
,
2064 &compat_rx_pkt
.payload_type
,
2065 OFFSETOF(compat_dhd_dbg_pkt_info_t
, pkt_hash
));
2066 __COPY_TO_USER(comp_ptr
->frame_inf
.frame_content
.ethernet_ii
,
2067 PKTDATA(dhdp
->osh
, rx_pkt
->info
.pkt
), rx_pkt
->info
.pkt_len
);
2074 #endif /* CONFIG_COMPAT */
2076 ptr
= (wifi_rx_report_t
*)user_buf
;
2077 while ((count
< pkt_count
) && rx_pkt
&& ptr
) {
2078 __dhd_dbg_dump_rx_pkt_info(dhdp
, rx_pkt
, count
);
2080 __COPY_TO_USER(&ptr
->fate
, &rx_pkt
->fate
, sizeof(rx_pkt
->fate
));
2081 __COPY_TO_USER(&ptr
->frame_inf
.payload_type
,
2082 &rx_pkt
->info
.payload_type
,
2083 OFFSETOF(dhd_dbg_pkt_info_t
, pkt_hash
));
2084 __COPY_TO_USER(ptr
->frame_inf
.frame_content
.ethernet_ii
,
2085 PKTDATA(dhdp
->osh
, rx_pkt
->info
.pkt
), rx_pkt
->info
.pkt_len
);
2093 *resp_count
= pkt_count
;
2094 DHD_PKT_MON_UNLOCK(dhdp
->dbg
->pkt_mon_lock
, flags
);
2100 dhd_dbg_detach_pkt_monitor(dhd_pub_t
*dhdp
)
2102 dhd_dbg_tx_report_t
*tx_report
;
2103 dhd_dbg_rx_report_t
*rx_report
;
2104 dhd_dbg_pkt_mon_state_t tx_pkt_state
;
2105 dhd_dbg_pkt_mon_state_t tx_status_state
;
2106 dhd_dbg_pkt_mon_state_t rx_pkt_state
;
2107 unsigned long flags
;
2109 if (!dhdp
|| !dhdp
->dbg
) {
2110 DHD_PKT_MON(("%s(): dhdp=%p, dhdp->dbg=%p\n", __FUNCTION__
,
2111 dhdp
, (dhdp
? dhdp
->dbg
: NULL
)));
2115 DHD_PKT_MON_LOCK(dhdp
->dbg
->pkt_mon_lock
, flags
);
2116 tx_pkt_state
= dhdp
->dbg
->pkt_mon
.tx_pkt_state
;
2117 tx_status_state
= dhdp
->dbg
->pkt_mon
.tx_status_state
;
2118 rx_pkt_state
= dhdp
->dbg
->pkt_mon
.rx_pkt_state
;
2120 if (PKT_MON_DETACHED(tx_pkt_state
) || PKT_MON_DETACHED(tx_status_state
) ||
2121 PKT_MON_DETACHED(rx_pkt_state
)) {
2122 DHD_PKT_MON(("%s(): packet monitor is already detached, "
2123 "tx_pkt_state=%d, tx_status_state=%d, rx_pkt_state=%d\n",
2124 __FUNCTION__
, tx_pkt_state
, tx_status_state
, rx_pkt_state
));
2125 DHD_PKT_MON_UNLOCK(dhdp
->dbg
->pkt_mon_lock
, flags
);
2129 tx_report
= dhdp
->dbg
->pkt_mon
.tx_report
;
2130 rx_report
= dhdp
->dbg
->pkt_mon
.rx_report
;
2132 /* free and de-initalize tx packet monitoring */
2133 dhdp
->dbg
->pkt_mon
.tx_pkt_state
= PKT_MON_DETACHED
;
2134 dhdp
->dbg
->pkt_mon
.tx_status_state
= PKT_MON_DETACHED
;
2136 if (tx_report
->tx_pkts
) {
2137 __dhd_dbg_free_tx_pkts(dhdp
, tx_report
->tx_pkts
,
2138 tx_report
->pkt_pos
);
2139 MFREE(dhdp
->osh
, tx_report
->tx_pkts
,
2140 (sizeof(*tx_report
->tx_pkts
) * MAX_FATE_LOG_LEN
));
2141 dhdp
->dbg
->pkt_mon
.tx_report
->tx_pkts
= NULL
;
2143 MFREE(dhdp
->osh
, tx_report
, sizeof(*tx_report
));
2144 dhdp
->dbg
->pkt_mon
.tx_report
= NULL
;
2146 dhdp
->dbg
->pkt_mon
.tx_pkt_mon
= NULL
;
2147 dhdp
->dbg
->pkt_mon
.tx_status_mon
= NULL
;
2149 /* free and de-initalize rx packet monitoring */
2150 dhdp
->dbg
->pkt_mon
.rx_pkt_state
= PKT_MON_DETACHED
;
2152 if (rx_report
->rx_pkts
) {
2153 __dhd_dbg_free_rx_pkts(dhdp
, rx_report
->rx_pkts
,
2154 rx_report
->pkt_pos
);
2155 MFREE(dhdp
->osh
, rx_report
->rx_pkts
,
2156 (sizeof(*rx_report
->rx_pkts
) * MAX_FATE_LOG_LEN
));
2157 dhdp
->dbg
->pkt_mon
.rx_report
->rx_pkts
= NULL
;
2159 MFREE(dhdp
->osh
, rx_report
, sizeof(*rx_report
));
2160 dhdp
->dbg
->pkt_mon
.rx_report
= NULL
;
2162 dhdp
->dbg
->pkt_mon
.rx_pkt_mon
= NULL
;
2164 DHD_PKT_MON_UNLOCK(dhdp
->dbg
->pkt_mon_lock
, flags
);
2165 DHD_PKT_MON(("%s(): packet monitor detach succeeded\n", __FUNCTION__
));
2168 #endif /* DBG_PKT_MON */
2170 #if defined(DBG_PKT_MON) || defined(DHD_PKT_LOGGING)
2172 * XXX: WAR: Because of the overloading by DMA marker field,
2173 * tx_status in TX completion message cannot be used. As a WAR,
2174 * send d11 tx_status through unused status field of PCIe
2175 * completion header.
2178 dhd_dbg_process_tx_status(dhd_pub_t
*dhdp
, void *pkt
, uint32 pktid
,
2181 bool pkt_fate
= TRUE
;
2182 if (dhdp
->d11_tx_status
) {
2183 pkt_fate
= (status
== WLFC_CTL_PKTFLAG_DISCARD
) ? TRUE
: FALSE
;
2184 DHD_DBG_PKT_MON_TX_STATUS(dhdp
, pkt
, pktid
, status
);
2188 #else /* DBG_PKT_MON || DHD_PKT_LOGGING */
2190 dhd_dbg_process_tx_status(dhd_pub_t
*dhdp
, void *pkt
,
2191 uint32 pktid
, uint16 status
)
2195 #endif /* DBG_PKT_MON || DHD_PKT_LOGGING */
2197 #define EL_LOG_STR_LEN 512
2199 #define PRINT_CHN_PER_LINE 8
2200 #define PRINT_CHAN_LINE(cnt) \
2203 if (cnt >= PRINT_CHN_PER_LINE) { \
2204 DHD_ERROR(("%s\n", b.origbuf)); \
2205 bcm_binit(&b, pr_buf, EL_LOG_STR_LEN); \
2206 bcm_bprintf(&b, "%s: ", prefix); \
2211 void print_roam_chan_list(char *prefix
, uint chan_num
, uint16 band_2g
,
2212 uint16 uni2a
, uint8 uni3
, uint8
*uni2c
)
2215 char pr_buf
[EL_LOG_STR_LEN
] = { 0 };
2219 bcm_binit(&b
, pr_buf
, EL_LOG_STR_LEN
);
2220 bcm_bprintf(&b
, "%s: count(%d)", prefix
, chan_num
);
2222 for (idx
= 0; idx
< NBITS(uint16
); idx
++) {
2223 if (BCM_BIT(idx
) & band_2g
) {
2224 bcm_bprintf(&b
, " %d", idx
);
2225 PRINT_CHAN_LINE(cnt
);
2230 /* 5G UNII BAND 1, UNII BAND 2A */
2231 for (idx
= 0; idx
< NBITS(uint16
); idx
++) {
2232 if (BCM_BIT(idx
) & uni2a
) {
2233 bcm_bprintf(&b
, " %u", ROAM_CHN_UNI_2A
+ idx
* ROAM_CHN_SPACE
);
2234 PRINT_CHAN_LINE(cnt
);
2238 /* 5G UNII BAND 2C */
2239 for (idx2
= 0; idx2
< 3; idx2
++) {
2240 for (idx
= 0; idx
< NBITS(uint8
); idx
++) {
2241 if (BCM_BIT(idx
) & uni2c
[idx2
]) {
2242 bcm_bprintf(&b
, " %u", ROAM_CHN_UNI_2C
+
2243 idx2
* ROAM_CHN_SPACE
* NBITS(uint8
) +
2244 idx
* ROAM_CHN_SPACE
);
2245 PRINT_CHAN_LINE(cnt
);
2250 /* 5G UNII BAND 3 */
2251 for (idx
= 0; idx
< NBITS(uint8
); idx
++) {
2252 if (BCM_BIT(idx
) & uni3
) {
2253 bcm_bprintf(&b
, " %u", ROAM_CHN_UNI_3
+ idx
* ROAM_CHN_SPACE
);
2254 PRINT_CHAN_LINE(cnt
);
2259 DHD_ERROR(("%s\n", b
.origbuf
));
2263 void pr_roam_scan_start_v1(prcd_event_log_hdr_t
*plog_hdr
);
2264 void pr_roam_scan_cmpl_v1(prcd_event_log_hdr_t
*plog_hdr
);
2265 void pr_roam_cmpl_v1(prcd_event_log_hdr_t
*plog_hdr
);
2266 void pr_roam_nbr_req_v1(prcd_event_log_hdr_t
*plog_hdr
);
2267 void pr_roam_nbr_rep_v1(prcd_event_log_hdr_t
*plog_hdr
);
2268 void pr_roam_bcn_req_v1(prcd_event_log_hdr_t
*plog_hdr
);
2269 void pr_roam_bcn_rep_v1(prcd_event_log_hdr_t
*plog_hdr
);
2271 void pr_roam_scan_start_v2(prcd_event_log_hdr_t
*plog_hdr
);
2272 void pr_roam_scan_cmpl_v2(prcd_event_log_hdr_t
*plog_hdr
);
2273 void pr_roam_nbr_rep_v2(prcd_event_log_hdr_t
*plog_hdr
);
2274 void pr_roam_bcn_rep_v2(prcd_event_log_hdr_t
*plog_hdr
);
2275 void pr_roam_btm_rep_v2(prcd_event_log_hdr_t
*plog_hdr
);
2277 void pr_roam_bcn_req_v3(prcd_event_log_hdr_t
*plog_hdr
);
2278 void pr_roam_bcn_rep_v3(prcd_event_log_hdr_t
*plog_hdr
);
2279 void pr_roam_btm_rep_v3(prcd_event_log_hdr_t
*plog_hdr
);
2281 static const pr_roam_tbl_t roam_log_print_tbl
[] =
2283 {ROAM_LOG_VER_1
, ROAM_LOG_SCANSTART
, pr_roam_scan_start_v1
},
2284 {ROAM_LOG_VER_1
, ROAM_LOG_SCAN_CMPLT
, pr_roam_scan_cmpl_v1
},
2285 {ROAM_LOG_VER_1
, ROAM_LOG_ROAM_CMPLT
, pr_roam_cmpl_v1
},
2286 {ROAM_LOG_VER_1
, ROAM_LOG_NBR_REQ
, pr_roam_nbr_req_v1
},
2287 {ROAM_LOG_VER_1
, ROAM_LOG_NBR_REP
, pr_roam_nbr_rep_v1
},
2288 {ROAM_LOG_VER_1
, ROAM_LOG_BCN_REQ
, pr_roam_bcn_req_v1
},
2289 {ROAM_LOG_VER_1
, ROAM_LOG_BCN_REP
, pr_roam_bcn_rep_v1
},
2291 {ROAM_LOG_VER_2
, ROAM_LOG_SCANSTART
, pr_roam_scan_start_v2
},
2292 {ROAM_LOG_VER_2
, ROAM_LOG_SCAN_CMPLT
, pr_roam_scan_cmpl_v2
},
2293 {ROAM_LOG_VER_2
, ROAM_LOG_ROAM_CMPLT
, pr_roam_cmpl_v1
},
2294 {ROAM_LOG_VER_2
, ROAM_LOG_NBR_REQ
, pr_roam_nbr_req_v1
},
2295 {ROAM_LOG_VER_2
, ROAM_LOG_NBR_REP
, pr_roam_nbr_rep_v2
},
2296 {ROAM_LOG_VER_2
, ROAM_LOG_BCN_REQ
, pr_roam_bcn_req_v1
},
2297 {ROAM_LOG_VER_2
, ROAM_LOG_BCN_REP
, pr_roam_bcn_rep_v2
},
2298 {ROAM_LOG_VER_2
, ROAM_LOG_BTM_REP
, pr_roam_btm_rep_v2
},
2300 {ROAM_LOG_VER_3
, ROAM_LOG_SCANSTART
, pr_roam_scan_start_v2
},
2301 {ROAM_LOG_VER_3
, ROAM_LOG_SCAN_CMPLT
, pr_roam_scan_cmpl_v2
},
2302 {ROAM_LOG_VER_3
, ROAM_LOG_ROAM_CMPLT
, pr_roam_cmpl_v1
},
2303 {ROAM_LOG_VER_3
, ROAM_LOG_NBR_REQ
, pr_roam_nbr_req_v1
},
2304 {ROAM_LOG_VER_3
, ROAM_LOG_NBR_REP
, pr_roam_nbr_rep_v2
},
2305 {ROAM_LOG_VER_3
, ROAM_LOG_BCN_REQ
, pr_roam_bcn_req_v3
},
2306 {ROAM_LOG_VER_3
, ROAM_LOG_BCN_REP
, pr_roam_bcn_rep_v3
},
2307 {ROAM_LOG_VER_3
, ROAM_LOG_BTM_REP
, pr_roam_btm_rep_v3
},
2309 {0, PRSV_PERIODIC_ID_MAX
, NULL
}
2313 void pr_roam_scan_start_v1(prcd_event_log_hdr_t
*plog_hdr
)
2315 roam_log_trig_v1_t
*log
= (roam_log_trig_v1_t
*)plog_hdr
->log_ptr
;
2317 DHD_ERROR(("ROAM_LOG_SCANSTART time: %d,"
2318 " version:%d reason: %d rssi:%d cu:%d result:%d\n",
2319 plog_hdr
->armcycle
, log
->hdr
.version
, log
->reason
,
2320 log
->rssi
, log
->current_cu
, log
->result
));
2321 if (log
->reason
== WLC_E_REASON_DEAUTH
||
2322 log
->reason
== WLC_E_REASON_DISASSOC
) {
2323 DHD_ERROR((" ROAM_LOG_PRT_ROAM: RCVD reason:%d\n",
2324 log
->prt_roam
.rcvd_reason
));
2325 } else if (log
->reason
== WLC_E_REASON_BSSTRANS_REQ
) {
2326 DHD_ERROR((" ROAM_LOG_BSS_REQ: mode:%d candidate:%d token:%d "
2327 "duration disassoc:%d valid:%d term:%d\n",
2328 log
->bss_trans
.req_mode
, log
->bss_trans
.nbrlist_size
,
2329 log
->bss_trans
.token
, log
->bss_trans
.disassoc_dur
,
2330 log
->bss_trans
.validity_dur
, log
->bss_trans
.bss_term_dur
));
2334 void pr_roam_scan_cmpl_v1(prcd_event_log_hdr_t
*plog_hdr
)
2336 roam_log_scan_cmplt_v1_t
*log
= (roam_log_scan_cmplt_v1_t
*)plog_hdr
->log_ptr
;
2337 char chanspec_buf
[CHANSPEC_STR_LEN
];
2340 DHD_ERROR(("ROAM_LOG_SCAN_CMPL: time:%d version:%d"
2341 "is_full:%d scan_count:%d score_delta:%d",
2342 plog_hdr
->armcycle
, log
->hdr
.version
, log
->full_scan
,
2343 log
->scan_count
, log
->score_delta
));
2344 DHD_ERROR((" ROAM_LOG_CUR_AP: " MACDBG
"rssi:%d score:%d channel:%s\n",
2345 MAC2STRDBG((uint8
*)&log
->cur_info
.addr
),
2347 log
->cur_info
.score
,
2348 wf_chspec_ntoa_ex(log
->cur_info
.chanspec
, chanspec_buf
)));
2349 for (i
= 0; i
< log
->scan_list_size
; i
++) {
2350 DHD_ERROR((" ROAM_LOG_CANDIDATE %d: " MACDBG
2351 "rssi:%d score:%d channel:%s TPUT:%dkbps\n",
2352 i
, MAC2STRDBG((uint8
*)&log
->scan_list
[i
].addr
),
2353 log
->scan_list
[i
].rssi
, log
->scan_list
[i
].score
,
2354 wf_chspec_ntoa_ex(log
->scan_list
[i
].chanspec
,
2356 log
->scan_list
[i
].estm_tput
!= ROAM_LOG_INVALID_TPUT
?
2357 log
->scan_list
[i
].estm_tput
:0));
2361 void pr_roam_cmpl_v1(prcd_event_log_hdr_t
*plog_hdr
)
2363 roam_log_cmplt_v1_t
*log
= (roam_log_cmplt_v1_t
*)plog_hdr
->log_ptr
;
2364 char chanspec_buf
[CHANSPEC_STR_LEN
];
2366 DHD_ERROR(("ROAM_LOG_ROAM_CMPL: time: %d, version:%d"
2367 "status: %d reason: %d channel:%s retry:%d " MACDBG
"\n",
2368 plog_hdr
->armcycle
, log
->hdr
.version
, log
->status
, log
->reason
,
2369 wf_chspec_ntoa_ex(log
->chanspec
, chanspec_buf
),
2370 log
->retry
, MAC2STRDBG((uint8
*)&log
->addr
)));
2373 void pr_roam_nbr_req_v1(prcd_event_log_hdr_t
*plog_hdr
)
2375 roam_log_nbrreq_v1_t
*log
= (roam_log_nbrreq_v1_t
*)plog_hdr
->log_ptr
;
2377 DHD_ERROR(("ROAM_LOG_NBR_REQ: time: %d, version:%d token:%d\n",
2378 plog_hdr
->armcycle
, log
->hdr
.version
, log
->token
));
2381 void pr_roam_nbr_rep_v1(prcd_event_log_hdr_t
*plog_hdr
)
2383 roam_log_nbrrep_v1_t
*log
= (roam_log_nbrrep_v1_t
*)plog_hdr
->log_ptr
;
2385 DHD_ERROR(("ROAM_LOG_NBR_REP: time:%d, veresion:%d chan_num:%d\n",
2386 plog_hdr
->armcycle
, log
->hdr
.version
, log
->channel_num
));
2389 void pr_roam_bcn_req_v1(prcd_event_log_hdr_t
*plog_hdr
)
2391 roam_log_bcnrpt_req_v1_t
*log
= (roam_log_bcnrpt_req_v1_t
*)plog_hdr
->log_ptr
;
2393 DHD_ERROR(("ROAM_LOG_BCN_REQ: time:%d, version:%d ret:%d"
2394 "class:%d num_chan:%d ",
2395 plog_hdr
->armcycle
, log
->hdr
.version
,
2396 log
->result
, log
->reg
, log
->channel
));
2397 DHD_ERROR(("ROAM_LOG_BCN_REQ: mode:%d is_wild:%d duration:%d"
2398 "ssid_len:%d\n", log
->mode
, log
->bssid_wild
,
2399 log
->duration
, log
->ssid_len
));
2402 void pr_roam_bcn_rep_v1(prcd_event_log_hdr_t
*plog_hdr
)
2404 roam_log_bcnrpt_rep_v1_t
*log
= (roam_log_bcnrpt_rep_v1_t
*)plog_hdr
->log_ptr
;
2405 DHD_ERROR(("ROAM_LOG_BCN_REP: time:%d, verseion:%d count:%d\n",
2406 plog_hdr
->armcycle
, log
->hdr
.version
,
2410 void pr_roam_scan_start_v2(prcd_event_log_hdr_t
*plog_hdr
)
2412 roam_log_trig_v2_t
*log
= (roam_log_trig_v2_t
*)plog_hdr
->log_ptr
;
2413 DHD_ERROR(("ROAM_LOG_SCANSTART time: %d,"
2414 " version:%d reason: %d rssi:%d cu:%d result:%d full_scan:%d\n",
2415 plog_hdr
->armcycle
, log
->hdr
.version
, log
->reason
,
2416 log
->rssi
, log
->current_cu
, log
->result
,
2417 log
->result
?(-1):log
->full_scan
));
2418 if (log
->reason
== WLC_E_REASON_DEAUTH
||
2419 log
->reason
== WLC_E_REASON_DISASSOC
) {
2420 DHD_ERROR((" ROAM_LOG_PRT_ROAM: RCVD reason:%d\n",
2421 log
->prt_roam
.rcvd_reason
));
2422 } else if (log
->reason
== WLC_E_REASON_BSSTRANS_REQ
) {
2423 DHD_ERROR((" ROAM_LOG_BSS_REQ: mode:%d candidate:%d token:%d "
2424 "duration disassoc:%d valid:%d term:%d\n",
2425 log
->bss_trans
.req_mode
, log
->bss_trans
.nbrlist_size
,
2426 log
->bss_trans
.token
, log
->bss_trans
.disassoc_dur
,
2427 log
->bss_trans
.validity_dur
, log
->bss_trans
.bss_term_dur
));
2428 } else if (log
->reason
== WLC_E_REASON_LOW_RSSI
) {
2429 DHD_ERROR((" ROAM_LOG_LOW_RSSI: threshold:%d\n",
2430 log
->low_rssi
.rssi_threshold
));
2434 void pr_roam_scan_cmpl_v2(prcd_event_log_hdr_t
*plog_hdr
)
2437 roam_log_scan_cmplt_v2_t
*log
= (roam_log_scan_cmplt_v2_t
*)plog_hdr
->log_ptr
;
2438 char chanspec_buf
[CHANSPEC_STR_LEN
];
2440 DHD_ERROR(("ROAM_LOG_SCAN_CMPL: time:%d version:%d"
2441 "scan_count:%d score_delta:%d",
2442 plog_hdr
->armcycle
, log
->hdr
.version
,
2443 log
->scan_count
, log
->score_delta
));
2444 DHD_ERROR((" ROAM_LOG_CUR_AP: " MACDBG
"rssi:%d score:%d channel:%s\n",
2445 MAC2STRDBG((uint8
*)&log
->cur_info
.addr
),
2447 log
->cur_info
.score
,
2448 wf_chspec_ntoa_ex(log
->cur_info
.chanspec
, chanspec_buf
)));
2449 for (i
= 0; i
< log
->scan_list_size
; i
++) {
2450 DHD_ERROR((" ROAM_LOG_CANDIDATE %d: " MACDBG
2451 "rssi:%d score:%d cu :%d channel:%s TPUT:%dkbps\n",
2452 i
, MAC2STRDBG((uint8
*)&log
->scan_list
[i
].addr
),
2453 log
->scan_list
[i
].rssi
, log
->scan_list
[i
].score
,
2454 log
->scan_list
[i
].cu
* 100 / WL_MAX_CHANNEL_USAGE
,
2455 wf_chspec_ntoa_ex(log
->scan_list
[i
].chanspec
,
2457 log
->scan_list
[i
].estm_tput
!= ROAM_LOG_INVALID_TPUT
?
2458 log
->scan_list
[i
].estm_tput
:0));
2460 if (log
->chan_num
!= 0) {
2461 print_roam_chan_list("ROAM_LOG_SCAN_CHANLIST", log
->chan_num
,
2462 log
->band2g_chan_list
, log
->uni2a_chan_list
,
2463 log
->uni3_chan_list
, log
->uni2c_chan_list
);
2468 void pr_roam_nbr_rep_v2(prcd_event_log_hdr_t
*plog_hdr
)
2470 roam_log_nbrrep_v2_t
*log
= (roam_log_nbrrep_v2_t
*)plog_hdr
->log_ptr
;
2471 DHD_ERROR(("ROAM_LOG_NBR_REP: time:%d, veresion:%d chan_num:%d\n",
2472 plog_hdr
->armcycle
, log
->hdr
.version
, log
->channel_num
));
2473 if (log
->channel_num
!= 0) {
2474 print_roam_chan_list("ROAM_LOG_NBR_REP_CHANLIST", log
->channel_num
,
2475 log
->band2g_chan_list
, log
->uni2a_chan_list
,
2476 log
->uni3_chan_list
, log
->uni2c_chan_list
);
2480 void pr_roam_bcn_rep_v2(prcd_event_log_hdr_t
*plog_hdr
)
2482 roam_log_bcnrpt_rep_v2_t
*log
= (roam_log_bcnrpt_rep_v2_t
*)plog_hdr
->log_ptr
;
2484 DHD_ERROR(("ROAM_LOG_BCN_REP: time:%d, verseion:%d count:%d mode:%d\n",
2485 plog_hdr
->armcycle
, log
->hdr
.version
,
2486 log
->count
, log
->reason
));
2489 void pr_roam_btm_rep_v2(prcd_event_log_hdr_t
*plog_hdr
)
2491 roam_log_btm_rep_v2_t
*log
= (roam_log_btm_rep_v2_t
*)plog_hdr
->log_ptr
;
2492 DHD_ERROR(("ROAM_LOG_BTM_REP: time:%d version:%d req_mode:%d "
2493 "status:%d ret:%d\n",
2494 plog_hdr
->armcycle
, log
->hdr
.version
,
2495 log
->req_mode
, log
->status
, log
->result
));
2498 void pr_roam_bcn_req_v3(prcd_event_log_hdr_t
*plog_hdr
)
2500 roam_log_bcnrpt_req_v3_t
*log
= (roam_log_bcnrpt_req_v3_t
*)plog_hdr
->log_ptr
;
2502 DHD_ERROR(("ROAM_LOG_BCN_REQ: time:%d, version:%d ret:%d"
2504 plog_hdr
->armcycle
, log
->hdr
.version
,
2505 log
->result
, log
->reg
, log
->channel
?"":"all_chan"));
2506 DHD_ERROR(("ROAM_LOG_BCN_REQ: mode:%d is_wild:%d duration:%d"
2507 "ssid_len:%d\n", log
->mode
, log
->bssid_wild
,
2508 log
->duration
, log
->ssid_len
));
2509 if (log
->channel_num
!= 0) {
2510 print_roam_chan_list("ROAM_LOG_BCNREQ_SCAN_CHANLIST", log
->channel_num
,
2511 log
->band2g_chan_list
, log
->uni2a_chan_list
,
2512 log
->uni3_chan_list
, log
->uni2c_chan_list
);
2517 pr_roam_bcn_rep_reason(uint16 reason_detail
)
2519 static const char* reason_tbl
[] = {
2520 "BCNRPT_RSN_SUCCESS",
2521 "BCNRPT_RSN_BADARG",
2522 "BCNRPT_RSN_SCAN_ING",
2523 "BCNRPT_RSN_SCAN_FAIL",
2527 if (reason_detail
>= ARRAYSIZE(reason_tbl
)) {
2528 DHD_ERROR(("UNKNOWN Reason:%u\n", reason_detail
));
2530 reason_detail
= ARRAYSIZE(reason_tbl
) - 1;
2533 return reason_tbl
[reason_detail
];
2536 void pr_roam_bcn_rep_v3(prcd_event_log_hdr_t
*plog_hdr
)
2538 roam_log_bcnrpt_rep_v3_t
*log
= (roam_log_bcnrpt_rep_v3_t
*)plog_hdr
->log_ptr
;
2540 DHD_ERROR(("ROAM_LOG_BCN_REP: time:%d, verseion:%d count:%d mode:%d\n",
2541 plog_hdr
->armcycle
, log
->hdr
.version
,
2542 log
->count
, log
->reason
));
2543 DHD_ERROR(("ROAM_LOG_BCN_REP: mode reason(%d):%s scan_stus:%u duration:%u\n",
2544 log
->reason_detail
, pr_roam_bcn_rep_reason(log
->reason_detail
),
2545 (log
->reason_detail
== BCNRPT_RSN_SCAN_FAIL
)? log
->scan_status
:0,
2549 void pr_roam_btm_rep_v3(prcd_event_log_hdr_t
*plog_hdr
)
2551 roam_log_btm_rep_v3_t
*log
= (roam_log_btm_rep_v3_t
*)plog_hdr
->log_ptr
;
2552 DHD_ERROR(("ROAM_LOG_BTM_REP: time:%d version:%d req_mode:%d "
2553 "status:%d ret:%d target:" MACDBG
"\n",
2554 plog_hdr
->armcycle
, log
->hdr
.version
,
2555 log
->req_mode
, log
->status
, log
->result
,
2556 MAC2STRDBG((uint8
*)&log
->target_addr
)));
2560 print_roam_enhanced_log(prcd_event_log_hdr_t
*plog_hdr
)
2562 prsv_periodic_log_hdr_t
*hdr
= (prsv_periodic_log_hdr_t
*)plog_hdr
->log_ptr
;
2563 uint32
*ptr
= (uint32
*)plog_hdr
->log_ptr
;
2565 int loop_cnt
= hdr
->length
/ sizeof(uint32
);
2567 char pr_buf
[EL_LOG_STR_LEN
] = { 0 };
2568 const pr_roam_tbl_t
*cur_elem
= &roam_log_print_tbl
[0];
2570 while (cur_elem
&& cur_elem
->pr_func
) {
2571 if (hdr
->version
== cur_elem
->version
&&
2572 hdr
->id
== cur_elem
->id
) {
2573 cur_elem
->pr_func(plog_hdr
);
2579 bcm_binit(&b
, pr_buf
, EL_LOG_STR_LEN
);
2580 bcm_bprintf(&b
, "ROAM_LOG_UNKNOWN ID:%d ver:%d armcycle:%d",
2581 hdr
->id
, hdr
->version
, plog_hdr
->armcycle
);
2582 for (i
= 0; i
< loop_cnt
&& b
.size
> 0; i
++) {
2583 bcm_bprintf(&b
, " %x", *ptr
);
2586 DHD_ERROR(("%s\n", b
.origbuf
));
2590 * dhd_dbg_attach: initialziation of dhd dbugability module
2592 * Return: An error code or 0 on success.
2595 dhd_dbg_attach(dhd_pub_t
*dhdp
, dbg_pullreq_t os_pullreq
,
2596 dbg_urgent_noti_t os_urgent_notifier
, void *os_priv
)
2598 dhd_dbg_t
*dbg
= NULL
;
2599 dhd_dbg_ring_t
*ring
= NULL
;
2600 int ret
= BCME_ERROR
, ring_id
= 0;
2603 dbg
= MALLOCZ(dhdp
->osh
, sizeof(dhd_dbg_t
));
2607 #ifdef CONFIG_DHD_USE_STATIC_BUF
2608 buf
= DHD_OS_PREALLOC(dhdp
, DHD_PREALLOC_FW_VERBOSE_RING
, FW_VERBOSE_RING_SIZE
);
2610 buf
= MALLOCZ(dhdp
->osh
, FW_VERBOSE_RING_SIZE
);
2614 ret
= dhd_dbg_ring_init(dhdp
, &dbg
->dbg_rings
[FW_VERBOSE_RING_ID
], FW_VERBOSE_RING_ID
,
2615 (uint8
*)FW_VERBOSE_RING_NAME
, FW_VERBOSE_RING_SIZE
, buf
, FALSE
);
2619 #ifdef CONFIG_DHD_USE_STATIC_BUF
2620 buf
= DHD_OS_PREALLOC(dhdp
, DHD_PREALLOC_DHD_EVENT_RING
, DHD_EVENT_RING_SIZE
);
2622 buf
= MALLOCZ(dhdp
->osh
, DHD_EVENT_RING_SIZE
);
2626 ret
= dhd_dbg_ring_init(dhdp
, &dbg
->dbg_rings
[DHD_EVENT_RING_ID
], DHD_EVENT_RING_ID
,
2627 (uint8
*)DHD_EVENT_RING_NAME
, DHD_EVENT_RING_SIZE
, buf
, FALSE
);
2631 dbg
->private = os_priv
;
2632 dbg
->pullreq
= os_pullreq
;
2633 dbg
->urgent_notifier
= os_urgent_notifier
;
2639 for (ring_id
= DEBUG_RING_ID_INVALID
+ 1; ring_id
< DEBUG_RING_ID_MAX
; ring_id
++) {
2640 if (VALID_RING(dbg
->dbg_rings
[ring_id
].id
)) {
2641 ring
= &dbg
->dbg_rings
[ring_id
];
2642 dhd_dbg_ring_deinit(dhdp
, ring
);
2643 if (ring
->ring_buf
) {
2644 #ifndef CONFIG_DHD_USE_STATIC_BUF
2645 MFREE(dhdp
->osh
, ring
->ring_buf
, ring
->ring_size
);
2647 ring
->ring_buf
= NULL
;
2649 ring
->ring_size
= 0;
2652 MFREE(dhdp
->osh
, dbg
, sizeof(dhd_dbg_t
));
2658 * dhd_dbg_detach: clean up dhd dbugability module
2661 dhd_dbg_detach(dhd_pub_t
*dhdp
)
2665 dhd_dbg_ring_t
*ring
= NULL
;
2671 for (ring_id
= DEBUG_RING_ID_INVALID
+ 1; ring_id
< DEBUG_RING_ID_MAX
; ring_id
++) {
2672 if (VALID_RING(dbg
->dbg_rings
[ring_id
].id
)) {
2673 ring
= &dbg
->dbg_rings
[ring_id
];
2674 dhd_dbg_ring_deinit(dhdp
, ring
);
2675 if (ring
->ring_buf
) {
2676 #ifndef CONFIG_DHD_USE_STATIC_BUF
2677 MFREE(dhdp
->osh
, ring
->ring_buf
, ring
->ring_size
);
2679 ring
->ring_buf
= NULL
;
2681 ring
->ring_size
= 0;
2684 MFREE(dhdp
->osh
, dhdp
->dbg
, sizeof(dhd_dbg_t
));
2688 dhd_dbg_get_fwverbose(dhd_pub_t
*dhdp
)
2690 if (dhdp
&& dhdp
->dbg
) {
2691 return dhdp
->dbg
->dbg_rings
[FW_VERBOSE_RING_ID
].log_level
;
2697 dhd_dbg_set_fwverbose(dhd_pub_t
*dhdp
, uint32 new_val
)
2700 if (dhdp
&& dhdp
->dbg
) {
2701 dhdp
->dbg
->dbg_rings
[FW_VERBOSE_RING_ID
].log_level
= new_val
;