Jeff Johnson | 295189b | 2012-06-20 16:38:30 -0700 | [diff] [blame] | 1 | /* |
Jeff Johnson | 32d95a3 | 2012-09-10 13:15:23 -0700 | [diff] [blame^] | 2 | * Copyright (c) 2012, The Linux Foundation. All rights reserved. |
Jeff Johnson | 295189b | 2012-06-20 16:38:30 -0700 | [diff] [blame] | 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 | |
| 22 | |
| 23 | |
| 24 | /**========================================================================= |
| 25 | |
| 26 | \file wlan_qct_pal_trace.c |
| 27 | |
| 28 | \brief Implementation trace/logging APIs PAL exports. wpt = (Wlan Pal Type) wpal = (Wlan PAL) |
| 29 | |
| 30 | Definitions for Linux/Android platform |
| 31 | |
| 32 | Copyright 2010-2011 (c) Qualcomm, Incorporated. All Rights Reserved. |
| 33 | |
| 34 | Qualcomm Confidential and Proprietary. |
| 35 | |
| 36 | ========================================================================*/ |
| 37 | |
| 38 | #include "wlan_qct_pal_trace.h" |
| 39 | #include "i_vos_types.h" |
| 40 | |
| 41 | #ifdef WLAN_DEBUG |
| 42 | |
| 43 | |
| 44 | /*-------------------------------------------------------------------------- |
| 45 | Preprocessor definitions and constants |
| 46 | ------------------------------------------------------------------------*/ |
| 47 | |
| 48 | #define WPAL_TRACE_BUFFER_SIZE ( 512 ) |
| 49 | |
| 50 | // macro to map wpal trace levels into the bitmask |
| 51 | #define WPAL_TRACE_LEVEL_TO_MODULE_BITMASK( _level ) ( ( 1 << (_level) ) ) |
| 52 | |
| 53 | typedef struct |
| 54 | { |
| 55 | // Trace level for a module, as a bitmask. The bits in this mask |
| 56 | // are ordered by wpt_tracelevel. For example, each bit represents |
| 57 | // one of the bits in wpt_tracelevel that may be turned on to have |
| 58 | // traces at that level logged, i.e. if eWLAN_PAL_TRACE_LEVEL_ERROR is |
| 59 | // == 2, then if bit 2 (low order) is turned ON, then ERROR traces |
| 60 | // will be printed to the trace log. |
| 61 | // |
| 62 | // Note that all bits turned OFF means no traces. |
| 63 | wpt_uint16 moduleTraceLevel; |
| 64 | |
| 65 | // 3 character string name for the module |
| 66 | wpt_uint8 moduleNameStr[ 4 ]; // 3 chars plus the NULL |
| 67 | |
| 68 | } moduleTraceInfo; |
| 69 | |
| 70 | |
| 71 | // Array of static data that contains all of the per module trace |
| 72 | // information. This includes the trace level for the module and |
| 73 | // the 3 character 'name' of the module for marking the trace logs. |
| 74 | moduleTraceInfo gTraceInfo[ eWLAN_MODULE_COUNT ] = |
| 75 | { |
| 76 | { (1<<eWLAN_PAL_TRACE_LEVEL_FATAL)|(1<<eWLAN_PAL_TRACE_LEVEL_ERROR), "DAL" }, |
| 77 | { (1<<eWLAN_PAL_TRACE_LEVEL_FATAL)|(1<<eWLAN_PAL_TRACE_LEVEL_ERROR), "CTL" }, |
| 78 | { (1<<eWLAN_PAL_TRACE_LEVEL_FATAL)|(1<<eWLAN_PAL_TRACE_LEVEL_ERROR), "DAT" }, |
| 79 | { (1<<eWLAN_PAL_TRACE_LEVEL_FATAL)|(1<<eWLAN_PAL_TRACE_LEVEL_ERROR), "PAL" }, |
| 80 | }; |
| 81 | |
| 82 | |
| 83 | // the trace level strings in an array. these are ordered in the same order |
| 84 | // as the trace levels are defined in the enum (see wpt_tracelevel) so we |
| 85 | // can index into this array with the level and get the right string. The |
| 86 | // trace levels are... |
| 87 | // none, Fatal, Error, Warning, Info, InfoHigh, InfoMed, InfoLow |
| 88 | static const char * TRACE_LEVEL_STR[] = { |
| 89 | " ", "F ", "E ", "W ", "I ", "IH", "IM", "IL" }; |
| 90 | |
| 91 | |
| 92 | /*------------------------------------------------------------------------- |
| 93 | Functions |
| 94 | ------------------------------------------------------------------------*/ |
| 95 | static void wpalOutput(wpt_tracelevel level, char *strBuffer) |
| 96 | { |
| 97 | switch(level) |
| 98 | { |
| 99 | default: |
| 100 | printk(KERN_CRIT "%s: Unknown trace level passed in!\n", __FUNCTION__); |
| 101 | // fall thru and use FATAL |
| 102 | |
| 103 | case eWLAN_PAL_TRACE_LEVEL_FATAL: |
| 104 | printk(KERN_CRIT "%s\n", strBuffer); |
| 105 | break; |
| 106 | |
| 107 | case eWLAN_PAL_TRACE_LEVEL_ERROR: |
| 108 | printk(KERN_ERR "%s\n", strBuffer); |
| 109 | break; |
| 110 | |
| 111 | case eWLAN_PAL_TRACE_LEVEL_WARN: |
| 112 | printk(KERN_WARNING "%s\n", strBuffer); |
| 113 | break; |
| 114 | |
| 115 | case eWLAN_PAL_TRACE_LEVEL_INFO: |
| 116 | printk(KERN_INFO "%s\n", strBuffer); |
| 117 | break; |
| 118 | |
| 119 | case eWLAN_PAL_TRACE_LEVEL_INFO_HIGH: |
| 120 | printk(KERN_NOTICE "%s\n", strBuffer); |
| 121 | break; |
| 122 | |
| 123 | case eWLAN_PAL_TRACE_LEVEL_INFO_MED: |
| 124 | printk(KERN_NOTICE "%s\n", strBuffer); |
| 125 | break; |
| 126 | |
| 127 | case eWLAN_PAL_TRACE_LEVEL_INFO_LOW: |
| 128 | printk(KERN_INFO "%s\n", strBuffer); |
| 129 | break; |
| 130 | } |
| 131 | } |
| 132 | |
| 133 | void wpalTraceSetLevel( wpt_moduleid module, wpt_tracelevel level, |
| 134 | wpt_boolean on ) |
| 135 | { |
| 136 | // Make sure the caller is passing in a valid LEVEL and MODULE. |
| 137 | if ( (eWLAN_PAL_TRACE_LEVEL_COUNT <= level) || |
| 138 | (eWLAN_MODULE_COUNT <= module) ) |
| 139 | { |
| 140 | return; |
| 141 | } |
| 142 | |
| 143 | if ( eWLAN_PAL_TRACE_LEVEL_NONE == level ) |
| 144 | { |
| 145 | // Treat 'none' differently. NONE means we have to turn off all |
| 146 | // the bits in the bit mask so none of the traces appear. |
| 147 | gTraceInfo[ module ].moduleTraceLevel = 0; |
| 148 | } |
| 149 | else if ( eWLAN_PAL_TRACE_LEVEL_ALL == level ) |
| 150 | { |
| 151 | // Treat 'all' differently. ALL means we have to turn on all |
| 152 | // the bits in the bit mask so all of the traces appear. |
| 153 | gTraceInfo[ module ].moduleTraceLevel = 0xFFFF; |
| 154 | } |
| 155 | else |
| 156 | { |
| 157 | // We are turning a particular trace level on or off |
| 158 | if (on) |
| 159 | { |
| 160 | // Set the desired bit in the bit mask for the module trace level. |
| 161 | gTraceInfo[ module ].moduleTraceLevel |= |
| 162 | WPAL_TRACE_LEVEL_TO_MODULE_BITMASK( level ); |
| 163 | } |
| 164 | else |
| 165 | { |
| 166 | // Clear the desired bit in the bit mask for the module trace level. |
| 167 | gTraceInfo[ module ].moduleTraceLevel &= |
| 168 | ~(WPAL_TRACE_LEVEL_TO_MODULE_BITMASK( level )); |
| 169 | } |
| 170 | } |
| 171 | } |
| 172 | |
| 173 | wpt_boolean wpalTraceCheckLevel( wpt_moduleid module, wpt_tracelevel level ) |
| 174 | { |
| 175 | wpt_boolean traceOn = eWLAN_PAL_FALSE; |
| 176 | |
| 177 | if ( ( eWLAN_PAL_TRACE_LEVEL_NONE == level ) || |
| 178 | ( level >= eWLAN_PAL_TRACE_LEVEL_COUNT )) |
| 179 | { |
| 180 | traceOn = eWLAN_PAL_FALSE; |
| 181 | } |
| 182 | else |
| 183 | { |
| 184 | traceOn = ( level & gTraceInfo[ module ].moduleTraceLevel ) ? eWLAN_PAL_TRUE : eWLAN_PAL_FALSE; |
| 185 | } |
| 186 | |
| 187 | return( traceOn ); |
| 188 | } |
| 189 | |
| 190 | void wpalTraceDisplay(void) |
| 191 | { |
| 192 | wpt_moduleid moduleId; |
| 193 | |
| 194 | printk(KERN_CRIT |
| 195 | " 1)FATAL 2)ERROR 3)WARN 4)INFO " |
| 196 | "5)INFO_H 6)INFO_M 7)INFO_L\n"); |
| 197 | for (moduleId = 0; moduleId < eWLAN_MODULE_COUNT; ++moduleId) |
| 198 | { |
| 199 | printk(KERN_CRIT |
| 200 | "%2d)%s %s %s %s " |
| 201 | "%s %s %s %s\n", |
| 202 | (int)moduleId, |
| 203 | gTraceInfo[moduleId].moduleNameStr, |
| 204 | (gTraceInfo[moduleId].moduleTraceLevel & |
| 205 | (1 << eWLAN_PAL_TRACE_LEVEL_FATAL)) ? "X":" ", |
| 206 | (gTraceInfo[moduleId].moduleTraceLevel & |
| 207 | (1 << eWLAN_PAL_TRACE_LEVEL_ERROR)) ? "X":" ", |
| 208 | (gTraceInfo[moduleId].moduleTraceLevel & |
| 209 | (1 << eWLAN_PAL_TRACE_LEVEL_WARN)) ? "X":" ", |
| 210 | (gTraceInfo[moduleId].moduleTraceLevel & |
| 211 | (1 << eWLAN_PAL_TRACE_LEVEL_INFO)) ? "X":" ", |
| 212 | (gTraceInfo[moduleId].moduleTraceLevel & |
| 213 | (1 << eWLAN_PAL_TRACE_LEVEL_INFO_HIGH)) ? "X":" ", |
| 214 | (gTraceInfo[moduleId].moduleTraceLevel & |
| 215 | (1 << eWLAN_PAL_TRACE_LEVEL_INFO_MED)) ? "X":" ", |
| 216 | (gTraceInfo[moduleId].moduleTraceLevel & |
| 217 | (1 << eWLAN_PAL_TRACE_LEVEL_INFO_LOW)) ? "X":" " |
| 218 | ); |
| 219 | } |
| 220 | |
| 221 | } |
| 222 | |
| 223 | /*---------------------------------------------------------------------------- |
| 224 | |
| 225 | \brief wpalTrace() - Externally called trace function |
| 226 | |
| 227 | Checks the level of severity and accordingly prints the trace messages |
| 228 | |
| 229 | \param module - module identifier. A member of the wpt_moduleid |
| 230 | enumeration that identifies the module issuing the trace message. |
| 231 | |
| 232 | \param level - trace level. A member of the wpt_tracelevel |
| 233 | enumeration indicating the severity of the condition causing the |
| 234 | trace message to be issued. More severe conditions are more |
| 235 | likely to be logged. |
| 236 | |
| 237 | \param strFormat - format string. The message to be logged. This format |
| 238 | string contains printf-like replacement parameters, which follow |
| 239 | this parameter in the variable argument list. |
| 240 | |
| 241 | \return nothing |
| 242 | |
| 243 | \sa |
| 244 | |
| 245 | --------------------------------------------------------------------------*/ |
| 246 | void wpalTrace( wpt_moduleid module, wpt_tracelevel level, char *strFormat, ... ) |
| 247 | { |
| 248 | wpt_uint8 strBuffer[ WPAL_TRACE_BUFFER_SIZE ]; |
| 249 | int n; |
| 250 | |
| 251 | // Print the trace message when the desired level bit is set in the module |
| 252 | // tracel level mask. |
| 253 | if ( gTraceInfo[ module ].moduleTraceLevel & WPAL_TRACE_LEVEL_TO_MODULE_BITMASK( level ) ) |
| 254 | { |
| 255 | va_list val; |
| 256 | va_start(val, strFormat); |
| 257 | |
| 258 | // print the prefix string into the string buffer... |
| 259 | n = snprintf(strBuffer, WPAL_TRACE_BUFFER_SIZE, "[%d:%d:%2s:%3s] ", |
| 260 | smp_processor_id(), |
| 261 | in_interrupt() ? 0 : current->pid, |
| 262 | (char *) TRACE_LEVEL_STR[ level ], |
| 263 | (char *) gTraceInfo[ module ].moduleNameStr); |
| 264 | |
| 265 | |
| 266 | // print the formatted log message after the prefix string. |
| 267 | // note we reserve space for the terminating NUL |
| 268 | vsnprintf(strBuffer + n, WPAL_TRACE_BUFFER_SIZE - n - 1, strFormat, val); |
| 269 | wpalOutput(level, strBuffer); |
| 270 | va_end(val); |
| 271 | } |
| 272 | } |
| 273 | |
| 274 | /**---------------------------------------------------------------------------- |
| 275 | |
| 276 | \brief WPAL_DUMP() / wpalDump() - Trace / logging API |
| 277 | |
| 278 | Users wishing to add tracing memory dumps to their code should use |
| 279 | WPAL_DUMP. WPAL_DUMP() will compile into a call to wpalDump() when |
| 280 | tracing is enabled. |
| 281 | |
| 282 | \param module - module identifier. A member of the wpt_moduleid |
| 283 | enumeration that identifies the module performing the dump |
| 284 | |
| 285 | \param level - trace level. A member of the wpt_tracelevel |
| 286 | enumeration indicating the severity of the condition causing the |
| 287 | memory to be dumped. More severe conditions are more |
| 288 | likely to be logged. |
| 289 | |
| 290 | \param pMemory - memory. A pointer to the memory to be dumped |
| 291 | |
| 292 | \param length - length. How many bytes of memory to be dumped |
| 293 | |
| 294 | \return nothing |
| 295 | |
| 296 | --------------------------------------------------------------------------*/ |
| 297 | // how many bytes do we output per line |
| 298 | #define BYTES_PER_LINE 16 |
| 299 | |
| 300 | // each byte takes 2 characters plus a space, plus need room for NUL |
| 301 | #define CHARS_PER_LINE ((BYTES_PER_LINE * 3) + 1) |
| 302 | |
| 303 | void wpalDump( wpt_moduleid module, wpt_tracelevel level, |
| 304 | wpt_uint8 *pMemory, wpt_uint32 length) |
| 305 | { |
| 306 | char strBuffer[CHARS_PER_LINE]; |
| 307 | int n, num, offset; |
| 308 | |
| 309 | // Dump the memory when the desired level bit is set in the module |
| 310 | // tracel level mask. |
| 311 | if ( gTraceInfo[ module ].moduleTraceLevel & WPAL_TRACE_LEVEL_TO_MODULE_BITMASK( level ) ) |
| 312 | { |
| 313 | num = 0; |
| 314 | offset = 0; |
| 315 | while (length > 0) |
| 316 | { |
| 317 | n = snprintf(strBuffer + offset, CHARS_PER_LINE - offset - 1, |
| 318 | "%02X ", *pMemory); |
| 319 | offset += n; |
| 320 | num++; |
| 321 | length--; |
| 322 | pMemory++; |
| 323 | if (BYTES_PER_LINE == num) |
| 324 | { |
| 325 | wpalOutput(level, strBuffer); |
| 326 | num = 0; |
| 327 | offset = 0; |
| 328 | } |
| 329 | } |
| 330 | |
| 331 | if (offset > 0) |
| 332 | { |
| 333 | // partial line remains |
| 334 | wpalOutput(level, strBuffer); |
| 335 | } |
| 336 | } |
| 337 | } |
| 338 | #endif //WLAN_DEBUG |