/*
 * ipg.c: Device Driver for the IP1000 Gigabit Ethernet Adapter
 *
 * Copyright (C) 2003, 2007  IC Plus Corp
 *
 * Original Author:
 *
 *   Craig Rich
 *   Sundance Technology, Inc.
 *   www.sundanceti.com
 *   craig_rich@sundanceti.com
 *
 * Current Maintainer:
 *
 *   Sorbica Shieh.
 *   http://www.icplus.com.tw
 *   sorbica@icplus.com.tw
 *
 *   Jesse Huang
 *   http://www.icplus.com.tw
 *   jesse@icplus.com.tw
 */
#include <linux/crc32.h>
#include <linux/ethtool.h>
#include <linux/gfp.h>
#include <linux/mii.h>
#include <linux/mutex.h>

#include <asm/div64.h>

#define IPG_RX_RING_BYTES	(sizeof(struct ipg_rx) * IPG_RFDLIST_LENGTH)
#define IPG_TX_RING_BYTES	(sizeof(struct ipg_tx) * IPG_TFDLIST_LENGTH)
#define IPG_RESET_MASK \
	(IPG_AC_GLOBAL_RESET | IPG_AC_RX_RESET | IPG_AC_TX_RESET | \
	 IPG_AC_DMA | IPG_AC_FIFO | IPG_AC_NETWORK | IPG_AC_HOST | \
	 IPG_AC_AUTO_INIT)

#define ipg_w32(val32, reg)	iowrite32((val32), ioaddr + (reg))
#define ipg_w16(val16, reg)	iowrite16((val16), ioaddr + (reg))
#define ipg_w8(val8, reg)	iowrite8((val8), ioaddr + (reg))

#define ipg_r32(reg)		ioread32(ioaddr + (reg))
#define ipg_r16(reg)		ioread16(ioaddr + (reg))
#define ipg_r8(reg)		ioread8(ioaddr + (reg))

enum {
	netdev_io_size = 128
};

#include "ipg.h"
#define DRV_NAME	"ipg"

MODULE_AUTHOR("IC Plus Corp. 2003");
MODULE_DESCRIPTION("IC Plus IP1000 Gigabit Ethernet Adapter Linux Driver");
MODULE_LICENSE("GPL");

/*
 * Defaults
 */
#define IPG_MAX_RXFRAME_SIZE	0x0600
#define IPG_RXFRAG_SIZE		0x0600
#define IPG_RXSUPPORT_SIZE	0x0600
#define IPG_IS_JUMBO		false

/*
 * Variable record -- index by leading revision/length
 * Revision/Length(=N*4), Address1, Data1, Address2, Data2,...,AddressN,DataN
 */
static unsigned short DefaultPhyParam[] = {
	/* 11/12/03 IP1000A v1-3 rev=0x40 */
	/*--------------------------------------------------------------------------
	(0x4000|(15*4)), 31, 0x0001, 27, 0x01e0, 31, 0x0002, 22, 0x85bd, 24, 0xfff2,
				 27, 0x0c10, 28, 0x0c10, 29, 0x2c10, 31, 0x0003, 23, 0x92f6,
				 31, 0x0000, 23, 0x003d, 30, 0x00de, 20, 0x20e7,  9, 0x0700,
	  --------------------------------------------------------------------------*/
	/* 12/17/03 IP1000A v1-4 rev=0x40 */
	(0x4000 | (07 * 4)), 31, 0x0001, 27, 0x01e0, 31, 0x0002, 27, 0xeb8e, 31,
	    0x0000,
	30, 0x005e, 9, 0x0700,
	/* 01/09/04 IP1000A v1-5 rev=0x41 */
	(0x4100 | (07 * 4)), 31, 0x0001, 27, 0x01e0, 31, 0x0002, 27, 0xeb8e, 31,
	    0x0000,
	30, 0x005e, 9, 0x0700,
	0x0000
};

static const char *ipg_brand_name[] = {
	"IC PLUS IP1000 1000/100/10 based NIC",
	"Sundance Technology ST2021 based NIC",
	"Tamarack Microelectronics TC9020/9021 based NIC",
	"D-Link NIC IP1000A"
};

static DEFINE_PCI_DEVICE_TABLE(ipg_pci_tbl) = {
	{ PCI_VDEVICE(SUNDANCE,	0x1023), 0 },
	{ PCI_VDEVICE(SUNDANCE,	0x2021), 1 },
	{ PCI_VDEVICE(DLINK,	0x9021), 2 },
	{ PCI_VDEVICE(DLINK,	0x4020), 3 },
	{ 0, }
};

MODULE_DEVICE_TABLE(pci, ipg_pci_tbl);

static inline void __iomem *ipg_ioaddr(struct net_device *dev)
{
	struct ipg_nic_private *sp = netdev_priv(dev);
	return sp->ioaddr;
}

#ifdef IPG_DEBUG
static void ipg_dump_rfdlist(struct net_device *dev)
{
	struct ipg_nic_private *sp = netdev_priv(dev);
	void __iomem *ioaddr = sp->ioaddr;
	unsigned int i;
	u32 offset;

	IPG_DEBUG_MSG("_dump_rfdlist\n");

	printk(KERN_INFO "rx_current = %2.2x\n", sp->rx_current);
	printk(KERN_INFO "rx_dirty   = %2.2x\n", sp->rx_dirty);
	printk(KERN_INFO "RFDList start address = %16.16lx\n",
	       (unsigned long) sp->rxd_map);
	printk(KERN_INFO "RFDListPtr register   = %8.8x%8.8x\n",
	       ipg_r32(IPG_RFDLISTPTR1), ipg_r32(IPG_RFDLISTPTR0));

	for (i = 0; i < IPG_RFDLIST_LENGTH; i++) {
		offset = (u32) &sp->rxd[i].next_desc - (u32) sp->rxd;
		printk(KERN_INFO "%2.2x %4.4x RFDNextPtr = %16.16lx\n", i,
		       offset, (unsigned long) sp->rxd[i].next_desc);
		offset = (u32) &sp->rxd[i].rfs - (u32) sp->rxd;
		printk(KERN_INFO "%2.2x %4.4x RFS        = %16.16lx\n", i,
		       offset, (unsigned long) sp->rxd[i].rfs);
		offset = (u32) &sp->rxd[i].frag_info - (u32) sp->rxd;
		printk(KERN_INFO "%2.2x %4.4x frag_info   = %16.16lx\n", i,
		       offset, (unsigned long) sp->rxd[i].frag_info);
	}
}

static void ipg_dump_tfdlist(struct net_device *dev)
{
	struct ipg_nic_private *sp = netdev_priv(dev);
	void __iomem *ioaddr = sp->ioaddr;
	unsigned int i;
	u32 offset;

	IPG_DEBUG_MSG("_dump_tfdlist\n");

	printk(KERN_INFO "tx_current         = %2.2x\n", sp->tx_current);
	printk(KERN_INFO "tx_dirty = %2.2x\n", sp->tx_dirty);
	printk(KERN_INFO "TFDList start address = %16.16lx\n",
	       (unsigned long) sp->txd_map);
	printk(KERN_INFO "TFDListPtr register   = %8.8x%8.8x\n",
	       ipg_r32(IPG_TFDLISTPTR1), ipg_r32(IPG_TFDLISTPTR0));

	for (i = 0; i < IPG_TFDLIST_LENGTH; i++) {
		offset = (u32) &sp->txd[i].next_desc - (u32) sp->txd;
		printk(KERN_INFO "%2.2x %4.4x TFDNextPtr = %16.16lx\n", i,
		       offset, (unsigned long) sp->txd[i].next_desc);

		offset = (u32) &sp->txd[i].tfc - (u32) sp->txd;
		printk(KERN_INFO "%2.2x %4.4x TFC        = %16.16lx\n", i,
		       offset, (unsigned long) sp->txd[i].tfc);
		offset = (u32) &sp->txd[i].frag_info - (u32) sp->txd;
		printk(KERN_INFO "%2.2x %4.4x frag_info   = %16.16lx\n", i,
		       offset, (unsigned long) sp->txd[i].frag_info);
	}
}
#endif

static void ipg_write_phy_ctl(void __iomem *ioaddr, u8 data)
{
	ipg_w8(IPG_PC_RSVD_MASK & data, PHY_CTRL);
	ndelay(IPG_PC_PHYCTRLWAIT_NS);
}

static void ipg_drive_phy_ctl_low_high(void __iomem *ioaddr, u8 data)
{
	ipg_write_phy_ctl(ioaddr, IPG_PC_MGMTCLK_LO | data);
	ipg_write_phy_ctl(ioaddr, IPG_PC_MGMTCLK_HI | data);
}

static void send_three_state(void __iomem *ioaddr, u8 phyctrlpolarity)
{
	phyctrlpolarity |= (IPG_PC_MGMTDATA & 0) | IPG_PC_MGMTDIR;

	ipg_drive_phy_ctl_low_high(ioaddr, phyctrlpolarity);
}

static void send_end(void __iomem *ioaddr, u8 phyctrlpolarity)
{
	ipg_w8((IPG_PC_MGMTCLK_LO | (IPG_PC_MGMTDATA & 0) | IPG_PC_MGMTDIR |
		phyctrlpolarity) & IPG_PC_RSVD_MASK, PHY_CTRL);
}

static u16 read_phy_bit(void __iomem *ioaddr, u8 phyctrlpolarity)
{
	u16 bit_data;

	ipg_write_phy_ctl(ioaddr, IPG_PC_MGMTCLK_LO | phyctrlpolarity);

	bit_data = ((ipg_r8(PHY_CTRL) & IPG_PC_MGMTDATA) >> 1) & 1;

	ipg_write_phy_ctl(ioaddr, IPG_PC_MGMTCLK_HI | phyctrlpolarity);

	return bit_data;
}

/*
 * Read a register from the Physical Layer device located
 * on the IPG NIC, using the IPG PHYCTRL register.
 */
static int mdio_read(struct net_device *dev, int phy_id, int phy_reg)
{
	void __iomem *ioaddr = ipg_ioaddr(dev);
	/*
	 * The GMII mangement frame structure for a read is as follows:
	 *
	 * |Preamble|st|op|phyad|regad|ta|      data      |idle|
	 * |< 32 1s>|01|10|AAAAA|RRRRR|z0|DDDDDDDDDDDDDDDD|z   |
	 *
	 * <32 1s> = 32 consecutive logic 1 values
	 * A = bit of Physical Layer device address (MSB first)
	 * R = bit of register address (MSB first)
	 * z = High impedance state
	 * D = bit of read data (MSB first)
	 *
	 * Transmission order is 'Preamble' field first, bits transmitted
	 * left to right (first to last).
	 */
	struct {
		u32 field;
		unsigned int len;
	} p[] = {
		{ GMII_PREAMBLE,	32 },	/* Preamble */
		{ GMII_ST,		2  },	/* ST */
		{ GMII_READ,		2  },	/* OP */
		{ phy_id,		5  },	/* PHYAD */
		{ phy_reg,		5  },	/* REGAD */
		{ 0x0000,		2  },	/* TA */
		{ 0x0000,		16 },	/* DATA */
		{ 0x0000,		1  }	/* IDLE */
	};
	unsigned int i, j;
	u8 polarity, data;

	polarity  = ipg_r8(PHY_CTRL);
	polarity &= (IPG_PC_DUPLEX_POLARITY | IPG_PC_LINK_POLARITY);

	/* Create the Preamble, ST, OP, PHYAD, and REGAD field. */
	for (j = 0; j < 5; j++) {
		for (i = 0; i < p[j].len; i++) {
			/* For each variable length field, the MSB must be
			 * transmitted first. Rotate through the field bits,
			 * starting with the MSB, and move each bit into the
			 * the 1st (2^1) bit position (this is the bit position
			 * corresponding to the MgmtData bit of the PhyCtrl
			 * register for the IPG).
			 *
			 * Example: ST = 01;
			 *
			 *          First write a '0' to bit 1 of the PhyCtrl
			 *          register, then write a '1' to bit 1 of the
			 *          PhyCtrl register.
			 *
			 * To do this, right shift the MSB of ST by the value:
			 * [field length - 1 - #ST bits already written]
			 * then left shift this result by 1.
			 */
			data  = (p[j].field >> (p[j].len - 1 - i)) << 1;
			data &= IPG_PC_MGMTDATA;
			data |= polarity | IPG_PC_MGMTDIR;

			ipg_drive_phy_ctl_low_high(ioaddr, data);
		}
	}

	send_three_state(ioaddr, polarity);

	read_phy_bit(ioaddr, polarity);

	/*
	 * For a read cycle, the bits for the next two fields (TA and
	 * DATA) are driven by the PHY (the IPG reads these bits).
	 */
	for (i = 0; i < p[6].len; i++) {
		p[6].field |=
		    (read_phy_bit(ioaddr, polarity) << (p[6].len - 1 - i));
	}

	send_three_state(ioaddr, polarity);
	send_three_state(ioaddr, polarity);
	send_three_state(ioaddr, polarity);
	send_end(ioaddr, polarity);

	/* Return the value of the DATA field. */
	return p[6].field;
}

/*
 * Write to a register from the Physical Layer device located
 * on the IPG NIC, using the IPG PHYCTRL register.
 */
static void mdio_write(struct net_device *dev, int phy_id, int phy_reg, int val)
{
	void __iomem *ioaddr = ipg_ioaddr(dev);
	/*
	 * The GMII mangement frame structure for a read is as follows:
	 *
	 * |Preamble|st|op|phyad|regad|ta|      data      |idle|
	 * |< 32 1s>|01|10|AAAAA|RRRRR|z0|DDDDDDDDDDDDDDDD|z   |
	 *
	 * <32 1s> = 32 consecutive logic 1 values
	 * A = bit of Physical Layer device address (MSB first)
	 * R = bit of register address (MSB first)
	 * z = High impedance state
	 * D = bit of write data (MSB first)
	 *
	 * Transmission order is 'Preamble' field first, bits transmitted
	 * left to right (first to last).
	 */
	struct {
		u32 field;
		unsigned int len;
	} p[] = {
		{ GMII_PREAMBLE,	32 },	/* Preamble */
		{ GMII_ST,		2  },	/* ST */
		{ GMII_WRITE,		2  },	/* OP */
		{ phy_id,		5  },	/* PHYAD */
		{ phy_reg,		5  },	/* REGAD */
		{ 0x0002,		2  },	/* TA */
		{ val & 0xffff,		16 },	/* DATA */
		{ 0x0000,		1  }	/* IDLE */
	};
	unsigned int i, j;
	u8 polarity, data;

	polarity  = ipg_r8(PHY_CTRL);
	polarity &= (IPG_PC_DUPLEX_POLARITY | IPG_PC_LINK_POLARITY);

	/* Create the Preamble, ST, OP, PHYAD, and REGAD field. */
	for (j = 0; j < 7; j++) {
		for (i = 0; i < p[j].len; i++) {
			/* For each variable length field, the MSB must be
			 * transmitted first. Rotate through the field bits,
			 * starting with the MSB, and move each bit into the
			 * the 1st (2^1) bit position (this is the bit position
			 * corresponding to the MgmtData bit of the PhyCtrl
			 * register for the IPG).
			 *
			 * Example: ST = 01;
			 *
			 *          First write a '0' to bit 1 of the PhyCtrl
			 *          register, then write a '1' to bit 1 of the
			 *          PhyCtrl register.
			 *
			 * To do this, right shift the MSB of ST by the value:
			 * [field length - 1 - #ST bits already written]
			 * then left shift this result by 1.
			 */
			data  = (p[j].field >> (p[j].len - 1 - i)) << 1;
			data &= IPG_PC_MGMTDATA;
			data |= polarity | IPG_PC_MGMTDIR;

			ipg_drive_phy_ctl_low_high(ioaddr, data);
		}
	}

	/* The last cycle is a tri-state, so read from the PHY. */
	for (j = 7; j < 8; j++) {
		for (i = 0; i < p[j].len; i++) {
			ipg_write_phy_ctl(ioaddr, IPG_PC_MGMTCLK_LO | polarity);

			p[j].field |= ((ipg_r8(PHY_CTRL) &
				IPG_PC_MGMTDATA) >> 1) << (p[j].len - 1 - i);

			ipg_write_phy_ctl(ioaddr, IPG_PC_MGMTCLK_HI | polarity);
		}
	}
}

static void ipg_set_led_mode(struct net_device *dev)
{
	struct ipg_nic_private *sp = netdev_priv(dev);
	void __iomem *ioaddr = sp->ioaddr;
	u32 mode;

	mode = ipg_r32(ASIC_CTRL);
	mode &= ~(IPG_AC_LED_MODE_BIT_1 | IPG_AC_LED_MODE | IPG_AC_LED_SPEED);

	if ((sp->led_mode & 0x03) > 1)
		mode |= IPG_AC_LED_MODE_BIT_1;	/* Write Asic Control Bit 29 */

	if ((sp->led_mode & 0x01) == 1)
		mode |= IPG_AC_LED_MODE;	/* Write Asic Control Bit 14 */

	if ((sp->led_mode & 0x08) == 8)
		mode |= IPG_AC_LED_SPEED;	/* Write Asic Control Bit 27 */

	ipg_w32(mode, ASIC_CTRL);
}

static void ipg_set_phy_set(struct net_device *dev)
{
	struct ipg_nic_private *sp = netdev_priv(dev);
	void __iomem *ioaddr = sp->ioaddr;
	int physet;

	physet = ipg_r8(PHY_SET);
	physet &= ~(IPG_PS_MEM_LENB9B | IPG_PS_MEM_LEN9 | IPG_PS_NON_COMPDET);
	physet |= ((sp->led_mode & 0x70) >> 4);
	ipg_w8(physet, PHY_SET);
}

static int ipg_reset(struct net_device *dev, u32 resetflags)
{
	/* Assert functional resets via the IPG AsicCtrl
	 * register as specified by the 'resetflags' input
	 * parameter.
	 */
	void __iomem *ioaddr = ipg_ioaddr(dev);
	unsigned int timeout_count = 0;

	IPG_DEBUG_MSG("_reset\n");

	ipg_w32(ipg_r32(ASIC_CTRL) | resetflags, ASIC_CTRL);

	/* Delay added to account for problem with 10Mbps reset. */
	mdelay(IPG_AC_RESETWAIT);

	while (IPG_AC_RESET_BUSY & ipg_r32(ASIC_CTRL)) {
		mdelay(IPG_AC_RESETWAIT);
		if (++timeout_count > IPG_AC_RESET_TIMEOUT)
			return -ETIME;
	}
	/* Set LED Mode in Asic Control */
	ipg_set_led_mode(dev);

	/* Set PHYSet Register Value */
	ipg_set_phy_set(dev);
	return 0;
}

/* Find the GMII PHY address. */
static int ipg_find_phyaddr(struct net_device *dev)
{
	unsigned int phyaddr, i;

	for (i = 0; i < 32; i++) {
		u32 status;

		/* Search for the correct PHY address among 32 possible. */
		phyaddr = (IPG_NIC_PHY_ADDRESS + i) % 32;

		/* 10/22/03 Grace change verify from GMII_PHY_STATUS to
		   GMII_PHY_ID1
		 */

		status = mdio_read(dev, phyaddr, MII_BMSR);

		if ((status != 0xFFFF) && (status != 0))
			return phyaddr;
	}

	return 0x1f;
}

/*
 * Configure IPG based on result of IEEE 802.3 PHY
 * auto-negotiation.
 */
static int ipg_config_autoneg(struct net_device *dev)
{
	struct ipg_nic_private *sp = netdev_priv(dev);
	void __iomem *ioaddr = sp->ioaddr;
	unsigned int txflowcontrol;
	unsigned int rxflowcontrol;
	unsigned int fullduplex;
	u32 mac_ctrl_val;
	u32 asicctrl;
	u8 phyctrl;

	IPG_DEBUG_MSG("_config_autoneg\n");

	asicctrl = ipg_r32(ASIC_CTRL);
	phyctrl = ipg_r8(PHY_CTRL);
	mac_ctrl_val = ipg_r32(MAC_CTRL);

	/* Set flags for use in resolving auto-negotation, assuming
	 * non-1000Mbps, half duplex, no flow control.
	 */
	fullduplex = 0;
	txflowcontrol = 0;
	rxflowcontrol = 0;

	/* To accomodate a problem in 10Mbps operation,
	 * set a global flag if PHY running in 10Mbps mode.
	 */
	sp->tenmbpsmode = 0;

	printk(KERN_INFO "%s: Link speed = ", dev->name);

	/* Determine actual speed of operation. */
	switch (phyctrl & IPG_PC_LINK_SPEED) {
	case IPG_PC_LINK_SPEED_10MBPS:
		printk("10Mbps.\n");
		printk(KERN_INFO "%s: 10Mbps operational mode enabled.\n",
		       dev->name);
		sp->tenmbpsmode = 1;
		break;
	case IPG_PC_LINK_SPEED_100MBPS:
		printk("100Mbps.\n");
		break;
	case IPG_PC_LINK_SPEED_1000MBPS:
		printk("1000Mbps.\n");
		break;
	default:
		printk("undefined!\n");
		return 0;
	}

	if (phyctrl & IPG_PC_DUPLEX_STATUS) {
		fullduplex = 1;
		txflowcontrol = 1;
		rxflowcontrol = 1;
	}

	/* Configure full duplex, and flow control. */
	if (fullduplex == 1) {
		/* Configure IPG for full duplex operation. */
		printk(KERN_INFO "%s: setting full duplex, ", dev->name);

		mac_ctrl_val |= IPG_MC_DUPLEX_SELECT_FD;

		if (txflowcontrol == 1) {
			printk("TX flow control");
			mac_ctrl_val |= IPG_MC_TX_FLOW_CONTROL_ENABLE;
		} else {
			printk("no TX flow control");
			mac_ctrl_val &= ~IPG_MC_TX_FLOW_CONTROL_ENABLE;
		}

		if (rxflowcontrol == 1) {
			printk(", RX flow control.");
			mac_ctrl_val |= IPG_MC_RX_FLOW_CONTROL_ENABLE;
		} else {
			printk(", no RX flow control.");
			mac_ctrl_val &= ~IPG_MC_RX_FLOW_CONTROL_ENABLE;
		}

		printk("\n");
	} else {
		/* Configure IPG for half duplex operation. */
		printk(KERN_INFO "%s: setting half duplex, "
		       "no TX flow control, no RX flow control.\n", dev->name);

		mac_ctrl_val &= ~IPG_MC_DUPLEX_SELECT_FD &
			~IPG_MC_TX_FLOW_CONTROL_ENABLE &
			~IPG_MC_RX_FLOW_CONTROL_ENABLE;
	}
	ipg_w32(mac_ctrl_val, MAC_CTRL);
	return 0;
}

/* Determine and configure multicast operation and set
 * receive mode for IPG.
 */
static void ipg_nic_set_multicast_list(struct net_device *dev)
{
	void __iomem *ioaddr = ipg_ioaddr(dev);
	struct netdev_hw_addr *ha;
	unsigned int hashindex;
	u32 hashtable[2];
	u8 receivemode;

	IPG_DEBUG_MSG("_nic_set_multicast_list\n");

	receivemode = IPG_RM_RECEIVEUNICAST | IPG_RM_RECEIVEBROADCAST;

	if (dev->flags & IFF_PROMISC) {
		/* NIC to be configured in promiscuous mode. */
		receivemode = IPG_RM_RECEIVEALLFRAMES;
	} else if ((dev->flags & IFF_ALLMULTI) ||
		   ((dev->flags & IFF_MULTICAST) &&
		    (netdev_mc_count(dev) > IPG_MULTICAST_HASHTABLE_SIZE))) {
		/* NIC to be configured to receive all multicast
		 * frames. */
		receivemode |= IPG_RM_RECEIVEMULTICAST;
	} else if ((dev->flags & IFF_MULTICAST) && !netdev_mc_empty(dev)) {
		/* NIC to be configured to receive selected
		 * multicast addresses. */
		receivemode |= IPG_RM_RECEIVEMULTICASTHASH;
	}

	/* Calculate the bits to set for the 64 bit, IPG HASHTABLE.
	 * The IPG applies a cyclic-redundancy-check (the same CRC
	 * used to calculate the frame data FCS) to the destination
	 * address all incoming multicast frames whose destination
	 * address has the multicast bit set. The least significant
	 * 6 bits of the CRC result are used as an addressing index
	 * into the hash table. If the value of the bit addressed by
	 * this index is a 1, the frame is passed to the host system.
	 */

	/* Clear hashtable. */
	hashtable[0] = 0x00000000;
	hashtable[1] = 0x00000000;

	/* Cycle through all multicast addresses to filter. */
	netdev_for_each_mc_addr(ha, dev) {
		/* Calculate CRC result for each multicast address. */
		hashindex = crc32_le(0xffffffff, ha->addr,
				     ETH_ALEN);

		/* Use only the least significant 6 bits. */
		hashindex = hashindex & 0x3F;

		/* Within "hashtable", set bit number "hashindex"
		 * to a logic 1.
		 */
		set_bit(hashindex, (void *)hashtable);
	}

	/* Write the value of the hashtable, to the 4, 16 bit
	 * HASHTABLE IPG registers.
	 */
	ipg_w32(hashtable[0], HASHTABLE_0);
	ipg_w32(hashtable[1], HASHTABLE_1);

	ipg_w8(IPG_RM_RSVD_MASK & receivemode, RECEIVE_MODE);

	IPG_DEBUG_MSG("ReceiveMode = %x\n", ipg_r8(RECEIVE_MODE));
}

static int ipg_io_config(struct net_device *dev)
{
	struct ipg_nic_private *sp = netdev_priv(dev);
	void __iomem *ioaddr = ipg_ioaddr(dev);
	u32 origmacctrl;
	u32 restoremacctrl;

	IPG_DEBUG_MSG("_io_config\n");

	origmacctrl = ipg_r32(MAC_CTRL);

	restoremacctrl = origmacctrl | IPG_MC_STATISTICS_ENABLE;

	/* Based on compilation option, determine if FCS is to be
	 * stripped on receive frames by IPG.
	 */
	if (!IPG_STRIP_FCS_ON_RX)
		restoremacctrl |= IPG_MC_RCV_FCS;

	/* Determine if transmitter and/or receiver are
	 * enabled so we may restore MACCTRL correctly.
	 */
	if (origmacctrl & IPG_MC_TX_ENABLED)
		restoremacctrl |= IPG_MC_TX_ENABLE;

	if (origmacctrl & IPG_MC_RX_ENABLED)
		restoremacctrl |= IPG_MC_RX_ENABLE;

	/* Transmitter and receiver must be disabled before setting
	 * IFSSelect.
	 */
	ipg_w32((origmacctrl & (IPG_MC_RX_DISABLE | IPG_MC_TX_DISABLE)) &
		IPG_MC_RSVD_MASK, MAC_CTRL);

	/* Now that transmitter and receiver are disabled, write
	 * to IFSSelect.
	 */
	ipg_w32((origmacctrl & IPG_MC_IFS_96BIT) & IPG_MC_RSVD_MASK, MAC_CTRL);

	/* Set RECEIVEMODE register. */
	ipg_nic_set_multicast_list(dev);

	ipg_w16(sp->max_rxframe_size, MAX_FRAME_SIZE);

	ipg_w8(IPG_RXDMAPOLLPERIOD_VALUE,   RX_DMA_POLL_PERIOD);
	ipg_w8(IPG_RXDMAURGENTTHRESH_VALUE, RX_DMA_URGENT_THRESH);
	ipg_w8(IPG_RXDMABURSTTHRESH_VALUE,  RX_DMA_BURST_THRESH);
	ipg_w8(IPG_TXDMAPOLLPERIOD_VALUE,   TX_DMA_POLL_PERIOD);
	ipg_w8(IPG_TXDMAURGENTTHRESH_VALUE, TX_DMA_URGENT_THRESH);
	ipg_w8(IPG_TXDMABURSTTHRESH_VALUE,  TX_DMA_BURST_THRESH);
	ipg_w16((IPG_IE_HOST_ERROR | IPG_IE_TX_DMA_COMPLETE |
		 IPG_IE_TX_COMPLETE | IPG_IE_INT_REQUESTED |
		 IPG_IE_UPDATE_STATS | IPG_IE_LINK_EVENT |
		 IPG_IE_RX_DMA_COMPLETE | IPG_IE_RX_DMA_PRIORITY), INT_ENABLE);
	ipg_w16(IPG_FLOWONTHRESH_VALUE,  FLOW_ON_THRESH);
	ipg_w16(IPG_FLOWOFFTHRESH_VALUE, FLOW_OFF_THRESH);

	/* IPG multi-frag frame bug workaround.
	 * Per silicon revision B3 eratta.
	 */
	ipg_w16(ipg_r16(DEBUG_CTRL) | 0x0200, DEBUG_CTRL);

	/* IPG TX poll now bug workaround.
	 * Per silicon revision B3 eratta.
	 */
	ipg_w16(ipg_r16(DEBUG_CTRL) | 0x0010, DEBUG_CTRL);

	/* IPG RX poll now bug workaround.
	 * Per silicon revision B3 eratta.
	 */
	ipg_w16(ipg_r16(DEBUG_CTRL) | 0x0020, DEBUG_CTRL);

	/* Now restore MACCTRL to original setting. */
	ipg_w32(IPG_MC_RSVD_MASK & restoremacctrl, MAC_CTRL);

	/* Disable unused RMON statistics. */
	ipg_w32(IPG_RZ_ALL, RMON_STATISTICS_MASK);

	/* Disable unused MIB statistics. */
	ipg_w32(IPG_SM_MACCONTROLFRAMESXMTD | IPG_SM_MACCONTROLFRAMESRCVD |
		IPG_SM_BCSTOCTETXMTOK_BCSTFRAMESXMTDOK | IPG_SM_TXJUMBOFRAMES |
		IPG_SM_MCSTOCTETXMTOK_MCSTFRAMESXMTDOK | IPG_SM_RXJUMBOFRAMES |
		IPG_SM_BCSTOCTETRCVDOK_BCSTFRAMESRCVDOK |
		IPG_SM_UDPCHECKSUMERRORS | IPG_SM_TCPCHECKSUMERRORS |
		IPG_SM_IPCHECKSUMERRORS, STATISTICS_MASK);

	return 0;
}

/*
 * Create a receive buffer within system memory and update
 * NIC private structure appropriately.
 */
static int ipg_get_rxbuff(struct net_device *dev, int entry)
{
	struct ipg_nic_private *sp = netdev_priv(dev);
	struct ipg_rx *rxfd = sp->rxd + entry;
	struct sk_buff *skb;
	u64 rxfragsize;

	IPG_DEBUG_MSG("_get_rxbuff\n");

	skb = netdev_alloc_skb_ip_align(dev, sp->rxsupport_size);
	if (!skb) {
		sp->rx_buff[entry] = NULL;
		return -ENOMEM;
	}

	/* Associate the receive buffer with the IPG NIC. */
	skb->dev = dev;

	/* Save the address of the sk_buff structure. */
	sp->rx_buff[entry] = skb;

	rxfd->frag_info = cpu_to_le64(pci_map_single(sp->pdev, skb->data,
		sp->rx_buf_sz, PCI_DMA_FROMDEVICE));

	/* Set the RFD fragment length. */
	rxfragsize = sp->rxfrag_size;
	rxfd->frag_info |= cpu_to_le64((rxfragsize << 48) & IPG_RFI_FRAGLEN);

	return 0;
}

static int init_rfdlist(struct net_device *dev)
{
	struct ipg_nic_private *sp = netdev_priv(dev);
	void __iomem *ioaddr = sp->ioaddr;
	unsigned int i;

	IPG_DEBUG_MSG("_init_rfdlist\n");

	for (i = 0; i < IPG_RFDLIST_LENGTH; i++) {
		struct ipg_rx *rxfd = sp->rxd + i;

		if (sp->rx_buff[i]) {
			pci_unmap_single(sp->pdev,
				le64_to_cpu(rxfd->frag_info) & ~IPG_RFI_FRAGLEN,
				sp->rx_buf_sz, PCI_DMA_FROMDEVICE);
			dev_kfree_skb_irq(sp->rx_buff[i]);
			sp->rx_buff[i] = NULL;
		}

		/* Clear out the RFS field. */
		rxfd->rfs = 0x0000000000000000;

		if (ipg_get_rxbuff(dev, i) < 0) {
			/*
			 * A receive buffer was not ready, break the
			 * RFD list here.
			 */
			IPG_DEBUG_MSG("Cannot allocate Rx buffer.\n");

			/* Just in case we cannot allocate a single RFD.
			 * Should not occur.
			 */
			if (i == 0) {
				printk(KERN_ERR "%s: No memory available"
					" for RFD list.\n", dev->name);
				return -ENOMEM;
			}
		}

		rxfd->next_desc = cpu_to_le64(sp->rxd_map +
			sizeof(struct ipg_rx)*(i + 1));
	}
	sp->rxd[i - 1].next_desc = cpu_to_le64(sp->rxd_map);

	sp->rx_current = 0;
	sp->rx_dirty = 0;

	/* Write the location of the RFDList to the IPG. */
	ipg_w32((u32) sp->rxd_map, RFD_LIST_PTR_0);
	ipg_w32(0x00000000, RFD_LIST_PTR_1);

	return 0;
}

static void init_tfdlist(struct net_device *dev)
{
	struct ipg_nic_private *sp = netdev_priv(dev);
	void __iomem *ioaddr = sp->ioaddr;
	unsigned int i;

	IPG_DEBUG_MSG("_init_tfdlist\n");

	for (i = 0; i < IPG_TFDLIST_LENGTH; i++) {
		struct ipg_tx *txfd = sp->txd + i;

		txfd->tfc = cpu_to_le64(IPG_TFC_TFDDONE);

		if (sp->tx_buff[i]) {
			dev_kfree_skb_irq(sp->tx_buff[i]);
			sp->tx_buff[i] = NULL;
		}

		txfd->next_desc = cpu_to_le64(sp->txd_map +
			sizeof(struct ipg_tx)*(i + 1));
	}
	sp->txd[i - 1].next_desc = cpu_to_le64(sp->txd_map);

	sp->tx_current = 0;
	sp->tx_dirty = 0;

	/* Write the location of the TFDList to the IPG. */
	IPG_DDEBUG_MSG("Starting TFDListPtr = %8.8x\n",
		       (u32) sp->txd_map);
	ipg_w32((u32) sp->txd_map, TFD_LIST_PTR_0);
	ipg_w32(0x00000000, TFD_LIST_PTR_1);

	sp->reset_current_tfd = 1;
}

/*
 * Free all transmit buffers which have already been transfered
 * via DMA to the IPG.
 */
static void ipg_nic_txfree(struct net_device *dev)
{
	struct ipg_nic_private *sp = netdev_priv(dev);
	unsigned int released, pending, dirty;

	IPG_DEBUG_MSG("_nic_txfree\n");

	pending = sp->tx_current - sp->tx_dirty;
	dirty = sp->tx_dirty % IPG_TFDLIST_LENGTH;

	for (released = 0; released < pending; released++) {
		struct sk_buff *skb = sp->tx_buff[dirty];
		struct ipg_tx *txfd = sp->txd + dirty;

		IPG_DEBUG_MSG("TFC = %16.16lx\n", (unsigned long) txfd->tfc);

		/* Look at each TFD's TFC field beginning
		 * at the last freed TFD up to the current TFD.
		 * If the TFDDone bit is set, free the associated
		 * buffer.
		 */
		if (!(txfd->tfc & cpu_to_le64(IPG_TFC_TFDDONE)))
                        break;

		/* Free the transmit buffer. */
		if (skb) {
			pci_unmap_single(sp->pdev,
				le64_to_cpu(txfd->frag_info) & ~IPG_TFI_FRAGLEN,
				skb->len, PCI_DMA_TODEVICE);

			dev_kfree_skb_irq(skb);

			sp->tx_buff[dirty] = NULL;
		}
		dirty = (dirty + 1) % IPG_TFDLIST_LENGTH;
	}

	sp->tx_dirty += released;

	if (netif_queue_stopped(dev) &&
	    (sp->tx_current != (sp->tx_dirty + IPG_TFDLIST_LENGTH))) {
		netif_wake_queue(dev);
	}
}

static void ipg_tx_timeout(struct net_device *dev)
{
	struct ipg_nic_private *sp = netdev_priv(dev);
	void __iomem *ioaddr = sp->ioaddr;

	ipg_reset(dev, IPG_AC_TX_RESET | IPG_AC_DMA | IPG_AC_NETWORK |
		  IPG_AC_FIFO);

	spin_lock_irq(&sp->lock);

	/* Re-configure after DMA reset. */
	if (ipg_io_config(dev) < 0) {
		printk(KERN_INFO "%s: Error during re-configuration.\n",
		       dev->name);
	}

	init_tfdlist(dev);

	spin_unlock_irq(&sp->lock);

	ipg_w32((ipg_r32(MAC_CTRL) | IPG_MC_TX_ENABLE) & IPG_MC_RSVD_MASK,
		MAC_CTRL);
}

/*
 * For TxComplete interrupts, free all transmit
 * buffers which have already been transfered via DMA
 * to the IPG.
 */
static void ipg_nic_txcleanup(struct net_device *dev)
{
	struct ipg_nic_private *sp = netdev_priv(dev);
	void __iomem *ioaddr = sp->ioaddr;
	unsigned int i;

	IPG_DEBUG_MSG("_nic_txcleanup\n");

	for (i = 0; i < IPG_TFDLIST_LENGTH; i++) {
		/* Reading the TXSTATUS register clears the
		 * TX_COMPLETE interrupt.
		 */
		u32 txstatusdword = ipg_r32(TX_STATUS);

		IPG_DEBUG_MSG("TxStatus = %8.8x\n", txstatusdword);

		/* Check for Transmit errors. Error bits only valid if
		 * TX_COMPLETE bit in the TXSTATUS register is a 1.
		 */
		if (!(txstatusdword & IPG_TS_TX_COMPLETE))
			break;

		/* If in 10Mbps mode, indicate transmit is ready. */
		if (sp->tenmbpsmode) {
			netif_wake_queue(dev);
		}

		/* Transmit error, increment stat counters. */
		if (txstatusdword & IPG_TS_TX_ERROR) {
			IPG_DEBUG_MSG("Transmit error.\n");
			sp->stats.tx_errors++;
		}

		/* Late collision, re-enable transmitter. */
		if (txstatusdword & IPG_TS_LATE_COLLISION) {
			IPG_DEBUG_MSG("Late collision on transmit.\n");
			ipg_w32((ipg_r32(MAC_CTRL) | IPG_MC_TX_ENABLE) &
				IPG_MC_RSVD_MASK, MAC_CTRL);
		}

		/* Maximum collisions, re-enable transmitter. */
		if (txstatusdword & IPG_TS_TX_MAX_COLL) {
			IPG_DEBUG_MSG("Maximum collisions on transmit.\n");
			ipg_w32((ipg_r32(MAC_CTRL) | IPG_MC_TX_ENABLE) &
				IPG_MC_RSVD_MASK, MAC_CTRL);
		}

		/* Transmit underrun, reset and re-enable
		 * transmitter.
		 */
		if (txstatusdword & IPG_TS_TX_UNDERRUN) {
			IPG_DEBUG_MSG("Transmitter underrun.\n");
			sp->stats.tx_fifo_errors++;
			ipg_reset(dev, IPG_AC_TX_RESET | IPG_AC_DMA |
				  IPG_AC_NETWORK | IPG_AC_FIFO);

			/* Re-configure after DMA reset. */
			if (ipg_io_config(dev) < 0) {
				printk(KERN_INFO
				       "%s: Error during re-configuration.\n",
				       dev->name);
			}
			init_tfdlist(dev);

			ipg_w32((ipg_r32(MAC_CTRL) | IPG_MC_TX_ENABLE) &
				IPG_MC_RSVD_MASK, MAC_CTRL);
		}
	}

	ipg_nic_txfree(dev);
}

/* Provides statistical information about the IPG NIC. */
static struct net_device_stats *ipg_nic_get_stats(struct net_device *dev)
{
	struct ipg_nic_private *sp = netdev_priv(dev);
	void __iomem *ioaddr = sp->ioaddr;
	u16 temp1;
	u16 temp2;

	IPG_DEBUG_MSG("_nic_get_stats\n");

	/* Check to see if the NIC has been initialized via nic_open,
	 * before trying to read statistic registers.
	 */
	if (!test_bit(__LINK_STATE_START, &dev->state))
		return &sp->stats;

	sp->stats.rx_packets += ipg_r32(IPG_FRAMESRCVDOK);
	sp->stats.tx_packets += ipg_r32(IPG_FRAMESXMTDOK);
	sp->stats.rx_bytes += ipg_r32(IPG_OCTETRCVOK);
	sp->stats.tx_bytes += ipg_r32(IPG_OCTETXMTOK);
	temp1 = ipg_r16(IPG_FRAMESLOSTRXERRORS);
	sp->stats.rx_errors += temp1;
	sp->stats.rx_missed_errors += temp1;
	temp1 = ipg_r32(IPG_SINGLECOLFRAMES) + ipg_r32(IPG_MULTICOLFRAMES) +
		ipg_r32(IPG_LATECOLLISIONS);
	temp2 = ipg_r16(IPG_CARRIERSENSEERRORS);
	sp->stats.collisions += temp1;
	sp->stats.tx_dropped += ipg_r16(IPG_FRAMESABORTXSCOLLS);
	sp->stats.tx_errors += ipg_r16(IPG_FRAMESWEXDEFERRAL) +
		ipg_r32(IPG_FRAMESWDEFERREDXMT) + temp1 + temp2;
	sp->stats.multicast += ipg_r32(IPG_MCSTOCTETRCVDOK);

	/* detailed tx_errors */
	sp->stats.tx_carrier_errors += temp2;

	/* detailed rx_errors */
	sp->stats.rx_length_errors += ipg_r16(IPG_INRANGELENGTHERRORS) +
		ipg_r16(IPG_FRAMETOOLONGERRRORS);
	sp->stats.rx_crc_errors += ipg_r16(IPG_FRAMECHECKSEQERRORS);

	/* Unutilized IPG statistic registers. */
	ipg_r32(IPG_MCSTFRAMESRCVDOK);

	return &sp->stats;
}

/* Restore used receive buffers. */
static int ipg_nic_rxrestore(struct net_device *dev)
{
	struct ipg_nic_private *sp = netdev_priv(dev);
	const unsigned int curr = sp->rx_current;
	unsigned int dirty = sp->rx_dirty;

	IPG_DEBUG_MSG("_nic_rxrestore\n");

	for (dirty = sp->rx_dirty; curr - dirty > 0; dirty++) {
		unsigned int entry = dirty % IPG_RFDLIST_LENGTH;

		/* rx_copybreak may poke hole here and there. */
		if (sp->rx_buff[entry])
			continue;

		/* Generate a new receive buffer to replace the
		 * current buffer (which will be released by the
		 * Linux system).
		 */
		if (ipg_get_rxbuff(dev, entry) < 0) {
			IPG_DEBUG_MSG("Cannot allocate new Rx buffer.\n");

			break;
		}

		/* Reset the RFS field. */
		sp->rxd[entry].rfs = 0x0000000000000000;
	}
	sp->rx_dirty = dirty;

	return 0;
}

/* use jumboindex and jumbosize to control jumbo frame status
 * initial status is jumboindex=-1 and jumbosize=0
 * 1. jumboindex = -1 and jumbosize=0 : previous jumbo frame has been done.
 * 2. jumboindex != -1 and jumbosize != 0 : jumbo frame is not over size and receiving
 * 3. jumboindex = -1 and jumbosize != 0 : jumbo frame is over size, already dump
 *               previous receiving and need to continue dumping the current one
 */
enum {
	NORMAL_PACKET,
	ERROR_PACKET
};

enum {
	FRAME_NO_START_NO_END	= 0,
	FRAME_WITH_START		= 1,
	FRAME_WITH_END		= 10,
	FRAME_WITH_START_WITH_END = 11
};

static void ipg_nic_rx_free_skb(struct net_device *dev)
{
	struct ipg_nic_private *sp = netdev_priv(dev);
	unsigned int entry = sp->rx_current % IPG_RFDLIST_LENGTH;

	if (sp->rx_buff[entry]) {
		struct ipg_rx *rxfd = sp->rxd + entry;

		pci_unmap_single(sp->pdev,
			le64_to_cpu(rxfd->frag_info) & ~IPG_RFI_FRAGLEN,
			sp->rx_buf_sz, PCI_DMA_FROMDEVICE);
		dev_kfree_skb_irq(sp->rx_buff[entry]);
		sp->rx_buff[entry] = NULL;
	}
}

static int ipg_nic_rx_check_frame_type(struct net_device *dev)
{
	struct ipg_nic_private *sp = netdev_priv(dev);
	struct ipg_rx *rxfd = sp->rxd + (sp->rx_current % IPG_RFDLIST_LENGTH);
	int type = FRAME_NO_START_NO_END;

	if (le64_to_cpu(rxfd->rfs) & IPG_RFS_FRAMESTART)
		type += FRAME_WITH_START;
	if (le64_to_cpu(rxfd->rfs) & IPG_RFS_FRAMEEND)
		type += FRAME_WITH_END;
	return type;
}

static int ipg_nic_rx_check_error(struct net_device *dev)
{
	struct ipg_nic_private *sp = netdev_priv(dev);
	unsigned int entry = sp->rx_current % IPG_RFDLIST_LENGTH;
	struct ipg_rx *rxfd = sp->rxd + entry;

	if (IPG_DROP_ON_RX_ETH_ERRORS && (le64_to_cpu(rxfd->rfs) &
	     (IPG_RFS_RXFIFOOVERRUN | IPG_RFS_RXRUNTFRAME |
	      IPG_RFS_RXALIGNMENTERROR | IPG_RFS_RXFCSERROR |
	      IPG_RFS_RXOVERSIZEDFRAME | IPG_RFS_RXLENGTHERROR))) {
		IPG_DEBUG_MSG("Rx error, RFS = %16.16lx\n",
			      (unsigned long) rxfd->rfs);

		/* Increment general receive error statistic. */
		sp->stats.rx_errors++;

		/* Increment detailed receive error statistics. */
		if (le64_to_cpu(rxfd->rfs) & IPG_RFS_RXFIFOOVERRUN) {
			IPG_DEBUG_MSG("RX FIFO overrun occured.\n");

			sp->stats.rx_fifo_errors++;
		}

		if (le64_to_cpu(rxfd->rfs) & IPG_RFS_RXRUNTFRAME) {
			IPG_DEBUG_MSG("RX runt occured.\n");
			sp->stats.rx_length_errors++;
		}

		/* Do nothing for IPG_RFS_RXOVERSIZEDFRAME,
		 * error count handled by a IPG statistic register.
		 */

		if (le64_to_cpu(rxfd->rfs) & IPG_RFS_RXALIGNMENTERROR) {
			IPG_DEBUG_MSG("RX alignment error occured.\n");
			sp->stats.rx_frame_errors++;
		}

		/* Do nothing for IPG_RFS_RXFCSERROR, error count
		 * handled by a IPG statistic register.
		 */

		/* Free the memory associated with the RX
		 * buffer since it is erroneous and we will
		 * not pass it to higher layer processes.
		 */
		if (sp->rx_buff[entry]) {
			pci_unmap_single(sp->pdev,
				le64_to_cpu(rxfd->frag_info) & ~IPG_RFI_FRAGLEN,
				sp->rx_buf_sz, PCI_DMA_FROMDEVICE);

			dev_kfree_skb_irq(sp->rx_buff[entry]);
			sp->rx_buff[entry] = NULL;
		}
		return ERROR_PACKET;
	}
	return NORMAL_PACKET;
}

static void ipg_nic_rx_with_start_and_end(struct net_device *dev,
					  struct ipg_nic_private *sp,
					  struct ipg_rx *rxfd, unsigned entry)
{
	struct ipg_jumbo *jumbo = &sp->jumbo;
	struct sk_buff *skb;
	int framelen;

	if (jumbo->found_start) {
		dev_kfree_skb_irq(jumbo->skb);
		jumbo->found_start = 0;
		jumbo->current_size = 0;
		jumbo->skb = NULL;
	}

	/* 1: found error, 0 no error */
	if (ipg_nic_rx_check_error(dev) != NORMAL_PACKET)
		return;

	skb = sp->rx_buff[entry];
	if (!skb)
		return;

	/* accept this frame and send to upper layer */
	framelen = le64_to_cpu(rxfd->rfs) & IPG_RFS_RXFRAMELEN;
	if (framelen > sp->rxfrag_size)
		framelen = sp->rxfrag_size;

	skb_put(skb, framelen);
	skb->protocol = eth_type_trans(skb, dev);
	skb_checksum_none_assert(skb);
	netif_rx(skb);
	sp->rx_buff[entry] = NULL;
}

static void ipg_nic_rx_with_start(struct net_device *dev,
				  struct ipg_nic_private *sp,
				  struct ipg_rx *rxfd, unsigned entry)
{
	struct ipg_jumbo *jumbo = &sp->jumbo;
	struct pci_dev *pdev = sp->pdev;
	struct sk_buff *skb;

	/* 1: found error, 0 no error */
	if (ipg_nic_rx_check_error(dev) != NORMAL_PACKET)
		return;

	/* accept this frame and send to upper layer */
	skb = sp->rx_buff[entry];
	if (!skb)
		return;

	if (jumbo->found_start)
		dev_kfree_skb_irq(jumbo->skb);

	pci_unmap_single(pdev, le64_to_cpu(rxfd->frag_info) & ~IPG_RFI_FRAGLEN,
			 sp->rx_buf_sz, PCI_DMA_FROMDEVICE);

	skb_put(skb, sp->rxfrag_size);

	jumbo->found_start = 1;
	jumbo->current_size = sp->rxfrag_size;
	jumbo->skb = skb;

	sp->rx_buff[entry] = NULL;
}

static void ipg_nic_rx_with_end(struct net_device *dev,
				struct ipg_nic_private *sp,
				struct ipg_rx *rxfd, unsigned entry)
{
	struct ipg_jumbo *jumbo = &sp->jumbo;

	/* 1: found error, 0 no error */
	if (ipg_nic_rx_check_error(dev) == NORMAL_PACKET) {
		struct sk_buff *skb = sp->rx_buff[entry];

		if (!skb)
			return;

		if (jumbo->found_start) {
			int framelen, endframelen;

			framelen = le64_to_cpu(rxfd->rfs) & IPG_RFS_RXFRAMELEN;

			endframelen = framelen - jumbo->current_size;
			if (framelen > sp->rxsupport_size)
				dev_kfree_skb_irq(jumbo->skb);
			else {
				memcpy(skb_put(jumbo->skb, endframelen),
				       skb->data, endframelen);

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

				skb_checksum_none_assert(jumbo->skb);
				netif_rx(jumbo->skb);
			}
		}

		jumbo->found_start = 0;
		jumbo->current_size = 0;
		jumbo->skb = NULL;

		ipg_nic_rx_free_skb(dev);
	} else {
		dev_kfree_skb_irq(jumbo->skb);
		jumbo->found_start = 0;
		jumbo->current_size = 0;
		jumbo->skb = NULL;
	}
}

static void ipg_nic_rx_no_start_no_end(struct net_device *dev,
				       struct ipg_nic_private *sp,
				       struct ipg_rx *rxfd, unsigned entry)
{
	struct ipg_jumbo *jumbo = &sp->jumbo;

	/* 1: found error, 0 no error */
	if (ipg_nic_rx_check_error(dev) == NORMAL_PACKET) {
		struct sk_buff *skb = sp->rx_buff[entry];

		if (skb) {
			if (jumbo->found_start) {
				jumbo->current_size += sp->rxfrag_size;
				if (jumbo->current_size <= sp->rxsupport_size) {
					memcpy(skb_put(jumbo->skb,
						       sp->rxfrag_size),
					       skb->data, sp->rxfrag_size);
				}
			}
			ipg_nic_rx_free_skb(dev);
		}
	} else {
		dev_kfree_skb_irq(jumbo->skb);
		jumbo->found_start = 0;
		jumbo->current_size = 0;
		jumbo->skb = NULL;
	}
}

static int ipg_nic_rx_jumbo(struct net_device *dev)
{
	struct ipg_nic_private *sp = netdev_priv(dev);
	unsigned int curr = sp->rx_current;
	void __iomem *ioaddr = sp->ioaddr;
	unsigned int i;

	IPG_DEBUG_MSG("_nic_rx\n");

	for (i = 0; i < IPG_MAXRFDPROCESS_COUNT; i++, curr++) {
		unsigned int entry = curr % IPG_RFDLIST_LENGTH;
		struct ipg_rx *rxfd = sp->rxd + entry;

		if (!(rxfd->rfs & cpu_to_le64(IPG_RFS_RFDDONE)))
			break;

		switch (ipg_nic_rx_check_frame_type(dev)) {
		case FRAME_WITH_START_WITH_END:
			ipg_nic_rx_with_start_and_end(dev, sp, rxfd, entry);
			break;
		case FRAME_WITH_START:
			ipg_nic_rx_with_start(dev, sp, rxfd, entry);
			break;
		case FRAME_WITH_END:
			ipg_nic_rx_with_end(dev, sp, rxfd, entry);
			break;
		case FRAME_NO_START_NO_END:
			ipg_nic_rx_no_start_no_end(dev, sp, rxfd, entry);
			break;
		}
	}

	sp->rx_current = curr;

	if (i == IPG_MAXRFDPROCESS_COUNT) {
		/* There are more RFDs to process, however the
		 * allocated amount of RFD processing time has
		 * expired. Assert Interrupt Requested to make
		 * sure we come back to process the remaining RFDs.
		 */
		ipg_w32(ipg_r32(ASIC_CTRL) | IPG_AC_INT_REQUEST, ASIC_CTRL);
	}

	ipg_nic_rxrestore(dev);

	return 0;
}

static int ipg_nic_rx(struct net_device *dev)
{
	/* Transfer received Ethernet frames to higher network layers. */
	struct ipg_nic_private *sp = netdev_priv(dev);
	unsigned int curr = sp->rx_current;
	void __iomem *ioaddr = sp->ioaddr;
	struct ipg_rx *rxfd;
	unsigned int i;

	IPG_DEBUG_MSG("_nic_rx\n");

#define __RFS_MASK \
	cpu_to_le64(IPG_RFS_RFDDONE | IPG_RFS_FRAMESTART | IPG_RFS_FRAMEEND)

	for (i = 0; i < IPG_MAXRFDPROCESS_COUNT; i++, curr++) {
		unsigned int entry = curr % IPG_RFDLIST_LENGTH;
		struct sk_buff *skb = sp->rx_buff[entry];
		unsigned int framelen;

		rxfd = sp->rxd + entry;

		if (((rxfd->rfs & __RFS_MASK) != __RFS_MASK) || !skb)
			break;

		/* Get received frame length. */
		framelen = le64_to_cpu(rxfd->rfs) & IPG_RFS_RXFRAMELEN;

		/* Check for jumbo frame arrival with too small
		 * RXFRAG_SIZE.
		 */
		if (framelen > sp->rxfrag_size) {
			IPG_DEBUG_MSG
			    ("RFS FrameLen > allocated fragment size.\n");

			framelen = sp->rxfrag_size;
		}

		if ((IPG_DROP_ON_RX_ETH_ERRORS && (le64_to_cpu(rxfd->rfs) &
		       (IPG_RFS_RXFIFOOVERRUN | IPG_RFS_RXRUNTFRAME |
			IPG_RFS_RXALIGNMENTERROR | IPG_RFS_RXFCSERROR |
			IPG_RFS_RXOVERSIZEDFRAME | IPG_RFS_RXLENGTHERROR)))) {

			IPG_DEBUG_MSG("Rx error, RFS = %16.16lx\n",
				      (unsigned long int) rxfd->rfs);

			/* Increment general receive error statistic. */
			sp->stats.rx_errors++;

			/* Increment detailed receive error statistics. */
			if (le64_to_cpu(rxfd->rfs) & IPG_RFS_RXFIFOOVERRUN) {
				IPG_DEBUG_MSG("RX FIFO overrun occured.\n");
				sp->stats.rx_fifo_errors++;
			}

			if (le64_to_cpu(rxfd->rfs) & IPG_RFS_RXRUNTFRAME) {
				IPG_DEBUG_MSG("RX runt occured.\n");
				sp->stats.rx_length_errors++;
			}

			if (le64_to_cpu(rxfd->rfs) & IPG_RFS_RXOVERSIZEDFRAME) ;
			/* Do nothing, error count handled by a IPG
			 * statistic register.
			 */

			if (le64_to_cpu(rxfd->rfs) & IPG_RFS_RXALIGNMENTERROR) {
				IPG_DEBUG_MSG("RX alignment error occured.\n");
				sp->stats.rx_frame_errors++;
			}

			if (le64_to_cpu(rxfd->rfs) & IPG_RFS_RXFCSERROR) ;
			/* Do nothing, error count handled by a IPG
			 * statistic register.
			 */

			/* Free the memory associated with the RX
			 * buffer since it is erroneous and we will
			 * not pass it to higher layer processes.
			 */
			if (skb) {
				__le64 info = rxfd->frag_info;

				pci_unmap_single(sp->pdev,
					le64_to_cpu(info) & ~IPG_RFI_FRAGLEN,
					sp->rx_buf_sz, PCI_DMA_FROMDEVICE);

				dev_kfree_skb_irq(skb);
			}
		} else {

			/* Adjust the new buffer length to accomodate the size
			 * of the received frame.
			 */
			skb_put(skb, framelen);

			/* Set the buffer's protocol field to Ethernet. */
			skb->protocol = eth_type_trans(skb, dev);

			/* The IPG encountered an error with (or
			 * there were no) IP/TCP/UDP checksums.
			 * This may or may not indicate an invalid
			 * IP/TCP/UDP frame was received. Let the
			 * upper layer decide.
			 */
			skb_checksum_none_assert(skb);

			/* Hand off frame for higher layer processing.
			 * The function netif_rx() releases the sk_buff
			 * when processing completes.
			 */
			netif_rx(skb);
		}

		/* Assure RX buffer is not reused by IPG. */
		sp->rx_buff[entry] = NULL;
	}

	/*
	 * If there are more RFDs to proces and the allocated amount of RFD
	 * processing time has expired, assert Interrupt Requested to make
	 * sure we come back to process the remaining RFDs.
	 */
	if (i == IPG_MAXRFDPROCESS_COUNT)
		ipg_w32(ipg_r32(ASIC_CTRL) | IPG_AC_INT_REQUEST, ASIC_CTRL);

#ifdef IPG_DEBUG
	/* Check if the RFD list contained no receive frame data. */
	if (!i)
		sp->EmptyRFDListCount++;
#endif
	while ((le64_to_cpu(rxfd->rfs) & IPG_RFS_RFDDONE) &&
	       !((le64_to_cpu(rxfd->rfs) & IPG_RFS_FRAMESTART) &&
		 (le64_to_cpu(rxfd->rfs) & IPG_RFS_FRAMEEND))) {
		unsigned int entry = curr++ % IPG_RFDLIST_LENGTH;

		rxfd = sp->rxd + entry;

		IPG_DEBUG_MSG("Frame requires multiple RFDs.\n");

		/* An unexpected event, additional code needed to handle
		 * properly. So for the time being, just disregard the
		 * frame.
		 */

		/* Free the memory associated with the RX
		 * buffer since it is erroneous and we will
		 * not pass it to higher layer processes.
		 */
		if (sp->rx_buff[entry]) {
			pci_unmap_single(sp->pdev,
				le64_to_cpu(rxfd->frag_info) & ~IPG_RFI_FRAGLEN,
				sp->rx_buf_sz, PCI_DMA_FROMDEVICE);
			dev_kfree_skb_irq(sp->rx_buff[entry]);
		}

		/* Assure RX buffer is not reused by IPG. */
		sp->rx_buff[entry] = NULL;
	}

	sp->rx_current = curr;

	/* Check to see if there are a minimum number of used
	 * RFDs before restoring any (should improve performance.)
	 */
	if ((curr - sp->rx_dirty) >= IPG_MINUSEDRFDSTOFREE)
		ipg_nic_rxrestore(dev);

	return 0;
}

static void ipg_reset_after_host_error(struct work_struct *work)
{
	struct ipg_nic_private *sp =
		container_of(work, struct ipg_nic_private, task.work);
	struct net_device *dev = sp->dev;

	/*
	 * Acknowledge HostError interrupt by resetting
	 * IPG DMA and HOST.
	 */
	ipg_reset(dev, IPG_AC_GLOBAL_RESET | IPG_AC_HOST | IPG_AC_DMA);

	init_rfdlist(dev);
	init_tfdlist(dev);

	if (ipg_io_config(dev) < 0) {
		printk(KERN_INFO "%s: Cannot recover from PCI error.\n",
		       dev->name);
		schedule_delayed_work(&sp->task, HZ);
	}
}

static irqreturn_t ipg_interrupt_handler(int irq, void *dev_inst)
{
	struct net_device *dev = dev_inst;
	struct ipg_nic_private *sp = netdev_priv(dev);
	void __iomem *ioaddr = sp->ioaddr;
	unsigned int handled = 0;
	u16 status;

	IPG_DEBUG_MSG("_interrupt_handler\n");

	if (sp->is_jumbo)
		ipg_nic_rxrestore(dev);

	spin_lock(&sp->lock);

	/* Get interrupt source information, and acknowledge
	 * some (i.e. TxDMAComplete, RxDMAComplete, RxEarly,
	 * IntRequested, MacControlFrame, LinkEvent) interrupts
	 * if issued. Also, all IPG interrupts are disabled by
	 * reading IntStatusAck.
	 */
	status = ipg_r16(INT_STATUS_ACK);

	IPG_DEBUG_MSG("IntStatusAck = %4.4x\n", status);

	/* Shared IRQ of remove event. */
	if (!(status & IPG_IS_RSVD_MASK))
		goto out_enable;

	handled = 1;

	if (unlikely(!netif_running(dev)))
		goto out_unlock;

	/* If RFDListEnd interrupt, restore all used RFDs. */
	if (status & IPG_IS_RFD_LIST_END) {
		IPG_DEBUG_MSG("RFDListEnd Interrupt.\n");

		/* The RFD list end indicates an RFD was encountered
		 * with a 0 NextPtr, or with an RFDDone bit set to 1
		 * (indicating the RFD is not read for use by the
		 * IPG.) Try to restore all RFDs.
		 */
		ipg_nic_rxrestore(dev);

#ifdef IPG_DEBUG
		/* Increment the RFDlistendCount counter. */
		sp->RFDlistendCount++;
#endif
	}

	/* If RFDListEnd, RxDMAPriority, RxDMAComplete, or
	 * IntRequested interrupt, process received frames. */
	if ((status & IPG_IS_RX_DMA_PRIORITY) ||
	    (status & IPG_IS_RFD_LIST_END) ||
	    (status & IPG_IS_RX_DMA_COMPLETE) ||
	    (status & IPG_IS_INT_REQUESTED)) {
#ifdef IPG_DEBUG
		/* Increment the RFD list checked counter if interrupted
		 * only to check the RFD list. */
		if (status & (~(IPG_IS_RX_DMA_PRIORITY | IPG_IS_RFD_LIST_END |
				IPG_IS_RX_DMA_COMPLETE | IPG_IS_INT_REQUESTED) &
			       (IPG_IS_HOST_ERROR | IPG_IS_TX_DMA_COMPLETE |
				IPG_IS_LINK_EVENT | IPG_IS_TX_COMPLETE |
				IPG_IS_UPDATE_STATS)))
			sp->RFDListCheckedCount++;
#endif

		if (sp->is_jumbo)
			ipg_nic_rx_jumbo(dev);
		else
			ipg_nic_rx(dev);
	}

	/* If TxDMAComplete interrupt, free used TFDs. */
	if (status & IPG_IS_TX_DMA_COMPLETE)
		ipg_nic_txfree(dev);

	/* TxComplete interrupts indicate one of numerous actions.
	 * Determine what action to take based on TXSTATUS register.
	 */
	if (status & IPG_IS_TX_COMPLETE)
		ipg_nic_txcleanup(dev);

	/* If UpdateStats interrupt, update Linux Ethernet statistics */
	if (status & IPG_IS_UPDATE_STATS)
		ipg_nic_get_stats(dev);

	/* If HostError interrupt, reset IPG. */
	if (status & IPG_IS_HOST_ERROR) {
		IPG_DDEBUG_MSG("HostError Interrupt\n");

		schedule_delayed_work(&sp->task, 0);
	}

	/* If LinkEvent interrupt, resolve autonegotiation. */
	if (status & IPG_IS_LINK_EVENT) {
		if (ipg_config_autoneg(dev) < 0)
			printk(KERN_INFO "%s: Auto-negotiation error.\n",
			       dev->name);
	}

	/* If MACCtrlFrame interrupt, do nothing. */
	if (status & IPG_IS_MAC_CTRL_FRAME)
		IPG_DEBUG_MSG("MACCtrlFrame interrupt.\n");

	/* If RxComplete interrupt, do nothing. */
	if (status & IPG_IS_RX_COMPLETE)
		IPG_DEBUG_MSG("RxComplete interrupt.\n");

	/* If RxEarly interrupt, do nothing. */
	if (status & IPG_IS_RX_EARLY)
		IPG_DEBUG_MSG("RxEarly interrupt.\n");

out_enable:
	/* Re-enable IPG interrupts. */
	ipg_w16(IPG_IE_TX_DMA_COMPLETE | IPG_IE_RX_DMA_COMPLETE |
		IPG_IE_HOST_ERROR | IPG_IE_INT_REQUESTED | IPG_IE_TX_COMPLETE |
		IPG_IE_LINK_EVENT | IPG_IE_UPDATE_STATS, INT_ENABLE);
out_unlock:
	spin_unlock(&sp->lock);

	return IRQ_RETVAL(handled);
}

static void ipg_rx_clear(struct ipg_nic_private *sp)
{
	unsigned int i;

	for (i = 0; i < IPG_RFDLIST_LENGTH; i++) {
		if (sp->rx_buff[i]) {
			struct ipg_rx *rxfd = sp->rxd + i;

			dev_kfree_skb_irq(sp->rx_buff[i]);
			sp->rx_buff[i] = NULL;
			pci_unmap_single(sp->pdev,
				le64_to_cpu(rxfd->frag_info) & ~IPG_RFI_FRAGLEN,
				sp->rx_buf_sz, PCI_DMA_FROMDEVICE);
		}
	}
}

static void ipg_tx_clear(struct ipg_nic_private *sp)
{
	unsigned int i;

	for (i = 0; i < IPG_TFDLIST_LENGTH; i++) {
		if (sp->tx_buff[i]) {
			struct ipg_tx *txfd = sp->txd + i;

			pci_unmap_single(sp->pdev,
				le64_to_cpu(txfd->frag_info) & ~IPG_TFI_FRAGLEN,
				sp->tx_buff[i]->len, PCI_DMA_TODEVICE);

			dev_kfree_skb_irq(sp->tx_buff[i]);

			sp->tx_buff[i] = NULL;
		}
	}
}

static int ipg_nic_open(struct net_device *dev)
{
	struct ipg_nic_private *sp = netdev_priv(dev);
	void __iomem *ioaddr = sp->ioaddr;
	struct pci_dev *pdev = sp->pdev;
	int rc;

	IPG_DEBUG_MSG("_nic_open\n");

	sp->rx_buf_sz = sp->rxsupport_size;

	/* Check for interrupt line conflicts, and request interrupt
	 * line for IPG.
	 *
	 * IMPORTANT: Disable IPG interrupts prior to registering
	 *            IRQ.
	 */
	ipg_w16(0x0000, INT_ENABLE);

	/* Register the interrupt line to be used by the IPG within
	 * the Linux system.
	 */
	rc = request_irq(pdev->irq, ipg_interrupt_handler, IRQF_SHARED,
			 dev->name, dev);
	if (rc < 0) {
		printk(KERN_INFO "%s: Error when requesting interrupt.\n",
		       dev->name);
		goto out;
	}

	dev->irq = pdev->irq;

	rc = -ENOMEM;

	sp->rxd = dma_alloc_coherent(&pdev->dev, IPG_RX_RING_BYTES,
				     &sp->rxd_map, GFP_KERNEL);
	if (!sp->rxd)
		goto err_free_irq_0;

	sp->txd = dma_alloc_coherent(&pdev->dev, IPG_TX_RING_BYTES,
				     &sp->txd_map, GFP_KERNEL);
	if (!sp->txd)
		goto err_free_rx_1;

	rc = init_rfdlist(dev);
	if (rc < 0) {
		printk(KERN_INFO "%s: Error during configuration.\n",
		       dev->name);
		goto err_free_tx_2;
	}

	init_tfdlist(dev);

	rc = ipg_io_config(dev);
	if (rc < 0) {
		printk(KERN_INFO "%s: Error during configuration.\n",
		       dev->name);
		goto err_release_tfdlist_3;
	}

	/* Resolve autonegotiation. */
	if (ipg_config_autoneg(dev) < 0)
		printk(KERN_INFO "%s: Auto-negotiation error.\n", dev->name);

	/* initialize JUMBO Frame control variable */
	sp->jumbo.found_start = 0;
	sp->jumbo.current_size = 0;
	sp->jumbo.skb = NULL;

	/* Enable transmit and receive operation of the IPG. */
	ipg_w32((ipg_r32(MAC_CTRL) | IPG_MC_RX_ENABLE | IPG_MC_TX_ENABLE) &
		 IPG_MC_RSVD_MASK, MAC_CTRL);

	netif_start_queue(dev);
out:
	return rc;

err_release_tfdlist_3:
	ipg_tx_clear(sp);
	ipg_rx_clear(sp);
err_free_tx_2:
	dma_free_coherent(&pdev->dev, IPG_TX_RING_BYTES, sp->txd, sp->txd_map);
err_free_rx_1:
	dma_free_coherent(&pdev->dev, IPG_RX_RING_BYTES, sp->rxd, sp->rxd_map);
err_free_irq_0:
	free_irq(pdev->irq, dev);
	goto out;
}

static int ipg_nic_stop(struct net_device *dev)
{
	struct ipg_nic_private *sp = netdev_priv(dev);
	void __iomem *ioaddr = sp->ioaddr;
	struct pci_dev *pdev = sp->pdev;

	IPG_DEBUG_MSG("_nic_stop\n");

	netif_stop_queue(dev);

	IPG_DUMPTFDLIST(dev);

	do {
		(void) ipg_r16(INT_STATUS_ACK);

		ipg_reset(dev, IPG_AC_GLOBAL_RESET | IPG_AC_HOST | IPG_AC_DMA);

		synchronize_irq(pdev->irq);
	} while (ipg_r16(INT_ENABLE) & IPG_IE_RSVD_MASK);

	ipg_rx_clear(sp);

	ipg_tx_clear(sp);

	pci_free_consistent(pdev, IPG_RX_RING_BYTES, sp->rxd, sp->rxd_map);
	pci_free_consistent(pdev, IPG_TX_RING_BYTES, sp->txd, sp->txd_map);

	free_irq(pdev->irq, dev);

	return 0;
}

static netdev_tx_t ipg_nic_hard_start_xmit(struct sk_buff *skb,
					   struct net_device *dev)
{
	struct ipg_nic_private *sp = netdev_priv(dev);
	void __iomem *ioaddr = sp->ioaddr;
	unsigned int entry = sp->tx_current % IPG_TFDLIST_LENGTH;
	unsigned long flags;
	struct ipg_tx *txfd;

	IPG_DDEBUG_MSG("_nic_hard_start_xmit\n");

	/* If in 10Mbps mode, stop the transmit queue so
	 * no more transmit frames are accepted.
	 */
	if (sp->tenmbpsmode)
		netif_stop_queue(dev);

	if (sp->reset_current_tfd) {
		sp->reset_current_tfd = 0;
		entry = 0;
	}

	txfd = sp->txd + entry;

	sp->tx_buff[entry] = skb;

	/* Clear all TFC fields, except TFDDONE. */
	txfd->tfc = cpu_to_le64(IPG_TFC_TFDDONE);

	/* Specify the TFC field within the TFD. */
	txfd->tfc |= cpu_to_le64(IPG_TFC_WORDALIGNDISABLED |
		(IPG_TFC_FRAMEID & sp->tx_current) |
		(IPG_TFC_FRAGCOUNT & (1 << 24)));
	/*
	 * 16--17 (WordAlign) <- 3 (disable),
	 * 0--15 (FrameId) <- sp->tx_current,
	 * 24--27 (FragCount) <- 1
	 */

	/* Request TxComplete interrupts at an interval defined
	 * by the constant IPG_FRAMESBETWEENTXCOMPLETES.
	 * Request TxComplete interrupt for every frame
	 * if in 10Mbps mode to accomodate problem with 10Mbps
	 * processing.
	 */
	if (sp->tenmbpsmode)
		txfd->tfc |= cpu_to_le64(IPG_TFC_TXINDICATE);
	txfd->tfc |= cpu_to_le64(IPG_TFC_TXDMAINDICATE);
	/* Based on compilation option, determine if FCS is to be
	 * appended to transmit frame by IPG.
	 */
	if (!(IPG_APPEND_FCS_ON_TX))
		txfd->tfc |= cpu_to_le64(IPG_TFC_FCSAPPENDDISABLE);

	/* Based on compilation option, determine if IP, TCP and/or
	 * UDP checksums are to be added to transmit frame by IPG.
	 */
	if (IPG_ADD_IPCHECKSUM_ON_TX)
		txfd->tfc |= cpu_to_le64(IPG_TFC_IPCHECKSUMENABLE);

	if (IPG_ADD_TCPCHECKSUM_ON_TX)
		txfd->tfc |= cpu_to_le64(IPG_TFC_TCPCHECKSUMENABLE);

	if (IPG_ADD_UDPCHECKSUM_ON_TX)
		txfd->tfc |= cpu_to_le64(IPG_TFC_UDPCHECKSUMENABLE);

	/* Based on compilation option, determine if VLAN tag info is to be
	 * inserted into transmit frame by IPG.
	 */
	if (IPG_INSERT_MANUAL_VLAN_TAG) {
		txfd->tfc |= cpu_to_le64(IPG_TFC_VLANTAGINSERT |
			((u64) IPG_MANUAL_VLAN_VID << 32) |
			((u64) IPG_MANUAL_VLAN_CFI << 44) |
			((u64) IPG_MANUAL_VLAN_USERPRIORITY << 45));
	}

	/* The fragment start location within system memory is defined
	 * by the sk_buff structure's data field. The physical address
	 * of this location within the system's virtual memory space
	 * is determined using the IPG_HOST2BUS_MAP function.
	 */
	txfd->frag_info = cpu_to_le64(pci_map_single(sp->pdev, skb->data,
		skb->len, PCI_DMA_TODEVICE));

	/* The length of the fragment within system memory is defined by
	 * the sk_buff structure's len field.
	 */
	txfd->frag_info |= cpu_to_le64(IPG_TFI_FRAGLEN &
		((u64) (skb->len & 0xffff) << 48));

	/* Clear the TFDDone bit last to indicate the TFD is ready
	 * for transfer to the IPG.
	 */
	txfd->tfc &= cpu_to_le64(~IPG_TFC_TFDDONE);

	spin_lock_irqsave(&sp->lock, flags);

	sp->tx_current++;

	mmiowb();

	ipg_w32(IPG_DC_TX_DMA_POLL_NOW, DMA_CTRL);

	if (sp->tx_current == (sp->tx_dirty + IPG_TFDLIST_LENGTH))
		netif_stop_queue(dev);

	spin_unlock_irqrestore(&sp->lock, flags);

	return NETDEV_TX_OK;
}

static void ipg_set_phy_default_param(unsigned char rev,
				      struct net_device *dev, int phy_address)
{
	unsigned short length;
	unsigned char revision;
	unsigned short *phy_param;
	unsigned short address, value;

	phy_param = &DefaultPhyParam[0];
	length = *phy_param & 0x00FF;
	revision = (unsigned char)((*phy_param) >> 8);
	phy_param++;
	while (length != 0) {
		if (rev == revision) {
			while (length > 1) {
				address = *phy_param;
				value = *(phy_param + 1);
				phy_param += 2;
				mdio_write(dev, phy_address, address, value);
				length -= 4;
			}
			break;
		} else {
			phy_param += length / 2;
			length = *phy_param & 0x00FF;
			revision = (unsigned char)((*phy_param) >> 8);
			phy_param++;
		}
	}
}

static int read_eeprom(struct net_device *dev, int eep_addr)
{
	void __iomem *ioaddr = ipg_ioaddr(dev);
	unsigned int i;
	int ret = 0;
	u16 value;

	value = IPG_EC_EEPROM_READOPCODE | (eep_addr & 0xff);
	ipg_w16(value, EEPROM_CTRL);

	for (i = 0; i < 1000; i++) {
		u16 data;

		mdelay(10);
		data = ipg_r16(EEPROM_CTRL);
		if (!(data & IPG_EC_EEPROM_BUSY)) {
			ret = ipg_r16(EEPROM_DATA);
			break;
		}
	}
	return ret;
}

static void ipg_init_mii(struct net_device *dev)
{
	struct ipg_nic_private *sp = netdev_priv(dev);
	struct mii_if_info *mii_if = &sp->mii_if;
	int phyaddr;

	mii_if->dev          = dev;
	mii_if->mdio_read    = mdio_read;
	mii_if->mdio_write   = mdio_write;
	mii_if->phy_id_mask  = 0x1f;
	mii_if->reg_num_mask = 0x1f;

	mii_if->phy_id = phyaddr = ipg_find_phyaddr(dev);

	if (phyaddr != 0x1f) {
		u16 mii_phyctrl, mii_1000cr;
		u8 revisionid = 0;

		mii_1000cr  = mdio_read(dev, phyaddr, MII_CTRL1000);
		mii_1000cr |= ADVERTISE_1000FULL | ADVERTISE_1000HALF |
			GMII_PHY_1000BASETCONTROL_PreferMaster;
		mdio_write(dev, phyaddr, MII_CTRL1000, mii_1000cr);

		mii_phyctrl = mdio_read(dev, phyaddr, MII_BMCR);

		/* Set default phyparam */
		pci_read_config_byte(sp->pdev, PCI_REVISION_ID, &revisionid);
		ipg_set_phy_default_param(revisionid, dev, phyaddr);

		/* Reset PHY */
		mii_phyctrl |= BMCR_RESET | BMCR_ANRESTART;
		mdio_write(dev, phyaddr, MII_BMCR, mii_phyctrl);

	}
}

static int ipg_hw_init(struct net_device *dev)
{
	struct ipg_nic_private *sp = netdev_priv(dev);
	void __iomem *ioaddr = sp->ioaddr;
	unsigned int i;
	int rc;

	/* Read/Write and Reset EEPROM Value */
	/* Read LED Mode Configuration from EEPROM */
	sp->led_mode = read_eeprom(dev, 6);

	/* Reset all functions within the IPG. Do not assert
	 * RST_OUT as not compatible with some PHYs.
	 */
	rc = ipg_reset(dev, IPG_RESET_MASK);
	if (rc < 0)
		goto out;

	ipg_init_mii(dev);

	/* Read MAC Address from EEPROM */
	for (i = 0; i < 3; i++)
		sp->station_addr[i] = read_eeprom(dev, 16 + i);

	for (i = 0; i < 3; i++)
		ipg_w16(sp->station_addr[i], STATION_ADDRESS_0 + 2*i);

	/* Set station address in ethernet_device structure. */
	dev->dev_addr[0] =  ipg_r16(STATION_ADDRESS_0) & 0x00ff;
	dev->dev_addr[1] = (ipg_r16(STATION_ADDRESS_0) & 0xff00) >> 8;
	dev->dev_addr[2] =  ipg_r16(STATION_ADDRESS_1) & 0x00ff;
	dev->dev_addr[3] = (ipg_r16(STATION_ADDRESS_1) & 0xff00) >> 8;
	dev->dev_addr[4] =  ipg_r16(STATION_ADDRESS_2) & 0x00ff;
	dev->dev_addr[5] = (ipg_r16(STATION_ADDRESS_2) & 0xff00) >> 8;
out:
	return rc;
}

static int ipg_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
{
	struct ipg_nic_private *sp = netdev_priv(dev);
	int rc;

	mutex_lock(&sp->mii_mutex);
	rc = generic_mii_ioctl(&sp->mii_if, if_mii(ifr), cmd, NULL);
	mutex_unlock(&sp->mii_mutex);

	return rc;
}

static int ipg_nic_change_mtu(struct net_device *dev, int new_mtu)
{
	struct ipg_nic_private *sp = netdev_priv(dev);
	int err;

	/* Function to accomodate changes to Maximum Transfer Unit
	 * (or MTU) of IPG NIC. Cannot use default function since
	 * the default will not allow for MTU > 1500 bytes.
	 */

	IPG_DEBUG_MSG("_nic_change_mtu\n");

	/*
	 * Check that the new MTU value is between 68 (14 byte header, 46 byte
	 * payload, 4 byte FCS) and 10 KB, which is the largest supported MTU.
	 */
	if (new_mtu < 68 || new_mtu > 10240)
		return -EINVAL;

	err = ipg_nic_stop(dev);
	if (err)
		return err;

	dev->mtu = new_mtu;

	sp->max_rxframe_size = new_mtu;

	sp->rxfrag_size = new_mtu;
	if (sp->rxfrag_size > 4088)
		sp->rxfrag_size = 4088;

	sp->rxsupport_size = sp->max_rxframe_size;

	if (new_mtu > 0x0600)
		sp->is_jumbo = true;
	else
		sp->is_jumbo = false;

	return ipg_nic_open(dev);
}

static int ipg_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
{
	struct ipg_nic_private *sp = netdev_priv(dev);
	int rc;

	mutex_lock(&sp->mii_mutex);
	rc = mii_ethtool_gset(&sp->mii_if, cmd);
	mutex_unlock(&sp->mii_mutex);

	return rc;
}

static int ipg_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
{
	struct ipg_nic_private *sp = netdev_priv(dev);
	int rc;

	mutex_lock(&sp->mii_mutex);
	rc = mii_ethtool_sset(&sp->mii_if, cmd);
	mutex_unlock(&sp->mii_mutex);

	return rc;
}

static int ipg_nway_reset(struct net_device *dev)
{
	struct ipg_nic_private *sp = netdev_priv(dev);
	int rc;

	mutex_lock(&sp->mii_mutex);
	rc = mii_nway_restart(&sp->mii_if);
	mutex_unlock(&sp->mii_mutex);

	return rc;
}

static const struct ethtool_ops ipg_ethtool_ops = {
	.get_settings = ipg_get_settings,
	.set_settings = ipg_set_settings,
	.nway_reset   = ipg_nway_reset,
};

static void __devexit ipg_remove(struct pci_dev *pdev)
{
	struct net_device *dev = pci_get_drvdata(pdev);
	struct ipg_nic_private *sp = netdev_priv(dev);

	IPG_DEBUG_MSG("_remove\n");

	/* Un-register Ethernet device. */
	unregister_netdev(dev);

	pci_iounmap(pdev, sp->ioaddr);

	pci_release_regions(pdev);

	free_netdev(dev);
	pci_disable_device(pdev);
	pci_set_drvdata(pdev, NULL);
}

static const struct net_device_ops ipg_netdev_ops = {
	.ndo_open		= ipg_nic_open,
	.ndo_stop		= ipg_nic_stop,
	.ndo_start_xmit		= ipg_nic_hard_start_xmit,
	.ndo_get_stats		= ipg_nic_get_stats,
	.ndo_set_multicast_list = ipg_nic_set_multicast_list,
	.ndo_do_ioctl		= ipg_ioctl,
	.ndo_tx_timeout 	= ipg_tx_timeout,
	.ndo_change_mtu 	= ipg_nic_change_mtu,
	.ndo_set_mac_address	= eth_mac_addr,
	.ndo_validate_addr	= eth_validate_addr,
};

static int __devinit ipg_probe(struct pci_dev *pdev,
			       const struct pci_device_id *id)
{
	unsigned int i = id->driver_data;
	struct ipg_nic_private *sp;
	struct net_device *dev;
	void __iomem *ioaddr;
	int rc;

	rc = pci_enable_device(pdev);
	if (rc < 0)
		goto out;

	printk(KERN_INFO "%s: %s\n", pci_name(pdev), ipg_brand_name[i]);

	pci_set_master(pdev);

	rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(40));
	if (rc < 0) {
		rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
		if (rc < 0) {
			printk(KERN_ERR "%s: DMA config failed.\n",
			       pci_name(pdev));
			goto err_disable_0;
		}
	}

	/*
	 * Initialize net device.
	 */
	dev = alloc_etherdev(sizeof(struct ipg_nic_private));
	if (!dev) {
		printk(KERN_ERR "%s: alloc_etherdev failed\n", pci_name(pdev));
		rc = -ENOMEM;
		goto err_disable_0;
	}

	sp = netdev_priv(dev);
	spin_lock_init(&sp->lock);
	mutex_init(&sp->mii_mutex);

	sp->is_jumbo = IPG_IS_JUMBO;
	sp->rxfrag_size = IPG_RXFRAG_SIZE;
	sp->rxsupport_size = IPG_RXSUPPORT_SIZE;
	sp->max_rxframe_size = IPG_MAX_RXFRAME_SIZE;

	/* Declare IPG NIC functions for Ethernet device methods.
	 */
	dev->netdev_ops = &ipg_netdev_ops;
	SET_NETDEV_DEV(dev, &pdev->dev);
	SET_ETHTOOL_OPS(dev, &ipg_ethtool_ops);

	rc = pci_request_regions(pdev, DRV_NAME);
	if (rc)
		goto err_free_dev_1;

	ioaddr = pci_iomap(pdev, 1, pci_resource_len(pdev, 1));
	if (!ioaddr) {
		printk(KERN_ERR "%s cannot map MMIO\n", pci_name(pdev));
		rc = -EIO;
		goto err_release_regions_2;
	}

	/* Save the pointer to the PCI device information. */
	sp->ioaddr = ioaddr;
	sp->pdev = pdev;
	sp->dev = dev;

	INIT_DELAYED_WORK(&sp->task, ipg_reset_after_host_error);

	pci_set_drvdata(pdev, dev);

	rc = ipg_hw_init(dev);
	if (rc < 0)
		goto err_unmap_3;

	rc = register_netdev(dev);
	if (rc < 0)
		goto err_unmap_3;

	printk(KERN_INFO "Ethernet device registered as: %s\n", dev->name);
out:
	return rc;

err_unmap_3:
	pci_iounmap(pdev, ioaddr);
err_release_regions_2:
	pci_release_regions(pdev);
err_free_dev_1:
	free_netdev(dev);
err_disable_0:
	pci_disable_device(pdev);
	goto out;
}

static struct pci_driver ipg_pci_driver = {
	.name		= IPG_DRIVER_NAME,
	.id_table	= ipg_pci_tbl,
	.probe		= ipg_probe,
	.remove		= __devexit_p(ipg_remove),
};

static int __init ipg_init_module(void)
{
	return pci_register_driver(&ipg_pci_driver);
}

static void __exit ipg_exit_module(void)
{
	pci_unregister_driver(&ipg_pci_driver);
}

module_init(ipg_init_module);
module_exit(ipg_exit_module);
