// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright 2020 SolidRun
 */

#include <common.h>
#include <tlv_eeprom.h>
#include "tlv_data.h"

#define SR_TLV_CODE_RAM_SIZE	0x81

static void store_product_name(struct tlvinfo_tlv *tlv_entry,
			       struct tlv_data *td)
{
	int len;
	char *dest;

	if (strlen(td->tlv_product_name[0]) == 0)
		dest = td->tlv_product_name[0];
	else if (strlen(td->tlv_product_name[1]) == 0)
		dest = td->tlv_product_name[1];
	else
		return;

	len = min_t(unsigned int, tlv_entry->length,
		    sizeof(td->tlv_product_name[0]) - 1);
	memcpy(dest, tlv_entry->value, len);
}

static void parse_tlv_vendor_ext(struct tlvinfo_tlv *tlv_entry,
				 struct tlv_data *td)
{
	u8 *val = tlv_entry->value;
	u32 pen; /* IANA Private Enterprise Numbers */

	if (tlv_entry->length < 5) /* 4 bytes PEN + at least 1 byte type */
		return;

	/* PEN is big endian */
	pen = (val[0] << 24) | (val[1] << 16) | (val[2] << 8) | val[3];
	/* Not a real PEN */
	if (pen != 0xffffffff)
		return;

	if (val[4] != SR_TLV_CODE_RAM_SIZE)
		return;
	if (tlv_entry->length != 6)
		return;
	td->ram_size = val[5];
}

static void parse_tlv_data(u8 *eeprom, struct tlvinfo_header *hdr,
			   struct tlvinfo_tlv *entry, struct tlv_data *td)
{
	unsigned int tlv_offset, tlv_len;

	tlv_offset = sizeof(struct tlvinfo_header);
	tlv_len = sizeof(struct tlvinfo_header) + be16_to_cpu(hdr->totallen);
	while (tlv_offset < tlv_len) {
		entry = (struct tlvinfo_tlv *)&eeprom[tlv_offset];

		switch (entry->type) {
		case TLV_CODE_PRODUCT_NAME:
			store_product_name(entry, td);
			break;
		case TLV_CODE_VENDOR_EXT:
			parse_tlv_vendor_ext(entry, td);
			break;
		default:
			break;
		}

		tlv_offset += sizeof(struct tlvinfo_tlv) + entry->length;
	}
}

void read_tlv_data(struct tlv_data *td)
{
	u8 eeprom_data[TLV_TOTAL_LEN_MAX];
	struct tlvinfo_header *tlv_hdr;
	struct tlvinfo_tlv *tlv_entry;
	int ret, i;

	for (i = 0; i < 2; i++) {
		ret = read_tlvinfo_tlv_eeprom(eeprom_data, &tlv_hdr,
					      &tlv_entry, i);
		if (ret < 0)
			continue;
		parse_tlv_data(eeprom_data, tlv_hdr, tlv_entry, td);
	}
}

bool sr_product_is(const struct tlv_data *td, const char *product)
{
	/* Allow prefix sub-string match */
	if (strncmp(td->tlv_product_name[0], product, strlen(product)) == 0)
		return true;
	if (strncmp(td->tlv_product_name[1], product, strlen(product)) == 0)
		return true;

	return false;
}
