 /***************************************************************************
 *
 * Copyright (C) 2007,2008  SMSC
 *
 * 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/interrupt.h>
#include <linux/kernel.h>
#include <linux/netdevice.h>
#include <linux/phy.h>
#include <linux/pci.h>
#include <linux/if_vlan.h>
#include <linux/dma-mapping.h>
#include <linux/crc32.h>
#include <linux/slab.h>
#include <asm/unaligned.h>
#include "smsc9420.h"

#define DRV_NAME		"smsc9420"
#define PFX			DRV_NAME ": "
#define DRV_MDIONAME		"smsc9420-mdio"
#define DRV_DESCRIPTION		"SMSC LAN9420 driver"
#define DRV_VERSION		"1.01"

MODULE_LICENSE("GPL");
MODULE_VERSION(DRV_VERSION);

struct smsc9420_dma_desc {
	u32 status;
	u32 length;
	u32 buffer1;
	u32 buffer2;
};

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

struct smsc9420_pdata {
	void __iomem *base_addr;
	struct pci_dev *pdev;
	struct net_device *dev;

	struct smsc9420_dma_desc *rx_ring;
	struct smsc9420_dma_desc *tx_ring;
	struct smsc9420_ring_info *tx_buffers;
	struct smsc9420_ring_info *rx_buffers;
	dma_addr_t rx_dma_addr;
	dma_addr_t tx_dma_addr;
	int tx_ring_head, tx_ring_tail;
	int rx_ring_head, rx_ring_tail;

	spinlock_t int_lock;
	spinlock_t phy_lock;

	struct napi_struct napi;

	bool software_irq_signal;
	bool rx_csum;
	u32 msg_enable;

	struct phy_device *phy_dev;
	struct mii_bus *mii_bus;
	int phy_irq[PHY_MAX_ADDR];
	int last_duplex;
	int last_carrier;
};

static DEFINE_PCI_DEVICE_TABLE(smsc9420_id_table) = {
	{ PCI_VENDOR_ID_9420, PCI_DEVICE_ID_9420, PCI_ANY_ID, PCI_ANY_ID, },
	{ 0, }
};

MODULE_DEVICE_TABLE(pci, smsc9420_id_table);

#define SMSC_MSG_DEFAULT (NETIF_MSG_DRV | NETIF_MSG_PROBE | NETIF_MSG_LINK)

static uint smsc_debug;
static uint debug = -1;
module_param(debug, uint, 0);
MODULE_PARM_DESC(debug, "debug level");

#define smsc_dbg(TYPE, f, a...) \
do {	if ((pd)->msg_enable & NETIF_MSG_##TYPE) \
		printk(KERN_DEBUG PFX f "\n", ## a); \
} while (0)

#define smsc_info(TYPE, f, a...) \
do {	if ((pd)->msg_enable & NETIF_MSG_##TYPE) \
		printk(KERN_INFO PFX f "\n", ## a); \
} while (0)

#define smsc_warn(TYPE, f, a...) \
do {	if ((pd)->msg_enable & NETIF_MSG_##TYPE) \
		printk(KERN_WARNING PFX f "\n", ## a); \
} while (0)

static inline u32 smsc9420_reg_read(struct smsc9420_pdata *pd, u32 offset)
{
	return ioread32(pd->base_addr + offset);
}

static inline void
smsc9420_reg_write(struct smsc9420_pdata *pd, u32 offset, u32 value)
{
	iowrite32(value, pd->base_addr + offset);
}

static inline void smsc9420_pci_flush_write(struct smsc9420_pdata *pd)
{
	/* to ensure PCI write completion, we must perform a PCI read */
	smsc9420_reg_read(pd, ID_REV);
}

static int smsc9420_mii_read(struct mii_bus *bus, int phyaddr, int regidx)
{
	struct smsc9420_pdata *pd = (struct smsc9420_pdata *)bus->priv;
	unsigned long flags;
	u32 addr;
	int i, reg = -EIO;

	spin_lock_irqsave(&pd->phy_lock, flags);

	/*  confirm MII not busy */
	if ((smsc9420_reg_read(pd, MII_ACCESS) & MII_ACCESS_MII_BUSY_)) {
		smsc_warn(DRV, "MII is busy???");
		goto out;
	}

	/* set the address, index & direction (read from PHY) */
	addr = ((phyaddr & 0x1F) << 11) | ((regidx & 0x1F) << 6) |
		MII_ACCESS_MII_READ_;
	smsc9420_reg_write(pd, MII_ACCESS, addr);

	/* wait for read to complete with 50us timeout */
	for (i = 0; i < 5; i++) {
		if (!(smsc9420_reg_read(pd, MII_ACCESS) &
			MII_ACCESS_MII_BUSY_)) {
			reg = (u16)smsc9420_reg_read(pd, MII_DATA);
			goto out;
		}
		udelay(10);
	}

	smsc_warn(DRV, "MII busy timeout!");

out:
	spin_unlock_irqrestore(&pd->phy_lock, flags);
	return reg;
}

static int smsc9420_mii_write(struct mii_bus *bus, int phyaddr, int regidx,
			   u16 val)
{
	struct smsc9420_pdata *pd = (struct smsc9420_pdata *)bus->priv;
	unsigned long flags;
	u32 addr;
	int i, reg = -EIO;

	spin_lock_irqsave(&pd->phy_lock, flags);

	/* confirm MII not busy */
	if ((smsc9420_reg_read(pd, MII_ACCESS) & MII_ACCESS_MII_BUSY_)) {
		smsc_warn(DRV, "MII is busy???");
		goto out;
	}

	/* put the data to write in the MAC */
	smsc9420_reg_write(pd, MII_DATA, (u32)val);

	/* set the address, index & direction (write to PHY) */
	addr = ((phyaddr & 0x1F) << 11) | ((regidx & 0x1F) << 6) |
		MII_ACCESS_MII_WRITE_;
	smsc9420_reg_write(pd, MII_ACCESS, addr);

	/* wait for write to complete with 50us timeout */
	for (i = 0; i < 5; i++) {
		if (!(smsc9420_reg_read(pd, MII_ACCESS) &
			MII_ACCESS_MII_BUSY_)) {
			reg = 0;
			goto out;
		}
		udelay(10);
	}

	smsc_warn(DRV, "MII busy timeout!");

out:
	spin_unlock_irqrestore(&pd->phy_lock, flags);
	return reg;
}

/* Returns hash bit number for given MAC address
 * Example:
 * 01 00 5E 00 00 01 -> returns bit number 31 */
static u32 smsc9420_hash(u8 addr[ETH_ALEN])
{
	return (ether_crc(ETH_ALEN, addr) >> 26) & 0x3f;
}

static int smsc9420_eeprom_reload(struct smsc9420_pdata *pd)
{
	int timeout = 100000;

	BUG_ON(!pd);

	if (smsc9420_reg_read(pd, E2P_CMD) & E2P_CMD_EPC_BUSY_) {
		smsc_dbg(DRV, "smsc9420_eeprom_reload: Eeprom busy");
		return -EIO;
	}

	smsc9420_reg_write(pd, E2P_CMD,
		(E2P_CMD_EPC_BUSY_ | E2P_CMD_EPC_CMD_RELOAD_));

	do {
		udelay(10);
		if (!(smsc9420_reg_read(pd, E2P_CMD) & E2P_CMD_EPC_BUSY_))
			return 0;
	} while (timeout--);

	smsc_warn(DRV, "smsc9420_eeprom_reload: Eeprom timed out");
	return -EIO;
}

/* Standard ioctls for mii-tool */
static int smsc9420_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
{
	struct smsc9420_pdata *pd = netdev_priv(dev);

	if (!netif_running(dev) || !pd->phy_dev)
		return -EINVAL;

	return phy_mii_ioctl(pd->phy_dev, ifr, cmd);
}

static int smsc9420_ethtool_get_settings(struct net_device *dev,
					 struct ethtool_cmd *cmd)
{
	struct smsc9420_pdata *pd = netdev_priv(dev);

	if (!pd->phy_dev)
		return -ENODEV;

	cmd->maxtxpkt = 1;
	cmd->maxrxpkt = 1;
	return phy_ethtool_gset(pd->phy_dev, cmd);
}

static int smsc9420_ethtool_set_settings(struct net_device *dev,
					 struct ethtool_cmd *cmd)
{
	struct smsc9420_pdata *pd = netdev_priv(dev);

	if (!pd->phy_dev)
		return -ENODEV;

	return phy_ethtool_sset(pd->phy_dev, cmd);
}

static void smsc9420_ethtool_get_drvinfo(struct net_device *netdev,
					 struct ethtool_drvinfo *drvinfo)
{
	struct smsc9420_pdata *pd = netdev_priv(netdev);

	strcpy(drvinfo->driver, DRV_NAME);
	strcpy(drvinfo->bus_info, pci_name(pd->pdev));
	strcpy(drvinfo->version, DRV_VERSION);
}

static u32 smsc9420_ethtool_get_msglevel(struct net_device *netdev)
{
	struct smsc9420_pdata *pd = netdev_priv(netdev);
	return pd->msg_enable;
}

static void smsc9420_ethtool_set_msglevel(struct net_device *netdev, u32 data)
{
	struct smsc9420_pdata *pd = netdev_priv(netdev);
	pd->msg_enable = data;
}

static int smsc9420_ethtool_nway_reset(struct net_device *netdev)
{
	struct smsc9420_pdata *pd = netdev_priv(netdev);

	if (!pd->phy_dev)
		return -ENODEV;

	return phy_start_aneg(pd->phy_dev);
}

static int smsc9420_ethtool_getregslen(struct net_device *dev)
{
	/* all smsc9420 registers plus all phy registers */
	return 0x100 + (32 * sizeof(u32));
}

static void
smsc9420_ethtool_getregs(struct net_device *dev, struct ethtool_regs *regs,
			 void *buf)
{
	struct smsc9420_pdata *pd = netdev_priv(dev);
	struct phy_device *phy_dev = pd->phy_dev;
	unsigned int i, j = 0;
	u32 *data = buf;

	regs->version = smsc9420_reg_read(pd, ID_REV);
	for (i = 0; i < 0x100; i += (sizeof(u32)))
		data[j++] = smsc9420_reg_read(pd, i);

	// cannot read phy registers if the net device is down
	if (!phy_dev)
		return;

	for (i = 0; i <= 31; i++)
		data[j++] = smsc9420_mii_read(phy_dev->bus, phy_dev->addr, i);
}

static void smsc9420_eeprom_enable_access(struct smsc9420_pdata *pd)
{
	unsigned int temp = smsc9420_reg_read(pd, GPIO_CFG);
	temp &= ~GPIO_CFG_EEPR_EN_;
	smsc9420_reg_write(pd, GPIO_CFG, temp);
	msleep(1);
}

static int smsc9420_eeprom_send_cmd(struct smsc9420_pdata *pd, u32 op)
{
	int timeout = 100;
	u32 e2cmd;

	smsc_dbg(HW, "op 0x%08x", op);
	if (smsc9420_reg_read(pd, E2P_CMD) & E2P_CMD_EPC_BUSY_) {
		smsc_warn(HW, "Busy at start");
		return -EBUSY;
	}

	e2cmd = op | E2P_CMD_EPC_BUSY_;
	smsc9420_reg_write(pd, E2P_CMD, e2cmd);

	do {
		msleep(1);
		e2cmd = smsc9420_reg_read(pd, E2P_CMD);
	} while ((e2cmd & E2P_CMD_EPC_BUSY_) && (--timeout));

	if (!timeout) {
		smsc_info(HW, "TIMED OUT");
		return -EAGAIN;
	}

	if (e2cmd & E2P_CMD_EPC_TIMEOUT_) {
		smsc_info(HW, "Error occurred during eeprom operation");
		return -EINVAL;
	}

	return 0;
}

static int smsc9420_eeprom_read_location(struct smsc9420_pdata *pd,
					 u8 address, u8 *data)
{
	u32 op = E2P_CMD_EPC_CMD_READ_ | address;
	int ret;

	smsc_dbg(HW, "address 0x%x", address);
	ret = smsc9420_eeprom_send_cmd(pd, op);

	if (!ret)
		data[address] = smsc9420_reg_read(pd, E2P_DATA);

	return ret;
}

static int smsc9420_eeprom_write_location(struct smsc9420_pdata *pd,
					  u8 address, u8 data)
{
	u32 op = E2P_CMD_EPC_CMD_ERASE_ | address;
	int ret;

	smsc_dbg(HW, "address 0x%x, data 0x%x", address, data);
	ret = smsc9420_eeprom_send_cmd(pd, op);

	if (!ret) {
		op = E2P_CMD_EPC_CMD_WRITE_ | address;
		smsc9420_reg_write(pd, E2P_DATA, (u32)data);
		ret = smsc9420_eeprom_send_cmd(pd, op);
	}

	return ret;
}

static int smsc9420_ethtool_get_eeprom_len(struct net_device *dev)
{
	return SMSC9420_EEPROM_SIZE;
}

static int smsc9420_ethtool_get_eeprom(struct net_device *dev,
				       struct ethtool_eeprom *eeprom, u8 *data)
{
	struct smsc9420_pdata *pd = netdev_priv(dev);
	u8 eeprom_data[SMSC9420_EEPROM_SIZE];
	int len, i;

	smsc9420_eeprom_enable_access(pd);

	len = min(eeprom->len, SMSC9420_EEPROM_SIZE);
	for (i = 0; i < len; i++) {
		int ret = smsc9420_eeprom_read_location(pd, i, eeprom_data);
		if (ret < 0) {
			eeprom->len = 0;
			return ret;
		}
	}

	memcpy(data, &eeprom_data[eeprom->offset], len);
	eeprom->magic = SMSC9420_EEPROM_MAGIC;
	eeprom->len = len;
	return 0;
}

static int smsc9420_ethtool_set_eeprom(struct net_device *dev,
				       struct ethtool_eeprom *eeprom, u8 *data)
{
	struct smsc9420_pdata *pd = netdev_priv(dev);
	int ret;

	if (eeprom->magic != SMSC9420_EEPROM_MAGIC)
		return -EINVAL;

	smsc9420_eeprom_enable_access(pd);
	smsc9420_eeprom_send_cmd(pd, E2P_CMD_EPC_CMD_EWEN_);
	ret = smsc9420_eeprom_write_location(pd, eeprom->offset, *data);
	smsc9420_eeprom_send_cmd(pd, E2P_CMD_EPC_CMD_EWDS_);

	/* Single byte write, according to man page */
	eeprom->len = 1;

	return ret;
}

static const struct ethtool_ops smsc9420_ethtool_ops = {
	.get_settings = smsc9420_ethtool_get_settings,
	.set_settings = smsc9420_ethtool_set_settings,
	.get_drvinfo = smsc9420_ethtool_get_drvinfo,
	.get_msglevel = smsc9420_ethtool_get_msglevel,
	.set_msglevel = smsc9420_ethtool_set_msglevel,
	.nway_reset = smsc9420_ethtool_nway_reset,
	.get_link = ethtool_op_get_link,
	.get_eeprom_len = smsc9420_ethtool_get_eeprom_len,
	.get_eeprom = smsc9420_ethtool_get_eeprom,
	.set_eeprom = smsc9420_ethtool_set_eeprom,
	.get_regs_len = smsc9420_ethtool_getregslen,
	.get_regs = smsc9420_ethtool_getregs,
};

/* Sets the device MAC address to dev_addr */
static void smsc9420_set_mac_address(struct net_device *dev)
{
	struct smsc9420_pdata *pd = netdev_priv(dev);
	u8 *dev_addr = dev->dev_addr;
	u32 mac_high16 = (dev_addr[5] << 8) | dev_addr[4];
	u32 mac_low32 = (dev_addr[3] << 24) | (dev_addr[2] << 16) |
	    (dev_addr[1] << 8) | dev_addr[0];

	smsc9420_reg_write(pd, ADDRH, mac_high16);
	smsc9420_reg_write(pd, ADDRL, mac_low32);
}

static void smsc9420_check_mac_address(struct net_device *dev)
{
	struct smsc9420_pdata *pd = netdev_priv(dev);

	/* Check if mac address has been specified when bringing interface up */
	if (is_valid_ether_addr(dev->dev_addr)) {
		smsc9420_set_mac_address(dev);
		smsc_dbg(PROBE, "MAC Address is specified by configuration");
	} else {
		/* Try reading mac address from device. if EEPROM is present
		 * it will already have been set */
		u32 mac_high16 = smsc9420_reg_read(pd, ADDRH);
		u32 mac_low32 = smsc9420_reg_read(pd, ADDRL);
		dev->dev_addr[0] = (u8)(mac_low32);
		dev->dev_addr[1] = (u8)(mac_low32 >> 8);
		dev->dev_addr[2] = (u8)(mac_low32 >> 16);
		dev->dev_addr[3] = (u8)(mac_low32 >> 24);
		dev->dev_addr[4] = (u8)(mac_high16);
		dev->dev_addr[5] = (u8)(mac_high16 >> 8);

		if (is_valid_ether_addr(dev->dev_addr)) {
			/* eeprom values are valid  so use them */
			smsc_dbg(PROBE, "Mac Address is read from EEPROM");
		} else {
			/* eeprom values are invalid, generate random MAC */
			random_ether_addr(dev->dev_addr);
			smsc9420_set_mac_address(dev);
			smsc_dbg(PROBE,
				"MAC Address is set to random_ether_addr");
		}
	}
}

static void smsc9420_stop_tx(struct smsc9420_pdata *pd)
{
	u32 dmac_control, mac_cr, dma_intr_ena;
	int timeout = 1000;

	/* disable TX DMAC */
	dmac_control = smsc9420_reg_read(pd, DMAC_CONTROL);
	dmac_control &= (~DMAC_CONTROL_ST_);
	smsc9420_reg_write(pd, DMAC_CONTROL, dmac_control);

	/* Wait max 10ms for transmit process to stop */
	while (--timeout) {
		if (smsc9420_reg_read(pd, DMAC_STATUS) & DMAC_STS_TS_)
			break;
		udelay(10);
	}

	if (!timeout)
		smsc_warn(IFDOWN, "TX DMAC failed to stop");

	/* ACK Tx DMAC stop bit */
	smsc9420_reg_write(pd, DMAC_STATUS, DMAC_STS_TXPS_);

	/* mask TX DMAC interrupts */
	dma_intr_ena = smsc9420_reg_read(pd, DMAC_INTR_ENA);
	dma_intr_ena &= ~(DMAC_INTR_ENA_TX_);
	smsc9420_reg_write(pd, DMAC_INTR_ENA, dma_intr_ena);
	smsc9420_pci_flush_write(pd);

	/* stop MAC TX */
	mac_cr = smsc9420_reg_read(pd, MAC_CR) & (~MAC_CR_TXEN_);
	smsc9420_reg_write(pd, MAC_CR, mac_cr);
	smsc9420_pci_flush_write(pd);
}

static void smsc9420_free_tx_ring(struct smsc9420_pdata *pd)
{
	int i;

	BUG_ON(!pd->tx_ring);

	if (!pd->tx_buffers)
		return;

	for (i = 0; i < TX_RING_SIZE; i++) {
		struct sk_buff *skb = pd->tx_buffers[i].skb;

		if (skb) {
			BUG_ON(!pd->tx_buffers[i].mapping);
			pci_unmap_single(pd->pdev, pd->tx_buffers[i].mapping,
					 skb->len, PCI_DMA_TODEVICE);
			dev_kfree_skb_any(skb);
		}

		pd->tx_ring[i].status = 0;
		pd->tx_ring[i].length = 0;
		pd->tx_ring[i].buffer1 = 0;
		pd->tx_ring[i].buffer2 = 0;
	}
	wmb();

	kfree(pd->tx_buffers);
	pd->tx_buffers = NULL;

	pd->tx_ring_head = 0;
	pd->tx_ring_tail = 0;
}

static void smsc9420_free_rx_ring(struct smsc9420_pdata *pd)
{
	int i;

	BUG_ON(!pd->rx_ring);

	if (!pd->rx_buffers)
		return;

	for (i = 0; i < RX_RING_SIZE; i++) {
		if (pd->rx_buffers[i].skb)
			dev_kfree_skb_any(pd->rx_buffers[i].skb);

		if (pd->rx_buffers[i].mapping)
			pci_unmap_single(pd->pdev, pd->rx_buffers[i].mapping,
				PKT_BUF_SZ, PCI_DMA_FROMDEVICE);

		pd->rx_ring[i].status = 0;
		pd->rx_ring[i].length = 0;
		pd->rx_ring[i].buffer1 = 0;
		pd->rx_ring[i].buffer2 = 0;
	}
	wmb();

	kfree(pd->rx_buffers);
	pd->rx_buffers = NULL;

	pd->rx_ring_head = 0;
	pd->rx_ring_tail = 0;
}

static void smsc9420_stop_rx(struct smsc9420_pdata *pd)
{
	int timeout = 1000;
	u32 mac_cr, dmac_control, dma_intr_ena;

	/* mask RX DMAC interrupts */
	dma_intr_ena = smsc9420_reg_read(pd, DMAC_INTR_ENA);
	dma_intr_ena &= (~DMAC_INTR_ENA_RX_);
	smsc9420_reg_write(pd, DMAC_INTR_ENA, dma_intr_ena);
	smsc9420_pci_flush_write(pd);

	/* stop RX MAC prior to stoping DMA */
	mac_cr = smsc9420_reg_read(pd, MAC_CR) & (~MAC_CR_RXEN_);
	smsc9420_reg_write(pd, MAC_CR, mac_cr);
	smsc9420_pci_flush_write(pd);

	/* stop RX DMAC */
	dmac_control = smsc9420_reg_read(pd, DMAC_CONTROL);
	dmac_control &= (~DMAC_CONTROL_SR_);
	smsc9420_reg_write(pd, DMAC_CONTROL, dmac_control);
	smsc9420_pci_flush_write(pd);

	/* wait up to 10ms for receive to stop */
	while (--timeout) {
		if (smsc9420_reg_read(pd, DMAC_STATUS) & DMAC_STS_RS_)
			break;
		udelay(10);
	}

	if (!timeout)
		smsc_warn(IFDOWN, "RX DMAC did not stop! timeout.");

	/* ACK the Rx DMAC stop bit */
	smsc9420_reg_write(pd, DMAC_STATUS, DMAC_STS_RXPS_);
}

static irqreturn_t smsc9420_isr(int irq, void *dev_id)
{
	struct smsc9420_pdata *pd = dev_id;
	u32 int_cfg, int_sts, int_ctl;
	irqreturn_t ret = IRQ_NONE;
	ulong flags;

	BUG_ON(!pd);
	BUG_ON(!pd->base_addr);

	int_cfg = smsc9420_reg_read(pd, INT_CFG);

	/* check if it's our interrupt */
	if ((int_cfg & (INT_CFG_IRQ_EN_ | INT_CFG_IRQ_INT_)) !=
	    (INT_CFG_IRQ_EN_ | INT_CFG_IRQ_INT_))
		return IRQ_NONE;

	int_sts = smsc9420_reg_read(pd, INT_STAT);

	if (likely(INT_STAT_DMAC_INT_ & int_sts)) {
		u32 status = smsc9420_reg_read(pd, DMAC_STATUS);
		u32 ints_to_clear = 0;

		if (status & DMAC_STS_TX_) {
			ints_to_clear |= (DMAC_STS_TX_ | DMAC_STS_NIS_);
			netif_wake_queue(pd->dev);
		}

		if (status & DMAC_STS_RX_) {
			/* mask RX DMAC interrupts */
			u32 dma_intr_ena = smsc9420_reg_read(pd, DMAC_INTR_ENA);
			dma_intr_ena &= (~DMAC_INTR_ENA_RX_);
			smsc9420_reg_write(pd, DMAC_INTR_ENA, dma_intr_ena);
			smsc9420_pci_flush_write(pd);

			ints_to_clear |= (DMAC_STS_RX_ | DMAC_STS_NIS_);
			napi_schedule(&pd->napi);
		}

		if (ints_to_clear)
			smsc9420_reg_write(pd, DMAC_STATUS, ints_to_clear);

		ret = IRQ_HANDLED;
	}

	if (unlikely(INT_STAT_SW_INT_ & int_sts)) {
		/* mask software interrupt */
		spin_lock_irqsave(&pd->int_lock, flags);
		int_ctl = smsc9420_reg_read(pd, INT_CTL);
		int_ctl &= (~INT_CTL_SW_INT_EN_);
		smsc9420_reg_write(pd, INT_CTL, int_ctl);
		spin_unlock_irqrestore(&pd->int_lock, flags);

		smsc9420_reg_write(pd, INT_STAT, INT_STAT_SW_INT_);
		pd->software_irq_signal = true;
		smp_wmb();

		ret = IRQ_HANDLED;
	}

	/* to ensure PCI write completion, we must perform a PCI read */
	smsc9420_pci_flush_write(pd);

	return ret;
}

#ifdef CONFIG_NET_POLL_CONTROLLER
static void smsc9420_poll_controller(struct net_device *dev)
{
	disable_irq(dev->irq);
	smsc9420_isr(0, dev);
	enable_irq(dev->irq);
}
#endif /* CONFIG_NET_POLL_CONTROLLER */

static void smsc9420_dmac_soft_reset(struct smsc9420_pdata *pd)
{
	smsc9420_reg_write(pd, BUS_MODE, BUS_MODE_SWR_);
	smsc9420_reg_read(pd, BUS_MODE);
	udelay(2);
	if (smsc9420_reg_read(pd, BUS_MODE) & BUS_MODE_SWR_)
		smsc_warn(DRV, "Software reset not cleared");
}

static int smsc9420_stop(struct net_device *dev)
{
	struct smsc9420_pdata *pd = netdev_priv(dev);
	u32 int_cfg;
	ulong flags;

	BUG_ON(!pd);
	BUG_ON(!pd->phy_dev);

	/* disable master interrupt */
	spin_lock_irqsave(&pd->int_lock, flags);
	int_cfg = smsc9420_reg_read(pd, INT_CFG) & (~INT_CFG_IRQ_EN_);
	smsc9420_reg_write(pd, INT_CFG, int_cfg);
	spin_unlock_irqrestore(&pd->int_lock, flags);

	netif_tx_disable(dev);
	napi_disable(&pd->napi);

	smsc9420_stop_tx(pd);
	smsc9420_free_tx_ring(pd);

	smsc9420_stop_rx(pd);
	smsc9420_free_rx_ring(pd);

	free_irq(dev->irq, pd);

	smsc9420_dmac_soft_reset(pd);

	phy_stop(pd->phy_dev);

	phy_disconnect(pd->phy_dev);
	pd->phy_dev = NULL;
	mdiobus_unregister(pd->mii_bus);
	mdiobus_free(pd->mii_bus);

	return 0;
}

static void smsc9420_rx_count_stats(struct net_device *dev, u32 desc_status)
{
	if (unlikely(desc_status & RDES0_ERROR_SUMMARY_)) {
		dev->stats.rx_errors++;
		if (desc_status & RDES0_DESCRIPTOR_ERROR_)
			dev->stats.rx_over_errors++;
		else if (desc_status & (RDES0_FRAME_TOO_LONG_ |
			RDES0_RUNT_FRAME_ | RDES0_COLLISION_SEEN_))
			dev->stats.rx_frame_errors++;
		else if (desc_status & RDES0_CRC_ERROR_)
			dev->stats.rx_crc_errors++;
	}

	if (unlikely(desc_status & RDES0_LENGTH_ERROR_))
		dev->stats.rx_length_errors++;

	if (unlikely(!((desc_status & RDES0_LAST_DESCRIPTOR_) &&
		(desc_status & RDES0_FIRST_DESCRIPTOR_))))
		dev->stats.rx_length_errors++;

	if (desc_status & RDES0_MULTICAST_FRAME_)
		dev->stats.multicast++;
}

static void smsc9420_rx_handoff(struct smsc9420_pdata *pd, const int index,
				const u32 status)
{
	struct net_device *dev = pd->dev;
	struct sk_buff *skb;
	u16 packet_length = (status & RDES0_FRAME_LENGTH_MASK_)
		>> RDES0_FRAME_LENGTH_SHFT_;

	/* remove crc from packet lendth */
	packet_length -= 4;

	if (pd->rx_csum)
		packet_length -= 2;

	dev->stats.rx_packets++;
	dev->stats.rx_bytes += packet_length;

	pci_unmap_single(pd->pdev, pd->rx_buffers[index].mapping,
		PKT_BUF_SZ, PCI_DMA_FROMDEVICE);
	pd->rx_buffers[index].mapping = 0;

	skb = pd->rx_buffers[index].skb;
	pd->rx_buffers[index].skb = NULL;

	if (pd->rx_csum) {
		u16 hw_csum = get_unaligned_le16(skb_tail_pointer(skb) +
			NET_IP_ALIGN + packet_length + 4);
		put_unaligned_le16(hw_csum, &skb->csum);
		skb->ip_summed = CHECKSUM_COMPLETE;
	}

	skb_reserve(skb, NET_IP_ALIGN);
	skb_put(skb, packet_length);

	skb->protocol = eth_type_trans(skb, dev);

	netif_receive_skb(skb);
}

static int smsc9420_alloc_rx_buffer(struct smsc9420_pdata *pd, int index)
{
	struct sk_buff *skb = netdev_alloc_skb(pd->dev, PKT_BUF_SZ);
	dma_addr_t mapping;

	BUG_ON(pd->rx_buffers[index].skb);
	BUG_ON(pd->rx_buffers[index].mapping);

	if (unlikely(!skb)) {
		smsc_warn(RX_ERR, "Failed to allocate new skb!");
		return -ENOMEM;
	}

	skb->dev = pd->dev;

	mapping = pci_map_single(pd->pdev, skb_tail_pointer(skb),
				 PKT_BUF_SZ, PCI_DMA_FROMDEVICE);
	if (pci_dma_mapping_error(pd->pdev, mapping)) {
		dev_kfree_skb_any(skb);
		smsc_warn(RX_ERR, "pci_map_single failed!");
		return -ENOMEM;
	}

	pd->rx_buffers[index].skb = skb;
	pd->rx_buffers[index].mapping = mapping;
	pd->rx_ring[index].buffer1 = mapping + NET_IP_ALIGN;
	pd->rx_ring[index].status = RDES0_OWN_;
	wmb();

	return 0;
}

static void smsc9420_alloc_new_rx_buffers(struct smsc9420_pdata *pd)
{
	while (pd->rx_ring_tail != pd->rx_ring_head) {
		if (smsc9420_alloc_rx_buffer(pd, pd->rx_ring_tail))
			break;

		pd->rx_ring_tail = (pd->rx_ring_tail + 1) % RX_RING_SIZE;
	}
}

static int smsc9420_rx_poll(struct napi_struct *napi, int budget)
{
	struct smsc9420_pdata *pd =
		container_of(napi, struct smsc9420_pdata, napi);
	struct net_device *dev = pd->dev;
	u32 drop_frame_cnt, dma_intr_ena, status;
	int work_done;

	for (work_done = 0; work_done < budget; work_done++) {
		rmb();
		status = pd->rx_ring[pd->rx_ring_head].status;

		/* stop if DMAC owns this dma descriptor */
		if (status & RDES0_OWN_)
			break;

		smsc9420_rx_count_stats(dev, status);
		smsc9420_rx_handoff(pd, pd->rx_ring_head, status);
		pd->rx_ring_head = (pd->rx_ring_head + 1) % RX_RING_SIZE;
		smsc9420_alloc_new_rx_buffers(pd);
	}

	drop_frame_cnt = smsc9420_reg_read(pd, MISS_FRAME_CNTR);
	dev->stats.rx_dropped +=
	    (drop_frame_cnt & 0xFFFF) + ((drop_frame_cnt >> 17) & 0x3FF);

	/* Kick RXDMA */
	smsc9420_reg_write(pd, RX_POLL_DEMAND, 1);
	smsc9420_pci_flush_write(pd);

	if (work_done < budget) {
		napi_complete(&pd->napi);

		/* re-enable RX DMA interrupts */
		dma_intr_ena = smsc9420_reg_read(pd, DMAC_INTR_ENA);
		dma_intr_ena |= (DMAC_INTR_ENA_RX_ | DMAC_INTR_ENA_NIS_);
		smsc9420_reg_write(pd, DMAC_INTR_ENA, dma_intr_ena);
		smsc9420_pci_flush_write(pd);
	}
	return work_done;
}

static void
smsc9420_tx_update_stats(struct net_device *dev, u32 status, u32 length)
{
	if (unlikely(status & TDES0_ERROR_SUMMARY_)) {
		dev->stats.tx_errors++;
		if (status & (TDES0_EXCESSIVE_DEFERRAL_ |
			TDES0_EXCESSIVE_COLLISIONS_))
			dev->stats.tx_aborted_errors++;

		if (status & (TDES0_LOSS_OF_CARRIER_ | TDES0_NO_CARRIER_))
			dev->stats.tx_carrier_errors++;
	} else {
		dev->stats.tx_packets++;
		dev->stats.tx_bytes += (length & 0x7FF);
	}

	if (unlikely(status & TDES0_EXCESSIVE_COLLISIONS_)) {
		dev->stats.collisions += 16;
	} else {
		dev->stats.collisions +=
			(status & TDES0_COLLISION_COUNT_MASK_) >>
			TDES0_COLLISION_COUNT_SHFT_;
	}

	if (unlikely(status & TDES0_HEARTBEAT_FAIL_))
		dev->stats.tx_heartbeat_errors++;
}

/* Check for completed dma transfers, update stats and free skbs */
static void smsc9420_complete_tx(struct net_device *dev)
{
	struct smsc9420_pdata *pd = netdev_priv(dev);

	while (pd->tx_ring_tail != pd->tx_ring_head) {
		int index = pd->tx_ring_tail;
		u32 status, length;

		rmb();
		status = pd->tx_ring[index].status;
		length = pd->tx_ring[index].length;

		/* Check if DMA still owns this descriptor */
		if (unlikely(TDES0_OWN_ & status))
			break;

		smsc9420_tx_update_stats(dev, status, length);

		BUG_ON(!pd->tx_buffers[index].skb);
		BUG_ON(!pd->tx_buffers[index].mapping);

		pci_unmap_single(pd->pdev, pd->tx_buffers[index].mapping,
			pd->tx_buffers[index].skb->len, PCI_DMA_TODEVICE);
		pd->tx_buffers[index].mapping = 0;

		dev_kfree_skb_any(pd->tx_buffers[index].skb);
		pd->tx_buffers[index].skb = NULL;

		pd->tx_ring[index].buffer1 = 0;
		wmb();

		pd->tx_ring_tail = (pd->tx_ring_tail + 1) % TX_RING_SIZE;
	}
}

static netdev_tx_t smsc9420_hard_start_xmit(struct sk_buff *skb,
					    struct net_device *dev)
{
	struct smsc9420_pdata *pd = netdev_priv(dev);
	dma_addr_t mapping;
	int index = pd->tx_ring_head;
	u32 tmp_desc1;
	bool about_to_take_last_desc =
		(((pd->tx_ring_head + 2) % TX_RING_SIZE) == pd->tx_ring_tail);

	smsc9420_complete_tx(dev);

	rmb();
	BUG_ON(pd->tx_ring[index].status & TDES0_OWN_);
	BUG_ON(pd->tx_buffers[index].skb);
	BUG_ON(pd->tx_buffers[index].mapping);

	mapping = pci_map_single(pd->pdev, skb->data,
				 skb->len, PCI_DMA_TODEVICE);
	if (pci_dma_mapping_error(pd->pdev, mapping)) {
		smsc_warn(TX_ERR, "pci_map_single failed, dropping packet");
		return NETDEV_TX_BUSY;
	}

	pd->tx_buffers[index].skb = skb;
	pd->tx_buffers[index].mapping = mapping;

	tmp_desc1 = (TDES1_LS_ | ((u32)skb->len & 0x7FF));
	if (unlikely(about_to_take_last_desc)) {
		tmp_desc1 |= TDES1_IC_;
		netif_stop_queue(pd->dev);
	}

	/* check if we are at the last descriptor and need to set EOR */
	if (unlikely(index == (TX_RING_SIZE - 1)))
		tmp_desc1 |= TDES1_TER_;

	pd->tx_ring[index].buffer1 = mapping;
	pd->tx_ring[index].length = tmp_desc1;
	wmb();

	/* increment head */
	pd->tx_ring_head = (pd->tx_ring_head + 1) % TX_RING_SIZE;

	/* assign ownership to DMAC */
	pd->tx_ring[index].status = TDES0_OWN_;
	wmb();

	skb_tx_timestamp(skb);

	/* kick the DMA */
	smsc9420_reg_write(pd, TX_POLL_DEMAND, 1);
	smsc9420_pci_flush_write(pd);

	return NETDEV_TX_OK;
}

static struct net_device_stats *smsc9420_get_stats(struct net_device *dev)
{
	struct smsc9420_pdata *pd = netdev_priv(dev);
	u32 counter = smsc9420_reg_read(pd, MISS_FRAME_CNTR);
	dev->stats.rx_dropped +=
	    (counter & 0x0000FFFF) + ((counter >> 17) & 0x000003FF);
	return &dev->stats;
}

static void smsc9420_set_multicast_list(struct net_device *dev)
{
	struct smsc9420_pdata *pd = netdev_priv(dev);
	u32 mac_cr = smsc9420_reg_read(pd, MAC_CR);

	if (dev->flags & IFF_PROMISC) {
		smsc_dbg(HW, "Promiscuous Mode Enabled");
		mac_cr |= MAC_CR_PRMS_;
		mac_cr &= (~MAC_CR_MCPAS_);
		mac_cr &= (~MAC_CR_HPFILT_);
	} else if (dev->flags & IFF_ALLMULTI) {
		smsc_dbg(HW, "Receive all Multicast Enabled");
		mac_cr &= (~MAC_CR_PRMS_);
		mac_cr |= MAC_CR_MCPAS_;
		mac_cr &= (~MAC_CR_HPFILT_);
	} else if (!netdev_mc_empty(dev)) {
		struct netdev_hw_addr *ha;
		u32 hash_lo = 0, hash_hi = 0;

		smsc_dbg(HW, "Multicast filter enabled");
		netdev_for_each_mc_addr(ha, dev) {
			u32 bit_num = smsc9420_hash(ha->addr);
			u32 mask = 1 << (bit_num & 0x1F);

			if (bit_num & 0x20)
				hash_hi |= mask;
			else
				hash_lo |= mask;

		}
		smsc9420_reg_write(pd, HASHH, hash_hi);
		smsc9420_reg_write(pd, HASHL, hash_lo);

		mac_cr &= (~MAC_CR_PRMS_);
		mac_cr &= (~MAC_CR_MCPAS_);
		mac_cr |= MAC_CR_HPFILT_;
	} else {
		smsc_dbg(HW, "Receive own packets only.");
		smsc9420_reg_write(pd, HASHH, 0);
		smsc9420_reg_write(pd, HASHL, 0);

		mac_cr &= (~MAC_CR_PRMS_);
		mac_cr &= (~MAC_CR_MCPAS_);
		mac_cr &= (~MAC_CR_HPFILT_);
	}

	smsc9420_reg_write(pd, MAC_CR, mac_cr);
	smsc9420_pci_flush_write(pd);
}

static void smsc9420_phy_update_flowcontrol(struct smsc9420_pdata *pd)
{
	struct phy_device *phy_dev = pd->phy_dev;
	u32 flow;

	if (phy_dev->duplex == DUPLEX_FULL) {
		u16 lcladv = phy_read(phy_dev, MII_ADVERTISE);
		u16 rmtadv = phy_read(phy_dev, MII_LPA);
		u8 cap = mii_resolve_flowctrl_fdx(lcladv, rmtadv);

		if (cap & FLOW_CTRL_RX)
			flow = 0xFFFF0002;
		else
			flow = 0;

		smsc_info(LINK, "rx pause %s, tx pause %s",
			(cap & FLOW_CTRL_RX ? "enabled" : "disabled"),
			(cap & FLOW_CTRL_TX ? "enabled" : "disabled"));
	} else {
		smsc_info(LINK, "half duplex");
		flow = 0;
	}

	smsc9420_reg_write(pd, FLOW, flow);
}

/* Update link mode if anything has changed.  Called periodically when the
 * PHY is in polling mode, even if nothing has changed. */
static void smsc9420_phy_adjust_link(struct net_device *dev)
{
	struct smsc9420_pdata *pd = netdev_priv(dev);
	struct phy_device *phy_dev = pd->phy_dev;
	int carrier;

	if (phy_dev->duplex != pd->last_duplex) {
		u32 mac_cr = smsc9420_reg_read(pd, MAC_CR);
		if (phy_dev->duplex) {
			smsc_dbg(LINK, "full duplex mode");
			mac_cr |= MAC_CR_FDPX_;
		} else {
			smsc_dbg(LINK, "half duplex mode");
			mac_cr &= ~MAC_CR_FDPX_;
		}
		smsc9420_reg_write(pd, MAC_CR, mac_cr);

		smsc9420_phy_update_flowcontrol(pd);
		pd->last_duplex = phy_dev->duplex;
	}

	carrier = netif_carrier_ok(dev);
	if (carrier != pd->last_carrier) {
		if (carrier)
			smsc_dbg(LINK, "carrier OK");
		else
			smsc_dbg(LINK, "no carrier");
		pd->last_carrier = carrier;
	}
}

static int smsc9420_mii_probe(struct net_device *dev)
{
	struct smsc9420_pdata *pd = netdev_priv(dev);
	struct phy_device *phydev = NULL;

	BUG_ON(pd->phy_dev);

	/* Device only supports internal PHY at address 1 */
	if (!pd->mii_bus->phy_map[1]) {
		pr_err("%s: no PHY found at address 1\n", dev->name);
		return -ENODEV;
	}

	phydev = pd->mii_bus->phy_map[1];
	smsc_info(PROBE, "PHY addr %d, phy_id 0x%08X", phydev->addr,
		phydev->phy_id);

	phydev = phy_connect(dev, dev_name(&phydev->dev),
		smsc9420_phy_adjust_link, 0, PHY_INTERFACE_MODE_MII);

	if (IS_ERR(phydev)) {
		pr_err("%s: Could not attach to PHY\n", dev->name);
		return PTR_ERR(phydev);
	}

	pr_info("%s: attached PHY driver [%s] (mii_bus:phy_addr=%s, irq=%d)\n",
		dev->name, phydev->drv->name, dev_name(&phydev->dev), phydev->irq);

	/* mask with MAC supported features */
	phydev->supported &= (PHY_BASIC_FEATURES | SUPPORTED_Pause |
			      SUPPORTED_Asym_Pause);
	phydev->advertising = phydev->supported;

	pd->phy_dev = phydev;
	pd->last_duplex = -1;
	pd->last_carrier = -1;

	return 0;
}

static int smsc9420_mii_init(struct net_device *dev)
{
	struct smsc9420_pdata *pd = netdev_priv(dev);
	int err = -ENXIO, i;

	pd->mii_bus = mdiobus_alloc();
	if (!pd->mii_bus) {
		err = -ENOMEM;
		goto err_out_1;
	}
	pd->mii_bus->name = DRV_MDIONAME;
	snprintf(pd->mii_bus->id, MII_BUS_ID_SIZE, "%x",
		(pd->pdev->bus->number << 8) | pd->pdev->devfn);
	pd->mii_bus->priv = pd;
	pd->mii_bus->read = smsc9420_mii_read;
	pd->mii_bus->write = smsc9420_mii_write;
	pd->mii_bus->irq = pd->phy_irq;
	for (i = 0; i < PHY_MAX_ADDR; ++i)
		pd->mii_bus->irq[i] = PHY_POLL;

	/* Mask all PHYs except ID 1 (internal) */
	pd->mii_bus->phy_mask = ~(1 << 1);

	if (mdiobus_register(pd->mii_bus)) {
		smsc_warn(PROBE, "Error registering mii bus");
		goto err_out_free_bus_2;
	}

	if (smsc9420_mii_probe(dev) < 0) {
		smsc_warn(PROBE, "Error probing mii bus");
		goto err_out_unregister_bus_3;
	}

	return 0;

err_out_unregister_bus_3:
	mdiobus_unregister(pd->mii_bus);
err_out_free_bus_2:
	mdiobus_free(pd->mii_bus);
err_out_1:
	return err;
}

static int smsc9420_alloc_tx_ring(struct smsc9420_pdata *pd)
{
	int i;

	BUG_ON(!pd->tx_ring);

	pd->tx_buffers = kmalloc((sizeof(struct smsc9420_ring_info) *
		TX_RING_SIZE), GFP_KERNEL);
	if (!pd->tx_buffers) {
		smsc_warn(IFUP, "Failed to allocated tx_buffers");
		return -ENOMEM;
	}

	/* Initialize the TX Ring */
	for (i = 0; i < TX_RING_SIZE; i++) {
		pd->tx_buffers[i].skb = NULL;
		pd->tx_buffers[i].mapping = 0;
		pd->tx_ring[i].status = 0;
		pd->tx_ring[i].length = 0;
		pd->tx_ring[i].buffer1 = 0;
		pd->tx_ring[i].buffer2 = 0;
	}
	pd->tx_ring[TX_RING_SIZE - 1].length = TDES1_TER_;
	wmb();

	pd->tx_ring_head = 0;
	pd->tx_ring_tail = 0;

	smsc9420_reg_write(pd, TX_BASE_ADDR, pd->tx_dma_addr);
	smsc9420_pci_flush_write(pd);

	return 0;
}

static int smsc9420_alloc_rx_ring(struct smsc9420_pdata *pd)
{
	int i;

	BUG_ON(!pd->rx_ring);

	pd->rx_buffers = kmalloc((sizeof(struct smsc9420_ring_info) *
		RX_RING_SIZE), GFP_KERNEL);
	if (pd->rx_buffers == NULL) {
		smsc_warn(IFUP, "Failed to allocated rx_buffers");
		goto out;
	}

	/* initialize the rx ring */
	for (i = 0; i < RX_RING_SIZE; i++) {
		pd->rx_ring[i].status = 0;
		pd->rx_ring[i].length = PKT_BUF_SZ;
		pd->rx_ring[i].buffer2 = 0;
		pd->rx_buffers[i].skb = NULL;
		pd->rx_buffers[i].mapping = 0;
	}
	pd->rx_ring[RX_RING_SIZE - 1].length = (PKT_BUF_SZ | RDES1_RER_);

	/* now allocate the entire ring of skbs */
	for (i = 0; i < RX_RING_SIZE; i++) {
		if (smsc9420_alloc_rx_buffer(pd, i)) {
			smsc_warn(IFUP, "failed to allocate rx skb %d", i);
			goto out_free_rx_skbs;
		}
	}

	pd->rx_ring_head = 0;
	pd->rx_ring_tail = 0;

	smsc9420_reg_write(pd, VLAN1, ETH_P_8021Q);
	smsc_dbg(IFUP, "VLAN1 = 0x%08x", smsc9420_reg_read(pd, VLAN1));

	if (pd->rx_csum) {
		/* Enable RX COE */
		u32 coe = smsc9420_reg_read(pd, COE_CR) | RX_COE_EN;
		smsc9420_reg_write(pd, COE_CR, coe);
		smsc_dbg(IFUP, "COE_CR = 0x%08x", coe);
	}

	smsc9420_reg_write(pd, RX_BASE_ADDR, pd->rx_dma_addr);
	smsc9420_pci_flush_write(pd);

	return 0;

out_free_rx_skbs:
	smsc9420_free_rx_ring(pd);
out:
	return -ENOMEM;
}

static int smsc9420_open(struct net_device *dev)
{
	struct smsc9420_pdata *pd;
	u32 bus_mode, mac_cr, dmac_control, int_cfg, dma_intr_ena, int_ctl;
	unsigned long flags;
	int result = 0, timeout;

	BUG_ON(!dev);
	pd = netdev_priv(dev);
	BUG_ON(!pd);

	if (!is_valid_ether_addr(dev->dev_addr)) {
		smsc_warn(IFUP, "dev_addr is not a valid MAC address");
		result = -EADDRNOTAVAIL;
		goto out_0;
	}

	netif_carrier_off(dev);

	/* disable, mask and acknowledge all interrupts */
	spin_lock_irqsave(&pd->int_lock, flags);
	int_cfg = smsc9420_reg_read(pd, INT_CFG) & (~INT_CFG_IRQ_EN_);
	smsc9420_reg_write(pd, INT_CFG, int_cfg);
	smsc9420_reg_write(pd, INT_CTL, 0);
	spin_unlock_irqrestore(&pd->int_lock, flags);
	smsc9420_reg_write(pd, DMAC_INTR_ENA, 0);
	smsc9420_reg_write(pd, INT_STAT, 0xFFFFFFFF);
	smsc9420_pci_flush_write(pd);

	if (request_irq(dev->irq, smsc9420_isr, IRQF_SHARED | IRQF_DISABLED,
			DRV_NAME, pd)) {
		smsc_warn(IFUP, "Unable to use IRQ = %d", dev->irq);
		result = -ENODEV;
		goto out_0;
	}

	smsc9420_dmac_soft_reset(pd);

	/* make sure MAC_CR is sane */
	smsc9420_reg_write(pd, MAC_CR, 0);

	smsc9420_set_mac_address(dev);

	/* Configure GPIO pins to drive LEDs */
	smsc9420_reg_write(pd, GPIO_CFG,
		(GPIO_CFG_LED_3_ | GPIO_CFG_LED_2_ | GPIO_CFG_LED_1_));

	bus_mode = BUS_MODE_DMA_BURST_LENGTH_16;

#ifdef __BIG_ENDIAN
	bus_mode |= BUS_MODE_DBO_;
#endif

	smsc9420_reg_write(pd, BUS_MODE, bus_mode);

	smsc9420_pci_flush_write(pd);

	/* set bus master bridge arbitration priority for Rx and TX DMA */
	smsc9420_reg_write(pd, BUS_CFG, BUS_CFG_RXTXWEIGHT_4_1);

	smsc9420_reg_write(pd, DMAC_CONTROL,
		(DMAC_CONTROL_SF_ | DMAC_CONTROL_OSF_));

	smsc9420_pci_flush_write(pd);

	/* test the IRQ connection to the ISR */
	smsc_dbg(IFUP, "Testing ISR using IRQ %d", dev->irq);
	pd->software_irq_signal = false;

	spin_lock_irqsave(&pd->int_lock, flags);
	/* configure interrupt deassertion timer and enable interrupts */
	int_cfg = smsc9420_reg_read(pd, INT_CFG) | INT_CFG_IRQ_EN_;
	int_cfg &= ~(INT_CFG_INT_DEAS_MASK);
	int_cfg |= (INT_DEAS_TIME & INT_CFG_INT_DEAS_MASK);
	smsc9420_reg_write(pd, INT_CFG, int_cfg);

	/* unmask software interrupt */
	int_ctl = smsc9420_reg_read(pd, INT_CTL) | INT_CTL_SW_INT_EN_;
	smsc9420_reg_write(pd, INT_CTL, int_ctl);
	spin_unlock_irqrestore(&pd->int_lock, flags);
	smsc9420_pci_flush_write(pd);

	timeout = 1000;
	while (timeout--) {
		if (pd->software_irq_signal)
			break;
		msleep(1);
	}

	/* disable interrupts */
	spin_lock_irqsave(&pd->int_lock, flags);
	int_cfg = smsc9420_reg_read(pd, INT_CFG) & (~INT_CFG_IRQ_EN_);
	smsc9420_reg_write(pd, INT_CFG, int_cfg);
	spin_unlock_irqrestore(&pd->int_lock, flags);

	if (!pd->software_irq_signal) {
		smsc_warn(IFUP, "ISR failed signaling test");
		result = -ENODEV;
		goto out_free_irq_1;
	}

	smsc_dbg(IFUP, "ISR passed test using IRQ %d", dev->irq);

	result = smsc9420_alloc_tx_ring(pd);
	if (result) {
		smsc_warn(IFUP, "Failed to Initialize tx dma ring");
		result = -ENOMEM;
		goto out_free_irq_1;
	}

	result = smsc9420_alloc_rx_ring(pd);
	if (result) {
		smsc_warn(IFUP, "Failed to Initialize rx dma ring");
		result = -ENOMEM;
		goto out_free_tx_ring_2;
	}

	result = smsc9420_mii_init(dev);
	if (result) {
		smsc_warn(IFUP, "Failed to initialize Phy");
		result = -ENODEV;
		goto out_free_rx_ring_3;
	}

	/* Bring the PHY up */
	phy_start(pd->phy_dev);

	napi_enable(&pd->napi);

	/* start tx and rx */
	mac_cr = smsc9420_reg_read(pd, MAC_CR) | MAC_CR_TXEN_ | MAC_CR_RXEN_;
	smsc9420_reg_write(pd, MAC_CR, mac_cr);

	dmac_control = smsc9420_reg_read(pd, DMAC_CONTROL);
	dmac_control |= DMAC_CONTROL_ST_ | DMAC_CONTROL_SR_;
	smsc9420_reg_write(pd, DMAC_CONTROL, dmac_control);
	smsc9420_pci_flush_write(pd);

	dma_intr_ena = smsc9420_reg_read(pd, DMAC_INTR_ENA);
	dma_intr_ena |=
		(DMAC_INTR_ENA_TX_ | DMAC_INTR_ENA_RX_ | DMAC_INTR_ENA_NIS_);
	smsc9420_reg_write(pd, DMAC_INTR_ENA, dma_intr_ena);
	smsc9420_pci_flush_write(pd);

	netif_wake_queue(dev);

	smsc9420_reg_write(pd, RX_POLL_DEMAND, 1);

	/* enable interrupts */
	spin_lock_irqsave(&pd->int_lock, flags);
	int_cfg = smsc9420_reg_read(pd, INT_CFG) | INT_CFG_IRQ_EN_;
	smsc9420_reg_write(pd, INT_CFG, int_cfg);
	spin_unlock_irqrestore(&pd->int_lock, flags);

	return 0;

out_free_rx_ring_3:
	smsc9420_free_rx_ring(pd);
out_free_tx_ring_2:
	smsc9420_free_tx_ring(pd);
out_free_irq_1:
	free_irq(dev->irq, pd);
out_0:
	return result;
}

#ifdef CONFIG_PM

static int smsc9420_suspend(struct pci_dev *pdev, pm_message_t state)
{
	struct net_device *dev = pci_get_drvdata(pdev);
	struct smsc9420_pdata *pd = netdev_priv(dev);
	u32 int_cfg;
	ulong flags;

	/* disable interrupts */
	spin_lock_irqsave(&pd->int_lock, flags);
	int_cfg = smsc9420_reg_read(pd, INT_CFG) & (~INT_CFG_IRQ_EN_);
	smsc9420_reg_write(pd, INT_CFG, int_cfg);
	spin_unlock_irqrestore(&pd->int_lock, flags);

	if (netif_running(dev)) {
		netif_tx_disable(dev);
		smsc9420_stop_tx(pd);
		smsc9420_free_tx_ring(pd);

		napi_disable(&pd->napi);
		smsc9420_stop_rx(pd);
		smsc9420_free_rx_ring(pd);

		free_irq(dev->irq, pd);

		netif_device_detach(dev);
	}

	pci_save_state(pdev);
	pci_enable_wake(pdev, pci_choose_state(pdev, state), 0);
	pci_disable_device(pdev);
	pci_set_power_state(pdev, pci_choose_state(pdev, state));

	return 0;
}

static int smsc9420_resume(struct pci_dev *pdev)
{
	struct net_device *dev = pci_get_drvdata(pdev);
	struct smsc9420_pdata *pd = netdev_priv(dev);
	int err;

	pci_set_power_state(pdev, PCI_D0);
	pci_restore_state(pdev);

	err = pci_enable_device(pdev);
	if (err)
		return err;

	pci_set_master(pdev);

	err = pci_enable_wake(pdev, 0, 0);
	if (err)
		smsc_warn(IFUP, "pci_enable_wake failed: %d", err);

	if (netif_running(dev)) {
		err = smsc9420_open(dev);
		netif_device_attach(dev);
	}
	return err;
}

#endif /* CONFIG_PM */

static const struct net_device_ops smsc9420_netdev_ops = {
	.ndo_open		= smsc9420_open,
	.ndo_stop		= smsc9420_stop,
	.ndo_start_xmit		= smsc9420_hard_start_xmit,
	.ndo_get_stats		= smsc9420_get_stats,
	.ndo_set_multicast_list	= smsc9420_set_multicast_list,
	.ndo_do_ioctl		= smsc9420_do_ioctl,
	.ndo_validate_addr	= eth_validate_addr,
	.ndo_set_mac_address 	= eth_mac_addr,
#ifdef CONFIG_NET_POLL_CONTROLLER
	.ndo_poll_controller	= smsc9420_poll_controller,
#endif /* CONFIG_NET_POLL_CONTROLLER */
};

static int __devinit
smsc9420_probe(struct pci_dev *pdev, const struct pci_device_id *id)
{
	struct net_device *dev;
	struct smsc9420_pdata *pd;
	void __iomem *virt_addr;
	int result = 0;
	u32 id_rev;

	printk(KERN_INFO DRV_DESCRIPTION " version " DRV_VERSION "\n");

	/* First do the PCI initialisation */
	result = pci_enable_device(pdev);
	if (unlikely(result)) {
		printk(KERN_ERR "Cannot enable smsc9420\n");
		goto out_0;
	}

	pci_set_master(pdev);

	dev = alloc_etherdev(sizeof(*pd));
	if (!dev) {
		printk(KERN_ERR "ether device alloc failed\n");
		goto out_disable_pci_device_1;
	}

	SET_NETDEV_DEV(dev, &pdev->dev);

	if (!(pci_resource_flags(pdev, SMSC_BAR) & IORESOURCE_MEM)) {
		printk(KERN_ERR "Cannot find PCI device base address\n");
		goto out_free_netdev_2;
	}

	if ((pci_request_regions(pdev, DRV_NAME))) {
		printk(KERN_ERR "Cannot obtain PCI resources, aborting.\n");
		goto out_free_netdev_2;
	}

	if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) {
		printk(KERN_ERR "No usable DMA configuration, aborting.\n");
		goto out_free_regions_3;
	}

	virt_addr = ioremap(pci_resource_start(pdev, SMSC_BAR),
		pci_resource_len(pdev, SMSC_BAR));
	if (!virt_addr) {
		printk(KERN_ERR "Cannot map device registers, aborting.\n");
		goto out_free_regions_3;
	}

	/* registers are double mapped with 0 offset for LE and 0x200 for BE */
	virt_addr += LAN9420_CPSR_ENDIAN_OFFSET;

	dev->base_addr = (ulong)virt_addr;

	pd = netdev_priv(dev);

	/* pci descriptors are created in the PCI consistent area */
	pd->rx_ring = pci_alloc_consistent(pdev,
		sizeof(struct smsc9420_dma_desc) * RX_RING_SIZE +
		sizeof(struct smsc9420_dma_desc) * TX_RING_SIZE,
		&pd->rx_dma_addr);

	if (!pd->rx_ring)
		goto out_free_io_4;

	/* descriptors are aligned due to the nature of pci_alloc_consistent */
	pd->tx_ring = (struct smsc9420_dma_desc *)
	    (pd->rx_ring + RX_RING_SIZE);
	pd->tx_dma_addr = pd->rx_dma_addr +
	    sizeof(struct smsc9420_dma_desc) * RX_RING_SIZE;

	pd->pdev = pdev;
	pd->dev = dev;
	pd->base_addr = virt_addr;
	pd->msg_enable = smsc_debug;
	pd->rx_csum = true;

	smsc_dbg(PROBE, "lan_base=0x%08lx", (ulong)virt_addr);

	id_rev = smsc9420_reg_read(pd, ID_REV);
	switch (id_rev & 0xFFFF0000) {
	case 0x94200000:
		smsc_info(PROBE, "LAN9420 identified, ID_REV=0x%08X", id_rev);
		break;
	default:
		smsc_warn(PROBE, "LAN9420 NOT identified");
		smsc_warn(PROBE, "ID_REV=0x%08X", id_rev);
		goto out_free_dmadesc_5;
	}

	smsc9420_dmac_soft_reset(pd);
	smsc9420_eeprom_reload(pd);
	smsc9420_check_mac_address(dev);

	dev->netdev_ops = &smsc9420_netdev_ops;
	dev->ethtool_ops = &smsc9420_ethtool_ops;
	dev->irq = pdev->irq;

	netif_napi_add(dev, &pd->napi, smsc9420_rx_poll, NAPI_WEIGHT);

	result = register_netdev(dev);
	if (result) {
		smsc_warn(PROBE, "error %i registering device", result);
		goto out_free_dmadesc_5;
	}

	pci_set_drvdata(pdev, dev);

	spin_lock_init(&pd->int_lock);
	spin_lock_init(&pd->phy_lock);

	dev_info(&dev->dev, "MAC Address: %pM\n", dev->dev_addr);

	return 0;

out_free_dmadesc_5:
	pci_free_consistent(pdev, sizeof(struct smsc9420_dma_desc) *
		(RX_RING_SIZE + TX_RING_SIZE), pd->rx_ring, pd->rx_dma_addr);
out_free_io_4:
	iounmap(virt_addr - LAN9420_CPSR_ENDIAN_OFFSET);
out_free_regions_3:
	pci_release_regions(pdev);
out_free_netdev_2:
	free_netdev(dev);
out_disable_pci_device_1:
	pci_disable_device(pdev);
out_0:
	return -ENODEV;
}

static void __devexit smsc9420_remove(struct pci_dev *pdev)
{
	struct net_device *dev;
	struct smsc9420_pdata *pd;

	dev = pci_get_drvdata(pdev);
	if (!dev)
		return;

	pci_set_drvdata(pdev, NULL);

	pd = netdev_priv(dev);
	unregister_netdev(dev);

	/* tx_buffers and rx_buffers are freed in stop */
	BUG_ON(pd->tx_buffers);
	BUG_ON(pd->rx_buffers);

	BUG_ON(!pd->tx_ring);
	BUG_ON(!pd->rx_ring);

	pci_free_consistent(pdev, sizeof(struct smsc9420_dma_desc) *
		(RX_RING_SIZE + TX_RING_SIZE), pd->rx_ring, pd->rx_dma_addr);

	iounmap(pd->base_addr - LAN9420_CPSR_ENDIAN_OFFSET);
	pci_release_regions(pdev);
	free_netdev(dev);
	pci_disable_device(pdev);
}

static struct pci_driver smsc9420_driver = {
	.name = DRV_NAME,
	.id_table = smsc9420_id_table,
	.probe = smsc9420_probe,
	.remove = __devexit_p(smsc9420_remove),
#ifdef CONFIG_PM
	.suspend = smsc9420_suspend,
	.resume = smsc9420_resume,
#endif /* CONFIG_PM */
};

static int __init smsc9420_init_module(void)
{
	smsc_debug = netif_msg_init(debug, SMSC_MSG_DEFAULT);

	return pci_register_driver(&smsc9420_driver);
}

static void __exit smsc9420_exit_module(void)
{
	pci_unregister_driver(&smsc9420_driver);
}

module_init(smsc9420_init_module);
module_exit(smsc9420_exit_module);
