/*
 * Copyright 2006 Freescale Semiconductor
 * York Sun (yorksun@freescale.com)
 * Haiying Wang (haiying.wang@freescale.com)
 *
 * See file CREDITS for list of people who contributed to this
 * project.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of
 * the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 * MA 02111-1307 USA
 */

#include <common.h>
#include <command.h>
#include <i2c.h>
#include <linux/ctype.h>

typedef struct {
	u8 id[4];		/* 0x0000 - 0x0003 EEPROM Tag */
	u8 sn[12];		/* 0x0004 - 0x000F Serial Number */
	u8 errata[5];		/* 0x0010 - 0x0014 Errata Level */
	u8 date[6];		/* 0x0015 - 0x001a Build Date */
	u8 res_0;		/* 0x001b 	   Reserved */
	u8 version[4];		/* 0x001c - 0x001f Version */
	u8 tempcal[8];		/* 0x0020 - 0x0027 Temperature Calibration Factors*/
	u8 tempcalsys[2]; 	/* 0x0028 - 0x0029 System Temperature Calibration Factors*/
	u8 res_1[22];		/* 0x0020 - 0x003f Reserved */
	u8 mac_size;		/* 0x0040 	   Mac table size */
	u8 mac_flag;		/* 0x0041 	   Mac table flags */
	u8 mac[8][6];		/* 0x0042 - 0x0071 Mac addresses */
	u32 crc;		/* 0x0072 	   crc32 checksum */
} EEPROM_data;

static EEPROM_data mac_data;

int mac_show(void)
{
	int i;
	u8 mac_size;
	unsigned char ethaddr[8][18];
	unsigned char enetvar[32];

	/* Show EEPROM tagID,
	 * always the four characters 'NXID'.
	 */
	printf("ID ");
	for (i = 0; i < 4; i++)
		printf("%c", mac_data.id[i]);
	printf("\n");

	/* Show Serial number,
	 * 0 to 11 charaters of errata information.
	 */
	printf("SN ");
	for (i = 0; i < 12; i++)
		printf("%c", mac_data.sn[i]);
	printf("\n");

	/* Show Errata Level,
	 * 0 to 4 characters of errata information.
	 */
	printf("Errata ");
	for (i = 0; i < 5; i++)
		printf("%c", mac_data.errata[i]);
	printf("\n");

	/* Show Build Date,
	 * BCD date values, as YYMMDDhhmmss.
	 */
	printf("Date 20%02x/%02x/%02x %02x:%02x:%02x\n",
	       mac_data.date[0],
	       mac_data.date[1],
	       mac_data.date[2],
	       mac_data.date[3],
	       mac_data.date[4],
	       mac_data.date[5]);

	/* Show MAC table size,
	 * Value from 0 to 7 indicating how many MAC
	 * addresses are stored in the system EEPROM.
	 */
	if((mac_data.mac_size > 0) && (mac_data.mac_size <= 8))
		mac_size = mac_data.mac_size;
	else
		mac_size = 8; /* Set the max size */
	printf("MACSIZE %x\n", mac_size);

	/* Show Mac addresses */
	for (i = 0; i < mac_size; i++) {
		sprintf((char *)ethaddr[i],
			"%02x:%02x:%02x:%02x:%02x:%02x",
			mac_data.mac[i][0],
			mac_data.mac[i][1],
			mac_data.mac[i][2],
			mac_data.mac[i][3],
			mac_data.mac[i][4],
			mac_data.mac[i][5]);
		printf("MAC %d %s\n", i, ethaddr[i]);

		sprintf((char *)enetvar,
			i ? "eth%daddr" : "ethaddr", i);
		setenv((char *)enetvar, (char *)ethaddr[i]);

	}

	return 0;
}

int mac_read(void)
{
	int ret, length;
	unsigned int crc = 0;
	unsigned char dev = ID_EEPROM_ADDR, *data;

	length = sizeof(EEPROM_data);
	ret = i2c_read(dev, 0, 1, (unsigned char *)(&mac_data), length);
	if (ret) {
		printf("Read failed.\n");
		return -1;
	}

	data = (unsigned char *)(&mac_data);
	printf("Check CRC on reading ...");
	crc = crc32(crc, data, length - 4);
	if (crc != mac_data.crc) {
		printf("CRC checksum is invalid, in EEPROM CRC is %x, calculated CRC is %x\n",
		     mac_data.crc, crc);
		return -1;
	} else {
		printf("CRC OK\n");
		mac_show();
	}
	return 0;
}

int mac_prog(void)
{
	int ret, i, length;
	unsigned int crc = 0;
	unsigned char dev = ID_EEPROM_ADDR, *ptr;
	unsigned char *eeprom_data = (unsigned char *)(&mac_data);

	mac_data.res_0 = 0;
	memset((void *)mac_data.res_1, 0, sizeof(mac_data.res_1));

	length = sizeof(EEPROM_data);
	crc = crc32(crc, eeprom_data, length - 4);
	mac_data.crc = crc;
	for (i = 0, ptr = eeprom_data; i < length; i += 8, ptr += 8) {
		ret = i2c_write(dev, i, 1, ptr, min((length - i),8));
		udelay(5000);	/* 5ms write cycle timing */
		if (ret)
			break;
	}
	if (ret) {
		printf("Programming failed.\n");
		return -1;
	} else {
		printf("Programming %d bytes. Reading back ...\n", length);
		mac_read();
	}
	return 0;
}

int do_mac(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
{
	int i;
	char cmd = 's';
	unsigned long long mac_val;

	if (i2c_probe(ID_EEPROM_ADDR) != 0)
		return -1;

	if (argc > 1) {
		cmd = argv[1][0];
		switch (cmd) {
		case 'r':	/* display */
			mac_read();
			break;
		case 's':	/* save */
			mac_prog();
			break;
		case 'i':	/* id */
			for (i = 0; i < 4; i++) {
				mac_data.id[i] = argv[2][i];
			}
			break;
		case 'n':	/* serial number */
			for (i = 0; i < 12; i++) {
				mac_data.sn[i] = argv[2][i];
			}
			break;
		case 'e':	/* errata */
			for (i = 0; i < 5; i++) {
				mac_data.errata[i] = argv[2][i];
			}
			break;
		case 'd':	/* date */
			mac_val = simple_strtoull(argv[2], NULL, 16);
			for (i = 0; i < 6; i++) {
				mac_data.date[i] = (mac_val >> (40 - 8 * i));
			}
			break;
		case 'p':	/* mac table size */
			mac_data.mac_size =
			    (unsigned char)simple_strtoul(argv[2], NULL, 16);
			break;
		case '0':	/* mac 0 */
		case '1':	/* mac 1 */
		case '2':	/* mac 2 */
		case '3':	/* mac 3 */
		case '4':	/* mac 4 */
		case '5':	/* mac 5 */
		case '6':	/* mac 6 */
		case '7':	/* mac 7 */
			mac_val = simple_strtoull(argv[2], NULL, 16);
			for (i = 0; i < 6; i++) {
				mac_data.mac[cmd - '0'][i] =
				    *((unsigned char *)
				      (((unsigned int)(&mac_val)) + i + 2));
			}
			break;
		case 'h':	/* help */
		default:
			printf("Usage:\n%s\n", cmdtp->usage);
			break;
		}
	} else {
		mac_show();
	}
	return 0;
}

int mac_read_from_eeprom(void)
{
	int length, i;
	unsigned char dev = ID_EEPROM_ADDR;
	unsigned char *data;
	unsigned char ethaddr[4][18];
	unsigned char enetvar[32];
	unsigned int crc = 0;

	length = sizeof(EEPROM_data);
	if (i2c_read(dev, 0, 1, (unsigned char *)(&mac_data), length)) {
		printf("Read failed.\n");
		return -1;
	}

	data = (unsigned char *)(&mac_data);
	crc = crc32(crc, data, length - 4);
	if (crc != mac_data.crc) {
		return -1;
	} else {
		for (i = 0; i < 4; i++) {
			if (memcmp(&mac_data.mac[i], "\0\0\0\0\0\0", 6)) {
				sprintf((char *)ethaddr[i],
					"%02x:%02x:%02x:%02x:%02x:%02x",
					mac_data.mac[i][0],
					mac_data.mac[i][1],
					mac_data.mac[i][2],
					mac_data.mac[i][3],
					mac_data.mac[i][4],
					mac_data.mac[i][5]);
				sprintf((char *)enetvar,
					i ? "eth%daddr" : "ethaddr",
					i);
				setenv((char *)enetvar, (char *)ethaddr[i]);
			}
		}
	}
	return 0;
}
