// 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 ring, TX rings */
	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);
}
