## diffname port/devlance.c 1990/0227 ## diff -e /dev/null /n/bootesdump/1990/0227/sys/src/9/mips/devlance.c 0a #include "u.h" #include "lib.h" #include "mem.h" #include "dat.h" #include "fns.h" #include "io.h" #include "errno.h" #include "devtab.h" /* * configuration parameters */ enum { Ntypes= 8, /* max number of ethernet packet types */ LogNrrb= 7, /* log of number of receive buffers */ Nrrb= (1<>16)&0xF) #define LADDR(a) (((ulong)a)&0xFFFF) /* * one per ethernet packet type */ typedef struct { QLock; int type; /* ethernet type */ Queue *q; } Ethertype; /* * circular debug queue (first 44 bytes of the last Ndpkt packets) */ typedef struct { uchar d[6]; uchar s[6]; uchar type[2]; uchar data[40]; } Dpkt; typedef struct { Lock; int next; char *tag[Ndpkt]; int len[Ndpkt]; Dpkt p[Ndpkt]; } Debqueue; /* * lance state */ typedef struct { QLock; int inited; uchar ea[6]; /* our ether addr */ uchar *lmp; /* location of parity test */ ushort *rap; /* lance address register */ ushort *rdp; /* lance data register */ Rendez rr; /* rendezvous for an input buffer */ ushort rl; /* first rcv Message belonging to Lance */ ushort rc; /* first rcv Message belonging to CPU */ Pkt *rp[Nrrb]; /* receive buffers */ int inpackets; Rendez tr; /* rendezvous for an output buffer */ QLock tlock; /* semaphore on tc */ ushort tl; /* first xmt Message belonging to Lance */ ushort tc; /* first xmt Message belonging to CPU */ Pkt *tp[Ntrb]; /* transmit buffers */ int outpackets; Ethertype e[Ntypes]; int debug; int prdebug; int kstarted; Debqueue dq; } Lance; static Lance l; /* * mode bits in the lance initialization block */ #define PROM 0x8000 #define INTL 0x40 #define DRTY 0x20 #define COLL 0x10 #define DTCR 0x8 #define LOOP 0x4 #define DTX 0x2 #define DRX 0x1 /* * LANCE CSR0, this is the register we play with most often. We leave * this register pointed to by l.rap in normal operation. */ #define ERR0 0x8000 #define BABL 0x4000 #define CERR 0x2000 #define MISS 0x1000 #define MERR 0x800 #define RINT 0x400 #define TINT 0x200 #define IDON 0x100 #define INTR 0x80 #define INEA 0x40 #define RXON 0x20 #define TXON 0x10 #define TDMD 0x8 #define STOP 0x4 #define STRT 0x2 #define INIT 0x1 /* * LANCE CSR3 */ #define BSWP 0x4 #define ACON 0x2 #define BCON 0x1 /* * flag bits from a buffer descriptor in the rcv/xmt rings */ #define OWN 0x8000 /* 1 means that the buffer can be used by the chip */ #define ERR 0x4000 /* error summary, the OR of all error bits */ #define FRAM 0x2000 /* CRC error and incoming packet not a multiple of 8 bits */ #define OFLO 0x1000 /* (receive) lost some of the packet */ #define MORE 0x1000 /* (transmit) more than 1 retry to send the packet */ #define CRC 0x800 /* (receive) crc error reading packet */ #define ONE 0x800 /* (transmit) one retry to transmit the packet */ #define BUF 0x400 /* (receive) out of buffers while reading a packet */ #define DEF 0x400 /* (transmit) deffered while transmitting packet */ #define STP 0x200 /* start of packet */ #define ENP 0x100 /* end of packet */ /* * cntflags bits from a buffer descriptor in the rcv/xmt rings */ #define BUFF 0x8000 /* buffer error (host screwed up?) */ #define UFLO 0x4000 /* underflow from memory */ #define LCOL 0x1000 /* late collision (ether too long?) */ #define LCAR 0x800 /* loss of carrier (ether broken?) */ #define RTRY 0x400 /* couldn't transmit (bad station on ether?) */ #define TTDR 0x3FF /* time domain reflectometer */ /* * predeclared */ void lancekproc(void *); /* * print a packet preceded by a message */ printpacket(char *tag, Pkt *p, int len) { print("%s: %d d(%.2ux%.2ux%.2ux%.2ux%.2ux%.2ux)s(%.2ux%.2ux%.2ux%.2ux%.2ux%.2ux)t(%ux %ux)d(%.2ux%.2ux%.2ux%.2ux%.2ux%.2ux%.2ux%.2ux%.2ux%.2ux%.2ux%.2ux)\n", tag, len, p->d[0], p->d[1], p->d[2], p->d[3], p->d[4], p->d[5], p->s[0], p->s[1], p->s[2], p->s[3], p->s[4], p->s[5], p->type[0], p->type[1], p->data[0], p->data[1], p->data[2], p->data[3], p->data[4], p->data[5], p->data[6], p->data[7], p->data[8], p->data[9], p->data[10], p->data[11]); } /* * save a message in a circular queue for later debugging */ void lancedebq(char *tag, Pkt *p, int len) { lock(&l.dq); l.dq.tag[l.dq.next] = tag; l.dq.len[l.dq.next] = len; memcpy(&l.dq.p[l.dq.next], p, sizeof(Dpkt)); l.dq.next = (l.dq.next+1) % Ndpkt; unlock(&l.dq); } /* * copy to/from lance memory till we get it right */ void slowcpy(uchar *to, uchar *from, int n) { memcpy(to, from, n); while(memcmp(to, from, n)!=0){ print("lance compare error\n"); memcpy(to, from, n); } } /* * lance stream module definition */ static void lanceoput(Queue*, Block*); static void lancestopen(Queue*, Stream*); static void lancestclose(Queue*); static void stagerbuf(void); Qinfo lanceinfo = { nullput, lanceoput, lancestopen, lancestclose, "lance" }; /* * open a lance line discipline * * the lock is to synchronize changing the ethertype with * sending packets up the stream on interrupts. */ void lancestopen(Queue *q, Stream *s) { Ethertype *et; et = &l.e[s->id]; qlock(et); RD(q)->ptr = WR(q)->ptr = et; et->type = 0; et->q = RD(q); qunlock(et); } /* * close lance line discipline * * the lock is to synchronize changing the ethertype with * sending packets up the stream on interrupts. */ static void lancestclose(Queue *q) { Ethertype *et; qlock(et); et = (Ethertype *)(q->ptr); et->type = 0; et->q = 0; qunlock(et); } /* * assume the q is locked external to this routine * * the ``connect'' control message specifyies the type */ Proc *lanceout; static int isobuf(void *x) { return TSUCC(l.tc) != l.tl; } static void lanceoput(Queue *q, Block *bp ) { int n, len; Pkt *p; Msg *m; if(bp->type == M_CTL){ if(streamparse("connect", bp)){ ((Ethertype *)q->ptr)->type = strtoul((char *)bp->rptr, 0, 0); } freeb(bp); return; } /* * save up to a delim */ if(!putq(q, bp)) return; /* * only one transmitter at a time */ qlock(&l.tlock); /* * Wait till we get an output buffer */ if(TSUCC(l.tc) == l.tl){ print("lance obuf sleep"); sleep(&l.tr, isobuf, (void *)0); print("done"); } p = l.tp[l.tc]; /* * copy message into lance RAM */ len = 0; while(bp = getq(q)){ if(sizeof(Pkt) - len >= (n = bp->wptr - bp->rptr)){ slowcpy(((uchar *)p)+len, bp->rptr, n); len += n; } else print("no room damn it\n"); if(bp->flags & S_DELIM){ freeb(bp); break; } else freeb(bp); } /* * give packet a local address */ memcpy(p->s, l.ea, sizeof(l.ea)); /* * pad the packet */ if(len < 60) len = 60; lancedebq("out", p, len); /* * set up the ring descriptor and hand to lance */ m = &(LANCEMEM->tmr[l.tc]); m->size = -len; m->cntflags = 0; m->laddr = LADDR(l.tp[l.tc]); m->flags = OWN|STP|ENP|HADDR(l.tp[l.tc]); l.tc = TSUCC(l.tc); *l.rdp = INEA|TDMD; /**/ qunlock(&l.tlock); } /* * lance directory */ enum { Lchanqid = 1 }; Dirtab lancedir[Ntypes]; /* * stop the lance, disable all ring buffers, and free all staged rcv buffers */ void lancereset(void) { Lancemem *lm=LANCEMEM; int i; /* * toggle lance's reset line */ MODEREG->promenet &= ~1; MODEREG->promenet |= 1; /* * disable all ring entries */ l.tl = l.tc = 0; for(i = 0; i < Ntrb; i++) lm->tmr[i].flags = 0; l.rl = l.rc = 0; for(i = 0; i < Ntrb; i++) lm->rmr[i].flags = 0; /* * run through all lance memory to set parity */ for(l.lmp=LANCERAM; l.lmp<=LANCEEND; l.lmp++) *l.lmp = 55; } /* * Initialize and start the lance. This routine can be called at any time. * It may be used to restart a dead lance. */ static void lancestart(void) { Lancemem *lm=LANCEMEM; int i; Pkt *p; lancereset(); /* * create the initialization block */ lm->mode = 0; /* * set ether addr from the value in the id prom. * the id prom has them in reverse order, the init * structure wants them in byte swapped order */ lm->etheraddr[0] = (LANCEID[16]&0xff00)|((LANCEID[20]>>8)&0xff); lm->etheraddr[1] = (LANCEID[8]&0xff00)|((LANCEID[12]>>8)&0xff); lm->etheraddr[2] = (LANCEID[0]&0xff00)|((LANCEID[4]>>8)&0xff); l.ea[0] = LANCEID[20]>>8; l.ea[1] = LANCEID[16]>>8; l.ea[2] = LANCEID[12]>>8; l.ea[3] = LANCEID[8]>>8; l.ea[4] = LANCEID[4]>>8; l.ea[5] = LANCEID[0]>>8; /* * ignore multicast addresses */ for(i=0; i<4; i++) lm->multi[i] = 0; /* * set up rcv message ring */ p = lm->p; for(i = 0; i < Nrrb; i++){ l.rp[i] = p++; lm->rmr[i].size = -sizeof(Pkt); lm->rmr[i].cntflags = 0; lm->rmr[i].laddr = LADDR(l.rp[i]); lm->rmr[i].flags = HADDR(l.rp[i]); } lm->rdralow = LADDR(lm->rmr); lm->rdrahigh = (LogNrrb<<13)|HADDR(lm->rmr); /* * give the lance all the rcv buffers except one (as a sentinel) */ l.rc = Nrrb - 1; for(i = 0; i < l.rc; i++) lm->rmr[i].flags |= OWN; /* * set up xmit message ring */ for(i = 0; i < Ntrb; i++){ l.tp[i] = p++; lm->tmr[i].size = 0; lm->tmr[i].cntflags = 0; lm->tmr[i].laddr = LADDR(l.tp[i]); lm->tmr[i].flags = HADDR(l.tp[i]); } lm->tdralow = LADDR(lm->tmr); lm->tdrahigh = (LogNtrb<<13)|HADDR(lm->tmr); /* * so that we don't have to indirect through constants */ l.rap = LANCERAP; l.rdp = LANCERDP; /* * point lance to the initialization block */ *l.rap = 1; *l.rdp = LADDR(lm); wbflush(); *l.rap = 2; *l.rdp = HADDR(lm); /* * The lance byte swaps the ethernet packet unless we tell it not to */ wbflush(); *l.rap = 3; *l.rdp = BSWP; /* * initialize lance, turn on interrupts, turn on transmit and rcv. */ *l.rap = 0; *l.rdp = INEA|INIT|STRT; /**/ } /* * set up the free list and lance directory. * start the lance. */ void lanceinit(void) { int i; /* * staticly set up types for now */ for(i=0; idev = 0; return c; } Chan* lanceclone(Chan *c, Chan *nc) { return devclone(c, nc); } /* * if the name doesn't exist, the name is numeric, and room exists * in lancedir, create a new entry. */ int lancewalk(Chan *c, char *name) { if(c->qid == CHDIR) return devwalk(c, name, lancedir, Ntypes, devgen); else return devwalk(c, name, 0, 0, streamgen); } void lancestat(Chan *c, char *dp) { if(c->qid == CHDIR) devstat(c, dp, lancedir, Ntypes, devgen); else devstat(c, dp, 0, 0, streamgen); } /* * Pass open's of anything except the directory to streamopen */ Chan* lanceopen(Chan *c, int omode) { extern Qinfo nonetinfo; if(c->qid == CHDIR){ if(omode != OREAD) error(0, Eperm); }else streamopen(c, &lanceinfo); c->mode = openmode(omode); c->flag |= COPEN; c->offset = 0; return c; } void lancecreate(Chan *c, char *name, int omode, ulong perm) { error(0, Eperm); } void lanceclose(Chan *c) { /* real closing happens in lancestclose */ if(c->qid != CHDIR) streamclose(c); } long lanceread(Chan *c, void *a, long n) { if(c->qid == CHDIR) return devdirread(c, a, n, lancedir, Ntypes, devgen); else return streamread(c, a, n); } long lancewrite(Chan *c, void *a, long n) { return streamwrite(c, a, n); } void lanceremove(Chan *c) { error(0, Eperm); } void lancewstat(Chan *c, char *dp) { error(0, Eperm); } void lanceerrstr(Error *e, char *buf) { rooterrstr(e, buf); } void lanceuserstr(Error *e, char *buf) { consuserstr(e, buf); } /* * We will: * (1) Clear interrupt cause in the lance * (2) service all current events */ void lanceintr(void) { ushort csr; Lancemem *lm; lm = LANCEMEM; csr = *l.rdp; /* * turn off the interrupt and any error indicators */ *l.rdp = IDON|INEA|TINT|RINT|BABL|CERR|MISS|MERR; /* * see if an error occurred */ if(csr & (BABL|MISS|MERR)) print("lance err %ux\n", csr); if(csr & IDON) l.inited = 1; /* * look for rcv'd packets, just wakeup the input process */ if(l.rl!=l.rc && (lm->rmr[l.rl].flags & OWN)==0) wakeup(&l.rr); /* * look for xmitt'd packets, wake any process waiting for a * transmit buffer */ while(l.tl != l.tc && (lm->tmr[l.tl].flags & OWN) == 0){ if(lm->tmr[l.tl].flags & ERR) print("xmt error %ux %ux\n", lm->tmr[l.tl].flags, lm->tmr[l.tl].cntflags); l.tl = TSUCC(l.tl); wakeup(&l.tr); } } /* * input process, awakened on each interrupt with rcv buffers filled */ static int isinput(void *arg) { return l.rl!=l.rc && (LANCEMEM->rmr[l.rl].flags & OWN)==0; } void lancekproc(void *arg) { Block *bp; Lancemem *lm; Pkt *p; Ethertype *e; int t; Msg *m; int len; int i, last; lm = LANCEMEM; for(;;){ for(; l.rl!=l.rc && (lm->rmr[l.rl].flags & OWN)==0 ; l.rl=RSUCC(l.rl)){ l.inpackets++; m = &(lm->rmr[l.rl]); if(m->flags & ERR){ print("rcv error %ux\n", m->flags&(FRAM|OFLO|CRC|BUFF)); goto stage; } /* * See if a queue exists for this packet type. */ p = l.rp[l.rl]; t = (p->type[1]<<8) | p->type[0]; len = m->cntflags - 4; lancedebq("in", p, len); for(e = &l.e[0]; e < &l.e[Ntypes]; e++){ if(!canqlock(e)) continue; if(e->q && t == e->type) break; qunlock(e); } /* * If no match, see if any stream has type -1. * It matches all packets. */ if(e == &l.e[Ntypes]){ for(e = &l.e[0]; e < &l.e[Ntypes]; e++){ if(!canqlock(e)) continue; if(e->q && e->type == -1) break; qunlock(e); } } if(e != &l.e[Ntypes] && e->q->next->len <= Streamhi){ /* * The lock on e makes sure the queue is still there. */ bp = allocb(len); slowcpy(bp->rptr, (uchar *)p, len); bp->wptr += len; bp->flags |= S_DELIM; PUTNEXT(e->q, bp); qunlock(e); } stage: /* * stage the next input buffer */ m = &(lm->rmr[l.rc]); m->size = -sizeof(Pkt); m->cntflags = 0; m->laddr = LADDR(l.rp[l.rc]); m->flags = OWN|HADDR(l.rp[l.rc]); l.rc = RSUCC(l.rc); } if(l.prdebug){ lock(&l.dq); i = l.dq.next; do { if(l.dq.tag[i]) printpacket(l.dq.tag[i], (Pkt *)&l.dq.p[i], l.dq.len[i]); i = (i+1) % Ndpkt; } while(i != l.dq.next); unlock(&l.dq); l.prdebug = 0; } sleep(&l.rr, isinput, 0); } } void lanceparity(void) { print("lance DRAM parity error lmp=%ux\n", l.lmp); MODEREG->promenet &= ~4; MODEREG->promenet |= 4; } void LANCEDEBUG() { l.debug ^= 1; } /* * print the debug queue */ void LANCEPRDEBQ() { l.prdebug = 1; wakeup(&l.rr); } . ## diffname port/devlance.c 1990/03011 ## diff -e /n/bootesdump/1990/0227/sys/src/9/mips/devlance.c /n/bootesdump/1990/03011/sys/src/9/mips/devlance.c 753c t = (p->type[0]<<8) | p->type[1]; . ## diffname port/devlance.c 1990/03042 ## diff -e /n/bootesdump/1990/03011/sys/src/9/mips/devlance.c /n/bootesdump/1990/03042/sys/src/9/mips/devlance.c 822,837d 800,811d 782c memcpy(bp->rptr, (uchar *)p, len); . 755c lancedebq('i', p, len); . 636a } . 633,635c switch(c->qid){ case CHDIR: return devdirread(c, a, n, lancedir, Ndir, devgen); case Ltraceqid: return lancetraceread(c, a, n); default: . 629a static long lancetraceread(Chan *c, void *a, long n) { char buf[512]; long rv; int i; char *ca = a; int offset; Trace *t; int plen; rv = 0; sprintpacket(buf, l.dq.t); plen = strlen(buf); offset = c->offset % plen; for(t = &l.dq.t[c->offset/plen]; n && t < &l.dq.t[Ndpkt]; t++){ if(t->tag == 0) break; lock(&l.dq); sprintpacket(buf, t); unlock(&l.dq); i = plen - offset; if(i > n) i = n; memcpy(ca, buf + offset, i); n -= i; ca += i; rv += i; offset = 0; } return rv; } . 627a break; } . 626c switch(c->qid){ case CHDIR: case Ltraceqid: break; default: . 609a break; } . 608c break; default: . 605c switch(c->qid){ case CHDIR: case Ltraceqid: . 592c devstat(c, dp, lancedir, Ndir, devgen); . 583c return devwalk(c, name, lancedir, Ndir, devgen); . 551a strcpy(lancedir[Ntypes].name, "trace"); lancedir[Ntypes].qid = Ltraceqid; lancedir[Ntypes].length = 0; lancedir[Ntypes].perm = 0600; . 397c Dirtab lancedir[Ndir]; . 395c Lchanqid = 1, Ltraceqid = 2, . 376c lancedebq('o', p, len); . 354c memcpy(((uchar *)p)+len, bp->rptr, n); . 235,237c t = &l.dq.t[l.dq.next]; t->ticks = NOW; t->tag = tag; t->len = len; memcpy(&(t->p), p, sizeof(Dpkt)); . 233a Trace *t; . 232c lancedebq(char tag, Pkt *p, int len) . 220,225c Dpkt *p = &t->p; sprint(buf, "%c: %.8ud %.4d d(%.2ux%.2ux%.2ux%.2ux%.2ux%.2ux)s(%.2ux%.2ux%.2ux%.2ux%.2ux%.2ux)t(%.2ux %.2ux)d(%.2ux%.2ux%.2ux%.2ux%.2ux%.2ux%.2ux%.2ux%.2ux%.2ux%.2ux%.2ux)\n", t->tag, t->ticks, t->len, p->d[0], p->d[1], p->d[2], p->d[3], p->d[4], p->d[5], p->s[0], p->s[1], p->s[2], p->s[3], p->s[4], p->s[5], p->type[0],p->type[1], p->data[0], p->data[1], p->data[2], p->data[3], p->data[4], p->data[5], p->data[6], p->data[7], p->data[8], p->data[9], p->data[10], p->data[11]); . 218c sprintpacket(char *buf, Trace *t) . 139d 107,109c Trace t[Ndpkt]; . 104a ulong ticks; char tag; int len; Dpkt p; } Trace; typedef struct { . 22a #define NOW (MACHP(0)->ticks) . 18c Ndpkt= 1000, /* number of debug packets */ . 13a Ndir= Ntypes+1, /* entries in top level directory */ . ## diffname port/devlance.c 1990/0312 ## diff -e /n/bootesdump/1990/03042/sys/src/9/mips/devlance.c /n/bootesdump/1990/0312/sys/src/9/mips/devlance.c 707c return streamwrite(c, a, n, 0); . 365c if(sizeof(Pkt) - len >= (n = BLEN(bp))){ . ## diffname port/devlance.c 1990/0319 ## diff -e /n/bootesdump/1990/0312/sys/src/9/mips/devlance.c /n/bootesdump/1990/0319/sys/src/9/mips/devlance.c 608c if(c->qid==CHDIR || c->qid==Ltraceqid) . ## diffname port/devlance.c 1990/0409 ## diff -e /n/bootesdump/1990/0319/sys/src/9/mips/devlance.c /n/bootesdump/1990/0409/sys/src/9/mips/devlance.c 228,233c sprint(buf, "%c: %.8ud %.4d d(%.2ux%.2ux%.2ux%.2ux%.2ux%.2ux)s(%.2ux%.2ux%.2ux%.2ux%.2ux%.2ux)t(%.2ux %.2ux)d(", t->tag, t->ticks, t->len, p->d[0], p->d[1], p->d[2], p->d[3], p->d[4], p->d[5], p->s[0], p->s[1], p->s[2], p->s[3], p->s[4], p->s[5], p->type[0], p->type[1]); for(i=0; i<41; i++) sprint(buf+strlen(buf), "%.2ux", p->data[i]); sprint(buf+strlen(buf), ")\n"); . 226a int i; . 105c uchar data[60]; . 19c Ndpkt= 200, /* number of debug packets */ . ## diffname port/devlance.c 1990/0419 ## diff -e /n/bootesdump/1990/0409/sys/src/9/mips/devlance.c /n/bootesdump/1990/0419/sys/src/9/mips/devlance.c 479a /* print("lance addr = %.4ux %.4ux %.4ux\n", lm->etheraddr[0], lm->etheraddr[1], lm->etheraddr[2]); /**/ . ## diffname port/devlance.c 1990/0427 ## diff -e /n/bootesdump/1990/0419/sys/src/9/mips/devlance.c /n/bootesdump/1990/0427/sys/src/9/mips/devlance.c 254a /* { char buf[1024]; if(p->d[0] != 0xff){ sprintpacket(buf, t); print("%s\n", buf); } } /**/ . ## diffname port/devlance.c 1990/0707 ## diff -e /n/bootesdump/1990/0427/sys/src/9/mips/devlance.c /n/bootesdump/1990/0707/sys/src/9/mips/devlance.c 582a . 24c #define NOW (MACHP(0)->ticks*MS2HZ) . ## diffname port/devlance.c 1990/0721 ## diff -e /n/bootesdump/1990/0707/sys/src/9/mips/devlance.c /n/bootesdump/1990/0721/sys/src/9/mips/devlance.c 317a qlock(et); . 316d ## diffname port/devlance.c 1990/0722 ## diff -e /n/bootesdump/1990/0721/sys/src/9/mips/devlance.c /n/bootesdump/1990/0722/sys/src/9/mips/devlance.c 592c kproc("lancekproc", lancekproc, 0); . ## diffname port/devlance.c 1990/0826 ## diff -e /n/bootesdump/1990/0722/sys/src/9/mips/devlance.c /n/bootesdump/1990/0826/sys/src/9/mips/devlance.c 890a void lance3intr(void) { panic("lance3 interrupt\n"); } . ## diffname port/devlance.c 1990/0911 ## diff -e /n/bootesdump/1990/0826/sys/src/9/mips/devlance.c /n/bootesdump/1990/0911/sys/src/9/mips/devlance.c 890,895d 874,877c MPs(m->size) = -sizeof(Pkt); MPus(m->cntflags) = 0; MPus(m->laddr) = LADDR(l.rpa[l.rc]); MPus(m->flags) = OWN|HADDR(l.rpa[l.rc]); . 857c if(e!=&l.e[Ntypes] && e->q->next->len<=Streamhi){ . 834,835c len = MPus(m->cntflags) - 4; lancedebq('i', p, len);/**/ . 832c p = &l.rp[l.rl]; . 823,825c if(MPus(m->flags) & ERR){ t = MPus(m->flags); if(t & FRAM) l.frames++; if(t & OFLO) l.overflows++; if(t & CRC) l.crcs++; if(t & BUFF) l.buffs++; . 820c for(; l.rl!=l.rc && (MPus(lm->rmr[l.rl].flags) & OWN)==0 ; l.rl=RSUCC(l.rl)){ . 817,818d 815a Lancemem *lm = LANCEMEM; Msg *m; . 813d 809d 803c Lancemem *lm = LANCEMEM; return l.rl!=l.rc && (MPus(lm->rmr[l.rl].flags) & OWN)==0; . 788,791c while(l.tl!=l.tc && (MPus(lm->tmr[l.tl].flags) & OWN)==0){ if(MPus(lm->tmr[l.tl].flags) & ERR) l.oerrs++; . 781c if(l.rl!=l.rc && (MPus(lm->rmr[l.rl].flags) & OWN)==0) . 760,761d 758c Lancemem *lm = LANCEMEM; . 756a int i; . 711a case Lstatsqid: sprint(buf, "in: %d\nout: %d\ncrc errs %d\noverflows: %d\nframe errs %d\nbuff errs: %d\noerrs %d\n", l.inpackets, l.outpackets, l.crcs, l.overflows, l.frames, l.buffs, l.oerrs); return stringread(c, a, n, buf); . 708a char buf[256]; . 665a case Lstatsqid: . 639a case Lstatsqid: . 623c if(c->qid==CHDIR || c->qid==Ltraceqid || c->qid==Lstatsqid) . 592c kproc("lancekproc", lancekproc, 0);/**/ . 583c strcpy(lancedir[Ntypes+1].name, "stats"); lancedir[Ntypes+1].qid = Lstatsqid; lancedir[Ntypes+1].length = 0; lancedir[Ntypes+1].perm = 0600; . 545c *l.rdp = HADDR(l.lm); . 542c *l.rdp = LADDR(l.lm); . 533,538d 529,530c MPus(lm->tdralow) = LADDR(l.lm->tmr); MPus(lm->tdrahigh) = (LogNtrb<<13)|HADDR(l.lm->tmr); . 522,527c m = lm->tmr; for(i = 0; i < Ntrb; i++, m++){ MPs(m->size) = 0; MPus(m->cntflags) = 0; MPus(m->laddr) = LADDR(l.tpa[i]); MPus(m->flags) = HADDR(l.tpa[i]); . 516,517c m = lm->rmr; for(i = 0; i < l.rc; i++, m++) MPus(m->flags) |= OWN; . 511a . 509,510c MPus(lm->rdralow) = LADDR(l.lm->rmr); MPus(lm->rdrahigh) = (LogNrrb<<13)|HADDR(l.lm->rmr); . 501,507c m = lm->rmr; for(i = 0; i < Nrrb; i++, m++){ MPs(m->size) = -sizeof(Pkt); MPus(m->cntflags) = 0; MPus(m->laddr) = LADDR(l.rpa[i]); MPus(m->flags) = HADDR(l.rpa[i]); . 495,496c MPus(lm->multi[0]) = 0; MPus(lm->multi[1]) = 0; MPus(lm->multi[2]) = 0; MPus(lm->multi[3]) = 0; . 487,490d 478,480c MPus(lm->etheraddr[0]) = (LANCEID[16]&0xff00)|((LANCEID[20]>>8)&0xff); MPus(lm->etheraddr[1]) = (LANCEID[8]&0xff00)|((LANCEID[12]>>8)&0xff); MPus(lm->etheraddr[2]) = (LANCEID[0]&0xff00)|((LANCEID[4]>>8)&0xff); . 471c MPus(lm->mode) = 0; . 464a Lancemem *lm = LANCEMEM; Msg *m; . 462d 451,452c for(sp = l.lanceram; sp < l.lanceend; sp += l.sep) *sp = 0; . 447a l.lanceram = LANCERAM; l.lanceend = LANCEEND; l.lm = (Lancemem *)0; l.sep = 1; /* * allocate packet buffers in lance memory */ for(i = 0; i < Nrrb; i++) l.rpa[i] = (uchar *)&l.lm->rp[i]; for(i = 0; i < Ntrb; i++) l.tpa[i] = (uchar *)&l.lm->tp[i]; } else { /* * toggle lance's reset line */ MODEREG->promenet |= 1; MODEREG->promenet &= ~1; l.lanceram = LANCE3RAM; l.lanceend = LANCE3END; l.lm = (Lancemem *)0x800000; l.sep = 4; /* * allocate packet buffers in MP bus memory * and map it into lance space */ l.rp = (Pkt *)ialloc((Nrrb + Ntrb)*sizeof(Pkt), 1); l.tp = l.rp + Nrrb; index = 0x1E00; for(i = 0; i < Nrrb; i++){ x = (ulong)&l.rp[i]; *WRITEMAP = (index<<16) | (x>>12)&0xFFFF; l.rpa[i] = (uchar *)((i<<12) | (x & 0xFFF)); index++; } for(i = 0; i < Ntrb; i++){ x = (ulong)&l.tp[i]; *WRITEMAP = (index<<16) | (x>>12)&0xFFFF; l.tpa[i] = (uchar *)(((i+Nrrb)<<12) | (x & 0xFFF)); index++; } } } . 441,446c if(already == 0){ already = 1; if(ioid < IO3R1){ /* * toggle lance's reset line */ MODEREG->promenet &= ~1; MODEREG->promenet |= 1; . 439c * allocate the send and receive buffers and map them into * the lance's address space. . 435,436c l.rap = LANCERAP; l.rdp = LANCERDP; . 433c * so that we don't have to indirect through constants . 430a ushort *sp; ulong x; int index; static int already; . 429d 422d 418a Lstatsqid = 3, . 404,407c MPs(m->size) = -len; MPus(m->cntflags) = 0; MPus(m->laddr) = LADDR(l.tpa[l.tc]); MPus(m->flags) = OWN|STP|ENP|HADDR(l.tpa[l.tc]); . 402a l.outpackets++; . 398c lancedebq('o', p, len);/**/ . 368c p = &l.tp[l.tc]; . 265,277d 234c for(i=0; i<16; i++) . 147a Pkt *rp; /* receive buffers */ Pkt *tp; /* transmit buffers */ uchar *rpa[Nrrb]; /* receive buffer address in lance space */ uchar *tpa[Ntrb]; /* transmit buffer address in lance space */ /* sadistics */ int inpackets; int outpackets; int crcs; /* input crc errors */ int oerrs; /* output erros */ int frames; /* framing errors */ int overflows; /* packet overflows */ int buffs; /* buffering errors */ . 141,142d 134,135d 129a int sep; /* separaqtion between shorts in lance ram as seen by host */ ushort *lanceram; /* start of lance ram as seen by host */ ushort *lanceend; /* end of lance ram as seen by host */ Lancemem *lm; /* start of lance memory as seen by lance */ . 87a #define MPs(a) (*(short *)(l.lanceram + l.sep*((ushort*)&a - (ushort*)0))) #define MPus(a) (*(ushort *)(l.lanceram + l.sep*((ushort*)&a - (ushort*)0))) . 86c #define HADDR(a) ((((ulong)(a))>>16)&0xFF) . 80c #define LANCEMEM ((Lancemem*)0) . 78c Pkt rp[Nrrb]; Pkt tp[Ntrb]; . 76c * packet buffers (for IO2 version) . 69,70c * ring buffers * first receive, then transmit . 58,66c ushort mode; /* chip control (see below) */ ushort etheraddr[3]; /* the ethernet physical address */ ushort multi[4]; /* multicast addresses, 1 bit for each of 64 */ ushort rdralow; /* receive buffer ring */ ushort rdrahigh; /* (top three bits define size of ring) */ ushort tdralow; /* transmit buffer ring */ ushort tdrahigh; /* (top three bits define size of ring) */ . 52,53c typedef struct Lancemem . 39,49d 26a * Ethernet packet buffers. These must also be in lance addressible RAM. */ typedef struct { uchar d[6]; uchar s[6]; uchar type[2]; uchar data[1500]; uchar crc[4]; } Pkt; /* . 14c Ndir= Ntypes+2, /* entries in top level directory */ . ## diffname port/devlance.c 1990/0912 ## diff -e /n/bootesdump/1990/0911/sys/src/9/mips/devlance.c /n/bootesdump/1990/0912/sys/src/9/mips/devlance.c 469a l.rp = ((Lancemem *)LANCERAM)->rp; l.tp = ((Lancemem *)LANCERAM)->tp; . ## diffname port/devlance.c 1990/11211 ## diff -e /n/bootesdump/1990/0912/sys/src/9/mips/devlance.c /n/bootesdump/1990/11211/sys/src/9/mips/devlance.c 800,812c error(Eperm); . 794c error(Eperm); . 770c switch(c->qid.path){ . 721c switch(c->qid.path){ . 714c error(Eperm); . 699c error(Eperm); . 694c switch(c->qid.path){ . 680c if(c->qid.path==CHDIR || c->qid.path==Ltraceqid || c->qid.path==Lstatsqid) . 671c if(c->qid.path == CHDIR) . 638c lancedir[Ntypes+1].qid.path = Lstatsqid; . 634c lancedir[Ntypes].qid.path = Ltraceqid; . 629c lancedir[i].qid.path = CHDIR|STREAMQID(i, Lchanqid); lancedir[i].qid.vers = 0; . ## diffname port/devlance.c 1990/1228 ## diff -e /n/bootesdump/1990/11211/sys/src/9/mips/devlance.c /n/bootesdump/1990/1228/sys/src/9/mips/devlance.c 933c MPs(m->size) = -sizeof(Etherpkt); . 863c Etherpkt *p; . 562c MPs(m->size) = -sizeof(Etherpkt); . 539,547c MPus(lm->etheraddr[0]) = (l.ea[1]<<8) | l.ea[0]; MPus(lm->etheraddr[1]) = (l.ea[3]<<8) | l.ea[2]; MPus(lm->etheraddr[2]) = (l.ea[5]<<8) | l.ea[4]; . 523c Etherpkt *p; . 507,512d 489c l.rp = (Etherpkt *)ialloc((Nrrb + Ntrb)*sizeof(Etherpkt), 1); . 475,485d 471,472c l.rp = ((Lancemem *)l.lanceram)->rp; l.tp = ((Lancemem *)l.lanceram)->tp; . 453,463d 445,448d 442,443c *l.rap = 0; *l.rdp = STOP; . 440c * stop the lance . 434d 427a * configure the lance */ void lanceconfig(void *ramstart, void *ramend, void *rap, void *rdp, int sep, void *lancemem, uchar* ea) { l.lanceram = ramstart; l.lanceend = ramend; l.rap = rap; l.rdp = rdp; l.sep = sep; l.lm = lancemem; /* where lance sees its memory start */ memcpy(l.ea, ea, 6); } /* . 378c if(sizeof(Etherpkt) - len >= (n = BLEN(bp))){ . 341c Etherpkt *p; . 259c lancedebq(char tag, Etherpkt *p, int len) . 150,151c Etherpkt *rp; /* receive buffers */ Etherpkt *tp; /* transmit buffers */ . 85a /* * The following functions exist to sidestep a quirk in the SGI IO3 lance * interface. In all other processors, the lance's initialization block and * descriptor rings look like normal memory. In the SGI IO3, the CPU sees a * 6 byte pad twixt all lance memory shorts. Therefore, we use the following * macros to compute the address whenever accessing the lance memory to make * the code portable. Sic transit gloria. */ #define LANCEMEM ((Lancemem*)0) . 78d 75,76c Etherpkt rp[Nrrb]; Etherpkt tp[Ntrb]; . 73c * packet buffers (for SGI IO2 version only) . 27,37d ## diffname port/devlance.c 1990/1229 ## diff -e /n/bootesdump/1990/1229/sys/src/9/mips/devlance.c /n/bootesdump/1990/1229/sys/src/9/port/devlance.c 921,923c plance ^= 1; . 918,919c lancetoggle() . 912a wbflush(); . 910,911c MPus(m->laddr) = LADDR(&l.lrp[l.rc]); MPus(m->flags) = OWN|HADDR(&l.lrp[l.rc]); . 811a } . 810c if(l.rl!=l.rc && (MPus(lm->rmr[l.rl].flags) & OWN)==0){ . 585a wbflush(); . 561,562c MPus(m->laddr) = LADDR(&l.ltp[i]); MPus(m->flags) = HADDR(&l.ltp[i]); . 539,540c MPus(m->laddr) = LADDR(&l.lrp[i]); MPus(m->flags) = HADDR(&l.lrp[i]); . 469,491c /* * lance ethernet address */ lanceeaddr(l.ea); /* * lance init block and descriptor rings */ lancectlmem(&hostaddr, &lanceaddr, &l.sep, sizeof(Lancemem)); l.lanceram = hostaddr; l.lm = (Lancemem*)lanceaddr; /* * lance receive buffers */ lancepktmem(&hostaddr, &lanceaddr, Nrrb*sizeof(Etherpkt)); l.rp = (Etherpkt*)hostaddr; l.lrp = (Etherpkt*)lanceaddr; /* * lance xmt buffers */ lancepktmem(&hostaddr, &lanceaddr, Ntrb*sizeof(Etherpkt)); l.tp = (Etherpkt*)hostaddr; l.ltp = (Etherpkt*)lanceaddr; . 460,467d 451a l.rap = LANCERAP; l.rdp = LANCERDP; . 450a ushort *lanceaddr; ushort *hostaddr; . 429,444d 426c * stop the lance and allocate buffers . 411a wbflush(); . 408,409c MPus(m->laddr) = LADDR(&l.ltp[l.tc]); MPus(m->flags) = OWN|STP|ENP|HADDR(&l.ltp[l.tc]); . 269c if(plance){ . 148,151c Etherpkt *rp; /* receive buffers (host address) */ Etherpkt *tp; /* transmit buffers (host address) */ Etherpkt *lrp; /* receive buffers (lance address) */ Etherpkt *ltp; /* transmit buffers (lance address) */ . 131d 60,65d 25a int plance; . ## diffname port/devlance.c 1990/1231 ## diff -e /n/bootesdump/1990/1229/sys/src/9/port/devlance.c /n/bootesdump/1990/1231/sys/src/9/port/devlance.c 785a } . 784c if(csr & IDON){ print("lance inited\n"); . 567a print("lance started\n"); . 565a print("starting lance\n"); . 544c MPus(lm->tdrahigh) = (l.logntrb<<13)|HADDR(l.lm->tmr); . 537c for(i = 0; i < l.ntrb; i++, m++){ . 528c l.rc = l.nrrb - 1; . 522c MPus(lm->rdrahigh) = (l.lognrrb<<13)|HADDR(l.lm->rmr); . 515c for(i = 0; i < l.nrrb; i++, m++){ . 442,472d 434,435c if(already == 0){ already = 1; lancesetup(&l); } . 157,158c } SoftLance; static SoftLance l; . 143,147d 122,127d 120d 118a Lance; /* host dependent lance params */ . 60,62c Msg rmr[Maxrb]; /* recieve message ring */ Msg tmr[Maxrb]; /* transmit message ring */ }; . 43c struct Lancemem . 21,22c #define RSUCC(x) (((x)+1)%l.nrrb) #define TSUCC(x) (((x)+1)%l.ntrb) . 19a Maxrb= 128, /* max buffers in a ring */ . 15,18d 9,11c . ## diffname port/devlance.c 1991/0108 ## diff -e /n/bootesdump/1990/1231/sys/src/9/port/devlance.c /n/bootesdump/1991/0108/sys/src/9/port/devlance.c 740a print("aser %lux asevar %lux\n", getw2(0x60000008), getw2(0x6000000C)); *l.rap = 0; *l.rdp = STOP; delay(100); *l.rap = 0; print("csr0 %lux\n", *l.rdp); *l.rap = 1; print("csr1 %lux\n", *l.rdp); *l.rap = 2; print("csr2 %lux\n", *l.rdp); } . 739c if(csr & (BABL|MISS|MERR)){ . 423a *l.rap = 0; print("csr0 %lux\n", *l.rdp); *l.rap = 1; print("csr1 %lux\n", *l.rdp); *l.rap = 2; print("csr2 %lux\n", *l.rdp); . 418a . ## diffname port/devlance.c 1991/0109 ## diff -e /n/bootesdump/1991/0108/sys/src/9/port/devlance.c /n/bootesdump/1991/0109/sys/src/9/port/devlance.c 749,758d 533d 530d 524c *l.rdp = l.busctl; . 425,431d 347d 345d 179,185d ## diffname port/devlance.c 1991/01151 ## diff -e /n/bootesdump/1991/0109/sys/src/9/port/devlance.c /n/bootesdump/1991/01151/sys/src/9/port/devlance.c 851c void lancetoggle(void) . ## diffname port/devlance.c 1991/0118 ## diff -e /n/bootesdump/1991/01151/sys/src/9/port/devlance.c /n/bootesdump/1991/0118/sys/src/9/port/devlance.c 639c char buf[1024]; . 368a } . 367c if(len < 60){ memset(((char*)p)+len, 0, 60-len); . 365c * pad the packet (zero the pad) . 221c for(i=0; idata); i++) . ## diffname port/devlance.c 1991/0313 ## diff -e /n/bootesdump/1991/0118/sys/src/9/port/devlance.c /n/bootesdump/1991/0313/sys/src/9/port/devlance.c 829,833c if(!waserror()){ bp = allocb(len); memcpy(bp->rptr, (uchar *)p, len); bp->wptr += len; bp->flags |= S_DELIM; PUTNEXT(e->q, bp); poperror(); } . ## diffname port/devlance.c 1991/0314 ## diff -e /n/bootesdump/1991/0313/sys/src/9/port/devlance.c /n/bootesdump/1991/0314/sys/src/9/port/devlance.c 825,829c /* * The lock on e makes sure the queue is still there. */ if(e!=&l.e[Ntypes]){ if(e->q->next->len<=Streamhi && !waserror()){ . 818c if(e->q==0 || e->type!=-1 || !canqlock(e)) . 805c if(e->q==0 || t!=e->type || !canqlock(e)) . ## diffname port/devlance.c 1991/0316 ## diff -e /n/bootesdump/1991/0314/sys/src/9/port/devlance.c /n/bootesdump/1991/0316/sys/src/9/port/devlance.c 634,635d 626,632c if(c->stream) . 598,599d 559,561c return devattach('l', spec); . 552,553d ## diffname port/devlance.c 1991/0318 ## diff -e /n/bootesdump/1991/0316/sys/src/9/port/devlance.c /n/bootesdump/1991/0318/sys/src/9/port/devlance.c 817c memmove(bp->rptr, (uchar *)p, len); . 648c memmove(ca, buf + offset, i); . 546a . 362c memmove(p->s, l.ea, sizeof(l.ea)); . 348c memmove(((uchar *)p)+len, bp->rptr, n); . 239c memmove(&(t->p), p, sizeof(Dpkt)); . ## diffname port/devlance.c 1991/0325 ## diff -e /n/bootesdump/1991/0318/sys/src/9/port/devlance.c /n/bootesdump/1991/0325/sys/src/9/port/devlance.c 667,669c sprint(buf, "in: %d\nout: %d\ncrc errs %d\noverflows: %d\nframe errs %d\nbuff errs: %d\noerrs %d\naddr: %.02x:%.02x:%.02x:%.02x:%.02x:%.02x\n", l.inpackets, l.outpackets, l.crcs, l.overflows, l.frames, l.buffs, l.oerrs, l.ea[0], l.ea[1], l.ea[2], l.ea[3], l.ea[4], l.ea[5]); . ## diffname port/devlance.c 1991/0411 ## diff -e /n/bootesdump/1991/0325/sys/src/9/port/devlance.c /n/bootesdump/1991/0411/sys/src/9/port/devlance.c 680c lancewrite(Chan *c, void *a, long n, ulong offset) . 673c return lancetraceread(c, a, n, offset); . 671c return stringread(c, a, n, buf, offset); . 659c lanceread(Chan *c, void *a, long n, ulong offset) . 653c off = 0; . 649c memmove(ca, buf + off, i); . 646c i = plen - off; . 639,640c off = offset % plen; for(t = &l.dq.t[offset/plen]; n && t < &l.dq.t[Ndpkt]; t++){ . 632c int off; . 626c lancetraceread(Chan *c, void *a, long n, ulong offset) . ## diffname port/devlance.c 1991/0413 ## diff -e /n/bootesdump/1991/0411/sys/src/9/port/devlance.c /n/bootesdump/1991/0413/sys/src/9/port/devlance.c 317c n = strtoul((char *)bp->rptr, 0, 0); ((Ethertype *)q->ptr)->type = n; . 312a Ethertype *e; . ## diffname port/devlance.c 1991/0419 ## diff -e /n/bootesdump/1991/0413/sys/src/9/port/devlance.c /n/bootesdump/1991/0419/sys/src/9/port/devlance.c 581a Chan* lanceclwalk(Chan *c, char *name) { return devclwalk(c, name); } . ## diffname port/devlance.c 1991/0423 ## diff -e /n/bootesdump/1991/0419/sys/src/9/port/devlance.c /n/bootesdump/1991/0423/sys/src/9/port/devlance.c 645,646c plen = sprintpacket(buf, l.dq.t); . 222,223c n += sprint(buf+n, "%.2ux", p->data[i]); n += sprint(buf+n, ")\n"); return n; . 216c n = sprint(buf, "%c: %.8ud %.4d d(%.2ux%.2ux%.2ux%.2ux%.2ux%.2ux)s(%.2ux%.2ux%.2ux%.2ux%.2ux%.2ux)t(%.2ux %.2ux)d(", . 214c int i, n; . 210a int . ## diffname port/devlance.c 1991/0427 ## diff -e /n/bootesdump/1991/0423/sys/src/9/port/devlance.c /n/bootesdump/1991/0427/sys/src/9/port/devlance.c 584,589d ## diffname port/devlance.c 1991/0510 ## diff -e /n/bootesdump/1991/0427/sys/src/9/port/devlance.c /n/bootesdump/1991/0510/sys/src/9/port/devlance.c 802d ## diffname port/devlance.c 1991/0620 ## diff -e /n/bootesdump/1991/0510/sys/src/9/port/devlance.c /n/bootesdump/1991/0620/sys/src/9/port/devlance.c 446c MPus(lm->mode) = lancemode; . 208a * mode used by restart */ int lancemode; /* . ## diffname port/devlance.c 1991/0621 ## diff -e /n/bootesdump/1991/0620/sys/src/9/port/devlance.c /n/bootesdump/1991/0621/sys/src/9/port/devlance.c 849,854d 846a qunlock(&l.rlock); . 820,834c . 801,816c if(e->q!=0 && (t==e->type||e->type==-1) && canqlock(e)){ if(t==e->type||e->type==-1) lanceup(e, p, len); . 799d 794c * stuff packet up each queue that wants it . 776a qlock(&l.rlock); . 772c int t; . 770d 767d 764c static void . 755a * send a packet upstream */ void lanceup(Ethertype *e, Etherpkt *p, int len) { Block *bp; /* * only a trace channel gets packets destined for other machines */ if(e->type != -1){ if(!(p->d[0]&0x80) && memcmp(p->d, l.ea, sizeof(p->d))!=0) return; } if(e->q && e->q->next->len<=Streamhi && !waserror()){ bp = allocb(len); memmove(bp->rptr, (uchar *)p, len); bp->wptr += len; bp->flags |= S_DELIM; PUTNEXT(e->q, bp); poperror(); } } /* . 733a qunlock(&l.rlock); qunlock(&l.tlock); . 732d 680,681d 634,665d 606d 592c if(c->qid.path==CHDIR || c->qid.path==Lstatsqid) . 565c lancestart(0); . 552,555d 548,549c strcpy(lancedir[Ntypes].name, "stats"); lancedir[Ntypes].qid.path = Lstatsqid; . 530,531c * set up lance directory. . 451c MPus(lm->mode) = mode; . 446a l.rl = 0; l.rc = 0; l.tl = 0; l.tc = 0; . 445a /* * wait till both receiver and transmitter are * quiescent */ qlock(&l.tlock); qlock(&l.rlock); . 439c lancestart(int mode) . 403,404c Lstatsqid = 2, . 381,382d 325,326c e->type = strtol((char *)bp->rptr, 0, 0); } else if(streamparse("promiscuous", bp)) { e->prom = 1; qlock(&l); l.prom++; if(l.prom == 1) lancestart(PROM); qunlock(&l); . 323a e = q->ptr; . 300a et->prom = 0; . 297a if(et->prom){ qlock(&l); l.prom--; if(l.prom == 0) lancestart(0); qunlock(&l); } . 209,258d 206,207c static void lancekproc(void *); static void lancestart(int); . 131d 119a QLock rlock; /* semaphore on tc */ . 114a int prom; /* number of promiscuous channels */ . 87,106d 83a int prom; /* promiscuous mode */ . 21,22d 11,13c Ntypes= 9, /* max number of ethernet packet types */ Ndir= Ntypes+1, /* entries in top level directory */ . ## diffname port/devlance.c 1991/0828 ## diff -e /n/bootesdump/1991/0621/sys/src/9/port/devlance.c /n/bootesdump/1991/0828/sys/src/9/port/devlance.c 758a } static void lancedump(void) { print("l.rl %d l.rc %d l.tl %d l.tc %d\n", l.rl, l.rc, l.tl, l.tc); . 652a misses = 0; . 640a if(csr & MISS) lancedump(); . 627a static int misses; . 512c lancestart(0, 1); . 391,392c if(dolock){ qlock(&l.tlock); qlock(&l.rlock); } . 380c lancestart(int mode, int dolock) . 337a poperror(); . 290,292c sleep(&l.tr, isobuf, (void *)0); . 285a if(waserror()){ qunlock(&l.tlock); nexterror(); } . 269c lancestart(PROM, 1); . 231c lancestart(0, 1); . 186c static void lancestart(int, int); static void lancedump(void); . ## diffname port/devlance.c 1991/0925 ## diff -e /n/bootesdump/1991/0828/sys/src/9/port/devlance.c /n/bootesdump/1991/0925/sys/src/9/port/devlance.c 340a freeb(bp); . 312,313d 309,310c if(bp->flags & S_DELIM) . 303,305c for(nbp = bp; nbp; nbp = nbp->next){ if(sizeof(Etherpkt) - len >= (n = BLEN(nbp))){ memmove(((uchar *)p)+len, nbp->rptr, n); . 288a freeb(bp); . 279,284d 260a Block *nbp; . ## diffname port/devlance.c 1991/0926 ## diff -e /n/bootesdump/1991/0925/sys/src/9/port/devlance.c /n/bootesdump/1991/0926/sys/src/9/port/devlance.c 685c if(p->d[0]!=0xff && memcmp(p->d, l.ea, sizeof(p->d))!=0) . ## diffname port/devlance.c 1991/1002 ## diff -e /n/bootesdump/1991/0926/sys/src/9/port/devlance.c /n/bootesdump/1991/1002/sys/src/9/port/devlance.c 244,245d ## diffname port/devlance.c 1991/1026 ## diff -e /n/bootesdump/1991/1002/sys/src/9/port/devlance.c /n/bootesdump/1991/1026/sys/src/9/port/devlance.c 760a print("!"); . 740a if(p->type[0] == 0x80 || p->type[0] == 0x8) print("*"); . 693a poperror(); . 692d 682,686c if(e->type != -1 && p->d[0]!=0xff && memcmp(p->d, l.ea, sizeof(p->d))!=0) return; if(waserror()) return; if(e->q && e->q->next->len<=Streamhi){ . ## diffname port/devlance.c 1991/1027 ## diff -e /n/bootesdump/1991/1026/sys/src/9/port/devlance.c /n/bootesdump/1991/1027/sys/src/9/port/devlance.c 764d 743d 706a . 687d ## diffname port/devlance.c 1991/1031 ## diff -e /n/bootesdump/1991/1027/sys/src/9/port/devlance.c /n/bootesdump/1991/1031/sys/src/9/port/devlance.c 722,723c t = MPus(m->flags); if(t & ERR){ . ## diffname port/devlance.c 1991/1106 ## diff -e /n/bootesdump/1991/1031/sys/src/9/port/devlance.c /n/bootesdump/1991/1106/sys/src/9/port/devlance.c 741,747c lanceup(p, len); . 739d 718a while(bp = getq(&l.self)){ lanceup((Etherpkt*)bp->rptr, BLEN(bp)); freeb(bp); } . 715a Block *bp; . 704c return l.self.first || (l.rl!=l.rc && (MPus(lm->rmr[l.rl].flags) & OWN)==0); . 694d 685,692c /* * only a trace channel gets packets destined for other machines */ if(e->type!=-1 && p->d[0]!=0xff && memcmp(p->d, l.ea, sizeof(p->d))!=0) continue; /* * check after locking to make sure things didn't * change under foot */ if(!canqlock(e)) continue; if(e->q==0 || e->q->next->len>Streamhi || (t!=e->type && e->type!=-1)){ qunlock(e); continue; } if(!waserror()){ bp = allocb(len); memmove(bp->rptr, (uchar *)p, len); bp->wptr += len; bp->flags |= S_DELIM; PUTNEXT(e->q, bp); } poperror(); qunlock(e); . 679,683c t = (p->type[0]<<8) | p->type[1]; for(e = &l.e[0]; e < &l.e[Ntypes]; e++){ /* * check before locking just to save a lock */ if(e->q==0 || (t!=e->type && e->type!=-1)) continue; . 677a Ethertype *e; int t; . 674,675c static void lanceup(Etherpkt *p, int len) . 308,312d 277a * give packet a local address, return upstream if destined for * this machine. */ if(BLEN(bp) < ETHERHDRSIZE){ bp = pullup(bp, ETHERHDRSIZE); if(bp == 0) return; } p = (Etherpkt *)bp->rptr; memmove(p->s, l.ea, sizeof(l.ea)); if(memcmp(l.ea, p->d, sizeof(l.ea)) == 0){ len = blen(bp); bp = expandb(bp, len >= 60 ? len : 60); if(bp){ putq(&l.self, bp); wakeup(&l.rr); } return; } /* . 243a * expand a block list to be one byte, len bytes long */ static Block* expandb(Block *bp, int len) { Block *nbp, *new; int i; new = allocb(len); if(new == 0){ freeb(bp); return 0; } /* * copy bytes into new block */ for(nbp = bp; len>0 && nbp; nbp = nbp->next){ i = BLEN(bp); if(i > len) { memmove(new->wptr, nbp->rptr, len); new->wptr += len; break; } else { memmove(new->wptr, nbp->rptr, i); new->wptr += i; len -= i; } } if(len){ memset(new->wptr, 0, len); new->wptr += len; } freeb(bp); return new; } /* . 187a static void lanceup(Etherpkt*, int); . 111a Queue self; /* packets turned around at the interface */ . ## diffname port/devlance.c 1991/1107 ## diff -e /n/bootesdump/1991/1106/sys/src/9/port/devlance.c /n/bootesdump/1991/1107/sys/src/9/port/devlance.c 840,845d 698,700c if(misses++ < 4) print("lance err %ux\n", csr); . 373,375c if(len < ETHERMINTU){ memset(((char*)p)+len, 0, ETHERMINTU-len); len = ETHERMINTU; . 332c bp = expandb(bp, len >= ETHERMINTU ? len : ETHERMINTU); . 247,285d 189d ## diffname port/devlance.c 1991/1112 ## diff -e /n/bootesdump/1991/1107/sys/src/9/port/devlance.c /n/bootesdump/1991/1112/sys/src/9/port/devlance.c 519c lancedir[Ntypes].perm = 0666; . 514c lancedir[i].perm = 0666; . ## diffname port/devlance.c 1991/1113 ## diff -e /n/bootesdump/1991/1112/sys/src/9/port/devlance.c /n/bootesdump/1991/1113/sys/src/9/port/devlance.c 19a static int netlight; . ## diffname port/devlance.c 1991/1114 ## diff -e /n/bootesdump/1991/1113/sys/src/9/port/devlance.c /n/bootesdump/1991/1114/sys/src/9/port/devlance.c 633a } /* * user level network interface routines */ static void lancestatsfill(Chan *c, char* p, int n) { char buf[256]; sprint(buf, "in: %d\nout: %d\ncrc errs %d\noverflows: %d\nframe errs %d\nbuff errs: %d\noerrs %d\naddr: %.02x:%.02x:%.02x:%.02x:%.02x:%.02x\n", l.inpackets, l.outpackets, l.crcs, l.overflows, l.frames, l.buffs, l.oerrs, l.ea[0], l.ea[1], l.ea[2], l.ea[3], l.ea[4], l.ea[5]); strncpy(p, buf, n); } static void lancetypefill(Chan *c, char* p, int n) { char buf[16]; Ethertype *e; e = &l.e[STREAMID(c->qid.path)]; sprint(buf, "%d", e->type); strncpy(p, buf, n); } static int lanceclonecon(Chan *c) { Ethertype *e; for(e = l.e; e < &l.e[Ntypes]; e++){ qlock(e); if(e->inuse || e->q){ qunlock(e); continue; } e->inuse = 1; qunlock(e); return e - l.e; } errors("no unused lance channels"); . 602,615c return netread(c, a, n, offset, &l.net); . 570,583c return netopen(c, omode, &l.net); . 558,561c netstat(c, dp, &l.net); . 549,552c return netwalk(c, name, &l.net); . 542,545d 506,522d 382a l.net.name = "ether"; l.net.nconv = Ntypes; l.net.devp = &lanceinfo; l.net.protop = 0; l.net.listen = 0; l.net.clone = lanceclonecon; l.net.ninfo = 2; l.net.info[0].name = "stats"; l.net.info[0].fill = lancestatsfill; l.net.info[1].name = "type"; l.net.info[1].fill = lancetypefill; . 379d 376,377d 372,374d 358,366d 243a et->inuse = 0; . 217a et->inuse = 1; . 189,191c static void lancekproc(void *); static void lancestart(int, int); static void lanceup(Etherpkt*, int); static int lanceclonecon(Chan*); static void lancestatsfill(Chan*, char*, int); static void lancetypefill(Chan*, char*, int); . 95a Network net; . 84a int inuse; . 12d ## diffname port/devlance.c 1991/1115 ## diff -e /n/bootesdump/1991/1114/sys/src/9/port/devlance.c /n/bootesdump/1991/1115/sys/src/9/port/devlance.c 749a USED(arg); . 735a USED(arg); . 622a netown(&l.net, e - l.e, u->p->user, 0); . 615a USED(c); . 599a . 593a USED(c); . 583c netwstat(c, dp, &l.net); . 576a USED(c); . 551a USED(c, name, omode, perm); . 381a l.net.prot = l.prot; . 259a USED(x); . 249a netdisown(&l.net, et - l.e); . 96a Netprot prot[Ntypes]; . ## diffname port/devlance.c 1991/1121 ## diff -e /n/bootesdump/1991/1115/sys/src/9/port/devlance.c /n/bootesdump/1991/1121/sys/src/9/port/devlance.c 389a memset(l.bcast, 0xff, sizeof l.bcast); . 309a if(memcmp(l.bcast, p->d, sizeof(l.bcast)) == 0){ len = blen(bp); nbp = copyb(bp, len = len >= ETHERMINTU ? len : ETHERMINTU); if(nbp){ nbp->wptr = nbp->rptr+len; putq(&l.self, nbp); wakeup(&l.rr); } } . 114a uchar bcast[6]; . ## diffname port/devlance.c 1991/1126 ## diff -e /n/bootesdump/1991/1121/sys/src/9/port/devlance.c /n/bootesdump/1991/1126/sys/src/9/port/devlance.c 782a l.misses = 0; . 691d 688,689c if(l.rl!=l.rc && (MPus(lm->rmr[l.rl].flags) & OWN)==0) . 675c if(l.misses++ < 4) . 662d 324a . 320a /* restart the lance if'n it needs it */ if(l.misses > 4){ l.misses = 0; print("restarting lance\n"); lancestart(0, 1); } . 120a int misses; . ## diffname port/devlance.c 1991/1214 ## diff -e /n/bootesdump/1991/1126/sys/src/9/port/devlance.c /n/bootesdump/1991/1214/sys/src/9/port/devlance.c 438,439c qlock(&l.rlock); . 436c if(dolock) . 343c tsleep(&l.tr, isobuf, (void *)0, 1000); if(isobuf(0) == 0 || l.misses > 4){ l.misses = 0; print("lance wedged, restarting\n"); lancestart(0, 0); freeb(bp); return; /* the interrupt routine will qunlock(&l.tlock) */ } . 341c * Wait till we get an output buffer, reset the lance if input * or output seems wedged. . 322,328d ## diffname port/devlance.c 1992/0111 ## diff -e /n/bootesdump/1991/1214/sys/src/9/port/devlance.c /n/bootesdump/1992/0111/sys/src/9/port/devlance.c 7c #include "../port/error.h" . ## diffname port/devlance.c 1992/0112 ## diff -e /n/bootesdump/1992/0111/sys/src/9/port/devlance.c /n/bootesdump/1992/0112/sys/src/9/port/devlance.c 657c error(Enodev); . ## diffname port/devlance.c 1992/0215 ## diff -e /n/bootesdump/1992/0112/sys/src/9/port/devlance.c /n/bootesdump/1992/0215/sys/src/9/port/devlance.c 314c nbp = copyb(bp, len); nbp = expandb(nbp, len >= ETHERMINTU ? len : ETHERMINTU); . ## diffname port/devlance.c 1992/0307 ## diff -e /n/bootesdump/1992/0215/sys/src/9/port/devlance.c /n/bootesdump/1992/0307/sys/src/9/port/devlance.c 312c if(memcmp(l.bcast, p->d, sizeof(l.bcast)) == 0 || l.prom){ . 285c /* lancestart(PROM, 1);/**/ . ## diffname port/devlance.c 1992/0312 ## diff -e /n/bootesdump/1992/0307/sys/src/9/port/devlance.c /n/bootesdump/1992/0312/sys/src/9/port/devlance.c 285c lancestart(PROM, 1);/**/ . ## diffname port/devlance.c 1992/0314 ## diff -e /n/bootesdump/1992/0312/sys/src/9/port/devlance.c /n/bootesdump/1992/0314/sys/src/9/port/devlance.c 433a if(mode == PROM) print("setting promiscuous mode\n"); . ## diffname port/devlance.c 1992/0315 ## diff -e /n/bootesdump/1992/0314/sys/src/9/port/devlance.c /n/bootesdump/1992/0315/sys/src/9/port/devlance.c 312c if(memcmp(l.bcast, p->d, sizeof(l.bcast)) == 0 || l.prom || l.all){ . 279a if(e->type == -1){ qlock(&l); l.all++; qunlock(&l); } . 247a if(et->type == -1){ qlock(&l); l.all--; qunlock(&l); } . 95a int all; /* number of channels listening to all packets */ . ## diffname port/devlance.c 1992/0316 ## diff -e /n/bootesdump/1992/0315/sys/src/9/port/devlance.c /n/bootesdump/1992/0316/sys/src/9/port/devlance.c 353a qunlock(&l.tlock); . 298a qunlock(&l); . 297d 293d 289,290d 286,287c if(e->type == -1) . 284a if(e->type == -1) l.all--; . 283a qlock(&l); . ## diffname port/devlance.c 1992/0319 ## diff -e /n/bootesdump/1992/0316/sys/src/9/port/devlance.c /n/bootesdump/1992/0319/sys/src/9/port/devlance.c 759a . 755a . ## diffname port/devlance.c 1992/0320 ## diff -e /n/bootesdump/1992/0319/sys/src/9/port/devlance.c /n/bootesdump/1992/0320/sys/src/9/port/devlance.c 444,446d 288c e->type = strtol((char *)bp->rptr, 0, 0); . ## diffname port/devlance.c 1992/0321 ## diff -e /n/bootesdump/1992/0320/sys/src/9/port/devlance.c /n/bootesdump/1992/0321/sys/src/9/port/devlance.c 2c #include "../port/lib.h" . ## diffname port/devlance.c 1992/0322 ## diff -e /n/bootesdump/1992/0321/sys/src/9/port/devlance.c /n/bootesdump/1992/0322/sys/src/9/port/devlance.c 554a print("lance ether: %.2x%.2x%.2x%.2x%.2x%.2x\n", l.ea[0], l.ea[1], l.ea[2], l.ea[3], l.ea[4], l.ea[5]); . ## diffname port/devlance.c 1992/0328 ## diff -e /n/bootesdump/1992/0322/sys/src/9/port/devlance.c /n/bootesdump/1992/0328/sys/src/9/port/devlance.c 354a poperror(); . 353d 351c print("lance wedged, restarting\n"); . ## diffname port/devlance.c 1992/0506 ## diff -e /n/bootesdump/1992/0328/sys/src/9/port/devlance.c /n/bootesdump/1992/0506/sys/src/9/port/devlance.c 394a freeb(bp); . 393d 355c return; . 350,352c print("lance wedged\n"); qunlock(&l.tlock); . 340a freeb(bp); . 339d ## diffname port/devlance.c 1992/0520 ## diff -e /n/bootesdump/1992/0506/sys/src/9/port/devlance.c /n/bootesdump/1992/0520/sys/src/9/port/devlance.c 671a return -1; /* never reached */ . ## diffname port/devlance.c 1992/0604 ## diff -e /n/bootesdump/1992/0520/sys/src/9/port/devlance.c /n/bootesdump/1992/0604/sys/src/9/port/devlance.c 330a } else if(*p->d == *l.ea && memcmp(l.ea, p->d, sizeof(l.ea)) == 0){ len = blen(bp); bp = expandb(bp, len >= ETHERMINTU ? len : ETHERMINTU); if(bp){ putq(&l.self, bp); wakeup(&l.rr); } return; . 315,323d 313c if(*p->d == 0xff || l.prom || l.all){ . ## diffname port/devlance.c 1992/0605 ## diff -e /n/bootesdump/1992/0604/sys/src/9/port/devlance.c /n/bootesdump/1992/0605/sys/src/9/port/devlance.c 840c sleep(&l.rr, isinput, m); /* * if the lance is wedged, restart it */ if(l.wedged){ print("lance wedged, restarting\n"); l.wedged = 0; lancestart(0); } /* * close ethertypes requesting it */ if(l.closeline){ lock(&l.closepin); for(e = l.closeline; e; e = e->closeline){ e->q = 0; wakeup(&e->rc); } l.closeline = 0; unlock(&l.closepin); } . 837a l.rl = RSUCC(l.rl); m = &(lm->rmr[l.rl]); . 834,836c MPus(m->laddr) = LADDR(&l.lrp[l.rl]); MPus(m->flags) = LANCEOWNER|HADDR(&l.lrp[l.rl]); . 831d 827d 819,825d 817c } else { /* * stuff packet up each queue that wants it */ p = &l.rp[l.rl]; len = MPus(m->cntflags) - 4; lanceup(p, len); . 805,806d 803c m = &(lm->rmr[l.rl]); while((MPus(m->flags) & LANCEOWNER)==0){ . 781,782c return l.self.first || ((MPus(m->flags) & LANCEOWNER)==0); . 779c Msg *m = arg; . 749,760d 746c if(e->type!=-1 && p->d[0]!=0xff && (*p->d != *l.ea || memcmp(p->d, l.ea, sizeof(p->d))!=0)) . 740c if(e->q==0 || (t!=e->type && e->type!=-1) || e->q->next->len>Streamhi) . 738c * check for open, the right type, and flow control . 722d 717,720c if(csr & TINT) . 714,715c * wake any process waiting for a transmit buffer . 710c if((csr & (TXON|RXON)) != (TXON|RXON)) l.wedged = 1; /* * wakeup the input process */ if(csr & RINT) . 708c * the lance turns off if it gets strange output errors . 702c l.wedged = 0; . 684d 552c lancestart(0); . 498,499c for(i = 0; i < l.nrrb; i++, m++) MPus(m->flags) |= LANCEOWNER; . 496d 453,454d 447,448c qlock(&l.tlock); . 436c lancestart(int mode) . 432c * Initialize and start the lance. This routine can be called only from a process. . 387c MPus(m->flags) = LANCEOWNER|STP|ENP|HADDR(&l.ltp[l.tc]); . 383d 355a if((MPus(m->flags)&LANCEOWNER) != 0) tsleep(&l.tr, isobuf, m, 128); if(isobuf(m) == 0){ qunlock(&l.tlock); freeb(bp); poperror(); print("lance wedged, dumping block & restarting\n"); lancestart(0); return; } . 347,354c m = &(LANCEMEM->tmr[l.tc]); . 344c * Wait till we get an output buffer, complain if input . 295c lancestart(PROM);/**/ . 288c e->type = strtol((char *)bp->rptr, 0, 0); . 274c lanceoput(Queue *q, Block *bp) . 270,271c Msg *m; m = x; return (MPus(m->flags)&LANCEOWNER) == 0; . 260d 254c /* * mark as closing and wait for kproc to close us */ lock(&l.closepin); et->closeline = l.closeline; l.closeline = et; unlock(&l.closepin); wakeup(&l.rr); sleep(&et->rc, isclosed, et); . 246c lancestart(0); . 235a static int isclosed(void *x) { return ((Ethertype *)x)->q == 0; } . 227d 222d 212,214d 195c static void lancestart(int); . 169c #define LANCEOWNER 0x8000 /* 1 means that the buffer can be used by the chip */ . 112a Ethertype *closeline; /* channels waiting to close */ Lock closepin; /* lock for closeline */ . 110,111c ushort tc; /* next xmt Message CPU will try for */ . 106d 96a int wedged; /* the lance is wedged */ . 81,85c int type; /* ethernet type */ int prom; /* promiscuous mode */ Queue *q; int inuse; Rendez rc; /* rendzvous for close */ Ethertype *closeline; /* close list */ }; . 79c typedef struct Ethertype Ethertype; struct Ethertype { . ## diffname port/devlance.c 1992/0621 ## diff -e /n/bootesdump/1992/0605/sys/src/9/port/devlance.c /n/bootesdump/1992/0621/sys/src/9/port/devlance.c 646c char buf[512]; . 569d 564c kproc("lancekproc", lancekproc, 0); . 552,554d 288a . 240a . 17,20d ## diffname port/devlance.c 1992/0623 ## diff -e /n/bootesdump/1992/0621/sys/src/9/port/devlance.c /n/bootesdump/1992/0623/sys/src/9/port/devlance.c 674c netown(e, u->p->user, 0); . 435a for(i = 0; i < Ntypes; i++) netadd(&l.net, &l.e[i], i); . 431d 418a int i; . 271c netdisown(et); . 99d 78a Netprot; /* stat info */ . ## diffname port/devlance.c 1992/0711 ## diff -e /n/bootesdump/1992/0623/sys/src/9/port/devlance.c /n/bootesdump/1992/0711/sys/src/9/port/devlance.c 692d 619a USED(offset); . 457d ## diffname port/devlance.c 1992/0714 ## diff -e /n/bootesdump/1992/0711/sys/src/9/port/devlance.c /n/bootesdump/1992/0714/sys/src/9/port/devlance.c 743a if(len <= 0) return; . ## diffname port/devlance.c 1992/0717 ## diff -e /n/bootesdump/1992/0714/sys/src/9/port/devlance.c /n/bootesdump/1992/0717/sys/src/9/port/devlance.c 796a while(waserror()) print("lancekproc err %s\n", u->error); . 769d 767a poperror(); . ## diffname port/devlance.c 1992/0912 ## diff -e /n/bootesdump/1992/0717/sys/src/9/port/devlance.c /n/bootesdump/1992/0912/sys/src/9/port/devlance.c 848a print("lance wedged, restarting\n"); . 847d 742d 739a int t; . 706a else { l.wedged = 1; l.misses = 0; *l.rap = 0; *l.rdp = STOP; wakeup(&l.rr); wakeup(&l.tr); return; } . 368a l.wedged = 0; . 365c if(l.wedged || isobuf(m) == 0){ . ## diffname port/devlance.c 1992/0913 ## diff -e /n/bootesdump/1992/0912/sys/src/9/port/devlance.c /n/bootesdump/1992/0913/sys/src/9/port/devlance.c 859a l.wedged = 0; . 857d 792c return l.wedged || l.self.first || ((MPus(m->flags) & LANCEOWNER)==0); . 711,712c lancereset(); . 708a print("lance stopped\n"); . 707c print("lance err #%ux\n", csr); . 373a } . 371a l.wedged = 0; . 369d 363c while((MPus(m->flags)&LANCEOWNER) != 0) { . 349a if(l.wedged) { qunlock(&l.tlock); freeb(bp); return; } . 345a if(l.wedged) { freeb(bp); return; } . 284c return l.wedged || (MPus(m->flags)&LANCEOWNER) == 0; . ## diffname port/devlance.c 1992/0926 ## diff -e /n/bootesdump/1992/0913/sys/src/9/port/devlance.c /n/bootesdump/1992/0926/sys/src/9/port/devlance.c 791d ## diffname port/devlance.c 1992/1017 ## diff -e /n/bootesdump/1992/0926/sys/src/9/port/devlance.c /n/bootesdump/1992/1017/sys/src/9/port/devlance.c 802c return ((MPus(m->flags) & LANCEOWNER)==0) || l.wedged || l.self.first || l.closeline; . ## diffname port/devlance.c 1993/0501 ## diff -e /n/bootesdump/1992/1017/sys/src/9/port/devlance.c /n/fornaxdump/1993/0501/sys/src/brazil/port/devlance.c 820c print("lancekproc err %s\n", up->error); . 688c netown(e, up->user, 0); . ## diffname port/devlance.c 1993/0806 ## diff -e /n/fornaxdump/1993/0501/sys/src/brazil/port/devlance.c /n/fornaxdump/1993/0806/sys/src/brazil/port/devlance.c 885a qunlock(&l.tlock); return n; } void lanceremove(Chan *c) { USED(c); } void lancestat(Chan *c, char *dp) { netifstat(&l, c, dp); } void lancewstat(Chan *c, char *dp) { netifwstat(&l, c, dp); . 884a memmove(p->s, l.ea, sizeof(l.ea)); l.outpackets++; MPs(m->size) = -n; MPus(m->cntflags) = 0; MPus(m->laddr) = LADDR(&l.ltp[l.tc]); MPus(m->flags) = LANCEOWNER|STP|ENP|HADDR(&l.ltp[l.tc]); l.tc = TSUCC(l.tc); *l.rdp = INEA|TDMD; /**/ . 873,883c /* we handle data */ qlock(&l.tlock); m = &(LANCEMEM->tmr[l.tc]); tsleep(&l.tr, isoutbuf, m, 10000); if(!isoutbuf(m) || l.wedged){ print("lance transmitter jammed\n"); } else { p = &l.tp[l.tc]; memmove(p->d, buf, n); if(n < 60) { memset(p->d+n, 0, 60-n); n = 60; . 864,871c /* etherif.c handles structure */ if(NETTYPE(c->qid.path) != Ndataqid) return netifwrite(&l, c, buf, n); . 850,862c if(n > ETHERMAXTU) error(Ebadarg); . 822,848c USED(offset); . 819,820c long lancewrite(Chan *c, void *buf, long n, ulong offset) { Msg *m; Lancepkt *p; . 817c m = x; return l.wedged || (MPus(m->flags)&LANCEOWNER) == 0; } . 815d 809,813c netifclose(&l, c); } long lanceread(Chan *c, void *buf, long n, ulong offset) { return netifread(&l, c, buf, n, offset); } static int isoutbuf(void *x) { . 806,807c void lanceclose(Chan *c) . 802,803c void lancecreate(Chan *c, char *name, int omode, ulong perm) { USED(c, name, omode, perm); . 800c return netifopen(&l, c, omode); } . 794,798c Chan* lanceopen(Chan *c, int omode) . 783,791c int lancewalk(Chan *c, char *name) { return netifwalk(&l, c, name); . 776,781c Chan* lanceclone(Chan *c, Chan *nc) { return devclone(c, nc); } . 768,774c Chan* lanceattach(char *spec) { return devattach('l', spec); } . 765,766c void lanceinit(void) { lancestart(0); print("lance ether: %.2x%.2x%.2x%.2x%.2x%.2x\n", l.ea[0], l.ea[1], l.ea[2], l.ea[3], l.ea[4], l.ea[5]); } . 761,763c USED(arg); if(on) lancestart(PROM); else lancestart(0);; } . 759c promiscuous(void *arg, int on) . 756c * turn promiscuous mode on/off . 747a /* * stage the next input buffer */ MPs(m->size) = -sizeof(Lancepkt); MPus(m->cntflags) = 0; MPus(m->laddr) = LADDR(&l.lrp[l.rl]); MPus(m->flags) = LANCEOWNER|HADDR(&l.lrp[l.rl]); wbflush(); l.rl = RSUCC(l.rl); m = &(lm->rmr[l.rl]); } } . 745,746c if(csr & RINT) { m = &(lm->rmr[l.rl]); while((MPus(m->flags) & LANCEOWNER)==0){ l.inpackets++; t = MPus(m->flags); if(t & ERR){ if(t & FRAM) l.frames++; if(t & OFLO) l.overflows++; if(t & CRC) l.crcs++; if(t & BUFF) l.buffs++; } else { /* stuff packet up each queue that wants it */ p = &l.rp[l.rl]; x = MPus(m->cntflags) - 4; t = (p->type[0]<<8) | p->type[1]; for(fp = l.f; fp < &l.f[Ntypes]; fp++){ f = *fp; if(f == 0) continue; if(f->type == t || f->type < 0) qproduce(f->in, p->d, x); } } . 743c * process incoming frames . 732d 724d 704c Msg *m; Lancepkt *p; Netfile *f, **fp; ushort csr, t, x; Lancemem *lm = LANCEMEM; . 564,701d 510c MPs(m->size) = -sizeof(Lancepkt); . 477d 462,463c * Initialize and start the lance. * This routine can be called only from a process. * It may be used to restart a dead lance. . 437,451c /* general network interface structure */ netifinit(&l, "ether", Ntypes, 32*1024); l.alen = 6; memmove(l.addr, l.ea, 6); memmove(l.bcast, etherbcast, 6); l.promiscuous = promiscuous; l.arg = &l; . 431d 215,427d 123,213d 121c static void promiscuous(void*, int); . 119c Netif; } l; . 112,117c QLock tlock; /* lock for grabbing transmitter queue */ Rendez tr; /* wait here for free xmit buffer */ . 107,109d 101,105d 99d 95,97d 89,93c uchar ea[6]; uchar bcast[6]; . 87a struct Softlance { Lance; /* host dependent lance params */ . 78,85c PROM = 0x8000, INTL = 0x40, DRTY = 0x20, COLL = 0x10, DTCR = 0x8, LOOP = 0x4, DTX = 0x2, DRX = 0x1, ERR0 = 0x8000, BABL = 0x4000, CERR = 0x2000, MISS = 0x1000, MERR = 0x800, RINT = 0x400, TINT = 0x200, IDON = 0x100, INTR = 0x80, INEA = 0x40, RXON = 0x20, TXON = 0x10, TDMD = 0x8, STOP = 0x4, STRT = 0x2, INIT = 0x1, /* flag bits from a buffer descriptor in the rcv/xmt rings */ LANCEOWNER= 0x8000, /* 1 means buffer can be used by the chip */ ERR = 0x4000, /* error summary, the OR of all error bits */ FRAM = 0x2000, /* CRC error */ OFLO = 0x1000, /* (receive) lost some of the packet */ MORE = 0x1000, /* (transmit) more than 1 retry to tx pkt */ CRC = 0x800, /* (rcv) crc error reading packet */ ONE = 0x800, /* (tx) one retry to transmit the packet */ BUF = 0x400, /* (rcv) out of buffers */ DEF = 0x400, /* (tx) deffered while transmitting packet */ STP = 0x200, /* start of packet */ ENP = 0x100, /* end of packet */ /* cntflags bits from a buffer descriptor in the rcv/xmt rings */ BUFF = 0x8000, /* buffer error (host screwed up?) */ UFLO = 0x4000, /* underflow from memory */ LCOL = 0x1000, /* late collision (ether too long?) */ LCAR = 0x800, /* loss of carrier (ether broken?) */ RTRY = 0x400, /* couldn't transmit (ether jammed?) */ TTDR = 0x3FF, /* time domain reflectometer */ . 72,76c enum . 26c ushort cntflags; /* (rcv)count of buffer; (xmt) more flags */ . 11,12c Ntypes= 9, /* max number of ethernet packet types */ Maxrb= 128, /* max buffers in a ring */ . 8c #include "../port/netif.h" . ## diffname port/devlance.c 1993/0807 ## diff -e /n/fornaxdump/1993/0806/sys/src/brazil/port/devlance.c /n/fornaxdump/1993/0807/sys/src/brazil/port/devlance.c 469c *l.rdp = INEA|TDMD; . 453d 451c if(!isoutbuf(m) || l.wedged) . 330a . 174a Lancemem *lm = LANCEMEM; . 173d 152a . 144,145c if(inited == 0){ inited = 1; . 142c static int inited; . 123d ## diffname port/devlance.c 1993/1008 ## diff -e /n/fornaxdump/1993/0807/sys/src/brazil/port/devlance.c /n/fornaxdump/1993/1008/sys/src/brazil/port/devlance.c 454a etherloop(buf, n); . 432a static void etherloop(Etherpkt *p, long n) { int s; ushort t; Netfile *f, **fp; if(memcmp(p->d, p->s, sizeof(p->d)) && memcmp(p->d, l.bcast, sizeof(p->d))) return; s = splhi(); t = (p->type[0]<<8) | p->type[1]; for(fp = l.f; fp < &l.f[Ntypes]; fp++) { f = *fp; if(f == 0) continue; if(f->type == t || f->type < 0) qproduce(f->in, p->d, n); } splx(s); } . ## diffname port/devlance.c 1993/1009 ## diff -e /n/fornaxdump/1993/1008/sys/src/brazil/port/devlance.c /n/fornaxdump/1993/1009/sys/src/brazil/port/devlance.c 477d 470a if(etherloop(buf, n)) return n; . 452a return !different; . 440,441c different = memcmp(p->d, p->s, sizeof(p->d)); if(different && memcmp(p->d, l.bcast, sizeof(p->d))) return 0; . 436c int s, different; . 433c static int . ## diffname port/devlance.c 1993/1202 ## diff -e /n/fornaxdump/1993/1009/sys/src/brazil/port/devlance.c /n/fornaxdump/1993/1202/sys/src/brazil/port/devlance.c 498a poperror(); . 476a if(waserror()) { qunlock(&ctlr->tlock); nexterror(); } . ## diffname port/devlance.c 1993/1216 ## diff -e /n/fornaxdump/1993/1202/sys/src/brazil/port/devlance.c /n/fornaxdump/1993/1216/sys/src/brazil/port/devlance.c 478c qunlock(&l.tlock); . ## diffname port/devlance.c 1994/0624 ## diff -e /n/fornaxdump/1993/1216/sys/src/brazil/port/devlance.c /n/fornaxdump/1994/0624/sys/src/brazil/port/devlance.c 6d ## diffname port/devlance.c 1994/0728 ## diff -e /n/fornaxdump/1994/0624/sys/src/brazil/port/devlance.c /n/fornaxdump/1994/0728/sys/src/brazil/port/devlance.c 299,300d 297c if(csr & IDON) . 262a for(i = 0; i < 1000; i++) if(l.wedged == 0) break; qunlock(&l.tlock); . 160a l.wedged = 1; . ## diffname port/devlance.c 1995/0108 ## diff -e /n/fornaxdump/1994/0728/sys/src/brazil/port/devlance.c /n/fornaxdump/1995/0108/sys/src/brazil/port/devlance.c 509a } long lancebwrite(Chan *c, Block *bp, ulong offset) { return devbwrite(c, bp, offset); . 427a Block* lancebread(Chan *c, long n, ulong offset) { return devbread(c, n, offset); } . ## diffname port/devlance.c 1995/0804 ## diff -e /n/fornaxdump/1995/0108/sys/src/brazil/port/devlance.c /n/fornaxdump/1995/0804/sys/src/brazil/port/devlance.c 527d 525c lanceremove(Chan*) . 473,474d 468c lancewrite(Chan *c, void *buf, long n, ulong) . 413d 411c lancecreate(Chan*, char*, int, ulong) . 371d 369c promiscuous(void*, int on) . ## diffname port/devlance.c 1997/0327 ## diff -e /n/fornaxdump/1995/0804/sys/src/brazil/port/devlance.c /n/emeliedump/1997/0327/sys/src/brazil/port/devlance.c 535a int parseether(uchar *to, char *from) { char nip[4]; char *p; int i; p = from; for(i = 0; i < 6; i++){ if(*p == 0) return -1; nip[0] = *p++; if(*p == 0) return -1; nip[1] = *p++; nip[2] = 0; to[i] = strtoul(nip, 0, 16); if(*p == ':') p++; } return 0; } Dev lancedevtab = { lancereset, lanceinit, lanceattach, devclone, lancewalk, lancestat, lanceopen, lancecreate, lanceclose, lanceread, devbread, lancewrite, devbwrite, lanceremove, lancewstat, }; . 531c static void . 525c static void . 514,520c static void . 465c static long . 426,431d 420c static long . 414c static void . 409c static void . 403c static Chan* . 391,397c static int . 387a char *s; s = spec; if(s && *s && (*s != '0' || *(s+1))) error(Enodev); . 385c static Chan* . 377c static void . 149,150c memmove(l.addr, l.ea, Eaddrlen); memset(l.bcast, 0xFF, Eaddrlen); . 147c netifinit(&l, "ether0", Ntypes, 32*1024); . 137c static void . ## diffname port/devlance.c 1997/0408 ## diff -e /n/emeliedump/1997/0327/sys/src/brazil/port/devlance.c /n/emeliedump/1997/0408/sys/src/brazil/port/devlance.c 548a 'l', "lance", . ## diffname port/devlance.c 1997/1101 # deleted ## diff -e /n/emeliedump/1997/0408/sys/src/brazil/port/devlance.c /n/emeliedump/1997/1101/sys/src/brazil/port/devlance.c 1,567d