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 [EMAIL PROTECTED]):
-       - 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 [EMAIL PROTECTED]):
-       - 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 <[EMAIL PROTECTED]>");
-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 ! [EMAIL PROTECTED]
-                                       */
-                                       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


-- 
To UNSUBSCRIBE, email to [EMAIL PROTECTED]
with a subject of "unsubscribe". Trouble? Contact [EMAIL PROTECTED]

Reply via email to