/*
 * (C) Copyright 2009
 * Marvell Semiconductor <www.marvell.com>
 * Written-by: Prafulla Wadaskar <prafulla@marvell.com>
 *
 * (C) Copyright 2003
 * Ingo Assmus <ingo.assmus@keymile.com>
 *
 * based on - Driver for MV64360X ethernet ports
 * Copyright (C) 2002 rabeeh@galileo.co.il
 *
 * 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., 51 Franklin Street, Fifth Floor, Boston,
 * MA 02110-1301 USA
 */

#include <common.h>
#include <net.h>
#include <malloc.h>
#include <miiphy.h>
#include <asm/errno.h>
#include <asm/types.h>
#include <asm/byteorder.h>
#include <asm/arch/kirkwood.h>
#include "kirkwood_egiga.h"

#define KIRKWOOD_PHY_ADR_REQUEST 0xee

/*
 * smi_reg_read - miiphy_read callback function.
 *
 * Returns 16bit phy register value, or 0xffff on error
 */
static int smi_reg_read(char *devname, u8 phy_adr, u8 reg_ofs, u16 * data)
{
	struct eth_device *dev = eth_get_dev_by_name(devname);
	struct kwgbe_device *dkwgbe = to_dkwgbe(dev);
	struct kwgbe_registers *regs = dkwgbe->regs;
	u32 smi_reg;
	u32 timeout;

	/* Phyadr read request */
	if (phy_adr == KIRKWOOD_PHY_ADR_REQUEST &&
			reg_ofs == KIRKWOOD_PHY_ADR_REQUEST) {
		/* */
		*data = (u16) (KWGBEREG_RD(regs->phyadr) & PHYADR_MASK);
		return 0;
	}
	/* check parameters */
	if (phy_adr > PHYADR_MASK) {
		printf("Err..(%s) Invalid PHY address %d\n",
			__FUNCTION__, phy_adr);
		return -EFAULT;
	}
	if (reg_ofs > PHYREG_MASK) {
		printf("Err..(%s) Invalid register offset %d\n",
			__FUNCTION__, reg_ofs);
		return -EFAULT;
	}

	timeout = KWGBE_PHY_SMI_TIMEOUT;
	/* wait till the SMI is not busy */
	do {
		/* read smi register */
		smi_reg = KWGBEREG_RD(regs->smi);
		if (timeout-- == 0) {
			printf("Err..(%s) SMI busy timeout\n", __FUNCTION__);
			return -EFAULT;
		}
	} while (smi_reg & KWGBE_PHY_SMI_BUSY_MASK);

	/* fill the phy address and regiser offset and read opcode */
	smi_reg = (phy_adr << KWGBE_PHY_SMI_DEV_ADDR_OFFS)
		| (reg_ofs << KWGBE_SMI_REG_ADDR_OFFS)
		| KWGBE_PHY_SMI_OPCODE_READ;

	/* write the smi register */
	KWGBEREG_WR(regs->smi, smi_reg);

	/*wait till read value is ready */
	timeout = KWGBE_PHY_SMI_TIMEOUT;

	do {
		/* read smi register */
		smi_reg = KWGBEREG_RD(regs->smi);
		if (timeout-- == 0) {
			printf("Err..(%s) SMI read ready timeout\n",
				__FUNCTION__);
			return -EFAULT;
		}
	} while (!(smi_reg & KWGBE_PHY_SMI_READ_VALID_MASK));

	/* Wait for the data to update in the SMI register */
	for (timeout = 0; timeout < KWGBE_PHY_SMI_TIMEOUT; timeout++) ;

	*data = (u16) (KWGBEREG_RD(regs->smi) & KWGBE_PHY_SMI_DATA_MASK);

	debug("%s:(adr %d, off %d) value= %04x\n", __FUNCTION__, phy_adr,
		reg_ofs, *data);

	return 0;
}

/*
 * smi_reg_write - imiiphy_write callback function.
 *
 * Returns 0 if write succeed, -EINVAL on bad parameters
 * -ETIME on timeout
 */
static int smi_reg_write(char *devname, u8 phy_adr, u8 reg_ofs, u16 data)
{
	struct eth_device *dev = eth_get_dev_by_name(devname);
	struct kwgbe_device *dkwgbe = to_dkwgbe(dev);
	struct kwgbe_registers *regs = dkwgbe->regs;
	u32 smi_reg;
	u32 timeout;

	/* Phyadr write request*/
	if (phy_adr == KIRKWOOD_PHY_ADR_REQUEST &&
			reg_ofs == KIRKWOOD_PHY_ADR_REQUEST) {
		KWGBEREG_WR(regs->phyadr, data);
		return 0;
	}

	/* check parameters */
	if (phy_adr > PHYADR_MASK) {
		printf("Err..(%s) Invalid phy address\n", __FUNCTION__);
		return -EINVAL;
	}
	if (reg_ofs > PHYREG_MASK) {
		printf("Err..(%s) Invalid register offset\n", __FUNCTION__);
		return -EINVAL;
	}

	/* wait till the SMI is not busy */
	timeout = KWGBE_PHY_SMI_TIMEOUT;
	do {
		/* read smi register */
		smi_reg = KWGBEREG_RD(regs->smi);
		if (timeout-- == 0) {
			printf("Err..(%s) SMI busy timeout\n", __FUNCTION__);
			return -ETIME;
		}
	} while (smi_reg & KWGBE_PHY_SMI_BUSY_MASK);

	/* fill the phy addr and reg offset and write opcode and data */
	smi_reg = (data << KWGBE_PHY_SMI_DATA_OFFS);
	smi_reg |= (phy_adr << KWGBE_PHY_SMI_DEV_ADDR_OFFS)
		| (reg_ofs << KWGBE_SMI_REG_ADDR_OFFS);
	smi_reg &= ~KWGBE_PHY_SMI_OPCODE_READ;

	/* write the smi register */
	KWGBEREG_WR(regs->smi, smi_reg);

	return 0;
}

/* Stop and checks all queues */
static void stop_queue(u32 * qreg)
{
	u32 reg_data;

	reg_data = readl(qreg);

	if (reg_data & 0xFF) {
		/* Issue stop command for active channels only */
		writel((reg_data << 8), qreg);

		/* Wait for all queue activity to terminate. */
		do {
			/*
			 * Check port cause register that all queues
			 * are stopped
			 */
			reg_data = readl(qreg);
		}
		while (reg_data & 0xFF);
	}
}

/*
 * set_access_control - Config address decode parameters for Ethernet unit
 *
 * This function configures the address decode parameters for the Gigabit
 * Ethernet Controller according the given parameters struct.
 *
 * @regs	Register struct pointer.
 * @param	Address decode parameter struct.
 */
static void set_access_control(struct kwgbe_registers *regs,
				struct kwgbe_winparam *param)
{
	u32 access_prot_reg;

	/* Set access control register */
	access_prot_reg = KWGBEREG_RD(regs->epap);
	/* clear window permission */
	access_prot_reg &= (~(3 << (param->win * 2)));
	access_prot_reg |= (param->access_ctrl << (param->win * 2));
	KWGBEREG_WR(regs->epap, access_prot_reg);

	/* Set window Size reg (SR) */
	KWGBEREG_WR(regs->barsz[param->win].size,
			(((param->size / 0x10000) - 1) << 16));

	/* Set window Base address reg (BA) */
	KWGBEREG_WR(regs->barsz[param->win].bar,
			(param->target | param->attrib | param->base_addr));
	/* High address remap reg (HARR) */
	if (param->win < 4)
		KWGBEREG_WR(regs->ha_remap[param->win], param->high_addr);

	/* Base address enable reg (BARER) */
	if (param->enable == 1)
		KWGBEREG_BITS_RESET(regs->bare, (1 << param->win));
	else
		KWGBEREG_BITS_SET(regs->bare, (1 << param->win));
}

static void set_dram_access(struct kwgbe_registers *regs)
{
	struct kwgbe_winparam win_param;
	int i;

	for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
		/* Set access parameters for DRAM bank i */
		win_param.win = i;	/* Use Ethernet window i */
		/* Window target - DDR */
		win_param.target = KWGBE_TARGET_DRAM;
		/* Enable full access */
		win_param.access_ctrl = EWIN_ACCESS_FULL;
		win_param.high_addr = 0;
		/* Get bank base */
		win_param.base_addr = kw_sdram_bar(i);
		win_param.size = kw_sdram_bs(i);	/* Get bank size */
		if (win_param.size == 0)
			win_param.enable = 0;
		else
			win_param.enable = 1;	/* Enable the access */

		/* Enable DRAM bank */
		switch (i) {
		case 0:
			win_param.attrib = EBAR_DRAM_CS0;
			break;
		case 1:
			win_param.attrib = EBAR_DRAM_CS1;
			break;
		case 2:
			win_param.attrib = EBAR_DRAM_CS2;
			break;
		case 3:
			win_param.attrib = EBAR_DRAM_CS3;
			break;
		default:
			/* invalide bank, disable access */
			win_param.enable = 0;
			win_param.attrib = 0;
			break;
		}
		/* Set the access control for address window(EPAPR) RD/WR */
		set_access_control(regs, &win_param);
	}
}

/*
 * port_init_mac_tables - Clear all entrance in the UC, SMC and OMC tables
 *
 * Go through all the DA filter tables (Unicast, Special Multicast & Other
 * Multicast) and set each entry to 0.
 */
static void port_init_mac_tables(struct kwgbe_registers *regs)
{
	int table_index;

	/* Clear DA filter unicast table (Ex_dFUT) */
	for (table_index = 0; table_index < 4; ++table_index)
		KWGBEREG_WR(regs->dfut[table_index], 0);

	for (table_index = 0; table_index < 64; ++table_index) {
		/* Clear DA filter special multicast table (Ex_dFSMT) */
		KWGBEREG_WR(regs->dfsmt[table_index], 0);
		/* Clear DA filter other multicast table (Ex_dFOMT) */
		KWGBEREG_WR(regs->dfomt[table_index], 0);
	}
}

/*
 * port_uc_addr - This function Set the port unicast address table
 *
 * This function locates the proper entry in the Unicast table for the
 * specified MAC nibble and sets its properties according to function
 * parameters.
 * This function add/removes MAC addresses from the port unicast address
 * table.
 *
 * @uc_nibble	Unicast MAC Address last nibble.
 * @option      0 = Add, 1 = remove address.
 *
 * RETURN: 1 if output succeeded. 0 if option parameter is invalid.
 */
static int port_uc_addr(struct kwgbe_registers *regs, u8 uc_nibble,
			int option)
{
	u32 unicast_reg;
	u32 tbl_offset;
	u32 reg_offset;

	/* Locate the Unicast table entry */
	uc_nibble = (0xf & uc_nibble);
	/* Register offset from unicast table base */
	tbl_offset = (uc_nibble / 4);
	/* Entry offset within the above register */
	reg_offset = uc_nibble % 4;

	switch (option) {
	case REJECT_MAC_ADDR:
		/*
		 * Clear accepts frame bit at specified unicast
		 * DA table entry
		 */
		unicast_reg = KWGBEREG_RD(regs->dfut[tbl_offset]);
		unicast_reg &= (0xFF << (8 * reg_offset));
		KWGBEREG_WR(regs->dfut[tbl_offset], unicast_reg);
		break;
	case ACCEPT_MAC_ADDR:
		/* Set accepts frame bit at unicast DA filter table entry */
		unicast_reg = KWGBEREG_RD(regs->dfut[tbl_offset]);
		unicast_reg &= (0xFF << (8 * reg_offset));
		unicast_reg |= ((0x01 | (RXUQ << 1)) << (8 * reg_offset));
		KWGBEREG_WR(regs->dfut[tbl_offset], unicast_reg);
		break;
	default:
		return 0;
	}
	return 1;
}

/*
 * port_uc_addr_set - This function Set the port Unicast address.
 */
static void port_uc_addr_set(struct kwgbe_registers *regs, u8 * p_addr)
{
	u32 mac_h;
	u32 mac_l;

	mac_l = (p_addr[4] << 8) | (p_addr[5]);
	mac_h = (p_addr[0] << 24) | (p_addr[1] << 16) | (p_addr[2] << 8) |
		(p_addr[3] << 0);

	KWGBEREG_WR(regs->macal, mac_l);
	KWGBEREG_WR(regs->macah, mac_h);

	/* Accept frames of this address */
	port_uc_addr(regs, p_addr[5], ACCEPT_MAC_ADDR);
}

/*
 * kwgbe_init_rx_desc_ring - Curve a Rx chain desc list and buffer in memory.
 */
static void kwgbe_init_rx_desc_ring(struct kwgbe_device *dkwgbe)
{
	struct kwgbe_rxdesc *p_rx_desc;
	int i;

	/* initialize the Rx descriptors ring */
	p_rx_desc = dkwgbe->p_rxdesc;
	for (i = 0; i < RINGSZ; i++) {
		p_rx_desc->cmd_sts =
			KWGBE_BUFFER_OWNED_BY_DMA | KWGBE_RX_EN_INTERRUPT;
		p_rx_desc->buf_size = PKTSIZE_ALIGN;
		p_rx_desc->byte_cnt = 0;
		p_rx_desc->buf_ptr = dkwgbe->p_rxbuf + i * PKTSIZE_ALIGN;
		if (i == (RINGSZ - 1))
			p_rx_desc->nxtdesc_p = dkwgbe->p_rxdesc;
		else {
			p_rx_desc->nxtdesc_p = (struct kwgbe_rxdesc *)
				((u32) p_rx_desc + KW_RXQ_DESC_ALIGNED_SIZE);
			p_rx_desc = p_rx_desc->nxtdesc_p;
		}
	}
	dkwgbe->p_rxdesc_curr = dkwgbe->p_rxdesc;
}

static int kwgbe_init(struct eth_device *dev)
{
	struct kwgbe_device *dkwgbe = to_dkwgbe(dev);
	struct kwgbe_registers *regs = dkwgbe->regs;
	int i;

	/* setup RX rings */
	kwgbe_init_rx_desc_ring(dkwgbe);

	/* Clear the ethernet port interrupts */
	KWGBEREG_WR(regs->ic, 0);
	KWGBEREG_WR(regs->ice, 0);
	/* Unmask RX buffer and TX end interrupt */
	KWGBEREG_WR(regs->pim, INT_CAUSE_UNMASK_ALL);
	/* Unmask phy and link status changes interrupts */
	KWGBEREG_WR(regs->peim, INT_CAUSE_UNMASK_ALL_EXT);

	set_dram_access(regs);
	port_init_mac_tables(regs);
	port_uc_addr_set(regs, dkwgbe->dev.enetaddr);

	/* Assign port configuration and command. */
	KWGBEREG_WR(regs->pxc, PRT_CFG_VAL);
	KWGBEREG_WR(regs->pxcx, PORT_CFG_EXTEND_VALUE);
	KWGBEREG_WR(regs->psc0, PORT_SERIAL_CONTROL_VALUE);
	/* Disable port initially */
	KWGBEREG_BITS_SET(regs->psc0, KWGBE_SERIAL_PORT_EN);

	/* Assign port SDMA configuration */
	KWGBEREG_WR(regs->sdc, PORT_SDMA_CFG_VALUE);
	KWGBEREG_WR(regs->tqx[0].qxttbc, QTKNBKT_DEF_VAL);
	KWGBEREG_WR(regs->tqx[0].tqxtbc, (QMTBS_DEF_VAL << 16) | QTKNRT_DEF_VAL);
	/* Turn off the port/RXUQ bandwidth limitation */
	KWGBEREG_WR(regs->pmtu, 0);

	/* Set maximum receive buffer to 9700 bytes */
	KWGBEREG_WR(regs->psc0,	KWGBE_MAX_RX_PACKET_9700BYTE
			| (KWGBEREG_RD(regs->psc0) & MRU_MASK));

	/*
	 * Set ethernet MTU for leaky bucket mechanism to 0 - this will
	 * disable the leaky bucket mechanism .
	 */
	KWGBEREG_WR(regs->pmtu, 0);

	/* Assignment of Rx CRDB of given RXUQ */
	KWGBEREG_WR(regs->rxcdp[RXUQ].rxcdp, (u32) dkwgbe->p_rxdesc_curr);
	/* Enable port Rx. */
	KWGBEREG_WR(regs->rqc, (1 << RXUQ));

#if (defined (CONFIG_MII) || defined (CONFIG_CMD_MII)) \
	 && defined (CONFIG_SYS_FAULT_ECHO_LINK_DOWN)
	/* Wait up to 5s for the link status */
	for (i = 0; i < 5; i++) {
		u16 phyadr;

		miiphy_read(dev->name, KIRKWOOD_PHY_ADR_REQUEST,
				KIRKWOOD_PHY_ADR_REQUEST, &phyadr);
		/* Return if we get link up */
		if (miiphy_link(dev->name, phyadr))
			return 0;
		udelay(1000000);
	}

	printf("No link on %s\n", dev->name);
	return -1;
#endif
	return 0;
}

static int kwgbe_halt(struct eth_device *dev)
{
	struct kwgbe_device *dkwgbe = to_dkwgbe(dev);
	struct kwgbe_registers *regs = dkwgbe->regs;

	/* Disable all gigE address decoder */
	KWGBEREG_WR(regs->bare, 0x3f);

	stop_queue(&regs->tqc);
	stop_queue(&regs->rqc);

	/* Enable port */
	KWGBEREG_BITS_RESET(regs->psc0, KWGBE_SERIAL_PORT_EN);
	/* Set port is not reset */
	KWGBEREG_BITS_RESET(regs->psc1, 1 << 4);
#ifdef CONFIG_SYS_MII_MODE
	/* Set MMI interface up */
	KWGBEREG_BITS_RESET(regs->psc1, 1 << 3);
#endif
	/* Disable & mask ethernet port interrupts */
	KWGBEREG_WR(regs->ic, 0);
	KWGBEREG_WR(regs->ice, 0);
	KWGBEREG_WR(regs->pim, 0);
	KWGBEREG_WR(regs->peim, 0);

	return 0;
}

static int kwgbe_send(struct eth_device *dev, volatile void *dataptr,
		      int datasize)
{
	struct kwgbe_device *dkwgbe = to_dkwgbe(dev);
	struct kwgbe_registers *regs = dkwgbe->regs;
	struct kwgbe_txdesc *p_txdesc = dkwgbe->p_txdesc;
	void *p = (void *)dataptr;
	u32 cmd_sts;

	/* Copy buffer if it's misaligned */
	if ((u32) dataptr & 0x07) {
		if (datasize > PKTSIZE_ALIGN) {
			printf("Non-aligned data too large (%d)\n",
					datasize);
			return -1;
		}

		memcpy(dkwgbe->p_aligned_txbuf, p, datasize);
		p = dkwgbe->p_aligned_txbuf;
	}

	p_txdesc->cmd_sts = KWGBE_ZERO_PADDING | KWGBE_GEN_CRC;
	p_txdesc->cmd_sts |= KWGBE_TX_FIRST_DESC | KWGBE_TX_LAST_DESC;
	p_txdesc->cmd_sts |= KWGBE_BUFFER_OWNED_BY_DMA;
	p_txdesc->cmd_sts |= KWGBE_TX_EN_INTERRUPT;
	p_txdesc->buf_ptr = (u8 *) p;
	p_txdesc->byte_cnt = datasize;

	/* Apply send command using zeroth RXUQ */
	KWGBEREG_WR(regs->tcqdp[TXUQ], (u32) p_txdesc);
	KWGBEREG_WR(regs->tqc, (1 << TXUQ));

	/*
	 * wait for packet xmit completion
	 */
	cmd_sts = readl(&p_txdesc->cmd_sts);
	while (cmd_sts & KWGBE_BUFFER_OWNED_BY_DMA) {
		/* return fail if error is detected */
		if ((cmd_sts & (KWGBE_ERROR_SUMMARY | KWGBE_TX_LAST_FRAME)) ==
				(KWGBE_ERROR_SUMMARY | KWGBE_TX_LAST_FRAME) &&
				cmd_sts & (KWGBE_UR_ERROR | KWGBE_RL_ERROR)) {
			printf("Err..(%s) in xmit packet\n", __FUNCTION__);
			return -1;
		}
		cmd_sts = readl(&p_txdesc->cmd_sts);
	};
	return 0;
}

static int kwgbe_recv(struct eth_device *dev)
{
	struct kwgbe_device *dkwgbe = to_dkwgbe(dev);
	struct kwgbe_rxdesc *p_rxdesc_curr = dkwgbe->p_rxdesc_curr;
	u32 cmd_sts;
	u32 timeout = 0;

	/* wait untill rx packet available or timeout */
	do {
		if (timeout < KWGBE_PHY_SMI_TIMEOUT)
			timeout++;
		else {
			debug("%s time out...\n", __FUNCTION__);
			return -1;
		}
	} while (readl(&p_rxdesc_curr->cmd_sts) & KWGBE_BUFFER_OWNED_BY_DMA);

	if (p_rxdesc_curr->byte_cnt != 0) {
		debug("%s: Received %d byte Packet @ 0x%x (cmd_sts= %08x)\n",
			__FUNCTION__, (u32) p_rxdesc_curr->byte_cnt,
			(u32) p_rxdesc_curr->buf_ptr,
			(u32) p_rxdesc_curr->cmd_sts);
	}

	/*
	 * In case received a packet without first/last bits on
	 * OR the error summary bit is on,
	 * the packets needs to be dropeed.
	 */
	cmd_sts = readl(&p_rxdesc_curr->cmd_sts);

	if ((cmd_sts &
		(KWGBE_RX_FIRST_DESC | KWGBE_RX_LAST_DESC))
		!= (KWGBE_RX_FIRST_DESC | KWGBE_RX_LAST_DESC)) {

		printf("Err..(%s) Dropping packet spread on"
			" multiple descriptors\n", __FUNCTION__);

	} else if (cmd_sts & KWGBE_ERROR_SUMMARY) {

		printf("Err..(%s) Dropping packet with errors\n",
			__FUNCTION__);

	} else {
		/* !!! call higher layer processing */
		debug("%s: Sending Received packet to"
			" upper layer (NetReceive)\n", __FUNCTION__);

		/* let the upper layer handle the packet */
		NetReceive((p_rxdesc_curr->buf_ptr + RX_BUF_OFFSET),
			(int)(p_rxdesc_curr->byte_cnt - RX_BUF_OFFSET));
	}
	/*
	 * free these descriptors and point next in the ring
	 */
	p_rxdesc_curr->cmd_sts =
		KWGBE_BUFFER_OWNED_BY_DMA | KWGBE_RX_EN_INTERRUPT;
	p_rxdesc_curr->buf_size = PKTSIZE_ALIGN;
	p_rxdesc_curr->byte_cnt = 0;

	writel((unsigned)p_rxdesc_curr->nxtdesc_p, &dkwgbe->p_rxdesc_curr);

	return 0;
}

int kirkwood_egiga_initialize(bd_t * bis)
{
	struct kwgbe_device *dkwgbe;
	struct eth_device *dev;
	int devnum;
	char *s;
	u8 used_ports[MAX_KWGBE_DEVS] = CONFIG_KIRKWOOD_EGIGA_PORTS;

	for (devnum = 0; devnum < MAX_KWGBE_DEVS; devnum++) {
		/*skip if port is configured not to use */
		if (used_ports[devnum] == 0)
			continue;

		if (!(dkwgbe = malloc(sizeof(struct kwgbe_device))))
			goto error1;

		memset(dkwgbe, 0, sizeof(struct kwgbe_device));

		if (!(dkwgbe->p_rxdesc =
		      (struct kwgbe_rxdesc *)memalign(PKTALIGN,
						KW_RXQ_DESC_ALIGNED_SIZE
						* RINGSZ + 1)))
			goto error2;

		if (!(dkwgbe->p_rxbuf = (u8 *) memalign(PKTALIGN, RINGSZ
							* PKTSIZE_ALIGN + 1)))
			goto error3;

		if (!(dkwgbe->p_aligned_txbuf = memalign(8, PKTSIZE_ALIGN)))
			goto error4;

		if (!(dkwgbe->p_txdesc = (struct kwgbe_txdesc *)
		      memalign(PKTALIGN, sizeof(struct kwgbe_txdesc) + 1))) {
			free(dkwgbe->p_aligned_txbuf);
		      error4:
			free(dkwgbe->p_rxbuf);
		      error3:
			free(dkwgbe->p_rxdesc);
		      error2:
			free(dkwgbe);
		      error1:
			printf("Err.. %s Failed to allocate memory\n",
				__FUNCTION__);
			return -1;
		}

		dev = &dkwgbe->dev;

		/* must be less than NAMESIZE (16) */
		sprintf(dev->name, "egiga%d", devnum);

		/* Extract the MAC address from the environment */
		switch (devnum) {
		case 0:
			dkwgbe->regs = (void *)KW_EGIGA0_BASE;
			s = "ethaddr";
			break;
		case 1:
			dkwgbe->regs = (void *)KW_EGIGA1_BASE;
			s = "eth1addr";
			break;
		default:	/* this should never happen */
			printf("Err..(%s) Invalid device number %d\n",
				__FUNCTION__, devnum);
			return -1;
		}

		while (!eth_getenv_enetaddr(s, dev->enetaddr)) {
			/* Generate Random Private MAC addr if not set */
			dev->enetaddr[0] = 0x02;
			dev->enetaddr[1] = 0x50;
			dev->enetaddr[2] = 0x43;
			dev->enetaddr[3] = get_random_hex();
			dev->enetaddr[4] = get_random_hex();
			dev->enetaddr[5] = get_random_hex();
			eth_setenv_enetaddr(s, dev->enetaddr);
		}

		dev->init = (void *)kwgbe_init;
		dev->halt = (void *)kwgbe_halt;
		dev->send = (void *)kwgbe_send;
		dev->recv = (void *)kwgbe_recv;

		eth_register(dev);

#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
		miiphy_register(dev->name, smi_reg_read, smi_reg_write);
		/* Set phy address of the port */
		miiphy_write(dev->name, KIRKWOOD_PHY_ADR_REQUEST,
				KIRKWOOD_PHY_ADR_REQUEST, PHY_BASE_ADR + devnum);
#endif
	}
	return 0;
}
