]> nv-tegra.nvidia Code Review - linux-3.10.git/blob - drivers/net/wd.c
[BNX2]: factor out gzip unpacker
[linux-3.10.git] / drivers / net / wd.c
1 /* wd.c: A WD80x3 ethernet driver for linux. */
2 /*
3         Written 1993-94 by Donald Becker.
4
5         Copyright 1993 United States Government as represented by the
6         Director, National Security Agency.
7
8         This software may be used and distributed according to the terms
9         of the GNU General Public License, incorporated herein by reference.
10
11         The author may be reached as becker@scyld.com, or C/O
12         Scyld Computing Corporation
13         410 Severn Ave., Suite 210
14         Annapolis MD 21403
15
16         This is a driver for WD8003 and WD8013 "compatible" ethercards.
17
18         Thanks to Russ Nelson (nelson@crnwyr.com) for loaning me a WD8013.
19
20         Changelog:
21
22         Paul Gortmaker  : multiple card support for module users, support
23                           for non-standard memory sizes.
24
25
26 */
27
28 static const char version[] =
29         "wd.c:v1.10 9/23/94 Donald Becker (becker@cesdis.gsfc.nasa.gov)\n";
30
31 #include <linux/module.h>
32 #include <linux/kernel.h>
33 #include <linux/errno.h>
34 #include <linux/string.h>
35 #include <linux/init.h>
36 #include <linux/interrupt.h>
37 #include <linux/delay.h>
38 #include <linux/netdevice.h>
39 #include <linux/etherdevice.h>
40
41 #include <asm/io.h>
42 #include <asm/system.h>
43
44 #include "8390.h"
45
46 #define DRV_NAME "wd"
47
48 /* A zero-terminated list of I/O addresses to be probed. */
49 static unsigned int wd_portlist[] __initdata =
50 {0x300, 0x280, 0x380, 0x240, 0};
51
52 static int wd_probe1(struct net_device *dev, int ioaddr);
53
54 static int wd_open(struct net_device *dev);
55 static void wd_reset_8390(struct net_device *dev);
56 static void wd_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr,
57                                                 int ring_page);
58 static void wd_block_input(struct net_device *dev, int count,
59                                                   struct sk_buff *skb, int ring_offset);
60 static void wd_block_output(struct net_device *dev, int count,
61                                                         const unsigned char *buf, int start_page);
62 static int wd_close(struct net_device *dev);
63
64
65 #define WD_START_PG             0x00    /* First page of TX buffer */
66 #define WD03_STOP_PG    0x20    /* Last page +1 of RX ring */
67 #define WD13_STOP_PG    0x40    /* Last page +1 of RX ring */
68
69 #define WD_CMDREG               0               /* Offset to ASIC command register. */
70 #define  WD_RESET               0x80    /* Board reset, in WD_CMDREG. */
71 #define  WD_MEMENB              0x40    /* Enable the shared memory. */
72 #define WD_CMDREG5              5               /* Offset to 16-bit-only ASIC register 5. */
73 #define  ISA16                  0x80    /* Enable 16 bit access from the ISA bus. */
74 #define  NIC16                  0x40    /* Enable 16 bit access from the 8390. */
75 #define WD_NIC_OFFSET   16              /* Offset to the 8390 from the base_addr. */
76 #define WD_IO_EXTENT    32
77
78
79 /*      Probe for the WD8003 and WD8013.  These cards have the station
80         address PROM at I/O ports <base>+8 to <base>+13, with a checksum
81         following. A Soundblaster can have the same checksum as an WDethercard,
82         so we have an extra exclusionary check for it.
83
84         The wd_probe1() routine initializes the card and fills the
85         station address field. */
86
87 static int __init do_wd_probe(struct net_device *dev)
88 {
89         int i;
90         struct resource *r;
91         int base_addr = dev->base_addr;
92         int irq = dev->irq;
93         int mem_start = dev->mem_start;
94         int mem_end = dev->mem_end;
95
96         if (base_addr > 0x1ff) {        /* Check a user specified location. */
97                 r = request_region(base_addr, WD_IO_EXTENT, "wd-probe");
98                 if ( r == NULL)
99                         return -EBUSY;
100                 i = wd_probe1(dev, base_addr);
101                 if (i != 0)
102                         release_region(base_addr, WD_IO_EXTENT);
103                 else
104                         r->name = dev->name;
105                 return i;
106         }
107         else if (base_addr != 0)        /* Don't probe at all. */
108                 return -ENXIO;
109
110         for (i = 0; wd_portlist[i]; i++) {
111                 int ioaddr = wd_portlist[i];
112                 r = request_region(ioaddr, WD_IO_EXTENT, "wd-probe");
113                 if (r == NULL)
114                         continue;
115                 if (wd_probe1(dev, ioaddr) == 0) {
116                         r->name = dev->name;
117                         return 0;
118                 }
119                 release_region(ioaddr, WD_IO_EXTENT);
120                 dev->irq = irq;
121                 dev->mem_start = mem_start;
122                 dev->mem_end = mem_end;
123         }
124
125         return -ENODEV;
126 }
127
128 #ifndef MODULE
129 struct net_device * __init wd_probe(int unit)
130 {
131         struct net_device *dev = alloc_ei_netdev();
132         int err;
133
134         if (!dev)
135                 return ERR_PTR(-ENOMEM);
136
137         sprintf(dev->name, "eth%d", unit);
138         netdev_boot_setup_check(dev);
139
140         err = do_wd_probe(dev);
141         if (err)
142                 goto out;
143         return dev;
144 out:
145         free_netdev(dev);
146         return ERR_PTR(err);
147 }
148 #endif
149
150 static int __init wd_probe1(struct net_device *dev, int ioaddr)
151 {
152         int i;
153         int err;
154         int checksum = 0;
155         int ancient = 0;                        /* An old card without config registers. */
156         int word16 = 0;                         /* 0 = 8 bit, 1 = 16 bit */
157         const char *model_name;
158         static unsigned version_printed;
159         DECLARE_MAC_BUF(mac);
160
161         for (i = 0; i < 8; i++)
162                 checksum += inb(ioaddr + 8 + i);
163         if (inb(ioaddr + 8) == 0xff     /* Extra check to avoid soundcard. */
164                 || inb(ioaddr + 9) == 0xff
165                 || (checksum & 0xff) != 0xFF)
166                 return -ENODEV;
167
168         /* Check for semi-valid mem_start/end values if supplied. */
169         if ((dev->mem_start % 0x2000) || (dev->mem_end % 0x2000)) {
170                 printk(KERN_WARNING "wd.c: user supplied mem_start or mem_end not on 8kB boundary - ignored.\n");
171                 dev->mem_start = 0;
172                 dev->mem_end = 0;
173         }
174
175         if (ei_debug  &&  version_printed++ == 0)
176                 printk(version);
177
178         for (i = 0; i < 6; i++)
179                 dev->dev_addr[i] = inb(ioaddr + 8 + i);
180
181         printk("%s: WD80x3 at %#3x, %s",
182                dev->name, ioaddr, print_mac(mac, dev->dev_addr));
183
184         /* The following PureData probe code was contributed by
185            Mike Jagdis <jaggy@purplet.demon.co.uk>. Puredata does software
186            configuration differently from others so we have to check for them.
187            This detects an 8 bit, 16 bit or dumb (Toshiba, jumpered) card.
188            */
189         if (inb(ioaddr+0) == 'P' && inb(ioaddr+1) == 'D') {
190                 unsigned char reg5 = inb(ioaddr+5);
191
192                 switch (inb(ioaddr+2)) {
193                 case 0x03: word16 = 0; model_name = "PDI8023-8";        break;
194                 case 0x05: word16 = 0; model_name = "PDUC8023"; break;
195                 case 0x0a: word16 = 1; model_name = "PDI8023-16"; break;
196                         /* Either 0x01 (dumb) or they've released a new version. */
197                 default:         word16 = 0; model_name = "PDI8023";    break;
198                 }
199                 dev->mem_start = ((reg5 & 0x1c) + 0xc0) << 12;
200                 dev->irq = (reg5 & 0xe0) == 0xe0 ? 10 : (reg5 >> 5) + 1;
201         } else {                                                                /* End of PureData probe */
202                 /* This method of checking for a 16-bit board is borrowed from the
203                    we.c driver.  A simpler method is just to look in ASIC reg. 0x03.
204                    I'm comparing the two method in alpha test to make certain they
205                    return the same result. */
206                 /* Check for the old 8 bit board - it has register 0/8 aliasing.
207                    Do NOT check i>=6 here -- it hangs the old 8003 boards! */
208                 for (i = 0; i < 6; i++)
209                         if (inb(ioaddr+i) != inb(ioaddr+8+i))
210                                 break;
211                 if (i >= 6) {
212                         ancient = 1;
213                         model_name = "WD8003-old";
214                         word16 = 0;
215                 } else {
216                         int tmp = inb(ioaddr+1); /* fiddle with 16bit bit */
217                         outb( tmp ^ 0x01, ioaddr+1 ); /* attempt to clear 16bit bit */
218                         if (((inb( ioaddr+1) & 0x01) == 0x01) /* A 16 bit card */
219                                 && (tmp & 0x01) == 0x01 ) {                             /* In a 16 slot. */
220                                 int asic_reg5 = inb(ioaddr+WD_CMDREG5);
221                                 /* Magic to set ASIC to word-wide mode. */
222                                 outb( NIC16 | (asic_reg5&0x1f), ioaddr+WD_CMDREG5);
223                                 outb(tmp, ioaddr+1);
224                                 model_name = "WD8013";
225                                 word16 = 1;             /* We have a 16bit board here! */
226                         } else {
227                                 model_name = "WD8003";
228                                 word16 = 0;
229                         }
230                         outb(tmp, ioaddr+1);                    /* Restore original reg1 value. */
231                 }
232 #ifndef final_version
233                 if ( !ancient && (inb(ioaddr+1) & 0x01) != (word16 & 0x01))
234                         printk("\nWD80?3: Bus width conflict, %d (probe) != %d (reg report).",
235                                    word16 ? 16 : 8, (inb(ioaddr+1) & 0x01) ? 16 : 8);
236 #endif
237         }
238
239 #if defined(WD_SHMEM) && WD_SHMEM > 0x80000
240         /* Allow a compile-time override.        */
241         dev->mem_start = WD_SHMEM;
242 #else
243         if (dev->mem_start == 0) {
244                 /* Sanity and old 8003 check */
245                 int reg0 = inb(ioaddr);
246                 if (reg0 == 0xff || reg0 == 0) {
247                         /* Future plan: this could check a few likely locations first. */
248                         dev->mem_start = 0xd0000;
249                         printk(" assigning address %#lx", dev->mem_start);
250                 } else {
251                         int high_addr_bits = inb(ioaddr+WD_CMDREG5) & 0x1f;
252                         /* Some boards don't have the register 5 -- it returns 0xff. */
253                         if (high_addr_bits == 0x1f || word16 == 0)
254                                 high_addr_bits = 0x01;
255                         dev->mem_start = ((reg0&0x3f) << 13) + (high_addr_bits << 19);
256                 }
257         }
258 #endif
259
260         /* The 8390 isn't at the base address -- the ASIC regs are there! */
261         dev->base_addr = ioaddr+WD_NIC_OFFSET;
262
263         if (dev->irq < 2) {
264                 int irqmap[] = {9,3,5,7,10,11,15,4};
265                 int reg1 = inb(ioaddr+1);
266                 int reg4 = inb(ioaddr+4);
267                 if (ancient || reg1 == 0xff) {  /* Ack!! No way to read the IRQ! */
268                         short nic_addr = ioaddr+WD_NIC_OFFSET;
269                         unsigned long irq_mask;
270
271                         /* We have an old-style ethercard that doesn't report its IRQ
272                            line.  Do autoirq to find the IRQ line. Note that this IS NOT
273                            a reliable way to trigger an interrupt. */
274                         outb_p(E8390_NODMA + E8390_STOP, nic_addr);
275                         outb(0x00, nic_addr+EN0_IMR);   /* Disable all intrs. */
276
277                         irq_mask = probe_irq_on();
278                         outb_p(0xff, nic_addr + EN0_IMR);       /* Enable all interrupts. */
279                         outb_p(0x00, nic_addr + EN0_RCNTLO);
280                         outb_p(0x00, nic_addr + EN0_RCNTHI);
281                         outb(E8390_RREAD+E8390_START, nic_addr); /* Trigger it... */
282                         mdelay(20);
283                         dev->irq = probe_irq_off(irq_mask);
284
285                         outb_p(0x00, nic_addr+EN0_IMR); /* Mask all intrs. again. */
286
287                         if (ei_debug > 2)
288                                 printk(" autoirq is %d", dev->irq);
289                         if (dev->irq < 2)
290                                 dev->irq = word16 ? 10 : 5;
291                 } else
292                         dev->irq = irqmap[((reg4 >> 5) & 0x03) + (reg1 & 0x04)];
293         } else if (dev->irq == 2)               /* Fixup bogosity: IRQ2 is really IRQ9 */
294                 dev->irq = 9;
295
296         /* Snarf the interrupt now.  There's no point in waiting since we cannot
297            share and the board will usually be enabled. */
298         i = request_irq(dev->irq, ei_interrupt, 0, DRV_NAME, dev);
299         if (i) {
300                 printk (" unable to get IRQ %d.\n", dev->irq);
301                 return i;
302         }
303
304         /* OK, were are certain this is going to work.  Setup the device. */
305         ei_status.name = model_name;
306         ei_status.word16 = word16;
307         ei_status.tx_start_page = WD_START_PG;
308         ei_status.rx_start_page = WD_START_PG + TX_PAGES;
309
310         /* Don't map in the shared memory until the board is actually opened. */
311
312         /* Some cards (eg WD8003EBT) can be jumpered for more (32k!) memory. */
313         if (dev->mem_end != 0) {
314                 ei_status.stop_page = (dev->mem_end - dev->mem_start)/256;
315                 ei_status.priv = dev->mem_end - dev->mem_start;
316         } else {
317                 ei_status.stop_page = word16 ? WD13_STOP_PG : WD03_STOP_PG;
318                 dev->mem_end = dev->mem_start + (ei_status.stop_page - WD_START_PG)*256;
319                 ei_status.priv = (ei_status.stop_page - WD_START_PG)*256;
320         }
321
322         ei_status.mem = ioremap(dev->mem_start, ei_status.priv);
323         if (!ei_status.mem) {
324                 free_irq(dev->irq, dev);
325                 return -ENOMEM;
326         }
327
328         printk(" %s, IRQ %d, shared memory at %#lx-%#lx.\n",
329                    model_name, dev->irq, dev->mem_start, dev->mem_end-1);
330
331         ei_status.reset_8390 = &wd_reset_8390;
332         ei_status.block_input = &wd_block_input;
333         ei_status.block_output = &wd_block_output;
334         ei_status.get_8390_hdr = &wd_get_8390_hdr;
335         dev->open = &wd_open;
336         dev->stop = &wd_close;
337 #ifdef CONFIG_NET_POLL_CONTROLLER
338         dev->poll_controller = ei_poll;
339 #endif
340         NS8390_init(dev, 0);
341
342 #if 1
343         /* Enable interrupt generation on softconfig cards -- M.U */
344         /* .. but possibly potentially unsafe - Donald */
345         if (inb(ioaddr+14) & 0x20)
346                 outb(inb(ioaddr+4)|0x80, ioaddr+4);
347 #endif
348
349         err = register_netdev(dev);
350         if (err)
351                 free_irq(dev->irq, dev);
352         return err;
353 }
354
355 static int
356 wd_open(struct net_device *dev)
357 {
358   int ioaddr = dev->base_addr - WD_NIC_OFFSET; /* WD_CMDREG */
359
360   /* Map in the shared memory. Always set register 0 last to remain
361          compatible with very old boards. */
362   ei_status.reg0 = ((dev->mem_start>>13) & 0x3f) | WD_MEMENB;
363   ei_status.reg5 = ((dev->mem_start>>19) & 0x1f) | NIC16;
364
365   if (ei_status.word16)
366           outb(ei_status.reg5, ioaddr+WD_CMDREG5);
367   outb(ei_status.reg0, ioaddr); /* WD_CMDREG */
368
369   ei_open(dev);
370   return 0;
371 }
372
373 static void
374 wd_reset_8390(struct net_device *dev)
375 {
376         int wd_cmd_port = dev->base_addr - WD_NIC_OFFSET; /* WD_CMDREG */
377
378         outb(WD_RESET, wd_cmd_port);
379         if (ei_debug > 1) printk("resetting the WD80x3 t=%lu...", jiffies);
380         ei_status.txing = 0;
381
382         /* Set up the ASIC registers, just in case something changed them. */
383         outb((((dev->mem_start>>13) & 0x3f)|WD_MEMENB), wd_cmd_port);
384         if (ei_status.word16)
385                 outb(NIC16 | ((dev->mem_start>>19) & 0x1f), wd_cmd_port+WD_CMDREG5);
386
387         if (ei_debug > 1) printk("reset done\n");
388         return;
389 }
390
391 /* Grab the 8390 specific header. Similar to the block_input routine, but
392    we don't need to be concerned with ring wrap as the header will be at
393    the start of a page, so we optimize accordingly. */
394
395 static void
396 wd_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page)
397 {
398
399         int wd_cmdreg = dev->base_addr - WD_NIC_OFFSET; /* WD_CMDREG */
400         void __iomem *hdr_start = ei_status.mem + ((ring_page - WD_START_PG)<<8);
401
402         /* We'll always get a 4 byte header read followed by a packet read, so
403            we enable 16 bit mode before the header, and disable after the body. */
404         if (ei_status.word16)
405                 outb(ISA16 | ei_status.reg5, wd_cmdreg+WD_CMDREG5);
406
407 #ifdef __BIG_ENDIAN
408         /* Officially this is what we are doing, but the readl() is faster */
409         /* unfortunately it isn't endian aware of the struct               */
410         memcpy_fromio(hdr, hdr_start, sizeof(struct e8390_pkt_hdr));
411         hdr->count = le16_to_cpu(hdr->count);
412 #else
413         ((unsigned int*)hdr)[0] = readl(hdr_start);
414 #endif
415 }
416
417 /* Block input and output are easy on shared memory ethercards, and trivial
418    on the Western digital card where there is no choice of how to do it.
419    The only complications are that the ring buffer wraps, and need to map
420    switch between 8- and 16-bit modes. */
421
422 static void
423 wd_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset)
424 {
425         int wd_cmdreg = dev->base_addr - WD_NIC_OFFSET; /* WD_CMDREG */
426         unsigned long offset = ring_offset - (WD_START_PG<<8);
427         void __iomem *xfer_start = ei_status.mem + offset;
428
429         if (offset + count > ei_status.priv) {
430                 /* We must wrap the input move. */
431                 int semi_count = ei_status.priv - offset;
432                 memcpy_fromio(skb->data, xfer_start, semi_count);
433                 count -= semi_count;
434                 memcpy_fromio(skb->data + semi_count, ei_status.mem + TX_PAGES * 256, count);
435         } else {
436                 /* Packet is in one chunk -- we can copy + cksum. */
437                 memcpy_fromio(skb->data, xfer_start, count);
438         }
439
440         /* Turn off 16 bit access so that reboot works.  ISA brain-damage */
441         if (ei_status.word16)
442                 outb(ei_status.reg5, wd_cmdreg+WD_CMDREG5);
443 }
444
445 static void
446 wd_block_output(struct net_device *dev, int count, const unsigned char *buf,
447                                 int start_page)
448 {
449         int wd_cmdreg = dev->base_addr - WD_NIC_OFFSET; /* WD_CMDREG */
450         void __iomem *shmem = ei_status.mem + ((start_page - WD_START_PG)<<8);
451
452
453         if (ei_status.word16) {
454                 /* Turn on and off 16 bit access so that reboot works. */
455                 outb(ISA16 | ei_status.reg5, wd_cmdreg+WD_CMDREG5);
456                 memcpy_toio(shmem, buf, count);
457                 outb(ei_status.reg5, wd_cmdreg+WD_CMDREG5);
458         } else
459                 memcpy_toio(shmem, buf, count);
460 }
461
462
463 static int
464 wd_close(struct net_device *dev)
465 {
466         int wd_cmdreg = dev->base_addr - WD_NIC_OFFSET; /* WD_CMDREG */
467
468         if (ei_debug > 1)
469                 printk("%s: Shutting down ethercard.\n", dev->name);
470         ei_close(dev);
471
472         /* Change from 16-bit to 8-bit shared memory so reboot works. */
473         if (ei_status.word16)
474                 outb(ei_status.reg5, wd_cmdreg + WD_CMDREG5 );
475
476         /* And disable the shared memory. */
477         outb(ei_status.reg0 & ~WD_MEMENB, wd_cmdreg);
478
479         return 0;
480 }
481
482
483 #ifdef MODULE
484 #define MAX_WD_CARDS    4       /* Max number of wd cards per module */
485 static struct net_device *dev_wd[MAX_WD_CARDS];
486 static int io[MAX_WD_CARDS];
487 static int irq[MAX_WD_CARDS];
488 static int mem[MAX_WD_CARDS];
489 static int mem_end[MAX_WD_CARDS];       /* for non std. mem size */
490
491 module_param_array(io, int, NULL, 0);
492 module_param_array(irq, int, NULL, 0);
493 module_param_array(mem, int, NULL, 0);
494 module_param_array(mem_end, int, NULL, 0);
495 MODULE_PARM_DESC(io, "I/O base address(es)");
496 MODULE_PARM_DESC(irq, "IRQ number(s) (ignored for PureData boards)");
497 MODULE_PARM_DESC(mem, "memory base address(es)(ignored for PureData boards)");
498 MODULE_PARM_DESC(mem_end, "memory end address(es)");
499 MODULE_DESCRIPTION("ISA Western Digital wd8003/wd8013 ; SMC Elite, Elite16 ethernet driver");
500 MODULE_LICENSE("GPL");
501
502 /* This is set up so that only a single autoprobe takes place per call.
503 ISA device autoprobes on a running machine are not recommended. */
504
505 int __init init_module(void)
506 {
507         struct net_device *dev;
508         int this_dev, found = 0;
509
510         for (this_dev = 0; this_dev < MAX_WD_CARDS; this_dev++) {
511                 if (io[this_dev] == 0)  {
512                         if (this_dev != 0) break; /* only autoprobe 1st one */
513                         printk(KERN_NOTICE "wd.c: Presently autoprobing (not recommended) for a single card.\n");
514                 }
515                 dev = alloc_ei_netdev();
516                 if (!dev)
517                         break;
518                 dev->irq = irq[this_dev];
519                 dev->base_addr = io[this_dev];
520                 dev->mem_start = mem[this_dev];
521                 dev->mem_end = mem_end[this_dev];
522                 if (do_wd_probe(dev) == 0) {
523                         dev_wd[found++] = dev;
524                         continue;
525                 }
526                 free_netdev(dev);
527                 printk(KERN_WARNING "wd.c: No wd80x3 card found (i/o = 0x%x).\n", io[this_dev]);
528                 break;
529         }
530         if (found)
531                 return 0;
532         return -ENXIO;
533 }
534
535 static void cleanup_card(struct net_device *dev)
536 {
537         free_irq(dev->irq, dev);
538         release_region(dev->base_addr - WD_NIC_OFFSET, WD_IO_EXTENT);
539         iounmap(ei_status.mem);
540 }
541
542 void __exit
543 cleanup_module(void)
544 {
545         int this_dev;
546
547         for (this_dev = 0; this_dev < MAX_WD_CARDS; this_dev++) {
548                 struct net_device *dev = dev_wd[this_dev];
549                 if (dev) {
550                         unregister_netdev(dev);
551                         cleanup_card(dev);
552                         free_netdev(dev);
553                 }
554         }
555 }
556 #endif /* MODULE */