patch-2.0.37 linux/drivers/net/rcpci45.c

Next file: linux/drivers/net/rtl8139.c
Previous file: linux/drivers/net/rcmtl.h
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.0.36/linux/drivers/net/rcpci45.c linux/drivers/net/rcpci45.c
@@ -1,10 +1,11 @@
 /* 
+**
 **  RCpci45.c  
 **
 **
 **
 **  ---------------------------------------------------------------------
-**  ---     Copyright (c) 1998, RedCreek Communications Inc.          ---
+**  ---     Copyright (c) 1998, 1999, RedCreek Communications Inc.    ---
 **  ---                   All rights reserved.                        ---
 **  ---------------------------------------------------------------------
 **
@@ -12,14 +13,13 @@
 **
 ** Known Problems
 ** 
-** Billions and Billions...  
-**
-** ... apparently added by Brian.  Pete knows of no bugs.
+** None known at this time.
 **
 **  TODO:
 **      -Get rid of the wait loops in the API and replace them
 **       with system independent delays ...something like
-**       "delayms(2)".
+**       "delayms(2)".  However, under normal circumstances, the 
+**       delays are very short so they're not a problem.
 **
 **  This program is free software; you can redistribute it and/or modify
 **  it under the terms of the GNU General Public License as published by
@@ -35,20 +35,24 @@
 **  along with this program; if not, write to the Free Software
 **  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 **
+**   
+**  Pete Popov, January 11,99: Fixed a couple of 2.1.x problems 
+**  (virt_to_bus() not called), tested it under 2.2pre5 (as a module), and 
+**  added a #define(s) to enable the use of the same file for both, the 2.0.x 
+**  kernels as well as the 2.1.x.
+**
+**  Ported to 2.1.x by Alan Cox 1998/12/9. 
+**
+**  Sometime in mid 1998, written by Pete Popov and Brian Moyle.
+**
 ***************************************************************************/
 
-#define __NO_VERSION__ /* don't define kernel_verion in module.h */
-
 static char *version =
-"RedCreek Communications PCI linux driver version 1.32 Beta\n";
+"RedCreek Communications PCI linux driver version 2.02\n";
 
 
-#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/version.h>
-
-static char kernel_version [] = UTS_RELEASE;
-
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/string.h>
@@ -65,25 +69,34 @@
 #include <asm/bitops.h>
 #include <asm/io.h>
 
+#if LINUX_VERSION_CODE >= 0x020100
+#define LINUX_2_1
+#endif
+
+#ifdef LINUX_2_1
+#include <asm/uaccess.h>
+#endif
+
 #include <linux/if_ether.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/skbuff.h>
 
+
 #define RC_LINUX_MODULE
-#include "rcmtl.h"
+#include "rclanmtl.h"
 #include "rcif.h"
 
 #define RUN_AT(x) (jiffies + (x))
-#define DEV_ALLOC_SKB(len) dev_alloc_skb(len + 2)
-
-#define FREE_IRQ(irqnum, dev) free_irq(irqnum)
-#define REQUEST_IRQ(i,h,f,n, instance) request_irq(i,h,f,n)
-#define IRQ(irq, dev_id, pt_regs) (irq, pt_regs)
 
 #define NEW_MULTICAST
 #include <linux/delay.h>
 
+#ifndef LINUX_2_1
+#define ioremap vremap
+#define iounmap vfree
+#endif
+
 /* PCI/45 Configuration space values */
 #define RC_PCI45_VENDOR_ID  0x4916
 #define RC_PCI45_DEVICE_ID  0x1960
@@ -111,25 +124,25 @@
 typedef struct
 {
 
-     /* 
-      *    pointer to the device structure which is part
-      * of the interface to the Linux kernel.
-      */
-      struct device *dev;            
+    /* 
+     *    pointer to the device structure which is part
+     * of the interface to the Linux kernel.
+     */
+    struct device *dev;            
      
-     char devname[8];                /* "ethN" string */
-     U8     id;                        /* the AdapterID */
-     U32    pci_addr;               /* the pci address of the adapter */
-     U32    bus;
-     U32    function;
-     struct timer_list timer;        /*  timer */
-     struct enet_statistics  stats; /* the statistics structure */
-     struct device *next;            /* points to the next RC adapter */
-     unsigned long numOutRcvBuffers;/* number of outstanding receive buffers*/
-     unsigned char shutdown;
-     unsigned char reboot;
-     unsigned char nexus;
-     PU8    PLanApiPA;             /* Pointer to Lan Api Private Area */
+    char devname[8];                /* "ethN" string */
+    U8     id;                        /* the AdapterID */
+    U32    pci_addr;               /* the pci address of the adapter */
+    U32    bus;
+    U32    function;
+    struct timer_list timer;        /*  timer */
+    struct enet_statistics  stats; /* the statistics structure */
+    struct device *next;            /* points to the next RC adapter */
+    unsigned long numOutRcvBuffers;/* number of outstanding receive buffers*/
+    unsigned char shutdown;
+    unsigned char reboot;
+    unsigned char nexus;
+    PU8    PLanApiPA;             /* Pointer to Lan Api Private Area */
 
 }
 DPA, *PDPA;
@@ -138,18 +151,17 @@
 
 static PDPA  PCIAdapters[MAX_ADAPTERS] = 
 {
-     NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-     NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-     NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-     NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
+    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
 };
 
 
-static int RCscan(void);
-static struct device 
-*RCfound_device(struct device *, int, int, int, int, int, int);
+static int RCinit(struct device *dev);
+static int RCscan(struct device *dev);
+static int RCfound_device(struct device *, int, int, int, int, int, int);
 
-static int RCprobe1(struct device *);
 static int RCopen(struct device *);
 static int RC_xmit_packet(struct sk_buff *, struct device *);
 static void RCinterrupt(int, void *, struct pt_regs *);
@@ -170,261 +182,282 @@
 #ifdef MODULE
 int init_module(void)
 #else
-int rcpci_probe(struct netdevice *dev)
+int rcpci_probe(struct device *dev)
 #endif
 {
-     int cards_found;
+    int cards_found;
 
-     printk(version);
-
-     root_RCdev = NULL;
-     cards_found = RCscan();
-#ifdef MODULE     
-     return cards_found ? 0 : -ENODEV;
+#ifdef MODULE
+    cards_found = RCscan(NULL);
 #else
-     return -1;
-#endif          
+    cards_found = RCscan(dev);
+#endif
+    if (cards_found)
+        printk(version);
+    return cards_found ? 0 : -ENODEV;
 }
 
-static int RCscan(void)
+static int RCscan(struct device *dev)
 {
-     int cards_found = 0;
-     struct device *dev = 0;
+    int cards_found = 0;
+    static int pci_index = 0;
 
-     if (pcibios_present()) 
-     {
-          static int pci_index = 0;
-          unsigned char pci_bus, pci_device_fn;
-          int scan_status;
-          int board_index = 0;
-
-          for (;pci_index < 0xff; pci_index++) 
-          {
-               unsigned char pci_irq_line;
-               unsigned short pci_command, vendor, device, class;
-               unsigned int pci_ioaddr;
-
-
-               scan_status =  
-                    (pcibios_find_device (RC_PCI45_VENDOR_ID, 
-                                          RC_PCI45_DEVICE_ID, 
-                                          pci_index, 
-                                          &pci_bus, 
-                                          &pci_device_fn));
-#ifdef RCDEBUG
-               printk("rc scan_status = 0x%X\n", scan_status);
-#endif
-               if (scan_status != PCIBIOS_SUCCESSFUL)
-                    break;
-               pcibios_read_config_word(pci_bus, 
-                                        pci_device_fn, 
-                                        PCI_VENDOR_ID, &vendor);
-               pcibios_read_config_word(pci_bus, 
-                                        pci_device_fn,
-                                        PCI_DEVICE_ID, &device);
-               pcibios_read_config_byte(pci_bus, 
-                                        pci_device_fn,
-                                        PCI_INTERRUPT_LINE, &pci_irq_line);
-               pcibios_read_config_dword(pci_bus, 
-                                         pci_device_fn,
-                                         PCI_BASE_ADDRESS_0, &pci_ioaddr);
-               pcibios_read_config_word(pci_bus, 
-                                        pci_device_fn,
-                                        PCI_CLASS_DEVICE, &class);
-
-               pci_ioaddr &= ~0xf;
-
-#ifdef RCDEBUG
-               printk("rc: Found RedCreek PCI adapter\n");
-               printk("rc: pci class = 0x%x  0x%x \n", class, class>>8);
-               printk("rc: pci_bus = %d,  pci_device_fn = %d\n", pci_bus, pci_device_fn);
-               printk("rc: pci_irq_line = 0x%x \n", pci_irq_line);
-               printk("rc: pci_ioaddr = 0x%x\n", pci_ioaddr);
-#endif
-
-#if 0
-               if (check_region(pci_ioaddr, 32768))
-               {
-                    printk("rc: check_region failed\n");
-                    continue;
-               }
-               else
-               {
-                    printk("rc: check_region passed\n");
-               }
-#endif
-               
-                /*
-                 * Get and check the bus-master and latency values.
-                 * Some PCI BIOSes fail to set the master-enable bit.
-                 */
-
-                pcibios_read_config_word(pci_bus, 
-                                         pci_device_fn,
-                                         PCI_COMMAND, 
-                                         &pci_command);
-                if ( ! (pci_command & PCI_COMMAND_MASTER)) {
-                     printk("rc: PCI Master Bit has not been set!\n");
-                            
-                     pci_command |= PCI_COMMAND_MASTER;
-                     pcibios_write_config_word(pci_bus, 
-                                               pci_device_fn,
-                                               PCI_COMMAND, 
-                                               pci_command);
-                }
-                if ( ! (pci_command & PCI_COMMAND_MEMORY)) {
-                /*
-                 * If the BIOS did not set the memory enable bit, what else
-                 * did it not initialize?  Skip this adapter.
-                 */
-                     printk("rc: Adapter %d, PCI Memory Bit has not been set!\n",
-                         cards_found);
-                     printk("rc: Bios problem? \n");
-                     continue;
-                }
-                    
-               dev = RCfound_device(dev, pci_ioaddr, pci_irq_line,
-                                    pci_bus, pci_device_fn,
-                                    board_index++, cards_found);
-
-               if (dev) {
-                    dev = 0;
-                    cards_found++;
-               }
-          }
-     }
-     printk("rc: found %d cards \n", cards_found);
-     return cards_found;
+    if (!pcibios_present()) 
+        return cards_found;
+
+    for (;pci_index < 0x8; pci_index++) 
+    {
+        unsigned char pci_bus, pci_device_fn;
+        int scan_status;
+        int board_index = 0;
+        unsigned char pci_irq_line;
+        unsigned short pci_command, vendor, device, class;
+        unsigned int pci_ioaddr;
+
+
+        scan_status =  
+            (pcibios_find_device (RC_PCI45_VENDOR_ID, 
+                                  RC_PCI45_DEVICE_ID, 
+                                  pci_index, 
+                                  &pci_bus, 
+                                  &pci_device_fn));
+#ifdef RCDEBUG
+        printk("rc scan_status = 0x%X\n", scan_status);
+#endif
+        if (scan_status != PCIBIOS_SUCCESSFUL)
+            break;
+        pcibios_read_config_word(pci_bus, 
+                                 pci_device_fn, 
+                                 PCI_VENDOR_ID, &vendor);
+        pcibios_read_config_word(pci_bus, 
+                                 pci_device_fn,
+                                 PCI_DEVICE_ID, &device);
+        pcibios_read_config_byte(pci_bus, 
+                                 pci_device_fn,
+                                 PCI_INTERRUPT_LINE, &pci_irq_line);
+        pcibios_read_config_dword(pci_bus, 
+                                  pci_device_fn,
+                                  PCI_BASE_ADDRESS_0, &pci_ioaddr);
+        pcibios_read_config_word(pci_bus, 
+                                 pci_device_fn,
+                                 PCI_CLASS_DEVICE, &class);
+
+        pci_ioaddr &= ~0xf;
+
+#ifdef RCDEBUG
+        printk("rc: Found RedCreek PCI adapter\n");
+        printk("rc: pci class = 0x%x  0x%x \n", class, class>>8);
+        printk("rc: pci_bus = %d,  pci_device_fn = %d\n", pci_bus, pci_device_fn);
+        printk("rc: pci_irq_line = 0x%x \n", pci_irq_line);
+        printk("rc: pci_ioaddr = 0x%x\n", pci_ioaddr);
+#endif
+
+        if (check_region(pci_ioaddr, 2*32768))
+        {
+            printk("rc: check_region failed\n");
+            continue;
+        }
+#ifdef RCDEBUG
+        else
+        {
+            printk("rc: check_region passed\n");
+        }
+#endif
+           
+        /*
+         * Get and check the bus-master and latency values.
+         * Some PCI BIOSes fail to set the master-enable bit.
+         */
+
+        pcibios_read_config_word(pci_bus, 
+                                 pci_device_fn,
+                                 PCI_COMMAND, 
+                                 &pci_command);
+        if ( ! (pci_command & PCI_COMMAND_MASTER)) {
+            printk("rc: PCI Master Bit has not been set!\n");
+                        
+            pci_command |= PCI_COMMAND_MASTER;
+            pcibios_write_config_word(pci_bus, 
+                                      pci_device_fn,
+                                      PCI_COMMAND, 
+                                      pci_command);
+        }
+        if ( ! (pci_command & PCI_COMMAND_MEMORY)) {
+            /*
+             * If the BIOS did not set the memory enable bit, what else
+             * did it not initialize?  Skip this adapter.
+             */
+            printk("rc: Adapter %d, PCI Memory Bit has not been set!\n",
+                   cards_found);
+            printk("rc: Bios problem? \n");
+            continue;
+        }
+                
+        if (!RCfound_device(dev, pci_ioaddr, pci_irq_line,
+                          pci_bus, pci_device_fn,
+                          board_index++, cards_found))
+        {
+            dev = 0;
+            cards_found++;
+        }
+    }
+#ifdef RCDEBUG
+    printk("rc: found %d cards \n", cards_found);
+#endif
+    return cards_found;
 }
 
-static struct device *
+static int RCinit(struct device *dev)
+{
+    dev->open = &RCopen;
+    dev->hard_start_xmit = &RC_xmit_packet;
+    dev->stop = &RCclose;
+    dev->get_stats = &RCget_stats;
+    dev->do_ioctl = &RCioctl;
+    dev->set_config = &RCconfig;
+    return 0;
+}
+
+static int
 RCfound_device(struct device *dev, int memaddr, int irq, 
                int bus, int function, int product_index, int card_idx)
 {
-     int dev_size = 32768;        
-     unsigned long *vaddr=0;
-     PDPA pDpa;
-     int init_status;
-
-     /* 
-      * Allocate and fill new device structure. 
-      * We need enough for struct device plus DPA plus the LAN API private
-      * area, which requires a minimum of 16KB.  The top of the allocated
-      * area will be assigned to struct device; the next chunk will be
-      * assigned to DPA; and finally, the rest will be assigned to the
-      * the LAN API layer.
-      */
-     dev = (struct device *) kmalloc(dev_size, GFP_DMA | GFP_KERNEL |GFP_ATOMIC);
-     memset(dev, 0, dev_size);
+    int dev_size = 32768;        
+    unsigned long *vaddr=0;
+    PDPA pDpa;
+    int init_status;
+
+    /* 
+     * Allocate and fill new device structure. 
+     * We need enough for struct device plus DPA plus the LAN API private
+     * area, which requires a minimum of 16KB.  The top of the allocated
+     * area will be assigned to struct device; the next chunk will be
+     * assigned to DPA; and finally, the rest will be assigned to the
+     * the LAN API layer.
+     */
+
+#ifdef MODULE
+    dev = (struct device *) kmalloc(dev_size, GFP_DMA | GFP_KERNEL |GFP_ATOMIC);
+    if (!dev)
+    {
+        printk("rc: unable to kmalloc dev\n");
+        return 1;   
+    }
+    memset(dev, 0, dev_size);
+    /*
+     * dev->priv will point to the start of DPA.
+     */
+    dev->priv = (void *)(((long)dev + sizeof(struct device) + 15) & ~15);
+#else
+    dev->priv = 0;
+    dev->priv = (struct device *) kmalloc(dev_size, GFP_DMA | GFP_KERNEL |GFP_ATOMIC);
+    if (!dev->priv)
+    {
+        printk("rc: unable to kmalloc private area\n");
+        return 1;  
+    }
+    memset(dev->priv, 0, dev_size);
+#endif
+
 #ifdef RCDEBUG
-     printk("rc: dev = 0x%08X\n", (uint)dev);
-#endif 
+    printk("rc: dev = 0x%x, dev->priv = 0x%x\n", (uint)dev, (uint)dev->priv);
+#endif
 
-     /*
-      * dev->priv will point to the start of DPA.
-      */
-     dev->priv = (void *)(((long)dev + sizeof(struct device) + 15) & ~15);
-     pDpa = dev->priv;
-     dev->name = pDpa->devname;
-
-     pDpa->dev = dev;            /* this is just for easy reference */
-     pDpa->function = function;
-     pDpa->bus = bus;
-     pDpa->id = card_idx;        /* the device number */
-     pDpa->pci_addr = memaddr;
-     PCIAdapters[card_idx] = pDpa;
-#ifdef RCDEBUG
-     printk("rc: pDpa = 0x%x, id = %d \n", (uint)pDpa, (uint)pDpa->id);
-#endif
-
-     /*
-      * Save the starting address of the LAN API private area.  We'll
-      * pass that to InitRCApiMsgLayer().
-      */
-     pDpa->PLanApiPA = (void *)(((long)pDpa + sizeof(DPA) + 0xff) & ~0xff);
+    pDpa = dev->priv;
+    if (!dev->name)
+        dev->name = pDpa->devname;
+
+    pDpa->dev = dev;            /* this is just for easy reference */
+    pDpa->function = function;
+    pDpa->bus = bus;
+    pDpa->id = card_idx;        /* the device number */
+    pDpa->pci_addr = memaddr;
+    PCIAdapters[card_idx] = pDpa;
 #ifdef RCDEBUG
-     printk("rc: pDpa->PLanApiPA = 0x%x\n", (uint)pDpa->PLanApiPA);
+    printk("rc: pDpa = 0x%x, id = %d \n", (uint)pDpa, (uint)pDpa->id);
 #endif
-    
-     /* The adapter is accessable through memory-access read/write, not
-      * I/O read/write.  Thus, we need to map it to some virtual address
-      * area in order to access the registers are normal memory.
-      */
-     vaddr = (ulong *) vremap (memaddr, 32768);
+
+    /*
+     * Save the starting address of the LAN API private area.  We'll
+     * pass that to RCInitI2OMsgLayer().
+     */
+    pDpa->PLanApiPA = (void *)(((long)pDpa + sizeof(DPA) + 0xff) & ~0xff);
 #ifdef RCDEBUG
-     printk("rc: RCfound_device: 0x%x, priv = 0x%x, vaddr = 0x%x\n", 
-            (uint)dev, (uint)dev->priv, (uint)vaddr);
+    printk("rc: pDpa->PLanApiPA = 0x%x\n", (uint)pDpa->PLanApiPA);
 #endif
-     dev->base_addr = (unsigned long)vaddr;
-     dev->irq = irq;
-     dev->interrupt = 0;
+    
+    /* The adapter is accessable through memory-access read/write, not
+     * I/O read/write.  Thus, we need to map it to some virtual address
+     * area in order to access the registers are normal memory.
+     */
+    vaddr = (ulong *) ioremap (memaddr, 2*32768);
+#ifdef RCDEBUG
+    printk("rc: RCfound_device: 0x%x, priv = 0x%x, vaddr = 0x%x\n", 
+           (uint)dev, (uint)dev->priv, (uint)vaddr);
+#endif
+    dev->base_addr = (unsigned long)vaddr;
+    dev->irq = irq;
+    dev->interrupt = 0;
+
+    /*
+     * Request a shared interrupt line.
+     */
+    if ( request_irq(dev->irq, (void *)RCinterrupt,
+                     SA_INTERRUPT|SA_SHIRQ, "RedCreek VPN Adapter", dev) )
+    {
+        printk( "RC PCI 45: %s: unable to get IRQ %d\n", (PU8)dev->name, (uint)dev->irq );
+        iounmap(vaddr);
+        kfree(dev);
+        return 1;
+    }
 
-     /*
-      * Request a shared interrupt line.
-      */
-     if ( request_irq(dev->irq, (void *)RCinterrupt,
-                      SA_INTERRUPT|SA_SHIRQ, "RedCreek VPN Adapter", dev) )
-     {
-          printk( "RC PCI 45: %s: unable to get IRQ %d\n", (PU8)dev->name, (uint)dev->irq );
-          vfree(vaddr);
-          kfree(dev);
-           return 0;
-     }
-
-     init_status = InitRCApiMsgLayer(pDpa->id, dev->base_addr, 
-                                     pDpa->PLanApiPA, pDpa->PLanApiPA,
-                                     (PFNTXCALLBACK)RCxmit_callback,
-                                     (PFNRXCALLBACK)RCrecv_callback,
-                                     (PFNCALLBACK)RCreboot_callback);
-#ifdef RCDEBUG
-     printk("rc: msg initted: status = 0x%x\n", init_status);
-#endif
-     if (init_status)
-     {
-          printk("rc: Unable to initialize msg layer\n");
-          free_irq(dev->irq, dev);
-          vfree(vaddr);
-          kfree(dev);
-          return 0;
-     }
-     if (RCGetMAC(pDpa->id, dev->dev_addr, NULL))
-     {
-          printk("rc: Unable to get adapter MAC\n");
-          free_irq(dev->irq, dev);
-          vfree(vaddr);
-          kfree(dev);
-          return 0;
-     }
-
-     DriverControlWord |= WARM_REBOOT_CAPABLE;
-     RCReportDriverCapability(pDpa->id, DriverControlWord);
-
-     dev->init = RCprobe1;
-     ether_setup(dev);            /* linux kernel interface */
-
-     pDpa->next = root_RCdev;
-     root_RCdev = dev;
-
-     if (register_netdev(dev) != 0) /* linux kernel interface */
-     {
-          printk("rc: unable to register device \n");
-          free_irq(dev->irq, dev);
-          vfree(vaddr);
-          kfree(dev);
-          return 0;
-     }
-     return dev;
-}
+    init_status = RCInitI2OMsgLayer(pDpa->id, dev->base_addr, 
+                  pDpa->PLanApiPA, (PU8)virt_to_bus((void *)pDpa->PLanApiPA),
+                  (PFNTXCALLBACK)RCxmit_callback,
+                  (PFNRXCALLBACK)RCrecv_callback,
+                  (PFNCALLBACK)RCreboot_callback);
+    if (init_status)
+    {
+        printk("rc: Unable to initialize msg layer\n");
+        free_irq(dev->irq, dev);
+        iounmap(vaddr);
+        kfree(dev);
+        return 1;
+    }
+    if (RCGetMAC(pDpa->id, dev->dev_addr, NULL))
+    {
+        printk("rc: Unable to get adapter MAC\n");
+        free_irq(dev->irq, dev);
+        iounmap(vaddr);
+        kfree(dev);
+        return 1;
+    }
 
-static int RCprobe1(struct device *dev)
-{
-     dev->open = RCopen;
-     dev->hard_start_xmit = RC_xmit_packet;
-     dev->stop = RCclose;
-     dev->get_stats = RCget_stats;
-     dev->do_ioctl = RCioctl;
-     dev->set_config = RCconfig;
-     return 0;
+    DriverControlWord |= WARM_REBOOT_CAPABLE;
+    RCReportDriverCapability(pDpa->id, DriverControlWord);
+
+    dev->init = &RCinit;
+    ether_setup(dev);            /* linux kernel interface */
+
+    pDpa->next = root_RCdev;
+    root_RCdev = dev;
+
+#ifdef MODULE
+    if (register_netdev(dev) != 0) /* linux kernel interface */
+    {
+        printk("rc: unable to register device \n");
+        free_irq(dev->irq, dev);
+        iounmap(vaddr);
+        kfree(dev);
+        return 1;
+    }
+#else
+    RCinit(dev);
+#endif
+    printk("%s: RedCreek Communications IPSEC VPN adapter\n",
+        dev->name);
+
+    return 0; /* success */
 }
 
 static int
@@ -438,25 +471,25 @@
 #ifdef RCDEBUG
     printk("rc: RCopen\n");
 #endif
-    RCEnableAdapterInterrupts(pDpa->id);
+    RCEnableI2OInterrupts(pDpa->id);
 
     if (pDpa->nexus)
     {
-       /* This is not the first time RCopen is called.  Thus,
-        * the interface was previously opened and later closed
-        * by RCclose().  RCclose() does a Shutdown; to wake up
-        * the adapter, a reset is mandatory before we can post
-        * receive buffers.  However, if the adapter initiated 
-        * a reboot while the interface was closed -- and interrupts
-        * were turned off -- we need will need to reinitialize
-        * the adapter, rather than simply waking it up.  
-        */
+        /* This is not the first time RCopen is called.  Thus,
+         * the interface was previously opened and later closed
+         * by RCclose().  RCclose() does a Shutdown; to wake up
+         * the adapter, a reset is mandatory before we can post
+         * receive buffers.  However, if the adapter initiated 
+         * a reboot while the interface was closed -- and interrupts
+         * were turned off -- we need will need to reinitialize
+         * the adapter, rather than simply waking it up.  
+         */
         printk("rc: Waking up adapter...\n");
         RCResetLANCard(pDpa->id,0,0,0);
     }
     else
     {
-       pDpa->nexus = 1;
+        pDpa->nexus = 1;
     }
 
     while(post_buffers)
@@ -469,19 +502,19 @@
 
         if ( count < requested )
         {
-             /*
-              * Check to see if we were able to post any buffers at all.
-              */
-             if (post_buffers == MAX_NMBR_RCV_BUFFERS)
-             {
-                  printk("rc: Error RCopen: not able to allocate any buffers\r\n");
-                  return(-ENOMEM);                    
-             }
-             printk("rc: Warning RCopen: not able to allocate all requested buffers\r\n");
-             break;            /* we'll try to post more buffers later */
+            /*
+             * Check to see if we were able to post any buffers at all.
+             */
+            if (post_buffers == MAX_NMBR_RCV_BUFFERS)
+            {
+                printk("rc: Error RCopen: not able to allocate any buffers\r\n");
+                return(-ENOMEM);                    
+            }
+            printk("rc: Warning RCopen: not able to allocate all requested buffers\r\n");
+            break;            /* we'll try to post more buffers later */
         }
         else
-             post_buffers -= count;
+            post_buffers -= count;
     }
     pDpa->numOutRcvBuffers = MAX_NMBR_RCV_BUFFERS - post_buffers;
     pDpa->shutdown = 0;        /* just in case */
@@ -496,68 +529,70 @@
 RC_xmit_packet(struct sk_buff *skb, struct device *dev)
 {
 
-     PDPA pDpa = (PDPA) dev->priv;
-     singleTCB tcb;
-     psingleTCB ptcb = &tcb;
-     RC_RETURN status = 0;
+    PDPA pDpa = (PDPA) dev->priv;
+    singleTCB tcb;
+    psingleTCB ptcb = &tcb;
+    RC_RETURN status = 0;
     
-     if (dev->tbusy || pDpa->shutdown || pDpa->reboot)
-     {
+        if (dev->tbusy || pDpa->shutdown || pDpa->reboot)
+        {
 #ifdef RCDEBUG
-          printk("rc: RC_xmit_packet: tbusy!\n");
+            printk("rc: RC_xmit_packet: tbusy!\n");
 #endif
-          return 1;
-     }
+            dev->tbusy = 1;
+            return 1;
+        }
       
-     if ( skb->len <= 0 ) 
-     {
-          printk("RC_xmit_packet: skb->len less than 0!\n");
-          return 0;
-     }
-
-     /*
-      * The user is free to reuse the TCB after RCSendPacket() returns, since
-      * the function copies the necessary info into its own private space.  Thus,
-      * our TCB can be a local structure.  The skb, on the other hand, will be
-      * freed up in our interrupt handler.
-      */
-     ptcb->bcount = 1;
-     /* 
-      * we'll get the context when the adapter interrupts us to tell us that
-      * the transmision is done. At that time, we can free skb.
-      */
-     ptcb->b.context = (U32)skb;    
-     ptcb->b.scount = 1;
-     ptcb->b.size = skb->len;
-     ptcb->b.addr = (U32)skb->data;
-
-#ifdef RCDEBUG
-     printk("rc: RC xmit: skb = 0x%x, pDpa = 0x%x, id = %d, ptcb = 0x%x\n", 
-            (uint)skb, (uint)pDpa, (uint)pDpa->id, (uint)ptcb);
-#endif
-     if ( (status = RCSendPacket(pDpa->id, (U32)NULL, (PRCTCB)ptcb))
-          != RC_RTN_NO_ERROR)
-     {
-#ifdef RCDEBUG
-          printk("rc: RC send error 0x%x\n", (uint)status);
-#endif
-          dev->tbusy = 1;
-     }
-     else
-     {
-          dev->trans_start = jiffies;
-          //       dev->tbusy = 0;
-     }
-     /*
-      * That's it!
-      */
-     return 0;
+    if ( skb->len <= 0 ) 
+    {
+        printk("RC_xmit_packet: skb->len less than 0!\n");
+        return 0;
+    }
+
+    /*
+     * The user is free to reuse the TCB after RCI2OSendPacket() returns, since
+     * the function copies the necessary info into its own private space.  Thus,
+     * our TCB can be a local structure.  The skb, on the other hand, will be
+     * freed up in our interrupt handler.
+     */
+    ptcb->bcount = 1;
+    /* 
+     * we'll get the context when the adapter interrupts us to tell us that
+     * the transmision is done. At that time, we can free skb.
+     */
+    ptcb->b.context = (U32)skb;    
+    ptcb->b.scount = 1;
+    ptcb->b.size = skb->len;
+    ptcb->b.addr = virt_to_bus((void *)skb->data);
+
+#ifdef RCDEBUG
+    printk("rc: RC xmit: skb = 0x%x, pDpa = 0x%x, id = %d, ptcb = 0x%x\n", 
+           (uint)skb, (uint)pDpa, (uint)pDpa->id, (uint)ptcb);
+#endif
+    if ( (status = RCI2OSendPacket(pDpa->id, (U32)NULL, (PRCTCB)ptcb))
+         != RC_RTN_NO_ERROR)
+    {
+#ifdef RCDEBUG
+        printk("rc: RC send error 0x%x\n", (uint)status);
+#endif
+        dev->tbusy = 1;
+        return 1;
+    }
+    else
+    {
+        dev->trans_start = jiffies;
+        //       dev->tbusy = 0;
+    }
+    /*
+     * That's it!
+     */
+    return 0;
 }
 
 /*
  * RCxmit_callback()
  *
- * The transmit callback routine. It's called by RCProcMsgQ()
+ * The transmit callback routine. It's called by RCProcI2OMsgQ()
  * because the adapter is done with one or more transmit buffers and
  * it's returning them to us, or we asked the adapter to return the
  * outstanding transmit buffers by calling RCResetLANCard() with 
@@ -574,80 +609,84 @@
     PDPA pDpa;
     struct device *dev;
 
-    pDpa = PCIAdapters[AdapterID];
-    if (!pDpa)
-    {
-        printk("rc: Fatal error: xmit callback, !pDpa\n");
-        return;
-    }
-    dev = pDpa->dev;
+        pDpa = PCIAdapters[AdapterID];
+        if (!pDpa)
+        {
+            printk("rc: Fatal error: xmit callback, !pDpa\n");
+            return;
+        }
+        dev = pDpa->dev;
 
         // printk("xmit_callback: Status = 0x%x\n", (uint)Status);
-    if (Status != RC_REPLY_STATUS_SUCCESS)
-    {
-        printk("rc: xmit_callback: Status = 0x%x\n", (uint)Status);
-    }
+        if (Status != I2O_REPLY_STATUS_SUCCESS)
+        {
+            printk("rc: xmit_callback: Status = 0x%x\n", (uint)Status);
+        }
 #ifdef RCDEBUG
-    if (pDpa->shutdown || pDpa->reboot)
-        printk("rc: xmit callback: shutdown||reboot\n");
+        if (pDpa->shutdown || pDpa->reboot)
+            printk("rc: xmit callback: shutdown||reboot\n");
 #endif
 
 #ifdef RCDEBUG     
-    printk("rc: xmit_callback: PcktCount = %d, BC = 0x%x\n", 
-            (uint)PcktCount, (uint)BufferContext);
+        printk("rc: xmit_callback: PcktCount = %d, BC = 0x%x\n", 
+               (uint)PcktCount, (uint)BufferContext);
 #endif
-    while (PcktCount--)
-    {
-        skb = (struct sk_buff *)(BufferContext[0]);
+        while (PcktCount--)
+        {
+            skb = (struct sk_buff *)(BufferContext[0]);
 #ifdef RCDEBUG
-        printk("rc: skb = 0x%x\n", (uint)skb);
+            printk("rc: skb = 0x%x\n", (uint)skb);
 #endif
-        BufferContext++;
-        dev_kfree_skb (skb, FREE_WRITE);
-    }
-    dev->tbusy = 0;
+            BufferContext++;
+#ifdef LINUX_2_1
+            dev_kfree_skb (skb);
+#else
+            dev_kfree_skb (skb, FREE_WRITE);
+#endif
+        }
+        dev->tbusy = 0;
 
 }
 
 static void
 RCreset_callback(U32 Status, U32 p1, U32 p2, U16 AdapterID)
 {
-     PDPA pDpa;
-     struct device *dev;
+    PDPA pDpa;
+    struct device *dev;
      
-     pDpa = PCIAdapters[AdapterID];
-     dev = pDpa->dev;
+    pDpa = PCIAdapters[AdapterID];
+    dev = pDpa->dev;
 #ifdef RCDEBUG
-      printk("rc: RCreset_callback Status 0x%x\n", (uint)Status);
+    printk("rc: RCreset_callback Status 0x%x\n", (uint)Status);
 #endif
-      /*
-       * Check to see why we were called.
-       */
-      if (pDpa->shutdown)
-      {
-           printk("rc: Shutting down interface\n");
-           pDpa->shutdown = 0;
-           pDpa->reboot = 0;
-           MOD_DEC_USE_COUNT; 
-      }
-      else if (pDpa->reboot)
-      {
-           printk("rc: reboot, shutdown adapter\n");
-           /*
-            * We don't set any of the flags in RCShutdownLANCard()
-            * and we don't pass a callback routine to it.
-            * The adapter will have already initiated the reboot by
-            * the time the function returns.
-            */
-		   RCDisableAdapterInterrupts(pDpa->id);
-           RCShutdownLANCard(pDpa->id,0,0,0);
-           printk("rc: scheduling timer...\n");
-           init_timer(&pDpa->timer);
-           pDpa->timer.expires = RUN_AT((30*HZ)/10); /* 3 sec. */
-           pDpa->timer.data = (unsigned long)dev;
-           pDpa->timer.function = &rc_timer;    /* timer handler */
-           add_timer(&pDpa->timer);
-      }
+    /*
+     * Check to see why we were called.
+     */
+    if (pDpa->shutdown)
+    {
+        printk("rc: Shutting down interface\n");
+        pDpa->shutdown = 0;
+        pDpa->reboot = 0;
+        MOD_DEC_USE_COUNT; 
+    }
+    else if (pDpa->reboot)
+    {
+        printk("rc: reboot, shutdown adapter\n");
+        /*
+         * We don't set any of the flags in RCShutdownLANCard()
+         * and we don't pass a callback routine to it.
+         * The adapter will have already initiated the reboot by
+         * the time the function returns.
+         */
+        RCDisableI2OInterrupts(pDpa->id);
+        RCShutdownLANCard(pDpa->id,0,0,0);
+        printk("rc: scheduling timer...\n");
+        init_timer(&pDpa->timer);
+        pDpa->timer.expires = RUN_AT((40*HZ)/10); /* 4 sec. */
+        pDpa->timer.data = (unsigned long)dev;
+        pDpa->timer.function = &rc_timer;    /* timer handler */
+        add_timer(&pDpa->timer);
+    }
 
 
 
@@ -656,33 +695,33 @@
 static void
 RCreboot_callback(U32 Status, U32 p1, U32 p2, U16 AdapterID)
 {
-     PDPA pDpa;
+    PDPA pDpa;
     
-     pDpa = PCIAdapters[AdapterID];
+    pDpa = PCIAdapters[AdapterID];
 #ifdef RCDEBUG
-     printk("rc: RCreboot: rcv buffers outstanding = %d\n", 
-            (uint)pDpa->numOutRcvBuffers);
+    printk("rc: RCreboot: rcv buffers outstanding = %d\n", 
+           (uint)pDpa->numOutRcvBuffers);
 #endif
-     if (pDpa->shutdown)
-     {
-          printk("rc: skipping reboot sequence -- shutdown already initiated\n");
-          return;
-     }
-     pDpa->reboot = 1;
-     /*
-      * OK, we reset the adapter and ask it to return all
-      * outstanding transmit buffers as well as the posted
-      * receive buffers.  When the adapter is done returning
-      * those buffers, it will call our RCreset_callback() 
-      * routine.  In that routine, we'll call RCShutdownLANCard()
-      * to tell the adapter that it's OK to start the reboot and
-      * schedule a timer callback routine to execute 3 seconds 
-      * later; this routine will reinitialize the adapter at that time.
-      */
-     RCResetLANCard(pDpa->id, 
-                    RC_RESOURCE_RETURN_POSTED_RX_BUCKETS | 
-                    RC_RESOURCE_RETURN_PEND_TX_BUFFERS,0,
-                    (PFNCALLBACK)RCreset_callback);
+    if (pDpa->shutdown)
+    {
+        printk("rc: skipping reboot sequence -- shutdown already initiated\n");
+        return;
+    }
+    pDpa->reboot = 1;
+    /*
+     * OK, we reset the adapter and ask it to return all
+     * outstanding transmit buffers as well as the posted
+     * receive buffers.  When the adapter is done returning
+     * those buffers, it will call our RCreset_callback() 
+     * routine.  In that routine, we'll call RCShutdownLANCard()
+     * to tell the adapter that it's OK to start the reboot and
+     * schedule a timer callback routine to execute 3 seconds 
+     * later; this routine will reinitialize the adapter at that time.
+     */
+    RCResetLANCard(pDpa->id, 
+                   RC_RESOURCE_RETURN_POSTED_RX_BUCKETS | 
+                   RC_RESOURCE_RETURN_PEND_TX_BUFFERS,0,
+                   (PFNCALLBACK)RCreset_callback);
 }
 
 
@@ -699,7 +738,7 @@
  * RCrecv_callback()
  * 
  * The receive packet callback routine.  This is called by
- * RCProcMsgQ() after the adapter posts buffers which have been
+ * RCProcI2OMsgQ() after the adapter posts buffers which have been
  * filled (one ethernet packet per buffer).
  */
 static void
@@ -710,134 +749,149 @@
                 U16  AdapterID)
 {
 
-     U32 len, count;
-     PDPA pDpa;
-     struct sk_buff *skb;
-     struct device *dev;
-     singleTCB tcb;
-     psingleTCB ptcb = &tcb;
+    U32 len, count;
+    PDPA pDpa;
+    struct sk_buff *skb;
+    struct device *dev;
+    singleTCB tcb;
+    psingleTCB ptcb = &tcb;
 
 
-          pDpa = PCIAdapters[AdapterID];
-          dev = pDpa->dev;
+        pDpa = PCIAdapters[AdapterID];
+        dev = pDpa->dev;
 
-          ptcb->bcount = 1;
+        ptcb->bcount = 1;
 
 #ifdef RCDEBUG
-          printk("rc: RCrecv_callback: 0x%x, 0x%x, 0x%x\n",
-                 (uint)PktCount, (uint)BucketsRemain, (uint)PacketDescBlock);
+        printk("rc: RCrecv_callback: 0x%x, 0x%x, 0x%x\n",
+               (uint)PktCount, (uint)BucketsRemain, (uint)PacketDescBlock);
 #endif
         
 #ifdef RCDEBUG
-          if ((pDpa->shutdown || pDpa->reboot) && !Status)
-               printk("shutdown||reboot && !Status: PktCount = %d\n",PktCount);
+        if ((pDpa->shutdown || pDpa->reboot) && !Status)
+            printk("shutdown||reboot && !Status: PktCount = %d\n",PktCount);
 #endif
 
-          if ( (Status != RC_REPLY_STATUS_SUCCESS) || pDpa->shutdown)
-          {
-               /*
-                * Free whatever buffers the adapter returned, but don't
-                * pass them to the kernel.
-                */
+        if ( (Status != I2O_REPLY_STATUS_SUCCESS) || pDpa->shutdown)
+        {
+            /*
+             * Free whatever buffers the adapter returned, but don't
+             * pass them to the kernel.
+             */
         
-                    if (!pDpa->shutdown && !pDpa->reboot)
-                         printk("rc: RCrecv error: status = 0x%x\n", (uint)Status);
-                    else
-                         printk("rc: Returning %d buffers, status = 0x%x\n", 
-                                PktCount, (uint)Status);
-               /*
-                * TO DO: check the nature of the failure and put the adapter in
-                * failed mode if it's a hard failure.  Send a reset to the adapter
-                * and free all outstanding memory.
-                */
-               if (Status == RC_REPLY_STATUS_ABORT_NO_DATA_TRANSFER)
-               {
-#ifdef RCDEBUG
-                    printk("RCrecv status ABORT NO DATA TRANSFER\n");
-#endif
-               }
-               /* check for reset status: RC_REPLY_STATUS_ABORT_NO_DATA_TRANSFER */ 
-               if (PacketDescBlock)
-               {
-                    while(PktCount--)
-                    {
-                         skb = (struct sk_buff *)PacketDescBlock[0];
-                         skb->free = 1;
-                         skb->lock = 0;    
-#ifdef RCDEBUG
-                         printk("free skb 0x%p\n", skb);
-#endif
-                         dev_kfree_skb(skb, FREE_READ);
-                         pDpa->numOutRcvBuffers--;
-                         PacketDescBlock += BD_SIZE; /* point to next context field */
-                    }
-               }
-               return;
-          }
-          else
-          {
-               while(PktCount--)
-               {
+                if (!pDpa->shutdown && !pDpa->reboot)
+                    printk("rc: RCrecv error: status = 0x%x\n", (uint)Status);
+#ifdef RCDEBUG
+                else
+                    printk("rc: Returning %d buffers, status = 0x%x\n", 
+                           PktCount, (uint)Status);
+#endif
+            /*
+             * TO DO: check the nature of the failure and put the adapter in
+             * failed mode if it's a hard failure.  Send a reset to the adapter
+             * and free all outstanding memory.
+             */
+            if (Status == I2O_REPLY_STATUS_ABORT_NO_DATA_TRANSFER)
+            {
+#ifdef RCDEBUG
+                printk("RCrecv status ABORT NO DATA TRANSFER\n");
+#endif
+            }
+            /* check for reset status: I2O_REPLY_STATUS_ABORT_NO_DATA_TRANSFER */ 
+            if (PacketDescBlock)
+            {
+                while(PktCount--)
+                {
                     skb = (struct sk_buff *)PacketDescBlock[0];
+#ifndef LINUX_2_1
+                    skb->free = 1;
+                    skb->lock = 0;    
+#endif
 #ifdef RCDEBUG
-                    if (pDpa->shutdown)
-                         printk("shutdown: skb=0x%x\n", (uint)skb);
-
-                    printk("skb = 0x%x: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", (uint)skb,
-                           (uint)skb->data[0], (uint)skb->data[1], (uint)skb->data[2],
-                           (uint)skb->data[3], (uint)skb->data[4], (uint)skb->data[5]);
+                    printk("free skb 0x%p\n", skb);
+#endif
+#ifdef LINUX_2_1
+                    dev_kfree_skb (skb);
+#else
+                    dev_kfree_skb(skb, FREE_READ);
 #endif
-                    if ( (memcmp(dev->dev_addr, skb->data, 6)) &&
-                         (!broadcast_packet(skb->data)))
+                    pDpa->numOutRcvBuffers--;
+                    PacketDescBlock += BD_SIZE; /* point to next context field */
+                }
+            }
+            return;
+        }
+        else
+        {
+            while(PktCount--)
+            {
+                skb = (struct sk_buff *)PacketDescBlock[0];
+#ifdef RCDEBUG
+                if (pDpa->shutdown)
+                    printk("shutdown: skb=0x%x\n", (uint)skb);
+
+                printk("skb = 0x%x: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", (uint)skb,
+                       (uint)skb->data[0], (uint)skb->data[1], (uint)skb->data[2],
+                       (uint)skb->data[3], (uint)skb->data[4], (uint)skb->data[5]);
+#endif
+
+#ifdef PROMISCUOUS_BY_DEFAULT   /* early 2.x firmware */
+                if ( (memcmp(dev->dev_addr, skb->data, 6)) &&
+                     (!broadcast_packet(skb->data)))
+                {
+                    /*
+                     * Re-post the buffer to the adapter.  Since the adapter usually
+                     * return 1 to 2 receive buffers at a time, it's not too inefficient
+                     * post one buffer at a time but ... may be that should be 
+                     * optimized at some point.
+                     */
+                    ptcb->b.context = (U32)skb;    
+                    ptcb->b.scount = 1;
+                    ptcb->b.size = MAX_ETHER_SIZE;
+                    ptcb->b.addr = virt_to_bus((void *)skb->data);
+
+                    if ( RCPostRecvBuffers(pDpa->id, (PRCTCB)ptcb ) != RC_RTN_NO_ERROR)
                     {
-                         /*
-                          * Re-post the buffer to the adapter.  Since the adapter usually
-                          * return 1 to 2 receive buffers at a time, it's not too inefficient
-                          * post one buffer at a time but ... may be that should be 
-                          * optimized at some point.
-                          */
-                         ptcb->b.context = (U32)skb;    
-                         ptcb->b.scount = 1;
-                         ptcb->b.size = MAX_ETHER_SIZE;
-                         ptcb->b.addr = (U32)skb->data;
-
-                         if ( RCPostRecvBuffers(pDpa->id, (PRCTCB)ptcb ) != RC_RTN_NO_ERROR)
-                         {
-                              printk("rc: RCrecv_callback: post buffer failed!\n");
-                              skb->free = 1;
-                              dev_kfree_skb(skb, FREE_READ);
-                         }
-                         else
-                         {
-                              pDpa->numOutRcvBuffers++;
-                         }
+                        printk("rc: RCrecv_callback: post buffer failed!\n");
+#ifdef LINUX_2_1
+                        dev_kfree_skb (skb);
+#else
+                        skb->free = 1;
+                        dev_kfree_skb(skb, FREE_READ);
+#endif
                     }
                     else
                     {
-                         len = PacketDescBlock[2];
-                         skb->dev = dev;
-                         skb_put( skb, len ); /* adjust length and tail */
-                         skb->protocol = eth_type_trans(skb, dev);
-                         netif_rx(skb);    /* send the packet to the kernel */
-                         dev->last_rx = jiffies;
+                        pDpa->numOutRcvBuffers++;
                     }
-                    pDpa->numOutRcvBuffers--;
-                    PacketDescBlock += BD_SIZE; /* point to next context field */
-               }
-          } 
+                }
+                else
+#endif /* PROMISCUOUS_BY_DEFAULT */
+                {
+                    len = PacketDescBlock[2];
+                    skb->dev = dev;
+                    skb_put( skb, len ); /* adjust length and tail */
+                    skb->protocol = eth_type_trans(skb, dev);
+                    netif_rx(skb);    /* send the packet to the kernel */
+                    dev->last_rx = jiffies;
+                }
+                pDpa->numOutRcvBuffers--;
+                PacketDescBlock += BD_SIZE; /* point to next context field */
+            }
+        } 
     
-          /*
-           * Replenish the posted receive buffers. 
-           * DO NOT replenish buffers if the driver has already
-           * initiated a reboot or shutdown!
-           */
-
-          if (!pDpa->shutdown && !pDpa->reboot)
-          {
-               count = RC_allocate_and_post_buffers(dev, 
-                                                    MAX_NMBR_RCV_BUFFERS-pDpa->numOutRcvBuffers);
-               pDpa->numOutRcvBuffers += count;
-          }
+        /*
+         * Replenish the posted receive buffers. 
+         * DO NOT replenish buffers if the driver has already
+         * initiated a reboot or shutdown!
+         */
+
+        if (!pDpa->shutdown && !pDpa->reboot)
+        {
+            count = RC_allocate_and_post_buffers(dev, 
+                                                 MAX_NMBR_RCV_BUFFERS-pDpa->numOutRcvBuffers);
+            pDpa->numOutRcvBuffers += count;
+        }
 
 }
 
@@ -846,156 +900,159 @@
  * 
  * Interrupt handler. 
  * This routine sets up a couple of pointers and calls
- * RCProcMsgQ(), which in turn process the message and
+ * RCProcI2OMsgQ(), which in turn process the message and
  * calls one of our callback functions.
  */
 static void 
 RCinterrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
 
-     PDPA pDpa;
-     struct device *dev = (struct device *)(dev_id);
+    PDPA pDpa;
+    struct device *dev = (struct device *)(dev_id);
 
-     pDpa = (PDPA) (dev->priv);
+    pDpa = (PDPA) (dev->priv);
      
-     if (pDpa->shutdown)
-          printk("rc: shutdown: service irq\n");
-
 #ifdef RCDEBUG
-     printk("RC irq: pDpa = 0x%x, dev = 0x%x, id = %d\n", 
-            (uint)pDpa, (uint)dev, (uint)pDpa->id);
-     printk("dev = 0x%x\n", (uint)dev);
+    if (pDpa->shutdown)
+        printk("rc: shutdown: service irq\n");
+
+    printk("RC irq: pDpa = 0x%x, dev = 0x%x, id = %d\n", 
+           (uint)pDpa, (uint)dev, (uint)pDpa->id);
+    printk("dev = 0x%x\n", (uint)dev);
 #endif
-     if (dev->interrupt)
-          printk("%s: Re-entering the interrupt handler.\n", dev->name);
-     dev->interrupt = 1;
+    if (dev->interrupt)
+        printk("%s: Re-entering the interrupt handler.\n", dev->name);
+    dev->interrupt = 1;
 
-     RCProcMsgQ(pDpa->id);
-     dev->interrupt = 0;
+    RCProcI2OMsgQ(pDpa->id);
+    dev->interrupt = 0;
 
-     return;
+    return;
 }
 
-#define REBOOT_REINIT_RETRY_LIMIT 10
+
+#define REBOOT_REINIT_RETRY_LIMIT 4
 static void rc_timer(unsigned long data)
 {
-     struct device *dev = (struct device *)data;
-     PDPA pDpa = (PDPA) (dev->priv);
-     int init_status;
-     static int retry = 0;
-     int post_buffers = MAX_NMBR_RCV_BUFFERS;
-     int count = 0;
-     int requested = 0;
-
-     if (pDpa->reboot)
-     {
-
-          init_status = InitRCApiMsgLayer(pDpa->id, dev->base_addr, 
-                                          pDpa->PLanApiPA, pDpa->PLanApiPA,
-                                          (PFNTXCALLBACK)RCxmit_callback,
-                                          (PFNRXCALLBACK)RCrecv_callback,
-                                          (PFNCALLBACK)RCreboot_callback);
-
-          switch(init_status)
-          {
-          case RC_RTN_NO_ERROR:
+    struct device *dev = (struct device *)data;
+    PDPA pDpa = (PDPA) (dev->priv);
+    int init_status;
+    static int retry = 0;
+    int post_buffers = MAX_NMBR_RCV_BUFFERS;
+    int count = 0;
+    int requested = 0;
+
+    if (pDpa->reboot)
+    {
+        init_status = RCInitI2OMsgLayer(pDpa->id, dev->base_addr, 
+                                    pDpa->PLanApiPA, 
+                                    (PU8)virt_to_bus((void *)pDpa->PLanApiPA),
+                                    (PFNTXCALLBACK)RCxmit_callback,
+                                    (PFNRXCALLBACK)RCrecv_callback,
+                                    (PFNCALLBACK)RCreboot_callback);
+
+        switch(init_status)
+        {
+        case RC_RTN_NO_ERROR:
  
-               pDpa->reboot = 0;
-               pDpa->shutdown = 0;        /* just in case */
-               RCReportDriverCapability(pDpa->id, DriverControlWord);
-               RCEnableAdapterInterrupts(pDpa->id);
-
-               if (dev->flags & IFF_UP)
-               {
-                    while(post_buffers)
-                    {
-                         if (post_buffers > MAX_NMBR_POST_BUFFERS_PER_MSG)
-                              requested = MAX_NMBR_POST_BUFFERS_PER_MSG;
-                         else
-                              requested = post_buffers;
-                         count = RC_allocate_and_post_buffers(dev, requested);
-                         post_buffers -= count;
-                         if ( count < requested )
-                              break;
-                    }
-                    pDpa->numOutRcvBuffers = 
-                         MAX_NMBR_RCV_BUFFERS - post_buffers;
-                    printk("rc: posted %d buffers \r\n", 
-                           (uint)pDpa->numOutRcvBuffers);
-               }
-               printk("rc: Initialization done.\n");
-               return;
-          case RC_RTN_FREE_Q_EMPTY:
-               retry++;
-               printk("rc: inbound free q emtpy\n");
-               break;
-          default:
-               retry++;
-               printk("rc: unexpected bad status after reboot\n");    
-               break;
-          }
-
-          if (retry > REBOOT_REINIT_RETRY_LIMIT)
-          {
-               printk("rc: unable to reinitialize adapter after reboot\n");
-               printk("rc: decrementing driver and closing interface\n");
-               RCDisableAdapterInterrupts(pDpa->id);
-               dev->flags &= ~IFF_UP;
-               MOD_DEC_USE_COUNT; 
-          }
-          else
-          {
-               printk("rc: rescheduling timer...\n");
-               init_timer(&pDpa->timer);
-               pDpa->timer.expires = RUN_AT((30*HZ)/10); /* 3 sec. */
-               pDpa->timer.data = (unsigned long)dev;
-               pDpa->timer.function = &rc_timer;    /* timer handler */
-               add_timer(&pDpa->timer);
-          }
-     }
-     else
-     {
-          printk("rc: timer??\n");
-     }
+            pDpa->reboot = 0;
+            pDpa->shutdown = 0;        /* just in case */
+            RCReportDriverCapability(pDpa->id, DriverControlWord);
+            RCEnableI2OInterrupts(pDpa->id);
+
+            if (dev->flags & IFF_UP)
+            {
+                while(post_buffers)
+                {
+                    if (post_buffers > MAX_NMBR_POST_BUFFERS_PER_MSG)
+                        requested = MAX_NMBR_POST_BUFFERS_PER_MSG;
+                    else
+                        requested = post_buffers;
+                    count = RC_allocate_and_post_buffers(dev, requested);
+                    post_buffers -= count;
+                    if ( count < requested )
+                        break;
+                }
+                pDpa->numOutRcvBuffers = 
+                    MAX_NMBR_RCV_BUFFERS - post_buffers;
+                printk("rc: posted %d buffers \r\n", 
+                       (uint)pDpa->numOutRcvBuffers);
+            }
+            printk("rc: Initialization done.\n");
+            dev->tbusy=0;
+            retry=0;
+            return;
+        case RC_RTN_FREE_Q_EMPTY:
+            retry++;
+            printk("rc: inbound free q empty\n");
+            break;
+        default:
+            retry++;
+            printk("rc: bad status after reboot: %d\n", init_status);    
+            break;
+        }
+
+        if (retry > REBOOT_REINIT_RETRY_LIMIT)
+        {
+            printk("rc: unable to reinitialize adapter after reboot\n");
+            printk("rc: decrementing driver and closing interface\n");
+            RCDisableI2OInterrupts(pDpa->id);
+            dev->flags &= ~IFF_UP;
+            MOD_DEC_USE_COUNT; 
+        }
+        else
+        {
+            printk("rc: rescheduling timer...\n");
+            init_timer(&pDpa->timer);
+            pDpa->timer.expires = RUN_AT((40*HZ)/10); /* 3 sec. */
+            pDpa->timer.data = (unsigned long)dev;
+            pDpa->timer.function = &rc_timer;    /* timer handler */
+            add_timer(&pDpa->timer);
+        }
+    }
+    else
+    {
+        printk("rc: timer??\n");
+    }
 }
 
 static int
 RCclose(struct device *dev)
 {
 
-     PDPA pDpa = (PDPA) dev->priv;
+    PDPA pDpa = (PDPA) dev->priv;
 
 #ifdef RCDEBUG
-     printk("rc: RCclose\r\n");
+    printk("rc: RCclose\r\n");
 #endif
-     if (pDpa->reboot)
-     {
-          printk("rc: skipping reset -- adapter already in reboot mode\n");
-          dev->flags &= ~IFF_UP;
-          pDpa->shutdown = 1;
-          return 0;
-     }
+    if (pDpa->reboot)
+    {
+        printk("rc: skipping reset -- adapter already in reboot mode\n");
+        dev->flags &= ~IFF_UP;
+        pDpa->shutdown = 1;
+        return 0;
+    }
 #ifdef RCDEBUG
-     printk("rc: receive buffers outstanding: %d\n", 
-            (uint)pDpa->numOutRcvBuffers);
+    printk("rc: receive buffers outstanding: %d\n", 
+           (uint)pDpa->numOutRcvBuffers);
 #endif
 
-     pDpa->shutdown = 1;
+    pDpa->shutdown = 1;
 
-     /*
-      * We can't allow the driver to be unloaded until the adapter returns
-      * all posted receive buffers.  It doesn't hurt to tell the adapter
-      * to return all posted receive buffers and outstanding xmit buffers,
-      * even if there are none.
-      */
+    /*
+     * We can't allow the driver to be unloaded until the adapter returns
+     * all posted receive buffers.  It doesn't hurt to tell the adapter
+     * to return all posted receive buffers and outstanding xmit buffers,
+     * even if there are none.
+     */
 
-     RCShutdownLANCard(pDpa->id, 
-                       RC_RESOURCE_RETURN_POSTED_RX_BUCKETS | 
-                       RC_RESOURCE_RETURN_PEND_TX_BUFFERS,0,
-                       (PFNCALLBACK)RCreset_callback);
+    RCShutdownLANCard(pDpa->id, 
+                      RC_RESOURCE_RETURN_POSTED_RX_BUCKETS | 
+                      RC_RESOURCE_RETURN_PEND_TX_BUFFERS,0,
+                      (PFNCALLBACK)RCreset_callback);
 
-     dev->flags &= ~IFF_UP;
-     return 0;
+        dev->flags &= ~IFF_UP;
+    return 0;
 }
 
 static struct enet_statistics *
@@ -1097,140 +1154,200 @@
  
     switch (cmd)  {
  
-        case RCU_PROTOCOL_REV:
-             /*
-              * Assign user protocol revision, to tell user-level
-              * controller program whether or not it's in sync.
-              */
-             rq->ifr_ifru.ifru_data = (caddr_t) USER_PROTOCOL_REV;
-             break;
+    case RCU_PROTOCOL_REV:
+        /*
+         * Assign user protocol revision, to tell user-level
+         * controller program whether or not it's in sync.
+         */
+        rq->ifr_ifru.ifru_data = (caddr_t) USER_PROTOCOL_REV;
+        break;
   
 
-        case RCU_COMMAND:
-        {
-            int error;
-
-            error=verify_area(VERIFY_WRITE, rq->ifr_data, sizeof(RCuser));
-            if (error)  {
-                return error;
-            }
-            memcpy_fromfs(&RCuser, rq->ifr_data, sizeof(RCuser));
+    case RCU_COMMAND:
+    {
+#ifdef LINUX_2_1
+        if(copy_from_user(&RCuser, rq->ifr_data, sizeof(RCuser)))
+             return -EFAULT;
+#else
+        int error;
+        error=verify_area(VERIFY_WRITE, rq->ifr_data, sizeof(RCuser));
+        if (error)  {
+            return error;
+        }
+        memcpy_fromfs(&RCuser, rq->ifr_data, sizeof(RCuser));
+#endif
         
 #ifdef RCDEBUG
-            printk("RCioctl: RCuser_cmd = 0x%x\n", RCuser.cmd);
+        printk("RCioctl: RCuser_cmd = 0x%x\n", RCuser.cmd);
 #endif
   
-            switch(RCuser.cmd)
+        switch(RCuser.cmd)
+        {
+        case RCUC_GETFWVER:
+            printk("RC GETFWVER\n");
+            RCUD_GETFWVER = &RCuser.RCUS_GETFWVER;
+            RCGetFirmwareVer(pDpa->id, (PU8) &RCUD_GETFWVER->FirmString, NULL);
+            break;
+        case RCUC_GETINFO:
+            printk("RC GETINFO\n");
+            RCUD_GETINFO = &RCuser.RCUS_GETINFO;
+            RCUD_GETINFO -> mem_start = dev->base_addr;
+            RCUD_GETINFO -> mem_end = dev->base_addr + 2*32768;
+            RCUD_GETINFO -> base_addr = pDpa->pci_addr;
+            RCUD_GETINFO -> irq = dev->irq;
+            break;
+        case RCUC_GETIPANDMASK:
+            printk("RC GETIPANDMASK\n");
+            RCUD_GETIPANDMASK = &RCuser.RCUS_GETIPANDMASK;
+            RCGetRavlinIPandMask(pDpa->id, (PU32) &RCUD_GETIPANDMASK->IpAddr,
+                                 (PU32) &RCUD_GETIPANDMASK->NetMask, NULL);
+            break;
+        case RCUC_GETLINKSTATISTICS:
+            printk("RC GETLINKSTATISTICS\n");
+            RCUD_GETLINKSTATISTICS = &RCuser.RCUS_GETLINKSTATISTICS;
+            RCGetLinkStatistics(pDpa->id, (P_RCLINKSTATS) &RCUD_GETLINKSTATISTICS->StatsReturn, NULL);
+            break;
+        case RCUC_GETLINKSTATUS:
+            printk("RC GETLINKSTATUS\n");
+            RCUD_GETLINKSTATUS = &RCuser.RCUS_GETLINKSTATUS;
+            RCGetLinkStatus(pDpa->id, (PU32) &RCUD_GETLINKSTATUS->ReturnStatus, NULL);
+            break;
+        case RCUC_GETMAC:
+            printk("RC GETMAC\n");
+            RCUD_GETMAC = &RCuser.RCUS_GETMAC;
+            RCGetMAC(pDpa->id, (PU8) &RCUD_GETMAC->mac, NULL);
+            break;
+        case RCUC_GETPROM:
+            printk("RC GETPROM\n");
+            RCUD_GETPROM = &RCuser.RCUS_GETPROM;
+            RCGetPromiscuousMode(pDpa->id, (PU32) &RCUD_GETPROM->PromMode, NULL);
+            break;
+        case RCUC_GETBROADCAST:
+            printk("RC GETBROADCAST\n");
+            RCUD_GETBROADCAST = &RCuser.RCUS_GETBROADCAST;
+            RCGetBroadcastMode(pDpa->id, (PU32) &RCUD_GETBROADCAST->BroadcastMode, NULL);
+            break;
+        case RCUC_GETSPEED:
+            printk("RC GETSPEED\n");
+            if (!(dev->flags & IFF_UP))    
             {
-                case RCUC_GETFWVER:
-                    printk("RC GETFWVER\n");
-                    RCUD_GETFWVER = &RCuser.RCUS_GETFWVER;
-                    RCGetFirmwareVer(pDpa->id, (PU8) &RCUD_GETFWVER->FirmString, NULL);
-                    break;
-                case RCUC_GETINFO:
-                    printk("RC GETINFO\n");
-                    RCUD_GETINFO = &RCuser.RCUS_GETINFO;
-                    RCUD_GETINFO -> mem_start = dev->base_addr;
-                    RCUD_GETINFO -> mem_end = dev->base_addr + 32768;
-                    RCUD_GETINFO -> base_addr = pDpa->pci_addr;
-                    RCUD_GETINFO -> irq = dev->irq;
-                    break;
-                case RCUC_GETIPANDMASK:
-                    printk("RC GETIPANDMASK\n");
-                    RCUD_GETIPANDMASK = &RCuser.RCUS_GETIPANDMASK;
-                    RCGetRavlinIPandMask(pDpa->id, (PU32) &RCUD_GETIPANDMASK->IpAddr,
-                        (PU32) &RCUD_GETIPANDMASK->NetMask, NULL);
-                    break;
-                case RCUC_GETLINKSTATISTICS:
-                    printk("RC GETLINKSTATISTICS\n");
-                    RCUD_GETLINKSTATISTICS = &RCuser.RCUS_GETLINKSTATISTICS;
-                    RCGetLinkStatistics(pDpa->id, (P_RCLINKSTATS) &RCUD_GETLINKSTATISTICS->StatsReturn, NULL);
-                    break;
-                case RCUC_GETLINKSTATUS:
-                    printk("RC GETLINKSTATUS\n");
-                    RCUD_GETLINKSTATUS = &RCuser.RCUS_GETLINKSTATUS;
-                    RCGetLinkStatus(pDpa->id, (PU32) &RCUD_GETLINKSTATUS->ReturnStatus, NULL);
-                    break;
-                case RCUC_GETMAC:
-                    printk("RC GETMAC\n");
-                    RCUD_GETMAC = &RCuser.RCUS_GETMAC;
-                    RCGetMAC(pDpa->id, (PU8) &RCUD_GETMAC->mac, NULL);
-                    break;
-                case RCUC_GETSPEED:
-                    printk("RC GETSPEED\n");
-                    if (!(dev->flags & IFF_UP))    
-                    {
-                        printk("RCioctl, GETSPEED error: interface down\n");
-                        return -ENODATA;
-                    }
-                    RCUD_GETSPEED = &RCuser.RCUS_GETSPEED;
-                    RCGetLinkSpeed(pDpa->id, (PU32) &RCUD_GETSPEED->LinkSpeedCode, NULL);
-                    printk("RC speed = 0x%ld\n", RCUD_GETSPEED->LinkSpeedCode);
-                    break;
-                default:
-                    printk("RC command default\n");
-                    RCUD_DEFAULT = &RCuser.RCUS_DEFAULT;
-                    RCUD_DEFAULT -> rc = 0x11223344;
-                    break;
+                printk("RCioctl, GETSPEED error: interface down\n");
+                return -ENODATA;
             }
-            memcpy_tofs(rq->ifr_data, &RCuser, sizeof(RCuser));
+            RCUD_GETSPEED = &RCuser.RCUS_GETSPEED;
+            RCGetLinkSpeed(pDpa->id, (PU32) &RCUD_GETSPEED->LinkSpeedCode, NULL);
+            printk("RC speed = 0x%ld\n", RCUD_GETSPEED->LinkSpeedCode);
+            break;
+        case RCUC_SETIPANDMASK:
+            printk("RC SETIPANDMASK\n");
+            RCUD_SETIPANDMASK = &RCuser.RCUS_SETIPANDMASK;
+            printk ("RC New IP Addr = %d.%d.%d.%d, ", (U8) ((RCUD_SETIPANDMASK->IpAddr) & 0xff),
+                    (U8) ((RCUD_SETIPANDMASK->IpAddr >>  8) & 0xff),
+                    (U8) ((RCUD_SETIPANDMASK->IpAddr >> 16) & 0xff),
+                    (U8) ((RCUD_SETIPANDMASK->IpAddr >> 24) & 0xff));
+            printk ("RC New Mask = %d.%d.%d.%d\n", (U8) ((RCUD_SETIPANDMASK->NetMask) & 0xff),
+                    (U8) ((RCUD_SETIPANDMASK->NetMask >>  8) & 0xff),
+                    (U8) ((RCUD_SETIPANDMASK->NetMask >> 16) & 0xff),
+                    (U8) ((RCUD_SETIPANDMASK->NetMask >> 24) & 0xff));
+            RCSetRavlinIPandMask(pDpa->id, (U32) RCUD_SETIPANDMASK->IpAddr,
+                                 (U32) RCUD_SETIPANDMASK->NetMask);
+            break;
+        case RCUC_SETMAC:
+            printk("RC SETMAC\n");
+            RCUD_SETMAC = &RCuser.RCUS_SETMAC;
+            printk ("RC New MAC addr = %02X:%02X:%02X:%02X:%02X:%02X\n",
+                    (U8) (RCUD_SETMAC->mac[0]), (U8) (RCUD_SETMAC->mac[1]), (U8) (RCUD_SETMAC->mac[2]),
+                    (U8) (RCUD_SETMAC->mac[3]), (U8) (RCUD_SETMAC->mac[4]), (U8) (RCUD_SETMAC->mac[5]));
+            RCSetMAC(pDpa->id, (PU8) &RCUD_SETMAC->mac);
+            break;
+        case RCUC_SETSPEED:
+            printk("RC SETSPEED\n");
+            RCUD_SETSPEED = &RCuser.RCUS_SETSPEED;
+            RCSetLinkSpeed(pDpa->id, (U16) RCUD_SETSPEED->LinkSpeedCode);
+            printk("RC New speed = 0x%d\n", RCUD_SETSPEED->LinkSpeedCode);
+            break;
+        case RCUC_SETPROM:
+            printk("RC SETPROM\n");
+            RCUD_SETPROM = &RCuser.RCUS_SETPROM;
+            RCSetPromiscuousMode(pDpa->id,(U16)RCUD_SETPROM->PromMode);
+            printk("RC New prom mode = 0x%d\n", RCUD_SETPROM->PromMode);
+            break;
+        case RCUC_SETBROADCAST:
+            printk("RC SETBROADCAST\n");
+            RCUD_SETBROADCAST = &RCuser.RCUS_SETBROADCAST;
+            RCSetBroadcastMode(pDpa->id,(U16)RCUD_SETBROADCAST->BroadcastMode);
+            printk("RC New broadcast mode = 0x%d\n", RCUD_SETBROADCAST->BroadcastMode);
             break;
-        }   /* RCU_COMMAND */ 
-
         default:
-            printk("RC default\n");
-            rq->ifr_ifru.ifru_data = (caddr_t) 0x12345678;
+            printk("RC command default\n");
+            RCUD_DEFAULT = &RCuser.RCUS_DEFAULT;
+            RCUD_DEFAULT -> rc = 0x11223344;
             break;
+        }
+#ifdef LINUX_2_1
+        copy_to_user(rq->ifr_data, &RCuser, sizeof(RCuser));
+#else
+        memcpy_tofs(rq->ifr_data, &RCuser, sizeof(RCuser));
+#endif
+        break;
+    }   /* RCU_COMMAND */ 
+
+    default:
+        printk("RC default\n");
+        rq->ifr_ifru.ifru_data = (caddr_t) 0x12345678;
+        break;
     }
     return 0;
 }
 
 static int RCconfig(struct device *dev, struct ifmap *map)
 {
-     /*
-      * To be completed ...
+    /*
+     * To be completed ...
       */
-      printk("rc: RCconfig\n");
-      return 0;
-      if (dev->flags & IFF_UP)    /* can't act on a running interface */
-           return -EBUSY;
+    printk("rc: RCconfig\n");
+    return 0;
+    if (dev->flags & IFF_UP)    /* can't act on a running interface */
+        return -EBUSY;
 
      /* Don't allow changing the I/O address */
-     if (map->base_addr != dev->base_addr) {
-          printk(KERN_WARNING "RC pci45: Change I/O address not implemented\n");
-          return -EOPNOTSUPP;
-     }
-     return 0;
+    if (map->base_addr != dev->base_addr) {
+        printk(KERN_WARNING "RC pci45: Change I/O address not implemented\n");
+        return -EOPNOTSUPP;
+    }
+    return 0;
 }
 
+
 #ifdef MODULE
-void cleanup_module(void)
+void
+cleanup_module(void)
 {
-     PDPA pDpa;
-     struct device *next;
+    PDPA pDpa;
+    struct device *next;
 
 
 #ifdef RCDEBUG
-     printk("rc: RC cleanup_module\n");
-     printk("rc: root_RCdev = 0x%x\n", (uint)root_RCdev);
+    printk("rc: RC cleanup_module\n");
+    printk("rc: root_RCdev = 0x%x\n", (uint)root_RCdev);
 #endif
 
 
-     while (root_RCdev)
-     {
-          pDpa = (PDPA) root_RCdev->priv;
+    while (root_RCdev)
+    {
+        pDpa = (PDPA) root_RCdev->priv;
 #ifdef RCDEBUG
-          printk("rc: cleanup 0x%08X\n", (uint)root_RCdev);
+        printk("rc: cleanup 0x%08X\n", (uint)root_RCdev);
 #endif
-          printk("Adapter reset: 0x%x\n", RCResetAdapter(pDpa->id));
-          unregister_netdev(root_RCdev);
-          next = pDpa->next;
-
-          vfree((unsigned long *)root_RCdev->base_addr); 
-          free_irq( root_RCdev->irq, root_RCdev );
-          kfree(root_RCdev);
-          root_RCdev = next;
-     }
+        printk("IOP reset: 0x%x\n", RCResetIOP(pDpa->id));
+        unregister_netdev(root_RCdev);
+        next = pDpa->next;
+
+        iounmap((unsigned long *)root_RCdev->base_addr); 
+        free_irq( root_RCdev->irq, root_RCdev );
+        kfree(root_RCdev);
+        root_RCdev = next;
+    }
 }
 #endif
 
@@ -1239,94 +1356,100 @@
 RC_allocate_and_post_buffers(struct device *dev, int numBuffers)
 {
 
-     int i;
-     PDPA pDpa = (PDPA)dev->priv;
-     PU32 p;
-     psingleB pB;
-     struct sk_buff *skb;
-     RC_RETURN status;
-
-     if (!numBuffers)
-          return 0;
-     else if (numBuffers > MAX_NMBR_POST_BUFFERS_PER_MSG)
-     {
+    int i;
+    PDPA pDpa = (PDPA)dev->priv;
+    PU32 p;
+    psingleB pB;
+    struct sk_buff *skb;
+    RC_RETURN status;
+
+    if (!numBuffers)
+        return 0;
+    else if (numBuffers > MAX_NMBR_POST_BUFFERS_PER_MSG)
+    {
 #ifdef RCDEBUG
-          printk("rc: Too many buffers requested!\n");
-          printk("rc: attempting to allocate only 32 buffers\n");
+        printk("rc: Too many buffers requested!\n");
+        printk("rc: attempting to allocate only 32 buffers\n");
 #endif
-          numBuffers = 32;
-     }
+        numBuffers = 32;
+    }
     
-     p = (PU32) kmalloc(sizeof(U32) + numBuffers*sizeof(singleB), GFP_ATOMIC);
+    p = (PU32) kmalloc(sizeof(U32) + numBuffers*sizeof(singleB), GFP_ATOMIC);
 
 #ifdef RCDEBUG
-     printk("rc: TCB = 0x%x\n", (uint)p);
+    printk("rc: TCB = 0x%x\n", (uint)p);
 #endif
 
-     if (!p)
-     {
-          printk("rc: RCopen: unable to allocate TCB\n");
-          return 0;
-     }
-
-     p[0] = 0;                              /* Buffer Count */
-     pB = (psingleB)((U32)p + sizeof(U32)); /* point to the first buffer */
-
-#ifdef RCDEBUG
-     printk("rc: p[0] = 0x%x, p = 0x%x, pB = 0x%x\n", (uint)p[0], (uint)p, (uint)pB);
-     printk("rc: pB = 0x%x\n", (uint)pB);
-#endif
-
-     for (i=0; i<numBuffers; i++)
-     {
-          skb = dev_alloc_skb(MAX_ETHER_SIZE+2);
-          if (!skb)
-          {
-               printk("rc: Doh! RCopen: unable to allocate enough skbs!\n");
-               if (*p != 0)        /* did we allocate any buffers at all? */
-               {
-#ifdef RCDEBUG
-                    printk("rc: will post only %d buffers \n", (uint)(*p));
-#endif
-                    break;
-               }
-               else 
-               {
-                    kfree(p);    /* Free the TCB */
-                    return 0;
-               }
-          }
-#ifdef RCDEBUG
-          printk("post 0x%x\n", (uint)skb);
-#endif
-          skb_reserve(skb, 2);    /* Align IP on 16 byte boundaries */
-          pB->context = (U32)skb;
-          pB->scount = 1;        /* segment count */
-          pB->size = MAX_ETHER_SIZE;
-          pB->addr = (U32)skb->data;
-          p[0]++;
-          pB++;
-     }
-
-     if ( (status = RCPostRecvBuffers(pDpa->id, (PRCTCB)p )) != RC_RTN_NO_ERROR)
-     {
-          printk("rc: Post buffer failed with error code 0x%x!\n", status);
-          pB = (psingleB)((U32)p + sizeof(U32)); /* point to the first buffer */
-          while(p[0])
-          {
-               skb = (struct sk_buff *)pB->context;
-               skb->free = 1;    
-#ifdef RCDEBUG
-               printk("rc: freeing 0x%x\n", (uint)skb);
-#endif
-               dev_kfree_skb(skb, FREE_READ);
-               p[0]--;
-               pB++;
-          }
-#ifdef RCDEBUG
-           printk("rc: freed all buffers, p[0] = %ld\n", p[0]);
-#endif
-     }
-     kfree(p);
-     return(p[0]);                /* return the number of posted buffers */
+    if (!p)
+    {
+        printk("rc: RCopen: unable to allocate TCB\n");
+        return 0;
+    }
+
+    p[0] = 0;                              /* Buffer Count */
+    pB = (psingleB)((U32)p + sizeof(U32)); /* point to the first buffer */
+
+#ifdef RCDEBUG
+    printk("rc: p[0] = 0x%x, p = 0x%x, pB = 0x%x\n", (uint)p[0], (uint)p, (uint)pB);
+    printk("rc: pB = 0x%x\n", (uint)pB);
+#endif
+
+    for (i=0; i<numBuffers; i++)
+    {
+        skb = dev_alloc_skb(MAX_ETHER_SIZE+2);
+        if (!skb)
+        {
+            printk("rc: Doh! RCopen: unable to allocate enough skbs!\n");
+            if (*p != 0)        /* did we allocate any buffers at all? */
+            {
+#ifdef RCDEBUG
+                printk("rc: will post only %d buffers \n", (uint)(*p));
+#endif
+                break;
+            }
+            else 
+            {
+                kfree(p);    /* Free the TCB */
+                return 0;
+            }
+        }
+#ifdef RCDEBUG
+        printk("post 0x%x\n", (uint)skb);
+#endif
+        skb_reserve(skb, 2);    /* Align IP on 16 byte boundaries */
+        pB->context = (U32)skb;
+        pB->scount = 1;        /* segment count */
+        pB->size = MAX_ETHER_SIZE;
+        pB->addr = virt_to_bus((void *)skb->data);
+        p[0]++;
+        pB++;
+    }
+
+    if ( (status = RCPostRecvBuffers(pDpa->id, (PRCTCB)p )) != RC_RTN_NO_ERROR)
+    {
+        printk("rc: Post buffer failed with error code 0x%x!\n", status);
+        pB = (psingleB)((U32)p + sizeof(U32)); /* point to the first buffer */
+        while(p[0])
+        {
+            skb = (struct sk_buff *)pB->context;
+#ifndef LINUX_2_1
+            skb->free = 1;    
+#endif
+#ifdef RCDEBUG
+            printk("rc: freeing 0x%x\n", (uint)skb);
+#endif
+#ifdef LINUX_2_1
+            dev_kfree_skb (skb);
+#else
+            dev_kfree_skb(skb, FREE_READ);
+#endif
+            p[0]--;
+            pB++;
+        }
+#ifdef RCDEBUG
+        printk("rc: freed all buffers, p[0] = %ld\n", p[0]);
+#endif
+    }
+    kfree(p);
+    return(p[0]);                /* return the number of posted buffers */
 }

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov