/*
 * (C) Copyright 2004
 * Robin Getz rgetz@blacfin.uclinux.org
 *
 * 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
 *
 * Heavily borrowed from the following peoples GPL'ed software:
 *  - Wolfgang Denk, DENX Software Engineering, wd@denx.de
 *       Das U-boot
 *  - Ladislav Michl ladis@linux-mips.org
 *       A rejected patch on the U-Boot mailing list
 */

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

#ifndef SMC91111_EEPROM_INIT
# define SMC91111_EEPROM_INIT()
#endif

#define SMC_BASE_ADDRESS CONFIG_SMC91111_BASE
#define EEPROM		0x1
#define MAC		0x2
#define UNKNOWN		0x4

void dump_reg (struct eth_device *dev);
void dump_eeprom (struct eth_device *dev);
int write_eeprom_reg (struct eth_device *dev, int value, int reg);
void copy_from_eeprom (struct eth_device *dev);
void print_MAC (struct eth_device *dev);
int read_eeprom_reg (struct eth_device *dev, int reg);
void print_macaddr (struct eth_device *dev);

int smc91111_eeprom (int argc, char *argv[])
{
	int c, i, j, done, line, reg, value, start, what;
	char input[50];

	struct eth_device dev;
	dev.iobase = CONFIG_SMC91111_BASE;

	/* Print the ABI version */
	app_startup (argv);
	if (XF_VERSION != (int) get_version ()) {
		printf ("Expects ABI version %d\n", XF_VERSION);
		printf ("Actual U-Boot ABI version %d\n",
			(int) get_version ());
		printf ("Can't run\n\n");
		return (0);
	}

	SMC91111_EEPROM_INIT();

	if ((SMC_inw (&dev, BANK_SELECT) & 0xFF00) != 0x3300) {
		printf ("Can't find SMSC91111\n");
		return (0);
	}

	done = 0;
	what = UNKNOWN;
	printf ("\n");
	while (!done) {
		/* print the prompt */
		printf ("SMC91111> ");
		line = 0;
		i = 0;
		start = 1;
		while (!line) {
			/* Wait for a keystroke */
			while (!tstc ());

			c = getc ();
			/* Make Uppercase */
			if (c >= 'Z')
				c -= ('a' - 'A');
			/* printf(" |%02x| ",c); */

			switch (c) {
			case '\r':	/* Enter                */
			case '\n':
				input[i] = 0;
				puts ("\r\n");
				line = 1;
				break;
			case '\0':	/* nul                  */
				continue;

			case 0x03:	/* ^C - break           */
				input[0] = 0;
				i = 0;
				line = 1;
				done = 1;
				break;

			case 0x5F:
			case 0x08:	/* ^H  - backspace      */
			case 0x7F:	/* DEL - backspace      */
				if (i > 0) {
					puts ("\b \b");
					i--;
				}
				break;
			default:
				if (start) {
					if ((c == 'W') || (c == 'D')
					    || (c == 'M') || (c == 'C')
					    || (c == 'P')) {
						putc (c);
						input[i] = c;
						if (i <= 45)
							i++;
						start = 0;
					}
				} else {
					if ((c >= '0' && c <= '9')
					    || (c >= 'A' && c <= 'F')
					    || (c == 'E') || (c == 'M')
					    || (c == ' ')) {
						putc (c);
						input[i] = c;
						if (i <= 45)
							i++;
						break;
					}
				}
				break;
			}
		}

		for (; i < 49; i++)
			input[i] = 0;

		switch (input[0]) {
		case ('W'):
			/* Line should be w reg value */
			i = 0;
			reg = 0;
			value = 0;
			/* Skip to the next space or end) */
			while ((input[i] != ' ') && (input[i] != 0))
				i++;

			if (input[i] != 0)
				i++;

			/* Are we writing to EEPROM or MAC */
			switch (input[i]) {
			case ('E'):
				what = EEPROM;
				break;
			case ('M'):
				what = MAC;
				break;
			default:
				what = UNKNOWN;
				break;
			}

			/* skip to the next space or end */
			while ((input[i] != ' ') && (input[i] != 0))
				i++;
			if (input[i] != 0)
				i++;

			/* Find register to write into */
			j = 0;
			while ((input[i] != ' ') && (input[i] != 0)) {
				j = input[i] - 0x30;
				if (j >= 0xA) {
					j -= 0x07;
				}
				reg = (reg * 0x10) + j;
				i++;
			}

			while ((input[i] != ' ') && (input[i] != 0))
				i++;

			if (input[i] != 0)
				i++;
			else
				what = UNKNOWN;

			/* Get the value to write */
			j = 0;
			while ((input[i] != ' ') && (input[i] != 0)) {
				j = input[i] - 0x30;
				if (j >= 0xA) {
					j -= 0x07;
				}
				value = (value * 0x10) + j;
				i++;
			}

			switch (what) {
			case 1:
				printf ("Writing EEPROM register %02x with %04x\n", reg, value);
				write_eeprom_reg (&dev, value, reg);
				break;
			case 2:
				printf ("Writing MAC register bank %i, reg %02x with %04x\n", reg >> 4, reg & 0xE, value);
				SMC_SELECT_BANK (&dev, reg >> 4);
				SMC_outw (&dev, value, reg & 0xE);
				break;
			default:
				printf ("Wrong\n");
				break;
			}
			break;
		case ('D'):
			dump_eeprom (&dev);
			break;
		case ('M'):
			dump_reg (&dev);
			break;
		case ('C'):
			copy_from_eeprom (&dev);
			break;
		case ('P'):
			print_macaddr (&dev);
			break;
		default:
			break;
		}

	}

	return (0);
}

void copy_from_eeprom (struct eth_device *dev)
{
	int i;

	SMC_SELECT_BANK (dev, 1);
	SMC_outw (dev, (SMC_inw (dev, CTL_REG) & !CTL_EEPROM_SELECT) |
		CTL_RELOAD, CTL_REG);
	i = 100;
	while ((SMC_inw (dev, CTL_REG) & CTL_RELOAD) && --i)
		udelay (100);
	if (i == 0) {
		printf ("Timeout Refreshing EEPROM registers\n");
	} else {
		printf ("EEPROM contents copied to MAC\n");
	}

}

void print_macaddr (struct eth_device *dev)
{
	int i, j, k, mac[6];

	printf ("Current MAC Address in SMSC91111 ");
	SMC_SELECT_BANK (dev, 1);
	for (i = 0; i < 5; i++) {
		printf ("%02x:", SMC_inb (dev, ADDR0_REG + i));
	}

	printf ("%02x\n", SMC_inb (dev, ADDR0_REG + 5));

	i = 0;
	for (j = 0x20; j < 0x23; j++) {
		k = read_eeprom_reg (dev, j);
		mac[i] = k & 0xFF;
		i++;
		mac[i] = k >> 8;
		i++;
	}

	printf ("Current MAC Address in EEPROM    ");
	for (i = 0; i < 5; i++)
		printf ("%02x:", mac[i]);
	printf ("%02x\n", mac[5]);

}
void dump_eeprom (struct eth_device *dev)
{
	int j, k;

	printf ("IOS2-0    ");
	for (j = 0; j < 8; j++) {
		printf ("%03x     ", j);
	}
	printf ("\n");

	for (k = 0; k < 4; k++) {
		if (k == 0)
			printf ("CONFIG ");
		if (k == 1)
			printf ("BASE   ");
		if ((k == 2) || (k == 3))
			printf ("       ");
		for (j = 0; j < 0x20; j += 4) {
			printf ("%02x:%04x ", j + k,
				read_eeprom_reg (dev, j + k));
		}
		printf ("\n");
	}

	for (j = 0x20; j < 0x40; j++) {
		if ((j & 0x07) == 0)
			printf ("\n");
		printf ("%02x:%04x ", j, read_eeprom_reg (dev, j));
	}
	printf ("\n");

}

int read_eeprom_reg (struct eth_device *dev, int 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 EEPROM register %02x\n", reg);
		return 0;
	}

	return SMC_inw (dev, GP_REG);

}

int write_eeprom_reg (struct eth_device *dev, int value, int 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 EEPROM register %02x\n", reg);
		return 0;
	}

	return 1;

}

void dump_reg (struct eth_device *dev)
{
	int i, j;

	printf ("    ");
	for (j = 0; j < 4; j++) {
		printf ("Bank%i ", j);
	}
	printf ("\n");
	for (i = 0; i < 0xF; i += 2) {
		printf ("%02x  ", i);
		for (j = 0; j < 4; j++) {
			SMC_SELECT_BANK (dev, j);
			printf ("%04x  ", SMC_inw (dev, i));
		}
		printf ("\n");
	}
}
