// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright 2016 General Electric Company
 */

#include "vpd_reader.h"
#include <malloc.h>

#include <i2c.h>
#include <linux/bch.h>
#include <stdlib.h>
#include <dm/uclass.h>
#include <i2c_eeprom.h>
#include <hexdump.h>

/* BCH configuration */

const struct {
	int header_ecc_capability_bits;
	int data_ecc_capability_bits;
	unsigned int prim_poly;
	struct {
		int min;
		int max;
	} galois_field_order;
} bch_configuration = {
	.header_ecc_capability_bits = 4,
	.data_ecc_capability_bits = 16,
	.prim_poly = 0,
	.galois_field_order = {
		.min = 5,
		.max = 15,
	},
};

static int calculate_galois_field_order(size_t source_length)
{
	int gfo = bch_configuration.galois_field_order.min;

	for (; gfo < bch_configuration.galois_field_order.max &&
	     ((((1 << gfo) - 1) - ((int)source_length * 8)) < 0);
	     gfo++) {
	}

	if (gfo == bch_configuration.galois_field_order.max)
		return -1;

	return gfo + 1;
}

static int verify_bch(int ecc_bits, unsigned int prim_poly, u8 *data,
		      size_t data_length, const u8 *ecc, size_t ecc_length)
{
	int gfo = calculate_galois_field_order(data_length);

	if (gfo < 0)
		return -1;

	struct bch_control *bch = init_bch(gfo, ecc_bits, prim_poly);

	if (!bch)
		return -1;

	if (bch->ecc_bytes != ecc_length) {
		free_bch(bch);
		return -1;
	}

	unsigned int *errloc = (unsigned int *)calloc(data_length,
						      sizeof(unsigned int));
	int errors = decode_bch(bch, data, data_length, ecc, NULL, NULL,
				errloc);

	free_bch(bch);
	if (errors < 0) {
		free(errloc);
		return -1;
	}

	if (errors > 0) {
		for (int n = 0; n < errors; n++) {
			if (errloc[n] >= 8 * data_length) {
				/*
				 * n-th error located in ecc (no need for data
				 * correction)
				 */
			} else {
				/* n-th error located in data */
				data[errloc[n] / 8] ^= 1 << (errloc[n] % 8);
			}
		}
	}

	free(errloc);
	return 0;
}

static const int ID;
static const int LEN = 1;
static const int VER = 2;
static const int TYP = 3;
static const int BLOCK_SIZE = 4;

static const u8 HEADER_BLOCK_ID;
static const u8 HEADER_BLOCK_LEN = 18;
static const u32 HEADER_BLOCK_MAGIC = 0xca53ca53;
static const size_t HEADER_BLOCK_VERIFY_LEN = 14;
static const size_t HEADER_BLOCK_ECC_OFF = 14;
static const size_t HEADER_BLOCK_ECC_LEN = 4;

static const u8 ECC_BLOCK_ID = 0xFF;

static int vpd_reader(size_t size, u8 *data, struct vpd_cache *userdata,
		      int (*fn)(struct vpd_cache *, u8 id, u8 version, u8 type,
				size_t size, u8 const *data))
{
	if (size < HEADER_BLOCK_LEN || !data || !fn)
		return -EINVAL;

	/*
	 * +--------------------+----------------+--//--+--------------------+
	 * | header block       | data block     | ...  | ecc block          |
	 * +--------------------+----------------+--//--+--------------------+
	 * :                    :                       :
	 * +------+-------+-----+                       +------+-------------+
	 * | id   | magic | ecc |                       | ...  | ecc         |
	 * | len  | off   |     |                       +------+-------------+
	 * | ver  | size  |     |                       :
	 * | type |       |     |                       :
	 * +------+-------+-----+                       :
	 * :              :     :                       :
	 * <----- [1] ---->     <--------- [2] --------->
	 *
	 * Repair (if necessary) the contents of header block [1] by using a
	 * 4 byte ECC located at the end of the header block.  A successful
	 * return value means that we can trust the header.
	 */
	int ret = verify_bch(bch_configuration.header_ecc_capability_bits,
			     bch_configuration.prim_poly, data,
			     HEADER_BLOCK_VERIFY_LEN,
			     &data[HEADER_BLOCK_ECC_OFF], HEADER_BLOCK_ECC_LEN);
	if (ret < 0)
		return ret;

	/* Validate header block { id, length, version, type }. */
	if (data[ID] != HEADER_BLOCK_ID || data[LEN] != HEADER_BLOCK_LEN ||
	    data[VER] != 0 || data[TYP] != 0 ||
	    ntohl(*(u32 *)(&data[4])) != HEADER_BLOCK_MAGIC)
		return -EINVAL;

	u32 offset = ntohl(*(u32 *)(&data[8]));
	u16 size_bits = ntohs(*(u16 *)(&data[12]));

	/* Check that ECC header fits. */
	if (offset + 3 >= size)
		return -EINVAL;

	/* Validate ECC block. */
	u8 *ecc = &data[offset];

	if (ecc[ID] != ECC_BLOCK_ID || ecc[LEN] < BLOCK_SIZE ||
	    ecc[LEN] + offset > size ||
	    ecc[LEN] - BLOCK_SIZE != size_bits / 8 || ecc[VER] != 1 ||
	    ecc[TYP] != 1)
		return -EINVAL;

	/*
	 * Use the header block to locate the ECC block and verify the data
	 * blocks [2] against the ecc block ECC.
	 */
	ret = verify_bch(bch_configuration.data_ecc_capability_bits,
			 bch_configuration.prim_poly, &data[data[LEN]],
			 offset - data[LEN], &data[offset + BLOCK_SIZE],
			 ecc[LEN] - BLOCK_SIZE);
	if (ret < 0)
		return ret;

	/* Stop after ECC.  Ignore possible zero padding. */
	size = offset;

	for (;;) {
		/* Move to next block. */
		size -= data[LEN];
		data += data[LEN];

		if (size == 0) {
			/* Finished iterating through blocks. */
			return 0;
		}

		if (size < BLOCK_SIZE || data[LEN] < BLOCK_SIZE) {
			/* Not enough data for a header, or short header. */
			return -EINVAL;
		}

		ret = fn(userdata, data[ID], data[VER], data[TYP],
			 data[LEN] - BLOCK_SIZE, &data[BLOCK_SIZE]);
		if (ret)
			return ret;
	}
}

int read_vpd(struct vpd_cache *cache,
	     int (*process_block)(struct vpd_cache *, u8 id, u8 version,
				  u8 type, size_t size, u8 const *data))
{
	struct udevice *dev;
	int ret;
	u8 *data;
	int size;

	ret = uclass_get_device_by_name(UCLASS_I2C_EEPROM, "vpd", &dev);
	if (ret)
		return ret;

	size = i2c_eeprom_size(dev);
	if (size < 0) {
		printf("Unable to get size of eeprom: %d\n", ret);
		return ret;
	}

	data = malloc(size);
	if (!data)
		return -ENOMEM;

	ret = i2c_eeprom_read(dev, 0, data, size);
	if (ret) {
		free(data);
		return ret;
	}

	ret = vpd_reader(size, data, cache, process_block);

	free(data);

	return ret;
}
