Commit a9b46dd2 authored by Sowmiya Sree Elavalagan's avatar Sowmiya Sree Elavalagan Committed by Jeff Johnson
Browse files

wifi: ath12k: Add firmware coredump collection support



In case of firmware assert snapshot of firmware memory is essential for
debugging. Add firmware coredump collection support for PCI bus.
Collect RDDM and firmware paging dumps from MHI and pack them in TLV
format and also pack various memory shared during QMI phase in separate
TLVs.  Add necessary header and share the dumps to user space using dev
coredump framework. Coredump collection is disabled by default and can
be enabled using menuconfig. Dump collected for a radio is 55 MB
approximately.

Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.2.1-00201-QCAHKSWPL_SILICONZ-1
Tested-on: WCN7850 WLAN.HMT.1.0-03427-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1.15378.4

Signed-off-by: default avatarSowmiya Sree Elavalagan <quic_ssreeela@quicinc.com>
Acked-by: default avatarJeff Johnson <quic_jjohnson@quicinc.com>
Link: https://patch.msgid.link/20240717085604.4131642-1-quic_ssreeela@quicinc.com


Signed-off-by: default avatarJeff Johnson <quic_jjohnson@quicinc.com>
parent c347f181
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -42,3 +42,13 @@ config ATH12K_TRACING

	  If unsure, say Y to make it easier to debug problems. But if
	  you want optimal performance choose N.

config ATH12K_COREDUMP
	bool "ath12k coredump"
	depends on ATH12K
	select WANT_DEV_COREDUMP
	help
	  Enable ath12k coredump collection

	  If unsure, say Y to make it easier to debug problems. But if
	  dump collection not required choose N.
+1 −0
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@ ath12k-$(CONFIG_ATH12K_DEBUGFS) += debugfs.o debugfs_htt_stats.o
ath12k-$(CONFIG_ACPI) += acpi.o
ath12k-$(CONFIG_ATH12K_TRACING) += trace.o
ath12k-$(CONFIG_PM) += wow.o
ath12k-$(CONFIG_ATH12K_COREDUMP) += coredump.o

# for tracing framework to find trace.h
CFLAGS_trace.o := -I$(src)
+2 −0
Original line number Diff line number Diff line
@@ -1187,6 +1187,7 @@ static void ath12k_core_reset(struct work_struct *work)
	ab->is_reset = true;
	atomic_set(&ab->recovery_count, 0);

	ath12k_coredump_collect(ab);
	ath12k_core_pre_reconfigure_recovery(ab);

	ath12k_core_post_reconfigure_recovery(ab);
@@ -1311,6 +1312,7 @@ struct ath12k_base *ath12k_core_alloc(struct device *dev, size_t priv_size,
	INIT_WORK(&ab->restart_work, ath12k_core_restart);
	INIT_WORK(&ab->reset_work, ath12k_core_reset);
	INIT_WORK(&ab->rfkill_work, ath12k_rfkill_work);
	INIT_WORK(&ab->dump_work, ath12k_coredump_upload);

	timer_setup(&ab->rx_replenish_retry, ath12k_ce_rx_replenish_retry, 0);
	init_completion(&ab->htc_suspend);
+5 −0
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@
#include "acpi.h"
#include "wow.h"
#include "debugfs_htt_stats.h"
#include "coredump.h"

#define SM(_v, _f) (((_v) << _f##_LSB) & _f##_MASK)

@@ -779,6 +780,10 @@ struct ath12k_base {
	/* HW channel counters frequency value in hertz common to all MACs */
	u32 cc_freq_hz;

	struct ath12k_dump_file_data *dump_data;
	size_t ath12k_coredump_len;
	struct work_struct dump_work;

	struct ath12k_htc htc;

	struct ath12k_dp dp;
+51 −0
Original line number Diff line number Diff line
// SPDX-License-Identifier: BSD-3-Clause-Clear
/*
 * Copyright (c) 2020 The Linux Foundation. All rights reserved.
 * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
 */
#include <linux/devcoredump.h>
#include "hif.h"
#include "coredump.h"
#include "debug.h"

enum
ath12k_fw_crash_dump_type ath12k_coredump_get_dump_type(enum ath12k_qmi_target_mem type)
{
	enum ath12k_fw_crash_dump_type dump_type;

	switch (type) {
	case HOST_DDR_REGION_TYPE:
		dump_type = FW_CRASH_DUMP_REMOTE_MEM_DATA;
		break;
	case M3_DUMP_REGION_TYPE:
		dump_type = FW_CRASH_DUMP_M3_DUMP;
		break;
	case PAGEABLE_MEM_REGION_TYPE:
		dump_type = FW_CRASH_DUMP_PAGEABLE_DATA;
		break;
	case BDF_MEM_REGION_TYPE:
	case CALDB_MEM_REGION_TYPE:
		dump_type = FW_CRASH_DUMP_NONE;
		break;
	default:
		dump_type = FW_CRASH_DUMP_TYPE_MAX;
		break;
	}

	return dump_type;
}

void ath12k_coredump_upload(struct work_struct *work)
{
	struct ath12k_base *ab = container_of(work, struct ath12k_base, dump_work);

	ath12k_info(ab, "Uploading coredump\n");
	/* dev_coredumpv() takes ownership of the buffer */
	dev_coredumpv(ab->dev, ab->dump_data, ab->ath12k_coredump_len, GFP_KERNEL);
	ab->dump_data = NULL;
}

void ath12k_coredump_collect(struct ath12k_base *ab)
{
	ath12k_hif_coredump_download(ab);
}
Loading