blob: 51e088eb575bf535971a4aaf73756a2dcba32f9b [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Kiet Lam0fb93dd2014-02-19 00:32:59 -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.
Kiet Lamaa8e15a2014-02-11 23:30:06 -080020 */
Kiet Lam0fb93dd2014-02-19 00:32:59 -080021
22/*
23 * This file was originally distributed by Qualcomm Atheros, Inc.
24 * under proprietary terms before Copyright ownership was assigned
25 * to the Linux Foundation.
26 */
27
Jeff Johnson295189b2012-06-20 16:38:30 -070028/*============================================================================
Jeff Johnson295189b2012-06-20 16:38:30 -070029
30logDump.c
31*/
32
33/*
Jeff Johnson295189b2012-06-20 16:38:30 -070034 * This file contains the utility functions to dump various
35 * MAC states and to enable/disable certain features during
36 * debugging.
37 * Author: Sandesh Goel
38 * Date: 02/27/02
39 * History:-
40 * 02/11/02 Created.
41 * --------------------------------------------------------------------
42 *
43 */
44
45/*
46 * @note : Bytes is to print overflow message information.
47 */
48
49#include "palTypes.h"
50
51#ifdef ANI_LOGDUMP
52
53#define MAX_OVERFLOW_MSG 400
Jeff Johnson295189b2012-06-20 16:38:30 -070054#define MAX_LOGDUMP_SIZE ((4*1024) - MAX_OVERFLOW_MSG)
Jeff Johnson295189b2012-06-20 16:38:30 -070055
Jeff Johnson77165482013-03-07 08:15:44 -080056#if defined(ANI_OS_TYPE_ANDROID)
Jeff Johnson295189b2012-06-20 16:38:30 -070057
58#include <linux/kernel.h>
59
60#endif
61
62
63#include "palApi.h"
64#include "aniGlobal.h"
65#include "sirCommon.h"
66#include <sirDebug.h>
67#include <utilsApi.h>
68
69#include <limApi.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070070#include <cfgApi.h>
71#include <utilsGlobal.h>
72#include <dphGlobal.h>
73#include <limGlobal.h>
74#include "limUtils.h"
75#include "schApi.h"
76
77#include "pmmApi.h"
78#include "limSerDesUtils.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070079#include "limAssocUtils.h"
80#include "limSendMessages.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070081#include "limSecurityUtils.h"
82//#include "halRadar.h"
83#include "logDump.h"
84#include "sysDebug.h"
85#include "wlan_qct_wda.h"
86
87#define HAL_LOG_DUMP_CMD_START 0
Madan Mohan Koyyalamudi90a90e42013-07-18 18:34:40 +053088
89/* Dump command id for Host modules starts from 300 onwards,
90 * hence do not extend the HAL commands beyond 300.
91 */
92#define HAL_LOG_DUMP_CMD_END 299
Jeff Johnson295189b2012-06-20 16:38:30 -070093
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -070094static int debug;
Jeff Johnson295189b2012-06-20 16:38:30 -070095
96 void
97logPrintf(tpAniSirGlobal pMac, tANI_U32 cmd, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4)
98{
99 static tANI_U8 buf[MAX_LOGDUMP_SIZE + MAX_OVERFLOW_MSG];
100 tANI_U16 bufLen;
101 pMac->gCurrentLogSize = 0;
102
103 bufLen = (tANI_U16)logRtaiDump(pMac, cmd, arg1, arg2, arg3, arg4, buf);
104}
105
106/**
107 @brief: This function is used to Aggregate the formated buffer, this
108 also check the overflow condition and adds the overflow message
109 to the end of the log Dump buffer reserved of MAX_OVERFLOW_MSG size.
110 @param: tpAniSirGlobal pMac
111 @param: char *pBuf
112 @param: variable arguments...
113 @return: Returns the number of bytes added to the buffer.
114 Returns 0 incase of overflow.
115
116 @note: Currently in windows we do not print the Aggregated buffer as there
117 is a limitation on the number of bytes that can be displayed by DbgPrint
118 So we print the buffer immediately and we would also aggregate where
119 the TestDbg might use this buffer to print out at the application level.
120 */
121int log_sprintf(tpAniSirGlobal pMac, char *pBuf, char *fmt, ...)
122{
123 tANI_S32 ret = 0;
124#ifdef WLAN_DEBUG
125
Jeff Johnson295189b2012-06-20 16:38:30 -0700126 va_list args;
127 va_start(args, fmt);
Jeff Johnson295189b2012-06-20 16:38:30 -0700128
129 if (pMac->gCurrentLogSize >= MAX_LOGDUMP_SIZE)
130 return 0;
131
Jeff Johnson77165482013-03-07 08:15:44 -0800132#if defined (ANI_OS_TYPE_ANDROID)
Jeff Johnson295189b2012-06-20 16:38:30 -0700133 ret = vsnprintf(pBuf, (MAX_LOGDUMP_SIZE - pMac->gCurrentLogSize), fmt, args);
Jeff Johnson295189b2012-06-20 16:38:30 -0700134#endif
135
Jeff Johnson295189b2012-06-20 16:38:30 -0700136 va_end(args);
Jeff Johnson295189b2012-06-20 16:38:30 -0700137
138 /* If an output error is encountered, a negative value is returned by vsnprintf */
139 if (ret < 0)
140 return 0;
141
142
143 if ((tANI_U32) ret > (MAX_LOGDUMP_SIZE - pMac->gCurrentLogSize)) {
144 pBuf += (MAX_LOGDUMP_SIZE - pMac->gCurrentLogSize);
145 pMac->gCurrentLogSize = MAX_LOGDUMP_SIZE;
146
Jeff Johnson77165482013-03-07 08:15:44 -0800147#if defined (ANI_OS_TYPE_ANDROID)
Jeff Johnson295189b2012-06-20 16:38:30 -0700148 ret = snprintf(pBuf, MAX_OVERFLOW_MSG, "\n-> ***********"
149 "\nOutput Exceeded the Buffer Size, message truncated!!\n<- ***********\n");
150#endif
151 /* If an output error is encountered, a negative value is returned by snprintf */
152 if (ret < 0)
153 return 0;
154
155 if (ret > MAX_OVERFLOW_MSG)
156 ret = MAX_OVERFLOW_MSG;
157 }
158
159 pMac->gCurrentLogSize += ret;
160
161
Jeff Johnson295189b2012-06-20 16:38:30 -0700162#endif //for #ifdef WLAN_DEBUG
163 return ret;
164}
165
166
167char* dumpLOG( tpAniSirGlobal pMac, char *p )
168{
169 tANI_U32 i;
170
171 for( i = SIR_FIRST_MODULE_ID; i <= SIR_LAST_MODULE_ID; i++ ) {
172 p += log_sprintf(pMac, p, "[0x%2x]", i);
173 switch (i)
174 {
175 case SIR_HAL_MODULE_ID: p += log_sprintf( pMac, p, "HAL "); break;
176 case SIR_CFG_MODULE_ID: p += log_sprintf( pMac, p, "CFG "); break;
177 case SIR_LIM_MODULE_ID: p += log_sprintf( pMac, p, "LIM "); break;
178 case SIR_ARQ_MODULE_ID: p += log_sprintf( pMac, p, "ARQ "); break;
179 case SIR_SCH_MODULE_ID: p += log_sprintf( pMac, p, "SCH "); break;
180 case SIR_PMM_MODULE_ID: p += log_sprintf( pMac, p, "PMM "); break;
181 case SIR_MNT_MODULE_ID: p += log_sprintf( pMac, p, "MNT "); break;
182 case SIR_DBG_MODULE_ID: p += log_sprintf( pMac, p, "DBG "); break;
183 case SIR_DPH_MODULE_ID: p += log_sprintf( pMac, p, "DPH "); break;
184 case SIR_SYS_MODULE_ID: p += log_sprintf( pMac, p, "SYS "); break;
185 case SIR_PHY_MODULE_ID: p += log_sprintf( pMac, p, "PHY "); break;
186 case SIR_DVT_MODULE_ID: p += log_sprintf( pMac, p, "DVT "); break;
187 case SIR_SMS_MODULE_ID: p += log_sprintf( pMac, p, "SMS "); break;
188 default: p += log_sprintf( pMac, p, "UNK ", i); break;
189 }
190
191 p += log_sprintf( pMac, p,
192 ": debug level is [0x%x] ",
193 pMac->utils.gLogDbgLevel[i - SIR_FIRST_MODULE_ID]);
194
195 switch( pMac->utils.gLogDbgLevel[i - SIR_FIRST_MODULE_ID] )
196 {
197 case LOGOFF: p += log_sprintf( pMac, p, "LOG disabled\n"); break;
198 case LOGP: p += log_sprintf( pMac, p, "LOGP(Panic only)\n"); break;
199 case LOGE: p += log_sprintf( pMac, p, "LOGE(Errors only)\n"); break;
200 case LOGW: p += log_sprintf( pMac, p, "LOGW(Warnings)\n"); break;
201 case LOG1: p += log_sprintf( pMac, p, "LOG1(Minimal debug)\n"); break;
202 case LOG2: p += log_sprintf( pMac, p, "LOG2(Verbose)\n"); break;
203 case LOG3: p += log_sprintf( pMac, p, "LOG3(Very Verbose)\n"); break;
204 case LOG4: p += log_sprintf( pMac, p, "LOG4(Very Very Verbose)\n"); break;
205 default: p += log_sprintf( pMac, p, "Unknown\n"); break;
206 }
207 }
208
209 return p;
210}
211
212char* setLOGLevel( tpAniSirGlobal pMac, char *p, tANI_U32 module, tANI_U32 level )
213{
214 tANI_U32 i;
215
216 if((module > SIR_LAST_MODULE_ID || module < SIR_FIRST_MODULE_ID) && module != 0xff ) {
217 p += log_sprintf( pMac, p, "Invalid module id 0x%x\n", module );
218 return p;
219 }
220
221 if( 0xff == module ) {
222 for( i = SIR_FIRST_MODULE_ID; i <= SIR_LAST_MODULE_ID; i++ )
223 pMac->utils.gLogDbgLevel[i - SIR_FIRST_MODULE_ID] = level;
224 } else {
225 pMac->utils.gLogDbgLevel[module - SIR_FIRST_MODULE_ID] = level;
226 }
227
228#ifdef ANI_PHY_DEBUG
229 if (module == 0xff || module == SIR_PHY_MODULE_ID) {
230 pMac->hphy.phy.phyDebugLogLevel = level;
231 }
232#endif
233
234 return dumpLOG( pMac, p );
235}
236
237static void Log_getCfg(tpAniSirGlobal pMac, tANI_U16 cfgId)
238{
239#define CFG_CTL_INT 0x00080000
240 if ((pMac->cfg.gCfgEntry[cfgId].control & CFG_CTL_INT) != 0)
241 {
242 tANI_U32 val;
243
244 // Get integer parameter
Jeff Johnson43971f52012-07-17 12:26:56 -0700245 if (wlan_cfgGetInt(pMac, (tANI_U16)cfgId, &val) != eSIR_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -0700246 {
247 sysLog(pMac, LOGE, FL("Get cfgId 0x%x failed\n"), cfgId);
248 }
249 else
250 {
251 sysLog( pMac, LOGE, FL("WNI_CFG_%s(%d 0x%x) = %ld\n"), gCfgParamName[cfgId], cfgId, cfgId, val );
252 }
253 }
254 else
255 {
256 tANI_U8 buf[CFG_MAX_STR_LEN] = {0} ;
257 tANI_U32 valueLen ;
258
259 // Get string parameter
260 valueLen = CFG_MAX_STR_LEN ;
261 if (wlan_cfgGetStr(pMac, cfgId, buf, &valueLen) != eSIR_SUCCESS)
262 {
263 sysLog(pMac, LOGE, FL("Get cfgId 0x%x failed\n"), cfgId);
264 }
265 else
266 {
267 sysLog( pMac, LOGE, FL("WNI_CFG_%s(%d 0x%x) len=%ld\n"), gCfgParamName[cfgId], cfgId, cfgId, valueLen );
Mohit Khanna23863762012-09-11 17:40:09 -0700268 sirDumpBuf(pMac, SIR_WDA_MODULE_ID, LOG1, buf, valueLen) ;
Jeff Johnson295189b2012-06-20 16:38:30 -0700269 }
270 }
271
272 return;
273}
274
275static void Log_setCfg(tpAniSirGlobal pMac, tANI_U16 cfgId, tANI_U32 val)
276{
277 sysLog(pMac, LOGE, FL("Set %s(0x%x) to value 0x%x\n"),
278 gCfgParamName[cfgId], cfgId, val);
279
Jeff Johnson43971f52012-07-17 12:26:56 -0700280 if (cfgSetInt(pMac, (tANI_U16)cfgId, val) != eSIR_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -0700281 sysLog(pMac, LOGE, FL("setting cfgId 0x%x to value 0x%x failed \n"),
282 cfgId, val);
283 return;
284}
285
286
287char * dump_cfg_get( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p)
288{
289 (void) arg2; (void) arg3; (void) arg4;
290 Log_getCfg(pMac, (tANI_U16) arg1);
291 return p;
292}
293
294char * dump_cfg_group_get( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p)
295{
296 tANI_U32 i, startId, endId;
297
298 (void) arg3; (void) arg4;
299
300 if (arg1 < CFG_PARAM_MAX_NUM) {
301 startId = arg1;
302 } else {
303 p += log_sprintf( pMac, p, "Start CFGID must be less than %d\n", CFG_PARAM_MAX_NUM);
304 return p;
305 }
306
307 if ((arg2 == 0) || (arg2 > CFG_PARAM_MAX_NUM))
308 arg2 = 30;
309
310 endId = ((startId + arg2) < CFG_PARAM_MAX_NUM) ? (startId + arg2) : CFG_PARAM_MAX_NUM;
311
312 for (i=startId; i < endId; i++)
313 Log_getCfg(pMac, (tANI_U16) i);
314
315 return p;
316}
317char * dump_cfg_set( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p)
318{
319 (void) arg3; (void) arg4;
320 Log_setCfg(pMac, (tANI_U16) arg1, arg2);
321 return p;
322}
323
324char * dump_log_level_set( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p)
325{
326 (void) arg1; (void) arg2; (void) arg3; (void) arg4;
327 p = setLOGLevel( pMac, p, arg1, arg2 );
328 return p;
329}
330
Jeff Johnson295189b2012-06-20 16:38:30 -0700331
332/* Initialize the index */
333void logDumpInit(tpAniSirGlobal pMac)
334{
335 pMac->dumpTablecurrentId = 0;
336
337}
338
339void logDumpRegisterTable( tpAniSirGlobal pMac, tDumpFuncEntry *pEntry, tANI_U32 nItems )
340{
341
342 pMac->dumpTableEntry[pMac->dumpTablecurrentId]->nItems = nItems;
343 pMac->dumpTableEntry[pMac->dumpTablecurrentId]->mindumpid = pEntry->id;
344 pMac->dumpTableEntry[pMac->dumpTablecurrentId]->maxdumpid = (pEntry + (nItems-1))->id;
345 pMac->dumpTableEntry[pMac->dumpTablecurrentId]->dumpTable = pEntry;
346 pMac->dumpTablecurrentId++;
347}
348
349
350/*
351 * print nItems from the menu list ponted to by m
352 */
353static tANI_U32 print_menu(tpAniSirGlobal pMac, char *p, tANI_U32 startId)
354{
355 tANI_U32 currentId = 0;
356 tANI_U32 i, j;
357 tANI_S32 ret = 0;
358 tDumpFuncEntry *pEntry = NULL;
359 tANI_U32 nItems = 0;
360
361 for(i = 0; i < pMac->dumpTablecurrentId; i++) {
362 pEntry = pMac->dumpTableEntry[i]->dumpTable;
363 nItems = pMac->dumpTableEntry[i]->nItems;
364
365 for (j = 0; j < nItems; j++, pEntry++) {
366 if (pEntry->description == NULL)
367 continue;
368
369 if (pEntry->id == 0) {
370 ret = log_sprintf( pMac,p, "---- %s\n", pEntry->description);
371
372 if (ret <= 0)
373 break;
374
375 p += ret;
376 continue;
377 }
378
379 if (pEntry->id < startId)
380 continue;
381
382 ret = log_sprintf(pMac, p, "%4d\t%s\n", pEntry->id, pEntry->description);
383
384 if (ret <= 0)
385 break;
386
387 currentId = pEntry->id;
388 p += ret;
389 }
390
391 if (ret <= 0)
392 break;
393 }
394
395 return currentId;
396}
397
398int logRtaiDump( tpAniSirGlobal pMac, tANI_U32 cmd, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, tANI_U8 *pBuf)
399{
400 char *p = (char *)pBuf;
401 tANI_U32 i;
402 tANI_U32 nItems = 0;
403 tDumpFuncEntry *pEntry = NULL;
404
405 pMac->gCurrentLogSize = 0;
406 if (debug) {
407 p += log_sprintf( pMac,p, "Cmd = %d Args (0x%x,0x%x,0x%x,0x%x)\n\n",
408 cmd, arg1, arg2, arg3, arg4);
409 }
410
411 if( cmd == MAX_DUMP_CMD || cmd == 0 ) {
412 pMac->menuCurrent = print_menu(pMac, p, pMac->menuCurrent);
413 return pMac->gCurrentLogSize;
414 }
415 if(cmd <= HAL_LOG_DUMP_CMD_END)
416 {
Siddharth Bhal68115602015-01-18 20:44:55 +0530417 WDA_HALDumpCmdReq(pMac, cmd, arg1, arg2, arg3, arg4, p, 0);
Jeff Johnson295189b2012-06-20 16:38:30 -0700418 }
419 else
420 {
421 for(i = 0; i < pMac->dumpTablecurrentId; i++) {
422 if( (cmd > pMac->dumpTableEntry[i]->mindumpid) && (cmd <= pMac->dumpTableEntry[i]->maxdumpid)) {
423 pEntry = pMac->dumpTableEntry[i]->dumpTable;
424 nItems = pMac->dumpTableEntry[i]->nItems;
425 break;
426 } else {
427 continue;
428 }
429 }
430
431 if((nItems > 0) && (pEntry != NULL)) {
432 for (i = 0; i < nItems; i++, pEntry++) {
433 if( cmd == pEntry->id ) {
434 if ( pEntry->func != NULL ) {
435 pEntry->func(pMac, arg1, arg2, arg3, arg4, p);
436 } else {
437 p += log_sprintf( pMac,p, "Cmd not supported\n");
438 }
439 break;
440 }
441 }
442 } else {
443 p += log_sprintf( pMac,p, "Cmd not found \n");
444 }
445 }
446 if (debug)
447 p += log_sprintf( pMac,p, "Returned %d bytes\n", pMac->gCurrentLogSize);
448
449 return pMac->gCurrentLogSize;
450
451}
452
453#endif