MFPAO: Add support for AX88190, equipped in MELCO LPC3-TX.
This commit is contained in:
parent
4d532a362e
commit
eecdc4415b
@ -200,7 +200,7 @@ ed_probe_WD80x3(dev)
|
||||
int i;
|
||||
int flags = device_get_flags(dev);
|
||||
u_int memsize, maddr;
|
||||
u_char iptr, isa16bit, sum;
|
||||
u_char iptr, isa16bit, sum, totalsum;
|
||||
u_long conf_maddr, conf_msize, irq, junk;
|
||||
|
||||
error = ed_alloc_port(dev, 0, ED_WD_IO_PORTS);
|
||||
@ -209,12 +209,16 @@ ed_probe_WD80x3(dev)
|
||||
|
||||
sc->asic_addr = rman_get_start(sc->port_res);
|
||||
sc->nic_addr = sc->asic_addr + ED_WD_NIC_OFFSET;
|
||||
sc->is790 = 0;
|
||||
sc->chip_type = ED_CHIP_TYPE_DP8390;
|
||||
|
||||
#ifdef TOSH_ETHER
|
||||
outb(sc->asic_addr + ED_WD_MSR, ED_WD_MSR_POW);
|
||||
DELAY(10000);
|
||||
#endif
|
||||
if (ED_FLAGS_GETTYPE(flags) == ED_FLAGS_TOSH_ETHER) {
|
||||
totalsum = ED_WD_ROM_CHECKSUM_TOTAL_TOSH_ETHER;
|
||||
outb(sc->asic_addr + ED_WD_MSR, ED_WD_MSR_POW);
|
||||
DELAY(10000);
|
||||
}
|
||||
else
|
||||
totalsum = ED_WD_ROM_CHECKSUM_TOTAL;
|
||||
|
||||
|
||||
/*
|
||||
* Attempt to do a checksum over the station address PROM. If it
|
||||
@ -225,7 +229,7 @@ ed_probe_WD80x3(dev)
|
||||
for (sum = 0, i = 0; i < 8; ++i)
|
||||
sum += inb(sc->asic_addr + ED_WD_PROM + i);
|
||||
|
||||
if (sum != ED_WD_ROM_CHECKSUM_TOTAL) {
|
||||
if (sum != totalsum) {
|
||||
|
||||
/*
|
||||
* Checksum is invalid. This often happens with cheap WD8003E
|
||||
@ -237,11 +241,11 @@ ed_probe_WD80x3(dev)
|
||||
return (ENXIO);
|
||||
}
|
||||
/* reset card to force it into a known state. */
|
||||
#ifdef TOSH_ETHER
|
||||
outb(sc->asic_addr + ED_WD_MSR, ED_WD_MSR_RST | ED_WD_MSR_POW);
|
||||
#else
|
||||
outb(sc->asic_addr + ED_WD_MSR, ED_WD_MSR_RST);
|
||||
#endif
|
||||
if (ED_FLAGS_GETTYPE(flags) == ED_FLAGS_TOSH_ETHER)
|
||||
outb(sc->asic_addr + ED_WD_MSR, ED_WD_MSR_RST | ED_WD_MSR_POW);
|
||||
else
|
||||
outb(sc->asic_addr + ED_WD_MSR, ED_WD_MSR_RST);
|
||||
|
||||
DELAY(100);
|
||||
outb(sc->asic_addr + ED_WD_MSR, inb(sc->asic_addr + ED_WD_MSR) & ~ED_WD_MSR_RST);
|
||||
/* wait in the case this card is reading its EEROM */
|
||||
@ -337,9 +341,8 @@ ed_probe_WD80x3(dev)
|
||||
inb(sc->asic_addr + ED_WD790_HWR) & ~ED_WD790_HWR_SWH);
|
||||
|
||||
isa16bit = 1;
|
||||
sc->is790 = 1;
|
||||
sc->chip_type = ED_CHIP_TYPE_WD790;
|
||||
break;
|
||||
#ifdef TOSH_ETHER
|
||||
case ED_TYPE_TOSHIBA1:
|
||||
sc->type_str = "Toshiba1";
|
||||
memsize = 32768;
|
||||
@ -350,7 +353,6 @@ ed_probe_WD80x3(dev)
|
||||
memsize = 32768;
|
||||
isa16bit = 1;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
sc->type_str = "";
|
||||
break;
|
||||
@ -361,9 +363,7 @@ ed_probe_WD80x3(dev)
|
||||
* in the ICR.
|
||||
*/
|
||||
if (isa16bit && (sc->type != ED_TYPE_WD8013EBT)
|
||||
#ifdef TOSH_ETHER
|
||||
&& (sc->type != ED_TYPE_TOSHIBA1) && (sc->type != ED_TYPE_TOSHIBA4)
|
||||
#endif
|
||||
&& ((inb(sc->asic_addr + ED_WD_ICR) & ED_WD_ICR_16BIT) == 0)) {
|
||||
isa16bit = 0;
|
||||
memsize = 8192;
|
||||
@ -407,7 +407,7 @@ ed_probe_WD80x3(dev)
|
||||
* If possible, get the assigned interrupt number from the card and
|
||||
* use it.
|
||||
*/
|
||||
if ((sc->type & ED_WD_SOFTCONFIG) && (!sc->is790)) {
|
||||
if ((sc->type & ED_WD_SOFTCONFIG) && (sc->chip_type != ED_CHIP_TYPE_WD790)) {
|
||||
|
||||
/*
|
||||
* Assemble together the encoded interrupt number.
|
||||
@ -432,7 +432,7 @@ ed_probe_WD80x3(dev)
|
||||
outb(sc->asic_addr + ED_WD_IRR,
|
||||
inb(sc->asic_addr + ED_WD_IRR) | ED_WD_IRR_IEN);
|
||||
}
|
||||
if (sc->is790) {
|
||||
if (sc->chip_type == ED_CHIP_TYPE_WD790) {
|
||||
outb(sc->asic_addr + ED_WD790_HWR,
|
||||
inb(sc->asic_addr + ED_WD790_HWR) | ED_WD790_HWR_SWH);
|
||||
iptr = (((inb(sc->asic_addr + ED_WD790_GCR) & ED_WD790_GCR_IR2) >> 4) |
|
||||
@ -500,7 +500,7 @@ ed_probe_WD80x3(dev)
|
||||
* Set upper address bits and 8/16 bit access to shared memory.
|
||||
*/
|
||||
if (isa16bit) {
|
||||
if (sc->is790) {
|
||||
if (sc->chip_type == ED_CHIP_TYPE_WD790) {
|
||||
sc->wd_laar_proto = inb(sc->asic_addr + ED_WD_LAAR);
|
||||
} else {
|
||||
sc->wd_laar_proto = ED_WD_LAAR_L16EN |
|
||||
@ -513,10 +513,8 @@ ed_probe_WD80x3(dev)
|
||||
ED_WD_LAAR_M16EN);
|
||||
} else {
|
||||
if (((sc->type & ED_WD_SOFTCONFIG) ||
|
||||
#ifdef TOSH_ETHER
|
||||
(sc->type == ED_TYPE_TOSHIBA1) || (sc->type == ED_TYPE_TOSHIBA4) ||
|
||||
#endif
|
||||
(sc->type == ED_TYPE_WD8013EBT)) && (!sc->is790)) {
|
||||
(sc->type == ED_TYPE_WD8013EBT)) && (sc->chip_type != ED_CHIP_TYPE_WD790)) {
|
||||
sc->wd_laar_proto = (kvtop(sc->mem_start) >> 19) &
|
||||
ED_WD_LAAR_ADDRHI;
|
||||
outb(sc->asic_addr + ED_WD_LAAR, sc->wd_laar_proto);
|
||||
@ -526,16 +524,20 @@ ed_probe_WD80x3(dev)
|
||||
/*
|
||||
* Set address and enable interface shared memory.
|
||||
*/
|
||||
if (!sc->is790) {
|
||||
#ifdef TOSH_ETHER
|
||||
outb(sc->asic_addr + ED_WD_MSR + 1, ((kvtop(sc->mem_start) >> 8) & 0xe0) | 4);
|
||||
outb(sc->asic_addr + ED_WD_MSR + 2, ((kvtop(sc->mem_start) >> 16) & 0x0f));
|
||||
outb(sc->asic_addr + ED_WD_MSR, ED_WD_MSR_MENB | ED_WD_MSR_POW);
|
||||
|
||||
#else
|
||||
outb(sc->asic_addr + ED_WD_MSR, ((kvtop(sc->mem_start) >> 13) &
|
||||
ED_WD_MSR_ADDR) | ED_WD_MSR_MENB);
|
||||
#endif
|
||||
if (sc->chip_type != ED_CHIP_TYPE_WD790) {
|
||||
if (ED_FLAGS_GETTYPE(flags) == ED_FLAGS_TOSH_ETHER) {
|
||||
outb(sc->asic_addr + ED_WD_MSR + 1,
|
||||
((kvtop(sc->mem_start) >> 8) & 0xe0) | 4);
|
||||
outb(sc->asic_addr + ED_WD_MSR + 2,
|
||||
((kvtop(sc->mem_start) >> 16) & 0x0f));
|
||||
outb(sc->asic_addr + ED_WD_MSR,
|
||||
ED_WD_MSR_MENB | ED_WD_MSR_POW);
|
||||
}
|
||||
else {
|
||||
outb(sc->asic_addr + ED_WD_MSR,
|
||||
((kvtop(sc->mem_start) >> 13) &
|
||||
ED_WD_MSR_ADDR) | ED_WD_MSR_MENB);
|
||||
}
|
||||
sc->cr_proto = ED_CR_RD2;
|
||||
} else {
|
||||
outb(sc->asic_addr + ED_WD_MSR, ED_WD_MSR_MENB);
|
||||
@ -569,7 +571,7 @@ ed_probe_WD80x3(dev)
|
||||
* Disable 16 bit access to shared memory
|
||||
*/
|
||||
if (isa16bit) {
|
||||
if (sc->is790) {
|
||||
if (sc->chip_type == ED_CHIP_TYPE_WD790) {
|
||||
outb(sc->asic_addr + ED_WD_MSR, 0x00);
|
||||
}
|
||||
outb(sc->asic_addr + ED_WD_LAAR, sc->wd_laar_proto &
|
||||
@ -588,7 +590,7 @@ ed_probe_WD80x3(dev)
|
||||
* shared memory can be used in this 128k region, too.
|
||||
*/
|
||||
if (isa16bit) {
|
||||
if (sc->is790) {
|
||||
if (sc->chip_type == ED_CHIP_TYPE_WD790) {
|
||||
outb(sc->asic_addr + ED_WD_MSR, 0x00);
|
||||
}
|
||||
outb(sc->asic_addr + ED_WD_LAAR, sc->wd_laar_proto &
|
||||
@ -947,10 +949,10 @@ ed_probe_Novell_generic(dev, port_rid, flags)
|
||||
/* XXX - do Novell-specific probe here */
|
||||
|
||||
/* Reset the board */
|
||||
#ifdef GWETHER
|
||||
outb(sc->asic_addr + ED_NOVELL_RESET, 0);
|
||||
DELAY(200);
|
||||
#endif /* GWETHER */
|
||||
if (ED_FLAGS_GETTYPE(flags) == ED_FLAGS_GWETHER) {
|
||||
outb(sc->asic_addr + ED_NOVELL_RESET, 0);
|
||||
DELAY(200);
|
||||
}
|
||||
tmp = inb(sc->asic_addr + ED_NOVELL_RESET);
|
||||
|
||||
/*
|
||||
@ -1053,7 +1055,7 @@ ed_probe_Novell_generic(dev, port_rid, flags)
|
||||
sc->mem_end = sc->mem_start + memsize;
|
||||
sc->tx_page_start = memsize / ED_PAGE_SIZE;
|
||||
|
||||
#ifdef GWETHER
|
||||
if (ED_FLAGS_GETTYPE(flags) == ED_FLAGS_GWETHER)
|
||||
{
|
||||
int x, i, mstart = 0, msize = 0;
|
||||
char pbuf0[ED_PAGE_SIZE], pbuf[ED_PAGE_SIZE], tbuf[ED_PAGE_SIZE];
|
||||
@ -1114,7 +1116,6 @@ ed_probe_Novell_generic(dev, port_rid, flags)
|
||||
sc->mem_end = (char *) (msize + mstart);
|
||||
sc->tx_page_start = mstart / ED_PAGE_SIZE;
|
||||
}
|
||||
#endif /* GWETHER */
|
||||
|
||||
/*
|
||||
* Use one xmit buffer if < 16k, two buffers otherwise (if not told
|
||||
@ -1134,11 +1135,10 @@ ed_probe_Novell_generic(dev, port_rid, flags)
|
||||
for (n = 0; n < ETHER_ADDR_LEN; n++)
|
||||
sc->arpcom.ac_enaddr[n] = romdata[n * (sc->isa16bit + 1)];
|
||||
|
||||
#ifdef GWETHER
|
||||
if (sc->arpcom.ac_enaddr[2] == 0x86) {
|
||||
if ((ED_FLAGS_GETTYPE(flags) == ED_FLAGS_GWETHER) &&
|
||||
(sc->arpcom.ac_enaddr[2] == 0x86)) {
|
||||
sc->type_str = "Gateway AT";
|
||||
}
|
||||
#endif /* GWETHER */
|
||||
|
||||
/* clear any pending interrupts that might have occurred above */
|
||||
outb(sc->nic_addr + ED_P0_ISR, 0xff);
|
||||
@ -1198,7 +1198,7 @@ ed_probe_HP_pclanp(dev)
|
||||
/* Fill in basic information */
|
||||
sc->asic_addr = rman_get_start(sc->port_res) + ED_HPP_ASIC_OFFSET;
|
||||
sc->nic_addr = rman_get_start(sc->port_res) + ED_HPP_NIC_OFFSET;
|
||||
sc->is790 = 0;
|
||||
sc->chip_type = ED_CHIP_TYPE_DP8390;
|
||||
sc->isa16bit = 0; /* the 8390 core needs to be in byte mode */
|
||||
|
||||
/*
|
||||
@ -1506,9 +1506,8 @@ ed_alloc_port(dev, rid, size)
|
||||
sc->port_res = res;
|
||||
sc->port_used = size;
|
||||
return (0);
|
||||
} else {
|
||||
} else
|
||||
return (ENOENT);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1618,7 +1617,7 @@ ed_attach(sc, unit, flags)
|
||||
/*
|
||||
* XXX - should do a better job.
|
||||
*/
|
||||
if (sc->is790)
|
||||
if (sc->chip_type == ED_CHIP_TYPE_WD790)
|
||||
sc->mibdata.dot3StatsEtherChipSet =
|
||||
DOT3CHIPSET(dot3VendorWesternDigital,
|
||||
dot3ChipSetWesternDigital83C790);
|
||||
@ -1716,7 +1715,8 @@ ed_stop(sc)
|
||||
* 'n' (about 5ms). It shouldn't even take 5us on modern DS8390's, but
|
||||
* just in case it's an old one.
|
||||
*/
|
||||
while (((inb(sc->nic_addr + ED_P0_ISR) & ED_ISR_RST) == 0) && --n);
|
||||
if (sc->chip_type != ED_CHIP_TYPE_AX88190)
|
||||
while (((inb(sc->nic_addr + ED_P0_ISR) & ED_ISR_RST) == 0) && --n);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1815,7 +1815,7 @@ ed_init(xsc)
|
||||
outb(sc->nic_addr + ED_P0_TPSR, sc->tx_page_start);
|
||||
outb(sc->nic_addr + ED_P0_PSTART, sc->rec_page_start);
|
||||
/* Set lower bits of byte addressable framing to 0 */
|
||||
if (sc->is790)
|
||||
if (sc->chip_type == ED_CHIP_TYPE_WD790)
|
||||
outb(sc->nic_addr + 0x09, 0);
|
||||
|
||||
/*
|
||||
@ -2033,11 +2033,12 @@ outloop:
|
||||
* WD/SMC boards.
|
||||
*/
|
||||
case ED_VENDOR_WD_SMC:{
|
||||
outb(sc->asic_addr + ED_WD_LAAR,
|
||||
sc->wd_laar_proto | ED_WD_LAAR_M16EN);
|
||||
if (sc->is790) {
|
||||
outb(sc->asic_addr + ED_WD_MSR, ED_WD_MSR_MENB);
|
||||
}
|
||||
outb(sc->asic_addr + ED_WD_LAAR,
|
||||
sc->wd_laar_proto | ED_WD_LAAR_M16EN);
|
||||
if (sc->chip_type == ED_CHIP_TYPE_WD790) {
|
||||
outb(sc->asic_addr + ED_WD_MSR,
|
||||
ED_WD_MSR_MENB);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -2058,12 +2059,12 @@ outloop:
|
||||
ED_3COM_GACFR_RSEL | ED_3COM_GACFR_MBS0);
|
||||
break;
|
||||
case ED_VENDOR_WD_SMC:{
|
||||
if (sc->is790) {
|
||||
outb(sc->asic_addr + ED_WD_MSR, 0x00);
|
||||
}
|
||||
outb(sc->asic_addr + ED_WD_LAAR,
|
||||
sc->wd_laar_proto & ~ED_WD_LAAR_M16EN);
|
||||
break;
|
||||
if (sc->chip_type == ED_CHIP_TYPE_WD790) {
|
||||
outb(sc->asic_addr + ED_WD_MSR, 0x00);
|
||||
}
|
||||
outb(sc->asic_addr + ED_WD_LAAR,
|
||||
sc->wd_laar_proto & ~ED_WD_LAAR_M16EN);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2265,6 +2266,14 @@ edintr(arg)
|
||||
*/
|
||||
outb(sc->nic_addr + ED_P0_ISR, isr);
|
||||
|
||||
/* XXX workaround for AX88190 */
|
||||
if (sc->chip_type == ED_CHIP_TYPE_AX88190) {
|
||||
while(inb(sc->nic_addr + ED_P0_ISR) & isr) {
|
||||
outb(sc->nic_addr + ED_P0_ISR,0);
|
||||
outb(sc->nic_addr + ED_P0_ISR,isr);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Handle transmitter interrupts. Handle these first because
|
||||
* the receiver will reset the board under some conditions.
|
||||
@ -2432,7 +2441,7 @@ edintr(arg)
|
||||
|
||||
outb(sc->asic_addr + ED_WD_LAAR,
|
||||
sc->wd_laar_proto | ED_WD_LAAR_M16EN);
|
||||
if (sc->is790) {
|
||||
if (sc->chip_type == ED_CHIP_TYPE_WD790) {
|
||||
outb(sc->asic_addr + ED_WD_MSR,
|
||||
ED_WD_MSR_MENB);
|
||||
}
|
||||
@ -2443,7 +2452,7 @@ edintr(arg)
|
||||
if (sc->isa16bit &&
|
||||
(sc->vendor == ED_VENDOR_WD_SMC)) {
|
||||
|
||||
if (sc->is790) {
|
||||
if (sc->chip_type == ED_CHIP_TYPE_WD790) {
|
||||
outb(sc->asic_addr + ED_WD_MSR, 0x00);
|
||||
}
|
||||
outb(sc->asic_addr + ED_WD_LAAR,
|
||||
@ -3174,6 +3183,14 @@ ed_setrcr(sc)
|
||||
{
|
||||
struct ifnet *ifp = (struct ifnet *)sc;
|
||||
int i;
|
||||
u_char reg1;
|
||||
|
||||
/* Bit 6 in AX88190 RCR register must be set. */
|
||||
if (sc->chip_type == ED_CHIP_TYPE_AX88190)
|
||||
reg1 = ED_RCR_INTT;
|
||||
else
|
||||
reg1 = 0x00;
|
||||
|
||||
|
||||
/* set page 1 registers */
|
||||
outb(sc->nic_addr + ED_P0_CR, sc->cr_proto | ED_CR_PAGE_1 | ED_CR_STP);
|
||||
@ -3194,7 +3211,7 @@ ed_setrcr(sc)
|
||||
outb(sc->nic_addr + ED_P0_CR, sc->cr_proto | ED_CR_STP);
|
||||
|
||||
outb(sc->nic_addr + ED_P0_RCR, ED_RCR_PRO | ED_RCR_AM |
|
||||
ED_RCR_AB | ED_RCR_AR | ED_RCR_SEP);
|
||||
ED_RCR_AB | ED_RCR_AR | ED_RCR_SEP | reg1);
|
||||
} else {
|
||||
/* set up multicast addresses and filter modes */
|
||||
if (ifp->if_flags & IFF_MULTICAST) {
|
||||
@ -3215,7 +3232,7 @@ ed_setrcr(sc)
|
||||
/* Set page 0 registers */
|
||||
outb(sc->nic_addr + ED_P0_CR, sc->cr_proto | ED_CR_STP);
|
||||
|
||||
outb(sc->nic_addr + ED_P0_RCR, ED_RCR_AM | ED_RCR_AB);
|
||||
outb(sc->nic_addr + ED_P0_RCR, ED_RCR_AM | ED_RCR_AB | reg1);
|
||||
} else {
|
||||
|
||||
/*
|
||||
@ -3228,7 +3245,7 @@ ed_setrcr(sc)
|
||||
/* Set page 0 registers */
|
||||
outb(sc->nic_addr + ED_P0_CR, sc->cr_proto | ED_CR_STP);
|
||||
|
||||
outb(sc->nic_addr + ED_P0_RCR, ED_RCR_AB);
|
||||
outb(sc->nic_addr + ED_P0_RCR, ED_RCR_AB | reg1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -31,6 +31,10 @@
|
||||
#include <sys/systm.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/conf.h>
|
||||
#include <sys/uio.h>
|
||||
#include <sys/select.h>
|
||||
#include <machine/clock.h>
|
||||
|
||||
#include <sys/module.h>
|
||||
#include <sys/bus.h>
|
||||
@ -41,8 +45,13 @@
|
||||
#include <net/if_arp.h>
|
||||
#include <net/if_mib.h>
|
||||
|
||||
#include <dev/ed/if_edreg.h>
|
||||
#include <dev/ed/if_edvar.h>
|
||||
#include <dev/pccard/pccardvar.h>
|
||||
#include <pccard/cardinfo.h>
|
||||
#include <pccard/slot.h>
|
||||
|
||||
#define CARD_MAJOR 50
|
||||
|
||||
/*
|
||||
* PC-Card (PCMCIA) specific code.
|
||||
@ -51,6 +60,10 @@ static int ed_pccard_probe(device_t);
|
||||
static int ed_pccard_attach(device_t);
|
||||
static int ed_pccard_detach(device_t);
|
||||
|
||||
static void ax88190_geteprom(device_t);
|
||||
static int ed_pccard_memwrite(device_t dev, off_t offset, u_char byte);
|
||||
static int ed_pccard_memread(device_t dev, off_t offset, u_char *buf, int size);
|
||||
|
||||
static device_method_t ed_pccard_methods[] = {
|
||||
/* Device interface */
|
||||
DEVMETHOD(device_probe, ed_pccard_probe),
|
||||
@ -107,6 +120,32 @@ static int
|
||||
ed_pccard_probe(device_t dev)
|
||||
{
|
||||
int error;
|
||||
int flags;
|
||||
struct ed_softc *sc = device_get_softc(dev);
|
||||
|
||||
flags = device_get_flags(dev);
|
||||
|
||||
if (ED_FLAGS_GETTYPE(flags) == ED_FLAGS_AX88190) {
|
||||
/* Special setup for AX88190 */
|
||||
u_char rdbuf[4];
|
||||
int iobase;
|
||||
int attr_ioport;
|
||||
sc->chip_type = ED_CHIP_TYPE_AX88190;
|
||||
/*
|
||||
* Check & Set Attribute Memory IOBASE Register
|
||||
*/
|
||||
ed_pccard_memread(dev,ED_AX88190_IOBASE0,rdbuf,4);
|
||||
attr_ioport = rdbuf[2] << 8 | rdbuf[0];
|
||||
iobase = bus_get_resource_start(dev, SYS_RES_IOPORT, 0);
|
||||
if (attr_ioport != iobase) {
|
||||
#if notdef
|
||||
printf("AX88190 IOBASE MISMATCH %04x -> %04x Setting\n",attr_ioport,iobase);
|
||||
#endif /* notdef */
|
||||
ed_pccard_memwrite(dev,ED_AX88190_IOBASE0,iobase & 0xff);
|
||||
ed_pccard_memwrite(dev,ED_AX88190_IOBASE1,(iobase >> 8) & 0xff);
|
||||
}
|
||||
ax88190_geteprom(dev);
|
||||
}
|
||||
|
||||
error = ed_probe_Novell(dev);
|
||||
if (error == 0)
|
||||
@ -161,3 +200,121 @@ ed_pccard_attach(device_t dev)
|
||||
error = ed_attach(sc, device_get_unit(dev), flags);
|
||||
return (error);
|
||||
}
|
||||
|
||||
static void
|
||||
ax88190_geteprom(device_t dev)
|
||||
{
|
||||
int prom[16],i;
|
||||
u_char tmp;
|
||||
struct ed_softc *sc;
|
||||
struct pccard_devinfo *devi;
|
||||
int iobase;
|
||||
struct {
|
||||
unsigned char offset,value;
|
||||
} pg_seq[]={
|
||||
{ED_P0_CR ,ED_CR_RD2|ED_CR_STP}, /* Select Page0 */
|
||||
{ED_P0_DCR,0x01},
|
||||
{ED_P0_RBCR0, 0x00}, /* Clear the count regs. */
|
||||
{ED_P0_RBCR1, 0x00},
|
||||
{ED_P0_IMR, 0x00}, /* Mask completion irq. */
|
||||
{ED_P0_ISR, 0xff},
|
||||
{ED_P0_RCR, ED_RCR_MON|ED_RCR_INTT}, /* Set To Monitor */
|
||||
{ED_P0_TCR, ED_TCR_LB0}, /* loopback mode. */
|
||||
{ED_P0_RBCR0,32},
|
||||
{ED_P0_RBCR1,0x00},
|
||||
{ED_P0_RSAR0,0x00},
|
||||
{ED_P0_RSAR1,0x04},
|
||||
{ED_P0_CR ,ED_CR_RD0|ED_CR_STA},
|
||||
};
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
devi = device_get_ivars(dev);
|
||||
iobase = bus_get_resource_start(dev, SYS_RES_IOPORT, 0);
|
||||
|
||||
/* XXX: no bus_space_*()? */
|
||||
|
||||
/* Default Set */
|
||||
sc->asic_addr = iobase + ED_NOVELL_ASIC_OFFSET;
|
||||
sc->nic_addr = iobase + ED_NOVELL_NIC_OFFSET;
|
||||
/* Reset Card */
|
||||
tmp = inb(sc->asic_addr + ED_NOVELL_RESET);
|
||||
outb(sc->asic_addr + ED_NOVELL_RESET, tmp);
|
||||
DELAY(5000);
|
||||
outb(sc->nic_addr + ED_P0_CR, ED_CR_RD2 | ED_CR_STP);
|
||||
DELAY(5000);
|
||||
|
||||
/* Card Settings */
|
||||
for(i=0;i<sizeof(pg_seq)/sizeof(pg_seq[0]);i++) {
|
||||
outb(sc->nic_addr + pg_seq[i].offset , pg_seq[i].value);
|
||||
}
|
||||
|
||||
/* Get Data */
|
||||
for(i=0;i<16;i++) {
|
||||
prom[i] = inw(sc->asic_addr);
|
||||
}
|
||||
/*
|
||||
for(i=0;i<16;i++) {
|
||||
printf("ax88190 eprom [%02d] %02x %02x\n",
|
||||
i,prom[i] & 0xff,prom[i] >> 8);
|
||||
}
|
||||
*/
|
||||
sc->arpcom.ac_enaddr[0] = prom[0] & 0xff;
|
||||
sc->arpcom.ac_enaddr[1] = prom[0] >> 8;
|
||||
sc->arpcom.ac_enaddr[2] = prom[1] & 0xff;
|
||||
sc->arpcom.ac_enaddr[3] = prom[1] >> 8;
|
||||
sc->arpcom.ac_enaddr[4] = prom[2] & 0xff;
|
||||
sc->arpcom.ac_enaddr[5] = prom[2] >> 8;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* XXX: Warner-san, any plan to provide access to the attribute memory? */
|
||||
static int
|
||||
ed_pccard_memwrite(device_t dev, off_t offset, u_char byte)
|
||||
{
|
||||
struct pccard_devinfo *devi;
|
||||
dev_t d;
|
||||
struct iovec iov;
|
||||
struct uio uios;
|
||||
|
||||
devi = device_get_ivars(dev);
|
||||
|
||||
iov.iov_base = &byte;
|
||||
iov.iov_len = sizeof(byte);
|
||||
|
||||
uios.uio_iov = &iov;
|
||||
uios.uio_iovcnt = 1;
|
||||
uios.uio_offset = offset;
|
||||
uios.uio_resid = sizeof(byte);
|
||||
uios.uio_segflg = UIO_SYSSPACE;
|
||||
uios.uio_rw = UIO_WRITE;
|
||||
uios.uio_procp = 0;
|
||||
|
||||
d = makedev(CARD_MAJOR, devi->slt->slotnum);
|
||||
return devsw(d)->d_write(d, &uios, 0);
|
||||
}
|
||||
|
||||
static int
|
||||
ed_pccard_memread(device_t dev, off_t offset, u_char *buf, int size)
|
||||
{
|
||||
struct pccard_devinfo *devi;
|
||||
dev_t d;
|
||||
struct iovec iov;
|
||||
struct uio uios;
|
||||
|
||||
devi = device_get_ivars(dev);
|
||||
|
||||
iov.iov_base = buf;
|
||||
iov.iov_len = size;
|
||||
|
||||
uios.uio_iov = &iov;
|
||||
uios.uio_iovcnt = 1;
|
||||
uios.uio_offset = offset;
|
||||
uios.uio_resid = size;
|
||||
uios.uio_segflg = UIO_SYSSPACE;
|
||||
uios.uio_rw = UIO_READ;
|
||||
uios.uio_procp = 0;
|
||||
|
||||
d = makedev(CARD_MAJOR, devi->slt->slotnum);
|
||||
return devsw(d)->d_read(d, &uios, 0);
|
||||
}
|
||||
|
@ -482,7 +482,12 @@
|
||||
#define ED_RCR_MON 0x20
|
||||
|
||||
/*
|
||||
* bits 6 and 7 are unused/reserved.
|
||||
* INTT: Interrupt Trigger Mode for AX88190.
|
||||
*/
|
||||
#define ED_RCR_INTT 0x40
|
||||
|
||||
/*
|
||||
* bit 7 is unused/reserved.
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -599,6 +604,15 @@ struct ed_ring {
|
||||
*/
|
||||
#define ED_FLAGS_FORCE_PIO 0x0010
|
||||
|
||||
/*
|
||||
* These are flags describing the chip type.
|
||||
*/
|
||||
#define ED_FLAGS_TOSH_ETHER 0x10000
|
||||
#define ED_FLAGS_GWETHER 0x20000
|
||||
#define ED_FLAGS_AX88190 0x30000
|
||||
|
||||
#define ED_FLAGS_GETTYPE(flg) ((flg) & 0xff0000)
|
||||
|
||||
/*
|
||||
* Definitions for Western digital/SMC WD80x3 series ASIC
|
||||
*/
|
||||
@ -629,14 +643,12 @@ struct ed_ring {
|
||||
#define ED_WD_ICR_RX7 0x20 /* recall all but i/o and LAN address */
|
||||
#define ED_WD_ICR_RIO 0x40 /* recall i/o address */
|
||||
#define ED_WD_ICR_STO 0x80 /* store to non-volatile memory */
|
||||
#ifdef TOSH_ETHER
|
||||
#define ED_WD_ICR_MEM 0xe0 /* shared mem address A15-A13 (R/W) */
|
||||
#define ED_WD_ICR_MSZ1 0x0f /* memory size, 0x08 = 64K, 0x04 = 32K,
|
||||
0x02 = 16K, 0x01 = 8K */
|
||||
/* 64K can only be used if mem address
|
||||
above 1Mb */
|
||||
/* IAR holds address A23-A16 (R/W) */
|
||||
#endif
|
||||
|
||||
/*
|
||||
* IO Address Register (IAR)
|
||||
@ -782,11 +794,8 @@ struct ed_ring {
|
||||
/*
|
||||
* Checksum total. All 8 bytes in station address PROM will add up to this
|
||||
*/
|
||||
#ifdef TOSH_ETHER
|
||||
#define ED_WD_ROM_CHECKSUM_TOTAL 0xA5
|
||||
#else
|
||||
#define ED_WD_ROM_CHECKSUM_TOTAL 0xFF
|
||||
#endif
|
||||
#define ED_WD_ROM_CHECKSUM_TOTAL 0xFF
|
||||
#define ED_WD_ROM_CHECKSUM_TOTAL_TOSH_ETHER 0xA5
|
||||
|
||||
#define ED_WD_NIC_OFFSET 0x10 /* I/O base offset to NIC */
|
||||
#define ED_WD_ASIC_OFFSET 0 /* I/O base offset to ASIC */
|
||||
@ -1088,3 +1097,18 @@ struct ed_ring {
|
||||
*/
|
||||
|
||||
#define ED_TYPE_HP_PCLANPLUS 0x00
|
||||
|
||||
/*
|
||||
* Chip types.
|
||||
*/
|
||||
|
||||
#define ED_CHIP_TYPE_DP8390 0x00
|
||||
#define ED_CHIP_TYPE_WD790 0x01
|
||||
#define ED_CHIP_TYPE_AX88190 0x02
|
||||
|
||||
/*
|
||||
* AX88190 IOBASE registers.
|
||||
*/
|
||||
|
||||
#define ED_AX88190_IOBASE0 0x3ca
|
||||
#define ED_AX88190_IOBASE1 0x3cc
|
||||
|
@ -58,8 +58,7 @@ struct ed_softc {
|
||||
u_char wd_laar_proto;
|
||||
u_char cr_proto;
|
||||
u_char isa16bit; /* width of access to card 0=8 or 1=16 */
|
||||
int is790; /* set by the probe code if the card is 790
|
||||
* based */
|
||||
int chip_type; /* the type of chip (one of ED_CHIP_TYPE_*) */
|
||||
|
||||
/*
|
||||
* HP PC LAN PLUS card support.
|
||||
|
Loading…
x
Reference in New Issue
Block a user