/*
 * (C) Copyright 2011
 * Holger Brunck, Keymile GmbH Hannover, holger.brunck@keymile.com
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */

#include <common.h>
#include <hush.h>
#include <i2c.h>
#include "common.h"

static int ivm_calc_crc(unsigned char *buf, int len)
{
	const unsigned short crc_tab[16] = {
		0x0000, 0xCC01, 0xD801, 0x1400,
		0xF001, 0x3C00, 0x2800, 0xE401,
		0xA001, 0x6C00, 0x7800, 0xB401,
		0x5000, 0x9C01, 0x8801, 0x4400};

	unsigned short crc     = 0;   /* final result */
	unsigned short r1      = 0;   /* temp */
	unsigned char  byte    = 0;   /* input buffer */
	int	i;

	/* calculate CRC from array data */
	for (i = 0; i < len; i++) {
		byte = buf[i];

		/* lower 4 bits */
		r1 = crc_tab[crc & 0xF];
		crc = ((crc) >> 4) & 0x0FFF;
		crc = crc ^ r1 ^ crc_tab[byte & 0xF];

		/* upper 4 bits */
		r1 = crc_tab[crc & 0xF];
		crc = (crc >> 4) & 0x0FFF;
		crc = crc ^ r1 ^ crc_tab[(byte >> 4) & 0xF];
	}
	return crc;
}

static int ivm_set_value(char *name, char *value)
{
	char tempbuf[256];

	if (value != NULL) {
		sprintf(tempbuf, "%s=%s", name, value);
		return set_local_var(tempbuf, 0);
	} else {
		unset_local_var(name);
	}
	return 0;
}

static int ivm_get_value(unsigned char *buf, int len, char *name, int off,
				int check)
{
	unsigned short	val;
	unsigned char	valbuf[30];

	if ((buf[off + 0] != buf[off + 2]) &&
	    (buf[off + 2] != buf[off + 4])) {
		printf("%s Error corrupted %s\n", __func__, name);
		val = -1;
	} else {
		val = buf[off + 0] + (buf[off + 1] << 8);
		if ((val == 0) && (check == 1))
			val = -1;
	}
	sprintf((char *)valbuf, "%x", val);
	ivm_set_value(name, (char *)valbuf);
	return val;
}

#define INV_BLOCKSIZE		0x100
#define INV_DATAADDRESS		0x21
#define INVENTORYDATASIZE	(INV_BLOCKSIZE - INV_DATAADDRESS - 3)

#define IVM_POS_SHORT_TEXT		0
#define IVM_POS_MANU_ID			1
#define IVM_POS_MANU_SERIAL		2
#define IVM_POS_PART_NUMBER		3
#define IVM_POS_BUILD_STATE		4
#define IVM_POS_SUPPLIER_PART_NUMBER	5
#define IVM_POS_DELIVERY_DATE		6
#define IVM_POS_SUPPLIER_BUILD_STATE	7
#define IVM_POS_CUSTOMER_ID		8
#define IVM_POS_CUSTOMER_PROD_ID	9
#define IVM_POS_HISTORY			10
#define IVM_POS_SYMBOL_ONLY		11

static char convert_char(char c)
{
	return (c < ' ' || c > '~') ? '.' : c;
}

static int ivm_findinventorystring(int type,
					unsigned char *const string,
					unsigned long maxlen,
					unsigned char *buf)
{
	int xcode = 0;
	unsigned long cr = 0;
	unsigned long addr = INV_DATAADDRESS;
	unsigned long size = 0;
	unsigned long nr = type;
	int stop = 0;	/* stop on semicolon */

	memset(string, '\0', maxlen);
	switch (type) {
	case IVM_POS_SYMBOL_ONLY:
		nr = 0;
		stop = 1;
	break;
	default:
		nr = type;
		stop = 0;
	}

	/* Look for the requested number of CR. */
	while ((cr != nr) && (addr < INVENTORYDATASIZE)) {
		if ((buf[addr] == '\r'))
			cr++;
		addr++;
	}

	/*
	 * the expected number of CR was found until the end of the IVM
	 *  content --> fill string
	 */
	if (addr < INVENTORYDATASIZE) {
		/* Copy the IVM string in the corresponding string */
		for (; (buf[addr] != '\r')			&&
			((buf[addr] != ';') ||  (!stop))	&&
			(size < (maxlen - 1)			&&
			(addr < INVENTORYDATASIZE)); addr++) {
			size += sprintf((char *)string + size, "%c",
						convert_char (buf[addr]));
		}

		/*
		 * copy phase is done: check if everything is ok. If not,
		 * the inventory data is most probably corrupted: tell
		 * the world there is a problem!
		 */
		if (addr == INVENTORYDATASIZE) {
			xcode = -1;
			printf("Error end of string not found\n");
		} else if ((size > (maxlen - 1)) &&
			   (buf[addr] != '\r')) {
			xcode = -1;
			printf("string too long till next CR\n");
		}
	} else {
		/*
		 * some CR are missing...
		 * the inventory data is most probably corrupted
		 */
		xcode = -1;
		printf("not enough cr found\n");
	}
	return xcode;
}

#define GET_STRING(name, which, len) \
	if (ivm_findinventorystring(which, valbuf, len, buf) == 0) { \
		ivm_set_value(name, (char *)valbuf); \
	}

static int ivm_check_crc(unsigned char *buf, int block)
{
	unsigned long	crc;
	unsigned long	crceeprom;

	crc = ivm_calc_crc(buf, CONFIG_SYS_IVM_EEPROM_PAGE_LEN - 2);
	crceeprom = (buf[CONFIG_SYS_IVM_EEPROM_PAGE_LEN - 1] + \
			buf[CONFIG_SYS_IVM_EEPROM_PAGE_LEN - 2] * 256);
	if (crc != crceeprom) {
		if (block == 0)
			printf("Error CRC Block: %d EEprom: calculated: \
			%lx EEprom: %lx\n", block, crc, crceeprom);
		return -1;
	}
	return 0;
}

static int calculate_mac_offset(unsigned char *valbuf, unsigned char *buf,
				int offset)
{
	unsigned long val = (buf[4] << 16) + (buf[5] << 8) + buf[6];

	if (offset == 0)
		return 0;

	val += offset;
	buf[4] = (val >> 16) & 0xff;
	buf[5] = (val >> 8) & 0xff;
	buf[6] = val & 0xff;
	sprintf((char *)valbuf, "%pM", buf + 1);
	return 0;
}

static int ivm_analyze_block2(unsigned char *buf, int len)
{
	unsigned char	valbuf[CONFIG_SYS_IVM_EEPROM_PAGE_LEN];
	unsigned long	count;

	/* IVM_MAC Adress begins at offset 1 */
	sprintf((char *)valbuf, "%pM", buf + 1);
	ivm_set_value("IVM_MacAddress", (char *)valbuf);
	/* if an offset is defined, add it */
	calculate_mac_offset(buf, valbuf, CONFIG_PIGGY_MAC_ADRESS_OFFSET);
#ifdef MACH_TYPE_KM_KIRKWOOD
	setenv((char *)"ethaddr", (char *)valbuf);
#else
	if (getenv("ethaddr") == NULL)
		setenv((char *)"ethaddr", (char *)valbuf);
#endif
#ifdef CONFIG_KMVECT1
/* KMVECT1 has two ethernet interfaces */
	if (getenv("eth1addr") == NULL) {
		calculate_mac_offset(buf, valbuf, 1);
		setenv((char *)"eth1addr", (char *)valbuf);
	}
#endif
	/* IVM_MacCount */
	count = (buf[10] << 24) +
		   (buf[11] << 16) +
		   (buf[12] << 8)  +
		    buf[13];
	if (count == 0xffffffff)
		count = 1;
	sprintf((char *)valbuf, "%lx", count);
	ivm_set_value("IVM_MacCount", (char *)valbuf);
	return 0;
}

static int ivm_analyze_eeprom(unsigned char *buf, int len)
{
	unsigned short	val;
	unsigned char	valbuf[CONFIG_SYS_IVM_EEPROM_PAGE_LEN];
	unsigned char	*tmp;

	if (ivm_check_crc(buf, 0) != 0)
		return -1;

	ivm_get_value(buf, CONFIG_SYS_IVM_EEPROM_PAGE_LEN,
			"IVM_BoardId", 0, 1);
	val = ivm_get_value(buf, CONFIG_SYS_IVM_EEPROM_PAGE_LEN,
			"IVM_HWKey", 6, 1);
	if (val != 0xffff) {
		sprintf((char *)valbuf, "%x", ((val / 100) % 10));
		ivm_set_value("IVM_HWVariant", (char *)valbuf);
		sprintf((char *)valbuf, "%x", (val % 100));
		ivm_set_value("IVM_HWVersion", (char *)valbuf);
	}
	ivm_get_value(buf, CONFIG_SYS_IVM_EEPROM_PAGE_LEN,
		"IVM_Functions", 12, 0);

	GET_STRING("IVM_Symbol", IVM_POS_SYMBOL_ONLY, 8)
	GET_STRING("IVM_DeviceName", IVM_POS_SHORT_TEXT, 64)
	tmp = (unsigned char *) getenv("IVM_DeviceName");
	if (tmp) {
		int	len = strlen((char *)tmp);
		int	i = 0;

		while (i < len) {
			if (tmp[i] == ';') {
				ivm_set_value("IVM_ShortText",
					(char *)&tmp[i + 1]);
				break;
			}
			i++;
		}
		if (i >= len)
			ivm_set_value("IVM_ShortText", NULL);
	} else {
		ivm_set_value("IVM_ShortText", NULL);
	}
	GET_STRING("IVM_ManufacturerID", IVM_POS_MANU_ID, 32)
	GET_STRING("IVM_ManufacturerSerialNumber", IVM_POS_MANU_SERIAL, 20)
	GET_STRING("IVM_ManufacturerPartNumber", IVM_POS_PART_NUMBER, 32)
	GET_STRING("IVM_ManufacturerBuildState", IVM_POS_BUILD_STATE, 32)
	GET_STRING("IVM_SupplierPartNumber", IVM_POS_SUPPLIER_PART_NUMBER, 32)
	GET_STRING("IVM_DelieveryDate", IVM_POS_DELIVERY_DATE, 32)
	GET_STRING("IVM_SupplierBuildState", IVM_POS_SUPPLIER_BUILD_STATE, 32)
	GET_STRING("IVM_CustomerID", IVM_POS_CUSTOMER_ID, 32)
	GET_STRING("IVM_CustomerProductID", IVM_POS_CUSTOMER_PROD_ID, 32)

	if (ivm_check_crc(&buf[CONFIG_SYS_IVM_EEPROM_PAGE_LEN * 2], 2) != 0)
		return 0;
	ivm_analyze_block2(&buf[CONFIG_SYS_IVM_EEPROM_PAGE_LEN * 2],
		CONFIG_SYS_IVM_EEPROM_PAGE_LEN);

	return 0;
}

int ivm_read_eeprom(void)
{
	uchar i2c_buffer[CONFIG_SYS_IVM_EEPROM_MAX_LEN];
	int ret;

	i2c_set_bus_num(CONFIG_KM_IVM_BUS);
	/* add deblocking here */
	i2c_make_abort();

	ret = i2c_read(CONFIG_SYS_IVM_EEPROM_ADR, 0, 1, i2c_buffer,
		CONFIG_SYS_IVM_EEPROM_MAX_LEN);
	if (ret != 0) {
		printf("Error reading EEprom\n");
		return -2;
	}

	return ivm_analyze_eeprom(i2c_buffer, CONFIG_SYS_IVM_EEPROM_MAX_LEN);
}
