summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAbhishek Singh <absingh@codeaurora.org>2016-04-27 14:10:53 +0530
committerGerrit - the friendly Code Review server <code-review@localhost>2016-05-04 21:18:44 -0700
commit5ea86536ef9359ec18e0ee5976650dc32f49bf2e (patch)
tree87ee0384812f00b08961ff4af1d4379ff5fbb6aa
parent437606ac2dc3376512191b0fa0c5e39c590f007b (diff)
qcacld-3.0: Add scenario based BUG report
qcacld-2.0 to qcacld-3.0 propagation Change to initiate BUG report in case of fatal event Add INI support to Enable/Disable it. The fatal event handled are as below: - Roaming failed after successful preauth. - SME command timeout. - PE defer queue is full. - CDS run out of message wrapper. - HDD level wait for event timeout. CRs-Fixed: 912560 Change-Id: I64dff8b7d0836340ce3bec5f5985d1919b600c23
-rw-r--r--core/cds/inc/cds_api.h17
-rw-r--r--core/cds/inc/cds_sched.h3
-rw-r--r--core/cds/src/cds_api.c145
-rw-r--r--core/hdd/inc/wlan_hdd_cfg.h10
-rw-r--r--core/hdd/src/wlan_hdd_cfg.c14
-rw-r--r--core/hdd/src/wlan_hdd_cfg80211.c3
-rw-r--r--core/hdd/src/wlan_hdd_main.c2
-rw-r--r--core/hdd/src/wlan_hdd_p2p.c8
-rw-r--r--core/hdd/src/wlan_hdd_tdls.c6
-rw-r--r--core/mac/inc/ani_global.h26
-rw-r--r--core/mac/src/pe/lim/lim_utils.c4
-rw-r--r--core/sme/inc/csr_api.h1
-rw-r--r--core/sme/inc/csr_internal.h1
-rw-r--r--core/sme/src/common/sme_api.c54
-rw-r--r--core/sme/src/csr/csr_api_roam.c8
-rw-r--r--core/utils/logging/inc/wlan_logging_sock_svc.h5
-rw-r--r--core/utils/logging/src/wlan_logging_sock_svc.c46
-rw-r--r--core/wma/src/wma_main.c2
18 files changed, 306 insertions, 49 deletions
diff --git a/core/cds/inc/cds_api.h b/core/cds/inc/cds_api.h
index e60ae4fd52a0..5b85fa1b0a48 100644
--- a/core/cds/inc/cds_api.h
+++ b/core/cds/inc/cds_api.h
@@ -231,16 +231,25 @@ void cds_set_multicast_logging(uint8_t value);
uint8_t cds_is_multicast_logging(void);
QDF_STATUS cds_set_log_completion(uint32_t is_fatal,
uint32_t type,
- uint32_t sub_type);
-void cds_get_log_completion(uint32_t *is_fatal,
+ uint32_t sub_type,
+ bool recovery_needed);
+void cds_get_and_reset_log_completion(uint32_t *is_fatal,
uint32_t *type,
- uint32_t *sub_type);
+ uint32_t *sub_type,
+ bool *recovery_needed);
bool cds_is_log_report_in_progress(void);
+bool cds_is_fatal_event_enabled(void);
+uint32_t cds_get_log_indicator(void);
+void cds_set_fatal_event(bool value);
+void cds_wlan_flush_host_logs_for_fatal(void);
+
void cds_init_log_completion(void);
void cds_deinit_log_completion(void);
QDF_STATUS cds_flush_logs(uint32_t is_fatal,
uint32_t indicator,
- uint32_t reason_code);
+ uint32_t reason_code,
+ bool dump_mac_trace,
+ bool recovery_needed);
void cds_logging_set_fw_flush_complete(void);
#ifdef FEATURE_WLAN_DIAG_SUPPORT
diff --git a/core/cds/inc/cds_sched.h b/core/cds/inc/cds_sched.h
index 4a26355e580b..cc082411e125 100644
--- a/core/cds/inc/cds_sched.h
+++ b/core/cds/inc/cds_sched.h
@@ -209,6 +209,7 @@ typedef struct _cds_sched_context {
* @indicator: Source of bug report
* @reason_code: Reason code for bug report
* @is_report_in_progress: If bug report is in progress
+ * @recovery_needed: if recovery is needed after report completion
*
* This structure internally stores the log related params
*/
@@ -217,6 +218,7 @@ struct cds_log_complete {
uint32_t indicator;
uint32_t reason_code;
bool is_report_in_progress;
+ bool recovery_needed;
};
/*
@@ -292,6 +294,7 @@ typedef struct _cds_context_type {
void (*sap_restart_chan_switch_cb)(void *, uint32_t, uint32_t);
#endif
bool do_hw_mode_change;
+ bool enable_fatal_event;
} cds_context_type, *p_cds_contextType;
/*---------------------------------------------------------------------------
diff --git a/core/cds/src/cds_api.c b/core/cds/src/cds_api.c
index 8fe325c92ae5..684bdb5dae29 100644
--- a/core/cds/src/cds_api.c
+++ b/core/cds/src/cds_api.c
@@ -1344,11 +1344,15 @@ QDF_STATUS cds_mq_post_message(CDS_MQ_ID msgQueueId, cds_msg_t *pMsg)
if (NULL == pMsgWrapper) {
debug_count = atomic_inc_return(&cds_wrapper_empty_count);
- if (1 == debug_count)
+ if (1 == debug_count) {
QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
"%s: CDS Core run out of message wrapper %d",
__func__, debug_count);
-
+ cds_flush_logs(WLAN_LOG_TYPE_FATAL,
+ WLAN_LOG_INDICATOR_HOST_ONLY,
+ WLAN_LOG_REASON_VOS_MSG_UNDER_RUN,
+ true, false);
+ }
if (CDS_WRAPPER_MAX_FAIL_COUNT == debug_count)
QDF_BUG(0);
@@ -1921,6 +1925,7 @@ void cds_deinit_log_completion(void)
* @is_fatal: Indicates if the event triggering bug report is fatal or not
* @indicator: Source which trigerred the bug report
* @reason_code: Reason for triggering bug report
+ * @recovery_needed: If recovery is needed after bug report
*
* This function is used to set the logging parameters based on the
* caller
@@ -1929,7 +1934,8 @@ void cds_deinit_log_completion(void)
*/
QDF_STATUS cds_set_log_completion(uint32_t is_fatal,
uint32_t indicator,
- uint32_t reason_code)
+ uint32_t reason_code,
+ bool recovery_needed)
{
p_cds_contextType p_cds_context;
@@ -1944,24 +1950,27 @@ QDF_STATUS cds_set_log_completion(uint32_t is_fatal,
p_cds_context->log_complete.is_fatal = is_fatal;
p_cds_context->log_complete.indicator = indicator;
p_cds_context->log_complete.reason_code = reason_code;
+ p_cds_context->log_complete.recovery_needed = recovery_needed;
p_cds_context->log_complete.is_report_in_progress = true;
qdf_spinlock_release(&p_cds_context->bug_report_lock);
return QDF_STATUS_SUCCESS;
}
/**
- * cds_get_log_completion() - Get the logging related params
+ * cds_get_and_reset_log_completion() - Get and reset logging related params
* @is_fatal: Indicates if the event triggering bug report is fatal or not
* @indicator: Source which trigerred the bug report
* @reason_code: Reason for triggering bug report
+ * @recovery_needed: If recovery is needed after bug report
*
* This function is used to get the logging related parameters
*
* Return: None
*/
-void cds_get_log_completion(uint32_t *is_fatal,
+void cds_get_and_reset_log_completion(uint32_t *is_fatal,
uint32_t *indicator,
- uint32_t *reason_code)
+ uint32_t *reason_code,
+ bool *recovery_needed)
{
p_cds_contextType p_cds_context;
@@ -1976,7 +1985,14 @@ void cds_get_log_completion(uint32_t *is_fatal,
*is_fatal = p_cds_context->log_complete.is_fatal;
*indicator = p_cds_context->log_complete.indicator;
*reason_code = p_cds_context->log_complete.reason_code;
+ *recovery_needed = p_cds_context->log_complete.recovery_needed;
+
+ /* reset */
+ p_cds_context->log_complete.indicator = WLAN_LOG_INDICATOR_UNUSED;
+ p_cds_context->log_complete.is_fatal = WLAN_LOG_TYPE_NON_FATAL;
p_cds_context->log_complete.is_report_in_progress = false;
+ p_cds_context->log_complete.reason_code = WLAN_LOG_REASON_CODE_UNUSED;
+ p_cds_context->log_complete.recovery_needed = false;
qdf_spinlock_release(&p_cds_context->bug_report_lock);
}
@@ -2001,10 +2017,79 @@ bool cds_is_log_report_in_progress(void)
}
/**
+ * cds_is_fatal_event_enabled() - Return if fatal event is enabled
+ *
+ * Return true if fatal event is enabled.
+ */
+bool cds_is_fatal_event_enabled(void)
+{
+ p_cds_contextType p_cds_context;
+
+ p_cds_context = cds_get_global_context();
+ if (!p_cds_context) {
+ QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
+ "%s: cds context is Invalid", __func__);
+ return false;
+ }
+
+
+ return p_cds_context->enable_fatal_event;
+}
+
+/**
+ * cds_get_log_indicator() - Get the log flush indicator
+ *
+ * This function is used to get the log flush indicator
+ *
+ * Return: log indicator
+ */
+uint32_t cds_get_log_indicator(void)
+{
+ p_cds_contextType p_cds_context;
+ uint32_t indicator;
+
+ p_cds_context = cds_get_global_context();
+ if (!p_cds_context) {
+ QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
+ "%s: cds context is Invalid", __func__);
+ return WLAN_LOG_INDICATOR_UNUSED;
+ }
+
+ if (cds_is_load_or_unload_in_progress() ||
+ cds_is_driver_recovering()) {
+ QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
+ "%s: vos context initialization is in progress"
+ , __func__);
+ return WLAN_LOG_INDICATOR_UNUSED;
+ }
+
+ qdf_spinlock_acquire(&p_cds_context->bug_report_lock);
+ indicator = p_cds_context->log_complete.indicator;
+ qdf_spinlock_release(&p_cds_context->bug_report_lock);
+ return indicator;
+}
+
+/**
+ * cds_wlan_flush_host_logs_for_fatal() - Wrapper to flush host logs
+ *
+ * This function is used to send signal to the logger thread to
+ * flush the host logs.
+ *
+ * Return: None
+ *
+ */
+void cds_wlan_flush_host_logs_for_fatal(void)
+{
+ wlan_flush_host_logs_for_fatal();
+}
+
+/**
* cds_flush_logs() - Report fatal event to userspace
* @is_fatal: Indicates if the event triggering bug report is fatal or not
* @indicator: Source which trigerred the bug report
* @reason_code: Reason for triggering bug report
+ * @dump_mac_trace: If mac trace are needed in logs.
+ * @recovery_needed: If recovery is needed after bug report
*
* This function sets the log related params and send the WMI command to the
* FW to flush its logs. On receiving the flush completion event from the FW
@@ -2014,7 +2099,9 @@ bool cds_is_log_report_in_progress(void)
*/
QDF_STATUS cds_flush_logs(uint32_t is_fatal,
uint32_t indicator,
- uint32_t reason_code)
+ uint32_t reason_code,
+ bool dump_mac_trace,
+ bool recovery_needed)
{
uint32_t ret;
QDF_STATUS status;
@@ -2027,6 +2114,17 @@ QDF_STATUS cds_flush_logs(uint32_t is_fatal,
"%s: cds context is Invalid", __func__);
return QDF_STATUS_E_FAILURE;
}
+ if (!p_cds_context->enable_fatal_event) {
+ QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
+ "%s: Fatal event not enabled", __func__);
+ return QDF_STATUS_E_FAILURE;
+ }
+ if (cds_is_load_or_unload_in_progress() ||
+ cds_is_driver_recovering()) {
+ QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
+ "%s: un/Load/SSR in progress", __func__);
+ return QDF_STATUS_E_FAILURE;
+ }
if (cds_is_log_report_in_progress() == true) {
QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
@@ -2035,17 +2133,26 @@ QDF_STATUS cds_flush_logs(uint32_t is_fatal,
return QDF_STATUS_E_FAILURE;
}
- status = cds_set_log_completion(is_fatal, indicator, reason_code);
+ status = cds_set_log_completion(is_fatal, indicator,
+ reason_code, recovery_needed);
if (QDF_STATUS_SUCCESS != status) {
QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
"%s: Failed to set log trigger params", __func__);
return QDF_STATUS_E_FAILURE;
}
- QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_INFO,
+ QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
"%s: Triggering bug report: type:%d, indicator=%d reason_code=%d",
__func__, is_fatal, indicator, reason_code);
+ if (dump_mac_trace)
+ qdf_trace_dump_all(p_cds_context->pMACContext, 0, 0, 500, 0);
+
+ if (WLAN_LOG_INDICATOR_HOST_ONLY == indicator) {
+ cds_wlan_flush_host_logs_for_fatal();
+ return QDF_STATUS_SUCCESS;
+ }
+
ret = sme_send_flush_logs_cmd_to_fw(p_cds_context->pMACContext);
if (0 != ret) {
QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
@@ -2070,3 +2177,23 @@ void cds_logging_set_fw_flush_complete(void)
{
wlan_logging_set_fw_flush_complete();
}
+
+/**
+ * cds_set_fatal_event() - set fatal event status
+ * @value: pending statue to set
+ *
+ * Return: None
+ */
+void cds_set_fatal_event(bool value)
+{
+ p_cds_contextType p_cds_context;
+
+ p_cds_context = cds_get_global_context();
+ if (!p_cds_context) {
+ QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
+ "%s: cds context is Invalid", __func__);
+ return;
+ }
+ p_cds_context->enable_fatal_event = value;
+}
+
diff --git a/core/hdd/inc/wlan_hdd_cfg.h b/core/hdd/inc/wlan_hdd_cfg.h
index 70d4ad63095f..fd581b48f628 100644
--- a/core/hdd/inc/wlan_hdd_cfg.h
+++ b/core/hdd/inc/wlan_hdd_cfg.h
@@ -2995,6 +2995,15 @@ enum dot11p_mode {
#define CFG_ROAM_DENSE_MIN_APS_MAX (5)
#define CFG_ROAM_DENSE_MIN_APS_DEFAULT (1)
+/*
+ * Enable/Disable to initiate BUG report in case of fatal event
+ * Default: Enable
+ */
+#define CFG_ENABLE_FATAL_EVENT_TRIGGER "gEnableFatalEvent"
+#define CFG_ENABLE_FATAL_EVENT_TRIGGER_MIN (0)
+#define CFG_ENABLE_FATAL_EVENT_TRIGGER_MAX (1)
+#define CFG_ENABLE_FATAL_EVENT_TRIGGER_DEFAULT (1)
+
/*---------------------------------------------------------------------------
Type declarations
-------------------------------------------------------------------------*/
@@ -3595,6 +3604,7 @@ struct hdd_config {
uint32_t roam_dense_rssi_thresh_offset;
bool ignore_peer_ht_opmode;
uint32_t roam_dense_min_aps;
+ bool enable_fatal_event;
};
#define VAR_OFFSET(_Struct, _Var) (offsetof(_Struct, _Var))
diff --git a/core/hdd/src/wlan_hdd_cfg.c b/core/hdd/src/wlan_hdd_cfg.c
index 5bbae4c696c1..23513f5677c5 100644
--- a/core/hdd/src/wlan_hdd_cfg.c
+++ b/core/hdd/src/wlan_hdd_cfg.c
@@ -3772,6 +3772,15 @@ REG_TABLE_ENTRY g_registry_table[] = {
CFG_ROAM_DENSE_MIN_APS_MIN,
CFG_ROAM_DENSE_MIN_APS_MAX),
+ REG_VARIABLE(CFG_ENABLE_FATAL_EVENT_TRIGGER, WLAN_PARAM_Integer,
+ struct hdd_config, enable_fatal_event,
+ VAR_FLAGS_OPTIONAL |
+ VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+ CFG_ENABLE_FATAL_EVENT_TRIGGER_DEFAULT,
+ CFG_ENABLE_FATAL_EVENT_TRIGGER_MIN,
+ CFG_ENABLE_FATAL_EVENT_TRIGGER_MAX),
+
+
};
@@ -5363,6 +5372,9 @@ void hdd_cfg_print(hdd_context_t *pHddCtx)
CFG_IGNORE_PEER_HT_MODE_NAME,
pHddCtx->config->ignore_peer_ht_opmode);
hdd_info("Name = [%s] Value = [%u]",
+ CFG_ENABLE_FATAL_EVENT_TRIGGER,
+ pHddCtx->config->enable_fatal_event);
+ hdd_info("Name = [%s] Value = [%u]",
CFG_ROAM_DENSE_MIN_APS,
pHddCtx->config->roam_dense_min_aps);
}
@@ -6808,6 +6820,8 @@ QDF_STATUS hdd_set_sme_config(hdd_context_t *pHddCtx)
pHddCtx->config->obss_passive_dwelltime;
smeConfig->csrConfig.ignore_peer_ht_opmode =
pConfig->ignore_peer_ht_opmode;
+ smeConfig->csrConfig.enable_fatal_event =
+ pConfig->enable_fatal_event;
status = sme_update_config(pHddCtx->hHal, smeConfig);
if (!QDF_IS_STATUS_SUCCESS(status)) {
diff --git a/core/hdd/src/wlan_hdd_cfg80211.c b/core/hdd/src/wlan_hdd_cfg80211.c
index c8af93844f02..cc8427103cba 100644
--- a/core/hdd/src/wlan_hdd_cfg80211.c
+++ b/core/hdd/src/wlan_hdd_cfg80211.c
@@ -3563,7 +3563,8 @@ static int __wlan_hdd_cfg80211_wifi_logger_get_ring_data(struct wiphy *wiphy,
status = cds_flush_logs(WLAN_LOG_TYPE_NON_FATAL,
WLAN_LOG_INDICATOR_FRAMEWORK,
- WLAN_LOG_REASON_CODE_UNUSED);
+ WLAN_LOG_REASON_CODE_UNUSED,
+ true, false);
if (QDF_STATUS_SUCCESS != status) {
hddLog(LOGE, FL("Failed to trigger bug report"));
return -EINVAL;
diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c
index 6722d4677832..552f7c9e04f2 100644
--- a/core/hdd/src/wlan_hdd_main.c
+++ b/core/hdd/src/wlan_hdd_main.c
@@ -5355,6 +5355,8 @@ hdd_context_t *hdd_init_context(struct device *dev, void *hif_sc)
hdd_notice("Setting configuredMcastBcastFilter: %d",
hdd_ctx->config->mcastBcastFilterSetting);
+ cds_set_fatal_event(hdd_ctx->config->enable_fatal_event);
+
hdd_override_ini_config(hdd_ctx);
ret = wlan_hdd_cfg80211_init(dev, hdd_ctx->wiphy, hdd_ctx->config);
diff --git a/core/hdd/src/wlan_hdd_p2p.c b/core/hdd/src/wlan_hdd_p2p.c
index 24f572a0e980..ebdb11f0bfc1 100644
--- a/core/hdd/src/wlan_hdd_p2p.c
+++ b/core/hdd/src/wlan_hdd_p2p.c
@@ -319,6 +319,10 @@ void wlan_hdd_cancel_existing_remain_on_channel(hdd_adapter_t *pAdapter)
hddLog(LOGE,
"%s: timeout waiting for remain on channel ready indication",
__func__);
+ cds_flush_logs(WLAN_LOG_TYPE_FATAL,
+ WLAN_LOG_INDICATOR_HOST_DRIVER,
+ WLAN_LOG_REASON_HDD_TIME_OUT,
+ true, false);
}
INIT_COMPLETION(pAdapter->cancel_rem_on_chan_var);
@@ -1171,6 +1175,10 @@ int __wlan_hdd_cfg80211_cancel_remain_on_channel(struct wiphy *wiphy,
cds_get_driver_state());
return -EAGAIN;
}
+ cds_flush_logs(WLAN_LOG_TYPE_FATAL,
+ WLAN_LOG_INDICATOR_HOST_DRIVER,
+ WLAN_LOG_REASON_HDD_TIME_OUT,
+ true, false);
}
INIT_COMPLETION(pAdapter->cancel_rem_on_chan_var);
/* Issue abort remain on chan request to sme.
diff --git a/core/hdd/src/wlan_hdd_tdls.c b/core/hdd/src/wlan_hdd_tdls.c
index 878bf0f05947..afc1fd62e4c1 100644
--- a/core/hdd/src/wlan_hdd_tdls.c
+++ b/core/hdd/src/wlan_hdd_tdls.c
@@ -3983,7 +3983,11 @@ static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
cds_get_driver_state());
return -EAGAIN;
}
-
+ if (rc <= 0)
+ cds_flush_logs(WLAN_LOG_TYPE_FATAL,
+ WLAN_LOG_INDICATOR_HOST_DRIVER,
+ WLAN_LOG_REASON_HDD_TIME_OUT,
+ true, false);
pAdapter->mgmtTxCompletionStatus = false;
return -EINVAL;
}
diff --git a/core/mac/inc/ani_global.h b/core/mac/inc/ani_global.h
index 8f68465306b0..05430a9bb978 100644
--- a/core/mac/inc/ani_global.h
+++ b/core/mac/inc/ani_global.h
@@ -131,6 +131,7 @@ enum log_event_type {
* @WLAN_LOG_INDICATOR_FRAMEWORK: Framework triggers bug report
* @WLAN_LOG_INDICATOR_HOST_DRIVER: Host driver triggers bug report
* @WLAN_LOG_INDICATOR_FIRMWARE: FW initiates bug report
+ * @WLAN_LOG_INDICATOR_HOST_ONLY: Host triggers fatal event bug report
*
* Enum indicating the module that triggered the bug report
*/
@@ -139,52 +140,39 @@ enum log_event_indicator {
WLAN_LOG_INDICATOR_FRAMEWORK,
WLAN_LOG_INDICATOR_HOST_DRIVER,
WLAN_LOG_INDICATOR_FIRMWARE,
+ WLAN_LOG_INDICATOR_HOST_ONLY,
};
/**
* enum log_event_host_reason_code - Reason code for bug report
* @WLAN_LOG_REASON_CODE_UNUSED: Unused
- * @WLAN_LOG_REASON_COMMAND_UNSUCCESSFUL: Command response status from FW
- * is error
* @WLAN_LOG_REASON_ROAM_FAIL: Driver initiated roam has failed
- * @WLAN_LOG_REASON_THREAD_STUCK: Monitor Health of host threads and report
- * fatal event if some thread is stuck
* @WLAN_LOG_REASON_DATA_STALL: Unable to send/receive data due to low resource
* scenario for a prolonged period
* @WLAN_LOG_REASON_SME_COMMAND_STUCK: SME command is stuck in SME active queue
- * @WLAN_LOG_REASON_ZERO_SCAN_RESULTS: Full scan resulted in zero scan results
* @WLAN_LOG_REASON_QUEUE_FULL: Defer queue becomes full for a prolonged period
* @WLAN_LOG_REASON_POWER_COLLAPSE_FAIL: Unable to allow apps power collapse
* for a prolonged period
- * @WLAN_LOG_REASON_SSR_FAIL: Unable to gracefully complete SSR
- * @WLAN_LOG_REASON_DISCONNECT_FAIL: Disconnect from Supplicant is not
- * successful
- * @WLAN_LOG_REASON_CLEAN_UP_FAIL: Clean up of TDLS or Pre-Auth Sessions
- * not successful
* @WLAN_LOG_REASON_MALLOC_FAIL: Memory allocation Fails
* @WLAN_LOG_REASON_VOS_MSG_UNDER_RUN: VOS Core runs out of message wrapper
- * @WLAN_LOG_REASON_MSG_POST_FAIL: Unable to post msg
- *
+ * @WLAN_LOG_REASON_HDD_TIME_OUT: Wait for event Timeout in HDD layer
+ @WLAN_LOG_REASON_SME_OUT_OF_CMD_BUFL sme out of cmd buffer
* This enum contains the different reason codes for bug report
*/
enum log_event_host_reason_code {
WLAN_LOG_REASON_CODE_UNUSED,
- WLAN_LOG_REASON_COMMAND_UNSUCCESSFUL,
WLAN_LOG_REASON_ROAM_FAIL,
- WLAN_LOG_REASON_THREAD_STUCK,
WLAN_LOG_REASON_DATA_STALL,
WLAN_LOG_REASON_SME_COMMAND_STUCK,
- WLAN_LOG_REASON_ZERO_SCAN_RESULTS,
WLAN_LOG_REASON_QUEUE_FULL,
WLAN_LOG_REASON_POWER_COLLAPSE_FAIL,
- WLAN_LOG_REASON_SSR_FAIL,
- WLAN_LOG_REASON_DISCONNECT_FAIL,
- WLAN_LOG_REASON_CLEAN_UP_FAIL,
WLAN_LOG_REASON_MALLOC_FAIL,
WLAN_LOG_REASON_VOS_MSG_UNDER_RUN,
- WLAN_LOG_REASON_MSG_POST_FAIL,
+ WLAN_LOG_REASON_HDD_TIME_OUT,
+ WLAN_LOG_REASON_SME_OUT_OF_CMD_BUF,
};
+
/**
* enum userspace_log_level - Log level at userspace
* @LOG_LEVEL_NO_COLLECTION: verbose_level 0 corresponds to no collection
diff --git a/core/mac/src/pe/lim/lim_utils.c b/core/mac/src/pe/lim/lim_utils.c
index 45265686cd83..3dbf1ff563e0 100644
--- a/core/mac/src/pe/lim/lim_utils.c
+++ b/core/mac/src/pe/lim/lim_utils.c
@@ -868,6 +868,10 @@ uint8_t lim_write_deferred_msg_q(tpAniSirGlobal mac_ctx, tpSirMsgQ lim_msg)
FL("queue->MsgQ full Msg:%d Msgs Failed:%d"),
lim_msg->type,
++mac_ctx->lim.deferredMsgCnt);
+ cds_flush_logs(WLAN_LOG_TYPE_NON_FATAL,
+ WLAN_LOG_INDICATOR_HOST_DRIVER,
+ WLAN_LOG_REASON_QUEUE_FULL,
+ true, false);
} else {
mac_ctx->lim.deferredMsgCnt++;
}
diff --git a/core/sme/inc/csr_api.h b/core/sme/inc/csr_api.h
index dd566f26ed17..3071a777c1c7 100644
--- a/core/sme/inc/csr_api.h
+++ b/core/sme/inc/csr_api.h
@@ -1221,6 +1221,7 @@ typedef struct tagCsrConfigParam {
uint32_t obss_active_dwelltime;
uint32_t obss_passive_dwelltime;
bool ignore_peer_ht_opmode;
+ bool enable_fatal_event;
} tCsrConfigParam;
/* Tush */
diff --git a/core/sme/inc/csr_internal.h b/core/sme/inc/csr_internal.h
index 15ce478fd687..4ed2c5597b42 100644
--- a/core/sme/inc/csr_internal.h
+++ b/core/sme/inc/csr_internal.h
@@ -639,6 +639,7 @@ typedef struct tagCsrConfig {
uint32_t obss_active_dwelltime;
uint32_t obss_passive_dwelltime;
bool ignore_peer_ht_opmode;
+ bool enable_fatal_event;
} tCsrConfig;
typedef struct tagCsrChannelPowerInfo {
diff --git a/core/sme/src/common/sme_api.c b/core/sme/src/common/sme_api.c
index 06ba472c1d42..c691401bebee 100644
--- a/core/sme/src/common/sme_api.c
+++ b/core/sme/src/common/sme_api.c
@@ -621,8 +621,16 @@ tSmeCmd *sme_get_command_buffer(tpAniSirGlobal pMac)
sme_command_queue_full++;
csr_ll_unlock(&pMac->roam.roamCmdPendingList);
- /* panic with out-of-command */
- QDF_BUG(0);
+ if (pMac->roam.configParam.enable_fatal_event)
+ cds_flush_logs(WLAN_LOG_TYPE_FATAL,
+ WLAN_LOG_INDICATOR_HOST_DRIVER,
+ WLAN_LOG_REASON_SME_OUT_OF_CMD_BUF,
+ false,
+ pMac->sme.enableSelfRecovery ? true : false);
+ else if (pMac->sme.enableSelfRecovery)
+ cds_trigger_recovery();
+ else
+ QDF_BUG(0);
}
/* memset to zero */
@@ -11682,19 +11690,41 @@ void sme_save_active_cmd_stats(tHalHandle hHal)
void active_list_cmd_timeout_handle(void *userData)
{
- if (NULL == userData)
- return;
- QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
- "%s: Active List command timeout Cmd List Count %d", __func__,
- csr_ll_count(&((tpAniSirGlobal) userData)->sme.
- smeCmdActiveList));
- sme_get_command_q_status((tHalHandle) userData);
+ tHalHandle hal = (tHalHandle)userData;
+ tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
- if (((tpAniSirGlobal) userData)->sme.enableSelfRecovery) {
- sme_save_active_cmd_stats((tHalHandle) userData);
+ if (NULL == mac_ctx) {
+ QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+ "%s: mac_ctx is null", __func__);
+ return;
+ }
+ /* Return if no cmd pending in active list as
+ * in this case we should not be here.
+ */
+ if (0 == csr_ll_count(&mac_ctx->sme.smeCmdActiveList))
+ return;
+ sms_log(mac_ctx, LOGE,
+ FL("Active List command timeout Cmd List Count %d"),
+ csr_ll_count(&mac_ctx->sme.smeCmdActiveList));
+ sme_get_command_q_status(hal);
+
+ if (mac_ctx->roam.configParam.enable_fatal_event)
+ cds_flush_logs(WLAN_LOG_TYPE_FATAL,
+ WLAN_LOG_INDICATOR_HOST_DRIVER,
+ WLAN_LOG_REASON_SME_COMMAND_STUCK,
+ false,
+ mac_ctx->sme.enableSelfRecovery ? true : false);
+ else
+ qdf_trace_dump_all(mac_ctx, 0, 0, 500, 0);
+
+ if (mac_ctx->sme.enableSelfRecovery) {
+ sme_save_active_cmd_stats(hal);
cds_trigger_recovery();
} else {
- QDF_BUG(0);
+ if (!mac_ctx->roam.configParam.enable_fatal_event &&
+ !(cds_is_load_or_unload_in_progress() ||
+ cds_is_driver_recovering()))
+ QDF_BUG(0);
}
}
diff --git a/core/sme/src/csr/csr_api_roam.c b/core/sme/src/csr/csr_api_roam.c
index 342ff292a210..d0b29e2129a8 100644
--- a/core/sme/src/csr/csr_api_roam.c
+++ b/core/sme/src/csr/csr_api_roam.c
@@ -2353,6 +2353,8 @@ QDF_STATUS csr_change_default_config_param(tpAniSirGlobal pMac,
pParam->early_stop_scan_min_threshold;
pMac->roam.configParam.early_stop_scan_max_threshold =
pParam->early_stop_scan_max_threshold;
+ pMac->roam.configParam.enable_fatal_event =
+ pParam->enable_fatal_event;
}
return status;
@@ -2536,6 +2538,8 @@ QDF_STATUS csr_get_config_param(tpAniSirGlobal pMac, tCsrConfigParam *pParam)
pParam->enableHtSmps = pMac->roam.configParam.enableHtSmps;
pParam->htSmps = pMac->roam.configParam.htSmps;
pParam->send_smps_action = pMac->roam.configParam.send_smps_action;
+ pParam->enable_fatal_event =
+ pMac->roam.configParam.enable_fatal_event;
return QDF_STATUS_SUCCESS;
}
@@ -8672,6 +8676,10 @@ static void csr_roam_roaming_state_reassoc_rsp_processor(tpAniSirGlobal pMac,
"CSR SmeReassocReq failed with statusCode= 0x%08X [%d]",
pSmeJoinRsp->statusCode, pSmeJoinRsp->statusCode);
result = eCsrReassocFailure;
+ cds_flush_logs(WLAN_LOG_TYPE_FATAL,
+ WLAN_LOG_INDICATOR_HOST_DRIVER,
+ WLAN_LOG_REASON_ROAM_FAIL,
+ true, false);
if ((eSIR_SME_FT_REASSOC_TIMEOUT_FAILURE ==
pSmeJoinRsp->statusCode)
|| (eSIR_SME_FT_REASSOC_FAILURE ==
diff --git a/core/utils/logging/inc/wlan_logging_sock_svc.h b/core/utils/logging/inc/wlan_logging_sock_svc.h
index 1850a0138466..d0b76d1aed9a 100644
--- a/core/utils/logging/inc/wlan_logging_sock_svc.h
+++ b/core/utils/logging/inc/wlan_logging_sock_svc.h
@@ -46,6 +46,7 @@ int wlan_log_to_user(QDF_TRACE_LEVEL log_level, char *to_be_sent, int length);
void wlan_logging_set_per_pkt_stats(void);
void wlan_logging_set_log_level(void);
void wlan_logging_set_fw_flush_complete(void);
+void wlan_flush_host_logs_for_fatal(void);
#ifdef FEATURE_WLAN_DIAG_SUPPORT
void wlan_report_log_completion(uint32_t is_fatal,
uint32_t indicator,
@@ -57,5 +58,9 @@ static inline void wlan_report_log_completion(uint32_t is_fatal,
{
return;
}
+static inline void wlan_flush_host_logs_for_fatal(void)
+{
+}
+
#endif /* FEATURE_WLAN_DIAG_SUPPORT */
#endif /* WLAN_LOGGING_SOCK_SVC_H */
diff --git a/core/utils/logging/src/wlan_logging_sock_svc.c b/core/utils/logging/src/wlan_logging_sock_svc.c
index 15687a2f7e15..c0c854f05bd4 100644
--- a/core/utils/logging/src/wlan_logging_sock_svc.c
+++ b/core/utils/logging/src/wlan_logging_sock_svc.c
@@ -39,6 +39,7 @@
#include <wlan_ptt_sock_svc.h>
#include "pktlog_ac.h"
#include <host_diag_core_event.h>
+#include "cds_utils.h"
#define LOGGING_TRACE(level, args ...) \
QDF_TRACE(QDF_MODULE_ID_HDD, level, ## args)
@@ -505,14 +506,19 @@ void wlan_report_log_completion(uint32_t is_fatal,
void send_flush_completion_to_user(void)
{
uint32_t is_fatal, indicator, reason_code;
+ bool recovery_needed;
- cds_get_log_completion(&is_fatal, &indicator, &reason_code);
+ cds_get_and_reset_log_completion(&is_fatal,
+ &indicator, &reason_code, &recovery_needed);
/* Error on purpose, so that it will get logged in the kmsg */
LOGGING_TRACE(QDF_TRACE_LEVEL_ERROR,
"%s: Sending flush done to userspace", __func__);
wlan_report_log_completion(is_fatal, indicator, reason_code);
+
+ if (recovery_needed)
+ cds_trigger_recovery();
}
/**
@@ -525,6 +531,7 @@ static int wlan_logging_thread(void *Arg)
{
int ret_wait_status = 0;
int ret = 0;
+ unsigned long flags;
set_user_nice(current, -2);
@@ -561,6 +568,10 @@ static int wlan_logging_thread(void *Arg)
ret = send_filled_buffers_to_user();
if (-ENOMEM == ret)
msleep(200);
+ if (WLAN_LOG_INDICATOR_HOST_ONLY ==
+ cds_get_log_indicator()) {
+ send_flush_completion_to_user();
+ }
}
if (test_and_clear_bit(HOST_LOG_PER_PKT_STATS,
@@ -582,6 +593,12 @@ static int wlan_logging_thread(void *Arg)
send_flush_completion_to_user();
} else {
gwlan_logging.is_flush_complete = true;
+ /* Flush all current host logs*/
+ spin_lock_irqsave(&gwlan_logging.spin_lock,
+ flags);
+ wlan_queue_logmsg_for_app();
+ spin_unlock_irqrestore(&gwlan_logging.spin_lock,
+ flags);
set_bit(HOST_LOG_DRIVER_MSG,
&gwlan_logging.eventFlag);
set_bit(HOST_LOG_PER_PKT_STATS,
@@ -804,10 +821,35 @@ void wlan_logging_set_log_level(void)
*/
void wlan_logging_set_fw_flush_complete(void)
{
- if (gwlan_logging.is_active == false)
+ if (gwlan_logging.is_active == false ||
+ !cds_is_fatal_event_enabled())
return;
set_bit(HOST_LOG_FW_FLUSH_COMPLETE, &gwlan_logging.eventFlag);
wake_up_interruptible(&gwlan_logging.wait_queue);
}
+
+/**
+ * wlan_flush_host_logs_for_fatal() - Flush host logs
+ *
+ * This function is used to send signal to the logger thread to
+ * Flush the host logs
+ *
+ * Return: None
+ */
+void wlan_flush_host_logs_for_fatal(void)
+{
+ unsigned long flags;
+
+ if (cds_is_log_report_in_progress()) {
+ pr_info("%s:flush all host logs Setting HOST_LOG_POST_MASK\n",
+ __func__);
+ spin_lock_irqsave(&gwlan_logging.spin_lock, flags);
+ wlan_queue_logmsg_for_app();
+ spin_unlock_irqrestore(&gwlan_logging.spin_lock, flags);
+ set_bit(HOST_LOG_DRIVER_MSG, &gwlan_logging.eventFlag);
+ wake_up_interruptible(&gwlan_logging.wait_queue);
+ }
+}
+
#endif /* WLAN_LOGGING_SOCK_SVC_ENABLE */
diff --git a/core/wma/src/wma_main.c b/core/wma/src/wma_main.c
index d679a6f9b0e1..d068183616bf 100644
--- a/core/wma/src/wma_main.c
+++ b/core/wma/src/wma_main.c
@@ -2269,7 +2269,7 @@ static int wma_flush_complete_evt_handler(void *handle,
reason_code);
status = cds_set_log_completion(WLAN_LOG_TYPE_FATAL,
WLAN_LOG_INDICATOR_FIRMWARE,
- reason_code);
+ reason_code, false);
if (QDF_STATUS_SUCCESS != status) {
WMA_LOGE("%s: Failed to set log trigger params",
__func__);