wlan: Handle fatal event triggered from framework and FW
Currently driver supports the fatal event triggered using ioctl.
Support is added for framework and FW triggered fatal events
Change-Id: I52acc8f85495b75807c72e0c5279701e38326c58
CRs-Fixed: 912066
diff --git a/CORE/HDD/inc/wlan_hdd_cfg80211.h b/CORE/HDD/inc/wlan_hdd_cfg80211.h
index 79c54f9..abbabe6 100644
--- a/CORE/HDD/inc/wlan_hdd_cfg80211.h
+++ b/CORE/HDD/inc/wlan_hdd_cfg80211.h
@@ -175,6 +175,8 @@
QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SSID_HOTLIST = 66,
QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_FOUND = 67,
QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_LOST = 68,
+ QCA_NL80211_VENDOR_SUBCMD_GET_RING_DATA = 77,
+
QCA_NL80211_VENDOR_SUBCMD_SETBAND = 105,
};
@@ -1082,6 +1084,21 @@
QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX =
QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_AFTER_LAST - 1,
};
+/*
+ * enum qca_wlan_vendor_attr_wifi_logger_get_ring_data - Get ring data
+ * @QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_INVALID: Invalid attribute
+ * @QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID: Ring ID
+ * @QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_AFTER_LAST: Last value
+ * @QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX: Max value
+ */
+enum qca_wlan_vendor_attr_wifi_logger_get_ring_data {
+ QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_INVALID = 0,
+ QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID = 1,
+ /* keep last */
+ QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_AFTER_LAST,
+ QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX =
+ QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_AFTER_LAST - 1,
+};
/* Vendor id to be used in vendor specific command and events
diff --git a/CORE/HDD/src/wlan_hdd_cfg80211.c b/CORE/HDD/src/wlan_hdd_cfg80211.c
index 5e4b849..85a58cc 100644
--- a/CORE/HDD/src/wlan_hdd_cfg80211.c
+++ b/CORE/HDD/src/wlan_hdd_cfg80211.c
@@ -5594,6 +5594,88 @@
return ret;
}
+
+static const struct
+nla_policy
+qca_wlan_vendor_wifi_logger_get_ring_data_policy
+[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX + 1] = {
+ [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]
+ = {.type = NLA_U32 },
+};
+
+static int
+ __wlan_hdd_cfg80211_wifi_logger_get_ring_data(struct wiphy *wiphy,
+ struct wireless_dev *wdev,
+ const void *data,
+ int data_len)
+{
+ int ret;
+ VOS_STATUS status;
+ uint32_t ring_id;
+ hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
+ struct nlattr *tb
+ [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX + 1];
+
+ ENTER();
+
+ ret = wlan_hdd_validate_context(hdd_ctx);
+ if (0 != ret) {
+ return ret;
+ }
+
+ if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX,
+ data, data_len,
+ qca_wlan_vendor_wifi_logger_get_ring_data_policy)) {
+ hddLog(LOGE, FL("Invalid attribute"));
+ return -EINVAL;
+ }
+
+ /* Parse and fetch ring id */
+ if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]) {
+ hddLog(LOGE, FL("attr ATTR failed"));
+ return -EINVAL;
+ }
+
+ ring_id = nla_get_u32(
+ tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]);
+
+ hddLog(LOG1, FL("Bug report triggered by framework"));
+
+ status = vos_fatal_event_logs_req(WLAN_LOG_TYPE_NON_FATAL,
+ WLAN_LOG_INDICATOR_FRAMEWORK,
+ WLAN_LOG_REASON_CODE_FRAMEWORK,
+ TRUE
+ );
+ if (VOS_STATUS_SUCCESS != status) {
+ hddLog(LOGE, FL("Failed to trigger bug report"));
+
+ return -EINVAL;
+ }
+
+ return 0;
+
+
+}
+
+
+static int
+ wlan_hdd_cfg80211_wifi_logger_get_ring_data(struct wiphy *wiphy,
+ struct wireless_dev *wdev,
+ const void *data,
+ int data_len)
+{
+ int ret = 0;
+
+ vos_ssr_protect(__func__);
+ ret = __wlan_hdd_cfg80211_wifi_logger_get_ring_data(wiphy,
+ wdev, data, data_len);
+ vos_ssr_unprotect(__func__);
+
+ return ret;
+
+}
+
+
static int
__wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
struct wireless_dev *wdev,
@@ -6396,6 +6478,14 @@
WIPHY_VENDOR_CMD_NEED_NETDEV|
WIPHY_VENDOR_CMD_NEED_RUNNING,
.doit = wlan_hdd_cfg80211_get_wifi_info
+ },
+ {
+ .info.vendor_id = QCA_NL80211_VENDOR_ID,
+ .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_RING_DATA,
+ .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
+ WIPHY_VENDOR_CMD_NEED_NETDEV |
+ WIPHY_VENDOR_CMD_NEED_RUNNING,
+ .doit = wlan_hdd_cfg80211_wifi_logger_get_ring_data
}
};
diff --git a/CORE/HDD/src/wlan_hdd_wext.c b/CORE/HDD/src/wlan_hdd_wext.c
index 2502c81..2304198 100644
--- a/CORE/HDD/src/wlan_hdd_wext.c
+++ b/CORE/HDD/src/wlan_hdd_wext.c
@@ -7089,7 +7089,7 @@
{
vos_fatal_event_logs_req(WLAN_LOG_TYPE_NON_FATAL,
WLAN_LOG_INDICATOR_IOCTL,
- WLAN_LOG_REASON_CODE_UNUSED,
+ WLAN_LOG_REASON_IOCTL,
TRUE);
break;
}
diff --git a/CORE/SVC/inc/wlan_logging_sock_svc.h b/CORE/SVC/inc/wlan_logging_sock_svc.h
index 95f278d..9d8d071 100644
--- a/CORE/SVC/inc/wlan_logging_sock_svc.h
+++ b/CORE/SVC/inc/wlan_logging_sock_svc.h
@@ -84,5 +84,19 @@
void wlan_disable_and_flush_pkt_stats(void);
void wlan_fillTxStruct(void *pktStat);
bool wlan_isPktStatsEnabled(void);
+#ifdef FEATURE_WLAN_DIAG_SUPPORT
+void wlan_report_log_completion(uint32 is_fatal,
+ uint32 indicator,
+ uint32 reason_code);
+#else
+static inline void wlan_report_log_completion(uint32 is_fatal,
+ uint32 indicator,
+ uint32 reason_code)
+{
+ return;
+}
+
+#endif
+
#endif /* WLAN_LOGGING_SOCK_SVC_H */
diff --git a/CORE/SVC/src/logging/wlan_logging_sock_svc.c b/CORE/SVC/src/logging/wlan_logging_sock_svc.c
index a8bee4d..ed10cfd 100644
--- a/CORE/SVC/src/logging/wlan_logging_sock_svc.c
+++ b/CORE/SVC/src/logging/wlan_logging_sock_svc.c
@@ -1368,7 +1368,6 @@
gwlan_logging.log_complete.is_report_in_progress = true;
gwlan_logging.log_complete.reason_code = reason_code;
spin_unlock_irqrestore(&gwlan_logging.bug_report_lock, flags);
-
return 0;
}
void wlan_get_log_completion(uint32 *is_fatal,
@@ -1382,15 +1381,15 @@
*is_fatal = gwlan_logging.log_complete.is_fatal;
*reason_code = gwlan_logging.log_complete.reason_code;
gwlan_logging.log_complete.is_report_in_progress = false;
-
spin_unlock_irqrestore(&gwlan_logging.bug_report_lock, flags);
-
}
+
bool wlan_is_log_report_in_progress(void)
{
return gwlan_logging.log_complete.is_report_in_progress;
}
+
void wlan_reset_log_report_in_progress(void)
{
unsigned long flags;
@@ -1849,6 +1848,7 @@
void wlan_process_done_indication(uint8 type, uint32 reason_code)
{
+<<<<<<< HEAD
if ((type == WLAN_FW_LOGS) && (wlan_is_log_report_in_progress() == TRUE))
{
pr_info("%s: Setting LOGGER_FATAL_EVENT\n", __func__);
@@ -1862,6 +1862,28 @@
wake_up_interruptible(&gwlan_logging.wait_queue);
}
+=======
+ if ((type == WLAN_FW_LOGS) && reason_code)
+ {
+ if(wlan_is_log_report_in_progress() == TRUE)
+ {
+ pr_info("%s : Setting LOGGER_FATAL_EVENT\n", __func__);
+ set_bit(LOGGER_FATAL_EVENT_POST_MASK, &gwlan_logging.event_flag);
+ wake_up_interruptible(&gwlan_logging.wait_queue);
+ }
+ else
+ {
+ /*Firmware Initiated*/
+ pr_info("%s : FW triggered Fatal Event, reason_code : %d\n", __func__,
+ reason_code);
+ wlan_set_log_completion(WLAN_LOG_TYPE_FATAL,
+ WLAN_LOG_INDICATOR_FIRMWARE,
+ reason_code);
+ set_bit(LOGGER_FATAL_EVENT_POST_MASK, &gwlan_logging.event_flag);
+ wake_up_interruptible(&gwlan_logging.wait_queue);
+ }
+ }
+>>>>>>> 6ea54f9... wlan: Handle fatal event triggered from framework and FW
}
/**
@@ -1907,6 +1929,7 @@
spin_unlock_irqrestore(&gwlan_logging.thread_stuck_lock, flags);
}
+<<<<<<< HEAD
int wlan_fwr_mem_dump_buffer_allocation(void)
{
/*Allocate the dump memory as reported by fw.
@@ -2104,5 +2127,33 @@
kfree_skb(skb);
return;
}
+=======
+#ifdef FEATURE_WLAN_DIAG_SUPPORT
+/**
+ * wlan_report_log_completion() - Report bug report completion to userspace
+ * @is_fatal: Type of event, fatal or not
+ * @indicator: Source of bug report, framework/host/firmware
+ * @reason_code: Reason for triggering bug report
+ *
+ * This function is used to report the bug report completion to userspace
+ *
+ * Return: None
+ */
+void wlan_report_log_completion(uint32_t is_fatal,
+ uint32_t indicator,
+ uint32_t reason_code)
+{
+ WLAN_VOS_DIAG_EVENT_DEF(wlan_diag_event,
+ struct vos_event_wlan_log_complete);
+
+ wlan_diag_event.is_fatal = is_fatal;
+ wlan_diag_event.indicator = indicator;
+ wlan_diag_event.reason_code = reason_code;
+ wlan_diag_event.reserved = 0;
+
+ WLAN_VOS_DIAG_EVENT_REPORT(&wlan_diag_event, EVENT_WLAN_LOG_COMPLETE);
+}
+#endif
+>>>>>>> 6ea54f9... wlan: Handle fatal event triggered from framework and FW
#endif /* WLAN_LOGGING_SOCK_SVC_ENABLE */
diff --git a/CORE/VOSS/inc/event_defs.h b/CORE/VOSS/inc/event_defs.h
index 38a1694..c076cfe 100644
--- a/CORE/VOSS/inc/event_defs.h
+++ b/CORE/VOSS/inc/event_defs.h
@@ -1903,6 +1903,7 @@
EVENT_SNS_DRV_OPMODE_CHANGE = 0x768,
EVENT_WLAN_EAPOL = 0xA8D,/* 18 bytes payload */
EVENT_WLAN_WAKE_LOCK = 0xAA2, /* 96 bytes payload */
+ EVENT_WLAN_LOG_COMPLETE = 0xAA7, /* 16 bytes payload */
EVENT_NEXT_UNUSED_EVENT,
EVENT_RSVD_START = 0x0800,
EVENT_RSVD_END = 0x083F,
diff --git a/CORE/VOSS/inc/vos_api.h b/CORE/VOSS/inc/vos_api.h
index 99746e5..1352502 100644
--- a/CORE/VOSS/inc/vos_api.h
+++ b/CORE/VOSS/inc/vos_api.h
@@ -196,6 +196,8 @@
WLAN_LOG_REASON_MALLOC_FAIL,
WLAN_LOG_REASON_VOS_MSG_UNDER_RUN,
WLAN_LOG_REASON_MSG_POST_FAIL,
+ WLAN_LOG_REASON_IOCTL,
+ WLAN_LOG_REASON_CODE_FRAMEWORK,
};
/*-------------------------------------------------------------------------
diff --git a/CORE/VOSS/inc/vos_diag_core_event.h b/CORE/VOSS/inc/vos_diag_core_event.h
index 715fbd2..596711d 100644
--- a/CORE/VOSS/inc/vos_diag_core_event.h
+++ b/CORE/VOSS/inc/vos_diag_core_event.h
@@ -283,6 +283,24 @@
};
+/*-------------------------------------------------------------------------
+ Event ID: EVENT_WLAN_LOG_COMPLETE
+ ------------------------------------------------------------------------*/
+/**
+ * struct vos_event_wlan_log_complete - Holds log completion details
+ * @is_fatal: Indicates if the event is fatal or not
+ * @indicator: Source of the bug report - Framework/Host/Firmware
+ * @reason_code: Reason for triggering bug report
+ * @reserved: Reserved field
+ *
+ * This structure holds the log completion related information
+ */
+struct vos_event_wlan_log_complete {
+ uint32_t is_fatal;
+ uint32_t indicator;
+ uint32_t reason_code;
+ uint32_t reserved;
+};
/*-------------------------------------------------------------------------
diff --git a/CORE/VOSS/src/vos_api.c b/CORE/VOSS/src/vos_api.c
index 9bb72ad..4a9a779 100644
--- a/CORE/VOSS/src/vos_api.c
+++ b/CORE/VOSS/src/vos_api.c
@@ -1722,8 +1722,10 @@
/*The below API will reset is_report_in_progress flag*/
vos_get_log_completion(&is_fatal, &indicator, &reason_code);
VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
- "%s: is_fatal : %d, indicator: %d, reason_code=%d",
- __func__, is_fatal, indicator, reason_code);
+ "is_fatal : %d, indicator: %d, reason_code=%d",
+ is_fatal, indicator, reason_code);
+ wlan_report_log_completion(is_fatal, indicator, reason_code);
+
}
diff --git a/CORE/WDI/TRP/DTS/src/wlan_qct_wdi_dts.c b/CORE/WDI/TRP/DTS/src/wlan_qct_wdi_dts.c
index bfb3ed9..1832804 100644
--- a/CORE/WDI/TRP/DTS/src/wlan_qct_wdi_dts.c
+++ b/CORE/WDI/TRP/DTS/src/wlan_qct_wdi_dts.c
@@ -940,6 +940,10 @@
vos_process_done_indication(pLoggingSession->logType,
pLoggingSession->reasonCode);
+
+ if (pLoggingSession->logType == QXDM_LOGGING &&
+ pLoggingSession->reasonCode)
+ pLoggingSession->logType = FATAL_EVENT;
((WDI_DS_ClientDataType *)(pContext))->rxLogCB(pLoggingSession->logType);
pLoggingSession->done = 0;