|
|
Plan 9 NeXT
#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"
/*
* National Semiconductor DP83905 AT/LANTIC.
*
* It doesn't seem possible to tell which mode (NE2000 or WD8003)
* the chip is configured in without a lot of work. For now we'll
* just assume WD8003 mode.
* Driver written for the Dauphin DTR-1.
*/
enum { /* Shared Memory Compatible Mode */
Control1 = 0x00, /* (WO) */
ATDetect = 0x01, /* (RO) */
Control2 = 0x05, /* (WO) */
Lar = 0x08, /* LAN Address Registers */
};
enum { /* Control1 */
Rst = 0x80, /* software reset */
Meme = 0x40, /* memory enable */
};
enum { /* ATDetect */
ATdet = 0x01, /* 8 or 16-bit slot */
};
enum { /* Control2 */
Memw = 0x40, /* */
M16 = 0x80, /* */
};
static void*
read(Ctlr *ctlr, void *to, ulong from, ulong len)
{
/*
* In this case, 'from' is an index into the shared memory.
*/
memmove(to, (void*)(ctlr->card.mem+from), len);
return to;
}
static void*
write(Ctlr *ctlr, ulong to, void *from, ulong len)
{
/*
* In this case, 'to' is an index into the shared memory.
*/
memmove((void*)(ctlr->card.mem+to), from, len);
return (void*)to;
}
/*
* Get configuration parameters, enable memory.
* There are opportunities here for buckets of code.
* We'll try to resist.
*/
static int
reset(Ctlr *ctlr)
{
int i;
uchar control1, control2;
ulong port;
/*
* Set up the software configuration.
* Use defaults for port, irq, mem and size if not specified.
* Defaults are set for the dumb 8003E which can't be
* autoconfigured.
*/
if(ctlr->card.port == 0)
ctlr->card.port = 0x280;
if(ctlr->card.irq == 0)
ctlr->card.irq = 3;
if(ctlr->card.mem == 0)
ctlr->card.mem = 0xD0000;
if(ctlr->card.size == 0)
ctlr->card.size = 8*1024;
ctlr->card.reset = reset;
ctlr->card.attach = dp8390attach;
ctlr->card.mode = dp8390mode;
ctlr->card.read = read;
ctlr->card.write = write;
ctlr->card.receive = dp8390receive;
ctlr->card.transmit = dp8390transmit;
ctlr->card.intr = dp8390intr;
ctlr->card.watch = 0;
ctlr->card.ram = 1;
port = ctlr->card.port;
for(i = 0; i < sizeof(ctlr->ea); i++)
ctlr->ea[i] = inb(port+Lar+i);
control1 = Meme|((ctlr->card.mem>>13) & 0x3F);
control2 = (ctlr->card.mem>>19) & 0x1F;
if(ctlr->card.bit16 = (inb(port+ATDetect) & ATdet))
control2 |= M16|Memw;
ctlr->card.mem |= KZERO;
/*
* Set the DP8390 ring addresses.
*/
ctlr->card.dp8390 = port+0x10;
ctlr->card.tstart = 0;
ctlr->card.pstart = HOWMANY(sizeof(Etherpkt), Dp8390BufSz);
ctlr->card.pstop = HOWMANY(ctlr->card.size, Dp8390BufSz);
/*
* Enable interface RAM, set interface width.
*/
outb(port+Control1, control1);
outb(port+Control2, control2);
/*
* Finally, init the 8390 and set the
* ethernet address.
*/
dp8390reset(ctlr);
dp8390setea(ctlr);
return 0;
}
void
ether83905link(void)
{
addethercard("DP83905", reset);
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.