// SPDX-License-Identifier: GPL-2.0-only
/*
 * ONIE tlv NVMEM cells provider
 *
 * Copyright (C) 2022 Open Compute Group ONIE
 * Author: Miquel Raynal <miquel.raynal@bootlin.com>
 * Based on the nvmem driver written by: Vadym Kochan <vadym.kochan@plvision.eu>
 * Inspired by the first layout written by: Rafał Miłecki <rafal@milecki.pl>
 */

#include <linux/crc32.h>
#include <linux/etherdevice.h>
#include <linux/nvmem-consumer.h>
#include <linux/nvmem-provider.h>
#include <linux/of.h>

#define ONIE_TLV_MAX_LEN 2048
#define ONIE_TLV_CRC_FIELD_SZ 6
#define ONIE_TLV_CRC_SZ 4
#define ONIE_TLV_HDR_ID	"TlvInfo"

struct onie_tlv_hdr {
	u8 id[8];
	u8 version;
	__be16 data_len;
} __packed;

struct onie_tlv {
	u8 type;
	u8 len;
} __packed;

static const char *onie_tlv_cell_name(u8 type)
{
	switch (type) {
	case 0x21:
		return "product-name";
	case 0x22:
		return "part-number";
	case 0x23:
		return "serial-number";
	case 0x24:
		return "mac-address";
	case 0x25:
		return "manufacture-date";
	case 0x26:
		return "device-version";
	case 0x27:
		return "label-revision";
	case 0x28:
		return "platform-name";
	case 0x29:
		return "onie-version";
	case 0x2A:
		return "num-macs";
	case 0x2B:
		return "manufacturer";
	case 0x2C:
		return "country-code";
	case 0x2D:
		return "vendor";
	case 0x2E:
		return "diag-version";
	case 0x2F:
		return "service-tag";
	case 0xFD:
		return "vendor-extension";
	case 0xFE:
		return "crc32";
	default:
		break;
	}

	return NULL;
}

static int onie_tlv_mac_read_cb(void *priv, const char *id, int index,
				unsigned int offset, void *buf,
				size_t bytes)
{
	eth_addr_add(buf, index);

	return 0;
}

static nvmem_cell_post_process_t onie_tlv_read_cb(u8 type, u8 *buf)
{
	switch (type) {
	case 0x24:
		return &onie_tlv_mac_read_cb;
	default:
		break;
	}

	return NULL;
}

static int onie_tlv_add_cells(struct device *dev, struct nvmem_device *nvmem,
			      size_t data_len, u8 *data)
{
	struct nvmem_cell_info cell = {};
	struct device_node *layout;
	struct onie_tlv tlv;
	unsigned int hdr_len = sizeof(struct onie_tlv_hdr);
	unsigned int offset = 0;
	int ret;

	layout = of_nvmem_layout_get_container(nvmem);
	if (!layout)
		return -ENOENT;

	while (offset < data_len) {
		memcpy(&tlv, data + offset, sizeof(tlv));
		if (offset + tlv.len >= data_len) {
			dev_err(dev, "Out of bounds field (0x%x bytes at 0x%x)\n",
				tlv.len, hdr_len + offset);
			break;
		}

		cell.name = onie_tlv_cell_name(tlv.type);
		if (!cell.name)
			continue;

		cell.offset = hdr_len + offset + sizeof(tlv.type) + sizeof(tlv.len);
		cell.bytes = tlv.len;
		cell.np = of_get_child_by_name(layout, cell.name);
		cell.read_post_process = onie_tlv_read_cb(tlv.type, data + offset + sizeof(tlv));

		ret = nvmem_add_one_cell(nvmem, &cell);
		if (ret) {
			of_node_put(layout);
			return ret;
		}

		offset += sizeof(tlv) + tlv.len;
	}

	of_node_put(layout);

	return 0;
}

static bool onie_tlv_hdr_is_valid(struct device *dev, struct onie_tlv_hdr *hdr)
{
	if (memcmp(hdr->id, ONIE_TLV_HDR_ID, sizeof(hdr->id))) {
		dev_err(dev, "Invalid header\n");
		return false;
	}

	if (hdr->version != 0x1) {
		dev_err(dev, "Invalid version number\n");
		return false;
	}

	return true;
}

static bool onie_tlv_crc_is_valid(struct device *dev, size_t table_len, u8 *table)
{
	struct onie_tlv crc_hdr;
	u32 read_crc, calc_crc;
	__be32 crc_be;

	memcpy(&crc_hdr, table + table_len - ONIE_TLV_CRC_FIELD_SZ, sizeof(crc_hdr));
	if (crc_hdr.type != 0xfe || crc_hdr.len != ONIE_TLV_CRC_SZ) {
		dev_err(dev, "Invalid CRC field\n");
		return false;
	}

	/* The table contains a JAMCRC, which is XOR'ed compared to the original
	 * CRC32 implementation as known in the Ethernet world.
	 */
	memcpy(&crc_be, table + table_len - ONIE_TLV_CRC_SZ, ONIE_TLV_CRC_SZ);
	read_crc = be32_to_cpu(crc_be);
	calc_crc = crc32(~0, table, table_len - ONIE_TLV_CRC_SZ) ^ 0xFFFFFFFF;
	if (read_crc != calc_crc) {
		dev_err(dev, "Invalid CRC read: 0x%08x, expected: 0x%08x\n",
			read_crc, calc_crc);
		return false;
	}

	return true;
}

static int onie_tlv_parse_table(struct nvmem_layout *layout)
{
	struct nvmem_device *nvmem = layout->nvmem;
	struct device *dev = &layout->dev;
	struct onie_tlv_hdr hdr;
	size_t table_len, data_len, hdr_len;
	u8 *table, *data;
	int ret;

	ret = nvmem_device_read(nvmem, 0, sizeof(hdr), &hdr);
	if (ret < 0)
		return ret;

	if (!onie_tlv_hdr_is_valid(dev, &hdr)) {
		dev_err(dev, "Invalid ONIE TLV header\n");
		return -EINVAL;
	}

	hdr_len = sizeof(hdr.id) + sizeof(hdr.version) + sizeof(hdr.data_len);
	data_len = be16_to_cpu(hdr.data_len);
	table_len = hdr_len + data_len;
	if (table_len > ONIE_TLV_MAX_LEN) {
		dev_err(dev, "Invalid ONIE TLV data length\n");
		return -EINVAL;
	}

	table = devm_kmalloc(dev, table_len, GFP_KERNEL);
	if (!table)
		return -ENOMEM;

	ret = nvmem_device_read(nvmem, 0, table_len, table);
	if (ret != table_len)
		return ret;

	if (!onie_tlv_crc_is_valid(dev, table_len, table))
		return -EINVAL;

	data = table + hdr_len;
	ret = onie_tlv_add_cells(dev, nvmem, data_len, data);
	if (ret)
		return ret;

	return 0;
}

static int onie_tlv_probe(struct nvmem_layout *layout)
{
	layout->add_cells = onie_tlv_parse_table;

	return nvmem_layout_register(layout);
}

static void onie_tlv_remove(struct nvmem_layout *layout)
{
	nvmem_layout_unregister(layout);
}

static const struct of_device_id onie_tlv_of_match_table[] = {
	{ .compatible = "onie,tlv-layout", },
	{},
};
MODULE_DEVICE_TABLE(of, onie_tlv_of_match_table);

static struct nvmem_layout_driver onie_tlv_layout = {
	.driver = {
		.name = "onie-tlv-layout",
		.of_match_table = onie_tlv_of_match_table,
	},
	.probe = onie_tlv_probe,
	.remove = onie_tlv_remove,
};
module_nvmem_layout_driver(onie_tlv_layout);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Miquel Raynal <miquel.raynal@bootlin.com>");
MODULE_DESCRIPTION("NVMEM layout driver for Onie TLV table parsing");
