// SPDX-License-Identifier: GPL-2.0
/*
 * (C) Copyright 2019 - 2020 Xilinx, Inc.
 */

#include <common.h>
#include <cpu_func.h>
#include <env.h>
#include <fdtdec.h>
#include <log.h>
#include <malloc.h>
#include <net.h>
#include <asm/io.h>
#include <asm/arch/hardware.h>

#include "fru.h"

struct fru_table fru_data __section(".data");

static u16 fru_cal_area_len(u8 len)
{
	return len * FRU_COMMON_HDR_LEN_MULTIPLIER;
}

static u8 fru_version(u8 ver)
{
	return ver & FRU_COMMON_HDR_VER_MASK;
}

static int fru_check_language(u8 code)
{
	if (code != FRU_LANG_CODE_ENGLISH && code != FRU_LANG_CODE_ENGLISH_1) {
		printf("FRU_ERROR: Only English Language is supported\n");
		return -EINVAL;
	}

	return 0;
}

u8 fru_checksum(u8 *addr, u8 len)
{
	u8 checksum = 0;
	u8 cnt = len;

	while (len--) {
		if (*addr == 0)
			cnt--;

		checksum += *addr;
		addr++;
	}

	/* If all data bytes are 0's return error */
	if (!cnt)
		return EINVAL;

	return checksum;
}

static int fru_check_type_len(u8 type_len, u8 language, u8 *type)
{
	int len;

	if (type_len == FRU_TYPELEN_EOF)
		return -EINVAL;

	*type = (type_len & FRU_TYPELEN_CODE_MASK) >> FRU_TYPELEN_TYPE_SHIFT;

	len = type_len & FRU_TYPELEN_LEN_MASK;

	return len;
}

/* Return len */
static u8 fru_gen_type_len(u8 *addr, char *name)
{
	int len = strlen(name);
	struct fru_board_info_member *member;

	member = (struct fru_board_info_member *)addr;
	member->type_len = FRU_TYPELEN_TYPE_ASCII8 << FRU_TYPELEN_TYPE_SHIFT;
	member->type_len |= len;

	debug("%lx/%lx: Add %s to 0x%lx (len 0x%x)\n", (ulong)addr,
	      (ulong)&member->type_len,  name, (ulong)&member->name, len);
	memcpy(&member->name, name, len);

	/* Add +1 for type_len parameter */
	return 1 + len;
}

int fru_generate(unsigned long addr, char *manufacturer, char *board_name,
		 char *serial_no, char *part_no, char *revision)
{
	struct fru_common_hdr *header = (struct fru_common_hdr *)addr;
	struct fru_board_info_header *board_info;
	u8 *member;
	u8 len, pad, modulo;

	header->version = 1; /* Only version 1.0 is supported now */
	header->off_internal = 0; /* not present */
	header->off_chassis = 0; /* not present */
	header->off_board = (sizeof(*header)) / 8; /* Starting offset 8 */
	header->off_product = 0; /* not present */
	header->off_multirec = 0; /* not present */
	header->pad = 0;
	/*
	 * This unsigned byte can be used to calculate a zero checksum
	 * for the data area following the header. I.e. the modulo 256 sum of
	 * the record data bytes plus the checksum byte equals zero.
	 */
	header->crc = 0; /* Clear before calculation */
	header->crc = 0 - fru_checksum((u8 *)header, sizeof(*header));

	/* board info is just right after header */
	board_info = (void *)((u8 *)header + sizeof(*header));

	debug("header %lx, board_info %lx\n", (ulong)header, (ulong)board_info);

	board_info->ver = 1; /* 1.0 spec */
	board_info->lang_code = 0; /* English */
	board_info->time[0] = 0; /* unspecified */
	board_info->time[1] = 0; /* unspecified */
	board_info->time[2] = 0; /* unspecified */

	/* Member fields are just after board_info header */
	member = (u8 *)board_info + sizeof(*board_info);

	len = fru_gen_type_len(member, manufacturer); /* Board Manufacturer */
	member += len;
	len = fru_gen_type_len(member, board_name); /* Board Product name */
	member += len;
	len = fru_gen_type_len(member, serial_no); /* Board Serial number */
	member += len;
	len = fru_gen_type_len(member, part_no); /* Board part number */
	member += len;
	len = fru_gen_type_len(member, "U-Boot generator"); /* File ID */
	member += len;
	len = fru_gen_type_len(member, revision); /* Revision */
	member += len;

	*member++ = 0xc1; /* Indication of no more fields */

	len = member - (u8 *)board_info; /* Find current length */
	len += 1; /* Add checksum there too for calculation */

	modulo = len % 8;

	if (modulo) {
		/* Do not fill last item which is checksum */
		for (pad = 0; pad < 8 - modulo; pad++)
			*member++ = 0;

		/* Increase structure size */
		len += 8 - modulo;
	}

	board_info->len = len / 8; /* Size in multiples of 8 bytes */

	*member = 0; /* Clear before calculation */
	*member = 0 - fru_checksum((u8 *)board_info, len);

	debug("checksum %x(addr %x)\n", *member, len);

	env_set_hex("fru_addr", addr);
	env_set_hex("filesize", (unsigned long)member - addr + 1);

	return 0;
}

static int fru_parse_board(unsigned long addr)
{
	u8 i, type;
	int len;
	u8 *data, *term, *limit;

	memcpy(&fru_data.brd.ver, (void *)addr, 6);
	addr += 6;
	data = (u8 *)&fru_data.brd.manufacturer_type_len;

	/* Record max structure limit not to write data over allocated space */
	limit = (u8 *)&fru_data.brd + sizeof(struct fru_board_data);

	for (i = 0; ; i++, data += FRU_BOARD_MAX_LEN) {
		len = fru_check_type_len(*(u8 *)addr, fru_data.brd.lang_code,
					 &type);
		/*
		 * Stop cature if it end of fields
		 */
		if (len == -EINVAL)
			break;

		/* Stop when amount of chars is more then fields to record */
		if (data + len > limit)
			break;
		/* This record type/len field */
		*data++ = *(u8 *)addr;

		/* Add offset to match data */
		addr += 1;

		/* If len is 0 it means empty field that's why skip writing */
		if (!len)
			continue;

		/* Record data field */
		memcpy(data, (u8 *)addr, len);
		term = data + (u8)len;
		*term = 0;
		addr += len;
	}

	if (i < FRU_BOARD_AREA_TOTAL_FIELDS) {
		printf("Board area require minimum %d fields\n",
		       FRU_BOARD_AREA_TOTAL_FIELDS);
		return -EINVAL;
	}

	return 0;
}

static int fru_parse_multirec(unsigned long addr)
{
	struct fru_multirec_hdr mrc;
	u8 checksum = 0;
	u8 hdr_len = sizeof(struct fru_multirec_hdr);
	int mac_len = 0;

	debug("%s: multirec addr %lx\n", __func__, addr);

	do {
		memcpy(&mrc.rec_type, (void *)addr, hdr_len);

		checksum = fru_checksum((u8 *)addr, hdr_len);
		if (checksum) {
			debug("%s header CRC error\n", __func__);
			return -EINVAL;
		}

		if (mrc.rec_type == FRU_MULTIREC_TYPE_OEM) {
			struct fru_multirec_mac *mac = (void *)addr + hdr_len;
			u32 type = FRU_DUT_MACID;

			if (CONFIG_IS_ENABLED(FRU_SC))
				type = FRU_SC_MACID;

			if (mac->ver == type) {
				mac_len = mrc.len - FRU_MULTIREC_MAC_OFFSET;
				memcpy(&fru_data.mac.macid, mac->macid, mac_len);
			}
		}
		addr += mrc.len + hdr_len;
	} while (!(mrc.type & FRU_LAST_REC));

	return 0;
}

int fru_capture(unsigned long addr)
{
	struct fru_common_hdr *hdr;
	u8 checksum = 0;
	unsigned long multirec_addr = addr;

	checksum = fru_checksum((u8 *)addr, sizeof(struct fru_common_hdr));
	if (checksum) {
		printf("%s Common header CRC error\n", __func__);
		return -EINVAL;
	}

	hdr = (struct fru_common_hdr *)addr;
	memset((void *)&fru_data, 0, sizeof(fru_data));
	memcpy((void *)&fru_data, (void *)hdr,
	       sizeof(struct fru_common_hdr));

	fru_data.captured = true;

	if (hdr->off_board) {
		addr += fru_cal_area_len(hdr->off_board);
		fru_parse_board(addr);
	}

	env_set_hex("fru_addr", addr);

	if (hdr->off_multirec) {
		multirec_addr += fru_cal_area_len(hdr->off_multirec);
		fru_parse_multirec(multirec_addr);
	}

	return 0;
}

static int fru_display_board(struct fru_board_data *brd, int verbose)
{
	u32 time = 0;
	u8 type;
	int len;
	u8 *data;
	static const char * const typecode[] = {
		"Binary/Unspecified",
		"BCD plus",
		"6-bit ASCII",
		"8-bit ASCII",
		"2-byte UNICODE"
	};
	static const char * const boardinfo[] = {
		"Manufacturer Name",
		"Product Name",
		"Serial No",
		"Part Number",
		"File ID",
		/* Xilinx spec */
		"Revision Number",
	};

	if (verbose) {
		printf("*****BOARD INFO*****\n");
		printf("Version:%d\n", fru_version(brd->ver));
		printf("Board Area Length:%d\n", fru_cal_area_len(brd->len));
	}

	if (fru_check_language(brd->lang_code))
		return -EINVAL;

	time = brd->time[2] << 16 | brd->time[1] << 8 |
	       brd->time[0];

	if (verbose)
		printf("Time in Minutes from 0:00hrs 1/1/96: %d\n", time);

	data = (u8 *)&brd->manufacturer_type_len;

	for (u8 i = 0; i < (sizeof(boardinfo) / sizeof(*boardinfo)); i++) {
		len = fru_check_type_len(*data++, brd->lang_code,
					 &type);
		if (len == -EINVAL) {
			printf("**** EOF for Board Area ****\n");
			break;
		}

		if (type <= FRU_TYPELEN_TYPE_ASCII8 &&
		    (brd->lang_code == FRU_LANG_CODE_ENGLISH ||
		     brd->lang_code == FRU_LANG_CODE_ENGLISH_1))
			debug("Type code: %s\n", typecode[type]);
		else
			debug("Type code: %s\n", typecode[type + 1]);

		if (!len) {
			debug("%s not found\n", boardinfo[i]);
			continue;
		}

		switch (type) {
		case FRU_TYPELEN_TYPE_BINARY:
			debug("Length: %d\n", len);
			printf(" %s: 0x%x\n", boardinfo[i], *data);
			break;
		case FRU_TYPELEN_TYPE_ASCII8:
			debug("Length: %d\n", len);
			printf(" %s: %s\n", boardinfo[i], data);
			break;
		default:
			debug("Unsupported type %x\n", type);
		}

		data += FRU_BOARD_MAX_LEN;
	}

	return 0;
}

static void fru_display_common_hdr(struct fru_common_hdr *hdr, int verbose)
{
	if (!verbose)
		return;

	printf("*****COMMON HEADER*****\n");
	printf("Version:%d\n", fru_version(hdr->version));
	if (hdr->off_internal)
		printf("Internal Use Area Offset:%d\n",
		       fru_cal_area_len(hdr->off_internal));
	else
		printf("*** No Internal Area ***\n");

	if (hdr->off_chassis)
		printf("Chassis Info Area Offset:%d\n",
		       fru_cal_area_len(hdr->off_chassis));
	else
		printf("*** No Chassis Info Area ***\n");

	if (hdr->off_board)
		printf("Board Area Offset:%d\n",
		       fru_cal_area_len(hdr->off_board));
	else
		printf("*** No Board Area ***\n");

	if (hdr->off_product)
		printf("Product Info Area Offset:%d\n",
		       fru_cal_area_len(hdr->off_product));
	else
		printf("*** No Product Info Area ***\n");

	if (hdr->off_multirec)
		printf("MultiRecord Area Offset:%d\n",
		       fru_cal_area_len(hdr->off_multirec));
	else
		printf("*** No MultiRecord Area ***\n");
}

int fru_display(int verbose)
{
	if (!fru_data.captured) {
		printf("FRU data not available please run fru parse\n");
		return -EINVAL;
	}

	fru_display_common_hdr(&fru_data.hdr, verbose);

	return fru_display_board(&fru_data.brd, verbose);
}
