|
|
1.1 root 1: /* $Id: eexpress.c,v 1.1 1999/04/26 05:52:09 tb Exp $
2: *
3: * Intel EtherExpress device driver for Linux
4: *
5: * Original version written 1993 by Donald Becker
6: * Modularized by Pauline Middelink <[email protected]>
7: * Changed to support io= irq= by Alan Cox <[email protected]>
8: * Reworked 1995 by John Sullivan <[email protected]>
9: * More fixes by Philip Blundell <[email protected]>
10: * Added the Compaq LTE Alan Cox <[email protected]>
11: *
12: * Note - this driver is experimental still - it has problems on faster
13: * machines. Someone needs to sit down and go through it line by line with
14: * a databook...
15: */
16:
17: /*
18: * The original EtherExpress driver was just about usable, but
19: * suffered from a long startup delay, a hard limit of 16k memory
20: * usage on the card (EtherExpress 16s have either 32k or 64k),
21: * and random locks under load. The last was particularly annoying
22: * and made running eXceed/W preferable to Linux/XFree. After hacking
23: * through the driver for a couple of days, I had fixed most of the
24: * card handling errors, at the expense of turning the code into
25: * a complete jungle, but still hadn't tracked down the lock-ups.
26: * I had hoped these would be an IP bug, but failed to reproduce them
27: * under other drivers, so decided to start from scratch and rewrite
28: * the driver cleanly. And here it is.
29: *
30: * It's still not quite there, but self-corrects a lot more problems.
31: * the 'CU wedged, resetting...' message shouldn't happen at all, but
32: * at least we recover. It still locks occasionally, any ideas welcome.
33: *
34: * The original startup delay experienced by some people was due to the
35: * first ARP request for the address of the default router getting lost.
36: * (mostly the reply we were getting back was arriving before our
37: * hardware address was set up, or before the configuration sequence
38: * had told the card NOT to strip of the frame header). If you a long
39: * startup delay, you may have lost this ARP request/reply, although
40: * the original cause has been fixed. However, it is more likely that
41: * you've just locked under this version.
42: *
43: * The main changes are in the 586 initialization procedure (which was
44: * just broken before - the EExp is a strange beasty and needs careful
45: * handling) the receive buffer handling (we now use a non-terminating
46: * circular list of buffers, which stops the card giving us out-of-
47: * resources errors), and the transmit code. The driver is also more
48: * structured, and I have tried to keep the kernel interface separate
49: * from the hardware interface (although some routines naturally want
50: * to do both).
51: *
52: * John Sullivan
53: *
54: * 18/5/95:
55: *
56: * The lock-ups seem to happen when you access card memory after a 586
57: * reset. This happens only 1 in 12 resets, on a random basis, and
58: * completely locks the machine. As far as I can see there is no
59: * workaround possible - the only thing to be done is make sure we
60: * never reset the card *after* booting the kernel - once at probe time
61: * must be sufficient, and we'll just have to put up with that failing
62: * occasionally (or buy a new NIC). By the way, this looks like a
63: * definite card bug, since Intel's own driver for DOS does exactly the
64: * same.
65: *
66: * This bug makes switching in and out of promiscuous mode a risky
67: * business, since we must do a 586 reset each time.
68: */
69:
70: /*
71: * Sources:
72: *
73: * The original eexpress.c by Donald Becker
74: * Sources: the Crynwr EtherExpress driver source.
75: * the Intel Microcommunications Databook Vol.1 1990
76: *
77: * wavelan.c and i82586.h
78: * This was invaluable for the complete '586 configuration details
79: * and command format.
80: *
81: * The Crynwr sources (again)
82: * Not as useful as the Wavelan driver, but then I had eexpress.c to
83: * go off.
84: *
85: * The Intel EtherExpress 16 ethernet card
86: * Provided the only reason I want to see a working etherexpress driver.
87: * A lot of fixes came from just observing how the card (mis)behaves when
88: * you prod it.
89: *
90: */
91:
92: static char version[] =
93: "eexpress.c: v0.10 04-May-95 John Sullivan <[email protected]>\n"
94: " v0.14 19-May-96 Philip Blundell <[email protected]>\n"
95: " v0.15 04-Aug-98 Alan Cox <[email protected]>\n";
96:
97: #include <linux/module.h>
98:
99: #include <linux/kernel.h>
100: #include <linux/sched.h>
101: #include <linux/types.h>
102: #include <linux/fcntl.h>
103: #include <linux/interrupt.h>
104: #include <linux/ptrace.h>
105: #include <linux/ioport.h>
106: #include <linux/string.h>
107: #include <linux/in.h>
108: #include <asm/system.h>
109: #include <asm/bitops.h>
110: #include <asm/io.h>
111: #include <asm/dma.h>
112: #include <linux/delay.h>
113: #include <linux/errno.h>
114:
115: #include <linux/netdevice.h>
116: #include <linux/etherdevice.h>
117: #include <linux/skbuff.h>
118: #include <linux/malloc.h>
119:
120: /*
121: * Not actually used yet - may be implemented when the driver has
122: * been debugged!
123: *
124: * Debug Level Driver Status
125: * 0 Final release
126: * 1 Beta test
127: * 2
128: * 3
129: * 4 Report timeouts & 586 errors (normal debug level)
130: * 5 Report all major events
131: * 6 Dump sent/received packet contents
132: * 7 Report function entry/exit
133: */
134:
135: #ifndef NET_DEBUG
136: #define NET_DEBUG 4
137: #endif
138: static unsigned int net_debug = NET_DEBUG;
139:
140: #undef F_DEB
141:
142: #include "eth82586.h"
143:
144: #define PRIV(x) ((struct net_local *)(x)->priv)
145: #define EEXP_IO_EXTENT 16
146:
147: /*
148: * Private data declarations
149: */
150:
151: struct net_local
152: {
153: struct enet_statistics stats;
154: unsigned long init_time; /* jiffies when eexp_hw_init586 called */
155: unsigned short rx_first; /* first rx buf, same as RX_BUF_START */
156: unsigned short rx_last; /* last rx buf */
157: unsigned short tx_head; /* next free tx buf */
158: unsigned short tx_reap; /* first in-use tx buf */
159: unsigned short tx_tail; /* previous tx buf to tx_head */
160: unsigned short tx_link; /* last known-executing tx buf */
161: unsigned short last_tx_restart; /* set to tx_link when we restart the CU */
162: unsigned char started;
163: unsigned char promisc;
164: unsigned short rx_buf_start;
165: unsigned short rx_buf_end;
166: unsigned short num_tx_bufs;
167: unsigned short num_rx_bufs;
168: };
169:
170: unsigned short start_code[] = {
171: 0x0000, /* SCP: set bus to 16 bits */
172: 0x0000,0x0000, /* junk */
173: 0x0000,0x0000, /* address of ISCP (lo,hi) */
174:
175: 0x0001, /* ISCP: busy - cleared after reset */
176: 0x0008,0x0000,0x0000, /* offset,address (lo,hi) of SCB */
177:
178: 0x0000,0x0000, /* SCB: status, commands */
179: 0x0000,0x0000, /* links to first command block, first receive descriptor */
180: 0x0000,0x0000, /* CRC error, alignment error counts */
181: 0x0000,0x0000, /* out of resources, overrun error counts */
182:
183: 0x0000,0x0000, /* pad */
184: 0x0000,0x0000,
185:
186: 0x0000,Cmd_Config, /* startup configure sequence, at 0x0020 */
187: 0x0032, /* link to next command */
188: 0x080c, /* 12 bytes follow : fifo threshold=8 */
189: 0x2e40, /* don't rx bad frames : SRDY/ARDY => ext. sync. : preamble len=8
190: * take addresses from data buffers : 6 bytes/address */
191: 0x6000, /* default backoff method & priority : interframe spacing = 0x60 */
192: 0xf200, /* slot time=0x200 : max collision retry = 0xf */
193: 0x0000, /* no HDLC : normal CRC : enable broadcast : disable promiscuous/multicast modes */
194: 0x003c, /* minimum frame length = 60 octets) */
195:
196: 0x0000,Cmd_INT|Cmd_SetAddr,
197: 0x003e, /* link to next command */
198: 0x0000,0x0000,0x0000, /* hardware address placed here, 0x0038 */
199: 0x0000,Cmd_END|Cmd_Nop, /* end of configure sequence */
200: 0x003e,
201:
202: 0x0000
203:
204: };
205:
206: #define CONF_LINK 0x0020
207: #define CONF_HW_ADDR 0x0038
208:
209: /* maps irq number to EtherExpress magic value */
210: static char irqrmap[] = { 0,0,1,2,3,4,0,0,0,1,5,6,0,0,0,0 };
211:
212: /*
213: * Prototypes for Linux interface
214: */
215:
216: extern int express_probe(struct device *dev);
217: static int eexp_open (struct device *dev);
218: static int eexp_close(struct device *dev);
219: static struct enet_statistics *eexp_stats(struct device *dev);
220: static int eexp_xmit (struct sk_buff *buf, struct device *dev);
221:
222: static void eexp_irq (int irq, void *dev_addr, struct pt_regs *regs);
223: static void eexp_set_multicast(struct device *dev);
224:
225: /*
226: * Prototypes for hardware access functions
227: */
228:
229: static void eexp_hw_rx (struct device *dev);
230: static void eexp_hw_tx (struct device *dev, unsigned short *buf, unsigned short len);
231: static int eexp_hw_probe (struct device *dev,unsigned short ioaddr);
232: static unsigned short eexp_hw_readeeprom(unsigned short ioaddr, unsigned char location);
233:
234: static unsigned short eexp_hw_lasttxstat(struct device *dev);
235: static void eexp_hw_txrestart (struct device *dev);
236:
237: static void eexp_hw_txinit (struct device *dev);
238: static void eexp_hw_rxinit (struct device *dev);
239:
240: static void eexp_hw_init586 (struct device *dev);
241: static void eexp_hw_ASICrst (struct device *dev);
242:
243: /*
244: * Linux interface
245: */
246:
247: /*
248: * checks for presence of EtherExpress card
249: */
250:
251: int express_probe(struct device *dev)
252: {
253: unsigned short *port,ports[] = { 0x0300,0x0270,0x0320,0x0340,0 };
254: unsigned short ioaddr = dev->base_addr;
255:
256: if (ioaddr&0xfe00)
257: return eexp_hw_probe(dev,ioaddr);
258: else if (ioaddr)
259: return ENXIO;
260:
261: for ( port=&ports[0] ; *port ; port++ )
262: {
263: unsigned short sum = 0;
264: int i;
265: for ( i=0 ; i<4 ; i++ )
266: {
267: unsigned short t;
268: t = inb(*port + ID_PORT);
269: sum |= (t>>4) << ((t & 0x03)<<2);
270: }
271: if (sum==0xbaba && !eexp_hw_probe(dev,*port))
272: return 0;
273: }
274: return ENODEV;
275: }
276:
277: /*
278: * open and initialize the adapter, ready for use
279: */
280:
281: static int eexp_open(struct device *dev)
282: {
283: int irq = dev->irq;
284: unsigned short ioaddr = dev->base_addr;
285:
286: #if NET_DEBUG > 6
287: printk(KERN_DEBUG "%s: eexp_open()\n", dev->name);
288: #endif
289:
290: if (!irq || !irqrmap[irq])
291: return -ENXIO;
292:
293: if (irq2dev_map[irq] ||
294: /* more consistent, surely? */
295: ((irq2dev_map[irq]=dev),0) ||
296: request_irq(irq,&eexp_irq,0,"eexpress",NULL))
297: return -EAGAIN;
298:
299: request_region(ioaddr, EEXP_IO_EXTENT, "eexpress");
300: dev->tbusy = 0;
301: dev->interrupt = 0;
302: eexp_hw_init586(dev);
303: dev->start = 1;
304: MOD_INC_USE_COUNT;
305: #if NET_DEBUG > 6
306: printk(KERN_DEBUG "%s: leaving eexp_open()\n", dev->name);
307: #endif
308: return 0;
309: }
310:
311: /*
312: * close and disable the interface, leaving
313: * the 586 in reset
314: */
315: static int eexp_close(struct device *dev)
316: {
317: unsigned short ioaddr = dev->base_addr;
318: int irq = dev->irq;
319:
320: dev->tbusy = 1;
321: dev->start = 0;
322:
323: outb(SIRQ_dis|irqrmap[irq],ioaddr+SET_IRQ);
324: PRIV(dev)->started = 0;
325: outw(SCB_CUsuspend|SCB_RUsuspend,ioaddr+SCB_CMD);
326: outb(0,ioaddr+SIGNAL_CA);
327: free_irq(irq,NULL);
328: irq2dev_map[irq] = NULL;
329: outb(i586_RST,ioaddr+EEPROM_Ctrl);
330: release_region(ioaddr,16);
331: MOD_DEC_USE_COUNT;
332: return 0;
333: }
334:
335: /*
336: * Return interface stats
337: */
338:
339: static struct enet_statistics *eexp_stats(struct device *dev)
340: {
341: struct net_local *lp = (struct net_local *)dev->priv;
342:
343: /*
344: * Hmmm, this looks a little too easy... The card maintains
345: * some stats in the SCB, and I'm not convinced we're
346: * incrementing the most sensible statistics when the card
347: * returns an error (esp. slow DMA, out-of-resources)
348: */
349: return &lp->stats;
350: }
351:
352: /*
353: * Called to transmit a packet, or to allow us to right ourselves
354: * if the kernel thinks we've died.
355: */
356:
357: static int eexp_xmit(struct sk_buff *buf, struct device *dev)
358: {
359: struct net_local *lp = (struct net_local *)dev->priv;
360: unsigned short ioaddr = dev->base_addr;
361:
362: #if NET_DEBUG > 6
363: printk(KERN_DEBUG "%s: eexp_xmit()\n", dev->name);
364: #endif
365:
366: outb(SIRQ_dis|irqrmap[dev->irq],ioaddr+SET_IRQ);
367: if (dev->tbusy)
368: {
369: /* This will happen, but hopefully not as often as when
370: * tbusy==0. If it happens too much, we probably ought
371: * to think about unwedging ourselves...
372: */
373: if (test_bit(0,(void *)&PRIV(dev)->started))
374: {
375: if ((jiffies - dev->trans_start)>5)
376: {
377: if (lp->tx_link==lp->last_tx_restart)
378: {
379: unsigned short boguscount=200,rsst;
380: printk(KERN_WARNING "%s: Retransmit timed out, status %04x, resetting...\n",
381: dev->name,inw(ioaddr+SCB_STATUS));
382: eexp_hw_txinit(dev);
383: lp->last_tx_restart = 0;
384: outw(lp->tx_link,ioaddr+SCB_CBL);
385: outw(0,ioaddr+SCB_STATUS);
386: outw(SCB_CUstart,ioaddr+SCB_CMD);
387: outb(0,ioaddr+SIGNAL_CA);
388: while (!SCB_complete(rsst=inw(ioaddr+SCB_STATUS)))
389: {
390: if (!--boguscount)
391: {
392: boguscount=200;
393: printk(KERN_WARNING "%s: Reset timed out status %04x, retrying...\n",
394: dev->name,rsst);
395: outw(lp->tx_link,ioaddr+SCB_CBL);
396: outw(0,ioaddr+SCB_STATUS);
397: outw(SCB_CUstart,ioaddr+SCB_CMD);
398: outb(0,ioaddr+SIGNAL_CA);
399: }
400: }
401: dev->tbusy = 0;
402: mark_bh(NET_BH);
403: }
404: else
405: {
406: unsigned short status = inw(ioaddr+SCB_STATUS);
407: if (SCB_CUdead(status))
408: {
409: unsigned short txstatus = eexp_hw_lasttxstat(dev);
410: printk(KERN_WARNING "%s: Transmit timed out, CU not active status %04x %04x, restarting...\n",
411: dev->name, status, txstatus);
412: eexp_hw_txrestart(dev);
413: }
414: else
415: {
416: unsigned short txstatus = eexp_hw_lasttxstat(dev);
417: if (dev->tbusy && !txstatus)
418: {
419: printk(KERN_WARNING "%s: CU wedged, status %04x %04x, resetting...\n",
420: dev->name,status,txstatus);
421: eexp_hw_init586(dev);
422: dev->tbusy = 0;
423: mark_bh(NET_BH);
424: }
425: }
426: }
427: }
428: }
429: else
430: {
431: if ((jiffies-lp->init_time)>10)
432: {
433: unsigned short status = inw(ioaddr+SCB_STATUS);
434: printk(KERN_WARNING "%s: i82586 startup timed out, status %04x, resetting...\n",
435: dev->name, status);
436: eexp_hw_init586(dev);
437: dev->tbusy = 0;
438: mark_bh(NET_BH);
439: }
440: }
441: }
442:
443: if (buf==NULL)
444: {
445: unsigned short status = inw(ioaddr+SCB_STATUS);
446: unsigned short txstatus = eexp_hw_lasttxstat(dev);
447: if (SCB_CUdead(status))
448: {
449: printk(KERN_WARNING "%s: CU has died! status %04x %04x, attempting to restart...\n",
450: dev->name, status, txstatus);
451: lp->stats.tx_errors++;
452: eexp_hw_txrestart(dev);
453: }
454: dev_tint(dev);
455: outb(SIRQ_en|irqrmap[dev->irq],ioaddr+SET_IRQ);
456: dev_kfree_skb(buf, FREE_WRITE);
457: return 0;
458: }
459:
460: if (set_bit(0,(void *)&dev->tbusy))
461: {
462: lp->stats.tx_dropped++;
463: }
464: else
465: {
466: unsigned short length = (ETH_ZLEN < buf->len) ? buf->len : ETH_ZLEN;
467: unsigned short *data = (unsigned short *)buf->data;
468:
469: outb(SIRQ_dis|irqrmap[dev->irq],ioaddr+SET_IRQ);
470: eexp_hw_tx(dev,data,length);
471: outb(SIRQ_en|irqrmap[dev->irq],ioaddr+SET_IRQ);
472: }
473: dev_kfree_skb(buf, FREE_WRITE);
474: outb(SIRQ_en|irqrmap[dev->irq],ioaddr+SET_IRQ);
475: return 0;
476: }
477:
478: /*
479: * Handle an EtherExpress interrupt
480: * If we've finished initializing, start the RU and CU up.
481: * If we've already started, reap tx buffers, handle any received packets,
482: * check to make sure we've not become wedged.
483: */
484:
485: static void eexp_irq(int irq, void *dev_info, struct pt_regs *regs)
486: {
487: struct device *dev = irq2dev_map[irq];
488: struct net_local *lp;
489: unsigned short ioaddr,status,ack_cmd;
490: unsigned short old_rp,old_wp;
491:
492: if (dev==NULL)
493: {
494: printk(KERN_WARNING "net_interrupt(): irq %d for unknown device caught by EExpress\n",irq);
495: return;
496: }
497:
498: #if NET_DEBUG > 6
499: printk(KERN_DEBUG "%s: interrupt\n", dev->name);
500: #endif
501:
502: dev->interrupt = 1; /* should this be reset on exit? */
503:
504: lp = (struct net_local *)dev->priv;
505: ioaddr = dev->base_addr;
506:
507: outb(SIRQ_dis|irqrmap[irq],ioaddr+SET_IRQ);
508: old_rp = inw(ioaddr+READ_PTR);
509: old_wp = inw(ioaddr+WRITE_PTR);
510: status = inw(ioaddr+SCB_STATUS);
511: ack_cmd = SCB_ack(status);
512:
513: if (PRIV(dev)->started==0 && SCB_complete(status))
514: {
515: #if NET_DEBUG > 4
516: printk(KERN_DEBUG "%s: SCBcomplete event received\n", dev->name);
517: #endif
518: while (SCB_CUstat(status)==2)
519: status = inw_p(ioaddr+SCB_STATUS);
520: #if NET_DEBUG > 4
521: printk(KERN_DEBUG "%s: CU went non-active (status = %08x)\n", dev->name, status);
522: #endif
523: PRIV(dev)->started=1;
524: outw_p(lp->tx_link,ioaddr+SCB_CBL);
525: outw_p(PRIV(dev)->rx_buf_start,ioaddr+SCB_RFA);
526: ack_cmd |= SCB_CUstart | SCB_RUstart;
527: }
528: else if (PRIV(dev)->started)
529: {
530: unsigned short txstatus;
531: txstatus = eexp_hw_lasttxstat(dev);
532: }
533:
534: if (SCB_rxdframe(status))
535: {
536: eexp_hw_rx(dev);
537: }
538:
539: if ((PRIV(dev)->started&2)!=0 && SCB_RUstat(status)!=4)
540: {
541: printk(KERN_WARNING "%s: RU stopped status %04x, restarting...\n",
542: dev->name,status);
543: lp->stats.rx_errors++;
544: eexp_hw_rxinit(dev);
545: outw(PRIV(dev)->rx_buf_start,ioaddr+SCB_RFA);
546: ack_cmd |= SCB_RUstart;
547: }
548: else if (PRIV(dev)->started==1 && SCB_RUstat(status)==4)
549: PRIV(dev)->started|=2;
550:
551: outw(ack_cmd,ioaddr+SCB_CMD);
552: outb(0,ioaddr+SIGNAL_CA);
553: outw(old_rp,ioaddr+READ_PTR);
554: outw(old_wp,ioaddr+WRITE_PTR);
555: outb(SIRQ_en|irqrmap[irq],ioaddr+SET_IRQ);
556: dev->interrupt = 0;
557: #if NET_DEBUG > 6
558: printk(KERN_DEBUG "%s: leaving eexp_irq()\n", dev->name);
559: #endif
560: return;
561: }
562:
563: /*
564: * Hardware access functions
565: */
566:
567: /*
568: * Check all the receive buffers, and hand any received packets
569: * to the upper levels. Basic sanity check on each frame
570: * descriptor
571: */
572:
573: static void eexp_hw_rx(struct device *dev)
574: {
575: struct net_local *lp = (struct net_local *)dev->priv;
576: unsigned short ioaddr = dev->base_addr;
577: unsigned short old_wp = inw(ioaddr+WRITE_PTR);
578: unsigned short old_rp = inw(ioaddr+READ_PTR);
579: unsigned short rx_block = lp->rx_first;
580: unsigned short boguscount = lp->num_rx_bufs;
581:
582: #if NET_DEBUG > 6
583: printk(KERN_DEBUG "%s: eexp_hw_rx()\n", dev->name);
584: #endif
585:
586: while (outw(rx_block,ioaddr+READ_PTR),boguscount--)
587: {
588: unsigned short status = inw(ioaddr);
589: unsigned short rfd_cmd = inw(ioaddr);
590: unsigned short rx_next = inw(ioaddr);
591: unsigned short pbuf = inw(ioaddr);
592: unsigned short pkt_len;
593:
594: if (FD_Done(status))
595: {
596: outw(pbuf,ioaddr+READ_PTR);
597: pkt_len = inw(ioaddr);
598:
599: if (rfd_cmd!=0x0000 || pbuf!=rx_block+0x16
600: || (pkt_len & 0xc000)!=0xc000)
601: {
602: printk(KERN_WARNING "%s: Rx frame at %04x corrupted, status %04x, cmd %04x, "
603: "next %04x, pbuf %04x, len %04x\n",dev->name,rx_block,
604: status,rfd_cmd,rx_next,pbuf,pkt_len);
605: boguscount++;
606: continue;
607: }
608: else if (!FD_OK(status))
609: {
610: lp->stats.rx_errors++;
611: if (FD_CRC(status))
612: lp->stats.rx_crc_errors++;
613: if (FD_Align(status))
614: lp->stats.rx_frame_errors++;
615: if (FD_Resrc(status))
616: lp->stats.rx_fifo_errors++;
617: if (FD_DMA(status))
618: lp->stats.rx_over_errors++;
619: if (FD_Short(status))
620: lp->stats.rx_length_errors++;
621: }
622: else
623: {
624: struct sk_buff *skb;
625: pkt_len &= 0x3fff;
626: skb = dev_alloc_skb(pkt_len+16);
627: if (skb == NULL)
628: {
629: printk(KERN_WARNING "%s: Memory squeeze, dropping packet\n",dev->name);
630: lp->stats.rx_dropped++;
631: break;
632: }
633: skb->dev = dev;
634: skb_reserve(skb, 2);
635: outw(pbuf+10,ioaddr+READ_PTR);
636: insw(ioaddr,skb_put(skb,pkt_len),(pkt_len+1)>>1);
637: skb->protocol = eth_type_trans(skb,dev);
638: netif_rx(skb);
639: lp->stats.rx_packets++;
640: }
641: outw(rx_block,ioaddr+WRITE_PTR);
642: outw(0x0000,ioaddr);
643: outw(0x0000,ioaddr);
644: }
645: rx_block = rx_next;
646: }
647: outw(old_rp,ioaddr+READ_PTR);
648: outw(old_wp,ioaddr+WRITE_PTR);
649: }
650:
651: /*
652: * Hand a packet to the card for transmission
653: * If we get here, we MUST have already checked
654: * to make sure there is room in the transmit
655: * buffer region
656: */
657:
658: static void eexp_hw_tx(struct device *dev, unsigned short *buf, unsigned short len)
659: {
660: struct net_local *lp = (struct net_local *)dev->priv;
661: unsigned short ioaddr = dev->base_addr;
662: unsigned short old_wp = inw(ioaddr+WRITE_PTR);
663:
664: outw(lp->tx_head,ioaddr+WRITE_PTR);
665: outw(0x0000,ioaddr);
666: outw(Cmd_INT|Cmd_Xmit,ioaddr);
667: outw(lp->tx_head+0x08,ioaddr);
668: outw(lp->tx_head+0x0e,ioaddr);
669: outw(0x0000,ioaddr);
670: outw(0x0000,ioaddr);
671: outw(lp->tx_head+0x08,ioaddr);
672: outw(0x8000|len,ioaddr);
673: outw(-1,ioaddr);
674: outw(lp->tx_head+0x16,ioaddr);
675: outw(0,ioaddr);
676: outsw(ioaddr,buf,(len+1)>>1);
677: outw(lp->tx_tail+0x0c,ioaddr+WRITE_PTR);
678: outw(lp->tx_head,ioaddr);
679: dev->trans_start = jiffies;
680: lp->tx_tail = lp->tx_head;
681: if (lp->tx_head==TX_BUF_START+((lp->num_tx_bufs-1)*TX_BUF_SIZE))
682: lp->tx_head = TX_BUF_START;
683: else
684: lp->tx_head += TX_BUF_SIZE;
685: if (lp->tx_head != lp->tx_reap)
686: dev->tbusy = 0;
687: outw(old_wp,ioaddr+WRITE_PTR);
688: }
689:
690: /*
691: * Sanity check the suspected EtherExpress card
692: * Read hardware address, reset card, size memory and
693: * initialize buffer memory pointers. These should
694: * probably be held in dev->priv, in case someone has 2
695: * differently configured cards in their box (Arghhh!)
696: */
697:
698: static int eexp_hw_probe(struct device *dev, unsigned short ioaddr)
699: {
700: unsigned short hw_addr[3];
701: int i;
702: unsigned char *chw_addr = (unsigned char *)hw_addr;
703:
704: printk("%s: EtherExpress at %#x, ",dev->name,ioaddr);
705:
706: hw_addr[0] = eexp_hw_readeeprom(ioaddr,2);
707: hw_addr[1] = eexp_hw_readeeprom(ioaddr,3);
708: hw_addr[2] = eexp_hw_readeeprom(ioaddr,4);
709:
710: /* Standard Address or Compaq LTE Address */
711: if (!((hw_addr[2]==0x00aa && ((hw_addr[1] & 0xff00)==0x0000)) ||
712: (hw_addr[2]==0x0080 && ((hw_addr[1] & 0xff00)==0x5F00))))
713: {
714: printk("rejected: invalid address %04x%04x%04x\n",
715: hw_addr[2],hw_addr[1],hw_addr[0]);
716: return -ENODEV;
717: }
718:
719: dev->base_addr = ioaddr;
720: for ( i=0 ; i<6 ; i++ )
721: dev->dev_addr[i] = chw_addr[5-i];
722:
723: {
724: char irqmap[]={0, 9, 3, 4, 5, 10, 11, 0};
725: char *ifmap[]={"AUI", "BNC", "10baseT"};
726: enum iftype {AUI=0, BNC=1, TP=2};
727: unsigned short setupval = eexp_hw_readeeprom(ioaddr,0);
728:
729: dev->irq = irqmap[setupval>>13];
730: dev->if_port = !(setupval & 0x1000) ? AUI :
731: eexp_hw_readeeprom(ioaddr,5) & 0x1 ? TP : BNC;
732:
733: printk("IRQ %d, Interface %s, ",dev->irq,ifmap[dev->if_port]);
734:
735: outb(SIRQ_dis|irqrmap[dev->irq],ioaddr+SET_IRQ);
736: outb(0,ioaddr+SET_IRQ);
737: }
738:
739: dev->priv = kmalloc(sizeof(struct net_local), GFP_KERNEL);
740: if (!dev->priv)
741: return -ENOMEM;
742:
743: memset(dev->priv, 0, sizeof(struct net_local));
744:
745: eexp_hw_ASICrst(dev);
746:
747: {
748: unsigned short i586mso = 0x023e;
749: unsigned short old_wp,old_rp,old_a0,old_a1;
750: unsigned short a0_0,a1_0,a0_1,a1_1;
751:
752: old_wp = inw(ioaddr+WRITE_PTR);
753: old_rp = inw(ioaddr+READ_PTR);
754: outw(0x8000+i586mso,ioaddr+READ_PTR);
755: old_a1 = inw(ioaddr);
756: outw(i586mso,ioaddr+READ_PTR);
757: old_a0 = inw(ioaddr);
758: outw(i586mso,ioaddr+WRITE_PTR);
759: outw(0x55aa,ioaddr);
760: outw(i586mso,ioaddr+READ_PTR);
761: a0_0 = inw(ioaddr);
762: outw(0x8000+i586mso,ioaddr+WRITE_PTR);
763: outw(0x5a5a,ioaddr);
764: outw(0x8000+i586mso,ioaddr+READ_PTR);
765: a1_0 = inw(ioaddr);
766: outw(i586mso,ioaddr+READ_PTR);
767: a0_1 = inw(ioaddr);
768: outw(i586mso,ioaddr+WRITE_PTR);
769: outw(0x1234,ioaddr);
770: outw(0x8000+i586mso,ioaddr+READ_PTR);
771: a1_1 = inw(ioaddr);
772:
773: if ((a0_0 != a0_1) || (a1_0 != a1_1) ||
774: (a1_0 != 0x5a5a) || (a0_0 != 0x55aa))
775: {
776: printk("32k\n");
777: PRIV(dev)->rx_buf_end = 0x7ff6;
778: PRIV(dev)->num_tx_bufs = 4;
779: }
780: else
781: {
782: printk("64k\n");
783: PRIV(dev)->num_tx_bufs = 8;
784: PRIV(dev)->rx_buf_start = TX_BUF_START + (PRIV(dev)->num_tx_bufs*TX_BUF_SIZE);
785: PRIV(dev)->rx_buf_end = 0xfff6;
786: }
787:
788: outw(0x8000+i586mso,ioaddr+WRITE_PTR);
789: outw(old_a1,ioaddr);
790: outw(i586mso,ioaddr+WRITE_PTR);
791: outw(old_a0,ioaddr);
792: outw(old_wp,ioaddr+WRITE_PTR);
793: outw(old_rp,ioaddr+READ_PTR);
794: }
795:
796: if (net_debug)
797: printk(version);
798: dev->open = eexp_open;
799: dev->stop = eexp_close;
800: dev->hard_start_xmit = eexp_xmit;
801: dev->get_stats = eexp_stats;
802: dev->set_multicast_list = &eexp_set_multicast;
803: ether_setup(dev);
804: return 0;
805: }
806:
807: /*
808: * Read a word from eeprom location (0-63?)
809: */
810: static unsigned short eexp_hw_readeeprom(unsigned short ioaddr, unsigned char location)
811: {
812: unsigned short cmd = 0x180|(location&0x7f);
813: unsigned short rval = 0,wval = EC_CS|i586_RST;
814: int i;
815:
816: outb(EC_CS|i586_RST,ioaddr+EEPROM_Ctrl);
817: for ( i=0x100 ; i ; i>>=1 )
818: {
819: if (cmd&i)
820: wval |= EC_Wr;
821: else
822: wval &= ~EC_Wr;
823:
824: outb(wval,ioaddr+EEPROM_Ctrl);
825: outb(wval|EC_Clk,ioaddr+EEPROM_Ctrl);
826: eeprom_delay();
827: outb(wval,ioaddr+EEPROM_Ctrl);
828: eeprom_delay();
829: }
830: wval &= ~EC_Wr;
831: outb(wval,ioaddr+EEPROM_Ctrl);
832: for ( i=0x8000 ; i ; i>>=1 )
833: {
834: outb(wval|EC_Clk,ioaddr+EEPROM_Ctrl);
835: eeprom_delay();
836: if (inb(ioaddr+EEPROM_Ctrl)&EC_Rd)
837: rval |= i;
838: outb(wval,ioaddr+EEPROM_Ctrl);
839: eeprom_delay();
840: }
841: wval &= ~EC_CS;
842: outb(wval|EC_Clk,ioaddr+EEPROM_Ctrl);
843: eeprom_delay();
844: outb(wval,ioaddr+EEPROM_Ctrl);
845: eeprom_delay();
846: return rval;
847: }
848:
849: /*
850: * Reap tx buffers and return last transmit status.
851: * if ==0 then either:
852: * a) we're not transmitting anything, so why are we here?
853: * b) we've died.
854: * otherwise, Stat_Busy(return) means we've still got some packets
855: * to transmit, Stat_Done(return) means our buffers should be empty
856: * again
857: */
858:
859: static unsigned short eexp_hw_lasttxstat(struct device *dev)
860: {
861: struct net_local *lp = (struct net_local *)dev->priv;
862: unsigned short ioaddr = dev->base_addr;
863: unsigned short old_rp = inw(ioaddr+READ_PTR);
864: unsigned short old_wp = inw(ioaddr+WRITE_PTR);
865: unsigned short tx_block = lp->tx_reap;
866: unsigned short status;
867:
868: if (!test_bit(0,(void *)&dev->tbusy) && lp->tx_head==lp->tx_reap)
869: return 0x0000;
870:
871: do
872: {
873: outw(tx_block,ioaddr+READ_PTR);
874: status = inw(ioaddr);
875: if (!Stat_Done(status))
876: {
877: lp->tx_link = tx_block;
878: outw(old_rp,ioaddr+READ_PTR);
879: outw(old_wp,ioaddr+WRITE_PTR);
880: return status;
881: }
882: else
883: {
884: lp->last_tx_restart = 0;
885: lp->stats.collisions += Stat_NoColl(status);
886: if (!Stat_OK(status))
887: {
888: if (Stat_Abort(status))
889: lp->stats.tx_aborted_errors++;
890: if (Stat_TNoCar(status) || Stat_TNoCTS(status))
891: lp->stats.tx_carrier_errors++;
892: if (Stat_TNoDMA(status))
893: lp->stats.tx_fifo_errors++;
894: }
895: else
896: lp->stats.tx_packets++;
897: }
898: if (tx_block == TX_BUF_START+((lp->num_tx_bufs-1)*TX_BUF_SIZE))
899: lp->tx_reap = tx_block = TX_BUF_START;
900: else
901: lp->tx_reap = tx_block += TX_BUF_SIZE;
902: dev->tbusy = 0;
903: mark_bh(NET_BH);
904: }
905: while (lp->tx_reap != lp->tx_head);
906:
907: lp->tx_link = lp->tx_tail + 0x08;
908: outw(old_rp,ioaddr+READ_PTR);
909: outw(old_wp,ioaddr+WRITE_PTR);
910:
911: return status;
912: }
913:
914: /*
915: * This should never happen. It is called when some higher
916: * routine detects the CU has stopped, to try to restart
917: * it from the last packet we knew we were working on,
918: * or the idle loop if we had finished for the time.
919: */
920:
921: static void eexp_hw_txrestart(struct device *dev)
922: {
923: struct net_local *lp = (struct net_local *)dev->priv;
924: unsigned short ioaddr = dev->base_addr;
925:
926: lp->last_tx_restart = lp->tx_link;
927: outw(lp->tx_link,ioaddr+SCB_CBL);
928: outw(SCB_CUstart,ioaddr+SCB_CMD);
929: outw(0,ioaddr+SCB_STATUS);
930: outb(0,ioaddr+SIGNAL_CA);
931:
932: {
933: unsigned short boguscount=50,failcount=5;
934: while (!inw(ioaddr+SCB_STATUS))
935: {
936: if (!--boguscount)
937: {
938: if (--failcount)
939: {
940: printk(KERN_WARNING "%s: CU start timed out, status %04x, cmd %04x\n",
941: dev->name, inw(ioaddr+SCB_STATUS), inw(ioaddr+SCB_CMD));
942: outw(lp->tx_link,ioaddr+SCB_CBL);
943: outw(0,ioaddr+SCB_STATUS);
944: outw(SCB_CUstart,ioaddr+SCB_CMD);
945: outb(0,ioaddr+SIGNAL_CA);
946: boguscount = 100;
947: }
948: else
949: {
950: printk(KERN_WARNING "%s: Failed to restart CU, resetting board...\n",dev->name);
951: eexp_hw_init586(dev);
952: dev->tbusy = 0;
953: mark_bh(NET_BH);
954: return;
955: }
956: }
957: }
958: }
959: }
960:
961: /*
962: * Writes down the list of transmit buffers into card
963: * memory. Initial separate, repeated transmits link
964: * them into a circular list, such that the CU can
965: * be constantly active, and unlink them as we reap
966: * transmitted packet buffers, so the CU doesn't loop
967: * and endlessly transmit packets. (Try hacking the driver
968: * to send continuous broadcast messages, say ARP requests
969: * on a subnet with Windows boxes running on Novell and
970: * LAN Workplace with EMM386. Amusing to watch them all die
971: * horribly leaving the Linux boxes up!)
972: */
973:
974: static void eexp_hw_txinit(struct device *dev)
975: {
976: struct net_local *lp = (struct net_local *)dev->priv;
977: unsigned short ioaddr = dev->base_addr;
978: unsigned short old_wp = inw(ioaddr+WRITE_PTR);
979: unsigned short tx_block = TX_BUF_START;
980: unsigned short curtbuf;
981:
982: for ( curtbuf=0 ; curtbuf<lp->num_tx_bufs ; curtbuf++ )
983: {
984: outw(tx_block,ioaddr+WRITE_PTR);
985: outw(0x0000,ioaddr);
986: outw(Cmd_INT|Cmd_Xmit,ioaddr);
987: outw(tx_block+0x08,ioaddr);
988: outw(tx_block+0x0e,ioaddr);
989: outw(0x0000,ioaddr);
990: outw(0x0000,ioaddr);
991: outw(tx_block+0x08,ioaddr);
992: outw(0x8000,ioaddr);
993: outw(-1,ioaddr);
994: outw(tx_block+0x16,ioaddr);
995: outw(0x0000,ioaddr);
996: tx_block += TX_BUF_SIZE;
997: }
998: lp->tx_head = TX_BUF_START;
999: lp->tx_reap = TX_BUF_START;
1000: lp->tx_tail = tx_block - TX_BUF_SIZE;
1001: lp->tx_link = lp->tx_tail + 0x08;
1002: lp->rx_buf_start = tx_block;
1003: outw(old_wp,ioaddr+WRITE_PTR);
1004: }
1005:
1006: /* is this a standard test pattern, or dbecker randomness? */
1007:
1008: unsigned short rx_words[] =
1009: {
1010: 0xfeed,0xf00d,0xf001,0x0505,0x2424,0x6565,0xdeaf
1011: };
1012:
1013: /*
1014: * Write the circular list of receive buffer descriptors to
1015: * card memory. Note, we no longer mark the end of the list,
1016: * so if all the buffers fill up, the 82586 will loop until
1017: * we free one. This may sound dodgy, but it works, and
1018: * it makes the error detection in the interrupt handler
1019: * a lot simpler.
1020: */
1021:
1022: static void eexp_hw_rxinit(struct device *dev)
1023: {
1024: struct net_local *lp = (struct net_local *)dev->priv;
1025: unsigned short ioaddr = dev->base_addr;
1026: unsigned short old_wp = inw(ioaddr+WRITE_PTR);
1027: unsigned short rx_block = lp->rx_buf_start;
1028:
1029: lp->num_rx_bufs = 0;
1030: lp->rx_first = rx_block;
1031: do
1032: {
1033: lp->num_rx_bufs++;
1034: outw(rx_block,ioaddr+WRITE_PTR);
1035: outw(0x0000,ioaddr);
1036: outw(0x0000,ioaddr);
1037: outw(rx_block+RX_BUF_SIZE,ioaddr);
1038: outw(rx_block+0x16,ioaddr);
1039: outsw(ioaddr, rx_words, sizeof(rx_words)>>1);
1040: outw(0x8000,ioaddr);
1041: outw(-1,ioaddr);
1042: outw(rx_block+0x20,ioaddr);
1043: outw(0x0000,ioaddr);
1044: outw(0x8000|(RX_BUF_SIZE-0x20),ioaddr);
1045: lp->rx_last = rx_block;
1046: rx_block += RX_BUF_SIZE;
1047: } while (rx_block <= lp->rx_buf_end-RX_BUF_SIZE);
1048:
1049: outw(lp->rx_last+4,ioaddr+WRITE_PTR);
1050: outw(lp->rx_first,ioaddr);
1051:
1052: outw(old_wp,ioaddr+WRITE_PTR);
1053: }
1054:
1055: /*
1056: * Reset the 586, fill memory (including calls to
1057: * eexp_hw_[(rx)(tx)]init()) unreset, and start
1058: * the configuration sequence. We don't wait for this
1059: * to finish, but allow the interrupt handler to start
1060: * the CU and RU for us. We can't start the receive/
1061: * transmission system up before we know that the
1062: * hardware is configured correctly
1063: */
1064: static void eexp_hw_init586(struct device *dev)
1065: {
1066: struct net_local *lp = (struct net_local *)dev->priv;
1067: unsigned short ioaddr = dev->base_addr;
1068:
1069: #if NET_DEBUG > 6
1070: printk("%s: eexp_hw_init586()\n", dev->name);
1071: #endif
1072:
1073: lp->started = 0;
1074: set_loopback;
1075:
1076: outb(SIRQ_dis|irqrmap[dev->irq],ioaddr+SET_IRQ);
1077: outb_p(i586_RST,ioaddr+EEPROM_Ctrl);
1078: udelay(2000); /* delay 20ms */
1079: {
1080: unsigned long ofs;
1081: for (ofs = 0; ofs < lp->rx_buf_end; ofs += 32) {
1082: unsigned long i;
1083: outw_p(ofs, ioaddr+SM_PTR);
1084: for (i = 0; i < 16; i++) {
1085: outw_p(0, ioaddr+SM_ADDR(i<<1));
1086: }
1087: }
1088: }
1089:
1090: outw_p(lp->rx_buf_end,ioaddr+WRITE_PTR);
1091: start_code[28] = (dev->flags & IFF_PROMISC)?(start_code[28] | 1):(start_code[28] & ~1);
1092: lp->promisc = dev->flags & IFF_PROMISC;
1093: /* We may die here */
1094: outsw(ioaddr, start_code, sizeof(start_code)>>1);
1095: outw(CONF_HW_ADDR,ioaddr+WRITE_PTR);
1096: outsw(ioaddr,dev->dev_addr,3);
1097: eexp_hw_txinit(dev);
1098: eexp_hw_rxinit(dev);
1099: outw(0,ioaddr+WRITE_PTR);
1100: outw(1,ioaddr);
1101: outb(0,ioaddr+EEPROM_Ctrl);
1102: outw(0,ioaddr+SCB_CMD);
1103: outb(0,ioaddr+SIGNAL_CA);
1104: {
1105: unsigned short rboguscount=50,rfailcount=5;
1106: while (outw(0,ioaddr+READ_PTR),inw(ioaddr))
1107: {
1108: if (!--rboguscount)
1109: {
1110: printk(KERN_WARNING "%s: i82586 reset timed out, kicking...\n",
1111: dev->name);
1112: outw(0,ioaddr+SCB_CMD);
1113: outb(0,ioaddr+SIGNAL_CA);
1114: rboguscount = 100;
1115: if (!--rfailcount)
1116: {
1117: printk(KERN_WARNING "%s: i82586 not responding, giving up.\n",
1118: dev->name);
1119: return;
1120: }
1121: }
1122: }
1123: }
1124:
1125: outw(CONF_LINK,ioaddr+SCB_CBL);
1126: outw(0,ioaddr+SCB_STATUS);
1127: outw(0xf000|SCB_CUstart,ioaddr+SCB_CMD);
1128: outb(0,ioaddr+SIGNAL_CA);
1129: {
1130: unsigned short iboguscount=50,ifailcount=5;
1131: while (!inw(ioaddr+SCB_STATUS))
1132: {
1133: if (!--iboguscount)
1134: {
1135: if (--ifailcount)
1136: {
1137: printk(KERN_WARNING "%s: i82586 initialization timed out, status %04x, cmd %04x\n",
1138: dev->name, inw(ioaddr+SCB_STATUS), inw(ioaddr+SCB_CMD));
1139: outw(CONF_LINK,ioaddr+SCB_CBL);
1140: outw(0,ioaddr+SCB_STATUS);
1141: outw(0xf000|SCB_CUstart,ioaddr+SCB_CMD);
1142: outb(0,ioaddr+SIGNAL_CA);
1143: iboguscount = 100;
1144: }
1145: else
1146: {
1147: printk(KERN_WARNING "%s: Failed to initialize i82586, giving up.\n",dev->name);
1148: return;
1149: }
1150: }
1151: }
1152: }
1153:
1154: outb(SIRQ_en|irqrmap[dev->irq],ioaddr+SET_IRQ);
1155: clear_loopback;
1156: lp->init_time = jiffies;
1157: #if NET_DEBUG > 6
1158: printk("%s: leaving eexp_hw_init586()\n", dev->name);
1159: #endif
1160: return;
1161: }
1162:
1163: /*
1164: * completely reset the EtherExpress hardware. We will most likely get
1165: * an interrupt during this whether we want one or not. It is best,
1166: * therefore, to call this while we don't have a request_irq() on.
1167: */
1168:
1169: static void eexp_hw_ASICrst(struct device *dev)
1170: {
1171: unsigned short ioaddr = dev->base_addr;
1172: unsigned short wrval = 0x0001,succount=0,boguscount=500;
1173:
1174: outb(SIRQ_dis|irqrmap[dev->irq],ioaddr+SET_IRQ);
1175:
1176: PRIV(dev)->started = 0;
1177: outb(ASIC_RST|i586_RST,ioaddr+EEPROM_Ctrl);
1178: while (succount<20)
1179: {
1180: if (wrval == 0xffff)
1181: wrval = 0x0001;
1182: outw(0,ioaddr+WRITE_PTR);
1183: outw(wrval,ioaddr);
1184: outw(0,ioaddr+READ_PTR);
1185: if (wrval++ == inw(ioaddr))
1186: succount++;
1187: else
1188: {
1189: succount = 0;
1190: if (!boguscount--)
1191: {
1192: boguscount = 500;
1193: printk("%s: Having problems resetting EtherExpress ASIC, continuing...\n",
1194: dev->name);
1195: wrval = 0x0001;
1196: outb(ASIC_RST|i586_RST,ioaddr+EEPROM_Ctrl);
1197: }
1198: }
1199: }
1200: outb(i586_RST,ioaddr+EEPROM_Ctrl);
1201: }
1202:
1203:
1204: /*
1205: * Set or clear the multicast filter for this adaptor.
1206: * We have to do a complete 586 restart for this to take effect.
1207: * At the moment only promiscuous mode is supported.
1208: */
1209: static void
1210: eexp_set_multicast(struct device *dev)
1211: {
1212: if ((dev->flags & IFF_PROMISC) != PRIV(dev)->promisc)
1213: eexp_hw_init586(dev);
1214: }
1215:
1216:
1217: /*
1218: * MODULE stuff
1219: */
1220: #ifdef MODULE
1221:
1222: #define EEXP_MAX_CARDS 4 /* max number of cards to support */
1223: #define NAMELEN 8 /* max length of dev->name (inc null) */
1224:
1225: static char namelist[NAMELEN * EEXP_MAX_CARDS] = { 0, };
1226:
1227: static struct device dev_eexp[EEXP_MAX_CARDS] =
1228: {
1229: { NULL, /* will allocate dynamically */
1230: 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, express_probe },
1231: };
1232:
1233: int irq[EEXP_MAX_CARDS] = {0, };
1234: int io[EEXP_MAX_CARDS] = {0, };
1235:
1236: /* Ideally the user would give us io=, irq= for every card. If any parameters
1237: * are specified, we verify and then use them. If no parameters are given, we
1238: * autoprobe for one card only.
1239: */
1240: int init_module(void)
1241: {
1242: int this_dev, found = 0;
1243:
1244: for (this_dev = 0; this_dev < EEXP_MAX_CARDS; this_dev++) {
1245: struct device *dev = &dev_eexp[this_dev];
1246: dev->name = namelist + (NAMELEN*this_dev);
1247: dev->irq = irq[this_dev];
1248: dev->base_addr = io[this_dev];
1249: if (io[this_dev] == 0) {
1250: if (this_dev) break;
1251: printk(KERN_NOTICE "eexpress.c: Module autoprobe not recommended, give io=xx.\n");
1252: }
1253: if (register_netdev(dev) != 0) {
1254: printk(KERN_WARNING "eexpress.c: Failed to register card at 0x%x.\n", io[this_dev]);
1255: if (found != 0) return 0;
1256: return -ENXIO;
1257: }
1258: found++;
1259: }
1260: return 0;
1261: }
1262:
1263: void cleanup_module(void)
1264: {
1265: int this_dev;
1266:
1267: for (this_dev = 0; this_dev < EEXP_MAX_CARDS; this_dev++) {
1268: struct device *dev = &dev_eexp[this_dev];
1269: if (dev->priv != NULL) {
1270: kfree(dev->priv);
1271: dev->priv = NULL;
1272: release_region(dev->base_addr, EEXP_IO_EXTENT);
1273: unregister_netdev(dev);
1274: }
1275: }
1276: }
1277: #endif
1278:
1279: /*
1280: * Local Variables:
1281: * c-file-style: "linux"
1282: * tab-width: 8
1283: * compile-command: "gcc -D__KERNEL__ -I/discs/bibble/src/linux-1.3.69/include -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -fno-strength-reduce -pipe -m486 -DCPU=486 -DMODULE -c 3c505.c"
1284: * End:
1285: */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.