static int acphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd) { struct ifmedia_entry *ife = mii->mii_media.ifm_cur; int reg; /* * If we're not selected, then do nothing, just isolate and power * down, if changing media. */ if (IFM_INST(ife->ifm_media) != sc->mii_inst) { if (cmd == MII_MEDIACHG) { reg = PHY_READ(sc, MII_BMCR); PHY_WRITE(sc, MII_BMCR, reg | BMCR_ISO | BMCR_PDOWN); } return (0); } switch (cmd) { case MII_POLLSTAT: break; case MII_MEDIACHG: /* * If the interface is not up, don't do anything. */ if ((mii->mii_ifp->if_flags & IFF_UP) == 0) break; mii_phy_set_media(sc); break; case MII_TICK: /* * Is the interface even up? */ if ((mii->mii_ifp->if_flags & IFF_UP) == 0) return (0); /* * Only used for autonegotiation. */ if (IFM_SUBTYPE(ife->ifm_media) != IFM_AUTO) break; /* * This PHY's autonegotiation doesn't need to be kicked. */ break; } /* Update the media status. */ acphy_status(sc); /* Callback if something changed. */ mii_phy_update(sc, cmd); return (0); }
static int ukphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd) { struct ifmedia_entry *ife = mii->mii_media.ifm_cur; int reg; switch (cmd) { case MII_POLLSTAT: /* * If we're not polling our PHY instance, just return. */ if (IFM_INST(ife->ifm_media) != sc->mii_inst) return (0); break; case MII_MEDIACHG: /* * If the media indicates a different PHY instance, * isolate ourselves. */ if (IFM_INST(ife->ifm_media) != sc->mii_inst) { reg = PHY_READ(sc, MII_BMCR); PHY_WRITE(sc, MII_BMCR, reg | BMCR_ISO); return (0); } /* * If the interface is not up, don't do anything. */ if ((mii->mii_ifp->if_flags & IFF_UP) == 0) break; mii_phy_set_media(sc); break; case MII_TICK: /* * If we're not currently selected, just return. */ if (IFM_INST(ife->ifm_media) != sc->mii_inst) return (0); if (mii_phy_tick(sc) == EJUSTRETURN) return (0); break; } /* Update the media status. */ ukphy_status(sc); /* Callback if something changed. */ mii_phy_update(sc, cmd); return (0); }
static int tlphy_service(struct mii_softc *self, struct mii_data *mii, int cmd) { struct tlphy_softc *sc = (struct tlphy_softc *)self; struct ifmedia_entry *ife = mii->mii_media.ifm_cur; int reg; if (sc->sc_need_acomp) tlphy_acomp(sc); switch (cmd) { case MII_POLLSTAT: /* * If we're not polling our PHY instance, just return. */ if (IFM_INST(ife->ifm_media) != sc->sc_mii.mii_inst) return (0); break; case MII_MEDIACHG: /* * If the media indicates a different PHY instance, * isolate ourselves. */ if (IFM_INST(ife->ifm_media) != sc->sc_mii.mii_inst) { reg = PHY_READ(&sc->sc_mii, MII_BMCR); PHY_WRITE(&sc->sc_mii, MII_BMCR, reg | BMCR_ISO); return (0); } /* * If the interface is not up, don't do anything. */ if ((mii->mii_ifp->if_flags & IFF_UP) == 0) break; switch (IFM_SUBTYPE(ife->ifm_media)) { case IFM_AUTO: /* * The ThunderLAN PHY doesn't self-configure after * an autonegotiation cycle, so there's no such * thing as "already in auto mode". */ tlphy_auto(sc, 1); break; case IFM_10_2: case IFM_10_5: PHY_WRITE(&sc->sc_mii, MII_BMCR, 0); PHY_WRITE(&sc->sc_mii, MII_TLPHY_CTRL, CTRL_AUISEL); DELAY(100000); break; default: PHY_WRITE(&sc->sc_mii, MII_TLPHY_CTRL, 0); DELAY(100000); mii_phy_set_media(&sc->sc_mii); break; } break; case MII_TICK: /* * If we're not currently selected, just return. */ if (IFM_INST(ife->ifm_media) != sc->sc_mii.mii_inst) return (0); /* * Is the interface even up? */ if ((mii->mii_ifp->if_flags & IFF_UP) == 0) return (0); /* * Only used for autonegotiation. */ if (IFM_SUBTYPE(ife->ifm_media) != IFM_AUTO) break; /* * Check to see if we have link. If we do, we don't * need to restart the autonegotiation process. Read * the BMSR twice in case it's latched. * * XXX WHAT ABOUT CHECKING LINK ON THE BNC/AUI?! */ reg = PHY_READ(&sc->sc_mii, MII_BMSR) | PHY_READ(&sc->sc_mii, MII_BMSR); if (reg & BMSR_LINK) { sc->sc_mii.mii_ticks = 0; break; } /* * Only retry autonegotiation every mii_anegticks seconds. */ if (++sc->sc_mii.mii_ticks <= sc->sc_mii.mii_anegticks) return (0); sc->sc_mii.mii_ticks = 0; mii_phy_reset(&sc->sc_mii); if (tlphy_auto(sc, 0) == EJUSTRETURN) return (0); break; } /* Update the media status. */ tlphy_status(sc); /* Callback if something changed. */ mii_phy_update(&sc->sc_mii, cmd); return (0); }
static int ruephy_service(struct mii_softc *sc, struct mii_data *mii, int cmd) { struct ifmedia_entry *ife = mii->mii_media.ifm_cur; int reg; /* * We can't isolate the RealTek RTL8150 PHY, * so it has to be the only one! */ KASSERT(IFM_INST(ife->ifm_media) == sc->mii_inst, ("ruephy_service: can't isolate RealTek RTL8150 PHY")); switch (cmd) { case MII_POLLSTAT: break; case MII_MEDIACHG: /* * If the interface is not up, don't do anything. */ if ((mii->mii_ifp->if_flags & IFF_UP) == 0) break; if (IFM_SUBTYPE(ife->ifm_media) == IFM_100_T4) { /* * XXX Not supported as a manual setting right now. */ return (EINVAL); } mii_phy_set_media(sc); break; case MII_TICK: /* * Is the interface even up? */ if ((mii->mii_ifp->if_flags & IFF_UP) == 0) return (0); /* * Only used for autonegotiation. */ if (IFM_SUBTYPE(ife->ifm_media) != IFM_AUTO) break; /* * Check to see if we have link. If we do, we don't * need to restart the autonegotiation process. Read * the MSR twice in case it's latched. */ reg = PHY_READ(sc, RUEPHY_MII_MSR) | PHY_READ(sc, RUEPHY_MII_MSR); if (reg & RUEPHY_MSR_LINK) { sc->mii_ticks = 0; break; } /* * Only retry autonegotiation every 5 seconds. */ if (++sc->mii_ticks != 5) return (0); sc->mii_ticks = 0; ruephy_reset(sc); if (mii_phy_auto(sc, 0) == EJUSTRETURN) return (0); break; } /* Update the media status. */ ruephy_status(sc); /* Callback if something changed. */ mii_phy_update(sc, cmd); return (0); }
static int truephy_service(struct mii_softc *sc, struct mii_data *mii, int cmd) { struct ifmedia_entry *ife = mii->mii_media.ifm_cur; int bmcr; switch (cmd) { case MII_POLLSTAT: /* * If we're not polling our PHY instance, just return. */ if (IFM_INST(ife->ifm_media) != sc->mii_inst) return 0; break; case MII_MEDIACHG: /* * If the media indicates a different PHY instance, * isolate ourselves. */ if (IFM_INST(ife->ifm_media) != sc->mii_inst) { bmcr = PHY_READ(sc, MII_BMCR); PHY_WRITE(sc, MII_BMCR, bmcr | BMCR_ISO); return 0; } /* * If the interface is not up, don't do anything. */ if ((mii->mii_ifp->if_flags & IFF_UP) == 0) break; if (IFM_SUBTYPE(ife->ifm_media) != IFM_AUTO) { bmcr = PHY_READ(sc, MII_BMCR) & ~BMCR_AUTOEN; PHY_WRITE(sc, MII_BMCR, bmcr); PHY_WRITE(sc, MII_BMCR, bmcr | BMCR_PDOWN); } mii_phy_set_media(sc); if (IFM_SUBTYPE(ife->ifm_media) != IFM_AUTO) { bmcr = PHY_READ(sc, MII_BMCR) & ~BMCR_PDOWN; PHY_WRITE(sc, MII_BMCR, bmcr); if (IFM_SUBTYPE(ife->ifm_media) == IFM_1000_T) { PHY_WRITE(sc, MII_BMCR, bmcr | BMCR_AUTOEN | BMCR_STARTNEG); } } break; case MII_TICK: /* * If we're not currently selected, just return. */ if (IFM_INST(ife->ifm_media) != sc->mii_inst) return 0; if (mii_phy_tick(sc) == EJUSTRETURN) return 0; break; } /* Update the media status. */ truephy_status(sc); /* Callback if something changed. */ mii_phy_update(sc, cmd); return 0; }
static int nsphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd) { struct ifmedia_entry *ife = mii->mii_media.ifm_cur; int reg; switch (cmd) { case MII_POLLSTAT: /* * If we're not polling our PHY instance, just return. */ if (IFM_INST(ife->ifm_media) != sc->mii_inst) return (0); break; case MII_MEDIACHG: /* * If the media indicates a different PHY instance, * isolate ourselves. */ if (IFM_INST(ife->ifm_media) != sc->mii_inst) { reg = PHY_READ(sc, MII_BMCR); PHY_WRITE(sc, MII_BMCR, reg | BMCR_ISO); return (0); } /* * If the interface is not up, don't do anything. */ if ((mii->mii_ifp->if_flags & IFF_UP) == 0) break; reg = PHY_READ(sc, MII_NSPHY_PCR); /* * Set up the PCR to use LED4 to indicate full-duplex * in both 10baseT and 100baseTX modes. */ reg |= PCR_LED4MODE; /* * Make sure Carrier Intgrity Monitor function is * disabled (normal for Node operation, but sometimes * it's not set?!) */ reg |= PCR_CIMDIS; /* * Make sure "force link good" is set to normal mode. * It's only intended for debugging. */ reg |= PCR_FLINK100; /* * Mystery bits which are supposedly `reserved', * but we seem to need to set them when the PHY * is connected to some interfaces: * * 0x0400 is needed for fxp * (Intel EtherExpress Pro 10+/100B, 82557 chip) * (nsphy with a DP83840 chip) * 0x0100 may be needed for some other card */ reg |= PCR_CONGCTRL | PCR_TXREADYSEL; if (strcmp(device_get_name(device_get_parent(sc->mii_dev)), "fxp") == 0) PHY_WRITE(sc, MII_NSPHY_PCR, reg); mii_phy_set_media(sc); break; case MII_TICK: /* * If we're not currently selected, just return. */ if (IFM_INST(ife->ifm_media) != sc->mii_inst) return (0); if (mii_phy_tick(sc) == EJUSTRETURN) return (0); break; } /* Update the media status. */ nsphy_status(sc); /* Callback if something changed. */ mii_phy_update(sc, cmd); return (0); }