Added dp8390 driver. Additional env_parse functions that take argc and argv.
This commit is contained in:
parent
c9ab8cce43
commit
db5a8bb2b8
16 changed files with 3917 additions and 4 deletions
|
@ -28,3 +28,4 @@ all install depend clean:
|
||||||
cd ./bios_wini && $(MAKE) $@
|
cd ./bios_wini && $(MAKE) $@
|
||||||
cd ./cmos && $(MAKE) $@
|
cd ./cmos && $(MAKE) $@
|
||||||
cd ./random && $(MAKE) $@
|
cd ./random && $(MAKE) $@
|
||||||
|
cd ./dp8390 && $(MAKE) $@
|
||||||
|
|
201
drivers/dp8390/3c503.c
Normal file
201
drivers/dp8390/3c503.c
Normal file
|
@ -0,0 +1,201 @@
|
||||||
|
/*
|
||||||
|
* 3c503.c A shared memory driver for Etherlink II board.
|
||||||
|
*
|
||||||
|
* Created: Dec. 20, 1996 by G. Falzoni <falzoni@marina.scn.de>
|
||||||
|
*
|
||||||
|
* Inspired by the TNET package by M. Ostrowski, the driver for Linux
|
||||||
|
* by D. Becker, the Crynwr 3c503 packet driver, and the Amoeba driver.
|
||||||
|
*
|
||||||
|
* It works in shared memory mode and should be used with the
|
||||||
|
* device driver for NS 8390 based cards of Minix. Programmed
|
||||||
|
* I/O could be used as well but would result in poor performance.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "../drivers.h"
|
||||||
|
|
||||||
|
#include <net/gen/ether.h>
|
||||||
|
#include <net/gen/eth_io.h>
|
||||||
|
|
||||||
|
#include "local.h"
|
||||||
|
#include "dp8390.h"
|
||||||
|
#include "3c503.h"
|
||||||
|
|
||||||
|
#if ENABLE_3C503
|
||||||
|
|
||||||
|
#define MILLIS_TO_TICKS(m) (((m)*HZ/1000)+1)
|
||||||
|
|
||||||
|
_PROTOTYPE(static void el2_init, (dpeth_t *dep));
|
||||||
|
_PROTOTYPE(static void el2_stop, (dpeth_t *dep));
|
||||||
|
_PROTOTYPE( static void milli_delay, (unsigned long millis) );
|
||||||
|
|
||||||
|
|
||||||
|
/*===========================================================================*
|
||||||
|
* el2_init *
|
||||||
|
*===========================================================================*/
|
||||||
|
static void el2_init(dep)
|
||||||
|
dpeth_t * dep;
|
||||||
|
{
|
||||||
|
/* Initalize hardware and data structures. */
|
||||||
|
int ix, irq;
|
||||||
|
int sendq_nr;
|
||||||
|
int cntr;
|
||||||
|
|
||||||
|
/* Map the address PROM to lower I/O address range */
|
||||||
|
cntr = inb_el2(dep, EL2_CNTR);
|
||||||
|
outb_el2(dep, EL2_CNTR, cntr | ECNTR_SAPROM);
|
||||||
|
|
||||||
|
/* Read station address from PROM */
|
||||||
|
for (ix = EL2_EA0; ix <= EL2_EA5; ix += 1)
|
||||||
|
dep->de_address.ea_addr[ix] = inb_el2(dep, ix);
|
||||||
|
|
||||||
|
/* Map the 8390 back to lower I/O address range */
|
||||||
|
outb_el2(dep, EL2_CNTR, cntr);
|
||||||
|
|
||||||
|
/* Enable memory, but turn off interrupts until we are ready */
|
||||||
|
outb_el2(dep, EL2_CFGR, ECFGR_IRQOFF);
|
||||||
|
|
||||||
|
dep->de_data_port = dep->de_dp8390_port = dep->de_base_port;
|
||||||
|
dep->de_prog_IO = 0; /* Programmed I/O not yet available */
|
||||||
|
|
||||||
|
/* Check width of data bus:
|
||||||
|
* 1. Write 0 to WTS bit. The board will drive it to 1 if it is a
|
||||||
|
* 16-bit card.
|
||||||
|
* 2. Select page 2
|
||||||
|
* 3. See if it is a 16-bit card
|
||||||
|
* 4. Select page 0
|
||||||
|
*/
|
||||||
|
outb_el2(dep, DP_CR, CR_PS_P0|CR_DM_ABORT|CR_STP);
|
||||||
|
outb_el2(dep, DP_DCR, 0);
|
||||||
|
outb_el2(dep, DP_CR, CR_PS_P2|CR_DM_ABORT|CR_STP);
|
||||||
|
dep->de_16bit = (inb_el2(dep, DP_DCR) & DCR_WTS) != 0;
|
||||||
|
outb_el2(dep, DP_CR, CR_PS_P0|CR_DM_ABORT|CR_STP);
|
||||||
|
|
||||||
|
/* Allocate one send buffer (1.5KB) per 8KB of on board memory. */
|
||||||
|
sendq_nr = (dep->de_ramsize - dep->de_offset_page) / 0x2000;
|
||||||
|
if (sendq_nr < 1)
|
||||||
|
sendq_nr = 1;
|
||||||
|
else if (sendq_nr > SENDQ_NR)
|
||||||
|
sendq_nr = SENDQ_NR;
|
||||||
|
|
||||||
|
dep->de_sendq_nr = sendq_nr;
|
||||||
|
for (ix = 0; ix < sendq_nr; ix++)
|
||||||
|
dep->de_sendq[ix].sq_sendpage = (ix * SENDQ_PAGES) + EL2_SM_START_PG;
|
||||||
|
|
||||||
|
dep->de_startpage = (ix * SENDQ_PAGES) + EL2_SM_START_PG;
|
||||||
|
dep->de_stoppage = EL2_SM_STOP_PG;
|
||||||
|
|
||||||
|
outb_el2(dep, EL2_STARTPG, dep->de_startpage);
|
||||||
|
outb_el2(dep, EL2_STOPPG, dep->de_stoppage);
|
||||||
|
|
||||||
|
/* Point the vector pointer registers somewhere ?harmless?. */
|
||||||
|
outb_el2(dep, EL2_VP2, 0xFF); /* Point at the ROM restart location */
|
||||||
|
outb_el2(dep, EL2_VP1, 0xFF); /* 0xFFFF:0000 (from original sources) */
|
||||||
|
outb_el2(dep, EL2_VP0, 0x00); /* - What for protected mode? */
|
||||||
|
|
||||||
|
/* Set interrupt level for 3c503 */
|
||||||
|
irq = (dep->de_irq &= ~DEI_DEFAULT); /* Strip the default flag. */
|
||||||
|
if (irq == 9) irq = 2;
|
||||||
|
if (irq < 2 || irq > 5) panic("", "bad 3c503 irq configuration", irq);
|
||||||
|
outb_el2(dep, EL2_IDCFG, (0x04 << irq));
|
||||||
|
|
||||||
|
outb_el2(dep, EL2_DRQCNT, 0x08); /* Set burst size to 8 */
|
||||||
|
outb_el2(dep, EL2_DMAAH, EL2_SM_START_PG); /* Put start of TX */
|
||||||
|
outb_el2(dep, EL2_DMAAL, 0x00); /* buffer in the GA DMA reg */
|
||||||
|
|
||||||
|
outb_el2(dep, EL2_CFGR, ECFGR_NORM); /* Enable shared memory */
|
||||||
|
|
||||||
|
if (!debug) {
|
||||||
|
printf("%s: 3c503 at %X:%d:%lX\n",
|
||||||
|
dep->de_name, dep->de_base_port, dep->de_irq,
|
||||||
|
dep->de_linmem + dep->de_offset_page);
|
||||||
|
} else {
|
||||||
|
printf("%s: 3Com Etherlink II %sat I/O address 0x%X, "
|
||||||
|
"memory address 0x%lX, irq %d\n",
|
||||||
|
dep->de_name, dep->de_16bit ? "(16-bit) " : "",
|
||||||
|
dep->de_base_port,
|
||||||
|
dep->de_linmem + dep->de_offset_page,
|
||||||
|
dep->de_irq);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*===========================================================================*
|
||||||
|
* el2_stop *
|
||||||
|
*===========================================================================*/
|
||||||
|
static void el2_stop(dep)
|
||||||
|
dpeth_t * dep;
|
||||||
|
{
|
||||||
|
/* Stops board by disabling interrupts. */
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
printf("%s: stopping Etherlink\n", dep->de_name);
|
||||||
|
#endif
|
||||||
|
outb_el2(dep, EL2_CFGR, ECFGR_IRQOFF);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*===========================================================================*
|
||||||
|
* el2_probe *
|
||||||
|
*===========================================================================*/
|
||||||
|
int el2_probe(dep)
|
||||||
|
dpeth_t * dep;
|
||||||
|
{
|
||||||
|
/* Probe for the presence of an EtherLink II card. Initialize memory
|
||||||
|
* addressing if card detected.
|
||||||
|
*/
|
||||||
|
int iobase, membase;
|
||||||
|
int thin;
|
||||||
|
|
||||||
|
/* Thin ethernet or AUI? */
|
||||||
|
thin = (dep->de_linmem & 1) ? ECNTR_AUI : ECNTR_THIN;
|
||||||
|
|
||||||
|
/* Location registers should have 1 bit set */
|
||||||
|
if (!(iobase = inb_el2(dep, EL2_IOBASE))) return 0;
|
||||||
|
if (!((membase = inb_el2(dep, EL2_MEMBASE)) & 0xF0)) return 0;
|
||||||
|
if ((iobase & (iobase - 1)) || (membase & (membase - 1))) return 0;
|
||||||
|
|
||||||
|
/* Resets board */
|
||||||
|
outb_el2(dep, EL2_CNTR, ECNTR_RESET | thin);
|
||||||
|
milli_delay(1);
|
||||||
|
outb_el2(dep, EL2_CNTR, thin);
|
||||||
|
milli_delay(5);
|
||||||
|
|
||||||
|
/* Map the address PROM to lower I/O address range */
|
||||||
|
outb_el2(dep, EL2_CNTR, ECNTR_SAPROM | thin);
|
||||||
|
if (inb_el2(dep, EL2_EA0) != 0x02 || /* Etherlink II Station address */
|
||||||
|
inb_el2(dep, EL2_EA1) != 0x60 || /* MUST be 02:60:8c:xx:xx:xx */
|
||||||
|
inb_el2(dep, EL2_EA2) != 0x8C)
|
||||||
|
return 0; /* No Etherlink board at this address */
|
||||||
|
|
||||||
|
/* Map the 8390 back to lower I/O address range */
|
||||||
|
outb_el2(dep, EL2_CNTR, thin);
|
||||||
|
|
||||||
|
/* Setup shared memory addressing for 3c503 */
|
||||||
|
dep->de_linmem = ((membase & 0xC0) ? EL2_BASE_0D8000 : EL2_BASE_0C8000) +
|
||||||
|
((membase & 0xA0) ? (EL2_BASE_0CC000 - EL2_BASE_0C8000) : 0x0000);
|
||||||
|
dep->de_offset_page = (EL2_SM_START_PG * DP_PAGESIZE);
|
||||||
|
dep->de_ramsize = (EL2_SM_STOP_PG - EL2_SM_START_PG) * DP_PAGESIZE;
|
||||||
|
|
||||||
|
/* (Bad kludge, something Philip needs to look into. -- kjb) */
|
||||||
|
dep->de_linmem -= dep->de_offset_page;
|
||||||
|
dep->de_ramsize += dep->de_offset_page;
|
||||||
|
|
||||||
|
/* Board initialization and stop functions */
|
||||||
|
dep->de_initf = el2_init;
|
||||||
|
dep->de_stopf = el2_stop;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void milli_delay(unsigned long millis)
|
||||||
|
{
|
||||||
|
tickdelay(MILLIS_TO_TICKS(millis));
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* ENABLE_3C503 */
|
||||||
|
|
||||||
|
/** 3c503.c **/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* $PchId: 3c503.c,v 1.3 2003/09/10 15:33:04 philip Exp $
|
||||||
|
*/
|
64
drivers/dp8390/3c503.h
Normal file
64
drivers/dp8390/3c503.h
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
/*
|
||||||
|
* 3c503.h A shared memory driver for Etherlink II board.
|
||||||
|
*
|
||||||
|
* Created: Dec. 20, 1996 by G. Falzoni <falzoni@marina.scn.de>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define EL2_MEMTEST 0 /* Set to 1 for on board memory test */
|
||||||
|
|
||||||
|
#define EL2_GA 0x0400 /* Offset of registers in Gate Array */
|
||||||
|
|
||||||
|
/* EtherLink II card */
|
||||||
|
|
||||||
|
#define EL2_STARTPG (EL2_GA+0x00) /* Start page matching DP_PSTARTPG */
|
||||||
|
#define EL2_STOPPG (EL2_GA+0x01) /* Stop page matching DP_PSTOPPG */
|
||||||
|
#define EL2_DRQCNT (EL2_GA+0x02) /* DMA burst count */
|
||||||
|
#define EL2_IOBASE (EL2_GA+0x03) /* I/O base jumpers (bit coded) */
|
||||||
|
#define EL2_MEMBASE (EL2_GA+0x04) /* Memory base jumpers (bit coded) */
|
||||||
|
#define EL2_CFGR (EL2_GA+0x05) /* Configuration Register for GA */
|
||||||
|
#define EL2_CNTR (EL2_GA+0x06) /* Control(write) and status(read) */
|
||||||
|
#define EL2_STATUS (EL2_GA+0x07)
|
||||||
|
#define EL2_IDCFG (EL2_GA+0x08) /* Interrupt/DMA configuration reg */
|
||||||
|
#define EL2_DMAAH (EL2_GA+0x09) /* DMA address register (High byte) */
|
||||||
|
#define EL2_DMAAL (EL2_GA+0x0A) /* DMA address register (Low byte) */
|
||||||
|
#define EL2_VP2 (EL2_GA+0x0B) /* Vector pointer - set to */
|
||||||
|
#define EL2_VP1 (EL2_GA+0x0C) /* reset address (0xFFFF:0) */
|
||||||
|
#define EL2_VP0 (EL2_GA+0x0D) /* */
|
||||||
|
#define EL2_FIFOH (EL2_GA+0x0E) /* FIFO for progr. I/O (High byte) */
|
||||||
|
#define EL2_FIFOL (EL2_GA+0x0F) /* FIFO for progr. I/O (Low byte) */
|
||||||
|
|
||||||
|
#define EL2_EA0 0x00 /* Most significant byte of ethernet address */
|
||||||
|
#define EL2_EA1 0x01
|
||||||
|
#define EL2_EA2 0x02
|
||||||
|
#define EL2_EA3 0x03
|
||||||
|
#define EL2_EA4 0x04
|
||||||
|
#define EL2_EA5 0x05 /* Least significant byte of ethernet address */
|
||||||
|
|
||||||
|
/* Bits in EL2_CNTR register */
|
||||||
|
#define ECNTR_RESET 0x01 /* Software Reset */
|
||||||
|
#define ECNTR_THIN 0x02 /* Onboard transceiver enable */
|
||||||
|
#define ECNTR_AUI 0x00 /* Onboard transceiver disable */
|
||||||
|
#define ECNTR_SAPROM 0x04 /* Map the station address prom */
|
||||||
|
|
||||||
|
/* Bits in EL2_CFGR register */
|
||||||
|
#define ECFGR_NORM 0x49 /* Enable 8k shared memory, no DMA, TC int */
|
||||||
|
#define ECFGR_IRQOFF 0xC9 /* As above, disable 8390 IRQ */
|
||||||
|
|
||||||
|
/* Shared memory management parameters */
|
||||||
|
#define EL2_SM_START_PG 0x20 /* First page of TX buffer */
|
||||||
|
#define EL2_SM_STOP_PG 0x40 /* Last page +1 of RX ring */
|
||||||
|
|
||||||
|
/* Physical addresses where an Etherlink board can be configured */
|
||||||
|
#define EL2_BASE_0C8000 0x0C8000
|
||||||
|
#define EL2_BASE_0CC000 0x0CC000
|
||||||
|
#define EL2_BASE_0D8000 0x0D8000
|
||||||
|
#define EL2_BASE_0DC000 0x0DC000
|
||||||
|
|
||||||
|
#define inb_el2(dep,reg) (inb((dep)->de_base_port+(reg)))
|
||||||
|
#define outb_el2(dep,reg,data) (outb((dep)->de_base_port+(reg),(data)))
|
||||||
|
|
||||||
|
/** 3c503.h **/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* $PchId: 3c503.h,v 1.3 2003/09/10 15:34:29 philip Exp $
|
||||||
|
*/
|
44
drivers/dp8390/Makefile
Normal file
44
drivers/dp8390/Makefile
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
# Makefile for dp8390 driver
|
||||||
|
DRIVER = dp8390
|
||||||
|
|
||||||
|
# directories
|
||||||
|
u = /usr
|
||||||
|
i = $u/include
|
||||||
|
s = $i/sys
|
||||||
|
m = $i/minix
|
||||||
|
b = $i/ibm
|
||||||
|
d = ..
|
||||||
|
|
||||||
|
# programs, flags, etc.
|
||||||
|
CC = exec cc
|
||||||
|
CFLAGS = -I$i
|
||||||
|
LDFLAGS = -i
|
||||||
|
LIBS = -lsys -lsysutil -ltimers
|
||||||
|
|
||||||
|
OBJ = 3c503.o dp8390.o ne2000.o rtl8029.o wdeth.o
|
||||||
|
LIBPCI = $d/libpci/pci.o $d/libpci/pci_table.o
|
||||||
|
|
||||||
|
# build local binary
|
||||||
|
all build: $(DRIVER)
|
||||||
|
$(DRIVER): $(OBJ) $(LIBPCI)
|
||||||
|
$(CC) -o $@ $(LDFLAGS) $(OBJ) $(LIBPCI) $(LIBS)
|
||||||
|
install -S 256w $(DRIVER)
|
||||||
|
|
||||||
|
$(LIBPCI):
|
||||||
|
cd $d/libpci && $(MAKE)
|
||||||
|
|
||||||
|
# install with other drivers
|
||||||
|
install: /usr/sbin/$(DRIVER)
|
||||||
|
/usr/sbin/$(DRIVER): $(DRIVER)
|
||||||
|
install -o root -cs $? $@
|
||||||
|
|
||||||
|
# clean up local files
|
||||||
|
clean:
|
||||||
|
rm -f *.o *.bak $(DRIVER)
|
||||||
|
|
||||||
|
depend:
|
||||||
|
/usr/bin/mkdep "$(CC) -E $(CPPFLAGS)" *.c ../libpci/*.c > .depend
|
||||||
|
|
||||||
|
# Include generated dependencies.
|
||||||
|
include .depend
|
||||||
|
|
1986
drivers/dp8390/dp8390.c
Normal file
1986
drivers/dp8390/dp8390.c
Normal file
File diff suppressed because it is too large
Load diff
298
drivers/dp8390/dp8390.h
Normal file
298
drivers/dp8390/dp8390.h
Normal file
|
@ -0,0 +1,298 @@
|
||||||
|
/*
|
||||||
|
dp8390.h
|
||||||
|
|
||||||
|
Created: before Dec 28, 1992 by Philip Homburg
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* National Semiconductor DP8390 Network Interface Controller. */
|
||||||
|
|
||||||
|
/* Page 0, for reading ------------- */
|
||||||
|
#define DP_CR 0x0 /* Read side of Command Register */
|
||||||
|
#define DP_CLDA0 0x1 /* Current Local Dma Address 0 */
|
||||||
|
#define DP_CLDA1 0x2 /* Current Local Dma Address 1 */
|
||||||
|
#define DP_BNRY 0x3 /* Boundary Pointer */
|
||||||
|
#define DP_TSR 0x4 /* Transmit Status Register */
|
||||||
|
#define DP_NCR 0x5 /* Number of Collisions Register */
|
||||||
|
#define DP_FIFO 0x6 /* Fifo ?? */
|
||||||
|
#define DP_ISR 0x7 /* Interrupt Status Register */
|
||||||
|
#define DP_CRDA0 0x8 /* Current Remote Dma Address 0 */
|
||||||
|
#define DP_CRDA1 0x9 /* Current Remote Dma Address 1 */
|
||||||
|
#define DP_DUM1 0xA /* unused */
|
||||||
|
#define DP_DUM2 0xB /* unused */
|
||||||
|
#define DP_RSR 0xC /* Receive Status Register */
|
||||||
|
#define DP_CNTR0 0xD /* Tally Counter 0 */
|
||||||
|
#define DP_CNTR1 0xE /* Tally Counter 1 */
|
||||||
|
#define DP_CNTR2 0xF /* Tally Counter 2 */
|
||||||
|
|
||||||
|
/* Page 0, for writing ------------- */
|
||||||
|
#define DP_CR 0x0 /* Write side of Command Register */
|
||||||
|
#define DP_PSTART 0x1 /* Page Start Register */
|
||||||
|
#define DP_PSTOP 0x2 /* Page Stop Register */
|
||||||
|
#define DP_BNRY 0x3 /* Boundary Pointer */
|
||||||
|
#define DP_TPSR 0x4 /* Transmit Page Start Register */
|
||||||
|
#define DP_TBCR0 0x5 /* Transmit Byte Count Register 0 */
|
||||||
|
#define DP_TBCR1 0x6 /* Transmit Byte Count Register 1 */
|
||||||
|
#define DP_ISR 0x7 /* Interrupt Status Register */
|
||||||
|
#define DP_RSAR0 0x8 /* Remote Start Address Register 0 */
|
||||||
|
#define DP_RSAR1 0x9 /* Remote Start Address Register 1 */
|
||||||
|
#define DP_RBCR0 0xA /* Remote Byte Count Register 0 */
|
||||||
|
#define DP_RBCR1 0xB /* Remote Byte Count Register 1 */
|
||||||
|
#define DP_RCR 0xC /* Receive Configuration Register */
|
||||||
|
#define DP_TCR 0xD /* Transmit Configuration Register */
|
||||||
|
#define DP_DCR 0xE /* Data Configuration Register */
|
||||||
|
#define DP_IMR 0xF /* Interrupt Mask Register */
|
||||||
|
|
||||||
|
/* Page 1, read/write -------------- */
|
||||||
|
#define DP_CR 0x0 /* Command Register */
|
||||||
|
#define DP_PAR0 0x1 /* Physical Address Register 0 */
|
||||||
|
#define DP_PAR1 0x2 /* Physical Address Register 1 */
|
||||||
|
#define DP_PAR2 0x3 /* Physical Address Register 2 */
|
||||||
|
#define DP_PAR3 0x4 /* Physical Address Register 3 */
|
||||||
|
#define DP_PAR4 0x5 /* Physical Address Register 4 */
|
||||||
|
#define DP_PAR5 0x6 /* Physical Address Register 5 */
|
||||||
|
#define DP_CURR 0x7 /* Current Page Register */
|
||||||
|
#define DP_MAR0 0x8 /* Multicast Address Register 0 */
|
||||||
|
#define DP_MAR1 0x9 /* Multicast Address Register 1 */
|
||||||
|
#define DP_MAR2 0xA /* Multicast Address Register 2 */
|
||||||
|
#define DP_MAR3 0xB /* Multicast Address Register 3 */
|
||||||
|
#define DP_MAR4 0xC /* Multicast Address Register 4 */
|
||||||
|
#define DP_MAR5 0xD /* Multicast Address Register 5 */
|
||||||
|
#define DP_MAR6 0xE /* Multicast Address Register 6 */
|
||||||
|
#define DP_MAR7 0xF /* Multicast Address Register 7 */
|
||||||
|
|
||||||
|
/* Bits in dp_cr */
|
||||||
|
#define CR_STP 0x01 /* Stop: software reset */
|
||||||
|
#define CR_STA 0x02 /* Start: activate NIC */
|
||||||
|
#define CR_TXP 0x04 /* Transmit Packet */
|
||||||
|
#define CR_DMA 0x38 /* Mask for DMA control */
|
||||||
|
#define CR_DM_NOP 0x00 /* DMA: No Operation */
|
||||||
|
#define CR_DM_RR 0x08 /* DMA: Remote Read */
|
||||||
|
#define CR_DM_RW 0x10 /* DMA: Remote Write */
|
||||||
|
#define CR_DM_SP 0x18 /* DMA: Send Packet */
|
||||||
|
#define CR_DM_ABORT 0x20 /* DMA: Abort Remote DMA Operation */
|
||||||
|
#define CR_PS 0xC0 /* Mask for Page Select */
|
||||||
|
#define CR_PS_P0 0x00 /* Register Page 0 */
|
||||||
|
#define CR_PS_P1 0x40 /* Register Page 1 */
|
||||||
|
#define CR_PS_P2 0x80 /* Register Page 2 */
|
||||||
|
#define CR_PS_T1 0xC0 /* Test Mode Register Map */
|
||||||
|
|
||||||
|
/* Bits in dp_isr */
|
||||||
|
#define ISR_PRX 0x01 /* Packet Received with no errors */
|
||||||
|
#define ISR_PTX 0x02 /* Packet Transmitted with no errors */
|
||||||
|
#define ISR_RXE 0x04 /* Receive Error */
|
||||||
|
#define ISR_TXE 0x08 /* Transmit Error */
|
||||||
|
#define ISR_OVW 0x10 /* Overwrite Warning */
|
||||||
|
#define ISR_CNT 0x20 /* Counter Overflow */
|
||||||
|
#define ISR_RDC 0x40 /* Remote DMA Complete */
|
||||||
|
#define ISR_RST 0x80 /* Reset Status */
|
||||||
|
|
||||||
|
/* Bits in dp_imr */
|
||||||
|
#define IMR_PRXE 0x01 /* Packet Received iEnable */
|
||||||
|
#define IMR_PTXE 0x02 /* Packet Transmitted iEnable */
|
||||||
|
#define IMR_RXEE 0x04 /* Receive Error iEnable */
|
||||||
|
#define IMR_TXEE 0x08 /* Transmit Error iEnable */
|
||||||
|
#define IMR_OVWE 0x10 /* Overwrite Warning iEnable */
|
||||||
|
#define IMR_CNTE 0x20 /* Counter Overflow iEnable */
|
||||||
|
#define IMR_RDCE 0x40 /* DMA Complete iEnable */
|
||||||
|
|
||||||
|
/* Bits in dp_dcr */
|
||||||
|
#define DCR_WTS 0x01 /* Word Transfer Select */
|
||||||
|
#define DCR_BYTEWIDE 0x00 /* WTS: byte wide transfers */
|
||||||
|
#define DCR_WORDWIDE 0x01 /* WTS: word wide transfers */
|
||||||
|
#define DCR_BOS 0x02 /* Byte Order Select */
|
||||||
|
#define DCR_LTLENDIAN 0x00 /* BOS: Little Endian */
|
||||||
|
#define DCR_BIGENDIAN 0x02 /* BOS: Big Endian */
|
||||||
|
#define DCR_LAS 0x04 /* Long Address Select */
|
||||||
|
#define DCR_BMS 0x08 /* Burst Mode Select
|
||||||
|
* Called Loopback Select (LS) in
|
||||||
|
* later manuals. Should be set. */
|
||||||
|
#define DCR_AR 0x10 /* Autoinitialize Remote */
|
||||||
|
#define DCR_FTS 0x60 /* Fifo Threshold Select */
|
||||||
|
#define DCR_2BYTES 0x00 /* 2 bytes */
|
||||||
|
#define DCR_4BYTES 0x40 /* 4 bytes */
|
||||||
|
#define DCR_8BYTES 0x20 /* 8 bytes */
|
||||||
|
#define DCR_12BYTES 0x60 /* 12 bytes */
|
||||||
|
|
||||||
|
/* Bits in dp_tcr */
|
||||||
|
#define TCR_CRC 0x01 /* Inhibit CRC */
|
||||||
|
#define TCR_ELC 0x06 /* Encoded Loopback Control */
|
||||||
|
#define TCR_NORMAL 0x00 /* ELC: Normal Operation */
|
||||||
|
#define TCR_INTERNAL 0x02 /* ELC: Internal Loopback */
|
||||||
|
#define TCR_0EXTERNAL 0x04 /* ELC: External Loopback LPBK=0 */
|
||||||
|
#define TCR_1EXTERNAL 0x06 /* ELC: External Loopback LPBK=1 */
|
||||||
|
#define TCR_ATD 0x08 /* Auto Transmit Disable */
|
||||||
|
#define TCR_OFST 0x10 /* Collision Offset Enable (be nice) */
|
||||||
|
|
||||||
|
/* Bits in dp_tsr */
|
||||||
|
#define TSR_PTX 0x01 /* Packet Transmitted (without error)*/
|
||||||
|
#define TSR_DFR 0x02 /* Transmit Deferred, reserved in
|
||||||
|
* later manuals. */
|
||||||
|
#define TSR_COL 0x04 /* Transmit Collided */
|
||||||
|
#define TSR_ABT 0x08 /* Transmit Aborted */
|
||||||
|
#define TSR_CRS 0x10 /* Carrier Sense Lost */
|
||||||
|
#define TSR_FU 0x20 /* FIFO Underrun */
|
||||||
|
#define TSR_CDH 0x40 /* CD Heartbeat */
|
||||||
|
#define TSR_OWC 0x80 /* Out of Window Collision */
|
||||||
|
|
||||||
|
/* Bits in tp_rcr */
|
||||||
|
#define RCR_SEP 0x01 /* Save Errored Packets */
|
||||||
|
#define RCR_AR 0x02 /* Accept Runt Packets */
|
||||||
|
#define RCR_AB 0x04 /* Accept Broadcast */
|
||||||
|
#define RCR_AM 0x08 /* Accept Multicast */
|
||||||
|
#define RCR_PRO 0x10 /* Physical Promiscuous */
|
||||||
|
#define RCR_MON 0x20 /* Monitor Mode */
|
||||||
|
|
||||||
|
/* Bits in dp_rsr */
|
||||||
|
#define RSR_PRX 0x01 /* Packet Received Intact */
|
||||||
|
#define RSR_CRC 0x02 /* CRC Error */
|
||||||
|
#define RSR_FAE 0x04 /* Frame Alignment Error */
|
||||||
|
#define RSR_FO 0x08 /* FIFO Overrun */
|
||||||
|
#define RSR_MPA 0x10 /* Missed Packet */
|
||||||
|
#define RSR_PHY 0x20 /* Multicast Address Match */
|
||||||
|
#define RSR_DIS 0x40 /* Receiver Disabled */
|
||||||
|
#define RSR_DFR 0x80 /* In later manuals: Deferring */
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct dp_rcvhdr
|
||||||
|
{
|
||||||
|
u8_t dr_status; /* Copy of rsr */
|
||||||
|
u8_t dr_next; /* Pointer to next packet */
|
||||||
|
u8_t dr_rbcl; /* Receive Byte Count Low */
|
||||||
|
u8_t dr_rbch; /* Receive Byte Count High */
|
||||||
|
} dp_rcvhdr_t;
|
||||||
|
|
||||||
|
#define DP_PAGESIZE 256
|
||||||
|
|
||||||
|
/* Some macros to simplify accessing the dp8390 */
|
||||||
|
#define inb_reg0(dep, reg) (inb(dep->de_dp8390_port+reg))
|
||||||
|
#define outb_reg0(dep, reg, data) (outb(dep->de_dp8390_port+reg, data))
|
||||||
|
#define inb_reg1(dep, reg) (inb(dep->de_dp8390_port+reg))
|
||||||
|
#define outb_reg1(dep, reg, data) (outb(dep->de_dp8390_port+reg, data))
|
||||||
|
|
||||||
|
/* Software interface to the dp8390 driver */
|
||||||
|
|
||||||
|
struct dpeth;
|
||||||
|
struct iovec_dat;
|
||||||
|
_PROTOTYPE( typedef void (*dp_initf_t), (struct dpeth *dep) );
|
||||||
|
_PROTOTYPE( typedef void (*dp_stopf_t), (struct dpeth *dep) );
|
||||||
|
_PROTOTYPE( typedef void (*dp_user2nicf_t), (struct dpeth *dep,
|
||||||
|
struct iovec_dat *iovp, vir_bytes offset,
|
||||||
|
int nic_addr, vir_bytes count) );
|
||||||
|
_PROTOTYPE( typedef void (*dp_nic2userf_t), (struct dpeth *dep,
|
||||||
|
int nic_addr, struct iovec_dat *iovp,
|
||||||
|
vir_bytes offset, vir_bytes count) );
|
||||||
|
#if 0
|
||||||
|
_PROTOTYPE( typedef void (*dp_getheaderf_t), (struct dpeth *dep,
|
||||||
|
int page, struct dp_rcvhdr *h, u16_t *eth_type) );
|
||||||
|
#endif
|
||||||
|
_PROTOTYPE( typedef void (*dp_getblock_t), (struct dpeth *dep,
|
||||||
|
int page, size_t offset, size_t size, void *dst) );
|
||||||
|
|
||||||
|
/* iovectors are handled IOVEC_NR entries at a time. */
|
||||||
|
#define IOVEC_NR 16
|
||||||
|
|
||||||
|
typedef int irq_hook_t;
|
||||||
|
|
||||||
|
typedef struct iovec_dat
|
||||||
|
{
|
||||||
|
iovec_t iod_iovec[IOVEC_NR];
|
||||||
|
int iod_iovec_s;
|
||||||
|
int iod_proc_nr;
|
||||||
|
vir_bytes iod_iovec_addr;
|
||||||
|
} iovec_dat_t;
|
||||||
|
|
||||||
|
#define SENDQ_NR 2 /* Maximum size of the send queue */
|
||||||
|
#define SENDQ_PAGES 6 /* 6 * DP_PAGESIZE >= 1514 bytes */
|
||||||
|
|
||||||
|
typedef struct dpeth
|
||||||
|
{
|
||||||
|
/* The de_base_port field is the starting point of the probe.
|
||||||
|
* The conf routine also fills de_linmem and de_irq. If the probe
|
||||||
|
* routine knows the irq and/or memory address because they are
|
||||||
|
* hardwired in the board, the probe should modify these fields.
|
||||||
|
* Futhermore, the probe routine should also fill in de_initf and
|
||||||
|
* de_stopf fields with the appropriate function pointers and set
|
||||||
|
* de_prog_IO iff programmed I/O is to be used.
|
||||||
|
*/
|
||||||
|
port_t de_base_port;
|
||||||
|
phys_bytes de_linmem;
|
||||||
|
int de_irq;
|
||||||
|
int de_int_pending;
|
||||||
|
irq_hook_t de_hook;
|
||||||
|
dp_initf_t de_initf;
|
||||||
|
dp_stopf_t de_stopf;
|
||||||
|
int de_prog_IO;
|
||||||
|
char de_name[sizeof("dp8390#n")];
|
||||||
|
|
||||||
|
/* The initf function fills the following fields. Only cards that do
|
||||||
|
* programmed I/O fill in the de_pata_port field.
|
||||||
|
* In addition, the init routine has to fill in the sendq data
|
||||||
|
* structures.
|
||||||
|
*/
|
||||||
|
ether_addr_t de_address;
|
||||||
|
port_t de_dp8390_port;
|
||||||
|
port_t de_data_port;
|
||||||
|
int de_16bit;
|
||||||
|
int de_ramsize;
|
||||||
|
int de_offset_page;
|
||||||
|
int de_startpage;
|
||||||
|
int de_stoppage;
|
||||||
|
|
||||||
|
#if ENABLE_PCI
|
||||||
|
/* PCI config */
|
||||||
|
char de_pci; /* TRUE iff PCI device */
|
||||||
|
u8_t de_pcibus;
|
||||||
|
u8_t de_pcidev;
|
||||||
|
u8_t de_pcifunc;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Do it yourself send queue */
|
||||||
|
struct sendq
|
||||||
|
{
|
||||||
|
int sq_filled; /* this buffer contains a packet */
|
||||||
|
int sq_size; /* with this size */
|
||||||
|
int sq_sendpage; /* starting page of the buffer */
|
||||||
|
} de_sendq[SENDQ_NR];
|
||||||
|
int de_sendq_nr;
|
||||||
|
int de_sendq_head; /* Enqueue at the head */
|
||||||
|
int de_sendq_tail; /* Dequeue at the tail */
|
||||||
|
|
||||||
|
/* Fields for internal use by the dp8390 driver. */
|
||||||
|
int de_flags;
|
||||||
|
int de_mode;
|
||||||
|
eth_stat_t de_stat;
|
||||||
|
iovec_dat_t de_read_iovec;
|
||||||
|
iovec_dat_t de_write_iovec;
|
||||||
|
iovec_dat_t de_tmp_iovec;
|
||||||
|
vir_bytes de_read_s;
|
||||||
|
int de_client;
|
||||||
|
message de_sendmsg;
|
||||||
|
dp_user2nicf_t de_user2nicf;
|
||||||
|
dp_nic2userf_t de_nic2userf;
|
||||||
|
dp_getblock_t de_getblockf;
|
||||||
|
} dpeth_t;
|
||||||
|
|
||||||
|
#define DEI_DEFAULT 0x8000
|
||||||
|
|
||||||
|
#define DEF_EMPTY 0x000
|
||||||
|
#define DEF_PACK_SEND 0x001
|
||||||
|
#define DEF_PACK_RECV 0x002
|
||||||
|
#define DEF_SEND_AVAIL 0x004
|
||||||
|
#define DEF_READING 0x010
|
||||||
|
#define DEF_PROMISC 0x040
|
||||||
|
#define DEF_MULTI 0x080
|
||||||
|
#define DEF_BROAD 0x100
|
||||||
|
#define DEF_ENABLED 0x200
|
||||||
|
#define DEF_STOPPED 0x400
|
||||||
|
|
||||||
|
#define DEM_DISABLED 0x0
|
||||||
|
#define DEM_SINK 0x1
|
||||||
|
#define DEM_ENABLED 0x2
|
||||||
|
|
||||||
|
#if !__minix_vmd
|
||||||
|
#define debug 0 /* Standard Minix lacks debug variable */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* $PchId: dp8390.h,v 1.10 2005/02/10 17:26:06 philip Exp $
|
||||||
|
*/
|
30
drivers/dp8390/local.h
Normal file
30
drivers/dp8390/local.h
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
/*
|
||||||
|
local.h
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define ENABLE_WDETH 1
|
||||||
|
#define ENABLE_NE2000 1
|
||||||
|
#define ENABLE_3C503 1
|
||||||
|
#define ENABLE_PCI 1
|
||||||
|
|
||||||
|
struct dpeth;
|
||||||
|
|
||||||
|
/* 3c503.c */
|
||||||
|
_PROTOTYPE( int el2_probe, (struct dpeth* dep) );
|
||||||
|
|
||||||
|
/* dp8390.c */
|
||||||
|
_PROTOTYPE( u8_t inb, (port_t port) );
|
||||||
|
_PROTOTYPE( u16_t inw, (port_t port) );
|
||||||
|
_PROTOTYPE( void outb, (port_t port, u8_t v) );
|
||||||
|
_PROTOTYPE( void outw, (port_t port, u16_t v) );
|
||||||
|
|
||||||
|
/* ne2000.c */
|
||||||
|
_PROTOTYPE( int ne_probe, (struct dpeth *dep) );
|
||||||
|
_PROTOTYPE( void ne_init, (struct dpeth *dep) );
|
||||||
|
|
||||||
|
/* rtl8029.c */
|
||||||
|
_PROTOTYPE( int rtl_probe, (struct dpeth *dep) );
|
||||||
|
|
||||||
|
/* wdeth.c */
|
||||||
|
_PROTOTYPE( int wdeth_probe, (struct dpeth* dep) );
|
||||||
|
|
334
drivers/dp8390/ne2000.c
Normal file
334
drivers/dp8390/ne2000.c
Normal file
|
@ -0,0 +1,334 @@
|
||||||
|
/*
|
||||||
|
ne2000.c
|
||||||
|
|
||||||
|
Driver for the ne2000 ethernet cards. This file contains only the ne2000
|
||||||
|
specific code, the rest is in dp8390.c
|
||||||
|
|
||||||
|
Created: March 15, 1994 by Philip Homburg <philip@f-mnx.phicoh.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "../drivers.h"
|
||||||
|
|
||||||
|
#include <net/gen/ether.h>
|
||||||
|
#include <net/gen/eth_io.h>
|
||||||
|
#if __minix_vmd
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "local.h"
|
||||||
|
#include "dp8390.h"
|
||||||
|
#include "ne2000.h"
|
||||||
|
|
||||||
|
#if ENABLE_NE2000
|
||||||
|
|
||||||
|
#define N 100
|
||||||
|
|
||||||
|
#define MILLIS_TO_TICKS(m) (((m)*HZ/1000)+1)
|
||||||
|
|
||||||
|
_PROTOTYPE( typedef int (*testf_t), (dpeth_t *dep, int pos, u8_t *pat) );
|
||||||
|
|
||||||
|
u8_t pat0[]= { 0x00, 0x00, 0x00, 0x00 };
|
||||||
|
u8_t pat1[]= { 0xFF, 0xFF, 0xFF, 0xFF };
|
||||||
|
u8_t pat2[]= { 0xA5, 0x5A, 0x69, 0x96 };
|
||||||
|
u8_t pat3[]= { 0x96, 0x69, 0x5A, 0xA5 };
|
||||||
|
|
||||||
|
_PROTOTYPE( static int test_8, (dpeth_t *dep, int pos, u8_t *pat) );
|
||||||
|
_PROTOTYPE( static int test_16, (dpeth_t *dep, int pos, u8_t *pat) );
|
||||||
|
_PROTOTYPE( static void ne_stop, (dpeth_t *dep) );
|
||||||
|
_PROTOTYPE( static void milli_delay, (unsigned long millis) );
|
||||||
|
|
||||||
|
/*===========================================================================*
|
||||||
|
* ne_probe *
|
||||||
|
*===========================================================================*/
|
||||||
|
int ne_probe(dep)
|
||||||
|
dpeth_t *dep;
|
||||||
|
{
|
||||||
|
int byte;
|
||||||
|
int i;
|
||||||
|
int loc1, loc2;
|
||||||
|
testf_t f;
|
||||||
|
|
||||||
|
dep->de_dp8390_port= dep->de_base_port + NE_DP8390;
|
||||||
|
|
||||||
|
/* We probe for an ne1000 or an ne2000 by testing whether the
|
||||||
|
* on board is reachable through the dp8390. Note that the
|
||||||
|
* ne1000 is an 8bit card and has a memory region distict from
|
||||||
|
* the 16bit ne2000
|
||||||
|
*/
|
||||||
|
|
||||||
|
for (dep->de_16bit= 0; dep->de_16bit < 2; dep->de_16bit++)
|
||||||
|
{
|
||||||
|
/* Reset the ethernet card */
|
||||||
|
byte= inb_ne(dep, NE_RESET);
|
||||||
|
milli_delay(2);
|
||||||
|
outb_ne(dep, NE_RESET, byte);
|
||||||
|
milli_delay(2);
|
||||||
|
|
||||||
|
/* Reset the dp8390 */
|
||||||
|
outb_reg0(dep, DP_CR, CR_STP | CR_DM_ABORT);
|
||||||
|
for (i= 0; i < 0x1000 && ((inb_reg0(dep, DP_ISR) & ISR_RST) == 0); i++)
|
||||||
|
; /* Do nothing */
|
||||||
|
|
||||||
|
/* Check if the dp8390 is really there */
|
||||||
|
if ((inb_reg0(dep, DP_CR) & (CR_STP|CR_DM_ABORT)) !=
|
||||||
|
(CR_STP|CR_DM_ABORT))
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Disable the receiver and init TCR and DCR. */
|
||||||
|
outb_reg0(dep, DP_RCR, RCR_MON);
|
||||||
|
outb_reg0(dep, DP_TCR, TCR_NORMAL);
|
||||||
|
if (dep->de_16bit)
|
||||||
|
{
|
||||||
|
outb_reg0(dep, DP_DCR, DCR_WORDWIDE | DCR_8BYTES |
|
||||||
|
DCR_BMS);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
outb_reg0(dep, DP_DCR, DCR_BYTEWIDE | DCR_8BYTES |
|
||||||
|
DCR_BMS);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dep->de_16bit)
|
||||||
|
{
|
||||||
|
loc1= NE2000_START;
|
||||||
|
loc2= NE2000_START + NE2000_SIZE - 4;
|
||||||
|
f= test_16;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
loc1= NE1000_START;
|
||||||
|
loc2= NE1000_START + NE1000_SIZE - 4;
|
||||||
|
f= test_8;
|
||||||
|
}
|
||||||
|
if (f(dep, loc1, pat0) && f(dep, loc1, pat1) &&
|
||||||
|
f(dep, loc1, pat2) && f(dep, loc1, pat3) &&
|
||||||
|
f(dep, loc2, pat0) && f(dep, loc2, pat1) &&
|
||||||
|
f(dep, loc2, pat2) && f(dep, loc2, pat3))
|
||||||
|
{
|
||||||
|
/* We don't need a memory segment */
|
||||||
|
dep->de_linmem= 0;
|
||||||
|
if (!dep->de_pci)
|
||||||
|
dep->de_initf= ne_init;
|
||||||
|
dep->de_stopf= ne_stop;
|
||||||
|
dep->de_prog_IO= 1;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*===========================================================================*
|
||||||
|
* ne_init *
|
||||||
|
*===========================================================================*/
|
||||||
|
void ne_init(dep)
|
||||||
|
dpeth_t *dep;
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int word, sendq_nr;
|
||||||
|
|
||||||
|
/* Setup a transfer to get the ethernet address. */
|
||||||
|
if (dep->de_16bit)
|
||||||
|
outb_reg0(dep, DP_RBCR0, 6*2);
|
||||||
|
else
|
||||||
|
outb_reg0(dep, DP_RBCR0, 6);
|
||||||
|
outb_reg0(dep, DP_RBCR1, 0);
|
||||||
|
outb_reg0(dep, DP_RSAR0, 0);
|
||||||
|
outb_reg0(dep, DP_RSAR1, 0);
|
||||||
|
outb_reg0(dep, DP_CR, CR_DM_RR | CR_PS_P0 | CR_STA);
|
||||||
|
|
||||||
|
for (i= 0; i<6; i++)
|
||||||
|
{
|
||||||
|
if (dep->de_16bit)
|
||||||
|
{
|
||||||
|
word= inw_ne(dep, NE_DATA);
|
||||||
|
dep->de_address.ea_addr[i]= word;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dep->de_address.ea_addr[i] = inb_ne(dep, NE_DATA);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dep->de_data_port= dep->de_base_port + NE_DATA;
|
||||||
|
if (dep->de_16bit)
|
||||||
|
{
|
||||||
|
dep->de_ramsize= NE2000_SIZE;
|
||||||
|
dep->de_offset_page= NE2000_START / DP_PAGESIZE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dep->de_ramsize= NE1000_SIZE;
|
||||||
|
dep->de_offset_page= NE1000_START / DP_PAGESIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Allocate one send buffer (1.5KB) per 8KB of on board memory. */
|
||||||
|
sendq_nr= dep->de_ramsize / 0x2000;
|
||||||
|
if (sendq_nr < 1)
|
||||||
|
sendq_nr= 1;
|
||||||
|
else if (sendq_nr > SENDQ_NR)
|
||||||
|
sendq_nr= SENDQ_NR;
|
||||||
|
dep->de_sendq_nr= sendq_nr;
|
||||||
|
for (i= 0; i<sendq_nr; i++)
|
||||||
|
{
|
||||||
|
dep->de_sendq[i].sq_sendpage= dep->de_offset_page +
|
||||||
|
i*SENDQ_PAGES;
|
||||||
|
}
|
||||||
|
|
||||||
|
dep->de_startpage= dep->de_offset_page + i*SENDQ_PAGES;
|
||||||
|
dep->de_stoppage= dep->de_offset_page + dep->de_ramsize / DP_PAGESIZE;
|
||||||
|
|
||||||
|
/* Can't override the default IRQ. */
|
||||||
|
dep->de_irq &= ~DEI_DEFAULT;
|
||||||
|
|
||||||
|
if (!debug)
|
||||||
|
{
|
||||||
|
printf("%s: NE%d000 at %X:%d\n",
|
||||||
|
dep->de_name, dep->de_16bit ? 2 : 1,
|
||||||
|
dep->de_base_port, dep->de_irq);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("%s: Novell NE%d000 ethernet card at I/O address "
|
||||||
|
"0x%X, memory size 0x%X, irq %d\n",
|
||||||
|
dep->de_name, dep->de_16bit ? 2 : 1,
|
||||||
|
dep->de_base_port, dep->de_ramsize, dep->de_irq);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*===========================================================================*
|
||||||
|
* test_8 *
|
||||||
|
*===========================================================================*/
|
||||||
|
static int test_8(dep, pos, pat)
|
||||||
|
dpeth_t *dep;
|
||||||
|
int pos;
|
||||||
|
u8_t *pat;
|
||||||
|
{
|
||||||
|
u8_t buf[4];
|
||||||
|
int i;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
outb_reg0(dep, DP_ISR, 0xFF);
|
||||||
|
|
||||||
|
/* Setup a transfer to put the pattern. */
|
||||||
|
outb_reg0(dep, DP_RBCR0, 4);
|
||||||
|
outb_reg0(dep, DP_RBCR1, 0);
|
||||||
|
outb_reg0(dep, DP_RSAR0, pos & 0xFF);
|
||||||
|
outb_reg0(dep, DP_RSAR1, pos >> 8);
|
||||||
|
outb_reg0(dep, DP_CR, CR_DM_RW | CR_PS_P0 | CR_STA);
|
||||||
|
|
||||||
|
for (i= 0; i<4; i++)
|
||||||
|
outb_ne(dep, NE_DATA, pat[i]);
|
||||||
|
|
||||||
|
for (i= 0; i<N; i++)
|
||||||
|
{
|
||||||
|
if (inb_reg0(dep, DP_ISR) & ISR_RDC)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (i == N)
|
||||||
|
{
|
||||||
|
if (debug)
|
||||||
|
{
|
||||||
|
printf("%s: NE1000 remote DMA test failed\n",
|
||||||
|
dep->de_name);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
outb_reg0(dep, DP_RBCR0, 4);
|
||||||
|
outb_reg0(dep, DP_RBCR1, 0);
|
||||||
|
outb_reg0(dep, DP_RSAR0, pos & 0xFF);
|
||||||
|
outb_reg0(dep, DP_RSAR1, pos >> 8);
|
||||||
|
outb_reg0(dep, DP_CR, CR_DM_RR | CR_PS_P0 | CR_STA);
|
||||||
|
|
||||||
|
for (i= 0; i<4; i++)
|
||||||
|
buf[i]= inb_ne(dep, NE_DATA);
|
||||||
|
|
||||||
|
r= (memcmp(buf, pat, 4) == 0);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*===========================================================================*
|
||||||
|
* test_16 *
|
||||||
|
*===========================================================================*/
|
||||||
|
static int test_16(dep, pos, pat)
|
||||||
|
dpeth_t *dep;
|
||||||
|
int pos;
|
||||||
|
u8_t *pat;
|
||||||
|
{
|
||||||
|
u8_t buf[4];
|
||||||
|
int i;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
outb_reg0(dep, DP_ISR, 0xFF);
|
||||||
|
|
||||||
|
/* Setup a transfer to put the pattern. */
|
||||||
|
outb_reg0(dep, DP_RBCR0, 4);
|
||||||
|
outb_reg0(dep, DP_RBCR1, 0);
|
||||||
|
outb_reg0(dep, DP_RSAR0, pos & 0xFF);
|
||||||
|
outb_reg0(dep, DP_RSAR1, pos >> 8);
|
||||||
|
outb_reg0(dep, DP_CR, CR_DM_RW | CR_PS_P0 | CR_STA);
|
||||||
|
|
||||||
|
for (i= 0; i<4; i += 2)
|
||||||
|
{
|
||||||
|
outw_ne(dep, NE_DATA, *(u16_t *)(pat+i));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i= 0; i<N; i++)
|
||||||
|
{
|
||||||
|
if (inb_reg0(dep, DP_ISR) & ISR_RDC)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (i == N)
|
||||||
|
{
|
||||||
|
if (debug)
|
||||||
|
{
|
||||||
|
printf("%s: NE2000 remote DMA test failed\n",
|
||||||
|
dep->de_name);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
outb_reg0(dep, DP_RBCR0, 4);
|
||||||
|
outb_reg0(dep, DP_RBCR1, 0);
|
||||||
|
outb_reg0(dep, DP_RSAR0, pos & 0xFF);
|
||||||
|
outb_reg0(dep, DP_RSAR1, pos >> 8);
|
||||||
|
outb_reg0(dep, DP_CR, CR_DM_RR | CR_PS_P0 | CR_STA);
|
||||||
|
|
||||||
|
for (i= 0; i<4; i += 2)
|
||||||
|
{
|
||||||
|
*(u16_t *)(buf+i)= inw_ne(dep, NE_DATA);
|
||||||
|
}
|
||||||
|
|
||||||
|
r= (memcmp(buf, pat, 4) == 0);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*===========================================================================*
|
||||||
|
* ne_stop *
|
||||||
|
*===========================================================================*/
|
||||||
|
static void ne_stop(dep)
|
||||||
|
dpeth_t *dep;
|
||||||
|
{
|
||||||
|
int byte;
|
||||||
|
|
||||||
|
/* Reset the ethernet card */
|
||||||
|
byte= inb_ne(dep, NE_RESET);
|
||||||
|
milli_delay(2);
|
||||||
|
outb_ne(dep, NE_RESET, byte);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void milli_delay(unsigned long millis)
|
||||||
|
{
|
||||||
|
tickdelay(MILLIS_TO_TICKS(millis));
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* ENABLE_NE2000 */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* $PchId: ne2000.c,v 1.10 2004/08/03 12:03:00 philip Exp $
|
||||||
|
*/
|
28
drivers/dp8390/ne2000.h
Normal file
28
drivers/dp8390/ne2000.h
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
/*
|
||||||
|
ne2000.h
|
||||||
|
|
||||||
|
Created: March 15, 1994 by Philip Homburg <philip@f-mnx.phicoh.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef NE2000_H
|
||||||
|
#define NE2000_H
|
||||||
|
|
||||||
|
#define NE_DP8390 0x00
|
||||||
|
#define NE_DATA 0x10
|
||||||
|
#define NE_RESET 0x1F
|
||||||
|
|
||||||
|
#define NE1000_START 0x2000
|
||||||
|
#define NE1000_SIZE 0x2000
|
||||||
|
#define NE2000_START 0x4000
|
||||||
|
#define NE2000_SIZE 0x4000
|
||||||
|
|
||||||
|
#define inb_ne(dep, reg) (inb(dep->de_base_port+reg))
|
||||||
|
#define outb_ne(dep, reg, data) (outb(dep->de_base_port+reg, data))
|
||||||
|
#define inw_ne(dep, reg) (inw(dep->de_base_port+reg))
|
||||||
|
#define outw_ne(dep, reg, data) (outw(dep->de_base_port+reg, data))
|
||||||
|
|
||||||
|
#endif /* NE2000_H */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* $PchId: ne2000.h,v 1.4 2004/08/03 12:03:20 philip Exp $
|
||||||
|
*/
|
376
drivers/dp8390/rtl8029.c
Normal file
376
drivers/dp8390/rtl8029.c
Normal file
|
@ -0,0 +1,376 @@
|
||||||
|
/*
|
||||||
|
rtl8029.c
|
||||||
|
|
||||||
|
Initialization of PCI DP8390-based ethernet cards
|
||||||
|
|
||||||
|
Created: April 2000 by Philip Homburg <philip@f-mnx.phicoh.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "../drivers.h"
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <net/gen/ether.h>
|
||||||
|
#include <net/gen/eth_io.h>
|
||||||
|
|
||||||
|
#include "assert.h"
|
||||||
|
#include "../libpci/pci.h"
|
||||||
|
|
||||||
|
#include "local.h"
|
||||||
|
#include "dp8390.h"
|
||||||
|
#include "rtl8029.h"
|
||||||
|
|
||||||
|
#if ENABLE_PCI
|
||||||
|
|
||||||
|
#define MICROS_TO_TICKS(m) (((m)*HZ/1000000)+1)
|
||||||
|
|
||||||
|
PRIVATE struct pcitab
|
||||||
|
{
|
||||||
|
u16_t vid;
|
||||||
|
u16_t did;
|
||||||
|
int checkclass;
|
||||||
|
} pcitab[]=
|
||||||
|
{
|
||||||
|
{ 0x10ec, 0x8029, 0 }, /* Realtek RTL8029 */
|
||||||
|
|
||||||
|
{ 0x0000, 0x0000, 0 }
|
||||||
|
};
|
||||||
|
|
||||||
|
_PROTOTYPE( static void rtl_init, (struct dpeth *dep) );
|
||||||
|
_PROTOTYPE( static u16_t get_ee_word, (dpeth_t *dep, int a) );
|
||||||
|
_PROTOTYPE( static void ee_wen, (dpeth_t *dep) );
|
||||||
|
_PROTOTYPE( static void set_ee_word, (dpeth_t *dep, int a, U16_t w) );
|
||||||
|
_PROTOTYPE( static void ee_wds, (dpeth_t *dep) );
|
||||||
|
_PROTOTYPE( static void micro_delay, (unsigned long usecs) );
|
||||||
|
|
||||||
|
PUBLIC int rtl_probe(dep)
|
||||||
|
struct dpeth *dep;
|
||||||
|
{
|
||||||
|
int i, r, devind, just_one;
|
||||||
|
u16_t vid, did;
|
||||||
|
u32_t bar;
|
||||||
|
u8_t ilr;
|
||||||
|
char *dname;
|
||||||
|
|
||||||
|
pci_init();
|
||||||
|
|
||||||
|
if ((dep->de_pcibus | dep->de_pcidev | dep->de_pcifunc) != 0)
|
||||||
|
{
|
||||||
|
/* Look for specific PCI device */
|
||||||
|
r= pci_find_dev(dep->de_pcibus, dep->de_pcidev,
|
||||||
|
dep->de_pcifunc, &devind);
|
||||||
|
if (r == 0)
|
||||||
|
{
|
||||||
|
printf("%s: no PCI found at %d.%d.%d\n",
|
||||||
|
dep->de_name, dep->de_pcibus,
|
||||||
|
dep->de_pcidev, dep->de_pcifunc);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
pci_ids(devind, &vid, &did);
|
||||||
|
just_one= TRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
r= pci_first_dev(&devind, &vid, &did);
|
||||||
|
if (r == 0)
|
||||||
|
return 0;
|
||||||
|
just_one= FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(;;)
|
||||||
|
{
|
||||||
|
for (i= 0; pcitab[i].vid != 0; i++)
|
||||||
|
{
|
||||||
|
if (pcitab[i].vid != vid)
|
||||||
|
continue;
|
||||||
|
if (pcitab[i].did != did)
|
||||||
|
continue;
|
||||||
|
if (pcitab[i].checkclass)
|
||||||
|
{
|
||||||
|
panic("",
|
||||||
|
"rtl_probe: class check not implemented",
|
||||||
|
NO_NUM);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (pcitab[i].vid != 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (just_one)
|
||||||
|
{
|
||||||
|
printf(
|
||||||
|
"%s: wrong PCI device (%04X/%04X) found at %d.%d.%d\n",
|
||||||
|
dep->de_name, vid, did,
|
||||||
|
dep->de_pcibus,
|
||||||
|
dep->de_pcidev, dep->de_pcifunc);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
r= pci_next_dev(&devind, &vid, &did);
|
||||||
|
if (!r)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
dname= pci_dev_name(vid, did);
|
||||||
|
if (!dname)
|
||||||
|
dname= "unknown device";
|
||||||
|
printf("%s: %s (%04X/%04X) at %s\n",
|
||||||
|
dep->de_name, dname, vid, did, pci_slot_name(devind));
|
||||||
|
pci_reserve(devind);
|
||||||
|
/* printf("cr = 0x%x\n", pci_attr_r16(devind, PCI_CR)); */
|
||||||
|
bar= pci_attr_r32(devind, PCI_BAR) & 0xffffffe0;
|
||||||
|
if ((bar & 0x3ff) >= 0x100-32 || bar < 0x400)
|
||||||
|
panic("", "base address is not properly configured", NO_NUM);
|
||||||
|
dep->de_base_port= bar;
|
||||||
|
|
||||||
|
ilr= pci_attr_r8(devind, PCI_ILR);
|
||||||
|
dep->de_irq= ilr;
|
||||||
|
if (debug)
|
||||||
|
{
|
||||||
|
printf("%s: using I/O address 0x%lx, IRQ %d\n",
|
||||||
|
dep->de_name, (unsigned long)bar, ilr);
|
||||||
|
}
|
||||||
|
dep->de_initf= rtl_init;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rtl_init(dep)
|
||||||
|
dpeth_t *dep;
|
||||||
|
{
|
||||||
|
u8_t reg_a, reg_b, cr, config0, config2, config3;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
printf("rtl_init called\n");
|
||||||
|
#endif
|
||||||
|
ne_init(dep);
|
||||||
|
|
||||||
|
/* ID */
|
||||||
|
outb_reg0(dep, DP_CR, CR_PS_P0);
|
||||||
|
reg_a = inb_reg0(dep, DP_DUM1);
|
||||||
|
reg_b = inb_reg0(dep, DP_DUM2);
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
printf("rtl_init: '%c', '%c'\n", reg_a, reg_b);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
outb_reg0(dep, DP_CR, CR_PS_P3);
|
||||||
|
config0 = inb_reg3(dep, 3);
|
||||||
|
config2 = inb_reg3(dep, 5);
|
||||||
|
config3 = inb_reg3(dep, 6);
|
||||||
|
outb_reg0(dep, DP_CR, CR_PS_P0);
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
printf("rtl_init: config 0/2/3 = %x/%x/%x\n",
|
||||||
|
config0, config2, config3);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (getenv("RTL8029FD"))
|
||||||
|
{
|
||||||
|
printf("rtl_init: setting full-duplex mode\n");
|
||||||
|
outb_reg0(dep, DP_CR, CR_PS_P3);
|
||||||
|
|
||||||
|
cr= inb_reg3(dep, 1);
|
||||||
|
outb_reg3(dep, 1, cr | 0xc0);
|
||||||
|
|
||||||
|
outb_reg3(dep, 6, config3 | 0x40);
|
||||||
|
config3 = inb_reg3(dep, 6);
|
||||||
|
|
||||||
|
config2= inb_reg3(dep, 5);
|
||||||
|
outb_reg3(dep, 5, config2 | 0x20);
|
||||||
|
config2= inb_reg3(dep, 5);
|
||||||
|
|
||||||
|
outb_reg3(dep, 1, cr);
|
||||||
|
|
||||||
|
outb_reg0(dep, DP_CR, CR_PS_P0);
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
printf("rtl_init: config 2 = %x\n", config2);
|
||||||
|
printf("rtl_init: config 3 = %x\n", config3);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
for (i= 0; i<64; i++)
|
||||||
|
printf("%x ", get_ee_word(dep, i));
|
||||||
|
printf("\n");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (getenv("RTL8029MN"))
|
||||||
|
{
|
||||||
|
ee_wen(dep);
|
||||||
|
|
||||||
|
set_ee_word(dep, 0x78/2, 0x10ec);
|
||||||
|
set_ee_word(dep, 0x7A/2, 0x8029);
|
||||||
|
set_ee_word(dep, 0x7C/2, 0x10ec);
|
||||||
|
set_ee_word(dep, 0x7E/2, 0x8029);
|
||||||
|
|
||||||
|
ee_wds(dep);
|
||||||
|
|
||||||
|
assert(get_ee_word(dep, 0x78/2) == 0x10ec);
|
||||||
|
assert(get_ee_word(dep, 0x7A/2) == 0x8029);
|
||||||
|
assert(get_ee_word(dep, 0x7C/2) == 0x10ec);
|
||||||
|
assert(get_ee_word(dep, 0x7E/2) == 0x8029);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (getenv("RTL8029XXX"))
|
||||||
|
{
|
||||||
|
ee_wen(dep);
|
||||||
|
|
||||||
|
set_ee_word(dep, 0x76/2, 0x8029);
|
||||||
|
|
||||||
|
ee_wds(dep);
|
||||||
|
|
||||||
|
assert(get_ee_word(dep, 0x76/2) == 0x8029);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static u16_t get_ee_word(dep, a)
|
||||||
|
dpeth_t *dep;
|
||||||
|
int a;
|
||||||
|
{
|
||||||
|
int b, i, cmd;
|
||||||
|
u16_t w;
|
||||||
|
|
||||||
|
outb_reg0(dep, DP_CR, CR_PS_P3); /* Bank 3 */
|
||||||
|
|
||||||
|
/* Switch to 9346 mode and enable CS */
|
||||||
|
outb_reg3(dep, 1, 0x80 | 0x8);
|
||||||
|
|
||||||
|
cmd= 0x180 | (a & 0x3f); /* 1 1 0 a5 a4 a3 a2 a1 a0 */
|
||||||
|
for (i= 8; i >= 0; i--)
|
||||||
|
{
|
||||||
|
b= (cmd & (1 << i));
|
||||||
|
b= (b ? 2 : 0);
|
||||||
|
|
||||||
|
/* Cmd goes out on the rising edge of the clock */
|
||||||
|
outb_reg3(dep, 1, 0x80 | 0x8 | b);
|
||||||
|
outb_reg3(dep, 1, 0x80 | 0x8 | 0x4 | b);
|
||||||
|
}
|
||||||
|
outb_reg3(dep, 1, 0x80 | 0x8); /* End of cmd */
|
||||||
|
|
||||||
|
w= 0;
|
||||||
|
for (i= 0; i<16; i++)
|
||||||
|
{
|
||||||
|
w <<= 1;
|
||||||
|
|
||||||
|
/* Data is shifted out on the rising edge. Read at the
|
||||||
|
* falling edge.
|
||||||
|
*/
|
||||||
|
outb_reg3(dep, 1, 0x80 | 0x8 | 0x4);
|
||||||
|
outb_reg3(dep, 1, 0x80 | 0x8 | b);
|
||||||
|
b= inb_reg3(dep, 1);
|
||||||
|
w |= (b & 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
outb_reg3(dep, 1, 0x80); /* drop CS */
|
||||||
|
outb_reg3(dep, 1, 0x00); /* back to normal */
|
||||||
|
outb_reg0(dep, DP_CR, CR_PS_P0); /* back to bank 0 */
|
||||||
|
|
||||||
|
return w;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ee_wen(dep)
|
||||||
|
dpeth_t *dep;
|
||||||
|
{
|
||||||
|
int b, i, cmd;
|
||||||
|
|
||||||
|
outb_reg0(dep, DP_CR, CR_PS_P3); /* Bank 3 */
|
||||||
|
|
||||||
|
/* Switch to 9346 mode and enable CS */
|
||||||
|
outb_reg3(dep, 1, 0x80 | 0x8);
|
||||||
|
|
||||||
|
cmd= 0x130; /* 1 0 0 1 1 x x x x */
|
||||||
|
for (i= 8; i >= 0; i--)
|
||||||
|
{
|
||||||
|
b= (cmd & (1 << i));
|
||||||
|
b= (b ? 2 : 0);
|
||||||
|
|
||||||
|
/* Cmd goes out on the rising edge of the clock */
|
||||||
|
outb_reg3(dep, 1, 0x80 | 0x8 | b);
|
||||||
|
outb_reg3(dep, 1, 0x80 | 0x8 | 0x4 | b);
|
||||||
|
}
|
||||||
|
outb_reg3(dep, 1, 0x80 | 0x8); /* End of cmd */
|
||||||
|
outb_reg3(dep, 1, 0x80); /* Drop CS */
|
||||||
|
micro_delay(1); /* Is this required? */
|
||||||
|
}
|
||||||
|
|
||||||
|
static void set_ee_word(dep, a, w)
|
||||||
|
dpeth_t *dep;
|
||||||
|
int a;
|
||||||
|
u16_t w;
|
||||||
|
{
|
||||||
|
int b, i, cmd;
|
||||||
|
|
||||||
|
outb_reg3(dep, 1, 0x80 | 0x8); /* Set CS */
|
||||||
|
|
||||||
|
cmd= 0x140 | (a & 0x3f); /* 1 0 1 a5 a4 a3 a2 a1 a0 */
|
||||||
|
for (i= 8; i >= 0; i--)
|
||||||
|
{
|
||||||
|
b= (cmd & (1 << i));
|
||||||
|
b= (b ? 2 : 0);
|
||||||
|
|
||||||
|
/* Cmd goes out on the rising edge of the clock */
|
||||||
|
outb_reg3(dep, 1, 0x80 | 0x8 | b);
|
||||||
|
outb_reg3(dep, 1, 0x80 | 0x8 | 0x4 | b);
|
||||||
|
}
|
||||||
|
for (i= 15; i >= 0; i--)
|
||||||
|
{
|
||||||
|
b= (w & (1 << i));
|
||||||
|
b= (b ? 2 : 0);
|
||||||
|
|
||||||
|
/* Cmd goes out on the rising edge of the clock */
|
||||||
|
outb_reg3(dep, 1, 0x80 | 0x8 | b);
|
||||||
|
outb_reg3(dep, 1, 0x80 | 0x8 | 0x4 | b);
|
||||||
|
}
|
||||||
|
outb_reg3(dep, 1, 0x80 | 0x8); /* End of data */
|
||||||
|
outb_reg3(dep, 1, 0x80); /* Drop CS */
|
||||||
|
micro_delay(1); /* Is this required? */
|
||||||
|
outb_reg3(dep, 1, 0x80 | 0x8); /* Set CS */
|
||||||
|
for (i= 0; i<10000; i++)
|
||||||
|
{
|
||||||
|
if (inb_reg3(dep, 1) & 1)
|
||||||
|
break;
|
||||||
|
micro_delay(1);
|
||||||
|
}
|
||||||
|
if (!(inb_reg3(dep, 1) & 1))
|
||||||
|
panic("", "set_ee_word: device remains busy", NO_NUM);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ee_wds(dep)
|
||||||
|
dpeth_t *dep;
|
||||||
|
{
|
||||||
|
int b, i, cmd;
|
||||||
|
|
||||||
|
outb_reg0(dep, DP_CR, CR_PS_P3); /* Bank 3 */
|
||||||
|
|
||||||
|
/* Switch to 9346 mode and enable CS */
|
||||||
|
outb_reg3(dep, 1, 0x80 | 0x8);
|
||||||
|
|
||||||
|
cmd= 0x100; /* 1 0 0 0 0 x x x x */
|
||||||
|
for (i= 8; i >= 0; i--)
|
||||||
|
{
|
||||||
|
b= (cmd & (1 << i));
|
||||||
|
b= (b ? 2 : 0);
|
||||||
|
|
||||||
|
/* Cmd goes out on the rising edge of the clock */
|
||||||
|
outb_reg3(dep, 1, 0x80 | 0x8 | b);
|
||||||
|
outb_reg3(dep, 1, 0x80 | 0x8 | 0x4 | b);
|
||||||
|
}
|
||||||
|
outb_reg3(dep, 1, 0x80 | 0x8); /* End of cmd */
|
||||||
|
outb_reg3(dep, 1, 0x80); /* Drop CS */
|
||||||
|
outb_reg3(dep, 1, 0x00); /* back to normal */
|
||||||
|
outb_reg0(dep, DP_CR, CR_PS_P0); /* back to bank 0 */
|
||||||
|
}
|
||||||
|
|
||||||
|
static void micro_delay(unsigned long usecs)
|
||||||
|
{
|
||||||
|
tickdelay(MICROS_TO_TICKS(usecs));
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* ENABLE_PCI */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* $PchId: rtl8029.c,v 1.7 2004/08/03 12:16:58 philip Exp $
|
||||||
|
*/
|
15
drivers/dp8390/rtl8029.h
Normal file
15
drivers/dp8390/rtl8029.h
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
/*
|
||||||
|
rtl8029.h
|
||||||
|
|
||||||
|
Created: Sep 2003 by Philip Homburg <philip@f-mnx.phicoh.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Bits in dp_cr */
|
||||||
|
#define CR_PS_P3 0xC0 /* Register Page 3 */
|
||||||
|
|
||||||
|
#define inb_reg3(dep, reg) (inb (dep->de_dp8390_port+reg))
|
||||||
|
#define outb_reg3(dep, reg, data) (outb(dep->de_dp8390_port+reg, data))
|
||||||
|
|
||||||
|
/*
|
||||||
|
* $PchId: rtl8029.h,v 1.3 2004/08/03 15:11:06 philip Exp $
|
||||||
|
*/
|
369
drivers/dp8390/wdeth.c
Normal file
369
drivers/dp8390/wdeth.c
Normal file
|
@ -0,0 +1,369 @@
|
||||||
|
/*
|
||||||
|
wdeth.c
|
||||||
|
|
||||||
|
Created: March 14, 1994 by Philip Homburg
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "../drivers.h"
|
||||||
|
|
||||||
|
#include <net/gen/ether.h>
|
||||||
|
#include <net/gen/eth_io.h>
|
||||||
|
#include "assert.h"
|
||||||
|
|
||||||
|
#include "local.h"
|
||||||
|
#include "dp8390.h"
|
||||||
|
#include "wdeth.h"
|
||||||
|
|
||||||
|
#if ENABLE_WDETH
|
||||||
|
|
||||||
|
#define WET_ETHERNET 0x01 /* Ethernet transceiver */
|
||||||
|
#define WET_STARLAN 0x02 /* Starlan transceiver */
|
||||||
|
#define WET_INTERF_CHIP 0x04 /* has a WD83C583 interface chip */
|
||||||
|
#define WET_BRD_16BIT 0x08 /* 16 bit board */
|
||||||
|
#define WET_SLT_16BIT 0x10 /* 16 bit slot */
|
||||||
|
#define WET_790 0x20 /* '790 chip */
|
||||||
|
|
||||||
|
static int we_int_table[8]= { 9, 3, 5, 7, 10, 11, 15, 4 };
|
||||||
|
static int we_790int_table[8]= { 0, 9, 3, 5, 7, 10, 11, 15 };
|
||||||
|
|
||||||
|
_PROTOTYPE( static void we_init, (dpeth_t *dep) );
|
||||||
|
_PROTOTYPE( static void we_stop, (dpeth_t *dep) );
|
||||||
|
_PROTOTYPE( static int we_aliasing, (dpeth_t *dep) );
|
||||||
|
_PROTOTYPE( static int we_interface_chip, (dpeth_t *dep) );
|
||||||
|
_PROTOTYPE( static int we_16bitboard, (dpeth_t *dep) );
|
||||||
|
_PROTOTYPE( static int we_16bitslot, (dpeth_t *dep) );
|
||||||
|
_PROTOTYPE( static int we_ultra, (dpeth_t *dep) );
|
||||||
|
|
||||||
|
/*===========================================================================*
|
||||||
|
* wdeth_probe *
|
||||||
|
*===========================================================================*/
|
||||||
|
int wdeth_probe(dep)
|
||||||
|
dpeth_t *dep;
|
||||||
|
{
|
||||||
|
int sum;
|
||||||
|
|
||||||
|
if (dep->de_linmem == 0)
|
||||||
|
return 0; /* No shared memory, so no WD board */
|
||||||
|
|
||||||
|
sum = inb_we(dep, EPL_EA0) + inb_we(dep, EPL_EA1) +
|
||||||
|
inb_we(dep, EPL_EA2) + inb_we(dep, EPL_EA3) +
|
||||||
|
inb_we(dep, EPL_EA4) + inb_we(dep, EPL_EA5) +
|
||||||
|
inb_we(dep, EPL_TLB) + inb_we(dep, EPL_CHKSUM);
|
||||||
|
if ((sum & 0xFF) != 0xFF)
|
||||||
|
return 0; /* No ethernet board at this address */
|
||||||
|
|
||||||
|
dep->de_initf= we_init;
|
||||||
|
dep->de_stopf= we_stop;
|
||||||
|
dep->de_prog_IO= 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*===========================================================================*
|
||||||
|
* we_init *
|
||||||
|
*===========================================================================*/
|
||||||
|
static void we_init(dep)
|
||||||
|
dpeth_t *dep;
|
||||||
|
{
|
||||||
|
int i, int_indx, int_nr;
|
||||||
|
int tlb, rambit, revision;
|
||||||
|
int icr, irr, hwr, b, gcr;
|
||||||
|
int we_type;
|
||||||
|
int sendq_nr;
|
||||||
|
|
||||||
|
assert(dep->de_mode == DEM_ENABLED);
|
||||||
|
assert(!(dep->de_flags & DEF_ENABLED));
|
||||||
|
|
||||||
|
dep->de_address.ea_addr[0] = inb_we(dep, EPL_EA0);
|
||||||
|
dep->de_address.ea_addr[1] = inb_we(dep, EPL_EA1);
|
||||||
|
dep->de_address.ea_addr[2] = inb_we(dep, EPL_EA2);
|
||||||
|
dep->de_address.ea_addr[3] = inb_we(dep, EPL_EA3);
|
||||||
|
dep->de_address.ea_addr[4] = inb_we(dep, EPL_EA4);
|
||||||
|
dep->de_address.ea_addr[5] = inb_we(dep, EPL_EA5);
|
||||||
|
|
||||||
|
dep->de_dp8390_port= dep->de_base_port + EPL_DP8390;
|
||||||
|
|
||||||
|
dep->de_16bit= 0;
|
||||||
|
|
||||||
|
we_type= 0;
|
||||||
|
we_type |= WET_ETHERNET; /* assume ethernet */
|
||||||
|
if (we_ultra(dep))
|
||||||
|
we_type |= WET_790;
|
||||||
|
if (!we_aliasing(dep))
|
||||||
|
{
|
||||||
|
if (we_interface_chip(dep))
|
||||||
|
we_type |= WET_INTERF_CHIP;
|
||||||
|
if (we_16bitboard(dep))
|
||||||
|
{
|
||||||
|
we_type |= WET_BRD_16BIT;
|
||||||
|
if (we_16bitslot(dep))
|
||||||
|
we_type |= WET_SLT_16BIT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (we_type & WET_SLT_16BIT)
|
||||||
|
dep->de_16bit= 1;
|
||||||
|
|
||||||
|
/* look at the on board ram size. */
|
||||||
|
tlb= inb_we(dep, EPL_TLB);
|
||||||
|
revision= tlb & E_TLB_REV;
|
||||||
|
rambit= tlb & E_TLB_RAM;
|
||||||
|
|
||||||
|
if (dep->de_ramsize != 0)
|
||||||
|
{
|
||||||
|
/* size set from boot environment. */
|
||||||
|
}
|
||||||
|
else if (revision < 2)
|
||||||
|
{
|
||||||
|
dep->de_ramsize= 0x2000; /* 8K */
|
||||||
|
if (we_type & WET_BRD_16BIT)
|
||||||
|
dep->de_ramsize= 0x4000; /* 16K */
|
||||||
|
else if ((we_type & WET_INTERF_CHIP) &&
|
||||||
|
inb_we(dep, EPL_ICR) & E_ICR_MEMBIT)
|
||||||
|
{
|
||||||
|
dep->de_ramsize= 0x8000; /* 32K */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (we_type & WET_BRD_16BIT)
|
||||||
|
{
|
||||||
|
/* 32K or 16K */
|
||||||
|
dep->de_ramsize= rambit ? 0x8000 : 0x4000;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* 32K or 8K */
|
||||||
|
dep->de_ramsize= rambit ? 0x8000 : 0x2000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (we_type & WET_790)
|
||||||
|
{
|
||||||
|
outb_we(dep, EPL_MSR, E_MSR_RESET);
|
||||||
|
if ((we_type & (WET_BRD_16BIT|WET_SLT_16BIT)) ==
|
||||||
|
(WET_BRD_16BIT|WET_SLT_16BIT))
|
||||||
|
{
|
||||||
|
outb_we(dep, EPL_LAAR, E_LAAR_LAN16E | E_LAAR_MEM16E);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (we_type & WET_BRD_16BIT)
|
||||||
|
{
|
||||||
|
if (we_type & WET_SLT_16BIT)
|
||||||
|
{
|
||||||
|
outb_we(dep, EPL_LAAR, E_LAAR_A19 | E_LAAR_SOFTINT |
|
||||||
|
E_LAAR_LAN16E | E_LAAR_MEM16E);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
outb_we(dep, EPL_LAAR, E_LAAR_A19 | E_LAAR_SOFTINT |
|
||||||
|
E_LAAR_LAN16E);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (we_type & WET_790)
|
||||||
|
{
|
||||||
|
outb_we(dep, EPL_MSR, E_MSR_MENABLE);
|
||||||
|
hwr= inb_we(dep, EPL_790_HWR);
|
||||||
|
outb_we(dep, EPL_790_HWR, hwr | E_790_HWR_SWH);
|
||||||
|
b= inb_we(dep, EPL_790_B);
|
||||||
|
outb_we(dep, EPL_790_B, ((dep->de_linmem >> 13) & 0x0f) |
|
||||||
|
((dep->de_linmem >> 11) & 0x40) | (b & 0xb0));
|
||||||
|
outb_we(dep, EPL_790_HWR, hwr & ~E_790_HWR_SWH);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
outb_we(dep, EPL_MSR, E_MSR_RESET);
|
||||||
|
outb_we(dep, EPL_MSR, E_MSR_MENABLE |
|
||||||
|
((dep->de_linmem >> 13) & E_MSR_MEMADDR));
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((we_type & WET_INTERF_CHIP) && !(we_type & WET_790))
|
||||||
|
{
|
||||||
|
icr= inb_we(dep, EPL_ICR);
|
||||||
|
irr= inb_we(dep, EPL_IRR);
|
||||||
|
int_indx= (icr & E_ICR_IR2) |
|
||||||
|
((irr & (E_IRR_IR0|E_IRR_IR1)) >> 5);
|
||||||
|
int_nr= we_int_table[int_indx];
|
||||||
|
#if DEBUG
|
||||||
|
{ printf("%s: encoded irq= %d\n", dep->de_name, int_nr); }
|
||||||
|
#endif
|
||||||
|
if (dep->de_irq & DEI_DEFAULT) dep->de_irq= int_nr;
|
||||||
|
|
||||||
|
outb_we(dep, EPL_IRR, irr | E_IRR_IEN);
|
||||||
|
}
|
||||||
|
if (we_type & WET_790)
|
||||||
|
{
|
||||||
|
hwr= inb_we(dep, EPL_790_HWR);
|
||||||
|
outb_we(dep, EPL_790_HWR, hwr | E_790_HWR_SWH);
|
||||||
|
|
||||||
|
gcr= inb_we(dep, EPL_790_GCR);
|
||||||
|
|
||||||
|
outb_we(dep, EPL_790_HWR, hwr & ~E_790_HWR_SWH);
|
||||||
|
|
||||||
|
int_indx= ((gcr & E_790_GCR_IR2) >> 4) |
|
||||||
|
((gcr & (E_790_GCR_IR1|E_790_GCR_IR0)) >> 2);
|
||||||
|
int_nr= we_790int_table[int_indx];
|
||||||
|
#if DEBUG
|
||||||
|
{ printf("%s: encoded irq= %d\n", dep->de_name, int_nr); }
|
||||||
|
#endif
|
||||||
|
if (dep->de_irq & DEI_DEFAULT) dep->de_irq= int_nr;
|
||||||
|
|
||||||
|
icr= inb_we(dep, EPL_790_ICR);
|
||||||
|
outb_we(dep, EPL_790_ICR, icr | E_790_ICR_EIL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Strip the "default flag." */
|
||||||
|
dep->de_irq &= ~DEI_DEFAULT;
|
||||||
|
|
||||||
|
if (!debug)
|
||||||
|
{
|
||||||
|
printf("%s: WD80%d3 at %X:%d:%lX\n",
|
||||||
|
dep->de_name, we_type & WET_BRD_16BIT ? 1 : 0,
|
||||||
|
dep->de_base_port, dep->de_irq, dep->de_linmem);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("%s: Western Digital %s%s card %s%s at I/O "
|
||||||
|
"address 0x%X, memory address 0x%lX, "
|
||||||
|
"memory size 0x%X, irq %d\n",
|
||||||
|
dep->de_name,
|
||||||
|
we_type & WET_BRD_16BIT ? "16-bit " : "",
|
||||||
|
we_type & WET_ETHERNET ? "Ethernet" :
|
||||||
|
we_type & WET_STARLAN ? "Starlan" : "Network",
|
||||||
|
we_type & WET_INTERF_CHIP ? "with an interface chip " : "",
|
||||||
|
we_type & WET_SLT_16BIT ? "in a 16-bit slot " : "",
|
||||||
|
dep->de_base_port, dep->de_linmem, dep->de_ramsize,
|
||||||
|
dep->de_irq);
|
||||||
|
}
|
||||||
|
|
||||||
|
dep->de_offset_page= 0; /* Shared memory starts at 0 */
|
||||||
|
|
||||||
|
/* Allocate one send buffer (1.5KB) per 8KB of on board memory. */
|
||||||
|
sendq_nr= dep->de_ramsize / 0x2000;
|
||||||
|
if (sendq_nr < 1)
|
||||||
|
sendq_nr= 1;
|
||||||
|
else if (sendq_nr > SENDQ_NR)
|
||||||
|
sendq_nr= SENDQ_NR;
|
||||||
|
dep->de_sendq_nr= sendq_nr;
|
||||||
|
for (i= 0; i<sendq_nr; i++)
|
||||||
|
dep->de_sendq[i].sq_sendpage= i*SENDQ_PAGES;
|
||||||
|
|
||||||
|
dep->de_startpage= i*SENDQ_PAGES;
|
||||||
|
dep->de_stoppage= dep->de_ramsize / DP_PAGESIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*===========================================================================*
|
||||||
|
* we_stop *
|
||||||
|
*===========================================================================*/
|
||||||
|
static void we_stop(dep)
|
||||||
|
dpeth_t *dep;
|
||||||
|
{
|
||||||
|
if (dep->de_16bit)
|
||||||
|
outb_we(dep, EPL_LAAR, E_LAAR_A19 | E_LAAR_LAN16E);
|
||||||
|
outb_we(dep, EPL_MSR, E_MSR_RESET);
|
||||||
|
outb_we(dep, EPL_MSR, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*===========================================================================*
|
||||||
|
* we_aliasing *
|
||||||
|
*===========================================================================*/
|
||||||
|
static int we_aliasing(dep)
|
||||||
|
dpeth_t *dep;
|
||||||
|
{
|
||||||
|
/* Determine whether wd8003 hardware performs register aliasing. This implies
|
||||||
|
* an old WD8003E board. */
|
||||||
|
|
||||||
|
if (inb_we(dep, EPL_REG1) != inb_we(dep, EPL_EA1))
|
||||||
|
return 0;
|
||||||
|
if (inb_we(dep, EPL_REG2) != inb_we(dep, EPL_EA2))
|
||||||
|
return 0;
|
||||||
|
if (inb_we(dep, EPL_REG3) != inb_we(dep, EPL_EA3))
|
||||||
|
return 0;
|
||||||
|
if (inb_we(dep, EPL_REG4) != inb_we(dep, EPL_EA4))
|
||||||
|
return 0;
|
||||||
|
if (inb_we(dep, EPL_REG7) != inb_we(dep, EPL_CHKSUM))
|
||||||
|
return 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*===========================================================================*
|
||||||
|
* we_interface_chip *
|
||||||
|
*===========================================================================*/
|
||||||
|
static int we_interface_chip(dep)
|
||||||
|
dpeth_t *dep;
|
||||||
|
{
|
||||||
|
/* Determine if the board has an interface chip. */
|
||||||
|
|
||||||
|
outb_we(dep, EPL_GP2, 0x35);
|
||||||
|
if (inb_we(dep, EPL_GP2) != 0x35)
|
||||||
|
return 0;
|
||||||
|
outb_we(dep, EPL_GP2, 0x3A);
|
||||||
|
if (inb_we(dep, EPL_GP2) != 0x3A)
|
||||||
|
return 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*===========================================================================*
|
||||||
|
* we_16bitboard *
|
||||||
|
*===========================================================================*/
|
||||||
|
static int we_16bitboard(dep)
|
||||||
|
dpeth_t *dep;
|
||||||
|
{
|
||||||
|
/* Determine whether the board is capable of doing 16 bit memory moves.
|
||||||
|
* If the 16 bit enable bit is unchangable by software we'll assume an
|
||||||
|
* 8 bit board.
|
||||||
|
*/
|
||||||
|
int icr;
|
||||||
|
u8_t tlb;
|
||||||
|
|
||||||
|
icr= inb_we(dep, EPL_ICR);
|
||||||
|
|
||||||
|
outb_we(dep, EPL_ICR, icr ^ E_ICR_16BIT);
|
||||||
|
if (inb_we(dep, EPL_ICR) == icr)
|
||||||
|
{
|
||||||
|
tlb= inb_we(dep, EPL_TLB);
|
||||||
|
#if DEBUG
|
||||||
|
printf("%s: tlb= 0x%x\n", dep->de_name, tlb);
|
||||||
|
#endif
|
||||||
|
return tlb == E_TLB_EB || tlb == E_TLB_E ||
|
||||||
|
tlb == E_TLB_SMCE || tlb == E_TLB_SMC8216T ||
|
||||||
|
tlb == E_TLB_SMC8216C;
|
||||||
|
}
|
||||||
|
outb_we(dep, EPL_ICR, icr);
|
||||||
|
return (icr & E_ICR_16BIT);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*===========================================================================*
|
||||||
|
* we_16bitslot *
|
||||||
|
*===========================================================================*/
|
||||||
|
static int we_16bitslot(dep)
|
||||||
|
dpeth_t *dep;
|
||||||
|
{
|
||||||
|
/* Determine if the 16 bit board in plugged into a 16 bit slot. */
|
||||||
|
return !!(inb_we(dep, EPL_ICR) & E_ICR_16BIT);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*===========================================================================*
|
||||||
|
* we_ultra *
|
||||||
|
*===========================================================================*/
|
||||||
|
static int we_ultra(dep)
|
||||||
|
dpeth_t *dep;
|
||||||
|
{
|
||||||
|
/* Determine if we has an '790 chip. */
|
||||||
|
u8_t tlb;
|
||||||
|
|
||||||
|
tlb= inb_we(dep, EPL_TLB);
|
||||||
|
return tlb == E_TLB_SMC8216T || tlb == E_TLB_SMC8216C;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* ENABLE_WDETH */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* $PchId: wdeth.c,v 1.10 2003/09/10 19:31:50 philip Exp $
|
||||||
|
*/
|
95
drivers/dp8390/wdeth.h
Normal file
95
drivers/dp8390/wdeth.h
Normal file
|
@ -0,0 +1,95 @@
|
||||||
|
/*
|
||||||
|
wdeth.h
|
||||||
|
|
||||||
|
Created: before Dec 28, 1992 by Philip Homburg
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef WDETH_H
|
||||||
|
#define WDETH_H
|
||||||
|
|
||||||
|
/* Western Digital Ethercard Plus, or WD8003E card. */
|
||||||
|
|
||||||
|
#define EPL_REG0 0x0 /* Control(write) and status(read) */
|
||||||
|
#define EPL_REG1 0x1
|
||||||
|
#define EPL_REG2 0x2
|
||||||
|
#define EPL_REG3 0x3
|
||||||
|
#define EPL_REG4 0x4
|
||||||
|
#define EPL_REG5 0x5
|
||||||
|
#define EPL_REG6 0x6
|
||||||
|
#define EPL_REG7 0x7
|
||||||
|
#define EPL_EA0 0x8 /* Most significant eaddr byte */
|
||||||
|
#define EPL_EA1 0x9
|
||||||
|
#define EPL_EA2 0xA
|
||||||
|
#define EPL_EA3 0xB
|
||||||
|
#define EPL_EA4 0xC
|
||||||
|
#define EPL_EA5 0xD /* Least significant eaddr byte */
|
||||||
|
#define EPL_TLB 0xE
|
||||||
|
#define EPL_CHKSUM 0xF /* sum from epl_ea0 upto here is 0xFF */
|
||||||
|
#define EPL_DP8390 0x10 /* NatSemi chip */
|
||||||
|
|
||||||
|
#define EPL_MSR EPL_REG0 /* memory select register */
|
||||||
|
#define EPL_ICR EPL_REG1 /* interface configuration register */
|
||||||
|
#define EPL_IRR EPL_REG4 /* interrupt request register (IRR) */
|
||||||
|
#define EPL_790_HWR EPL_REG4 /* '790 hardware support register */
|
||||||
|
#define EPL_LAAR EPL_REG5 /* LA address register (write only) */
|
||||||
|
#define EPL_790_ICR EPL_REG6 /* '790 interrupt control register */
|
||||||
|
#define EPL_GP2 EPL_REG7 /* general purpose register 2 */
|
||||||
|
#define EPL_790_B EPL_EA3 /* '790 memory register */
|
||||||
|
#define EPL_790_GCR EPL_EA5 /* '790 General Control Register */
|
||||||
|
|
||||||
|
/* Bits in EPL_MSR */
|
||||||
|
#define E_MSR_MEMADDR 0x3F /* Bits SA18-SA13, SA19 implicit 1 */
|
||||||
|
#define E_MSR_MENABLE 0x40 /* Memory Enable */
|
||||||
|
#define E_MSR_RESET 0x80 /* Software Reset */
|
||||||
|
|
||||||
|
/* Bits in EPL_ICR */
|
||||||
|
#define E_ICR_16BIT 0x01 /* 16 bit bus */
|
||||||
|
#define E_ICR_IR2 0x04 /* bit 2 of encoded IRQ */
|
||||||
|
#define E_ICR_MEMBIT 0x08 /* 583 mem size mask */
|
||||||
|
|
||||||
|
/* Bits in EPL_IRR */
|
||||||
|
#define E_IRR_IR0 0x20 /* bit 0 of encoded IRQ */
|
||||||
|
#define E_IRR_IR1 0x40 /* bit 1 of encoded IRQ */
|
||||||
|
#define E_IRR_IEN 0x80 /* enable interrupts */
|
||||||
|
|
||||||
|
/* Bits in EPL_LAAR */
|
||||||
|
#define E_LAAR_A19 0x01 /* address lines for above 1M ram */
|
||||||
|
#define E_LAAR_A20 0x02 /* address lines for above 1M ram */
|
||||||
|
#define E_LAAR_A21 0x04 /* address lines for above 1M ram */
|
||||||
|
#define E_LAAR_A22 0x08 /* address lines for above 1M ram */
|
||||||
|
#define E_LAAR_A23 0x10 /* address lines for above 1M ram */
|
||||||
|
#define E_LAAR_SOFTINT 0x20 /* enable software interrupt */
|
||||||
|
#define E_LAAR_LAN16E 0x40 /* enables 16 bit RAM for LAN */
|
||||||
|
#define E_LAAR_MEM16E 0x80 /* enables 16 bit RAM for host */
|
||||||
|
|
||||||
|
/* Bits and values in EPL_TLB */
|
||||||
|
#define E_TLB_EB 0x05 /* WD8013EB */
|
||||||
|
#define E_TLB_E 0x27 /* WD8013 Elite */
|
||||||
|
#define E_TLB_SMCE 0x29 /* SMC Elite 16 */
|
||||||
|
#define E_TLB_SMC8216T 0x2A /* SMC 8216 T */
|
||||||
|
#define E_TLB_SMC8216C 0x2B /* SMC 8216 C */
|
||||||
|
|
||||||
|
#define E_TLB_REV 0x1F /* revision mask */
|
||||||
|
#define E_TLB_SOFT 0x20 /* soft config */
|
||||||
|
#define E_TLB_RAM 0x40 /* extra ram bit */
|
||||||
|
|
||||||
|
/* Bits in EPL_790_HWR */
|
||||||
|
#define E_790_HWR_SWH 0x80 /* switch register set */
|
||||||
|
|
||||||
|
/* Bits in EPL_790_ICR */
|
||||||
|
#define E_790_ICR_EIL 0x01 /* enable interrupts */
|
||||||
|
|
||||||
|
/* Bits in EPL_790_GCR when E_790_HWR_SWH is set in EPL_790_HWR */
|
||||||
|
#define E_790_GCR_IR0 0x04 /* bit 0 of encoded IRQ */
|
||||||
|
#define E_790_GCR_IR1 0x08 /* bit 1 of encoded IRQ */
|
||||||
|
#define E_790_GCR_IR2 0x40 /* bit 2 of encoded IRQ */
|
||||||
|
|
||||||
|
|
||||||
|
#define inb_we(dep, reg) (inb(dep->de_base_port+reg))
|
||||||
|
#define outb_we(dep, reg, data) (outb(dep->de_base_port+reg, data))
|
||||||
|
|
||||||
|
#endif /* WDETH_H */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* $PchId: wdeth.h,v 1.6 2003/09/10 19:29:52 philip Exp $
|
||||||
|
*/
|
|
@ -31,9 +31,14 @@
|
||||||
|
|
||||||
_PROTOTYPE( int get_mon_param, (char *key, char *value, int max_size) );
|
_PROTOTYPE( int get_mon_param, (char *key, char *value, int max_size) );
|
||||||
_PROTOTYPE( int env_prefix, (char *env, char *prefix) );
|
_PROTOTYPE( int env_prefix, (char *env, char *prefix) );
|
||||||
|
_PROTOTYPE( int env_prefix_x, (int argc, char *argv[],
|
||||||
|
char *env, char *prefix) );
|
||||||
_PROTOTYPE( void env_panic, (char *key) );
|
_PROTOTYPE( void env_panic, (char *key) );
|
||||||
_PROTOTYPE( int env_parse, (char *env, char *fmt, int field, long *param,
|
_PROTOTYPE( int env_parse, (char *env, char *fmt, int field, long *param,
|
||||||
long min, long max) );
|
long min, long max) );
|
||||||
|
_PROTOTYPE( int env_parse_x, (int argc, char *argv[], char *env,
|
||||||
|
char *fmt, int field, long *param, long min, long max) );
|
||||||
|
|
||||||
|
|
||||||
#define fkey_map(fkeys, sfkeys) fkey_ctl(FKEY_MAP, (fkeys), (sfkeys))
|
#define fkey_map(fkeys, sfkeys) fkey_ctl(FKEY_MAP, (fkeys), (sfkeys))
|
||||||
#define fkey_unmap(fkeys, sfkeys) fkey_ctl(FKEY_UNMAP, (fkeys), (sfkeys))
|
#define fkey_unmap(fkeys, sfkeys) fkey_ctl(FKEY_UNMAP, (fkeys), (sfkeys))
|
||||||
|
|
|
@ -12,6 +12,21 @@ char *fmt; /* template to parse it with */
|
||||||
int field; /* field number of value to return */
|
int field; /* field number of value to return */
|
||||||
long *param; /* address of parameter to get */
|
long *param; /* address of parameter to get */
|
||||||
long min, max; /* minimum and maximum values for the parameter */
|
long min, max; /* minimum and maximum values for the parameter */
|
||||||
|
{
|
||||||
|
return env_parse_x(0, NULL, env, fmt, field, param, min, max);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*=========================================================================*
|
||||||
|
* env_parse_x *
|
||||||
|
*=========================================================================*/
|
||||||
|
PUBLIC int env_parse_x(argc, argv, env, fmt, field, param, min, max)
|
||||||
|
int argc;
|
||||||
|
char *argv[];
|
||||||
|
char *env; /* environment variable to inspect */
|
||||||
|
char *fmt; /* template to parse it with */
|
||||||
|
int field; /* field number of value to return */
|
||||||
|
long *param; /* address of parameter to get */
|
||||||
|
long min, max; /* minimum and maximum values for the parameter */
|
||||||
{
|
{
|
||||||
/* Parse an environment variable setting, something like "DPETH0=300:3".
|
/* Parse an environment variable setting, something like "DPETH0=300:3".
|
||||||
* Panic if the parsing fails. Return EP_UNSET if the environment variable
|
* Panic if the parsing fails. Return EP_UNSET if the environment variable
|
||||||
|
@ -29,9 +44,27 @@ long min, max; /* minimum and maximum values for the parameter */
|
||||||
char value[EP_BUF_SIZE];
|
char value[EP_BUF_SIZE];
|
||||||
char PUNCT[] = ":,;.";
|
char PUNCT[] = ":,;.";
|
||||||
long newpar;
|
long newpar;
|
||||||
int s, i = 0, radix, r;
|
int s, i, radix, r, keylen;
|
||||||
|
|
||||||
if ((s=get_mon_param(env, value, sizeof(value))) != 0) {
|
keylen= strlen(env);
|
||||||
|
for (i= 0; i<argc; i++)
|
||||||
|
{
|
||||||
|
if (strncmp(argv[i], env, keylen) != 0)
|
||||||
|
continue;
|
||||||
|
if (strlen(argv[i]) <= keylen)
|
||||||
|
continue;
|
||||||
|
if (argv[i][keylen] != '=')
|
||||||
|
continue;
|
||||||
|
val= argv[i]+keylen+1;
|
||||||
|
if (strlen(val)+1 > EP_BUF_SIZE)
|
||||||
|
{
|
||||||
|
printf("WARNING: env_parse() failed: argument too long\n");
|
||||||
|
return(EP_EGETKENV);
|
||||||
|
}
|
||||||
|
strcpy(value, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i >= argc && (s=get_mon_param(env, value, sizeof(value))) != 0) {
|
||||||
if (s == ESRCH) return(EP_UNSET); /* only error allowed */
|
if (s == ESRCH) return(EP_UNSET); /* only error allowed */
|
||||||
printf("WARNING: get_mon_param() failed in env_parse(): %d\n",s);
|
printf("WARNING: get_mon_param() failed in env_parse(): %d\n",s);
|
||||||
return(EP_EGETKENV);
|
return(EP_EGETKENV);
|
||||||
|
@ -40,6 +73,7 @@ long min, max; /* minimum and maximum values for the parameter */
|
||||||
if (strcmp(val, "off") == 0) return(EP_OFF);
|
if (strcmp(val, "off") == 0) return(EP_OFF);
|
||||||
if (strcmp(val, "on") == 0) return(EP_ON);
|
if (strcmp(val, "on") == 0) return(EP_ON);
|
||||||
|
|
||||||
|
i = 0;
|
||||||
r = EP_ON;
|
r = EP_ON;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
while (*val == ' ') val++; /* skip spaces */
|
while (*val == ' ') val++; /* skip spaces */
|
||||||
|
|
|
@ -8,16 +8,49 @@
|
||||||
PUBLIC int env_prefix(env, prefix)
|
PUBLIC int env_prefix(env, prefix)
|
||||||
char *env; /* environment variable to inspect */
|
char *env; /* environment variable to inspect */
|
||||||
char *prefix; /* prefix to test for */
|
char *prefix; /* prefix to test for */
|
||||||
|
{
|
||||||
|
return env_prefix_x(0, NULL, env, prefix);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*=========================================================================*
|
||||||
|
* env_prefix_x *
|
||||||
|
*=========================================================================*/
|
||||||
|
PUBLIC int env_prefix_x(argc, argv, env, prefix)
|
||||||
|
int argc;
|
||||||
|
char *argv[];
|
||||||
|
char *env; /* environment variable to inspect */
|
||||||
|
char *prefix; /* prefix to test for */
|
||||||
{
|
{
|
||||||
/* An environment setting may be prefixed by a word, usually "pci".
|
/* An environment setting may be prefixed by a word, usually "pci".
|
||||||
* Return TRUE if a given prefix is used.
|
* Return TRUE if a given prefix is used.
|
||||||
*/
|
*/
|
||||||
char value[EP_BUF_SIZE];
|
char value[EP_BUF_SIZE];
|
||||||
char punct[] = ":,;.";
|
char punct[] = ":,;.";
|
||||||
int s;
|
int i, s, keylen;
|
||||||
|
char *val;
|
||||||
size_t n;
|
size_t n;
|
||||||
|
|
||||||
if ((s = get_mon_param(env, value, sizeof(value))) != 0) {
|
keylen= strlen(env);
|
||||||
|
for (i= 0; i<argc; i++)
|
||||||
|
{
|
||||||
|
printf("env_prefix_x: argv[%d] = '%s'\n", i, argv[i]);
|
||||||
|
if (strncmp(argv[i], env, keylen) != 0)
|
||||||
|
continue;
|
||||||
|
if (strlen(argv[i]) <= keylen)
|
||||||
|
continue;
|
||||||
|
if (argv[i][keylen] != '=')
|
||||||
|
continue;
|
||||||
|
val= argv[i]+keylen+1;
|
||||||
|
if (strlen(val)+1 > EP_BUF_SIZE)
|
||||||
|
{
|
||||||
|
printf("WARNING: env_parse() failed: argument too long\n");
|
||||||
|
return(EP_EGETKENV);
|
||||||
|
}
|
||||||
|
strcpy(value, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i >= argc && (s = get_mon_param(env, value, sizeof(value))) != 0) {
|
||||||
if (s != ESRCH) /* only error allowed */
|
if (s != ESRCH) /* only error allowed */
|
||||||
printf("WARNING: get_mon_param() failed in env_prefix(): %d\n", s);
|
printf("WARNING: get_mon_param() failed in env_prefix(): %d\n", s);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue