/*
 * drivers/net/arm/ambarella_eth.c
 *
 * Author: Anthony Ginger <hfjiang@ambarella.com>
 * Copyright (C) 2004-2011, Ambarella, Inc.
 *
 * 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 <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/ioport.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>
#include <linux/delay.h>
#include <linux/dma-mapping.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
#include <linux/spinlock.h>
#include <linux/crc32.h>
#include <linux/time.h>
#include <linux/mii.h>
#include <linux/phy.h>
#include <linux/ethtool.h>

#include <asm/dma.h>

#include <mach/hardware.h>
#include <plat/eth.h>

/* ==========================================================================*/
#define AMBETH_PACKET_MAXFRAME	(1536)
#define AMBETH_RX_COPYBREAK	(1518)
#define AMBETH_RX_RNG_MIN	(8)
#define AMBETH_TX_RNG_MIN	(4)

#define AMBETH_RXDMA_STATUS	(ETH_DMA_STATUS_OVF | ETH_DMA_STATUS_RI | \
				ETH_DMA_STATUS_RU | ETH_DMA_STATUS_RPS | \
				ETH_DMA_STATUS_RWT)
#define AMBETH_RXDMA_INTEN	(ETH_DMA_INTEN_OVE | ETH_DMA_INTEN_RIE | \
				ETH_DMA_INTEN_RUE | ETH_DMA_INTEN_RSE | \
				ETH_DMA_INTEN_RWE)
#define AMBETH_TXDMA_STATUS	(ETH_DMA_STATUS_TI | ETH_DMA_STATUS_TPS | \
				ETH_DMA_STATUS_TU | ETH_DMA_STATUS_TJT | \
				ETH_DMA_STATUS_UNF)
#define AMBETH_TXDMA_INTEN	(ETH_DMA_INTEN_TIE | ETH_DMA_INTEN_TSE | \
				ETH_DMA_INTEN_TUE | ETH_DMA_INTEN_TJE | \
				ETH_DMA_INTEN_UNE)
#define AMBETH_DMA_INTEN	(ETH_DMA_INTEN_NIE | ETH_DMA_INTEN_AIE | \
				ETH_DMA_INTEN_FBE | AMBETH_RXDMA_INTEN | \
				AMBETH_TXDMA_INTEN)

#define AMBETH_TDES0_ATOMIC_CHECK
#undef AMBETH_TDES0_ATOMIC_CHECK_ALL
#define AMBETH_RDES0_ATOMIC_CHECK
#undef AMBETH_RDES0_ATOMIC_CHECK_ALL

/* ==========================================================================*/
struct ambeth_desc {
	u32					status;
	u32					length;
	u32					buffer1;
	u32					buffer2;
} __attribute((packed));

struct ambeth_rng_info {
	struct sk_buff				*skb;
	dma_addr_t				mapping;
};

struct ambeth_tx_rngmng {
	unsigned int				cur_tx;
	unsigned int				dirty_tx;
	struct ambeth_rng_info			*rng_tx;
	struct ambeth_desc			*desc_tx;
};

struct ambeth_rx_rngmng {
	unsigned int				cur_rx;
	unsigned int				dirty_rx;
	struct ambeth_rng_info			*rng_rx;
	struct ambeth_desc			*desc_rx;
};

struct ambeth_info {
	unsigned int				rx_count;
	struct ambeth_rx_rngmng			rx;
	unsigned int				tx_count;
	unsigned int				tx_irq_count;
	struct ambeth_tx_rngmng			tx;
	dma_addr_t				rx_dma_desc;
	dma_addr_t				tx_dma_desc;
	spinlock_t				lock;
	int					oldspeed;
	int					oldduplex;
	int					oldlink;

	struct net_device_stats			stats;
	struct napi_struct			napi;
	struct net_device			*ndev;
	struct mii_bus				new_bus;
	struct phy_device			*phydev;
	uint32_t				msg_enable;

	unsigned char __iomem			*regbase;
	struct ambarella_eth_platform_info	*platform_info;
};

/* ==========================================================================*/
static int msg_level = -1;
module_param (msg_level, int, 0);
MODULE_PARM_DESC (msg_level, "Override default message level");

/* ==========================================================================*/
static inline int ambhw_dma_reset(struct ambeth_info *lp)
{
	int					errorCode = 0;
	u32					counter = 0;

	amba_setbitsl(lp->regbase + ETH_DMA_BUS_MODE_OFFSET,
		ETH_DMA_BUS_MODE_SWR);
	do {
		if (counter++ > 100) {
			errorCode = -EIO;
			break;
		}
		mdelay(1);
	} while (amba_tstbitsl(lp->regbase + ETH_DMA_BUS_MODE_OFFSET,
		ETH_DMA_BUS_MODE_SWR));

	if (errorCode && netif_msg_drv(lp))
		dev_err(&lp->ndev->dev, "DMA Error: Check PHY.\n");

	return errorCode;
}

static inline void ambhw_dma_int_enable(struct ambeth_info *lp)
{
	amba_writel(lp->regbase + ETH_DMA_INTEN_OFFSET, AMBETH_DMA_INTEN);
}

static inline void ambhw_dma_int_disable(struct ambeth_info *lp)
{
	amba_writel(lp->regbase + ETH_DMA_INTEN_OFFSET, 0);
}

static inline void ambhw_dma_rx_start(struct ambeth_info *lp)
{
	amba_setbitsl(lp->regbase + ETH_DMA_OPMODE_OFFSET, ETH_DMA_OPMODE_SR);
}

static inline void ambhw_dma_rx_stop(struct ambeth_info *lp)
{
	unsigned int				irq_status;
	int					i = 1300;

	amba_clrbitsl(lp->regbase + ETH_DMA_OPMODE_OFFSET, ETH_DMA_OPMODE_SR);
	do {
		udelay(1);
		irq_status = amba_readl(lp->regbase + ETH_DMA_STATUS_OFFSET);
	} while ((irq_status & ETH_DMA_STATUS_RS_MASK) && --i);
	if ((i <= 0) && netif_msg_drv(lp)) {
		dev_err(&lp->ndev->dev,
			"DMA Error: Stop RX status=0x%x, opmode=0x%x.\n",
			amba_readl(lp->regbase + ETH_DMA_STATUS_OFFSET),
			amba_readl(lp->regbase + ETH_DMA_OPMODE_OFFSET));
	}
}

static inline void ambhw_dma_tx_start(struct ambeth_info *lp)
{
	amba_setbitsl(lp->regbase + ETH_DMA_OPMODE_OFFSET, ETH_DMA_OPMODE_ST);
}

static inline void ambhw_dma_tx_stop(struct ambeth_info *lp)
{
	unsigned int				irq_status;
	int					i = 1300;

	amba_clrbitsl(lp->regbase + ETH_DMA_OPMODE_OFFSET, ETH_DMA_OPMODE_ST);
	do {
		udelay(1);
		irq_status = amba_readl(lp->regbase + ETH_DMA_STATUS_OFFSET);
	} while ((irq_status & ETH_DMA_STATUS_TS_MASK) && --i);
	if ((i <= 0) && netif_msg_drv(lp)) {
		dev_err(&lp->ndev->dev,
			"DMA Error: Stop TX status=0x%x, opmode=0x%x.\n",
			amba_readl(lp->regbase + ETH_DMA_STATUS_OFFSET),
			amba_readl(lp->regbase + ETH_DMA_OPMODE_OFFSET));
	}
	amba_setbitsl(lp->regbase + ETH_DMA_OPMODE_OFFSET, ETH_DMA_OPMODE_FTF);
}

static inline void ambhw_dma_tx_restart(struct ambeth_info *lp, u32 entry)
{
	amba_writel(lp->regbase + ETH_DMA_TX_DESC_LIST_OFFSET,
		(u32)lp->tx_dma_desc + (entry * sizeof(struct ambeth_desc)));
	ambhw_dma_tx_start(lp);
}

static inline void ambhw_dma_tx_poll(struct ambeth_info *lp, u32 entry)
{
	lp->tx.desc_tx[entry].status = ETH_TDES0_OWN;
	amba_writel(lp->regbase + ETH_DMA_TX_POLL_DMD_OFFSET, 0x01);
}

static inline void ambhw_stop_tx_rx(struct ambeth_info *lp)
{
	unsigned int				irq_status;
	int					i = 1300;

	amba_clrbitsl(lp->regbase + ETH_MAC_CFG_OFFSET, ETH_MAC_CFG_RE);
	amba_clrbitsl(lp->regbase + ETH_DMA_OPMODE_OFFSET,
		(ETH_DMA_OPMODE_SR | ETH_DMA_OPMODE_ST));
	do {
		udelay(1);
		irq_status = amba_readl(lp->regbase + ETH_DMA_STATUS_OFFSET);
	} while ((irq_status & (ETH_DMA_STATUS_TS_MASK |
		ETH_DMA_STATUS_RS_MASK)) && --i);
	if ((i <= 0) && netif_msg_drv(lp)) {
		dev_err(&lp->ndev->dev,
			"DMA Error: Stop TX/RX status=0x%x, opmode=0x%x.\n",
			amba_readl(lp->regbase + ETH_DMA_STATUS_OFFSET),
			amba_readl(lp->regbase + ETH_DMA_OPMODE_OFFSET));
	}
	amba_clrbitsl(lp->regbase + ETH_MAC_CFG_OFFSET, ETH_MAC_CFG_TE);
}

static inline void ambhw_set_dma_desc(struct ambeth_info *lp)
{
	amba_writel(lp->regbase + ETH_DMA_RX_DESC_LIST_OFFSET,
		lp->rx_dma_desc);
	amba_writel(lp->regbase + ETH_DMA_TX_DESC_LIST_OFFSET,
		lp->tx_dma_desc);
}

static inline phy_interface_t ambhw_get_interface(struct ambeth_info *lp)
{
	return amba_tstbitsl(lp->regbase + ETH_MAC_CFG_OFFSET,
		ETH_MAC_CFG_PS) ? PHY_INTERFACE_MODE_MII :
		PHY_INTERFACE_MODE_GMII;
}

static inline void ambhw_set_hwaddr(struct ambeth_info *lp, u8 *hwaddr)
{
	u32					val;

	val = (hwaddr[5] << 8) | hwaddr[4];
	amba_writel(lp->regbase + ETH_MAC_MAC0_HI_OFFSET, val);
	udelay(4);
	val = (hwaddr[3] << 24) | (hwaddr[2] << 16) |
		(hwaddr[1] << 8) | hwaddr[0];
	amba_writel(lp->regbase + ETH_MAC_MAC0_LO_OFFSET, val);
}

static inline void ambhw_get_hwaddr(struct ambeth_info *lp, u8 *hwaddr)
{
	u32					hval;
	u32					lval;

	hval = amba_readl(lp->regbase + ETH_MAC_MAC0_HI_OFFSET);
	lval = amba_readl(lp->regbase + ETH_MAC_MAC0_LO_OFFSET);
	hwaddr[5] = ((hval >> 8) & 0xff);
	hwaddr[4] = ((hval >> 0) & 0xff);
	hwaddr[3] = ((lval >> 24) & 0xff);
	hwaddr[2] = ((lval >> 16) & 0xff);
	hwaddr[1] = ((lval >> 8) & 0xff);
	hwaddr[0] = ((lval >> 0) & 0xff);
}

static inline void ambhw_set_link_mode_speed(struct ambeth_info *lp)
{
	u32					val;

	val = amba_readl(lp->regbase + ETH_MAC_CFG_OFFSET);
	switch (lp->oldspeed) {
	case SPEED_1000:
		val &= ~(ETH_MAC_CFG_PS);
		break;
	case SPEED_100:
	case SPEED_10:
	default:
		val |= ETH_MAC_CFG_PS;
		break;
	}
	if (lp->oldduplex) {
		val &= ~(ETH_MAC_CFG_DO);
		val |= ETH_MAC_CFG_DM;
	} else {
		val &= ~(ETH_MAC_CFG_DM);
		val |= ETH_MAC_CFG_DO;
	}
	amba_writel(lp->regbase + ETH_MAC_CFG_OFFSET, val);
}

static inline int ambhw_enable(struct ambeth_info *lp)
{
	int					errorCode = 0;

	ambarella_set_gpio_output(&lp->platform_info->mii_power, 1);
	ambarella_set_gpio_reset(&lp->platform_info->mii_reset);

	errorCode = ambhw_dma_reset(lp);
	if (errorCode)
		goto ambhw_init_exit;

	ambhw_set_hwaddr(lp, lp->ndev->dev_addr);
	amba_writel(lp->regbase + ETH_DMA_BUS_MODE_OFFSET,
		lp->platform_info->default_dma_bus_mode);
	amba_writel(lp->regbase + ETH_MAC_FRAME_FILTER_OFFSET, 0);
	amba_writel(lp->regbase + ETH_DMA_OPMODE_OFFSET,
		lp->platform_info->default_dma_opmode);
#if defined(CONFIG_AMBARELLA_ETH_SUPPORT_IPC)
	amba_setbitsl(lp->regbase + ETH_DMA_OPMODE_OFFSET, ETH_DMA_OPMODE_TSF);
#endif
	amba_writel(lp->regbase + ETH_DMA_STATUS_OFFSET,
		amba_readl(lp->regbase + ETH_DMA_STATUS_OFFSET));
	amba_writel(lp->regbase + ETH_MAC_CFG_OFFSET,
		(ETH_MAC_CFG_TE | ETH_MAC_CFG_RE));
#if defined(CONFIG_AMBARELLA_ETH_SUPPORT_IPC)
	amba_setbitsl(lp->regbase + ETH_MAC_CFG_OFFSET, ETH_MAC_CFG_IPC);
#endif

ambhw_init_exit:
	return errorCode;
}

static inline void ambhw_disable(struct ambeth_info *lp)
{
	ambhw_stop_tx_rx(lp);
	ambhw_dma_int_disable(lp);
	ambarella_set_gpio_output(&lp->platform_info->mii_power, 0);
	ambarella_set_gpio_output(&lp->platform_info->mii_reset, 1);
}

static inline void ambhw_dump(struct ambeth_info *lp)
{
	u32					i;

	dev_info(&lp->ndev->dev, "RX Info: cur_rx %d, dirty_rx %d.\n",
		lp->rx.cur_rx, lp->rx.dirty_rx);
	dev_info(&lp->ndev->dev, "RX Info: RX descriptor "
		"0x%08x 0x%08x 0x%08x 0x%08x.\n",
		lp->rx.desc_rx[lp->rx.dirty_rx % lp->rx_count].status,
		lp->rx.desc_rx[lp->rx.dirty_rx % lp->rx_count].length,
		lp->rx.desc_rx[lp->rx.dirty_rx % lp->rx_count].buffer1,
		lp->rx.desc_rx[lp->rx.dirty_rx % lp->rx_count].buffer2);
	dev_info(&lp->ndev->dev, "TX Info: cur_tx %d, dirty_tx %d.\n",
		lp->tx.cur_tx, lp->tx.dirty_tx);
	for (i = lp->tx.dirty_tx; i < lp->tx.cur_tx; i++) {
		dev_info(&lp->ndev->dev, "TX Info: TX descriptor[%d] "
			"0x%08x 0x%08x 0x%08x 0x%08x.\n", i,
			lp->tx.desc_tx[i % lp->tx_count].status,
			lp->tx.desc_tx[i % lp->tx_count].length,
			lp->tx.desc_tx[i % lp->tx_count].buffer1,
			lp->tx.desc_tx[i % lp->tx_count].buffer2);
	}
	for (i = 0; i <= 21; i++) {
		dev_info(&lp->ndev->dev, "GMAC[%d]: 0x%08x.\n", i,
		amba_readl(lp->regbase + ETH_MAC_CFG_OFFSET + (i << 2)));
	}
	for (i = 0; i <= 54; i++) {
		dev_info(&lp->ndev->dev, "GDMA[%d]: 0x%08x.\n", i,
		amba_readl(lp->regbase + ETH_DMA_BUS_MODE_OFFSET + (i << 2)));
	}
}

/* ==========================================================================*/
static int ambhw_mdio_read(struct mii_bus *bus,
	int mii_id, int regnum)
{
	struct ambeth_info			*lp;
	int					val;
	int					limit;

	lp = (struct ambeth_info *)bus->priv;

	for (limit = lp->platform_info->mii_retry_limit; limit > 0; limit--) {
		if (!amba_tstbitsl(lp->regbase + ETH_MAC_GMII_ADDR_OFFSET,
			ETH_MAC_GMII_ADDR_GB))
			break;
		udelay(lp->platform_info->mii_retry_tmo);
	}
	if ((limit <= 0) && netif_msg_hw(lp)) {
		dev_err(&lp->ndev->dev, "MII Error: Preread tmo!\n");
		val = 0xFFFFFFFF;
		goto ambhw_mdio_read_exit;
	}

	val = ETH_MAC_GMII_ADDR_PA(mii_id) | ETH_MAC_GMII_ADDR_GR(regnum);
	val |= ETH_MAC_GMII_ADDR_CR_250_300MHZ | ETH_MAC_GMII_ADDR_GB;
	amba_writel(lp->regbase + ETH_MAC_GMII_ADDR_OFFSET, val);

	for (limit = lp->platform_info->mii_retry_limit; limit > 0; limit--) {
		if (!amba_tstbitsl(lp->regbase + ETH_MAC_GMII_ADDR_OFFSET,
			ETH_MAC_GMII_ADDR_GB))
			break;
		udelay(lp->platform_info->mii_retry_tmo);
	}
	if ((limit <= 0) && netif_msg_hw(lp)) {
		dev_err(&lp->ndev->dev, "MII Error: Postread tmo!\n");
		val = 0xFFFFFFFF;
		goto ambhw_mdio_read_exit;
	}

	val = amba_readl(lp->regbase + ETH_MAC_GMII_DATA_OFFSET);

ambhw_mdio_read_exit:
	if (netif_msg_hw(lp))
		dev_info(&lp->ndev->dev,
			"MII Read: id[0x%02x], add[0x%02x], val[0x%04x].\n",
			mii_id, regnum, val);

	return val;
}

static int ambhw_mdio_write(struct mii_bus *bus,
	int mii_id, int regnum, u16 value)
{
	int					errorCode = 0;
	struct ambeth_info			*lp;
	int					val;
	int					limit = 0;

	lp = (struct ambeth_info *)bus->priv;

	if (netif_msg_hw(lp))
		dev_info(&lp->ndev->dev,
			"MII Write: id[0x%02x], add[0x%02x], val[0x%04x].\n",
			mii_id, regnum, value);

	for (limit = lp->platform_info->mii_retry_limit; limit > 0; limit--) {
		if (!amba_tstbitsl(lp->regbase + ETH_MAC_GMII_ADDR_OFFSET,
			ETH_MAC_GMII_ADDR_GB))
			break;
		udelay(lp->platform_info->mii_retry_tmo);
	}
	if ((limit <= 0) && netif_msg_hw(lp)) {
		dev_err(&lp->ndev->dev, "MII Error: Prewrite tmo!\n");
		errorCode = -EIO;
		goto ambhw_mdio_write_exit;
	}

	val = value;
	amba_writel(lp->regbase + ETH_MAC_GMII_DATA_OFFSET, val);
	val = ETH_MAC_GMII_ADDR_PA(mii_id) | ETH_MAC_GMII_ADDR_GR(regnum);
	val |= ETH_MAC_GMII_ADDR_CR_250_300MHZ | ETH_MAC_GMII_ADDR_GW |
		ETH_MAC_GMII_ADDR_GB;
	amba_writel(lp->regbase + ETH_MAC_GMII_ADDR_OFFSET, val);

	for (limit = lp->platform_info->mii_retry_limit; limit > 0; limit--) {
		if (!amba_tstbitsl(lp->regbase + ETH_MAC_GMII_ADDR_OFFSET,
			ETH_MAC_GMII_ADDR_GB))
			break;
		udelay(lp->platform_info->mii_retry_tmo);
	}
	if ((limit <= 0) && netif_msg_hw(lp)) {
		dev_err(&lp->ndev->dev, "MII Error: Postwrite tmo!\n");
		errorCode = -EIO;
		goto ambhw_mdio_write_exit;
	}

ambhw_mdio_write_exit:
	return errorCode;
}

static int ambhw_mdio_reset(struct mii_bus *bus)
{
	int					errorCode = 0;
	struct ambeth_info			*lp;

	lp = (struct ambeth_info *)bus->priv;

	if (netif_msg_hw(lp))
		dev_info(&lp->ndev->dev, "MII Info: Power gpio = %d, "
			"Reset gpio = %d.\n",
			lp->platform_info->mii_power.gpio_id,
			lp->platform_info->mii_reset.gpio_id);

	ambarella_set_gpio_output(&lp->platform_info->mii_power, 0);
	ambarella_set_gpio_output(&lp->platform_info->mii_reset, 1);
	ambarella_set_gpio_output(&lp->platform_info->mii_power, 1);
	ambarella_set_gpio_output(&lp->platform_info->mii_reset, 0);

	return errorCode;
}

/* ==========================================================================*/
static void ambeth_adjust_link(struct net_device *ndev)
{
	struct ambeth_info			*lp;
	unsigned long				flags;
	struct phy_device			*phydev;
	int					need_update = 0;

	lp = (struct ambeth_info *)netdev_priv(ndev);

	spin_lock_irqsave(&lp->lock, flags);
	phydev = lp->phydev;
	if (phydev->link) {
		if (phydev->duplex != lp->oldduplex) {
			need_update = 1;
			lp->oldduplex = phydev->duplex;
		}
		if (phydev->speed != lp->oldspeed) {
			switch (phydev->speed) {
			case SPEED_1000:
			case SPEED_100:
			case SPEED_10:
				need_update = 1;
				lp->oldspeed = phydev->speed;
				break;
			default:
				if (netif_msg_link(lp))
					dev_warn(&lp->ndev->dev,
						"Unknown Speed(%d).\n",
						phydev->speed);
				break;
			}
		}
		if (lp->oldlink != phydev->link) {
			need_update = 1;
			lp->oldlink = phydev->link;
		}
	} else if (lp->oldlink) {
		need_update = 1;
		lp->oldlink = PHY_DOWN;
		lp->oldspeed = 0;
		lp->oldduplex = -1;
	}

	if (need_update) {
		ambhw_set_link_mode_speed(lp);
		if (netif_msg_link(lp))
			phy_print_status(phydev);
	}
	spin_unlock_irqrestore(&lp->lock, flags);
}

static int ambeth_phy_start(struct ambeth_info *lp)
{
	int					errorCode = 0;
	struct phy_device			*phydev;
	phy_interface_t				interface;
	struct net_device			*ndev;
	int					phy_addr;
	unsigned long				flags;

	spin_lock_irqsave(&lp->lock, flags);
	phydev = lp->phydev;
	spin_unlock_irqrestore(&lp->lock, flags);
	if (phydev)
		goto ambeth_init_phy_exit;

	ndev = lp->ndev;
	lp->oldlink = PHY_DOWN;
	lp->oldspeed = 0;
	lp->oldduplex = -1;

	phy_addr = lp->platform_info->mii_id;
	if ((phy_addr >= 0) && (phy_addr < PHY_MAX_ADDR)) {
		if (lp->new_bus.phy_map[phy_addr]) {
			phydev = lp->new_bus.phy_map[phy_addr];
			if (phydev->phy_id == lp->platform_info->phy_id) {
				goto ambeth_init_phy_default;
			}
		}
		dev_notice(&lp->ndev->dev,
			"Could not find default PHY in %d.\n", phy_addr);
	}
	goto ambeth_init_phy_scan;

ambeth_init_phy_default:
	if (netif_msg_hw(lp))
		dev_info(&lp->ndev->dev, "Find default PHY in %d!\n", phy_addr);
	if (ambarella_is_valid_gpio_irq(&lp->platform_info->phy_irq)) {
		ambarella_gpio_config(lp->platform_info->phy_irq.irq_gpio,
			lp->platform_info->phy_irq.irq_gpio_mode);
		phydev->irq = lp->platform_info->phy_irq.irq_line;
		phydev->irq_flags = lp->platform_info->phy_irq.irq_type;
	}
	goto ambeth_init_phy_connect;

ambeth_init_phy_scan:
	for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++) {
		if (lp->new_bus.phy_map[phy_addr]) {
			phydev = lp->new_bus.phy_map[phy_addr];
			if (phydev->phy_id == lp->platform_info->phy_id)
				goto ambeth_init_phy_connect;
		}
	}
	if (!phydev) {
		if (netif_msg_drv(lp))
			dev_err(&lp->ndev->dev, "No PHY device.\n");
		errorCode = -ENODEV;
		goto ambeth_init_phy_exit;
	} else {
		if (netif_msg_drv(lp))
			dev_notice(&lp->ndev->dev,
			"Try PHY[%d] whose id is 0x%08x!\n",
			phydev->addr, phydev->phy_id);
	}

ambeth_init_phy_connect:
	interface = ambhw_get_interface(lp);
	phydev = phy_connect(ndev, dev_name(&phydev->dev),
		&ambeth_adjust_link, 0, interface);
	if (IS_ERR(phydev)) {
		if (netif_msg_drv(lp))
			dev_err(&lp->ndev->dev, "Could not attach to PHY!\n");
		errorCode = PTR_ERR(phydev);
		goto ambeth_init_phy_exit;
	}

	phydev->supported &= lp->platform_info->phy_supported;
	phydev->advertising = phydev->supported;

	spin_lock_irqsave(&lp->lock, flags);
	lp->phydev = phydev;
	spin_unlock_irqrestore(&lp->lock, flags);

	errorCode = phy_start_aneg(phydev);

ambeth_init_phy_exit:
	return errorCode;
}

static void ambeth_phy_stop(struct ambeth_info *lp)
{
	struct phy_device			*phydev;
	unsigned long				flags;

	spin_lock_irqsave(&lp->lock, flags);
	phydev = lp->phydev;
	lp->phydev = NULL;
	spin_unlock_irqrestore(&lp->lock, flags);
	if (phydev)
		phy_disconnect(phydev);
}

static inline int ambeth_rx_rngmng_check_skb(struct ambeth_info *lp, u32 entry)
{
	int					errorCode = 0;
	dma_addr_t				mapping;
	struct sk_buff				*skb;

	if (lp->rx.rng_rx[entry].skb == NULL) {
		skb = dev_alloc_skb(AMBETH_PACKET_MAXFRAME);
		if (skb == NULL) {
			if (netif_msg_drv(lp))
				dev_err(&lp->ndev->dev,
				"RX Error: dev_alloc_skb.\n");
			errorCode = -ENOMEM;
			goto ambeth_rx_rngmng_skb_exit;
		}
		skb->dev = lp->ndev;
		skb->len = AMBETH_PACKET_MAXFRAME;
		mapping = dma_map_single(&lp->ndev->dev, skb->data,
			skb->len, DMA_FROM_DEVICE);
		lp->rx.rng_rx[entry].skb = skb;
		lp->rx.rng_rx[entry].mapping = mapping;
		lp->rx.desc_rx[entry].buffer1 = mapping;
	}

ambeth_rx_rngmng_skb_exit:
	return errorCode;
}

static inline void ambeth_rx_rngmng_init(struct ambeth_info *lp)
{
	int					i;

	lp->rx.cur_rx = 0;
	lp->rx.dirty_rx = 0;
	for (i = 0; i < lp->rx_count; i++) {
		if (ambeth_rx_rngmng_check_skb(lp, i))
			break;
		lp->rx.desc_rx[i].status = ETH_RDES0_OWN;
		lp->rx.desc_rx[i].length =
			ETH_RDES1_RCH | AMBETH_PACKET_MAXFRAME;
		lp->rx.desc_rx[i].buffer2 = (u32)lp->rx_dma_desc +
			((i + 1) * sizeof(struct ambeth_desc));
	}
	lp->rx.desc_rx[lp->rx_count - 1].buffer2 = (u32)lp->rx_dma_desc;
}

static inline void ambeth_rx_rngmng_refill(struct ambeth_info *lp)
{
	u32					entry;

	while (lp->rx.cur_rx > lp->rx.dirty_rx) {
		entry = lp->rx.dirty_rx % lp->rx_count;
		if (ambeth_rx_rngmng_check_skb(lp, entry))
			break;
		lp->rx.desc_rx[entry].status = ETH_RDES0_OWN;
		lp->rx.dirty_rx++;
	}
}

static inline void ambeth_rx_rngmng_del(struct ambeth_info *lp)
{
	int					i;
	dma_addr_t				mapping;
	struct sk_buff				*skb;

	for (i = 0; i < lp->rx_count; i++) {
		if (lp->rx.rng_rx) {
			skb = lp->rx.rng_rx[i].skb;
			mapping = lp->rx.rng_rx[i].mapping;
			lp->rx.rng_rx[i].skb = NULL;
			lp->rx.rng_rx[i].mapping = 0;
			if (skb) {
				dma_unmap_single(&lp->ndev->dev, mapping,
					skb->len, DMA_FROM_DEVICE);
				dev_kfree_skb(skb);
			}
		}
		if (lp->rx.desc_rx) {
			lp->rx.desc_rx[i].status = 0;
			lp->rx.desc_rx[i].length = 0;
			lp->rx.desc_rx[i].buffer1 = 0xBADF00D0;
			lp->rx.desc_rx[i].buffer2 = 0xBADF00D0;
		}
	}
}

static inline void ambeth_tx_rngmng_init(struct ambeth_info *lp)
{
	int					i;

	lp->tx.cur_tx = 0;
	lp->tx.dirty_tx = 0;
	for (i = 0; i < lp->tx_count; i++) {
		lp->tx.rng_tx[i].mapping = 0 ;
		lp->tx.desc_tx[i].length = (ETH_TDES1_LS | ETH_TDES1_FS |
			ETH_TDES1_TCH);
		lp->tx.desc_tx[i].buffer1 = 0;
		lp->tx.desc_tx[i].buffer2 = (u32)lp->tx_dma_desc +
			((i + 1) * sizeof(struct ambeth_desc));
	}
	lp->tx.desc_tx[lp->tx_count - 1].buffer2 = (u32)lp->tx_dma_desc;
}

static inline void ambeth_tx_rngmng_del(struct ambeth_info *lp)
{
	int					i;
	dma_addr_t				mapping;
	struct sk_buff				*skb;
	unsigned int				dirty_tx;
	u32					entry;
	u32					status;

	for (dirty_tx = lp->tx.dirty_tx; lp->tx.cur_tx > dirty_tx; dirty_tx++) {
		entry = dirty_tx % lp->tx_count;
		if (lp->tx.desc_tx) {
			status = lp->tx.desc_tx[entry].status;
			if (status & ETH_TDES0_OWN)
				lp->stats.tx_dropped++;
		}
	}
	for (i = 0; i < lp->tx_count; i++) {
		if (lp->tx.rng_tx) {
			skb = lp->tx.rng_tx[i].skb;
			mapping = lp->tx.rng_tx[i].mapping;
			lp->tx.rng_tx[i].skb = NULL;
			lp->tx.rng_tx[i].mapping = 0;
			if (skb) {
				dma_unmap_single(&lp->ndev->dev, mapping,
					skb->len, DMA_TO_DEVICE);
				dev_kfree_skb(skb);
			}
		}
		if (lp->tx.desc_tx) {
			lp->tx.desc_tx[i].status = 0;
			lp->tx.desc_tx[i].length = 0;
			lp->tx.desc_tx[i].buffer1 = 0xBADF00D0;
			lp->tx.desc_tx[i].buffer2 = 0xBADF00D0;
		}
	}
}

static inline void ambeth_check_dma_error(struct ambeth_info *lp,
	u32 irq_status)
{
	u32					miss_ov = 0;

	if (unlikely(irq_status & ETH_DMA_STATUS_AIS)) {
		if (irq_status & (ETH_DMA_STATUS_RU | ETH_DMA_STATUS_OVF))
			miss_ov = amba_readl(lp->regbase +
				ETH_DMA_MISS_FRAME_BOCNT_OFFSET);

		if (irq_status & ETH_DMA_STATUS_FBI) {
			if (netif_msg_drv(lp))
				dev_err(&lp->ndev->dev,
				"DMA Error: Fatal Bus Error 0x%x.\n",
				(irq_status & ETH_DMA_STATUS_EB_MASK));
		}
		if (irq_status & ETH_DMA_STATUS_ETI) {
			if (netif_msg_tx_err(lp))
				dev_err(&lp->ndev->dev,
				"DMA Error: Early Transmit.\n");
		}
		if (irq_status & ETH_DMA_STATUS_RWT) {
			if (netif_msg_rx_err(lp))
				dev_err(&lp->ndev->dev,
				"DMA Error: Receive Watchdog Timeout.\n");
		}
		if (irq_status & ETH_DMA_STATUS_RPS) {
			if (netif_msg_rx_err(lp))
				dev_err(&lp->ndev->dev,
				"DMA Error: Receive Process Stopped.\n");
		}
		if (irq_status & ETH_DMA_STATUS_RU) {
			if (miss_ov & ETH_DMA_MISS_FRAME_BOCNT_FRAME) {
				lp->stats.rx_dropped +=
					ETH_DMA_MISS_FRAME_BOCNT_HOST(miss_ov);
			}
			ambhw_dma_rx_stop(lp);
			if (netif_msg_rx_err(lp))
				dev_err(&lp->ndev->dev,
				"DMA Error: Receive Buffer Unavailable, %d.\n",
				ETH_DMA_MISS_FRAME_BOCNT_HOST(miss_ov));
		}
		if (irq_status & ETH_DMA_STATUS_UNF) {
			if (netif_msg_tx_err(lp))
				dev_err(&lp->ndev->dev,
				"DMA Error: Transmit Underflow.\n");
		}
		if (irq_status & ETH_DMA_STATUS_OVF) {
			if (miss_ov & ETH_DMA_MISS_FRAME_BOCNT_FIFO) {
				lp->stats.rx_fifo_errors +=
					ETH_DMA_MISS_FRAME_BOCNT_APP(miss_ov);
			}
			if (netif_msg_rx_err(lp))
				dev_err(&lp->ndev->dev,
				"DMA Error: Receive FIFO Overflow, %d.\n",
				ETH_DMA_MISS_FRAME_BOCNT_APP(miss_ov));
		}
		if (irq_status & ETH_DMA_STATUS_TJT) {
			lp->stats.tx_errors++;
			if (netif_msg_drv(lp))
				dev_err(&lp->ndev->dev,
				"DMA Error: Transmit Jabber Timeout.\n");
		}
		if (irq_status & ETH_DMA_STATUS_TPS) {
			if (netif_msg_tx_err(lp))
				dev_err(&lp->ndev->dev,
				"DMA Error: Transmit Process Stopped.\n");
		}
		if (netif_msg_tx_err(lp) || netif_msg_rx_err(lp)) {
			dev_err(&lp->ndev->dev, "DMA Error: Abnormal: 0x%x.\n",
				irq_status);
			ambhw_dump(lp);
		}
	}
}

static inline void ambeth_interrupt_rx(struct ambeth_info *lp, u32 irq_status)
{
	if (irq_status & AMBETH_RXDMA_STATUS) {
		dev_vdbg(&lp->ndev->dev, "RX IRQ[0x%x]!\n", irq_status);
		amba_clrbitsl(lp->regbase + ETH_DMA_INTEN_OFFSET,
			AMBETH_RXDMA_INTEN);
		napi_schedule(&lp->napi);
	}
}

static inline u32 ambeth_check_tdes0_status(struct ambeth_info *lp,
	unsigned int status)
{
	u32					tx_retry = 0;

	if (status & ETH_TDES0_JT) {
		lp->stats.tx_heartbeat_errors++;
		if (netif_msg_drv(lp))
			dev_err(&lp->ndev->dev, "TX Error: Jabber Timeout.\n");
	}
	if (status & ETH_TDES0_FF) {
		lp->stats.tx_dropped++;
		if (netif_msg_drv(lp))
			dev_err(&lp->ndev->dev, "TX Error: Frame Flushed.\n");
	}
	if (status & ETH_TDES0_PCE) {
		lp->stats.tx_fifo_errors++;
		if (netif_msg_drv(lp))
			dev_err(&lp->ndev->dev,
			"TX Error: Payload Checksum Error.\n");
	}
	if (status & ETH_TDES0_LCA) {
		lp->stats.tx_carrier_errors++;
		dev_err(&lp->ndev->dev, "TX Error: Loss of Carrier.\n");
	}
	if (status & ETH_TDES0_NC) {
		lp->stats.tx_carrier_errors++;
		if (netif_msg_drv(lp))
			dev_err(&lp->ndev->dev, "TX Error: No Carrier.\n");
	}
	if (status & ETH_TDES0_LCO) {
		lp->stats.tx_aborted_errors++;
		lp->stats.collisions++;
		if (netif_msg_drv(lp))
			dev_err(&lp->ndev->dev, "TX Error: Late Collision.\n");
	}
	if (status & ETH_TDES0_EC) {
		lp->stats.tx_aborted_errors++;
		lp->stats.collisions += ETH_TDES0_CC(status);
		if (netif_msg_drv(lp))
			dev_err(&lp->ndev->dev,
			"TX Error: Excessive Collision %d.\n",
			ETH_TDES0_CC(status));
	}
	if (status & ETH_TDES0_VF) {
		if (netif_msg_drv(lp))
			dev_info(&lp->ndev->dev, "TX Info: VLAN Frame.\n");
	}
	if (status & ETH_TDES0_ED) {
		lp->stats.tx_fifo_errors++;
		if (netif_msg_drv(lp))
			dev_err(&lp->ndev->dev,
			"TX Error: Excessive Deferral.\n");
	}
	if (status & ETH_TDES0_UF) {
		tx_retry = 1;
		if (netif_msg_tx_err(lp)) {
			dev_err(&lp->ndev->dev, "TX Error: Underflow Error.\n");
			ambhw_dump(lp);
		}
	}
	if (status & ETH_TDES0_DB) {
		lp->stats.tx_fifo_errors++;
		if (netif_msg_drv(lp))
			dev_err(&lp->ndev->dev, "TX Error: Deferred Bit.\n");
	}

	return tx_retry;
}

static inline void ambeth_interrupt_tx(struct ambeth_info *lp, u32 irq_status)
{
	unsigned int				dirty_tx;
	unsigned int				dirty_to_tx;
	u32					entry;
	u32					status;

	if (irq_status & AMBETH_TXDMA_STATUS) {
		dev_vdbg(&lp->ndev->dev, "cur_tx[%d], dirty_tx[%d], 0x%x.\n",
			lp->tx.cur_tx, lp->tx.dirty_tx, irq_status);
		for (dirty_tx = lp->tx.dirty_tx; dirty_tx < lp->tx.cur_tx;
			dirty_tx++) {
			entry = dirty_tx % lp->tx_count;
			status = lp->tx.desc_tx[entry].status;

			if (status & ETH_TDES0_OWN)
				break;

			if (unlikely(status & ETH_TDES0_ES)) {
#if defined(AMBETH_TDES0_ATOMIC_CHECK)
				if ((status & ETH_TDES0_ES_MASK) ==
					ETH_TDES0_ES) {
					if (netif_msg_probe(lp)) {
						dev_err(&lp->ndev->dev,
						"TX Error: Wrong ES"
						" 0x%08x vs 0x%08x.\n",
						status,
						lp->tx.desc_tx[entry].status);
						ambhw_dump(lp);
					}
					break;
				}
#endif
				if (ambeth_check_tdes0_status(lp, status)) {
					ambhw_dma_tx_stop(lp);
					ambhw_dma_tx_restart(lp, entry);
					ambhw_dma_tx_poll(lp, entry);
					break;
				} else {
					lp->stats.tx_errors++;
				}
			} else {
#if defined(AMBETH_TDES0_ATOMIC_CHECK_ALL)
				udelay(1);
				if (unlikely(status !=
					lp->tx.desc_tx[entry].status)) {
					if (netif_msg_probe(lp)) {
						dev_err(&lp->ndev->dev,
						"TX Error: Wrong status"
						" 0x%08x vs 0x%08x.\n",
						status,
						lp->tx.desc_tx[entry].status);
						ambhw_dump(lp);
					}
				}
#endif
#if defined(CONFIG_AMBARELLA_ETH_SUPPORT_IPC)
				if (unlikely(status & ETH_TDES0_IHE)) {
					if (netif_msg_drv(lp))
						dev_err(&lp->ndev->dev,
						"TX Error: IP Header Error.\n");
				}
#endif
				lp->stats.tx_bytes +=
					lp->tx.rng_tx[entry].skb->len;
				lp->stats.tx_packets++;
			}

			dma_unmap_single(&lp->ndev->dev,
				lp->tx.rng_tx[entry].mapping,
				lp->tx.rng_tx[entry].skb->len,
				DMA_TO_DEVICE);
			dev_kfree_skb_irq(lp->tx.rng_tx[entry].skb);
			lp->tx.rng_tx[entry].skb = NULL;
			lp->tx.rng_tx[entry].mapping = 0;
		}

		dirty_to_tx = lp->tx.cur_tx - dirty_tx;
		if (unlikely(dirty_to_tx > lp->tx_count)) {
			netif_stop_queue(lp->ndev);
			if (netif_msg_drv(lp))
				dev_err(&lp->ndev->dev, "TX Error: TX OV.\n");
			ambhw_dump(lp);
			ambhw_dma_tx_stop(lp);
			ambeth_tx_rngmng_del(lp);
			ambeth_tx_rngmng_init(lp);
			dirty_tx = dirty_to_tx = 0;
		}
		if (likely(dirty_to_tx < (lp->tx_count / 2))) {
			dev_vdbg(&lp->ndev->dev, "TX Info: Now gap %d.\n",
				dirty_to_tx);
			netif_wake_queue(lp->ndev);
		}
		lp->tx.dirty_tx = dirty_tx;
	}
}

static irqreturn_t ambeth_interrupt(int irq, void *dev_id)
{
	struct net_device			*ndev;
	struct ambeth_info			*lp;
	u32					irq_status;
	unsigned long				flags;

	ndev = (struct net_device *)dev_id;
	lp = netdev_priv(ndev);

	spin_lock_irqsave(&lp->lock, flags);
	irq_status = amba_readl(lp->regbase + ETH_DMA_STATUS_OFFSET);
	ambeth_check_dma_error(lp, irq_status);
	ambeth_interrupt_rx(lp, irq_status);
	ambeth_interrupt_tx(lp, irq_status);
	amba_writel(lp->regbase + ETH_DMA_STATUS_OFFSET, irq_status);
	spin_unlock_irqrestore(&lp->lock, flags);

	return IRQ_HANDLED;
}

static int ambeth_start_hw(struct net_device *ndev)
{
	int					errorCode = 0;
	struct ambeth_info			*lp;
	unsigned long				flags;

	lp = (struct ambeth_info *)netdev_priv(ndev);

	spin_lock_irqsave(&lp->lock, flags);
	errorCode = ambhw_enable(lp);
	spin_unlock_irqrestore(&lp->lock, flags);
	if (errorCode)
		goto ambeth_start_hw_exit;

	lp->rx.rng_rx = kmalloc((sizeof(struct ambeth_rng_info) *
		lp->rx_count), GFP_KERNEL);
	if (lp->rx.rng_rx == NULL) {
		if (netif_msg_drv(lp))
			dev_err(&lp->ndev->dev, "alloc rng_rx fail.\n");
		errorCode = -ENOMEM;
		goto ambeth_start_hw_exit;
	}
	lp->rx.desc_rx = dma_alloc_coherent(&lp->ndev->dev,
		(sizeof(struct ambeth_desc) * lp->rx_count),
		&lp->rx_dma_desc, GFP_KERNEL);
	if (lp->rx.desc_rx == NULL) {
		if (netif_msg_drv(lp))
			dev_err(&lp->ndev->dev,
			"dma_alloc_coherent desc_rx fail.\n");
		errorCode = -ENOMEM;
		goto ambeth_start_hw_exit;
	}
	memset(lp->rx.rng_rx, 0,
		(sizeof(struct ambeth_rng_info) * lp->rx_count));
	memset(lp->rx.desc_rx, 0,
		(sizeof(struct ambeth_desc) * lp->rx_count));
	ambeth_rx_rngmng_init(lp);

	lp->tx.rng_tx = kmalloc((sizeof(struct ambeth_rng_info) *
		lp->tx_count), GFP_KERNEL);
	if (lp->tx.rng_tx == NULL) {
		if (netif_msg_drv(lp))
			dev_err(&lp->ndev->dev, "alloc rng_tx fail.\n");
		errorCode = -ENOMEM;
		goto ambeth_start_hw_exit;
	}
	lp->tx.desc_tx = dma_alloc_coherent(&lp->ndev->dev,
		(sizeof(struct ambeth_desc) * lp->tx_count),
		&lp->tx_dma_desc, GFP_KERNEL);
	if (lp->tx.desc_tx == NULL) {
		if (netif_msg_drv(lp))
			dev_err(&lp->ndev->dev,
			"dma_alloc_coherent desc_tx fail.\n");
		errorCode = -ENOMEM;
		goto ambeth_start_hw_exit;
	}
	memset(lp->tx.rng_tx, 0,
		(sizeof(struct ambeth_rng_info) * lp->tx_count));
	memset(lp->tx.desc_tx, 0,
		(sizeof(struct ambeth_desc) * lp->tx_count));
	ambeth_tx_rngmng_init(lp);

	spin_lock_irqsave(&lp->lock, flags);
	ambhw_set_dma_desc(lp);
	ambhw_dma_rx_start(lp);
	ambhw_dma_tx_start(lp);
	spin_unlock_irqrestore(&lp->lock, flags);

ambeth_start_hw_exit:
	return errorCode;
}

static void ambeth_stop_hw(struct net_device *ndev)
{
	struct ambeth_info			*lp;
	unsigned long				flags;

	lp = (struct ambeth_info *)netdev_priv(ndev);

	spin_lock_irqsave(&lp->lock, flags);
	ambhw_disable(lp);
	spin_unlock_irqrestore(&lp->lock, flags);

	ambeth_tx_rngmng_del(lp);
	if (lp->tx.desc_tx) {
		dma_free_coherent(&lp->ndev->dev,
			(sizeof(struct ambeth_desc) * lp->tx_count),
			lp->tx.desc_tx, lp->tx_dma_desc);
		lp->tx.desc_tx = NULL;
	}
	if (lp->tx.rng_tx) {
		kfree(lp->tx.rng_tx);
		lp->tx.rng_tx = NULL;
	}

	ambeth_rx_rngmng_del(lp);
	if (lp->rx.desc_rx) {
		dma_free_coherent(&lp->ndev->dev,
			(sizeof(struct ambeth_desc) * lp->rx_count),
			lp->rx.desc_rx, lp->rx_dma_desc);
		lp->rx.desc_rx = NULL;
	}
	if (lp->rx.rng_rx) {
		kfree(lp->rx.rng_rx);
		lp->rx.rng_rx = NULL;
	}
}

static int ambeth_open(struct net_device *ndev)
{
	int					errorCode = 0;
	struct ambeth_info			*lp;

	lp = (struct ambeth_info *)netdev_priv(ndev);

	errorCode = ambeth_start_hw(ndev);
	if (errorCode)
		goto ambeth_open_exit;

	errorCode = request_irq(ndev->irq, ambeth_interrupt,
		IRQF_SHARED | IRQF_TRIGGER_HIGH, ndev->name, ndev);
	if (errorCode) {
		if (netif_msg_drv(lp))
			dev_err(&lp->ndev->dev,
			"Request_irq[%d] fail.\n", ndev->irq);
		goto ambeth_open_exit;
	}

	napi_enable(&lp->napi);
	netif_start_queue(ndev);
	ambhw_dma_int_enable(lp);

	netif_carrier_off(ndev);
	errorCode = ambeth_phy_start(lp);

ambeth_open_exit:
	if (errorCode) {
		ambeth_phy_stop(lp);
		ambeth_stop_hw(ndev);
	}

	return errorCode;
}

static int ambeth_stop(struct net_device *ndev)
{
	int					errorCode = 0;
	struct ambeth_info			*lp;

	lp = (struct ambeth_info *)netdev_priv(ndev);

	netif_stop_queue(ndev);
	napi_disable(&lp->napi);
	flush_scheduled_work();
	free_irq(ndev->irq, ndev);
	ambeth_phy_stop(lp);
	ambeth_stop_hw(ndev);

	return errorCode;
}

static int ambeth_hard_start_xmit(struct sk_buff *skb, struct net_device *ndev)
{
	int					errorCode = 0;
	struct ambeth_info			*lp;
	dma_addr_t				mapping;
	u32					entry;
	unsigned int				dirty_to_tx;
	u32					tx_flag;
	unsigned long				flags;

	lp = (struct ambeth_info *)netdev_priv(ndev);

	spin_lock_irqsave(&lp->lock, flags);
	entry = lp->tx.cur_tx % lp->tx_count;
	dirty_to_tx = lp->tx.cur_tx - lp->tx.dirty_tx;
	if (dirty_to_tx >= lp->tx_count) {
		netif_stop_queue(ndev);
		errorCode = -ENOMEM;
		spin_unlock_irqrestore(&lp->lock, flags);
		goto ambeth_hard_start_xmit_exit;
	}

	mapping = dma_map_single(&lp->ndev->dev,
		skb->data, skb->len, DMA_TO_DEVICE);
	tx_flag = ETH_TDES1_LS | ETH_TDES1_FS | ETH_TDES1_TCH;
	if (dirty_to_tx >= lp->tx_irq_count) {
		netif_stop_queue(ndev);
		tx_flag |= ETH_TDES1_IC;
	}
#if defined(CONFIG_AMBARELLA_ETH_SUPPORT_IPC)
	if (skb->ip_summed == CHECKSUM_PARTIAL) {
		tx_flag |= ETH_TDES1_CIC_TUI | ETH_TDES1_CIC_HDR;
	}
#endif
	lp->tx.rng_tx[entry].skb = skb;
	lp->tx.rng_tx[entry].mapping = mapping;
	lp->tx.desc_tx[entry].buffer1 = mapping;
	lp->tx.desc_tx[entry].length = ETH_TDES1_TBS1x(skb->len) | tx_flag;
	lp->tx.cur_tx++;
	ambhw_dma_tx_poll(lp, entry);
	spin_unlock_irqrestore(&lp->lock, flags);

	ndev->trans_start = jiffies;
	dev_vdbg(&lp->ndev->dev, "TX Info: cur_tx[%d], dirty_tx[%d], "
		"entry[%d], len[%d], data_len[%d], ip_summed[%d], "
		"csum_start[%d], csum_offset[%d].\n",
		lp->tx.cur_tx, lp->tx.dirty_tx, entry, skb->len, skb->data_len,
		skb->ip_summed, skb->csum_start, skb->csum_offset);

ambeth_hard_start_xmit_exit:
	return errorCode;
}

static void ambeth_timeout(struct net_device *ndev)
{
	struct ambeth_info			*lp;
	unsigned long				flags;
	u32					irq_status;

	lp = (struct ambeth_info *)netdev_priv(ndev);

	dev_info(&lp->ndev->dev, "OOM Info:...\n");
	spin_lock_irqsave(&lp->lock, flags);
	irq_status = amba_readl(lp->regbase + ETH_DMA_STATUS_OFFSET);
	ambeth_interrupt_tx(lp, irq_status | AMBETH_TXDMA_STATUS);
	ambhw_dump(lp);
	spin_unlock_irqrestore(&lp->lock, flags);

	netif_wake_queue(ndev);
}

static struct net_device_stats *ambeth_get_stats(struct net_device *ndev)
{
	struct ambeth_info *lp = netdev_priv(ndev);

	return &lp->stats;
}

static inline void ambeth_check_rdes0_status(struct ambeth_info *lp,
	unsigned int status)
{
	if (status & ETH_RDES0_DE) {
		lp->stats.rx_frame_errors++;
		if (netif_msg_drv(lp))
			dev_err(&lp->ndev->dev,
			"RX Error: Descriptor Error.\n");
	}
	if (status & ETH_RDES0_SAF) {
		if (netif_msg_drv(lp))
			dev_err(&lp->ndev->dev,
			"RX Error: Source Address Filter Fail.\n");
	}
	if (status & ETH_RDES0_LE) {
		lp->stats.rx_length_errors++;
		if (netif_msg_drv(lp))
			dev_err(&lp->ndev->dev, "RX Error: Length Error.\n");
	}
	if (status & ETH_RDES0_OE) {
		lp->stats.rx_over_errors++;
		if (netif_msg_rx_err(lp))
			dev_err(&lp->ndev->dev, "RX Error: Overflow Error.\n");
	}
	if (status & ETH_RDES0_VLAN) {
		if (netif_msg_drv(lp))
			dev_info(&lp->ndev->dev, "RX Info: VLAN.\n");
	}
	if (status & ETH_RDES0_IPC) {
		if (netif_msg_drv(lp))
			dev_err(&lp->ndev->dev,
			"RX Error: IPC Checksum/Giant Frame.\n");
	}
	if (status & ETH_RDES0_LC) {
		lp->stats.collisions++;
		if (netif_msg_drv(lp))
			dev_err(&lp->ndev->dev, "RX Error: Late Collision.\n");
	}
	if (status & ETH_RDES0_FT) {
		if (netif_msg_rx_err(lp))
			dev_info(&lp->ndev->dev,
			"RX Info: Ethernet-type frame.\n");
	}
	if (status & ETH_RDES0_RWT) {
		if (netif_msg_drv(lp))
			dev_err(&lp->ndev->dev,
			"RX Error: Watchdog Timeout.\n");
	}
	if (status & ETH_RDES0_RE) {
		lp->stats.rx_errors++;
		if (netif_msg_rx_err(lp))
			dev_err(&lp->ndev->dev, "RX Error: Receive.\n");
	}
	if (status & ETH_RDES0_DBE) {
		if (amba_tstbitsl(lp->regbase + ETH_MAC_CFG_OFFSET,
			ETH_MAC_CFG_PS)) {
			lp->stats.rx_length_errors++;
			if (netif_msg_drv(lp))
				dev_err(&lp->ndev->dev,
				"RX Error: Dribble Bit.\n");
		}
	}
	if (status & ETH_RDES0_CE) {
		lp->stats.rx_crc_errors++;
		if (netif_msg_rx_err(lp))
			dev_err(&lp->ndev->dev, "RX Error: CRC.\n");
	}
	if (status & ETH_RDES0_RX) {
		if (netif_msg_drv(lp))
			dev_err(&lp->ndev->dev,
			"RX Error: Rx MAC Address/Payload Checksum.\n");
	}
}

static inline void ambeth_napi_rx(struct ambeth_info *lp, u32 status, u32 entry)
{
	short					pkt_len;
	struct sk_buff				*skb;
	dma_addr_t				mapping;

	pkt_len = ETH_RDES0_FL(status) - 4;

	if (unlikely(pkt_len > AMBETH_RX_COPYBREAK)) {
		dev_warn(&lp->ndev->dev, "Bogus packet size %d.\n", pkt_len);
		pkt_len = AMBETH_RX_COPYBREAK;
		lp->stats.rx_length_errors++;
	}

	skb = lp->rx.rng_rx[entry].skb;
	mapping = lp->rx.rng_rx[entry].mapping;
	if (likely(skb && mapping)) {
		dma_unmap_single(&lp->ndev->dev, mapping,
			skb->len, DMA_FROM_DEVICE);
		skb_put(skb, pkt_len);
		skb->protocol = eth_type_trans(skb, lp->ndev);
#if defined(CONFIG_AMBARELLA_ETH_SUPPORT_IPC)
		if ((status & ETH_RDES0_COE_MASK) == ETH_RDES0_COE_NOCHKERROR) {
			skb->ip_summed = CHECKSUM_UNNECESSARY;
		} else {
			skb->ip_summed = CHECKSUM_NONE;
			if (netif_msg_rx_err(lp)) {
				dev_err(&lp->ndev->dev,
				"RX Error: RDES0_COE[0x%x].\n", status);
				ambhw_dump(lp);
			}
		}
#endif
		netif_receive_skb(skb);
		lp->rx.rng_rx[entry].skb = NULL;
		lp->rx.rng_rx[entry].mapping = 0;
		lp->ndev->last_rx = jiffies;
		lp->stats.rx_packets++;
		lp->stats.rx_bytes += pkt_len;
	} else {
		if (netif_msg_drv(lp)) {
			dev_err(&lp->ndev->dev,
			"RX Error: %d skb[%p], map[0x%08X].\n",
			entry, skb, mapping);
			ambhw_dump(lp);
		}
	}
}

int ambeth_napi(struct napi_struct *napi, int budget)
{
	int					rx_budget = budget;
	struct ambeth_info			*lp;
	u32					entry;
	u32					status;
	unsigned long				flags;

	lp = container_of(napi, struct ambeth_info, napi);

	if (unlikely(!netif_carrier_ok(lp->ndev)))
		goto ambeth_poll_complete;

	while (rx_budget > 0) {
		entry = lp->rx.cur_rx % lp->rx_count;
		status = lp->rx.desc_rx[entry].status;
		if (status & ETH_RDES0_OWN)
			break;
#if defined(AMBETH_RDES0_ATOMIC_CHECK)
		if (unlikely((status & (ETH_RDES0_FS | ETH_RDES0_LS)) !=
			(ETH_RDES0_FS | ETH_RDES0_LS))) {
			if (netif_msg_probe(lp)) {
				dev_err(&lp->ndev->dev, "RX Error: Wrong FS/LS"
				" cur_rx[%d] status 0x%08x.\n",
				lp->rx.cur_rx, status);
				ambhw_dump(lp);
			}
			break;
		}
#endif
#if defined(AMBETH_TDES0_ATOMIC_CHECK_ALL)
		udelay(1);
		if (unlikely(status != lp->rx.desc_rx[entry].status)) {
			if (netif_msg_probe(lp)) {
				dev_err(&lp->ndev->dev, "RX Error: Wrong status"
				" 0x%08x vs 0x%08x.\n",
				status, lp->rx.desc_rx[entry].status);
				ambhw_dump(lp);
			}
		}
#endif
		if (likely((status & ETH_RDES0_ES) != ETH_RDES0_ES)) {
			ambeth_napi_rx(lp, status, entry);
		} else {
			ambeth_check_rdes0_status(lp, status);
		}
		rx_budget--;
		lp->rx.cur_rx++;

		if ((lp->rx.cur_rx - lp->rx.dirty_rx) > (lp->rx_count / 4))
			ambeth_rx_rngmng_refill(lp);
	}

ambeth_poll_complete:
	if (rx_budget > 0) {
		ambeth_rx_rngmng_refill(lp);
		spin_lock_irqsave(&lp->lock, flags);
		napi_complete(&lp->napi);
		amba_setbitsl(lp->regbase + ETH_DMA_INTEN_OFFSET,
			AMBETH_RXDMA_INTEN);
		ambhw_dma_rx_start(lp);
		spin_unlock_irqrestore(&lp->lock, flags);
	}

	return (budget - rx_budget);
}

static inline u32 ambhw_hashtable_crc(unsigned char *mac)
{
	unsigned char				tmpbuf[ETH_ALEN];
	int					i;
	u32					crc;

	for (i = 0; i < ETH_ALEN; i++)
		tmpbuf[i] = bitrev8(mac[i]);
	crc = crc32_be(~0, tmpbuf, ETH_ALEN);

	return (crc ^ ~0);
}

static inline void ambhw_hashtable_get(struct net_device *ndev, u32 *hat)
{
	struct netdev_hw_addr			*ha;
	unsigned int				bitnr;
#if 0
	unsigned char test1[] = {0x1F,0x52,0x41,0x9C,0xB6,0xAF};
	unsigned char test2[] = {0xA0,0x0A,0x98,0x00,0x00,0x45};
	dev_info(&ndev->dev,
		"Test1: 0x%08X.\n", ambhw_hashtable_crc(test1));
	dev_info(&ndev->dev,
		"Test2: 0x%08X.\n", ambhw_hashtable_crc(test2));
#endif

	hat[0] = hat[1] = 0;
	netdev_for_each_mc_addr(ha, ndev) {
		if (!(ha->addr[0] & 1))
			continue;
		bitnr = ambhw_hashtable_crc(ha->addr);
		bitnr >>= 26;
		bitnr &= 0x3F;
		hat[bitnr >> 5] |= 1 << (bitnr & 31);
	}
}

static void ambeth_set_multicast_list(struct net_device *ndev)
{
	struct ambeth_info			*lp;
	unsigned int				mac_filter;
	u32					hat[2];
	unsigned long				flags;

	lp = (struct ambeth_info *)netdev_priv(ndev);
	spin_lock_irqsave(&lp->lock, flags);

	mac_filter = amba_readl(lp->regbase + ETH_MAC_FRAME_FILTER_OFFSET);
	hat[0] = 0;
	hat[1] = 0;

	if (ndev->flags & IFF_PROMISC) {
		mac_filter |= ETH_MAC_FRAME_FILTER_PR;
	} else if (ndev->flags & (~IFF_PROMISC)) {
		mac_filter &= ~ETH_MAC_FRAME_FILTER_PR;
	}

	if (ndev->flags & IFF_ALLMULTI) {
		hat[0] = 0xFFFFFFFF;
		hat[1] = 0xFFFFFFFF;
		mac_filter |= ETH_MAC_FRAME_FILTER_PM;
	} else if (!netdev_mc_empty(ndev)) {
		ambhw_hashtable_get(ndev, hat);
		mac_filter &= ~ETH_MAC_FRAME_FILTER_PM;
		mac_filter |= ETH_MAC_FRAME_FILTER_HMC;
	} else if (ndev->flags & (~IFF_ALLMULTI)) {
		mac_filter &= ~ETH_MAC_FRAME_FILTER_PM;
		mac_filter |= ETH_MAC_FRAME_FILTER_HMC;
	}

	if (netif_msg_hw(lp)) {
		dev_info(&lp->ndev->dev, "MC Info: flags 0x%x.\n", ndev->flags);
		dev_info(&lp->ndev->dev, "MC Info: mc_count 0x%x.\n",
			netdev_mc_count(ndev));
		dev_info(&lp->ndev->dev, "MC Info: mac_filter 0x%x.\n",
			mac_filter);
		dev_info(&lp->ndev->dev, "MC Info: hat[0x%x:0x%x].\n",
			hat[1], hat[0]);
	}

	amba_writel(lp->regbase + ETH_MAC_HASH_HI_OFFSET, hat[1]);
	amba_writel(lp->regbase + ETH_MAC_HASH_LO_OFFSET, hat[0]);
	amba_writel(lp->regbase + ETH_MAC_FRAME_FILTER_OFFSET, mac_filter);

	spin_unlock_irqrestore(&lp->lock, flags);
}

static int ambeth_set_mac_address(struct net_device *ndev, void *addr)
{
	struct ambeth_info			*lp;
	unsigned long				flags;
	struct sockaddr				*saddr;

	lp = (struct ambeth_info *)netdev_priv(ndev);
	spin_lock_irqsave(&lp->lock, flags);
	saddr = (struct sockaddr *)(addr);

	if (netif_running(ndev))
		return -EBUSY;

	if (!is_valid_ether_addr(saddr->sa_data))
		return -EADDRNOTAVAIL;

	dev_dbg(&lp->ndev->dev, "MAC address[%pM].\n", saddr->sa_data);

	memcpy(ndev->dev_addr, saddr->sa_data, ndev->addr_len);
	ambhw_set_hwaddr(lp, ndev->dev_addr);
	ambhw_get_hwaddr(lp, ndev->dev_addr);
	memcpy(lp->platform_info->mac_addr, ndev->dev_addr, AMBETH_MAC_SIZE);

	spin_unlock_irqrestore(&lp->lock, flags);

	return 0;
}

#ifdef CONFIG_NET_POLL_CONTROLLER
static void ambeth_poll_controller(struct net_device *ndev)
{
	ambeth_interrupt(ndev->irq, ndev);
}
#endif

static int ambeth_get_settings(struct net_device *ndev,
	struct ethtool_cmd *ecmd)
{
	int					errorCode = 0;
	struct ambeth_info			*lp;
	unsigned long				flags;

	if (!netif_running(ndev)) {
		errorCode = -EINVAL;
		goto ambeth_get_settings_exit;
	}

	lp = (struct ambeth_info *)netdev_priv(ndev);
	spin_lock_irqsave(&lp->lock, flags);
	if (lp->phydev) {
		errorCode = phy_ethtool_gset(lp->phydev, ecmd);
	} else {
		errorCode = -EINVAL;
	}
	spin_unlock_irqrestore(&lp->lock, flags);

ambeth_get_settings_exit:
	return errorCode;
}

static int ambeth_set_settings(struct net_device *ndev,
	struct ethtool_cmd *ecmd)
{
	int					errorCode = 0;
	struct ambeth_info			*lp;
	unsigned long				flags;

	if (!netif_running(ndev)) {
		errorCode = -EINVAL;
		goto ambeth_get_settings_exit;
	}

	lp = (struct ambeth_info *)netdev_priv(ndev);
	spin_lock_irqsave(&lp->lock, flags);
	if (lp->phydev) {
		errorCode = phy_ethtool_sset(lp->phydev, ecmd);
	} else {
		errorCode = -EINVAL;
	}
	spin_unlock_irqrestore(&lp->lock, flags);

ambeth_get_settings_exit:
	return errorCode;
}

static int ambeth_ioctl(struct net_device *ndev, struct ifreq *ifr, int cmd)
{
	int					errorCode = 0;
	struct ambeth_info			*lp;
	unsigned long				flags;

	if (!netif_running(ndev)) {
		errorCode = -EINVAL;
		goto ambeth_get_settings_exit;
	}

	lp = (struct ambeth_info *)netdev_priv(ndev);
	spin_lock_irqsave(&lp->lock, flags);
	if (lp->phydev) {
		errorCode = phy_mii_ioctl(lp->phydev, ifr, cmd);
	} else {
		errorCode = -EINVAL;
	}
	spin_unlock_irqrestore(&lp->lock, flags);

ambeth_get_settings_exit:
	return errorCode;
}

/* ==========================================================================*/
static const struct net_device_ops ambeth_netdev_ops = {
	.ndo_open		= ambeth_open,
	.ndo_stop		= ambeth_stop,
	.ndo_start_xmit		= ambeth_hard_start_xmit,
	.ndo_set_multicast_list	= ambeth_set_multicast_list,
	.ndo_set_mac_address 	= ambeth_set_mac_address,
	.ndo_validate_addr	= eth_validate_addr,
	.ndo_do_ioctl		= ambeth_ioctl,
	.ndo_change_mtu		= eth_change_mtu,
	.ndo_tx_timeout		= ambeth_timeout,
	.ndo_get_stats		= ambeth_get_stats,
#ifdef CONFIG_NET_POLL_CONTROLLER
	.ndo_poll_controller	= ambeth_poll_controller,
#endif
};

static const struct ethtool_ops ambeth_ethtool_ops = {
	.get_settings	= ambeth_get_settings,
	.set_settings	= ambeth_set_settings,
	.get_link	= ethtool_op_get_link,
};

static int __devinit ambeth_drv_probe(struct platform_device *pdev)
{
	int					errorCode = 0;
	struct net_device			*ndev;
	struct ambeth_info			*lp;
	struct ambarella_eth_platform_info	*platform_info;
	struct resource				*reg_res;
	struct resource				*irq_res;
	int					i;

	platform_info =
		(struct ambarella_eth_platform_info *)pdev->dev.platform_data;
	if (platform_info == NULL) {
		dev_err(&pdev->dev, "Can't get platform_data!\n");
		errorCode = - EPERM;
		goto ambeth_drv_probe_exit;
	}
	if (platform_info->is_enabled) {
		if (!platform_info->is_enabled()) {
			dev_err(&pdev->dev, "Not enabled, check HW config!\n");
			errorCode = -EPERM;
			goto ambeth_drv_probe_exit;
		}
	}

	reg_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (reg_res == NULL) {
		dev_err(&pdev->dev, "Get reg_res failed!\n");
		errorCode = -ENXIO;
		goto ambeth_drv_probe_exit;
	}

	irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
	if (irq_res == NULL) {
		dev_err(&pdev->dev, "Get irq_res failed!\n");
		errorCode = -ENXIO;
		goto ambeth_drv_probe_exit;
	}

	ndev = alloc_etherdev(sizeof(struct ambeth_info));
	if (ndev == NULL) {
		dev_err(&pdev->dev, "alloc_etherdev fail.\n");
		errorCode = -ENOMEM;
		goto ambeth_drv_probe_exit;
	}
	SET_NETDEV_DEV(ndev, &pdev->dev);
	ndev->dev.dma_mask = pdev->dev.dma_mask;
	ndev->dev.coherent_dma_mask = pdev->dev.coherent_dma_mask;
	ndev->irq = irq_res->start;
#if defined(CONFIG_AMBARELLA_ETH_SUPPORT_IPC)
	ndev->features = NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
#endif
	lp = netdev_priv(ndev);
	spin_lock_init(&lp->lock);
	lp->ndev = ndev;
	lp->regbase = (unsigned char __iomem *)reg_res->start;
	lp->platform_info = platform_info;
	lp->rx_count = lp->platform_info->default_rx_ring_size;
	if (lp->rx_count < AMBETH_RX_RNG_MIN)
		lp->rx_count = AMBETH_RX_RNG_MIN;
	lp->tx_count = lp->platform_info->default_tx_ring_size;
	if (lp->tx_count < AMBETH_TX_RNG_MIN)
		lp->tx_count = AMBETH_TX_RNG_MIN;
	lp->tx_irq_count = (lp->tx_count * 2) / 3;
	lp->msg_enable = netif_msg_init(msg_level, NETIF_MSG_DRV);

	if (lp->platform_info->mii_power.gpio_id != -1) {
		errorCode = gpio_request(lp->platform_info->mii_power.gpio_id,
			pdev->name);
		if (errorCode) {
			dev_err(&pdev->dev, "gpio_request %d fail %d.\n",
				lp->platform_info->mii_power.gpio_id,
				errorCode);
			goto ambeth_drv_probe_free_netdev;
		}
	}

	if (lp->platform_info->mii_reset.gpio_id != -1) {
		errorCode = gpio_request(lp->platform_info->mii_reset.gpio_id,
			pdev->name);
		if (errorCode) {
			dev_err(&pdev->dev, "gpio_request %d fail %d.\n",
				lp->platform_info->mii_reset.gpio_id,
				errorCode);
			goto ambeth_drv_probe_free_mii_power;
		}
	}

	if (ambarella_is_valid_gpio_irq(&lp->platform_info->phy_irq)) {
		errorCode = gpio_request(lp->platform_info->phy_irq.irq_gpio,
			pdev->name);
		if (errorCode) {
			dev_err(&pdev->dev,
				"gpio_request %d for IRQ %d fail %d.\n",
				lp->platform_info->phy_irq.irq_gpio,
				lp->platform_info->phy_irq.irq_line,
				errorCode);
			goto ambeth_drv_probe_free_mii_reset;
		}
	}

	lp->new_bus.name = "Ambarella MII Bus",
	lp->new_bus.read = &ambhw_mdio_read,
	lp->new_bus.write = &ambhw_mdio_write,
	lp->new_bus.reset = &ambhw_mdio_reset,
	snprintf(lp->new_bus.id, MII_BUS_ID_SIZE, "%x", pdev->id);
	lp->new_bus.priv = lp;
	lp->new_bus.irq = kmalloc(sizeof(int)*PHY_MAX_ADDR, GFP_KERNEL);
	if (lp->new_bus.irq == NULL) {
		dev_err(&pdev->dev, "alloc new_bus.irq fail.\n");
		errorCode = -ENOMEM;
		goto ambeth_drv_probe_free_mii_gpio_irq;
	}
	for(i = 0; i < PHY_MAX_ADDR; ++i)
		lp->new_bus.irq[i] = PHY_POLL;
	lp->new_bus.parent = &pdev->dev;
	lp->new_bus.state = MDIOBUS_ALLOCATED;
	errorCode = mdiobus_register(&lp->new_bus);
	if (errorCode) {
		dev_err(&pdev->dev, "mdiobus_register fail%d.\n", errorCode);
		goto ambeth_drv_probe_kfree_mdiobus;
	}

	ether_setup(ndev);
	ndev->netdev_ops = &ambeth_netdev_ops;
	ndev->watchdog_timeo = lp->platform_info->watchdog_timeo;
	netif_napi_add(ndev, &lp->napi, ambeth_napi,
		lp->platform_info->napi_weight);
	if (!is_valid_ether_addr(lp->platform_info->mac_addr))
		random_ether_addr(lp->platform_info->mac_addr);
	memcpy(ndev->dev_addr, lp->platform_info->mac_addr, AMBETH_MAC_SIZE);

	SET_ETHTOOL_OPS(ndev, &ambeth_ethtool_ops);
	errorCode = register_netdev(ndev);
	if (errorCode) {
		dev_err(&pdev->dev, " register_netdev fail%d.\n", errorCode);
		goto ambeth_drv_probe_netif_napi_del;
	}

	platform_set_drvdata(pdev, ndev);
	dev_notice(&pdev->dev, "MAC Address[%pM].\n", ndev->dev_addr);
	goto ambeth_drv_probe_exit;

ambeth_drv_probe_netif_napi_del:
	netif_napi_del(&lp->napi);
	mdiobus_unregister(&lp->new_bus);

ambeth_drv_probe_kfree_mdiobus:
	kfree(lp->new_bus.irq);

ambeth_drv_probe_free_mii_gpio_irq:
	if (ambarella_is_valid_gpio_irq(&lp->platform_info->phy_irq))
		gpio_free(lp->platform_info->phy_irq.irq_gpio);

ambeth_drv_probe_free_mii_reset:
	if (lp->platform_info->mii_reset.gpio_id != -1)
		gpio_free(lp->platform_info->mii_reset.gpio_id);

ambeth_drv_probe_free_mii_power:
	if (lp->platform_info->mii_power.gpio_id != -1)
		gpio_free(lp->platform_info->mii_power.gpio_id);

ambeth_drv_probe_free_netdev:
	free_netdev(ndev);

ambeth_drv_probe_exit:
	return errorCode;
}

static int __devexit ambeth_drv_remove(struct platform_device *pdev)
{
	struct net_device			*ndev;
	struct ambeth_info			*lp;

	ndev = platform_get_drvdata(pdev);
	if (ndev) {
		lp = (struct ambeth_info *)netdev_priv(ndev);
		unregister_netdev(ndev);
		netif_napi_del(&lp->napi);
		if (lp->platform_info->mii_power.gpio_id != -1)
			gpio_free(lp->platform_info->mii_power.gpio_id);
		if (lp->platform_info->mii_reset.gpio_id != -1)
			gpio_free(lp->platform_info->mii_reset.gpio_id);
		if (ambarella_is_valid_gpio_irq(&lp->platform_info->phy_irq))
			gpio_free(lp->platform_info->phy_irq.irq_gpio);
		mdiobus_unregister(&lp->new_bus);
		kfree(lp->new_bus.irq);
		platform_set_drvdata(pdev, NULL);
		free_netdev(ndev);
		dev_notice(&pdev->dev, "Removed.\n");
	}

	return 0;
}

#ifdef CONFIG_PM
static int ambeth_drv_suspend(struct platform_device *pdev, pm_message_t state)
{
	int					errorCode = 0;
	struct net_device			*ndev;
	struct ambeth_info			*lp;
	unsigned long				flags;

	ndev = platform_get_drvdata(pdev);
	if (ndev) {
		if (!netif_running(ndev))
			goto ambeth_drv_suspend_exit;

		lp = (struct ambeth_info *)netdev_priv(ndev);

		napi_disable(&lp->napi);
		netif_device_detach(ndev);
		disable_irq(ndev->irq);

		spin_lock_irqsave(&lp->lock, flags);
		ambhw_disable(lp);
		spin_unlock_irqrestore(&lp->lock, flags);
	}

ambeth_drv_suspend_exit:
	dev_dbg(&pdev->dev, "%s exit with %d @ %d\n",
		__func__, errorCode, state.event);
	return errorCode;
}

static int ambeth_drv_resume(struct platform_device *pdev)
{
	int					errorCode = 0;
	struct net_device			*ndev;
	struct ambeth_info			*lp;
	unsigned long				flags;

	ndev = platform_get_drvdata(pdev);
	if (ndev) {
		if (!netif_running(ndev))
			goto ambeth_drv_resume_exit;

		lp = (struct ambeth_info *)netdev_priv(ndev);

		spin_lock_irqsave(&lp->lock, flags);
		errorCode = ambhw_enable(lp);
		ambhw_set_link_mode_speed(lp);
		ambeth_rx_rngmng_init(lp);
		ambeth_tx_rngmng_init(lp);
		ambhw_set_dma_desc(lp);
		ambhw_dma_rx_start(lp);
		ambhw_dma_tx_start(lp);
		ambhw_dma_int_enable(lp);
		spin_unlock_irqrestore(&lp->lock, flags);

		if (errorCode) {
			dev_err(&pdev->dev, "ambhw_enable.\n");
		} else {
			enable_irq(ndev->irq);
			netif_device_attach(ndev);
			napi_enable(&lp->napi);
		}
	}

ambeth_drv_resume_exit:
	dev_dbg(&pdev->dev, "%s exit with %d\n", __func__, errorCode);
	return errorCode;
}
#endif

static struct platform_driver ambeth_driver = {
	.probe		= ambeth_drv_probe,
	.remove		= __devexit_p(ambeth_drv_remove),
#ifdef CONFIG_PM
	.suspend        = ambeth_drv_suspend,
	.resume		= ambeth_drv_resume,
#endif
	.driver = {
		.name	= "ambarella-eth",
		.owner	= THIS_MODULE,
	},
};

static int __init ambeth_init(void)
{
	return platform_driver_register(&ambeth_driver);
}

static void __exit ambeth_exit(void)
{
	platform_driver_unregister(&ambeth_driver);
}

module_init(ambeth_init);
module_exit(ambeth_exit);

MODULE_DESCRIPTION("Ambarella Media Processor Ethernet Driver");
MODULE_AUTHOR("Anthony Ginger, <hfjiang@ambarella.com>");
MODULE_LICENSE("GPL");

