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
This commit is contained in:
Arun Kumar Khandavalli 2020-03-28 19:32:20 +05:30 • committed by nshrivas
commit 8037f0b7e9
3 changed files with 44 additions and 9 deletions

View file

@ -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;

View file

@ -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);

View file

@ -44,6 +44,8 @@
#include "wlan_hdd_debugfs.h"
#include "cfg_ucfg_api.h"
#include <linux/suspend.h>
#include <qdf_notifier.h>
#include <qdf_hang_event_notifier.h>
#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