diff options
author | Aaron Campbell <aaron@cvs.openbsd.org> | 2000-10-26 20:50:45 +0000 |
---|---|---|
committer | Aaron Campbell <aaron@cvs.openbsd.org> | 2000-10-26 20:50:45 +0000 |
commit | 948f076ca0946c27e2283d0d442c7b55a84f2bc2 (patch) | |
tree | c7d79cb835b3a02061b754deae11d45e82599626 /sys/dev | |
parent | c8b93224246edba27e693e5e51e5368c654387f1 (diff) |
Add support for Xircom X3201-based CardBus Ethernet cards. Tested successfully
on four different models, including the CBEM56G-100, RBE-100 RealPort, and the
RBEM56G-100 RealPort. This commit adds support only for the LAN components; the
modem is not configured yet. Detach support to come. Based on work from
FreeBSD, mickey@, nate@, and myself.
Diffstat (limited to 'sys/dev')
-rw-r--r-- | sys/dev/cardbus/files.cardbus | 8 | ||||
-rw-r--r-- | sys/dev/cardbus/if_dc_cardbus.c | 289 | ||||
-rw-r--r-- | sys/dev/ic/dc.c | 170 | ||||
-rw-r--r-- | sys/dev/ic/dcreg.h | 24 |
4 files changed, 467 insertions, 24 deletions
diff --git a/sys/dev/cardbus/files.cardbus b/sys/dev/cardbus/files.cardbus index ae24d348e43..2af27946058 100644 --- a/sys/dev/cardbus/files.cardbus +++ b/sys/dev/cardbus/files.cardbus @@ -1,4 +1,4 @@ -# $OpenBSD: files.cardbus,v 1.3 2000/09/17 05:11:13 aaron Exp $ +# $OpenBSD: files.cardbus,v 1.4 2000/10/26 20:50:44 aaron Exp $ # $NetBSD: files.cardbus,v 1.8 2000/01/26 06:37:24 thorpej Exp $ # # files.cardbus @@ -26,6 +26,12 @@ attach xl at cardbus with xl_cardbus file dev/cardbus/if_xl_cardbus.c xl_cardbus # +# Tulip clone based CardBus cards +# +attach dc at cardbus with dc_cardbus +file dev/cardbus/if_dc_cardbus.c dc_cardbus + +# # Intel PRO/100 8255x based CardBus cards # attach fxp at cardbus with fxp_cardbus diff --git a/sys/dev/cardbus/if_dc_cardbus.c b/sys/dev/cardbus/if_dc_cardbus.c new file mode 100644 index 00000000000..7d842642bc8 --- /dev/null +++ b/sys/dev/cardbus/if_dc_cardbus.c @@ -0,0 +1,289 @@ +/* $OpenBSD: if_dc_cardbus.c,v 1.1 2000/10/26 20:50:44 aaron Exp $ */ + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/mbuf.h> +#include <sys/socket.h> +#include <sys/ioctl.h> +#include <sys/errno.h> +#include <sys/malloc.h> +#include <sys/kernel.h> +#include <sys/proc.h> +#include <sys/device.h> + +#include <net/if.h> +#include <net/if_dl.h> +#include <net/if_types.h> +#include <net/if_media.h> + +#include <netinet/in.h> +#include <netinet/if_ether.h> + +#include <dev/mii/mii.h> +#include <dev/mii/miivar.h> + +#include <machine/bus.h> + +#include <dev/pci/pcivar.h> +#include <dev/pci/pcireg.h> +#include <dev/pci/pcidevs.h> + +#include <dev/cardbus/cardbusvar.h> +#include <dev/cardbus/cardbusdevs.h> + +#include <dev/ic/dcreg.h> + +/* PCI configuration regs */ +#define PCI_CBIO 0x10 +#define PCI_CBMEM 0x14 +#define PCI_CFDA 0x40 + +#define DC_CFDA_SUSPEND 0x80000000 +#define DC_CFDA_STANDBY 0x40000000 + +struct dc_cardbus_softc { + struct dc_softc sc_dc; + int sc_intrline; + + cardbus_devfunc_t sc_ct; + cardbustag_t sc_tag; + bus_size_t sc_mapsize; + int sc_actype; +}; + +int dc_cardbus_match __P((struct device *, void *, void *)); +void dc_cardbus_attach __P((struct device *, struct device *,void *)); +int dc_cardbus_detach __P((struct device *, int)); +int dc_cardbus_activate __P((struct device *, enum devact)); +void dc_cardbus_setup __P((struct dc_cardbus_softc *csc)); + +struct cfattach dc_cardbus_ca = { + sizeof(struct dc_cardbus_softc), dc_cardbus_match, + dc_cardbus_attach, dc_cardbus_detach, + dc_cardbus_activate +}; + +struct dc_type dc_cardbus_devs[] = { + { PCI_VENDOR_DEC, PCI_PRODUCT_DEC_21142 }, + { PCI_VENDOR_XIRCOM, PCI_PRODUCT_XIRCOM_X3201_3_21143 }, + { 0 } +}; + +int +dc_cardbus_match(parent, match, aux) + struct device *parent; + void *match, *aux; +{ + struct cardbus_attach_args *ca = aux; + struct dc_type *t; + + for (t = dc_cardbus_devs; t->dc_vid != 0; t++) { + if ((PCI_VENDOR(ca->ca_id) == t->dc_vid) && + (PCI_PRODUCT(ca->ca_id) == t->dc_did)) + return (1); + } + + return (0); +} + +void +dc_cardbus_attach(parent, self, aux) + struct device *parent, *self; + void *aux; +{ + struct dc_cardbus_softc *csc = (struct dc_cardbus_softc *)self; + struct dc_softc *sc = &csc->sc_dc; + struct cardbus_attach_args *ca = aux; + struct cardbus_devfunc *ct = ca->ca_ct; + cardbus_chipset_tag_t cc = ct->ct_cc; + cardbus_function_tag_t cf = ct->ct_cf; + cardbusreg_t reg; + bus_addr_t addr; + + sc->dc_unit = sc->sc_dev.dv_unit; + csc->sc_ct = ct; + csc->sc_tag = ca->ca_tag; + + Cardbus_function_enable(ct); + + switch (PCI_VENDOR(ca->ca_id)) { + case PCI_VENDOR_DEC: + if (PCI_PRODUCT(ca->ca_id) == PCI_PRODUCT_DEC_21142) { + sc->dc_type = DC_TYPE_21143; + sc->dc_flags |= DC_TX_POLL|DC_TX_USE_TX_INTR; + sc->dc_flags |= DC_REDUCED_MII_POLL; + + sc->dc_pmode = DC_PMODE_MII; + } + break; + case PCI_VENDOR_XIRCOM: + if (PCI_PRODUCT(ca->ca_id) == + PCI_PRODUCT_XIRCOM_X3201_3_21143) { + sc->dc_type = DC_TYPE_XIRCOM; + sc->dc_flags |= DC_TX_INTR_ALWAYS|DC_TX_COALESCE; + sc->dc_pmode = DC_PMODE_MII; + + bcopy(ca->ca_cis.funce.network.netid, + &sc->arpcom.ac_enaddr, + sizeof sc->arpcom.ac_enaddr); + } + break; + default: + printf(": unknown device\n"); + return; + } + + if (Cardbus_mapreg_map(ct, PCI_CBIO, + PCI_MAPREG_TYPE_IO, 0, &sc->dc_btag, &sc->dc_bhandle, &addr, + &csc->sc_mapsize) == 0) { + + csc->sc_actype = CARDBUS_IO_ENABLE; + } else if (Cardbus_mapreg_map(ct, PCI_CBMEM, + PCI_MAPREG_TYPE_MEM|PCI_MAPREG_MEM_TYPE_32BIT, 0, + &sc->dc_btag, &sc->dc_bhandle, &addr, &csc->sc_mapsize) == 0) { + csc->sc_actype = CARDBUS_MEM_ENABLE; + } else { + printf(": can\'t map device registers\n"); + return; + } + + csc->sc_intrline = ca->ca_intrline; + + sc->dc_cachesize = pci_conf_read(cc, ca->ca_tag, DC_PCI_CFLT) & 0xFF; + + dc_cardbus_setup(csc); + cardbus_save_bar(ct); + + /* + * set latency timer, do we really need this? + */ + reg = cardbus_conf_read(cc, cf, ca->ca_tag, CARDBUS_BHLC_REG); + if (CARDBUS_LATTIMER(reg) < 0x20) { + reg &= ~(CARDBUS_LATTIMER_MASK << CARDBUS_LATTIMER_SHIFT); + reg |= (0x20 << CARDBUS_LATTIMER_SHIFT); + cardbus_conf_write(cc, cf, ca->ca_tag, CARDBUS_BHLC_REG, reg); + } + + sc->sc_ih = cardbus_intr_establish(cc, cf, + ca->ca_intrline, IPL_NET, dc_intr, csc); + if (sc->sc_ih == NULL) { + printf(": can\'t establish interrupt at %d\n", + ca->ca_intrline); + return; + } else + printf(" irq %d", ca->ca_intrline); + + dc_reset(sc); + + sc->dc_revision = CARDBUS_REVISION(ca->ca_class); + dc_attach_common(sc); +} + +int +dc_cardbus_detach(self, flags) + struct device *self; + int flags; +{ + struct dc_cardbus_softc *csc = (struct dc_cardbus_softc *)self; + struct dc_softc *sc = &csc->sc_dc; + struct cardbus_devfunc *ct = csc->sc_ct; + struct ifnet *ifp = &sc->arpcom.ac_if; +#if 0 + struct mii_softc *msc; +#endif + int rv = 0; + +#if 0 + for (msc = LIST_FIRST(&sc->sc_mii.mii_phys); msc; + msc = LIST_FIRST(&sc->sc_mii.mii_phys)) + rv |= mii_detach(msc, flags); +#endif + + /* unmap cardbus resources */ + Cardbus_mapreg_unmap(ct, + csc->sc_actype == CARDBUS_IO_ENABLE ? PCI_CBIO : PCI_CBMEM, + sc->dc_btag, sc->dc_bhandle, csc->sc_mapsize); + + ether_ifdetach(ifp); + if_detach(ifp); + + return (rv); +} + +int +dc_cardbus_activate(dev, act) + struct device *dev; + enum devact act; +{ + struct dc_cardbus_softc *csc = (struct dc_cardbus_softc *)dev; + struct dc_softc *sc = &csc->sc_dc; + cardbus_devfunc_t ct = csc->sc_ct; + int s; + + s = splnet(); + switch (act) { + case DVACT_ACTIVATE: + Cardbus_function_enable(ct); + cardbus_restore_bar(ct); + dc_cardbus_setup(csc); + sc->sc_ih = cardbus_intr_establish(ct->ct_cc, ct->ct_cf, + csc->sc_intrline, IPL_NET, dc_intr, csc); + if (sc->sc_ih == NULL) { + printf(": can\'t establish interrupt at %d\n", + csc->sc_intrline); + Cardbus_function_disable(ct); + return -1; + } else + printf("%s: interrupting at %d", + sc->sc_dev.dv_xname, csc->sc_intrline); + break; + + case DVACT_DEACTIVATE: + cardbus_save_bar(ct); + cardbus_intr_disestablish(ct->ct_cc, ct->ct_cf, sc->sc_ih); + Cardbus_function_disable(ct); + break; + } + + splx(s); + return 0; +} + +void +dc_cardbus_setup(csc) + struct dc_cardbus_softc *csc; +{ + cardbus_devfunc_t ct = csc->sc_ct; + cardbus_chipset_tag_t cc = ct->ct_cc; + cardbus_function_tag_t cf = ct->ct_cf; + cardbusreg_t reg; + int r; + + /* wakeup the card if needed */ + reg = cardbus_conf_read(cc, cf, csc->sc_tag, PCI_CFDA); + if (reg | (DC_CFDA_SUSPEND|DC_CFDA_STANDBY)) { + cardbus_conf_write(cc, cf, csc->sc_tag, PCI_CFDA, + reg & ~(DC_CFDA_SUSPEND|DC_CFDA_STANDBY)); +#if 0 +printf("wakeup %x\n", cardbus_conf_read(cc, cf, csc->sc_tag, PCI_CFDA)); +#endif + } + + if (cardbus_get_capability(cc, cf, csc->sc_tag, PCI_CAP_PWRMGMT, &r, 0)) { + r = cardbus_conf_read(cc, cf, csc->sc_tag, r + 4) & 3; + if (r) { + printf("%s: awakening from state D%d\n", + csc->sc_dc.sc_dev.dv_xname, r); + cardbus_conf_write(cc, cf, csc->sc_tag, r + 4, 0); + } + } + + (*ct->ct_cf->cardbus_ctrl)(cc, csc->sc_actype); + (*ct->ct_cf->cardbus_ctrl)(cc, CARDBUS_BM_ENABLE); + + reg = cardbus_conf_read(cc, cf, csc->sc_tag, CARDBUS_COMMAND_STATUS_REG); + reg |= CARDBUS_COMMAND_IO_ENABLE | CARDBUS_COMMAND_MEM_ENABLE | + CARDBUS_COMMAND_MASTER_ENABLE; + cardbus_conf_write(cc, cf, csc->sc_tag, CARDBUS_COMMAND_STATUS_REG, reg); + reg = cardbus_conf_read(cc, cf, csc->sc_tag, CARDBUS_COMMAND_STATUS_REG); +} diff --git a/sys/dev/ic/dc.c b/sys/dev/ic/dc.c index 0480aff6fb6..d07542e9049 100644 --- a/sys/dev/ic/dc.c +++ b/sys/dev/ic/dc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: dc.c,v 1.17 2000/10/18 16:19:34 aaron Exp $ */ +/* $OpenBSD: dc.c,v 1.18 2000/10/26 20:50:43 aaron Exp $ */ /* * Copyright (c) 1997, 1998, 1999 @@ -45,7 +45,9 @@ * ASIX Electronics AX88141 (www.asix.com.tw) * ADMtek AL981 (www.admtek.com.tw) * ADMtek AN983 (www.admtek.com.tw) - * Davicom DM9100, DM9102 (www.davicom8.com) + * Davicom DM9100, DM9102, DM9102A (www.davicom8.com) + * Accton EN1217 (www.accton.com) + * Xircom X3201 (www.xircom.com) * * Datasheets for the 21143 are available at developer.intel.com. * Datasheets for the clone parts can be found at their respective sites. @@ -141,8 +143,8 @@ #include <net/bpf.h> #endif -#include <vm/vm.h> /* for vtophys */ -#include <vm/pmap.h> /* for vtophys */ +#include <vm/vm.h> /* for vtophys */ +#include <vm/pmap.h> /* for vtophys */ #include <dev/mii/mii.h> #include <dev/mii/miivar.h> @@ -199,6 +201,7 @@ u_int32_t dc_crc_be __P((caddr_t)); void dc_setfilt_21143 __P((struct dc_softc *)); void dc_setfilt_asix __P((struct dc_softc *)); void dc_setfilt_admtek __P((struct dc_softc *)); +void dc_setfilt_xircom __P((struct dc_softc *)); void dc_setfilt __P((struct dc_softc *)); @@ -878,6 +881,15 @@ u_int32_t dc_crc_le(sc, addr) if (sc->dc_flags & DC_64BIT_HASH) return (crc & ((1 << DC_BITS_64) - 1)); + /* Xircom's hash filtering table is different (read: weird) */ + /* Xircom uses the LEAST significant bits */ + if (DC_IS_XIRCOM(sc)) { + if ((crc & 0x180) == 0x180) + return (crc & 0x0F) + (crc & 0x70)*3 + (14 << 4); + else + return (crc & 0x1F) + ((crc>>1) & 0xF0)*3 + (12 << 4); + } + return (crc & ((1 << DC_BITS_512) - 1)); } @@ -1056,12 +1068,12 @@ void dc_setfilt_asix(sc) ifp = &sc->arpcom.ac_if; - /* Init our MAC address */ - CSR_WRITE_4(sc, DC_AX_FILTIDX, DC_AX_FILTIDX_PAR0); - CSR_WRITE_4(sc, DC_AX_FILTDATA, + /* Init our MAC address */ + CSR_WRITE_4(sc, DC_AX_FILTIDX, DC_AX_FILTIDX_PAR0); + CSR_WRITE_4(sc, DC_AX_FILTDATA, *(u_int32_t *)(&sc->arpcom.ac_enaddr[0])); - CSR_WRITE_4(sc, DC_AX_FILTIDX, DC_AX_FILTIDX_PAR1); - CSR_WRITE_4(sc, DC_AX_FILTDATA, + CSR_WRITE_4(sc, DC_AX_FILTIDX, DC_AX_FILTIDX_PAR1); + CSR_WRITE_4(sc, DC_AX_FILTDATA, *(u_int32_t *)(&sc->arpcom.ac_enaddr[4])); /* If we want promiscuous mode, set the allframes bit. */ @@ -1116,6 +1128,78 @@ void dc_setfilt_asix(sc) return; } +void dc_setfilt_xircom(sc) + struct dc_softc *sc; +{ + struct dc_desc *sframe; + struct arpcom *ac = &sc->arpcom; + struct ether_multi *enm; + struct ether_multistep step; + u_int32_t h, *sp; + struct ifnet *ifp; + int i; + + ifp = &sc->arpcom.ac_if; + DC_CLRBIT(sc, DC_NETCFG, (DC_NETCFG_TX_ON|DC_NETCFG_RX_ON)); + + i = sc->dc_cdata.dc_tx_prod; + DC_INC(sc->dc_cdata.dc_tx_prod, DC_TX_LIST_CNT); + sc->dc_cdata.dc_tx_cnt++; + sframe = &sc->dc_ldata->dc_tx_list[i]; + sp = (u_int32_t *)&sc->dc_cdata.dc_sbuf; + bzero((char *)sp, DC_SFRAME_LEN); + + sframe->dc_data = vtophys(&sc->dc_cdata.dc_sbuf); + sframe->dc_ctl = DC_SFRAME_LEN | DC_TXCTL_SETUP | DC_TXCTL_TLINK | + DC_FILTER_HASHPERF | DC_TXCTL_FINT; + + sc->dc_cdata.dc_tx_chain[i] = (struct mbuf *)&sc->dc_cdata.dc_sbuf; + + /* If we want promiscuous mode, set the allframes bit. */ + if (ifp->if_flags & IFF_PROMISC) + DC_SETBIT(sc, DC_NETCFG, DC_NETCFG_RX_PROMISC); + else + DC_CLRBIT(sc, DC_NETCFG, DC_NETCFG_RX_PROMISC); + + if (ifp->if_flags & IFF_ALLMULTI) + DC_SETBIT(sc, DC_NETCFG, DC_NETCFG_RX_ALLMULTI); + else + DC_CLRBIT(sc, DC_NETCFG, DC_NETCFG_RX_ALLMULTI); + + /* now program new ones */ + ETHER_FIRST_MULTI(step, ac, enm); + while (enm != NULL) { + h = dc_crc_le(sc, enm->enm_addrlo); + sp[h >> 4] |= 1 << (h & 0xF); + ETHER_NEXT_MULTI(step, enm); + } + + if (ifp->if_flags & IFF_BROADCAST) { + h = dc_crc_le(sc, (caddr_t)ðerbroadcastaddr); + sp[h >> 4] |= 1 << (h & 0xF); + } + + /* Set our MAC address */ + sp[0] = ((u_int16_t *)sc->arpcom.ac_enaddr)[0]; + sp[1] = ((u_int16_t *)sc->arpcom.ac_enaddr)[1]; + sp[2] = ((u_int16_t *)sc->arpcom.ac_enaddr)[2]; + + DC_SETBIT(sc, DC_NETCFG, DC_NETCFG_TX_ON); + DC_SETBIT(sc, DC_NETCFG, DC_NETCFG_RX_ON); + ifp->if_flags |= IFF_RUNNING; + sframe->dc_status = DC_TXSTAT_OWN; + CSR_WRITE_4(sc, DC_TXSTART, 0xFFFFFFFF); + + /* + * wait some time... + */ + DELAY(1000); + + ifp->if_timer = 5; + + return; +} + void dc_setfilt(sc) struct dc_softc *sc; { @@ -1129,6 +1213,9 @@ void dc_setfilt(sc) if (DC_IS_ADMTEK(sc)) dc_setfilt_admtek(sc); + if (DC_IS_XIRCOM(sc)) + dc_setfilt_xircom(sc); + return; } @@ -1277,7 +1364,8 @@ void dc_reset(sc) break; } - if (DC_IS_ASIX(sc) || DC_IS_ADMTEK(sc)) { + if (DC_IS_ASIX(sc) || DC_IS_ADMTEK(sc) || DC_IS_XIRCOM(sc) || + DC_IS_INTEL(sc)) { DELAY(10000); DC_CLRBIT(sc, DC_BUSCTL, DC_BUSCTL_RESET); i = 0; @@ -1302,7 +1390,7 @@ void dc_reset(sc) if (DC_IS_INTEL(sc)) DC_SETBIT(sc, DC_SIARESET, DC_SIA_RESET); - return; + return; } /* @@ -1315,7 +1403,8 @@ void dc_attach_common(sc) struct ifnet *ifp; int error = 0, mac_offset; - dc_eeprom_width(sc); + if (!DC_IS_XIRCOM(sc)) + dc_eeprom_width(sc); /* * Get station address from the EEPROM. @@ -1344,6 +1433,8 @@ void dc_attach_common(sc) dc_read_eeprom(sc, (caddr_t)&sc->arpcom.ac_enaddr, DC_AL_EE_NODEADDR, 3, 0); break; + case DC_TYPE_XIRCOM: + break; default: dc_read_eeprom(sc, (caddr_t)&sc->arpcom.ac_enaddr, DC_EE_NODEADDR, 3, 0); @@ -1414,6 +1505,19 @@ void dc_attach_common(sc) goto fail; } + if (DC_IS_XIRCOM(sc)) { + /* + * setup General Purpose Port mode and data so the tulip + * can talk to the MII. + */ + CSR_WRITE_4(sc, DC_SIAGP, DC_SIAGP_WRITE_EN | DC_SIAGP_INT1_EN | + DC_SIAGP_MD_GP2_OUTPUT | DC_SIAGP_MD_GP0_OUTPUT); + DELAY(10); + CSR_WRITE_4(sc, DC_SIAGP, DC_SIAGP_INT1_EN | + DC_SIAGP_MD_GP2_OUTPUT | DC_SIAGP_MD_GP0_OUTPUT); + DELAY(10); + } + /* * Call MI attach routines. */ @@ -1700,9 +1804,9 @@ int dc_rx_resync(sc) void dc_rxeof(sc) struct dc_softc *sc; { - struct ether_header *eh; - struct mbuf *m; - struct ifnet *ifp; + struct ether_header *eh; + struct mbuf *m; + struct ifnet *ifp; struct dc_desc *cur_rx; int i, total_len = 0; u_int32_t rxstat; @@ -1850,11 +1954,23 @@ void dc_txeof(sc) continue; } - if (/*sc->dc_type == DC_TYPE_21143 &&*/ - sc->dc_pmode == DC_PMODE_MII && - ((txstat & 0xFFFF) & ~(DC_TXSTAT_ERRSUM| - DC_TXSTAT_NOCARRIER|DC_TXSTAT_CARRLOST))) - txstat &= ~DC_TXSTAT_ERRSUM; + if (DC_IS_XIRCOM(sc)) { + /* + * XXX: Why does my Xircom taunt me so? + * For some reason it likes setting the CARRLOST flag + * even when the carrier is there. wtf?! */ + if (/*sc->dc_type == DC_TYPE_21143 &&*/ + sc->dc_pmode == DC_PMODE_MII && + ((txstat & 0xFFFF) & ~(DC_TXSTAT_ERRSUM| + DC_TXSTAT_NOCARRIER))) + txstat &= ~DC_TXSTAT_ERRSUM; + } else { + if (/*sc->dc_type == DC_TYPE_21143 &&*/ + sc->dc_pmode == DC_PMODE_MII && + ((txstat & 0xFFFF) & ~(DC_TXSTAT_ERRSUM| + DC_TXSTAT_NOCARRIER|DC_TXSTAT_CARRLOST))) + txstat &= ~DC_TXSTAT_ERRSUM; + } if (txstat & DC_TXSTAT_ERRSUM) { ifp->if_oerrors++; @@ -1987,7 +2103,8 @@ int dc_intr(arg) /* Disable interrupts. */ CSR_WRITE_4(sc, DC_IMR, 0x00000000); - while((status = CSR_READ_4(sc, DC_ISR)) & DC_INTRS) { + while(((status = CSR_READ_4(sc, DC_ISR)) & DC_INTRS) && + status != 0xFFFFFFFF) { claimed = 1; @@ -2139,7 +2256,7 @@ int dc_coal(sc, m_head) struct dc_softc *sc; struct mbuf **m_head; { - struct mbuf *m_new, *m; + struct mbuf *m_new, *m; m = *m_head; MGETHDR(m_new, M_DONTWAIT, MT_DATA); @@ -2307,6 +2424,15 @@ void dc_init(xsc) DC_SETBIT(sc, DC_MX_MAGICPACKET, DC_MX_MAGIC_98715); } + if (DC_IS_XIRCOM(sc)) { + CSR_WRITE_4(sc, DC_SIAGP, DC_SIAGP_WRITE_EN | DC_SIAGP_INT1_EN | + DC_SIAGP_MD_GP2_OUTPUT | DC_SIAGP_MD_GP0_OUTPUT); + DELAY(10); + CSR_WRITE_4(sc, DC_SIAGP, DC_SIAGP_INT1_EN | + DC_SIAGP_MD_GP2_OUTPUT | DC_SIAGP_MD_GP0_OUTPUT); + DELAY(10); + } + DC_CLRBIT(sc, DC_NETCFG, DC_NETCFG_TX_THRESH); DC_SETBIT(sc, DC_NETCFG, DC_TXTHRESH_72BYTES); diff --git a/sys/dev/ic/dcreg.h b/sys/dev/ic/dcreg.h index 39582cbf1f8..8144a61afe4 100644 --- a/sys/dev/ic/dcreg.h +++ b/sys/dev/ic/dcreg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: dcreg.h,v 1.8 2000/09/13 00:29:35 aaron Exp $ */ +/* $OpenBSD: dcreg.h,v 1.9 2000/10/26 20:50:43 aaron Exp $ */ /* * Copyright (c) 1997, 1998, 1999 @@ -54,6 +54,7 @@ #define DC_SIARESET 0x68 /* SIA connectivity */ #define DC_10BTCTRL 0x70 /* SIA transmit and receive */ #define DC_WATCHDOG 0x78 /* SIA and general purpose port */ +#define DC_SIAGP 0x78 /* SIA and general purpose port (X3201) */ /* * There are two general 'types' of MX chips that we need to be @@ -77,6 +78,7 @@ #define DC_TYPE_DM9102 0x8 /* Davicom DM9102 */ #define DC_TYPE_PNICII 0x9 /* 82c115 PNIC II */ #define DC_TYPE_PNIC 0xA /* 82c168/82c169 PNIC I */ +#define DC_TYPE_XIRCOM 0xB /* Xircom X3201 */ #define DC_IS_MACRONIX(x) \ (x->dc_type == DC_TYPE_98713 || \ @@ -94,6 +96,7 @@ #define DC_IS_DAVICOM(x) (x->dc_type == DC_TYPE_DM9102) #define DC_IS_PNICII(x) (x->dc_type == DC_TYPE_PNICII) #define DC_IS_PNIC(x) (x->dc_type == DC_TYPE_PNIC) +#define DC_IS_XIRCOM(x) (x->dc_type == DC_TYPE_XIRCOM) /* MII/symbol mode port types */ #define DC_PMODE_MII 0x1 @@ -349,6 +352,25 @@ #define DC_WDOG_CTLWREN 0x08000000 /* + * SIA and General Purpose Port register (X3201) + */ +#define DC_SIAGP_RXMATCH 0x40000000 +#define DC_SIAGP_INT1 0x20000000 +#define DC_SIAGP_INT0 0x10000000 +#define DC_SIAGP_WRITE_EN 0x08000000 +#define DC_SIAGP_RXMATCH_EN 0x04000000 +#define DC_SIAGP_INT1_EN 0x02000000 +#define DC_SIAGP_INT0_EN 0x01000000 +#define DC_SIAGP_LED3 0x00800000 +#define DC_SIAGP_LED2 0x00400000 +#define DC_SIAGP_LED1 0x00200000 +#define DC_SIAGP_LED0 0x00100000 +#define DC_SIAGP_MD_GP3_OUTPUT 0x00080000 +#define DC_SIAGP_MD_GP2_OUTPUT 0x00040000 +#define DC_SIAGP_MD_GP1_OUTPUT 0x00020000 +#define DC_SIAGP_MD_GP0_OUTPUT 0x00010000 + +/* * Size of a setup frame. */ #define DC_SFRAME_LEN 192 |