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