/*
 * (C) Copyright 2005
 * Ladislav Michl, 2N Telekomunikace, michl@2n.cz
 *
 * 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 version 2 as
 * published by the Free Software Foundation.
 *
 * 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
 *
 * Some code shamelessly stolen back from Robin Getz.
 */

#include <common.h>
#include <exports.h>
#include <timestamp.h>
#include <net.h>
#include "../drivers/net/smc91111.h"

static struct eth_device dev = {
	.iobase = CONFIG_SMC91111_BASE
};

static u16 read_eeprom_reg(u16 reg)
{
	int timeout;

	SMC_SELECT_BANK(&dev, 2);
	SMC_outw(&dev, reg, PTR_REG);

	SMC_SELECT_BANK(&dev, 1);
	SMC_outw(&dev, SMC_inw(&dev, CTL_REG) | CTL_EEPROM_SELECT |
		CTL_RELOAD, CTL_REG);

	timeout = 100;

	while ((SMC_inw(&dev, CTL_REG) & CTL_RELOAD) && --timeout)
		udelay(100);
	if (timeout == 0) {
		printf("Timeout reading register %02x\n", reg);
		return 0;
	}

	return SMC_inw(&dev, GP_REG);
}

static int write_eeprom_reg(u16 value, u16 reg)
{
	int timeout;

	SMC_SELECT_BANK(&dev, 2);
	SMC_outw(&dev, reg, PTR_REG);

	SMC_SELECT_BANK(&dev, 1);

	SMC_outw(&dev, value, GP_REG);
	SMC_outw(&dev, SMC_inw(&dev, CTL_REG) | CTL_EEPROM_SELECT |
		CTL_STORE, CTL_REG);

	timeout = 100;

	while ((SMC_inw(&dev, CTL_REG) & CTL_STORE) && --timeout)
		udelay(100);
	if (timeout == 0) {
		printf("Timeout writing register %02x\n", reg);
		return 0;
	}

	return 1;
}

static int write_data(u16 *buf, int len)
{
	u16 reg = 0x23;

	while (len--)
		write_eeprom_reg(*buf++, reg++);

	return 0;
}

static int verify_macaddr(char *s)
{
	u16 reg;
	int i, err = 0;

	puts("HWaddr: ");
	for (i = 0; i < 3; i++) {
		reg = read_eeprom_reg(0x20 + i);
		printf("%02x:%02x%c", reg & 0xff, reg >> 8, i != 2 ? ':' : '\n');
		if (s)
			err |= reg != ((u16 *)s)[i];
	}

	return err ? 0 : 1;
}

static int set_mac(char *s)
{
	int i;
	char *e, eaddr[6];

	/* turn string into mac value */
	for (i = 0; i < 6; i++) {
		eaddr[i] = simple_strtoul(s, &e, 16);
		s = (*e) ? e+1 : e;
	}

	for (i = 0; i < 3; i++)
		write_eeprom_reg(*(((u16 *)eaddr) + i), 0x20 + i);

	return 0;
}

static int parse_element(char *s, unsigned char *buf, int len)
{
	int cnt;
	char *p, num[3];
	unsigned char id;

	id = simple_strtoul(s, &p, 16);
	if (*p++ != ':')
		return -1;
	cnt = 2;
	num[2] = 0;
	for (; *p; p += 2) {
		if (p[1] == 0)
			return -2;
		if (cnt + 3 > len)
			return -3;
		num[0] = p[0];
		num[1] = p[1];
		buf[cnt++] = simple_strtoul(num, NULL, 16);
	}
	buf[0] = id;
	buf[1] = cnt - 2;

	return cnt;
}

int eeprom(int argc, char * const argv[])
{
	int i, len, ret;
	unsigned char buf[58], *p;

	app_startup(argv);
	i = get_version();
	if (i != XF_VERSION) {
		printf("Using ABI version %d, but U-Boot provides %d\n",
			XF_VERSION, i);
		return 1;
	}

	if ((SMC_inw(&dev, BANK_SELECT) & 0xFF00) != 0x3300) {
		puts("SMSC91111 not found\n");
		return 2;
	}

	/* Called without parameters - print MAC address */
	if (argc < 2) {
		verify_macaddr(NULL);
		return 0;
	}

	/* Print help message */
	if (argv[1][1] == 'h') {
		puts("VoiceBlue EEPROM writer\n"
			"Built: " U_BOOT_DATE " at " U_BOOT_TIME "\n"
			"Usage:\n\t<mac_address> [<element_1>] [<...>]\n");
		return 0;
	}

	/* Try to parse information elements */
	len = sizeof(buf);
	p = buf;
	for (i = 2; i < argc; i++) {
		ret = parse_element(argv[i], p, len);
		switch (ret) {
		case -1:
			printf("Element %d: malformed\n", i - 1);
			return 3;
		case -2:
			printf("Element %d: odd character count\n", i - 1);
			return 3;
		case -3:
			puts("Out of EEPROM memory\n");
			return 3;
		default:
			p += ret;
			len -= ret;
		}
	}

	/* First argument (MAC) is mandatory */
	set_mac(argv[1]);
	if (verify_macaddr(argv[1])) {
		puts("*** HWaddr does not match! ***\n");
		return 4;
	}

	while (len--)
		*p++ = 0;

	write_data((u16 *)buf, sizeof(buf) >> 1);

	return 0;
}
