## 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) {
.
|