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

#include <compiler.h>
#include <tlv_eeprom.h>
#include <linux/kernel.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];

	/* extension with additional data field for number of ddr channels */
	if (tlv_entry->length >= 7) {
		td->ram_channels = val[6];
	}
}

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;
}
