diff options
author | Martin Reindl <martin@cvs.openbsd.org> | 2006-01-23 14:42:56 +0000 |
---|---|---|
committer | Martin Reindl <martin@cvs.openbsd.org> | 2006-01-23 14:42:56 +0000 |
commit | 7e90e3248d9ab8799ada46e4f632318798e109be (patch) | |
tree | 50af27776788516e17526a9ad923d1a0f646becf /sys/dev/ic | |
parent | bb8715953fa75bf442c55521686f8f0c7c1a0d2e (diff) |
update sm(4) from NetBSD, including support for more models and MII;
also activate ISA attachment;
ok brad@
Diffstat (limited to 'sys/dev/ic')
-rw-r--r-- | sys/dev/ic/smc91cxx.c | 363 | ||||
-rw-r--r-- | sys/dev/ic/smc91cxxreg.h | 14 | ||||
-rw-r--r-- | sys/dev/ic/smc91cxxvar.h | 19 |
3 files changed, 342 insertions, 54 deletions
diff --git a/sys/dev/ic/smc91cxx.c b/sys/dev/ic/smc91cxx.c index ac991e35036..9761b81b826 100644 --- a/sys/dev/ic/smc91cxx.c +++ b/sys/dev/ic/smc91cxx.c @@ -1,4 +1,4 @@ -/* $OpenBSD: smc91cxx.c,v 1.21 2005/06/08 17:03:00 henning Exp $ */ +/* $OpenBSD: smc91cxx.c,v 1.22 2006/01/23 14:42:55 martin Exp $ */ /* $NetBSD: smc91cxx.c,v 1.11 1998/08/08 23:51:41 mycroft Exp $ */ /*- @@ -86,6 +86,7 @@ #include <sys/syslog.h> #include <sys/socket.h> #include <sys/device.h> +#include <sys/kernel.h> #include <sys/malloc.h> #include <sys/ioctl.h> #include <sys/errno.h> @@ -112,9 +113,20 @@ #include <net/bpf.h> #endif +#include <dev/mii/mii.h> +#include <dev/mii/miivar.h> +#include <dev/mii/mii_bitbang.h> + #include <dev/ic/smc91cxxreg.h> #include <dev/ic/smc91cxxvar.h> +#ifndef __BUS_SPACE_HAS_STREAM_METHODS +#define bus_space_write_multi_stream_2 bus_space_write_multi_2 +#define bus_space_write_multi_stream_4 bus_space_write_multi_4 +#define bus_space_read_multi_stream_2 bus_space_read_multi_2 +#define bus_space_read_multi_stream_4 bus_space_read_multi_4 +#endif /* __BUS_SPACE_HAS_STREAM_METHODS */ + /* XXX Hardware padding doesn't work yet(?) */ #define SMC91CXX_SW_PAD @@ -123,11 +135,11 @@ const char *smc91cxx_idstrs[] = { NULL, /* 1 */ NULL, /* 2 */ "SMC91C90/91C92", /* 3 */ - "SMC91C94", /* 4 */ + "SMC91C94/91C96", /* 4 */ "SMC91C95", /* 5 */ NULL, /* 6 */ "SMC91C100", /* 7 */ - NULL, /* 8 */ + "SMC91C100FD", /* 8 */ NULL, /* 9 */ NULL, /* 10 */ NULL, /* 11 */ @@ -144,10 +156,34 @@ const int smc91cxx_media[] = { }; #define NSMC91CxxMEDIA (sizeof(smc91cxx_media) / sizeof(smc91cxx_media[0])) +/* + * MII bit-bang glue. + */ +u_int32_t smc91cxx_mii_bitbang_read(struct device *); +void smc91cxx_mii_bitbang_write(struct device *, u_int32_t); + +const struct mii_bitbang_ops smc91cxx_mii_bitbang_ops = { + smc91cxx_mii_bitbang_read, + smc91cxx_mii_bitbang_write, + { + MR_MDO, /* MII_BIT_MDO */ + MR_MDI, /* MII_BIT_MDI */ + MR_MCLK, /* MII_BIT_MDC */ + MR_MDOE, /* MII_BIT_DIR_HOST_PHY */ + 0, /* MII_BIT_DIR_PHY_HOST */ + } +}; + struct cfdriver sm_cd = { NULL, "sm", DV_IFNET }; +/* MII callbacks */ +int smc91cxx_mii_readreg(struct device *, int, int); +void smc91cxx_mii_writereg(struct device *, int, int, int); +void smc91cxx_statchg(struct device *); +void smc91cxx_tick(void *); + int smc91cxx_mediachange(struct ifnet *); void smc91cxx_mediastatus(struct ifnet *, struct ifmediareq *); @@ -160,9 +196,6 @@ void smc91cxx_resume(struct smc91cxx_softc *); void smc91cxx_watchdog(struct ifnet *); int smc91cxx_ioctl(struct ifnet *, u_long, caddr_t); -int smc91cxx_enable(struct smc91cxx_softc *); -void smc91cxx_disable(struct smc91cxx_softc *); - static __inline int ether_cmp(void *, void *); static __inline int ether_cmp(va, vb) @@ -183,25 +216,31 @@ smc91cxx_attach(sc, myea) struct ifnet *ifp = &sc->sc_arpcom.ac_if; bus_space_tag_t bst = sc->sc_bst; bus_space_handle_t bsh = sc->sc_bsh; + struct ifmedia *ifm = &sc->sc_mii.mii_media; + u_int32_t miicapabilities; u_int16_t tmp; int i, aui; -#ifdef SMC_DEBUG const char *idstr; -#endif /* Make sure the chip is stopped. */ smc91cxx_stop(sc); -#ifdef SMC_DEBUG SMC_SELECT_BANK(sc, 3); tmp = bus_space_read_2(bst, bsh, REVISION_REG_W); - idstr = smc91cxx_idstrs[RR_ID(tmp)]; - printf("%s: ", sc->sc_dev.dv_xname); + sc->sc_chipid = RR_ID(tmp); + /* check magic number */ + if ((tmp & BSR_DETECT_MASK) != BSR_DETECT_VALUE) { + idstr = NULL; + printf("%s: invalid BSR 0x%04x\n", sc->sc_dev.dv_xname, tmp); + } else + idstr = smc91cxx_idstrs[RR_ID(tmp)]; +#ifdef SMC_DEBUG + printf("\n%s: ", sc->sc_dev.dv_xname); if (idstr != NULL) printf("%s, ", idstr); else - printf("unknown chip id %d, ", RR_ID(tmp)); - printf("revision %d\n", RR_REV(tmp)); + printf("unknown chip id %d, ", sc->sc_chipid); + printf("revision %d", RR_REV(tmp)); #endif /* Read the station address from the chip. */ @@ -216,13 +255,7 @@ smc91cxx_attach(sc, myea) bcopy(myea, sc->sc_arpcom.ac_enaddr, ETHER_ADDR_LEN); } - printf(": address %s, ", - ether_sprintf(sc->sc_arpcom.ac_enaddr)); - - /* ..and default media. */ - tmp = bus_space_read_2(bst, bsh, CONFIG_REG_W); - printf("utp/aui (default %s)\n", (aui = (tmp & CR_AUI_SELECT)) ? - "aui" : "utp"); + printf(": address %s\n", ether_sprintf(sc->sc_arpcom.ac_enaddr)); /* Initialize the ifnet structure. */ bcopy(sc->sc_dev.dv_xname, ifp->if_xname, IFNAMSIZ); @@ -238,16 +271,67 @@ smc91cxx_attach(sc, myea) if_attach(ifp); ether_ifattach(ifp); - /* Initialize the media structures. */ - ifmedia_init(&sc->sc_media, 0, smc91cxx_mediachange, - smc91cxx_mediastatus); - for (i = 0; i < NSMC91CxxMEDIA; i++) - ifmedia_add(&sc->sc_media, smc91cxx_media[i], 0, NULL); - ifmedia_set(&sc->sc_media, IFM_ETHER | (aui ? IFM_10_5 : IFM_10_T)); + /* + * Initialize our media structures and MII info. We will + * probe the MII if we are on the SMC91Cxx + */ + sc->sc_mii.mii_ifp = ifp; + sc->sc_mii.mii_readreg = smc91cxx_mii_readreg; + sc->sc_mii.mii_writereg = smc91cxx_mii_writereg; + sc->sc_mii.mii_statchg = smc91cxx_statchg; + ifmedia_init(ifm, 0, smc91cxx_mediachange, smc91cxx_mediastatus); + + SMC_SELECT_BANK(sc, 1); + tmp = bus_space_read_2(bst, bsh, CONFIG_REG_W); + + miicapabilities = BMSR_MEDIAMASK|BMSR_ANEG; + switch (sc->sc_chipid) { + case CHIP_91100: + /* + * The 91100 does not have full-duplex capabilities, + * even if the PHY does. + */ + miicapabilities &= ~(BMSR_100TXFDX | BMSR_10TFDX); + case CHIP_91100FD: + if (tmp & CR_MII_SELECT) { +#ifdef SMC_DEBUG + printf("%s: default media MII\n", + sc->sc_dev.dv_xname); +#endif + mii_attach(&sc->sc_dev, &sc->sc_mii, 0xffffffff, + MII_PHY_ANY, MII_OFFSET_ANY, 0); + if (LIST_FIRST(&sc->sc_mii.mii_phys) == NULL) { + ifmedia_add(&sc->sc_mii.mii_media, + IFM_ETHER|IFM_NONE, 0, NULL); + ifmedia_set(&sc->sc_mii.mii_media, + IFM_ETHER|IFM_NONE); + } else { + ifmedia_set(&sc->sc_mii.mii_media, + IFM_ETHER|IFM_AUTO); + } + sc->sc_flags |= SMC_FLAGS_HAS_MII; + break; + } + /*FALLTHROUGH*/ + default: + aui = tmp & CR_AUI_SELECT; +#ifdef SMC_DEBUG + printf("%s: default media %s\n", sc->sc_dev.dv_xname, + aui ? "AUI" : "UTP"); +#endif + for (i = 0; i < NSMC91CxxMEDIA; i++) + ifmedia_add(ifm, smc91cxx_media[i], 0, NULL); + ifmedia_set(ifm, IFM_ETHER | (aui ? IFM_10_5 : IFM_10_T)); + break; + } #if NRND > 0 - rnd_attach_source(&sc->rnd_source, sc->sc_dev.dv_xname, RND_TYPE_NET); + rnd_attach_source(&sc->rnd_source, sc->sc_dev.dv_xname, + RND_TYPE_NET, 0); #endif + + /* The attach is successful. */ + sc->sc_flags |= SMC_FLAGS_ATTACHED; } /* @@ -259,7 +343,7 @@ smc91cxx_mediachange(ifp) { struct smc91cxx_softc *sc = ifp->if_softc; - return (smc91cxx_set_media(sc, sc->sc_media.ifm_media)); + return (smc91cxx_set_media(sc, sc->sc_mii.mii_media.ifm_media)); } int @@ -276,12 +360,15 @@ smc91cxx_set_media(sc, media) * When it is enabled later, smc91cxx_init() will properly set * up the media for us. */ - if (sc->sc_enabled == 0) + if ((sc->sc_flags & SMC_FLAGS_ENABLED) == 0) return (0); if (IFM_TYPE(media) != IFM_ETHER) return (EINVAL); + if (sc->sc_flags & SMC_FLAGS_HAS_MII) + return (mii_mediachg(&sc->sc_mii)); + switch (IFM_SUBTYPE(media)) { case IFM_10_T: case IFM_10_5: @@ -315,12 +402,22 @@ smc91cxx_mediastatus(ifp, ifmr) bus_space_handle_t bsh = sc->sc_bsh; u_int16_t tmp; - if (sc->sc_enabled == 0) { + if ((sc->sc_flags & SMC_FLAGS_ENABLED) == 0) { ifmr->ifm_active = IFM_ETHER | IFM_NONE; ifmr->ifm_status = 0; return; } + /* + * If we have MII, go ask the PHY what's going on. + */ + if (sc->sc_flags & SMC_FLAGS_HAS_MII) { + mii_pollstat(&sc->sc_mii); + ifmr->ifm_active = sc->sc_mii.mii_media_active; + ifmr->ifm_status = sc->sc_mii.mii_media_status; + return; + } + SMC_SELECT_BANK(sc, 1); tmp = bus_space_read_2(bst, bsh, CONFIG_REG_W); ifmr->ifm_active = @@ -387,7 +484,7 @@ smc91cxx_init(sc) /* * Set current media. */ - smc91cxx_set_media(sc, sc->sc_media.ifm_cur->ifm_media); + smc91cxx_set_media(sc, sc->sc_mii.mii_media.ifm_cur->ifm_media); /* * Set the receive filter. We want receive enable and auto @@ -432,6 +529,12 @@ smc91cxx_init(sc) ifp->if_flags |= IFF_RUNNING; ifp->if_flags &= ~IFF_OACTIVE; + if (sc->sc_flags & SMC_FLAGS_HAS_MII) { + /* Start the one second clock. */ + timeout_set(&sc->sc_mii_timeout, smc91cxx_tick, sc); + timeout_add(&sc->sc_mii_timeout, hz); + } + /* * Attempt to start any pending transmission. */ @@ -568,8 +671,9 @@ smc91cxx_start(ifp) */ for (top = m; m != NULL; m = m->m_next) { /* Words... */ - bus_space_write_multi_2(bst, bsh, DATA_REG_W, - mtod(m, u_int16_t *), m->m_len >> 1); + if (m->m_len > 1) + bus_space_write_multi_stream_2(bst, bsh, DATA_REG_W, + mtod(m, u_int16_t *), m->m_len >> 1); /* ...and the remaining byte, if any. */ if (m->m_len & 1) @@ -641,7 +745,8 @@ smc91cxx_intr(arg) u_int8_t mask, interrupts, status; u_int16_t packetno, tx_status, card_stats; - if (sc->sc_enabled == 0) + if ((sc->sc_flags & SMC_FLAGS_ENABLED) == 0 || + (sc->sc_dev.dv_flags & DVF_ACTIVE) == 0) return (0); SMC_SELECT_BANK(sc, 2); @@ -681,10 +786,11 @@ smc91cxx_intr(arg) if (status & IM_RCV_INT) { #if 1 /* DIAGNOSTIC */ packetno = bus_space_read_2(bst, bsh, FIFO_PORTS_REG_W); - if (packetno & FIFO_REMPTY) + if (packetno & FIFO_REMPTY) { printf("%s: receive interrupt on empty fifo\n", sc->sc_dev.dv_xname); - else + goto out; + } else #endif smc91cxx_read(sc); } @@ -805,6 +911,7 @@ smc91cxx_intr(arg) */ smc91cxx_start(ifp); +out: /* * Reenable the interrupts we wish to receive now that processing * is complete. @@ -876,9 +983,8 @@ smc91cxx_read(sc) MGETHDR(m, M_DONTWAIT, MT_DATA); if (m == NULL) goto out; - m->m_pkthdr.rcvif = ifp; - m->m_pkthdr.len = m->m_len = packetlen; + m->m_pkthdr.len = packetlen; /* * Always put the packet in a cluster. @@ -894,11 +1000,16 @@ smc91cxx_read(sc) } /* - * Pull the packet off the interface. + * Pull the packet off the interface. Make sure the payload + * is aligned. */ + m->m_data = (caddr_t) ALIGN(mtod(m, caddr_t) + + sizeof(struct ether_header)) - sizeof(struct ether_header); + data = mtod(m, u_int8_t *); - bus_space_read_multi_2(bst, bsh, DATA_REG_W, (u_int16_t *)data, - packetlen >> 1); + if (packetlen > 1) + bus_space_read_multi_stream_2(bst, bsh, DATA_REG_W, + (u_int16_t *)data, packetlen >> 1); if (packetlen & 1) { data += packetlen & ~1; *data = bus_space_read_1(bst, bsh, DATA_REG_B); @@ -988,7 +1099,7 @@ smc91cxx_ioctl(ifp, cmd, data) if ((error = smc91cxx_enable(sc)) != 0) break; smc91cxx_init(sc); - } else if (sc->sc_enabled) { + } else if ((ifp->if_flags & IFF_UP) != 0) { /* * Reset the interface to pick up changes in any * other flags that affect hardware registers. @@ -999,7 +1110,7 @@ smc91cxx_ioctl(ifp, cmd, data) case SIOCADDMULTI: case SIOCDELMULTI: - if (sc->sc_enabled == 0) { + if ((sc->sc_flags & SMC_FLAGS_ENABLED) == 0) { error = EIO; break; } @@ -1020,7 +1131,7 @@ smc91cxx_ioctl(ifp, cmd, data) case SIOCGIFMEDIA: case SIOCSIFMEDIA: - error = ifmedia_ioctl(ifp, ifr, &sc->sc_media, cmd); + error = ifmedia_ioctl(ifp, ifr, &sc->sc_mii.mii_media, cmd); break; default: @@ -1098,8 +1209,7 @@ int smc91cxx_enable(sc) struct smc91cxx_softc *sc; { - - if (sc->sc_enabled == 0 && sc->sc_enable != NULL) { + if ((sc->sc_flags & SMC_FLAGS_ENABLED) == 0 && sc->sc_enable != NULL) { if ((*sc->sc_enable)(sc) != 0) { printf("%s: device enable failed\n", sc->sc_dev.dv_xname); @@ -1107,7 +1217,7 @@ smc91cxx_enable(sc) } } - sc->sc_enabled = 1; + sc->sc_flags |= SMC_FLAGS_ENABLED; return (0); } @@ -1118,9 +1228,162 @@ void smc91cxx_disable(sc) struct smc91cxx_softc *sc; { - - if (sc->sc_enabled != 0 && sc->sc_disable != NULL) { + if ((sc->sc_flags & SMC_FLAGS_ENABLED) != 0 && sc->sc_disable != NULL) { (*sc->sc_disable)(sc); - sc->sc_enabled = 0; + sc->sc_flags &= ~SMC_FLAGS_ENABLED; } } + +int +smc91cxx_activate(self, act) + struct device *self; + enum devact act; +{ +#if 0 + struct smc91cxx_softc *sc = (struct smc91cxx_softc *)self; +#endif + int rv = 0, s; + + s = splnet(); + switch (act) { + case DVACT_ACTIVATE: + rv = EOPNOTSUPP; + break; + + case DVACT_DEACTIVATE: +#if 0 + if_deactivate(&sc->sc_ic.ic_if); +#endif + break; + } + splx(s); + return(rv); +} + +int +smc91cxx_detach(self, flags) + struct device *self; + int flags; +{ + struct smc91cxx_softc *sc = (struct smc91cxx_softc *)self; + struct ifnet *ifp = &sc->sc_arpcom.ac_if; + + /* Succeed now if there's no work to do. */ + if ((sc->sc_flags & SMC_FLAGS_ATTACHED) == 0) + return(0); + + /* smc91cxx_disable() checks SMC_FLAGS_ENABLED */ + smc91cxx_disable(sc); + + /* smc91cxx_attach() never fails */ + + /* Delete all media. */ + ifmedia_delete_instance(&sc->sc_mii.mii_media, IFM_INST_ANY); + +#if NRND > 0 + rnd_detach_source(&sc->rnd_source); +#endif +#if NBPFILTER > 0 + bpfdetach(ifp); +#endif + ether_ifdetach(ifp); + if_detach(ifp); + + return (0); +} + +u_int32_t +smc91cxx_mii_bitbang_read(self) + struct device *self; +{ + struct smc91cxx_softc *sc = (void *) self; + + /* We're already in bank 3. */ + return (bus_space_read_2(sc->sc_bst, sc->sc_bsh, MGMT_REG_W)); +} + +void +smc91cxx_mii_bitbang_write(self, val) + struct device *self; + u_int32_t val; +{ + struct smc91cxx_softc *sc = (void *) self; + + /* We're already in bank 3. */ + bus_space_write_2(sc->sc_bst, sc->sc_bsh, MGMT_REG_W, val); +} + +int +smc91cxx_mii_readreg(self, phy, reg) + struct device *self; + int phy, reg; +{ + struct smc91cxx_softc *sc = (void *) self; + int val; + + SMC_SELECT_BANK(sc, 3); + + val = mii_bitbang_readreg(self, &smc91cxx_mii_bitbang_ops, phy, reg); + + SMC_SELECT_BANK(sc, 2); + + return (val); +} + +void +smc91cxx_mii_writereg(self, phy, reg, val) + struct device *self; + int phy, reg, val; +{ + struct smc91cxx_softc *sc = (void *) self; + + SMC_SELECT_BANK(sc, 3); + + mii_bitbang_writereg(self, &smc91cxx_mii_bitbang_ops, phy, reg, val); + + SMC_SELECT_BANK(sc, 2); +} + +void +smc91cxx_statchg(self) + struct device *self; +{ + struct smc91cxx_softc *sc = (struct smc91cxx_softc *)self; + bus_space_tag_t bst = sc->sc_bst; + bus_space_handle_t bsh = sc->sc_bsh; + int mctl; + + SMC_SELECT_BANK(sc, 0); + mctl = bus_space_read_2(bst, bsh, TXMIT_CONTROL_REG_W); + if (sc->sc_mii.mii_media_active & IFM_FDX) + mctl |= TCR_SWFDUP; + else + mctl &= ~TCR_SWFDUP; + bus_space_write_2(bst, bsh, TXMIT_CONTROL_REG_W, mctl); + SMC_SELECT_BANK(sc, 2); /* back to operating window */ +} + +/* + * One second timer, used to tick the MII. + */ +void +smc91cxx_tick(arg) + void *arg; +{ + struct smc91cxx_softc *sc = arg; + int s; + +#ifdef DIAGNOSTIC + if ((sc->sc_flags & SMC_FLAGS_HAS_MII) == 0) + panic("smc91cxx_tick"); +#endif + + if ((sc->sc_dev.dv_flags & DVF_ACTIVE) == 0) + return; + + s = splnet(); + mii_tick(&sc->sc_mii); + splx(s); + + timeout_add(&sc->sc_mii_timeout, hz); +} diff --git a/sys/dev/ic/smc91cxxreg.h b/sys/dev/ic/smc91cxxreg.h index 545f6873d94..5714ee5fcb2 100644 --- a/sys/dev/ic/smc91cxxreg.h +++ b/sys/dev/ic/smc91cxxreg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: smc91cxxreg.h,v 1.2 2001/06/27 05:44:52 nate Exp $ */ +/* $OpenBSD: smc91cxxreg.h,v 1.3 2006/01/23 14:42:55 martin Exp $ */ /* $NetBSD: smc91cxxreg.h,v 1.2 1997/09/02 00:10:58 thorpej Exp $ */ /* @@ -109,6 +109,7 @@ #define TCR_FDUPLX 0x0800 /* receive packets sent out */ #define TCR_STP_SQET 0x1000 /* stop transmitting if Signal quality error */ #define TCR_EPH_LOOP 0x2000 /* Enable internal digital loopback */ +#define TCR_SWFDUP 0x8000 /* FEAST: Switched full-duplex (only w/ MII) */ /* @@ -179,6 +180,7 @@ */ #define MEM_CFG_REG_W 0x0a +#define MCR_MEM_MULT(x) (((x)>>9)&7) /* Memory size multiplier */ #define MCR_TXRSV_MASK 0x001f /* Count of pages reserved for transmit */ @@ -204,6 +206,7 @@ #define CR_SET_SQLCH 0x0200 /* Squelch level */ #define CR_FULL_STEP 0x0400 /* AUI signalling mode */ #define CR_NOW_WAIT_ST 0x1000 /* Disable bus wait states */ +#define CR_MII_SELECT 0x8000 /* FEAST: MII port selected */ /* @@ -367,10 +370,18 @@ /* * These registers do not exist on SMC9192, or at least * are not documented in the SMC91C92 data sheet. + * * The REVISION_REG_W register does however seem to work. + * + * On the FEAST, the low nibble controls the MII interface. */ #define MGMT_REG_W 0x08 +#define MR_MDOE 0x08 +#define MR_MCLK 0x04 +#define MR_MDI 0x02 +#define MR_MDO 0x01 + #define REVISION_REG_W 0x0a /* (hi: chip id low: rev #) */ #define RR_REV(x) ((x) & 0x0f) #define RR_ID(x) (((x) >> 4) & 0x0f) @@ -385,6 +396,7 @@ #define CHIP_9194 4 #define CHIP_9195 5 #define CHIP_91100 7 +#define CHIP_91100FD 8 /* diff --git a/sys/dev/ic/smc91cxxvar.h b/sys/dev/ic/smc91cxxvar.h index 58ae97c2f3c..13294ad5509 100644 --- a/sys/dev/ic/smc91cxxvar.h +++ b/sys/dev/ic/smc91cxxvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: smc91cxxvar.h,v 1.4 2002/03/14 01:26:55 millert Exp $ */ +/* $OpenBSD: smc91cxxvar.h,v 1.5 2006/01/23 14:42:55 martin Exp $ */ /* $NetBSD: smc91cxxvar.h,v 1.4 1997/10/15 05:56:13 explorer Exp $ */ /*- @@ -49,15 +49,24 @@ struct smc91cxx_softc { #endif struct arpcom sc_arpcom; /* ethernet common glue */ + struct mii_data sc_mii; /* MII/media control */ + struct timeout sc_mii_timeout; /* MII callout handle */ + bus_space_tag_t sc_bst; /* bus space */ bus_space_handle_t sc_bsh; - struct ifmedia sc_media; /* our media info */ - /* Power management hooks and state. */ int (*sc_enable)(struct smc91cxx_softc *); void (*sc_disable)(struct smc91cxx_softc *); int sc_enabled; + u_int32_t sc_flags; /* misc. flags*/ +#define SMC_FLAGS_ENABLED 0x0001 +#define SMC_FLAGS_ATTACHED 0x0002 /* attach was successful */ +#define SMC_FLAGS_HAS_MII 0x0004 /* Has MII (FEAST) */ +#define SMC_FLAGS_32BIT_READ 0x0008 /* reads are always 32-bits */ + + u_int8_t sc_chipid; + u_int8_t sc_internal_phy; /* 91C111 only */ #if NRND > 0 rndsource_element_t rnd_source; @@ -72,3 +81,7 @@ void smc91cxx_attach(struct smc91cxx_softc *, u_int8_t *); int smc91cxx_intr(void *); void smc91cxx_init(struct smc91cxx_softc *); void smc91cxx_stop(struct smc91cxx_softc *); +int smc91cxx_enable(struct smc91cxx_softc *); +void smc91cxx_disable(struct smc91cxx_softc *); +int smc91cxx_activate(struct device *, enum devact); +int smc91cxx_detach(struct device *, int); |