blob: 7119e3a0ad5c2337191afc284e1f3c63d7292a59 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Gopichand Nakkala92f07d82013-01-08 21:16:34 -08002 * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
3 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21/*
Jeff Johnson32d95a32012-09-10 13:15:23 -070022 * Copyright (c) 2012, The Linux Foundation. All rights reserved.
Jeff Johnson295189b2012-06-20 16:38:30 -070023 *
24 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
25 *
26 *
27 * Permission to use, copy, modify, and/or distribute this software for
28 * any purpose with or without fee is hereby granted, provided that the
29 * above copyright notice and this permission notice appear in all
30 * copies.
31 *
32 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
33 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
34 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
35 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
36 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
37 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
38 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
39 * PERFORMANCE OF THIS SOFTWARE.
40 */
41
42/**=========================================================================
43
44 \file vos_trace.c
45
46 \brief virtual Operating System Servies (vOS)
47
48 Trace, logging, and debugging definitions and APIs
49
50 Copyright 2008,2011 (c) Qualcomm, Incorporated. All Rights Reserved.
51
52 Qualcomm Confidential and Proprietary.
53
54 ========================================================================*/
55
56/*===========================================================================
57
58 EDIT HISTORY FOR FILE
59
60
61 This section contains comments describing changes made to the module.
62 Notice that changes are listed in reverse chronological order.
63
64
65 $Header:$ $DateTime: $ $Author: $
66
67
68 when who what, where, why
69 -------- --- --------------------------------------------------------
70 09/16/08 hvm Adding ability to set multiple trace levels per component
71 09/11/08 lac Added trace levels per component. Cleanup from review.
72 08/14/08 vpai Particular modules and desired level can be selected
73 06/20/08 vpai Created Module
74===========================================================================*/
75
76/*--------------------------------------------------------------------------
77 Include Files
78 ------------------------------------------------------------------------*/
79#include <vos_trace.h>
Leela Venkata Kiran Kumar Reddy Chirala57af2692013-04-10 22:39:51 -070080#include <aniGlobal.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070081/*--------------------------------------------------------------------------
82 Preprocessor definitions and constants
83 ------------------------------------------------------------------------*/
84
85#define VOS_TRACE_BUFFER_SIZE ( 512 )
86
87// macro to map vos trace levels into the bitmask
88#define VOS_TRACE_LEVEL_TO_MODULE_BITMASK( _level ) ( ( 1 << (_level) ) )
89
90typedef struct
91{
92 // Trace level for a module, as a bitmask. The bits in this mask
93 // are ordered by VOS_TRACE_LEVEL. For example, each bit represents
94 // one of the bits in VOS_TRACE_LEVEL that may be turned on to have
95 // traces at that level logged, i.e. if VOS_TRACE_LEVEL_ERROR is
96 // == 2, then if bit 2 (low order) is turned ON, then ERROR traces
97 // will be printed to the trace log.
98 //
99 // Note that all bits turned OFF means no traces.
100 v_U16_t moduleTraceLevel;
101
102 // 3 character string name for the module
103 unsigned char moduleNameStr[ 4 ]; // 3 chars plus the NULL
104
105} moduleTraceInfo;
106
107#define VOS_DEFAULT_TRACE_LEVEL \
108 ((1<<VOS_TRACE_LEVEL_FATAL)|(1<<VOS_TRACE_LEVEL_ERROR))
109
110// Array of static data that contains all of the per module trace
111// information. This includes the trace level for the module and
112// the 3 character 'name' of the module for marking the trace logs.
113moduleTraceInfo gVosTraceInfo[ VOS_MODULE_ID_MAX ] =
114{
Mohit Khanna23863762012-09-11 17:40:09 -0700115 [VOS_MODULE_ID_BAP] = { VOS_DEFAULT_TRACE_LEVEL, "BAP" },
116 [VOS_MODULE_ID_TL] = { VOS_DEFAULT_TRACE_LEVEL, "TL " },
Mohit Khanna23863762012-09-11 17:40:09 -0700117 [VOS_MODULE_ID_WDI] = { VOS_DEFAULT_TRACE_LEVEL, "WDI"},
Mohit Khanna23863762012-09-11 17:40:09 -0700118 [VOS_MODULE_ID_HDD] = { VOS_DEFAULT_TRACE_LEVEL, "HDD" },
119 [VOS_MODULE_ID_SME] = { VOS_DEFAULT_TRACE_LEVEL, "SME" },
120 [VOS_MODULE_ID_PE] = { VOS_DEFAULT_TRACE_LEVEL, "PE " },
Mohit Khanna23863762012-09-11 17:40:09 -0700121 [VOS_MODULE_ID_WDA] = { VOS_DEFAULT_TRACE_LEVEL, "WDA" },
Mohit Khanna23863762012-09-11 17:40:09 -0700122 [VOS_MODULE_ID_SYS] = { VOS_DEFAULT_TRACE_LEVEL, "SYS" },
Jeff Johnson295189b2012-06-20 16:38:30 -0700123 [VOS_MODULE_ID_VOSS] = { VOS_DEFAULT_TRACE_LEVEL, "VOS" },
Mohit Khanna23863762012-09-11 17:40:09 -0700124 [VOS_MODULE_ID_SAP] = { VOS_DEFAULT_TRACE_LEVEL, "SAP" },
125 [VOS_MODULE_ID_HDD_SOFTAP] = { VOS_DEFAULT_TRACE_LEVEL, "HSP" },
Katya Nigam70d68332013-09-16 16:49:45 +0530126 [VOS_MODULE_ID_PMC] = { VOS_DEFAULT_TRACE_LEVEL, "PMC" },
Jeff Johnson295189b2012-06-20 16:38:30 -0700127};
Leela Venkata Kiran Kumar Reddy Chirala57af2692013-04-10 22:39:51 -0700128/*-------------------------------------------------------------------------
129 Static and Global variables
130 ------------------------------------------------------------------------*/
131static spinlock_t ltraceLock;
Jeff Johnson295189b2012-06-20 16:38:30 -0700132
Leela Venkata Kiran Kumar Reddy Chirala57af2692013-04-10 22:39:51 -0700133static tvosTraceRecord gvosTraceTbl[MAX_VOS_TRACE_RECORDS];
134// Global vosTraceData
135static tvosTraceData gvosTraceData;
136/*
137 * all the call back functions for dumping MTRACE messages from ring buffer
138 * are stored in vostraceCBTable,these callbacks are initialized during init only
139 * so, we will make a copy of these call back functions and maintain in to
140 * vostraceRestoreCBTable. Incase if we make modifications to vostraceCBTable,
141 * we can certainly retrieve all the call back functions back from Restore Table
142 */
143static tpvosTraceCb vostraceCBTable[VOS_MODULE_ID_MAX];
144static tpvosTraceCb vostraceRestoreCBTable[VOS_MODULE_ID_MAX];
Jeff Johnson295189b2012-06-20 16:38:30 -0700145/*-------------------------------------------------------------------------
146 Functions
147 ------------------------------------------------------------------------*/
148void vos_trace_setLevel( VOS_MODULE_ID module, VOS_TRACE_LEVEL level )
149{
150 // Make sure the caller is passing in a valid LEVEL.
151 if ( level >= VOS_TRACE_LEVEL_MAX )
152 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700153 pr_err("%s: Invalid trace level %d passed in!\n", __func__, level);
Jeff Johnson295189b2012-06-20 16:38:30 -0700154 return;
155 }
156
157 // Treat 'none' differently. NONE means we have to run off all
158 // the bits in the bit mask so none of the traces appear. Anything other
159 // than 'none' means we need to turn ON a bit in the bitmask.
160 if ( VOS_TRACE_LEVEL_NONE == level )
161 {
162 gVosTraceInfo[ module ].moduleTraceLevel = VOS_TRACE_LEVEL_NONE;
163 }
164 else
165 {
166 // Set the desired bit in the bit mask for the module trace level.
167 gVosTraceInfo[ module ].moduleTraceLevel |= VOS_TRACE_LEVEL_TO_MODULE_BITMASK( level );
168 }
169}
170
171void vos_trace_setValue( VOS_MODULE_ID module, VOS_TRACE_LEVEL level, v_U8_t on)
172{
173 // Make sure the caller is passing in a valid LEVEL.
174 if ( level < 0 || level >= VOS_TRACE_LEVEL_MAX )
175 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700176 pr_err("%s: Invalid trace level %d passed in!\n", __func__, level);
Jeff Johnson295189b2012-06-20 16:38:30 -0700177 return;
178 }
179
180 // Make sure the caller is passing in a valid module.
181 if ( module < 0 || module >= VOS_MODULE_ID_MAX )
182 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700183 pr_err("%s: Invalid module id %d passed in!\n", __func__, module);
Jeff Johnson295189b2012-06-20 16:38:30 -0700184 return;
185 }
186
187 // Treat 'none' differently. NONE means we have to turn off all
188 // the bits in the bit mask so none of the traces appear.
189 if ( VOS_TRACE_LEVEL_NONE == level )
190 {
191 gVosTraceInfo[ module ].moduleTraceLevel = VOS_TRACE_LEVEL_NONE;
192 }
193 // Treat 'All' differently. All means we have to turn on all
194 // the bits in the bit mask so all of the traces appear.
195 else if ( VOS_TRACE_LEVEL_ALL == level )
196 {
197 gVosTraceInfo[ module ].moduleTraceLevel = 0xFFFF;
198 }
199
200 else
201 {
202 if (on)
203 // Set the desired bit in the bit mask for the module trace level.
204 gVosTraceInfo[ module ].moduleTraceLevel |= VOS_TRACE_LEVEL_TO_MODULE_BITMASK( level );
205 else
206 // Clear the desired bit in the bit mask for the module trace level.
207 gVosTraceInfo[ module ].moduleTraceLevel &= ~(VOS_TRACE_LEVEL_TO_MODULE_BITMASK( level ));
208 }
209}
210
211
212v_BOOL_t vos_trace_getLevel( VOS_MODULE_ID module, VOS_TRACE_LEVEL level )
213{
214 v_BOOL_t traceOn = VOS_FALSE;
215
216 if ( ( VOS_TRACE_LEVEL_NONE == level ) ||
217 ( VOS_TRACE_LEVEL_ALL == level ) ||
218 ( level >= VOS_TRACE_LEVEL_MAX ) )
219 {
220 traceOn = VOS_FALSE;
221 }
222 else
223 {
224 traceOn = ( level & gVosTraceInfo[ module ].moduleTraceLevel ) ? VOS_TRUE : VOS_FALSE;
225 }
226
227 return( traceOn );
228}
229
230void vos_snprintf(char *strBuffer, unsigned int size, char *strFormat, ...)
231{
232 va_list val;
233
234 va_start( val, strFormat );
235 snprintf (strBuffer, size, strFormat, val);
236 va_end( val );
237}
238
Gopichand Nakkalad0774962013-05-24 11:32:21 +0530239#ifdef WCONN_TRACE_KMSG_LOG_BUFF
240
241/* 64k:: size should be power of 2 to
242 get serial 'wconnstrContBuffIdx' index */
243#define KMSG_WCONN_TRACE_LOG_MAX 65536
244
245static char wconnStrLogBuff[KMSG_WCONN_TRACE_LOG_MAX];
246static unsigned int wconnstrContBuffIdx;
247static void kmsgwconnstrlogchar(char c)
248{
249 wconnStrLogBuff[wconnstrContBuffIdx & (KMSG_WCONN_TRACE_LOG_MAX-1)] = c;
250 wconnstrContBuffIdx++;
251}
252
253/******************************************************************************
254 * function:: kmsgwconnBuffWrite()
255 * wconnlogstrRead -> Recieved the string(log msg) from vos_trace_msg()
256 * 1) Get the timetick, convert into HEX and store in wconnStrLogBuff[]
257 * 2) And 'pwconnlogstr' would be copied into wconnStrLogBuff[] character by
258 character
259 * 3) wconnStrLogBuff[] is been treated as circular buffer.
260 *
261 * Note:: In T32 simulator the content of wconnStrLogBuff[] will appear as
262 continuous string please use logparse.cmm file to extract into
263 readable format
264 *******************************************************************************/
265
266void kmsgwconnBuffWrite(const char *wconnlogstrRead)
267{
268 const char *pwconnlogstr = wconnlogstrRead;
269 static const char num[16] = {'0','1','2','3','4','5','6','7','8','9','A',
270 'B','C','D','E','F'};
271 unsigned int timetick;
272 int bits; /*timetick for now returns 32 bit number*/
273
274 timetick = ( jiffies_to_msecs(jiffies) / 10 );
275 bits = sizeof(timetick) * 8/*number of bits in a byte*/;
276
277 kmsgwconnstrlogchar('[');
278
279 for ( ; bits > 0; bits -= 4 )
280 kmsgwconnstrlogchar( num[((timetick & (0xF << (bits-4)))>>(bits-4))] );
281
282 kmsgwconnstrlogchar(']');
283
284 for ( ; *pwconnlogstr; pwconnlogstr++)
285 {
286 kmsgwconnstrlogchar(*pwconnlogstr);
287 }
288 kmsgwconnstrlogchar('\n');/*log \n*/
289}
290
291spinlock_t gVosSpinLock;
292
293void vos_wconn_trace_init(void)
294{
295 spin_lock_init(&gVosSpinLock);
296}
297
298void vos_wconn_trace_exit(void)
299{
300 /* does nothing */
301}
302
303#endif
304
Jeff Johnson295189b2012-06-20 16:38:30 -0700305#ifdef VOS_ENABLE_TRACING
306
307/*----------------------------------------------------------------------------
308
309 \brief vos_trace_msg() - Externally called trace function
310
311 Checks the level of severity and accordingly prints the trace messages
312
313 \param module - module identifier. A member of the VOS_MODULE_ID
314 enumeration that identifies the module issuing the trace message.
315
316 \param level - trace level. A member of the VOS_TRACE_LEVEL
317 enumeration indicating the severity of the condition causing the
318 trace message to be issued. More severe conditions are more
319 likely to be logged.
320
321 \param strFormat - format string. The message to be logged. This format
322 string contains printf-like replacement parameters, which follow
323 this parameter in the variable argument list.
324
325 \return nothing
326
327 \sa
328
329 --------------------------------------------------------------------------*/
330void vos_trace_msg( VOS_MODULE_ID module, VOS_TRACE_LEVEL level, char *strFormat, ... )
331{
332 char strBuffer[VOS_TRACE_BUFFER_SIZE];
333 int n;
Gopichand Nakkalad0774962013-05-24 11:32:21 +0530334 unsigned long irq_flag;
Jeff Johnson295189b2012-06-20 16:38:30 -0700335
Gopichand Nakkalaa845f7a2012-12-31 16:14:20 -0800336 // Print the trace message when the desired level bit is set in the module
337 // tracel level mask.
338 if ( gVosTraceInfo[ module ].moduleTraceLevel & VOS_TRACE_LEVEL_TO_MODULE_BITMASK( level ) )
339 {
Madan Mohan Koyyalamudid5fba4a2013-01-16 04:33:09 +0530340 // the trace level strings in an array. these are ordered in the same order
341 // as the trace levels are defined in the enum (see VOS_TRACE_LEVEL) so we
342 // can index into this array with the level and get the right string. The
343 // vos trace levels are...
Varun Reddy Yeturuf68abd62013-02-11 14:05:06 -0800344 // none, Fatal, Error, Warning, Info, InfoHigh, InfoMed, InfoLow, Debug
345 static const char * TRACE_LEVEL_STR[] = { " ", "F ", "E ", "W ", "I ", "IH", "IM", "IL", "D" };
Madan Mohan Koyyalamudid5fba4a2013-01-16 04:33:09 +0530346 va_list val;
347 va_start(val, strFormat);
348
349 // print the prefix string into the string buffer...
350 n = snprintf(strBuffer, VOS_TRACE_BUFFER_SIZE, "wlan: [%d:%2s:%3s] ",
351 in_interrupt() ? 0 : current->pid,
352 (char *) TRACE_LEVEL_STR[ level ],
353 (char *) gVosTraceInfo[ module ].moduleNameStr );
354
355 // print the formatted log message after the prefix string.
Yue Ma68045742013-04-17 10:48:13 -0700356 if ((n >= 0) && (n < VOS_TRACE_BUFFER_SIZE))
Tushnim Bhattacharyya5dd94562013-03-20 20:15:03 -0700357 {
358 vsnprintf(strBuffer + n, VOS_TRACE_BUFFER_SIZE - n, strFormat, val );
Gopichand Nakkalad0774962013-05-24 11:32:21 +0530359
360#ifdef WCONN_TRACE_KMSG_LOG_BUFF
361 spin_lock_irqsave (&gVosSpinLock, irq_flag);
362 kmsgwconnBuffWrite(strBuffer);
363 spin_unlock_irqrestore (&gVosSpinLock, irq_flag);
364#endif
Tushnim Bhattacharyya5dd94562013-03-20 20:15:03 -0700365 pr_err("%s\n", strBuffer);
366 }
Gopichand Nakkalad0774962013-05-24 11:32:21 +0530367 va_end(val);
Jeff Johnson295189b2012-06-20 16:38:30 -0700368 }
369}
370
371void vos_trace_display(void)
372{
373 VOS_MODULE_ID moduleId;
374
Varun Reddy Yeturuf68abd62013-02-11 14:05:06 -0800375 pr_err(" 1)FATAL 2)ERROR 3)WARN 4)INFO 5)INFO_H 6)INFO_M 7)INFO_L 8)DEBUG\n");
Jeff Johnson295189b2012-06-20 16:38:30 -0700376 for (moduleId = 0; moduleId < VOS_MODULE_ID_MAX; ++moduleId)
377 {
Varun Reddy Yeturuf68abd62013-02-11 14:05:06 -0800378 pr_err("%2d)%s %s %s %s %s %s %s %s %s\n",
Jeff Johnson295189b2012-06-20 16:38:30 -0700379 (int)moduleId,
380 gVosTraceInfo[moduleId].moduleNameStr,
381 (gVosTraceInfo[moduleId].moduleTraceLevel & (1 << VOS_TRACE_LEVEL_FATAL)) ? "X":" ",
382 (gVosTraceInfo[moduleId].moduleTraceLevel & (1 << VOS_TRACE_LEVEL_ERROR)) ? "X":" ",
383 (gVosTraceInfo[moduleId].moduleTraceLevel & (1 << VOS_TRACE_LEVEL_WARN)) ? "X":" ",
384 (gVosTraceInfo[moduleId].moduleTraceLevel & (1 << VOS_TRACE_LEVEL_INFO)) ? "X":" ",
385 (gVosTraceInfo[moduleId].moduleTraceLevel & (1 << VOS_TRACE_LEVEL_INFO_HIGH)) ? "X":" ",
386 (gVosTraceInfo[moduleId].moduleTraceLevel & (1 << VOS_TRACE_LEVEL_INFO_MED)) ? "X":" ",
Varun Reddy Yeturuf68abd62013-02-11 14:05:06 -0800387 (gVosTraceInfo[moduleId].moduleTraceLevel & (1 << VOS_TRACE_LEVEL_INFO_LOW)) ? "X":" ",
388 (gVosTraceInfo[moduleId].moduleTraceLevel & (1 << VOS_TRACE_LEVEL_DEBUG)) ? "X":" "
Jeff Johnson295189b2012-06-20 16:38:30 -0700389 );
390 }
391}
392
Madan Mohan Koyyalamudi99af06e2013-08-08 02:17:17 +0530393/*----------------------------------------------------------------------------
394
395 \brief vos_trace_hex_dump() - Externally called hex dump function
396
397 Checks the level of severity and accordingly prints the trace messages
398
399 \param module - module identifier. A member of the VOS_MODULE_ID
400 enumeration that identifies the module issuing the trace message.
401
402 \param level - trace level. A member of the VOS_TRACE_LEVEL
403 enumeration indicating the severity of the condition causing the
404 trace message to be issued. More severe conditions are more
405 likely to be logged.
406
407 \param data - . The base address of the buffer to be logged.
408
409 \param buf_len - . The size of the buffer to be logged.
410
411 \return nothing
412
413 \sa
414 --------------------------------------------------------------------------*/
415void vos_trace_hex_dump( VOS_MODULE_ID module, VOS_TRACE_LEVEL level,
416 void *data, int buf_len )
417{
418 char *buf = (char *)data;
419 int i;
420 for (i=0; (i+7)<buf_len; i+=8)
421 {
422 vos_trace_msg( module, level,
423 "%02x %02x %02x %02x %02x %02x %02x %02x \n",
424 buf[i],
425 buf[i+1],
426 buf[i+2],
427 buf[i+3],
428 buf[i+4],
429 buf[i+5],
430 buf[i+6],
431 buf[i+7]);
432 }
433
434 // Dump the bytes in the last line
435 for (; i < buf_len; i++)
436 {
437 vos_trace_msg( module, level, "%02x ", buf[i]);
438 if ((i+1) == buf_len)
439 vos_trace_msg( module, level, "\n");
440 }
441
442}
443
Jeff Johnson295189b2012-06-20 16:38:30 -0700444#endif
Leela Venkata Kiran Kumar Reddy Chirala57af2692013-04-10 22:39:51 -0700445
446/*-----------------------------------------------------------------------------
447 \brief vosTraceEnable() - Enable MTRACE for specific modules whose bits are
448 set in bitmask. set the bitmask according to enum value of the modules.
449
450 this functions will be called when you issue ioctl as mentioned following
451 [iwpriv wlan0 setdumplog <value>].
452 <value> - Decimal number, i.e. 64 decimal value shows only SME module,
453 128 decimal value shows only PE module, 192 decimal value shows PE and SME.
454
455 \param - bitmask_of_moduleId - as explained above set bitmask according to
456 enum of the modules.
457 32 [dec] = 0010 0000 [bin] <enum of HDD is 5>
458 64 [dec] = 0100 0000 [bin] <enum of SME is 6>
459 128 [dec] = 1000 0000 [bin] <enum of PE is 7>
460 ---------------------------------------------------------------------------*/
461void vosTraceEnable(v_U32_t bitmask_of_moduleId)
462{
463 int i;
464 if (bitmask_of_moduleId)
465 {
466 for (i=0; i<VOS_MODULE_ID_MAX; i++)
467 {
468 if (!((bitmask_of_moduleId >> i) & 1 ))
469 {
470 vostraceRestoreCBTable[i] = vostraceCBTable[i];
471 vostraceCBTable[i] = NULL;
472 }
473 }
474 }
475 else
476 {
477 for (i=0; i<VOS_MODULE_ID_MAX; i++)
478 {
479 if (NULL != vostraceRestoreCBTable[i])
480 {
481 vostraceCBTable[i] = vostraceRestoreCBTable[i];
482 }
483 }
484 }
485}
486
487/*-----------------------------------------------------------------------------
488 \brief vosTraceInit() - Initializes vos trace structures and variables.
489
490 Called immediately after vos_preopen, so that we can start recording HDD
491 events ASAP.
492 ----------------------------------------------------------------------------*/
493void vosTraceInit()
494{
495 v_U8_t i;
496 gvosTraceData.head = INVALID_VOS_TRACE_ADDR;
497 gvosTraceData.tail = INVALID_VOS_TRACE_ADDR;
498 gvosTraceData.num = 0;
499 gvosTraceData.enable = TRUE;
500 gvosTraceData.dumpCount = DEFAULT_VOS_TRACE_DUMP_COUNT;
501 gvosTraceData.numSinceLastDump = 0;
502
503 for (i=0; i<VOS_MODULE_ID_MAX; i++)
504 {
505 vostraceCBTable[i] = NULL;
506 vostraceRestoreCBTable[i] = NULL;
507 }
508}
509
510/*-----------------------------------------------------------------------------
511 \brief vos_trace() - puts the messages in to ring-buffer
512
513 This function will be called from each module who wants record the messages
514 in circular queue. Before calling this functions make sure you have
515 registered your module with voss through vosTraceRegister function.
516
517 \param module - enum of module, basically module id.
518 \param code -
519 \param session -
520 \param data - actual message contents.
521 ----------------------------------------------------------------------------*/
522void vos_trace(v_U8_t module, v_U8_t code, v_U8_t session, v_U32_t data)
523{
524 tpvosTraceRecord rec = NULL;
525
526
527 if (!gvosTraceData.enable)
528 {
529 return;
530 }
531 //If module is not registered, don't record for that module.
532 if (NULL == vostraceCBTable[module])
533 {
534 return;
535 }
536
537 /* Aquire the lock so that only one thread at a time can fill the ring buffer */
538 spin_lock(&ltraceLock);
539
540 gvosTraceData.num++;
541
542 if (gvosTraceData.num > MAX_VOS_TRACE_RECORDS)
543 {
544 gvosTraceData.num = MAX_VOS_TRACE_RECORDS;
545 }
546
547 if (INVALID_VOS_TRACE_ADDR == gvosTraceData.head)
548 {
549 /* first record */
550 gvosTraceData.head = 0;
551 gvosTraceData.tail = 0;
552 }
553 else
554 {
555 /* queue is not empty */
556 v_U32_t tail = gvosTraceData.tail + 1;
557
558 if (MAX_VOS_TRACE_RECORDS == tail)
559 {
560 tail = 0;
561 }
562
563 if (gvosTraceData.head == tail)
564 {
565 /* full */
566 if (MAX_VOS_TRACE_RECORDS == ++gvosTraceData.head)
567 {
568 gvosTraceData.head = 0;
569 }
570 }
571
572 gvosTraceData.tail = tail;
573 }
574
575 rec = &gvosTraceTbl[gvosTraceData.tail];
576 rec->code = code;
577 rec->session = session;
578 rec->data = data;
579 rec->time = vos_timer_get_system_time();
580 rec->module = module;
581 gvosTraceData.numSinceLastDump ++;
582 spin_unlock(&ltraceLock);
583}
584
585
586/*-----------------------------------------------------------------------------
587 \brief vos_trace_spin_lock_init() - Initializes the lock variable before use
588
589 This function will be called from vos_preOpen, we will have lock available
590 to use ASAP.
591 ----------------------------------------------------------------------------*/
592VOS_STATUS vos_trace_spin_lock_init()
593{
594 spin_lock_init(&ltraceLock);
595
596 return VOS_STATUS_SUCCESS;
597}
598
599/*-----------------------------------------------------------------------------
600 \brief vosTraceRegister() - Registers the call back functions to display the
601 messages in particular format mentioned in these call back functions.
602
603 this functions should be called by interested module in their init part as
604 we will be ready to register as soon as modules are up.
605
606 \param moduleID - enum value of module
607 \param vostraceCb - call back functions to display the messages in particular
608 format.
609 ----------------------------------------------------------------------------*/
610void vosTraceRegister(VOS_MODULE_ID moduleID, tpvosTraceCb vostraceCb)
611{
612 vostraceCBTable[moduleID] = vostraceCb;
613}
614
615/*------------------------------------------------------------------------------
616 \brief vosTraceDumpAll() - Dump data from ring buffer via call back functions
617 registered with VOSS
618
619 This function will be called up on issueing ioctl call as mentioned following
620 [iwpriv wlan0 dumplog 0 0 <n> <bitmask_of_module>]
621
622 <n> - number lines to dump starting from tail to head.
623
624 <bitmask_of_module> - if anybody wants to know how many messages were recorded
625 for particular module/s mentioned by setbit in bitmask from last <n> messages.
626 it is optional, if you don't provide then it will dump everything from buffer.
627
628 \param pMac - context of particular module
629 \param code -
630 \param session -
631 \param count - number of lines to dump starting from tail to head
632 ----------------------------------------------------------------------------*/
633void vosTraceDumpAll(void *pMac, v_U8_t code, v_U8_t session,
634 v_U32_t count, v_U32_t bitmask_of_module)
635{
636 tvosTraceRecord pRecord;
637 tANI_S32 i, tail;
638
639
640 if (!gvosTraceData.enable)
641 {
642 VOS_TRACE( VOS_MODULE_ID_SYS,
643 VOS_TRACE_LEVEL_ERROR, "Tracing Disabled");
644 return;
645 }
646
647 VOS_TRACE( VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_ERROR,
648 "Total Records: %d, Head: %d, Tail: %d",
649 gvosTraceData.num, gvosTraceData.head, gvosTraceData.tail);
650
651 /* Aquire the lock so that only one thread at a time can read the ring buffer */
652 spin_lock(&ltraceLock);
653
654 if (gvosTraceData.head != INVALID_VOS_TRACE_ADDR)
655 {
656 i = gvosTraceData.head;
657 tail = gvosTraceData.tail;
658
659 if (count)
660 {
661 if (count > gvosTraceData.num)
662 {
663 count = gvosTraceData.num;
664 }
665 if (tail >= (count - 1))
666 {
667 i = tail - count + 1;
668 }
669 else if (count != MAX_VOS_TRACE_RECORDS)
670 {
671 i = MAX_VOS_TRACE_RECORDS - ((count - 1) - tail);
672 }
673 }
674
675 pRecord = gvosTraceTbl[i];
676 /* right now we are not using numSinceLastDump member but in future
677 we might re-visit and use this member to track how many latest
678 messages got added while we were dumping from ring buffer */
679 gvosTraceData.numSinceLastDump = 0;
680 spin_unlock(&ltraceLock);
681 for (;;)
682 {
683 if ((code == 0 || (code == pRecord.code)) &&
684 (vostraceCBTable[pRecord.module] != NULL))
685 {
686 if (0 == bitmask_of_module)
687 {
688 vostraceCBTable[pRecord.module](pMac, &pRecord, (v_U16_t)i);
689 }
690 else
691 {
692 if (bitmask_of_module & (1 << pRecord.module))
693 {
694 vostraceCBTable[pRecord.module](pMac, &pRecord, (v_U16_t)i);
695 }
696 }
697 }
698
699 if (i == tail)
700 {
701 break;
702 }
703 i += 1;
704
705 spin_lock(&ltraceLock);
706 if (MAX_VOS_TRACE_RECORDS == i)
707 {
708 i = 0;
709 pRecord= gvosTraceTbl[0];
710 }
711 else
712 {
713 pRecord = gvosTraceTbl[i];
714 }
715 spin_unlock(&ltraceLock);
716 }
717 }
718 else
719 {
720 spin_unlock(&ltraceLock);
721 }
722}