diff options
| author | pk <pk@NetBSD.org> | 1999-12-20 22:23:39 +0000 |
|---|---|---|
| committer | pk <pk@NetBSD.org> | 1999-12-20 22:23:39 +0000 |
| commit | bbbbfe896e31841296de6caf3a893acf12e831d1 (patch) | |
| tree | cb4029eed1fb28f4f8b96b40f121d8b1a2e4b2e3 /sys/dev | |
| parent | d135edf1a70eceeae96373d7df928263a645ecc5 (diff) | |
* Remove spurious blockade in the path to get the transceiver status word.
* Make sure to flip the 10baseT/100baseTX bit when doing autoselect.
* Miscellaneous cosmetics.
Diffstat (limited to 'sys/dev')
| -rw-r--r-- | sys/dev/sbus/be.c | 142 |
1 files changed, 61 insertions, 81 deletions
diff --git a/sys/dev/sbus/be.c b/sys/dev/sbus/be.c index fde9ee06a9f..7699a7742e5 100644 --- a/sys/dev/sbus/be.c +++ b/sys/dev/sbus/be.c @@ -1,4 +1,4 @@ -/* $NetBSD: be.c,v 1.9 1999/11/21 15:01:50 pk Exp $ */ +/* $NetBSD: be.c,v 1.10 1999/12/20 22:23:39 pk Exp $ */ /*- * Copyright (c) 1999 The NetBSD Foundation, Inc. @@ -183,7 +183,7 @@ void be_mcreset __P((struct be_softc *)); /* MII methods & callbacks */ static int be_mii_readreg __P((struct device *, int, int)); static void be_mii_writereg __P((struct device *, int, int, int)); -static void be_statchg __P((struct device *)); +static void be_mii_statchg __P((struct device *)); /* MII helpers */ static void be_mii_sync __P((struct be_softc *)); @@ -328,33 +328,14 @@ beattach(parent, self, aux) mii->mii_ifp = ifp; mii->mii_readreg = be_mii_readreg; mii->mii_writereg = be_mii_writereg; - mii->mii_statchg = be_statchg; + mii->mii_statchg = be_mii_statchg; ifmedia_init(&mii->mii_media, 0, be_ifmedia_upd, be_ifmedia_sts); if ((sc->sc_conf & BE_CONF_MII) != 0) { -#if 1 - mii_phy_probe(&sc->sc_dev, mii, 0xffffffff, MII_PHY_ANY, + + mii_phy_probe(&sc->sc_dev, mii, 0xffffffff, BE_PHY_EXTERNAL, MII_OFFSET_ANY); -#else - /* TEST */ - extern int mii_print __P((void *, const char *)); - struct mii_attach_args ma; - struct mii_softc *child; - - bzero(&ma, sizeof(ma)); - ma.mii_phyno = BE_PHY_INTERNAL; - ma.mii_data = mii; - ma.mii_capmask = 0xffffffff; - if ((child = (struct mii_softc *) - config_found(&sc->sc_dev, &ma, mii_print)) != NULL) { - /* - * Link it up in the parent's MII data. - */ - LIST_INSERT_HEAD(&mii->mii_phys, child, mii_list); - mii->mii_instance++; - } -#endif if (LIST_FIRST(&sc->sc_mii.mii_phys) == NULL) { /* No PHY attached */ @@ -1199,7 +1180,7 @@ be_mii_sync(sc) { bus_space_tag_t t = sc->sc_bustag; bus_space_handle_t tr = sc->sc_tr; - int n = 20; + int n = 32; while (n--) { bus_space_write_4(t, tr, BE_TRI_MGMTPAL, @@ -1252,24 +1233,14 @@ be_tcvr_init(sc) bitmask_snprintf(v, MGMT_PAL_BITS, bits, sizeof(bits))); } #endif -{ - char bits[64]; - printf("be_tcvr_init: MGMTPAL=%s\n", - bitmask_snprintf(v, MGMT_PAL_BITS, bits, sizeof(bits))); - if ((v & MGMT_PAL_EXT_MDIO) != 0) { - printf("EXTERNAL\n"); - } -} + if ((v & MGMT_PAL_EXT_MDIO) != 0) { sc->sc_conf |= BE_CONF_MII; - /*sc->sc_tcvr_type = BE_TCVR_EXTERNAL;*/ bus_space_write_4(t, tr, BE_TRI_TCVRPAL, ~(TCVR_PAL_EXTLBACK | TCVR_PAL_MSENSE | TCVR_PAL_LTENABLE)); - (void)bus_space_read_4(t, tr, BE_TRI_TCVRPAL); } else if ((v & MGMT_PAL_INT_MDIO) != 0) { - /*sc->sc_tcvr_type = BE_TCVR_INTERNAL;*/ bus_space_write_4(t, tr, BE_TRI_TCVRPAL, ~(TCVR_PAL_EXTLBACK | TCVR_PAL_MSENSE | TCVR_PAL_LTENABLE | TCVR_PAL_SERIAL)); @@ -1281,7 +1252,7 @@ be_tcvr_init(sc) } -static __inline__ int +static int be_tcvr_read_bit(sc, phy) struct be_softc *sc; int phy; @@ -1296,15 +1267,13 @@ be_tcvr_read_bit(sc, phy) bus_space_write_4(t, tr, BE_TRI_MGMTPAL, MGMT_PAL_EXT_MDIO | MGMT_PAL_DCLOCK); (void)bus_space_read_4(t, tr, BE_TRI_MGMTPAL); - DELAY(20); ret = (bus_space_read_4(t, tr, BE_TRI_MGMTPAL) & - MGMT_PAL_INT_MDIO) >> 3; + MGMT_PAL_INT_MDIO) >> MGMT_PAL_INT_MDIO_SHIFT; } else { bus_space_write_4(t, tr, BE_TRI_MGMTPAL, MGMT_PAL_INT_MDIO); (void)bus_space_read_4(t, tr, BE_TRI_MGMTPAL); - DELAY(20); ret = (bus_space_read_4(t, tr, BE_TRI_MGMTPAL) & - MGMT_PAL_EXT_MDIO) >> 2; + MGMT_PAL_EXT_MDIO) >> MGMT_PAL_EXT_MDIO_SHIFT; bus_space_write_4(t, tr, BE_TRI_MGMTPAL, MGMT_PAL_INT_MDIO | MGMT_PAL_DCLOCK); (void)bus_space_read_4(t, tr, BE_TRI_MGMTPAL); @@ -1313,7 +1282,7 @@ be_tcvr_read_bit(sc, phy) return (ret); } -static __inline__ void +static void be_tcvr_write_bit(sc, phy, bit) struct be_softc *sc; int phy; @@ -1321,24 +1290,27 @@ be_tcvr_write_bit(sc, phy, bit) { bus_space_tag_t t = sc->sc_bustag; bus_space_handle_t tr = sc->sc_tr; + u_int32_t v; if (phy == BE_PHY_INTERNAL) { - bit = ((bit & 1) << 3) | MGMT_PAL_OENAB | MGMT_PAL_EXT_MDIO; - bus_space_write_4(t, tr, BE_TRI_MGMTPAL, bit); + v = ((bit & 1) << MGMT_PAL_INT_MDIO_SHIFT) | + MGMT_PAL_OENAB | MGMT_PAL_EXT_MDIO; + bus_space_write_4(t, tr, BE_TRI_MGMTPAL, v); (void)bus_space_read_4(t, tr, BE_TRI_MGMTPAL); bus_space_write_4(t, tr, BE_TRI_MGMTPAL, bit | MGMT_PAL_DCLOCK); (void)bus_space_read_4(t, tr, BE_TRI_MGMTPAL); } else { - bit = ((bit & 1) << 2) | MGMT_PAL_OENAB | MGMT_PAL_INT_MDIO; - bus_space_write_4(t, tr, BE_TRI_MGMTPAL, bit); + v = ((bit & 1) << MGMT_PAL_EXT_MDIO_SHIFT) + | MGMT_PAL_OENAB | MGMT_PAL_INT_MDIO; + bus_space_write_4(t, tr, BE_TRI_MGMTPAL, v); (void)bus_space_read_4(t, tr, BE_TRI_MGMTPAL); - bus_space_write_4(t, tr, BE_TRI_MGMTPAL, bit | MGMT_PAL_DCLOCK); + bus_space_write_4(t, tr, BE_TRI_MGMTPAL, v | MGMT_PAL_DCLOCK); (void)bus_space_read_4(t, tr, BE_TRI_MGMTPAL); } } -static __inline__ void +static void be_mii_sendbits(sc, phy, data, nbits) struct be_softc *sc; int phy; @@ -1360,10 +1332,6 @@ be_mii_readreg(self, phy, reg) struct be_softc *sc = (struct be_softc *)self; int val = 0, i; - /* The `be' internal PHY is not treated as an MII device */ - if (phy == BE_PHY_INTERNAL) - return (0); - /* * Read the PHY register by manually driving the MII control lines. */ @@ -1435,12 +1403,24 @@ be_mii_reset(sc, phy) } void -be_statchg(self) +be_mii_statchg(self) struct device *self; { struct be_softc *sc = (struct be_softc *)self; + bus_space_tag_t t = sc->sc_bustag; + bus_space_handle_t br = sc->sc_br; + u_int32_t v; - printf("be_statchg: media_active=%x\n", sc->sc_mii.mii_media_active); + printf("%s: media_active=%x\n", + self->dv_xname, sc->sc_mii.mii_media_active); + + /* Update duplex mode in TX configuration */ + v = bus_space_read_4(t, br, BE_BRI_TXCFG); + if ((IFM_OPTIONS(sc->sc_mii.mii_media_active) & IFM_FDX) != 0) + v |= BE_BR_TXCFG_FULLDPLX; + else + v &= ~BE_BR_TXCFG_FULLDPLX; + bus_space_write_4(t, br, BE_BRI_TXCFG, v); } void @@ -1465,6 +1445,7 @@ be_internal_phy_auto(sc) { struct ifnet *ifp = &sc->sc_ethercom.ec_if; int bmcr, bmsr; + int bmcr_s100_bit; /* * Check link status; if we don't have a link, try another @@ -1489,9 +1470,16 @@ be_internal_phy_auto(sc) return; } + /* Note current fast speed bit */ + bmcr = be_mii_readreg((struct device *)sc, BE_PHY_INTERNAL, MII_BMCR); + bmcr_s100_bit = bmcr & BMCR_S100; + + if (be_mii_reset(sc, BE_PHY_INTERNAL) != 0) + return; + bmcr = be_mii_readreg((struct device *)sc, BE_PHY_INTERNAL, MII_BMCR); /* Just flip the fast speed bit */ - bmcr ^= BMCR_S100; + bmcr ^= bmcr_s100_bit; be_mii_writereg((struct device *)sc, BE_PHY_INTERNAL, MII_BMCR, bmcr); } @@ -1504,6 +1492,7 @@ be_ifmedia_sts(ifp, ifmr) struct ifmediareq *ifmr; { struct be_softc *sc = ifp->if_softc; + int media_active, media_status; int bmcr, bmsr; if ((sc->sc_conf & BE_CONF_MII) != 0) { @@ -1513,6 +1502,9 @@ be_ifmedia_sts(ifp, ifmr) return; } + media_status = IFM_AVALID; + media_active = 0; + /* * Internal transceiver; do the work here. */ @@ -1520,16 +1512,16 @@ be_ifmedia_sts(ifp, ifmr) switch (bmcr & (BMCR_S100 | BMCR_FDX)) { case (BMCR_S100 | BMCR_FDX): - ifmr->ifm_active = IFM_ETHER | IFM_100_TX | IFM_FDX; + media_active = IFM_ETHER | IFM_100_TX | IFM_FDX; break; case BMCR_S100: - ifmr->ifm_active = IFM_ETHER | IFM_100_TX | IFM_HDX; + media_active = IFM_ETHER | IFM_100_TX | IFM_HDX; break; case BMCR_FDX: - ifmr->ifm_active = IFM_ETHER | IFM_10_T | IFM_FDX; + media_active = IFM_ETHER | IFM_10_T | IFM_FDX; break; case 0: - ifmr->ifm_active = IFM_ETHER | IFM_10_T | IFM_HDX; + media_active = IFM_ETHER | IFM_10_T | IFM_HDX; break; } @@ -1537,11 +1529,10 @@ be_ifmedia_sts(ifp, ifmr) bmsr = be_mii_readreg((struct device *)sc, BE_PHY_INTERNAL, MII_BMSR)| be_mii_readreg((struct device *)sc, BE_PHY_INTERNAL, MII_BMSR); if (bmsr & BMSR_LINK) - ifmr->ifm_status |= IFM_AVALID | IFM_ACTIVE; - else { - ifmr->ifm_status |= IFM_AVALID; - ifmr->ifm_status &= ~IFM_ACTIVE; - } + ifmr->ifm_status |= IFM_ACTIVE; + + ifmr->ifm_status = media_status; + ifmr->ifm_active = media_active; } /* @@ -1556,33 +1547,22 @@ be_ifmedia_upd(ifp) int newmedia = ifm->ifm_media; int n, error, phy, bmcr; char *speed, *mode; + bus_space_tag_t t; + bus_space_handle_t br; u_int32_t v; - bus_space_tag_t t = sc->sc_bustag; - bus_space_handle_t br = sc->sc_br; if (IFM_TYPE(newmedia) != IFM_ETHER) return (EINVAL); - if ((sc->sc_conf & BE_CONF_MII) != 0) { - int error; - - if ((error = mii_mediachg(&sc->sc_mii)) != 0) - return (error); - - v = bus_space_read_4(t, br, BE_BRI_TXCFG); - if ((IFM_OPTIONS(sc->sc_mii.mii_media_active) & IFM_FDX) != 0) - v |= BE_BR_TXCFG_FULLDPLX; - else - v &= ~BE_BR_TXCFG_FULLDPLX; - bus_space_write_4(t, br, BE_BRI_TXCFG, v); - - return (0); - } + if ((sc->sc_conf & BE_CONF_MII) != 0) + return (mii_mediachg(&sc->sc_mii)); /* * The rest of this routine is devoted to the * not-quite-a-phy internal transceiver case. */ + t = sc->sc_bustag; + br = sc->sc_br; phy = BE_PHY_INTERNAL; /* Why must we reset the device? */ |
