## 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<<LogNrrb), /* number of recieve buffers */
LogNtrb= 7, /* log of number of transmit buffers */
Ntrb= (1<<LogNtrb), /* number of transmit buffers */
Ndpkt= 30, /* number of debug packets */
};
#define RSUCC(x) (((x)+1)%Nrrb)
#define TSUCC(x) (((x)+1)%Ntrb)
/*
* Communication with the lance is via a transmit and receive ring of
* message descriptors. The Initblock contains pointers to and sizes of
* these rings. The rings must be in RAM addressible by the lance
*/
typedef struct {
ushort laddr; /* low order piece of address */
ushort flags; /* flags and high order piece of address */
short size; /* size of buffer */
ushort cntflags; /* (rcv)count of bytes in buffer; (xmt) more flags */
} Msg;
/*
* 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;
/*
* lance memory map
*/
typedef
struct
{
/*
* initialization block
*/
struct initblock {
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) */
};
/*
* ring buffers
* first receive, then transmit
*/
Msg rmr[Nrrb]; /* recieve message ring */
Msg tmr[Ntrb]; /* transmit message ring */
/*
* actual packets
*/
Pkt p[1];
} Lancemem;
#define LANCEMEM ((Lancemem *)LANCERAM)
/*
* Some macros for dealing with lance memory addresses. The lance splits
* its 24 bit addresses across two 16 bit registers.
*/
#define HADDR(a) ((((ulong)(a))>>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; i<Ntypes; i++) {
sprint(lancedir[i].name, "%d", i);
lancedir[i].qid = CHDIR|STREAMQID(i, Lchanqid);
lancedir[i].length = 0;
lancedir[i].perm = 0600;
}
}
Chan*
lanceattach(char *spec)
{
Chan *c;
if(l.kstarted == 0){
kproc("**lancekproc**", lancekproc, 0);
l.kstarted = 1;
lancestart();
}
c = devattach('l', spec);
c->dev = 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; i<sizeof(p->data); 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
|