fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / drivers / net / ne.c
index 9de5ccc..a5c4199 100644 (file)
@@ -29,6 +29,7 @@
     last in cleanup_modue()
     Richard Guenther    : Added support for ISAPnP cards
     Paul Gortmaker     : Discontinued PCI support - use ne2k-pci.c instead.
+    Hayato Fujiwara    : Add m32r support.
 
 */
 
@@ -49,12 +50,19 @@ static const char version2[] =
 #include <linux/delay.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
+#include <linux/jiffies.h>
 
 #include <asm/system.h>
 #include <asm/io.h>
 
+#if defined(CONFIG_TOSHIBA_RBTX4927) || defined(CONFIG_TOSHIBA_RBTX4938)
+#include <asm/tx4938/rbtx4938.h>
+#endif
+
 #include "8390.h"
 
+#define DRV_NAME "ne"
+
 /* Some defines that people can play with if so inclined. */
 
 /* Do we support clones that don't adhere to 14,15 of the SAprom ? */
@@ -108,8 +116,11 @@ bad_clone_list[] __initdata = {
     {"E-LAN100", "E-LAN200", {0x00, 0x00, 0x5d}}, /* Broken ne1000 clones */
     {"PCM-4823", "PCM-4823", {0x00, 0xc0, 0x6c}}, /* Broken Advantech MoBo */
     {"REALTEK", "RTL8019", {0x00, 0x00, 0xe8}}, /* no-name with Realtek chip */
+#if defined(CONFIG_TOSHIBA_RBTX4927) || defined(CONFIG_TOSHIBA_RBTX4938)
+    {"RBHMA4X00-RTL8019", "RBHMA4X00/RTL8019", {0x00, 0x60, 0x0a}},  /* Toshiba built-in */
+#endif
     {"LCS-8834", "LCS-8836", {0x04, 0x04, 0x37}}, /* ShinyNet (SET) */
-    {0,}
+    {NULL,}
 };
 #endif
 
@@ -126,6 +137,15 @@ bad_clone_list[] __initdata = {
 #define NESM_START_PG  0x40    /* First page of TX buffer */
 #define NESM_STOP_PG   0x80    /* Last page +1 of RX ring */
 
+#if defined(CONFIG_PLAT_MAPPI)
+#  define DCR_VAL 0x4b
+#elif defined(CONFIG_PLAT_OAKS32R)  || \
+   defined(CONFIG_TOSHIBA_RBTX4927) || defined(CONFIG_TOSHIBA_RBTX4938)
+#  define DCR_VAL 0x48         /* 8-bit mode */
+#else
+#  define DCR_VAL 0x49
+#endif
+
 static int ne_probe1(struct net_device *dev, int ioaddr);
 static int ne_probe_isapnp(struct net_device *dev);
 
@@ -140,7 +160,7 @@ static void ne_block_input(struct net_device *dev, int count,
 static void ne_block_output(struct net_device *dev, const int count,
                const unsigned char *buf, const int start_page);
 
-\f
+
 /*  Probe for various non-shared-memory ethercards.
 
    NEx000-clone boards have a Station Address PROM (SAPROM) in the packet
@@ -194,15 +214,7 @@ static int __init do_ne_probe(struct net_device *dev)
        return -ENODEV;
 }
 
-static void cleanup_card(struct net_device *dev)
-{
-       struct pnp_dev *idev = (struct pnp_dev *)ei_status.priv;
-       if (idev)
-               pnp_device_detach(idev);
-       free_irq(dev->irq, dev);
-       release_region(dev->base_addr, NE_IO_EXTENT);
-}
-
+#ifndef MODULE
 struct net_device * __init ne_probe(int unit)
 {
        struct net_device *dev = alloc_ei_netdev();
@@ -214,19 +226,19 @@ struct net_device * __init ne_probe(int unit)
        sprintf(dev->name, "eth%d", unit);
        netdev_boot_setup_check(dev);
 
+#ifdef CONFIG_TOSHIBA_RBTX4938
+       dev->base_addr = RBTX4938_RTL_8019_BASE;
+       dev->irq = RBTX4938_RTL_8019_IRQ;
+#endif
        err = do_ne_probe(dev);
        if (err)
                goto out;
-       err = register_netdev(dev);
-       if (err)
-               goto out1;
        return dev;
-out1:
-       cleanup_card(dev);
 out:
        free_netdev(dev);
        return ERR_PTR(err);
 }
+#endif
 
 static int __init ne_probe_isapnp(struct net_device *dev)
 {
@@ -284,7 +296,7 @@ static int __init ne_probe1(struct net_device *dev, int ioaddr)
        int reg0, ret;
        static unsigned version_printed;
 
-       if (!request_region(ioaddr, NE_IO_EXTENT, dev->name))
+       if (!request_region(ioaddr, NE_IO_EXTENT, DRV_NAME))
                return -EBUSY;
 
        reg0 = inb_p(ioaddr);
@@ -331,7 +343,7 @@ static int __init ne_probe1(struct net_device *dev, int ioaddr)
                outb(inb(ioaddr + NE_RESET), ioaddr + NE_RESET);
 
                while ((inb_p(ioaddr + EN0_ISR) & ENISR_RESET) == 0)
-               if (jiffies - reset_start_time > 2*HZ/100) {
+               if (time_after(jiffies, reset_start_time + 2*HZ/100)) {
                        if (bad_card) {
                                printk(" (warning: no reset ack)");
                                break;
@@ -383,15 +395,32 @@ static int __init ne_probe1(struct net_device *dev, int ioaddr)
                for (i = 0; i < 16; i++)
                        SA_prom[i] = SA_prom[i+i];
                /* We must set the 8390 for word mode. */
-               outb_p(0x49, ioaddr + EN0_DCFG);
+               outb_p(DCR_VAL, ioaddr + EN0_DCFG);
                start_page = NESM_START_PG;
-               stop_page = NESM_STOP_PG;
+
+               /*
+                * Realtek RTL8019AS datasheet says that the PSTOP register
+                * shouldn't exceed 0x60 in 8-bit mode.
+                * This chip can be identified by reading the signature from
+                * the  remote byte count registers (otherwise write-only)...
+                */
+               if ((DCR_VAL & 0x01) == 0 &&            /* 8-bit mode */
+                   inb(ioaddr + EN0_RCNTLO) == 0x50 &&
+                   inb(ioaddr + EN0_RCNTHI) == 0x70)
+                       stop_page = 0x60;
+               else
+                       stop_page = NESM_STOP_PG;
        } else {
                start_page = NE1SM_START_PG;
-               stop_page = NE1SM_STOP_PG;
+               stop_page  = NE1SM_STOP_PG;
        }
 
+#if  defined(CONFIG_PLAT_MAPPI) || defined(CONFIG_PLAT_OAKS32R)
+       neX000 = ((SA_prom[14] == 0x57  &&  SA_prom[15] == 0x57)
+               || (SA_prom[14] == 0x42 && SA_prom[15] == 0x42));
+#else
        neX000 = (SA_prom[14] == 0x57  &&  SA_prom[15] == 0x57);
+#endif
        ctron =  (SA_prom[0] == 0x00 && SA_prom[1] == 0x00 && SA_prom[2] == 0x1d);
        copam =  (SA_prom[14] == 0x49 && SA_prom[15] == 0x00);
 
@@ -472,10 +501,20 @@ static int __init ne_probe1(struct net_device *dev, int ioaddr)
 
        dev->base_addr = ioaddr;
 
+#ifdef CONFIG_PLAT_MAPPI
+       outb_p(E8390_NODMA + E8390_PAGE1 + E8390_STOP,
+               ioaddr + E8390_CMD); /* 0x61 */
+       for (i = 0 ; i < ETHER_ADDR_LEN ; i++) {
+               dev->dev_addr[i] = SA_prom[i]
+                       = inb_p(ioaddr + EN1_PHYS_SHIFT(i));
+               printk(" %2.2x", SA_prom[i]);
+       }
+#else
        for(i = 0; i < ETHER_ADDR_LEN; i++) {
                printk(" %2.2x", SA_prom[i]);
                dev->dev_addr[i] = SA_prom[i];
        }
+#endif
 
        printk("\n%s: %s found at %#x, using IRQ %d.\n",
                dev->name, name, ioaddr, dev->irq);
@@ -483,7 +522,9 @@ static int __init ne_probe1(struct net_device *dev, int ioaddr)
        ei_status.name = name;
        ei_status.tx_start_page = start_page;
        ei_status.stop_page = stop_page;
-       ei_status.word16 = (wordlength == 2);
+
+       /* Use 16-bit mode only if this wasn't overridden by DCR_VAL */
+       ei_status.word16 = (wordlength == 2 && (DCR_VAL & 0x01));
 
        ei_status.rx_start_page = start_page + TX_PAGES;
 #ifdef PACKETBUF_MEMSIZE
@@ -502,8 +543,14 @@ static int __init ne_probe1(struct net_device *dev, int ioaddr)
        dev->poll_controller = ei_poll;
 #endif
        NS8390_init(dev, 0);
+
+       ret = register_netdev(dev);
+       if (ret)
+               goto out_irq;
        return 0;
 
+out_irq:
+       free_irq(dev->irq, dev);
 err_out:
        release_region(ioaddr, NE_IO_EXTENT);
        return ret;
@@ -541,7 +588,7 @@ static void ne_reset_8390(struct net_device *dev)
 
        /* This check _should_not_ be necessary, omit eventually. */
        while ((inb_p(NE_BASE+EN0_ISR) & ENISR_RESET) == 0)
-               if (jiffies - reset_start_time > 2*HZ/100) {
+               if (time_after(jiffies, reset_start_time + 2*HZ/100)) {
                        printk(KERN_WARNING "%s: ne_reset_8390() did not complete.\n", dev->name);
                        break;
                }
@@ -748,7 +795,7 @@ retry:
 #endif
 
        while ((inb_p(nic_base + EN0_ISR) & ENISR_RDC) == 0)
-               if (jiffies - dma_start > 2*HZ/100) {           /* 20ms */
+               if (time_after(jiffies, dma_start + 2*HZ/100)) {                /* 20ms */
                        printk(KERN_WARNING "%s: timeout waiting for Tx RDC.\n", dev->name);
                        ne_reset_8390(dev);
                        NS8390_init(dev,1);
@@ -760,7 +807,7 @@ retry:
        return;
 }
 
-\f
+
 #ifdef MODULE
 #define MAX_NE_CARDS   4       /* Max number of NE cards per module */
 static struct net_device *dev_ne[MAX_NE_CARDS];
@@ -768,9 +815,9 @@ static int io[MAX_NE_CARDS];
 static int irq[MAX_NE_CARDS];
 static int bad[MAX_NE_CARDS];  /* 0xbad = bad sig or no reset ack */
 
-MODULE_PARM(io, "1-" __MODULE_STRING(MAX_NE_CARDS) "i");
-MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_NE_CARDS) "i");
-MODULE_PARM(bad, "1-" __MODULE_STRING(MAX_NE_CARDS) "i");
+module_param_array(io, int, NULL, 0);
+module_param_array(irq, int, NULL, 0);
+module_param_array(bad, int, NULL, 0);
 MODULE_PARM_DESC(io, "I/O base address(es),required");
 MODULE_PARM_DESC(irq, "IRQ number(s)");
 MODULE_PARM_DESC(bad, "Accept card(s) with bad signatures");
@@ -782,7 +829,7 @@ that the ne2k probe is the last 8390 based probe to take place (as it
 is at boot) and so the probe will get confused by any other 8390 cards.
 ISA device autoprobes on a running machine are not recommended anyway. */
 
-int init_module(void)
+int __init init_module(void)
 {
        int this_dev, found = 0;
 
@@ -794,11 +841,8 @@ int init_module(void)
                dev->mem_end = bad[this_dev];
                dev->base_addr = io[this_dev];
                if (do_ne_probe(dev) == 0) {
-                       if (register_netdev(dev) == 0) {
-                               dev_ne[found++] = dev;
-                               continue;
-                       }
-                       cleanup_card(dev);
+                       dev_ne[found++] = dev;
+                       continue;
                }
                free_netdev(dev);
                if (found)
@@ -814,7 +858,16 @@ int init_module(void)
        return -ENODEV;
 }
 
-void cleanup_module(void)
+static void cleanup_card(struct net_device *dev)
+{
+       struct pnp_dev *idev = (struct pnp_dev *)ei_status.priv;
+       if (idev)
+               pnp_device_detach(idev);
+       free_irq(dev->irq, dev);
+       release_region(dev->base_addr, NE_IO_EXTENT);
+}
+
+void __exit cleanup_module(void)
 {
        int this_dev;