|
|
1.1 root 1: /* apricot.c: An Apricot 82596 ethernet driver for linux. */
2: /*
3: Apricot
4: Written 1994 by Mark Evans.
5: This driver is for the Apricot 82596 bus-master interface
6:
7: Modularised 12/94 Mark Evans
8:
9: Driver skeleton
10: Written 1993 by Donald Becker.
11: Copyright 1993 United States Government as represented by the Director,
12: National Security Agency. This software may only be used and distributed
13: according to the terms of the GNU Public License as modified by SRC,
14: incorporated herein by reference.
15:
16: The author may be reached as [email protected] or
17: C/O Supercomputing Research Ctr., 17100 Science Dr., Bowie MD 20715
18:
19:
20: */
21:
22: static const char *version = "apricot.c:v0.2 05/12/94\n";
23:
24: #include <linux/module.h>
25:
26: #include <linux/kernel.h>
27: #include <linux/sched.h>
28: #include <linux/string.h>
29: #include <linux/ptrace.h>
30: #include <linux/errno.h>
31: #include <linux/ioport.h>
32: #include <linux/malloc.h>
33: #include <linux/interrupt.h>
34: #include <linux/netdevice.h>
35: #include <linux/etherdevice.h>
36: #include <linux/skbuff.h>
37:
38: #include <asm/bitops.h>
39: #include <asm/io.h>
40: #include <asm/dma.h>
41:
42: #ifndef HAVE_PORTRESERVE
43: #define check_region(addr, size) 0
44: #define request_region(addr, size,name) do ; while(0)
45: #endif
46:
47: #ifndef HAVE_ALLOC_SKB
48: #define alloc_skb(size, priority) (struct sk_buff *) kmalloc(size,priority)
49: #define kfree_skbmem(buff, size) kfree_s(buff,size)
50: #endif
51:
52: #define APRICOT_DEBUG 1
53:
54: #ifdef APRICOT_DEBUG
55: int i596_debug = APRICOT_DEBUG;
56: #else
57: int i596_debug = 1;
58: #endif
59:
60: #define APRICOT_TOTAL_SIZE 17
61:
62: #define I596_NULL -1
63:
64: #define CMD_EOL 0x8000 /* The last command of the list, stop. */
65: #define CMD_SUSP 0x4000 /* Suspend after doing cmd. */
66: #define CMD_INTR 0x2000 /* Interrupt after doing cmd. */
67:
68: #define CMD_FLEX 0x0008 /* Enable flexible memory model */
69:
70: enum commands {
71: CmdNOp = 0, CmdSASetup = 1, CmdConfigure = 2, CmdMulticastList = 3,
72: CmdTx = 4, CmdTDR = 5, CmdDump = 6, CmdDiagnose = 7};
73:
74: #define STAT_C 0x8000 /* Set to 0 after execution */
75: #define STAT_B 0x4000 /* Command being executed */
76: #define STAT_OK 0x2000 /* Command executed ok */
77: #define STAT_A 0x1000 /* Command aborted */
78:
79: #define CUC_START 0x0100
80: #define CUC_RESUME 0x0200
81: #define CUC_SUSPEND 0x0300
82: #define CUC_ABORT 0x0400
83: #define RX_START 0x0010
84: #define RX_RESUME 0x0020
85: #define RX_SUSPEND 0x0030
86: #define RX_ABORT 0x0040
87:
88: struct i596_cmd {
89: unsigned short status;
90: unsigned short command;
91: struct i596_cmd *next;
92: };
93:
94: #define EOF 0x8000
95: #define SIZE_MASK 0x3fff
96:
97: struct i596_tbd {
98: unsigned short size;
99: unsigned short pad;
100: struct i596_tbd *next;
1.1.1.2 root 101: unsigned char *data;
1.1 root 102: };
103:
104: struct tx_cmd {
105: struct i596_cmd cmd;
106: struct i596_tbd *tbd;
107: unsigned short size;
108: unsigned short pad;
109: };
110:
111: struct i596_rfd {
112: unsigned short stat;
113: unsigned short cmd;
114: struct i596_rfd *next;
115: long rbd;
116: unsigned short count;
117: unsigned short size;
1.1.1.2 root 118: unsigned char data[1532];
1.1 root 119: };
120:
121: #define RX_RING_SIZE 8
122:
123: struct i596_scb {
124: unsigned short status;
125: unsigned short command;
126: struct i596_cmd *cmd;
127: struct i596_rfd *rfd;
128: unsigned long crc_err;
129: unsigned long align_err;
130: unsigned long resource_err;
131: unsigned long over_err;
132: unsigned long rcvdt_err;
133: unsigned long short_err;
134: unsigned short t_on;
135: unsigned short t_off;
136: };
137:
138: struct i596_iscp {
139: unsigned long stat;
140: struct i596_scb *scb;
141: };
142:
143: struct i596_scp {
144: unsigned long sysbus;
145: unsigned long pad;
146: struct i596_iscp *iscp;
147: };
148:
149: struct i596_private {
150: volatile struct i596_scp scp;
151: volatile struct i596_iscp iscp;
152: volatile struct i596_scb scb;
153: volatile struct i596_cmd set_add;
154: char eth_addr[8];
155: volatile struct i596_cmd set_conf;
156: char i596_config[16];
157: volatile struct i596_cmd tdr;
158: unsigned long stat;
159: int last_restart;
160: struct i596_rfd *rx_tail;
161: struct i596_cmd *cmd_tail;
162: struct i596_cmd *cmd_head;
163: int cmd_backlog;
164: unsigned long last_cmd;
165: struct enet_statistics stats;
166: };
167:
168: char init_setup[] = {
169: 0x8E, /* length, prefetch on */
170: 0xC8, /* fifo to 8, monitor off */
171: 0x80, /* don't save bad frames */
172: 0x2E, /* No source address insertion, 8 byte preamble */
173: 0x00, /* priority and backoff defaults */
174: 0x60, /* interframe spacing */
175: 0x00, /* slot time LSB */
176: 0xf2, /* slot time and retries */
177: 0x00, /* promiscuous mode */
178: 0x00, /* collision detect */
179: 0x40, /* minimum frame length */
180: 0xff,
181: 0x00,
182: 0x7f /* *multi IA */ };
183:
184: static int i596_open(struct device *dev);
185: static int i596_start_xmit(struct sk_buff *skb, struct device *dev);
186: static void i596_interrupt(int irq, void *dev_id, struct pt_regs *regs);
187: static int i596_close(struct device *dev);
188: static struct enet_statistics *i596_get_stats(struct device *dev);
189: static void i596_add_cmd(struct device *dev, struct i596_cmd *cmd);
1.1.1.2 root 190: static void print_eth(unsigned char *);
1.1 root 191: static void set_multicast_list(struct device *dev);
192:
193:
194: static inline int
195: init_rx_bufs(struct device *dev, int num)
196: {
197: struct i596_private *lp = (struct i596_private *)dev->priv;
198: int i;
199: struct i596_rfd *rfd;
200:
201: lp->scb.rfd = (struct i596_rfd *)I596_NULL;
202:
203: if (i596_debug > 1) printk ("%s: init_rx_bufs %d.\n", dev->name, num);
204:
205: for (i = 0; i < num; i++)
206: {
207: if (!(rfd = (struct i596_rfd *)kmalloc(sizeof(struct i596_rfd), GFP_KERNEL)))
208: break;
209:
210: rfd->stat = 0x0000;
211: rfd->rbd = I596_NULL;
212: rfd->count = 0;
213: rfd->size = 1532;
214: if (i == 0)
215: {
216: rfd->cmd = CMD_EOL;
217: lp->rx_tail = rfd;
218: }
219: else
220: rfd->cmd = 0x0000;
221:
222: rfd->next = lp->scb.rfd;
223: lp->scb.rfd = rfd;
224: }
225:
226: if (i != 0)
227: lp->rx_tail->next = lp->scb.rfd;
228:
229: return (i);
230: }
231:
232: static inline void
233: remove_rx_bufs(struct device *dev)
234: {
235: struct i596_private *lp = (struct i596_private *)dev->priv;
236: struct i596_rfd *rfd = lp->scb.rfd;
237:
238: lp->rx_tail->next = (struct i596_rfd *)I596_NULL;
239:
240: do
241: {
242: lp->scb.rfd = rfd->next;
243: kfree_s(rfd, sizeof(struct i596_rfd));
244: rfd = lp->scb.rfd;
245: }
246: while (rfd != lp->rx_tail);
247: }
248:
249: static inline void
250: init_i596_mem(struct device *dev)
251: {
252: struct i596_private *lp = (struct i596_private *)dev->priv;
253: short ioaddr = dev->base_addr;
254: int boguscnt = 100;
255:
256: /* change the scp address */
257: outw(0, ioaddr);
258: outw(0, ioaddr);
259: outb(4, ioaddr+0xf);
260: outw(((((int)&lp->scp) & 0xffff) | 2), ioaddr);
261: outw((((int)&lp->scp)>>16) & 0xffff, ioaddr);
262:
263: lp->last_cmd = jiffies;
264:
265: lp->scp.sysbus = 0x00440000;
266: lp->scp.iscp = &(lp->iscp);
267: lp->iscp.scb = &(lp->scb);
268: lp->iscp.stat = 0x0001;
269: lp->cmd_backlog = 0;
270:
271: lp->cmd_head = lp->scb.cmd = (struct i596_cmd *) I596_NULL;
272:
273: if (i596_debug > 2) printk("%s: starting i82596.\n", dev->name);
274:
275: (void) inb (ioaddr+0x10);
276: outb(4, ioaddr+0xf);
277: outw(0, ioaddr+4);
278:
279: while (lp->iscp.stat)
280: if (--boguscnt == 0)
281: {
282: printk("%s: i82596 initialization timed out with status %4.4x, cmd %4.4x.\n",
283: dev->name, lp->scb.status, lp->scb.command);
284: break;
285: }
286:
287: lp->scb.command = 0;
288:
289: memcpy (lp->i596_config, init_setup, 14);
290: lp->set_conf.command = CmdConfigure;
291: i596_add_cmd(dev, &lp->set_conf);
292:
293: memcpy (lp->eth_addr, dev->dev_addr, 6);
294: lp->set_add.command = CmdSASetup;
295: i596_add_cmd(dev, &lp->set_add);
296:
297: lp->tdr.command = CmdTDR;
298: i596_add_cmd(dev, &lp->tdr);
299:
300: boguscnt = 200;
301: while (lp->scb.status, lp->scb.command)
302: if (--boguscnt == 0)
303: {
304: printk("%s: receive unit start timed out with status %4.4x, cmd %4.4x.\n",
305: dev->name, lp->scb.status, lp->scb.command);
306: break;
307: }
308:
309: lp->scb.command = RX_START;
310: outw(0, ioaddr+4);
311:
312: boguscnt = 200;
313: while (lp->scb.status, lp->scb.command)
314: if (--boguscnt == 0)
315: {
316: printk("i82596 init timed out with status %4.4x, cmd %4.4x.\n",
317: lp->scb.status, lp->scb.command);
318: break;
319: }
320:
321: return;
322: }
323:
324: static inline int
325: i596_rx(struct device *dev)
326: {
327: struct i596_private *lp = (struct i596_private *)dev->priv;
328: int frames = 0;
329:
330: if (i596_debug > 3) printk ("i596_rx()\n");
331:
332: while ((lp->scb.rfd->stat) & STAT_C)
333: {
334: if (i596_debug >2) print_eth(lp->scb.rfd->data);
335:
336: if ((lp->scb.rfd->stat) & STAT_OK)
337: {
338: /* a good frame */
339: int pkt_len = lp->scb.rfd->count & 0x3fff;
340: struct sk_buff *skb = dev_alloc_skb(pkt_len);
341:
342: frames++;
343:
344: if (skb == NULL)
345: {
346: printk ("%s: i596_rx Memory squeeze, dropping packet.\n", dev->name);
347: lp->stats.rx_dropped++;
348: break;
349: }
350:
351: skb->dev = dev;
352: memcpy(skb_put(skb,pkt_len), lp->scb.rfd->data, pkt_len);
353:
354: skb->protocol=eth_type_trans(skb,dev);
355: netif_rx(skb);
356: lp->stats.rx_packets++;
357:
358: if (i596_debug > 4) print_eth(skb->data);
359: }
360: else
361: {
362: lp->stats.rx_errors++;
363: if ((lp->scb.rfd->stat) & 0x0001) lp->stats.collisions++;
364: if ((lp->scb.rfd->stat) & 0x0080) lp->stats.rx_length_errors++;
365: if ((lp->scb.rfd->stat) & 0x0100) lp->stats.rx_over_errors++;
366: if ((lp->scb.rfd->stat) & 0x0200) lp->stats.rx_fifo_errors++;
367: if ((lp->scb.rfd->stat) & 0x0400) lp->stats.rx_frame_errors++;
368: if ((lp->scb.rfd->stat) & 0x0800) lp->stats.rx_crc_errors++;
369: if ((lp->scb.rfd->stat) & 0x1000) lp->stats.rx_length_errors++;
370: }
371:
372: lp->scb.rfd->stat = 0;
373: lp->rx_tail->cmd = 0;
374: lp->rx_tail = lp->scb.rfd;
375: lp->scb.rfd = lp->scb.rfd->next;
376: lp->rx_tail->count = 0;
377: lp->rx_tail->cmd = CMD_EOL;
378:
379: }
380:
381: if (i596_debug > 3) printk ("frames %d\n", frames);
382:
383: return 0;
384: }
385:
386: static inline void
387: i596_cleanup_cmd(struct i596_private *lp)
388: {
389: struct i596_cmd *ptr;
390: int boguscnt = 100;
391:
392: if (i596_debug > 4) printk ("i596_cleanup_cmd\n");
393:
394: while (lp->cmd_head != (struct i596_cmd *) I596_NULL)
395: {
396: ptr = lp->cmd_head;
397:
398: lp->cmd_head = lp->cmd_head->next;
399: lp->cmd_backlog--;
400:
401: switch ((ptr->command) & 0x7)
402: {
403: case CmdTx:
404: {
405: struct tx_cmd *tx_cmd = (struct tx_cmd *) ptr;
406: struct sk_buff *skb = ((struct sk_buff *)(tx_cmd->tbd->data)) -1;
407:
408: dev_kfree_skb(skb, FREE_WRITE);
409:
410: lp->stats.tx_errors++;
411: lp->stats.tx_aborted_errors++;
412:
413: ptr->next = (struct i596_cmd * ) I596_NULL;
414: kfree_s((unsigned char *)tx_cmd, (sizeof (struct tx_cmd) + sizeof (struct i596_tbd)));
415: break;
416: }
417: case CmdMulticastList:
418: {
419: unsigned short count = *((unsigned short *) (ptr + 1));
420:
421: ptr->next = (struct i596_cmd * ) I596_NULL;
422: kfree_s((unsigned char *)ptr, (sizeof (struct i596_cmd) + count + 2));
423: break;
424: }
425: default:
426: ptr->next = (struct i596_cmd * ) I596_NULL;
427: }
428: }
429:
430: while (lp->scb.status, lp->scb.command)
431: if (--boguscnt == 0)
432: {
433: printk("i596_cleanup_cmd timed out with status %4.4x, cmd %4.4x.\n",
434: lp->scb.status, lp->scb.command);
435: break;
436: }
437:
438: lp->scb.cmd = lp->cmd_head;
439: }
440:
441: static inline void
442: i596_reset(struct device *dev, struct i596_private *lp, int ioaddr)
443: {
444: int boguscnt = 100;
445:
446: if (i596_debug > 4) printk ("i596_reset\n");
447:
448: while (lp->scb.status, lp->scb.command)
449: if (--boguscnt == 0)
450: {
451: printk("i596_reset timed out with status %4.4x, cmd %4.4x.\n",
452: lp->scb.status, lp->scb.command);
453: break;
454: }
455:
456: dev->start = 0;
457: dev->tbusy = 1;
458:
459: lp->scb.command = CUC_ABORT|RX_ABORT;
460: outw(0, ioaddr+4);
461:
462: /* wait for shutdown */
463: boguscnt = 400;
464:
465: while ((lp->scb.status, lp->scb.command) || lp->scb.command)
466: if (--boguscnt == 0)
467: {
468: printk("i596_reset 2 timed out with status %4.4x, cmd %4.4x.\n",
469: lp->scb.status, lp->scb.command);
470: break;
471: }
472:
473: i596_cleanup_cmd(lp);
474: i596_rx(dev);
475:
476: dev->start = 1;
477: dev->tbusy = 0;
478: dev->interrupt = 0;
479: init_i596_mem(dev);
480: }
481:
482: static void i596_add_cmd(struct device *dev, struct i596_cmd *cmd)
483: {
484: struct i596_private *lp = (struct i596_private *)dev->priv;
485: int ioaddr = dev->base_addr;
486: unsigned long flags;
487: int boguscnt = 100;
488:
489: if (i596_debug > 4) printk ("i596_add_cmd\n");
490:
491: cmd->status = 0;
492: cmd->command |= (CMD_EOL|CMD_INTR);
493: cmd->next = (struct i596_cmd *) I596_NULL;
494:
495: save_flags(flags);
496: cli();
497: if (lp->cmd_head != (struct i596_cmd *) I596_NULL)
498: lp->cmd_tail->next = cmd;
499: else
500: {
501: lp->cmd_head = cmd;
502: while (lp->scb.status, lp->scb.command)
503: if (--boguscnt == 0)
504: {
505: printk("i596_add_cmd timed out with status %4.4x, cmd %4.4x.\n",
506: lp->scb.status, lp->scb.command);
507: break;
508: }
509:
510: lp->scb.cmd = cmd;
511: lp->scb.command = CUC_START;
512: outw (0, ioaddr+4);
513: }
514: lp->cmd_tail = cmd;
515: lp->cmd_backlog++;
516:
517: lp->cmd_head = lp->scb.cmd;
518: restore_flags(flags);
519:
520: if (lp->cmd_backlog > 16)
521: {
522: int tickssofar = jiffies - lp->last_cmd;
523:
524: if (tickssofar < 25) return;
525:
526: printk("%s: command unit timed out, status resetting.\n", dev->name);
527:
528: i596_reset(dev, lp, ioaddr);
529: }
530: }
531:
532: static int
533: i596_open(struct device *dev)
534: {
535: int i;
536:
537: if (i596_debug > 1)
538: printk("%s: i596_open() irq %d.\n", dev->name, dev->irq);
539:
540: if (request_irq(dev->irq, &i596_interrupt, 0, "apricot", NULL))
541: return -EAGAIN;
542:
543: irq2dev_map[dev->irq] = dev;
544:
545: i = init_rx_bufs(dev, RX_RING_SIZE);
546:
547: if ((i = init_rx_bufs(dev, RX_RING_SIZE)) < RX_RING_SIZE)
548: printk("%s: only able to allocate %d receive buffers\n", dev->name, i);
549:
550: if (i < 4)
551: {
552: free_irq(dev->irq, NULL);
553: irq2dev_map[dev->irq] = 0;
554: return -EAGAIN;
555: }
556:
557: dev->tbusy = 0;
558: dev->interrupt = 0;
559: dev->start = 1;
560: MOD_INC_USE_COUNT;
561:
562: /* Initialize the 82596 memory */
563: init_i596_mem(dev);
564:
565: return 0; /* Always succeed */
566: }
567:
568: static int
569: i596_start_xmit(struct sk_buff *skb, struct device *dev)
570: {
571: struct i596_private *lp = (struct i596_private *)dev->priv;
572: int ioaddr = dev->base_addr;
573: struct tx_cmd *tx_cmd;
574:
575: if (i596_debug > 2) printk ("%s: Apricot start xmit\n", dev->name);
576:
577: /* Transmitter timeout, serious problems. */
578: if (dev->tbusy) {
579: int tickssofar = jiffies - dev->trans_start;
580: if (tickssofar < 5)
581: return 1;
582: printk("%s: transmit timed out, status resetting.\n",
583: dev->name);
584: lp->stats.tx_errors++;
585: /* Try to restart the adaptor */
586: if (lp->last_restart == lp->stats.tx_packets) {
587: if (i596_debug > 1) printk ("Resetting board.\n");
588:
589: /* Shutdown and restart */
590: i596_reset(dev,lp, ioaddr);
591: } else {
592: /* Issue a channel attention signal */
593: if (i596_debug > 1) printk ("Kicking board.\n");
594:
595: lp->scb.command = CUC_START|RX_START;
596: outw(0, ioaddr+4);
597:
598: lp->last_restart = lp->stats.tx_packets;
599: }
600: dev->tbusy = 0;
601: dev->trans_start = jiffies;
602: }
603:
604: /* If some higher level thinks we've misses a tx-done interrupt
605: we are passed NULL. n.b. dev_tint handles the cli()/sti()
606: itself. */
607: if (skb == NULL) {
608: dev_tint(dev);
609: return 0;
610: }
611:
612: /* shouldn't happen */
613: if (skb->len <= 0) return 0;
614:
615: if (i596_debug > 3) printk("%s: i596_start_xmit() called\n", dev->name);
616:
617: /* Block a timer-based transmit from overlapping. This could better be
618: done with atomic_swap(1, dev->tbusy), but set_bit() works as well. */
619: if (set_bit(0, (void*)&dev->tbusy) != 0)
620: printk("%s: Transmitter access conflict.\n", dev->name);
621: else
622: {
623: short length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
624: dev->trans_start = jiffies;
625:
626: tx_cmd = (struct tx_cmd *) kmalloc ((sizeof (struct tx_cmd) + sizeof (struct i596_tbd)), GFP_ATOMIC);
627: if (tx_cmd == NULL)
628: {
629: printk ("%s: i596_xmit Memory squeeze, dropping packet.\n", dev->name);
630: lp->stats.tx_dropped++;
631:
632: dev_kfree_skb(skb, FREE_WRITE);
633: }
634: else
635: {
636: tx_cmd->tbd = (struct i596_tbd *) (tx_cmd + 1);
637: tx_cmd->tbd->next = (struct i596_tbd *) I596_NULL;
638:
639: tx_cmd->cmd.command = CMD_FLEX|CmdTx;
640:
641: tx_cmd->pad = 0;
642: tx_cmd->size = 0;
643: tx_cmd->tbd->pad = 0;
644: tx_cmd->tbd->size = EOF | length;
645:
646: tx_cmd->tbd->data = skb->data;
647:
648: if (i596_debug > 3) print_eth(skb->data);
649:
650: i596_add_cmd(dev, (struct i596_cmd *)tx_cmd);
651:
652: lp->stats.tx_packets++;
653: }
654: }
655:
656: dev->tbusy = 0;
657:
658: return 0;
659: }
660:
661:
1.1.1.2 root 662: static void print_eth(unsigned char *add)
1.1 root 663: {
664: int i;
665:
666: printk ("Dest ");
667: for (i = 0; i < 6; i++)
1.1.1.2 root 668: printk(" %2.2X", add[i]);
1.1 root 669: printk ("\n");
670:
671: printk ("Source");
672: for (i = 0; i < 6; i++)
1.1.1.2 root 673: printk(" %2.2X", add[i+6]);
1.1 root 674: printk ("\n");
1.1.1.2 root 675: printk ("type %2.2X%2.2X\n", add[12], add[13]);
1.1 root 676: }
677:
678: int apricot_probe(struct device *dev)
679: {
680: int i;
681: struct i596_private *lp;
682: int checksum = 0;
683: int ioaddr = 0x300;
1.1.1.2 root 684: char eth_addr[8];
1.1 root 685:
686: /* this is easy the ethernet interface can only be at 0x300 */
687: /* first check nothing is already registered here */
688:
689: if (check_region(ioaddr, APRICOT_TOTAL_SIZE))
690: return ENODEV;
691:
692: for (i = 0; i < 8; i++)
693: {
694: eth_addr[i] = inb(ioaddr+8+i);
695: checksum += eth_addr[i];
696: }
697:
698: /* checksum is a multiple of 0x100, got this wrong first time
699: some machines have 0x100, some 0x200. The DOS driver doesn't
700: even bother with the checksum */
701:
702: if (checksum % 0x100) return ENODEV;
703:
704: /* Some other boards trip the checksum.. but then appear as ether
705: address 0. Trap these - AC */
706:
707: if(memcmp(eth_addr,"\x00\x00\x49",3)!= 0)
708: return ENODEV;
709:
710: request_region(ioaddr, APRICOT_TOTAL_SIZE, "apricot");
711:
712: dev->base_addr = ioaddr;
713: ether_setup(dev);
714: printk("%s: Apricot 82596 at %#3x,", dev->name, ioaddr);
715:
716: for (i = 0; i < 6; i++)
717: printk(" %2.2X", dev->dev_addr[i] = eth_addr[i]);
718:
719: dev->base_addr = ioaddr;
720: dev->irq = 10;
721: printk(" IRQ %d.\n", dev->irq);
722:
1.1.1.3 ! root 723: if (i596_debug > 0) printk("%s", version);
1.1 root 724:
725: /* The APRICOT-specific entries in the device structure. */
726: dev->open = &i596_open;
727: dev->stop = &i596_close;
728: dev->hard_start_xmit = &i596_start_xmit;
729: dev->get_stats = &i596_get_stats;
730: dev->set_multicast_list = &set_multicast_list;
731:
732: dev->mem_start = (int)kmalloc(sizeof(struct i596_private)+ 0x0f, GFP_KERNEL);
733: /* align for scp */
734: dev->priv = (void *)((dev->mem_start + 0xf) & 0xfffffff0);
735:
736: lp = (struct i596_private *)dev->priv;
737: memset((void *)lp, 0, sizeof(struct i596_private));
738: lp->scb.command = 0;
739: lp->scb.cmd = (struct i596_cmd *) I596_NULL;
740: lp->scb.rfd = (struct i596_rfd *)I596_NULL;
741:
742: return 0;
743: }
744:
745: static void
746: i596_interrupt(int irq, void *dev_id, struct pt_regs *regs)
747: {
748: struct device *dev = (struct device *)(irq2dev_map[irq]);
749: struct i596_private *lp;
750: short ioaddr;
751: int boguscnt = 200;
752: unsigned short status, ack_cmd = 0;
753:
754: if (dev == NULL) {
755: printk ("i596_interrupt(): irq %d for unknown device.\n", irq);
756: return;
757: }
758:
759: if (i596_debug > 3) printk ("%s: i596_interrupt(): irq %d\n",dev->name, irq);
760:
761: if (dev->interrupt)
762: printk("%s: Re-entering the interrupt handler.\n", dev->name);
763:
764: dev->interrupt = 1;
765:
766: ioaddr = dev->base_addr;
767:
768: lp = (struct i596_private *)dev->priv;
769:
770: while (lp->scb.status, lp->scb.command)
771: if (--boguscnt == 0)
772: {
773: printk("%s: i596 interrupt, timeout status %4.4x command %4.4x.\n", dev->name, lp->scb.status, lp->scb.command);
774: break;
775: }
776: status = lp->scb.status;
777:
778: if (i596_debug > 4)
779: printk("%s: i596 interrupt, status %4.4x.\n", dev->name, status);
780:
781: ack_cmd = status & 0xf000;
782:
783: if ((status & 0x8000) || (status & 0x2000))
784: {
785: struct i596_cmd *ptr;
786:
787: if ((i596_debug > 4) && (status & 0x8000))
788: printk("%s: i596 interrupt completed command.\n", dev->name);
789: if ((i596_debug > 4) && (status & 0x2000))
790: printk("%s: i596 interrupt command unit inactive %x.\n", dev->name, status & 0x0700);
791:
792: while ((lp->cmd_head != (struct i596_cmd *) I596_NULL) && (lp->cmd_head->status & STAT_C))
793: {
794: ptr = lp->cmd_head;
795:
796: lp->cmd_head = lp->cmd_head->next;
797: lp->cmd_backlog--;
798:
799: switch ((ptr->command) & 0x7)
800: {
801: case CmdTx:
802: {
803: struct tx_cmd *tx_cmd = (struct tx_cmd *) ptr;
804: struct sk_buff *skb = ((struct sk_buff *)(tx_cmd->tbd->data)) -1;
805:
806: dev_kfree_skb(skb, FREE_WRITE);
807:
808: if ((ptr->status) & STAT_OK)
809: {
810: if (i596_debug >2) print_eth(skb->data);
811: }
812: else
813: {
814: lp->stats.tx_errors++;
815: if ((ptr->status) & 0x0020) lp->stats.collisions++;
816: if (!((ptr->status) & 0x0040)) lp->stats.tx_heartbeat_errors++;
817: if ((ptr->status) & 0x0400) lp->stats.tx_carrier_errors++;
818: if ((ptr->status) & 0x0800) lp->stats.collisions++;
819: if ((ptr->status) & 0x1000) lp->stats.tx_aborted_errors++;
820: }
821:
822:
823: ptr->next = (struct i596_cmd * ) I596_NULL;
824: kfree_s((unsigned char *)tx_cmd, (sizeof (struct tx_cmd) + sizeof (struct i596_tbd)));
825: break;
826: }
827: case CmdMulticastList:
828: {
829: unsigned short count = *((unsigned short *) (ptr + 1));
830:
831: ptr->next = (struct i596_cmd * ) I596_NULL;
832: kfree_s((unsigned char *)ptr, (sizeof (struct i596_cmd) + count + 2));
833: break;
834: }
835: case CmdTDR:
836: {
837: unsigned long status = *((unsigned long *) (ptr + 1));
838:
839: if (status & 0x8000)
840: {
841: if (i596_debug > 3)
842: printk("%s: link ok.\n", dev->name);
843: }
844: else
845: {
846: if (status & 0x4000)
847: printk("%s: Transceiver problem.\n", dev->name);
848: if (status & 0x2000)
849: printk("%s: Termination problem.\n", dev->name);
850: if (status & 0x1000)
851: printk("%s: Short circuit.\n", dev->name);
852:
853: printk("%s: Time %ld.\n", dev->name, status & 0x07ff);
854: }
855: }
856: default:
857: ptr->next = (struct i596_cmd * ) I596_NULL;
858:
859: lp->last_cmd = jiffies;
860: }
861: }
862:
863: ptr = lp->cmd_head;
864: while ((ptr != (struct i596_cmd *) I596_NULL) && (ptr != lp->cmd_tail))
865: {
866: ptr->command &= 0x1fff;
867: ptr = ptr->next;
868: }
869:
870: if ((lp->cmd_head != (struct i596_cmd *) I596_NULL) && (dev->start)) ack_cmd |= CUC_START;
871: lp->scb.cmd = lp->cmd_head;
872: }
873:
874: if ((status & 0x1000) || (status & 0x4000))
875: {
876: if ((i596_debug > 4) && (status & 0x4000))
877: printk("%s: i596 interrupt received a frame.\n", dev->name);
878: if ((i596_debug > 4) && (status & 0x1000))
879: printk("%s: i596 interrupt receive unit inactive %x.\n", dev->name, status & 0x0070);
880:
881: i596_rx(dev);
882:
883: if (dev->start) ack_cmd |= RX_START;
884: }
885:
886: /* acknowledge the interrupt */
887:
888: /*
889: if ((lp->scb.cmd != (struct i596_cmd *) I596_NULL) && (dev->start)) ack_cmd | = CUC_START;
890: */
891: boguscnt = 100;
892: while (lp->scb.status, lp->scb.command)
893: if (--boguscnt == 0)
894: {
895: printk("%s: i596 interrupt, timeout status %4.4x command %4.4x.\n", dev->name, lp->scb.status, lp->scb.command);
896: break;
897: }
898: lp->scb.command = ack_cmd;
899:
900: (void) inb (ioaddr+0x10);
901: outb (4, ioaddr+0xf);
902: outw (0, ioaddr+4);
903:
904: if (i596_debug > 4)
905: printk("%s: exiting interrupt.\n", dev->name);
906:
907: dev->interrupt = 0;
908: return;
909: }
910:
911: static int
912: i596_close(struct device *dev)
913: {
914: int ioaddr = dev->base_addr;
915: struct i596_private *lp = (struct i596_private *)dev->priv;
916: int boguscnt = 200;
917:
918: dev->start = 0;
919: dev->tbusy = 1;
920:
921: if (i596_debug > 1)
922: printk("%s: Shutting down ethercard, status was %4.4x.\n",
923: dev->name, lp->scb.status);
924:
925: lp->scb.command = CUC_ABORT|RX_ABORT;
926: outw(0, ioaddr+4);
927:
928: i596_cleanup_cmd(lp);
929:
930: while (lp->scb.status, lp->scb.command)
931: if (--boguscnt == 0)
932: {
933: printk("%s: close timed out with status %4.4x, cmd %4.4x.\n",
934: dev->name, lp->scb.status, lp->scb.command);
935: break;
936: }
937: free_irq(dev->irq, NULL);
938: irq2dev_map[dev->irq] = 0;
939: remove_rx_bufs(dev);
940: MOD_DEC_USE_COUNT;
941:
942: return 0;
943: }
944:
945: static struct enet_statistics *
946: i596_get_stats(struct device *dev)
947: {
948: struct i596_private *lp = (struct i596_private *)dev->priv;
949:
950: return &lp->stats;
951: }
952:
953: /*
954: * Set or clear the multicast filter for this adaptor.
955: */
956:
957: static void set_multicast_list(struct device *dev)
958: {
959: struct i596_private *lp = (struct i596_private *)dev->priv;
960: struct i596_cmd *cmd;
961:
962: if (i596_debug > 1)
963: printk ("%s: set multicast list %d\n", dev->name, dev->mc_count);
964:
965: if (dev->mc_count > 0)
966: {
967: struct dev_mc_list *dmi;
968: char *cp;
969: cmd = (struct i596_cmd *) kmalloc(sizeof(struct i596_cmd)+2+dev->mc_count*6, GFP_ATOMIC);
970: if (cmd == NULL)
971: {
972: printk ("%s: set_multicast Memory squeeze.\n", dev->name);
973: return;
974: }
975: cmd->command = CmdMulticastList;
976: *((unsigned short *) (cmd + 1)) = dev->mc_count * 6;
977: cp=((char *)(cmd + 1))+2;
978: for(dmi=dev->mc_list;dmi!=NULL;dmi=dmi->next)
979: {
980: memcpy(cp, dmi,6);
981: cp+=6;
982: }
1.1.1.2 root 983: print_eth (((unsigned char *)(cmd + 1)) + 2);
1.1 root 984: i596_add_cmd(dev, cmd);
985: }
986: else
987: {
988: if (lp->set_conf.next != (struct i596_cmd * ) I596_NULL)
989: return;
990: if (dev->mc_count == 0 && !(dev->flags&(IFF_PROMISC|IFF_ALLMULTI)))
991: {
992: if(dev->flags&IFF_ALLMULTI)
993: dev->flags|=IFF_PROMISC;
994: lp->i596_config[8] &= ~0x01;
995: }
996: else
997: lp->i596_config[8] |= 0x01;
998:
999: i596_add_cmd(dev, &lp->set_conf);
1000: }
1001: }
1002:
1003: #ifdef HAVE_DEVLIST
1004: static unsigned int apricot_portlist[] = {0x300, 0};
1005: struct netdev_entry apricot_drv =
1006: {"apricot", apricot_probe, APRICOT_TOTAL_SIZE, apricot_portlist};
1007: #endif
1008:
1009: #ifdef MODULE
1010: static char devicename[9] = { 0, };
1011: static struct device dev_apricot = {
1012: devicename, /* device name inserted by /linux/drivers/net/net_init.c */
1013: 0, 0, 0, 0,
1014: 0x300, 10,
1015: 0, 0, 0, NULL, apricot_probe };
1016:
1017: static int io = 0x300;
1018: static int irq = 10;
1019:
1020: int
1021: init_module(void)
1022: {
1023: dev_apricot.base_addr = io;
1024: dev_apricot.irq = irq;
1025: if (register_netdev(&dev_apricot) != 0)
1026: return -EIO;
1027: return 0;
1028: }
1029:
1030: void
1031: cleanup_module(void)
1032: {
1033: unregister_netdev(&dev_apricot);
1034: kfree_s((void *)dev_apricot.mem_start, sizeof(struct i596_private) + 0xf);
1035: dev_apricot.priv = NULL;
1036:
1037: /* If we don't do this, we can't re-insmod it later. */
1038: release_region(dev_apricot.base_addr, APRICOT_TOTAL_SIZE);
1039: }
1040: #endif /* MODULE */
1041:
1042: /*
1043: * Local variables:
1044: * compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O6 -m486 -c apricot.c"
1045: * End:
1046: */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.