patch-2.2.11 linux/drivers/net/ne2k-pci.c
Next file: linux/drivers/net/net_init.c
Previous file: linux/drivers/net/mace.c
Back to the patch index
Back to the overall index
- Lines: 339
- Date:
Mon Aug 9 12:04:39 1999
- Orig file:
v2.2.10/linux/drivers/net/ne2k-pci.c
- Orig date:
Sun Jan 24 22:04:02 1999
diff -u --recursive --new-file v2.2.10/linux/drivers/net/ne2k-pci.c linux/drivers/net/ne2k-pci.c
@@ -24,11 +24,8 @@
/* Our copyright info must remain in the binary. */
static const char *version =
-"ne2k-pci.c:v0.99L 2/7/98 D. Becker/P. Gortmaker http://cesdis.gsfc.nasa.gov/linux/drivers/ne2k-pci.html\n";
+"ne2k-pci.c:vpre-1.00e 5/27/99 D. Becker/P. Gortmaker http://cesdis.gsfc.nasa.gov/linux/drivers/ne2k-pci.html\n";
-#ifdef MODVERSIONS
-#include <linux/modversions.h>
-#endif
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/sched.h>
@@ -44,6 +41,13 @@
#include <linux/etherdevice.h>
#include "8390.h"
+#if defined(__powerpc__)
+#define inl_le(addr) le32_to_cpu(inl(addr))
+#define inw_le(addr) le16_to_cpu(inw(addr))
+#define insl insl_ns
+#define outsl outsl_ns
+#endif
+
/* Set statically or when loading the driver module. */
static int debug = 1;
@@ -58,19 +62,34 @@
/* Do we have a non std. amount of memory? (in units of 256 byte pages) */
/* #define PACKETBUF_MEMSIZE 0x40 */
+#define ne2k_flags reg0 /* Rename an existing field to store flags! */
+
+/* Only the low 8 bits are usable for non-init-time flags! */
+enum {
+ HOLTEK_FDX=1, /* Full duplex -> set 0x80 at offset 0x20. */
+ ONLY_16BIT_IO=2, ONLY_32BIT_IO=4, /* Chip can do only 16/32-bit xfers. */
+ STOP_PG_0x60=0x100,
+};
+
+/* This will eventually be converted to the standard PCI probe table. */
+
static struct {
unsigned short vendor, dev_id;
char *name;
+ int flags;
}
pci_clone_list[] __initdata = {
- {0x10ec, 0x8029, "RealTek RTL-8029"},
- {0x1050, 0x0940, "Winbond 89C940"},
- {0x11f6, 0x1401, "Compex RL2000"},
- {0x8e2e, 0x3000, "KTI ET32P2"},
- {0x4a14, 0x5000, "NetVin NV5000SC"},
- {0x1106, 0x0926, "Via 82C926"},
- {0x10bd, 0x0e34, "SureCom NE34"},
- {0x1050, 0x5a5a, "Winbond"},
+ {0x10ec, 0x8029, "RealTek RTL-8029", 0},
+ {0x1050, 0x0940, "Winbond 89C940", 0},
+ {0x11f6, 0x1401, "Compex RL2000", 0},
+ {0x8e2e, 0x3000, "KTI ET32P2", 0},
+ {0x4a14, 0x5000, "NetVin NV5000SC", 0},
+ {0x1106, 0x0926, "Via 86C926", ONLY_16BIT_IO},
+ {0x10bd, 0x0e34, "SureCom NE34", 0},
+ {0x1050, 0x5a5a, "Winbond", 0},
+ {0x12c3, 0x0058, "Holtek HT80232", ONLY_16BIT_IO | HOLTEK_FDX},
+ {0x12c3, 0x5598, "Holtek HT80229",
+ ONLY_32BIT_IO | HOLTEK_FDX | STOP_PG_0x60 },
{0,}
};
@@ -86,7 +105,8 @@
#define NESM_STOP_PG 0x80 /* Last page +1 of RX ring */
int ne2k_pci_probe(struct device *dev);
-static struct device *ne2k_pci_probe1(struct device *dev, int ioaddr, int irq);
+static struct device *ne2k_pci_probe1(struct device *dev, int ioaddr, int irq,
+ int chip_idx);
static int ne2k_pci_open(struct device *dev);
static int ne2k_pci_close(struct device *dev);
@@ -115,17 +135,13 @@
int
init_module(void)
{
- int retval;
-
/* We must emit version information. */
if (debug)
printk(KERN_INFO "%s", version);
- retval = ne2k_pci_probe(0);
-
- if (retval) {
- printk(KERN_NOTICE "ne2k-pci.c: no (useable) cards found, driver NOT installed.\n");
- return retval;
+ if (ne2k_pci_probe(0)) {
+ printk(KERN_NOTICE "ne2k-pci.c: No useable cards found, driver NOT installed.\n");
+ return -ENODEV;
}
lock_8390_module();
return 0;
@@ -225,7 +241,7 @@
printk("ne2k-pci.c: PCI NE2000 clone '%s' at I/O %#x, IRQ %d.\n",
pci_clone_list[i].name, pci_ioaddr, pci_irq_line);
- dev = ne2k_pci_probe1(dev, pci_ioaddr, pci_irq_line);
+ dev = ne2k_pci_probe1(dev, pci_ioaddr, pci_irq_line, i);
if (dev == 0) {
/* Should not happen. */
printk(KERN_ERR "ne2k-pci: Probe of PCI card at %#x failed.\n",
@@ -247,11 +263,11 @@
return cards_found ? 0 : -ENODEV;
}
-__initfunc (static struct device *ne2k_pci_probe1(struct device *dev, int ioaddr, int irq))
+__initfunc (static struct device *ne2k_pci_probe1(struct device *dev, int ioaddr, int irq,
+ int chip_idx))
{
int i;
unsigned char SA_prom[32];
- const char *name = NULL;
int start_page, stop_page;
int reg0 = inb(ioaddr);
@@ -273,6 +289,8 @@
}
}
+ dev = init_etherdev(dev, 0);
+
/* Reset card. Who knows what dain-bramaged state it was left in. */
{
unsigned long reset_start_time = jiffies;
@@ -321,59 +339,47 @@
}
-#ifdef notdef
- /* Some broken PCI cards don't respect the byte-wide
- request in program_seq above, and hence don't have doubled up values.
- */
- for(i = 0; i < 32 /*sizeof(SA_prom)*/; i+=2) {
- SA_prom[i] = inb(ioaddr + NE_DATAPORT);
- SA_prom[i+1] = inb(ioaddr + NE_DATAPORT);
- if (SA_prom[i] != SA_prom[i+1])
- sa_prom_doubled = 0;
- }
-
- if (sa_prom_doubled)
- for (i = 0; i < 16; i++)
- SA_prom[i] = SA_prom[i+i];
-#else
- for(i = 0; i < 32 /*sizeof(SA_prom)*/; i++)
- SA_prom[i] = inb(ioaddr + NE_DATAPORT);
+ /* Note: all PCI cards have at least 16 bit access, so we don't have
+ to check for 8 bit cards. Most cards permit 32 bit access. */
-#endif
+ if (pci_clone_list[chip_idx].flags & ONLY_32BIT_IO) {
+ for (i = 0; i < 4 ; i++)
+ ((u32 *)SA_prom)[i] = le32_to_cpu(inl(ioaddr + NE_DATAPORT));
+ } else
+ for(i = 0; i < 32 /*sizeof(SA_prom)*/; i++)
+ SA_prom[i] = inb(ioaddr + NE_DATAPORT);
/* We always set the 8390 registers for word mode. */
outb(0x49, ioaddr + EN0_DCFG);
start_page = NESM_START_PG;
- stop_page = NESM_STOP_PG;
- /* Set up the rest of the parameters. */
- name = "PCI NE2000";
-
- dev = init_etherdev(dev, 0);
+ stop_page =
+ pci_clone_list[chip_idx].flags&STOP_PG_0x60 ? 0x60 : NESM_STOP_PG;
+ /* Set up the rest of the parameters. */
dev->irq = irq;
dev->base_addr = ioaddr;
/* Allocate dev->priv and fill in 8390 specific dev fields. */
if (ethdev_init(dev)) {
printk ("%s: unable to get memory for dev->priv.\n", dev->name);
- kfree(dev);
return 0;
}
request_region(ioaddr, NE_IO_EXTENT, dev->name);
printk("%s: %s found at %#x, IRQ %d, ",
- dev->name, name, ioaddr, dev->irq);
+ dev->name, pci_clone_list[chip_idx].name, ioaddr, dev->irq);
for(i = 0; i < 6; i++) {
printk("%2.2X%s", SA_prom[i], i == 5 ? ".\n": ":");
dev->dev_addr[i] = SA_prom[i];
}
- ei_status.name = name;
+ ei_status.name = pci_clone_list[chip_idx].name;
ei_status.tx_start_page = start_page;
ei_status.stop_page = stop_page;
ei_status.word16 = 1;
+ ei_status.ne2k_flags = pci_clone_list[chip_idx].flags;
ei_status.rx_start_page = start_page + TX_PAGES;
#ifdef PACKETBUF_MEMSIZE
@@ -447,9 +453,9 @@
/* This *shouldn't* happen. If it does, it's the last thing you'll see */
if (ei_status.dmaing) {
printk("%s: DMAing conflict in ne2k_pci_get_8390_hdr "
- "[DMAstat:%d][irqlock:%d][intr:%ld].\n",
+ "[DMAstat:%d][irqlock:%d][intr:%d].\n",
dev->name, ei_status.dmaing, ei_status.irqlock,
- dev->interrupt);
+ (int)dev->interrupt);
return;
}
@@ -461,11 +467,12 @@
outb(ring_page, nic_base + EN0_RSARHI);
outb(E8390_RREAD+E8390_START, nic_base + NE_CMD);
-#if defined(USE_LONGIO)
- *(u32*)hdr = inl(NE_BASE + NE_DATAPORT);
-#else
- insw(NE_BASE + NE_DATAPORT, hdr, sizeof(struct e8390_pkt_hdr)>>1);
-#endif
+ if (ei_status.ne2k_flags & ONLY_16BIT_IO) {
+ insw(NE_BASE + NE_DATAPORT, hdr, sizeof(struct e8390_pkt_hdr)>>1);
+ } else {
+ *(u32*)hdr = le32_to_cpu(inl(NE_BASE + NE_DATAPORT));
+ le16_to_cpus(&hdr->count);
+ }
outb(ENISR_RDC, nic_base + EN0_ISR); /* Ack intr. */
ei_status.dmaing &= ~0x01;
@@ -485,12 +492,14 @@
/* This *shouldn't* happen. If it does, it's the last thing you'll see */
if (ei_status.dmaing) {
printk("%s: DMAing conflict in ne2k_pci_block_input "
- "[DMAstat:%d][irqlock:%d][intr:%ld].\n",
+ "[DMAstat:%d][irqlock:%d][intr:%d].\n",
dev->name, ei_status.dmaing, ei_status.irqlock,
- dev->interrupt);
+ (int)dev->interrupt);
return;
}
ei_status.dmaing |= 0x01;
+ if (ei_status.ne2k_flags & ONLY_32BIT_IO)
+ count = (count + 3) & 0xFFFC;
outb(E8390_NODMA+E8390_PAGE0+E8390_START, nic_base+ NE_CMD);
outb(count & 0xff, nic_base + EN0_RCNTLO);
outb(count >> 8, nic_base + EN0_RCNTHI);
@@ -498,21 +507,21 @@
outb(ring_offset >> 8, nic_base + EN0_RSARHI);
outb(E8390_RREAD+E8390_START, nic_base + NE_CMD);
-#if defined(USE_LONGIO)
- insl(NE_BASE + NE_DATAPORT, buf, count>>2);
- if (count & 3) {
- buf += count & ~3;
- if (count & 2)
- *((u16*)buf)++ = inw(NE_BASE + NE_DATAPORT);
- if (count & 1)
- *buf = inb(NE_BASE + NE_DATAPORT);
- }
-#else
- insw(NE_BASE + NE_DATAPORT,buf,count>>1);
- if (count & 0x01) {
- buf[count-1] = inb(NE_BASE + NE_DATAPORT);
+ if (ei_status.ne2k_flags & ONLY_16BIT_IO) {
+ insw(NE_BASE + NE_DATAPORT,buf,count>>1);
+ if (count & 0x01) {
+ buf[count-1] = inb(NE_BASE + NE_DATAPORT);
+ }
+ } else {
+ insl(NE_BASE + NE_DATAPORT, buf, count>>2);
+ if (count & 3) {
+ buf += count & ~3;
+ if (count & 2)
+ *((u16*)buf)++ = le16_to_cpu(inw(NE_BASE + NE_DATAPORT));
+ if (count & 1)
+ *buf = inb(NE_BASE + NE_DATAPORT);
+ }
}
-#endif
outb(ENISR_RDC, nic_base + EN0_ISR); /* Ack intr. */
ei_status.dmaing &= ~0x01;
@@ -527,15 +536,18 @@
/* On little-endian it's always safe to round the count up for
word writes. */
- if (count & 0x01)
- count++;
+ if (ei_status.ne2k_flags & ONLY_32BIT_IO)
+ count = (count + 3) & 0xFFFC;
+ else
+ if (count & 0x01)
+ count++;
/* This *shouldn't* happen. If it does, it's the last thing you'll see */
if (ei_status.dmaing) {
printk("%s: DMAing conflict in ne2k_pci_block_output."
- "[DMAstat:%d][irqlock:%d][intr:%ld]\n",
+ "[DMAstat:%d][irqlock:%d][intr:%d]\n",
dev->name, ei_status.dmaing, ei_status.irqlock,
- dev->interrupt);
+ (int)dev->interrupt);
return;
}
ei_status.dmaing |= 0x01;
@@ -561,16 +573,16 @@
outb(0x00, nic_base + EN0_RSARLO);
outb(start_page, nic_base + EN0_RSARHI);
outb(E8390_RWRITE+E8390_START, nic_base + NE_CMD);
-#if defined(USE_LONGIO)
- outsl(NE_BASE + NE_DATAPORT, buf, count>>2);
- if (count & 3) {
- buf += count & ~3;
- if (count & 2)
- outw(*((u16*)buf)++, NE_BASE + NE_DATAPORT);
+ if (ei_status.ne2k_flags & ONLY_16BIT_IO) {
+ outsw(NE_BASE + NE_DATAPORT, buf, count>>1);
+ } else {
+ outsl(NE_BASE + NE_DATAPORT, buf, count>>2);
+ if (count & 3) {
+ buf += count & ~3;
+ if (count & 2)
+ outw(cpu_to_le16(*((u16*)buf)++), NE_BASE + NE_DATAPORT);
+ }
}
-#else
- outsw(NE_BASE + NE_DATAPORT, buf, count>>1);
-#endif
dma_start = jiffies;
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)