// SPDX-License-Identifier: ISC
/* Copyright (C) 2023 MediaTek Inc. */

#include <linux/devcoredump.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/utsname.h>
#include "coredump.h"

static bool coredump_memdump;
module_param(coredump_memdump, bool, 0644);
MODULE_PARM_DESC(coredump_memdump, "Optional ability to dump firmware memory");

static const struct mt7996_mem_region mt7996_mem_regions[] = {
	{
		.start = 0x00800000,
		.len = 0x0004ffff,
		.name = "ULM0",
	},
	{
		.start = 0x00900000,
		.len = 0x00037fff,
		.name = "ULM1",
	},
	{
		.start = 0x02200000,
		.len = 0x0003ffff,
		.name = "ULM2",
	},
	{
		.start = 0x00400000,
		.len = 0x00067fff,
		.name = "SRAM",
	},
	{
		.start = 0xe0000000,
		.len = 0x0015ffff,
		.name = "CRAM0",
	},
	{
		.start = 0xe0160000,
		.len = 0x0011bfff,
		.name = "CRAM1",
	},
};

const struct mt7996_mem_region*
mt7996_coredump_get_mem_layout(struct mt7996_dev *dev, u32 *num)
{
	switch (mt76_chip(&dev->mt76)) {
	case 0x7990:
	case 0x7991:
		*num = ARRAY_SIZE(mt7996_mem_regions);
		return &mt7996_mem_regions[0];
	default:
		return NULL;
	}
}

static int mt7996_coredump_get_mem_size(struct mt7996_dev *dev)
{
	const struct mt7996_mem_region *mem_region;
	size_t size = 0;
	u32 num;
	int i;

	mem_region = mt7996_coredump_get_mem_layout(dev, &num);
	if (!mem_region)
		return 0;

	for (i = 0; i < num; i++) {
		size += mem_region->len;
		mem_region++;
	}

	/* reserve space for the headers */
	size += num * sizeof(struct mt7996_mem_hdr);
	/* make sure it is aligned 4 bytes for debug message print out */
	size = ALIGN(size, 4);

	return size;
}

struct mt7996_crash_data *mt7996_coredump_new(struct mt7996_dev *dev)
{
	struct mt7996_crash_data *crash_data = dev->coredump.crash_data;

	lockdep_assert_held(&dev->dump_mutex);

	if (coredump_memdump &&
	    !mt76_poll_msec(dev, MT_FW_DUMP_STATE, 0x3, 0x2, 500))
		return NULL;

	guid_gen(&crash_data->guid);
	ktime_get_real_ts64(&crash_data->timestamp);

	return crash_data;
}

static void
mt7996_coredump_fw_state(struct mt7996_dev *dev, struct mt7996_coredump *dump,
			 bool *exception)
{
	u32 count;

	count = mt76_rr(dev, MT_FW_ASSERT_CNT);

	/* normal mode: driver can manually trigger assert for detail info */
	if (!count)
		strscpy(dump->fw_state, "normal", sizeof(dump->fw_state));
	else
		strscpy(dump->fw_state, "exception", sizeof(dump->fw_state));

	*exception = !!count;
}

static void
mt7996_coredump_fw_stack(struct mt7996_dev *dev, struct mt7996_coredump *dump,
			 bool exception)
{
	u32 oldest, i, idx;

	strscpy(dump->pc_current, "program counter", sizeof(dump->pc_current));

	/* 0: WM PC log output */
	mt76_wr(dev, MT_CONN_DBG_CTL_OUT_SEL, 0);
	/* choose 33th PC log buffer to read current PC index */
	mt76_wr(dev, MT_CONN_DBG_CTL_PC_LOG_SEL, 0x3f);

	/* read current PC */
	dump->pc_stack[0] = mt76_rr(dev, MT_CONN_DBG_CTL_PC_LOG);

	/* stop call stack record */
	if (!exception) {
		mt76_clear(dev, MT_MCU_WM_EXCP_PC_CTRL, BIT(0));
		mt76_clear(dev, MT_MCU_WM_EXCP_LR_CTRL, BIT(0));
	}

	oldest = (u32)mt76_get_field(dev, MT_MCU_WM_EXCP_PC_CTRL,
				     GENMASK(20, 16)) + 2;
	for (i = 0; i < 16; i++) {
		idx = ((oldest + 2 * i + 1) % 32);
		dump->pc_stack[i + 1] =
			mt76_rr(dev, MT_MCU_WM_EXCP_PC_LOG + idx * 4);
	}

	oldest = (u32)mt76_get_field(dev, MT_MCU_WM_EXCP_LR_CTRL,
				     GENMASK(20, 16)) + 2;
	for (i = 0; i < 16; i++) {
		idx = ((oldest + 2 * i + 1) % 32);
		dump->lr_stack[i] =
			mt76_rr(dev, MT_MCU_WM_EXCP_LR_LOG + idx * 4);
	}

	/* start call stack record */
	if (!exception) {
		mt76_set(dev, MT_MCU_WM_EXCP_PC_CTRL, BIT(0));
		mt76_set(dev, MT_MCU_WM_EXCP_LR_CTRL, BIT(0));
	}
}

static struct mt7996_coredump *mt7996_coredump_build(struct mt7996_dev *dev)
{
	struct mt7996_crash_data *crash_data = dev->coredump.crash_data;
	struct mt7996_coredump *dump;
	struct mt7996_coredump_mem *dump_mem;
	size_t len, sofar = 0, hdr_len = sizeof(*dump);
	unsigned char *buf;
	bool exception;

	len = hdr_len;

	if (coredump_memdump && crash_data->memdump_buf_len)
		len += sizeof(*dump_mem) + crash_data->memdump_buf_len;

	sofar += hdr_len;

	/* this is going to get big when we start dumping memory and such,
	 * so go ahead and use vmalloc.
	 */
	buf = vzalloc(len);
	if (!buf)
		return NULL;

	mutex_lock(&dev->dump_mutex);

	dump = (struct mt7996_coredump *)(buf);
	dump->len = len;

	/* plain text */
	strscpy(dump->magic, "mt76-crash-dump", sizeof(dump->magic));
	strscpy(dump->kernel, init_utsname()->release, sizeof(dump->kernel));
	strscpy(dump->fw_ver, dev->mt76.hw->wiphy->fw_version,
		sizeof(dump->fw_ver));

	guid_copy(&dump->guid, &crash_data->guid);
	dump->tv_sec = crash_data->timestamp.tv_sec;
	dump->tv_nsec = crash_data->timestamp.tv_nsec;
	dump->device_id = mt76_chip(&dev->mt76);

	mt7996_coredump_fw_state(dev, dump, &exception);
	mt7996_coredump_fw_stack(dev, dump, exception);

	/* gather memory content */
	dump_mem = (struct mt7996_coredump_mem *)(buf + sofar);
	dump_mem->len = crash_data->memdump_buf_len;
	if (coredump_memdump && crash_data->memdump_buf_len)
		memcpy(dump_mem->data, crash_data->memdump_buf,
		       crash_data->memdump_buf_len);

	mutex_unlock(&dev->dump_mutex);

	return dump;
}

int mt7996_coredump_submit(struct mt7996_dev *dev)
{
	struct mt7996_coredump *dump;

	dump = mt7996_coredump_build(dev);
	if (!dump) {
		dev_warn(dev->mt76.dev, "no crash dump data found\n");
		return -ENODATA;
	}

	dev_coredumpv(dev->mt76.dev, dump, dump->len, GFP_KERNEL);

	return 0;
}

int mt7996_coredump_register(struct mt7996_dev *dev)
{
	struct mt7996_crash_data *crash_data;

	crash_data = vzalloc(sizeof(*dev->coredump.crash_data));
	if (!crash_data)
		return -ENOMEM;

	dev->coredump.crash_data = crash_data;

	if (coredump_memdump) {
		crash_data->memdump_buf_len = mt7996_coredump_get_mem_size(dev);
		if (!crash_data->memdump_buf_len)
			/* no memory content */
			return 0;

		crash_data->memdump_buf = vzalloc(crash_data->memdump_buf_len);
		if (!crash_data->memdump_buf) {
			vfree(crash_data);
			return -ENOMEM;
		}
	}

	return 0;
}

void mt7996_coredump_unregister(struct mt7996_dev *dev)
{
	if (dev->coredump.crash_data->memdump_buf) {
		vfree(dev->coredump.crash_data->memdump_buf);
		dev->coredump.crash_data->memdump_buf = NULL;
		dev->coredump.crash_data->memdump_buf_len = 0;
	}

	vfree(dev->coredump.crash_data);
	dev->coredump.crash_data = NULL;
}

