summaryrefslogtreecommitdiffstats
path: root/sys/dev/ed
diff options
context:
space:
mode:
authortanimura <tanimura@FreeBSD.org>2000-07-23 15:15:43 +0000
committertanimura <tanimura@FreeBSD.org>2000-07-23 15:15:43 +0000
commit314fd9990b8d7318d55df0fd6e87d0af6aa4cbf0 (patch)
tree068d1c849661b2f20e43b8ed237230489fd041bf /sys/dev/ed
parent2ae5c3dffce3ca0150eb28e8e2e79b27183490c4 (diff)
downloadFreeBSD-src-314fd9990b8d7318d55df0fd6e87d0af6aa4cbf0.zip
FreeBSD-src-314fd9990b8d7318d55df0fd6e87d0af6aa4cbf0.tar.gz
MFPAO: Add support for AX88190, equipped in MELCO LPC3-TX.
Diffstat (limited to 'sys/dev/ed')
-rw-r--r--sys/dev/ed/if_ed.c149
-rw-r--r--sys/dev/ed/if_ed_pccard.c157
-rw-r--r--sys/dev/ed/if_edreg.h40
-rw-r--r--sys/dev/ed/if_edvar.h3
4 files changed, 273 insertions, 76 deletions
diff --git a/sys/dev/ed/if_ed.c b/sys/dev/ed/if_ed.c
index cd35bea..e1bab28 100644
--- a/sys/dev/ed/if_ed.c
+++ b/sys/dev/ed/if_ed.c
@@ -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);
}
}
diff --git a/sys/dev/ed/if_ed_pccard.c b/sys/dev/ed/if_ed_pccard.c
index 9d5fb7f..49bdab8 100644
--- a/sys/dev/ed/if_ed_pccard.c
+++ b/sys/dev/ed/if_ed_pccard.c
@@ -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);
+}
diff --git a/sys/dev/ed/if_edreg.h b/sys/dev/ed/if_edreg.h
index 2d06ef5..c3b38cf 100644
--- a/sys/dev/ed/if_edreg.h
+++ b/sys/dev/ed/if_edreg.h
@@ -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.
*/
/*
@@ -600,6 +605,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
diff --git a/sys/dev/ed/if_edvar.h b/sys/dev/ed/if_edvar.h
index 85170b6..d0ada5a 100644
--- a/sys/dev/ed/if_edvar.h
+++ b/sys/dev/ed/if_edvar.h
@@ -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.
OpenPOWER on IntegriCloud