|
|
1.1 root 1: /*
2: * Copyright (c) 1985 by Sun Microsystems, Inc.
3: */
4: #include "le.h"
5:
6: /*
7: * AMD Am7990 LANCE Ethernet Controller driver
8: */
9: #include "../h/param.h"
10: #include "../h/systm.h"
11: #include "../machine/pte.h"
12: #include "../h/map.h"
13: #include "../h/buf.h"
14: #include "../h/vmmac.h"
15: #include "../h/conf.h"
16: #include "../h/ttyio.h"
17: #include "../h/enio.h"
18: #include "../h/ttyld.h"
19: #include "../h/stream.h"
20: #include "../h/ethernet.h"
21:
22: #include "../sundev/mbvar.h"
23: #include "../sundev/lereg.h"
24:
25: #define ETHERMAXP (1500 + sizeof(struct etherpup))
26:
27: /* corresponds to minor device numbers (# of servers) */
28: #define CHANS_PER_UNIT 8
29:
30: int leprobe(), leattach(), leintr();
31: struct mb_device *leinfo[NLE];
32: struct mb_driver ledriver = {
33: leprobe, 0, leattach, 0, 0, leintr,
34: sizeof (struct le_device), "le", leinfo, 0, 0, 0,
35: };
36:
37: /*
38: * Transmit and receive buffer layout.
39: * The buffer size is chosen to give room for the maximum ether
40: * transmission unit, an overrun consisting of the entire fifo
41: * contents, and slop that experience indicates is necessary.
42: * (The exact amount of slop required is still unknown.)
43: */
44: struct lebuf {
45: char buffer[MAXBUF]; /* Packet's data */
46: };
47:
48: struct leu {
49: struct le_device *dev; /* hardware pointer */
50: struct le_init_block *ib; /* Initialization block */
51: struct le_md *rdrp; /* Receive Descriptor Ring Ptr */
52: struct le_md *tdrp; /* Transmit Descriptor Ring Ptr */
53: struct le_md *rdrend; /* Receive Descriptor Ring End */
54: struct le_md *his_rmd; /* Next descriptor in ring */
55: int nrmdp2; /* log(2) Num. Rcv. Msg. Descs. */
56: int ntmdp2; /* log(2) Num. Tran. Msg. Descs. */
57: int nrmds; /* Num. Rcv. Msg. Descs. */
58: int ntmds; /* Num. Xmit. Msg. Descs. */
59: struct lebuf *rbufs; /* Receive Buffers */
60: struct lebuf *tbufs; /* Transmit Buffers */
61: /* Error counters */
62: int frame; /* Receive Framing Errors (dribble) */
63: int crc; /* Receive CRC Errors */
64: int oflo; /* Receive overruns */
65: int uflo; /* Transmit underruns */
66: int retries; /* Transmit retries */
67: int missed; /* Number of missed packets */
68: int noheartbeat; /* Number of nonexistent heartbeats */
69: int ierrors, oerrors;
70: int ipackets, opackets;
71: char myetheradr[6];
72: char attached;
73: char active;
74: } leu[NLE];
75:
76: #define NLECHAN (CHANS_PER_UNIT * NLE)
77: struct lechan {
78: struct leu *leu;
79: int packets;
80: struct queue *q;
81: int type;
82: } lechan[NLECHAN];
83:
84: int nodev(), leopen(), leclose(), leput();
85: static struct qinit lerinit = { nodev, NULL, leopen, leclose, 0, 0 };
86: static struct qinit lewinit = { leput, NULL, leopen, leclose, 1514, 0 };
87: /* 1514 bytes is minimum highwater mark to send 1514 byte packets */
88: struct streamtab lesinfo = { &lerinit, &lewinit };
89:
90: /*
91: * Resource amounts.
92: */
93: /* Numbers of ring descriptors */
94: int le_ntmdp2 = 0; /* 2 ^ 0 = 1 */
95: int le_nrmdp2 = 4; /* 2 ^ 4 = 16 */
96:
97: /*
98: * Return the address of an adjacent descriptor in the given ring.
99: */
100: #define next_rmd(lu,rmdp) ((rmdp) == (lu)->rdrend \
101: ? (lu)->rdrp : ((rmdp) + 1))
102:
103: /*
104: * Probe for device.
105: */
106: leprobe(reg)
107: caddr_t reg;
108: {
109: register struct le_device *le = (struct le_device *)reg;
110:
111: if (pokec((char *)&le->le_rdp, 0))
112: return (0);
113: return (sizeof (struct le_device));
114: }
115:
116: /*
117: * Interface exists: make available by filling in network interface
118: * record. System will initialize the interface when it is ready
119: * to accept packets.
120: */
121: leattach(md)
122: struct mb_device *md;
123: {
124: struct leu *lu = &leu[md->md_unit];
125:
126: /* Reset the chip. */
127: lu->dev = (struct le_device *)md->md_addr;
128: lu->dev->le_rap = LE_CSR0;
129: lu->dev->le_csr = LE_STOP;
130: localetheraddr(NULL, lu->myetheradr);
131: le_alloc_buffers(lu);
132: lu->attached = 1;
133: }
134:
135: /* ARGSUSED */
136: leopen(q, dev)
137: register struct queue *q;
138: register dev_t dev;
139: {
140: register struct lechan *led;
141: register struct leu *lu;
142: register unit;
143:
144: dev = minor(dev);
145: unit = dev / CHANS_PER_UNIT;
146:
147: if (dev >= NLECHAN)
148: return(0);
149: if (unit >= NLE)
150: return(0);
151:
152: lu = &leu[unit];
153: if(!lu->attached)
154: return(0);
155: led = &lechan[dev];
156: if (led->q)
157: return(0);
158: led->leu = lu;
159: led->q = q;
160: q->ptr = (caddr_t)led;
161: q->flag |= QBIGB | QDELIM;
162: WR(q)->ptr = (caddr_t)led;
163: WR(q)->flag |= QBIGB|QDELIM;
164: return(1);
165: }
166:
167: leclose(q)
168: register struct queue *q;
169: {
170: register struct lechan *led;
171:
172: led = (struct lechan *)q->ptr;
173: flushq(WR(q), 1);
174: lechan->q = NULL;
175: }
176:
177: leput(q, bp)
178: register struct queue *q;
179: register struct block *bp;
180: {
181: register struct lechan *led;
182: register struct leu *lu;
183: register s;
184:
185: led = (struct lechan *)q->ptr;
186: lu = led->leu;
187:
188: switch(bp->type) {
189:
190: case M_IOCTL:
191: leioctl(q, bp);
192: return;
193:
194: case M_DATA:
195: putq(q, bp);
196: return;
197:
198: case M_DELIM:
199: break;
200:
201: default:
202: freeb(bp);
203: return;
204: }
205:
206: putq(q, bp);
207: s = splimp();
208: led->packets++;
209: if (lu->active == 0)
210: lestart(lu);
211: splx(s);
212: }
213:
214: /*
215: * Grab memory for message descriptors and buffers and set fields
216: * in the interfaces's software status structure accordingly.
217: */
218: le_alloc_buffers(lu)
219: register struct leu *lu;
220: {
221: int size;
222: int memall();
223: caddr_t wmemall(), v;
224:
225: /* Set numbers of message descriptors. */
226: lu->nrmdp2 = le_nrmdp2;
227: lu->ntmdp2 = le_ntmdp2;
228: lu->nrmds = 1 << lu->nrmdp2;
229: lu->ntmds = 1 << lu->ntmdp2;
230:
231: size = sizeof(struct le_md) * (lu->nrmds + lu->ntmds) +
232: sizeof(struct lebuf) * (lu->nrmds + lu->ntmds) +
233: sizeof(struct le_init_block);
234: v = wmemall(memall, size);
235:
236: #define valloc(name, type, num) \
237: (name) = (type *)(v); (v) = (caddr_t)((name)+(num))
238:
239: valloc(lu->rdrp, struct le_md , lu->nrmds);
240: valloc(lu->tdrp, struct le_md , lu->ntmds);
241: valloc(lu->ib, struct le_init_block , 1);
242: valloc(lu->rbufs, struct lebuf , lu->nrmds);
243: valloc(lu->tbufs, struct lebuf , lu->ntmds);
244:
245: /*
246: * Remember address of last descriptor in the ring for
247: * ease of bumping pointers around the ring.
248: */
249: lu->rdrend = &((lu->rdrp)[lu->nrmds-1]);
250: leinit(lu);
251: }
252:
253: /*
254: * Initialization of interface; clear recorded pending
255: * operations.
256: */
257: leinit(lu)
258: register struct leu *lu;
259: {
260: register struct le_device *le;
261: register struct le_init_block *ib;
262: register int s;
263: register struct lebuf *bp;
264: register struct le_md *md;
265: int i;
266:
267: s = splimp();
268:
269: le = lu->dev;
270: le->le_csr = LE_STOP; /* reset the chip */
271:
272: /*
273: * Reset message descriptors.
274: */
275: lu->his_rmd = lu->rdrp;
276:
277: /* Construct the initialization block */
278: ib = lu->ib;
279: bzero((caddr_t)ib, sizeof (struct le_init_block));
280:
281: ib->ib_padr[0] = lu->myetheradr[1];
282: ib->ib_padr[1] = lu->myetheradr[0];
283: ib->ib_padr[2] = lu->myetheradr[3];
284: ib->ib_padr[3] = lu->myetheradr[2];
285: ib->ib_padr[4] = lu->myetheradr[5];
286: ib->ib_padr[5] = lu->myetheradr[4];
287:
288: /* No multicast filter yet, FIXME MULTICAST, leave zeros. */
289:
290: ib->ib_rdrp.drp_laddr = (long)lu->rdrp;
291: ib->ib_rdrp.drp_haddr = (long)lu->rdrp >> 16;
292: ib->ib_rdrp.drp_len = (long)lu->nrmdp2;
293: ib->ib_tdrp.drp_laddr = (long)lu->tdrp;
294: ib->ib_tdrp.drp_haddr = (long)lu->tdrp >> 16;
295: ib->ib_tdrp.drp_len = (long)lu->ntmdp2;
296:
297: /* Clear all the descriptors */
298: bzero((caddr_t)lu->rdrp, lu->nrmds * sizeof (struct le_md));
299: bzero((caddr_t)lu->tdrp, lu->ntmds * sizeof (struct le_md));
300:
301: /* Hang out the receive buffers. */
302: for(i = 0; i < lu->nrmds; i++) {
303: bp = &lu->rbufs[i];
304: md = &lu->rdrp[i];
305: md->lmd_ladr = (u_short) bp;
306: md->lmd_hadr = (long)bp >> 16;
307: md->lmd_bcnt = -MAXBUF;
308: md->lmd_mcnt = 0;
309: md->lmd_flags = LMD_OWN;
310: }
311: lu->his_rmd == lu->rdrp;
312:
313: /* Transmit md intialization */
314: for(i = 0; i < lu->ntmds; i++) {
315: bp = &lu->tbufs[i];
316: md = &lu->tdrp[i];
317: md->lmd_ladr = (u_short) bp;
318: md->lmd_hadr = (long)bp >> 16;
319: }
320:
321: /* Give the init block to the chip */
322: le->le_rap = LE_CSR1; /* select the low address register */
323: le->le_rdp = (long)ib & 0xffff;
324:
325: le->le_rap = LE_CSR2; /* select the high address register */
326: le->le_rdp = ((long)ib >> 16) & 0xff;
327:
328: le->le_rap = LE_CSR3; /* Bus Master control register */
329: le->le_rdp = LE_BSWP;
330:
331: le->le_rap = LE_CSR0; /* main control/status register */
332: le->le_csr = LE_INIT;
333:
334: for (i = 10000; ! (le->le_csr & LE_IDON); i-- )
335: if (i <= 0)
336: panic("le: chip didn't initialize");
337: le->le_csr = LE_IDON; /* Now reset the interrupt */
338: lu->active = 0;
339: /* (Re)start the chip. */
340: le->le_csr = LE_STRT | LE_INEA;
341: (void) splx(s);
342: }
343:
344: /*
345: * Start or restart output on interface.
346: * If interface is already active, then this is a nop.
347: * If interface is not already active, get another packet
348: * to send from the interface queue, and map it to the
349: * interface before starting the output.
350: */
351: lestart(lu)
352: register struct leu *lu;
353: {
354: register char *to;
355: register struct lechan *led;
356: register struct queue *q;
357: register struct block *bp;
358: register count, i;
359: struct le_device *le;
360: register struct le_md *t;
361:
362: led = &lechan[(lu - leu) * CHANS_PER_UNIT];
363: for(i = 0; i < CHANS_PER_UNIT; i++, led++)
364: if (led->q && led->packets > 0)
365: break;
366: if (i >= CHANS_PER_UNIT)
367: return;
368:
369: led->packets--;
370: q = WR(led->q);
371:
372: le = (struct le_device *)lu->dev;
373: to = lu->tbufs->buffer;
374: count = 0;
375: while (bp = getq(q)) {
376: if (bp->type == M_DELIM) {
377: freeb(bp);
378: break;
379: }
380: i = bp->wptr - bp->rptr;
381: /*
382: * If larger than maximum packet, throw out extra
383: */
384: if (count + i > ETHERMAXP) {
385: i = ETHERMAXP - count;
386: bcopy(bp->rptr, to, i);
387: count += i;
388: freeb(bp);
389: while (bp = getq(q)) {
390: if (bp->type == M_DELIM) {
391: freeb(bp);
392: break;
393: }
394: freeb(bp);
395: }
396: break;
397: }
398: bcopy(bp->rptr, to, i);
399: to += i;
400: count += i;
401: freeb(bp);
402: }
403:
404: /* if there is no ethernet header in packet, throw it out */
405: if (count < sizeof(struct etherpup))
406: return;
407: if (count < 60)
408: count = 60;
409:
410: to = lu->tbufs->buffer + 6;
411: bcopy(lu->myetheradr, to, 6);
412: t = lu->tdrp;
413: if (t->lmd_flags & LMD_OWN)
414: panic("lestart: tmd ownership conflict");
415: t->lmd_bcnt = -count;
416: t->lmd_flags3 = 0;
417: t->lmd_flags = 0;
418: t->lmd_flags = LMD_STP|LMD_ENP;
419: t->lmd_flags |= LMD_OWN;
420: lu->active = 1;
421: le->le_csr = LE_TDMD | LE_INEA;
422:
423: }
424:
425: /*
426: * interrupt routine
427: */
428: leintr()
429: {
430: register struct leu *lu;
431: register struct le_device *le;
432: register struct le_md *lmd;
433: register struct mb_device *md;
434: int serviced = 0;
435:
436: lu = leu;
437: for (lu = leu; lu < &leu[NLE]; lu++) {
438: if (!lu->attached)
439: continue;
440: le = lu->dev;
441: if (!(le->le_csr & LE_INTR))
442: continue;
443:
444: /* Keep statistics for lack of heartbeat */
445: if (le->le_csr & LE_CERR) {
446: le->le_csr = LE_CERR | LE_INEA;
447: lu->noheartbeat++;
448: }
449:
450: /* Check for receive activity */
451: if ( (le->le_csr & LE_RINT) && (le->le_csr & LE_RXON) ) {
452: /* Pull packets off interface */
453: for (lmd = lu->his_rmd;
454: !(lmd->lmd_flags & LMD_OWN);
455: lu->his_rmd = lmd = next_rmd(lu, lmd)) {
456: serviced = 1;
457: le->le_csr = LE_RINT | LE_INEA;
458: leread(lu, lmd);
459: lmd->lmd_mcnt = 0;
460: lmd->lmd_flags = LMD_OWN;
461: }
462: if (!serviced)
463: panic("RINT with buffer owned by chip");
464: }
465:
466: /* Check for transmit activity */
467: if ((le->le_csr & LE_TINT) && (le->le_csr & LE_TXON)) {
468: lmd = lu->tdrp;
469: if (lmd->lmd_flags & (TMD_MORE | TMD_ONE))
470: lu->retries++;
471: if (lmd->lmd_flags3 &
472: (TMD_BUFF|TMD_UFLO|TMD_LCOL|TMD_LCAR|TMD_RTRY))
473: le_xmit_error(lu, lmd->lmd_flags3, le);
474: le->le_csr = LE_TINT | LE_INEA;
475: lu->active = 0;
476: lu->opackets++;
477: lestart(lu);
478: serviced = 1;
479: }
480:
481: /*
482: * Check for errors not specifically related
483: * to transmission or reception.
484: */
485: if ( (le->le_csr & (LE_BABL|LE_MERR|LE_MISS|LE_TXON|LE_RXON))
486: != (LE_RXON|LE_TXON) ) {
487: serviced = 1;
488: le_chip_error(lu, le);
489: }
490: }
491: return (serviced);
492: }
493:
494: /*
495: * Move info from driver toward protocol interface
496: */
497: leread(lu, rmd)
498: register struct leu *lu;
499: register struct le_md *rmd;
500: {
501: register struct lechan *led;
502: register struct queue *q;
503: register struct block *bp;
504: register short type;
505: register caddr_t from;
506: register len, i;
507:
508: /* Check for packet errors. */
509: if ((rmd->lmd_flags & ~RMD_OFLO) != (LMD_STP|LMD_ENP)) {
510: le_rcv_error(lu, rmd->lmd_flags);
511: lu->ierrors++;
512: return;
513: }
514:
515: /*
516: * Get input data length (minus crc)
517: */
518: len = rmd->lmd_mcnt - 4; /* subtract off trailing crc */
519: if (len == 0) {
520: printf("runt packet\n");
521: lu->ierrors++;
522: return;
523: }
524:
525: from = (caddr_t)lu->rbufs[rmd - lu->rdrp].buffer;
526: type = ((struct etherpup *)from)->type;
527: led = &lechan[(lu - leu) * CHANS_PER_UNIT];
528: for (i = 0; i < CHANS_PER_UNIT; i++, led++)
529: if (led->q && led->type == type)
530: break;
531: if (i >= CHANS_PER_UNIT)
532: return;
533: q = led->q;
534: if (q->next->flag & QFULL) {
535: lu->ierrors++;
536: return;
537: }
538: while (len > 0) {
539: bp = allocb(len);
540: i = MIN((bp->lim - bp->base), len);
541: len -= i;
542: bcopy(from, bp->wptr, i);
543: bp->wptr += i;
544: from += i;
545: (*q->next->qinfo->putp)(q->next, bp);
546: }
547: if (putctl(q->next, M_DELIM))
548: lu->ipackets++;
549: else
550: printf("leread no DELIM bp\n");
551: }
552:
553: /*
554: * Process an ioctl request.
555: */
556: leioctl(q, bp)
557: register struct queue *q;
558: register struct block *bp;
559: {
560: register struct lechan *led;
561: register struct leu *lu;
562: register u_char *msg;
563: int cmd;
564:
565: led = (struct lechan *)q->ptr;
566: lu = led->leu;
567: cmd = ((union stmsg *)(bp->rptr))->ioc1.com;
568: msg = (u_char *)&((union stmsg *)(bp->rptr))->ioc1.sb;
569:
570: bp->type = M_IOCACK;
571: switch (cmd) {
572: case ENIOADDR: /* get my Ethernet address */
573: bcopy(lu->myetheradr, (int *)msg, 6);
574: break;
575:
576: case ENIOTYPE:
577: led->type = *(int *)msg;
578: break;
579:
580: default:
581: bp->type = M_IOCNAK;
582: break;
583: }
584: qreply(q, bp);
585: }
586:
587: le_rcv_error(lu, flags)
588: struct leu *lu;
589: u_char flags;
590: {
591: if (flags & RMD_FRAM)
592: lu->frame++;
593: if (flags & RMD_CRC )
594: lu->crc++;
595: if (flags & RMD_OFLO)
596: lu->oflo++;
597: if (flags & RMD_BUFF)
598: printf("Receive buffer error - BUFF bit set in rmd\n");
599: if (!(flags & LMD_STP))
600: printf("Received packet with STP bit in rmd cleared\n");
601: if (!(flags & LMD_ENP))
602: printf("Received packet with ENP bit in rmd cleared\n");
603: }
604:
605: le_xmit_error(lu, flags, le)
606: struct leu *lu;
607: u_short flags;
608: struct le_device *le;
609: {
610: /*
611: * The BUFF bit isn't valid if the RTRY bit is set.
612: */
613: if ((flags & (TMD_BUFF | TMD_RTRY)) == TMD_BUFF)
614: printf("Transmit buffer error - BUFF bit set in tmd\n");
615: if (flags & TMD_UFLO) {
616: printf("Transmit underflow error\n");
617: lu->uflo++;
618: }
619: if (flags & TMD_LCOL)
620: printf("Transmit late collision - net problem?\n");
621: if (flags & TMD_LCAR)
622: printf("No carrier - transceiver cable problem?\n");
623: if (flags & TMD_RTRY)
624: printf("Transmit retried more than 16 times - net jammed\n");
625: }
626:
627: /* Handles errors that are reported in the chip's status register */
628: /* ARGSUSED */
629: le_chip_error(lu, le)
630: struct leu *lu;
631: struct le_device *le;
632: {
633: register u_short csr = le->le_csr;
634: int restart = 0;
635:
636: if (csr & LE_MISS) {
637: lu->missed++;
638: le->le_csr = LE_MISS | LE_INEA;
639: }
640:
641: if (csr & LE_BABL) {
642: printf("Babble error - sent a packet longer than the maximum length\n");
643: le->le_csr = LE_BABL | LE_INEA;
644: }
645: /*
646: * If a memory error has occurred, both the transmitter
647: * and the receiver will have shut down.
648: */
649: if (csr & LE_MERR) {
650: printf("Memory Error! Ethernet chip memory access timed out\n");
651: le->le_csr = LE_MERR | LE_INEA;
652: }
653: if ( !(csr & LE_RXON) ) {
654: printf("Reception stopped\n");
655: restart++;
656: }
657: if ( !(csr & LE_TXON) ) {
658: printf("Transmission stopped\n");
659: restart++;
660: }
661: if (restart) {
662: le_print_csr(csr);
663: leinit(lu);
664: }
665: }
666:
667: /*
668: * Print out a csr value in a nicely formatted way.
669: */
670: le_print_csr (csr)
671: register u_short csr;
672: {
673: printf("csr: %b\n", csr,
674: "\20\20ERR\17BABL\16CERR\15MISS\14MERR\13RINT\12TINT\11IDON\10INTR\7INEA\6RXON\5TXON\4TDMD\3STOP\2STRT\1INIT\n");
675: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.