static int pnphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd) { struct ifmedia_entry *ife = mii->mii_media.ifm_cur; 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; switch (IFM_SUBTYPE(ife->ifm_media)) { case IFM_AUTO: /* NWAY is busted on this chip */ case IFM_100_T4: /* * XXX Not supported as a manual setting right now. */ return (EINVAL); case IFM_100_TX: mii->mii_media_active = IFM_ETHER | IFM_100_TX; if ((ife->ifm_media & IFM_GMASK) == IFM_FDX) mii->mii_media_active |= IFM_FDX; MIIBUS_STATCHG(sc->mii_dev); return (0); case IFM_10_T: mii->mii_media_active = IFM_ETHER | IFM_10_T; if ((ife->ifm_media & IFM_GMASK) == IFM_FDX) mii->mii_media_active |= IFM_FDX; MIIBUS_STATCHG(sc->mii_dev); return (0); default: return (EINVAL); } break; case MII_TICK: /* * Is the interface even up? */ if ((mii->mii_ifp->if_flags & IFF_UP) == 0) return (0); break; } /* Update the media status. */ pnphy_status(sc); /* Callback if something changed. */ mii_phy_update(sc, cmd); return (0); }
static int pnphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd) { struct ifmedia_entry *ife = mii->mii_media.ifm_cur; 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; /* * Note that auto-negotiation is broken on this chip. */ switch (IFM_SUBTYPE(ife->ifm_media)) { case IFM_100_TX: mii->mii_media_active = IFM_ETHER | IFM_100_TX; if ((ife->ifm_media & IFM_FDX) != 0) mii->mii_media_active |= IFM_FDX; MIIBUS_STATCHG(sc->mii_dev); return (0); case IFM_10_T: mii->mii_media_active = IFM_ETHER | IFM_10_T; if ((ife->ifm_media & IFM_FDX) != 0) mii->mii_media_active |= IFM_FDX; MIIBUS_STATCHG(sc->mii_dev); return (0); default: return (EINVAL); } break; case MII_TICK: /* * Is the interface even up? */ if ((mii->mii_ifp->if_flags & IFF_UP) == 0) return (0); break; } /* Update the media status. */ PHY_STATUS(sc); /* Callback if something changed. */ mii_phy_update(sc, cmd); return (0); }
static void miibus_statchg(device_t dev) { device_t parent; parent = device_get_parent(dev); MIIBUS_STATCHG(parent); return; }
void mii_phy_update(struct mii_softc *sc, int cmd) { struct mii_data *mii = sc->mii_pdata; if (sc->mii_media_active != mii->mii_media_active || cmd == MII_MEDIACHG) { MIIBUS_STATCHG(sc->mii_dev); sc->mii_media_active = mii->mii_media_active; } if (sc->mii_media_status != mii->mii_media_status) { MIIBUS_LINKCHG(sc->mii_dev); sc->mii_media_status = mii->mii_media_status; } }
int e1000phy_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, E1000_CR); PHY_WRITE(sc, E1000_CR, reg | E1000_CR_ISOLATE); 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: /* * If we're already in auto mode, just return. */ if (sc->mii_flags & MIIF_DOINGAUTO) { return (0); } e1000phy_reset(sc); (void)e1000phy_mii_phy_auto(sc, 1); break; case IFM_1000_TX: if (sc->mii_flags & MIIF_DOINGAUTO) return (0); e1000phy_reset(sc); /* TODO - any other way to force 1000BT? */ (void)e1000phy_mii_phy_auto(sc, 1); break; case IFM_100_TX: e1000phy_reset(sc); if ((ife->ifm_media & IFM_GMASK) == IFM_FDX) { PHY_WRITE(sc, E1000_CR, E1000_CR_FULL_DUPLEX | E1000_CR_SPEED_100); PHY_WRITE(sc, E1000_AR, E1000_AR_100TX_FD); } else { PHY_WRITE(sc, E1000_CR, E1000_CR_SPEED_100); PHY_WRITE(sc, E1000_AR, E1000_AR_100TX); } break; case IFM_10_T: e1000phy_reset(sc); if ((ife->ifm_media & IFM_GMASK) == IFM_FDX) { PHY_WRITE(sc, E1000_CR, E1000_CR_FULL_DUPLEX | E1000_CR_SPEED_10); PHY_WRITE(sc, E1000_AR, E1000_AR_10T_FD); } else { PHY_WRITE(sc, E1000_CR, E1000_CR_SPEED_10); PHY_WRITE(sc, E1000_AR, E1000_AR_10T); } break; default: return (EINVAL); } break; case MII_TICK: /* * If we're not currently selected, just return. */ if (IFM_INST(ife->ifm_media) != sc->mii_inst) { return (0); } /* * Only used for autonegotiation. */ if (IFM_SUBTYPE(ife->ifm_media) != IFM_AUTO) { return (0); } /* * Is the interface even up? */ if ((mii->mii_ifp->if_flags & IFF_UP) == 0) { return (0); } /* * Only retry autonegotiation every 5 seconds. */ if (++(sc->mii_ticks) != 5) { return (0); } sc->mii_ticks = 0; /* * 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. */ reg = PHY_READ(sc, E1000_SR) | PHY_READ(sc, E1000_SR); if (reg & E1000_SR_LINK_STATUS) break; e1000phy_reset(sc); if (e1000phy_mii_phy_auto(sc, 0) == EJUSTRETURN) { return(0); } break; } /* Update the media status. */ e1000phy_status(sc); /* Callback if something changed. */ if (sc->mii_active != mii->mii_media_active || cmd == MII_MEDIACHG) { MIIBUS_STATCHG(sc->mii_dev); sc->mii_active = mii->mii_media_active; } return (0); }
static int pnphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd) { struct ifmedia_entry *ife = mii->mii_media.ifm_cur; 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) return (0); /* * If the interface is not up, don't do anything. */ if ((mii->mii_ifp->if_flags & IFF_UP) == 0) break; sc->mii_flags = 0; switch (IFM_SUBTYPE(ife->ifm_media)) { case IFM_AUTO: /* NWAY is busted on this chip */ case IFM_100_T4: /* * XXX Not supported as a manual setting right now. */ return (EINVAL); case IFM_100_TX: mii->mii_media_active = IFM_ETHER|IFM_100_TX; if ((ife->ifm_media & IFM_GMASK) == IFM_FDX) mii->mii_media_active |= IFM_FDX; MIIBUS_STATCHG(sc->mii_dev); return(0); break; case IFM_10_T: mii->mii_media_active = IFM_ETHER|IFM_10_T; if ((ife->ifm_media & IFM_GMASK) == IFM_FDX) mii->mii_media_active |= IFM_FDX; MIIBUS_STATCHG(sc->mii_dev); return(0); break; default: return(EINVAL); break; } break; case MII_TICK: /* * If we're not currently selected, just return. */ if (IFM_INST(ife->ifm_media) != sc->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; /* * This PHY's autonegotiation doesn't need to be kicked. */ return(0); } /* Update the media status. */ pnphy_status(sc); /* Callback if something changed. */ mii_phy_update(sc, cmd); return (0); }