/* SPDX-License-Identifier: GPL-2.0-only */

#include <console/console.h>
#include <string.h>
#include <delay.h>
#include <stdlib.h>

#include "ipmi_if.h"
#include "ipmi_ops.h"

#define MAX_FRU_BUSY_RETRY 5
#define READ_FRU_DATA_RETRY_INTERVAL_MS 30 /* From IPMI spec v2.0 rev 1.1 */
#define OFFSET_LENGTH_MULTIPLIER 8 /* offsets/lengths are multiples of 8 */
#define NUM_DATA_BYTES(t) (t & 0x3f) /* Encoded in type/length byte */
#define FRU_END_OF_FIELDS 0xc1 /* type/length byte encoded to indicate no more info fields */

static enum cb_err ipmi_read_fru(const int port, struct ipmi_read_fru_data_req *req,
			uint8_t *fru_data)
{
	int ret;
	uint8_t total_size;
	uint16_t offset = 0;
	struct ipmi_read_fru_data_rsp rsp;
	int retry_count = 0;

	if (req == NULL || fru_data == NULL) {
		printk(BIOS_ERR, "%s failed, null pointer parameter\n",
			 __func__);
		return CB_ERR;
	}

	total_size = req->count;
	do {
		if (req->count > CONFIG_IPMI_FRU_SINGLE_RW_SZ)
			req->count = CONFIG_IPMI_FRU_SINGLE_RW_SZ;

		while (retry_count <= MAX_FRU_BUSY_RETRY) {
			ret = ipmi_message(port, IPMI_NETFN_STORAGE, 0x0,
					IPMI_READ_FRU_DATA, (const unsigned char *)req,
					sizeof(*req), (unsigned char *)&rsp, sizeof(rsp));
			if (rsp.resp.completion_code == 0x81) {
				/* Device is busy */
				if (retry_count == MAX_FRU_BUSY_RETRY) {
					printk(BIOS_ERR, "IPMI: %s command failed, "
						"device busy timeout\n", __func__);
					return CB_ERR;
				}
				printk(BIOS_ERR, "IPMI: FRU device is busy, "
					"retry count:%d\n", retry_count);
				retry_count++;
				mdelay(READ_FRU_DATA_RETRY_INTERVAL_MS);
			} else if (ret < sizeof(struct ipmi_rsp) || rsp.resp.completion_code) {
				printk(BIOS_ERR, "IPMI: %s command failed (ret=%d resp=0x%x)\n",
					__func__, ret, rsp.resp.completion_code);
				return CB_ERR;
			}
			break;
		}
		retry_count = 0;
		memcpy(fru_data + offset, rsp.data, rsp.count);
		offset += rsp.count;
		total_size -= rsp.count;
		req->fru_offset += rsp.count;
		req->count = total_size;
	} while (total_size > 0);

	return CB_SUCCESS;
}

/* data: data to check, offset: offset to checksum. */
static uint8_t checksum(uint8_t *data, int offset)
{
	uint8_t c = 0;
	for (; offset > 0; offset--, data++)
		c += *data;
	return -c;
}

static uint8_t data2str(const uint8_t *frudata, char *stringdata, uint8_t length)
{
	uint8_t type;

	/* bit[7:6] is the type code. */
	type = ((frudata[0] & 0xc0) >> 6);
	if (type != ASCII_8BIT) {
		printk(BIOS_ERR, "%s typecode %d is unsupported, FRU string only "
			"supports 8-bit ASCII + Latin 1 for now.\n", __func__, type);
		return 0;
	}
	/* In the spec the string data is always the next byte to the type/length byte. */
	memcpy(stringdata, frudata + 1, length);
	stringdata[length] = '\0';
	return length;
}

/*
 * Read data string from data_ptr and store it to string, return the
 * length of the string or 0 when it's failed.
 */
static int read_data_string(const uint8_t *data_ptr, char **string)
{
	uint8_t length;

	length = NUM_DATA_BYTES(data_ptr[0]);
	if (length == 0) {
		printk(BIOS_DEBUG, "%s:%d - failed due to length is zero\n", __func__,
			__LINE__);
		return 0;
	}

	*string = malloc(length + 1);
	if (!*string) {
		printk(BIOS_ERR, "%s failed to malloc %d bytes for string data.\n", __func__,
			length + 1);
		return 0;
	}
	if (!data2str((const uint8_t *)data_ptr, *string, length)) {
		printk(BIOS_ERR, "%s:%d - data2str failed\n", __func__, __LINE__);
		free(*string);
		return 0;
	}

	return length;
}

static enum cb_err read_fru_chassis_info_area(const int port, const uint8_t id,
				uint8_t offset, struct fru_chassis_info *info)
{
	uint8_t length;
	struct ipmi_read_fru_data_req req;
	uint8_t *data_ptr, *end, *custom_data_ptr;
	int ret = CB_SUCCESS;

	if (!offset)
		return CB_ERR;

	offset = offset * OFFSET_LENGTH_MULTIPLIER;
	req.fru_device_id = id;
	/* Read Chassis Info Area length first. */
	req.fru_offset = offset + 1;
	req.count = sizeof(length);
	if (ipmi_read_fru(port, &req, &length) != CB_SUCCESS || !length) {
		printk(BIOS_ERR, "%s failed, length: %d\n", __func__, length);
		return CB_ERR;
	}
	length = length * OFFSET_LENGTH_MULTIPLIER;
	data_ptr = (uint8_t *)malloc(length);
	if (!data_ptr) {
		printk(BIOS_ERR, "malloc %d bytes for chassis info failed\n", length);
		return CB_ERR;
	}
	end = data_ptr + length;
	/* Read Chassis Info Area data. */
	req.fru_offset = offset;
	req.count = length;
	if (ipmi_read_fru(port, &req, data_ptr) != CB_SUCCESS) {
		printk(BIOS_ERR, "%s failed to read fru\n", __func__);
		ret = CB_ERR;
		goto out;
	}
	if (checksum(data_ptr, length)) {
		printk(BIOS_ERR, "Bad FRU chassis info checksum.\n");
		ret = CB_ERR;
		goto out;
	}
	/* Read chassis type. */
	info->chassis_type = data_ptr[CHASSIS_TYPE_OFFSET];

	printk(BIOS_DEBUG, "Read chassis part number string.\n");
	length = read_data_string(data_ptr + CHASSIS_TYPE_OFFSET + 1,
		&info->chassis_partnumber);

	printk(BIOS_DEBUG, "Read chassis serial number string.\n");
	data_ptr += CHASSIS_TYPE_OFFSET + 1 + length + 1;
	length = read_data_string(data_ptr, &info->serial_number);

	printk(BIOS_DEBUG, "Read custom chassis info fields.\n");
	data_ptr += length + 1;
	/* Check how many valid custom fields first. */
	info->custom_count = 0;
	custom_data_ptr = data_ptr;
	while ((data_ptr < end) && ((data_ptr[0] != FRU_END_OF_FIELDS))) {
		length = NUM_DATA_BYTES(data_ptr[0]);
		if (length > 0)
			info->custom_count++;
		data_ptr += length + 1;
	}
	if (!info->custom_count)
		goto out;

	info->chassis_custom = malloc(info->custom_count * sizeof(char *));
	if (!info->chassis_custom) {
		printk(BIOS_ERR, "%s failed to malloc %zu bytes for "
			"chassis custom data array.\n", __func__,
			info->custom_count * sizeof(char *));
		ret = CB_ERR;
		goto out;
	}

	/* Start reading custom chassis data. */
	data_ptr = custom_data_ptr;
	int count = 0;
	while ((data_ptr < end) && ((data_ptr[0] != FRU_END_OF_FIELDS))) {
		length = NUM_DATA_BYTES(data_ptr[0]);
		if (length > 0) {
			length = read_data_string(data_ptr, info->chassis_custom + count);
			count++;
		}
		data_ptr += length + 1;
	}

out:
	free(data_ptr);
	return ret;
}

static enum cb_err read_fru_board_info_area(const int port, const uint8_t id,
				uint8_t offset, struct fru_board_info *info)
{
	uint8_t length;
	struct ipmi_read_fru_data_req req;
	uint8_t *data_ptr, *end, *custom_data_ptr;
	int ret = CB_SUCCESS;

	if (!offset)
		return CB_ERR;

	offset = offset * OFFSET_LENGTH_MULTIPLIER;
	req.fru_device_id = id;
	/* Read Board Info Area length first. */
	req.fru_offset = offset + 1;
	req.count = sizeof(length);
	if (ipmi_read_fru(port, &req, &length) != CB_SUCCESS || !length) {
		printk(BIOS_ERR, "%s failed, length: %d\n", __func__, length);
		return CB_ERR;
	}
	length = length * OFFSET_LENGTH_MULTIPLIER;
	data_ptr = (uint8_t *)malloc(length);
	if (!data_ptr) {
		printk(BIOS_ERR, "malloc %d bytes for board info failed\n", length);
		return CB_ERR;
	}
	end = data_ptr + length;
	/* Read Board Info Area data. */
	req.fru_offset = offset;
	req.count = length;
	if (ipmi_read_fru(port, &req, data_ptr) != CB_SUCCESS) {
		printk(BIOS_ERR, "%s failed to read fru\n", __func__);
		ret = CB_ERR;
		goto out;
	}
	if (checksum(data_ptr, length)) {
		printk(BIOS_ERR, "Bad FRU board info checksum.\n");
		ret = CB_ERR;
		goto out;
	}
	printk(BIOS_DEBUG, "Read board manufacturer string\n");
	length = read_data_string(data_ptr + BOARD_MAN_TYPE_LEN_OFFSET,
		&info->manufacturer);

	printk(BIOS_DEBUG, "Read board product name string.\n");
	data_ptr += BOARD_MAN_TYPE_LEN_OFFSET + length + 1;
	length = read_data_string(data_ptr, &info->product_name);

	printk(BIOS_DEBUG, "Read board serial number string.\n");
	data_ptr += length + 1;
	length = read_data_string(data_ptr, &info->serial_number);

	printk(BIOS_DEBUG, "Read board part number string.\n");
	data_ptr += length + 1;
	length = read_data_string(data_ptr, &info->part_number);

	printk(BIOS_DEBUG, "Read board FRU file ID string.\n");
	data_ptr += length + 1;
	length = read_data_string(data_ptr, &info->fru_file_id);

	/* Check how many valid custom fields first. */
	data_ptr += length + 1;
	info->custom_count = 0;
	custom_data_ptr = data_ptr;
	while ((data_ptr < end) && ((data_ptr[0] != FRU_END_OF_FIELDS))) {
		length = NUM_DATA_BYTES(data_ptr[0]);
		if (length > 0)
			info->custom_count++;
		data_ptr += length + 1;
	}
	if (!info->custom_count)
		goto out;

	info->board_custom = malloc(info->custom_count * sizeof(char *));
	if (!info->board_custom) {
		printk(BIOS_ERR, "%s failed to malloc %zu bytes for "
			"board custom data array.\n", __func__,
			info->custom_count * sizeof(char *));
		ret = CB_ERR;
		goto out;
	}

	/* Start reading custom board data. */
	data_ptr = custom_data_ptr;
	int count = 0;
	while ((data_ptr < end) && ((data_ptr[0] != FRU_END_OF_FIELDS))) {
		length = NUM_DATA_BYTES(data_ptr[0]);
		if (length > 0) {
			length = read_data_string(data_ptr, info->board_custom + count);
			count++;
		}
		data_ptr += length + 1;
	}

out:
	free(data_ptr);
	return ret;
}

static enum cb_err read_fru_product_info_area(const int port, const uint8_t id,
				uint8_t offset, struct fru_product_info *info)
{
	uint8_t length;
	struct ipmi_read_fru_data_req req;
	uint8_t *data_ptr, *end, *custom_data_ptr;
	int ret = CB_SUCCESS;

	if (!offset)
		return CB_ERR;

	offset = offset * OFFSET_LENGTH_MULTIPLIER;
	req.fru_device_id = id;
	/* Read Product Info Area length first. */
	req.fru_offset = offset + 1;
	req.count = sizeof(length);
	if (ipmi_read_fru(port, &req, &length) != CB_SUCCESS || !length) {
		printk(BIOS_ERR, "%s failed, length: %d\n", __func__, length);
		return CB_ERR;
	}
	length = length * OFFSET_LENGTH_MULTIPLIER;
	data_ptr = (uint8_t *)malloc(length);
	if (!data_ptr) {
		printk(BIOS_ERR, "malloc %d bytes for product info failed\n", length);
		return CB_ERR;
	}
	end = data_ptr + length;
	/* Read Product Info Area data. */
	req.fru_offset = offset;
	req.count = length;
	if (ipmi_read_fru(port, &req, data_ptr) != CB_SUCCESS) {
		printk(BIOS_ERR, "%s failed to read fru\n", __func__);
		ret = CB_ERR;
		goto out;
	}
	if (checksum(data_ptr, length)) {
		printk(BIOS_ERR, "Bad FRU product info checksum.\n");
		ret = CB_ERR;
		goto out;
	}
	printk(BIOS_DEBUG, "Read product manufacturer string.\n");
	length = read_data_string(data_ptr + PRODUCT_MAN_TYPE_LEN_OFFSET,
		&info->manufacturer);

	data_ptr += PRODUCT_MAN_TYPE_LEN_OFFSET + length + 1;
	printk(BIOS_DEBUG, "Read product_name string.\n");
	length = read_data_string(data_ptr, &info->product_name);

	data_ptr += length + 1;
	printk(BIOS_DEBUG, "Read product part/model number.\n");
	length = read_data_string(data_ptr, &info->product_partnumber);

	data_ptr += length + 1;
	printk(BIOS_DEBUG, "Read product version string.\n");
	length = read_data_string(data_ptr, &info->product_version);

	data_ptr += length + 1;
	printk(BIOS_DEBUG, "Read serial number string.\n");
	length = read_data_string(data_ptr, &info->serial_number);

	data_ptr += length + 1;
	printk(BIOS_DEBUG, "Read asset tag string.\n");
	length = read_data_string(data_ptr, &info->asset_tag);

	printk(BIOS_DEBUG, "Read product FRU file ID string.\n");
	data_ptr += length + 1;
	length = read_data_string(data_ptr, &info->fru_file_id);

	/* Check how many valid custom fields first. */
	data_ptr += length + 1;
	info->custom_count = 0;
	custom_data_ptr = data_ptr;
	while ((data_ptr < end) && ((data_ptr[0] != FRU_END_OF_FIELDS))) {
		length = NUM_DATA_BYTES(data_ptr[0]);
		if (length > 0)
			info->custom_count++;
		data_ptr += length + 1;
	}
	if (!info->custom_count)
		goto out;

	info->product_custom = malloc(info->custom_count * sizeof(char *));
	if (!info->product_custom) {
		printk(BIOS_ERR, "%s failed to malloc %zu bytes for "
			"product custom data array.\n", __func__,
			info->custom_count * sizeof(char *));
		ret = CB_ERR;
		goto out;
	}

	/* Start reading custom product data. */
	data_ptr = custom_data_ptr;
	int count = 0;
	while ((data_ptr < end) && ((data_ptr[0] != FRU_END_OF_FIELDS))) {
		length = NUM_DATA_BYTES(data_ptr[0]);
		if (length > 0) {
			length = read_data_string(data_ptr, info->product_custom + count);
			count++;
		}
		data_ptr += length + 1;
	}

out:
	free(data_ptr);
	return ret;
}

void read_fru_areas(const int port, const uint8_t id, uint16_t offset,
			struct fru_info_str *fru_info_str)
{
	struct ipmi_read_fru_data_req req;
	struct ipmi_fru_common_hdr fru_common_hdr;

	/* Set all the char pointers to 0 first, to avoid mainboard
	 * overwriting SMBIOS string with any non-NULL char pointer
	 * by accident. */
	memset(fru_info_str, 0, sizeof(*fru_info_str));
	req.fru_device_id = id;
	req.fru_offset = offset;
	req.count = sizeof(fru_common_hdr);
	/* Read FRU common header first */
	if (ipmi_read_fru(port, &req, (uint8_t *)&fru_common_hdr) == CB_SUCCESS) {
		if (checksum((uint8_t *)&fru_common_hdr, sizeof(fru_common_hdr))) {
			printk(BIOS_ERR, "Bad FRU common header checksum.\n");
			return;
		}
		printk(BIOS_DEBUG, "FRU common header: format_version: %x\n"
			"product_area_offset: %x\n"
			"board_area_offset: %x\n"
			"chassis_area_offset: %x\n",
			fru_common_hdr.format_version,
			fru_common_hdr.product_area_offset,
			fru_common_hdr.board_area_offset,
			fru_common_hdr.chassis_area_offset);
	} else {
		printk(BIOS_ERR, "Read FRU common header failed\n");
		return;
	}

	read_fru_product_info_area(port, id, fru_common_hdr.product_area_offset,
		&fru_info_str->prod_info);
	read_fru_board_info_area(port, id, fru_common_hdr.board_area_offset,
		&fru_info_str->board_info);
	read_fru_chassis_info_area(port, id, fru_common_hdr.chassis_area_offset,
		&fru_info_str->chassis_info);
}

void read_fru_one_area(const int port, const uint8_t id, uint16_t offset,
			struct fru_info_str *fru_info_str, enum fru_area fru_area)
{
	struct ipmi_read_fru_data_req req;
	struct ipmi_fru_common_hdr fru_common_hdr;

	req.fru_device_id = id;
	req.fru_offset = offset;
	req.count = sizeof(fru_common_hdr);
	if (ipmi_read_fru(port, &req, (uint8_t *)&fru_common_hdr) == CB_SUCCESS) {
		if (checksum((uint8_t *)&fru_common_hdr, sizeof(fru_common_hdr))) {
			printk(BIOS_ERR, "Bad FRU common header checksum.\n");
			return;
		}
		printk(BIOS_DEBUG, "FRU common header: format_version: %x\n"
			"product_area_offset: %x\n"
			"board_area_offset: %x\n"
			"chassis_area_offset: %x\n",
			fru_common_hdr.format_version,
			fru_common_hdr.product_area_offset,
			fru_common_hdr.board_area_offset,
			fru_common_hdr.chassis_area_offset);
	} else {
		printk(BIOS_ERR, "Read FRU common header failed\n");
		return;
	}

	switch (fru_area) {
	case PRODUCT_INFO_AREA:
		memset(&fru_info_str->prod_info, 0, sizeof(fru_info_str->prod_info));
		read_fru_product_info_area(port, id, fru_common_hdr.product_area_offset,
			&fru_info_str->prod_info);
		break;
	case BOARD_INFO_AREA:
		memset(&fru_info_str->board_info, 0, sizeof(fru_info_str->board_info));
		read_fru_board_info_area(port, id, fru_common_hdr.board_area_offset,
			&fru_info_str->board_info);
		break;
	case CHASSIS_INFO_AREA:
		memset(&fru_info_str->chassis_info, 0, sizeof(fru_info_str->chassis_info));
		read_fru_chassis_info_area(port, id, fru_common_hdr.chassis_area_offset,
			&fru_info_str->chassis_info);
		break;
	default:
		printk(BIOS_ERR, "Invalid fru_area: %d\n", fru_area);
		break;
	}
}

void print_fru_areas(struct fru_info_str *fru_info_str)
{
	int count = 0;
	if (fru_info_str == NULL) {
		printk(BIOS_ERR, "FRU data is null pointer\n");
		return;
	}
	struct fru_product_info prod_info = fru_info_str->prod_info;
	struct fru_board_info board_info = fru_info_str->board_info;
	struct fru_chassis_info chassis_info = fru_info_str->chassis_info;

	printk(BIOS_DEBUG, "Printing Product Info Area...\n");
	if (prod_info.manufacturer != NULL)
		printk(BIOS_DEBUG, "manufacturer: %s\n", prod_info.manufacturer);
	if (prod_info.product_name != NULL)
		printk(BIOS_DEBUG, "product name: %s\n", prod_info.product_name);
	if (prod_info.product_partnumber != NULL)
		printk(BIOS_DEBUG, "product part number: %s\n", prod_info.product_partnumber);
	if (prod_info.product_version != NULL)
		printk(BIOS_DEBUG, "product version: %s\n", prod_info.product_version);
	if (prod_info.serial_number != NULL)
		printk(BIOS_DEBUG, "serial number: %s\n", prod_info.serial_number);
	if (prod_info.asset_tag != NULL)
		printk(BIOS_DEBUG, "asset tag: %s\n", prod_info.asset_tag);
	if (prod_info.fru_file_id != NULL)
		printk(BIOS_DEBUG, "FRU file ID: %s\n", prod_info.fru_file_id);

	for (count = 0; count < prod_info.custom_count; count++) {
		if (*(prod_info.product_custom + count) != NULL)
			printk(BIOS_DEBUG, "product custom data %i: %s\n", count,
				*(prod_info.product_custom + count));
	}

	printk(BIOS_DEBUG, "Printing Board Info Area...\n");
	if (board_info.manufacturer != NULL)
		printk(BIOS_DEBUG, "manufacturer: %s\n", board_info.manufacturer);
	if (board_info.product_name != NULL)
		printk(BIOS_DEBUG, "product name: %s\n", board_info.product_name);
	if (board_info.serial_number != NULL)
		printk(BIOS_DEBUG, "serial number: %s\n", board_info.serial_number);
	if (board_info.part_number != NULL)
		printk(BIOS_DEBUG, "part number: %s\n", board_info.part_number);
	if (board_info.fru_file_id != NULL)
		printk(BIOS_DEBUG, "FRU file ID: %s\n", board_info.fru_file_id);

	for (count = 0; count < board_info.custom_count; count++) {
		if (*(board_info.board_custom + count) != NULL)
			printk(BIOS_DEBUG, "board custom data %i: %s\n", count,
				*(board_info.board_custom + count));
	}

	printk(BIOS_DEBUG, "Printing Chassis Info Area...\n");
	printk(BIOS_DEBUG, "chassis type: 0x%x\n", chassis_info.chassis_type);
	if (chassis_info.chassis_partnumber != NULL)
		printk(BIOS_DEBUG, "part number: %s\n", chassis_info.chassis_partnumber);
	if (chassis_info.serial_number != NULL)
		printk(BIOS_DEBUG, "serial number: %s\n", chassis_info.serial_number);

	for (count = 0; count < chassis_info.custom_count; count++) {
		if (*(chassis_info.chassis_custom + count) != NULL)
			printk(BIOS_DEBUG, "chassis custom data %i: %s\n", count,
				*(chassis_info.chassis_custom + count));
	}
}
