Ok. I didn't make 2.4.0 in 2000. Tough. I tried, but we had some
[davej-history.git] / drivers / net / 3c523.c
blobbf17e006fda41279be918eeaa36339cc97bbfd73
1 /*
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.
18 sources:
19 ni52.c
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
36 Known Problems:
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
57 why.
59 Features:
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
63 parameters.
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
70 know of).
72 History:
73 Jan 1st, 1996
74 first public release
75 Feb 4th, 1996
76 update to 1.3.59, incorporated multicast diffs from ni52.c
77 Feb 15th, 1996
78 added shared irq support
79 Apr 1999
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>
100 #include <asm/io.h>
102 #include <linux/netdevice.h>
103 #include <linux/etherdevice.h>
104 #include <linux/skbuff.h>
105 #include <linux/init.h>
107 #include "3c523.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 = {
123 12, 7, 3, 9
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;
145 sizeof(nop_cmd) = 8;
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 */
157 #endif
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; \
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(); } } }
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);
184 #endif
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);
196 struct priv {
197 struct net_device_stats stats;
198 unsigned long base;
199 char *memtop;
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];
208 #else
209 volatile struct nop_cmd_struct *nop_cmds[NUM_XMIT_BUFFS];
210 #endif
211 volatile int nop_point, num_recv_buffs;
212 volatile char *xmit_cbuffs[NUM_XMIT_BUFFS];
213 volatile int xmit_count, xmit_last;
214 volatile int slot;
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 /**********************************************
261 * close device
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);
269 return 0;
272 /**********************************************
273 * open device
276 static int elmc_open(struct net_device *dev)
278 int ret;
280 elmc_id_attn586(); /* disable interrupts */
282 ret = request_irq(dev->irq, &elmc_interrupt, SA_SHIRQ | SA_SAMPLE_RANDOM,
283 dev->name, dev);
284 if (ret) {
285 printk(KERN_ERR "%s: couldn't get irq %d\n", dev->name, dev->irq);
286 elmc_id_reset586();
287 return ret;
289 alloc586(dev);
290 init586(dev);
291 startrecv586(dev);
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;
303 char *iscp_addrs[2];
304 int i = 0;
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);
320 p->iscp->busy = 1;
322 elmc_id_reset586();
324 /* reset586 does an implicit CA */
326 /* apparently, you sometimes have to kick the 82586 twice... */
327 elmc_id_attn586();
329 if (p->iscp->busy) { /* i82586 clears 'busy' after successful init */
330 return 0;
333 return 1;
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;
344 elmc_id_reset586();
345 DELAY(2);
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);
358 p->iscp->busy = 1;
359 elmc_id_reset586();
360 elmc_id_attn586();
362 DELAY(2);
364 if (p->iscp->busy) {
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)
374 int len = 0;
375 struct net_device *dev = (struct net_device *) d;
376 int i;
378 if (dev == NULL)
379 return len;
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,
387 dev->mem_end - 1);
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]);
395 buf[len++] = '\n';
396 buf[len] = 0;
398 return len;
399 } /* elmc_getinfo() */
401 /*****************************************************************/
403 int __init elmc_probe(struct net_device *dev)
405 static int slot = 0;
406 int base_addr = dev->base_addr;
407 int irq = dev->irq;
408 u_char status = 0;
409 u_char revision = 0;
410 int i = 0;
411 unsigned int size = 0;
413 SET_MODULE_OWNER(dev);
414 if (MCA_bus == 0) {
415 return -ENODEV;
417 /* search through the slots for the 3c523. */
418 slot = mca_find_adapter(ELMC_MCA_ID, 0);
419 while (slot != -1) {
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);
434 continue;
436 /* found what we're looking for... */
437 break;
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
466 properly. */
467 switch (dev->irq) {
468 case 3:
469 mca_write_pos(slot, 3, 0x04);
470 break;
471 case 7:
472 mca_write_pos(slot, 3, 0x02);
473 break;
474 case 9:
475 mca_write_pos(slot, 3, 0x08);
476 break;
477 case 12:
478 mca_write_pos(slot, 3, 0x01);
479 break;
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) {
486 return -ENOMEM;
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,
493 dev->base_addr);
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,
515 dev->mem_start);
516 release_region(dev->base_addr, ELMC_IO_EXTENT);
517 return -ENODEV;
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;
522 alloc586(dev);
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]);
541 printk("\n");
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;
551 #else
552 dev->set_multicast_list = NULL;
553 #endif
555 ether_setup(dev);
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 */
563 #endif
565 return 0;
568 /**********************************************
569 * init the chip (elmc-interrupt should be disabled?!)
570 * needs a correct 'allocated' memory
573 static int init586(struct net_device *dev)
575 void *ptr;
576 unsigned long s;
577 int i, result = 0;
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;
598 cfg_cmd->ifs = 0x60;
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 */
611 elmc_id_attn586();
613 s = jiffies; /* warning: only active with interrupts on !! */
614 while (!(cfg_cmd->cmd_status & STAT_COMPL)) {
615 if (jiffies - s > 30*HZ/100)
616 break;
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);
621 return 1;
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 */
637 elmc_id_attn586();
639 s = jiffies;
640 while (!(ias_cmd->cmd_status & STAT_COMPL)) {
641 if (jiffies - s > 30*HZ/100)
642 break;
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);
647 return 1;
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;
657 tdr_cmd->status = 0;
659 p->scb->cbl_offset = make16(tdr_cmd);
661 p->scb->cmd = CUC_START; /* cmd.-unit start */
662 elmc_attn586();
664 s = jiffies;
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__);
668 result = 1;
669 break;
673 if (!result) {
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) {
681 /* empty */
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);
689 } else {
690 printk(KERN_WARNING "%s: TDR: Unknown status %04x\n", dev->name, result);
694 * ack interrupts
696 p->scb->cmd = p->scb->status & STAT_MASK;
697 elmc_id_attn586();
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);
712 #else
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);
722 #endif
724 ptr = alloc_rfa(dev, (void *) ptr); /* init receive-frame-area */
727 * Multicast setup
730 if (dev->mc_count) {
731 /* I don't understand this: do we really need memory after the init? */
732 int len = ((char *) p->iscp - (char *) ptr - 8) / 6;
733 if (len <= 0) {
734 printk(KERN_ERR "%s: Ooooops, no memory for MC-Setup!\n", dev->name);
735 } else {
736 if (len < num_addrs) {
737 num_addrs = len;
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);
748 dmi = dmi->next;
750 p->scb->cbl_offset = make16(mc_cmd);
751 p->scb->cmd = CUC_START;
752 elmc_id_attn586();
753 s = jiffies;
754 while (!(mc_cmd->cmd_status & STAT_COMPL)) {
755 if (jiffies - s > 30*HZ/100)
756 break;
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);
773 return 1;
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]));
784 p->xmit_count = 0;
785 p->xmit_last = 0;
786 #ifndef NO_NOPCOMMANDS
787 p->nop_point = 0;
788 #endif
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;
796 elmc_id_attn586();
797 WAIT_4_SCB_CMD();
798 #else
799 p->xmit_cmds[0]->cmd_link = 0xffff;
800 p->xmit_cmds[0]->cmd_cmd = CMD_XMIT | CMD_LAST | CMD_INT;
801 #endif
803 return 0;
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;
815 int i;
816 struct priv *p = (struct priv *) dev->priv;
818 memset((char *) rfd, 0, sizeof(struct rfd_struct) * p->num_recv_buffs);
819 p->rfd_first = rfd;
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);
847 return ptr;
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;
858 unsigned short stat;
859 struct priv *p;
861 if (dev == NULL) {
862 printk(KERN_ERR "elmc-interrupt: irq %d for unknown device.\n", (int) -(((struct pt_regs *) reg_ptr)->orig_eax + 2));
863 return;
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 */
872 return;
873 } else if (!(ELMC_CTRL_INT & inb(dev->base_addr + ELMC_CTRL))) {
874 /* wasn't this device */
875 return;
877 /* reading ELMC_CTRL also clears the INT bit. */
879 p = (struct priv *) dev->priv;
881 while ((stat = p->scb->status & STAT_MASK))
883 p->scb->cmd = stat;
884 elmc_attn586(); /* ack inter. */
886 if (stat & STAT_CX) {
887 /* command with I-bit set complete */
888 elmc_xmt_int(dev);
890 if (stat & STAT_FR) {
891 /* received a frame */
892 elmc_rcv_int(dev);
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);
901 #endif
903 if (stat & STAT_RNR) {
904 /* RU went 'not ready' */
906 if (p->scb->status & RU_SUSPEND) {
907 /* special case: RU_SUSPEND */
909 WAIT_4_SCB_CMD();
910 p->scb->cmd = RUC_RESUME;
911 elmc_attn586();
912 } else {
913 printk(KERN_WARNING "%s: Receiver-Unit went 'NOT READY': %04x/%04x.\n", dev->name, (int) stat, (int) p->scb->status);
914 elmc_rnr_int(dev);
917 WAIT_4_SCB_CMD(); /* wait for ack. (elmc_xmt_int can be faster than ack!!) */
918 if (p->scb->cmd) { /* timed out? */
919 break;
924 /*******************************************************
925 * receive-interrupt
928 static void elmc_rcv_int(struct net_device *dev)
930 int status;
931 unsigned short totlen;
932 struct sk_buff *skb;
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 */
942 rbd->status = 0;
943 skb = (struct sk_buff *) dev_alloc_skb(totlen + 2);
944 if (skb != NULL) {
945 skb->dev = dev;
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);
949 netif_rx(skb);
950 p->stats.rx_packets++;
951 p->stats.rx_bytes += totlen;
952 } else {
953 p->stats.rx_dropped++;
955 } else {
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. */
983 elmc_attn586();
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)
999 int status;
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);
1009 } else {
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) {
1030 p->xmit_last = 0;
1032 #endif
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 /******************************************************
1052 * timeout
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) {
1060 #ifdef DEBUG
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);
1063 #endif
1064 p->scb->cmd = CUC_ABORT;
1065 elmc_attn586();
1066 WAIT_4_SCB_CMD();
1067 p->scb->cbl_offset = make16(p->nop_cmds[p->nop_point]);
1068 p->scb->cmd = CUC_START;
1069 elmc_attn586();
1070 WAIT_4_SCB_CMD();
1071 netif_wake_queue(dev);
1072 } else {
1073 #ifdef DEBUG
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);
1076 #endif
1077 elmc_close(dev);
1078 elmc_open(dev);
1082 /******************************************************
1083 * send frame
1086 static int elmc_send_packet(struct sk_buff *skb, struct net_device *dev)
1088 int len;
1089 #ifndef NO_NOPCOMMANDS
1090 int next_nop;
1091 #endif
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;
1106 elmc_attn586();
1107 dev->trans_start = jiffies;
1108 if (!i) {
1109 dev_kfree_skb(skb);
1111 WAIT_4_SCB_CMD();
1112 if ((p->scb->status & CU_ACTIVE)) { /* test it, because CU sometimes doesn't start immediately */
1113 break;
1115 if (p->xmit_cmds[0]->cmd_status) {
1116 break;
1118 if (i == 15) {
1119 printk(KERN_WARNING "%s: Can't start transmit-command.\n", dev->name);
1122 #else
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;
1133 dev_kfree_skb(skb);
1134 #endif
1135 #else
1136 p->xmit_buffs[p->xmit_count]->size = TBD_LAST | len;
1137 if ((next_nop = p->xmit_count + 1) == NUM_XMIT_BUFFS) {
1138 next_nop = 0;
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);
1149 dev_kfree_skb(skb);
1150 #endif
1151 return 0;
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;
1177 return &p->stats;
1180 /********************************************************
1181 * Set MC list ..
1184 #ifdef ELMC_MULTICAST
1185 static void set_multicast_list(struct net_device *dev)
1187 if (!dev->start) {
1188 /* without a running interface, promiscuous doesn't work */
1189 return;
1191 dev->start = 0;
1192 alloc586(dev);
1193 init586(dev);
1194 startrecv586(dev);
1195 dev->start = 1;
1197 #endif
1199 /*************************************************************************/
1201 #ifdef MODULE
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]);
1226 } else found++;
1229 if(found==0) {
1230 if(io[0]==0) printk(KERN_NOTICE "3c523.c: No 3c523 cards found\n");
1231 return -ENXIO;
1232 } else return 0;
1235 void cleanup_module(void)
1237 int this_dev;
1238 for(this_dev=0; this_dev<MAX_3C523_CARDS; this_dev++) {
1240 struct net_device *dev = &dev_elmc[this_dev];
1241 if(dev->priv) {
1242 /* shutdown interrupts on the card */
1243 elmc_id_reset586();
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);
1248 dev->irq = 0;
1250 if (dev->base_addr != 0) {
1251 release_region(dev->base_addr, ELMC_IO_EXTENT);
1252 dev->base_addr = 0;
1254 irq[this_dev] = 0;
1255 io[this_dev] = 0;
1256 unregister_netdev(dev);
1258 mca_set_adapter_procfn(((struct priv *) (dev->priv))->slot,
1259 NULL, NULL);
1261 kfree(dev->priv);
1262 dev->priv = NULL;
1267 #endif /* MODULE */