31 #include <linux/module.h>
32 #include <linux/kernel.h>
33 #include <linux/errno.h>
34 #include <linux/string.h>
38 #include <linux/netdevice.h>
49 {0x300, 0x280, 0x380, 0x240, 0};
60 const unsigned char *
buf,
int start_page);
64 #define WD_START_PG 0x00
65 #define WD03_STOP_PG 0x20
66 #define WD13_STOP_PG 0x40
70 #define WD_MEMENB 0x40
74 #define WD_NIC_OFFSET 16
75 #define WD_IO_EXTENT 32
95 if (base_addr > 0x1ff) {
99 i = wd_probe1(dev, base_addr);
106 else if (base_addr != 0)
109 for (i = 0; wd_portlist[
i]; i++) {
110 int ioaddr = wd_portlist[
i];
114 if (wd_probe1(dev, ioaddr) == 0) {
139 err = do_wd_probe(dev);
151 .ndo_stop = wd_close,
159 #ifdef CONFIG_NET_POLL_CONTROLLER
160 .ndo_poll_controller = ei_poll,
171 const char *model_name;
172 static unsigned version_printed;
174 for (i = 0; i < 8; i++)
175 checksum +=
inb(ioaddr + 8 + i);
176 if (
inb(ioaddr + 8) == 0xff
177 ||
inb(ioaddr + 9) == 0xff
178 || (checksum & 0xff) != 0xFF)
183 printk(
KERN_WARNING "wd.c: user supplied mem_start or mem_end not on 8kB boundary - ignored.\n");
188 if (
ei_debug && version_printed++ == 0)
191 for (i = 0; i < 6; i++)
194 printk(
"%s: WD80x3 at %#3x, %pM",
202 if (
inb(ioaddr+0) ==
'P' &&
inb(ioaddr+1) ==
'D') {
203 unsigned char reg5 =
inb(ioaddr+5);
205 switch (
inb(ioaddr+2)) {
206 case 0x03: word16 = 0; model_name =
"PDI8023-8";
break;
207 case 0x05: word16 = 0; model_name =
"PDUC8023";
break;
208 case 0x0a: word16 = 1; model_name =
"PDI8023-16";
break;
210 default: word16 = 0; model_name =
"PDI8023";
break;
212 dev->
mem_start = ((reg5 & 0x1c) + 0xc0) << 12;
213 dev->
irq = (reg5 & 0xe0) == 0xe0 ? 10 : (reg5 >> 5) + 1;
221 for (i = 0; i < 6; i++)
222 if (
inb(ioaddr+i) !=
inb(ioaddr+8+i))
226 model_name =
"WD8003-old";
230 outb( tmp ^ 0x01, ioaddr+1 );
231 if (((
inb( ioaddr+1) & 0x01) == 0x01)
232 && (tmp & 0x01) == 0x01 ) {
237 model_name =
"WD8013";
240 model_name =
"WD8003";
245 #ifndef final_version
246 if ( !ancient && (
inb(ioaddr+1) & 0x01) != (word16 & 0x01))
247 printk(
"\nWD80?3: Bus width conflict, %d (probe) != %d (reg report).",
248 word16 ? 16 : 8, (
inb(ioaddr+1) & 0x01) ? 16 : 8);
252 #if defined(WD_SHMEM) && WD_SHMEM > 0x80000
259 if (reg0 == 0xff || reg0 == 0) {
266 if (high_addr_bits == 0x1f || word16 == 0)
267 high_addr_bits = 0x01;
268 dev->
mem_start = ((reg0&0x3f) << 13) + (high_addr_bits << 19);
277 static const int irqmap[] = {9, 3, 5, 7, 10, 11, 15, 4};
280 if (ancient || reg1 == 0xff) {
282 unsigned long irq_mask;
303 dev->
irq = word16 ? 10 : 5;
305 dev->
irq = irqmap[((reg4 >> 5) & 0x03) + (reg1 & 0x04)];
306 }
else if (dev->
irq == 2)
313 printk (
" unable to get IRQ %d.\n", dev->
irq);
341 printk(
" %s, IRQ %d, shared memory at %#lx-%#lx.\n",
346 ei_status.block_output = wd_block_output;
347 ei_status.get_8390_hdr = wd_get_8390_hdr;
355 if (
inb(ioaddr+14) & 0x20)
356 outb(
inb(ioaddr+4)|0x80, ioaddr+4);
390 if (
ei_debug > 1)
printk(
"resetting the WD80x3 t=%lu...", jiffies);
423 ((
unsigned int*)hdr)[0] =
readl(hdr_start);
456 wd_block_output(
struct net_device *dev,
int count,
const unsigned char *
buf,
479 printk(
"%s: Shutting down ethercard.\n", dev->
name);
494 #define MAX_WD_CARDS 4
495 static struct net_device *dev_wd[MAX_WD_CARDS];
496 static int io[MAX_WD_CARDS];
497 static int irq[MAX_WD_CARDS];
498 static int mem[MAX_WD_CARDS];
499 static int mem_end[MAX_WD_CARDS];
507 MODULE_PARM_DESC(mem,
"memory base address(es)(ignored for PureData boards)");
509 MODULE_DESCRIPTION(
"ISA Western Digital wd8003/wd8013 ; SMC Elite, Elite16 ethernet driver");
518 int this_dev, found = 0;
520 for (this_dev = 0; this_dev < MAX_WD_CARDS; this_dev++) {
521 if (io[this_dev] == 0) {
522 if (this_dev != 0)
break;
523 printk(
KERN_NOTICE "wd.c: Presently autoprobing (not recommended) for a single card.\n");
525 dev = alloc_ei_netdev();
528 dev->
irq = irq[this_dev];
531 dev->
mem_end = mem_end[this_dev];
532 if (do_wd_probe(dev) == 0) {
533 dev_wd[found++] =
dev;
545 static void cleanup_card(
struct net_device *dev)
557 for (this_dev = 0; this_dev < MAX_WD_CARDS; this_dev++) {