diff options
| author | Leela Venkata Kiran Kumar Reddy Chirala <kchirala@qca.qualcomm.com> | 2014-03-30 17:00:42 -0700 |
|---|---|---|
| committer | Akash Patel <c_akashp@qca.qualcomm.com> | 2014-04-17 16:46:02 -0700 |
| commit | c86213233bd234a25468fcda3b83fad45a52bcfe (patch) | |
| tree | fcdfeed7f2f294b6752cf0593ecdc111a01d97af | |
| parent | 942c0e60c9b11ce0bec261a399b1d71b864cf7a8 (diff) | |
wlan: Support for MTRACE.
This fix will move MTRACE funcionality from PE to VOSS
Change-Id: I91ec21bf802d3894b47f07de65c1dee236f40113
CRs-Fixed: 592922
| -rw-r--r-- | CORE/HDD/src/wlan_hdd_wext.c | 40 | ||||
| -rw-r--r-- | CORE/MAC/inc/macTrace.h | 37 | ||||
| -rw-r--r-- | CORE/MAC/src/pe/include/limTrace.h | 16 | ||||
| -rw-r--r-- | CORE/MAC/src/pe/lim/limApi.c | 10 | ||||
| -rw-r--r-- | CORE/MAC/src/pe/lim/limLogDump.c | 15 | ||||
| -rw-r--r-- | CORE/MAC/src/pe/lim/limTrace.c | 5 | ||||
| -rw-r--r-- | CORE/SYS/legacy/src/system/src/macInitApi.c | 6 | ||||
| -rw-r--r-- | CORE/SYS/legacy/src/utils/src/macTrace.c | 240 | ||||
| -rw-r--r-- | CORE/VOSS/inc/vos_trace.h | 51 | ||||
| -rw-r--r-- | CORE/VOSS/src/vos_api.c | 9 | ||||
| -rw-r--r-- | CORE/VOSS/src/vos_trace.c | 295 |
11 files changed, 411 insertions, 313 deletions
diff --git a/CORE/HDD/src/wlan_hdd_wext.c b/CORE/HDD/src/wlan_hdd_wext.c index eb0ffcd0611c..25ffee2e8d66 100644 --- a/CORE/HDD/src/wlan_hdd_wext.c +++ b/CORE/HDD/src/wlan_hdd_wext.c @@ -105,6 +105,7 @@ #include "qc_sap_ioctl.h" #include "sme_Api.h" #include "wlan_qct_wda.h" +#include "vos_trace.h" #ifdef QCA_PKT_PROTO_TRACE #include "vos_packet.h" @@ -121,6 +122,7 @@ extern void hdd_resume_wlan(struct early_suspend *wlan_suspend); #define HDD_FINISH_ULA_TIME_OUT 800 + extern int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand); static int ioctl_debug; @@ -244,6 +246,8 @@ static const hdd_freq_chan_map_t freq_chan_map[] = { {2412, 1}, {2417, 2}, /* Private ioctl for packet power save */ #define WE_PPS_5G_EBT 83 +#define WE_MTRACE_SELECTIVE_MODULE_LOG_ENABLE_CMD 84 + /* Private ioctls and their sub-ioctls */ #define WLAN_PRIV_SET_NONE_GET_INT (SIOCIWFIRSTPRIV + 1) #define WE_GET_11D_STATE 1 @@ -383,6 +387,9 @@ static const hdd_freq_chan_map_t freq_chan_map[] = { {2412, 1}, {2417, 2}, #ifdef FEATURE_WLAN_TDLS #define WE_TDLS_CONFIG_PARAMS 5 #endif + +#define WE_MTRACE_DUMP_CMD 8 + #ifdef FEATURE_WLAN_TDLS #undef MAX_VAR_ARGS #ifdef QCA_WIFI_2_0 @@ -4854,6 +4861,15 @@ static int iw_setint_getnone(struct net_device *dev, struct iw_request_info *inf break; } + case WE_MTRACE_SELECTIVE_MODULE_LOG_ENABLE_CMD: + { + hddLog(LOG1, "%s: SELECTIVE_MODULE_LOG %d arg1", + __func__, set_value); + vosTraceEnable(set_value); + + break; + } + case WE_ENABLE_STRICT_FCC_REG: { hdd_context_t *hddCtxt = WLAN_HDD_GET_CTX(pAdapter); @@ -7450,6 +7466,18 @@ int iw_set_var_ints_getnone(struct net_device *dev, struct iw_request_info *info } break; + case WE_MTRACE_DUMP_CMD: + { + hddLog(LOG1, "%s: MTRACE_DUMP code %d session %d count %d " + "bitmask_of_module %d ", + __func__, apps_args[0], apps_args[1], apps_args[2], + apps_args[3]); + vosTraceDumpAll((void*)hHal , apps_args[0], apps_args[1], + apps_args[2], apps_args[3]); + + } + break; + case WE_MCC_CONFIG_CREDENTIAL : { cmd = 287; //Command should be updated if there is any change @@ -9769,6 +9797,11 @@ static const struct iw_priv_args we_private_args[] = { 0, "setStrictFCCreg" }, + { WE_MTRACE_SELECTIVE_MODULE_LOG_ENABLE_CMD, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "setdumplog" }, + /* handlers for main ioctl */ { WLAN_PRIV_SET_INT_GET_NONE, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, @@ -10683,6 +10716,13 @@ static const struct iw_priv_args we_private_args[] = { IW_PRIV_TYPE_INT | MAX_VAR_ARGS, 0, "dump" }, + + /* handlers for sub-ioctl */ + { WE_MTRACE_DUMP_CMD, + IW_PRIV_TYPE_INT | MAX_VAR_ARGS, + 0, + "dumplog" }, + /* handlers for sub ioctl */ { WE_MCC_CONFIG_CREDENTIAL, diff --git a/CORE/MAC/inc/macTrace.h b/CORE/MAC/inc/macTrace.h index 5f1d6897b55d..6a125faa5f6e 100644 --- a/CORE/MAC/inc/macTrace.h +++ b/CORE/MAC/inc/macTrace.h @@ -51,50 +51,13 @@ #define MAC_TRACE_GET_MSG_ID(data) (data & 0xffff) -typedef struct sTraceRecord -{ - tANI_U32 time; - tANI_U8 module; - tANI_U8 code; - tANI_U8 session; - tANI_U32 data; -}tTraceRecord, *tpTraceRecord; - #define eLOG_NODROP_MISSED_BEACON_SCENARIO 0 #define eLOG_PROC_DEAUTH_FRAME_SCENARIO 1 -#define MAX_TRACE_RECORDS 2000 -#define INVALID_TRACE_ADDR 0xffffffff -#define DEFAULT_TRACE_DUMP_COUNT 0 - - -typedef void (*tpTraceCb)(tpAniSirGlobal, tpTraceRecord, tANI_U16); - - - - -typedef struct sTraceData -{ - tANI_U32 head; - tANI_U32 tail; - tANI_U32 num; - tANI_U16 numSinceLastDump; - - //Config for controlling the trace - tANI_U8 enable; - tANI_U16 dumpCount; //will dump after number of records reach this number. - -}tTraceData; - - -void macTraceInit(tpAniSirGlobal pMac); void macTraceReset(tpAniSirGlobal pMac); void macTrace(tpAniSirGlobal pMac, tANI_U8 code, tANI_U8 session, tANI_U32 data); void macTraceNew(tpAniSirGlobal pMac, tANI_U8 module, tANI_U8 code, tANI_U8 session, tANI_U32 data); -void macTraceDumpAll(tpAniSirGlobal pMac, tANI_U8 code, tANI_U8 session, tANI_U32 count); -void macTraceCfg(tpAniSirGlobal pMac, tANI_U32 enable, tANI_U32 dumpWhenFull, tANI_U32 code, tANI_U32 session); -void macTraceRegister( tpAniSirGlobal pMac, VOS_MODULE_ID moduleId, tpTraceCb traceCb); tANI_U8* macTraceGetCfgMsgString( tANI_U16 cfgMsg ); tANI_U8* macTraceGetLimMsgString( tANI_U16 limMsg ); tANI_U8* macTraceGetWdaMsgString( tANI_U16 wdaMsg ); diff --git a/CORE/MAC/src/pe/include/limTrace.h b/CORE/MAC/src/pe/include/limTrace.h index c9211879273a..66772e1af72f 100644 --- a/CORE/MAC/src/pe/include/limTrace.h +++ b/CORE/MAC/src/pe/include/limTrace.h @@ -42,6 +42,7 @@ #include "limGlobal.h" #include "macTrace.h" +#include "vos_trace.h" #ifdef LIM_TRACE_RECORD @@ -96,23 +97,12 @@ void limTraceUpdateMgmtStat(tpAniSirGlobal pMac, tANI_U8 subtype); void limTraceDumpMgmtStat(tpAniSirGlobal pMac, tANI_U8 subtype); tANI_U8* limTraceGetMlmStateString( tANI_U32 mlmState ); tANI_U8* limTraceGetSmeStateString( tANI_U32 smeState ); -void limTraceDump(tpAniSirGlobal pMac, tpTraceRecord pRecord, tANI_U16 recIndex); +void limTraceDump(tpAniSirGlobal pMac, tpvosTraceRecord pRecord, tANI_U16 recIndex); void macTraceMsgTx(tpAniSirGlobal pMac, tANI_U8 session, tANI_U32 data); void macTraceMsgRx(tpAniSirGlobal pMac, tANI_U8 session, tANI_U32 data); void macTraceMsgRxNew(tpAniSirGlobal pMac, tANI_U8 module, tANI_U8 session, tANI_U32 data); void macTraceMsgTxNew(tpAniSirGlobal pMac, tANI_U8 module, tANI_U8 session, tANI_U32 data); - - - - - -#define MTRACE(p) p -#define NO_SESSION 0xFF - -#else -#define MTRACE(p) { } - -#endif +#endif //endof LIM_TRACE_RECORD MACRO #endif diff --git a/CORE/MAC/src/pe/lim/limApi.c b/CORE/MAC/src/pe/lim/limApi.c index 5491e785e659..4aa692bdaeff 100644 --- a/CORE/MAC/src/pe/lim/limApi.c +++ b/CORE/MAC/src/pe/lim/limApi.c @@ -769,7 +769,6 @@ limInitialize(tpAniSirGlobal pMac) vos_trace_setLevel(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR); #endif - MTRACE(limTraceInit(pMac)); //Initialize the configurations needed by PE if( eSIR_FAILURE == __limInitConfig(pMac)) @@ -1035,6 +1034,15 @@ tSirRetStatus peOpen(tpAniSirGlobal pMac, tMacOpenParameters *pMacOpenParam) return eSIR_FAILURE; } pMac->lim.deauthMsgCnt = 0; + + /* + * peOpen is successful by now, so it is right time to initialize + * MTRACE for PE module. if LIM_TRACE_RECORD is not defined in build file + * then nothing will be logged for PE module. + */ +#ifdef LIM_TRACE_RECORD + MTRACE(limTraceInit(pMac)); +#endif return eSIR_SUCCESS; } diff --git a/CORE/MAC/src/pe/lim/limLogDump.c b/CORE/MAC/src/pe/lim/limLogDump.c index 266e8350e4b1..1a5180385b8a 100644 --- a/CORE/MAC/src/pe/lim/limLogDump.c +++ b/CORE/MAC/src/pe/lim/limLogDump.c @@ -1753,19 +1753,6 @@ dump_sch_beacon_trigger( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI return p; } - -static char* dump_lim_trace_cfg(tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) -{ - MTRACE(macTraceCfg(pMac, arg1, arg2, arg3, arg4);) - return p; -} - -static char* dump_lim_trace_dump(tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) -{ - MTRACE(macTraceDumpAll(pMac, (tANI_U8)arg1, (tANI_U8)arg2, arg3);) - return p; -} - static char* dump_lim_set_scan_in_powersave( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) { p += log_sprintf( pMac,p, "logDump set scan in powersave to %d \n", arg1); @@ -2485,8 +2472,6 @@ static tDumpFuncEntry limMenuDumpTable[] = { * be moved to logDump.c */ {321, "PE:LIM: Set Log Level <VOS Module> <VOS Log Level>", dump_lim_update_log_level}, - {322, "PE.LIM: Enable/Disable PE Tracing", dump_lim_trace_cfg}, - {323, "PE.LIM: Trace Dump if enabled", dump_lim_trace_dump}, {331, "PE.LIM: Send finish scan to LIM", dump_lim_finishscan_send}, {332, "PE.LIM: force probe rsp send from LIM", dump_lim_prb_rsp_send}, {333, "PE.SCH: Trigger to generate a beacon", dump_sch_beacon_trigger}, diff --git a/CORE/MAC/src/pe/lim/limTrace.c b/CORE/MAC/src/pe/lim/limTrace.c index 927bfd654361..f4179830a171 100644 --- a/CORE/MAC/src/pe/lim/limTrace.c +++ b/CORE/MAC/src/pe/lim/limTrace.c @@ -44,6 +44,7 @@ #include "limTrace.h" #include "limTimerUtils.h" +#include "vos_trace.h" #ifdef LIM_TRACE_RECORD @@ -119,13 +120,13 @@ static tANI_U8* __limTraceGetMgmtDropReasonString( tANI_U16 dropReason ) void limTraceInit(tpAniSirGlobal pMac) { - macTraceRegister(pMac, VOS_MODULE_ID_PE, limTraceDump); + vosTraceRegister(VOS_MODULE_ID_PE, (tpvosTraceCb)&limTraceDump); } -void limTraceDump(tpAniSirGlobal pMac, tpTraceRecord pRecord, tANI_U16 recIndex) +void limTraceDump(tpAniSirGlobal pMac, tpvosTraceRecord pRecord, tANI_U16 recIndex) { static char *frameSubtypeStr[LIM_TRACE_MAX_SUBTYPES] = diff --git a/CORE/SYS/legacy/src/system/src/macInitApi.c b/CORE/SYS/legacy/src/system/src/macInitApi.c index 9397289fced7..ef534675d147 100644 --- a/CORE/SYS/legacy/src/system/src/macInitApi.c +++ b/CORE/SYS/legacy/src/system/src/macInitApi.c @@ -117,12 +117,6 @@ tSirRetStatus macStart(tHalHandle hHal, void* pHalMacStartParams) do { - -#if defined(TRACE_RECORD) - //Enable Tracing - macTraceInit(pMac); -#endif - pMac->pResetMsg = vos_mem_malloc(sizeof(tSirMbMsg)); if ( NULL == pMac->pResetMsg ) { diff --git a/CORE/SYS/legacy/src/utils/src/macTrace.c b/CORE/SYS/legacy/src/utils/src/macTrace.c index 68f962720f9e..c3fa38866cb8 100644 --- a/CORE/SYS/legacy/src/utils/src/macTrace.c +++ b/CORE/SYS/legacy/src/utils/src/macTrace.c @@ -51,11 +51,9 @@ #include "limGlobal.h" #include "wlan_qct_tl.h" #include "vos_memory.h" +#include "vos_trace.h" #ifdef TRACE_RECORD -static tTraceRecord gTraceTbl[MAX_TRACE_RECORDS]; -static tTraceData gTraceData; -static tpTraceCb traceCBTable[VOS_MODULE_ID_MAX]; /* --------------------------------------------------------------------------- \fn macTraceGetHDDWlanConnState @@ -812,8 +810,6 @@ tANI_U8* macTraceGetWdaMsgString( tANI_U16 wdaMsg ) } } - - tANI_U8* macTraceGetLimMsgString( tANI_U16 limMsg ) { switch( limMsg ) @@ -878,9 +874,6 @@ tANI_U8* macTraceGetLimMsgString( tANI_U16 limMsg ) } } - - - tANI_U8* macTraceGetCfgMsgString( tANI_U16 cfgMsg ) { switch( cfgMsg ) @@ -918,157 +911,21 @@ tANI_U8* macTraceGetModuleString( tANI_U8 moduleId ) //return gVosTraceInfo[moduleId].moduleNameStr; } - - - - - - - - - -void macTraceInit(tpAniSirGlobal pMac) -{ - tANI_U8 i; - gTraceData.head = INVALID_TRACE_ADDR; - gTraceData.tail = INVALID_TRACE_ADDR; - gTraceData.num = 0; - gTraceData.enable = TRUE; - gTraceData.dumpCount = DEFAULT_TRACE_DUMP_COUNT; - gTraceData.numSinceLastDump = 0; - - for(i=0; i<VOS_MODULE_ID_MAX; i++) - traceCBTable[i] = NULL; - -} - - - - - void macTraceReset(tpAniSirGlobal pMac) { } - void macTrace(tpAniSirGlobal pMac, tANI_U8 code, tANI_U8 session, tANI_U32 data) { //Today macTrace is being invoked by PE only, need to remove this function once PE is migrated to using new trace API. macTraceNew(pMac, VOS_MODULE_ID_PE, code, session, data); - -#if 0 - tpTraceRecord rec = NULL; - - //limLog(pMac, LOGE, "mac Trace code: %d, data: %x, head: %d, tail: %d\n", code, data, gTraceData.head, gTraceData.tail); - - if(!gTraceData.enable) - return; - gTraceData.num++; - - if (gTraceData.head == INVALID_TRACE_ADDR) - { - /* first record */ - gTraceData.head = 0; - gTraceData.tail = 0; - } - else - { - /* queue is not empty */ - tANI_U32 tail = gTraceData.tail + 1; - - if (tail == MAX_TRACE_RECORDS) - tail = 0; - - if (gTraceData.head == tail) - { - /* full */ - if (++gTraceData.head == MAX_TRACE_RECORDS) - gTraceData.head = 0; - } - - gTraceData.tail = tail; - } - - rec = &gTraceTbl[gTraceData.tail]; - rec->code = code; - rec->session = session; - rec->data = data; - rec->time = vos_timer_get_system_time(); - rec->module = VOS_MODULE_ID_PE; - gTraceData.numSinceLastDump ++; - - if(gTraceData.numSinceLastDump == gTraceData.dumpCount) - { - limLog(pMac, LOGE, "Trace Dump last %d traces\n", gTraceData.dumpCount); - macTraceDumpAll(pMac, 0, 0, gTraceData.dumpCount); - gTraceData.numSinceLastDump = 0; - } - #endif - } - - void macTraceNew(tpAniSirGlobal pMac, tANI_U8 module, tANI_U8 code, tANI_U8 session, tANI_U32 data) { - tpTraceRecord rec = NULL; - - //limLog(pMac, LOGE, "mac Trace code: %d, data: %x, head: %d, tail: %d\n", code, data, gTraceData.head, gTraceData.tail); - - if(!gTraceData.enable) - return; - - if(vos_is_in_irq_context()) - return; - - //If module is not registered, don't record for that module. - if(traceCBTable[module] == NULL) - return; - pe_AcquireGlobalLock( &pMac->lim ); - - gTraceData.num++; - - if (gTraceData.head == INVALID_TRACE_ADDR) - { - /* first record */ - gTraceData.head = 0; - gTraceData.tail = 0; - } - else - { - /* queue is not empty */ - tANI_U32 tail = gTraceData.tail + 1; - - if (tail == MAX_TRACE_RECORDS) - tail = 0; - - if (gTraceData.head == tail) - { - /* full */ - if (++gTraceData.head == MAX_TRACE_RECORDS) - gTraceData.head = 0; - } - - gTraceData.tail = tail; - } - - rec = &gTraceTbl[gTraceData.tail]; - rec->code = code; - rec->session = session; - rec->data = data; - rec->time = vos_timer_get_system_time(); - rec->module = module; - gTraceData.numSinceLastDump ++; - pe_ReleaseGlobalLock( &pMac->lim ); - + vos_trace(module, code, session, data); } - - - - - - tANI_U8* macTraceMsgString(tpAniSirGlobal pMac, tANI_U32 msgType) { tANI_U16 msgId = (tANI_U16)MAC_TRACE_GET_MSG_ID(msgType); @@ -1090,97 +947,4 @@ tANI_U8* macTraceMsgString(tpAniSirGlobal pMac, tANI_U32 msgType) return ((tANI_U8*)"Unknown MsgType"); } } - - - - - - -void macTraceDumpAll(tpAniSirGlobal pMac, tANI_U8 code, tANI_U8 session, tANI_U32 count) -{ - tpTraceRecord pRecord; - tANI_S32 i, tail; - - - if(!gTraceData.enable) - { - VOS_TRACE( VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_ERROR, "Tracing Disabled \n"); - return; - } - - VOS_TRACE( VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_ERROR, - "Total Records: %d, Head: %d, Tail: %d\n", gTraceData.num, gTraceData.head, gTraceData.tail); - - pe_AcquireGlobalLock( &pMac->lim ); - if (gTraceData.head != INVALID_TRACE_ADDR) - { - - i = gTraceData.head; - tail = gTraceData.tail; - - if (count) - { - if (count > gTraceData.num) - count = gTraceData.num; - if (count > MAX_TRACE_RECORDS) - count = MAX_TRACE_RECORDS; - if(tail >= (count + 1)) - { - i = tail - count + 1; - } - else - { - i = MAX_TRACE_RECORDS - ((count + 1) - tail); - } - } - - if (i < 0) - { - i = 0; - } - else if (i >= MAX_TRACE_RECORDS) - { - i = MAX_TRACE_RECORDS - 1; - } - pRecord = &gTraceTbl[i]; - - for (;;) - { - if ( (code == 0 || (code == pRecord->code)) && - (traceCBTable[pRecord->module] != NULL)) - traceCBTable[pRecord->module](pMac, pRecord, (tANI_U16)i); - - if (i == tail) - break; - i += 1; - - if (i == MAX_TRACE_RECORDS) - { - i = 0; - pRecord = &gTraceTbl[0]; - } - else - pRecord += 1; - } - gTraceData.numSinceLastDump = 0; - - } - pe_ReleaseGlobalLock( &pMac->lim ); - -} - - -void macTraceCfg(tpAniSirGlobal pMac, tANI_U32 enable, tANI_U32 dumpCount, tANI_U32 code, tANI_U32 session) -{ - gTraceData.enable = (tANI_U8)enable; - gTraceData.dumpCount= (tANI_U16)dumpCount; - gTraceData.numSinceLastDump = 0; -} - -void macTraceRegister( tpAniSirGlobal pMac, VOS_MODULE_ID moduleId, tpTraceCb traceCb) -{ - traceCBTable[moduleId] = traceCb; -} - - #endif diff --git a/CORE/VOSS/inc/vos_trace.h b/CORE/VOSS/inc/vos_trace.h index 897a9e036f67..b87a41edb4fb 100644 --- a/CORE/VOSS/inc/vos_trace.h +++ b/CORE/VOSS/inc/vos_trace.h @@ -45,6 +45,8 @@ ------------------------------------------------------------------------*/ #include <vos_types.h> // For VOS_MODULE_ID... #include <stdarg.h> // For va_list... +#include <vos_status.h> +#include <i_vos_types.h> /*-------------------------------------------------------------------------- Type declarations @@ -88,9 +90,51 @@ typedef enum // TODO: remove this once this is not used on Android #define VOS_ENABLE_TRACING #define WCONN_TRACE_KMSG_LOG_BUFF +#define MAX_VOS_TRACE_RECORDS 4000 +#define INVALID_VOS_TRACE_ADDR 0xffffffff +#define DEFAULT_VOS_TRACE_DUMP_COUNT 0 #include <i_vos_trace.h> +#ifdef TRACE_RECORD + +#define MTRACE(p) p +#define NO_SESSION 0xFF + +#else +#define MTRACE(p) { } + +#endif + +/*-------------------------------------------------------------------------- + Structure definition + ------------------------------------------------------------------------*/ +typedef struct svosTraceRecord +{ + v_U32_t time; + v_U8_t module; + v_U8_t code; + v_U8_t session; + v_U32_t data; +}tvosTraceRecord, *tpvosTraceRecord; + +typedef struct svosTraceData +{ + // MTRACE logs are stored in ring buffer where head represents the position + // of first record, tail represents the position of last record added till + // now and num is the count of total record added. + v_U32_t head; + v_U32_t tail; + v_U32_t num; + v_U16_t numSinceLastDump; + + //Config for controlling the trace + v_U8_t enable; + v_U16_t dumpCount; //will dump after number of records reach this number. + +}tvosTraceData; + + #define CASE_RETURN_STRING( str ) \ case ( ( str ) ): return( (tANI_U8*)(#str) ); @@ -157,4 +201,11 @@ void vos_wconn_trace_init(void); void vos_wconn_trace_exit(void); #endif +typedef void (*tpvosTraceCb) (void *pMac, tpvosTraceRecord, v_U16_t); +void vos_trace(v_U8_t module, v_U8_t code, v_U8_t session, v_U32_t data); +void vosTraceRegister(VOS_MODULE_ID, tpvosTraceCb); +VOS_STATUS vos_trace_spin_lock_init(void); +void vosTraceInit(void); +void vosTraceEnable(v_U32_t); +void vosTraceDumpAll(void*, v_U8_t, v_U8_t, v_U32_t, v_U32_t); #endif diff --git a/CORE/VOSS/src/vos_api.c b/CORE/VOSS/src/vos_api.c index 299cd34c4473..b47e3694fde1 100644 --- a/CORE/VOSS/src/vos_api.c +++ b/CORE/VOSS/src/vos_api.c @@ -74,6 +74,7 @@ #endif #include "sapApi.h" +#include "vos_trace.h" #ifdef WLAN_BTAMP_FEATURE @@ -174,6 +175,13 @@ VOS_STATUS vos_preOpen ( v_CONTEXT_t *pVosContext ) *pVosContext = gpVosContext; + /* Initialize the spinlock */ + vos_trace_spin_lock_init(); + /* it is the right time to initialize MTRACE structures */ + #if defined(TRACE_RECORD) + vosTraceInit(); + #endif + return VOS_STATUS_SUCCESS; } /* vos_preOpen()*/ @@ -282,6 +290,7 @@ VOS_STATUS vos_open( v_CONTEXT_t *pVosContext, v_SIZE_t hddContextSize ) /* Initialize the timer module */ vos_timer_module_init(); + /* Initialize the probe event */ if (vos_event_init(&gpVosContext->ProbeEvent) != VOS_STATUS_SUCCESS) { diff --git a/CORE/VOSS/src/vos_trace.c b/CORE/VOSS/src/vos_trace.c index dad092cb2692..19b221d0afc5 100644 --- a/CORE/VOSS/src/vos_trace.c +++ b/CORE/VOSS/src/vos_trace.c @@ -114,8 +114,23 @@ moduleTraceInfo gVosTraceInfo[ VOS_MODULE_ID_MAX ] = [VOS_MODULE_ID_HTC] = { VOS_DEFAULT_TRACE_LEVEL, "HTC" }, #endif }; +/*------------------------------------------------------------------------- + Static and Global variables + ------------------------------------------------------------------------*/ +static spinlock_t ltraceLock; - +static tvosTraceRecord gvosTraceTbl[MAX_VOS_TRACE_RECORDS]; +// Global vosTraceData +static tvosTraceData gvosTraceData; +/* + * all the call back functions for dumping MTRACE messages from ring buffer + * are stored in vostraceCBTable,these callbacks are initialized during init only + * so, we will make a copy of these call back functions and maintain in to + * vostraceRestoreCBTable. Incase if we make modifications to vostraceCBTable, + * we can certainly retrieve all the call back functions back from Restore Table + */ +static tpvosTraceCb vostraceCBTable[VOS_MODULE_ID_MAX]; +static tpvosTraceCb vostraceRestoreCBTable[VOS_MODULE_ID_MAX]; /*------------------------------------------------------------------------- Functions ------------------------------------------------------------------------*/ @@ -421,3 +436,281 @@ void vos_trace_hex_dump( VOS_MODULE_ID module, VOS_TRACE_LEVEL level, } #endif + +/*----------------------------------------------------------------------------- + \brief vosTraceEnable() - Enable MTRACE for specific modules whose bits are + set in bitmask. set the bitmask according to enum value of the modules. + + this functions will be called when you issue ioctl as mentioned following + [iwpriv wlan0 setdumplog <value>]. + <value> - Decimal number, i.e. 64 decimal value shows only SME module, + 128 decimal value shows only PE module, 192 decimal value shows PE and SME. + + \param - bitmask_of_moduleId - as explained above set bitmask according to + enum of the modules. + 32 [dec] = 0010 0000 [bin] <enum of HDD is 5> + 64 [dec] = 0100 0000 [bin] <enum of SME is 6> + 128 [dec] = 1000 0000 [bin] <enum of PE is 7> + ---------------------------------------------------------------------------*/ +void vosTraceEnable(v_U32_t bitmask_of_moduleId) +{ + int i; + if (bitmask_of_moduleId) + { + for (i=0; i<VOS_MODULE_ID_MAX; i++) + { + if (!((bitmask_of_moduleId >> i) & 1 )) + { + vostraceRestoreCBTable[i] = vostraceCBTable[i]; + vostraceCBTable[i] = NULL; + } + } + } + else + { + for (i=0; i<VOS_MODULE_ID_MAX; i++) + { + if (NULL != vostraceRestoreCBTable[i]) + { + vostraceCBTable[i] = vostraceRestoreCBTable[i]; + } + } + } +} + +/*----------------------------------------------------------------------------- + \brief vosTraceInit() - Initializes vos trace structures and variables. + + Called immediately after vos_preopen, so that we can start recording HDD + events ASAP. + ----------------------------------------------------------------------------*/ +void vosTraceInit() +{ + v_U8_t i; + gvosTraceData.head = INVALID_VOS_TRACE_ADDR; + gvosTraceData.tail = INVALID_VOS_TRACE_ADDR; + gvosTraceData.num = 0; + gvosTraceData.enable = TRUE; + gvosTraceData.dumpCount = DEFAULT_VOS_TRACE_DUMP_COUNT; + gvosTraceData.numSinceLastDump = 0; + + for (i=0; i<VOS_MODULE_ID_MAX; i++) + { + vostraceCBTable[i] = NULL; + vostraceRestoreCBTable[i] = NULL; + } +} + +/*----------------------------------------------------------------------------- + \brief vos_trace() - puts the messages in to ring-buffer + + This function will be called from each module who wants record the messages + in circular queue. Before calling this functions make sure you have + registered your module with voss through vosTraceRegister function. + + \param module - enum of module, basically module id. + \param code - + \param session - + \param data - actual message contents. + ----------------------------------------------------------------------------*/ +void vos_trace(v_U8_t module, v_U8_t code, v_U8_t session, v_U32_t data) +{ + tpvosTraceRecord rec = NULL; + + + if (!gvosTraceData.enable) + { + return; + } + //If module is not registered, don't record for that module. + if (NULL == vostraceCBTable[module]) + { + return; + } + + /* Aquire the lock so that only one thread at a time can fill the ring buffer */ + spin_lock(<raceLock); + + gvosTraceData.num++; + + if (gvosTraceData.num > MAX_VOS_TRACE_RECORDS) + { + gvosTraceData.num = MAX_VOS_TRACE_RECORDS; + } + + if (INVALID_VOS_TRACE_ADDR == gvosTraceData.head) + { + /* first record */ + gvosTraceData.head = 0; + gvosTraceData.tail = 0; + } + else + { + /* queue is not empty */ + v_U32_t tail = gvosTraceData.tail + 1; + + if (MAX_VOS_TRACE_RECORDS == tail) + { + tail = 0; + } + + if (gvosTraceData.head == tail) + { + /* full */ + if (MAX_VOS_TRACE_RECORDS == ++gvosTraceData.head) + { + gvosTraceData.head = 0; + } + } + + gvosTraceData.tail = tail; + } + + rec = &gvosTraceTbl[gvosTraceData.tail]; + rec->code = code; + rec->session = session; + rec->data = data; + rec->time = vos_timer_get_system_time(); + rec->module = module; + gvosTraceData.numSinceLastDump ++; + spin_unlock(<raceLock); +} + + +/*----------------------------------------------------------------------------- + \brief vos_trace_spin_lock_init() - Initializes the lock variable before use + + This function will be called from vos_preOpen, we will have lock available + to use ASAP. + ----------------------------------------------------------------------------*/ +VOS_STATUS vos_trace_spin_lock_init() +{ + spin_lock_init(<raceLock); + + return VOS_STATUS_SUCCESS; +} + +/*----------------------------------------------------------------------------- + \brief vosTraceRegister() - Registers the call back functions to display the + messages in particular format mentioned in these call back functions. + + this functions should be called by interested module in their init part as + we will be ready to register as soon as modules are up. + + \param moduleID - enum value of module + \param vostraceCb - call back functions to display the messages in particular + format. + ----------------------------------------------------------------------------*/ +void vosTraceRegister(VOS_MODULE_ID moduleID, tpvosTraceCb vostraceCb) +{ + vostraceCBTable[moduleID] = vostraceCb; +} + +/*------------------------------------------------------------------------------ + \brief vosTraceDumpAll() - Dump data from ring buffer via call back functions + registered with VOSS + + This function will be called up on issueing ioctl call as mentioned following + [iwpriv wlan0 dumplog 0 0 <n> <bitmask_of_module>] + + <n> - number lines to dump starting from tail to head. + + <bitmask_of_module> - if anybody wants to know how many messages were recorded + for particular module/s mentioned by setbit in bitmask from last <n> messages. + it is optional, if you don't provide then it will dump everything from buffer. + + \param pMac - context of particular module + \param code - + \param session - + \param count - number of lines to dump starting from tail to head + ----------------------------------------------------------------------------*/ +void vosTraceDumpAll(void *pMac, v_U8_t code, v_U8_t session, + v_U32_t count, v_U32_t bitmask_of_module) +{ + tvosTraceRecord pRecord; + tANI_S32 i, tail; + + + if (!gvosTraceData.enable) + { + VOS_TRACE( VOS_MODULE_ID_SYS, + VOS_TRACE_LEVEL_ERROR, "Tracing Disabled"); + return; + } + + VOS_TRACE( VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_ERROR, + "Total Records: %d, Head: %d, Tail: %d", + gvosTraceData.num, gvosTraceData.head, gvosTraceData.tail); + + /* Aquire the lock so that only one thread at a time can read the ring buffer */ + spin_lock(<raceLock); + + if (gvosTraceData.head != INVALID_VOS_TRACE_ADDR) + { + i = gvosTraceData.head; + tail = gvosTraceData.tail; + + if (count) + { + if (count > gvosTraceData.num) + { + count = gvosTraceData.num; + } + if (tail >= (count - 1)) + { + i = tail - count + 1; + } + else if (count != MAX_VOS_TRACE_RECORDS) + { + i = MAX_VOS_TRACE_RECORDS - ((count - 1) - tail); + } + } + + pRecord = gvosTraceTbl[i]; + /* right now we are not using numSinceLastDump member but in future + we might re-visit and use this member to track how many latest + messages got added while we were dumping from ring buffer */ + gvosTraceData.numSinceLastDump = 0; + spin_unlock(<raceLock); + for (;;) + { + if ((code == 0 || (code == pRecord.code)) && + (vostraceCBTable[pRecord.module] != NULL)) + { + if (0 == bitmask_of_module) + { + vostraceCBTable[pRecord.module](pMac, &pRecord, (v_U16_t)i); + } + else + { + if (bitmask_of_module & (1 << pRecord.module)) + { + vostraceCBTable[pRecord.module](pMac, &pRecord, (v_U16_t)i); + } + } + } + + if (i == tail) + { + break; + } + i += 1; + + spin_lock(<raceLock); + if (MAX_VOS_TRACE_RECORDS == i) + { + i = 0; + pRecord= gvosTraceTbl[0]; + } + else + { + pRecord = gvosTraceTbl[i]; + } + spin_unlock(<raceLock); + } + } + else + { + spin_unlock(<raceLock); + } +} |
