wlan:Logging Implement DXE Trace record

Implement DXE trace record for debugging stability issues.
This provide information about last actions performed by
the DXE host driver.

Change-Id: I8214a0847d37d9e03342af952abd58eb0fe8b5b8
CRs-Fixed: 930016
diff --git a/CORE/DXE/src/wlan_qct_dxe.c b/CORE/DXE/src/wlan_qct_dxe.c
index 253203b..4d3d3f9 100644
--- a/CORE/DXE/src/wlan_qct_dxe.c
+++ b/CORE/DXE/src/wlan_qct_dxe.c
@@ -90,13 +90,17 @@
 /* CSR max retry count */
 #define WLANDXE_CSR_MAX_READ_COUNT         30
 
+/* DXETRACE max records count */
+#define MAX_DXE_TRACE_RECORDS              512
+#define INVALID_TRACE_ADDR                 0xffffffff
 
 /* This is temporary fot the compile
  * WDI will release official version
  * This must be removed */
 #define WDI_GET_PAL_CTX()                  NULL
 
-
+#define TRACE_WLANDXE_VAR_ENABLE           1
+#define TRACE_WLANDXE_VAR_DISABLE          0
 /*-------------------------------------------------------------------------
   *  Local Varables
   *-------------------------------------------------------------------------*/
@@ -113,6 +117,9 @@
    };
 static  wpt_packet               *rx_reaped_buf[WLANDXE_MAX_REAPED_RX_FRAMES];
 static WLANDXE_EnvInformation    dxeEnvBlk;
+static dxeTraceData              gdxeTraceData;
+static dxeTraceRecord            gdxeTraceTbl[MAX_DXE_TRACE_RECORDS];
+static spinlock_t                dtraceLock;
 
 /*-------------------------------------------------------------------------
   *  External Function Proto Type
@@ -144,6 +151,11 @@
    WLANDXE_CtrlBlkType     *hostCtxt
 );
 
+static void dxeTrace
+(
+  v_U8_t chan, v_U8_t code, v_U32_t data
+);
+
 /*-------------------------------------------------------------------------
   *  Local Function
   *-------------------------------------------------------------------------*/
@@ -3033,7 +3045,8 @@
                "dxeRXEventHandler Enable RX Ready interrupt fail");
       return;
    }
-
+   DXTRACE(dxeTrace(WLANDXE_DMA_CHANNEL_MAX, TRACE_RXINT_STATE,
+                    TRACE_WLANDXE_VAR_ENABLE));
    HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
             "%s Exit", __func__);
    return;
@@ -3158,6 +3171,7 @@
    WLANDXE_CtrlBlkType      *dxeCtxt    = (WLANDXE_CtrlBlkType *)hostCtxt;
    wpt_status                status     = eWLAN_PAL_STATUS_SUCCESS;
    wpt_uint32                regValue;
+   wpt_uint32                intSrc     = 0;
 
    /* Set Interrupt processing bit
     * During this bit set, WLAN HW may not power collapse */
@@ -3185,6 +3199,12 @@
       return;         
    }
 
+   wpalReadRegister(WLANDXE_INT_SRC_RAW_ADDRESS,
+                                  &intSrc);
+   /* Note: intSrc which holds the INT_SRC_RAW_ADDRESS reg value
+      While debugging crash dump convert to power of 2 for channel type */
+   DXTRACE(dxeTrace(intSrc, TRACE_RXINT_STATE, TRACE_WLANDXE_VAR_DISABLE));
+
    /* Serialize RX Ready interrupt upon RX thread */
    if(NULL == dxeCtxt->rxIsrMsg)
    {
@@ -3382,6 +3402,7 @@
          dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_TRUE);
          dxeNotifySmsm(eWLAN_PAL_TRUE, eWLAN_PAL_FALSE);
          tempDxeCtrlBlk->smsmToggled = eWLAN_PAL_TRUE;
+         DXTRACE(dxeTrace(channelEntry->channelType, TRACE_SMSM_NOTIFY, TRACE_WLANDXE_VAR_ENABLE));
       }
       return status;
    }
@@ -3408,6 +3429,7 @@
                   "dxeTXPushFrame Write Channel Ctrl Register fail");
          return status;
       }
+      DXTRACE(dxeTrace(channelEntry->channelType, TRACE_CH_ENABLE, TRACE_WLANDXE_VAR_ENABLE));
 
       /* Update channel head as next avaliable linked slot */
       channelEntry->headCtrlBlk = currentCtrlBlk;
@@ -4144,6 +4166,10 @@
       }
    }
 
+   if(eWLAN_PAL_TRUE == dxeCtxt->txIntEnable)
+      DXTRACE(dxeTrace(WLANDXE_DMA_CHANNEL_MAX, TRACE_TXINT_STATE,
+                       TRACE_WLANDXE_VAR_ENABLE));
+
    dxeEnvBlk.txCmpIntChanlSrc = 0;
 
    /*Kicking the DXE after the TX Complete interrupt was enabled - to avoid 
@@ -4440,8 +4466,9 @@
    void                    *hostCtxt
 )
 {
-   WLANDXE_CtrlBlkType      *dxeCtxt    = (WLANDXE_CtrlBlkType *)hostCtxt;
+   WLANDXE_CtrlBlkType      *dxeCtxt = (WLANDXE_CtrlBlkType *)hostCtxt;
    wpt_status                status  = eWLAN_PAL_STATUS_SUCCESS;
+   wpt_uint32                intSrc  = 0;
 
    HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
             "%s Enter", __func__);
@@ -4475,6 +4502,11 @@
    }
    dxeCtxt->txIntEnable = eWLAN_PAL_FALSE;
 
+   wpalReadRegister(WLANDXE_INT_SRC_RAW_ADDRESS,
+                                  &intSrc);
+   /* intSrc which holds the INT_SRC_RAW_ADDRESS reg value
+      While debugging crash dump convert to power of 2 for channel type */
+   DXTRACE(dxeTrace(intSrc, TRACE_TXINT_STATE, TRACE_WLANDXE_VAR_DISABLE));
 
    if( dxeCtxt->ucTxMsgCnt )
    {
@@ -4482,7 +4514,7 @@
                  "Avoiding serializing TX Complete event");
     return;
    }
-   
+
    dxeCtxt->ucTxMsgCnt = 1;
 
    /* Serialize TX complete interrupt upon TX thread */
@@ -4493,6 +4525,7 @@
        HDXE_ASSERT(0);
        return;
    }
+
    status = wpalPostTxMsg(WDI_GET_PAL_CTX(),
                           dxeCtxt->txIsrMsg);
    if(eWLAN_PAL_STATUS_SUCCESS != status)
@@ -4506,6 +4539,97 @@
    return;
 }
 
+/*==========================================================================
+  @  Function Name
+      dxeTraceInit
+
+  @  Description
+      Initialize the DXTRACE when enabled
+
+  @  Parameters
+      NONE
+
+  @  Return
+      NONE
+===========================================================================*/
+void dxeTraceInit(void)
+{
+   gdxeTraceData.head   = INVALID_VOS_TRACE_ADDR;
+   gdxeTraceData.tail   = INVALID_VOS_TRACE_ADDR;
+   gdxeTraceData.num    = 0;
+   gdxeTraceData.enable = eWLAN_PAL_TRUE;
+}
+
+/*==========================================================================
+  @  Function Name
+      dxeTrace
+
+  @  Description
+       puts the messages in to ring-buffer
+
+  @  Parameters
+      v_U8_t   chan
+               Rx/Tx path record
+      v_U8_t   code
+               Rx/Tx Event
+      v_U32_t  data
+               Actual message contents
+  @  Return
+      NONE
+===========================================================================*/
+void dxeTrace(v_U8_t chan, v_U8_t code, v_U32_t data)
+{
+    pdxeTraceRecord rec = NULL;
+    unsigned long flags;
+
+    if (!gdxeTraceData.enable)
+    {
+        return;
+    }
+
+    /* Aquire the lock and only one thread can access the buffer at a time */
+    spin_lock_irqsave(&dtraceLock, flags);
+
+    gdxeTraceData.num++;
+
+    if (gdxeTraceData.num > MAX_DXE_TRACE_RECORDS)
+    {
+        gdxeTraceData.num = MAX_DXE_TRACE_RECORDS;
+    }
+    if (INVALID_VOS_TRACE_ADDR == gdxeTraceData.head)
+    {
+        /* first record */
+        gdxeTraceData.head = 0;
+        gdxeTraceData.tail = 0;
+    }
+    else
+    {
+        /* queue is not empty */
+        v_U32_t tail = gdxeTraceData.tail + 1;
+        if (MAX_DXE_TRACE_RECORDS == tail)
+        {
+            tail = 0;
+        }
+        if (gdxeTraceData.head == tail)
+        {
+            /* full */
+            if (MAX_DXE_TRACE_RECORDS == ++gdxeTraceData.head)
+            {
+                gdxeTraceData.head = 0;
+            }
+        }
+        gdxeTraceData.tail = tail;
+    }
+
+    rec = &gdxeTraceTbl[gdxeTraceData.tail];
+    rec->code = code;
+    rec->data = data;
+    rec->time = vos_timer_get_system_time();
+    rec->chan = chan;
+
+    spin_unlock_irqrestore(&dtraceLock, flags);
+}
+
 /*-------------------------------------------------------------------------
  *  Global Function
  *-------------------------------------------------------------------------*/
@@ -4678,6 +4802,10 @@
    wpalTimerInit(&tempDxeCtrlBlk->dxeSSRTimer,
                  dxeSSRTimerExpHandler, tempDxeCtrlBlk);
 
+#ifdef DXE_TRACE
+   DXTRACE(dxeTraceInit());
+#endif
+
    HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
             "WLANDXE_Open Success");
    HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
@@ -5364,6 +5492,8 @@
          break;
    }
 
+   DXTRACE(dxeTrace(WLANDXE_DMA_CHANNEL_MAX, TRACE_POWER_STATE, dxeCtxt->hostPowerState));
+
    if(WLANDXE_POWER_STATE_BMPS_PENDING != dxeCtxt->hostPowerState)
    {
       dxeCtxt->setPowerStateCb(status, 
diff --git a/CORE/DXE/src/wlan_qct_dxe_i.h b/CORE/DXE/src/wlan_qct_dxe_i.h
index 23f3b29..90a8935 100644
--- a/CORE/DXE/src/wlan_qct_dxe_i.h
+++ b/CORE/DXE/src/wlan_qct_dxe_i.h
@@ -73,6 +73,12 @@
  * -------------------------------------------------------------------------*/
 #define WLANDXE_CTXT_COOKIE              0xC00CC111
 
+#ifdef DXE_TRACE
+#define DXTRACE(p) p
+#else
+#define DXTRACE(p) {  }
+#endif
+
 #define foreach_valid_channel(idx)                \
     for (idx = 0; idx < WDTS_CHANNEL_MAX; idx++)  \
         if (!(dxeGetEnabledChannels() & 1<<idx))  \
@@ -509,6 +515,15 @@
    WLANDXE_DMA_CHANNEL_MAX
 } WLANDXE_DMAChannelType;
 
+enum
+{
+   TRACE_CH_ENABLE,
+   TRACE_POWER_STATE,
+   TRACE_RXINT_STATE,
+   TRACE_TXINT_STATE,
+   TRACE_SMSM_NOTIFY
+};
+
 /** DXE HW Long Descriptor format */
 typedef struct
 {
@@ -720,6 +735,26 @@
    wpt_uint8                       rxIntChanlSrc;
    wpt_uint8                       txCmpIntChanlSrc;
 } WLANDXE_EnvInformation;
+
+typedef struct
+{
+    /* Records are stored in ring buffer */
+    v_U32_t head;
+    v_U32_t tail;
+    v_U32_t num;
+
+    /* Config for controlling the trace */
+    v_U8_t enable;
+}dxeTraceData;
+
+typedef struct
+{
+    v_U32_t time;
+    v_U8_t chan;
+    v_U8_t code;
+    v_U32_t data;
+}dxeTraceRecord, *pdxeTraceRecord;
+
 /*==========================================================================
   @  Function Name 
       dxeCommonDefaultConfig
diff --git a/Kbuild b/Kbuild
index 66d7b98..148b655 100644
--- a/Kbuild
+++ b/Kbuild
@@ -576,6 +576,7 @@
 		-DSME_TRACE_RECORD \
 		-DPE_DEBUG_LOGW \
 		-DPE_DEBUG_LOGE \
+                -DDXE_TRACE \
 		-DDEBUG
 endif