static void rgephy_disable_eee(struct mii_softc *sc) { uint16_t anar; PHY_WRITE(sc, RGEPHY_F_EPAGSR, 0x0000); PHY_WRITE(sc, MII_MMDACR, MMDACR_FN_ADDRESS | (MMDACR_DADDRMASK & RGEPHY_F_MMD_DEV_7)); PHY_WRITE(sc, MII_MMDAADR, RGEPHY_F_MMD_EEEAR); PHY_WRITE(sc, MII_MMDACR, MMDACR_FN_DATANPI | (MMDACR_DADDRMASK & RGEPHY_F_MMD_DEV_7)); PHY_WRITE(sc, MII_MMDAADR, 0x0000); PHY_WRITE(sc, MII_MMDACR, 0x0000); /* * XXX * Restart auto-negotiation to take changes effect. * This may result in link establishment. */ anar = BMSR_MEDIA_TO_ANAR(sc->mii_capabilities) | ANAR_CSMA; PHY_WRITE(sc, RGEPHY_MII_ANAR, anar); PHY_WRITE(sc, RGEPHY_MII_1000CTL, RGEPHY_1000CTL_AHD | RGEPHY_1000CTL_AFD); PHY_WRITE(sc, RGEPHY_MII_BMCR, RGEPHY_BMCR_RESET | RGEPHY_BMCR_AUTOEN | RGEPHY_BMCR_STARTNEG); }
int brgphy_mii_phy_auto(struct mii_softc *sc) { int anar, ktcr = 0; PHY_RESET(sc); if (sc->mii_flags & MIIF_HAVEFIBER) { anar = BRGPHY_SERDES_ANAR_FDX | BRGPHY_SERDES_ANAR_HDX; if (sc->mii_flags & MIIF_DOPAUSE) anar |= BRGPHY_SERDES_ANAR_BOTH_PAUSE; PHY_WRITE(sc, BRGPHY_SERDES_ANAR, anar); } else { anar = BMSR_MEDIA_TO_ANAR(sc->mii_capabilities) | ANAR_CSMA; if (sc->mii_flags & MIIF_DOPAUSE) anar |= BRGPHY_ANAR_ASP | BRGPHY_ANAR_PC; PHY_WRITE(sc, BRGPHY_MII_ANAR, anar); } /* Enable speed in the 1000baseT control register */ ktcr = BRGPHY_1000CTL_AFD | BRGPHY_1000CTL_AHD; if (sc->mii_model == MII_MODEL_xxBROADCOM_BCM5701) ktcr |= BRGPHY_1000CTL_MSE | BRGPHY_1000CTL_MSC; PHY_WRITE(sc, BRGPHY_MII_1000CTL, ktcr); ktcr = PHY_READ(sc, BRGPHY_MII_1000CTL); /* Start autonegotiation */ PHY_WRITE(sc, BRGPHY_MII_BMCR, BRGPHY_BMCR_AUTOEN | BRGPHY_BMCR_STARTNEG); PHY_WRITE(sc, BRGPHY_MII_IMR, 0xFF00); return (EJUSTRETURN); }
static void atphy_auto(struct mii_softc *sc) { uint16_t anar; anar = BMSR_MEDIA_TO_ANAR(sc->mii_capabilities); PHY_WRITE(sc, MII_ANAR, anar | (3 << 10) | ANAR_CSMA); if (sc->mii_extcapabilities & (EXTSR_1000TFDX | EXTSR_1000THDX)) { PHY_WRITE(sc, MII_100T2CR, GTCR_ADV_1000TFDX | GTCR_ADV_1000THDX); } else if (sc->mii_model == MII_MODEL_ATHEROS_F1) { /* * AR8132 has 10/100 PHY and the PHY uses the same * model number of F1 gigabit PHY. The PHY has no * ability to establish gigabit link so explicitly * disable 1000baseT configuration for the PHY. * Otherwise, there is a case that atphy(4) could * not establish a link against gigabit link partner * unless the link partner supports down-shifting. */ PHY_WRITE(sc, MII_100T2CR, 0); } PHY_WRITE(sc, MII_BMCR, BMCR_RESET | BMCR_AUTOEN | BMCR_STARTNEG); }
static void brgphy_mii_phy_auto(struct mii_softc *sc) { struct brgphy_softc *bsc = (struct brgphy_softc *)sc; int ktcr = 0; brgphy_reset(sc); /* Enable flow control in the advertisement register. */ if ((sc->mii_flags & MIIF_HAVEFIBER) == 0) { /* Pause capability advertisement (pause capable & asymmetric) */ PHY_WRITE(sc, BRGPHY_MII_ANAR, BMSR_MEDIA_TO_ANAR(sc->mii_capabilities) | ANAR_CSMA | BRGPHY_ANAR_ASP | BRGPHY_ANAR_PC); } else { PHY_WRITE(sc, BRGPHY_SERDES_ANAR, BRGPHY_SERDES_ANAR_FDX | BRGPHY_SERDES_ANAR_HDX | BRGPHY_SERDES_ANAR_BOTH_PAUSE); } /* Enable speed in the 1000baseT control register */ ktcr = BRGPHY_1000CTL_AFD | BRGPHY_1000CTL_AHD; if (bsc->mii_model == MII_MODEL_xxBROADCOM_BCM5701) ktcr |= BRGPHY_1000CTL_MSE | BRGPHY_1000CTL_MSC; PHY_WRITE(sc, BRGPHY_MII_1000CTL, ktcr); ktcr = PHY_READ(sc, BRGPHY_MII_1000CTL); /* Start autonegotiation */ PHY_WRITE(sc, BRGPHY_MII_BMCR,BRGPHY_BMCR_AUTOEN | BRGPHY_BMCR_STARTNEG); PHY_WRITE(sc, BRGPHY_MII_IMR, 0xFF00); }
static int atphy_setmedia(struct mii_softc *sc, int media) { uint16_t anar; anar = BMSR_MEDIA_TO_ANAR(sc->mii_capabilities) | ANAR_CSMA; if ((IFM_SUBTYPE(media) == IFM_AUTO || (media & IFM_FDX) != 0) && ((media & 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); else if (sc->mii_mpd_model == MII_MODEL_xxATHEROS_F1) { /* * AR8132 has 10/100 PHY and the PHY uses the same * model number of F1 gigabit PHY. The PHY has no * ability to establish gigabit link so explicitly * disable 1000baseT configuration for the PHY. * Otherwise, there is a case that atphy(4) could * not establish a link against gigabit link partner * unless the link partner supports down-shifting. */ PHY_WRITE(sc, MII_100T2CR, 0); } PHY_WRITE(sc, MII_BMCR, BMCR_RESET | BMCR_AUTOEN | BMCR_STARTNEG); return (EJUSTRETURN); }
static void brgphy_mii_phy_auto(struct mii_softc *sc, int media) { int anar, ktcr = 0; PHY_RESET(sc); if ((sc->mii_flags & MIIF_HAVEFIBER) == 0) { anar = BMSR_MEDIA_TO_ANAR(sc->mii_capabilities) | ANAR_CSMA; if ((media & IFM_FLOW) != 0 || (sc->mii_flags & MIIF_FORCEPAUSE) != 0) anar |= BRGPHY_ANAR_PC | BRGPHY_ANAR_ASP; PHY_WRITE(sc, BRGPHY_MII_ANAR, anar); ktcr = BRGPHY_1000CTL_AFD | BRGPHY_1000CTL_AHD; if (sc->mii_mpd_model == MII_MODEL_BROADCOM_BCM5701) ktcr |= BRGPHY_1000CTL_MSE | BRGPHY_1000CTL_MSC; PHY_WRITE(sc, BRGPHY_MII_1000CTL, ktcr); PHY_READ(sc, BRGPHY_MII_1000CTL); } else { anar = BRGPHY_SERDES_ANAR_FDX | BRGPHY_SERDES_ANAR_HDX; if ((media & IFM_FLOW) != 0 || (sc->mii_flags & MIIF_FORCEPAUSE) != 0) anar |= BRGPHY_SERDES_ANAR_BOTH_PAUSE; PHY_WRITE(sc, BRGPHY_SERDES_ANAR, anar); } PHY_WRITE(sc, BRGPHY_MII_BMCR, BRGPHY_BMCR_AUTOEN | BRGPHY_BMCR_STARTNEG); PHY_WRITE(sc, BRGPHY_MII_IMR, 0xFF00); }
static void nsphy_reset(struct mii_softc *sc) { int anar; mii_phy_reset(sc); anar = PHY_READ(sc, MII_ANAR); anar |= BMSR_MEDIA_TO_ANAR(PHY_READ(sc, MII_BMSR)); PHY_WRITE(sc, MII_ANAR, anar); }
static void smcphy_auto(struct mii_softc *sc, int media) { uint16_t anar; anar = BMSR_MEDIA_TO_ANAR(sc->mii_capabilities) | ANAR_CSMA; if ((media & IFM_FLOW) != 0 || (sc->mii_flags & MIIF_FORCEPAUSE) != 0) anar |= ANAR_FC; PHY_WRITE(sc, MII_ANAR, anar); /* Apparently this helps. */ anar = PHY_READ(sc, MII_ANAR); PHY_WRITE(sc, MII_BMCR, BMCR_AUTOEN | BMCR_STARTNEG); }
static int atphy_auto(struct mii_softc *sc) { uint16_t anar; anar = BMSR_MEDIA_TO_ANAR(sc->mii_capabilities); PHY_WRITE(sc, MII_ANAR, anar | (3 << 10) | ANAR_CSMA); if ((sc->mii_extcapabilities & (EXTSR_1000TFDX | EXTSR_1000THDX)) != 0) PHY_WRITE(sc, MII_100T2CR, GTCR_ADV_1000TFDX | GTCR_ADV_1000THDX); PHY_WRITE(sc, MII_BMCR, BMCR_RESET | BMCR_AUTOEN | BMCR_STARTNEG); return (EJUSTRETURN); }
int mii_phy_auto(struct mii_softc *sc) { struct ifmedia_entry *ife = sc->mii_pdata->mii_media.ifm_cur; int anar, gtcr; /* * Check for 1000BASE-X. Autonegotiation is a bit * different on such devices. */ if ((sc->mii_flags & MIIF_IS_1000X) != 0) { anar = 0; if ((sc->mii_extcapabilities & EXTSR_1000XFDX) != 0) anar |= ANAR_X_FD; if ((sc->mii_extcapabilities & EXTSR_1000XHDX) != 0) anar |= ANAR_X_HD; if ((ife->ifm_media & IFM_FLOW) != 0 || (sc->mii_flags & MIIF_FORCEPAUSE) != 0) anar |= ANAR_X_PAUSE_TOWARDS; PHY_WRITE(sc, MII_ANAR, anar); } else { anar = BMSR_MEDIA_TO_ANAR(sc->mii_capabilities) | ANAR_CSMA; if ((ife->ifm_media & IFM_FLOW) != 0 || (sc->mii_flags & MIIF_FORCEPAUSE) != 0) { if ((sc->mii_capabilities & (BMSR_10TFDX | BMSR_100TXFDX)) != 0) anar |= ANAR_FC; /* XXX Only 1000BASE-T has PAUSE_ASYM? */ if (((sc->mii_flags & MIIF_HAVE_GTCR) != 0) && (sc->mii_extcapabilities & (EXTSR_1000THDX | EXTSR_1000TFDX)) != 0) anar |= ANAR_X_PAUSE_ASYM; } PHY_WRITE(sc, MII_ANAR, anar); if ((sc->mii_flags & MIIF_HAVE_GTCR) != 0) { gtcr = 0; if ((sc->mii_extcapabilities & EXTSR_1000TFDX) != 0) gtcr |= GTCR_ADV_1000TFDX; if ((sc->mii_extcapabilities & EXTSR_1000THDX) != 0) gtcr |= GTCR_ADV_1000THDX; PHY_WRITE(sc, MII_100T2CR, gtcr); } } PHY_WRITE(sc, MII_BMCR, BMCR_AUTOEN | BMCR_STARTNEG); return (EJUSTRETURN); }
int atphy_mii_phy_auto(struct mii_softc *sc) { uint16_t anar; anar = BMSR_MEDIA_TO_ANAR(sc->mii_capabilities) | ANAR_CSMA; if (sc->mii_flags & MIIF_DOPAUSE) anar |= ANAR_PAUSE_TOWARDS; PHY_WRITE(sc, MII_ANAR, anar); if (sc->mii_extcapabilities & (EXTSR_1000TFDX | EXTSR_1000THDX)) PHY_WRITE(sc, MII_100T2CR, GTCR_ADV_1000TFDX | GTCR_ADV_1000THDX); PHY_WRITE(sc, MII_BMCR, BMCR_RESET | BMCR_AUTOEN | BMCR_STARTNEG); return (EJUSTRETURN); }
int mii_phy_auto(struct mii_softc *sc) { /* * Check for 1000BASE-X. Autonegotiation is a bit * different on such devices. */ if (sc->mii_flags & MIIF_IS_1000X) { uint16_t anar = 0; if (sc->mii_extcapabilities & EXTSR_1000XFDX) anar |= ANAR_X_FD; if (sc->mii_extcapabilities & EXTSR_1000XHDX) anar |= ANAR_X_HD; if (sc->mii_flags & MIIF_DOPAUSE) { /* XXX Asymmetric vs. symmetric? */ anar |= ANLPAR_X_PAUSE_TOWARDS; } PHY_WRITE(sc, MII_ANAR, anar); } else { uint16_t anar; anar = BMSR_MEDIA_TO_ANAR(sc->mii_capabilities) | ANAR_CSMA; if (sc->mii_flags & MIIF_DOPAUSE) anar |= ANAR_FC; PHY_WRITE(sc, MII_ANAR, anar); if (sc->mii_flags & MIIF_HAVE_GTCR) { uint16_t gtcr = 0; if (sc->mii_extcapabilities & EXTSR_1000TFDX) gtcr |= GTCR_ADV_1000TFDX; if (sc->mii_extcapabilities & EXTSR_1000THDX) gtcr |= GTCR_ADV_1000THDX; PHY_WRITE(sc, MII_100T2CR, gtcr); } } PHY_WRITE(sc, MII_BMCR, BMCR_AUTOEN | BMCR_STARTNEG); return (EJUSTRETURN); }
static int rgephy_mii_phy_auto(struct mii_softc *mii) { rgephy_loop(mii); rgephy_reset(mii); PHY_WRITE(mii, RGEPHY_MII_ANAR, BMSR_MEDIA_TO_ANAR(mii->mii_capabilities) | ANAR_CSMA); DELAY(1000); PHY_WRITE(mii, RGEPHY_MII_1000CTL, RGEPHY_1000CTL_AHD|RGEPHY_1000CTL_AFD); DELAY(1000); PHY_WRITE(mii, RGEPHY_MII_BMCR, RGEPHY_BMCR_AUTOEN | RGEPHY_BMCR_STARTNEG); DELAY(100); return (EJUSTRETURN); }
static void brgphy_mii_phy_auto(struct mii_softc *sc) { int ktcr; brgphy_reset(sc); PHY_WRITE(sc, BRGPHY_MII_ANAR, BMSR_MEDIA_TO_ANAR(sc->mii_capabilities) | ANAR_CSMA); DELAY(1000); ktcr = BRGPHY_1000CTL_AFD|BRGPHY_1000CTL_AHD; if (sc->mii_model == MII_MODEL_xxBROADCOM_BCM5701) ktcr |= BRGPHY_1000CTL_MSE|BRGPHY_1000CTL_MSC; PHY_WRITE(sc, BRGPHY_MII_1000CTL, ktcr); ktcr = PHY_READ(sc, BRGPHY_MII_1000CTL); DELAY(1000); PHY_WRITE(sc, BRGPHY_MII_BMCR, BRGPHY_BMCR_AUTOEN | BRGPHY_BMCR_STARTNEG); PHY_WRITE(sc, BRGPHY_MII_IMR, 0xFF00); }
static int rgephy_mii_phy_auto(struct mii_softc *sc, int media) { int anar; rgephy_loop(sc); PHY_RESET(sc); 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(sc, RGEPHY_MII_1000CTL, RGEPHY_1000CTL_AHD | RGEPHY_1000CTL_AFD); DELAY(1000); PHY_WRITE(sc, RGEPHY_MII_BMCR, RGEPHY_BMCR_AUTOEN | RGEPHY_BMCR_STARTNEG); DELAY(100); return (EJUSTRETURN); }
int brgphy_mii_phy_auto(struct mii_softc *sc) { int anar, ktcr = 0; sc->mii_ticks = 0; brgphy_loop(sc); PHY_RESET(sc); ktcr = GTCR_ADV_1000TFDX | GTCR_ADV_1000THDX; if ((sc->mii_mpd_oui == MII_OUI_BROADCOM) && (sc->mii_mpd_model == MII_MODEL_BROADCOM_BCM5701)) ktcr |= GTCR_MAN_MS | GTCR_ADV_MS; PHY_WRITE(sc, MII_100T2CR, ktcr); ktcr = PHY_READ(sc, MII_100T2CR); DELAY(1000); if (sc->mii_flags & MIIF_HAVEFIBER) { anar = ANAR_X_FD | ANAR_X_HD; if (sc->mii_flags & MIIF_DOPAUSE) anar |= BRGPHY_SERDES_ANAR_BOTH_PAUSE; } else { anar = BMSR_MEDIA_TO_ANAR(sc->mii_capabilities) | ANAR_CSMA; if (sc->mii_flags & MIIF_DOPAUSE) anar |= ANAR_FC | ANAR_PAUSE_ASYM; } PHY_WRITE(sc, MII_ANAR, anar); DELAY(1000); /* Start autonegotiation */ PHY_WRITE(sc, MII_BMCR, BMCR_AUTOEN | BMCR_STARTNEG); PHY_WRITE(sc, BRGPHY_MII_IMR, 0xFF00); return (EJUSTRETURN); }
int mii_phy_auto(struct mii_softc *sc, int waitfor) { int bmsr, i; if ((sc->mii_flags & MIIF_DOINGAUTO) == 0) { /* * Check for 1000BASE-X. Autonegotiation is a bit * different on such devices. */ if (sc->mii_flags & MIIF_IS_1000X) { uint16_t anar = 0; if (sc->mii_extcapabilities & EXTSR_1000XFDX) anar |= ANAR_X_FD; if (sc->mii_extcapabilities & EXTSR_1000XHDX) anar |= ANAR_X_HD; if (sc->mii_flags & MIIF_DOPAUSE && sc->mii_extcapabilities & EXTSR_1000XFDX) anar |= ANAR_X_PAUSE_TOWARDS; PHY_WRITE(sc, MII_ANAR, anar); } else { uint16_t anar; anar = BMSR_MEDIA_TO_ANAR(sc->mii_capabilities) | ANAR_CSMA; /* * Most 100baseTX PHY's only support symmetric * PAUSE, so we don't advertise asymmetric * PAUSE unless we also have 1000baseT capability. */ if (sc->mii_flags & MIIF_DOPAUSE) { if (sc->mii_capabilities & BMSR_100TXFDX) anar |= ANAR_FC; if (sc->mii_extcapabilities & EXTSR_1000TFDX) anar |= ANAR_PAUSE_TOWARDS; } PHY_WRITE(sc, MII_ANAR, anar); if (sc->mii_flags & MIIF_HAVE_GTCR) { uint16_t gtcr = 0; if (sc->mii_extcapabilities & EXTSR_1000TFDX) gtcr |= GTCR_ADV_1000TFDX; if (sc->mii_extcapabilities & EXTSR_1000THDX) gtcr |= GTCR_ADV_1000THDX; PHY_WRITE(sc, MII_100T2CR, gtcr); } } PHY_WRITE(sc, MII_BMCR, BMCR_AUTOEN | BMCR_STARTNEG); } if (waitfor) { /* Wait 500ms for it to complete. */ for (i = 0; i < 500; i++) { if ((bmsr = PHY_READ(sc, MII_BMSR)) & BMSR_ACOMP) return (0); delay(1000); } /* * Don't need to worry about clearing MIIF_DOINGAUTO. * If that's set, a timeout is pending, and it will * clear the flag. */ return (EIO); } /* * Just let it finish asynchronously. This is for the benefit of * the tick handler driving autonegotiation. Don't want 500ms * delays all the time while the system is running! */ if (sc->mii_flags & MIIF_AUTOTSLEEP) { sc->mii_flags |= MIIF_DOINGAUTO; tsleep(&sc->mii_flags, PZERO, "miiaut", hz >> 1); mii_phy_auto_timeout(sc); } else if ((sc->mii_flags & MIIF_DOINGAUTO) == 0) {
int mii_phy_auto(struct mii_softc *sc, int waitfor) { int i; struct mii_data *mii = sc->mii_pdata; struct ifmedia_entry *ife = mii->mii_media.ifm_cur; sc->mii_ticks = 0; if ((sc->mii_flags & MIIF_DOINGAUTO) == 0) { /* * Check for 1000BASE-X. Autonegotiation is a bit * different on such devices. */ if (sc->mii_flags & MIIF_IS_1000X) { uint16_t anar = 0; if (sc->mii_extcapabilities & EXTSR_1000XFDX) anar |= ANAR_X_FD; if (sc->mii_extcapabilities & EXTSR_1000XHDX) anar |= ANAR_X_HD; if (sc->mii_flags & MIIF_DOPAUSE) { /* XXX Asymmetric vs. symmetric? */ anar |= ANLPAR_X_PAUSE_TOWARDS; } PHY_WRITE(sc, MII_ANAR, anar); } else { uint16_t anar; anar = BMSR_MEDIA_TO_ANAR(sc->mii_capabilities) | ANAR_CSMA; if (sc->mii_flags & MIIF_DOPAUSE) { anar |= ANAR_FC; /* XXX Only 1000BASE-T has PAUSE_ASYM? */ if ((sc->mii_flags & MIIF_HAVE_GTCR) && (sc->mii_extcapabilities & (EXTSR_1000THDX | EXTSR_1000TFDX))) anar |= ANAR_PAUSE_ASYM; } /* *for 1000-base-T, autonegotiation mus be enabled, but *if we're not set to auto, only advertise *1000-base-T with the link partner. */ if (IFM_SUBTYPE(ife->ifm_media) == IFM_1000_T) { anar &= ~(ANAR_T4|ANAR_TX_FD|ANAR_TX|ANAR_10_FD|ANAR_10); } PHY_WRITE(sc, MII_ANAR, anar); if (sc->mii_flags & MIIF_HAVE_GTCR) { uint16_t gtcr = 0; if (sc->mii_extcapabilities & EXTSR_1000TFDX) gtcr |= GTCR_ADV_1000TFDX; if (sc->mii_extcapabilities & EXTSR_1000THDX) gtcr |= GTCR_ADV_1000THDX; PHY_WRITE(sc, MII_100T2CR, gtcr); } } PHY_WRITE(sc, MII_BMCR, BMCR_AUTOEN | BMCR_STARTNEG); } if (waitfor) { /* Wait 500ms for it to complete. */ for (i = 0; i < 500; i++) { if (PHY_READ(sc, MII_BMSR) & BMSR_ACOMP) return (0); delay(1000); } /* * Don't need to worry about clearing MIIF_DOINGAUTO. * If that's set, a timeout is pending, and it will * clear the flag. */ return (EIO); } /* * Just let it finish asynchronously. This is for the benefit of * the tick handler driving autonegotiation. Don't want 500ms * delays all the time while the system is running! */ if (sc->mii_flags & MIIF_AUTOTSLEEP) { sc->mii_flags |= MIIF_DOINGAUTO; tsleep(&sc->mii_flags, PZERO, "miiaut", hz >> 1); mii_phy_auto_timeout(sc); } else if ((sc->mii_flags & MIIF_DOINGAUTO) == 0) {