Plan 9 from Bell Labs’s /usr/web/sources/extra/9hist/port/devlance.c

Copyright © 2021 Plan 9 Foundation.
Distributed under the MIT License.
Download the Plan 9 distribution.


## 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

Bell Labs OSI certified Powered by Plan 9

(Return to Plan 9 Home Page)

Copyright © 2021 Plan 9 Foundation. All Rights Reserved.
Comments to [email protected].