/*
 * (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"

/*
 * 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;
	volatile u32 timeout;

	/* Phyadr read request */
	if (phy_adr == 0xEE && reg_ofs == 0xEE) {
		/* */
		*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;
	volatile u32 timeout;

	/* Phyadr write request*/
	if (phy_adr == 0xEE && reg_ofs == 0xEE) {
		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)
{
	volatile 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;

	/* 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)
	u16 phyadr;
	miiphy_read(dev->name, 0xEE, 0xEE, &phyadr);
	if (!miiphy_link(dev->name, phyadr)) {
		printf("%s: No link on %s\n", __FUNCTION__, 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;

	if ((u32) dataptr & 0x07) {
		printf("Err..(%s) xmit dataptr not 64bit aligned\n",
			__FUNCTION__);
		return -1;
	}
	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 *) dataptr;
	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
	 */
	while (p_txdesc->cmd_sts & KWGBE_BUFFER_OWNED_BY_DMA) {
		/* return fail if error is detected */
		if (p_txdesc->cmd_sts & (KWGBE_UR_ERROR | KWGBE_RL_ERROR)) {
			printf("Err..(%s) in xmit packet\n", __FUNCTION__);
			return -1;
		}
	};
	return 0;
}

static int kwgbe_recv(struct eth_device *dev)
{
	volatile struct kwgbe_device *dkwgbe = to_dkwgbe(dev);
	volatile struct kwgbe_rxdesc *p_rxdesc_curr = dkwgbe->p_rxdesc_curr;
	volatile 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 (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.
	 */
	if ((p_rxdesc_curr->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 (p_rxdesc_curr->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;

	dkwgbe->p_rxdesc_curr = p_rxdesc_curr->nxtdesc_p;
	return 0;
}

int kirkwood_egiga_initialize(bd_t * bis)
{
	struct kwgbe_device *dkwgbe;
	struct eth_device *dev;
	int devnum;
	char *s, buf[NAMESIZE * 2];
	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_txdesc = (struct kwgbe_txdesc *)
		      memalign(PKTALIGN, sizeof(struct kwgbe_txdesc) + 1))) {
			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 Ramdom MAC addresses if not set */
			sprintf(buf, "00:50:43:%02x:%02x:%02x",
				get_random_hex(), get_random_hex(),
				get_random_hex());
			setenv(s, buf);
		}

		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, 0xEE, 0xEE, PHY_BASE_ADR + devnum);
#endif
	}
	return 0;
}
