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 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 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); }
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 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 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 tlphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd) { struct tlphy_softc *tsc = (struct tlphy_softc *)sc; struct ifmedia_entry *ife = mii->mii_media.ifm_cur; int reg; if ((sc->mii_flags & MIIF_DOINGAUTO) == 0 && tsc->sc_need_acomp) tlphy_acomp(tsc); 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: /* * The ThunderLAN PHY doesn't self-configure after * an autonegotiation cycle, so there's no such * thing as "already in auto mode". */ (void) tlphy_auto(tsc, 1); break; case IFM_10_2: case IFM_10_5: PHY_WRITE(sc, MII_BMCR, 0); PHY_WRITE(sc, MII_TLPHY_CTRL, CTRL_AUISEL); delay(100000); break; default: PHY_WRITE(sc, MII_TLPHY_CTRL, 0); delay(100000); 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); /* * 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); /* * XXX WHAT ABOUT CHECKING LINK ON THE BNC/AUI?! */ 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 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 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 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); }
static int makphy_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_setmedia(sc); if (IFM_SUBTYPE(ife->ifm_media) != IFM_AUTO) { /* * when not in auto mode, we need to restart nego * anyway, or a switch from a fixed mode to another * fixed mode may not be seen by the switch. */ PHY_WRITE(sc, MII_BMCR, PHY_READ(sc, MII_BMCR) | 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; 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 ihphy_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; /* * If media is deselected, disable link (standby). */ reg = PHY_READ(sc, IHPHY_MII_ECR); if (IFM_SUBTYPE(ife->ifm_media) == IFM_NONE) reg &= ~IHPHY_ECR_LNK_EN; else reg |= IHPHY_ECR_LNK_EN; PHY_WRITE(sc, IHPHY_MII_ECR, reg); /* * XXX Adjust MDI/MDIX configuration? Other settings? */ 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); PHY_WRITE(sc, MII_BMCR, BMCR_PDOWN); return 0; } /* Update the media status. */ mii_phy_status(sc); /* Callback if something changed. */ mii_phy_update(sc, cmd); return 0; }
static int rdcphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd) { struct rdcphy_softc *rsc; struct ifmedia_entry *ife; rsc = (struct rdcphy_softc *)sc; 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; mii_phy_setmedia(sc); switch (IFM_SUBTYPE(ife->ifm_media)) { case IFM_100_TX: case IFM_10_T: /* * Report fake lost link event to parent * driver. This will stop MAC of parent * driver and make it possible to reconfigure * MAC after completion of link establishment. * Note, the parent MAC seems to require * restarting MAC when underlying any PHY * configuration was changed even if the * resolved speed/duplex was not changed at * all. */ mii->mii_media_status = 0; mii->mii_media_active = IFM_ETHER | IFM_NONE; rsc->mii_link_tick = RDCPHY_MANNEG_TICK; /* Immediately report link down. */ mii_phy_update(sc, MII_MEDIACHG); return (0); default: break; } break; case MII_TICK: if (mii_phy_tick(sc) == EJUSTRETURN) return (0); if (IFM_SUBTYPE(ife->ifm_media) != IFM_AUTO) { /* * It seems the PHY hardware does not correctly * report link status changes when manual link * configuration is in progress. It is also * possible for the PHY to complete establishing * a link within one second such that mii(4) * did not notice the link change. To workaround * the issue, emulate lost link event and wait * for 3 seconds when manual link configuration * is in progress. 3 seconds would be long * enough to absorb transient link flips. */ if (rsc->mii_link_tick > 0) { rsc->mii_link_tick--; return (0); } } break; } /* Update the media status. */ PHY_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); }
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: /* * 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; 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 if (mii_phy_auto(sc, 0) == EJUSTRETURN) return (0); 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_GMASK) == IFM_FDX) { speed |= CIPHY_BMCR_FDX; gig = CIPHY_1000CTL_AFD; } else { gig = CIPHY_1000CTL_AHD; } PHY_WRITE(sc, CIPHY_MII_1000CTL, 0); PHY_WRITE(sc, CIPHY_MII_BMCR, speed); PHY_WRITE(sc, CIPHY_MII_ANAR, CIPHY_SEL_TYPE); if (IFM_SUBTYPE(ife->ifm_media) != IFM_1000_T) break; PHY_WRITE(sc, CIPHY_MII_1000CTL, gig); PHY_WRITE(sc, CIPHY_MII_BMCR, speed|CIPHY_BMCR_AUTOEN|CIPHY_BMCR_STARTNEG); /* * 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, CIPHY_MII_1000CTL, gig|CIPHY_1000CTL_MSE|CIPHY_1000CTL_MSC); } else { PHY_WRITE(sc, CIPHY_MII_1000CTL, gig|CIPHY_1000CTL_MSE); } break; case IFM_NONE: PHY_WRITE(sc, MII_BMCR, BMCR_ISO|BMCR_PDOWN); break; case IFM_100_T4: 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); if (mii_phy_tick(sc) == EJUSTRETURN) return (0); break; } /* Update the media status. */ ciphy_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 pnaphy_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; switch (IFM_SUBTYPE(ife->ifm_media)) { case IFM_AUTO: case IFM_10_T: case IFM_100_TX: case IFM_100_T4: return (EINVAL); default: /* * BMCR data is stored in the ifmedia entry. */ PHY_WRITE(sc, MII_ANAR, mii_anar(ife->ifm_media)); PHY_WRITE(sc, MII_BMCR, ife->ifm_data); } 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); 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); }
int eephy_service(struct mii_softc *sc, struct mii_data *mii, int cmd) { struct ifmedia_entry *ife = mii->mii_media.ifm_cur; int bmcr; 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) { bmcr = PHY_READ(sc, E1000_CR); PHY_WRITE(sc, E1000_CR, bmcr | 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; mii_phy_setmedia(sc); /* * If autonegitation is not enabled, we need a * software reset for the settings to take effect. */ if (IFM_SUBTYPE(ife->ifm_media) != IFM_AUTO) { bmcr = PHY_READ(sc, E1000_CR); PHY_WRITE(sc, E1000_CR, bmcr | E1000_CR_RESET); } 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); }