[3682] in linux-net channel archive

home help back first fref pref prev next nref lref last post

new lance patch - round 2

daemon@ATHENA.MIT.EDU (Tekno Soft Snc)
Sun Jul 14 07:07:31 1996

To: linux-net@vger.rutgers.edu
Date: 	Sat, 13 Jul 96 13:20:38 CEST
From: Tekno Soft Snc <MC3641@mclink.it>

Hi All,

This new other lance patch divide lance.c and lance32.c, and make possible
to link in the kernel only ISA cards or only PCI/VLB cards or both.

I think that next work must be to make a library where put the same lance
and
lance32 code (am7990.c ?) as 8390.c, so we can reduce the kernel size when
both
lance drivers are used.

This is the patch:

--- cut here --- cut here --- cut here --- cut here --- cut here --- cut
here
--- linux/drivers/net/lance.c.old       Fri Jul 12 19:47:06 1996
+++ linux/drivers/net/lance.c   Sat Jul 13 13:05:12 1996
@@ -169,6 +169,9 @@
  *
  *     Paul Gortmaker (gpg109@rsphy1.anu.edu.au):
  *     - hopefully fix above so Linux/Alpha can use ISA cards too.
+ *
+ *     Roberto Fichera (MC3641@mclink.it):
+ *     - removed the lance32 probing call
  */
 
 /* Set the number of Tx and Rx buffers, using Log_2(# buffers).
@@ -261,23 +264,17 @@
        {0x2260, "PCnet/ISA+ 79C961",           /* 79C961 PCnet/ISA+,
Plug-n-Play.  */
                LANCE_ENABLE_AUTOSELECT + LANCE_MUST_REINIT_RING +
                        LANCE_HAS_MISSED_FRAME},
-       {0x2420, "PCnet/PCI 79C970",            /* 79C970 or 79C974
PCnet-SCSI, PCI. */
-               LANCE_ENABLE_AUTOSELECT + LANCE_MUST_REINIT_RING +
-                       LANCE_HAS_MISSED_FRAME},
        /* Bug: the PCnet/PCI actually uses the PCnet/VLB ID number, so
just call
                it the PCnet32. */
        {0x2430, "PCnet32",                                     /* 79C965
PCnet for VL bus. */
                LANCE_ENABLE_AUTOSELECT + LANCE_MUST_REINIT_RING +
                        LANCE_HAS_MISSED_FRAME},
-        {0x2621, "PCnet/PCI-II 79C970A",        /* 79C970A PCInetPCI II.
*/
-                LANCE_ENABLE_AUTOSELECT + LANCE_MUST_REINIT_RING +
-                        LANCE_HAS_MISSED_FRAME},
        {0x0,    "PCnet (unknown)",
                LANCE_ENABLE_AUTOSELECT + LANCE_MUST_REINIT_RING +
                        LANCE_HAS_MISSED_FRAME},
 };
 
-enum {OLD_LANCE = 0, PCNET_ISA=1, PCNET_ISAP=2, PCNET_PCI=3, PCNET_VLB=4,
PCNET_PCI_II=5, LANCE_UNKNOWN=6};
+enum {OLD_LANCE = 0, PCNET_ISA=1, PCNET_ISAP=2, PCNET_VLB=3,
LANCE_UNKNOWN=4};
 
 /* Non-zero only if the current card is a PCI with BIOS-set IRQ. */
 static unsigned char pci_irq_line = 0;
@@ -311,45 +308,6 @@
        if (high_memory <= 16*1024*1024)
                lance_need_isa_bounce_buffers = 0;
 
-#if defined(CONFIG_PCI)
-    if (pcibios_present()) {
-           int pci_index;
-               printk("lance.c: PCI bios is present, checking for
devices...\n");
-               for (pci_index = 0; pci_index < 8; pci_index++) {
-                       unsigned char pci_bus, pci_device_fn;
-                       unsigned int pci_ioaddr;
-                       unsigned short pci_command;
-
-                       if (pcibios_find_device (PCI_VENDOR_ID_AMD,
-                                                                       
PCI_DEVICE_ID_AMD_LANCE, pci_index,
-                                                                       
&pci_bus, &pci_device_fn) != 0)
-                               break;
-                       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);
-                       /* Remove I/O space marker in bit 0. */
-                       pci_ioaddr &= ~3;
-                       /* PCI Spec 2.1 states that it is either the
driver or PCI card's
-                        * responsibility to set the PCI Master Enable Bit
if needed.
-                        *      (From Mark Stockton
<marks@schooner.sys.hou.compaq.com>)
-                        */
-                       pcibios_read_config_word(pci_bus, pci_device_fn,
-                                                                       
PCI_COMMAND, &pci_command);
-                       if ( ! (pci_command & PCI_COMMAND_MASTER)) {
-                               printk("PCI Master Bit has not been set.
Setting...\n");
-                               pci_command |= PCI_COMMAND_MASTER;
-                               pcibios_write_config_word(pci_bus,
pci_device_fn,
-                                                                         
       PCI_COMMAND, pci_command);
-                       }
-                       printk("Found PCnet/PCI at %#x, irq %d.\n",
-                                  pci_ioaddr, pci_irq_line);
-                       lance_probe1(pci_ioaddr);
-                       pci_irq_line = 0;
-               }
-       }
-#endif  /* defined(CONFIG_PCI) */
-
        for (port = lance_portlist; *port; port++) {
                int ioaddr = *port;
 
@@ -424,6 +382,10 @@
                        if (chip_table[lance_version].id_number ==
chip_version)
                                break;
                }
+               
+               /* only ISA card on chip_table are probed */
+               if (lance_version == PCNET_VLB || lance_version ==
LANCE_UNKNOWN)
+                       return;
        }
 
        dev = init_etherdev(0, 0);
@@ -439,15 +401,6 @@
        dev->base_addr = ioaddr;
        request_region(ioaddr, LANCE_TOTAL_SIZE,
chip_table[lance_version].name);
 
-#ifdef CONFIG_LANCE32
-        /* look if it's a PCI or VLB chip */
-        if (lance_version == PCNET_PCI || lance_version == PCNET_VLB ||
lance_version == PCNET_PCI_II) {
-           extern void lance32_probe1 (struct device *dev, const char
*chipname, int pci_irq_line);
-           
-           lance32_probe1 (dev, chipname, pci_irq_line);
-           return;
-       }
-#endif    
        /* Make certain the data structures used by the LANCE are aligned
and DMAble. */
        lp = (struct lance_private *) LANCE_KMALLOC(sizeof(*lp));
        if (lance_debug > 6) printk(" (#0x%05lx)", (unsigned long)lp);
--- linux/drivers/net/lance32.c.old     Fri Jul 12 19:47:13 1996
+++ linux/drivers/net/lance32.c Sat Jul 13 13:13:35 1996
@@ -13,7 +13,7 @@
  *     This driver is for PCnet32 and PCnetPCI based ethercards
  */
 
-static const char *version = "lance32.c:v0.10 28.4.96
tsbogend@bigbug.franken.de\n";
+static const char *version = "lance32.c:v0.20 28.4.96
tsbogend@bigbug.franken.de\n";
 
 #include <linux/kernel.h>
 #include <linux/sched.h>
@@ -33,6 +33,14 @@
 #include <linux/etherdevice.h>
 #include <linux/skbuff.h>
 
+static unsigned int lance32_portlist[] = {0x300, 0x320, 0x340, 0x360, 0};
+void lance32_probe1(int ioaddr);
+
+#ifdef HAVE_DEVLIST
+struct netdev_entry lance32_drv =
+{"lance32", lance32_probe1, LANCE_TOTAL_SIZE, lance32_portlist};
+#endif
+
 #ifdef LANCE32_DEBUG
 int lance32_debug = LANCE32_DEBUG;
 #else
@@ -60,6 +68,9 @@
  *         short period of time; now we do a reinit of the lance; the
  *         bug was triggered by doing ifconfig eth0 <ip> broadcast <addr>
  *         and hangs the machine (thanks to Klaus Liedl for debugging)
+ *
+ * v0.20:  Roberto Fichera MC3641@mclink.it
+ *         divided from lance.c
  */
 
 
@@ -137,7 +148,43 @@
        unsigned long lock;
 };
 
+#define LANCE_MUST_PAD          0x00000001
+#define LANCE_ENABLE_AUTOSELECT 0x00000002
+#define LANCE_MUST_REINIT_RING  0x00000004
+#define LANCE_MUST_UNRESET      0x00000008
+#define LANCE_HAS_MISSED_FRAME  0x00000010
+
+/* A mapping from the chip ID number to the part number and features.
+   These are from the datasheets -- in real life the '970 version
+   reportedly has the same ID as the '965. */
+static struct lance_chip_type {
+       int id_number;
+       const char *name;
+       int flags;
+} chip_table[] = {
+       {0x2420, "PCnet/PCI 79C970",            /* 79C970 or 79C974
PCnet-SCSI, PCI. */
+               LANCE_ENABLE_AUTOSELECT + LANCE_MUST_REINIT_RING +
+                       LANCE_HAS_MISSED_FRAME},
+       /* Bug: the PCnet/PCI actually uses the PCnet/VLB ID number, so
just call
+               it the PCnet32. */
+       {0x2430, "PCnet32",                                     /* 79C965
PCnet for VL bus. */
+               LANCE_ENABLE_AUTOSELECT + LANCE_MUST_REINIT_RING +
+                       LANCE_HAS_MISSED_FRAME},
+        {0x2621, "PCnet/PCI-II 79C970A",        /* 79C970A PCInetPCI II.
*/
+                LANCE_ENABLE_AUTOSELECT + LANCE_MUST_REINIT_RING +
+                        LANCE_HAS_MISSED_FRAME},
+       {0x0,    "PCnet (unknown)",
+               LANCE_ENABLE_AUTOSELECT + LANCE_MUST_REINIT_RING +
+                       LANCE_HAS_MISSED_FRAME},
+};
+
+enum {PCNET_PCI=0, PCNET_VLB=1, PCNET_PCI_II=2, LANCE_UNKNOWN=3};
+
+/* Non-zero only if the current card is a PCI with BIOS-set IRQ. */
+static unsigned char pci_irq_line = 0;
+
 static int lance32_open(struct device *dev);
+static int lance32_open_fail(struct device *dev);
 static void lance32_init_ring(struct device *dev);
 static int lance32_start_xmit(struct sk_buff *skb, struct device *dev);
 static int lance32_rx(struct device *dev);
@@ -147,15 +194,118 @@
 static void lance32_set_multicast_list(struct device *dev);
 
 
+int lance32_init(void)
+{
+       int *port;
+
+#if defined(CONFIG_PCI)
+    if (pcibios_present()) {
+           int pci_index;
+               printk("lance32.c: PCI bios is present, checking for
devices...\n");
+               for (pci_index = 0; pci_index < 8; pci_index++) {
+                       unsigned char pci_bus, pci_device_fn;
+                       unsigned int pci_ioaddr;
+                       unsigned short pci_command;
+
+                       if (pcibios_find_device (PCI_VENDOR_ID_AMD,
+                                                                       
PCI_DEVICE_ID_AMD_LANCE, pci_index,
+                                                                       
&pci_bus, &pci_device_fn) != 0)
+                               break;
+                       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);
+                       /* Remove I/O space marker in bit 0. */
+                       pci_ioaddr &= ~3;
+                       /* PCI Spec 2.1 states that it is either the
driver or PCI card's
+                        * responsibility to set the PCI Master Enable Bit
if needed.
+                        *      (From Mark Stockton
<marks@schooner.sys.hou.compaq.com>)
+                        */
+                       pcibios_read_config_word(pci_bus, pci_device_fn,
+                                                                       
PCI_COMMAND, &pci_command);
+                       if ( ! (pci_command & PCI_COMMAND_MASTER)) {
+                               printk("PCI Master Bit has not been set.
Setting...\n");
+                               pci_command |= PCI_COMMAND_MASTER;
+                               pcibios_write_config_word(pci_bus,
pci_device_fn,
+                                                                         
       PCI_COMMAND, pci_command);
+                       }
+                       printk("Found PCnet/PCI at %#x, irq %d.\n",
+                                  pci_ioaddr, pci_irq_line);
+                       lance32_probe1(pci_ioaddr);
+                       pci_irq_line = 0;
+               }
+       }
+#endif  /* defined(CONFIG_PCI) */
+
+       for (port = lance32_portlist; *port; port++) {
+               int ioaddr = *port;
+
+               if ( check_region(ioaddr, LANCE_TOTAL_SIZE) == 0) {
+                       /* Detect "normal" 0x57 0x57 and the NI6510EB 0x52
0x44
+                          signatures w/ minimal I/O reads */
+                       char offset15, offset14 = inb(ioaddr + 14);
+                       
+                       if ((offset14 == 0x52 || offset14 == 0x57) &&
+                               ((offset15 = inb(ioaddr + 15)) == 0x57 ||
offset15 == 0x44))
+                               lance32_probe1(ioaddr);
+               }
+       }
+       return 0;
+}
 
 /* lance32_probe1 */
-void lance32_probe1(struct device *dev, char *chipname, int pci_irq_line)
+void lance32_probe1(int ioaddr)
 {
+       struct device *dev;
        struct lance32_private *lp;
-        int ioaddr = dev->base_addr;
        short dma_channels;                                     /* Mark
spuriously-busy DMA channels */    
-        int i;
-    
+        int i, reset_val, lance_version;
+       const char *chipname;
+
+       /* Reset the LANCE.      */
+       reset_val = inw(ioaddr+LANCE_RESET); /* Reset the LANCE */
+       outw(reset_val, ioaddr+LANCE_RESET);
+
+       outw(0x0000, ioaddr+LANCE_ADDR); /* Switch to window 0 */
+       if (inw(ioaddr+LANCE_DATA) != 0x0004)
+               return;
+
+       /* Get the version of the chip. */
+       outw(88, ioaddr+LANCE_ADDR);
+       if (inw(ioaddr+LANCE_ADDR) != 88) {
+               return;
+       } else {                                                        /*
Good, it's a newer chip. */
+               int chip_version = inw(ioaddr+LANCE_DATA);
+               outw(89, ioaddr+LANCE_ADDR);
+               chip_version |= inw(ioaddr+LANCE_DATA) << 16;
+               if (lance32_debug > 2)
+                       printk("  LANCE chip version is %#x.\n",
chip_version);
+               if ((chip_version & 0xfff) != 0x003)
+                       return;
+               chip_version = (chip_version >> 12) & 0xffff;
+               for (lance_version = 0;
chip_table[lance_version].id_number; lance_version++) {
+                       if (chip_table[lance_version].id_number ==
chip_version)
+                               break;
+               }
+
+               /* only VLB/PCI card on chip_table are probed */
+               if (lance_version == LANCE_UNKNOWN)
+                       return;
+       }
+
+       dev = init_etherdev(0, 0);
+       dev->open = lance32_open_fail;
+       chipname = chip_table[lance_version].name;
+       printk("%s: %s at %#3x,", dev->name, chipname, ioaddr);
+
+       /* There is a 16 byte station address PROM at the base address.
+          The first six bytes are the station address. */
+       for (i = 0; i < 6; i++)
+               printk(" %2.2x", dev->dev_addr[i] = inb(ioaddr + i));
+
+       dev->base_addr = ioaddr;
+       request_region(ioaddr, LANCE_TOTAL_SIZE,
chip_table[lance_version].name);
+
        /* Make certain the data structures used by the LANCE are 16byte
aligned and DMAble. */
        lp = (struct lance32_private *) (((unsigned
long)kmalloc(sizeof(*lp)+15, GFP_DMA | GFP_KERNEL)+15) & ~15);
       
@@ -284,6 +434,12 @@
        dev->set_multicast_list = &lance32_set_multicast_list;
 
        return;
+}
+
+static int
+lance32_open_fail(struct device *dev)
+{
+       return -ENODEV;
 }
 
 
--- linux/drivers/net/Config.in.old     Fri Jul 12 19:55:24 1996
+++ linux/drivers/net/Config.in Fri Jul 12 19:58:21 1996
@@ -53,9 +53,7 @@
     tristate '3c590 series (592/595/597) "Vortex" support' CONFIG_VORTEX
   fi
   bool 'AMD LANCE and PCnet (AT1500 and NE2100) support' CONFIG_LANCE
-  if [ "$CONFIG_LANCE" = "y" ]; then
-    bool 'AMD PCInet32 (VLB and PCI) support' CONFIG_LANCE32
-  fi  
+  bool 'AMD LANCE PCnet/VLB and PCnet/PCI support' CONFIG_LANCE32
   bool 'Western Digital/SMC cards' CONFIG_NET_VENDOR_SMC
   if [ "$CONFIG_NET_VENDOR_SMC" = "y" ]; then
     tristate 'WD80*3 support' CONFIG_WD80x3
--- linux/drivers/net/Makefile.old      Fri Jul 12 19:59:09 1996
+++ linux/drivers/net/Makefile  Fri Jul 12 19:59:27 1996
@@ -237,9 +237,10 @@
 
 ifeq ($(CONFIG_LANCE),y)
 L_OBJS += lance.o
-  ifeq ($(CONFIG_LANCE32),y)
-  L_OBJS += lance32.o
-  endif
+endif
+
+ifeq ($(CONFIG_LANCE32),y)
+L_OBJS += lance32.o
 endif
 
 ifeq ($(CONFIG_SUNLANCE),y)
--- linux/net/core/dev.c.old    Fri Jul 12 20:02:54 1996
+++ linux/net/core/dev.c        Fri Jul 12 20:02:54 1996
@@ -1361,6 +1361,7 @@
  *
  */
 extern int lance_init(void);
+extern int lance32_init(void);
 extern int ni65_init(void);
 extern int pi_init(void);
 extern void sdla_setup(void);
@@ -1391,6 +1392,9 @@
         */
 #if defined(CONFIG_LANCE)
        lance_init();
+#endif
+#if defined(CONFIG_LANCE32)
+       lance32_init();
 #endif
 #if defined(CONFIG_NI65)
        ni65_init();

--- cut here --- cut here --- cut here --- cut here --- cut here --- cut
here

--
Roberto Fichera - email MC3641@mclink.it


home help back first fref pref prev next nref lref last post