Plan 9 from Bell Labs’s /usr/web/sources/extra/9hist/pc/ether503.c

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


## diffname pc/ether503.c 1992/1222
## diff -e /dev/null /n/bootesdump/1992/1222/sys/src/9/pc/ether503.c
0a
#include "u.h"
#include "../port/lib.h"
#include "mem.h"
#include "dat.h"
#include "fns.h"
#include "../port/error.h"
#include "io.h"
#include "devtab.h"

#include "ether.h"

static int
reset(Ctlr *ctlr)
{
	USED(ctlr);

	return -1;
}

Board ether503 = {
	reset,
	0,			/* init */
	0,			/* attach */
	0,			/* mode */
	0,			/* receive */
	0,			/* transmit */
	0,			/* interrupt */
	0,			/* watch */

	0,			/* addr */
	0,			/* irq */
	0,			/* bit16 */

	0,			/* ram */
	0,			/* ramstart */
	0,			/* ramstop */

	0,			/* dp8390 */
	0,			/* data */
	0,			/* tstart */
	0,			/* pstart */
	0,			/* pstop */
};
.
## diffname pc/ether503.c 1993/0212
## diff -e /n/bootesdump/1992/1222/sys/src/9/pc/ether503.c /n/bootesdump/1993/0212/sys/src/9/pc/ether503.c
38,42c
static void*
write(Ctlr *ctlr, ulong to, void *from, ulong len)
{
	uchar *addr, ctrl;

	/*
	 * See the comments in 'read()' above.
	 */
	if(ctlr->card.ram)
		return memmove((void*)(ctlr->card.ramstart+to-RamOffset), from, len);

	outb(ctlr->card.io+Dalsb, to & 0xFF);
	outb(ctlr->card.io+Damsb, (to>>8) & 0xFF);
	ctrl = inb(ctlr->card.io+Ctrl);
	outb(ctlr->card.io+Ctrl, Start|Ddir|ctrl);
	addr = from;
	while(len){
		while((inb(ctlr->card.io+Streg) & Dprdy) == 0)
			;
		if(len >= 8){
			outss(ctlr->card.io+Rfmsb, addr, 4);
			addr += 8;
			len -= 8;
		}
		else{
			outsb(ctlr->card.io+Rfmsb, addr, len);
			break;
		}
	}
	outb(ctlr->card.io+Ctrl, ctrl);
	return (void*)to;
}

Card ether503 = {
	"3Com503",			/* ident */

	reset,				/* reset */
	0,				/* init */
	dp8390attach,			/* attach */
	dp8390mode,			/* mode */

	read,				/* read */
	write,				/* write */

	dp8390receive,			/* receive */
	dp8390transmit,			/* transmit */
	dp8390intr,			/* interrupt */
	dp8390watch,			/* watch */
	dp8390overflow,			/* overflow */

	0,				/* io */
	0,				/* irq */
	0,				/* bit16 */

	0,				/* ram */
	0,				/* ramstart */
	0,				/* ramstop */

	0,				/* dp8390 */
	0,				/* data */
	0,				/* software bndry */
	RamOffset/Dp8390BufSz,		/* tstart */
	(RamOffset+0x600)/Dp8390BufSz,	/* pstart */
	(RamOffset+8*1024)/Dp8390BufSz,	/* pstop */
.
34,36c
	/*
	 * Polled I/O. This should be tuned.
	 * Set up the dma registers and pump the fifo.
	 */
	outb(ctlr->card.io+Dalsb, from & 0xFF);
	outb(ctlr->card.io+Damsb, (from>>8) & 0xFF);
	ctrl = inb(ctlr->card.io+Ctrl);
	outb(ctlr->card.io+Ctrl, Start|ctrl);
	addr = to;
	while(len){
		/*
		 * The fifo is 8 bytes deep, we have to wait
		 * until it's ready before stuffing it.
		 * The fifo is in its default configuration,
		 * so we can do word accesses.
		 */
		while((inb(ctlr->card.io+Streg) & Dprdy) == 0)
			;
		if(len >= 8){
			inss(ctlr->card.io+Rfmsb, addr, 4);
			addr += 8;
			len -= 8;
		}
		else{
			insb(ctlr->card.io+Rfmsb, addr, len);
			break;
		}
	}
	outb(ctlr->card.io+Ctrl, ctrl);
	return to;
}
.
30,32c
	/*
	 * If the interface has shared memory, just do a memmove.
	 * In this case, 'from' is an index into the shared memory.
	 * Due to 'hardware considerations', the memory is seen by
	 * the adapter at RamOffset, so we have to adjust.
	 */
	if(ctlr->card.ram)
		return memmove(to, (void*)(ctlr->card.ramstart+from-RamOffset), len);
.
20,28c
static void*
read(Ctlr *ctlr, void *to, ulong from, ulong len)
{
	uchar *addr, ctrl;
.
17c
	/*
	 * The Gate Array Ctrl register bits <3,2> determine what is
	 * mapped at the I/O base address. The options are the DP8390,
	 * PROM bytes 0-15 or PROM bytes 16-31.
	 * At power-on, the I/O base address contains PROM bytes 16-31.
	 */
	for(tp = table; ctlr->card.io = tp->io; tp++){
		/*
		 * Toggle the software reset bit, this should initialise the
		 * Ctrl register to 0x0A (Eahi|Xsel).
		 * Hopefully there is no other card at the gate-array address.
		 */
		outb(ctlr->card.io+Ctrl, Rst);
		delay(1);
		outb(ctlr->card.io+Ctrl, 0);
		if(inb(ctlr->card.io+Ctrl) == (Eahi|Xsel))
			break;
	}
	if(ctlr->card.io == 0)
		return -1;

	/*
	 * Map PROM bytes 0-15 to the I/O base address
	 * and read the ethernet address.
	 * When done, map the DP8390 at the I/O base address
	 * and set the transceiver type and irq.
	 */
	outb(ctlr->card.io+Ctrl, Ealo|Xsel);
	for(i = 0; i < sizeof(ctlr->ea); i++)
		ctlr->ea[i] = inb(ctlr->card.io+i);

	outb(ctlr->card.io+Gacfr, Nim|Tcm);

	outb(ctlr->card.io+Ctrl, 0|tp->bnc);
	outb(ctlr->card.io+Idcfr, tp->irq);

	if(tp->irq == Irq2)
		ctlr->card.irq = 2;
	else if(tp->irq == Irq3)
		ctlr->card.irq = 3;
	else if(tp->irq == Irq4)
		ctlr->card.irq = 4;
	else if(tp->irq == Irq5)
		ctlr->card.irq = 5;
	else
		return -1;

	/*
	 * Try to configure the shared memory.
	 * Assume this is an 8K card.
	 */
	ctlr->card.ram = 1;
	cfr = inb(ctlr->card.io+Pcfr);
	if(cfr & C8xxx)
		ctlr->card.ramstart = KZERO|0xC8000;
	else if(cfr & CCxxx)
		ctlr->card.ramstart = KZERO|0xCC000;
	else if(cfr & D8xxx)
		ctlr->card.ramstart = KZERO|0xD8000;
	else if(cfr & DCxxx)
		ctlr->card.ramstart = KZERO|0xDC000;
	else
		ctlr->card.ram = 0;

	ctlr->card.ramstop = ctlr->card.ramstart + 8*1024;

	/*
	 * Finish initialising the gate-array.
	 * The Pstr and Pspr registers must be the same as those
	 * given to the DP8390.
	 * Gacfr is set to enable shared memory and block DMA
	 * interrupts.
	 */
	outb(ctlr->card.io+Pstr, ctlr->card.pstart);
	outb(ctlr->card.io+Pspr, ctlr->card.pstop);

	outb(ctlr->card.io+Dqtr, 8);
	outb(ctlr->card.io+Damsb, ctlr->card.tstart);
	outb(ctlr->card.io+Dalsb, 0);

	outb(ctlr->card.io+Vptr2, 0xFF);
	outb(ctlr->card.io+Vptr1, 0xFF);
	outb(ctlr->card.io+Vptr0, 0x00);

	/*
	 * Finally, init the 8390, set the ethernet address
	 * and turn on the shared memory if any.
	 */
	ctlr->card.dp8390 = ctlr->card.io;
	dp8390reset(ctlr);
	dp8390setea(ctlr);

	if(ctlr->card.ram)
		outb(ctlr->card.io+Gacfr, Tcm|Rsel|Mbs0);
	else
		outb(ctlr->card.io+Gacfr, Tcm);

	return 0;
.
15c
	Table *tp;
	int i;
	uchar cfr;
.
11a
/*
 * 3Com 503 (EtherLink II).
 * This driver doesn't work under load, the card gets blasted by
 * overwrite-warning interrupts and eventually just hangs. Always clearing
 * the Ovw bit in the DP8390 Isr along with the Rxe and Prx bits stops
 * the overwrite-warning interrupts, but the card eventually hangs anyway.
 * I really don't understand why this card doesn't work,
 * there is plenty of evidence that other systems manage to use it.
 * The only good thing about this driver is that both shared
 * memory and polled I/O work (given the above restraints), although
 * the polled I/O should be tuned.
 */
enum {					/* Gate Array Registers */
	Pstr		= 0x400,	/* Page Start Register */
	Pspr		= 0x401,	/* Page Stop Register */
	Dqtr		= 0x402,	/* Drq Timer Register */
	Bcfr		= 0x403,	/* Base Configuration Register */
	Pcfr		= 0x404,	/* EPROM Configuration Register */
	Gacfr		= 0x405,	/* GA Configuration Register */
	Ctrl		= 0x406,	/* Control Register */
	Streg		= 0x407,	/* Status Register */
	Idcfr		= 0x408,	/* Interrupt/DMA Configuration Register */
	Damsb		= 0x409,	/* DMA Address Register MSB */
	Dalsb		= 0x40A,	/* DMA Address Register LSB */
	Vptr2		= 0x40B,	/* Vector Pointer Register 2 */
	Vptr1		= 0x40C,	/* Vector Pointer Register 1 */
	Vptr0		= 0x40D,	/* Vector Pointer Register 0 */
	Rfmsb		= 0x40E,	/* Register File Access MSB */
	Rflsb		= 0x40F,	/* Register File Access LSB */
};

enum {					/* Pcfr */
	C8xxx		= 0x10,		/* memory address 0xC8000 */
	CCxxx		= 0x20,		/* memory address 0xCC000 */
	D8xxx		= 0x40,		/* memory address 0xD8000 */
	DCxxx		= 0x80,		/* memory address 0xDC000 */
};

enum {					/* Gacfr */
	Mbs0		= 0x01,		/* memory bank select 0 */
	Mbs1		= 0x02,		/* memory bank select 1 */
	Mbs2		= 0x04,		/* memory bank select 2 */
	Rsel		= 0x08,		/* RAM select */
	Test		= 0x10,		/* test */
	Ows		= 0x20,		/* 0 wait state */
	Tcm		= 0x40,		/* terminal count mask */
	Nim		= 0x80,		/* MIC interrupt mask */
};

enum {					/* Ctrl */
	Rst		= 0x01,		/* software reset */
	Xsel		= 0x02,		/* transceiver select (BNC = 1, AUI = 0) */
	Ealo		= 0x04,		/* ethernet address low */
	Eahi		= 0x08,		/* ethernet address high */
	Share		= 0x10,		/* interrupt share */
	Dbsel		= 0x20,		/* double buffer select */
	Ddir		= 0x40,		/* DMA direction */
	Start		= 0x80,		/* DMA start */
};

enum {					/* Streg */
	Rev0		= 0x01,		/* gate array revision bit 0 */
	Rev1		= 0x02,		/* gate array revision bit 1 */
	Rev2		= 0x04,		/* gate array revision bit 2 */
	Dip		= 0x08,		/* DMA in progress */
	Dtc		= 0x10,		/* DMA terminal count */
	Oflw		= 0x20,		/* overflow */
	Uflw		= 0x40,		/* underflow */
	Dprdy		= 0x80,		/* data port ready */
};

enum {					/* Idcfr */
	Drq1		= 0x01,		/* DMA request 1 */
	Drq2		= 0x02,		/* DMA request 2 */
	Drq3		= 0x04,		/* DMA request 3 */
	Irq2		= 0x10,		/* interrupt request 2 */
	Irq3		= 0x20,		/* interrupt request 3 */
	Irq4		= 0x40,		/* interrupt request 4 */
	Irq5		= 0x80,		/* interrupt request 5 */
};

enum {
	RamOffset	= 0x2000,	/* where the card sees the shared memory */
};

typedef struct {
	ulong	io;			/* I/O base address */
	uchar	irq;			/* interrupt level */
	uchar	bnc;			/* use BNC connector */
} Table;

/*
 * The only configuration info we can get from the card is the
 * I/O base address and the shared-memory address. So let's make
 * a little hard-wired configuration table.
 */
static Table table[] = {
	{ 0x300, Irq2, 0, },		/* external transceiver */
	{ 0x310, Irq3, 0, },
	{ 0x330, Irq4, 0, },
	{ 0x350, Irq5, 0, },

	{ 0x250, Irq2, 1, },		/* BNC */
	{ 0x280, Irq3, 1, },
	{ 0x2A0, Irq4, 1, },
	{ 0x2E0, Irq5, 1, },

	{ 0 },
};

.
## diffname pc/ether503.c 1993/0213
## diff -e /n/bootesdump/1993/0212/sys/src/9/pc/ether503.c /n/bootesdump/1993/0213/sys/src/9/pc/ether503.c
114,117c
	{ 0x350, Irq5, Xsel, },		/* BNC */
	{ 0x250, Irq2, Xsel, },
	{ 0x280, Irq3, Xsel, },
	{ 0x2A0, Irq4, Xsel, },
	{ 0x2E0, Irq5, Xsel, },
.
112d
## diffname pc/ether503.c 1993/0223
## diff -e /n/bootesdump/1993/0213/sys/src/9/pc/ether503.c /n/bootesdump/1993/0223/sys/src/9/pc/ether503.c
121a

.
## diffname pc/ether503.c 1993/0303
## diff -e /n/bootesdump/1993/0223/sys/src/9/pc/ether503.c /n/bootesdump/1993/0303/sys/src/9/pc/ether503.c
113,114c
	{ 0x250, Irq2, Xsel, },		/* BNC */
.
111a
	{ 0x350, Irq5, 0, },
.
## diffname pc/ether503.c 1993/0915
## diff -e /n/bootesdump/1993/0303/sys/src/9/pc/ether503.c /n/fornaxdump/1993/0915/sys/src/brazil/pc/ether503.c
340a

void
ether503link(void)
{
	addethercard("3C503",  ccc503reset);
}
.
## diffname pc/ether503.c 1993/1113 # deleted
## diff -e /n/fornaxdump/1993/0915/sys/src/brazil/pc/ether503.c /n/fornaxdump/1993/1113/sys/src/brazil/pc/ether503.c
1,346d

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].