Index: dev/age/if_age.c =================================================================== --- dev/age/if_age.c (revision 215249) +++ dev/age/if_age.c (working copy) @@ -619,7 +619,7 @@ age_attach(device_t dev) /* Set up MII bus. */ error = mii_attach(dev, &sc->age_miibus, ifp, age_mediachange, age_mediastatus, BMSR_DEFCAPMASK, sc->age_phyaddr, MII_OFFSET_ANY, - 0); + MIIF_DOPAUSE); if (error != 0) { device_printf(dev, "attaching PHYs failed\n"); goto fail; @@ -1939,12 +1939,10 @@ age_mac_config(struct age_softc *sc) } if ((IFM_OPTIONS(mii->mii_media_active) & IFM_FDX) != 0) { reg |= MAC_CFG_FULL_DUPLEX; -#ifdef notyet if ((IFM_OPTIONS(mii->mii_media_active) & IFM_ETH_TXPAUSE) != 0) reg |= MAC_CFG_TX_FC; if ((IFM_OPTIONS(mii->mii_media_active) & IFM_ETH_RXPAUSE) != 0) reg |= MAC_CFG_RX_FC; -#endif } CSR_WRITE_4(sc, AGE_MAC_CFG, reg); Index: dev/alc/if_alc.c =================================================================== --- dev/alc/if_alc.c (revision 215249) +++ dev/alc/if_alc.c (working copy) @@ -974,7 +974,7 @@ alc_attach(device_t dev) /* Set up MII bus. */ error = mii_attach(dev, &sc->alc_miibus, ifp, alc_mediachange, alc_mediastatus, BMSR_DEFCAPMASK, sc->alc_phyaddr, MII_OFFSET_ANY, - 0); + MIIF_DOPAUSE); if (error != 0) { device_printf(dev, "attaching PHYs failed\n"); goto fail; @@ -2475,12 +2475,10 @@ alc_mac_config(struct alc_softc *sc) } if ((IFM_OPTIONS(mii->mii_media_active) & IFM_FDX) != 0) { reg |= MAC_CFG_FULL_DUPLEX; -#ifdef notyet if ((IFM_OPTIONS(mii->mii_media_active) & IFM_ETH_TXPAUSE) != 0) reg |= MAC_CFG_TX_FC; if ((IFM_OPTIONS(mii->mii_media_active) & IFM_ETH_RXPAUSE) != 0) reg |= MAC_CFG_RX_FC; -#endif } CSR_WRITE_4(sc, ALC_MAC_CFG, reg); } Index: dev/ale/if_ale.c =================================================================== --- dev/ale/if_ale.c (revision 215249) +++ dev/ale/if_ale.c (working copy) @@ -601,7 +601,7 @@ ale_attach(device_t dev) /* Set up MII bus. */ error = mii_attach(dev, &sc->ale_miibus, ifp, ale_mediachange, ale_mediastatus, BMSR_DEFCAPMASK, sc->ale_phyaddr, MII_OFFSET_ANY, - 0); + MIIF_DOPAUSE); if (error != 0) { device_printf(dev, "attaching PHYs failed\n"); goto fail; @@ -2071,12 +2071,10 @@ ale_mac_config(struct ale_softc *sc) } if ((IFM_OPTIONS(mii->mii_media_active) & IFM_FDX) != 0) { reg |= MAC_CFG_FULL_DUPLEX; -#ifdef notyet if ((IFM_OPTIONS(mii->mii_media_active) & IFM_ETH_TXPAUSE) != 0) reg |= MAC_CFG_TX_FC; if ((IFM_OPTIONS(mii->mii_media_active) & IFM_ETH_RXPAUSE) != 0) reg |= MAC_CFG_RX_FC; -#endif } CSR_WRITE_4(sc, ALE_MAC_CFG, reg); } Index: dev/cas/if_cas.c =================================================================== --- dev/cas/if_cas.c (revision 215249) +++ dev/cas/if_cas.c (working copy) @@ -346,7 +346,7 @@ cas_attach(struct cas_softc *sc) } error = mii_attach(sc->sc_dev, &sc->sc_miibus, ifp, cas_mediachange, cas_mediastatus, BMSR_DEFCAPMASK, - MII_PHY_ANY, MII_OFFSET_ANY, 0); + MII_PHY_ANY, MII_OFFSET_ANY, MIIF_DOPAUSE); } /* * Fall back on an internal PHY if no external PHY was found. @@ -366,7 +366,7 @@ cas_attach(struct cas_softc *sc) } error = mii_attach(sc->sc_dev, &sc->sc_miibus, ifp, cas_mediachange, cas_mediastatus, BMSR_DEFCAPMASK, - MII_PHY_ANY, MII_OFFSET_ANY, 0); + MII_PHY_ANY, MII_OFFSET_ANY, MIIF_DOPAUSE); } } else { /* @@ -388,7 +388,7 @@ cas_attach(struct cas_softc *sc) BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); error = mii_attach(sc->sc_dev, &sc->sc_miibus, ifp, cas_mediachange, cas_mediastatus, BMSR_DEFCAPMASK, - CAS_PHYAD_EXTERNAL, MII_OFFSET_ANY, 0); + CAS_PHYAD_EXTERNAL, MII_OFFSET_ANY, MIIF_DOPAUSE); } if (error != 0) { device_printf(sc->sc_dev, "attaching PHYs failed\n"); @@ -2356,14 +2356,12 @@ cas_mii_statchg(device_t dev) v = CAS_READ_4(sc, CAS_MAC_CTRL_CONF) & ~(CAS_MAC_CTRL_CONF_TXP | CAS_MAC_CTRL_CONF_RXP); -#ifdef notyet if ((IFM_OPTIONS(sc->sc_mii->mii_media_active) & IFM_ETH_RXPAUSE) != 0) v |= CAS_MAC_CTRL_CONF_RXP; if ((IFM_OPTIONS(sc->sc_mii->mii_media_active) & IFM_ETH_TXPAUSE) != 0) v |= CAS_MAC_CTRL_CONF_TXP; -#endif CAS_WRITE_4(sc, CAS_MAC_CTRL_CONF, v); /* Index: dev/gem/if_gem.c =================================================================== --- dev/gem/if_gem.c (revision 215249) +++ dev/gem/if_gem.c (working copy) @@ -302,7 +302,7 @@ gem_attach(struct gem_softc *sc) } error = mii_attach(sc->sc_dev, &sc->sc_miibus, ifp, gem_mediachange, gem_mediastatus, BMSR_DEFCAPMASK, phy, - MII_OFFSET_ANY, 0); + MII_OFFSET_ANY, MIIF_DOPAUSE); } /* @@ -330,7 +330,7 @@ gem_attach(struct gem_softc *sc) } error = mii_attach(sc->sc_dev, &sc->sc_miibus, ifp, gem_mediachange, gem_mediastatus, BMSR_DEFCAPMASK, phy, - MII_OFFSET_ANY, 0); + MII_OFFSET_ANY, MIIF_DOPAUSE); } /* @@ -352,7 +352,7 @@ gem_attach(struct gem_softc *sc) sc->sc_flags |= GEM_SERDES; error = mii_attach(sc->sc_dev, &sc->sc_miibus, ifp, gem_mediachange, gem_mediastatus, BMSR_DEFCAPMASK, - GEM_PHYAD_EXTERNAL, MII_OFFSET_ANY, 0); + GEM_PHYAD_EXTERNAL, MII_OFFSET_ANY, MIIF_DOPAUSE); } if (error != 0) { device_printf(sc->sc_dev, "attaching PHYs failed\n"); @@ -2039,14 +2039,12 @@ gem_mii_statchg(device_t dev) v = GEM_BANK1_READ_4(sc, GEM_MAC_CONTROL_CONFIG) & ~(GEM_MAC_CC_RX_PAUSE | GEM_MAC_CC_TX_PAUSE); -#ifdef notyet if ((IFM_OPTIONS(sc->sc_mii->mii_media_active) & IFM_ETH_RXPAUSE) != 0) v |= GEM_MAC_CC_RX_PAUSE; if ((IFM_OPTIONS(sc->sc_mii->mii_media_active) & IFM_ETH_TXPAUSE) != 0) v |= GEM_MAC_CC_TX_PAUSE; -#endif GEM_BANK1_WRITE_4(sc, GEM_MAC_CONTROL_CONFIG, v); if ((IFM_OPTIONS(sc->sc_mii->mii_media_active) & IFM_FDX) == 0 && Index: dev/jme/if_jme.c =================================================================== --- dev/jme/if_jme.c (revision 215249) +++ dev/jme/if_jme.c (working copy) @@ -735,7 +735,7 @@ jme_attach(device_t dev) /* Set up MII bus. */ error = mii_attach(dev, &sc->jme_miibus, ifp, jme_mediachange, jme_mediastatus, BMSR_DEFCAPMASK, sc->jme_phyaddr, MII_OFFSET_ANY, - 0); + MIIF_DOPAUSE); if (error != 0) { device_printf(dev, "attaching PHYs failed\n"); goto fail; @@ -2032,12 +2032,10 @@ jme_mac_config(struct jme_softc *sc) txmac &= ~(TXMAC_COLL_ENB | TXMAC_CARRIER_SENSE | TXMAC_BACKOFF | TXMAC_CARRIER_EXT | TXMAC_FRAME_BURST); -#ifdef notyet if ((IFM_OPTIONS(mii->mii_media_active) & IFM_ETH_TXPAUSE) != 0) txpause |= TXPFC_PAUSE_ENB; if ((IFM_OPTIONS(mii->mii_media_active) & IFM_ETH_RXPAUSE) != 0) rxmac |= RXMAC_FC_ENB; -#endif /* Disable retry transmit timer/retry limit. */ CSR_WRITE_4(sc, JME_TXTRHD, CSR_READ_4(sc, JME_TXTRHD) & ~(TXTRHD_RT_PERIOD_ENB | TXTRHD_RT_LIMIT_ENB)); Index: dev/mii/atphy.c =================================================================== --- dev/mii/atphy.c (revision 215249) +++ dev/mii/atphy.c (working copy) @@ -82,7 +82,7 @@ static int atphy_service(struct mii_softc *, struc static void atphy_status(struct mii_softc *); static void atphy_reset(struct mii_softc *); static uint16_t atphy_anar(struct ifmedia_entry *); -static int atphy_auto(struct mii_softc *); +static int atphy_setmedia(struct mii_softc *, int); static const struct mii_phydesc atphys[] = { MII_PHY_DESC(ATHEROS, F1), @@ -158,7 +158,7 @@ atphy_service(struct mii_softc *sc, struct mii_dat if (IFM_SUBTYPE(ife->ifm_media) == IFM_AUTO || IFM_SUBTYPE(ife->ifm_media) == IFM_1000_T) { - atphy_auto(sc); + atphy_setmedia(sc, ife->ifm_media); break; } @@ -175,7 +175,7 @@ atphy_service(struct mii_softc *sc, struct mii_dat /* * XXX * Due to an unknown reason powering down PHY resulted - * in unexpected results such as inaccessbility of + * in unexpected results such as inaccessibility of * hardware of freshly rebooted system. Disable * powering down PHY until I got more information for * Attansic/Atheros PHY hardwares. @@ -189,8 +189,9 @@ atphy_service(struct mii_softc *sc, struct mii_dat anar = atphy_anar(ife); if (((ife->ifm_media & IFM_GMASK) & IFM_FDX) != 0) { bmcr |= BMCR_FDX; - /* Enable pause. */ - anar |= (3 << 10); + if (((ife->ifm_media & IFM_GMASK) & IFM_FLOW) != 0 || + (sc->mii_flags & MIIF_FORCEPAUSE) != 0) + anar |= ANAR_PAUSE_TOWARDS; } if ((sc->mii_extcapabilities & (EXTSR_1000TFDX | @@ -222,7 +223,7 @@ done: } /* - * check for link. + * Check for link. * Read the status register twice; BMSR_LINK is latch-low. */ bmsr = PHY_READ(sc, MII_BMSR) | PHY_READ(sc, MII_BMSR); @@ -238,7 +239,7 @@ done: return (0); sc->mii_ticks = 0; - atphy_auto(sc); + atphy_setmedia(sc, ife->ifm_media); break; } @@ -284,7 +285,7 @@ atphy_status(struct mii_softc *sc) case ATPHY_SSR_1000MBS: mii->mii_media_active |= IFM_1000_T; /* - * atphy(4) got a valid link so reset mii_ticks. + * atphy(4) has a valid link so reset mii_ticks. * Resetting mii_ticks is needed in order to * detect link loss after auto-negotiation. */ @@ -304,11 +305,13 @@ atphy_status(struct mii_softc *sc) } if ((ssr & ATPHY_SSR_DUPLEX) != 0) - mii->mii_media_active |= IFM_FDX; + mii->mii_media_active |= IFM_FDX | mii_phy_flowstatus(sc); else mii->mii_media_active |= IFM_HDX; - /* XXX Master/Slave, Flow-control */ + if ((IFM_SUBTYPE(mii->mii_media_active) == IFM_1000_T) && + (PHY_READ(sc, MII_100T2SR) & GTSR_MS_RES) != 0) + mii->mii_media_active |= IFM_ETH_MASTER; } static void @@ -336,7 +339,7 @@ atphy_reset(struct mii_softc *sc) PHY_WRITE(sc, ATPHY_SCR, reg); /* Workaround F1 bug to reset phy. */ - atphy_auto(sc); + atphy_setmedia(sc, sc->mii_pdata->mii_media.ifm_cur->ifm_media); for (i = 0; i < 1000; i++) { DELAY(1); @@ -378,12 +381,17 @@ atphy_anar(struct ifmedia_entry *ife) } static int -atphy_auto(struct mii_softc *sc) +atphy_setmedia(struct mii_softc *sc, int media) { uint16_t anar; - anar = BMSR_MEDIA_TO_ANAR(sc->mii_capabilities); - PHY_WRITE(sc, MII_ANAR, anar | (3 << 10) | ANAR_CSMA); + anar = BMSR_MEDIA_TO_ANAR(sc->mii_capabilities) | ANAR_CSMA; + if (((IFM_SUBTYPE(media) == IFM_AUTO || + ((media & IFM_GMASK) & IFM_FDX) != 0) && + ((media & IFM_GMASK) & IFM_FLOW) != 0) || + (sc->mii_flags & MIIF_FORCEPAUSE) != 0) + anar |= ANAR_PAUSE_TOWARDS; + PHY_WRITE(sc, MII_ANAR, anar); if ((sc->mii_extcapabilities & (EXTSR_1000TFDX | EXTSR_1000THDX)) != 0) PHY_WRITE(sc, MII_100T2CR, GTCR_ADV_1000TFDX | GTCR_ADV_1000THDX); Index: dev/mii/gentbi.c =================================================================== --- dev/mii/gentbi.c (revision 215249) +++ dev/mii/gentbi.c (working copy) @@ -267,7 +267,8 @@ gentbi_status(struct mii_softc *sc) anlpar = PHY_READ(sc, MII_ANLPAR); if ((sc->mii_extcapabilities & EXTSR_1000XFDX) != 0 && (anlpar & ANLPAR_X_FD) != 0) - mii->mii_media_active |= IFM_FDX; + mii->mii_media_active |= + IFM_FDX | mii_phy_flowstatus(sc); else mii->mii_media_active |= IFM_HDX; } else Index: dev/mii/jmphy.c =================================================================== --- dev/mii/jmphy.c (revision 215249) +++ dev/mii/jmphy.c (working copy) @@ -50,11 +50,11 @@ __FBSDID("$FreeBSD$"); #include "miibus_if.h" -static int jmphy_probe(device_t); -static int jmphy_attach(device_t); +static int jmphy_probe(device_t); +static int jmphy_attach(device_t); static void jmphy_reset(struct mii_softc *); static uint16_t jmphy_anar(struct ifmedia_entry *); -static int jmphy_auto(struct mii_softc *, struct ifmedia_entry *); +static int jmphy_setmedia(struct mii_softc *, struct ifmedia_entry *); struct jmphy_softc { struct mii_softc mii_sc; @@ -154,7 +154,7 @@ jmphy_service(struct mii_softc *sc, struct mii_dat if ((mii->mii_ifp->if_flags & IFF_UP) == 0) break; - if (jmphy_auto(sc, ife) != EJUSTRETURN) + if (jmphy_setmedia(sc, ife) != EJUSTRETURN) return (EINVAL); break; @@ -186,7 +186,7 @@ jmphy_service(struct mii_softc *sc, struct mii_dat return (0); sc->mii_ticks = 0; - jmphy_auto(sc, ife); + (void)jmphy_setmedia(sc, ife); break; } @@ -251,16 +251,14 @@ jmphy_status(struct mii_softc *sc) } if ((ssr & JMPHY_SSR_DUPLEX) != 0) - mii->mii_media_active |= IFM_FDX; + mii->mii_media_active |= IFM_FDX | mii_phy_flowstatus(sc); else mii->mii_media_active |= IFM_HDX; - /* XXX Flow-control. */ -#ifdef notyet + if (IFM_SUBTYPE(mii->mii_media_active) == IFM_1000_T) { if ((PHY_READ(sc, MII_100T2SR) & GTSR_MS_RES) != 0) mii->mii_media_active |= IFM_ETH_MASTER; } -#endif } static void @@ -309,7 +307,7 @@ jmphy_anar(struct ifmedia_entry *ife) } static int -jmphy_auto(struct mii_softc *sc, struct ifmedia_entry *ife) +jmphy_setmedia(struct mii_softc *sc, struct ifmedia_entry *ife) { uint16_t anar, bmcr, gig; @@ -336,17 +334,18 @@ static int bmcr |= BMCR_LOOP; anar = jmphy_anar(ife); - /* XXX Always advertise pause capability. */ - anar |= (3 << 10); + if (((IFM_SUBTYPE(ife->ifm_media) == IFM_AUTO || + (ife->ifm_media & IFM_FDX) != 0) && + (ife->ifm_media & IFM_FLOW) != 0) || + (sc->mii_flags & MIIF_FORCEPAUSE) != 0) + anar |= ANAR_PAUSE_TOWARDS; if ((sc->mii_flags & MIIF_HAVE_GTCR) != 0) { -#ifdef notyet - struct mii_data *mii; - - mii = sc->mii_pdata; - if ((mii->mii_media.ifm_media & IFM_ETH_MASTER) != 0) - gig |= GTCR_MAN_MS | GTCR_MAN_ADV; -#endif + if (IFM_SUBTYPE(ife->ifm_media) == IFM_1000_T) { + gig |= GTCR_MAN_MS; + if ((ife->ifm_media & IFM_ETH_MASTER) != 0) + gig |= GTCR_ADV_MS; + } PHY_WRITE(sc, MII_100T2CR, gig); } PHY_WRITE(sc, MII_ANAR, anar | ANAR_CSMA); Index: dev/mii/nsgphy.c =================================================================== --- dev/mii/nsgphy.c (revision 215249) +++ dev/mii/nsgphy.c (working copy) @@ -246,7 +246,8 @@ nsgphy_status(struct mii_softc *sc) } if (physup & PHY_SUP_DUPLEX) - mii->mii_media_active |= IFM_FDX; + mii->mii_media_active |= + IFM_FDX | mii_phy_flowstatus(sc); else mii->mii_media_active |= IFM_HDX; } else Index: dev/mii/rgephy.c =================================================================== --- dev/mii/rgephy.c (revision 215249) +++ dev/mii/rgephy.c (working copy) @@ -89,7 +89,7 @@ DRIVER_MODULE(rgephy, miibus, rgephy_driver, rgeph static int rgephy_service(struct mii_softc *, struct mii_data *, int); static void rgephy_status(struct mii_softc *); -static int rgephy_mii_phy_auto(struct mii_softc *); +static int rgephy_mii_phy_auto(struct mii_softc *, int); static void rgephy_reset(struct mii_softc *); static void rgephy_loop(struct mii_softc *); static void rgephy_load_dspcode(struct mii_softc *); @@ -113,7 +113,6 @@ rgephy_attach(device_t dev) struct mii_softc *sc; struct mii_attach_args *ma; struct mii_data *mii; - const char *sep = ""; rsc = device_get_softc(dev); sc = &rsc->mii_sc; @@ -132,27 +131,21 @@ rgephy_attach(device_t dev) rsc->mii_revision = MII_REV(ma->mii_id2); #define ADD(m, c) ifmedia_add(&mii->mii_media, (m), (c), NULL) -#define PRINT(s) printf("%s%s", sep, s); sep = ", " #if 0 ADD(IFM_MAKEWORD(IFM_ETHER, IFM_100_TX, IFM_LOOP, sc->mii_inst), MII_MEDIA_100_TX); #endif - sc->mii_capabilities = PHY_READ(sc, MII_BMSR) & ma->mii_capmask; - sc->mii_capabilities &= ~BMSR_ANEG; + /* RTL8169S do not report auto-sense; add manually. */ + sc->mii_capabilities = (PHY_READ(sc, MII_BMSR) | BMSR_ANEG) & + ma->mii_capmask; if (sc->mii_capabilities & BMSR_EXTSTAT) sc->mii_extcapabilities = PHY_READ(sc, MII_EXTSR); - device_printf(dev, " "); mii_phy_add_media(sc); - /* RTL8169S do not report auto-sense; add manually. */ - ADD(IFM_MAKEWORD(IFM_ETHER, IFM_AUTO, 0, sc->mii_inst), MII_NMEDIA); - sep = ", "; - PRINT("auto"); printf("\n"); #undef ADD -#undef PRINT rgephy_reset(sc); MIIBUS_MEDIAINIT(sc->mii_dev); @@ -182,7 +175,8 @@ rgephy_service(struct mii_softc *sc, struct mii_da rgephy_reset(sc); /* XXX hardware bug work-around */ anar = PHY_READ(sc, RGEPHY_MII_ANAR); - anar &= ~(RGEPHY_ANAR_TX_FD | RGEPHY_ANAR_TX | + anar &= ~(RGEPHY_ANAR_PC | RGEPHY_ANAR_ASP | + RGEPHY_ANAR_TX_FD | RGEPHY_ANAR_TX | RGEPHY_ANAR_10_FD | RGEPHY_ANAR_10); switch (IFM_SUBTYPE(ife->ifm_media)) { @@ -194,7 +188,7 @@ rgephy_service(struct mii_softc *sc, struct mii_da if (PHY_READ(sc, RGEPHY_MII_BMCR) & RGEPHY_BMCR_AUTOEN) return (0); #endif - (void) rgephy_mii_phy_auto(sc); + (void)rgephy_mii_phy_auto(sc, ife->ifm_media); break; case IFM_1000_T: speed = RGEPHY_S1000; @@ -222,32 +216,26 @@ setit: PHY_WRITE(sc, RGEPHY_MII_1000CTL, 0); PHY_WRITE(sc, RGEPHY_MII_ANAR, anar); PHY_WRITE(sc, RGEPHY_MII_BMCR, speed | - RGEPHY_BMCR_AUTOEN | RGEPHY_BMCR_STARTNEG); + RGEPHY_BMCR_AUTOEN | + RGEPHY_BMCR_STARTNEG); break; } - /* - * When setting the link manually, one side must - * be the master and the other the slave. However - * ifmedia doesn't give us a good way to specify - * this, so we fake it by using one of the LINK - * flags. If LINK0 is set, we program the PHY to - * be a master, otherwise it's a slave. - */ - if ((mii->mii_ifp->if_flags & IFF_LINK0)) { - PHY_WRITE(sc, RGEPHY_MII_1000CTL, - gig|RGEPHY_1000CTL_MSE|RGEPHY_1000CTL_MSC); - } else { - PHY_WRITE(sc, RGEPHY_MII_1000CTL, - gig|RGEPHY_1000CTL_MSE); - } + if ((ife->ifm_media & IFM_FLOW) != 0 || + (sc->mii_flags & MIIF_FORCEPAUSE) != 0) + anar |= RGEPHY_ANAR_PC | RGEPHY_ANAR_ASP; + + gig |= RGEPHY_1000CTL_MSE; + if ((ife->ifm_media & IFM_ETH_MASTER) != 0) + gig |= RGEPHY_1000CTL_MSC; + PHY_WRITE(sc, RGEPHY_MII_1000CTL, gig); + PHY_WRITE(sc, RGEPHY_MII_ANAR, anar); PHY_WRITE(sc, RGEPHY_MII_BMCR, speed | RGEPHY_BMCR_AUTOEN | RGEPHY_BMCR_STARTNEG); break; case IFM_NONE: - PHY_WRITE(sc, MII_BMCR, BMCR_ISO|BMCR_PDOWN); + PHY_WRITE(sc, MII_BMCR, BMCR_ISO | BMCR_PDOWN); break; - case IFM_100_T4: default: return (EINVAL); } @@ -297,7 +285,7 @@ setit: return (0); sc->mii_ticks = 0; - rgephy_mii_phy_auto(sc); + rgephy_mii_phy_auto(sc, ife->ifm_media); break; } @@ -395,22 +383,32 @@ rgephy_status(struct mii_softc *sc) else mii->mii_media_active |= IFM_HDX; } + + if ((mii->mii_media_active & IFM_FDX) != 0) + mii->mii_media_active |= mii_phy_flowstatus(sc); + + if ((IFM_SUBTYPE(mii->mii_media_active) == IFM_1000_T) && + (PHY_READ(sc, RGEPHY_MII_1000STS) & RGEPHY_1000STS_MSR) != 0) + mii->mii_media_active |= IFM_ETH_MASTER; } static int -rgephy_mii_phy_auto(struct mii_softc *mii) +rgephy_mii_phy_auto(struct mii_softc *sc, int media) { + int anar; - rgephy_loop(mii); - rgephy_reset(mii); + rgephy_loop(sc); + rgephy_reset(sc); - PHY_WRITE(mii, RGEPHY_MII_ANAR, - BMSR_MEDIA_TO_ANAR(mii->mii_capabilities) | ANAR_CSMA); + anar = BMSR_MEDIA_TO_ANAR(sc->mii_capabilities) | ANAR_CSMA; + if ((media & IFM_FLOW) != 0 || (sc->mii_flags & MIIF_FORCEPAUSE) != 0) + anar |= RGEPHY_ANAR_PC | RGEPHY_ANAR_ASP; + PHY_WRITE(sc, RGEPHY_MII_ANAR, anar); DELAY(1000); - PHY_WRITE(mii, RGEPHY_MII_1000CTL, - RGEPHY_1000CTL_AHD|RGEPHY_1000CTL_AFD); + PHY_WRITE(sc, RGEPHY_MII_1000CTL, + RGEPHY_1000CTL_AHD | RGEPHY_1000CTL_AFD); DELAY(1000); - PHY_WRITE(mii, RGEPHY_MII_BMCR, + PHY_WRITE(sc, RGEPHY_MII_BMCR, RGEPHY_BMCR_AUTOEN | RGEPHY_BMCR_STARTNEG); DELAY(100); Index: dev/nge/if_nge.c =================================================================== --- dev/nge/if_nge.c (revision 215249) +++ dev/nge/if_nge.c (working copy) @@ -712,13 +712,10 @@ nge_miibus_statchg(device_t dev) NGE_SETBIT(sc, NGE_TX_CFG, (NGE_TXCFG_IGN_HBEAT | NGE_TXCFG_IGN_CARR)); NGE_SETBIT(sc, NGE_RX_CFG, NGE_RXCFG_RX_FDX); -#ifdef notyet - /* Enable flow-control. */ if ((IFM_OPTIONS(mii->mii_media_active) & (IFM_ETH_RXPAUSE | IFM_ETH_TXPAUSE)) != 0) NGE_SETBIT(sc, NGE_PAUSECSR, NGE_PAUSECSR_PAUSE_ENB); -#endif } else { NGE_CLRBIT(sc, NGE_TX_CFG, (NGE_TXCFG_IGN_HBEAT | NGE_TXCFG_IGN_CARR)); @@ -1080,7 +1077,8 @@ nge_attach(device_t dev) * Do MII setup. */ error = mii_attach(dev, &sc->nge_miibus, ifp, nge_mediachange, - nge_mediastatus, BMSR_DEFCAPMASK, MII_PHY_ANY, MII_OFFSET_ANY, 0); + nge_mediastatus, BMSR_DEFCAPMASK, MII_PHY_ANY, MII_OFFSET_ANY, + MIIF_DOPAUSE); if (error != 0) { device_printf(dev, "attaching PHYs failed\n"); goto fail; Index: dev/sf/if_sf.c =================================================================== --- dev/sf/if_sf.c (revision 215249) +++ dev/sf/if_sf.c (working copy) @@ -434,15 +434,12 @@ sf_link_task(void *arg, int pending) if ((IFM_OPTIONS(mii->mii_media_active) & IFM_FDX) != 0) { val |= SF_MACCFG1_FULLDUPLEX; csr_write_4(sc, SF_BKTOBKIPG, SF_IPGT_FDX); -#ifdef notyet - /* Configure flow-control bits. */ - if ((IFM_OPTIONS(sc->sc_mii->mii_media_active) & + if ((IFM_OPTIONS(mii->mii_media_active) & IFM_ETH_RXPAUSE) != 0) val |= SF_MACCFG1_RX_FLOWENB; - if ((IFM_OPTIONS(sc->sc_mii->mii_media_active) & + if ((IFM_OPTIONS(mii->mii_media_active) & IFM_ETH_TXPAUSE) != 0) val |= SF_MACCFG1_TX_FLOWENB; -#endif } else csr_write_4(sc, SF_BKTOBKIPG, SF_IPGT_HDX); @@ -867,7 +864,8 @@ sf_attach(device_t dev) /* Do MII setup. */ error = mii_attach(dev, &sc->sf_miibus, ifp, sf_ifmedia_upd, - sf_ifmedia_sts, BMSR_DEFCAPMASK, MII_PHY_ANY, MII_OFFSET_ANY, 0); + sf_ifmedia_sts, BMSR_DEFCAPMASK, MII_PHY_ANY, MII_OFFSET_ANY, + MIIF_DOPAUSE); if (error != 0) { device_printf(dev, "attaching PHYs failed\n"); goto fail; Index: dev/vr/if_vr.c =================================================================== --- dev/vr/if_vr.c (revision 215249) +++ dev/vr/if_vr.c (working copy) @@ -354,8 +354,6 @@ vr_link_task(void *arg, int pending) CSR_WRITE_1(sc, VR_CR1, cr1); } fc = 0; -#ifdef notyet - /* Configure flow-control. */ if (sc->vr_revid >= REV_ID_VT6105_A0) { fc = CSR_READ_1(sc, VR_FLOWCR1); fc &= ~(VR_FLOWCR1_TXPAUSE | VR_FLOWCR1_RXPAUSE); @@ -367,7 +365,7 @@ vr_link_task(void *arg, int pending) fc |= VR_FLOWCR1_TXPAUSE; CSR_WRITE_1(sc, VR_FLOWCR1, fc); } else if (sc->vr_revid >= REV_ID_VT6102_A) { - /* No Tx puase capability available for Rhine II. */ + /* No Tx pause capability available for Rhine II. */ fc = CSR_READ_1(sc, VR_MISC_CR0); fc &= ~VR_MISCCR0_RXPAUSE; if ((IFM_OPTIONS(mii->mii_media_active) & @@ -375,7 +373,6 @@ vr_link_task(void *arg, int pending) fc |= VR_MISCCR0_RXPAUSE; CSR_WRITE_1(sc, VR_MISC_CR0, fc); } -#endif vr_rx_start(sc); vr_tx_start(sc); } else { @@ -782,7 +779,8 @@ vr_attach(device_t dev) else phy = CSR_READ_1(sc, VR_PHYADDR) & VR_PHYADDR_MASK; error = mii_attach(dev, &sc->vr_miibus, ifp, vr_ifmedia_upd, - vr_ifmedia_sts, BMSR_DEFCAPMASK, phy, MII_OFFSET_ANY, 0); + vr_ifmedia_sts, BMSR_DEFCAPMASK, phy, MII_OFFSET_ANY, + MIIF_DOPAUSE); if (error != 0) { device_printf(dev, "attaching PHYs failed\n"); goto fail;