~kris/9p

9hist

1fb13e8ba2eea54e41f4301bd82f5f11950b1376 — David du Colombier 29 years ago 47455df
Plan 9 from Bell Labs 1997-03-28
3 files changed, 177 insertions(+), 96 deletions(-)

M pc/etherelnk3.c
M pc/main.c
M pc/memory.c
M pc/etherelnk3.c => pc/etherelnk3.c +175 -95
@@ 6,7 6,8 @@
 *	autoSelect;
 *	PCI latency timer and master enable;
 *	errata list;
 *	3C90x.
 *	3C90x full busmastering;
 *	rewrite all initialisation.
 *
 * Product ID:
 *	9150 ISA	3C509[B]


@@ 27,6 28,11 @@
 *	5951 PCI	3C595-T4	Fast Etherlink Shared 10BASE-T/100BASE-T4
 *	5952 PCI	3C595-MII	Fast Etherlink 10BASE-T/MII
 *
 *	9000 PCI	3C900-TPO	Etherlink III XL PCI 10BASE-T
 *	9001 PCI	3C900-COMBO	Etherlink III XL PCI 10BASE-T/10BASE-2/AUI
 *	9050 PCI	3C905-TX	Fast Etherlink XL Shared 10BASE-T/100BASE-TX
 *	9051 PCI	3C905-T4	Fast Etherlink Shared 10BASE-T/100BASE-T4
 *
 *	9058 PCMCIA	3C589[B]-[TP|COMBO]
 *
 *	627C MCA	3C529


@@ 54,12 60,13 @@ enum {						/* all windows */

enum {						/* Commands */
	GlobalReset		= 0x0000,
	SelectRegisterWindow	= 0x0001,	
	SelectRegisterWindow	= 0x0001,
	EnableDcConverter	= 0x0002,
	RxDisable		= 0x0003,
	RxEnable		= 0x0004,
	RxReset			= 0x0005,
	TxDone			= 0x0007,	
	Stall			= 0x0006,	/* 3C90x */
	TxDone			= 0x0007,
	RxDiscard		= 0x0008,
	TxEnable		= 0x0009,
	TxDisable		= 0x000A,


@@ 91,8 98,16 @@ enum {						/* (Global|Rx|Tx)Reset command bits */
	hostReset		= 0x0020,	/* bus interface logic */
	dmaReset		= 0x0040,	/* bus master logic */
	vcoReset		= 0x0080,	/* on-board 10Mbps VCO */
	updnReset		= 0x0100,	/* upload/download (Rx/TX) logic */

	resetMask		= 0x01FF,
};

	resetMask		= 0x00FF,
enum {						/* Stall command bits */
	UpStall			= 0x0000,
	UpUnStall		= 0x0001,
	DnStall			= 0x0002,
	DnUnStall		= 0x0003,
};

enum {						/* SetRxFilter command bits */


@@ 117,10 132,12 @@ enum {						/* IntStatus bits */
	intRequested		= 0x0040,
	updateStats		= 0x0080,
	transferInt		= 0x0100,	/* Bus Master Transfer Complete */
	dnComplete		= 0x0200,
	upComplete		= 0x0400,
	busMasterInProgress	= 0x0800,
	commandInProgress	= 0x1000,

	interruptMask		= 0x01FE,
	interruptMask		= 0x07FE,
};

#define COMMAND(port, cmd, a)	outs((port)+CommandR, ((cmd)<<11)|(a))


@@ 201,9 218,12 @@ enum {						/* Window 3 - FIFO management */
	ResetOptions		= 0x0008,	/* 3C59[0257] */
	RxFree			= 0x000A,
						/* InternalConfig bits */
	disableBadSsdDetect	= 0x00000100,
	ramLocation		= 0x00000200,	/* 0 external, 1 internal */
	ramPartition5to3	= 0x00000000,
	ramPartition3to1	= 0x00010000,
	ramPartition1to1	= 0x00020000,
	ramPartition3to5	= 0x00030000,
	ramPartitionMask	= 0x00030000,
	xcvr10BaseT		= 0x00000000,
	xcvrAui			= 0x00100000,	/* 10BASE5 */


@@ 225,7 245,7 @@ enum {						/* Window 3 - FIFO management */
	base10TAvailable	= 0x0008,
	coaxAvailable		= 0x0010,
	auiAvailable		= 0x0020,
	miiAvailable		= 0x0040,
	miiConnector		= 0x0040,
};

enum {						/* Window 4 - diagnostic */


@@ 237,6 257,7 @@ enum {						/* Window 4 - diagnostic */
	PhysicalMgmt		= 0x0008,
	MediaStatus		= 0x000A,
	BadSSD			= 0x000C,
	UpperBytesOk		= 0x000D,
						/* FifoDiagnostic bits */
	txOverrun		= 0x0400,
	rxUnderrun		= 0x2000,


@@ 254,7 275,7 @@ enum {						/* Window 4 - diagnostic */
	linkBeatDetect		= 0x0800,
	txInProg		= 0x1000,
	dcConverterEnabled	= 0x4000,
	auiDisable		= 0x8000,
	auiDisable		= 0x8000,	/* 10BaseT transceiver selected */
};

enum {						/* Window 5 - internal state */


@@ 301,7 322,58 @@ enum {						/* Window 7 - bus master operations */
	masterInProgress	= 0x8000,

	masterMask		= 0xD00F,
};	
};

enum {						/* 3C90x extended register set */
	PktStatus		= 0x0020,	/* 32-bits */
	DnListPtr		= 0x0024,	/* 32-bits, 8-byte aligned */
	FragAddr		= 0x0028,	/* 32-bits */
	FragLen			= 0x002C,	/* 16-bits */
	ListOffset		= 0x002E,	/* 8-bits */
	TxFreeThresh		= 0x002F,	/* 8-bits */
	UpPktStatus		= 0x0030,	/* 32-bits */
	FreeTimer		= 0x0034,	/* 16-bits */
	UpListPtr		= 0x0038,	/* 32-bits, 8-byte aligned */

						/* PktStatus bits */
	fragLast		= 0x00000001,
	dnCmplReq		= 0x00000002,
	dnStalled		= 0x00000004,
	upCompleteX		= 0x00000008,
	dnCompleteX		= 0x00000010,
	upRxEarlyEnable		= 0x00000020,
	armCountdown		= 0x00000040,
	dnInProg		= 0x00000080,
	counterSpeed		= 0x00000010,	/* 0 3.2uS, 1 320nS */
	countdownMode		= 0x00000020,
						/* UpPktStatus bits */
	upPktLenMask		= 0x00001FFF,
	upStalled		= 0x00002000,
	upError			= 0x00004000,
	upPktComplete		= 0x00008000,
	upOverrrun		= 0x00010000,	/* RxError<<16 */
	upRuntFrame		= 0x00020000,
	upAlignmentError	= 0x00040000,
	upCRCError		= 0x00080000,
	upOversizedFrame	= 0x00100000,
	upDribbleBits		= 0x00800000,
	upOverflow		= 0x01000000,
};

/*
 * Up/Dn Packet Descriptor.
 * The hardware info (np, control, addr, len) must be 8-byte aligned.
 */
typedef struct Pd Pd;
typedef struct Pd {
	Pd*	next;
	Block*	bp;

	ulong	np;				/* next pointer */
	ulong	control;			/* FSH or UpPktStatus */
	ulong	addr;
	ulong	len;
};

typedef struct {
	Lock	wlock;				/* window access */


@@ 316,19 388,7 @@ typedef struct {

	long	interrupts;			/* statistics */
	long	timer;
	
	long	carrierlost;
	long	sqeerrors;
	long	multiplecolls;
	long	singlecollframes;
	long	latecollisions;
	long	rxoverruns;
	long	framesxmittedok;
	long	framesrcvdok;
	long	framesdeferred;
	long	bytesrcvdok;
	long	bytesxmittedok;
	long	badssd;
	long	stats[BytesRcvdOk+2];

	int	xcvr;				/* transceiver type */
	int	rxstatus9;			/* old-style RxStatus register */


@@ 385,7 445,7 @@ promiscuous(void* arg, int on)
	int filter, port;

	port = ((Ether*)arg)->port;
	

	filter = receiveBroadcast|receiveIndividual;
	if(on)
		filter |= receiveAllFrames;


@@ 437,7 497,7 @@ attach(Ether* ether)
static void
statistics(Ether* ether)
{
	int port, u, w;
	int port, i, u, w;
	Ctlr *ctlr;

	port = ether->port;


@@ 451,25 511,18 @@ statistics(Ether* ether)
	COMMAND(port, SelectRegisterWindow, Wstatistics);
	STATUS(port);

	ctlr->carrierlost += inb(port+CarrierLost) & 0xFF;
	ctlr->sqeerrors += inb(port+SqeErrors) & 0xFF;
	ctlr->multiplecolls += inb(port+MultipleColls) & 0xFF;
	ctlr->singlecollframes += inb(port+SingleCollFrames) & 0xFF;
	ctlr->latecollisions += inb(port+LateCollisions) & 0xFF;
	ctlr->rxoverruns += inb(port+RxOverruns) & 0xFF;
	ctlr->framesxmittedok += inb(port+FramesXmittedOk) & 0xFF;
	ctlr->framesrcvdok += inb(port+FramesRcvdOk) & 0xFF;
	for(i = 0; i < UpperFramesOk; i++)
		ctlr->stats[i] += inb(port+i) & 0xFF;
	u = inb(port+UpperFramesOk) & 0xFF;
	ctlr->framesxmittedok += (u & 0x30)<<4;
	ctlr->framesrcvdok += (u & 0x03)<<8;
	ctlr->framesdeferred += inb(port+FramesDeferred) & 0xFF;
	ctlr->bytesrcvdok += ins(port+BytesRcvdOk) & 0xFFFF;
	ctlr->bytesxmittedok += ins(port+BytesXmittedOk) & 0xFFFF;
	ctlr->stats[FramesXmittedOk] += (u & 0x30)<<4;
	ctlr->stats[FramesRcvdOk] += (u & 0x03)<<8;
	ctlr->stats[BytesRcvdOk] += ins(port+BytesRcvdOk) & 0xFFFF;
	ctlr->stats[BytesRcvdOk+1] += ins(port+BytesXmittedOk) & 0xFFFF;

	if(ctlr->xcvr == xcvr100BaseTX || ctlr->xcvr == xcvr100BaseFX){
		COMMAND(port, SelectRegisterWindow, Wdiagnostic);
		STATUS(port);
		ctlr->badssd += inb(port+BadSSD);
		ctlr->stats[BytesRcvdOk+2] += inb(port+BadSSD);
	}

	COMMAND(port, SelectRegisterWindow, w);


@@ 656,7 709,7 @@ interrupt(Ureg*, void* arg)

	ctlr->interrupts++;
	ctlr->timer += inb(port+Timer) & 0xFF;
	for(status = STATUS(port); status & interruptMask; status = STATUS(port)){
	while((status = STATUS(port)) & (interruptMask|interruptLatch)){
		if(status & hostError){
			/*
			 * Adapter failure, try to find out why, reset if


@@ 732,7 785,7 @@ interrupt(Ureg*, void* arg)
				if(ctlr->busmaster == 0)
					COMMAND(port, TxReset, 0);
				else
					COMMAND(port, TxReset, dmaReset);
					COMMAND(port, TxReset, (updnReset|dmaReset));
				while(STATUS(port) & commandInProgress)
					;
				COMMAND(port, SetTxStartThresh, ctlr->txthreshold>>ctlr->ts);


@@ 768,8 821,9 @@ interrupt(Ureg*, void* arg)
		 */
		if(status & interruptMask)
			panic("#l%d: interrupt mask 0x%uX\n", ether->ctlrno, status);

		COMMAND(port, AcknowledgeInterrupt, interruptLatch);
	}
	COMMAND(port, AcknowledgeInterrupt, interruptLatch);

	COMMAND(port, SelectRegisterWindow, w);
	unlock(&ctlr->wlock);


@@ 793,18 847,18 @@ ifstat(Ether* ether, void* a, long n, ulong offset)

	len = sprint(buf, "interrupts: %ld\n", ctlr->interrupts);
	len += sprint(buf+len, "timer: %ld\n", ctlr->timer);
	len += sprint(buf+len, "carrierlost: %ld\n", ctlr->carrierlost);
	len += sprint(buf+len, "sqeerrors: %ld\n", ctlr->sqeerrors);
	len += sprint(buf+len, "multiplecolls: %ld\n", ctlr->multiplecolls);
	len += sprint(buf+len, "singlecollframes: %ld\n", ctlr->singlecollframes);
	len += sprint(buf+len, "latecollisions: %ld\n", ctlr->latecollisions);
	len += sprint(buf+len, "rxoverruns: %ld\n", ctlr->rxoverruns);
	len += sprint(buf+len, "framesxmittedok: %ld\n", ctlr->framesxmittedok);
	len += sprint(buf+len, "framesrcvdok: %ld\n", ctlr->framesrcvdok);
	len += sprint(buf+len, "framesdeferred: %ld\n", ctlr->framesdeferred);
	len += sprint(buf+len, "bytesrcvdok: %ld\n", ctlr->bytesrcvdok);
	len += sprint(buf+len, "bytesxmittedok: %ld\n", ctlr->bytesxmittedok);
	sprint(buf+len, "badssd: %ld\n", ctlr->badssd);
	len += sprint(buf+len, "carrierlost: %ld\n", ctlr->stats[CarrierLost]);
	len += sprint(buf+len, "sqeerrors: %ld\n", ctlr->stats[SqeErrors]);
	len += sprint(buf+len, "multiplecolls: %ld\n", ctlr->stats[MultipleColls]);
	len += sprint(buf+len, "singlecollframes: %ld\n", ctlr->stats[SingleCollFrames]);
	len += sprint(buf+len, "latecollisions: %ld\n", ctlr->stats[LateCollisions]);
	len += sprint(buf+len, "rxoverruns: %ld\n", ctlr->stats[RxOverruns]);
	len += sprint(buf+len, "framesxmittedok: %ld\n", ctlr->stats[FramesXmittedOk]);
	len += sprint(buf+len, "framesrcvdok: %ld\n", ctlr->stats[FramesRcvdOk]);
	len += sprint(buf+len, "framesdeferred: %ld\n", ctlr->stats[FramesDeferred]);
	len += sprint(buf+len, "bytesrcvdok: %ld\n", ctlr->stats[BytesRcvdOk]);
	len += sprint(buf+len, "bytesxmittedok: %ld\n", ctlr->stats[BytesRcvdOk+1]);
	sprint(buf+len, "badssd: %ld\n", ctlr->stats[BytesRcvdOk+2]);

	return readstr(offset, a, n, buf);
}


@@ 1037,6 1091,9 @@ tcm59Xpci(Ether* ether)
	while(p = pcimatch(p, 0x10B7, 0)){
		port = p->bar[0] & ~0x01;
		irq = p->intl;
		COMMAND(port, GlobalReset, 0);
		while(STATUS(port) & commandInProgress)
			;
		if(ether->port == 0 || ether->port == port){
			ether->irq = irq;
			ether->tbdf = p->tbdf;


@@ 1074,6 1131,9 @@ autoselect(int port, int rxstatus9)
		media = ins(port+ResetOptions);
	}

	if(media & miiConnector)
		return xcvrMii;

	COMMAND(port, SelectRegisterWindow, Wdiagnostic);
	x = ins(port+MediaStatus) & ~(dcConverterEnabled|linkBeatEnable|jabberGuardEnable);
	outs(port+MediaStatus, x);


@@ 1139,10 1199,22 @@ autoselect(int port, int rxstatus9)
	return autoSelect;
}

static int
eepromdata(int port, int offset)
{
	COMMAND(port, SelectRegisterWindow, Wsetup);
	while(EEPROMBUSY(port))
		;
	EEPROMCMD(port, EepromReadRegister, offset);
	while(EEPROMBUSY(port))
		;
	return EEPROMDATA(port);
}

int
etherelnk3reset(Ether* ether)
{
	int busmaster, i, port, rxearly, rxstatus9, x, xcvr;
	int busmaster, did, i, port, rxearly, rxstatus9, x, xcvr;
	Block *bp, **bpp;
	Adapter *ap;
	uchar ea[Eaddrlen];


@@ 1157,9 1229,6 @@ etherelnk3reset(Ether* ether)
	 * If an adapter is found save the IRQ and transceiver type.
	 */
	port = 0;
	rxearly = 2044;
	rxstatus9 = 0;
	xcvr = 0;
	bpp = &adapter;
	for(bp = *bpp; bp; bp = bp->next){
		ap = (Adapter*)bp->rp;


@@ 1173,44 1242,60 @@ etherelnk3reset(Ether* ether)
		}
		bpp = &bp->next;
	}
	if(port == 0 && (port = tcm5XXpcmcia(ether))){
		xcvr = ((ins(port+AddressConfig) & xcvrMask9)>>14)<<20;
		rxstatus9 = 1;
	}
	else if(port == 0 && (port = tcm59Xpci(ether))){
		COMMAND(port, GlobalReset, 0);
		while(STATUS(port) & commandInProgress)
			;
	if(port == 0)
		port = tcm5XXpcmcia(ether);
	if(port == 0)
		port = tcm59Xpci(ether);
	if(port == 0)
		port = tcm5XXeisa(ether);
	if(port == 0)
		port = tcm509isa(ether);
	if(port == 0)
		return -1;
	/*
	 * Read the DeviceID from the EEPROM, it's at offset 0x03,
	 * and do something depending on capabilities.
	 */
	switch(did = eepromdata(port, 0x03)){

	case 0x9000:
	case 0x9001:
	case 0x9050:
	case 0x9051:
		if(BUSTYPE(ether->tbdf) != BusPCI)
			goto buggery;
		busmaster = 2;
		goto vortex;

	case 0x5900:
	case 0x5920:
	case 0x5950:
	case 0x5951:
	case 0x5952:
	case 0x5970:
	case 0x5971:
	case 0x5972:
		busmaster = 1;
	vortex:
		COMMAND(port, SelectRegisterWindow, Wfifo);
		rxearly = 8188;
		xcvr = inl(port+InternalConfig) & (autoSelect|xcvrMask);
	}
	else if(port == 0 && (port = tcm5XXeisa(ether))){
		x = ins(port+ProductID);
		if((x & 0xFF00) == 0x5900){
			COMMAND(port, SelectRegisterWindow, Wfifo);
			rxearly = 8188;
			xcvr = inl(port+InternalConfig) & (autoSelect|xcvrMask);
		}
		else{
			x = ins(port+AddressConfig);
			xcvr = ((x & xcvrMask9)>>14)<<20;
			if(x & autoSelect9)
				xcvr |= autoSelect;
			rxstatus9 = 1;
		}
	}
	else if(port == 0 && (port = tcm509isa(ether))){
		rxearly = 8188;
		rxstatus9 = 0;
		break;

	buggery:
	default:
		busmaster = 0;
		COMMAND(port, SelectRegisterWindow, Wsetup);
		x = ins(port+AddressConfig);
		xcvr = ((x & xcvrMask9)>>14)<<20;
		if(x & autoSelect9)
			xcvr |= autoSelect;
		rxearly = 2044;
		rxstatus9 = 1;
		break;
	}

	if(port == 0)
		return -1;

	/*
	 * Check if the adapter's station address is to be overridden.
	 * If not, read it from the EEPROM and set in ether->ea prior to loading the


@@ 1218,14 1303,8 @@ etherelnk3reset(Ether* ether)
	 */
	memset(ea, 0, Eaddrlen);
	if(memcmp(ea, ether->ea, Eaddrlen) == 0){
		COMMAND(port, SelectRegisterWindow, Wsetup);
		while(EEPROMBUSY(port))
			;
		for(i = 0; i < Eaddrlen/2; i++){
			EEPROMCMD(port, EepromReadRegister, i);
			while(EEPROMBUSY(port))
				;
			x = EEPROMDATA(port);
			x = eepromdata(port, i);
			ether->ea[2*i] = x>>8;
			ether->ea[2*i+1] = x;
		}


@@ 1246,7 1325,7 @@ etherelnk3reset(Ether* ether)
	x = ins(port+MediaStatus) & ~(linkBeatEnable|jabberGuardEnable);
	outs(port+MediaStatus, x);
	if(x & dataRate100){
		busmaster = 1;
		ether->mbps = 100;
		x = inl(port+InternalConfig) & ~ramPartitionMask;
		outl(port+InternalConfig, x|ramPartition1to1);
	}


@@ 1254,10 1333,11 @@ etherelnk3reset(Ether* ether)
		busmaster = 0;
	switch(xcvr){

	case xcvrMii:
		break;

	case xcvr100BaseTX:
	case xcvr100BaseFX:
		ether->mbps = 100;
		/*FALLTHROUGH*/
	case xcvr10BaseT:
		/*
		 * Enable Link Beat and Jabber to start the

M pc/main.c => pc/main.c +1 -0
@@ 81,6 81,7 @@ main(void)
	archinit();
	confinit();
	xinit();
	dmainit();
	trapinit();
	screeninit();
	printinit();

M pc/memory.c => pc/memory.c +1 -1
@@ 21,7 21,7 @@ enum {
	KB		= 1024,

	MemMinMB	= 4,		/* minimum physical memory (<=4MB) */
	MemMaxMB	= 192,		/* maximum physical memory to check */
	MemMaxMB	= 512,		/* maximum physical memory to check */

	NMemBase	= 10,
};