ni5010: Move the Racal-Interlan (Micom) driver
authorJeff Kirsher <jeffrey.t.kirsher@intel.com>
Fri, 13 May 2011 04:21:33 +0000 (21:21 -0700)
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>
Thu, 11 Aug 2011 09:33:31 +0000 (02:33 -0700)
Moves the Racal-Interlan driver into drivers/net/ethernet/racal/ and
make the necessary Kconfig and Makefile changes.

CC: "Jan-Pascal van Best" <janpascal@vanbest.org>
CC: Andreas Mohr <andi@lisas.de>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
MAINTAINERS
drivers/net/Kconfig
drivers/net/Makefile
drivers/net/ethernet/Kconfig
drivers/net/ethernet/Makefile
drivers/net/ethernet/racal/Kconfig [new file with mode: 0644]
drivers/net/ethernet/racal/Makefile [new file with mode: 0644]
drivers/net/ethernet/racal/ni5010.c [new file with mode: 0644]
drivers/net/ethernet/racal/ni5010.h [new file with mode: 0644]
drivers/net/ni5010.c [deleted file]
drivers/net/ni5010.h [deleted file]

index 5b368ccf757284734a32a41c67dab0fcf71fcc7a..19bd60deb13505ccd6bc110ad6b26e70cd37b4c6 100644 (file)
@@ -4520,7 +4520,7 @@ M:        Jan-Pascal van Best <janpascal@vanbest.org>
 M:     Andreas Mohr <andi@lisas.de>
 L:     netdev@vger.kernel.org
 S:     Maintained
-F:     drivers/net/ni5010.*
+F:     drivers/net/ethernet/racal/ni5010.*
 
 NILFS2 FILESYSTEM
 M:     KONISHI Ryusuke <konishi.ryusuke@lab.ntt.co.jp>
index d7d0b3532bc339368dbf2c1d6d48b81009d56f1f..b76de822b52fdd0a8b604255f587cc5b7a6f635e 100644 (file)
@@ -581,31 +581,6 @@ config GRETH
        help
          Say Y here if you want to use the Aeroflex Gaisler GRETH Ethernet MAC.
 
-config NET_VENDOR_RACAL
-       bool "Racal-Interlan (Micom) NI cards"
-       depends on ISA
-       help
-         If you have a network (Ethernet) card belonging to this class, such
-         as the NI5010, say Y and read the Ethernet-HOWTO,
-         available from <http://www.tldp.org/docs.html#howto>.
-
-         Note that the answer to this question doesn't directly affect the
-         kernel: saying N will just cause the configurator to skip all
-         the questions about NI cards. If you say Y, you will be asked for
-         your specific card in the following questions.
-
-config NI5010
-       tristate "NI5010 support (EXPERIMENTAL)"
-       depends on NET_VENDOR_RACAL && ISA && EXPERIMENTAL && BROKEN_ON_SMP
-       ---help---
-         If you have a network (Ethernet) card of this type, say Y and read
-         the Ethernet-HOWTO, available from
-         <http://www.tldp.org/docs.html#howto>. Note that this is still
-         experimental code.
-
-         To compile this driver as a module, choose M here. The module
-         will be called ni5010.
-
 config DNET
        tristate "Dave ethernet support (DNET)"
        depends on NET_ETHERNET && HAS_IOMEM
index 49b3e87075d36b1ebce1027706307b9a0879001d..e641f703bbad8e859bca3014a079b45a1cad8ba5 100644 (file)
@@ -140,7 +140,6 @@ obj-$(CONFIG_8139TOO) += 8139too.o
 obj-$(CONFIG_CPMAC) += cpmac.o
 obj-$(CONFIG_EWRK3) += ewrk3.o
 obj-$(CONFIG_ATP) += atp.o
-obj-$(CONFIG_NI5010) += ni5010.o
 obj-$(CONFIG_SC92031) += sc92031.o
 
 obj-$(CONFIG_ETH16I) += eth16i.o
index d0a8fa8ab7ec2710c5ac66a275676ed5d928eda9..7efbb7cf91a976d9ac6d803bde294d02e7bb1595 100644 (file)
@@ -19,6 +19,7 @@ source "drivers/net/ethernet/chelsio/Kconfig"
 source "drivers/net/ethernet/intel/Kconfig"
 source "drivers/net/ethernet/i825xx/Kconfig"
 source "drivers/net/ethernet/qlogic/Kconfig"
+source "drivers/net/ethernet/racal/Kconfig"
 source "drivers/net/ethernet/smsc/Kconfig"
 
 endif # ETHERNET
index 6d3276a48012bf91005e8f6d16e8a05643e2d857..86da8b8339e133a28719e0d2c37265eb8402548d 100644 (file)
@@ -10,4 +10,5 @@ obj-$(CONFIG_NET_VENDOR_CHELSIO) += chelsio/
 obj-$(CONFIG_NET_VENDOR_INTEL) += intel/
 obj-$(CONFIG_NET_VENDOR_I825XX) += i825xx/
 obj-$(CONFIG_NET_VENDOR_QLOGIC) += qlogic/
+obj-$(CONFIG_NET_VENDOR_RACAL) += racal/
 obj-$(CONFIG_NET_VENDOR_SMSC) += smsc/
diff --git a/drivers/net/ethernet/racal/Kconfig b/drivers/net/ethernet/racal/Kconfig
new file mode 100644 (file)
index 0000000..45d4930
--- /dev/null
@@ -0,0 +1,32 @@
+#
+# Racal-Interlan device configuration
+#
+
+config NET_VENDOR_RACAL
+       bool "Racal-Interlan (Micom) NI devices"
+       depends on ISA
+       ---help---
+         If you have a network (Ethernet) card belonging to this class, such
+         as the NI5010, NI5210 or NI6210, say Y and read the Ethernet-HOWTO,
+         available from <http://www.tldp.org/docs.html#howto>.
+
+         Note that the answer to this question doesn't directly affect the
+         kernel: saying N will just cause the configurator to skip all
+         the questions about NI cards. If you say Y, you will be asked for
+         your specific card in the following questions.
+
+if NET_VENDOR_RACAL
+
+config NI5010
+       tristate "NI5010 support (EXPERIMENTAL)"
+       depends on ISA && EXPERIMENTAL && BROKEN_ON_SMP
+       ---help---
+         If you have a network (Ethernet) card of this type, say Y and read
+         the Ethernet-HOWTO, available from
+         <http://www.tldp.org/docs.html#howto>. Note that this is still
+         experimental code.
+
+         To compile this driver as a module, choose M here. The module
+         will be called ni5010.
+
+endif # NET_VENDOR_RACAL
diff --git a/drivers/net/ethernet/racal/Makefile b/drivers/net/ethernet/racal/Makefile
new file mode 100644 (file)
index 0000000..1e210ca
--- /dev/null
@@ -0,0 +1,5 @@
+#
+# Makefile for the Racal-Interlan network device drivers.
+#
+
+obj-$(CONFIG_NI5010) += ni5010.o
diff --git a/drivers/net/ethernet/racal/ni5010.c b/drivers/net/ethernet/racal/ni5010.c
new file mode 100644 (file)
index 0000000..4d3f2e2
--- /dev/null
@@ -0,0 +1,771 @@
+/*     ni5010.c: A network driver for the MiCom-Interlan NI5010 ethercard.
+ *
+ *     Copyright 1996,1997,2006 Jan-Pascal van Best and Andreas Mohr.
+ *
+ *     This software may be used and distributed according to the terms
+ *     of the GNU General Public License, incorporated herein by reference.
+ *
+ *     The authors may be reached as:
+ *             janpascal@vanbest.org           andi@lisas.de
+ *
+ *     Sources:
+ *             Donald Becker's "skeleton.c"
+ *             Crynwr ni5010 packet driver
+ *
+ *     Changes:
+ *             v0.0: First test version
+ *             v0.1: First working version
+ *             v0.2:
+ *             v0.3->v0.90: Now demand setting io and irq when loading as module
+ *     970430  v0.91: modified for Linux 2.1.14
+ *             v0.92: Implemented Andreas' (better) NI5010 probe
+ *     970503  v0.93: Fixed auto-irq failure on warm reboot (JB)
+ *     970623  v1.00: First kernel version (AM)
+ *     970814  v1.01: Added detection of onboard receive buffer size (AM)
+ *     060611  v1.02: slight cleanup: email addresses, driver modernization.
+ *     Bugs:
+ *             - not SMP-safe (no locking of I/O accesses)
+ *             - Note that you have to patch ifconfig for the new /proc/net/dev
+ *             format. It gives incorrect stats otherwise.
+ *
+ *     To do:
+ *             Fix all bugs :-)
+ *             Move some stuff to chipset_init()
+ *             Handle xmt errors other than collisions
+ *             Complete merge with Andreas' driver
+ *             Implement ring buffers (Is this useful? You can't squeeze
+ *                     too many packet in a 2k buffer!)
+ *             Implement DMA (Again, is this useful? Some docs say DMA is
+ *                     slower than programmed I/O)
+ *
+ *     Compile with:
+ *             gcc -O2 -fomit-frame-pointer -m486 -D__KERNEL__ \
+ *                     -DMODULE -c ni5010.c
+ *
+ *     Insert with e.g.:
+ *             insmod ni5010.ko io=0x300 irq=5
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/errno.h>
+#include <linux/ioport.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/bitops.h>
+#include <asm/io.h>
+#include <asm/dma.h>
+
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+
+#include "ni5010.h"
+
+static const char boardname[] = "NI5010";
+static char version[] __initdata =
+       "ni5010.c: v1.02 20060611 Jan-Pascal van Best and Andreas Mohr\n";
+
+/* bufsize_rcv == 0 means autoprobing */
+static unsigned int bufsize_rcv;
+
+#define JUMPERED_INTERRUPTS    /* IRQ line jumpered on board */
+#undef JUMPERED_DMA            /* No DMA used */
+#undef FULL_IODETECT           /* Only detect in portlist */
+
+#ifndef FULL_IODETECT
+/* A zero-terminated list of I/O addresses to be probed. */
+static unsigned int ports[] __initdata =
+       { 0x300, 0x320, 0x340, 0x360, 0x380, 0x3a0, 0 };
+#endif
+
+/* Use 0 for production, 1 for verification, >2 for debug */
+#ifndef NI5010_DEBUG
+#define NI5010_DEBUG 0
+#endif
+
+/* Information that needs to be kept for each board. */
+struct ni5010_local {
+       int o_pkt_size;
+       spinlock_t lock;
+};
+
+/* Index to functions, as function prototypes. */
+
+static int     ni5010_probe1(struct net_device *dev, int ioaddr);
+static int     ni5010_open(struct net_device *dev);
+static int     ni5010_send_packet(struct sk_buff *skb, struct net_device *dev);
+static irqreturn_t ni5010_interrupt(int irq, void *dev_id);
+static void    ni5010_rx(struct net_device *dev);
+static void    ni5010_timeout(struct net_device *dev);
+static int     ni5010_close(struct net_device *dev);
+static void    ni5010_set_multicast_list(struct net_device *dev);
+static void    reset_receiver(struct net_device *dev);
+
+static int     process_xmt_interrupt(struct net_device *dev);
+#define tx_done(dev) 1
+static void    hardware_send_packet(struct net_device *dev, char *buf, int length, int pad);
+static void    chipset_init(struct net_device *dev, int startp);
+static void    dump_packet(void *buf, int len);
+static void    ni5010_show_registers(struct net_device *dev);
+
+static int io;
+static int irq;
+
+struct net_device * __init ni5010_probe(int unit)
+{
+       struct net_device *dev = alloc_etherdev(sizeof(struct ni5010_local));
+       int *port;
+       int err = 0;
+
+       if (!dev)
+               return ERR_PTR(-ENOMEM);
+
+       if (unit >= 0) {
+               sprintf(dev->name, "eth%d", unit);
+               netdev_boot_setup_check(dev);
+               io = dev->base_addr;
+               irq = dev->irq;
+       }
+
+       PRINTK2((KERN_DEBUG "%s: Entering ni5010_probe\n", dev->name));
+
+       if (io > 0x1ff) {       /* Check a single specified location. */
+               err = ni5010_probe1(dev, io);
+       } else if (io != 0) {   /* Don't probe at all. */
+               err = -ENXIO;
+       } else {
+#ifdef FULL_IODETECT
+               for (io=0x200; io<0x400 && ni5010_probe1(dev, io) ; io+=0x20)
+                       ;
+               if (io == 0x400)
+                       err = -ENODEV;
+
+#else
+               for (port = ports; *port && ni5010_probe1(dev, *port); port++)
+                       ;
+               if (!*port)
+                       err = -ENODEV;
+#endif /* FULL_IODETECT */
+       }
+       if (err)
+               goto out;
+       err = register_netdev(dev);
+       if (err)
+               goto out1;
+       return dev;
+out1:
+       release_region(dev->base_addr, NI5010_IO_EXTENT);
+out:
+       free_netdev(dev);
+       return ERR_PTR(err);
+}
+
+static inline int rd_port(int ioaddr)
+{
+       inb(IE_RBUF);
+       return inb(IE_SAPROM);
+}
+
+static void __init trigger_irq(int ioaddr)
+{
+               outb(0x00, EDLC_RESET); /* Clear EDLC hold RESET state */
+               outb(0x00, IE_RESET);   /* Board reset */
+               outb(0x00, EDLC_XMASK); /* Disable all Xmt interrupts */
+               outb(0x00, EDLC_RMASK); /* Disable all Rcv interrupt */
+               outb(0xff, EDLC_XCLR);  /* Clear all pending Xmt interrupts */
+               outb(0xff, EDLC_RCLR);  /* Clear all pending Rcv interrupts */
+               /*
+                * Transmit packet mode: Ignore parity, Power xcvr,
+                *      Enable loopback
+                */
+               outb(XMD_IG_PAR | XMD_T_MODE | XMD_LBC, EDLC_XMODE);
+               outb(RMD_BROADCAST, EDLC_RMODE); /* Receive normal&broadcast */
+               outb(XM_ALL, EDLC_XMASK);       /* Enable all Xmt interrupts */
+               udelay(50);                     /* FIXME: Necessary? */
+               outb(MM_EN_XMT|MM_MUX, IE_MMODE); /* Start transmission */
+}
+
+static const struct net_device_ops ni5010_netdev_ops = {
+       .ndo_open               = ni5010_open,
+       .ndo_stop               = ni5010_close,
+       .ndo_start_xmit         = ni5010_send_packet,
+       .ndo_set_multicast_list = ni5010_set_multicast_list,
+       .ndo_tx_timeout         = ni5010_timeout,
+       .ndo_validate_addr      = eth_validate_addr,
+       .ndo_set_mac_address    = eth_mac_addr,
+       .ndo_change_mtu         = eth_change_mtu,
+};
+
+/*
+ *      This is the real probe routine.  Linux has a history of friendly device
+ *      probes on the ISA bus.  A good device probes avoids doing writes, and
+ *      verifies that the correct device exists and functions.
+ */
+
+static int __init ni5010_probe1(struct net_device *dev, int ioaddr)
+{
+       static unsigned version_printed;
+       struct ni5010_local *lp;
+       int i;
+       unsigned int data = 0;
+       int boguscount = 40;
+       int err = -ENODEV;
+
+       dev->base_addr = ioaddr;
+       dev->irq = irq;
+
+       if (!request_region(ioaddr, NI5010_IO_EXTENT, boardname))
+               return -EBUSY;
+
+       /*
+        * This is no "official" probe method, I've rather tested which
+        * probe works best with my seven NI5010 cards
+        * (they have very different serial numbers)
+        * Suggestions or failure reports are very, very welcome !
+        * But I think it is a relatively good probe method
+        * since it doesn't use any "outb"
+        * It should be nearly 100% reliable !
+        * well-known WARNING: this probe method (like many others)
+        * will hang the system if a NE2000 card region is probed !
+        *
+        *   - Andreas
+        */
+
+       PRINTK2((KERN_DEBUG "%s: entering ni5010_probe1(%#3x)\n",
+               dev->name, ioaddr));
+
+       if (inb(ioaddr+0) == 0xff)
+               goto out;
+
+       while ( (rd_port(ioaddr) & rd_port(ioaddr) & rd_port(ioaddr) &
+                rd_port(ioaddr) & rd_port(ioaddr) & rd_port(ioaddr)) != 0xff)
+       {
+               if (boguscount-- == 0)
+                       goto out;
+       }
+
+       PRINTK2((KERN_DEBUG "%s: I/O #1 passed!\n", dev->name));
+
+       for (i=0; i<32; i++)
+               if ( (data = rd_port(ioaddr)) != 0xff) break;
+       if (data==0xff)
+               goto out;
+
+       PRINTK2((KERN_DEBUG "%s: I/O #2 passed!\n", dev->name));
+
+       if ((data != SA_ADDR0) || (rd_port(ioaddr) != SA_ADDR1) ||
+           (rd_port(ioaddr) != SA_ADDR2))
+               goto out;
+
+       for (i=0; i<4; i++)
+               rd_port(ioaddr);
+
+       if ( (rd_port(ioaddr) != NI5010_MAGICVAL1) ||
+            (rd_port(ioaddr) != NI5010_MAGICVAL2) )
+               goto out;
+
+       PRINTK2((KERN_DEBUG "%s: I/O #3 passed!\n", dev->name));
+
+       if (NI5010_DEBUG && version_printed++ == 0)
+               printk(KERN_INFO "%s", version);
+
+       printk("NI5010 ethercard probe at 0x%x: ", ioaddr);
+
+       dev->base_addr = ioaddr;
+
+       for (i=0; i<6; i++) {
+               outw(i, IE_GP);
+               dev->dev_addr[i] = inb(IE_SAPROM);
+       }
+       printk("%pM ", dev->dev_addr);
+
+       PRINTK2((KERN_DEBUG "%s: I/O #4 passed!\n", dev->name));
+
+#ifdef JUMPERED_INTERRUPTS
+       if (dev->irq == 0xff)
+               ;
+       else if (dev->irq < 2) {
+               unsigned long irq_mask;
+
+               PRINTK2((KERN_DEBUG "%s: I/O #5 passed!\n", dev->name));
+
+               irq_mask = probe_irq_on();
+               trigger_irq(ioaddr);
+               mdelay(20);
+               dev->irq = probe_irq_off(irq_mask);
+
+               PRINTK2((KERN_DEBUG "%s: I/O #6 passed!\n", dev->name));
+
+               if (dev->irq == 0) {
+                       err = -EAGAIN;
+                       printk(KERN_WARNING "%s: no IRQ found!\n", dev->name);
+                       goto out;
+               }
+               PRINTK2((KERN_DEBUG "%s: I/O #7 passed!\n", dev->name));
+       } else if (dev->irq == 2) {
+               dev->irq = 9;
+       }
+#endif /* JUMPERED_INTERRUPTS */
+       PRINTK2((KERN_DEBUG "%s: I/O #9 passed!\n", dev->name));
+
+       /* DMA is not supported (yet?), so no use detecting it */
+       lp = netdev_priv(dev);
+
+       spin_lock_init(&lp->lock);
+
+       PRINTK2((KERN_DEBUG "%s: I/O #10 passed!\n", dev->name));
+
+/* get the size of the onboard receive buffer
+ * higher addresses than bufsize are wrapped into real buffer
+ * i.e. data for offs. 0x801 is written to 0x1 with a 2K onboard buffer
+ */
+       if (!bufsize_rcv) {
+               outb(1, IE_MMODE);      /* Put Rcv buffer on system bus */
+               outw(0, IE_GP);         /* Point GP at start of packet */
+               outb(0, IE_RBUF);       /* set buffer byte 0 to 0 */
+               for (i = 1; i < 0xff; i++) {
+                       outw(i << 8, IE_GP); /* Point GP at packet size to be tested */
+                       outb(i, IE_RBUF);
+                       outw(0x0, IE_GP); /* Point GP at start of packet */
+                       data = inb(IE_RBUF);
+                       if (data == i) break;
+               }
+               bufsize_rcv = i << 8;
+               outw(0, IE_GP);         /* Point GP at start of packet */
+               outb(0, IE_RBUF);       /* set buffer byte 0 to 0 again */
+       }
+        printk("-> bufsize rcv/xmt=%d/%d\n", bufsize_rcv, NI5010_BUFSIZE);
+
+       dev->netdev_ops         = &ni5010_netdev_ops;
+       dev->watchdog_timeo     = HZ/20;
+
+       dev->flags &= ~IFF_MULTICAST;   /* Multicast doesn't work */
+
+       /* Shut up the ni5010 */
+       outb(0, EDLC_RMASK);    /* Mask all receive interrupts */
+       outb(0, EDLC_XMASK);    /* Mask all xmit interrupts */
+       outb(0xff, EDLC_RCLR);  /* Kill all pending rcv interrupts */
+       outb(0xff, EDLC_XCLR);  /* Kill all pending xmt interrupts */
+
+       printk(KERN_INFO "%s: NI5010 found at 0x%x, using IRQ %d", dev->name, ioaddr, dev->irq);
+       if (dev->dma)
+               printk(" & DMA %d", dev->dma);
+       printk(".\n");
+       return 0;
+out:
+       release_region(dev->base_addr, NI5010_IO_EXTENT);
+       return err;
+}
+
+/*
+ * Open/initialize the board.  This is called (in the current kernel)
+ * sometime after booting when the 'ifconfig' program is run.
+ *
+ * This routine should set everything up anew at each open, even
+ * registers that "should" only need to be set once at boot, so that
+ * there is a non-reboot way to recover if something goes wrong.
+ */
+
+static int ni5010_open(struct net_device *dev)
+{
+       int ioaddr = dev->base_addr;
+       int i;
+
+       PRINTK2((KERN_DEBUG "%s: entering ni5010_open()\n", dev->name));
+
+       if (request_irq(dev->irq, ni5010_interrupt, 0, boardname, dev)) {
+               printk(KERN_WARNING "%s: Cannot get irq %#2x\n", dev->name, dev->irq);
+               return -EAGAIN;
+       }
+       PRINTK3((KERN_DEBUG "%s: passed open() #1\n", dev->name));
+        /*
+         * Always allocate the DMA channel after the IRQ,
+         * and clean up on failure.
+         */
+#ifdef JUMPERED_DMA
+        if (request_dma(dev->dma, cardname)) {
+               printk(KERN_WARNING "%s: Cannot get dma %#2x\n", dev->name, dev->dma);
+                free_irq(dev->irq, NULL);
+                return -EAGAIN;
+        }
+#endif /* JUMPERED_DMA */
+
+       PRINTK3((KERN_DEBUG "%s: passed open() #2\n", dev->name));
+       /* Reset the hardware here.  Don't forget to set the station address. */
+
+       outb(RS_RESET, EDLC_RESET);     /* Hold up EDLC_RESET while configing board */
+       outb(0, IE_RESET);              /* Hardware reset of ni5010 board */
+       outb(XMD_LBC, EDLC_XMODE);      /* Only loopback xmits */
+
+       PRINTK3((KERN_DEBUG "%s: passed open() #3\n", dev->name));
+       /* Set the station address */
+       for(i = 0;i < 6; i++) {
+               outb(dev->dev_addr[i], EDLC_ADDR + i);
+       }
+
+       PRINTK3((KERN_DEBUG "%s: Initialising ni5010\n", dev->name));
+       outb(0, EDLC_XMASK);    /* No xmit interrupts for now */
+       outb(XMD_IG_PAR | XMD_T_MODE | XMD_LBC, EDLC_XMODE);
+                               /* Normal packet xmit mode */
+       outb(0xff, EDLC_XCLR);  /* Clear all pending xmit interrupts */
+       outb(RMD_BROADCAST, EDLC_RMODE);
+                               /* Receive broadcast and normal packets */
+       reset_receiver(dev);    /* Ready ni5010 for receiving packets */
+
+       outb(0, EDLC_RESET);    /* Un-reset the ni5010 */
+
+       netif_start_queue(dev);
+
+       if (NI5010_DEBUG) ni5010_show_registers(dev);
+
+       PRINTK((KERN_DEBUG "%s: open successful\n", dev->name));
+       return 0;
+}
+
+static void reset_receiver(struct net_device *dev)
+{
+       int ioaddr = dev->base_addr;
+
+       PRINTK3((KERN_DEBUG "%s: resetting receiver\n", dev->name));
+       outw(0, IE_GP);         /* Receive packet at start of buffer */
+       outb(0xff, EDLC_RCLR);  /* Clear all pending rcv interrupts */
+       outb(0, IE_MMODE);      /* Put EDLC to rcv buffer */
+       outb(MM_EN_RCV, IE_MMODE); /* Enable rcv */
+       outb(0xff, EDLC_RMASK); /* Enable all rcv interrupts */
+}
+
+static void ni5010_timeout(struct net_device *dev)
+{
+       printk(KERN_WARNING "%s: transmit timed out, %s?\n", dev->name,
+                  tx_done(dev) ? "IRQ conflict" : "network cable problem");
+       /* Try to restart the adaptor. */
+       /* FIXME: Give it a real kick here */
+       chipset_init(dev, 1);
+       dev->trans_start = jiffies; /* prevent tx timeout */
+       netif_wake_queue(dev);
+}
+
+static int ni5010_send_packet(struct sk_buff *skb, struct net_device *dev)
+{
+       int length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
+
+       PRINTK2((KERN_DEBUG "%s: entering ni5010_send_packet\n", dev->name));
+
+       /*
+         * Block sending
+        */
+
+       netif_stop_queue(dev);
+       hardware_send_packet(dev, (unsigned char *)skb->data, skb->len, length-skb->len);
+       dev_kfree_skb (skb);
+       return NETDEV_TX_OK;
+}
+
+/*
+ * The typical workload of the driver:
+ * Handle the network interface interrupts.
+ */
+static irqreturn_t ni5010_interrupt(int irq, void *dev_id)
+{
+       struct net_device *dev = dev_id;
+       struct ni5010_local *lp;
+       int ioaddr, status;
+       int xmit_was_error = 0;
+
+       PRINTK2((KERN_DEBUG "%s: entering ni5010_interrupt\n", dev->name));
+
+       ioaddr = dev->base_addr;
+       lp = netdev_priv(dev);
+
+       spin_lock(&lp->lock);
+       status = inb(IE_ISTAT);
+       PRINTK3((KERN_DEBUG "%s: IE_ISTAT = %#02x\n", dev->name, status));
+
+        if ((status & IS_R_INT) == 0) ni5010_rx(dev);
+
+        if ((status & IS_X_INT) == 0) {
+                xmit_was_error = process_xmt_interrupt(dev);
+        }
+
+        if ((status & IS_DMA_INT) == 0) {
+                PRINTK((KERN_DEBUG "%s: DMA complete (?)\n", dev->name));
+                outb(0, IE_DMA_RST); /* Reset DMA int */
+        }
+
+       if (!xmit_was_error)
+               reset_receiver(dev);
+       spin_unlock(&lp->lock);
+       return IRQ_HANDLED;
+}
+
+
+static void dump_packet(void *buf, int len)
+{
+       int i;
+
+       printk(KERN_DEBUG "Packet length = %#4x\n", len);
+       for (i = 0; i < len; i++){
+               if (i % 16 == 0) printk(KERN_DEBUG "%#4.4x", i);
+               if (i % 2 == 0) printk(" ");
+               printk("%2.2x", ((unsigned char *)buf)[i]);
+               if (i % 16 == 15) printk("\n");
+       }
+       printk("\n");
+}
+
+/* We have a good packet, get it out of the buffer. */
+static void ni5010_rx(struct net_device *dev)
+{
+       int ioaddr = dev->base_addr;
+       unsigned char rcv_stat;
+       struct sk_buff *skb;
+       int i_pkt_size;
+
+       PRINTK2((KERN_DEBUG "%s: entering ni5010_rx()\n", dev->name));
+
+       rcv_stat = inb(EDLC_RSTAT);
+       PRINTK3((KERN_DEBUG "%s: EDLC_RSTAT = %#2x\n", dev->name, rcv_stat));
+
+       if ( (rcv_stat & RS_VALID_BITS) != RS_PKT_OK) {
+               PRINTK((KERN_INFO "%s: receive error.\n", dev->name));
+               dev->stats.rx_errors++;
+               if (rcv_stat & RS_RUNT) dev->stats.rx_length_errors++;
+               if (rcv_stat & RS_ALIGN) dev->stats.rx_frame_errors++;
+               if (rcv_stat & RS_CRC_ERR) dev->stats.rx_crc_errors++;
+               if (rcv_stat & RS_OFLW) dev->stats.rx_fifo_errors++;
+               outb(0xff, EDLC_RCLR); /* Clear the interrupt */
+               return;
+       }
+
+        outb(0xff, EDLC_RCLR);  /* Clear the interrupt */
+
+       i_pkt_size = inw(IE_RCNT);
+       if (i_pkt_size > ETH_FRAME_LEN || i_pkt_size < 10 ) {
+               PRINTK((KERN_DEBUG "%s: Packet size error, packet size = %#4.4x\n",
+                       dev->name, i_pkt_size));
+               dev->stats.rx_errors++;
+               dev->stats.rx_length_errors++;
+               return;
+       }
+
+       /* Malloc up new buffer. */
+       skb = dev_alloc_skb(i_pkt_size + 3);
+       if (skb == NULL) {
+               printk(KERN_WARNING "%s: Memory squeeze, dropping packet.\n", dev->name);
+               dev->stats.rx_dropped++;
+               return;
+       }
+
+       skb_reserve(skb, 2);
+
+       /* Read packet into buffer */
+        outb(MM_MUX, IE_MMODE); /* Rcv buffer to system bus */
+       outw(0, IE_GP); /* Seek to beginning of packet */
+       insb(IE_RBUF, skb_put(skb, i_pkt_size), i_pkt_size);
+
+       if (NI5010_DEBUG >= 4)
+               dump_packet(skb->data, skb->len);
+
+       skb->protocol = eth_type_trans(skb,dev);
+       netif_rx(skb);
+       dev->stats.rx_packets++;
+       dev->stats.rx_bytes += i_pkt_size;
+
+       PRINTK2((KERN_DEBUG "%s: Received packet, size=%#4.4x\n",
+               dev->name, i_pkt_size));
+}
+
+static int process_xmt_interrupt(struct net_device *dev)
+{
+       struct ni5010_local *lp = netdev_priv(dev);
+       int ioaddr = dev->base_addr;
+       int xmit_stat;
+
+       PRINTK2((KERN_DEBUG "%s: entering process_xmt_interrupt\n", dev->name));
+
+       xmit_stat = inb(EDLC_XSTAT);
+       PRINTK3((KERN_DEBUG "%s: EDLC_XSTAT = %2.2x\n", dev->name, xmit_stat));
+
+       outb(0, EDLC_XMASK);    /* Disable xmit IRQ's */
+       outb(0xff, EDLC_XCLR);  /* Clear all pending xmit IRQ's */
+
+       if (xmit_stat & XS_COLL){
+               PRINTK((KERN_DEBUG "%s: collision detected, retransmitting\n",
+                       dev->name));
+               outw(NI5010_BUFSIZE - lp->o_pkt_size, IE_GP);
+               /* outb(0, IE_MMODE); */ /* xmt buf on sysbus FIXME: needed ? */
+               outb(MM_EN_XMT | MM_MUX, IE_MMODE);
+               outb(XM_ALL, EDLC_XMASK); /* Enable xmt IRQ's */
+               dev->stats.collisions++;
+               return 1;
+       }
+
+       /* FIXME: handle other xmt error conditions */
+
+       dev->stats.tx_packets++;
+       dev->stats.tx_bytes += lp->o_pkt_size;
+       netif_wake_queue(dev);
+
+       PRINTK2((KERN_DEBUG "%s: sent packet, size=%#4.4x\n",
+               dev->name, lp->o_pkt_size));
+
+       return 0;
+}
+
+/* The inverse routine to ni5010_open(). */
+static int ni5010_close(struct net_device *dev)
+{
+       int ioaddr = dev->base_addr;
+
+       PRINTK2((KERN_DEBUG "%s: entering ni5010_close\n", dev->name));
+#ifdef JUMPERED_INTERRUPTS
+       free_irq(dev->irq, NULL);
+#endif
+       /* Put card in held-RESET state */
+       outb(0, IE_MMODE);
+       outb(RS_RESET, EDLC_RESET);
+
+       netif_stop_queue(dev);
+
+       PRINTK((KERN_DEBUG "%s: %s closed down\n", dev->name, boardname));
+       return 0;
+
+}
+
+/* Set or clear the multicast filter for this adaptor.
+   num_addrs == -1      Promiscuous mode, receive all packets
+   num_addrs == 0       Normal mode, clear multicast list
+   num_addrs > 0        Multicast mode, receive normal and MC packets, and do
+                        best-effort filtering.
+*/
+static void ni5010_set_multicast_list(struct net_device *dev)
+{
+       short ioaddr = dev->base_addr;
+
+       PRINTK2((KERN_DEBUG "%s: entering set_multicast_list\n", dev->name));
+
+       if (dev->flags & IFF_PROMISC || dev->flags & IFF_ALLMULTI ||
+           !netdev_mc_empty(dev)) {
+               outb(RMD_PROMISC, EDLC_RMODE); /* Enable promiscuous mode */
+               PRINTK((KERN_DEBUG "%s: Entering promiscuous mode\n", dev->name));
+       } else {
+               PRINTK((KERN_DEBUG "%s: Entering broadcast mode\n", dev->name));
+               outb(RMD_BROADCAST, EDLC_RMODE);  /* Disable promiscuous mode, use normal mode */
+       }
+}
+
+static void hardware_send_packet(struct net_device *dev, char *buf, int length, int pad)
+{
+       struct ni5010_local *lp = netdev_priv(dev);
+       int ioaddr = dev->base_addr;
+       unsigned long flags;
+       unsigned int buf_offs;
+
+       PRINTK2((KERN_DEBUG "%s: entering hardware_send_packet\n", dev->name));
+
+        if (length > ETH_FRAME_LEN) {
+                PRINTK((KERN_WARNING "%s: packet too large, not possible\n",
+                        dev->name));
+                return;
+        }
+
+       if (NI5010_DEBUG) ni5010_show_registers(dev);
+
+       if (inb(IE_ISTAT) & IS_EN_XMT) {
+               PRINTK((KERN_WARNING "%s: sending packet while already transmitting, not possible\n",
+                       dev->name));
+               return;
+       }
+
+       if (NI5010_DEBUG > 3) dump_packet(buf, length);
+
+       buf_offs = NI5010_BUFSIZE - length - pad;
+
+       spin_lock_irqsave(&lp->lock, flags);
+       lp->o_pkt_size = length + pad;
+
+       outb(0, EDLC_RMASK);    /* Mask all receive interrupts */
+       outb(0, IE_MMODE);      /* Put Xmit buffer on system bus */
+       outb(0xff, EDLC_RCLR);  /* Clear out pending rcv interrupts */
+
+       outw(buf_offs, IE_GP); /* Point GP at start of packet */
+       outsb(IE_XBUF, buf, length); /* Put data in buffer */
+       while(pad--)
+               outb(0, IE_XBUF);
+
+       outw(buf_offs, IE_GP); /* Rewrite where packet starts */
+
+       /* should work without that outb() (Crynwr used it) */
+       /*outb(MM_MUX, IE_MMODE);*/ /* Xmt buffer to EDLC bus */
+       outb(MM_EN_XMT | MM_MUX, IE_MMODE); /* Begin transmission */
+       outb(XM_ALL, EDLC_XMASK); /* Cause interrupt after completion or fail */
+
+       spin_unlock_irqrestore(&lp->lock, flags);
+
+       netif_wake_queue(dev);
+
+       if (NI5010_DEBUG) ni5010_show_registers(dev);
+}
+
+static void chipset_init(struct net_device *dev, int startp)
+{
+       /* FIXME: Move some stuff here */
+       PRINTK3((KERN_DEBUG "%s: doing NOTHING in chipset_init\n", dev->name));
+}
+
+static void ni5010_show_registers(struct net_device *dev)
+{
+       int ioaddr = dev->base_addr;
+
+       PRINTK3((KERN_DEBUG "%s: XSTAT %#2.2x\n", dev->name, inb(EDLC_XSTAT)));
+       PRINTK3((KERN_DEBUG "%s: XMASK %#2.2x\n", dev->name, inb(EDLC_XMASK)));
+       PRINTK3((KERN_DEBUG "%s: RSTAT %#2.2x\n", dev->name, inb(EDLC_RSTAT)));
+       PRINTK3((KERN_DEBUG "%s: RMASK %#2.2x\n", dev->name, inb(EDLC_RMASK)));
+       PRINTK3((KERN_DEBUG "%s: RMODE %#2.2x\n", dev->name, inb(EDLC_RMODE)));
+       PRINTK3((KERN_DEBUG "%s: XMODE %#2.2x\n", dev->name, inb(EDLC_XMODE)));
+       PRINTK3((KERN_DEBUG "%s: ISTAT %#2.2x\n", dev->name, inb(IE_ISTAT)));
+}
+
+#ifdef MODULE
+static struct net_device *dev_ni5010;
+
+module_param(io, int, 0);
+module_param(irq, int, 0);
+MODULE_PARM_DESC(io, "ni5010 I/O base address");
+MODULE_PARM_DESC(irq, "ni5010 IRQ number");
+
+static int __init ni5010_init_module(void)
+{
+       PRINTK2((KERN_DEBUG "%s: entering init_module\n", boardname));
+       /*
+       if(io <= 0 || irq == 0){
+               printk(KERN_WARNING "%s: Autoprobing not allowed for modules.\n", boardname);
+               printk(KERN_WARNING "%s: Set symbols 'io' and 'irq'\n", boardname);
+               return -EINVAL;
+       }
+       */
+       if (io <= 0){
+               printk(KERN_WARNING "%s: Autoprobing for modules is hazardous, trying anyway..\n", boardname);
+       }
+
+       PRINTK2((KERN_DEBUG "%s: init_module irq=%#2x, io=%#3x\n", boardname, irq, io));
+       dev_ni5010 = ni5010_probe(-1);
+       if (IS_ERR(dev_ni5010))
+               return PTR_ERR(dev_ni5010);
+        return 0;
+}
+
+static void __exit ni5010_cleanup_module(void)
+{
+       PRINTK2((KERN_DEBUG "%s: entering cleanup_module\n", boardname));
+       unregister_netdev(dev_ni5010);
+       release_region(dev_ni5010->base_addr, NI5010_IO_EXTENT);
+       free_netdev(dev_ni5010);
+}
+module_init(ni5010_init_module);
+module_exit(ni5010_cleanup_module);
+#endif /* MODULE */
+MODULE_LICENSE("GPL");
diff --git a/drivers/net/ethernet/racal/ni5010.h b/drivers/net/ethernet/racal/ni5010.h
new file mode 100644 (file)
index 0000000..e10e717
--- /dev/null
@@ -0,0 +1,144 @@
+/*
+ * Racal-Interlan ni5010 Ethernet definitions
+ *
+ * This is an extension to the Linux operating system, and is covered by the
+ * same GNU General Public License that covers that work.
+ *
+ * copyrights (c) 1996 by Jan-Pascal van Best (jvbest@wi.leidenuniv.nl)
+ *
+ * I have done a look in the following sources:
+ *   crynwr-packet-driver by Russ Nelson
+ */
+
+#define NI5010_BUFSIZE 2048    /* number of bytes in a buffer */
+
+#define NI5010_MAGICVAL0 0x00  /* magic-values for ni5010 card */
+#define NI5010_MAGICVAL1 0x55
+#define NI5010_MAGICVAL2 0xAA
+
+#define SA_ADDR0 0x02
+#define SA_ADDR1 0x07
+#define SA_ADDR2 0x01
+
+/* The number of low I/O ports used by the ni5010 ethercard. */
+#define NI5010_IO_EXTENT       32
+
+#define PRINTK(x) if (NI5010_DEBUG) printk x
+#define PRINTK2(x) if (NI5010_DEBUG>=2) printk x
+#define PRINTK3(x) if (NI5010_DEBUG>=3) printk x
+
+/* The various IE command registers */
+#define EDLC_XSTAT     (ioaddr + 0x00) /* EDLC transmit csr */
+#define EDLC_XCLR      (ioaddr + 0x00) /* EDLC transmit "Clear IRQ" */
+#define EDLC_XMASK     (ioaddr + 0x01) /* EDLC transmit "IRQ Masks" */
+#define EDLC_RSTAT     (ioaddr + 0x02) /* EDLC receive csr */
+#define EDLC_RCLR      (ioaddr + 0x02) /* EDLC receive "Clear IRQ" */
+#define EDLC_RMASK     (ioaddr + 0x03) /* EDLC receive "IRQ Masks" */
+#define EDLC_XMODE     (ioaddr + 0x04) /* EDLC transmit Mode */
+#define EDLC_RMODE     (ioaddr + 0x05) /* EDLC receive Mode */
+#define EDLC_RESET     (ioaddr + 0x06) /* EDLC RESET register */
+#define EDLC_TDR1      (ioaddr + 0x07) /* "Time Domain Reflectometry" reg1 */
+#define EDLC_ADDR      (ioaddr + 0x08) /* EDLC station address, 6 bytes */
+                               /* 0x0E doesn't exist for r/w */
+#define EDLC_TDR2      (ioaddr + 0x0f) /* "Time Domain Reflectometry" reg2 */
+#define IE_GP          (ioaddr + 0x10) /* GP pointer (word register) */
+                               /* 0x11 is 2nd byte of GP Pointer */
+#define IE_RCNT                (ioaddr + 0x10) /* Count of bytes in rcv'd packet */
+                               /* 0x11 is 2nd byte of "Byte Count" */
+#define IE_MMODE       (ioaddr + 0x12) /* Memory Mode register */
+#define IE_DMA_RST     (ioaddr + 0x13) /* IE DMA Reset.  write only */
+#define IE_ISTAT       (ioaddr + 0x13) /* IE Interrupt Status.  read only */
+#define IE_RBUF                (ioaddr + 0x14) /* IE Receive Buffer port */
+#define IE_XBUF                (ioaddr + 0x15) /* IE Transmit Buffer port */
+#define IE_SAPROM      (ioaddr + 0x16) /* window on station addr prom */
+#define IE_RESET       (ioaddr + 0x17) /* any write causes Board Reset */
+
+/* bits in EDLC_XSTAT, interrupt clear on write, status when read */
+#define XS_TPOK                0x80    /* transmit packet successful */
+#define XS_CS          0x40    /* carrier sense */
+#define XS_RCVD                0x20    /* transmitted packet received */
+#define XS_SHORT       0x10    /* transmission media is shorted */
+#define XS_UFLW                0x08    /* underflow.  iff failed board */
+#define XS_COLL                0x04    /* collision occurred */
+#define XS_16COLL      0x02    /* 16th collision occurred */
+#define XS_PERR                0x01    /* parity error */
+
+#define XS_CLR_UFLW    0x08    /* clear underflow */
+#define XS_CLR_COLL    0x04    /* clear collision */
+#define XS_CLR_16COLL  0x02    /* clear 16th collision */
+#define XS_CLR_PERR    0x01    /* clear parity error */
+
+/* bits in EDLC_XMASK, mask/enable transmit interrupts.  register is r/w */
+#define XM_TPOK                0x80    /* =1 to enable Xmt Pkt OK interrupts */
+#define XM_RCVD                0x20    /* =1 to enable Xmt Pkt Rcvd ints */
+#define XM_UFLW                0x08    /* =1 to enable Xmt Underflow ints */
+#define XM_COLL                0x04    /* =1 to enable Xmt Collision ints */
+#define XM_COLL16      0x02    /* =1 to enable Xmt 16th Coll ints */
+#define XM_PERR                0x01    /* =1 to enable Xmt Parity Error ints */
+                               /* note: always clear this bit */
+#define XM_ALL         (XM_TPOK | XM_RCVD | XM_UFLW | XM_COLL | XM_COLL16)
+
+/* bits in EDLC_RSTAT, interrupt clear on write, status when read */
+#define RS_PKT_OK      0x80    /* received good packet */
+#define RS_RST_PKT     0x10    /* RESET packet received */
+#define RS_RUNT                0x08    /* Runt Pkt rcvd.  Len < 64 Bytes */
+#define RS_ALIGN       0x04    /* Alignment error. not 8 bit aligned */
+#define RS_CRC_ERR     0x02    /* Bad CRC on rcvd pkt */
+#define RS_OFLW                0x01    /* overflow for rcv FIFO */
+#define RS_VALID_BITS  ( RS_PKT_OK | RS_RST_PKT | RS_RUNT | RS_ALIGN | RS_CRC_ERR | RS_OFLW )
+                               /* all valid RSTAT bits */
+
+#define RS_CLR_PKT_OK  0x80    /* clear rcvd packet interrupt */
+#define RS_CLR_RST_PKT 0x10    /* clear RESET packet received */
+#define RS_CLR_RUNT    0x08    /* clear Runt Pckt received */
+#define RS_CLR_ALIGN   0x04    /* clear Alignment error */
+#define RS_CLR_CRC_ERR 0x02    /* clear CRC error */
+#define RS_CLR_OFLW    0x01    /* clear rcv FIFO Overflow */
+
+/* bits in EDLC_RMASK, mask/enable receive interrupts.  register is r/w */
+#define RM_PKT_OK      0x80    /* =1 to enable rcvd good packet ints */
+#define RM_RST_PKT     0x10    /* =1 to enable RESET packet ints */
+#define RM_RUNT                0x08    /* =1 to enable Runt Pkt rcvd ints */
+#define RM_ALIGN       0x04    /* =1 to enable Alignment error ints */
+#define RM_CRC_ERR     0x02    /* =1 to enable Bad CRC error ints */
+#define RM_OFLW                0x01    /* =1 to enable overflow error ints */
+
+/* bits in EDLC_RMODE, set Receive Packet mode.  register is r/w */
+#define RMD_TEST       0x80    /* =1 for Chip testing.  normally 0 */
+#define RMD_ADD_SIZ    0x10    /* =1 5-byte addr match.  normally 0 */
+#define RMD_EN_RUNT    0x08    /* =1 enable runt rcv.  normally 0 */
+#define RMD_EN_RST     0x04    /* =1 to rcv RESET pkt.  normally 0 */
+
+#define RMD_PROMISC    0x03    /* receive *all* packets.  unusual */
+#define RMD_MULTICAST  0x02    /* receive multicasts too.  unusual */
+#define RMD_BROADCAST  0x01    /* receive broadcasts & normal. usual */
+#define RMD_NO_PACKETS 0x00    /* don't receive any packets. unusual */
+
+/* bits in EDLC_XMODE, set Transmit Packet mode.  register is r/w */
+#define XMD_COLL_CNT   0xf0    /* coll's since success.  read-only */
+#define XMD_IG_PAR     0x08    /* =1 to ignore parity.  ALWAYS set */
+#define XMD_T_MODE     0x04    /* =1 to power xcvr. ALWAYS set this */
+#define XMD_LBC                0x02    /* =1 for loopbakc.  normally set */
+#define XMD_DIS_C      0x01    /* =1 disables contention. normally 0 */
+
+/* bits in EDLC_RESET, write only */
+#define RS_RESET       0x80    /* =1 to hold EDLC in reset state */
+
+/* bits in IE_MMODE, write only */
+#define MM_EN_DMA      0x80    /* =1 begin DMA xfer, Cplt clrs it */
+#define MM_EN_RCV      0x40    /* =1 allows Pkt rcv.  clr'd by rcv */
+#define MM_EN_XMT      0x20    /* =1 begin Xmt pkt.  Cplt clrs it */
+#define MM_BUS_PAGE    0x18    /* =00 ALWAYS.  Used when MUX=1 */
+#define MM_NET_PAGE    0x06    /* =00 ALWAYS.  Used when MUX=0 */
+#define MM_MUX         0x01    /* =1 means Rcv Buff on system bus */
+                               /* =0 means Xmt Buff on system bus */
+
+/* bits in IE_ISTAT, read only */
+#define IS_TDIAG       0x80    /* =1 if Diagnostic problem */
+#define IS_EN_RCV      0x20    /* =1 until frame is rcv'd cplt */
+#define IS_EN_XMT      0x10    /* =1 until frame is xmt'd cplt */
+#define IS_EN_DMA      0x08    /* =1 until DMA is cplt or aborted */
+#define IS_DMA_INT     0x04    /* =0 iff DMA done interrupt. */
+#define IS_R_INT       0x02    /* =0 iff unmasked Rcv interrupt */
+#define IS_X_INT       0x01    /* =0 iff unmasked Xmt interrupt */
+
diff --git a/drivers/net/ni5010.c b/drivers/net/ni5010.c
deleted file mode 100644 (file)
index 4d3f2e2..0000000
+++ /dev/null
@@ -1,771 +0,0 @@
-/*     ni5010.c: A network driver for the MiCom-Interlan NI5010 ethercard.
- *
- *     Copyright 1996,1997,2006 Jan-Pascal van Best and Andreas Mohr.
- *
- *     This software may be used and distributed according to the terms
- *     of the GNU General Public License, incorporated herein by reference.
- *
- *     The authors may be reached as:
- *             janpascal@vanbest.org           andi@lisas.de
- *
- *     Sources:
- *             Donald Becker's "skeleton.c"
- *             Crynwr ni5010 packet driver
- *
- *     Changes:
- *             v0.0: First test version
- *             v0.1: First working version
- *             v0.2:
- *             v0.3->v0.90: Now demand setting io and irq when loading as module
- *     970430  v0.91: modified for Linux 2.1.14
- *             v0.92: Implemented Andreas' (better) NI5010 probe
- *     970503  v0.93: Fixed auto-irq failure on warm reboot (JB)
- *     970623  v1.00: First kernel version (AM)
- *     970814  v1.01: Added detection of onboard receive buffer size (AM)
- *     060611  v1.02: slight cleanup: email addresses, driver modernization.
- *     Bugs:
- *             - not SMP-safe (no locking of I/O accesses)
- *             - Note that you have to patch ifconfig for the new /proc/net/dev
- *             format. It gives incorrect stats otherwise.
- *
- *     To do:
- *             Fix all bugs :-)
- *             Move some stuff to chipset_init()
- *             Handle xmt errors other than collisions
- *             Complete merge with Andreas' driver
- *             Implement ring buffers (Is this useful? You can't squeeze
- *                     too many packet in a 2k buffer!)
- *             Implement DMA (Again, is this useful? Some docs say DMA is
- *                     slower than programmed I/O)
- *
- *     Compile with:
- *             gcc -O2 -fomit-frame-pointer -m486 -D__KERNEL__ \
- *                     -DMODULE -c ni5010.c
- *
- *     Insert with e.g.:
- *             insmod ni5010.ko io=0x300 irq=5
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/errno.h>
-#include <linux/ioport.h>
-#include <linux/interrupt.h>
-#include <linux/delay.h>
-#include <linux/init.h>
-#include <linux/bitops.h>
-#include <asm/io.h>
-#include <asm/dma.h>
-
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
-
-#include "ni5010.h"
-
-static const char boardname[] = "NI5010";
-static char version[] __initdata =
-       "ni5010.c: v1.02 20060611 Jan-Pascal van Best and Andreas Mohr\n";
-
-/* bufsize_rcv == 0 means autoprobing */
-static unsigned int bufsize_rcv;
-
-#define JUMPERED_INTERRUPTS    /* IRQ line jumpered on board */
-#undef JUMPERED_DMA            /* No DMA used */
-#undef FULL_IODETECT           /* Only detect in portlist */
-
-#ifndef FULL_IODETECT
-/* A zero-terminated list of I/O addresses to be probed. */
-static unsigned int ports[] __initdata =
-       { 0x300, 0x320, 0x340, 0x360, 0x380, 0x3a0, 0 };
-#endif
-
-/* Use 0 for production, 1 for verification, >2 for debug */
-#ifndef NI5010_DEBUG
-#define NI5010_DEBUG 0
-#endif
-
-/* Information that needs to be kept for each board. */
-struct ni5010_local {
-       int o_pkt_size;
-       spinlock_t lock;
-};
-
-/* Index to functions, as function prototypes. */
-
-static int     ni5010_probe1(struct net_device *dev, int ioaddr);
-static int     ni5010_open(struct net_device *dev);
-static int     ni5010_send_packet(struct sk_buff *skb, struct net_device *dev);
-static irqreturn_t ni5010_interrupt(int irq, void *dev_id);
-static void    ni5010_rx(struct net_device *dev);
-static void    ni5010_timeout(struct net_device *dev);
-static int     ni5010_close(struct net_device *dev);
-static void    ni5010_set_multicast_list(struct net_device *dev);
-static void    reset_receiver(struct net_device *dev);
-
-static int     process_xmt_interrupt(struct net_device *dev);
-#define tx_done(dev) 1
-static void    hardware_send_packet(struct net_device *dev, char *buf, int length, int pad);
-static void    chipset_init(struct net_device *dev, int startp);
-static void    dump_packet(void *buf, int len);
-static void    ni5010_show_registers(struct net_device *dev);
-
-static int io;
-static int irq;
-
-struct net_device * __init ni5010_probe(int unit)
-{
-       struct net_device *dev = alloc_etherdev(sizeof(struct ni5010_local));
-       int *port;
-       int err = 0;
-
-       if (!dev)
-               return ERR_PTR(-ENOMEM);
-
-       if (unit >= 0) {
-               sprintf(dev->name, "eth%d", unit);
-               netdev_boot_setup_check(dev);
-               io = dev->base_addr;
-               irq = dev->irq;
-       }
-
-       PRINTK2((KERN_DEBUG "%s: Entering ni5010_probe\n", dev->name));
-
-       if (io > 0x1ff) {       /* Check a single specified location. */
-               err = ni5010_probe1(dev, io);
-       } else if (io != 0) {   /* Don't probe at all. */
-               err = -ENXIO;
-       } else {
-#ifdef FULL_IODETECT
-               for (io=0x200; io<0x400 && ni5010_probe1(dev, io) ; io+=0x20)
-                       ;
-               if (io == 0x400)
-                       err = -ENODEV;
-
-#else
-               for (port = ports; *port && ni5010_probe1(dev, *port); port++)
-                       ;
-               if (!*port)
-                       err = -ENODEV;
-#endif /* FULL_IODETECT */
-       }
-       if (err)
-               goto out;
-       err = register_netdev(dev);
-       if (err)
-               goto out1;
-       return dev;
-out1:
-       release_region(dev->base_addr, NI5010_IO_EXTENT);
-out:
-       free_netdev(dev);
-       return ERR_PTR(err);
-}
-
-static inline int rd_port(int ioaddr)
-{
-       inb(IE_RBUF);
-       return inb(IE_SAPROM);
-}
-
-static void __init trigger_irq(int ioaddr)
-{
-               outb(0x00, EDLC_RESET); /* Clear EDLC hold RESET state */
-               outb(0x00, IE_RESET);   /* Board reset */
-               outb(0x00, EDLC_XMASK); /* Disable all Xmt interrupts */
-               outb(0x00, EDLC_RMASK); /* Disable all Rcv interrupt */
-               outb(0xff, EDLC_XCLR);  /* Clear all pending Xmt interrupts */
-               outb(0xff, EDLC_RCLR);  /* Clear all pending Rcv interrupts */
-               /*
-                * Transmit packet mode: Ignore parity, Power xcvr,
-                *      Enable loopback
-                */
-               outb(XMD_IG_PAR | XMD_T_MODE | XMD_LBC, EDLC_XMODE);
-               outb(RMD_BROADCAST, EDLC_RMODE); /* Receive normal&broadcast */
-               outb(XM_ALL, EDLC_XMASK);       /* Enable all Xmt interrupts */
-               udelay(50);                     /* FIXME: Necessary? */
-               outb(MM_EN_XMT|MM_MUX, IE_MMODE); /* Start transmission */
-}
-
-static const struct net_device_ops ni5010_netdev_ops = {
-       .ndo_open               = ni5010_open,
-       .ndo_stop               = ni5010_close,
-       .ndo_start_xmit         = ni5010_send_packet,
-       .ndo_set_multicast_list = ni5010_set_multicast_list,
-       .ndo_tx_timeout         = ni5010_timeout,
-       .ndo_validate_addr      = eth_validate_addr,
-       .ndo_set_mac_address    = eth_mac_addr,
-       .ndo_change_mtu         = eth_change_mtu,
-};
-
-/*
- *      This is the real probe routine.  Linux has a history of friendly device
- *      probes on the ISA bus.  A good device probes avoids doing writes, and
- *      verifies that the correct device exists and functions.
- */
-
-static int __init ni5010_probe1(struct net_device *dev, int ioaddr)
-{
-       static unsigned version_printed;
-       struct ni5010_local *lp;
-       int i;
-       unsigned int data = 0;
-       int boguscount = 40;
-       int err = -ENODEV;
-
-       dev->base_addr = ioaddr;
-       dev->irq = irq;
-
-       if (!request_region(ioaddr, NI5010_IO_EXTENT, boardname))
-               return -EBUSY;
-
-       /*
-        * This is no "official" probe method, I've rather tested which
-        * probe works best with my seven NI5010 cards
-        * (they have very different serial numbers)
-        * Suggestions or failure reports are very, very welcome !
-        * But I think it is a relatively good probe method
-        * since it doesn't use any "outb"
-        * It should be nearly 100% reliable !
-        * well-known WARNING: this probe method (like many others)
-        * will hang the system if a NE2000 card region is probed !
-        *
-        *   - Andreas
-        */
-
-       PRINTK2((KERN_DEBUG "%s: entering ni5010_probe1(%#3x)\n",
-               dev->name, ioaddr));
-
-       if (inb(ioaddr+0) == 0xff)
-               goto out;
-
-       while ( (rd_port(ioaddr) & rd_port(ioaddr) & rd_port(ioaddr) &
-                rd_port(ioaddr) & rd_port(ioaddr) & rd_port(ioaddr)) != 0xff)
-       {
-               if (boguscount-- == 0)
-                       goto out;
-       }
-
-       PRINTK2((KERN_DEBUG "%s: I/O #1 passed!\n", dev->name));
-
-       for (i=0; i<32; i++)
-               if ( (data = rd_port(ioaddr)) != 0xff) break;
-       if (data==0xff)
-               goto out;
-
-       PRINTK2((KERN_DEBUG "%s: I/O #2 passed!\n", dev->name));
-
-       if ((data != SA_ADDR0) || (rd_port(ioaddr) != SA_ADDR1) ||
-           (rd_port(ioaddr) != SA_ADDR2))
-               goto out;
-
-       for (i=0; i<4; i++)
-               rd_port(ioaddr);
-
-       if ( (rd_port(ioaddr) != NI5010_MAGICVAL1) ||
-            (rd_port(ioaddr) != NI5010_MAGICVAL2) )
-               goto out;
-
-       PRINTK2((KERN_DEBUG "%s: I/O #3 passed!\n", dev->name));
-
-       if (NI5010_DEBUG && version_printed++ == 0)
-               printk(KERN_INFO "%s", version);
-
-       printk("NI5010 ethercard probe at 0x%x: ", ioaddr);
-
-       dev->base_addr = ioaddr;
-
-       for (i=0; i<6; i++) {
-               outw(i, IE_GP);
-               dev->dev_addr[i] = inb(IE_SAPROM);
-       }
-       printk("%pM ", dev->dev_addr);
-
-       PRINTK2((KERN_DEBUG "%s: I/O #4 passed!\n", dev->name));
-
-#ifdef JUMPERED_INTERRUPTS
-       if (dev->irq == 0xff)
-               ;
-       else if (dev->irq < 2) {
-               unsigned long irq_mask;
-
-               PRINTK2((KERN_DEBUG "%s: I/O #5 passed!\n", dev->name));
-
-               irq_mask = probe_irq_on();
-               trigger_irq(ioaddr);
-               mdelay(20);
-               dev->irq = probe_irq_off(irq_mask);
-
-               PRINTK2((KERN_DEBUG "%s: I/O #6 passed!\n", dev->name));
-
-               if (dev->irq == 0) {
-                       err = -EAGAIN;
-                       printk(KERN_WARNING "%s: no IRQ found!\n", dev->name);
-                       goto out;
-               }
-               PRINTK2((KERN_DEBUG "%s: I/O #7 passed!\n", dev->name));
-       } else if (dev->irq == 2) {
-               dev->irq = 9;
-       }
-#endif /* JUMPERED_INTERRUPTS */
-       PRINTK2((KERN_DEBUG "%s: I/O #9 passed!\n", dev->name));
-
-       /* DMA is not supported (yet?), so no use detecting it */
-       lp = netdev_priv(dev);
-
-       spin_lock_init(&lp->lock);
-
-       PRINTK2((KERN_DEBUG "%s: I/O #10 passed!\n", dev->name));
-
-/* get the size of the onboard receive buffer
- * higher addresses than bufsize are wrapped into real buffer
- * i.e. data for offs. 0x801 is written to 0x1 with a 2K onboard buffer
- */
-       if (!bufsize_rcv) {
-               outb(1, IE_MMODE);      /* Put Rcv buffer on system bus */
-               outw(0, IE_GP);         /* Point GP at start of packet */
-               outb(0, IE_RBUF);       /* set buffer byte 0 to 0 */
-               for (i = 1; i < 0xff; i++) {
-                       outw(i << 8, IE_GP); /* Point GP at packet size to be tested */
-                       outb(i, IE_RBUF);
-                       outw(0x0, IE_GP); /* Point GP at start of packet */
-                       data = inb(IE_RBUF);
-                       if (data == i) break;
-               }
-               bufsize_rcv = i << 8;
-               outw(0, IE_GP);         /* Point GP at start of packet */
-               outb(0, IE_RBUF);       /* set buffer byte 0 to 0 again */
-       }
-        printk("-> bufsize rcv/xmt=%d/%d\n", bufsize_rcv, NI5010_BUFSIZE);
-
-       dev->netdev_ops         = &ni5010_netdev_ops;
-       dev->watchdog_timeo     = HZ/20;
-
-       dev->flags &= ~IFF_MULTICAST;   /* Multicast doesn't work */
-
-       /* Shut up the ni5010 */
-       outb(0, EDLC_RMASK);    /* Mask all receive interrupts */
-       outb(0, EDLC_XMASK);    /* Mask all xmit interrupts */
-       outb(0xff, EDLC_RCLR);  /* Kill all pending rcv interrupts */
-       outb(0xff, EDLC_XCLR);  /* Kill all pending xmt interrupts */
-
-       printk(KERN_INFO "%s: NI5010 found at 0x%x, using IRQ %d", dev->name, ioaddr, dev->irq);
-       if (dev->dma)
-               printk(" & DMA %d", dev->dma);
-       printk(".\n");
-       return 0;
-out:
-       release_region(dev->base_addr, NI5010_IO_EXTENT);
-       return err;
-}
-
-/*
- * Open/initialize the board.  This is called (in the current kernel)
- * sometime after booting when the 'ifconfig' program is run.
- *
- * This routine should set everything up anew at each open, even
- * registers that "should" only need to be set once at boot, so that
- * there is a non-reboot way to recover if something goes wrong.
- */
-
-static int ni5010_open(struct net_device *dev)
-{
-       int ioaddr = dev->base_addr;
-       int i;
-
-       PRINTK2((KERN_DEBUG "%s: entering ni5010_open()\n", dev->name));
-
-       if (request_irq(dev->irq, ni5010_interrupt, 0, boardname, dev)) {
-               printk(KERN_WARNING "%s: Cannot get irq %#2x\n", dev->name, dev->irq);
-               return -EAGAIN;
-       }
-       PRINTK3((KERN_DEBUG "%s: passed open() #1\n", dev->name));
-        /*
-         * Always allocate the DMA channel after the IRQ,
-         * and clean up on failure.
-         */
-#ifdef JUMPERED_DMA
-        if (request_dma(dev->dma, cardname)) {
-               printk(KERN_WARNING "%s: Cannot get dma %#2x\n", dev->name, dev->dma);
-                free_irq(dev->irq, NULL);
-                return -EAGAIN;
-        }
-#endif /* JUMPERED_DMA */
-
-       PRINTK3((KERN_DEBUG "%s: passed open() #2\n", dev->name));
-       /* Reset the hardware here.  Don't forget to set the station address. */
-
-       outb(RS_RESET, EDLC_RESET);     /* Hold up EDLC_RESET while configing board */
-       outb(0, IE_RESET);              /* Hardware reset of ni5010 board */
-       outb(XMD_LBC, EDLC_XMODE);      /* Only loopback xmits */
-
-       PRINTK3((KERN_DEBUG "%s: passed open() #3\n", dev->name));
-       /* Set the station address */
-       for(i = 0;i < 6; i++) {
-               outb(dev->dev_addr[i], EDLC_ADDR + i);
-       }
-
-       PRINTK3((KERN_DEBUG "%s: Initialising ni5010\n", dev->name));
-       outb(0, EDLC_XMASK);    /* No xmit interrupts for now */
-       outb(XMD_IG_PAR | XMD_T_MODE | XMD_LBC, EDLC_XMODE);
-                               /* Normal packet xmit mode */
-       outb(0xff, EDLC_XCLR);  /* Clear all pending xmit interrupts */
-       outb(RMD_BROADCAST, EDLC_RMODE);
-                               /* Receive broadcast and normal packets */
-       reset_receiver(dev);    /* Ready ni5010 for receiving packets */
-
-       outb(0, EDLC_RESET);    /* Un-reset the ni5010 */
-
-       netif_start_queue(dev);
-
-       if (NI5010_DEBUG) ni5010_show_registers(dev);
-
-       PRINTK((KERN_DEBUG "%s: open successful\n", dev->name));
-       return 0;
-}
-
-static void reset_receiver(struct net_device *dev)
-{
-       int ioaddr = dev->base_addr;
-
-       PRINTK3((KERN_DEBUG "%s: resetting receiver\n", dev->name));
-       outw(0, IE_GP);         /* Receive packet at start of buffer */
-       outb(0xff, EDLC_RCLR);  /* Clear all pending rcv interrupts */
-       outb(0, IE_MMODE);      /* Put EDLC to rcv buffer */
-       outb(MM_EN_RCV, IE_MMODE); /* Enable rcv */
-       outb(0xff, EDLC_RMASK); /* Enable all rcv interrupts */
-}
-
-static void ni5010_timeout(struct net_device *dev)
-{
-       printk(KERN_WARNING "%s: transmit timed out, %s?\n", dev->name,
-                  tx_done(dev) ? "IRQ conflict" : "network cable problem");
-       /* Try to restart the adaptor. */
-       /* FIXME: Give it a real kick here */
-       chipset_init(dev, 1);
-       dev->trans_start = jiffies; /* prevent tx timeout */
-       netif_wake_queue(dev);
-}
-
-static int ni5010_send_packet(struct sk_buff *skb, struct net_device *dev)
-{
-       int length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
-
-       PRINTK2((KERN_DEBUG "%s: entering ni5010_send_packet\n", dev->name));
-
-       /*
-         * Block sending
-        */
-
-       netif_stop_queue(dev);
-       hardware_send_packet(dev, (unsigned char *)skb->data, skb->len, length-skb->len);
-       dev_kfree_skb (skb);
-       return NETDEV_TX_OK;
-}
-
-/*
- * The typical workload of the driver:
- * Handle the network interface interrupts.
- */
-static irqreturn_t ni5010_interrupt(int irq, void *dev_id)
-{
-       struct net_device *dev = dev_id;
-       struct ni5010_local *lp;
-       int ioaddr, status;
-       int xmit_was_error = 0;
-
-       PRINTK2((KERN_DEBUG "%s: entering ni5010_interrupt\n", dev->name));
-
-       ioaddr = dev->base_addr;
-       lp = netdev_priv(dev);
-
-       spin_lock(&lp->lock);
-       status = inb(IE_ISTAT);
-       PRINTK3((KERN_DEBUG "%s: IE_ISTAT = %#02x\n", dev->name, status));
-
-        if ((status & IS_R_INT) == 0) ni5010_rx(dev);
-
-        if ((status & IS_X_INT) == 0) {
-                xmit_was_error = process_xmt_interrupt(dev);
-        }
-
-        if ((status & IS_DMA_INT) == 0) {
-                PRINTK((KERN_DEBUG "%s: DMA complete (?)\n", dev->name));
-                outb(0, IE_DMA_RST); /* Reset DMA int */
-        }
-
-       if (!xmit_was_error)
-               reset_receiver(dev);
-       spin_unlock(&lp->lock);
-       return IRQ_HANDLED;
-}
-
-
-static void dump_packet(void *buf, int len)
-{
-       int i;
-
-       printk(KERN_DEBUG "Packet length = %#4x\n", len);
-       for (i = 0; i < len; i++){
-               if (i % 16 == 0) printk(KERN_DEBUG "%#4.4x", i);
-               if (i % 2 == 0) printk(" ");
-               printk("%2.2x", ((unsigned char *)buf)[i]);
-               if (i % 16 == 15) printk("\n");
-       }
-       printk("\n");
-}
-
-/* We have a good packet, get it out of the buffer. */
-static void ni5010_rx(struct net_device *dev)
-{
-       int ioaddr = dev->base_addr;
-       unsigned char rcv_stat;
-       struct sk_buff *skb;
-       int i_pkt_size;
-
-       PRINTK2((KERN_DEBUG "%s: entering ni5010_rx()\n", dev->name));
-
-       rcv_stat = inb(EDLC_RSTAT);
-       PRINTK3((KERN_DEBUG "%s: EDLC_RSTAT = %#2x\n", dev->name, rcv_stat));
-
-       if ( (rcv_stat & RS_VALID_BITS) != RS_PKT_OK) {
-               PRINTK((KERN_INFO "%s: receive error.\n", dev->name));
-               dev->stats.rx_errors++;
-               if (rcv_stat & RS_RUNT) dev->stats.rx_length_errors++;
-               if (rcv_stat & RS_ALIGN) dev->stats.rx_frame_errors++;
-               if (rcv_stat & RS_CRC_ERR) dev->stats.rx_crc_errors++;
-               if (rcv_stat & RS_OFLW) dev->stats.rx_fifo_errors++;
-               outb(0xff, EDLC_RCLR); /* Clear the interrupt */
-               return;
-       }
-
-        outb(0xff, EDLC_RCLR);  /* Clear the interrupt */
-
-       i_pkt_size = inw(IE_RCNT);
-       if (i_pkt_size > ETH_FRAME_LEN || i_pkt_size < 10 ) {
-               PRINTK((KERN_DEBUG "%s: Packet size error, packet size = %#4.4x\n",
-                       dev->name, i_pkt_size));
-               dev->stats.rx_errors++;
-               dev->stats.rx_length_errors++;
-               return;
-       }
-
-       /* Malloc up new buffer. */
-       skb = dev_alloc_skb(i_pkt_size + 3);
-       if (skb == NULL) {
-               printk(KERN_WARNING "%s: Memory squeeze, dropping packet.\n", dev->name);
-               dev->stats.rx_dropped++;
-               return;
-       }
-
-       skb_reserve(skb, 2);
-
-       /* Read packet into buffer */
-        outb(MM_MUX, IE_MMODE); /* Rcv buffer to system bus */
-       outw(0, IE_GP); /* Seek to beginning of packet */
-       insb(IE_RBUF, skb_put(skb, i_pkt_size), i_pkt_size);
-
-       if (NI5010_DEBUG >= 4)
-               dump_packet(skb->data, skb->len);
-
-       skb->protocol = eth_type_trans(skb,dev);
-       netif_rx(skb);
-       dev->stats.rx_packets++;
-       dev->stats.rx_bytes += i_pkt_size;
-
-       PRINTK2((KERN_DEBUG "%s: Received packet, size=%#4.4x\n",
-               dev->name, i_pkt_size));
-}
-
-static int process_xmt_interrupt(struct net_device *dev)
-{
-       struct ni5010_local *lp = netdev_priv(dev);
-       int ioaddr = dev->base_addr;
-       int xmit_stat;
-
-       PRINTK2((KERN_DEBUG "%s: entering process_xmt_interrupt\n", dev->name));
-
-       xmit_stat = inb(EDLC_XSTAT);
-       PRINTK3((KERN_DEBUG "%s: EDLC_XSTAT = %2.2x\n", dev->name, xmit_stat));
-
-       outb(0, EDLC_XMASK);    /* Disable xmit IRQ's */
-       outb(0xff, EDLC_XCLR);  /* Clear all pending xmit IRQ's */
-
-       if (xmit_stat & XS_COLL){
-               PRINTK((KERN_DEBUG "%s: collision detected, retransmitting\n",
-                       dev->name));
-               outw(NI5010_BUFSIZE - lp->o_pkt_size, IE_GP);
-               /* outb(0, IE_MMODE); */ /* xmt buf on sysbus FIXME: needed ? */
-               outb(MM_EN_XMT | MM_MUX, IE_MMODE);
-               outb(XM_ALL, EDLC_XMASK); /* Enable xmt IRQ's */
-               dev->stats.collisions++;
-               return 1;
-       }
-
-       /* FIXME: handle other xmt error conditions */
-
-       dev->stats.tx_packets++;
-       dev->stats.tx_bytes += lp->o_pkt_size;
-       netif_wake_queue(dev);
-
-       PRINTK2((KERN_DEBUG "%s: sent packet, size=%#4.4x\n",
-               dev->name, lp->o_pkt_size));
-
-       return 0;
-}
-
-/* The inverse routine to ni5010_open(). */
-static int ni5010_close(struct net_device *dev)
-{
-       int ioaddr = dev->base_addr;
-
-       PRINTK2((KERN_DEBUG "%s: entering ni5010_close\n", dev->name));
-#ifdef JUMPERED_INTERRUPTS
-       free_irq(dev->irq, NULL);
-#endif
-       /* Put card in held-RESET state */
-       outb(0, IE_MMODE);
-       outb(RS_RESET, EDLC_RESET);
-
-       netif_stop_queue(dev);
-
-       PRINTK((KERN_DEBUG "%s: %s closed down\n", dev->name, boardname));
-       return 0;
-
-}
-
-/* Set or clear the multicast filter for this adaptor.
-   num_addrs == -1      Promiscuous mode, receive all packets
-   num_addrs == 0       Normal mode, clear multicast list
-   num_addrs > 0        Multicast mode, receive normal and MC packets, and do
-                        best-effort filtering.
-*/
-static void ni5010_set_multicast_list(struct net_device *dev)
-{
-       short ioaddr = dev->base_addr;
-
-       PRINTK2((KERN_DEBUG "%s: entering set_multicast_list\n", dev->name));
-
-       if (dev->flags & IFF_PROMISC || dev->flags & IFF_ALLMULTI ||
-           !netdev_mc_empty(dev)) {
-               outb(RMD_PROMISC, EDLC_RMODE); /* Enable promiscuous mode */
-               PRINTK((KERN_DEBUG "%s: Entering promiscuous mode\n", dev->name));
-       } else {
-               PRINTK((KERN_DEBUG "%s: Entering broadcast mode\n", dev->name));
-               outb(RMD_BROADCAST, EDLC_RMODE);  /* Disable promiscuous mode, use normal mode */
-       }
-}
-
-static void hardware_send_packet(struct net_device *dev, char *buf, int length, int pad)
-{
-       struct ni5010_local *lp = netdev_priv(dev);
-       int ioaddr = dev->base_addr;
-       unsigned long flags;
-       unsigned int buf_offs;
-
-       PRINTK2((KERN_DEBUG "%s: entering hardware_send_packet\n", dev->name));
-
-        if (length > ETH_FRAME_LEN) {
-                PRINTK((KERN_WARNING "%s: packet too large, not possible\n",
-                        dev->name));
-                return;
-        }
-
-       if (NI5010_DEBUG) ni5010_show_registers(dev);
-
-       if (inb(IE_ISTAT) & IS_EN_XMT) {
-               PRINTK((KERN_WARNING "%s: sending packet while already transmitting, not possible\n",
-                       dev->name));
-               return;
-       }
-
-       if (NI5010_DEBUG > 3) dump_packet(buf, length);
-
-       buf_offs = NI5010_BUFSIZE - length - pad;
-
-       spin_lock_irqsave(&lp->lock, flags);
-       lp->o_pkt_size = length + pad;
-
-       outb(0, EDLC_RMASK);    /* Mask all receive interrupts */
-       outb(0, IE_MMODE);      /* Put Xmit buffer on system bus */
-       outb(0xff, EDLC_RCLR);  /* Clear out pending rcv interrupts */
-
-       outw(buf_offs, IE_GP); /* Point GP at start of packet */
-       outsb(IE_XBUF, buf, length); /* Put data in buffer */
-       while(pad--)
-               outb(0, IE_XBUF);
-
-       outw(buf_offs, IE_GP); /* Rewrite where packet starts */
-
-       /* should work without that outb() (Crynwr used it) */
-       /*outb(MM_MUX, IE_MMODE);*/ /* Xmt buffer to EDLC bus */
-       outb(MM_EN_XMT | MM_MUX, IE_MMODE); /* Begin transmission */
-       outb(XM_ALL, EDLC_XMASK); /* Cause interrupt after completion or fail */
-
-       spin_unlock_irqrestore(&lp->lock, flags);
-
-       netif_wake_queue(dev);
-
-       if (NI5010_DEBUG) ni5010_show_registers(dev);
-}
-
-static void chipset_init(struct net_device *dev, int startp)
-{
-       /* FIXME: Move some stuff here */
-       PRINTK3((KERN_DEBUG "%s: doing NOTHING in chipset_init\n", dev->name));
-}
-
-static void ni5010_show_registers(struct net_device *dev)
-{
-       int ioaddr = dev->base_addr;
-
-       PRINTK3((KERN_DEBUG "%s: XSTAT %#2.2x\n", dev->name, inb(EDLC_XSTAT)));
-       PRINTK3((KERN_DEBUG "%s: XMASK %#2.2x\n", dev->name, inb(EDLC_XMASK)));
-       PRINTK3((KERN_DEBUG "%s: RSTAT %#2.2x\n", dev->name, inb(EDLC_RSTAT)));
-       PRINTK3((KERN_DEBUG "%s: RMASK %#2.2x\n", dev->name, inb(EDLC_RMASK)));
-       PRINTK3((KERN_DEBUG "%s: RMODE %#2.2x\n", dev->name, inb(EDLC_RMODE)));
-       PRINTK3((KERN_DEBUG "%s: XMODE %#2.2x\n", dev->name, inb(EDLC_XMODE)));
-       PRINTK3((KERN_DEBUG "%s: ISTAT %#2.2x\n", dev->name, inb(IE_ISTAT)));
-}
-
-#ifdef MODULE
-static struct net_device *dev_ni5010;
-
-module_param(io, int, 0);
-module_param(irq, int, 0);
-MODULE_PARM_DESC(io, "ni5010 I/O base address");
-MODULE_PARM_DESC(irq, "ni5010 IRQ number");
-
-static int __init ni5010_init_module(void)
-{
-       PRINTK2((KERN_DEBUG "%s: entering init_module\n", boardname));
-       /*
-       if(io <= 0 || irq == 0){
-               printk(KERN_WARNING "%s: Autoprobing not allowed for modules.\n", boardname);
-               printk(KERN_WARNING "%s: Set symbols 'io' and 'irq'\n", boardname);
-               return -EINVAL;
-       }
-       */
-       if (io <= 0){
-               printk(KERN_WARNING "%s: Autoprobing for modules is hazardous, trying anyway..\n", boardname);
-       }
-
-       PRINTK2((KERN_DEBUG "%s: init_module irq=%#2x, io=%#3x\n", boardname, irq, io));
-       dev_ni5010 = ni5010_probe(-1);
-       if (IS_ERR(dev_ni5010))
-               return PTR_ERR(dev_ni5010);
-        return 0;
-}
-
-static void __exit ni5010_cleanup_module(void)
-{
-       PRINTK2((KERN_DEBUG "%s: entering cleanup_module\n", boardname));
-       unregister_netdev(dev_ni5010);
-       release_region(dev_ni5010->base_addr, NI5010_IO_EXTENT);
-       free_netdev(dev_ni5010);
-}
-module_init(ni5010_init_module);
-module_exit(ni5010_cleanup_module);
-#endif /* MODULE */
-MODULE_LICENSE("GPL");
diff --git a/drivers/net/ni5010.h b/drivers/net/ni5010.h
deleted file mode 100644 (file)
index e10e717..0000000
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * Racal-Interlan ni5010 Ethernet definitions
- *
- * This is an extension to the Linux operating system, and is covered by the
- * same GNU General Public License that covers that work.
- *
- * copyrights (c) 1996 by Jan-Pascal van Best (jvbest@wi.leidenuniv.nl)
- *
- * I have done a look in the following sources:
- *   crynwr-packet-driver by Russ Nelson
- */
-
-#define NI5010_BUFSIZE 2048    /* number of bytes in a buffer */
-
-#define NI5010_MAGICVAL0 0x00  /* magic-values for ni5010 card */
-#define NI5010_MAGICVAL1 0x55
-#define NI5010_MAGICVAL2 0xAA
-
-#define SA_ADDR0 0x02
-#define SA_ADDR1 0x07
-#define SA_ADDR2 0x01
-
-/* The number of low I/O ports used by the ni5010 ethercard. */
-#define NI5010_IO_EXTENT       32
-
-#define PRINTK(x) if (NI5010_DEBUG) printk x
-#define PRINTK2(x) if (NI5010_DEBUG>=2) printk x
-#define PRINTK3(x) if (NI5010_DEBUG>=3) printk x
-
-/* The various IE command registers */
-#define EDLC_XSTAT     (ioaddr + 0x00) /* EDLC transmit csr */
-#define EDLC_XCLR      (ioaddr + 0x00) /* EDLC transmit "Clear IRQ" */
-#define EDLC_XMASK     (ioaddr + 0x01) /* EDLC transmit "IRQ Masks" */
-#define EDLC_RSTAT     (ioaddr + 0x02) /* EDLC receive csr */
-#define EDLC_RCLR      (ioaddr + 0x02) /* EDLC receive "Clear IRQ" */
-#define EDLC_RMASK     (ioaddr + 0x03) /* EDLC receive "IRQ Masks" */
-#define EDLC_XMODE     (ioaddr + 0x04) /* EDLC transmit Mode */
-#define EDLC_RMODE     (ioaddr + 0x05) /* EDLC receive Mode */
-#define EDLC_RESET     (ioaddr + 0x06) /* EDLC RESET register */
-#define EDLC_TDR1      (ioaddr + 0x07) /* "Time Domain Reflectometry" reg1 */
-#define EDLC_ADDR      (ioaddr + 0x08) /* EDLC station address, 6 bytes */
-                               /* 0x0E doesn't exist for r/w */
-#define EDLC_TDR2      (ioaddr + 0x0f) /* "Time Domain Reflectometry" reg2 */
-#define IE_GP          (ioaddr + 0x10) /* GP pointer (word register) */
-                               /* 0x11 is 2nd byte of GP Pointer */
-#define IE_RCNT                (ioaddr + 0x10) /* Count of bytes in rcv'd packet */
-                               /* 0x11 is 2nd byte of "Byte Count" */
-#define IE_MMODE       (ioaddr + 0x12) /* Memory Mode register */
-#define IE_DMA_RST     (ioaddr + 0x13) /* IE DMA Reset.  write only */
-#define IE_ISTAT       (ioaddr + 0x13) /* IE Interrupt Status.  read only */
-#define IE_RBUF                (ioaddr + 0x14) /* IE Receive Buffer port */
-#define IE_XBUF                (ioaddr + 0x15) /* IE Transmit Buffer port */
-#define IE_SAPROM      (ioaddr + 0x16) /* window on station addr prom */
-#define IE_RESET       (ioaddr + 0x17) /* any write causes Board Reset */
-
-/* bits in EDLC_XSTAT, interrupt clear on write, status when read */
-#define XS_TPOK                0x80    /* transmit packet successful */
-#define XS_CS          0x40    /* carrier sense */
-#define XS_RCVD                0x20    /* transmitted packet received */
-#define XS_SHORT       0x10    /* transmission media is shorted */
-#define XS_UFLW                0x08    /* underflow.  iff failed board */
-#define XS_COLL                0x04    /* collision occurred */
-#define XS_16COLL      0x02    /* 16th collision occurred */
-#define XS_PERR                0x01    /* parity error */
-
-#define XS_CLR_UFLW    0x08    /* clear underflow */
-#define XS_CLR_COLL    0x04    /* clear collision */
-#define XS_CLR_16COLL  0x02    /* clear 16th collision */
-#define XS_CLR_PERR    0x01    /* clear parity error */
-
-/* bits in EDLC_XMASK, mask/enable transmit interrupts.  register is r/w */
-#define XM_TPOK                0x80    /* =1 to enable Xmt Pkt OK interrupts */
-#define XM_RCVD                0x20    /* =1 to enable Xmt Pkt Rcvd ints */
-#define XM_UFLW                0x08    /* =1 to enable Xmt Underflow ints */
-#define XM_COLL                0x04    /* =1 to enable Xmt Collision ints */
-#define XM_COLL16      0x02    /* =1 to enable Xmt 16th Coll ints */
-#define XM_PERR                0x01    /* =1 to enable Xmt Parity Error ints */
-                               /* note: always clear this bit */
-#define XM_ALL         (XM_TPOK | XM_RCVD | XM_UFLW | XM_COLL | XM_COLL16)
-
-/* bits in EDLC_RSTAT, interrupt clear on write, status when read */
-#define RS_PKT_OK      0x80    /* received good packet */
-#define RS_RST_PKT     0x10    /* RESET packet received */
-#define RS_RUNT                0x08    /* Runt Pkt rcvd.  Len < 64 Bytes */
-#define RS_ALIGN       0x04    /* Alignment error. not 8 bit aligned */
-#define RS_CRC_ERR     0x02    /* Bad CRC on rcvd pkt */
-#define RS_OFLW                0x01    /* overflow for rcv FIFO */
-#define RS_VALID_BITS  ( RS_PKT_OK | RS_RST_PKT | RS_RUNT | RS_ALIGN | RS_CRC_ERR | RS_OFLW )
-                               /* all valid RSTAT bits */
-
-#define RS_CLR_PKT_OK  0x80    /* clear rcvd packet interrupt */
-#define RS_CLR_RST_PKT 0x10    /* clear RESET packet received */
-#define RS_CLR_RUNT    0x08    /* clear Runt Pckt received */
-#define RS_CLR_ALIGN   0x04    /* clear Alignment error */
-#define RS_CLR_CRC_ERR 0x02    /* clear CRC error */
-#define RS_CLR_OFLW    0x01    /* clear rcv FIFO Overflow */
-
-/* bits in EDLC_RMASK, mask/enable receive interrupts.  register is r/w */
-#define RM_PKT_OK      0x80    /* =1 to enable rcvd good packet ints */
-#define RM_RST_PKT     0x10    /* =1 to enable RESET packet ints */
-#define RM_RUNT                0x08    /* =1 to enable Runt Pkt rcvd ints */
-#define RM_ALIGN       0x04    /* =1 to enable Alignment error ints */
-#define RM_CRC_ERR     0x02    /* =1 to enable Bad CRC error ints */
-#define RM_OFLW                0x01    /* =1 to enable overflow error ints */
-
-/* bits in EDLC_RMODE, set Receive Packet mode.  register is r/w */
-#define RMD_TEST       0x80    /* =1 for Chip testing.  normally 0 */
-#define RMD_ADD_SIZ    0x10    /* =1 5-byte addr match.  normally 0 */
-#define RMD_EN_RUNT    0x08    /* =1 enable runt rcv.  normally 0 */
-#define RMD_EN_RST     0x04    /* =1 to rcv RESET pkt.  normally 0 */
-
-#define RMD_PROMISC    0x03    /* receive *all* packets.  unusual */
-#define RMD_MULTICAST  0x02    /* receive multicasts too.  unusual */
-#define RMD_BROADCAST  0x01    /* receive broadcasts & normal. usual */
-#define RMD_NO_PACKETS 0x00    /* don't receive any packets. unusual */
-
-/* bits in EDLC_XMODE, set Transmit Packet mode.  register is r/w */
-#define XMD_COLL_CNT   0xf0    /* coll's since success.  read-only */
-#define XMD_IG_PAR     0x08    /* =1 to ignore parity.  ALWAYS set */
-#define XMD_T_MODE     0x04    /* =1 to power xcvr. ALWAYS set this */
-#define XMD_LBC                0x02    /* =1 for loopbakc.  normally set */
-#define XMD_DIS_C      0x01    /* =1 disables contention. normally 0 */
-
-/* bits in EDLC_RESET, write only */
-#define RS_RESET       0x80    /* =1 to hold EDLC in reset state */
-
-/* bits in IE_MMODE, write only */
-#define MM_EN_DMA      0x80    /* =1 begin DMA xfer, Cplt clrs it */
-#define MM_EN_RCV      0x40    /* =1 allows Pkt rcv.  clr'd by rcv */
-#define MM_EN_XMT      0x20    /* =1 begin Xmt pkt.  Cplt clrs it */
-#define MM_BUS_PAGE    0x18    /* =00 ALWAYS.  Used when MUX=1 */
-#define MM_NET_PAGE    0x06    /* =00 ALWAYS.  Used when MUX=0 */
-#define MM_MUX         0x01    /* =1 means Rcv Buff on system bus */
-                               /* =0 means Xmt Buff on system bus */
-
-/* bits in IE_ISTAT, read only */
-#define IS_TDIAG       0x80    /* =1 if Diagnostic problem */
-#define IS_EN_RCV      0x20    /* =1 until frame is rcv'd cplt */
-#define IS_EN_XMT      0x10    /* =1 until frame is xmt'd cplt */
-#define IS_EN_DMA      0x08    /* =1 until DMA is cplt or aborted */
-#define IS_DMA_INT     0x04    /* =0 iff DMA done interrupt. */
-#define IS_R_INT       0x02    /* =0 iff unmasked Rcv interrupt */
-#define IS_X_INT       0x01    /* =0 iff unmasked Xmt interrupt */
-
This page took 0.052273 seconds and 5 git commands to generate.