xref: /OK3568_Linux_fs/external/rkwifibt/drivers/bcmdhd/dhd_mschdbg.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun  * DHD debugability support
3*4882a593Smuzhiyun  *
4*4882a593Smuzhiyun  * Copyright (C) 2020, Broadcom.
5*4882a593Smuzhiyun  *
6*4882a593Smuzhiyun  *      Unless you and Broadcom execute a separate written software license
7*4882a593Smuzhiyun  * agreement governing use of this software, this software is licensed to you
8*4882a593Smuzhiyun  * under the terms of the GNU General Public License version 2 (the "GPL"),
9*4882a593Smuzhiyun  * available at http://www.broadcom.com/licenses/GPLv2.php, with the
10*4882a593Smuzhiyun  * following added to such license:
11*4882a593Smuzhiyun  *
12*4882a593Smuzhiyun  *      As a special exception, the copyright holders of this software give you
13*4882a593Smuzhiyun  * permission to link this software with independent modules, and to copy and
14*4882a593Smuzhiyun  * distribute the resulting executable under terms of your choice, provided that
15*4882a593Smuzhiyun  * you also meet, for each linked independent module, the terms and conditions of
16*4882a593Smuzhiyun  * the license of that module.  An independent module is a module which is not
17*4882a593Smuzhiyun  * derived from this software.  The special exception does not apply to any
18*4882a593Smuzhiyun  * modifications of the software.
19*4882a593Smuzhiyun  *
20*4882a593Smuzhiyun  *
21*4882a593Smuzhiyun  * <<Broadcom-WL-IPTag/Open:>>
22*4882a593Smuzhiyun  *
23*4882a593Smuzhiyun  * $Id: dhd_mschdbg.c 639872 2016-05-25 05:39:30Z sjadhav $
24*4882a593Smuzhiyun  */
25*4882a593Smuzhiyun #ifdef SHOW_LOGTRACE
26*4882a593Smuzhiyun #include <typedefs.h>
27*4882a593Smuzhiyun #include <osl.h>
28*4882a593Smuzhiyun #include <bcmutils.h>
29*4882a593Smuzhiyun #include <bcmendian.h>
30*4882a593Smuzhiyun #include <dngl_stats.h>
31*4882a593Smuzhiyun #include <dhd.h>
32*4882a593Smuzhiyun #include <dhd_dbg.h>
33*4882a593Smuzhiyun #include <dhd_debug.h>
34*4882a593Smuzhiyun #include <dhd_mschdbg.h>
35*4882a593Smuzhiyun 
36*4882a593Smuzhiyun #include <event_log.h>
37*4882a593Smuzhiyun #include <event_trace.h>
38*4882a593Smuzhiyun #include <msgtrace.h>
39*4882a593Smuzhiyun 
40*4882a593Smuzhiyun static const char *head_log = "";
41*4882a593Smuzhiyun #define MSCH_EVENT_HEAD(space) \
42*4882a593Smuzhiyun 	do { \
43*4882a593Smuzhiyun 		MSCH_EVENT(("%s_E:  ", head_log)); \
44*4882a593Smuzhiyun 		if (space > 0) { \
45*4882a593Smuzhiyun 			int ii; \
46*4882a593Smuzhiyun 			for (ii = 0; ii < space; ii += 4) MSCH_EVENT(("    ")); \
47*4882a593Smuzhiyun 		} \
48*4882a593Smuzhiyun 	} while (0)
49*4882a593Smuzhiyun 
50*4882a593Smuzhiyun #ifdef DHD_EFI
51*4882a593Smuzhiyun #define MSCH_EVENT(args) \
52*4882a593Smuzhiyun do {	\
53*4882a593Smuzhiyun 	if (dhd_msg_level & DHD_EVENT_VAL) {	\
54*4882a593Smuzhiyun 		DHD_LOG_DUMP_WRITE_FW("[%s]: ", dhd_log_dump_get_timestamp()); \
55*4882a593Smuzhiyun 		DHD_LOG_DUMP_WRITE_FW args; \
56*4882a593Smuzhiyun 	}	\
57*4882a593Smuzhiyun } while (0)
58*4882a593Smuzhiyun #else
59*4882a593Smuzhiyun #define MSCH_EVENT(args) do {if (dhd_msg_level & DHD_EVENT_VAL) printf args;} while (0)
60*4882a593Smuzhiyun #endif /* DHD_EFI */
61*4882a593Smuzhiyun 
62*4882a593Smuzhiyun static uint64 solt_start_time[4], req_start_time[4], profiler_start_time[4];
63*4882a593Smuzhiyun static uint32 solt_chanspec[4] = {0, }, req_start[4] = {0, };
64*4882a593Smuzhiyun static bool lastMessages = FALSE;
65*4882a593Smuzhiyun 
66*4882a593Smuzhiyun #define US_PRE_SEC		1000000
67*4882a593Smuzhiyun #define DATA_UNIT_FOR_LOG_CNT	4
68*4882a593Smuzhiyun 
dhd_mschdbg_us_to_sec(uint32 time_h,uint32 time_l,uint32 * sec,uint32 * remain)69*4882a593Smuzhiyun static void dhd_mschdbg_us_to_sec(uint32 time_h, uint32 time_l, uint32 *sec, uint32 *remain)
70*4882a593Smuzhiyun {
71*4882a593Smuzhiyun 	uint64 cur_time = ((uint64)(ntoh32(time_h)) << 32) | ntoh32(time_l);
72*4882a593Smuzhiyun 	uint64 r, u = 0;
73*4882a593Smuzhiyun 
74*4882a593Smuzhiyun 	r = cur_time;
75*4882a593Smuzhiyun 	while (time_h != 0) {
76*4882a593Smuzhiyun 		u += (uint64)((0xffffffff / US_PRE_SEC)) * time_h;
77*4882a593Smuzhiyun 		r = cur_time - u * US_PRE_SEC;
78*4882a593Smuzhiyun 		time_h = (uint32)(r >> 32);
79*4882a593Smuzhiyun 	}
80*4882a593Smuzhiyun 
81*4882a593Smuzhiyun 	*sec = (uint32)(u + ((uint32)(r) / US_PRE_SEC));
82*4882a593Smuzhiyun 	*remain = (uint32)(r) % US_PRE_SEC;
83*4882a593Smuzhiyun }
84*4882a593Smuzhiyun 
dhd_mschdbg_display_time(uint32 time_h,uint32 time_l)85*4882a593Smuzhiyun static char *dhd_mschdbg_display_time(uint32 time_h, uint32 time_l)
86*4882a593Smuzhiyun {
87*4882a593Smuzhiyun 	static char display_time[32];
88*4882a593Smuzhiyun 	uint32 s, ss;
89*4882a593Smuzhiyun 
90*4882a593Smuzhiyun 	if (time_h == 0xffffffff && time_l == 0xffffffff) {
91*4882a593Smuzhiyun 		snprintf(display_time, 31, "-1");
92*4882a593Smuzhiyun 	} else {
93*4882a593Smuzhiyun 		dhd_mschdbg_us_to_sec(time_h, time_l, &s, &ss);
94*4882a593Smuzhiyun 		snprintf(display_time, 31, "%d.%06d", s, ss);
95*4882a593Smuzhiyun 	}
96*4882a593Smuzhiyun 	return display_time;
97*4882a593Smuzhiyun }
98*4882a593Smuzhiyun 
99*4882a593Smuzhiyun static void
dhd_mschdbg_chanspec_list(int sp,char * data,uint16 ptr,uint16 chanspec_cnt)100*4882a593Smuzhiyun dhd_mschdbg_chanspec_list(int sp, char *data, uint16 ptr, uint16 chanspec_cnt)
101*4882a593Smuzhiyun {
102*4882a593Smuzhiyun 	int i, cnt = (int)ntoh16(chanspec_cnt);
103*4882a593Smuzhiyun 	uint16 *chanspec_list = (uint16 *)(data + ntoh16(ptr));
104*4882a593Smuzhiyun 	char buf[CHANSPEC_STR_LEN];
105*4882a593Smuzhiyun 	chanspec_t c;
106*4882a593Smuzhiyun 
107*4882a593Smuzhiyun 	MSCH_EVENT_HEAD(sp);
108*4882a593Smuzhiyun 	MSCH_EVENT(("<chanspec_list>:"));
109*4882a593Smuzhiyun 	for (i = 0; i < cnt; i++) {
110*4882a593Smuzhiyun 		c = (chanspec_t)ntoh16(chanspec_list[i]);
111*4882a593Smuzhiyun 		MSCH_EVENT((" %s", wf_chspec_ntoa(c, buf)));
112*4882a593Smuzhiyun 	}
113*4882a593Smuzhiyun 	MSCH_EVENT(("\n"));
114*4882a593Smuzhiyun }
115*4882a593Smuzhiyun 
116*4882a593Smuzhiyun static void
dhd_mschdbg_elem_list(int sp,char * title,char * data,uint16 ptr,uint16 list_cnt)117*4882a593Smuzhiyun dhd_mschdbg_elem_list(int sp, char *title, char *data, uint16 ptr, uint16 list_cnt)
118*4882a593Smuzhiyun {
119*4882a593Smuzhiyun 	int i, cnt = (int)ntoh16(list_cnt);
120*4882a593Smuzhiyun 	uint32 *list = (uint32 *)(data + ntoh16(ptr));
121*4882a593Smuzhiyun 
122*4882a593Smuzhiyun 	MSCH_EVENT_HEAD(sp);
123*4882a593Smuzhiyun 	MSCH_EVENT(("%s_list: ", title));
124*4882a593Smuzhiyun 	for (i = 0; i < cnt; i++) {
125*4882a593Smuzhiyun 		MSCH_EVENT(("0x%08x->", ntoh32(list[i])));
126*4882a593Smuzhiyun 	}
127*4882a593Smuzhiyun 	MSCH_EVENT(("null\n"));
128*4882a593Smuzhiyun }
129*4882a593Smuzhiyun 
130*4882a593Smuzhiyun static void
dhd_mschdbg_req_param_profiler_event_data(int sp,int ver,char * data,uint16 ptr)131*4882a593Smuzhiyun dhd_mschdbg_req_param_profiler_event_data(int sp, int ver, char *data, uint16 ptr)
132*4882a593Smuzhiyun {
133*4882a593Smuzhiyun 	int sn = sp + 4;
134*4882a593Smuzhiyun 	msch_req_param_profiler_event_data_t *p =
135*4882a593Smuzhiyun 		(msch_req_param_profiler_event_data_t *)(data + ntoh16(ptr));
136*4882a593Smuzhiyun 	uint32 type, flags;
137*4882a593Smuzhiyun 
138*4882a593Smuzhiyun 	MSCH_EVENT_HEAD(sp);
139*4882a593Smuzhiyun 	MSCH_EVENT(("<request parameters>\n"));
140*4882a593Smuzhiyun 	MSCH_EVENT_HEAD(sn);
141*4882a593Smuzhiyun 	MSCH_EVENT(("req_type: "));
142*4882a593Smuzhiyun 
143*4882a593Smuzhiyun 	type = p->req_type;
144*4882a593Smuzhiyun 	if (type < 4) {
145*4882a593Smuzhiyun 		char *req_type[] = {"fixed", "start-flexible", "duration-flexible",
146*4882a593Smuzhiyun 			"both-flexible"};
147*4882a593Smuzhiyun 		MSCH_EVENT(("%s", req_type[type]));
148*4882a593Smuzhiyun 	}
149*4882a593Smuzhiyun 	else
150*4882a593Smuzhiyun 		MSCH_EVENT(("unknown(%d)", type));
151*4882a593Smuzhiyun 
152*4882a593Smuzhiyun 	flags = ntoh16(p->flags);
153*4882a593Smuzhiyun 	if (flags & WL_MSCH_REQ_FLAGS_CHAN_CONTIGUOUS)
154*4882a593Smuzhiyun 		MSCH_EVENT((", CHAN_CONTIGUOUS"));
155*4882a593Smuzhiyun 	if (flags & WL_MSCH_REQ_FLAGS_MERGE_CONT_SLOTS)
156*4882a593Smuzhiyun 		MSCH_EVENT((", MERGE_CONT_SLOTS"));
157*4882a593Smuzhiyun 	if (flags & WL_MSCH_REQ_FLAGS_PREMTABLE)
158*4882a593Smuzhiyun 		MSCH_EVENT((", PREMTABLE"));
159*4882a593Smuzhiyun 	if (flags & WL_MSCH_REQ_FLAGS_PREMT_CURTS)
160*4882a593Smuzhiyun 		MSCH_EVENT((", PREMT_CURTS"));
161*4882a593Smuzhiyun 	if (flags & WL_MSCH_REQ_FLAGS_PREMT_IMMEDIATE)
162*4882a593Smuzhiyun 		MSCH_EVENT((", PREMT_IMMEDIATE"));
163*4882a593Smuzhiyun 	MSCH_EVENT((", priority: %d\n", p->priority));
164*4882a593Smuzhiyun 
165*4882a593Smuzhiyun 	MSCH_EVENT_HEAD(sn);
166*4882a593Smuzhiyun 	MSCH_EVENT(("start-time: %s, duration: %d(us), interval: %d(us)\n",
167*4882a593Smuzhiyun 		dhd_mschdbg_display_time(p->start_time_h, p->start_time_l),
168*4882a593Smuzhiyun 		ntoh32(p->duration), ntoh32(p->interval)));
169*4882a593Smuzhiyun 
170*4882a593Smuzhiyun 	if (type == WL_MSCH_RT_DUR_FLEX) {
171*4882a593Smuzhiyun 		MSCH_EVENT_HEAD(sn);
172*4882a593Smuzhiyun 		MSCH_EVENT(("dur_flex: %d(us)\n", ntoh32(p->flex.dur_flex)));
173*4882a593Smuzhiyun 	} else if (type == WL_MSCH_RT_BOTH_FLEX) {
174*4882a593Smuzhiyun 		MSCH_EVENT_HEAD(sn);
175*4882a593Smuzhiyun 		MSCH_EVENT(("min_dur: %d(us), max_away_dur: %d(us)\n",
176*4882a593Smuzhiyun 			ntoh32(p->flex.bf.min_dur), ntoh32(p->flex.bf.max_away_dur)));
177*4882a593Smuzhiyun 
178*4882a593Smuzhiyun 		MSCH_EVENT_HEAD(sn);
179*4882a593Smuzhiyun 		MSCH_EVENT(("hi_prio_time: %s, hi_prio_interval: %d(us)\n",
180*4882a593Smuzhiyun 			dhd_mschdbg_display_time(p->flex.bf.hi_prio_time_h,
181*4882a593Smuzhiyun 			p->flex.bf.hi_prio_time_l),
182*4882a593Smuzhiyun 			ntoh32(p->flex.bf.hi_prio_interval)));
183*4882a593Smuzhiyun 	}
184*4882a593Smuzhiyun }
185*4882a593Smuzhiyun 
186*4882a593Smuzhiyun static void
dhd_mschdbg_timeslot_profiler_event_data(int sp,int ver,char * title,char * data,uint16 ptr,bool empty)187*4882a593Smuzhiyun dhd_mschdbg_timeslot_profiler_event_data(int sp, int ver, char *title, char *data,
188*4882a593Smuzhiyun 	uint16 ptr, bool empty)
189*4882a593Smuzhiyun {
190*4882a593Smuzhiyun 	int s, sn = sp + 4;
191*4882a593Smuzhiyun 	msch_timeslot_profiler_event_data_t *p =
192*4882a593Smuzhiyun 		(msch_timeslot_profiler_event_data_t *)(data + ntoh16(ptr));
193*4882a593Smuzhiyun 	char *state[] = {"NONE", "CHN_SW", "ONCHAN_FIRE", "OFF_CHN_PREP",
194*4882a593Smuzhiyun 		"OFF_CHN_DONE", "TS_COMPLETE"};
195*4882a593Smuzhiyun 
196*4882a593Smuzhiyun 	MSCH_EVENT_HEAD(sp);
197*4882a593Smuzhiyun 	MSCH_EVENT(("<%s timeslot>: ", title));
198*4882a593Smuzhiyun 	if (empty) {
199*4882a593Smuzhiyun 		MSCH_EVENT((" null\n"));
200*4882a593Smuzhiyun 		return;
201*4882a593Smuzhiyun 	}
202*4882a593Smuzhiyun 	else
203*4882a593Smuzhiyun 		MSCH_EVENT(("0x%08x\n", ntoh32(p->p_timeslot)));
204*4882a593Smuzhiyun 
205*4882a593Smuzhiyun 	s = (int)(ntoh32(p->state));
206*4882a593Smuzhiyun 	if (s < 0 || s > 5) s = 0;
207*4882a593Smuzhiyun 
208*4882a593Smuzhiyun 	MSCH_EVENT_HEAD(sn);
209*4882a593Smuzhiyun 	MSCH_EVENT(("id: %d, state[%d]: %s, chan_ctxt: [0x%08x]\n",
210*4882a593Smuzhiyun 		ntoh32(p->timeslot_id), ntoh32(p->state), state[s], ntoh32(p->p_chan_ctxt)));
211*4882a593Smuzhiyun 
212*4882a593Smuzhiyun 	MSCH_EVENT_HEAD(sn);
213*4882a593Smuzhiyun 	MSCH_EVENT(("fire_time: %s",
214*4882a593Smuzhiyun 		dhd_mschdbg_display_time(p->fire_time_h, p->fire_time_l)));
215*4882a593Smuzhiyun 
216*4882a593Smuzhiyun 	MSCH_EVENT((", pre_start_time: %s",
217*4882a593Smuzhiyun 		dhd_mschdbg_display_time(p->pre_start_time_h, p->pre_start_time_l)));
218*4882a593Smuzhiyun 
219*4882a593Smuzhiyun 	MSCH_EVENT((", end_time: %s",
220*4882a593Smuzhiyun 		dhd_mschdbg_display_time(p->end_time_h, p->end_time_l)));
221*4882a593Smuzhiyun 
222*4882a593Smuzhiyun 	MSCH_EVENT((", sch_dur: %s\n",
223*4882a593Smuzhiyun 		dhd_mschdbg_display_time(p->sch_dur_h, p->sch_dur_l)));
224*4882a593Smuzhiyun }
225*4882a593Smuzhiyun 
226*4882a593Smuzhiyun static void
dhd_mschdbg_req_timing_profiler_event_data(int sp,int ver,char * title,char * data,uint16 ptr,bool empty)227*4882a593Smuzhiyun dhd_mschdbg_req_timing_profiler_event_data(int sp, int ver, char *title, char *data,
228*4882a593Smuzhiyun 	uint16 ptr, bool empty)
229*4882a593Smuzhiyun {
230*4882a593Smuzhiyun 	int sn = sp + 4;
231*4882a593Smuzhiyun 	msch_req_timing_profiler_event_data_t *p =
232*4882a593Smuzhiyun 		(msch_req_timing_profiler_event_data_t *)(data + ntoh16(ptr));
233*4882a593Smuzhiyun 	uint32 type;
234*4882a593Smuzhiyun 
235*4882a593Smuzhiyun 	MSCH_EVENT_HEAD(sp);
236*4882a593Smuzhiyun 	MSCH_EVENT(("<%s req_timing>: ", title));
237*4882a593Smuzhiyun 	if (empty) {
238*4882a593Smuzhiyun 		MSCH_EVENT((" null\n"));
239*4882a593Smuzhiyun 		return;
240*4882a593Smuzhiyun 	}
241*4882a593Smuzhiyun 	else
242*4882a593Smuzhiyun 		MSCH_EVENT(("0x%08x (prev 0x%08x, next 0x%08x)\n",
243*4882a593Smuzhiyun 			ntoh32(p->p_req_timing), ntoh32(p->p_prev), ntoh32(p->p_next)));
244*4882a593Smuzhiyun 
245*4882a593Smuzhiyun 	MSCH_EVENT_HEAD(sn);
246*4882a593Smuzhiyun 	MSCH_EVENT(("flags:"));
247*4882a593Smuzhiyun 	type = ntoh16(p->flags);
248*4882a593Smuzhiyun 	if ((type & 0x7f) == 0)
249*4882a593Smuzhiyun 		MSCH_EVENT((" NONE"));
250*4882a593Smuzhiyun 	else {
251*4882a593Smuzhiyun 		if (type & WL_MSCH_RC_FLAGS_ONCHAN_FIRE)
252*4882a593Smuzhiyun 			MSCH_EVENT((" ONCHAN_FIRE"));
253*4882a593Smuzhiyun 		if (type & WL_MSCH_RC_FLAGS_START_FIRE_DONE)
254*4882a593Smuzhiyun 			MSCH_EVENT((" START_FIRE"));
255*4882a593Smuzhiyun 		if (type & WL_MSCH_RC_FLAGS_END_FIRE_DONE)
256*4882a593Smuzhiyun 			MSCH_EVENT((" END_FIRE"));
257*4882a593Smuzhiyun 		if (type & WL_MSCH_RC_FLAGS_ONFIRE_DONE)
258*4882a593Smuzhiyun 			MSCH_EVENT((" ONFIRE_DONE"));
259*4882a593Smuzhiyun 		if (type & WL_MSCH_RC_FLAGS_SPLIT_SLOT_START)
260*4882a593Smuzhiyun 			MSCH_EVENT((" SPLIT_SLOT_START"));
261*4882a593Smuzhiyun 		if (type & WL_MSCH_RC_FLAGS_SPLIT_SLOT_END)
262*4882a593Smuzhiyun 			MSCH_EVENT((" SPLIT_SLOT_END"));
263*4882a593Smuzhiyun 		if (type & WL_MSCH_RC_FLAGS_PRE_ONFIRE_DONE)
264*4882a593Smuzhiyun 			MSCH_EVENT((" PRE_ONFIRE_DONE"));
265*4882a593Smuzhiyun 	}
266*4882a593Smuzhiyun 	MSCH_EVENT(("\n"));
267*4882a593Smuzhiyun 
268*4882a593Smuzhiyun 	MSCH_EVENT_HEAD(sn);
269*4882a593Smuzhiyun 	MSCH_EVENT(("pre_start_time: %s",
270*4882a593Smuzhiyun 		dhd_mschdbg_display_time(p->pre_start_time_h, p->pre_start_time_l)));
271*4882a593Smuzhiyun 
272*4882a593Smuzhiyun 	MSCH_EVENT((", start_time: %s",
273*4882a593Smuzhiyun 		dhd_mschdbg_display_time(p->start_time_h, p->start_time_l)));
274*4882a593Smuzhiyun 
275*4882a593Smuzhiyun 	MSCH_EVENT((", end_time: %s\n",
276*4882a593Smuzhiyun 		dhd_mschdbg_display_time(p->end_time_h, p->end_time_l)));
277*4882a593Smuzhiyun 
278*4882a593Smuzhiyun 	if (p->p_timeslot && (p->timeslot_ptr == 0)) {
279*4882a593Smuzhiyun 		MSCH_EVENT_HEAD(sn);
280*4882a593Smuzhiyun 		MSCH_EVENT(("<%s timeslot>: 0x%08x\n", title, ntoh32(p->p_timeslot)));
281*4882a593Smuzhiyun 	} else
282*4882a593Smuzhiyun 		dhd_mschdbg_timeslot_profiler_event_data(sn, ver, title, data, p->timeslot_ptr,
283*4882a593Smuzhiyun 			(p->timeslot_ptr == 0));
284*4882a593Smuzhiyun }
285*4882a593Smuzhiyun 
286*4882a593Smuzhiyun static void
dhd_mschdbg_chan_ctxt_profiler_event_data(int sp,int ver,char * data,uint16 ptr,bool empty)287*4882a593Smuzhiyun dhd_mschdbg_chan_ctxt_profiler_event_data(int sp, int ver, char *data, uint16 ptr, bool empty)
288*4882a593Smuzhiyun {
289*4882a593Smuzhiyun 	int sn = sp + 4;
290*4882a593Smuzhiyun 	msch_chan_ctxt_profiler_event_data_t *p =
291*4882a593Smuzhiyun 		(msch_chan_ctxt_profiler_event_data_t *)(data + ntoh16(ptr));
292*4882a593Smuzhiyun 	chanspec_t c;
293*4882a593Smuzhiyun 	char buf[CHANSPEC_STR_LEN];
294*4882a593Smuzhiyun 
295*4882a593Smuzhiyun 	MSCH_EVENT_HEAD(sp);
296*4882a593Smuzhiyun 	MSCH_EVENT(("<chan_ctxt>: "));
297*4882a593Smuzhiyun 	if (empty) {
298*4882a593Smuzhiyun 		MSCH_EVENT((" null\n"));
299*4882a593Smuzhiyun 		return;
300*4882a593Smuzhiyun 	}
301*4882a593Smuzhiyun 	else
302*4882a593Smuzhiyun 		MSCH_EVENT(("0x%08x (prev 0x%08x, next 0x%08x)\n",
303*4882a593Smuzhiyun 			ntoh32(p->p_chan_ctxt), ntoh32(p->p_prev), ntoh32(p->p_next)));
304*4882a593Smuzhiyun 
305*4882a593Smuzhiyun 	c = (chanspec_t)ntoh16(p->chanspec);
306*4882a593Smuzhiyun 
307*4882a593Smuzhiyun 	MSCH_EVENT_HEAD(sn);
308*4882a593Smuzhiyun 	MSCH_EVENT(("channel: %s, bf_sch_pending: %s, bf_skipped: %d\n",
309*4882a593Smuzhiyun 		wf_chspec_ntoa(c, buf), p->bf_sch_pending? "TRUE" : "FALSE",
310*4882a593Smuzhiyun 		ntoh32(p->bf_skipped_count)));
311*4882a593Smuzhiyun 
312*4882a593Smuzhiyun 	MSCH_EVENT_HEAD(sn);
313*4882a593Smuzhiyun 	MSCH_EVENT(("bf_link: prev 0x%08x, next 0x%08x\n",
314*4882a593Smuzhiyun 		ntoh32(p->bf_link_prev), ntoh32(p->bf_link_next)));
315*4882a593Smuzhiyun 
316*4882a593Smuzhiyun 	MSCH_EVENT_HEAD(sn);
317*4882a593Smuzhiyun 	MSCH_EVENT(("onchan_time: %s",
318*4882a593Smuzhiyun 		dhd_mschdbg_display_time(p->onchan_time_h, p->onchan_time_l)));
319*4882a593Smuzhiyun 	MSCH_EVENT((", actual_onchan_dur: %s",
320*4882a593Smuzhiyun 		dhd_mschdbg_display_time(p->actual_onchan_dur_h, p->actual_onchan_dur_l)));
321*4882a593Smuzhiyun 	MSCH_EVENT((", pend_onchan_dur: %s\n",
322*4882a593Smuzhiyun 		dhd_mschdbg_display_time(p->pend_onchan_dur_h, p->pend_onchan_dur_l)));
323*4882a593Smuzhiyun 
324*4882a593Smuzhiyun 	dhd_mschdbg_elem_list(sn, "req_entity", data, p->req_entity_list_ptr,
325*4882a593Smuzhiyun 		p->req_entity_list_cnt);
326*4882a593Smuzhiyun 	dhd_mschdbg_elem_list(sn, "bf_entity", data, p->bf_entity_list_ptr,
327*4882a593Smuzhiyun 		p->bf_entity_list_cnt);
328*4882a593Smuzhiyun }
329*4882a593Smuzhiyun 
330*4882a593Smuzhiyun static void
dhd_mschdbg_req_entity_profiler_event_data(int sp,int ver,char * data,uint16 ptr,bool empty)331*4882a593Smuzhiyun dhd_mschdbg_req_entity_profiler_event_data(int sp, int ver, char *data, uint16 ptr, bool empty)
332*4882a593Smuzhiyun {
333*4882a593Smuzhiyun 	int sn = sp + 4;
334*4882a593Smuzhiyun 	msch_req_entity_profiler_event_data_t *p =
335*4882a593Smuzhiyun 		(msch_req_entity_profiler_event_data_t *)(data + ntoh16(ptr));
336*4882a593Smuzhiyun 	char buf[CHANSPEC_STR_LEN];
337*4882a593Smuzhiyun 	chanspec_t c;
338*4882a593Smuzhiyun 	uint32 flags;
339*4882a593Smuzhiyun 
340*4882a593Smuzhiyun 	MSCH_EVENT_HEAD(sp);
341*4882a593Smuzhiyun 	MSCH_EVENT(("<req_entity>: "));
342*4882a593Smuzhiyun 	if (empty) {
343*4882a593Smuzhiyun 		MSCH_EVENT((" null\n"));
344*4882a593Smuzhiyun 		return;
345*4882a593Smuzhiyun 	}
346*4882a593Smuzhiyun 	else
347*4882a593Smuzhiyun 		MSCH_EVENT(("0x%08x (prev 0x%08x, next 0x%08x)\n",
348*4882a593Smuzhiyun 			ntoh32(p->p_req_entity), ntoh32(p->req_hdl_link_prev),
349*4882a593Smuzhiyun 			ntoh32(p->req_hdl_link_next)));
350*4882a593Smuzhiyun 
351*4882a593Smuzhiyun 	MSCH_EVENT_HEAD(sn);
352*4882a593Smuzhiyun 	MSCH_EVENT(("req_hdl: [0x%08x]\n", ntoh32(p->p_req_hdl)));
353*4882a593Smuzhiyun 
354*4882a593Smuzhiyun 	MSCH_EVENT_HEAD(sn);
355*4882a593Smuzhiyun 	MSCH_EVENT(("chan_ctxt_link: prev 0x%08x, next 0x%08x\n",
356*4882a593Smuzhiyun 		ntoh32(p->chan_ctxt_link_prev), ntoh32(p->chan_ctxt_link_next)));
357*4882a593Smuzhiyun 	MSCH_EVENT_HEAD(sn);
358*4882a593Smuzhiyun 	MSCH_EVENT(("rt_specific_link: prev 0x%08x, next 0x%08x\n",
359*4882a593Smuzhiyun 		ntoh32(p->rt_specific_link_prev), ntoh32(p->rt_specific_link_next)));
360*4882a593Smuzhiyun 	MSCH_EVENT_HEAD(sn);
361*4882a593Smuzhiyun 	MSCH_EVENT(("start_fixed_link: prev 0x%08x, next 0x%08x\n",
362*4882a593Smuzhiyun 		ntoh32(p->start_fixed_link_prev), ntoh32(p->start_fixed_link_next)));
363*4882a593Smuzhiyun 	MSCH_EVENT_HEAD(sn);
364*4882a593Smuzhiyun 	MSCH_EVENT(("both_flex_list: prev 0x%08x, next 0x%08x\n",
365*4882a593Smuzhiyun 		ntoh32(p->both_flex_list_prev), ntoh32(p->both_flex_list_next)));
366*4882a593Smuzhiyun 
367*4882a593Smuzhiyun 	c = (chanspec_t)ntoh16(p->chanspec);
368*4882a593Smuzhiyun 	MSCH_EVENT_HEAD(sn);
369*4882a593Smuzhiyun 	if (ver >= 2) {
370*4882a593Smuzhiyun 		MSCH_EVENT(("channel: %s, onchan Id %d, current chan Id %d, priority %d",
371*4882a593Smuzhiyun 			wf_chspec_ntoa(c, buf), ntoh16(p->onchan_chn_idx), ntoh16(p->cur_chn_idx),
372*4882a593Smuzhiyun 			ntoh16(p->priority)));
373*4882a593Smuzhiyun 		flags = ntoh32(p->flags);
374*4882a593Smuzhiyun 		if (flags & WL_MSCH_ENTITY_FLAG_MULTI_INSTANCE)
375*4882a593Smuzhiyun 			MSCH_EVENT((" : MULTI_INSTANCE\n"));
376*4882a593Smuzhiyun 		else
377*4882a593Smuzhiyun 			MSCH_EVENT(("\n"));
378*4882a593Smuzhiyun 		MSCH_EVENT_HEAD(sn);
379*4882a593Smuzhiyun 		MSCH_EVENT(("actual_start_time: %s, ",
380*4882a593Smuzhiyun 			dhd_mschdbg_display_time(p->actual_start_time_h, p->actual_start_time_l)));
381*4882a593Smuzhiyun 		MSCH_EVENT(("curts_fire_time: %s, ",
382*4882a593Smuzhiyun 			dhd_mschdbg_display_time(p->curts_fire_time_h, p->curts_fire_time_l)));
383*4882a593Smuzhiyun 	} else {
384*4882a593Smuzhiyun 		MSCH_EVENT(("channel: %s, priority %d, ", wf_chspec_ntoa(c, buf),
385*4882a593Smuzhiyun 			ntoh16(p->priority)));
386*4882a593Smuzhiyun 	}
387*4882a593Smuzhiyun 	MSCH_EVENT(("bf_last_serv_time: %s\n",
388*4882a593Smuzhiyun 		dhd_mschdbg_display_time(p->bf_last_serv_time_h, p->bf_last_serv_time_l)));
389*4882a593Smuzhiyun 
390*4882a593Smuzhiyun 	dhd_mschdbg_req_timing_profiler_event_data(sn, ver, "current", data, p->cur_slot_ptr,
391*4882a593Smuzhiyun 		(p->cur_slot_ptr == 0));
392*4882a593Smuzhiyun 	dhd_mschdbg_req_timing_profiler_event_data(sn, ver, "pending", data, p->pend_slot_ptr,
393*4882a593Smuzhiyun 		(p->pend_slot_ptr == 0));
394*4882a593Smuzhiyun 
395*4882a593Smuzhiyun 	if (p->p_chan_ctxt && (p->chan_ctxt_ptr == 0)) {
396*4882a593Smuzhiyun 		MSCH_EVENT_HEAD(sn);
397*4882a593Smuzhiyun 		MSCH_EVENT(("<chan_ctxt>: 0x%08x\n", ntoh32(p->p_chan_ctxt)));
398*4882a593Smuzhiyun 	}
399*4882a593Smuzhiyun 	else
400*4882a593Smuzhiyun 		dhd_mschdbg_chan_ctxt_profiler_event_data(sn, ver, data, p->chan_ctxt_ptr,
401*4882a593Smuzhiyun 			(p->chan_ctxt_ptr == 0));
402*4882a593Smuzhiyun }
403*4882a593Smuzhiyun 
404*4882a593Smuzhiyun static void
dhd_mschdbg_req_handle_profiler_event_data(int sp,int ver,char * data,uint16 ptr,bool empty)405*4882a593Smuzhiyun dhd_mschdbg_req_handle_profiler_event_data(int sp, int ver, char *data, uint16 ptr, bool empty)
406*4882a593Smuzhiyun {
407*4882a593Smuzhiyun 	int sn = sp + 4;
408*4882a593Smuzhiyun 	msch_req_handle_profiler_event_data_t *p =
409*4882a593Smuzhiyun 		(msch_req_handle_profiler_event_data_t *)(data + ntoh16(ptr));
410*4882a593Smuzhiyun 	uint32 flags;
411*4882a593Smuzhiyun 
412*4882a593Smuzhiyun 	MSCH_EVENT_HEAD(sp);
413*4882a593Smuzhiyun 	MSCH_EVENT(("<req_handle>: "));
414*4882a593Smuzhiyun 	if (empty) {
415*4882a593Smuzhiyun 		MSCH_EVENT((" null\n"));
416*4882a593Smuzhiyun 		return;
417*4882a593Smuzhiyun 	}
418*4882a593Smuzhiyun 	else
419*4882a593Smuzhiyun 		MSCH_EVENT(("0x%08x (prev 0x%08x, next 0x%08x)\n",
420*4882a593Smuzhiyun 			ntoh32(p->p_req_handle), ntoh32(p->p_prev), ntoh32(p->p_next)));
421*4882a593Smuzhiyun 
422*4882a593Smuzhiyun 	dhd_mschdbg_elem_list(sn, "req_entity", data, p->req_entity_list_ptr,
423*4882a593Smuzhiyun 		p->req_entity_list_cnt);
424*4882a593Smuzhiyun 	MSCH_EVENT_HEAD(sn);
425*4882a593Smuzhiyun 	MSCH_EVENT(("cb_func: [0x%08x], cb_func: [0x%08x]",
426*4882a593Smuzhiyun 		ntoh32(p->cb_func), ntoh32(p->cb_ctxt)));
427*4882a593Smuzhiyun 	if (ver < 2) {
428*4882a593Smuzhiyun 		MSCH_EVENT((", chan_cnt: %d", ntoh16(p->chan_cnt)));
429*4882a593Smuzhiyun 	}
430*4882a593Smuzhiyun 	flags = ntoh32(p->flags);
431*4882a593Smuzhiyun 	if (flags & WL_MSCH_REQ_HDL_FLAGS_NEW_REQ)
432*4882a593Smuzhiyun 		MSCH_EVENT((", NEW_REQ"));
433*4882a593Smuzhiyun 	MSCH_EVENT(("\n"));
434*4882a593Smuzhiyun 
435*4882a593Smuzhiyun 	dhd_mschdbg_req_param_profiler_event_data(sn, ver, data, p->req_param_ptr);
436*4882a593Smuzhiyun 
437*4882a593Smuzhiyun 	if (ver >= 2) {
438*4882a593Smuzhiyun 		MSCH_EVENT_HEAD(sn);
439*4882a593Smuzhiyun 		MSCH_EVENT(("req_time: %s\n",
440*4882a593Smuzhiyun 			dhd_mschdbg_display_time(p->req_time_h, p->req_time_l)));
441*4882a593Smuzhiyun 		MSCH_EVENT_HEAD(sn);
442*4882a593Smuzhiyun 		MSCH_EVENT(("chan_cnt: %d, chan idx %d, last chan idx %d\n",
443*4882a593Smuzhiyun 			ntoh16(p->chan_cnt), ntoh16(p->chan_idx), ntoh16(p->last_chan_idx)));
444*4882a593Smuzhiyun 		if (p->chanspec_list && p->chanspec_cnt) {
445*4882a593Smuzhiyun 			dhd_mschdbg_chanspec_list(sn, data, p->chanspec_list, p->chanspec_cnt);
446*4882a593Smuzhiyun 		}
447*4882a593Smuzhiyun 	}
448*4882a593Smuzhiyun }
449*4882a593Smuzhiyun 
450*4882a593Smuzhiyun static void
dhd_mschdbg_profiler_profiler_event_data(int sp,int ver,char * data,uint16 ptr)451*4882a593Smuzhiyun dhd_mschdbg_profiler_profiler_event_data(int sp, int ver, char *data, uint16 ptr)
452*4882a593Smuzhiyun {
453*4882a593Smuzhiyun 	msch_profiler_profiler_event_data_t *p =
454*4882a593Smuzhiyun 		(msch_profiler_profiler_event_data_t *)(data + ntoh16(ptr));
455*4882a593Smuzhiyun 	uint32 flags;
456*4882a593Smuzhiyun 
457*4882a593Smuzhiyun 	MSCH_EVENT_HEAD(sp);
458*4882a593Smuzhiyun 	MSCH_EVENT(("free list: req_hdl 0x%08x, req_entity 0x%08x,"
459*4882a593Smuzhiyun 		" chan_ctxt 0x%08x, chanspec 0x%08x\n",
460*4882a593Smuzhiyun 		ntoh32(p->free_req_hdl_list), ntoh32(p->free_req_entity_list),
461*4882a593Smuzhiyun 		ntoh32(p->free_chan_ctxt_list), ntoh32(p->free_chanspec_list)));
462*4882a593Smuzhiyun 
463*4882a593Smuzhiyun 	MSCH_EVENT_HEAD(sp);
464*4882a593Smuzhiyun 	MSCH_EVENT(("alloc count: chanspec %d, req_entity %d, req_hdl %d, "
465*4882a593Smuzhiyun 		"chan_ctxt %d, timeslot %d\n",
466*4882a593Smuzhiyun 		ntoh16(p->msch_chanspec_alloc_cnt), ntoh16(p->msch_req_entity_alloc_cnt),
467*4882a593Smuzhiyun 		ntoh16(p->msch_req_hdl_alloc_cnt), ntoh16(p->msch_chan_ctxt_alloc_cnt),
468*4882a593Smuzhiyun 		ntoh16(p->msch_timeslot_alloc_cnt)));
469*4882a593Smuzhiyun 
470*4882a593Smuzhiyun 	dhd_mschdbg_elem_list(sp, "req_hdl", data, p->msch_req_hdl_list_ptr,
471*4882a593Smuzhiyun 		p->msch_req_hdl_list_cnt);
472*4882a593Smuzhiyun 	dhd_mschdbg_elem_list(sp, "chan_ctxt", data, p->msch_chan_ctxt_list_ptr,
473*4882a593Smuzhiyun 		p->msch_chan_ctxt_list_cnt);
474*4882a593Smuzhiyun 	dhd_mschdbg_elem_list(sp, "req_timing", data, p->msch_req_timing_list_ptr,
475*4882a593Smuzhiyun 		p->msch_req_timing_list_cnt);
476*4882a593Smuzhiyun 	dhd_mschdbg_elem_list(sp, "start_fixed", data, p->msch_start_fixed_list_ptr,
477*4882a593Smuzhiyun 		p->msch_start_fixed_list_cnt);
478*4882a593Smuzhiyun 	dhd_mschdbg_elem_list(sp, "both_flex_req_entity", data,
479*4882a593Smuzhiyun 		p->msch_both_flex_req_entity_list_ptr,
480*4882a593Smuzhiyun 		p->msch_both_flex_req_entity_list_cnt);
481*4882a593Smuzhiyun 	dhd_mschdbg_elem_list(sp, "start_flex", data, p->msch_start_flex_list_ptr,
482*4882a593Smuzhiyun 		p->msch_start_flex_list_cnt);
483*4882a593Smuzhiyun 	dhd_mschdbg_elem_list(sp, "both_flex", data, p->msch_both_flex_list_ptr,
484*4882a593Smuzhiyun 		p->msch_both_flex_list_cnt);
485*4882a593Smuzhiyun 
486*4882a593Smuzhiyun 	if (p->p_cur_msch_timeslot && (p->cur_msch_timeslot_ptr == 0)) {
487*4882a593Smuzhiyun 		MSCH_EVENT_HEAD(sp);
488*4882a593Smuzhiyun 		MSCH_EVENT(("<cur_msch timeslot>: 0x%08x\n",
489*4882a593Smuzhiyun 			ntoh32(p->p_cur_msch_timeslot)));
490*4882a593Smuzhiyun 	} else
491*4882a593Smuzhiyun 		dhd_mschdbg_timeslot_profiler_event_data(sp, ver, "cur_msch", data,
492*4882a593Smuzhiyun 			p->cur_msch_timeslot_ptr, (p->cur_msch_timeslot_ptr == 0));
493*4882a593Smuzhiyun 
494*4882a593Smuzhiyun 	if (p->p_next_timeslot && (p->next_timeslot_ptr == 0)) {
495*4882a593Smuzhiyun 		MSCH_EVENT_HEAD(sp);
496*4882a593Smuzhiyun 		MSCH_EVENT(("<next timeslot>: 0x%08x\n",
497*4882a593Smuzhiyun 			ntoh32(p->p_next_timeslot)));
498*4882a593Smuzhiyun 	} else
499*4882a593Smuzhiyun 		dhd_mschdbg_timeslot_profiler_event_data(sp, ver, "next", data,
500*4882a593Smuzhiyun 			p->next_timeslot_ptr, (p->next_timeslot_ptr == 0));
501*4882a593Smuzhiyun 
502*4882a593Smuzhiyun 	MSCH_EVENT_HEAD(sp);
503*4882a593Smuzhiyun 	MSCH_EVENT(("ts_id: %d, ", ntoh32(p->ts_id)));
504*4882a593Smuzhiyun 	flags = ntoh32(p->flags);
505*4882a593Smuzhiyun 	if (flags & WL_MSCH_STATE_IN_TIEMR_CTXT)
506*4882a593Smuzhiyun 		MSCH_EVENT(("IN_TIEMR_CTXT, "));
507*4882a593Smuzhiyun 	if (flags & WL_MSCH_STATE_SCHD_PENDING)
508*4882a593Smuzhiyun 		MSCH_EVENT(("SCHD_PENDING, "));
509*4882a593Smuzhiyun 	MSCH_EVENT(("slotskip_flags: %d, cur_armed_timeslot: 0x%08x\n",
510*4882a593Smuzhiyun 		(ver >= 2)? ntoh32(p->slotskip_flag) : 0, ntoh32(p->cur_armed_timeslot)));
511*4882a593Smuzhiyun 	MSCH_EVENT_HEAD(sp);
512*4882a593Smuzhiyun 	MSCH_EVENT(("flex_list_cnt: %d, service_interval: %d, "
513*4882a593Smuzhiyun 		"max_lo_prio_interval: %d\n",
514*4882a593Smuzhiyun 		ntoh16(p->flex_list_cnt), ntoh32(p->service_interval),
515*4882a593Smuzhiyun 		ntoh32(p->max_lo_prio_interval)));
516*4882a593Smuzhiyun }
517*4882a593Smuzhiyun 
dhd_mschdbg_dump_data(dhd_pub_t * dhdp,void * raw_event_ptr,int type,char * data,int len)518*4882a593Smuzhiyun static void dhd_mschdbg_dump_data(dhd_pub_t *dhdp, void *raw_event_ptr, int type,
519*4882a593Smuzhiyun 	char *data, int len)
520*4882a593Smuzhiyun {
521*4882a593Smuzhiyun 	uint64 t = 0, tt = 0;
522*4882a593Smuzhiyun 	uint32 s = 0, ss = 0;
523*4882a593Smuzhiyun 	int wlc_index, ver;
524*4882a593Smuzhiyun 
525*4882a593Smuzhiyun 	ver = (type & WL_MSCH_PROFILER_VER_MASK) >> WL_MSCH_PROFILER_VER_SHIFT;
526*4882a593Smuzhiyun 	wlc_index = (type & WL_MSCH_PROFILER_WLINDEX_MASK) >> WL_MSCH_PROFILER_WLINDEX_SHIFT;
527*4882a593Smuzhiyun 	if (wlc_index >= 4)
528*4882a593Smuzhiyun 		return;
529*4882a593Smuzhiyun 
530*4882a593Smuzhiyun 	type &= WL_MSCH_PROFILER_TYPE_MASK;
531*4882a593Smuzhiyun 	if (type <= WL_MSCH_PROFILER_PROFILE_END) {
532*4882a593Smuzhiyun 		msch_profiler_event_data_t *pevent = (msch_profiler_event_data_t *)data;
533*4882a593Smuzhiyun 		tt = ((uint64)(ntoh32(pevent->time_hi)) << 32) | ntoh32(pevent->time_lo);
534*4882a593Smuzhiyun 		dhd_mschdbg_us_to_sec(pevent->time_hi, pevent->time_lo, &s, &ss);
535*4882a593Smuzhiyun 	}
536*4882a593Smuzhiyun 
537*4882a593Smuzhiyun 	if (lastMessages && (type != WL_MSCH_PROFILER_MESSAGE) &&
538*4882a593Smuzhiyun 		(type != WL_MSCH_PROFILER_EVENT_LOG)) {
539*4882a593Smuzhiyun 		MSCH_EVENT_HEAD(0);
540*4882a593Smuzhiyun 		MSCH_EVENT(("\n"));
541*4882a593Smuzhiyun 		lastMessages = FALSE;
542*4882a593Smuzhiyun 	}
543*4882a593Smuzhiyun 
544*4882a593Smuzhiyun 	switch (type) {
545*4882a593Smuzhiyun 	case WL_MSCH_PROFILER_START:
546*4882a593Smuzhiyun 		MSCH_EVENT_HEAD(0);
547*4882a593Smuzhiyun 		MSCH_EVENT(("%06d.%06d START\n", s, ss));
548*4882a593Smuzhiyun 		break;
549*4882a593Smuzhiyun 
550*4882a593Smuzhiyun 	case WL_MSCH_PROFILER_EXIT:
551*4882a593Smuzhiyun 		MSCH_EVENT_HEAD(0);
552*4882a593Smuzhiyun 		MSCH_EVENT(("%06d.%06d EXIT\n", s, ss));
553*4882a593Smuzhiyun 		break;
554*4882a593Smuzhiyun 
555*4882a593Smuzhiyun 	case WL_MSCH_PROFILER_REQ:
556*4882a593Smuzhiyun 	{
557*4882a593Smuzhiyun 		msch_req_profiler_event_data_t *p = (msch_req_profiler_event_data_t *)data;
558*4882a593Smuzhiyun 		MSCH_EVENT_HEAD(0);
559*4882a593Smuzhiyun 		MSCH_EVENT(("\n"));
560*4882a593Smuzhiyun 		MSCH_EVENT_HEAD(0);
561*4882a593Smuzhiyun 		MSCH_EVENT(("===============================\n"));
562*4882a593Smuzhiyun 		MSCH_EVENT_HEAD(0);
563*4882a593Smuzhiyun 		MSCH_EVENT(("%06d.%06d [wl%d] REGISTER:\n", s, ss, wlc_index));
564*4882a593Smuzhiyun 		dhd_mschdbg_req_param_profiler_event_data(4, ver, data, p->req_param_ptr);
565*4882a593Smuzhiyun 		dhd_mschdbg_chanspec_list(4, data, p->chanspec_ptr, p->chanspec_cnt);
566*4882a593Smuzhiyun 		MSCH_EVENT_HEAD(0);
567*4882a593Smuzhiyun 		MSCH_EVENT(("===============================\n"));
568*4882a593Smuzhiyun 		MSCH_EVENT_HEAD(0);
569*4882a593Smuzhiyun 		MSCH_EVENT(("\n"));
570*4882a593Smuzhiyun 	}
571*4882a593Smuzhiyun 		break;
572*4882a593Smuzhiyun 
573*4882a593Smuzhiyun 	case WL_MSCH_PROFILER_CALLBACK:
574*4882a593Smuzhiyun 	{
575*4882a593Smuzhiyun 		msch_callback_profiler_event_data_t *p =
576*4882a593Smuzhiyun 			(msch_callback_profiler_event_data_t *)data;
577*4882a593Smuzhiyun 		char buf[CHANSPEC_STR_LEN];
578*4882a593Smuzhiyun 		chanspec_t chanspec;
579*4882a593Smuzhiyun 		uint16 cbtype;
580*4882a593Smuzhiyun 
581*4882a593Smuzhiyun 		MSCH_EVENT_HEAD(0);
582*4882a593Smuzhiyun 		MSCH_EVENT(("%06d.%06d [wl%d] CALLBACK: ", s, ss, wlc_index));
583*4882a593Smuzhiyun 		chanspec = (chanspec_t)ntoh16(p->chanspec);
584*4882a593Smuzhiyun 		MSCH_EVENT(("req_hdl[0x%08x], channel %s --",
585*4882a593Smuzhiyun 			ntoh32(p->p_req_hdl), wf_chspec_ntoa(chanspec, buf)));
586*4882a593Smuzhiyun 
587*4882a593Smuzhiyun 		cbtype = ntoh16(p->type);
588*4882a593Smuzhiyun 		if (cbtype & WL_MSCH_CT_ON_CHAN)
589*4882a593Smuzhiyun 			MSCH_EVENT((" ON_CHAN"));
590*4882a593Smuzhiyun 		if (cbtype & WL_MSCH_CT_OFF_CHAN)
591*4882a593Smuzhiyun 			MSCH_EVENT((" OFF_CHAN"));
592*4882a593Smuzhiyun 		if (cbtype & WL_MSCH_CT_REQ_START)
593*4882a593Smuzhiyun 			MSCH_EVENT((" REQ_START"));
594*4882a593Smuzhiyun 		if (cbtype & WL_MSCH_CT_REQ_END)
595*4882a593Smuzhiyun 			MSCH_EVENT((" REQ_END"));
596*4882a593Smuzhiyun 		if (cbtype & WL_MSCH_CT_SLOT_START)
597*4882a593Smuzhiyun 			MSCH_EVENT((" SLOT_START"));
598*4882a593Smuzhiyun 		if (cbtype & WL_MSCH_CT_SLOT_SKIP)
599*4882a593Smuzhiyun 			MSCH_EVENT((" SLOT_SKIP"));
600*4882a593Smuzhiyun 		if (cbtype & WL_MSCH_CT_SLOT_END)
601*4882a593Smuzhiyun 			MSCH_EVENT((" SLOT_END"));
602*4882a593Smuzhiyun 		if (cbtype & WL_MSCH_CT_OFF_CHAN_DONE)
603*4882a593Smuzhiyun 			MSCH_EVENT((" OFF_CHAN_DONE"));
604*4882a593Smuzhiyun 		if (cbtype & WL_MSCH_CT_PARTIAL)
605*4882a593Smuzhiyun 			MSCH_EVENT((" PARTIAL"));
606*4882a593Smuzhiyun 		if (cbtype & WL_MSCH_CT_PRE_ONCHAN)
607*4882a593Smuzhiyun 			MSCH_EVENT((" PRE_ONCHAN"));
608*4882a593Smuzhiyun 		if (cbtype & WL_MSCH_CT_PRE_REQ_START)
609*4882a593Smuzhiyun 			MSCH_EVENT((" PRE_REQ_START"));
610*4882a593Smuzhiyun 
611*4882a593Smuzhiyun 		if (cbtype & WL_MSCH_CT_REQ_START) {
612*4882a593Smuzhiyun 			req_start[wlc_index] = 1;
613*4882a593Smuzhiyun 			req_start_time[wlc_index] = tt;
614*4882a593Smuzhiyun 		} else if (cbtype & WL_MSCH_CT_REQ_END) {
615*4882a593Smuzhiyun 			if (req_start[wlc_index]) {
616*4882a593Smuzhiyun 				MSCH_EVENT((" : REQ duration %d",
617*4882a593Smuzhiyun 					(uint32)(tt - req_start_time[wlc_index])));
618*4882a593Smuzhiyun 				req_start[wlc_index] = 0;
619*4882a593Smuzhiyun 			}
620*4882a593Smuzhiyun 		}
621*4882a593Smuzhiyun 
622*4882a593Smuzhiyun 		if (cbtype & WL_MSCH_CT_SLOT_START) {
623*4882a593Smuzhiyun 			solt_chanspec[wlc_index] = p->chanspec;
624*4882a593Smuzhiyun 			solt_start_time[wlc_index] = tt;
625*4882a593Smuzhiyun 		} else if (cbtype & WL_MSCH_CT_SLOT_END) {
626*4882a593Smuzhiyun 			if (p->chanspec == solt_chanspec[wlc_index]) {
627*4882a593Smuzhiyun 				MSCH_EVENT((" : SLOT duration %d",
628*4882a593Smuzhiyun 					(uint32)(tt - solt_start_time[wlc_index])));
629*4882a593Smuzhiyun 				solt_chanspec[wlc_index] = 0;
630*4882a593Smuzhiyun 			}
631*4882a593Smuzhiyun 		}
632*4882a593Smuzhiyun 		MSCH_EVENT(("\n"));
633*4882a593Smuzhiyun 
634*4882a593Smuzhiyun 		if (cbtype & (WL_MSCH_CT_ON_CHAN | WL_MSCH_CT_SLOT_SKIP)) {
635*4882a593Smuzhiyun 			MSCH_EVENT_HEAD(4);
636*4882a593Smuzhiyun 			if (cbtype & WL_MSCH_CT_ON_CHAN) {
637*4882a593Smuzhiyun 				MSCH_EVENT(("ID %d onchan idx %d cur_chan_seq_start %s ",
638*4882a593Smuzhiyun 					ntoh32(p->timeslot_id), ntoh32(p->onchan_idx),
639*4882a593Smuzhiyun 					dhd_mschdbg_display_time(p->cur_chan_seq_start_time_h,
640*4882a593Smuzhiyun 					p->cur_chan_seq_start_time_l)));
641*4882a593Smuzhiyun 			}
642*4882a593Smuzhiyun 			t = ((uint64)(ntoh32(p->start_time_h)) << 32) |
643*4882a593Smuzhiyun 				ntoh32(p->start_time_l);
644*4882a593Smuzhiyun 			MSCH_EVENT(("start %s ",
645*4882a593Smuzhiyun 				dhd_mschdbg_display_time(p->start_time_h,
646*4882a593Smuzhiyun 				p->start_time_l)));
647*4882a593Smuzhiyun 			tt = ((uint64)(ntoh32(p->end_time_h)) << 32) | ntoh32(p->end_time_l);
648*4882a593Smuzhiyun 			MSCH_EVENT(("end %s duration %d\n",
649*4882a593Smuzhiyun 				dhd_mschdbg_display_time(p->end_time_h, p->end_time_l),
650*4882a593Smuzhiyun 				(p->end_time_h == 0xffffffff && p->end_time_l == 0xffffffff)?
651*4882a593Smuzhiyun 				-1 : (int)(tt - t)));
652*4882a593Smuzhiyun 		}
653*4882a593Smuzhiyun 
654*4882a593Smuzhiyun 	}
655*4882a593Smuzhiyun 		break;
656*4882a593Smuzhiyun 
657*4882a593Smuzhiyun 	case WL_MSCH_PROFILER_EVENT_LOG:
658*4882a593Smuzhiyun 	{
659*4882a593Smuzhiyun 		while (len >= (int)WL_MSCH_EVENT_LOG_HEAD_SIZE) {
660*4882a593Smuzhiyun 			msch_event_log_profiler_event_data_t *p =
661*4882a593Smuzhiyun 				(msch_event_log_profiler_event_data_t *)data;
662*4882a593Smuzhiyun 			/* TODO: How to parse MSCH if extended event tag is present ??? */
663*4882a593Smuzhiyun 			prcd_event_log_hdr_t hdr;
664*4882a593Smuzhiyun 			int size = WL_MSCH_EVENT_LOG_HEAD_SIZE + p->hdr.count * sizeof(uint32);
665*4882a593Smuzhiyun 			if (len < size || size > sizeof(msch_event_log_profiler_event_data_t)) {
666*4882a593Smuzhiyun 				break;
667*4882a593Smuzhiyun 			}
668*4882a593Smuzhiyun 			data += size;
669*4882a593Smuzhiyun 			len -= size;
670*4882a593Smuzhiyun 			dhd_mschdbg_us_to_sec(p->time_hi, p->time_lo, &s, &ss);
671*4882a593Smuzhiyun 			MSCH_EVENT_HEAD(0);
672*4882a593Smuzhiyun 			MSCH_EVENT(("%06d.%06d [wl%d]: ", s, ss, p->hdr.tag));
673*4882a593Smuzhiyun 			bzero(&hdr, sizeof(hdr));
674*4882a593Smuzhiyun 			hdr.tag = EVENT_LOG_TAG_MSCHPROFILE;
675*4882a593Smuzhiyun 			hdr.count = p->hdr.count + 1;
676*4882a593Smuzhiyun 			/* exclude LSB 2 bits which indicate binary/non-binary data */
677*4882a593Smuzhiyun 			hdr.fmt_num = ntoh16(p->hdr.fmt_num) >> 2;
678*4882a593Smuzhiyun 			hdr.fmt_num_raw = ntoh16(p->hdr.fmt_num);
679*4882a593Smuzhiyun 			if (ntoh16(p->hdr.fmt_num) == DHD_OW_BI_RAW_EVENT_LOG_FMT) {
680*4882a593Smuzhiyun 				hdr.binary_payload = TRUE;
681*4882a593Smuzhiyun 			}
682*4882a593Smuzhiyun 			dhd_dbg_verboselog_printf(dhdp, &hdr, raw_event_ptr, p->data, 0, 0);
683*4882a593Smuzhiyun 		}
684*4882a593Smuzhiyun 		lastMessages = TRUE;
685*4882a593Smuzhiyun 		break;
686*4882a593Smuzhiyun 	}
687*4882a593Smuzhiyun 
688*4882a593Smuzhiyun 	case WL_MSCH_PROFILER_MESSAGE:
689*4882a593Smuzhiyun 	{
690*4882a593Smuzhiyun 		msch_message_profiler_event_data_t *p = (msch_message_profiler_event_data_t *)data;
691*4882a593Smuzhiyun 		MSCH_EVENT_HEAD(0);
692*4882a593Smuzhiyun 		MSCH_EVENT(("%06d.%06d [wl%d]: %s", s, ss, wlc_index, p->message));
693*4882a593Smuzhiyun 		lastMessages = TRUE;
694*4882a593Smuzhiyun 		break;
695*4882a593Smuzhiyun 	}
696*4882a593Smuzhiyun 
697*4882a593Smuzhiyun 	case WL_MSCH_PROFILER_PROFILE_START:
698*4882a593Smuzhiyun 		profiler_start_time[wlc_index] = tt;
699*4882a593Smuzhiyun 		MSCH_EVENT_HEAD(0);
700*4882a593Smuzhiyun 		MSCH_EVENT(("-------------------------------\n"));
701*4882a593Smuzhiyun 		MSCH_EVENT_HEAD(0);
702*4882a593Smuzhiyun 		MSCH_EVENT(("%06d.%06d [wl%d] PROFILE DATA:\n", s, ss, wlc_index));
703*4882a593Smuzhiyun 		dhd_mschdbg_profiler_profiler_event_data(4, ver, data, 0);
704*4882a593Smuzhiyun 		break;
705*4882a593Smuzhiyun 
706*4882a593Smuzhiyun 	case WL_MSCH_PROFILER_PROFILE_END:
707*4882a593Smuzhiyun 		MSCH_EVENT_HEAD(0);
708*4882a593Smuzhiyun 		MSCH_EVENT(("%06d.%06d [wl%d] PROFILE END: take time %d\n", s, ss,
709*4882a593Smuzhiyun 			wlc_index, (uint32)(tt - profiler_start_time[wlc_index])));
710*4882a593Smuzhiyun 		MSCH_EVENT_HEAD(0);
711*4882a593Smuzhiyun 		MSCH_EVENT(("-------------------------------\n"));
712*4882a593Smuzhiyun 		MSCH_EVENT_HEAD(0);
713*4882a593Smuzhiyun 		MSCH_EVENT(("\n"));
714*4882a593Smuzhiyun 		break;
715*4882a593Smuzhiyun 
716*4882a593Smuzhiyun 	case WL_MSCH_PROFILER_REQ_HANDLE:
717*4882a593Smuzhiyun 		dhd_mschdbg_req_handle_profiler_event_data(4, ver, data, 0, FALSE);
718*4882a593Smuzhiyun 		break;
719*4882a593Smuzhiyun 
720*4882a593Smuzhiyun 	case WL_MSCH_PROFILER_REQ_ENTITY:
721*4882a593Smuzhiyun 		dhd_mschdbg_req_entity_profiler_event_data(4, ver, data, 0, FALSE);
722*4882a593Smuzhiyun 		break;
723*4882a593Smuzhiyun 
724*4882a593Smuzhiyun 	case WL_MSCH_PROFILER_CHAN_CTXT:
725*4882a593Smuzhiyun 		dhd_mschdbg_chan_ctxt_profiler_event_data(4, ver, data, 0, FALSE);
726*4882a593Smuzhiyun 		break;
727*4882a593Smuzhiyun 
728*4882a593Smuzhiyun 	case WL_MSCH_PROFILER_REQ_TIMING:
729*4882a593Smuzhiyun 		dhd_mschdbg_req_timing_profiler_event_data(4, ver, "msch", data, 0, FALSE);
730*4882a593Smuzhiyun 		break;
731*4882a593Smuzhiyun 
732*4882a593Smuzhiyun 	default:
733*4882a593Smuzhiyun 		MSCH_EVENT_HEAD(0);
734*4882a593Smuzhiyun 		MSCH_EVENT(("[wl%d] ERROR: unsupported EVENT reason code:%d; ",
735*4882a593Smuzhiyun 			wlc_index, type));
736*4882a593Smuzhiyun 		break;
737*4882a593Smuzhiyun 	}
738*4882a593Smuzhiyun }
739*4882a593Smuzhiyun 
740*4882a593Smuzhiyun void
wl_mschdbg_event_handler(dhd_pub_t * dhdp,void * raw_event_ptr,int type,void * data,int len)741*4882a593Smuzhiyun wl_mschdbg_event_handler(dhd_pub_t *dhdp, void *raw_event_ptr, int type, void *data, int len)
742*4882a593Smuzhiyun {
743*4882a593Smuzhiyun 	head_log = "MSCH";
744*4882a593Smuzhiyun 	dhd_mschdbg_dump_data(dhdp, raw_event_ptr, type, (char *)data, len);
745*4882a593Smuzhiyun }
746*4882a593Smuzhiyun 
747*4882a593Smuzhiyun void
wl_mschdbg_verboselog_handler(dhd_pub_t * dhdp,void * raw_event_ptr,prcd_event_log_hdr_t * plog_hdr,uint32 * log_ptr)748*4882a593Smuzhiyun wl_mschdbg_verboselog_handler(dhd_pub_t *dhdp, void *raw_event_ptr, prcd_event_log_hdr_t *plog_hdr,
749*4882a593Smuzhiyun 	uint32 *log_ptr)
750*4882a593Smuzhiyun {
751*4882a593Smuzhiyun 	uint32 log_pyld_len;
752*4882a593Smuzhiyun 	head_log = "CONSOLE";
753*4882a593Smuzhiyun 
754*4882a593Smuzhiyun 	if (plog_hdr->count == 0) {
755*4882a593Smuzhiyun 		return;
756*4882a593Smuzhiyun 	}
757*4882a593Smuzhiyun 	log_pyld_len = (plog_hdr->count - 1) * DATA_UNIT_FOR_LOG_CNT;
758*4882a593Smuzhiyun 
759*4882a593Smuzhiyun 	if (plog_hdr->tag == EVENT_LOG_TAG_MSCHPROFILE) {
760*4882a593Smuzhiyun 		msch_event_log_profiler_event_data_t *p =
761*4882a593Smuzhiyun 			(msch_event_log_profiler_event_data_t *)log_ptr;
762*4882a593Smuzhiyun 		/* TODO: How to parse MSCH if extended event tag is present ??? */
763*4882a593Smuzhiyun 		prcd_event_log_hdr_t hdr;
764*4882a593Smuzhiyun 		uint32 s, ss;
765*4882a593Smuzhiyun 
766*4882a593Smuzhiyun 		if (log_pyld_len < OFFSETOF(msch_event_log_profiler_event_data_t, data) ||
767*4882a593Smuzhiyun 			log_pyld_len > sizeof(msch_event_log_profiler_event_data_t)) {
768*4882a593Smuzhiyun 			return;
769*4882a593Smuzhiyun 		}
770*4882a593Smuzhiyun 
771*4882a593Smuzhiyun 		dhd_mschdbg_us_to_sec(p->time_hi, p->time_lo, &s, &ss);
772*4882a593Smuzhiyun 		MSCH_EVENT_HEAD(0);
773*4882a593Smuzhiyun 		MSCH_EVENT(("%06d.%06d [wl%d]: ", s, ss, p->hdr.tag));
774*4882a593Smuzhiyun 		bzero(&hdr, sizeof(hdr));
775*4882a593Smuzhiyun 		hdr.tag = EVENT_LOG_TAG_MSCHPROFILE;
776*4882a593Smuzhiyun 		hdr.count = p->hdr.count + 1;
777*4882a593Smuzhiyun 		/* exclude LSB 2 bits which indicate binary/non-binary data */
778*4882a593Smuzhiyun 		hdr.fmt_num = ntoh16(p->hdr.fmt_num) >> 2;
779*4882a593Smuzhiyun 		hdr.fmt_num_raw = ntoh16(p->hdr.fmt_num);
780*4882a593Smuzhiyun 		if (ntoh16(p->hdr.fmt_num) == DHD_OW_BI_RAW_EVENT_LOG_FMT) {
781*4882a593Smuzhiyun 			hdr.binary_payload = TRUE;
782*4882a593Smuzhiyun 		}
783*4882a593Smuzhiyun 		dhd_dbg_verboselog_printf(dhdp, &hdr, raw_event_ptr, p->data, 0, 0);
784*4882a593Smuzhiyun 	} else {
785*4882a593Smuzhiyun 		msch_collect_tlv_t *p = (msch_collect_tlv_t *)log_ptr;
786*4882a593Smuzhiyun 		int type = ntoh16(p->type);
787*4882a593Smuzhiyun 		int len = ntoh16(p->size);
788*4882a593Smuzhiyun 
789*4882a593Smuzhiyun 		if (log_pyld_len < OFFSETOF(msch_collect_tlv_t, value) + len) {
790*4882a593Smuzhiyun 			return;
791*4882a593Smuzhiyun 		}
792*4882a593Smuzhiyun 
793*4882a593Smuzhiyun 		dhd_mschdbg_dump_data(dhdp, raw_event_ptr, type, p->value, len);
794*4882a593Smuzhiyun 	}
795*4882a593Smuzhiyun }
796*4882a593Smuzhiyun #endif /* SHOW_LOGTRACE */
797