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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88#include <linux/module.h>
89#include <linux/kernel.h>
90#include <linux/sched.h>
91#include <linux/string.h>
92#include <linux/errno.h>
93#include <linux/ioport.h>
94#include <linux/slab.h>
95#include <linux/interrupt.h>
96#include <linux/delay.h>
97#include <linux/mca.h>
98#include <asm/processor.h>
99#include <asm/bitops.h>
100#include <asm/io.h>
101
102#include <linux/netdevice.h>
103#include <linux/etherdevice.h>
104#include <linux/skbuff.h>
105#include <linux/init.h>
106
107#include "3c523.h"
108
109
110#define DEBUG
111#define SYSBUSVAL 0
112#undef ELMC_MULTICAST
113
114#define make32(ptr16) (p->memtop + (short) (ptr16) )
115#define make24(ptr32) ((char *) (ptr32) - p->base)
116#define make16(ptr32) ((unsigned short) ((unsigned long) (ptr32) - (unsigned long) p->memtop ))
117
118
119
120
121
122static int irq_table[] __initdata = {
123 12, 7, 3, 9
124};
125
126static int csr_table[] __initdata = {
127 0x300, 0x1300, 0x2300, 0x3300
128};
129
130static int shm_table[] __initdata = {
131 0x0c0000, 0x0c8000, 0x0d0000, 0x0d8000
132};
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149#define RECV_BUFF_SIZE 1524
150#define XMIT_BUFF_SIZE 1524
151#define NUM_XMIT_BUFFS 1
152#define NUM_RECV_BUFFS_8 4
153#define NUM_RECV_BUFFS_16 9
154
155#if (NUM_XMIT_BUFFS == 1)
156#define NO_NOPCOMMANDS
157#endif
158
159
160
161#define DELAY(x) { mdelay(32 * x); }
162
163
164#define DELAY_16(); { udelay(16) ; }
165
166
167#define WAIT_4_SCB_CMD() { int i; \
168 for(i=0;i<1024;i++) { \
169 if(!p->scb->cmd) break; \
170 DELAY_16(); \
171 if(i == 1023) { \
172 printk(KERN_WARNING "%s:%d: scb_cmd timed out .. resetting i82586\n",\
173 dev->name,__LINE__); \
174 elmc_id_reset586(); } } }
175
176static void elmc_interrupt(int irq, void *dev_id, struct pt_regs *reg_ptr);
177static int elmc_open(struct net_device *dev);
178static int elmc_close(struct net_device *dev);
179static int elmc_send_packet(struct sk_buff *, struct net_device *);
180static struct net_device_stats *elmc_get_stats(struct net_device *dev);
181static void elmc_timeout(struct net_device *dev);
182#ifdef ELMC_MULTICAST
183static void set_multicast_list(struct net_device *dev);
184#endif
185
186
187static int init586(struct net_device *dev);
188static int check586(struct net_device *dev, unsigned long where, unsigned size);
189static void alloc586(struct net_device *dev);
190static void startrecv586(struct net_device *dev);
191static void *alloc_rfa(struct net_device *dev, void *ptr);
192static void elmc_rcv_int(struct net_device *dev);
193static void elmc_xmt_int(struct net_device *dev);
194static void elmc_rnr_int(struct net_device *dev);
195
196struct priv {
197 struct net_device_stats stats;
198 unsigned long base;
199 char *memtop;
200 unsigned long mapped_start;
201 volatile struct rfd_struct *rfd_last, *rfd_top, *rfd_first;
202 volatile struct scp_struct *scp;
203 volatile struct iscp_struct *iscp;
204 volatile struct scb_struct *scb;
205 volatile struct tbd_struct *xmit_buffs[NUM_XMIT_BUFFS];
206 volatile struct transmit_cmd_struct *xmit_cmds[NUM_XMIT_BUFFS];
207#if (NUM_XMIT_BUFFS == 1)
208 volatile struct nop_cmd_struct *nop_cmds[2];
209#else
210 volatile struct nop_cmd_struct *nop_cmds[NUM_XMIT_BUFFS];
211#endif
212 volatile int nop_point, num_recv_buffs;
213 volatile char *xmit_cbuffs[NUM_XMIT_BUFFS];
214 volatile int xmit_count, xmit_last;
215 volatile int slot;
216};
217
218#define elmc_attn586() {elmc_do_attn586(dev->base_addr,ELMC_CTRL_INTE);}
219#define elmc_reset586() {elmc_do_reset586(dev->base_addr,ELMC_CTRL_INTE);}
220
221
222
223
224#define elmc_id_attn586() {elmc_do_attn586(dev->base_addr,0);}
225#define elmc_id_reset586() {elmc_do_reset586(dev->base_addr,0);}
226
227
228
229
230
231static void elmc_do_attn586(int ioaddr, int ints)
232{
233
234
235
236
237
238
239
240
241
242 outb(ELMC_CTRL_RST | 0x3 | ELMC_CTRL_CA | ints, ioaddr + ELMC_CTRL);
243 DELAY_16();
244 outb(ELMC_CTRL_RST | 0x3 | ints, ioaddr + ELMC_CTRL);
245}
246
247
248
249
250
251static void elmc_do_reset586(int ioaddr, int ints)
252{
253
254 outb(0x3 | ELMC_CTRL_LBK, ioaddr + ELMC_CTRL);
255 DELAY_16();
256 outb(ELMC_CTRL_RST | ELMC_CTRL_LBK | 0x3, ioaddr + ELMC_CTRL);
257
258 elmc_do_attn586(ioaddr, ints);
259}
260
261
262
263
264
265static int elmc_close(struct net_device *dev)
266{
267 netif_stop_queue(dev);
268 elmc_id_reset586();
269 free_irq(dev->irq, dev);
270 return 0;
271}
272
273
274
275
276
277static int elmc_open(struct net_device *dev)
278{
279 int ret;
280
281 elmc_id_attn586();
282
283 ret = request_irq(dev->irq, &elmc_interrupt, SA_SHIRQ | SA_SAMPLE_RANDOM,
284 dev->name, dev);
285 if (ret) {
286 printk(KERN_ERR "%s: couldn't get irq %d\n", dev->name, dev->irq);
287 elmc_id_reset586();
288 return ret;
289 }
290 alloc586(dev);
291 init586(dev);
292 startrecv586(dev);
293 netif_start_queue(dev);
294 return 0;
295}
296
297
298
299
300
301static int __init check586(struct net_device *dev, unsigned long where, unsigned size)
302{
303 struct priv *p = (struct priv *) dev->priv;
304 char *iscp_addrs[2];
305 int i = 0;
306
307 p->base = (unsigned long) bus_to_virt((unsigned long)where) + size - 0x01000000;
308 p->memtop = bus_to_virt((unsigned long)where) + size;
309 p->scp = (struct scp_struct *)(p->base + SCP_DEFAULT_ADDRESS);
310 memset((char *) p->scp, 0, sizeof(struct scp_struct));
311 p->scp->sysbus = SYSBUSVAL;
312
313 iscp_addrs[0] = bus_to_virt((unsigned long)where);
314 iscp_addrs[1] = (char *) p->scp - sizeof(struct iscp_struct);
315
316 for (i = 0; i < 2; i++) {
317 p->iscp = (struct iscp_struct *) iscp_addrs[i];
318 memset((char *) p->iscp, 0, sizeof(struct iscp_struct));
319
320 p->scp->iscp = make24(p->iscp);
321 p->iscp->busy = 1;
322
323 elmc_id_reset586();
324
325
326
327
328 elmc_id_attn586();
329 DELAY(1);
330
331 if (p->iscp->busy) {
332 return 0;
333 }
334 }
335 return 1;
336}
337
338
339
340
341
342void alloc586(struct net_device *dev)
343{
344 struct priv *p = (struct priv *) dev->priv;
345
346 elmc_id_reset586();
347 DELAY(2);
348
349 p->scp = (struct scp_struct *) (p->base + SCP_DEFAULT_ADDRESS);
350 p->scb = (struct scb_struct *) bus_to_virt(dev->mem_start);
351 p->iscp = (struct iscp_struct *) ((char *) p->scp - sizeof(struct iscp_struct));
352
353 memset((char *) p->iscp, 0, sizeof(struct iscp_struct));
354 memset((char *) p->scp, 0, sizeof(struct scp_struct));
355
356 p->scp->iscp = make24(p->iscp);
357 p->scp->sysbus = SYSBUSVAL;
358 p->iscp->scb_offset = make16(p->scb);
359
360 p->iscp->busy = 1;
361 elmc_id_reset586();
362 elmc_id_attn586();
363
364 DELAY(2);
365
366 if (p->iscp->busy) {
367 printk(KERN_ERR "%s: Init-Problems (alloc).\n", dev->name);
368 }
369 memset((char *) p->scb, 0, sizeof(struct scb_struct));
370}
371
372
373
374static int elmc_getinfo(char *buf, int slot, void *d)
375{
376 int len = 0;
377 struct net_device *dev = (struct net_device *) d;
378 int i;
379
380 if (dev == NULL)
381 return len;
382
383 len += sprintf(buf + len, "Revision: 0x%x\n",
384 inb(dev->base_addr + ELMC_REVISION) & 0xf);
385 len += sprintf(buf + len, "IRQ: %d\n", dev->irq);
386 len += sprintf(buf + len, "IO Address: %#lx-%#lx\n", dev->base_addr,
387 dev->base_addr + ELMC_IO_EXTENT);
388 len += sprintf(buf + len, "Memory: %#lx-%#lx\n", dev->mem_start,
389 dev->mem_end - 1);
390 len += sprintf(buf + len, "Transceiver: %s\n", dev->if_port ?
391 "External" : "Internal");
392 len += sprintf(buf + len, "Device: %s\n", dev->name);
393 len += sprintf(buf + len, "Hardware Address:");
394 for (i = 0; i < 6; i++) {
395 len += sprintf(buf + len, " %02x", dev->dev_addr[i]);
396 }
397 buf[len++] = '\n';
398 buf[len] = 0;
399
400 return len;
401}
402
403
404
405int __init elmc_probe(struct net_device *dev)
406{
407 static int slot;
408 int base_addr = dev->base_addr;
409 int irq = dev->irq;
410 u_char status = 0;
411 u_char revision = 0;
412 int i = 0;
413 unsigned int size = 0;
414 int retval;
415 struct priv *pr;
416
417 SET_MODULE_OWNER(dev);
418 if (MCA_bus == 0) {
419 return -ENODEV;
420 }
421
422 slot = mca_find_adapter(ELMC_MCA_ID, 0);
423 while (slot != -1) {
424 status = mca_read_stored_pos(slot, 2);
425
426 dev->irq=irq_table[(status & ELMC_STATUS_IRQ_SELECT) >> 6];
427 dev->base_addr=csr_table[(status & ELMC_STATUS_CSR_SELECT) >> 1];
428
429
430
431
432
433
434
435 if ((irq && irq != dev->irq) ||
436 (base_addr && base_addr != dev->base_addr)) {
437 slot = mca_find_adapter(ELMC_MCA_ID, slot + 1);
438 continue;
439 }
440 if (!request_region(dev->base_addr, ELMC_IO_EXTENT, dev->name)) {
441 slot = mca_find_adapter(ELMC_MCA_ID, slot + 1);
442 continue;
443 }
444
445
446 break;
447 }
448
449
450 if (slot == MCA_NOTFOUND) {
451 retval = ((base_addr || irq) ? -ENXIO : -ENODEV);
452 goto err_out;
453 }
454 mca_set_adapter_name(slot, "3Com 3c523 Etherlink/MC");
455 mca_set_adapter_procfn(slot, (MCA_ProcFn) elmc_getinfo, dev);
456
457
458 printk(KERN_INFO "%s: 3c523 adapter found in slot %d\n", dev->name, slot + 1);
459
460
461
462
463
464
465
466
467
468
469
470
471
472 revision = inb(dev->base_addr + ELMC_REVISION) & 0xf;
473
474
475
476
477 switch (dev->irq) {
478 case 3:
479 mca_write_pos(slot, 3, 0x04);
480 break;
481 case 7:
482 mca_write_pos(slot, 3, 0x02);
483 break;
484 case 9:
485 mca_write_pos(slot, 3, 0x08);
486 break;
487 case 12:
488 mca_write_pos(slot, 3, 0x01);
489 break;
490 }
491
492 pr = dev->priv = kmalloc(sizeof(struct priv), GFP_KERNEL);
493 if (dev->priv == NULL) {
494 retval = -ENOMEM;
495 goto err_out;
496 }
497 memset(pr, 0, sizeof(struct priv));
498
499 pr->slot = slot;
500
501 printk(KERN_INFO "%s: 3Com 3c523 Rev 0x%x at %#lx\n", dev->name, (int) revision,
502 dev->base_addr);
503
504
505
506
507 dev->if_port = (status & ELMC_STATUS_DISABLE_THIN);
508
509
510
511
512
513
514 dev->mem_start = shm_table[(status & ELMC_STATUS_MEMORY_SELECT) >> 3];
515
516
517
518
519 elmc_id_reset586();
520
521 size = 0x4000;
522 if (!check586(dev, dev->mem_start, size)) {
523 printk(KERN_ERR "%s: memprobe, Can't find memory at 0x%lx!\n", dev->name,
524 dev->mem_start);
525 kfree(dev->priv);
526 dev->priv = NULL;
527 retval = -ENODEV;
528 goto err_out;
529 }
530 dev->mem_end = dev->mem_start + size;
531
532 pr->memtop = bus_to_virt(dev->mem_start) + size;
533 pr->base = (unsigned long) bus_to_virt(dev->mem_start) + size - 0x01000000;
534 alloc586(dev);
535
536 elmc_id_reset586();
537
538
539 pr->num_recv_buffs = NUM_RECV_BUFFS_16;
540
541
542 printk(KERN_INFO "%s: IRQ %d, %sternal xcvr, memory %#lx-%#lx.\n", dev->name,
543 dev->irq, dev->if_port ? "ex" : "in",
544 dev->mem_start, dev->mem_end - 1);
545
546
547
548 printk(KERN_INFO "%s: hardware address ", dev->name);
549 for (i = 0; i < 6; i++) {
550 dev->dev_addr[i] = inb(dev->base_addr + i);
551 printk(" %02x", dev->dev_addr[i]);
552 }
553 printk("\n");
554
555 dev->open = &elmc_open;
556 dev->stop = &elmc_close;
557 dev->get_stats = &elmc_get_stats;
558 dev->hard_start_xmit = &elmc_send_packet;
559 dev->tx_timeout = &elmc_timeout;
560 dev->watchdog_timeo = HZ;
561#ifdef ELMC_MULTICAST
562 dev->set_multicast_list = &set_multicast_list;
563#else
564 dev->set_multicast_list = NULL;
565#endif
566
567 ether_setup(dev);
568
569
570
571
572
573#ifndef ELMC_MULTICAST
574 dev->flags&=~IFF_MULTICAST;
575#endif
576
577 return 0;
578err_out:
579 release_region(dev->base_addr, ELMC_IO_EXTENT);
580 return retval;
581}
582
583
584
585
586
587
588static int init586(struct net_device *dev)
589{
590 void *ptr;
591 unsigned long s;
592 int i, result = 0;
593 struct priv *p = (struct priv *) dev->priv;
594 volatile struct configure_cmd_struct *cfg_cmd;
595 volatile struct iasetup_cmd_struct *ias_cmd;
596 volatile struct tdr_cmd_struct *tdr_cmd;
597 volatile struct mcsetup_cmd_struct *mc_cmd;
598 struct dev_mc_list *dmi = dev->mc_list;
599 int num_addrs = dev->mc_count;
600
601 ptr = (void *) ((char *) p->scb + sizeof(struct scb_struct));
602
603 cfg_cmd = (struct configure_cmd_struct *) ptr;
604 cfg_cmd->cmd_status = 0;
605 cfg_cmd->cmd_cmd = CMD_CONFIGURE | CMD_LAST;
606 cfg_cmd->cmd_link = 0xffff;
607
608 cfg_cmd->byte_cnt = 0x0a;
609 cfg_cmd->fifo = 0x08;
610 cfg_cmd->sav_bf = 0x40;
611 cfg_cmd->adr_len = 0x2e;
612 cfg_cmd->priority = 0x00;
613 cfg_cmd->ifs = 0x60;
614 cfg_cmd->time_low = 0x00;
615 cfg_cmd->time_high = 0xf2;
616 cfg_cmd->promisc = 0;
617 if (dev->flags & (IFF_ALLMULTI | IFF_PROMISC)) {
618 cfg_cmd->promisc = 1;
619 dev->flags |= IFF_PROMISC;
620 }
621 cfg_cmd->carr_coll = 0x00;
622
623 p->scb->cbl_offset = make16(cfg_cmd);
624
625 p->scb->cmd = CUC_START;
626 elmc_id_attn586();
627
628 s = jiffies;
629 while (!(cfg_cmd->cmd_status & STAT_COMPL)) {
630 if (jiffies - s > 30*HZ/100)
631 break;
632 }
633
634 if ((cfg_cmd->cmd_status & (STAT_OK | STAT_COMPL)) != (STAT_COMPL | STAT_OK)) {
635 printk(KERN_WARNING "%s (elmc): configure command failed: %x\n", dev->name, cfg_cmd->cmd_status);
636 return 1;
637 }
638
639
640
641 ias_cmd = (struct iasetup_cmd_struct *) ptr;
642
643 ias_cmd->cmd_status = 0;
644 ias_cmd->cmd_cmd = CMD_IASETUP | CMD_LAST;
645 ias_cmd->cmd_link = 0xffff;
646
647 memcpy((char *) &ias_cmd->iaddr, (char *) dev->dev_addr, ETH_ALEN);
648
649 p->scb->cbl_offset = make16(ias_cmd);
650
651 p->scb->cmd = CUC_START;
652 elmc_id_attn586();
653
654 s = jiffies;
655 while (!(ias_cmd->cmd_status & STAT_COMPL)) {
656 if (jiffies - s > 30*HZ/100)
657 break;
658 }
659
660 if ((ias_cmd->cmd_status & (STAT_OK | STAT_COMPL)) != (STAT_OK | STAT_COMPL)) {
661 printk(KERN_WARNING "%s (elmc): individual address setup command failed: %04x\n", dev->name, ias_cmd->cmd_status);
662 return 1;
663 }
664
665
666
667 tdr_cmd = (struct tdr_cmd_struct *) ptr;
668
669 tdr_cmd->cmd_status = 0;
670 tdr_cmd->cmd_cmd = CMD_TDR | CMD_LAST;
671 tdr_cmd->cmd_link = 0xffff;
672 tdr_cmd->status = 0;
673
674 p->scb->cbl_offset = make16(tdr_cmd);
675
676 p->scb->cmd = CUC_START;
677 elmc_attn586();
678
679 s = jiffies;
680 while (!(tdr_cmd->cmd_status & STAT_COMPL)) {
681 if (jiffies - s > 30*HZ/100) {
682 printk(KERN_WARNING "%s: %d Problems while running the TDR.\n", dev->name, __LINE__);
683 result = 1;
684 break;
685 }
686 }
687
688 if (!result) {
689 DELAY(2);
690 result = tdr_cmd->status;
691
692 p->scb->cmd = p->scb->status & STAT_MASK;
693 elmc_id_attn586();
694
695 if (result & TDR_LNK_OK) {
696
697 } else if (result & TDR_XCVR_PRB) {
698 printk(KERN_WARNING "%s: TDR: Transceiver problem!\n", dev->name);
699 } else if (result & TDR_ET_OPN) {
700 printk(KERN_WARNING "%s: TDR: No correct termination %d clocks away.\n", dev->name, result & TDR_TIMEMASK);
701 } else if (result & TDR_ET_SRT) {
702 if (result & TDR_TIMEMASK)
703 printk(KERN_WARNING "%s: TDR: Detected a short circuit %d clocks away.\n", dev->name, result & TDR_TIMEMASK);
704 } else {
705 printk(KERN_WARNING "%s: TDR: Unknown status %04x\n", dev->name, result);
706 }
707 }
708
709
710
711 p->scb->cmd = p->scb->status & STAT_MASK;
712 elmc_id_attn586();
713
714
715
716
717#if (NUM_XMIT_BUFFS == 1)
718 for (i = 0; i < 2; i++) {
719 p->nop_cmds[i] = (struct nop_cmd_struct *) ptr;
720 p->nop_cmds[i]->cmd_cmd = CMD_NOP;
721 p->nop_cmds[i]->cmd_status = 0;
722 p->nop_cmds[i]->cmd_link = make16((p->nop_cmds[i]));
723 ptr = (char *) ptr + sizeof(struct nop_cmd_struct);
724 }
725 p->xmit_cmds[0] = (struct transmit_cmd_struct *) ptr;
726 ptr = (char *) ptr + sizeof(struct transmit_cmd_struct);
727#else
728 for (i = 0; i < NUM_XMIT_BUFFS; i++) {
729 p->nop_cmds[i] = (struct nop_cmd_struct *) ptr;
730 p->nop_cmds[i]->cmd_cmd = CMD_NOP;
731 p->nop_cmds[i]->cmd_status = 0;
732 p->nop_cmds[i]->cmd_link = make16((p->nop_cmds[i]));
733 ptr = (char *) ptr + sizeof(struct nop_cmd_struct);
734 p->xmit_cmds[i] = (struct transmit_cmd_struct *) ptr;
735 ptr = (char *) ptr + sizeof(struct transmit_cmd_struct);
736 }
737#endif
738
739 ptr = alloc_rfa(dev, (void *) ptr);
740
741
742
743
744
745 if (dev->mc_count) {
746
747 int len = ((char *) p->iscp - (char *) ptr - 8) / 6;
748 if (len <= 0) {
749 printk(KERN_ERR "%s: Ooooops, no memory for MC-Setup!\n", dev->name);
750 } else {
751 if (len < num_addrs) {
752 num_addrs = len;
753 printk(KERN_WARNING "%s: Sorry, can only apply %d MC-Address(es).\n",
754 dev->name, num_addrs);
755 }
756 mc_cmd = (struct mcsetup_cmd_struct *) ptr;
757 mc_cmd->cmd_status = 0;
758 mc_cmd->cmd_cmd = CMD_MCSETUP | CMD_LAST;
759 mc_cmd->cmd_link = 0xffff;
760 mc_cmd->mc_cnt = num_addrs * 6;
761 for (i = 0; i < num_addrs; i++) {
762 memcpy((char *) mc_cmd->mc_list[i], dmi->dmi_addr, 6);
763 dmi = dmi->next;
764 }
765 p->scb->cbl_offset = make16(mc_cmd);
766 p->scb->cmd = CUC_START;
767 elmc_id_attn586();
768 s = jiffies;
769 while (!(mc_cmd->cmd_status & STAT_COMPL)) {
770 if (jiffies - s > 30*HZ/100)
771 break;
772 }
773 if (!(mc_cmd->cmd_status & STAT_COMPL)) {
774 printk(KERN_WARNING "%s: Can't apply multicast-address-list.\n", dev->name);
775 }
776 }
777 }
778
779
780
781 for (i = 0; i < NUM_XMIT_BUFFS; i++) {
782 p->xmit_cbuffs[i] = (char *) ptr;
783 ptr = (char *) ptr + XMIT_BUFF_SIZE;
784 p->xmit_buffs[i] = (struct tbd_struct *) ptr;
785 ptr = (char *) ptr + sizeof(struct tbd_struct);
786 if ((void *) ptr > (void *) p->iscp) {
787 printk(KERN_ERR "%s: not enough shared-mem for your configuration!\n", dev->name);
788 return 1;
789 }
790 memset((char *) (p->xmit_cmds[i]), 0, sizeof(struct transmit_cmd_struct));
791 memset((char *) (p->xmit_buffs[i]), 0, sizeof(struct tbd_struct));
792 p->xmit_cmds[i]->cmd_status = STAT_COMPL;
793 p->xmit_cmds[i]->cmd_cmd = CMD_XMIT | CMD_INT;
794 p->xmit_cmds[i]->tbd_offset = make16((p->xmit_buffs[i]));
795 p->xmit_buffs[i]->next = 0xffff;
796 p->xmit_buffs[i]->buffer = make24((p->xmit_cbuffs[i]));
797 }
798
799 p->xmit_count = 0;
800 p->xmit_last = 0;
801#ifndef NO_NOPCOMMANDS
802 p->nop_point = 0;
803#endif
804
805
806
807
808#ifndef NO_NOPCOMMANDS
809 p->scb->cbl_offset = make16(p->nop_cmds[0]);
810 p->scb->cmd = CUC_START;
811 elmc_id_attn586();
812 WAIT_4_SCB_CMD();
813#else
814 p->xmit_cmds[0]->cmd_link = 0xffff;
815 p->xmit_cmds[0]->cmd_cmd = CMD_XMIT | CMD_LAST | CMD_INT;
816#endif
817
818 return 0;
819}
820
821
822
823
824
825
826static void *alloc_rfa(struct net_device *dev, void *ptr)
827{
828 volatile struct rfd_struct *rfd = (struct rfd_struct *) ptr;
829 volatile struct rbd_struct *rbd;
830 int i;
831 struct priv *p = (struct priv *) dev->priv;
832
833 memset((char *) rfd, 0, sizeof(struct rfd_struct) * p->num_recv_buffs);
834 p->rfd_first = rfd;
835
836 for (i = 0; i < p->num_recv_buffs; i++) {
837 rfd[i].next = make16(rfd + (i + 1) % p->num_recv_buffs);
838 }
839 rfd[p->num_recv_buffs - 1].last = RFD_SUSP;
840
841 ptr = (void *) (rfd + p->num_recv_buffs);
842
843 rbd = (struct rbd_struct *) ptr;
844 ptr = (void *) (rbd + p->num_recv_buffs);
845
846
847 memset((char *) rbd, 0, sizeof(struct rbd_struct) * p->num_recv_buffs);
848
849 for (i = 0; i < p->num_recv_buffs; i++) {
850 rbd[i].next = make16((rbd + (i + 1) % p->num_recv_buffs));
851 rbd[i].size = RECV_BUFF_SIZE;
852 rbd[i].buffer = make24(ptr);
853 ptr = (char *) ptr + RECV_BUFF_SIZE;
854 }
855
856 p->rfd_top = p->rfd_first;
857 p->rfd_last = p->rfd_first + p->num_recv_buffs - 1;
858
859 p->scb->rfa_offset = make16(p->rfd_first);
860 p->rfd_first->rbd_offset = make16(rbd);
861
862 return ptr;
863}
864
865
866
867
868
869
870static void elmc_interrupt(int irq, void *dev_id, struct pt_regs *reg_ptr)
871{
872 struct net_device *dev = (struct net_device *) dev_id;
873 unsigned short stat;
874 struct priv *p;
875
876 if (dev == NULL) {
877 printk(KERN_ERR "elmc-interrupt: irq %d for unknown device.\n", (int) -(((struct pt_regs *) reg_ptr)->orig_eax + 2));
878 return;
879 } else if (!netif_running(dev)) {
880
881
882
883
884
885
886 elmc_id_attn586();
887 return;
888 } else if (!(ELMC_CTRL_INT & inb(dev->base_addr + ELMC_CTRL))) {
889
890 return;
891 }
892
893
894 p = (struct priv *) dev->priv;
895
896 while ((stat = p->scb->status & STAT_MASK))
897 {
898 p->scb->cmd = stat;
899 elmc_attn586();
900
901 if (stat & STAT_CX) {
902
903 elmc_xmt_int(dev);
904 }
905 if (stat & STAT_FR) {
906
907 elmc_rcv_int(dev);
908 }
909#ifndef NO_NOPCOMMANDS
910 if (stat & STAT_CNA) {
911
912 if (netif_running(dev)) {
913 printk(KERN_WARNING "%s: oops! CU has left active state. stat: %04x/%04x.\n", dev->name, (int) stat, (int) p->scb->status);
914 }
915 }
916#endif
917
918 if (stat & STAT_RNR) {
919
920
921 if (p->scb->status & RU_SUSPEND) {
922
923
924 WAIT_4_SCB_CMD();
925 p->scb->cmd = RUC_RESUME;
926 elmc_attn586();
927 } else {
928 printk(KERN_WARNING "%s: Receiver-Unit went 'NOT READY': %04x/%04x.\n", dev->name, (int) stat, (int) p->scb->status);
929 elmc_rnr_int(dev);
930 }
931 }
932 WAIT_4_SCB_CMD();
933 if (p->scb->cmd) {
934 break;
935 }
936 }
937}
938
939
940
941
942
943static void elmc_rcv_int(struct net_device *dev)
944{
945 int status;
946 unsigned short totlen;
947 struct sk_buff *skb;
948 struct rbd_struct *rbd;
949 struct priv *p = (struct priv *) dev->priv;
950
951 for (; (status = p->rfd_top->status) & STAT_COMPL;) {
952 rbd = (struct rbd_struct *) make32(p->rfd_top->rbd_offset);
953
954 if (status & STAT_OK) {
955 if ((totlen = rbd->status) & RBD_LAST) {
956 totlen &= RBD_MASK;
957 rbd->status = 0;
958 skb = (struct sk_buff *) dev_alloc_skb(totlen + 2);
959 if (skb != NULL) {
960 skb->dev = dev;
961 skb_reserve(skb, 2);
962 skb_put(skb,totlen);
963 eth_copy_and_sum(skb, (char *) p->base+(unsigned long) rbd->buffer,totlen,0);
964 skb->protocol = eth_type_trans(skb, dev);
965 netif_rx(skb);
966 dev->last_rx = jiffies;
967 p->stats.rx_packets++;
968 p->stats.rx_bytes += totlen;
969 } else {
970 p->stats.rx_dropped++;
971 }
972 } else {
973 printk(KERN_WARNING "%s: received oversized frame.\n", dev->name);
974 p->stats.rx_dropped++;
975 }
976 } else {
977 printk(KERN_WARNING "%s: oops! rfd-error-status: %04x\n", dev->name, status);
978 p->stats.rx_errors++;
979 }
980 p->rfd_top->status = 0;
981 p->rfd_top->last = RFD_SUSP;
982 p->rfd_last->last = 0;
983 p->rfd_last = p->rfd_top;
984 p->rfd_top = (struct rfd_struct *) make32(p->rfd_top->next);
985 }
986}
987
988
989
990
991
992static void elmc_rnr_int(struct net_device *dev)
993{
994 struct priv *p = (struct priv *) dev->priv;
995
996 p->stats.rx_errors++;
997
998 WAIT_4_SCB_CMD();
999 p->scb->cmd = RUC_ABORT;
1000 elmc_attn586();
1001 WAIT_4_SCB_CMD();
1002
1003 alloc_rfa(dev, (char *) p->rfd_first);
1004 startrecv586(dev);
1005
1006 printk(KERN_WARNING "%s: Receive-Unit restarted. Status: %04x\n", dev->name, p->scb->status);
1007
1008}
1009
1010
1011
1012
1013
1014static void elmc_xmt_int(struct net_device *dev)
1015{
1016 int status;
1017 struct priv *p = (struct priv *) dev->priv;
1018
1019 status = p->xmit_cmds[p->xmit_last]->cmd_status;
1020 if (!(status & STAT_COMPL)) {
1021 printk(KERN_WARNING "%s: strange .. xmit-int without a 'COMPLETE'\n", dev->name);
1022 }
1023 if (status & STAT_OK) {
1024 p->stats.tx_packets++;
1025 p->stats.collisions += (status & TCMD_MAXCOLLMASK);
1026 } else {
1027 p->stats.tx_errors++;
1028 if (status & TCMD_LATECOLL) {
1029 printk(KERN_WARNING "%s: late collision detected.\n", dev->name);
1030 p->stats.collisions++;
1031 } else if (status & TCMD_NOCARRIER) {
1032 p->stats.tx_carrier_errors++;
1033 printk(KERN_WARNING "%s: no carrier detected.\n", dev->name);
1034 } else if (status & TCMD_LOSTCTS) {
1035 printk(KERN_WARNING "%s: loss of CTS detected.\n", dev->name);
1036 } else if (status & TCMD_UNDERRUN) {
1037 p->stats.tx_fifo_errors++;
1038 printk(KERN_WARNING "%s: DMA underrun detected.\n", dev->name);
1039 } else if (status & TCMD_MAXCOLL) {
1040 printk(KERN_WARNING "%s: Max. collisions exceeded.\n", dev->name);
1041 p->stats.collisions += 16;
1042 }
1043 }
1044
1045#if (NUM_XMIT_BUFFS != 1)
1046 if ((++p->xmit_last) == NUM_XMIT_BUFFS) {
1047 p->xmit_last = 0;
1048 }
1049#endif
1050
1051 netif_wake_queue(dev);
1052}
1053
1054
1055
1056
1057
1058static void startrecv586(struct net_device *dev)
1059{
1060 struct priv *p = (struct priv *) dev->priv;
1061
1062 p->scb->rfa_offset = make16(p->rfd_first);
1063 p->scb->cmd = RUC_START;
1064 elmc_attn586();
1065 WAIT_4_SCB_CMD();
1066}
1067
1068
1069
1070
1071
1072static void elmc_timeout(struct net_device *dev)
1073{
1074 struct priv *p = (struct priv *) dev->priv;
1075
1076 if (p->scb->status & CU_ACTIVE) {
1077#ifdef DEBUG
1078 printk("%s: strange ... timeout with CU active?!?\n", dev->name);
1079 printk("%s: X0: %04x N0: %04x N1: %04x %d\n", dev->name, (int) p->xmit_cmds[0]->cmd_status, (int) p->nop_cmds[0]->cmd_status, (int) p->nop_cmds[1]->cmd_status, (int) p->nop_point);
1080#endif
1081 p->scb->cmd = CUC_ABORT;
1082 elmc_attn586();
1083 WAIT_4_SCB_CMD();
1084 p->scb->cbl_offset = make16(p->nop_cmds[p->nop_point]);
1085 p->scb->cmd = CUC_START;
1086 elmc_attn586();
1087 WAIT_4_SCB_CMD();
1088 netif_wake_queue(dev);
1089 } else {
1090#ifdef DEBUG
1091 printk("%s: xmitter timed out, try to restart! stat: %04x\n", dev->name, p->scb->status);
1092 printk("%s: command-stats: %04x %04x\n", dev->name, p->xmit_cmds[0]->cmd_status, p->xmit_cmds[1]->cmd_status);
1093#endif
1094 elmc_close(dev);
1095 elmc_open(dev);
1096 }
1097}
1098
1099
1100
1101
1102
1103static int elmc_send_packet(struct sk_buff *skb, struct net_device *dev)
1104{
1105 int len;
1106 int i;
1107#ifndef NO_NOPCOMMANDS
1108 int next_nop;
1109#endif
1110 struct priv *p = (struct priv *) dev->priv;
1111
1112 netif_stop_queue(dev);
1113
1114 memcpy((char *) p->xmit_cbuffs[p->xmit_count], (char *) (skb->data), skb->len);
1115 len = (ETH_ZLEN < skb->len) ? skb->len : ETH_ZLEN;
1116
1117#if (NUM_XMIT_BUFFS == 1)
1118#ifdef NO_NOPCOMMANDS
1119 p->xmit_buffs[0]->size = TBD_LAST | len;
1120 for (i = 0; i < 16; i++) {
1121 p->scb->cbl_offset = make16(p->xmit_cmds[0]);
1122 p->scb->cmd = CUC_START;
1123 p->xmit_cmds[0]->cmd_status = 0;
1124 elmc_attn586();
1125 dev->trans_start = jiffies;
1126 if (!i) {
1127 dev_kfree_skb(skb);
1128 }
1129 WAIT_4_SCB_CMD();
1130 if ((p->scb->status & CU_ACTIVE)) {
1131 break;
1132 }
1133 if (p->xmit_cmds[0]->cmd_status) {
1134 break;
1135 }
1136 if (i == 15) {
1137 printk(KERN_WARNING "%s: Can't start transmit-command.\n", dev->name);
1138 }
1139 }
1140#else
1141 next_nop = (p->nop_point + 1) & 0x1;
1142 p->xmit_buffs[0]->size = TBD_LAST | len;
1143
1144 p->xmit_cmds[0]->cmd_link = p->nop_cmds[next_nop]->cmd_link
1145 = make16((p->nop_cmds[next_nop]));
1146 p->xmit_cmds[0]->cmd_status = p->nop_cmds[next_nop]->cmd_status = 0;
1147
1148 p->nop_cmds[p->nop_point]->cmd_link = make16((p->xmit_cmds[0]));
1149 dev->trans_start = jiffies;
1150 p->nop_point = next_nop;
1151 dev_kfree_skb(skb);
1152#endif
1153#else
1154 p->xmit_buffs[p->xmit_count]->size = TBD_LAST | len;
1155 if ((next_nop = p->xmit_count + 1) == NUM_XMIT_BUFFS) {
1156 next_nop = 0;
1157 }
1158 p->xmit_cmds[p->xmit_count]->cmd_status = 0;
1159 p->xmit_cmds[p->xmit_count]->cmd_link = p->nop_cmds[next_nop]->cmd_link
1160 = make16((p->nop_cmds[next_nop]));
1161 p->nop_cmds[next_nop]->cmd_status = 0;
1162 p->nop_cmds[p->xmit_count]->cmd_link = make16((p->xmit_cmds[p->xmit_count]));
1163 dev->trans_start = jiffies;
1164 p->xmit_count = next_nop;
1165 if (p->xmit_count != p->xmit_last)
1166 netif_wake_queue(dev);
1167 dev_kfree_skb(skb);
1168#endif
1169 return 0;
1170}
1171
1172
1173
1174
1175
1176static struct net_device_stats *elmc_get_stats(struct net_device *dev)
1177{
1178 struct priv *p = (struct priv *) dev->priv;
1179 unsigned short crc, aln, rsc, ovrn;
1180
1181 crc = p->scb->crc_errs;
1182 p->scb->crc_errs -= crc;
1183 aln = p->scb->aln_errs;
1184 p->scb->aln_errs -= aln;
1185 rsc = p->scb->rsc_errs;
1186 p->scb->rsc_errs -= rsc;
1187 ovrn = p->scb->ovrn_errs;
1188 p->scb->ovrn_errs -= ovrn;
1189
1190 p->stats.rx_crc_errors += crc;
1191 p->stats.rx_fifo_errors += ovrn;
1192 p->stats.rx_frame_errors += aln;
1193 p->stats.rx_dropped += rsc;
1194
1195 return &p->stats;
1196}
1197
1198
1199
1200
1201
1202#ifdef ELMC_MULTICAST
1203static void set_multicast_list(struct net_device *dev)
1204{
1205 if (!dev->start) {
1206
1207 return;
1208 }
1209 dev->start = 0;
1210 alloc586(dev);
1211 init586(dev);
1212 startrecv586(dev);
1213 dev->start = 1;
1214}
1215#endif
1216
1217
1218
1219#ifdef MODULE
1220
1221
1222#define MAX_3C523_CARDS 4
1223
1224static struct net_device dev_elmc[MAX_3C523_CARDS];
1225static int irq[MAX_3C523_CARDS];
1226static int io[MAX_3C523_CARDS];
1227MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_3C523_CARDS) "i");
1228MODULE_PARM(io, "1-" __MODULE_STRING(MAX_3C523_CARDS) "i");
1229MODULE_PARM_DESC(io, "EtherLink/MC I/O base address(es)");
1230MODULE_PARM_DESC(irq, "EtherLink/MC IRQ number(s)");
1231
1232int init_module(void)
1233{
1234 int this_dev,found = 0;
1235
1236
1237 for(this_dev=0; this_dev<MAX_3C523_CARDS; this_dev++)
1238 {
1239 struct net_device *dev = &dev_elmc[this_dev];
1240 dev->irq=irq[this_dev];
1241 dev->base_addr=io[this_dev];
1242 dev->init=elmc_probe;
1243 if(register_netdev(dev)!=0) {
1244 if(io[this_dev]==0) break;
1245 printk(KERN_WARNING "3c523.c: No 3c523 card found at io=%#x\n",io[this_dev]);
1246 } else found++;
1247 }
1248
1249 if(found==0) {
1250 if(io[0]==0) printk(KERN_NOTICE "3c523.c: No 3c523 cards found\n");
1251 return -ENXIO;
1252 } else return 0;
1253}
1254
1255void cleanup_module(void)
1256{
1257 int this_dev;
1258 for(this_dev=0; this_dev<MAX_3C523_CARDS; this_dev++) {
1259
1260 struct net_device *dev = &dev_elmc[this_dev];
1261 if(dev->priv) {
1262
1263 elmc_id_reset586();
1264 if (dev->irq != 0) {
1265
1266
1267 free_irq(dev->irq, dev);
1268 dev->irq = 0;
1269 }
1270 if (dev->base_addr != 0) {
1271 release_region(dev->base_addr, ELMC_IO_EXTENT);
1272 dev->base_addr = 0;
1273 }
1274 irq[this_dev] = 0;
1275 io[this_dev] = 0;
1276 unregister_netdev(dev);
1277
1278 mca_set_adapter_procfn(((struct priv *) (dev->priv))->slot,
1279 NULL, NULL);
1280
1281 kfree(dev->priv);
1282 dev->priv = NULL;
1283 }
1284 }
1285}
1286
1287#endif
1288