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

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


## diffname pc/ether589.c 1995/0331
## diff -e /dev/null /n/fornaxdump/1995/0331/sys/src/brazil/pc/ether589.c
0a
#include "u.h"
#include "../port/lib.h"
#include "mem.h"
#include "dat.h"
#include "fns.h"
#include "io.h"
#include "../port/error.h"
#include "../port/netif.h"

#include "etherif.h"

enum {
	SelectWindow	= 0x01,		/* SelectWindow command */

	Command		= 0x0E,		/* all windows */
	Status		= 0x0E,

	ManufacturerID	= 0x00,		/* window 0 */
	ProductID	= 0x02,
	ConfigControl	= 0x04,
	AddressConfig	= 0x06,
	ResourceConfig	= 0x08,
	EEPROMcmd	= 0x0A,
	EEPROMdata	= 0x0C,
};

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

extern int ether509reset(Ether*);

static int
reset(Ether *ether)
{
	int slot;
	int port;
	ushort x;

	if(ether->irq == 0)
		ether->irq = 10;
	if(ether->port == 0)
		ether->port = 0x3F0;
	port = ether->port;

	slot = pcmspecial("3C589", ether);
	if(slot < 0)
		return -1;

	/* set Window 0 configuration registers */
	COMMAND(port, SelectWindow, 0);

	/* ROM size & base - must be set before we can access ROM */
	/* transceiver type (for now always 10baseT) */
	x = ins(port + AddressConfig);
	outs(port + AddressConfig, x & 0x20);

	/* IRQ must be 3 on 3C589 */
	x = ins(port + ResourceConfig);
	outs(port + ResourceConfig, 0x3000 | (x&0xfff));

	/* move product ID to register */
	while(ins(port+EEPROMcmd) & 0x8000)
		;
	outs(port+EEPROMcmd, (2<<6)|3);
	while(ins(port+EEPROMcmd) & 0x8000)
		;
	x = ins(port+EEPROMdata);
	outs(port + ProductID, x);

	if(ether509reset(ether) < 0){
		pcmspecialclose(slot);
		return -1;
	}
	return 0;
}

void
ether589link(void)
{
	addethercard("3C589", reset);
}
.
## diffname pc/ether589.c 1995/0401
## diff -e /n/fornaxdump/1995/0331/sys/src/brazil/pc/ether589.c /n/fornaxdump/1995/0401/sys/src/brazil/pc/ether589.c
58c
	outs(port + ResourceConfig, 0x3f00 | (x&0xfff));
.
41c
		ether->port = 0x240;
.
## diffname pc/ether589.c 1995/0627
## diff -e /n/fornaxdump/1995/0401/sys/src/brazil/pc/ether589.c /n/fornaxdump/1995/0627/sys/src/brazil/pc/ether589.c
72a
	delay(100);
	COMMAND(port, SelectWindow, 4);
	if(ins(port+MediaStatus) & LinkBeatOk){
		/* reselect window 1 for normal operation */
		COMMAND(port, SelectWindow, 1);
		print("10baseT 3C589\n");
		return 0;
	}

	/* try configuring as a 10base2 */
	COMMAND(port, GlobalReset, 0);
	if(configASIC(ether, port, XcvrBNC) < 0){
		pcmspecialclose(slot);
		return -1;
	}
	print("BNC 3C589\n");
.
69c
	return ether509reset(ether);
}

static int
reset(Ether *ether)
{
	int slot;
	int port;

	if(ether->irq == 0)
		ether->irq = 10;
	if(ether->port == 0)
		ether->port = 0x240;
	port = ether->port;

	slot = pcmspecial("3C589", ether);
	if(slot < 0)
		return -1;

	/* try configuring as a 10baseT */
	if(configASIC(ether, port, Xcvr10BaseT) < 0){
.
54c
	outs(port + AddressConfig, (x & 0x20) | xcvr);
.
52c
	/* transceiver type is 2 for 'figure it out'  */
.
38,47d
34,35d
32c
configASIC(Ether *ether, int port, int xcvr)
.
24a

	FIFOdiag	= 0x04,		/* window 4 */
	MediaStatus	= 0x0A,

					/* MediaStatus bits */
	JabberEna	= 0x0040,	/* Jabber Enabled (writeable) */
	LinkBeatEna	= 0x0080,	/* Link Beat Enabled (writeable) */
	LinkBeatOk	= 0x0800,	/* Valid link beat detected (ro) */
.
17a
	XcvrTypeMask	= 0xC000,	/* Transceiver Type Select */
	Xcvr10BaseT	= 0x0000,
	XcvrAUI		= 0x4000,
	XcvrBNC		= 0xC000,

.
12a
	GlobalReset	= 0x00,		/* Global Reset */
.
## diffname pc/ether589.c 1995/1019
## diff -e /n/fornaxdump/1995/0627/sys/src/brazil/pc/ether589.c /n/fornaxdump/1995/1019/sys/src/brazil/pc/ether589.c
60c
	outs(port + ResourceConfig, 0x3f00 | (x&0xff));
.
56c
	outs(port + AddressConfig, (x & 0xf0) | xcvr);
.
## diffname pc/ether589.c 1996/0521
## diff -e /n/fornaxdump/1995/1019/sys/src/brazil/pc/ether589.c /n/fornaxdump/1996/0521/sys/src/brazil/pc/ether589.c
71c
	r = ether509reset(ether);
	outs(port + ResourceConfig, 0x3f00);
	return r;
.
55a
print("x = %uX\n", x);
.
48a
int r;
.
## diffname pc/ether589.c 1996/0522
## diff -e /n/fornaxdump/1996/0521/sys/src/brazil/pc/ether589.c /n/fornaxdump/1996/0522/sys/src/brazil/pc/ether589.c
73,75c
	return ether509reset(ether);
.
57d
49d
## diffname pc/ether589.c 1996/0607
## diff -e /n/fornaxdump/1996/0522/sys/src/brazil/pc/ether589.c /n/fornaxdump/1996/0607/sys/src/brazil/pc/ether589.c
62,71c
	return etherelnk3reset(ether);
.
59,60c
	outs(port + ResourceConfig, 0x3F00);
.
55,56c
	outs(port + AddressConfig, xcvr);
.
52a
	x = ins(port+ConfigControl);
	outs(port+ConfigControl, x|1);

.
43c
extern int etherelnk3reset(Ether*);
.
## diffname pc/ether589.c 1996/0613
## diff -e /n/fornaxdump/1996/0607/sys/src/brazil/pc/ether589.c /n/fornaxdump/1996/0613/sys/src/brazil/pc/ether589.c
102c
	print("BNC %s\n", ether->type);
.
92c
		print("10baseT %s\n", ether->type);
.
78,80c
	if((slot = pcmspecial("3C589", ether)) < 0){
		if((slot = pcmspecial("3C562", ether)) < 0)
			return -1;
		strcpy(ether->type, "3C562");
	}
.
60,62d
53,54c
	/* IRQ must be 3 on 3C589/3C562 */
	outs(port + ResourceConfig, 0x3F00);
.
51a
	outs(port+ConfigControl, 1);
.
48,49d
## diffname pc/ether589.c 1996/0614
## diff -e /n/fornaxdump/1996/0613/sys/src/brazil/pc/ether589.c /n/fornaxdump/1996/0614/sys/src/brazil/pc/ether589.c
107a
	addethercard("3C562", reset);
.
74,78c
	if((slot = pcmspecial(ether->type, ether)) < 0)
		return -1;
.
## diffname pc/ether589.c 1998/0312
## diff -e /n/fornaxdump/1996/0614/sys/src/brazil/pc/ether589.c /n/emeliedump/1998/0312/sys/src/brazil/pc/ether589.c
97c
	print("#l%d: xcvr10Base2 %s\n", ether->ctlrno, ether->type);

.
93c
	if(configASIC(ether, port, xcvr10Base2) < 0){
.
83,87c
	COMMAND(port, SelectRegisterWindow, Wdiagnostic);
	if(ins(port+MediaStatus) & linkBeatDetect){
		COMMAND(port, SelectRegisterWindow, Wop);
		print("#l%d: xcvr10BaseT %s\n", ether->ctlrno, ether->type);
.
77,78c
	/* try configuring as a 10BaseT */
	if(configASIC(ether, port, xcvr10BaseT) < 0){
.
63c
reset(Ether* ether)
.
58a
	COMMAND(port, TxReset, 0);
	while(STATUS(port) & commandInProgress)
		;
	COMMAND(port, RxReset, 0);
	while(STATUS(port) & commandInProgress)
		;

.
55,57c
	x = ins(port+AddressConfig) & ~xcvrMask9;
	x |= (xcvr>>20)<<14;
	outs(port+AddressConfig, x);
.
49,50c
	COMMAND(port, SelectRegisterWindow, Wsetup);
	outs(port+ConfigControl, Ena);
.
47a
	int x;

.
46c
configASIC(Ether* ether, int port, int xcvr)
.
42a
enum {						/* Window 4 - diagnostic */
	Wdiagnostic		= 0x0004,
						/* registers */
	MediaStatus		= 0x000A,
						/* MediaStatus bits */
	linkBeatDetect		= 0x0800,
};

.
41c
enum {						/* Window 3 - FIFO management */
	Wfifo			= 0x0003,
						/* registers */
	InternalConfig		= 0x0000,	/* 3C509B, 3C589, 3C59[0257] */
						/* InternalConfig bits */
	xcvr10BaseT		= 0x00000000,
	xcvr10Base2		= 0x00300000,
};
.
35,38c
enum {						/* Window 1 - operating set */
	Wop			= 0x0001,
.
32,33c
enum {						/* Window 0 - setup */
	Wsetup			= 0x0000,
						/* registers */
	ManufacturerID		= 0x0000,	/* 3C5[08]*, 3C59[27] */
	ProductID		= 0x0002,	/* 3C5[08]*, 3C59[27] */
	ConfigControl		= 0x0004,	/* 3C5[08]*, 3C59[27] */
	AddressConfig		= 0x0006,	/* 3C5[08]*, 3C59[27] */
	ResourceConfig		= 0x0008,	/* 3C5[08]*, 3C59[27] */
	EepromCommand		= 0x000A,
	EepromData		= 0x000C,
						/* AddressConfig Bits */
	autoSelect9		= 0x0080,
	xcvrMask9		= 0xC000,
						/* ConfigControl bits */
	Ena			= 0x0001,
	base10TAvailable9	= 0x0200,
	coaxAvailable9		= 0x1000,
	auiAvailable9		= 0x2000,
						/* EepromCommand bits */
	EepromReadRegister	= 0x0080,
	EepromBusy		= 0x8000,
};
.
24,30c
#define COMMAND(port, cmd, a)	outs((port)+CommandR, ((cmd)<<11)|(a))
#define STATUS(port)		ins((port)+IntStatusR)
.
19,22c
enum {						/* IntStatus bits */
	commandInProgress	= 0x1000,
};
.
16,17c
enum {						/* Commands */
	GlobalReset		= 0x0000,
	SelectRegisterWindow	= 0x0001,
	RxReset			= 0x0005,
	TxReset			= 0x000B,
	AcknowledgeInterrupt	= 0x000D,
};
.
12,14c
enum {						/* all windows */
	CommandR		= 0x000E,
	IntStatusR		= 0x000E,
};
.
0a
/*
 * 3C589 and 3C562.
 * To do:
 *	check xcvr10Base2 still works (is GlobalReset necessary?).
 *	pull the station address out of the card space for the 3C562,
 *	it has no EEPROM.
 */
.
## diffname pc/ether589.c 1999/0219
## diff -e /n/emeliedump/1998/0312/sys/src/brazil/pc/ether589.c /n/emeliedump/1999/0219/sys/src/brazil/pc/ether589.c
154a
	addethercard("589E", reset);
.
## diffname pc/ether589.c 1999/0714
## diff -e /n/emeliedump/1999/0219/sys/src/brazil/pc/ether589.c /n/emeliedump/1999/0714/sys/src/brazil/pc/ether589.c
122a
	if(ioalloc(port, 0x10, 0, "3C589") < 0)
		return -1;

.
## diffname pc/ether589.c 1999/0716
## diff -e /n/emeliedump/1999/0714/sys/src/brazil/pc/ether589.c /n/emeliedump/1999/0716/sys/src/brazil/pc/ether589.c
145a
		iofree(port);
.
131a
		iofree(port);
.
127a
	}
.
126c
	if((slot = pcmspecial(ether->type, ether)) < 0){
		iofree(port);
.
## diffname pc/ether589.c 1999/0916
## diff -e /n/emeliedump/1999/0716/sys/src/brazil/pc/ether589.c /n/emeliedump/1999/0916/sys/src/brazil/pc/ether589.c
152,154c
	return -1;		/* not reached */
.
146,150c
	if(want==WantAny || want==Want10B2){
		COMMAND(port, GlobalReset, 0);
		if(configASIC(ether, port, xcvr10Base2) < 0){
			pcmspecialclose(slot);
			iofree(port);
			return -1;
		}
		print("#l%d: xcvr10Base2 %s\n", ether->ctlrno, ether->type);
		return 0;
.
137,143d
132,135c
	if(want==WantAny || want==Want10BT){
		if(configASIC(ether, port, xcvr10BaseT) < 0){
			pcmspecialclose(slot);
			iofree(port);
			return -1;
		}
		delay(100);
		COMMAND(port, SelectRegisterWindow, Wdiagnostic);
		if((ins(port+MediaStatus)&linkBeatDetect) || want==Want10BT){
			COMMAND(port, SelectRegisterWindow, Wop);
			print("#l%d: xcvr10BaseT %s\n", ether->ctlrno, ether->type);
			return 0;
		}
.
130a
	/*
	 * Allow user to specify desired media in plan9.ini
	 */
	want = WantAny;
	for(i = 0; i < ether->nopt; i++){
		if(cistrncmp(ether->opt[i], "media=", 6) != 0)
			continue;
		p = ether->opt[i]+6;
		if(cistrcmp(p, "10base2") == 0)
			want = Want10B2;
		else if(cistrcmp(p, "10baseT") == 0)
			want = Want10BT;
	}
	
.
115a
	enum { WantAny, Want10BT, Want10B2 };
	int want;
	char *p;
.
114c
	int i, slot;
.
## diffname pc/ether589.c 2000/0605
## diff -e /n/emeliedump/1999/0916/sys/src/brazil/pc/ether589.c /n/emeliedump/2000/0605/sys/src/9/pc/ether589.c
172c
		print("#l%d: xcvr10Base2 %s\n", ether->ctlrno, type);
.
159c
			print("#l%d: xcvr10BaseT %s\n", ether->ctlrno, type);
.
134a
	 * Read Ethernet address from card memory
	 * on 3C562, but only if the user has not 
	 * overridden it.
	 */
	memset(ea, 0, sizeof ea);
	if(memcmp(ea, ether->ea, 6) == 0 && strcmp(type, "3C562") == 0) {
		if(pcmcistuple(slot, 0x88, ea, 6) == 6) {
			for(i = 0; i < 6; i += 2){
				t = ea[i];
				ea[i] = ea[i+1];
				ea[i+1] = t;
			}
			memmove(ether->ea, ea, 6);
		}
	}
	/*
.
129c
	type = nil;
	slot = -1;
	for(i = 0; tcmpcmcia[i] != nil; i++){
		type = tcmpcmcia[i];
		if((slot = pcmspecial(type, ether)) >= 0)
			break;
	}
	if(slot < 0){
.
117a
	uchar ea[6];
.
114c
	int i, t, slot;
	char *type;
.
84a
static char *tcmpcmcia[] = {
	"3C589",			/* 3COM 589[ABCD] */
	"3C562",			/* 3COM 562 */
	"589E",				/* 3COM Megahertz 589E */
	nil,
};

.
5,6d
## diffname pc/ether589.c 2000/1021
## diff -e /n/emeliedump/2000/0605/sys/src/9/pc/ether589.c /n/emeliedump/2000/1021/sys/src/9/pc/ether589.c
155c
		if(pcmcistuple(slot, 0x88, -1, ea, 6) == 6) {
.

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