// SPDX-License-Identifier: GPL-2.0
//
// mcp251xfd - Microchip MCP251xFD Family CAN controller driver
//
// Copyright (c) 2020, 2021 Pengutronix,
//               Marc Kleine-Budde <kernel@pengutronix.de>
// Copyright (C) 2015-2018 Etnaviv Project
//

#include <linux/devcoredump.h>

#include "mcp251xfd.h"
#include "mcp251xfd-dump.h"

struct mcp251xfd_dump_iter {
	void *start;
	struct mcp251xfd_dump_object_header *hdr;
	void *data;
};

struct mcp251xfd_dump_reg_space {
	u16 base;
	u16 size;
};

struct mcp251xfd_dump_ring {
	enum mcp251xfd_dump_object_ring_key key;
	u32 val;
};

static const struct mcp251xfd_dump_reg_space mcp251xfd_dump_reg_space[] = {
	{
		.base = MCP251XFD_REG_CON,
		.size = MCP251XFD_REG_FLTOBJ(32) - MCP251XFD_REG_CON,
	}, {
		.base = MCP251XFD_RAM_START,
		.size = MCP251XFD_RAM_SIZE,
	}, {
		.base = MCP251XFD_REG_OSC,
		.size = MCP251XFD_REG_DEVID - MCP251XFD_REG_OSC,
	},
};

static void mcp251xfd_dump_header(struct mcp251xfd_dump_iter *iter,
				  enum mcp251xfd_dump_object_type object_type,
				  const void *data_end)
{
	struct mcp251xfd_dump_object_header *hdr = iter->hdr;
	unsigned int len;

	len = data_end - iter->data;
	if (!len)
		return;

	hdr->magic = cpu_to_le32(MCP251XFD_DUMP_MAGIC);
	hdr->type = cpu_to_le32(object_type);
	hdr->offset = cpu_to_le32(iter->data - iter->start);
	hdr->len = cpu_to_le32(len);

	iter->hdr++;
	iter->data += len;
}

static void mcp251xfd_dump_registers(const struct mcp251xfd_priv *priv,
				     struct mcp251xfd_dump_iter *iter)
{
	const int val_bytes = regmap_get_val_bytes(priv->map_rx);
	struct mcp251xfd_dump_object_reg *reg = iter->data;
	unsigned int i, j;
	int err;

	for (i = 0; i < ARRAY_SIZE(mcp251xfd_dump_reg_space); i++) {
		const struct mcp251xfd_dump_reg_space *reg_space;
		void *buf;

		reg_space = &mcp251xfd_dump_reg_space[i];

		buf = kmalloc(reg_space->size, GFP_KERNEL);
		if (!buf)
			goto out;

		err = regmap_bulk_read(priv->map_reg, reg_space->base,
				       buf, reg_space->size / val_bytes);
		if (err) {
			kfree(buf);
			continue;
		}

		for (j = 0; j < reg_space->size; j += sizeof(u32), reg++) {
			reg->reg = cpu_to_le32(reg_space->base + j);
			reg->val = cpu_to_le32p(buf + j);
		}

		kfree(buf);
	}

out:
	mcp251xfd_dump_header(iter, MCP251XFD_DUMP_OBJECT_TYPE_REG, reg);
}

static void mcp251xfd_dump_ring(struct mcp251xfd_dump_iter *iter,
				enum mcp251xfd_dump_object_type object_type,
				const struct mcp251xfd_dump_ring *dump_ring,
				unsigned int len)
{
	struct mcp251xfd_dump_object_reg *reg = iter->data;
	unsigned int i;

	for (i = 0; i < len; i++, reg++) {
		reg->reg = cpu_to_le32(dump_ring[i].key);
		reg->val = cpu_to_le32(dump_ring[i].val);
	}

	mcp251xfd_dump_header(iter, object_type, reg);
}

static void mcp251xfd_dump_tef_ring(const struct mcp251xfd_priv *priv,
				    struct mcp251xfd_dump_iter *iter)
{
	const struct mcp251xfd_tef_ring *tef = priv->tef;
	const struct mcp251xfd_tx_ring *tx = priv->tx;
	const struct mcp251xfd_dump_ring dump_ring[] = {
		{
			.key = MCP251XFD_DUMP_OBJECT_RING_KEY_HEAD,
			.val = tef->head,
		}, {
			.key = MCP251XFD_DUMP_OBJECT_RING_KEY_TAIL,
			.val = tef->tail,
		}, {
			.key = MCP251XFD_DUMP_OBJECT_RING_KEY_BASE,
			.val = 0,
		}, {
			.key = MCP251XFD_DUMP_OBJECT_RING_KEY_NR,
			.val = 0,
		}, {
			.key = MCP251XFD_DUMP_OBJECT_RING_KEY_FIFO_NR,
			.val = 0,
		}, {
			.key = MCP251XFD_DUMP_OBJECT_RING_KEY_OBJ_NUM,
			.val = tx->obj_num,
		}, {
			.key = MCP251XFD_DUMP_OBJECT_RING_KEY_OBJ_SIZE,
			.val = sizeof(struct mcp251xfd_hw_tef_obj),
		},
	};

	mcp251xfd_dump_ring(iter, MCP251XFD_DUMP_OBJECT_TYPE_TEF,
			    dump_ring, ARRAY_SIZE(dump_ring));
}

static void mcp251xfd_dump_rx_ring_one(const struct mcp251xfd_priv *priv,
				       struct mcp251xfd_dump_iter *iter,
				       const struct mcp251xfd_rx_ring *rx)
{
	const struct mcp251xfd_dump_ring dump_ring[] = {
		{
			.key = MCP251XFD_DUMP_OBJECT_RING_KEY_HEAD,
			.val = rx->head,
		}, {
			.key = MCP251XFD_DUMP_OBJECT_RING_KEY_TAIL,
			.val = rx->tail,
		}, {
			.key = MCP251XFD_DUMP_OBJECT_RING_KEY_BASE,
			.val = rx->base,
		}, {
			.key = MCP251XFD_DUMP_OBJECT_RING_KEY_NR,
			.val = rx->nr,
		}, {
			.key = MCP251XFD_DUMP_OBJECT_RING_KEY_FIFO_NR,
			.val = rx->fifo_nr,
		}, {
			.key = MCP251XFD_DUMP_OBJECT_RING_KEY_OBJ_NUM,
			.val = rx->obj_num,
		}, {
			.key = MCP251XFD_DUMP_OBJECT_RING_KEY_OBJ_SIZE,
			.val = rx->obj_size,
		},
	};

	mcp251xfd_dump_ring(iter, MCP251XFD_DUMP_OBJECT_TYPE_RX,
			    dump_ring, ARRAY_SIZE(dump_ring));
}

static void mcp251xfd_dump_rx_ring(const struct mcp251xfd_priv *priv,
				   struct mcp251xfd_dump_iter *iter)
{
	struct mcp251xfd_rx_ring *rx_ring;
	unsigned int i;

	mcp251xfd_for_each_rx_ring(priv, rx_ring, i)
		mcp251xfd_dump_rx_ring_one(priv, iter, rx_ring);
}

static void mcp251xfd_dump_tx_ring(const struct mcp251xfd_priv *priv,
				   struct mcp251xfd_dump_iter *iter)
{
	const struct mcp251xfd_tx_ring *tx = priv->tx;
	const struct mcp251xfd_dump_ring dump_ring[] = {
		{
			.key = MCP251XFD_DUMP_OBJECT_RING_KEY_HEAD,
			.val = tx->head,
		}, {
			.key = MCP251XFD_DUMP_OBJECT_RING_KEY_TAIL,
			.val = tx->tail,
		}, {
			.key = MCP251XFD_DUMP_OBJECT_RING_KEY_BASE,
			.val = tx->base,
		}, {
			.key = MCP251XFD_DUMP_OBJECT_RING_KEY_NR,
			.val = tx->nr,
		}, {
			.key = MCP251XFD_DUMP_OBJECT_RING_KEY_FIFO_NR,
			.val = tx->fifo_nr,
		}, {
			.key = MCP251XFD_DUMP_OBJECT_RING_KEY_OBJ_NUM,
			.val = tx->obj_num,
		}, {
			.key = MCP251XFD_DUMP_OBJECT_RING_KEY_OBJ_SIZE,
			.val = tx->obj_size,
		},
	};

	mcp251xfd_dump_ring(iter, MCP251XFD_DUMP_OBJECT_TYPE_TX,
			    dump_ring, ARRAY_SIZE(dump_ring));
}

static void mcp251xfd_dump_end(const struct mcp251xfd_priv *priv,
			       struct mcp251xfd_dump_iter *iter)
{
	struct mcp251xfd_dump_object_header *hdr = iter->hdr;

	hdr->magic = cpu_to_le32(MCP251XFD_DUMP_MAGIC);
	hdr->type = cpu_to_le32(MCP251XFD_DUMP_OBJECT_TYPE_END);
	hdr->offset = cpu_to_le32(0);
	hdr->len = cpu_to_le32(0);

	/* provoke NULL pointer access, if used after END object */
	iter->hdr = NULL;
}

void mcp251xfd_dump(const struct mcp251xfd_priv *priv)
{
	struct mcp251xfd_dump_iter iter;
	unsigned int rings_num, obj_num;
	unsigned int file_size = 0;
	unsigned int i;

	/* register space + end marker */
	obj_num = 2;

	/* register space */
	for (i = 0; i < ARRAY_SIZE(mcp251xfd_dump_reg_space); i++)
		file_size += mcp251xfd_dump_reg_space[i].size / sizeof(u32) *
			sizeof(struct mcp251xfd_dump_object_reg);

	/* TEF ring, RX rings, TX ring */
	rings_num = 1 + priv->rx_ring_num + 1;
	obj_num += rings_num;
	file_size += rings_num * __MCP251XFD_DUMP_OBJECT_RING_KEY_MAX  *
		sizeof(struct mcp251xfd_dump_object_reg);

	/* size of the headers */
	file_size += sizeof(*iter.hdr) * obj_num;

	/* allocate the file in vmalloc memory, it's likely to be big */
	iter.start = __vmalloc(file_size, GFP_KERNEL | __GFP_NOWARN |
			       __GFP_ZERO | __GFP_NORETRY);
	if (!iter.start) {
		netdev_warn(priv->ndev, "Failed to allocate devcoredump file.\n");
		return;
	}

	/* point the data member after the headers */
	iter.hdr = iter.start;
	iter.data = &iter.hdr[obj_num];

	mcp251xfd_dump_registers(priv, &iter);
	mcp251xfd_dump_tef_ring(priv, &iter);
	mcp251xfd_dump_rx_ring(priv, &iter);
	mcp251xfd_dump_tx_ring(priv, &iter);
	mcp251xfd_dump_end(priv, &iter);

	dev_coredumpv(&priv->spi->dev, iter.start,
		      iter.data - iter.start, GFP_KERNEL);
}
