|
|
1.1 root 1: /*
2: * DEQNA Ethernet Communications Controller interface,
3: * vaguely derived from the driver in Ultrix.
4: * Each DEQNA has eight minor devices starting at N*8;
5: * the different channels may be caused to receive different
6: * Ethernet protocols via ENIOTYPE.
7: * Packets read or written have the Ethernet header in front.
8: */
9:
10: #include "sys/param.h"
11: #include "sys/buf.h"
12: #include "sys/stream.h"
13: #include "sys/ubaddr.h"
14: #include "sys/conf.h"
15: #include "sys/enio.h"
16: #include "sys/deqna.h"
17: #include "sys/ethernet.h"
18:
19: struct qedevice {
20: unsigned short qe_sta_addr[2]; /* ethernet addr; 6 shorts, overlaid */
21: unsigned short qe_rcvlist_lo; /* rcv list addr */
22: unsigned short qe_rcvlist_hi;
23: unsigned short qe_xmtlist_lo; /* xmt list addr */
24: unsigned short qe_xmtlist_hi;
25: unsigned short qe_vector;
26: unsigned short qe_csr;
27: };
28:
29: /*
30: * qe_csr
31: */
32: #define QE_RCV_ENABLE 0x0001 /* receiver enable */
33: #define QE_RESET 0x0002 /* controller reset */
34: #define QE_NEX_MEM_INT 0x0004 /* non-existent memory */
35: #define QE_XL_INVALID 0x0010 /* nothing left to transmit */
36: #define QE_RL_INVALID 0x0020 /* no buffers left to receive */
37: #define QE_INT_ENABLE 0x0040 /* interrupt enable */
38: #define QE_XMIT_INT 0x0080 /* intr because xmit finished */
39: #define QE_ILOOP 0x0100 /* internal loopback disable */
40: #define QE_ELOOP 0x0200 /* external loopback enable */
41: #define QE_RCV_INT 0x8000 /* intr because rcv finished */
42:
43: /*
44: * bits to shove into qe_csr for normal operation
45: */
46: int qebits = QE_RCV_ENABLE|QE_INT_ENABLE|QE_ILOOP;
47: /*
48: * interrupt request bits:
49: * after an interrupt, write the ones that are set
50: * to allow the next interrupt
51: */
52: #define INTFLAGS (QE_XMIT_INT|QE_RCV_INT)
53:
54: /*
55: * buffer descriptor
56: * flag is who owns it;
57: * the rest is where the data is, and how big
58: * they may be a list, or a chain.
59: * we just use a ring; the DEQNA thinks it's a list,
60: * but the chain flag is used to sew the ring together that the end
61: */
62:
63: struct qe_ring {
64: short flag;
65: short hiaddr; /* and descriptor type flags */
66: short loaddr;
67: short len; /* negative length */
68: unsigned short status1;
69: unsigned short status2;
70: };
71:
72: /*
73: * flags: just descriptor ownership
74: */
75:
76: #define FREADY 0x8000 /* descriptor ready, port not using yet */
77:
78: /*
79: * descriptor type flags, in hiaddr
80: */
81:
82: #define DVALID 0x8000 /* valid descriptor */
83: #define DCHAIN 0x4000 /* chain: address is that of next descriptor */
84: #define DEND 0x2000 /* end of message; push output packet */
85: #define DSETUP 0x1000 /* this is a setup packet */
86: #define DENDODD 0x80 /* buffer ends on odd address */
87: #define DBEGODD 0x40 /* buffer begins on odd address */
88:
89: /*
90: * status1 when we write it
91: */
92: #define NOTYET 0x8000 /* descriptor ready, but DEQNA hasn't taken it */
93: /*
94: * status1 when DEQNA is through
95: */
96: #define NOTLAST 0x8000 /* rcv: not the last descriptor of a packet */
97: #define ERROR 0x4000 /* either: some error happened */
98: #define ESETUP 0x2000 /* rcv: setup packet acknowledgement */
99: #define RHILEN 0x0700 /* rcv: high bits of received packet length */
100:
101: /*
102: * status2 when we write it
103: */
104: #define S2MAGIC 1 /* write this there to make descriptor ready. why? */
105: /*
106: * status2 when DEQNA is through
107: */
108: #define RLOLEN 0x00ff /* rcv: low bits of received length */
109:
110: #define RMINLEN 60 /* add this to get real received packet length */
111:
112: /*
113: * operating condition set-up bits
114: */
115: #define ALLM 0x1 /* match all multicast addresses */
116: #define PROM 0x2 /* match all addresses (promiscuous mode) */
117:
118: /*
119: * setup packet:
120: * lists the addresses we may receive
121: * each column (sic) of the array contains an address
122: * e.g. setup[1][0..5]
123: * setup[0][*] and setup[*][6..7] are junk
124: */
125:
126: struct setup {
127: char d[16][8];
128: };
129:
130: /*
131: * data accessed directly by the DEQNA:
132: * the buffer descriptors and the setup packet
133: */
134:
135: struct qeio {
136: struct qe_ring rring[QENRCV+1];
137: struct qe_ring xring[QENXMT+1];
138: struct setup setup;
139: };
140:
141: /*
142: * This constant should really be 60 because the qna adds 4 bytes of crc.
143: * However when set to 60 our packets are ignored by deuna's , 3coms are
144: * okay ??????????????????????????????????????????
145: */
146: #define ETHERMINTU 64
147: #define ETHERMAXTU 1564
148: #define MAX_RCV_BYTES (3*ETHERMAXTU) /* maximum bytes in receive ring */
149: int nRCV = QENRCV;
150: int nXMT = QENXMT;
151:
152: struct qechan *qefindchan();
153:
154: extern int qecnt;
155: extern struct qe qe[];
156: extern struct ubaddr qeaddr[];
157:
158: #define NEXTCH(c) (((c)+1)%QENCHAN) /* next channel */
159:
160: /* flag settings */
161: #define ATTACHED 0x4
162: #define SETUPQD 0x8
163:
164: /* handy macros for ring management */
165: #define NFREE(s) ((s)->xindex>=(s)->oxindex?(QENXMT-((s)->xindex-(s)->oxindex)-1):\
166: ((s)->oxindex-(s)->xindex-1))
167: #define NEXTRCV(c) (((c)+1)%QENRCV)
168: #define NEXTXMT(c) (((c)+1)%QENXMT)
169:
170: long qeopen();
171: int qeclose(), qeput();
172: static struct qinit qerinit = { noput, NULL, qeopen, qeclose, 0, 0 };
173: static struct qinit qewinit = { qeput, NULL, qeopen, qeclose, 4*ETHERMAXTU, 64 };
174: static struct streamtab qesinfo = { &qerinit, &qewinit };
175: struct cdevsw qecdev = cstrinit(&qesinfo);
176:
177: /* open a channel */
178: long
179: qeopen(q, dev)
180: register struct queue *q;
181: register dev_t dev;
182: {
183: register struct qechan *cp;
184: register struct qe *qp;
185: int unit, chan;
186:
187: dev = minor(dev);
188: chan = dev % QENCHAN;
189: unit = dev / QENCHAN;
190: if(unit >= qecnt)
191: return(0);
192: if (qeinit(unit) == 0)
193: return (0);
194: qp = &qe[unit];
195: cp = &qp->chan[chan];
196: if(cp->rq)
197: return(0);
198: cp->unit = unit;
199: cp->type = 0;
200: q->ptr = (caddr_t)cp;
201: WR(q)->ptr = (caddr_t)cp;
202: WR(q)->flag |= QDELIM|QBIGB;
203: q->flag |= QDELIM;
204: cp->rq = q;
205: return(1);
206: }
207:
208: qeclose(q)
209: register struct queue *q;
210: {
211: register struct qechan *cp;
212:
213: cp = (struct qechan *)q->ptr;
214: cp->rq = 0;
215: cp->type = 0;
216: }
217:
218: /*
219: * init a controller--
220: * grab and map a buffer for qeio
221: * reset the device and send it a setup packet
222: */
223: qeinit(unit)
224: int unit;
225: {
226: register struct qedevice *addr;
227: register struct qe *qp;
228: register uaddr_t ua;
229:
230: qp = &qe[unit];
231: if (qp->addr)
232: return (1);
233: if ((addr = (struct qedevice *)ubaddr(&qeaddr[unit])) == 0
234: || badaddr(&addr->qe_sta_addr[0], sizeof(short))) {
235: printf("deqna %d absent\n", unit);
236: return (0);
237: }
238: qp->intvec = qeaddr[unit].vec;
239: qp->ubno = qeaddr[unit].ubno;
240: if (qp->iobuf == NULL) {
241: qp->iobuf = geteblk();
242: qp->iobm = ubmbuf(qp->ubno, qp->iobuf, 0);
243: ua = ubadbuf(qp->ubno, qp->iobuf, qp->iobm);
244: qp->rring = ((struct qeio *)(qp->iobuf->b_un.b_addr))->rring;
245: qp->xring = ((struct qeio *)(qp->iobuf->b_un.b_addr))->xring;
246: qp->setup = &((struct qeio *)(qp->iobuf->b_un.b_addr))->setup;
247: qp->raddr = (uaddr_t)((struct qeio *)ua)->rring;
248: qp->xaddr = (uaddr_t)((struct qeio *)ua)->xring;
249: qp->setupaddr = (uaddr_t)&((struct qeio *)ua)->setup;
250: }
251: qp->addr = addr;
252: addr->qe_csr = QE_RESET;
253: addr->qe_csr = 0; /* clear RESET to make reset happen */
254: qemkrings(qp);
255: qemksetup(qp);
256: qeenable(qp);
257: return (1);
258: }
259:
260: /*
261: * make the setup packet
262: * receive from our address, and from the broadcast address
263: */
264: qemksetup(qp)
265: register struct qe *qp;
266: {
267: register struct setup *sp;
268: register int i, j;
269:
270: sp = qp->setup;
271: /*
272: * fetch our Ethernet address into column 1
273: * toss the broadcast address into column 2
274: * copy our address into the rest of the first half
275: * duplicate first half into second
276: * columns 0 and 8 are junk
277: */
278: for (i = 0; i < ETHERALEN; i++)
279: sp->d[i][1] = qp->addr->qe_sta_addr[i];
280: #ifndef NOTDEF
281: for (i = 0; i < ETHERALEN; i++)
282: sp->d[i][2] = 0xff; /* the broadcast addr */
283: for (i = 0; i < ETHERALEN; i++)
284: for (j = 3; j < 8; j++)
285: sp->d[i][j] = sp->d[i][1];
286: #else
287: for (i = 0; i < ETHERALEN; i++)
288: for (j = 2; j < 8; j++)
289: sp->d[i][j] = sp->d[i][1];
290: #endif
291: bcopy(&sp->d[0][0], &sp->d[8][0], 8*8);
292: }
293:
294: /*
295: * output put routine
296: * treasure up data till a DELIM comes,
297: * then send it all as one packet
298: */
299: qeput(q, bp)
300: register struct queue *q;
301: struct block *bp;
302: {
303: register struct qechan *cp=(struct qechan *)q->ptr;
304: int s;
305:
306: switch (bp->type) {
307: case M_IOCTL:
308: qeioctl(q, bp);
309: return;
310:
311: case M_DATA:
312: putq(q, bp);
313: if (bp->class&S_DELIM)
314: break;
315: return;
316:
317: default:
318: freeb(bp);
319: return;
320: }
321: s = spl6();
322: qestagepacket(cp);
323: while (qexmtpacket(&qe[cp->unit])==0)
324: ;
325: splx(s);
326: }
327:
328: qeioctl(q, bp)
329: register struct queue *q;
330: register struct block *bp;
331: {
332: register struct qechan *cp;
333: int i;
334: char *ap;
335:
336: cp = (struct qechan *)q->ptr;
337: bp->type = M_IOCACK;
338: switch(stiocom(bp)){
339: case ENIOTYPE:
340: cp->type = *((int *)stiodata(bp));
341: break;
342:
343: case ENIOPROM:
344: qexmtsetup(&qe[cp->unit], PROM, 1);
345: break;
346:
347: case ENIOADDR:
348: for (ap=stiodata(bp), i=0; i<ETHERALEN; i++)
349: *ap++ = qe[cp->unit].addr->qe_sta_addr[i];
350: bp->wptr = bp->rptr + ETHERALEN + STIOCHDR;
351: break;
352:
353: default:
354: bp->type = M_IOCNAK;
355: break;
356: }
357: qreply(q, bp);
358: }
359:
360: /*
361: * primitives for sending/receiving packets
362: */
363:
364: /*
365: * make a descriptor invalid
366: */
367: qeinvaldesc(rp)
368: register struct qe_ring *rp;
369: {
370: bzero((caddr_t)rp, sizeof(struct qe_ring));
371: }
372:
373: /*
374: * set up a buffer descriptor
375: * tflags are the ones in hiaddr,
376: * like `setup packet'
377: */
378: qefilldesc(rp, addr, len, tflags)
379: register struct qe_ring *rp;
380: uaddr_t addr;
381: int len;
382: int tflags;
383: {
384:
385: rp->hiaddr = tflags;
386: if (addr & 1) {
387: len++;
388: addr--;
389: rp->hiaddr |= DBEGODD;
390: }
391: if (len & 1) {
392: len++;
393: rp->hiaddr |= DENDODD;
394: }
395: rp->len = -(len/2);
396: rp->loaddr = addr;
397: rp->hiaddr |= addr >> 16;
398: rp->status2 = S2MAGIC; /* something meaningless */
399: rp->status1 = NOTYET;
400: rp->flag = FREADY;
401: rp->hiaddr |= DVALID;
402: }
403:
404: /*
405: * allocate a receive buffer
406: * and give it to the DEQNA
407: * if we're out of descriptors or are using too much memory,
408: * return quietly
409: */
410: qercvblock(qp)
411: register struct qe *qp;
412: {
413: register uaddr_t a;
414: register int len;
415: register struct block *bp;
416:
417: if (qp->rbytes>MAX_RCV_BYTES || NEXTRCV(qp->rindex)==qp->orindex)
418: return -1;
419: if ((bp = allocb(ETHERMAXTU))==NULL)
420: panic("qercvblock");
421: qp->rbp[qp->rindex] = bp;
422: a = ubadwptr(qp->ubno, bp, ubmblk(qe->ubno, bp, 0));
423: len = bp->lim - bp->wptr;
424: qefilldesc(&qp->rring[qp->rindex], a, len, 0);
425: qp->rbytes += len;
426: if ((qp->addr->qe_csr&QE_RL_INVALID) &&
427: qp->rring[qp->rindex].status1 == NOTYET) { /* wake up device */
428: a = qp->raddr + qp->rindex*sizeof(struct qe_ring);
429: qp->addr->qe_rcvlist_lo = a;
430: qp->addr->qe_rcvlist_hi = a >> 16;
431: }
432: qp->rindex = NEXTRCV(qp->rindex);
433: return 0;
434: }
435:
436: /*
437: * send a block
438: */
439: qexmtblock(qp, bp, tflags)
440: register struct qe *qp;
441: struct block *bp;
442: int tflags;
443: {
444: register uaddr_t a;
445:
446: if (qp->xring[qp->xindex].status1 == NOTYET)
447: panic("qexmitbp");
448: qp->xbp[qp->xindex] = bp;
449: a = ubadrptr(qp->ubno, bp, ubmblk(qe->ubno, bp, 0));
450: qefilldesc(&qp->xring[qp->xindex], a, bp->wptr - bp->rptr, tflags);
451: if ((qp->addr->qe_csr&QE_XL_INVALID) &&
452: qp->xring[qp->xindex].status1==NOTYET) { /* wake up device */
453: a = qp->xaddr + qp->xindex*sizeof(struct qe_ring);
454: qp->addr->qe_xmtlist_lo = (short)a;
455: qp->addr->qe_xmtlist_hi = (short)(a >> 16);
456: }
457: qp->xindex = NEXTXMT(qp->xindex);
458: }
459:
460: /*
461: * send the setup packet
462: * -- knows it's the first packet ever sent
463: */
464: qexmtsetup(qp, cmd, docmd)
465: register struct qe *qp;
466: int cmd;
467: int docmd;
468: {
469: register uaddr_t a;
470:
471: qefilldesc(&qp->xring[qp->xindex], qp->setupaddr,
472: docmd ? (128+cmd) : sizeof(struct setup), DSETUP|DEND);
473: if ((qp->addr->qe_csr&QE_XL_INVALID) &&
474: qp->xring[qp->xindex].status1==NOTYET) { /* presumably always */
475: a = qp->xaddr + qp->xindex*sizeof(struct qe_ring);
476: qp->addr->qe_xmtlist_lo = a;
477: qp->addr->qe_xmtlist_hi = a >> 16;
478: }
479: qp->xindex = NEXTXMT(qp->xindex);
480: }
481:
482: /*
483: * init the descriptor rings:
484: * clear out any stale blocks
485: * zap all the descriptors
486: * point the last descriptor at the first,
487: * forming the ring
488: */
489: qemkrings(qp)
490: register struct qe *qp;
491: {
492: register int i, ch;
493:
494: for (i=0; i<QENRCV; i++)
495: if (qp->rbp[i]) {
496: freeb(qp->rbp[i]);
497: qp->rbp[i] = NULL;
498: }
499: for (i=0; i<QENXMT; i++)
500: if (qp->xbp[i]) {
501: freeb(qp->xbp[i]);
502: qp->xbp[i] = NULL;
503: }
504: for (ch=0; ch<QENCHAN; ch++) {
505: qp->chan[ch].nxmt = 0;
506: for (i=0; i<QENXMT; i++)
507: if (qp->chan[ch].xmt[i]) {
508: freeb(qp->chan[ch].xmt[i]);
509: qp->chan[ch].xmt[i] = NULL;
510: }
511: }
512: for (i = 0 ; i < QENRCV ; i++)
513: qeinvaldesc(&qp->rring[i]);
514: qefilldesc(&qp->rring[QENRCV], qp->raddr, 0, DCHAIN);
515: for (i = 0 ; i < QENXMT ; i++)
516: qeinvaldesc(&qp->xring[i]);
517: qefilldesc(&qp->xring[QENRCV], qp->xaddr, 0, DCHAIN);
518: qp->lastch = qp->orindex = qp->oxindex = qp->xindex = qp->rindex = 0;
519: qp->rbytes = 0;
520: }
521:
522: /*
523: * turn the receiver on:
524: * enable the hardware, set up receive buffers
525: * send a setup packet
526: */
527:
528: qeenable(qp)
529: register struct qe *qp;
530: {
531:
532: qp->addr->qe_vector = qp->intvec;
533: qp->addr->qe_csr = qebits;
534: while (qercvblock(qp)==0)
535: ;
536: qexmtsetup(qp, 0, 0);
537: /*printf("qe csr after enable: %x\n", qp->addr->qe_csr);*/
538: }
539:
540: /*
541: * find a staged packet and send it
542: */
543: qexmtpacket(qp)
544: register struct qe *qp;
545: {
546: register int i;
547: register struct qechan *cp;
548:
549: /* Look for a channel that has a packet that will fit */
550: for(i=NEXTCH(qp->lastch); ; i=NEXTCH(i)) {
551: cp = &qp->chan[i];
552: if (cp->nxmt && cp->nxmt<=NFREE(qp))
553: break;
554: if (i==qp->lastch)
555: return -1;
556: }
557: qp->lastch = i;
558: qedebug(cp->xmt[0], 1, cp->nbytes);
559: for (i=0; i<cp->nxmt-1; i++) { /* send any partial pieces */
560: qexmtblock(qp, cp->xmt[i], 0);
561: cp->xmt[i] = NULL;
562: }
563: qexmtblock(qp, cp->xmt[i], DEND); /* send the last piece */
564: cp->xmt[i] = NULL;
565: cp->nxmt = 0;
566: qestagepacket(cp); /* stage the next packet for this channel */
567: return 0;
568:
569: }
570:
571: /*
572: * Here on any interrupt
573: */
574: qe0int(unit)
575: int unit;
576: {
577: register struct qe *qp = &qe[unit];
578: register int csr;
579:
580: csr = qp->addr->qe_csr;
581: qp->addr->qe_csr = qebits|(csr&INTFLAGS);
582: if( csr & QE_RCV_INT )
583: qerint(qp);
584: if( csr & QE_XMIT_INT )
585: qexint(qp);
586: if( csr & QE_NEX_MEM_INT )
587: printf("deqna %d: nxm\n", unit);
588: }
589:
590: /*
591: * transmit interrupt:
592: * free up descriptors and blocks
593: * DEQNA doesn't hear its own broadcasts,
594: * so loop them around by hand here
595: */
596: qexint(qp)
597: register struct qe *qp;
598: {
599: register int last; /* last block of packet */
600: register int first; /* first block of packet */
601: register struct qechan *cp;
602:
603: /* loop once per packet */
604: for(;;) {
605: /* loop once per block */
606: first = qp->oxindex;
607: for (last=first; ; last=NEXTXMT(last)) {
608: if (last==qp->xindex || qp->xring[last].status1==NOTYET){
609: /*
610: * nothing left
611: */
612: while (qexmtpacket(qp)==0)
613: ;
614: return;
615: }
616: if (qp->xring[last].hiaddr & DEND)
617: break;
618: }
619: /*
620: * first -> first descriptor for some packet
621: * last -> last descriptor for the same packet
622: */
623: if ((qp->xring[last].status1&ERROR) == 0)
624: qp->opackets++;
625: else {
626: printf("deqna %d: xmt err st1 %x st2 %x\n",
627: qp - qe,
628: qp->xring[last].status1,
629: qp->xring[last].status2);
630: qp->oerrors++;
631: }
632: if (qp->xring[first].hiaddr & DSETUP) { /* skip over setup packet */
633: qeinvaldesc(&qp->xring[first]); /* just one desc */
634: qp->oxindex = NEXTXMT(last);
635: continue;
636: }
637: if (qebits&QE_ELOOP) /* debuggery */
638: cp = NULL;
639: else
640: cp = qefindchan(qp, qp->xbp[first], 1);
641:
642: /* loop once per block to free (or loop back) packet */
643: for(last=NEXTXMT(last); first!=last; first=NEXTXMT(first)) {
644: /*printf("qexint: removing %d to %x\n", first, cp);*/
645: if (cp)
646: (*cp->rq->next->qinfo->putp)(cp->rq->next,qp->xbp[first]);
647: else
648: freeb(qp->xbp[first]);
649: qeinvaldesc(&qp->xring[first]);
650: qp->xbp[first] = NULL;
651: }
652: qp->oxindex = last;
653: }
654: }
655:
656: /*
657: * receiver interrupt:
658: * hand packet to the channel
659: * that wants that protocol
660: */
661: qerint(qp)
662: register struct qe *qp;
663: {
664: register int last; /* last block of packet */
665: register int first; /* first block of packet */
666: register struct qechan *cp;
667: struct qe_ring *rp;
668: struct block *bp;
669: int len;
670:
671: /* loop once per packet */
672: for(;;) {
673: /* loop once per block */
674: first = qp->orindex;
675: for (last=first; ; last=NEXTRCV(last)) {
676: if (last==qp->rindex ||
677: qp->rring[last].status1==NOTYET) {
678: /*
679: * nothing left
680: */
681: while(qercvblock(qp)==0)
682: ;
683: return;
684: }
685: if ((qp->rring[last].status1&NOTLAST) == 0)
686: break;
687: }
688: /*
689: * first -> first block of received packet
690: * last -> last block of that packet
691: */
692: if (qp->rring[last].status1&ERROR) {
693: #if NOTDEF /* usually boring */
694: printf("deqna %d: rcv err st1 %x st2 %x\n",
695: qp - qe,
696: qp->rring[last].status1,
697: qp->rring[last].status2);
698: #endif
699: cp = NULL;
700: qp->ierrors++;
701: } else if (qp->rring[last].status1&ESETUP) {
702: /* printf("qerint: setup\n");*/
703: cp = NULL;
704: } else {
705: cp = qefindchan(qp, qp->rbp[first], 0);
706: qp->ipackets++;
707: }
708:
709: /* loop once per block to receive packet */
710: if (cp) {
711: rp = &qp->rring[last];
712: len = ((rp->status1&RHILEN)|(rp->status2&RLOLEN))+RMINLEN;
713: qedebug(qp->rbp[first], 0, len);
714: }
715: /* install delimiter */
716: if (qp->rbp[last] == NULL)
717: panic("qerint");
718: qp->rbp[last]->class |= S_DELIM;
719: for(last=NEXTRCV(last); first!=last; first=NEXTRCV(first)) {
720: /*printf("qerint: received %d to %x\n", first, cp);*/
721: bp = qp->rbp[first];
722: qp->rbytes -= bp->lim - bp->wptr;
723: if (cp) {
724: rp = &qp->rring[first];
725: if (rp->status1&NOTLAST) {
726: len -= bp->lim-bp->wptr;
727: bp->wptr = bp->lim;
728: } else {
729: bp->wptr += len;
730: if (bp->wptr > bp->lim)
731: panic("qerint: length");
732: }
733: bp = cramb(bp);
734: if(cp->rq->next->flag & QFULL)
735: freeb(bp);
736: else
737: (*cp->rq->next->qinfo->putp)(cp->rq->next, bp);
738: } else
739: freeb(bp);
740: qeinvaldesc(&qp->rring[first]);
741: qp->rbp[first] = NULL;
742: }
743: qp->orindex = last;
744: }
745: }
746:
747: /*
748: * find the channel for this input packet
749: * checklocal means check that the packet was
750: * addressed to us; used for loopback
751: */
752: struct qechan *
753: qefindchan(qp, bp, checklocal)
754: register struct qe *qp;
755: struct block *bp;
756: int checklocal;
757: {
758: register int i;
759: register struct etherpup *ep=(struct etherpup *)bp->rptr;
760: register struct qechan *ch;
761:
762: /*printf("qefindchan: %x,%x,%x,%x,%x,%x:%d\n",
763: ep->dhost[0], ep->dhost[1], ep->dhost[2],
764: ep->dhost[3], ep->dhost[4], ep->dhost[5],
765: ep->type);*/
766: if (checklocal) {
767: for (i=0; i<ETHERALEN; i++) {
768: if (ep->dhost[i]!=qp->setup->d[i][1]
769: && ep->dhost[i]!=0xff) /* broadcast */
770: return NULL;
771: }
772: }
773: for (i=0, ch=qp->chan; i<QENCHAN; i++, ch++)
774: if (ch->rq!=NULL && ch->type==ep->type)
775: return (ch);
776: return NULL;
777: }
778:
779: /*
780: * stage the next packet for this channel:
781: * gather the blocks, make sure they look sensible
782: * printfs are a bit silly
783: */
784: qestagepacket(cp)
785: register struct qechan *cp;
786: {
787: register struct block *bp;
788: register int blk;
789: int nbytes;
790: register struct etherpup *ep;
791: register struct setup *sp;
792:
793: if (cp->nxmt) /* already have one staged */
794: return;
795: blk = 0;
796: nbytes = 0;
797: while ((bp = getq(WR(cp->rq))) != NULL) {
798: if (bp->type != M_DATA)
799: panic("qestagepkt");
800: if (blk >= QENXMT-1) {
801: blk = qepullup(cp);
802: if (blk >= QENXMT-1) {
803: freeb(bp); /* wrong! but too hard for now */
804: continue;
805: }
806: }
807: cp->xmt[blk++] = bp;
808: nbytes += bp->wptr-bp->rptr;
809: if ((bp->class & S_DELIM) == 0)
810: continue;
811: /*
812: * have a whole packet
813: */
814: if (nbytes > ETHERMAXTU) {
815: printf("deqna %d: packet too long\n", cp->unit);
816: break;
817: }
818: if (cp->xmt[0]->wptr-cp->xmt[0]->rptr < sizeof(struct etherpup)) {
819: printf("deqna %d: too fragmented\n", cp->unit);
820: break;
821: }
822: if (nbytes < ETHERMINTU) /* wrong, but do it anyway */
823: cp->xmt[blk-1]->wptr += ETHERMINTU-nbytes;
824: /*
825: * force our address into the packet
826: * why doesn't the hardware do this?
827: */
828: ep = (struct etherpup *)cp->xmt[0]->rptr;
829: ep->type = cp->type;
830: cp->nxmt = blk;
831: sp = qe[cp->unit].setup;
832: for(blk=0; blk < ETHERALEN; blk++)
833: ep->shost[blk] = sp->d[blk][1];
834: /*printf("qestagepacket: staged %d\n", cp->nxmt);*/
835: cp->nbytes = nbytes;
836: return;
837: }
838: /*
839: * if we come here, something went wrong
840: * any useful packet has already been removed from the queue
841: */
842: if (bp)
843: freeb(bp);
844: else if (blk!=0)
845: printf("deqna %d: stage no delim\n", cp->unit);
846: while (--blk >= 0)
847: freeb(cp->xmt[blk]);
848: cp->nxmt = 0;
849: }
850:
851: /*
852: * transmit packet came in too many pieces
853: * to fit in staging area
854: * allocate a big block,
855: * and try to squeeze some pieces into it
856: * returns the first slot now available for a block,
857: * QENXMT-1 if no space could be made
858: *
859: * assertion: no block we replace is S_DELIM
860: */
861:
862: int
863: qepullup(cp)
864: register struct qechan *cp;
865: {
866: register struct block *newbp, *bp;
867: register int blk, rep, space;
868: register int n;
869:
870: if ((newbp = allocb(ETHERMAXTU/2)) == NULL)
871: return (QENXMT-1);
872: space = newbp->lim - newbp->wptr;
873: for (blk = 0; blk < QENXMT-1; blk++) {
874: bp = cp->xmt[blk];
875: if (bp->wptr - bp->rptr < space)
876: break;
877: }
878: if (blk >= QENXMT - 1) { /* no block small enough to fit */
879: freeb(newbp);
880: return (blk);
881: }
882: /*
883: * pack as much as possible into newbp
884: */
885: rep = blk;
886: for (; blk < QENXMT-1; blk++) {
887: bp = cp->xmt[blk];
888: n = bp->wptr - bp->rptr;
889: if (n > space)
890: break;
891: bcopy(bp->rptr, newbp->wptr, n);
892: freeb(bp);
893: newbp->wptr += n;
894: space -= n;
895: }
896: /*
897: * slide remaining blocks up
898: */
899: cp->xmt[rep++] = newbp;
900: for (; blk < QENXMT-1; blk++, rep++)
901: cp->xmt[rep] = cp->xmt[blk];
902: return (rep);
903: }
904:
905: /*
906: * tracing stuff
907: */
908:
909: #include "sys/systm.h" /* for time */
910:
911: #define QEDEBSIZE 64
912: struct {
913: time_t time;
914: unsigned short code;
915: struct etherpup pup;
916: short len;
917: } qed[QEDEBSIZE];
918:
919: int qei = 0;
920:
921: qedebug(bp, code, len)
922: register struct block *bp;
923: {
924: qed[qei].time = time;
925: qed[qei].code = code;
926: qed[qei].len = len;
927: bcopy(bp->rptr, &qed[qei].pup, sizeof(qed[qei].pup));
928: qei = (qei + 1) % QEDEBSIZE;
929: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.