From 8037f0b7e9c0e91b2d5762936566efdee16a360a Mon Sep 17 00:00:00 2001 From: Arun Kumar Khandavalli Date: Sat, 28 Mar 2020 19:32:20 +0530 Subject: [PATCH] qcacld-3.0: Send hang data to userspace With the new feature when the recovery is triggered informatation is collected from the various modules and send the data to user space. Change-Id: I8d7bb5be46df6150d0efa1cdb8db74a135ba89d7 CRs-Fixed: 2651903 --- core/hdd/src/wlan_hdd_cfg80211.c | 10 ++++++--- core/hdd/src/wlan_hdd_cfg80211.h | 5 ++++- core/hdd/src/wlan_hdd_driver_ops.c | 36 ++++++++++++++++++++++++++---- 3 files changed, 43 insertions(+), 8 deletions(-) diff --git a/core/hdd/src/wlan_hdd_cfg80211.c b/core/hdd/src/wlan_hdd_cfg80211.c index 260629318175..1e0d359cee63 100644 --- a/core/hdd/src/wlan_hdd_cfg80211.c +++ b/core/hdd/src/wlan_hdd_cfg80211.c @@ -1129,11 +1129,13 @@ hdd_convert_hang_reason(enum qdf_hang_reason reason) * wlan_hdd_send_hang_reason_event() - Send hang reason to the userspace * @hdd_ctx: Pointer to hdd context * @reason: cds recovery reason + * @data: Hang Data * * Return: 0 on success or failure reason */ int wlan_hdd_send_hang_reason_event(struct hdd_context *hdd_ctx, - enum qdf_hang_reason reason) + enum qdf_hang_reason reason, void *data, + size_t data_len) { struct sk_buff *vendor_event; enum qca_wlan_vendor_hang_reason hang_reason; @@ -1153,7 +1155,7 @@ int wlan_hdd_send_hang_reason_event(struct hdd_context *hdd_ctx, vendor_event = cfg80211_vendor_event_alloc(hdd_ctx->wiphy, wdev, - sizeof(uint32_t), + sizeof(uint32_t) + data_len, HANG_REASON_INDEX, GFP_KERNEL); if (!vendor_event) { @@ -1164,7 +1166,9 @@ int wlan_hdd_send_hang_reason_event(struct hdd_context *hdd_ctx, hang_reason = hdd_convert_hang_reason(reason); if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_HANG_REASON, - (uint32_t)hang_reason)) { + (uint32_t)hang_reason) || + nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_HANG_REASON_DATA, + data_len, data)) { hdd_err("QCA_WLAN_VENDOR_ATTR_HANG_REASON put fail"); kfree_skb(vendor_event); return -EINVAL; diff --git a/core/hdd/src/wlan_hdd_cfg80211.h b/core/hdd/src/wlan_hdd_cfg80211.h index 696f2e110f63..5688c6ba0170 100644 --- a/core/hdd/src/wlan_hdd_cfg80211.h +++ b/core/hdd/src/wlan_hdd_cfg80211.h @@ -462,11 +462,14 @@ int wlan_hdd_send_avoid_freq_event(struct hdd_context *hdd_ctx, * wlan_hdd_send_hang_reason_event() - Send hang reason to the userspace * @hdd_ctx: Pointer to hdd context * @reason: cds recovery reason + * @data: Hang Data + * @data_len: Hang Data len * * Return: 0 on success or failure reason */ int wlan_hdd_send_hang_reason_event(struct hdd_context *hdd_ctx, - uint32_t reason); + uint32_t reason, void *data, + size_t data_len); int wlan_hdd_send_avoid_freq_for_dnbs(struct hdd_context *hdd_ctx, uint8_t op_chan); diff --git a/core/hdd/src/wlan_hdd_driver_ops.c b/core/hdd/src/wlan_hdd_driver_ops.c index b9e1f7604acb..66f27990d27d 100644 --- a/core/hdd/src/wlan_hdd_driver_ops.c +++ b/core/hdd/src/wlan_hdd_driver_ops.c @@ -44,6 +44,8 @@ #include "wlan_hdd_debugfs.h" #include "cfg_ucfg_api.h" #include +#include +#include #ifdef MODULE #define WLAN_MODULE_NAME module_name(THIS_MODULE) @@ -698,11 +700,12 @@ static inline void hdd_wlan_ssr_shutdown_event(void) { } #endif /** - * hdd_send_hang_reason() - Send hang reason to the userspace + * hdd_send_hang_data() - Send hang data to userspace + * @data: Hang data * * Return: None */ -static void hdd_send_hang_reason(void) +static void hdd_send_hang_data(void *data, size_t data_len) { enum qdf_hang_reason reason = QDF_REASON_UNSPECIFIED; struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); @@ -712,7 +715,7 @@ static void hdd_send_hang_reason(void) cds_get_recovery_reason(&reason); cds_reset_recovery_reason(); - wlan_hdd_send_hang_reason_event(hdd_ctx, reason); + wlan_hdd_send_hang_reason_event(hdd_ctx, reason, data, data_len); } /** @@ -744,7 +747,7 @@ static void hdd_psoc_shutdown_notify(struct hdd_context *hdd_ctx) cds_shutdown_notifier_purge(); hdd_wlan_ssr_shutdown_event(); - hdd_send_hang_reason(); + hdd_send_hang_data(NULL, 0); } static void __hdd_soc_recovery_shutdown(void) @@ -1707,6 +1710,9 @@ static void wlan_hdd_pld_notify_handler(struct device *dev, static void wlan_hdd_pld_uevent(struct device *dev, struct pld_uevent_data *event_data) { + struct qdf_notifer_data hang_evt_data; + enum qdf_hang_reason reason = QDF_REASON_UNSPECIFIED; + switch (event_data->uevent) { case PLD_FW_DOWN: hdd_info("Received firmware down indication"); @@ -1726,13 +1732,35 @@ wlan_hdd_pld_uevent(struct device *dev, struct pld_uevent_data *event_data) * on a firmware we already know is down. */ qdf_complete_wait_events(); + cds_get_recovery_reason(&reason); + hang_evt_data.hang_data = + qdf_mem_malloc(QDF_HANG_EVENT_DATA_SIZE); + if (!hang_evt_data.hang_data) + return; + hang_evt_data.offset = 0; + qdf_hang_event_notifier_call(reason, &hang_evt_data); + if (event_data->fw_down.hang_event_data_len >= + QDF_HANG_EVENT_DATA_SIZE / 2) + event_data->fw_down.hang_event_data_len = + QDF_HANG_EVENT_DATA_SIZE / 2; + hang_evt_data.offset = QDF_WLAN_HANG_FW_OFFSET; + if (event_data->fw_down.hang_event_data_len) + qdf_mem_copy((hang_evt_data.hang_data + + hang_evt_data.offset), + event_data->fw_down.hang_event_data, + event_data->fw_down.hang_event_data_len); + + hdd_send_hang_data(hang_evt_data.hang_data, + QDF_HANG_EVENT_DATA_SIZE); + qdf_mem_free(hang_evt_data.hang_data); break; default: /* other events intentionally not handled */ hdd_debug("Received uevent %d", event_data->uevent); break; } + } #ifdef FEATURE_RUNTIME_PM