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);
+}