wlan: Get debug information when the HAL_START_RSP fails

When there is a timout during in the vos_start waiting for HAL_START_RSP
from the firmware there is not much debug information if the SMD event is
recieved or if the mcthread is stuck, dump following information :

1) SMD stats, open/read/write/close smd stats.
2) Dump the infomation regarding the messages processed by the MCthread.
3) Also probe the mcthread if it is stuck and dump the mcthread struck info

CRs-Fixed: 1110501
Change-Id: I48041576a5af26b466a9a50b8185d5f3655ff56d
diff --git a/CORE/SYS/common/src/wlan_qct_sys.c b/CORE/SYS/common/src/wlan_qct_sys.c
index be54dff..11f9fe5 100644
--- a/CORE/SYS/common/src/wlan_qct_sys.c
+++ b/CORE/SYS/common/src/wlan_qct_sys.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2015,2017 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -778,7 +778,7 @@
 
     vosMessage.reserved = FTM_SYS_MSG_COOKIE;
     vosMessage.type     = SYS_MSG_ID_MC_THR_PROBE;
-    vosMessage.callback = NULL;
+    vosMessage.callback = vos_dump_thread_stacks;
     vosMessage.bodyptr  = NULL;
 
     vos_mq_post_message(VOS_MQ_ID_SYS, &vosMessage);
diff --git a/CORE/VOSS/inc/vos_api.h b/CORE/VOSS/inc/vos_api.h
index ddfc25c..00c1817 100644
--- a/CORE/VOSS/inc/vos_api.h
+++ b/CORE/VOSS/inc/vos_api.h
@@ -208,6 +208,17 @@
 	WLAN_LOG_REASON_SCAN_NOT_ALLOWED,
 };
 
+/**
+ * vos_wdi_trace_event_type: Trace type for WDI Write/Read
+ * VOS_WDI_READ: Log the WDI read event
+ * VOS_WDI_WRITE: Log the WDI write event
+ */
+typedef enum
+{
+   VOS_WDI_READ,
+   VOS_WDI_WRITE,
+} vos_wdi_trace_event_type;
+
 /*------------------------------------------------------------------------- 
   Function declarations and documenation
   ------------------------------------------------------------------------*/
@@ -516,4 +527,7 @@
 
 v_BOOL_t vos_is_probe_rsp_offload_enabled(void);
 void vos_set_snoc_high_freq_voting(bool enable);
+void vos_smd_dump_stats(void);
+void vos_log_wdi_event(uint16 msg, vos_wdi_trace_event_type event);
+void vos_dump_wdi_events(void);
 #endif // if !defined __VOS_NVITEM_H
diff --git a/CORE/VOSS/src/vos_api.c b/CORE/VOSS/src/vos_api.c
index fe97e74..814c113 100644
--- a/CORE/VOSS/src/vos_api.c
+++ b/CORE/VOSS/src/vos_api.c
@@ -83,7 +83,7 @@
 #include "bapInternal.h"
 #include "bap_hdd_main.h"
 #endif //WLAN_BTAMP_FEATURE
-
+#include "wlan_qct_wdi_cts.h"
 
 /*---------------------------------------------------------------------------
  * Preprocessor Definitions and Constants
@@ -100,6 +100,9 @@
 /* Approximate amount of time to wait for WDA to issue a DUMP req */
 #define VOS_WDA_RESP_TIMEOUT WDA_STOP_TIMEOUT
 
+/* Trace index for WDI Read/Write */
+#define VOS_TRACE_INDEX_MAX 256
+
 /*---------------------------------------------------------------------------
  * Data definitions
  * ------------------------------------------------------------------------*/
@@ -107,6 +110,16 @@
 static pVosContextType gpVosContext;
 static v_U8_t vos_multicast_logging;
 
+struct vos_wdi_trace
+{
+   vos_wdi_trace_event_type event;
+   uint16        message;
+   uint64        time;
+};
+
+static struct vos_wdi_trace gvos_wdi_msg_trace[VOS_TRACE_INDEX_MAX];
+uint16 gvos_wdi_msg_trace_index = 0;
+
 /*---------------------------------------------------------------------------
  * Forward declaration
  * ------------------------------------------------------------------------*/
@@ -900,6 +913,12 @@
      if ( vStatus == VOS_STATUS_E_TIMEOUT )
      {
          WDA_setNeedShutdown(vosContext);
+         vos_smd_dump_stats();
+         vos_dump_wdi_events();
+         VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
+               "%s: Test MC thread by posting a probe message to SYS",
+                __func__);
+         wlan_sys_probe();
      }
      VOS_ASSERT(0);
      return VOS_STATUS_E_FAILURE;
@@ -3705,3 +3724,38 @@
    return;
 }
 #endif
+
+void vos_smd_dump_stats(void)
+{
+  WCTS_Dump_Smd_status();
+}
+
+void vos_log_wdi_event(uint16 msg, vos_wdi_trace_event_type event)
+{
+
+   if (gvos_wdi_msg_trace_index >= VOS_TRACE_INDEX_MAX)
+   {
+          gvos_wdi_msg_trace_index = 0;
+   }
+
+   gvos_wdi_msg_trace[gvos_wdi_msg_trace_index].event = event;
+   gvos_wdi_msg_trace[gvos_wdi_msg_trace_index].time =
+                                 vos_get_monotonic_boottime();
+   gvos_wdi_msg_trace[gvos_wdi_msg_trace_index].message =  msg;
+   gvos_wdi_msg_trace_index++;
+
+   return;
+}
+
+void vos_dump_wdi_events(void)
+{
+   int i;
+
+   for(i = 0; i < VOS_TRACE_INDEX_MAX; i++) {
+            VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
+            "%s:event:%d time:%lld msg:%d ",__func__,
+            gvos_wdi_msg_trace[i].event,
+            gvos_wdi_msg_trace[i].time,
+            gvos_wdi_msg_trace[i].message);
+  }
+}
diff --git a/CORE/VOSS/src/vos_sched.c b/CORE/VOSS/src/vos_sched.c
index 0dafd25..f9014e7 100644
--- a/CORE/VOSS/src/vos_sched.c
+++ b/CORE/VOSS/src/vos_sched.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -2206,3 +2206,23 @@
                     "%s: Invalid thread %d invoked",__func__, thread_id);
    }
 }
+
+void vos_dump_thread_stacks(int threadId)
+{
+   /* Make sure that Vos Watchdog context has been initialized */
+   if (gpVosWatchdogContext == NULL)
+   {
+      VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
+          "%s: gpVosWatchdogContext == NULL", __func__);
+      return;
+   }
+     hddLog(LOGE, FL("Thread Stuck count reached threshold!!!"
+              "MC Count %d RX count %d TX count %d"),
+              gpVosWatchdogContext->mcThreadStuckCount,
+              gpVosWatchdogContext->rxThreadStuckCount,
+              gpVosWatchdogContext->txThreadStuckCount);
+
+   vos_dump_stack(MC_Thread);
+   vos_dump_stack(TX_Thread);
+   vos_dump_stack(RX_Thread);
+}
diff --git a/CORE/VOSS/src/vos_sched.h b/CORE/VOSS/src/vos_sched.h
index ed4839e..09b8038 100644
--- a/CORE/VOSS/src/vos_sched.h
+++ b/CORE/VOSS/src/vos_sched.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2017  The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -539,6 +539,6 @@
 void vos_wd_reset_thread_stuck_count(int threadId);
 bool vos_is_wd_thread(int threadId);
 void vos_dump_stack(uint8_t value);
-
+void vos_dump_thread_stacks(int threadId);
 
 #endif // #if !defined __VOSS_SCHED_H
diff --git a/CORE/WDI/CP/src/wlan_qct_wdi.c b/CORE/WDI/CP/src/wlan_qct_wdi.c
index 6de2e84..4e36426 100644
--- a/CORE/WDI/CP/src/wlan_qct_wdi.c
+++ b/CORE/WDI/CP/src/wlan_qct_wdi.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -22921,6 +22921,7 @@
   }
 
   wdiEventData.wdiResponse = HAL_2_WDI_RSP_TYPE( pHalMsgHeader->msgType );
+  vos_log_wdi_event(wdiEventData.wdiResponse, VOS_WDI_READ);
 
   /*The message itself starts after the header*/
   wdiEventData.pEventData     = (wpt_uint8*)pMsg + sizeof(tHalMsgHeader);
diff --git a/CORE/WDI/TRP/CTS/inc/wlan_qct_wdi_cts.h b/CORE/WDI/TRP/CTS/inc/wlan_qct_wdi_cts.h
index 16bfad0..daf87b0 100644
--- a/CORE/WDI/TRP/CTS/inc/wlan_qct_wdi_cts.h
+++ b/CORE/WDI/TRP/CTS/inc/wlan_qct_wdi_cts.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2013,2017 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -97,6 +97,16 @@
    WCTS_EVENT_MAX
 } WCTS_NotifyEventType;
 
+struct WdiSmdStats
+{
+  int smd_event_data;
+  int smd_event_open;
+  int smd_event_close;
+  int smd_event_status;
+  int smd_event_reopen_ready;
+  int smd_event_err;
+};
+
 /*----------------------------------------------------------------------------
  *   WDI callback types
  *--------------------------------------------------------------------------*/
@@ -253,4 +263,6 @@
 (
    WCTS_HandleType      wctsHandle
 );
+
+void WCTS_Dump_Smd_status(void);
 #endif /* #ifndef WLAN_QCT_WDI_CTS_H */
diff --git a/CORE/WDI/TRP/CTS/src/wlan_qct_wdi_cts.c b/CORE/WDI/TRP/CTS/src/wlan_qct_wdi_cts.c
index 9c04d88..ddf4d4d 100644
--- a/CORE/WDI/TRP/CTS/src/wlan_qct_wdi_cts.c
+++ b/CORE/WDI/TRP/CTS/src/wlan_qct_wdi_cts.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2015,2017 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -108,6 +108,8 @@
 /* time to wait for SMD channel to close (in msecs) */
 #define WCTS_SMD_CLOSE_TIMEOUT 5000
 
+/* Global Variable for WDI SMD stats */
+static struct WdiSmdStats gWdiSmdStats;
 /*----------------------------------------------------------------------------
  * Type Declarations
  * -------------------------------------------------------------------------*/
@@ -528,6 +530,7 @@
            wpalDriverReInit();
            return;
       }
+      gWdiSmdStats.smd_event_open++;
       palMsg = &pWCTSCb->wctsOpenMsg;
       break;
 
@@ -543,6 +546,7 @@
       WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
                  "%s: received SMD_EVENT_DATA from SMD", __func__);
       palMsg = &pWCTSCb->wctsDataMsg;
+      gWdiSmdStats.smd_event_data++;
       break;
 
    case SMD_EVENT_CLOSE:
@@ -560,11 +564,13 @@
 
       /* subsystem restart: shutdown */
       wpalDriverShutdown();
+      gWdiSmdStats.smd_event_close++;
       return;
 
    case SMD_EVENT_STATUS:
       WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
                  "%s: received SMD_EVENT_STATUS from SMD", __func__);
+      gWdiSmdStats.smd_event_status++;
       return;
 
    case SMD_EVENT_REOPEN_READY:
@@ -575,12 +581,14 @@
          running, this one is received when the threads are closed and
          the rmmod thread is waiting.  so just unblock that thread */
       wpalEventSet(&pWCTSCb->wctsEvent);
+      gWdiSmdStats.smd_event_reopen_ready++;
       return;
 
    default:
       WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
                  "%s: Unexpected event %u received from SMD",
                  __func__, event);
+      gWdiSmdStats.smd_event_err++;
 
       return;
    }
@@ -977,3 +985,19 @@
    return eWLAN_PAL_STATUS_SUCCESS;
 
 }/*WCTS_SendMessage*/
+
+void WCTS_Dump_Smd_status(void)
+{
+    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
+              "Smd Read Stats: %d", gWdiSmdStats.smd_event_data);
+    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
+              "Smd Open Stats: %d", gWdiSmdStats.smd_event_open);
+    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
+              "Smd Close Stats: %d", gWdiSmdStats.smd_event_close);
+    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
+              "Smd Status Stats: %d", gWdiSmdStats.smd_event_status);
+    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
+              "Smd Reopen Stats: %d", gWdiSmdStats.smd_event_reopen_ready);
+    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
+              "Smd Error Stats: %d", gWdiSmdStats.smd_event_err);
+}