1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36#define DRV_NAME "3c503"
37#define DRV_VERSION "1.10a"
38#define DRV_RELDATE "11/17/2001"
39
40
41static const char version[] =
42 DRV_NAME ".c:v" DRV_VERSION " " DRV_RELDATE " Donald Becker (becker@scyld.com)\n";
43
44#include <linux/module.h>
45#include <linux/kernel.h>
46#include <linux/errno.h>
47#include <linux/string.h>
48#include <linux/delay.h>
49#include <linux/netdevice.h>
50#include <linux/etherdevice.h>
51#include <linux/init.h>
52#include <linux/ethtool.h>
53
54#include <asm/uaccess.h>
55#include <asm/io.h>
56#include <asm/system.h>
57#include <asm/byteorder.h>
58
59#include "8390.h"
60#include "3c503.h"
61#define WRD_COUNT 4
62
63int el2_probe(struct net_device *dev);
64static int el2_pio_probe(struct net_device *dev);
65static int el2_probe1(struct net_device *dev, int ioaddr);
66
67
68static unsigned int netcard_portlist[] __initdata =
69 { 0x300,0x310,0x330,0x350,0x250,0x280,0x2a0,0x2e0,0};
70
71#define EL2_IO_EXTENT 16
72
73static int el2_open(struct net_device *dev);
74static int el2_close(struct net_device *dev);
75static void el2_reset_8390(struct net_device *dev);
76static void el2_init_card(struct net_device *dev);
77static void el2_block_output(struct net_device *dev, int count,
78 const unsigned char *buf, int start_page);
79static void el2_block_input(struct net_device *dev, int count, struct sk_buff *skb,
80 int ring_offset);
81static void el2_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr,
82 int ring_page);
83static struct ethtool_ops netdev_ethtool_ops;
84
85
86
87
88
89
90
91
92
93int __init
94el2_probe(struct net_device *dev)
95{
96 int *addr, addrs[] = { 0xddffe, 0xd9ffe, 0xcdffe, 0xc9ffe, 0};
97 int base_addr = dev->base_addr;
98
99 SET_MODULE_OWNER(dev);
100
101 if (base_addr > 0x1ff)
102 return el2_probe1(dev, base_addr);
103 else if (base_addr != 0)
104 return -ENXIO;
105
106 for (addr = addrs; *addr; addr++) {
107 int i;
108 unsigned int base_bits = isa_readb(*addr);
109
110 for(i = 7; i >= 0; i--, base_bits >>= 1)
111 if (base_bits & 0x1)
112 break;
113 if (base_bits != 1)
114 continue;
115 if (el2_probe1(dev, netcard_portlist[i]) == 0)
116 return 0;
117 }
118#if ! defined(no_probe_nonshared_memory)
119 return el2_pio_probe(dev);
120#else
121 return -ENODEV;
122#endif
123}
124
125
126
127static int __init
128el2_pio_probe(struct net_device *dev)
129{
130 int i;
131 int base_addr = dev ? dev->base_addr : 0;
132
133 if (base_addr > 0x1ff)
134 return el2_probe1(dev, base_addr);
135 else if (base_addr != 0)
136 return -ENXIO;
137
138 for (i = 0; netcard_portlist[i]; i++)
139 if (el2_probe1(dev, netcard_portlist[i]) == 0)
140 return 0;
141
142 return -ENODEV;
143}
144
145
146
147
148static int __init
149el2_probe1(struct net_device *dev, int ioaddr)
150{
151 int i, iobase_reg, membase_reg, saved_406, wordlength, retval;
152 static unsigned version_printed;
153 unsigned long vendor_id;
154
155
156 if (!request_region(ioaddr, EL2_IO_EXTENT, dev->name))
157 return -EBUSY;
158
159
160 if (inb(ioaddr + 0x408) == 0xff) {
161 mdelay(1);
162 retval = -ENODEV;
163 goto out;
164 }
165
166
167
168 iobase_reg = inb(ioaddr+0x403);
169 membase_reg = inb(ioaddr+0x404);
170
171 if ( (iobase_reg & (iobase_reg - 1))
172 || (membase_reg & (membase_reg - 1))) {
173 retval = -ENODEV;
174 goto out;
175 }
176 saved_406 = inb_p(ioaddr + 0x406);
177 outb_p(ECNTRL_RESET|ECNTRL_THIN, ioaddr + 0x406);
178 outb_p(ECNTRL_THIN, ioaddr + 0x406);
179
180
181 outb(ECNTRL_SAPROM|ECNTRL_THIN, ioaddr + 0x406);
182 vendor_id = inb(ioaddr)*0x10000 + inb(ioaddr + 1)*0x100 + inb(ioaddr + 2);
183 if ((vendor_id != OLD_3COM_ID) && (vendor_id != NEW_3COM_ID)) {
184
185 outb(saved_406, ioaddr + 0x406);
186 retval = -ENODEV;
187 goto out;
188 }
189
190 if (ei_debug && version_printed++ == 0)
191 printk(version);
192
193 dev->base_addr = ioaddr;
194
195 if (ethdev_init(dev)) {
196 printk ("3c503: unable to allocate memory for dev->priv.\n");
197 retval = -ENOMEM;
198 goto out;
199 }
200
201 printk("%s: 3c503 at i/o base %#3x, node ", dev->name, ioaddr);
202
203
204 for (i = 0; i < 6; i++)
205 printk(" %2.2x", dev->dev_addr[i] = inb(ioaddr + i));
206
207
208 outb(ECNTRL_THIN, ioaddr + 0x406);
209
210
211 outb_p(E8390_PAGE0, ioaddr + E8390_CMD);
212 outb_p(0, ioaddr + EN0_DCFG);
213 outb_p(E8390_PAGE2, ioaddr + E8390_CMD);
214 wordlength = inb_p(ioaddr + EN0_DCFG) & ENDCFG_WTS;
215 outb_p(E8390_PAGE0, ioaddr + E8390_CMD);
216
217
218 if (ei_debug > 2) printk(" memory jumpers %2.2x ", membase_reg);
219 outb(EGACFR_NORM, ioaddr + 0x405);
220
221
222
223
224
225#if defined(EI8390_THICK) || defined(EL2_AUI)
226 ei_status.interface_num = 1;
227#else
228 ei_status.interface_num = dev->mem_end & 0xf;
229#endif
230 printk(", using %sternal xcvr.\n", ei_status.interface_num == 0 ? "in" : "ex");
231
232 if ((membase_reg & 0xf0) == 0) {
233 dev->mem_start = 0;
234 ei_status.name = "3c503-PIO";
235 } else {
236 dev->mem_start = ((membase_reg & 0xc0) ? 0xD8000 : 0xC8000) +
237 ((membase_reg & 0xA0) ? 0x4000 : 0);
238
239#define EL2_MEMSIZE (EL2_MB1_STOP_PG - EL2_MB1_START_PG)*256
240#ifdef EL2MEMTEST
241
242
243
244 {
245 unsigned long mem_base = dev->mem_start;
246 unsigned int test_val = 0xbbadf00d;
247 isa_writel(0xba5eba5e, mem_base);
248 for (i = sizeof(test_val); i < EL2_MEMSIZE; i+=sizeof(test_val)) {
249 isa_writel(test_val, mem_base + i);
250 if (isa_readl(mem_base) != 0xba5eba5e
251 || isa_readl(mem_base + i) != test_val) {
252 printk("3c503: memory failure or memory address conflict.\n");
253 dev->mem_start = 0;
254 ei_status.name = "3c503-PIO";
255 break;
256 }
257 test_val += 0x55555555;
258 isa_writel(0, mem_base + i);
259 }
260 }
261#endif
262
263 if (dev->mem_start)
264 dev->mem_end = ei_status.rmem_end = dev->mem_start + EL2_MEMSIZE;
265
266 if (wordlength) {
267 ei_status.rmem_start = dev->mem_start;
268 ei_status.name = "3c503/16";
269 } else {
270 ei_status.rmem_start = TX_PAGES*256 + dev->mem_start;
271 ei_status.name = "3c503";
272 }
273 }
274
275
276
277
278
279
280
281
282
283 if (wordlength) {
284 ei_status.tx_start_page = EL2_MB0_START_PG;
285 ei_status.rx_start_page = EL2_MB1_START_PG;
286 } else {
287 ei_status.tx_start_page = EL2_MB1_START_PG;
288 ei_status.rx_start_page = EL2_MB1_START_PG + TX_PAGES;
289 }
290
291
292 ei_status.stop_page = EL2_MB1_STOP_PG;
293 ei_status.word16 = wordlength;
294 ei_status.reset_8390 = &el2_reset_8390;
295 ei_status.get_8390_hdr = &el2_get_8390_hdr;
296 ei_status.block_input = &el2_block_input;
297 ei_status.block_output = &el2_block_output;
298
299 if (dev->irq == 2)
300 dev->irq = 9;
301 else if (dev->irq > 5 && dev->irq != 9) {
302 printk("3c503: configured interrupt %d invalid, will use autoIRQ.\n",
303 dev->irq);
304 dev->irq = 0;
305 }
306
307 ei_status.saved_irq = dev->irq;
308
309 dev->open = &el2_open;
310 dev->stop = &el2_close;
311 dev->ethtool_ops = &netdev_ethtool_ops;
312
313 if (dev->mem_start)
314 printk("%s: %s - %dkB RAM, 8kB shared mem window at %#6lx-%#6lx.\n",
315 dev->name, ei_status.name, (wordlength+1)<<3,
316 dev->mem_start, dev->mem_end-1);
317
318 else
319 {
320 ei_status.tx_start_page = EL2_MB1_START_PG;
321 ei_status.rx_start_page = EL2_MB1_START_PG + TX_PAGES;
322 printk("\n%s: %s, %dkB RAM, using programmed I/O (REJUMPER for SHARED MEMORY).\n",
323 dev->name, ei_status.name, (wordlength+1)<<3);
324 }
325 return 0;
326out:
327 release_region(ioaddr, EL2_IO_EXTENT);
328 return retval;
329}
330
331static int
332el2_open(struct net_device *dev)
333{
334 int retval = -EAGAIN;
335
336 if (dev->irq < 2) {
337 int irqlist[] = {5, 9, 3, 4, 0};
338 int *irqp = irqlist;
339
340 outb(EGACFR_NORM, E33G_GACFR);
341 do {
342 if (request_irq (*irqp, NULL, 0, "bogus", dev) != -EBUSY) {
343
344 unsigned long cookie = probe_irq_on();
345 outb_p(0x04 << ((*irqp == 9) ? 2 : *irqp), E33G_IDCFR);
346 outb_p(0x00, E33G_IDCFR);
347 if (*irqp == probe_irq_off(cookie)
348 && ((retval = request_irq(dev->irq = *irqp,
349 ei_interrupt, 0, dev->name, dev)) == 0))
350 break;
351 }
352 } while (*++irqp);
353 if (*irqp == 0) {
354 outb(EGACFR_IRQOFF, E33G_GACFR);
355 return retval;
356 }
357 } else {
358 if ((retval = request_irq(dev->irq, ei_interrupt, 0, dev->name, dev))) {
359 return retval;
360 }
361 }
362
363 el2_init_card(dev);
364 ei_open(dev);
365 return 0;
366}
367
368static int
369el2_close(struct net_device *dev)
370{
371 free_irq(dev->irq, dev);
372 dev->irq = ei_status.saved_irq;
373 outb(EGACFR_IRQOFF, E33G_GACFR);
374
375 ei_close(dev);
376 return 0;
377}
378
379
380
381
382
383static void
384el2_reset_8390(struct net_device *dev)
385{
386 if (ei_debug > 1) {
387 printk("%s: Resetting the 3c503 board...", dev->name);
388 printk("%#lx=%#02x %#lx=%#02x %#lx=%#02x...", E33G_IDCFR, inb(E33G_IDCFR),
389 E33G_CNTRL, inb(E33G_CNTRL), E33G_GACFR, inb(E33G_GACFR));
390 }
391 outb_p(ECNTRL_RESET|ECNTRL_THIN, E33G_CNTRL);
392 ei_status.txing = 0;
393 outb_p(ei_status.interface_num==0 ? ECNTRL_THIN : ECNTRL_AUI, E33G_CNTRL);
394 el2_init_card(dev);
395 if (ei_debug > 1) printk("done\n");
396}
397
398
399static void
400el2_init_card(struct net_device *dev)
401{
402
403 outb_p(ei_status.interface_num==0 ? ECNTRL_THIN : ECNTRL_AUI, E33G_CNTRL);
404
405
406
407 outb(ei_status.rx_start_page, E33G_STARTPG);
408 outb(ei_status.stop_page, E33G_STOPPG);
409
410
411 outb(0xff, E33G_VP2);
412 outb(0xff, E33G_VP1);
413 outb(0x00, E33G_VP0);
414
415 outb_p(0x00, dev->base_addr + EN0_IMR);
416
417 outb(EGACFR_NORM, E33G_GACFR);
418
419
420 outb_p((0x04 << (dev->irq == 9 ? 2 : dev->irq)), E33G_IDCFR);
421 outb_p((WRD_COUNT << 1), E33G_DRQCNT);
422 outb_p(0x20, E33G_DMAAH);
423 outb_p(0x00, E33G_DMAAL);
424 return;
425}
426
427
428
429
430
431static void
432el2_block_output(struct net_device *dev, int count,
433 const unsigned char *buf, int start_page)
434{
435 unsigned short int *wrd;
436 int boguscount;
437 unsigned short word;
438
439 if (ei_status.word16)
440 outb(EGACFR_RSEL|EGACFR_TCM, E33G_GACFR);
441 else
442 outb(EGACFR_NORM, E33G_GACFR);
443
444 if (dev->mem_start) {
445 unsigned long dest_addr = dev->mem_start +
446 ((start_page - ei_status.tx_start_page) << 8);
447 isa_memcpy_toio(dest_addr, buf, count);
448 outb(EGACFR_NORM, E33G_GACFR);
449 return;
450 }
451
452
453
454
455
456
457 word = (unsigned short)start_page;
458 outb(word&0xFF, E33G_DMAAH);
459 outb(word>>8, E33G_DMAAL);
460
461 outb_p((ei_status.interface_num ? ECNTRL_AUI : ECNTRL_THIN ) | ECNTRL_OUTPUT
462 | ECNTRL_START, E33G_CNTRL);
463
464
465
466
467
468
469
470
471
472 wrd = (unsigned short int *) buf;
473 count = (count + 1) >> 1;
474 for(;;)
475 {
476 boguscount = 0x1000;
477 while ((inb(E33G_STATUS) & ESTAT_DPRDY) == 0)
478 {
479 if(!boguscount--)
480 {
481 printk("%s: FIFO blocked in el2_block_output.\n", dev->name);
482 el2_reset_8390(dev);
483 goto blocked;
484 }
485 }
486 if(count > WRD_COUNT)
487 {
488 outsw(E33G_FIFOH, wrd, WRD_COUNT);
489 wrd += WRD_COUNT;
490 count -= WRD_COUNT;
491 }
492 else
493 {
494 outsw(E33G_FIFOH, wrd, count);
495 break;
496 }
497 }
498 blocked:;
499 outb_p(ei_status.interface_num==0 ? ECNTRL_THIN : ECNTRL_AUI, E33G_CNTRL);
500 return;
501}
502
503
504static void
505el2_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page)
506{
507 int boguscount;
508 unsigned long hdr_start = dev->mem_start + ((ring_page - EL2_MB1_START_PG)<<8);
509 unsigned short word;
510
511 if (dev->mem_start) {
512 isa_memcpy_fromio(hdr, hdr_start, sizeof(struct e8390_pkt_hdr));
513 hdr->count = le16_to_cpu(hdr->count);
514 return;
515 }
516
517
518
519
520
521 word = (unsigned short)ring_page;
522 outb(word&0xFF, E33G_DMAAH);
523 outb(word>>8, E33G_DMAAL);
524
525 outb_p((ei_status.interface_num == 0 ? ECNTRL_THIN : ECNTRL_AUI) | ECNTRL_INPUT
526 | ECNTRL_START, E33G_CNTRL);
527 boguscount = 0x1000;
528 while ((inb(E33G_STATUS) & ESTAT_DPRDY) == 0)
529 {
530 if(!boguscount--)
531 {
532 printk("%s: FIFO blocked in el2_get_8390_hdr.\n", dev->name);
533 memset(hdr, 0x00, sizeof(struct e8390_pkt_hdr));
534 el2_reset_8390(dev);
535 goto blocked;
536 }
537 }
538 insw(E33G_FIFOH, hdr, (sizeof(struct e8390_pkt_hdr))>> 1);
539 blocked:;
540 outb_p(ei_status.interface_num == 0 ? ECNTRL_THIN : ECNTRL_AUI, E33G_CNTRL);
541}
542
543
544static void
545el2_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset)
546{
547 int boguscount = 0;
548 unsigned short int *buf;
549 unsigned short word;
550
551 int end_of_ring = ei_status.rmem_end;
552
553
554 if (dev->mem_start) {
555 ring_offset -= (EL2_MB1_START_PG<<8);
556 if (dev->mem_start + ring_offset + count > end_of_ring) {
557
558 int semi_count = end_of_ring - (dev->mem_start + ring_offset);
559 isa_memcpy_fromio(skb->data, dev->mem_start + ring_offset, semi_count);
560 count -= semi_count;
561 isa_memcpy_fromio(skb->data + semi_count, ei_status.rmem_start, count);
562 } else {
563
564 isa_eth_io_copy_and_sum(skb, dev->mem_start + ring_offset, count, 0);
565 }
566 return;
567 }
568
569
570
571
572 word = (unsigned short) ring_offset;
573 outb(word>>8, E33G_DMAAH);
574 outb(word&0xFF, E33G_DMAAL);
575
576 outb_p((ei_status.interface_num == 0 ? ECNTRL_THIN : ECNTRL_AUI) | ECNTRL_INPUT
577 | ECNTRL_START, E33G_CNTRL);
578
579
580
581
582
583
584
585
586
587
588
589 buf = (unsigned short int *) skb->data;
590 count = (count + 1) >> 1;
591 for(;;)
592 {
593 boguscount = 0x1000;
594 while ((inb(E33G_STATUS) & ESTAT_DPRDY) == 0)
595 {
596 if(!boguscount--)
597 {
598 printk("%s: FIFO blocked in el2_block_input.\n", dev->name);
599 el2_reset_8390(dev);
600 goto blocked;
601 }
602 }
603 if(count > WRD_COUNT)
604 {
605 insw(E33G_FIFOH, buf, WRD_COUNT);
606 buf += WRD_COUNT;
607 count -= WRD_COUNT;
608 }
609 else
610 {
611 insw(E33G_FIFOH, buf, count);
612 break;
613 }
614 }
615 blocked:;
616 outb_p(ei_status.interface_num == 0 ? ECNTRL_THIN : ECNTRL_AUI, E33G_CNTRL);
617 return;
618}
619
620
621static void netdev_get_drvinfo(struct net_device *dev,
622 struct ethtool_drvinfo *info)
623{
624 strcpy(info->driver, DRV_NAME);
625 strcpy(info->version, DRV_VERSION);
626 sprintf(info->bus_info, "ISA 0x%lx", dev->base_addr);
627}
628
629static struct ethtool_ops netdev_ethtool_ops = {
630 .get_drvinfo = netdev_get_drvinfo,
631};
632
633#ifdef MODULE
634#define MAX_EL2_CARDS 4
635
636static struct net_device dev_el2[MAX_EL2_CARDS];
637static int io[MAX_EL2_CARDS];
638static int irq[MAX_EL2_CARDS];
639static int xcvr[MAX_EL2_CARDS];
640MODULE_PARM(io, "1-" __MODULE_STRING(MAX_EL2_CARDS) "i");
641MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_EL2_CARDS) "i");
642MODULE_PARM(xcvr, "1-" __MODULE_STRING(MAX_EL2_CARDS) "i");
643MODULE_PARM_DESC(io, "I/O base address(es)");
644MODULE_PARM_DESC(irq, "IRQ number(s) (assigned)");
645MODULE_PARM_DESC(xcvr, "transceiver(s) (0=internal, 1=external)");
646MODULE_DESCRIPTION("3Com ISA EtherLink II, II/16 (3c503, 3c503/16) driver");
647MODULE_LICENSE("GPL");
648
649
650
651int
652init_module(void)
653{
654 int this_dev, found = 0;
655
656 for (this_dev = 0; this_dev < MAX_EL2_CARDS; this_dev++) {
657 struct net_device *dev = &dev_el2[this_dev];
658 dev->irq = irq[this_dev];
659 dev->base_addr = io[this_dev];
660 dev->mem_end = xcvr[this_dev];
661 dev->init = el2_probe;
662 if (io[this_dev] == 0) {
663 if (this_dev != 0) break;
664 printk(KERN_NOTICE "3c503.c: Presently autoprobing (not recommended) for a single card.\n");
665 }
666 if (register_netdev(dev) != 0) {
667 printk(KERN_WARNING "3c503.c: No 3c503 card found (i/o = 0x%x).\n", io[this_dev]);
668 if (found != 0) {
669 return 0;
670 }
671 return -ENXIO;
672 }
673 found++;
674 }
675 return 0;
676}
677
678void
679cleanup_module(void)
680{
681 int this_dev;
682
683 for (this_dev = 0; this_dev < MAX_EL2_CARDS; this_dev++) {
684 struct net_device *dev = &dev_el2[this_dev];
685 if (dev->priv != NULL) {
686 void *priv = dev->priv;
687
688 release_region(dev->base_addr, EL2_IO_EXTENT);
689 unregister_netdev(dev);
690 kfree(priv);
691 }
692 }
693}
694#endif
695