2 net-3-driver for the 3c523 Etherlink/MC card (i82586 Ethernet chip)
5 This is an extension to the Linux operating system, and is covered by the
6 same Gnu Public License that covers that work.
8 Copyright 1995, 1996 by Chris Beauregard (cpbeaure@undergrad.math.uwaterloo.ca)
10 This is basically Michael Hipp's ni52 driver, with a new probing
11 algorithm and some minor changes to the 82586 CA and reset routines.
12 Thanks a lot Michael for a really clean i82586 implementation! Unless
13 otherwise documented in ni52.c, any bugs are mine.
15 Contrary to the Ethernet-HOWTO, this isn't based on the 3c507 driver in
16 any way. The ni52 is a lot easier to modify.
21 Crynwr packet driver collection was a great reference for my first
22 attempt at this sucker. The 3c507 driver also helped, until I noticed
23 that ni52.c was a lot nicer.
25 EtherLink/MC: Micro Channel Ethernet Adapter Technical Reference
26 Manual, courtesy of 3Com CardFacts, documents the 3c523-specific
27 stuff. Information on CardFacts is found in the Ethernet HOWTO.
28 Also see <a href="http://www.3com.com/">
30 Microprocessor Communications Support Chips, T.J. Byers, ISBN
31 0-444-01224-9, has a section on the i82586. It tells you just enough
32 to know that you really don't want to learn how to program the chip.
34 The original device probe code was stolen from ps2esdi.c
37 Since most of the code was stolen from ni52.c, you'll run across the
38 same bugs in the 0.62 version of ni52.c, plus maybe a few because of
39 the 3c523 idiosynchacies. The 3c523 has 16K of RAM though, so there
40 shouldn't be the overrun problem that the 8K ni52 has.
42 This driver is for a 16K adapter. It should work fine on the 64K
43 adapters, but it will only use one of the 4 banks of RAM. Modifying
44 this for the 64K version would require a lot of heinous bank
45 switching, which I'm sure not interested in doing. If you try to
46 implement a bank switching version, you'll basically have to remember
47 what bank is enabled and do a switch everytime you access a memory
48 location that's not current. You'll also have to remap pointers on
49 the driver side, because it only knows about 16K of the memory.
50 Anyone desperate or masochistic enough to try?
52 It seems to be stable now when multiple transmit buffers are used. I
53 can't see any performance difference, but then I'm working on a 386SX.
55 Multicast doesn't work. It doesn't even pretend to work. Don't use
56 it. Don't compile your kernel with multicast support. I don't know
60 This driver is useable as a loadable module. If you try to specify an
61 IRQ or a IO address (via insmod 3c523.o irq=xx io=0xyyy), it will
62 search the MCA slots until it finds a 3c523 with the specified
65 This driver does support multiple ethernet cards when used as a module
66 (up to MAX_3C523_CARDS, the default being 4)
68 This has been tested with both BNC and TP versions, internal and
69 external transceivers. Haven't tested with the 64K version (that I
76 update to 1.3.59, incorporated multicast diffs from ni52.c
78 added shared irq support
80 added support for multiple cards when used as a module
81 added option to disable multicast as is causes problems
82 Ganesh Sittampalam <ganesh.sittampalam@magdalen.oxford.ac.uk>
83 Stuart Adamson <stuart.adamson@compsoc.net>
85 $Header: /fsys2/home/chrisb/linux-1.3.59-MCA/drivers/net/RCS/3c523.c,v 1.1 1996/02/05 01:53:46 chrisb Exp chrisb $
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/malloc.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>
102 #include <linux/netdevice.h>
103 #include <linux/etherdevice.h>
104 #include <linux/skbuff.h>
105 #include <linux/init.h>
109 /*************************************************************************/
110 #define DEBUG /* debug on */
111 #define SYSBUSVAL 0 /* 1 = 8 Bit, 0 = 16 bit - 3c523 only does 16 bit */
112 #undef ELMC_MULTICAST /* Disable multicast support as it is somewhat seriously broken at the moment */
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 ))
118 /*************************************************************************/
120 Tables to which we can map values in the configuration registers.
122 static int irq_table
[] __initdata
= {
126 static int csr_table
[] __initdata
= {
127 0x300, 0x1300, 0x2300, 0x3300
130 static int shm_table
[] __initdata
= {
131 0x0c0000, 0x0c8000, 0x0d0000, 0x0d8000
134 /******************* how to calculate the buffers *****************************
137 * IMPORTANT NOTE: if you configure only one NUM_XMIT_BUFFS, the driver works
138 * --------------- in a different (more stable?) mode. Only in this mode it's
139 * possible to configure the driver with 'NO_NOPCOMMANDS'
141 sizeof(scp)=12; sizeof(scb)=16; sizeof(iscp)=8;
142 sizeof(scp)+sizeof(iscp)+sizeof(scb) = 36 = INIT
143 sizeof(rfd) = 24; sizeof(rbd) = 12;
144 sizeof(tbd) = 8; sizeof(transmit_cmd) = 16;
147 * if you don't know the driver, better do not change this values: */
149 #define RECV_BUFF_SIZE 1524 /* slightly oversized */
150 #define XMIT_BUFF_SIZE 1524 /* slightly oversized */
151 #define NUM_XMIT_BUFFS 4 /* config for both, 8K and 16K shmem */
152 #define NUM_RECV_BUFFS_8 1 /* config for 8K shared mem */
153 #define NUM_RECV_BUFFS_16 6 /* config for 16K shared mem */
155 #if (NUM_XMIT_BUFFS == 1)
156 #define NO_NOPCOMMANDS /* only possible with NUM_XMIT_BUFFS=1 */
159 /**************************************************************************/
161 #define DELAY(x) { mdelay(32 * x); }
163 /* a much shorter delay: */
164 #define DELAY_16(); { udelay(16) ; }
166 /* wait for command with timeout: */
167 #define WAIT_4_SCB_CMD() { int i; \
168 for(i=0;i<1024;i++) { \
169 if(!p->scb->cmd) break; \
172 printk(KERN_WARNING "%s:%d: scb_cmd timed out .. resetting i82586\n",\
173 dev->name,__LINE__); \
174 elmc_id_reset586(); } } }
176 static void elmc_interrupt(int irq
, void *dev_id
, struct pt_regs
*reg_ptr
);
177 static int elmc_open(struct net_device
*dev
);
178 static int elmc_close(struct net_device
*dev
);
179 static int elmc_send_packet(struct sk_buff
*, struct net_device
*);
180 static struct net_device_stats
*elmc_get_stats(struct net_device
*dev
);
181 static void elmc_timeout(struct net_device
*dev
);
182 #ifdef ELMC_MULTICAST
183 static void set_multicast_list(struct net_device
*dev
);
186 /* helper-functions */
187 static int init586(struct net_device
*dev
);
188 static int check586(struct net_device
*dev
, unsigned long where
, unsigned size
);
189 static void alloc586(struct net_device
*dev
);
190 static void startrecv586(struct net_device
*dev
);
191 static void *alloc_rfa(struct net_device
*dev
, void *ptr
);
192 static void elmc_rcv_int(struct net_device
*dev
);
193 static void elmc_xmt_int(struct net_device
*dev
);
194 static void elmc_rnr_int(struct net_device
*dev
);
197 struct net_device_stats stats
;
200 volatile struct rfd_struct
*rfd_last
, *rfd_top
, *rfd_first
;
201 volatile struct scp_struct
*scp
; /* volatile is important */
202 volatile struct iscp_struct
*iscp
; /* volatile is important */
203 volatile struct scb_struct
*scb
; /* volatile is important */
204 volatile struct tbd_struct
*xmit_buffs
[NUM_XMIT_BUFFS
];
205 volatile struct transmit_cmd_struct
*xmit_cmds
[NUM_XMIT_BUFFS
];
206 #if (NUM_XMIT_BUFFS == 1)
207 volatile struct nop_cmd_struct
*nop_cmds
[2];
209 volatile struct nop_cmd_struct
*nop_cmds
[NUM_XMIT_BUFFS
];
211 volatile int nop_point
, num_recv_buffs
;
212 volatile char *xmit_cbuffs
[NUM_XMIT_BUFFS
];
213 volatile int xmit_count
, xmit_last
;
217 #define elmc_attn586() {elmc_do_attn586(dev->base_addr,ELMC_CTRL_INTE);}
218 #define elmc_reset586() {elmc_do_reset586(dev->base_addr,ELMC_CTRL_INTE);}
220 /* with interrupts disabled - this will clear the interrupt bit in the
221 3c523 control register, and won't put it back. This effectively
222 disables interrupts on the card. */
223 #define elmc_id_attn586() {elmc_do_attn586(dev->base_addr,0);}
224 #define elmc_id_reset586() {elmc_do_reset586(dev->base_addr,0);}
226 /*************************************************************************/
228 Do a Channel Attention on the 3c523. This is extremely board dependent.
230 static void elmc_do_attn586(int ioaddr
, int ints
)
232 /* the 3c523 requires a minimum of 500 ns. The delays here might be
233 a little too large, and hence they may cut the performance of the
234 card slightly. If someone who knows a little more about Linux
235 timing would care to play with these, I'd appreciate it. */
237 /* this bit masking stuff is crap. I'd rather have separate
238 registers with strobe triggers for each of these functions. <sigh>
239 Ya take what ya got. */
241 outb(ELMC_CTRL_RST
| 0x3 | ELMC_CTRL_CA
| ints
, ioaddr
+ ELMC_CTRL
);
242 DELAY_16(); /* > 500 ns */
243 outb(ELMC_CTRL_RST
| 0x3 | ints
, ioaddr
+ ELMC_CTRL
);
246 /*************************************************************************/
248 Reset the 82586 on the 3c523. Also very board dependent.
250 static void elmc_do_reset586(int ioaddr
, int ints
)
252 /* toggle the RST bit low then high */
253 outb(0x3 | ELMC_CTRL_LBK
, ioaddr
+ ELMC_CTRL
);
254 DELAY_16(); /* > 500 ns */
255 outb(ELMC_CTRL_RST
| ELMC_CTRL_LBK
| 0x3, ioaddr
+ ELMC_CTRL
);
257 elmc_do_attn586(ioaddr
, ints
);
260 /**********************************************
264 static int elmc_close(struct net_device
*dev
)
266 netif_stop_queue(dev
);
267 elmc_id_reset586(); /* the hard way to stop the receiver */
268 free_irq(dev
->irq
, dev
);
272 /**********************************************
276 static int elmc_open(struct net_device
*dev
)
280 elmc_id_attn586(); /* disable interrupts */
282 ret
= request_irq(dev
->irq
, &elmc_interrupt
, SA_SHIRQ
| SA_SAMPLE_RANDOM
,
285 printk(KERN_ERR
"%s: couldn't get irq %d\n", dev
->name
, dev
->irq
);
292 netif_start_queue(dev
);
293 return 0; /* most done by init */
296 /**********************************************
297 * Check to see if there's an 82586 out there.
300 static int __init
check586(struct net_device
*dev
, unsigned long where
, unsigned size
)
302 struct priv
*p
= (struct priv
*) dev
->priv
;
306 p
->base
= where
+ size
- 0x01000000;
307 p
->memtop
= phys_to_virt(where
) + size
;
308 p
->scp
= (struct scp_struct
*)phys_to_virt(p
->base
+ SCP_DEFAULT_ADDRESS
);
309 memset((char *) p
->scp
, 0, sizeof(struct scp_struct
));
310 p
->scp
->sysbus
= SYSBUSVAL
; /* 1 = 8Bit-Bus, 0 = 16 Bit */
312 iscp_addrs
[0] = phys_to_virt(where
);
313 iscp_addrs
[1] = (char *) p
->scp
- sizeof(struct iscp_struct
);
315 for (i
= 0; i
< 2; i
++) {
316 p
->iscp
= (struct iscp_struct
*) iscp_addrs
[i
];
317 memset((char *) p
->iscp
, 0, sizeof(struct iscp_struct
));
319 p
->scp
->iscp
= make24(p
->iscp
);
324 /* reset586 does an implicit CA */
326 /* apparently, you sometimes have to kick the 82586 twice... */
329 if (p
->iscp
->busy
) { /* i82586 clears 'busy' after successful init */
336 /******************************************************************
337 * set iscp at the right place, called by elmc_probe and open586.
340 void alloc586(struct net_device
*dev
)
342 struct priv
*p
= (struct priv
*) dev
->priv
;
347 p
->scp
= (struct scp_struct
*) phys_to_virt(p
->base
+ SCP_DEFAULT_ADDRESS
);
348 p
->scb
= (struct scb_struct
*) phys_to_virt(dev
->mem_start
);
349 p
->iscp
= (struct iscp_struct
*) ((char *) p
->scp
- sizeof(struct iscp_struct
));
351 memset((char *) p
->iscp
, 0, sizeof(struct iscp_struct
));
352 memset((char *) p
->scp
, 0, sizeof(struct scp_struct
));
354 p
->scp
->iscp
= make24(p
->iscp
);
355 p
->scp
->sysbus
= SYSBUSVAL
;
356 p
->iscp
->scb_offset
= make16(p
->scb
);
365 printk(KERN_ERR
"%s: Init-Problems (alloc).\n", dev
->name
);
367 memset((char *) p
->scb
, 0, sizeof(struct scb_struct
));
370 /*****************************************************************/
372 static int elmc_getinfo(char *buf
, int slot
, void *d
)
375 struct net_device
*dev
= (struct net_device
*) d
;
381 len
+= sprintf(buf
+ len
, "Revision: 0x%x\n",
382 inb(dev
->base_addr
+ ELMC_REVISION
) & 0xf);
383 len
+= sprintf(buf
+ len
, "IRQ: %d\n", dev
->irq
);
384 len
+= sprintf(buf
+ len
, "IO Address: %#lx-%#lx\n", dev
->base_addr
,
385 dev
->base_addr
+ ELMC_IO_EXTENT
);
386 len
+= sprintf(buf
+ len
, "Memory: %#lx-%#lx\n", dev
->mem_start
,
388 len
+= sprintf(buf
+ len
, "Transceiver: %s\n", dev
->if_port
?
389 "External" : "Internal");
390 len
+= sprintf(buf
+ len
, "Device: %s\n", dev
->name
);
391 len
+= sprintf(buf
+ len
, "Hardware Address:");
392 for (i
= 0; i
< 6; i
++) {
393 len
+= sprintf(buf
+ len
, " %02x", dev
->dev_addr
[i
]);
399 } /* elmc_getinfo() */
401 /*****************************************************************/
403 int __init
elmc_probe(struct net_device
*dev
)
406 int base_addr
= dev
->base_addr
;
411 unsigned int size
= 0;
413 SET_MODULE_OWNER(dev
);
417 /* search through the slots for the 3c523. */
418 slot
= mca_find_adapter(ELMC_MCA_ID
, 0);
420 status
= mca_read_stored_pos(slot
, 2);
422 dev
->irq
=irq_table
[(status
& ELMC_STATUS_IRQ_SELECT
) >> 6];
423 dev
->base_addr
=csr_table
[(status
& ELMC_STATUS_CSR_SELECT
) >> 1];
426 If we're trying to match a specified irq or IO address,
427 we'll reject a match unless it's what we're looking for.
428 Also reject it if the card is already in use.
431 if((irq
&& irq
!= dev
->irq
) || (base_addr
&& base_addr
!= dev
->base_addr
)
432 || check_region(dev
->base_addr
,ELMC_IO_EXTENT
)) {
433 slot
= mca_find_adapter(ELMC_MCA_ID
, slot
+ 1);
436 /* found what we're looking for... */
440 /* we didn't find any 3c523 in the slots we checked for */
441 if (slot
== MCA_NOTFOUND
) {
442 return ((base_addr
|| irq
) ? ENXIO
: ENODEV
);
444 mca_set_adapter_name(slot
, "3Com 3c523 Etherlink/MC");
445 mca_set_adapter_procfn(slot
, (MCA_ProcFn
) elmc_getinfo
, dev
);
447 /* if we get this far, adapter has been found - carry on */
448 printk(KERN_INFO
"%s: 3c523 adapter found in slot %d\n", dev
->name
, slot
+ 1);
450 /* Now we extract configuration info from the card.
451 The 3c523 provides information in two of the POS registers, but
452 the second one is only needed if we want to tell the card what IRQ
453 to use. I suspect that whoever sets the thing up initially would
454 prefer we don't screw with those things.
456 Note that we read the status info when we found the card...
458 See 3c523.h for more details.
461 /* revision is stored in the first 4 bits of the revision register */
462 revision
= inb(dev
->base_addr
+ ELMC_REVISION
) & 0xf;
464 /* according to docs, we read the interrupt and write it back to
465 the IRQ select register, since the POST might not configure the IRQ
469 mca_write_pos(slot
, 3, 0x04);
472 mca_write_pos(slot
, 3, 0x02);
475 mca_write_pos(slot
, 3, 0x08);
478 mca_write_pos(slot
, 3, 0x01);
482 request_region(dev
->base_addr
, ELMC_IO_EXTENT
, "3c523");
484 dev
->priv
= (void *) kmalloc(sizeof(struct priv
), GFP_KERNEL
);
485 if (dev
->priv
== NULL
) {
488 memset((char *) dev
->priv
, 0, sizeof(struct priv
));
490 ((struct priv
*) (dev
->priv
))->slot
= slot
;
492 printk(KERN_INFO
"%s: 3Com 3c523 Rev 0x%x at %#lx\n", dev
->name
, (int) revision
,
495 /* Determine if we're using the on-board transceiver (i.e. coax) or
496 an external one. The information is pretty much useless, but I
497 guess it's worth brownie points. */
498 dev
->if_port
= (status
& ELMC_STATUS_DISABLE_THIN
);
500 /* The 3c523 has a 24K chunk of memory. The first 16K is the
501 shared memory, while the last 8K is for the EtherStart BIOS ROM.
502 Which we don't care much about here. We'll just tell Linux that
503 we're using 16K. MCA won't permit address space conflicts caused
504 by not mapping the other 8K. */
505 dev
->mem_start
= shm_table
[(status
& ELMC_STATUS_MEMORY_SELECT
) >> 3];
507 /* We're using MCA, so it's a given that the information about memory
508 size is correct. The Crynwr drivers do something like this. */
510 elmc_id_reset586(); /* seems like a good idea before checking it... */
512 size
= 0x4000; /* check for 16K mem */
513 if (!check586(dev
, dev
->mem_start
, size
)) {
514 printk(KERN_ERR
"%s: memprobe, Can't find memory at 0x%lx!\n", dev
->name
,
516 release_region(dev
->base_addr
, ELMC_IO_EXTENT
);
519 dev
->mem_end
= dev
->mem_start
+ size
; /* set mem_end showed by 'ifconfig' */
521 ((struct priv
*) (dev
->priv
))->base
= dev
->mem_start
+ size
- 0x01000000;
524 elmc_id_reset586(); /* make sure it doesn't generate spurious ints */
526 /* set number of receive-buffs according to memsize */
527 ((struct priv
*) dev
->priv
)->num_recv_buffs
= NUM_RECV_BUFFS_16
;
529 /* dump all the assorted information */
530 printk(KERN_INFO
"%s: IRQ %d, %sternal xcvr, memory %#lx-%#lx.\n", dev
->name
,
531 dev
->irq
, dev
->if_port
? "ex" : "in",
532 dev
->mem_start
, dev
->mem_end
- 1);
534 /* The hardware address for the 3c523 is stored in the first six
535 bytes of the IO address. */
536 printk(KERN_INFO
"%s: hardware address ", dev
->name
);
537 for (i
= 0; i
< 6; i
++) {
538 dev
->dev_addr
[i
] = inb(dev
->base_addr
+ i
);
539 printk(" %02x", dev
->dev_addr
[i
]);
543 dev
->open
= &elmc_open
;
544 dev
->stop
= &elmc_close
;
545 dev
->get_stats
= &elmc_get_stats
;
546 dev
->hard_start_xmit
= &elmc_send_packet
;
547 dev
->tx_timeout
= &elmc_timeout
;
548 dev
->watchdog_timeo
= HZ
;
549 #ifdef ELMC_MULTICAST
550 dev
->set_multicast_list
= &set_multicast_list
;
552 dev
->set_multicast_list
= NULL
;
557 /* note that we haven't actually requested the IRQ from the kernel.
558 That gets done in elmc_open(). I'm not sure that's such a good idea,
559 but it works, so I'll go with it. */
561 #ifndef ELMC_MULTICAST
562 dev
->flags
&=~IFF_MULTICAST
; /* Multicast doesn't work */
568 /**********************************************
569 * init the chip (elmc-interrupt should be disabled?!)
570 * needs a correct 'allocated' memory
573 static int init586(struct net_device
*dev
)
578 struct priv
*p
= (struct priv
*) dev
->priv
;
579 volatile struct configure_cmd_struct
*cfg_cmd
;
580 volatile struct iasetup_cmd_struct
*ias_cmd
;
581 volatile struct tdr_cmd_struct
*tdr_cmd
;
582 volatile struct mcsetup_cmd_struct
*mc_cmd
;
583 struct dev_mc_list
*dmi
= dev
->mc_list
;
584 int num_addrs
= dev
->mc_count
;
586 ptr
= (void *) ((char *) p
->scb
+ sizeof(struct scb_struct
));
588 cfg_cmd
= (struct configure_cmd_struct
*) ptr
; /* configure-command */
589 cfg_cmd
->cmd_status
= 0;
590 cfg_cmd
->cmd_cmd
= CMD_CONFIGURE
| CMD_LAST
;
591 cfg_cmd
->cmd_link
= 0xffff;
593 cfg_cmd
->byte_cnt
= 0x0a; /* number of cfg bytes */
594 cfg_cmd
->fifo
= 0x08; /* fifo-limit (8=tx:32/rx:64) */
595 cfg_cmd
->sav_bf
= 0x40; /* hold or discard bad recv frames (bit 7) */
596 cfg_cmd
->adr_len
= 0x2e; /* addr_len |!src_insert |pre-len |loopback */
597 cfg_cmd
->priority
= 0x00;
599 cfg_cmd
->time_low
= 0x00;
600 cfg_cmd
->time_high
= 0xf2;
601 cfg_cmd
->promisc
= 0;
602 if (dev
->flags
& (IFF_ALLMULTI
| IFF_PROMISC
)) {
603 cfg_cmd
->promisc
= 1;
604 dev
->flags
|= IFF_PROMISC
;
606 cfg_cmd
->carr_coll
= 0x00;
608 p
->scb
->cbl_offset
= make16(cfg_cmd
);
610 p
->scb
->cmd
= CUC_START
; /* cmd.-unit start */
613 s
= jiffies
; /* warning: only active with interrupts on !! */
614 while (!(cfg_cmd
->cmd_status
& STAT_COMPL
)) {
615 if (jiffies
- s
> 30*HZ
/100)
619 if ((cfg_cmd
->cmd_status
& (STAT_OK
| STAT_COMPL
)) != (STAT_COMPL
| STAT_OK
)) {
620 printk(KERN_WARNING
"%s (elmc): configure command failed: %x\n", dev
->name
, cfg_cmd
->cmd_status
);
624 * individual address setup
626 ias_cmd
= (struct iasetup_cmd_struct
*) ptr
;
628 ias_cmd
->cmd_status
= 0;
629 ias_cmd
->cmd_cmd
= CMD_IASETUP
| CMD_LAST
;
630 ias_cmd
->cmd_link
= 0xffff;
632 memcpy((char *) &ias_cmd
->iaddr
, (char *) dev
->dev_addr
, ETH_ALEN
);
634 p
->scb
->cbl_offset
= make16(ias_cmd
);
636 p
->scb
->cmd
= CUC_START
; /* cmd.-unit start */
640 while (!(ias_cmd
->cmd_status
& STAT_COMPL
)) {
641 if (jiffies
- s
> 30*HZ
/100)
645 if ((ias_cmd
->cmd_status
& (STAT_OK
| STAT_COMPL
)) != (STAT_OK
| STAT_COMPL
)) {
646 printk(KERN_WARNING
"%s (elmc): individual address setup command failed: %04x\n", dev
->name
, ias_cmd
->cmd_status
);
650 * TDR, wire check .. e.g. no resistor e.t.c
652 tdr_cmd
= (struct tdr_cmd_struct
*) ptr
;
654 tdr_cmd
->cmd_status
= 0;
655 tdr_cmd
->cmd_cmd
= CMD_TDR
| CMD_LAST
;
656 tdr_cmd
->cmd_link
= 0xffff;
659 p
->scb
->cbl_offset
= make16(tdr_cmd
);
661 p
->scb
->cmd
= CUC_START
; /* cmd.-unit start */
665 while (!(tdr_cmd
->cmd_status
& STAT_COMPL
)) {
666 if (jiffies
- s
> 30*HZ
/100) {
667 printk(KERN_WARNING
"%s: %d Problems while running the TDR.\n", dev
->name
, __LINE__
);
674 DELAY(2); /* wait for result */
675 result
= tdr_cmd
->status
;
677 p
->scb
->cmd
= p
->scb
->status
& STAT_MASK
;
678 elmc_id_attn586(); /* ack the interrupts */
680 if (result
& TDR_LNK_OK
) {
682 } else if (result
& TDR_XCVR_PRB
) {
683 printk(KERN_WARNING
"%s: TDR: Transceiver problem!\n", dev
->name
);
684 } else if (result
& TDR_ET_OPN
) {
685 printk(KERN_WARNING
"%s: TDR: No correct termination %d clocks away.\n", dev
->name
, result
& TDR_TIMEMASK
);
686 } else if (result
& TDR_ET_SRT
) {
687 if (result
& TDR_TIMEMASK
) /* time == 0 -> strange :-) */
688 printk(KERN_WARNING
"%s: TDR: Detected a short circuit %d clocks away.\n", dev
->name
, result
& TDR_TIMEMASK
);
690 printk(KERN_WARNING
"%s: TDR: Unknown status %04x\n", dev
->name
, result
);
696 p
->scb
->cmd
= p
->scb
->status
& STAT_MASK
;
700 * alloc nop/xmit-cmds
702 #if (NUM_XMIT_BUFFS == 1)
703 for (i
= 0; i
< 2; i
++) {
704 p
->nop_cmds
[i
] = (struct nop_cmd_struct
*) ptr
;
705 p
->nop_cmds
[i
]->cmd_cmd
= CMD_NOP
;
706 p
->nop_cmds
[i
]->cmd_status
= 0;
707 p
->nop_cmds
[i
]->cmd_link
= make16((p
->nop_cmds
[i
]));
708 ptr
= (char *) ptr
+ sizeof(struct nop_cmd_struct
);
710 p
->xmit_cmds
[0] = (struct transmit_cmd_struct
*) ptr
; /* transmit cmd/buff 0 */
711 ptr
= (char *) ptr
+ sizeof(struct transmit_cmd_struct
);
713 for (i
= 0; i
< NUM_XMIT_BUFFS
; i
++) {
714 p
->nop_cmds
[i
] = (struct nop_cmd_struct
*) ptr
;
715 p
->nop_cmds
[i
]->cmd_cmd
= CMD_NOP
;
716 p
->nop_cmds
[i
]->cmd_status
= 0;
717 p
->nop_cmds
[i
]->cmd_link
= make16((p
->nop_cmds
[i
]));
718 ptr
= (char *) ptr
+ sizeof(struct nop_cmd_struct
);
719 p
->xmit_cmds
[i
] = (struct transmit_cmd_struct
*) ptr
; /*transmit cmd/buff 0 */
720 ptr
= (char *) ptr
+ sizeof(struct transmit_cmd_struct
);
724 ptr
= alloc_rfa(dev
, (void *) ptr
); /* init receive-frame-area */
731 /* I don't understand this: do we really need memory after the init? */
732 int len
= ((char *) p
->iscp
- (char *) ptr
- 8) / 6;
734 printk(KERN_ERR
"%s: Ooooops, no memory for MC-Setup!\n", dev
->name
);
736 if (len
< num_addrs
) {
738 printk(KERN_WARNING
"%s: Sorry, can only apply %d MC-Address(es).\n",
739 dev
->name
, num_addrs
);
741 mc_cmd
= (struct mcsetup_cmd_struct
*) ptr
;
742 mc_cmd
->cmd_status
= 0;
743 mc_cmd
->cmd_cmd
= CMD_MCSETUP
| CMD_LAST
;
744 mc_cmd
->cmd_link
= 0xffff;
745 mc_cmd
->mc_cnt
= num_addrs
* 6;
746 for (i
= 0; i
< num_addrs
; i
++) {
747 memcpy((char *) mc_cmd
->mc_list
[i
], dmi
->dmi_addr
, 6);
750 p
->scb
->cbl_offset
= make16(mc_cmd
);
751 p
->scb
->cmd
= CUC_START
;
754 while (!(mc_cmd
->cmd_status
& STAT_COMPL
)) {
755 if (jiffies
- s
> 30*HZ
/100)
758 if (!(mc_cmd
->cmd_status
& STAT_COMPL
)) {
759 printk(KERN_WARNING
"%s: Can't apply multicast-address-list.\n", dev
->name
);
764 * alloc xmit-buffs / init xmit_cmds
766 for (i
= 0; i
< NUM_XMIT_BUFFS
; i
++) {
767 p
->xmit_cbuffs
[i
] = (char *) ptr
; /* char-buffs */
768 ptr
= (char *) ptr
+ XMIT_BUFF_SIZE
;
769 p
->xmit_buffs
[i
] = (struct tbd_struct
*) ptr
; /* TBD */
770 ptr
= (char *) ptr
+ sizeof(struct tbd_struct
);
771 if ((void *) ptr
> (void *) p
->iscp
) {
772 printk(KERN_ERR
"%s: not enough shared-mem for your configuration!\n", dev
->name
);
775 memset((char *) (p
->xmit_cmds
[i
]), 0, sizeof(struct transmit_cmd_struct
));
776 memset((char *) (p
->xmit_buffs
[i
]), 0, sizeof(struct tbd_struct
));
777 p
->xmit_cmds
[i
]->cmd_status
= STAT_COMPL
;
778 p
->xmit_cmds
[i
]->cmd_cmd
= CMD_XMIT
| CMD_INT
;
779 p
->xmit_cmds
[i
]->tbd_offset
= make16((p
->xmit_buffs
[i
]));
780 p
->xmit_buffs
[i
]->next
= 0xffff;
781 p
->xmit_buffs
[i
]->buffer
= make24((p
->xmit_cbuffs
[i
]));
786 #ifndef NO_NOPCOMMANDS
791 * 'start transmitter' (nop-loop)
793 #ifndef NO_NOPCOMMANDS
794 p
->scb
->cbl_offset
= make16(p
->nop_cmds
[0]);
795 p
->scb
->cmd
= CUC_START
;
799 p
->xmit_cmds
[0]->cmd_link
= 0xffff;
800 p
->xmit_cmds
[0]->cmd_cmd
= CMD_XMIT
| CMD_LAST
| CMD_INT
;
806 /******************************************************
807 * This is a helper routine for elmc_rnr_int() and init586().
808 * It sets up the Receive Frame Area (RFA).
811 static void *alloc_rfa(struct net_device
*dev
, void *ptr
)
813 volatile struct rfd_struct
*rfd
= (struct rfd_struct
*) ptr
;
814 volatile struct rbd_struct
*rbd
;
816 struct priv
*p
= (struct priv
*) dev
->priv
;
818 memset((char *) rfd
, 0, sizeof(struct rfd_struct
) * p
->num_recv_buffs
);
821 for (i
= 0; i
< p
->num_recv_buffs
; i
++) {
822 rfd
[i
].next
= make16(rfd
+ (i
+ 1) % p
->num_recv_buffs
);
824 rfd
[p
->num_recv_buffs
- 1].last
= RFD_SUSP
; /* RU suspend */
826 ptr
= (void *) (rfd
+ p
->num_recv_buffs
);
828 rbd
= (struct rbd_struct
*) ptr
;
829 ptr
= (void *) (rbd
+ p
->num_recv_buffs
);
831 /* clr descriptors */
832 memset((char *) rbd
, 0, sizeof(struct rbd_struct
) * p
->num_recv_buffs
);
834 for (i
= 0; i
< p
->num_recv_buffs
; i
++) {
835 rbd
[i
].next
= make16((rbd
+ (i
+ 1) % p
->num_recv_buffs
));
836 rbd
[i
].size
= RECV_BUFF_SIZE
;
837 rbd
[i
].buffer
= make24(ptr
);
838 ptr
= (char *) ptr
+ RECV_BUFF_SIZE
;
841 p
->rfd_top
= p
->rfd_first
;
842 p
->rfd_last
= p
->rfd_first
+ p
->num_recv_buffs
- 1;
844 p
->scb
->rfa_offset
= make16(p
->rfd_first
);
845 p
->rfd_first
->rbd_offset
= make16(rbd
);
851 /**************************************************
852 * Interrupt Handler ...
855 static void elmc_interrupt(int irq
, void *dev_id
, struct pt_regs
*reg_ptr
)
857 struct net_device
*dev
= (struct net_device
*) dev_id
;
862 printk(KERN_ERR
"elmc-interrupt: irq %d for unknown device.\n", (int) -(((struct pt_regs
*) reg_ptr
)->orig_eax
+ 2));
864 } else if (!netif_running(dev
)) {
865 /* The 3c523 has this habit of generating interrupts during the
866 reset. I'm not sure if the ni52 has this same problem, but it's
867 really annoying if we haven't finished initializing it. I was
868 hoping all the elmc_id_* commands would disable this, but I
869 might have missed a few. */
871 elmc_id_attn586(); /* ack inter. and disable any more */
873 } else if (!(ELMC_CTRL_INT
& inb(dev
->base_addr
+ ELMC_CTRL
))) {
874 /* wasn't this device */
877 /* reading ELMC_CTRL also clears the INT bit. */
879 p
= (struct priv
*) dev
->priv
;
881 while ((stat
= p
->scb
->status
& STAT_MASK
))
884 elmc_attn586(); /* ack inter. */
886 if (stat
& STAT_CX
) {
887 /* command with I-bit set complete */
890 if (stat
& STAT_FR
) {
891 /* received a frame */
894 #ifndef NO_NOPCOMMANDS
895 if (stat
& STAT_CNA
) {
896 /* CU went 'not ready' */
897 if (netif_running(dev
)) {
898 printk(KERN_WARNING
"%s: oops! CU has left active state. stat: %04x/%04x.\n", dev
->name
, (int) stat
, (int) p
->scb
->status
);
903 if (stat
& STAT_RNR
) {
904 /* RU went 'not ready' */
906 if (p
->scb
->status
& RU_SUSPEND
) {
907 /* special case: RU_SUSPEND */
910 p
->scb
->cmd
= RUC_RESUME
;
913 printk(KERN_WARNING
"%s: Receiver-Unit went 'NOT READY': %04x/%04x.\n", dev
->name
, (int) stat
, (int) p
->scb
->status
);
917 WAIT_4_SCB_CMD(); /* wait for ack. (elmc_xmt_int can be faster than ack!!) */
918 if (p
->scb
->cmd
) { /* timed out? */
924 /*******************************************************
928 static void elmc_rcv_int(struct net_device
*dev
)
931 unsigned short totlen
;
933 struct rbd_struct
*rbd
;
934 struct priv
*p
= (struct priv
*) dev
->priv
;
936 for (; (status
= p
->rfd_top
->status
) & STAT_COMPL
;) {
937 rbd
= (struct rbd_struct
*) make32(p
->rfd_top
->rbd_offset
);
939 if (status
& STAT_OK
) { /* frame received without error? */
940 if ((totlen
= rbd
->status
) & RBD_LAST
) { /* the first and the last buffer? */
941 totlen
&= RBD_MASK
; /* length of this frame */
943 skb
= (struct sk_buff
*) dev_alloc_skb(totlen
+ 2);
946 skb_reserve(skb
, 2); /* 16 byte alignment */
947 memcpy(skb_put(skb
, totlen
), (u8
*)phys_to_virt(p
->base
) + (unsigned long) rbd
->buffer
, totlen
);
948 skb
->protocol
= eth_type_trans(skb
, dev
);
950 p
->stats
.rx_packets
++;
951 p
->stats
.rx_bytes
+= totlen
;
953 p
->stats
.rx_dropped
++;
956 printk(KERN_WARNING
"%s: received oversized frame.\n", dev
->name
);
957 p
->stats
.rx_dropped
++;
959 } else { /* frame !(ok), only with 'save-bad-frames' */
960 printk(KERN_WARNING
"%s: oops! rfd-error-status: %04x\n", dev
->name
, status
);
961 p
->stats
.rx_errors
++;
963 p
->rfd_top
->status
= 0;
964 p
->rfd_top
->last
= RFD_SUSP
;
965 p
->rfd_last
->last
= 0; /* delete RU_SUSP */
966 p
->rfd_last
= p
->rfd_top
;
967 p
->rfd_top
= (struct rfd_struct
*) make32(p
->rfd_top
->next
); /* step to next RFD */
971 /**********************************************************
972 * handle 'Receiver went not ready'.
975 static void elmc_rnr_int(struct net_device
*dev
)
977 struct priv
*p
= (struct priv
*) dev
->priv
;
979 p
->stats
.rx_errors
++;
981 WAIT_4_SCB_CMD(); /* wait for the last cmd */
982 p
->scb
->cmd
= RUC_ABORT
; /* usually the RU is in the 'no resource'-state .. abort it now. */
984 WAIT_4_SCB_CMD(); /* wait for accept cmd. */
986 alloc_rfa(dev
, (char *) p
->rfd_first
);
987 startrecv586(dev
); /* restart RU */
989 printk(KERN_WARNING
"%s: Receive-Unit restarted. Status: %04x\n", dev
->name
, p
->scb
->status
);
993 /**********************************************************
994 * handle xmit - interrupt
997 static void elmc_xmt_int(struct net_device
*dev
)
1000 struct priv
*p
= (struct priv
*) dev
->priv
;
1002 status
= p
->xmit_cmds
[p
->xmit_last
]->cmd_status
;
1003 if (!(status
& STAT_COMPL
)) {
1004 printk(KERN_WARNING
"%s: strange .. xmit-int without a 'COMPLETE'\n", dev
->name
);
1006 if (status
& STAT_OK
) {
1007 p
->stats
.tx_packets
++;
1008 p
->stats
.collisions
+= (status
& TCMD_MAXCOLLMASK
);
1010 p
->stats
.tx_errors
++;
1011 if (status
& TCMD_LATECOLL
) {
1012 printk(KERN_WARNING
"%s: late collision detected.\n", dev
->name
);
1013 p
->stats
.collisions
++;
1014 } else if (status
& TCMD_NOCARRIER
) {
1015 p
->stats
.tx_carrier_errors
++;
1016 printk(KERN_WARNING
"%s: no carrier detected.\n", dev
->name
);
1017 } else if (status
& TCMD_LOSTCTS
) {
1018 printk(KERN_WARNING
"%s: loss of CTS detected.\n", dev
->name
);
1019 } else if (status
& TCMD_UNDERRUN
) {
1020 p
->stats
.tx_fifo_errors
++;
1021 printk(KERN_WARNING
"%s: DMA underrun detected.\n", dev
->name
);
1022 } else if (status
& TCMD_MAXCOLL
) {
1023 printk(KERN_WARNING
"%s: Max. collisions exceeded.\n", dev
->name
);
1024 p
->stats
.collisions
+= 16;
1028 #if (NUM_XMIT_BUFFS != 1)
1029 if ((++p
->xmit_last
) == NUM_XMIT_BUFFS
) {
1034 netif_wake_queue(dev
);
1037 /***********************************************************
1038 * (re)start the receiver
1041 static void startrecv586(struct net_device
*dev
)
1043 struct priv
*p
= (struct priv
*) dev
->priv
;
1045 p
->scb
->rfa_offset
= make16(p
->rfd_first
);
1046 p
->scb
->cmd
= RUC_START
;
1047 elmc_attn586(); /* start cmd. */
1048 WAIT_4_SCB_CMD(); /* wait for accept cmd. (no timeout!!) */
1051 /******************************************************
1055 static void elmc_timeout(struct net_device
*dev
)
1057 struct priv
*p
= (struct priv
*) dev
->priv
;
1058 /* COMMAND-UNIT active? */
1059 if (p
->scb
->status
& CU_ACTIVE
) {
1061 printk("%s: strange ... timeout with CU active?!?\n", dev
->name
);
1062 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
);
1064 p
->scb
->cmd
= CUC_ABORT
;
1067 p
->scb
->cbl_offset
= make16(p
->nop_cmds
[p
->nop_point
]);
1068 p
->scb
->cmd
= CUC_START
;
1071 netif_wake_queue(dev
);
1074 printk("%s: xmitter timed out, try to restart! stat: %04x\n", dev
->name
, p
->scb
->status
);
1075 printk("%s: command-stats: %04x %04x\n", dev
->name
, p
->xmit_cmds
[0]->cmd_status
, p
->xmit_cmds
[1]->cmd_status
);
1082 /******************************************************
1086 static int elmc_send_packet(struct sk_buff
*skb
, struct net_device
*dev
)
1089 #ifndef NO_NOPCOMMANDS
1092 struct priv
*p
= (struct priv
*) dev
->priv
;
1094 netif_stop_queue(dev
);
1096 memcpy((char *) p
->xmit_cbuffs
[p
->xmit_count
], (char *) (skb
->data
), skb
->len
);
1097 len
= (ETH_ZLEN
< skb
->len
) ? skb
->len
: ETH_ZLEN
;
1099 #if (NUM_XMIT_BUFFS == 1)
1100 #ifdef NO_NOPCOMMANDS
1101 p
->xmit_buffs
[0]->size
= TBD_LAST
| len
;
1102 for (i
= 0; i
< 16; i
++) {
1103 p
->scb
->cbl_offset
= make16(p
->xmit_cmds
[0]);
1104 p
->scb
->cmd
= CUC_START
;
1105 p
->xmit_cmds
[0]->cmd_status
= 0;
1107 dev
->trans_start
= jiffies
;
1112 if ((p
->scb
->status
& CU_ACTIVE
)) { /* test it, because CU sometimes doesn't start immediately */
1115 if (p
->xmit_cmds
[0]->cmd_status
) {
1119 printk(KERN_WARNING
"%s: Can't start transmit-command.\n", dev
->name
);
1123 next_nop
= (p
->nop_point
+ 1) & 0x1;
1124 p
->xmit_buffs
[0]->size
= TBD_LAST
| len
;
1126 p
->xmit_cmds
[0]->cmd_link
= p
->nop_cmds
[next_nop
]->cmd_link
1127 = make16((p
->nop_cmds
[next_nop
]));
1128 p
->xmit_cmds
[0]->cmd_status
= p
->nop_cmds
[next_nop
]->cmd_status
= 0;
1130 p
->nop_cmds
[p
->nop_point
]->cmd_link
= make16((p
->xmit_cmds
[0]));
1131 dev
->trans_start
= jiffies
;
1132 p
->nop_point
= next_nop
;
1136 p
->xmit_buffs
[p
->xmit_count
]->size
= TBD_LAST
| len
;
1137 if ((next_nop
= p
->xmit_count
+ 1) == NUM_XMIT_BUFFS
) {
1140 p
->xmit_cmds
[p
->xmit_count
]->cmd_status
= 0;
1141 p
->xmit_cmds
[p
->xmit_count
]->cmd_link
= p
->nop_cmds
[next_nop
]->cmd_link
1142 = make16((p
->nop_cmds
[next_nop
]));
1143 p
->nop_cmds
[next_nop
]->cmd_status
= 0;
1144 p
->nop_cmds
[p
->xmit_count
]->cmd_link
= make16((p
->xmit_cmds
[p
->xmit_count
]));
1145 dev
->trans_start
= jiffies
;
1146 p
->xmit_count
= next_nop
;
1147 if (p
->xmit_count
!= p
->xmit_last
)
1148 netif_wake_queue(dev
);
1154 /*******************************************
1155 * Someone wanna have the statistics
1158 static struct net_device_stats
*elmc_get_stats(struct net_device
*dev
)
1160 struct priv
*p
= (struct priv
*) dev
->priv
;
1161 unsigned short crc
, aln
, rsc
, ovrn
;
1163 crc
= p
->scb
->crc_errs
; /* get error-statistic from the ni82586 */
1164 p
->scb
->crc_errs
-= crc
;
1165 aln
= p
->scb
->aln_errs
;
1166 p
->scb
->aln_errs
-= aln
;
1167 rsc
= p
->scb
->rsc_errs
;
1168 p
->scb
->rsc_errs
-= rsc
;
1169 ovrn
= p
->scb
->ovrn_errs
;
1170 p
->scb
->ovrn_errs
-= ovrn
;
1172 p
->stats
.rx_crc_errors
+= crc
;
1173 p
->stats
.rx_fifo_errors
+= ovrn
;
1174 p
->stats
.rx_frame_errors
+= aln
;
1175 p
->stats
.rx_dropped
+= rsc
;
1180 /********************************************************
1184 #ifdef ELMC_MULTICAST
1185 static void set_multicast_list(struct net_device
*dev
)
1188 /* without a running interface, promiscuous doesn't work */
1199 /*************************************************************************/
1203 /* Increase if needed ;) */
1204 #define MAX_3C523_CARDS 4
1206 static struct net_device dev_elmc
[MAX_3C523_CARDS
];
1207 static int irq
[MAX_3C523_CARDS
];
1208 static int io
[MAX_3C523_CARDS
];
1209 MODULE_PARM(irq
, "1-" __MODULE_STRING(MAX_3C523_CARDS
) "i");
1210 MODULE_PARM(io
, "1-" __MODULE_STRING(MAX_3C523_CARDS
) "i");
1212 int init_module(void)
1214 int this_dev
,found
= 0;
1216 /* Loop until we either can't find any more cards, or we have MAX_3C523_CARDS */
1217 for(this_dev
=0; this_dev
<MAX_3C523_CARDS
; this_dev
++)
1219 struct net_device
*dev
= &dev_elmc
[this_dev
];
1220 dev
->irq
=irq
[this_dev
];
1221 dev
->base_addr
=io
[this_dev
];
1222 dev
->init
=elmc_probe
;
1223 if(register_netdev(dev
)!=0) {
1224 if(io
[this_dev
]==0) break;
1225 printk(KERN_WARNING
"3c523.c: No 3c523 card found at io=%#x\n",io
[this_dev
]);
1230 if(io
[0]==0) printk(KERN_NOTICE
"3c523.c: No 3c523 cards found\n");
1235 void cleanup_module(void)
1238 for(this_dev
=0; this_dev
<MAX_3C523_CARDS
; this_dev
++) {
1240 struct net_device
*dev
= &dev_elmc
[this_dev
];
1242 /* shutdown interrupts on the card */
1244 if (dev
->irq
!= 0) {
1245 /* this should be done by close, but if we failed to
1246 initialize properly something may have gotten hosed. */
1247 free_irq(dev
->irq
, dev
);
1250 if (dev
->base_addr
!= 0) {
1251 release_region(dev
->base_addr
, ELMC_IO_EXTENT
);
1256 unregister_netdev(dev
);
1258 mca_set_adapter_procfn(((struct priv
*) (dev
->priv
))->slot
,