[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#366455: marked as done (linux-source-2.6.16: Please add support to IC Plus IP100A Fast Ethernet Adapter [patch])



Your message dated Tue, 31 Jul 2007 12:51:40 +0200
with message-id <20070731105140.GJ18968@stro.at>
and subject line linux-source-2.6.16: Please add support to IC Plus IP100A Fast Ethernet Adapter [patch]
has caused the attached Bug report to be marked as done.

This means that you claim that the problem has been dealt with.
If this is not the case it is now your responsibility to reopen the
Bug report if necessary, and/or fix the problem forthwith.

(NB: If you are a system administrator and have no idea what I am
talking about this indicates a serious mail system misconfiguration
somewhere.  Please contact me immediately.)

Debian bug tracking system administrator
(administrator, Debian Bugs database)

--- Begin Message ---
Package: linux-source-2.6.16
Version: 2.6.16-12
Severity: normal
Tags: patch


The new driver downloaded from http://www.icplus.com.tw/Data/driver/IP100A%20for%20Linux%20driver%20v1.20a.zip

sarge:~# lspci --version
lspci version 2.1.11
sarge:~# lspci -v
...
0000:00:0d.0 Ethernet controller: Sundance Technology Inc: Unknown device 0200 (rev 31)
        Subsystem: Sundance Technology Inc: Unknown device 0201
        Flags: bus master, medium devsel, latency 32, IRQ 11
        I/O ports at 9400 [size=128]
        Memory at cd000000 (32-bit, non-prefetchable) [size=512]
        Expansion ROM at 20020000 [disabled] [size=64K]
        Capabilities: [50] Power Management version 2

...


--- sundance.c.dpkg-dist	2006-05-08 17:26:02.000000000 -0300
+++ sundance.c	2006-05-08 17:26:42.000000000 -0300
@@ -71,34 +71,57 @@
 
 	Versin LK1.06b (D-Link):
 	- New tx scheme, adaptive tx_coalesce
-	
+
 	Version LK1.07 (D-Link):
 	- Fix tx bugs in big-endian machines
-	- Remove unused max_interrupt_work module parameter, the new 
+	- Remove unused max_interrupt_work module parameter, the new
 	  NAPI-like rx scheme doesn't need it.
-	- Remove redundancy get_stats() in intr_handler(), those 
+	- Remove redundancy get_stats() in intr_handler(), those
 	  I/O access could affect performance in ARM-based system
 	- Add Linux software VLAN support
-	
-	Version LK1.08 (Philippe De Muyter phdm@macqel.be):
-	- Fix bug of custom mac address 
-	(StationAddr register only accept word write) 
+
+	Version LK1.08 (D-Link):
+	- Fix bug of custom mac address
+	(StationAddr register only accept word write)
 
 	Version LK1.09 (D-Link):
-	- Fix the flowctrl bug.	
-	- Set Pause bit in MII ANAR if flow control enabled.	
+	- Fix the flowctrl bug.
+	- Set Pause bit in MII ANAR if flow control enabled.
 
-	Version LK1.09a (ICPlus):
-	- Add the delay time in reading the contents of EEPROM
+	Version LK1.10 (D-Link):
+	- Fix tx timeout when MaxCollions error.
 
-	Version LK1.10 (Philippe De Muyter phdm@macqel.be):
-	- Make 'unblock interface after Tx underrun' work
+	Version LK1.11 (IC Plus) <Jesse Huang>
+	- Start phy id scan at id 0.
 
+	Version LK1.12 (IC Plus):
+	- Change Vendor from Sundance to IC Plus
+	- Change MODULE_DESCRIPTION to "IC Plus Fast Ethernet Driver"
+	- Add Device ID 0200
+
+	Version LK1.13 (IC Plus)
+	- Update Global reset
+	
+	Version LK1.14 (IC Plus) <Jesse Huang>
+	-Fix parameter "media" for change speed function. //20040817Jesse_ChangeSpeed
+	
+	Version LK1.15 (IC Plus) <Jesse Huang>
+	-Mask memory base address and IO base address bit 0 to 6.//20040826Jesse_mask_BaseAddr
+	
+	Version LK1.16 (IC Plus) <Jesse Huang>
+	-Support for kernel 2.6.x
+	
+	Version LK1.17b (IC Plus) <Jesse Huang>
+	- Modify function form pci_dma_sync_single() to pci_dma_sync_single_for_cpu()
+	- (Thanks for Moz Lala's support)
+	
+	Version LK1.19 (IC Plus) <Jesse Huang>
+	- After 2.6.11, changed slot_name to pci_name().
 */
 
 #define DRV_NAME	"sundance"
-#define DRV_VERSION	"1.01+LK1.10"
-#define DRV_RELDATE	"28-Oct-2005"
+#define DRV_VERSION	"1.01+LK1.20"
+#define DRV_RELDATE	"12-09-2005"
 
 
 /* The user-configurable values.
@@ -151,6 +174,15 @@
 #define TX_TIMEOUT  (4*HZ)
 #define PKT_BUF_SZ		1536	/* Size of each temporary Rx buffer.*/
 
+#ifndef __KERNEL__
+#define __KERNEL__
+#endif
+#if !defined(__OPTIMIZE__)
+#warning  You must compile this file with the correct options!
+#warning  See the last lines of the source file.
+#error You must compile this driver with "-O".
+#endif
+
 /* Include files, designed to support most kernel versions 2.0.0 and later. */
 #include <linux/module.h>
 #include <linux/kernel.h>
@@ -165,9 +197,10 @@
 #include <linux/etherdevice.h>
 #include <linux/skbuff.h>
 #include <linux/init.h>
-#include <linux/bitops.h>
+#include <linux/version.h>
 #include <asm/uaccess.h>
 #include <asm/processor.h>		/* Processor type for cache alignment. */
+#include <asm/bitops.h>
 #include <asm/io.h>
 #include <linux/delay.h>
 #include <linux/spinlock.h>
@@ -188,13 +221,14 @@
 KERN_INFO "  http://www.scyld.com/network/sundance.html\n";;
 
 MODULE_AUTHOR("Donald Becker <becker@scyld.com>");
-MODULE_DESCRIPTION("Sundance Alta Ethernet driver");
+// 04/13/2004 MODULE_DESCRIPTION("Sundance Alta Ethernet driver");
+MODULE_DESCRIPTION("IC Plus Fast Ethernet driver");
 MODULE_LICENSE("GPL");
 
-module_param(debug, int, 0);
-module_param(rx_copybreak, int, 0);
-module_param_array(media, charp, NULL, 0);
-module_param(flowctrl, int, 0);
+MODULE_PARM(debug, "i");
+MODULE_PARM(rx_copybreak, "i");
+MODULE_PARM(media, "1-" __MODULE_STRING(MAX_UNITS) "s");
+MODULE_PARM(flowctrl, "i");
 MODULE_PARM_DESC(debug, "Sundance Alta debug level (0-5)");
 MODULE_PARM_DESC(rx_copybreak, "Sundance Alta copy breakpoint for copy-only-tiny-frames");
 MODULE_PARM_DESC(flowctrl, "Sundance Alta flow control [0|1]");
@@ -266,10 +300,8 @@
 IVb. References
 
 The Sundance ST201 datasheet, preliminary version.
-The Kendin KS8723 datasheet, preliminary version.
-The ICplus IP100 datasheet, preliminary version.
-http://www.scyld.com/expert/100mbps.html
-http://www.scyld.com/expert/NWay.html
+http://cesdis.gsfc.nasa.gov/linux/misc/100mbps.html
+http://cesdis.gsfc.nasa.gov/linux/misc/NWay.html
 
 IVc. Errata
 
@@ -280,13 +312,14 @@
 #define USE_IO_OPS 1
 #endif
 
-static struct pci_device_id sundance_pci_tbl[] = {
+static struct pci_device_id sundance_pci_tbl[] __devinitdata = {
 	{0x1186, 0x1002, 0x1186, 0x1002, 0, 0, 0},
 	{0x1186, 0x1002, 0x1186, 0x1003, 0, 0, 1},
 	{0x1186, 0x1002, 0x1186, 0x1012, 0, 0, 2},
 	{0x1186, 0x1002, 0x1186, 0x1040, 0, 0, 3},
 	{0x1186, 0x1002, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4},
 	{0x13F0, 0x0201, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 5},
+	{0x13F0, 0x0200, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 6},
 	{0,}
 };
 MODULE_DEVICE_TABLE(pci, sundance_pci_tbl);
@@ -304,12 +337,28 @@
 	{"D-Link DFE-580TX 4 port Server Adapter"},
 	{"D-Link DFE-530TXS FAST Ethernet Adapter"},
 	{"D-Link DL10050-based FAST Ethernet Adapter"},
-	{"Sundance Technology Alta"},
-	{NULL,},			/* 0 terminated list. */
+// 04/13/2004 	{"Sundance Technology Alta"},
+    {"IC Plus IP100 Fast Ethernet Adapter"},
+    {"IC Plus IP100A Fast Ethernet Adapter" },
+	{0,},			/* 0 terminated list. */
 };
 
 /* This driver was written to use PCI memory space, however x86-oriented
    hardware often uses I/O space accesses. */
+#ifdef USE_IO_OPS
+#undef readb
+#undef readw
+#undef readl
+#undef writeb
+#undef writew
+#undef writel
+#define readb inb
+#define readw inw
+#define readl inl
+#define writeb outb
+#define writew outw
+#define writel outl
+#endif
 
 /* Offsets to the device registers.
    Unlike software-only systems, device drivers interact with complex hardware.
@@ -471,7 +520,6 @@
 	int mii_preamble_required;
 	unsigned char phys[MII_CNT];		/* MII device addresses, only first one used. */
 	struct pci_dev *pci_dev;
-	void __iomem *base;
 	unsigned char pci_rev_id;
 };
 
@@ -482,7 +530,7 @@
 			LinkChange)
 
 static int  change_mtu(struct net_device *dev, int new_mtu);
-static int  eeprom_read(void __iomem *ioaddr, int location);
+static int  eeprom_read(long ioaddr, int location);
 static int  mdio_read(struct net_device *dev, int phy_id, int location);
 static void mdio_write(struct net_device *dev, int phy_id, int location, int value);
 static int  netdev_open(struct net_device *dev);
@@ -492,7 +540,11 @@
 static void init_ring(struct net_device *dev);
 static int  start_tx(struct sk_buff *skb, struct net_device *dev);
 static int reset_tx (struct net_device *dev);
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) 
+static void intr_handler(int irq, void *dev_instance, struct pt_regs *regs);
+#else
 static irqreturn_t intr_handler(int irq, void *dev_instance, struct pt_regs *regs);
+#endif
 static void rx_poll(unsigned long data);
 static void tx_poll(unsigned long data);
 static void refill_rx (struct net_device *dev);
@@ -503,26 +555,8 @@
 static struct net_device_stats *get_stats(struct net_device *dev);
 static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
 static int  netdev_close(struct net_device *dev);
-static struct ethtool_ops ethtool_ops;
 
-static void sundance_reset(struct net_device *dev, unsigned long reset_cmd)
-{
-	struct netdev_private *np = netdev_priv(dev);
-	void __iomem *ioaddr = np->base + ASICCtrl;
-	int countdown;
-
-	/* ST201 documentation states ASICCtrl is a 32bit register */
-	iowrite32 (reset_cmd | ioread32 (ioaddr), ioaddr);
-	/* ST201 documentation states reset can take up to 1 ms */
-	countdown = 10 + 1;
-	while (ioread32 (ioaddr) & (ResetBusy << 16)) {
-		if (--countdown == 0) {
-			printk(KERN_WARNING "%s : reset not completed !!\n", dev->name);
-			break;
-		}
-		udelay(100);
-	}
-}
+
 
 static int __devinit sundance_probe1 (struct pci_dev *pdev,
 				      const struct pci_device_id *ent)
@@ -533,16 +567,10 @@
 	int chip_idx = ent->driver_data;
 	int irq;
 	int i;
-	void __iomem *ioaddr;
-	u16 mii_ctl;
+	long ioaddr;
+	u16 mii_ctl,mii_avt;
 	void *ring_space;
 	dma_addr_t ring_dma;
-#ifdef USE_IO_OPS
-	int bar = 0;
-#else
-	int bar = 1;
-#endif
-	int phy, phy_idx = 0;
 
 
 /* when built into the kernel, we only print version if device is found */
@@ -562,25 +590,27 @@
 	if (!dev)
 		return -ENOMEM;
 	SET_MODULE_OWNER(dev);
-	SET_NETDEV_DEV(dev, &pdev->dev);
 
 	if (pci_request_regions(pdev, DRV_NAME))
 		goto err_out_netdev;
 
-	ioaddr = pci_iomap(pdev, bar, netdev_io_size);
+#ifdef USE_IO_OPS
+	ioaddr = pci_resource_start(pdev, 0)&0xffffff80;////20040826Jesse_mask_BaseAddr:Mask IOBaseAddr[bit0~6]
+#else
+	ioaddr = pci_resource_start(pdev, 1)&0xffffff80;//20040826Jesse_mask_BaseAddr:Mask MemBaseAddr[bit0~6]
+	ioaddr = (long) ioremap (ioaddr, netdev_io_size);
 	if (!ioaddr)
 		goto err_out_res;
+#endif
 
 	for (i = 0; i < 3; i++)
 		((u16 *)dev->dev_addr)[i] =
 			le16_to_cpu(eeprom_read(ioaddr, i + EEPROM_SA_OFFSET));
-	memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
 
-	dev->base_addr = (unsigned long)ioaddr;
+	dev->base_addr = ioaddr;
 	dev->irq = irq;
 
-	np = netdev_priv(dev);
-	np->base = ioaddr;
+	np = dev->priv;
 	np->pci_dev = pdev;
 	np->chip_id = chip_idx;
 	np->msg_enable = (1 << debug) - 1;
@@ -613,7 +643,6 @@
 	dev->get_stats = &get_stats;
 	dev->set_multicast_list = &set_rx_mode;
 	dev->do_ioctl = &netdev_ioctl;
-	SET_ETHTOOL_OPS(dev, &ethtool_ops);
 	dev->tx_timeout = &tx_timeout;
 	dev->watchdog_timeo = TX_TIMEOUT;
 	dev->change_mtu = &change_mtu;
@@ -625,36 +654,39 @@
 	if (i)
 		goto err_out_unmap_rx;
 
-	printk(KERN_INFO "%s: %s at %p, ",
+	printk(KERN_INFO "%s: %s at 0x%lx, ",
 		   dev->name, pci_id_tbl[chip_idx].name, ioaddr);
 	for (i = 0; i < 5; i++)
 			printk("%2.2x:", dev->dev_addr[i]);
 	printk("%2.2x, IRQ %d.\n", dev->dev_addr[i], irq);
 
-	np->phys[0] = 1;		/* Default setting */
-	np->mii_preamble_required++;
-	for (phy = 1; phy <= 32 && phy_idx < MII_CNT; phy++) {
-		int mii_status = mdio_read(dev, phy, MII_BMSR);
-		int phyx = phy & 0x1f;
-		if (mii_status != 0xffff  &&  mii_status != 0x0000) {
-			np->phys[phy_idx++] = phyx;
-			np->mii_if.advertising = mdio_read(dev, phyx, MII_ADVERTISE);
-			if ((mii_status & 0x0040) == 0)
-				np->mii_preamble_required++;
-			printk(KERN_INFO "%s: MII PHY found at address %d, status "
-				   "0x%4.4x advertising %4.4x.\n",
-				   dev->name, phyx, mii_status, np->mii_if.advertising);
-		}
-	}
-	np->mii_preamble_required--;
-
-	if (phy_idx == 0) {
-		printk(KERN_INFO "%s: No MII transceiver found, aborting.  ASIC status %x\n",
-			   dev->name, ioread32(ioaddr + ASICCtrl));
-		goto err_out_unregister;
-	}
+	if (1) {
+		int phy, phy_idx = 0;
+		np->phys[0] = 1;		/* Default setting */
+		np->mii_preamble_required++;
+		//for (phy = 1; phy < 32 && phy_idx < MII_CNT; phy++) {//Modify by Jesse
+		for (phy = 0; phy < 32 && phy_idx < MII_CNT; phy++) {
+			int mii_status = mdio_read(dev, phy, MII_BMSR);
+			if (mii_status != 0xffff  &&  mii_status != 0x0000) {
+				np->phys[phy_idx++] = phy;
+				np->mii_if.advertising = mdio_read(dev, phy, MII_ADVERTISE);
+				if ((mii_status & 0x0040) == 0)
+					np->mii_preamble_required++;
+				printk(KERN_INFO "%s: MII PHY found at address %d, status "
+					   "0x%4.4x advertising %4.4x.\n",
+					   dev->name, phy, mii_status, np->mii_if.advertising);
+			}
+		}
+		np->mii_preamble_required--;
+
+		if (phy_idx == 0) {
+			printk(KERN_INFO "%s: No MII transceiver found, aborting.  ASIC status %x\n",
+				   dev->name, readl(ioaddr + ASICCtrl));
+			goto err_out_unregister;
+		}
 
-	np->mii_if.phy_id = np->phys[0];
+		np->mii_if.phy_id = np->phys[0];
+	}
 
 	/* Parse override configuration */
 	np->an_enable = 1;
@@ -686,7 +718,7 @@
 	}
 
 	/* Fibre PHY? */
-	if (ioread32 (ioaddr + ASICCtrl) & 0x80) {
+	if (readl (ioaddr + ASICCtrl) & 0x80) {
 		/* Default 100Mbps Full */
 		if (np->an_enable) {
 			np->speed = 100;
@@ -700,25 +732,52 @@
 	/* If flow control enabled, we need to advertise it.*/
 	if (np->flowctrl)
 		mdio_write (dev, np->phys[0], MII_ADVERTISE, np->mii_if.advertising | 0x0400);
-	mdio_write (dev, np->phys[0], MII_BMCR, BMCR_ANENABLE|BMCR_ANRESTART);
+	//mdio_write (dev, np->phys[0], MII_BMCR, BMCR_ANENABLE|BMCR_ANRESTART);//20040817Jesse_ChangeSpeed: Remove
 	/* Force media type */
 	if (!np->an_enable) {
-		mii_ctl = 0;
+		//20040817Jesse_ChangeSpeed:remove
+/*		mii_ctl = 0;
 		mii_ctl |= (np->speed == 100) ? BMCR_SPEED100 : 0;
 		mii_ctl |= (np->mii_if.full_duplex) ? BMCR_FULLDPLX : 0;
 		mdio_write (dev, np->phys[0], MII_BMCR, mii_ctl);
 		printk (KERN_INFO "Override speed=%d, %s duplex\n",
-			np->speed, np->mii_if.full_duplex ? "Full" : "Half");
-
-	}
-
+			np->speed, np->mii_if.full_duplex ? "Full" : "Half");*/
+                
+      //20040817Jesse_ChangeSpeed:Add
+		mii_ctl=(mdio_read(dev,np->phys[0],MII_BMCR)&0x0000ffff);
+      mii_avt=(mdio_read(dev,np->phys[0],MII_ADVERTISE)&~(ADVERTISE_100FULL+ADVERTISE_100HALF+ADVERTISE_10FULL+ADVERTISE_10HALF));
+      if(np->speed==100)
+		{
+		   mii_avt|=(np->mii_if.full_duplex)?ADVERTISE_100FULL:ADVERTISE_100HALF;
+		}
+		else
+		{
+		   mii_avt|=(np->mii_if.full_duplex)?ADVERTISE_10FULL:ADVERTISE_10HALF;
+		}
+                mdio_write(dev,np->phys[0],MII_ADVERTISE,mii_avt);
+                mdio_write(dev,np->phys[0],MII_BMCR,mii_ctl|0x1000|0x200);
+	}
+	else
+   {
+	mdio_write (dev, np->phys[0], MII_BMCR, BMCR_ANENABLE|BMCR_ANRESTART);//20040817Jesse_ChangeSpeed: move to here
+   }
+   //20040817Jesse_ChangeSpeed: Add
+   for(i=1000;i;i--)
+	{
+	   mdelay(1);
+      if(mdio_read(dev,np->phys[0],MII_BMSR)&0x20)break;
+   }
+   
 	/* Perhaps move the reset here? */
 	/* Reset the chip to erase previous misconfiguration. */
 	if (netif_msg_hw(np))
-		printk("ASIC Control is %x.\n", ioread32(ioaddr + ASICCtrl));
-	iowrite16(0x00ff, ioaddr + ASICCtrl + 2);
+		printk("ASIC Control is %x.\n", readl(ioaddr + ASICCtrl));
+
+	// 07/24/2004 Grace set AUTOINIT
+	//writew(0x007f, ioaddr + ASICCtrl + 2);
+	writew(0x00ff, ioaddr + ASICCtrl + 2);
 	if (netif_msg_hw(np))
-		printk("ASIC Control is now %x.\n", ioread32(ioaddr + ASICCtrl));
+		printk("ASIC Control is now %x.\n", readl(ioaddr + ASICCtrl));
 
 	card_idx++;
 	return 0;
@@ -731,11 +790,13 @@
         pci_free_consistent(pdev, TX_TOTAL_SIZE, np->tx_ring, np->tx_ring_dma);
 err_out_cleardev:
 	pci_set_drvdata(pdev, NULL);
-	pci_iounmap(pdev, ioaddr);
+#ifndef USE_IO_OPS
+	iounmap((void *)ioaddr);
 err_out_res:
+#endif
 	pci_release_regions(pdev);
 err_out_netdev:
-	free_netdev (dev);
+	kfree (dev);
 	return -ENODEV;
 }
 
@@ -749,16 +810,14 @@
 	return 0;
 }
 
-#define eeprom_delay(ee_addr)	ioread32(ee_addr)
 /* Read the EEPROM and MII Management Data I/O (MDIO) interfaces. */
-static int __devinit eeprom_read(void __iomem *ioaddr, int location)
+static int __devinit eeprom_read(long ioaddr, int location)
 {
-	int boguscnt = 10000;		/* Typical 1900 ticks. */
-	iowrite16(0x0200 | (location & 0xff), ioaddr + EECtrl);
+	int boguscnt = 1000;		/* Typical 190 ticks. */
+	writew(0x0200 | (location & 0xff), ioaddr + EECtrl);
 	do {
-		eeprom_delay(ioaddr + EECtrl);
-		if (! (ioread16(ioaddr + EECtrl) & 0x8000)) {
-			return ioread16(ioaddr + EEData);
+		if (! (readw(ioaddr + EECtrl) & 0x8000)) {
+			return readw(ioaddr + EEData);
 		}
 	} while (--boguscnt > 0);
 	return 0;
@@ -771,7 +830,7 @@
 
 	The maximum data clock rate is 2.5 Mhz.  The minimum timing is usually
 	met by back-to-back 33Mhz PCI cycles. */
-#define mdio_delay() ioread8(mdio_addr)
+#define mdio_delay() readb(mdio_addr)
 
 enum mii_reg_bits {
 	MDIO_ShiftClk=0x0001, MDIO_Data=0x0002, MDIO_EnbOutput=0x0004,
@@ -782,23 +841,23 @@
 
 /* Generate the preamble required for initial synchronization and
    a few older transceivers. */
-static void mdio_sync(void __iomem *mdio_addr)
+static void mdio_sync(long mdio_addr)
 {
 	int bits = 32;
 
 	/* Establish sync by sending at least 32 logic ones. */
 	while (--bits >= 0) {
-		iowrite8(MDIO_WRITE1, mdio_addr);
+		writeb(MDIO_WRITE1, mdio_addr);
 		mdio_delay();
-		iowrite8(MDIO_WRITE1 | MDIO_ShiftClk, mdio_addr);
+		writeb(MDIO_WRITE1 | MDIO_ShiftClk, mdio_addr);
 		mdio_delay();
 	}
 }
 
 static int mdio_read(struct net_device *dev, int phy_id, int location)
 {
-	struct netdev_private *np = netdev_priv(dev);
-	void __iomem *mdio_addr = np->base + MIICtrl;
+	struct netdev_private *np = dev->priv;
+	long mdio_addr = dev->base_addr + MIICtrl;
 	int mii_cmd = (0xf6 << 10) | (phy_id << 5) | location;
 	int i, retval = 0;
 
@@ -809,17 +868,17 @@
 	for (i = 15; i >= 0; i--) {
 		int dataval = (mii_cmd & (1 << i)) ? MDIO_WRITE1 : MDIO_WRITE0;
 
-		iowrite8(dataval, mdio_addr);
+		writeb(dataval, mdio_addr);
 		mdio_delay();
-		iowrite8(dataval | MDIO_ShiftClk, mdio_addr);
+		writeb(dataval | MDIO_ShiftClk, mdio_addr);
 		mdio_delay();
 	}
 	/* Read the two transition, 16 data, and wire-idle bits. */
 	for (i = 19; i > 0; i--) {
-		iowrite8(MDIO_EnbIn, mdio_addr);
+		writeb(MDIO_EnbIn, mdio_addr);
 		mdio_delay();
-		retval = (retval << 1) | ((ioread8(mdio_addr) & MDIO_Data) ? 1 : 0);
-		iowrite8(MDIO_EnbIn | MDIO_ShiftClk, mdio_addr);
+		retval = (retval << 1) | ((readb(mdio_addr) & MDIO_Data) ? 1 : 0);
+		writeb(MDIO_EnbIn | MDIO_ShiftClk, mdio_addr);
 		mdio_delay();
 	}
 	return (retval>>1) & 0xffff;
@@ -827,8 +886,8 @@
 
 static void mdio_write(struct net_device *dev, int phy_id, int location, int value)
 {
-	struct netdev_private *np = netdev_priv(dev);
-	void __iomem *mdio_addr = np->base + MIICtrl;
+	struct netdev_private *np = dev->priv;
+	long mdio_addr = dev->base_addr + MIICtrl;
 	int mii_cmd = (0x5002 << 16) | (phy_id << 23) | (location<<18) | value;
 	int i;
 
@@ -839,16 +898,16 @@
 	for (i = 31; i >= 0; i--) {
 		int dataval = (mii_cmd & (1 << i)) ? MDIO_WRITE1 : MDIO_WRITE0;
 
-		iowrite8(dataval, mdio_addr);
+		writeb(dataval, mdio_addr);
 		mdio_delay();
-		iowrite8(dataval | MDIO_ShiftClk, mdio_addr);
+		writeb(dataval | MDIO_ShiftClk, mdio_addr);
 		mdio_delay();
 	}
 	/* Clear out extra bits. */
 	for (i = 2; i > 0; i--) {
-		iowrite8(MDIO_EnbIn, mdio_addr);
+		writeb(MDIO_EnbIn, mdio_addr);
 		mdio_delay();
-		iowrite8(MDIO_EnbIn | MDIO_ShiftClk, mdio_addr);
+		writeb(MDIO_EnbIn | MDIO_ShiftClk, mdio_addr);
 		mdio_delay();
 	}
 	return;
@@ -856,8 +915,8 @@
 
 static int netdev_open(struct net_device *dev)
 {
-	struct netdev_private *np = netdev_priv(dev);
-	void __iomem *ioaddr = np->base;
+	struct netdev_private *np = dev->priv;
+	long ioaddr = dev->base_addr;
 	int i;
 
 	/* Do we need to reset the chip??? */
@@ -871,45 +930,50 @@
 			   dev->name, dev->irq);
 	init_ring(dev);
 
-	iowrite32(np->rx_ring_dma, ioaddr + RxListPtr);
+	writel(np->rx_ring_dma, ioaddr + RxListPtr);
 	/* The Tx list pointer is written as packets are queued. */
 
 	/* Initialize other registers. */
 	__set_mac_addr(dev);
 #if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
-	iowrite16(dev->mtu + 18, ioaddr + MaxFrameSize);
+	writew(dev->mtu + 18, ioaddr + MaxFrameSize);
 #else
-	iowrite16(dev->mtu + 14, ioaddr + MaxFrameSize);
+	writew(dev->mtu + 14, ioaddr + MaxFrameSize);
 #endif
 	if (dev->mtu > 2047)
-		iowrite32(ioread32(ioaddr + ASICCtrl) | 0x0C, ioaddr + ASICCtrl);
+		writel(readl(ioaddr + ASICCtrl) | 0x0C, ioaddr + ASICCtrl);
 
 	/* Configure the PCI bus bursts and FIFO thresholds. */
 
 	if (dev->if_port == 0)
 		dev->if_port = np->default_port;
 
-	spin_lock_init(&np->mcastlock);
+	np->mcastlock = (spinlock_t) SPIN_LOCK_UNLOCKED;
 
 	set_rx_mode(dev);
-	iowrite16(0, ioaddr + IntrEnable);
-	iowrite16(0, ioaddr + DownCounter);
+	writew(0, ioaddr + IntrEnable);
+	writew(0, ioaddr + DownCounter);
 	/* Set the chip to poll every N*320nsec. */
-	iowrite8(100, ioaddr + RxDMAPollPeriod);
-	iowrite8(127, ioaddr + TxDMAPollPeriod);
+	writeb(100, ioaddr + RxDMAPollPeriod);
+	writeb(127, ioaddr + TxDMAPollPeriod);
 	/* Fix DFE-580TX packet drop issue */
 	if (np->pci_rev_id >= 0x14)
-		iowrite8(0x01, ioaddr + DebugCtrl1);
+		writeb(0x01, ioaddr + DebugCtrl1);
 	netif_start_queue(dev);
-
-	iowrite16 (StatsEnable | RxEnable | TxEnable, ioaddr + MACCtrl1);
+	
+	// 04/19/2005 Jesse fix for complete initial step
+	spin_lock(&np->lock);
+	reset_tx(dev);
+	spin_unlock(&np->lock);
+	writew(0x200, ioaddr + DMACtrl);
+	writew (StatsEnable | RxEnable | TxEnable, ioaddr + MACCtrl1);
 
 	if (netif_msg_ifup(np))
 		printk(KERN_DEBUG "%s: Done netdev_open(), status: Rx %x Tx %x "
 			   "MAC Control %x, %4.4x %4.4x.\n",
-			   dev->name, ioread32(ioaddr + RxStatus), ioread8(ioaddr + TxStatus),
-			   ioread32(ioaddr + MACCtrl0),
-			   ioread16(ioaddr + MACCtrl1), ioread16(ioaddr + MACCtrl0));
+			   dev->name, readl(ioaddr + RxStatus), readb(ioaddr + TxStatus),
+			   readl(ioaddr + MACCtrl0),
+			   readw(ioaddr + MACCtrl1), readw(ioaddr + MACCtrl0));
 
 	/* Set the timer to check for link beat. */
 	init_timer(&np->timer);
@@ -919,15 +983,15 @@
 	add_timer(&np->timer);
 
 	/* Enable interrupts by setting the interrupt mask. */
-	iowrite16(DEFAULT_INTR, ioaddr + IntrEnable);
-
+	writew(DEFAULT_INTR, ioaddr + IntrEnable);
+	
 	return 0;
 }
 
 static void check_duplex(struct net_device *dev)
 {
-	struct netdev_private *np = netdev_priv(dev);
-	void __iomem *ioaddr = np->base;
+	struct netdev_private *np = dev->priv;
+	long ioaddr = dev->base_addr;
 	int mii_lpa = mdio_read(dev, np->phys[0], MII_LPA);
 	int negotiated = mii_lpa & np->mii_if.advertising;
 	int duplex;
@@ -935,7 +999,7 @@
 	/* Force media */
 	if (!np->an_enable || mii_lpa == 0xffff) {
 		if (np->mii_if.full_duplex)
-			iowrite16 (ioread16 (ioaddr + MACCtrl0) | EnbFullDuplex,
+			writew (readw (ioaddr + MACCtrl0) | EnbFullDuplex,
 				ioaddr + MACCtrl0);
 		return;
 	}
@@ -948,22 +1012,22 @@
 			printk(KERN_INFO "%s: Setting %s-duplex based on MII #%d "
 				   "negotiated capability %4.4x.\n", dev->name,
 				   duplex ? "full" : "half", np->phys[0], negotiated);
-		iowrite16(ioread16(ioaddr + MACCtrl0) | duplex ? 0x20 : 0, ioaddr + MACCtrl0);
+		writew(readw(ioaddr + MACCtrl0) | duplex ? 0x20 : 0, ioaddr + MACCtrl0);
 	}
 }
 
 static void netdev_timer(unsigned long data)
 {
 	struct net_device *dev = (struct net_device *)data;
-	struct netdev_private *np = netdev_priv(dev);
-	void __iomem *ioaddr = np->base;
+	struct netdev_private *np = dev->priv;
+	long ioaddr = dev->base_addr;
 	int next_tick = 10*HZ;
 
 	if (netif_msg_timer(np)) {
 		printk(KERN_DEBUG "%s: Media selection timer tick, intr status %4.4x, "
 			   "Tx %x Rx %x.\n",
-			   dev->name, ioread16(ioaddr + IntrEnable),
-			   ioread8(ioaddr + TxStatus), ioread32(ioaddr + RxStatus));
+			   dev->name, readw(ioaddr + IntrEnable),
+			   readb(ioaddr + TxStatus), readl(ioaddr + RxStatus));
 	}
 	check_duplex(dev);
 	np->timer.expires = jiffies + next_tick;
@@ -972,33 +1036,33 @@
 
 static void tx_timeout(struct net_device *dev)
 {
-	struct netdev_private *np = netdev_priv(dev);
-	void __iomem *ioaddr = np->base;
+	struct netdev_private *np = dev->priv;
+	long ioaddr = dev->base_addr;
 	unsigned long flag;
-	
+
 	netif_stop_queue(dev);
 	tasklet_disable(&np->tx_tasklet);
-	iowrite16(0, ioaddr + IntrEnable);
+	writew(0, ioaddr + IntrEnable);
 	printk(KERN_WARNING "%s: Transmit timed out, TxStatus %2.2x "
 		   "TxFrameId %2.2x,"
-		   " resetting...\n", dev->name, ioread8(ioaddr + TxStatus),
-		   ioread8(ioaddr + TxFrameId));
+		   " resetting...\n", dev->name, readb(ioaddr + TxStatus),
+		   readb(ioaddr + TxFrameId));
 
 	{
 		int i;
 		for (i=0; i<TX_RING_SIZE; i++) {
-			printk(KERN_DEBUG "%02x %08llx %08x %08x(%02x) %08x %08x\n", i,
-				(unsigned long long)(np->tx_ring_dma + i*sizeof(*np->tx_ring)),
+			printk(KERN_DEBUG "%02x %08x %08x %08x(%02x) %08x %08x\n", i,
+				np->tx_ring_dma + i*sizeof(*np->tx_ring),
 				le32_to_cpu(np->tx_ring[i].next_desc),
 				le32_to_cpu(np->tx_ring[i].status),
 				(le32_to_cpu(np->tx_ring[i].status) >> 2) & 0xff,
-				le32_to_cpu(np->tx_ring[i].frag[0].addr), 
+				le32_to_cpu(np->tx_ring[i].frag[0].addr),
 				le32_to_cpu(np->tx_ring[i].frag[0].length));
 		}
-		printk(KERN_DEBUG "TxListPtr=%08x netif_queue_stopped=%d\n", 
-			ioread32(np->base + TxListPtr), 
+		printk(KERN_DEBUG "TxListPtr=%08x netif_queue_stopped=%d\n",
+			readl(dev->base_addr + TxListPtr),
 			netif_queue_stopped(dev));
-		printk(KERN_DEBUG "cur_tx=%d(%02x) dirty_tx=%d(%02x)\n", 
+		printk(KERN_DEBUG "cur_tx=%d(%02x) dirty_tx=%d(%02x)\n",
 			np->cur_tx, np->cur_tx % TX_RING_SIZE,
 			np->dirty_tx, np->dirty_tx % TX_RING_SIZE);
 		printk(KERN_DEBUG "cur_rx=%d dirty_rx=%d\n", np->cur_rx, np->dirty_rx);
@@ -1017,7 +1081,7 @@
 	if (np->cur_tx - np->dirty_tx < TX_QUEUE_LEN - 4) {
 		netif_wake_queue(dev);
 	}
-	iowrite16(DEFAULT_INTR, ioaddr + IntrEnable);
+	writew(DEFAULT_INTR, ioaddr + IntrEnable);
 	tasklet_enable(&np->tx_tasklet);
 }
 
@@ -1025,7 +1089,7 @@
 /* Initialize the Rx and Tx rings, along with various 'dev' bits. */
 static void init_ring(struct net_device *dev)
 {
-	struct netdev_private *np = netdev_priv(dev);
+	struct netdev_private *np = dev->priv;
 	int i;
 
 	np->cur_rx = np->cur_tx = 0;
@@ -1040,7 +1104,7 @@
 			((i+1)%RX_RING_SIZE)*sizeof(*np->rx_ring));
 		np->rx_ring[i].status = 0;
 		np->rx_ring[i].frag[0].length = 0;
-		np->rx_skbuff[i] = NULL;
+		np->rx_skbuff[i] = 0;
 	}
 
 	/* Fill in the Rx buffers.  Handle allocation failure gracefully. */
@@ -1052,14 +1116,14 @@
 		skb->dev = dev;		/* Mark as being used by this device. */
 		skb_reserve(skb, 2);	/* 16 byte align the IP header. */
 		np->rx_ring[i].frag[0].addr = cpu_to_le32(
-			pci_map_single(np->pci_dev, skb->data, np->rx_buf_sz,
+			pci_map_single(np->pci_dev, skb->tail, np->rx_buf_sz,
 				PCI_DMA_FROMDEVICE));
 		np->rx_ring[i].frag[0].length = cpu_to_le32(np->rx_buf_sz | LastFrag);
 	}
 	np->dirty_rx = (unsigned int)(i - RX_RING_SIZE);
 
 	for (i = 0; i < TX_RING_SIZE; i++) {
-		np->tx_skbuff[i] = NULL;
+		np->tx_skbuff[i] = 0;
 		np->tx_ring[i].status = 0;
 	}
 	return;
@@ -1068,11 +1132,11 @@
 static void tx_poll (unsigned long data)
 {
 	struct net_device *dev = (struct net_device *)data;
-	struct netdev_private *np = netdev_priv(dev);
+	struct netdev_private *np = dev->priv;
 	unsigned head = np->cur_task % TX_RING_SIZE;
-	struct netdev_desc *txdesc = 
+	struct netdev_desc *txdesc =
 		&np->tx_ring[(np->cur_tx - 1) % TX_RING_SIZE];
-	
+
 	/* Chain the next pointer */
 	for (; np->cur_tx - np->cur_task > 0; np->cur_task++) {
 		int entry = np->cur_task % TX_RING_SIZE;
@@ -1086,16 +1150,16 @@
 	/* Indicate the latest descriptor of tx ring */
 	txdesc->status |= cpu_to_le32(DescIntrOnTx);
 
-	if (ioread32 (np->base + TxListPtr) == 0)
-		iowrite32 (np->tx_ring_dma + head * sizeof(struct netdev_desc),
-			np->base + TxListPtr);
+	if (readl (dev->base_addr + TxListPtr) == 0)
+		writel (np->tx_ring_dma + head * sizeof(struct netdev_desc),
+			dev->base_addr + TxListPtr);
 	return;
 }
 
 static int
 start_tx (struct sk_buff *skb, struct net_device *dev)
 {
-	struct netdev_private *np = netdev_priv(dev);
+	struct netdev_private *np = dev->priv;
 	struct netdev_desc *txdesc;
 	unsigned entry;
 
@@ -1137,58 +1201,71 @@
 static int
 reset_tx (struct net_device *dev)
 {
-	struct netdev_private *np = netdev_priv(dev);
-	void __iomem *ioaddr = np->base;
+	struct netdev_private *np = (struct netdev_private*) dev->priv;
+	long ioaddr = dev->base_addr;
 	struct sk_buff *skb;
 	int i;
 	int irq = in_interrupt();
-	
+	tasklet_kill(&np->tx_tasklet);
 	/* Reset tx logic, TxListPtr will be cleaned */
-	iowrite16 (TxDisable, ioaddr + MACCtrl1);
-	iowrite16 (TxReset | DMAReset | FIFOReset | NetworkReset,
+	writew (TxDisable, ioaddr + MACCtrl1);
+	writew (TxReset | DMAReset | FIFOReset | NetworkReset,
 			ioaddr + ASICCtrl + 2);
 	for (i=50; i > 0; i--) {
-		if ((ioread16(ioaddr + ASICCtrl + 2) & ResetBusy) == 0)
+		if ((readw(ioaddr + ASICCtrl + 2) & ResetBusy) == 0)
 			break;
 		mdelay(1);
 	}
 	/* free all tx skbuff */
 	for (i = 0; i < TX_RING_SIZE; i++) {
+// 2005/11/4	    
+		np->tx_ring[i].next_desc=0;
+//
 		skb = np->tx_skbuff[i];
 		if (skb) {
-			pci_unmap_single(np->pci_dev, 
+			pci_unmap_single(np->pci_dev,
 				np->tx_ring[i].frag[0].addr, skb->len,
 				PCI_DMA_TODEVICE);
 			if (irq)
 				dev_kfree_skb_irq (skb);
 			else
 				dev_kfree_skb (skb);
-			np->tx_skbuff[i] = NULL;
+			np->tx_skbuff[i] = 0;
 			np->stats.tx_dropped++;
 		}
 	}
 	np->cur_tx = np->dirty_tx = 0;
 	np->cur_task = 0;
-	iowrite16 (StatsEnable | RxEnable | TxEnable, ioaddr + MACCtrl1);
+	np->last_tx=0;
+	
+	writeb(127, ioaddr + TxDMAPollPeriod);
+	writew (StatsEnable | RxEnable | TxEnable, ioaddr + MACCtrl1);
 	return 0;
 }
 
-/* The interrupt handler cleans up after the Tx thread, 
+/* The interrupt handler cleans up after the Tx thread,
    and schedule a Rx thread work */
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+static void intr_handler(int irq, void *dev_instance, struct pt_regs *rgs)
+#else
 static irqreturn_t intr_handler(int irq, void *dev_instance, struct pt_regs *rgs)
+#endif
 {
 	struct net_device *dev = (struct net_device *)dev_instance;
-	struct netdev_private *np = netdev_priv(dev);
-	void __iomem *ioaddr = np->base;
+	struct netdev_private *np;
+	long ioaddr;
 	int hw_frame_id;
 	int tx_cnt;
 	int tx_status;
-	int handled = 0;
-
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
+        irqreturn_t intr_handled=IRQ_HANDLED;//IRQ_NONE;
+#endif
+	ioaddr = dev->base_addr;
+	np = dev->priv;
 
 	do {
-		int intr_status = ioread16(ioaddr + IntrStatus);
-		iowrite16(intr_status, ioaddr + IntrStatus);
+		int intr_status = readw(ioaddr + IntrStatus);
+		writew(intr_status, ioaddr + IntrStatus);
 
 		if (netif_msg_intr(np))
 			printk(KERN_DEBUG "%s: Interrupt, status %4.4x.\n",
@@ -1197,65 +1274,58 @@
 		if (!(intr_status & DEFAULT_INTR))
 			break;
 
-		handled = 1;
-
 		if (intr_status & (IntrRxDMADone)) {
-			iowrite16(DEFAULT_INTR & ~(IntrRxDone|IntrRxDMADone),
+			writew(DEFAULT_INTR & ~(IntrRxDone|IntrRxDMADone),
 					ioaddr + IntrEnable);
 			if (np->budget < 0)
 				np->budget = RX_BUDGET;
 			tasklet_schedule(&np->rx_tasklet);
 		}
 		if (intr_status & (IntrTxDone | IntrDrvRqst)) {
-			tx_status = ioread16 (ioaddr + TxStatus);
+			tx_status = readw (ioaddr + TxStatus);
 			for (tx_cnt=32; tx_status & 0x80; --tx_cnt) {
 				if (netif_msg_tx_done(np))
 					printk
 					    ("%s: Transmit status is %2.2x.\n",
 				     	dev->name, tx_status);
 				if (tx_status & 0x1e) {
-					if (netif_msg_tx_err(np))
-						printk("%s: Transmit error status %4.4x.\n",
-							   dev->name, tx_status);
 					np->stats.tx_errors++;
 					if (tx_status & 0x10)
 						np->stats.tx_fifo_errors++;
 					if (tx_status & 0x08)
 						np->stats.collisions++;
-					if (tx_status & 0x04)
-						np->stats.tx_fifo_errors++;
 					if (tx_status & 0x02)
 						np->stats.tx_window_errors++;
-					/*
-					** This reset has been verified on
-					** DFE-580TX boards ! phdm@macqel.be.
-					*/
-					if (tx_status & 0x10) {	/* TxUnderrun */
-						unsigned short txthreshold;
-
-						txthreshold = ioread16 (ioaddr + TxStartThresh);
-						/* Restart Tx FIFO and transmitter */
-						sundance_reset(dev, (NetworkReset|FIFOReset|TxReset) << 16);
-						iowrite16 (txthreshold, ioaddr + TxStartThresh);
-						/* No need to reset the Tx pointer here */
+					/* This reset has not been verified!. */
+					if (tx_status & 0x10) {	/* Reset the Tx. */
+						np->stats.tx_fifo_errors++;
+						spin_lock(&np->lock);
+						reset_tx(dev);
+						spin_unlock(&np->lock);
+					}
+					if (tx_status & 0x1e) {
+					/* It could fail to restart the tx when MaxCollions, need to try more times */
+						int i = 10;
+						do {
+							writew (readw(ioaddr + MACCtrl1) | TxEnable, ioaddr + MACCtrl1);
+							if (readw(ioaddr + MACCtrl1) & TxEnabled)
+								break;
+							mdelay(1);
+						} while (--i);
 					}
-					/* Restart the Tx. */
-					iowrite16 (TxEnable, ioaddr + MACCtrl1);
 				}
 				/* Yup, this is a documentation bug.  It cost me *hours*. */
-				iowrite16 (0, ioaddr + TxStatus);
-				if (tx_cnt < 0) {
-					iowrite32(5000, ioaddr + DownCounter);
+				writew (0, ioaddr + TxStatus);
+				tx_status = readw (ioaddr + TxStatus);
+				if (tx_cnt < 0)
 					break;
-				}
-				tx_status = ioread16 (ioaddr + TxStatus);
 			}
 			hw_frame_id = (tx_status >> 8) & 0xff;
 		} else 	{
-			hw_frame_id = ioread8(ioaddr + TxFrameId);
+			hw_frame_id = readb(ioaddr + TxFrameId);
 		}
-			
-		if (np->pci_rev_id >= 0x14) {	
+
+		if (np->pci_rev_id >= 0x14) {
 			spin_lock(&np->lock);
 			for (; np->cur_tx - np->dirty_tx > 0; np->dirty_tx++) {
 				int entry = np->dirty_tx % TX_RING_SIZE;
@@ -1267,7 +1337,7 @@
 					!(le32_to_cpu(np->tx_ring[entry].status)
 					& 0x00010000))
 						break;
-				if (sw_frame_id == (hw_frame_id + 1) % 
+				if (sw_frame_id == (hw_frame_id + 1) %
 					TX_RING_SIZE)
 						break;
 				skb = np->tx_skbuff[entry];
@@ -1276,7 +1346,7 @@
 					np->tx_ring[entry].frag[0].addr,
 					skb->len, PCI_DMA_TODEVICE);
 				dev_kfree_skb_irq (np->tx_skbuff[entry]);
-				np->tx_skbuff[entry] = NULL;
+				np->tx_skbuff[entry] = 0;
 				np->tx_ring[entry].frag[0].addr = 0;
 				np->tx_ring[entry].frag[0].length = 0;
 			}
@@ -1286,7 +1356,7 @@
 			for (; np->cur_tx - np->dirty_tx > 0; np->dirty_tx++) {
 				int entry = np->dirty_tx % TX_RING_SIZE;
 				struct sk_buff *skb;
-				if (!(le32_to_cpu(np->tx_ring[entry].status) 
+				if (!(le32_to_cpu(np->tx_ring[entry].status)
 							& 0x00010000))
 					break;
 				skb = np->tx_skbuff[entry];
@@ -1295,13 +1365,13 @@
 					np->tx_ring[entry].frag[0].addr,
 					skb->len, PCI_DMA_TODEVICE);
 				dev_kfree_skb_irq (np->tx_skbuff[entry]);
-				np->tx_skbuff[entry] = NULL;
+				np->tx_skbuff[entry] = 0;
 				np->tx_ring[entry].frag[0].addr = 0;
 				np->tx_ring[entry].frag[0].length = 0;
 			}
 			spin_unlock(&np->lock);
 		}
-		
+
 		if (netif_queue_stopped(dev) &&
 			np->cur_tx - np->dirty_tx < TX_QUEUE_LEN - 4) {
 			/* The ring is no longer full, clear busy flag. */
@@ -1313,17 +1383,21 @@
 	} while (0);
 	if (netif_msg_intr(np))
 		printk(KERN_DEBUG "%s: exiting interrupt, status=%#4.4x.\n",
-			   dev->name, ioread16(ioaddr + IntrStatus));
-	return IRQ_RETVAL(handled);
+			   dev->name, readw(ioaddr + IntrStatus));
+	writel(5000, ioaddr + DownCounter);
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
+    return intr_handled;
+#endif
+
 }
 
 static void rx_poll(unsigned long data)
 {
 	struct net_device *dev = (struct net_device *)data;
-	struct netdev_private *np = netdev_priv(dev);
+	struct netdev_private *np = dev->priv;
 	int entry = np->cur_rx % RX_RING_SIZE;
 	int boguscnt = np->budget;
-	void __iomem *ioaddr = np->base;
+	long ioaddr = dev->base_addr;
 	int received = 0;
 
 	/* If EOP is set on the next entry, it's a new packet. Send it up. */
@@ -1341,6 +1415,12 @@
 		if (netif_msg_rx_status(np))
 			printk(KERN_DEBUG "  netdev_rx() status was %8.8x.\n",
 				   frame_status);
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) 
+		pci_dma_sync_single(np->pci_dev, desc->frag[0].addr,np->rx_buf_sz, PCI_DMA_FROMDEVICE);
+#else
+		pci_dma_sync_single_for_cpu(np->pci_dev, desc->frag[0].addr,np->rx_buf_sz, PCI_DMA_FROMDEVICE);
+#endif
+
 		if (frame_status & 0x001f4000) {
 			/* There was a error. */
 			if (netif_msg_rx_err(np))
@@ -1370,16 +1450,7 @@
 				&& (skb = dev_alloc_skb(pkt_len + 2)) != NULL) {
 				skb->dev = dev;
 				skb_reserve(skb, 2);	/* 16 byte align the IP header */
-				pci_dma_sync_single_for_cpu(np->pci_dev,
-							    desc->frag[0].addr,
-							    np->rx_buf_sz,
-							    PCI_DMA_FROMDEVICE);
-
-				eth_copy_and_sum(skb, np->rx_skbuff[entry]->data, pkt_len, 0);
-				pci_dma_sync_single_for_device(np->pci_dev,
-							       desc->frag[0].addr,
-							       np->rx_buf_sz,
-							       PCI_DMA_FROMDEVICE);
+				eth_copy_and_sum(skb, np->rx_skbuff[entry]->tail, pkt_len, 0);
 				skb_put(skb, pkt_len);
 			} else {
 				pci_unmap_single(np->pci_dev,
@@ -1400,7 +1471,7 @@
 	np->cur_rx = entry;
 	refill_rx (dev);
 	np->budget -= received;
-	iowrite16(DEFAULT_INTR, ioaddr + IntrEnable);
+	writew(DEFAULT_INTR, ioaddr + IntrEnable);
 	return;
 
 not_done:
@@ -1417,7 +1488,7 @@
 
 static void refill_rx (struct net_device *dev)
 {
-	struct netdev_private *np = netdev_priv(dev);
+	struct netdev_private *np = dev->priv;
 	int entry;
 	int cnt = 0;
 
@@ -1434,7 +1505,7 @@
 			skb->dev = dev;		/* Mark as being used by this device. */
 			skb_reserve(skb, 2);	/* Align IP on 16 byte boundaries */
 			np->rx_ring[entry].frag[0].addr = cpu_to_le32(
-				pci_map_single(np->pci_dev, skb->data,
+				pci_map_single(np->pci_dev, skb->tail,
 					np->rx_buf_sz, PCI_DMA_FROMDEVICE));
 		}
 		/* Perhaps we need not reset this field. */
@@ -1447,8 +1518,8 @@
 }
 static void netdev_error(struct net_device *dev, int intr_status)
 {
-	struct netdev_private *np = netdev_priv(dev);
-	void __iomem *ioaddr = np->base;
+	long ioaddr = dev->base_addr;
+	struct netdev_private *np = dev->priv;
 	u16 mii_ctl, mii_advertise, mii_lpa;
 	int speed;
 
@@ -1484,9 +1555,9 @@
 		}
 		check_duplex (dev);
 		if (np->flowctrl && np->mii_if.full_duplex) {
-			iowrite16(ioread16(ioaddr + MulticastFilter1+2) | 0x0200,
+			writew(readw(ioaddr + MulticastFilter1+2) | 0x0200,
 				ioaddr + MulticastFilter1+2);
-			iowrite16(ioread16(ioaddr + MACCtrl0) | EnbFlowCtrl,
+			writew(readw(ioaddr + MACCtrl0) | EnbFlowCtrl,
 				ioaddr + MACCtrl0);
 		}
 	}
@@ -1502,36 +1573,36 @@
 
 static struct net_device_stats *get_stats(struct net_device *dev)
 {
-	struct netdev_private *np = netdev_priv(dev);
-	void __iomem *ioaddr = np->base;
+	struct netdev_private *np = dev->priv;
+	long ioaddr = dev->base_addr;
 	int i;
 
 	/* We should lock this segment of code for SMP eventually, although
 	   the vulnerability window is very small and statistics are
 	   non-critical. */
 	/* The chip only need report frame silently dropped. */
-	np->stats.rx_missed_errors	+= ioread8(ioaddr + RxMissed);
-	np->stats.tx_packets += ioread16(ioaddr + TxFramesOK);
-	np->stats.rx_packets += ioread16(ioaddr + RxFramesOK);
-	np->stats.collisions += ioread8(ioaddr + StatsLateColl);
-	np->stats.collisions += ioread8(ioaddr + StatsMultiColl);
-	np->stats.collisions += ioread8(ioaddr + StatsOneColl);
-	np->stats.tx_carrier_errors += ioread8(ioaddr + StatsCarrierError);
-	ioread8(ioaddr + StatsTxDefer);
+	np->stats.rx_missed_errors	+= readb(ioaddr + RxMissed);
+	np->stats.tx_packets += readw(ioaddr + TxFramesOK);
+	np->stats.rx_packets += readw(ioaddr + RxFramesOK);
+	np->stats.collisions += readb(ioaddr + StatsLateColl);
+	np->stats.collisions += readb(ioaddr + StatsMultiColl);
+	np->stats.collisions += readb(ioaddr + StatsOneColl);
+	np->stats.tx_carrier_errors += readb(ioaddr + StatsCarrierError);
+	readb(ioaddr + StatsTxDefer);
 	for (i = StatsTxDefer; i <= StatsMcastRx; i++)
-		ioread8(ioaddr + i);
-	np->stats.tx_bytes += ioread16(ioaddr + TxOctetsLow);
-	np->stats.tx_bytes += ioread16(ioaddr + TxOctetsHigh) << 16;
-	np->stats.rx_bytes += ioread16(ioaddr + RxOctetsLow);
-	np->stats.rx_bytes += ioread16(ioaddr + RxOctetsHigh) << 16;
+		readb(ioaddr + i);
+	np->stats.tx_bytes += readw(ioaddr + TxOctetsLow);
+	np->stats.tx_bytes += readw(ioaddr + TxOctetsHigh) << 16;
+	np->stats.rx_bytes += readw(ioaddr + RxOctetsLow);
+	np->stats.rx_bytes += readw(ioaddr + RxOctetsHigh) << 16;
 
 	return &np->stats;
 }
 
 static void set_rx_mode(struct net_device *dev)
 {
-	struct netdev_private *np = netdev_priv(dev);
-	void __iomem *ioaddr = np->base;
+	long ioaddr = dev->base_addr;
+	struct netdev_private *np = dev->priv;
 	u16 mc_filter[4];			/* Multicast hash filter */
 	u32 rx_mode;
 	int i;
@@ -1561,170 +1632,212 @@
 		}
 		rx_mode = AcceptBroadcast | AcceptMultiHash | AcceptMyPhys;
 	} else {
-		iowrite8(AcceptBroadcast | AcceptMyPhys, ioaddr + RxMode);
+		writeb(AcceptBroadcast | AcceptMyPhys, ioaddr + RxMode);
 		return;
 	}
 	if (np->mii_if.full_duplex && np->flowctrl)
 		mc_filter[3] |= 0x0200;
 
 	for (i = 0; i < 4; i++)
-		iowrite16(mc_filter[i], ioaddr + MulticastFilter0 + i*2);
-	iowrite8(rx_mode, ioaddr + RxMode);
+		writew(mc_filter[i], ioaddr + MulticastFilter0 + i*2);
+	writeb(rx_mode, ioaddr + RxMode);
 }
 
 static int __set_mac_addr(struct net_device *dev)
 {
-	struct netdev_private *np = netdev_priv(dev);
 	u16 addr16;
 
 	addr16 = (dev->dev_addr[0] | (dev->dev_addr[1] << 8));
-	iowrite16(addr16, np->base + StationAddr);
+	writew(addr16, dev->base_addr + StationAddr);
 	addr16 = (dev->dev_addr[2] | (dev->dev_addr[3] << 8));
-	iowrite16(addr16, np->base + StationAddr+2);
+	writew(addr16, dev->base_addr + StationAddr+2);
 	addr16 = (dev->dev_addr[4] | (dev->dev_addr[5] << 8));
-	iowrite16(addr16, np->base + StationAddr+4);
+	writew(addr16, dev->base_addr + StationAddr+4);
 	return 0;
 }
 
-static int check_if_running(struct net_device *dev)
-{
-	if (!netif_running(dev))
-		return -EINVAL;
-	return 0;
-}
 
-static void get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
+static int netdev_ethtool_ioctl(struct net_device *dev, void *useraddr)
 {
-	struct netdev_private *np = netdev_priv(dev);
-	strcpy(info->driver, DRV_NAME);
-	strcpy(info->version, DRV_VERSION);
-	strcpy(info->bus_info, pci_name(np->pci_dev));
-}
+	struct netdev_private *np = dev->priv;
+	u32 ethcmd;
 
-static int get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
-{
-	struct netdev_private *np = netdev_priv(dev);
-	spin_lock_irq(&np->lock);
-	mii_ethtool_gset(&np->mii_if, ecmd);
-	spin_unlock_irq(&np->lock);
-	return 0;
-}
+	if (copy_from_user(&ethcmd, useraddr, sizeof(ethcmd)))
+		return -EFAULT;
 
-static int set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
-{
-	struct netdev_private *np = netdev_priv(dev);
-	int res;
-	spin_lock_irq(&np->lock);
-	res = mii_ethtool_sset(&np->mii_if, ecmd);
-	spin_unlock_irq(&np->lock);
-	return res;
-}
+        switch (ethcmd) {
+		/* get constant driver settings/info */
+        	case ETHTOOL_GDRVINFO: {
+			struct ethtool_drvinfo info = {ETHTOOL_GDRVINFO};
+			strcpy(info.driver, DRV_NAME);
+			strcpy(info.version, DRV_VERSION);
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11) 
+		   strcpy(info.bus_info, np->pci_dev->slot_name);
+#else
+		   strcpy(info.bus_info, pci_name(np->pci_dev));
+#endif						
+			memset(&info.fw_version, 0, sizeof(info.fw_version));
+			if (copy_to_user(useraddr, &info, sizeof(info)))
+				return -EFAULT;
+			return 0;
+		}
 
-static int nway_reset(struct net_device *dev)
-{
-	struct netdev_private *np = netdev_priv(dev);
-	return mii_nway_restart(&np->mii_if);
-}
+		/* get media settings */
+		case ETHTOOL_GSET: {
+			struct ethtool_cmd ecmd = { ETHTOOL_GSET };
+			spin_lock_irq(&np->lock);
+			mii_ethtool_gset(&np->mii_if, &ecmd);
+			spin_unlock_irq(&np->lock);
+			if (copy_to_user(useraddr, &ecmd, sizeof(ecmd)))
+				return -EFAULT;
+			return 0;
+		}
+		/* set media settings */
+		case ETHTOOL_SSET: {
+			int r;
+			struct ethtool_cmd ecmd;
+			if (copy_from_user(&ecmd, useraddr, sizeof(ecmd)))
+				return -EFAULT;
+			spin_lock_irq(&np->lock);
+			r = mii_ethtool_sset(&np->mii_if, &ecmd);
+			spin_unlock_irq(&np->lock);
+			return r;
+		}
+
+		/* restart autonegotiation */
+		case ETHTOOL_NWAY_RST: {
+			return mii_nway_restart(&np->mii_if);
+		}
+
+		/* get link status */
+		case ETHTOOL_GLINK: {
+			struct ethtool_value edata = {ETHTOOL_GLINK};
+			edata.data = mii_link_ok(&np->mii_if);
+			if (copy_to_user(useraddr, &edata, sizeof(edata)))
+				return -EFAULT;
+			return 0;
+		}
 
-static u32 get_link(struct net_device *dev)
-{
-	struct netdev_private *np = netdev_priv(dev);
-	return mii_link_ok(&np->mii_if);
-}
+		/* get message-level */
+		case ETHTOOL_GMSGLVL: {
+			struct ethtool_value edata = {ETHTOOL_GMSGLVL};
+			edata.data = np->msg_enable;
+			if (copy_to_user(useraddr, &edata, sizeof(edata)))
+				return -EFAULT;
+			return 0;
+		}
+		/* set message-level */
+		case ETHTOOL_SMSGLVL: {
+			struct ethtool_value edata;
+			if (copy_from_user(&edata, useraddr, sizeof(edata)))
+				return -EFAULT;
+			np->msg_enable = edata.data;
+			return 0;
+		}
 
-static u32 get_msglevel(struct net_device *dev)
-{
-	struct netdev_private *np = netdev_priv(dev);
-	return np->msg_enable;
-}
+		default:
+		return -EOPNOTSUPP;
 
-static void set_msglevel(struct net_device *dev, u32 val)
-{
-	struct netdev_private *np = netdev_priv(dev);
-	np->msg_enable = val;
+        }
 }
 
-static struct ethtool_ops ethtool_ops = {
-	.begin = check_if_running,
-	.get_drvinfo = get_drvinfo,
-	.get_settings = get_settings,
-	.set_settings = set_settings,
-	.nway_reset = nway_reset,
-	.get_link = get_link,
-	.get_msglevel = get_msglevel,
-	.set_msglevel = set_msglevel,
-	.get_perm_addr = ethtool_op_get_perm_addr,
-};
-
 static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 {
-	struct netdev_private *np = netdev_priv(dev);
-	void __iomem *ioaddr = np->base;
+	struct netdev_private *np = dev->priv;
+	struct mii_ioctl_data *data = (struct mii_ioctl_data *) & rq->ifr_data;
 	int rc;
 	int i;
+	long ioaddr = dev->base_addr;
 
 	if (!netif_running(dev))
 		return -EINVAL;
 
-	spin_lock_irq(&np->lock);
-	rc = generic_mii_ioctl(&np->mii_if, if_mii(rq), cmd, NULL);
-	spin_unlock_irq(&np->lock);
+	if (cmd == SIOCETHTOOL)
+		rc = netdev_ethtool_ioctl(dev, (void *) rq->ifr_data);
+
+	else {
+		spin_lock_irq(&np->lock);
+		rc = generic_mii_ioctl(&np->mii_if, data, cmd, NULL);
+		spin_unlock_irq(&np->lock);
+	}
 	switch (cmd) {
 		case SIOCDEVPRIVATE:
 		for (i=0; i<TX_RING_SIZE; i++) {
-			printk(KERN_DEBUG "%02x %08llx %08x %08x(%02x) %08x %08x\n", i,
-				(unsigned long long)(np->tx_ring_dma + i*sizeof(*np->tx_ring)),	
+			printk(KERN_DEBUG "%02x %08x %08x %08x(%02x) %08x %08x\n", i,
+				np->tx_ring_dma + i*sizeof(*np->tx_ring),
 				le32_to_cpu(np->tx_ring[i].next_desc),
 				le32_to_cpu(np->tx_ring[i].status),
-				(le32_to_cpu(np->tx_ring[i].status) >> 2) 
+				(le32_to_cpu(np->tx_ring[i].status) >> 2)
 					& 0xff,
-				le32_to_cpu(np->tx_ring[i].frag[0].addr), 
+				le32_to_cpu(np->tx_ring[i].frag[0].addr),
 				le32_to_cpu(np->tx_ring[i].frag[0].length));
 		}
-		printk(KERN_DEBUG "TxListPtr=%08x netif_queue_stopped=%d\n", 
-			ioread32(np->base + TxListPtr), 
+		printk(KERN_DEBUG "TxListPtr=%08x netif_queue_stopped=%d\n",
+			readl(dev->base_addr + TxListPtr),
 			netif_queue_stopped(dev));
-		printk(KERN_DEBUG "cur_tx=%d(%02x) dirty_tx=%d(%02x)\n", 
+		printk(KERN_DEBUG "cur_tx=%d(%02x) dirty_tx=%d(%02x)\n",
 			np->cur_tx, np->cur_tx % TX_RING_SIZE,
 			np->dirty_tx, np->dirty_tx % TX_RING_SIZE);
 		printk(KERN_DEBUG "cur_rx=%d dirty_rx=%d\n", np->cur_rx, np->dirty_rx);
 		printk(KERN_DEBUG "cur_task=%d\n", np->cur_task);
-		printk(KERN_DEBUG "TxStatus=%04x\n", ioread16(ioaddr + TxStatus));
+		printk(KERN_DEBUG "TxStatus=%04x\n", readw(ioaddr + TxStatus));
 			return 0;
 	}
-				
+
 
 	return rc;
 }
 
 static int netdev_close(struct net_device *dev)
 {
-	struct netdev_private *np = netdev_priv(dev);
-	void __iomem *ioaddr = np->base;
+	long ioaddr = dev->base_addr;
+	struct netdev_private *np = dev->priv;
 	struct sk_buff *skb;
 	int i;
 
+	/* Wait and kill tasklet */
+	tasklet_kill(&np->rx_tasklet);
+	tasklet_kill(&np->tx_tasklet);
+   np->cur_tx = np->dirty_tx = 0;
+	np->cur_task = 0;
+	np->last_tx=0;
+
 	netif_stop_queue(dev);
 
 	if (netif_msg_ifdown(np)) {
 		printk(KERN_DEBUG "%s: Shutting down ethercard, status was Tx %2.2x "
 			   "Rx %4.4x Int %2.2x.\n",
-			   dev->name, ioread8(ioaddr + TxStatus),
-			   ioread32(ioaddr + RxStatus), ioread16(ioaddr + IntrStatus));
+			   dev->name, readb(ioaddr + TxStatus),
+			   readl(ioaddr + RxStatus), readw(ioaddr + IntrStatus));
 		printk(KERN_DEBUG "%s: Queue pointers were Tx %d / %d,  Rx %d / %d.\n",
 			   dev->name, np->cur_tx, np->dirty_tx, np->cur_rx, np->dirty_rx);
 	}
 
-	/* Disable interrupts by clearing the interrupt mask. */
-	iowrite16(0x0000, ioaddr + IntrEnable);
-
-	/* Stop the chip's Tx and Rx processes. */
-	iowrite16(TxDisable | RxDisable | StatsDisable, ioaddr + MACCtrl1);
+	/* Stop the chip's Rx processes. */
+	writew(RxDisable | StatsDisable, ioaddr + MACCtrl1);
+	writew(0x100, ioaddr + DMACtrl);
+	
+	/* Stop the chip's Tx processes. */
+	writew(0x400, ioaddr + DMACtrl);
+	writew(TxDisable, ioaddr + MACCtrl1);
 
-	/* Wait and kill tasklet */
-	tasklet_kill(&np->rx_tasklet);
-	tasklet_kill(&np->tx_tasklet);
+	/* Disable interrupts by clearing the interrupt mask. */
+	writew(0x0000, ioaddr + IntrEnable);
+    
+    for(i=2000;i> 0;i--) {
+		if(readl(ioaddr + DMACtrl)&0xC000 == 0)break;
+		mdelay(1);
+    }	
 
+    writew(GlobalReset | DMAReset | FIFOReset |NetworkReset, ioaddr +ASICCtrl + 2);
+    
+    for(i=2000;i >0;i--)
+    {
+		if((readw(ioaddr + ASICCtrl +2)&ResetBusy) == 0)
+	    	break;
+		mdelay(1);
+    }
+    
 #ifdef __i386__
 	if (netif_msg_hw(np)) {
 		printk("\n"KERN_DEBUG"  Tx ring at %8.8x:\n",
@@ -1757,17 +1870,20 @@
 				np->rx_ring[i].frag[0].addr, np->rx_buf_sz,
 				PCI_DMA_FROMDEVICE);
 			dev_kfree_skb(skb);
-			np->rx_skbuff[i] = NULL;
+			np->rx_skbuff[i] = 0;
 		}
 	}
 	for (i = 0; i < TX_RING_SIZE; i++) {
+// 2005/11/4	    
+		np->tx_ring[i].next_desc=0;
+//	
 		skb = np->tx_skbuff[i];
 		if (skb) {
 			pci_unmap_single(np->pci_dev,
 				np->tx_ring[i].frag[0].addr, skb->len,
 				PCI_DMA_TODEVICE);
 			dev_kfree_skb(skb);
-			np->tx_skbuff[i] = NULL;
+			np->tx_skbuff[i] = 0;
 		}
 	}
 
@@ -1778,17 +1894,20 @@
 {
 	struct net_device *dev = pci_get_drvdata(pdev);
 
+	/* No need to check MOD_IN_USE, as sys_delete_module() checks. */
 	if (dev) {
-		struct netdev_private *np = netdev_priv(dev);
+		struct netdev_private *np = dev->priv;
 
 		unregister_netdev(dev);
         	pci_free_consistent(pdev, RX_TOTAL_SIZE, np->rx_ring,
 			np->rx_ring_dma);
 	        pci_free_consistent(pdev, TX_TOTAL_SIZE, np->tx_ring,
 			np->tx_ring_dma);
-		pci_iounmap(pdev, np->base);
 		pci_release_regions(pdev);
-		free_netdev(dev);
+#ifndef USE_IO_OPS
+		iounmap((char *)(dev->base_addr));
+#endif
+		kfree(dev);
 		pci_set_drvdata(pdev, NULL);
 	}
 }


-- System Information:
Debian Release: testing/unstable
  APT prefers testing
  APT policy: (990, 'testing'), (500, 'unstable')
Architecture: i386 (i686)
Shell:  /bin/sh linked to /bin/bash
Kernel: Linux 2.6.16-1-p3
Locale: LANG=pt_BR.UTF-8, LC_CTYPE=pt_BR.UTF-8 (charmap=ISO-8859-1) (ignored: LC_ALL set to pt_BR)

Versions of packages linux-source-2.6.16 depends on:
ii  binutils             2.16.1cvs20060413-1 The GNU assembler, linker and bina
ii  bzip2                1.0.3-2             high-quality block-sorting file co

Versions of packages linux-source-2.6.16 recommends:
ii  gcc                           4:4.0.2-2  The GNU C compiler
ii  libc6-dev [libc-dev]          2.3.6-7    GNU C Library: Development Librari
ii  make                          3.81-1     The GNU version of the "make" util


-- no debconf information


--- End Message ---
--- Begin Message ---
Version: 2.6.20-1

upstream merged the relevant IP100/IP100A support in sundance
thus closing.

-- 
maks

--- End Message ---

Reply to: