static int rlphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd) { switch (cmd) { case MII_POLLSTAT: break; case MII_MEDIACHG: mii_phy_setmedia(sc); break; case MII_TICK: /* * The RealTek PHY's autonegotiation doesn't need to be * kicked; it continues in the background. */ break; } /* Update the media status. */ PHY_STATUS(sc); /* Callback if something changed. */ mii_phy_update(sc, cmd); return (0); }
static int tdkphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd) { 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_setmedia(sc); break; case MII_TICK: if (mii_phy_tick(sc) == EJUSTRETURN) return (0); break; } /* Update the media status. */ PHY_STATUS(sc); if (sc->mii_pdata->mii_media_active & IFM_FDX) PHY_WRITE(sc, MII_BMCR, PHY_READ(sc, MII_BMCR) | BMCR_FDX); else PHY_WRITE(sc, MII_BMCR, PHY_READ(sc, MII_BMCR) & ~BMCR_FDX); /* Callback if something changed. */ mii_phy_update(sc, cmd); return (0); }
int nsgphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd) { struct ifmedia_entry *ife = mii->mii_media.ifm_cur; int reg; if ((sc->mii_dev.dv_flags & DVF_ACTIVE) == 0) return (ENXIO); 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_setmedia(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; case MII_DOWN: mii_phy_down(sc); return (0); } /* Update the media status. */ mii_phy_status(sc); /* Callback if something changed. */ mii_phy_update(sc, cmd); return (0); }
static int amphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd) { 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_setmedia(sc); break; case MII_TICK: if (mii_phy_tick(sc) == EJUSTRETURN) return (0); break; } /* Update the media status. */ PHY_STATUS(sc); /* Callback if something changed. */ mii_phy_update(sc, cmd); return (0); }
static int micphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd) { switch (cmd) { case MII_POLLSTAT: break; case MII_MEDIACHG: mii_phy_setmedia(sc); break; case MII_TICK: if (mii_phy_tick(sc) == EJUSTRETURN) return (0); break; } /* Update the media status. */ PHY_STATUS(sc); /* Callback if something changed. */ mii_phy_update(sc, cmd); return (0); }
static int smcphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd) { struct ifmedia_entry *ife; int reg; ife = mii->mii_media.ifm_cur; switch (cmd) { case MII_POLLSTAT: break; case MII_MEDIACHG: switch (IFM_SUBTYPE(ife->ifm_media)) { case IFM_AUTO: smcphy_auto(sc, ife->ifm_media); break; default: mii_phy_setmedia(sc); break; } break; case MII_TICK: if (IFM_SUBTYPE(ife->ifm_media) != IFM_AUTO) { break; } /* I have no idea why BMCR_ISO gets set. */ reg = PHY_READ(sc, MII_BMCR); if (reg & BMCR_ISO) { PHY_WRITE(sc, MII_BMCR, reg & ~BMCR_ISO); } reg = PHY_READ(sc, MII_BMSR) | PHY_READ(sc, MII_BMSR); if (reg & BMSR_LINK) { sc->mii_ticks = 0; break; } if (++sc->mii_ticks <= MII_ANEGTICKS) { break; } sc->mii_ticks = 0; PHY_RESET(sc); smcphy_auto(sc, ife->ifm_media); break; } /* Update the media status. */ PHY_STATUS(sc); /* Callback if something changed. */ mii_phy_update(sc, cmd); return (0); }
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 jmphy_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; if (jmphy_setmedia(sc, ife) != EJUSTRETURN) return (EINVAL); 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) { sc->mii_ticks = 0; break; } /* Check for link. */ if ((PHY_READ(sc, JMPHY_SSR) & JMPHY_SSR_LINK_UP) != 0) { sc->mii_ticks = 0; break; } /* Announce link loss right after it happens. */ if (sc->mii_ticks++ == 0) break; if (sc->mii_ticks <= sc->mii_anegticks) return (0); sc->mii_ticks = 0; (void)jmphy_setmedia(sc, ife); break; } /* Update the media status. */ PHY_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; 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); }
int rlphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd) { struct ifmedia_entry *ife = mii->mii_media.ifm_cur; /* * Can't isolate the RTL8139 phy, so it has to be the only one. */ if (IFM_INST(ife->ifm_media) != sc->mii_inst) panic("rlphy_service: attempt to isolate 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; mii_phy_setmedia(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; /* * The RealTek PHY's autonegotiation doesn't need to be * kicked; it continues in the background. */ break; case MII_DOWN: mii_phy_down(sc); return (0); } /* Update the media status. */ mii_phy_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 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: 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_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_setmedia(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 (mii_phy_tick(sc) == EJUSTRETURN) return (0); break; } /* Update the media status. */ PHY_STATUS(sc); /* Callback if something changed. */ mii_phy_update(sc, cmd); return (0); }
static int exphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd) { struct ifmedia_entry *ife = mii->mii_media.ifm_cur; /* * We can't isolate the 3Com PHY, so it has to be the only one! */ if (IFM_INST(ife->ifm_media) != sc->mii_inst) panic("exphy_service: can't isolate 3Com 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; mii_phy_setmedia(sc); break; case MII_TICK: /* * Is the interface even up? */ if ((mii->mii_ifp->if_flags & IFF_UP) == 0) return (0); /* * The 3Com PHY's autonegotiation doesn't need to be * kicked; it continues in the background. */ break; } /* Update the media status. */ ukphy_status(sc); /* Callback if something changed. */ mii_phy_update(sc, cmd); return (0); }
int exphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd) { struct ifmedia_entry *ife = mii->mii_media.ifm_cur; if ((sc->mii_dev.dv_flags & DVF_ACTIVE) == 0) return (ENXIO); /* * We can't isolate the 3Com PHY, so it has to be the only one! */ if (IFM_INST(ife->ifm_media) != sc->mii_inst) panic("exphy_service: can't isolate 3Com 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; mii_phy_setmedia(sc); break; case MII_TICK: if (mii_phy_tick(sc) == EJUSTRETURN) return (0); break; case MII_DOWN: mii_phy_down(sc); return (0); } /* Update the media status. */ mii_phy_status(sc); /* Callback if something changed. */ mii_phy_update(sc, cmd); return (0); }
static int acphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd) { int reg; 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; /* Wake & deisolate up if necessary */ reg = PHY_READ(sc, MII_BMCR); if (reg & (BMCR_ISO | BMCR_PDOWN)) PHY_WRITE(sc, MII_BMCR, reg & ~(BMCR_ISO | BMCR_PDOWN)); mii_phy_setmedia(sc); break; case MII_TICK: /* * Is the interface even up? */ if ((mii->mii_ifp->if_flags & IFF_UP) == 0) return (0); /* * This PHY's autonegotiation doesn't need to be kicked. */ break; } /* Update the media status. */ PHY_STATUS(sc); /* Callback if something changed. */ mii_phy_update(sc, cmd); return (0); }
static int axphy_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 (IFM_INST(ife->ifm_media) != sc->mii_inst) return (0); break; case MII_MEDIACHG: 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_setmedia(sc); break; case MII_TICK: if (IFM_INST(ife->ifm_media) != sc->mii_inst) return (0); if (mii_phy_tick(sc) == EJUSTRETURN) return (0); break; } /* Update the media status. */ axphy_status(sc); /* Callback if something changed. */ mii_phy_update(sc, cmd); return (0); }
static int pnaphy_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_HPNA_1: mii_phy_setmedia(sc); break; default: return (EINVAL); } break; case MII_TICK: if (mii_phy_tick(sc) == EJUSTRETURN) return (0); break; } /* Update the media status. */ PHY_STATUS(sc); if (IFM_SUBTYPE(mii->mii_media_active) == IFM_10_T) mii->mii_media_active = IFM_ETHER | IFM_HPNA_1; /* Callback if something changed. */ mii_phy_update(sc, cmd); return (0); }
static int rlphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd) { 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_setmedia(sc); break; case MII_TICK: /* * Is the interface even up? */ if ((mii->mii_ifp->if_flags & IFF_UP) == 0) return (0); /* * The RealTek PHY's autonegotiation doesn't need to be * kicked; it continues in the background. */ break; } /* Update the media status. */ PHY_STATUS(sc); /* Callback if something changed. */ mii_phy_update(sc, cmd); return (0); }
static int lxtphy_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; if (IFM_SUBTYPE(ife->ifm_media) == IFM_100_FX) lxtphy_set_fx(sc); else lxtphy_set_tp(sc); mii_phy_setmedia(sc); break; case MII_TICK: if (mii_phy_tick(sc) == EJUSTRETURN) return (0); break; } /* Update the media status. */ PHY_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_setmedia(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 igphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd) { struct ifmedia_entry *ife = mii->mii_media.ifm_cur; uint16_t 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_IGPHY_PORT_CTRL); if (IFM_SUBTYPE(ife->ifm_media) == IFM_AUTO) { reg |= PSCR_AUTO_MDIX; reg &= ~PSCR_FORCE_MDI_MDIX; PHY_WRITE(sc, MII_IGPHY_PORT_CTRL, reg); } else { reg &= ~(PSCR_AUTO_MDIX | PSCR_FORCE_MDI_MDIX); PHY_WRITE(sc, MII_IGPHY_PORT_CTRL, reg); } mii_phy_setmedia(sc); break; case MII_TICK: /* * If we're not currently selected, just return. */ if (IFM_INST(ife->ifm_media) != sc->mii_inst) return (0); igphy_smartspeed_workaround(sc); if (mii_phy_tick(sc) == EJUSTRETURN) return (0); break; case MII_DOWN: mii_phy_down(sc); return (0); } /* Update the media status. */ mii_phy_status(sc); /* Callback if something changed. */ mii_phy_update(sc, cmd); return (0); }
static int ip1000phy_service(struct mii_softc *sc, struct mii_data *mii, int cmd) { struct ifmedia_entry *ife = mii->mii_media.ifm_cur; uint32_t gig, reg, speed; switch (cmd) { case MII_POLLSTAT: break; case MII_MEDIACHG: PHY_RESET(sc); switch (IFM_SUBTYPE(ife->ifm_media)) { case IFM_AUTO: (void)ip1000phy_mii_phy_auto(sc, ife->ifm_media); goto done; case IFM_1000_T: /* * XXX * Manual 1000baseT setting doesn't seem to work. */ speed = IP1000PHY_BMCR_1000; break; case IFM_100_TX: speed = IP1000PHY_BMCR_100; break; case IFM_10_T: speed = IP1000PHY_BMCR_10; break; default: return (EINVAL); } if ((ife->ifm_media & IFM_FDX) != 0) { speed |= IP1000PHY_BMCR_FDX; gig = IP1000PHY_1000CR_1000T_FDX; } else gig = IP1000PHY_1000CR_1000T; if (IFM_SUBTYPE(ife->ifm_media) == IFM_1000_T) { gig |= IP1000PHY_1000CR_MASTER | IP1000PHY_1000CR_MANUAL; if ((ife->ifm_media & IFM_ETH_MASTER) != 0) gig |= IP1000PHY_1000CR_MMASTER; } else gig = 0; PHY_WRITE(sc, IP1000PHY_MII_1000CR, gig); PHY_WRITE(sc, IP1000PHY_MII_BMCR, speed); done: break; case MII_TICK: /* * Only used for autonegotiation. */ if (IFM_SUBTYPE(ife->ifm_media) != IFM_AUTO) { sc->mii_ticks = 0; break; } /* * check for link. */ reg = PHY_READ(sc, MII_BMSR) | PHY_READ(sc, MII_BMSR); if (reg & BMSR_LINK) { sc->mii_ticks = 0; break; } /* Announce link loss right after it happens */ if (sc->mii_ticks++ == 0) break; /* * Only retry autonegotiation every mii_anegticks seconds. */ if (sc->mii_ticks <= sc->mii_anegticks) break; sc->mii_ticks = 0; ip1000phy_mii_phy_auto(sc, ife->ifm_media); break; } /* Update the media status. */ PHY_STATUS(sc); /* Callback if something changed. */ mii_phy_update(sc, cmd); return (0); }
static int e1000phy_service(struct mii_softc *sc, struct mii_data *mii, int cmd) { struct ifmedia_entry *ife = mii->mii_media.ifm_cur; uint16_t speed, gig; int reg; 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_AUTO) { e1000phy_mii_phy_auto(sc, ife->ifm_media); break; } speed = 0; switch (IFM_SUBTYPE(ife->ifm_media)) { case IFM_1000_T: if ((sc->mii_extcapabilities & (EXTSR_1000TFDX | EXTSR_1000THDX)) == 0) return (EINVAL); speed = E1000_CR_SPEED_1000; break; case IFM_1000_SX: if ((sc->mii_extcapabilities & (EXTSR_1000XFDX | EXTSR_1000XHDX)) == 0) return (EINVAL); speed = E1000_CR_SPEED_1000; break; case IFM_100_TX: speed = E1000_CR_SPEED_100; break; case IFM_10_T: speed = E1000_CR_SPEED_10; break; case IFM_NONE: reg = PHY_READ(sc, E1000_CR); PHY_WRITE(sc, E1000_CR, reg | E1000_CR_ISOLATE | E1000_CR_POWER_DOWN); goto done; default: return (EINVAL); } if ((ife->ifm_media & IFM_FDX) != 0) { speed |= E1000_CR_FULL_DUPLEX; gig = E1000_1GCR_1000T_FD; } else gig = E1000_1GCR_1000T; reg = PHY_READ(sc, E1000_CR); reg &= ~E1000_CR_AUTO_NEG_ENABLE; PHY_WRITE(sc, E1000_CR, reg | E1000_CR_RESET); if (IFM_SUBTYPE(ife->ifm_media) == IFM_1000_T) { gig |= E1000_1GCR_MS_ENABLE; if ((ife->ifm_media & IFM_ETH_MASTER) != 0) gig |= E1000_1GCR_MS_VALUE; } else if ((sc->mii_extcapabilities & (EXTSR_1000TFDX | EXTSR_1000THDX)) != 0) gig = 0; PHY_WRITE(sc, E1000_1GCR, gig); PHY_WRITE(sc, E1000_AR, E1000_AR_SELECTOR_FIELD); PHY_WRITE(sc, E1000_CR, speed | E1000_CR_RESET); done: 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) { sc->mii_ticks = 0; break; } /* * check for link. * Read the status register twice; BMSR_LINK is latch-low. */ reg = PHY_READ(sc, MII_BMSR) | PHY_READ(sc, MII_BMSR); if (reg & BMSR_LINK) { sc->mii_ticks = 0; break; } /* Announce link loss right after it happens. */ if (sc->mii_ticks++ == 0) break; if (sc->mii_ticks <= sc->mii_anegticks) break; sc->mii_ticks = 0; PHY_RESET(sc); e1000phy_mii_phy_auto(sc, ife->ifm_media); break; } /* Update the media status. */ PHY_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 brgphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd) { struct ifmedia_entry *ife = mii->mii_media.ifm_cur; int val; 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; /* Todo: Why is this here? Is it really needed? */ PHY_RESET(sc); /* XXX hardware bug work-around */ switch (IFM_SUBTYPE(ife->ifm_media)) { case IFM_AUTO: brgphy_mii_phy_auto(sc, ife->ifm_media); break; case IFM_2500_SX: case IFM_1000_SX: case IFM_1000_T: case IFM_100_TX: case IFM_10_T: brgphy_setmedia(sc, ife->ifm_media); break; default: return (EINVAL); } break; case MII_TICK: /* Bail if the interface isn't up. */ if ((mii->mii_ifp->if_flags & IFF_UP) == 0) return (0); /* Bail if autoneg isn't in process. */ if (IFM_SUBTYPE(ife->ifm_media) != IFM_AUTO) { sc->mii_ticks = 0; break; } /* * Check to see if we have link. If we do, we don't * need to restart the autonegotiation process. */ val = PHY_READ(sc, MII_BMSR) | PHY_READ(sc, MII_BMSR); if (val & BMSR_LINK) { sc->mii_ticks = 0; /* Reset autoneg timer. */ break; } /* Announce link loss right after it happens. */ if (sc->mii_ticks++ == 0) break; /* Only retry autonegotiation every mii_anegticks seconds. */ if (sc->mii_ticks <= sc->mii_anegticks) break; /* Retry autonegotiation */ sc->mii_ticks = 0; brgphy_mii_phy_auto(sc, ife->ifm_media); break; } /* Update the media status. */ PHY_STATUS(sc); /* * Callback if something changed. Note that we need to poke * the DSP on the Broadcom PHYs if the media changes. */ if (sc->mii_media_active != mii->mii_media_active || sc->mii_media_status != mii->mii_media_status || cmd == MII_MEDIACHG) { switch (sc->mii_mpd_oui) { case MII_OUI_BROADCOM: switch (sc->mii_mpd_model) { case MII_MODEL_BROADCOM_BCM5400: bcm5401_load_dspcode(sc); break; case MII_MODEL_BROADCOM_BCM5401: if (sc->mii_mpd_rev == 1 || sc->mii_mpd_rev == 3) bcm5401_load_dspcode(sc); break; case MII_MODEL_BROADCOM_BCM5411: bcm5411_load_dspcode(sc); break; case MII_MODEL_BROADCOM_BCM54K2: bcm54k2_load_dspcode(sc); break; } break; } } mii_phy_update(sc, cmd); return (0); }
int atphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd) { struct ifmedia_entry *ife = mii->mii_media.ifm_cur; uint16_t anar, bmcr, bmsr; 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; bmcr = 0; switch (IFM_SUBTYPE(ife->ifm_media)) { case IFM_AUTO: case IFM_1000_T: atphy_mii_phy_auto(sc); goto done; case IFM_100_TX: bmcr = BMCR_S100; break; case IFM_10_T: bmcr = BMCR_S10; break; case IFM_NONE: bmcr = PHY_READ(sc, MII_BMCR); /* * XXX * Due to an unknown reason powering down PHY resulted * 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. */ PHY_WRITE(sc, MII_BMCR, bmcr | BMCR_ISO); goto done; default: return (EINVAL); } anar = mii_anar(ife->ifm_media); if (((ife->ifm_media & IFM_GMASK) & IFM_FDX) != 0) { bmcr |= BMCR_FDX; /* Enable pause. */ if (sc->mii_flags & MIIF_DOPAUSE) anar |= ANAR_PAUSE_TOWARDS; } if ((sc->mii_extcapabilities & (EXTSR_1000TFDX | EXTSR_1000THDX)) != 0) PHY_WRITE(sc, MII_100T2CR, 0); PHY_WRITE(sc, MII_ANAR, anar); /* * Reset the PHY so all changes take effect. */ PHY_WRITE(sc, MII_BMCR, bmcr | BMCR_RESET | BMCR_AUTOEN | BMCR_STARTNEG); done: 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) { sc->mii_ticks = 0; break; } /* * Check for link. * Read the status register twice; BMSR_LINK is latch-low. */ bmsr = PHY_READ(sc, MII_BMSR) | PHY_READ(sc, MII_BMSR); if (bmsr & BMSR_LINK) { sc->mii_ticks = 0; break; } /* Announce link loss right after it happens. */ if (sc->mii_ticks++ == 0) break; /* * Only retry autonegotiation every mii_anegticks seconds. */ if (sc->mii_ticks <= sc->mii_anegticks) break; sc->mii_ticks = 0; atphy_mii_phy_auto(sc); break; } /* Update the media status. */ mii_phy_status(sc); /* Callback if something changed. */ mii_phy_update(sc, cmd); return (0); }
int xmphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd) { struct ifmedia_entry *ife = mii->mii_media.ifm_cur; int reg; if ((sc->mii_dev.dv_flags & DVF_ACTIVE) == 0) return (ENXIO); 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; switch (IFM_SUBTYPE(ife->ifm_media)) { case IFM_AUTO: (void) xmphy_mii_phy_auto(sc); break; case IFM_1000_SX: PHY_RESET(sc); if ((ife->ifm_media & IFM_GMASK) == IFM_FDX) { PHY_WRITE(sc, XMPHY_MII_ANAR, XMPHY_ANAR_FDX); PHY_WRITE(sc, XMPHY_MII_BMCR, XMPHY_BMCR_FDX); } else { PHY_WRITE(sc, XMPHY_MII_ANAR, XMPHY_ANAR_HDX); PHY_WRITE(sc, XMPHY_MII_BMCR, 0); } break; case IFM_100_T4: case IFM_100_TX: case IFM_10_T: 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); /* * 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. */ reg = PHY_READ(sc, MII_BMSR) | PHY_READ(sc, MII_BMSR); if (reg & BMSR_LINK) break; /* * Only retry autonegotiation every mii_anegticks seconds. */ if (++sc->mii_ticks <= sc->mii_anegticks) break; sc->mii_ticks = 0; PHY_RESET(sc); xmphy_mii_phy_auto(sc); break; } /* Update the media status. */ mii_phy_status(sc); /* Callback if something changed. */ mii_phy_update(sc, cmd); return (0); }
static int ciphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd) { struct ifmedia_entry *ife = mii->mii_media.ifm_cur; int reg, speed, gig; 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; ciphy_fixup(sc); /* XXX hardware bug work-around */ switch (IFM_SUBTYPE(ife->ifm_media)) { case IFM_AUTO: #ifdef foo /* * If we're already in auto mode, just return. */ if (PHY_READ(sc, CIPHY_MII_BMCR) & CIPHY_BMCR_AUTOEN) return (0); #endif (void)mii_phy_auto(sc); break; case IFM_1000_T: speed = CIPHY_S1000; goto setit; case IFM_100_TX: speed = CIPHY_S100; goto setit; case IFM_10_T: speed = CIPHY_S10; setit: if ((ife->ifm_media & IFM_FDX) != 0) { speed |= CIPHY_BMCR_FDX; gig = CIPHY_1000CTL_AFD; } else gig = CIPHY_1000CTL_AHD; if (IFM_SUBTYPE(ife->ifm_media) == IFM_1000_T) { gig |= CIPHY_1000CTL_MSE; if ((ife->ifm_media & IFM_ETH_MASTER) != 0) gig |= CIPHY_1000CTL_MSC; speed |= CIPHY_BMCR_AUTOEN | CIPHY_BMCR_STARTNEG; } else gig = 0; PHY_WRITE(sc, CIPHY_MII_1000CTL, gig); PHY_WRITE(sc, CIPHY_MII_BMCR, speed); PHY_WRITE(sc, CIPHY_MII_ANAR, CIPHY_SEL_TYPE); break; case IFM_NONE: PHY_WRITE(sc, MII_BMCR, BMCR_ISO | BMCR_PDOWN); break; default: return (EINVAL); } 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 BMSR twice in case it's latched. */ reg = PHY_READ(sc, MII_BMSR) | PHY_READ(sc, MII_BMSR); if (reg & BMSR_LINK) break; /* Announce link loss right after it happens. */ if (++sc->mii_ticks == 0) break; /* * Only retry autonegotiation every mii_anegticks seconds. */ if (sc->mii_ticks <= sc->mii_anegticks) break; sc->mii_ticks = 0; mii_phy_auto(sc); break; } /* Update the media status. */ PHY_STATUS(sc); /* * Callback if something changed. Note that we need to poke * apply fixups for certain PHY revs. */ if (sc->mii_media_active != mii->mii_media_active || sc->mii_media_status != mii->mii_media_status || cmd == MII_MEDIACHG) { ciphy_fixup(sc); } mii_phy_update(sc, cmd); return (0); }
static int nsphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd) { int reg; 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; 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 Integrity 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 |= 0x0100 | 0x0400; if (strcmp(mii->mii_ifp->if_dname, "fxp") == 0) PHY_WRITE(sc, MII_NSPHY_PCR, reg); mii_phy_setmedia(sc); break; case MII_TICK: if (mii_phy_tick(sc) == EJUSTRETURN) return (0); break; } /* Update the media status. */ PHY_STATUS(sc); /* Callback if something changed. */ mii_phy_update(sc, cmd); return (0); }
int dcphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd) { struct dc_softc *dc_sc; struct ifmedia_entry *ife = mii->mii_media.ifm_cur; int reg; u_int32_t mode; if ((sc->mii_dev.dv_flags & DVF_ACTIVE) == 0) return (ENXIO); dc_sc = mii->mii_ifp->if_softc; 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; mii->mii_media_active = IFM_NONE; mode = CSR_READ_4(dc_sc, DC_NETCFG); mode &= ~(DC_NETCFG_FULLDUPLEX|DC_NETCFG_PORTSEL| DC_NETCFG_PCS|DC_NETCFG_SCRAMBLER|DC_NETCFG_SPEEDSEL); switch (IFM_SUBTYPE(ife->ifm_media)) { case IFM_AUTO: /*PHY_RESET(sc);*/ sc->mii_flags &= ~MIIF_DOINGAUTO; (void) dcphy_mii_phy_auto(sc, 0); break; case IFM_100_TX: PHY_RESET(sc); DC_CLRBIT(dc_sc, DC_10BTCTRL, DC_TCTL_AUTONEGENBL); mode |= DC_NETCFG_PORTSEL|DC_NETCFG_PCS| DC_NETCFG_SCRAMBLER; if ((ife->ifm_media & IFM_GMASK) == IFM_FDX) mode |= DC_NETCFG_FULLDUPLEX; else mode &= ~DC_NETCFG_FULLDUPLEX; CSR_WRITE_4(dc_sc, DC_NETCFG, mode); break; case IFM_10_T: DC_CLRBIT(dc_sc, DC_SIARESET, DC_SIA_RESET); DC_CLRBIT(dc_sc, DC_10BTCTRL, 0xFFFF); if ((ife->ifm_media & IFM_GMASK) == IFM_FDX) DC_SETBIT(dc_sc, DC_10BTCTRL, 0x7F3D); else DC_SETBIT(dc_sc, DC_10BTCTRL, 0x7F3F); DC_SETBIT(dc_sc, DC_SIARESET, DC_SIA_RESET); DC_CLRBIT(dc_sc, DC_10BTCTRL, DC_TCTL_AUTONEGENBL); mode &= ~DC_NETCFG_PORTSEL; mode |= DC_NETCFG_SPEEDSEL; if ((ife->ifm_media & IFM_GMASK) == IFM_FDX) mode |= DC_NETCFG_FULLDUPLEX; else mode &= ~DC_NETCFG_FULLDUPLEX; CSR_WRITE_4(dc_sc, DC_NETCFG, mode); 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); /* * 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; reg = CSR_READ_4(dc_sc, DC_10BTSTAT); if (!(reg & DC_TSTAT_LS10) || !(reg & DC_TSTAT_LS100)) break; /* * Only retry autonegotiation every mii_anegticks seconds. * * Otherwise, fall through to calling dcphy_status() * since real Intel 21143 chips don't show valid link * status until autonegotiation is switched off, and * that only happens in dcphy_status(). Without this, * successful autonegotiation is never recognised on * these chips. */ if (++sc->mii_ticks <= sc->mii_anegticks) break; sc->mii_ticks = 0; sc->mii_flags &= ~MIIF_DOINGAUTO; dcphy_mii_phy_auto(sc, 0); break; } /* Update the media status. */ mii_phy_status(sc); /* Callback if something changed. */ mii_phy_update(sc, cmd); return (0); }